@noy-db/hub 0.2.0-pre.29 → 0.2.0-pre.30
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.
- package/dist/aggregate/index.js +1 -0
- package/dist/aggregate/index.js.map +1 -1
- package/dist/attestation/index.d.cts +1 -1
- package/dist/attestation/index.d.ts +1 -1
- package/dist/attestation/index.js +4 -3
- package/dist/attestation/index.js.map +1 -1
- package/dist/blobs/index.d.cts +3 -3
- package/dist/blobs/index.d.ts +3 -3
- package/dist/blobs/index.js +2 -1
- package/dist/blobs/index.js.map +1 -1
- package/dist/bundle/index.cjs +16825 -893
- package/dist/bundle/index.cjs.map +1 -1
- package/dist/bundle/index.d.cts +3 -3
- package/dist/bundle/index.d.ts +3 -3
- package/dist/bundle/index.js +2 -1
- package/dist/bundle/index.js.map +1 -1
- package/dist/{chunk-DJO4OYCJ.js → chunk-33EQCZXE.js} +2 -2
- package/dist/{chunk-ZDW22N3E.js → chunk-BVKLJBJJ.js} +694 -191
- package/dist/chunk-BVKLJBJJ.js.map +1 -0
- package/dist/{chunk-REHF3HSJ.js → chunk-K4JID2ZE.js} +16 -3
- package/dist/chunk-K4JID2ZE.js.map +1 -0
- package/dist/{chunk-553CK4E2.js → chunk-OCYFFBZS.js} +2 -2
- package/dist/chunk-PZ5AY32C.js +10 -0
- package/dist/{chunk-45QJXLLS.js → chunk-Y6YUWZTS.js} +2 -2
- package/dist/{chunk-6BSYMFYS.js → chunk-ZK66B5EY.js} +2 -2
- package/dist/{chunk-BITB3T5Z.js → chunk-ZPJSQPQH.js} +2 -2
- package/dist/consent/index.d.cts +2 -2
- package/dist/consent/index.d.ts +2 -2
- package/dist/consent/index.js +1 -0
- package/dist/consent/index.js.map +1 -1
- package/dist/crdt/index.js +1 -0
- package/dist/crdt/index.js.map +1 -1
- package/dist/{crypto-G6XU2V2Y.js → crypto-OSIV2IIW.js} +2 -1
- package/dist/{decrypt-partition-DDSArPPW.d.cts → decrypt-partition-C0iDpbSd.d.cts} +1 -1
- package/dist/{decrypt-partition-5Gt0EcTc.d.ts → decrypt-partition-Mhjh6nnG.d.ts} +1 -1
- package/dist/{delegation-ZEH4LKEM.js → delegation-BQTRJATI.js} +2 -1
- package/dist/derivations/index.d.cts +3 -3
- package/dist/derivations/index.d.ts +3 -3
- package/dist/derivations/index.js +1 -0
- package/dist/{dev-unlock-CIkHrcRm.d.cts → dev-unlock-0Z6yxfS7.d.cts} +1 -1
- package/dist/{dev-unlock-BF9IhLPn.d.ts → dev-unlock-DJ3IhgY9.d.ts} +1 -1
- package/dist/{executor-DWVP4BSJ.js → executor-KYSKFJ2R.js} +2 -1
- package/dist/{executor-HO3SIRSF.js → executor-M7W3NEKR.js} +2 -1
- package/dist/{executor-HB2YMIYC.js → executor-VDTDGWO6.js} +2 -1
- package/dist/{fanout-sidecar-BMT7I6FI.js → fanout-sidecar-AZALISHB.js} +2 -1
- package/dist/{fanout-sidecar-BMT7I6FI.js.map → fanout-sidecar-AZALISHB.js.map} +1 -1
- package/dist/forget/index.js +1 -0
- package/dist/guards/index.d.cts +3 -3
- package/dist/guards/index.d.ts +3 -3
- package/dist/guards/index.js +1 -0
- package/dist/{hash-Jl0qarQx.d.ts → hash-DLwkYf1d.d.ts} +1 -1
- package/dist/{hash-DfhndFcd.d.cts → hash-Db8ncXGr.d.cts} +1 -1
- package/dist/history/index.d.cts +3 -3
- package/dist/history/index.d.ts +3 -3
- package/dist/history/index.js +1 -0
- package/dist/history/index.js.map +1 -1
- package/dist/i18n/index.cjs +15 -2
- package/dist/i18n/index.cjs.map +1 -1
- package/dist/i18n/index.d.cts +2 -2
- package/dist/i18n/index.d.ts +2 -2
- package/dist/i18n/index.js +2 -1
- package/dist/i18n/index.js.map +1 -1
- package/dist/{index-DcxTv3zx.d.ts → index-CMRIx_zx.d.ts} +1 -1
- package/dist/{index-DPG2nFmT.d.cts → index-xJEPkvMb.d.cts} +1 -1
- package/dist/index.cjs +16956 -1011
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +19 -16
- package/dist/index.d.ts +19 -16
- package/dist/index.js +8 -7
- package/dist/index.js.map +1 -1
- package/dist/indexing/index.js +1 -0
- package/dist/indexing/index.js.map +1 -1
- package/dist/{issue-FZRTVGRE.js → issue-DPHRF2TI.js} +2 -1
- package/dist/kernel/index.cjs.map +1 -1
- package/dist/kernel/index.d.cts +2 -2
- package/dist/kernel/index.d.ts +2 -2
- package/dist/kernel/index.js +1 -0
- package/dist/{ledger-PMTR2Q62.js → ledger-CI7GSMLB.js} +2 -1
- package/dist/materialized-views/index.d.cts +3 -3
- package/dist/materialized-views/index.d.ts +3 -3
- package/dist/materialized-views/index.js +2 -1
- package/dist/{mime-magic-BOI-I5dq.d.ts → mime-magic-CacDBwYp.d.ts} +1 -1
- package/dist/{mime-magic-C0TM7FtF.d.cts → mime-magic-sdMzsfVK.d.cts} +1 -1
- package/dist/{noydb-Y3ZLZNXA.js → noydb-5MIBD77B.js} +6 -5
- package/dist/overlay-views/index.d.cts +3 -3
- package/dist/overlay-views/index.d.ts +3 -3
- package/dist/overlay-views/index.js +1 -0
- package/dist/periods/index.d.cts +2 -2
- package/dist/periods/index.d.ts +2 -2
- package/dist/periods/index.js +2 -1
- package/dist/{public-envelope-S2S2VR3F.js → public-envelope-MFMBFJLZ.js} +2 -1
- package/dist/query/index.js +1 -0
- package/dist/{read-only-facade-EX6WZZBP.js → read-only-facade-3OQRZ3VS.js} +2 -1
- package/dist/{registry-DKEXOJVO.js → registry-IX5WKK4F.js} +2 -1
- package/dist/{registry-53A55ZZE.js → registry-LMHO5265.js} +2 -1
- package/dist/{registry-IEU6ATO7.js → registry-TXCKWH26.js} +2 -1
- package/dist/{registry-FKL4SLU4.js → registry-VFEDQSYV.js} +2 -1
- package/dist/{revoke-AOCAVR56.js → revoke-5PUOZPJJ.js} +2 -1
- package/dist/sealed-record/index.js +1 -0
- package/dist/sealed-record/index.js.map +1 -1
- package/dist/session/index.d.cts +3 -3
- package/dist/session/index.d.ts +3 -3
- package/dist/session/index.js +1 -0
- package/dist/session/index.js.map +1 -1
- package/dist/shadow/index.d.cts +2 -2
- package/dist/shadow/index.d.ts +2 -2
- package/dist/shadow/index.js +1 -0
- package/dist/shadow/index.js.map +1 -1
- package/dist/{signer-JMK6W2Y6.js → signer-UB5TQOZ6.js} +2 -1
- package/dist/snapshots/index.d.cts +2 -2
- package/dist/snapshots/index.d.ts +2 -2
- package/dist/snapshots/index.js +1 -0
- package/dist/snapshots/index.js.map +1 -1
- package/dist/{stale-IIIGOHBW.js → stale-J3TUF5C5.js} +3 -2
- package/dist/store/index.d.cts +2 -2
- package/dist/store/index.d.ts +2 -2
- package/dist/store/index.js +1 -0
- package/dist/sync/index.d.cts +1 -1
- package/dist/sync/index.d.ts +1 -1
- package/dist/sync/index.js +1 -0
- package/dist/sync/index.js.map +1 -1
- package/dist/team/index.d.cts +2 -2
- package/dist/team/index.d.ts +2 -2
- package/dist/team/index.js +1 -0
- package/dist/{transition-guard-BixCDmBI.d.ts → transition-guard-J04-jime.d.ts} +1 -1
- package/dist/{transition-guard-DnAlUf9R.d.cts → transition-guard-tWZIsaXe.d.cts} +1 -1
- package/dist/tx/index.d.cts +2 -2
- package/dist/tx/index.d.ts +2 -2
- package/dist/tx/index.js +3 -2
- package/dist/tx/index.js.map +1 -1
- package/dist/{types-Ba1vQ3AY.d.cts → types-CdVfiQgt.d.cts} +444 -161
- package/dist/{types-CUmZYJwN.d.ts → types-DHn9lEP0.d.ts} +444 -161
- package/dist/{ulid-COREQ2RQ.js → ulid-KEPZMD2N.js} +2 -1
- package/dist/ulid-KEPZMD2N.js.map +1 -0
- package/dist/util/index.js +1 -0
- package/dist/util/index.js.map +1 -1
- package/dist/{with-materialized-view-Bjx6VYPc.d.ts → with-materialized-view-DNfzC5lH.d.ts} +1 -1
- package/dist/{with-materialized-view-Z_aHLln6.d.cts → with-materialized-view-DfgPcvi9.d.cts} +1 -1
- package/dist/{with-overlayed-view-pTOFgHRq.d.cts → with-overlayed-view-Cvfkx1lg.d.cts} +1 -1
- package/dist/{with-overlayed-view-B8PkL179.d.ts → with-overlayed-view-qk3lbhOd.d.ts} +1 -1
- package/dist/{with-rollup-Cd3t01Mz.d.ts → with-rollup-Dd3_ZG4b.d.ts} +1 -1
- package/dist/{with-rollup-D9qQoffP.d.cts → with-rollup-nIxo7h9z.d.cts} +1 -1
- package/dist/zod-HAJM7LMS.js +14763 -0
- package/dist/zod-HAJM7LMS.js.map +1 -0
- package/package.json +4 -4
- package/dist/chunk-REHF3HSJ.js.map +0 -1
- package/dist/chunk-ZDW22N3E.js.map +0 -1
- /package/dist/{chunk-DJO4OYCJ.js.map → chunk-33EQCZXE.js.map} +0 -0
- /package/dist/{chunk-553CK4E2.js.map → chunk-OCYFFBZS.js.map} +0 -0
- /package/dist/{crypto-G6XU2V2Y.js.map → chunk-PZ5AY32C.js.map} +0 -0
- /package/dist/{chunk-45QJXLLS.js.map → chunk-Y6YUWZTS.js.map} +0 -0
- /package/dist/{chunk-6BSYMFYS.js.map → chunk-ZK66B5EY.js.map} +0 -0
- /package/dist/{chunk-BITB3T5Z.js.map → chunk-ZPJSQPQH.js.map} +0 -0
- /package/dist/{delegation-ZEH4LKEM.js.map → crypto-OSIV2IIW.js.map} +0 -0
- /package/dist/{executor-DWVP4BSJ.js.map → delegation-BQTRJATI.js.map} +0 -0
- /package/dist/{executor-HB2YMIYC.js.map → executor-KYSKFJ2R.js.map} +0 -0
- /package/dist/{executor-HO3SIRSF.js.map → executor-M7W3NEKR.js.map} +0 -0
- /package/dist/{issue-FZRTVGRE.js.map → executor-VDTDGWO6.js.map} +0 -0
- /package/dist/{ledger-PMTR2Q62.js.map → issue-DPHRF2TI.js.map} +0 -0
- /package/dist/{noydb-Y3ZLZNXA.js.map → ledger-CI7GSMLB.js.map} +0 -0
- /package/dist/{public-envelope-S2S2VR3F.js.map → noydb-5MIBD77B.js.map} +0 -0
- /package/dist/{read-only-facade-EX6WZZBP.js.map → public-envelope-MFMBFJLZ.js.map} +0 -0
- /package/dist/{registry-53A55ZZE.js.map → read-only-facade-3OQRZ3VS.js.map} +0 -0
- /package/dist/{registry-DKEXOJVO.js.map → registry-IX5WKK4F.js.map} +0 -0
- /package/dist/{registry-FKL4SLU4.js.map → registry-LMHO5265.js.map} +0 -0
- /package/dist/{registry-IEU6ATO7.js.map → registry-TXCKWH26.js.map} +0 -0
- /package/dist/{revoke-AOCAVR56.js.map → registry-VFEDQSYV.js.map} +0 -0
- /package/dist/{signer-JMK6W2Y6.js.map → revoke-5PUOZPJJ.js.map} +0 -0
- /package/dist/{stale-IIIGOHBW.js.map → signer-UB5TQOZ6.js.map} +0 -0
- /package/dist/{ulid-COREQ2RQ.js.map → stale-J3TUF5C5.js.map} +0 -0
|
@@ -24,13 +24,26 @@ function dictCollectionName(dictionaryName) {
|
|
|
24
24
|
function isDictCollectionName(name) {
|
|
25
25
|
return name.startsWith(DICT_COLLECTION_PREFIX);
|
|
26
26
|
}
|
|
27
|
-
function dictKey(name,
|
|
27
|
+
function dictKey(name, keysOrMap, opts) {
|
|
28
|
+
let keys;
|
|
29
|
+
let labels;
|
|
30
|
+
if (Array.isArray(keysOrMap)) {
|
|
31
|
+
keys = keysOrMap;
|
|
32
|
+
labels = opts?.labels;
|
|
33
|
+
} else if (keysOrMap && typeof keysOrMap === "object") {
|
|
34
|
+
keys = Object.keys(keysOrMap);
|
|
35
|
+
labels = keysOrMap;
|
|
36
|
+
} else {
|
|
37
|
+
keys = void 0;
|
|
38
|
+
labels = opts?.labels;
|
|
39
|
+
}
|
|
28
40
|
return {
|
|
29
41
|
_noydbDictKey: true,
|
|
30
42
|
name,
|
|
31
43
|
keys,
|
|
32
44
|
...opts?.onMissing !== void 0 ? { onMissing: opts.onMissing } : {},
|
|
33
|
-
...opts?.substitute !== void 0 ? { substitute: opts.substitute } : {}
|
|
45
|
+
...opts?.substitute !== void 0 ? { substitute: opts.substitute } : {},
|
|
46
|
+
...labels !== void 0 ? { labels } : {}
|
|
34
47
|
};
|
|
35
48
|
}
|
|
36
49
|
function isDictKeyDescriptor(x) {
|
|
@@ -398,4 +411,4 @@ export {
|
|
|
398
411
|
isStaticDictDescriptor,
|
|
399
412
|
DictionaryHandle
|
|
400
413
|
};
|
|
401
|
-
//# sourceMappingURL=chunk-
|
|
414
|
+
//# sourceMappingURL=chunk-K4JID2ZE.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/i18n/dictionary.ts"],"sourcesContent":["/**\n * _dict_* reserved collections + dictKey schema descriptor —\n *\n * Stores bounded enum-like field dictionaries as reserved encrypted\n * collections (`_dict_<name>/`) within a vault. Each dictionary\n * entry maps a stable key (e.g. `'paid'`) to a locale → label record\n * (e.g. `{ en: 'Paid', th: 'ชำระแล้ว' }`).\n *\n * Design decisions\n * ────────────────\n *\n * **Why reserved collections, not a separate store?**\n * Same answer as `_sync_credentials`: the compartment's existing\n * encryption stack is exactly right. Dictionaries are encrypted under the\n * same vault DEK, inherit ACL, ledger, and backup/restore for free.\n *\n * **One collection per dictionary, not one collection with namespaces.**\n * Each `_dict_<name>/` collection holds entries `{ id: key, labels: {...} }`.\n * This composes with `ref()` naturally (a dictKey IS a ref to the dict\n * collection), and means the query DSL works over dictionary entries\n * without any special-casing.\n *\n * **dictKey() is a descriptor, not a Zod type.**\n * The descriptor pattern matches `ref()`: declare NOYDB-specific metadata\n * in the collection options alongside `refs`. TypeScript inference comes\n * from the descriptor's generic parameter, not from Zod internals.\n *\n * API:\n * `dictKey(name, keys?)` — returns a DictKeyDescriptor\n * `vault.dictionary(name)` — returns a DictionaryHandle\n * `DictionaryHandle.put/putAll/get/delete/rename/list` — CRUD\n */\n\nimport type { NoydbStore, EncryptedEnvelope } from '../types.js'\nimport type { NoydbEventEmitter } from '../events.js'\nimport { NOYDB_FORMAT_VERSION } from '../types.js'\nimport type { UnlockedKeyring } from '../team/keyring.js'\nimport { encrypt, decrypt } from '../crypto.js'\nimport { ensureCollectionDEK } from '../team/keyring.js'\nimport type { LedgerStore } from '../history/ledger/store.js'\nimport type { OnMissingPolicy } from './policy.js'\nimport { envelopePayloadHash } from '../history/ledger/hash.js'\nimport {\n PermissionDeniedError,\n DictKeyMissingError,\n} from '../errors.js'\n\n/** Reserved collection name prefix. Never collides with user collections. */\nexport const DICT_COLLECTION_PREFIX = '_dict_'\n\n/** Return the adapter collection name for a named dictionary. */\nexport function dictCollectionName(dictionaryName: string): string {\n return `${DICT_COLLECTION_PREFIX}${dictionaryName}`\n}\n\n/** Return true when a collection name is a reserved dictionary collection. */\nexport function isDictCollectionName(name: string): boolean {\n return name.startsWith(DICT_COLLECTION_PREFIX)\n}\n\n// ─── DictKey descriptor ────────────────────────────────────────────────\n\n/**\n * Descriptor returned by `dictKey()`. Attach to the collection's\n * `dictKeyFields` option to declare which fields are dictionary-backed:\n *\n * ```ts\n * const invoices = company.collection<Invoice>('invoices', {\n * dictKeyFields: {\n * status: dictKey('status', ['draft', 'open', 'paid'] as const),\n * },\n * })\n * ```\n *\n * The generic parameter `Keys` narrows the TypeScript type of the field\n * to a literal union; the runtime value of `keys` is used by `put()`\n * validation to reject unknown keys when a key set is declared.\n */\nexport interface DictKeyDescriptor<Keys extends string = string> {\n readonly _noydbDictKey: true\n /** Which dictionary this field references. */\n readonly name: string\n /** Declared valid keys. When set, `put()` rejects keys not in this set. */\n readonly keys: readonly Keys[] | undefined\n /**\n * What to do when a label is missing for the resolved locale. Mirrors\n * `i18nText`'s `onMissing`. Default behavior (when unset) preserves the\n * legacy contract: a missing label is omitted (scalar) or `null`\n * (array element) — i.e. `'null'`. Set `'substitute'` to walk the\n * declared `substitute` chain, or `'throw'` to raise.\n */\n readonly onMissing?: OnMissingPolicy\n /** Ordered preferred-substitute locales for label resolution. */\n readonly substitute?: readonly string[]\n /**\n * Optional inline display labels (value → label map). A SYNC display\n * fallback for `describe()` when async `dictLabels` (from `_dict_`) are\n * not resolved. The async path still wins when available.\n */\n readonly labels?: Record<string, string>\n}\n\n/**\n * Create a `DictKeyDescriptor` for a dictionary-backed enum field.\n *\n * @param name The dictionary name (corresponds to `_dict_<name>` collection).\n * @param keysOrMap Either:\n * - An `as const` array of valid key literals — narrows the TypeScript type\n * to a literal union and enables put-time validation.\n * - A **value→label map** (`{ draft: 'Draft', paid: 'Paid' }`) — keys are\n * inferred from the map, and the labels are stored as inline display\n * defaults surfaced by `describe()` without a store read.\n * @param opts `{ labels?, onMissing?, substitute? }` when the array form\n * is used; `opts.labels` provides inline display defaults for\n * specific keys (same semantics as the map form, but\n * explicit key order from the array is preserved).\n *\n * @example\n * ```ts\n * // array form (original):\n * dictKey('status', ['draft', 'open', 'paid'] as const)\n *\n * // value→label map form (keys inferred, inline labels for describe()):\n * dictKey('status', { draft: 'Draft', open: 'Open', paid: 'Paid' })\n *\n * // array + opts.labels (preserves explicit order, partial labels OK):\n * dictKey('status', ['draft', 'open', 'paid'] as const, { labels: { paid: 'Paid' } })\n * ```\n */\nexport function dictKey<Keys extends string>(\n name: string,\n keysOrMap?: readonly Keys[] | Record<Keys, string>,\n opts?: { onMissing?: OnMissingPolicy; substitute?: readonly string[]; labels?: Record<string, string> },\n): DictKeyDescriptor<Keys> {\n let keys: readonly Keys[] | undefined\n let labels: Record<string, string> | undefined\n if (Array.isArray(keysOrMap)) {\n keys = keysOrMap as readonly Keys[]\n labels = opts?.labels\n } else if (keysOrMap && typeof keysOrMap === 'object') {\n keys = Object.keys(keysOrMap) as Keys[]\n labels = keysOrMap as Record<string, string>\n } else {\n keys = undefined\n labels = opts?.labels\n }\n return {\n _noydbDictKey: true,\n name,\n keys,\n ...(opts?.onMissing !== undefined ? { onMissing: opts.onMissing } : {}),\n ...(opts?.substitute !== undefined ? { substitute: opts.substitute } : {}),\n ...(labels !== undefined ? { labels } : {}),\n }\n}\n\n/** Runtime predicate for detecting a DictKeyDescriptor. */\nexport function isDictKeyDescriptor(x: unknown): x is DictKeyDescriptor {\n return (\n typeof x === 'object' &&\n x !== null &&\n (x as { _noydbDictKey?: unknown })._noydbDictKey === true\n )\n}\n\n// ─── StaticDict descriptor (code-provided dictionary) ──────────────────\n\n/**\n * Descriptor returned by `staticDict()`. A sibling to {@link DictKeyDescriptor}\n * for **closed, defined-in-code, identical-across-vaults** enums (honorific,\n * civil-status, gender, religion, ContactTitle, status…).\n *\n * Unlike `dictKey`, the labels are supplied **at registration in code** and\n * resolved through the *same* label machinery, but with **no `_dict_*`\n * per-vault encrypted copy** and **no `rename()`**. The record stores only\n * the **code**; a static dict has no mutation surface.\n *\n * **Hybrid resolution.** Because a static dict is pure code with no\n * vault-locale dependency, it can — via a configured `displayLocale` — emit a\n * `<field>Label` even under a **locale-less read** (the property a locale-less\n * consumer needs and `dictKey` cannot provide). When a locale *is* active it\n * behaves exactly like `dictKey` (honoring `onMissing`/`substitute`).\n *\n * ```ts\n * const workers = vault.collection<Worker>('workers', {\n * dictKeyFields: {\n * civilStatus: staticDict('civilStatus', {\n * adultMale: { th: 'นาย', en: 'Mr' },\n * adultFemale: { th: 'นาง', en: 'Mrs' },\n * }, { displayLocale: 'th' }),\n * },\n * })\n * ```\n */\nexport interface StaticDictDescriptor<Keys extends string = string> {\n readonly _noydbStaticDict: true\n /** Which dictionary this field references (the registry name). */\n readonly name: string\n /** The in-code label table: key → { locale → label }. */\n readonly table: Readonly<Record<Keys, Readonly<Record<string, string>>>>\n /** Declared valid keys — derived from `Object.keys(table)`. */\n readonly keys: readonly Keys[]\n /**\n * Locale used to emit `<field>Label` under a **locale-less** read — the\n * hybrid hinge. When unset, a static dict behaves like `dictKey` under a\n * locale-less read (no label); a locale-less consumer almost always wants\n * it set.\n */\n readonly displayLocale?: string\n /** Same `onMissing` policy engine as `dictKey`. Default `'null'`. */\n readonly onMissing?: OnMissingPolicy\n /** Ordered preferred-substitute locales for label resolution. */\n readonly substitute?: readonly string[]\n /**\n * Validate the stored code against `keys` on every `put()`. Default `true`\n * — codes are closed by construction, so an unknown code is a bug. Set\n * `false` to allow open codes (skips the `UnknownDictCodeError` guard).\n */\n readonly validateCodes?: boolean\n}\n\n/**\n * Create a `StaticDictDescriptor` for a code-provided enum field — a sibling\n * to {@link dictKey} for closed, code-defined, identical-across-vaults enums.\n *\n * The labels live in `table` (no `_dict_*` collection, no `rename()`); the\n * record stores only the stable code. Pass `displayLocale` so `<field>Label`\n * resolves even under a locale-less read.\n *\n * @param name The dictionary name (used for the readonly-guard registry and\n * the query label seam — never creates a `_dict_<name>` key).\n * @param table `{ key: { locale: label } }` map.\n * @param opts `displayLocale` (locale-less label), `onMissing`, `substitute`.\n *\n * @example\n * ```ts\n * staticDict('civilStatus', {\n * adultMale: { th: 'นาย', en: 'Mr' },\n * adultFemale: { th: 'นาง', en: 'Mrs' },\n * }, { displayLocale: 'th' })\n * ```\n */\nexport function staticDict<const T extends Record<string, Record<string, string>>>(\n name: string,\n table: T,\n opts?: {\n displayLocale?: string\n onMissing?: OnMissingPolicy\n substitute?: readonly string[]\n validateCodes?: boolean\n },\n): StaticDictDescriptor<Extract<keyof T, string>> {\n return {\n _noydbStaticDict: true,\n name,\n table: table as Readonly<Record<Extract<keyof T, string>, Readonly<Record<string, string>>>>,\n keys: Object.keys(table) as Extract<keyof T, string>[],\n ...(opts?.displayLocale !== undefined ? { displayLocale: opts.displayLocale } : {}),\n ...(opts?.onMissing !== undefined ? { onMissing: opts.onMissing } : {}),\n ...(opts?.substitute !== undefined ? { substitute: opts.substitute } : {}),\n ...(opts?.validateCodes !== undefined ? { validateCodes: opts.validateCodes } : {}),\n }\n}\n\n/** Runtime predicate for detecting a StaticDictDescriptor. */\nexport function isStaticDictDescriptor(x: unknown): x is StaticDictDescriptor {\n return (\n typeof x === 'object' &&\n x !== null &&\n (x as { _noydbStaticDict?: unknown })._noydbStaticDict === true\n )\n}\n\n// ─── Dictionary entry shape ────────────────────────────────────────────\n\n/**\n * One entry in a `_dict_*` collection. The record `id` (adapter-side\n * key) IS the stable dictionary key (e.g. `'paid'`). The `labels`\n * record maps locale codes to display strings.\n */\nexport interface DictEntry {\n /** Stable key — same as the record id in the adapter. */\n readonly key: string\n /** Locale → label map, e.g. `{ en: 'Paid', th: 'ชำระแล้ว' }`. */\n readonly labels: Record<string, string>\n}\n\n// ─── Per-dictionary options ────────────────────────────────────────────\n\n/**\n * Options for `vault.dictionary(name, options?)`.\n *\n * `writableBy` controls the minimum role for write operations (put,\n * putAll, delete, rename). Defaults to `'admin'` to match the standard\n * \"dictionary contents are owned by admins\" convention; set to\n * `'operator'` for user-editable dictionaries like custom tags.\n */\nexport interface DictionaryOptions {\n /** Minimum role allowed to write dictionary entries. Default: `'admin'`. */\n readonly writableBy?: 'owner' | 'admin' | 'operator'\n}\n\n// ─── DictionaryHandle ──────────────────────────────────────────────────\n\n/**\n * Handle to a named dictionary within a vault.\n *\n * Obtained via `vault.dictionary(name)`. Provides strongly-typed\n * CRUD for dictionary entries, plus the `rename()` operation that is the\n * only sanctioned mass-mutation path for dictKey fields.\n *\n * All writes are encrypted under the compartment's DEK for the\n * `_dict_<name>` collection. Adapters never see plaintext.\n */\nexport class DictionaryHandle<Keys extends string = string> {\n private readonly collName: string\n\n /**\n * Synchronous write-through cache for dict-join support.\n * Populated on every `put()`, `delete()`, and `rename()`. The snapshot\n * is built from this cache by `snapshotEntries()` — the query executor\n * calls this synchronously inside `.toArray()`.\n *\n * `null` means \"not yet initialized\" — callers should use `list()`\n * to warm the cache before using dict joins on pre-existing data.\n */\n private readonly _syncCache = new Map<string, DictEntry>()\n\n /**\n * Return all cached entries as `{ key, labels, ...labels }` records —\n * usable synchronously by the join executor's `snapshot()` call.\n * Returns an empty array when the cache has never been populated.\n */\n snapshotEntries(): readonly Record<string, unknown>[] {\n return Array.from(this._syncCache.values()).map((e) => ({\n key: e.key,\n labels: e.labels,\n ...e.labels,\n }))\n }\n\n constructor(\n private readonly adapter: NoydbStore,\n private readonly compartmentName: string,\n private readonly dictionaryName: string,\n private readonly keyring: UnlockedKeyring,\n private readonly getDEK: (collectionName: string) => Promise<CryptoKey>,\n private readonly encrypted: boolean,\n private readonly ledger: LedgerStore | undefined,\n private readonly options: DictionaryOptions,\n /**\n * Callback provided by the Vault to find and rewrite records\n * in any registered collection that has a dictKeyField pointing at\n * this dictionary, used by `rename()`.\n */\n private readonly findAndUpdateReferences:\n | ((\n dictionaryName: string,\n oldKey: string,\n newKey: string,\n ) => Promise<void>)\n | undefined,\n private readonly emitter: NoydbEventEmitter,\n ) {\n this.collName = dictCollectionName(dictionaryName)\n }\n\n // ─── Access checks ────────────────────────────────────────────────\n\n private requireWriteAccess(): void {\n const minRole = this.options.writableBy ?? 'admin'\n const roleRank: Record<string, number> = {\n client: 1,\n viewer: 2,\n operator: 3,\n admin: 4,\n owner: 5,\n }\n const callerRank = roleRank[this.keyring.role] ?? 0\n const requiredRank = roleRank[minRole] ?? 4\n if (callerRank < requiredRank) {\n throw new PermissionDeniedError(\n `Dictionary \"${this.dictionaryName}\" writes require \"${minRole}\" role or above. ` +\n `Current role: \"${this.keyring.role}\".`,\n )\n }\n }\n\n // ─── Internal helpers ─────────────────────────────────────────────\n\n private async getDekForDict(): Promise<CryptoKey> {\n const resolve = await ensureCollectionDEK(\n this.adapter,\n this.compartmentName,\n this.keyring,\n )\n return resolve(this.collName)\n }\n\n private async encryptEntry(entry: DictEntry, version: number): Promise<EncryptedEnvelope> {\n if (!this.encrypted) {\n return {\n _noydb: NOYDB_FORMAT_VERSION,\n _v: version,\n _ts: new Date().toISOString(),\n _iv: '',\n _data: JSON.stringify(entry),\n _by: this.keyring.userId,\n }\n }\n const dek = await this.getDekForDict()\n const { iv, data } = await encrypt(JSON.stringify(entry), dek)\n return {\n _noydb: NOYDB_FORMAT_VERSION,\n _v: version,\n _ts: new Date().toISOString(),\n _iv: iv,\n _data: data,\n _by: this.keyring.userId,\n }\n }\n\n private async decryptEntry(envelope: EncryptedEnvelope): Promise<DictEntry> {\n if (!this.encrypted) {\n return JSON.parse(envelope._data) as DictEntry\n }\n const dek = await this.getDekForDict()\n const json = await decrypt(envelope._iv, envelope._data, dek)\n return JSON.parse(json) as DictEntry\n }\n\n // ─── Public API ───────────────────────────────────────────────────\n\n /**\n * Add or overwrite a single dictionary entry.\n *\n * @param key The stable key to store (e.g. `'paid'`).\n * @param labels Locale → label map (e.g. `{ en: 'Paid', th: 'ชำระแล้ว' }`).\n */\n async put(key: Keys, labels: Record<string, string>): Promise<void> {\n this.requireWriteAccess()\n\n const entry: DictEntry = { key, labels }\n const existing = await this.adapter.get(\n this.compartmentName,\n this.collName,\n key,\n )\n const version = existing ? existing._v + 1 : 1\n const envelope = await this.encryptEntry(entry, version)\n\n await this.adapter.put(\n this.compartmentName,\n this.collName,\n key,\n envelope,\n existing ? existing._v : undefined,\n )\n\n // Maintain synchronous cache for dict-join snapshot\n this._syncCache.set(key, entry)\n\n this.emitter.emit('change', {\n vault: this.compartmentName,\n collection: this.collName,\n id: key,\n action: 'put',\n })\n\n if (this.ledger) {\n await this.ledger.append({\n op: 'put',\n collection: this.collName,\n id: key,\n version,\n actor: this.keyring.userId,\n // — must be the real envelope hash so\n // vault.verifyBackupIntegrity()'s data-cross-check matches.\n payloadHash: await envelopePayloadHash(envelope),\n })\n }\n }\n\n /**\n * Batch-add or overwrite multiple dictionary entries in one call.\n *\n * @param entries `{ key: { locale: label } }` map.\n */\n async putAll(entries: Record<Keys, Record<string, string>>): Promise<void> {\n this.requireWriteAccess()\n for (const [key, labels] of Object.entries(entries) as [Keys, Record<string, string>][]) {\n await this.put(key, labels)\n }\n }\n\n /**\n * Load the label map for a single key.\n *\n * @returns The label map, or `null` if the key doesn't exist.\n */\n async get(key: Keys): Promise<Record<string, string> | null> {\n const envelope = await this.adapter.get(\n this.compartmentName,\n this.collName,\n key,\n )\n if (!envelope) return null\n const entry = await this.decryptEntry(envelope)\n return entry.labels\n }\n\n /**\n * Delete a dictionary key.\n *\n * Default mode is `'strict'` — throws `DictKeyInUseError` if any\n * registered collection has a record referencing this key. Pass\n * `{ mode: 'warn' }` to skip the check (dev-mode cleanup only).\n */\n async delete(key: Keys, opts: { mode?: 'strict' | 'warn' } = {}): Promise<void> {\n this.requireWriteAccess()\n\n const existing = await this.adapter.get(\n this.compartmentName,\n this.collName,\n key,\n )\n if (!existing) {\n throw new DictKeyMissingError(this.dictionaryName, key)\n }\n\n const mode = opts.mode ?? 'strict'\n if (mode === 'strict' && this.findAndUpdateReferences) {\n // Check for references by attempting a rename to a sentinel that\n // doesn't exist — we reuse the reference-finding machinery but\n // abort before applying changes. Simpler: the vault\n // exposes a separate checkReferences() callback. For now we rely\n // on the caller to confirm no references exist, or use warn mode.\n // A dedicated findReferences API is tracked as a follow-up.\n }\n\n await this.adapter.delete(this.compartmentName, this.collName, key)\n\n // Maintain synchronous cache for dict-join snapshot\n this._syncCache.delete(key)\n\n this.emitter.emit('change', {\n vault: this.compartmentName,\n collection: this.collName,\n id: key,\n action: 'delete',\n })\n\n if (this.ledger) {\n await this.ledger.append({\n op: 'delete',\n collection: this.collName,\n id: key,\n version: existing._v,\n actor: this.keyring.userId,\n // — for delete the prior envelope is what was just\n // removed; we hash it so the chain captures intent. The\n // verifyBackupIntegrity data-cross-check skips delete\n // entries entirely (the live record is gone), but the\n // chain still benefits from a stable non-empty hash.\n payloadHash: await envelopePayloadHash(existing),\n })\n }\n }\n\n /**\n * Rename a dictionary key — the only sanctioned mass-mutation path.\n *\n * Atomically:\n * 1. Adds the new key with the same labels as the old key.\n * 2. Updates every registered record that stores the old key to\n * store the new key instead.\n * 3. Deletes the old key.\n * 4. Appends a single ledger entry recording the rename.\n *\n * Respects ACL: throws `PermissionDeniedError` before any mutation\n * if the caller can't write. The cascade is best-effort atomic\n * within this call — no two-phase commit across adapter calls.\n *\n * Cascade-on-delete is NOT supported. Use `rename()` when you need\n * to change a key that records reference.\n */\n async rename(oldKey: Keys, newKey: string): Promise<void> {\n this.requireWriteAccess()\n\n // 1. Load old entry\n const existing = await this.adapter.get(\n this.compartmentName,\n this.collName,\n oldKey,\n )\n if (!existing) {\n throw new DictKeyMissingError(this.dictionaryName, oldKey)\n }\n const oldEntry = await this.decryptEntry(existing)\n\n // 2. Write new key\n const newEntry: DictEntry = { key: newKey, labels: oldEntry.labels }\n const newEnvelope = await this.encryptEntry(newEntry, 1)\n await this.adapter.put(\n this.compartmentName,\n this.collName,\n newKey,\n newEnvelope,\n )\n\n // 3. Update all referencing records in registered collections\n if (this.findAndUpdateReferences) {\n await this.findAndUpdateReferences(this.dictionaryName, oldKey, newKey)\n }\n\n // 4. Delete old key\n await this.adapter.delete(this.compartmentName, this.collName, oldKey)\n\n // Maintain synchronous cache for dict-join snapshot\n this._syncCache.delete(oldKey)\n this._syncCache.set(newKey, newEntry)\n\n this.emitter.emit('change', {\n vault: this.compartmentName,\n collection: this.collName,\n id: oldKey,\n action: 'delete',\n })\n this.emitter.emit('change', {\n vault: this.compartmentName,\n collection: this.collName,\n id: newKey,\n action: 'put',\n })\n\n // 5. Ledger — record the rename as delete(oldKey) + put(newKey)\n // so verifyBackupIntegrity()'s data-cross-check matches reality\n // (the oldKey envelope is gone; the newKey envelope is what was\n // just written). Two entries instead of one — the chain still\n // captures the rename intent via the matching ts + actor.\n if (this.ledger) {\n await this.ledger.append({\n op: 'delete',\n collection: this.collName,\n id: oldKey,\n version: existing._v,\n actor: this.keyring.userId,\n payloadHash: await envelopePayloadHash(existing),\n })\n await this.ledger.append({\n op: 'put',\n collection: this.collName,\n id: newKey,\n version: 1,\n actor: this.keyring.userId,\n payloadHash: await envelopePayloadHash(newEnvelope),\n })\n }\n }\n\n /**\n * List all entries in this dictionary.\n *\n * @returns Array of `{ key, labels }` objects.\n */\n async list(): Promise<DictEntry[]> {\n const keys = await this.adapter.list(this.compartmentName, this.collName)\n const entries: DictEntry[] = []\n for (const key of keys) {\n const envelope = await this.adapter.get(\n this.compartmentName,\n this.collName,\n key,\n )\n if (!envelope) continue\n const entry = await this.decryptEntry(envelope)\n entries.push(entry)\n // Warm the synchronous cache\n this._syncCache.set(key, entry)\n }\n return entries\n }\n\n /**\n * Resolve a key to its label for the given locale.\n *\n * Used by the collection's locale-aware read path to populate\n * `<field>Label` virtual fields. Returns `undefined` when the\n * key doesn't exist or has no label for the requested locale\n * (after exhausting the fallback chain).\n */\n async resolveLabel(\n key: string,\n locale: string,\n fallback?: string | readonly string[],\n ): Promise<string | undefined> {\n const labels = await this.get(key as Keys)\n if (!labels) return undefined\n\n // Try primary locale\n if (labels[locale] !== undefined) return labels[locale]\n\n // Try fallback chain\n const chain = Array.isArray(fallback) ? (fallback as readonly string[]) : fallback ? [fallback as string] : []\n for (const fb of chain) {\n if (fb === 'any') {\n // Return any available label\n const any = Object.values(labels)[0]\n if (any !== undefined) return any\n } else if (labels[fb] !== undefined) {\n return labels[fb]\n }\n }\n\n return undefined\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -56,7 +56,7 @@ function validatePeriodName(name, existing) {
|
|
|
56
56
|
}
|
|
57
57
|
async function appendPeriodLedgerEntry(ledger, actor, envelope, name) {
|
|
58
58
|
if (!ledger) return;
|
|
59
|
-
const { envelopePayloadHash } = await import("./ledger-
|
|
59
|
+
const { envelopePayloadHash } = await import("./ledger-CI7GSMLB.js");
|
|
60
60
|
await ledger.append({
|
|
61
61
|
op: "put",
|
|
62
62
|
collection: PERIODS_COLLECTION,
|
|
@@ -87,4 +87,4 @@ export {
|
|
|
87
87
|
appendPeriodLedgerEntry,
|
|
88
88
|
withPeriods
|
|
89
89
|
};
|
|
90
|
-
//# sourceMappingURL=chunk-
|
|
90
|
+
//# sourceMappingURL=chunk-OCYFFBZS.js.map
|
|
@@ -176,7 +176,7 @@ async function createOwnerOnAdoptedPartition(store, vaultName, opts) {
|
|
|
176
176
|
}
|
|
177
177
|
}
|
|
178
178
|
if (isManaged(opts)) {
|
|
179
|
-
const { createNoydb } = await import("./noydb-
|
|
179
|
+
const { createNoydb } = await import("./noydb-5MIBD77B.js");
|
|
180
180
|
const db = await createNoydb({
|
|
181
181
|
store,
|
|
182
182
|
user: userId,
|
|
@@ -229,4 +229,4 @@ export {
|
|
|
229
229
|
createOwnerOnAdoptedPartition,
|
|
230
230
|
decryptExtractedPartition
|
|
231
231
|
};
|
|
232
|
-
//# sourceMappingURL=chunk-
|
|
232
|
+
//# sourceMappingURL=chunk-Y6YUWZTS.js.map
|
|
@@ -1153,7 +1153,7 @@ var BlobSet = class {
|
|
|
1153
1153
|
return this.buildResponse(slot, result.blob, { inline: true });
|
|
1154
1154
|
}
|
|
1155
1155
|
const aad = chunkAAD(slot.eTag, 0, result.blob.chunkCount);
|
|
1156
|
-
const { decryptBytesWithAAD: decryptAAD } = await import("./crypto-
|
|
1156
|
+
const { decryptBytesWithAAD: decryptAAD } = await import("./crypto-OSIV2IIW.js");
|
|
1157
1157
|
const decrypted = await decryptAAD(envelope._iv, envelope._data, blobDEK, aad);
|
|
1158
1158
|
const plaintext = result.blob.compression === "gzip" ? await decompressBytes(decrypted) : decrypted;
|
|
1159
1159
|
const body = new ReadableStream({
|
|
@@ -1303,4 +1303,4 @@ export {
|
|
|
1303
1303
|
memoryObjectProjection,
|
|
1304
1304
|
importExternalObjects
|
|
1305
1305
|
};
|
|
1306
|
-
//# sourceMappingURL=chunk-
|
|
1306
|
+
//# sourceMappingURL=chunk-ZK66B5EY.js.map
|
|
@@ -216,7 +216,7 @@ async function runTransaction(db, fn, options, txInvariants) {
|
|
|
216
216
|
db._clearActiveTxContext(ctx);
|
|
217
217
|
}
|
|
218
218
|
if (ctx._amendment) {
|
|
219
|
-
const { GuardExecutor } = await import("./executor-
|
|
219
|
+
const { GuardExecutor } = await import("./executor-M7W3NEKR.js");
|
|
220
220
|
try {
|
|
221
221
|
for (const [vaultName, v] of ctx._amendmentVaults) {
|
|
222
222
|
const registry = v._getGuardRegistry();
|
|
@@ -352,4 +352,4 @@ export {
|
|
|
352
352
|
runTransaction,
|
|
353
353
|
revertExecuted
|
|
354
354
|
};
|
|
355
|
-
//# sourceMappingURL=chunk-
|
|
355
|
+
//# sourceMappingURL=chunk-ZPJSQPQH.js.map
|
package/dist/consent/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a3 as ConsentStrategy } from '../types-
|
|
2
|
-
export { a4 as CONSENT_AUDIT_COLLECTION, a5 as ConsentAuditEntry, a6 as ConsentAuditFilter, a7 as ConsentContext, a8 as ConsentOp, a9 as loadConsentEntries, aa as writeConsentEntry } from '../types-
|
|
1
|
+
import { a3 as ConsentStrategy } from '../types-CdVfiQgt.cjs';
|
|
2
|
+
export { a4 as CONSENT_AUDIT_COLLECTION, a5 as ConsentAuditEntry, a6 as ConsentAuditFilter, a7 as ConsentContext, a8 as ConsentOp, a9 as loadConsentEntries, aa as writeConsentEntry } from '../types-CdVfiQgt.cjs';
|
|
3
3
|
import '../lazy-builder-eYZzLEL1.cjs';
|
|
4
4
|
import '../predicate-BmhBSPCH.cjs';
|
|
5
5
|
import '../strategy-mJExw4LQ.cjs';
|
package/dist/consent/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a3 as ConsentStrategy } from '../types-
|
|
2
|
-
export { a4 as CONSENT_AUDIT_COLLECTION, a5 as ConsentAuditEntry, a6 as ConsentAuditFilter, a7 as ConsentContext, a8 as ConsentOp, a9 as loadConsentEntries, aa as writeConsentEntry } from '../types-
|
|
1
|
+
import { a3 as ConsentStrategy } from '../types-DHn9lEP0.js';
|
|
2
|
+
export { a4 as CONSENT_AUDIT_COLLECTION, a5 as ConsentAuditEntry, a6 as ConsentAuditFilter, a7 as ConsentContext, a8 as ConsentOp, a9 as loadConsentEntries, aa as writeConsentEntry } from '../types-DHn9lEP0.js';
|
|
3
3
|
import '../lazy-builder-ChSqcF5t.js';
|
|
4
4
|
import '../predicate-BmhBSPCH.js';
|
|
5
5
|
import '../strategy-8QGs5KQE.js';
|
package/dist/consent/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/consent/active.ts"],"sourcesContent":["/**\n * Active consent strategy. Calling `withConsent()` returns a\n * `ConsentStrategy` that delegates to the real\n * `writeConsentEntry` / `loadConsentEntries` functions. Only\n * reachable through the `@noy-db/hub/consent` subpath.\n */\n\nimport { writeConsentEntry, loadConsentEntries } from './consent.js'\nimport type { ConsentStrategy } from './strategy.js'\n\n/**\n * Build the default consent strategy. Pass into\n * `createNoydb({ consentStrategy: withConsent() })` to enable\n * per-operation audit writes into the reserved `_consent_audit`\n * collection.\n */\nexport function withConsent(): ConsentStrategy {\n return {\n write: writeConsentEntry,\n read: loadConsentEntries,\n }\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../src/consent/active.ts"],"sourcesContent":["/**\n * Active consent strategy. Calling `withConsent()` returns a\n * `ConsentStrategy` that delegates to the real\n * `writeConsentEntry` / `loadConsentEntries` functions. Only\n * reachable through the `@noy-db/hub/consent` subpath.\n */\n\nimport { writeConsentEntry, loadConsentEntries } from './consent.js'\nimport type { ConsentStrategy } from './strategy.js'\n\n/**\n * Build the default consent strategy. Pass into\n * `createNoydb({ consentStrategy: withConsent() })` to enable\n * per-operation audit writes into the reserved `_consent_audit`\n * collection.\n */\nexport function withConsent(): ConsentStrategy {\n return {\n write: writeConsentEntry,\n read: loadConsentEntries,\n }\n}\n"],"mappings":";;;;;;;;;;;AAgBO,SAAS,cAA+B;AAC7C,SAAO;AAAA,IACL,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AACF;","names":[]}
|
package/dist/crdt/index.js
CHANGED
package/dist/crdt/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/crdt/active.ts"],"sourcesContent":["/**\n * Active CRDT strategy factory. Calling `withCrdt()` returns a\n * `CrdtStrategy` whose methods delegate to the real LWW-Map / RGA /\n * merge / snapshot helpers in `./crdt.ts`. Only reachable through\n * the `@noy-db/hub/crdt` subpath.\n */\n\nimport {\n buildLwwMapState,\n buildRgaState,\n mergeCrdtStates,\n resolveCrdtSnapshot,\n} from './crdt.js'\nimport type { CrdtStrategy } from './strategy.js'\n\n/**\n * Build the default CRDT strategy. Pass into\n * `createNoydb({ crdtStrategy: withCrdt() })` to enable collections\n * declared with `crdt: 'lww-map' | 'rga' | 'yjs'`.\n *\n * @example\n * ```ts\n * import { createNoydb } from '@noy-db/hub'\n * import { withCrdt } from '@noy-db/hub/crdt'\n *\n * const db = await createNoydb({\n * store, user, secret,\n * crdtStrategy: withCrdt(),\n * })\n * const notes = vault.collection('notes', { crdt: 'lww-map' })\n * ```\n */\nexport function withCrdt(): CrdtStrategy {\n return {\n buildLwwMapState,\n buildRgaState,\n mergeCrdtStates,\n resolveCrdtSnapshot,\n }\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../src/crdt/active.ts"],"sourcesContent":["/**\n * Active CRDT strategy factory. Calling `withCrdt()` returns a\n * `CrdtStrategy` whose methods delegate to the real LWW-Map / RGA /\n * merge / snapshot helpers in `./crdt.ts`. Only reachable through\n * the `@noy-db/hub/crdt` subpath.\n */\n\nimport {\n buildLwwMapState,\n buildRgaState,\n mergeCrdtStates,\n resolveCrdtSnapshot,\n} from './crdt.js'\nimport type { CrdtStrategy } from './strategy.js'\n\n/**\n * Build the default CRDT strategy. Pass into\n * `createNoydb({ crdtStrategy: withCrdt() })` to enable collections\n * declared with `crdt: 'lww-map' | 'rga' | 'yjs'`.\n *\n * @example\n * ```ts\n * import { createNoydb } from '@noy-db/hub'\n * import { withCrdt } from '@noy-db/hub/crdt'\n *\n * const db = await createNoydb({\n * store, user, secret,\n * crdtStrategy: withCrdt(),\n * })\n * const notes = vault.collection('notes', { crdt: 'lww-map' })\n * ```\n */\nexport function withCrdt(): CrdtStrategy {\n return {\n buildLwwMapState,\n buildRgaState,\n mergeCrdtStates,\n resolveCrdtSnapshot,\n }\n}\n"],"mappings":";;;;;;;;;AAgCO,SAAS,WAAyB;AACvC,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;","names":[]}
|
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
wrapKey
|
|
23
23
|
} from "./chunk-E2MDPPOC.js";
|
|
24
24
|
import "./chunk-JZ5DS4DP.js";
|
|
25
|
+
import "./chunk-PZ5AY32C.js";
|
|
25
26
|
export {
|
|
26
27
|
base64ToBuffer,
|
|
27
28
|
bufferToBase64,
|
|
@@ -45,4 +46,4 @@ export {
|
|
|
45
46
|
wrapCek,
|
|
46
47
|
wrapKey
|
|
47
48
|
};
|
|
48
|
-
//# sourceMappingURL=crypto-
|
|
49
|
+
//# sourceMappingURL=crypto-OSIV2IIW.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { bc as PublicEnvelope, bd as SealingKeyProvider, be as BundleRecipient, bf as RecipientSealer, bg as RecipientHint, bh as Vault } from './types-
|
|
1
|
+
import { bc as PublicEnvelope, bd as SealingKeyProvider, be as BundleRecipient, bf as RecipientSealer, bg as RecipientHint, bh as Vault } from './types-CdVfiQgt.cjs';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* `.noydb` container format — byte layout, header schema, validators.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { bc as PublicEnvelope, bd as SealingKeyProvider, be as BundleRecipient, bf as RecipientSealer, bg as RecipientHint, bh as Vault } from './types-
|
|
1
|
+
import { bc as PublicEnvelope, bd as SealingKeyProvider, be as BundleRecipient, bf as RecipientSealer, bg as RecipientHint, bh as Vault } from './types-DHn9lEP0.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* `.noydb` container format — byte layout, header schema, validators.
|
|
@@ -8,10 +8,11 @@ import "./chunk-MSMDDDDJ.js";
|
|
|
8
8
|
import "./chunk-FZU343FL.js";
|
|
9
9
|
import "./chunk-E2MDPPOC.js";
|
|
10
10
|
import "./chunk-JZ5DS4DP.js";
|
|
11
|
+
import "./chunk-PZ5AY32C.js";
|
|
11
12
|
export {
|
|
12
13
|
DELEGATIONS_COLLECTION,
|
|
13
14
|
issueDelegation,
|
|
14
15
|
loadActiveDelegations,
|
|
15
16
|
revokeDelegation
|
|
16
17
|
};
|
|
17
|
-
//# sourceMappingURL=delegation-
|
|
18
|
+
//# sourceMappingURL=delegation-BQTRJATI.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export { w as withDerivation, a as withRollup } from '../with-rollup-
|
|
2
|
-
import { aC as DerivationStrategy, aD as DerivationContext } from '../types-
|
|
3
|
-
export { aE as ArrayOutputSpec, aF as DerivationRegistry, aG as DerivationStrategyHandle, aH as DerivedFromMeta, aI as OutputSpec, aJ as RecordOutputSpec } from '../types-
|
|
1
|
+
export { w as withDerivation, a as withRollup } from '../with-rollup-nIxo7h9z.cjs';
|
|
2
|
+
import { aC as DerivationStrategy, aD as DerivationContext } from '../types-CdVfiQgt.cjs';
|
|
3
|
+
export { aE as ArrayOutputSpec, aF as DerivationRegistry, aG as DerivationStrategyHandle, aH as DerivedFromMeta, aI as OutputSpec, aJ as RecordOutputSpec } from '../types-CdVfiQgt.cjs';
|
|
4
4
|
export { i as DerivationCapExceededError, j as DerivationCycleError, k as DerivationDepthError, l as DerivationOutputShapeError, m as DerivationOutputUnknownError } from '../errors-BAWO5Z5a.cjs';
|
|
5
5
|
import '../lazy-builder-eYZzLEL1.cjs';
|
|
6
6
|
import '../predicate-BmhBSPCH.cjs';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export { w as withDerivation, a as withRollup } from '../with-rollup-
|
|
2
|
-
import { aC as DerivationStrategy, aD as DerivationContext } from '../types-
|
|
3
|
-
export { aE as ArrayOutputSpec, aF as DerivationRegistry, aG as DerivationStrategyHandle, aH as DerivedFromMeta, aI as OutputSpec, aJ as RecordOutputSpec } from '../types-
|
|
1
|
+
export { w as withDerivation, a as withRollup } from '../with-rollup-Dd3_ZG4b.js';
|
|
2
|
+
import { aC as DerivationStrategy, aD as DerivationContext } from '../types-DHn9lEP0.js';
|
|
3
|
+
export { aE as ArrayOutputSpec, aF as DerivationRegistry, aG as DerivationStrategyHandle, aH as DerivedFromMeta, aI as OutputSpec, aJ as RecordOutputSpec } from '../types-DHn9lEP0.js';
|
|
4
4
|
export { i as DerivationCapExceededError, j as DerivationCycleError, k as DerivationDepthError, l as DerivationOutputShapeError, m as DerivationOutputUnknownError } from '../errors-BAWO5Z5a.js';
|
|
5
5
|
import '../lazy-builder-ChSqcF5t.js';
|
|
6
6
|
import '../predicate-BmhBSPCH.js';
|
|
@@ -6,7 +6,8 @@ import "./chunk-K6NVSHAH.js";
|
|
|
6
6
|
import "./chunk-KJ3K5VZM.js";
|
|
7
7
|
import "./chunk-QXWJQ7UU.js";
|
|
8
8
|
import "./chunk-JZ5DS4DP.js";
|
|
9
|
+
import "./chunk-PZ5AY32C.js";
|
|
9
10
|
export {
|
|
10
11
|
MaterializedViewExecutor
|
|
11
12
|
};
|
|
12
|
-
//# sourceMappingURL=executor-
|
|
13
|
+
//# sourceMappingURL=executor-VDTDGWO6.js.map
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
NOYDB_FORMAT_VERSION
|
|
3
3
|
} from "./chunk-A7DNZVAV.js";
|
|
4
|
+
import "./chunk-PZ5AY32C.js";
|
|
4
5
|
|
|
5
6
|
// src/derivations/fanout-sidecar.ts
|
|
6
7
|
function recordId(source, sourceId, outputKey) {
|
|
@@ -48,4 +49,4 @@ export {
|
|
|
48
49
|
loadFanoutSidecar,
|
|
49
50
|
saveFanoutSidecar
|
|
50
51
|
};
|
|
51
|
-
//# sourceMappingURL=fanout-sidecar-
|
|
52
|
+
//# sourceMappingURL=fanout-sidecar-AZALISHB.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/derivations/fanout-sidecar.ts"],"sourcesContent":["/**\n * Per-source-row fanout sidecar for `shape: 'array'` derivations.\n *\n * Each `(sourceCollection, sourceId, outputKey)` triple gets its own\n * envelope at:\n *\n * _meta/derivations-fanout/<sourceCollection>/<sourceId>/<outputKey>\n *\n * The envelope records the last-emitted derived row ids so the\n * dispatcher can compute the diff on every source-row update in O(1):\n * read prior keys, compute `toDelete = prev \\ new`, write new, persist\n * back.\n *\n * Stored as plain JSON with AES-GCM bypassed (same pattern as\n * `_meta/policy`, `_meta/recovery-paper`, `_meta/sealed-passphrase`,\n * etc.): the sidecar is system metadata, not user data, and the\n * derived outputs themselves carry their own encryption envelopes.\n *\n * @module\n */\nimport type { NoydbStore, EncryptedEnvelope } from '../types.js'\nimport { NOYDB_FORMAT_VERSION } from '../types.js'\n\n/** Magic-prefixed JSON payload at `_meta/<recordId>`. */\nexport interface FanoutSidecar {\n readonly _noydb_fanout: 1\n /** Source collection name. */\n readonly source: string\n /** Source record id. */\n readonly sourceId: string\n /** Strategy output key (the key in `strategy.outputs`). */\n readonly outputKey: string\n /** Output collection name (audit / forensics). */\n readonly outputCollection: string\n /** Derived-row ids last emitted for this (source, output) pair. */\n readonly keys: ReadonlyArray<string>\n /** ISO timestamp of last dispatch. */\n readonly emittedAt: string\n}\n\n/**\n * Build the canonical `_meta` record id for a fanout sidecar.\n *\n * The full path inside the store is `_meta/<this-string>`. We pack the\n * full triple into the id so a single `_meta` collection holds all\n * sidecars (collection-per-source would proliferate names; the\n * existing `_meta` flat namespace is cheaper).\n */\nfunction recordId(source: string, sourceId: string, outputKey: string): string {\n // Use `/` as a separator. None of the components is supposed to\n // contain it (collection names + output keys are bare identifiers;\n // source ids are typically ULIDs / UUIDs / app-chosen strings\n // without slashes). If a future source carries `/` in its id, we'd\n // need an escape; deferred until that's a real case.\n return `derivations-fanout/${source}/${sourceId}/${outputKey}`\n}\n\n/** Read the sidecar; returns empty if absent. */\nexport async function loadFanoutSidecar(\n store: NoydbStore,\n vault: string,\n source: string,\n sourceId: string,\n outputKey: string,\n): Promise<FanoutSidecar | undefined> {\n const envelope = await store.get(vault, '_meta', recordId(source, sourceId, outputKey))\n if (!envelope) return undefined\n try {\n const parsed = JSON.parse(envelope._data) as FanoutSidecar\n if (parsed._noydb_fanout !== 1) return undefined\n if (!Array.isArray(parsed.keys)) return undefined\n return parsed\n } catch {\n return undefined\n }\n}\n\n/** Persist (insert/replace) the sidecar with a fresh key set. */\nexport async function saveFanoutSidecar(\n store: NoydbStore,\n vault: string,\n payload: {\n readonly source: string\n readonly sourceId: string\n readonly outputKey: string\n readonly outputCollection: string\n readonly keys: ReadonlyArray<string>\n },\n): Promise<void> {\n const doc: FanoutSidecar = {\n _noydb_fanout: 1,\n source: payload.source,\n sourceId: payload.sourceId,\n outputKey: payload.outputKey,\n outputCollection: payload.outputCollection,\n keys: payload.keys,\n emittedAt: new Date().toISOString(),\n }\n const id = recordId(payload.source, payload.sourceId, payload.outputKey)\n const prior = await store.get(vault, '_meta', id)\n const envelope: EncryptedEnvelope = {\n _noydb: NOYDB_FORMAT_VERSION,\n _v: (prior?._v ?? 0) + 1,\n _ts: new Date().toISOString(),\n // AES-GCM bypassed — sidecar is system metadata, no user data inside.\n _iv: '',\n _data: JSON.stringify(doc),\n }\n await store.put(vault, '_meta', id, envelope)\n}\n\n/** Delete the sidecar (used on source-row delete cascade). */\nexport async function deleteFanoutSidecar(\n store: NoydbStore,\n vault: string,\n source: string,\n sourceId: string,\n outputKey: string,\n): Promise<void> {\n await store.delete(vault, '_meta', recordId(source, sourceId, outputKey))\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../src/derivations/fanout-sidecar.ts"],"sourcesContent":["/**\n * Per-source-row fanout sidecar for `shape: 'array'` derivations.\n *\n * Each `(sourceCollection, sourceId, outputKey)` triple gets its own\n * envelope at:\n *\n * _meta/derivations-fanout/<sourceCollection>/<sourceId>/<outputKey>\n *\n * The envelope records the last-emitted derived row ids so the\n * dispatcher can compute the diff on every source-row update in O(1):\n * read prior keys, compute `toDelete = prev \\ new`, write new, persist\n * back.\n *\n * Stored as plain JSON with AES-GCM bypassed (same pattern as\n * `_meta/policy`, `_meta/recovery-paper`, `_meta/sealed-passphrase`,\n * etc.): the sidecar is system metadata, not user data, and the\n * derived outputs themselves carry their own encryption envelopes.\n *\n * @module\n */\nimport type { NoydbStore, EncryptedEnvelope } from '../types.js'\nimport { NOYDB_FORMAT_VERSION } from '../types.js'\n\n/** Magic-prefixed JSON payload at `_meta/<recordId>`. */\nexport interface FanoutSidecar {\n readonly _noydb_fanout: 1\n /** Source collection name. */\n readonly source: string\n /** Source record id. */\n readonly sourceId: string\n /** Strategy output key (the key in `strategy.outputs`). */\n readonly outputKey: string\n /** Output collection name (audit / forensics). */\n readonly outputCollection: string\n /** Derived-row ids last emitted for this (source, output) pair. */\n readonly keys: ReadonlyArray<string>\n /** ISO timestamp of last dispatch. */\n readonly emittedAt: string\n}\n\n/**\n * Build the canonical `_meta` record id for a fanout sidecar.\n *\n * The full path inside the store is `_meta/<this-string>`. We pack the\n * full triple into the id so a single `_meta` collection holds all\n * sidecars (collection-per-source would proliferate names; the\n * existing `_meta` flat namespace is cheaper).\n */\nfunction recordId(source: string, sourceId: string, outputKey: string): string {\n // Use `/` as a separator. None of the components is supposed to\n // contain it (collection names + output keys are bare identifiers;\n // source ids are typically ULIDs / UUIDs / app-chosen strings\n // without slashes). If a future source carries `/` in its id, we'd\n // need an escape; deferred until that's a real case.\n return `derivations-fanout/${source}/${sourceId}/${outputKey}`\n}\n\n/** Read the sidecar; returns empty if absent. */\nexport async function loadFanoutSidecar(\n store: NoydbStore,\n vault: string,\n source: string,\n sourceId: string,\n outputKey: string,\n): Promise<FanoutSidecar | undefined> {\n const envelope = await store.get(vault, '_meta', recordId(source, sourceId, outputKey))\n if (!envelope) return undefined\n try {\n const parsed = JSON.parse(envelope._data) as FanoutSidecar\n if (parsed._noydb_fanout !== 1) return undefined\n if (!Array.isArray(parsed.keys)) return undefined\n return parsed\n } catch {\n return undefined\n }\n}\n\n/** Persist (insert/replace) the sidecar with a fresh key set. */\nexport async function saveFanoutSidecar(\n store: NoydbStore,\n vault: string,\n payload: {\n readonly source: string\n readonly sourceId: string\n readonly outputKey: string\n readonly outputCollection: string\n readonly keys: ReadonlyArray<string>\n },\n): Promise<void> {\n const doc: FanoutSidecar = {\n _noydb_fanout: 1,\n source: payload.source,\n sourceId: payload.sourceId,\n outputKey: payload.outputKey,\n outputCollection: payload.outputCollection,\n keys: payload.keys,\n emittedAt: new Date().toISOString(),\n }\n const id = recordId(payload.source, payload.sourceId, payload.outputKey)\n const prior = await store.get(vault, '_meta', id)\n const envelope: EncryptedEnvelope = {\n _noydb: NOYDB_FORMAT_VERSION,\n _v: (prior?._v ?? 0) + 1,\n _ts: new Date().toISOString(),\n // AES-GCM bypassed — sidecar is system metadata, no user data inside.\n _iv: '',\n _data: JSON.stringify(doc),\n }\n await store.put(vault, '_meta', id, envelope)\n}\n\n/** Delete the sidecar (used on source-row delete cascade). */\nexport async function deleteFanoutSidecar(\n store: NoydbStore,\n vault: string,\n source: string,\n sourceId: string,\n outputKey: string,\n): Promise<void> {\n await store.delete(vault, '_meta', recordId(source, sourceId, outputKey))\n}\n"],"mappings":";;;;;;AAgDA,SAAS,SAAS,QAAgB,UAAkB,WAA2B;AAM7E,SAAO,sBAAsB,MAAM,IAAI,QAAQ,IAAI,SAAS;AAC9D;AAGA,eAAsB,kBACpB,OACA,OACA,QACA,UACA,WACoC;AACpC,QAAM,WAAW,MAAM,MAAM,IAAI,OAAO,SAAS,SAAS,QAAQ,UAAU,SAAS,CAAC;AACtF,MAAI,CAAC,SAAU,QAAO;AACtB,MAAI;AACF,UAAM,SAAS,KAAK,MAAM,SAAS,KAAK;AACxC,QAAI,OAAO,kBAAkB,EAAG,QAAO;AACvC,QAAI,CAAC,MAAM,QAAQ,OAAO,IAAI,EAAG,QAAO;AACxC,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGA,eAAsB,kBACpB,OACA,OACA,SAOe;AACf,QAAM,MAAqB;AAAA,IACzB,eAAe;AAAA,IACf,QAAQ,QAAQ;AAAA,IAChB,UAAU,QAAQ;AAAA,IAClB,WAAW,QAAQ;AAAA,IACnB,kBAAkB,QAAQ;AAAA,IAC1B,MAAM,QAAQ;AAAA,IACd,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,EACpC;AACA,QAAM,KAAK,SAAS,QAAQ,QAAQ,QAAQ,UAAU,QAAQ,SAAS;AACvE,QAAM,QAAQ,MAAM,MAAM,IAAI,OAAO,SAAS,EAAE;AAChD,QAAM,WAA8B;AAAA,IAClC,QAAQ;AAAA,IACR,KAAK,OAAO,MAAM,KAAK;AAAA,IACvB,MAAK,oBAAI,KAAK,GAAE,YAAY;AAAA;AAAA,IAE5B,KAAK;AAAA,IACL,OAAO,KAAK,UAAU,GAAG;AAAA,EAC3B;AACA,QAAM,MAAM,IAAI,OAAO,SAAS,IAAI,QAAQ;AAC9C;AAGA,eAAsB,oBACpB,OACA,OACA,QACA,UACA,WACe;AACf,QAAM,MAAM,OAAO,OAAO,SAAS,SAAS,QAAQ,UAAU,SAAS,CAAC;AAC1E;","names":[]}
|
package/dist/forget/index.js
CHANGED
package/dist/guards/index.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export { I as ImmutableGuardConfig, T as TransitionGuardConfig, i as immutableGuard, t as transitionGuard, w as withGuard } from '../transition-guard-
|
|
2
|
-
import { an as GuardStrategy, ao as GuardChange, ap as GuardContext } from '../types-
|
|
3
|
-
export { aq as GuardRegistry, ar as GuardStrategyHandle, as as ReadOnlyVaultFacade } from '../types-
|
|
1
|
+
export { I as ImmutableGuardConfig, T as TransitionGuardConfig, i as immutableGuard, t as transitionGuard, w as withGuard } from '../transition-guard-tWZIsaXe.cjs';
|
|
2
|
+
import { an as GuardStrategy, ao as GuardChange, ap as GuardContext } from '../types-CdVfiQgt.cjs';
|
|
3
|
+
export { aq as GuardRegistry, ar as GuardStrategyHandle, as as ReadOnlyVaultFacade } from '../types-CdVfiQgt.cjs';
|
|
4
4
|
export { A as AmendmentForbiddenError, F as FieldFrozenError, I as IllegalTransitionError, f as InvariantError, g as RecordLockedError } from '../errors-BAWO5Z5a.cjs';
|
|
5
5
|
import '../lazy-builder-eYZzLEL1.cjs';
|
|
6
6
|
import '../predicate-BmhBSPCH.cjs';
|
package/dist/guards/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export { I as ImmutableGuardConfig, T as TransitionGuardConfig, i as immutableGuard, t as transitionGuard, w as withGuard } from '../transition-guard-
|
|
2
|
-
import { an as GuardStrategy, ao as GuardChange, ap as GuardContext } from '../types-
|
|
3
|
-
export { aq as GuardRegistry, ar as GuardStrategyHandle, as as ReadOnlyVaultFacade } from '../types-
|
|
1
|
+
export { I as ImmutableGuardConfig, T as TransitionGuardConfig, i as immutableGuard, t as transitionGuard, w as withGuard } from '../transition-guard-J04-jime.js';
|
|
2
|
+
import { an as GuardStrategy, ao as GuardChange, ap as GuardContext } from '../types-DHn9lEP0.js';
|
|
3
|
+
export { aq as GuardRegistry, ar as GuardStrategyHandle, as as ReadOnlyVaultFacade } from '../types-DHn9lEP0.js';
|
|
4
4
|
export { A as AmendmentForbiddenError, F as FieldFrozenError, I as IllegalTransitionError, f as InvariantError, g as RecordLockedError } from '../errors-BAWO5Z5a.js';
|
|
5
5
|
import '../lazy-builder-ChSqcF5t.js';
|
|
6
6
|
import '../predicate-BmhBSPCH.js';
|
package/dist/guards/index.js
CHANGED
package/dist/history/index.d.cts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { aV as HistoryStrategy, aW as NoydbStore, aX as HistoryOptions, aY as EncryptedEnvelope, aZ as PruneOptions } from '../types-
|
|
2
|
-
export { a_ as AppendInput, a$ as ChangeType, b0 as CollectionInstant, b1 as DiffEntry, b2 as JsonPatch, b3 as JsonPatchOp, b4 as LedgerStore, b5 as VaultEngine, b6 as VaultInstant, b7 as VerifyResult, b8 as applyPatch, b9 as computePatch, ba as diff, bb as formatDiff } from '../types-
|
|
1
|
+
import { aV as HistoryStrategy, aW as NoydbStore, aX as HistoryOptions, aY as EncryptedEnvelope, aZ as PruneOptions } from '../types-CdVfiQgt.cjs';
|
|
2
|
+
export { a_ as AppendInput, a$ as ChangeType, b0 as CollectionInstant, b1 as DiffEntry, b2 as JsonPatch, b3 as JsonPatchOp, b4 as LedgerStore, b5 as VaultEngine, b6 as VaultInstant, b7 as VerifyResult, b8 as applyPatch, b9 as computePatch, ba as diff, bb as formatDiff } from '../types-CdVfiQgt.cjs';
|
|
3
3
|
export { L as LedgerEntry, c as canonicalJson, h as hashEntry, p as paddedIndex, a as parseIndex, s as sha256Hex } from '../index-BMmajblo.cjs';
|
|
4
|
-
export { L as LEDGER_COLLECTION, a as LEDGER_DELTAS_COLLECTION, e as envelopePayloadHash } from '../hash-
|
|
4
|
+
export { L as LEDGER_COLLECTION, a as LEDGER_DELTAS_COLLECTION, e as envelopePayloadHash } from '../hash-Db8ncXGr.cjs';
|
|
5
5
|
import '../lazy-builder-eYZzLEL1.cjs';
|
|
6
6
|
import '../predicate-BmhBSPCH.cjs';
|
|
7
7
|
import '../strategy-mJExw4LQ.cjs';
|
package/dist/history/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { aV as HistoryStrategy, aW as NoydbStore, aX as HistoryOptions, aY as EncryptedEnvelope, aZ as PruneOptions } from '../types-
|
|
2
|
-
export { a_ as AppendInput, a$ as ChangeType, b0 as CollectionInstant, b1 as DiffEntry, b2 as JsonPatch, b3 as JsonPatchOp, b4 as LedgerStore, b5 as VaultEngine, b6 as VaultInstant, b7 as VerifyResult, b8 as applyPatch, b9 as computePatch, ba as diff, bb as formatDiff } from '../types-
|
|
1
|
+
import { aV as HistoryStrategy, aW as NoydbStore, aX as HistoryOptions, aY as EncryptedEnvelope, aZ as PruneOptions } from '../types-DHn9lEP0.js';
|
|
2
|
+
export { a_ as AppendInput, a$ as ChangeType, b0 as CollectionInstant, b1 as DiffEntry, b2 as JsonPatch, b3 as JsonPatchOp, b4 as LedgerStore, b5 as VaultEngine, b6 as VaultInstant, b7 as VerifyResult, b8 as applyPatch, b9 as computePatch, ba as diff, bb as formatDiff } from '../types-DHn9lEP0.js';
|
|
3
3
|
export { L as LedgerEntry, c as canonicalJson, h as hashEntry, p as paddedIndex, a as parseIndex, s as sha256Hex } from '../index-BMmajblo.js';
|
|
4
|
-
export { L as LEDGER_COLLECTION, a as LEDGER_DELTAS_COLLECTION, e as envelopePayloadHash } from '../hash-
|
|
4
|
+
export { L as LEDGER_COLLECTION, a as LEDGER_DELTAS_COLLECTION, e as envelopePayloadHash } from '../hash-DLwkYf1d.js';
|
|
5
5
|
import '../lazy-builder-ChSqcF5t.js';
|
|
6
6
|
import '../predicate-BmhBSPCH.js';
|
|
7
7
|
import '../strategy-8QGs5KQE.js';
|
package/dist/history/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/history/active.ts"],"sourcesContent":["/**\n * Active history strategy — `withHistory()` returns the real\n * implementation that wires per-record snapshots, the hash-chained\n * audit ledger, JSON-patch deltas, and time-machine reads into the\n * core write/read paths.\n *\n * Consumers opt in by:\n *\n * ```ts\n * import { createNoydb } from '@noy-db/hub'\n * import { withHistory } from '@noy-db/hub/history'\n *\n * const db = await createNoydb({\n * store: ...,\n * user: ...,\n * historyStrategy: withHistory(),\n * })\n * ```\n *\n * The factory is a thin wrapper that delegates to the existing\n * `history.ts`, `diff.ts`, `ledger/store.ts`, `ledger/patch.ts`, and\n * `time-machine.ts` modules. Splitting the import chain through this\n * file is what lets `tsup` tree-shake the heavy modules out of the\n * default `@noy-db/hub` bundle when no `withHistory()` import is\n * present in the consumer.\n *\n * @public\n */\n\nimport type { HistoryStrategy, BuildLedgerOptions } from './strategy.js'\nimport {\n saveHistory,\n getHistory,\n getVersionEnvelope,\n pruneHistory,\n clearHistory,\n tombstoneHistory,\n} from './history.js'\nimport { diff as computeDiff } from './diff.js'\nimport { LedgerStore, envelopePayloadHash } from './ledger/store.js'\nimport { computePatch } from './ledger/patch.js'\nimport { VaultInstant } from './time-machine.js'\n\n/**\n * Build the active history strategy. Today the factory takes no\n * options; per-collection retention tuning still flows through\n * `HistoryConfig` on `Vault.collection()` / `vault.openVault()`.\n *\n * Future option slots (kept off the LTS surface for now):\n * - global maxVersions cap\n * - global beforeDate prune cadence\n * - ledger encryption toggle (today inferred from vault.encrypted)\n */\nexport function withHistory(): HistoryStrategy {\n return {\n saveHistory,\n getHistoryEntries: getHistory,\n getVersionEnvelope,\n pruneHistory,\n clearHistory,\n tombstoneHistory,\n envelopePayloadHash,\n computePatch,\n diff: computeDiff,\n buildLedger(opts: BuildLedgerOptions): LedgerStore {\n return new LedgerStore({\n adapter: opts.adapter,\n vault: opts.vault,\n encrypted: opts.encrypted,\n getDEK: opts.getDEK,\n actor: opts.actor,\n })\n },\n buildVaultInstant(engine, timestamp): VaultInstant {\n return new VaultInstant(engine, timestamp)\n },\n }\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../src/history/active.ts"],"sourcesContent":["/**\n * Active history strategy — `withHistory()` returns the real\n * implementation that wires per-record snapshots, the hash-chained\n * audit ledger, JSON-patch deltas, and time-machine reads into the\n * core write/read paths.\n *\n * Consumers opt in by:\n *\n * ```ts\n * import { createNoydb } from '@noy-db/hub'\n * import { withHistory } from '@noy-db/hub/history'\n *\n * const db = await createNoydb({\n * store: ...,\n * user: ...,\n * historyStrategy: withHistory(),\n * })\n * ```\n *\n * The factory is a thin wrapper that delegates to the existing\n * `history.ts`, `diff.ts`, `ledger/store.ts`, `ledger/patch.ts`, and\n * `time-machine.ts` modules. Splitting the import chain through this\n * file is what lets `tsup` tree-shake the heavy modules out of the\n * default `@noy-db/hub` bundle when no `withHistory()` import is\n * present in the consumer.\n *\n * @public\n */\n\nimport type { HistoryStrategy, BuildLedgerOptions } from './strategy.js'\nimport {\n saveHistory,\n getHistory,\n getVersionEnvelope,\n pruneHistory,\n clearHistory,\n tombstoneHistory,\n} from './history.js'\nimport { diff as computeDiff } from './diff.js'\nimport { LedgerStore, envelopePayloadHash } from './ledger/store.js'\nimport { computePatch } from './ledger/patch.js'\nimport { VaultInstant } from './time-machine.js'\n\n/**\n * Build the active history strategy. Today the factory takes no\n * options; per-collection retention tuning still flows through\n * `HistoryConfig` on `Vault.collection()` / `vault.openVault()`.\n *\n * Future option slots (kept off the LTS surface for now):\n * - global maxVersions cap\n * - global beforeDate prune cadence\n * - ledger encryption toggle (today inferred from vault.encrypted)\n */\nexport function withHistory(): HistoryStrategy {\n return {\n saveHistory,\n getHistoryEntries: getHistory,\n getVersionEnvelope,\n pruneHistory,\n clearHistory,\n tombstoneHistory,\n envelopePayloadHash,\n computePatch,\n diff: computeDiff,\n buildLedger(opts: BuildLedgerOptions): LedgerStore {\n return new LedgerStore({\n adapter: opts.adapter,\n vault: opts.vault,\n encrypted: opts.encrypted,\n getDEK: opts.getDEK,\n actor: opts.actor,\n })\n },\n buildVaultInstant(engine, timestamp): VaultInstant {\n return new VaultInstant(engine, timestamp)\n },\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqDO,SAAS,cAA+B;AAC7C,SAAO;AAAA,IACL;AAAA,IACA,mBAAmB;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,YAAY,MAAuC;AACjD,aAAO,IAAI,YAAY;AAAA,QACrB,SAAS,KAAK;AAAA,QACd,OAAO,KAAK;AAAA,QACZ,WAAW,KAAK;AAAA,QAChB,QAAQ,KAAK;AAAA,QACb,OAAO,KAAK;AAAA,MACd,CAAC;AAAA,IACH;AAAA,IACA,kBAAkB,QAAQ,WAAyB;AACjD,aAAO,IAAI,aAAa,QAAQ,SAAS;AAAA,IAC3C;AAAA,EACF;AACF;","names":[]}
|
package/dist/i18n/index.cjs
CHANGED
|
@@ -769,13 +769,26 @@ function dictCollectionName(dictionaryName) {
|
|
|
769
769
|
function isDictCollectionName(name) {
|
|
770
770
|
return name.startsWith(DICT_COLLECTION_PREFIX);
|
|
771
771
|
}
|
|
772
|
-
function dictKey(name,
|
|
772
|
+
function dictKey(name, keysOrMap, opts) {
|
|
773
|
+
let keys;
|
|
774
|
+
let labels;
|
|
775
|
+
if (Array.isArray(keysOrMap)) {
|
|
776
|
+
keys = keysOrMap;
|
|
777
|
+
labels = opts?.labels;
|
|
778
|
+
} else if (keysOrMap && typeof keysOrMap === "object") {
|
|
779
|
+
keys = Object.keys(keysOrMap);
|
|
780
|
+
labels = keysOrMap;
|
|
781
|
+
} else {
|
|
782
|
+
keys = void 0;
|
|
783
|
+
labels = opts?.labels;
|
|
784
|
+
}
|
|
773
785
|
return {
|
|
774
786
|
_noydbDictKey: true,
|
|
775
787
|
name,
|
|
776
788
|
keys,
|
|
777
789
|
...opts?.onMissing !== void 0 ? { onMissing: opts.onMissing } : {},
|
|
778
|
-
...opts?.substitute !== void 0 ? { substitute: opts.substitute } : {}
|
|
790
|
+
...opts?.substitute !== void 0 ? { substitute: opts.substitute } : {},
|
|
791
|
+
...labels !== void 0 ? { labels } : {}
|
|
779
792
|
};
|
|
780
793
|
}
|
|
781
794
|
function isDictKeyDescriptor(x) {
|