@noy-db/hub 0.2.0-pre.28 → 0.2.0-pre.29
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.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 -5
- package/dist/attestation/index.cjs.map +1 -1
- package/dist/attestation/index.d.cts +4 -4
- package/dist/attestation/index.d.ts +4 -4
- package/dist/attestation/index.js +6 -6
- package/dist/blobs/index.cjs +2 -2
- 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 +864 -1
- package/dist/bundle/index.cjs.map +1 -1
- package/dist/bundle/index.d.cts +6 -6
- package/dist/bundle/index.d.ts +6 -6
- package/dist/bundle/index.js +10 -10
- package/dist/{chunk-42EGY2FQ.js → chunk-2QDWRK3B.js} +5 -5
- package/dist/{chunk-7GKDVWMD.js → chunk-2UT7HJJR.js} +4 -4
- package/dist/{chunk-E5TJAQS7.js → chunk-2ZYIN3BL.js} +2 -2
- package/dist/{chunk-DQ6XF2K2.js → chunk-45QJXLLS.js} +8 -8
- package/dist/{chunk-H4XFA2LM.js → chunk-4K4QKYK4.js} +3 -3
- package/dist/{chunk-RHVYFAVQ.js → chunk-4L6N56B4.js} +2 -2
- package/dist/{chunk-EW3H5Y7N.js → chunk-4YD7VZH4.js} +2 -2
- package/dist/{chunk-GVEUI7VR.js → chunk-553CK4E2.js} +3 -3
- package/dist/{chunk-YYLFXX2K.js → chunk-5PTX7PKD.js} +4 -4
- package/dist/{chunk-4FHKQDHN.js → chunk-6BSYMFYS.js} +7 -7
- package/dist/chunk-6BSYMFYS.js.map +1 -0
- package/dist/{chunk-TESFHBOW.js → chunk-6EKRQ7QF.js} +3 -3
- package/dist/{chunk-Q7P4WHTL.js → chunk-7GPQPLGO.js} +2 -2
- package/dist/{chunk-QSLIT4JZ.js → chunk-A7DNZVAV.js} +1 -1
- package/dist/{chunk-QSLIT4JZ.js.map → chunk-A7DNZVAV.js.map} +1 -1
- package/dist/{chunk-OMBPGXCL.js → chunk-ASIGWYRA.js} +2 -2
- package/dist/{chunk-QBC2TZHC.js → chunk-AWU4JF7C.js} +6 -6
- package/dist/{chunk-SKYBEGHB.js → chunk-BEZ2EV43.js} +2 -2
- package/dist/{chunk-EJJTUDNI.js → chunk-BITB3T5Z.js} +3 -3
- package/dist/{chunk-WH7G2YEE.js → chunk-CIZDUAHI.js} +4 -4
- package/dist/{chunk-ENC4C6XW.js → chunk-CUPTCF4R.js} +5 -5
- package/dist/{chunk-FO5WEDKF.js → chunk-DEE4CRYN.js} +2 -2
- package/dist/{chunk-HI7FY7QZ.js → chunk-DJO4OYCJ.js} +2 -2
- package/dist/{chunk-7JSP3E67.js → chunk-E2MDPPOC.js} +2 -2
- package/dist/{chunk-LX4CPLU6.js → chunk-FFKQ65YX.js} +2 -2
- package/dist/{chunk-VUUQYWF5.js → chunk-G7ALNCQH.js} +2 -2
- package/dist/{chunk-M2VZQ24Q.js → chunk-GGXN73NM.js} +36 -4
- package/dist/chunk-GGXN73NM.js.map +1 -0
- package/dist/{chunk-IMY4FXYE.js → chunk-JOJPBZSZ.js} +5 -5
- package/dist/{chunk-DDOYOMAD.js → chunk-JZ5DS4DP.js} +32 -2
- package/dist/chunk-JZ5DS4DP.js.map +1 -0
- package/dist/{chunk-345PYZD6.js → chunk-K6NVSHAH.js} +4 -4
- package/dist/{chunk-3BANVNDH.js → chunk-KJ3K5VZM.js} +2 -2
- package/dist/{chunk-ZW2YSN6G.js → chunk-LBILABKZ.js} +4 -4
- package/dist/{chunk-DMWUOV7X.js → chunk-LXKBG52H.js} +4 -4
- package/dist/{chunk-YYTM4U4J.js → chunk-MPIZQGFA.js} +2 -2
- package/dist/{chunk-JEQB2KVI.js → chunk-MRJPSXPE.js} +3 -3
- package/dist/{chunk-J73KU4AE.js → chunk-MSMDDDDJ.js} +2 -2
- package/dist/{chunk-7TBCLM52.js → chunk-QBLPY44S.js} +3 -3
- package/dist/{chunk-2M62POB5.js → chunk-QGBBQKDS.js} +35 -5
- package/dist/chunk-QGBBQKDS.js.map +1 -0
- package/dist/{chunk-PPF7Z2YQ.js → chunk-QWJCNXH2.js} +3 -3
- package/dist/{chunk-6LD37AMK.js → chunk-QXWJQ7UU.js} +2 -2
- package/dist/{chunk-YRQPI67X.js → chunk-RCB6GWTC.js} +2 -2
- package/dist/{chunk-HQ242WNG.js → chunk-REHF3HSJ.js} +5 -5
- package/dist/{chunk-FUDVHE2U.js → chunk-SAAJYSVV.js} +2 -2
- package/dist/{chunk-AHDQYG7P.js → chunk-SHJ3BRTZ.js} +5 -5
- package/dist/{chunk-RG5KLMEU.js → chunk-SQXTKZL7.js} +3 -3
- package/dist/{chunk-2KA3PDUR.js → chunk-TMUMMAWV.js} +2 -2
- package/dist/{chunk-SWGVCSIY.js → chunk-TZGWI5AX.js} +4 -4
- package/dist/{chunk-KNJ7MK4B.js → chunk-UBF5JEOJ.js} +2 -2
- package/dist/{chunk-FJ3C3ELF.js → chunk-XAYDHD2O.js} +2 -2
- package/dist/{chunk-DCYWBKQ2.js → chunk-XYW2CSCI.js} +3 -3
- package/dist/{chunk-VSL3W2MO.js → chunk-ZCMOS4H2.js} +4 -4
- package/dist/{chunk-3LHTFCU2.js → chunk-ZDW22N3E.js} +744 -51
- package/dist/chunk-ZDW22N3E.js.map +1 -0
- package/dist/consent/index.cjs.map +1 -1
- package/dist/consent/index.d.cts +5 -5
- package/dist/consent/index.d.ts +5 -5
- package/dist/consent/index.js +3 -3
- package/dist/{crypto-YBKBNPVM.js → crypto-G6XU2V2Y.js} +3 -3
- package/dist/{decrypt-partition-BtGtE-19.d.ts → decrypt-partition-5Gt0EcTc.d.ts} +1 -1
- package/dist/{decrypt-partition-Cqi5gcOl.d.cts → decrypt-partition-DDSArPPW.d.cts} +1 -1
- package/dist/{delegation-4JSMM6BB.js → delegation-ZEH4LKEM.js} +5 -5
- package/dist/derivations/index.cjs.map +1 -1
- package/dist/derivations/index.d.cts +6 -6
- package/dist/derivations/index.d.ts +6 -6
- package/dist/derivations/index.js +4 -4
- package/dist/{dev-unlock-D0p9cQzN.d.ts → dev-unlock-BF9IhLPn.d.ts} +1 -1
- package/dist/{dev-unlock-Cts_iiVv.d.cts → dev-unlock-CIkHrcRm.d.cts} +1 -1
- package/dist/{errors-Dwk2k1xY.d.ts → errors-BAWO5Z5a.d.cts} +25 -1
- package/dist/{errors-Dwk2k1xY.d.cts → errors-BAWO5Z5a.d.ts} +25 -1
- package/dist/executor-DWVP4BSJ.js +8 -0
- package/dist/executor-HB2YMIYC.js +12 -0
- package/dist/executor-HO3SIRSF.js +8 -0
- package/dist/{fanout-sidecar-DSBVAR2P.js → fanout-sidecar-BMT7I6FI.js} +2 -2
- package/dist/forget/index.js +4 -4
- package/dist/guards/index.cjs.map +1 -1
- package/dist/guards/index.d.cts +6 -6
- package/dist/guards/index.d.ts +6 -6
- package/dist/guards/index.js +3 -3
- package/dist/{hash-DA75XwW2.d.cts → hash-DfhndFcd.d.cts} +1 -1
- package/dist/{hash-BtDtwguU.d.ts → hash-Jl0qarQx.d.ts} +1 -1
- package/dist/history/index.cjs.map +1 -1
- package/dist/history/index.d.cts +6 -6
- package/dist/history/index.d.ts +6 -6
- package/dist/history/index.js +5 -5
- package/dist/i18n/index.cjs.map +1 -1
- package/dist/i18n/index.d.cts +5 -5
- package/dist/i18n/index.d.ts +5 -5
- package/dist/i18n/index.js +6 -6
- package/dist/{index-CVnt2Qmq.d.cts → index-C1SC1EPe.d.cts} +19 -2
- package/dist/{index-CP24aYCp.d.cts → index-DPG2nFmT.d.cts} +28 -5
- package/dist/{index-BidHvmWf.d.ts → index-DcxTv3zx.d.ts} +28 -5
- package/dist/{index-DxBNV54L.d.ts → index-Ddm8D3Oo.d.ts} +19 -2
- package/dist/index.cjs +874 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +16 -16
- package/dist/index.d.ts +16 -16
- package/dist/index.js +54 -47
- 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-FZRTVGRE.js +12 -0
- package/dist/kernel/index.cjs +33 -0
- package/dist/kernel/index.cjs.map +1 -1
- package/dist/kernel/index.d.cts +5 -5
- package/dist/kernel/index.d.ts +5 -5
- package/dist/kernel/index.js +9 -7
- package/dist/{ledger-PLMSH7LD.js → ledger-PMTR2Q62.js} +5 -5
- package/dist/materialized-views/index.cjs.map +1 -1
- package/dist/materialized-views/index.d.cts +6 -6
- package/dist/materialized-views/index.d.ts +6 -6
- package/dist/materialized-views/index.js +8 -8
- package/dist/{mime-magic--NcogI82.d.ts → mime-magic-BOI-I5dq.d.ts} +1 -1
- package/dist/{mime-magic-i2VSlkPM.d.cts → mime-magic-C0TM7FtF.d.cts} +1 -1
- package/dist/noydb-Y3ZLZNXA.js +39 -0
- package/dist/overlay-views/index.cjs.map +1 -1
- package/dist/overlay-views/index.d.cts +6 -6
- package/dist/overlay-views/index.d.ts +6 -6
- package/dist/overlay-views/index.js +4 -4
- package/dist/periods/index.cjs.map +1 -1
- package/dist/periods/index.d.cts +5 -5
- package/dist/periods/index.d.ts +5 -5
- package/dist/periods/index.js +5 -5
- package/dist/{public-envelope-7MTH2PVE.js → public-envelope-S2S2VR3F.js} +4 -4
- package/dist/query/index.cjs +30 -0
- 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 -7
- package/dist/{registry-OUZ3VBZA.js → registry-53A55ZZE.js} +3 -3
- package/dist/registry-FKL4SLU4.js +8 -0
- package/dist/registry-IEU6ATO7.js +8 -0
- package/dist/{revoke-DBAGKIDA.js → revoke-AOCAVR56.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 +6 -6
- package/dist/session/index.d.ts +6 -6
- package/dist/session/index.js +3 -3
- package/dist/shadow/index.cjs.map +1 -1
- package/dist/shadow/index.d.cts +5 -5
- package/dist/shadow/index.d.ts +5 -5
- package/dist/shadow/index.js +2 -2
- package/dist/{signer-ADFJNS5W.js → signer-JMK6W2Y6.js} +5 -5
- package/dist/snapshots/index.cjs.map +1 -1
- package/dist/snapshots/index.d.cts +5 -5
- package/dist/snapshots/index.d.ts +5 -5
- package/dist/snapshots/index.js +4 -4
- package/dist/{stale-BCIE3SMC.js → stale-IIIGOHBW.js} +2 -2
- package/dist/store/index.cjs.map +1 -1
- package/dist/store/index.d.cts +5 -5
- package/dist/store/index.d.ts +5 -5
- package/dist/store/index.js +2 -2
- package/dist/{strategy-BoITAb2H.d.ts → strategy-8QGs5KQE.d.ts} +1 -1
- package/dist/{strategy-DDNvt_UD.d.cts → strategy-mJExw4LQ.d.cts} +1 -1
- package/dist/sync/index.cjs.map +1 -1
- package/dist/sync/index.d.cts +4 -4
- package/dist/sync/index.d.ts +4 -4
- package/dist/sync/index.js +4 -4
- package/dist/team/index.cjs.map +1 -1
- package/dist/team/index.d.cts +5 -5
- package/dist/team/index.d.ts +5 -5
- package/dist/team/index.js +8 -8
- package/dist/{transition-guard-BZhOlrFT.d.ts → transition-guard-BixCDmBI.d.ts} +1 -1
- package/dist/{transition-guard-Bekgaxux.d.cts → transition-guard-DnAlUf9R.d.cts} +1 -1
- package/dist/tx/index.cjs.map +1 -1
- package/dist/tx/index.d.cts +5 -5
- package/dist/tx/index.d.ts +5 -5
- package/dist/tx/index.js +3 -3
- package/dist/{types-B_eCkuEI.d.cts → types-Ba1vQ3AY.d.cts} +160 -4
- package/dist/{types-84nsWSDF.d.ts → types-CUmZYJwN.d.ts} +160 -4
- package/dist/util/index.cjs.map +1 -1
- package/dist/util/index.js +1 -1
- package/dist/{with-materialized-view-CAMGQroY.d.ts → with-materialized-view-Bjx6VYPc.d.ts} +1 -1
- package/dist/{with-materialized-view-DKMaZmkJ.d.cts → with-materialized-view-Z_aHLln6.d.cts} +1 -1
- package/dist/{with-overlayed-view-FnOf1v6H.d.ts → with-overlayed-view-B8PkL179.d.ts} +1 -1
- package/dist/{with-overlayed-view--lWXImbV.d.cts → with-overlayed-view-pTOFgHRq.d.cts} +1 -1
- package/dist/{with-rollup-xi-mkY6Y.d.ts → with-rollup-Cd3t01Mz.d.ts} +1 -1
- package/dist/{with-rollup-C5875Ad5.d.cts → with-rollup-D9qQoffP.d.cts} +1 -1
- package/package.json +3 -3
- package/dist/chunk-2M62POB5.js.map +0 -1
- package/dist/chunk-3LHTFCU2.js.map +0 -1
- package/dist/chunk-4FHKQDHN.js.map +0 -1
- package/dist/chunk-DDOYOMAD.js.map +0 -1
- package/dist/chunk-M2VZQ24Q.js.map +0 -1
- package/dist/executor-3SVNESQ3.js +0 -8
- package/dist/executor-PJHMRZWJ.js +0 -12
- package/dist/executor-VEZUBJNQ.js +0 -8
- package/dist/issue-JSGGSVY4.js +0 -12
- package/dist/noydb-PHXA5E6I.js +0 -39
- package/dist/registry-CMEVTOCN.js +0 -8
- package/dist/registry-XUBRO5JJ.js +0 -8
- /package/dist/{chunk-42EGY2FQ.js.map → chunk-2QDWRK3B.js.map} +0 -0
- /package/dist/{chunk-7GKDVWMD.js.map → chunk-2UT7HJJR.js.map} +0 -0
- /package/dist/{chunk-E5TJAQS7.js.map → chunk-2ZYIN3BL.js.map} +0 -0
- /package/dist/{chunk-DQ6XF2K2.js.map → chunk-45QJXLLS.js.map} +0 -0
- /package/dist/{chunk-H4XFA2LM.js.map → chunk-4K4QKYK4.js.map} +0 -0
- /package/dist/{chunk-RHVYFAVQ.js.map → chunk-4L6N56B4.js.map} +0 -0
- /package/dist/{chunk-EW3H5Y7N.js.map → chunk-4YD7VZH4.js.map} +0 -0
- /package/dist/{chunk-GVEUI7VR.js.map → chunk-553CK4E2.js.map} +0 -0
- /package/dist/{chunk-YYLFXX2K.js.map → chunk-5PTX7PKD.js.map} +0 -0
- /package/dist/{chunk-TESFHBOW.js.map → chunk-6EKRQ7QF.js.map} +0 -0
- /package/dist/{chunk-Q7P4WHTL.js.map → chunk-7GPQPLGO.js.map} +0 -0
- /package/dist/{chunk-OMBPGXCL.js.map → chunk-ASIGWYRA.js.map} +0 -0
- /package/dist/{chunk-QBC2TZHC.js.map → chunk-AWU4JF7C.js.map} +0 -0
- /package/dist/{chunk-SKYBEGHB.js.map → chunk-BEZ2EV43.js.map} +0 -0
- /package/dist/{chunk-EJJTUDNI.js.map → chunk-BITB3T5Z.js.map} +0 -0
- /package/dist/{chunk-WH7G2YEE.js.map → chunk-CIZDUAHI.js.map} +0 -0
- /package/dist/{chunk-ENC4C6XW.js.map → chunk-CUPTCF4R.js.map} +0 -0
- /package/dist/{chunk-FO5WEDKF.js.map → chunk-DEE4CRYN.js.map} +0 -0
- /package/dist/{chunk-HI7FY7QZ.js.map → chunk-DJO4OYCJ.js.map} +0 -0
- /package/dist/{chunk-7JSP3E67.js.map → chunk-E2MDPPOC.js.map} +0 -0
- /package/dist/{chunk-LX4CPLU6.js.map → chunk-FFKQ65YX.js.map} +0 -0
- /package/dist/{chunk-VUUQYWF5.js.map → chunk-G7ALNCQH.js.map} +0 -0
- /package/dist/{chunk-IMY4FXYE.js.map → chunk-JOJPBZSZ.js.map} +0 -0
- /package/dist/{chunk-345PYZD6.js.map → chunk-K6NVSHAH.js.map} +0 -0
- /package/dist/{chunk-3BANVNDH.js.map → chunk-KJ3K5VZM.js.map} +0 -0
- /package/dist/{chunk-ZW2YSN6G.js.map → chunk-LBILABKZ.js.map} +0 -0
- /package/dist/{chunk-DMWUOV7X.js.map → chunk-LXKBG52H.js.map} +0 -0
- /package/dist/{chunk-YYTM4U4J.js.map → chunk-MPIZQGFA.js.map} +0 -0
- /package/dist/{chunk-JEQB2KVI.js.map → chunk-MRJPSXPE.js.map} +0 -0
- /package/dist/{chunk-J73KU4AE.js.map → chunk-MSMDDDDJ.js.map} +0 -0
- /package/dist/{chunk-7TBCLM52.js.map → chunk-QBLPY44S.js.map} +0 -0
- /package/dist/{chunk-PPF7Z2YQ.js.map → chunk-QWJCNXH2.js.map} +0 -0
- /package/dist/{chunk-6LD37AMK.js.map → chunk-QXWJQ7UU.js.map} +0 -0
- /package/dist/{chunk-YRQPI67X.js.map → chunk-RCB6GWTC.js.map} +0 -0
- /package/dist/{chunk-HQ242WNG.js.map → chunk-REHF3HSJ.js.map} +0 -0
- /package/dist/{chunk-FUDVHE2U.js.map → chunk-SAAJYSVV.js.map} +0 -0
- /package/dist/{chunk-AHDQYG7P.js.map → chunk-SHJ3BRTZ.js.map} +0 -0
- /package/dist/{chunk-RG5KLMEU.js.map → chunk-SQXTKZL7.js.map} +0 -0
- /package/dist/{chunk-2KA3PDUR.js.map → chunk-TMUMMAWV.js.map} +0 -0
- /package/dist/{chunk-SWGVCSIY.js.map → chunk-TZGWI5AX.js.map} +0 -0
- /package/dist/{chunk-KNJ7MK4B.js.map → chunk-UBF5JEOJ.js.map} +0 -0
- /package/dist/{chunk-FJ3C3ELF.js.map → chunk-XAYDHD2O.js.map} +0 -0
- /package/dist/{chunk-DCYWBKQ2.js.map → chunk-XYW2CSCI.js.map} +0 -0
- /package/dist/{chunk-VSL3W2MO.js.map → chunk-ZCMOS4H2.js.map} +0 -0
- /package/dist/{crypto-YBKBNPVM.js.map → crypto-G6XU2V2Y.js.map} +0 -0
- /package/dist/{delegation-4JSMM6BB.js.map → delegation-ZEH4LKEM.js.map} +0 -0
- /package/dist/{executor-3SVNESQ3.js.map → executor-DWVP4BSJ.js.map} +0 -0
- /package/dist/{executor-PJHMRZWJ.js.map → executor-HB2YMIYC.js.map} +0 -0
- /package/dist/{executor-VEZUBJNQ.js.map → executor-HO3SIRSF.js.map} +0 -0
- /package/dist/{fanout-sidecar-DSBVAR2P.js.map → fanout-sidecar-BMT7I6FI.js.map} +0 -0
- /package/dist/{issue-JSGGSVY4.js.map → issue-FZRTVGRE.js.map} +0 -0
- /package/dist/{ledger-PLMSH7LD.js.map → ledger-PMTR2Q62.js.map} +0 -0
- /package/dist/{noydb-PHXA5E6I.js.map → noydb-Y3ZLZNXA.js.map} +0 -0
- /package/dist/{public-envelope-7MTH2PVE.js.map → public-envelope-S2S2VR3F.js.map} +0 -0
- /package/dist/{registry-CMEVTOCN.js.map → registry-53A55ZZE.js.map} +0 -0
- /package/dist/{registry-OUZ3VBZA.js.map → registry-FKL4SLU4.js.map} +0 -0
- /package/dist/{registry-XUBRO5JJ.js.map → registry-IEU6ATO7.js.map} +0 -0
- /package/dist/{revoke-DBAGKIDA.js.map → revoke-AOCAVR56.js.map} +0 -0
- /package/dist/{signer-ADFJNS5W.js.map → signer-JMK6W2Y6.js.map} +0 -0
- /package/dist/{stale-BCIE3SMC.js.map → stale-IIIGOHBW.js.map} +0 -0
package/dist/index.cjs
CHANGED
|
@@ -46,7 +46,7 @@ var init_types = __esm({
|
|
|
46
46
|
});
|
|
47
47
|
|
|
48
48
|
// src/errors.ts
|
|
49
|
-
var NoydbError, DebugPlaintextError, DebugReservedFieldError, DecryptionError, TamperedError, InvalidKeyError, KeyringCorruptError, NoAccessError, ReadOnlyError, ReadOnlyAtInstantError, ReadOnlyFrameError, PermissionDeniedError, ExportCapabilityError, KeyringExpiredError, ImportCapabilityError, StoreCapabilityError, PrivilegeEscalationError, ReservedVaultNameError, PeriodClosedError, RecordLockedError, FieldFrozenError, IllegalTransitionError, InvariantError, AmendmentForbiddenError, DirectoryDisabledError, TierNotGrantedError, ElevationExpiredError, AlreadyElevatedError, TierDemoteDeniedError, DelegationTargetMissingError, ConflictError, LedgerContentionError, SequenceContentionError, SequenceOfflineError, NumberingUncertaintyError, BundleVersionConflictError, NetworkError, NotFoundError, ValidationError, SchemaValidationError, SchemaUpdateError, NonAdditiveSchemaChangeError, SchemaLockedError, SchemaFenceError, MigrationRequiredError, QuiesceTimeoutError, GroupCardinalityError, IndexRequiredError, UniqueConstraintError, UnsupportedIndexOptionError, IndexWriteFailureError, BundleIntegrityError, BundleSealMismatchError, ReservedCollectionNameError, DictKeyMissingError, DictKeyInUseError, MissingTranslationError, LocaleNotSpecifiedError, ScriptViolationError, StaticDictReadonlyError, UnknownDictCodeError, TranslatorNotConfiguredError, BackupLedgerError, BackupCorruptedError, TransferSealError, AttestationError, SessionExpiredError, SessionNotFoundError, SessionPolicyError, JoinTooLargeError, CrossJoinTooLargeError, CrossJoinSourceUnknownError, DanglingReferenceError, FilenameSanitizationError, PathEscapeError, DerivationCycleError, DerivationDepthError, DerivationOutputUnknownError, DerivationOutputShapeError, DerivationCapExceededError, MaterializedViewCycleError, MaterializedViewSourceUnknownError, MaterializedViewTooLargeError, MaterializedViewConfigError, OverlayBaseIsVirtualError, OverlayCollectionUnavailableError, OverlayNameCollisionError, OverlayIdMismatchError, SnapshotNotFoundError, UnknownShardError, ShardProvisioningError, DataResidencyError, VaultTemplateNotFoundError, ForgetStrategyNotConfiguredError, SealedRecordExpiredError, SealedRecordMismatchError, RecordCekNotFoundError;
|
|
49
|
+
var NoydbError, DebugPlaintextError, DebugReservedFieldError, DecryptionError, TamperedError, InvalidKeyError, KeyringCorruptError, NoAccessError, ReadOnlyError, ReadOnlyAtInstantError, ReadOnlyFrameError, PermissionDeniedError, ExportCapabilityError, KeyringExpiredError, ImportCapabilityError, StoreCapabilityError, PrivilegeEscalationError, ReservedVaultNameError, PeriodClosedError, RecordLockedError, FieldFrozenError, IllegalTransitionError, InvariantError, AmendmentForbiddenError, DirectoryDisabledError, TierNotGrantedError, ElevationExpiredError, AlreadyElevatedError, TierDemoteDeniedError, DelegationTargetMissingError, ConflictError, LedgerContentionError, SequenceContentionError, SequenceOfflineError, NumberingUncertaintyError, BundleVersionConflictError, NetworkError, NotFoundError, ValidationError, SchemaValidationError, SchemaUpdateError, NonAdditiveSchemaChangeError, SchemaLockedError, SchemaFenceError, MigrationRequiredError, QuiesceTimeoutError, GroupCardinalityError, IndexRequiredError, UniqueConstraintError, UnsupportedIndexOptionError, IndexWriteFailureError, BundleIntegrityError, BundleSealMismatchError, ReservedCollectionNameError, DictKeyMissingError, DictKeyInUseError, MissingTranslationError, LocaleNotSpecifiedError, ScriptViolationError, StaticDictReadonlyError, UnknownDictCodeError, TranslatorNotConfiguredError, BackupLedgerError, BackupCorruptedError, TransferSealError, AttestationError, SessionExpiredError, SessionNotFoundError, SessionPolicyError, JoinTooLargeError, CrossJoinTooLargeError, CrossJoinSourceUnknownError, DanglingReferenceError, FilenameSanitizationError, PathEscapeError, DerivationCycleError, DerivationDepthError, DerivationOutputUnknownError, DerivationOutputShapeError, DerivationCapExceededError, MaterializedViewCycleError, MaterializedViewSourceUnknownError, MaterializedViewTooLargeError, MaterializedViewConfigError, OverlayBaseIsVirtualError, OverlayCollectionUnavailableError, OverlayNameCollisionError, OverlayIdMismatchError, SnapshotNotFoundError, UnknownShardError, ShardProvisioningError, DataResidencyError, VaultTemplateNotFoundError, ForgetStrategyNotConfiguredError, SealedRecordExpiredError, SealedRecordMismatchError, RecordCekNotFoundError, EmbeddingDimMismatchError, EmbeddingModelMismatchError;
|
|
50
50
|
var init_errors = __esm({
|
|
51
51
|
"src/errors.ts"() {
|
|
52
52
|
"use strict";
|
|
@@ -1125,6 +1125,34 @@ Resolutions:
|
|
|
1125
1125
|
this.id = id;
|
|
1126
1126
|
}
|
|
1127
1127
|
};
|
|
1128
|
+
EmbeddingDimMismatchError = class extends NoydbError {
|
|
1129
|
+
field;
|
|
1130
|
+
expected;
|
|
1131
|
+
actual;
|
|
1132
|
+
constructor(field, expected, actual) {
|
|
1133
|
+
super(
|
|
1134
|
+
"EMBEDDING_DIM_MISMATCH",
|
|
1135
|
+
`Embedding for "${field}" has dim ${actual}, expected ${expected}.`
|
|
1136
|
+
);
|
|
1137
|
+
this.name = "EmbeddingDimMismatchError";
|
|
1138
|
+
this.field = field;
|
|
1139
|
+
this.expected = expected;
|
|
1140
|
+
this.actual = actual;
|
|
1141
|
+
}
|
|
1142
|
+
};
|
|
1143
|
+
EmbeddingModelMismatchError = class extends NoydbError {
|
|
1144
|
+
expected;
|
|
1145
|
+
found;
|
|
1146
|
+
constructor(expected, found) {
|
|
1147
|
+
super(
|
|
1148
|
+
"EMBEDDING_MODEL_MISMATCH",
|
|
1149
|
+
`Embedding model mismatch: collection uses "${expected}" but a stored vector is "${found}". Run vault.embeddings.reindex() after changing the encoder.`
|
|
1150
|
+
);
|
|
1151
|
+
this.name = "EmbeddingModelMismatchError";
|
|
1152
|
+
this.expected = expected;
|
|
1153
|
+
this.found = found;
|
|
1154
|
+
}
|
|
1155
|
+
};
|
|
1128
1156
|
}
|
|
1129
1157
|
});
|
|
1130
1158
|
|
|
@@ -10114,6 +10142,36 @@ var init_builder = __esm({
|
|
|
10114
10142
|
predicates
|
|
10115
10143
|
);
|
|
10116
10144
|
}
|
|
10145
|
+
/**
|
|
10146
|
+
* @internal — #308 L3. The ids of records matching this query's plan,
|
|
10147
|
+
* recovered by reference identity: `executePlanWithSource` returns the
|
|
10148
|
+
* ORIGINAL snapshot record references (money-decode and joins are applied
|
|
10149
|
+
* later, in `toArray`), so each matched record is found in the id-paired
|
|
10150
|
+
* `snapshotEntries()` map. Used by `collection.retrieve({ within })`.
|
|
10151
|
+
* Throws if the source is not collection-backed (no `snapshotEntries`).
|
|
10152
|
+
*/
|
|
10153
|
+
_idArray() {
|
|
10154
|
+
const entries = this.source.snapshotEntries?.();
|
|
10155
|
+
if (entries === void 0) {
|
|
10156
|
+
throw new Error(
|
|
10157
|
+
"Query._idArray(): the query source has no snapshotEntries(); retrieve({ within }) requires a collection-backed query (collection.query())."
|
|
10158
|
+
);
|
|
10159
|
+
}
|
|
10160
|
+
if (this.plan.clauses.some((c) => c.type === "crossJoin")) {
|
|
10161
|
+
throw new Error(
|
|
10162
|
+
"Query._idArray(): retrieve({ within }) does not support crossJoin queries (cross-join produces new row objects, breaking id recovery). Use where/filter/and/or, or a projection .join()."
|
|
10163
|
+
);
|
|
10164
|
+
}
|
|
10165
|
+
const refToId = /* @__PURE__ */ new Map();
|
|
10166
|
+
for (const { id, record } of entries) refToId.set(record, id);
|
|
10167
|
+
const matched = executePlanWithSource(this.source, this.plan, this.joinContext);
|
|
10168
|
+
const ids = [];
|
|
10169
|
+
for (const r of matched) {
|
|
10170
|
+
const id = refToId.get(r);
|
|
10171
|
+
if (id !== void 0) ids.push(id);
|
|
10172
|
+
}
|
|
10173
|
+
return ids;
|
|
10174
|
+
}
|
|
10117
10175
|
/**
|
|
10118
10176
|
* Filter by a registered deterministic predicate. Requires
|
|
10119
10177
|
* the Query to have been augmented with a predicates map (typically
|
|
@@ -12075,12 +12133,470 @@ var init_scan = __esm({
|
|
|
12075
12133
|
}
|
|
12076
12134
|
});
|
|
12077
12135
|
|
|
12136
|
+
// src/search/segment.ts
|
|
12137
|
+
var SEGMENTER, segmentTokens, segmentTokenizer;
|
|
12138
|
+
var init_segment = __esm({
|
|
12139
|
+
"src/search/segment.ts"() {
|
|
12140
|
+
"use strict";
|
|
12141
|
+
SEGMENTER = new Intl.Segmenter(void 0, { granularity: "word" });
|
|
12142
|
+
segmentTokens = (text) => {
|
|
12143
|
+
const out = [];
|
|
12144
|
+
if (!text) return out;
|
|
12145
|
+
for (const s of SEGMENTER.segment(text)) {
|
|
12146
|
+
if (s.isWordLike) out.push({ term: s.segment.normalize("NFKC").toLowerCase(), offset: s.index });
|
|
12147
|
+
}
|
|
12148
|
+
return out;
|
|
12149
|
+
};
|
|
12150
|
+
segmentTokenizer = (text) => segmentTokens(text).map((t) => t.term);
|
|
12151
|
+
}
|
|
12152
|
+
});
|
|
12153
|
+
|
|
12154
|
+
// src/search/inverted-index.ts
|
|
12155
|
+
var K12, B2, InvertedIndex;
|
|
12156
|
+
var init_inverted_index = __esm({
|
|
12157
|
+
"src/search/inverted-index.ts"() {
|
|
12158
|
+
"use strict";
|
|
12159
|
+
init_segment();
|
|
12160
|
+
K12 = 1.2;
|
|
12161
|
+
B2 = 0.75;
|
|
12162
|
+
InvertedIndex = class _InvertedIndex {
|
|
12163
|
+
// per field: df (term -> #docs), N (#docs), totalLen
|
|
12164
|
+
fieldStats = /* @__PURE__ */ new Map();
|
|
12165
|
+
docs = [];
|
|
12166
|
+
static build(docs) {
|
|
12167
|
+
const idx = new _InvertedIndex();
|
|
12168
|
+
for (const d of docs) {
|
|
12169
|
+
for (const f of d.fields) {
|
|
12170
|
+
const tokens = segmentTokens(f.text);
|
|
12171
|
+
const tf = /* @__PURE__ */ new Map();
|
|
12172
|
+
const firstOffset = /* @__PURE__ */ new Map();
|
|
12173
|
+
for (const t of tokens) {
|
|
12174
|
+
tf.set(t.term, (tf.get(t.term) ?? 0) + 1);
|
|
12175
|
+
if (!firstOffset.has(t.term)) firstOffset.set(t.term, t.offset);
|
|
12176
|
+
}
|
|
12177
|
+
const doc = { id: d.id, field: f.field, ...f.locale !== void 0 ? { locale: f.locale } : {}, text: f.text, len: tokens.length, tf, firstOffset };
|
|
12178
|
+
idx.docs.push(doc);
|
|
12179
|
+
let s = idx.fieldStats.get(f.field);
|
|
12180
|
+
if (!s) {
|
|
12181
|
+
s = { df: /* @__PURE__ */ new Map(), n: 0, totalLen: 0 };
|
|
12182
|
+
idx.fieldStats.set(f.field, s);
|
|
12183
|
+
}
|
|
12184
|
+
s.n += 1;
|
|
12185
|
+
s.totalLen += doc.len;
|
|
12186
|
+
for (const term of tf.keys()) s.df.set(term, (s.df.get(term) ?? 0) + 1);
|
|
12187
|
+
}
|
|
12188
|
+
}
|
|
12189
|
+
return idx;
|
|
12190
|
+
}
|
|
12191
|
+
query(query, opts = {}) {
|
|
12192
|
+
const terms = segmentTokenizer(query);
|
|
12193
|
+
if (terms.length === 0) return [];
|
|
12194
|
+
const usePrefix = opts.prefix ?? false;
|
|
12195
|
+
const exact = usePrefix ? terms.slice(0, -1) : terms;
|
|
12196
|
+
const prefix = usePrefix ? terms[terms.length - 1] : void 0;
|
|
12197
|
+
const match = opts.match ?? "any";
|
|
12198
|
+
const required = exact.length + (prefix !== void 0 ? 1 : 0);
|
|
12199
|
+
const best = /* @__PURE__ */ new Map();
|
|
12200
|
+
for (const doc of this.docs) {
|
|
12201
|
+
if (opts.fields !== void 0 && !opts.fields.includes(doc.field)) continue;
|
|
12202
|
+
const stats = this.fieldStats.get(doc.field);
|
|
12203
|
+
const avgdl = stats.totalLen / stats.n || 1;
|
|
12204
|
+
let score = 0;
|
|
12205
|
+
let matchedCount = 0;
|
|
12206
|
+
let snippetOffset = -1;
|
|
12207
|
+
const scoreTerm = (tf, df, offset) => {
|
|
12208
|
+
if (tf <= 0) return;
|
|
12209
|
+
matchedCount += 1;
|
|
12210
|
+
if (snippetOffset < 0 && offset >= 0) snippetOffset = offset;
|
|
12211
|
+
const idf = Math.log(1 + (stats.n - df + 0.5) / (df + 0.5));
|
|
12212
|
+
const denom = tf + K12 * (1 - B2 + B2 * (doc.len / avgdl));
|
|
12213
|
+
score += idf * (tf * (K12 + 1) / (denom || 1));
|
|
12214
|
+
};
|
|
12215
|
+
for (const qt of exact) scoreTerm(doc.tf.get(qt) ?? 0, stats.df.get(qt) ?? 0, doc.firstOffset.get(qt) ?? -1);
|
|
12216
|
+
if (prefix !== void 0) {
|
|
12217
|
+
const exactSet = new Set(exact);
|
|
12218
|
+
let ptf = 0;
|
|
12219
|
+
let poff = -1;
|
|
12220
|
+
for (const [term, c] of doc.tf) {
|
|
12221
|
+
if (term.startsWith(prefix) && !exactSet.has(term)) {
|
|
12222
|
+
ptf += c;
|
|
12223
|
+
if (poff < 0) poff = doc.firstOffset.get(term) ?? -1;
|
|
12224
|
+
}
|
|
12225
|
+
}
|
|
12226
|
+
if (ptf > 0) {
|
|
12227
|
+
let pdf = 0;
|
|
12228
|
+
for (const d of this.docs) {
|
|
12229
|
+
if (d.field === doc.field && [...d.tf.keys()].some((t) => t.startsWith(prefix))) pdf++;
|
|
12230
|
+
}
|
|
12231
|
+
scoreTerm(ptf, pdf || 1, poff);
|
|
12232
|
+
}
|
|
12233
|
+
}
|
|
12234
|
+
if (matchedCount === 0) continue;
|
|
12235
|
+
if (match === "all" && matchedCount < required) continue;
|
|
12236
|
+
const hit = {
|
|
12237
|
+
id: doc.id,
|
|
12238
|
+
score,
|
|
12239
|
+
field: doc.field,
|
|
12240
|
+
text: doc.text,
|
|
12241
|
+
offset: snippetOffset < 0 ? 0 : snippetOffset,
|
|
12242
|
+
...doc.locale !== void 0 ? { locale: doc.locale } : {}
|
|
12243
|
+
};
|
|
12244
|
+
const prev = best.get(doc.id);
|
|
12245
|
+
if (!prev || hit.score > prev.score) best.set(doc.id, hit);
|
|
12246
|
+
}
|
|
12247
|
+
const results = [...best.values()].sort((a, b) => b.score - a.score);
|
|
12248
|
+
return opts.limit !== void 0 ? results.slice(0, opts.limit) : results;
|
|
12249
|
+
}
|
|
12250
|
+
toSnapshot() {
|
|
12251
|
+
return {
|
|
12252
|
+
v: 1,
|
|
12253
|
+
fieldStats: [...this.fieldStats].map(([f, s]) => [f, { df: [...s.df], n: s.n, totalLen: s.totalLen }]),
|
|
12254
|
+
docs: this.docs.map((d) => ({
|
|
12255
|
+
id: d.id,
|
|
12256
|
+
field: d.field,
|
|
12257
|
+
text: d.text,
|
|
12258
|
+
len: d.len,
|
|
12259
|
+
tf: [...d.tf],
|
|
12260
|
+
firstOffset: [...d.firstOffset],
|
|
12261
|
+
...d.locale !== void 0 ? { locale: d.locale } : {}
|
|
12262
|
+
}))
|
|
12263
|
+
};
|
|
12264
|
+
}
|
|
12265
|
+
static fromSnapshot(s) {
|
|
12266
|
+
const idx = new _InvertedIndex();
|
|
12267
|
+
for (const [f, st] of s.fieldStats) idx.fieldStats.set(f, { df: new Map(st.df), n: st.n, totalLen: st.totalLen });
|
|
12268
|
+
for (const d of s.docs) {
|
|
12269
|
+
idx.docs.push({
|
|
12270
|
+
id: d.id,
|
|
12271
|
+
field: d.field,
|
|
12272
|
+
text: d.text,
|
|
12273
|
+
len: d.len,
|
|
12274
|
+
tf: new Map(d.tf),
|
|
12275
|
+
firstOffset: new Map(d.firstOffset),
|
|
12276
|
+
...d.locale !== void 0 ? { locale: d.locale } : {}
|
|
12277
|
+
});
|
|
12278
|
+
}
|
|
12279
|
+
return idx;
|
|
12280
|
+
}
|
|
12281
|
+
};
|
|
12282
|
+
}
|
|
12283
|
+
});
|
|
12284
|
+
|
|
12285
|
+
// src/search/snippet.ts
|
|
12286
|
+
function extractSnippet(text, offset, window2 = 80) {
|
|
12287
|
+
const chars = Array.from(text);
|
|
12288
|
+
if (chars.length <= window2) return text;
|
|
12289
|
+
const cpOffset = Array.from(text.slice(0, Math.max(0, offset))).length;
|
|
12290
|
+
const half = Math.floor(window2 / 2);
|
|
12291
|
+
let start = Math.max(0, cpOffset - half);
|
|
12292
|
+
const end = Math.min(chars.length, start + window2);
|
|
12293
|
+
start = Math.max(0, end - window2);
|
|
12294
|
+
const body = chars.slice(start, end).join("");
|
|
12295
|
+
return `${start > 0 ? "\u2026" : ""}${body}${end < chars.length ? "\u2026" : ""}`;
|
|
12296
|
+
}
|
|
12297
|
+
var init_snippet = __esm({
|
|
12298
|
+
"src/search/snippet.ts"() {
|
|
12299
|
+
"use strict";
|
|
12300
|
+
}
|
|
12301
|
+
});
|
|
12302
|
+
|
|
12303
|
+
// src/search/index-store.ts
|
|
12304
|
+
var MemoryIndexStore;
|
|
12305
|
+
var init_index_store = __esm({
|
|
12306
|
+
"src/search/index-store.ts"() {
|
|
12307
|
+
"use strict";
|
|
12308
|
+
init_inverted_index();
|
|
12309
|
+
MemoryIndexStore = class {
|
|
12310
|
+
index;
|
|
12311
|
+
get built() {
|
|
12312
|
+
return this.index !== void 0;
|
|
12313
|
+
}
|
|
12314
|
+
async ensureBuilt(build) {
|
|
12315
|
+
if (this.index === void 0) this.index = InvertedIndex.build(build());
|
|
12316
|
+
return this.index;
|
|
12317
|
+
}
|
|
12318
|
+
markDirty() {
|
|
12319
|
+
this.index = void 0;
|
|
12320
|
+
}
|
|
12321
|
+
async flush() {
|
|
12322
|
+
}
|
|
12323
|
+
};
|
|
12324
|
+
}
|
|
12325
|
+
});
|
|
12326
|
+
|
|
12327
|
+
// src/search/build-docs.ts
|
|
12328
|
+
function buildStringFieldEntries(record, textIndexes, only) {
|
|
12329
|
+
const fields = only ? textIndexes.filter((f) => only.includes(f)) : textIndexes;
|
|
12330
|
+
const out = [];
|
|
12331
|
+
for (const field of fields) {
|
|
12332
|
+
for (const leaf of getAtPath(record, field)) {
|
|
12333
|
+
if (typeof leaf === "string" && leaf !== "") out.push({ field, text: leaf });
|
|
12334
|
+
}
|
|
12335
|
+
}
|
|
12336
|
+
return out;
|
|
12337
|
+
}
|
|
12338
|
+
function buildI18nFieldEntries(record, i18nFields, textIndexes, only) {
|
|
12339
|
+
const fields = (only ? textIndexes.filter((f) => only.includes(f)) : textIndexes).filter((f) => f in i18nFields);
|
|
12340
|
+
const out = [];
|
|
12341
|
+
for (const field of fields) {
|
|
12342
|
+
for (const leaf of getAtPath(record, field)) {
|
|
12343
|
+
if (!leaf || typeof leaf !== "object" || Array.isArray(leaf)) continue;
|
|
12344
|
+
for (const [locale, val] of Object.entries(leaf)) {
|
|
12345
|
+
if (typeof val === "string" && val !== "") out.push({ field, locale, text: val });
|
|
12346
|
+
}
|
|
12347
|
+
}
|
|
12348
|
+
}
|
|
12349
|
+
return out;
|
|
12350
|
+
}
|
|
12351
|
+
function buildDictKeyFieldEntries(record, dictKeyFields, labelMaps, textIndexes, only) {
|
|
12352
|
+
const fields = (only ? textIndexes.filter((f) => only.includes(f)) : textIndexes).filter((f) => f in dictKeyFields);
|
|
12353
|
+
const out = [];
|
|
12354
|
+
for (const field of fields) {
|
|
12355
|
+
const map = labelMaps.get(field);
|
|
12356
|
+
if (!map) continue;
|
|
12357
|
+
for (const leaf of getAtPath(record, field)) {
|
|
12358
|
+
const keys = typeof leaf === "string" ? [leaf] : Array.isArray(leaf) ? leaf.filter((k) => typeof k === "string") : [];
|
|
12359
|
+
for (const key of keys) {
|
|
12360
|
+
const labels = map.get(key);
|
|
12361
|
+
if (!labels) continue;
|
|
12362
|
+
for (const [locale, label] of Object.entries(labels)) {
|
|
12363
|
+
if (label !== "") out.push({ field, locale, text: label });
|
|
12364
|
+
}
|
|
12365
|
+
}
|
|
12366
|
+
}
|
|
12367
|
+
}
|
|
12368
|
+
return out;
|
|
12369
|
+
}
|
|
12370
|
+
function buildBlobFieldEntries(filenamesByField) {
|
|
12371
|
+
const out = [];
|
|
12372
|
+
for (const [field, names] of filenamesByField) {
|
|
12373
|
+
for (const name of names) if (name !== "") out.push({ field, text: name });
|
|
12374
|
+
}
|
|
12375
|
+
return out;
|
|
12376
|
+
}
|
|
12377
|
+
var init_build_docs = __esm({
|
|
12378
|
+
"src/search/build-docs.ts"() {
|
|
12379
|
+
"use strict";
|
|
12380
|
+
init_core();
|
|
12381
|
+
}
|
|
12382
|
+
});
|
|
12383
|
+
|
|
12384
|
+
// src/search/fuse.ts
|
|
12385
|
+
function fuseRetrieval(lists, opts = {}) {
|
|
12386
|
+
const k = opts.k ?? 60;
|
|
12387
|
+
const acc = /* @__PURE__ */ new Map();
|
|
12388
|
+
for (const list of lists) {
|
|
12389
|
+
for (const hit of list) {
|
|
12390
|
+
const contribution = 1 / (k + hit.rank);
|
|
12391
|
+
const prev = acc.get(hit.id);
|
|
12392
|
+
if (prev === void 0) {
|
|
12393
|
+
acc.set(hit.id, { score: contribution, hit });
|
|
12394
|
+
} else {
|
|
12395
|
+
prev.score += contribution;
|
|
12396
|
+
prev.hit = mergePresentation(prev.hit, hit);
|
|
12397
|
+
}
|
|
12398
|
+
}
|
|
12399
|
+
}
|
|
12400
|
+
const merged = [...acc.values()].sort(
|
|
12401
|
+
(a, b) => b.score - a.score || (a.hit.id < b.hit.id ? -1 : a.hit.id > b.hit.id ? 1 : 0)
|
|
12402
|
+
);
|
|
12403
|
+
const limited = opts.limit !== void 0 ? merged.slice(0, opts.limit) : merged;
|
|
12404
|
+
return limited.map((m, i) => ({ ...m.hit, score: m.score, rank: i + 1 }));
|
|
12405
|
+
}
|
|
12406
|
+
function mergePresentation(a, b) {
|
|
12407
|
+
const lexical = a.field !== "(vector)" ? a : b;
|
|
12408
|
+
const other = lexical === a ? b : a;
|
|
12409
|
+
return {
|
|
12410
|
+
...lexical,
|
|
12411
|
+
...lexical.record === void 0 && other.record !== void 0 ? { record: other.record } : {}
|
|
12412
|
+
};
|
|
12413
|
+
}
|
|
12414
|
+
var init_fuse = __esm({
|
|
12415
|
+
"src/search/fuse.ts"() {
|
|
12416
|
+
"use strict";
|
|
12417
|
+
}
|
|
12418
|
+
});
|
|
12419
|
+
|
|
12078
12420
|
// src/search/index.ts
|
|
12079
12421
|
var init_search = __esm({
|
|
12080
12422
|
"src/search/index.ts"() {
|
|
12081
12423
|
"use strict";
|
|
12082
12424
|
init_tokenize();
|
|
12083
12425
|
init_scan();
|
|
12426
|
+
init_fuse();
|
|
12427
|
+
}
|
|
12428
|
+
});
|
|
12429
|
+
|
|
12430
|
+
// src/search/serialize.ts
|
|
12431
|
+
function serializeIndex(idx) {
|
|
12432
|
+
return JSON.stringify(idx.toSnapshot());
|
|
12433
|
+
}
|
|
12434
|
+
function deserializeIndex(json) {
|
|
12435
|
+
return InvertedIndex.fromSnapshot(JSON.parse(json));
|
|
12436
|
+
}
|
|
12437
|
+
var init_serialize = __esm({
|
|
12438
|
+
"src/search/serialize.ts"() {
|
|
12439
|
+
"use strict";
|
|
12440
|
+
init_inverted_index();
|
|
12441
|
+
}
|
|
12442
|
+
});
|
|
12443
|
+
|
|
12444
|
+
// src/search/persisted-index-store.ts
|
|
12445
|
+
function fpEqual(a, b) {
|
|
12446
|
+
return a.count === b.count && a.maxVersion === b.maxVersion;
|
|
12447
|
+
}
|
|
12448
|
+
var PersistedIndexStore;
|
|
12449
|
+
var init_persisted_index_store = __esm({
|
|
12450
|
+
"src/search/persisted-index-store.ts"() {
|
|
12451
|
+
"use strict";
|
|
12452
|
+
init_inverted_index();
|
|
12453
|
+
init_serialize();
|
|
12454
|
+
PersistedIndexStore = class {
|
|
12455
|
+
constructor(cb) {
|
|
12456
|
+
this.cb = cb;
|
|
12457
|
+
this.debounceMs = cb.debounceMs ?? 1e3;
|
|
12458
|
+
}
|
|
12459
|
+
cb;
|
|
12460
|
+
index;
|
|
12461
|
+
timer = null;
|
|
12462
|
+
lastBuild;
|
|
12463
|
+
debounceMs;
|
|
12464
|
+
get built() {
|
|
12465
|
+
return this.index !== void 0;
|
|
12466
|
+
}
|
|
12467
|
+
async ensureBuilt(build) {
|
|
12468
|
+
this.lastBuild = build;
|
|
12469
|
+
if (this.index !== void 0) return this.index;
|
|
12470
|
+
const loaded = await this.cb.load();
|
|
12471
|
+
if (loaded !== null && fpEqual(loaded.fingerprint, this.cb.currentFingerprint())) {
|
|
12472
|
+
this.index = deserializeIndex(loaded.json);
|
|
12473
|
+
return this.index;
|
|
12474
|
+
}
|
|
12475
|
+
this.index = InvertedIndex.build(build());
|
|
12476
|
+
await this.persist();
|
|
12477
|
+
return this.index;
|
|
12478
|
+
}
|
|
12479
|
+
markDirty() {
|
|
12480
|
+
this.index = void 0;
|
|
12481
|
+
if (this.timer) clearTimeout(this.timer);
|
|
12482
|
+
this.timer = setTimeout(() => {
|
|
12483
|
+
this.timer = null;
|
|
12484
|
+
void this.rebuildAndPersist().catch(() => {
|
|
12485
|
+
});
|
|
12486
|
+
}, this.debounceMs);
|
|
12487
|
+
}
|
|
12488
|
+
/** Force an immediate persist (cancels any pending debounce). */
|
|
12489
|
+
async flush() {
|
|
12490
|
+
if (this.timer) {
|
|
12491
|
+
clearTimeout(this.timer);
|
|
12492
|
+
this.timer = null;
|
|
12493
|
+
}
|
|
12494
|
+
await this.rebuildAndPersist();
|
|
12495
|
+
}
|
|
12496
|
+
/** Delete the persisted blob and drop the in-memory index (forget/erasure). */
|
|
12497
|
+
async removePersisted() {
|
|
12498
|
+
if (this.timer) {
|
|
12499
|
+
clearTimeout(this.timer);
|
|
12500
|
+
this.timer = null;
|
|
12501
|
+
}
|
|
12502
|
+
this.index = void 0;
|
|
12503
|
+
await this.cb.remove();
|
|
12504
|
+
}
|
|
12505
|
+
/** Rebuild using the last known build thunk, then persist. */
|
|
12506
|
+
async rebuildAndPersist() {
|
|
12507
|
+
if (this.lastBuild === void 0) return;
|
|
12508
|
+
if (this.index === void 0) {
|
|
12509
|
+
this.index = InvertedIndex.build(this.lastBuild());
|
|
12510
|
+
}
|
|
12511
|
+
await this.persist();
|
|
12512
|
+
}
|
|
12513
|
+
async persist() {
|
|
12514
|
+
if (this.index === void 0) return;
|
|
12515
|
+
await this.cb.save(serializeIndex(this.index), this.cb.currentFingerprint());
|
|
12516
|
+
}
|
|
12517
|
+
};
|
|
12518
|
+
}
|
|
12519
|
+
});
|
|
12520
|
+
|
|
12521
|
+
// src/embeddings/cosine.ts
|
|
12522
|
+
function cosine(a, b) {
|
|
12523
|
+
if (a.length !== b.length) return 0;
|
|
12524
|
+
let dot = 0, na = 0, nb = 0;
|
|
12525
|
+
for (let i = 0; i < a.length; i++) {
|
|
12526
|
+
const x = a[i], y = b[i];
|
|
12527
|
+
dot += x * y;
|
|
12528
|
+
na += x * x;
|
|
12529
|
+
nb += y * y;
|
|
12530
|
+
}
|
|
12531
|
+
if (na === 0 || nb === 0) return 0;
|
|
12532
|
+
return dot / (Math.sqrt(na) * Math.sqrt(nb));
|
|
12533
|
+
}
|
|
12534
|
+
var init_cosine = __esm({
|
|
12535
|
+
"src/embeddings/cosine.ts"() {
|
|
12536
|
+
"use strict";
|
|
12537
|
+
}
|
|
12538
|
+
});
|
|
12539
|
+
|
|
12540
|
+
// src/embeddings/descriptor.ts
|
|
12541
|
+
function embeddingSourceText(record, source) {
|
|
12542
|
+
const fields = typeof source === "string" ? [source] : source;
|
|
12543
|
+
const parts = [];
|
|
12544
|
+
for (const f of fields) {
|
|
12545
|
+
for (const leaf of getAtPath(record, f)) {
|
|
12546
|
+
if (typeof leaf === "string" && leaf !== "") parts.push(leaf);
|
|
12547
|
+
}
|
|
12548
|
+
}
|
|
12549
|
+
return parts.join(" ");
|
|
12550
|
+
}
|
|
12551
|
+
var init_descriptor2 = __esm({
|
|
12552
|
+
"src/embeddings/descriptor.ts"() {
|
|
12553
|
+
"use strict";
|
|
12554
|
+
init_core();
|
|
12555
|
+
}
|
|
12556
|
+
});
|
|
12557
|
+
|
|
12558
|
+
// src/embeddings/vector-set.ts
|
|
12559
|
+
var VectorSet;
|
|
12560
|
+
var init_vector_set = __esm({
|
|
12561
|
+
"src/embeddings/vector-set.ts"() {
|
|
12562
|
+
"use strict";
|
|
12563
|
+
init_cosine();
|
|
12564
|
+
init_errors();
|
|
12565
|
+
VectorSet = class {
|
|
12566
|
+
vectors;
|
|
12567
|
+
get loaded() {
|
|
12568
|
+
return this.vectors !== void 0;
|
|
12569
|
+
}
|
|
12570
|
+
async ensureLoaded(load) {
|
|
12571
|
+
if (this.vectors === void 0) this.vectors = await load();
|
|
12572
|
+
}
|
|
12573
|
+
markDirty() {
|
|
12574
|
+
this.vectors = void 0;
|
|
12575
|
+
}
|
|
12576
|
+
cosineTopK(query, k, opts = {}) {
|
|
12577
|
+
const all = this.vectors ?? [];
|
|
12578
|
+
const minScore = opts.minScore ?? -Infinity;
|
|
12579
|
+
const hits = [];
|
|
12580
|
+
for (const v of all) {
|
|
12581
|
+
if (opts.expectModel !== void 0 && v.model !== opts.expectModel) {
|
|
12582
|
+
throw new EmbeddingModelMismatchError(opts.expectModel, v.model);
|
|
12583
|
+
}
|
|
12584
|
+
const score = cosine(query, v.vec);
|
|
12585
|
+
if (score >= minScore) hits.push({ id: v.id, score });
|
|
12586
|
+
}
|
|
12587
|
+
hits.sort((a, b) => b.score - a.score);
|
|
12588
|
+
return hits.slice(0, k);
|
|
12589
|
+
}
|
|
12590
|
+
};
|
|
12591
|
+
}
|
|
12592
|
+
});
|
|
12593
|
+
|
|
12594
|
+
// src/embeddings/index.ts
|
|
12595
|
+
var init_embeddings = __esm({
|
|
12596
|
+
"src/embeddings/index.ts"() {
|
|
12597
|
+
"use strict";
|
|
12598
|
+
init_descriptor2();
|
|
12599
|
+
init_vector_set();
|
|
12084
12600
|
}
|
|
12085
12601
|
});
|
|
12086
12602
|
|
|
@@ -13739,7 +14255,12 @@ var init_collection = __esm({
|
|
|
13739
14255
|
init_lazy_builder();
|
|
13740
14256
|
init_strategy5();
|
|
13741
14257
|
init_search();
|
|
14258
|
+
init_index_store();
|
|
14259
|
+
init_persisted_index_store();
|
|
14260
|
+
init_snippet();
|
|
14261
|
+
init_build_docs();
|
|
13742
14262
|
init_errors();
|
|
14263
|
+
init_embeddings();
|
|
13743
14264
|
init_unique_constraints();
|
|
13744
14265
|
init_cache();
|
|
13745
14266
|
init_ulid();
|
|
@@ -13891,12 +14412,33 @@ var init_collection = __esm({
|
|
|
13891
14412
|
* Declared via the `i18nFields` collection option.
|
|
13892
14413
|
*/
|
|
13893
14414
|
i18nFields;
|
|
14415
|
+
/**
|
|
14416
|
+
* #308 L1 — the configured string fields exposed to `retrieve()`. `undefined`
|
|
14417
|
+
* for ordinary collections, so the search path costs nothing when unused.
|
|
14418
|
+
*/
|
|
14419
|
+
textIndexes;
|
|
14420
|
+
/**
|
|
14421
|
+
* #308 L1 — the session-scoped lexical index store. `undefined` (so the dirty
|
|
14422
|
+
* poke + retrieve are zero-cost) unless `textIndexes` is non-empty.
|
|
14423
|
+
*/
|
|
14424
|
+
searchIndexStore;
|
|
13894
14425
|
/**
|
|
13895
14426
|
* #435 — the densify-enabled subset of {@link i18nFields} (fields whose
|
|
13896
14427
|
* descriptor opts in via `densifyOnWrite: true`). `undefined` when none opt
|
|
13897
14428
|
* in, so the write path skips all densify work for ordinary collections.
|
|
13898
14429
|
*/
|
|
13899
14430
|
i18nDensifyFields;
|
|
14431
|
+
/**
|
|
14432
|
+
* #308 L2 — embedding config for write-time vector derivation. `undefined`
|
|
14433
|
+
* for ordinary collections (zero cost). When set, `put()` encodes the
|
|
14434
|
+
* source field(s) and stores an encrypted `_vec` sidecar.
|
|
14435
|
+
*/
|
|
14436
|
+
embeddings;
|
|
14437
|
+
/**
|
|
14438
|
+
* #308 L2 — in-memory vector set, populated lazily from `_vec` sidecars.
|
|
14439
|
+
* `undefined` when no embedding config is declared.
|
|
14440
|
+
*/
|
|
14441
|
+
vectorSet;
|
|
13900
14442
|
/**
|
|
13901
14443
|
* Map of field name → `DictKeyDescriptor` for fields declared with
|
|
13902
14444
|
* `dictKey()`. Used by `get()`/`list()` to add `<field>Label` virtual
|
|
@@ -13923,6 +14465,12 @@ var init_collection = __esm({
|
|
|
13923
14465
|
* Signature: `(dictName, key, locale, fallback?) => Promise<string | undefined>`
|
|
13924
14466
|
*/
|
|
13925
14467
|
dictLabelResolver;
|
|
14468
|
+
/**
|
|
14469
|
+
* #308 L1 — async callback provided by the Vault to open a dynamic
|
|
14470
|
+
* dictionary handle (for label-map pre-computation in the search index).
|
|
14471
|
+
* Only used in `resolveDictLabelMaps()`; static dicts bypass this entirely.
|
|
14472
|
+
*/
|
|
14473
|
+
getDictionary;
|
|
13926
14474
|
/**
|
|
13927
14475
|
* Synchronous callback provided by the Vault that validates
|
|
13928
14476
|
* i18nText fields on `put()`. Throws `MissingTranslationError` when
|
|
@@ -14083,15 +14631,25 @@ var init_collection = __esm({
|
|
|
14083
14631
|
this.refEnforcer = opts.refEnforcer;
|
|
14084
14632
|
this.joinResolver = opts.joinResolver;
|
|
14085
14633
|
this.i18nFields = opts.i18nFields;
|
|
14634
|
+
this.textIndexes = opts.textIndexes;
|
|
14635
|
+
this.searchIndexStore = opts.textIndexes && opts.textIndexes.length > 0 ? opts.textIndexPersist ? new PersistedIndexStore(this.buildPersistedIndexCallbacks()) : new MemoryIndexStore() : void 0;
|
|
14086
14636
|
const densifyFields = opts.i18nFields ? Object.fromEntries(
|
|
14087
14637
|
Object.entries(opts.i18nFields).filter(([, d]) => d.options.densifyOnWrite === true)
|
|
14088
14638
|
) : {};
|
|
14089
14639
|
this.i18nDensifyFields = Object.keys(densifyFields).length > 0 ? densifyFields : void 0;
|
|
14640
|
+
if (opts.embeddings && opts.crdt) {
|
|
14641
|
+
throw new Error(
|
|
14642
|
+
`Collection "${opts.name}": embeddings are not supported on CRDT collections (L2). Use a non-CRDT collection for semantic search.`
|
|
14643
|
+
);
|
|
14644
|
+
}
|
|
14645
|
+
this.embeddings = opts.embeddings;
|
|
14646
|
+
this.vectorSet = opts.embeddings ? new VectorSet() : void 0;
|
|
14090
14647
|
this.dictKeyFields = opts.dictKeyFields;
|
|
14091
14648
|
if (opts.moneyFields) validateMoneyFieldPaths(opts.moneyFields);
|
|
14092
14649
|
this.moneyFields = opts.moneyFields;
|
|
14093
14650
|
this.computed = opts.computed;
|
|
14094
14651
|
this.dictLabelResolver = opts.dictLabelResolver;
|
|
14652
|
+
this.getDictionary = opts.getDictionary;
|
|
14095
14653
|
this.i18nPutValidator = opts.i18nPutValidator;
|
|
14096
14654
|
this.autoTranslateHook = opts.autoTranslateHook;
|
|
14097
14655
|
this.defaultLocale = opts.defaultLocale;
|
|
@@ -14673,6 +15231,7 @@ var init_collection = __esm({
|
|
|
14673
15231
|
}
|
|
14674
15232
|
await this.onDirty?.(this.name, id, "put", version2);
|
|
14675
15233
|
this.emitter.emit("change", { vault: this.vault, collection: this.name, id, action: "put" });
|
|
15234
|
+
this.searchIndexStore?.markDirty();
|
|
14676
15235
|
await this.onAccess?.("put", id);
|
|
14677
15236
|
await this.dispatchDerivations(id, record, version2);
|
|
14678
15237
|
await this.dispatchMaterializedViews(id, record);
|
|
@@ -14714,6 +15273,15 @@ var init_collection = __esm({
|
|
|
14714
15273
|
}
|
|
14715
15274
|
const envelope = await this.encryptRecord(record, version, cek, options?.source, options?.sourceTs);
|
|
14716
15275
|
await this.adapter.put(this.vault, this.name, id, envelope);
|
|
15276
|
+
if (this.embeddings) {
|
|
15277
|
+
const text = embeddingSourceText(record, this.embeddings.source);
|
|
15278
|
+
const vec = await this.embeddings.encode(text);
|
|
15279
|
+
if (vec.length !== this.embeddings.dim) throw new EmbeddingDimMismatchError("embeddings", this.embeddings.dim, vec.length);
|
|
15280
|
+
const body = JSON.stringify({ vec: Array.from(vec), model: this.embeddings.model, dim: this.embeddings.dim });
|
|
15281
|
+
const vecEnv = await this.encryptJsonString(body, version);
|
|
15282
|
+
await this.adapter.put(this.vault, "_vec", id, vecEnv);
|
|
15283
|
+
this.vectorSet?.markDirty();
|
|
15284
|
+
}
|
|
14717
15285
|
if (this.ledger) {
|
|
14718
15286
|
const appendInput = {
|
|
14719
15287
|
op: "put",
|
|
@@ -14744,6 +15312,7 @@ var init_collection = __esm({
|
|
|
14744
15312
|
id,
|
|
14745
15313
|
action: "put"
|
|
14746
15314
|
});
|
|
15315
|
+
this.searchIndexStore?.markDirty();
|
|
14747
15316
|
await this.onAccess?.("put", id);
|
|
14748
15317
|
await this.dispatchDerivations(id, record, version);
|
|
14749
15318
|
await this.dispatchMaterializedViews(id, record);
|
|
@@ -15267,6 +15836,7 @@ var init_collection = __esm({
|
|
|
15267
15836
|
id,
|
|
15268
15837
|
action: "delete"
|
|
15269
15838
|
});
|
|
15839
|
+
this.searchIndexStore?.markDirty();
|
|
15270
15840
|
await this.onAccess?.("delete", id);
|
|
15271
15841
|
if (!internal) {
|
|
15272
15842
|
await this.dispatchMaterializedViewsOnDelete(id);
|
|
@@ -15451,6 +16021,252 @@ var init_collection = __esm({
|
|
|
15451
16021
|
for (const [id, e] of this.cache) entries.push({ id, record: stripI18nFilled(e.record) });
|
|
15452
16022
|
return searchScan(entries, field, query, opts);
|
|
15453
16023
|
}
|
|
16024
|
+
/** #308 L1 — build IndexDoc[] for the configured text fields over the live cache. */
|
|
16025
|
+
buildRetrievalDocs(labelMaps, blobFilenames, only) {
|
|
16026
|
+
const docs = [];
|
|
16027
|
+
for (const [id, e] of this.cache) {
|
|
16028
|
+
const rec = stripI18nFilled(e.record);
|
|
16029
|
+
const fields = buildStringFieldEntries(rec, this.textIndexes ?? [], only);
|
|
16030
|
+
if (this.i18nFields) fields.push(...buildI18nFieldEntries(rec, this.i18nFields, this.textIndexes ?? [], only));
|
|
16031
|
+
if (this.dictKeyFields) fields.push(...buildDictKeyFieldEntries(rec, this.dictKeyFields, labelMaps, this.textIndexes ?? [], only));
|
|
16032
|
+
const blobNames = blobFilenames.get(id);
|
|
16033
|
+
if (blobNames) fields.push(...buildBlobFieldEntries(blobNames));
|
|
16034
|
+
if (fields.length > 0) docs.push({ id, fields });
|
|
16035
|
+
}
|
|
16036
|
+
return docs;
|
|
16037
|
+
}
|
|
16038
|
+
/** #308 L1 — true iff any configured text index is also a blob field (gates ALL slot I/O). */
|
|
16039
|
+
hasIndexedBlobFields(only) {
|
|
16040
|
+
if (!this.blobFields || !this.textIndexes) return false;
|
|
16041
|
+
const fields = only ? this.textIndexes.filter((f) => only.includes(f)) : this.textIndexes;
|
|
16042
|
+
return fields.some((f) => f in this.blobFields);
|
|
16043
|
+
}
|
|
16044
|
+
/**
|
|
16045
|
+
* #308 L1 — resolve `recordId -> (blobField -> filenames[])` by listing slots
|
|
16046
|
+
* for the configured blob fields of each cached record. Blob slot metadata is
|
|
16047
|
+
* NOT inline on the record: it lives in a separate `_blob_slots_*` collection,
|
|
16048
|
+
* so this costs ONE `blob(id).list()` (a `listSlots`) per record at build time
|
|
16049
|
+
* — the heaviest indexing source. Fully gated by {@link hasIndexedBlobFields};
|
|
16050
|
+
* non-blob (and blob-but-not-indexed) collections do ZERO slot I/O.
|
|
16051
|
+
*/
|
|
16052
|
+
async resolveBlobFilenames(only) {
|
|
16053
|
+
const out = /* @__PURE__ */ new Map();
|
|
16054
|
+
if (!this.hasIndexedBlobFields(only)) return out;
|
|
16055
|
+
const indexed = (only ? this.textIndexes.filter((f) => only.includes(f)) : this.textIndexes).filter((f) => f in this.blobFields);
|
|
16056
|
+
const indexedSet = new Set(indexed);
|
|
16057
|
+
for (const id of this.cache.keys()) {
|
|
16058
|
+
let slots;
|
|
16059
|
+
try {
|
|
16060
|
+
slots = await this.blob(id).list();
|
|
16061
|
+
} catch {
|
|
16062
|
+
continue;
|
|
16063
|
+
}
|
|
16064
|
+
let byField;
|
|
16065
|
+
for (const slot of slots) {
|
|
16066
|
+
if (!indexedSet.has(slot.name) || !slot.filename) continue;
|
|
16067
|
+
if (!byField) {
|
|
16068
|
+
byField = /* @__PURE__ */ new Map();
|
|
16069
|
+
out.set(id, byField);
|
|
16070
|
+
}
|
|
16071
|
+
const names = byField.get(slot.name);
|
|
16072
|
+
if (names) names.push(slot.filename);
|
|
16073
|
+
else byField.set(slot.name, [slot.filename]);
|
|
16074
|
+
}
|
|
16075
|
+
}
|
|
16076
|
+
return out;
|
|
16077
|
+
}
|
|
16078
|
+
/** #308 L1 — field -> (key -> {locale->label}) for dictKey fields; static from table, dynamic via getDictionary().list(). */
|
|
16079
|
+
async resolveDictLabelMaps() {
|
|
16080
|
+
const maps = /* @__PURE__ */ new Map();
|
|
16081
|
+
if (!this.dictKeyFields || !this.textIndexes) return maps;
|
|
16082
|
+
for (const field of this.textIndexes) {
|
|
16083
|
+
const desc = this.dictKeyFields[field];
|
|
16084
|
+
if (!desc) continue;
|
|
16085
|
+
const m = /* @__PURE__ */ new Map();
|
|
16086
|
+
if (isStaticDictDescriptor(desc)) {
|
|
16087
|
+
for (const [key, labels] of Object.entries(desc.table)) m.set(key, labels);
|
|
16088
|
+
} else {
|
|
16089
|
+
if (this.getDictionary) {
|
|
16090
|
+
const handle = await this.getDictionary(desc.name);
|
|
16091
|
+
for (const e of await handle.list()) m.set(e.key, e.labels);
|
|
16092
|
+
}
|
|
16093
|
+
}
|
|
16094
|
+
maps.set(field, m);
|
|
16095
|
+
}
|
|
16096
|
+
return maps;
|
|
16097
|
+
}
|
|
16098
|
+
/** #308 L1.5 — force-persist the lexical index now (e.g. on save/idle). Persists only when textIndexPersist is enabled; a no-op otherwise. */
|
|
16099
|
+
async flushIndex() {
|
|
16100
|
+
if (!this.searchIndexStore) return;
|
|
16101
|
+
await this.ensureHydrated();
|
|
16102
|
+
const labelMaps = await this.resolveDictLabelMaps();
|
|
16103
|
+
const blobFilenames = await this.resolveBlobFilenames();
|
|
16104
|
+
await this.searchIndexStore.ensureBuilt(() => this.buildRetrievalDocs(labelMaps, blobFilenames));
|
|
16105
|
+
await this.searchIndexStore.flush?.();
|
|
16106
|
+
}
|
|
16107
|
+
/** #308 L2 — load + decrypt all _vec sidecars into StoredVector[] for the VectorSet. */
|
|
16108
|
+
buildVectorLoad() {
|
|
16109
|
+
return async () => {
|
|
16110
|
+
const ids = await this.adapter.list(this.vault, "_vec");
|
|
16111
|
+
const out = [];
|
|
16112
|
+
for (const id of ids) {
|
|
16113
|
+
const env = await this.adapter.get(this.vault, "_vec", id);
|
|
16114
|
+
if (!env) continue;
|
|
16115
|
+
const body = await this.decryptJsonString(env);
|
|
16116
|
+
if (body === null) continue;
|
|
16117
|
+
const parsed = JSON.parse(body);
|
|
16118
|
+
out.push({ id, vec: new Float32Array(parsed.vec), model: parsed.model });
|
|
16119
|
+
}
|
|
16120
|
+
return out;
|
|
16121
|
+
};
|
|
16122
|
+
}
|
|
16123
|
+
/**
|
|
16124
|
+
* #308 L1.5 — build the PersistedIndexCallbacks bridge: crypto lives here
|
|
16125
|
+
* (collection has getDEK / encryptJsonString / decryptJsonString / adapter),
|
|
16126
|
+
* the index store itself is crypto-free.
|
|
16127
|
+
*
|
|
16128
|
+
* Fingerprint encoding: body-wrap approach — save(json, fp) stores
|
|
16129
|
+
* JSON.stringify({ fp, idx: json }) as the encrypted body so the standard
|
|
16130
|
+
* EncryptedEnvelope shape is never extended. load() decrypts and JSON.parses
|
|
16131
|
+
* the wrapper back out.
|
|
16132
|
+
*
|
|
16133
|
+
* Cache shape: this.cache stores { record, version } — currentFingerprint()
|
|
16134
|
+
* iterates over e.version.
|
|
16135
|
+
*/
|
|
16136
|
+
buildPersistedIndexCallbacks() {
|
|
16137
|
+
const FT = "_ftindex";
|
|
16138
|
+
return {
|
|
16139
|
+
load: async () => {
|
|
16140
|
+
const env = await this.adapter.get(this.vault, FT, this.name);
|
|
16141
|
+
if (!env) return null;
|
|
16142
|
+
const body = await this.decryptJsonString(env);
|
|
16143
|
+
if (body === null) return null;
|
|
16144
|
+
try {
|
|
16145
|
+
const wrapped = JSON.parse(body);
|
|
16146
|
+
return { json: wrapped.idx, fingerprint: wrapped.fp };
|
|
16147
|
+
} catch {
|
|
16148
|
+
return null;
|
|
16149
|
+
}
|
|
16150
|
+
},
|
|
16151
|
+
save: async (json, fp) => {
|
|
16152
|
+
const body = JSON.stringify({ fp, idx: json });
|
|
16153
|
+
const env = await this.encryptJsonString(body, fp.count);
|
|
16154
|
+
await this.adapter.put(this.vault, FT, this.name, env);
|
|
16155
|
+
},
|
|
16156
|
+
remove: async () => {
|
|
16157
|
+
await this.adapter.delete(this.vault, FT, this.name);
|
|
16158
|
+
},
|
|
16159
|
+
currentFingerprint: () => {
|
|
16160
|
+
let maxVersion = 0;
|
|
16161
|
+
for (const e of this.cache.values()) if (e.version > maxVersion) maxVersion = e.version;
|
|
16162
|
+
return { count: this.cache.size, maxVersion };
|
|
16163
|
+
}
|
|
16164
|
+
};
|
|
16165
|
+
}
|
|
16166
|
+
/** #308 L1 — pre-build the lexical index (e.g. on open) so the first retrieve() pays no build scan. */
|
|
16167
|
+
async warmIndex() {
|
|
16168
|
+
if (!this.searchIndexStore) return;
|
|
16169
|
+
if (this.lazy) {
|
|
16170
|
+
throw new Error(
|
|
16171
|
+
`Collection "${this.name}": warmIndex() requires eager mode (prefetch: true).`
|
|
16172
|
+
);
|
|
16173
|
+
}
|
|
16174
|
+
await this.ensureHydrated();
|
|
16175
|
+
const built = this.searchIndexStore.built;
|
|
16176
|
+
const labelMaps = built ? /* @__PURE__ */ new Map() : await this.resolveDictLabelMaps();
|
|
16177
|
+
const blobFilenames = built ? /* @__PURE__ */ new Map() : await this.resolveBlobFilenames();
|
|
16178
|
+
await this.searchIndexStore.ensureBuilt(() => this.buildRetrievalDocs(labelMaps, blobFilenames));
|
|
16179
|
+
}
|
|
16180
|
+
/** #308 — retrieval. mode: 'lexical' (default) | 'semantic' (L2) | 'hybrid' (L3). */
|
|
16181
|
+
async retrieve(query, opts = {}) {
|
|
16182
|
+
const hits = opts.mode === "semantic" ? await this.retrieveSemantic(query, opts) : opts.mode === "hybrid" ? await this.retrieveHybrid(query, opts) : await this.retrieveLexical(query, opts);
|
|
16183
|
+
return opts.within ? this.applyWithin(hits, opts.within) : hits;
|
|
16184
|
+
}
|
|
16185
|
+
/** #308 L3 — keep only hits whose id matches the structured query, re-rank 1-based. */
|
|
16186
|
+
applyWithin(hits, within) {
|
|
16187
|
+
const ids = new Set(within._idArray());
|
|
16188
|
+
return hits.filter((h) => ids.has(h.id)).map((h, i) => ({ ...h, rank: i + 1 }));
|
|
16189
|
+
}
|
|
16190
|
+
/** #308 L1 — client-side lexical retrieval; ranked { id, score, field, snippet, locale? }. */
|
|
16191
|
+
async retrieveLexical(query, opts) {
|
|
16192
|
+
if (!this.searchIndexStore) {
|
|
16193
|
+
throw new Error(`Collection "${this.name}": retrieve() requires a textIndexes config.`);
|
|
16194
|
+
}
|
|
16195
|
+
if (this.lazy) {
|
|
16196
|
+
throw new Error(
|
|
16197
|
+
`Collection "${this.name}": retrieve() requires eager mode (prefetch: true).`
|
|
16198
|
+
);
|
|
16199
|
+
}
|
|
16200
|
+
await this.ensureHydrated();
|
|
16201
|
+
const built = this.searchIndexStore.built;
|
|
16202
|
+
const labelMaps = built ? /* @__PURE__ */ new Map() : await this.resolveDictLabelMaps();
|
|
16203
|
+
const blobFilenames = built ? /* @__PURE__ */ new Map() : await this.resolveBlobFilenames();
|
|
16204
|
+
const index = await this.searchIndexStore.ensureBuilt(() => this.buildRetrievalDocs(labelMaps, blobFilenames));
|
|
16205
|
+
const hits = index.query(query, {
|
|
16206
|
+
...opts.limit !== void 0 ? { limit: opts.limit } : {},
|
|
16207
|
+
...opts.match ? { match: opts.match } : {},
|
|
16208
|
+
...opts.prefix ? { prefix: opts.prefix } : {},
|
|
16209
|
+
...opts.fields ? { fields: opts.fields } : {}
|
|
16210
|
+
});
|
|
16211
|
+
const window2 = opts.snippetWindow ?? 80;
|
|
16212
|
+
return hits.map((h, i) => {
|
|
16213
|
+
const base = {
|
|
16214
|
+
id: h.id,
|
|
16215
|
+
score: h.score,
|
|
16216
|
+
rank: i + 1,
|
|
16217
|
+
field: h.field,
|
|
16218
|
+
snippet: extractSnippet(h.text, h.offset, window2),
|
|
16219
|
+
...h.locale !== void 0 ? { locale: h.locale } : {},
|
|
16220
|
+
...opts.includeRecord ? (() => {
|
|
16221
|
+
const e = this.cache.get(h.id);
|
|
16222
|
+
return e ? { record: stripI18nFilled(e.record) } : {};
|
|
16223
|
+
})() : {}
|
|
16224
|
+
};
|
|
16225
|
+
return base;
|
|
16226
|
+
});
|
|
16227
|
+
}
|
|
16228
|
+
/** #308 L3 — hybrid: fuse lexical (L1) + semantic (L2) by RRF. Requires embeddings. */
|
|
16229
|
+
async retrieveHybrid(query, opts) {
|
|
16230
|
+
if (!this.embeddings) {
|
|
16231
|
+
throw new Error(`Collection "${this.name}": retrieve({mode:'hybrid'}) requires an embeddings config.`);
|
|
16232
|
+
}
|
|
16233
|
+
const [lex, sem] = await Promise.all([
|
|
16234
|
+
this.retrieveLexical(query, opts),
|
|
16235
|
+
this.retrieveSemantic(query, opts)
|
|
16236
|
+
]);
|
|
16237
|
+
return fuseRetrieval([lex, sem], opts.limit !== void 0 ? { limit: opts.limit } : {});
|
|
16238
|
+
}
|
|
16239
|
+
/** #308 L2 — semantic branch of retrieve(): encode query → similarTo(). */
|
|
16240
|
+
async retrieveSemantic(query, opts) {
|
|
16241
|
+
if (!this.embeddings) throw new Error(`Collection "${this.name}": retrieve({mode:'semantic'}) requires an embeddings config.`);
|
|
16242
|
+
if (this.lazy) throw new Error(`Collection "${this.name}": retrieve() requires eager mode (prefetch: true).`);
|
|
16243
|
+
const qVec = await this.embeddings.encode(query);
|
|
16244
|
+
return this.similarTo(qVec, {
|
|
16245
|
+
...opts.limit !== void 0 ? { k: opts.limit } : {},
|
|
16246
|
+
...opts.minScore !== void 0 ? { minScore: opts.minScore } : {},
|
|
16247
|
+
...opts.includeRecord ? { includeRecord: true } : {}
|
|
16248
|
+
});
|
|
16249
|
+
}
|
|
16250
|
+
/** #308 L2 — raw-vector kNN over the encrypted vector set (decrypted in the trusted tier).
|
|
16251
|
+
* Snippet is '' for vector hits in v1 (semantic match isn't span-located). */
|
|
16252
|
+
async similarTo(vector, opts = {}) {
|
|
16253
|
+
if (!this.embeddings || !this.vectorSet) throw new Error(`Collection "${this.name}": similarTo() requires an embeddings config.`);
|
|
16254
|
+
if (this.lazy) throw new Error(`Collection "${this.name}": similarTo() requires eager mode (prefetch: true).`);
|
|
16255
|
+
await this.ensureHydrated();
|
|
16256
|
+
await this.vectorSet.ensureLoaded(this.buildVectorLoad());
|
|
16257
|
+
const hits = this.vectorSet.cosineTopK(vector, opts.k ?? 10, {
|
|
16258
|
+
...opts.minScore !== void 0 ? { minScore: opts.minScore } : {},
|
|
16259
|
+
expectModel: this.embeddings.model
|
|
16260
|
+
});
|
|
16261
|
+
return hits.map((h, i) => {
|
|
16262
|
+
const base = { id: h.id, score: h.score, rank: i + 1, field: "(vector)", snippet: "" };
|
|
16263
|
+
if (opts.includeRecord) {
|
|
16264
|
+
const e = this.cache.get(h.id);
|
|
16265
|
+
if (e) base.record = stripI18nFilled(e.record);
|
|
16266
|
+
}
|
|
16267
|
+
return base;
|
|
16268
|
+
});
|
|
16269
|
+
}
|
|
15454
16270
|
// ─── Bulk operations ─────────────────────────────────────
|
|
15455
16271
|
/**
|
|
15456
16272
|
* Put many records in one call. Each item is processed sequentially
|
|
@@ -15620,6 +16436,7 @@ var init_collection = __esm({
|
|
|
15620
16436
|
// back to a linear scan otherwise.
|
|
15621
16437
|
getIndexes: () => this.getIndexes(),
|
|
15622
16438
|
lookupById: (id) => this.cache.get(id)?.record,
|
|
16439
|
+
snapshotEntries: () => [...this.cache.entries()].map(([id, e]) => ({ id, record: e.record })),
|
|
15623
16440
|
...this.moneyFields ? { moneyFields: this.moneyFields } : {}
|
|
15624
16441
|
};
|
|
15625
16442
|
const resolver = this.joinResolver;
|
|
@@ -16050,6 +16867,7 @@ var init_collection = __esm({
|
|
|
16050
16867
|
async _applyRemoteChange(id, action) {
|
|
16051
16868
|
await this._invalidateCacheEntry(id);
|
|
16052
16869
|
this.emitter.emit("change", { vault: this.vault, collection: this.name, id, action });
|
|
16870
|
+
this.searchIndexStore?.markDirty();
|
|
16053
16871
|
}
|
|
16054
16872
|
/** @internal — the current in-memory record without a store read (for conflict capture). */
|
|
16055
16873
|
_peekCached(id) {
|
|
@@ -16548,6 +17366,19 @@ var init_collection = __esm({
|
|
|
16548
17366
|
}
|
|
16549
17367
|
return { purged, residue };
|
|
16550
17368
|
}
|
|
17369
|
+
/** #308 L2 — drop a record's encrypted _vec sidecar on erasure (a vector is text-invertible).
|
|
17370
|
+
* Called by vault.ts forget() inside a resilient try/catch; residue is reported in ForgetResult. */
|
|
17371
|
+
async _purgeVector(id) {
|
|
17372
|
+
await this.adapter.delete(this.vault, "_vec", id);
|
|
17373
|
+
this.vectorSet?.markDirty();
|
|
17374
|
+
}
|
|
17375
|
+
/** #308 L1.5 — drop the persisted lexical-index blob (forget/erasure): an opaque
|
|
17376
|
+
* all-records index must not survive crypto-shred. Idempotent; no-op without persist. */
|
|
17377
|
+
async _purgeSearchIndex() {
|
|
17378
|
+
const store = this.searchIndexStore;
|
|
17379
|
+
if (store && "removePersisted" in store) await store.removePersisted();
|
|
17380
|
+
else store?.markDirty();
|
|
17381
|
+
}
|
|
16551
17382
|
/**
|
|
16552
17383
|
* Bulk-load the persisted-index mirror from `_idx/<field>/*` side-cars
|
|
16553
17384
|
* on first lazy-mode query. Idempotent — subsequent calls short-circuit
|
|
@@ -19833,6 +20664,10 @@ var init_vault = __esm({
|
|
|
19833
20664
|
collOpts.onCrossTierAccess = (event) => this.emitCrossTier(event);
|
|
19834
20665
|
if (this.syncAdapter !== void 0) collOpts.syncAdapter = this.syncAdapter;
|
|
19835
20666
|
if (options?.i18nFields !== void 0) collOpts.i18nFields = options.i18nFields;
|
|
20667
|
+
if (options?.embeddings !== void 0) collOpts.embeddings = options.embeddings;
|
|
20668
|
+
if (options?.textIndexes !== void 0) collOpts.textIndexes = options.textIndexes;
|
|
20669
|
+
if (options?.warmIndexOnOpen !== void 0) collOpts.warmIndexOnOpen = options.warmIndexOnOpen;
|
|
20670
|
+
if (options?.textIndexPersist !== void 0) collOpts.textIndexPersist = options.textIndexPersist;
|
|
19836
20671
|
if (options?.moneyFields !== void 0) collOpts.moneyFields = options.moneyFields;
|
|
19837
20672
|
if (options?.computed !== void 0) collOpts.computed = options.computed;
|
|
19838
20673
|
if (options?.dictKeyFields !== void 0) {
|
|
@@ -19845,6 +20680,7 @@ var init_vault = __esm({
|
|
|
19845
20680
|
const handle = this.dictionary(dictName);
|
|
19846
20681
|
return handle.resolveLabel(key, locale, fallback);
|
|
19847
20682
|
};
|
|
20683
|
+
collOpts.getDictionary = async (name) => this.dictionary(name);
|
|
19848
20684
|
collOpts.dictKeyFields = options.dictKeyFields;
|
|
19849
20685
|
}
|
|
19850
20686
|
if (options?.i18nFields !== void 0 || options?.dictKeyFields !== void 0) {
|
|
@@ -19858,6 +20694,10 @@ var init_vault = __esm({
|
|
|
19858
20694
|
}
|
|
19859
20695
|
coll = new Collection(collOpts);
|
|
19860
20696
|
this.collectionCache.set(collectionName, coll);
|
|
20697
|
+
if (options?.warmIndexOnOpen === true && options.prefetch !== false) {
|
|
20698
|
+
void coll.warmIndex().catch(() => {
|
|
20699
|
+
});
|
|
20700
|
+
}
|
|
19861
20701
|
if (options?.persistJsonSchema === true && options.schema !== void 0 && (options.schemaUpdate?.length ?? 0) === 0) {
|
|
19862
20702
|
const validator = options.schema;
|
|
19863
20703
|
const work = (async () => {
|
|
@@ -19967,6 +20807,16 @@ var init_vault = __esm({
|
|
|
19967
20807
|
this.#fenceWatcher = void 0;
|
|
19968
20808
|
this.#fenceCoordinationStarted = false;
|
|
19969
20809
|
}
|
|
20810
|
+
/** @internal #308 L1.5 — best-effort flush of all open collections' persisted
|
|
20811
|
+
* lexical indexes on close(). Called fire-and-forget from noydb.close().
|
|
20812
|
+
* Correctness is backstopped by the fingerprint: a missed flush → rebuild on
|
|
20813
|
+
* next load. Only collections with textIndexPersist have a flush(); others no-op. */
|
|
20814
|
+
async _flushSearchIndexes() {
|
|
20815
|
+
for (const coll of this.collectionCache.values()) {
|
|
20816
|
+
await coll.flushIndex().catch(() => {
|
|
20817
|
+
});
|
|
20818
|
+
}
|
|
20819
|
+
}
|
|
19970
20820
|
/** @internal Drive one heartbeat + watch cycle deterministically (tests). */
|
|
19971
20821
|
async _fenceTick() {
|
|
19972
20822
|
this._ensureFenceCoordination();
|
|
@@ -21041,6 +21891,11 @@ var init_vault = __esm({
|
|
|
21041
21891
|
const idxPurge = await coll._purgePersistedIndexes(ref2.id);
|
|
21042
21892
|
indexPostingsPurged += idxPurge.purged;
|
|
21043
21893
|
for (const field of idxPurge.residue) indexResidue.push(`${ref2.collection}:${ref2.id}:${field}`);
|
|
21894
|
+
try {
|
|
21895
|
+
await coll._purgeVector(ref2.id);
|
|
21896
|
+
} catch {
|
|
21897
|
+
indexResidue.push(`${ref2.collection}:${ref2.id}:_vec`);
|
|
21898
|
+
}
|
|
21044
21899
|
if (blobsEnabled) {
|
|
21045
21900
|
const r = await this.collection(ref2.collection).blob(ref2.id).shredAllForRecord();
|
|
21046
21901
|
blobsShredded += r.shredded.length;
|
|
@@ -21055,6 +21910,13 @@ var init_vault = __esm({
|
|
|
21055
21910
|
}
|
|
21056
21911
|
await this._removeSubjectRef(subjectId, ref2);
|
|
21057
21912
|
}
|
|
21913
|
+
for (const collName of collections) {
|
|
21914
|
+
try {
|
|
21915
|
+
await this.collection(collName)._purgeSearchIndex();
|
|
21916
|
+
} catch {
|
|
21917
|
+
indexResidue.push(`${collName}:_ftindex`);
|
|
21918
|
+
}
|
|
21919
|
+
}
|
|
21058
21920
|
const subjectHash = await sha256Hex3(subjectId);
|
|
21059
21921
|
const ledger = this.getLedgerOrNull();
|
|
21060
21922
|
if (!ledger) {
|
|
@@ -24930,6 +25792,7 @@ var init_noydb = __esm({
|
|
|
24930
25792
|
}
|
|
24931
25793
|
this.syncEngines.clear();
|
|
24932
25794
|
for (const v of this.vaultCache.values()) v._stopFenceCoordination();
|
|
25795
|
+
for (const v of this.vaultCache.values()) void v._flushSearchIndexes();
|
|
24933
25796
|
this.disableTabCoordination();
|
|
24934
25797
|
this.keyringCache.clear();
|
|
24935
25798
|
this.vaultCache.clear();
|
|
@@ -26081,6 +26944,8 @@ __export(src_exports, {
|
|
|
26081
26944
|
ELEVATION_AUDIT_COLLECTION: () => ELEVATION_AUDIT_COLLECTION,
|
|
26082
26945
|
ElevatedHandle: () => ElevatedHandle,
|
|
26083
26946
|
ElevationExpiredError: () => ElevationExpiredError,
|
|
26947
|
+
EmbeddingDimMismatchError: () => EmbeddingDimMismatchError,
|
|
26948
|
+
EmbeddingModelMismatchError: () => EmbeddingModelMismatchError,
|
|
26084
26949
|
ExportCapabilityError: () => ExportCapabilityError,
|
|
26085
26950
|
FieldFrozenError: () => FieldFrozenError,
|
|
26086
26951
|
FilenameSanitizationError: () => FilenameSanitizationError,
|
|
@@ -26290,6 +27155,7 @@ __export(src_exports, {
|
|
|
26290
27155
|
exportAccessibleData: () => exportAccessibleData,
|
|
26291
27156
|
findAuthenticator: () => findAuthenticator,
|
|
26292
27157
|
formatDiff: () => formatDiff,
|
|
27158
|
+
fuseRetrieval: () => fuseRetrieval,
|
|
26293
27159
|
generateULID: () => generateULID,
|
|
26294
27160
|
getCredential: () => getCredential,
|
|
26295
27161
|
groupAndReduce: () => groupAndReduce,
|
|
@@ -27138,7 +28004,7 @@ var BlobSet = class {
|
|
|
27138
28004
|
...backlink.token ? { backlink: backlink.token } : {},
|
|
27139
28005
|
...prevMeta ? { meta: prevMeta } : {}
|
|
27140
28006
|
},
|
|
27141
|
-
filename: slotName,
|
|
28007
|
+
filename: opts?.filename ?? slotName,
|
|
27142
28008
|
size: data.byteLength,
|
|
27143
28009
|
mimeType: contentType,
|
|
27144
28010
|
uploadedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -27210,7 +28076,7 @@ var BlobSet = class {
|
|
|
27210
28076
|
const oldETag = slots[slotName]?.eTag;
|
|
27211
28077
|
slots[slotName] = {
|
|
27212
28078
|
eTag,
|
|
27213
|
-
filename: slotName,
|
|
28079
|
+
filename: opts?.filename ?? slotName,
|
|
27214
28080
|
size: data.byteLength,
|
|
27215
28081
|
...mimeType !== void 0 ? { mimeType } : {},
|
|
27216
28082
|
uploadedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -30648,6 +31514,8 @@ init_crypto();
|
|
|
30648
31514
|
init_crypto();
|
|
30649
31515
|
init_errors();
|
|
30650
31516
|
init_errors();
|
|
31517
|
+
init_fuse();
|
|
31518
|
+
init_errors();
|
|
30651
31519
|
init_errors();
|
|
30652
31520
|
init_tiers();
|
|
30653
31521
|
init_delegation();
|
|
@@ -30927,6 +31795,8 @@ init_search();
|
|
|
30927
31795
|
ELEVATION_AUDIT_COLLECTION,
|
|
30928
31796
|
ElevatedHandle,
|
|
30929
31797
|
ElevationExpiredError,
|
|
31798
|
+
EmbeddingDimMismatchError,
|
|
31799
|
+
EmbeddingModelMismatchError,
|
|
30930
31800
|
ExportCapabilityError,
|
|
30931
31801
|
FieldFrozenError,
|
|
30932
31802
|
FilenameSanitizationError,
|
|
@@ -31136,6 +32006,7 @@ init_search();
|
|
|
31136
32006
|
exportAccessibleData,
|
|
31137
32007
|
findAuthenticator,
|
|
31138
32008
|
formatDiff,
|
|
32009
|
+
fuseRetrieval,
|
|
31139
32010
|
generateULID,
|
|
31140
32011
|
getCredential,
|
|
31141
32012
|
groupAndReduce,
|