@noy-db/hub 0.10.0-pre.1 → 0.10.0-pre.2
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/CHANGELOG.md +81 -0
- package/dist/api-QSEKT4KS.js +15 -0
- package/dist/as/index.js +19 -12
- package/dist/as/index.js.map +1 -1
- package/dist/at/index.js +6 -9
- package/dist/attestation/index.js +16 -19
- package/dist/attestation/index.js.map +1 -1
- package/dist/{backup-6EKBNC67.js → backup-BHKVK5SD.js} +9 -12
- package/dist/{backup-6EKBNC67.js.map → backup-BHKVK5SD.js.map} +1 -1
- package/dist/blobs/index.js +10 -13
- package/dist/blobs/index.js.map +1 -1
- package/dist/broker/index.js +11 -14
- package/dist/broker/index.js.map +1 -1
- package/dist/by/index.js +2 -2
- package/dist/capsule/contract.d.ts +176 -16
- package/dist/capsule/contract.js +35 -30
- package/dist/capsule/enclave-aes/bound.d.ts +11 -1
- package/dist/capsule/enclave-aes/classify/digest.d.ts +4 -2
- package/dist/capsule/enclave-aes/index.d.ts +9 -0
- package/dist/capsule/enclave-aes/index.js +643 -78
- package/dist/capsule/enclave-aes/index.js.map +1 -1
- package/dist/capsule/enclave-aes/primitives.d.ts +2 -2
- package/dist/capsule/index.d.ts +1 -1
- package/dist/capsule/plumbing/classify-reveal.d.ts +29 -0
- package/dist/capsule/plumbing/classify-verify.d.ts +53 -0
- package/dist/capsule/plumbing/index.d.ts +17 -0
- package/dist/{capsule-QJJFUUSH.js → capsule-YAITMH77.js} +16 -9
- package/dist/cargo/index.js +34 -36
- package/dist/{chunk-J57OMNJ4.js → chunk-23A4SBRR.js} +3 -4
- package/dist/{chunk-J57OMNJ4.js.map → chunk-23A4SBRR.js.map} +1 -1
- package/dist/{chunk-E3CUGBGW.js → chunk-24AGG4PP.js} +3 -3
- package/dist/{chunk-M2VLXPRU.js → chunk-24IJZA4M.js} +14 -8
- package/dist/chunk-24IJZA4M.js.map +1 -0
- package/dist/{chunk-BCJAUHSG.js → chunk-2NVQ5SEA.js} +15 -5
- package/dist/chunk-2NVQ5SEA.js.map +1 -0
- package/dist/{chunk-MRVQKRXI.js → chunk-2SIREKBR.js} +2 -2
- package/dist/{chunk-CE443VXM.js → chunk-37FOG6AE.js} +14 -7
- package/dist/chunk-37FOG6AE.js.map +1 -0
- package/dist/{chunk-ZZZVNHN2.js → chunk-3M2KK7O7.js} +3 -3
- package/dist/{chunk-P6FATPXQ.js → chunk-3ZCVY3T6.js} +2 -2
- package/dist/{chunk-I7NDTNHK.js → chunk-4CGWLHPQ.js} +6 -6
- package/dist/{chunk-PVQIME6P.js → chunk-56Z4NOC6.js} +3 -3
- package/dist/{chunk-XBG6YJPK.js → chunk-5AVIUJP4.js} +11 -9
- package/dist/{chunk-XBG6YJPK.js.map → chunk-5AVIUJP4.js.map} +1 -1
- package/dist/{chunk-HQFTE3DX.js → chunk-5BGHAVBN.js} +2 -2
- package/dist/{chunk-QHG7GQKM.js → chunk-5JNEDW7I.js} +2 -2
- package/dist/{chunk-NC6CF37L.js → chunk-5OWJSDTO.js} +4 -4
- package/dist/{chunk-NC6CF37L.js.map → chunk-5OWJSDTO.js.map} +1 -1
- package/dist/{chunk-YAYDDYRU.js → chunk-5Y4MO7UQ.js} +4 -4
- package/dist/{chunk-TLIFNRU5.js → chunk-63LZLRWG.js} +2 -2
- package/dist/{chunk-BUFFPAR2.js → chunk-74W56QPY.js} +4 -4
- package/dist/{chunk-VPG2UJYR.js → chunk-7KNYLHVX.js} +3 -3
- package/dist/chunk-7KNYLHVX.js.map +1 -0
- package/dist/{chunk-LFUID7OW.js → chunk-7VJ2SIEI.js} +42 -22
- package/dist/chunk-7VJ2SIEI.js.map +1 -0
- package/dist/{chunk-U2N7DH4S.js → chunk-AHA7UALU.js} +4 -4
- package/dist/{chunk-NB2DYYZL.js → chunk-AIHBYQHF.js} +254 -118
- package/dist/chunk-AIHBYQHF.js.map +1 -0
- package/dist/{chunk-RNQ7V4LH.js → chunk-ANYX2M6P.js} +3 -3
- package/dist/{chunk-VFGLMRO2.js → chunk-ATKYMRBC.js} +4 -4
- package/dist/{chunk-7UHLO4ZN.js → chunk-B2HU55QD.js} +2 -2
- package/dist/{chunk-RKOXA5GZ.js → chunk-BEKMLYQ4.js} +4 -4
- package/dist/{chunk-AYUMAPOS.js → chunk-BPFXD4EX.js} +23 -3
- package/dist/chunk-BPFXD4EX.js.map +1 -0
- package/dist/{chunk-R4PDYYK5.js → chunk-C2NXAR3D.js} +5 -5
- package/dist/{chunk-XBOGGTUJ.js → chunk-CJBWJO5P.js} +6 -6
- package/dist/{chunk-XBOGGTUJ.js.map → chunk-CJBWJO5P.js.map} +1 -1
- package/dist/{chunk-44CU4N7N.js → chunk-CQLMRCKX.js} +2 -2
- package/dist/{chunk-VUBRHJ4H.js → chunk-CR5UPYIJ.js} +1 -1
- package/dist/chunk-CR5UPYIJ.js.map +1 -0
- package/dist/{chunk-4XXRPSPS.js → chunk-DS2JXSUA.js} +6 -6
- package/dist/{chunk-X6Z2SIRF.js → chunk-E2JIE4S3.js} +2 -2
- package/dist/{chunk-EQ6C2ZPT.js → chunk-E7Y4J4GL.js} +2 -2
- package/dist/{chunk-ZMDSBTFT.js → chunk-ECDM6YRX.js} +2 -2
- package/dist/{chunk-WRLWEYHY.js → chunk-EFINFZIF.js} +11 -1
- package/dist/chunk-EFINFZIF.js.map +1 -0
- package/dist/{chunk-JM72WDAY.js → chunk-EM56MHN5.js} +6 -6
- package/dist/{chunk-YWJMM2WY.js → chunk-EQXOJH6O.js} +4 -4
- package/dist/{chunk-ME6LY5UG.js → chunk-ET3U2C3A.js} +2 -2
- package/dist/{chunk-G2KLVCKO.js → chunk-EU4G7PQH.js} +2 -2
- package/dist/{chunk-WJXLTO43.js → chunk-EUCUYK5E.js} +10 -10
- package/dist/{chunk-EPMX3SCC.js → chunk-EWSIJDWO.js} +4 -4
- package/dist/{chunk-KFYUQMF5.js → chunk-F2FD4LSB.js} +2 -2
- package/dist/{chunk-L4UL4IAR.js → chunk-F7ENMZYJ.js} +2 -2
- package/dist/{chunk-5OG7YQX5.js → chunk-FIIVYQOW.js} +5 -5
- package/dist/{chunk-4RF7DVH2.js → chunk-FPK2LPLR.js} +8 -8
- package/dist/chunk-FPK2LPLR.js.map +1 -0
- package/dist/{chunk-2EF2Z4UN.js → chunk-FQEUJGBV.js} +2 -2
- package/dist/{chunk-UORWAG7K.js → chunk-FY4FFNKK.js} +2 -2
- package/dist/{chunk-WA4ZPMKP.js → chunk-GDCYZGPB.js} +2 -2
- package/dist/{chunk-3HDBDUX2.js → chunk-H6Q7GKLI.js} +2 -2
- package/dist/{chunk-654RE5YC.js → chunk-HDAPQF6Q.js} +3 -3
- package/dist/{chunk-B5PWQMZN.js → chunk-HRLMUZLI.js} +5 -5
- package/dist/{chunk-QWC2PRUR.js → chunk-HRNQYGLQ.js} +2 -2
- package/dist/{chunk-YIVAKBCW.js → chunk-I4S7IZSS.js} +321 -235
- package/dist/chunk-I4S7IZSS.js.map +1 -0
- package/dist/{chunk-7DWAYY45.js → chunk-IN4XZJYD.js} +4 -3
- package/dist/{chunk-7DWAYY45.js.map → chunk-IN4XZJYD.js.map} +1 -1
- package/dist/{chunk-JGYCKX56.js → chunk-ISIXU45J.js} +1 -1
- package/dist/{chunk-JGYCKX56.js.map → chunk-ISIXU45J.js.map} +1 -1
- package/dist/{chunk-7PFOKQOJ.js → chunk-J4L4AS2W.js} +2 -2
- package/dist/{chunk-PZZWAHEJ.js → chunk-JPSOFWJR.js} +2 -2
- package/dist/{chunk-B24ODIKE.js → chunk-JRCO67NG.js} +2 -2
- package/dist/{chunk-PNEBCVXP.js → chunk-JW3I3NNZ.js} +2 -2
- package/dist/{chunk-MXNYMFHE.js → chunk-JZMPSQBH.js} +4 -4
- package/dist/{chunk-IIQMNZXT.js → chunk-K5TVSOPQ.js} +5 -5
- package/dist/{chunk-ZPXCQNXJ.js → chunk-K75SL74I.js} +2 -2
- package/dist/{chunk-TA5VTIC4.js → chunk-KA4AAUST.js} +2 -2
- package/dist/chunk-KHSBMLQE.js +161 -0
- package/dist/chunk-KHSBMLQE.js.map +1 -0
- package/dist/{chunk-JWLVBYP4.js → chunk-KUGUML7H.js} +3 -3
- package/dist/{chunk-GWYZEPBY.js → chunk-L4J5NC2Q.js} +2 -2
- package/dist/{chunk-PIF3TNU2.js → chunk-LIX4QPMM.js} +2 -2
- package/dist/{chunk-LCY6ANV2.js → chunk-LWQFGR34.js} +3 -3
- package/dist/{chunk-HQPS27BT.js → chunk-MMSSHMHW.js} +2 -2
- package/dist/{chunk-T5EXREMW.js → chunk-N25Z6PR4.js} +6 -5
- package/dist/chunk-N25Z6PR4.js.map +1 -0
- package/dist/{chunk-ND6S2DKC.js → chunk-N5S2BCW3.js} +2 -2
- package/dist/{chunk-63INIVE4.js → chunk-NIZH2TYZ.js} +2 -2
- package/dist/{chunk-WQHEEYQA.js → chunk-NLDBQHDV.js} +2 -2
- package/dist/{chunk-SKSHWV3E.js → chunk-NQQ4MOPC.js} +4 -4
- package/dist/{chunk-B6EWMGFX.js → chunk-NUBI6PYH.js} +2 -2
- package/dist/{chunk-VWUSOPBF.js → chunk-NYEXUZDW.js} +4 -4
- package/dist/{chunk-GU6QXHPZ.js → chunk-OIBFIWVJ.js} +4 -4
- package/dist/chunk-OIBFIWVJ.js.map +1 -0
- package/dist/{chunk-PIEX7WSG.js → chunk-OOLF5FU2.js} +2 -2
- package/dist/{chunk-HOK5KGBO.js → chunk-OQA7UF2Q.js} +3 -3
- package/dist/{chunk-JMMG7UWR.js → chunk-ORJPICJI.js} +2 -2
- package/dist/{chunk-IF2M43G4.js → chunk-PBRD75JF.js} +2 -2
- package/dist/{chunk-X7Q2XL5U.js → chunk-PDCBL23X.js} +39 -17
- package/dist/chunk-PDCBL23X.js.map +1 -0
- package/dist/{chunk-PR2R57YF.js → chunk-PR36DD2X.js} +7 -7
- package/dist/{chunk-LFCX2JAV.js → chunk-PV4HIC4E.js} +2 -2
- package/dist/{chunk-SKF3DF7M.js → chunk-PZNK4HTV.js} +3 -3
- package/dist/{chunk-5F3KYRG6.js → chunk-QBLPLNPE.js} +3 -3
- package/dist/{chunk-4ZRNXWF6.js → chunk-QZXUISRF.js} +5 -5
- package/dist/{chunk-7Q72NTBE.js → chunk-RBXYO7MD.js} +5 -5
- package/dist/{chunk-S2BQV6HM.js → chunk-RIACRFWA.js} +4 -4
- package/dist/{chunk-DO33YCSZ.js → chunk-RL6RNDJQ.js} +8 -8
- package/dist/{chunk-2SPWVX6W.js → chunk-SJ2P7UXD.js} +7 -7
- package/dist/{chunk-26FMWFAW.js → chunk-SWXS4LV3.js} +11 -11
- package/dist/{chunk-J3ECXFU7.js → chunk-TOTCZFRF.js} +2 -2
- package/dist/{chunk-AN4GUUQM.js → chunk-TT4D52EK.js} +6 -6
- package/dist/{chunk-KOJHCSGS.js → chunk-U7CMJY5P.js} +10 -10
- package/dist/{chunk-DDR6SCG7.js → chunk-UNKTZDA2.js} +11 -11
- package/dist/{chunk-DDR6SCG7.js.map → chunk-UNKTZDA2.js.map} +1 -1
- package/dist/{chunk-WVML7HUZ.js → chunk-UXH4AKH3.js} +95 -151
- package/dist/chunk-UXH4AKH3.js.map +1 -0
- package/dist/{chunk-MKQHIYUY.js → chunk-UZVHSYIF.js} +2 -2
- package/dist/{chunk-FDGE56FS.js → chunk-VHKAW5OI.js} +29 -5
- package/dist/chunk-VHKAW5OI.js.map +1 -0
- package/dist/{chunk-OCSKQUNE.js → chunk-VKZ3TDET.js} +3 -3
- package/dist/{chunk-ESDYDGPH.js → chunk-VLZPUG5A.js} +4 -4
- package/dist/{chunk-PCYIDPFM.js → chunk-VSN5FLMI.js} +2 -2
- package/dist/{chunk-S4QDN4IQ.js → chunk-VYBBE7RN.js} +5 -5
- package/dist/{chunk-XBFJRCRW.js → chunk-WHK4JVKF.js} +8 -8
- package/dist/{chunk-CZEWEOOV.js → chunk-X4LDBALX.js} +2 -2
- package/dist/{chunk-YWEPWJRG.js → chunk-X67E7NIJ.js} +3 -3
- package/dist/{chunk-RRI3JBD6.js → chunk-XMARKBUC.js} +3 -3
- package/dist/{chunk-B3B6HV5S.js → chunk-XMBBTETD.js} +2 -2
- package/dist/{chunk-GQ4MF3CM.js → chunk-XMBTAN5E.js} +28 -14
- package/dist/chunk-XMBTAN5E.js.map +1 -0
- package/dist/{chunk-GEICXZCQ.js → chunk-XROQP6IQ.js} +4 -4
- package/dist/chunk-XWWDZKLS.js +196 -0
- package/dist/chunk-XWWDZKLS.js.map +1 -0
- package/dist/{chunk-VX72USUQ.js → chunk-Y2RYUWSQ.js} +10 -10
- package/dist/{chunk-6I5RRBPP.js → chunk-YCTSQV7K.js} +5 -5
- package/dist/{chunk-7WV6R7RG.js → chunk-YF7P2DG7.js} +2 -2
- package/dist/{chunk-ZZLIFVZG.js → chunk-ZG7DBIVX.js} +2 -2
- package/dist/{chunk-Y6WJJRVV.js → chunk-ZGJ775X7.js} +2 -2
- package/dist/{chunk-PQGCWTTI.js → chunk-ZQQLOEWN.js} +3 -3
- package/dist/classified/index.js +5 -5
- package/dist/{classified-marker-LY7KQFPH.js → classified-marker-HKMRC7SC.js} +3 -3
- package/dist/{reveal-LK3GX4L6.js → classify-reveal-YSJKJEIR.js} +7 -12
- package/dist/classify-reveal-YSJKJEIR.js.map +1 -0
- package/dist/{verify-FT5COLP2.js → classify-verify-ZCTKYQ43.js} +31 -41
- package/dist/classify-verify-ZCTKYQ43.js.map +1 -0
- package/dist/collection-facade-PPKNUR2J.js +38 -0
- package/dist/{computed-XG7LFB7A.js → computed-UCYVPMZA.js} +3 -3
- package/dist/consent/index.js +6 -9
- package/dist/consent/index.js.map +1 -1
- package/dist/cover/index.js +6 -9
- package/dist/custody/index.js +11 -13
- package/dist/{dead-filter-F4EKHDQY.js → dead-filter-YOBWRG4O.js} +8 -11
- package/dist/{dead-filter-F4EKHDQY.js.map → dead-filter-YOBWRG4O.js.map} +1 -1
- package/dist/debug/index.js +5 -8
- package/dist/debug/index.js.map +1 -1
- package/dist/delegation-SNALWRMO.js +24 -0
- package/dist/derivations/index.js +20 -23
- package/dist/derive-4GNU4E4I.js +17 -0
- package/dist/directory/index.js +7 -10
- package/dist/{dispatch-YNHZLB72.js → dispatch-QW32QBLW.js} +17 -20
- package/dist/{dispatch-YNHZLB72.js.map → dispatch-QW32QBLW.js.map} +1 -1
- package/dist/{dispatch-URNW4Q2T.js → dispatch-V5WLDTVX.js} +5 -5
- package/dist/executor-7QN22OKI.js +8 -0
- package/dist/executor-BJZJNVBB.js +8 -0
- package/dist/executor-JEAAEJUM.js +32 -0
- package/dist/export-accessible-TVO2KQPG.js +20 -0
- package/dist/extract-partition-43CLDRN4.js +33 -0
- package/dist/{fanout-sidecar-6CSMTIVB.js → fanout-sidecar-DDONAFJT.js} +6 -9
- package/dist/{fanout-sidecar-6CSMTIVB.js.map → fanout-sidecar-DDONAFJT.js.map} +1 -1
- package/dist/forget/index.js +6 -9
- package/dist/forget/index.js.map +1 -1
- package/dist/guards/index.js +4 -4
- package/dist/history/index.js +11 -14
- package/dist/history/index.js.map +1 -1
- package/dist/i18n/index.js +11 -14
- package/dist/i18n/index.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +122 -123
- package/dist/index.js.map +1 -1
- package/dist/indexing/index.js +5 -5
- package/dist/introspection/index.js +8 -11
- package/dist/issue-EIHEDAXM.js +16 -0
- package/dist/kernel/capsule-requirements.d.ts +84 -0
- package/dist/kernel/errors.d.ts +15 -0
- package/dist/kernel/export-scope.d.ts +28 -1
- package/dist/kernel/store-segment-guard.d.ts +29 -0
- package/dist/kernel/types.d.ts +164 -8
- package/dist/kernel/validation.d.ts +32 -0
- package/dist/kernel/vault.d.ts +3 -3
- package/dist/{ledger-FV6NFTOR.js → ledger-BMVUFQ3R.js} +8 -11
- package/dist/liberate-7KHXCLNJ.js +23 -0
- package/dist/link-set-PC2EJRKL.js +26 -0
- package/dist/{managed-secret-PBJZHPQO.js → managed-secret-RPRVEYZA.js} +7 -10
- package/dist/materialized-views/index.js +23 -26
- package/dist/{migrate-cek-J634S4NU.js → migrate-cek-DTSCWGEF.js} +2 -2
- package/dist/money/index.js +5 -5
- package/dist/noydb-AYDNOXAX.js +98 -0
- package/dist/on/index.js +11 -13
- package/dist/overlay-views/index.js +4 -4
- package/dist/periods/index.js +9 -12
- package/dist/pod/index.js +65 -67
- package/dist/{pod-handle-IOEYUDCA.js → pod-handle-KBPQRN6Q.js} +6 -9
- package/dist/{pod-handle-IOEYUDCA.js.map → pod-handle-KBPQRN6Q.js.map} +1 -1
- package/dist/policy/index.js +7 -10
- package/dist/port/at/index.d.ts +1 -0
- package/dist/port/with/collection-registries.d.ts +37 -0
- package/dist/portability/index.js +8 -8
- package/dist/{post-register-L42VXYFB.js → post-register-RITSNASO.js} +6 -6
- package/dist/query/all/index.js +15 -15
- package/dist/query/index.js +7 -7
- package/dist/query/live/index.js +7 -7
- package/dist/query/reduce/index.js +10 -10
- package/dist/query/relate/index.js +9 -9
- package/dist/reduce/index.js +8 -8
- package/dist/register-BB34SK7E.js +27 -0
- package/dist/registry-65L6V5TO.js +20 -0
- package/dist/registry-HU62GPWA.js +32 -0
- package/dist/registry-SMNK6UM4.js +8 -0
- package/dist/registry-X5VPBKCO.js +8 -0
- package/dist/request-withdrawal-4SKAH46W.js +26 -0
- package/dist/{restore-to-ZQ2MXOFO.js → restore-to-VQHT67OH.js} +7 -10
- package/dist/{restore-to-ZQ2MXOFO.js.map → restore-to-VQHT67OH.js.map} +1 -1
- package/dist/revoke-IF5PX2JY.js +21 -0
- package/dist/satellites/index.js +1 -1
- package/dist/schema-update/index.js +2 -2
- package/dist/sealed-record/index.js +9 -12
- package/dist/sealed-record/index.js.map +1 -1
- package/dist/search/index.js +4 -4
- package/dist/{seed-XHQQF6LJ.js → seed-F2OSDZJR.js} +11 -13
- package/dist/{seed-XHQQF6LJ.js.map → seed-F2OSDZJR.js.map} +1 -1
- package/dist/sequence/index.js +6 -9
- package/dist/session/index.js +6 -9
- package/dist/session/index.js.map +1 -1
- package/dist/shadow/index.js +2 -2
- package/dist/signer-5P7IZC2K.js +20 -0
- package/dist/snapshots/index.js +8 -10
- package/dist/snapshots/index.js.map +1 -1
- package/dist/{stale-XY2QUSGU.js → stale-PUCZH5GJ.js} +7 -10
- package/dist/storage-5EGY5OYE.js +18 -0
- package/dist/store/index.js +1 -1
- package/dist/{store-coordination-provider-F7YG22D3.js → store-coordination-provider-SEQM7SHJ.js} +7 -10
- package/dist/{store-coordination-provider-F7YG22D3.js.map → store-coordination-provider-SEQM7SHJ.js.map} +1 -1
- package/dist/sync/index.js +13 -15
- package/dist/sync/index.js.map +1 -1
- package/dist/team/index.js +14 -16
- package/dist/tiers/index.js +8 -11
- package/dist/to/index.js +2 -2
- package/dist/transactions/index.js +3 -3
- package/dist/util/index.js +1 -1
- package/dist/vault-diff-H7LT5ZBJ.js +8 -0
- package/dist/vault-head/index.js +5 -8
- package/dist/vault-head/index.js.map +1 -1
- package/dist/walk-Z4N7PCZ2.js +17 -0
- package/dist/with-audit/portability/export-accessible.d.ts +3 -1
- package/dist/with-cargo/vault-diff.d.ts +28 -0
- package/dist/with-commit/sequence/index.d.ts +22 -0
- package/dist/with-party/team/keyring.d.ts +77 -0
- package/dist/with-party/team/managed-secret.d.ts +40 -3
- package/dist/with-shape/manifest/storage.d.ts +2 -2
- package/dist/with-shape/manifest/writer.d.ts +2 -2
- package/dist/with-store/store-middleware.d.ts +18 -5
- package/dist/withdraw-accessible-CRCIQSTL.js +23 -0
- package/package.json +3 -3
- package/dist/api-ARU35MCC.js +0 -18
- package/dist/capsule/enclave-aes/classify/reveal.d.ts +0 -10
- package/dist/capsule/enclave-aes/classify/verify.d.ts +0 -36
- package/dist/chunk-4RF7DVH2.js.map +0 -1
- package/dist/chunk-6B4X447I.js +0 -40
- package/dist/chunk-6B4X447I.js.map +0 -1
- package/dist/chunk-6Y3UJT5H.js +0 -157
- package/dist/chunk-6Y3UJT5H.js.map +0 -1
- package/dist/chunk-AYUMAPOS.js.map +0 -1
- package/dist/chunk-BCJAUHSG.js.map +0 -1
- package/dist/chunk-CE443VXM.js.map +0 -1
- package/dist/chunk-FDGE56FS.js.map +0 -1
- package/dist/chunk-GLSRKIU3.js +0 -591
- package/dist/chunk-GLSRKIU3.js.map +0 -1
- package/dist/chunk-GQ4MF3CM.js.map +0 -1
- package/dist/chunk-GU6QXHPZ.js.map +0 -1
- package/dist/chunk-LFUID7OW.js.map +0 -1
- package/dist/chunk-M2VLXPRU.js.map +0 -1
- package/dist/chunk-NB2DYYZL.js.map +0 -1
- package/dist/chunk-NH2UOV3B.js +0 -18
- package/dist/chunk-NH2UOV3B.js.map +0 -1
- package/dist/chunk-OJAFKGI7.js +0 -27
- package/dist/chunk-OJAFKGI7.js.map +0 -1
- package/dist/chunk-PVBKEBJU.js +0 -22
- package/dist/chunk-PVBKEBJU.js.map +0 -1
- package/dist/chunk-RQLCOSEJ.js +0 -78
- package/dist/chunk-RQLCOSEJ.js.map +0 -1
- package/dist/chunk-T5EXREMW.js.map +0 -1
- package/dist/chunk-VPG2UJYR.js.map +0 -1
- package/dist/chunk-VUBRHJ4H.js.map +0 -1
- package/dist/chunk-WRLWEYHY.js.map +0 -1
- package/dist/chunk-WVML7HUZ.js.map +0 -1
- package/dist/chunk-X7Q2XL5U.js.map +0 -1
- package/dist/chunk-YIVAKBCW.js.map +0 -1
- package/dist/collection-facade-SETOHJ3R.js +0 -41
- package/dist/delegation-JIQCMKW6.js +0 -26
- package/dist/derive-45KCFFOS.js +0 -20
- package/dist/executor-BVVZ5UHG.js +0 -8
- package/dist/executor-R25UN3FA.js +0 -8
- package/dist/executor-SIYBLT3P.js +0 -35
- package/dist/export-accessible-P672FZEJ.js +0 -22
- package/dist/extract-partition-DQ3FVL6H.js +0 -35
- package/dist/find-HHF2HBAC.js +0 -10
- package/dist/issue-NPLQHB3S.js +0 -19
- package/dist/liberate-A7WASOCG.js +0 -25
- package/dist/link-set-UMRSGMQ5.js +0 -29
- package/dist/noydb-V23UJKHT.js +0 -100
- package/dist/register-2VINJWYJ.js +0 -30
- package/dist/registry-3VLHDUID.js +0 -8
- package/dist/registry-6HVHDR3P.js +0 -35
- package/dist/registry-V4FQUMYP.js +0 -23
- package/dist/registry-Z2E6ZCPM.js +0 -8
- package/dist/request-withdrawal-PSIHKQP4.js +0 -28
- package/dist/reveal-LK3GX4L6.js.map +0 -1
- package/dist/revoke-2NYMID63.js +0 -24
- package/dist/signer-CP6XZLE3.js +0 -23
- package/dist/storage-QTM6JYQF.js +0 -21
- package/dist/vault-diff-C6WUJFNP.js +0 -8
- package/dist/verify-FT5COLP2.js.map +0 -1
- package/dist/walk-52FW6EKP.js +0 -20
- package/dist/withdraw-accessible-IVMKJGEN.js +0 -25
- package/dist/withdraw-accessible-IVMKJGEN.js.map +0 -1
- /package/dist/{api-ARU35MCC.js.map → api-QSEKT4KS.js.map} +0 -0
- /package/dist/{capsule-QJJFUUSH.js.map → capsule-YAITMH77.js.map} +0 -0
- /package/dist/{chunk-E3CUGBGW.js.map → chunk-24AGG4PP.js.map} +0 -0
- /package/dist/{chunk-MRVQKRXI.js.map → chunk-2SIREKBR.js.map} +0 -0
- /package/dist/{chunk-ZZZVNHN2.js.map → chunk-3M2KK7O7.js.map} +0 -0
- /package/dist/{chunk-P6FATPXQ.js.map → chunk-3ZCVY3T6.js.map} +0 -0
- /package/dist/{chunk-I7NDTNHK.js.map → chunk-4CGWLHPQ.js.map} +0 -0
- /package/dist/{chunk-PVQIME6P.js.map → chunk-56Z4NOC6.js.map} +0 -0
- /package/dist/{chunk-HQFTE3DX.js.map → chunk-5BGHAVBN.js.map} +0 -0
- /package/dist/{chunk-QHG7GQKM.js.map → chunk-5JNEDW7I.js.map} +0 -0
- /package/dist/{chunk-YAYDDYRU.js.map → chunk-5Y4MO7UQ.js.map} +0 -0
- /package/dist/{chunk-TLIFNRU5.js.map → chunk-63LZLRWG.js.map} +0 -0
- /package/dist/{chunk-BUFFPAR2.js.map → chunk-74W56QPY.js.map} +0 -0
- /package/dist/{chunk-U2N7DH4S.js.map → chunk-AHA7UALU.js.map} +0 -0
- /package/dist/{chunk-RNQ7V4LH.js.map → chunk-ANYX2M6P.js.map} +0 -0
- /package/dist/{chunk-VFGLMRO2.js.map → chunk-ATKYMRBC.js.map} +0 -0
- /package/dist/{chunk-7UHLO4ZN.js.map → chunk-B2HU55QD.js.map} +0 -0
- /package/dist/{chunk-RKOXA5GZ.js.map → chunk-BEKMLYQ4.js.map} +0 -0
- /package/dist/{chunk-R4PDYYK5.js.map → chunk-C2NXAR3D.js.map} +0 -0
- /package/dist/{chunk-44CU4N7N.js.map → chunk-CQLMRCKX.js.map} +0 -0
- /package/dist/{chunk-4XXRPSPS.js.map → chunk-DS2JXSUA.js.map} +0 -0
- /package/dist/{chunk-X6Z2SIRF.js.map → chunk-E2JIE4S3.js.map} +0 -0
- /package/dist/{chunk-EQ6C2ZPT.js.map → chunk-E7Y4J4GL.js.map} +0 -0
- /package/dist/{chunk-ZMDSBTFT.js.map → chunk-ECDM6YRX.js.map} +0 -0
- /package/dist/{chunk-JM72WDAY.js.map → chunk-EM56MHN5.js.map} +0 -0
- /package/dist/{chunk-YWJMM2WY.js.map → chunk-EQXOJH6O.js.map} +0 -0
- /package/dist/{chunk-ME6LY5UG.js.map → chunk-ET3U2C3A.js.map} +0 -0
- /package/dist/{chunk-G2KLVCKO.js.map → chunk-EU4G7PQH.js.map} +0 -0
- /package/dist/{chunk-WJXLTO43.js.map → chunk-EUCUYK5E.js.map} +0 -0
- /package/dist/{chunk-EPMX3SCC.js.map → chunk-EWSIJDWO.js.map} +0 -0
- /package/dist/{chunk-KFYUQMF5.js.map → chunk-F2FD4LSB.js.map} +0 -0
- /package/dist/{chunk-L4UL4IAR.js.map → chunk-F7ENMZYJ.js.map} +0 -0
- /package/dist/{chunk-5OG7YQX5.js.map → chunk-FIIVYQOW.js.map} +0 -0
- /package/dist/{chunk-2EF2Z4UN.js.map → chunk-FQEUJGBV.js.map} +0 -0
- /package/dist/{chunk-UORWAG7K.js.map → chunk-FY4FFNKK.js.map} +0 -0
- /package/dist/{chunk-WA4ZPMKP.js.map → chunk-GDCYZGPB.js.map} +0 -0
- /package/dist/{chunk-3HDBDUX2.js.map → chunk-H6Q7GKLI.js.map} +0 -0
- /package/dist/{chunk-654RE5YC.js.map → chunk-HDAPQF6Q.js.map} +0 -0
- /package/dist/{chunk-B5PWQMZN.js.map → chunk-HRLMUZLI.js.map} +0 -0
- /package/dist/{chunk-QWC2PRUR.js.map → chunk-HRNQYGLQ.js.map} +0 -0
- /package/dist/{chunk-7PFOKQOJ.js.map → chunk-J4L4AS2W.js.map} +0 -0
- /package/dist/{chunk-PZZWAHEJ.js.map → chunk-JPSOFWJR.js.map} +0 -0
- /package/dist/{chunk-B24ODIKE.js.map → chunk-JRCO67NG.js.map} +0 -0
- /package/dist/{chunk-PNEBCVXP.js.map → chunk-JW3I3NNZ.js.map} +0 -0
- /package/dist/{chunk-MXNYMFHE.js.map → chunk-JZMPSQBH.js.map} +0 -0
- /package/dist/{chunk-IIQMNZXT.js.map → chunk-K5TVSOPQ.js.map} +0 -0
- /package/dist/{chunk-ZPXCQNXJ.js.map → chunk-K75SL74I.js.map} +0 -0
- /package/dist/{chunk-TA5VTIC4.js.map → chunk-KA4AAUST.js.map} +0 -0
- /package/dist/{chunk-JWLVBYP4.js.map → chunk-KUGUML7H.js.map} +0 -0
- /package/dist/{chunk-GWYZEPBY.js.map → chunk-L4J5NC2Q.js.map} +0 -0
- /package/dist/{chunk-PIF3TNU2.js.map → chunk-LIX4QPMM.js.map} +0 -0
- /package/dist/{chunk-LCY6ANV2.js.map → chunk-LWQFGR34.js.map} +0 -0
- /package/dist/{chunk-HQPS27BT.js.map → chunk-MMSSHMHW.js.map} +0 -0
- /package/dist/{chunk-ND6S2DKC.js.map → chunk-N5S2BCW3.js.map} +0 -0
- /package/dist/{chunk-63INIVE4.js.map → chunk-NIZH2TYZ.js.map} +0 -0
- /package/dist/{chunk-WQHEEYQA.js.map → chunk-NLDBQHDV.js.map} +0 -0
- /package/dist/{chunk-SKSHWV3E.js.map → chunk-NQQ4MOPC.js.map} +0 -0
- /package/dist/{chunk-B6EWMGFX.js.map → chunk-NUBI6PYH.js.map} +0 -0
- /package/dist/{chunk-VWUSOPBF.js.map → chunk-NYEXUZDW.js.map} +0 -0
- /package/dist/{chunk-PIEX7WSG.js.map → chunk-OOLF5FU2.js.map} +0 -0
- /package/dist/{chunk-HOK5KGBO.js.map → chunk-OQA7UF2Q.js.map} +0 -0
- /package/dist/{chunk-JMMG7UWR.js.map → chunk-ORJPICJI.js.map} +0 -0
- /package/dist/{chunk-IF2M43G4.js.map → chunk-PBRD75JF.js.map} +0 -0
- /package/dist/{chunk-PR2R57YF.js.map → chunk-PR36DD2X.js.map} +0 -0
- /package/dist/{chunk-LFCX2JAV.js.map → chunk-PV4HIC4E.js.map} +0 -0
- /package/dist/{chunk-SKF3DF7M.js.map → chunk-PZNK4HTV.js.map} +0 -0
- /package/dist/{chunk-5F3KYRG6.js.map → chunk-QBLPLNPE.js.map} +0 -0
- /package/dist/{chunk-4ZRNXWF6.js.map → chunk-QZXUISRF.js.map} +0 -0
- /package/dist/{chunk-7Q72NTBE.js.map → chunk-RBXYO7MD.js.map} +0 -0
- /package/dist/{chunk-S2BQV6HM.js.map → chunk-RIACRFWA.js.map} +0 -0
- /package/dist/{chunk-DO33YCSZ.js.map → chunk-RL6RNDJQ.js.map} +0 -0
- /package/dist/{chunk-2SPWVX6W.js.map → chunk-SJ2P7UXD.js.map} +0 -0
- /package/dist/{chunk-26FMWFAW.js.map → chunk-SWXS4LV3.js.map} +0 -0
- /package/dist/{chunk-J3ECXFU7.js.map → chunk-TOTCZFRF.js.map} +0 -0
- /package/dist/{chunk-AN4GUUQM.js.map → chunk-TT4D52EK.js.map} +0 -0
- /package/dist/{chunk-KOJHCSGS.js.map → chunk-U7CMJY5P.js.map} +0 -0
- /package/dist/{chunk-MKQHIYUY.js.map → chunk-UZVHSYIF.js.map} +0 -0
- /package/dist/{chunk-OCSKQUNE.js.map → chunk-VKZ3TDET.js.map} +0 -0
- /package/dist/{chunk-ESDYDGPH.js.map → chunk-VLZPUG5A.js.map} +0 -0
- /package/dist/{chunk-PCYIDPFM.js.map → chunk-VSN5FLMI.js.map} +0 -0
- /package/dist/{chunk-S4QDN4IQ.js.map → chunk-VYBBE7RN.js.map} +0 -0
- /package/dist/{chunk-XBFJRCRW.js.map → chunk-WHK4JVKF.js.map} +0 -0
- /package/dist/{chunk-CZEWEOOV.js.map → chunk-X4LDBALX.js.map} +0 -0
- /package/dist/{chunk-YWEPWJRG.js.map → chunk-X67E7NIJ.js.map} +0 -0
- /package/dist/{chunk-RRI3JBD6.js.map → chunk-XMARKBUC.js.map} +0 -0
- /package/dist/{chunk-B3B6HV5S.js.map → chunk-XMBBTETD.js.map} +0 -0
- /package/dist/{chunk-GEICXZCQ.js.map → chunk-XROQP6IQ.js.map} +0 -0
- /package/dist/{chunk-VX72USUQ.js.map → chunk-Y2RYUWSQ.js.map} +0 -0
- /package/dist/{chunk-6I5RRBPP.js.map → chunk-YCTSQV7K.js.map} +0 -0
- /package/dist/{chunk-7WV6R7RG.js.map → chunk-YF7P2DG7.js.map} +0 -0
- /package/dist/{chunk-ZZLIFVZG.js.map → chunk-ZG7DBIVX.js.map} +0 -0
- /package/dist/{chunk-Y6WJJRVV.js.map → chunk-ZGJ775X7.js.map} +0 -0
- /package/dist/{chunk-PQGCWTTI.js.map → chunk-ZQQLOEWN.js.map} +0 -0
- /package/dist/{classified-marker-LY7KQFPH.js.map → classified-marker-HKMRC7SC.js.map} +0 -0
- /package/dist/{collection-facade-SETOHJ3R.js.map → collection-facade-PPKNUR2J.js.map} +0 -0
- /package/dist/{computed-XG7LFB7A.js.map → computed-UCYVPMZA.js.map} +0 -0
- /package/dist/{delegation-JIQCMKW6.js.map → delegation-SNALWRMO.js.map} +0 -0
- /package/dist/{derive-45KCFFOS.js.map → derive-4GNU4E4I.js.map} +0 -0
- /package/dist/{dispatch-URNW4Q2T.js.map → dispatch-V5WLDTVX.js.map} +0 -0
- /package/dist/{executor-BVVZ5UHG.js.map → executor-7QN22OKI.js.map} +0 -0
- /package/dist/{executor-R25UN3FA.js.map → executor-BJZJNVBB.js.map} +0 -0
- /package/dist/{executor-SIYBLT3P.js.map → executor-JEAAEJUM.js.map} +0 -0
- /package/dist/{export-accessible-P672FZEJ.js.map → export-accessible-TVO2KQPG.js.map} +0 -0
- /package/dist/{extract-partition-DQ3FVL6H.js.map → extract-partition-43CLDRN4.js.map} +0 -0
- /package/dist/{find-HHF2HBAC.js.map → issue-EIHEDAXM.js.map} +0 -0
- /package/dist/{issue-NPLQHB3S.js.map → ledger-BMVUFQ3R.js.map} +0 -0
- /package/dist/{ledger-FV6NFTOR.js.map → liberate-7KHXCLNJ.js.map} +0 -0
- /package/dist/{liberate-A7WASOCG.js.map → link-set-PC2EJRKL.js.map} +0 -0
- /package/dist/{link-set-UMRSGMQ5.js.map → managed-secret-RPRVEYZA.js.map} +0 -0
- /package/dist/{migrate-cek-J634S4NU.js.map → migrate-cek-DTSCWGEF.js.map} +0 -0
- /package/dist/{managed-secret-PBJZHPQO.js.map → noydb-AYDNOXAX.js.map} +0 -0
- /package/dist/{post-register-L42VXYFB.js.map → post-register-RITSNASO.js.map} +0 -0
- /package/dist/{noydb-V23UJKHT.js.map → register-BB34SK7E.js.map} +0 -0
- /package/dist/{register-2VINJWYJ.js.map → registry-65L6V5TO.js.map} +0 -0
- /package/dist/{registry-3VLHDUID.js.map → registry-HU62GPWA.js.map} +0 -0
- /package/dist/{registry-6HVHDR3P.js.map → registry-SMNK6UM4.js.map} +0 -0
- /package/dist/{registry-V4FQUMYP.js.map → registry-X5VPBKCO.js.map} +0 -0
- /package/dist/{registry-Z2E6ZCPM.js.map → request-withdrawal-4SKAH46W.js.map} +0 -0
- /package/dist/{request-withdrawal-PSIHKQP4.js.map → revoke-IF5PX2JY.js.map} +0 -0
- /package/dist/{revoke-2NYMID63.js.map → signer-5P7IZC2K.js.map} +0 -0
- /package/dist/{signer-CP6XZLE3.js.map → stale-PUCZH5GJ.js.map} +0 -0
- /package/dist/{stale-XY2QUSGU.js.map → storage-5EGY5OYE.js.map} +0 -0
- /package/dist/{storage-QTM6JYQF.js.map → vault-diff-H7LT5ZBJ.js.map} +0 -0
- /package/dist/{vault-diff-C6WUJFNP.js.map → walk-Z4N7PCZ2.js.map} +0 -0
- /package/dist/{walk-52FW6EKP.js.map → withdraw-accessible-CRCIQSTL.js.map} +0 -0
package/dist/sync/index.js
CHANGED
|
@@ -3,23 +3,21 @@ import {
|
|
|
3
3
|
SyncEngine,
|
|
4
4
|
SyncTransaction,
|
|
5
5
|
bootstrapKeyrings
|
|
6
|
-
} from "../chunk-
|
|
6
|
+
} from "../chunk-37FOG6AE.js";
|
|
7
7
|
import {
|
|
8
8
|
NO_SYNC
|
|
9
|
-
} from "../chunk-
|
|
10
|
-
import "../chunk-
|
|
11
|
-
import "../chunk-
|
|
12
|
-
import "../chunk-
|
|
13
|
-
import "../chunk-
|
|
14
|
-
import "../chunk-
|
|
15
|
-
import "../chunk-
|
|
16
|
-
import "../chunk-
|
|
17
|
-
import "../chunk-
|
|
18
|
-
import "../chunk-
|
|
19
|
-
import "../chunk-
|
|
20
|
-
import "../chunk-
|
|
21
|
-
import "../chunk-VUBRHJ4H.js";
|
|
22
|
-
import "../chunk-JGYCKX56.js";
|
|
9
|
+
} from "../chunk-B2HU55QD.js";
|
|
10
|
+
import "../chunk-JRCO67NG.js";
|
|
11
|
+
import "../chunk-UXH4AKH3.js";
|
|
12
|
+
import "../chunk-ZQQLOEWN.js";
|
|
13
|
+
import "../chunk-KHSBMLQE.js";
|
|
14
|
+
import "../chunk-VKZ3TDET.js";
|
|
15
|
+
import "../chunk-F2FD4LSB.js";
|
|
16
|
+
import "../chunk-EFINFZIF.js";
|
|
17
|
+
import "../chunk-I4S7IZSS.js";
|
|
18
|
+
import "../chunk-XWWDZKLS.js";
|
|
19
|
+
import "../chunk-CR5UPYIJ.js";
|
|
20
|
+
import "../chunk-ISIXU45J.js";
|
|
23
21
|
|
|
24
22
|
// src/with-sync/active.ts
|
|
25
23
|
function withSync(options) {
|
package/dist/sync/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/with-sync/active.ts"],"sourcesContent":["/**\n * Active sync strategy — `withSync()` returns the real implementation\n * that wires the `SyncEngine`, `SyncTransaction`, and `PresenceHandle`\n * constructors into the Noydb / Vault / Collection hot paths.\n *\n * Consumers opt in by:\n *\n * ```ts\n * import { createNoydb } from '@noy-db/hub'\n * import { withSync } from '@noy-db/hub/sync'\n *\n * const db = await createNoydb({\n * store: localStore,\n * sync: remoteStore,\n * user: ...,\n * syncStrategy: withSync(),\n * })\n * ```\n *\n * The factory delegates to the existing `sync.ts`,\n * `sync-transaction.ts`, and `presence.ts` modules. Splitting the\n * import chain through this file is what lets tsup tree-shake the\n * ~856 LOC of replication + presence machinery out of the default\n * bundle when no `withSync()` import is present.\n *\n * Keyring + grant/revoke/magic-link/delegation stay in the always-on\n * core (or tree-shake via direct named imports) — those are required\n * for any multi-user vault, even purely local ones.\n *\n * @public\n */\n\nimport type { SyncStrategy, BuildSyncEngineOptions } from './strategy.js'\nimport type { PresenceHandleOpts } from './presence.js'\nimport type { Vault } from '../kernel/vault.js'\nimport { SyncEngine } from './engine.js'\nimport { SyncTransaction } from './transaction.js'\nimport { PresenceHandle } from './presence.js'\nimport { bootstrapKeyrings } from './reserved-mirror.js'\n\n/**\n * core#107 — `arbiter: true` makes this device the vault's ARBITER: its\n * admission refusals are replicated so the writer finds out, instead of\n * staying local to the device that judged them.\n *\n * ⚠️ One arbiter, named by configuration on the device that is to be it\n * (the admin host, or the daemon) — ruled over a quorum because the failure\n * mode is legible: no arbiter configured means no replication, which is\n * exactly the pre-core#107 behaviour. It is NOT an authority proof: nothing\n * stops a member hand-writing `_sync_rejections`, and the reason that is\n * tolerable is the report-only ruling — a replicated refusal never deletes,\n * tombstones or retracts anything, so the worst a forged one does is show\n * somebody a notice about their own record.\n *\n * ⚠️ THE CONDITION THAT WOULD MAKE THAT NON-BOUNDARY A REAL ONE, named by\n * pilot-1 when they accepted it: every member is currently staff of the same\n * firm, and a forged refusal is sealed under the refused record's own\n * collection DEK — so a forger can only show a notice about a record they\n * could already read. ⛔ If EXTERNAL `client`-role users ever hold\n * collections of their own, \"who may write `_sync_rejections`\" stops being\n * cosmetic and this needs an authority design, not a flag. Do not read the\n * paragraph above as a general safety argument; it is an argument about one\n * topology, and this is the trigger to re-open it.\n */\nexport interface WithSyncOptions {\n readonly arbiter?: boolean\n}\n\nexport function withSync(options?: WithSyncOptions): SyncStrategy {\n return {\n bootstrapKeyrings,\n buildSyncEngine(opts: BuildSyncEngineOptions): SyncEngine {\n return new SyncEngine({ ...opts, ...(options?.arbiter === true && { arbiter: true }) })\n },\n buildSyncTransaction(vault: Vault, engine: SyncEngine): SyncTransaction {\n return new SyncTransaction(vault, engine)\n },\n buildPresence<P>(opts: PresenceHandleOpts): PresenceHandle<P> {\n return new PresenceHandle<P>(opts)\n },\n }\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../src/with-sync/active.ts"],"sourcesContent":["/**\n * Active sync strategy — `withSync()` returns the real implementation\n * that wires the `SyncEngine`, `SyncTransaction`, and `PresenceHandle`\n * constructors into the Noydb / Vault / Collection hot paths.\n *\n * Consumers opt in by:\n *\n * ```ts\n * import { createNoydb } from '@noy-db/hub'\n * import { withSync } from '@noy-db/hub/sync'\n *\n * const db = await createNoydb({\n * store: localStore,\n * sync: remoteStore,\n * user: ...,\n * syncStrategy: withSync(),\n * })\n * ```\n *\n * The factory delegates to the existing `sync.ts`,\n * `sync-transaction.ts`, and `presence.ts` modules. Splitting the\n * import chain through this file is what lets tsup tree-shake the\n * ~856 LOC of replication + presence machinery out of the default\n * bundle when no `withSync()` import is present.\n *\n * Keyring + grant/revoke/magic-link/delegation stay in the always-on\n * core (or tree-shake via direct named imports) — those are required\n * for any multi-user vault, even purely local ones.\n *\n * @public\n */\n\nimport type { SyncStrategy, BuildSyncEngineOptions } from './strategy.js'\nimport type { PresenceHandleOpts } from './presence.js'\nimport type { Vault } from '../kernel/vault.js'\nimport { SyncEngine } from './engine.js'\nimport { SyncTransaction } from './transaction.js'\nimport { PresenceHandle } from './presence.js'\nimport { bootstrapKeyrings } from './reserved-mirror.js'\n\n/**\n * core#107 — `arbiter: true` makes this device the vault's ARBITER: its\n * admission refusals are replicated so the writer finds out, instead of\n * staying local to the device that judged them.\n *\n * ⚠️ One arbiter, named by configuration on the device that is to be it\n * (the admin host, or the daemon) — ruled over a quorum because the failure\n * mode is legible: no arbiter configured means no replication, which is\n * exactly the pre-core#107 behaviour. It is NOT an authority proof: nothing\n * stops a member hand-writing `_sync_rejections`, and the reason that is\n * tolerable is the report-only ruling — a replicated refusal never deletes,\n * tombstones or retracts anything, so the worst a forged one does is show\n * somebody a notice about their own record.\n *\n * ⚠️ THE CONDITION THAT WOULD MAKE THAT NON-BOUNDARY A REAL ONE, named by\n * pilot-1 when they accepted it: every member is currently staff of the same\n * firm, and a forged refusal is sealed under the refused record's own\n * collection DEK — so a forger can only show a notice about a record they\n * could already read. ⛔ If EXTERNAL `client`-role users ever hold\n * collections of their own, \"who may write `_sync_rejections`\" stops being\n * cosmetic and this needs an authority design, not a flag. Do not read the\n * paragraph above as a general safety argument; it is an argument about one\n * topology, and this is the trigger to re-open it.\n */\nexport interface WithSyncOptions {\n readonly arbiter?: boolean\n}\n\nexport function withSync(options?: WithSyncOptions): SyncStrategy {\n return {\n bootstrapKeyrings,\n buildSyncEngine(opts: BuildSyncEngineOptions): SyncEngine {\n return new SyncEngine({ ...opts, ...(options?.arbiter === true && { arbiter: true }) })\n },\n buildSyncTransaction(vault: Vault, engine: SyncEngine): SyncTransaction {\n return new SyncTransaction(vault, engine)\n },\n buildPresence<P>(opts: PresenceHandleOpts): PresenceHandle<P> {\n return new PresenceHandle<P>(opts)\n },\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAoEO,SAAS,SAAS,SAAyC;AAChE,SAAO;AAAA,IACL;AAAA,IACA,gBAAgB,MAA0C;AACxD,aAAO,IAAI,WAAW,EAAE,GAAG,MAAM,GAAI,SAAS,YAAY,QAAQ,EAAE,SAAS,KAAK,EAAG,CAAC;AAAA,IACxF;AAAA,IACA,qBAAqB,OAAc,QAAqC;AACtE,aAAO,IAAI,gBAAgB,OAAO,MAAM;AAAA,IAC1C;AAAA,IACA,cAAiB,MAA6C;AAC5D,aAAO,IAAI,eAAkB,IAAI;AAAA,IACnC;AAAA,EACF;AACF;","names":[]}
|
package/dist/team/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
MemoryDeviceSeal,
|
|
3
3
|
withTeam
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-VLZPUG5A.js";
|
|
5
5
|
import {
|
|
6
6
|
beginEchoUnlock
|
|
7
|
-
} from "../chunk-
|
|
7
|
+
} from "../chunk-X67E7NIJ.js";
|
|
8
8
|
import {
|
|
9
9
|
NO_TEAM,
|
|
10
10
|
burnPaperRecoveryEntry,
|
|
@@ -34,8 +34,8 @@ import {
|
|
|
34
34
|
unwrapMagicLinkGrant,
|
|
35
35
|
updateAuthenticator,
|
|
36
36
|
writeMagicLinkGrant
|
|
37
|
-
} from "../chunk-
|
|
38
|
-
import "../chunk-
|
|
37
|
+
} from "../chunk-5AVIUJP4.js";
|
|
38
|
+
import "../chunk-XMBBTETD.js";
|
|
39
39
|
import {
|
|
40
40
|
buildEchoBlock,
|
|
41
41
|
buildRecipientKeyringFile,
|
|
@@ -56,20 +56,18 @@ import {
|
|
|
56
56
|
updateKeyringIdentity,
|
|
57
57
|
verifyPrompt,
|
|
58
58
|
verifyTypedEcho
|
|
59
|
-
} from "../chunk-
|
|
60
|
-
import "../chunk-
|
|
61
|
-
import "../chunk-
|
|
62
|
-
import "../chunk-
|
|
63
|
-
import "../chunk-
|
|
64
|
-
import "../chunk-
|
|
65
|
-
import "../chunk-
|
|
66
|
-
import "../chunk-
|
|
67
|
-
import "../chunk-
|
|
68
|
-
import "../chunk-6Y3UJT5H.js";
|
|
69
|
-
import "../chunk-VUBRHJ4H.js";
|
|
59
|
+
} from "../chunk-UXH4AKH3.js";
|
|
60
|
+
import "../chunk-ZQQLOEWN.js";
|
|
61
|
+
import "../chunk-KHSBMLQE.js";
|
|
62
|
+
import "../chunk-VKZ3TDET.js";
|
|
63
|
+
import "../chunk-F2FD4LSB.js";
|
|
64
|
+
import "../chunk-EFINFZIF.js";
|
|
65
|
+
import "../chunk-I4S7IZSS.js";
|
|
66
|
+
import "../chunk-XWWDZKLS.js";
|
|
67
|
+
import "../chunk-CR5UPYIJ.js";
|
|
70
68
|
import {
|
|
71
69
|
TeamNotEnabledError
|
|
72
|
-
} from "../chunk-
|
|
70
|
+
} from "../chunk-ISIXU45J.js";
|
|
73
71
|
export {
|
|
74
72
|
MemoryDeviceSeal,
|
|
75
73
|
NO_TEAM,
|
package/dist/tiers/index.js
CHANGED
|
@@ -12,19 +12,16 @@ import {
|
|
|
12
12
|
putAtTier,
|
|
13
13
|
syncDerivedOutputs,
|
|
14
14
|
withTiers
|
|
15
|
-
} from "../chunk-
|
|
16
|
-
import "../chunk-
|
|
17
|
-
import "../chunk-
|
|
18
|
-
import "../chunk-
|
|
19
|
-
import "../chunk-
|
|
20
|
-
import "../chunk-
|
|
21
|
-
import "../chunk-
|
|
22
|
-
import "../chunk-YIVAKBCW.js";
|
|
23
|
-
import "../chunk-6Y3UJT5H.js";
|
|
24
|
-
import "../chunk-VUBRHJ4H.js";
|
|
15
|
+
} from "../chunk-PR36DD2X.js";
|
|
16
|
+
import "../chunk-VKZ3TDET.js";
|
|
17
|
+
import "../chunk-F2FD4LSB.js";
|
|
18
|
+
import "../chunk-EFINFZIF.js";
|
|
19
|
+
import "../chunk-I4S7IZSS.js";
|
|
20
|
+
import "../chunk-XWWDZKLS.js";
|
|
21
|
+
import "../chunk-CR5UPYIJ.js";
|
|
25
22
|
import {
|
|
26
23
|
TiersNotEnabledError
|
|
27
|
-
} from "../chunk-
|
|
24
|
+
} from "../chunk-ISIXU45J.js";
|
|
28
25
|
export {
|
|
29
26
|
NO_TIERS,
|
|
30
27
|
TiersNotEnabledError,
|
package/dist/to/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
NOYDB_ENVELOPE_GENERATION
|
|
3
|
-
} from "../chunk-
|
|
3
|
+
} from "../chunk-CR5UPYIJ.js";
|
|
4
4
|
import {
|
|
5
5
|
ConflictError,
|
|
6
6
|
DuplicateStoreKindError,
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
StoreCapabilityError,
|
|
10
10
|
UnknownStoreKindError,
|
|
11
11
|
isConflictError
|
|
12
|
-
} from "../chunk-
|
|
12
|
+
} from "../chunk-ISIXU45J.js";
|
|
13
13
|
|
|
14
14
|
// src/port/to/locator.ts
|
|
15
15
|
function isPodStore(store) {
|
|
@@ -3,15 +3,15 @@ import {
|
|
|
3
3
|
TxContext,
|
|
4
4
|
TxVault,
|
|
5
5
|
runTransaction
|
|
6
|
-
} from "../chunk-
|
|
6
|
+
} from "../chunk-56Z4NOC6.js";
|
|
7
7
|
import {
|
|
8
8
|
lazy
|
|
9
9
|
} from "../chunk-5D2ALSM5.js";
|
|
10
10
|
import "../chunk-4AOERLTV.js";
|
|
11
|
-
import "../chunk-
|
|
11
|
+
import "../chunk-ISIXU45J.js";
|
|
12
12
|
|
|
13
13
|
// src/with-commit/tx/dry-run.ts
|
|
14
|
-
var loadGuardExecutor = lazy(() => import("../executor-
|
|
14
|
+
var loadGuardExecutor = lazy(() => import("../executor-BJZJNVBB.js"));
|
|
15
15
|
var SEP = " ";
|
|
16
16
|
var keyOf = (op) => `${op.vaultName}${SEP}${op.collectionName}${SEP}${op.id}`;
|
|
17
17
|
async function runDryRun(db, fn) {
|
package/dist/util/index.js
CHANGED
package/dist/vault-head/index.js
CHANGED
|
@@ -8,14 +8,11 @@ import {
|
|
|
8
8
|
buildRecordEnvelope,
|
|
9
9
|
encrypt,
|
|
10
10
|
openEnvelopeJson
|
|
11
|
-
} from "../chunk-
|
|
12
|
-
import "../chunk-
|
|
13
|
-
import "../chunk-
|
|
14
|
-
import "../chunk-
|
|
15
|
-
import "../chunk-
|
|
16
|
-
import "../chunk-6Y3UJT5H.js";
|
|
17
|
-
import "../chunk-VUBRHJ4H.js";
|
|
18
|
-
import "../chunk-JGYCKX56.js";
|
|
11
|
+
} from "../chunk-EFINFZIF.js";
|
|
12
|
+
import "../chunk-I4S7IZSS.js";
|
|
13
|
+
import "../chunk-XWWDZKLS.js";
|
|
14
|
+
import "../chunk-CR5UPYIJ.js";
|
|
15
|
+
import "../chunk-ISIXU45J.js";
|
|
19
16
|
|
|
20
17
|
// src/with-commit/vault-head/head.ts
|
|
21
18
|
function bucketIndex(collection, id, buckets) {
|
|
@@ -1 +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 '../../capsule/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 '../../capsule/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 '../../capsule/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":"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","names":[]}
|
|
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 '../../capsule/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 '../../capsule/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 '../../capsule/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":"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","names":[]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import {
|
|
2
|
+
dumpVaultSchema
|
|
3
|
+
} from "./chunk-HDAPQF6Q.js";
|
|
4
|
+
import "./chunk-RXLYKVTF.js";
|
|
5
|
+
import "./chunk-VYYM3MEN.js";
|
|
6
|
+
import "./chunk-FY4FFNKK.js";
|
|
7
|
+
import "./chunk-Y2NBBT6K.js";
|
|
8
|
+
import "./chunk-PBRD75JF.js";
|
|
9
|
+
import "./chunk-EFINFZIF.js";
|
|
10
|
+
import "./chunk-I4S7IZSS.js";
|
|
11
|
+
import "./chunk-XWWDZKLS.js";
|
|
12
|
+
import "./chunk-CR5UPYIJ.js";
|
|
13
|
+
import "./chunk-ISIXU45J.js";
|
|
14
|
+
export {
|
|
15
|
+
dumpVaultSchema
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=walk-Z4N7PCZ2.js.map
|
|
@@ -41,6 +41,8 @@ export interface ExportAccessibleOptions {
|
|
|
41
41
|
}
|
|
42
42
|
/**
|
|
43
43
|
* Produce a re-keyed, access-scoped `.noydb` bundle of the caller's accessible
|
|
44
|
-
* data. Appends a tamper-evident audit entry (`reason: 'user-export:<userId>'`)
|
|
44
|
+
* data. Appends a tamper-evident audit entry (`reason: 'user-export:<userId>'`)
|
|
45
|
+
* BEFORE building, so a build that fails part-way still records the access it
|
|
46
|
+
* already made (family#175).
|
|
45
47
|
*/
|
|
46
48
|
export declare function exportAccessibleData(vault: Vault, opts?: ExportAccessibleOptions): Promise<Uint8Array>;
|
|
@@ -88,7 +88,16 @@ export interface VaultDiff<T = unknown> {
|
|
|
88
88
|
readonly modify: number;
|
|
89
89
|
readonly delete: number;
|
|
90
90
|
readonly total: number;
|
|
91
|
+
/** family#151 — `skipped.length`, so a caller reading only the summary sees it. */
|
|
92
|
+
readonly skipped: number;
|
|
91
93
|
};
|
|
94
|
+
/**
|
|
95
|
+
* Records this diff could not key, and therefore says nothing about
|
|
96
|
+
* (family#151). Empty for a vault-to-vault diff. ⚠️ A non-empty value means
|
|
97
|
+
* the diff is INCOMPLETE — an importer walking only the buckets will not
|
|
98
|
+
* write these rows, which used to happen silently.
|
|
99
|
+
*/
|
|
100
|
+
readonly skipped: readonly VaultDiffSkipped[];
|
|
92
101
|
/**
|
|
93
102
|
* Format the diff as a human-readable string.
|
|
94
103
|
*
|
|
@@ -127,6 +136,25 @@ export interface DiffOptions {
|
|
|
127
136
|
* - A `VaultDump` (output of `vault.dump()`) — a JSON string carrying the
|
|
128
137
|
* full vault state. Parsed and reduced to the map shape above.
|
|
129
138
|
*/
|
|
139
|
+
/**
|
|
140
|
+
* A record neither side could key, and therefore one this diff does NOT report
|
|
141
|
+
* on (family#151).
|
|
142
|
+
*
|
|
143
|
+
* ⛔ IT EXISTS BECAUSE THE SKIP WAS SILENT. A record with no `idKey` field was
|
|
144
|
+
* dropped from the map on both sides, so it appeared in no bucket — and
|
|
145
|
+
* `@noy-db/hub/as`'s `plan().apply()` walks only `added`/`modified`/`deleted`.
|
|
146
|
+
* An import therefore did not write it, with no error and no count. A diff that
|
|
147
|
+
* omits a record is reporting a difference it did not find.
|
|
148
|
+
*
|
|
149
|
+
* ⚠️ Only reachable on the object/string candidate path. A vault-to-vault diff
|
|
150
|
+
* keys both sides by the hub id, which every record has.
|
|
151
|
+
*/
|
|
152
|
+
export interface VaultDiffSkipped {
|
|
153
|
+
readonly collection: string;
|
|
154
|
+
readonly side: 'vault' | 'candidate';
|
|
155
|
+
/** Position within that side's record list for the collection. */
|
|
156
|
+
readonly index: number;
|
|
157
|
+
}
|
|
130
158
|
export type DiffCandidate<T = unknown> = Vault | Record<string, readonly T[]> | string;
|
|
131
159
|
/**
|
|
132
160
|
* Compute the diff between a live vault and a candidate state.
|
|
@@ -23,6 +23,28 @@ import { type EnclaveKey } from '../../capsule/index.js';
|
|
|
23
23
|
export { withSequence } from './active.js';
|
|
24
24
|
export { NO_SEQUENCE, type SequenceStrategy } from './strategy.js';
|
|
25
25
|
export { SequenceNotEnabledError } from '../../kernel/errors.js';
|
|
26
|
+
/**
|
|
27
|
+
* ⛔ **COUNTERS NEVER SYNC — A SEQUENCE IS UNIQUE PER DEVICE, NOT ACROSS A
|
|
28
|
+
* FLEET (family#206).** `_sequences` is absent from `RESERVED_REPLICATION`
|
|
29
|
+
* (`with-sync/reserved-mirror.ts:108`, whose replicated set is `_keyring`,
|
|
30
|
+
* `_broker_member`, `_broker`, `_meta`, `_users`, `_delegations`,
|
|
31
|
+
* `_rejections`), and `next()` CASes the counter record against the LOCAL
|
|
32
|
+
* store. So two devices issuing from the same sequence name produce the SAME
|
|
33
|
+
* numbers, and `next()`'s "no duplicates under concurrency" guarantee holds
|
|
34
|
+
* within one device only.
|
|
35
|
+
*
|
|
36
|
+
* ⚠️ The CAS is doing real work and it is not the gap here — it serializes
|
|
37
|
+
* concurrent writers against ONE store. What is missing is replication of the
|
|
38
|
+
* counter itself, which is why the failure is invisible to any single-device
|
|
39
|
+
* test and to every in-tree simulation that shares a store.
|
|
40
|
+
*
|
|
41
|
+
* ⛔ Do not use this for an invoice number that must be unique across devices
|
|
42
|
+
* until family#206 lands — it is the first item of the next cycle.
|
|
43
|
+
*
|
|
44
|
+
* ⭐ Measured: with sync on both devices, A `next()` → 1, A pushes, B pulls the
|
|
45
|
+
* whole vault, B `next()` → 1. Two records numbered 1 after a COMPLETE sync
|
|
46
|
+
* cycle — the pull cannot help, because there is nothing replicating to pull.
|
|
47
|
+
*/
|
|
26
48
|
export declare const SEQUENCE_COLLECTION = "_sequences";
|
|
27
49
|
/** Options for `SequenceHandle.next`. Deferred-numbering series use `for`; the CAS counter ignores all of these. */
|
|
28
50
|
export interface NextOptions {
|
|
@@ -147,6 +147,56 @@ export declare function loadKeyring(store: NoydbStore, vault: string, opts: Load
|
|
|
147
147
|
* otherwise. Placed before managed-secret secret resolution (which persists
|
|
148
148
|
* on first open), so a fail-closed open writes nothing.
|
|
149
149
|
*/
|
|
150
|
+
/**
|
|
151
|
+
* ⚠️ family#162 — THIS GATE'S FAIL-CLOSED PROPERTY RESTS ON THE STORE
|
|
152
|
+
* CONTRACT. It decides "genuinely-new vault" from `list()` returning empty, so
|
|
153
|
+
* a store that answers a read FAILURE with `[]` turns the refusal below into a
|
|
154
|
+
* pass: hub then self-provisions a second owner into a vault that already has
|
|
155
|
+
* one. `NoydbStore`'s docstring states the rule (absence and failure are
|
|
156
|
+
* different answers); `to-file` violated it in `get`, `list` and `loadAll`.
|
|
157
|
+
*
|
|
158
|
+
* ⛔ Hub cannot verify it. A `[]` is a `[]` — there is no second question to
|
|
159
|
+
* ask that a store answering wrongly would answer differently. So the guard is
|
|
160
|
+
* the contract plus each store honouring it, and what hub owes is to NOT
|
|
161
|
+
* swallow a store that does throw. `__tests__/162-...` asserts that.
|
|
162
|
+
*/
|
|
163
|
+
/**
|
|
164
|
+
* Refuse to attach a sync peer whose keyring for this user is a DIFFERENT file
|
|
165
|
+
* from the local one (family#178).
|
|
166
|
+
*
|
|
167
|
+
* ⛔ WHAT IT CATCHES, measured on two devices. A second device that attaches its
|
|
168
|
+
* peer with `attachSyncTarget` rather than the construction-time `sync` option
|
|
169
|
+
* finds no `_keyring` at open, self-provisions a brand-new owner keyring, and
|
|
170
|
+
* then diverges permanently: each device reads only its own records, under two
|
|
171
|
+
* different keyrings, with NO error anywhere. Device 1 cannot read device 2's
|
|
172
|
+
* data and device 2 cannot read device 1's.
|
|
173
|
+
*
|
|
174
|
+
* ⭐ THE TRIGGER IS A LOCAL WRITE BEFORE THE ATTACH. With no local write the
|
|
175
|
+
* reserved-keyring mirror adopts the peer's keyring on the first pull and
|
|
176
|
+
* everything works — so a two-device test WITHOUT the write passes and proves
|
|
177
|
+
* nothing. Once the device has written under its self-provisioned keyring the
|
|
178
|
+
* mirror will not supersede it, and the divergence sticks.
|
|
179
|
+
*
|
|
180
|
+
* ⛔ WHY THE CHECK IS HERE AND NOT AT FIRST KEYRING ACCESS. It cannot be there:
|
|
181
|
+
* `Noydb.vault()` throws unless the vault is already open, so `attachSyncTarget`
|
|
182
|
+
* necessarily runs AFTER `openVault` — and `openVault` is where the
|
|
183
|
+
* self-provision happens. At that moment no peer is attached and none can be
|
|
184
|
+
* consulted. "Bootstrap from any attached peer at first keyring access" is empty
|
|
185
|
+
* on a first open, and "refuse while an attached peer has not been checked"
|
|
186
|
+
* would refuse every first open.
|
|
187
|
+
*
|
|
188
|
+
* ⚠️ IT REFUSES RATHER THAN REPAIRS, deliberately. Adopting the peer's keyring
|
|
189
|
+
* would discard the local one, and every record this device already wrote is
|
|
190
|
+
* sealed under the discarded DEKs — so a "repair" trades a visible divergence
|
|
191
|
+
* for silent data loss. Refusing leaves both copies intact and tells the caller
|
|
192
|
+
* the two supported paths.
|
|
193
|
+
*
|
|
194
|
+
* ⚠️ The invariant it rests on was verified, not assumed: a legitimate pair ends
|
|
195
|
+
* with BYTE-IDENTICAL `_keyring/<user>` on both stores (measured for the
|
|
196
|
+
* construction-time form), because the keyring is per-user and mirrored. Two
|
|
197
|
+
* different files for one userId cannot both be right.
|
|
198
|
+
*/
|
|
199
|
+
export declare function assertPeerKeyringMatches(local: NoydbStore, peer: NoydbStore, vault: string, userId: string): Promise<void>;
|
|
150
200
|
export declare function assertKeyringOpenAllowed(store: NoydbStore, vault: string, userId: string, create: boolean): Promise<void>;
|
|
151
201
|
/**
|
|
152
202
|
* Options for {@link createOwnerKeyring} (#846b). The `SecretPolicy` knobs are
|
|
@@ -193,6 +243,33 @@ export interface CreateOwnerKeyringOptions extends SecretPolicy {
|
|
|
193
243
|
* `NoydbOptions.validateSecret`. Direct callers (CLI, scripts,
|
|
194
244
|
* test fixtures) opt in explicitly.
|
|
195
245
|
*/
|
|
246
|
+
/**
|
|
247
|
+
* Create the owner keyring, yielding to whoever won a concurrent create
|
|
248
|
+
* (family#164).
|
|
249
|
+
*
|
|
250
|
+
* ⛔ TWO CONCURRENT FIRST OPENS LEFT ONE CALLER WITH A RAW `ConflictError`.
|
|
251
|
+
* {@link writeKeyringFile} CASes a create at `expectedVersion: 0` (core#134),
|
|
252
|
+
* so the second create is correctly REFUSED — but nothing caught the refusal,
|
|
253
|
+
* and `Version conflict: expected 0, found 1` reached the caller out of
|
|
254
|
+
* `openVault`. A caller who does not retry reads that as a vault it cannot
|
|
255
|
+
* open; a caller who does retry succeeds, which is what made this a latent race
|
|
256
|
+
* rather than a visible one.
|
|
257
|
+
*
|
|
258
|
+
* ⭐ The loser is a READER, not a failure. A keyring now exists for this
|
|
259
|
+
* principal, written from the same secret, so loading it is both correct and
|
|
260
|
+
* what the caller asked for. Retried ONCE: a second conflict would mean a third
|
|
261
|
+
* writer, and looping against a shared store is how a race becomes a hang.
|
|
262
|
+
*
|
|
263
|
+
* ⚠️ RESIDUAL, measured rather than assumed. On a store whose
|
|
264
|
+
* `capabilities.casAtomic` is false the CAS is advisory, so two creates could in
|
|
265
|
+
* principle both land and the second clobber the first — which WOULD be
|
|
266
|
+
* permanent unopenability, because the first session's collection DEKs are
|
|
267
|
+
* wrapped under a KEK nobody holds. I could not reproduce it: the
|
|
268
|
+
* 600K-iteration KEK derivation dominates any store's read-then-write window by
|
|
269
|
+
* orders of magnitude, so the two writes serialise in practice. Recorded
|
|
270
|
+
* because "could not reproduce" is not "cannot happen".
|
|
271
|
+
*/
|
|
272
|
+
export declare function createOwnerKeyringOrLoad(store: NoydbStore, vault: string, options: CreateOwnerKeyringOptions): Promise<UnlockedKeyring>;
|
|
196
273
|
export declare function createOwnerKeyring(store: NoydbStore, vault: string, opts: CreateOwnerKeyringOptions): Promise<UnlockedKeyring>;
|
|
197
274
|
/** Grant access to a new user. Caller must have grant privilege. */
|
|
198
275
|
export declare function grant(store: NoydbStore, vault: string, callerKeyring: UnlockedKeyring, options: GrantOptions): Promise<void>;
|
|
@@ -78,14 +78,51 @@ export interface NoydbSealer {
|
|
|
78
78
|
* parses this; it's purely audit metadata.
|
|
79
79
|
*/
|
|
80
80
|
readonly id: string;
|
|
81
|
-
/**
|
|
82
|
-
|
|
81
|
+
/**
|
|
82
|
+
* Seal raw secret bytes. Output bytes are opaque to hub.
|
|
83
|
+
*
|
|
84
|
+
* `ctx` is ADDITIVE and OPTIONAL (family#157): hub passes it where the bytes
|
|
85
|
+
* belong to one vault, so a provider can scope its key material — a KMS
|
|
86
|
+
* encryption context, a per-vault keychain account, a key-id suffix. An
|
|
87
|
+
* existing provider that ignores the second argument keeps working unchanged.
|
|
88
|
+
*
|
|
89
|
+
* ⛔ A provider MUST stay functional when `ctx` is ABSENT, and must not treat
|
|
90
|
+
* absence as an error. Hub omits it deliberately where sealed bytes have to
|
|
91
|
+
* TRAVEL — see {@link SealContext}.
|
|
92
|
+
*/
|
|
93
|
+
seal(secret: Uint8Array, ctx?: SealContext): Promise<Uint8Array>;
|
|
83
94
|
/**
|
|
84
95
|
* Reverse {@link seal}. MUST throw on tamper, wrong-provider, or
|
|
85
96
|
* any other failure — hub treats a thrown error as "this provider
|
|
86
97
|
* cannot unlock this vault" and surfaces it to the caller.
|
|
98
|
+
*
|
|
99
|
+
* ⚠️ Hub passes the SAME `ctx` it sealed under at every paired call site, so a
|
|
100
|
+
* provider that binds key material to `ctx.vault` can unseal its own output.
|
|
101
|
+
* It is not passed where it was not available at seal time.
|
|
87
102
|
*/
|
|
88
|
-
unseal(sealed: Uint8Array): Promise<Uint8Array>;
|
|
103
|
+
unseal(sealed: Uint8Array, ctx?: SealContext): Promise<Uint8Array>;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* What hub knows about the bytes it is asking a {@link NoydbSealer} to seal
|
|
107
|
+
* (family#157). Deliberately one field — anything a provider needs beyond the
|
|
108
|
+
* vault name belongs in its own construction, not in a per-call argument.
|
|
109
|
+
*
|
|
110
|
+
* ⛔ **Hub does NOT pass this on every call, and the exception is load-bearing.**
|
|
111
|
+
* A pod's auto-unlock credentials (`with-pod/pod.ts`) are sealed WITHOUT a
|
|
112
|
+
* context, because a pod is a PORTABLE bundle: `ReadPodOptions` carries no
|
|
113
|
+
* vault, and the pod may be read into a differently-named vault or merely
|
|
114
|
+
* inspected with no vault at all. A provider that bound those bytes to a vault
|
|
115
|
+
* name would produce a credential only the originating vault could open, which
|
|
116
|
+
* defeats the entire point of the format.
|
|
117
|
+
*
|
|
118
|
+
* ⭐ So the rule for a provider author is the asymmetry itself: `ctx` present
|
|
119
|
+
* means "these bytes stay in this vault" and `ctx` absent means "these bytes
|
|
120
|
+
* are meant to travel". Scoping to `ctx.vault` when it IS given is safe for
|
|
121
|
+
* exactly that reason.
|
|
122
|
+
*/
|
|
123
|
+
export interface SealContext {
|
|
124
|
+
/** The vault whose secret is being sealed or unsealed. */
|
|
125
|
+
readonly vault: string;
|
|
89
126
|
}
|
|
90
127
|
/**
|
|
91
128
|
* In-memory test provider. NOT secure — uses a deterministic
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
* @module
|
|
22
22
|
*/
|
|
23
23
|
import { type EnclaveKey } from '../../capsule/index.js';
|
|
24
|
-
import type { NoydbStore } from '../../kernel/types.js';
|
|
24
|
+
import type { NoydbStore, EncryptedEnvelope } from '../../kernel/types.js';
|
|
25
25
|
import { type SchemaManifest, type SchemaManifestEntry } from './types.js';
|
|
26
26
|
/** A resolver for a collection's DEK — the same shape as `Vault`'s internal `getDEK`. */
|
|
27
27
|
export type GetManifestDEK = (collectionName: string) => Promise<EnclaveKey>;
|
|
@@ -51,7 +51,7 @@ export declare function loadSchemaManifestEntry(store: NoydbStore, vault: string
|
|
|
51
51
|
* `writer.ts`'s `writeSchemaManifest` as `ManifestConflictError` rather than
|
|
52
52
|
* retried.
|
|
53
53
|
*/
|
|
54
|
-
export declare function saveSchemaManifest(store: NoydbStore, vault: string, manifest: SchemaManifest, expectedVersion: number, getDEK: GetManifestDEK): Promise<
|
|
54
|
+
export declare function saveSchemaManifest(store: NoydbStore, vault: string, manifest: SchemaManifest, expectedVersion: number, getDEK: GetManifestDEK): Promise<EncryptedEnvelope>;
|
|
55
55
|
/**
|
|
56
56
|
* `sha256Hex(canonicalJson(collections))` — the pod-wide content binding
|
|
57
57
|
* over a schema manifest's per-collection index. Canonical JSON sorts
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
* @module
|
|
22
22
|
*/
|
|
23
23
|
import { type GetManifestDEK } from './storage.js';
|
|
24
|
-
import type { NoydbStore } from '../../kernel/types.js';
|
|
24
|
+
import type { NoydbStore, EncryptedEnvelope } from '../../kernel/types.js';
|
|
25
25
|
import type { SchemaManifest } from './types.js';
|
|
26
26
|
/**
|
|
27
27
|
* Write the schema manifest as a strict CAS: `expectedVersion` must match
|
|
@@ -29,4 +29,4 @@ import type { SchemaManifest } from './types.js';
|
|
|
29
29
|
* conflict, throws {@link ManifestConflictError} — this function never
|
|
30
30
|
* retries.
|
|
31
31
|
*/
|
|
32
|
-
export declare function writeSchemaManifest(store: NoydbStore, vault: string, manifest: SchemaManifest, expectedVersion: number, getDEK: GetManifestDEK): Promise<
|
|
32
|
+
export declare function writeSchemaManifest(store: NoydbStore, vault: string, manifest: SchemaManifest, expectedVersion: number, getDEK: GetManifestDEK): Promise<EncryptedEnvelope>;
|
|
@@ -24,15 +24,28 @@ import type { NoydbStore } from '../kernel/types.js';
|
|
|
24
24
|
* compose left-to-right via `wrapStore()`: the first argument is outermost
|
|
25
25
|
* (first to intercept requests, last to process responses).
|
|
26
26
|
*
|
|
27
|
+
* ⛔ **Do not write `{ ...next, get() {…} }`** — this example used to, and it
|
|
28
|
+
* taught the defect family#173 fixed. A spread copies own enumerable properties
|
|
29
|
+
* only, so a store implemented as a class loses every prototype method the
|
|
30
|
+
* middleware does not redeclare (`listPage`, `tx`, `getStoreTime`, …) and hub
|
|
31
|
+
* silently takes its fallback paths. Build the wrapper over `next` instead:
|
|
32
|
+
*
|
|
27
33
|
* ```ts
|
|
28
|
-
* const mw: StoreMiddleware = (next) =>
|
|
29
|
-
*
|
|
30
|
-
* async get(vault, collection, id) {
|
|
34
|
+
* const mw: StoreMiddleware = (next) => {
|
|
35
|
+
* const log = async (vault: string, collection: string, id: string) => {
|
|
31
36
|
* console.log('get', id)
|
|
32
37
|
* return next.get(vault, collection, id)
|
|
33
|
-
* }
|
|
34
|
-
*
|
|
38
|
+
* }
|
|
39
|
+
* return new Proxy(next, {
|
|
40
|
+
* get: (t, p) => (p === 'get' ? log : Reflect.get(t, p, t)),
|
|
41
|
+
* })
|
|
42
|
+
* }
|
|
35
43
|
* ```
|
|
44
|
+
*
|
|
45
|
+
* ⚠️ The snippet above is the shape, simplified: the real `overlay()` in this
|
|
46
|
+
* module also binds forwarded methods to the wrapped store (so a class store's
|
|
47
|
+
* `#private` fields keep working) and caches them (so a method reference is
|
|
48
|
+
* stable). A middleware doing this by hand should do both.
|
|
36
49
|
*/
|
|
37
50
|
export type StoreMiddleware = (next: NoydbStore) => NoydbStore;
|
|
38
51
|
/**
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import {
|
|
2
|
+
freezeAndDeleteClosure,
|
|
3
|
+
freezeSnapshotOnly,
|
|
4
|
+
randomId,
|
|
5
|
+
withdrawAccessibleData
|
|
6
|
+
} from "./chunk-XROQP6IQ.js";
|
|
7
|
+
import "./chunk-23A4SBRR.js";
|
|
8
|
+
import "./chunk-2NVQ5SEA.js";
|
|
9
|
+
import "./chunk-OQA7UF2Q.js";
|
|
10
|
+
import "./chunk-GMKGGY7V.js";
|
|
11
|
+
import "./chunk-KHSBMLQE.js";
|
|
12
|
+
import "./chunk-EFINFZIF.js";
|
|
13
|
+
import "./chunk-I4S7IZSS.js";
|
|
14
|
+
import "./chunk-XWWDZKLS.js";
|
|
15
|
+
import "./chunk-CR5UPYIJ.js";
|
|
16
|
+
import "./chunk-ISIXU45J.js";
|
|
17
|
+
export {
|
|
18
|
+
freezeAndDeleteClosure,
|
|
19
|
+
freezeSnapshotOnly,
|
|
20
|
+
randomId,
|
|
21
|
+
withdrawAccessibleData
|
|
22
|
+
};
|
|
23
|
+
//# sourceMappingURL=withdraw-accessible-CRCIQSTL.js.map
|