diff --git a/CHANGELOG.md b/CHANGELOG.md index 43c2f324..8fe40b8b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ + + +# [0.6.0](https://github.com/KATT/tupleson/compare/0.5.0...0.6.0) (2023-09-30) + + +### Features + +* add custom serializer example ([#8](https://github.com/KATT/tupleson/issues/8)) ([58eab05](https://github.com/KATT/tupleson/commit/58eab05baff0dd07803b5aa01c402fcd02df5b09)) + # [0.5.0](https://github.com/KATT/tupleson/compare/0.4.0...0.5.0) (2023-09-30) ### Features @@ -33,4 +42,4 @@ ### Features - initial version ([#1](https://github.com/KATT/tupleson/issues/1)) ([ccce25b](https://github.com/KATT/tupleson/commit/ccce25b6a039cf2e5c1a774c1ab022f0946ca8d5)) -- initialized repo ✨ ([c9e92a4](https://github.com/KATT/tupleson/commit/c9e92a42c97a8bc1ee3a9214f65626425c8598e3)) +- initialized repo ✨ ([c9e92a4](https://github.com/KATT/tupleson/commit/c9e92a42c97a8bc1ee3a9214f65626425c8598e3)) \ No newline at end of file diff --git a/README.md b/README.md index 6b5b7b36..d70a821e 100644 --- a/README.md +++ b/README.md @@ -101,6 +101,36 @@ type Obj = typeof obj; // type Obj = { foo: string; set: Set; } ``` +### Extend with a custom serializer + +#### `Temporal` + +> See test reference in [`./src/extend/temporal.test.ts`](./src/extend/temporal.test.ts) + +```ts +/* eslint-disable eslint-comments/disable-enable-pair, @typescript-eslint/no-unused-vars, n/no-missing-import, n/no-unpublished-import */ +import { Temporal } from "@js-temporal/polyfill"; +import { TsonType, createTson } from "tupleson"; + +const plainDate: TsonType = { + deserialize: (v) => Temporal.PlainDate.from(v), + key: "PlainDate", + serialize: (v) => v.toString(), + test: (v) => v instanceof Temporal.PlainDate, +}; + +const instant: TsonType = { + deserialize: (v) => Temporal.Instant.from(v), + key: "Instant", + serialize: (v) => v.toString(), + test: (v) => v instanceof Temporal.Instant, +}; + +const tson = createTson({ + types: [plainDate, instant], +}); +``` + **Footnotes**: [^1]: We don't support circular references as we don't think it's very desireable, but if you wanna contribute with adding opt-in support for that, you are very welcome! diff --git a/package.json b/package.json index c402c4d6..cbddae9a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "tupleson", - "version": "0.5.0", + "version": "0.6.0", "description": "A hackable JSON serializer/deserializer", "repository": { "type": "git", @@ -32,6 +32,7 @@ "tsc": "tsc" }, "devDependencies": { + "@js-temporal/polyfill": "^0.4.4", "@release-it/conventional-changelog": "^7.0.2", "@tsconfig/strictest": "^2.0.2", "@types/eslint": "^8.44.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 826d7558..bc24daaa 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5,6 +5,9 @@ settings: excludeLinksFromLockfile: false devDependencies: + '@js-temporal/polyfill': + specifier: ^0.4.4 + version: 0.4.4 '@release-it/conventional-changelog': specifier: ^7.0.2 version: 7.0.2(release-it@16.2.1) @@ -881,6 +884,14 @@ packages: '@jridgewell/sourcemap-codec': 1.4.15 dev: true + /@js-temporal/polyfill@0.4.4: + resolution: {integrity: sha512-2X6bvghJ/JAoZO52lbgyAPFj8uCflhTo2g7nkFzEQdXd/D8rEeD4HtmTEpmtGCva260fcd66YNXBOYdnmHqSOg==} + engines: {node: '>=12'} + dependencies: + jsbi: 4.3.0 + tslib: 2.6.2 + dev: true + /@ljharb/through@2.3.9: resolution: {integrity: sha512-yN599ZBuMPPK4tdoToLlvgJB4CLK8fGl7ntfy0Wn7U6ttNvHYurd81bfUiK/6sMkiIwm65R6ck4L6+Y3DfVbNQ==} engines: {node: '>= 0.4'} @@ -4113,6 +4124,10 @@ packages: argparse: 2.0.1 dev: true + /jsbi@4.3.0: + resolution: {integrity: sha512-SnZNcinB4RIcnEyZqFPdGPVgrg2AcnykiBy0sHVJQKHYeaLUvi3Exj+iaPpLnFVkDPZIV4U0yvgC9/R4uEAZ9g==} + dev: true + /jsdoc-type-pratt-parser@4.0.0: resolution: {integrity: sha512-YtOli5Cmzy3q4dP26GraSOeAhqecewG04hoO8DY56CH4KJ9Fvv5qKWUCCo3HZob7esJQHCv6/+bnTy72xZZaVQ==} engines: {node: '>=12.0.0'} diff --git a/src/extend/temporal.test.ts b/src/extend/temporal.test.ts new file mode 100644 index 00000000..49e90744 --- /dev/null +++ b/src/extend/temporal.test.ts @@ -0,0 +1,61 @@ +import { Temporal } from "@js-temporal/polyfill"; +import { expect, test } from "vitest"; + +import { TsonType, createTson } from "../index.js"; + +const plainDate: TsonType = { + deserialize: (v) => Temporal.PlainDate.from(v), + key: "PlainDate", + serialize: (v) => v.toString(), + test: (v) => v instanceof Temporal.PlainDate, +}; + +const instant: TsonType = { + deserialize: (v) => Temporal.Instant.from(v), + key: "Instant", + serialize: (v) => v.toString(), + test: (v) => v instanceof Temporal.Instant, +}; + +const tson = createTson({ + types: [plainDate, instant], +}); +test("PlainDate", () => { + const expected = Temporal.PlainDate.from("2021-01-01"); + + const serialized = tson.serialize(expected); + + expect(serialized).toMatchInlineSnapshot(` + { + "json": [ + "PlainDate", + "2021-01-01", + "__tson", + ], + "nonce": "__tson", + } + `); + const deserialized = tson.deserialize(serialized); + + expect(deserialized).toEqual(expected); +}); + +test("Instant", () => { + const expected = Temporal.Instant.from("2021-01-01T00:00:00Z"); + + const serialized = tson.serialize(expected); + + expect(serialized).toMatchInlineSnapshot(` + { + "json": [ + "Instant", + "2021-01-01T00:00:00Z", + "__tson", + ], + "nonce": "__tson", + } + `); + const deserialized = tson.deserialize(serialized); + + expect(deserialized).toEqual(expected); +}); diff --git a/src/index.ts b/src/index.ts index 98f84ee1..bab470ee 100644 --- a/src/index.ts +++ b/src/index.ts @@ -7,3 +7,5 @@ export { } from "./tson.js"; export * from "./handlers/index.js"; + +export type { TsonType } from "./types.js";