@vielzeug/vault 1.0.4 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/README.md +18 -59
  2. package/dist/_dev.cjs +1 -1
  3. package/dist/_dev.cjs.map +1 -1
  4. package/dist/_dev.js +3 -8
  5. package/dist/_dev.js.map +1 -1
  6. package/dist/adapter-core.cjs +1 -1
  7. package/dist/adapter-core.cjs.map +1 -1
  8. package/dist/adapter-core.d.ts +6 -3
  9. package/dist/adapter-core.d.ts.map +1 -1
  10. package/dist/adapter-core.js +138 -148
  11. package/dist/adapter-core.js.map +1 -1
  12. package/dist/adapters/indexeddb.cjs +1 -1
  13. package/dist/adapters/indexeddb.cjs.map +1 -1
  14. package/dist/adapters/indexeddb.d.ts +2 -5
  15. package/dist/adapters/indexeddb.d.ts.map +1 -1
  16. package/dist/adapters/indexeddb.js +113 -127
  17. package/dist/adapters/indexeddb.js.map +1 -1
  18. package/dist/adapters/memory.cjs +1 -1
  19. package/dist/adapters/memory.cjs.map +1 -1
  20. package/dist/adapters/memory.d.ts +3 -9
  21. package/dist/adapters/memory.d.ts.map +1 -1
  22. package/dist/adapters/memory.js +104 -140
  23. package/dist/adapters/memory.js.map +1 -1
  24. package/dist/adapters/webstorage.cjs +1 -1
  25. package/dist/adapters/webstorage.cjs.map +1 -1
  26. package/dist/adapters/webstorage.d.ts +3 -3
  27. package/dist/adapters/webstorage.d.ts.map +1 -1
  28. package/dist/adapters/webstorage.js +72 -67
  29. package/dist/adapters/webstorage.js.map +1 -1
  30. package/dist/errors.cjs.map +1 -1
  31. package/dist/errors.js.map +1 -1
  32. package/dist/index.cjs +1 -1
  33. package/dist/index.d.ts +2 -7
  34. package/dist/index.d.ts.map +1 -1
  35. package/dist/index.js +8 -10
  36. package/dist/internal.cjs +1 -1
  37. package/dist/internal.cjs.map +1 -1
  38. package/dist/internal.d.ts +8 -37
  39. package/dist/internal.d.ts.map +1 -1
  40. package/dist/internal.js +48 -98
  41. package/dist/internal.js.map +1 -1
  42. package/dist/migration.cjs +1 -1
  43. package/dist/migration.cjs.map +1 -1
  44. package/dist/migration.js +1 -3
  45. package/dist/migration.js.map +1 -1
  46. package/dist/prune.cjs +1 -1
  47. package/dist/prune.cjs.map +1 -1
  48. package/dist/prune.d.ts +2 -2
  49. package/dist/prune.d.ts.map +1 -1
  50. package/dist/prune.js +13 -13
  51. package/dist/prune.js.map +1 -1
  52. package/dist/query.cjs +1 -1
  53. package/dist/query.cjs.map +1 -1
  54. package/dist/query.d.ts +6 -6
  55. package/dist/query.d.ts.map +1 -1
  56. package/dist/query.js +1 -1
  57. package/dist/query.js.map +1 -1
  58. package/dist/streaming.d.ts +1 -21
  59. package/dist/streaming.d.ts.map +1 -1
  60. package/dist/ttl.cjs +1 -1
  61. package/dist/ttl.cjs.map +1 -1
  62. package/dist/ttl.d.ts +2 -47
  63. package/dist/ttl.d.ts.map +1 -1
  64. package/dist/ttl.js +1 -8
  65. package/dist/ttl.js.map +1 -1
  66. package/dist/types.cjs.map +1 -1
  67. package/dist/types.d.ts +29 -316
  68. package/dist/types.d.ts.map +1 -1
  69. package/dist/types.js.map +1 -1
  70. package/dist/vault.cjs +1 -1
  71. package/dist/vault.cjs.map +1 -1
  72. package/dist/vault.iife.js +1 -1
  73. package/dist/vault.iife.js.map +1 -1
  74. package/dist/vault.js +1 -1
  75. package/dist/vault.js.map +1 -1
  76. package/dist/versioned-codec.d.ts +1 -43
  77. package/dist/versioned-codec.d.ts.map +1 -1
  78. package/package.json +4 -4
  79. package/dist/streaming.cjs +0 -2
  80. package/dist/streaming.cjs.map +0 -1
  81. package/dist/streaming.js +0 -21
  82. package/dist/streaming.js.map +0 -1
  83. package/dist/versioned-codec.cjs +0 -2
  84. package/dist/versioned-codec.cjs.map +0 -1
  85. package/dist/versioned-codec.js +0 -32
  86. package/dist/versioned-codec.js.map +0 -1
@@ -1,44 +1,2 @@
1
- import type { VaultCodec } from './ttl';
2
- /**
3
- * A single version entry in a `createVersionedCodec` definition.
4
- * `version` must be a non-negative integer. `codec` is the codec responsible for
5
- * encoding/decoding records that carry this version number.
6
- */
7
- export type CodecVersion = {
8
- codec: VaultCodec;
9
- version: number;
10
- };
11
- /**
12
- * Creates a versioned codec that prepends a `__v` field to every encoded envelope.
13
- * When decoding, the `__v` field selects the matching codec from `versions`.
14
- * This allows safe codec upgrades: old records encoded with a previous codec continue
15
- * to decode correctly as long as the old codec remains in `versions`.
16
- *
17
- * ```ts
18
- * const v1Codec: VaultCodec = { ... };
19
- * const v2Codec: VaultCodec = { ... }; // newer, more compact format
20
- *
21
- * const codec = createVersionedCodec([
22
- * { version: 1, codec: v1Codec },
23
- * { version: 2, codec: v2Codec },
24
- * ], 2); // write new records with version 2
25
- *
26
- * const db = createMemory({ schema, codec });
27
- * // Old records (version 1) are decoded by v1Codec; new records use v2Codec.
28
- * ```
29
- *
30
- * **Rules:**
31
- * - `currentVersion` must be one of the versions listed in `versions`.
32
- * - Version numbers must be unique non-negative integers.
33
- * - The current version's codec is used for all new writes.
34
- * - Unrecognised `__v` values cause `decode` to return `undefined` (treated as corrupt).
35
- * - **Migration note:** records written by any other codec (including `defaultCodec`) lack
36
- * the `__v` field and will decode as `undefined` — they will be treated as missing/expired.
37
- * Perform a data migration or clear the store before switching to a versioned codec.
38
- * - **Secondary index caveat:** the `{ __d, __v }` envelope replaces the default
39
- * `{ value, expiresAt? }` shape, so IndexedDB secondary indexes (created via `.index()`
40
- * with keyPath `value.<field>`) silently stop matching. Don't combine a versioned codec
41
- * with `.index()` on the same table.
42
- */
43
- export declare function createVersionedCodec(versions: CodecVersion[], currentVersion: number): VaultCodec;
1
+ export {};
44
2
  //# sourceMappingURL=versioned-codec.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"versioned-codec.d.ts","sourceRoot":"","sources":["../src/versioned-codec.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAIxC;;;;GAIG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,KAAK,EAAE,UAAU,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,YAAY,EAAE,EAAE,cAAc,EAAE,MAAM,GAAG,UAAU,CAiDjG"}
1
+ {"version":3,"file":"versioned-codec.d.ts","sourceRoot":"","sources":["../src/versioned-codec.ts"],"names":[],"mappings":""}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@vielzeug/vault",
3
- "version": "1.0.4",
4
- "description": "Storage adapter for IndexedDB and localStorage with TTL, reactive signals, and schema validation",
3
+ "version": "2.0.0",
4
+ "description": "Typed browser storage with portable keys, TTL, observation, and IndexedDB transactions",
5
5
  "type": "module",
6
6
  "files": [
7
7
  "dist"
@@ -35,10 +35,10 @@
35
35
  "node": ">=22"
36
36
  },
37
37
  "devDependencies": {
38
- "@types/node": "^26.1.0",
38
+ "@types/node": "^26.1.2",
39
39
  "fake-indexeddb": "^6.2.5",
40
40
  "typescript": "^6.0.3",
41
- "vite": "^8.1.3",
41
+ "vite": "^8.2.0",
42
42
  "vitest": "^4.1.10"
43
43
  }
44
44
  }
@@ -1,2 +0,0 @@
1
- function e(e){let t=e[Symbol.asyncIterator]();return new ReadableStream({async cancel(){await t.return?.()},async pull(e){try{let{done:n,value:r}=await t.next();n?e.close():e.enqueue(r)}catch(t){e.error(t)}}})}exports.toReadableStream=e;
2
- //# sourceMappingURL=streaming.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"streaming.cjs","names":[],"sources":["../src/streaming.ts"],"sourcesContent":["/**\n * Converts an `AsyncIterable<T>` into a Web Standard `ReadableStream<T>`.\n *\n * Use this with `db.watch()` when you need a `ReadableStream` instead of an async iterator —\n * for example, to `pipeTo()` a `WritableStream` or `pipeThrough()` a `TransformStream`.\n *\n * ```ts\n * const stream = toReadableStream(db.watch('users'));\n * await stream.pipeTo(new WritableStream({ write: (users) => render(users) }));\n * ```\n *\n * The stream closes when the iterable is exhausted or when the stream is cancelled.\n * Pass an `AbortSignal` to `db.watch()` to cancel from outside:\n *\n * ```ts\n * const controller = new AbortController();\n * const stream = toReadableStream(db.watch('users', { signal: controller.signal }));\n * controller.abort(); // closes the stream\n * ```\n */\nexport function toReadableStream<T>(iterable: AsyncIterable<T>): ReadableStream<T> {\n const iter = iterable[Symbol.asyncIterator]();\n\n return new ReadableStream<T>({\n async cancel() {\n await iter.return?.();\n },\n async pull(controller) {\n try {\n const { done, value } = await iter.next();\n\n if (done) {\n controller.close();\n } else {\n controller.enqueue(value);\n }\n } catch (err) {\n controller.error(err);\n }\n },\n });\n}\n"],"mappings":"AAoBA,SAAgB,EAAoB,EAA+C,CACjF,IAAM,EAAO,EAAS,OAAO,cAAc,CAAC,EAE5C,OAAO,IAAI,eAAkB,CAC3B,MAAM,QAAS,CACb,MAAM,EAAK,SAAS,CACtB,EACA,MAAM,KAAK,EAAY,CACrB,GAAI,CACF,GAAM,CAAE,OAAM,SAAU,MAAM,EAAK,KAAK,EAEpC,EACF,EAAW,MAAM,EAEjB,EAAW,QAAQ,CAAK,CAE5B,OAAS,EAAK,CACZ,EAAW,MAAM,CAAG,CACtB,CACF,CACF,CAAC,CACH"}
package/dist/streaming.js DELETED
@@ -1,21 +0,0 @@
1
- //#region src/streaming.ts
2
- function e(e) {
3
- let t = e[Symbol.asyncIterator]();
4
- return new ReadableStream({
5
- async cancel() {
6
- await t.return?.();
7
- },
8
- async pull(e) {
9
- try {
10
- let { done: n, value: r } = await t.next();
11
- n ? e.close() : e.enqueue(r);
12
- } catch (t) {
13
- e.error(t);
14
- }
15
- }
16
- });
17
- }
18
- //#endregion
19
- export { e as toReadableStream };
20
-
21
- //# sourceMappingURL=streaming.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"streaming.js","names":[],"sources":["../src/streaming.ts"],"sourcesContent":["/**\n * Converts an `AsyncIterable<T>` into a Web Standard `ReadableStream<T>`.\n *\n * Use this with `db.watch()` when you need a `ReadableStream` instead of an async iterator —\n * for example, to `pipeTo()` a `WritableStream` or `pipeThrough()` a `TransformStream`.\n *\n * ```ts\n * const stream = toReadableStream(db.watch('users'));\n * await stream.pipeTo(new WritableStream({ write: (users) => render(users) }));\n * ```\n *\n * The stream closes when the iterable is exhausted or when the stream is cancelled.\n * Pass an `AbortSignal` to `db.watch()` to cancel from outside:\n *\n * ```ts\n * const controller = new AbortController();\n * const stream = toReadableStream(db.watch('users', { signal: controller.signal }));\n * controller.abort(); // closes the stream\n * ```\n */\nexport function toReadableStream<T>(iterable: AsyncIterable<T>): ReadableStream<T> {\n const iter = iterable[Symbol.asyncIterator]();\n\n return new ReadableStream<T>({\n async cancel() {\n await iter.return?.();\n },\n async pull(controller) {\n try {\n const { done, value } = await iter.next();\n\n if (done) {\n controller.close();\n } else {\n controller.enqueue(value);\n }\n } catch (err) {\n controller.error(err);\n }\n },\n });\n}\n"],"mappings":";AAoBA,SAAgB,EAAoB,GAA+C;CACjF,IAAM,IAAO,EAAS,OAAO,cAAc,CAAC;CAE5C,OAAO,IAAI,eAAkB;EAC3B,MAAM,SAAS;GACb,MAAM,EAAK,SAAS;EACtB;EACA,MAAM,KAAK,GAAY;GACrB,IAAI;IACF,IAAM,EAAE,SAAM,aAAU,MAAM,EAAK,KAAK;IAExC,AAAI,IACF,EAAW,MAAM,IAEjB,EAAW,QAAQ,CAAK;GAE5B,SAAS,GAAK;IACZ,EAAW,MAAM,CAAG;GACtB;EACF;CACF,CAAC;AACH"}
@@ -1,2 +0,0 @@
1
- const e=require("./errors.cjs");function t(t,n){if(t.length===0)throw new e.VaultError(`createVersionedCodec: at least one version entry is required`);let r=new Map;for(let n of t){if(!Number.isInteger(n.version)||n.version<0)throw new e.VaultError(`createVersionedCodec: version must be a non-negative integer, got ${String(n.version)}`);if(r.has(n.version))throw new e.VaultError(`createVersionedCodec: duplicate version ${String(n.version)}`);r.set(n.version,n.codec)}if(!r.has(n))throw new e.VaultError(`createVersionedCodec: currentVersion ${String(n)} is not listed in versions`);let i=r.get(n);return{decode(e){if(typeof e!=`object`||!e||!(`__v`in e))return;let t=e,n=t.__v;if(typeof n!=`number`)return;let i=r.get(n);if(i)return i.decode(t.__d)},encode(e,t){return{__d:i.encode(e,t),__v:n}}}}exports.createVersionedCodec=t;
2
- //# sourceMappingURL=versioned-codec.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"versioned-codec.cjs","names":[],"sources":["../src/versioned-codec.ts"],"sourcesContent":["import type { VaultCodec } from './ttl';\n\nimport { VaultError } from './errors';\n\n/**\n * A single version entry in a `createVersionedCodec` definition.\n * `version` must be a non-negative integer. `codec` is the codec responsible for\n * encoding/decoding records that carry this version number.\n */\nexport type CodecVersion = {\n codec: VaultCodec;\n version: number;\n};\n\n/**\n * Creates a versioned codec that prepends a `__v` field to every encoded envelope.\n * When decoding, the `__v` field selects the matching codec from `versions`.\n * This allows safe codec upgrades: old records encoded with a previous codec continue\n * to decode correctly as long as the old codec remains in `versions`.\n *\n * ```ts\n * const v1Codec: VaultCodec = { ... };\n * const v2Codec: VaultCodec = { ... }; // newer, more compact format\n *\n * const codec = createVersionedCodec([\n * { version: 1, codec: v1Codec },\n * { version: 2, codec: v2Codec },\n * ], 2); // write new records with version 2\n *\n * const db = createMemory({ schema, codec });\n * // Old records (version 1) are decoded by v1Codec; new records use v2Codec.\n * ```\n *\n * **Rules:**\n * - `currentVersion` must be one of the versions listed in `versions`.\n * - Version numbers must be unique non-negative integers.\n * - The current version's codec is used for all new writes.\n * - Unrecognised `__v` values cause `decode` to return `undefined` (treated as corrupt).\n * - **Migration note:** records written by any other codec (including `defaultCodec`) lack\n * the `__v` field and will decode as `undefined` — they will be treated as missing/expired.\n * Perform a data migration or clear the store before switching to a versioned codec.\n * - **Secondary index caveat:** the `{ __d, __v }` envelope replaces the default\n * `{ value, expiresAt? }` shape, so IndexedDB secondary indexes (created via `.index()`\n * with keyPath `value.<field>`) silently stop matching. Don't combine a versioned codec\n * with `.index()` on the same table.\n */\nexport function createVersionedCodec(versions: CodecVersion[], currentVersion: number): VaultCodec {\n if (versions.length === 0) {\n throw new VaultError('createVersionedCodec: at least one version entry is required');\n }\n\n const byVersion = new Map<number, VaultCodec>();\n\n for (const entry of versions) {\n if (!Number.isInteger(entry.version) || entry.version < 0) {\n throw new VaultError(\n `createVersionedCodec: version must be a non-negative integer, got ${String(entry.version)}`,\n );\n }\n\n if (byVersion.has(entry.version)) {\n throw new VaultError(`createVersionedCodec: duplicate version ${String(entry.version)}`);\n }\n\n byVersion.set(entry.version, entry.codec);\n }\n\n if (!byVersion.has(currentVersion)) {\n throw new VaultError(`createVersionedCodec: currentVersion ${String(currentVersion)} is not listed in versions`);\n }\n\n const writeCodec = byVersion.get(currentVersion)!;\n\n return {\n decode<T>(raw: unknown): { expiresAt?: number; value: T } | undefined {\n if (typeof raw !== 'object' || raw === null || !('__v' in raw)) {\n return undefined;\n }\n\n const wrapper = raw as { __d: unknown; __v: unknown };\n const version = wrapper.__v;\n\n if (typeof version !== 'number') return undefined;\n\n const codec = byVersion.get(version);\n\n if (!codec) return undefined;\n\n return codec.decode<T>(wrapper.__d);\n },\n\n encode<T>(value: T, expiresAt?: number): unknown {\n return { __d: writeCodec.encode(value, expiresAt), __v: currentVersion };\n },\n };\n}\n"],"mappings":"gCA8CA,SAAgB,EAAqB,EAA0B,EAAoC,CACjG,GAAI,EAAS,SAAW,EACtB,MAAM,IAAI,EAAA,WAAW,8DAA8D,EAGrF,IAAM,EAAY,IAAI,IAEtB,IAAK,IAAM,KAAS,EAAU,CAC5B,GAAI,CAAC,OAAO,UAAU,EAAM,OAAO,GAAK,EAAM,QAAU,EACtD,MAAM,IAAI,EAAA,WACR,qEAAqE,OAAO,EAAM,OAAO,GAC3F,EAGF,GAAI,EAAU,IAAI,EAAM,OAAO,EAC7B,MAAM,IAAI,EAAA,WAAW,2CAA2C,OAAO,EAAM,OAAO,GAAG,EAGzF,EAAU,IAAI,EAAM,QAAS,EAAM,KAAK,CAC1C,CAEA,GAAI,CAAC,EAAU,IAAI,CAAc,EAC/B,MAAM,IAAI,EAAA,WAAW,wCAAwC,OAAO,CAAc,EAAE,2BAA2B,EAGjH,IAAM,EAAa,EAAU,IAAI,CAAc,EAE/C,MAAO,CACL,OAAU,EAA4D,CACpE,GAAI,OAAO,GAAQ,WAAY,GAAgB,EAAE,QAAS,GACxD,OAGF,IAAM,EAAU,EACV,EAAU,EAAQ,IAExB,GAAI,OAAO,GAAY,SAAU,OAEjC,IAAM,EAAQ,EAAU,IAAI,CAAO,EAE9B,KAEL,OAAO,EAAM,OAAU,EAAQ,GAAG,CACpC,EAEA,OAAU,EAAU,EAA6B,CAC/C,MAAO,CAAE,IAAK,EAAW,OAAO,EAAO,CAAS,EAAG,IAAK,CAAe,CACzE,CACF,CACF"}
@@ -1,32 +0,0 @@
1
- import { VaultError as e } from "./errors.js";
2
- //#region src/versioned-codec.ts
3
- function t(t, n) {
4
- if (t.length === 0) throw new e("createVersionedCodec: at least one version entry is required");
5
- let r = /* @__PURE__ */ new Map();
6
- for (let n of t) {
7
- if (!Number.isInteger(n.version) || n.version < 0) throw new e(`createVersionedCodec: version must be a non-negative integer, got ${String(n.version)}`);
8
- if (r.has(n.version)) throw new e(`createVersionedCodec: duplicate version ${String(n.version)}`);
9
- r.set(n.version, n.codec);
10
- }
11
- if (!r.has(n)) throw new e(`createVersionedCodec: currentVersion ${String(n)} is not listed in versions`);
12
- let i = r.get(n);
13
- return {
14
- decode(e) {
15
- if (typeof e != "object" || !e || !("__v" in e)) return;
16
- let t = e, n = t.__v;
17
- if (typeof n != "number") return;
18
- let i = r.get(n);
19
- if (i) return i.decode(t.__d);
20
- },
21
- encode(e, t) {
22
- return {
23
- __d: i.encode(e, t),
24
- __v: n
25
- };
26
- }
27
- };
28
- }
29
- //#endregion
30
- export { t as createVersionedCodec };
31
-
32
- //# sourceMappingURL=versioned-codec.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"versioned-codec.js","names":[],"sources":["../src/versioned-codec.ts"],"sourcesContent":["import type { VaultCodec } from './ttl';\n\nimport { VaultError } from './errors';\n\n/**\n * A single version entry in a `createVersionedCodec` definition.\n * `version` must be a non-negative integer. `codec` is the codec responsible for\n * encoding/decoding records that carry this version number.\n */\nexport type CodecVersion = {\n codec: VaultCodec;\n version: number;\n};\n\n/**\n * Creates a versioned codec that prepends a `__v` field to every encoded envelope.\n * When decoding, the `__v` field selects the matching codec from `versions`.\n * This allows safe codec upgrades: old records encoded with a previous codec continue\n * to decode correctly as long as the old codec remains in `versions`.\n *\n * ```ts\n * const v1Codec: VaultCodec = { ... };\n * const v2Codec: VaultCodec = { ... }; // newer, more compact format\n *\n * const codec = createVersionedCodec([\n * { version: 1, codec: v1Codec },\n * { version: 2, codec: v2Codec },\n * ], 2); // write new records with version 2\n *\n * const db = createMemory({ schema, codec });\n * // Old records (version 1) are decoded by v1Codec; new records use v2Codec.\n * ```\n *\n * **Rules:**\n * - `currentVersion` must be one of the versions listed in `versions`.\n * - Version numbers must be unique non-negative integers.\n * - The current version's codec is used for all new writes.\n * - Unrecognised `__v` values cause `decode` to return `undefined` (treated as corrupt).\n * - **Migration note:** records written by any other codec (including `defaultCodec`) lack\n * the `__v` field and will decode as `undefined` — they will be treated as missing/expired.\n * Perform a data migration or clear the store before switching to a versioned codec.\n * - **Secondary index caveat:** the `{ __d, __v }` envelope replaces the default\n * `{ value, expiresAt? }` shape, so IndexedDB secondary indexes (created via `.index()`\n * with keyPath `value.<field>`) silently stop matching. Don't combine a versioned codec\n * with `.index()` on the same table.\n */\nexport function createVersionedCodec(versions: CodecVersion[], currentVersion: number): VaultCodec {\n if (versions.length === 0) {\n throw new VaultError('createVersionedCodec: at least one version entry is required');\n }\n\n const byVersion = new Map<number, VaultCodec>();\n\n for (const entry of versions) {\n if (!Number.isInteger(entry.version) || entry.version < 0) {\n throw new VaultError(\n `createVersionedCodec: version must be a non-negative integer, got ${String(entry.version)}`,\n );\n }\n\n if (byVersion.has(entry.version)) {\n throw new VaultError(`createVersionedCodec: duplicate version ${String(entry.version)}`);\n }\n\n byVersion.set(entry.version, entry.codec);\n }\n\n if (!byVersion.has(currentVersion)) {\n throw new VaultError(`createVersionedCodec: currentVersion ${String(currentVersion)} is not listed in versions`);\n }\n\n const writeCodec = byVersion.get(currentVersion)!;\n\n return {\n decode<T>(raw: unknown): { expiresAt?: number; value: T } | undefined {\n if (typeof raw !== 'object' || raw === null || !('__v' in raw)) {\n return undefined;\n }\n\n const wrapper = raw as { __d: unknown; __v: unknown };\n const version = wrapper.__v;\n\n if (typeof version !== 'number') return undefined;\n\n const codec = byVersion.get(version);\n\n if (!codec) return undefined;\n\n return codec.decode<T>(wrapper.__d);\n },\n\n encode<T>(value: T, expiresAt?: number): unknown {\n return { __d: writeCodec.encode(value, expiresAt), __v: currentVersion };\n },\n };\n}\n"],"mappings":";;AA8CA,SAAgB,EAAqB,GAA0B,GAAoC;CACjG,IAAI,EAAS,WAAW,GACtB,MAAM,IAAI,EAAW,8DAA8D;CAGrF,IAAM,oBAAY,IAAI,IAAwB;CAE9C,KAAK,IAAM,KAAS,GAAU;EAC5B,IAAI,CAAC,OAAO,UAAU,EAAM,OAAO,KAAK,EAAM,UAAU,GACtD,MAAM,IAAI,EACR,qEAAqE,OAAO,EAAM,OAAO,GAC3F;EAGF,IAAI,EAAU,IAAI,EAAM,OAAO,GAC7B,MAAM,IAAI,EAAW,2CAA2C,OAAO,EAAM,OAAO,GAAG;EAGzF,EAAU,IAAI,EAAM,SAAS,EAAM,KAAK;CAC1C;CAEA,IAAI,CAAC,EAAU,IAAI,CAAc,GAC/B,MAAM,IAAI,EAAW,wCAAwC,OAAO,CAAc,EAAE,2BAA2B;CAGjH,IAAM,IAAa,EAAU,IAAI,CAAc;CAE/C,OAAO;EACL,OAAU,GAA4D;GACpE,IAAI,OAAO,KAAQ,aAAY,KAAgB,EAAE,SAAS,IACxD;GAGF,IAAM,IAAU,GACV,IAAU,EAAQ;GAExB,IAAI,OAAO,KAAY,UAAU;GAEjC,IAAM,IAAQ,EAAU,IAAI,CAAO;GAE9B,OAEL,OAAO,EAAM,OAAU,EAAQ,GAAG;EACpC;EAEA,OAAU,GAAU,GAA6B;GAC/C,OAAO;IAAE,KAAK,EAAW,OAAO,GAAO,CAAS;IAAG,KAAK;GAAe;EACzE;CACF;AACF"}