-
-
Notifications
You must be signed in to change notification settings - Fork 69
feat: add serialization support for Set, Map, Date, RegExp, and BigInt via ISerializer contract #1136
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
feat: add serialization support for Set, Map, Date, RegExp, and BigInt via ISerializer contract #1136
Changes from 3 commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
0e6e0aa
Initial plan
Copilot 5c34f88
feat: add serialization support for Date, Set, Map, RegExp, and BigIn…
Copilot abfdf0f
fix: address code review feedback - update JSDoc and remove unused im…
Copilot c33e9aa
refactor: remove parseDates, add addSerializer(), escape __type in us…
Copilot bb0318c
perf: use Map for O(1) serializer lookup in JsonAdapter reviver
Copilot ff62c96
refactor: streamline JsonAdapter serializer internal
Belphemur File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| /** | ||
| * Contract for custom type serialization/deserialization. | ||
| * Implement this interface to add support for custom types | ||
| * that are not natively supported by JSON. | ||
| * | ||
| * Types are serialized using a `__type` discriminator: | ||
| * ```json | ||
| * { "__type": "TypeName", "__value": <serialized-data> } | ||
| * ``` | ||
| */ | ||
| export interface ISerializer { | ||
| /** | ||
| * Unique type identifier stored as `__type` in the serialized JSON. | ||
| */ | ||
| readonly type: string; | ||
|
|
||
| /** | ||
| * Serialize a value to a JSON-compatible representation. | ||
| * The returned value will be stored under `__value` in the serialized JSON. | ||
| * @param value The value to serialize | ||
| * @returns A JSON-compatible value | ||
| */ | ||
| serialize(value: any): any; | ||
|
|
||
| /** | ||
| * Deserialize a value from its JSON representation. | ||
| * The input is the `__value` from the serialized JSON. | ||
| * @param value The stored JSON value | ||
| * @returns The deserialized runtime value | ||
| */ | ||
| deserialize(value: any): any; | ||
|
|
||
| /** | ||
| * Test if a runtime value should be handled by this serializer. | ||
| * @param value The value to test | ||
| * @returns true if this serializer should handle this value | ||
| */ | ||
| test(value: any): boolean; | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,152 @@ | ||
| import {ISerializer} from "./ISerializer"; | ||
|
|
||
| /** | ||
| * Serializer for JavaScript Date objects. | ||
| * Serializes a Date as an ISO 8601 string. | ||
| * | ||
| * @example | ||
| * ```json | ||
| * { "__type": "Date", "__value": "2023-01-01T00:00:00.000Z" } | ||
| * ``` | ||
| */ | ||
| export class DateSerializer implements ISerializer { | ||
| readonly type = "Date"; | ||
|
|
||
| serialize(value: Date): string { | ||
| return value.toISOString(); | ||
| } | ||
|
|
||
| deserialize(value: string): Date { | ||
| return new Date(value); | ||
| } | ||
|
|
||
| test(value: any): boolean { | ||
| return value instanceof Date; | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Serializer for JavaScript Set objects. | ||
| * Serializes a Set as an array of its values. | ||
| * | ||
| * @example | ||
| * ```json | ||
| * { "__type": "Set", "__value": [1, 2, 3] } | ||
| * ``` | ||
| */ | ||
| export class SetSerializer implements ISerializer { | ||
| readonly type = "Set"; | ||
|
|
||
| serialize(value: Set<any>): any[] { | ||
| return [...value]; | ||
| } | ||
|
|
||
| deserialize(value: any[]): Set<any> { | ||
| return new Set(value); | ||
| } | ||
|
|
||
| test(value: any): boolean { | ||
| return value instanceof Set; | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Serializer for JavaScript Map objects. | ||
| * Serializes a Map as an array of key-value pairs. | ||
| * | ||
| * @example | ||
| * ```json | ||
| * { "__type": "Map", "__value": [["key1", "value1"], ["key2", "value2"]] } | ||
| * ``` | ||
| */ | ||
| export class MapSerializer implements ISerializer { | ||
| readonly type = "Map"; | ||
|
|
||
| serialize(value: Map<any, any>): [any, any][] { | ||
| return [...value]; | ||
| } | ||
|
|
||
| deserialize(value: [any, any][]): Map<any, any> { | ||
| return new Map(value); | ||
| } | ||
|
|
||
| test(value: any): boolean { | ||
| return value instanceof Map; | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Serializer for JavaScript RegExp objects. | ||
| * Serializes a RegExp as an object with source and flags. | ||
| * | ||
| * @example | ||
| * ```json | ||
| * { "__type": "RegExp", "__value": { "source": "hello\\s+world", "flags": "gi" } } | ||
| * ``` | ||
| */ | ||
| export class RegExpSerializer implements ISerializer { | ||
| readonly type = "RegExp"; | ||
|
|
||
| serialize(value: RegExp): { source: string; flags: string } { | ||
| return {source: value.source, flags: value.flags}; | ||
| } | ||
|
|
||
| deserialize(value: { source: string; flags: string }): RegExp { | ||
| return new RegExp(value.source, value.flags); | ||
| } | ||
|
|
||
| test(value: any): boolean { | ||
| return value instanceof RegExp; | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Serializer for JavaScript BigInt values. | ||
| * Serializes a BigInt as a string representation. | ||
| * | ||
| * @example | ||
| * ```json | ||
| * { "__type": "BigInt", "__value": "9007199254740993" } | ||
| * ``` | ||
| */ | ||
| export class BigIntSerializer implements ISerializer { | ||
| readonly type = "BigInt"; | ||
|
|
||
| serialize(value: bigint): string { | ||
| return value.toString(); | ||
| } | ||
|
|
||
| deserialize(value: string): bigint { | ||
| return BigInt(value); | ||
| } | ||
|
|
||
| test(value: any): boolean { | ||
| return typeof value === 'bigint'; | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Default serializers included with the JsonAdapter. | ||
| * Provides built-in support for Date, Set, Map, RegExp, and BigInt types. | ||
| * | ||
| * You can extend this list with your own serializers: | ||
| * ```typescript | ||
| * import { JsonAdapter, defaultSerializers, ISerializer } from 'node-json-db'; | ||
| * | ||
| * const mySerializer: ISerializer = { | ||
| * type: "MyType", | ||
| * serialize: (value) => value.toJSON(), | ||
| * deserialize: (value) => MyType.fromJSON(value), | ||
| * test: (value) => value instanceof MyType, | ||
| * }; | ||
| * | ||
| * const adapter = new JsonAdapter(fileAdapter, false, true, [...defaultSerializers, mySerializer]); | ||
| * ``` | ||
| */ | ||
| export const defaultSerializers: ISerializer[] = [ | ||
| new DateSerializer(), | ||
| new SetSerializer(), | ||
| new MapSerializer(), | ||
| new RegExpSerializer(), | ||
| new BigIntSerializer(), | ||
| ]; | ||
|
Belphemur marked this conversation as resolved.
Outdated
|
||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.