@noy-db/hub 0.2.0-pre.1 → 0.2.0-pre.10
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.cjs +9 -0
- 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 +4 -4
- package/dist/attestation/index.cjs +305 -0
- package/dist/attestation/index.cjs.map +1 -0
- package/dist/attestation/index.d.cts +52 -0
- package/dist/attestation/index.d.ts +52 -0
- package/dist/attestation/index.js +36 -0
- package/dist/attestation/index.js.map +1 -0
- package/dist/blobs/index.cjs.map +1 -1
- package/dist/blobs/index.d.cts +7 -6
- package/dist/blobs/index.d.ts +7 -6
- package/dist/blobs/index.js +10 -8
- package/dist/blobs/index.js.map +1 -1
- package/dist/bundle/index.cjs +18899 -129
- package/dist/bundle/index.cjs.map +1 -1
- package/dist/bundle/index.d.cts +175 -6
- package/dist/bundle/index.d.ts +175 -6
- package/dist/bundle/index.js +533 -5
- package/dist/bundle/index.js.map +1 -1
- package/dist/{chunk-6HPZY4ON.js → chunk-26NK23DZ.js} +9 -4
- package/dist/chunk-26NK23DZ.js.map +1 -0
- package/dist/{chunk-XGSOTWYX.js → chunk-2LPPNWF6.js} +3 -3
- package/dist/{chunk-5SCJ5UEF.js → chunk-2N62W5YP.js} +3 -3
- package/dist/{chunk-537VFZTR.js → chunk-3LPV6BXR.js} +4 -4
- package/dist/{chunk-UA4RI7OT.js → chunk-4CLICFEY.js} +5 -5
- package/dist/chunk-4CLICFEY.js.map +1 -0
- package/dist/chunk-4USCAEDT.js +10529 -0
- package/dist/chunk-4USCAEDT.js.map +1 -0
- package/dist/chunk-5IXJGFF2.js +83 -0
- package/dist/chunk-5IXJGFF2.js.map +1 -0
- package/dist/{chunk-HB3Z2GCR.js → chunk-5OEJ6GOT.js} +2 -2
- package/dist/chunk-5OEJ6GOT.js.map +1 -0
- package/dist/chunk-5OX6XVNS.js +79 -0
- package/dist/chunk-5OX6XVNS.js.map +1 -0
- package/dist/{chunk-VMIO4IXG.js → chunk-6EOXTJS2.js} +6 -229
- package/dist/chunk-6EOXTJS2.js.map +1 -0
- package/dist/{chunk-UZXLQCHP.js → chunk-6T2UDBKG.js} +2 -2
- package/dist/chunk-6T2UDBKG.js.map +1 -0
- package/dist/{chunk-23TTQXVO.js → chunk-6YLPHBKR.js} +214 -9
- package/dist/chunk-6YLPHBKR.js.map +1 -0
- package/dist/{chunk-Z72JH4KG.js → chunk-7CEGU63S.js} +5 -35
- package/dist/chunk-7CEGU63S.js.map +1 -0
- package/dist/{chunk-PEULZC6M.js → chunk-A3JMGXPG.js} +8 -1
- package/dist/chunk-A3JMGXPG.js.map +1 -0
- package/dist/{chunk-7H6DOO3E.js → chunk-BB27JMWB.js} +211 -36
- package/dist/chunk-BB27JMWB.js.map +1 -0
- package/dist/{chunk-I6MX32UC.js → chunk-BDV7INMP.js} +4 -4
- package/dist/{chunk-MKSA2V7A.js → chunk-C3WE6UJY.js} +2 -2
- package/dist/{chunk-FCXOFQAJ.js → chunk-CH22FZHT.js} +19 -2
- package/dist/chunk-CH22FZHT.js.map +1 -0
- package/dist/{chunk-DYBQG5PQ.js → chunk-CXFOITNS.js} +2 -2
- package/dist/{chunk-5ZGZ6HIZ.js → chunk-CXJG63MA.js} +11 -2
- package/dist/chunk-CXJG63MA.js.map +1 -0
- package/dist/{chunk-EGQYGYIU.js → chunk-DAP2XL7Q.js} +3 -3
- package/dist/chunk-DAP2XL7Q.js.map +1 -0
- package/dist/{chunk-4TFSM22V.js → chunk-DJRWA3Q5.js} +4 -4
- package/dist/chunk-DRXIZOFV.js +233 -0
- package/dist/chunk-DRXIZOFV.js.map +1 -0
- package/dist/{chunk-DPMFBCV6.js → chunk-FO3UEG4S.js} +20 -3
- package/dist/chunk-FO3UEG4S.js.map +1 -0
- package/dist/{chunk-SIZWEV2Y.js → chunk-GAUEWM7D.js} +7 -5
- package/dist/chunk-GAUEWM7D.js.map +1 -0
- package/dist/{chunk-NIOHFJPJ.js → chunk-GNHAC43Q.js} +218 -119
- package/dist/chunk-GNHAC43Q.js.map +1 -0
- package/dist/chunk-HHOO7HGH.js +57 -0
- package/dist/chunk-HHOO7HGH.js.map +1 -0
- package/dist/{chunk-PA6R5ZCI.js → chunk-HQSQC2XL.js} +5 -5
- package/dist/chunk-HQSQC2XL.js.map +1 -0
- package/dist/chunk-IMYKDWB4.js +139 -0
- package/dist/chunk-IMYKDWB4.js.map +1 -0
- package/dist/{chunk-5DWL3JBF.js → chunk-LSTBFLL2.js} +2 -2
- package/dist/{chunk-ADQ5MQ54.js → chunk-O6EJ6WTI.js} +163 -2
- package/dist/chunk-O6EJ6WTI.js.map +1 -0
- package/dist/{chunk-OMLIZL2P.js → chunk-PC6ZEDRL.js} +12 -2
- package/dist/{chunk-OMLIZL2P.js.map → chunk-PC6ZEDRL.js.map} +1 -1
- package/dist/chunk-PM3QYWUU.js +251 -0
- package/dist/chunk-PM3QYWUU.js.map +1 -0
- package/dist/{chunk-34YSDCDP.js → chunk-PVUUIWHY.js} +2 -2
- package/dist/{chunk-CBAHB2BF.js → chunk-PXTQPZO4.js} +7 -70
- package/dist/chunk-PXTQPZO4.js.map +1 -0
- package/dist/{chunk-DYECX3IX.js → chunk-QSOYKKMD.js} +4 -4
- package/dist/chunk-QSOYKKMD.js.map +1 -0
- package/dist/{chunk-WCA2NROQ.js → chunk-R233SLY3.js} +2 -2
- package/dist/chunk-RC6SU5NO.js +36 -0
- package/dist/chunk-RC6SU5NO.js.map +1 -0
- package/dist/{chunk-P7EQ2S5O.js → chunk-RRNA5GKT.js} +2 -2
- package/dist/{chunk-ZNOEIM6Y.js → chunk-RYIL3PI2.js} +2 -2
- package/dist/chunk-STNPB3UM.js +9 -0
- package/dist/chunk-STNPB3UM.js.map +1 -0
- package/dist/{chunk-MRIBLZL3.js → chunk-TV3YZ35S.js} +5 -1
- package/dist/chunk-TV3YZ35S.js.map +1 -0
- package/dist/chunk-TY32C732.js +59 -0
- package/dist/chunk-TY32C732.js.map +1 -0
- package/dist/{chunk-YMYK7US4.js → chunk-WIBHRONM.js} +2 -2
- package/dist/chunk-WIBHRONM.js.map +1 -0
- package/dist/{chunk-YS3POABP.js → chunk-WIRRPTFH.js} +1 -1
- package/dist/chunk-WIRRPTFH.js.map +1 -0
- package/dist/{chunk-KESP7GOK.js → chunk-Y26YV5R3.js} +3 -3
- package/dist/{chunk-MIQHZESA.js → chunk-YM7LFCG7.js} +5 -5
- package/dist/{chunk-MIQHZESA.js.map → chunk-YM7LFCG7.js.map} +1 -1
- package/dist/{chunk-2AXFIYHT.js → chunk-Z6FNBOTC.js} +1 -1
- package/dist/chunk-Z6FNBOTC.js.map +1 -0
- package/dist/{chunk-RD5LYKD6.js → chunk-ZROPXHJY.js} +2 -2
- package/dist/chunk-ZROPXHJY.js.map +1 -0
- package/dist/consent/index.cjs.map +1 -1
- package/dist/consent/index.d.cts +7 -6
- package/dist/consent/index.d.ts +7 -6
- package/dist/consent/index.js +3 -3
- package/dist/{crypto-A7FRXYHC.js → crypto-2CRLG4F4.js} +3 -3
- package/dist/{delegation-YBA4X4JN.js → delegation-ZTRT2PRV.js} +5 -5
- package/dist/derivations/index.cjs +18 -1
- package/dist/derivations/index.cjs.map +1 -1
- package/dist/derivations/index.d.cts +10 -9
- package/dist/derivations/index.d.ts +10 -9
- package/dist/derivations/index.js +4 -4
- package/dist/{dev-unlock-DRwVSy2S.d.cts → dev-unlock-AglVnkPY.d.cts} +1 -1
- package/dist/{dev-unlock-D9s-loPr.d.ts → dev-unlock-BOEYl1xl.d.ts} +1 -1
- package/dist/discriminant-BN9REW3o.d.cts +60 -0
- package/dist/discriminant-BN9REW3o.d.ts +60 -0
- package/dist/executor-S76VN45G.js +8 -0
- package/dist/executor-UCXLIGLW.js +11 -0
- package/dist/executor-ZCNZJMGR.js +8 -0
- package/dist/{fanout-sidecar-VJ52RIEY.js → fanout-sidecar-OKPMMPLG.js} +2 -2
- package/dist/fanout-sidecar-OKPMMPLG.js.map +1 -0
- package/dist/guards/index.cjs +7 -0
- package/dist/guards/index.cjs.map +1 -1
- package/dist/guards/index.d.cts +8 -7
- package/dist/guards/index.d.ts +8 -7
- package/dist/guards/index.js +4 -4
- package/dist/{hash-DXXXusyk.d.ts → hash-B9m3_fhj.d.ts} +1 -1
- package/dist/{hash-DtRih9MQ.d.cts → hash-RVqz2zi8.d.cts} +1 -1
- package/dist/history/index.cjs +2 -2
- package/dist/history/index.cjs.map +1 -1
- package/dist/history/index.d.cts +8 -7
- package/dist/history/index.d.ts +8 -7
- package/dist/history/index.js +6 -6
- package/dist/i18n/index.cjs +287 -27
- package/dist/i18n/index.cjs.map +1 -1
- package/dist/i18n/index.d.cts +7 -6
- package/dist/i18n/index.d.ts +7 -6
- package/dist/i18n/index.js +21 -6
- package/dist/i18n/index.js.map +1 -1
- package/dist/{index-CmVgTkqk.d.cts → index-B8bjExET.d.cts} +214 -18
- package/dist/{index-CNwA-B6-.d.ts → index-DfUbNad8.d.ts} +214 -18
- package/dist/index.cjs +3329 -446
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +43 -22
- package/dist/index.d.ts +43 -22
- package/dist/index.js +179 -8799
- package/dist/index.js.map +1 -1
- package/dist/indexing/index.cjs +5 -1
- package/dist/indexing/index.cjs.map +1 -1
- package/dist/indexing/index.d.cts +3 -3
- package/dist/indexing/index.d.ts +3 -3
- package/dist/indexing/index.js +4 -4
- package/dist/issue-3W6IVLKH.js +12 -0
- package/dist/{lazy-builder-Rpd-V3jP.d.ts → lazy-builder-Ci5_YG73.d.cts} +2 -2
- package/dist/{lazy-builder-C-rPfWG0.d.cts → lazy-builder-D5GU14TS.d.ts} +2 -2
- package/dist/{ledger-3TXNP47J.js → ledger-O7FXOG3D.js} +6 -6
- package/dist/materialized-views/index.cjs +21 -2
- package/dist/materialized-views/index.cjs.map +1 -1
- package/dist/materialized-views/index.d.cts +23 -20
- package/dist/materialized-views/index.d.ts +23 -20
- package/dist/materialized-views/index.js +12 -12
- package/dist/noydb-YAZNH5TI.js +34 -0
- package/dist/overlay-views/index.cjs +11 -1
- package/dist/overlay-views/index.cjs.map +1 -1
- package/dist/overlay-views/index.d.cts +10 -9
- package/dist/overlay-views/index.d.ts +10 -9
- package/dist/overlay-views/index.js +6 -4
- package/dist/periods/index.cjs.map +1 -1
- package/dist/periods/index.d.cts +7 -6
- package/dist/periods/index.d.ts +7 -6
- package/dist/periods/index.js +6 -6
- package/dist/{predicate-Dnu81tsS.d.cts → predicate-Bt5ft-9c.d.cts} +28 -3
- package/dist/{predicate-Dnu81tsS.d.ts → predicate-Bt5ft-9c.d.ts} +28 -3
- package/dist/{public-envelope-PY6NKFLI.js → public-envelope-HMYHZIRH.js} +4 -4
- package/dist/query/index.cjs +255 -6
- package/dist/query/index.cjs.map +1 -1
- package/dist/query/index.d.cts +3 -3
- package/dist/query/index.d.ts +3 -3
- package/dist/query/index.js +12 -6
- package/dist/registry-DKEXOJVO.js +7 -0
- package/dist/{registry-3L3N3PTG.js → registry-ST2VNFZC.js} +3 -3
- package/dist/registry-UFIK7CSR.js +8 -0
- package/dist/registry-ZGYYSM5I.js +8 -0
- package/dist/registry-ZGYYSM5I.js.map +1 -0
- package/dist/revoke-S6JMSLUN.js +17 -0
- package/dist/revoke-S6JMSLUN.js.map +1 -0
- package/dist/session/index.cjs.map +1 -1
- package/dist/session/index.d.cts +8 -7
- package/dist/session/index.d.ts +8 -7
- package/dist/session/index.js +3 -3
- package/dist/shadow/index.cjs.map +1 -1
- package/dist/shadow/index.d.cts +7 -6
- package/dist/shadow/index.d.ts +7 -6
- package/dist/shadow/index.js +2 -2
- package/dist/signer-7NPTB3SQ.js +18 -0
- package/dist/signer-7NPTB3SQ.js.map +1 -0
- package/dist/snapshots/index.cjs +937 -0
- package/dist/snapshots/index.cjs.map +1 -0
- package/dist/snapshots/index.d.cts +28 -0
- package/dist/snapshots/index.d.ts +28 -0
- package/dist/snapshots/index.js +152 -0
- package/dist/snapshots/index.js.map +1 -0
- package/dist/{stale-HSC5YO2O.js → stale-VKXSXJF4.js} +2 -2
- package/dist/stale-VKXSXJF4.js.map +1 -0
- package/dist/store/index.cjs.map +1 -1
- package/dist/store/index.d.cts +7 -6
- package/dist/store/index.d.ts +7 -6
- package/dist/store/index.js +2 -2
- package/dist/{strategy-DSTrsZ8t.d.cts → strategy-CT2LCKAX.d.cts} +12 -0
- package/dist/{strategy-DSTrsZ8t.d.ts → strategy-CT2LCKAX.d.ts} +12 -0
- package/dist/sync/index.cjs.map +1 -1
- package/dist/sync/index.d.cts +6 -5
- package/dist/sync/index.d.ts +6 -5
- package/dist/sync/index.js +4 -4
- package/dist/team/index.cjs +1 -1
- package/dist/team/index.cjs.map +1 -1
- package/dist/team/index.d.cts +7 -6
- package/dist/team/index.d.ts +7 -6
- package/dist/team/index.js +13 -11
- package/dist/tx/index.cjs +82 -2
- package/dist/tx/index.cjs.map +1 -1
- package/dist/tx/index.d.cts +8 -7
- package/dist/tx/index.d.ts +8 -7
- package/dist/tx/index.js +56 -3
- package/dist/tx/index.js.map +1 -1
- package/dist/{types-DW9RGSSs.d.ts → types-CaNQm4i8.d.ts} +1270 -259
- package/dist/{types-C4lwMKKF.d.cts → types-n2_IfwlQ.d.cts} +1270 -259
- package/dist/{index-4agOpzqd.d.ts → ulid-B9SMWj5i.d.ts} +64 -46
- package/dist/{index-hdFvZkBP.d.cts → ulid-CLMjmyhG.d.cts} +64 -46
- package/dist/util/index.cjs +7 -0
- package/dist/util/index.cjs.map +1 -1
- package/dist/util/index.d.cts +2 -0
- package/dist/util/index.d.ts +2 -0
- package/dist/util/index.js +5 -1
- package/dist/util/index.js.map +1 -1
- package/dist/{with-derivation-g-pGoMzL.d.ts → with-derivation-CVIOPTUf.d.ts} +1 -1
- package/dist/{with-derivation-C8LDlV7t.d.cts → with-derivation-aKrtS7Jj.d.cts} +1 -1
- package/dist/{with-guard-jI1x9Z3k.d.cts → with-guard-DZQbPzoP.d.cts} +1 -1
- package/dist/{with-guard-DWOCK4Ca.d.ts → with-guard-DseETUrF.d.ts} +1 -1
- package/dist/{with-materialized-view-DaKR-N6J.d.ts → with-materialized-view-C1eA1_T_.d.cts} +2 -2
- package/dist/{with-materialized-view-DcTx4H3j.d.cts → with-materialized-view-DaYaE8-Q.d.ts} +2 -2
- package/dist/{with-overlayed-view-N7jYuNOS.d.ts → with-overlayed-view-DQsh2p8H.d.ts} +2 -2
- package/dist/{with-overlayed-view-D-6oWAgM.d.cts → with-overlayed-view-DleJfKcV.d.cts} +2 -2
- package/package.json +27 -4
- package/dist/chunk-23TTQXVO.js.map +0 -1
- package/dist/chunk-2AXFIYHT.js.map +0 -1
- package/dist/chunk-5ZGZ6HIZ.js.map +0 -1
- package/dist/chunk-6HPZY4ON.js.map +0 -1
- package/dist/chunk-7H6DOO3E.js.map +0 -1
- package/dist/chunk-ADQ5MQ54.js.map +0 -1
- package/dist/chunk-CBAHB2BF.js.map +0 -1
- package/dist/chunk-DPMFBCV6.js.map +0 -1
- package/dist/chunk-DYECX3IX.js.map +0 -1
- package/dist/chunk-EGQYGYIU.js.map +0 -1
- package/dist/chunk-FCXOFQAJ.js.map +0 -1
- package/dist/chunk-HB3Z2GCR.js.map +0 -1
- package/dist/chunk-MRIBLZL3.js.map +0 -1
- package/dist/chunk-NIOHFJPJ.js.map +0 -1
- package/dist/chunk-PA6R5ZCI.js.map +0 -1
- package/dist/chunk-PEULZC6M.js.map +0 -1
- package/dist/chunk-RD5LYKD6.js.map +0 -1
- package/dist/chunk-SIZWEV2Y.js.map +0 -1
- package/dist/chunk-UA4RI7OT.js.map +0 -1
- package/dist/chunk-UZXLQCHP.js.map +0 -1
- package/dist/chunk-VMIO4IXG.js.map +0 -1
- package/dist/chunk-YMYK7US4.js.map +0 -1
- package/dist/chunk-YS3POABP.js.map +0 -1
- package/dist/chunk-Z72JH4KG.js.map +0 -1
- package/dist/executor-7E3VFGW7.js +0 -11
- package/dist/executor-CEWX2FQI.js +0 -8
- package/dist/executor-X4SQ3ZLC.js +0 -8
- package/dist/fanout-sidecar-VJ52RIEY.js.map +0 -1
- package/dist/registry-O47PUPSY.js +0 -8
- package/dist/registry-RFGGMVNJ.js +0 -7
- package/dist/registry-WLLMODKN.js +0 -8
- /package/dist/{chunk-XGSOTWYX.js.map → chunk-2LPPNWF6.js.map} +0 -0
- /package/dist/{chunk-5SCJ5UEF.js.map → chunk-2N62W5YP.js.map} +0 -0
- /package/dist/{chunk-537VFZTR.js.map → chunk-3LPV6BXR.js.map} +0 -0
- /package/dist/{chunk-I6MX32UC.js.map → chunk-BDV7INMP.js.map} +0 -0
- /package/dist/{chunk-MKSA2V7A.js.map → chunk-C3WE6UJY.js.map} +0 -0
- /package/dist/{chunk-DYBQG5PQ.js.map → chunk-CXFOITNS.js.map} +0 -0
- /package/dist/{chunk-4TFSM22V.js.map → chunk-DJRWA3Q5.js.map} +0 -0
- /package/dist/{chunk-5DWL3JBF.js.map → chunk-LSTBFLL2.js.map} +0 -0
- /package/dist/{chunk-34YSDCDP.js.map → chunk-PVUUIWHY.js.map} +0 -0
- /package/dist/{chunk-WCA2NROQ.js.map → chunk-R233SLY3.js.map} +0 -0
- /package/dist/{chunk-P7EQ2S5O.js.map → chunk-RRNA5GKT.js.map} +0 -0
- /package/dist/{chunk-ZNOEIM6Y.js.map → chunk-RYIL3PI2.js.map} +0 -0
- /package/dist/{chunk-KESP7GOK.js.map → chunk-Y26YV5R3.js.map} +0 -0
- /package/dist/{crypto-A7FRXYHC.js.map → crypto-2CRLG4F4.js.map} +0 -0
- /package/dist/{delegation-YBA4X4JN.js.map → delegation-ZTRT2PRV.js.map} +0 -0
- /package/dist/{executor-7E3VFGW7.js.map → executor-S76VN45G.js.map} +0 -0
- /package/dist/{executor-CEWX2FQI.js.map → executor-UCXLIGLW.js.map} +0 -0
- /package/dist/{executor-X4SQ3ZLC.js.map → executor-ZCNZJMGR.js.map} +0 -0
- /package/dist/{ledger-3TXNP47J.js.map → issue-3W6IVLKH.js.map} +0 -0
- /package/dist/{public-envelope-PY6NKFLI.js.map → ledger-O7FXOG3D.js.map} +0 -0
- /package/dist/{registry-3L3N3PTG.js.map → noydb-YAZNH5TI.js.map} +0 -0
- /package/dist/{registry-O47PUPSY.js.map → public-envelope-HMYHZIRH.js.map} +0 -0
- /package/dist/{registry-RFGGMVNJ.js.map → registry-DKEXOJVO.js.map} +0 -0
- /package/dist/{registry-WLLMODKN.js.map → registry-ST2VNFZC.js.map} +0 -0
- /package/dist/{stale-HSC5YO2O.js.map → registry-UFIK7CSR.js.map} +0 -0
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { I as IndexStrategy, d as LazyQuery } from './lazy-builder-
|
|
2
|
-
import { b as AggregateSpec, A as AggregateStrategy } from './strategy-
|
|
1
|
+
import { I as IndexStrategy, d as LazyQuery } from './lazy-builder-Ci5_YG73.cjs';
|
|
2
|
+
import { b as AggregateSpec, A as AggregateStrategy } from './strategy-CT2LCKAX.cjs';
|
|
3
3
|
import { C as CrdtStrategy, a as CrdtMode, b as CrdtState } from './strategy-BSxFXGzb.cjs';
|
|
4
|
-
import { N as NoydbError, Q as Query,
|
|
5
|
-
import { F as FieldClause, I as IndexDef, C as CollectionIndexes } from './predicate-
|
|
4
|
+
import { N as NoydbError, Q as Query, aw as RefRegistry, at as RefDescriptor, a7 as JoinableSource, ay as RefViolation, az as ScanBuilder } from './index-B8bjExET.cjs';
|
|
5
|
+
import { F as FieldClause, I as IndexDef, C as CollectionIndexes } from './predicate-Bt5ft-9c.cjs';
|
|
6
|
+
import { AttestationFieldSchema, RevocationList } from '@noy-db/attestation';
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* Standard Schema v1 integration.
|
|
@@ -794,8 +795,15 @@ interface LedgerEntry {
|
|
|
794
795
|
* guards subsystem when an admin/owner uses `withTransactions(...)`
|
|
795
796
|
* to repair a constraint-violating state. See `amendment` field
|
|
796
797
|
* below for the structured payload.
|
|
798
|
+
*
|
|
799
|
+
* `'lifecycle'` records a non-data audit event (e.g. partition
|
|
800
|
+
* handover) — `collection`/`id` are empty and the event detail
|
|
801
|
+
* lives in `reason` (e.g. `'partition-handed-over:<sealId>'`). Like
|
|
802
|
+
* `amendment`, it carries no data envelope, so `verifyBackupIntegrity`
|
|
803
|
+
* skips it in the data cross-check (it still participates in the
|
|
804
|
+
* tamper-evident chain).
|
|
797
805
|
*/
|
|
798
|
-
readonly op: 'put' | 'delete' | 'amendment';
|
|
806
|
+
readonly op: 'put' | 'delete' | 'amendment' | 'lifecycle' | 'migration';
|
|
799
807
|
/** The collection the mutation targeted. */
|
|
800
808
|
readonly collection: string;
|
|
801
809
|
/** The record id the mutation targeted. */
|
|
@@ -820,8 +828,8 @@ interface LedgerEntry {
|
|
|
820
828
|
*/
|
|
821
829
|
readonly payloadHash: string;
|
|
822
830
|
/**
|
|
823
|
-
* Optional human-readable tag describing why this mutation happened
|
|
824
|
-
*
|
|
831
|
+
* Optional human-readable tag describing why this mutation happened.
|
|
832
|
+
* Threaded through `collection.put(_, _, { reason })`. Common
|
|
825
833
|
* values include `'import:csv'`, `'import:json'`, `'import:xlsx'` from
|
|
826
834
|
* `as-*` ImportPlan.apply(), but consumers can use any string for
|
|
827
835
|
* domain-specific audit filtering. Auto-strip via `canonicalJson` —
|
|
@@ -1098,8 +1106,8 @@ interface AppendInput {
|
|
|
1098
1106
|
*/
|
|
1099
1107
|
amendment?: LedgerEntry['amendment'];
|
|
1100
1108
|
/**
|
|
1101
|
-
* Optional human-readable tag describing why this mutation happened
|
|
1102
|
-
*
|
|
1109
|
+
* Optional human-readable tag describing why this mutation happened.
|
|
1110
|
+
* Threaded from `collection.put(_, _, { reason })`.
|
|
1103
1111
|
* Carried verbatim onto the resulting ledger entry's `reason` field;
|
|
1104
1112
|
* omitted from canonical JSON when undefined.
|
|
1105
1113
|
*/
|
|
@@ -1636,6 +1644,51 @@ interface PeriodsStrategy {
|
|
|
1636
1644
|
appendPeriodLedgerEntry(ledger: LedgerStore | null, actor: string, envelope: EncryptedEnvelope, periodName: string): Promise<void>;
|
|
1637
1645
|
}
|
|
1638
1646
|
|
|
1647
|
+
/**
|
|
1648
|
+
* Per-layer i18n resolution policy.
|
|
1649
|
+
*
|
|
1650
|
+
* `onMissing` governs what happens when a multilingual field is resolved
|
|
1651
|
+
* to a target locale that is absent. It may be a single scalar policy or
|
|
1652
|
+
* a per-layer map, so a field can be lenient at the app read boundary but
|
|
1653
|
+
* strict inside a materialized view.
|
|
1654
|
+
*
|
|
1655
|
+
* Effective policy for layer `λ`:
|
|
1656
|
+
*
|
|
1657
|
+
* ```
|
|
1658
|
+
* explicit(λ) = typeof onMissing === 'object' ? onMissing[λ] : undefined
|
|
1659
|
+
* scalar = typeof onMissing === 'string' ? onMissing : undefined
|
|
1660
|
+
* policy(λ) = explicit(λ) ?? layerDefault(λ) ?? scalar ?? 'throw'
|
|
1661
|
+
* ```
|
|
1662
|
+
*
|
|
1663
|
+
* - `layerDefault('guard') = 'substitute'` — guards are lenient unless
|
|
1664
|
+
* EXPLICITLY overridden; they never inherit a scalar policy (a guard
|
|
1665
|
+
* reading a display value must not hard-fail on a missing locale).
|
|
1666
|
+
* - every other layer has no default, so it inherits the scalar, else
|
|
1667
|
+
* falls back to `'throw'` (today's behavior — zero breaking change).
|
|
1668
|
+
*
|
|
1669
|
+
* @public
|
|
1670
|
+
*/
|
|
1671
|
+
type OnMissing = 'substitute' | 'null' | 'throw';
|
|
1672
|
+
/**
|
|
1673
|
+
* The contexts in which a multilingual field is resolved. Each can carry
|
|
1674
|
+
* its own `onMissing` policy.
|
|
1675
|
+
*
|
|
1676
|
+
* - `read` — ordinary app reads (`get`/`list`/query projection).
|
|
1677
|
+
* - `guard` — a guard callback reading a value.
|
|
1678
|
+
* - `join` — a joined record expanded onto a row.
|
|
1679
|
+
* - `mv` — materialized-view input.
|
|
1680
|
+
* - `derivation` — derivation input.
|
|
1681
|
+
* - `export` — bundle/public-envelope export.
|
|
1682
|
+
*/
|
|
1683
|
+
type Layer = 'read' | 'guard' | 'join' | 'mv' | 'derivation' | 'export';
|
|
1684
|
+
/** Field-level policy: a single scalar, or a per-layer map. */
|
|
1685
|
+
type OnMissingPolicy = OnMissing | Partial<Record<Layer, OnMissing>>;
|
|
1686
|
+
/**
|
|
1687
|
+
* Resolve the effective `OnMissing` for a layer from a field's declared
|
|
1688
|
+
* policy. See module docs for the resolution rule.
|
|
1689
|
+
*/
|
|
1690
|
+
declare function resolvePolicy(onMissing: OnMissingPolicy | undefined, layer: Layer): OnMissing;
|
|
1691
|
+
|
|
1639
1692
|
/**
|
|
1640
1693
|
* i18nText schema type —
|
|
1641
1694
|
*
|
|
@@ -1677,6 +1730,37 @@ interface PeriodsStrategy {
|
|
|
1677
1730
|
* Pluralization, RTL rendering, date/number formatting, per-locale CRDT
|
|
1678
1731
|
* merging.
|
|
1679
1732
|
*/
|
|
1733
|
+
|
|
1734
|
+
/** Flatten an intersection into a single object literal for nicer hovers. */
|
|
1735
|
+
type Prettify<T> = {
|
|
1736
|
+
[K in keyof T]: T[K];
|
|
1737
|
+
} & {};
|
|
1738
|
+
/**
|
|
1739
|
+
* The stored shape of a multilingual field, inferred from its `required`
|
|
1740
|
+
* mode — so the compiler forces you to handle an absent optional locale
|
|
1741
|
+
* (`string | undefined`) instead of silently yielding `undefined`.
|
|
1742
|
+
*
|
|
1743
|
+
* Mirrors `i18nText({ languages, required })`:
|
|
1744
|
+
* - `'all'` (default) — every locale required: `{ th: string; en: string }`
|
|
1745
|
+
* - `'any'` — every locale optional: `{ th?: string; en?: string }`
|
|
1746
|
+
* (the "at least one present" guarantee is runtime-only — not expressible
|
|
1747
|
+
* in TypeScript — so each key is optional)
|
|
1748
|
+
* - `readonly L[]` — listed locales required, the rest optional:
|
|
1749
|
+
* `I18nMap<'th'|'en', ['th']>` → `{ th: string; en?: string }`
|
|
1750
|
+
*
|
|
1751
|
+
* @example
|
|
1752
|
+
* ```ts
|
|
1753
|
+
* type Lang = 'th' | 'en'
|
|
1754
|
+
* interface Contact {
|
|
1755
|
+
* name: I18nMap<Lang, 'any'> // { th?: string; en?: string }
|
|
1756
|
+
* legalName: I18nMap<Lang, ['th']> // { th: string; en?: string }
|
|
1757
|
+
* slug: I18nMap<Lang> // { th: string; en: string }
|
|
1758
|
+
* }
|
|
1759
|
+
* ```
|
|
1760
|
+
*
|
|
1761
|
+
* @public
|
|
1762
|
+
*/
|
|
1763
|
+
type I18nMap<Langs extends string, Required extends 'all' | 'any' | readonly Langs[] = 'all'> = Required extends 'all' ? Record<Langs, string> : Required extends 'any' ? Partial<Record<Langs, string>> : Required extends readonly (infer R extends Langs)[] ? Prettify<Record<R, string> & Partial<Record<Exclude<Langs, R>, string>>> : never;
|
|
1680
1764
|
/**
|
|
1681
1765
|
* Options for `i18nText()`.
|
|
1682
1766
|
*
|
|
@@ -1705,6 +1789,38 @@ interface I18nTextOptions {
|
|
|
1705
1789
|
* before `put()` if a translator is configured. Default: `false`.
|
|
1706
1790
|
*/
|
|
1707
1791
|
readonly autoTranslate?: boolean;
|
|
1792
|
+
/**
|
|
1793
|
+
* What to do when this field is resolved to a locale that is absent.
|
|
1794
|
+
* A single policy, or a per-layer map (read/guard/join/mv/derivation/
|
|
1795
|
+
* export). Default `'throw'` — today's behavior, zero breaking change.
|
|
1796
|
+
* See {@link OnMissingPolicy}.
|
|
1797
|
+
*
|
|
1798
|
+
* NOTE (current wiring): the `read` layer (`get`/`list`) is enforced.
|
|
1799
|
+
* Guard, derivation, mv, join and export reads currently resolve
|
|
1800
|
+
* through the same read path and so observe the `read`/scalar policy;
|
|
1801
|
+
* dedicated per-layer enforcement for those contexts is a tracked
|
|
1802
|
+
* follow-up (mv/join additionally require resolution to be injected
|
|
1803
|
+
* into the query/aggregate pipeline, which today reads raw maps).
|
|
1804
|
+
*/
|
|
1805
|
+
readonly onMissing?: OnMissingPolicy;
|
|
1806
|
+
/**
|
|
1807
|
+
* Ordered preferred-substitute locales used when `onMissing` resolves
|
|
1808
|
+
* to `'substitute'` and the target locale is absent. `'any'` as an
|
|
1809
|
+
* element means "first non-empty value". A caller-supplied `fallback`
|
|
1810
|
+
* at read time takes precedence over this declared list.
|
|
1811
|
+
*/
|
|
1812
|
+
readonly substitute?: readonly string[];
|
|
1813
|
+
/**
|
|
1814
|
+
* Per-locale script enforcement (write-time). `'auto'` infers the
|
|
1815
|
+
* allowed Unicode scripts per locale (asymmetric Latin tolerance); an
|
|
1816
|
+
* object overrides per slot. Absent ⇒ no check. See `./script.ts`.
|
|
1817
|
+
*/
|
|
1818
|
+
readonly script?: 'auto' | Partial<Record<string, readonly string[]>>;
|
|
1819
|
+
/**
|
|
1820
|
+
* What to do when a slot's value contains characters outside its
|
|
1821
|
+
* allowed script set. Default `'reject'`.
|
|
1822
|
+
*/
|
|
1823
|
+
readonly onScriptViolation?: 'reject' | 'filter' | 'warn';
|
|
1708
1824
|
}
|
|
1709
1825
|
/**
|
|
1710
1826
|
* Descriptor returned by `i18nText()`. Attach to the collection's
|
|
@@ -1759,23 +1875,52 @@ declare function validateI18nTextValue(value: unknown, field: string, descriptor
|
|
|
1759
1875
|
* @param field Field name used in `LocaleNotSpecifiedError` messages.
|
|
1760
1876
|
* @returns The resolved string, OR the original map when `locale === 'raw'`.
|
|
1761
1877
|
*/
|
|
1878
|
+
/** Options for the policy-aware form of {@link resolveI18nText}. */
|
|
1879
|
+
interface ResolveI18nOptions {
|
|
1880
|
+
/** Effective policy for the resolution layer. Default `'throw'`. */
|
|
1881
|
+
readonly policy?: OnMissing;
|
|
1882
|
+
/** Declared substitute chain; applied only under policy `'substitute'`. */
|
|
1883
|
+
readonly substitute?: readonly string[];
|
|
1884
|
+
}
|
|
1762
1885
|
declare function resolveI18nText(value: Record<string, string>, locale: string, fallback?: string | readonly string[], field?: string): string | Record<string, string>;
|
|
1886
|
+
declare function resolveI18nText(value: Record<string, string>, locale: string, fallback: string | readonly string[] | undefined, field: string | undefined, opts: ResolveI18nOptions): string | Record<string, string> | null;
|
|
1887
|
+
/**
|
|
1888
|
+
* Return all leaf values at `path`, expanding `[].` array wildcards.
|
|
1889
|
+
*
|
|
1890
|
+
* - `'name'` → `[obj.name]`
|
|
1891
|
+
* - `'address.lineOne'` → `[obj.address.lineOne]`
|
|
1892
|
+
* - `'contacts[].title'` → `[obj.contacts[0].title, obj.contacts[1].title, …]`
|
|
1893
|
+
*
|
|
1894
|
+
* Returns an empty array when the path does not resolve (missing key,
|
|
1895
|
+
* wrong type, etc.). Used by `enforceI18nOnPut` to validate nested fields.
|
|
1896
|
+
*/
|
|
1897
|
+
declare function getAtPath(obj: Record<string, unknown>, path: string): unknown[];
|
|
1763
1898
|
/**
|
|
1764
|
-
*
|
|
1899
|
+
* Mutate `obj` in-place, setting `value` at the nested `path`.
|
|
1900
|
+
* Supports dot notation (`'address.lineOne'`) but not array wildcards —
|
|
1901
|
+
* auto-translate on `contacts[].title` style paths is not supported.
|
|
1902
|
+
*/
|
|
1903
|
+
declare function setAtPathInPlace(obj: Record<string, unknown>, path: string, value: unknown): void;
|
|
1904
|
+
/**
|
|
1905
|
+
* Apply locale resolution to a single record, returning a new copy.
|
|
1765
1906
|
*
|
|
1766
1907
|
* For each field registered as an `i18nText` descriptor:
|
|
1767
1908
|
* - If `locale === 'raw'`, the field value is left as the stored map.
|
|
1768
1909
|
* - Otherwise, the field value is replaced with the resolved string.
|
|
1769
1910
|
*
|
|
1770
|
-
*
|
|
1771
|
-
*
|
|
1911
|
+
* Field paths support dot notation (`'address.lineOne'`) and array
|
|
1912
|
+
* wildcards (`'contacts[].title'`). Top-level fields work as before.
|
|
1772
1913
|
*
|
|
1773
1914
|
* @param record The decrypted record.
|
|
1774
|
-
* @param i18nFields Map of field
|
|
1915
|
+
* @param i18nFields Map of field path → `I18nTextDescriptor`.
|
|
1775
1916
|
* @param locale The requested locale (or `'raw'`).
|
|
1776
1917
|
* @param fallback Fallback chain (optional).
|
|
1918
|
+
* @param layer Resolution layer (default `'read'`). Each field's
|
|
1919
|
+
* `onMissing` policy is resolved for this layer, so the
|
|
1920
|
+
* same record resolves leniently on a get but strictly
|
|
1921
|
+
* inside an mv/derivation.
|
|
1777
1922
|
*/
|
|
1778
|
-
declare function applyI18nLocale(record: Record<string, unknown>, i18nFields: Record<string, I18nTextDescriptor>, locale: string, fallback?: string | readonly string[]): Record<string, unknown>;
|
|
1923
|
+
declare function applyI18nLocale(record: Record<string, unknown>, i18nFields: Record<string, I18nTextDescriptor>, locale: string, fallback?: string | readonly string[], layer?: Layer): Record<string, unknown>;
|
|
1779
1924
|
|
|
1780
1925
|
type EventHandler<T> = (data: T) => void;
|
|
1781
1926
|
/** Typed event emitter for NOYDB events. */
|
|
@@ -1840,7 +1985,6 @@ interface PassphrasePolicy {
|
|
|
1840
1985
|
* double-space). For non-space-delimited word semantics, use
|
|
1841
1986
|
* {@link customValidator} instead.
|
|
1842
1987
|
*
|
|
1843
|
-
* Added in pre.8 (#31).
|
|
1844
1988
|
*/
|
|
1845
1989
|
readonly pattern?: RegExp;
|
|
1846
1990
|
/**
|
|
@@ -1858,7 +2002,6 @@ interface PassphrasePolicy {
|
|
|
1858
2002
|
* {@link assertStrongPassphrase} dispatches on — `ok: true` accepts;
|
|
1859
2003
|
* `ok: false` throws `WeakPassphraseError` with the supplied reason.
|
|
1860
2004
|
*
|
|
1861
|
-
* Added in pre.8 (#31).
|
|
1862
2005
|
*/
|
|
1863
2006
|
readonly customValidator?: (phrase: string) => PassphraseValidationResult;
|
|
1864
2007
|
}
|
|
@@ -1975,7 +2118,7 @@ interface UnlockedKeyring {
|
|
|
1975
2118
|
* - Unencrypted mode (no KEK exists)
|
|
1976
2119
|
* - Tier-3 PIN quick-resume (`@noy-db/on-pin`)
|
|
1977
2120
|
* - Wrap-DEKs tier-2 unlock (`@noy-db/on-password`'s
|
|
1978
|
-
* `verifyPasswordSlot`
|
|
2121
|
+
* `verifyPasswordSlot`)
|
|
1979
2122
|
* - Session-state restore (`session/session.ts`)
|
|
1980
2123
|
* - Dev-unlock fixture (`session/dev-unlock.ts`)
|
|
1981
2124
|
*
|
|
@@ -1984,9 +2127,8 @@ interface UnlockedKeyring {
|
|
|
1984
2127
|
* null-check and throw a clear error if absent — re-authenticate
|
|
1985
2128
|
* at tier 1 first to recover the KEK.
|
|
1986
2129
|
*
|
|
1987
|
-
* Tightened from `CryptoKey` to `CryptoKey | null
|
|
1988
|
-
*
|
|
1989
|
-
* matches reality.
|
|
2130
|
+
* Tightened from `CryptoKey` to `CryptoKey | null`; the runtime
|
|
2131
|
+
* contract has always allowed null, the type now matches reality.
|
|
1990
2132
|
*/
|
|
1991
2133
|
readonly kek: CryptoKey | null;
|
|
1992
2134
|
readonly salt: Uint8Array;
|
|
@@ -2007,7 +2149,7 @@ interface UnlockedKeyring {
|
|
|
2007
2149
|
/**
|
|
2008
2150
|
* Tier-2 authenticator slots — readonly snapshot loaded from the
|
|
2009
2151
|
* keyring file. Mutations go through `enrollAuthenticator` /
|
|
2010
|
-
* `removeAuthenticator
|
|
2152
|
+
* `removeAuthenticator`, which write back via
|
|
2011
2153
|
* `persistKeyring`. Always defined; loads with an empty array for
|
|
2012
2154
|
* keyrings written before the multi-slot extension landed.
|
|
2013
2155
|
*/
|
|
@@ -2060,7 +2202,6 @@ declare function revoke(adapter: NoydbStore, vault: string, callerKeyring: Unloc
|
|
|
2060
2202
|
* @throws `PermissionDeniedError` when the role hierarchy rejects.
|
|
2061
2203
|
* @throws `ValidationError` when the diff is empty (nothing to update).
|
|
2062
2204
|
*
|
|
2063
|
-
* @see #54
|
|
2064
2205
|
*/
|
|
2065
2206
|
declare function updateKeyringIdentity(adapter: NoydbStore, vault: string, callerKeyring: UnlockedKeyring, options: UpdateUserOptions): Promise<void>;
|
|
2066
2207
|
/**
|
|
@@ -2155,7 +2296,7 @@ interface ListUsersOptions {
|
|
|
2155
2296
|
* `userEnvelopeDek` is the vault's `_users` collection DEK
|
|
2156
2297
|
* (`vault.getDEK('_users')`); used to decrypt every envelope.
|
|
2157
2298
|
*
|
|
2158
|
-
* `callerRole`
|
|
2299
|
+
* `callerRole` drives the directory-visibility checks:
|
|
2159
2300
|
*
|
|
2160
2301
|
* - When the vault's `_meta/directory` document has `enabled: false`,
|
|
2161
2302
|
* only `owner` and `admin` callers may enumerate; anyone else gets
|
|
@@ -2165,7 +2306,7 @@ interface ListUsersOptions {
|
|
|
2165
2306
|
* `{ includeHidden: true }` to see them; lower roles passing that
|
|
2166
2307
|
* option get `PermissionDeniedError`.
|
|
2167
2308
|
*
|
|
2168
|
-
* Honest caveat
|
|
2309
|
+
* Honest caveat: these filters are a UX hint, not a security
|
|
2169
2310
|
* boundary. The keyring file is still listed at `_keyring/*` and the
|
|
2170
2311
|
* envelope ciphertext at `_users/*`. A caller with direct store access
|
|
2171
2312
|
* — or a caller that calls this function with `callerRole: 'owner'`
|
|
@@ -2304,6 +2445,16 @@ interface DictKeyDescriptor<Keys extends string = string> {
|
|
|
2304
2445
|
readonly name: string;
|
|
2305
2446
|
/** Declared valid keys. When set, `put()` rejects keys not in this set. */
|
|
2306
2447
|
readonly keys: readonly Keys[] | undefined;
|
|
2448
|
+
/**
|
|
2449
|
+
* What to do when a label is missing for the resolved locale. Mirrors
|
|
2450
|
+
* `i18nText`'s `onMissing`. Default behavior (when unset) preserves the
|
|
2451
|
+
* legacy contract: a missing label is omitted (scalar) or `null`
|
|
2452
|
+
* (array element) — i.e. `'null'`. Set `'substitute'` to walk the
|
|
2453
|
+
* declared `substitute` chain, or `'throw'` to raise.
|
|
2454
|
+
*/
|
|
2455
|
+
readonly onMissing?: OnMissingPolicy;
|
|
2456
|
+
/** Ordered preferred-substitute locales for label resolution. */
|
|
2457
|
+
readonly substitute?: readonly string[];
|
|
2307
2458
|
}
|
|
2308
2459
|
/**
|
|
2309
2460
|
* Create a `DictKeyDescriptor` for a dictionary-backed enum field.
|
|
@@ -2322,7 +2473,10 @@ interface DictKeyDescriptor<Keys extends string = string> {
|
|
|
2322
2473
|
* })
|
|
2323
2474
|
* ```
|
|
2324
2475
|
*/
|
|
2325
|
-
declare function dictKey<Keys extends string>(name: string, keys?: readonly Keys[]
|
|
2476
|
+
declare function dictKey<Keys extends string>(name: string, keys?: readonly Keys[], opts?: {
|
|
2477
|
+
onMissing?: OnMissingPolicy;
|
|
2478
|
+
substitute?: readonly string[];
|
|
2479
|
+
}): DictKeyDescriptor<Keys>;
|
|
2326
2480
|
/** Runtime predicate for detecting a DictKeyDescriptor. */
|
|
2327
2481
|
declare function isDictKeyDescriptor(x: unknown): x is DictKeyDescriptor;
|
|
2328
2482
|
/**
|
|
@@ -2466,6 +2620,32 @@ declare class DictionaryHandle<Keys extends string = string> {
|
|
|
2466
2620
|
resolveLabel(key: string, locale: string, fallback?: string | readonly string[]): Promise<string | undefined>;
|
|
2467
2621
|
}
|
|
2468
2622
|
|
|
2623
|
+
/**
|
|
2624
|
+
* Infer the allowed Unicode scripts for a BCP-47 locale, with asymmetric
|
|
2625
|
+
* Latin tolerance. A script subtag (`th-Latn`) wins over the base
|
|
2626
|
+
* language. Unknown locales default to `['Latin']`.
|
|
2627
|
+
*/
|
|
2628
|
+
declare function inferScripts(locale: string): readonly string[];
|
|
2629
|
+
/** A non-fatal script violation recorded under `'filter'`/`'warn'` modes. */
|
|
2630
|
+
interface ScriptWarning {
|
|
2631
|
+
readonly field: string;
|
|
2632
|
+
readonly locale: string;
|
|
2633
|
+
readonly expected: readonly string[];
|
|
2634
|
+
readonly sample: string;
|
|
2635
|
+
}
|
|
2636
|
+
/**
|
|
2637
|
+
* Enforce a field's script constraint over an i18nText value map.
|
|
2638
|
+
*
|
|
2639
|
+
* - No `script` option ⇒ returns the value unchanged.
|
|
2640
|
+
* - `onScriptViolation: 'reject'` (default) ⇒ throws {@link ScriptViolationError}.
|
|
2641
|
+
* - `'filter'` ⇒ returns a copy with disallowed characters stripped + warnings.
|
|
2642
|
+
* - `'warn'` ⇒ returns the value unchanged + warnings.
|
|
2643
|
+
*/
|
|
2644
|
+
declare function enforceScript(value: Record<string, unknown>, field: string, descriptor: I18nTextDescriptor): {
|
|
2645
|
+
value: Record<string, unknown>;
|
|
2646
|
+
warnings: ScriptWarning[];
|
|
2647
|
+
};
|
|
2648
|
+
|
|
2469
2649
|
/**
|
|
2470
2650
|
* Strategy seam for the optional i18n (multi-locale + dictionary)
|
|
2471
2651
|
* subsystem. Core imports `I18nStrategy` type-only + `NO_I18N` stub;
|
|
@@ -2527,13 +2707,23 @@ interface I18nStrategy {
|
|
|
2527
2707
|
* return a new object. Returns the input unchanged under
|
|
2528
2708
|
* `NO_I18N`.
|
|
2529
2709
|
*/
|
|
2530
|
-
applyI18nLocale(record: Record<string, unknown>, fields: Record<string, I18nTextDescriptor>, locale: string, fallback?: string | readonly string[]): Record<string, unknown>;
|
|
2710
|
+
applyI18nLocale(record: Record<string, unknown>, fields: Record<string, I18nTextDescriptor>, locale: string, fallback?: string | readonly string[], layer?: Layer): Record<string, unknown>;
|
|
2531
2711
|
/**
|
|
2532
2712
|
* Validate that an i18nText field's value satisfies its descriptor
|
|
2533
2713
|
* (required locales present, etc.). Throws under `NO_I18N` —
|
|
2534
2714
|
* declaring i18nFields without opting in is a misconfiguration.
|
|
2535
2715
|
*/
|
|
2536
2716
|
validateI18nTextValue(value: unknown, field: string, descriptor: I18nTextDescriptor): void;
|
|
2717
|
+
/**
|
|
2718
|
+
* Enforce per-locale script constraints over an i18nText value map
|
|
2719
|
+
* (write-time). Returns the (possibly filtered) value plus any
|
|
2720
|
+
* non-fatal warnings. Returns the value unchanged when the field has
|
|
2721
|
+
* no `script` option, or under `NO_I18N`.
|
|
2722
|
+
*/
|
|
2723
|
+
enforceScript(value: Record<string, unknown>, field: string, descriptor: I18nTextDescriptor): {
|
|
2724
|
+
value: Record<string, unknown>;
|
|
2725
|
+
warnings: ScriptWarning[];
|
|
2726
|
+
};
|
|
2537
2727
|
/**
|
|
2538
2728
|
* Construct a typed `DictionaryHandle` for the named dictionary.
|
|
2539
2729
|
* Throws under `NO_I18N`.
|
|
@@ -2541,6 +2731,326 @@ interface I18nStrategy {
|
|
|
2541
2731
|
buildDictionaryHandle<Keys extends string = string>(opts: BuildDictionaryHandleOptions<Keys>): DictionaryHandle<Keys>;
|
|
2542
2732
|
}
|
|
2543
2733
|
|
|
2734
|
+
/**
|
|
2735
|
+
* Observable write-queue.
|
|
2736
|
+
*
|
|
2737
|
+
* Tracks outstanding in-flight *logical* writes (a full Collection.put /
|
|
2738
|
+
* delete, including ledger + cache + derivation + MV dispatch — not just
|
|
2739
|
+
* the adapter call). The hub holds one tracker per instance; it is
|
|
2740
|
+
* framework-agnostic (no Vue/React dependency). UI layers subscribe via
|
|
2741
|
+
* onChange(); the migration drain (Slice 2) quiesces via onFlush().
|
|
2742
|
+
*/
|
|
2743
|
+
/** Public, read-only view of the hub's write-queue. */
|
|
2744
|
+
interface WriteQueue {
|
|
2745
|
+
/** True while one or more writes are in flight (`depth > 0`). */
|
|
2746
|
+
readonly pending: boolean;
|
|
2747
|
+
/** Count of outstanding write operations. */
|
|
2748
|
+
readonly depth: number;
|
|
2749
|
+
/**
|
|
2750
|
+
* Subscribe to depth changes (fires on every begin and settle).
|
|
2751
|
+
* Returns an unsubscribe function. Intended for reactive wrappers
|
|
2752
|
+
* (e.g. `@noy-db/in-vue` turns this into a `ref`).
|
|
2753
|
+
*/
|
|
2754
|
+
onChange(handler: () => void): () => void;
|
|
2755
|
+
/**
|
|
2756
|
+
* Resolves once `depth` reaches 0. If a write settled with an error
|
|
2757
|
+
* while this flush was waiting, the returned promise REJECTS with that
|
|
2758
|
+
* error instead — so a drain caller surfaces the failure rather than
|
|
2759
|
+
* hanging. Resolves immediately when already idle and error-free.
|
|
2760
|
+
*/
|
|
2761
|
+
onFlush(): Promise<void>;
|
|
2762
|
+
}
|
|
2763
|
+
declare class WriteQueueTracker implements WriteQueue {
|
|
2764
|
+
#private;
|
|
2765
|
+
get pending(): boolean;
|
|
2766
|
+
get depth(): number;
|
|
2767
|
+
/** Mark one write as started. */
|
|
2768
|
+
begin(): void;
|
|
2769
|
+
/** Mark one write as finished. Pass the error if it failed. */
|
|
2770
|
+
settle(error?: Error): void;
|
|
2771
|
+
onChange(handler: () => void): () => void;
|
|
2772
|
+
onFlush(): Promise<void>;
|
|
2773
|
+
/**
|
|
2774
|
+
* Run `fn` as a tracked write: depth++ on entry, depth-- on settle
|
|
2775
|
+
* (success or failure). The fn's resolved value is returned; a thrown
|
|
2776
|
+
* error is re-thrown after the queue is decremented.
|
|
2777
|
+
*/
|
|
2778
|
+
track<R>(fn: () => Promise<R>): Promise<R>;
|
|
2779
|
+
}
|
|
2780
|
+
|
|
2781
|
+
/**
|
|
2782
|
+
* Hub-level write lifecycle hooks. `onBeforeWrite` may abort (throw);
|
|
2783
|
+
* `onAfterWrite` is awaited and its errors are warned, not thrown. A
|
|
2784
|
+
* re-entrancy flag suppresses nested firing so a handler that writes can't
|
|
2785
|
+
* loop. Held on the Noydb instance, threaded into every Collection.
|
|
2786
|
+
*/
|
|
2787
|
+
interface WriteEvent {
|
|
2788
|
+
readonly op: 'create' | 'update' | 'delete';
|
|
2789
|
+
readonly vault: string;
|
|
2790
|
+
readonly collection: string;
|
|
2791
|
+
readonly docId: string;
|
|
2792
|
+
readonly before: unknown;
|
|
2793
|
+
readonly after: unknown;
|
|
2794
|
+
readonly baseVersion: number;
|
|
2795
|
+
readonly version: number;
|
|
2796
|
+
readonly userId: string;
|
|
2797
|
+
readonly timestamp: number;
|
|
2798
|
+
readonly txId: string;
|
|
2799
|
+
}
|
|
2800
|
+
type WriteHook = (event: WriteEvent) => void | Promise<void>;
|
|
2801
|
+
type Unsubscribe$3 = () => void;
|
|
2802
|
+
declare class WriteHookRegistry {
|
|
2803
|
+
#private;
|
|
2804
|
+
/** True while handlers are running — used by the write path to skip nested firing. */
|
|
2805
|
+
get suppressed(): boolean;
|
|
2806
|
+
/** True when any hook is registered (cheap gate for the write path). */
|
|
2807
|
+
get hasHandlers(): boolean;
|
|
2808
|
+
onBeforeWrite(handler: WriteHook): Unsubscribe$3;
|
|
2809
|
+
onAfterWrite(handler: WriteHook): Unsubscribe$3;
|
|
2810
|
+
/** Run before-hooks (awaited, in order). A throw propagates and aborts the write. */
|
|
2811
|
+
runBefore(event: WriteEvent): Promise<void>;
|
|
2812
|
+
/** Run after-hooks (awaited, in order). Per-handler errors are warned, not thrown. */
|
|
2813
|
+
runAfter(event: WriteEvent): Promise<void>;
|
|
2814
|
+
}
|
|
2815
|
+
|
|
2816
|
+
/**
|
|
2817
|
+
* Generic per-instance **observe** bus. Observe-class
|
|
2818
|
+
* subsystems (devtools inspector, audit, sync-dirty notification) register
|
|
2819
|
+
* handlers against named lifecycle points instead of the kernel naming each
|
|
2820
|
+
* subsystem. Mirrors the registry pattern of {@link WriteHookRegistry} but is
|
|
2821
|
+
* internal and keyed by lifecycle point.
|
|
2822
|
+
*
|
|
2823
|
+
* OBSERVE SEMANTICS: handlers react to a write that already happened. A
|
|
2824
|
+
* handler throw is warned, not propagated — it can never abort a write. Write-
|
|
2825
|
+
* *gating* subsystems (guards, periods) need a throw-propagating gate bus.
|
|
2826
|
+
* Add observe points by extending {@link LifecycleEventMap}. Write-*gating*
|
|
2827
|
+
* subsystems use the sibling gate API on this same class
|
|
2828
|
+
* (`registerGate`/`dispatchGate`, throw-propagating); see {@link GateEventMap}.
|
|
2829
|
+
*
|
|
2830
|
+
* @module
|
|
2831
|
+
*/
|
|
2832
|
+
|
|
2833
|
+
/** Typed map of OBSERVE lifecycle point → event payload. Extend by adding keys. */
|
|
2834
|
+
interface LifecycleEventMap {
|
|
2835
|
+
afterPut: WriteEvent;
|
|
2836
|
+
afterDelete: WriteEvent;
|
|
2837
|
+
}
|
|
2838
|
+
type LifecyclePoint = keyof LifecycleEventMap;
|
|
2839
|
+
type BusHandler<P extends LifecyclePoint> = (event: LifecycleEventMap[P]) => void | Promise<void>;
|
|
2840
|
+
type Unsubscribe$2 = () => void;
|
|
2841
|
+
/** Payload for a `beforePut` gate — carries the data guards and periods need to validate or reject a write. */
|
|
2842
|
+
interface GatePutEvent {
|
|
2843
|
+
readonly op: 'create' | 'update';
|
|
2844
|
+
readonly vault: string;
|
|
2845
|
+
readonly collection: string;
|
|
2846
|
+
readonly docId: string;
|
|
2847
|
+
/** The record about to be written (pre schema-validation). */
|
|
2848
|
+
readonly incoming: unknown;
|
|
2849
|
+
/** Decrypted prior record, or null on create / when prior is unreadable. */
|
|
2850
|
+
readonly existing: unknown;
|
|
2851
|
+
/** Prior envelope version, or 0 when none. */
|
|
2852
|
+
readonly existingVersion: number;
|
|
2853
|
+
/** Prior envelope timestamp (`_ts` ISO string), or undefined when none — periods compares against this. */
|
|
2854
|
+
readonly existingTs: string | undefined;
|
|
2855
|
+
readonly userId: string;
|
|
2856
|
+
readonly role: Role;
|
|
2857
|
+
}
|
|
2858
|
+
/** Payload for a `beforeDelete` gate. Like {@link GatePutEvent} without `incoming`. */
|
|
2859
|
+
interface GateDeleteEvent {
|
|
2860
|
+
readonly vault: string;
|
|
2861
|
+
readonly collection: string;
|
|
2862
|
+
readonly docId: string;
|
|
2863
|
+
/** True for system-internal (housekeeping) deletes — handlers branch on this. */
|
|
2864
|
+
readonly internal: boolean;
|
|
2865
|
+
readonly existing: unknown;
|
|
2866
|
+
readonly existingVersion: number;
|
|
2867
|
+
readonly existingTs: string | undefined;
|
|
2868
|
+
readonly userId: string;
|
|
2869
|
+
readonly role: Role;
|
|
2870
|
+
}
|
|
2871
|
+
/** Typed map of GATE lifecycle point → event payload. Extend by adding keys. */
|
|
2872
|
+
interface GateEventMap {
|
|
2873
|
+
beforePut: GatePutEvent;
|
|
2874
|
+
beforeDelete: GateDeleteEvent;
|
|
2875
|
+
}
|
|
2876
|
+
type GatePoint = keyof GateEventMap;
|
|
2877
|
+
type GateHandler<P extends GatePoint> = (event: GateEventMap[P]) => void | Promise<void>;
|
|
2878
|
+
declare class SubsystemBus {
|
|
2879
|
+
#private;
|
|
2880
|
+
/** Register a handler for an observe point. Returns an unsubscribe fn. */
|
|
2881
|
+
register<P extends LifecyclePoint>(point: P, handler: BusHandler<P>): Unsubscribe$2;
|
|
2882
|
+
/** Cheap gate for the write path — true when any handler is registered for the point. */
|
|
2883
|
+
hasHandlers(point: LifecyclePoint): boolean;
|
|
2884
|
+
/**
|
|
2885
|
+
* True while one or more dispatches are in flight. Backed by a depth counter
|
|
2886
|
+
* so that two concurrent async dispatches (`Promise.all([put('a'), put('b')])`
|
|
2887
|
+
* each captured `busAfterPut=true` at their respective put() tops while depth
|
|
2888
|
+
* was 0) both proceed independently — the counter stays > 0 until BOTH finish,
|
|
2889
|
+
* so any nested write attempted by a handler still sees `dispatching === true`
|
|
2890
|
+
* and is suppressed by the write-path gate in `collection.ts`
|
|
2891
|
+
* (`busAfterPut = hasHandlers('afterPut') && !dispatching`). Re-entrancy
|
|
2892
|
+
* suppression lives exclusively on that write-path gate; concurrent independent
|
|
2893
|
+
* dispatches must not drop each other's events.
|
|
2894
|
+
*/
|
|
2895
|
+
get dispatching(): boolean;
|
|
2896
|
+
/**
|
|
2897
|
+
* Dispatch in registration order, awaited. Per-handler errors are warned, not
|
|
2898
|
+
* thrown — an observe handler must never abort a completed write. A
|
|
2899
|
+
* re-entrancy guard suppresses nested firing so a handler that itself writes
|
|
2900
|
+
* cannot loop (same rationale as WriteHookRegistry.#suppressed).
|
|
2901
|
+
*/
|
|
2902
|
+
dispatch<P extends LifecyclePoint>(point: P, event: LifecycleEventMap[P]): Promise<void>;
|
|
2903
|
+
/** Register a write-gating handler. A throw from the handler ABORTS the write. Returns an unsubscribe fn. */
|
|
2904
|
+
registerGate<P extends GatePoint>(point: P, handler: GateHandler<P>): Unsubscribe$2;
|
|
2905
|
+
/** Cheap gate for the write path — true when any gate handler is registered for the point. */
|
|
2906
|
+
hasGateHandlers(point: GatePoint): boolean;
|
|
2907
|
+
/**
|
|
2908
|
+
* Run gate handlers in registration order, awaited. Unlike `dispatch`
|
|
2909
|
+
* (observe), a handler throw is NOT swallowed — it PROPAGATES, aborting the
|
|
2910
|
+
* write before it reaches the store. The first throw stops the remaining
|
|
2911
|
+
* handlers (fail-fast). This is the seam guards/periods migrate onto.
|
|
2912
|
+
*
|
|
2913
|
+
* Note: gate handlers are validators that read, not write. A gate handler
|
|
2914
|
+
* that writes back into the same collection would re-enter the write path
|
|
2915
|
+
* and re-dispatch this point; loop-suppression for that case is deferred to
|
|
2916
|
+
* the migration slice (contract: gate handlers must not perform writes that
|
|
2917
|
+
* re-trigger their own point).
|
|
2918
|
+
*/
|
|
2919
|
+
dispatchGate<P extends GatePoint>(point: P, event: GateEventMap[P]): Promise<void>;
|
|
2920
|
+
}
|
|
2921
|
+
|
|
2922
|
+
/**
|
|
2923
|
+
* Schema-update strategy framework types (M12 §3a).
|
|
2924
|
+
*
|
|
2925
|
+
* The hub core detects a schema change (SchemaDelta) and dispatches it
|
|
2926
|
+
* through a collection's ordered strategy list. Strategies decide what
|
|
2927
|
+
* happens; the core only knows this interface.
|
|
2928
|
+
*/
|
|
2929
|
+
/** A single changed top-level property in a schema delta. */
|
|
2930
|
+
interface FieldChange {
|
|
2931
|
+
readonly field: string;
|
|
2932
|
+
/** True when the field's required-ness flipped. */
|
|
2933
|
+
readonly requiredChanged: boolean;
|
|
2934
|
+
/** True when the field's subschema shape changed. */
|
|
2935
|
+
readonly shapeChanged: boolean;
|
|
2936
|
+
}
|
|
2937
|
+
/** The classified difference between a stored and a freshly-derived schema. */
|
|
2938
|
+
interface SchemaDelta {
|
|
2939
|
+
readonly collection: string;
|
|
2940
|
+
readonly kind: 'none' | 'additive' | 'non-additive';
|
|
2941
|
+
/** Top-level properties present in the new schema but not the old. */
|
|
2942
|
+
readonly added: readonly string[];
|
|
2943
|
+
/** Top-level properties present in the old schema but not the new. */
|
|
2944
|
+
readonly removed: readonly string[];
|
|
2945
|
+
/** Top-level properties present in both but altered. */
|
|
2946
|
+
readonly changed: readonly FieldChange[];
|
|
2947
|
+
}
|
|
2948
|
+
/** Context handed to a strategy alongside the delta. */
|
|
2949
|
+
interface UpdateContext {
|
|
2950
|
+
readonly collection: string;
|
|
2951
|
+
}
|
|
2952
|
+
/** Bulk transform run by the coordinatedCutover strategy. */
|
|
2953
|
+
type TransformFn = (doc: Record<string, unknown>) => Record<string, unknown>;
|
|
2954
|
+
/**
|
|
2955
|
+
* A strategy's verdict on a detected schema change.
|
|
2956
|
+
* - `allow` — no objection; the dispatcher falls through to the next strategy.
|
|
2957
|
+
* - `reject` — terminal: refuse the change; `error` is thrown at the write path.
|
|
2958
|
+
* - `cutover` — terminal: run a coordinated drain-barrier (handled by coordinatedCutover).
|
|
2959
|
+
* New terminal actions may be added without breaking existing strategies.
|
|
2960
|
+
*/
|
|
2961
|
+
type UpdateDecision = {
|
|
2962
|
+
readonly action: 'allow';
|
|
2963
|
+
} | {
|
|
2964
|
+
readonly action: 'reject';
|
|
2965
|
+
readonly error: Error;
|
|
2966
|
+
} | {
|
|
2967
|
+
readonly action: 'cutover';
|
|
2968
|
+
readonly transform: TransformFn;
|
|
2969
|
+
};
|
|
2970
|
+
/** A pluggable schema-evolution policy. */
|
|
2971
|
+
interface SchemaUpdateStrategy {
|
|
2972
|
+
readonly name: string;
|
|
2973
|
+
onSchemaDelta(delta: SchemaDelta, ctx: UpdateContext): UpdateDecision | Promise<UpdateDecision>;
|
|
2974
|
+
}
|
|
2975
|
+
|
|
2976
|
+
/**
|
|
2977
|
+
* Per-collection write gate. Holds the (async) update decision
|
|
2978
|
+
* computed at registration; `Collection.put`/`delete` await it before
|
|
2979
|
+
* writing and throw the strategy's rejection error.
|
|
2980
|
+
*
|
|
2981
|
+
* Detection FAILURE (the promise rejecting) is deliberately NOT a write
|
|
2982
|
+
* block — schema detection is a fingerprint safety net, not a correctness
|
|
2983
|
+
* invariant (matches how persisted-schema write failures are swallowed).
|
|
2984
|
+
* Only an explicit `reject` decision blocks writes.
|
|
2985
|
+
*/
|
|
2986
|
+
|
|
2987
|
+
declare class SchemaUpdateGate {
|
|
2988
|
+
#private;
|
|
2989
|
+
constructor(decision: Promise<UpdateDecision>);
|
|
2990
|
+
assertWritable(): Promise<void>;
|
|
2991
|
+
}
|
|
2992
|
+
|
|
2993
|
+
/**
|
|
2994
|
+
* Schema-fence document. Vault-level generation counter + drain
|
|
2995
|
+
* state, stored at `_meta/schema-fence` using the plaintext-envelope
|
|
2996
|
+
* pattern of `_meta/policy` (no PII — a counter + a state enum).
|
|
2997
|
+
*/
|
|
2998
|
+
|
|
2999
|
+
type FenceState = 'normal' | 'draining' | 'migrating' | 'complete';
|
|
3000
|
+
interface FenceDoc {
|
|
3001
|
+
readonly currentSchemaVersion: number;
|
|
3002
|
+
readonly fenceState: FenceState;
|
|
3003
|
+
}
|
|
3004
|
+
|
|
3005
|
+
/**
|
|
3006
|
+
* Vault-level schema-fence controller.
|
|
3007
|
+
*
|
|
3008
|
+
* Owns the open-time generation snapshot, the pending-cutover registry,
|
|
3009
|
+
* and the cutover orchestration. 3a: single-client (the caller is the
|
|
3010
|
+
* migrator). 3b: a cooperative ack-barrier — after `draining`, the
|
|
3011
|
+
* migrator waits for the active client set (registry heartbeats) to ack
|
|
3012
|
+
* the draining generation before transforming. No leader election.
|
|
3013
|
+
*/
|
|
3014
|
+
|
|
3015
|
+
/** Runs one collection's transform; supplied by the Vault (binds to a Collection). */
|
|
3016
|
+
type RunTransform = (collection: string, transform: TransformFn) => Promise<void>;
|
|
3017
|
+
declare class SchemaFenceController {
|
|
3018
|
+
#private;
|
|
3019
|
+
constructor(opts: {
|
|
3020
|
+
store: NoydbStore;
|
|
3021
|
+
vault: string;
|
|
3022
|
+
onFlush: () => Promise<void>;
|
|
3023
|
+
clientId?: string;
|
|
3024
|
+
now?: () => number;
|
|
3025
|
+
staleMs?: number;
|
|
3026
|
+
quiesceTimeoutMs?: number;
|
|
3027
|
+
emit?: (e: {
|
|
3028
|
+
currentSchemaVersion: number;
|
|
3029
|
+
fenceState: FenceState;
|
|
3030
|
+
}) => void;
|
|
3031
|
+
});
|
|
3032
|
+
/** Capture the generation snapshot at vault-open. */
|
|
3033
|
+
init(): Promise<void>;
|
|
3034
|
+
/** Record a per-collection pending cutover (from a registration `cutover` decision). */
|
|
3035
|
+
registerPendingCutover(collection: string, transform: TransformFn): void;
|
|
3036
|
+
/** Write-path gate. Throws when behind, fenced, or this collection is cutover-pending. */
|
|
3037
|
+
assertWritable(collection: string): Promise<void>;
|
|
3038
|
+
/**
|
|
3039
|
+
* Admin trigger. Drain → wait for the active set to quiesce (or time out)
|
|
3040
|
+
* → migrate each pending transform → bump → complete → normal. The
|
|
3041
|
+
* migrator excludes itself from the barrier (it drained synchronously
|
|
3042
|
+
* here). `onPoll` (tests) advances other clients between barrier checks;
|
|
3043
|
+
* production falls back to a short real delay.
|
|
3044
|
+
*/
|
|
3045
|
+
runCutover(run: RunTransform, opts?: {
|
|
3046
|
+
onPoll?: () => Promise<void>;
|
|
3047
|
+
}): Promise<{
|
|
3048
|
+
migrated: number;
|
|
3049
|
+
}>;
|
|
3050
|
+
/** Recover a stuck drain: reset fenceState to normal at the current version (no bump). */
|
|
3051
|
+
abort(): Promise<void>;
|
|
3052
|
+
}
|
|
3053
|
+
|
|
2544
3054
|
/**
|
|
2545
3055
|
* Zero-dependency JSON diff.
|
|
2546
3056
|
* Produces a flat list of changes between two plain objects.
|
|
@@ -3091,7 +3601,7 @@ declare class SyncEngine {
|
|
|
3091
3601
|
}
|
|
3092
3602
|
|
|
3093
3603
|
/**
|
|
3094
|
-
* **Wrap-DEKs primitive
|
|
3604
|
+
* **Wrap-DEKs primitive** — a single canonical shape for the
|
|
3095
3605
|
* pattern of "serialize a DEK set, encrypt it under a credential-derived
|
|
3096
3606
|
* AES-GCM key." Used by:
|
|
3097
3607
|
*
|
|
@@ -3109,7 +3619,7 @@ declare class SyncEngine {
|
|
|
3109
3619
|
* `PIN_PBKDF2_ITERATIONS` and the threat-model rationale in its
|
|
3110
3620
|
* module docstring.
|
|
3111
3621
|
*
|
|
3112
|
-
*
|
|
3622
|
+
* Previously, the same crypto lived in two places: `mintPaperRecoveryEntry`
|
|
3113
3623
|
* (in `team/recovery.ts`) and `enrollPasswordAuthenticator` (in
|
|
3114
3624
|
* `@noy-db/on-password`). Both functions did identical work — PBKDF2
|
|
3115
3625
|
* the credential, AES-GCM-encrypt the JSON-serialized DEK set — but
|
|
@@ -3136,7 +3646,7 @@ declare class SyncEngine {
|
|
|
3136
3646
|
* Composition: `PaperRecoveryEntry extends WrappedDeksBlob` plus
|
|
3137
3647
|
* `{ codeId, enrolledAt }`. `KeyringAuthenticatorWrappingDEKs`
|
|
3138
3648
|
* carries the same three fields with `salt` stored in `meta` for
|
|
3139
|
-
* slot-format back-compat (
|
|
3649
|
+
* slot-format back-compat (defers moving it to top-level).
|
|
3140
3650
|
*/
|
|
3141
3651
|
interface WrappedDeksBlob {
|
|
3142
3652
|
/** Base64 PBKDF2 salt for the credential-derived wrapping key. */
|
|
@@ -3193,9 +3703,9 @@ interface ShamirRecoveryProvider {
|
|
|
3193
3703
|
}
|
|
3194
3704
|
|
|
3195
3705
|
/**
|
|
3196
|
-
* Recovery profile persistence + dispatch
|
|
3706
|
+
* Recovery profile persistence + dispatch.
|
|
3197
3707
|
*
|
|
3198
|
-
*
|
|
3708
|
+
* Wires the **paper** profile end-to-end through
|
|
3199
3709
|
* `@noy-db/on-recovery`. The other three profiles (Shamir,
|
|
3200
3710
|
* multi-channel, admin-mediated) ship the API surface and throw
|
|
3201
3711
|
* {@link RecoveryProfileNotImplementedError} during use; per-profile
|
|
@@ -3232,7 +3742,7 @@ interface ShamirRecoveryProvider {
|
|
|
3232
3742
|
* PBKDF2-derived key), and it sidesteps the non-extractable-KEK
|
|
3233
3743
|
* constraint cleanly.
|
|
3234
3744
|
*
|
|
3235
|
-
* Type-level composition
|
|
3745
|
+
* Type-level composition: `PaperRecoveryEntry extends
|
|
3236
3746
|
* WrappedDeksBlob` — the three crypto fields (`salt`, `iv`,
|
|
3237
3747
|
* `wrappedDeks`) come from the shared primitive; `codeId` and
|
|
3238
3748
|
* `enrolledAt` are paper-recovery's own metadata. Wire format
|
|
@@ -3346,7 +3856,7 @@ declare function unwrapDeksFromShamirEntry(provider: ShamirRecoveryProvider, ent
|
|
|
3346
3856
|
* {@link savePaperRecoveryEntries}). The recovery flow unwraps the
|
|
3347
3857
|
* DEK set, then mints a fresh KEK from the user's new passphrase.
|
|
3348
3858
|
*
|
|
3349
|
-
* Thin wrapper over {@link mintWrappedDeksBlob}
|
|
3859
|
+
* Thin wrapper over {@link mintWrappedDeksBlob} — the crypto
|
|
3350
3860
|
* lives in the shared primitive; this function just adds paper-
|
|
3351
3861
|
* recovery's own metadata (`codeId`, `enrolledAt`).
|
|
3352
3862
|
*
|
|
@@ -3361,14 +3871,14 @@ declare function mintPaperRecoveryEntry(deks: Map<string, CryptoKey>, code: stri
|
|
|
3361
3871
|
* Decrypt a recovery entry to recover the raw DEK set. Used by the
|
|
3362
3872
|
* `recoverPassphrase` flow after the user's code has been parsed.
|
|
3363
3873
|
*
|
|
3364
|
-
* Thin wrapper over {@link unwrapDeksFromBlob}
|
|
3874
|
+
* Thin wrapper over {@link unwrapDeksFromBlob}.
|
|
3365
3875
|
*
|
|
3366
3876
|
* @throws when the code does not match the entry (AES-GCM auth tag fail).
|
|
3367
3877
|
*/
|
|
3368
3878
|
declare function unwrapDeksFromPaperEntry(entry: PaperRecoveryEntry, code: string): Promise<Map<string, CryptoKey>>;
|
|
3369
3879
|
|
|
3370
3880
|
/**
|
|
3371
|
-
* Tier-2 authenticator slot management
|
|
3881
|
+
* Tier-2 authenticator slot management.
|
|
3372
3882
|
*
|
|
3373
3883
|
* Each slot independently wraps the SAME KEK under a method-specific
|
|
3374
3884
|
* derived key (LUKS pattern). Enrolling adds a slot; removing drops
|
|
@@ -3418,15 +3928,14 @@ type EnrollAuthenticatorOptions = EnrollAuthenticatorWrappingKEKOptions | Enroll
|
|
|
3418
3928
|
*/
|
|
3419
3929
|
declare function enrollAuthenticator(store: NoydbStore, vault: string, keyring: UnlockedKeyring, options: EnrollAuthenticatorOptions): Promise<UnlockedKeyring>;
|
|
3420
3930
|
/**
|
|
3421
|
-
* Caller payload for {@link updateAuthenticator}
|
|
3931
|
+
* Caller payload for {@link updateAuthenticator}. Mutates only
|
|
3422
3932
|
* `meta` — the slot's id, method, and wrap material are immutable
|
|
3423
3933
|
* through this primitive, preserving the anti-slot-swap guard.
|
|
3424
3934
|
*
|
|
3425
3935
|
* `meta` is **merged** at the top level: keys absent from the patch
|
|
3426
3936
|
* are preserved, keys present overwrite. To clear a meta key, pass
|
|
3427
|
-
* `null` for that key explicitly. (Same semantics as
|
|
3428
|
-
* `UserApi.updateMe`,
|
|
3429
|
-
* into nested meta values.)
|
|
3937
|
+
* `null` for that key explicitly. (Same top-level merge semantics as
|
|
3938
|
+
* `UserApi.updateMe`, non-recursive — meta is a flat label bag.)
|
|
3430
3939
|
*/
|
|
3431
3940
|
interface UpdateAuthenticatorOptions {
|
|
3432
3941
|
readonly meta?: Record<string, unknown>;
|
|
@@ -3448,7 +3957,6 @@ interface UpdateAuthenticatorOptions {
|
|
|
3448
3957
|
* @throws `NoAccessError` when no slot with the given id exists.
|
|
3449
3958
|
* @throws `ValidationError` when no patch field is provided.
|
|
3450
3959
|
*
|
|
3451
|
-
* @see #55
|
|
3452
3960
|
*/
|
|
3453
3961
|
declare function updateAuthenticator(store: NoydbStore, vault: string, keyring: UnlockedKeyring, slotId: string, options: UpdateAuthenticatorOptions): Promise<UnlockedKeyring>;
|
|
3454
3962
|
/**
|
|
@@ -3465,7 +3973,7 @@ declare function findAuthenticator(keyring: UnlockedKeyring, slotId: string): Ke
|
|
|
3465
3973
|
|
|
3466
3974
|
/**
|
|
3467
3975
|
* Tier-1 change flows — `rotatePassphrase` (user remembers old) and
|
|
3468
|
-
* `recoverPassphrase` (user supplies a recovery proof).
|
|
3976
|
+
* `recoverPassphrase` (user supplies a recovery proof).
|
|
3469
3977
|
*
|
|
3470
3978
|
* The two flows share the post-verification half — fresh salt, fresh
|
|
3471
3979
|
* KEK, rewrap every DEK — and differ only in how they re-derive the
|
|
@@ -3531,10 +4039,9 @@ interface RotatePassphraseInput {
|
|
|
3531
4039
|
* Map of slot id → re-enrolment ceremony. Slots whose id appears
|
|
3532
4040
|
* here are PRESERVED across rotation (the ceremony re-derives the
|
|
3533
4041
|
* method-specific wrapping under the new keyring); slots whose id
|
|
3534
|
-
* is absent are DROPPED (the pre
|
|
4042
|
+
* is absent are DROPPED (the pre-slot-ceremony behavior).
|
|
3535
4043
|
*
|
|
3536
|
-
* Without this map, `rotatePassphrase`
|
|
3537
|
-
* behavior of wiping every tier-2 slot. Consumers building a
|
|
4044
|
+
* Without this map, `rotatePassphrase` wipes every tier-2 slot. Consumers building a
|
|
3538
4045
|
* "rotate without losing my biometric" flow supply ceremonies for
|
|
3539
4046
|
* each slot they want to keep.
|
|
3540
4047
|
*
|
|
@@ -3542,7 +4049,7 @@ interface RotatePassphraseInput {
|
|
|
3542
4049
|
* state. Callers wrap individual ceremonies in try/catch + return
|
|
3543
4050
|
* a sentinel if they want graceful degradation per slot.
|
|
3544
4051
|
*
|
|
3545
|
-
* Added
|
|
4052
|
+
* Added when slot-ceremony rewrapping landed.
|
|
3546
4053
|
*/
|
|
3547
4054
|
readonly slotCeremonies?: {
|
|
3548
4055
|
readonly [slotId: string]: SlotRewrapCeremony;
|
|
@@ -3553,10 +4060,10 @@ interface RotatePassphraseInput {
|
|
|
3553
4060
|
* under a freshly-derived KEK from `newPassphrase`, and persist.
|
|
3554
4061
|
*
|
|
3555
4062
|
* Tier-2 authenticator slots are dropped UNLESS the caller supplies
|
|
3556
|
-
* a `slotCeremonies` map
|
|
4063
|
+
* a `slotCeremonies` map — each ceremony re-derives its
|
|
3557
4064
|
* method-specific wrapping under the new keyring, and hub persists
|
|
3558
4065
|
* the rewrapped slots atomically with the rotation. Slots whose id
|
|
3559
|
-
* isn't in the map are still dropped
|
|
4066
|
+
* isn't in the map are still dropped.
|
|
3560
4067
|
*
|
|
3561
4068
|
* @throws `InvalidKeyError` if `oldPassphrase` does not unwrap the keyring.
|
|
3562
4069
|
* @throws `WeakPassphraseError` if `newPassphrase` fails the strength rule.
|
|
@@ -3567,7 +4074,7 @@ declare function rotatePassphrase(store: NoydbStore, vault: string, userId: stri
|
|
|
3567
4074
|
/**
|
|
3568
4075
|
* Caller payload for {@link recoverPassphrase}.
|
|
3569
4076
|
*
|
|
3570
|
-
*
|
|
4077
|
+
* `paper` and `shamir` are wired end-to-end.
|
|
3571
4078
|
* The remaining two profiles (`multi-channel`, `admin-mediated`)
|
|
3572
4079
|
* stay outside the union and throw
|
|
3573
4080
|
* {@link RecoveryProfileNotImplementedError} at the runtime guard
|
|
@@ -3597,7 +4104,7 @@ interface RecoverPassphraseInput {
|
|
|
3597
4104
|
* After a successful paper-recovery, replace ALL remaining recovery
|
|
3598
4105
|
* entries with freshly-minted ones. Defaults to `true` (defensive).
|
|
3599
4106
|
*
|
|
3600
|
-
* Rationale
|
|
4107
|
+
* Rationale: the user just demonstrated they had access
|
|
3601
4108
|
* to AT LEAST one code. The remaining codes from the same printed
|
|
3602
4109
|
* sheet may also be compromised — photographed, leaked via a
|
|
3603
4110
|
* screen-share slip, or in the hands of whoever stole the sheet.
|
|
@@ -3647,7 +4154,7 @@ interface RecoverPassphraseResult {
|
|
|
3647
4154
|
readonly newCodes: readonly string[];
|
|
3648
4155
|
}
|
|
3649
4156
|
/**
|
|
3650
|
-
* Input for {@link Noydb.rotateRecovery}
|
|
4157
|
+
* Input for {@link Noydb.rotateRecovery} — deliberate
|
|
3651
4158
|
* recovery-credential regeneration when the user knows their
|
|
3652
4159
|
* passphrase but wants a fresh sheet (paper) or fresh shares
|
|
3653
4160
|
* (shamir). Symmetric to {@link RotatePassphraseInput}.
|
|
@@ -3698,7 +4205,7 @@ interface EnrollRecoveryResult {
|
|
|
3698
4205
|
}
|
|
3699
4206
|
/**
|
|
3700
4207
|
* Input shape for {@link Noydb.enrollRecovery} and
|
|
3701
|
-
* {@link Noydb.openVaultAndEnrollRecovery}
|
|
4208
|
+
* {@link Noydb.openVaultAndEnrollRecovery}. Discriminated
|
|
3702
4209
|
* union over recovery profiles.
|
|
3703
4210
|
*
|
|
3704
4211
|
* - `paper`: caller pre-mints entries (typically via
|
|
@@ -3724,9 +4231,8 @@ type RecoveryEnrollmentInput = {
|
|
|
3724
4231
|
readonly entryId?: string;
|
|
3725
4232
|
};
|
|
3726
4233
|
/**
|
|
3727
|
-
* Reset the user's passphrase using a recovery proof.
|
|
3728
|
-
*
|
|
3729
|
-
* persisted in `_meta/recovery-paper`. The other three profiles throw
|
|
4234
|
+
* Reset the user's passphrase using a recovery proof.
|
|
4235
|
+
* Supports `'paper'` and `'shamir'` profiles. The other profiles throw
|
|
3730
4236
|
* {@link RecoveryProfileNotImplementedError}.
|
|
3731
4237
|
*
|
|
3732
4238
|
* On success, the used recovery entry is burned (deleted from the
|
|
@@ -3735,7 +4241,7 @@ type RecoveryEnrollmentInput = {
|
|
|
3735
4241
|
declare function recoverPassphrase(provider: ShamirRecoveryProvider | undefined, store: NoydbStore, vault: string, userId: string, input: RecoverPassphraseInput): Promise<UnlockedKeyring>;
|
|
3736
4242
|
|
|
3737
4243
|
/**
|
|
3738
|
-
* Atomic peer-recovery primitive
|
|
4244
|
+
* Atomic peer-recovery primitive.
|
|
3739
4245
|
*
|
|
3740
4246
|
* `recoverUser` is a SEPARATE operation from `revoke + grant`. It
|
|
3741
4247
|
* exists because peer-recovery has different semantics than account
|
|
@@ -3764,7 +4270,7 @@ declare function recoverPassphrase(provider: ShamirRecoveryProvider | undefined,
|
|
|
3764
4270
|
*
|
|
3765
4271
|
* Caller must be at least as privileged as the target. The hub
|
|
3766
4272
|
* `db.recoverUser` method gates this with the `peer-recover-user`
|
|
3767
|
-
* policy gate (
|
|
4273
|
+
* policy gate (the `peer-recover-user` factor-proof requirement); the function below
|
|
3768
4274
|
* enforces only the role + anti-privilege-escalation invariants.
|
|
3769
4275
|
*
|
|
3770
4276
|
* @module
|
|
@@ -3920,7 +4426,64 @@ declare function validatePublicEnvelopeInput(input: SetPublicEnvelopeInput, sche
|
|
|
3920
4426
|
declare function isPublicEnvelope(x: unknown): x is PublicEnvelope;
|
|
3921
4427
|
|
|
3922
4428
|
/**
|
|
3923
|
-
*
|
|
4429
|
+
* Multi-tab coordination: primary/secondary election (Web Locks)
|
|
4430
|
+
* + presence heartbeat (BroadcastChannel). Browser-only; opt-in; no-op
|
|
4431
|
+
* when the APIs are absent. The lock/channel interfaces are hub-local
|
|
4432
|
+
* (structurally compatible with @noy-db/by-peer + @noy-db/by-tabs, but
|
|
4433
|
+
* not imported — those packages depend on hub).
|
|
4434
|
+
*/
|
|
4435
|
+
type TabRole = 'primary' | 'secondary' | 'unknown';
|
|
4436
|
+
interface TabPresence {
|
|
4437
|
+
readonly tabId: string;
|
|
4438
|
+
readonly lastSeen: number;
|
|
4439
|
+
readonly role: TabRole;
|
|
4440
|
+
}
|
|
4441
|
+
type Unsubscribe$1 = () => void;
|
|
4442
|
+
/** Structural subset of the Web Locks API / by-peer's MinimalLockManager. */
|
|
4443
|
+
interface TabLockManager {
|
|
4444
|
+
request<T>(name: string, options: {
|
|
4445
|
+
mode?: 'exclusive' | 'shared';
|
|
4446
|
+
signal?: AbortSignal;
|
|
4447
|
+
}, callback: (lock: unknown) => Promise<T>): Promise<T>;
|
|
4448
|
+
}
|
|
4449
|
+
/** Structural subset of by-peer's PeerChannel / a BroadcastChannel wrapper. */
|
|
4450
|
+
interface TabChannel {
|
|
4451
|
+
send(payload: string): void;
|
|
4452
|
+
on(event: 'message', listener: (payload: string) => void): Unsubscribe$1;
|
|
4453
|
+
on(event: 'close', listener: () => void): Unsubscribe$1;
|
|
4454
|
+
close(): void;
|
|
4455
|
+
readonly isOpen: boolean;
|
|
4456
|
+
}
|
|
4457
|
+
interface TabCoordinationOptions {
|
|
4458
|
+
readonly lockManager?: TabLockManager;
|
|
4459
|
+
readonly channel?: TabChannel;
|
|
4460
|
+
readonly tabId?: string;
|
|
4461
|
+
readonly lockName?: string;
|
|
4462
|
+
readonly heartbeatMs?: number;
|
|
4463
|
+
readonly staleMs?: number;
|
|
4464
|
+
readonly now?: () => number;
|
|
4465
|
+
/**
|
|
4466
|
+
* Close the channel on `dispose()`. Set this only for a channel the
|
|
4467
|
+
* coordinator owns (e.g. the one `defaultChannel()` created); leave it
|
|
4468
|
+
* false for a caller-injected channel so the coordinator never closes a
|
|
4469
|
+
* channel it didn't create. Default: false.
|
|
4470
|
+
*/
|
|
4471
|
+
readonly closeChannelOnDispose?: boolean;
|
|
4472
|
+
/**
|
|
4473
|
+
* Also propagate committed writes to other tabs. Default true:
|
|
4474
|
+
* when tab coordination is enabled and a channel is available, a write in
|
|
4475
|
+
* one tab refreshes that document in every other tab. Set false to opt out.
|
|
4476
|
+
*/
|
|
4477
|
+
readonly propagateWrites?: boolean;
|
|
4478
|
+
/**
|
|
4479
|
+
* Channel for write propagation — distinct from the presence
|
|
4480
|
+
* channel. Default: an inline BroadcastChannel on `noydb:tab-writes`.
|
|
4481
|
+
*/
|
|
4482
|
+
readonly writeChannel?: TabChannel;
|
|
4483
|
+
}
|
|
4484
|
+
|
|
4485
|
+
/**
|
|
4486
|
+
* Per-vault tier-3 (PIN / quick-resume) state.
|
|
3924
4487
|
*
|
|
3925
4488
|
* The hub holds a `PinResumeState`-shaped record in memory, keyed by
|
|
3926
4489
|
* vault. `enrollUnlock` populates it; `unlockViaPin` consumes it via
|
|
@@ -3967,6 +4530,69 @@ declare class QuickUnlockStore {
|
|
|
3967
4530
|
private clearTimer;
|
|
3968
4531
|
}
|
|
3969
4532
|
|
|
4533
|
+
/**
|
|
4534
|
+
* Cadence policy for automatic snapshots. Borrows the vocabulary of the sync
|
|
4535
|
+
* `SyncPolicy` (debounce / interval / minInterval / onUnload) but is a separate,
|
|
4536
|
+
* snapshot-specific shape — automatic snapshots write the single rolling
|
|
4537
|
+
* `<vault>__auto` key, never the immutable on-demand pool.
|
|
4538
|
+
*
|
|
4539
|
+
* Default mode is `'manual'`: no timers, snapshots stay on-demand.
|
|
4540
|
+
*/
|
|
4541
|
+
type SnapshotMode = 'manual' | 'debounce' | 'interval';
|
|
4542
|
+
interface SnapshotPolicy {
|
|
4543
|
+
/** Trigger mode. Default `'manual'` — no automatic snapshots. */
|
|
4544
|
+
readonly mode?: SnapshotMode;
|
|
4545
|
+
/** Idle delay (ms) after a write before an auto-snapshot fires. `mode:'debounce'`. Default 30_000. */
|
|
4546
|
+
readonly debounceMs?: number;
|
|
4547
|
+
/** Fixed interval (ms). `mode:'interval'`. Default 300_000. */
|
|
4548
|
+
readonly intervalMs?: number;
|
|
4549
|
+
/** Hard floor (ms) between auto-snapshots regardless of mode. Default 0. */
|
|
4550
|
+
readonly minIntervalMs?: number;
|
|
4551
|
+
/** Flush a pending auto-snapshot on tab-hide / process exit. Default true for non-manual modes. */
|
|
4552
|
+
readonly onUnload?: boolean;
|
|
4553
|
+
/** Label applied to each auto-snapshot. Default `'auto'`. */
|
|
4554
|
+
readonly label?: string;
|
|
4555
|
+
}
|
|
4556
|
+
|
|
4557
|
+
interface SnapshotMeta {
|
|
4558
|
+
readonly version: string;
|
|
4559
|
+
readonly label?: string;
|
|
4560
|
+
readonly note?: string;
|
|
4561
|
+
readonly exportedAt: string;
|
|
4562
|
+
readonly exportedBy: string;
|
|
4563
|
+
readonly size: number;
|
|
4564
|
+
/**
|
|
4565
|
+
* `'verified'` — bundle was produced by `writeNoydbBundle(vault, {})`, which embeds
|
|
4566
|
+
* ledgerHead metadata; `vault.load()` runs `verifyBackupIntegrity()` on restore.
|
|
4567
|
+
* `'legacy-unverifiable'` — reserved for v2 import paths that read pre-existing bundles
|
|
4568
|
+
* lacking a ledgerHead; not produced by the current engine.
|
|
4569
|
+
*/
|
|
4570
|
+
readonly integrity: 'verified' | 'legacy-unverifiable';
|
|
4571
|
+
/** `true` for the rolling auto-snapshot; absent on on-demand checkpoints. */
|
|
4572
|
+
readonly auto?: true;
|
|
4573
|
+
}
|
|
4574
|
+
interface RetentionPolicy {
|
|
4575
|
+
readonly keepLast?: number;
|
|
4576
|
+
readonly maxAgeDays?: number;
|
|
4577
|
+
readonly prune?: boolean;
|
|
4578
|
+
}
|
|
4579
|
+
/** @internal */
|
|
4580
|
+
interface SnapshotStrategy {
|
|
4581
|
+
snapshot(vault: unknown, by: string, opts?: {
|
|
4582
|
+
label?: string;
|
|
4583
|
+
note?: string;
|
|
4584
|
+
}): Promise<SnapshotMeta>;
|
|
4585
|
+
listSnapshots(vaultId: string): Promise<SnapshotMeta[]>;
|
|
4586
|
+
restoreSnapshot(vault: unknown, version: string): Promise<void>;
|
|
4587
|
+
/** Rolling auto-snapshot to the fixed `<vault>__auto` key. */
|
|
4588
|
+
autoSnapshot(vault: unknown, by: string, opts?: {
|
|
4589
|
+
label?: string;
|
|
4590
|
+
note?: string;
|
|
4591
|
+
}): Promise<SnapshotMeta>;
|
|
4592
|
+
/** Configured cadence policy. Undefined or `mode:'manual'` ⇒ no scheduler is wired. */
|
|
4593
|
+
readonly policy?: SnapshotPolicy;
|
|
4594
|
+
}
|
|
4595
|
+
|
|
3970
4596
|
/**
|
|
3971
4597
|
* Multi-record atomic transactions.
|
|
3972
4598
|
*
|
|
@@ -4036,7 +4662,7 @@ interface StagedOp {
|
|
|
4036
4662
|
expectedVersion?: number;
|
|
4037
4663
|
/**
|
|
4038
4664
|
* Optional human-readable tag forwarded to the resulting ledger
|
|
4039
|
-
* entry's `reason` field
|
|
4665
|
+
* entry's `reason` field. Set by callers via
|
|
4040
4666
|
* `tx.vault(v).collection(c).put(id, record, { reason })`.
|
|
4041
4667
|
*/
|
|
4042
4668
|
reason?: string;
|
|
@@ -4068,6 +4694,8 @@ interface AmendmentTxOptions {
|
|
|
4068
4694
|
* facade; its `put`/`delete`/`get` calls stage ops against the tx.
|
|
4069
4695
|
*/
|
|
4070
4696
|
declare class TxContext {
|
|
4697
|
+
/** Stable id for this transaction; shared by all writes it performs. */
|
|
4698
|
+
readonly txId: string;
|
|
4071
4699
|
/** @internal */
|
|
4072
4700
|
readonly _ops: StagedOp[];
|
|
4073
4701
|
/**
|
|
@@ -4076,7 +4704,7 @@ declare class TxContext {
|
|
|
4076
4704
|
* restore prior state via `revertExecuted`. Side-effect writes (e.g.
|
|
4077
4705
|
* recursive derivation outputs fired inside `Collection.put`) are
|
|
4078
4706
|
* appended here in execution order so they roll back alongside the
|
|
4079
|
-
* main staged ops
|
|
4707
|
+
* main staged ops.
|
|
4080
4708
|
*/
|
|
4081
4709
|
readonly _executed: ExecutedOp[];
|
|
4082
4710
|
/** @internal */
|
|
@@ -4148,12 +4776,40 @@ declare class TxCollection<T> {
|
|
|
4148
4776
|
* in `noydb.ts`. `Collection.putManyAtomic` runs its own Phase 2 loop
|
|
4149
4777
|
* but shares the `_activeTxContext` mechanism (and the `revertExecuted`
|
|
4150
4778
|
* helper) so nested side-effect derivation writes get registered for
|
|
4151
|
-
* revert alongside the bulk-put source ops
|
|
4779
|
+
* revert alongside the bulk-put source ops.
|
|
4152
4780
|
*/
|
|
4153
4781
|
declare function runTransaction<T>(db: Noydb, fn: (tx: TxContext) => Promise<T> | T, options?: AmendmentTxOptions): Promise<T>;
|
|
4154
4782
|
|
|
4155
4783
|
/**
|
|
4156
|
-
*
|
|
4784
|
+
* Dry-run transactions. Runs the tx body to STAGE ops, then builds
|
|
4785
|
+
* the directly-affected diff (before = current committed via collection.get,
|
|
4786
|
+
* after = staged record) and collects guard violations — without executing
|
|
4787
|
+
* phase 2. No adapter writes, no write-hooks, no commit. MV/derivation
|
|
4788
|
+
* cascade is NOT simulated (v2). Mirrors the guard loop in
|
|
4789
|
+
* `Collection.putInternal` — keep the two in sync.
|
|
4790
|
+
*/
|
|
4791
|
+
|
|
4792
|
+
interface AffectedDocument {
|
|
4793
|
+
readonly vault: string;
|
|
4794
|
+
readonly op: 'create' | 'update' | 'delete';
|
|
4795
|
+
readonly collection: string;
|
|
4796
|
+
readonly docId: string;
|
|
4797
|
+
readonly before: unknown;
|
|
4798
|
+
readonly after: unknown;
|
|
4799
|
+
}
|
|
4800
|
+
interface GuardViolation {
|
|
4801
|
+
readonly vault: string;
|
|
4802
|
+
readonly collection: string;
|
|
4803
|
+
readonly docId: string;
|
|
4804
|
+
readonly message: string;
|
|
4805
|
+
}
|
|
4806
|
+
interface DryRunResult {
|
|
4807
|
+
readonly affected: ReadonlyArray<AffectedDocument>;
|
|
4808
|
+
readonly guardViolations: ReadonlyArray<GuardViolation>;
|
|
4809
|
+
}
|
|
4810
|
+
|
|
4811
|
+
/**
|
|
4812
|
+
* Policy gate DSL types.
|
|
4157
4813
|
*
|
|
4158
4814
|
* Sensitive operations (rotate the passphrase, enroll an authenticator,
|
|
4159
4815
|
* export plaintext, grant a user, …) are gated by a typed policy
|
|
@@ -4187,12 +4843,10 @@ declare function runTransaction<T>(db: Noydb, fn: (tx: TxContext) => Promise<T>
|
|
|
4187
4843
|
* devices — policies can require ANY of them or insist on a count of 2
|
|
4188
4844
|
* to force a mix.
|
|
4189
4845
|
*
|
|
4190
|
-
*
|
|
4191
|
-
*
|
|
4192
|
-
*
|
|
4193
|
-
*
|
|
4194
|
-
* pin "any second factor I have wired" without losing the freshness
|
|
4195
|
-
* guarantee.
|
|
4846
|
+
* `webauthn-platform`, `password`, `pin` — for consumers with no
|
|
4847
|
+
* off-device infrastructure (no TOTP, no email-OTP, paper recovery not
|
|
4848
|
+
* enrolled) who want to require "any second factor I have wired"
|
|
4849
|
+
* without losing the freshness guarantee.
|
|
4196
4850
|
*/
|
|
4197
4851
|
type FactorKind = 'totp' | 'email-otp' | 'recovery' | 'shamir' | 'webauthn-roaming' | 'webauthn-platform' | 'password' | 'pin';
|
|
4198
4852
|
/**
|
|
@@ -4236,7 +4890,7 @@ interface GatePolicy {
|
|
|
4236
4890
|
type BuiltInGateName = 'rotate-passphrase' | 'recover-passphrase' | 'enroll-authenticator' | 'remove-authenticator'
|
|
4237
4891
|
/**
|
|
4238
4892
|
* Authorize a deliberate paper-recovery-code regeneration —
|
|
4239
|
-
* `db.rotateRecovery
|
|
4893
|
+
* `db.rotateRecovery`. Symmetric to `rotate-passphrase` for
|
|
4240
4894
|
* the case where the user remembers their passphrase but wants a
|
|
4241
4895
|
* fresh sheet (lost the printout, suspect compromise of the off-site
|
|
4242
4896
|
* copy). PERSONAL allows tier-1; STRICT requires an off-device
|
|
@@ -4246,19 +4900,19 @@ type BuiltInGateName = 'rotate-passphrase' | 'recover-passphrase' | 'enroll-auth
|
|
|
4246
4900
|
| 'rotate-recovery'
|
|
4247
4901
|
/**
|
|
4248
4902
|
* Authorize a meta-only mutation on an existing authenticator slot —
|
|
4249
|
-
* `db.updateAuthenticator
|
|
4903
|
+
* `db.updateAuthenticator`. The slot's wrap material, id, and
|
|
4250
4904
|
* method are immutable through this gate; only the `meta` blob
|
|
4251
4905
|
* (nicknames, method-specific labels) can change. Anti-slot-swap
|
|
4252
4906
|
* guard is preserved structurally regardless of this gate's
|
|
4253
4907
|
* settings.
|
|
4254
4908
|
*/
|
|
4255
4909
|
| 'update-authenticator' | 'rotate-unlock' | 'enroll-user' | 'revoke-user' | 'export-bundle' | 'export-plaintext' | 'view-user-auth'
|
|
4256
|
-
/** Authorize a write to one's own user envelope
|
|
4910
|
+
/** Authorize a write to one's own user envelope. */
|
|
4257
4911
|
| 'edit-own-profile'
|
|
4258
|
-
/** Authorize reading other principals' user envelopes
|
|
4912
|
+
/** Authorize reading other principals' user envelopes. */
|
|
4259
4913
|
| 'view-team-profiles'
|
|
4260
4914
|
/**
|
|
4261
|
-
* Authorize an atomic peer-recovery — `db.recoverUser
|
|
4915
|
+
* Authorize an atomic peer-recovery — `db.recoverUser`.
|
|
4262
4916
|
* Distinct from `revoke-user` because peer-recovery is intentional
|
|
4263
4917
|
* re-issuance of someone's keyring under a temp passphrase, NOT
|
|
4264
4918
|
* removal. Allows owner→owner natively (matches the threat model:
|
|
@@ -4268,7 +4922,7 @@ type BuiltInGateName = 'rotate-passphrase' | 'recover-passphrase' | 'enroll-auth
|
|
|
4268
4922
|
*/
|
|
4269
4923
|
| 'peer-recover-user'
|
|
4270
4924
|
/**
|
|
4271
|
-
* Authorize a post-grant identity mutation — `db.updateUser
|
|
4925
|
+
* Authorize a post-grant identity mutation — `db.updateUser`.
|
|
4272
4926
|
* Covers `role`, `displayName`, `permissions` changes on an existing
|
|
4273
4927
|
* keyring. Pure plaintext-header rewrite — no DEKs touched, no KEK
|
|
4274
4928
|
* required. The role-elevation guard inside the implementation
|
|
@@ -4281,7 +4935,7 @@ type GateName = BuiltInGateName | `app:${string}`;
|
|
|
4281
4935
|
/**
|
|
4282
4936
|
* Top-level policy object. Persisted at `_meta/policy` once at vault
|
|
4283
4937
|
* creation. The `passphrase` block configures the strength rules
|
|
4284
|
-
* applied at every passphrase ingress
|
|
4938
|
+
* applied at every passphrase ingress; `gates` configures
|
|
4285
4939
|
* the action-level requirements.
|
|
4286
4940
|
*/
|
|
4287
4941
|
interface VaultPolicy {
|
|
@@ -4305,7 +4959,7 @@ interface FactorProof {
|
|
|
4305
4959
|
* `db.recoverUser`, `db.enrollUnlock`, `db.describeUserAuth`,
|
|
4306
4960
|
* `db.describeAllUsersAuth`.
|
|
4307
4961
|
*
|
|
4308
|
-
*
|
|
4962
|
+
* Previously this type was inlined at every call site as
|
|
4309
4963
|
* `{ factors?: ReadonlyArray<FactorProof>; sharedDevice?: boolean }`
|
|
4310
4964
|
* and parameter names alternated between `factors` and `presented`.
|
|
4311
4965
|
* Now exported so consumers can name their helpers and so the param
|
|
@@ -4320,14 +4974,19 @@ type ActiveTier = 1 | 2 | 3;
|
|
|
4320
4974
|
|
|
4321
4975
|
/** The top-level NOYDB instance. */
|
|
4322
4976
|
declare class Noydb {
|
|
4977
|
+
#private;
|
|
4323
4978
|
private readonly options;
|
|
4324
4979
|
private readonly emitter;
|
|
4980
|
+
private readonly writeQueueTracker;
|
|
4981
|
+
private readonly writeHooks;
|
|
4982
|
+
private readonly subsystemBus;
|
|
4983
|
+
private readonly clientId;
|
|
4325
4984
|
private readonly vaultCache;
|
|
4326
4985
|
private readonly keyringCache;
|
|
4327
4986
|
private readonly syncEngines;
|
|
4328
4987
|
/**
|
|
4329
4988
|
* Per-vault active session tier — defaults to `1` after a passphrase
|
|
4330
|
-
* unlock; tier-2 / tier-3 unlocks
|
|
4989
|
+
* unlock; tier-2 / tier-3 unlocks downgrade it. Used by
|
|
4331
4990
|
* {@link checkGate} to evaluate `gate.minTier`.
|
|
4332
4991
|
*/
|
|
4333
4992
|
private readonly activeTier;
|
|
@@ -4337,14 +4996,14 @@ declare class Noydb {
|
|
|
4337
4996
|
*/
|
|
4338
4997
|
private readonly policyCache;
|
|
4339
4998
|
/**
|
|
4340
|
-
* One-shot bypass for the managed-mode strong-recovery check
|
|
4999
|
+
* One-shot bypass for the managed-mode strong-recovery check.
|
|
4341
5000
|
* Set true by {@link openVaultAndEnrollRecovery} for the duration of
|
|
4342
5001
|
* the bootstrap window so the keyring can be created before the
|
|
4343
5002
|
* strong recovery is enrolled. Always cleared (try/finally).
|
|
4344
5003
|
* @internal
|
|
4345
5004
|
*/
|
|
4346
5005
|
private _skipNextManagedRecoveryCheck;
|
|
4347
|
-
/** Per-vault tier-3 (PIN / quick-resume) state
|
|
5006
|
+
/** Per-vault tier-3 (PIN / quick-resume) state. */
|
|
4348
5007
|
private readonly quickUnlock;
|
|
4349
5008
|
/**
|
|
4350
5009
|
* Resolved public-envelope schema. Lazily computed once from
|
|
@@ -4354,19 +5013,26 @@ declare class Noydb {
|
|
|
4354
5013
|
private readonly publicEnvelopeSchema;
|
|
4355
5014
|
private closed;
|
|
4356
5015
|
private sessionTimer;
|
|
5016
|
+
/** Same-device multi-tab coordinator; created on `enableTabCoordination()`. */
|
|
5017
|
+
private tabCoordinator;
|
|
5018
|
+
/** Cross-tab write relay; created on `enableTabCoordination()`. */
|
|
5019
|
+
private writeRelay;
|
|
4357
5020
|
/** Per-vault policy enforcers. */
|
|
4358
5021
|
private readonly policyEnforcers;
|
|
4359
5022
|
private readonly txStrategy;
|
|
4360
5023
|
private readonly sessionStrategy;
|
|
4361
5024
|
private readonly syncStrategy;
|
|
5025
|
+
private readonly snapshotStrategy;
|
|
5026
|
+
private snapshotScheduler;
|
|
5027
|
+
private readonly dirtySnapshotVaults;
|
|
4362
5028
|
/**
|
|
4363
5029
|
* Currently-running multi-record transaction, set by
|
|
4364
5030
|
* `runTransaction` at the start of Phase 2 (commit) and cleared in
|
|
4365
5031
|
* the same function's `finally` block. Side-effect writes triggered
|
|
4366
5032
|
* during a staged op's `Collection.put` (today: eager derivation
|
|
4367
5033
|
* outputs) register their pre-write envelope on `_executed` here so
|
|
4368
|
-
* a mid-batch failure rolls them back alongside the main staged ops
|
|
4369
|
-
*
|
|
5034
|
+
* a mid-batch failure rolls them back alongside the main staged ops.
|
|
5035
|
+
* `null` outside of Phase 2.
|
|
4370
5036
|
* @internal
|
|
4371
5037
|
*/
|
|
4372
5038
|
private _activeTxContext;
|
|
@@ -4469,8 +5135,6 @@ declare class Noydb {
|
|
|
4469
5135
|
* @throws `NoAccessError` when no keyring exists for the target.
|
|
4470
5136
|
* @throws `PermissionDeniedError` when the role hierarchy rejects.
|
|
4471
5137
|
* @throws `ValidationError` when no field is provided.
|
|
4472
|
-
*
|
|
4473
|
-
* @see #54
|
|
4474
5138
|
*/
|
|
4475
5139
|
updateUser(vault: string, options: UpdateUserOptions, factors?: FactorProofBundle): Promise<void>;
|
|
4476
5140
|
/**
|
|
@@ -4657,6 +5321,15 @@ declare class Noydb {
|
|
|
4657
5321
|
* to the vault's ledger as `op: 'amendment'`.
|
|
4658
5322
|
*/
|
|
4659
5323
|
transaction<T>(options: AmendmentTxOptions, fn: (tx: TxContext) => Promise<T> | T): Promise<T>;
|
|
5324
|
+
/**
|
|
5325
|
+
* Dry-run a transaction: run the body to stage ops, then return
|
|
5326
|
+
* the directly-affected diff + collected guard violations WITHOUT
|
|
5327
|
+
* committing (no adapter writes, no write hooks). MV/derivation cascade
|
|
5328
|
+
* is not simulated. Requires `withTransactions()`.
|
|
5329
|
+
*/
|
|
5330
|
+
transaction(options: {
|
|
5331
|
+
readonly dryRun: true;
|
|
5332
|
+
}, fn: (tx: TxContext) => unknown): Promise<DryRunResult>;
|
|
4660
5333
|
/**
|
|
4661
5334
|
* Create a sync transaction for the given vault.
|
|
4662
5335
|
* The vault must already be open via `openVault()`.
|
|
@@ -4677,7 +5350,7 @@ declare class Noydb {
|
|
|
4677
5350
|
* Phase 2. `Collection.dispatchDerivations` consults this so a
|
|
4678
5351
|
* recursive derived-output write inside `Collection.put` can register
|
|
4679
5352
|
* its envelope onto `ctx._executed` and roll back with the main
|
|
4680
|
-
* staged ops on mid-batch failure
|
|
5353
|
+
* staged ops on mid-batch failure.
|
|
4681
5354
|
*
|
|
4682
5355
|
* @internal
|
|
4683
5356
|
*/
|
|
@@ -4702,7 +5375,7 @@ declare class Noydb {
|
|
|
4702
5375
|
* `Collection.putManyAtomic` (via `derivationSource.createTxContext`)
|
|
4703
5376
|
* to publish an active context for the duration of its bulk-atomic
|
|
4704
5377
|
* Phase 2 loop, so recursive derivation-output writes register on
|
|
4705
|
-
* `ctx._executed` and roll back together with the source ops
|
|
5378
|
+
* `ctx._executed` and roll back together with the source ops.
|
|
4706
5379
|
*
|
|
4707
5380
|
* @internal
|
|
4708
5381
|
*/
|
|
@@ -4721,6 +5394,54 @@ declare class Noydb {
|
|
|
4721
5394
|
private getSyncEngine;
|
|
4722
5395
|
on<K extends keyof NoydbEventMap>(event: K, handler: (data: NoydbEventMap[K]) => void): void;
|
|
4723
5396
|
off<K extends keyof NoydbEventMap>(event: K, handler: (data: NoydbEventMap[K]) => void): void;
|
|
5397
|
+
/**
|
|
5398
|
+
* Observable write-queue for this hub instance. Reflects outstanding
|
|
5399
|
+
* in-flight writes across all collections. See {@link WriteQueue}.
|
|
5400
|
+
*
|
|
5401
|
+
* @example
|
|
5402
|
+
* window.addEventListener('beforeunload', (e) => {
|
|
5403
|
+
* if (db.writeQueue.pending) { e.preventDefault(); e.returnValue = '' }
|
|
5404
|
+
* })
|
|
5405
|
+
*/
|
|
5406
|
+
get writeQueue(): WriteQueue;
|
|
5407
|
+
/**
|
|
5408
|
+
* @internal Mutable tracker behind {@link writeQueue}. Threaded into
|
|
5409
|
+
* each Collection (via Vault) so `put`/`delete` can `track()` writes.
|
|
5410
|
+
* Not part of the public surface — consumers use `writeQueue`.
|
|
5411
|
+
*/
|
|
5412
|
+
get _writeQueueTracker(): WriteQueueTracker;
|
|
5413
|
+
/**
|
|
5414
|
+
* Register a hook that runs before each write. Awaited; a throw
|
|
5415
|
+
* aborts the write. Returns an unsubscribe function.
|
|
5416
|
+
*/
|
|
5417
|
+
onBeforeWrite(handler: WriteHook): Unsubscribe$3;
|
|
5418
|
+
/**
|
|
5419
|
+
* Register a hook that runs after each committed write. Awaited;
|
|
5420
|
+
* a handler error is warned, never rolled back. Returns an unsubscribe fn.
|
|
5421
|
+
*/
|
|
5422
|
+
onAfterWrite(handler: WriteHook): Unsubscribe$3;
|
|
5423
|
+
/** Subscribe to cross-tab write conflicts. Returns an unsubscribe. */
|
|
5424
|
+
onWriteConflict(fn: (c: WriteConflict) => void): Unsubscribe$3;
|
|
5425
|
+
/**
|
|
5426
|
+
* Enable same-device multi-tab coordination: primary/secondary
|
|
5427
|
+
* election + presence. Browser-only — a graceful no-op (role 'unknown')
|
|
5428
|
+
* when Web Locks / BroadcastChannel are unavailable and nothing is
|
|
5429
|
+
* injected. Idempotent; returns a disposer.
|
|
5430
|
+
*/
|
|
5431
|
+
enableTabCoordination(opts?: TabCoordinationOptions): {
|
|
5432
|
+
dispose: () => void;
|
|
5433
|
+
};
|
|
5434
|
+
private disableTabCoordination;
|
|
5435
|
+
get tabRole(): TabRole;
|
|
5436
|
+
activeTabs(): TabPresence[];
|
|
5437
|
+
onTabRoleChange(fn: (r: TabRole) => void): Unsubscribe$3;
|
|
5438
|
+
onActiveTabsChange(fn: (t: TabPresence[]) => void): Unsubscribe$3;
|
|
5439
|
+
/** @internal The write-hook registry, threaded into each Collection. */
|
|
5440
|
+
get _writeHooks(): WriteHookRegistry;
|
|
5441
|
+
/** @internal The observe bus, threaded into every Collection. */
|
|
5442
|
+
get _subsystemBus(): SubsystemBus;
|
|
5443
|
+
/** @internal Stable per-instance id for schema-cutover coordination. */
|
|
5444
|
+
get _clientId(): string;
|
|
4724
5445
|
/**
|
|
4725
5446
|
* Soft-lock a single vault: clear its in-memory keyring, DEKs, vault
|
|
4726
5447
|
* instance, sync engine, policy enforcer, and active-tier entry —
|
|
@@ -4737,10 +5458,6 @@ declare class Noydb {
|
|
|
4737
5458
|
* survives lock; nothing about it changes when DEKs are scrubbed).
|
|
4738
5459
|
*
|
|
4739
5460
|
* No-op when `vault` is not currently in cache (idempotent).
|
|
4740
|
-
*
|
|
4741
|
-
* Unblocks vLannaAi/niwat#33.
|
|
4742
|
-
*
|
|
4743
|
-
* @see #17
|
|
4744
5461
|
*/
|
|
4745
5462
|
lockVault(vault: string): void;
|
|
4746
5463
|
close(): void;
|
|
@@ -4774,7 +5491,7 @@ declare class Noydb {
|
|
|
4774
5491
|
*/
|
|
4775
5492
|
updatePolicy(vault: string, override: Partial<VaultPolicy>): Promise<VaultPolicy>;
|
|
4776
5493
|
/**
|
|
4777
|
-
* Read the current vault-level user-directory toggle
|
|
5494
|
+
* Read the current vault-level user-directory toggle. Returns
|
|
4778
5495
|
* the default-on shape (`{ enabled: true }`) when no `_meta/directory`
|
|
4779
5496
|
* document has been persisted yet.
|
|
4780
5497
|
*
|
|
@@ -4782,7 +5499,7 @@ declare class Noydb {
|
|
|
4782
5499
|
*/
|
|
4783
5500
|
getDirectoryEnabled(vault: string): Promise<boolean>;
|
|
4784
5501
|
/**
|
|
4785
|
-
* Toggle the vault's user-directory listing on or off
|
|
5502
|
+
* Toggle the vault's user-directory listing on or off.
|
|
4786
5503
|
* Owner-only. When disabled, `listUsersWithEnvelopes()` throws
|
|
4787
5504
|
* {@link import('./errors.js').DirectoryDisabledError} for callers
|
|
4788
5505
|
* whose role is neither `owner` nor `admin`.
|
|
@@ -4814,7 +5531,7 @@ declare class Noydb {
|
|
|
4814
5531
|
*
|
|
4815
5532
|
* Two enforcement modes:
|
|
4816
5533
|
*
|
|
4817
|
-
* 1. **Managed-mode mandatory strong-recovery
|
|
5534
|
+
* 1. **Managed-mode mandatory strong-recovery.** When
|
|
4818
5535
|
* `passphraseMode === 'managed'`, the vault MUST have at least
|
|
4819
5536
|
* one **strong** recovery profile (Shamir today). Paper alone is
|
|
4820
5537
|
* rejected because under managed mode the user has no memorized
|
|
@@ -4834,7 +5551,7 @@ declare class Noydb {
|
|
|
4834
5551
|
*/
|
|
4835
5552
|
private assertRecoveryEnrolled;
|
|
4836
5553
|
/**
|
|
4837
|
-
* Internal accessor used by tier-2/tier-3 unlock paths
|
|
5554
|
+
* Internal accessor used by tier-2/tier-3 unlock paths
|
|
4838
5555
|
* to mark the active session tier.
|
|
4839
5556
|
* @internal
|
|
4840
5557
|
*/
|
|
@@ -4858,7 +5575,7 @@ declare class Noydb {
|
|
|
4858
5575
|
* `remove-authenticator`.
|
|
4859
5576
|
*/
|
|
4860
5577
|
removeAuthenticator(vault: string, slotId: string, factors?: FactorProofBundle): Promise<void>;
|
|
4861
|
-
/** Read the slot list for a vault. Internal — `describeAuthConfig`
|
|
5578
|
+
/** Read the slot list for a vault. Internal — `describeAuthConfig` consumes this. */
|
|
4862
5579
|
listAuthenticators(vault: string): Promise<ReadonlyArray<KeyringAuthenticator>>;
|
|
4863
5580
|
/**
|
|
4864
5581
|
* Mutate the `meta` blob on an existing authenticator slot — slot
|
|
@@ -4867,7 +5584,7 @@ declare class Noydb {
|
|
|
4867
5584
|
* are immutable through this method. Anti-slot-swap is structural,
|
|
4868
5585
|
* not gate-driven.
|
|
4869
5586
|
*
|
|
4870
|
-
* `meta` patch semantics (
|
|
5587
|
+
* `meta` patch semantics (top-level merge):
|
|
4871
5588
|
* - Top-level merge — absent keys preserved
|
|
4872
5589
|
* - `null` value — delete that meta key
|
|
4873
5590
|
* - Other values — replace verbatim
|
|
@@ -4885,12 +5602,10 @@ declare class Noydb {
|
|
|
4885
5602
|
*
|
|
4886
5603
|
* @throws `NoAccessError` when no slot with the given id exists.
|
|
4887
5604
|
* @throws `ValidationError` when no patch field is provided.
|
|
4888
|
-
*
|
|
4889
|
-
* @see #55
|
|
4890
5605
|
*/
|
|
4891
5606
|
updateAuthenticator(vault: string, slotId: string, options: UpdateAuthenticatorOptions, factors?: FactorProofBundle): Promise<void>;
|
|
4892
5607
|
/**
|
|
4893
|
-
* Native WebAuthn enrollment using the **real** internal keyring
|
|
5608
|
+
* Native WebAuthn enrollment using the **real** internal keyring.
|
|
4894
5609
|
*
|
|
4895
5610
|
* Why this exists: when a consumer is using `createNoydb({ secret })`,
|
|
4896
5611
|
* they cannot reach the live `UnlockedKeyring` to feed it to
|
|
@@ -4933,8 +5648,6 @@ declare class Noydb {
|
|
|
4933
5648
|
* a server-side allowlist).
|
|
4934
5649
|
*
|
|
4935
5650
|
* Gated by `enroll-authenticator` like `enrollAuthenticator()` itself.
|
|
4936
|
-
*
|
|
4937
|
-
* @see #16
|
|
4938
5651
|
*/
|
|
4939
5652
|
enrollWebAuthn(vault: string, ceremony: (keyring: UnlockedKeyring) => Promise<EnrollAuthenticatorOptions>, factors?: FactorProofBundle): Promise<{
|
|
4940
5653
|
credentialId: string;
|
|
@@ -4945,8 +5658,6 @@ declare class Noydb {
|
|
|
4945
5658
|
* deciding when a new device prompt should appear. Identity is
|
|
4946
5659
|
* `id` + `enrolled_at`; the `meta.credentialId` (base64) is used by
|
|
4947
5660
|
* `allowCredentials` at unlock time.
|
|
4948
|
-
*
|
|
4949
|
-
* @see #16
|
|
4950
5661
|
*/
|
|
4951
5662
|
listWebAuthnSlots(vault: string): Promise<ReadonlyArray<{
|
|
4952
5663
|
id: string;
|
|
@@ -5010,8 +5721,7 @@ declare class Noydb {
|
|
|
5010
5721
|
*
|
|
5011
5722
|
* Tier-2 authenticator slots are dropped — each slot wraps the old
|
|
5012
5723
|
* KEK and would need its derivation key to be re-presented. Re-enrol
|
|
5013
|
-
* via `db.enrollAuthenticator` after rotation.
|
|
5014
|
-
* v0.1.0-pre.5 limitation.
|
|
5724
|
+
* via `db.enrollAuthenticator` after rotation.
|
|
5015
5725
|
*
|
|
5016
5726
|
* @throws `WeakPassphraseError` on a weak new phrase.
|
|
5017
5727
|
* @throws `PolicyDeniedError` when the gate denies (missing factor, …).
|
|
@@ -5020,14 +5730,14 @@ declare class Noydb {
|
|
|
5020
5730
|
rotatePassphrase(vault: string, input: RotatePassphraseInput, factors?: FactorProofBundle): Promise<void>;
|
|
5021
5731
|
/**
|
|
5022
5732
|
* Reset the passphrase using a recovery proof (user forgot the old).
|
|
5023
|
-
*
|
|
5024
|
-
* other
|
|
5733
|
+
* Currently supports the `'paper'` profile end-to-end; the
|
|
5734
|
+
* other profiles throw {@link RecoveryProfileNotImplementedError}.
|
|
5025
5735
|
*
|
|
5026
5736
|
* Burns the used recovery entry on success.
|
|
5027
5737
|
*/
|
|
5028
5738
|
recoverPassphrase(vault: string, input: RecoverPassphraseInput, factors?: FactorProofBundle): Promise<RecoverPassphraseResult>;
|
|
5029
5739
|
/**
|
|
5030
|
-
* Deliberate paper-recovery-code regeneration
|
|
5740
|
+
* Deliberate paper-recovery-code regeneration. User knows their
|
|
5031
5741
|
* passphrase but wants a fresh sheet — they lost the printout or
|
|
5032
5742
|
* suspect compromise of the off-site copy.
|
|
5033
5743
|
*
|
|
@@ -5037,7 +5747,7 @@ declare class Noydb {
|
|
|
5037
5747
|
*
|
|
5038
5748
|
* Gated by the `rotate-recovery` policy gate:
|
|
5039
5749
|
* - PERSONAL_POLICY: `{ minTier: 1 }` — knowing the passphrase
|
|
5040
|
-
* suffices, matching the
|
|
5750
|
+
* suffices, matching the lower-level flow's bar.
|
|
5041
5751
|
* - STRICT_POLICY: `{ minTier: 1, factors: [{ anyOf: ['totp',
|
|
5042
5752
|
* 'email-otp', 'webauthn-roaming'] }] }` — rotation is an
|
|
5043
5753
|
* off-site-trust event; require an off-device factor so a
|
|
@@ -5073,7 +5783,7 @@ declare class Noydb {
|
|
|
5073
5783
|
private rotateRecoveryPaper;
|
|
5074
5784
|
private rotateRecoveryShamir;
|
|
5075
5785
|
/**
|
|
5076
|
-
* **Atomic create-and-enroll for managed-mode vaults
|
|
5786
|
+
* **Atomic create-and-enroll for managed-mode vaults.**
|
|
5077
5787
|
*
|
|
5078
5788
|
* Bootstraps a managed-mode vault and enrolls strong recovery in
|
|
5079
5789
|
* a single ceremony. Under `passphraseMode: 'managed'`, every
|
|
@@ -5118,7 +5828,7 @@ declare class Noydb {
|
|
|
5118
5828
|
readonly recoveryEnrollments: ReadonlyArray<EnrollRecoveryResult>;
|
|
5119
5829
|
}>;
|
|
5120
5830
|
/**
|
|
5121
|
-
* **Recovery flow under managed-passphrase mode
|
|
5831
|
+
* **Recovery flow under managed-passphrase mode.**
|
|
5122
5832
|
*
|
|
5123
5833
|
* Replaces the sealed passphrase of a managed-mode vault with a
|
|
5124
5834
|
* fresh 256-bit random, sealed under the configured
|
|
@@ -5135,7 +5845,7 @@ declare class Noydb {
|
|
|
5135
5845
|
* 5. Drop the keyring cache so the next operation re-derives.
|
|
5136
5846
|
*
|
|
5137
5847
|
* The vault's strong-recovery enrollment is preserved across
|
|
5138
|
-
* recovery (Shamir entries are not burned on use
|
|
5848
|
+
* recovery (Shamir entries are not burned on use).
|
|
5139
5849
|
*
|
|
5140
5850
|
* @throws ValidationError if the Noydb instance is not in managed mode.
|
|
5141
5851
|
*/
|
|
@@ -5145,7 +5855,7 @@ declare class Noydb {
|
|
|
5145
5855
|
}): Promise<void>;
|
|
5146
5856
|
/**
|
|
5147
5857
|
* Atomic peer-recovery — re-wraps an EXISTING user's keyring under
|
|
5148
|
-
* a fresh temp passphrase in a single store write. Closes
|
|
5858
|
+
* a fresh temp passphrase in a single store write. Closes the
|
|
5149
5859
|
* partial-failure window (the previous compose-from-primitives
|
|
5150
5860
|
* pattern was `db.revoke + db.grant`, two writes — if the issuer
|
|
5151
5861
|
* cancelled between them the target was locked out entirely).
|
|
@@ -5155,7 +5865,7 @@ declare class Noydb {
|
|
|
5155
5865
|
* - Same `userId`, role, permissions, capabilities preserved.
|
|
5156
5866
|
* - DEKs unchanged → every other principal in the vault keeps
|
|
5157
5867
|
* access. No key rotation.
|
|
5158
|
-
* - Allows owner→owner natively
|
|
5868
|
+
* - Allows owner→owner natively. The existing
|
|
5159
5869
|
* `db.revoke` retains its block — peer-recovery is a separate,
|
|
5160
5870
|
* intentionally-named operation.
|
|
5161
5871
|
* - Tier-2 slots dropped (they wrap the old KEK).
|
|
@@ -5184,11 +5894,10 @@ declare class Noydb {
|
|
|
5184
5894
|
* @throws `PrivilegeEscalationError` when the caller lacks a DEK
|
|
5185
5895
|
* the target previously had access to.
|
|
5186
5896
|
*
|
|
5187
|
-
* @see #33 #34 — the issues this method closes.
|
|
5188
5897
|
*/
|
|
5189
5898
|
recoverUser(vault: string, options: RecoverUserOptions, factors?: FactorProofBundle): Promise<void>;
|
|
5190
5899
|
/**
|
|
5191
|
-
* Persist a recovery enrollment.
|
|
5900
|
+
* Persist a recovery enrollment. Accepts the `'paper'`
|
|
5192
5901
|
* profile.
|
|
5193
5902
|
*
|
|
5194
5903
|
* The hub wraps the user's DEK set (not the KEK) under a code-derived
|
|
@@ -5208,7 +5917,7 @@ declare class Noydb {
|
|
|
5208
5917
|
* showCodesToUser(codes)
|
|
5209
5918
|
* ```
|
|
5210
5919
|
*
|
|
5211
|
-
*
|
|
5920
|
+
* `@noy-db/on-recovery`'s `generateRecoveryCodeSet`
|
|
5212
5921
|
* delegates to `mintPaperRecoveryEntry` internally — its output is
|
|
5213
5922
|
* fed directly to this API. Pick whichever fits your code-gen layer:
|
|
5214
5923
|
*
|
|
@@ -5219,7 +5928,7 @@ declare class Noydb {
|
|
|
5219
5928
|
* ```
|
|
5220
5929
|
*/
|
|
5221
5930
|
enrollRecovery(vault: string, enrollment: RecoveryEnrollmentInput): Promise<EnrollRecoveryResult>;
|
|
5222
|
-
/** Read the persisted recovery entries (paper + Shamir). Used by `describeAuthConfig
|
|
5931
|
+
/** Read the persisted recovery entries (paper + Shamir). Used by `describeAuthConfig`. */
|
|
5223
5932
|
listRecoveryEntries(vault: string): Promise<{
|
|
5224
5933
|
paper: ReadonlyArray<PaperRecoveryEntry>;
|
|
5225
5934
|
shamir: ReadonlyArray<ShamirRecoveryEntry>;
|
|
@@ -5247,11 +5956,11 @@ declare class Noydb {
|
|
|
5247
5956
|
/** Drop the tier-3 state for a vault — explicit logout. */
|
|
5248
5957
|
clearQuickUnlock(vault: string): void;
|
|
5249
5958
|
/**
|
|
5250
|
-
* Public accessor for the unlocked keyring of a vault
|
|
5959
|
+
* Public accessor for the unlocked keyring of a vault.
|
|
5251
5960
|
*
|
|
5252
5961
|
* Returns a **defensive shallow copy** so consumers can read the DEK
|
|
5253
5962
|
* map and authenticator list without the risk of mutating the hub's
|
|
5254
|
-
* internal cache
|
|
5963
|
+
* internal cache. Internal hub code paths use a live reference
|
|
5255
5964
|
* via `getKeyringInternal`; ceremonies and external consumers always
|
|
5256
5965
|
* get a snapshot.
|
|
5257
5966
|
*
|
|
@@ -5287,6 +5996,34 @@ declare class Noydb {
|
|
|
5287
5996
|
* should use {@link getKeyring}, which returns a defensive copy.
|
|
5288
5997
|
*/
|
|
5289
5998
|
private getKeyringInternal;
|
|
5999
|
+
/**
|
|
6000
|
+
* Take an on-demand checkpoint of the given vault.
|
|
6001
|
+
* Requires `snapshotStrategy: withSnapshots({ store })` in `createNoydb`.
|
|
6002
|
+
* @throws ValidationError when the vault is not open
|
|
6003
|
+
*/
|
|
6004
|
+
snapshot(vault: string, opts?: {
|
|
6005
|
+
label?: string;
|
|
6006
|
+
note?: string;
|
|
6007
|
+
}): Promise<SnapshotMeta>;
|
|
6008
|
+
/**
|
|
6009
|
+
* Wire the automatic-snapshot cadence when a non-manual `snapshotPolicy` is
|
|
6010
|
+
* configured. Subscribes to `onAfterWrite` to mark the written vault dirty and
|
|
6011
|
+
* nudge the scheduler; the scheduler fires `autoSnapshot()` per dirty vault.
|
|
6012
|
+
* No-op for `mode:'manual'` or no policy.
|
|
6013
|
+
*/
|
|
6014
|
+
private initSnapshotCadence;
|
|
6015
|
+
/**
|
|
6016
|
+
* List all snapshots for the given vault, newest first.
|
|
6017
|
+
* Reads only the sidecar index — does not download snapshot bytes.
|
|
6018
|
+
*/
|
|
6019
|
+
listSnapshots(vault: string): Promise<SnapshotMeta[]>;
|
|
6020
|
+
/**
|
|
6021
|
+
* Restore the vault to a previously snapshotted state.
|
|
6022
|
+
* Runs `verifyBackupIntegrity()` automatically on restore.
|
|
6023
|
+
* @throws SnapshotNotFoundError when `version` doesn't exist in the store
|
|
6024
|
+
* @throws ValidationError when the vault is not open
|
|
6025
|
+
*/
|
|
6026
|
+
restoreSnapshot(vault: string, version: string): Promise<void>;
|
|
5290
6027
|
}
|
|
5291
6028
|
/** Create a new NOYDB instance. */
|
|
5292
6029
|
declare function createNoydb(options: NoydbOptions): Promise<Noydb>;
|
|
@@ -5492,8 +6229,8 @@ interface GuardStrategy<T extends Record<string, unknown>> {
|
|
|
5492
6229
|
* })
|
|
5493
6230
|
* ```
|
|
5494
6231
|
*
|
|
5495
|
-
* Also skipped on system-internal deletes (derivation tombstones
|
|
5496
|
-
*
|
|
6232
|
+
* Also skipped on system-internal deletes (derivation tombstones,
|
|
6233
|
+
* MV refresh from Dim 14 v2) — those use `_internalDelete`
|
|
5497
6234
|
* which bypasses every user-facing delete hook. Housekeeping ops are
|
|
5498
6235
|
* NOT user-initiated and should not trip user invariants.
|
|
5499
6236
|
*
|
|
@@ -5552,14 +6289,14 @@ interface RecordOutputSpec {
|
|
|
5552
6289
|
* `undefined`) for this output key. The executor interprets that as
|
|
5553
6290
|
* "no output for this invocation": a previously-emitted output at
|
|
5554
6291
|
* the same id is deleted (mirroring the empty-group / empty-aggregate
|
|
5555
|
-
* semantics
|
|
6292
|
+
* semantics for empty groups); a never-emitted output is a silent
|
|
5556
6293
|
* no-op. When `false` (default), returning `null` throws
|
|
5557
6294
|
* `DerivationOutputShapeError` — same as v1.
|
|
5558
6295
|
*/
|
|
5559
6296
|
optional?: boolean;
|
|
5560
6297
|
}
|
|
5561
6298
|
/**
|
|
5562
|
-
* Array-shape output
|
|
6299
|
+
* Array-shape output — one source row produces a variable-length
|
|
5563
6300
|
* list of output rows, each with its own id (from the `key` extractor).
|
|
5564
6301
|
*
|
|
5565
6302
|
* On every source-row change, the dispatcher diffs the previously
|
|
@@ -5629,6 +6366,17 @@ interface DerivationStrategy<TSource extends Record<string, unknown>, TOutputs e
|
|
|
5629
6366
|
* sibling records via `ctx.vault.collection<T>(name).get(id)` /
|
|
5630
6367
|
* `.list()` / `.query()`. The vault accessor is read-only; there is
|
|
5631
6368
|
* no path to a writer from `ctx`.
|
|
6369
|
+
*
|
|
6370
|
+
* **Per-output omission (runtime-supported):** returning `null` or
|
|
6371
|
+
* `undefined` for an individual output key is handled at runtime via
|
|
6372
|
+
* the `optional: true` flag on the output's `RecordOutputSpec` —
|
|
6373
|
+
* the executor deletes any previously-emitted output at that id, or
|
|
6374
|
+
* silently no-ops if none exists. For `shape: 'array'` outputs, null
|
|
6375
|
+
* / undefined is treated as an empty array (clears all prior rows for
|
|
6376
|
+
* that source). The *top-level* return must always be a `TOutputs`
|
|
6377
|
+
* object; returning `null` for the whole result is not supported.
|
|
6378
|
+
* (#297 — MV `unionSources` map drop-row is the analogous feature for
|
|
6379
|
+
* materialized views.)
|
|
5632
6380
|
*/
|
|
5633
6381
|
derive: (source: TSource, ctx: DerivationContext) => Promise<TOutputs> | TOutputs;
|
|
5634
6382
|
/**
|
|
@@ -5669,6 +6417,17 @@ declare class DerivationRegistry {
|
|
|
5669
6417
|
register(spec: DerivationStrategy<any, any>): Promise<void>;
|
|
5670
6418
|
strategiesForSource(source: string): ReadonlyArray<RegisteredStrategy>;
|
|
5671
6419
|
strategiesProducingOutput(collection: string): ReadonlyArray<RegisteredStrategy>;
|
|
6420
|
+
/**
|
|
6421
|
+
* All registered strategies as a flat, deduplicated array.
|
|
6422
|
+
* Each strategy is indexed once per source (not once per output key),
|
|
6423
|
+
* so iterating `_bySource.values()` naturally yields each strategy
|
|
6424
|
+
* exactly once per source — deduplication is handled by flattening
|
|
6425
|
+
* the per-source arrays and collecting into a Set by identity.
|
|
6426
|
+
*
|
|
6427
|
+
* Used by `dumpSchema()` / `describeDerivations()` in the introspection
|
|
6428
|
+
* walker to populate the derivations map.
|
|
6429
|
+
*/
|
|
6430
|
+
all(): ReadonlyArray<RegisteredStrategy>;
|
|
5672
6431
|
/**
|
|
5673
6432
|
* Cycle detection over the source → output → … graph. Call after all
|
|
5674
6433
|
* `register()` calls complete (i.e. at vault open). Throws
|
|
@@ -5750,8 +6509,14 @@ interface UnionSource<TRow extends Record<string, unknown>> {
|
|
|
5750
6509
|
* Called once per source row at materialization time. Each arm's
|
|
5751
6510
|
* mapped output is concatenated into a single stream before
|
|
5752
6511
|
* `groupBy` + `aggregate` run.
|
|
6512
|
+
*
|
|
6513
|
+
* Returning `null` or `undefined` **omits** the source row from the
|
|
6514
|
+
* materialized output entirely — the row is not pushed into the
|
|
6515
|
+
* unified stream and never reaches `groupBy` / `aggregate`. This
|
|
6516
|
+
* removes the need for sentinel rows (e.g. `{ amount: 0 }`) whose
|
|
6517
|
+
* sole purpose is to be aggregated away (#297).
|
|
5753
6518
|
*/
|
|
5754
|
-
readonly map: (sourceRow: Record<string, unknown>) => TRow;
|
|
6519
|
+
readonly map: (sourceRow: Record<string, unknown>) => TRow | null | undefined;
|
|
5755
6520
|
}
|
|
5756
6521
|
/**
|
|
5757
6522
|
* Registration shape passed to `withMaterializedView()`.
|
|
@@ -5782,7 +6547,7 @@ interface MaterializedViewStrategy<TRow extends Record<string, unknown>> {
|
|
|
5782
6547
|
*/
|
|
5783
6548
|
query?: (db: MVQueryContext) => Query<TRow>;
|
|
5784
6549
|
/**
|
|
5785
|
-
* UNION-form sources
|
|
6550
|
+
* UNION-form sources: an explicit list of sibling collections
|
|
5786
6551
|
* that contribute rows to a single MV. Each arm's `map` projects a
|
|
5787
6552
|
* source row into the MV's unified row shape; the mapped streams are
|
|
5788
6553
|
* concatenated, then {@link groupBy} + {@link aggregate} run on the
|
|
@@ -5798,7 +6563,7 @@ interface MaterializedViewStrategy<TRow extends Record<string, unknown>> {
|
|
|
5798
6563
|
*/
|
|
5799
6564
|
unionSources?: ReadonlyArray<UnionSource<TRow>>;
|
|
5800
6565
|
/**
|
|
5801
|
-
* Group-key field(s) for UNION mode
|
|
6566
|
+
* Group-key field(s) for UNION mode. Applied to the
|
|
5802
6567
|
* concatenated mapped-row stream from {@link unionSources} before
|
|
5803
6568
|
* {@link aggregate} runs. Accepts a single field name or a tuple of
|
|
5804
6569
|
* field names for multi-key grouping (same shape as
|
|
@@ -5810,7 +6575,7 @@ interface MaterializedViewStrategy<TRow extends Record<string, unknown>> {
|
|
|
5810
6575
|
*/
|
|
5811
6576
|
groupBy?: string | ReadonlyArray<string>;
|
|
5812
6577
|
/**
|
|
5813
|
-
* Aggregation spec for UNION mode
|
|
6578
|
+
* Aggregation spec for UNION mode. Applied per-group after
|
|
5814
6579
|
* {@link groupBy} buckets the concatenated mapped-row stream from
|
|
5815
6580
|
* {@link unionSources}. Same shape as the `AggregateSpec` passed to
|
|
5816
6581
|
* `Query.aggregate()`.
|
|
@@ -5821,11 +6586,11 @@ interface MaterializedViewStrategy<TRow extends Record<string, unknown>> {
|
|
|
5821
6586
|
/**
|
|
5822
6587
|
* Pure function from a materialized row → stable id used in the
|
|
5823
6588
|
* output collection. Required — explicit always beats default-with-pitfalls
|
|
5824
|
-
* (
|
|
6589
|
+
* (explicit always beats default-with-pitfalls; see the slash-collision rationale).
|
|
5825
6590
|
*/
|
|
5826
6591
|
rowKey: (row: TRow) => string;
|
|
5827
6592
|
/**
|
|
5828
|
-
* Explicit source collections
|
|
6593
|
+
* Explicit source collections. Required when `query()` returns
|
|
5829
6594
|
* an `Aggregation` or `GroupedAggregation` rather than a `Query<T>`
|
|
5830
6595
|
* — the dependency analyzer can't introspect through `groupBy().aggregate()`
|
|
5831
6596
|
* back to the source. Optional for plain `Query<T>` results — the
|
|
@@ -5835,7 +6600,7 @@ interface MaterializedViewStrategy<TRow extends Record<string, unknown>> {
|
|
|
5835
6600
|
*/
|
|
5836
6601
|
sources?: ReadonlyArray<string>;
|
|
5837
6602
|
/**
|
|
5838
|
-
* Declared deterministic predicates
|
|
6603
|
+
* Declared deterministic predicates. Each entry pairs a
|
|
5839
6604
|
* consumer-stable `hash` with a function. The `query()` callback's
|
|
5840
6605
|
* Query<T> can invoke them via `.wherePredicate(name, ctx?)`. The
|
|
5841
6606
|
* predicate's `hash` + a canonical-JSON hash of `ctx` both fold
|
|
@@ -5872,8 +6637,8 @@ interface MaterializedViewStrategy<TRow extends Record<string, unknown>> {
|
|
|
5872
6637
|
*
|
|
5873
6638
|
* - `'delete'` (default) — tombstone the prior MV row via
|
|
5874
6639
|
* `Collection._internalDelete` (system housekeeping bypasses user
|
|
5875
|
-
* `onDelete` guards on the output collection —
|
|
5876
|
-
* composition fix).
|
|
6640
|
+
* `onDelete` guards on the output collection — the housekeeping
|
|
6641
|
+
* bypass composition fix).
|
|
5877
6642
|
* - `'keep'` — leave the prior MV row in place. Useful when zero
|
|
5878
6643
|
* is a meaningful state.
|
|
5879
6644
|
*/
|
|
@@ -5881,7 +6646,7 @@ interface MaterializedViewStrategy<TRow extends Record<string, unknown>> {
|
|
|
5881
6646
|
/**
|
|
5882
6647
|
* `true` re-throws on any row-write failure → composes with
|
|
5883
6648
|
* `withTransactions` to roll back the source-write atomically via
|
|
5884
|
-
* `revertExecuted
|
|
6649
|
+
* `revertExecuted`. Default `false` (failed rows are
|
|
5885
6650
|
* isolated; other rows commit).
|
|
5886
6651
|
*/
|
|
5887
6652
|
strict?: boolean;
|
|
@@ -5915,7 +6680,7 @@ interface RegisteredMV {
|
|
|
5915
6680
|
* Top-level FieldClauses on the partition field, captured at
|
|
5916
6681
|
* registration time. Used by the cycle detector to resolve
|
|
5917
6682
|
* same-collection-as-source edges via the partition-discriminator
|
|
5918
|
-
* check
|
|
6683
|
+
* check. Empty when `spec.output?.partition` is undefined.
|
|
5919
6684
|
*/
|
|
5920
6685
|
readonly partitionClauses: readonly FieldClause[];
|
|
5921
6686
|
}
|
|
@@ -5967,7 +6732,7 @@ declare class MaterializedViewRegistry {
|
|
|
5967
6732
|
}
|
|
5968
6733
|
|
|
5969
6734
|
/**
|
|
5970
|
-
* Read-shadow overlay primitive (
|
|
6735
|
+
* Read-shadow overlay primitive (MV v2 spec § Composition with
|
|
5971
6736
|
* operator-editable lifecycle). Binds an MV's read-only base output
|
|
5972
6737
|
* to a separate user-writable overlay collection; reads merge via a
|
|
5973
6738
|
* single shadow predicate, writes route to the overlay.
|
|
@@ -6045,6 +6810,14 @@ declare class OverlayedViewRegistry {
|
|
|
6045
6810
|
/** All overlay virtual names. */
|
|
6046
6811
|
names(): ReadonlySet<string>;
|
|
6047
6812
|
isOverlay(name: string): boolean;
|
|
6813
|
+
/**
|
|
6814
|
+
* All registered overlay strategies as a flat array.
|
|
6815
|
+
* Each strategy carries `name`, `base`, and `overlay` fields that
|
|
6816
|
+
* `describeOverlays()` in the introspection walker reads directly.
|
|
6817
|
+
*
|
|
6818
|
+
* Used by `dumpSchema()` to populate the `overlayViews` map.
|
|
6819
|
+
*/
|
|
6820
|
+
all(): ReadonlyArray<OverlayedViewStrategy>;
|
|
6048
6821
|
/**
|
|
6049
6822
|
* Resolve the `rowKey` function for an overlay's base MV. Returns
|
|
6050
6823
|
* `undefined` if the base isn't an MV (raw source collection) or
|
|
@@ -6070,6 +6843,11 @@ declare class GuardRegistry {
|
|
|
6070
6843
|
register<T extends Record<string, unknown>>(spec: GuardStrategy<T>): void;
|
|
6071
6844
|
/** All guards registered against `collection` in registration order. */
|
|
6072
6845
|
guardsFor(collection: string): ReadonlyArray<AnyGuard>;
|
|
6846
|
+
/** Per-collection guard counts, for introspection. */
|
|
6847
|
+
summary(): {
|
|
6848
|
+
collection: string;
|
|
6849
|
+
count: number;
|
|
6850
|
+
}[];
|
|
6073
6851
|
/**
|
|
6074
6852
|
* Run every guard's `check` for this collection. First throw wins —
|
|
6075
6853
|
* remaining guards are not invoked. Guards without a `check` skip.
|
|
@@ -6506,7 +7284,7 @@ declare function magicLinkGrantRecordId(token: string, index: number): string;
|
|
|
6506
7284
|
declare function isMagicLinkGrantExpired(payload: MagicLinkGrantPayload, now?: Date): boolean;
|
|
6507
7285
|
|
|
6508
7286
|
/**
|
|
6509
|
-
* Type surface for the user-list visibility subsystem
|
|
7287
|
+
* Type surface for the user-list visibility subsystem.
|
|
6510
7288
|
*
|
|
6511
7289
|
* Two complementary flags:
|
|
6512
7290
|
* - {@link DirectoryConfig} — vault-level "is the directory listing
|
|
@@ -6557,7 +7335,7 @@ interface UserVisibility {
|
|
|
6557
7335
|
* own keyringId. **Own-only write rule** is structural — no method
|
|
6558
7336
|
* exists to write someone else's envelope.
|
|
6559
7337
|
* - Read-anyone: `get` / `list` — read other principals' envelopes
|
|
6560
|
-
* (subject to `view-team-profiles` policy gate
|
|
7338
|
+
* (subject to `view-team-profiles` policy gate).
|
|
6561
7339
|
* - Reactive: `subscribe` / `live` — in-process event emission on local
|
|
6562
7340
|
* writes. Cross-instance updates land via the team/sync engine and
|
|
6563
7341
|
* surface to subscribers when the sync diff replays through this API.
|
|
@@ -6577,7 +7355,7 @@ type DeepPartial<T> = T extends object ? {
|
|
|
6577
7355
|
} : T;
|
|
6578
7356
|
/**
|
|
6579
7357
|
* Recursive partial with `null` allowed at every level — used by
|
|
6580
|
-
* `updateMe`
|
|
7358
|
+
* `updateMe` to express deletion intent in addition to merge.
|
|
6581
7359
|
*
|
|
6582
7360
|
* Semantics inside `updateMe`:
|
|
6583
7361
|
* - `undefined` (or absent key) — skip; source value preserved
|
|
@@ -6586,8 +7364,8 @@ type DeepPartial<T> = T extends object ? {
|
|
|
6586
7364
|
* replace for primitives / arrays)
|
|
6587
7365
|
*
|
|
6588
7366
|
* Matches lodash `_.merge` behavior on `null` and Firestore's
|
|
6589
|
-
* `FieldValue.delete()` semantics. Loosened from `DeepPartial<T
|
|
6590
|
-
*
|
|
7367
|
+
* `FieldValue.delete()` semantics. Loosened from `DeepPartial<T>`.
|
|
7368
|
+
* Consumers wanting the original "merge-only" surface can keep
|
|
6591
7369
|
* importing `DeepPartial` and avoid passing `null`.
|
|
6592
7370
|
*/
|
|
6593
7371
|
type DeepPartialOrNull<T> = T extends object ? {
|
|
@@ -6659,7 +7437,7 @@ declare class UserApi {
|
|
|
6659
7437
|
* the envelope on first call. Optimistic-concurrency safe — a stale
|
|
6660
7438
|
* `_v` (parallel writer on another device) throws `ConflictError`.
|
|
6661
7439
|
*
|
|
6662
|
-
* Patch semantics
|
|
7440
|
+
* Patch semantics:
|
|
6663
7441
|
* - `undefined` (or omitted key) — skip; existing value preserved
|
|
6664
7442
|
* - `null` — delete the field from the merged result
|
|
6665
7443
|
* - any other value — overwrite (deep-merge for plain objects,
|
|
@@ -6813,6 +7591,29 @@ interface PersistedSchemaEnvelope {
|
|
|
6813
7591
|
* @module
|
|
6814
7592
|
*/
|
|
6815
7593
|
|
|
7594
|
+
/** Flat snapshot of a vault's registered schema. */
|
|
7595
|
+
interface SchemaIntrospection {
|
|
7596
|
+
readonly collections: ReadonlyArray<{
|
|
7597
|
+
name: string;
|
|
7598
|
+
docCount: number;
|
|
7599
|
+
}>;
|
|
7600
|
+
readonly guards: ReadonlyArray<{
|
|
7601
|
+
collection: string;
|
|
7602
|
+
count: number;
|
|
7603
|
+
}>;
|
|
7604
|
+
readonly materializedViews: ReadonlyArray<{
|
|
7605
|
+
name: string;
|
|
7606
|
+
sourceCollections: string[];
|
|
7607
|
+
}>;
|
|
7608
|
+
readonly schemaUpdate: ReadonlyArray<{
|
|
7609
|
+
collection: string;
|
|
7610
|
+
strategies: string[];
|
|
7611
|
+
}>;
|
|
7612
|
+
readonly grants: ReadonlyArray<{
|
|
7613
|
+
collection: string;
|
|
7614
|
+
permission: Permission;
|
|
7615
|
+
}>;
|
|
7616
|
+
}
|
|
6816
7617
|
/** Where the field-level info in the snapshot came from. */
|
|
6817
7618
|
type FieldSource = 'persisted' | 'live-validator' | 'sampled' | 'unknown';
|
|
6818
7619
|
interface FieldDescriptor {
|
|
@@ -6921,6 +7722,7 @@ interface VaultIntrospectState {
|
|
|
6921
7722
|
|
|
6922
7723
|
/** A vault (tenant namespace) containing collections. */
|
|
6923
7724
|
declare class Vault {
|
|
7725
|
+
#private;
|
|
6924
7726
|
private readonly adapter;
|
|
6925
7727
|
/** The vault's name as passed to `openVault()`. Stable for the instance lifetime. */
|
|
6926
7728
|
readonly name: string;
|
|
@@ -6966,23 +7768,23 @@ declare class Vault {
|
|
|
6966
7768
|
* `null` for vaults that never register any guard strategy. The
|
|
6967
7769
|
* runtime class is dynamic-imported on demand so consumers that
|
|
6968
7770
|
* never use guards don't pull `GuardRegistry`/`GuardExecutor` into
|
|
6969
|
-
* their bundle
|
|
7771
|
+
* their bundle.
|
|
6970
7772
|
*/
|
|
6971
7773
|
private guardRegistry;
|
|
6972
7774
|
/**
|
|
6973
7775
|
* Per-vault derivation registry. Same lazy-load contract as
|
|
6974
7776
|
* `guardRegistry` — `null` until `_initDerivations()` runs with at
|
|
6975
|
-
* least one strategy handle.
|
|
7777
|
+
* least one strategy handle.
|
|
6976
7778
|
*/
|
|
6977
7779
|
private derivationRegistry;
|
|
6978
7780
|
/**
|
|
6979
|
-
* Per-vault materialized-view registry
|
|
7781
|
+
* Per-vault materialized-view registry. Same lazy-load
|
|
6980
7782
|
* contract as `derivationRegistry` — `null` until
|
|
6981
7783
|
* `_initMaterializedViews()` runs with at least one MV handle.
|
|
6982
7784
|
*/
|
|
6983
7785
|
private materializedViewRegistry;
|
|
6984
7786
|
/**
|
|
6985
|
-
* Per-vault overlay registry
|
|
7787
|
+
* Per-vault overlay registry. Same lazy-load contract as
|
|
6986
7788
|
* `materializedViewRegistry` — `null` until `_initOverlayedViews()`
|
|
6987
7789
|
* runs with at least one handle.
|
|
6988
7790
|
*/
|
|
@@ -7003,7 +7805,7 @@ declare class Vault {
|
|
|
7003
7805
|
* target this vault session's keyringId. There is no method to write
|
|
7004
7806
|
* another principal's envelope (own-only write rule, structural).
|
|
7005
7807
|
* - Read-anyone: `get(keyringId)`, `list()` — read other principals'
|
|
7006
|
-
* envelopes, subject to the `view-team-profiles` policy gate
|
|
7808
|
+
* envelopes, subject to the `view-team-profiles` policy gate.
|
|
7007
7809
|
* - Reactive: `subscribe(id, cb)`, `live(id)` — fire on local writes.
|
|
7008
7810
|
*
|
|
7009
7811
|
* @see docs/superpowers/specs/2026-05-05-user-envelope-design.md
|
|
@@ -7023,12 +7825,20 @@ declare class Vault {
|
|
|
7023
7825
|
*/
|
|
7024
7826
|
private readonly reloadKeyring;
|
|
7025
7827
|
private readonly collectionCache;
|
|
7828
|
+
/** Vault-level schema cutover fence/controller. */
|
|
7829
|
+
readonly schemaFence: SchemaFenceController;
|
|
7026
7830
|
/**
|
|
7027
7831
|
* per-collection `blobFields` retention/TTL config.
|
|
7028
7832
|
* Populated on `collection({ blobFields })` and read by
|
|
7029
7833
|
* `vault.compact()`. Indexed by collection name.
|
|
7030
7834
|
*/
|
|
7031
7835
|
private readonly blobFieldsRegistry;
|
|
7836
|
+
/**
|
|
7837
|
+
* Per-collection attestation field-schema (issue side). Populated on
|
|
7838
|
+
* `collection({ attestation })` and read by `issueAttestation()`.
|
|
7839
|
+
* Indexed by collection name.
|
|
7840
|
+
*/
|
|
7841
|
+
private readonly attestationRegistry;
|
|
7032
7842
|
/**
|
|
7033
7843
|
* Per-vault ledger store. Lazy-initialized on first
|
|
7034
7844
|
* `collection()` call (which passes it through to the Collection)
|
|
@@ -7089,8 +7899,7 @@ declare class Vault {
|
|
|
7089
7899
|
* Cache of closed/opened accounting periods.
|
|
7090
7900
|
* Populated on first `closePeriod` / `openPeriod` / `listPeriods` /
|
|
7091
7901
|
* per-collection write call. Kept in memory as an ordered list (by
|
|
7092
|
-
* `closedAt`) so
|
|
7093
|
-
* each collection's put/delete path.
|
|
7902
|
+
* `closedAt`) so period checks run fast when the gate bus fires.
|
|
7094
7903
|
*
|
|
7095
7904
|
* Sentinel `null` means "not yet loaded" — the first consumer
|
|
7096
7905
|
* triggers a one-time `loadPeriods()` pass. Every subsequent
|
|
@@ -7249,6 +8058,15 @@ declare class Vault {
|
|
|
7249
8058
|
* @see docs/superpowers/specs/2026-05-22-schema-dump-design.md
|
|
7250
8059
|
*/
|
|
7251
8060
|
persistJsonSchema?: boolean;
|
|
8061
|
+
/**
|
|
8062
|
+
* Ordered schema-update strategies. On a detected schema
|
|
8063
|
+
* change, evaluated in order; the first non-`allow` decision wins.
|
|
8064
|
+
* A `reject` is enforced at the write path (`put`/`delete` throw).
|
|
8065
|
+
* Requires `persistJsonSchema: true` (detection needs the baseline).
|
|
8066
|
+
*/
|
|
8067
|
+
schemaUpdate?: readonly SchemaUpdateStrategy[];
|
|
8068
|
+
/** — declare the per-field schema for document attestation (issue side). */
|
|
8069
|
+
attestation?: AttestationFieldSchema;
|
|
7252
8070
|
}): Collection<T>;
|
|
7253
8071
|
/**
|
|
7254
8072
|
* Await all background persisted-schema writes triggered by
|
|
@@ -7256,6 +8074,45 @@ declare class Vault {
|
|
|
7256
8074
|
* Used in tests; production code does not need to call this.
|
|
7257
8075
|
*/
|
|
7258
8076
|
_drainPendingSchemaWrites(): Promise<void>;
|
|
8077
|
+
/**
|
|
8078
|
+
* Run a coordinated schema cutover. Drains pending writes, waits
|
|
8079
|
+
* for the active client set to quiesce (the ack-barrier), applies every
|
|
8080
|
+
* pending collection transform in bulk, bumps the vault schema generation,
|
|
8081
|
+
* and clears the fence. Returns the count of collections migrated.
|
|
8082
|
+
* `opts.onPoll` (tests) advances other clients between barrier checks.
|
|
8083
|
+
*/
|
|
8084
|
+
runSchemaCutover(opts?: {
|
|
8085
|
+
onPoll?: () => Promise<void>;
|
|
8086
|
+
}): Promise<{
|
|
8087
|
+
migrated: number;
|
|
8088
|
+
}>;
|
|
8089
|
+
/**
|
|
8090
|
+
* Refresh a loaded collection's view of one document from a peer
|
|
8091
|
+
* tab's broadcast. No-op when the collection isn't loaded in this tab
|
|
8092
|
+
* (it will read fresh on next open). Mirrors `#runCutoverTransform`'s guard.
|
|
8093
|
+
*/
|
|
8094
|
+
_applyRemoteWrite(collectionName: string, docId: string, action: 'put' | 'delete'): Promise<void>;
|
|
8095
|
+
/**
|
|
8096
|
+
* For a detected conflict: capture this tab's clobbered record,
|
|
8097
|
+
* read the common ancestor from history, converge the cache to the store's
|
|
8098
|
+
* authoritative value (the re-read), and return all three for the
|
|
8099
|
+
* WriteConflict payload. Returns null when the collection isn't loaded.
|
|
8100
|
+
*/
|
|
8101
|
+
_captureAndConverge(collectionName: string, docId: string, action: 'put' | 'delete', baseV: number): Promise<{
|
|
8102
|
+
local: unknown;
|
|
8103
|
+
remote: unknown;
|
|
8104
|
+
base: unknown;
|
|
8105
|
+
} | null>;
|
|
8106
|
+
/** Recover a stuck cutover fence — reset to normal without bumping. */
|
|
8107
|
+
abortSchemaCutover(): Promise<void>;
|
|
8108
|
+
/** Current schema-cutover fence state for this vault. Thin live read. */
|
|
8109
|
+
schemaFenceState(): Promise<FenceDoc>;
|
|
8110
|
+
/** @internal Start the per-client heartbeat + fence watcher once a cutover is registered. */
|
|
8111
|
+
_ensureFenceCoordination(): void;
|
|
8112
|
+
/** @internal Stop the heartbeat/watcher (vault lock/close). */
|
|
8113
|
+
_stopFenceCoordination(): void;
|
|
8114
|
+
/** @internal Drive one heartbeat + watch cycle deterministically (tests). */
|
|
8115
|
+
_fenceTick(): Promise<void>;
|
|
7259
8116
|
/**
|
|
7260
8117
|
* Validate i18nText fields on a `put()`. Called by Collection just
|
|
7261
8118
|
* before the adapter write, after schema validation. Throws
|
|
@@ -7431,6 +8288,22 @@ declare class Vault {
|
|
|
7431
8288
|
*/
|
|
7432
8289
|
compact(options?: CompactRunOptions): Promise<CompactionResult>;
|
|
7433
8290
|
exportBlobs(options?: ExportBlobsOptions): ExportBlobsHandle;
|
|
8291
|
+
issueAttestation(collectionName: string, id: string): Promise<{
|
|
8292
|
+
docId: string;
|
|
8293
|
+
qr: string;
|
|
8294
|
+
keyId: string;
|
|
8295
|
+
publicKeyB64: string;
|
|
8296
|
+
}>;
|
|
8297
|
+
getDocumentSigningPublicKey(): Promise<{
|
|
8298
|
+
keyId: string;
|
|
8299
|
+
publicKeyB64: string;
|
|
8300
|
+
}>;
|
|
8301
|
+
private makeIssueContext;
|
|
8302
|
+
revokeAttestation(docId: string): Promise<void>;
|
|
8303
|
+
unrevokeAttestation(docId: string): Promise<void>;
|
|
8304
|
+
getRevokedDocIds(): Promise<string[]>;
|
|
8305
|
+
publishRevocationList(): Promise<RevocationList>;
|
|
8306
|
+
private makeRevokeContext;
|
|
7434
8307
|
private writeExportAudit;
|
|
7435
8308
|
/**
|
|
7436
8309
|
* Read-only accessor for the invoking keyring's export capability,
|
|
@@ -7550,7 +8423,7 @@ declare class Vault {
|
|
|
7550
8423
|
* Dynamic-imports `GuardRegistry` + `ReadOnlyVaultFacade` and seeds
|
|
7551
8424
|
* the registry with the supplied strategy handles. No-op when the
|
|
7552
8425
|
* handles array is empty — keeps the guard subsystem out of the
|
|
7553
|
-
* floor bundle for consumers that don't use guards
|
|
8426
|
+
* floor bundle for consumers that don't use guards.
|
|
7554
8427
|
*
|
|
7555
8428
|
* The read-only facade is eagerly instantiated here so the sync
|
|
7556
8429
|
* accessor `_getReadOnlyFacade()` (called from the tx amendment
|
|
@@ -7558,10 +8431,9 @@ declare class Vault {
|
|
|
7558
8431
|
*/
|
|
7559
8432
|
_initGuards(handles: ReadonlyArray<GuardStrategyHandleAny>): Promise<void>;
|
|
7560
8433
|
/**
|
|
7561
|
-
* @internal —
|
|
7562
|
-
* vaults that never registered any guard
|
|
7563
|
-
* gate on null
|
|
7564
|
-
* `Collection` already do this transitively).
|
|
8434
|
+
* @internal — The gate handler in Noydb.#registerGuardGate calls into
|
|
8435
|
+
* this. Returns `null` for vaults that never registered any guard
|
|
8436
|
+
* strategy. Callers MUST gate on null.
|
|
7565
8437
|
*/
|
|
7566
8438
|
_getGuardRegistry(): GuardRegistry | null;
|
|
7567
8439
|
/**
|
|
@@ -7570,7 +8442,7 @@ declare class Vault {
|
|
|
7570
8442
|
* derivation strategies (async because `strategyHash` computation
|
|
7571
8443
|
* goes through `crypto.subtle.digest`). No-op when the handles
|
|
7572
8444
|
* array is empty — keeps the derivation subsystem out of the floor
|
|
7573
|
-
* bundle for consumers that don't use derivations
|
|
8445
|
+
* bundle for consumers that don't use derivations. Throws
|
|
7574
8446
|
* `DerivationCycleError` if a cycle is detected after registration.
|
|
7575
8447
|
*/
|
|
7576
8448
|
_initDerivations(handles: ReadonlyArray<DerivationStrategyHandle>): Promise<void>;
|
|
@@ -7585,7 +8457,7 @@ declare class Vault {
|
|
|
7585
8457
|
* MV spec (which invokes its `query()` once for dependency
|
|
7586
8458
|
* analysis), then runs the unified cycle detection across the MV +
|
|
7587
8459
|
* derivation graphs. No-op when the handles array is empty — keeps
|
|
7588
|
-
* the MV subsystem out of the floor bundle (mirrors
|
|
8460
|
+
* the MV subsystem out of the floor bundle (mirrors the derivation lazy-import pattern).
|
|
7589
8461
|
* Throws `MaterializedViewCycleError` if a cycle is detected.
|
|
7590
8462
|
*/
|
|
7591
8463
|
_initMaterializedViews(handles: ReadonlyArray<MaterializedViewStrategyHandle>): Promise<void>;
|
|
@@ -7607,13 +8479,13 @@ declare class Vault {
|
|
|
7607
8479
|
*/
|
|
7608
8480
|
_getOverlayedViewRegistry(): OverlayedViewRegistry | null;
|
|
7609
8481
|
/**
|
|
7610
|
-
* Manual re-materialize for a single registered MV
|
|
8482
|
+
* Manual re-materialize for a single registered MV. Useful
|
|
7611
8483
|
* for `refresh: 'manual'` MVs (whose consumer drives refreshes
|
|
7612
8484
|
* externally), for stale-bit recovery on vault re-open, and as the
|
|
7613
8485
|
* explicit bulk-recompute escape hatch after a strategy change.
|
|
7614
8486
|
*
|
|
7615
|
-
* Returns `{ written, deleted, failed }`. `deleted` is always 0
|
|
7616
|
-
*
|
|
8487
|
+
* Returns `{ written, deleted, failed }`. `deleted` is always 0
|
|
8488
|
+
* when tombstoning is not enabled.
|
|
7617
8489
|
*
|
|
7618
8490
|
* Throws if `name` is not a registered MV.
|
|
7619
8491
|
*/
|
|
@@ -7636,20 +8508,17 @@ declare class Vault {
|
|
|
7636
8508
|
/**
|
|
7637
8509
|
* @internal — exposed for `runTransaction({ amendment: true })` so
|
|
7638
8510
|
* the amendment invariant runner can pass the SAME read-only vault
|
|
7639
|
-
* facade that the
|
|
7640
|
-
*
|
|
7641
|
-
* `
|
|
7642
|
-
*
|
|
7643
|
-
*
|
|
8511
|
+
* facade that the gate handler in Noydb.#registerGuardGate uses.
|
|
8512
|
+
* Eagerly instantiated by `_initGuards()` so this accessor stays
|
|
8513
|
+
* synchronous; returns `null` for vaults that never registered any
|
|
8514
|
+
* guard (amendments require at least one guard, so the caller should
|
|
8515
|
+
* never see null).
|
|
7644
8516
|
*/
|
|
7645
8517
|
_getReadOnlyFacade(): ReadOnlyVaultFacade | null;
|
|
7646
8518
|
/**
|
|
7647
|
-
* Internal lazy-allocator for the read-only facade. Used
|
|
7648
|
-
*
|
|
7649
|
-
*
|
|
7650
|
-
* invocation (theoretically impossible — `Noydb.openVault` awaits
|
|
7651
|
-
* `_initGuards` before returning — but we keep the defensive lazy
|
|
7652
|
-
* path so the closure's contract stays "always returns a facade").
|
|
8519
|
+
* Internal lazy-allocator for the read-only facade. Used as a
|
|
8520
|
+
* defensive fallback; in practice `_initGuards()` eagerly
|
|
8521
|
+
* instantiates this, so the lazy path is a no-op.
|
|
7653
8522
|
*/
|
|
7654
8523
|
private _ensureReadOnlyFacade;
|
|
7655
8524
|
/**
|
|
@@ -7856,7 +8725,7 @@ declare class Vault {
|
|
|
7856
8725
|
listPeriods(): Promise<readonly PeriodRecord[]>;
|
|
7857
8726
|
/** Look up a single period by name. Returns `null` if not found. */
|
|
7858
8727
|
getPeriod(name: string): Promise<PeriodRecord | null>;
|
|
7859
|
-
/** @internal —
|
|
8728
|
+
/** @internal — called by the gate bus before put/delete. */
|
|
7860
8729
|
_assertTsWritable(existing: {
|
|
7861
8730
|
ts: string | null;
|
|
7862
8731
|
record: Record<string, unknown> | null;
|
|
@@ -7886,6 +8755,14 @@ declare class Vault {
|
|
|
7886
8755
|
* @see docs/superpowers/specs/2026-05-22-schema-dump-design.md
|
|
7887
8756
|
*/
|
|
7888
8757
|
dumpSchema(opts?: DumpSchemaOptions): Promise<VaultSchemaSnapshot>;
|
|
8758
|
+
/**
|
|
8759
|
+
* Lightweight read of the vault's registered schema: collections
|
|
8760
|
+
* (+ doc counts), guards, materialized views, schema-update strategies,
|
|
8761
|
+
* and the unlocked user's grants. Cheap — one `adapter.list` per
|
|
8762
|
+
* collection, no decryption. For a full snapshot + stats use dumpSchema().
|
|
8763
|
+
* Post-unlock by construction (a Vault only exists with an unlocked keyring).
|
|
8764
|
+
*/
|
|
8765
|
+
introspect(): Promise<SchemaIntrospection>;
|
|
7889
8766
|
/**
|
|
7890
8767
|
* Internal accessor for {@link dumpVaultSchema}. Exposes the structural
|
|
7891
8768
|
* state the walker needs (collection cache, registries, ref registry,
|
|
@@ -8362,12 +9239,19 @@ interface CacheStats extends LruStats {
|
|
|
8362
9239
|
}
|
|
8363
9240
|
/** A typed collection of records within a vault. */
|
|
8364
9241
|
declare class Collection<T> {
|
|
9242
|
+
#private;
|
|
8365
9243
|
private readonly adapter;
|
|
8366
9244
|
private readonly vault;
|
|
8367
9245
|
private readonly name;
|
|
8368
9246
|
private readonly keyring;
|
|
8369
9247
|
private readonly encrypted;
|
|
8370
9248
|
private readonly emitter;
|
|
9249
|
+
private readonly writeQueue;
|
|
9250
|
+
private readonly schemaUpdateGate;
|
|
9251
|
+
private readonly schemaFence;
|
|
9252
|
+
private readonly writeHooks;
|
|
9253
|
+
private readonly subsystemBus;
|
|
9254
|
+
private readonly activeTxId;
|
|
8371
9255
|
private readonly getDEK;
|
|
8372
9256
|
private readonly onDirty;
|
|
8373
9257
|
private readonly historyConfig;
|
|
@@ -8414,6 +9298,12 @@ declare class Collection<T> {
|
|
|
8414
9298
|
* caller site.
|
|
8415
9299
|
*/
|
|
8416
9300
|
private readonly indexState;
|
|
9301
|
+
/**
|
|
9302
|
+
* In-memory unique-constraint enforcement for eager mode.
|
|
9303
|
+
* `null` when no `unique:true` indexes are declared on this collection,
|
|
9304
|
+
* or when the collection is in lazy mode (which throws at registration).
|
|
9305
|
+
*/
|
|
9306
|
+
private readonly uniqueConstraints;
|
|
8417
9307
|
/**
|
|
8418
9308
|
* True once `_idx/*` side-cars have been bulk-loaded into
|
|
8419
9309
|
* `persistedIndexes`. Flipped by `ensurePersistedIndexesLoaded()` on
|
|
@@ -8548,42 +9438,14 @@ declare class Collection<T> {
|
|
|
8548
9438
|
private readonly syncAdapter;
|
|
8549
9439
|
/** — consent-audit hook, no-op when no scope is active. */
|
|
8550
9440
|
private readonly onAccess;
|
|
8551
|
-
/**
|
|
8552
|
-
* accounting-period write guard. Called BEFORE any
|
|
8553
|
-
* adapter write with:
|
|
8554
|
-
* - `existing` — the prior envelope's `_ts` and decrypted record
|
|
8555
|
-
* (or `null` if no prior envelope exists)
|
|
8556
|
-
* - `incoming` — the record being written (or `null` for delete)
|
|
8557
|
-
*
|
|
8558
|
-
* Throws `PeriodClosedError` if either side falls inside a closed
|
|
8559
|
-
* period. Installed by Vault; no-op when no period has been closed.
|
|
8560
|
-
* Async so the Vault can lazy-load the period list from the
|
|
8561
|
-
* adapter on first use.
|
|
8562
|
-
*/
|
|
8563
|
-
private readonly periodGuard;
|
|
8564
|
-
/**
|
|
8565
|
-
* Optional back-reference to the owning vault's guard registry + a
|
|
8566
|
-
* read-only vault facade. When present, `Collection.put` and
|
|
8567
|
-
* `Collection.delete` consult the registry for guards declared
|
|
8568
|
-
* against this collection and run their `check` + `frozenFields`
|
|
8569
|
-
* before the adapter write. Absent in unit tests that construct
|
|
8570
|
-
* a Collection directly; production code always sets it via
|
|
8571
|
-
* `Vault.collection()`.
|
|
8572
|
-
*
|
|
8573
|
-
* Typed structurally rather than as `Vault` to avoid a circular
|
|
8574
|
-
* import (mirrors the `refEnforcer` / `joinResolver` pattern).
|
|
8575
|
-
*/
|
|
8576
|
-
private readonly guardSource;
|
|
8577
9441
|
/**
|
|
8578
9442
|
* Vault-internal hook for derivation dispatch. When set,
|
|
8579
9443
|
* `Collection.put` consults the registry after the source-write
|
|
8580
9444
|
* commits and writes derived outputs through `getCollection(name).put`.
|
|
8581
|
-
* Same structural-interface pattern as `guardSource` to avoid a
|
|
8582
|
-
* circular Vault import.
|
|
8583
9445
|
*/
|
|
8584
9446
|
private readonly derivationSource;
|
|
8585
9447
|
/**
|
|
8586
|
-
* Vault-internal hook for materialized-view dispatch
|
|
9448
|
+
* Vault-internal hook for materialized-view dispatch.
|
|
8587
9449
|
* Parallel to `derivationSource` — when set, `Collection.put` fires
|
|
8588
9450
|
* `MaterializedViewRegistry.onSourceWrite` after the source-write
|
|
8589
9451
|
* commits + after `dispatchDerivations` has run.
|
|
@@ -8635,6 +9497,23 @@ declare class Collection<T> {
|
|
|
8635
9497
|
keyring: UnlockedKeyring;
|
|
8636
9498
|
encrypted: boolean;
|
|
8637
9499
|
emitter: NoydbEventEmitter;
|
|
9500
|
+
/**
|
|
9501
|
+
* Vault-level in-flight write tracker. When present,
|
|
9502
|
+
* `put`/`delete` run inside `writeQueue.track()` so `hub.writeQueue`
|
|
9503
|
+
* reflects outstanding writes. Optional so direct Collection
|
|
9504
|
+
* construction in tests still works untracked.
|
|
9505
|
+
*/
|
|
9506
|
+
writeQueue?: WriteQueueTracker | undefined;
|
|
9507
|
+
/** Per-collection schema-update gate; `put`/`delete` await it. */
|
|
9508
|
+
schemaUpdateGate?: SchemaUpdateGate | undefined;
|
|
9509
|
+
/** Vault-level fence controller; `put`/`delete` consult it. */
|
|
9510
|
+
schemaFence?: SchemaFenceController | undefined;
|
|
9511
|
+
/** Hub-level write-hook registry; fired around put/delete. */
|
|
9512
|
+
writeHooks?: WriteHookRegistry | undefined;
|
|
9513
|
+
/** The observe bus, threaded from Noydb. */
|
|
9514
|
+
subsystemBus?: SubsystemBus | undefined;
|
|
9515
|
+
/** Active transaction id supplier (null outside a transaction). */
|
|
9516
|
+
activeTxId?: (() => string | null) | undefined;
|
|
8638
9517
|
getDEK: (collectionName: string) => Promise<CryptoKey>;
|
|
8639
9518
|
historyConfig?: HistoryConfig | undefined;
|
|
8640
9519
|
onDirty?: OnDirtyCallback | undefined;
|
|
@@ -8838,33 +9717,19 @@ declare class Collection<T> {
|
|
|
8838
9717
|
* to the ledger.
|
|
8839
9718
|
*/
|
|
8840
9719
|
onCrossTierAccess?: ((event: CrossTierAccessEvent) => void) | undefined;
|
|
8841
|
-
periodGuard?: (existing: {
|
|
8842
|
-
ts: string | null;
|
|
8843
|
-
record: Record<string, unknown> | null;
|
|
8844
|
-
} | null, incoming: Record<string, unknown> | null) => Promise<void>;
|
|
8845
9720
|
/**
|
|
8846
|
-
* Optional back-reference to the owning vault's guard registry +
|
|
8847
|
-
* read-only facade. When present, put/delete consult registered
|
|
8848
|
-
* guards for this collection. Same structural-interface pattern
|
|
8849
|
-
* as `refEnforcer` to avoid a circular Vault import.
|
|
8850
|
-
*/
|
|
8851
|
-
guardSource?: {
|
|
8852
|
-
registry(): GuardRegistry;
|
|
8853
|
-
readOnlyVault(): ReadOnlyVaultFacade$1;
|
|
8854
|
-
} | undefined;
|
|
8855
9721
|
/**
|
|
8856
9722
|
* Optional back-reference to the owning vault's derivation
|
|
8857
9723
|
* registry + collection accessor. When present, successful
|
|
8858
9724
|
* `put()` dispatches registered derivation strategies for the
|
|
8859
|
-
* source collection.
|
|
8860
|
-
* `guardSource` to avoid a circular Vault import.
|
|
9725
|
+
* source collection.
|
|
8861
9726
|
*/
|
|
8862
9727
|
derivationSource?: {
|
|
8863
9728
|
registry(): DerivationRegistry;
|
|
8864
9729
|
getCollection(name: string): Collection<Record<string, unknown>>;
|
|
8865
9730
|
/**
|
|
8866
9731
|
* Read-only vault facade handed to `derive(source, ctx)` so a
|
|
8867
|
-
* derivation can fetch sibling records
|
|
9732
|
+
* derivation can fetch sibling records. Same shape and
|
|
8868
9733
|
* instance the guards subsystem uses for `check(incoming, ctx)`.
|
|
8869
9734
|
*/
|
|
8870
9735
|
getReadOnlyFacade(): ReadOnlyVaultFacade$1;
|
|
@@ -8873,13 +9738,13 @@ declare class Collection<T> {
|
|
|
8873
9738
|
* transaction context, or `null` when no transaction is running.
|
|
8874
9739
|
* `dispatchDerivations` consults this so a recursive derived-output
|
|
8875
9740
|
* write can register its pre-write envelope onto `ctx._executed`
|
|
8876
|
-
* and roll back alongside the source op on mid-batch failure
|
|
9741
|
+
* and roll back alongside the source op on mid-batch failure.
|
|
8877
9742
|
*/
|
|
8878
9743
|
getActiveTxContext(): TxContext | null;
|
|
8879
9744
|
/**
|
|
8880
9745
|
* Construct a transient TxContext bound to the owning Noydb. Used
|
|
8881
9746
|
* by `Collection.putManyAtomic` to publish an active context for
|
|
8882
|
-
* its Phase 2 loop
|
|
9747
|
+
* its Phase 2 loop.
|
|
8883
9748
|
*/
|
|
8884
9749
|
createTxContext(): TxContext;
|
|
8885
9750
|
/** Publish a TxContext for the duration of a bulk-atomic loop. */
|
|
@@ -8888,7 +9753,7 @@ declare class Collection<T> {
|
|
|
8888
9753
|
clearActiveTxContext(ctx: TxContext): void;
|
|
8889
9754
|
} | undefined;
|
|
8890
9755
|
/**
|
|
8891
|
-
* Vault-internal hook for materialized-view dispatch
|
|
9756
|
+
* Vault-internal hook for materialized-view dispatch.
|
|
8892
9757
|
* Parallel to `derivationSource`. When set, `Collection.put` fires
|
|
8893
9758
|
* registered MV `onSourceWrite` after the standard derivation
|
|
8894
9759
|
* dispatch.
|
|
@@ -8950,24 +9815,27 @@ declare class Collection<T> {
|
|
|
8950
9815
|
pollIntervalMs?: number;
|
|
8951
9816
|
}): PresenceHandle<P>;
|
|
8952
9817
|
/**
|
|
8953
|
-
* Create or update a record.
|
|
9818
|
+
* Create or update a record. Runs inside the hub's write-queue tracker
|
|
9819
|
+
* so `hub.writeQueue.pending` reflects this write.
|
|
8954
9820
|
*
|
|
8955
9821
|
* @param id Record identifier.
|
|
8956
9822
|
* @param record The record body (validated by the collection's schema
|
|
8957
9823
|
* if one was attached at `vault.collection(...)` time).
|
|
8958
9824
|
* @param options Optional metadata for audit + import workflows.
|
|
8959
9825
|
* `reason` is stamped onto the resulting ledger entry
|
|
8960
|
-
*
|
|
9826
|
+
* so audit consumers can filter via
|
|
8961
9827
|
* `entries.filter(e => e.reason?.startsWith('import:'))`.
|
|
8962
9828
|
*/
|
|
8963
9829
|
put(id: string, record: T, options?: {
|
|
8964
9830
|
readonly reason?: string;
|
|
8965
9831
|
}): Promise<void>;
|
|
9832
|
+
/** @internal Untracked put body — call {@link put}, not this. */
|
|
9833
|
+
private putInternal;
|
|
8966
9834
|
/**
|
|
8967
9835
|
* Fire registered MV strategies whose dependency set includes this
|
|
8968
9836
|
* collection. Eager-mode MVs re-materialize inline via
|
|
8969
9837
|
* `MaterializedViewExecutor.refresh`; lazy / manual modes are
|
|
8970
|
-
* no-ops in the foundation
|
|
9838
|
+
* no-ops in the foundation; wired in the lazy-mode implementation.
|
|
8971
9839
|
*
|
|
8972
9840
|
* Skips entirely when the record being written is itself an
|
|
8973
9841
|
* MV-emitted row (carries `_materializedFrom`) — defensive guard
|
|
@@ -8988,12 +9856,23 @@ declare class Collection<T> {
|
|
|
8988
9856
|
* cycle detection.
|
|
8989
9857
|
*/
|
|
8990
9858
|
private dispatchDerivations;
|
|
8991
|
-
/**
|
|
9859
|
+
/**
|
|
9860
|
+
* Delete a record by ID. Runs inside the hub's write-queue tracker
|
|
9861
|
+
* so `hub.writeQueue.pending` reflects this write.
|
|
9862
|
+
*/
|
|
8992
9863
|
delete(id: string): Promise<void>;
|
|
9864
|
+
/**
|
|
9865
|
+
* @internal — bulk-rewrite every record through a cutover transform.
|
|
9866
|
+
* Raw adapter path (bypasses the write gate + guards — the transform is
|
|
9867
|
+
* trusted and runs only during the `migrating` phase). Bumps each
|
|
9868
|
+
* record's `_v` and appends a ledger `op:'migration'` entry.
|
|
9869
|
+
*/
|
|
9870
|
+
_applyCutoverTransform(transform: (doc: Record<string, unknown>) => Record<string, unknown>): Promise<number>;
|
|
9871
|
+
/** @internal Untracked delete body — call {@link delete}, not this. */
|
|
9872
|
+
private deleteInternal;
|
|
8993
9873
|
/**
|
|
8994
9874
|
* @internal — system-internal delete that bypasses user-facing
|
|
8995
|
-
* delete hooks (`onDelete`,
|
|
8996
|
-
* enforcer). Used by derivation tombstones (#144) and MV refresh
|
|
9875
|
+
* delete hooks (`onDelete`, FK ref enforcer). Used by derivation tombstones and MV refresh
|
|
8997
9876
|
* (Dim 14 v2) — system housekeeping shouldn't trip user invariants
|
|
8998
9877
|
* registered against the output collection. The ledger entry and
|
|
8999
9878
|
* history snapshot still fire so backup integrity and time-travel
|
|
@@ -9005,7 +9884,7 @@ declare class Collection<T> {
|
|
|
9005
9884
|
*
|
|
9006
9885
|
* When a `txCtx` is supplied, the prior envelope is captured and
|
|
9007
9886
|
* pushed onto `txCtx._executed` BEFORE the delete fires — mirrors
|
|
9008
|
-
* the
|
|
9887
|
+
* the rollback hardening for puts. Callers outside a
|
|
9009
9888
|
* multi-record transaction pass `null` and skip the tracking.
|
|
9010
9889
|
*
|
|
9011
9890
|
* Amendment composition: if `_internalDelete` runs while a vault's
|
|
@@ -9032,7 +9911,7 @@ declare class Collection<T> {
|
|
|
9032
9911
|
private _doDelete;
|
|
9033
9912
|
/**
|
|
9034
9913
|
* Cascade deletes of array-shape derived rows when a source row is
|
|
9035
|
-
* deleted
|
|
9914
|
+
* deleted. Reads each registered strategy's fanout sidecar
|
|
9036
9915
|
* for this source id, deletes every listed derived row, then
|
|
9037
9916
|
* deletes the sidecar itself.
|
|
9038
9917
|
*
|
|
@@ -9043,8 +9922,8 @@ declare class Collection<T> {
|
|
|
9043
9922
|
*/
|
|
9044
9923
|
private dispatchArrayDerivationsOnDelete;
|
|
9045
9924
|
/**
|
|
9046
|
-
* Mirror of {@link dispatchMaterializedViews} for the delete path
|
|
9047
|
-
*
|
|
9925
|
+
* Mirror of {@link dispatchMaterializedViews} for the delete path.
|
|
9926
|
+
* No record content is available (it's gone), so the
|
|
9048
9927
|
* `_materializedFrom` skip used by the put-side dispatch doesn't
|
|
9049
9928
|
* apply here — instead, the recursion guard is the `internal` gate
|
|
9050
9929
|
* at the `_doDelete` call site above.
|
|
@@ -9126,7 +10005,7 @@ declare class Collection<T> {
|
|
|
9126
10005
|
* the filtered records directly (the API). Prefer the chainable
|
|
9127
10006
|
* form for new code.
|
|
9128
10007
|
*
|
|
9129
|
-
* **Lazy-MV gap
|
|
10008
|
+
* **Lazy-MV gap:** `query()` is synchronous and does NOT
|
|
9130
10009
|
* trigger lazy materialized-view resolve-on-read. If this
|
|
9131
10010
|
* collection is a lazy MV's output and the MV is currently stale,
|
|
9132
10011
|
* `query().toArray()` returns the pre-stale snapshot. To force a
|
|
@@ -9287,7 +10166,7 @@ declare class Collection<T> {
|
|
|
9287
10166
|
* .aggregate({ total: sum('amount'), n: count() })
|
|
9288
10167
|
* ```
|
|
9289
10168
|
*
|
|
9290
|
-
* **Lazy-MV gap
|
|
10169
|
+
* **Lazy-MV gap:** `scan()` is synchronous-build and does
|
|
9291
10170
|
* NOT trigger lazy materialized-view resolve-on-read. For lazy
|
|
9292
10171
|
* MVs, call `list()` (which DOES resolve) or `vault.refreshView(name)`
|
|
9293
10172
|
* before scanning. Same shape as the `query()` limitation.
|
|
@@ -9326,6 +10205,15 @@ declare class Collection<T> {
|
|
|
9326
10205
|
* gone before the tx and the revert deleted it again).
|
|
9327
10206
|
*/
|
|
9328
10207
|
_invalidateCacheEntry(id: string): Promise<void>;
|
|
10208
|
+
/**
|
|
10209
|
+
* Apply a peer tab's committed write to THIS tab's in-memory view:
|
|
10210
|
+
* re-read the (already-persisted) envelope from the shared store + refresh
|
|
10211
|
+
* cache/indexes, then emit a `change` event so reactive consumers re-render.
|
|
10212
|
+
* Never writes to the store and never fires write hooks, so it cannot loop.
|
|
10213
|
+
*/
|
|
10214
|
+
_applyRemoteChange(id: string, action: 'put' | 'delete'): Promise<void>;
|
|
10215
|
+
/** @internal — the current in-memory record without a store read (for conflict capture). */
|
|
10216
|
+
_peekCached(id: string): T | null;
|
|
9329
10217
|
private ensureHydrated;
|
|
9330
10218
|
/** Hydrate from a pre-loaded snapshot (used by Vault). */
|
|
9331
10219
|
hydrateFromSnapshot(records: Record<string, EncryptedEnvelope>): Promise<void>;
|
|
@@ -9340,6 +10228,11 @@ declare class Collection<T> {
|
|
|
9340
10228
|
* 1K–50K records this completes in single-digit milliseconds.
|
|
9341
10229
|
*/
|
|
9342
10230
|
private rebuildEagerIndexesFromCache;
|
|
10231
|
+
/**
|
|
10232
|
+
* Rebuild unique-constraint maps from the current in-memory cache.
|
|
10233
|
+
* Called after any bulk hydration alongside `rebuildEagerIndexesFromCache`.
|
|
10234
|
+
*/
|
|
10235
|
+
private rebuildUniqueConstraintsFromCache;
|
|
9343
10236
|
/**
|
|
9344
10237
|
* Rebuild every declared index from scratch.
|
|
9345
10238
|
*
|
|
@@ -9751,6 +10644,7 @@ interface ShadowStrategy {
|
|
|
9751
10644
|
*/
|
|
9752
10645
|
interface TxStrategy {
|
|
9753
10646
|
runTransaction<T>(db: Noydb, fn: (tx: TxContext) => Promise<T> | T, options?: AmendmentTxOptions): Promise<T>;
|
|
10647
|
+
runDryRun(db: Noydb, fn: (tx: TxContext) => unknown): Promise<DryRunResult>;
|
|
9754
10648
|
}
|
|
9755
10649
|
|
|
9756
10650
|
/**
|
|
@@ -9881,7 +10775,7 @@ interface SessionStrategy {
|
|
|
9881
10775
|
}
|
|
9882
10776
|
|
|
9883
10777
|
/**
|
|
9884
|
-
* Managed-passphrase mode —
|
|
10778
|
+
* Managed-passphrase mode — rubber-hose-resistant vaults.
|
|
9885
10779
|
*
|
|
9886
10780
|
* A vault mode where the passphrase is machine-generated and never
|
|
9887
10781
|
* exposed to the user, sealed under a developer-provided
|
|
@@ -9897,6 +10791,18 @@ interface SessionStrategy {
|
|
|
9897
10791
|
* - {@link MemorySealingKeyProvider} — in-memory test provider; uses
|
|
9898
10792
|
* a deterministic per-instance "key" so two providers with
|
|
9899
10793
|
* different ids cannot unseal each other's outputs.
|
|
10794
|
+
* - {@link RecipientHint} — public material a sender uses to seal
|
|
10795
|
+
* plaintext for a specific recipient; published by
|
|
10796
|
+
* {@link RecipientSealer.publishRecipientHint} and transported
|
|
10797
|
+
* out-of-band to the sender before bundle writes.
|
|
10798
|
+
* - {@link RecipientSealer} — interface for asymmetric/granted
|
|
10799
|
+
* providers that support recipient-target sealing (RSA-OAEP,
|
|
10800
|
+
* cloud-KMS asymmetric, etc.); distinct from self-only
|
|
10801
|
+
* {@link SealingKeyProvider} (macOS Keychain, WebAuthn-PRF).
|
|
10802
|
+
* - {@link MemoryRecipientSealer} — in-process reference
|
|
10803
|
+
* implementation of both `RecipientSealer` and
|
|
10804
|
+
* `SealingKeyProvider` using real WebCrypto RSA-OAEP + AES-GCM;
|
|
10805
|
+
* safe for tests and same-process sender/recipient scenarios.
|
|
9900
10806
|
* - {@link loadSealedPassphrase} / {@link saveSealedPassphrase} —
|
|
9901
10807
|
* plaintext envelope storage at `_meta/sealed-passphrase`.
|
|
9902
10808
|
* Mirrors the `_meta/handle` and `_meta/public-envelope` AES-
|
|
@@ -9908,9 +10814,9 @@ interface SessionStrategy {
|
|
|
9908
10814
|
* Returns the plaintext passphrase string that the rest of the
|
|
9909
10815
|
* `createNoydb` keyring path consumes.
|
|
9910
10816
|
*
|
|
9911
|
-
*
|
|
10817
|
+
* Deferred to follow-ups:
|
|
9912
10818
|
* - Block `rotate-passphrase` policy gate under managed mode.
|
|
9913
|
-
* - Mandatory strong-recovery enforcement
|
|
10819
|
+
* - Mandatory strong-recovery enforcement.
|
|
9914
10820
|
* - Recovery flow under managed mode (generates fresh sealed phrase).
|
|
9915
10821
|
*
|
|
9916
10822
|
* @see docs/subsystems/session-tiers.md → Managed-passphrase mode
|
|
@@ -9977,6 +10883,78 @@ declare class MemorySealingKeyProvider implements SealingKeyProvider {
|
|
|
9977
10883
|
seal(passphrase: Uint8Array): Promise<Uint8Array>;
|
|
9978
10884
|
unseal(sealed: Uint8Array): Promise<Uint8Array>;
|
|
9979
10885
|
}
|
|
10886
|
+
/**
|
|
10887
|
+
* Public material a sender uses to seal-for-this-recipient. Published by
|
|
10888
|
+
* a recipient's RecipientSealer; transported to the sender out-of-band
|
|
10889
|
+
* (email, S3, in-app message). The sender obtains the hint, supplies it
|
|
10890
|
+
* to writeNoydbBundle's sealedCredentials.perUser[userId].hint, and the
|
|
10891
|
+
* hub seals each user's credential against it. Per foundation §11.4.
|
|
10892
|
+
*/
|
|
10893
|
+
type RecipientHint = {
|
|
10894
|
+
readonly v: 1;
|
|
10895
|
+
/** Recipient's provider id; matches the SealedAutoUnlockEntry.pid they'll unseal under. */
|
|
10896
|
+
readonly pid: string;
|
|
10897
|
+
/** Algorithm the sender uses to produce the seal. Slice 1 ships RSA-OAEP-SHA256 only. */
|
|
10898
|
+
readonly alg: 'rsa-oaep-sha256';
|
|
10899
|
+
/** Public material — alg-specific. For 'rsa-oaep-sha256': { publicKeyPem: string }. */
|
|
10900
|
+
readonly material: Readonly<Record<string, unknown>>;
|
|
10901
|
+
};
|
|
10902
|
+
/**
|
|
10903
|
+
* Handover-capable provider. Implemented additionally by asymmetric/granted
|
|
10904
|
+
* providers (cloud-KMS asymmetric, Azure RSA Key Vault, AWS KMS with grant).
|
|
10905
|
+
* Self-only providers (macOS Keychain, env-var, WebAuthn-PRF) do NOT
|
|
10906
|
+
* implement this — the §11.2 capability matrix lives in the type system.
|
|
10907
|
+
*
|
|
10908
|
+
* Per foundation §11.4. A function that requires recipient-target sealing
|
|
10909
|
+
* takes `RecipientSealer`, not `SealingKeyProvider` — the compiler rejects
|
|
10910
|
+
* passing a self-only provider at the spec site.
|
|
10911
|
+
*/
|
|
10912
|
+
interface RecipientSealer {
|
|
10913
|
+
readonly id: string;
|
|
10914
|
+
/** Produce hint material a sender uses to seal-for-this-recipient. */
|
|
10915
|
+
publishRecipientHint(): Promise<RecipientHint>;
|
|
10916
|
+
/**
|
|
10917
|
+
* Seal plaintext for the recipient described by `hint`. Returns opaque
|
|
10918
|
+
* bytes — same contract as `SealingKeyProvider.seal()`. The bundle
|
|
10919
|
+
* layer base64-encodes the bytes into `SealedAutoUnlockEntry.sealed`
|
|
10920
|
+
* without inspecting them.
|
|
10921
|
+
*/
|
|
10922
|
+
sealForRecipient(plaintext: Uint8Array, hint: RecipientHint): Promise<Uint8Array>;
|
|
10923
|
+
}
|
|
10924
|
+
/**
|
|
10925
|
+
* Reference implementation of `RecipientSealer` + `SealingKeyProvider`.
|
|
10926
|
+
* Uses WebCrypto RSA-OAEP-SHA256 (2048-bit) to wrap a fresh 32-byte
|
|
10927
|
+
* AES-GCM CEK, AES-GCM-encrypts plaintext under it, and packs the
|
|
10928
|
+
* result into a self-describing TLV:
|
|
10929
|
+
*
|
|
10930
|
+
* byte 0 : version (0x01)
|
|
10931
|
+
* bytes 1..256 : RSA-OAEP-wrapped CEK (fixed 256 bytes at RSA-2048)
|
|
10932
|
+
* bytes 257..268: AES-GCM IV (12 bytes)
|
|
10933
|
+
* bytes 269.. : AES-GCM ciphertext ‖ 16-byte tag
|
|
10934
|
+
*
|
|
10935
|
+
* Implements BOTH interfaces. `seal(plaintext)` (self-target) is just
|
|
10936
|
+
* `sealForRecipient(plaintext, this own hint)` — same TLV. Convenient
|
|
10937
|
+
* for tests where one provider plays both ends. Real cloud providers
|
|
10938
|
+
* (`at-aws-kms`, etc.) will pick their own internal layouts; the only
|
|
10939
|
+
* contract is round-trip identity.
|
|
10940
|
+
*
|
|
10941
|
+
* SAFE for production within its scope — the cryptography is real
|
|
10942
|
+
* (RSA-OAEP + AES-GCM via WebCrypto), but the keypair lives in-process
|
|
10943
|
+
* and is regenerated on every construction. Not suitable as a managed
|
|
10944
|
+
* keychain; use it for tests and for shipping bundles where the
|
|
10945
|
+
* recipient instance lives in the same process as the sender (rare).
|
|
10946
|
+
*/
|
|
10947
|
+
declare class MemoryRecipientSealer implements SealingKeyProvider, RecipientSealer {
|
|
10948
|
+
readonly id: string;
|
|
10949
|
+
private readonly keypair;
|
|
10950
|
+
constructor(opts: {
|
|
10951
|
+
id: string;
|
|
10952
|
+
});
|
|
10953
|
+
publishRecipientHint(): Promise<RecipientHint>;
|
|
10954
|
+
sealForRecipient(plaintext: Uint8Array, hint: RecipientHint): Promise<Uint8Array>;
|
|
10955
|
+
seal(plaintext: Uint8Array): Promise<Uint8Array>;
|
|
10956
|
+
unseal(bytes: Uint8Array): Promise<Uint8Array>;
|
|
10957
|
+
}
|
|
9980
10958
|
/** Reserved id for the managed-passphrase envelope under `_meta`. */
|
|
9981
10959
|
declare const SEALED_PASSPHRASE_RECORD_ID: "sealed-passphrase";
|
|
9982
10960
|
/** Plaintext payload stored inside the `_meta/sealed-passphrase` envelope. */
|
|
@@ -9998,12 +10976,12 @@ interface SealedPassphrase {
|
|
|
9998
10976
|
*
|
|
9999
10977
|
* v1 shape (this release): `{ v: 1, _noydb_sealed: 1, pid, payload }`.
|
|
10000
10978
|
*
|
|
10001
|
-
* Legacy shape (
|
|
10979
|
+
* Legacy shape (earlier releases): `{ _noydb_sealed: 1, providerId, sealed }`
|
|
10002
10980
|
* — accepted on read for backwards compatibility; never produced on
|
|
10003
10981
|
* write going forward.
|
|
10004
10982
|
*/
|
|
10005
10983
|
interface SealedEnvelope {
|
|
10006
|
-
/** Envelope schema version. v1 is the shape
|
|
10984
|
+
/** Envelope schema version. v1 is the current shape. */
|
|
10007
10985
|
readonly v: 1;
|
|
10008
10986
|
/** Magic marker for forensics + legacy-shape detection. */
|
|
10009
10987
|
readonly _noydb_sealed: 1;
|
|
@@ -10017,9 +10995,9 @@ interface SealedEnvelope {
|
|
|
10017
10995
|
* in-memory {@link SealedPassphrase} representation. Accepts both:
|
|
10018
10996
|
*
|
|
10019
10997
|
* 1. v1 wire format `{ v: 1, _noydb_sealed: 1, pid, payload }` —
|
|
10020
|
-
* the shape
|
|
10998
|
+
* the current shape.
|
|
10021
10999
|
* 2. Legacy wire format `{ _noydb_sealed: 1, providerId, sealed }` —
|
|
10022
|
-
*
|
|
11000
|
+
* read-only; never written
|
|
10023
11001
|
* going forward.
|
|
10024
11002
|
*
|
|
10025
11003
|
* Returns `undefined` for any input that doesn't match either shape,
|
|
@@ -10404,9 +11382,9 @@ interface ImportCapability {
|
|
|
10404
11382
|
*/
|
|
10405
11383
|
type VaultPolicyOnDisk = Record<string, unknown>;
|
|
10406
11384
|
/**
|
|
10407
|
-
* Recovery profile enrolled at vault creation
|
|
11385
|
+
* Recovery profile enrolled at vault creation.
|
|
10408
11386
|
*
|
|
10409
|
-
* - `paper` — `on-recovery` codes (the
|
|
11387
|
+
* - `paper` — `on-recovery` codes (the standard end-to-end profile).
|
|
10410
11388
|
* - `shamir` / `multi-channel` / `admin-mediated` — API surface ships;
|
|
10411
11389
|
* per-profile dispatch lands in follow-up issues. Calling
|
|
10412
11390
|
* `db.recoverPassphrase` against these throws
|
|
@@ -10469,7 +11447,7 @@ interface KeyringAuthenticatorBase {
|
|
|
10469
11447
|
* extractable KEK from its own credential — WebAuthn (PRF-derived
|
|
10470
11448
|
* wrapping key) and split-key OIDC.
|
|
10471
11449
|
*
|
|
10472
|
-
* `wrapKind` is optional/absent on slots
|
|
11450
|
+
* `wrapKind` is optional/absent on older slots — those
|
|
10473
11451
|
* legacy slots are treated as wrap-KEK by default at unlock time.
|
|
10474
11452
|
*/
|
|
10475
11453
|
interface KeyringAuthenticatorWrappingKEK extends KeyringAuthenticatorBase {
|
|
@@ -10532,11 +11510,11 @@ interface KeyringFile {
|
|
|
10532
11510
|
readonly granted_by: string;
|
|
10533
11511
|
/**
|
|
10534
11512
|
* Passphrase canary — base64 AES-KW-wrapped form of a known constant
|
|
10535
|
-
* 256-bit value, wrapped under the keyring's KEK
|
|
11513
|
+
* 256-bit value, wrapped under the keyring's KEK.
|
|
10536
11514
|
*
|
|
10537
|
-
* Optional:
|
|
10538
|
-
* the multi-DEK corruption heuristic
|
|
10539
|
-
*
|
|
11515
|
+
* Optional: older keyrings load with no canary and fall back to
|
|
11516
|
+
* the multi-DEK corruption heuristic. Newer keyrings
|
|
11517
|
+
* carry one and let `loadKeyring` distinguish wrong-passphrase
|
|
10540
11518
|
* from corruption even when ALL DEKs (including a single-DEK keyring's
|
|
10541
11519
|
* sole DEK) are corrupted.
|
|
10542
11520
|
*
|
|
@@ -10758,6 +11736,23 @@ interface Conflict {
|
|
|
10758
11736
|
*/
|
|
10759
11737
|
readonly resolve?: (winner: EncryptedEnvelope | null) => void;
|
|
10760
11738
|
}
|
|
11739
|
+
/**
|
|
11740
|
+
* A same-device cross-tab write conflict: another tab overwrote a
|
|
11741
|
+
* document this tab had written, having diverged from an older base. Records
|
|
11742
|
+
* are decrypted (cross-tab handlers reconcile in plaintext). `base` is the
|
|
11743
|
+
* common ancestor from history, or null when history is unavailable.
|
|
11744
|
+
*/
|
|
11745
|
+
interface WriteConflict {
|
|
11746
|
+
readonly vault: string;
|
|
11747
|
+
readonly collection: string;
|
|
11748
|
+
readonly docId: string;
|
|
11749
|
+
readonly local: unknown;
|
|
11750
|
+
readonly remote: unknown;
|
|
11751
|
+
readonly base: unknown;
|
|
11752
|
+
readonly localVersion: number;
|
|
11753
|
+
readonly remoteVersion: number;
|
|
11754
|
+
readonly baseVersion: number;
|
|
11755
|
+
}
|
|
10761
11756
|
type ConflictStrategy = 'local-wins' | 'remote-wins' | 'version' | ((conflict: Conflict) => 'local' | 'remote');
|
|
10762
11757
|
/**
|
|
10763
11758
|
* Collection-level conflict policy.
|
|
@@ -10844,9 +11839,20 @@ interface ChangeEvent {
|
|
|
10844
11839
|
interface NoydbEventMap {
|
|
10845
11840
|
'change': ChangeEvent;
|
|
10846
11841
|
'error': Error;
|
|
11842
|
+
/**
|
|
11843
|
+
* Same-instance signal that this vault's schema-fence state changed.
|
|
11844
|
+
* For UI integration. Cross-client coordination goes
|
|
11845
|
+
* through the store, not this event.
|
|
11846
|
+
*/
|
|
11847
|
+
'schema:fence-changed': {
|
|
11848
|
+
vault: string;
|
|
11849
|
+
currentSchemaVersion: number;
|
|
11850
|
+
fenceState: 'normal' | 'draining' | 'migrating' | 'complete';
|
|
11851
|
+
};
|
|
10847
11852
|
'sync:push': PushResult;
|
|
10848
11853
|
'sync:pull': PullResult;
|
|
10849
11854
|
'sync:conflict': Conflict;
|
|
11855
|
+
'write:conflict': WriteConflict;
|
|
10850
11856
|
'sync:online': void;
|
|
10851
11857
|
'sync:offline': void;
|
|
10852
11858
|
'sync:backup-error': {
|
|
@@ -10941,7 +11947,7 @@ interface GrantOptions {
|
|
|
10941
11947
|
readonly initialProfile?: unknown;
|
|
10942
11948
|
}
|
|
10943
11949
|
/**
|
|
10944
|
-
* Caller payload for `db.updateUser
|
|
11950
|
+
* Caller payload for `db.updateUser`. Mutate one or more
|
|
10945
11951
|
* identity fields on an existing keyring without rotating any keys.
|
|
10946
11952
|
*
|
|
10947
11953
|
* `role`, `displayName`, and `permissions` live in the plaintext header
|
|
@@ -10955,7 +11961,7 @@ interface GrantOptions {
|
|
|
10955
11961
|
* `null` on `displayName` clears the field (stored as the empty string;
|
|
10956
11962
|
* UI consumers typically render the empty case by falling back to the
|
|
10957
11963
|
* user id). `undefined` / absent leaves the field untouched. Mirrors
|
|
10958
|
-
* the `null`-as-clear convention `UserApi.updateMe` uses
|
|
11964
|
+
* the `null`-as-clear convention `UserApi.updateMe` uses.
|
|
10959
11965
|
*
|
|
10960
11966
|
* `permissions`, however, is a **full replacement** at the map level —
|
|
10961
11967
|
* passing `{ invoices: 'rw' }` REPLACES the entire permissions map,
|
|
@@ -10969,8 +11975,6 @@ interface GrantOptions {
|
|
|
10969
11975
|
* do anything. Non-admin callers (operator/viewer/client) cannot call
|
|
10970
11976
|
* `db.updateUser` at all — for self-displayName changes, use
|
|
10971
11977
|
* `vault.user.updateMe` (the user-envelope API).
|
|
10972
|
-
*
|
|
10973
|
-
* @see #54
|
|
10974
11978
|
*/
|
|
10975
11979
|
interface UpdateUserOptions {
|
|
10976
11980
|
readonly userId: string;
|
|
@@ -11546,6 +12550,13 @@ interface NoydbOptions {
|
|
|
11546
12550
|
* @internal
|
|
11547
12551
|
*/
|
|
11548
12552
|
readonly syncStrategy?: SyncStrategy;
|
|
12553
|
+
/**
|
|
12554
|
+
* Tree-shake seam — optional snapshot-lifecycle subsystem. Pass
|
|
12555
|
+
* `withSnapshots({ store })` from `@noy-db/hub/snapshots` to enable
|
|
12556
|
+
* `db.snapshot()`, `db.listSnapshots()`, and `db.restoreSnapshot()`.
|
|
12557
|
+
* When omitted, all three methods throw with a pointer at the subpath.
|
|
12558
|
+
*/
|
|
12559
|
+
readonly snapshotStrategy?: SnapshotStrategy;
|
|
11549
12560
|
/**
|
|
11550
12561
|
* Optional guard strategies — collection-level write guards. Each
|
|
11551
12562
|
* handle is the output of `withGuard()` from `@noy-db/hub/guards`.
|
|
@@ -11562,7 +12573,7 @@ interface NoydbOptions {
|
|
|
11562
12573
|
*/
|
|
11563
12574
|
readonly derivationStrategies?: ReadonlyArray<DerivationStrategyHandle>;
|
|
11564
12575
|
/**
|
|
11565
|
-
* Optional materialized-view strategies
|
|
12576
|
+
* Optional materialized-view strategies.
|
|
11566
12577
|
* Each handle returned by `withMaterializedView()` from
|
|
11567
12578
|
* `@noy-db/hub/materialized-views`. The vault runs unified cycle
|
|
11568
12579
|
* detection across the MV + derivation graphs at `openVault`; a
|
|
@@ -11570,7 +12581,7 @@ interface NoydbOptions {
|
|
|
11570
12581
|
*/
|
|
11571
12582
|
readonly materializedViewStrategies?: ReadonlyArray<MaterializedViewStrategyHandle>;
|
|
11572
12583
|
/**
|
|
11573
|
-
* Optional overlay strategies
|
|
12584
|
+
* Optional overlay strategies. Each handle returned by
|
|
11574
12585
|
* `withOverlayedView()` from `@noy-db/hub/overlay-views`. The vault
|
|
11575
12586
|
* validates name uniqueness + base concreteness + overlay
|
|
11576
12587
|
* availability at `openVault`; a clash throws one of the
|
|
@@ -11623,7 +12634,7 @@ interface NoydbOptions {
|
|
|
11623
12634
|
*/
|
|
11624
12635
|
readonly getKeyring?: (vault: string) => Promise<UnlockedKeyring>;
|
|
11625
12636
|
/**
|
|
11626
|
-
* Passphrase mode
|
|
12637
|
+
* Passphrase mode. Default `'standard'`.
|
|
11627
12638
|
*
|
|
11628
12639
|
* - `'standard'` — the legacy flow. `secret` supplies the
|
|
11629
12640
|
* plaintext passphrase, the user knows it, and the policy gate
|
|
@@ -11684,14 +12695,14 @@ interface NoydbOptions {
|
|
|
11684
12695
|
readonly sessionPolicy?: SessionPolicy;
|
|
11685
12696
|
/**
|
|
11686
12697
|
* Validate passphrase strength against the phrase format
|
|
11687
|
-
*
|
|
12698
|
+
* on first-time keyring creation. When
|
|
11688
12699
|
* `true`, weak phrases throw {@link WeakPassphraseError} from
|
|
11689
12700
|
* `createNoydb()` / `db.rotatePassphrase()`. Default: `false` for
|
|
11690
|
-
* back-compat
|
|
12701
|
+
* back-compat; planned to flip to `true` in a future major release.
|
|
11691
12702
|
*/
|
|
11692
12703
|
readonly validatePassphrase?: boolean;
|
|
11693
12704
|
/**
|
|
11694
|
-
* Vault-level policy gate document
|
|
12705
|
+
* Vault-level policy gate document. When present, the hub
|
|
11695
12706
|
* persists the merged policy at `_meta/policy` on first-time vault
|
|
11696
12707
|
* creation and gates sensitive operations (`db.rotatePassphrase`,
|
|
11697
12708
|
* `db.export*`, …) against it. Omitted ⇒ the engine uses
|
|
@@ -11707,14 +12718,14 @@ interface NoydbOptions {
|
|
|
11707
12718
|
*/
|
|
11708
12719
|
readonly policy?: VaultPolicy;
|
|
11709
12720
|
/**
|
|
11710
|
-
* Mandatory recovery profile enrollment
|
|
12721
|
+
* Mandatory recovery profile enrollment. Vaults with
|
|
11711
12722
|
* `recover-passphrase` enabled MUST register at least one profile
|
|
11712
12723
|
* before being production-ready, otherwise `createNoydb()` throws
|
|
11713
12724
|
* {@link RecoveryNotEnrolledError}. Set
|
|
11714
12725
|
* `policy.gates['recover-passphrase'].enabled = false` to
|
|
11715
12726
|
* deliberately opt out of recovery (passphrase loss = data loss).
|
|
11716
12727
|
*
|
|
11717
|
-
*
|
|
12728
|
+
* The `'paper'` profile is supported end-to-end. Other
|
|
11718
12729
|
* profiles ship the API shape and throw
|
|
11719
12730
|
* {@link RecoveryProfileNotImplementedError} during use.
|
|
11720
12731
|
*/
|
|
@@ -11722,9 +12733,9 @@ interface NoydbOptions {
|
|
|
11722
12733
|
/**
|
|
11723
12734
|
* When `true`, `createNoydb` rejects vaults with no recovery
|
|
11724
12735
|
* entries persisted (per the spec's mandatory-enrollment
|
|
11725
|
-
* requirement). Default `false` for
|
|
11726
|
-
* flip to `true`
|
|
11727
|
-
* turn this on now.
|
|
12736
|
+
* requirement). Default `false` for back-compat; planned to
|
|
12737
|
+
* flip to `true` in a future major release. Apps in regulated
|
|
12738
|
+
* environments should turn this on now.
|
|
11728
12739
|
*/
|
|
11729
12740
|
readonly requireRecovery?: boolean;
|
|
11730
12741
|
/**
|
|
@@ -11851,4 +12862,4 @@ interface DeleteManyResult {
|
|
|
11851
12862
|
}>;
|
|
11852
12863
|
}
|
|
11853
12864
|
|
|
11854
|
-
export { type ConsentAuditEntry as $, type BlobObject as A, type BlobStrategy as B, type BlobPutOptions as C, DICT_COLLECTION_PREFIX as D, type BlobResponseOptions as E, BlobSet as F, type BlobStrategyOpenArgs as G, type CompactRunOptions as H, type I18nStrategy as I, type CompactionContext as J, type CompactionResult as K, DEFAULT_CHUNK_SIZE as L, EXPORT_AUDIT_COLLECTION as M, ExportBlobsAbortedError as N, type ExportBlobsAuditEntry as O, PolicyEnforcer as P, type ExportBlobsHandle as Q, type ExportBlobsOptions as R, type SessionStrategy as S, type ExportedBlob as T, type SlotInfo as U, type SlotRecord as V, type VersionRecord as W, createExportBlobsHandle as X, runCompaction as Y, type ConsentStrategy as Z, CONSENT_AUDIT_COLLECTION as _, type DictEntry as a, VaultInstant as a$, type ConsentAuditFilter as a0, type ConsentContext as a1, type ConsentOp as a2, loadConsentEntries as a3, writeConsentEntry as a4, type PeriodsStrategy as a5, type CarryForwardContext as a6, type ClosePeriodOptions as a7, type OpenPeriodOptions as a8, PERIODS_COLLECTION as a9, type DerivationStrategyHandle as aA, type DerivedFromMeta as aB, type OutputSpec as aC, type RecordOutputSpec as aD, type MaterializedViewStrategy as aE, type MaterializedViewStrategyHandle as aF, type OverlayedViewStrategy as aG, Collection as aH, OverlayedViewRegistry as aI, type OverlayedViewStrategyHandle as aJ, type SyncStrategy as aK, type Role as aL, type UnlockedKeyring as aM, type HistoryStrategy as aN, type NoydbStore as aO, type HistoryOptions as aP, type EncryptedEnvelope as aQ, type PruneOptions as aR, type AppendInput as aS, type ChangeType as aT, CollectionInstant as aU, type DiffEntry as aV, type JsonPatch as aW, type JsonPatchOp as aX, type LedgerEntry as aY, LedgerStore as aZ, type VaultEngine as a_, type PeriodRecord as aa, type ReadOnlyCollection as ab, appendPeriodLedgerEntry as ac, assertTsWritable as ad, chainAnchor as ae, loadPeriods as af, validatePeriodName as ag, type GuardStrategy as ah, type GuardChange as ai, type GuardContext as aj, GuardRegistry as ak, type GuardStrategyHandle as al, ReadOnlyVaultFacade as am, type ShadowStrategy as an, CollectionFrame as ao, VaultFrame as ap, type TxStrategy as aq, type AmendmentTxOptions as ar, TxCollection as as, TxContext as at, TxVault as au, runTransaction as av, type DerivationStrategy as aw, type DerivationContext as ax, type ArrayOutputSpec as ay, DerivationRegistry as az, type DictKeyDescriptor as b, type FactorRequirement as b$, type VerifyResult as b0, applyPatch as b1, canonicalJson as b2, computePatch as b3, diff as b4, formatDiff as b5, hashEntry as b6, paddedIndex as b7, parseIndex as b8, sha256Hex as b9, type CollectionDescriptor as bA, type CollectionStats as bB, type Conflict as bC, type ConflictPolicy as bD, type ConflictStrategy as bE, type CrossTierAccessEvent as bF, DEFAULT_PUBLIC_ENVELOPE_SCHEMA as bG, DELEGATIONS_COLLECTION as bH, type DeepPartial as bI, type DeepPartialOrNull as bJ, type DelegationToken as bK, type DeleteManyResult as bL, type DerivationDescriptor as bM, type DirtyEntry as bN, type DumpSchemaOptions as bO, ELEVATION_AUDIT_COLLECTION as bP, ElevatedHandle as bQ, type EnrollAuthenticatorOptions as bR, type EnrollAuthenticatorWrappingDEKsOptions as bS, type EnrollAuthenticatorWrappingKEKOptions as bT, type EnrollRecoveryResult as bU, type ExportCapability as bV, type ExportChunk as bW, type ExportFormat as bX, type ExportStreamOptions as bY, type FactorKind as bZ, type FactorProofBundle as b_, type MVQueryContext as ba, type RegisteredMV as bb, MaterializedViewRegistry as bc, type MaterializedFromMeta as bd, type MaterializedViewOutput as be, type UnionSource as bf, type UserEnvelope as bg, type PublicEnvelope as bh, type GateName as bi, type GatePolicy as bj, type VaultPolicy as bk, type ActiveTier as bl, type FactorProof as bm, type PersistedSchemaEnvelope as bn, type DirectoryConfig as bo, type UserVisibility as bp, Vault as bq, type AccessibleVault as br, BUNDLE_STORE_POLICY as bs, type BuiltInGateName as bt, type BundleRecipient as bu, type CacheOptions as bv, type CacheStats as bw, type ChangeEvent as bx, type CollectionChangeEvent as by, type CollectionConflictResolver as bz, DictionaryHandle as c, type PutManyItemOptions as c$, type FieldDescriptor as c0, type FieldSource as c1, type GhostRecord as c2, type GrantOptions as c3, type HistoryConfig as c4, type HistoryEntry as c5, INDEXED_STORE_POLICY as c6, type ImportCapability as c7, type InferOutput as c8, type InternalCollectionStats as c9, type NoydbBundleStore as cA, type NoydbEventMap as cB, type NoydbOptions as cC, type OverlayViewDescriptor as cD, PUBLIC_ENVELOPE_FIELDS as cE, type PaperRecoveryDoc as cF, type PaperRecoveryEntry as cG, type PassphrasePolicy as cH, type PassphraseValidationResult as cI, type Permission as cJ, type Permissions as cK, type PersistedSchemaKind as cL, type PlaintextTranslatorContext as cM, type PlaintextTranslatorFn as cN, PresenceHandle as cO, type PresencePeer as cP, type PublicEnvelopeField as cQ, type PublicEnvelopeSchema as cR, type PublicEnvelopeText as cS, type PullMode as cT, type PullOptions as cU, type PullPolicy as cV, type PullResult as cW, type PushMode as cX, type PushOptions as cY, type PushPolicy as cZ, type PushResult as c_, type IssueDelegationOptions as ca, type IssueMagicLinkGrantOptions as cb, type KeyringAuthenticator as cc, type KeyringAuthenticatorWrappingDEKs as cd, type KeyringAuthenticatorWrappingKEK as ce, type KeyringFile as cf, type ListAccessibleVaultsOptions as cg, type ListPageResult as ch, type ListUsersOptions as ci, type LiveUserEnvelope as cj, type LocaleReadOptions as ck, Lru as cl, type LruOptions as cm, type LruStats as cn, MAGIC_LINK_CONTENT_INFO_PREFIX as co, MAGIC_LINK_GRANTS_COLLECTION as cp, MAGIC_LINK_KEK_INFO_PREFIX as cq, type MagicLinkGrantPayload as cr, type MagicLinkGrantRecord as cs, type MaterializedViewDescriptor as ct, MemorySealingKeyProvider as cu, NOYDB_BACKUP_VERSION as cv, NOYDB_FORMAT_VERSION as cw, NOYDB_KEYRING_VERSION as cx, NOYDB_SYNC_VERSION as cy, Noydb as cz, type DictionaryOptions as d, type WeakPassphraseReason as d$, type PutManyOptions as d0, type PutManyResult as d1, type QueryAcrossOptions as d2, type QueryAcrossResult as d3, type QuickUnlockState as d4, QuickUnlockStore as d5, type ReAuthOperation as d6, type RecoverPassphraseInput as d7, type RecoverPassphraseResult as d8, type RecoverUserOptions as d9, type SyncPolicy as dA, SyncScheduler as dB, type SyncSchedulerStatus as dC, type SyncStatus as dD, type SyncTarget as dE, type SyncTargetRole as dF, SyncTransaction as dG, type SyncTransactionResult as dH, type TierMode as dI, type TranslatorAuditEntry as dJ, type TxOp as dK, USER_ENVELOPE_COLLECTION as dL, USER_ENVELOPE_MAX_BYTES as dM, type Unsubscribe as dN, type UpdateAuthenticatorOptions as dO, type UpdateUserOptions as dP, UserApi as dQ, type UserEnvelopeCheckGate as dR, UserEnvelopeOversizedError as dS, type UserEnvelopePresented as dT, type UserInfo as dU, type VaultBackup as dV, type VaultPolicyOnDisk as dW, type VaultSchemaSnapshot as dX, type VaultSnapshot as dY, type WarningRules as dZ, WeakPassphraseError as d_, type RecoveryProof as da, type ResolvedPublicEnvelopeSchema as db, type RevokeOptions as dc, type RotatePassphraseInput as dd, type RotateRecoveryOptions as de, type RotateRecoveryResult as df, SEALED_PASSPHRASE_RECORD_ID as dg, type SealedEnvelope as dh, type SealedPassphrase as di, type SealingKeyProvider as dj, type SessionPolicy as dk, type SetPublicEnvelopeInput as dl, type ShamirRecoveryDoc as dm, type ShamirRecoveryEntry as dn, type ShamirRecoveryProvider as dp, type SlotRewrapCeremony as dq, type SlotRewrapContext as dr, type StandardSchemaV1 as ds, type StandardSchemaV1Issue as dt, type StandardSchemaV1SyncResult as du, type StoreAuth as dv, type StoreAuthKind as dw, type StoreCapabilities as dx, SyncEngine as dy, type SyncMetadata as dz, type I18nTextDescriptor as e, type WrappedDeksBlob as e0, assertStrongPassphrase as e1, buildRecipientKeyringFile as e2, burnPaperRecoveryEntry as e3, createNoydb as e4, createStore as e5, deriveMagicLinkContentKey as e6, enrollAuthenticator as e7, estimateEntropy as e8, evaluateExportCapability as e9, revokeDelegation as eA, revokeMagicLinkGrant as eB, savePaperRecoveryEntries as eC, saveSealedPassphrase as eD, saveShamirRecoveryEntries as eE, unwrapDeksFromBlob as eF, unwrapDeksFromPaperEntry as eG, unwrapDeksFromShamirEntry as eH, unwrapMagicLinkGrant as eI, validatePassphrase as eJ, validatePublicEnvelopeInput as eK, validateSchemaInput as eL, validateSchemaOutput as eM, writeMagicLinkGrant as eN, changeSecret as eO, createOwnerKeyring as eP, ensureCollectionDEK as eQ, grant as eR, loadKeyring as eS, persistKeyring as eT, revoke as eU, updateAuthenticator as eV, updateKeyringIdentity as eW, evaluateImportCapability as ea, findAuthenticator as eb, hasExportCapability as ec, hasImportCapability as ed, hasRecoveryEnrolled as ee, isMagicLinkGrantExpired as ef, isPublicEnvelope as eg, issueDelegation as eh, recoverPassphrase as ei, rotatePassphrase as ej, listMagicLinkGrants as ek, listUsers as el, listUsersWithEnvelopes as em, loadActiveDelegations as en, loadPaperRecoveryEntries as eo, loadSealedPassphrase as ep, loadShamirRecoveryEntries as eq, magicLinkGrantRecordId as er, mintPaperRecoveryEntry as es, mintShamirRecoveryEntry as et, mintWrappedDeksBlob as eu, parseSealedEnvelope as ev, readMagicLinkGrantRecord as ew, recoverUser as ex, removeAuthenticator as ey, resolveSchema as ez, type I18nTextOptions as f, applyI18nLocale as g, dictCollectionName as h, dictKey as i, i18nText as j, isDictCollectionName as k, isDictKeyDescriptor as l, isI18nTextDescriptor as m, createEnforcer as n, validateSessionPolicy as o, BLOB_CHUNKS_COLLECTION as p, BLOB_COLLECTION as q, resolveI18nText as r, BLOB_EVICTION_AUDIT_COLLECTION as s, BLOB_INDEX_COLLECTION as t, BLOB_SLOTS_PREFIX as u, validateI18nTextValue as v, BLOB_VERSIONS_PREFIX as w, type BlobEvictionEntry as x, type BlobFieldPolicy as y, type BlobFieldsConfig as z };
|
|
12865
|
+
export { type ExportBlobsAuditEntry as $, BLOB_COLLECTION as A, type BlobStrategy as B, BLOB_EVICTION_AUDIT_COLLECTION as C, DICT_COLLECTION_PREFIX as D, BLOB_INDEX_COLLECTION as E, BLOB_SLOTS_PREFIX as F, BLOB_VERSIONS_PREFIX as G, type BlobEvictionEntry as H, type I18nStrategy as I, type BlobFieldPolicy as J, type BlobFieldsConfig as K, type Layer as L, type BlobObject as M, type BlobPutOptions as N, type OnMissing as O, PolicyEnforcer as P, type BlobResponseOptions as Q, type ResolveI18nOptions as R, type ScriptWarning as S, BlobSet as T, type BlobStrategyOpenArgs as U, type CompactRunOptions as V, type CompactionContext as W, type CompactionResult as X, DEFAULT_CHUNK_SIZE as Y, EXPORT_AUDIT_COLLECTION as Z, ExportBlobsAbortedError as _, type DictEntry as a, type SyncStrategy as a$, type ExportBlobsHandle as a0, type ExportBlobsOptions as a1, type ExportedBlob as a2, type SlotInfo as a3, type SlotRecord as a4, type VersionRecord as a5, createExportBlobsHandle as a6, runCompaction as a7, type ConsentStrategy as a8, CONSENT_AUDIT_COLLECTION as a9, VaultFrame as aA, type NoydbBundleStore as aB, type RetentionPolicy as aC, type SnapshotPolicy as aD, type SnapshotStrategy as aE, type SnapshotMeta as aF, type SnapshotMode as aG, type TxStrategy as aH, type AmendmentTxOptions as aI, TxCollection as aJ, TxContext as aK, TxVault as aL, runTransaction as aM, type DerivationStrategy as aN, type DerivationContext as aO, type ArrayOutputSpec as aP, DerivationRegistry as aQ, type DerivationStrategyHandle as aR, type DerivedFromMeta as aS, type OutputSpec as aT, type RecordOutputSpec as aU, type MaterializedViewStrategy as aV, type MaterializedViewStrategyHandle as aW, type OverlayedViewStrategy as aX, Collection as aY, OverlayedViewRegistry as aZ, type OverlayedViewStrategyHandle as a_, type ConsentAuditEntry as aa, type ConsentAuditFilter as ab, type ConsentContext as ac, type ConsentOp as ad, loadConsentEntries as ae, writeConsentEntry as af, type PeriodsStrategy as ag, type CarryForwardContext as ah, type ClosePeriodOptions as ai, type OpenPeriodOptions as aj, PERIODS_COLLECTION as ak, type PeriodRecord as al, type ReadOnlyCollection as am, appendPeriodLedgerEntry as an, assertTsWritable as ao, chainAnchor as ap, loadPeriods as aq, validatePeriodName as ar, type GuardStrategy as as, type GuardChange as at, type GuardContext as au, GuardRegistry as av, type GuardStrategyHandle as aw, ReadOnlyVaultFacade as ax, type ShadowStrategy as ay, CollectionFrame as az, type DictKeyDescriptor as b, type CollectionStats as b$, type Role as b0, type UnlockedKeyring as b1, type HistoryStrategy as b2, type NoydbStore as b3, type HistoryOptions as b4, type EncryptedEnvelope as b5, type PruneOptions as b6, type AppendInput as b7, type ChangeType as b8, CollectionInstant as b9, type RegisteredMV as bA, MaterializedViewRegistry as bB, type MaterializedFromMeta as bC, type MaterializedViewOutput as bD, type UnionSource as bE, type UserEnvelope as bF, type GateName as bG, type GatePolicy as bH, type VaultPolicy as bI, type ActiveTier as bJ, type FactorProof as bK, type SchemaUpdateStrategy as bL, type TransformFn as bM, type PersistedSchemaEnvelope as bN, type UpdateDecision as bO, type DirectoryConfig as bP, type UserVisibility as bQ, type AccessibleVault as bR, type AffectedDocument as bS, BUNDLE_STORE_POLICY as bT, type BuiltInGateName as bU, type CacheOptions as bV, type CacheStats as bW, type ChangeEvent as bX, type CollectionChangeEvent as bY, type CollectionConflictResolver as bZ, type CollectionDescriptor as b_, type DiffEntry as ba, type JsonPatch as bb, type JsonPatchOp as bc, type LedgerEntry as bd, LedgerStore as be, type VaultEngine as bf, VaultInstant as bg, type VerifyResult as bh, applyPatch as bi, canonicalJson as bj, computePatch as bk, diff as bl, formatDiff as bm, hashEntry as bn, paddedIndex as bo, parseIndex as bp, sha256Hex as bq, type PublicEnvelope as br, type SealingKeyProvider as bs, type BundleRecipient as bt, type RecipientSealer as bu, type RecipientHint as bv, Vault as bw, type RecoveryEnrollmentInput as bx, type ShamirRecoveryProvider as by, type MVQueryContext as bz, DictionaryHandle as c, NOYDB_BACKUP_VERSION as c$, type Conflict as c0, type ConflictPolicy as c1, type ConflictStrategy as c2, type CrossTierAccessEvent as c3, DEFAULT_PUBLIC_ENVELOPE_SCHEMA as c4, DELEGATIONS_COLLECTION as c5, type DeepPartial as c6, type DeepPartialOrNull as c7, type DelegationToken as c8, type DeleteManyResult as c9, type HistoryEntry as cA, INDEXED_STORE_POLICY as cB, type ImportCapability as cC, type InferOutput as cD, type InternalCollectionStats as cE, type IssueDelegationOptions as cF, type IssueMagicLinkGrantOptions as cG, type KeyringAuthenticator as cH, type KeyringAuthenticatorWrappingDEKs as cI, type KeyringAuthenticatorWrappingKEK as cJ, type KeyringFile as cK, type ListAccessibleVaultsOptions as cL, type ListPageResult as cM, type ListUsersOptions as cN, type LiveUserEnvelope as cO, type LocaleReadOptions as cP, Lru as cQ, type LruOptions as cR, type LruStats as cS, MAGIC_LINK_CONTENT_INFO_PREFIX as cT, MAGIC_LINK_GRANTS_COLLECTION as cU, MAGIC_LINK_KEK_INFO_PREFIX as cV, type MagicLinkGrantPayload as cW, type MagicLinkGrantRecord as cX, type MaterializedViewDescriptor as cY, MemoryRecipientSealer as cZ, MemorySealingKeyProvider as c_, type DerivationDescriptor as ca, type DirtyEntry as cb, type DryRunResult as cc, type DumpSchemaOptions as cd, ELEVATION_AUDIT_COLLECTION as ce, ElevatedHandle as cf, type EnrollAuthenticatorOptions as cg, type EnrollAuthenticatorWrappingDEKsOptions as ch, type EnrollAuthenticatorWrappingKEKOptions as ci, type EnrollRecoveryResult as cj, type ExportCapability as ck, type ExportChunk as cl, type ExportFormat as cm, type ExportStreamOptions as cn, type FactorKind as co, type FactorProofBundle as cp, type FactorRequirement as cq, type FenceDoc as cr, type FenceState as cs, type FieldChange as ct, type FieldDescriptor as cu, type FieldSource as cv, type GhostRecord as cw, type GrantOptions as cx, type GuardViolation as cy, type HistoryConfig as cz, type DictionaryOptions as d, type StoreAuthKind as d$, NOYDB_FORMAT_VERSION as d0, NOYDB_KEYRING_VERSION as d1, NOYDB_SYNC_VERSION as d2, Noydb as d3, type NoydbEventMap as d4, type NoydbOptions as d5, type OverlayViewDescriptor as d6, PUBLIC_ENVELOPE_FIELDS as d7, type PaperRecoveryDoc as d8, type PaperRecoveryEntry as d9, type QuickUnlockState as dA, QuickUnlockStore as dB, type ReAuthOperation as dC, type RecoverPassphraseInput as dD, type RecoverPassphraseResult as dE, type RecoverUserOptions as dF, type RecoveryProof as dG, type ResolvedPublicEnvelopeSchema as dH, type RevokeOptions as dI, type RotatePassphraseInput as dJ, type RotateRecoveryOptions as dK, type RotateRecoveryResult as dL, SEALED_PASSPHRASE_RECORD_ID as dM, type SchemaDelta as dN, type SchemaIntrospection as dO, type SealedEnvelope as dP, type SealedPassphrase as dQ, type SessionPolicy as dR, type SetPublicEnvelopeInput as dS, type ShamirRecoveryDoc as dT, type ShamirRecoveryEntry as dU, type SlotRewrapCeremony as dV, type SlotRewrapContext as dW, type StandardSchemaV1 as dX, type StandardSchemaV1Issue as dY, type StandardSchemaV1SyncResult as dZ, type StoreAuth as d_, type PassphrasePolicy as da, type PassphraseValidationResult as db, type Permission as dc, type Permissions as dd, type PersistedSchemaKind as de, type PlaintextTranslatorContext as df, type PlaintextTranslatorFn as dg, PresenceHandle as dh, type PresencePeer as di, type PublicEnvelopeField as dj, type PublicEnvelopeSchema as dk, type PublicEnvelopeText as dl, type PullMode as dm, type PullOptions as dn, type PullPolicy as dp, type PullResult as dq, type PushMode as dr, type PushOptions as ds, type PushPolicy as dt, type PushResult as du, type PutManyItemOptions as dv, type PutManyOptions as dw, type PutManyResult as dx, type QueryAcrossOptions as dy, type QueryAcrossResult as dz, type I18nMap as e, listUsersWithEnvelopes as e$, type StoreCapabilities as e0, SyncEngine as e1, type SyncMetadata as e2, type SyncPolicy as e3, SyncScheduler as e4, type SyncSchedulerStatus as e5, type SyncStatus as e6, type SyncTarget as e7, type SyncTargetRole as e8, SyncTransaction as e9, type WeakPassphraseReason as eA, type WrappedDeksBlob as eB, type WriteConflict as eC, type WriteEvent as eD, type WriteHook as eE, type WriteQueue as eF, assertStrongPassphrase as eG, buildRecipientKeyringFile as eH, burnPaperRecoveryEntry as eI, createNoydb as eJ, createStore as eK, deriveMagicLinkContentKey as eL, enrollAuthenticator as eM, estimateEntropy as eN, evaluateExportCapability as eO, evaluateImportCapability as eP, findAuthenticator as eQ, hasExportCapability as eR, hasImportCapability as eS, hasRecoveryEnrolled as eT, isMagicLinkGrantExpired as eU, isPublicEnvelope as eV, issueDelegation as eW, recoverPassphrase as eX, rotatePassphrase as eY, listMagicLinkGrants as eZ, listUsers as e_, type SyncTransactionResult as ea, type TabChannel as eb, type TabCoordinationOptions as ec, type TabLockManager as ed, type TabPresence as ee, type TabRole as ef, type TierMode as eg, type TranslatorAuditEntry as eh, type TxOp as ei, USER_ENVELOPE_COLLECTION as ej, USER_ENVELOPE_MAX_BYTES as ek, type Unsubscribe as el, type UpdateAuthenticatorOptions as em, type UpdateContext as en, type UpdateUserOptions as eo, UserApi as ep, type UserEnvelopeCheckGate as eq, UserEnvelopeOversizedError as er, type UserEnvelopePresented as es, type UserInfo as et, type VaultBackup as eu, type VaultPolicyOnDisk as ev, type VaultSchemaSnapshot as ew, type VaultSnapshot as ex, type WarningRules as ey, WeakPassphraseError as ez, type I18nTextDescriptor as f, loadActiveDelegations as f0, loadPaperRecoveryEntries as f1, loadSealedPassphrase as f2, loadShamirRecoveryEntries as f3, magicLinkGrantRecordId as f4, mintPaperRecoveryEntry as f5, mintShamirRecoveryEntry as f6, mintWrappedDeksBlob as f7, parseSealedEnvelope as f8, readMagicLinkGrantRecord as f9, recoverUser as fa, removeAuthenticator as fb, resolveSchema as fc, revokeDelegation as fd, revokeMagicLinkGrant as fe, savePaperRecoveryEntries as ff, saveSealedPassphrase as fg, saveShamirRecoveryEntries as fh, unwrapDeksFromBlob as fi, unwrapDeksFromPaperEntry as fj, unwrapDeksFromShamirEntry as fk, unwrapMagicLinkGrant as fl, validatePassphrase as fm, validatePublicEnvelopeInput as fn, validateSchemaInput as fo, validateSchemaOutput as fp, writeMagicLinkGrant as fq, changeSecret as fr, createOwnerKeyring as fs, ensureCollectionDEK as ft, grant as fu, loadKeyring as fv, persistKeyring as fw, revoke as fx, updateAuthenticator as fy, updateKeyringIdentity as fz, type I18nTextOptions as g, type OnMissingPolicy as h, applyI18nLocale as i, dictCollectionName as j, dictKey as k, enforceScript as l, getAtPath as m, i18nText as n, inferScripts as o, isDictCollectionName as p, isDictKeyDescriptor as q, isI18nTextDescriptor as r, resolveI18nText as s, resolvePolicy as t, setAtPathInPlace as u, validateI18nTextValue as v, type SessionStrategy as w, createEnforcer as x, validateSessionPolicy as y, BLOB_CHUNKS_COLLECTION as z };
|