@noy-db/hub 0.6.0-pre.2 → 0.6.0-pre.20
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/codemods/0.4.0-pre.json +699 -0
- package/codemods/0.6.0-pre.json +211 -0
- package/dist/api-Z5VHH24A.js +20 -0
- package/dist/attestation/index.js +19 -19
- package/dist/{backup-YYBE5RPC.js → backup-K62BFMYK.js} +36 -18
- package/dist/backup-K62BFMYK.js.map +1 -0
- package/dist/blobs/index.js +13 -13
- package/dist/broker/index.js +12 -12
- package/dist/cargo/index.js +33 -33
- package/dist/{chunk-FDX7OWWI.js → chunk-2E2MKBMI.js} +2 -2
- package/dist/{chunk-VOQW5LAM.js → chunk-2IK6AC6A.js} +102 -71
- package/dist/chunk-2IK6AC6A.js.map +1 -0
- package/dist/{chunk-EDXAQ6JI.js → chunk-32O2N2CH.js} +87 -34
- package/dist/chunk-32O2N2CH.js.map +1 -0
- package/dist/{chunk-W5W6KHN2.js → chunk-3Y4OFWQJ.js} +1 -1
- package/dist/chunk-3Y4OFWQJ.js.map +1 -0
- package/dist/{chunk-7G6VDWXB.js → chunk-437FDIHO.js} +3 -3
- package/dist/chunk-437FDIHO.js.map +1 -0
- package/dist/{chunk-3FSX6LDG.js → chunk-47ZFULEZ.js} +8 -3
- package/dist/{chunk-3FSX6LDG.js.map → chunk-47ZFULEZ.js.map} +1 -1
- package/dist/{chunk-ZJADGNYF.js → chunk-4AOERLTV.js} +1 -1
- package/dist/chunk-4AOERLTV.js.map +1 -0
- package/dist/{chunk-MWKDOHEF.js → chunk-4HVTRHSA.js} +17 -10
- package/dist/chunk-4HVTRHSA.js.map +1 -0
- package/dist/{chunk-V5KYPBUR.js → chunk-5BS6IQZZ.js} +11 -14
- package/dist/chunk-5BS6IQZZ.js.map +1 -0
- package/dist/{chunk-LWSJG3LI.js → chunk-5EJQNA26.js} +7 -3
- package/dist/chunk-5EJQNA26.js.map +1 -0
- package/dist/{chunk-7F4DBNSP.js → chunk-5J5TTSGW.js} +3 -3
- package/dist/{chunk-BTVYJWSN.js → chunk-5JT4Y5UE.js} +10 -10
- package/dist/{chunk-C2OOEM57.js → chunk-6S466CMQ.js} +92 -35
- package/dist/chunk-6S466CMQ.js.map +1 -0
- package/dist/{chunk-PY7CI6L5.js → chunk-6TXUVKPG.js} +516 -263
- package/dist/chunk-6TXUVKPG.js.map +1 -0
- package/dist/{chunk-7NXHMW6Y.js → chunk-7RCZ436O.js} +2 -2
- package/dist/{chunk-DG27IUVI.js → chunk-A3NTKHDB.js} +2 -2
- package/dist/{chunk-CCZJJ4I2.js → chunk-A4K5GLE6.js} +4 -4
- package/dist/{chunk-CEJWMBXO.js → chunk-APV42WPR.js} +2 -2
- package/dist/{chunk-4HDYQL3J.js → chunk-AQF7JSQR.js} +2 -2
- package/dist/{chunk-KUDZVJKQ.js → chunk-BP4I7IBK.js} +2 -2
- package/dist/{chunk-4UVDI4XE.js → chunk-BTNKPDZM.js} +4 -4
- package/dist/{chunk-HVQGCKY4.js → chunk-C7WJNVJG.js} +2 -2
- package/dist/{chunk-WYZ5MYUA.js → chunk-CV7WXCZD.js} +44 -42
- package/dist/chunk-CV7WXCZD.js.map +1 -0
- package/dist/{chunk-KCQX65FU.js → chunk-CVYXIN5B.js} +3 -3
- package/dist/{chunk-VN45YLWM.js → chunk-D5UDZANO.js} +255 -132
- package/dist/chunk-D5UDZANO.js.map +1 -0
- package/dist/{chunk-AR2JDFAE.js → chunk-DJ23QZIN.js} +2 -2
- package/dist/{chunk-PJNTR2NV.js → chunk-DKYEVHZH.js} +7 -10
- package/dist/chunk-DKYEVHZH.js.map +1 -0
- package/dist/{chunk-SZ2K3MHL.js → chunk-DYASJSKI.js} +8 -11
- package/dist/{chunk-SZ2K3MHL.js.map → chunk-DYASJSKI.js.map} +1 -1
- package/dist/{chunk-G5APARUV.js → chunk-E6VDPBE3.js} +13 -15
- package/dist/chunk-E6VDPBE3.js.map +1 -0
- package/dist/{chunk-A67356IR.js → chunk-EG6AQBYW.js} +33 -8
- package/dist/chunk-EG6AQBYW.js.map +1 -0
- package/dist/{chunk-PVU7LW5L.js → chunk-EJIVFOOQ.js} +6 -6
- package/dist/{chunk-VRA4Q7DA.js → chunk-F5AJZC3U.js} +35 -47
- package/dist/chunk-F5AJZC3U.js.map +1 -0
- package/dist/{chunk-VMCCGUQB.js → chunk-GDGTIWB4.js} +2 -2
- package/dist/{chunk-FUHKW252.js → chunk-GILI76SU.js} +2 -2
- package/dist/{chunk-35EBKWQU.js → chunk-GT72D4FO.js} +4 -4
- package/dist/{chunk-PRDRGL73.js → chunk-GYUCRDAU.js} +17 -14
- package/dist/chunk-GYUCRDAU.js.map +1 -0
- package/dist/{chunk-JRCYZEHU.js → chunk-HGJC7I5F.js} +2 -2
- package/dist/{chunk-TOAIYQJR.js → chunk-HJRTFXAA.js} +7 -10
- package/dist/chunk-HJRTFXAA.js.map +1 -0
- package/dist/chunk-HK67PX4J.js +27 -0
- package/dist/chunk-HK67PX4J.js.map +1 -0
- package/dist/{chunk-JXIDGFKS.js → chunk-HTHRCGWP.js} +4 -2
- package/dist/chunk-HTHRCGWP.js.map +1 -0
- package/dist/{chunk-AHLJSVRL.js → chunk-HTMQBBF3.js} +5 -7
- package/dist/chunk-HTMQBBF3.js.map +1 -0
- package/dist/{chunk-ZNACADFG.js → chunk-ICCRAPWD.js} +4 -4
- package/dist/chunk-ICCRAPWD.js.map +1 -0
- package/dist/{chunk-66W5OOCX.js → chunk-IOURTXTM.js} +52 -65
- package/dist/chunk-IOURTXTM.js.map +1 -0
- package/dist/{chunk-MZ5ZFO2D.js → chunk-IPDS2TYW.js} +84 -112
- package/dist/chunk-IPDS2TYW.js.map +1 -0
- package/dist/{chunk-UIBGXRDD.js → chunk-JHO6FGZX.js} +25 -31
- package/dist/chunk-JHO6FGZX.js.map +1 -0
- package/dist/{chunk-YAWK6AWF.js → chunk-JIF3IBRK.js} +2 -2
- package/dist/{chunk-HNHCQ556.js → chunk-KBOPY6W2.js} +2 -2
- package/dist/{chunk-UHXCLPGC.js → chunk-KDX6VEYV.js} +2 -2
- package/dist/chunk-KDX6VEYV.js.map +1 -0
- package/dist/{chunk-W3TVWF6N.js → chunk-KM6YR5XF.js} +2 -2
- package/dist/{chunk-3737A6EA.js → chunk-KUXTWVAR.js} +75 -18
- package/dist/chunk-KUXTWVAR.js.map +1 -0
- package/dist/chunk-L2XQ776M.js +123 -0
- package/dist/chunk-L2XQ776M.js.map +1 -0
- package/dist/{chunk-E6427JU2.js → chunk-L6FSZFG7.js} +18 -2
- package/dist/chunk-L6FSZFG7.js.map +1 -0
- package/dist/{chunk-5PR33AC4.js → chunk-M4IKEOJS.js} +20 -17
- package/dist/chunk-M4IKEOJS.js.map +1 -0
- package/dist/{chunk-6HFM7EIT.js → chunk-MNMYHZVU.js} +2 -2
- package/dist/{chunk-NIVEDYJZ.js → chunk-MNUTPZRQ.js} +31 -49
- package/dist/chunk-MNUTPZRQ.js.map +1 -0
- package/dist/{chunk-VV4NSB7P.js → chunk-MQXYR65M.js} +15 -24
- package/dist/chunk-MQXYR65M.js.map +1 -0
- package/dist/{chunk-QD724WDJ.js → chunk-N2HKBESK.js} +4 -4
- package/dist/{chunk-Z45YRGFO.js → chunk-N7YAQKAO.js} +2 -2
- package/dist/{chunk-DMQCLZ4Z.js → chunk-NH2MST6J.js} +2 -2
- package/dist/{chunk-TAGFGKHP.js → chunk-NRNTXBHT.js} +7 -10
- package/dist/chunk-NRNTXBHT.js.map +1 -0
- package/dist/{chunk-I6SDX7WX.js → chunk-NYSD43OE.js} +16 -22
- package/dist/chunk-NYSD43OE.js.map +1 -0
- package/dist/{chunk-I4F6PKUK.js → chunk-ODVIFBAQ.js} +16 -17
- package/dist/chunk-ODVIFBAQ.js.map +1 -0
- package/dist/{chunk-26JMGSSC.js → chunk-OIIAXFKM.js} +4 -4
- package/dist/chunk-OIIAXFKM.js.map +1 -0
- package/dist/{chunk-HXGUIPQB.js → chunk-OQLYMBJI.js} +3 -3
- package/dist/{chunk-RKKORO4M.js → chunk-OWGEHDT2.js} +10 -10
- package/dist/chunk-OWGEHDT2.js.map +1 -0
- package/dist/{chunk-HNGSV2YC.js → chunk-P7L3OQLL.js} +25 -10
- package/dist/chunk-P7L3OQLL.js.map +1 -0
- package/dist/{chunk-MSWYQLMQ.js → chunk-PG6PFMDC.js} +2 -2
- package/dist/{chunk-E7OBCBXS.js → chunk-PNAIDIP7.js} +13 -16
- package/dist/chunk-PNAIDIP7.js.map +1 -0
- package/dist/{chunk-GLKDWWNO.js → chunk-PZSS7MUM.js} +16 -14
- package/dist/chunk-PZSS7MUM.js.map +1 -0
- package/dist/{chunk-WKPJXWKR.js → chunk-QPIUFRUC.js} +3 -3
- package/dist/{chunk-JIUVJ4M7.js → chunk-REL4OLWW.js} +2 -2
- package/dist/{chunk-ERB6NDDW.js → chunk-RKDH6L53.js} +134 -33
- package/dist/chunk-RKDH6L53.js.map +1 -0
- package/dist/{chunk-VW6ZZGCG.js → chunk-RNSC2ARR.js} +3 -3
- package/dist/{chunk-WLYIROCJ.js → chunk-RORE2GX2.js} +2 -2
- package/dist/{chunk-TDJPS3T2.js → chunk-RQY5UWEL.js} +24 -19
- package/dist/chunk-RQY5UWEL.js.map +1 -0
- package/dist/{chunk-7TSYBD3E.js → chunk-RSFG7XHM.js} +2 -2
- package/dist/{chunk-FAXZQ5UF.js → chunk-S55DBWRC.js} +2 -2
- package/dist/{chunk-WHJKIZS7.js → chunk-SA77BQ7F.js} +27 -149
- package/dist/chunk-SA77BQ7F.js.map +1 -0
- package/dist/{chunk-747LRSOO.js → chunk-SFD2LL7G.js} +2 -2
- package/dist/{chunk-P7OG2ETF.js → chunk-SG3OQCRG.js} +3 -3
- package/dist/{chunk-55LKVALY.js → chunk-T7IR4N2S.js} +1 -3
- package/dist/chunk-T7IR4N2S.js.map +1 -0
- package/dist/{chunk-EP7VPR7Y.js → chunk-TC6MBEGH.js} +11 -8
- package/dist/chunk-TC6MBEGH.js.map +1 -0
- package/dist/{chunk-HFQ6LGIO.js → chunk-TENLCGYD.js} +12 -10
- package/dist/{chunk-HFQ6LGIO.js.map → chunk-TENLCGYD.js.map} +1 -1
- package/dist/{chunk-WQDTCJ6W.js → chunk-VEX2BQVX.js} +3 -3
- package/dist/{chunk-7VHY5E3X.js → chunk-VH2W6BOG.js} +7 -7
- package/dist/chunk-VHVMJWM6.js +201 -0
- package/dist/chunk-VHVMJWM6.js.map +1 -0
- package/dist/{chunk-VCETL77O.js → chunk-VJ4B3ZXY.js} +27 -7
- package/dist/chunk-VJ4B3ZXY.js.map +1 -0
- package/dist/{chunk-OF3L2SD6.js → chunk-W6NFONOV.js} +2 -2
- package/dist/{chunk-NJDQ4YSV.js → chunk-WBNXZU42.js} +4 -4
- package/dist/{chunk-FNSMZQS4.js → chunk-WKD5ESK4.js} +2 -2
- package/dist/{chunk-NKH7GSIH.js → chunk-XGQGWZ6D.js} +4 -4
- package/dist/chunk-YOT7D63X.js +190 -0
- package/dist/chunk-YOT7D63X.js.map +1 -0
- package/dist/{chunk-4MC5JRRX.js → chunk-YVTADFTC.js} +14 -15
- package/dist/chunk-YVTADFTC.js.map +1 -0
- package/dist/{chunk-GASWQ3XG.js → chunk-ZBDWKPBW.js} +15 -16
- package/dist/chunk-ZBDWKPBW.js.map +1 -0
- package/dist/{chunk-52QYGZHH.js → chunk-ZPMXYPBR.js} +2 -2
- package/dist/chunk-ZPMXYPBR.js.map +1 -0
- package/dist/chunk-ZVAFJQZB.js +66 -0
- package/dist/chunk-ZVAFJQZB.js.map +1 -0
- package/dist/{chunk-VJFMXYKP.js → chunk-ZWKF3CD3.js} +2 -2
- package/dist/{chunk-I4ZAO7F7.js → chunk-ZXW3X3DQ.js} +7 -11
- package/dist/chunk-ZXW3X3DQ.js.map +1 -0
- package/dist/classified/index.js +5 -5
- package/dist/{classified-marker-FTOX7Q5L.js → classified-marker-PMDG3O36.js} +3 -3
- package/dist/collection-facade-ZJK5EB33.js +45 -0
- package/dist/{computed-6G5M3UPH.js → computed-UHCBRILW.js} +3 -3
- package/dist/consent/index.js +10 -10
- package/dist/cover/index.js +10 -3
- package/dist/custody/index.js +11 -11
- package/dist/{dead-filter-ENRIOQIE.js → dead-filter-777VWDER.js} +2 -2
- package/dist/debug/index.js +1 -1
- package/dist/{delegation-SSEPLXXO.js → delegation-4R5DU23X.js} +24 -23
- package/dist/delegation-4R5DU23X.js.map +1 -0
- package/dist/derivations/index.js +12 -12
- package/dist/derive-3WAS2G5T.js +22 -0
- package/dist/directory/index.js +10 -10
- package/dist/{dispatch-BDVGYC6X.js → dispatch-3EN6YCCS.js} +18 -18
- package/dist/{dispatch-RE74SH6L.js → dispatch-ASL257KG.js} +5 -5
- package/dist/{enclave-52VUXNRL.js → enclave-ZJS5R5RH.js} +25 -9
- package/dist/executor-GPM6DNWV.js +9 -0
- package/dist/executor-LJSMZ4IB.js +9 -0
- package/dist/executor-SHUVRZUJ.js +29 -0
- package/dist/export-accessible-GNY6DC6U.js +23 -0
- package/dist/extract-partition-BG3AF4NZ.js +38 -0
- package/dist/{fanout-sidecar-DTBIDOWF.js → fanout-sidecar-TFPWDOME.js} +18 -27
- package/dist/fanout-sidecar-TFPWDOME.js.map +1 -0
- package/dist/find-KX6OKHDP.js +11 -0
- package/dist/forget/index.js +9 -9
- package/dist/guards/index.js +4 -4
- package/dist/history/index.js +23 -20
- package/dist/history/index.js.map +1 -1
- package/dist/i18n/index.js +14 -14
- package/dist/index.d.ts +32 -15
- package/dist/index.js +183 -191
- package/dist/index.js.map +1 -1
- package/dist/indexing/index.js +2 -2
- package/dist/introspection/index.js +11 -11
- package/dist/issue-PAUM7NCX.js +19 -0
- package/dist/kernel/enclave/crypto.d.ts +24 -4
- package/dist/kernel/enclave/index.d.ts +8 -2
- package/dist/kernel/enclave/record-aad.d.ts +131 -0
- package/dist/kernel/enclave/record-envelope.d.ts +76 -0
- package/dist/kernel/enclave/record-keys/envelope-body.d.ts +34 -2
- package/dist/kernel/enclave/record-keys/lifecycle.d.ts +22 -5
- package/dist/kernel/enclave/record-keys/record-codec.d.ts +47 -14
- package/dist/kernel/enclave/record-keys/rekey.d.ts +68 -0
- package/dist/kernel/enclave/record-keys/tombstone.d.ts +3 -2
- package/dist/kernel/errors.d.ts +23 -11
- package/dist/kernel/merge-authority.d.ts +25 -0
- package/dist/kernel/noydb.d.ts +9 -3
- package/dist/kernel/query/builder.d.ts +15 -2
- package/dist/kernel/query/join.d.ts +27 -0
- package/dist/kernel/sync-policy.d.ts +0 -2
- package/dist/kernel/tier-visibility.d.ts +15 -0
- package/dist/kernel/types.d.ts +125 -6
- package/dist/kernel/vault.d.ts +21 -17
- package/dist/kernel/via/index.d.ts +11 -2
- package/dist/{ledger-4WJL66BW.js → ledger-62CEPRPX.js} +11 -11
- package/dist/liberate-I6AOLWXW.js +24 -0
- package/dist/{link-set-N4ZPV6E6.js → link-set-ZRYNUHN3.js} +11 -11
- package/dist/{managed-secret-OTHS64IF.js → managed-secret-T2WB4O47.js} +11 -3
- package/dist/materialized-views/index.js +22 -21
- package/dist/money/index.js +12 -8
- package/dist/noydb-SS6EN7TK.js +84 -0
- package/dist/overlay-views/index.js +4 -4
- package/dist/periods/index.js +22 -12
- package/dist/pod/index.js +75 -86
- package/dist/pod-handle-UPLXOGIK.js +41 -0
- package/dist/pod-handle-UPLXOGIK.js.map +1 -0
- package/dist/policy/index.js +11 -4
- package/dist/port/to/index.d.ts +4 -4
- package/dist/port/to/locator.d.ts +54 -8
- package/dist/port/with/i18n-strategy.d.ts +4 -1
- package/dist/port/with/lookup-strategy.d.ts +4 -1
- package/dist/port/with/merge-authority.d.ts +52 -0
- package/dist/port/with/service-bus.d.ts +0 -4
- package/dist/port/with/strategies.d.ts +2 -0
- package/dist/portability/index.js +8 -8
- package/dist/{post-register-ZAG2CAIY.js → post-register-J4DEVNXK.js} +6 -6
- package/dist/query/index.js +3 -3
- package/dist/reduce/index.js +4 -4
- package/dist/register-UPD4GKBC.js +32 -0
- package/dist/registry-7KX2HWFS.js +18 -0
- package/dist/registry-PKYYEHEW.js +9 -0
- package/dist/registry-XHCYMD34.js +19 -0
- package/dist/registry-XIRTZHPC.js +9 -0
- package/dist/request-withdrawal-XZSESWZV.js +31 -0
- package/dist/{reveal-CMOJY4VO.js → reveal-525XWQU2.js} +6 -6
- package/dist/revoke-QI7YHQ2B.js +24 -0
- package/dist/satellites/index.js +1 -1
- package/dist/schema-update/index.js +2 -2
- package/dist/sealed-record/index.js +20 -13
- package/dist/sealed-record/index.js.map +1 -1
- package/dist/search/index.js +4 -4
- package/dist/{seed-UK4QRIUN.js → seed-SGIF3EN4.js} +19 -22
- package/dist/seed-SGIF3EN4.js.map +1 -0
- package/dist/sequence/index.js +9 -9
- package/dist/session/index.js +10 -10
- package/dist/shadow/index.js +2 -2
- package/dist/share-link/index.js +1 -1
- package/dist/signer-BZWDPGGN.js +25 -0
- package/dist/snapshots/index.js +10 -10
- package/dist/snapshots/index.js.map +1 -1
- package/dist/{stale-ZWXSOWJI.js → stale-PQYPVCER.js} +10 -10
- package/dist/storage-MJHKNQRO.js +23 -0
- package/dist/{store-coordination-provider-PB6QZ57W.js → store-coordination-provider-TFHZLKHG.js} +18 -12
- package/dist/store-coordination-provider-TFHZLKHG.js.map +1 -0
- package/dist/sync/index.js +11 -11
- package/dist/team/index.js +15 -14
- package/dist/tiers/index.js +11 -10
- package/dist/to/index.js +17 -9
- package/dist/to/index.js.map +1 -1
- package/dist/transactions/index.js +4 -4
- package/dist/{ulid-PTAIMDG4.js → ulid-VQW6ERQN.js} +2 -2
- package/dist/util/index.js +1 -1
- package/dist/vault-head/index.js +115 -0
- package/dist/vault-head/index.js.map +1 -0
- package/dist/{verify-RO5RTZOJ.js → verify-J6DEOXP3.js} +5 -5
- package/dist/via/lookup/handle.d.ts +4 -1
- package/dist/via/money/exact.d.ts +44 -0
- package/dist/via/money/index.d.ts +2 -0
- package/dist/via/money/normalize.d.ts +20 -0
- package/dist/walk-BX4NSB5L.js +21 -0
- package/dist/with-audit/guards/immutable-guard.d.ts +14 -0
- package/dist/with-audit/periods/active.d.ts +28 -1
- package/dist/with-audit/periods/index.d.ts +4 -2
- package/dist/with-audit/periods/periods.d.ts +161 -6
- package/dist/with-audit/periods/strategy.d.ts +14 -5
- package/dist/with-audit/periods/vault-facade.d.ts +89 -10
- package/dist/with-audit/periods/window.d.ts +10 -0
- package/dist/with-audit/sealed-record/index.d.ts +13 -0
- package/dist/with-audit/tiers/index.d.ts +17 -2
- package/dist/with-cargo/adopt-partition.d.ts +1 -1
- package/dist/with-cargo/extract-partition.d.ts +1 -1
- package/dist/with-cargo/index.d.ts +2 -2
- package/dist/with-commit/history/history.d.ts +26 -0
- package/dist/with-commit/history/index.d.ts +2 -1
- package/dist/with-commit/history/ledger/store.d.ts +7 -1
- package/dist/with-commit/history/strategy.d.ts +11 -1
- package/dist/with-commit/numbering/index.d.ts +0 -5
- package/dist/with-commit/vault-head/active.d.ts +2 -0
- package/dist/with-commit/vault-head/head.d.ts +28 -0
- package/dist/with-commit/vault-head/index.d.ts +10 -0
- package/dist/with-commit/vault-head/strategy.d.ts +127 -0
- package/dist/with-commit/vault-head/verify.d.ts +90 -0
- package/dist/with-formula/materialized-views/types.d.ts +52 -0
- package/dist/with-party/directory/cover/storage.d.ts +0 -8
- package/dist/with-party/directory/storage.d.ts +0 -11
- package/dist/with-party/directory/visibility.d.ts +0 -21
- package/dist/with-party/policy/storage.d.ts +0 -10
- package/dist/with-party/team/index.d.ts +1 -1
- package/dist/with-party/team/keyring.d.ts +17 -3
- package/dist/with-party/team/tiers.d.ts +2 -1
- package/dist/with-pod/format.d.ts +10 -12
- package/dist/with-pod/index.d.ts +10 -10
- package/dist/with-pod/open.d.ts +2 -2
- package/dist/with-pod/pod-handle.d.ts +19 -0
- package/dist/with-pod/pod-store.d.ts +0 -8
- package/dist/with-pod/{bundle.d.ts → pod.d.ts} +26 -19
- package/dist/with-pod/ulid.d.ts +1 -1
- package/dist/with-shape/introspection/index.d.ts +1 -0
- package/dist/with-sync/engine.d.ts +54 -5
- package/dist/with-sync/strategy.d.ts +3 -0
- package/dist/withdraw-accessible-K4CPMH4C.js +28 -0
- package/package.json +12 -5
- package/dist/api-WVY3H3YH.js +0 -20
- package/dist/backup-YYBE5RPC.js.map +0 -1
- package/dist/bundle-handle-JEUWU2SJ.js +0 -36
- package/dist/bundle-handle-JEUWU2SJ.js.map +0 -1
- package/dist/chunk-26JMGSSC.js.map +0 -1
- package/dist/chunk-3737A6EA.js.map +0 -1
- package/dist/chunk-4MC5JRRX.js.map +0 -1
- package/dist/chunk-52QYGZHH.js.map +0 -1
- package/dist/chunk-55LKVALY.js.map +0 -1
- package/dist/chunk-5PR33AC4.js.map +0 -1
- package/dist/chunk-66W5OOCX.js.map +0 -1
- package/dist/chunk-7G6VDWXB.js.map +0 -1
- package/dist/chunk-A67356IR.js.map +0 -1
- package/dist/chunk-AFHQATY4.js +0 -47
- package/dist/chunk-AFHQATY4.js.map +0 -1
- package/dist/chunk-AHLJSVRL.js.map +0 -1
- package/dist/chunk-C2OOEM57.js.map +0 -1
- package/dist/chunk-DIMKRG2E.js +0 -131
- package/dist/chunk-DIMKRG2E.js.map +0 -1
- package/dist/chunk-E6427JU2.js.map +0 -1
- package/dist/chunk-E7OBCBXS.js.map +0 -1
- package/dist/chunk-EDXAQ6JI.js.map +0 -1
- package/dist/chunk-EP7VPR7Y.js.map +0 -1
- package/dist/chunk-ERB6NDDW.js.map +0 -1
- package/dist/chunk-G5APARUV.js.map +0 -1
- package/dist/chunk-GASWQ3XG.js.map +0 -1
- package/dist/chunk-GLKDWWNO.js.map +0 -1
- package/dist/chunk-HNGSV2YC.js.map +0 -1
- package/dist/chunk-I4F6PKUK.js.map +0 -1
- package/dist/chunk-I4ZAO7F7.js.map +0 -1
- package/dist/chunk-I6SDX7WX.js.map +0 -1
- package/dist/chunk-JXIDGFKS.js.map +0 -1
- package/dist/chunk-LWSJG3LI.js.map +0 -1
- package/dist/chunk-MWKDOHEF.js.map +0 -1
- package/dist/chunk-MZ5ZFO2D.js.map +0 -1
- package/dist/chunk-NIVEDYJZ.js.map +0 -1
- package/dist/chunk-NWCGDAV6.js +0 -45
- package/dist/chunk-NWCGDAV6.js.map +0 -1
- package/dist/chunk-PJNTR2NV.js.map +0 -1
- package/dist/chunk-PRDRGL73.js.map +0 -1
- package/dist/chunk-PY7CI6L5.js.map +0 -1
- package/dist/chunk-RKKORO4M.js.map +0 -1
- package/dist/chunk-TAGFGKHP.js.map +0 -1
- package/dist/chunk-TDJPS3T2.js.map +0 -1
- package/dist/chunk-TOAIYQJR.js.map +0 -1
- package/dist/chunk-UHXCLPGC.js.map +0 -1
- package/dist/chunk-UIBGXRDD.js.map +0 -1
- package/dist/chunk-V5KYPBUR.js.map +0 -1
- package/dist/chunk-VCETL77O.js.map +0 -1
- package/dist/chunk-VN45YLWM.js.map +0 -1
- package/dist/chunk-VOQW5LAM.js.map +0 -1
- package/dist/chunk-VRA4Q7DA.js.map +0 -1
- package/dist/chunk-VV4NSB7P.js.map +0 -1
- package/dist/chunk-W5W6KHN2.js.map +0 -1
- package/dist/chunk-WHJKIZS7.js.map +0 -1
- package/dist/chunk-WYZ5MYUA.js.map +0 -1
- package/dist/chunk-ZJADGNYF.js.map +0 -1
- package/dist/chunk-ZNACADFG.js.map +0 -1
- package/dist/collection-facade-QN5ULWYC.js +0 -45
- package/dist/delegation-SSEPLXXO.js.map +0 -1
- package/dist/derive-6V3PIZF7.js +0 -22
- package/dist/executor-CYJQLKKI.js +0 -9
- package/dist/executor-FHHLXO4Y.js +0 -28
- package/dist/executor-S4QIKEHW.js +0 -9
- package/dist/export-accessible-PE5AYKZR.js +0 -23
- package/dist/extract-partition-X2L26O6A.js +0 -38
- package/dist/fanout-sidecar-DTBIDOWF.js.map +0 -1
- package/dist/find-RBBYKXI7.js +0 -11
- package/dist/issue-RNU55YOF.js +0 -19
- package/dist/liberate-PX4CAT5V.js +0 -24
- package/dist/noydb-YPSEGK32.js +0 -83
- package/dist/register-TMD6YRCX.js +0 -32
- package/dist/registry-CZVINVQH.js +0 -9
- package/dist/registry-FVLDWQKT.js +0 -18
- package/dist/registry-IKUR2MXD.js +0 -9
- package/dist/registry-JET4HBLY.js +0 -19
- package/dist/request-withdrawal-RH55LNZL.js +0 -31
- package/dist/revoke-R5TBYVA6.js +0 -24
- package/dist/seed-UK4QRIUN.js.map +0 -1
- package/dist/signer-AGALOXOO.js +0 -25
- package/dist/storage-N7LB275C.js +0 -23
- package/dist/store-coordination-provider-PB6QZ57W.js.map +0 -1
- package/dist/walk-OCUHCYJ6.js +0 -21
- package/dist/with-pod/bundle-handle.d.ts +0 -9
- package/dist/withdraw-accessible-QQNWM5BO.js +0 -28
- /package/dist/{api-WVY3H3YH.js.map → api-Z5VHH24A.js.map} +0 -0
- /package/dist/{chunk-FDX7OWWI.js.map → chunk-2E2MKBMI.js.map} +0 -0
- /package/dist/{chunk-7F4DBNSP.js.map → chunk-5J5TTSGW.js.map} +0 -0
- /package/dist/{chunk-BTVYJWSN.js.map → chunk-5JT4Y5UE.js.map} +0 -0
- /package/dist/{chunk-7NXHMW6Y.js.map → chunk-7RCZ436O.js.map} +0 -0
- /package/dist/{chunk-DG27IUVI.js.map → chunk-A3NTKHDB.js.map} +0 -0
- /package/dist/{chunk-CCZJJ4I2.js.map → chunk-A4K5GLE6.js.map} +0 -0
- /package/dist/{chunk-CEJWMBXO.js.map → chunk-APV42WPR.js.map} +0 -0
- /package/dist/{chunk-4HDYQL3J.js.map → chunk-AQF7JSQR.js.map} +0 -0
- /package/dist/{chunk-KUDZVJKQ.js.map → chunk-BP4I7IBK.js.map} +0 -0
- /package/dist/{chunk-4UVDI4XE.js.map → chunk-BTNKPDZM.js.map} +0 -0
- /package/dist/{chunk-HVQGCKY4.js.map → chunk-C7WJNVJG.js.map} +0 -0
- /package/dist/{chunk-KCQX65FU.js.map → chunk-CVYXIN5B.js.map} +0 -0
- /package/dist/{chunk-AR2JDFAE.js.map → chunk-DJ23QZIN.js.map} +0 -0
- /package/dist/{chunk-PVU7LW5L.js.map → chunk-EJIVFOOQ.js.map} +0 -0
- /package/dist/{chunk-VMCCGUQB.js.map → chunk-GDGTIWB4.js.map} +0 -0
- /package/dist/{chunk-FUHKW252.js.map → chunk-GILI76SU.js.map} +0 -0
- /package/dist/{chunk-35EBKWQU.js.map → chunk-GT72D4FO.js.map} +0 -0
- /package/dist/{chunk-JRCYZEHU.js.map → chunk-HGJC7I5F.js.map} +0 -0
- /package/dist/{chunk-YAWK6AWF.js.map → chunk-JIF3IBRK.js.map} +0 -0
- /package/dist/{chunk-HNHCQ556.js.map → chunk-KBOPY6W2.js.map} +0 -0
- /package/dist/{chunk-W3TVWF6N.js.map → chunk-KM6YR5XF.js.map} +0 -0
- /package/dist/{chunk-6HFM7EIT.js.map → chunk-MNMYHZVU.js.map} +0 -0
- /package/dist/{chunk-QD724WDJ.js.map → chunk-N2HKBESK.js.map} +0 -0
- /package/dist/{chunk-Z45YRGFO.js.map → chunk-N7YAQKAO.js.map} +0 -0
- /package/dist/{chunk-DMQCLZ4Z.js.map → chunk-NH2MST6J.js.map} +0 -0
- /package/dist/{chunk-HXGUIPQB.js.map → chunk-OQLYMBJI.js.map} +0 -0
- /package/dist/{chunk-MSWYQLMQ.js.map → chunk-PG6PFMDC.js.map} +0 -0
- /package/dist/{chunk-WKPJXWKR.js.map → chunk-QPIUFRUC.js.map} +0 -0
- /package/dist/{chunk-JIUVJ4M7.js.map → chunk-REL4OLWW.js.map} +0 -0
- /package/dist/{chunk-VW6ZZGCG.js.map → chunk-RNSC2ARR.js.map} +0 -0
- /package/dist/{chunk-WLYIROCJ.js.map → chunk-RORE2GX2.js.map} +0 -0
- /package/dist/{chunk-7TSYBD3E.js.map → chunk-RSFG7XHM.js.map} +0 -0
- /package/dist/{chunk-FAXZQ5UF.js.map → chunk-S55DBWRC.js.map} +0 -0
- /package/dist/{chunk-747LRSOO.js.map → chunk-SFD2LL7G.js.map} +0 -0
- /package/dist/{chunk-P7OG2ETF.js.map → chunk-SG3OQCRG.js.map} +0 -0
- /package/dist/{chunk-WQDTCJ6W.js.map → chunk-VEX2BQVX.js.map} +0 -0
- /package/dist/{chunk-7VHY5E3X.js.map → chunk-VH2W6BOG.js.map} +0 -0
- /package/dist/{chunk-OF3L2SD6.js.map → chunk-W6NFONOV.js.map} +0 -0
- /package/dist/{chunk-NJDQ4YSV.js.map → chunk-WBNXZU42.js.map} +0 -0
- /package/dist/{chunk-FNSMZQS4.js.map → chunk-WKD5ESK4.js.map} +0 -0
- /package/dist/{chunk-NKH7GSIH.js.map → chunk-XGQGWZ6D.js.map} +0 -0
- /package/dist/{chunk-VJFMXYKP.js.map → chunk-ZWKF3CD3.js.map} +0 -0
- /package/dist/{classified-marker-FTOX7Q5L.js.map → classified-marker-PMDG3O36.js.map} +0 -0
- /package/dist/{collection-facade-QN5ULWYC.js.map → collection-facade-ZJK5EB33.js.map} +0 -0
- /package/dist/{computed-6G5M3UPH.js.map → computed-UHCBRILW.js.map} +0 -0
- /package/dist/{dead-filter-ENRIOQIE.js.map → dead-filter-777VWDER.js.map} +0 -0
- /package/dist/{derive-6V3PIZF7.js.map → derive-3WAS2G5T.js.map} +0 -0
- /package/dist/{dispatch-BDVGYC6X.js.map → dispatch-3EN6YCCS.js.map} +0 -0
- /package/dist/{dispatch-RE74SH6L.js.map → dispatch-ASL257KG.js.map} +0 -0
- /package/dist/{enclave-52VUXNRL.js.map → enclave-ZJS5R5RH.js.map} +0 -0
- /package/dist/{executor-CYJQLKKI.js.map → executor-GPM6DNWV.js.map} +0 -0
- /package/dist/{executor-FHHLXO4Y.js.map → executor-LJSMZ4IB.js.map} +0 -0
- /package/dist/{executor-S4QIKEHW.js.map → executor-SHUVRZUJ.js.map} +0 -0
- /package/dist/{export-accessible-PE5AYKZR.js.map → export-accessible-GNY6DC6U.js.map} +0 -0
- /package/dist/{extract-partition-X2L26O6A.js.map → extract-partition-BG3AF4NZ.js.map} +0 -0
- /package/dist/{find-RBBYKXI7.js.map → find-KX6OKHDP.js.map} +0 -0
- /package/dist/{issue-RNU55YOF.js.map → issue-PAUM7NCX.js.map} +0 -0
- /package/dist/{ledger-4WJL66BW.js.map → ledger-62CEPRPX.js.map} +0 -0
- /package/dist/{liberate-PX4CAT5V.js.map → liberate-I6AOLWXW.js.map} +0 -0
- /package/dist/{link-set-N4ZPV6E6.js.map → link-set-ZRYNUHN3.js.map} +0 -0
- /package/dist/{managed-secret-OTHS64IF.js.map → managed-secret-T2WB4O47.js.map} +0 -0
- /package/dist/{noydb-YPSEGK32.js.map → noydb-SS6EN7TK.js.map} +0 -0
- /package/dist/{post-register-ZAG2CAIY.js.map → post-register-J4DEVNXK.js.map} +0 -0
- /package/dist/{register-TMD6YRCX.js.map → register-UPD4GKBC.js.map} +0 -0
- /package/dist/{registry-CZVINVQH.js.map → registry-7KX2HWFS.js.map} +0 -0
- /package/dist/{registry-FVLDWQKT.js.map → registry-PKYYEHEW.js.map} +0 -0
- /package/dist/{registry-IKUR2MXD.js.map → registry-XHCYMD34.js.map} +0 -0
- /package/dist/{registry-JET4HBLY.js.map → registry-XIRTZHPC.js.map} +0 -0
- /package/dist/{request-withdrawal-RH55LNZL.js.map → request-withdrawal-XZSESWZV.js.map} +0 -0
- /package/dist/{reveal-CMOJY4VO.js.map → reveal-525XWQU2.js.map} +0 -0
- /package/dist/{revoke-R5TBYVA6.js.map → revoke-QI7YHQ2B.js.map} +0 -0
- /package/dist/{signer-AGALOXOO.js.map → signer-BZWDPGGN.js.map} +0 -0
- /package/dist/{stale-ZWXSOWJI.js.map → stale-PQYPVCER.js.map} +0 -0
- /package/dist/{storage-N7LB275C.js.map → storage-MJHKNQRO.js.map} +0 -0
- /package/dist/{ulid-PTAIMDG4.js.map → ulid-VQW6ERQN.js.map} +0 -0
- /package/dist/{verify-RO5RTZOJ.js.map → verify-J6DEOXP3.js.map} +0 -0
- /package/dist/{walk-OCUHCYJ6.js.map → walk-BX4NSB5L.js.map} +0 -0
- /package/dist/{withdraw-accessible-QQNWM5BO.js.map → withdraw-accessible-K4CPMH4C.js.map} +0 -0
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
generateULID,
|
|
3
3
|
isULID
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-4AOERLTV.js";
|
|
5
5
|
import "./chunk-PZ5AY32C.js";
|
|
6
6
|
export {
|
|
7
7
|
generateULID,
|
|
8
8
|
isULID
|
|
9
9
|
};
|
|
10
|
-
//# sourceMappingURL=ulid-
|
|
10
|
+
//# sourceMappingURL=ulid-VQW6ERQN.js.map
|
package/dist/util/index.js
CHANGED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DEFAULT_HEAD_BUCKETS,
|
|
3
|
+
NO_VAULT_HEAD,
|
|
4
|
+
VAULT_HEAD_COLLECTION
|
|
5
|
+
} from "../chunk-HK67PX4J.js";
|
|
6
|
+
import {
|
|
7
|
+
buildRecordAad,
|
|
8
|
+
openEnvelopeJson
|
|
9
|
+
} from "../chunk-D5UDZANO.js";
|
|
10
|
+
import {
|
|
11
|
+
buildRecordEnvelope
|
|
12
|
+
} from "../chunk-ZVAFJQZB.js";
|
|
13
|
+
import "../chunk-OQLYMBJI.js";
|
|
14
|
+
import "../chunk-DJ23QZIN.js";
|
|
15
|
+
import "../chunk-SFD2LL7G.js";
|
|
16
|
+
import "../chunk-LP7BEXCT.js";
|
|
17
|
+
import {
|
|
18
|
+
encrypt
|
|
19
|
+
} from "../chunk-VJ4B3ZXY.js";
|
|
20
|
+
import "../chunk-3Y4OFWQJ.js";
|
|
21
|
+
import "../chunk-P7L3OQLL.js";
|
|
22
|
+
import "../chunk-PZ5AY32C.js";
|
|
23
|
+
|
|
24
|
+
// src/with-commit/vault-head/head.ts
|
|
25
|
+
function bucketIndex(collection, id, buckets) {
|
|
26
|
+
let h = 2166136261;
|
|
27
|
+
const s = `${collection}/${id}`;
|
|
28
|
+
for (let i = 0; i < s.length; i++) {
|
|
29
|
+
h ^= s.charCodeAt(i);
|
|
30
|
+
h = Math.imul(h, 16777619) >>> 0;
|
|
31
|
+
}
|
|
32
|
+
return h % buckets;
|
|
33
|
+
}
|
|
34
|
+
function bucketId(collection, id, buckets) {
|
|
35
|
+
return `${collection}::${String(bucketIndex(collection, id, buckets))}`;
|
|
36
|
+
}
|
|
37
|
+
async function readBucket(store, vault, dek, bucket) {
|
|
38
|
+
const env = await store.get(vault, VAULT_HEAD_COLLECTION, bucket);
|
|
39
|
+
if (!env) return { body: {}, version: 0 };
|
|
40
|
+
const json = await openEnvelopeJson({ collection: VAULT_HEAD_COLLECTION, id: bucket }, env, dek);
|
|
41
|
+
return { body: JSON.parse(json), version: env._v };
|
|
42
|
+
}
|
|
43
|
+
async function writeBucket(store, vault, dek, bucket, body, expectedVersion) {
|
|
44
|
+
const identity = { collection: VAULT_HEAD_COLLECTION, id: bucket, version: expectedVersion + 1 };
|
|
45
|
+
const json = JSON.stringify(body);
|
|
46
|
+
const { iv, data } = await encrypt(json, dek, buildRecordAad(identity));
|
|
47
|
+
const env = buildRecordEnvelope(identity, { iv, data });
|
|
48
|
+
await store.put(vault, VAULT_HEAD_COLLECTION, bucket, env, expectedVersion || void 0);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// src/with-commit/vault-head/active.ts
|
|
52
|
+
function withVaultHead(opts = {}) {
|
|
53
|
+
const buckets = opts.buckets ?? DEFAULT_HEAD_BUCKETS;
|
|
54
|
+
const dekFor = (getDEK) => getDEK(VAULT_HEAD_COLLECTION);
|
|
55
|
+
return {
|
|
56
|
+
enabled: true,
|
|
57
|
+
bucketFor: (collection, id) => bucketId(collection, id, buckets),
|
|
58
|
+
async note(store, vault, getDEK, entry) {
|
|
59
|
+
const dek = await dekFor(getDEK);
|
|
60
|
+
const bucket = bucketId(entry.collection, entry.id, buckets);
|
|
61
|
+
const { body, version } = await readBucket(store, vault, dek, bucket);
|
|
62
|
+
const key = `${entry.collection}/${entry.id}`;
|
|
63
|
+
if ((body[key] ?? -1) >= entry.version) return;
|
|
64
|
+
body[key] = entry.version;
|
|
65
|
+
await writeBucket(store, vault, dek, bucket, body, version);
|
|
66
|
+
},
|
|
67
|
+
async expected(store, vault, getDEK, collection, id) {
|
|
68
|
+
const dek = await dekFor(getDEK);
|
|
69
|
+
const { body } = await readBucket(store, vault, dek, bucketId(collection, id, buckets));
|
|
70
|
+
return body[`${collection}/${id}`] ?? null;
|
|
71
|
+
},
|
|
72
|
+
async knownIn(store, vault, getDEK, collection) {
|
|
73
|
+
const dek = await dekFor(getDEK);
|
|
74
|
+
const out = /* @__PURE__ */ new Map();
|
|
75
|
+
const prefix = `${collection}/`;
|
|
76
|
+
for (const bucket of await store.list(vault, VAULT_HEAD_COLLECTION)) {
|
|
77
|
+
if (!bucket.startsWith(`${collection}::`)) continue;
|
|
78
|
+
const { body } = await readBucket(store, vault, dek, bucket);
|
|
79
|
+
for (const [k, v] of Object.entries(body)) {
|
|
80
|
+
if (k.startsWith(prefix)) out.set(k.slice(prefix.length), v);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return out;
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// src/with-commit/vault-head/verify.ts
|
|
89
|
+
async function verifyVaultHead(head, store, vault, getDEK, collection) {
|
|
90
|
+
const known = await head.knownIn(store, vault, getDEK, collection);
|
|
91
|
+
const discrepancies = [];
|
|
92
|
+
const because = [];
|
|
93
|
+
if (known.size === 0) because.push("no-expectations");
|
|
94
|
+
if (store.capabilities?.casAtomic !== true) because.push("store-cannot-cas");
|
|
95
|
+
for (const [id, expected] of known) {
|
|
96
|
+
const env = await store.get(vault, collection, id);
|
|
97
|
+
if (env === null) {
|
|
98
|
+
discrepancies.push({ collection, id, expected, actual: null, kind: "withheld" });
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
if (env._v < expected) {
|
|
102
|
+
discrepancies.push({ collection, id, expected, actual: env._v, kind: "rolled-back" });
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
const verdict = discrepancies.length > 0 ? "tampered" : because.length > 0 ? "unverifiable" : "verified";
|
|
106
|
+
return { verdict, checked: known.size, discrepancies, because };
|
|
107
|
+
}
|
|
108
|
+
export {
|
|
109
|
+
DEFAULT_HEAD_BUCKETS,
|
|
110
|
+
NO_VAULT_HEAD,
|
|
111
|
+
VAULT_HEAD_COLLECTION,
|
|
112
|
+
verifyVaultHead,
|
|
113
|
+
withVaultHead
|
|
114
|
+
};
|
|
115
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/with-commit/vault-head/head.ts","../../src/with-commit/vault-head/active.ts","../../src/with-commit/vault-head/verify.ts"],"sourcesContent":["/**\n * The vault head's storage layer (#1044).\n *\n * A bucket is an ordinary encrypted record at `_head/<collection>::<n>`, so it\n * inherits #1041's identity binding for free: the store cannot relocate a\n * bucket, re-author it, or serve one bucket's bytes as another's. What it can\n * still do is serve an OLD bucket, which is why {@link readBucket} enforces\n * monotonicity against the caller's own record of what it last wrote.\n *\n * @packageDocumentation\n */\nimport { encrypt, buildRecordAad, openEnvelopeJson, buildRecordEnvelope, type EnclaveKey } from '../../kernel/enclave/index.js'\nimport type { NoydbStore } from '../../kernel/types.js'\nimport { VAULT_HEAD_COLLECTION } from './strategy.js'\n\n/** `{ recordId → version }` for one bucket. */\nexport type BucketBody = Record<string, number>\n\n/**\n * FNV-1a over `collection/id`. A hash, not a cipher: the bucket a record lands\n * in is not secret — the store already sees which bucket was written, and it\n * already saw the record's own address. Choosing something stronger would buy\n * nothing and cost every write.\n */\nexport function bucketIndex(collection: string, id: string, buckets: number): number {\n let h = 0x811c9dc5\n const s = `${collection}/${id}`\n for (let i = 0; i < s.length; i++) {\n h ^= s.charCodeAt(i)\n h = Math.imul(h, 0x01000193) >>> 0\n }\n return h % buckets\n}\n\nexport function bucketId(collection: string, id: string, buckets: number): string {\n return `${collection}::${String(bucketIndex(collection, id, buckets))}`\n}\n\nexport async function readBucket(\n store: NoydbStore,\n vault: string,\n dek: EnclaveKey,\n bucket: string,\n): Promise<{ body: BucketBody; version: number }> {\n const env = await store.get(vault, VAULT_HEAD_COLLECTION, bucket)\n if (!env) return { body: {}, version: 0 }\n const json = await openEnvelopeJson({ collection: VAULT_HEAD_COLLECTION, id: bucket }, env, dek)\n return { body: JSON.parse(json) as BucketBody, version: env._v }\n}\n\nexport async function writeBucket(\n store: NoydbStore,\n vault: string,\n dek: EnclaveKey,\n bucket: string,\n body: BucketBody,\n expectedVersion: number,\n): Promise<void> {\n const identity = { collection: VAULT_HEAD_COLLECTION, id: bucket, version: expectedVersion + 1 }\n const json = JSON.stringify(body)\n const { iv, data } = await encrypt(json, dek, buildRecordAad(identity))\n const env = buildRecordEnvelope(identity, { iv, data })\n // CAS: two writers racing on one bucket must not silently lose an entry.\n // A lost head entry is a record the sweep stops expecting — a false clean.\n await store.put(vault, VAULT_HEAD_COLLECTION, bucket, env, expectedVersion || undefined)\n}\n","/**\n * The real {@link VaultHeadStrategy} (#1044).\n *\n * @packageDocumentation\n */\nimport type { NoydbStore } from '../../kernel/types.js'\nimport type { EnclaveKey } from '../../kernel/enclave/index.js'\nimport {\n DEFAULT_HEAD_BUCKETS,\n VAULT_HEAD_COLLECTION,\n type HeadEntry,\n type VaultHeadStrategy,\n type WithVaultHeadOptions,\n} from './strategy.js'\nimport { bucketId, readBucket, writeBucket } from './head.js'\n\nexport function withVaultHead(opts: WithVaultHeadOptions = {}): VaultHeadStrategy {\n const buckets = opts.buckets ?? DEFAULT_HEAD_BUCKETS\n\n const dekFor = (getDEK: (c: string) => Promise<EnclaveKey>) => getDEK(VAULT_HEAD_COLLECTION)\n\n return {\n enabled: true,\n bucketFor: (collection, id) => bucketId(collection, id, buckets),\n\n async note(store: NoydbStore, vault, getDEK, entry: HeadEntry) {\n const dek = await dekFor(getDEK)\n const bucket = bucketId(entry.collection, entry.id, buckets)\n const { body, version } = await readBucket(store, vault, dek, bucket)\n const key = `${entry.collection}/${entry.id}`\n // Monotonic: a head entry never moves BACKWARD. A write that would lower\n // it is either a stale retry or a rollback being laundered through the\n // client's own head, and neither should be recorded.\n if ((body[key] ?? -1) >= entry.version) return\n body[key] = entry.version\n await writeBucket(store, vault, dek, bucket, body, version)\n },\n\n async expected(store, vault, getDEK, collection, id) {\n const dek = await dekFor(getDEK)\n const { body } = await readBucket(store, vault, dek, bucketId(collection, id, buckets))\n return body[`${collection}/${id}`] ?? null\n },\n\n async knownIn(store, vault, getDEK, collection) {\n const dek = await dekFor(getDEK)\n const out = new Map<string, number>()\n const prefix = `${collection}/`\n // Sweep every bucket: a record's bucket is a function of its id, so the\n // set for one collection is spread across all of them.\n for (const bucket of await store.list(vault, VAULT_HEAD_COLLECTION)) {\n if (!bucket.startsWith(`${collection}::`)) continue\n const { body } = await readBucket(store, vault, dek, bucket)\n for (const [k, v] of Object.entries(body)) {\n if (k.startsWith(prefix)) out.set(k.slice(prefix.length), v)\n }\n }\n return out\n },\n }\n}\n","/**\n * The sweep — comparing what the head expects against what the store serves (#1044).\n *\n * This is the only place absence becomes visible. #1041 and #1042 can reject a\n * record that lies about itself; neither can notice one that never arrived, or\n * one served at an older version than the client wrote. Both are indistinguishable\n * from the truth without an independent record of what should be there.\n *\n * @packageDocumentation\n */\nimport type { NoydbStore } from '../../kernel/types.js'\nimport type { EnclaveKey } from '../../kernel/enclave/index.js'\nimport type { VaultHeadStrategy } from './strategy.js'\n\n/** One record the store is not serving faithfully. */\nexport interface HeadDiscrepancy {\n readonly collection: string\n readonly id: string\n /** What the client last committed. */\n readonly expected: number\n /**\n * What the store serves now — or `null` when it serves nothing.\n *\n * The two are different attacks wearing the same result. `null` is\n * **suppression**: the record is gone. A lower number is **rollback**: an\n * authentic older version served in place of the current one, which is the\n * case no amount of per-envelope authentication can see.\n */\n readonly actual: number | null\n readonly kind: 'withheld' | 'rolled-back'\n}\n\n/**\n * Why a sweep could not reach a conclusion.\n *\n * - `'no-expectations'` — the head holds nothing for this collection. A fresh\n * vault, a head switched on after the fact, or a **restore from a snapshot**:\n * `_head` is `_`-prefixed, so `loadAll` excludes it and a restored vault has\n * no head to compare against.\n * - `'store-cannot-cas'` — the store does not advertise `capabilities.casAtomic`,\n * so two writers racing on one bucket can silently lose an entry. A lost entry\n * is a record the sweep stops expecting, which is a false clean.\n */\nexport type HeadUnverifiableReason = 'no-expectations' | 'store-cannot-cas'\n\n/**\n * ## Three-way, deliberately (#1101)\n *\n * - `'verified'` — the head held expectations, every one was met, and the store\n * can serialize head writes.\n * - `'unverifiable'` — the sweep could not conclude. See `because`.\n * - `'tampered'` — at least one discrepancy. Positive evidence, so it wins over\n * any `unverifiable` reason present at the same time.\n *\n * **The middle value is the point, and collapsing it is wrong in a different\n * direction each way:** folded into \"clean\" it hides withholding, which is the\n * one thing this service exists to catch; folded into \"tampered\" it cries wolf\n * on a vault that is merely unexamined.\n *\n * That is not hypothetical. #1044's own first bug was a head that recorded\n * nothing and swept **perfectly clean** — the degraded state rendered\n * identically to a healthy one, which is why its test asserts `checked` before\n * anything else. A two-way verdict makes that state a supported outcome.\n */\nexport type HeadVerdict = 'verified' | 'unverifiable' | 'tampered'\n\nexport interface HeadVerifyResult {\n readonly verdict: HeadVerdict\n readonly checked: number\n readonly discrepancies: readonly HeadDiscrepancy[]\n /**\n * Non-empty only when `verdict === 'unverifiable'`.\n *\n * There is deliberately no `clean: boolean`. It could not distinguish \"no\n * expectations\" from \"all expectations met\" — both rendered `true` — and that\n * indistinguishability *was* the defect. Replacing it rather than keeping it\n * alongside forces every caller to face the three-way.\n */\n readonly because: readonly HeadUnverifiableReason[]\n}\n\n/**\n * Sweep one collection.\n *\n * **A record the store serves that the head does NOT know is not reported.**\n * That is not an oversight: the head can be enabled on an existing vault, and\n * every pre-existing record would otherwise read as an anomaly. The head's\n * claim is one-directional — *what I wrote must still be there* — and an\n * unknown record simply falls outside it.\n *\n * **A HIGHER version than expected is also not reported**, for the same reason:\n * another device legitimately advanced it. The head detects going backwards, not\n * moving forwards.\n */\nexport async function verifyVaultHead(\n head: VaultHeadStrategy,\n store: NoydbStore,\n vault: string,\n getDEK: (collection: string) => Promise<EnclaveKey>,\n collection: string,\n): Promise<HeadVerifyResult> {\n const known = await head.knownIn(store, vault, getDEK, collection)\n const discrepancies: HeadDiscrepancy[] = []\n\n const because: HeadUnverifiableReason[] = []\n if (known.size === 0) because.push('no-expectations')\n // Read the store's OWN declared capability rather than probing: a store that\n // cannot serialize head writes may have silently dropped an entry, and a\n // dropped entry is invisible by construction — there is nothing left to find.\n if (store.capabilities?.casAtomic !== true) because.push('store-cannot-cas')\n\n for (const [id, expected] of known) {\n const env = await store.get(vault, collection, id)\n if (env === null) {\n discrepancies.push({ collection, id, expected, actual: null, kind: 'withheld' })\n continue\n }\n if (env._v < expected) {\n discrepancies.push({ collection, id, expected, actual: env._v, kind: 'rolled-back' })\n }\n }\n\n // A discrepancy is positive evidence, so it outranks any reason the sweep was\n // also incomplete: a rolled-back record found by a head that may be missing\n // OTHER entries is still a rolled-back record.\n const verdict: HeadVerdict = discrepancies.length > 0\n ? 'tampered'\n : because.length > 0 ? 'unverifiable' : 'verified'\n\n return { verdict, checked: known.size, discrepancies, because }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAwBO,SAAS,YAAY,YAAoB,IAAY,SAAyB;AACnF,MAAI,IAAI;AACR,QAAM,IAAI,GAAG,UAAU,IAAI,EAAE;AAC7B,WAAS,IAAI,GAAG,IAAI,EAAE,QAAQ,KAAK;AACjC,SAAK,EAAE,WAAW,CAAC;AACnB,QAAI,KAAK,KAAK,GAAG,QAAU,MAAM;AAAA,EACnC;AACA,SAAO,IAAI;AACb;AAEO,SAAS,SAAS,YAAoB,IAAY,SAAyB;AAChF,SAAO,GAAG,UAAU,KAAK,OAAO,YAAY,YAAY,IAAI,OAAO,CAAC,CAAC;AACvE;AAEA,eAAsB,WACpB,OACA,OACA,KACA,QACgD;AAChD,QAAM,MAAM,MAAM,MAAM,IAAI,OAAO,uBAAuB,MAAM;AAChE,MAAI,CAAC,IAAK,QAAO,EAAE,MAAM,CAAC,GAAG,SAAS,EAAE;AACxC,QAAM,OAAO,MAAM,iBAAiB,EAAE,YAAY,uBAAuB,IAAI,OAAO,GAAG,KAAK,GAAG;AAC/F,SAAO,EAAE,MAAM,KAAK,MAAM,IAAI,GAAiB,SAAS,IAAI,GAAG;AACjE;AAEA,eAAsB,YACpB,OACA,OACA,KACA,QACA,MACA,iBACe;AACf,QAAM,WAAW,EAAE,YAAY,uBAAuB,IAAI,QAAQ,SAAS,kBAAkB,EAAE;AAC/F,QAAM,OAAO,KAAK,UAAU,IAAI;AAChC,QAAM,EAAE,IAAI,KAAK,IAAI,MAAM,QAAQ,MAAM,KAAK,eAAe,QAAQ,CAAC;AACtE,QAAM,MAAM,oBAAoB,UAAU,EAAE,IAAI,KAAK,CAAC;AAGtD,QAAM,MAAM,IAAI,OAAO,uBAAuB,QAAQ,KAAK,mBAAmB,MAAS;AACzF;;;ACjDO,SAAS,cAAc,OAA6B,CAAC,GAAsB;AAChF,QAAM,UAAU,KAAK,WAAW;AAEhC,QAAM,SAAS,CAAC,WAA+C,OAAO,qBAAqB;AAE3F,SAAO;AAAA,IACL,SAAS;AAAA,IACT,WAAW,CAAC,YAAY,OAAO,SAAS,YAAY,IAAI,OAAO;AAAA,IAE/D,MAAM,KAAK,OAAmB,OAAO,QAAQ,OAAkB;AAC7D,YAAM,MAAM,MAAM,OAAO,MAAM;AAC/B,YAAM,SAAS,SAAS,MAAM,YAAY,MAAM,IAAI,OAAO;AAC3D,YAAM,EAAE,MAAM,QAAQ,IAAI,MAAM,WAAW,OAAO,OAAO,KAAK,MAAM;AACpE,YAAM,MAAM,GAAG,MAAM,UAAU,IAAI,MAAM,EAAE;AAI3C,WAAK,KAAK,GAAG,KAAK,OAAO,MAAM,QAAS;AACxC,WAAK,GAAG,IAAI,MAAM;AAClB,YAAM,YAAY,OAAO,OAAO,KAAK,QAAQ,MAAM,OAAO;AAAA,IAC5D;AAAA,IAEA,MAAM,SAAS,OAAO,OAAO,QAAQ,YAAY,IAAI;AACnD,YAAM,MAAM,MAAM,OAAO,MAAM;AAC/B,YAAM,EAAE,KAAK,IAAI,MAAM,WAAW,OAAO,OAAO,KAAK,SAAS,YAAY,IAAI,OAAO,CAAC;AACtF,aAAO,KAAK,GAAG,UAAU,IAAI,EAAE,EAAE,KAAK;AAAA,IACxC;AAAA,IAEA,MAAM,QAAQ,OAAO,OAAO,QAAQ,YAAY;AAC9C,YAAM,MAAM,MAAM,OAAO,MAAM;AAC/B,YAAM,MAAM,oBAAI,IAAoB;AACpC,YAAM,SAAS,GAAG,UAAU;AAG5B,iBAAW,UAAU,MAAM,MAAM,KAAK,OAAO,qBAAqB,GAAG;AACnE,YAAI,CAAC,OAAO,WAAW,GAAG,UAAU,IAAI,EAAG;AAC3C,cAAM,EAAE,KAAK,IAAI,MAAM,WAAW,OAAO,OAAO,KAAK,MAAM;AAC3D,mBAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,IAAI,GAAG;AACzC,cAAI,EAAE,WAAW,MAAM,EAAG,KAAI,IAAI,EAAE,MAAM,OAAO,MAAM,GAAG,CAAC;AAAA,QAC7D;AAAA,MACF;AACA,aAAO;AAAA,IACT;AAAA,EACF;AACF;;;ACkCA,eAAsB,gBACpB,MACA,OACA,OACA,QACA,YAC2B;AAC3B,QAAM,QAAQ,MAAM,KAAK,QAAQ,OAAO,OAAO,QAAQ,UAAU;AACjE,QAAM,gBAAmC,CAAC;AAE1C,QAAM,UAAoC,CAAC;AAC3C,MAAI,MAAM,SAAS,EAAG,SAAQ,KAAK,iBAAiB;AAIpD,MAAI,MAAM,cAAc,cAAc,KAAM,SAAQ,KAAK,kBAAkB;AAE3E,aAAW,CAAC,IAAI,QAAQ,KAAK,OAAO;AAClC,UAAM,MAAM,MAAM,MAAM,IAAI,OAAO,YAAY,EAAE;AACjD,QAAI,QAAQ,MAAM;AAChB,oBAAc,KAAK,EAAE,YAAY,IAAI,UAAU,QAAQ,MAAM,MAAM,WAAW,CAAC;AAC/E;AAAA,IACF;AACA,QAAI,IAAI,KAAK,UAAU;AACrB,oBAAc,KAAK,EAAE,YAAY,IAAI,UAAU,QAAQ,IAAI,IAAI,MAAM,cAAc,CAAC;AAAA,IACtF;AAAA,EACF;AAKA,QAAM,UAAuB,cAAc,SAAS,IAChD,aACA,QAAQ,SAAS,IAAI,iBAAiB;AAE1C,SAAO,EAAE,SAAS,SAAS,MAAM,MAAM,eAAe,QAAQ;AAChE;","names":[]}
|
|
@@ -2,10 +2,10 @@ import {
|
|
|
2
2
|
blindedEqual,
|
|
3
3
|
evaluateKofN,
|
|
4
4
|
openVdigPayload
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-OQLYMBJI.js";
|
|
6
6
|
import {
|
|
7
7
|
dualReadSealedSlot
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-DJ23QZIN.js";
|
|
9
9
|
import {
|
|
10
10
|
VDIG_ITERATIONS,
|
|
11
11
|
normalizeForVerify,
|
|
@@ -14,11 +14,11 @@ import {
|
|
|
14
14
|
import {
|
|
15
15
|
base64ToBuffer,
|
|
16
16
|
generateSalt
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-VJ4B3ZXY.js";
|
|
18
18
|
import {
|
|
19
19
|
ClassifiedConfigError,
|
|
20
20
|
ClassifiedVerifyError
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-P7L3OQLL.js";
|
|
22
22
|
import "./chunk-PZ5AY32C.js";
|
|
23
23
|
|
|
24
24
|
// src/kernel/enclave/classify/verify.ts
|
|
@@ -137,4 +137,4 @@ export {
|
|
|
137
137
|
verifyDigestField,
|
|
138
138
|
verifyTextField
|
|
139
139
|
};
|
|
140
|
-
//# sourceMappingURL=verify-
|
|
140
|
+
//# sourceMappingURL=verify-J6DEOXP3.js.map
|
|
@@ -132,7 +132,10 @@ export declare class LookupHandle<Keys extends string = string> {
|
|
|
132
132
|
* `enclave-body-only` / Check 15 `via-enclave-isolation`) — the Vault binds the real
|
|
133
133
|
* `kernel/enclave` function at construction time, same pattern as `reservedEnvelopes` above.
|
|
134
134
|
*/
|
|
135
|
-
buildDeleteMarker: (
|
|
135
|
+
buildDeleteMarker: (identity: {
|
|
136
|
+
collection: string;
|
|
137
|
+
id: string;
|
|
138
|
+
}, version: number, actor: string) => EncryptedEnvelope,
|
|
136
139
|
/** #650 Task 4 (#647) — dirty-log participation hook (origin `local-write`), threaded from `BuildLookupHandleOptions`. */
|
|
137
140
|
onDirty?: ((collection: string, id: string, action: "put" | "delete", version: number) => Promise<void>) | undefined,
|
|
138
141
|
/** #650 Task 4 — thin `graphDispatch.collect`-equivalent; opens/collects/flushes a one-shot wave for this touch. */
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Exact decimal arithmetic for post-aggregate row math (#1007).
|
|
3
|
+
*
|
|
4
|
+
* Money leaves a reducer as a `MoneyString` — a decimal string, exact by
|
|
5
|
+
* construction. Doing `Number(a) - Number(b)` on two of those re-introduces
|
|
6
|
+
* binary floating point at the one step the money type exists to protect:
|
|
7
|
+
* `10.05 - 0.10` becomes `9.950000000000001`, which `quantizeMoneyFields`
|
|
8
|
+
* then correctly REFUSES rather than silently storing drift.
|
|
9
|
+
*
|
|
10
|
+
* So `derive` is handed these instead. Everything runs in scaled BigInt at the
|
|
11
|
+
* widest scale of its inputs and formats back to a decimal string, which means
|
|
12
|
+
* no operation here can introduce a representation error. Deliberately just
|
|
13
|
+
* the additive set — `add` / `sub` / `neg` / `min` / `max` / `cmp`. Anything
|
|
14
|
+
* needing multiplication or division needs a rounding policy, and a rounding
|
|
15
|
+
* policy is a decision the caller must make explicitly, not one this module
|
|
16
|
+
* should guess.
|
|
17
|
+
*
|
|
18
|
+
* @module
|
|
19
|
+
*/
|
|
20
|
+
/** A value these helpers accept: a decimal string, a number, or a bigint of whole units. */
|
|
21
|
+
export type ExactOperand = string | number | bigint;
|
|
22
|
+
/**
|
|
23
|
+
* Exact decimal helpers handed to an MV `derive` as its second argument.
|
|
24
|
+
*
|
|
25
|
+
* Every result is a decimal string, so results compose without ever passing
|
|
26
|
+
* through a float. Declare the derived field in the MV's `moneyFields` and the
|
|
27
|
+
* final value is quantised to that descriptor's scale on the way to storage.
|
|
28
|
+
*/
|
|
29
|
+
export interface ExactMath {
|
|
30
|
+
/** `a + b`, exact. */
|
|
31
|
+
add(a: ExactOperand, b: ExactOperand): string;
|
|
32
|
+
/** `a - b`, exact. */
|
|
33
|
+
sub(a: ExactOperand, b: ExactOperand): string;
|
|
34
|
+
/** `-a`, exact. */
|
|
35
|
+
neg(a: ExactOperand): string;
|
|
36
|
+
/** The larger of `a` and `b`. */
|
|
37
|
+
max(a: ExactOperand, b: ExactOperand): string;
|
|
38
|
+
/** The smaller of `a` and `b`. */
|
|
39
|
+
min(a: ExactOperand, b: ExactOperand): string;
|
|
40
|
+
/** `-1` when `a < b`, `0` when equal, `1` when `a > b`. */
|
|
41
|
+
cmp(a: ExactOperand, b: ExactOperand): -1 | 0 | 1;
|
|
42
|
+
}
|
|
43
|
+
/** The singleton passed to `derive` — stateless, so there is nothing to construct per row. */
|
|
44
|
+
export declare const exactMath: ExactMath;
|
|
@@ -13,3 +13,5 @@ export { mulRate, allocate } from './arith.js';
|
|
|
13
13
|
export type { MulRateOptions, AllocateOptions } from './arith.js';
|
|
14
14
|
export { asMoney, isMoneyString, moneyNumber } from './branded.js';
|
|
15
15
|
export type { MoneyString } from './branded.js';
|
|
16
|
+
export { exactMath } from './exact.js';
|
|
17
|
+
export type { ExactMath, ExactOperand } from './exact.js';
|
|
@@ -40,6 +40,26 @@ export declare function canonicalizeStoredMoney(record: unknown, moneyFields: Re
|
|
|
40
40
|
* `MoneyPrecisionError`/`TypeError`.
|
|
41
41
|
*/
|
|
42
42
|
export declare function canonicalizeIncomingMoney(record: unknown, moneyFields: Record<string, MoneyDescriptor> | undefined): unknown;
|
|
43
|
+
/**
|
|
44
|
+
* Canonicalize money values for a MATERIALIZED-VIEW row (#1018).
|
|
45
|
+
*
|
|
46
|
+
* A money field in an MV row is NOT in the scaled-integer storage form a
|
|
47
|
+
* collection uses — the money-aware reducers emit `formatScaledInt(...)`, an
|
|
48
|
+
* exact decimal string, and that is what lands in the output collection. So a
|
|
49
|
+
* derived money field has to be canonicalized into the same shape as the
|
|
50
|
+
* aggregated ones beside it.
|
|
51
|
+
*
|
|
52
|
+
* Quantizing it into storage form instead is what #1018 reported: `toPay` came
|
|
53
|
+
* back as `"1000000"` where `netTotal` in the SAME row read `"10000.00"` —
|
|
54
|
+
* 100× the true value, and a string that looks like a plausible amount rather
|
|
55
|
+
* than an obvious error.
|
|
56
|
+
*
|
|
57
|
+
* Precision handling is identical to {@link quantizeMoneyFields} — the same
|
|
58
|
+
* `parseToScaledInt` and the same `MoneyPrecisionError` — so a value that
|
|
59
|
+
* cannot be represented at the declared scale is still refused rather than
|
|
60
|
+
* silently rounded. Only the OUTPUT shape differs: decimal, not scaled.
|
|
61
|
+
*/
|
|
62
|
+
export declare function canonicalizeMoneyFieldsAsDecimal<T extends Record<string, unknown>>(record: T, moneyFields: Record<string, MoneyDescriptor>): T;
|
|
43
63
|
/**
|
|
44
64
|
* Convert money fields in `record` from user input to their canonical
|
|
45
65
|
* stored form. Returns a shallow clone (deep along declared nested
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import {
|
|
2
|
+
dumpVaultSchema
|
|
3
|
+
} from "./chunk-SG3OQCRG.js";
|
|
4
|
+
import "./chunk-KHKKD62N.js";
|
|
5
|
+
import "./chunk-N7YAQKAO.js";
|
|
6
|
+
import "./chunk-Y2NBBT6K.js";
|
|
7
|
+
import "./chunk-YVTADFTC.js";
|
|
8
|
+
import "./chunk-D5UDZANO.js";
|
|
9
|
+
import "./chunk-ZVAFJQZB.js";
|
|
10
|
+
import "./chunk-OQLYMBJI.js";
|
|
11
|
+
import "./chunk-DJ23QZIN.js";
|
|
12
|
+
import "./chunk-SFD2LL7G.js";
|
|
13
|
+
import "./chunk-LP7BEXCT.js";
|
|
14
|
+
import "./chunk-VJ4B3ZXY.js";
|
|
15
|
+
import "./chunk-3Y4OFWQJ.js";
|
|
16
|
+
import "./chunk-P7L3OQLL.js";
|
|
17
|
+
import "./chunk-PZ5AY32C.js";
|
|
18
|
+
export {
|
|
19
|
+
dumpVaultSchema
|
|
20
|
+
};
|
|
21
|
+
//# sourceMappingURL=walk-BX4NSB5L.js.map
|
|
@@ -29,6 +29,20 @@ import type { GuardStrategy, GuardContext, GuardChange } from './types.js';
|
|
|
29
29
|
export interface ImmutableGuardConfig<T extends Record<string, unknown>> {
|
|
30
30
|
/** The collection to make WORM. */
|
|
31
31
|
collection: string;
|
|
32
|
+
/**
|
|
33
|
+
* Optional stable per-vault identifier, forwarded verbatim to the
|
|
34
|
+
* underlying {@link GuardSpec.name} — `immutableGuard` is a wrapper
|
|
35
|
+
* around `withGuard` and grants the same identity affordance (#1006).
|
|
36
|
+
*
|
|
37
|
+
* Omit and `vault.listBehaviors()` falls back to a POSITIONAL
|
|
38
|
+
* `${collection}#${occurrence}` key, which renumbers when another
|
|
39
|
+
* guard on the same collection is registered ahead of this one. Pass
|
|
40
|
+
* a name whenever something joins to the behavior manifest by key —
|
|
41
|
+
* a generated rulebook, a diff between two vault versions, an audit
|
|
42
|
+
* report — so the identifier tracks the rule rather than its
|
|
43
|
+
* registration order.
|
|
44
|
+
*/
|
|
45
|
+
readonly name?: string;
|
|
32
46
|
/**
|
|
33
47
|
* A record becomes immutable once this predicate holds. Evaluated on
|
|
34
48
|
* the *existing* (already-persisted) record, so the write that first
|
|
@@ -2,10 +2,37 @@
|
|
|
2
2
|
* Active periods strategy factory. Only reachable through the
|
|
3
3
|
* `@noy-db/hub/periods` subpath.
|
|
4
4
|
*/
|
|
5
|
+
import type { PeriodPartition } from './periods.js';
|
|
5
6
|
import type { PeriodsStrategy } from './strategy.js';
|
|
7
|
+
/** Options for {@link withPeriods}. */
|
|
8
|
+
export interface WithPeriodsOptions {
|
|
9
|
+
/**
|
|
10
|
+
* Maps a collection to the timeline each of its records belongs to (#1005) —
|
|
11
|
+
* the answer to "which close calendar governs THIS record".
|
|
12
|
+
*
|
|
13
|
+
* ```ts
|
|
14
|
+
* withPeriods({
|
|
15
|
+
* subjects: { receipts: (r) => [r.clientId, layerOf(r)] },
|
|
16
|
+
* })
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* Same shape as `withForget({ subjects })`, which answers the same question
|
|
20
|
+
* for erasure. A collection with no entry — and every collection when
|
|
21
|
+
* `subjects` is omitted entirely — stays on the vault-wide timeline, so an
|
|
22
|
+
* existing vault behaves exactly as it did before partitions existed.
|
|
23
|
+
*
|
|
24
|
+
* Return `undefined` from a mapper to put an individual record back on the
|
|
25
|
+
* vault-wide timeline (e.g. a record that predates the field the mapping
|
|
26
|
+
* reads).
|
|
27
|
+
*/
|
|
28
|
+
readonly subjects?: Readonly<Record<string, (record: Record<string, unknown>) => PeriodPartition | undefined>>;
|
|
29
|
+
}
|
|
6
30
|
/**
|
|
7
31
|
* Build the default periods strategy. Pass into
|
|
8
32
|
* `createNoydb({ periodsStrategy: withPeriods() })` to enable
|
|
9
33
|
* `vault.closePeriod()` / `vault.openPeriod()` / write-guards.
|
|
34
|
+
*
|
|
35
|
+
* Pass `subjects` to run more than one close calendar in a single vault — see
|
|
36
|
+
* {@link WithPeriodsOptions.subjects}.
|
|
10
37
|
*/
|
|
11
|
-
export declare function withPeriods(): PeriodsStrategy;
|
|
38
|
+
export declare function withPeriods(options?: WithPeriodsOptions): PeriodsStrategy;
|
|
@@ -13,8 +13,10 @@
|
|
|
13
13
|
* Vault can call them without TypeScript barrel gymnastics.
|
|
14
14
|
*/
|
|
15
15
|
export { withPeriods } from './active.js';
|
|
16
|
+
export type { WithPeriodsOptions } from './active.js';
|
|
16
17
|
export type { PeriodsStrategy } from './strategy.js';
|
|
17
|
-
export {
|
|
18
|
-
export
|
|
18
|
+
export type { PeriodScope, PeriodScopeWithReason, ReopenPeriodOptions } from './vault-facade.js';
|
|
19
|
+
export { PERIODS_COLLECTION, PERIOD_FREEZES_COLLECTION, PERIOD_ARCHIVES_COLLECTION, PERIOD_TARGET_PURGES_COLLECTION, PERIOD_REOPENS_COLLECTION, periodExclusiveUpperBound, resolvePeriodKey, samePartition, resolveReopenState, isEffectivelyReopened, loadPeriods, chainAnchor, assertTsWritable, validatePeriodName, appendPeriodLedgerEntry, purgeMarkersOn, } from './periods.js';
|
|
20
|
+
export type { PeriodPartition, PartitionResolver, PeriodReopenEvent, PeriodReopenRecord, PeriodRecord, PeriodFreezeRecord, PeriodArchiveRecord, PeriodTargetPurgeRecord, TargetPurgeCount, ClosePeriodOptions, OpenPeriodOptions, CarryForwardContext, ReadOnlyCollection, } from './periods.js';
|
|
19
21
|
/** The un-opted-in stub for this service — exported so callers can compare against it (#844). */
|
|
20
22
|
export { NO_PERIODS } from './strategy.js';
|
|
@@ -146,7 +146,7 @@
|
|
|
146
146
|
*/
|
|
147
147
|
import type { NoydbStore, EncryptedEnvelope } from '../../kernel/types.js';
|
|
148
148
|
import type { LedgerStore } from '../../with-commit/history/ledger/index.js';
|
|
149
|
-
export { PERIODS_COLLECTION, PERIOD_FREEZES_COLLECTION, PERIOD_ARCHIVES_COLLECTION, PERIOD_TARGET_PURGES_COLLECTION, periodExclusiveUpperBound, } from './window.js';
|
|
149
|
+
export { PERIODS_COLLECTION, PERIOD_FREEZES_COLLECTION, PERIOD_ARCHIVES_COLLECTION, PERIOD_TARGET_PURGES_COLLECTION, PERIOD_REOPENS_COLLECTION, periodExclusiveUpperBound, } from './window.js';
|
|
150
150
|
/**
|
|
151
151
|
* Companion record recording that a closed period was frozen (its delete
|
|
152
152
|
* markers physically purged). Stored in {@link PERIOD_FREEZES_COLLECTION},
|
|
@@ -177,6 +177,73 @@ export interface TargetPurgeCount {
|
|
|
177
177
|
readonly role: 'backup' | 'archive';
|
|
178
178
|
readonly purgedCount: number;
|
|
179
179
|
}
|
|
180
|
+
/**
|
|
181
|
+
* One entry in a period's append-only reopen/reclose log (#1022).
|
|
182
|
+
*
|
|
183
|
+
* Real accounting close is a three-state lifecycle — open / closed / reopened
|
|
184
|
+
* — not a one-way door. A month gets closed, a missing invoice arrives or a
|
|
185
|
+
* filing is rejected, the month is reopened, corrected, and reclosed. The audit
|
|
186
|
+
* value is not the ability to write again; it is the chain being able to say
|
|
187
|
+
* *closed at T1, reopened at T2 by U, reclosed at T3*.
|
|
188
|
+
*/
|
|
189
|
+
export interface PeriodReopenEvent {
|
|
190
|
+
readonly op: 'reopen' | 'reclose';
|
|
191
|
+
/** ISO timestamp the event was recorded. */
|
|
192
|
+
readonly at: string;
|
|
193
|
+
/** userId of the keyring that performed it. */
|
|
194
|
+
readonly by: string;
|
|
195
|
+
/**
|
|
196
|
+
* `reopen` only — ISO instant after which the period re-seals on its own,
|
|
197
|
+
* with nobody acting. Absent means the window stays open until an explicit
|
|
198
|
+
* `reclosePeriod`.
|
|
199
|
+
*/
|
|
200
|
+
readonly until?: string;
|
|
201
|
+
/** Free-text justification, carried verbatim into the audit trail. */
|
|
202
|
+
readonly reason?: string;
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Companion holding a period's reopen/reclose history (#1022). Stored in
|
|
206
|
+
* {@link PERIOD_REOPENS_COLLECTION}, keyed by the period's storage key — kept
|
|
207
|
+
* OFF the hash-chained `_periods/<name>` record for the same reason freeze and
|
|
208
|
+
* archive are: reopening must never rewrite the close, or the chain that proves
|
|
209
|
+
* the close happened is the very thing the reopen destroys.
|
|
210
|
+
*
|
|
211
|
+
* `events` is APPEND-ONLY. Where the other companions are single-shot and
|
|
212
|
+
* idempotent, this one accumulates, because the cycle repeats.
|
|
213
|
+
*/
|
|
214
|
+
export interface PeriodReopenRecord {
|
|
215
|
+
readonly period: string;
|
|
216
|
+
readonly partition?: PeriodPartition;
|
|
217
|
+
readonly events: readonly PeriodReopenEvent[];
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Collapse an append-only reopen log into the return-only fields merged onto a
|
|
221
|
+
* {@link PeriodRecord} on read.
|
|
222
|
+
*
|
|
223
|
+
* Expiry is deliberately NOT resolved here: `reopenedUntil` is carried through
|
|
224
|
+
* verbatim and compared against the clock at write-guard time, so a bounded
|
|
225
|
+
* window re-seals on its own without anything having to run.
|
|
226
|
+
*
|
|
227
|
+
* @internal
|
|
228
|
+
*/
|
|
229
|
+
export declare function resolveReopenState(events: readonly PeriodReopenEvent[]): {
|
|
230
|
+
reopenedAt?: string;
|
|
231
|
+
reopenedBy?: string;
|
|
232
|
+
reopenedUntil?: string;
|
|
233
|
+
reopenReason?: string;
|
|
234
|
+
reclosedAt?: string;
|
|
235
|
+
reopenCount: number;
|
|
236
|
+
};
|
|
237
|
+
/**
|
|
238
|
+
* Is this period writable right now on account of a reopen? (#1022)
|
|
239
|
+
*
|
|
240
|
+
* Three ways to be sealed again: never reopened, explicitly reclosed after the
|
|
241
|
+
* last reopen, or a bounded window that has elapsed. The clock is read by the
|
|
242
|
+
* caller and passed in, so the guard and any diagnostic agree on one instant.
|
|
243
|
+
*
|
|
244
|
+
* @internal
|
|
245
|
+
*/
|
|
246
|
+
export declare function isEffectivelyReopened(period: PeriodRecord, nowIso: string): boolean;
|
|
180
247
|
/**
|
|
181
248
|
* Companion record noting that a closed+frozen period's delete markers were
|
|
182
249
|
* swept off the vault's push-only sync targets (#615). Stored in
|
|
@@ -189,6 +256,46 @@ export interface PeriodTargetPurgeRecord {
|
|
|
189
256
|
readonly purgedBy: string;
|
|
190
257
|
readonly targets: readonly TargetPurgeCount[];
|
|
191
258
|
}
|
|
259
|
+
/**
|
|
260
|
+
* Scope tuple for a period timeline (#1005).
|
|
261
|
+
*
|
|
262
|
+
* Identical in shape and semantics to `SequenceOptions.partition`: a
|
|
263
|
+
* partitioned timeline is always disjoint from any unpartitioned one, and from
|
|
264
|
+
* every other tuple. `['acme', 'vat']` and `['acme', 'wht']` are two
|
|
265
|
+
* independent close calendars for the same subject — which is the whole point,
|
|
266
|
+
* since sub-ledgers for one legal entity and one month routinely close on
|
|
267
|
+
* different statutory deadlines.
|
|
268
|
+
*/
|
|
269
|
+
export type PeriodPartition = readonly (string | number)[];
|
|
270
|
+
/**
|
|
271
|
+
* Resolve the `_periods` storage key for a (name, partition) pair.
|
|
272
|
+
*
|
|
273
|
+
* Deliberately the same encoding as `resolveSequenceKey`: `name` verbatim when
|
|
274
|
+
* unpartitioned, else `${name}\x00${parts}` with each component
|
|
275
|
+
* `encodeURIComponent`d and `'/'`-joined. The null-byte separator cannot occur
|
|
276
|
+
* in a period name, so a partitioned key never collides with an unpartitioned
|
|
277
|
+
* one; URI-encoding keeps `['a/b']` distinct from `['a','b']`.
|
|
278
|
+
*
|
|
279
|
+
* @throws {ValidationError} on an empty component or a non-finite number.
|
|
280
|
+
* @internal
|
|
281
|
+
*/
|
|
282
|
+
export declare function resolvePeriodKey(name: string, partition?: PeriodPartition): string;
|
|
283
|
+
/**
|
|
284
|
+
* Do two partitions denote the same timeline? Absent and empty both mean "the
|
|
285
|
+
* unpartitioned timeline", so they compare equal.
|
|
286
|
+
*
|
|
287
|
+
* @internal
|
|
288
|
+
*/
|
|
289
|
+
export declare function samePartition(a?: PeriodPartition, b?: PeriodPartition): boolean;
|
|
290
|
+
/**
|
|
291
|
+
* Resolves a record to the timeline that governs it. Supplied by
|
|
292
|
+
* `withPeriods({ subjects })`; returns `undefined` for any collection with no
|
|
293
|
+
* mapping, which is what keeps an unconfigured vault on the single vault-wide
|
|
294
|
+
* timeline it has always had.
|
|
295
|
+
*
|
|
296
|
+
* @internal
|
|
297
|
+
*/
|
|
298
|
+
export type PartitionResolver = (collection: string, record: Record<string, unknown>) => PeriodPartition | undefined;
|
|
192
299
|
/**
|
|
193
300
|
* Stored record for one closed or opened accounting period. One entry
|
|
194
301
|
* per period, keyed by `name` in the reserved `_periods` collection.
|
|
@@ -199,8 +306,19 @@ export interface PeriodTargetPurgeRecord {
|
|
|
199
306
|
* into the next one, the same way the ledger's `prevHash` works.
|
|
200
307
|
*/
|
|
201
308
|
export interface PeriodRecord {
|
|
202
|
-
/**
|
|
309
|
+
/**
|
|
310
|
+
* Human-readable name (e.g., `'FY2026-Q1'`). Unique per PARTITION — two
|
|
311
|
+
* timelines may each carry a `'2026-06'`, which is the normal case when one
|
|
312
|
+
* vault serves several subjects (#1005). Unique per vault when unpartitioned.
|
|
313
|
+
*/
|
|
203
314
|
readonly name: string;
|
|
315
|
+
/**
|
|
316
|
+
* The timeline this period belongs to. Absent = the vault-wide timeline.
|
|
317
|
+
* Two periods with the same `name` and different `partition` are unrelated:
|
|
318
|
+
* separate hash chains, separate close state, and the write guard applies
|
|
319
|
+
* each only to records that resolve to its own tuple.
|
|
320
|
+
*/
|
|
321
|
+
readonly partition?: PeriodPartition;
|
|
204
322
|
/**
|
|
205
323
|
* Role discriminator. A period is `'closed'` from the moment its
|
|
206
324
|
* `closedAt` is recorded; `'opened'` marks a period whose opening
|
|
@@ -261,6 +379,19 @@ export interface PeriodRecord {
|
|
|
261
379
|
readonly targetsPurgedAt?: string;
|
|
262
380
|
readonly targetsPurgedBy?: string;
|
|
263
381
|
readonly targetsPurged?: readonly TargetPurgeCount[];
|
|
382
|
+
/** #1022 return-only — collapsed from the `_period_reopens/<key>` append-only
|
|
383
|
+
* log on read; NEVER written into the stored `_periods/<name>` record, so a
|
|
384
|
+
* reopen cannot disturb the inter-period hash chain. Absent = never reopened.
|
|
385
|
+
* `reclosedAt` present (and >= `reopenedAt`) means the window was closed
|
|
386
|
+
* again explicitly; `reopenedUntil` in the past means it lapsed on its own.
|
|
387
|
+
* Use {@link isEffectivelyReopened} rather than reading these directly. */
|
|
388
|
+
readonly reopenedAt?: string;
|
|
389
|
+
readonly reopenedBy?: string;
|
|
390
|
+
readonly reopenedUntil?: string;
|
|
391
|
+
readonly reopenReason?: string;
|
|
392
|
+
readonly reclosedAt?: string;
|
|
393
|
+
/** How many times this period has been reopened, ever. */
|
|
394
|
+
readonly reopenCount?: number;
|
|
264
395
|
}
|
|
265
396
|
/** Options for `vault.closePeriod()`. */
|
|
266
397
|
export interface ClosePeriodOptions {
|
|
@@ -283,11 +414,32 @@ export interface ClosePeriodOptions {
|
|
|
283
414
|
* an explicit `dateField`.
|
|
284
415
|
*/
|
|
285
416
|
readonly dateField?: string;
|
|
417
|
+
/**
|
|
418
|
+
* Close only this timeline (#1005). Omit for the vault-wide timeline.
|
|
419
|
+
*
|
|
420
|
+
* ```ts
|
|
421
|
+
* vault.closePeriod({
|
|
422
|
+
* name: '2026-06', endDate: '2026-06-30', dateField: 'issuedAt',
|
|
423
|
+
* partition: [clientId, 'vat'],
|
|
424
|
+
* })
|
|
425
|
+
* ```
|
|
426
|
+
*
|
|
427
|
+
* Which records the resulting seal applies to is decided by the
|
|
428
|
+
* `subjects` map passed to `withPeriods()` — without one, no record ever
|
|
429
|
+
* resolves to a partition and a partitioned close seals nothing.
|
|
430
|
+
*/
|
|
431
|
+
readonly partition?: PeriodPartition;
|
|
286
432
|
}
|
|
287
433
|
/** Options for `vault.openPeriod()`. */
|
|
288
434
|
export interface OpenPeriodOptions<TCollections = Record<string, Record<string, unknown>>> {
|
|
289
435
|
/** Human-readable name for the new period. Must be unique. */
|
|
290
436
|
readonly name: string;
|
|
437
|
+
/**
|
|
438
|
+
* The timeline to open in. Must match the partition of `fromPeriod` — a
|
|
439
|
+
* period cannot chain across timelines, since each carries its own hash
|
|
440
|
+
* chain (#1005).
|
|
441
|
+
*/
|
|
442
|
+
readonly partition?: PeriodPartition;
|
|
291
443
|
/** ISO lower bound of the new period (usually prior `endDate + 1 day`). */
|
|
292
444
|
readonly startDate: string;
|
|
293
445
|
/**
|
|
@@ -349,7 +501,7 @@ export interface ReadOnlyCollection<T> {
|
|
|
349
501
|
* @internal — called by Vault methods that need the closed-period
|
|
350
502
|
* cache. Not part of the public API surface.
|
|
351
503
|
*/
|
|
352
|
-
export declare function loadPeriods(adapter: NoydbStore, vault: string, decrypt: (envelope: EncryptedEnvelope) => Promise<PeriodRecord>): Promise<PeriodRecord[]>;
|
|
504
|
+
export declare function loadPeriods(adapter: NoydbStore, vault: string, decrypt: (id: string, envelope: EncryptedEnvelope) => Promise<PeriodRecord>): Promise<PeriodRecord[]>;
|
|
353
505
|
/**
|
|
354
506
|
* Given the current ordered period list, pick the last entry that
|
|
355
507
|
* belongs to the hash chain — used as the `priorPeriodHash` anchor
|
|
@@ -357,7 +509,7 @@ export declare function loadPeriods(adapter: NoydbStore, vault: string, decrypt:
|
|
|
357
509
|
*
|
|
358
510
|
* @internal
|
|
359
511
|
*/
|
|
360
|
-
export declare function chainAnchor(records: readonly PeriodRecord[]): Promise<{
|
|
512
|
+
export declare function chainAnchor(records: readonly PeriodRecord[], partition?: PeriodPartition): Promise<{
|
|
361
513
|
priorPeriodName?: string;
|
|
362
514
|
priorPeriodHash: string;
|
|
363
515
|
}>;
|
|
@@ -382,7 +534,10 @@ export declare function chainAnchor(records: readonly PeriodRecord[]): Promise<{
|
|
|
382
534
|
export declare function assertTsWritable(existing: {
|
|
383
535
|
ts: string | null;
|
|
384
536
|
record: Record<string, unknown> | null;
|
|
385
|
-
} | null, incomingRecord: Record<string, unknown> | null, closedPeriods: readonly PeriodRecord[]
|
|
537
|
+
} | null, incomingRecord: Record<string, unknown> | null, closedPeriods: readonly PeriodRecord[], scope?: {
|
|
538
|
+
collection: string;
|
|
539
|
+
resolve?: PartitionResolver;
|
|
540
|
+
}): void;
|
|
386
541
|
/**
|
|
387
542
|
* Sanity-check a proposed period name + endDate against existing
|
|
388
543
|
* records. Shared by closePeriod / openPeriod so the two pathways
|
|
@@ -390,7 +545,7 @@ export declare function assertTsWritable(existing: {
|
|
|
390
545
|
*
|
|
391
546
|
* @internal
|
|
392
547
|
*/
|
|
393
|
-
export declare function validatePeriodName(name: string, existing: readonly PeriodRecord[]): void;
|
|
548
|
+
export declare function validatePeriodName(name: string, existing: readonly PeriodRecord[], partition?: PeriodPartition): void;
|
|
394
549
|
/**
|
|
395
550
|
* Wire a reserved-collection ledger append for a period record. The
|
|
396
551
|
* period itself is stored via the adapter as an encrypted envelope;
|