@noy-db/hub 0.2.0-pre.18 → 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 +520 -46
- 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-6Q5XRLKG.js → chunk-3FSMVWBN.js} +4 -4
- package/dist/{chunk-647TFNYL.js → chunk-3Q2AOPLT.js} +76 -28
- package/dist/chunk-3Q2AOPLT.js.map +1 -0
- package/dist/{chunk-2U226RDC.js → chunk-4ULLGYPA.js} +3 -3
- package/dist/{chunk-6FHCU3QO.js → chunk-5IGWRMEC.js} +5 -5
- package/dist/{chunk-Y5XVB75E.js → chunk-6KESZO5D.js} +35 -7
- package/dist/chunk-6KESZO5D.js.map +1 -0
- package/dist/{chunk-KQ523X3A.js → chunk-6OSOE6BY.js} +2 -2
- package/dist/{chunk-HWK75CYX.js → chunk-7C6VFNIY.js} +2 -2
- package/dist/{chunk-33DAO2XG.js → chunk-7HD67R6U.js} +2 -2
- package/dist/{chunk-RQFG2YSV.js → chunk-B6E5IRPJ.js} +3 -3
- package/dist/{chunk-YWYW2YNO.js → chunk-CYNTFU2D.js} +2 -2
- package/dist/{chunk-HMFC6M2G.js → chunk-DJF3FXW5.js} +17 -1
- package/dist/{chunk-HMFC6M2G.js.map → chunk-DJF3FXW5.js.map} +1 -1
- package/dist/{chunk-KTZ2MHQK.js → chunk-DY3EOJEN.js} +2 -2
- package/dist/{chunk-PGVEL5IZ.js → chunk-E66DSTJP.js} +3 -3
- package/dist/{chunk-6YEC7LLO.js → chunk-FBLAWK6A.js} +2 -2
- package/dist/{chunk-LQ3GD5LL.js → chunk-FPHRTW2Z.js} +5 -5
- package/dist/{chunk-ZJ67TB4S.js → chunk-G4PYA575.js} +2 -2
- package/dist/{chunk-45643PAU.js → chunk-GKQAU52M.js} +4 -4
- package/dist/{chunk-5KKNBDCT.js → chunk-GYAWXHFO.js} +2 -2
- package/dist/{chunk-KOURQXIU.js → chunk-H42KZXNV.js} +5 -210
- package/dist/chunk-H42KZXNV.js.map +1 -0
- package/dist/{chunk-6XEGHIBA.js → chunk-IBVTH4JR.js} +4 -4
- package/dist/{chunk-AB7JF2KF.js → chunk-IVP5IVON.js} +2 -2
- package/dist/{chunk-T4T5I5L6.js → chunk-KEDJDWWQ.js} +3 -3
- package/dist/{chunk-C2OYWD5S.js → chunk-KNKNOJFS.js} +3 -3
- package/dist/chunk-KNKNOJFS.js.map +1 -0
- package/dist/{chunk-F2IJ2HGD.js → chunk-KYGGXXT6.js} +228 -69
- package/dist/chunk-KYGGXXT6.js.map +1 -0
- package/dist/{chunk-RZWQNMMP.js → chunk-LSIIPKYT.js} +2 -2
- package/dist/{chunk-FQRAYDS4.js → chunk-M3FPNTO2.js} +4 -4
- package/dist/{chunk-DR5I7Q6N.js → chunk-MI36HL5G.js} +4 -4
- package/dist/{chunk-Z3I2WNGF.js → chunk-NN6IISZO.js} +2 -2
- package/dist/{chunk-32XVU2LT.js → chunk-OBMYMKGO.js} +29 -6
- package/dist/{chunk-32XVU2LT.js.map → chunk-OBMYMKGO.js.map} +1 -1
- package/dist/{chunk-QJKZ5WUP.js → chunk-OKOKPYWH.js} +2 -2
- package/dist/{chunk-CMISAJAE.js → chunk-OY7RX2VL.js} +9 -15
- package/dist/chunk-OY7RX2VL.js.map +1 -0
- package/dist/{chunk-Z3BE5BRK.js → chunk-PTGQPWMV.js} +2 -2
- package/dist/{chunk-QPJ7Z4L3.js → chunk-PWFTQHYX.js} +2 -2
- package/dist/{chunk-K3NYRK7U.js → chunk-Q5MCHUXZ.js} +2 -2
- package/dist/{chunk-IQ4GMEYZ.js → chunk-S22UOMHM.js} +6 -6
- package/dist/{chunk-WZCG3EZ6.js → chunk-S3XA7G35.js} +2 -2
- package/dist/{chunk-LGPSCKWZ.js → chunk-SHIUFIPW.js} +1 -1
- package/dist/chunk-SHIUFIPW.js.map +1 -0
- package/dist/{chunk-BUBJYIZ7.js → chunk-U7JNBSS3.js} +3 -3
- package/dist/{chunk-TFAN3NFD.js → chunk-V3VIRTTE.js} +3 -3
- package/dist/{chunk-VVDSDOVV.js → chunk-V5FZWQNN.js} +4 -4
- package/dist/chunk-VEIVAYJ7.js +361 -0
- package/dist/chunk-VEIVAYJ7.js.map +1 -0
- package/dist/{chunk-P57D4KBG.js → chunk-VNUE6FHP.js} +3 -3
- package/dist/{chunk-TPOHMOGX.js → chunk-WFK2EVYU.js} +10 -2
- package/dist/chunk-WFK2EVYU.js.map +1 -0
- package/dist/{chunk-TTS3RWL5.js → chunk-X7FJMKT3.js} +2 -2
- package/dist/{chunk-HZOEBM67.js → chunk-XPH3FWME.js} +7 -2
- package/dist/{chunk-HZOEBM67.js.map → chunk-XPH3FWME.js.map} +1 -1
- package/dist/{chunk-DKMPR76W.js → chunk-Y5J63SMF.js} +5 -5
- package/dist/{chunk-HOO5I3VG.js → chunk-YLRRU72W.js} +2 -2
- package/dist/{chunk-MGB67HKX.js → chunk-YX333DPS.js} +4 -4
- package/dist/{chunk-4UI5T3K7.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-FNK3XPCS.js → crypto-B46VNH6X.js} +3 -3
- package/dist/{delegation-FMXNUWE6.js → delegation-5HON72PV.js} +5 -5
- 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 +4 -4
- package/dist/{dev-unlock-3_2b_vo6.d.cts → dev-unlock-BR1rMOS-.d.cts} +1 -1
- package/dist/{dev-unlock-BMvwPr_E.d.ts → dev-unlock-whL49sxV.d.ts} +1 -1
- package/dist/{errors-DUTlAt3Y.d.ts → errors-DL-zTrrF.d.cts} +14 -1
- package/dist/{errors-DUTlAt3Y.d.cts → errors-DL-zTrrF.d.ts} +14 -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-JGHXAJO5.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.map +1 -1
- package/dist/guards/index.d.cts +7 -7
- package/dist/guards/index.d.ts +7 -7
- package/dist/guards/index.js +3 -3
- package/dist/{hash-BnWnL9bQ.d.cts → hash-BEUBmmI4.d.cts} +1 -1
- package/dist/{hash-BThBJFO1.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-C6lgoUhK.d.cts → index-BM7O48Ur.d.cts} +47 -8
- package/dist/{index-C-SSRIxP.d.ts → index-BMmajblo.d.cts} +14 -0
- package/dist/{index-C-SSRIxP.d.cts → index-BMmajblo.d.ts} +14 -0
- package/dist/{index-DP1JTWHZ.d.ts → index-BelbyUwz.d.ts} +47 -8
- package/dist/index.cjs +799 -465
- 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 +56 -52
- 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-GXC2YA3A.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-HXOFHY4N.js → public-envelope-AGU6SS4Z.js} +4 -4
- package/dist/query/index.cjs +296 -27
- 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/registry-ERNAMRDE.js +8 -0
- package/dist/registry-EXTHSXQW.js +8 -0
- package/dist/{registry-WVXO6NH5.js → registry-RDPTFXQ7.js} +3 -3
- package/dist/{revoke-7LCWE2AH.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-HAVDLGOK.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-PGTEGJDI.js → stale-NTEV5SLX.js} +2 -2
- package/dist/{state-vault-QKQKN3H3.js → state-vault-TUTFRTOA.js} +4 -4
- 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-Diwh5lzS.d.ts → strategy-BDxQnnTX.d.ts} +315 -4
- package/dist/{strategy-nuyN8K5N.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--t3exQHF.d.cts → transition-guard-B1N82hMf.d.cts} +1 -1
- package/dist/{transition-guard-BlI9Oy5K.d.ts → transition-guard-C__YeF3_.d.ts} +1 -1
- 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-Diqc2caK.d.ts → types-CraiZOyO.d.ts} +134 -292
- package/dist/{types-BpLPqyaO.d.cts → types-D-gr5t0G.d.cts} +134 -292
- package/dist/{ulid-DNiRB4Mx.d.cts → ulid-DQnSAP5W.d.cts} +1 -1
- package/dist/{ulid-B1zNV8r9.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-DPZVFRI5.js → vault-group-27EV7KB4.js} +29 -8
- package/dist/vault-group-27EV7KB4.js.map +1 -0
- package/dist/{with-materialized-view-BdH_A_r6.d.cts → with-materialized-view-BboqxyV3.d.cts} +1 -1
- package/dist/{with-materialized-view-CzAgp_HJ.d.ts → with-materialized-view-CguCeVcT.d.ts} +1 -1
- package/dist/{with-overlayed-view-BJbqQnsR.d.ts → with-overlayed-view-DO08u_tx.d.ts} +1 -1
- package/dist/{with-overlayed-view-C40rDPlu.d.cts → with-overlayed-view-mmsg5Of3.d.cts} +1 -1
- package/dist/{with-rollup-DrlGkxiE.d.ts → with-rollup-_TyBzz3T.d.ts} +1 -1
- package/dist/{with-rollup-Bopu5UDZ.d.cts → with-rollup-aaxOZcIb.d.cts} +1 -1
- package/package.json +3 -3
- package/dist/chunk-647TFNYL.js.map +0 -1
- package/dist/chunk-C2OYWD5S.js.map +0 -1
- package/dist/chunk-CMISAJAE.js.map +0 -1
- package/dist/chunk-F2IJ2HGD.js.map +0 -1
- package/dist/chunk-KOURQXIU.js.map +0 -1
- package/dist/chunk-LGPSCKWZ.js.map +0 -1
- package/dist/chunk-M3H7VSRV.js +0 -139
- package/dist/chunk-M3H7VSRV.js.map +0 -1
- package/dist/chunk-TPOHMOGX.js.map +0 -1
- package/dist/chunk-Y5XVB75E.js.map +0 -1
- package/dist/executor-IZ2NVXCY.js +0 -11
- package/dist/executor-THSEYEJG.js +0 -8
- package/dist/executor-WLFDUTOM.js +0 -8
- package/dist/issue-R2MWQO6K.js +0 -12
- package/dist/noydb-RJL6FQ4B.js +0 -37
- package/dist/registry-3T2RZC5A.js +0 -8
- package/dist/registry-DMS7OKBM.js +0 -8
- package/dist/vault-group-DPZVFRI5.js.map +0 -1
- /package/dist/{chunk-6Q5XRLKG.js.map → chunk-3FSMVWBN.js.map} +0 -0
- /package/dist/{chunk-2U226RDC.js.map → chunk-4ULLGYPA.js.map} +0 -0
- /package/dist/{chunk-6FHCU3QO.js.map → chunk-5IGWRMEC.js.map} +0 -0
- /package/dist/{chunk-KQ523X3A.js.map → chunk-6OSOE6BY.js.map} +0 -0
- /package/dist/{chunk-HWK75CYX.js.map → chunk-7C6VFNIY.js.map} +0 -0
- /package/dist/{chunk-33DAO2XG.js.map → chunk-7HD67R6U.js.map} +0 -0
- /package/dist/{chunk-RQFG2YSV.js.map → chunk-B6E5IRPJ.js.map} +0 -0
- /package/dist/{chunk-YWYW2YNO.js.map → chunk-CYNTFU2D.js.map} +0 -0
- /package/dist/{chunk-KTZ2MHQK.js.map → chunk-DY3EOJEN.js.map} +0 -0
- /package/dist/{chunk-PGVEL5IZ.js.map → chunk-E66DSTJP.js.map} +0 -0
- /package/dist/{chunk-6YEC7LLO.js.map → chunk-FBLAWK6A.js.map} +0 -0
- /package/dist/{chunk-LQ3GD5LL.js.map → chunk-FPHRTW2Z.js.map} +0 -0
- /package/dist/{chunk-ZJ67TB4S.js.map → chunk-G4PYA575.js.map} +0 -0
- /package/dist/{chunk-45643PAU.js.map → chunk-GKQAU52M.js.map} +0 -0
- /package/dist/{chunk-5KKNBDCT.js.map → chunk-GYAWXHFO.js.map} +0 -0
- /package/dist/{chunk-6XEGHIBA.js.map → chunk-IBVTH4JR.js.map} +0 -0
- /package/dist/{chunk-AB7JF2KF.js.map → chunk-IVP5IVON.js.map} +0 -0
- /package/dist/{chunk-T4T5I5L6.js.map → chunk-KEDJDWWQ.js.map} +0 -0
- /package/dist/{chunk-RZWQNMMP.js.map → chunk-LSIIPKYT.js.map} +0 -0
- /package/dist/{chunk-FQRAYDS4.js.map → chunk-M3FPNTO2.js.map} +0 -0
- /package/dist/{chunk-DR5I7Q6N.js.map → chunk-MI36HL5G.js.map} +0 -0
- /package/dist/{chunk-Z3I2WNGF.js.map → chunk-NN6IISZO.js.map} +0 -0
- /package/dist/{chunk-QJKZ5WUP.js.map → chunk-OKOKPYWH.js.map} +0 -0
- /package/dist/{chunk-Z3BE5BRK.js.map → chunk-PTGQPWMV.js.map} +0 -0
- /package/dist/{chunk-QPJ7Z4L3.js.map → chunk-PWFTQHYX.js.map} +0 -0
- /package/dist/{chunk-K3NYRK7U.js.map → chunk-Q5MCHUXZ.js.map} +0 -0
- /package/dist/{chunk-IQ4GMEYZ.js.map → chunk-S22UOMHM.js.map} +0 -0
- /package/dist/{chunk-WZCG3EZ6.js.map → chunk-S3XA7G35.js.map} +0 -0
- /package/dist/{chunk-BUBJYIZ7.js.map → chunk-U7JNBSS3.js.map} +0 -0
- /package/dist/{chunk-TFAN3NFD.js.map → chunk-V3VIRTTE.js.map} +0 -0
- /package/dist/{chunk-VVDSDOVV.js.map → chunk-V5FZWQNN.js.map} +0 -0
- /package/dist/{chunk-P57D4KBG.js.map → chunk-VNUE6FHP.js.map} +0 -0
- /package/dist/{chunk-TTS3RWL5.js.map → chunk-X7FJMKT3.js.map} +0 -0
- /package/dist/{chunk-DKMPR76W.js.map → chunk-Y5J63SMF.js.map} +0 -0
- /package/dist/{chunk-HOO5I3VG.js.map → chunk-YLRRU72W.js.map} +0 -0
- /package/dist/{chunk-MGB67HKX.js.map → chunk-YX333DPS.js.map} +0 -0
- /package/dist/{chunk-4UI5T3K7.js.map → chunk-YZE6C3TQ.js.map} +0 -0
- /package/dist/{crypto-FNK3XPCS.js.map → crypto-B46VNH6X.js.map} +0 -0
- /package/dist/{delegation-FMXNUWE6.js.map → delegation-5HON72PV.js.map} +0 -0
- /package/dist/{executor-IZ2NVXCY.js.map → executor-44R5CUS2.js.map} +0 -0
- /package/dist/{executor-THSEYEJG.js.map → executor-AOACUK7Z.js.map} +0 -0
- /package/dist/{executor-WLFDUTOM.js.map → executor-OKFLQCDW.js.map} +0 -0
- /package/dist/{fanout-sidecar-JGHXAJO5.js.map → fanout-sidecar-DCQWJQ6S.js.map} +0 -0
- /package/dist/{issue-R2MWQO6K.js.map → issue-EPA2PSWP.js.map} +0 -0
- /package/dist/{ledger-GXC2YA3A.js.map → ledger-LS6GXCBP.js.map} +0 -0
- /package/dist/{noydb-RJL6FQ4B.js.map → noydb-BVKFP74P.js.map} +0 -0
- /package/dist/{public-envelope-HXOFHY4N.js.map → public-envelope-AGU6SS4Z.js.map} +0 -0
- /package/dist/{registry-3T2RZC5A.js.map → registry-ERNAMRDE.js.map} +0 -0
- /package/dist/{registry-DMS7OKBM.js.map → registry-EXTHSXQW.js.map} +0 -0
- /package/dist/{registry-WVXO6NH5.js.map → registry-RDPTFXQ7.js.map} +0 -0
- /package/dist/{revoke-7LCWE2AH.js.map → revoke-IFLXEZA5.js.map} +0 -0
- /package/dist/{signer-HAVDLGOK.js.map → signer-UNWOUJAK.js.map} +0 -0
- /package/dist/{stale-PGTEGJDI.js.map → stale-NTEV5SLX.js.map} +0 -0
- /package/dist/{state-vault-QKQKN3H3.js.map → state-vault-TUTFRTOA.js.map} +0 -0
package/dist/bundle/index.cjs
CHANGED
|
@@ -31,7 +31,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
31
31
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
32
32
|
|
|
33
33
|
// src/errors.ts
|
|
34
|
-
var NoydbError, DecryptionError, TamperedError, InvalidKeyError, KeyringCorruptError, NoAccessError, ReadOnlyError, PermissionDeniedError, ExportCapabilityError, KeyringExpiredError, ImportCapabilityError, StoreCapabilityError, PrivilegeEscalationError, ReservedVaultNameError, FieldFrozenError, InvariantError, AmendmentForbiddenError, TierNotGrantedError, ElevationExpiredError, AlreadyElevatedError, TierDemoteDeniedError, DelegationTargetMissingError, ConflictError, LedgerContentionError, SequenceContentionError, SequenceOfflineError, NumberingUncertaintyError, BundleVersionConflictError, ValidationError, SchemaValidationError, SchemaUpdateError, SchemaFenceError, MigrationRequiredError, QuiesceTimeoutError, GroupCardinalityError, IndexRequiredError, UniqueConstraintError, UnsupportedIndexOptionError, IndexWriteFailureError, BundleIntegrityError, BundleSealMismatchError, ReservedCollectionNameError, LocaleNotSpecifiedError, StaticDictReadonlyError, UnknownDictCodeError, TranslatorNotConfiguredError, BackupLedgerError, BackupCorruptedError, PartitionExtractionError, TransferSealError, AdoptionStateError, AttestationError, JoinTooLargeError, CrossJoinTooLargeError, CrossJoinSourceUnknownError, DanglingReferenceError, DerivationCycleError, DerivationOutputShapeError, DerivationCapExceededError, MaterializedViewCycleError, MaterializedViewSourceUnknownError, MaterializedViewTooLargeError, OverlayBaseIsVirtualError, OverlayCollectionUnavailableError, OverlayNameCollisionError, OverlayIdMismatchError, UnknownShardError, ShardProvisioningError, CrossShardJoinError, VaultTemplateNotFoundError, ForgetStrategyNotConfiguredError, RecordCekNotFoundError;
|
|
34
|
+
var NoydbError, DecryptionError, TamperedError, InvalidKeyError, KeyringCorruptError, NoAccessError, ReadOnlyError, PermissionDeniedError, ExportCapabilityError, KeyringExpiredError, ImportCapabilityError, StoreCapabilityError, PrivilegeEscalationError, ReservedVaultNameError, FieldFrozenError, InvariantError, AmendmentForbiddenError, TierNotGrantedError, ElevationExpiredError, AlreadyElevatedError, TierDemoteDeniedError, DelegationTargetMissingError, ConflictError, LedgerContentionError, SequenceContentionError, SequenceOfflineError, NumberingUncertaintyError, BundleVersionConflictError, ValidationError, SchemaValidationError, SchemaUpdateError, SchemaFenceError, MigrationRequiredError, QuiesceTimeoutError, GroupCardinalityError, IndexRequiredError, UniqueConstraintError, UnsupportedIndexOptionError, IndexWriteFailureError, BundleIntegrityError, BundleSealMismatchError, ReservedCollectionNameError, LocaleNotSpecifiedError, StaticDictReadonlyError, UnknownDictCodeError, TranslatorNotConfiguredError, BackupLedgerError, BackupCorruptedError, PartitionExtractionError, TransferSealError, AdoptionStateError, AttestationError, JoinTooLargeError, CrossJoinTooLargeError, CrossJoinSourceUnknownError, DanglingReferenceError, DerivationCycleError, DerivationOutputShapeError, DerivationCapExceededError, MaterializedViewCycleError, MaterializedViewSourceUnknownError, MaterializedViewTooLargeError, OverlayBaseIsVirtualError, OverlayCollectionUnavailableError, OverlayNameCollisionError, OverlayIdMismatchError, UnknownShardError, ShardProvisioningError, DataResidencyError, CrossShardJoinError, VaultTemplateNotFoundError, ForgetStrategyNotConfiguredError, RecordCekNotFoundError;
|
|
35
35
|
var init_errors = __esm({
|
|
36
36
|
"src/errors.ts"() {
|
|
37
37
|
"use strict";
|
|
@@ -776,6 +776,21 @@ Resolutions:
|
|
|
776
776
|
this.vaultId = vaultId;
|
|
777
777
|
}
|
|
778
778
|
};
|
|
779
|
+
DataResidencyError = class extends NoydbError {
|
|
780
|
+
vaultId;
|
|
781
|
+
requiredRegion;
|
|
782
|
+
backendRegion;
|
|
783
|
+
constructor(vaultId, requiredRegion, backendRegion) {
|
|
784
|
+
super(
|
|
785
|
+
"DATA_RESIDENCY",
|
|
786
|
+
`Shard "${vaultId}" requires region "${requiredRegion}" but its placement backend declares region ${backendRegion === void 0 ? "(none)" : `"${backendRegion}"`}. Refusing to provision \u2014 route this shard to a region-correct backend via routeStore({ vaultRoutes }) (e.g. a region-encoded partition key) before retrying.`
|
|
787
|
+
);
|
|
788
|
+
this.name = "DataResidencyError";
|
|
789
|
+
this.vaultId = vaultId;
|
|
790
|
+
this.requiredRegion = requiredRegion;
|
|
791
|
+
this.backendRegion = backendRegion;
|
|
792
|
+
}
|
|
793
|
+
};
|
|
779
794
|
CrossShardJoinError = class extends NoydbError {
|
|
780
795
|
constructor(message) {
|
|
781
796
|
super("CROSS_SHARD_JOIN", message);
|
|
@@ -3893,7 +3908,146 @@ var init_policy = __esm({
|
|
|
3893
3908
|
}
|
|
3894
3909
|
});
|
|
3895
3910
|
|
|
3911
|
+
// src/i18n/script.ts
|
|
3912
|
+
function inferScripts(locale) {
|
|
3913
|
+
const parts = locale.split("-");
|
|
3914
|
+
const subtag = parts.find((t) => /^[A-Z][a-z]{3}$/.test(t));
|
|
3915
|
+
if (subtag && SUBTAG_SCRIPTS[subtag]) return SUBTAG_SCRIPTS[subtag];
|
|
3916
|
+
const base = (parts[0] ?? "").toLowerCase();
|
|
3917
|
+
if (LATIN_BASE.has(base)) return ["Latin"];
|
|
3918
|
+
const primary = SCRIPT_TABLE[base];
|
|
3919
|
+
if (primary) return [...primary, "Latin"];
|
|
3920
|
+
return ["Latin"];
|
|
3921
|
+
}
|
|
3922
|
+
var LATIN_BASE, SCRIPT_TABLE, SUBTAG_SCRIPTS, BASELINE;
|
|
3923
|
+
var init_script = __esm({
|
|
3924
|
+
"src/i18n/script.ts"() {
|
|
3925
|
+
"use strict";
|
|
3926
|
+
LATIN_BASE = /* @__PURE__ */ new Set([
|
|
3927
|
+
"en",
|
|
3928
|
+
"fr",
|
|
3929
|
+
"de",
|
|
3930
|
+
"es",
|
|
3931
|
+
"it",
|
|
3932
|
+
"pt",
|
|
3933
|
+
"nl",
|
|
3934
|
+
"sv",
|
|
3935
|
+
"no",
|
|
3936
|
+
"da",
|
|
3937
|
+
"fi",
|
|
3938
|
+
"is",
|
|
3939
|
+
"pl",
|
|
3940
|
+
"cs",
|
|
3941
|
+
"sk",
|
|
3942
|
+
"hu",
|
|
3943
|
+
"ro",
|
|
3944
|
+
"hr",
|
|
3945
|
+
"sl",
|
|
3946
|
+
"et",
|
|
3947
|
+
"lv",
|
|
3948
|
+
"lt",
|
|
3949
|
+
"tr",
|
|
3950
|
+
"vi",
|
|
3951
|
+
"id",
|
|
3952
|
+
"ms",
|
|
3953
|
+
"tl",
|
|
3954
|
+
"sw",
|
|
3955
|
+
"af",
|
|
3956
|
+
"ca",
|
|
3957
|
+
"gl",
|
|
3958
|
+
"eu",
|
|
3959
|
+
"cy",
|
|
3960
|
+
"ga"
|
|
3961
|
+
]);
|
|
3962
|
+
SCRIPT_TABLE = {
|
|
3963
|
+
th: ["Thai"],
|
|
3964
|
+
ko: ["Hangul", "Han"],
|
|
3965
|
+
ja: ["Han", "Hiragana", "Katakana"],
|
|
3966
|
+
zh: ["Han"],
|
|
3967
|
+
ar: ["Arabic"],
|
|
3968
|
+
fa: ["Arabic"],
|
|
3969
|
+
ur: ["Arabic"],
|
|
3970
|
+
ru: ["Cyrillic"],
|
|
3971
|
+
uk: ["Cyrillic"],
|
|
3972
|
+
bg: ["Cyrillic"],
|
|
3973
|
+
sr: ["Cyrillic"],
|
|
3974
|
+
he: ["Hebrew"],
|
|
3975
|
+
el: ["Greek"],
|
|
3976
|
+
hi: ["Devanagari"],
|
|
3977
|
+
ta: ["Tamil"],
|
|
3978
|
+
km: ["Khmer"],
|
|
3979
|
+
lo: ["Lao"],
|
|
3980
|
+
my: ["Myanmar"]
|
|
3981
|
+
};
|
|
3982
|
+
SUBTAG_SCRIPTS = {
|
|
3983
|
+
Latn: ["Latin"],
|
|
3984
|
+
Cyrl: ["Cyrillic", "Latin"],
|
|
3985
|
+
Hans: ["Han", "Latin"],
|
|
3986
|
+
Hant: ["Han", "Latin"],
|
|
3987
|
+
Thai: ["Thai", "Latin"],
|
|
3988
|
+
Arab: ["Arabic", "Latin"]
|
|
3989
|
+
};
|
|
3990
|
+
BASELINE = String.raw`\p{White_Space}\p{Script=Common}\p{Script=Inherited}\p{Mark}`;
|
|
3991
|
+
}
|
|
3992
|
+
});
|
|
3993
|
+
|
|
3896
3994
|
// src/i18n/core.ts
|
|
3995
|
+
function toChain(fallback) {
|
|
3996
|
+
return Array.isArray(fallback) ? fallback : fallback ? [fallback] : [];
|
|
3997
|
+
}
|
|
3998
|
+
function pickFromChain(value, chain) {
|
|
3999
|
+
for (const fb of chain) {
|
|
4000
|
+
if (fb === "any") {
|
|
4001
|
+
const any = Object.values(value).find((v) => v !== "");
|
|
4002
|
+
if (any !== void 0) return any;
|
|
4003
|
+
} else if (value[fb] !== void 0 && value[fb] !== "") {
|
|
4004
|
+
return value[fb];
|
|
4005
|
+
}
|
|
4006
|
+
}
|
|
4007
|
+
return void 0;
|
|
4008
|
+
}
|
|
4009
|
+
function resolveI18nText(value, locale, fallback, field, opts) {
|
|
4010
|
+
if (locale === "raw") {
|
|
4011
|
+
return value;
|
|
4012
|
+
}
|
|
4013
|
+
if (!locale) {
|
|
4014
|
+
throw new LocaleNotSpecifiedError(field ?? "<unknown>");
|
|
4015
|
+
}
|
|
4016
|
+
if (value[locale] !== void 0 && value[locale] !== "") {
|
|
4017
|
+
return value[locale];
|
|
4018
|
+
}
|
|
4019
|
+
const policy = opts?.policy ?? "throw";
|
|
4020
|
+
const callerChain = toChain(fallback);
|
|
4021
|
+
const callerHit = pickFromChain(value, callerChain);
|
|
4022
|
+
if (callerHit !== void 0) return callerHit;
|
|
4023
|
+
if (policy === "substitute") {
|
|
4024
|
+
const subHit = pickFromChain(value, toChain(opts?.substitute));
|
|
4025
|
+
if (subHit !== void 0) return subHit;
|
|
4026
|
+
if (opts?.smartSubstitute) {
|
|
4027
|
+
const smartHit = pickNearestScript(value, locale);
|
|
4028
|
+
if (smartHit !== void 0) return smartHit;
|
|
4029
|
+
}
|
|
4030
|
+
}
|
|
4031
|
+
if (policy === "throw") {
|
|
4032
|
+
throw new LocaleNotSpecifiedError(
|
|
4033
|
+
field ?? "<unknown>",
|
|
4034
|
+
`No translation available for locale "${locale}"` + (callerChain.length > 0 ? ` or fallback chain [${callerChain.join(", ")}]` : "") + "."
|
|
4035
|
+
);
|
|
4036
|
+
}
|
|
4037
|
+
return null;
|
|
4038
|
+
}
|
|
4039
|
+
function pickNearestScript(value, target) {
|
|
4040
|
+
const targetScript = inferScripts(target)[0] ?? "Latin";
|
|
4041
|
+
let best;
|
|
4042
|
+
for (const [loc, v] of Object.entries(value)) {
|
|
4043
|
+
if (typeof v !== "string" || v === "") continue;
|
|
4044
|
+
const s = inferScripts(loc)[0] ?? "Latin";
|
|
4045
|
+
const score = s === targetScript ? 0 : s === "Latin" ? 1 : 2;
|
|
4046
|
+
if (best === void 0 || score < best.score) best = { score, v };
|
|
4047
|
+
if (score === 0) break;
|
|
4048
|
+
}
|
|
4049
|
+
return best?.v;
|
|
4050
|
+
}
|
|
3897
4051
|
function getAtPath(obj, path) {
|
|
3898
4052
|
const arrayIdx = path.indexOf("[].");
|
|
3899
4053
|
if (arrayIdx !== -1) {
|
|
@@ -3929,9 +4083,61 @@ function setAtPathInPlace(obj, path, value) {
|
|
|
3929
4083
|
}
|
|
3930
4084
|
obj[path] = value;
|
|
3931
4085
|
}
|
|
4086
|
+
function applyAtPath(obj, path, locale, fallback, opts) {
|
|
4087
|
+
const arrayIdx = path.indexOf("[].");
|
|
4088
|
+
if (arrayIdx !== -1) {
|
|
4089
|
+
const arrayKey = path.slice(0, arrayIdx);
|
|
4090
|
+
const restPath = path.slice(arrayIdx + 3);
|
|
4091
|
+
const arr = obj[arrayKey];
|
|
4092
|
+
if (!Array.isArray(arr)) return obj;
|
|
4093
|
+
return {
|
|
4094
|
+
...obj,
|
|
4095
|
+
[arrayKey]: arr.map((item) => {
|
|
4096
|
+
if (!item || typeof item !== "object" || Array.isArray(item)) return item;
|
|
4097
|
+
return applyAtPath(item, restPath, locale, fallback, opts);
|
|
4098
|
+
})
|
|
4099
|
+
};
|
|
4100
|
+
}
|
|
4101
|
+
const dotIdx = path.indexOf(".");
|
|
4102
|
+
if (dotIdx !== -1) {
|
|
4103
|
+
const head = path.slice(0, dotIdx);
|
|
4104
|
+
const rest = path.slice(dotIdx + 1);
|
|
4105
|
+
const nested = obj[head];
|
|
4106
|
+
if (!nested || typeof nested !== "object" || Array.isArray(nested)) return obj;
|
|
4107
|
+
return {
|
|
4108
|
+
...obj,
|
|
4109
|
+
[head]: applyAtPath(nested, rest, locale, fallback, opts)
|
|
4110
|
+
};
|
|
4111
|
+
}
|
|
4112
|
+
const raw = obj[path];
|
|
4113
|
+
if (raw === void 0 || raw === null) return obj;
|
|
4114
|
+
if (typeof raw !== "object" || Array.isArray(raw)) return obj;
|
|
4115
|
+
return {
|
|
4116
|
+
...obj,
|
|
4117
|
+
[path]: resolveI18nText(raw, locale, fallback, path, opts)
|
|
4118
|
+
};
|
|
4119
|
+
}
|
|
4120
|
+
function applyI18nLocale(record, i18nFields, locale, fallback, layer = "read") {
|
|
4121
|
+
const fieldNames = Object.keys(i18nFields);
|
|
4122
|
+
if (fieldNames.length === 0) return record;
|
|
4123
|
+
let result = record;
|
|
4124
|
+
for (const [field, descriptor] of Object.entries(i18nFields)) {
|
|
4125
|
+
const { onMissing, substitute, smartSubstitute } = descriptor.options;
|
|
4126
|
+
const opts = {
|
|
4127
|
+
policy: resolvePolicy(onMissing, layer),
|
|
4128
|
+
...substitute !== void 0 ? { substitute } : {},
|
|
4129
|
+
...smartSubstitute ? { smartSubstitute } : {}
|
|
4130
|
+
};
|
|
4131
|
+
result = applyAtPath(result, field, locale, fallback, opts);
|
|
4132
|
+
}
|
|
4133
|
+
return result;
|
|
4134
|
+
}
|
|
3932
4135
|
var init_core = __esm({
|
|
3933
4136
|
"src/i18n/core.ts"() {
|
|
3934
4137
|
"use strict";
|
|
4138
|
+
init_errors();
|
|
4139
|
+
init_policy();
|
|
4140
|
+
init_script();
|
|
3935
4141
|
}
|
|
3936
4142
|
});
|
|
3937
4143
|
|
|
@@ -4868,15 +5074,15 @@ function warnCeilingApproaching(target, side, rows, maxRows) {
|
|
|
4868
5074
|
`[noy-db] .join() ${side} side is at ${pct}% of the ${maxRows}-row ceiling for target "${target}" (${rows} rows). Streaming joins over scan() are not yet supported for collections that need to exceed this.`
|
|
4869
5075
|
);
|
|
4870
5076
|
}
|
|
4871
|
-
function applyJoins(rows, joins, context) {
|
|
5077
|
+
function applyJoins(rows, joins, context, locale) {
|
|
4872
5078
|
if (joins.length === 0) return [...rows];
|
|
4873
5079
|
let result = [...rows];
|
|
4874
5080
|
for (const leg of joins) {
|
|
4875
|
-
result = applyOneJoin(result, leg, context);
|
|
5081
|
+
result = applyOneJoin(result, leg, context, locale);
|
|
4876
5082
|
}
|
|
4877
5083
|
return result;
|
|
4878
5084
|
}
|
|
4879
|
-
function applyOneJoin(leftRows, leg, context) {
|
|
5085
|
+
function applyOneJoin(leftRows, leg, context, locale) {
|
|
4880
5086
|
if (leg.isDictJoin) {
|
|
4881
5087
|
const dictSource = context.resolveDictSource?.(leg.field);
|
|
4882
5088
|
if (!dictSource) {
|
|
@@ -4931,24 +5137,27 @@ function applyOneJoin(leftRows, leg, context) {
|
|
|
4931
5137
|
if (rightSnapshot.length > maxRows * JOIN_WARN_FRACTION) {
|
|
4932
5138
|
warnCeilingApproaching(leg.target, "right", rightSnapshot.length, maxRows);
|
|
4933
5139
|
}
|
|
5140
|
+
const effLocale = locale ?? context.defaultLocale;
|
|
5141
|
+
const i18nResolve = effLocale !== void 0 && source.i18nFields !== void 0 ? (right) => right !== null && typeof right === "object" ? applyI18nLocale(right, source.i18nFields, effLocale, void 0, "join") : right : void 0;
|
|
4934
5142
|
const strategy = leg.strategy ?? (source.lookupById ? "nested" : "hash");
|
|
4935
5143
|
if (strategy === "nested" && source.lookupById) {
|
|
4936
5144
|
const lookup = (id) => source.lookupById?.(id);
|
|
4937
|
-
return nestedLoopJoin(leftRows, leg, lookup);
|
|
5145
|
+
return nestedLoopJoin(leftRows, leg, lookup, i18nResolve);
|
|
4938
5146
|
}
|
|
4939
|
-
return hashJoin(leftRows, leg, rightSnapshot);
|
|
5147
|
+
return hashJoin(leftRows, leg, rightSnapshot, i18nResolve);
|
|
4940
5148
|
}
|
|
4941
|
-
function nestedLoopJoin(leftRows, leg, lookupById) {
|
|
5149
|
+
function nestedLoopJoin(leftRows, leg, lookupById, i18nResolve) {
|
|
4942
5150
|
const out = [];
|
|
4943
5151
|
for (const left of leftRows) {
|
|
4944
5152
|
const rawId = readPath(left, leg.field);
|
|
4945
5153
|
const key = coerceRefKey(rawId);
|
|
4946
|
-
|
|
5154
|
+
let right = key === null ? void 0 : lookupById(key);
|
|
5155
|
+
if (i18nResolve && right !== void 0) right = i18nResolve(right);
|
|
4947
5156
|
out.push(attachJoin(left, leg, right, rawId));
|
|
4948
5157
|
}
|
|
4949
5158
|
return out;
|
|
4950
5159
|
}
|
|
4951
|
-
function hashJoin(leftRows, leg, rightSnapshot) {
|
|
5160
|
+
function hashJoin(leftRows, leg, rightSnapshot, i18nResolve) {
|
|
4952
5161
|
const rightMap = /* @__PURE__ */ new Map();
|
|
4953
5162
|
for (const record of rightSnapshot) {
|
|
4954
5163
|
const rawId = readPath(record, "id");
|
|
@@ -4961,7 +5170,8 @@ function hashJoin(leftRows, leg, rightSnapshot) {
|
|
|
4961
5170
|
for (const left of leftRows) {
|
|
4962
5171
|
const rawId = readPath(left, leg.field);
|
|
4963
5172
|
const key = coerceRefKey(rawId);
|
|
4964
|
-
|
|
5173
|
+
let right = key === null ? void 0 : rightMap.get(key);
|
|
5174
|
+
if (i18nResolve && right !== void 0) right = i18nResolve(right);
|
|
4965
5175
|
out.push(attachJoin(left, leg, right, rawId));
|
|
4966
5176
|
}
|
|
4967
5177
|
return out;
|
|
@@ -4996,6 +5206,7 @@ var init_join = __esm({
|
|
|
4996
5206
|
"use strict";
|
|
4997
5207
|
init_predicate();
|
|
4998
5208
|
init_errors();
|
|
5209
|
+
init_core();
|
|
4999
5210
|
DEFAULT_JOIN_MAX_ROWS = 5e4;
|
|
5000
5211
|
JOIN_WARN_FRACTION = 0.8;
|
|
5001
5212
|
warnedDanglingKeys = /* @__PURE__ */ new Set();
|
|
@@ -5300,7 +5511,7 @@ var init_money_reducer = __esm({
|
|
|
5300
5511
|
});
|
|
5301
5512
|
|
|
5302
5513
|
// src/query/builder.ts
|
|
5303
|
-
function executePlanWithSource(source, plan, joinContext) {
|
|
5514
|
+
function executePlanWithSource(source, plan, joinContext, locale) {
|
|
5304
5515
|
const hasCrossJoins = plan.clauses.some((c) => c.type === "crossJoin");
|
|
5305
5516
|
let result;
|
|
5306
5517
|
if (hasCrossJoins) {
|
|
@@ -5315,7 +5526,8 @@ function executePlanWithSource(source, plan, joinContext) {
|
|
|
5315
5526
|
result = remainingClauses.length === 0 ? [...candidates] : filterRecords(candidates, remainingClauses, fnViewDecoder(source));
|
|
5316
5527
|
}
|
|
5317
5528
|
if (plan.orderBy.length > 0) {
|
|
5318
|
-
|
|
5529
|
+
const labelMaps = buildOrderLabelMaps(plan.orderBy, joinContext, locale);
|
|
5530
|
+
result = sortRecords(result, plan.orderBy, source.moneyFields, labelMaps);
|
|
5319
5531
|
}
|
|
5320
5532
|
if (plan.offset > 0) {
|
|
5321
5533
|
result = result.slice(plan.offset);
|
|
@@ -5454,11 +5666,19 @@ function applyCrossJoin(leftRel, clause, rightSource) {
|
|
|
5454
5666
|
}
|
|
5455
5667
|
return expanded;
|
|
5456
5668
|
}
|
|
5457
|
-
function sortRecords(records, orderBy, moneyFields) {
|
|
5669
|
+
function sortRecords(records, orderBy, moneyFields, labelMaps) {
|
|
5458
5670
|
return [...records].sort((a, b) => {
|
|
5459
|
-
for (const { field, direction } of orderBy) {
|
|
5460
|
-
|
|
5461
|
-
|
|
5671
|
+
for (const { field, direction, by } of orderBy) {
|
|
5672
|
+
let av = readField(a, field);
|
|
5673
|
+
let bv = readField(b, field);
|
|
5674
|
+
const labelMap = by === "label" ? labelMaps?.get(field) : void 0;
|
|
5675
|
+
if (labelMap) {
|
|
5676
|
+
av = (typeof av === "string" ? labelMap.get(av) : void 0) ?? av;
|
|
5677
|
+
bv = (typeof bv === "string" ? labelMap.get(bv) : void 0) ?? bv;
|
|
5678
|
+
const cmp2 = compareValues(av, bv);
|
|
5679
|
+
if (cmp2 !== 0) return direction === "asc" ? cmp2 : -cmp2;
|
|
5680
|
+
continue;
|
|
5681
|
+
}
|
|
5462
5682
|
const desc = moneyFields?.[field];
|
|
5463
5683
|
const cmp = desc ? compareMoney(av, bv, desc) : compareValues(av, bv);
|
|
5464
5684
|
if (cmp !== 0) return direction === "asc" ? cmp : -cmp;
|
|
@@ -5466,6 +5686,28 @@ function sortRecords(records, orderBy, moneyFields) {
|
|
|
5466
5686
|
return 0;
|
|
5467
5687
|
});
|
|
5468
5688
|
}
|
|
5689
|
+
function buildOrderLabelMaps(orderBy, joinContext, locale) {
|
|
5690
|
+
if (!joinContext?.resolveDictSource) return void 0;
|
|
5691
|
+
const resolveDict = joinContext.resolveDictSource.bind(joinContext);
|
|
5692
|
+
let maps;
|
|
5693
|
+
for (const { field, by } of orderBy) {
|
|
5694
|
+
if (by !== "label") continue;
|
|
5695
|
+
const dictSource = resolveDict(field);
|
|
5696
|
+
if (!dictSource) continue;
|
|
5697
|
+
const loc = locale ?? dictSource.displayLocale;
|
|
5698
|
+
if (loc === void 0) continue;
|
|
5699
|
+
const codeToLabel = /* @__PURE__ */ new Map();
|
|
5700
|
+
for (const entry of dictSource.snapshot()) {
|
|
5701
|
+
const k = entry["key"];
|
|
5702
|
+
const labels = entry["labels"];
|
|
5703
|
+
const label = labels?.[loc];
|
|
5704
|
+
if (typeof k === "string" && typeof label === "string") codeToLabel.set(k, label);
|
|
5705
|
+
}
|
|
5706
|
+
;
|
|
5707
|
+
(maps ??= /* @__PURE__ */ new Map()).set(field, codeToLabel);
|
|
5708
|
+
}
|
|
5709
|
+
return maps;
|
|
5710
|
+
}
|
|
5469
5711
|
function compareMoney(a, b, desc) {
|
|
5470
5712
|
const av = moneyScaledValue(a, desc);
|
|
5471
5713
|
const bv = moneyScaledValue(b, desc);
|
|
@@ -5766,11 +6008,16 @@ var init_builder = __esm({
|
|
|
5766
6008
|
this.predicates
|
|
5767
6009
|
);
|
|
5768
6010
|
}
|
|
5769
|
-
/**
|
|
5770
|
-
|
|
6011
|
+
/**
|
|
6012
|
+
* Sort by a field. Subsequent calls are tie-breakers. Pass
|
|
6013
|
+
* `{ by: 'label' }` to sort a `dictKey`/`staticDict` field by its resolved
|
|
6014
|
+
* label at the query locale instead of the stored code (#285).
|
|
6015
|
+
*/
|
|
6016
|
+
orderBy(field, direction = "asc", opts) {
|
|
6017
|
+
const entry = opts?.by === "label" ? { field, direction, by: "label" } : { field, direction };
|
|
5771
6018
|
return new _Query(
|
|
5772
6019
|
this.source,
|
|
5773
|
-
{ ...this.plan, orderBy: [...this.plan.orderBy,
|
|
6020
|
+
{ ...this.plan, orderBy: [...this.plan.orderBy, entry] },
|
|
5774
6021
|
this.joinContext,
|
|
5775
6022
|
this.aggregateStrategy,
|
|
5776
6023
|
this.predicates
|
|
@@ -5973,16 +6220,21 @@ var init_builder = __esm({
|
|
|
5973
6220
|
* carries any join legs, they are applied after `where` / `orderBy`
|
|
5974
6221
|
* / `limit` / `offset` narrow the left set. See the `.join()` doc
|
|
5975
6222
|
* for the ordering rationale.
|
|
6223
|
+
*
|
|
6224
|
+
* `opts.locale` (#285 §3) resolves JOINED right-side i18n fields at the
|
|
6225
|
+
* `join` layer to that locale; without it, the owning collection's default
|
|
6226
|
+
* locale applies, and a locale-less query leaves joined i18n fields raw.
|
|
6227
|
+
* (Left/base i18n fields are resolved by `get`/`list`, not here.)
|
|
5976
6228
|
*/
|
|
5977
|
-
toArray() {
|
|
5978
|
-
const base = this.decodeMoney(executePlanWithSource(this.source, this.plan, this.joinContext));
|
|
6229
|
+
toArray(opts) {
|
|
6230
|
+
const base = this.decodeMoney(executePlanWithSource(this.source, this.plan, this.joinContext, opts?.locale));
|
|
5979
6231
|
if (this.plan.joins.length === 0) return base;
|
|
5980
6232
|
if (!this.joinContext) {
|
|
5981
6233
|
throw new Error(
|
|
5982
6234
|
`Query.toArray(): plan carries ${this.plan.joins.length} join leg(s) but no JoinContext is attached. This usually means the Query was constructed via the raw Query constructor with a plan that had joins pre-populated. Use collection.query().join(...) instead.`
|
|
5983
6235
|
);
|
|
5984
6236
|
}
|
|
5985
|
-
return applyJoins(base, this.plan.joins, this.joinContext);
|
|
6237
|
+
return applyJoins(base, this.plan.joins, this.joinContext, opts?.locale);
|
|
5986
6238
|
}
|
|
5987
6239
|
/**
|
|
5988
6240
|
* Decode this source's money fields on read (stored scaled-int → canonical
|
|
@@ -6001,9 +6253,9 @@ var init_builder = __esm({
|
|
|
6001
6253
|
if (!moneyFields || Object.keys(moneyFields).length === 0) return records;
|
|
6002
6254
|
return records.map((r) => decodeMoneyFields(r, moneyFields, "raw"));
|
|
6003
6255
|
}
|
|
6004
|
-
/** Return the first matching record, or null. Joins are applied. */
|
|
6005
|
-
first() {
|
|
6006
|
-
const arr = this.limit(1).toArray();
|
|
6256
|
+
/** Return the first matching record, or null. Joins are applied. `opts.locale` resolves joined i18n fields (#285 §3). */
|
|
6257
|
+
first(opts) {
|
|
6258
|
+
const arr = this.limit(1).toArray(opts);
|
|
6007
6259
|
return arr[0] ?? null;
|
|
6008
6260
|
}
|
|
6009
6261
|
/**
|
|
@@ -7017,6 +7269,95 @@ var init_strategy5 = __esm({
|
|
|
7017
7269
|
}
|
|
7018
7270
|
});
|
|
7019
7271
|
|
|
7272
|
+
// src/search/tokenize.ts
|
|
7273
|
+
var WORD, tokenize;
|
|
7274
|
+
var init_tokenize = __esm({
|
|
7275
|
+
"src/search/tokenize.ts"() {
|
|
7276
|
+
"use strict";
|
|
7277
|
+
WORD = /[\p{L}\p{N}]+/gu;
|
|
7278
|
+
tokenize = (text) => {
|
|
7279
|
+
if (!text) return [];
|
|
7280
|
+
return text.normalize("NFKC").toLowerCase().match(WORD) ?? [];
|
|
7281
|
+
};
|
|
7282
|
+
}
|
|
7283
|
+
});
|
|
7284
|
+
|
|
7285
|
+
// src/search/scan.ts
|
|
7286
|
+
function fieldText(record, field) {
|
|
7287
|
+
const v = record[field];
|
|
7288
|
+
if (typeof v === "string") return v;
|
|
7289
|
+
if (v === null || v === void 0) return "";
|
|
7290
|
+
if (typeof v === "number" || typeof v === "boolean") return String(v);
|
|
7291
|
+
return "";
|
|
7292
|
+
}
|
|
7293
|
+
function searchScan(entries, field, query, opts = {}, tokenizer = tokenize) {
|
|
7294
|
+
const queryTerms = tokenizer(query);
|
|
7295
|
+
if (queryTerms.length === 0) return [];
|
|
7296
|
+
const match = opts.match ?? "any";
|
|
7297
|
+
const usePrefix = opts.prefix ?? false;
|
|
7298
|
+
const exactTerms = usePrefix ? queryTerms.slice(0, -1) : queryTerms;
|
|
7299
|
+
const prefixTerm = usePrefix ? queryTerms[queryTerms.length - 1] : void 0;
|
|
7300
|
+
const docs = entries.map((e) => ({ id: e.id, record: e.record, terms: tokenizer(fieldText(e.record, field)) }));
|
|
7301
|
+
const N = docs.length || 1;
|
|
7302
|
+
const df = /* @__PURE__ */ new Map();
|
|
7303
|
+
let totalLen = 0;
|
|
7304
|
+
for (const d of docs) {
|
|
7305
|
+
totalLen += d.terms.length;
|
|
7306
|
+
for (const t of new Set(d.terms)) df.set(t, (df.get(t) ?? 0) + 1);
|
|
7307
|
+
}
|
|
7308
|
+
const avgdl = totalLen / N || 1;
|
|
7309
|
+
let prefixDf = 0;
|
|
7310
|
+
if (prefixTerm !== void 0) {
|
|
7311
|
+
for (const d of docs) {
|
|
7312
|
+
if (d.terms.some((t) => t.startsWith(prefixTerm))) prefixDf++;
|
|
7313
|
+
}
|
|
7314
|
+
}
|
|
7315
|
+
const requiredCount = exactTerms.length + (prefixTerm !== void 0 ? 1 : 0);
|
|
7316
|
+
const results = [];
|
|
7317
|
+
for (const d of docs) {
|
|
7318
|
+
const tf = /* @__PURE__ */ new Map();
|
|
7319
|
+
for (const t of d.terms) tf.set(t, (tf.get(t) ?? 0) + 1);
|
|
7320
|
+
const matched = [];
|
|
7321
|
+
for (const qt of exactTerms) {
|
|
7322
|
+
const c = tf.get(qt) ?? 0;
|
|
7323
|
+
if (c > 0) matched.push({ tf: c, df: df.get(qt) ?? 0 });
|
|
7324
|
+
}
|
|
7325
|
+
if (prefixTerm !== void 0) {
|
|
7326
|
+
let ptf = 0;
|
|
7327
|
+
for (const [t, c] of tf) if (t.startsWith(prefixTerm)) ptf += c;
|
|
7328
|
+
if (ptf > 0) matched.push({ tf: ptf, df: prefixDf });
|
|
7329
|
+
}
|
|
7330
|
+
if (matched.length === 0) continue;
|
|
7331
|
+
if (match === "all" && matched.length < requiredCount) continue;
|
|
7332
|
+
let score = 0;
|
|
7333
|
+
for (const m of matched) {
|
|
7334
|
+
const idf = Math.log(1 + (N - m.df + 0.5) / (m.df + 0.5));
|
|
7335
|
+
const denom = m.tf + K1 * (1 - B + B * (d.terms.length / avgdl));
|
|
7336
|
+
score += idf * (m.tf * (K1 + 1) / (denom || 1));
|
|
7337
|
+
}
|
|
7338
|
+
results.push({ id: d.id, score, record: d.record });
|
|
7339
|
+
}
|
|
7340
|
+
results.sort((a, b) => b.score - a.score);
|
|
7341
|
+
return opts.limit !== void 0 ? results.slice(0, opts.limit) : results;
|
|
7342
|
+
}
|
|
7343
|
+
var K1, B;
|
|
7344
|
+
var init_scan = __esm({
|
|
7345
|
+
"src/search/scan.ts"() {
|
|
7346
|
+
"use strict";
|
|
7347
|
+
init_tokenize();
|
|
7348
|
+
K1 = 1.2;
|
|
7349
|
+
B = 0.75;
|
|
7350
|
+
}
|
|
7351
|
+
});
|
|
7352
|
+
|
|
7353
|
+
// src/search/index.ts
|
|
7354
|
+
var init_search = __esm({
|
|
7355
|
+
"src/search/index.ts"() {
|
|
7356
|
+
"use strict";
|
|
7357
|
+
init_scan();
|
|
7358
|
+
}
|
|
7359
|
+
});
|
|
7360
|
+
|
|
7020
7361
|
// src/indexing/unique-constraints.ts
|
|
7021
7362
|
function buildUniqueConstraintSet(collectionName, indexes, mode) {
|
|
7022
7363
|
const uniqueDefs = [];
|
|
@@ -8034,12 +8375,13 @@ var executor_exports2 = {};
|
|
|
8034
8375
|
__export(executor_exports2, {
|
|
8035
8376
|
MaterializedViewExecutor: () => MaterializedViewExecutor
|
|
8036
8377
|
});
|
|
8037
|
-
async function materializeQueryResult(q, mvName) {
|
|
8378
|
+
async function materializeQueryResult(q, mvName, i18nLocale, i18nFields) {
|
|
8038
8379
|
if (typeof q?.toArray === "function") {
|
|
8039
8380
|
return await q.toArray();
|
|
8040
8381
|
}
|
|
8041
8382
|
if (typeof q?.run === "function") {
|
|
8042
|
-
const
|
|
8383
|
+
const runOpts = i18nLocale !== void 0 ? { locale: i18nLocale, i18nFields } : void 0;
|
|
8384
|
+
const result = await Promise.resolve(q.run(runOpts));
|
|
8043
8385
|
if (Array.isArray(result)) {
|
|
8044
8386
|
return result;
|
|
8045
8387
|
}
|
|
@@ -8068,6 +8410,29 @@ async function materializeUnionResult(spec, db) {
|
|
|
8068
8410
|
}
|
|
8069
8411
|
if (!spec.groupBy) return unified;
|
|
8070
8412
|
const groupFields = typeof spec.groupBy === "string" ? [spec.groupBy] : spec.groupBy;
|
|
8413
|
+
if (spec.i18nLocale !== void 0 && spec.i18nFields !== void 0) {
|
|
8414
|
+
const groupI18n = {};
|
|
8415
|
+
for (const f of groupFields) {
|
|
8416
|
+
const d = spec.i18nFields[f];
|
|
8417
|
+
if (d !== void 0) groupI18n[f] = d;
|
|
8418
|
+
}
|
|
8419
|
+
if (Object.keys(groupI18n).length > 0) {
|
|
8420
|
+
for (let i = 0; i < unified.length; i++) {
|
|
8421
|
+
unified[i] = applyI18nLocale(unified[i], groupI18n, spec.i18nLocale, void 0, "mv");
|
|
8422
|
+
}
|
|
8423
|
+
}
|
|
8424
|
+
}
|
|
8425
|
+
for (const f of groupFields) {
|
|
8426
|
+
for (const row of unified) {
|
|
8427
|
+
const v = row[f];
|
|
8428
|
+
if (v !== null && typeof v === "object") {
|
|
8429
|
+
throw new LocaleNotSpecifiedError(
|
|
8430
|
+
f,
|
|
8431
|
+
`Materialized view "${spec.name}" groups by "${f}", whose value is a raw i18n locale map \u2014 an unstable object group key. Declare { i18nLocale, i18nFields } on the MV to resolve it at the 'mv' layer, or group by a dictKey/staticDict code (the stable key) and resolve the label at read time.`
|
|
8432
|
+
);
|
|
8433
|
+
}
|
|
8434
|
+
}
|
|
8435
|
+
}
|
|
8071
8436
|
if (!spec.aggregate) {
|
|
8072
8437
|
const seen = /* @__PURE__ */ new Map();
|
|
8073
8438
|
for (const row of unified) {
|
|
@@ -8099,6 +8464,7 @@ var init_executor2 = __esm({
|
|
|
8099
8464
|
init_registry();
|
|
8100
8465
|
init_groupby();
|
|
8101
8466
|
init_canonical_key();
|
|
8467
|
+
init_core();
|
|
8102
8468
|
DEFAULT_MAX_ROWS = 1e5;
|
|
8103
8469
|
MaterializedViewExecutor = {
|
|
8104
8470
|
async refresh(reg, accessor) {
|
|
@@ -8114,7 +8480,7 @@ var init_executor2 = __esm({
|
|
|
8114
8480
|
rows = await materializeUnionResult(spec, ctxForQuery);
|
|
8115
8481
|
} else {
|
|
8116
8482
|
const q = spec.query(ctxForQuery);
|
|
8117
|
-
rows = await materializeQueryResult(q, spec.name);
|
|
8483
|
+
rows = await materializeQueryResult(q, spec.name, spec.i18nLocale, spec.i18nFields);
|
|
8118
8484
|
}
|
|
8119
8485
|
if (rows.length > maxRows) {
|
|
8120
8486
|
throw new MaterializedViewTooLargeError(spec.name, rows.length, maxRows);
|
|
@@ -8373,6 +8739,7 @@ var init_collection = __esm({
|
|
|
8373
8739
|
init_persisted_indexes();
|
|
8374
8740
|
init_lazy_builder();
|
|
8375
8741
|
init_strategy5();
|
|
8742
|
+
init_search();
|
|
8376
8743
|
init_errors();
|
|
8377
8744
|
init_unique_constraints();
|
|
8378
8745
|
init_cache();
|
|
@@ -9935,6 +10302,29 @@ var init_collection = __esm({
|
|
|
9935
10302
|
hasReadTransforms() {
|
|
9936
10303
|
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;
|
|
9937
10304
|
}
|
|
10305
|
+
/**
|
|
10306
|
+
* Scan-mode full-text search over a plain-text `field` (#308). Decrypts the
|
|
10307
|
+
* collection in memory and ranks records by BM25 against the tokenized query.
|
|
10308
|
+
* **Zero added store leakage** — pure client-side scan; nothing searchable is
|
|
10309
|
+
* written to the store. (A store-usable blind index for at-scale search is a
|
|
10310
|
+
* separate, gated opt-in — see the #308 design note.) Eager mode only.
|
|
10311
|
+
*
|
|
10312
|
+
* `opts.match` (`'any'` default | `'all'`), `opts.prefix` (last query term as
|
|
10313
|
+
* a prefix → typeahead), `opts.limit` (top-N). Returns `{ id, score, record }`
|
|
10314
|
+
* ranked by descending score. The default tokenizer is word-boundary based —
|
|
10315
|
+
* see `src/search/tokenize.ts` for the Thai/CJK caveat.
|
|
10316
|
+
*/
|
|
10317
|
+
async search(field, query, opts = {}) {
|
|
10318
|
+
if (this.lazy) {
|
|
10319
|
+
throw new Error(
|
|
10320
|
+
`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).`
|
|
10321
|
+
);
|
|
10322
|
+
}
|
|
10323
|
+
await this.ensureHydrated();
|
|
10324
|
+
const entries = [];
|
|
10325
|
+
for (const [id, e] of this.cache) entries.push({ id, record: e.record });
|
|
10326
|
+
return searchScan(entries, field, query, opts);
|
|
10327
|
+
}
|
|
9938
10328
|
// ─── Bulk operations ─────────────────────────────────────
|
|
9939
10329
|
/**
|
|
9940
10330
|
* Put many records in one call. Each item is processed sequentially
|
|
@@ -10112,6 +10502,10 @@ var init_collection = __esm({
|
|
|
10112
10502
|
leftCollection,
|
|
10113
10503
|
resolveRef: (field) => resolver.resolveRef(leftCollection, field),
|
|
10114
10504
|
resolveSource: (collectionName) => resolver.resolveSource(collectionName),
|
|
10505
|
+
// #285 §3 — flow the vault/collection default locale to joins so a
|
|
10506
|
+
// joined i18n field resolves like get()/list() when no per-call
|
|
10507
|
+
// locale is given; toArray({ locale }) overrides it.
|
|
10508
|
+
...this.defaultLocale !== void 0 ? { defaultLocale: this.defaultLocale } : {},
|
|
10115
10509
|
...resolver.resolveDictSource ? { resolveDictSource: (field) => resolver.resolveDictSource(leftCollection, field) } : {}
|
|
10116
10510
|
} : void 0;
|
|
10117
10511
|
return new Query(source, void 0, joinContext, this.aggregateStrategy);
|
|
@@ -10200,7 +10594,10 @@ var init_collection = __esm({
|
|
|
10200
10594
|
};
|
|
10201
10595
|
this.emitter.on("change", handler);
|
|
10202
10596
|
return () => this.emitter.off("change", handler);
|
|
10203
|
-
}
|
|
10597
|
+
},
|
|
10598
|
+
// #285 §3 — expose this (right-side) collection's i18nText descriptors so
|
|
10599
|
+
// the join executor can resolve joined i18n fields at the `join` layer.
|
|
10600
|
+
...this.i18nFields !== void 0 ? { i18nFields: this.i18nFields } : {}
|
|
10204
10601
|
};
|
|
10205
10602
|
}
|
|
10206
10603
|
/**
|
|
@@ -10433,6 +10830,10 @@ var init_collection = __esm({
|
|
|
10433
10830
|
leftCollection,
|
|
10434
10831
|
resolveRef: (field) => resolver.resolveRef(leftCollection, field),
|
|
10435
10832
|
resolveSource: (collectionName) => resolver.resolveSource(collectionName),
|
|
10833
|
+
// #285 §3 — flow the vault/collection default locale to joins so a
|
|
10834
|
+
// joined i18n field resolves like get()/list() when no per-call
|
|
10835
|
+
// locale is given; toArray({ locale }) overrides it.
|
|
10836
|
+
...this.defaultLocale !== void 0 ? { defaultLocale: this.defaultLocale } : {},
|
|
10436
10837
|
...resolver.resolveDictSource ? { resolveDictSource: (field) => resolver.resolveDictSource(leftCollection, field) } : {}
|
|
10437
10838
|
} : void 0;
|
|
10438
10839
|
return new ScanBuilder(
|
|
@@ -10990,6 +11391,34 @@ var init_collection = __esm({
|
|
|
10990
11391
|
}
|
|
10991
11392
|
}
|
|
10992
11393
|
}
|
|
11394
|
+
/**
|
|
11395
|
+
* @internal — hard-delete this record's persisted `_idx/<field>/<recordId>`
|
|
11396
|
+
* side-cars for the erasure path (#401). `forget()` crypto-shreds the body but
|
|
11397
|
+
* keeps the collection DEK, under which these side-cars are encrypted — so
|
|
11398
|
+
* without this they leave the indexed field VALUES readable after a "forget".
|
|
11399
|
+
*
|
|
11400
|
+
* Content-free: the side-car id is `encodeIdxId(def.key, id)`, so it needs no
|
|
11401
|
+
* body decode (the body is being shredded). Eager mode has no durable side-car
|
|
11402
|
+
* → no-op. The in-memory mirror is left as-is: it is ephemeral (rebuilt from
|
|
11403
|
+
* the now-deleted side-cars on reopen) and live reads skip the tombstone, so a
|
|
11404
|
+
* stale mirror hit cannot surface the erased record. Returns the count deleted
|
|
11405
|
+
* + the `def.key`s whose delete FAILED (residue that still leaks the value).
|
|
11406
|
+
*/
|
|
11407
|
+
async _purgePersistedIndexes(id) {
|
|
11408
|
+
const persisted = this.persistedIndexes;
|
|
11409
|
+
if (!persisted) return { purged: 0, residue: [] };
|
|
11410
|
+
let purged = 0;
|
|
11411
|
+
const residue = [];
|
|
11412
|
+
for (const def of persisted.definitions()) {
|
|
11413
|
+
try {
|
|
11414
|
+
await this.adapter.delete(this.vault, this.name, encodeIdxId(def.key, id));
|
|
11415
|
+
purged++;
|
|
11416
|
+
} catch {
|
|
11417
|
+
residue.push(def.key);
|
|
11418
|
+
}
|
|
11419
|
+
}
|
|
11420
|
+
return { purged, residue };
|
|
11421
|
+
}
|
|
10993
11422
|
/**
|
|
10994
11423
|
* Bulk-load the persisted-index mirror from `_idx/<field>/*` side-cars
|
|
10995
11424
|
* on first lazy-mode query. Idempotent — subsequent calls short-circuit
|
|
@@ -16353,6 +16782,8 @@ var init_vault = __esm({
|
|
|
16353
16782
|
const blobResidueCollections = /* @__PURE__ */ new Set();
|
|
16354
16783
|
let blobsShredded = 0;
|
|
16355
16784
|
let blobsRetainedShared = 0;
|
|
16785
|
+
let indexPostingsPurged = 0;
|
|
16786
|
+
const indexResidue = [];
|
|
16356
16787
|
const blobsEnabled = this.blobStrategy !== void 0;
|
|
16357
16788
|
const actor = this.keyring.userId;
|
|
16358
16789
|
for (const ref of refs) {
|
|
@@ -16374,6 +16805,9 @@ var init_vault = __esm({
|
|
|
16374
16805
|
ref.id,
|
|
16375
16806
|
actor
|
|
16376
16807
|
);
|
|
16808
|
+
const idxPurge = await coll._purgePersistedIndexes(ref.id);
|
|
16809
|
+
indexPostingsPurged += idxPurge.purged;
|
|
16810
|
+
for (const field of idxPurge.residue) indexResidue.push(`${ref.collection}:${ref.id}:${field}`);
|
|
16377
16811
|
if (blobsEnabled) {
|
|
16378
16812
|
const r = await this.collection(ref.collection).blob(ref.id).shredAllForRecord();
|
|
16379
16813
|
blobsShredded += r.shredded.length;
|
|
@@ -16409,7 +16843,9 @@ var init_vault = __esm({
|
|
|
16409
16843
|
unmigratedCount: unmigratedRecords.length,
|
|
16410
16844
|
blobsShredded,
|
|
16411
16845
|
blobsRetainedShared,
|
|
16412
|
-
blobResidueCollections: [...blobResidueCollections]
|
|
16846
|
+
blobResidueCollections: [...blobResidueCollections],
|
|
16847
|
+
indexPostingsPurged,
|
|
16848
|
+
indexResidueCount: indexResidue.length
|
|
16413
16849
|
})
|
|
16414
16850
|
});
|
|
16415
16851
|
return {
|
|
@@ -16421,6 +16857,8 @@ var init_vault = __esm({
|
|
|
16421
16857
|
blobsShredded,
|
|
16422
16858
|
blobsRetainedShared,
|
|
16423
16859
|
blobResidueCollections: [...blobResidueCollections],
|
|
16860
|
+
indexPostingsPurged,
|
|
16861
|
+
indexResidue,
|
|
16424
16862
|
ledgerEntry
|
|
16425
16863
|
};
|
|
16426
16864
|
}
|
|
@@ -17683,6 +18121,8 @@ var init_vault = __esm({
|
|
|
17683
18121
|
*/
|
|
17684
18122
|
async *exportStream(opts = {}) {
|
|
17685
18123
|
const granularity = opts.granularity ?? "collection";
|
|
18124
|
+
const exportLocale = opts.resolveLabels;
|
|
18125
|
+
const localeOpts = exportLocale !== void 0 ? { locale: exportLocale, _layer: "export" } : void 0;
|
|
17686
18126
|
const snapshot = await this.adapter.loadAll(this.name);
|
|
17687
18127
|
const collectionNames = Object.keys(snapshot).sort();
|
|
17688
18128
|
const ledgerHead = opts.withLedgerHead ? await (async () => {
|
|
@@ -17692,19 +18132,21 @@ var init_vault = __esm({
|
|
|
17692
18132
|
return head ? { hash: head.hash, index: head.entry.index, ts: head.entry.ts } : void 0;
|
|
17693
18133
|
})() : void 0;
|
|
17694
18134
|
const dictSnapshotCache = /* @__PURE__ */ new Map();
|
|
17695
|
-
|
|
17696
|
-
const
|
|
17697
|
-
|
|
17698
|
-
|
|
17699
|
-
|
|
17700
|
-
const
|
|
17701
|
-
|
|
17702
|
-
|
|
17703
|
-
|
|
18135
|
+
if (exportLocale === void 0) {
|
|
18136
|
+
for (const collectionName of collectionNames) {
|
|
18137
|
+
const dictFields = this.dictKeyFieldRegistry.get(collectionName);
|
|
18138
|
+
if (dictFields && Object.keys(dictFields).length > 0) {
|
|
18139
|
+
const snap = {};
|
|
18140
|
+
for (const [fieldName, dictName] of Object.entries(dictFields)) {
|
|
18141
|
+
const entries = await this.dictionary(dictName).list();
|
|
18142
|
+
const keyMap = {};
|
|
18143
|
+
for (const entry of entries) {
|
|
18144
|
+
keyMap[entry.key] = entry.labels;
|
|
18145
|
+
}
|
|
18146
|
+
snap[fieldName] = keyMap;
|
|
17704
18147
|
}
|
|
17705
|
-
snap
|
|
18148
|
+
dictSnapshotCache.set(collectionName, snap);
|
|
17706
18149
|
}
|
|
17707
|
-
dictSnapshotCache.set(collectionName, snap);
|
|
17708
18150
|
}
|
|
17709
18151
|
}
|
|
17710
18152
|
for (const collectionName of collectionNames) {
|
|
@@ -17717,7 +18159,7 @@ var init_vault = __esm({
|
|
|
17717
18159
|
if (granularity === "collection") {
|
|
17718
18160
|
const records = [];
|
|
17719
18161
|
for (const id of ids) {
|
|
17720
|
-
const record = await coll.get(id);
|
|
18162
|
+
const record = await coll.get(id, localeOpts);
|
|
17721
18163
|
if (record !== null) records.push(record);
|
|
17722
18164
|
}
|
|
17723
18165
|
const chunk = {
|
|
@@ -17731,7 +18173,7 @@ var init_vault = __esm({
|
|
|
17731
18173
|
yield chunk;
|
|
17732
18174
|
} else {
|
|
17733
18175
|
for (const id of ids) {
|
|
17734
|
-
const record = await coll.get(id);
|
|
18176
|
+
const record = await coll.get(id, localeOpts);
|
|
17735
18177
|
if (record === null) continue;
|
|
17736
18178
|
const chunk = {
|
|
17737
18179
|
collection: collectionName,
|
|
@@ -17835,7 +18277,10 @@ var init_vault = __esm({
|
|
|
17835
18277
|
const allDictionaries = {};
|
|
17836
18278
|
for await (const chunk of this.exportStream({
|
|
17837
18279
|
granularity: "collection",
|
|
17838
|
-
withLedgerHead: opts.withLedgerHead === true
|
|
18280
|
+
withLedgerHead: opts.withLedgerHead === true,
|
|
18281
|
+
// #285 export layer: thread the export locale so records are read at the
|
|
18282
|
+
// `export` layer (i18nText collapsed + dictKey/staticDict labels resolved).
|
|
18283
|
+
...opts.resolveLabels !== void 0 ? { resolveLabels: opts.resolveLabels } : {}
|
|
17839
18284
|
})) {
|
|
17840
18285
|
collections[chunk.collection] = {
|
|
17841
18286
|
schema: null,
|
|
@@ -19690,13 +20135,21 @@ var init_vault_group = __esm({
|
|
|
19690
20135
|
* - row + vault present → no-op, return handle
|
|
19691
20136
|
* - row present, vault gone → ShardProvisioningError
|
|
19692
20137
|
* - row absent (vault present or not) → open-or-create, configure, write row
|
|
20138
|
+
*
|
|
20139
|
+
* When `region` is given (the routing `put` passes `sharding.regionOf(record)`),
|
|
20140
|
+
* the candidate backend's `capabilities.region` must match or this throws
|
|
20141
|
+
* `DataResidencyError` BEFORE provisioning (#271 data-residency guard).
|
|
19693
20142
|
*/
|
|
19694
|
-
async createShard(partitionKey) {
|
|
20143
|
+
async createShard(partitionKey, region) {
|
|
19695
20144
|
const vaultId = this.shardVaultId(partitionKey);
|
|
19696
20145
|
const row = await this.registry.get(this.registryId(partitionKey));
|
|
19697
20146
|
const provisioned = await this.db._shardVaultProvisioned(vaultId);
|
|
19698
20147
|
if (row && !provisioned) throw new ShardProvisioningError(vaultId, partitionKey);
|
|
19699
20148
|
if (row && provisioned) return this.openShard(partitionKey);
|
|
20149
|
+
if (region !== void 0) {
|
|
20150
|
+
const backendRegion = this.db._resolveBackend(vaultId).capabilities?.region;
|
|
20151
|
+
if (backendRegion !== region) throw new DataResidencyError(vaultId, region, backendRegion);
|
|
20152
|
+
}
|
|
19700
20153
|
const vault = await this.db.openVault(vaultId);
|
|
19701
20154
|
this.template.configure(vault);
|
|
19702
20155
|
await this.registry.put(this.registryId(partitionKey), {
|
|
@@ -19778,8 +20231,19 @@ var init_vault_group = __esm({
|
|
|
19778
20231
|
*
|
|
19779
20232
|
* v1 is explicit-refresh (no write-path push); call `refreshInsights()`
|
|
19780
20233
|
* after a batch of writes, or on a schedule.
|
|
20234
|
+
*
|
|
20235
|
+
* The `target.vault` must NOT be the group itself or one of its shards —
|
|
20236
|
+
* a summary writing back into client-shard data would breach the Insight
|
|
20237
|
+
* Vault's separate-DEK-boundary contract. Such a target throws a
|
|
20238
|
+
* `ValidationError` at registration (#271 Insight-write isolation).
|
|
19781
20239
|
*/
|
|
19782
20240
|
withCrossVaultDerivation(spec) {
|
|
20241
|
+
const target = spec.target.vault;
|
|
20242
|
+
if (target === this.name || target.startsWith(`${this.name}${SHARD_SEPARATOR}`)) {
|
|
20243
|
+
throw new ValidationError(
|
|
20244
|
+
`withCrossVaultDerivation: target.vault "${target}" is the "${this.name}" group itself or one of its shards \u2014 an Insight summary must target a SEPARATE analytics vault, never write back into client-shard data (it would breach the per-shard DEK boundary). Use a distinct vault name.`
|
|
20245
|
+
);
|
|
20246
|
+
}
|
|
19783
20247
|
this.crossVaultDerivations.push(spec);
|
|
19784
20248
|
}
|
|
19785
20249
|
/**
|
|
@@ -19928,7 +20392,7 @@ var init_vault_group = __esm({
|
|
|
19928
20392
|
if (this.group.sharding.autoCreate === false) {
|
|
19929
20393
|
throw new UnknownShardError(key, this.group.name);
|
|
19930
20394
|
}
|
|
19931
|
-
vault = await this.group.createShard(key);
|
|
20395
|
+
vault = await this.group.createShard(key, this.group.sharding.regionOf?.(record));
|
|
19932
20396
|
} else {
|
|
19933
20397
|
vault = await this.group.openShard(key);
|
|
19934
20398
|
}
|
|
@@ -21021,6 +21485,16 @@ var init_noydb = __esm({
|
|
|
21021
21485
|
async _shardVaultProvisioned(vaultId) {
|
|
21022
21486
|
return (await this.options.store.list(vaultId, "_keyring")).length > 0;
|
|
21023
21487
|
}
|
|
21488
|
+
/**
|
|
21489
|
+
* @internal — the physical backend store a vault id maps to. A
|
|
21490
|
+
* `routeStore` resolves the vault-prefix route via its `resolveBackend`;
|
|
21491
|
+
* a plain store is its own backend. Used by the federation data-residency
|
|
21492
|
+
* guard to read the placement backend's `capabilities.region` (#271).
|
|
21493
|
+
*/
|
|
21494
|
+
_resolveBackend(vaultId) {
|
|
21495
|
+
const store = this.options.store;
|
|
21496
|
+
return store.resolveBackend ? store.resolveBackend(vaultId) : this.options.store;
|
|
21497
|
+
}
|
|
21024
21498
|
/**
|
|
21025
21499
|
* Change the current user's passphrase for a vault.
|
|
21026
21500
|
*
|