@vielzeug/vault 3.0.0 → 3.0.3

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 (78) hide show
  1. package/dist/adapter-core.cjs +1 -1
  2. package/dist/adapter-core.cjs.map +1 -1
  3. package/dist/adapter-core.d.ts +5 -34
  4. package/dist/adapter-core.d.ts.map +1 -1
  5. package/dist/adapter-core.js +1 -282
  6. package/dist/adapter-core.js.map +1 -1
  7. package/dist/adapters/indexeddb.cjs +1 -1
  8. package/dist/adapters/indexeddb.cjs.map +1 -1
  9. package/dist/adapters/indexeddb.d.ts +5 -35
  10. package/dist/adapters/indexeddb.d.ts.map +1 -1
  11. package/dist/adapters/indexeddb.js +1 -365
  12. package/dist/adapters/indexeddb.js.map +1 -1
  13. package/dist/adapters/memory.cjs +1 -1
  14. package/dist/adapters/memory.cjs.map +1 -1
  15. package/dist/adapters/memory.d.ts +8 -3
  16. package/dist/adapters/memory.d.ts.map +1 -1
  17. package/dist/adapters/memory.js +1 -60
  18. package/dist/adapters/memory.js.map +1 -1
  19. package/dist/adapters/sqlite.cjs +14 -32
  20. package/dist/adapters/sqlite.cjs.map +1 -1
  21. package/dist/adapters/sqlite.d.ts.map +1 -1
  22. package/dist/adapters/sqlite.js +14 -409
  23. package/dist/adapters/sqlite.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 +0 -6
  27. package/dist/adapters/webstorage.d.ts.map +1 -1
  28. package/dist/adapters/webstorage.js +1 -160
  29. package/dist/adapters/webstorage.js.map +1 -1
  30. package/dist/codec.cjs +1 -1
  31. package/dist/codec.cjs.map +1 -1
  32. package/dist/codec.js +1 -5
  33. package/dist/codec.js.map +1 -1
  34. package/dist/errors.cjs +1 -1
  35. package/dist/errors.cjs.map +1 -1
  36. package/dist/errors.d.ts +0 -5
  37. package/dist/errors.d.ts.map +1 -1
  38. package/dist/errors.js +1 -21
  39. package/dist/errors.js.map +1 -1
  40. package/dist/index.cjs +1 -1
  41. package/dist/index.d.ts +1 -3
  42. package/dist/index.d.ts.map +1 -1
  43. package/dist/index.js +1 -5
  44. package/dist/indexeddb.cjs +1 -1
  45. package/dist/indexeddb.d.ts +2 -2
  46. package/dist/indexeddb.d.ts.map +1 -1
  47. package/dist/indexeddb.js +1 -2
  48. package/dist/internal.cjs +1 -1
  49. package/dist/internal.cjs.map +1 -1
  50. package/dist/internal.js +1 -72
  51. package/dist/internal.js.map +1 -1
  52. package/dist/local-storage.js +1 -2
  53. package/dist/memory.js +1 -2
  54. package/dist/session-storage.js +1 -2
  55. package/dist/sqlite.js +1 -2
  56. package/dist/ttl.cjs +1 -1
  57. package/dist/ttl.cjs.map +1 -1
  58. package/dist/ttl.js +1 -24
  59. package/dist/ttl.js.map +1 -1
  60. package/dist/types.cjs +1 -1
  61. package/dist/types.cjs.map +1 -1
  62. package/dist/types.d.ts +0 -2
  63. package/dist/types.d.ts.map +1 -1
  64. package/dist/types.js +1 -27
  65. package/dist/types.js.map +1 -1
  66. package/dist/vault.cjs +1 -1
  67. package/dist/vault.cjs.map +1 -1
  68. package/dist/vault.iife.js +1 -1
  69. package/dist/vault.iife.js.map +1 -1
  70. package/dist/vault.js +1 -1
  71. package/dist/vault.js.map +1 -1
  72. package/package.json +6 -6
  73. package/dist/query.cjs +0 -2
  74. package/dist/query.cjs.map +0 -1
  75. package/dist/query.d.ts +0 -23
  76. package/dist/query.d.ts.map +0 -1
  77. package/dist/query.js +0 -54
  78. package/dist/query.js.map +0 -1
package/dist/internal.js CHANGED
@@ -1,73 +1,2 @@
1
- import { VaultDisposedError as e, VaultError as t } from "./errors.js";
2
- //#region src/internal.ts
3
- var n = "\0";
4
- function r(e) {
5
- if (typeof e == "number") {
6
- if (!Number.isFinite(e)) throw new t(`primary key must be a finite number, received ${String(e)}`);
7
- return `n:${String(e)}`;
8
- }
9
- return `s:${encodeURIComponent(e)}`;
10
- }
11
- function i(e) {
12
- return `${encodeURIComponent(e)}${n}`;
13
- }
14
- function a(e, t, i) {
15
- return `${encodeURIComponent(e)}${n}${encodeURIComponent(t)}${n}${r(i)}`;
16
- }
17
- function o(e, t) {
18
- return `${encodeURIComponent(e)}${n}${encodeURIComponent(t)}${n}`;
19
- }
20
- function s(e, t) {
21
- if (!t) return;
22
- let r = i(e);
23
- if (!t.startsWith(r)) return;
24
- let a = t.slice(r.length), o = a.indexOf(n);
25
- if (o !== -1) try {
26
- return decodeURIComponent(a.slice(0, o));
27
- } catch {
28
- return;
29
- }
30
- }
31
- function c(t) {
32
- let n = /* @__PURE__ */ new Map(), r = /* @__PURE__ */ new Map(), i = !1, a = (e) => {
33
- if (i) return;
34
- let a = (r.get(e) ?? 0) + 1;
35
- r.set(e, a);
36
- let o = n.get(e);
37
- o && o.size !== 0 && t(e).then((t) => {
38
- if (i || r.get(e) !== a) return;
39
- let o = n.get(e);
40
- if (o && o.size !== 0) for (let e of o) try {
41
- e(t);
42
- } catch {}
43
- }).catch(() => {});
44
- };
45
- return {
46
- dispose: () => {
47
- i = !0, n.clear(), r.clear();
48
- },
49
- notify: a,
50
- observe: (t, r, { immediate: o = !0, signal: s } = {}) => {
51
- if (i) throw new e("observer hub is disposed");
52
- if (s?.aborted) return () => {};
53
- let c = r, l = n.get(t) ?? /* @__PURE__ */ new Set();
54
- n.set(t, l), l.add(c), o && a(t);
55
- let u = () => {
56
- s?.removeEventListener("abort", u);
57
- let e = n.get(t);
58
- e && (e.delete(c), e.size === 0 && n.delete(t));
59
- };
60
- return s?.addEventListener("abort", u, { once: !0 }), u;
61
- }
62
- };
63
- }
64
- function l(e, n, r) {
65
- let i = String(e[n].key), a = r[i];
66
- if (typeof a != "number" && typeof a != "string") throw new t(`record in table "${String(n)}" must have a string or finite-number key at "${i}"`);
67
- if (typeof a == "number" && !Number.isFinite(a)) throw new t(`record in table "${String(n)}" must have a finite-number key at "${i}"`);
68
- return a;
69
- }
70
- //#endregion
71
- export { c as createObserverHub, s as decodeStorageTableFromKey, i as encodeDbPrefix, a as encodeStorageKey, o as encodeStorageTablePrefix, r as encodeVaultKey, l as getRecordKey };
72
-
1
+ import{VaultDisposedError as e,VaultError as t}from"./errors.js";var n=`\0`;function encodeVaultKey(e){if(typeof e==`number`){if(!Number.isFinite(e))throw new t(`primary key must be a finite number, received ${String(e)}`);return`n:${String(e)}`}return`s:${encodeURIComponent(e)}`}function encodeDbPrefix(e){return`${encodeURIComponent(e)}${n}`}function encodeStorageKey(e,t,r){return`${encodeURIComponent(e)}${n}${encodeURIComponent(t)}${n}${encodeVaultKey(r)}`}function encodeStorageTablePrefix(e,t){return`${encodeURIComponent(e)}${n}${encodeURIComponent(t)}${n}`}function decodeStorageTableFromKey(e,t){if(!t)return;let r=encodeDbPrefix(e);if(!t.startsWith(r))return;let i=t.slice(r.length),a=i.indexOf(n);if(a!==-1)try{return decodeURIComponent(i.slice(0,a))}catch{return}}function createObserverHub(t){let n=new Map,r=new Map,i=!1,notify=e=>{if(i)return;let a=(r.get(e)??0)+1;r.set(e,a);let o=n.get(e);o&&o.size!==0&&t(e).then(t=>{if(i||r.get(e)!==a)return;let o=n.get(e);if(o&&o.size!==0)for(let e of o)try{e(t)}catch{}}).catch(()=>{})},observe=(t,r,{immediate:a=!0,signal:o}={})=>{if(i)throw new e(`observer hub is disposed`);if(o?.aborted)return()=>{};let s=r,c=n.get(t)??new Set;n.set(t,c),c.add(s),a&&notify(t);let stop=()=>{o?.removeEventListener(`abort`,stop);let e=n.get(t);e&&(e.delete(s),e.size===0&&n.delete(t))};return o?.addEventListener(`abort`,stop,{once:!0}),stop};return{dispose:()=>{i=!0,n.clear(),r.clear()},notify,observe}}function getRecordKey(e,n,r){let i=String(e[n].key),a=r[i];if(typeof a!=`number`&&typeof a!=`string`)throw new t(`record in table "${String(n)}" must have a string or finite-number key at "${i}"`);if(typeof a==`number`&&!Number.isFinite(a))throw new t(`record in table "${String(n)}" must have a finite-number key at "${i}"`);return a}export{createObserverHub,decodeStorageTableFromKey,encodeDbPrefix,encodeStorageKey,encodeStorageTablePrefix,encodeVaultKey,getRecordKey};
73
2
  //# sourceMappingURL=internal.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"internal.js","names":[],"sources":["../src/internal.ts"],"sourcesContent":["import { VaultDisposedError, VaultError } from './errors';\nimport type { AnySchema, KeyOf, RecordOf, VaultKey } from './types';\n\ntype ObserverListener<T> = (records: T[]) => void;\n\nconst SEP = '\\x00';\n\n/**\n * Type-tagged keys make `1` and `'1'` distinct in string-keyed adapters while\n * keeping the same portable primary-key contract as IndexedDB.\n */\nexport function encodeVaultKey(key: VaultKey): string {\n if (typeof key === 'number') {\n if (!Number.isFinite(key)) throw new VaultError(`primary key must be a finite number, received ${String(key)}`);\n\n return `n:${String(key)}`;\n }\n\n return `s:${encodeURIComponent(key)}`;\n}\n\nexport function encodeDbPrefix(dbName: string): string {\n return `${encodeURIComponent(dbName)}${SEP}`;\n}\n\nexport function encodeStorageKey(dbName: string, table: string, key: VaultKey): string {\n return `${encodeURIComponent(dbName)}${SEP}${encodeURIComponent(table)}${SEP}${encodeVaultKey(key)}`;\n}\n\nexport function encodeStorageTablePrefix(dbName: string, table: string): string {\n return `${encodeURIComponent(dbName)}${SEP}${encodeURIComponent(table)}${SEP}`;\n}\n\nexport function decodeStorageTableFromKey(dbName: string, storageKey: string | null): string | undefined {\n if (!storageKey) return undefined;\n\n const prefix = encodeDbPrefix(dbName);\n\n if (!storageKey.startsWith(prefix)) return undefined;\n\n const tail = storageKey.slice(prefix.length);\n const end = tail.indexOf(SEP);\n\n if (end === -1) return undefined;\n\n try {\n return decodeURIComponent(tail.slice(0, end));\n } catch {\n return undefined;\n }\n}\n\n/** `observe()` is Vault's single reactivity primitive: a snapshot now, then on mutations. */\nexport function createObserverHub<S extends AnySchema>(\n getAll: <K extends keyof S & string>(table: K) => Promise<RecordOf<S, K>[]>,\n) {\n const observers = new Map<string, Set<ObserverListener<unknown>>>();\n const revisions = new Map<string, number>();\n let disposed = false;\n\n const notify = <K extends keyof S & string>(table: K): void => {\n if (disposed) return;\n\n const revision = (revisions.get(table) ?? 0) + 1;\n revisions.set(table, revision);\n const listeners = observers.get(table);\n\n if (!listeners || listeners.size === 0) return;\n\n void getAll(table)\n .then((records) => {\n if (disposed || revisions.get(table) !== revision) return;\n\n const current = observers.get(table);\n\n if (!current || current.size === 0) return;\n\n for (const listener of current) {\n try {\n listener(records as unknown[]);\n } catch {\n /* observer listener errors are intentionally swallowed */\n }\n }\n })\n .catch(() => {\n /* observer source errors are intentionally swallowed */\n });\n };\n\n const observe = <K extends keyof S & string>(\n table: K,\n listener: (records: RecordOf<S, K>[]) => void,\n { immediate = true, signal }: { immediate?: boolean; signal?: AbortSignal } = {},\n ): (() => void) => {\n if (disposed) throw new VaultDisposedError('observer hub is disposed');\n\n if (signal?.aborted) return () => {};\n\n const wrapped = listener as ObserverListener<unknown>;\n const listeners = observers.get(table) ?? new Set<ObserverListener<unknown>>();\n\n observers.set(table, listeners);\n listeners.add(wrapped);\n\n if (immediate) notify(table);\n\n const stop = (): void => {\n signal?.removeEventListener('abort', stop);\n const current = observers.get(table);\n\n if (!current) return;\n\n current.delete(wrapped);\n\n if (current.size === 0) observers.delete(table);\n };\n\n signal?.addEventListener('abort', stop, { once: true });\n\n return stop;\n };\n\n return {\n dispose: () => {\n disposed = true;\n observers.clear();\n revisions.clear();\n },\n notify,\n observe,\n };\n}\n\nexport function getRecordKey<S extends AnySchema, K extends keyof S>(\n schema: S,\n table: K,\n value: RecordOf<S, K>,\n): KeyOf<S, K> {\n const keyField = String(schema[table].key);\n const keyValue = (value as Record<string, unknown>)[keyField];\n\n if (typeof keyValue !== 'number' && typeof keyValue !== 'string') {\n throw new VaultError(`record in table \"${String(table)}\" must have a string or finite-number key at \"${keyField}\"`);\n }\n\n if (typeof keyValue === 'number' && !Number.isFinite(keyValue)) {\n throw new VaultError(`record in table \"${String(table)}\" must have a finite-number key at \"${keyField}\"`);\n }\n\n return keyValue as KeyOf<S, K>;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"internal.js","names":[],"sources":["../src/internal.ts"],"sourcesContent":["import { VaultDisposedError, VaultError } from './errors';\nimport type { AnySchema, KeyOf, RecordOf, VaultKey } from './types';\n\ntype ObserverListener<T> = (records: T[]) => void;\n\nconst SEP = '\\x00';\n\n/**\n * Type-tagged keys make `1` and `'1'` distinct in string-keyed adapters while\n * keeping the same portable primary-key contract as IndexedDB.\n */\nexport function encodeVaultKey(key: VaultKey): string {\n if (typeof key === 'number') {\n if (!Number.isFinite(key)) throw new VaultError(`primary key must be a finite number, received ${String(key)}`);\n\n return `n:${String(key)}`;\n }\n\n return `s:${encodeURIComponent(key)}`;\n}\n\nexport function encodeDbPrefix(dbName: string): string {\n return `${encodeURIComponent(dbName)}${SEP}`;\n}\n\nexport function encodeStorageKey(dbName: string, table: string, key: VaultKey): string {\n return `${encodeURIComponent(dbName)}${SEP}${encodeURIComponent(table)}${SEP}${encodeVaultKey(key)}`;\n}\n\nexport function encodeStorageTablePrefix(dbName: string, table: string): string {\n return `${encodeURIComponent(dbName)}${SEP}${encodeURIComponent(table)}${SEP}`;\n}\n\nexport function decodeStorageTableFromKey(dbName: string, storageKey: string | null): string | undefined {\n if (!storageKey) return undefined;\n\n const prefix = encodeDbPrefix(dbName);\n\n if (!storageKey.startsWith(prefix)) return undefined;\n\n const tail = storageKey.slice(prefix.length);\n const end = tail.indexOf(SEP);\n\n if (end === -1) return undefined;\n\n try {\n return decodeURIComponent(tail.slice(0, end));\n } catch {\n return undefined;\n }\n}\n\n/** `observe()` is Vault's single reactivity primitive: a snapshot now, then on mutations. */\nexport function createObserverHub<S extends AnySchema>(\n getAll: <K extends keyof S & string>(table: K) => Promise<RecordOf<S, K>[]>,\n) {\n const observers = new Map<string, Set<ObserverListener<unknown>>>();\n const revisions = new Map<string, number>();\n let disposed = false;\n\n const notify = <K extends keyof S & string>(table: K): void => {\n if (disposed) return;\n\n const revision = (revisions.get(table) ?? 0) + 1;\n revisions.set(table, revision);\n const listeners = observers.get(table);\n\n if (!listeners || listeners.size === 0) return;\n\n void getAll(table)\n .then((records) => {\n if (disposed || revisions.get(table) !== revision) return;\n\n const current = observers.get(table);\n\n if (!current || current.size === 0) return;\n\n for (const listener of current) {\n try {\n listener(records as unknown[]);\n } catch {\n /* observer listener errors are intentionally swallowed */\n }\n }\n })\n .catch(() => {\n /* observer source errors are intentionally swallowed */\n });\n };\n\n const observe = <K extends keyof S & string>(\n table: K,\n listener: (records: RecordOf<S, K>[]) => void,\n { immediate = true, signal }: { immediate?: boolean; signal?: AbortSignal } = {},\n ): (() => void) => {\n if (disposed) throw new VaultDisposedError('observer hub is disposed');\n\n if (signal?.aborted) return () => {};\n\n const wrapped = listener as ObserverListener<unknown>;\n const listeners = observers.get(table) ?? new Set<ObserverListener<unknown>>();\n\n observers.set(table, listeners);\n listeners.add(wrapped);\n\n if (immediate) notify(table);\n\n const stop = (): void => {\n signal?.removeEventListener('abort', stop);\n const current = observers.get(table);\n\n if (!current) return;\n\n current.delete(wrapped);\n\n if (current.size === 0) observers.delete(table);\n };\n\n signal?.addEventListener('abort', stop, { once: true });\n\n return stop;\n };\n\n return {\n dispose: () => {\n disposed = true;\n observers.clear();\n revisions.clear();\n },\n notify,\n observe,\n };\n}\n\nexport function getRecordKey<S extends AnySchema, K extends keyof S>(\n schema: S,\n table: K,\n value: RecordOf<S, K>,\n): KeyOf<S, K> {\n const keyField = String(schema[table].key);\n const keyValue = (value as Record<string, unknown>)[keyField];\n\n if (typeof keyValue !== 'number' && typeof keyValue !== 'string') {\n throw new VaultError(`record in table \"${String(table)}\" must have a string or finite-number key at \"${keyField}\"`);\n }\n\n if (typeof keyValue === 'number' && !Number.isFinite(keyValue)) {\n throw new VaultError(`record in table \"${String(table)}\" must have a finite-number key at \"${keyField}\"`);\n }\n\n return keyValue as KeyOf<S, K>;\n}\n"],"mappings":"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"}
@@ -1,2 +1 @@
1
- import { createLocalStorage as e } from "./adapters/webstorage.js";
2
- export { e as createLocalStorage };
1
+ import{createLocalStorage as e}from"./adapters/webstorage.js";export{e as createLocalStorage};
package/dist/memory.js CHANGED
@@ -1,2 +1 @@
1
- import { createMemory as e } from "./adapters/memory.js";
2
- export { e as createMemory };
1
+ import{createMemory as e}from"./adapters/memory.js";export{e as createMemory};
@@ -1,2 +1 @@
1
- import { createSessionStorage as e } from "./adapters/webstorage.js";
2
- export { e as createSessionStorage };
1
+ import{createSessionStorage as e}from"./adapters/webstorage.js";export{e as createSessionStorage};
package/dist/sqlite.js CHANGED
@@ -1,2 +1 @@
1
- import { createSQLite as e } from "./adapters/sqlite.js";
2
- export { e as createSQLite };
1
+ import{createSQLite as e}from"./adapters/sqlite.js";export{e as createSQLite};
package/dist/ttl.cjs CHANGED
@@ -1,2 +1,2 @@
1
- const e=require("./errors.cjs");var t={days:e=>r(e*864e5,`ttl.days`),hours:e=>r(e*36e5,`ttl.hours`),minutes:e=>r(e*6e4,`ttl.minutes`),ms:e=>r(e,`ttl.ms`),seconds:e=>r(e*1e3,`ttl.seconds`)};function n(e){return e!==void 0&&Date.now()>=e}function r(t,n){if(!Number.isFinite(t)||t<=0)throw new e.VaultError(`${n} expected a finite positive number, received ${String(t)}`);return t}function i(e){if(typeof e!=`object`||!e||!(`value`in e))return;let t=e;if(t.expiresAt===void 0||typeof t.expiresAt==`number`&&Number.isFinite(t.expiresAt))return t}exports.assertPositiveFinite=r,exports.isExpired=n,exports.parseStored=i,exports.ttl=t;
1
+ const e=require("./errors.cjs");var t={days:e=>assertPositiveFinite(e*864e5,`ttl.days`),hours:e=>assertPositiveFinite(e*36e5,`ttl.hours`),minutes:e=>assertPositiveFinite(e*6e4,`ttl.minutes`),ms:e=>assertPositiveFinite(e,`ttl.ms`),seconds:e=>assertPositiveFinite(e*1e3,`ttl.seconds`)};function isExpired(e){return e!==void 0&&Date.now()>=e}function assertPositiveFinite(t,n){if(!Number.isFinite(t)||t<=0)throw new e.VaultError(`${n} expected a finite positive number, received ${String(t)}`);return t}function parseStored(e){if(typeof e!=`object`||!e||!(`value`in e))return;let t=e;if(t.expiresAt===void 0||typeof t.expiresAt==`number`&&Number.isFinite(t.expiresAt))return t}exports.assertPositiveFinite=assertPositiveFinite,exports.isExpired=isExpired,exports.parseStored=parseStored,exports.ttl=t;
2
2
  //# sourceMappingURL=ttl.cjs.map
package/dist/ttl.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"ttl.cjs","names":[],"sources":["../src/ttl.ts"],"sourcesContent":["import { VaultError } from './errors';\n\n/** Duration helpers that produce finite, positive millisecond values. */\nexport const ttl = {\n days: (n: number) => assertPositiveFinite(n * 86_400_000, 'ttl.days'),\n hours: (n: number) => assertPositiveFinite(n * 3_600_000, 'ttl.hours'),\n minutes: (n: number) => assertPositiveFinite(n * 60_000, 'ttl.minutes'),\n ms: (n: number) => assertPositiveFinite(n, 'ttl.ms'),\n seconds: (n: number) => assertPositiveFinite(n * 1000, 'ttl.seconds'),\n} as const;\n\n/** Fixed storage envelope shared by every adapter, so data and indexes stay portable. */\nexport type StoredRecord<T> = { expiresAt?: number; value: T };\n\nexport function isExpired(expiresAt: number | undefined): boolean {\n return expiresAt !== undefined && Date.now() >= expiresAt;\n}\n\n/** Throws when `ttlMs` is not a finite, positive number. Returns it unchanged otherwise. */\nexport function assertPositiveFinite(ttlMs: number, source: string): number {\n if (!Number.isFinite(ttlMs) || ttlMs <= 0) {\n throw new VaultError(`${source} expected a finite positive number, received ${String(ttlMs)}`);\n }\n\n return ttlMs;\n}\n\nexport function parseStored<T>(raw: unknown): StoredRecord<T> | undefined {\n if (typeof raw !== 'object' || raw === null || !('value' in raw)) return undefined;\n\n const record = raw as { expiresAt?: unknown; value: unknown };\n\n if (record.expiresAt !== undefined && (typeof record.expiresAt !== 'number' || !Number.isFinite(record.expiresAt))) {\n return undefined;\n }\n\n return record as StoredRecord<T>;\n}\n"],"mappings":"gCAGA,IAAa,EAAM,CACjB,KAAO,GAAc,EAAqB,EAAI,MAAY,UAAU,EACpE,MAAQ,GAAc,EAAqB,EAAI,KAAW,WAAW,EACrE,QAAU,GAAc,EAAqB,EAAI,IAAQ,aAAa,EACtE,GAAK,GAAc,EAAqB,EAAG,QAAQ,EACnD,QAAU,GAAc,EAAqB,EAAI,IAAM,aAAa,CACtE,EAKA,SAAgB,EAAU,EAAwC,CAChE,OAAO,IAAc,IAAA,IAAa,KAAK,IAAI,GAAK,CAClD,CAGA,SAAgB,EAAqB,EAAe,EAAwB,CAC1E,GAAI,CAAC,OAAO,SAAS,CAAK,GAAK,GAAS,EACtC,MAAM,IAAI,EAAA,WAAW,GAAG,EAAO,+CAA+C,OAAO,CAAK,GAAG,EAG/F,OAAO,CACT,CAEA,SAAgB,EAAe,EAA2C,CACxE,GAAI,OAAO,GAAQ,WAAY,GAAgB,EAAE,UAAW,GAAM,OAElE,IAAM,EAAS,EAEX,KAAO,YAAc,IAAA,IAAc,OAAO,EAAO,WAAc,UAAa,OAAO,SAAS,EAAO,SAAS,EAIhH,OAAO,CACT"}
1
+ {"version":3,"file":"ttl.cjs","names":[],"sources":["../src/ttl.ts"],"sourcesContent":["import { VaultError } from './errors';\n\n/** Duration helpers that produce finite, positive millisecond values. */\nexport const ttl = {\n days: (n: number) => assertPositiveFinite(n * 86_400_000, 'ttl.days'),\n hours: (n: number) => assertPositiveFinite(n * 3_600_000, 'ttl.hours'),\n minutes: (n: number) => assertPositiveFinite(n * 60_000, 'ttl.minutes'),\n ms: (n: number) => assertPositiveFinite(n, 'ttl.ms'),\n seconds: (n: number) => assertPositiveFinite(n * 1000, 'ttl.seconds'),\n} as const;\n\n/** Fixed storage envelope shared by every adapter, so data and indexes stay portable. */\nexport type StoredRecord<T> = { expiresAt?: number; value: T };\n\nexport function isExpired(expiresAt: number | undefined): boolean {\n return expiresAt !== undefined && Date.now() >= expiresAt;\n}\n\n/** Throws when `ttlMs` is not a finite, positive number. Returns it unchanged otherwise. */\nexport function assertPositiveFinite(ttlMs: number, source: string): number {\n if (!Number.isFinite(ttlMs) || ttlMs <= 0) {\n throw new VaultError(`${source} expected a finite positive number, received ${String(ttlMs)}`);\n }\n\n return ttlMs;\n}\n\nexport function parseStored<T>(raw: unknown): StoredRecord<T> | undefined {\n if (typeof raw !== 'object' || raw === null || !('value' in raw)) return undefined;\n\n const record = raw as { expiresAt?: unknown; value: unknown };\n\n if (record.expiresAt !== undefined && (typeof record.expiresAt !== 'number' || !Number.isFinite(record.expiresAt))) {\n return undefined;\n }\n\n return record as StoredRecord<T>;\n}\n"],"mappings":"gCAGA,IAAa,EAAM,CACjB,KAAO,GAAc,qBAAqB,EAAI,MAAY,UAAU,EACpE,MAAQ,GAAc,qBAAqB,EAAI,KAAW,WAAW,EACrE,QAAU,GAAc,qBAAqB,EAAI,IAAQ,aAAa,EACtE,GAAK,GAAc,qBAAqB,EAAG,QAAQ,EACnD,QAAU,GAAc,qBAAqB,EAAI,IAAM,aAAa,CACtE,EAKA,SAAgB,UAAU,EAAwC,CAChE,OAAO,IAAc,IAAA,IAAa,KAAK,IAAI,GAAK,CAClD,CAGA,SAAgB,qBAAqB,EAAe,EAAwB,CAC1E,GAAI,CAAC,OAAO,SAAS,CAAK,GAAK,GAAS,EACtC,MAAM,IAAI,EAAA,WAAW,GAAG,EAAO,+CAA+C,OAAO,CAAK,GAAG,EAG/F,OAAO,CACT,CAEA,SAAgB,YAAe,EAA2C,CACxE,GAAI,OAAO,GAAQ,WAAY,GAAgB,EAAE,UAAW,GAAM,OAElE,IAAM,EAAS,EAEX,KAAO,YAAc,IAAA,IAAc,OAAO,EAAO,WAAc,UAAa,OAAO,SAAS,EAAO,SAAS,EAIhH,OAAO,CACT"}
package/dist/ttl.js CHANGED
@@ -1,25 +1,2 @@
1
- import { VaultError as e } from "./errors.js";
2
- //#region src/ttl.ts
3
- var t = {
4
- days: (e) => r(e * 864e5, "ttl.days"),
5
- hours: (e) => r(e * 36e5, "ttl.hours"),
6
- minutes: (e) => r(e * 6e4, "ttl.minutes"),
7
- ms: (e) => r(e, "ttl.ms"),
8
- seconds: (e) => r(e * 1e3, "ttl.seconds")
9
- };
10
- function n(e) {
11
- return e !== void 0 && Date.now() >= e;
12
- }
13
- function r(t, n) {
14
- if (!Number.isFinite(t) || t <= 0) throw new e(`${n} expected a finite positive number, received ${String(t)}`);
15
- return t;
16
- }
17
- function i(e) {
18
- if (typeof e != "object" || !e || !("value" in e)) return;
19
- let t = e;
20
- if (t.expiresAt === void 0 || typeof t.expiresAt == "number" && Number.isFinite(t.expiresAt)) return t;
21
- }
22
- //#endregion
23
- export { r as assertPositiveFinite, n as isExpired, i as parseStored, t as ttl };
24
-
1
+ import{VaultError as e}from"./errors.js";var t={days:e=>assertPositiveFinite(e*864e5,`ttl.days`),hours:e=>assertPositiveFinite(e*36e5,`ttl.hours`),minutes:e=>assertPositiveFinite(e*6e4,`ttl.minutes`),ms:e=>assertPositiveFinite(e,`ttl.ms`),seconds:e=>assertPositiveFinite(e*1e3,`ttl.seconds`)};function isExpired(e){return e!==void 0&&Date.now()>=e}function assertPositiveFinite(t,n){if(!Number.isFinite(t)||t<=0)throw new e(`${n} expected a finite positive number, received ${String(t)}`);return t}function parseStored(e){if(typeof e!=`object`||!e||!(`value`in e))return;let t=e;if(t.expiresAt===void 0||typeof t.expiresAt==`number`&&Number.isFinite(t.expiresAt))return t}export{assertPositiveFinite,isExpired,parseStored,t as ttl};
25
2
  //# sourceMappingURL=ttl.js.map
package/dist/ttl.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"ttl.js","names":[],"sources":["../src/ttl.ts"],"sourcesContent":["import { VaultError } from './errors';\n\n/** Duration helpers that produce finite, positive millisecond values. */\nexport const ttl = {\n days: (n: number) => assertPositiveFinite(n * 86_400_000, 'ttl.days'),\n hours: (n: number) => assertPositiveFinite(n * 3_600_000, 'ttl.hours'),\n minutes: (n: number) => assertPositiveFinite(n * 60_000, 'ttl.minutes'),\n ms: (n: number) => assertPositiveFinite(n, 'ttl.ms'),\n seconds: (n: number) => assertPositiveFinite(n * 1000, 'ttl.seconds'),\n} as const;\n\n/** Fixed storage envelope shared by every adapter, so data and indexes stay portable. */\nexport type StoredRecord<T> = { expiresAt?: number; value: T };\n\nexport function isExpired(expiresAt: number | undefined): boolean {\n return expiresAt !== undefined && Date.now() >= expiresAt;\n}\n\n/** Throws when `ttlMs` is not a finite, positive number. Returns it unchanged otherwise. */\nexport function assertPositiveFinite(ttlMs: number, source: string): number {\n if (!Number.isFinite(ttlMs) || ttlMs <= 0) {\n throw new VaultError(`${source} expected a finite positive number, received ${String(ttlMs)}`);\n }\n\n return ttlMs;\n}\n\nexport function parseStored<T>(raw: unknown): StoredRecord<T> | undefined {\n if (typeof raw !== 'object' || raw === null || !('value' in raw)) return undefined;\n\n const record = raw as { expiresAt?: unknown; value: unknown };\n\n if (record.expiresAt !== undefined && (typeof record.expiresAt !== 'number' || !Number.isFinite(record.expiresAt))) {\n return undefined;\n }\n\n return record as StoredRecord<T>;\n}\n"],"mappings":";;AAGA,IAAa,IAAM;CACjB,OAAO,MAAc,EAAqB,IAAI,OAAY,UAAU;CACpE,QAAQ,MAAc,EAAqB,IAAI,MAAW,WAAW;CACrE,UAAU,MAAc,EAAqB,IAAI,KAAQ,aAAa;CACtE,KAAK,MAAc,EAAqB,GAAG,QAAQ;CACnD,UAAU,MAAc,EAAqB,IAAI,KAAM,aAAa;AACtE;AAKA,SAAgB,EAAU,GAAwC;CAChE,OAAO,MAAc,KAAA,KAAa,KAAK,IAAI,KAAK;AAClD;AAGA,SAAgB,EAAqB,GAAe,GAAwB;CAC1E,IAAI,CAAC,OAAO,SAAS,CAAK,KAAK,KAAS,GACtC,MAAM,IAAI,EAAW,GAAG,EAAO,+CAA+C,OAAO,CAAK,GAAG;CAG/F,OAAO;AACT;AAEA,SAAgB,EAAe,GAA2C;CACxE,IAAI,OAAO,KAAQ,aAAY,KAAgB,EAAE,WAAW,IAAM;CAElE,IAAM,IAAS;CAEX,MAAO,cAAc,KAAA,KAAc,OAAO,EAAO,aAAc,YAAa,OAAO,SAAS,EAAO,SAAS,GAIhH,OAAO;AACT"}
1
+ {"version":3,"file":"ttl.js","names":[],"sources":["../src/ttl.ts"],"sourcesContent":["import { VaultError } from './errors';\n\n/** Duration helpers that produce finite, positive millisecond values. */\nexport const ttl = {\n days: (n: number) => assertPositiveFinite(n * 86_400_000, 'ttl.days'),\n hours: (n: number) => assertPositiveFinite(n * 3_600_000, 'ttl.hours'),\n minutes: (n: number) => assertPositiveFinite(n * 60_000, 'ttl.minutes'),\n ms: (n: number) => assertPositiveFinite(n, 'ttl.ms'),\n seconds: (n: number) => assertPositiveFinite(n * 1000, 'ttl.seconds'),\n} as const;\n\n/** Fixed storage envelope shared by every adapter, so data and indexes stay portable. */\nexport type StoredRecord<T> = { expiresAt?: number; value: T };\n\nexport function isExpired(expiresAt: number | undefined): boolean {\n return expiresAt !== undefined && Date.now() >= expiresAt;\n}\n\n/** Throws when `ttlMs` is not a finite, positive number. Returns it unchanged otherwise. */\nexport function assertPositiveFinite(ttlMs: number, source: string): number {\n if (!Number.isFinite(ttlMs) || ttlMs <= 0) {\n throw new VaultError(`${source} expected a finite positive number, received ${String(ttlMs)}`);\n }\n\n return ttlMs;\n}\n\nexport function parseStored<T>(raw: unknown): StoredRecord<T> | undefined {\n if (typeof raw !== 'object' || raw === null || !('value' in raw)) return undefined;\n\n const record = raw as { expiresAt?: unknown; value: unknown };\n\n if (record.expiresAt !== undefined && (typeof record.expiresAt !== 'number' || !Number.isFinite(record.expiresAt))) {\n return undefined;\n }\n\n return record as StoredRecord<T>;\n}\n"],"mappings":"yCAGA,IAAa,EAAM,CACjB,KAAO,GAAc,qBAAqB,EAAI,MAAY,UAAU,EACpE,MAAQ,GAAc,qBAAqB,EAAI,KAAW,WAAW,EACrE,QAAU,GAAc,qBAAqB,EAAI,IAAQ,aAAa,EACtE,GAAK,GAAc,qBAAqB,EAAG,QAAQ,EACnD,QAAU,GAAc,qBAAqB,EAAI,IAAM,aAAa,CACtE,EAKA,SAAgB,UAAU,EAAwC,CAChE,OAAO,IAAc,IAAA,IAAa,KAAK,IAAI,GAAK,CAClD,CAGA,SAAgB,qBAAqB,EAAe,EAAwB,CAC1E,GAAI,CAAC,OAAO,SAAS,CAAK,GAAK,GAAS,EACtC,MAAM,IAAI,EAAW,GAAG,EAAO,+CAA+C,OAAO,CAAK,GAAG,EAG/F,OAAO,CACT,CAEA,SAAgB,YAAe,EAA2C,CACxE,GAAI,OAAO,GAAQ,WAAY,GAAgB,EAAE,UAAW,GAAM,OAElE,IAAM,EAAS,EAEX,KAAO,YAAc,IAAA,IAAc,OAAO,EAAO,WAAc,UAAa,OAAO,SAAS,EAAO,SAAS,EAIhH,OAAO,CACT"}
package/dist/types.cjs CHANGED
@@ -1,2 +1,2 @@
1
- const e=require("./errors.cjs"),t=require("./ttl.cjs");function n(e){return{decode:t=>e.parse(t),encode:e=>e}}function r(n,r={}){let{defaultTtl:i,indexes:a}=r;if(i!==void 0&&t.assertPositiveFinite(i,`table: defaultTtl`),a){let t=new Set;for(let n of a){if(t.has(n))throw new e.VaultError(`table: index "${n}" is already registered`);t.add(n)}}return{defaultTtl:i,indexes:a,key:n}}exports.table=r,exports.validatorCodec=n;
1
+ const e=require("./errors.cjs"),t=require("./ttl.cjs");function validatorCodec(e){return{decode:t=>e.parse(t),encode:e=>e}}function table(n,r={}){let{defaultTtl:i,indexes:a}=r;if(i!==void 0&&t.assertPositiveFinite(i,`table: defaultTtl`),a){let t=new Set;for(let n of a){if(t.has(n))throw new e.VaultError(`table: index "${n}" is already registered`);t.add(n)}}return{defaultTtl:i,indexes:a,key:n}}exports.table=table,exports.validatorCodec=validatorCodec;
2
2
  //# sourceMappingURL=types.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.cjs","names":[],"sources":["../src/types.ts"],"sourcesContent":["/// <reference lib=\"dom\" />\n\nimport { VaultError } from './errors';\nimport type { QueryBuilder } from './query';\nimport { assertPositiveFinite } from './ttl';\n\n/** Portable primary-key values. Vault preserves their type and encodes them distinctly at rest. */\nexport type VaultKey = number | string;\n\n/** A typed table definition whose primary-key field must hold a portable Vault key. */\nexport type SchemaEntry<T extends object, Key extends keyof T & string = keyof T & string> = {\n defaultTtl?: number;\n /** IndexedDB creates these as `value.<field>` indexes; other stores filter in memory. */\n indexes?: readonly (keyof T & string)[];\n key: Key;\n};\n\nexport type AnySchema = Record<string, { defaultTtl?: number; indexes?: readonly string[]; key: string }>;\n\nexport type RecordOf<S extends AnySchema, K extends keyof S> =\n S[K] extends SchemaEntry<infer R, infer _Key> ? R : never;\nexport type KeyOf<S extends AnySchema, K extends keyof S> = Extract<\n S[K] extends SchemaEntry<infer R, infer Key> ? R[Key] : never,\n VaultKey\n>;\n\n/** A codec validates and decodes persisted values crossing a trust boundary. */\nexport type RecordCodec<T> = {\n decode(value: unknown): T;\n encode(value: T): unknown;\n};\n\nexport type RecordParser<T> = {\n parse(value: unknown): T;\n};\n\nexport type CodecInput<T> = RecordCodec<T> | RecordParser<T>;\n\nexport type TableCodecs<S extends AnySchema> = {\n [K in keyof S]: CodecInput<RecordOf<S, K>>;\n};\n\n/** A validator-only codec: encodes values as-is, validates on decode. */\nexport function validatorCodec<T>(validator: RecordParser<T>): RecordCodec<T> {\n return {\n decode: (value) => validator.parse(value),\n encode: (value) => value,\n };\n}\n\nexport type Observer<T> = (records: T[]) => void;\nexport type Unsubscribe = () => void;\n\n/** Shared factory options for stores that do not require durable codecs. */\nexport type MemoryStoreOptions<S extends AnySchema> = {\n schema: S;\n /** Optional per-table codecs. Memory values never cross a trust boundary, so codecs may be omitted. */\n codecs?: TableCodecs<S>;\n};\n\n/** Shared factory options for durable stores whose values cross a trust boundary. */\nexport type DurableStoreOptions<S extends AnySchema> = {\n schema: S;\n /** Required per-table codecs. Persisted values are decoded through these before entering typed code. */\n codecs: TableCodecs<S>;\n};\n\nexport type VaultConveniences<S extends AnySchema, K extends keyof S & string = keyof S & string> = {\n count<T extends K>(table: T): Promise<number>;\n deleteMany<T extends K>(table: T, keys: readonly KeyOf<S, T>[]): Promise<number>;\n getMany<T extends K>(table: T, keys: readonly KeyOf<S, T>[]): Promise<Array<RecordOf<S, T> | undefined>>;\n has<T extends K>(table: T, key: KeyOf<S, T>): Promise<boolean>;\n isEmpty<T extends K>(table: T): Promise<boolean>;\n keys<T extends K>(table: T, filter?: (record: RecordOf<S, T>) => boolean): Promise<KeyOf<S, T>[]>;\n query<T extends K>(table: T): QueryBuilder<RecordOf<S, T>>;\n update<T extends K>(\n table: T,\n key: KeyOf<S, T>,\n changes: Partial<RecordOf<S, T>>,\n ttl?: number,\n ): Promise<RecordOf<S, T> | undefined>;\n upsert<T extends K>(\n table: T,\n key: KeyOf<S, T>,\n update: (existing: RecordOf<S, T> | undefined) => RecordOf<S, T>,\n ttl?: number,\n ): Promise<RecordOf<S, T>>;\n};\n\n/** Methods available within an IndexedDB or SQLite transaction. */\nexport type TransactionContext<S extends AnySchema, K extends keyof S & string = keyof S & string> = VaultConveniences<\n S,\n K\n> & {\n clear<T extends K>(table: T): Promise<void>;\n delete<T extends K>(table: T, key: KeyOf<S, T>): Promise<boolean>;\n get<T extends K>(table: T, key: KeyOf<S, T>): Promise<RecordOf<S, T> | undefined>;\n getAll<T extends K>(table: T): Promise<RecordOf<S, T>[]>;\n iterate<T extends K>(table: T): AsyncIterable<RecordOf<S, T>>;\n put<T extends K>(table: T, value: RecordOf<S, T>, ttl?: number): Promise<RecordOf<S, T>>;\n putAll<T extends K>(table: T, values: readonly RecordOf<S, T>[], ttl?: number): Promise<void>;\n};\n\n/** Key-value store for Memory and Web Storage: core CRUD, observation, TTL, and pruning. */\nexport interface KeyValueVaultStore<S extends AnySchema> extends VaultConveniences<S> {\n clear<K extends keyof S & string>(table: K): Promise<void>;\n delete<K extends keyof S & string>(table: K, key: KeyOf<S, K>): Promise<boolean>;\n readonly disposalSignal: AbortSignal;\n dispose(): Promise<void>;\n readonly disposed: boolean;\n get<K extends keyof S & string>(table: K, key: KeyOf<S, K>): Promise<RecordOf<S, K> | undefined>;\n getAll<K extends keyof S & string>(table: K): Promise<RecordOf<S, K>[]>;\n observe<K extends keyof S & string>(\n table: K,\n listener: Observer<RecordOf<S, K>>,\n options?: { immediate?: boolean; signal?: AbortSignal },\n ): Unsubscribe;\n pruneExpired(): Promise<Record<keyof S & string, number>>;\n put<K extends keyof S & string>(table: K, value: RecordOf<S, K>, ttl?: number): Promise<RecordOf<S, K>>;\n putAll<K extends keyof S & string>(table: K, values: readonly RecordOf<S, K>[], ttl?: number): Promise<void>;\n [Symbol.asyncDispose](): Promise<void>;\n}\n\n/** Document store for IndexedDB and SQLite: adds atomic transactions and lazy iteration. */\nexport interface DocumentVaultStore<S extends AnySchema> extends KeyValueVaultStore<S> {\n batch<K extends keyof S & string, R>(\n tables: readonly K[],\n fn: (tx: TransactionContext<S, K>) => Promise<R>,\n ): Promise<R>;\n iterate<K extends keyof S & string>(table: K): AsyncIterable<RecordOf<S, K>>;\n}\n\ntype VaultKeyField<T extends object> = {\n [K in keyof T & string]: T[K] extends VaultKey ? K : never;\n}[keyof T & string];\n\n/** Define a typed table whose primary-key field holds a portable Vault key. */\nexport function table<T extends object, Key extends VaultKeyField<T> = VaultKeyField<T>>(\n key: Key,\n options: { defaultTtl?: number; indexes?: readonly (keyof T & string)[] } = {},\n): SchemaEntry<T, Key> {\n const { defaultTtl, indexes } = options;\n\n if (defaultTtl !== undefined) assertPositiveFinite(defaultTtl, 'table: defaultTtl');\n\n if (indexes) {\n const seen = new Set<string>();\n\n for (const field of indexes) {\n if (seen.has(field)) {\n throw new VaultError(`table: index \"${field}\" is already registered`);\n }\n\n seen.add(field);\n }\n }\n\n return { defaultTtl, indexes, key };\n}\n"],"mappings":"uDA2CA,SAAgB,EAAkB,EAA4C,CAC5E,MAAO,CACL,OAAS,GAAU,EAAU,MAAM,CAAK,EACxC,OAAS,GAAU,CACrB,CACF,CAyFA,SAAgB,EACd,EACA,EAA4E,CAAC,EACxD,CACrB,GAAM,CAAE,aAAY,WAAY,EAIhC,GAFI,IAAe,IAAA,IAAW,EAAA,qBAAqB,EAAY,mBAAmB,EAE9E,EAAS,CACX,IAAM,EAAO,IAAI,IAEjB,IAAK,IAAM,KAAS,EAAS,CAC3B,GAAI,EAAK,IAAI,CAAK,EAChB,MAAM,IAAI,EAAA,WAAW,iBAAiB,EAAM,wBAAwB,EAGtE,EAAK,IAAI,CAAK,CAChB,CACF,CAEA,MAAO,CAAE,aAAY,UAAS,KAAI,CACpC"}
1
+ {"version":3,"file":"types.cjs","names":[],"sources":["../src/types.ts"],"sourcesContent":["/// <reference lib=\"dom\" />\n\nimport { VaultError } from './errors';\nimport { assertPositiveFinite } from './ttl';\n\n/** Portable primary-key values. Vault preserves their type and encodes them distinctly at rest. */\nexport type VaultKey = number | string;\n\n/** A typed table definition whose primary-key field must hold a portable Vault key. */\nexport type SchemaEntry<T extends object, Key extends keyof T & string = keyof T & string> = {\n defaultTtl?: number;\n /** IndexedDB creates these as `value.<field>` indexes; other stores filter in memory. */\n indexes?: readonly (keyof T & string)[];\n key: Key;\n};\n\nexport type AnySchema = Record<string, { defaultTtl?: number; indexes?: readonly string[]; key: string }>;\n\nexport type RecordOf<S extends AnySchema, K extends keyof S> =\n S[K] extends SchemaEntry<infer R, infer _Key> ? R : never;\nexport type KeyOf<S extends AnySchema, K extends keyof S> = Extract<\n S[K] extends SchemaEntry<infer R, infer Key> ? R[Key] : never,\n VaultKey\n>;\n\n/** A codec validates and decodes persisted values crossing a trust boundary. */\nexport type RecordCodec<T> = {\n decode(value: unknown): T;\n encode(value: T): unknown;\n};\n\nexport type RecordParser<T> = {\n parse(value: unknown): T;\n};\n\nexport type CodecInput<T> = RecordCodec<T> | RecordParser<T>;\n\nexport type TableCodecs<S extends AnySchema> = {\n [K in keyof S]: CodecInput<RecordOf<S, K>>;\n};\n\n/** A validator-only codec: encodes values as-is, validates on decode. */\nexport function validatorCodec<T>(validator: RecordParser<T>): RecordCodec<T> {\n return {\n decode: (value) => validator.parse(value),\n encode: (value) => value,\n };\n}\n\nexport type Observer<T> = (records: T[]) => void;\nexport type Unsubscribe = () => void;\n\n/** Shared factory options for stores that do not require durable codecs. */\nexport type MemoryStoreOptions<S extends AnySchema> = {\n schema: S;\n /** Optional per-table codecs. Memory values never cross a trust boundary, so codecs may be omitted. */\n codecs?: TableCodecs<S>;\n};\n\n/** Shared factory options for durable stores whose values cross a trust boundary. */\nexport type DurableStoreOptions<S extends AnySchema> = {\n schema: S;\n /** Required per-table codecs. Persisted values are decoded through these before entering typed code. */\n codecs: TableCodecs<S>;\n};\n\nexport type VaultConveniences<S extends AnySchema, K extends keyof S & string = keyof S & string> = {\n count<T extends K>(table: T): Promise<number>;\n deleteMany<T extends K>(table: T, keys: readonly KeyOf<S, T>[]): Promise<number>;\n getMany<T extends K>(table: T, keys: readonly KeyOf<S, T>[]): Promise<Array<RecordOf<S, T> | undefined>>;\n has<T extends K>(table: T, key: KeyOf<S, T>): Promise<boolean>;\n isEmpty<T extends K>(table: T): Promise<boolean>;\n keys<T extends K>(table: T, filter?: (record: RecordOf<S, T>) => boolean): Promise<KeyOf<S, T>[]>;\n update<T extends K>(\n table: T,\n key: KeyOf<S, T>,\n changes: Partial<RecordOf<S, T>>,\n ttl?: number,\n ): Promise<RecordOf<S, T> | undefined>;\n upsert<T extends K>(\n table: T,\n key: KeyOf<S, T>,\n update: (existing: RecordOf<S, T> | undefined) => RecordOf<S, T>,\n ttl?: number,\n ): Promise<RecordOf<S, T>>;\n};\n\n/** Methods available within an IndexedDB or SQLite transaction. */\nexport type TransactionContext<S extends AnySchema, K extends keyof S & string = keyof S & string> = VaultConveniences<\n S,\n K\n> & {\n clear<T extends K>(table: T): Promise<void>;\n delete<T extends K>(table: T, key: KeyOf<S, T>): Promise<boolean>;\n get<T extends K>(table: T, key: KeyOf<S, T>): Promise<RecordOf<S, T> | undefined>;\n getAll<T extends K>(table: T): Promise<RecordOf<S, T>[]>;\n iterate<T extends K>(table: T): AsyncIterable<RecordOf<S, T>>;\n put<T extends K>(table: T, value: RecordOf<S, T>, ttl?: number): Promise<RecordOf<S, T>>;\n putAll<T extends K>(table: T, values: readonly RecordOf<S, T>[], ttl?: number): Promise<void>;\n};\n\n/** Key-value store for Memory and Web Storage: core CRUD, observation, TTL, and pruning. */\nexport interface KeyValueVaultStore<S extends AnySchema> extends VaultConveniences<S> {\n clear<K extends keyof S & string>(table: K): Promise<void>;\n delete<K extends keyof S & string>(table: K, key: KeyOf<S, K>): Promise<boolean>;\n readonly disposalSignal: AbortSignal;\n dispose(): Promise<void>;\n readonly disposed: boolean;\n get<K extends keyof S & string>(table: K, key: KeyOf<S, K>): Promise<RecordOf<S, K> | undefined>;\n getAll<K extends keyof S & string>(table: K): Promise<RecordOf<S, K>[]>;\n observe<K extends keyof S & string>(\n table: K,\n listener: Observer<RecordOf<S, K>>,\n options?: { immediate?: boolean; signal?: AbortSignal },\n ): Unsubscribe;\n pruneExpired(): Promise<Record<keyof S & string, number>>;\n put<K extends keyof S & string>(table: K, value: RecordOf<S, K>, ttl?: number): Promise<RecordOf<S, K>>;\n putAll<K extends keyof S & string>(table: K, values: readonly RecordOf<S, K>[], ttl?: number): Promise<void>;\n [Symbol.asyncDispose](): Promise<void>;\n}\n\n/** Document store for IndexedDB and SQLite: adds atomic transactions and lazy iteration. */\nexport interface DocumentVaultStore<S extends AnySchema> extends KeyValueVaultStore<S> {\n batch<K extends keyof S & string, R>(\n tables: readonly K[],\n fn: (tx: TransactionContext<S, K>) => Promise<R>,\n ): Promise<R>;\n iterate<K extends keyof S & string>(table: K): AsyncIterable<RecordOf<S, K>>;\n}\n\ntype VaultKeyField<T extends object> = {\n [K in keyof T & string]: T[K] extends VaultKey ? K : never;\n}[keyof T & string];\n\n/** Define a typed table whose primary-key field holds a portable Vault key. */\nexport function table<T extends object, Key extends VaultKeyField<T> = VaultKeyField<T>>(\n key: Key,\n options: { defaultTtl?: number; indexes?: readonly (keyof T & string)[] } = {},\n): SchemaEntry<T, Key> {\n const { defaultTtl, indexes } = options;\n\n if (defaultTtl !== undefined) assertPositiveFinite(defaultTtl, 'table: defaultTtl');\n\n if (indexes) {\n const seen = new Set<string>();\n\n for (const field of indexes) {\n if (seen.has(field)) {\n throw new VaultError(`table: index \"${field}\" is already registered`);\n }\n\n seen.add(field);\n }\n }\n\n return { defaultTtl, indexes, key };\n}\n"],"mappings":"uDA0CA,SAAgB,eAAkB,EAA4C,CAC5E,MAAO,CACL,OAAS,GAAU,EAAU,MAAM,CAAK,EACxC,OAAS,GAAU,CACrB,CACF,CAwFA,SAAgB,MACd,EACA,EAA4E,CAAC,EACxD,CACrB,GAAM,CAAE,aAAY,WAAY,EAIhC,GAFI,IAAe,IAAA,IAAW,EAAA,qBAAqB,EAAY,mBAAmB,EAE9E,EAAS,CACX,IAAM,EAAO,IAAI,IAEjB,IAAK,IAAM,KAAS,EAAS,CAC3B,GAAI,EAAK,IAAI,CAAK,EAChB,MAAM,IAAI,EAAA,WAAW,iBAAiB,EAAM,wBAAwB,EAGtE,EAAK,IAAI,CAAK,CAChB,CACF,CAEA,MAAO,CAAE,aAAY,UAAS,KAAI,CACpC"}
package/dist/types.d.ts CHANGED
@@ -1,4 +1,3 @@
1
- import type { QueryBuilder } from './query';
2
1
  /** Portable primary-key values. Vault preserves their type and encodes them distinctly at rest. */
3
2
  export type VaultKey = number | string;
4
3
  /** A typed table definition whose primary-key field must hold a portable Vault key. */
@@ -50,7 +49,6 @@ export type VaultConveniences<S extends AnySchema, K extends keyof S & string =
50
49
  has<T extends K>(table: T, key: KeyOf<S, T>): Promise<boolean>;
51
50
  isEmpty<T extends K>(table: T): Promise<boolean>;
52
51
  keys<T extends K>(table: T, filter?: (record: RecordOf<S, T>) => boolean): Promise<KeyOf<S, T>[]>;
53
- query<T extends K>(table: T): QueryBuilder<RecordOf<S, T>>;
54
52
  update<T extends K>(table: T, key: KeyOf<S, T>, changes: Partial<RecordOf<S, T>>, ttl?: number): Promise<RecordOf<S, T> | undefined>;
55
53
  upsert<T extends K>(table: T, key: KeyOf<S, T>, update: (existing: RecordOf<S, T> | undefined) => RecordOf<S, T>, ttl?: number): Promise<RecordOf<S, T>>;
56
54
  };
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js CHANGED
@@ -1,28 +1,2 @@
1
- import { VaultError as e } from "./errors.js";
2
- import { assertPositiveFinite as t } from "./ttl.js";
3
- //#region src/types.ts
4
- function n(e) {
5
- return {
6
- decode: (t) => e.parse(t),
7
- encode: (e) => e
8
- };
9
- }
10
- function r(n, r = {}) {
11
- let { defaultTtl: i, indexes: a } = r;
12
- if (i !== void 0 && t(i, "table: defaultTtl"), a) {
13
- let t = /* @__PURE__ */ new Set();
14
- for (let n of a) {
15
- if (t.has(n)) throw new e(`table: index "${n}" is already registered`);
16
- t.add(n);
17
- }
18
- }
19
- return {
20
- defaultTtl: i,
21
- indexes: a,
22
- key: n
23
- };
24
- }
25
- //#endregion
26
- export { r as table, n as validatorCodec };
27
-
1
+ import{VaultError as e}from"./errors.js";import{assertPositiveFinite as t}from"./ttl.js";function validatorCodec(e){return{decode:t=>e.parse(t),encode:e=>e}}function table(n,r={}){let{defaultTtl:i,indexes:a}=r;if(i!==void 0&&t(i,`table: defaultTtl`),a){let t=new Set;for(let n of a){if(t.has(n))throw new e(`table: index "${n}" is already registered`);t.add(n)}}return{defaultTtl:i,indexes:a,key:n}}export{table,validatorCodec};
28
2
  //# sourceMappingURL=types.js.map
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","names":[],"sources":["../src/types.ts"],"sourcesContent":["/// <reference lib=\"dom\" />\n\nimport { VaultError } from './errors';\nimport type { QueryBuilder } from './query';\nimport { assertPositiveFinite } from './ttl';\n\n/** Portable primary-key values. Vault preserves their type and encodes them distinctly at rest. */\nexport type VaultKey = number | string;\n\n/** A typed table definition whose primary-key field must hold a portable Vault key. */\nexport type SchemaEntry<T extends object, Key extends keyof T & string = keyof T & string> = {\n defaultTtl?: number;\n /** IndexedDB creates these as `value.<field>` indexes; other stores filter in memory. */\n indexes?: readonly (keyof T & string)[];\n key: Key;\n};\n\nexport type AnySchema = Record<string, { defaultTtl?: number; indexes?: readonly string[]; key: string }>;\n\nexport type RecordOf<S extends AnySchema, K extends keyof S> =\n S[K] extends SchemaEntry<infer R, infer _Key> ? R : never;\nexport type KeyOf<S extends AnySchema, K extends keyof S> = Extract<\n S[K] extends SchemaEntry<infer R, infer Key> ? R[Key] : never,\n VaultKey\n>;\n\n/** A codec validates and decodes persisted values crossing a trust boundary. */\nexport type RecordCodec<T> = {\n decode(value: unknown): T;\n encode(value: T): unknown;\n};\n\nexport type RecordParser<T> = {\n parse(value: unknown): T;\n};\n\nexport type CodecInput<T> = RecordCodec<T> | RecordParser<T>;\n\nexport type TableCodecs<S extends AnySchema> = {\n [K in keyof S]: CodecInput<RecordOf<S, K>>;\n};\n\n/** A validator-only codec: encodes values as-is, validates on decode. */\nexport function validatorCodec<T>(validator: RecordParser<T>): RecordCodec<T> {\n return {\n decode: (value) => validator.parse(value),\n encode: (value) => value,\n };\n}\n\nexport type Observer<T> = (records: T[]) => void;\nexport type Unsubscribe = () => void;\n\n/** Shared factory options for stores that do not require durable codecs. */\nexport type MemoryStoreOptions<S extends AnySchema> = {\n schema: S;\n /** Optional per-table codecs. Memory values never cross a trust boundary, so codecs may be omitted. */\n codecs?: TableCodecs<S>;\n};\n\n/** Shared factory options for durable stores whose values cross a trust boundary. */\nexport type DurableStoreOptions<S extends AnySchema> = {\n schema: S;\n /** Required per-table codecs. Persisted values are decoded through these before entering typed code. */\n codecs: TableCodecs<S>;\n};\n\nexport type VaultConveniences<S extends AnySchema, K extends keyof S & string = keyof S & string> = {\n count<T extends K>(table: T): Promise<number>;\n deleteMany<T extends K>(table: T, keys: readonly KeyOf<S, T>[]): Promise<number>;\n getMany<T extends K>(table: T, keys: readonly KeyOf<S, T>[]): Promise<Array<RecordOf<S, T> | undefined>>;\n has<T extends K>(table: T, key: KeyOf<S, T>): Promise<boolean>;\n isEmpty<T extends K>(table: T): Promise<boolean>;\n keys<T extends K>(table: T, filter?: (record: RecordOf<S, T>) => boolean): Promise<KeyOf<S, T>[]>;\n query<T extends K>(table: T): QueryBuilder<RecordOf<S, T>>;\n update<T extends K>(\n table: T,\n key: KeyOf<S, T>,\n changes: Partial<RecordOf<S, T>>,\n ttl?: number,\n ): Promise<RecordOf<S, T> | undefined>;\n upsert<T extends K>(\n table: T,\n key: KeyOf<S, T>,\n update: (existing: RecordOf<S, T> | undefined) => RecordOf<S, T>,\n ttl?: number,\n ): Promise<RecordOf<S, T>>;\n};\n\n/** Methods available within an IndexedDB or SQLite transaction. */\nexport type TransactionContext<S extends AnySchema, K extends keyof S & string = keyof S & string> = VaultConveniences<\n S,\n K\n> & {\n clear<T extends K>(table: T): Promise<void>;\n delete<T extends K>(table: T, key: KeyOf<S, T>): Promise<boolean>;\n get<T extends K>(table: T, key: KeyOf<S, T>): Promise<RecordOf<S, T> | undefined>;\n getAll<T extends K>(table: T): Promise<RecordOf<S, T>[]>;\n iterate<T extends K>(table: T): AsyncIterable<RecordOf<S, T>>;\n put<T extends K>(table: T, value: RecordOf<S, T>, ttl?: number): Promise<RecordOf<S, T>>;\n putAll<T extends K>(table: T, values: readonly RecordOf<S, T>[], ttl?: number): Promise<void>;\n};\n\n/** Key-value store for Memory and Web Storage: core CRUD, observation, TTL, and pruning. */\nexport interface KeyValueVaultStore<S extends AnySchema> extends VaultConveniences<S> {\n clear<K extends keyof S & string>(table: K): Promise<void>;\n delete<K extends keyof S & string>(table: K, key: KeyOf<S, K>): Promise<boolean>;\n readonly disposalSignal: AbortSignal;\n dispose(): Promise<void>;\n readonly disposed: boolean;\n get<K extends keyof S & string>(table: K, key: KeyOf<S, K>): Promise<RecordOf<S, K> | undefined>;\n getAll<K extends keyof S & string>(table: K): Promise<RecordOf<S, K>[]>;\n observe<K extends keyof S & string>(\n table: K,\n listener: Observer<RecordOf<S, K>>,\n options?: { immediate?: boolean; signal?: AbortSignal },\n ): Unsubscribe;\n pruneExpired(): Promise<Record<keyof S & string, number>>;\n put<K extends keyof S & string>(table: K, value: RecordOf<S, K>, ttl?: number): Promise<RecordOf<S, K>>;\n putAll<K extends keyof S & string>(table: K, values: readonly RecordOf<S, K>[], ttl?: number): Promise<void>;\n [Symbol.asyncDispose](): Promise<void>;\n}\n\n/** Document store for IndexedDB and SQLite: adds atomic transactions and lazy iteration. */\nexport interface DocumentVaultStore<S extends AnySchema> extends KeyValueVaultStore<S> {\n batch<K extends keyof S & string, R>(\n tables: readonly K[],\n fn: (tx: TransactionContext<S, K>) => Promise<R>,\n ): Promise<R>;\n iterate<K extends keyof S & string>(table: K): AsyncIterable<RecordOf<S, K>>;\n}\n\ntype VaultKeyField<T extends object> = {\n [K in keyof T & string]: T[K] extends VaultKey ? K : never;\n}[keyof T & string];\n\n/** Define a typed table whose primary-key field holds a portable Vault key. */\nexport function table<T extends object, Key extends VaultKeyField<T> = VaultKeyField<T>>(\n key: Key,\n options: { defaultTtl?: number; indexes?: readonly (keyof T & string)[] } = {},\n): SchemaEntry<T, Key> {\n const { defaultTtl, indexes } = options;\n\n if (defaultTtl !== undefined) assertPositiveFinite(defaultTtl, 'table: defaultTtl');\n\n if (indexes) {\n const seen = new Set<string>();\n\n for (const field of indexes) {\n if (seen.has(field)) {\n throw new VaultError(`table: index \"${field}\" is already registered`);\n }\n\n seen.add(field);\n }\n }\n\n return { defaultTtl, indexes, key };\n}\n"],"mappings":";;;AA2CA,SAAgB,EAAkB,GAA4C;CAC5E,OAAO;EACL,SAAS,MAAU,EAAU,MAAM,CAAK;EACxC,SAAS,MAAU;CACrB;AACF;AAyFA,SAAgB,EACd,GACA,IAA4E,CAAC,GACxD;CACrB,IAAM,EAAE,eAAY,eAAY;CAIhC,IAFI,MAAe,KAAA,KAAW,EAAqB,GAAY,mBAAmB,GAE9E,GAAS;EACX,IAAM,oBAAO,IAAI,IAAY;EAE7B,KAAK,IAAM,KAAS,GAAS;GAC3B,IAAI,EAAK,IAAI,CAAK,GAChB,MAAM,IAAI,EAAW,iBAAiB,EAAM,wBAAwB;GAGtE,EAAK,IAAI,CAAK;EAChB;CACF;CAEA,OAAO;EAAE;EAAY;EAAS;CAAI;AACpC"}
1
+ {"version":3,"file":"types.js","names":[],"sources":["../src/types.ts"],"sourcesContent":["/// <reference lib=\"dom\" />\n\nimport { VaultError } from './errors';\nimport { assertPositiveFinite } from './ttl';\n\n/** Portable primary-key values. Vault preserves their type and encodes them distinctly at rest. */\nexport type VaultKey = number | string;\n\n/** A typed table definition whose primary-key field must hold a portable Vault key. */\nexport type SchemaEntry<T extends object, Key extends keyof T & string = keyof T & string> = {\n defaultTtl?: number;\n /** IndexedDB creates these as `value.<field>` indexes; other stores filter in memory. */\n indexes?: readonly (keyof T & string)[];\n key: Key;\n};\n\nexport type AnySchema = Record<string, { defaultTtl?: number; indexes?: readonly string[]; key: string }>;\n\nexport type RecordOf<S extends AnySchema, K extends keyof S> =\n S[K] extends SchemaEntry<infer R, infer _Key> ? R : never;\nexport type KeyOf<S extends AnySchema, K extends keyof S> = Extract<\n S[K] extends SchemaEntry<infer R, infer Key> ? R[Key] : never,\n VaultKey\n>;\n\n/** A codec validates and decodes persisted values crossing a trust boundary. */\nexport type RecordCodec<T> = {\n decode(value: unknown): T;\n encode(value: T): unknown;\n};\n\nexport type RecordParser<T> = {\n parse(value: unknown): T;\n};\n\nexport type CodecInput<T> = RecordCodec<T> | RecordParser<T>;\n\nexport type TableCodecs<S extends AnySchema> = {\n [K in keyof S]: CodecInput<RecordOf<S, K>>;\n};\n\n/** A validator-only codec: encodes values as-is, validates on decode. */\nexport function validatorCodec<T>(validator: RecordParser<T>): RecordCodec<T> {\n return {\n decode: (value) => validator.parse(value),\n encode: (value) => value,\n };\n}\n\nexport type Observer<T> = (records: T[]) => void;\nexport type Unsubscribe = () => void;\n\n/** Shared factory options for stores that do not require durable codecs. */\nexport type MemoryStoreOptions<S extends AnySchema> = {\n schema: S;\n /** Optional per-table codecs. Memory values never cross a trust boundary, so codecs may be omitted. */\n codecs?: TableCodecs<S>;\n};\n\n/** Shared factory options for durable stores whose values cross a trust boundary. */\nexport type DurableStoreOptions<S extends AnySchema> = {\n schema: S;\n /** Required per-table codecs. Persisted values are decoded through these before entering typed code. */\n codecs: TableCodecs<S>;\n};\n\nexport type VaultConveniences<S extends AnySchema, K extends keyof S & string = keyof S & string> = {\n count<T extends K>(table: T): Promise<number>;\n deleteMany<T extends K>(table: T, keys: readonly KeyOf<S, T>[]): Promise<number>;\n getMany<T extends K>(table: T, keys: readonly KeyOf<S, T>[]): Promise<Array<RecordOf<S, T> | undefined>>;\n has<T extends K>(table: T, key: KeyOf<S, T>): Promise<boolean>;\n isEmpty<T extends K>(table: T): Promise<boolean>;\n keys<T extends K>(table: T, filter?: (record: RecordOf<S, T>) => boolean): Promise<KeyOf<S, T>[]>;\n update<T extends K>(\n table: T,\n key: KeyOf<S, T>,\n changes: Partial<RecordOf<S, T>>,\n ttl?: number,\n ): Promise<RecordOf<S, T> | undefined>;\n upsert<T extends K>(\n table: T,\n key: KeyOf<S, T>,\n update: (existing: RecordOf<S, T> | undefined) => RecordOf<S, T>,\n ttl?: number,\n ): Promise<RecordOf<S, T>>;\n};\n\n/** Methods available within an IndexedDB or SQLite transaction. */\nexport type TransactionContext<S extends AnySchema, K extends keyof S & string = keyof S & string> = VaultConveniences<\n S,\n K\n> & {\n clear<T extends K>(table: T): Promise<void>;\n delete<T extends K>(table: T, key: KeyOf<S, T>): Promise<boolean>;\n get<T extends K>(table: T, key: KeyOf<S, T>): Promise<RecordOf<S, T> | undefined>;\n getAll<T extends K>(table: T): Promise<RecordOf<S, T>[]>;\n iterate<T extends K>(table: T): AsyncIterable<RecordOf<S, T>>;\n put<T extends K>(table: T, value: RecordOf<S, T>, ttl?: number): Promise<RecordOf<S, T>>;\n putAll<T extends K>(table: T, values: readonly RecordOf<S, T>[], ttl?: number): Promise<void>;\n};\n\n/** Key-value store for Memory and Web Storage: core CRUD, observation, TTL, and pruning. */\nexport interface KeyValueVaultStore<S extends AnySchema> extends VaultConveniences<S> {\n clear<K extends keyof S & string>(table: K): Promise<void>;\n delete<K extends keyof S & string>(table: K, key: KeyOf<S, K>): Promise<boolean>;\n readonly disposalSignal: AbortSignal;\n dispose(): Promise<void>;\n readonly disposed: boolean;\n get<K extends keyof S & string>(table: K, key: KeyOf<S, K>): Promise<RecordOf<S, K> | undefined>;\n getAll<K extends keyof S & string>(table: K): Promise<RecordOf<S, K>[]>;\n observe<K extends keyof S & string>(\n table: K,\n listener: Observer<RecordOf<S, K>>,\n options?: { immediate?: boolean; signal?: AbortSignal },\n ): Unsubscribe;\n pruneExpired(): Promise<Record<keyof S & string, number>>;\n put<K extends keyof S & string>(table: K, value: RecordOf<S, K>, ttl?: number): Promise<RecordOf<S, K>>;\n putAll<K extends keyof S & string>(table: K, values: readonly RecordOf<S, K>[], ttl?: number): Promise<void>;\n [Symbol.asyncDispose](): Promise<void>;\n}\n\n/** Document store for IndexedDB and SQLite: adds atomic transactions and lazy iteration. */\nexport interface DocumentVaultStore<S extends AnySchema> extends KeyValueVaultStore<S> {\n batch<K extends keyof S & string, R>(\n tables: readonly K[],\n fn: (tx: TransactionContext<S, K>) => Promise<R>,\n ): Promise<R>;\n iterate<K extends keyof S & string>(table: K): AsyncIterable<RecordOf<S, K>>;\n}\n\ntype VaultKeyField<T extends object> = {\n [K in keyof T & string]: T[K] extends VaultKey ? K : never;\n}[keyof T & string];\n\n/** Define a typed table whose primary-key field holds a portable Vault key. */\nexport function table<T extends object, Key extends VaultKeyField<T> = VaultKeyField<T>>(\n key: Key,\n options: { defaultTtl?: number; indexes?: readonly (keyof T & string)[] } = {},\n): SchemaEntry<T, Key> {\n const { defaultTtl, indexes } = options;\n\n if (defaultTtl !== undefined) assertPositiveFinite(defaultTtl, 'table: defaultTtl');\n\n if (indexes) {\n const seen = new Set<string>();\n\n for (const field of indexes) {\n if (seen.has(field)) {\n throw new VaultError(`table: index \"${field}\" is already registered`);\n }\n\n seen.add(field);\n }\n }\n\n return { defaultTtl, indexes, key };\n}\n"],"mappings":"yFA0CA,SAAgB,eAAkB,EAA4C,CAC5E,MAAO,CACL,OAAS,GAAU,EAAU,MAAM,CAAK,EACxC,OAAS,GAAU,CACrB,CACF,CAwFA,SAAgB,MACd,EACA,EAA4E,CAAC,EACxD,CACrB,GAAM,CAAE,aAAY,WAAY,EAIhC,GAFI,IAAe,IAAA,IAAW,EAAqB,EAAY,mBAAmB,EAE9E,EAAS,CACX,IAAM,EAAO,IAAI,IAEjB,IAAK,IAAM,KAAS,EAAS,CAC3B,GAAI,EAAK,IAAI,CAAK,EAChB,MAAM,IAAI,EAAW,iBAAiB,EAAM,wBAAwB,EAGtE,EAAK,IAAI,CAAK,CAChB,CACF,CAEA,MAAO,CAAE,aAAY,UAAS,KAAI,CACpC"}
package/dist/vault.cjs CHANGED
@@ -1,2 +1,2 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e=class extends Error{static errorName=`VaultError`;constructor(e,t){super(e,t),this.name=new.target.errorName,Object.setPrototypeOf(this,new.target.prototype)}},t=class extends e{static errorName=`VaultDisposedError`;constructor(e=`adapter is disposed`,t){super(e,t)}},n=class extends e{static errorName=`VaultScopeError`},r=class extends e{static errorName=`VaultQuotaError`},i=class extends e{static errorName=`VaultMigrationError`},a={days:e=>s(e*864e5,`ttl.days`),hours:e=>s(e*36e5,`ttl.hours`),minutes:e=>s(e*6e4,`ttl.minutes`),ms:e=>s(e,`ttl.ms`),seconds:e=>s(e*1e3,`ttl.seconds`)};function o(e){return e!==void 0&&Date.now()>=e}function s(t,n){if(!Number.isFinite(t)||t<=0)throw new e(`${n} expected a finite positive number, received ${String(t)}`);return t}async function c(e,t,n){return e.has(t,n)}async function l(e,t){return e.count(t)}async function u(e,t){return e.isEmpty(t)}async function d(e,t,n){return e.getMany(t,n)}async function f(e,t,n){return e.keys(t,n)}async function p(e,t,n){return e.deleteMany(t,n)}async function m(e,t,n,r,i){return e.update(t,n,r,i)}async function h(e,t,n,r,i){return e.upsert(t,n,r,i)}function g(e){return{decode:t=>e.parse(t),encode:e=>e}}function _(t,n={}){let{defaultTtl:r,indexes:i}=n;if(r!==void 0&&s(r,`table: defaultTtl`),i){let t=new Set;for(let n of i){if(t.has(n))throw new e(`table: index "${n}" is already registered`);t.add(n)}}return{defaultTtl:r,indexes:i,key:t}}exports.VaultDisposedError=t,exports.VaultError=e,exports.VaultMigrationError=i,exports.VaultQuotaError=r,exports.VaultScopeError=n,exports.count=l,exports.deleteMany=p,exports.getMany=d,exports.has=c,exports.isEmpty=u,exports.isExpired=o,exports.keys=f,exports.table=_,exports.ttl=a,exports.update=m,exports.upsert=h,exports.validatorCodec=g;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var VaultError=class extends Error{constructor(e,t){super(e,t),this.name=new.target.name,Object.setPrototypeOf(this,new.target.prototype)}},VaultDisposedError=class extends VaultError{constructor(e=`adapter is disposed`,t){super(e,t)}},VaultScopeError=class extends VaultError{},VaultQuotaError=class extends VaultError{},VaultMigrationError=class extends VaultError{},e={days:e=>assertPositiveFinite(e*864e5,`ttl.days`),hours:e=>assertPositiveFinite(e*36e5,`ttl.hours`),minutes:e=>assertPositiveFinite(e*6e4,`ttl.minutes`),ms:e=>assertPositiveFinite(e,`ttl.ms`),seconds:e=>assertPositiveFinite(e*1e3,`ttl.seconds`)};function assertPositiveFinite(e,t){if(!Number.isFinite(e)||e<=0)throw new VaultError(`${t} expected a finite positive number, received ${String(e)}`);return e}function validatorCodec(e){return{decode:t=>e.parse(t),encode:e=>e}}function table(e,t={}){let{defaultTtl:n,indexes:r}=t;if(n!==void 0&&assertPositiveFinite(n,`table: defaultTtl`),r){let e=new Set;for(let t of r){if(e.has(t))throw new VaultError(`table: index "${t}" is already registered`);e.add(t)}}return{defaultTtl:n,indexes:r,key:e}}exports.VaultDisposedError=VaultDisposedError,exports.VaultError=VaultError,exports.VaultMigrationError=VaultMigrationError,exports.VaultQuotaError=VaultQuotaError,exports.VaultScopeError=VaultScopeError,exports.table=table,exports.ttl=e,exports.validatorCodec=validatorCodec;
2
2
  //# sourceMappingURL=vault.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"vault.cjs","names":[],"sources":["../src/errors.ts","../src/ttl.ts","../src/adapter-core.ts","../src/types.ts"],"sourcesContent":["/**\n * Base class for all vault errors. Catch with `instanceof VaultError` to\n * handle any vault-originated error regardless of its specific subtype.\n */\nexport class VaultError extends Error {\n protected static readonly errorName: string = 'VaultError';\n\n constructor(message: string, opts?: ErrorOptions) {\n super(message, opts);\n this.name = (new.target as typeof VaultError).errorName;\n // Ensures `instanceof` works correctly when transpiled to ES5.\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/** Thrown when an operation is attempted on a disposed adapter or observer hub. */\nexport class VaultDisposedError extends VaultError {\n protected static override readonly errorName = 'VaultDisposedError';\n\n constructor(message = 'adapter is disposed', opts?: ErrorOptions) {\n super(message, opts);\n }\n}\n\n/** Thrown when a `batch()` callback accesses a table not declared in the scope. */\nexport class VaultScopeError extends VaultError {\n protected static override readonly errorName = 'VaultScopeError';\n}\n\n/** Thrown when a WebStorage write exceeds the storage quota. */\nexport class VaultQuotaError extends VaultError {\n protected static override readonly errorName = 'VaultQuotaError';\n}\n\n/** Thrown when an IndexedDB `onupgradeneeded` migration callback throws. */\nexport class VaultMigrationError extends VaultError {\n protected static override readonly errorName = 'VaultMigrationError';\n}\n","import { VaultError } from './errors';\n\n/** Duration helpers that produce finite, positive millisecond values. */\nexport const ttl = {\n days: (n: number) => assertPositiveFinite(n * 86_400_000, 'ttl.days'),\n hours: (n: number) => assertPositiveFinite(n * 3_600_000, 'ttl.hours'),\n minutes: (n: number) => assertPositiveFinite(n * 60_000, 'ttl.minutes'),\n ms: (n: number) => assertPositiveFinite(n, 'ttl.ms'),\n seconds: (n: number) => assertPositiveFinite(n * 1000, 'ttl.seconds'),\n} as const;\n\n/** Fixed storage envelope shared by every adapter, so data and indexes stay portable. */\nexport type StoredRecord<T> = { expiresAt?: number; value: T };\n\nexport function isExpired(expiresAt: number | undefined): boolean {\n return expiresAt !== undefined && Date.now() >= expiresAt;\n}\n\n/** Throws when `ttlMs` is not a finite, positive number. Returns it unchanged otherwise. */\nexport function assertPositiveFinite(ttlMs: number, source: string): number {\n if (!Number.isFinite(ttlMs) || ttlMs <= 0) {\n throw new VaultError(`${source} expected a finite positive number, received ${String(ttlMs)}`);\n }\n\n return ttlMs;\n}\n\nexport function parseStored<T>(raw: unknown): StoredRecord<T> | undefined {\n if (typeof raw !== 'object' || raw === null || !('value' in raw)) return undefined;\n\n const record = raw as { expiresAt?: unknown; value: unknown };\n\n if (record.expiresAt !== undefined && (typeof record.expiresAt !== 'number' || !Number.isFinite(record.expiresAt))) {\n return undefined;\n }\n\n return record as StoredRecord<T>;\n}\n","import { validateRecord } from './codec';\nimport { VaultDisposedError, VaultError, VaultScopeError } from './errors';\nimport { createObserverHub, getRecordKey } from './internal';\nimport { createQueryBuilder } from './query';\nimport { assertPositiveFinite } from './ttl';\nimport type {\n AnySchema,\n DocumentVaultStore,\n DurableStoreOptions,\n KeyOf,\n KeyValueVaultStore,\n MemoryStoreOptions,\n RecordOf,\n TableCodecs,\n TransactionContext,\n} from './types';\n\n/* -------------------- Internal backend protocol -------------------- */\n\n/** @internal Full backend protocol implemented by each adapter. */\nexport type StorageBackend<S extends AnySchema, K extends keyof S & string = keyof S & string> = {\n clear<T extends K>(table: T): Promise<void>;\n count?<T extends K>(table: T): Promise<number>;\n delete<T extends K>(table: T, key: KeyOf<S, T>): Promise<boolean>;\n deleteMany?<T extends K>(table: T, keys: readonly KeyOf<S, T>[]): Promise<number>;\n dispose?(): Promise<void>;\n get<T extends K>(table: T, key: KeyOf<S, T>): Promise<RecordOf<S, T> | undefined>;\n getAll<T extends K>(table: T): Promise<RecordOf<S, T>[]>;\n getAllKeys?<T extends K>(table: T): Promise<KeyOf<S, T>[]>;\n getMany?<T extends K>(table: T, keys: readonly KeyOf<S, T>[]): Promise<Array<RecordOf<S, T> | undefined>>;\n has?<T extends K>(table: T, key: KeyOf<S, T>): Promise<boolean>;\n /**\n * Optional: lazy iteration over live records. Document stores implement this natively\n * (IDB cursor, SQLite keyset pagination). Key-value stores fall back to getAll().\n */\n iterate?<T extends K>(table: T): AsyncIterable<RecordOf<S, T>>;\n /**\n * Optional: prune all expired records across all tables in a single atomic operation.\n * When present, `pruneExpired()` delegates here instead of calling `pruneExpiredInTable` N times.\n */\n pruneAllExpired?(): Promise<Record<string, number>>;\n pruneExpiredInTable<T extends K>(table: T): Promise<number>;\n put<T extends K>(table: T, value: RecordOf<S, T>, ttl?: number): Promise<void>;\n putAll<T extends K>(table: T, values: readonly RecordOf<S, T>[], ttl?: number): Promise<void>;\n};\n\n/** @internal */\nexport type BatchDeps<S extends AnySchema> = {\n notifyMutation: (table: keyof S & string) => void;\n validate: <K extends keyof S & string>(table: K, value: RecordOf<S, K>) => RecordOf<S, K>;\n};\n\n/** @internal */\nexport type BatchImpl<S extends AnySchema> = <K extends keyof S & string, R>(\n tables: readonly K[],\n fn: (tx: TransactionContext<S, K>) => Promise<R>,\n) => Promise<R>;\n\n/* -------------------- Helpers -------------------- */\n\nexport function assertBatchTables(tables: readonly string[]): void {\n if (tables.length === 0) throw new VaultError('batch: declare at least one table');\n}\n\nfunction resolveTtl<S extends AnySchema, K extends keyof S & string>(\n schema: S,\n table: K,\n ttl?: number,\n): number | undefined {\n if (ttl !== undefined) assertPositiveFinite(ttl, 'put/putAll');\n\n return ttl ?? schema[table].defaultTtl;\n}\n\nfunction verifyKey<S extends AnySchema, K extends keyof S & string>(\n schema: S,\n table: K,\n expected: KeyOf<S, K>,\n value: RecordOf<S, K>,\n op: string,\n): void {\n const actual = getRecordKey(schema, table, value);\n\n if (actual !== expected) {\n throw new VaultError(\n `${op}: key field \"${schema[table].key}\" must be \"${String(expected)}\" but got \"${String(actual)}\" in table \"${table}\"`,\n );\n }\n}\n\n/* -------------------- Codec helpers -------------------- */\n\nexport function makeValidator<S extends AnySchema>(\n codecs: TableCodecs<S> | undefined,\n): <K extends keyof S & string>(table: K, value: RecordOf<S, K>) => RecordOf<S, K> {\n return <K extends keyof S & string>(table: K, value: RecordOf<S, K>): RecordOf<S, K> => {\n const codec = codecs?.[table];\n\n if (!codec) return value;\n\n try {\n return validateRecord(codec, value);\n } catch (err) {\n throw new VaultError(`validation failed for table \"${table}\"`, { cause: err });\n }\n };\n}\n\n/* -------------------- buildTxContext -------------------- */\n\nexport function buildTxContext<S extends AnySchema, K extends keyof S & string>(\n schema: S,\n core: StorageBackend<S, K>,\n onMutate: (table: K) => void,\n validate?: <T extends K>(table: T, value: RecordOf<S, T>) => RecordOf<S, T>,\n scope?: ReadonlySet<string>,\n isActive: () => boolean = () => true,\n): TransactionContext<S, K> {\n const applyValidation = validate ?? ((_: K, v: RecordOf<S, K>) => v);\n\n const checkScope = (table: K): void => {\n if (!isActive()) throw new VaultScopeError('transaction context is no longer active');\n if (scope && !scope.has(table)) throw new VaultScopeError(`table \"${table}\" is not part of this batch scope`);\n };\n\n const context: TransactionContext<S, K> = {\n async clear(table) {\n checkScope(table);\n await core.clear(table);\n onMutate(table);\n },\n async count(table) {\n checkScope(table);\n return core.count ? core.count(table) : (await core.getAll(table)).length;\n },\n async delete(table, key) {\n checkScope(table);\n\n const deleted = await core.delete(table, key);\n\n if (deleted) onMutate(table);\n\n return deleted;\n },\n async deleteMany(table, keys) {\n checkScope(table);\n if (!core.deleteMany) {\n const results = await Promise.all(keys.map((key) => core.delete(table, key)));\n const deleted = results.filter(Boolean).length;\n if (deleted > 0) onMutate(table);\n return deleted;\n }\n const deleted = await core.deleteMany(table, keys);\n if (deleted > 0) onMutate(table);\n return deleted;\n },\n async get(table, key) {\n checkScope(table);\n\n return core.get(table, key);\n },\n async getAll(table) {\n checkScope(table);\n\n return core.getAll(table);\n },\n async getMany(table, keys) {\n checkScope(table);\n return core.getMany ? core.getMany(table, keys) : Promise.all(keys.map((key) => core.get(table, key)));\n },\n async has(table, key) {\n checkScope(table);\n return core.has ? core.has(table, key) : (await core.get(table, key)) !== undefined;\n },\n async isEmpty(table) {\n return (await context.count(table)) === 0;\n },\n iterate(table) {\n checkScope(table);\n\n if (core.iterate) return core.iterate(table);\n\n // Fallback: iterate over getAll() materialized records.\n return (async function* (): AsyncIterable<RecordOf<S, typeof table>> {\n const records = await core.getAll(table);\n\n for (const record of records) yield record;\n })();\n },\n async keys(table, filter) {\n checkScope(table);\n if (!filter && core.getAllKeys) return core.getAllKeys(table);\n const records = await core.getAll(table);\n const selected = filter ? records.filter(filter) : records;\n const keyField = schema[table].key;\n return selected.map((record) => (record as Record<string, unknown>)[keyField] as KeyOf<S, typeof table>);\n },\n async put(table, value, ttl) {\n checkScope(table);\n const canonical = applyValidation(table, value);\n await core.put(table, canonical, resolveTtl(schema, table, ttl));\n onMutate(table);\n return canonical;\n },\n async putAll(table, values, ttl) {\n checkScope(table);\n\n if (values.length === 0) return;\n\n const toWrite = values.map((v) => applyValidation(table, v));\n\n await core.putAll(table, toWrite, resolveTtl(schema, table, ttl));\n onMutate(table);\n },\n query(table) {\n checkScope(table);\n return createQueryBuilder({\n deleteMany: async (records) => {\n const keys = records.map((record) => getRecordKey(schema, table, record));\n return context.deleteMany(table, keys);\n },\n source: () => context.getAll(table),\n });\n },\n async update(table, key, changes, ttl) {\n const current = await context.get(table, key);\n if (current === undefined) return undefined;\n const merged = { ...current, ...changes } as RecordOf<S, typeof table>;\n verifyKey(schema, table, key, merged, 'update');\n return context.put(table, merged, ttl);\n },\n async upsert(table, key, update, ttl) {\n const value = update(await context.get(table, key));\n verifyKey(schema, table, key, value, 'upsert: update()');\n return context.put(table, value, ttl);\n },\n };\n\n return context;\n}\n\n/* -------------------- buildKeyValueStore -------------------- */\n\n/** Builds a KeyValueVaultStore from a backend and options. */\nexport function buildKeyValueStore<S extends AnySchema>(\n schema: S,\n core: StorageBackend<S>,\n options?: MemoryStoreOptions<S> & {\n onCrossTabMessage?: (notify: (table: keyof S & string) => void) => (() => void) | undefined;\n onMutation?: (table: keyof S & string) => void;\n onTransactions?: (deps: BatchDeps<S>) => void;\n },\n): KeyValueVaultStore<S> {\n const { codecs } = options ?? {};\n\n const observers = createObserverHub<S>((table) => core.getAll(table));\n\n const notifyMutation = (table: keyof S & string): void => {\n observers.notify(table);\n options?.onMutation?.(table);\n };\n\n // Cross-tab notifications must NOT call onMutation (which would re-publish to BroadcastChannel,\n // creating an infinite loop). They only notify local observers.\n const notifyExternal = (table: keyof S & string): void => {\n observers.notify(table);\n };\n\n const pruneAll = core.pruneAllExpired?.bind(core);\n\n const disconnectExternal = options?.onCrossTabMessage?.(notifyExternal) ?? undefined;\n\n const validate = makeValidator(codecs);\n\n options?.onTransactions?.({ notifyMutation, validate });\n\n const disposeController = new AbortController();\n let disposed = false;\n\n const checkDisposed = (): void => {\n if (disposed) throw new VaultDisposedError();\n };\n\n const adapter: KeyValueVaultStore<S> = {\n async clear(table) {\n checkDisposed();\n await core.clear(table);\n notifyMutation(table);\n },\n async count(table) {\n checkDisposed();\n return core.count ? core.count(table) : (await core.getAll(table)).length;\n },\n\n async delete(table, key) {\n checkDisposed();\n\n const deleted = await core.delete(table, key);\n\n if (deleted) notifyMutation(table);\n\n return deleted;\n },\n async deleteMany(table, keys) {\n checkDisposed();\n const deleted = core.deleteMany\n ? await core.deleteMany(table, keys)\n : (await Promise.all(keys.map((key) => core.delete(table, key)))).filter(Boolean).length;\n if (deleted > 0) notifyMutation(table);\n return deleted;\n },\n\n get disposalSignal(): AbortSignal {\n return disposeController.signal;\n },\n\n async dispose() {\n if (disposed) return;\n\n disposed = true;\n disposeController.abort();\n disconnectExternal?.();\n observers.dispose();\n await core.dispose?.();\n },\n\n get disposed(): boolean {\n return disposed;\n },\n\n async get(table, key) {\n checkDisposed();\n\n return core.get(table, key);\n },\n\n async getAll(table) {\n checkDisposed();\n\n return core.getAll(table);\n },\n async getMany(table, keys) {\n checkDisposed();\n return core.getMany ? core.getMany(table, keys) : Promise.all(keys.map((key) => core.get(table, key)));\n },\n async has(table, key) {\n checkDisposed();\n return core.has ? core.has(table, key) : (await core.get(table, key)) !== undefined;\n },\n async isEmpty(table) {\n return (await adapter.count(table)) === 0;\n },\n async keys(table, filter) {\n checkDisposed();\n if (!filter && core.getAllKeys) return core.getAllKeys(table);\n const records = await core.getAll(table);\n const selected = filter ? records.filter(filter) : records;\n const keyField = schema[table].key;\n return selected.map((record) => (record as Record<string, unknown>)[keyField] as KeyOf<S, typeof table>);\n },\n\n observe(table, listener, opts) {\n checkDisposed();\n\n return observers.observe(table, listener, opts);\n },\n\n async pruneExpired() {\n checkDisposed();\n\n if (pruneAll) {\n const result = await pruneAll();\n\n for (const [table, pruned] of Object.entries(result)) {\n if (pruned > 0) notifyMutation(table as keyof S & string);\n }\n\n return result as { [K in keyof S & string]: number };\n }\n\n const tableNames = Object.keys(schema) as Array<keyof S & string>;\n const pairs = await Promise.all(\n tableNames.map(async (name) => {\n const pruned = await core.pruneExpiredInTable(name);\n\n return [name, pruned] as const;\n }),\n );\n\n for (const [table, pruned] of pairs) {\n if (pruned > 0) notifyMutation(table);\n }\n\n return Object.fromEntries(pairs) as { [K in keyof S & string]: number };\n },\n\n async put(table, value, ttl) {\n checkDisposed();\n const canonical = validate(table, value);\n await core.put(table, canonical, resolveTtl(schema, table, ttl));\n notifyMutation(table);\n return canonical;\n },\n\n async putAll(table, values, ttl) {\n checkDisposed();\n\n if (values.length === 0) return;\n\n const toWrite = values.map((v) => validate(table, v));\n\n await core.putAll(table, toWrite, resolveTtl(schema, table, ttl));\n notifyMutation(table);\n },\n query(table) {\n checkDisposed();\n return createQueryBuilder({\n deleteMany: async (records) => {\n const keys = records.map((record) => getRecordKey(schema, table, record));\n return adapter.deleteMany(table, keys);\n },\n source: () => adapter.getAll(table),\n });\n },\n async update(table, key, changes, ttl) {\n const current = await adapter.get(table, key);\n if (current === undefined) return undefined;\n const merged = { ...current, ...changes } as RecordOf<S, typeof table>;\n verifyKey(schema, table, key, merged, 'update');\n return adapter.put(table, merged, ttl);\n },\n async upsert(table, key, apply, ttl) {\n const value = apply(await adapter.get(table, key));\n verifyKey(schema, table, key, value, 'upsert: apply()');\n return adapter.put(table, value, ttl);\n },\n\n async [Symbol.asyncDispose]() {\n await adapter.dispose();\n },\n };\n\n return adapter;\n}\n\n/* -------------------- buildDocumentStore -------------------- */\n\n/** A document store before batch() is attached. */\nexport type DocumentVaultStoreWithoutBatch<S extends AnySchema> = Omit<DocumentVaultStore<S>, 'batch'>;\n\n/** Builds a DocumentVaultStore (without batch) from a backend, codecs, and options. */\nexport function buildDocumentStore<S extends AnySchema>(\n schema: S,\n core: StorageBackend<S>,\n options: DurableStoreOptions<S> & {\n onCrossTabMessage?: (notify: (table: keyof S & string) => void) => (() => void) | undefined;\n onMutation?: (table: keyof S & string) => void;\n onTransactions?: (deps: BatchDeps<S>) => void;\n },\n): DocumentVaultStoreWithoutBatch<S> {\n const store = buildKeyValueStore(schema, core, options);\n\n return Object.assign(store, {\n iterate<K extends keyof S & string>(table: K): AsyncIterable<RecordOf<S, K>> {\n if (store.disposed) throw new VaultDisposedError();\n if (core.iterate) return core.iterate(table);\n return (async function* (): AsyncIterable<RecordOf<S, K>> {\n for (const record of await store.getAll(table)) yield record;\n })();\n },\n });\n}\n\n/** Attaches a batch() implementation to a document store. */\nexport function withBatch<S extends AnySchema>(\n store: DocumentVaultStoreWithoutBatch<S>,\n batch: BatchImpl<S>,\n schema: S,\n): DocumentVaultStore<S> {\n const runBatch: BatchImpl<S> = (tables, fn) => {\n if (store.disposed) return Promise.reject(new VaultDisposedError());\n return batch(tables, fn);\n };\n\n return Object.assign(store, {\n batch: runBatch,\n deleteMany<K extends keyof S & string>(table: K, keys: readonly KeyOf<S, K>[]) {\n return runBatch([table], (tx) => tx.deleteMany(table, keys));\n },\n query<K extends keyof S & string>(table: K) {\n if (store.disposed) throw new VaultDisposedError();\n return createQueryBuilder({\n deleteMany: async (records) => {\n const keys = records.map((record) => getRecordKey(schema, table, record));\n return runBatch([table], (tx) => tx.deleteMany(table, keys));\n },\n source: () => store.getAll(table),\n });\n },\n update<K extends keyof S & string>(table: K, key: KeyOf<S, K>, changes: Partial<RecordOf<S, K>>, ttl?: number) {\n return runBatch([table], (tx) => tx.update(table, key, changes, ttl));\n },\n upsert<K extends keyof S & string>(\n table: K,\n key: KeyOf<S, K>,\n apply: (existing: RecordOf<S, K> | undefined) => RecordOf<S, K>,\n ttl?: number,\n ) {\n return runBatch([table], (tx) => tx.upsert(table, key, apply, ttl));\n },\n }) as DocumentVaultStore<S>;\n}\n\n/* -------------------- Derived convenience helpers -------------------- */\n\n/** Check whether a record exists for the given key. */\nexport async function has<S extends AnySchema, K extends keyof S & string>(\n store: KeyValueVaultStore<S>,\n table: K,\n key: KeyOf<S, K>,\n): Promise<boolean> {\n return store.has(table, key);\n}\n\n/** Count live records in a table. */\nexport async function count<S extends AnySchema, K extends keyof S & string>(\n store: KeyValueVaultStore<S>,\n table: K,\n): Promise<number> {\n return store.count(table);\n}\n\n/** Check whether a table has no live records. */\nexport async function isEmpty<S extends AnySchema, K extends keyof S & string>(\n store: KeyValueVaultStore<S>,\n table: K,\n): Promise<boolean> {\n return store.isEmpty(table);\n}\n\n/** Fetch multiple records by key. Preserves key order; missing keys yield `undefined`. */\nexport async function getMany<S extends AnySchema, K extends keyof S & string>(\n store: KeyValueVaultStore<S>,\n table: K,\n keys: readonly KeyOf<S, K>[],\n): Promise<Array<RecordOf<S, K> | undefined>> {\n return store.getMany(table, keys);\n}\n\n/** Fetch all live primary keys for a table. */\nexport async function keys<S extends AnySchema, K extends keyof S & string>(\n store: KeyValueVaultStore<S>,\n table: K,\n filter?: (record: RecordOf<S, K>) => boolean,\n): Promise<KeyOf<S, K>[]> {\n return store.keys(table, filter);\n}\n\n/** Delete multiple records by key. Returns the count of records that were actually deleted. */\nexport async function deleteMany<S extends AnySchema, K extends keyof S & string>(\n store: KeyValueVaultStore<S>,\n table: K,\n keys: readonly KeyOf<S, K>[],\n): Promise<number> {\n return store.deleteMany(table, keys);\n}\n\n/** Partially update an existing record. Returns `undefined` when the key does not exist. */\nexport async function update<S extends AnySchema, K extends keyof S & string>(\n store: KeyValueVaultStore<S>,\n table: K,\n key: KeyOf<S, K>,\n changes: Partial<RecordOf<S, K>>,\n ttl?: number,\n): Promise<RecordOf<S, K> | undefined> {\n return store.update(table, key, changes, ttl);\n}\n\n/** Read-modify-write: the callback receives the current record (or `undefined`) and returns the value to store. */\nexport async function upsert<S extends AnySchema, K extends keyof S & string>(\n store: KeyValueVaultStore<S>,\n table: K,\n key: KeyOf<S, K>,\n apply: (existing: RecordOf<S, K> | undefined) => RecordOf<S, K>,\n ttl?: number,\n): Promise<RecordOf<S, K>> {\n return store.upsert(table, key, apply, ttl);\n}\n","/// <reference lib=\"dom\" />\n\nimport { VaultError } from './errors';\nimport type { QueryBuilder } from './query';\nimport { assertPositiveFinite } from './ttl';\n\n/** Portable primary-key values. Vault preserves their type and encodes them distinctly at rest. */\nexport type VaultKey = number | string;\n\n/** A typed table definition whose primary-key field must hold a portable Vault key. */\nexport type SchemaEntry<T extends object, Key extends keyof T & string = keyof T & string> = {\n defaultTtl?: number;\n /** IndexedDB creates these as `value.<field>` indexes; other stores filter in memory. */\n indexes?: readonly (keyof T & string)[];\n key: Key;\n};\n\nexport type AnySchema = Record<string, { defaultTtl?: number; indexes?: readonly string[]; key: string }>;\n\nexport type RecordOf<S extends AnySchema, K extends keyof S> =\n S[K] extends SchemaEntry<infer R, infer _Key> ? R : never;\nexport type KeyOf<S extends AnySchema, K extends keyof S> = Extract<\n S[K] extends SchemaEntry<infer R, infer Key> ? R[Key] : never,\n VaultKey\n>;\n\n/** A codec validates and decodes persisted values crossing a trust boundary. */\nexport type RecordCodec<T> = {\n decode(value: unknown): T;\n encode(value: T): unknown;\n};\n\nexport type RecordParser<T> = {\n parse(value: unknown): T;\n};\n\nexport type CodecInput<T> = RecordCodec<T> | RecordParser<T>;\n\nexport type TableCodecs<S extends AnySchema> = {\n [K in keyof S]: CodecInput<RecordOf<S, K>>;\n};\n\n/** A validator-only codec: encodes values as-is, validates on decode. */\nexport function validatorCodec<T>(validator: RecordParser<T>): RecordCodec<T> {\n return {\n decode: (value) => validator.parse(value),\n encode: (value) => value,\n };\n}\n\nexport type Observer<T> = (records: T[]) => void;\nexport type Unsubscribe = () => void;\n\n/** Shared factory options for stores that do not require durable codecs. */\nexport type MemoryStoreOptions<S extends AnySchema> = {\n schema: S;\n /** Optional per-table codecs. Memory values never cross a trust boundary, so codecs may be omitted. */\n codecs?: TableCodecs<S>;\n};\n\n/** Shared factory options for durable stores whose values cross a trust boundary. */\nexport type DurableStoreOptions<S extends AnySchema> = {\n schema: S;\n /** Required per-table codecs. Persisted values are decoded through these before entering typed code. */\n codecs: TableCodecs<S>;\n};\n\nexport type VaultConveniences<S extends AnySchema, K extends keyof S & string = keyof S & string> = {\n count<T extends K>(table: T): Promise<number>;\n deleteMany<T extends K>(table: T, keys: readonly KeyOf<S, T>[]): Promise<number>;\n getMany<T extends K>(table: T, keys: readonly KeyOf<S, T>[]): Promise<Array<RecordOf<S, T> | undefined>>;\n has<T extends K>(table: T, key: KeyOf<S, T>): Promise<boolean>;\n isEmpty<T extends K>(table: T): Promise<boolean>;\n keys<T extends K>(table: T, filter?: (record: RecordOf<S, T>) => boolean): Promise<KeyOf<S, T>[]>;\n query<T extends K>(table: T): QueryBuilder<RecordOf<S, T>>;\n update<T extends K>(\n table: T,\n key: KeyOf<S, T>,\n changes: Partial<RecordOf<S, T>>,\n ttl?: number,\n ): Promise<RecordOf<S, T> | undefined>;\n upsert<T extends K>(\n table: T,\n key: KeyOf<S, T>,\n update: (existing: RecordOf<S, T> | undefined) => RecordOf<S, T>,\n ttl?: number,\n ): Promise<RecordOf<S, T>>;\n};\n\n/** Methods available within an IndexedDB or SQLite transaction. */\nexport type TransactionContext<S extends AnySchema, K extends keyof S & string = keyof S & string> = VaultConveniences<\n S,\n K\n> & {\n clear<T extends K>(table: T): Promise<void>;\n delete<T extends K>(table: T, key: KeyOf<S, T>): Promise<boolean>;\n get<T extends K>(table: T, key: KeyOf<S, T>): Promise<RecordOf<S, T> | undefined>;\n getAll<T extends K>(table: T): Promise<RecordOf<S, T>[]>;\n iterate<T extends K>(table: T): AsyncIterable<RecordOf<S, T>>;\n put<T extends K>(table: T, value: RecordOf<S, T>, ttl?: number): Promise<RecordOf<S, T>>;\n putAll<T extends K>(table: T, values: readonly RecordOf<S, T>[], ttl?: number): Promise<void>;\n};\n\n/** Key-value store for Memory and Web Storage: core CRUD, observation, TTL, and pruning. */\nexport interface KeyValueVaultStore<S extends AnySchema> extends VaultConveniences<S> {\n clear<K extends keyof S & string>(table: K): Promise<void>;\n delete<K extends keyof S & string>(table: K, key: KeyOf<S, K>): Promise<boolean>;\n readonly disposalSignal: AbortSignal;\n dispose(): Promise<void>;\n readonly disposed: boolean;\n get<K extends keyof S & string>(table: K, key: KeyOf<S, K>): Promise<RecordOf<S, K> | undefined>;\n getAll<K extends keyof S & string>(table: K): Promise<RecordOf<S, K>[]>;\n observe<K extends keyof S & string>(\n table: K,\n listener: Observer<RecordOf<S, K>>,\n options?: { immediate?: boolean; signal?: AbortSignal },\n ): Unsubscribe;\n pruneExpired(): Promise<Record<keyof S & string, number>>;\n put<K extends keyof S & string>(table: K, value: RecordOf<S, K>, ttl?: number): Promise<RecordOf<S, K>>;\n putAll<K extends keyof S & string>(table: K, values: readonly RecordOf<S, K>[], ttl?: number): Promise<void>;\n [Symbol.asyncDispose](): Promise<void>;\n}\n\n/** Document store for IndexedDB and SQLite: adds atomic transactions and lazy iteration. */\nexport interface DocumentVaultStore<S extends AnySchema> extends KeyValueVaultStore<S> {\n batch<K extends keyof S & string, R>(\n tables: readonly K[],\n fn: (tx: TransactionContext<S, K>) => Promise<R>,\n ): Promise<R>;\n iterate<K extends keyof S & string>(table: K): AsyncIterable<RecordOf<S, K>>;\n}\n\ntype VaultKeyField<T extends object> = {\n [K in keyof T & string]: T[K] extends VaultKey ? K : never;\n}[keyof T & string];\n\n/** Define a typed table whose primary-key field holds a portable Vault key. */\nexport function table<T extends object, Key extends VaultKeyField<T> = VaultKeyField<T>>(\n key: Key,\n options: { defaultTtl?: number; indexes?: readonly (keyof T & string)[] } = {},\n): SchemaEntry<T, Key> {\n const { defaultTtl, indexes } = options;\n\n if (defaultTtl !== undefined) assertPositiveFinite(defaultTtl, 'table: defaultTtl');\n\n if (indexes) {\n const seen = new Set<string>();\n\n for (const field of indexes) {\n if (seen.has(field)) {\n throw new VaultError(`table: index \"${field}\" is already registered`);\n }\n\n seen.add(field);\n }\n }\n\n return { defaultTtl, indexes, key };\n}\n"],"mappings":"mEAIA,IAAa,EAAb,cAAgC,KAAM,CACpC,OAA0B,UAAoB,aAE9C,YAAY,EAAiB,EAAqB,CAChD,MAAM,EAAS,CAAI,EACnB,KAAK,KAAQ,WAAiC,UAE9C,OAAO,eAAe,KAAM,WAAW,SAAS,CAClD,CACF,EAGa,EAAb,cAAwC,CAAW,CACjD,OAAmC,UAAY,qBAE/C,YAAY,EAAU,sBAAuB,EAAqB,CAChE,MAAM,EAAS,CAAI,CACrB,CACF,EAGa,EAAb,cAAqC,CAAW,CAC9C,OAAmC,UAAY,iBACjD,EAGa,EAAb,cAAqC,CAAW,CAC9C,OAAmC,UAAY,iBACjD,EAGa,EAAb,cAAyC,CAAW,CAClD,OAAmC,UAAY,qBACjD,EClCa,EAAM,CACjB,KAAO,GAAc,EAAqB,EAAI,MAAY,UAAU,EACpE,MAAQ,GAAc,EAAqB,EAAI,KAAW,WAAW,EACrE,QAAU,GAAc,EAAqB,EAAI,IAAQ,aAAa,EACtE,GAAK,GAAc,EAAqB,EAAG,QAAQ,EACnD,QAAU,GAAc,EAAqB,EAAI,IAAM,aAAa,CACtE,EAKA,SAAgB,EAAU,EAAwC,CAChE,OAAO,IAAc,IAAA,IAAa,KAAK,IAAI,GAAK,CAClD,CAGA,SAAgB,EAAqB,EAAe,EAAwB,CAC1E,GAAI,CAAC,OAAO,SAAS,CAAK,GAAK,GAAS,EACtC,MAAM,IAAI,EAAW,GAAG,EAAO,+CAA+C,OAAO,CAAK,GAAG,EAG/F,OAAO,CACT,CC2eA,eAAsB,EACpB,EACA,EACA,EACkB,CAClB,OAAO,EAAM,IAAI,EAAO,CAAG,CAC7B,CAGA,eAAsB,EACpB,EACA,EACiB,CACjB,OAAO,EAAM,MAAM,CAAK,CAC1B,CAGA,eAAsB,EACpB,EACA,EACkB,CAClB,OAAO,EAAM,QAAQ,CAAK,CAC5B,CAGA,eAAsB,EACpB,EACA,EACA,EAC4C,CAC5C,OAAO,EAAM,QAAQ,EAAO,CAAI,CAClC,CAGA,eAAsB,EACpB,EACA,EACA,EACwB,CACxB,OAAO,EAAM,KAAK,EAAO,CAAM,CACjC,CAGA,eAAsB,EACpB,EACA,EACA,EACiB,CACjB,OAAO,EAAM,WAAW,EAAO,CAAI,CACrC,CAGA,eAAsB,EACpB,EACA,EACA,EACA,EACA,EACqC,CACrC,OAAO,EAAM,OAAO,EAAO,EAAK,EAAS,CAAG,CAC9C,CAGA,eAAsB,EACpB,EACA,EACA,EACA,EACA,EACyB,CACzB,OAAO,EAAM,OAAO,EAAO,EAAK,EAAO,CAAG,CAC5C,CChiBA,SAAgB,EAAkB,EAA4C,CAC5E,MAAO,CACL,OAAS,GAAU,EAAU,MAAM,CAAK,EACxC,OAAS,GAAU,CACrB,CACF,CAyFA,SAAgB,EACd,EACA,EAA4E,CAAC,EACxD,CACrB,GAAM,CAAE,aAAY,WAAY,EAIhC,GAFI,IAAe,IAAA,IAAW,EAAqB,EAAY,mBAAmB,EAE9E,EAAS,CACX,IAAM,EAAO,IAAI,IAEjB,IAAK,IAAM,KAAS,EAAS,CAC3B,GAAI,EAAK,IAAI,CAAK,EAChB,MAAM,IAAI,EAAW,iBAAiB,EAAM,wBAAwB,EAGtE,EAAK,IAAI,CAAK,CAChB,CACF,CAEA,MAAO,CAAE,aAAY,UAAS,KAAI,CACpC"}
1
+ {"version":3,"file":"vault.cjs","names":[],"sources":["../src/errors.ts","../src/ttl.ts","../src/types.ts"],"sourcesContent":["/**\n * Base class for all vault errors. Catch with `instanceof VaultError` to\n * handle any vault-originated error regardless of its specific subtype.\n */\nexport class VaultError extends Error {\n constructor(message: string, opts?: ErrorOptions) {\n super(message, opts);\n this.name = new.target.name;\n // Ensures `instanceof` works correctly when transpiled to ES5.\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/** Thrown when an operation is attempted on a disposed adapter or observer hub. */\nexport class VaultDisposedError extends VaultError {\n constructor(message = 'adapter is disposed', opts?: ErrorOptions) {\n super(message, opts);\n }\n}\n\n/** Thrown when a `batch()` callback accesses a table not declared in the scope. */\nexport class VaultScopeError extends VaultError {}\n\n/** Thrown when a WebStorage write exceeds the storage quota. */\nexport class VaultQuotaError extends VaultError {}\n\n/** Thrown when an IndexedDB `onupgradeneeded` migration callback throws. */\nexport class VaultMigrationError extends VaultError {}\n","import { VaultError } from './errors';\n\n/** Duration helpers that produce finite, positive millisecond values. */\nexport const ttl = {\n days: (n: number) => assertPositiveFinite(n * 86_400_000, 'ttl.days'),\n hours: (n: number) => assertPositiveFinite(n * 3_600_000, 'ttl.hours'),\n minutes: (n: number) => assertPositiveFinite(n * 60_000, 'ttl.minutes'),\n ms: (n: number) => assertPositiveFinite(n, 'ttl.ms'),\n seconds: (n: number) => assertPositiveFinite(n * 1000, 'ttl.seconds'),\n} as const;\n\n/** Fixed storage envelope shared by every adapter, so data and indexes stay portable. */\nexport type StoredRecord<T> = { expiresAt?: number; value: T };\n\nexport function isExpired(expiresAt: number | undefined): boolean {\n return expiresAt !== undefined && Date.now() >= expiresAt;\n}\n\n/** Throws when `ttlMs` is not a finite, positive number. Returns it unchanged otherwise. */\nexport function assertPositiveFinite(ttlMs: number, source: string): number {\n if (!Number.isFinite(ttlMs) || ttlMs <= 0) {\n throw new VaultError(`${source} expected a finite positive number, received ${String(ttlMs)}`);\n }\n\n return ttlMs;\n}\n\nexport function parseStored<T>(raw: unknown): StoredRecord<T> | undefined {\n if (typeof raw !== 'object' || raw === null || !('value' in raw)) return undefined;\n\n const record = raw as { expiresAt?: unknown; value: unknown };\n\n if (record.expiresAt !== undefined && (typeof record.expiresAt !== 'number' || !Number.isFinite(record.expiresAt))) {\n return undefined;\n }\n\n return record as StoredRecord<T>;\n}\n","/// <reference lib=\"dom\" />\n\nimport { VaultError } from './errors';\nimport { assertPositiveFinite } from './ttl';\n\n/** Portable primary-key values. Vault preserves their type and encodes them distinctly at rest. */\nexport type VaultKey = number | string;\n\n/** A typed table definition whose primary-key field must hold a portable Vault key. */\nexport type SchemaEntry<T extends object, Key extends keyof T & string = keyof T & string> = {\n defaultTtl?: number;\n /** IndexedDB creates these as `value.<field>` indexes; other stores filter in memory. */\n indexes?: readonly (keyof T & string)[];\n key: Key;\n};\n\nexport type AnySchema = Record<string, { defaultTtl?: number; indexes?: readonly string[]; key: string }>;\n\nexport type RecordOf<S extends AnySchema, K extends keyof S> =\n S[K] extends SchemaEntry<infer R, infer _Key> ? R : never;\nexport type KeyOf<S extends AnySchema, K extends keyof S> = Extract<\n S[K] extends SchemaEntry<infer R, infer Key> ? R[Key] : never,\n VaultKey\n>;\n\n/** A codec validates and decodes persisted values crossing a trust boundary. */\nexport type RecordCodec<T> = {\n decode(value: unknown): T;\n encode(value: T): unknown;\n};\n\nexport type RecordParser<T> = {\n parse(value: unknown): T;\n};\n\nexport type CodecInput<T> = RecordCodec<T> | RecordParser<T>;\n\nexport type TableCodecs<S extends AnySchema> = {\n [K in keyof S]: CodecInput<RecordOf<S, K>>;\n};\n\n/** A validator-only codec: encodes values as-is, validates on decode. */\nexport function validatorCodec<T>(validator: RecordParser<T>): RecordCodec<T> {\n return {\n decode: (value) => validator.parse(value),\n encode: (value) => value,\n };\n}\n\nexport type Observer<T> = (records: T[]) => void;\nexport type Unsubscribe = () => void;\n\n/** Shared factory options for stores that do not require durable codecs. */\nexport type MemoryStoreOptions<S extends AnySchema> = {\n schema: S;\n /** Optional per-table codecs. Memory values never cross a trust boundary, so codecs may be omitted. */\n codecs?: TableCodecs<S>;\n};\n\n/** Shared factory options for durable stores whose values cross a trust boundary. */\nexport type DurableStoreOptions<S extends AnySchema> = {\n schema: S;\n /** Required per-table codecs. Persisted values are decoded through these before entering typed code. */\n codecs: TableCodecs<S>;\n};\n\nexport type VaultConveniences<S extends AnySchema, K extends keyof S & string = keyof S & string> = {\n count<T extends K>(table: T): Promise<number>;\n deleteMany<T extends K>(table: T, keys: readonly KeyOf<S, T>[]): Promise<number>;\n getMany<T extends K>(table: T, keys: readonly KeyOf<S, T>[]): Promise<Array<RecordOf<S, T> | undefined>>;\n has<T extends K>(table: T, key: KeyOf<S, T>): Promise<boolean>;\n isEmpty<T extends K>(table: T): Promise<boolean>;\n keys<T extends K>(table: T, filter?: (record: RecordOf<S, T>) => boolean): Promise<KeyOf<S, T>[]>;\n update<T extends K>(\n table: T,\n key: KeyOf<S, T>,\n changes: Partial<RecordOf<S, T>>,\n ttl?: number,\n ): Promise<RecordOf<S, T> | undefined>;\n upsert<T extends K>(\n table: T,\n key: KeyOf<S, T>,\n update: (existing: RecordOf<S, T> | undefined) => RecordOf<S, T>,\n ttl?: number,\n ): Promise<RecordOf<S, T>>;\n};\n\n/** Methods available within an IndexedDB or SQLite transaction. */\nexport type TransactionContext<S extends AnySchema, K extends keyof S & string = keyof S & string> = VaultConveniences<\n S,\n K\n> & {\n clear<T extends K>(table: T): Promise<void>;\n delete<T extends K>(table: T, key: KeyOf<S, T>): Promise<boolean>;\n get<T extends K>(table: T, key: KeyOf<S, T>): Promise<RecordOf<S, T> | undefined>;\n getAll<T extends K>(table: T): Promise<RecordOf<S, T>[]>;\n iterate<T extends K>(table: T): AsyncIterable<RecordOf<S, T>>;\n put<T extends K>(table: T, value: RecordOf<S, T>, ttl?: number): Promise<RecordOf<S, T>>;\n putAll<T extends K>(table: T, values: readonly RecordOf<S, T>[], ttl?: number): Promise<void>;\n};\n\n/** Key-value store for Memory and Web Storage: core CRUD, observation, TTL, and pruning. */\nexport interface KeyValueVaultStore<S extends AnySchema> extends VaultConveniences<S> {\n clear<K extends keyof S & string>(table: K): Promise<void>;\n delete<K extends keyof S & string>(table: K, key: KeyOf<S, K>): Promise<boolean>;\n readonly disposalSignal: AbortSignal;\n dispose(): Promise<void>;\n readonly disposed: boolean;\n get<K extends keyof S & string>(table: K, key: KeyOf<S, K>): Promise<RecordOf<S, K> | undefined>;\n getAll<K extends keyof S & string>(table: K): Promise<RecordOf<S, K>[]>;\n observe<K extends keyof S & string>(\n table: K,\n listener: Observer<RecordOf<S, K>>,\n options?: { immediate?: boolean; signal?: AbortSignal },\n ): Unsubscribe;\n pruneExpired(): Promise<Record<keyof S & string, number>>;\n put<K extends keyof S & string>(table: K, value: RecordOf<S, K>, ttl?: number): Promise<RecordOf<S, K>>;\n putAll<K extends keyof S & string>(table: K, values: readonly RecordOf<S, K>[], ttl?: number): Promise<void>;\n [Symbol.asyncDispose](): Promise<void>;\n}\n\n/** Document store for IndexedDB and SQLite: adds atomic transactions and lazy iteration. */\nexport interface DocumentVaultStore<S extends AnySchema> extends KeyValueVaultStore<S> {\n batch<K extends keyof S & string, R>(\n tables: readonly K[],\n fn: (tx: TransactionContext<S, K>) => Promise<R>,\n ): Promise<R>;\n iterate<K extends keyof S & string>(table: K): AsyncIterable<RecordOf<S, K>>;\n}\n\ntype VaultKeyField<T extends object> = {\n [K in keyof T & string]: T[K] extends VaultKey ? K : never;\n}[keyof T & string];\n\n/** Define a typed table whose primary-key field holds a portable Vault key. */\nexport function table<T extends object, Key extends VaultKeyField<T> = VaultKeyField<T>>(\n key: Key,\n options: { defaultTtl?: number; indexes?: readonly (keyof T & string)[] } = {},\n): SchemaEntry<T, Key> {\n const { defaultTtl, indexes } = options;\n\n if (defaultTtl !== undefined) assertPositiveFinite(defaultTtl, 'table: defaultTtl');\n\n if (indexes) {\n const seen = new Set<string>();\n\n for (const field of indexes) {\n if (seen.has(field)) {\n throw new VaultError(`table: index \"${field}\" is already registered`);\n }\n\n seen.add(field);\n }\n }\n\n return { defaultTtl, indexes, key };\n}\n"],"mappings":"mEAIA,IAAa,WAAb,cAAgC,KAAM,CACpC,YAAY,EAAiB,EAAqB,CAChD,MAAM,EAAS,CAAI,EACnB,KAAK,KAAO,WAAW,KAEvB,OAAO,eAAe,KAAM,WAAW,SAAS,CAClD,CACF,EAGa,mBAAb,cAAwC,UAAW,CACjD,YAAY,EAAU,sBAAuB,EAAqB,CAChE,MAAM,EAAS,CAAI,CACrB,CACF,EAGa,gBAAb,cAAqC,UAAW,CAAC,EAGpC,gBAAb,cAAqC,UAAW,CAAC,EAGpC,oBAAb,cAAyC,UAAW,CAAC,ECxBxC,EAAM,CACjB,KAAO,GAAc,qBAAqB,EAAI,MAAY,UAAU,EACpE,MAAQ,GAAc,qBAAqB,EAAI,KAAW,WAAW,EACrE,QAAU,GAAc,qBAAqB,EAAI,IAAQ,aAAa,EACtE,GAAK,GAAc,qBAAqB,EAAG,QAAQ,EACnD,QAAU,GAAc,qBAAqB,EAAI,IAAM,aAAa,CACtE,EAUA,SAAgB,qBAAqB,EAAe,EAAwB,CAC1E,GAAI,CAAC,OAAO,SAAS,CAAK,GAAK,GAAS,EACtC,MAAM,IAAI,WAAW,GAAG,EAAO,+CAA+C,OAAO,CAAK,GAAG,EAG/F,OAAO,CACT,CCiBA,SAAgB,eAAkB,EAA4C,CAC5E,MAAO,CACL,OAAS,GAAU,EAAU,MAAM,CAAK,EACxC,OAAS,GAAU,CACrB,CACF,CAwFA,SAAgB,MACd,EACA,EAA4E,CAAC,EACxD,CACrB,GAAM,CAAE,aAAY,WAAY,EAIhC,GAFI,IAAe,IAAA,IAAW,qBAAqB,EAAY,mBAAmB,EAE9E,EAAS,CACX,IAAM,EAAO,IAAI,IAEjB,IAAK,IAAM,KAAS,EAAS,CAC3B,GAAI,EAAK,IAAI,CAAK,EAChB,MAAM,IAAI,WAAW,iBAAiB,EAAM,wBAAwB,EAGtE,EAAK,IAAI,CAAK,CAChB,CACF,CAEA,MAAO,CAAE,aAAY,UAAS,KAAI,CACpC"}
@@ -1,2 +1,2 @@
1
- var Vault=(function(e){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});var t=class extends Error{static errorName=`VaultError`;constructor(e,t){super(e,t),this.name=new.target.errorName,Object.setPrototypeOf(this,new.target.prototype)}},n=class extends t{static errorName=`VaultDisposedError`;constructor(e=`adapter is disposed`,t){super(e,t)}},r=class extends t{static errorName=`VaultScopeError`},i=class extends t{static errorName=`VaultQuotaError`},a=class extends t{static errorName=`VaultMigrationError`},o={days:e=>c(e*864e5,`ttl.days`),hours:e=>c(e*36e5,`ttl.hours`),minutes:e=>c(e*6e4,`ttl.minutes`),ms:e=>c(e,`ttl.ms`),seconds:e=>c(e*1e3,`ttl.seconds`)};function s(e){return e!==void 0&&Date.now()>=e}function c(e,n){if(!Number.isFinite(e)||e<=0)throw new t(`${n} expected a finite positive number, received ${String(e)}`);return e}async function l(e,t,n){return e.has(t,n)}async function u(e,t){return e.count(t)}async function d(e,t){return e.isEmpty(t)}async function f(e,t,n){return e.getMany(t,n)}async function p(e,t,n){return e.keys(t,n)}async function m(e,t,n){return e.deleteMany(t,n)}async function h(e,t,n,r,i){return e.update(t,n,r,i)}async function g(e,t,n,r,i){return e.upsert(t,n,r,i)}function _(e){return{decode:t=>e.parse(t),encode:e=>e}}function v(e,n={}){let{defaultTtl:r,indexes:i}=n;if(r!==void 0&&c(r,`table: defaultTtl`),i){let e=new Set;for(let n of i){if(e.has(n))throw new t(`table: index "${n}" is already registered`);e.add(n)}}return{defaultTtl:r,indexes:i,key:e}}return e.VaultDisposedError=n,e.VaultError=t,e.VaultMigrationError=a,e.VaultQuotaError=i,e.VaultScopeError=r,e.count=u,e.deleteMany=m,e.getMany=f,e.has=l,e.isEmpty=d,e.isExpired=s,e.keys=p,e.table=v,e.ttl=o,e.update=h,e.upsert=g,e.validatorCodec=_,e})({});
1
+ var Vault=(function(e){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});var VaultError=class extends Error{constructor(e,t){super(e,t),this.name=new.target.name,Object.setPrototypeOf(this,new.target.prototype)}},VaultDisposedError=class extends VaultError{constructor(e=`adapter is disposed`,t){super(e,t)}},VaultScopeError=class extends VaultError{},VaultQuotaError=class extends VaultError{},VaultMigrationError=class extends VaultError{},t={days:e=>assertPositiveFinite(e*864e5,`ttl.days`),hours:e=>assertPositiveFinite(e*36e5,`ttl.hours`),minutes:e=>assertPositiveFinite(e*6e4,`ttl.minutes`),ms:e=>assertPositiveFinite(e,`ttl.ms`),seconds:e=>assertPositiveFinite(e*1e3,`ttl.seconds`)};function assertPositiveFinite(e,t){if(!Number.isFinite(e)||e<=0)throw new VaultError(`${t} expected a finite positive number, received ${String(e)}`);return e}function validatorCodec(e){return{decode:t=>e.parse(t),encode:e=>e}}function table(e,t={}){let{defaultTtl:n,indexes:r}=t;if(n!==void 0&&assertPositiveFinite(n,`table: defaultTtl`),r){let e=new Set;for(let t of r){if(e.has(t))throw new VaultError(`table: index "${t}" is already registered`);e.add(t)}}return{defaultTtl:n,indexes:r,key:e}}return e.VaultDisposedError=VaultDisposedError,e.VaultError=VaultError,e.VaultMigrationError=VaultMigrationError,e.VaultQuotaError=VaultQuotaError,e.VaultScopeError=VaultScopeError,e.table=table,e.ttl=t,e.validatorCodec=validatorCodec,e})({});
2
2
  //# sourceMappingURL=vault.iife.js.map