@noy-db/hub 0.2.0-pre.17 → 0.2.0-pre.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/aggregate/index.cjs +227 -3
- package/dist/aggregate/index.cjs.map +1 -1
- package/dist/aggregate/index.d.cts +3 -3
- package/dist/aggregate/index.d.ts +3 -3
- package/dist/aggregate/index.js +5 -4
- package/dist/aggregate/index.js.map +1 -1
- package/dist/attestation/index.cjs.map +1 -1
- package/dist/attestation/index.d.cts +5 -5
- package/dist/attestation/index.d.ts +5 -5
- package/dist/attestation/index.js +6 -6
- package/dist/blobs/index.cjs +4 -10
- package/dist/blobs/index.cjs.map +1 -1
- package/dist/blobs/index.d.cts +6 -6
- package/dist/blobs/index.d.ts +6 -6
- package/dist/blobs/index.js +6 -6
- package/dist/bundle/index.cjs +1587 -392
- package/dist/bundle/index.cjs.map +1 -1
- package/dist/bundle/index.d.cts +7 -7
- package/dist/bundle/index.d.ts +7 -7
- package/dist/bundle/index.js +10 -10
- package/dist/{chunk-NBBMMJ2H.js → chunk-3FSMVWBN.js} +4 -4
- package/dist/{chunk-HGVSHKZW.js → chunk-3Q2AOPLT.js} +100 -29
- package/dist/chunk-3Q2AOPLT.js.map +1 -0
- package/dist/{chunk-SHX5QBCI.js → chunk-4ULLGYPA.js} +3 -3
- package/dist/{chunk-CD2AVTEM.js → chunk-5IGWRMEC.js} +5 -5
- package/dist/{chunk-QO6RGLLD.js → chunk-6KESZO5D.js} +35 -7
- package/dist/chunk-6KESZO5D.js.map +1 -0
- package/dist/{chunk-GP3SDSH2.js → chunk-6OSOE6BY.js} +15 -2
- package/dist/chunk-6OSOE6BY.js.map +1 -0
- package/dist/{chunk-F4G63NTZ.js → chunk-7C6VFNIY.js} +2 -2
- package/dist/{chunk-XJV6OB4D.js → chunk-7HD67R6U.js} +2 -2
- package/dist/{chunk-UMLVJTYV.js → chunk-ADB7GPM3.js} +7 -4
- package/dist/chunk-ADB7GPM3.js.map +1 -0
- package/dist/{chunk-NYSYPFXJ.js → chunk-B6E5IRPJ.js} +3 -3
- package/dist/chunk-CYNTFU2D.js +129 -0
- package/dist/chunk-CYNTFU2D.js.map +1 -0
- package/dist/{chunk-ZEGSDPB7.js → chunk-DJF3FXW5.js} +35 -1
- package/dist/chunk-DJF3FXW5.js.map +1 -0
- package/dist/{chunk-3G3W65EQ.js → chunk-DY3EOJEN.js} +2 -2
- package/dist/{chunk-YYVZYTWW.js → chunk-E66DSTJP.js} +3 -3
- package/dist/{chunk-5LIROIDM.js → chunk-FBLAWK6A.js} +2 -2
- package/dist/{chunk-E77UKJYL.js → chunk-FPHRTW2Z.js} +5 -5
- package/dist/{state-vault-W2OEABNO.js → chunk-G4PYA575.js} +24 -7
- package/dist/chunk-G4PYA575.js.map +1 -0
- package/dist/{chunk-U5QCMH3W.js → chunk-GKQAU52M.js} +4 -4
- package/dist/{chunk-2FU2FTXD.js → chunk-GYAWXHFO.js} +2 -2
- package/dist/{chunk-ROPJVUG3.js → chunk-H42KZXNV.js} +5 -210
- package/dist/chunk-H42KZXNV.js.map +1 -0
- package/dist/{chunk-XPIHJ34I.js → chunk-IBVTH4JR.js} +4 -4
- package/dist/{chunk-C3HYQPV4.js → chunk-IVP5IVON.js} +2 -2
- package/dist/{chunk-BL5GYANC.js → chunk-KEDJDWWQ.js} +3 -3
- package/dist/{chunk-I5IUYN7B.js → chunk-KNKNOJFS.js} +3 -3
- package/dist/chunk-KNKNOJFS.js.map +1 -0
- package/dist/{chunk-D77ZQSQQ.js → chunk-KYGGXXT6.js} +829 -170
- package/dist/chunk-KYGGXXT6.js.map +1 -0
- package/dist/{chunk-J7RWBXFY.js → chunk-LSIIPKYT.js} +2 -2
- package/dist/{chunk-BSZOCSDZ.js → chunk-M3FPNTO2.js} +4 -4
- package/dist/{chunk-XMVHEWF6.js → chunk-MI36HL5G.js} +4 -4
- package/dist/{chunk-ROVO6NPJ.js → chunk-NN6IISZO.js} +58 -3
- package/dist/chunk-NN6IISZO.js.map +1 -0
- package/dist/{chunk-7H2GEJ3O.js → chunk-OBMYMKGO.js} +29 -6
- package/dist/{chunk-7H2GEJ3O.js.map → chunk-OBMYMKGO.js.map} +1 -1
- package/dist/{chunk-UNTGHX5A.js → chunk-OKOKPYWH.js} +2 -2
- package/dist/{chunk-WV7WV6JO.js → chunk-OY7RX2VL.js} +9 -15
- package/dist/chunk-OY7RX2VL.js.map +1 -0
- package/dist/{chunk-H2MRGONI.js → chunk-PTGQPWMV.js} +2 -2
- package/dist/{chunk-BJSLBUJ7.js → chunk-PWFTQHYX.js} +2 -2
- package/dist/{chunk-5AXTH4QZ.js → chunk-Q5MCHUXZ.js} +2 -2
- package/dist/{chunk-QHM6XEAH.js → chunk-S22UOMHM.js} +6 -6
- package/dist/{chunk-WIAOUFFB.js → chunk-S3XA7G35.js} +2 -2
- package/dist/{chunk-SISBMAPO.js → chunk-SHIUFIPW.js} +1 -1
- package/dist/chunk-SHIUFIPW.js.map +1 -0
- package/dist/{chunk-KCEHMDZF.js → chunk-U7JNBSS3.js} +3 -3
- package/dist/{chunk-ZNGPEV5J.js → chunk-V3VIRTTE.js} +3 -3
- package/dist/{chunk-TIDXB5DF.js → chunk-V5FZWQNN.js} +4 -4
- package/dist/chunk-VEIVAYJ7.js +361 -0
- package/dist/chunk-VEIVAYJ7.js.map +1 -0
- package/dist/{chunk-AEIKD3PP.js → chunk-VNUE6FHP.js} +3 -3
- package/dist/{chunk-DYYYUW5D.js → chunk-WFK2EVYU.js} +10 -2
- package/dist/chunk-WFK2EVYU.js.map +1 -0
- package/dist/{chunk-XMHUK5PN.js → chunk-X7FJMKT3.js} +2 -2
- package/dist/{chunk-FEJDVE3Z.js → chunk-XPH3FWME.js} +7 -2
- package/dist/{chunk-FEJDVE3Z.js.map → chunk-XPH3FWME.js.map} +1 -1
- package/dist/{chunk-SNMJ7SB3.js → chunk-Y5J63SMF.js} +5 -5
- package/dist/{chunk-M476FOQ7.js → chunk-YLRRU72W.js} +2 -2
- package/dist/{chunk-DWEBTE2W.js → chunk-YX333DPS.js} +4 -4
- package/dist/{chunk-BH3X5L6A.js → chunk-YZE6C3TQ.js} +3 -3
- package/dist/consent/index.cjs.map +1 -1
- package/dist/consent/index.d.cts +6 -6
- package/dist/consent/index.d.ts +6 -6
- package/dist/consent/index.js +3 -3
- package/dist/{crypto-7BN2HDWG.js → crypto-B46VNH6X.js} +3 -3
- package/dist/{delegation-MGH5SODX.js → delegation-5HON72PV.js} +5 -5
- package/dist/derivations/index.cjs +82 -2
- package/dist/derivations/index.cjs.map +1 -1
- package/dist/derivations/index.d.cts +7 -7
- package/dist/derivations/index.d.ts +7 -7
- package/dist/derivations/index.js +8 -6
- package/dist/{dev-unlock-iXbYFAWl.d.cts → dev-unlock-BR1rMOS-.d.cts} +1 -1
- package/dist/{dev-unlock-CI1ijTML.d.ts → dev-unlock-whL49sxV.d.ts} +1 -1
- package/dist/{errors-Dz64FA65.d.cts → errors-DL-zTrrF.d.cts} +29 -1
- package/dist/{errors-Dz64FA65.d.ts → errors-DL-zTrrF.d.ts} +29 -1
- package/dist/executor-44R5CUS2.js +12 -0
- package/dist/executor-AOACUK7Z.js +8 -0
- package/dist/executor-OKFLQCDW.js +8 -0
- package/dist/{fanout-sidecar-FIJJ46YG.js → fanout-sidecar-DCQWJQ6S.js} +2 -2
- package/dist/forget/index.cjs.map +1 -1
- package/dist/forget/index.d.cts +1 -1
- package/dist/forget/index.d.ts +1 -1
- package/dist/forget/index.js +4 -4
- package/dist/guards/index.cjs +80 -3
- package/dist/guards/index.cjs.map +1 -1
- package/dist/guards/index.d.cts +7 -7
- package/dist/guards/index.d.ts +7 -7
- package/dist/guards/index.js +8 -4
- package/dist/{hash-tEcM5fnv.d.cts → hash-BEUBmmI4.d.cts} +1 -1
- package/dist/{hash-blk7Bkes.d.ts → hash-Dtb7FwWd.d.ts} +1 -1
- package/dist/history/index.cjs.map +1 -1
- package/dist/history/index.d.cts +7 -7
- package/dist/history/index.d.ts +7 -7
- package/dist/history/index.js +5 -5
- package/dist/i18n/index.cjs +149 -132
- package/dist/i18n/index.cjs.map +1 -1
- package/dist/i18n/index.d.cts +6 -6
- package/dist/i18n/index.d.ts +6 -6
- package/dist/i18n/index.js +14 -14
- package/dist/{index-u-kWzSrL.d.cts → index-BM7O48Ur.d.cts} +85 -9
- package/dist/{index-C-SSRIxP.d.cts → index-BMmajblo.d.cts} +14 -0
- package/dist/{index-C-SSRIxP.d.ts → index-BMmajblo.d.ts} +14 -0
- package/dist/{index-DpU6KWof.d.ts → index-BelbyUwz.d.ts} +85 -9
- package/dist/index.cjs +2206 -992
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +29 -16
- package/dist/index.d.ts +29 -16
- package/dist/index.js +76 -54
- package/dist/index.js.map +1 -1
- package/dist/indexing/index.cjs.map +1 -1
- package/dist/indexing/index.js +4 -4
- package/dist/issue-EPA2PSWP.js +12 -0
- package/dist/{ledger-LFVLHE5H.js → ledger-LS6GXCBP.js} +5 -5
- package/dist/materialized-views/index.cjs +257 -4
- package/dist/materialized-views/index.cjs.map +1 -1
- package/dist/materialized-views/index.d.cts +7 -7
- package/dist/materialized-views/index.d.ts +7 -7
- package/dist/materialized-views/index.js +8 -7
- package/dist/noydb-BVKFP74P.js +38 -0
- package/dist/overlay-views/index.cjs.map +1 -1
- package/dist/overlay-views/index.d.cts +7 -7
- package/dist/overlay-views/index.d.ts +7 -7
- package/dist/overlay-views/index.js +4 -4
- package/dist/periods/index.cjs.map +1 -1
- package/dist/periods/index.d.cts +6 -6
- package/dist/periods/index.d.ts +6 -6
- package/dist/periods/index.js +5 -5
- package/dist/{public-envelope-RXZNP3V6.js → public-envelope-AGU6SS4Z.js} +4 -4
- package/dist/query/index.cjs +320 -28
- package/dist/query/index.cjs.map +1 -1
- package/dist/query/index.d.cts +3 -3
- package/dist/query/index.d.ts +3 -3
- package/dist/query/index.js +7 -6
- package/dist/read-only-facade-EX6WZZBP.js +7 -0
- package/dist/registry-ERNAMRDE.js +8 -0
- package/dist/registry-EXTHSXQW.js +8 -0
- package/dist/{registry-SECUWSGY.js → registry-RDPTFXQ7.js} +3 -3
- package/dist/{revoke-B54H2S2W.js → revoke-IFLXEZA5.js} +6 -6
- package/dist/sealed-record/index.cjs.map +1 -1
- package/dist/sealed-record/index.d.cts +1 -1
- package/dist/sealed-record/index.d.ts +1 -1
- package/dist/sealed-record/index.js +2 -2
- package/dist/session/index.cjs.map +1 -1
- package/dist/session/index.d.cts +7 -7
- package/dist/session/index.d.ts +7 -7
- package/dist/session/index.js +3 -3
- package/dist/shadow/index.cjs.map +1 -1
- package/dist/shadow/index.d.cts +6 -6
- package/dist/shadow/index.d.ts +6 -6
- package/dist/shadow/index.js +2 -2
- package/dist/{signer-YSXZT574.js → signer-UNWOUJAK.js} +5 -5
- package/dist/snapshots/index.cjs.map +1 -1
- package/dist/snapshots/index.d.cts +6 -6
- package/dist/snapshots/index.d.ts +6 -6
- package/dist/snapshots/index.js +4 -4
- package/dist/{stale-TOA36SRK.js → stale-NTEV5SLX.js} +2 -2
- package/dist/state-vault-TUTFRTOA.js +14 -0
- package/dist/state-vault-TUTFRTOA.js.map +1 -0
- package/dist/store/index.cjs +8 -0
- package/dist/store/index.cjs.map +1 -1
- package/dist/store/index.d.cts +13 -6
- package/dist/store/index.d.ts +13 -6
- package/dist/store/index.js +2 -2
- package/dist/{strategy-4M9jo172.d.ts → strategy-BDxQnnTX.d.ts} +315 -4
- package/dist/{strategy-CLC1j79g.d.cts → strategy-C5ol6NdV.d.cts} +315 -4
- package/dist/sync/index.cjs.map +1 -1
- package/dist/sync/index.d.cts +5 -5
- package/dist/sync/index.d.ts +5 -5
- package/dist/sync/index.js +4 -4
- package/dist/team/index.cjs.map +1 -1
- package/dist/team/index.d.cts +6 -6
- package/dist/team/index.d.ts +6 -6
- package/dist/team/index.js +8 -8
- package/dist/transition-guard-B1N82hMf.d.cts +165 -0
- package/dist/transition-guard-C__YeF3_.d.ts +165 -0
- package/dist/tx/index.cjs.map +1 -1
- package/dist/tx/index.d.cts +6 -6
- package/dist/tx/index.d.ts +6 -6
- package/dist/tx/index.js +3 -3
- package/dist/{types-CljIHm_J.d.ts → types-CraiZOyO.d.ts} +609 -305
- package/dist/{types-CrSpRDuG.d.cts → types-D-gr5t0G.d.cts} +609 -305
- package/dist/{ulid-CrI7PPbA.d.cts → ulid-DQnSAP5W.d.cts} +1 -1
- package/dist/{ulid-CWfL2Vfv.d.ts → ulid-FFRRHkVf.d.ts} +1 -1
- package/dist/util/index.cjs.map +1 -1
- package/dist/util/index.js +1 -1
- package/dist/{vault-group-DHAHFX2A.js → vault-group-27EV7KB4.js} +205 -8
- package/dist/vault-group-27EV7KB4.js.map +1 -0
- package/dist/{with-materialized-view-NzF71cG_.d.cts → with-materialized-view-BboqxyV3.d.cts} +1 -1
- package/dist/{with-materialized-view-B892zYZV.d.ts → with-materialized-view-CguCeVcT.d.ts} +1 -1
- package/dist/{with-overlayed-view-CR6m7CHe.d.ts → with-overlayed-view-DO08u_tx.d.ts} +1 -1
- package/dist/{with-overlayed-view-UI8qSGL4.d.cts → with-overlayed-view-mmsg5Of3.d.cts} +1 -1
- package/dist/with-rollup-_TyBzz3T.d.ts +47 -0
- package/dist/with-rollup-aaxOZcIb.d.cts +47 -0
- package/package.json +3 -3
- package/dist/chunk-D77ZQSQQ.js.map +0 -1
- package/dist/chunk-DYYYUW5D.js.map +0 -1
- package/dist/chunk-GP3SDSH2.js.map +0 -1
- package/dist/chunk-HGVSHKZW.js.map +0 -1
- package/dist/chunk-I5IUYN7B.js.map +0 -1
- package/dist/chunk-JDWE6JMX.js +0 -139
- package/dist/chunk-JDWE6JMX.js.map +0 -1
- package/dist/chunk-PDULVIBY.js +0 -63
- package/dist/chunk-PDULVIBY.js.map +0 -1
- package/dist/chunk-QO6RGLLD.js.map +0 -1
- package/dist/chunk-ROPJVUG3.js.map +0 -1
- package/dist/chunk-ROVO6NPJ.js.map +0 -1
- package/dist/chunk-SISBMAPO.js.map +0 -1
- package/dist/chunk-UMLVJTYV.js.map +0 -1
- package/dist/chunk-WV7WV6JO.js.map +0 -1
- package/dist/chunk-ZEGSDPB7.js.map +0 -1
- package/dist/executor-3W63Y44O.js +0 -11
- package/dist/executor-CFFWPWBJ.js +0 -8
- package/dist/executor-VDQQOR4F.js +0 -8
- package/dist/immutable-guard-B5M95nbq.d.ts +0 -82
- package/dist/immutable-guard-qN3zF8o1.d.cts +0 -82
- package/dist/issue-TTMGHQ2J.js +0 -12
- package/dist/noydb-36S6GQNC.js +0 -37
- package/dist/read-only-facade-ITU6L7BL.js +0 -7
- package/dist/registry-3YFLZ7WD.js +0 -8
- package/dist/registry-TGZISEWC.js +0 -8
- package/dist/state-vault-W2OEABNO.js.map +0 -1
- package/dist/vault-group-DHAHFX2A.js.map +0 -1
- package/dist/with-derivation-BZ2y4bzF.d.ts +0 -13
- package/dist/with-derivation-Bozs8DmD.d.cts +0 -13
- /package/dist/{chunk-NBBMMJ2H.js.map → chunk-3FSMVWBN.js.map} +0 -0
- /package/dist/{chunk-SHX5QBCI.js.map → chunk-4ULLGYPA.js.map} +0 -0
- /package/dist/{chunk-CD2AVTEM.js.map → chunk-5IGWRMEC.js.map} +0 -0
- /package/dist/{chunk-F4G63NTZ.js.map → chunk-7C6VFNIY.js.map} +0 -0
- /package/dist/{chunk-XJV6OB4D.js.map → chunk-7HD67R6U.js.map} +0 -0
- /package/dist/{chunk-NYSYPFXJ.js.map → chunk-B6E5IRPJ.js.map} +0 -0
- /package/dist/{chunk-3G3W65EQ.js.map → chunk-DY3EOJEN.js.map} +0 -0
- /package/dist/{chunk-YYVZYTWW.js.map → chunk-E66DSTJP.js.map} +0 -0
- /package/dist/{chunk-5LIROIDM.js.map → chunk-FBLAWK6A.js.map} +0 -0
- /package/dist/{chunk-E77UKJYL.js.map → chunk-FPHRTW2Z.js.map} +0 -0
- /package/dist/{chunk-U5QCMH3W.js.map → chunk-GKQAU52M.js.map} +0 -0
- /package/dist/{chunk-2FU2FTXD.js.map → chunk-GYAWXHFO.js.map} +0 -0
- /package/dist/{chunk-XPIHJ34I.js.map → chunk-IBVTH4JR.js.map} +0 -0
- /package/dist/{chunk-C3HYQPV4.js.map → chunk-IVP5IVON.js.map} +0 -0
- /package/dist/{chunk-BL5GYANC.js.map → chunk-KEDJDWWQ.js.map} +0 -0
- /package/dist/{chunk-J7RWBXFY.js.map → chunk-LSIIPKYT.js.map} +0 -0
- /package/dist/{chunk-BSZOCSDZ.js.map → chunk-M3FPNTO2.js.map} +0 -0
- /package/dist/{chunk-XMVHEWF6.js.map → chunk-MI36HL5G.js.map} +0 -0
- /package/dist/{chunk-UNTGHX5A.js.map → chunk-OKOKPYWH.js.map} +0 -0
- /package/dist/{chunk-H2MRGONI.js.map → chunk-PTGQPWMV.js.map} +0 -0
- /package/dist/{chunk-BJSLBUJ7.js.map → chunk-PWFTQHYX.js.map} +0 -0
- /package/dist/{chunk-5AXTH4QZ.js.map → chunk-Q5MCHUXZ.js.map} +0 -0
- /package/dist/{chunk-QHM6XEAH.js.map → chunk-S22UOMHM.js.map} +0 -0
- /package/dist/{chunk-WIAOUFFB.js.map → chunk-S3XA7G35.js.map} +0 -0
- /package/dist/{chunk-KCEHMDZF.js.map → chunk-U7JNBSS3.js.map} +0 -0
- /package/dist/{chunk-ZNGPEV5J.js.map → chunk-V3VIRTTE.js.map} +0 -0
- /package/dist/{chunk-TIDXB5DF.js.map → chunk-V5FZWQNN.js.map} +0 -0
- /package/dist/{chunk-AEIKD3PP.js.map → chunk-VNUE6FHP.js.map} +0 -0
- /package/dist/{chunk-XMHUK5PN.js.map → chunk-X7FJMKT3.js.map} +0 -0
- /package/dist/{chunk-SNMJ7SB3.js.map → chunk-Y5J63SMF.js.map} +0 -0
- /package/dist/{chunk-M476FOQ7.js.map → chunk-YLRRU72W.js.map} +0 -0
- /package/dist/{chunk-DWEBTE2W.js.map → chunk-YX333DPS.js.map} +0 -0
- /package/dist/{chunk-BH3X5L6A.js.map → chunk-YZE6C3TQ.js.map} +0 -0
- /package/dist/{crypto-7BN2HDWG.js.map → crypto-B46VNH6X.js.map} +0 -0
- /package/dist/{delegation-MGH5SODX.js.map → delegation-5HON72PV.js.map} +0 -0
- /package/dist/{executor-3W63Y44O.js.map → executor-44R5CUS2.js.map} +0 -0
- /package/dist/{executor-CFFWPWBJ.js.map → executor-AOACUK7Z.js.map} +0 -0
- /package/dist/{executor-VDQQOR4F.js.map → executor-OKFLQCDW.js.map} +0 -0
- /package/dist/{fanout-sidecar-FIJJ46YG.js.map → fanout-sidecar-DCQWJQ6S.js.map} +0 -0
- /package/dist/{issue-TTMGHQ2J.js.map → issue-EPA2PSWP.js.map} +0 -0
- /package/dist/{ledger-LFVLHE5H.js.map → ledger-LS6GXCBP.js.map} +0 -0
- /package/dist/{noydb-36S6GQNC.js.map → noydb-BVKFP74P.js.map} +0 -0
- /package/dist/{public-envelope-RXZNP3V6.js.map → public-envelope-AGU6SS4Z.js.map} +0 -0
- /package/dist/{read-only-facade-ITU6L7BL.js.map → read-only-facade-EX6WZZBP.js.map} +0 -0
- /package/dist/{registry-3YFLZ7WD.js.map → registry-ERNAMRDE.js.map} +0 -0
- /package/dist/{registry-SECUWSGY.js.map → registry-EXTHSXQW.js.map} +0 -0
- /package/dist/{registry-TGZISEWC.js.map → registry-RDPTFXQ7.js.map} +0 -0
- /package/dist/{revoke-B54H2S2W.js.map → revoke-IFLXEZA5.js.map} +0 -0
- /package/dist/{signer-YSXZT574.js.map → signer-UNWOUJAK.js.map} +0 -0
- /package/dist/{stale-TOA36SRK.js.map → stale-NTEV5SLX.js.map} +0 -0
|
@@ -7,10 +7,10 @@ import {
|
|
|
7
7
|
import {
|
|
8
8
|
TxContext,
|
|
9
9
|
revertExecuted
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-V3VIRTTE.js";
|
|
11
11
|
import {
|
|
12
12
|
OverlayedCollection
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-X7FJMKT3.js";
|
|
14
14
|
import {
|
|
15
15
|
NO_AGGREGATE,
|
|
16
16
|
Query,
|
|
@@ -20,36 +20,36 @@ import {
|
|
|
20
20
|
decodeMoneyFields,
|
|
21
21
|
quantizeMoneyFields,
|
|
22
22
|
validateMoneyFieldPaths
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-3Q2AOPLT.js";
|
|
24
24
|
import {
|
|
25
25
|
EXPORT_AUDIT_COLLECTION,
|
|
26
26
|
createExportBlobsHandle,
|
|
27
27
|
runCompaction
|
|
28
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-U7JNBSS3.js";
|
|
29
29
|
import {
|
|
30
30
|
LazyQuery,
|
|
31
31
|
decodeIdxId,
|
|
32
32
|
encodeIdxId
|
|
33
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-B6E5IRPJ.js";
|
|
34
34
|
import {
|
|
35
35
|
canonicalGroupKey
|
|
36
|
-
} from "./chunk-
|
|
36
|
+
} from "./chunk-OBMYMKGO.js";
|
|
37
37
|
import {
|
|
38
38
|
readPath
|
|
39
|
-
} from "./chunk-
|
|
39
|
+
} from "./chunk-LSIIPKYT.js";
|
|
40
40
|
import {
|
|
41
41
|
SCHEMAS_COLLECTION,
|
|
42
42
|
loadPersistedSchema,
|
|
43
43
|
resolveManagedSecret,
|
|
44
44
|
savePersistedSchema,
|
|
45
45
|
saveSealedPassphrase
|
|
46
|
-
} from "./chunk-
|
|
46
|
+
} from "./chunk-VNUE6FHP.js";
|
|
47
47
|
import {
|
|
48
48
|
loadPublicEnvelope,
|
|
49
49
|
readPublicEnvelope,
|
|
50
50
|
savePublicEnvelope,
|
|
51
51
|
validatePublicEnvelopeInput
|
|
52
|
-
} from "./chunk-
|
|
52
|
+
} from "./chunk-E66DSTJP.js";
|
|
53
53
|
import {
|
|
54
54
|
buildTombstone,
|
|
55
55
|
isTombstone,
|
|
@@ -58,17 +58,19 @@ import {
|
|
|
58
58
|
rewrapBodyToDek,
|
|
59
59
|
rotateRecordCek,
|
|
60
60
|
sealRecordToHost
|
|
61
|
-
} from "./chunk-
|
|
61
|
+
} from "./chunk-GKQAU52M.js";
|
|
62
62
|
import {
|
|
63
63
|
PERIODS_COLLECTION
|
|
64
|
-
} from "./chunk-
|
|
64
|
+
} from "./chunk-YZE6C3TQ.js";
|
|
65
65
|
import {
|
|
66
|
-
getAtPath,
|
|
67
66
|
isDictCollectionName,
|
|
68
|
-
isStaticDictDescriptor
|
|
67
|
+
isStaticDictDescriptor
|
|
68
|
+
} from "./chunk-H42KZXNV.js";
|
|
69
|
+
import {
|
|
70
|
+
getAtPath,
|
|
69
71
|
resolvePolicy,
|
|
70
72
|
setAtPathInPlace
|
|
71
|
-
} from "./chunk-
|
|
73
|
+
} from "./chunk-VEIVAYJ7.js";
|
|
72
74
|
import {
|
|
73
75
|
ManagedRecoveryNotEnrolledError,
|
|
74
76
|
PolicyDeniedError,
|
|
@@ -90,11 +92,11 @@ import {
|
|
|
90
92
|
saveShamirRecoveryEntries,
|
|
91
93
|
updateAuthenticator,
|
|
92
94
|
writeMagicLinkGrant
|
|
93
|
-
} from "./chunk-
|
|
95
|
+
} from "./chunk-S22UOMHM.js";
|
|
94
96
|
import {
|
|
95
97
|
assertTierAccess,
|
|
96
98
|
dekKey
|
|
97
|
-
} from "./chunk-
|
|
99
|
+
} from "./chunk-FBLAWK6A.js";
|
|
98
100
|
import {
|
|
99
101
|
USER_ENVELOPE_COLLECTION,
|
|
100
102
|
assertKeyringOpenAllowed,
|
|
@@ -119,7 +121,7 @@ import {
|
|
|
119
121
|
rotateKeys,
|
|
120
122
|
saveUserEnvelope,
|
|
121
123
|
updateKeyringIdentity
|
|
122
|
-
} from "./chunk-
|
|
124
|
+
} from "./chunk-M3FPNTO2.js";
|
|
123
125
|
import {
|
|
124
126
|
INDEXED_STORE_POLICY
|
|
125
127
|
} from "./chunk-2QR2PQTT.js";
|
|
@@ -129,7 +131,7 @@ import {
|
|
|
129
131
|
import {
|
|
130
132
|
LEDGER_COLLECTION,
|
|
131
133
|
LEDGER_DELTAS_COLLECTION
|
|
132
|
-
} from "./chunk-
|
|
134
|
+
} from "./chunk-YX333DPS.js";
|
|
133
135
|
import {
|
|
134
136
|
sha256Hex as sha256Hex2
|
|
135
137
|
} from "./chunk-PDVP3C2I.js";
|
|
@@ -141,11 +143,11 @@ import {
|
|
|
141
143
|
readDottedPath,
|
|
142
144
|
rebuildSubjectIndex,
|
|
143
145
|
removeSubjectRef
|
|
144
|
-
} from "./chunk-
|
|
146
|
+
} from "./chunk-KNKNOJFS.js";
|
|
145
147
|
import {
|
|
146
148
|
NOYDB_BACKUP_VERSION,
|
|
147
149
|
NOYDB_FORMAT_VERSION
|
|
148
|
-
} from "./chunk-
|
|
150
|
+
} from "./chunk-SHIUFIPW.js";
|
|
149
151
|
import {
|
|
150
152
|
decrypt,
|
|
151
153
|
encrypt,
|
|
@@ -153,13 +155,14 @@ import {
|
|
|
153
155
|
sha256Hex,
|
|
154
156
|
unwrapCek,
|
|
155
157
|
wrapCek
|
|
156
|
-
} from "./chunk-
|
|
158
|
+
} from "./chunk-OKOKPYWH.js";
|
|
157
159
|
import {
|
|
158
160
|
AlreadyElevatedError,
|
|
159
161
|
AttestationError,
|
|
160
162
|
BackupCorruptedError,
|
|
161
163
|
BackupLedgerError,
|
|
162
164
|
ConflictError,
|
|
165
|
+
DerivationCapExceededError,
|
|
163
166
|
ElevationExpiredError,
|
|
164
167
|
ExportCapabilityError,
|
|
165
168
|
ForgetStrategyNotConfiguredError,
|
|
@@ -191,7 +194,7 @@ import {
|
|
|
191
194
|
UnsupportedIndexOptionError,
|
|
192
195
|
ValidationError,
|
|
193
196
|
VaultTemplateNotFoundError
|
|
194
|
-
} from "./chunk-
|
|
197
|
+
} from "./chunk-DJF3FXW5.js";
|
|
195
198
|
|
|
196
199
|
// src/policy/storage.ts
|
|
197
200
|
var META_COLLECTION = "_meta";
|
|
@@ -506,6 +509,74 @@ var DISABLED_STATE = {
|
|
|
506
509
|
getPersistedIndexes: () => null
|
|
507
510
|
};
|
|
508
511
|
|
|
512
|
+
// src/search/tokenize.ts
|
|
513
|
+
var WORD = /[\p{L}\p{N}]+/gu;
|
|
514
|
+
var tokenize = (text) => {
|
|
515
|
+
if (!text) return [];
|
|
516
|
+
return text.normalize("NFKC").toLowerCase().match(WORD) ?? [];
|
|
517
|
+
};
|
|
518
|
+
|
|
519
|
+
// src/search/scan.ts
|
|
520
|
+
var K1 = 1.2;
|
|
521
|
+
var B = 0.75;
|
|
522
|
+
function fieldText(record, field) {
|
|
523
|
+
const v = record[field];
|
|
524
|
+
if (typeof v === "string") return v;
|
|
525
|
+
if (v === null || v === void 0) return "";
|
|
526
|
+
if (typeof v === "number" || typeof v === "boolean") return String(v);
|
|
527
|
+
return "";
|
|
528
|
+
}
|
|
529
|
+
function searchScan(entries, field, query, opts = {}, tokenizer = tokenize) {
|
|
530
|
+
const queryTerms = tokenizer(query);
|
|
531
|
+
if (queryTerms.length === 0) return [];
|
|
532
|
+
const match = opts.match ?? "any";
|
|
533
|
+
const usePrefix = opts.prefix ?? false;
|
|
534
|
+
const exactTerms = usePrefix ? queryTerms.slice(0, -1) : queryTerms;
|
|
535
|
+
const prefixTerm = usePrefix ? queryTerms[queryTerms.length - 1] : void 0;
|
|
536
|
+
const docs = entries.map((e) => ({ id: e.id, record: e.record, terms: tokenizer(fieldText(e.record, field)) }));
|
|
537
|
+
const N = docs.length || 1;
|
|
538
|
+
const df = /* @__PURE__ */ new Map();
|
|
539
|
+
let totalLen = 0;
|
|
540
|
+
for (const d of docs) {
|
|
541
|
+
totalLen += d.terms.length;
|
|
542
|
+
for (const t of new Set(d.terms)) df.set(t, (df.get(t) ?? 0) + 1);
|
|
543
|
+
}
|
|
544
|
+
const avgdl = totalLen / N || 1;
|
|
545
|
+
let prefixDf = 0;
|
|
546
|
+
if (prefixTerm !== void 0) {
|
|
547
|
+
for (const d of docs) {
|
|
548
|
+
if (d.terms.some((t) => t.startsWith(prefixTerm))) prefixDf++;
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
const requiredCount = exactTerms.length + (prefixTerm !== void 0 ? 1 : 0);
|
|
552
|
+
const results = [];
|
|
553
|
+
for (const d of docs) {
|
|
554
|
+
const tf = /* @__PURE__ */ new Map();
|
|
555
|
+
for (const t of d.terms) tf.set(t, (tf.get(t) ?? 0) + 1);
|
|
556
|
+
const matched = [];
|
|
557
|
+
for (const qt of exactTerms) {
|
|
558
|
+
const c = tf.get(qt) ?? 0;
|
|
559
|
+
if (c > 0) matched.push({ tf: c, df: df.get(qt) ?? 0 });
|
|
560
|
+
}
|
|
561
|
+
if (prefixTerm !== void 0) {
|
|
562
|
+
let ptf = 0;
|
|
563
|
+
for (const [t, c] of tf) if (t.startsWith(prefixTerm)) ptf += c;
|
|
564
|
+
if (ptf > 0) matched.push({ tf: ptf, df: prefixDf });
|
|
565
|
+
}
|
|
566
|
+
if (matched.length === 0) continue;
|
|
567
|
+
if (match === "all" && matched.length < requiredCount) continue;
|
|
568
|
+
let score = 0;
|
|
569
|
+
for (const m of matched) {
|
|
570
|
+
const idf = Math.log(1 + (N - m.df + 0.5) / (m.df + 0.5));
|
|
571
|
+
const denom = m.tf + K1 * (1 - B + B * (d.terms.length / avgdl));
|
|
572
|
+
score += idf * (m.tf * (K1 + 1) / (denom || 1));
|
|
573
|
+
}
|
|
574
|
+
results.push({ id: d.id, score, record: d.record });
|
|
575
|
+
}
|
|
576
|
+
results.sort((a, b) => b.score - a.score);
|
|
577
|
+
return opts.limit !== void 0 ? results.slice(0, opts.limit) : results;
|
|
578
|
+
}
|
|
579
|
+
|
|
509
580
|
// src/indexing/unique-constraints.ts
|
|
510
581
|
var UniqueConstraintSet = class {
|
|
511
582
|
constructor(collectionName, uniqueDefs) {
|
|
@@ -837,7 +908,7 @@ async function resolveStaleOnRead(accessor, outputCollection, id) {
|
|
|
837
908
|
}
|
|
838
909
|
const sourceWithId = { ...source, id };
|
|
839
910
|
if (DerivationExecutor === null) {
|
|
840
|
-
({ DerivationExecutor } = await import("./executor-
|
|
911
|
+
({ DerivationExecutor } = await import("./executor-OKFLQCDW.js"));
|
|
841
912
|
}
|
|
842
913
|
const ctx = { vault: accessor.getReadOnlyFacade() };
|
|
843
914
|
const result = await DerivationExecutor.run(spec, sourceWithId, 0, strategyHash, ctx);
|
|
@@ -875,6 +946,15 @@ async function resolveStaleOnRead(accessor, outputCollection, id) {
|
|
|
875
946
|
}
|
|
876
947
|
|
|
877
948
|
// src/collection.ts
|
|
949
|
+
function selfWriteFieldEqual(a, b) {
|
|
950
|
+
if (a === b) return true;
|
|
951
|
+
if (a === null || b === null || typeof a !== "object" || typeof b !== "object") return false;
|
|
952
|
+
try {
|
|
953
|
+
return JSON.stringify(a) === JSON.stringify(b);
|
|
954
|
+
} catch {
|
|
955
|
+
return false;
|
|
956
|
+
}
|
|
957
|
+
}
|
|
878
958
|
var fallbackWarned = /* @__PURE__ */ new Set();
|
|
879
959
|
function warnOnceFallback(adapterName) {
|
|
880
960
|
if (fallbackWarned.has(adapterName)) return;
|
|
@@ -1373,7 +1453,7 @@ var Collection = class {
|
|
|
1373
1453
|
}
|
|
1374
1454
|
}
|
|
1375
1455
|
if (this.materializedViewSource !== void 0) {
|
|
1376
|
-
const { resolveStaleMVOnRead } = await import("./stale-
|
|
1456
|
+
const { resolveStaleMVOnRead } = await import("./stale-NTEV5SLX.js");
|
|
1377
1457
|
await resolveStaleMVOnRead(this.materializedViewSource, this.name);
|
|
1378
1458
|
}
|
|
1379
1459
|
let record;
|
|
@@ -1783,7 +1863,7 @@ var Collection = class {
|
|
|
1783
1863
|
if (mode === "eager") {
|
|
1784
1864
|
if (executor === null) {
|
|
1785
1865
|
;
|
|
1786
|
-
({ MaterializedViewExecutor: executor } = await import("./executor-
|
|
1866
|
+
({ MaterializedViewExecutor: executor } = await import("./executor-44R5CUS2.js"));
|
|
1787
1867
|
}
|
|
1788
1868
|
await executor.refresh(reg, {
|
|
1789
1869
|
getCollection: (name) => this.materializedViewSource.getCollection(name),
|
|
@@ -1792,7 +1872,7 @@ var Collection = class {
|
|
|
1792
1872
|
});
|
|
1793
1873
|
} else if (mode === "lazy") {
|
|
1794
1874
|
if (staleHelpers === null) {
|
|
1795
|
-
staleHelpers = await import("./stale-
|
|
1875
|
+
staleHelpers = await import("./stale-NTEV5SLX.js");
|
|
1796
1876
|
}
|
|
1797
1877
|
staleHelpers.markMVStale(registry, reg.spec.name);
|
|
1798
1878
|
}
|
|
@@ -1809,6 +1889,111 @@ var Collection = class {
|
|
|
1809
1889
|
* output (carries `_derivedFrom`) — defensive guard against missed
|
|
1810
1890
|
* cycle detection.
|
|
1811
1891
|
*/
|
|
1892
|
+
/**
|
|
1893
|
+
* @internal #376 — the RAW stored record (canonical-money form, i18n maps
|
|
1894
|
+
* intact), WITHOUT the locale resolution `get()` applies. Used as the
|
|
1895
|
+
* patch base for self-write reverse-denorm so writing back never clobbers
|
|
1896
|
+
* an i18n map or re-quantizes money incorrectly. Returns null for
|
|
1897
|
+
* missing / tombstoned records.
|
|
1898
|
+
*/
|
|
1899
|
+
async _getStoredRecord(id) {
|
|
1900
|
+
let raw;
|
|
1901
|
+
if (this.lazy && this.lru) {
|
|
1902
|
+
const cached = this.lru.get(id);
|
|
1903
|
+
if (cached) raw = cached.record;
|
|
1904
|
+
else {
|
|
1905
|
+
const env = await this.adapter.get(this.vault, this.name, id);
|
|
1906
|
+
if (!env || isTombstone(env, this.encrypted)) return null;
|
|
1907
|
+
raw = await this.decryptRecord(env, { id });
|
|
1908
|
+
if (raw === null) return null;
|
|
1909
|
+
this.lru.set(id, { record: raw, version: env._v }, estimateRecordBytes(raw));
|
|
1910
|
+
}
|
|
1911
|
+
} else {
|
|
1912
|
+
await this.ensureHydrated();
|
|
1913
|
+
raw = this.cache.get(id)?.record ?? null;
|
|
1914
|
+
}
|
|
1915
|
+
if (raw === null) return null;
|
|
1916
|
+
return canonicalizeStoredMoney(raw, this.moneyFields);
|
|
1917
|
+
}
|
|
1918
|
+
/**
|
|
1919
|
+
* @internal #376 — ids of records whose top-level `field` equals `value`.
|
|
1920
|
+
* Uses the FK index when the field is indexed (O(matches)); otherwise a
|
|
1921
|
+
* linear scan (O(N) — fine for small child sets; index the FK to scale).
|
|
1922
|
+
*/
|
|
1923
|
+
async _findMatchingIds(field, value) {
|
|
1924
|
+
const hit = this.getIndexes()?.lookupEqual(field, value);
|
|
1925
|
+
if (hit) return [...hit];
|
|
1926
|
+
const target = String(value);
|
|
1927
|
+
const matches = (rec) => {
|
|
1928
|
+
const fv = rec[field];
|
|
1929
|
+
return (typeof fv === "string" || typeof fv === "number") && String(fv) === target;
|
|
1930
|
+
};
|
|
1931
|
+
if (!this.lazy) {
|
|
1932
|
+
await this.ensureHydrated();
|
|
1933
|
+
const out2 = [];
|
|
1934
|
+
for (const [rid, e] of this.cache) {
|
|
1935
|
+
if (matches(e.record)) out2.push(rid);
|
|
1936
|
+
}
|
|
1937
|
+
return out2;
|
|
1938
|
+
}
|
|
1939
|
+
const ids = await this.adapter.list(this.vault, this.name);
|
|
1940
|
+
const out = [];
|
|
1941
|
+
for (const rid of ids) {
|
|
1942
|
+
const raw = await this._getStoredRecord(rid);
|
|
1943
|
+
if (raw !== null && matches(raw)) out.push(rid);
|
|
1944
|
+
}
|
|
1945
|
+
return out;
|
|
1946
|
+
}
|
|
1947
|
+
/**
|
|
1948
|
+
* @internal #376 slice 2 — recompute a rollup aggregate onto the parent.
|
|
1949
|
+
* Gathers every child of `parentId`, runs `compute`, and patches only the
|
|
1950
|
+
* rollup `field` onto the parent's raw stored record (value-equality
|
|
1951
|
+
* guarded). No-op when the parent record does not exist.
|
|
1952
|
+
*/
|
|
1953
|
+
async recomputeRollup(spec, parentId) {
|
|
1954
|
+
if (this.derivationSource === void 0 || spec.rollup === void 0) return;
|
|
1955
|
+
const { from, key, field, compute } = spec.rollup;
|
|
1956
|
+
const into = spec.source;
|
|
1957
|
+
const intoColl = this.derivationSource.getCollection(into);
|
|
1958
|
+
const base = await intoColl._getStoredRecord(parentId);
|
|
1959
|
+
if (base === null) return;
|
|
1960
|
+
const fromColl = this.derivationSource.getCollection(from);
|
|
1961
|
+
const childIds = await fromColl._findMatchingIds(key, parentId);
|
|
1962
|
+
const children = [];
|
|
1963
|
+
for (const cid of childIds) {
|
|
1964
|
+
const c = await fromColl.get(cid);
|
|
1965
|
+
if (c !== null && c !== void 0) children.push(c);
|
|
1966
|
+
}
|
|
1967
|
+
const newValue = compute(children);
|
|
1968
|
+
if (selfWriteFieldEqual(base[field], newValue)) return;
|
|
1969
|
+
const patched = { ...base, [field]: newValue };
|
|
1970
|
+
const txCtx = this.derivationSource.getActiveTxContext();
|
|
1971
|
+
if (txCtx !== null) {
|
|
1972
|
+
const prior = await this.adapter.get(this.vault, into, parentId);
|
|
1973
|
+
txCtx._executed.push({
|
|
1974
|
+
op: { type: "put", vaultName: this.vault, collectionName: into, id: parentId },
|
|
1975
|
+
priorEnvelope: prior
|
|
1976
|
+
});
|
|
1977
|
+
}
|
|
1978
|
+
await intoColl.put(parentId, patched);
|
|
1979
|
+
}
|
|
1980
|
+
/**
|
|
1981
|
+
* @internal #376 slice 2 — fire any rollups for which THIS collection is the
|
|
1982
|
+
* child `from`, recomputing the affected parent after a child delete. Called
|
|
1983
|
+
* from the delete path with the just-removed record's key value. Other
|
|
1984
|
+
* derivation kinds do not react to deletes (unchanged).
|
|
1985
|
+
*/
|
|
1986
|
+
async dispatchRollupsOnDelete(deleted) {
|
|
1987
|
+
if (this.derivationSource === void 0) return;
|
|
1988
|
+
const registry = this.derivationSource.registry();
|
|
1989
|
+
const rec = deleted;
|
|
1990
|
+
for (const { spec } of registry.strategiesForSource(this.name)) {
|
|
1991
|
+
if (!spec.rollup || spec.rollup.from !== this.name) continue;
|
|
1992
|
+
const kv = rec[spec.rollup.key];
|
|
1993
|
+
if (typeof kv !== "string" && typeof kv !== "number") continue;
|
|
1994
|
+
await this.recomputeRollup(spec, String(kv));
|
|
1995
|
+
}
|
|
1996
|
+
}
|
|
1812
1997
|
async dispatchDerivations(id, record, version) {
|
|
1813
1998
|
if (this.derivationSource === void 0) return;
|
|
1814
1999
|
const incoming = canonicalizeStoredMoney(record, this.moneyFields);
|
|
@@ -1819,29 +2004,60 @@ var Collection = class {
|
|
|
1819
2004
|
let DerivationExecutor = null;
|
|
1820
2005
|
for (const { spec, strategyHash } of strategies) {
|
|
1821
2006
|
const mode = typeof spec.lifecycle === "string" ? spec.lifecycle : spec.lifecycle.mode;
|
|
1822
|
-
if (
|
|
1823
|
-
if (
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
if (spec.source === this.name) {
|
|
1829
|
-
sourceWithId = { ...incoming, id };
|
|
2007
|
+
if (spec.rollup) {
|
|
2008
|
+
if (mode !== "eager") continue;
|
|
2009
|
+
let parentId;
|
|
2010
|
+
if (this.name === spec.rollup.from) {
|
|
2011
|
+
const kv = incoming[spec.rollup.key];
|
|
2012
|
+
parentId = typeof kv === "string" || typeof kv === "number" ? String(kv) : null;
|
|
1830
2013
|
} else {
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
2014
|
+
parentId = id;
|
|
2015
|
+
}
|
|
2016
|
+
if (parentId !== null) await this.recomputeRollup(spec, parentId);
|
|
2017
|
+
continue;
|
|
2018
|
+
}
|
|
2019
|
+
const isSource = spec.source === this.name;
|
|
2020
|
+
const isSibling = !isSource && (spec.sources?.includes(this.name) ?? false);
|
|
2021
|
+
const trigger = !isSource && !isSibling ? spec.triggerBy?.find((t) => t.collection === this.name) : void 0;
|
|
2022
|
+
const runs = [];
|
|
2023
|
+
if (isSource) {
|
|
2024
|
+
runs.push({ input: { ...incoming, id }, base: incoming, runId: id, version });
|
|
2025
|
+
} else if (isSibling) {
|
|
2026
|
+
const p = await this.derivationSource.getCollection(spec.source).get(id);
|
|
2027
|
+
if (p !== null && p !== void 0) {
|
|
2028
|
+
const raw = await this.derivationSource.getCollection(spec.source)._getStoredRecord(id);
|
|
2029
|
+
runs.push({ input: { ...p, id }, base: raw ?? p, runId: id, version: 0 });
|
|
2030
|
+
}
|
|
2031
|
+
} else if (trigger) {
|
|
2032
|
+
const srcColl = this.derivationSource.getCollection(spec.source);
|
|
2033
|
+
const ids = await srcColl._findMatchingIds(trigger.on, id);
|
|
2034
|
+
if (trigger.maxFanout !== void 0 && ids.length > trigger.maxFanout) {
|
|
2035
|
+
throw new DerivationCapExceededError(`triggerBy ${this.name}\u2192${spec.source}`, ids.length, trigger.maxFanout);
|
|
1835
2036
|
}
|
|
2037
|
+
for (const sid of ids) {
|
|
2038
|
+
const raw = await srcColl._getStoredRecord(sid);
|
|
2039
|
+
if (raw === null) continue;
|
|
2040
|
+
runs.push({ input: { ...raw, id: sid }, base: raw, runId: sid, version: 0 });
|
|
2041
|
+
}
|
|
2042
|
+
}
|
|
2043
|
+
if (runs.length === 0) continue;
|
|
2044
|
+
if (mode !== "eager") {
|
|
2045
|
+
for (const run of runs) await markStale(registry, spec, run.runId);
|
|
2046
|
+
continue;
|
|
2047
|
+
}
|
|
2048
|
+
if (DerivationExecutor === null) {
|
|
2049
|
+
({ DerivationExecutor } = await import("./executor-OKFLQCDW.js"));
|
|
2050
|
+
}
|
|
2051
|
+
for (const run of runs) {
|
|
1836
2052
|
const ctx = { vault: this.derivationSource.getReadOnlyFacade() };
|
|
1837
|
-
const result = await DerivationExecutor.run(spec,
|
|
2053
|
+
const result = await DerivationExecutor.run(spec, run.input, run.version, strategyHash, ctx);
|
|
1838
2054
|
for (const key of Object.keys(spec.outputs)) {
|
|
1839
2055
|
const out = result.outputs[key];
|
|
1840
2056
|
if (!out) continue;
|
|
1841
2057
|
if (out.kind === "failed") {
|
|
1842
2058
|
const err = out.error;
|
|
1843
2059
|
if (spec.strict) throw err;
|
|
1844
|
-
console.warn(`[derivation] output "${key}" for source "${spec.source}" id="${
|
|
2060
|
+
console.warn(`[derivation] output "${key}" for source "${spec.source}" id="${run.runId}" failed:`, err);
|
|
1845
2061
|
continue;
|
|
1846
2062
|
}
|
|
1847
2063
|
const outSpec = spec.outputs[key];
|
|
@@ -1849,12 +2065,12 @@ var Collection = class {
|
|
|
1849
2065
|
const outputCollection = this.derivationSource.getCollection(outSpec.collection);
|
|
1850
2066
|
const txCtx = this.derivationSource.getActiveTxContext();
|
|
1851
2067
|
if (out.kind === "array") {
|
|
1852
|
-
const { loadFanoutSidecar, saveFanoutSidecar } = await import("./fanout-sidecar-
|
|
2068
|
+
const { loadFanoutSidecar, saveFanoutSidecar } = await import("./fanout-sidecar-DCQWJQ6S.js");
|
|
1853
2069
|
const prior = await loadFanoutSidecar(
|
|
1854
2070
|
this.adapter,
|
|
1855
2071
|
this.vault,
|
|
1856
2072
|
spec.source,
|
|
1857
|
-
|
|
2073
|
+
run.runId,
|
|
1858
2074
|
key
|
|
1859
2075
|
);
|
|
1860
2076
|
const prevKeys = new Set(prior?.keys ?? []);
|
|
@@ -1881,7 +2097,7 @@ var Collection = class {
|
|
|
1881
2097
|
}
|
|
1882
2098
|
await saveFanoutSidecar(this.adapter, this.vault, {
|
|
1883
2099
|
source: spec.source,
|
|
1884
|
-
sourceId:
|
|
2100
|
+
sourceId: run.runId,
|
|
1885
2101
|
outputKey: key,
|
|
1886
2102
|
outputCollection: outSpec.collection,
|
|
1887
2103
|
keys: newKeysList
|
|
@@ -1889,25 +2105,44 @@ var Collection = class {
|
|
|
1889
2105
|
continue;
|
|
1890
2106
|
}
|
|
1891
2107
|
if (out.skipped === true) {
|
|
1892
|
-
await outputCollection._internalDelete(
|
|
2108
|
+
await outputCollection._internalDelete(run.runId, txCtx);
|
|
2109
|
+
continue;
|
|
2110
|
+
}
|
|
2111
|
+
if (outSpec.shape === "record" && outSpec.denorm !== void 0 && outSpec.collection === spec.source) {
|
|
2112
|
+
const value = out.value;
|
|
2113
|
+
const patched = { ...run.base };
|
|
2114
|
+
let changed = false;
|
|
2115
|
+
for (const f of outSpec.denorm) {
|
|
2116
|
+
if (!selfWriteFieldEqual(run.base[f], value[f])) {
|
|
2117
|
+
patched[f] = value[f];
|
|
2118
|
+
changed = true;
|
|
2119
|
+
}
|
|
2120
|
+
}
|
|
2121
|
+
if (!changed) continue;
|
|
2122
|
+
if (txCtx !== null) {
|
|
2123
|
+
const prior = await this.adapter.get(this.vault, outSpec.collection, run.runId);
|
|
2124
|
+
txCtx._executed.push({
|
|
2125
|
+
op: { type: "put", vaultName: this.vault, collectionName: outSpec.collection, id: run.runId },
|
|
2126
|
+
priorEnvelope: prior
|
|
2127
|
+
});
|
|
2128
|
+
}
|
|
2129
|
+
await outputCollection.put(run.runId, patched);
|
|
1893
2130
|
continue;
|
|
1894
2131
|
}
|
|
1895
2132
|
if (txCtx !== null) {
|
|
1896
|
-
const prior = await this.adapter.get(this.vault, outSpec.collection,
|
|
2133
|
+
const prior = await this.adapter.get(this.vault, outSpec.collection, run.runId);
|
|
1897
2134
|
txCtx._executed.push({
|
|
1898
2135
|
op: {
|
|
1899
2136
|
type: "put",
|
|
1900
2137
|
vaultName: this.vault,
|
|
1901
2138
|
collectionName: outSpec.collection,
|
|
1902
|
-
id
|
|
2139
|
+
id: run.runId
|
|
1903
2140
|
},
|
|
1904
2141
|
priorEnvelope: prior
|
|
1905
2142
|
});
|
|
1906
2143
|
}
|
|
1907
|
-
await outputCollection.put(
|
|
2144
|
+
await outputCollection.put(run.runId, out.value);
|
|
1908
2145
|
}
|
|
1909
|
-
} else {
|
|
1910
|
-
await markStale(registry, spec, id);
|
|
1911
2146
|
}
|
|
1912
2147
|
}
|
|
1913
2148
|
}
|
|
@@ -2124,6 +2359,7 @@ var Collection = class {
|
|
|
2124
2359
|
if (!internal) {
|
|
2125
2360
|
await this.dispatchMaterializedViewsOnDelete(id);
|
|
2126
2361
|
await this.dispatchArrayDerivationsOnDelete(id);
|
|
2362
|
+
if (existing) await this.dispatchRollupsOnDelete(existing.record);
|
|
2127
2363
|
}
|
|
2128
2364
|
}
|
|
2129
2365
|
/**
|
|
@@ -2192,7 +2428,7 @@ var Collection = class {
|
|
|
2192
2428
|
for (const [outputKey, outSpec] of Object.entries(spec.outputs)) {
|
|
2193
2429
|
if (outSpec.shape !== "array") continue;
|
|
2194
2430
|
if (helpers === null) {
|
|
2195
|
-
helpers = await import("./fanout-sidecar-
|
|
2431
|
+
helpers = await import("./fanout-sidecar-DCQWJQ6S.js");
|
|
2196
2432
|
}
|
|
2197
2433
|
const sidecar = await helpers.loadFanoutSidecar(
|
|
2198
2434
|
this.adapter,
|
|
@@ -2232,7 +2468,7 @@ var Collection = class {
|
|
|
2232
2468
|
if (mode === "eager") {
|
|
2233
2469
|
if (executor === null) {
|
|
2234
2470
|
;
|
|
2235
|
-
({ MaterializedViewExecutor: executor } = await import("./executor-
|
|
2471
|
+
({ MaterializedViewExecutor: executor } = await import("./executor-44R5CUS2.js"));
|
|
2236
2472
|
}
|
|
2237
2473
|
await executor.refresh(reg, {
|
|
2238
2474
|
getCollection: (name) => this.materializedViewSource.getCollection(name),
|
|
@@ -2241,7 +2477,7 @@ var Collection = class {
|
|
|
2241
2477
|
});
|
|
2242
2478
|
} else if (mode === "lazy") {
|
|
2243
2479
|
if (staleHelpers === null) {
|
|
2244
|
-
staleHelpers = await import("./stale-
|
|
2480
|
+
staleHelpers = await import("./stale-NTEV5SLX.js");
|
|
2245
2481
|
}
|
|
2246
2482
|
staleHelpers.markMVStale(registry, reg.spec.name);
|
|
2247
2483
|
}
|
|
@@ -2264,7 +2500,7 @@ var Collection = class {
|
|
|
2264
2500
|
);
|
|
2265
2501
|
}
|
|
2266
2502
|
if (this.materializedViewSource !== void 0) {
|
|
2267
|
-
const { resolveStaleMVOnRead } = await import("./stale-
|
|
2503
|
+
const { resolveStaleMVOnRead } = await import("./stale-NTEV5SLX.js");
|
|
2268
2504
|
await resolveStaleMVOnRead(this.materializedViewSource, this.name);
|
|
2269
2505
|
}
|
|
2270
2506
|
await this.ensureHydrated();
|
|
@@ -2280,6 +2516,29 @@ var Collection = class {
|
|
|
2280
2516
|
hasReadTransforms() {
|
|
2281
2517
|
return this.moneyFields !== void 0 && Object.keys(this.moneyFields).length > 0 || this.i18nFields !== void 0 && Object.keys(this.i18nFields).length > 0 || this.dictKeyFields !== void 0 && Object.keys(this.dictKeyFields).length > 0;
|
|
2282
2518
|
}
|
|
2519
|
+
/**
|
|
2520
|
+
* Scan-mode full-text search over a plain-text `field` (#308). Decrypts the
|
|
2521
|
+
* collection in memory and ranks records by BM25 against the tokenized query.
|
|
2522
|
+
* **Zero added store leakage** — pure client-side scan; nothing searchable is
|
|
2523
|
+
* written to the store. (A store-usable blind index for at-scale search is a
|
|
2524
|
+
* separate, gated opt-in — see the #308 design note.) Eager mode only.
|
|
2525
|
+
*
|
|
2526
|
+
* `opts.match` (`'any'` default | `'all'`), `opts.prefix` (last query term as
|
|
2527
|
+
* a prefix → typeahead), `opts.limit` (top-N). Returns `{ id, score, record }`
|
|
2528
|
+
* ranked by descending score. The default tokenizer is word-boundary based —
|
|
2529
|
+
* see `src/search/tokenize.ts` for the Thai/CJK caveat.
|
|
2530
|
+
*/
|
|
2531
|
+
async search(field, query, opts = {}) {
|
|
2532
|
+
if (this.lazy) {
|
|
2533
|
+
throw new Error(
|
|
2534
|
+
`Collection "${this.name}": search() (scan mode) requires eager mode (prefetch: true). A store-usable blind index for lazy / at-scale search is a separate gated opt-in (#308).`
|
|
2535
|
+
);
|
|
2536
|
+
}
|
|
2537
|
+
await this.ensureHydrated();
|
|
2538
|
+
const entries = [];
|
|
2539
|
+
for (const [id, e] of this.cache) entries.push({ id, record: e.record });
|
|
2540
|
+
return searchScan(entries, field, query, opts);
|
|
2541
|
+
}
|
|
2283
2542
|
// ─── Bulk operations ─────────────────────────────────────
|
|
2284
2543
|
/**
|
|
2285
2544
|
* Put many records in one call. Each item is processed sequentially
|
|
@@ -2457,6 +2716,10 @@ var Collection = class {
|
|
|
2457
2716
|
leftCollection,
|
|
2458
2717
|
resolveRef: (field) => resolver.resolveRef(leftCollection, field),
|
|
2459
2718
|
resolveSource: (collectionName) => resolver.resolveSource(collectionName),
|
|
2719
|
+
// #285 §3 — flow the vault/collection default locale to joins so a
|
|
2720
|
+
// joined i18n field resolves like get()/list() when no per-call
|
|
2721
|
+
// locale is given; toArray({ locale }) overrides it.
|
|
2722
|
+
...this.defaultLocale !== void 0 ? { defaultLocale: this.defaultLocale } : {},
|
|
2460
2723
|
...resolver.resolveDictSource ? { resolveDictSource: (field) => resolver.resolveDictSource(leftCollection, field) } : {}
|
|
2461
2724
|
} : void 0;
|
|
2462
2725
|
return new Query(source, void 0, joinContext, this.aggregateStrategy);
|
|
@@ -2545,7 +2808,10 @@ var Collection = class {
|
|
|
2545
2808
|
};
|
|
2546
2809
|
this.emitter.on("change", handler);
|
|
2547
2810
|
return () => this.emitter.off("change", handler);
|
|
2548
|
-
}
|
|
2811
|
+
},
|
|
2812
|
+
// #285 §3 — expose this (right-side) collection's i18nText descriptors so
|
|
2813
|
+
// the join executor can resolve joined i18n fields at the `join` layer.
|
|
2814
|
+
...this.i18nFields !== void 0 ? { i18nFields: this.i18nFields } : {}
|
|
2549
2815
|
};
|
|
2550
2816
|
}
|
|
2551
2817
|
/**
|
|
@@ -2778,6 +3044,10 @@ var Collection = class {
|
|
|
2778
3044
|
leftCollection,
|
|
2779
3045
|
resolveRef: (field) => resolver.resolveRef(leftCollection, field),
|
|
2780
3046
|
resolveSource: (collectionName) => resolver.resolveSource(collectionName),
|
|
3047
|
+
// #285 §3 — flow the vault/collection default locale to joins so a
|
|
3048
|
+
// joined i18n field resolves like get()/list() when no per-call
|
|
3049
|
+
// locale is given; toArray({ locale }) overrides it.
|
|
3050
|
+
...this.defaultLocale !== void 0 ? { defaultLocale: this.defaultLocale } : {},
|
|
2781
3051
|
...resolver.resolveDictSource ? { resolveDictSource: (field) => resolver.resolveDictSource(leftCollection, field) } : {}
|
|
2782
3052
|
} : void 0;
|
|
2783
3053
|
return new ScanBuilder(
|
|
@@ -3178,14 +3448,15 @@ var Collection = class {
|
|
|
3178
3448
|
(d) => isStaticDictDescriptor(d) && d.displayLocale !== void 0
|
|
3179
3449
|
);
|
|
3180
3450
|
if (!locale && !hasStaticDisplay) return result;
|
|
3451
|
+
const layer = localeOpts?._layer ?? "read";
|
|
3181
3452
|
if (locale && hasI18n && this.i18nFields) {
|
|
3182
|
-
result = this.i18nStrategy.applyI18nLocale(result, this.i18nFields, locale, localeOpts?.fallback);
|
|
3453
|
+
result = this.i18nStrategy.applyI18nLocale(result, this.i18nFields, locale, localeOpts?.fallback, layer);
|
|
3183
3454
|
}
|
|
3184
3455
|
if (hasDict && this.dictKeyFields && this.dictLabelResolver && locale !== "raw") {
|
|
3185
3456
|
const withLabels = { ...result };
|
|
3186
3457
|
const resolver = this.dictLabelResolver;
|
|
3187
3458
|
for (const [field, desc] of Object.entries(this.dictKeyFields)) {
|
|
3188
|
-
const policy = desc.onMissing ? resolvePolicy(desc.onMissing,
|
|
3459
|
+
const policy = desc.onMissing ? resolvePolicy(desc.onMissing, layer) : "null";
|
|
3189
3460
|
const fallback = policy === "substitute" ? localeOpts?.fallback ?? desc.substitute : localeOpts?.fallback;
|
|
3190
3461
|
const effLocale = locale ?? (isStaticDictDescriptor(desc) ? desc.displayLocale : void 0);
|
|
3191
3462
|
const resolveKey = async (key) => {
|
|
@@ -3334,6 +3605,34 @@ var Collection = class {
|
|
|
3334
3605
|
}
|
|
3335
3606
|
}
|
|
3336
3607
|
}
|
|
3608
|
+
/**
|
|
3609
|
+
* @internal — hard-delete this record's persisted `_idx/<field>/<recordId>`
|
|
3610
|
+
* side-cars for the erasure path (#401). `forget()` crypto-shreds the body but
|
|
3611
|
+
* keeps the collection DEK, under which these side-cars are encrypted — so
|
|
3612
|
+
* without this they leave the indexed field VALUES readable after a "forget".
|
|
3613
|
+
*
|
|
3614
|
+
* Content-free: the side-car id is `encodeIdxId(def.key, id)`, so it needs no
|
|
3615
|
+
* body decode (the body is being shredded). Eager mode has no durable side-car
|
|
3616
|
+
* → no-op. The in-memory mirror is left as-is: it is ephemeral (rebuilt from
|
|
3617
|
+
* the now-deleted side-cars on reopen) and live reads skip the tombstone, so a
|
|
3618
|
+
* stale mirror hit cannot surface the erased record. Returns the count deleted
|
|
3619
|
+
* + the `def.key`s whose delete FAILED (residue that still leaks the value).
|
|
3620
|
+
*/
|
|
3621
|
+
async _purgePersistedIndexes(id) {
|
|
3622
|
+
const persisted = this.persistedIndexes;
|
|
3623
|
+
if (!persisted) return { purged: 0, residue: [] };
|
|
3624
|
+
let purged = 0;
|
|
3625
|
+
const residue = [];
|
|
3626
|
+
for (const def of persisted.definitions()) {
|
|
3627
|
+
try {
|
|
3628
|
+
await this.adapter.delete(this.vault, this.name, encodeIdxId(def.key, id));
|
|
3629
|
+
purged++;
|
|
3630
|
+
} catch {
|
|
3631
|
+
residue.push(def.key);
|
|
3632
|
+
}
|
|
3633
|
+
}
|
|
3634
|
+
return { purged, residue };
|
|
3635
|
+
}
|
|
3337
3636
|
/**
|
|
3338
3637
|
* Bulk-load the persisted-index mirror from `_idx/<field>/*` side-cars
|
|
3339
3638
|
* on first lazy-mode query. Idempotent — subsequent calls short-circuit
|
|
@@ -4026,6 +4325,38 @@ function withArchive(opts) {
|
|
|
4026
4325
|
// src/sequence/index.ts
|
|
4027
4326
|
var SEQUENCE_COLLECTION = "_sequences";
|
|
4028
4327
|
var MAX_NEXT_ATTEMPTS = 16;
|
|
4328
|
+
var SEQ_FORMAT_TOKEN = /\{([^{}]*)\}/g;
|
|
4329
|
+
var SEQ_PAD_TOKEN = /^seq:0(\d+)$/;
|
|
4330
|
+
var SEQ_PARTITION_TOKEN = /^partition\.(\d+)$/;
|
|
4331
|
+
function compileSequenceFormat(format, series, partition) {
|
|
4332
|
+
const parts = partition ?? [];
|
|
4333
|
+
for (const m of format.matchAll(SEQ_FORMAT_TOKEN)) {
|
|
4334
|
+
const token = m[1] ?? "";
|
|
4335
|
+
if (token === "seq") continue;
|
|
4336
|
+
if (SEQ_PAD_TOKEN.test(token)) continue;
|
|
4337
|
+
const partMatch = SEQ_PARTITION_TOKEN.exec(token);
|
|
4338
|
+
if (partMatch) {
|
|
4339
|
+
const idx = Number(partMatch[1]);
|
|
4340
|
+
if (idx >= parts.length) {
|
|
4341
|
+
throw new ValidationError(
|
|
4342
|
+
`sequence("${series}"): format token "{${token}}" references partition index ${idx}, but only ${parts.length} partition component(s) were supplied.`
|
|
4343
|
+
);
|
|
4344
|
+
}
|
|
4345
|
+
continue;
|
|
4346
|
+
}
|
|
4347
|
+
throw new ValidationError(
|
|
4348
|
+
`sequence("${series}"): format contains unknown token "{${token}}". Accepted tokens: {seq}, {seq:0N}, {partition.i}.`
|
|
4349
|
+
);
|
|
4350
|
+
}
|
|
4351
|
+
return (serial) => format.replace(SEQ_FORMAT_TOKEN, (full, token) => {
|
|
4352
|
+
if (token === "seq") return String(serial);
|
|
4353
|
+
const padMatch = SEQ_PAD_TOKEN.exec(token);
|
|
4354
|
+
if (padMatch) return String(serial).padStart(Number(padMatch[1]), "0");
|
|
4355
|
+
const partMatch = SEQ_PARTITION_TOKEN.exec(token);
|
|
4356
|
+
if (partMatch) return String(parts[Number(partMatch[1])]);
|
|
4357
|
+
return full;
|
|
4358
|
+
});
|
|
4359
|
+
}
|
|
4029
4360
|
function resolveSequenceKey(series, opts) {
|
|
4030
4361
|
const partition = opts?.partition;
|
|
4031
4362
|
if (!partition || partition.length === 0) return series;
|
|
@@ -4345,6 +4676,9 @@ var NO_PERIODS = {
|
|
|
4345
4676
|
};
|
|
4346
4677
|
|
|
4347
4678
|
// src/refs.ts
|
|
4679
|
+
function isRefArray(desc) {
|
|
4680
|
+
return desc.isArray === true;
|
|
4681
|
+
}
|
|
4348
4682
|
var RefIntegrityError = class extends NoydbError {
|
|
4349
4683
|
collection;
|
|
4350
4684
|
id;
|
|
@@ -4381,6 +4715,17 @@ function ref(target, mode = "strict") {
|
|
|
4381
4715
|
}
|
|
4382
4716
|
return { target, mode };
|
|
4383
4717
|
}
|
|
4718
|
+
function refArray(target, mode = "strict") {
|
|
4719
|
+
if (target.includes("/")) {
|
|
4720
|
+
throw new RefScopeError(target);
|
|
4721
|
+
}
|
|
4722
|
+
if (!target || target.startsWith("_")) {
|
|
4723
|
+
throw new Error(
|
|
4724
|
+
`refArray(): target collection name must be non-empty and cannot start with '_' (reserved for internal collections). Got "${target}".`
|
|
4725
|
+
);
|
|
4726
|
+
}
|
|
4727
|
+
return { target, mode, isArray: true };
|
|
4728
|
+
}
|
|
4384
4729
|
var RefRegistry = class {
|
|
4385
4730
|
outbound = /* @__PURE__ */ new Map();
|
|
4386
4731
|
inbound = /* @__PURE__ */ new Map();
|
|
@@ -4405,7 +4750,7 @@ var RefRegistry = class {
|
|
|
4405
4750
|
for (const k of existingKeys) {
|
|
4406
4751
|
const a = existing[k];
|
|
4407
4752
|
const b = refs[k];
|
|
4408
|
-
if (!a || !b || a.target !== b.target || a.mode !== b.mode) {
|
|
4753
|
+
if (!a || !b || a.target !== b.target || a.mode !== b.mode || a.isArray !== b.isArray) {
|
|
4409
4754
|
throw new Error(
|
|
4410
4755
|
`RefRegistry: conflicting ref declarations for collection "${collection}" field "${k}"`
|
|
4411
4756
|
);
|
|
@@ -4416,7 +4761,7 @@ var RefRegistry = class {
|
|
|
4416
4761
|
this.outbound.set(collection, { ...refs });
|
|
4417
4762
|
for (const [field, desc] of Object.entries(refs)) {
|
|
4418
4763
|
const list = this.inbound.get(desc.target) ?? [];
|
|
4419
|
-
list.push({ collection, field, mode: desc.mode });
|
|
4764
|
+
list.push({ collection, field, mode: desc.mode, ...desc.isArray ? { isArray: true } : {} });
|
|
4420
4765
|
this.inbound.set(desc.target, list);
|
|
4421
4766
|
}
|
|
4422
4767
|
}
|
|
@@ -4444,6 +4789,141 @@ var RefRegistry = class {
|
|
|
4444
4789
|
}
|
|
4445
4790
|
};
|
|
4446
4791
|
|
|
4792
|
+
// src/links/link-set.ts
|
|
4793
|
+
var LINK_COLLECTION_PREFIX = "_links_";
|
|
4794
|
+
function linkCollectionName(name) {
|
|
4795
|
+
return `${LINK_COLLECTION_PREFIX}${name}`;
|
|
4796
|
+
}
|
|
4797
|
+
function isLinkCollectionName(name) {
|
|
4798
|
+
return name.startsWith(LINK_COLLECTION_PREFIX);
|
|
4799
|
+
}
|
|
4800
|
+
function linkRowKey(aId, bId) {
|
|
4801
|
+
return `${encodeURIComponent(aId)}|${encodeURIComponent(bId)}`;
|
|
4802
|
+
}
|
|
4803
|
+
var LinkSet = class {
|
|
4804
|
+
constructor(adapter, vault, name, spec, encrypted, getDEK, actor, emitter, endpointExists) {
|
|
4805
|
+
this.adapter = adapter;
|
|
4806
|
+
this.vault = vault;
|
|
4807
|
+
this.name = name;
|
|
4808
|
+
this.spec = spec;
|
|
4809
|
+
this.encrypted = encrypted;
|
|
4810
|
+
this.getDEK = getDEK;
|
|
4811
|
+
this.actor = actor;
|
|
4812
|
+
this.emitter = emitter;
|
|
4813
|
+
this.endpointExists = endpointExists;
|
|
4814
|
+
this.collName = linkCollectionName(name);
|
|
4815
|
+
}
|
|
4816
|
+
adapter;
|
|
4817
|
+
vault;
|
|
4818
|
+
name;
|
|
4819
|
+
spec;
|
|
4820
|
+
encrypted;
|
|
4821
|
+
getDEK;
|
|
4822
|
+
actor;
|
|
4823
|
+
emitter;
|
|
4824
|
+
endpointExists;
|
|
4825
|
+
collName;
|
|
4826
|
+
dekPromise = null;
|
|
4827
|
+
dek() {
|
|
4828
|
+
if (!this.dekPromise) this.dekPromise = this.getDEK(this.collName);
|
|
4829
|
+
return this.dekPromise;
|
|
4830
|
+
}
|
|
4831
|
+
async encryptEntry(entry, version) {
|
|
4832
|
+
const json = JSON.stringify(entry);
|
|
4833
|
+
const base = { _noydb: NOYDB_FORMAT_VERSION, _v: version, _ts: (/* @__PURE__ */ new Date()).toISOString(), _by: this.actor };
|
|
4834
|
+
if (!this.encrypted) return { ...base, _iv: "", _data: json };
|
|
4835
|
+
const { iv, data } = await encrypt(json, await this.dek());
|
|
4836
|
+
return { ...base, _iv: iv, _data: data };
|
|
4837
|
+
}
|
|
4838
|
+
async decryptEntry(env) {
|
|
4839
|
+
const json = this.encrypted ? await decrypt(env._iv, env._data, await this.dek()) : env._data;
|
|
4840
|
+
return JSON.parse(json);
|
|
4841
|
+
}
|
|
4842
|
+
async connect(aId, bId, meta) {
|
|
4843
|
+
if (!await this.endpointExists(this.spec.a, aId)) {
|
|
4844
|
+
throw new LinkEndpointError(this.name, this.spec.a, aId);
|
|
4845
|
+
}
|
|
4846
|
+
if (!await this.endpointExists(this.spec.b, bId)) {
|
|
4847
|
+
throw new LinkEndpointError(this.name, this.spec.b, bId);
|
|
4848
|
+
}
|
|
4849
|
+
const key = linkRowKey(aId, bId);
|
|
4850
|
+
const entry = meta !== void 0 ? { a: aId, b: bId, meta } : { a: aId, b: bId };
|
|
4851
|
+
const existing = await this.adapter.get(this.vault, this.collName, key);
|
|
4852
|
+
const env = await this.encryptEntry(entry, (existing?._v ?? 0) + 1);
|
|
4853
|
+
await this.adapter.put(this.vault, this.collName, key, env, existing?._v);
|
|
4854
|
+
this.emitter.emit("change", { vault: this.vault, collection: this.collName, id: key, action: "put" });
|
|
4855
|
+
}
|
|
4856
|
+
async disconnect(aId, bId) {
|
|
4857
|
+
const key = linkRowKey(aId, bId);
|
|
4858
|
+
const existing = await this.adapter.get(this.vault, this.collName, key);
|
|
4859
|
+
if (!existing) return;
|
|
4860
|
+
await this.adapter.delete(this.vault, this.collName, key);
|
|
4861
|
+
this.emitter.emit("change", { vault: this.vault, collection: this.collName, id: key, action: "delete" });
|
|
4862
|
+
}
|
|
4863
|
+
async has(aId, bId) {
|
|
4864
|
+
return await this.adapter.get(this.vault, this.collName, linkRowKey(aId, bId)) !== null;
|
|
4865
|
+
}
|
|
4866
|
+
async of(id) {
|
|
4867
|
+
const rows = await this.list();
|
|
4868
|
+
return rows.filter((r) => r.a === id || r.b === id);
|
|
4869
|
+
}
|
|
4870
|
+
async list() {
|
|
4871
|
+
const keys = await this.adapter.list(this.vault, this.collName);
|
|
4872
|
+
const out = [];
|
|
4873
|
+
for (const key of keys) {
|
|
4874
|
+
const env = await this.adapter.get(this.vault, this.collName, key);
|
|
4875
|
+
if (!env) continue;
|
|
4876
|
+
const e = await this.decryptEntry(env);
|
|
4877
|
+
out.push(e.meta !== void 0 ? { a: e.a, b: e.b, meta: e.meta } : { a: e.a, b: e.b });
|
|
4878
|
+
}
|
|
4879
|
+
return out;
|
|
4880
|
+
}
|
|
4881
|
+
// ── Vault-internal cascade helpers ──────────────────────────────────
|
|
4882
|
+
/** @internal — rows where the deleted endpoint id matches the relevant slot. */
|
|
4883
|
+
async _rowsTouchingEndpoint(collection, id) {
|
|
4884
|
+
const rows = await this.list();
|
|
4885
|
+
return rows.filter(
|
|
4886
|
+
(r) => this.spec.a === collection && r.a === id || this.spec.b === collection && r.b === id
|
|
4887
|
+
);
|
|
4888
|
+
}
|
|
4889
|
+
/** @internal — the storage collection name (for tx pre-image capture). */
|
|
4890
|
+
get _collectionName() {
|
|
4891
|
+
return this.collName;
|
|
4892
|
+
}
|
|
4893
|
+
};
|
|
4894
|
+
var LinkEndpointError = class extends NoydbError {
|
|
4895
|
+
link;
|
|
4896
|
+
endpoint;
|
|
4897
|
+
missingId;
|
|
4898
|
+
constructor(link, endpoint, missingId) {
|
|
4899
|
+
super(
|
|
4900
|
+
"LINK_ENDPOINT",
|
|
4901
|
+
`link("${link}").connect: endpoint "${endpoint}" has no record "${missingId}".`
|
|
4902
|
+
);
|
|
4903
|
+
this.name = "LinkEndpointError";
|
|
4904
|
+
this.link = link;
|
|
4905
|
+
this.endpoint = endpoint;
|
|
4906
|
+
this.missingId = missingId;
|
|
4907
|
+
}
|
|
4908
|
+
};
|
|
4909
|
+
var LinkIntegrityError = class extends NoydbError {
|
|
4910
|
+
link;
|
|
4911
|
+
endpoint;
|
|
4912
|
+
id;
|
|
4913
|
+
count;
|
|
4914
|
+
constructor(link, endpoint, id, count) {
|
|
4915
|
+
super(
|
|
4916
|
+
"LINK_INTEGRITY",
|
|
4917
|
+
`Cannot delete "${endpoint}"/"${id}": ${count} link(s) in "${link}" still reference it (onDelete: 'strict').`
|
|
4918
|
+
);
|
|
4919
|
+
this.name = "LinkIntegrityError";
|
|
4920
|
+
this.link = link;
|
|
4921
|
+
this.endpoint = endpoint;
|
|
4922
|
+
this.id = id;
|
|
4923
|
+
this.count = count;
|
|
4924
|
+
}
|
|
4925
|
+
};
|
|
4926
|
+
|
|
4447
4927
|
// src/meta/user-envelope/api.ts
|
|
4448
4928
|
var UserApi = class {
|
|
4449
4929
|
constructor(adapter, vaultName, writerKeyringId, getDek, checkGate2) {
|
|
@@ -5468,13 +5948,17 @@ var Vault = class {
|
|
|
5468
5948
|
*/
|
|
5469
5949
|
overlayedViewRegistry = null;
|
|
5470
5950
|
/**
|
|
5471
|
-
* Cached read-only
|
|
5472
|
-
* and to derivation callbacks via `derive(source, ctx)`.
|
|
5473
|
-
*
|
|
5951
|
+
* Cached read-only facades handed to guard callbacks via `ctx.vault`
|
|
5952
|
+
* and to derivation callbacks via `derive(source, ctx)`. Split by
|
|
5953
|
+
* resolution layer (#285): the guard facade reads at `layer:'guard'`,
|
|
5954
|
+
* the derivation facade at `layer:'derivation'`, so i18nText / dictKey
|
|
5955
|
+
* fields resolve under that layer's `onMissing` policy. Allocated
|
|
5956
|
+
* eagerly inside `_initGuards()` / `_initDerivations()` so read
|
|
5474
5957
|
* accessors stay synchronous (callers in `tx/transaction.ts` rely on
|
|
5475
|
-
* that).
|
|
5958
|
+
* that). Each stays `null` for vaults without that subsystem.
|
|
5476
5959
|
*/
|
|
5477
|
-
|
|
5960
|
+
guardFacade = null;
|
|
5961
|
+
derivationFacade = null;
|
|
5478
5962
|
getDEK;
|
|
5479
5963
|
/**
|
|
5480
5964
|
* Per-principal user envelope API.
|
|
@@ -5636,6 +6120,10 @@ var Vault = class {
|
|
|
5636
6120
|
i18nFieldRegistry = /* @__PURE__ */ new Map();
|
|
5637
6121
|
/** Cache of DictionaryHandle instances, one per dictionary name. */
|
|
5638
6122
|
dictionaryCache = /* @__PURE__ */ new Map();
|
|
6123
|
+
/** Registered link specs (#377-B), keyed by link name; set by `vault.link()`. */
|
|
6124
|
+
linkRegistry = /* @__PURE__ */ new Map();
|
|
6125
|
+
/** Cache of LinkSet handles, one per link name. */
|
|
6126
|
+
linkSetCache = /* @__PURE__ */ new Map();
|
|
5639
6127
|
/** — subscribers for cross-tier access events. */
|
|
5640
6128
|
crossTierSubs = /* @__PURE__ */ new Set();
|
|
5641
6129
|
/** — currently-active elevation, or null. One per vault. */
|
|
@@ -5752,6 +6240,9 @@ var Vault = class {
|
|
|
5752
6240
|
if (collectionName === SEQUENCE_COLLECTION) {
|
|
5753
6241
|
throw new ReservedCollectionNameError(collectionName);
|
|
5754
6242
|
}
|
|
6243
|
+
if (isLinkCollectionName(collectionName)) {
|
|
6244
|
+
throw new ReservedCollectionNameError(collectionName);
|
|
6245
|
+
}
|
|
5755
6246
|
let coll = this.collectionCache.get(collectionName);
|
|
5756
6247
|
if (coll && options?.moneyFields) {
|
|
5757
6248
|
coll._applyMoneyFields(options.moneyFields);
|
|
@@ -5823,6 +6314,7 @@ var Vault = class {
|
|
|
5823
6314
|
}));
|
|
5824
6315
|
schemaUpdateGate = new SchemaUpdateGate(work);
|
|
5825
6316
|
}
|
|
6317
|
+
const effectiveHistoryConfig = options?.historyConfig ?? this.historyConfig;
|
|
5826
6318
|
const collOpts = {
|
|
5827
6319
|
adapter: this.adapter,
|
|
5828
6320
|
vault: this.name,
|
|
@@ -5838,7 +6330,7 @@ var Vault = class {
|
|
|
5838
6330
|
schemaFence: this.schemaFence,
|
|
5839
6331
|
getDEK: this.getDEK,
|
|
5840
6332
|
onDirty: this.onDirty,
|
|
5841
|
-
historyConfig:
|
|
6333
|
+
historyConfig: effectiveHistoryConfig,
|
|
5842
6334
|
// thread the vault-wide blob strategy into every
|
|
5843
6335
|
// collection. `undefined` is intentionally preserved so the
|
|
5844
6336
|
// Collection constructor uses its NO_BLOBS default.
|
|
@@ -5849,7 +6341,11 @@ var Vault = class {
|
|
|
5849
6341
|
historyStrategy: this.historyStrategy,
|
|
5850
6342
|
i18nStrategy: this.i18nStrategy,
|
|
5851
6343
|
syncStrategy: this.syncStrategy,
|
|
5852
|
-
ledger
|
|
6344
|
+
// Per-collection ledger opt-out (#361): when this collection sets
|
|
6345
|
+
// `historyConfig.ledger: false`, withhold the ledger reference so all
|
|
6346
|
+
// four `if (this.ledger)` append sites in Collection no-op. The chain
|
|
6347
|
+
// stays valid — it simply never receives this collection's entries.
|
|
6348
|
+
ledger: effectiveHistoryConfig.ledger === false ? void 0 : this.getLedgerOrNull() ?? void 0,
|
|
5853
6349
|
refEnforcer: this,
|
|
5854
6350
|
joinResolver: this,
|
|
5855
6351
|
defaultLocale: this.locale,
|
|
@@ -6210,6 +6706,68 @@ var Vault = class {
|
|
|
6210
6706
|
}
|
|
6211
6707
|
return handle;
|
|
6212
6708
|
}
|
|
6709
|
+
/**
|
|
6710
|
+
* Declare a managed many-to-many link set (#377-B). Registers a
|
|
6711
|
+
* `_links_<name>` junction between two endpoint collections; access its
|
|
6712
|
+
* rows via `vault.links(name)`. Idempotent for an identical re-declaration;
|
|
6713
|
+
* a conflicting one throws. See {@link links}.
|
|
6714
|
+
*
|
|
6715
|
+
* ```ts
|
|
6716
|
+
* vault.link('saleLineLinks', { a: ref('saleLines'), b: ref('purchaseLines'), onDelete: 'cascade' })
|
|
6717
|
+
* ```
|
|
6718
|
+
*
|
|
6719
|
+
* `a` / `b` accept either a collection name or a `ref(target)` descriptor
|
|
6720
|
+
* (only its `target` is used — links manage their own integrity). `onDelete`
|
|
6721
|
+
* governs what happens to link rows when an endpoint record is deleted
|
|
6722
|
+
* (`'cascade'` default, `'strict'`, `'warn'`).
|
|
6723
|
+
*/
|
|
6724
|
+
link(name, spec) {
|
|
6725
|
+
const a = typeof spec.a === "string" ? spec.a : spec.a.target;
|
|
6726
|
+
const b = typeof spec.b === "string" ? spec.b : spec.b.target;
|
|
6727
|
+
for (const [slot, target] of [["a", a], ["b", b]]) {
|
|
6728
|
+
if (!target || target.startsWith("_") || target.includes("/")) {
|
|
6729
|
+
throw new ValidationError(
|
|
6730
|
+
`vault.link("${name}"): endpoint "${slot}" must be a simple collection name, got "${target}".`
|
|
6731
|
+
);
|
|
6732
|
+
}
|
|
6733
|
+
}
|
|
6734
|
+
const resolved = { a, b, ...spec.onDelete ? { onDelete: spec.onDelete } : {} };
|
|
6735
|
+
const existing = this.linkRegistry.get(name);
|
|
6736
|
+
if (existing) {
|
|
6737
|
+
if (existing.a !== resolved.a || existing.b !== resolved.b || (existing.onDelete ?? "cascade") !== (resolved.onDelete ?? "cascade")) {
|
|
6738
|
+
throw new ValidationError(`vault.link("${name}"): conflicting re-declaration.`);
|
|
6739
|
+
}
|
|
6740
|
+
return;
|
|
6741
|
+
}
|
|
6742
|
+
this.linkRegistry.set(name, resolved);
|
|
6743
|
+
}
|
|
6744
|
+
/**
|
|
6745
|
+
* Access a declared link set (#377-B). Throws if `name` was not first
|
|
6746
|
+
* declared via {@link link}. Returns a cached {@link LinkSetHandle}:
|
|
6747
|
+
* `connect(a, b, meta?)`, `disconnect(a, b)`, `has(a, b)`, `of(id)`, `list()`.
|
|
6748
|
+
*/
|
|
6749
|
+
links(name) {
|
|
6750
|
+
let handle = this.linkSetCache.get(name);
|
|
6751
|
+
if (!handle) {
|
|
6752
|
+
const spec = this.linkRegistry.get(name);
|
|
6753
|
+
if (!spec) {
|
|
6754
|
+
throw new ValidationError(`vault.links("${name}"): not declared. Call vault.link("${name}", { a, b }) first.`);
|
|
6755
|
+
}
|
|
6756
|
+
handle = new LinkSet(
|
|
6757
|
+
this.adapter,
|
|
6758
|
+
this.name,
|
|
6759
|
+
name,
|
|
6760
|
+
spec,
|
|
6761
|
+
this.encrypted,
|
|
6762
|
+
this.getDEK,
|
|
6763
|
+
this.keyring.userId,
|
|
6764
|
+
this.emitter,
|
|
6765
|
+
async (collection, id) => await this.collection(collection).get(id) !== null
|
|
6766
|
+
);
|
|
6767
|
+
this.linkSetCache.set(name, handle);
|
|
6768
|
+
}
|
|
6769
|
+
return handle;
|
|
6770
|
+
}
|
|
6213
6771
|
/**
|
|
6214
6772
|
* Build a `JoinableSource` for a dictKey field, for use in dict joins
|
|
6215
6773
|
*. Returns a source whose snapshot contains `{ key, ...labels }`
|
|
@@ -6369,65 +6927,16 @@ var Vault = class {
|
|
|
6369
6927
|
});
|
|
6370
6928
|
}
|
|
6371
6929
|
}
|
|
6372
|
-
/**
|
|
6373
|
-
* Bulk blob extraction primitive.
|
|
6374
|
-
*
|
|
6375
|
-
* Returns an async-iterable handle over every blob attached to
|
|
6376
|
-
* records in the vault. Single capability check (`plaintext/blob`)
|
|
6377
|
-
* at handle creation; single audit entry to `_export_audit` before
|
|
6378
|
-
* the first yield. Per-blob decryption happens lazily as the
|
|
6379
|
-
* consumer pulls tuples.
|
|
6380
|
-
*
|
|
6381
|
-
* ```ts
|
|
6382
|
-
* const handle = vault.exportBlobs({
|
|
6383
|
-
* collections: ['invoiceScans'],
|
|
6384
|
-
* where: (rec) => (rec as { clientId?: string }).clientId === 'c-123',
|
|
6385
|
-
* })
|
|
6386
|
-
* for await (const { bytes, meta, recordRef } of handle) {
|
|
6387
|
-
* await uploadToColdStorage(bytes, recordRef)
|
|
6388
|
-
* }
|
|
6389
|
-
* ```
|
|
6390
|
-
*
|
|
6391
|
-
* @see `@noy-db/hub/store/export-blobs` for the full option surface.
|
|
6392
|
-
*/
|
|
6393
|
-
/**
|
|
6394
|
-
* Evict blob slots per the per-collection `blobFields` retention
|
|
6395
|
-
* policy.
|
|
6396
|
-
*
|
|
6397
|
-
* Iterates every collection declared with `{ blobFields: {...} }`.
|
|
6398
|
-
* For each record, checks every configured slot against its
|
|
6399
|
-
* policy — `retainDays` (age-based TTL) and/or `evictWhen(record)`
|
|
6400
|
-
* (predicate) — and evicts matching slots. Every eviction writes
|
|
6401
|
-
* one entry to `_blob_eviction_audit` (actor + eTag + reason +
|
|
6402
|
-
* timestamp, no plaintext). Consumer-scheduled; noy-db never runs
|
|
6403
|
-
* this on its own.
|
|
6404
|
-
*
|
|
6405
|
-
* ```ts
|
|
6406
|
-
* await vault.compact() // run full pass
|
|
6407
|
-
* await vault.compact({ dryRun: true }) // preview counts
|
|
6408
|
-
* await vault.compact({ maxEvictions: 1000 }) // cap batch
|
|
6409
|
-
* ```
|
|
6410
|
-
*/
|
|
6411
|
-
/**
|
|
6412
|
-
* Atomic, gap-free numbering. `vault.sequence('invoice-2026').next()`
|
|
6413
|
-
* returns 1, 2, 3, … with no gaps or duplicates under concurrency, via
|
|
6414
|
-
* an optimistic-CAS counter at `_sequences/<name>`. Each name is an
|
|
6415
|
-
* independent sequence.
|
|
6416
|
-
*
|
|
6417
|
-
* **Online-only:** `next()` throws `SequenceOfflineError` unless the
|
|
6418
|
-
* store advertises `capabilities.casAtomic` — gap-free numbering cannot
|
|
6419
|
-
* be serialized by an offline / non-CAS writer.
|
|
6420
|
-
*
|
|
6421
|
-
* ```ts
|
|
6422
|
-
* const n = await vault.sequence('invoice-2026').next() // 1, then 2, …
|
|
6423
|
-
* const cur = await vault.sequence('invoice-2026').peek() // current value, no allocation
|
|
6424
|
-
* ```
|
|
6425
|
-
*/
|
|
6426
6930
|
sequence(series, opts) {
|
|
6427
6931
|
if (series.includes("\0")) {
|
|
6428
6932
|
throw new ValidationError(`sequence("${series}"): series name must not contain a null byte (\\x00).`);
|
|
6429
6933
|
}
|
|
6430
6934
|
if (this.numberingConfigs.has(series)) {
|
|
6935
|
+
if (opts?.format !== void 0) {
|
|
6936
|
+
throw new ValidationError(
|
|
6937
|
+
`sequence("${series}") is a deferred-numbering series; the format option applies to CAS sequences only.`
|
|
6938
|
+
);
|
|
6939
|
+
}
|
|
6431
6940
|
const eng = this.deferred();
|
|
6432
6941
|
return {
|
|
6433
6942
|
next: async (nextOpts) => {
|
|
@@ -6451,7 +6960,17 @@ var Vault = class {
|
|
|
6451
6960
|
actor: this.keyring.userId
|
|
6452
6961
|
});
|
|
6453
6962
|
}
|
|
6454
|
-
|
|
6963
|
+
const handle = this.sequenceStore.handle(resolveSequenceKey(series, opts));
|
|
6964
|
+
if (opts?.format === void 0) return handle;
|
|
6965
|
+
const render = compileSequenceFormat(opts.format, series, opts.partition);
|
|
6966
|
+
return {
|
|
6967
|
+
next: async (nextOpts) => {
|
|
6968
|
+
const serial = await handle.next(nextOpts);
|
|
6969
|
+
return { serial, formatted: render(serial) };
|
|
6970
|
+
},
|
|
6971
|
+
peek: () => handle.peek(),
|
|
6972
|
+
seedTo: (n) => handle.seedTo(n)
|
|
6973
|
+
};
|
|
6455
6974
|
}
|
|
6456
6975
|
/** @internal — lazily build the deferred-numbering engine with a cache-coherent stamp. */
|
|
6457
6976
|
deferred() {
|
|
@@ -6566,12 +7085,12 @@ var Vault = class {
|
|
|
6566
7085
|
if (!fieldSchema) {
|
|
6567
7086
|
throw new AttestationError(`issueAttestation: collection '${collectionName}' has no attestation field-schema. Declare it via vault.collection('${collectionName}', { attestation: { fields: [...] } }).`);
|
|
6568
7087
|
}
|
|
6569
|
-
const { issueAttestationCore } = await import("./issue-
|
|
7088
|
+
const { issueAttestationCore } = await import("./issue-EPA2PSWP.js");
|
|
6570
7089
|
const out = await issueAttestationCore(this.makeIssueContext(), { collection: collectionName, id, fieldSchema });
|
|
6571
7090
|
return { docId: out.docId, qr: out.qr, keyId: out.keyId, publicKeyB64: out.publicKeyB64 };
|
|
6572
7091
|
}
|
|
6573
7092
|
async getDocumentSigningPublicKey() {
|
|
6574
|
-
const { loadSigner, loadOrCreateSigner } = await import("./signer-
|
|
7093
|
+
const { loadSigner, loadOrCreateSigner } = await import("./signer-UNWOUJAK.js");
|
|
6575
7094
|
const existing = await loadSigner(this.adapter, this.name, this.getDEK);
|
|
6576
7095
|
if (existing) return { keyId: existing.keyId, publicKeyB64: existing.publicKeyB64 };
|
|
6577
7096
|
if (this.keyring.role !== "owner") {
|
|
@@ -6597,19 +7116,19 @@ var Vault = class {
|
|
|
6597
7116
|
};
|
|
6598
7117
|
}
|
|
6599
7118
|
async revokeAttestation(docId) {
|
|
6600
|
-
const { revokeDocCore } = await import("./revoke-
|
|
7119
|
+
const { revokeDocCore } = await import("./revoke-IFLXEZA5.js");
|
|
6601
7120
|
await revokeDocCore(this.makeRevokeContext(), docId);
|
|
6602
7121
|
}
|
|
6603
7122
|
async unrevokeAttestation(docId) {
|
|
6604
|
-
const { unrevokeDocCore } = await import("./revoke-
|
|
7123
|
+
const { unrevokeDocCore } = await import("./revoke-IFLXEZA5.js");
|
|
6605
7124
|
await unrevokeDocCore(this.makeRevokeContext(), docId);
|
|
6606
7125
|
}
|
|
6607
7126
|
async getRevokedDocIds() {
|
|
6608
|
-
const { getRevokedDocIdsCore } = await import("./revoke-
|
|
7127
|
+
const { getRevokedDocIdsCore } = await import("./revoke-IFLXEZA5.js");
|
|
6609
7128
|
return getRevokedDocIdsCore(this.makeRevokeContext());
|
|
6610
7129
|
}
|
|
6611
7130
|
async publishRevocationList() {
|
|
6612
|
-
const { publishRevocationListCore } = await import("./revoke-
|
|
7131
|
+
const { publishRevocationListCore } = await import("./revoke-IFLXEZA5.js");
|
|
6613
7132
|
return publishRevocationListCore(this.makeRevokeContext());
|
|
6614
7133
|
}
|
|
6615
7134
|
makeRevokeContext() {
|
|
@@ -6678,6 +7197,43 @@ var Vault = class {
|
|
|
6678
7197
|
if (descriptor.mode !== "strict") continue;
|
|
6679
7198
|
const rawId = obj[field];
|
|
6680
7199
|
if (rawId === null || rawId === void 0) continue;
|
|
7200
|
+
if (isRefArray(descriptor)) {
|
|
7201
|
+
if (!Array.isArray(rawId)) {
|
|
7202
|
+
throw new RefIntegrityError({
|
|
7203
|
+
collection: collectionName,
|
|
7204
|
+
id: obj["id"] ?? "<unknown>",
|
|
7205
|
+
field,
|
|
7206
|
+
refTo: descriptor.target,
|
|
7207
|
+
refId: null,
|
|
7208
|
+
message: `Array ref field "${collectionName}.${field}" must be an array, got ${typeof rawId}.`
|
|
7209
|
+
});
|
|
7210
|
+
}
|
|
7211
|
+
const arrTarget = this.collection(descriptor.target);
|
|
7212
|
+
for (const el of rawId) {
|
|
7213
|
+
if (typeof el !== "string" && typeof el !== "number") {
|
|
7214
|
+
throw new RefIntegrityError({
|
|
7215
|
+
collection: collectionName,
|
|
7216
|
+
id: obj["id"] ?? "<unknown>",
|
|
7217
|
+
field,
|
|
7218
|
+
refTo: descriptor.target,
|
|
7219
|
+
refId: null,
|
|
7220
|
+
message: `Array ref "${collectionName}.${field}" elements must be strings or numbers, got ${typeof el}.`
|
|
7221
|
+
});
|
|
7222
|
+
}
|
|
7223
|
+
const elId = String(el);
|
|
7224
|
+
if (!await arrTarget.get(elId)) {
|
|
7225
|
+
throw new RefIntegrityError({
|
|
7226
|
+
collection: collectionName,
|
|
7227
|
+
id: obj["id"] ?? "<unknown>",
|
|
7228
|
+
field,
|
|
7229
|
+
refTo: descriptor.target,
|
|
7230
|
+
refId: elId,
|
|
7231
|
+
message: `Strict array ref "${collectionName}.${field}" \u2192 "${descriptor.target}" cannot be satisfied: element id "${elId}" not found in "${descriptor.target}".`
|
|
7232
|
+
});
|
|
7233
|
+
}
|
|
7234
|
+
}
|
|
7235
|
+
continue;
|
|
7236
|
+
}
|
|
6681
7237
|
if (typeof rawId !== "string" && typeof rawId !== "number") {
|
|
6682
7238
|
throw new RefIntegrityError({
|
|
6683
7239
|
collection: collectionName,
|
|
@@ -6727,6 +7283,11 @@ var Vault = class {
|
|
|
6727
7283
|
const allRecords = await fromCollection.list();
|
|
6728
7284
|
const matches = allRecords.filter((rec) => {
|
|
6729
7285
|
const raw = rec[rule.field];
|
|
7286
|
+
if (rule.isArray) {
|
|
7287
|
+
return Array.isArray(raw) && raw.some(
|
|
7288
|
+
(el) => (typeof el === "string" || typeof el === "number") && String(el) === id
|
|
7289
|
+
);
|
|
7290
|
+
}
|
|
6730
7291
|
if (typeof raw !== "string" && typeof raw !== "number") return false;
|
|
6731
7292
|
return String(raw) === id;
|
|
6732
7293
|
});
|
|
@@ -6765,10 +7326,45 @@ var Vault = class {
|
|
|
6765
7326
|
}
|
|
6766
7327
|
}
|
|
6767
7328
|
}
|
|
7329
|
+
await this.enforceLinksOnDelete(collectionName, id);
|
|
6768
7330
|
} finally {
|
|
6769
7331
|
this.cascadeInProgress.delete(key);
|
|
6770
7332
|
}
|
|
6771
7333
|
}
|
|
7334
|
+
/**
|
|
7335
|
+
* @internal — apply link `onDelete` policy when an endpoint record is
|
|
7336
|
+
* deleted (#377-B). `'strict'` throws (blocks the delete), `'cascade'`
|
|
7337
|
+
* removes the touching link rows (tx-atomic when a transaction is active),
|
|
7338
|
+
* `'warn'` leaves orphans for `checkIntegrity()`.
|
|
7339
|
+
*/
|
|
7340
|
+
async enforceLinksOnDelete(collectionName, id) {
|
|
7341
|
+
for (const [name, spec] of this.linkRegistry) {
|
|
7342
|
+
if (spec.a !== collectionName && spec.b !== collectionName) continue;
|
|
7343
|
+
const handle = this.links(name);
|
|
7344
|
+
const touching = await handle._rowsTouchingEndpoint(collectionName, id);
|
|
7345
|
+
if (touching.length === 0) continue;
|
|
7346
|
+
const mode = spec.onDelete ?? "cascade";
|
|
7347
|
+
if (mode === "warn") continue;
|
|
7348
|
+
if (mode === "strict") {
|
|
7349
|
+
throw new LinkIntegrityError(name, collectionName, id, touching.length);
|
|
7350
|
+
}
|
|
7351
|
+
const linkColl = handle._collectionName;
|
|
7352
|
+
const txCtx = this.noydb._activeTxContextOrNull;
|
|
7353
|
+
for (const row of touching) {
|
|
7354
|
+
const rowKey = linkRowKey(row.a, row.b);
|
|
7355
|
+
if (txCtx !== null) {
|
|
7356
|
+
const prior = await this.adapter.get(this.name, linkColl, rowKey);
|
|
7357
|
+
if (prior !== null) {
|
|
7358
|
+
txCtx._executed.push({
|
|
7359
|
+
op: { type: "delete", vaultName: this.name, collectionName: linkColl, id: rowKey },
|
|
7360
|
+
priorEnvelope: prior
|
|
7361
|
+
});
|
|
7362
|
+
}
|
|
7363
|
+
}
|
|
7364
|
+
await handle.disconnect(row.a, row.b);
|
|
7365
|
+
}
|
|
7366
|
+
}
|
|
7367
|
+
}
|
|
6772
7368
|
// ─── Join resolver) ────────────────────
|
|
6773
7369
|
/**
|
|
6774
7370
|
* Look up the `RefDescriptor` the left collection declared for a
|
|
@@ -6829,6 +7425,23 @@ var Vault = class {
|
|
|
6829
7425
|
for (const [field, descriptor] of Object.entries(refs)) {
|
|
6830
7426
|
const rawId = record[field];
|
|
6831
7427
|
if (rawId === null || rawId === void 0) continue;
|
|
7428
|
+
const target = this.collection(descriptor.target);
|
|
7429
|
+
if (isRefArray(descriptor)) {
|
|
7430
|
+
if (!Array.isArray(rawId)) {
|
|
7431
|
+
violations.push({ collection: collectionName, id: recId, field, refTo: descriptor.target, refId: rawId, mode: descriptor.mode });
|
|
7432
|
+
continue;
|
|
7433
|
+
}
|
|
7434
|
+
for (const el of rawId) {
|
|
7435
|
+
if (typeof el !== "string" && typeof el !== "number") {
|
|
7436
|
+
violations.push({ collection: collectionName, id: recId, field, refTo: descriptor.target, refId: el, mode: descriptor.mode });
|
|
7437
|
+
continue;
|
|
7438
|
+
}
|
|
7439
|
+
if (!await target.get(String(el))) {
|
|
7440
|
+
violations.push({ collection: collectionName, id: recId, field, refTo: descriptor.target, refId: el, mode: descriptor.mode });
|
|
7441
|
+
}
|
|
7442
|
+
}
|
|
7443
|
+
continue;
|
|
7444
|
+
}
|
|
6832
7445
|
if (typeof rawId !== "string" && typeof rawId !== "number") {
|
|
6833
7446
|
violations.push({
|
|
6834
7447
|
collection: collectionName,
|
|
@@ -6841,7 +7454,6 @@ var Vault = class {
|
|
|
6841
7454
|
continue;
|
|
6842
7455
|
}
|
|
6843
7456
|
const refId = String(rawId);
|
|
6844
|
-
const target = this.collection(descriptor.target);
|
|
6845
7457
|
const exists = await target.get(refId);
|
|
6846
7458
|
if (!exists) {
|
|
6847
7459
|
violations.push({
|
|
@@ -6856,6 +7468,19 @@ var Vault = class {
|
|
|
6856
7468
|
}
|
|
6857
7469
|
}
|
|
6858
7470
|
}
|
|
7471
|
+
for (const [name, spec] of this.linkRegistry) {
|
|
7472
|
+
const linkColl = linkCollectionName(name);
|
|
7473
|
+
const rows = await this.links(name).list();
|
|
7474
|
+
for (const row of rows) {
|
|
7475
|
+
const rowKey = linkRowKey(row.a, row.b);
|
|
7476
|
+
if (await this.collection(spec.a).get(row.a) === null) {
|
|
7477
|
+
violations.push({ collection: linkColl, id: rowKey, field: "a", refTo: spec.a, refId: row.a, mode: spec.onDelete ?? "cascade" });
|
|
7478
|
+
}
|
|
7479
|
+
if (await this.collection(spec.b).get(row.b) === null) {
|
|
7480
|
+
violations.push({ collection: linkColl, id: rowKey, field: "b", refTo: spec.b, refId: row.b, mode: spec.onDelete ?? "cascade" });
|
|
7481
|
+
}
|
|
7482
|
+
}
|
|
7483
|
+
}
|
|
6859
7484
|
return { violations };
|
|
6860
7485
|
}
|
|
6861
7486
|
/**
|
|
@@ -6962,6 +7587,8 @@ var Vault = class {
|
|
|
6962
7587
|
const blobResidueCollections = /* @__PURE__ */ new Set();
|
|
6963
7588
|
let blobsShredded = 0;
|
|
6964
7589
|
let blobsRetainedShared = 0;
|
|
7590
|
+
let indexPostingsPurged = 0;
|
|
7591
|
+
const indexResidue = [];
|
|
6965
7592
|
const blobsEnabled = this.blobStrategy !== void 0;
|
|
6966
7593
|
const actor = this.keyring.userId;
|
|
6967
7594
|
for (const ref2 of refs) {
|
|
@@ -6983,6 +7610,9 @@ var Vault = class {
|
|
|
6983
7610
|
ref2.id,
|
|
6984
7611
|
actor
|
|
6985
7612
|
);
|
|
7613
|
+
const idxPurge = await coll._purgePersistedIndexes(ref2.id);
|
|
7614
|
+
indexPostingsPurged += idxPurge.purged;
|
|
7615
|
+
for (const field of idxPurge.residue) indexResidue.push(`${ref2.collection}:${ref2.id}:${field}`);
|
|
6986
7616
|
if (blobsEnabled) {
|
|
6987
7617
|
const r = await this.collection(ref2.collection).blob(ref2.id).shredAllForRecord();
|
|
6988
7618
|
blobsShredded += r.shredded.length;
|
|
@@ -7018,7 +7648,9 @@ var Vault = class {
|
|
|
7018
7648
|
unmigratedCount: unmigratedRecords.length,
|
|
7019
7649
|
blobsShredded,
|
|
7020
7650
|
blobsRetainedShared,
|
|
7021
|
-
blobResidueCollections: [...blobResidueCollections]
|
|
7651
|
+
blobResidueCollections: [...blobResidueCollections],
|
|
7652
|
+
indexPostingsPurged,
|
|
7653
|
+
indexResidueCount: indexResidue.length
|
|
7022
7654
|
})
|
|
7023
7655
|
});
|
|
7024
7656
|
return {
|
|
@@ -7030,6 +7662,8 @@ var Vault = class {
|
|
|
7030
7662
|
blobsShredded,
|
|
7031
7663
|
blobsRetainedShared,
|
|
7032
7664
|
blobResidueCollections: [...blobResidueCollections],
|
|
7665
|
+
indexPostingsPurged,
|
|
7666
|
+
indexResidue,
|
|
7033
7667
|
ledgerEntry
|
|
7034
7668
|
};
|
|
7035
7669
|
}
|
|
@@ -7126,12 +7760,12 @@ var Vault = class {
|
|
|
7126
7760
|
if (handles.length === 0) return;
|
|
7127
7761
|
const [{ GuardRegistry }, { ReadOnlyVaultFacade }] = await Promise.all([
|
|
7128
7762
|
import("./registry-DKEXOJVO.js"),
|
|
7129
|
-
import("./read-only-facade-
|
|
7763
|
+
import("./read-only-facade-EX6WZZBP.js")
|
|
7130
7764
|
]);
|
|
7131
7765
|
const registry = new GuardRegistry();
|
|
7132
7766
|
for (const h of handles) registry.register(h.spec);
|
|
7133
7767
|
this.guardRegistry = registry;
|
|
7134
|
-
this.
|
|
7768
|
+
this.guardFacade = new ReadOnlyVaultFacade(this, "guard");
|
|
7135
7769
|
}
|
|
7136
7770
|
/**
|
|
7137
7771
|
* @internal — The gate handler in Noydb.#registerGuardGate calls into
|
|
@@ -7153,8 +7787,8 @@ var Vault = class {
|
|
|
7153
7787
|
async _initDerivations(handles) {
|
|
7154
7788
|
if (handles.length === 0) return;
|
|
7155
7789
|
const [{ DerivationRegistry }, { ReadOnlyVaultFacade }] = await Promise.all([
|
|
7156
|
-
import("./registry-
|
|
7157
|
-
import("./read-only-facade-
|
|
7790
|
+
import("./registry-ERNAMRDE.js"),
|
|
7791
|
+
import("./read-only-facade-EX6WZZBP.js")
|
|
7158
7792
|
]);
|
|
7159
7793
|
const registry = new DerivationRegistry();
|
|
7160
7794
|
for (const h of handles) {
|
|
@@ -7162,8 +7796,8 @@ var Vault = class {
|
|
|
7162
7796
|
}
|
|
7163
7797
|
registry.validate();
|
|
7164
7798
|
this.derivationRegistry = registry;
|
|
7165
|
-
if (this.
|
|
7166
|
-
this.
|
|
7799
|
+
if (this.derivationFacade === null) {
|
|
7800
|
+
this.derivationFacade = new ReadOnlyVaultFacade(this, "derivation");
|
|
7167
7801
|
}
|
|
7168
7802
|
}
|
|
7169
7803
|
/**
|
|
@@ -7184,7 +7818,7 @@ var Vault = class {
|
|
|
7184
7818
|
*/
|
|
7185
7819
|
async _initMaterializedViews(handles) {
|
|
7186
7820
|
if (handles.length === 0) return;
|
|
7187
|
-
const { MaterializedViewRegistry } = await import("./registry-
|
|
7821
|
+
const { MaterializedViewRegistry } = await import("./registry-RDPTFXQ7.js");
|
|
7188
7822
|
const registry = new MaterializedViewRegistry();
|
|
7189
7823
|
this.materializedViewRegistry = registry;
|
|
7190
7824
|
const db = this;
|
|
@@ -7208,7 +7842,7 @@ var Vault = class {
|
|
|
7208
7842
|
*/
|
|
7209
7843
|
async _initOverlayedViews(handles) {
|
|
7210
7844
|
if (handles.length === 0) return;
|
|
7211
|
-
const { OverlayedViewRegistry } = await import("./registry-
|
|
7845
|
+
const { OverlayedViewRegistry } = await import("./registry-EXTHSXQW.js");
|
|
7212
7846
|
const registry = new OverlayedViewRegistry();
|
|
7213
7847
|
const mvRegistry = this.materializedViewRegistry;
|
|
7214
7848
|
const overlayNames = /* @__PURE__ */ new Set();
|
|
@@ -7255,13 +7889,13 @@ var Vault = class {
|
|
|
7255
7889
|
if (!reg) {
|
|
7256
7890
|
throw new Error(`refreshView: no MV registered with name "${name}"`);
|
|
7257
7891
|
}
|
|
7258
|
-
const { MaterializedViewExecutor } = await import("./executor-
|
|
7892
|
+
const { MaterializedViewExecutor } = await import("./executor-44R5CUS2.js");
|
|
7259
7893
|
const result = await MaterializedViewExecutor.refresh(reg, {
|
|
7260
7894
|
getCollection: (n) => this.collection(n),
|
|
7261
7895
|
getActiveTxContext: () => this.noydb._activeTxContextOrNull,
|
|
7262
7896
|
getQueryContext: () => this
|
|
7263
7897
|
});
|
|
7264
|
-
const { clearMVStale } = await import("./stale-
|
|
7898
|
+
const { clearMVStale } = await import("./stale-NTEV5SLX.js");
|
|
7265
7899
|
clearMVStale(registry, name);
|
|
7266
7900
|
return result;
|
|
7267
7901
|
}
|
|
@@ -7277,10 +7911,10 @@ var Vault = class {
|
|
|
7277
7911
|
if (registry === null) return { derived: 0, failed: 0 };
|
|
7278
7912
|
const strategies = registry.strategiesForSource(sourceCollection);
|
|
7279
7913
|
if (strategies.length === 0) return { derived: 0, failed: 0 };
|
|
7280
|
-
const { DerivationExecutor } = await import("./executor-
|
|
7914
|
+
const { DerivationExecutor } = await import("./executor-OKFLQCDW.js");
|
|
7281
7915
|
const sourceColl = this.collection(sourceCollection);
|
|
7282
7916
|
const records = await sourceColl.list();
|
|
7283
|
-
const ctx = { vault: this.
|
|
7917
|
+
const ctx = { vault: this.derivationFacade ?? new (await import("./read-only-facade-EX6WZZBP.js")).ReadOnlyVaultFacade(this, "derivation") };
|
|
7284
7918
|
let derived = 0;
|
|
7285
7919
|
let failed = 0;
|
|
7286
7920
|
for (const record of records) {
|
|
@@ -7302,7 +7936,7 @@ var Vault = class {
|
|
|
7302
7936
|
if (!outSpec) continue;
|
|
7303
7937
|
const outputColl = this.collection(outSpec.collection);
|
|
7304
7938
|
if (out.kind === "array") {
|
|
7305
|
-
const { loadFanoutSidecar, saveFanoutSidecar } = await import("./fanout-sidecar-
|
|
7939
|
+
const { loadFanoutSidecar, saveFanoutSidecar } = await import("./fanout-sidecar-DCQWJQ6S.js");
|
|
7306
7940
|
const prior = await loadFanoutSidecar(this.adapter, this.name, spec.source, id, key);
|
|
7307
7941
|
const prevKeys = new Set(prior?.keys ?? []);
|
|
7308
7942
|
const newKeysList = out.entries.map((e) => e.key);
|
|
@@ -7345,17 +7979,18 @@ var Vault = class {
|
|
|
7345
7979
|
* never see null).
|
|
7346
7980
|
*/
|
|
7347
7981
|
_getReadOnlyFacade() {
|
|
7348
|
-
return this.
|
|
7982
|
+
return this.guardFacade;
|
|
7349
7983
|
}
|
|
7350
7984
|
/**
|
|
7351
|
-
* Internal lazy-allocator for the read-only facade
|
|
7352
|
-
* defensive fallback; in practice
|
|
7353
|
-
* instantiates this, so the lazy path is
|
|
7985
|
+
* Internal lazy-allocator for the derivation read-only facade
|
|
7986
|
+
* (`layer:'derivation'`). Used as a defensive fallback; in practice
|
|
7987
|
+
* `_initDerivations()` eagerly instantiates this, so the lazy path is
|
|
7988
|
+
* a no-op.
|
|
7354
7989
|
*/
|
|
7355
7990
|
_ensureReadOnlyFacade() {
|
|
7356
|
-
if (this.
|
|
7991
|
+
if (this.derivationFacade !== null) return this.derivationFacade;
|
|
7357
7992
|
throw new Error(
|
|
7358
|
-
"Vault:
|
|
7993
|
+
"Vault: derivation hook fired before _initDerivations() completed. This typically means the vault was opened via the sync fallback path (Noydb.vault(name)) without first calling await db.openVault(name). See issue #132."
|
|
7359
7994
|
);
|
|
7360
7995
|
}
|
|
7361
7996
|
/**
|
|
@@ -7523,7 +8158,7 @@ var Vault = class {
|
|
|
7523
8158
|
* collection.
|
|
7524
8159
|
*/
|
|
7525
8160
|
async delegate(opts) {
|
|
7526
|
-
const { issueDelegation, DELEGATIONS_COLLECTION } = await import("./delegation-
|
|
8161
|
+
const { issueDelegation, DELEGATIONS_COLLECTION } = await import("./delegation-5HON72PV.js");
|
|
7527
8162
|
if (!this.keyring.kek) {
|
|
7528
8163
|
throw new ValidationError(
|
|
7529
8164
|
"issueDelegation: keyring.kek is null \u2014 issuing a delegation requires a tier-1 unlock. Re-authenticate at tier 1 (passphrase) first."
|
|
@@ -7545,7 +8180,7 @@ var Vault = class {
|
|
|
7545
8180
|
* if the id does not exist.
|
|
7546
8181
|
*/
|
|
7547
8182
|
async revokeDelegation(id) {
|
|
7548
|
-
const { revokeDelegation, DELEGATIONS_COLLECTION } = await import("./delegation-
|
|
8183
|
+
const { revokeDelegation, DELEGATIONS_COLLECTION } = await import("./delegation-5HON72PV.js");
|
|
7549
8184
|
await revokeDelegation(this.adapter, this.name, id);
|
|
7550
8185
|
void DELEGATIONS_COLLECTION;
|
|
7551
8186
|
}
|
|
@@ -8014,7 +8649,7 @@ var Vault = class {
|
|
|
8014
8649
|
* @see docs/subsystems/public-envelope.md
|
|
8015
8650
|
*/
|
|
8016
8651
|
async getPublicEnvelope(opts = {}) {
|
|
8017
|
-
const { readPublicEnvelope: readPublicEnvelope2 } = await import("./public-envelope-
|
|
8652
|
+
const { readPublicEnvelope: readPublicEnvelope2 } = await import("./public-envelope-AGU6SS4Z.js");
|
|
8018
8653
|
return readPublicEnvelope2(this.adapter, this.name, opts);
|
|
8019
8654
|
}
|
|
8020
8655
|
/**
|
|
@@ -8291,6 +8926,8 @@ var Vault = class {
|
|
|
8291
8926
|
*/
|
|
8292
8927
|
async *exportStream(opts = {}) {
|
|
8293
8928
|
const granularity = opts.granularity ?? "collection";
|
|
8929
|
+
const exportLocale = opts.resolveLabels;
|
|
8930
|
+
const localeOpts = exportLocale !== void 0 ? { locale: exportLocale, _layer: "export" } : void 0;
|
|
8294
8931
|
const snapshot = await this.adapter.loadAll(this.name);
|
|
8295
8932
|
const collectionNames = Object.keys(snapshot).sort();
|
|
8296
8933
|
const ledgerHead = opts.withLedgerHead ? await (async () => {
|
|
@@ -8300,19 +8937,21 @@ var Vault = class {
|
|
|
8300
8937
|
return head ? { hash: head.hash, index: head.entry.index, ts: head.entry.ts } : void 0;
|
|
8301
8938
|
})() : void 0;
|
|
8302
8939
|
const dictSnapshotCache = /* @__PURE__ */ new Map();
|
|
8303
|
-
|
|
8304
|
-
const
|
|
8305
|
-
|
|
8306
|
-
|
|
8307
|
-
|
|
8308
|
-
const
|
|
8309
|
-
|
|
8310
|
-
|
|
8311
|
-
|
|
8940
|
+
if (exportLocale === void 0) {
|
|
8941
|
+
for (const collectionName of collectionNames) {
|
|
8942
|
+
const dictFields = this.dictKeyFieldRegistry.get(collectionName);
|
|
8943
|
+
if (dictFields && Object.keys(dictFields).length > 0) {
|
|
8944
|
+
const snap = {};
|
|
8945
|
+
for (const [fieldName, dictName] of Object.entries(dictFields)) {
|
|
8946
|
+
const entries = await this.dictionary(dictName).list();
|
|
8947
|
+
const keyMap = {};
|
|
8948
|
+
for (const entry of entries) {
|
|
8949
|
+
keyMap[entry.key] = entry.labels;
|
|
8950
|
+
}
|
|
8951
|
+
snap[fieldName] = keyMap;
|
|
8312
8952
|
}
|
|
8313
|
-
snap
|
|
8953
|
+
dictSnapshotCache.set(collectionName, snap);
|
|
8314
8954
|
}
|
|
8315
|
-
dictSnapshotCache.set(collectionName, snap);
|
|
8316
8955
|
}
|
|
8317
8956
|
}
|
|
8318
8957
|
for (const collectionName of collectionNames) {
|
|
@@ -8325,7 +8964,7 @@ var Vault = class {
|
|
|
8325
8964
|
if (granularity === "collection") {
|
|
8326
8965
|
const records = [];
|
|
8327
8966
|
for (const id of ids) {
|
|
8328
|
-
const record = await coll.get(id);
|
|
8967
|
+
const record = await coll.get(id, localeOpts);
|
|
8329
8968
|
if (record !== null) records.push(record);
|
|
8330
8969
|
}
|
|
8331
8970
|
const chunk = {
|
|
@@ -8339,7 +8978,7 @@ var Vault = class {
|
|
|
8339
8978
|
yield chunk;
|
|
8340
8979
|
} else {
|
|
8341
8980
|
for (const id of ids) {
|
|
8342
|
-
const record = await coll.get(id);
|
|
8981
|
+
const record = await coll.get(id, localeOpts);
|
|
8343
8982
|
if (record === null) continue;
|
|
8344
8983
|
const chunk = {
|
|
8345
8984
|
collection: collectionName,
|
|
@@ -8443,7 +9082,10 @@ var Vault = class {
|
|
|
8443
9082
|
const allDictionaries = {};
|
|
8444
9083
|
for await (const chunk of this.exportStream({
|
|
8445
9084
|
granularity: "collection",
|
|
8446
|
-
withLedgerHead: opts.withLedgerHead === true
|
|
9085
|
+
withLedgerHead: opts.withLedgerHead === true,
|
|
9086
|
+
// #285 export layer: thread the export locale so records are read at the
|
|
9087
|
+
// `export` layer (i18nText collapsed + dictKey/staticDict labels resolved).
|
|
9088
|
+
...opts.resolveLabels !== void 0 ? { resolveLabels: opts.resolveLabels } : {}
|
|
8447
9089
|
})) {
|
|
8448
9090
|
collections[chunk.collection] = {
|
|
8449
9091
|
schema: null,
|
|
@@ -9679,7 +10321,7 @@ var Noydb = class {
|
|
|
9679
10321
|
if (!facade) return;
|
|
9680
10322
|
const ctx = { existing, vault: facade, userId: e.userId, role: e.role };
|
|
9681
10323
|
await registry.runChecks(e.collection, incoming, ctx);
|
|
9682
|
-
const { GuardExecutor } = await import("./executor-
|
|
10324
|
+
const { GuardExecutor } = await import("./executor-AOACUK7Z.js");
|
|
9683
10325
|
for (const g of guards) {
|
|
9684
10326
|
await GuardExecutor.checkFrozenFields(g, e.docId, existing, incoming, e.computedFieldNames);
|
|
9685
10327
|
}
|
|
@@ -10280,11 +10922,11 @@ var Noydb = class {
|
|
|
10280
10922
|
if (name === STATE_VAULT_NAME) throw new ReservedVaultNameError(name);
|
|
10281
10923
|
const template = this.vaultTemplates.get(opts.sharding.vaultTemplate);
|
|
10282
10924
|
if (!template) throw new VaultTemplateNotFoundError(opts.sharding.vaultTemplate);
|
|
10283
|
-
const { VaultGroup } = await import("./vault-group-
|
|
10284
|
-
const { StateManagementVault } = await import("./state-vault-
|
|
10925
|
+
const { VaultGroup } = await import("./vault-group-27EV7KB4.js");
|
|
10926
|
+
const { StateManagementVault } = await import("./state-vault-TUTFRTOA.js");
|
|
10285
10927
|
const stateVault = opts.registry ? void 0 : await StateManagementVault.open(this);
|
|
10286
10928
|
const registry = opts.registry ?? stateVault.registry;
|
|
10287
|
-
const group = new VaultGroup(this, name, registry, opts.sharding, template);
|
|
10929
|
+
const group = new VaultGroup(this, name, registry, opts.sharding, template, opts.migrateOnOpen ?? false);
|
|
10288
10930
|
if (stateVault) {
|
|
10289
10931
|
group._attachStateVault(stateVault);
|
|
10290
10932
|
await stateVault.recordManifest(opts.sharding.vaultTemplate, template);
|
|
@@ -10308,7 +10950,7 @@ var Noydb = class {
|
|
|
10308
10950
|
*/
|
|
10309
10951
|
async openStateManagementVault() {
|
|
10310
10952
|
if (this.closed) throw new ValidationError("Instance is closed");
|
|
10311
|
-
const { StateManagementVault } = await import("./state-vault-
|
|
10953
|
+
const { StateManagementVault } = await import("./state-vault-TUTFRTOA.js");
|
|
10312
10954
|
return StateManagementVault.open(this);
|
|
10313
10955
|
}
|
|
10314
10956
|
/**
|
|
@@ -10318,6 +10960,16 @@ var Noydb = class {
|
|
|
10318
10960
|
async _shardVaultProvisioned(vaultId) {
|
|
10319
10961
|
return (await this.options.store.list(vaultId, "_keyring")).length > 0;
|
|
10320
10962
|
}
|
|
10963
|
+
/**
|
|
10964
|
+
* @internal — the physical backend store a vault id maps to. A
|
|
10965
|
+
* `routeStore` resolves the vault-prefix route via its `resolveBackend`;
|
|
10966
|
+
* a plain store is its own backend. Used by the federation data-residency
|
|
10967
|
+
* guard to read the placement backend's `capabilities.region` (#271).
|
|
10968
|
+
*/
|
|
10969
|
+
_resolveBackend(vaultId) {
|
|
10970
|
+
const store = this.options.store;
|
|
10971
|
+
return store.resolveBackend ? store.resolveBackend(vaultId) : this.options.store;
|
|
10972
|
+
}
|
|
10321
10973
|
/**
|
|
10322
10974
|
* Change the current user's passphrase for a vault.
|
|
10323
10975
|
*
|
|
@@ -11810,6 +12462,7 @@ function normalizeSyncTargets(sync) {
|
|
|
11810
12462
|
|
|
11811
12463
|
export {
|
|
11812
12464
|
withArchive,
|
|
12465
|
+
compileSequenceFormat,
|
|
11813
12466
|
resolveSequenceKey,
|
|
11814
12467
|
SequenceStore,
|
|
11815
12468
|
validateSchemaInput,
|
|
@@ -11817,10 +12470,15 @@ export {
|
|
|
11817
12470
|
isZodSchema,
|
|
11818
12471
|
derivePersistedSchema,
|
|
11819
12472
|
persistSchemaIfNeeded,
|
|
12473
|
+
isRefArray,
|
|
11820
12474
|
RefIntegrityError,
|
|
11821
12475
|
RefScopeError,
|
|
11822
12476
|
ref,
|
|
12477
|
+
refArray,
|
|
11823
12478
|
RefRegistry,
|
|
12479
|
+
isLinkCollectionName,
|
|
12480
|
+
LinkEndpointError,
|
|
12481
|
+
LinkIntegrityError,
|
|
11824
12482
|
QuickUnlockStore,
|
|
11825
12483
|
UserApi,
|
|
11826
12484
|
META_COLLECTION,
|
|
@@ -11833,6 +12491,7 @@ export {
|
|
|
11833
12491
|
describeAllUsersAuth,
|
|
11834
12492
|
ComputedFieldError,
|
|
11835
12493
|
evalComputedFields,
|
|
12494
|
+
tokenize,
|
|
11836
12495
|
Lru,
|
|
11837
12496
|
parseBytes,
|
|
11838
12497
|
estimateRecordBytes,
|
|
@@ -11849,4 +12508,4 @@ export {
|
|
|
11849
12508
|
Noydb,
|
|
11850
12509
|
createNoydb
|
|
11851
12510
|
};
|
|
11852
|
-
//# sourceMappingURL=chunk-
|
|
12511
|
+
//# sourceMappingURL=chunk-KYGGXXT6.js.map
|