@noy-db/hub 0.4.0 → 0.6.0-pre.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api-67SBPMMH.js +20 -0
- package/dist/attestation/index.js +18 -18
- package/dist/{backup-X7F3TCFV.js → backup-GAYWQAFN.js} +16 -11
- package/dist/backup-GAYWQAFN.js.map +1 -0
- package/dist/blobs/index.js +20 -20
- package/dist/broker/index.js +12 -12
- package/dist/bundle-handle-5OUAI7CV.js +36 -0
- package/dist/bundle-handle-5OUAI7CV.js.map +1 -0
- package/dist/cargo/index.js +36 -36
- package/dist/{chunk-DQZXPGGZ.js → chunk-24UICKTB.js} +3 -3
- package/dist/{chunk-77AEMXFA.js → chunk-24ZLWWEO.js} +1 -1
- package/dist/chunk-24ZLWWEO.js.map +1 -0
- package/dist/{chunk-2BET5QTS.js → chunk-27TCYH6G.js} +5 -5
- package/dist/{chunk-MSMJJB4J.js → chunk-2KIV7BEK.js} +2 -2
- package/dist/{chunk-6ZNSB3H6.js → chunk-2LGDCNFJ.js} +2 -2
- package/dist/{chunk-GTYFIVIZ.js → chunk-35EBKWQU.js} +5 -5
- package/dist/chunk-35EBKWQU.js.map +1 -0
- package/dist/{chunk-WBKZUO5V.js → chunk-3737A6EA.js} +3 -3
- package/dist/{chunk-ZBYFMI6D.js → chunk-3CLZY46Y.js} +638 -300
- package/dist/chunk-3CLZY46Y.js.map +1 -0
- package/dist/{chunk-HLKXPJ4V.js → chunk-3EO7RZLJ.js} +6 -6
- package/dist/{chunk-JYJFGD2H.js → chunk-3FSX6LDG.js} +2 -2
- package/dist/{chunk-MXUT7FTE.js → chunk-3HYWYLXL.js} +2 -2
- package/dist/{chunk-IVYQAVWO.js → chunk-3IIPWA75.js} +11 -11
- package/dist/{chunk-7H3WWH6J.js → chunk-3UK6STWO.js} +3 -3
- package/dist/chunk-46V67XP5.js +117 -0
- package/dist/chunk-46V67XP5.js.map +1 -0
- package/dist/{chunk-NJ4DYYO5.js → chunk-4HDYQL3J.js} +2 -2
- package/dist/{chunk-P4JO3H6R.js → chunk-4MQDV3HZ.js} +2 -2
- package/dist/{chunk-X4MVWPHV.js → chunk-4UVDI4XE.js} +3 -3
- package/dist/{chunk-LXRTP3AQ.js → chunk-4VCWI42L.js} +2 -2
- package/dist/{chunk-QJNCB5SK.js → chunk-747LRSOO.js} +2 -2
- package/dist/{chunk-3HUYRN24.js → chunk-7F4DBNSP.js} +3 -3
- package/dist/{chunk-UADPR6F4.js → chunk-7G6VDWXB.js} +3 -3
- package/dist/{chunk-PTHKZWEH.js → chunk-AHLJSVRL.js} +2 -2
- package/dist/{chunk-NFZGZ4AK.js → chunk-AR2JDFAE.js} +2 -2
- package/dist/{chunk-3ECU57YH.js → chunk-BPTZ4K5L.js} +11 -11
- package/dist/{chunk-KRCBZYTZ.js → chunk-CCZJJ4I2.js} +4 -4
- package/dist/{chunk-NYEFP7DY.js → chunk-CJ73OLMW.js} +2 -2
- package/dist/{chunk-Q36YXK77.js → chunk-CYQOUTMY.js} +3 -3
- package/dist/{chunk-RBTVFPHF.js → chunk-DCMQR46R.js} +5 -5
- package/dist/{chunk-TG634KCO.js → chunk-DG27IUVI.js} +2 -2
- package/dist/{chunk-E23UGFVC.js → chunk-DMQCLZ4Z.js} +8 -6
- package/dist/chunk-DMQCLZ4Z.js.map +1 -0
- package/dist/{chunk-ZNWSG7XC.js → chunk-DPJTDNUF.js} +68 -34
- package/dist/chunk-DPJTDNUF.js.map +1 -0
- package/dist/{chunk-V6UQZA2H.js → chunk-E6427JU2.js} +2 -2
- package/dist/{chunk-JEI6JJNI.js → chunk-EK7DT5BT.js} +220 -13
- package/dist/chunk-EK7DT5BT.js.map +1 -0
- package/dist/chunk-EPFF7LOX.js +14 -0
- package/dist/chunk-EPFF7LOX.js.map +1 -0
- package/dist/{chunk-TWPK7KUJ.js → chunk-F3GVO44K.js} +6 -6
- package/dist/{chunk-QD46HPZG.js → chunk-FAXZQ5UF.js} +2 -2
- package/dist/{chunk-IG6KUWBX.js → chunk-FNSMZQS4.js} +2 -2
- package/dist/{chunk-BLBAQRBM.js → chunk-FUHKW252.js} +2 -2
- package/dist/{chunk-SU6SGWXM.js → chunk-FY343IZR.js} +8 -8
- package/dist/{chunk-KPZS5QAQ.js → chunk-GQ3BX5EA.js} +9 -1
- package/dist/chunk-GQ3BX5EA.js.map +1 -0
- package/dist/{chunk-DAFBJS4Y.js → chunk-GS5RT2KK.js} +4 -4
- package/dist/{chunk-5UQ7Y6SQ.js → chunk-HFKGIBMD.js} +3 -3
- package/dist/{chunk-QZWTRENR.js → chunk-HNGSV2YC.js} +133 -1
- package/dist/chunk-HNGSV2YC.js.map +1 -0
- package/dist/chunk-HNHCQ556.js +63 -0
- package/dist/chunk-HNHCQ556.js.map +1 -0
- package/dist/chunk-HS7HNYBD.js +91 -0
- package/dist/chunk-HS7HNYBD.js.map +1 -0
- package/dist/{chunk-SHEEBRZ4.js → chunk-HVQGCKY4.js} +2 -2
- package/dist/{chunk-35NMVJ7I.js → chunk-HXGUIPQB.js} +3 -3
- package/dist/{chunk-ERGECZEI.js → chunk-JEM2IGS3.js} +9 -9
- package/dist/chunk-JH3OHQM4.js +260 -0
- package/dist/chunk-JH3OHQM4.js.map +1 -0
- package/dist/{chunk-L3YYLT4E.js → chunk-JIUVJ4M7.js} +2 -2
- package/dist/{chunk-55LX6FSX.js → chunk-JRCYZEHU.js} +2 -2
- package/dist/{chunk-SFBYQMZM.js → chunk-JSRU5W2M.js} +5 -5
- package/dist/{chunk-NM5UYF6Q.js → chunk-JXIDGFKS.js} +2 -2
- package/dist/{chunk-VYYM3MEN.js → chunk-KHKKD62N.js} +16 -2
- package/dist/chunk-KHKKD62N.js.map +1 -0
- package/dist/{chunk-FQ5CHJR7.js → chunk-KUDZVJKQ.js} +21 -2
- package/dist/chunk-KUDZVJKQ.js.map +1 -0
- package/dist/{chunk-RO5NM6UI.js → chunk-KZ3KMDN3.js} +2 -2
- package/dist/{chunk-HZZP2ZIG.js → chunk-LBGPO5RL.js} +6 -6
- package/dist/{chunk-ZFG5EBI3.js → chunk-LTU4FLHG.js} +57 -27
- package/dist/chunk-LTU4FLHG.js.map +1 -0
- package/dist/{chunk-CLE3TMIS.js → chunk-MC2LFTQM.js} +5 -2
- package/dist/{chunk-467SWYT5.js → chunk-MJWCLSQL.js} +17 -8
- package/dist/chunk-MJWCLSQL.js.map +1 -0
- package/dist/{chunk-W3G5REIU.js → chunk-MSWYQLMQ.js} +2 -2
- package/dist/{chunk-WK7ULBTP.js → chunk-MVOWXQHN.js} +5 -3
- package/dist/chunk-MVOWXQHN.js.map +1 -0
- package/dist/{chunk-2J6UEN2V.js → chunk-MXZ5TSTR.js} +118 -4
- package/dist/chunk-MXZ5TSTR.js.map +1 -0
- package/dist/{chunk-SGDPRCC4.js → chunk-MZ5ZFO2D.js} +3 -3
- package/dist/{chunk-NBXFCQX4.js → chunk-NQCNSVGI.js} +9 -9
- package/dist/chunk-NQCNSVGI.js.map +1 -0
- package/dist/{chunk-EFJAAFBW.js → chunk-NQRJ5AJO.js} +2 -2
- package/dist/{chunk-Q2SEJMP2.js → chunk-NVU7ZMPN.js} +2 -2
- package/dist/{chunk-ZTLOXFPB.js → chunk-OF3L2SD6.js} +2 -2
- package/dist/{chunk-LLYIMSQQ.js → chunk-OMSAULZM.js} +11 -11
- package/dist/{chunk-SF2ZIRD6.js → chunk-OSFPNKY4.js} +3 -3
- package/dist/{chunk-WUHEP3HH.js → chunk-P7NGLLUF.js} +5 -5
- package/dist/{chunk-RQ4ZI4ZI.js → chunk-PGAPBZEK.js} +7 -7
- package/dist/{chunk-T2MOJF76.js → chunk-PP5CO2PR.js} +6 -6
- package/dist/{chunk-Q5YJCVJY.js → chunk-RLWY6Z44.js} +227 -41
- package/dist/chunk-RLWY6Z44.js.map +1 -0
- package/dist/{chunk-QGIBI6GL.js → chunk-ROWL352P.js} +5 -5
- package/dist/{chunk-ZHDSUZQU.js → chunk-RPXL6KSX.js} +4 -4
- package/dist/{chunk-DTFA5DO4.js → chunk-SKONR2OL.js} +3 -3
- package/dist/{chunk-AT2JJEKJ.js → chunk-SRGJET2F.js} +16 -5
- package/dist/chunk-SRGJET2F.js.map +1 -0
- package/dist/{chunk-4ZKNC6A6.js → chunk-T4GPR2IR.js} +2 -2
- package/dist/{chunk-NLYALJMY.js → chunk-TFZ7LLOQ.js} +113 -36
- package/dist/chunk-TFZ7LLOQ.js.map +1 -0
- package/dist/{chunk-TS5XLBZR.js → chunk-TLNNHG3A.js} +4 -4
- package/dist/{chunk-6UBZ6I5Z.js → chunk-UHXCLPGC.js} +2 -2
- package/dist/{chunk-KD4HGBJV.js → chunk-V5C5NNBR.js} +4 -4
- package/dist/{chunk-WYUAEZSC.js → chunk-VBY6ZLJT.js} +15 -14
- package/dist/chunk-VBY6ZLJT.js.map +1 -0
- package/dist/{chunk-AKKRXT23.js → chunk-VCETL77O.js} +34 -16
- package/dist/chunk-VCETL77O.js.map +1 -0
- package/dist/{chunk-5GQEU4DN.js → chunk-VJFMXYKP.js} +2 -2
- package/dist/{chunk-5DRROK5W.js → chunk-VMCCGUQB.js} +2 -2
- package/dist/{chunk-IXNCZTWA.js → chunk-W3TVWF6N.js} +2 -2
- package/dist/{chunk-W66AM5IB.js → chunk-WLYIROCJ.js} +2 -2
- package/dist/{chunk-OWHP3H5C.js → chunk-XB7LUDKM.js} +4 -4
- package/dist/{chunk-KYRDJI5O.js → chunk-XBLKM73C.js} +10 -10
- package/dist/{chunk-MHMLXJ3I.js → chunk-YAWK6AWF.js} +2 -2
- package/dist/{chunk-PWPYO73B.js → chunk-ZGGVOADG.js} +5 -5
- package/dist/{chunk-YGK2HMLR.js → chunk-ZK4CO2KZ.js} +9 -9
- package/dist/chunk-ZK4CO2KZ.js.map +1 -0
- package/dist/{chunk-DSDXAKIP.js → chunk-ZVF37PKE.js} +34 -5
- package/dist/chunk-ZVF37PKE.js.map +1 -0
- package/dist/{chunk-IFOH7RBI.js → chunk-ZWMO5GL5.js} +5 -5
- package/dist/{chunk-LRRX57UA.js → chunk-ZXJXDHNK.js} +4 -4
- package/dist/classified/index.js +5 -5
- package/dist/{classified-marker-LE54HWSX.js → classified-marker-MH3ON5OL.js} +3 -3
- package/dist/collection-facade-AHT7FATG.js +45 -0
- package/dist/{computed-AB45PS4V.js → computed-6G5M3UPH.js} +3 -3
- package/dist/consent/index.js +9 -9
- package/dist/cover/index.js +3 -3
- package/dist/custody/index.js +11 -11
- package/dist/{dead-filter-V3LVWYEJ.js → dead-filter-U575NGSH.js} +2 -2
- package/dist/debug/index.js +1 -1
- package/dist/{delegation-JDUMAF6L.js → delegation-PDYL6RWT.js} +10 -10
- package/dist/derivations/index.js +12 -12
- package/dist/derive-AKT4KU36.js +22 -0
- package/dist/directory/index.js +10 -10
- package/dist/{dispatch-6TV3DGO6.js → dispatch-4XIJSFTT.js} +5 -5
- package/dist/{dispatch-W7NWQ637.js → dispatch-N5HGVUGU.js} +18 -18
- package/dist/{enclave-YFCLPIDR.js → enclave-OPK24QDR.js} +13 -9
- package/dist/executor-3JZ4POTW.js +28 -0
- package/dist/executor-CYJQLKKI.js +9 -0
- package/dist/executor-S4QIKEHW.js +9 -0
- package/dist/export-accessible-CPTP5STN.js +23 -0
- package/dist/extract-partition-TWXPHVU7.js +38 -0
- package/dist/{fanout-sidecar-273RDMYS.js → fanout-sidecar-T2ZGLQFE.js} +9 -9
- package/dist/find-RBBYKXI7.js +11 -0
- package/dist/forget/index.js +9 -9
- package/dist/guards/index.js +6 -6
- package/dist/history/index.js +15 -15
- package/dist/i18n/index.js +14 -14
- package/dist/index.d.ts +35 -7
- package/dist/index.js +279 -202
- package/dist/index.js.map +1 -1
- package/dist/indexing/index.js +3 -3
- package/dist/introspection/index.js +12 -12
- package/dist/issue-N74C55X6.js +19 -0
- package/dist/kernel/collection-config.d.ts +4 -0
- package/dist/kernel/collection.d.ts +34 -8
- package/dist/kernel/cutover-transform.d.ts +64 -0
- package/dist/kernel/enclave/crypto.d.ts +24 -0
- package/dist/kernel/enclave/index.d.ts +2 -1
- package/dist/kernel/errors.d.ts +138 -0
- package/dist/kernel/noydb.d.ts +10 -1
- package/dist/kernel/put-many-atomic.d.ts +45 -0
- package/dist/kernel/secret-mode.d.ts +59 -0
- package/dist/kernel/types.d.ts +98 -7
- package/dist/kernel/validation.d.ts +33 -0
- package/dist/kernel/vault.d.ts +32 -6
- package/dist/{ledger-XE7JF2I2.js → ledger-DONWFC5M.js} +11 -11
- package/dist/liberate-KICI7AJN.js +24 -0
- package/dist/{link-set-CGYC3OH5.js → link-set-2TTP4VLO.js} +11 -11
- package/dist/managed-secret-EAOYWRYF.js +27 -0
- package/dist/materialized-views/index.js +19 -19
- package/dist/money/index.js +3 -3
- package/dist/noydb-6W2XGQCS.js +83 -0
- package/dist/overlay-views/index.js +6 -6
- package/dist/periods/index.js +16 -16
- package/dist/pod/index.js +121 -12
- package/dist/policy/index.js +4 -4
- package/dist/port/to/index.d.ts +3 -1
- package/dist/port/to/locator.d.ts +84 -0
- package/dist/port/with/device-seal-strategy.d.ts +16 -0
- package/dist/port/with/strategies.d.ts +2 -0
- package/dist/port/with/write-hooks.d.ts +6 -0
- package/dist/portability/index.js +8 -8
- package/dist/{post-register-LY35EDTJ.js → post-register-ORQOQJCS.js} +6 -6
- package/dist/query/index.js +4 -4
- package/dist/reduce/index.js +4 -4
- package/dist/register-LHETZRJM.js +32 -0
- package/dist/registry-AMAZ6QRZ.js +19 -0
- package/dist/registry-CZVINVQH.js +9 -0
- package/dist/registry-IKUR2MXD.js +9 -0
- package/dist/registry-JRIN447B.js +18 -0
- package/dist/request-withdrawal-2DN2RGCO.js +31 -0
- package/dist/{reveal-T34ADTPY.js → reveal-AG4SCHUQ.js} +6 -6
- package/dist/revoke-ZX4NM2CJ.js +24 -0
- package/dist/satellites/index.js +1 -1
- package/dist/schema-update/index.js +6 -6
- package/dist/sealed-record/index.js +12 -12
- package/dist/search/index.js +4 -4
- package/dist/{seed-JOV54PB3.js → seed-IRCDGIRK.js} +15 -15
- package/dist/seed-IRCDGIRK.js.map +1 -0
- package/dist/sequence/index.js +9 -9
- package/dist/session/index.js +9 -9
- package/dist/shadow/index.js +2 -2
- package/dist/signer-7KHD4OL2.js +25 -0
- package/dist/snapshots/index.js +10 -10
- package/dist/{stale-T3V7XEOB.js → stale-K734VACF.js} +10 -10
- package/dist/storage-4H2GF6RQ.js +23 -0
- package/dist/{store-coordination-provider-AHGFEMFA.js → store-coordination-provider-4SKLSFUG.js} +3 -3
- package/dist/sync/index.js +10 -10
- package/dist/team/index.js +27 -15
- package/dist/tiers/index.js +10 -10
- package/dist/to/index.js +28 -3
- package/dist/to/index.js.map +1 -1
- package/dist/transactions/index.js +3 -3
- package/dist/util/index.js +1 -1
- package/dist/{verify-7XWHJWUN.js → verify-RO5RTZOJ.js} +5 -5
- package/dist/walk-MQHYNDLZ.js +21 -0
- package/dist/with-audit/guards/registry.d.ts +8 -1
- package/dist/with-audit/guards/types.d.ts +5 -0
- package/dist/with-audit/periods/index.d.ts +1 -1
- package/dist/with-audit/periods/periods.d.ts +7 -0
- package/dist/with-commit/tx/atomic-eligibility.d.ts +13 -11
- package/dist/with-formula/derivations/registry.d.ts +6 -0
- package/dist/with-formula/derivations/types.d.ts +5 -0
- package/dist/with-lookup/indexing/eager-indexes.d.ts +10 -0
- package/dist/with-party/team/device-seal.d.ts +25 -0
- package/dist/with-party/team/echo-ceremony.d.ts +74 -0
- package/dist/with-party/team/echo-secret.d.ts +56 -0
- package/dist/with-party/team/index.d.ts +8 -0
- package/dist/with-party/team/keyring.d.ts +71 -9
- package/dist/with-party/team/rotate-recover.d.ts +99 -5
- package/dist/with-pod/bundle-handle.d.ts +9 -0
- package/dist/with-pod/bundle.d.ts +100 -2
- package/dist/with-pod/format.d.ts +92 -1
- package/dist/with-pod/index.d.ts +22 -1
- package/dist/with-pod/open.d.ts +117 -0
- package/dist/with-pod/redirect.d.ts +78 -0
- package/dist/with-pod/signature.d.ts +13 -0
- package/dist/with-shape/introspection/behaviors.d.ts +100 -0
- package/dist/with-shape/introspection/derivation-key.d.ts +17 -0
- package/dist/with-shape/introspection/describe.d.ts +36 -0
- package/dist/with-shape/introspection/index.d.ts +1 -0
- package/dist/with-shape/introspection/subsystem-matrix.d.ts +22 -0
- package/dist/with-shape/introspection/types.d.ts +2 -1
- package/dist/with-shape/links/names.d.ts +14 -0
- package/dist/with-shape/manifest/derive.d.ts +86 -0
- package/dist/with-shape/manifest/reserved-collections.d.ts +27 -0
- package/dist/with-shape/manifest/storage.d.ts +62 -0
- package/dist/with-shape/manifest/sync.d.ts +135 -0
- package/dist/with-shape/manifest/types.d.ts +49 -0
- package/dist/with-shape/manifest/writer.d.ts +32 -0
- package/dist/with-shape/persisted-schemas/field-ids.d.ts +29 -0
- package/dist/with-shape/persisted-schemas/register.d.ts +3 -0
- package/dist/with-shape/persisted-schemas/types.d.ts +17 -0
- package/dist/with-shape/schema-update/fence-controller.d.ts +34 -0
- package/dist/with-shape/schema-update/fence.d.ts +9 -0
- package/dist/with-shape/schema-update/strategies.d.ts +18 -2
- package/dist/with-shape/schema-update/types.d.ts +11 -0
- package/dist/with-sync/engine.d.ts +17 -0
- package/dist/with-sync/presence.d.ts +31 -1
- package/dist/withdraw-accessible-JSDQHXHE.js +28 -0
- package/dist/withdraw-accessible-JSDQHXHE.js.map +1 -0
- package/package.json +3 -3
- package/dist/api-SI2IVBQO.js +0 -20
- package/dist/backup-X7F3TCFV.js.map +0 -1
- package/dist/chunk-2J6UEN2V.js.map +0 -1
- package/dist/chunk-467SWYT5.js.map +0 -1
- package/dist/chunk-4JQK3L4V.js +0 -41
- package/dist/chunk-4JQK3L4V.js.map +0 -1
- package/dist/chunk-77AEMXFA.js.map +0 -1
- package/dist/chunk-AKKRXT23.js.map +0 -1
- package/dist/chunk-AT2JJEKJ.js.map +0 -1
- package/dist/chunk-DSDXAKIP.js.map +0 -1
- package/dist/chunk-E23UGFVC.js.map +0 -1
- package/dist/chunk-FQ5CHJR7.js.map +0 -1
- package/dist/chunk-GTYFIVIZ.js.map +0 -1
- package/dist/chunk-JEI6JJNI.js.map +0 -1
- package/dist/chunk-JQ2AX4T5.js +0 -23
- package/dist/chunk-JQ2AX4T5.js.map +0 -1
- package/dist/chunk-KPZS5QAQ.js.map +0 -1
- package/dist/chunk-NBXFCQX4.js.map +0 -1
- package/dist/chunk-NLYALJMY.js.map +0 -1
- package/dist/chunk-Q5YJCVJY.js.map +0 -1
- package/dist/chunk-QZWTRENR.js.map +0 -1
- package/dist/chunk-S7GIXBXV.js +0 -129
- package/dist/chunk-S7GIXBXV.js.map +0 -1
- package/dist/chunk-SBHN6QUT.js +0 -25
- package/dist/chunk-SBHN6QUT.js.map +0 -1
- package/dist/chunk-VYYM3MEN.js.map +0 -1
- package/dist/chunk-WK7ULBTP.js.map +0 -1
- package/dist/chunk-WYUAEZSC.js.map +0 -1
- package/dist/chunk-YGK2HMLR.js.map +0 -1
- package/dist/chunk-ZBYFMI6D.js.map +0 -1
- package/dist/chunk-ZFG5EBI3.js.map +0 -1
- package/dist/chunk-ZNWSG7XC.js.map +0 -1
- package/dist/collection-facade-DO2AABZT.js +0 -45
- package/dist/derive-ZPGVLE2Q.js +0 -22
- package/dist/executor-FPHKWDWT.js +0 -28
- package/dist/executor-IEBLTBCW.js +0 -9
- package/dist/executor-RM7XWQDU.js +0 -9
- package/dist/export-accessible-EKM3HGB2.js +0 -23
- package/dist/extract-partition-LS4ET5A6.js +0 -38
- package/dist/find-OZMTRIK3.js +0 -11
- package/dist/issue-LIA7FXBJ.js +0 -19
- package/dist/liberate-WZ3RHVKW.js +0 -24
- package/dist/noydb-ZLPVCDES.js +0 -81
- package/dist/register-6RIBIT3I.js +0 -25
- package/dist/registry-7Y5WF7GS.js +0 -9
- package/dist/registry-BWD2ED52.js +0 -8
- package/dist/registry-MUSL4AW6.js +0 -19
- package/dist/registry-RON4WHAP.js +0 -18
- package/dist/request-withdrawal-FT3ORAWN.js +0 -31
- package/dist/revoke-HC7WG3HE.js +0 -24
- package/dist/seed-JOV54PB3.js.map +0 -1
- package/dist/signer-CTWOH6KT.js +0 -25
- package/dist/storage-LLNLPWWB.js +0 -23
- package/dist/walk-G3NFEP5L.js +0 -21
- package/dist/withdraw-accessible-ANSVG6XG.js +0 -28
- /package/dist/{api-SI2IVBQO.js.map → api-67SBPMMH.js.map} +0 -0
- /package/dist/{chunk-DQZXPGGZ.js.map → chunk-24UICKTB.js.map} +0 -0
- /package/dist/{chunk-2BET5QTS.js.map → chunk-27TCYH6G.js.map} +0 -0
- /package/dist/{chunk-MSMJJB4J.js.map → chunk-2KIV7BEK.js.map} +0 -0
- /package/dist/{chunk-6ZNSB3H6.js.map → chunk-2LGDCNFJ.js.map} +0 -0
- /package/dist/{chunk-WBKZUO5V.js.map → chunk-3737A6EA.js.map} +0 -0
- /package/dist/{chunk-HLKXPJ4V.js.map → chunk-3EO7RZLJ.js.map} +0 -0
- /package/dist/{chunk-JYJFGD2H.js.map → chunk-3FSX6LDG.js.map} +0 -0
- /package/dist/{chunk-MXUT7FTE.js.map → chunk-3HYWYLXL.js.map} +0 -0
- /package/dist/{chunk-IVYQAVWO.js.map → chunk-3IIPWA75.js.map} +0 -0
- /package/dist/{chunk-7H3WWH6J.js.map → chunk-3UK6STWO.js.map} +0 -0
- /package/dist/{chunk-NJ4DYYO5.js.map → chunk-4HDYQL3J.js.map} +0 -0
- /package/dist/{chunk-P4JO3H6R.js.map → chunk-4MQDV3HZ.js.map} +0 -0
- /package/dist/{chunk-X4MVWPHV.js.map → chunk-4UVDI4XE.js.map} +0 -0
- /package/dist/{chunk-LXRTP3AQ.js.map → chunk-4VCWI42L.js.map} +0 -0
- /package/dist/{chunk-QJNCB5SK.js.map → chunk-747LRSOO.js.map} +0 -0
- /package/dist/{chunk-3HUYRN24.js.map → chunk-7F4DBNSP.js.map} +0 -0
- /package/dist/{chunk-UADPR6F4.js.map → chunk-7G6VDWXB.js.map} +0 -0
- /package/dist/{chunk-PTHKZWEH.js.map → chunk-AHLJSVRL.js.map} +0 -0
- /package/dist/{chunk-NFZGZ4AK.js.map → chunk-AR2JDFAE.js.map} +0 -0
- /package/dist/{chunk-3ECU57YH.js.map → chunk-BPTZ4K5L.js.map} +0 -0
- /package/dist/{chunk-KRCBZYTZ.js.map → chunk-CCZJJ4I2.js.map} +0 -0
- /package/dist/{chunk-NYEFP7DY.js.map → chunk-CJ73OLMW.js.map} +0 -0
- /package/dist/{chunk-Q36YXK77.js.map → chunk-CYQOUTMY.js.map} +0 -0
- /package/dist/{chunk-RBTVFPHF.js.map → chunk-DCMQR46R.js.map} +0 -0
- /package/dist/{chunk-TG634KCO.js.map → chunk-DG27IUVI.js.map} +0 -0
- /package/dist/{chunk-V6UQZA2H.js.map → chunk-E6427JU2.js.map} +0 -0
- /package/dist/{chunk-TWPK7KUJ.js.map → chunk-F3GVO44K.js.map} +0 -0
- /package/dist/{chunk-QD46HPZG.js.map → chunk-FAXZQ5UF.js.map} +0 -0
- /package/dist/{chunk-IG6KUWBX.js.map → chunk-FNSMZQS4.js.map} +0 -0
- /package/dist/{chunk-BLBAQRBM.js.map → chunk-FUHKW252.js.map} +0 -0
- /package/dist/{chunk-SU6SGWXM.js.map → chunk-FY343IZR.js.map} +0 -0
- /package/dist/{chunk-DAFBJS4Y.js.map → chunk-GS5RT2KK.js.map} +0 -0
- /package/dist/{chunk-5UQ7Y6SQ.js.map → chunk-HFKGIBMD.js.map} +0 -0
- /package/dist/{chunk-SHEEBRZ4.js.map → chunk-HVQGCKY4.js.map} +0 -0
- /package/dist/{chunk-35NMVJ7I.js.map → chunk-HXGUIPQB.js.map} +0 -0
- /package/dist/{chunk-ERGECZEI.js.map → chunk-JEM2IGS3.js.map} +0 -0
- /package/dist/{chunk-L3YYLT4E.js.map → chunk-JIUVJ4M7.js.map} +0 -0
- /package/dist/{chunk-55LX6FSX.js.map → chunk-JRCYZEHU.js.map} +0 -0
- /package/dist/{chunk-SFBYQMZM.js.map → chunk-JSRU5W2M.js.map} +0 -0
- /package/dist/{chunk-NM5UYF6Q.js.map → chunk-JXIDGFKS.js.map} +0 -0
- /package/dist/{chunk-RO5NM6UI.js.map → chunk-KZ3KMDN3.js.map} +0 -0
- /package/dist/{chunk-HZZP2ZIG.js.map → chunk-LBGPO5RL.js.map} +0 -0
- /package/dist/{chunk-CLE3TMIS.js.map → chunk-MC2LFTQM.js.map} +0 -0
- /package/dist/{chunk-W3G5REIU.js.map → chunk-MSWYQLMQ.js.map} +0 -0
- /package/dist/{chunk-SGDPRCC4.js.map → chunk-MZ5ZFO2D.js.map} +0 -0
- /package/dist/{chunk-EFJAAFBW.js.map → chunk-NQRJ5AJO.js.map} +0 -0
- /package/dist/{chunk-Q2SEJMP2.js.map → chunk-NVU7ZMPN.js.map} +0 -0
- /package/dist/{chunk-ZTLOXFPB.js.map → chunk-OF3L2SD6.js.map} +0 -0
- /package/dist/{chunk-LLYIMSQQ.js.map → chunk-OMSAULZM.js.map} +0 -0
- /package/dist/{chunk-SF2ZIRD6.js.map → chunk-OSFPNKY4.js.map} +0 -0
- /package/dist/{chunk-WUHEP3HH.js.map → chunk-P7NGLLUF.js.map} +0 -0
- /package/dist/{chunk-RQ4ZI4ZI.js.map → chunk-PGAPBZEK.js.map} +0 -0
- /package/dist/{chunk-T2MOJF76.js.map → chunk-PP5CO2PR.js.map} +0 -0
- /package/dist/{chunk-QGIBI6GL.js.map → chunk-ROWL352P.js.map} +0 -0
- /package/dist/{chunk-ZHDSUZQU.js.map → chunk-RPXL6KSX.js.map} +0 -0
- /package/dist/{chunk-DTFA5DO4.js.map → chunk-SKONR2OL.js.map} +0 -0
- /package/dist/{chunk-4ZKNC6A6.js.map → chunk-T4GPR2IR.js.map} +0 -0
- /package/dist/{chunk-TS5XLBZR.js.map → chunk-TLNNHG3A.js.map} +0 -0
- /package/dist/{chunk-6UBZ6I5Z.js.map → chunk-UHXCLPGC.js.map} +0 -0
- /package/dist/{chunk-KD4HGBJV.js.map → chunk-V5C5NNBR.js.map} +0 -0
- /package/dist/{chunk-5GQEU4DN.js.map → chunk-VJFMXYKP.js.map} +0 -0
- /package/dist/{chunk-5DRROK5W.js.map → chunk-VMCCGUQB.js.map} +0 -0
- /package/dist/{chunk-IXNCZTWA.js.map → chunk-W3TVWF6N.js.map} +0 -0
- /package/dist/{chunk-W66AM5IB.js.map → chunk-WLYIROCJ.js.map} +0 -0
- /package/dist/{chunk-OWHP3H5C.js.map → chunk-XB7LUDKM.js.map} +0 -0
- /package/dist/{chunk-KYRDJI5O.js.map → chunk-XBLKM73C.js.map} +0 -0
- /package/dist/{chunk-MHMLXJ3I.js.map → chunk-YAWK6AWF.js.map} +0 -0
- /package/dist/{chunk-PWPYO73B.js.map → chunk-ZGGVOADG.js.map} +0 -0
- /package/dist/{chunk-IFOH7RBI.js.map → chunk-ZWMO5GL5.js.map} +0 -0
- /package/dist/{chunk-LRRX57UA.js.map → chunk-ZXJXDHNK.js.map} +0 -0
- /package/dist/{classified-marker-LE54HWSX.js.map → classified-marker-MH3ON5OL.js.map} +0 -0
- /package/dist/{collection-facade-DO2AABZT.js.map → collection-facade-AHT7FATG.js.map} +0 -0
- /package/dist/{computed-AB45PS4V.js.map → computed-6G5M3UPH.js.map} +0 -0
- /package/dist/{dead-filter-V3LVWYEJ.js.map → dead-filter-U575NGSH.js.map} +0 -0
- /package/dist/{delegation-JDUMAF6L.js.map → delegation-PDYL6RWT.js.map} +0 -0
- /package/dist/{derive-ZPGVLE2Q.js.map → derive-AKT4KU36.js.map} +0 -0
- /package/dist/{dispatch-6TV3DGO6.js.map → dispatch-4XIJSFTT.js.map} +0 -0
- /package/dist/{dispatch-W7NWQ637.js.map → dispatch-N5HGVUGU.js.map} +0 -0
- /package/dist/{enclave-YFCLPIDR.js.map → enclave-OPK24QDR.js.map} +0 -0
- /package/dist/{executor-FPHKWDWT.js.map → executor-3JZ4POTW.js.map} +0 -0
- /package/dist/{executor-IEBLTBCW.js.map → executor-CYJQLKKI.js.map} +0 -0
- /package/dist/{executor-RM7XWQDU.js.map → executor-S4QIKEHW.js.map} +0 -0
- /package/dist/{export-accessible-EKM3HGB2.js.map → export-accessible-CPTP5STN.js.map} +0 -0
- /package/dist/{extract-partition-LS4ET5A6.js.map → extract-partition-TWXPHVU7.js.map} +0 -0
- /package/dist/{fanout-sidecar-273RDMYS.js.map → fanout-sidecar-T2ZGLQFE.js.map} +0 -0
- /package/dist/{find-OZMTRIK3.js.map → find-RBBYKXI7.js.map} +0 -0
- /package/dist/{issue-LIA7FXBJ.js.map → issue-N74C55X6.js.map} +0 -0
- /package/dist/{ledger-XE7JF2I2.js.map → ledger-DONWFC5M.js.map} +0 -0
- /package/dist/{liberate-WZ3RHVKW.js.map → liberate-KICI7AJN.js.map} +0 -0
- /package/dist/{link-set-CGYC3OH5.js.map → link-set-2TTP4VLO.js.map} +0 -0
- /package/dist/{noydb-ZLPVCDES.js.map → managed-secret-EAOYWRYF.js.map} +0 -0
- /package/dist/{register-6RIBIT3I.js.map → noydb-6W2XGQCS.js.map} +0 -0
- /package/dist/{post-register-LY35EDTJ.js.map → post-register-ORQOQJCS.js.map} +0 -0
- /package/dist/{registry-7Y5WF7GS.js.map → register-LHETZRJM.js.map} +0 -0
- /package/dist/{registry-BWD2ED52.js.map → registry-AMAZ6QRZ.js.map} +0 -0
- /package/dist/{registry-MUSL4AW6.js.map → registry-CZVINVQH.js.map} +0 -0
- /package/dist/{registry-RON4WHAP.js.map → registry-IKUR2MXD.js.map} +0 -0
- /package/dist/{request-withdrawal-FT3ORAWN.js.map → registry-JRIN447B.js.map} +0 -0
- /package/dist/{revoke-HC7WG3HE.js.map → request-withdrawal-2DN2RGCO.js.map} +0 -0
- /package/dist/{reveal-T34ADTPY.js.map → reveal-AG4SCHUQ.js.map} +0 -0
- /package/dist/{signer-CTWOH6KT.js.map → revoke-ZX4NM2CJ.js.map} +0 -0
- /package/dist/{stale-T3V7XEOB.js.map → signer-7KHD4OL2.js.map} +0 -0
- /package/dist/{storage-LLNLPWWB.js.map → stale-K734VACF.js.map} +0 -0
- /package/dist/{walk-G3NFEP5L.js.map → storage-4H2GF6RQ.js.map} +0 -0
- /package/dist/{store-coordination-provider-AHGFEMFA.js.map → store-coordination-provider-4SKLSFUG.js.map} +0 -0
- /package/dist/{verify-7XWHJWUN.js.map → verify-RO5RTZOJ.js.map} +0 -0
- /package/dist/{withdraw-accessible-ANSVG6XG.js.map → walk-MQHYNDLZ.js.map} +0 -0
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Read / write the pod-wide `_manifest/schema` envelope.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors `with-shape/persisted-schemas/storage.ts`'s shape: the same
|
|
5
|
+
* standard noy-db record envelope, AES-GCM encrypted with a collection DEK
|
|
6
|
+
* (here, the `_manifest` collection's own DEK — the manifest INDEX
|
|
7
|
+
* discloses collection names + hashes + generations + field ids, metadata
|
|
8
|
+
* rather than schema bodies, so it gets the same encryption grain as
|
|
9
|
+
* `_schemas` itself).
|
|
10
|
+
*
|
|
11
|
+
* Storage layout:
|
|
12
|
+
*
|
|
13
|
+
* <vault>/_manifest/schema → EncryptedEnvelope
|
|
14
|
+
*
|
|
15
|
+
* Unlike `persisted-schemas/storage.ts` (which takes an already-resolved
|
|
16
|
+
* `EnclaveKey`), these functions take a `getDEK` resolver and call
|
|
17
|
+
* `getDEK(MANIFEST_COLLECTION)` themselves — there is exactly one manifest
|
|
18
|
+
* record per pod, so there is no per-collection DEK the caller needs to
|
|
19
|
+
* pick; resolving it here keeps every manifest call-site symmetric.
|
|
20
|
+
*
|
|
21
|
+
* @module
|
|
22
|
+
*/
|
|
23
|
+
import { type EnclaveKey } from '../../kernel/enclave/index.js';
|
|
24
|
+
import type { NoydbStore } from '../../kernel/types.js';
|
|
25
|
+
import { type SchemaManifest, type SchemaManifestEntry } from './types.js';
|
|
26
|
+
/** A resolver for a collection's DEK — the same shape as `Vault`'s internal `getDEK`. */
|
|
27
|
+
export type GetManifestDEK = (collectionName: string) => Promise<EnclaveKey>;
|
|
28
|
+
/**
|
|
29
|
+
* A decrypted schema-manifest read paired with the wrapping envelope's `_v`
|
|
30
|
+
* — the optimistic-concurrency token. Pass `version` back to
|
|
31
|
+
* {@link saveSchemaManifest} (via `writeSchemaManifest`'s `expectedVersion`)
|
|
32
|
+
* to make the write a strict CAS.
|
|
33
|
+
*/
|
|
34
|
+
export interface LoadedSchemaManifest {
|
|
35
|
+
/** Wrapping envelope `_v`. */
|
|
36
|
+
readonly version: number;
|
|
37
|
+
/** Decrypted schema manifest. */
|
|
38
|
+
readonly manifest: SchemaManifest;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Read the `_manifest/schema` envelope together with its wrapping `_v`.
|
|
42
|
+
* Returns `undefined` when no manifest has ever been written, when the
|
|
43
|
+
* envelope fails to decrypt (wrong DEK), or when it doesn't parse as a
|
|
44
|
+
* `v: 1, kind: 'schema'` manifest.
|
|
45
|
+
*/
|
|
46
|
+
export declare function loadSchemaManifestEntry(store: NoydbStore, vault: string, getDEK: GetManifestDEK): Promise<LoadedSchemaManifest | undefined>;
|
|
47
|
+
/**
|
|
48
|
+
* Encrypt and persist the schema manifest as a strict CAS write:
|
|
49
|
+
* `expectedVersion` must match the stored envelope's `_v` (0 when no
|
|
50
|
+
* envelope exists yet) or `store.put` throws `ConflictError` — surfaced by
|
|
51
|
+
* `writer.ts`'s `writeSchemaManifest` as `ManifestConflictError` rather than
|
|
52
|
+
* retried.
|
|
53
|
+
*/
|
|
54
|
+
export declare function saveSchemaManifest(store: NoydbStore, vault: string, manifest: SchemaManifest, expectedVersion: number, getDEK: GetManifestDEK): Promise<void>;
|
|
55
|
+
/**
|
|
56
|
+
* `sha256Hex(canonicalJson(collections))` — the pod-wide content binding
|
|
57
|
+
* over a schema manifest's per-collection index. Canonical JSON sorts
|
|
58
|
+
* object keys at every depth, so the result is independent of the map's
|
|
59
|
+
* key insertion order. Shared by the writer's tests and (#941 Task 3) the
|
|
60
|
+
* derivation path, so the hash is computed identically everywhere.
|
|
61
|
+
*/
|
|
62
|
+
export declare function computeAggregateHash(collections: Record<string, SchemaManifestEntry>): Promise<string>;
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Keep the persisted `_manifest/schema` record in sync with the
|
|
3
|
+
* per-collection `_schemas/<collection>` source of truth (#941 Task 3).
|
|
4
|
+
*
|
|
5
|
+
* Called from `persisted-schemas/register.ts`'s `persistSchemaIfNeeded`
|
|
6
|
+
* right after a `_schemas/<collection>` write succeeds.
|
|
7
|
+
*
|
|
8
|
+
* ## Reconciling strict-CAS-refuse with the derived nature of the manifest
|
|
9
|
+
*
|
|
10
|
+
* `writer.ts`'s `writeSchemaManifest` is deliberately strict-CAS: a
|
|
11
|
+
* concurrent *direct* edit to the manifest is refused, never retried (AC
|
|
12
|
+
* #1). But this call site is not a direct edit — it is a re-derivation
|
|
13
|
+
* from the source of truth, triggered as a side effect of a `_schemas`
|
|
14
|
+
* write that has ALREADY succeeded. When N collections are declared
|
|
15
|
+
* together (one `openVault()` call registering several `persistJsonSchema:
|
|
16
|
+
* true` collections), their `persistSchemaIfNeeded` calls run CONCURRENTLY
|
|
17
|
+
* — each one's own `_schemas/<collection>` write lands independently, and
|
|
18
|
+
* each then calls this function. A single derive-then-write with no
|
|
19
|
+
* feedback loop is NOT enough here: a call whose `deriveSchemaManifest`
|
|
20
|
+
* snapshot ran before a sibling's `_schemas` write landed would persist a
|
|
21
|
+
* manifest that's missing that sibling forever (nothing re-triggers it) —
|
|
22
|
+
* this was a REAL bug (not a test-isolation artifact — reproduced with 0
|
|
23
|
+
* shared state, purely from concurrent `_schemas` writes racing the derive
|
|
24
|
+
* snapshot; see #941 flake fix commit). `syncSchemaManifest` therefore
|
|
25
|
+
* loops (bounded by {@link MAX_SYNC_ATTEMPTS}):
|
|
26
|
+
*
|
|
27
|
+
* 1. Derive fresh, compare to what's persisted. Already converged → done.
|
|
28
|
+
* 2. Write via strict-CAS. `ManifestConflictError` (another writer moved
|
|
29
|
+
* the manifest first) → loop: re-derive against the NEW state and
|
|
30
|
+
* retry, exactly like a normal optimistic-CAS retry.
|
|
31
|
+
* 3. On a successful write, derive ONE more time. If a sibling's
|
|
32
|
+
* `_schemas` write landed while we were deriving/writing, the state
|
|
33
|
+
* has already moved past what we just wrote — loop again to catch it
|
|
34
|
+
* up. If the re-derive matches what we wrote, we're the last writer
|
|
35
|
+
* and the manifest is provably converged: return.
|
|
36
|
+
*
|
|
37
|
+
* This guarantees that whichever collection's `_schemas` write is the LAST
|
|
38
|
+
* to land (in real wall-clock order — there is always exactly one, even
|
|
39
|
+
* though no single caller knows which) ends up running a sync whose own
|
|
40
|
+
* derive sees every sibling's write already committed, and whose
|
|
41
|
+
* recheck-after-write confirms nothing moved further — so it converges the
|
|
42
|
+
* manifest deterministically, regardless of interleaving. If attempts are
|
|
43
|
+
* exhausted under pathological contention, the loop gives up — with a
|
|
44
|
+
* `console.warn` (see cap-exhaustion note below), not silently — leaving
|
|
45
|
+
* the last successful write in place; the manifest is a derivable cache
|
|
46
|
+
* (not a correctness invariant), so a next schema write or `open()`'s
|
|
47
|
+
* re-derive still converges it, matching how `persistSchemaIfNeeded`
|
|
48
|
+
* already treats its own write failures.
|
|
49
|
+
* Any error OTHER than `ManifestConflictError` (store failure, DEK
|
|
50
|
+
* resolution failure, etc.) is NOT swallowed — it propagates to the
|
|
51
|
+
* caller immediately, matching how `persistSchemaIfNeeded` already treats
|
|
52
|
+
* its own write failures as a visible (not silently discarded) fingerprint
|
|
53
|
+
* failure.
|
|
54
|
+
*
|
|
55
|
+
* ## CRITICAL fix (#941 review): a scoped principal must never write a
|
|
56
|
+
* partial manifest
|
|
57
|
+
*
|
|
58
|
+
* `deriveSchemaManifest` returns `undecodableCollections` for any
|
|
59
|
+
* `_schemas/<collection>` entry this principal's `lookupDEK` couldn't
|
|
60
|
+
* resolve — e.g. a member `grant()`-scoped to one collection can decrypt
|
|
61
|
+
* `_manifest` itself (system-prefixed DEKs propagate to every role) but
|
|
62
|
+
* NOT a sibling data collection's `_schemas/<sibling>` entry. Before this
|
|
63
|
+
* fix, `deriveSchemaManifest` silently treated "can't decrypt" the same as
|
|
64
|
+
* "no derivable content" and omitted the sibling — so a scoped member's
|
|
65
|
+
* OWN schema declare would derive a manifest missing every collection they
|
|
66
|
+
* can't see, load the real (complete) persisted manifest as a valid CAS
|
|
67
|
+
* token, observe a hash mismatch, and OVERWRITE it — permanently dropping
|
|
68
|
+
* the siblings, silently, ledger-audited as a legitimate migration. The
|
|
69
|
+
* converging recheck loop above made this WORSE, not better: re-deriving
|
|
70
|
+
* from the same restricted view just re-confirms the same partial result
|
|
71
|
+
* and declares it "stable."
|
|
72
|
+
*
|
|
73
|
+
* Fix: if `undecodableCollections` is non-empty, `syncSchemaManifest`
|
|
74
|
+
* `SKIP`s entirely — no read-compare, no write, no audit, no loop. It does
|
|
75
|
+
* NOT try to merge-preserve the undecodable entries from what's currently
|
|
76
|
+
* persisted: an `aggregateHash` computed over entries this principal can't
|
|
77
|
+
* verify would be a hash asserting something it never actually checked,
|
|
78
|
+
* which is worse than not writing at all. This is safe because:
|
|
79
|
+
*
|
|
80
|
+
* - The source of truth, `_schemas/<their-collection>`, was ALREADY
|
|
81
|
+
* updated by their declare — nothing about their own change is lost.
|
|
82
|
+
* - The pod-wide `_manifest` cache simply isn't rewritten by a principal
|
|
83
|
+
* who'd corrupt it by omission — it stays whatever a full-visibility
|
|
84
|
+
* principal (owner/admin/custodian) last wrote.
|
|
85
|
+
* - `open()` re-derives from `_schemas` directly (not from the cached
|
|
86
|
+
* manifest) for whoever opens it, so a stale cache is never load-bearing.
|
|
87
|
+
* - The NEXT full-visibility principal's declare (or any subsequent sync
|
|
88
|
+
* by someone with complete access) naturally refreshes the cache,
|
|
89
|
+
* including the scoped member's own just-landed change.
|
|
90
|
+
*
|
|
91
|
+
* ## Ledger audit (AC #5)
|
|
92
|
+
*
|
|
93
|
+
* Schema-generation transitions are not ledger-audited anywhere else today
|
|
94
|
+
* (neither the `_schemas/<collection>` write in `register.ts` nor the fence
|
|
95
|
+
* bump in `schema-update/fence-controller.ts#runCutover`). This is the
|
|
96
|
+
* first ledger-audited signal for a schema change: every manifest write
|
|
97
|
+
* that actually happens (i.e. every time the derived manifest differs from
|
|
98
|
+
* what's stored) appends an `op: 'migration'` entry via the optional
|
|
99
|
+
* `getLedgerOrNull` callback — `null`/absent when the history strategy
|
|
100
|
+
* isn't opted in, matching every other optional-ledger call site
|
|
101
|
+
* (`vault._getLedgerOrNull()?.append(...)`, see `liberate.ts`,
|
|
102
|
+
* `with-audit/periods/vault-facade.ts`). No audit fires on the no-op path
|
|
103
|
+
* (derived manifest unchanged), on a swallowed conflict (the winning
|
|
104
|
+
* writer's own sync already audits its write), or on the scoped-principal
|
|
105
|
+
* SKIP path above (nothing was written).
|
|
106
|
+
*
|
|
107
|
+
* @module
|
|
108
|
+
*/
|
|
109
|
+
import type { LedgerStore } from '../../with-commit/history/ledger/store.js';
|
|
110
|
+
import type { NoydbStore } from '../../kernel/types.js';
|
|
111
|
+
import { type LookupDEK } from './derive.js';
|
|
112
|
+
import { type GetManifestDEK } from './storage.js';
|
|
113
|
+
export interface ManifestSyncDeps {
|
|
114
|
+
/** Resolver for `_manifest`'s OWN DEK — mints if absent (this principal's declare is about to write it). */
|
|
115
|
+
readonly getDEK: GetManifestDEK;
|
|
116
|
+
/**
|
|
117
|
+
* NON-MINTING lookup for every OTHER (sibling data) collection's DEK,
|
|
118
|
+
* used by `deriveSchemaManifest` to build the index — see `derive.ts`'s
|
|
119
|
+
* `LookupDEK` doc for why minting here would be actively harmful.
|
|
120
|
+
*/
|
|
121
|
+
readonly lookupDEK: LookupDEK;
|
|
122
|
+
/** Optional ledger handle — absent when the history strategy isn't opted in (no-op audit). */
|
|
123
|
+
readonly getLedgerOrNull?: () => LedgerStore | null;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Re-derive the schema manifest and write it if it changed, looping until
|
|
127
|
+
* the write is provably stable against concurrent sibling `_schemas`
|
|
128
|
+
* writes (see module doc). SKIPS entirely (no write, no audit) when this
|
|
129
|
+
* principal's view is incomplete (`undecodableCollections` non-empty) —
|
|
130
|
+
* see the module doc's CRITICAL fix section. Swallows a
|
|
131
|
+
* {@link ManifestConflictError} by retrying against the fresher state; any
|
|
132
|
+
* other error propagates. Ledger-audits (`op: 'migration'`) once per
|
|
133
|
+
* successful write.
|
|
134
|
+
*/
|
|
135
|
+
export declare function syncSchemaManifest(store: NoydbStore, vault: string, deps: ManifestSyncDeps): Promise<void>;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The pod-wide **schema manifest** record type (#941).
|
|
3
|
+
*
|
|
4
|
+
* This is an INDEX, not a full-inline manifest: `SchemaManifest.collections`
|
|
5
|
+
* carries per-collection *metadata* (generation / content hash / field ids),
|
|
6
|
+
* never the JSON Schema body itself. The JSON Schema stays the source of
|
|
7
|
+
* truth at `_schemas/<collection>`, encrypted under that collection's own
|
|
8
|
+
* DEK (see `with-shape/persisted-schemas`). Inlining full schemas into one
|
|
9
|
+
* pod-wide manifest record would either leak every collection's schema to a
|
|
10
|
+
* principal scoped to a single collection, or force the manifest itself
|
|
11
|
+
* onto a collection-DEK it has no business holding — the index preserves
|
|
12
|
+
* per-collection DEK isolation while still giving a single place to answer
|
|
13
|
+
* "what schema generation is this pod at, and does collection X's stored
|
|
14
|
+
* schema match its declared content hash."
|
|
15
|
+
*
|
|
16
|
+
* `aggregateHash` binds the whole per-collection index's content: it is
|
|
17
|
+
* `sha256Hex(canonicalJson(collections))`, so any change to any collection's
|
|
18
|
+
* entry (a new generation, a changed hash, added/renamed field ids) changes
|
|
19
|
+
* `aggregateHash` too. Canonical JSON (sorted object keys, no whitespace)
|
|
20
|
+
* makes the hash independent of the map's key insertion order.
|
|
21
|
+
*
|
|
22
|
+
* @module
|
|
23
|
+
*/
|
|
24
|
+
/** Per-collection entry inside a {@link SchemaManifest}'s `collections` index. */
|
|
25
|
+
export interface SchemaManifestEntry {
|
|
26
|
+
/** The vault-wide schema-fence generation this collection's schema was last written at. */
|
|
27
|
+
readonly generation: number;
|
|
28
|
+
/** SHA-256 (hex) of the collection's canonicalised JSON Schema (see `persisted-schemas/derive.ts`). */
|
|
29
|
+
readonly contentHash: string;
|
|
30
|
+
/** Stable per-field ids (#946), keyed by the field's current name. Absent when the collection has none. */
|
|
31
|
+
readonly fieldIds?: Record<string, string>;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* The pod-wide schema manifest — one record per pod, stored at
|
|
35
|
+
* `_manifest/schema` (see `storage.ts`). An INDEX over the per-collection
|
|
36
|
+
* `_schemas/<collection>` entries, not the schemas themselves.
|
|
37
|
+
*/
|
|
38
|
+
export interface SchemaManifest {
|
|
39
|
+
readonly v: 1;
|
|
40
|
+
readonly kind: 'schema';
|
|
41
|
+
/** Pod-wide schema-fence generation (`FenceDoc.currentSchemaVersion`) as of this manifest's derivation. */
|
|
42
|
+
readonly generation: number;
|
|
43
|
+
/** Per-collection index: collection name → its manifest entry. */
|
|
44
|
+
readonly collections: Record<string, SchemaManifestEntry>;
|
|
45
|
+
/** `sha256Hex(canonicalJson(collections))` — the pod-wide content binding over the index. */
|
|
46
|
+
readonly aggregateHash: string;
|
|
47
|
+
}
|
|
48
|
+
/** The record id the schema manifest is stored under inside `_manifest`. */
|
|
49
|
+
export declare const MANIFEST_SCHEMA_RECORD_ID: "schema";
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Strict-CAS schema-manifest writer (#941, AC #1).
|
|
3
|
+
*
|
|
4
|
+
* Every other reserved-collection writer in the hub (`persisted-schemas`'s
|
|
5
|
+
* `savePersistedSchema` callers, the classified/satellite marker writers)
|
|
6
|
+
* retries on a CAS conflict: re-read, re-apply, try again. The schema
|
|
7
|
+
* manifest deliberately does NOT — two concurrent *direct* edits to the
|
|
8
|
+
* manifest must be refused and surfaced, never silently merged or
|
|
9
|
+
* retry-resolved, because a manifest write encodes a specific point-in-time
|
|
10
|
+
* claim about the pod's schema generation/content-hash set. A caller that
|
|
11
|
+
* lost the race must re-derive against the fresh state and decide what to
|
|
12
|
+
* do, not have its stale write quietly re-applied on top of someone else's.
|
|
13
|
+
*
|
|
14
|
+
* Ledger audit: this writer does not have a `LedgerStore` handle at this
|
|
15
|
+
* seam (mirroring `persisted-schemas`, whose `_schemas/<collection>` writes
|
|
16
|
+
* are likewise not ledger-audited today). Wiring `LedgerStore.append({ op:
|
|
17
|
+
* 'migration', ... })` around a manifest write belongs at the call site
|
|
18
|
+
* where a ledger handle is already in scope (the open/write integration —
|
|
19
|
+
* #941 Task 3/4), not here.
|
|
20
|
+
*
|
|
21
|
+
* @module
|
|
22
|
+
*/
|
|
23
|
+
import { type GetManifestDEK } from './storage.js';
|
|
24
|
+
import type { NoydbStore } from '../../kernel/types.js';
|
|
25
|
+
import type { SchemaManifest } from './types.js';
|
|
26
|
+
/**
|
|
27
|
+
* Write the schema manifest as a strict CAS: `expectedVersion` must match
|
|
28
|
+
* the stored envelope's `_v` (0 when no manifest exists yet). On a
|
|
29
|
+
* conflict, throws {@link ManifestConflictError} — this function never
|
|
30
|
+
* retries.
|
|
31
|
+
*/
|
|
32
|
+
export declare function writeSchemaManifest(store: NoydbStore, vault: string, manifest: SchemaManifest, expectedVersion: number, getDEK: GetManifestDEK): Promise<void>;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stable field-identifier minting (#946).
|
|
3
|
+
*
|
|
4
|
+
* A field's `id` is opaque and permanent — minted once, from randomness
|
|
5
|
+
* only, with no timestamp and no name-derivation. A name-derived id would
|
|
6
|
+
* change when the field is renamed, defeating the whole point (identity
|
|
7
|
+
* must survive a rename). See `PersistedSchemaEnvelope.fieldIds`.
|
|
8
|
+
*
|
|
9
|
+
* @module
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Resolve the `fieldIds` map for a freshly-derived schema against the
|
|
13
|
+
* previously-stored envelope's map (if any). Existing ids are preserved by
|
|
14
|
+
* name — a field keeps its id across re-derivation as long as its name is
|
|
15
|
+
* unchanged; a genuinely new field name mints a fresh id. Returns
|
|
16
|
+
* `undefined` when the fresh schema has no derivable top-level field set
|
|
17
|
+
* (e.g. a stub envelope, or a non-object root schema).
|
|
18
|
+
*
|
|
19
|
+
* `renamed` (#946 Task 2) — unambiguous rename pairs from
|
|
20
|
+
* `computeSchemaDelta`'s `SchemaDelta.renamed`. When the fresh name is a
|
|
21
|
+
* rename target (`to`), the id is looked up under its OLD name (`from`)
|
|
22
|
+
* instead of the fresh name itself — the whole point of a stable field id
|
|
23
|
+
* is that it survives exactly this case; without it, a rename would mint a
|
|
24
|
+
* fresh id for the new name and silently drop the old one.
|
|
25
|
+
*/
|
|
26
|
+
export declare function resolveFieldIds(freshJsonSchema: object | null, priorFieldIds: Record<string, string> | undefined, renamed?: readonly {
|
|
27
|
+
readonly from: string;
|
|
28
|
+
readonly to: string;
|
|
29
|
+
}[]): Record<string, string> | undefined;
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
*
|
|
14
14
|
* @module
|
|
15
15
|
*/
|
|
16
|
+
import { type ManifestSyncDeps } from '../manifest/sync.js';
|
|
16
17
|
import type { SchemaUpdateStrategy, UpdateDecision } from '../schema-update/types.js';
|
|
17
18
|
import type { NoydbStore, ClassifiedMarker } from '../../kernel/types.js';
|
|
18
19
|
import type { PersistedSchemaEnvelope } from './types.js';
|
|
@@ -35,6 +36,8 @@ export declare function persistSchemaIfNeeded(opts: {
|
|
|
35
36
|
readonly validator: unknown;
|
|
36
37
|
readonly dek: EnclaveKey;
|
|
37
38
|
readonly strategies?: readonly SchemaUpdateStrategy[];
|
|
39
|
+
/** #941 Task 3: re-derive + sync the `_manifest/schema` INDEX after a write. Omitted → no sync (e.g. tests that don't care). */
|
|
40
|
+
readonly manifestSync?: ManifestSyncDeps;
|
|
38
41
|
}): Promise<PersistSchemaResult>;
|
|
39
42
|
/**
|
|
40
43
|
* Persist (or refresh) the C-A / R10 classified marker into the collection's
|
|
@@ -51,4 +51,21 @@ export interface PersistedSchemaEnvelope {
|
|
|
51
51
|
* the satellite-pair analogue of {@link classified}'s config-drift guard.
|
|
52
52
|
*/
|
|
53
53
|
readonly satellite?: PairingMarker;
|
|
54
|
+
/**
|
|
55
|
+
* Stable per-field identifiers (#946), keyed by the field's current name
|
|
56
|
+
* (top-level JSON Schema `properties` key) and mapping to an opaque,
|
|
57
|
+
* permanent id minted once via `mintFieldId()`. IDs are preserved by name
|
|
58
|
+
* across re-derivation (a field keeps its id as long as its name is
|
|
59
|
+
* unchanged) so a field's identity survives a rename — the name is a
|
|
60
|
+
* label, the id is the stable key. Absent on a legacy (pre-#946) envelope
|
|
61
|
+
* and on a stub envelope with no derivable field set (`jsonSchema === null`).
|
|
62
|
+
*/
|
|
63
|
+
readonly fieldIds?: Record<string, string>;
|
|
64
|
+
/**
|
|
65
|
+
* The vault-wide schema-fence generation (`FenceDoc.currentSchemaVersion`)
|
|
66
|
+
* as of this envelope's most recent write. Together with
|
|
67
|
+
* `FenceDoc.schemaHash`, answers "generation N = which schema content
|
|
68
|
+
* hash" (#946). Absent on a legacy (pre-#946) envelope.
|
|
69
|
+
*/
|
|
70
|
+
readonly generation?: number;
|
|
54
71
|
}
|
|
@@ -17,6 +17,37 @@ import type { TransformFn } from './types.js';
|
|
|
17
17
|
import { type CoordinationProvider } from '../../port/by/index.js';
|
|
18
18
|
/** Runs one collection's transform; supplied by the Vault (binds to a Collection). */
|
|
19
19
|
export type RunTransform = (collection: string, transform: TransformFn) => Promise<void>;
|
|
20
|
+
/** Structural (no static import — kernel-spine port-layering carve-out, same rationale as
|
|
21
|
+
* `kernel/via/dispatch.ts`'s `AuditLedgerLike`) shape of the with-history `LedgerStore.append`
|
|
22
|
+
* seam {@link schemaBumpAuditHook} needs. */
|
|
23
|
+
interface AuditLedgerLike {
|
|
24
|
+
append(input: {
|
|
25
|
+
readonly op: 'lifecycle';
|
|
26
|
+
readonly collection: string;
|
|
27
|
+
readonly id: string;
|
|
28
|
+
readonly version: number;
|
|
29
|
+
readonly actor: string;
|
|
30
|
+
readonly payloadHash: string;
|
|
31
|
+
readonly reason?: string;
|
|
32
|
+
}): Promise<unknown>;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* #965 — a bare `runCutover` generation bump (no re-declare, no per-record
|
|
36
|
+
* migrations) otherwise leaves zero ledger evidence: per-record `migration`
|
|
37
|
+
* entries only fire from `applyCutoverTransform` when records + a transform
|
|
38
|
+
* exist. Mirrors `ledgerAuditHook` (`kernel/via/dispatch.ts`): encoded as a
|
|
39
|
+
* `'lifecycle'` entry (no ciphertext to hash, `payloadHash: ''`), distinct
|
|
40
|
+
* from the per-record `op: 'migration'` entries via its
|
|
41
|
+
* `reason: 'schema:generation-bump=<n>'`. Fires once per successful bump,
|
|
42
|
+
* always — even when the same cutover also produced per-record entries —
|
|
43
|
+
* so "one bump entry per generation bump" stays a simple, unconditional
|
|
44
|
+
* invariant to audit against.
|
|
45
|
+
*
|
|
46
|
+
* `getLedger` is called lazily (at bump time, not at wiring time) — same
|
|
47
|
+
* lazy-init contract as `Vault.getLedgerOrNull`; calling it eagerly during
|
|
48
|
+
* `Vault` construction (before `this.strategies` is assigned) would throw.
|
|
49
|
+
*/
|
|
50
|
+
export declare function schemaBumpAuditHook(getLedger: () => AuditLedgerLike | null, actor: string): (generation: number) => Promise<void>;
|
|
20
51
|
export declare class SchemaFenceController {
|
|
21
52
|
#private;
|
|
22
53
|
constructor(opts: {
|
|
@@ -38,6 +69,8 @@ export declare class SchemaFenceController {
|
|
|
38
69
|
currentSchemaVersion: number;
|
|
39
70
|
fenceState: FenceState;
|
|
40
71
|
}) => void;
|
|
72
|
+
/** #965 — best-effort ledger audit for a bare (no-record) generation bump. See {@link schemaBumpAuditHook}. */
|
|
73
|
+
auditBump?: ((generation: number) => Promise<void>) | undefined;
|
|
41
74
|
});
|
|
42
75
|
/** Capture the generation snapshot at vault-open. */
|
|
43
76
|
init(): Promise<void>;
|
|
@@ -60,3 +93,4 @@ export declare class SchemaFenceController {
|
|
|
60
93
|
/** Recover a stuck drain: reset fenceState to normal at the current version (no bump). */
|
|
61
94
|
abort(): Promise<void>;
|
|
62
95
|
}
|
|
96
|
+
export {};
|
|
@@ -8,6 +8,15 @@ export type FenceState = 'normal' | 'draining' | 'migrating' | 'complete';
|
|
|
8
8
|
export interface FenceDoc {
|
|
9
9
|
readonly currentSchemaVersion: number;
|
|
10
10
|
readonly fenceState: FenceState;
|
|
11
|
+
/**
|
|
12
|
+
* Content hash (`PersistedSchemaEnvelope.hash`) of the schema most
|
|
13
|
+
* recently persisted while the vault sat at `currentSchemaVersion` —
|
|
14
|
+
* binds "generation N" to a concrete schema-content hash (#946), so
|
|
15
|
+
* "which schema is generation N" is answerable from `schemaFenceState()`
|
|
16
|
+
* alone. Optional: absent on a fresh vault (generation 0, nothing
|
|
17
|
+
* persisted yet) and on a fence document written before #946.
|
|
18
|
+
*/
|
|
19
|
+
readonly schemaHash?: string;
|
|
11
20
|
}
|
|
12
21
|
export declare const FENCE_RECORD_ID = "schema-fence";
|
|
13
22
|
export declare const DEFAULT_FENCE: FenceDoc;
|
|
@@ -1,11 +1,27 @@
|
|
|
1
1
|
import type { SchemaUpdateStrategy } from './types.js';
|
|
2
2
|
/** Allow any schema change. Explicit blind / back-compat. */
|
|
3
3
|
export declare function blindUpdate(): SchemaUpdateStrategy;
|
|
4
|
-
/**
|
|
4
|
+
/**
|
|
5
|
+
* Allow additive changes; reject non-additive ones. The safety backstop.
|
|
6
|
+
*
|
|
7
|
+
* #946: a `renamed` pair is NOT additive-safe *for this gate* — the delta
|
|
8
|
+
* itself carries no data migration, so an allowed rename would orphan
|
|
9
|
+
* existing record values under the old key. `computeSchemaDelta` classifies
|
|
10
|
+
* a pure rename as `kind: 'additive'` (it IS additive-safe as far as the
|
|
11
|
+
* name-change itself is concerned, and the id-carry through `SchemaDelta.
|
|
12
|
+
* renamed` is real), but a guard whose whole job is "don't admit anything
|
|
13
|
+
* that isn't a mechanical additive write" must still block it — the same as
|
|
14
|
+
* it blocks any other non-additive change — forcing a `coordinatedCutover()`
|
|
15
|
+
* (or `blindUpdate()`) to actually move the data.
|
|
16
|
+
*/
|
|
5
17
|
export declare function additiveOnly(): SchemaUpdateStrategy;
|
|
6
18
|
/**
|
|
7
19
|
* Reject schema changes. With `fields`, reject only when one of those
|
|
8
|
-
* fields is added/removed/changed; otherwise reject any non-`none`
|
|
20
|
+
* fields is added/removed/changed/renamed; otherwise reject any non-`none`
|
|
21
|
+
* delta. #946: a `renamed` pair's `from` AND `to` both count as touching a
|
|
22
|
+
* locked field — a rename away from a locked name (or onto one) still
|
|
23
|
+
* violates the lock, and a blanket `lockSchema()` (no `fields`) already
|
|
24
|
+
* blocks any rename since a pure rename's `kind` is never `'none'`.
|
|
9
25
|
*/
|
|
10
26
|
export declare function lockSchema(opts?: {
|
|
11
27
|
readonly fields?: readonly string[];
|
|
@@ -23,6 +23,17 @@ export interface SchemaDelta {
|
|
|
23
23
|
readonly removed: readonly string[];
|
|
24
24
|
/** Top-level properties present in both but altered. */
|
|
25
25
|
readonly changed: readonly FieldChange[];
|
|
26
|
+
/**
|
|
27
|
+
* Unambiguous rename pairs detected by shape-matching a removed name
|
|
28
|
+
* against an added name (#946) — same field, new label. Present only
|
|
29
|
+
* when at least one pairing was found; the paired names are excluded
|
|
30
|
+
* from `added`/`removed` (a pure rename is additive-safe, not a
|
|
31
|
+
* drop+add). See `computeSchemaDelta`'s doc comment for the pairing rule.
|
|
32
|
+
*/
|
|
33
|
+
readonly renamed?: readonly {
|
|
34
|
+
readonly from: string;
|
|
35
|
+
readonly to: string;
|
|
36
|
+
}[];
|
|
26
37
|
}
|
|
27
38
|
/** Context handed to a strategy alongside the delta. */
|
|
28
39
|
export interface UpdateContext {
|
|
@@ -19,6 +19,10 @@ export declare class SyncEngine {
|
|
|
19
19
|
private readonly vault;
|
|
20
20
|
readonly role: SyncTargetRole;
|
|
21
21
|
readonly label: string | undefined;
|
|
22
|
+
/** #948: the resolved policy this engine was constructed with, retained for
|
|
23
|
+
* introspection (`Noydb.listSyncTargets()`) — otherwise lost once consumed
|
|
24
|
+
* into the scheduler below. */
|
|
25
|
+
readonly policy: SyncPolicy | undefined;
|
|
22
26
|
private dirty;
|
|
23
27
|
private lastPush;
|
|
24
28
|
private lastPull;
|
|
@@ -158,6 +162,19 @@ export declare class SyncEngine {
|
|
|
158
162
|
* ordinary put. `isTombstoneShape` covers a forgotten-elsewhere record arriving as a shred;
|
|
159
163
|
* `isDeleteMarker` covers an ordinary (#589) delete — both route to the SAME 'delete' action
|
|
160
164
|
* (sync delete ≠ forget: freshness only, no shred/residue channel on the receiving side). */
|
|
165
|
+
/**
|
|
166
|
+
* #936 — a local-wins resolution write must SUPERSEDE the remote, never
|
|
167
|
+
* overwrite it in place: when the winner's `_v` does not already exceed
|
|
168
|
+
* the remote's (the same-`_v` push tie), re-stamp it at `remote._v + 1`.
|
|
169
|
+
* Without this the loser's next pull sees no delta (`_v`-based
|
|
170
|
+
* detection) and the peers stay silently diverged at the same version.
|
|
171
|
+
* `_v` is envelope metadata — AEAD-unbound, and `_vdig` is deliberately
|
|
172
|
+
* `_v`-independent — so the engine may restamp ciphertext. Callers must
|
|
173
|
+
* mirror the advanced envelope locally (`applyRemote`) so both sides
|
|
174
|
+
* agree. The 'merged' branch needs none of this: resolver output is
|
|
175
|
+
* already stamped `max(local, remote) + 1`.
|
|
176
|
+
*/
|
|
177
|
+
private advancePastRemote;
|
|
161
178
|
private applyRemote;
|
|
162
179
|
/** Record + emit a tombstone enforcement (#590). */
|
|
163
180
|
private reportErasure;
|
|
@@ -26,7 +26,14 @@ export interface PresenceHandleOpts {
|
|
|
26
26
|
vault: string;
|
|
27
27
|
/** Collection name — used as HKDF `info` and channel suffix. */
|
|
28
28
|
collectionName: string;
|
|
29
|
-
/**
|
|
29
|
+
/**
|
|
30
|
+
* Calling user's ID. In encrypted mode it is encrypted inside the
|
|
31
|
+
* storage-poll record's `data` field — the record id is an
|
|
32
|
+
* adapter-opaque HMAC tag, not the userId, so the adapter never learns
|
|
33
|
+
* peer identities. Unencrypted vaults have no key to tag or encrypt
|
|
34
|
+
* with, so the userId is used as the record id in cleartext (dev posture
|
|
35
|
+
* only — identity privacy requires encryption).
|
|
36
|
+
*/
|
|
30
37
|
userId: string;
|
|
31
38
|
/** Whether encryption is active. When false, presence payloads are stored as JSON. */
|
|
32
39
|
encrypted: boolean;
|
|
@@ -51,6 +58,7 @@ export declare class PresenceHandle<P> {
|
|
|
51
58
|
private readonly channel;
|
|
52
59
|
private readonly storageCollection;
|
|
53
60
|
private presenceKey;
|
|
61
|
+
private presenceTagKey;
|
|
54
62
|
private subscribers;
|
|
55
63
|
private unsubscribePubSub;
|
|
56
64
|
private pollTimer;
|
|
@@ -71,6 +79,28 @@ export declare class PresenceHandle<P> {
|
|
|
71
79
|
/** Stop all listening and clear resources. */
|
|
72
80
|
stop(): void;
|
|
73
81
|
private getPresenceKey;
|
|
82
|
+
/**
|
|
83
|
+
* Derive (and cache) the presence-tag key — a non-extractable, sign-only
|
|
84
|
+
* HMAC-SHA256 key HKDF-derived from the collection DEK, domain-separated
|
|
85
|
+
* from the presence payload key by {@link PRESENCE_TAG_KEY_DOMAIN}.
|
|
86
|
+
* Mirrors `deriveClassifyIndexKey` (kernel/enclave/classify/bidx.ts). No
|
|
87
|
+
* PBKDF2 stretch — the adapter never holds this key, so a plain keyed HMAC
|
|
88
|
+
* tag is sufficient and deterministic. Returns `null` when unencrypted
|
|
89
|
+
* (no DEK to derive from).
|
|
90
|
+
*/
|
|
91
|
+
private getPresenceTagKey;
|
|
92
|
+
/**
|
|
93
|
+
* Deterministic, adapter-opaque tag for `userId` — used as the
|
|
94
|
+
* storage-poll record id in encrypted mode so the adapter never sees the
|
|
95
|
+
* userId. Falls back to the raw `userId` when unencrypted (no key exists
|
|
96
|
+
* to tag with — see {@link PresenceHandleOpts.userId}).
|
|
97
|
+
*
|
|
98
|
+
* Signs directly via `subtle.sign` (like `bidx.ts`'s `mintAt`) rather than
|
|
99
|
+
* the barrel's `hmacSha256Hex` helper: that helper re-exports its key
|
|
100
|
+
* argument's raw bytes internally, which only works for extractable keys
|
|
101
|
+
* (e.g. an AES-GCM DEK) — `presenceTagKey` is deliberately non-extractable.
|
|
102
|
+
*/
|
|
103
|
+
private presenceTag;
|
|
74
104
|
private getPubSubAdapter;
|
|
75
105
|
private startListening;
|
|
76
106
|
private stopListening;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import {
|
|
2
|
+
FROZEN_SNAPSHOTS_COLLECTION,
|
|
3
|
+
freezeAndDeleteClosure,
|
|
4
|
+
freezeSnapshotOnly,
|
|
5
|
+
randomId,
|
|
6
|
+
withdrawAccessibleData
|
|
7
|
+
} from "./chunk-JSRU5W2M.js";
|
|
8
|
+
import "./chunk-4MQDV3HZ.js";
|
|
9
|
+
import "./chunk-EK7DT5BT.js";
|
|
10
|
+
import "./chunk-CYQOUTMY.js";
|
|
11
|
+
import "./chunk-FY343IZR.js";
|
|
12
|
+
import "./chunk-NQRJ5AJO.js";
|
|
13
|
+
import "./chunk-HXGUIPQB.js";
|
|
14
|
+
import "./chunk-AR2JDFAE.js";
|
|
15
|
+
import "./chunk-747LRSOO.js";
|
|
16
|
+
import "./chunk-LP7BEXCT.js";
|
|
17
|
+
import "./chunk-VCETL77O.js";
|
|
18
|
+
import "./chunk-24ZLWWEO.js";
|
|
19
|
+
import "./chunk-HNGSV2YC.js";
|
|
20
|
+
import "./chunk-PZ5AY32C.js";
|
|
21
|
+
export {
|
|
22
|
+
FROZEN_SNAPSHOTS_COLLECTION,
|
|
23
|
+
freezeAndDeleteClosure,
|
|
24
|
+
freezeSnapshotOnly,
|
|
25
|
+
randomId,
|
|
26
|
+
withdrawAccessibleData
|
|
27
|
+
};
|
|
28
|
+
//# sourceMappingURL=withdraw-accessible-JSDQHXHE.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@noy-db/hub",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0-pre.0",
|
|
4
4
|
"description": "Zero-knowledge, offline-first, encrypted document store — core library with AES-256-GCM, PBKDF2, multi-user keyring, and sync engine",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "vLannaAi <vicio@lanna.ai>",
|
|
@@ -208,14 +208,14 @@
|
|
|
208
208
|
"node": ">=22.0.0"
|
|
209
209
|
},
|
|
210
210
|
"dependencies": {
|
|
211
|
-
"@noy-db/attestation": "0.
|
|
211
|
+
"@noy-db/attestation": "0.6.0-pre.0"
|
|
212
212
|
},
|
|
213
213
|
"devDependencies": {
|
|
214
214
|
"@types/node": "^22.0.0",
|
|
215
215
|
"esbuild": "^0.25.0",
|
|
216
216
|
"zod": "^4.0.0",
|
|
217
217
|
"zod-to-json-schema": "^3.25.2",
|
|
218
|
-
"@noy-db/on-shamir": "0.
|
|
218
|
+
"@noy-db/on-shamir": "0.6.0-pre.0"
|
|
219
219
|
},
|
|
220
220
|
"peerDependencies": {
|
|
221
221
|
"zod-to-json-schema": "^3.25.0"
|
package/dist/api-SI2IVBQO.js
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
UserApi,
|
|
3
|
-
createUserApi
|
|
4
|
-
} from "./chunk-SF2ZIRD6.js";
|
|
5
|
-
import "./chunk-2BET5QTS.js";
|
|
6
|
-
import "./chunk-SU6SGWXM.js";
|
|
7
|
-
import "./chunk-EFJAAFBW.js";
|
|
8
|
-
import "./chunk-35NMVJ7I.js";
|
|
9
|
-
import "./chunk-NFZGZ4AK.js";
|
|
10
|
-
import "./chunk-QJNCB5SK.js";
|
|
11
|
-
import "./chunk-LP7BEXCT.js";
|
|
12
|
-
import "./chunk-AKKRXT23.js";
|
|
13
|
-
import "./chunk-77AEMXFA.js";
|
|
14
|
-
import "./chunk-QZWTRENR.js";
|
|
15
|
-
import "./chunk-PZ5AY32C.js";
|
|
16
|
-
export {
|
|
17
|
-
UserApi,
|
|
18
|
-
createUserApi
|
|
19
|
-
};
|
|
20
|
-
//# sourceMappingURL=api-SI2IVBQO.js.map
|