@noy-db/hub 0.2.0-pre.10 → 0.2.0-pre.12
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/README.md +126 -0
- package/dist/aggregate/index.cjs +289 -12
- package/dist/aggregate/index.cjs.map +1 -1
- package/dist/aggregate/index.d.cts +2 -2
- package/dist/aggregate/index.d.ts +2 -2
- package/dist/aggregate/index.js +7 -7
- package/dist/aggregate/index.js.map +1 -1
- package/dist/attestation/index.cjs.map +1 -1
- package/dist/attestation/index.d.cts +3 -3
- package/dist/attestation/index.d.ts +3 -3
- package/dist/attestation/index.js +6 -6
- package/dist/blobs/index.cjs +28 -0
- package/dist/blobs/index.cjs.map +1 -1
- package/dist/blobs/index.d.cts +4 -4
- package/dist/blobs/index.d.ts +4 -4
- package/dist/blobs/index.js +5 -5
- package/dist/bundle/index.cjs +1468 -19
- package/dist/bundle/index.cjs.map +1 -1
- package/dist/bundle/index.d.cts +5 -5
- package/dist/bundle/index.d.ts +5 -5
- package/dist/bundle/index.js +9 -9
- package/dist/{chunk-7CEGU63S.js → chunk-4BHFNKTP.js} +2 -2
- package/dist/{chunk-5OEJ6GOT.js → chunk-5ARRXIVR.js} +2 -2
- package/dist/{chunk-DRXIZOFV.js → chunk-6AD5TBF2.js} +31 -3
- package/dist/chunk-6AD5TBF2.js.map +1 -0
- package/dist/{chunk-YM7LFCG7.js → chunk-6BYBVRZU.js} +3 -3
- package/dist/{chunk-5IXJGFF2.js → chunk-7JJE3OMJ.js} +5 -5
- package/dist/{chunk-HHOO7HGH.js → chunk-7LVRIW4G.js} +4 -4
- package/dist/{chunk-O6EJ6WTI.js → chunk-AGRC7NQQ.js} +62 -2
- package/dist/chunk-AGRC7NQQ.js.map +1 -0
- package/dist/{chunk-IMYKDWB4.js → chunk-B7GGYNKQ.js} +2 -2
- package/dist/{chunk-BDV7INMP.js → chunk-BXOUVUES.js} +4 -4
- package/dist/{chunk-FO3UEG4S.js → chunk-C2CIIQRG.js} +2 -2
- package/dist/{chunk-ZROPXHJY.js → chunk-CHBXWJZQ.js} +2 -2
- package/dist/{chunk-RYIL3PI2.js → chunk-CILT6V3V.js} +2 -2
- package/dist/{chunk-PXTQPZO4.js → chunk-DLTU4M2I.js} +6 -6
- package/dist/{chunk-GAUEWM7D.js → chunk-EKNUBIIQ.js} +4 -4
- package/dist/{chunk-HQSQC2XL.js → chunk-GFPR7VJS.js} +17 -4
- package/dist/chunk-GFPR7VJS.js.map +1 -0
- package/dist/{chunk-6EOXTJS2.js → chunk-HBAJDI2N.js} +5 -5
- package/dist/{chunk-PVUUIWHY.js → chunk-HLGDYFWR.js} +10 -3
- package/dist/chunk-HLGDYFWR.js.map +1 -0
- package/dist/{chunk-RRNA5GKT.js → chunk-IEPT7HVP.js} +2 -2
- package/dist/{chunk-R233SLY3.js → chunk-IUBHXEPJ.js} +2 -2
- package/dist/{chunk-CH22FZHT.js → chunk-L6BYRCYB.js} +2 -2
- package/dist/{chunk-5OX6XVNS.js → chunk-LOA2VCMS.js} +5 -5
- package/dist/{chunk-BB27JMWB.js → chunk-LSEW3ZZ2.js} +3 -3
- package/dist/{chunk-Y26YV5R3.js → chunk-LWSD4QPT.js} +3 -3
- package/dist/{chunk-WIRRPTFH.js → chunk-LYNNZEQD.js} +1 -1
- package/dist/chunk-LYNNZEQD.js.map +1 -0
- package/dist/{chunk-26NK23DZ.js → chunk-M45IRXDM.js} +3 -3
- package/dist/{chunk-CXJG63MA.js → chunk-NP6EZT44.js} +20 -6
- package/dist/chunk-NP6EZT44.js.map +1 -0
- package/dist/{chunk-GNHAC43Q.js → chunk-O53RIZCC.js} +5 -5
- package/dist/chunk-OPDTLHFA.js +783 -0
- package/dist/chunk-OPDTLHFA.js.map +1 -0
- package/dist/{chunk-LSTBFLL2.js → chunk-P3Z5Y2TS.js} +2 -2
- package/dist/{chunk-QSOYKKMD.js → chunk-P4EDT5ZP.js} +2 -2
- package/dist/{chunk-PC6ZEDRL.js → chunk-RHQYVHFH.js} +2 -2
- package/dist/{chunk-3LPV6BXR.js → chunk-RRDWXNBQ.js} +3 -3
- package/dist/{chunk-4CLICFEY.js → chunk-SJJQKNMP.js} +4 -4
- package/dist/{chunk-TY32C732.js → chunk-SZ4N3IL5.js} +5 -5
- package/dist/{chunk-4USCAEDT.js → chunk-TMHJEYW7.js} +502 -60
- package/dist/chunk-TMHJEYW7.js.map +1 -0
- package/dist/{chunk-2N62W5YP.js → chunk-UA6G45ME.js} +3 -3
- package/dist/{chunk-6YLPHBKR.js → chunk-UOC7JMZO.js} +13 -4
- package/dist/chunk-UOC7JMZO.js.map +1 -0
- package/dist/{chunk-DAP2XL7Q.js → chunk-VOXMU6LB.js} +2 -2
- package/dist/chunk-WNRGOVLG.js +64 -0
- package/dist/chunk-WNRGOVLG.js.map +1 -0
- package/dist/{chunk-DJRWA3Q5.js → chunk-WUG3E423.js} +4 -4
- package/dist/{chunk-PM3QYWUU.js → chunk-XHM2SARW.js} +3 -3
- package/dist/{chunk-RC6SU5NO.js → chunk-XSIFXX54.js} +2 -2
- package/dist/{chunk-CXFOITNS.js → chunk-ZC7MNVYN.js} +2 -2
- package/dist/{chunk-6T2UDBKG.js → chunk-ZCFS7U4J.js} +2 -2
- package/dist/consent/index.cjs.map +1 -1
- package/dist/consent/index.d.cts +4 -4
- package/dist/consent/index.d.ts +4 -4
- package/dist/consent/index.js +3 -3
- package/dist/{crypto-2CRLG4F4.js → crypto-AJB72OKN.js} +3 -3
- package/dist/{delegation-ZTRT2PRV.js → delegation-6FCWDRUS.js} +5 -5
- package/dist/derivations/index.cjs.map +1 -1
- package/dist/derivations/index.d.cts +5 -5
- package/dist/derivations/index.d.ts +5 -5
- package/dist/derivations/index.js +4 -4
- package/dist/{dev-unlock-BOEYl1xl.d.ts → dev-unlock-D3mpVFRc.d.ts} +1 -1
- package/dist/{dev-unlock-AglVnkPY.d.cts → dev-unlock-ckqa_Nso.d.cts} +1 -1
- package/dist/executor-7KSCEIFA.js +8 -0
- package/dist/executor-D2QMNGRJ.js +8 -0
- package/dist/executor-O5AZK7UW.js +11 -0
- package/dist/{fanout-sidecar-OKPMMPLG.js → fanout-sidecar-ZSKEQ6NI.js} +2 -2
- package/dist/guards/index.cjs +53 -1
- package/dist/guards/index.cjs.map +1 -1
- package/dist/guards/index.d.cts +12 -6
- package/dist/guards/index.d.ts +12 -6
- package/dist/guards/index.js +5 -3
- package/dist/{hash-B9m3_fhj.d.ts → hash-CTZVkXLx.d.ts} +1 -1
- package/dist/{hash-RVqz2zi8.d.cts → hash-rDSSd_oW.d.cts} +1 -1
- package/dist/history/index.cjs.map +1 -1
- package/dist/history/index.d.cts +5 -5
- package/dist/history/index.d.ts +5 -5
- package/dist/history/index.js +5 -5
- package/dist/i18n/index.cjs.map +1 -1
- package/dist/i18n/index.d.cts +4 -4
- package/dist/i18n/index.d.ts +4 -4
- package/dist/i18n/index.js +6 -6
- package/dist/immutable-guard-C51vAHuh.d.cts +67 -0
- package/dist/immutable-guard-DyD0qg2k.d.ts +67 -0
- package/dist/index-CkFHr4OP.d.ts +1190 -0
- package/dist/index-Cmop06zJ.d.cts +1190 -0
- package/dist/index.cjs +1636 -61
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +46 -13
- package/dist/index.d.ts +46 -13
- package/dist/index.js +76 -44
- package/dist/index.js.map +1 -1
- package/dist/indexing/index.cjs.map +1 -1
- package/dist/indexing/index.js +2 -2
- package/dist/issue-YIYG4OW5.js +12 -0
- package/dist/{ledger-O7FXOG3D.js → ledger-5JMVF7PY.js} +5 -5
- package/dist/materialized-views/index.cjs.map +1 -1
- package/dist/materialized-views/index.d.cts +5 -6
- package/dist/materialized-views/index.d.ts +5 -6
- package/dist/materialized-views/index.js +6 -6
- package/dist/noydb-D5SLAJ6V.js +34 -0
- package/dist/overlay-views/index.cjs.map +1 -1
- package/dist/overlay-views/index.d.cts +5 -5
- package/dist/overlay-views/index.d.ts +5 -5
- package/dist/overlay-views/index.js +4 -4
- package/dist/periods/index.cjs.map +1 -1
- package/dist/periods/index.d.cts +4 -4
- package/dist/periods/index.d.ts +4 -4
- package/dist/periods/index.js +5 -5
- package/dist/{public-envelope-HMYHZIRH.js → public-envelope-PFLZI5MO.js} +4 -4
- package/dist/query/index.cjs +293 -10
- package/dist/query/index.cjs.map +1 -1
- package/dist/query/index.d.cts +2 -2
- package/dist/query/index.d.ts +2 -2
- package/dist/query/index.js +4 -4
- package/dist/registry-BVQ5ITMF.js +8 -0
- package/dist/registry-JLP3QOLD.js +8 -0
- package/dist/{registry-ST2VNFZC.js → registry-NCY445U5.js} +3 -3
- package/dist/{revoke-S6JMSLUN.js → revoke-7RLGQWZ7.js} +6 -6
- package/dist/session/index.cjs.map +1 -1
- package/dist/session/index.d.cts +5 -5
- package/dist/session/index.d.ts +5 -5
- package/dist/session/index.js +3 -3
- package/dist/shadow/index.cjs.map +1 -1
- package/dist/shadow/index.d.cts +4 -4
- package/dist/shadow/index.d.ts +4 -4
- package/dist/shadow/index.js +2 -2
- package/dist/{signer-7NPTB3SQ.js → signer-6JF44I4A.js} +5 -5
- package/dist/snapshots/index.cjs.map +1 -1
- package/dist/snapshots/index.d.cts +4 -4
- package/dist/snapshots/index.d.ts +4 -4
- package/dist/snapshots/index.js +4 -4
- package/dist/{stale-VKXSXJF4.js → stale-UBLP3RJ3.js} +2 -2
- package/dist/store/index.cjs.map +1 -1
- package/dist/store/index.d.cts +4 -4
- package/dist/store/index.d.ts +4 -4
- package/dist/store/index.js +2 -2
- package/dist/strategy-rtpKDfTC.d.cts +2029 -0
- package/dist/strategy-rtpKDfTC.d.ts +2029 -0
- package/dist/sync/index.cjs.map +1 -1
- package/dist/sync/index.d.cts +3 -3
- package/dist/sync/index.d.ts +3 -3
- package/dist/sync/index.js +4 -4
- package/dist/team/index.cjs.map +1 -1
- package/dist/team/index.d.cts +4 -4
- package/dist/team/index.d.ts +4 -4
- package/dist/team/index.js +8 -8
- package/dist/tx/index.cjs +8 -1
- package/dist/tx/index.cjs.map +1 -1
- package/dist/tx/index.d.cts +4 -4
- package/dist/tx/index.d.ts +4 -4
- package/dist/tx/index.js +3 -3
- package/dist/{types-n2_IfwlQ.d.cts → types-BGwjsDef.d.cts} +520 -6
- package/dist/{types-CaNQm4i8.d.ts → types-DRdfwgTG.d.ts} +520 -6
- package/dist/{ulid-CLMjmyhG.d.cts → ulid-D4d0Xto3.d.cts} +1 -1
- package/dist/{ulid-B9SMWj5i.d.ts → ulid-DOTPZ5_h.d.ts} +1 -1
- package/dist/util/index.cjs.map +1 -1
- package/dist/util/index.js +1 -1
- package/dist/vault-group-Z4KB75ZH.js +450 -0
- package/dist/vault-group-Z4KB75ZH.js.map +1 -0
- package/dist/{with-derivation-CVIOPTUf.d.ts → with-derivation-B082Y_WQ.d.ts} +1 -1
- package/dist/{with-derivation-aKrtS7Jj.d.cts → with-derivation-CB1EdcFF.d.cts} +1 -1
- package/dist/{with-materialized-view-C1eA1_T_.d.cts → with-materialized-view-CzRg1Dpr.d.cts} +1 -1
- package/dist/{with-materialized-view-DaYaE8-Q.d.ts → with-materialized-view-Dw4SwjKl.d.ts} +1 -1
- package/dist/{with-overlayed-view-DleJfKcV.d.cts → with-overlayed-view-C9YFKXzn.d.cts} +1 -1
- package/dist/{with-overlayed-view-DQsh2p8H.d.ts → with-overlayed-view-CaCXeW26.d.ts} +1 -1
- package/package.json +3 -3
- package/dist/chunk-2LPPNWF6.js +0 -340
- package/dist/chunk-2LPPNWF6.js.map +0 -1
- package/dist/chunk-4USCAEDT.js.map +0 -1
- package/dist/chunk-6YLPHBKR.js.map +0 -1
- package/dist/chunk-C3WE6UJY.js +0 -19
- package/dist/chunk-C3WE6UJY.js.map +0 -1
- package/dist/chunk-CXJG63MA.js.map +0 -1
- package/dist/chunk-DRXIZOFV.js.map +0 -1
- package/dist/chunk-HQSQC2XL.js.map +0 -1
- package/dist/chunk-O6EJ6WTI.js.map +0 -1
- package/dist/chunk-PVUUIWHY.js.map +0 -1
- package/dist/chunk-WIRRPTFH.js.map +0 -1
- package/dist/executor-S76VN45G.js +0 -8
- package/dist/executor-UCXLIGLW.js +0 -11
- package/dist/executor-ZCNZJMGR.js +0 -8
- package/dist/index-B8bjExET.d.cts +0 -2434
- package/dist/index-DfUbNad8.d.ts +0 -2434
- package/dist/issue-3W6IVLKH.js +0 -12
- package/dist/noydb-YAZNH5TI.js +0 -34
- package/dist/registry-UFIK7CSR.js +0 -8
- package/dist/registry-ZGYYSM5I.js +0 -8
- package/dist/strategy-CT2LCKAX.d.cts +0 -613
- package/dist/strategy-CT2LCKAX.d.ts +0 -613
- package/dist/with-guard-DZQbPzoP.d.cts +0 -18
- package/dist/with-guard-DseETUrF.d.ts +0 -18
- /package/dist/{chunk-7CEGU63S.js.map → chunk-4BHFNKTP.js.map} +0 -0
- /package/dist/{chunk-5OEJ6GOT.js.map → chunk-5ARRXIVR.js.map} +0 -0
- /package/dist/{chunk-YM7LFCG7.js.map → chunk-6BYBVRZU.js.map} +0 -0
- /package/dist/{chunk-5IXJGFF2.js.map → chunk-7JJE3OMJ.js.map} +0 -0
- /package/dist/{chunk-HHOO7HGH.js.map → chunk-7LVRIW4G.js.map} +0 -0
- /package/dist/{chunk-IMYKDWB4.js.map → chunk-B7GGYNKQ.js.map} +0 -0
- /package/dist/{chunk-BDV7INMP.js.map → chunk-BXOUVUES.js.map} +0 -0
- /package/dist/{chunk-FO3UEG4S.js.map → chunk-C2CIIQRG.js.map} +0 -0
- /package/dist/{chunk-ZROPXHJY.js.map → chunk-CHBXWJZQ.js.map} +0 -0
- /package/dist/{chunk-RYIL3PI2.js.map → chunk-CILT6V3V.js.map} +0 -0
- /package/dist/{chunk-PXTQPZO4.js.map → chunk-DLTU4M2I.js.map} +0 -0
- /package/dist/{chunk-GAUEWM7D.js.map → chunk-EKNUBIIQ.js.map} +0 -0
- /package/dist/{chunk-6EOXTJS2.js.map → chunk-HBAJDI2N.js.map} +0 -0
- /package/dist/{chunk-RRNA5GKT.js.map → chunk-IEPT7HVP.js.map} +0 -0
- /package/dist/{chunk-R233SLY3.js.map → chunk-IUBHXEPJ.js.map} +0 -0
- /package/dist/{chunk-CH22FZHT.js.map → chunk-L6BYRCYB.js.map} +0 -0
- /package/dist/{chunk-5OX6XVNS.js.map → chunk-LOA2VCMS.js.map} +0 -0
- /package/dist/{chunk-BB27JMWB.js.map → chunk-LSEW3ZZ2.js.map} +0 -0
- /package/dist/{chunk-Y26YV5R3.js.map → chunk-LWSD4QPT.js.map} +0 -0
- /package/dist/{chunk-26NK23DZ.js.map → chunk-M45IRXDM.js.map} +0 -0
- /package/dist/{chunk-GNHAC43Q.js.map → chunk-O53RIZCC.js.map} +0 -0
- /package/dist/{chunk-LSTBFLL2.js.map → chunk-P3Z5Y2TS.js.map} +0 -0
- /package/dist/{chunk-QSOYKKMD.js.map → chunk-P4EDT5ZP.js.map} +0 -0
- /package/dist/{chunk-PC6ZEDRL.js.map → chunk-RHQYVHFH.js.map} +0 -0
- /package/dist/{chunk-3LPV6BXR.js.map → chunk-RRDWXNBQ.js.map} +0 -0
- /package/dist/{chunk-4CLICFEY.js.map → chunk-SJJQKNMP.js.map} +0 -0
- /package/dist/{chunk-TY32C732.js.map → chunk-SZ4N3IL5.js.map} +0 -0
- /package/dist/{chunk-2N62W5YP.js.map → chunk-UA6G45ME.js.map} +0 -0
- /package/dist/{chunk-DAP2XL7Q.js.map → chunk-VOXMU6LB.js.map} +0 -0
- /package/dist/{chunk-DJRWA3Q5.js.map → chunk-WUG3E423.js.map} +0 -0
- /package/dist/{chunk-PM3QYWUU.js.map → chunk-XHM2SARW.js.map} +0 -0
- /package/dist/{chunk-RC6SU5NO.js.map → chunk-XSIFXX54.js.map} +0 -0
- /package/dist/{chunk-CXFOITNS.js.map → chunk-ZC7MNVYN.js.map} +0 -0
- /package/dist/{chunk-6T2UDBKG.js.map → chunk-ZCFS7U4J.js.map} +0 -0
- /package/dist/{crypto-2CRLG4F4.js.map → crypto-AJB72OKN.js.map} +0 -0
- /package/dist/{delegation-ZTRT2PRV.js.map → delegation-6FCWDRUS.js.map} +0 -0
- /package/dist/{executor-S76VN45G.js.map → executor-7KSCEIFA.js.map} +0 -0
- /package/dist/{executor-UCXLIGLW.js.map → executor-D2QMNGRJ.js.map} +0 -0
- /package/dist/{executor-ZCNZJMGR.js.map → executor-O5AZK7UW.js.map} +0 -0
- /package/dist/{fanout-sidecar-OKPMMPLG.js.map → fanout-sidecar-ZSKEQ6NI.js.map} +0 -0
- /package/dist/{issue-3W6IVLKH.js.map → issue-YIYG4OW5.js.map} +0 -0
- /package/dist/{ledger-O7FXOG3D.js.map → ledger-5JMVF7PY.js.map} +0 -0
- /package/dist/{noydb-YAZNH5TI.js.map → noydb-D5SLAJ6V.js.map} +0 -0
- /package/dist/{public-envelope-HMYHZIRH.js.map → public-envelope-PFLZI5MO.js.map} +0 -0
- /package/dist/{registry-ST2VNFZC.js.map → registry-BVQ5ITMF.js.map} +0 -0
- /package/dist/{registry-UFIK7CSR.js.map → registry-JLP3QOLD.js.map} +0 -0
- /package/dist/{registry-ZGYYSM5I.js.map → registry-NCY445U5.js.map} +0 -0
- /package/dist/{revoke-S6JMSLUN.js.map → revoke-7RLGQWZ7.js.map} +0 -0
- /package/dist/{signer-7NPTB3SQ.js.map → signer-6JF44I4A.js.map} +0 -0
- /package/dist/{stale-VKXSXJF4.js.map → stale-UBLP3RJ3.js.map} +0 -0
package/dist/index.js
CHANGED
|
@@ -3,9 +3,10 @@ import {
|
|
|
3
3
|
issueDelegation,
|
|
4
4
|
loadActiveDelegations,
|
|
5
5
|
revokeDelegation
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-BXOUVUES.js";
|
|
7
7
|
import {
|
|
8
8
|
Collection,
|
|
9
|
+
ComputedFieldError,
|
|
9
10
|
DEFAULT_FRESHNESS_MS,
|
|
10
11
|
ELEVATION_AUDIT_COLLECTION,
|
|
11
12
|
ElevatedHandle,
|
|
@@ -19,6 +20,7 @@ import {
|
|
|
19
20
|
RefRegistry,
|
|
20
21
|
RefScopeError,
|
|
21
22
|
STRICT_POLICY,
|
|
23
|
+
SequenceStore,
|
|
22
24
|
UserApi,
|
|
23
25
|
Vault,
|
|
24
26
|
checkGate,
|
|
@@ -30,6 +32,7 @@ import {
|
|
|
30
32
|
describeUserAuth,
|
|
31
33
|
diagramAuthConfig,
|
|
32
34
|
estimateRecordBytes,
|
|
35
|
+
evalComputedFields,
|
|
33
36
|
isZodSchema,
|
|
34
37
|
loadVaultPolicy,
|
|
35
38
|
mergePolicy,
|
|
@@ -38,8 +41,9 @@ import {
|
|
|
38
41
|
ref,
|
|
39
42
|
saveVaultPolicy,
|
|
40
43
|
validateSchemaInput,
|
|
41
|
-
validateSchemaOutput
|
|
42
|
-
|
|
44
|
+
validateSchemaOutput,
|
|
45
|
+
withArchive
|
|
46
|
+
} from "./chunk-TMHJEYW7.js";
|
|
43
47
|
import {
|
|
44
48
|
DEFAULT_PUBLIC_ENVELOPE_SCHEMA,
|
|
45
49
|
PUBLIC_ENVELOPE_FIELDS,
|
|
@@ -50,27 +54,27 @@ import {
|
|
|
50
54
|
TxContext,
|
|
51
55
|
TxVault,
|
|
52
56
|
runTransaction
|
|
53
|
-
} from "./chunk-
|
|
57
|
+
} from "./chunk-M45IRXDM.js";
|
|
54
58
|
import {
|
|
55
59
|
withDerivation
|
|
56
|
-
} from "./chunk-
|
|
57
|
-
import "./chunk-
|
|
58
|
-
import "./chunk-
|
|
60
|
+
} from "./chunk-VOXMU6LB.js";
|
|
61
|
+
import "./chunk-L6BYRCYB.js";
|
|
62
|
+
import "./chunk-5ARRXIVR.js";
|
|
59
63
|
import {
|
|
60
64
|
withMaterializedView
|
|
61
|
-
} from "./chunk-
|
|
62
|
-
import "./chunk-
|
|
63
|
-
import "./chunk-
|
|
64
|
-
import "./chunk-
|
|
65
|
+
} from "./chunk-CHBXWJZQ.js";
|
|
66
|
+
import "./chunk-ZCFS7U4J.js";
|
|
67
|
+
import "./chunk-EKNUBIIQ.js";
|
|
68
|
+
import "./chunk-C2CIIQRG.js";
|
|
65
69
|
import {
|
|
66
70
|
withOverlayedView
|
|
67
|
-
} from "./chunk-
|
|
68
|
-
import "./chunk-
|
|
69
|
-
import "./chunk-
|
|
71
|
+
} from "./chunk-XSIFXX54.js";
|
|
72
|
+
import "./chunk-RHQYVHFH.js";
|
|
73
|
+
import "./chunk-4BHFNKTP.js";
|
|
70
74
|
import {
|
|
71
75
|
isDiscriminant
|
|
72
76
|
} from "./chunk-STNPB3UM.js";
|
|
73
|
-
import "./chunk-
|
|
77
|
+
import "./chunk-P4EDT5ZP.js";
|
|
74
78
|
import {
|
|
75
79
|
mergeCrdtStates,
|
|
76
80
|
resolveCrdtSnapshot
|
|
@@ -85,7 +89,7 @@ import {
|
|
|
85
89
|
parseSealedEnvelope,
|
|
86
90
|
savePersistedSchema,
|
|
87
91
|
saveSealedPassphrase
|
|
88
|
-
} from "./chunk-
|
|
92
|
+
} from "./chunk-XHM2SARW.js";
|
|
89
93
|
import {
|
|
90
94
|
NOYDB_BUNDLE_FORMAT_VERSION,
|
|
91
95
|
NOYDB_BUNDLE_MAGIC,
|
|
@@ -96,7 +100,7 @@ import {
|
|
|
96
100
|
readNoydbBundlePublicEnvelope,
|
|
97
101
|
resetBrotliSupportCache,
|
|
98
102
|
writeNoydbBundle
|
|
99
|
-
} from "./chunk-
|
|
103
|
+
} from "./chunk-LSEW3ZZ2.js";
|
|
100
104
|
import {
|
|
101
105
|
PUBLIC_ENVELOPE_RECORD_ID,
|
|
102
106
|
isPublicEnvelope,
|
|
@@ -104,28 +108,29 @@ import {
|
|
|
104
108
|
readPublicEnvelope,
|
|
105
109
|
savePublicEnvelope,
|
|
106
110
|
validatePublicEnvelopeInput
|
|
107
|
-
} from "./chunk-
|
|
111
|
+
} from "./chunk-UA6G45ME.js";
|
|
108
112
|
import {
|
|
109
113
|
CONSENT_AUDIT_COLLECTION
|
|
110
|
-
} from "./chunk-
|
|
114
|
+
} from "./chunk-P3Z5Y2TS.js";
|
|
111
115
|
import {
|
|
112
116
|
PERIODS_COLLECTION
|
|
113
|
-
} from "./chunk-
|
|
117
|
+
} from "./chunk-RRDWXNBQ.js";
|
|
114
118
|
import "./chunk-UF3BUNQZ.js";
|
|
115
119
|
import {
|
|
120
|
+
immutableGuard,
|
|
116
121
|
withGuard
|
|
117
|
-
} from "./chunk-
|
|
122
|
+
} from "./chunk-WNRGOVLG.js";
|
|
118
123
|
import "./chunk-A3JMGXPG.js";
|
|
119
124
|
import "./chunk-UMLVJTYV.js";
|
|
120
|
-
import "./chunk-
|
|
125
|
+
import "./chunk-HLGDYFWR.js";
|
|
121
126
|
import {
|
|
122
127
|
CollectionFrame,
|
|
123
128
|
VaultFrame
|
|
124
|
-
} from "./chunk-
|
|
129
|
+
} from "./chunk-CILT6V3V.js";
|
|
125
130
|
import {
|
|
126
131
|
enforceScript,
|
|
127
132
|
inferScripts
|
|
128
|
-
} from "./chunk-
|
|
133
|
+
} from "./chunk-B7GGYNKQ.js";
|
|
129
134
|
import {
|
|
130
135
|
DICT_COLLECTION_PREFIX,
|
|
131
136
|
DictionaryHandle,
|
|
@@ -139,7 +144,7 @@ import {
|
|
|
139
144
|
resolveI18nText,
|
|
140
145
|
resolvePolicy,
|
|
141
146
|
validateI18nTextValue
|
|
142
|
-
} from "./chunk-
|
|
147
|
+
} from "./chunk-O53RIZCC.js";
|
|
143
148
|
import {
|
|
144
149
|
createBundleStore,
|
|
145
150
|
routeStore,
|
|
@@ -151,7 +156,7 @@ import {
|
|
|
151
156
|
withRetry,
|
|
152
157
|
wrapBundleStore,
|
|
153
158
|
wrapStore
|
|
154
|
-
} from "./chunk-
|
|
159
|
+
} from "./chunk-IEPT7HVP.js";
|
|
155
160
|
import {
|
|
156
161
|
SYNC_CREDENTIALS_COLLECTION,
|
|
157
162
|
credentialStatus,
|
|
@@ -159,7 +164,7 @@ import {
|
|
|
159
164
|
getCredential,
|
|
160
165
|
listCredentials,
|
|
161
166
|
putCredential
|
|
162
|
-
} from "./chunk-
|
|
167
|
+
} from "./chunk-LOA2VCMS.js";
|
|
163
168
|
import {
|
|
164
169
|
MAGIC_LINK_CONTENT_INFO_PREFIX,
|
|
165
170
|
MAGIC_LINK_GRANTS_COLLECTION,
|
|
@@ -194,17 +199,17 @@ import {
|
|
|
194
199
|
unwrapDeksFromShamirEntry,
|
|
195
200
|
unwrapMagicLinkGrant,
|
|
196
201
|
writeMagicLinkGrant
|
|
197
|
-
} from "./chunk-
|
|
202
|
+
} from "./chunk-DLTU4M2I.js";
|
|
198
203
|
import {
|
|
199
204
|
assertTierAccess,
|
|
200
205
|
dekKey,
|
|
201
206
|
effectiveClearance
|
|
202
|
-
} from "./chunk-
|
|
207
|
+
} from "./chunk-ZC7MNVYN.js";
|
|
203
208
|
import {
|
|
204
209
|
PresenceHandle,
|
|
205
210
|
SyncEngine,
|
|
206
211
|
SyncTransaction
|
|
207
|
-
} from "./chunk-
|
|
212
|
+
} from "./chunk-WUG3E423.js";
|
|
208
213
|
import {
|
|
209
214
|
DIRECTORY_RECORD_ID,
|
|
210
215
|
USER_ENVELOPE_COLLECTION,
|
|
@@ -232,7 +237,7 @@ import {
|
|
|
232
237
|
saveUserEnvelope,
|
|
233
238
|
validatePassphrase,
|
|
234
239
|
visibilityRecordId
|
|
235
|
-
} from "./chunk-
|
|
240
|
+
} from "./chunk-GFPR7VJS.js";
|
|
236
241
|
import {
|
|
237
242
|
BUNDLE_STORE_POLICY,
|
|
238
243
|
INDEXED_STORE_POLICY,
|
|
@@ -252,7 +257,7 @@ import {
|
|
|
252
257
|
revokeAllSessions,
|
|
253
258
|
revokeSession,
|
|
254
259
|
validateSessionPolicy
|
|
255
|
-
} from "./chunk-
|
|
260
|
+
} from "./chunk-LWSD4QPT.js";
|
|
256
261
|
import {
|
|
257
262
|
generateULID,
|
|
258
263
|
isULID
|
|
@@ -262,14 +267,14 @@ import {
|
|
|
262
267
|
VaultInstant,
|
|
263
268
|
diff,
|
|
264
269
|
formatDiff
|
|
265
|
-
} from "./chunk-
|
|
270
|
+
} from "./chunk-6BYBVRZU.js";
|
|
266
271
|
import {
|
|
267
272
|
LEDGER_COLLECTION,
|
|
268
273
|
LEDGER_DELTAS_COLLECTION,
|
|
269
274
|
LedgerStore,
|
|
270
275
|
applyPatch,
|
|
271
276
|
computePatch
|
|
272
|
-
} from "./chunk-
|
|
277
|
+
} from "./chunk-SJJQKNMP.js";
|
|
273
278
|
import {
|
|
274
279
|
canonicalJson,
|
|
275
280
|
envelopePayloadHash,
|
|
@@ -287,7 +292,7 @@ import {
|
|
|
287
292
|
buildLiveQuery,
|
|
288
293
|
executePlan,
|
|
289
294
|
resetJoinWarnings
|
|
290
|
-
} from "./chunk-
|
|
295
|
+
} from "./chunk-UOC7JMZO.js";
|
|
291
296
|
import {
|
|
292
297
|
CollectionIndexes
|
|
293
298
|
} from "./chunk-WIBHRONM.js";
|
|
@@ -297,7 +302,7 @@ import {
|
|
|
297
302
|
max,
|
|
298
303
|
min,
|
|
299
304
|
sum
|
|
300
|
-
} from "./chunk-
|
|
305
|
+
} from "./chunk-NP6EZT44.js";
|
|
301
306
|
import {
|
|
302
307
|
Aggregation,
|
|
303
308
|
GROUPBY_MAX_CARDINALITY,
|
|
@@ -305,9 +310,15 @@ import {
|
|
|
305
310
|
GroupedAggregation,
|
|
306
311
|
GroupedQuery,
|
|
307
312
|
GroupedQueryN,
|
|
313
|
+
MoneyCurrencyError,
|
|
314
|
+
MoneyPrecisionError,
|
|
315
|
+
MoneyUnsupportedError,
|
|
308
316
|
groupAndReduce,
|
|
309
|
-
|
|
310
|
-
|
|
317
|
+
isMoneyDescriptor,
|
|
318
|
+
money,
|
|
319
|
+
reduceRecords,
|
|
320
|
+
scaleForCurrency
|
|
321
|
+
} from "./chunk-OPDTLHFA.js";
|
|
311
322
|
import {
|
|
312
323
|
evaluateClause,
|
|
313
324
|
evaluateFieldClause,
|
|
@@ -324,15 +335,15 @@ import {
|
|
|
324
335
|
detectMagic,
|
|
325
336
|
detectMimeType,
|
|
326
337
|
isPreCompressed
|
|
327
|
-
} from "./chunk-
|
|
328
|
-
import "./chunk-
|
|
338
|
+
} from "./chunk-HBAJDI2N.js";
|
|
339
|
+
import "./chunk-6AD5TBF2.js";
|
|
329
340
|
import {
|
|
330
341
|
NOYDB_BACKUP_VERSION,
|
|
331
342
|
NOYDB_FORMAT_VERSION,
|
|
332
343
|
NOYDB_KEYRING_VERSION,
|
|
333
344
|
NOYDB_SYNC_VERSION,
|
|
334
345
|
createStore
|
|
335
|
-
} from "./chunk-
|
|
346
|
+
} from "./chunk-LYNNZEQD.js";
|
|
336
347
|
import {
|
|
337
348
|
base64ToBuffer,
|
|
338
349
|
bufferToBase64,
|
|
@@ -341,7 +352,7 @@ import {
|
|
|
341
352
|
derivePresenceKey,
|
|
342
353
|
encryptBytes,
|
|
343
354
|
encryptDeterministic
|
|
344
|
-
} from "./chunk-
|
|
355
|
+
} from "./chunk-IUBHXEPJ.js";
|
|
345
356
|
import {
|
|
346
357
|
AlreadyElevatedError,
|
|
347
358
|
AmendmentForbiddenError,
|
|
@@ -410,9 +421,12 @@ import {
|
|
|
410
421
|
SchemaUpdateError,
|
|
411
422
|
SchemaValidationError,
|
|
412
423
|
ScriptViolationError,
|
|
424
|
+
SequenceContentionError,
|
|
425
|
+
SequenceOfflineError,
|
|
413
426
|
SessionExpiredError,
|
|
414
427
|
SessionNotFoundError,
|
|
415
428
|
SessionPolicyError,
|
|
429
|
+
ShardProvisioningError,
|
|
416
430
|
SnapshotNotFoundError,
|
|
417
431
|
StoreCapabilityError,
|
|
418
432
|
TamperedError,
|
|
@@ -420,9 +434,11 @@ import {
|
|
|
420
434
|
TierNotGrantedError,
|
|
421
435
|
TranslatorNotConfiguredError,
|
|
422
436
|
UniqueConstraintError,
|
|
437
|
+
UnknownShardError,
|
|
423
438
|
UnsupportedIndexOptionError,
|
|
424
|
-
ValidationError
|
|
425
|
-
|
|
439
|
+
ValidationError,
|
|
440
|
+
VaultTemplateNotFoundError
|
|
441
|
+
} from "./chunk-AGRC7NQQ.js";
|
|
426
442
|
|
|
427
443
|
// src/schema-update/strategies.ts
|
|
428
444
|
function blindUpdate() {
|
|
@@ -648,6 +664,7 @@ export {
|
|
|
648
664
|
CollectionFrame,
|
|
649
665
|
CollectionIndexes,
|
|
650
666
|
CollectionInstant,
|
|
667
|
+
ComputedFieldError,
|
|
651
668
|
ConflictError,
|
|
652
669
|
CrossJoinSourceUnknownError,
|
|
653
670
|
CrossJoinTooLargeError,
|
|
@@ -711,6 +728,9 @@ export {
|
|
|
711
728
|
MemorySealingKeyProvider,
|
|
712
729
|
MigrationRequiredError,
|
|
713
730
|
MissingTranslationError,
|
|
731
|
+
MoneyCurrencyError,
|
|
732
|
+
MoneyPrecisionError,
|
|
733
|
+
MoneyUnsupportedError,
|
|
714
734
|
NOYDB_BACKUP_VERSION,
|
|
715
735
|
NOYDB_BUNDLE_FORMAT_VERSION,
|
|
716
736
|
NOYDB_BUNDLE_MAGIC,
|
|
@@ -763,9 +783,13 @@ export {
|
|
|
763
783
|
SchemaUpdateError,
|
|
764
784
|
SchemaValidationError,
|
|
765
785
|
ScriptViolationError,
|
|
786
|
+
SequenceContentionError,
|
|
787
|
+
SequenceOfflineError,
|
|
788
|
+
SequenceStore,
|
|
766
789
|
SessionExpiredError,
|
|
767
790
|
SessionNotFoundError,
|
|
768
791
|
SessionPolicyError,
|
|
792
|
+
ShardProvisioningError,
|
|
769
793
|
SnapshotNotFoundError,
|
|
770
794
|
StoreCapabilityError,
|
|
771
795
|
SyncEngine,
|
|
@@ -781,6 +805,7 @@ export {
|
|
|
781
805
|
USER_ENVELOPE_COLLECTION,
|
|
782
806
|
USER_ENVELOPE_MAX_BYTES,
|
|
783
807
|
UniqueConstraintError,
|
|
808
|
+
UnknownShardError,
|
|
784
809
|
UnsupportedIndexOptionError,
|
|
785
810
|
UserApi,
|
|
786
811
|
UserEnvelopeOversizedError,
|
|
@@ -789,6 +814,7 @@ export {
|
|
|
789
814
|
Vault,
|
|
790
815
|
VaultFrame,
|
|
791
816
|
VaultInstant,
|
|
817
|
+
VaultTemplateNotFoundError,
|
|
792
818
|
WeakPassphraseError,
|
|
793
819
|
activeSessionCount,
|
|
794
820
|
additiveOnly,
|
|
@@ -845,6 +871,7 @@ export {
|
|
|
845
871
|
envelopePayloadHash,
|
|
846
872
|
estimateEntropy,
|
|
847
873
|
estimateRecordBytes,
|
|
874
|
+
evalComputedFields,
|
|
848
875
|
evaluateClause,
|
|
849
876
|
evaluateExportCapability,
|
|
850
877
|
evaluateFieldClause,
|
|
@@ -861,6 +888,7 @@ export {
|
|
|
861
888
|
hasRecoveryEnrolled,
|
|
862
889
|
hashEntry,
|
|
863
890
|
i18nText,
|
|
891
|
+
immutableGuard,
|
|
864
892
|
inferScripts,
|
|
865
893
|
isDevUnlockActive,
|
|
866
894
|
isDictCollectionName,
|
|
@@ -868,6 +896,7 @@ export {
|
|
|
868
896
|
isDiscriminant,
|
|
869
897
|
isI18nTextDescriptor,
|
|
870
898
|
isMagicLinkGrantExpired,
|
|
899
|
+
isMoneyDescriptor,
|
|
871
900
|
isPreCompressed,
|
|
872
901
|
isPublicEnvelope,
|
|
873
902
|
isSessionAlive,
|
|
@@ -899,6 +928,7 @@ export {
|
|
|
899
928
|
mintPaperRecoveryEntry,
|
|
900
929
|
mintShamirRecoveryEntry,
|
|
901
930
|
mintWrappedDeksBlob,
|
|
931
|
+
money,
|
|
902
932
|
paddedIndex,
|
|
903
933
|
parseBytes,
|
|
904
934
|
parseIndex,
|
|
@@ -939,6 +969,7 @@ export {
|
|
|
939
969
|
saveShamirRecoveryEntries,
|
|
940
970
|
saveUserEnvelope,
|
|
941
971
|
saveVaultPolicy,
|
|
972
|
+
scaleForCurrency,
|
|
942
973
|
sha256Hex,
|
|
943
974
|
sum,
|
|
944
975
|
unwrapDeksFromBlob,
|
|
@@ -952,6 +983,7 @@ export {
|
|
|
952
983
|
validateSchemaOutput,
|
|
953
984
|
validateSessionPolicy,
|
|
954
985
|
visibilityRecordId,
|
|
986
|
+
withArchive,
|
|
955
987
|
withCache,
|
|
956
988
|
withCircuitBreaker,
|
|
957
989
|
withDerivation,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/schema-update/strategies.ts","../src/schema-update/cutover.ts","../src/vault-diff.ts"],"sourcesContent":["/** Bundled light update strategies. */\nimport { NonAdditiveSchemaChangeError, SchemaLockedError } from '../errors.js'\nimport type { SchemaUpdateStrategy, SchemaDelta } from './types.js'\n\n/** Allow any schema change. Explicit blind / back-compat. */\nexport function blindUpdate(): SchemaUpdateStrategy {\n return { name: 'blindUpdate', onSchemaDelta: () => ({ action: 'allow' }) }\n}\n\n/** Allow additive changes; reject non-additive ones. The safety backstop. */\nexport function additiveOnly(): SchemaUpdateStrategy {\n return {\n name: 'additiveOnly',\n onSchemaDelta(delta: SchemaDelta) {\n if (delta.kind === 'non-additive') {\n return {\n action: 'reject' as const,\n error: new NonAdditiveSchemaChangeError(\n `Non-additive schema change to \"${delta.collection}\" ` +\n `(added: [${delta.added.join(', ')}], removed: [${delta.removed.join(', ')}], ` +\n `changed: [${delta.changed.map(c => c.field).join(', ')}]). ` +\n `Register a coordinatedCutover() strategy to migrate, or revert the change.`,\n ),\n }\n }\n return { action: 'allow' as const }\n },\n }\n}\n\n/**\n * Reject schema changes. With `fields`, reject only when one of those\n * fields is added/removed/changed; otherwise reject any non-`none` delta.\n */\nexport function lockSchema(opts?: { readonly fields?: readonly string[] }): SchemaUpdateStrategy {\n const fields = opts?.fields\n return {\n name: 'lockSchema',\n onSchemaDelta(delta: SchemaDelta) {\n if (delta.kind === 'none') return { action: 'allow' as const }\n const touched = fields\n ? [...delta.added, ...delta.removed, ...delta.changed.map(c => c.field)].filter(f => fields.includes(f))\n : ['<any>']\n if (touched.length === 0) return { action: 'allow' as const }\n return {\n action: 'reject' as const,\n error: new SchemaLockedError(\n `Schema for \"${delta.collection}\" is locked` +\n (fields ? ` on fields [${fields.join(', ')}] (touched: [${touched.join(', ')}])` : '') +\n `; the change was refused.`,\n ),\n }\n },\n }\n}\n","/** The coordinatedCutover update strategy (single-step — no from/to). */\nimport type { SchemaUpdateStrategy, SchemaDelta, TransformFn } from './types.js'\n\nexport function coordinatedCutover(opts: { readonly transform: TransformFn }): SchemaUpdateStrategy {\n return {\n name: 'coordinatedCutover',\n onSchemaDelta(delta: SchemaDelta) {\n if (delta.kind === 'non-additive') {\n return { action: 'cutover' as const, transform: opts.transform }\n }\n return { action: 'allow' as const }\n },\n }\n}\n","/**\n * Vault-level diff orchestrator.\n *\n * Compares a live `Vault`'s plaintext state against a candidate state\n * (another vault, a plain `{ collection: records[] }` map, or a vault\n * dump JSON) and returns a structured `VaultDiff` plan listing the\n * records that would be added, modified, or deleted to bring the live\n * vault into the candidate's shape.\n *\n * Builds on two existing record-level helpers:\n *\n * 1. `diff(a, b)` from `./history/diff.ts` — emits dot-pathed\n * `DiffEntry[]` with `type: 'added' | 'removed' | 'changed'` for\n * each changed field of two records. Used here for the\n * `fieldDiffs` of every `modified` entry, and (with empty result)\n * as the default deep-equal check.\n *\n * 2. `Vault.exportStream()` from `./vault.ts` — the canonical\n * decrypt-and-stream-records iterator. Used to walk both sides\n * when the candidate is itself a `Vault`. ACL-scoped: collections\n * the caller can't read silently drop out, the same way every\n * other plaintext-emitting export pipeline filters them.\n *\n * The new orchestration is the **vault-level** enumeration: bucket\n * each record id into added (only in candidate), deleted (only in\n * vault), or modified (in both with field changes); leave the\n * field-level granularity to the existing `diff()`.\n *\n * Use cases:\n *\n * - Import preview (`@noy-db/as-*` `fromString` returns a plan\n * whose body is a `VaultDiff`).\n * - Backup verification (\"does this `.noydb` bundle from yesterday\n * match the current vault?\").\n * - Two-vault reconciliation (\"what's different between Office A\n * and Office B before we sync?\").\n * - Test assertions (golden-file testing with one-liner\n * `expect(plan.summary).toEqual(...)`).\n *\n * @module\n */\n\nimport type { Vault } from './vault.js'\nimport { diff as fieldDiff, type DiffEntry as FieldDiffEntry } from './history/diff.js'\n\n// ─── Public types ──────────────────────────────────────────────────────\n\n/** Per-record entry shape — added and deleted records carry only the record value. */\nexport interface VaultDiffEntry<T = unknown> {\n readonly collection: string\n readonly id: string\n readonly record: T\n}\n\n/** Modified records carry both halves of the diff plus the field-level breakdown. */\nexport interface VaultDiffModifiedEntry<T = unknown> extends VaultDiffEntry<T> {\n /** The record as it stands in the live vault. */\n readonly before: T\n /** Top-level keys whose values differ between `before` and `record`. */\n readonly fieldsChanged: readonly string[]\n /**\n * Field-level diff entries from `diff(before, record)`. Reuses the\n * existing per-record diff helper so consumers can render git-style\n * `path: from → to` rows without re-walking the records.\n */\n readonly fieldDiffs: readonly FieldDiffEntry[]\n}\n\nexport interface VaultDiff<T = unknown> {\n readonly added: readonly VaultDiffEntry<T>[]\n readonly modified: readonly VaultDiffModifiedEntry<T>[]\n readonly deleted: readonly VaultDiffEntry<T>[]\n /** Only populated when `options.includeUnchanged: true`. */\n readonly unchanged: readonly VaultDiffEntry<T>[] | undefined\n readonly summary: {\n readonly add: number\n readonly modify: number\n readonly delete: number\n readonly total: number\n }\n /**\n * Format the diff as a human-readable string.\n *\n * - `'count'` — one line, just the numbers (`12 added · 3 modified · 0 deleted`)\n * - `'one-line'` — count plus a single overview line\n * - `'full'` — count + one row per added/modified/deleted record (default)\n */\n format(opts?: { detail?: 'count' | 'one-line' | 'full' }): string\n}\n\nexport interface DiffOptions {\n /** Restrict the diff to a subset of collections. */\n readonly collections?: readonly string[]\n /** Field on each record that carries its id. Defaults to `'id'`. */\n readonly idKey?: string\n /** Override the default deep-equal check for \"modified vs unchanged\". */\n readonly compareFn?: (a: unknown, b: unknown) => boolean\n /** If true, include unchanged records in the diff (off by default to save memory). */\n readonly includeUnchanged?: boolean\n}\n\n/**\n * Candidate state to diff the vault against:\n *\n * - A `Vault` instance — both sides are walked via `exportStream()`.\n * - A `Record<collection, records[]>` map — same shape `as-json.toObject()`\n * produces. Useful for diffing parsed file content against the live vault.\n * - A `VaultDump` (output of `vault.dump()`) — a JSON string carrying the\n * full vault state. Parsed and reduced to the map shape above.\n */\nexport type DiffCandidate<T = unknown> =\n | Vault\n | Record<string, readonly T[]>\n | string\n\n// ─── Implementation ────────────────────────────────────────────────────\n\n/**\n * Compute the diff between a live vault and a candidate state.\n *\n * Returns a fully buffered `VaultDiff` — no streaming. Memory cost is\n * O(n + m) in the row count of vault + candidate. For documented\n * 1K-50K-record vaults this is fine; a streaming variant lands as a\n * follow-up if a > 100K-record consumer arrives.\n */\nexport async function diffVault<T = unknown>(\n vault: Vault,\n candidate: DiffCandidate<T>,\n options: DiffOptions = {},\n): Promise<VaultDiff<T>> {\n const idKey = options.idKey ?? 'id'\n const filter = options.collections ? new Set(options.collections) : null\n const compareFn =\n options.compareFn ?? ((a: unknown, b: unknown) => fieldDiff(a, b).length === 0)\n\n // Side A — walk the live vault via exportStream(). Each chunk arrives\n // already decrypted and ACL-scoped, so collections the caller can't\n // read silently drop out. exportStream's records are typed `unknown[]`\n // — diffVault is the type-erasure boundary; the caller asserts the\n // record shape via the function's `<T>` generic.\n const live = new Map<string, Map<string, T>>()\n for await (const chunk of vault.exportStream({ granularity: 'collection' })) {\n if (filter && !filter.has(chunk.collection)) continue\n const collection = live.get(chunk.collection) ?? new Map<string, T>()\n for (const record of chunk.records) {\n const id = readIdField(record, idKey)\n if (!id) continue\n collection.set(id, record as T)\n }\n live.set(chunk.collection, collection)\n }\n\n // Side B — normalise the candidate into the same shape.\n const cand = await normaliseCandidate<T>(candidate, idKey, filter)\n\n // Walk every (collection, id) on either side and bucket.\n const added: VaultDiffEntry<T>[] = []\n const modified: VaultDiffModifiedEntry<T>[] = []\n const deleted: VaultDiffEntry<T>[] = []\n const unchanged: VaultDiffEntry<T>[] | undefined = options.includeUnchanged ? [] : undefined\n\n const collectionNames = new Set([...live.keys(), ...cand.keys()])\n for (const collection of [...collectionNames].sort()) {\n const liveColl = live.get(collection) ?? new Map<string, T>()\n const candColl = cand.get(collection) ?? new Map<string, T>()\n const allIds = new Set([...liveColl.keys(), ...candColl.keys()])\n\n for (const id of [...allIds].sort()) {\n const before = liveColl.get(id)\n const after = candColl.get(id)\n\n if (before === undefined && after !== undefined) {\n added.push({ collection, id, record: after })\n } else if (before !== undefined && after === undefined) {\n deleted.push({ collection, id, record: before })\n } else if (before !== undefined && after !== undefined) {\n if (compareFn(before, after)) {\n unchanged?.push({ collection, id, record: after })\n } else {\n const fieldDiffs = fieldDiff(before, after)\n const fieldsChanged = uniqueTopLevelKeys(fieldDiffs)\n modified.push({\n collection,\n id,\n record: after,\n before,\n fieldsChanged,\n fieldDiffs,\n })\n }\n }\n }\n }\n\n const summary = {\n add: added.length,\n modify: modified.length,\n delete: deleted.length,\n total: added.length + modified.length + deleted.length,\n }\n\n return {\n added,\n modified,\n deleted,\n unchanged,\n summary,\n format(opts) {\n return formatDiff(opts?.detail ?? 'full', { added, modified, deleted, summary })\n },\n }\n}\n\n// ─── Internals ─────────────────────────────────────────────────────────\n\nasync function normaliseCandidate<T>(\n candidate: DiffCandidate<T>,\n idKey: string,\n filter: Set<string> | null,\n): Promise<Map<string, Map<string, T>>> {\n const out = new Map<string, Map<string, T>>()\n\n // Vault instance — duck-type via the exportStream method (matches\n // vault.ts's structural shape without forcing a runtime instanceof check\n // that would import the class and risk circular deps).\n if (\n typeof candidate === 'object' &&\n candidate !== null &&\n 'exportStream' in candidate &&\n typeof (candidate as Vault).exportStream === 'function'\n ) {\n for await (const chunk of (candidate as Vault).exportStream({ granularity: 'collection' })) {\n if (filter && !filter.has(chunk.collection)) continue\n const collection = out.get(chunk.collection) ?? new Map<string, T>()\n for (const record of chunk.records) {\n const id = readIdField(record, idKey)\n if (!id) continue\n collection.set(id, record as T)\n }\n out.set(chunk.collection, collection)\n }\n return out\n }\n\n // String — assume a vault.dump() JSON string. Parse and reduce to the map shape.\n if (typeof candidate === 'string') {\n let parsed: unknown\n try {\n parsed = JSON.parse(candidate)\n } catch (err) {\n throw new Error(\n `diffVault: candidate string is not valid JSON (${(err as Error).message})`,\n )\n }\n return collectionsFromObject<T>(parsed, idKey, filter)\n }\n\n // Plain object — `Record<collection, records[]>` (same shape as-json.toObject() returns).\n return collectionsFromObject<T>(candidate, idKey, filter)\n}\n\nfunction collectionsFromObject<T>(\n raw: unknown,\n idKey: string,\n filter: Set<string> | null,\n): Map<string, Map<string, T>> {\n const out = new Map<string, Map<string, T>>()\n if (raw === null || typeof raw !== 'object') {\n throw new Error('diffVault: candidate must be a Vault, an object, or a JSON string')\n }\n // A vault dump JSON has a top-level shape like { _compartment, _keyring, <coll>: <records[]> }.\n // We accept both: keys starting with `_` are skipped (they're metadata), the rest are collections.\n for (const [key, value] of Object.entries(raw)) {\n if (key.startsWith('_')) continue\n if (filter && !filter.has(key)) continue\n if (!Array.isArray(value)) continue\n const collection = new Map<string, T>()\n for (const record of value as readonly T[]) {\n if (record === null || typeof record !== 'object') continue\n const id = readIdField(record, idKey)\n if (!id) continue\n collection.set(id, record)\n }\n out.set(key, collection)\n }\n return out\n}\n\nfunction uniqueTopLevelKeys(diffs: readonly FieldDiffEntry[]): readonly string[] {\n const keys = new Set<string>()\n for (const d of diffs) {\n // path is dot-separated; the top-level key is everything before the\n // first `.` or `[`. (`a.b.c` → `a`, `tags[0]` → `tags`, `(root)` → `(root)`).\n const m = /^[^.[]+/.exec(d.path)\n if (m) keys.add(m[0])\n }\n return [...keys]\n}\n\n/**\n * Pull the id field off a record without going through `String(obj)`,\n * which would emit `[object Object]` for nested objects and silently\n * collapse rows that share the same parent. Only string and number ids\n * are accepted; anything else returns the empty string and the record\n * is skipped at the call site.\n */\nfunction readIdField(record: unknown, idKey: string): string {\n if (record === null || typeof record !== 'object') return ''\n const v = (record as Record<string, unknown>)[idKey]\n if (typeof v === 'string') return v\n if (typeof v === 'number' && Number.isFinite(v)) return String(v)\n return ''\n}\n\ninterface FormatBuckets<T> {\n readonly added: readonly VaultDiffEntry<T>[]\n readonly modified: readonly VaultDiffModifiedEntry<T>[]\n readonly deleted: readonly VaultDiffEntry<T>[]\n readonly summary: VaultDiff<T>['summary']\n}\n\nfunction formatDiff<T>(\n detail: 'count' | 'one-line' | 'full',\n b: FormatBuckets<T>,\n): string {\n const head = `${b.summary.add} added · ${b.summary.modify} modified · ${b.summary.delete} deleted`\n if (detail === 'count') return head\n if (b.summary.total === 0) return head + '\\n(no changes)'\n if (detail === 'one-line') return head\n\n const rows: string[] = [head, '']\n for (const e of b.added) rows.push(`${e.collection}/${e.id}\\tadded`)\n for (const e of b.modified) {\n const fields = e.fieldDiffs\n .map((f) => `${f.path}: ${shortJSON(f.from)} → ${shortJSON(f.to)}`)\n .join(', ')\n rows.push(`${e.collection}/${e.id}\\tmodified\\t${fields}`)\n }\n for (const e of b.deleted) rows.push(`${e.collection}/${e.id}\\tdeleted`)\n return rows.join('\\n')\n}\n\nfunction shortJSON(value: unknown): string {\n if (value === undefined) return 'undefined'\n const s = JSON.stringify(value)\n // JSON.stringify returns string for any JSON value except `undefined`\n // (handled above), `function`, and `symbol`. Fall back to a static\n // tag for those — never let an arbitrary object hit the default\n // stringifier (which the lint rule explicitly bans).\n if (typeof s !== 'string') return '<unrepresentable>'\n return s.length > 60 ? s.slice(0, 57) + '...' : s\n}\n"],"mappings":"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","names":["formatDiff"]}
|
|
1
|
+
{"version":3,"sources":["../src/schema-update/strategies.ts","../src/schema-update/cutover.ts","../src/vault-diff.ts"],"sourcesContent":["/** Bundled light update strategies. */\nimport { NonAdditiveSchemaChangeError, SchemaLockedError } from '../errors.js'\nimport type { SchemaUpdateStrategy, SchemaDelta } from './types.js'\n\n/** Allow any schema change. Explicit blind / back-compat. */\nexport function blindUpdate(): SchemaUpdateStrategy {\n return { name: 'blindUpdate', onSchemaDelta: () => ({ action: 'allow' }) }\n}\n\n/** Allow additive changes; reject non-additive ones. The safety backstop. */\nexport function additiveOnly(): SchemaUpdateStrategy {\n return {\n name: 'additiveOnly',\n onSchemaDelta(delta: SchemaDelta) {\n if (delta.kind === 'non-additive') {\n return {\n action: 'reject' as const,\n error: new NonAdditiveSchemaChangeError(\n `Non-additive schema change to \"${delta.collection}\" ` +\n `(added: [${delta.added.join(', ')}], removed: [${delta.removed.join(', ')}], ` +\n `changed: [${delta.changed.map(c => c.field).join(', ')}]). ` +\n `Register a coordinatedCutover() strategy to migrate, or revert the change.`,\n ),\n }\n }\n return { action: 'allow' as const }\n },\n }\n}\n\n/**\n * Reject schema changes. With `fields`, reject only when one of those\n * fields is added/removed/changed; otherwise reject any non-`none` delta.\n */\nexport function lockSchema(opts?: { readonly fields?: readonly string[] }): SchemaUpdateStrategy {\n const fields = opts?.fields\n return {\n name: 'lockSchema',\n onSchemaDelta(delta: SchemaDelta) {\n if (delta.kind === 'none') return { action: 'allow' as const }\n const touched = fields\n ? [...delta.added, ...delta.removed, ...delta.changed.map(c => c.field)].filter(f => fields.includes(f))\n : ['<any>']\n if (touched.length === 0) return { action: 'allow' as const }\n return {\n action: 'reject' as const,\n error: new SchemaLockedError(\n `Schema for \"${delta.collection}\" is locked` +\n (fields ? ` on fields [${fields.join(', ')}] (touched: [${touched.join(', ')}])` : '') +\n `; the change was refused.`,\n ),\n }\n },\n }\n}\n","/** The coordinatedCutover update strategy (single-step — no from/to). */\nimport type { SchemaUpdateStrategy, SchemaDelta, TransformFn } from './types.js'\n\nexport function coordinatedCutover(opts: { readonly transform: TransformFn }): SchemaUpdateStrategy {\n return {\n name: 'coordinatedCutover',\n onSchemaDelta(delta: SchemaDelta) {\n if (delta.kind === 'non-additive') {\n return { action: 'cutover' as const, transform: opts.transform }\n }\n return { action: 'allow' as const }\n },\n }\n}\n","/**\n * Vault-level diff orchestrator.\n *\n * Compares a live `Vault`'s plaintext state against a candidate state\n * (another vault, a plain `{ collection: records[] }` map, or a vault\n * dump JSON) and returns a structured `VaultDiff` plan listing the\n * records that would be added, modified, or deleted to bring the live\n * vault into the candidate's shape.\n *\n * Builds on two existing record-level helpers:\n *\n * 1. `diff(a, b)` from `./history/diff.ts` — emits dot-pathed\n * `DiffEntry[]` with `type: 'added' | 'removed' | 'changed'` for\n * each changed field of two records. Used here for the\n * `fieldDiffs` of every `modified` entry, and (with empty result)\n * as the default deep-equal check.\n *\n * 2. `Vault.exportStream()` from `./vault.ts` — the canonical\n * decrypt-and-stream-records iterator. Used to walk both sides\n * when the candidate is itself a `Vault`. ACL-scoped: collections\n * the caller can't read silently drop out, the same way every\n * other plaintext-emitting export pipeline filters them.\n *\n * The new orchestration is the **vault-level** enumeration: bucket\n * each record id into added (only in candidate), deleted (only in\n * vault), or modified (in both with field changes); leave the\n * field-level granularity to the existing `diff()`.\n *\n * Use cases:\n *\n * - Import preview (`@noy-db/as-*` `fromString` returns a plan\n * whose body is a `VaultDiff`).\n * - Backup verification (\"does this `.noydb` bundle from yesterday\n * match the current vault?\").\n * - Two-vault reconciliation (\"what's different between Office A\n * and Office B before we sync?\").\n * - Test assertions (golden-file testing with one-liner\n * `expect(plan.summary).toEqual(...)`).\n *\n * @module\n */\n\nimport type { Vault } from './vault.js'\nimport { diff as fieldDiff, type DiffEntry as FieldDiffEntry } from './history/diff.js'\n\n// ─── Public types ──────────────────────────────────────────────────────\n\n/** Per-record entry shape — added and deleted records carry only the record value. */\nexport interface VaultDiffEntry<T = unknown> {\n readonly collection: string\n readonly id: string\n readonly record: T\n}\n\n/** Modified records carry both halves of the diff plus the field-level breakdown. */\nexport interface VaultDiffModifiedEntry<T = unknown> extends VaultDiffEntry<T> {\n /** The record as it stands in the live vault. */\n readonly before: T\n /** Top-level keys whose values differ between `before` and `record`. */\n readonly fieldsChanged: readonly string[]\n /**\n * Field-level diff entries from `diff(before, record)`. Reuses the\n * existing per-record diff helper so consumers can render git-style\n * `path: from → to` rows without re-walking the records.\n */\n readonly fieldDiffs: readonly FieldDiffEntry[]\n}\n\nexport interface VaultDiff<T = unknown> {\n readonly added: readonly VaultDiffEntry<T>[]\n readonly modified: readonly VaultDiffModifiedEntry<T>[]\n readonly deleted: readonly VaultDiffEntry<T>[]\n /** Only populated when `options.includeUnchanged: true`. */\n readonly unchanged: readonly VaultDiffEntry<T>[] | undefined\n readonly summary: {\n readonly add: number\n readonly modify: number\n readonly delete: number\n readonly total: number\n }\n /**\n * Format the diff as a human-readable string.\n *\n * - `'count'` — one line, just the numbers (`12 added · 3 modified · 0 deleted`)\n * - `'one-line'` — count plus a single overview line\n * - `'full'` — count + one row per added/modified/deleted record (default)\n */\n format(opts?: { detail?: 'count' | 'one-line' | 'full' }): string\n}\n\nexport interface DiffOptions {\n /** Restrict the diff to a subset of collections. */\n readonly collections?: readonly string[]\n /** Field on each record that carries its id. Defaults to `'id'`. */\n readonly idKey?: string\n /** Override the default deep-equal check for \"modified vs unchanged\". */\n readonly compareFn?: (a: unknown, b: unknown) => boolean\n /** If true, include unchanged records in the diff (off by default to save memory). */\n readonly includeUnchanged?: boolean\n}\n\n/**\n * Candidate state to diff the vault against:\n *\n * - A `Vault` instance — both sides are walked via `exportStream()`.\n * - A `Record<collection, records[]>` map — same shape `as-json.toObject()`\n * produces. Useful for diffing parsed file content against the live vault.\n * - A `VaultDump` (output of `vault.dump()`) — a JSON string carrying the\n * full vault state. Parsed and reduced to the map shape above.\n */\nexport type DiffCandidate<T = unknown> =\n | Vault\n | Record<string, readonly T[]>\n | string\n\n// ─── Implementation ────────────────────────────────────────────────────\n\n/**\n * Compute the diff between a live vault and a candidate state.\n *\n * Returns a fully buffered `VaultDiff` — no streaming. Memory cost is\n * O(n + m) in the row count of vault + candidate. For documented\n * 1K-50K-record vaults this is fine; a streaming variant lands as a\n * follow-up if a > 100K-record consumer arrives.\n */\nexport async function diffVault<T = unknown>(\n vault: Vault,\n candidate: DiffCandidate<T>,\n options: DiffOptions = {},\n): Promise<VaultDiff<T>> {\n const idKey = options.idKey ?? 'id'\n const filter = options.collections ? new Set(options.collections) : null\n const compareFn =\n options.compareFn ?? ((a: unknown, b: unknown) => fieldDiff(a, b).length === 0)\n\n // Side A — walk the live vault via exportStream(). Each chunk arrives\n // already decrypted and ACL-scoped, so collections the caller can't\n // read silently drop out. exportStream's records are typed `unknown[]`\n // — diffVault is the type-erasure boundary; the caller asserts the\n // record shape via the function's `<T>` generic.\n const live = new Map<string, Map<string, T>>()\n for await (const chunk of vault.exportStream({ granularity: 'collection' })) {\n if (filter && !filter.has(chunk.collection)) continue\n const collection = live.get(chunk.collection) ?? new Map<string, T>()\n for (const record of chunk.records) {\n const id = readIdField(record, idKey)\n if (!id) continue\n collection.set(id, record as T)\n }\n live.set(chunk.collection, collection)\n }\n\n // Side B — normalise the candidate into the same shape.\n const cand = await normaliseCandidate<T>(candidate, idKey, filter)\n\n // Walk every (collection, id) on either side and bucket.\n const added: VaultDiffEntry<T>[] = []\n const modified: VaultDiffModifiedEntry<T>[] = []\n const deleted: VaultDiffEntry<T>[] = []\n const unchanged: VaultDiffEntry<T>[] | undefined = options.includeUnchanged ? [] : undefined\n\n const collectionNames = new Set([...live.keys(), ...cand.keys()])\n for (const collection of [...collectionNames].sort()) {\n const liveColl = live.get(collection) ?? new Map<string, T>()\n const candColl = cand.get(collection) ?? new Map<string, T>()\n const allIds = new Set([...liveColl.keys(), ...candColl.keys()])\n\n for (const id of [...allIds].sort()) {\n const before = liveColl.get(id)\n const after = candColl.get(id)\n\n if (before === undefined && after !== undefined) {\n added.push({ collection, id, record: after })\n } else if (before !== undefined && after === undefined) {\n deleted.push({ collection, id, record: before })\n } else if (before !== undefined && after !== undefined) {\n if (compareFn(before, after)) {\n unchanged?.push({ collection, id, record: after })\n } else {\n const fieldDiffs = fieldDiff(before, after)\n const fieldsChanged = uniqueTopLevelKeys(fieldDiffs)\n modified.push({\n collection,\n id,\n record: after,\n before,\n fieldsChanged,\n fieldDiffs,\n })\n }\n }\n }\n }\n\n const summary = {\n add: added.length,\n modify: modified.length,\n delete: deleted.length,\n total: added.length + modified.length + deleted.length,\n }\n\n return {\n added,\n modified,\n deleted,\n unchanged,\n summary,\n format(opts) {\n return formatDiff(opts?.detail ?? 'full', { added, modified, deleted, summary })\n },\n }\n}\n\n// ─── Internals ─────────────────────────────────────────────────────────\n\nasync function normaliseCandidate<T>(\n candidate: DiffCandidate<T>,\n idKey: string,\n filter: Set<string> | null,\n): Promise<Map<string, Map<string, T>>> {\n const out = new Map<string, Map<string, T>>()\n\n // Vault instance — duck-type via the exportStream method (matches\n // vault.ts's structural shape without forcing a runtime instanceof check\n // that would import the class and risk circular deps).\n if (\n typeof candidate === 'object' &&\n candidate !== null &&\n 'exportStream' in candidate &&\n typeof (candidate as Vault).exportStream === 'function'\n ) {\n for await (const chunk of (candidate as Vault).exportStream({ granularity: 'collection' })) {\n if (filter && !filter.has(chunk.collection)) continue\n const collection = out.get(chunk.collection) ?? new Map<string, T>()\n for (const record of chunk.records) {\n const id = readIdField(record, idKey)\n if (!id) continue\n collection.set(id, record as T)\n }\n out.set(chunk.collection, collection)\n }\n return out\n }\n\n // String — assume a vault.dump() JSON string. Parse and reduce to the map shape.\n if (typeof candidate === 'string') {\n let parsed: unknown\n try {\n parsed = JSON.parse(candidate)\n } catch (err) {\n throw new Error(\n `diffVault: candidate string is not valid JSON (${(err as Error).message})`,\n )\n }\n return collectionsFromObject<T>(parsed, idKey, filter)\n }\n\n // Plain object — `Record<collection, records[]>` (same shape as-json.toObject() returns).\n return collectionsFromObject<T>(candidate, idKey, filter)\n}\n\nfunction collectionsFromObject<T>(\n raw: unknown,\n idKey: string,\n filter: Set<string> | null,\n): Map<string, Map<string, T>> {\n const out = new Map<string, Map<string, T>>()\n if (raw === null || typeof raw !== 'object') {\n throw new Error('diffVault: candidate must be a Vault, an object, or a JSON string')\n }\n // A vault dump JSON has a top-level shape like { _compartment, _keyring, <coll>: <records[]> }.\n // We accept both: keys starting with `_` are skipped (they're metadata), the rest are collections.\n for (const [key, value] of Object.entries(raw)) {\n if (key.startsWith('_')) continue\n if (filter && !filter.has(key)) continue\n if (!Array.isArray(value)) continue\n const collection = new Map<string, T>()\n for (const record of value as readonly T[]) {\n if (record === null || typeof record !== 'object') continue\n const id = readIdField(record, idKey)\n if (!id) continue\n collection.set(id, record)\n }\n out.set(key, collection)\n }\n return out\n}\n\nfunction uniqueTopLevelKeys(diffs: readonly FieldDiffEntry[]): readonly string[] {\n const keys = new Set<string>()\n for (const d of diffs) {\n // path is dot-separated; the top-level key is everything before the\n // first `.` or `[`. (`a.b.c` → `a`, `tags[0]` → `tags`, `(root)` → `(root)`).\n const m = /^[^.[]+/.exec(d.path)\n if (m) keys.add(m[0])\n }\n return [...keys]\n}\n\n/**\n * Pull the id field off a record without going through `String(obj)`,\n * which would emit `[object Object]` for nested objects and silently\n * collapse rows that share the same parent. Only string and number ids\n * are accepted; anything else returns the empty string and the record\n * is skipped at the call site.\n */\nfunction readIdField(record: unknown, idKey: string): string {\n if (record === null || typeof record !== 'object') return ''\n const v = (record as Record<string, unknown>)[idKey]\n if (typeof v === 'string') return v\n if (typeof v === 'number' && Number.isFinite(v)) return String(v)\n return ''\n}\n\ninterface FormatBuckets<T> {\n readonly added: readonly VaultDiffEntry<T>[]\n readonly modified: readonly VaultDiffModifiedEntry<T>[]\n readonly deleted: readonly VaultDiffEntry<T>[]\n readonly summary: VaultDiff<T>['summary']\n}\n\nfunction formatDiff<T>(\n detail: 'count' | 'one-line' | 'full',\n b: FormatBuckets<T>,\n): string {\n const head = `${b.summary.add} added · ${b.summary.modify} modified · ${b.summary.delete} deleted`\n if (detail === 'count') return head\n if (b.summary.total === 0) return head + '\\n(no changes)'\n if (detail === 'one-line') return head\n\n const rows: string[] = [head, '']\n for (const e of b.added) rows.push(`${e.collection}/${e.id}\\tadded`)\n for (const e of b.modified) {\n const fields = e.fieldDiffs\n .map((f) => `${f.path}: ${shortJSON(f.from)} → ${shortJSON(f.to)}`)\n .join(', ')\n rows.push(`${e.collection}/${e.id}\\tmodified\\t${fields}`)\n }\n for (const e of b.deleted) rows.push(`${e.collection}/${e.id}\\tdeleted`)\n return rows.join('\\n')\n}\n\nfunction shortJSON(value: unknown): string {\n if (value === undefined) return 'undefined'\n const s = JSON.stringify(value)\n // JSON.stringify returns string for any JSON value except `undefined`\n // (handled above), `function`, and `symbol`. Fall back to a static\n // tag for those — never let an arbitrary object hit the default\n // stringifier (which the lint rule explicitly bans).\n if (typeof s !== 'string') return '<unrepresentable>'\n return s.length > 60 ? s.slice(0, 57) + '...' : s\n}\n"],"mappings":"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","names":["formatDiff"]}
|