@noy-db/hub 0.7.1-pre.0 → 0.8.0-pre.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +97 -14
- package/LICENSE +202 -21
- package/NOTICE +1 -0
- package/README.md +5 -5
- package/codemods/0.8.0-pre.json +61 -0
- package/dist/api-GVYEKSJE.js +19 -0
- package/dist/as/index.js +11 -11
- package/dist/at/index.js +9 -9
- package/dist/attestation/index.js +20 -20
- package/dist/{backup-XKCXVKV3.js → backup-7TFRVFLH.js} +12 -12
- package/dist/blobs/index.js +13 -13
- package/dist/broker/index.js +12 -12
- package/dist/by/index.js +2 -2
- package/dist/cargo/index.js +39 -36
- package/dist/{chunk-7O3Y4PPD.js → chunk-244VXYPG.js} +140 -16
- package/dist/chunk-244VXYPG.js.map +1 -0
- package/dist/{chunk-BUE2D7PX.js → chunk-32YV3TJT.js} +2 -2
- package/dist/{chunk-3PGS7TYR.js → chunk-3ELRMVJK.js} +12 -12
- package/dist/{chunk-OTQZ7ZWU.js → chunk-3F7GLNAE.js} +6 -6
- package/dist/{chunk-SGZAIJCV.js → chunk-3H5KLDZN.js} +4 -4
- package/dist/{chunk-VTFVLCUH.js → chunk-3JWHAR6E.js} +2 -2
- package/dist/{chunk-YMUFFJCO.js → chunk-3TDUWVWB.js} +5 -2
- package/dist/chunk-3TDUWVWB.js.map +1 -0
- package/dist/{chunk-JBDFMYKQ.js → chunk-4AF3TUMP.js} +2 -2
- package/dist/{chunk-ZORTV6NH.js → chunk-4I522ERM.js} +88 -4
- package/dist/chunk-4I522ERM.js.map +1 -0
- package/dist/{chunk-A66I4JOA.js → chunk-4MXI3ODD.js} +4 -4
- package/dist/chunk-4MXI3ODD.js.map +1 -0
- package/dist/{chunk-BLN54W3L.js → chunk-5FDLC6G7.js} +56 -3
- package/dist/chunk-5FDLC6G7.js.map +1 -0
- package/dist/chunk-5O7D6ZTW.js +53 -0
- package/dist/chunk-5O7D6ZTW.js.map +1 -0
- package/dist/{chunk-DFMWUOU5.js → chunk-6B3VNR4P.js} +12 -12
- package/dist/{chunk-TUFM4UZP.js → chunk-6K7DPM7D.js} +2 -2
- package/dist/{chunk-3VF3WQ4F.js → chunk-6LMQ5R26.js} +7 -7
- package/dist/{chunk-UP4BECPY.js → chunk-6LNL42F5.js} +94 -32
- package/dist/chunk-6LNL42F5.js.map +1 -0
- package/dist/{chunk-XLMEZIAJ.js → chunk-6OWXYZK2.js} +2 -2
- package/dist/{chunk-BRLKZUBT.js → chunk-6QSQQLSE.js} +3 -3
- package/dist/chunk-7JE7BDYJ.js +1558 -0
- package/dist/chunk-7JE7BDYJ.js.map +1 -0
- package/dist/{chunk-XKWGNJ26.js → chunk-7VCXZDA4.js} +5 -5
- package/dist/chunk-7VCXZDA4.js.map +1 -0
- package/dist/{chunk-NQKIUNW5.js → chunk-A6IJU4TK.js} +2 -2
- package/dist/{chunk-HIWCKBEY.js → chunk-ANWPSTZU.js} +38 -9
- package/dist/chunk-ANWPSTZU.js.map +1 -0
- package/dist/{chunk-QIZPZMUI.js → chunk-AOWGXU6D.js} +2 -2
- package/dist/{chunk-CUZLNGD5.js → chunk-B2YY6WDD.js} +1 -1
- package/dist/chunk-B2YY6WDD.js.map +1 -0
- package/dist/{chunk-SFAWCTEM.js → chunk-B57AFBY2.js} +2 -2
- package/dist/{chunk-UHHPLO3I.js → chunk-B6SJIBQK.js} +4 -4
- package/dist/chunk-BJ2IXQ5Q.js +100 -0
- package/dist/chunk-BJ2IXQ5Q.js.map +1 -0
- package/dist/{chunk-Q2PU57HC.js → chunk-BK2HHQGN.js} +2 -2
- package/dist/chunk-BKT776R5.js +1 -0
- package/dist/{chunk-FET5XCAT.js → chunk-BP6DARYA.js} +33 -5
- package/dist/chunk-BP6DARYA.js.map +1 -0
- package/dist/{chunk-YJX7EOJD.js → chunk-BUDAGWL5.js} +6 -6
- package/dist/chunk-CF5UU4S7.js +757 -0
- package/dist/chunk-CF5UU4S7.js.map +1 -0
- package/dist/{chunk-QPQUVOZ2.js → chunk-CKNGS5MH.js} +3 -3
- package/dist/chunk-CY2CYVWZ.js +41 -0
- package/dist/chunk-CY2CYVWZ.js.map +1 -0
- package/dist/{chunk-2577DKXB.js → chunk-DC5QVPV7.js} +2 -2
- package/dist/chunk-DC5QVPV7.js.map +1 -0
- package/dist/{chunk-BTDR2PXY.js → chunk-DE4DH2RZ.js} +2 -2
- package/dist/{chunk-Q2MPFCQ7.js → chunk-DF73H4UN.js} +4 -4
- package/dist/{chunk-4GVM6QZA.js → chunk-ENAG3IY7.js} +2 -2
- package/dist/chunk-ENAG3IY7.js.map +1 -0
- package/dist/{chunk-6LKOJBV6.js → chunk-EOVMT6TB.js} +2 -2
- package/dist/chunk-F24ZZTHQ.js +193 -0
- package/dist/chunk-F24ZZTHQ.js.map +1 -0
- package/dist/chunk-F2TDU7MQ.js +456 -0
- package/dist/chunk-F2TDU7MQ.js.map +1 -0
- package/dist/chunk-F6NCB7KT.js +13 -0
- package/dist/chunk-F6NCB7KT.js.map +1 -0
- package/dist/{chunk-SPYWXKJN.js → chunk-F7XGHL5O.js} +3 -3
- package/dist/chunk-F7XGHL5O.js.map +1 -0
- package/dist/{chunk-R42NSZI6.js → chunk-FCKWQE2H.js} +5 -5
- package/dist/{chunk-R7BX2NB3.js → chunk-FH2L2E34.js} +4 -4
- package/dist/chunk-FH2L2E34.js.map +1 -0
- package/dist/{chunk-4OZNXTO4.js → chunk-FN5EBVTQ.js} +2 -2
- package/dist/chunk-FQ54DWUQ.js +270 -0
- package/dist/chunk-FQ54DWUQ.js.map +1 -0
- package/dist/{chunk-P3MG6QCN.js → chunk-FQ5VRHIB.js} +4 -4
- package/dist/{chunk-FAHMLERK.js → chunk-FW22ZCXT.js} +2 -2
- package/dist/chunk-FXQBGFOX.js +524 -0
- package/dist/chunk-FXQBGFOX.js.map +1 -0
- package/dist/{chunk-7APJ6CO6.js → chunk-GF5BZ7D4.js} +45 -9
- package/dist/chunk-GF5BZ7D4.js.map +1 -0
- package/dist/{chunk-TRGTKX5E.js → chunk-GHLTDZRS.js} +5 -3
- package/dist/{chunk-TRGTKX5E.js.map → chunk-GHLTDZRS.js.map} +1 -1
- package/dist/{chunk-BVN6KXL2.js → chunk-HBPPGWUM.js} +5 -5
- package/dist/chunk-HBPPGWUM.js.map +1 -0
- package/dist/{chunk-KTFRCC5C.js → chunk-HBRLNOHL.js} +82 -8
- package/dist/chunk-HBRLNOHL.js.map +1 -0
- package/dist/chunk-HLEK5VAN.js +275 -0
- package/dist/chunk-HLEK5VAN.js.map +1 -0
- package/dist/{chunk-RMS3NEA3.js → chunk-HT2AHGQI.js} +2 -2
- package/dist/{chunk-2N5ML6HT.js → chunk-HVSCEIYL.js} +7 -7
- package/dist/{chunk-LH5A3ZPG.js → chunk-I3JDRCMW.js} +150 -22
- package/dist/chunk-I3JDRCMW.js.map +1 -0
- package/dist/{chunk-GY4WYNNG.js → chunk-ID6Z6E66.js} +2 -2
- package/dist/{chunk-YJRT5UQM.js → chunk-IEX7NK2K.js} +3 -3
- package/dist/{chunk-334WSVOW.js → chunk-ISZQJBML.js} +5 -5
- package/dist/{chunk-LWBCUYZW.js → chunk-IT22PWKV.js} +2 -2
- package/dist/{chunk-EQEYOJBM.js → chunk-IUWCVHQ7.js} +3 -3
- package/dist/chunk-IUWCVHQ7.js.map +1 -0
- package/dist/{chunk-RF6D3Y5E.js → chunk-J6UOHJY5.js} +4 -4
- package/dist/{chunk-JMGDHKQF.js → chunk-JCN44NCY.js} +2 -2
- package/dist/{chunk-3BZZJJMQ.js → chunk-K6W7BVZ6.js} +3 -3
- package/dist/{chunk-4ZS56W5S.js → chunk-KJFW62P4.js} +29 -11
- package/dist/chunk-KJFW62P4.js.map +1 -0
- package/dist/{chunk-453F654R.js → chunk-L7DOS3TE.js} +2 -2
- package/dist/chunk-LGNDFRYC.js +23 -0
- package/dist/chunk-LGNDFRYC.js.map +1 -0
- package/dist/{chunk-QTQUH4DS.js → chunk-LGRLME4M.js} +7 -7
- package/dist/{chunk-CHQCZZWC.js → chunk-LQ4ZHOKP.js} +2 -2
- package/dist/{chunk-GPNTB4Y7.js → chunk-M522UYZ2.js} +5 -5
- package/dist/{chunk-3V4KWFX7.js → chunk-M7NI3IWE.js} +45 -12
- package/dist/chunk-M7NI3IWE.js.map +1 -0
- package/dist/chunk-MDWKM2XC.js +293 -0
- package/dist/chunk-MDWKM2XC.js.map +1 -0
- package/dist/chunk-MKXXMNJH.js +204 -0
- package/dist/chunk-MKXXMNJH.js.map +1 -0
- package/dist/{chunk-SKGMN35F.js → chunk-MLPHLJIQ.js} +3 -3
- package/dist/chunk-MLPHLJIQ.js.map +1 -0
- package/dist/{chunk-UDHWDSRL.js → chunk-MTL7MXGR.js} +6 -6
- package/dist/{chunk-TFR7DSOV.js → chunk-MVZ2TPVP.js} +2 -2
- package/dist/{chunk-K23VKTN4.js → chunk-N5DNADLQ.js} +7 -7
- package/dist/{chunk-RSGLUIO6.js → chunk-NNARWO72.js} +6 -6
- package/dist/{chunk-2ENE6445.js → chunk-NRT6QZQB.js} +102 -16
- package/dist/chunk-NRT6QZQB.js.map +1 -0
- package/dist/{chunk-PPTHY5QO.js → chunk-NWHBJQAL.js} +99 -8
- package/dist/chunk-NWHBJQAL.js.map +1 -0
- package/dist/chunk-NYMLINRP.js +28 -0
- package/dist/chunk-NYMLINRP.js.map +1 -0
- package/dist/{chunk-7MG7SJT7.js → chunk-ODVPTDPK.js} +1 -1
- package/dist/chunk-ODVPTDPK.js.map +1 -0
- package/dist/chunk-ORDURZBU.js +461 -0
- package/dist/chunk-ORDURZBU.js.map +1 -0
- package/dist/{chunk-6YXCPL4T.js → chunk-PDCG6PR5.js} +2 -2
- package/dist/{chunk-ACAQ2DSG.js → chunk-PSIV7CJV.js} +2 -2
- package/dist/{chunk-KKEESNPE.js → chunk-QBBUZ3I3.js} +126 -19
- package/dist/chunk-QBBUZ3I3.js.map +1 -0
- package/dist/{chunk-5VCRVKOZ.js → chunk-QOOUUR4A.js} +6 -4
- package/dist/{chunk-5VCRVKOZ.js.map → chunk-QOOUUR4A.js.map} +1 -1
- package/dist/{chunk-G73UVHCA.js → chunk-QWFHIOD2.js} +5 -5
- package/dist/{chunk-AYX7AINO.js → chunk-QWGU66MP.js} +3 -3
- package/dist/chunk-RHVMZSUU.js +7 -0
- package/dist/chunk-RHVMZSUU.js.map +1 -0
- package/dist/{chunk-3BVH633C.js → chunk-S57HTZ6X.js} +5 -5
- package/dist/{chunk-SZJ3DLZA.js → chunk-SEE332EV.js} +2 -2
- package/dist/{chunk-YYP7WSEB.js → chunk-SI3V7D4G.js} +2 -2
- package/dist/{chunk-UGTBXF5U.js → chunk-SOIQ4MM4.js} +3 -3
- package/dist/chunk-SUZKW6UR.js +25 -0
- package/dist/chunk-SUZKW6UR.js.map +1 -0
- package/dist/{chunk-4GFX6MPA.js → chunk-SYVZW77S.js} +6 -6
- package/dist/{chunk-ZYIYHJ5R.js → chunk-T2LBQ5DV.js} +815 -222
- package/dist/chunk-T2LBQ5DV.js.map +1 -0
- package/dist/chunk-T52GX4SA.js +215 -0
- package/dist/chunk-T52GX4SA.js.map +1 -0
- package/dist/{chunk-MVMXZYXT.js → chunk-TKUOEU2F.js} +2 -2
- package/dist/chunk-TOPYQ6GA.js +31 -0
- package/dist/chunk-TOPYQ6GA.js.map +1 -0
- package/dist/{chunk-SMH6SRX7.js → chunk-TROR3ALR.js} +2 -2
- package/dist/{chunk-CUQPWYRX.js → chunk-UD5EVGZ7.js} +42 -389
- package/dist/chunk-UD5EVGZ7.js.map +1 -0
- package/dist/{chunk-M4YPHYEH.js → chunk-UPD5NWI5.js} +65 -17
- package/dist/chunk-UPD5NWI5.js.map +1 -0
- package/dist/{chunk-HPVZCW43.js → chunk-UYB234ZR.js} +2 -2
- package/dist/chunk-VHM7HCKB.js +220 -0
- package/dist/chunk-VHM7HCKB.js.map +1 -0
- package/dist/{chunk-DGOZ4UZD.js → chunk-VNNRUGMM.js} +2 -2
- package/dist/{chunk-F3W6YMDC.js → chunk-VNPEWFPD.js} +4 -4
- package/dist/{chunk-JVIBCBC7.js → chunk-WNJ4AVGE.js} +2 -2
- package/dist/{chunk-ZHKOPKE3.js → chunk-WX5ADGTZ.js} +3 -3
- package/dist/{chunk-VXANTWBJ.js → chunk-WY2XXTET.js} +92 -6
- package/dist/{chunk-VXANTWBJ.js.map → chunk-WY2XXTET.js.map} +1 -1
- package/dist/{chunk-HJUWN7JN.js → chunk-X25NWUZB.js} +33 -8
- package/dist/chunk-X25NWUZB.js.map +1 -0
- package/dist/{chunk-Q7HZX3IF.js → chunk-X4773RBR.js} +2 -2
- package/dist/chunk-XBKH4FOC.js +195 -0
- package/dist/chunk-XBKH4FOC.js.map +1 -0
- package/dist/{chunk-A2HKRLPV.js → chunk-YNIUIERI.js} +3 -3
- package/dist/chunk-YSK2CU2Q.js +936 -0
- package/dist/chunk-YSK2CU2Q.js.map +1 -0
- package/dist/{chunk-UXVWEX5L.js → chunk-Z5HTYMMQ.js} +6 -2
- package/dist/chunk-Z5HTYMMQ.js.map +1 -0
- package/dist/{chunk-WQBG4SZS.js → chunk-ZE4CHIED.js} +56 -34
- package/dist/chunk-ZE4CHIED.js.map +1 -0
- package/dist/chunk-ZSX4S5XB.js +1289 -0
- package/dist/chunk-ZSX4S5XB.js.map +1 -0
- package/dist/{chunk-BZ3534YM.js → chunk-ZUVBC32X.js} +2 -2
- package/dist/{chunk-V7ZRRCRJ.js → chunk-ZXABPVM6.js} +6 -6
- package/dist/classified/index.js +5 -5
- package/dist/{classified-marker-BWOFVYAC.js → classified-marker-W3USLL5M.js} +3 -3
- package/dist/collection-facade-QU6IJBN3.js +48 -0
- package/dist/{computed-VPOKQK4N.js → computed-TPFBX7U4.js} +3 -3
- package/dist/consent/index.js +9 -9
- package/dist/cover/index.js +10 -10
- package/dist/coverage/index.js +306 -0
- package/dist/coverage/index.js.map +1 -0
- package/dist/custody/index.js +12 -12
- package/dist/{dead-filter-PKQDLOT4.js → dead-filter-U2UYKSZL.js} +2 -2
- package/dist/debug/index.js +1 -1
- package/dist/{delegation-DS5NRILW.js → delegation-S3AEPW2T.js} +11 -11
- package/dist/derivations/index.js +25 -22
- package/dist/derive-OX7F6TGG.js +21 -0
- package/dist/directory/index.js +10 -10
- package/dist/{dispatch-IEPAVQUM.js → dispatch-3CQDJV5Q.js} +5 -5
- package/dist/{dispatch-Q6MWLOJY.js → dispatch-RH4LHKBH.js} +21 -21
- package/dist/{enclave-55PAM4YO.js → enclave-27SMF6GF.js} +9 -9
- package/dist/executor-B6SRO2QS.js +36 -0
- package/dist/executor-BI5CHWRY.js +8 -0
- package/dist/executor-RBKM5W5K.js +8 -0
- package/dist/export-accessible-VMA3YM5V.js +22 -0
- package/dist/extract-partition-NF7PXGPP.js +37 -0
- package/dist/{fanout-sidecar-S3QL53YX.js → fanout-sidecar-OT6RYLOL.js} +9 -9
- package/dist/find-LZMP26KF.js +10 -0
- package/dist/forget/index.js +9 -9
- package/dist/guards/index.js +4 -4
- package/dist/history/index.js +13 -13
- package/dist/i18n/index.js +14 -14
- package/dist/index.d.ts +28 -6
- package/dist/index.js +999 -191
- package/dist/index.js.map +1 -1
- package/dist/indexing/index.js +13 -5
- package/dist/indexing/index.js.map +1 -1
- package/dist/introspection/index.js +11 -11
- package/dist/issue-IHARXWW5.js +18 -0
- package/dist/ivf-flat-UZ6DQDLS.js +314 -0
- package/dist/ivf-flat-UZ6DQDLS.js.map +1 -0
- package/dist/{json-schema-V3M5MUCM.js → json-schema-3SHX72CC.js} +2 -1
- package/dist/json-schema-3SHX72CC.js.map +1 -0
- package/dist/kernel/collection-config.d.ts +4 -20
- package/dist/kernel/collection.d.ts +29 -8
- package/dist/kernel/enclave/record-keys/record-codec.d.ts +25 -0
- package/dist/kernel/errors.d.ts +227 -36
- package/dist/kernel/generation-map.d.ts +48 -0
- package/dist/kernel/noydb.d.ts +6 -1
- package/dist/kernel/present-cache.d.ts +58 -0
- package/dist/kernel/query/all.d.ts +7 -0
- package/dist/kernel/query/builder.d.ts +601 -270
- package/dist/kernel/query/civil-date.d.ts +64 -0
- package/dist/kernel/query/cursor.d.ts +40 -0
- package/dist/kernel/query/distinct-key.d.ts +98 -0
- package/dist/kernel/query/hydration.d.ts +76 -0
- package/dist/kernel/query/index.d.ts +31 -15
- package/dist/kernel/query/internal/core.d.ts +30 -0
- package/dist/kernel/query/internal/hooks.d.ts +22 -0
- package/dist/kernel/query/internal/maintenance.d.ts +43 -0
- package/dist/kernel/query/live/incremental.d.ts +314 -0
- package/dist/kernel/query/live/index.d.ts +22 -0
- package/dist/kernel/query/live/install.d.ts +2 -0
- package/dist/kernel/query/{live.d.ts → live/live.d.ts} +39 -9
- package/dist/kernel/query/live/methods.d.ts +107 -0
- package/dist/kernel/query/predicate.d.ts +119 -1
- package/dist/kernel/query/reduce/date-trunc.d.ts +75 -0
- package/dist/kernel/query/reduce/index.d.ts +36 -0
- package/dist/kernel/query/reduce/install.d.ts +2 -0
- package/dist/kernel/query/reduce/methods.d.ts +259 -0
- package/dist/kernel/query/reduce/scan-methods.d.ts +121 -0
- package/dist/kernel/query/relate/explain.d.ts +199 -0
- package/dist/kernel/query/relate/index.d.ts +48 -0
- package/dist/kernel/query/relate/install.d.ts +2 -0
- package/dist/kernel/query/relate/join-on.d.ts +126 -0
- package/dist/kernel/query/relate/join-reduce.d.ts +16 -0
- package/dist/kernel/query/relate/join.d.ts +452 -0
- package/dist/kernel/query/relate/methods.d.ts +426 -0
- package/dist/kernel/query/relate/partition.d.ts +87 -0
- package/dist/kernel/query/relate/scan-methods.d.ts +163 -0
- package/dist/kernel/query/relate/traverse.d.ts +109 -0
- package/dist/kernel/query/scan-builder.d.ts +79 -176
- package/dist/kernel/query/sort-key.d.ts +52 -0
- package/dist/kernel/tx-write-gate.d.ts +77 -0
- package/dist/kernel/types.d.ts +71 -3
- package/dist/kernel/validation.d.ts +27 -10
- package/dist/kernel/vault.d.ts +9 -4
- package/dist/kernel/via/compose.d.ts +3 -0
- package/dist/kernel/via/index.d.ts +56 -0
- package/dist/kernel/via/pipeline.d.ts +48 -0
- package/dist/{ledger-EDXFFZQL.js → ledger-KZPCMVZY.js} +11 -11
- package/dist/liberate-GRLCZMW4.js +24 -0
- package/dist/link-set-JCMJ7ULP.js +30 -0
- package/dist/{managed-secret-NCWEMPUQ.js → managed-secret-S3MQ6SH6.js} +10 -10
- package/dist/materialized-views/index.js +30 -23
- package/dist/{migrate-cek-5ENH64AA.js → migrate-cek-V7GKJZ7O.js} +2 -2
- package/dist/money/index.js +5 -5
- package/dist/noydb-SWQJ3MZS.js +97 -0
- package/dist/overlay-views/index.js +4 -4
- package/dist/periods/index.js +12 -12
- package/dist/pod/index.js +75 -68
- package/dist/{pod-handle-ECVCDIXW.js → pod-handle-WGDFB4C2.js} +9 -9
- package/dist/policy/index.js +10 -10
- package/dist/port/with/blob-strategy.d.ts +9 -0
- package/dist/port/with/collection-options.d.ts +5 -0
- package/dist/port/with/coverage-strategy.d.ts +83 -0
- package/dist/port/with/service-bus.d.ts +46 -0
- package/dist/port/with/strategies.d.ts +2 -0
- package/dist/portability/index.js +8 -8
- package/dist/{post-register-3IPCSG6Q.js → post-register-SLSXIPBV.js} +6 -6
- package/dist/query/all/index.js +31 -0
- package/dist/query/index.js +20 -32
- package/dist/query/live/index.js +21 -0
- package/dist/query/live/index.js.map +1 -0
- package/dist/query/reduce/index.js +33 -0
- package/dist/query/reduce/index.js.map +1 -0
- package/dist/query/relate/index.js +56 -0
- package/dist/query/relate/index.js.map +1 -0
- package/dist/reduce/index.js +72 -18
- package/dist/reduce/index.js.map +1 -1
- package/dist/register-F3OYE7MJ.js +31 -0
- package/dist/registry-CILQFXFK.js +8 -0
- package/dist/registry-XNNYQVKV.js +8 -0
- package/dist/registry-YCDZV3VW.js +35 -0
- package/dist/registry-ZGYS33TE.js +24 -0
- package/dist/request-withdrawal-Z5NC6TXT.js +30 -0
- package/dist/{reveal-QZDHSGD4.js → reveal-4BCKPEC2.js} +6 -6
- package/dist/revoke-ZL62WC2D.js +23 -0
- package/dist/satellites/index.js +1 -1
- package/dist/schema-update/index.js +2 -2
- package/dist/sealed-record/index.js +12 -12
- package/dist/search/index.js +11 -5
- package/dist/{seed-X5CC22CQ.js → seed-4JS2RJ4A.js} +12 -12
- package/dist/sequence/index.js +9 -9
- package/dist/session/index.js +9 -9
- package/dist/shadow/index.js +2 -2
- package/dist/signer-MBZZMXTC.js +24 -0
- package/dist/snapshots/index.js +10 -10
- package/dist/{stale-BZS6H2RY.js → stale-TJ3DYZMQ.js} +10 -10
- package/dist/storage-SVMKRGCW.js +22 -0
- package/dist/{store-coordination-provider-4WZAIRHC.js → store-coordination-provider-2O2VUHKW.js} +10 -10
- package/dist/sync/index.js +10 -10
- package/dist/team/index.js +17 -15
- package/dist/tiers/index.js +13 -11
- package/dist/to/index.js +2 -2
- package/dist/transactions/index.js +3 -3
- package/dist/util/index.js +1 -1
- package/dist/vault-head/index.js +8 -8
- package/dist/{verify-6MDTIUEV.js → verify-RVT67IMH.js} +5 -5
- package/dist/via/blob/index.d.ts +1 -0
- package/dist/via/geo/binding.d.ts +31 -0
- package/dist/via/geo/descriptor.d.ts +54 -0
- package/dist/via/geo/geohash.d.ts +95 -0
- package/dist/via/geo/index.d.ts +13 -0
- package/dist/via/geo/where.d.ts +50 -0
- package/dist/via/i18n/core.d.ts +1 -1
- package/dist/via/lookup/registry.d.ts +1 -1
- package/dist/via/lookup/snapshot.d.ts +3 -3
- package/dist/walk-HJ42EISE.js +21 -0
- package/dist/walk-HJ42EISE.js.map +1 -0
- package/dist/with-audit/coverage/accounting.d.ts +112 -0
- package/dist/with-audit/coverage/active.d.ts +29 -0
- package/dist/with-audit/coverage/index.d.ts +61 -0
- package/dist/with-audit/coverage/sketch.d.ts +75 -0
- package/dist/with-audit/periods/periods.d.ts +55 -7
- package/dist/with-audit/periods/reserved-collections.d.ts +3 -0
- package/dist/with-audit/periods/vault-facade.d.ts +17 -0
- package/dist/with-audit/tiers/index.d.ts +51 -0
- package/dist/with-audit/tiers/strategy.d.ts +8 -0
- package/dist/with-cargo/floor.d.ts +2 -2
- package/dist/with-commit/tx/invariants.d.ts +1 -1
- package/dist/with-commit/tx/transaction.d.ts +13 -3
- package/dist/with-formula/materialized-views/dependency-analyzer.d.ts +4 -3
- package/dist/with-formula/materialized-views/emit-memo.d.ts +40 -0
- package/dist/with-formula/materialized-views/executor.d.ts +8 -0
- package/dist/with-formula/materialized-views/index.d.ts +1 -1
- package/dist/with-formula/materialized-views/registry.d.ts +15 -0
- package/dist/with-formula/materialized-views/types.d.ts +106 -14
- package/dist/with-formula/materialized-views/window-stage.d.ts +11 -0
- package/dist/with-formula/overlay-views/types.d.ts +1 -1
- package/dist/with-formula/overlay-views/virtual-collection.d.ts +13 -4
- package/dist/with-lookup/embeddings/chunks.d.ts +79 -0
- package/dist/with-lookup/embeddings/descriptor.d.ts +21 -0
- package/dist/with-lookup/embeddings/index.d.ts +3 -0
- package/dist/with-lookup/embeddings/ivf-flat.d.ts +93 -0
- package/dist/with-lookup/embeddings/vector-index.d.ts +73 -0
- package/dist/with-lookup/embeddings/vector-set.d.ts +94 -1
- package/dist/with-lookup/embeddings/with-vector-index.d.ts +67 -0
- package/dist/with-lookup/indexing/collection-facade.d.ts +85 -2
- package/dist/with-lookup/indexing/compound-indexes.d.ts +129 -0
- package/dist/with-lookup/indexing/eager-indexes.d.ts +170 -1
- package/dist/with-lookup/indexing/index-snapshot.d.ts +62 -0
- package/dist/with-lookup/indexing/lazy-builder.d.ts +33 -0
- package/dist/with-lookup/indexing/persisted-field-indexes.d.ts +104 -0
- package/dist/with-lookup/indexing/persisted-indexes.d.ts +12 -0
- package/dist/with-lookup/indexing/sorted-indexes.d.ts +117 -0
- package/dist/with-lookup/indexing/unique-constraints.d.ts +106 -23
- package/dist/with-lookup/reduce/active.d.ts +2 -24
- package/dist/with-lookup/reduce/group-core.d.ts +43 -0
- package/dist/with-lookup/reduce/groupby.d.ts +195 -36
- package/dist/with-lookup/reduce/incremental-group.d.ts +153 -0
- package/dist/with-lookup/reduce/index.d.ts +26 -5
- package/dist/with-lookup/reduce/reducers.d.ts +255 -1
- package/dist/with-lookup/reduce/reduction.d.ts +44 -13
- package/dist/with-lookup/reduce/strategy.d.ts +43 -3
- package/dist/with-lookup/reduce/window.d.ts +262 -0
- package/dist/with-lookup/search/collection-facade.d.ts +44 -8
- package/dist/with-lookup/search/index-store.d.ts +5 -3
- package/dist/with-lookup/search/index.d.ts +4 -2
- package/dist/with-lookup/search/inverted-index.d.ts +38 -2
- package/dist/with-lookup/search/persisted-index-store.d.ts +5 -2
- package/dist/with-lookup/search/phrase.d.ts +28 -0
- package/dist/with-lookup/search/retrieve-types.d.ts +57 -1
- package/dist/with-lookup/search/serialize.d.ts +29 -3
- package/dist/with-lookup/search/strategy.d.ts +2 -6
- package/dist/with-party/directory/cover/index.d.ts +1 -1
- package/dist/with-party/directory/cover/storage.d.ts +1 -1
- package/dist/with-party/directory/cover/types.d.ts +1 -1
- package/dist/with-party/directory/index.d.ts +1 -1
- package/dist/with-party/directory/types.d.ts +1 -1
- package/dist/with-party/directory/user-envelope/api.d.ts +1 -1
- package/dist/with-party/policy/engine.d.ts +1 -1
- package/dist/with-party/policy/index.d.ts +1 -1
- package/dist/with-party/policy/presets.d.ts +1 -1
- package/dist/with-party/team/authenticators.d.ts +91 -1
- package/dist/with-party/team/index.d.ts +3 -2
- package/dist/with-party/team/keyring.d.ts +1 -1
- package/dist/with-party/team/managed-secret.d.ts +1 -1
- package/dist/with-party/team/noydb-facade.d.ts +12 -3
- package/dist/with-pod/format.d.ts +1 -1
- package/dist/with-pod/pod.d.ts +1 -1
- package/dist/with-shape/blobs/blob-compaction.d.ts +16 -0
- package/dist/with-shape/blobs/blob-set.d.ts +21 -2
- package/dist/with-shape/blobs/legacy-sweep.d.ts +35 -0
- package/dist/with-shape/introspection/describe.d.ts +6 -0
- package/dist/with-shape/introspection/field-meta.d.ts +18 -0
- package/dist/with-shape/introspection/types.d.ts +57 -1
- package/dist/with-shape/links/vault-facade.d.ts +1 -1
- package/dist/with-store/partitioned/index.d.ts +337 -0
- package/dist/with-sync/change-broadcast.d.ts +153 -0
- package/dist/withdraw-accessible-5NZUPAVA.js +27 -0
- package/dist/withdraw-accessible-5NZUPAVA.js.map +1 -0
- package/package.json +37 -10
- package/dist/api-WYW4YEQG.js +0 -19
- package/dist/chunk-2577DKXB.js.map +0 -1
- package/dist/chunk-2ENE6445.js.map +0 -1
- package/dist/chunk-3V4KWFX7.js.map +0 -1
- package/dist/chunk-4GVM6QZA.js.map +0 -1
- package/dist/chunk-4ZS56W5S.js.map +0 -1
- package/dist/chunk-7APJ6CO6.js.map +0 -1
- package/dist/chunk-7MG2LHO5.js +0 -1616
- package/dist/chunk-7MG2LHO5.js.map +0 -1
- package/dist/chunk-7MG7SJT7.js.map +0 -1
- package/dist/chunk-7O3Y4PPD.js.map +0 -1
- package/dist/chunk-A66I4JOA.js.map +0 -1
- package/dist/chunk-ATL3ZVXT.js +0 -151
- package/dist/chunk-ATL3ZVXT.js.map +0 -1
- package/dist/chunk-BLN54W3L.js.map +0 -1
- package/dist/chunk-BVN6KXL2.js.map +0 -1
- package/dist/chunk-CUQPWYRX.js.map +0 -1
- package/dist/chunk-CUZLNGD5.js.map +0 -1
- package/dist/chunk-EQEYOJBM.js.map +0 -1
- package/dist/chunk-FET5XCAT.js.map +0 -1
- package/dist/chunk-HIWCKBEY.js.map +0 -1
- package/dist/chunk-HJUWN7JN.js.map +0 -1
- package/dist/chunk-I3ISCYT7.js +0 -159
- package/dist/chunk-I3ISCYT7.js.map +0 -1
- package/dist/chunk-KKEESNPE.js.map +0 -1
- package/dist/chunk-KTFRCC5C.js.map +0 -1
- package/dist/chunk-LH5A3ZPG.js.map +0 -1
- package/dist/chunk-M4YPHYEH.js.map +0 -1
- package/dist/chunk-NSITFOCJ.js +0 -99
- package/dist/chunk-NSITFOCJ.js.map +0 -1
- package/dist/chunk-PPTHY5QO.js.map +0 -1
- package/dist/chunk-R7BX2NB3.js.map +0 -1
- package/dist/chunk-RTBJ5IOO.js +0 -87
- package/dist/chunk-RTBJ5IOO.js.map +0 -1
- package/dist/chunk-SKGMN35F.js.map +0 -1
- package/dist/chunk-SPYWXKJN.js.map +0 -1
- package/dist/chunk-UP4BECPY.js.map +0 -1
- package/dist/chunk-UXVWEX5L.js.map +0 -1
- package/dist/chunk-WQBG4SZS.js.map +0 -1
- package/dist/chunk-XKWGNJ26.js.map +0 -1
- package/dist/chunk-YMUFFJCO.js.map +0 -1
- package/dist/chunk-ZN4FD4PE.js +0 -364
- package/dist/chunk-ZN4FD4PE.js.map +0 -1
- package/dist/chunk-ZORTV6NH.js.map +0 -1
- package/dist/chunk-ZYIYHJ5R.js.map +0 -1
- package/dist/collection-facade-JSJYIKS4.js +0 -45
- package/dist/derive-E642AOUB.js +0 -21
- package/dist/executor-5NIMLSKZ.js +0 -8
- package/dist/executor-7UQ3BZ4F.js +0 -29
- package/dist/executor-AQVXV5GZ.js +0 -8
- package/dist/export-accessible-ORMKLA3E.js +0 -22
- package/dist/extract-partition-NKYO3WNG.js +0 -37
- package/dist/find-NOGJ25VX.js +0 -10
- package/dist/issue-3DTQ7VJJ.js +0 -18
- package/dist/json-schema-V3M5MUCM.js.map +0 -1
- package/dist/kernel/query/join.d.ts +0 -232
- package/dist/liberate-V35QUHJP.js +0 -24
- package/dist/link-set-2TTM3IZC.js +0 -30
- package/dist/noydb-62MX4QUG.js +0 -90
- package/dist/register-HHLXEQDN.js +0 -31
- package/dist/registry-23WF3TGH.js +0 -8
- package/dist/registry-4AYVUNXK.js +0 -8
- package/dist/registry-JS3YFQQM.js +0 -18
- package/dist/registry-XX2Z7B46.js +0 -32
- package/dist/request-withdrawal-CHPATE4G.js +0 -30
- package/dist/revoke-7M2VW4ON.js +0 -23
- package/dist/signer-SJQJVSM6.js +0 -24
- package/dist/storage-RW4QBS23.js +0 -22
- package/dist/walk-ZURCH6RZ.js +0 -21
- package/dist/withdraw-accessible-PXR4IXDX.js +0 -27
- /package/dist/{api-WYW4YEQG.js.map → api-GVYEKSJE.js.map} +0 -0
- /package/dist/{backup-XKCXVKV3.js.map → backup-7TFRVFLH.js.map} +0 -0
- /package/dist/{chunk-BUE2D7PX.js.map → chunk-32YV3TJT.js.map} +0 -0
- /package/dist/{chunk-3PGS7TYR.js.map → chunk-3ELRMVJK.js.map} +0 -0
- /package/dist/{chunk-OTQZ7ZWU.js.map → chunk-3F7GLNAE.js.map} +0 -0
- /package/dist/{chunk-SGZAIJCV.js.map → chunk-3H5KLDZN.js.map} +0 -0
- /package/dist/{chunk-VTFVLCUH.js.map → chunk-3JWHAR6E.js.map} +0 -0
- /package/dist/{chunk-JBDFMYKQ.js.map → chunk-4AF3TUMP.js.map} +0 -0
- /package/dist/{chunk-DFMWUOU5.js.map → chunk-6B3VNR4P.js.map} +0 -0
- /package/dist/{chunk-TUFM4UZP.js.map → chunk-6K7DPM7D.js.map} +0 -0
- /package/dist/{chunk-3VF3WQ4F.js.map → chunk-6LMQ5R26.js.map} +0 -0
- /package/dist/{chunk-XLMEZIAJ.js.map → chunk-6OWXYZK2.js.map} +0 -0
- /package/dist/{chunk-BRLKZUBT.js.map → chunk-6QSQQLSE.js.map} +0 -0
- /package/dist/{chunk-NQKIUNW5.js.map → chunk-A6IJU4TK.js.map} +0 -0
- /package/dist/{chunk-QIZPZMUI.js.map → chunk-AOWGXU6D.js.map} +0 -0
- /package/dist/{chunk-SFAWCTEM.js.map → chunk-B57AFBY2.js.map} +0 -0
- /package/dist/{chunk-UHHPLO3I.js.map → chunk-B6SJIBQK.js.map} +0 -0
- /package/dist/{chunk-Q2PU57HC.js.map → chunk-BK2HHQGN.js.map} +0 -0
- /package/dist/{collection-facade-JSJYIKS4.js.map → chunk-BKT776R5.js.map} +0 -0
- /package/dist/{chunk-YJX7EOJD.js.map → chunk-BUDAGWL5.js.map} +0 -0
- /package/dist/{chunk-QPQUVOZ2.js.map → chunk-CKNGS5MH.js.map} +0 -0
- /package/dist/{chunk-BTDR2PXY.js.map → chunk-DE4DH2RZ.js.map} +0 -0
- /package/dist/{chunk-Q2MPFCQ7.js.map → chunk-DF73H4UN.js.map} +0 -0
- /package/dist/{chunk-6LKOJBV6.js.map → chunk-EOVMT6TB.js.map} +0 -0
- /package/dist/{chunk-R42NSZI6.js.map → chunk-FCKWQE2H.js.map} +0 -0
- /package/dist/{chunk-4OZNXTO4.js.map → chunk-FN5EBVTQ.js.map} +0 -0
- /package/dist/{chunk-P3MG6QCN.js.map → chunk-FQ5VRHIB.js.map} +0 -0
- /package/dist/{chunk-FAHMLERK.js.map → chunk-FW22ZCXT.js.map} +0 -0
- /package/dist/{chunk-RMS3NEA3.js.map → chunk-HT2AHGQI.js.map} +0 -0
- /package/dist/{chunk-2N5ML6HT.js.map → chunk-HVSCEIYL.js.map} +0 -0
- /package/dist/{chunk-GY4WYNNG.js.map → chunk-ID6Z6E66.js.map} +0 -0
- /package/dist/{chunk-YJRT5UQM.js.map → chunk-IEX7NK2K.js.map} +0 -0
- /package/dist/{chunk-334WSVOW.js.map → chunk-ISZQJBML.js.map} +0 -0
- /package/dist/{chunk-LWBCUYZW.js.map → chunk-IT22PWKV.js.map} +0 -0
- /package/dist/{chunk-RF6D3Y5E.js.map → chunk-J6UOHJY5.js.map} +0 -0
- /package/dist/{chunk-JMGDHKQF.js.map → chunk-JCN44NCY.js.map} +0 -0
- /package/dist/{chunk-3BZZJJMQ.js.map → chunk-K6W7BVZ6.js.map} +0 -0
- /package/dist/{chunk-453F654R.js.map → chunk-L7DOS3TE.js.map} +0 -0
- /package/dist/{chunk-QTQUH4DS.js.map → chunk-LGRLME4M.js.map} +0 -0
- /package/dist/{chunk-CHQCZZWC.js.map → chunk-LQ4ZHOKP.js.map} +0 -0
- /package/dist/{chunk-GPNTB4Y7.js.map → chunk-M522UYZ2.js.map} +0 -0
- /package/dist/{chunk-UDHWDSRL.js.map → chunk-MTL7MXGR.js.map} +0 -0
- /package/dist/{chunk-TFR7DSOV.js.map → chunk-MVZ2TPVP.js.map} +0 -0
- /package/dist/{chunk-K23VKTN4.js.map → chunk-N5DNADLQ.js.map} +0 -0
- /package/dist/{chunk-RSGLUIO6.js.map → chunk-NNARWO72.js.map} +0 -0
- /package/dist/{chunk-6YXCPL4T.js.map → chunk-PDCG6PR5.js.map} +0 -0
- /package/dist/{chunk-ACAQ2DSG.js.map → chunk-PSIV7CJV.js.map} +0 -0
- /package/dist/{chunk-G73UVHCA.js.map → chunk-QWFHIOD2.js.map} +0 -0
- /package/dist/{chunk-AYX7AINO.js.map → chunk-QWGU66MP.js.map} +0 -0
- /package/dist/{chunk-3BVH633C.js.map → chunk-S57HTZ6X.js.map} +0 -0
- /package/dist/{chunk-SZJ3DLZA.js.map → chunk-SEE332EV.js.map} +0 -0
- /package/dist/{chunk-YYP7WSEB.js.map → chunk-SI3V7D4G.js.map} +0 -0
- /package/dist/{chunk-UGTBXF5U.js.map → chunk-SOIQ4MM4.js.map} +0 -0
- /package/dist/{chunk-4GFX6MPA.js.map → chunk-SYVZW77S.js.map} +0 -0
- /package/dist/{chunk-MVMXZYXT.js.map → chunk-TKUOEU2F.js.map} +0 -0
- /package/dist/{chunk-SMH6SRX7.js.map → chunk-TROR3ALR.js.map} +0 -0
- /package/dist/{chunk-HPVZCW43.js.map → chunk-UYB234ZR.js.map} +0 -0
- /package/dist/{chunk-DGOZ4UZD.js.map → chunk-VNNRUGMM.js.map} +0 -0
- /package/dist/{chunk-F3W6YMDC.js.map → chunk-VNPEWFPD.js.map} +0 -0
- /package/dist/{chunk-JVIBCBC7.js.map → chunk-WNJ4AVGE.js.map} +0 -0
- /package/dist/{chunk-ZHKOPKE3.js.map → chunk-WX5ADGTZ.js.map} +0 -0
- /package/dist/{chunk-Q7HZX3IF.js.map → chunk-X4773RBR.js.map} +0 -0
- /package/dist/{chunk-A2HKRLPV.js.map → chunk-YNIUIERI.js.map} +0 -0
- /package/dist/{chunk-BZ3534YM.js.map → chunk-ZUVBC32X.js.map} +0 -0
- /package/dist/{chunk-V7ZRRCRJ.js.map → chunk-ZXABPVM6.js.map} +0 -0
- /package/dist/{classified-marker-BWOFVYAC.js.map → classified-marker-W3USLL5M.js.map} +0 -0
- /package/dist/{computed-VPOKQK4N.js.map → collection-facade-QU6IJBN3.js.map} +0 -0
- /package/dist/{derive-E642AOUB.js.map → computed-TPFBX7U4.js.map} +0 -0
- /package/dist/{dead-filter-PKQDLOT4.js.map → dead-filter-U2UYKSZL.js.map} +0 -0
- /package/dist/{delegation-DS5NRILW.js.map → delegation-S3AEPW2T.js.map} +0 -0
- /package/dist/{enclave-55PAM4YO.js.map → derive-OX7F6TGG.js.map} +0 -0
- /package/dist/{dispatch-IEPAVQUM.js.map → dispatch-3CQDJV5Q.js.map} +0 -0
- /package/dist/{dispatch-Q6MWLOJY.js.map → dispatch-RH4LHKBH.js.map} +0 -0
- /package/dist/{executor-5NIMLSKZ.js.map → enclave-27SMF6GF.js.map} +0 -0
- /package/dist/{executor-7UQ3BZ4F.js.map → executor-B6SRO2QS.js.map} +0 -0
- /package/dist/{executor-AQVXV5GZ.js.map → executor-BI5CHWRY.js.map} +0 -0
- /package/dist/{export-accessible-ORMKLA3E.js.map → executor-RBKM5W5K.js.map} +0 -0
- /package/dist/{extract-partition-NKYO3WNG.js.map → export-accessible-VMA3YM5V.js.map} +0 -0
- /package/dist/{find-NOGJ25VX.js.map → extract-partition-NF7PXGPP.js.map} +0 -0
- /package/dist/{fanout-sidecar-S3QL53YX.js.map → fanout-sidecar-OT6RYLOL.js.map} +0 -0
- /package/dist/{issue-3DTQ7VJJ.js.map → find-LZMP26KF.js.map} +0 -0
- /package/dist/{ledger-EDXFFZQL.js.map → issue-IHARXWW5.js.map} +0 -0
- /package/dist/{liberate-V35QUHJP.js.map → ledger-KZPCMVZY.js.map} +0 -0
- /package/dist/{link-set-2TTM3IZC.js.map → liberate-GRLCZMW4.js.map} +0 -0
- /package/dist/{managed-secret-NCWEMPUQ.js.map → link-set-JCMJ7ULP.js.map} +0 -0
- /package/dist/{noydb-62MX4QUG.js.map → managed-secret-S3MQ6SH6.js.map} +0 -0
- /package/dist/{migrate-cek-5ENH64AA.js.map → migrate-cek-V7GKJZ7O.js.map} +0 -0
- /package/dist/{register-HHLXEQDN.js.map → noydb-SWQJ3MZS.js.map} +0 -0
- /package/dist/{pod-handle-ECVCDIXW.js.map → pod-handle-WGDFB4C2.js.map} +0 -0
- /package/dist/{post-register-3IPCSG6Q.js.map → post-register-SLSXIPBV.js.map} +0 -0
- /package/dist/{registry-23WF3TGH.js.map → query/all/index.js.map} +0 -0
- /package/dist/{registry-4AYVUNXK.js.map → register-F3OYE7MJ.js.map} +0 -0
- /package/dist/{registry-JS3YFQQM.js.map → registry-CILQFXFK.js.map} +0 -0
- /package/dist/{registry-XX2Z7B46.js.map → registry-XNNYQVKV.js.map} +0 -0
- /package/dist/{request-withdrawal-CHPATE4G.js.map → registry-YCDZV3VW.js.map} +0 -0
- /package/dist/{revoke-7M2VW4ON.js.map → registry-ZGYS33TE.js.map} +0 -0
- /package/dist/{signer-SJQJVSM6.js.map → request-withdrawal-Z5NC6TXT.js.map} +0 -0
- /package/dist/{reveal-QZDHSGD4.js.map → reveal-4BCKPEC2.js.map} +0 -0
- /package/dist/{stale-BZS6H2RY.js.map → revoke-ZL62WC2D.js.map} +0 -0
- /package/dist/{seed-X5CC22CQ.js.map → seed-4JS2RJ4A.js.map} +0 -0
- /package/dist/{storage-RW4QBS23.js.map → signer-MBZZMXTC.js.map} +0 -0
- /package/dist/{walk-ZURCH6RZ.js.map → stale-TJ3DYZMQ.js.map} +0 -0
- /package/dist/{withdraw-accessible-PXR4IXDX.js.map → storage-SVMKRGCW.js.map} +0 -0
- /package/dist/{store-coordination-provider-4WZAIRHC.js.map → store-coordination-provider-2O2VUHKW.js.map} +0 -0
- /package/dist/{verify-6MDTIUEV.js.map → verify-RVT67IMH.js.map} +0 -0
package/dist/chunk-RTBJ5IOO.js
DELETED
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
getAtPath
|
|
3
|
-
} from "./chunk-TRGTKX5E.js";
|
|
4
|
-
import {
|
|
5
|
-
EmbeddingModelMismatchError
|
|
6
|
-
} from "./chunk-7O3Y4PPD.js";
|
|
7
|
-
|
|
8
|
-
// src/with-lookup/embeddings/descriptor.ts
|
|
9
|
-
function embeddingSourceText(record, source) {
|
|
10
|
-
const fields = typeof source === "string" ? [source] : source;
|
|
11
|
-
const parts = [];
|
|
12
|
-
for (const f of fields) {
|
|
13
|
-
for (const leaf of getAtPath(record, f)) {
|
|
14
|
-
if (typeof leaf === "string" && leaf !== "") parts.push(leaf);
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
return parts.join(" ");
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
// src/with-lookup/embeddings/vec-id.ts
|
|
21
|
-
function encodeVecId(collection, recordId) {
|
|
22
|
-
if (collection.includes("/")) {
|
|
23
|
-
throw new Error(
|
|
24
|
-
`encodeVecId: collection name "${collection}" must not contain "/" \u2014 it would make the "${collection}/${recordId}" _vec id ambiguous against another collection's rows.`
|
|
25
|
-
);
|
|
26
|
-
}
|
|
27
|
-
return `${collection}/${recordId}`;
|
|
28
|
-
}
|
|
29
|
-
function decodeVecId(collection, vecId) {
|
|
30
|
-
const prefix = `${collection}/`;
|
|
31
|
-
if (!vecId.startsWith(prefix)) return null;
|
|
32
|
-
return vecId.slice(prefix.length);
|
|
33
|
-
}
|
|
34
|
-
function isVecIdFor(collection, vecId) {
|
|
35
|
-
return vecId.startsWith(`${collection}/`);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
// src/with-lookup/embeddings/cosine.ts
|
|
39
|
-
function cosine(a, b) {
|
|
40
|
-
if (a.length !== b.length) return 0;
|
|
41
|
-
let dot = 0, na = 0, nb = 0;
|
|
42
|
-
for (let i = 0; i < a.length; i++) {
|
|
43
|
-
const x = a[i], y = b[i];
|
|
44
|
-
dot += x * y;
|
|
45
|
-
na += x * x;
|
|
46
|
-
nb += y * y;
|
|
47
|
-
}
|
|
48
|
-
if (na === 0 || nb === 0) return 0;
|
|
49
|
-
return dot / (Math.sqrt(na) * Math.sqrt(nb));
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
// src/with-lookup/embeddings/vector-set.ts
|
|
53
|
-
var VectorSet = class {
|
|
54
|
-
vectors;
|
|
55
|
-
get loaded() {
|
|
56
|
-
return this.vectors !== void 0;
|
|
57
|
-
}
|
|
58
|
-
async ensureLoaded(load) {
|
|
59
|
-
if (this.vectors === void 0) this.vectors = await load();
|
|
60
|
-
}
|
|
61
|
-
markDirty() {
|
|
62
|
-
this.vectors = void 0;
|
|
63
|
-
}
|
|
64
|
-
cosineTopK(query, k, opts = {}) {
|
|
65
|
-
const all = this.vectors ?? [];
|
|
66
|
-
const minScore = opts.minScore ?? -Infinity;
|
|
67
|
-
const hits = [];
|
|
68
|
-
for (const v of all) {
|
|
69
|
-
if (opts.expectModel !== void 0 && v.model !== opts.expectModel) {
|
|
70
|
-
throw new EmbeddingModelMismatchError(opts.expectModel, v.model);
|
|
71
|
-
}
|
|
72
|
-
const score = cosine(query, v.vec);
|
|
73
|
-
if (score >= minScore) hits.push({ id: v.id, score });
|
|
74
|
-
}
|
|
75
|
-
hits.sort((a, b) => b.score - a.score);
|
|
76
|
-
return hits.slice(0, k);
|
|
77
|
-
}
|
|
78
|
-
};
|
|
79
|
-
|
|
80
|
-
export {
|
|
81
|
-
embeddingSourceText,
|
|
82
|
-
VectorSet,
|
|
83
|
-
encodeVecId,
|
|
84
|
-
decodeVecId,
|
|
85
|
-
isVecIdFor
|
|
86
|
-
};
|
|
87
|
-
//# sourceMappingURL=chunk-RTBJ5IOO.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/with-lookup/embeddings/descriptor.ts","../src/with-lookup/embeddings/vec-id.ts","../src/with-lookup/embeddings/cosine.ts","../src/with-lookup/embeddings/vector-set.ts"],"sourcesContent":["/** Per-collection embedding config (L2). The encode hook is host/remote — no bundled model. */\nimport { getAtPath } from '../../via/i18n/core.js'\n\nexport interface EmbeddingDescriptor {\n readonly source: string | readonly string[]\n readonly encode: (text: string) => Promise<Float32Array>\n readonly dim: number\n readonly model: string\n}\n\n/** Concatenate the record's source-field text (skips empties; supports nested/[]-wildcard paths). */\nexport function embeddingSourceText(record: Record<string, unknown>, source: string | readonly string[]): string {\n const fields = typeof source === 'string' ? [source] : source\n const parts: string[] = []\n for (const f of fields) {\n for (const leaf of getAtPath(record, f)) {\n if (typeof leaf === 'string' && leaf !== '') parts.push(leaf)\n }\n }\n return parts.join(' ')\n}\n","/**\n * Collection-namespaced `_vec` side-car ids (#726).\n *\n * `_vec` embedding side-cars used to be keyed by the bare record id,\n * vault-wide — two collections sharing a record id shared one `_vec` row.\n * This was verified to be a clobber/crash bug, NOT a confidentiality leak:\n * every collection has its own DEK, and AES-GCM auth-tag verification means\n * decrypting a foreign collection's `_vec` row under the wrong DEK throws\n * `TamperedError` rather than returning wrong plaintext — no disclosure\n * mechanism exists. The real bug was id collision: a same-id write/forget in\n * one collection could clobber or delete the other collection's row, and a\n * collection whose `similarTo()` / cold semantic `retrieve()` encountered a\n * foreign same-id row crashed with an uncaught `TamperedError` (a DoS). The\n * store-collection bucket stays the literal `'_vec'`; the id becomes\n * composite: `${collection}/${recordId}`. Mirrors `encodeIdxId`\n * (`../indexing/persisted-indexes.js`).\n *\n * Decode is deliberately NOT split-on-`/`: the collection is always known\n * at the decode site (`ctx.name`), so `decodeVecId` strips that known\n * prefix — correct even when `recordId` itself contains `/`.\n *\n * Precondition: `collection` itself must not contain `/` — otherwise\n * `${collection}/${recordId}` is ambiguous (e.g. collection `'a'` would\n * misattribute collection `'a/b'`'s rows via prefix match in `isVecIdFor`).\n * Collection names are NOT currently restricted to a `/`-free charset by\n * `vault.collection()`, so `encodeVecId` enforces the precondition itself,\n * failing loud at the write boundary rather than silently misencoding.\n */\n\n/**\n * Encode the `_vec` side-car id for a (collection, recordId) pair.\n * Format: `<collection>/<recordId>` — no escaping; `recordId` may contain `/`.\n *\n * Throws if `collection` contains `/`: that would make the composite id\n * ambiguous against `isVecIdFor`'s prefix match (collection `'a'` would\n * appear to own collection `'a/b'`'s rows), reintroducing the clobber/crash\n * risk the namespacing fix exists to close.\n */\nexport function encodeVecId(collection: string, recordId: string): string {\n if (collection.includes('/')) {\n throw new Error(\n `encodeVecId: collection name \"${collection}\" must not contain \"/\" — ` +\n `it would make the \"${collection}/${recordId}\" _vec id ambiguous against another collection's rows.`,\n )\n }\n return `${collection}/${recordId}`\n}\n\n/**\n * Decode a `_vec` id back to the bare record id, given the KNOWN owning\n * collection — strips the `<collection>/` prefix rather than splitting on\n * `/`, so a `recordId` containing `/` round-trips correctly. Returns `null`\n * if `vecId` does not belong to `collection`.\n */\nexport function decodeVecId(collection: string, vecId: string): string | null {\n const prefix = `${collection}/`\n if (!vecId.startsWith(prefix)) return null\n return vecId.slice(prefix.length)\n}\n\n/** Predicate form of {@link decodeVecId} — used to filter `list()` results. */\nexport function isVecIdFor(collection: string, vecId: string): boolean {\n return vecId.startsWith(`${collection}/`)\n}\n","/** Cosine similarity in [-1,1]; 0 on zero-norm or length mismatch (no NaN). (L2) */\nexport function cosine(a: Float32Array | number[], b: Float32Array | number[]): number {\n if (a.length !== b.length) return 0\n let dot = 0, na = 0, nb = 0\n for (let i = 0; i < a.length; i++) {\n const x = a[i]!, y = b[i]!\n dot += x * y; na += x * x; nb += y * y\n }\n if (na === 0 || nb === 0) return 0\n return dot / (Math.sqrt(na) * Math.sqrt(nb))\n}\n","/** In-memory vector set for L2 semantic retrieval. Loaded once per session from\n * decrypted _vec sidecars (injected loader), brute-force cosine kNN, model-guarded. */\nimport { cosine } from './cosine.js'\nimport { EmbeddingModelMismatchError } from '../../kernel/errors.js'\n\nexport interface StoredVector { readonly id: string; readonly vec: Float32Array; readonly model: string }\nexport interface VectorHit { readonly id: string; readonly score: number }\n\nexport class VectorSet {\n private vectors: StoredVector[] | undefined\n get loaded(): boolean { return this.vectors !== undefined }\n\n async ensureLoaded(load: () => Promise<StoredVector[]>): Promise<void> {\n if (this.vectors === undefined) this.vectors = await load()\n }\n\n markDirty(): void { this.vectors = undefined }\n\n cosineTopK(query: Float32Array, k: number, opts: { minScore?: number; expectModel?: string } = {}): VectorHit[] {\n const all = this.vectors ?? []\n const minScore = opts.minScore ?? -Infinity\n const hits: VectorHit[] = []\n for (const v of all) {\n if (opts.expectModel !== undefined && v.model !== opts.expectModel) {\n throw new EmbeddingModelMismatchError(opts.expectModel, v.model)\n }\n const score = cosine(query, v.vec)\n if (score >= minScore) hits.push({ id: v.id, score })\n }\n hits.sort((a, b) => b.score - a.score)\n return hits.slice(0, k)\n }\n}\n"],"mappings":";;;;;;;;AAWO,SAAS,oBAAoB,QAAiC,QAA4C;AAC/G,QAAM,SAAS,OAAO,WAAW,WAAW,CAAC,MAAM,IAAI;AACvD,QAAM,QAAkB,CAAC;AACzB,aAAW,KAAK,QAAQ;AACtB,eAAW,QAAQ,UAAU,QAAQ,CAAC,GAAG;AACvC,UAAI,OAAO,SAAS,YAAY,SAAS,GAAI,OAAM,KAAK,IAAI;AAAA,IAC9D;AAAA,EACF;AACA,SAAO,MAAM,KAAK,GAAG;AACvB;;;ACkBO,SAAS,YAAY,YAAoB,UAA0B;AACxE,MAAI,WAAW,SAAS,GAAG,GAAG;AAC5B,UAAM,IAAI;AAAA,MACR,iCAAiC,UAAU,oDACnB,UAAU,IAAI,QAAQ;AAAA,IAChD;AAAA,EACF;AACA,SAAO,GAAG,UAAU,IAAI,QAAQ;AAClC;AAQO,SAAS,YAAY,YAAoB,OAA8B;AAC5E,QAAM,SAAS,GAAG,UAAU;AAC5B,MAAI,CAAC,MAAM,WAAW,MAAM,EAAG,QAAO;AACtC,SAAO,MAAM,MAAM,OAAO,MAAM;AAClC;AAGO,SAAS,WAAW,YAAoB,OAAwB;AACrE,SAAO,MAAM,WAAW,GAAG,UAAU,GAAG;AAC1C;;;AC9DO,SAAS,OAAO,GAA4B,GAAoC;AACrF,MAAI,EAAE,WAAW,EAAE,OAAQ,QAAO;AAClC,MAAI,MAAM,GAAG,KAAK,GAAG,KAAK;AAC1B,WAAS,IAAI,GAAG,IAAI,EAAE,QAAQ,KAAK;AACjC,UAAM,IAAI,EAAE,CAAC,GAAI,IAAI,EAAE,CAAC;AACxB,WAAO,IAAI;AAAG,UAAM,IAAI;AAAG,UAAM,IAAI;AAAA,EACvC;AACA,MAAI,OAAO,KAAK,OAAO,EAAG,QAAO;AACjC,SAAO,OAAO,KAAK,KAAK,EAAE,IAAI,KAAK,KAAK,EAAE;AAC5C;;;ACFO,IAAM,YAAN,MAAgB;AAAA,EACb;AAAA,EACR,IAAI,SAAkB;AAAE,WAAO,KAAK,YAAY;AAAA,EAAU;AAAA,EAE1D,MAAM,aAAa,MAAoD;AACrE,QAAI,KAAK,YAAY,OAAW,MAAK,UAAU,MAAM,KAAK;AAAA,EAC5D;AAAA,EAEA,YAAkB;AAAE,SAAK,UAAU;AAAA,EAAU;AAAA,EAE7C,WAAW,OAAqB,GAAW,OAAoD,CAAC,GAAgB;AAC9G,UAAM,MAAM,KAAK,WAAW,CAAC;AAC7B,UAAM,WAAW,KAAK,YAAY;AAClC,UAAM,OAAoB,CAAC;AAC3B,eAAW,KAAK,KAAK;AACnB,UAAI,KAAK,gBAAgB,UAAa,EAAE,UAAU,KAAK,aAAa;AAClE,cAAM,IAAI,4BAA4B,KAAK,aAAa,EAAE,KAAK;AAAA,MACjE;AACA,YAAM,QAAQ,OAAO,OAAO,EAAE,GAAG;AACjC,UAAI,SAAS,SAAU,MAAK,KAAK,EAAE,IAAI,EAAE,IAAI,MAAM,CAAC;AAAA,IACtD;AACA,SAAK,KAAK,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK;AACrC,WAAO,KAAK,MAAM,GAAG,CAAC;AAAA,EACxB;AACF;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/with-formula/overlay-views/virtual-collection.ts"],"sourcesContent":["import { OverlayIdMismatchError } from '../../kernel/errors.js'\nimport type { Collection } from '../../kernel/collection.js'\nimport type { OverlayedViewSpec } from './types.js'\n\n/**\n * Virtual-collection proxy returned by `vault.collection(overlayName)`\n * when `overlayName` is a registered `withOverlayedView`.\n *\n * Implements the core `Collection<T>`-shaped read/write surface with\n * merge-on-read semantics:\n * - `get(id)`: overlay row wins iff `overlay[shadowField] === shadowValue`;\n * when `spec.mergeMode` is set, an intermediate status may instead pull\n * a declared subset of fields from the overlay over the base\n * - `list()` / `.query()`: union of ids, per-id merge applied\n * - `put(record)` / `put(id, record)`: routes to overlay; id derived\n * via the base MV's `rowKey` (validated on the two-arg form)\n * - `delete(id)`: removes the overlay row only; base stays\n *\n * Reactive APIs (`live`, `subscribe`, `query().live()`) are out of\n * scope for this release and surface as \"not yet implemented\" — wired in a\n * future sub-issue.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport class OverlayedCollection<T extends Record<string, unknown> = any> {\n constructor(\n private readonly spec: OverlayedViewSpec,\n private readonly baseCollection: Collection<T>,\n private readonly overlayCollection: Collection<T>,\n private readonly baseRowKey: ((row: Record<string, unknown>) => string) | undefined,\n ) {}\n\n /**\n * Convenience accessors for advanced callers that need to bypass the\n * virtual layer (bulk imports, direct overlay queries). Mirrors the\n * spec's \"direct writes to the underlying overlay collection skip\n * the validation\" escape hatch.\n */\n readonly overlay = {\n rowKey: (row: Record<string, unknown>): string => {\n if (!this.baseRowKey) {\n throw new Error(\n `Overlay \"${this.spec.name}\": base \"${this.spec.base}\" is not an MV — ` +\n `cannot auto-derive id from the row. Use \\`put(id, record)\\` instead.`,\n )\n }\n return this.baseRowKey(row)\n },\n }\n\n /** Get the merged row by id. */\n async get(id: string): Promise<T | null> {\n const overlayRow = await this.overlayCollection.get(id)\n const baseRow = await this.baseCollection.get(id)\n return this.mergeRows(overlayRow, baseRow)\n }\n\n /** List union of base + overlay ids, applying the merge per row. */\n async list(): Promise<T[]> {\n const baseRows = await this.baseCollection.list()\n const overlayRows = await this.overlayCollection.list()\n const idOf = (row: T): string => {\n // Best-effort: use baseRowKey if available, else assume the row\n // has a `.id` field (common pattern). The spec requires every\n // base MV to declare `rowKey`, so the first branch is the\n // canonical path.\n if (this.baseRowKey) return this.baseRowKey(row as Record<string, unknown>)\n const idField = (row as Record<string, unknown>).id\n return typeof idField === 'string' ? idField : ''\n }\n // Key base + overlay rows by id, then union the id sets and run the\n // same per-id merge `get()` uses. Nulls (overlay-only rows that\n // don't qualify and have no base) are filtered out.\n const baseById = new Map<string, T>()\n const overlayById = new Map<string, T>()\n for (const row of baseRows) {\n const id = idOf(row)\n if (id) baseById.set(id, row)\n }\n for (const row of overlayRows) {\n const id = idOf(row)\n if (id) overlayById.set(id, row)\n }\n const out: T[] = []\n for (const id of new Set([...baseById.keys(), ...overlayById.keys()])) {\n const merged = this.mergeRows(overlayById.get(id) ?? null, baseById.get(id) ?? null)\n if (merged !== null) out.push(merged)\n }\n return out\n }\n\n /**\n * Write to the overlay. Two forms:\n * - `put(record)`: id is derived via the base MV's `rowKey(record)`.\n * Throws if the base isn't an MV.\n * - `put(id, record)`: validates `id === rowKey(record)`; throws\n * `OverlayIdMismatchError` on mismatch.\n */\n async put(idOrRecord: string | T, maybeRecord?: T): Promise<void> {\n let id: string\n let record: T\n if (maybeRecord === undefined) {\n // Single-arg form: put(record). Derive id via base rowKey.\n record = idOrRecord as T\n if (!this.baseRowKey) {\n throw new Error(\n `Overlay \"${this.spec.name}\".put(record): base \"${this.spec.base}\" is not an MV. ` +\n `Use put(id, record) explicitly.`,\n )\n }\n id = this.baseRowKey(record as Record<string, unknown>)\n } else {\n // Two-arg form: put(id, record). Validate against rowKey.\n id = idOrRecord as string\n record = maybeRecord\n if (this.baseRowKey) {\n const expected = this.baseRowKey(record as Record<string, unknown>)\n if (id !== expected) {\n throw new OverlayIdMismatchError(id, expected)\n }\n }\n }\n await this.overlayCollection.put(id, record)\n }\n\n /**\n * Remove the overlay row only. Idempotent (no-op on absent).\n * The base row is untouched — if a base row exists for `id`,\n * subsequent reads return it.\n */\n async delete(id: string): Promise<void> {\n await this.overlayCollection.delete(id)\n }\n\n /**\n * Merge a single id's overlay + base rows into the visible row.\n *\n * Priority (first match wins):\n * 1. Binary shadow win — overlay present AND\n * `overlay[shadowField] === shadowValue` → return the overlay row\n * entirely. This stays FIRST so the original binary behaviour is\n * unchanged whether or not `mergeMode` is configured.\n * 2. Field-level merge — overlay present, `mergeMode` configured,\n * and a rule whose `whenStatus` equals `overlay[shadowField]`.\n * The matched rule pulls its `overlayFields` (those present on\n * the overlay row) on top of the base row. With no base row, the\n * overlay row is returned as-is.\n * 3. Fallback — return the base row (possibly `null`). An\n * overlay-only row that qualifies under neither (1) nor (2) and\n * has no base is therefore NOT surfaced.\n */\n private mergeRows(overlayRow: T | null, baseRow: T | null): T | null {\n const shadowField = this.spec.shadowField\n if (\n overlayRow !== null &&\n (overlayRow as Record<string, unknown>)[shadowField] === this.spec.shadowValue\n ) {\n return overlayRow\n }\n if (overlayRow !== null && this.spec.mergeMode) {\n const status = (overlayRow as Record<string, unknown>)[shadowField]\n const rule = this.spec.mergeMode.rules.find((r) => r.whenStatus === status)\n if (rule) {\n if (baseRow === null) return overlayRow\n const overlaySrc = overlayRow as Record<string, unknown>\n const picked: Record<string, unknown> = {}\n for (const field of rule.overlayFields) {\n if (field in overlaySrc) picked[field] = overlaySrc[field]\n }\n return { ...(baseRow as Record<string, unknown>), ...picked } as T\n }\n }\n return baseRow\n }\n\n // ─── Throw-stubs for the unimplemented Collection<T> surface ───────\n //\n // `Vault.collection(name)` widens the return type to `Collection<T>`\n // for the overlay intercept, but `OverlayedCollection` doesn't\n // implement the full surface. These stubs catch the common\n // reactive / chainable APIs with a clear \"not yet implemented\"\n // error pointing at the relevant issue — so consumers don't hit a\n // cryptic `undefined is not a function` runtime crash.\n //\n // Throw-stubs so consumers get actionable errors rather than cryptic crashes.\n\n /** @throws — chainable Query<T> over a virtual collection is deferred. */\n query(): never {\n throw new Error(\n `OverlayedCollection \"${this.spec.name}\".query() is not yet implemented for overlay views (#154). ` +\n `Use \\`list()\\` + filter for now, or read from the underlying \\`${this.spec.base}\\` / \\`${this.spec.overlay}\\` collections directly. ` +\n `Reactive APIs land in a future MV sub-issue.`,\n )\n }\n\n /** @throws — change-stream subscription over a virtual collection is deferred. */\n subscribe(): never {\n throw new Error(\n `OverlayedCollection \"${this.spec.name}\".subscribe() is not yet implemented for overlay views (#154). ` +\n `Subscribe to the underlying \\`${this.spec.base}\\` / \\`${this.spec.overlay}\\` collections individually for now. ` +\n `Merged change-stream lands in a future MV sub-issue.`,\n )\n }\n\n /** @throws — live query over a virtual collection is deferred. */\n live(): never {\n throw new Error(\n `OverlayedCollection \"${this.spec.name}\".live() is not yet implemented for overlay views (#154). ` +\n `Reactive APIs land in a future MV sub-issue.`,\n )\n }\n\n /** @throws — async iteration over a virtual collection is deferred. */\n scan(): never {\n throw new Error(\n `OverlayedCollection \"${this.spec.name}\".scan() is not yet implemented for overlay views (#154). ` +\n `Use \\`list()\\` for now (no row-count ceiling at niwat scale), or scan the underlying collections directly.`,\n )\n }\n\n /** @throws — lazy-mode query is not applicable to virtual collections. */\n lazyQuery(): never {\n throw new Error(\n `OverlayedCollection \"${this.spec.name}\".lazyQuery() is not supported. ` +\n `Virtual collections always materialize through base + overlay reads — lazy-mode indexed lookups don't apply.`,\n )\n }\n\n /** @throws — bulk-atomic put is deferred to a future MV sub-issue. */\n putManyAtomic(): never {\n throw new Error(\n `OverlayedCollection \"${this.spec.name}\".putManyAtomic() is not yet implemented for overlay views (#154). ` +\n `Use sequential \\`.put(record)\\` calls for now, or write to \\`${this.spec.overlay}\\` directly.`,\n )\n }\n\n /** @throws — bulk delete is deferred to a future MV sub-issue. */\n deleteMany(): never {\n throw new Error(\n `OverlayedCollection \"${this.spec.name}\".deleteMany() is not yet implemented for overlay views (#154). ` +\n `Use sequential \\`.delete(id)\\` calls for now, or operate on \\`${this.spec.overlay}\\` directly.`,\n )\n }\n\n /** @throws — `.first()` over a virtual collection is deferred. */\n first(): never {\n throw new Error(\n `OverlayedCollection \"${this.spec.name}\".first() is not yet implemented for overlay views (#154). ` +\n `Use \\`(await list())[0]\\` for now.`,\n )\n }\n\n /** @throws — `.count()` over a virtual collection is deferred. */\n count(): never {\n throw new Error(\n `OverlayedCollection \"${this.spec.name}\".count() is not yet implemented for overlay views (#154). ` +\n `Use \\`(await list()).length\\` for now.`,\n )\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/with-party/policy/presets.ts","../src/with-party/policy/engine.ts","../src/with-party/policy/noydb-facade.ts"],"sourcesContent":["import type { VaultPolicy } from '../../kernel/types.js'\n\n/**\n * Default policy for personal vaults and SMB deployments — the gates\n * that need an off-device factor get one (TOTP / email-OTP / paper\n * recovery), the rest take a tier-1 unlock alone. Tier-3 (PIN) is the\n * floor only for `rotate-unlock` because that's the\n * \"change my PIN\" flow.\n *\n * The unspecified gates (e.g. `view-user-auth`) inherit the engine\n * default of `{ enabled: false, minTier: 1 }` — they fail closed.\n *\n * @see https://github.com/vLannaAi/noy-db-docs/blob/main/content/docs/services/session-tiers.md → Built-in gates\n */\nexport const PERSONAL_POLICY: VaultPolicy = Object.freeze({\n secret: {\n minWords: 6,\n minWordLength: 3,\n rejectRepeatedAdjacent: true,\n },\n gates: {\n 'rotate-secret': {\n minTier: 1,\n // Any second factor satisfies the gate — off-device kinds (TOTP,\n // email-OTP, paper recovery, roaming WebAuthn) are the strongest;\n // platform-bound kinds (platform WebAuthn, password, PIN) are\n // accepted because requiring \"something off-device\" is overkill\n // for personal/SMB threat models. Consumers needing the off-device\n // guarantee should use STRICT_POLICY or override this gate.\n factors: [{\n anyOf: [\n 'totp', 'email-otp', 'recovery',\n 'webauthn-roaming', 'webauthn-platform',\n 'password', 'pin',\n ],\n }],\n },\n 'recover-secret': {\n minTier: 1,\n enabled: true,\n },\n // rotate-recovery: deliberate paper-sheet regeneration\n // when the user remembers their secret. PERSONAL allows tier-1 —\n // knowing the secret is enough.\n 'rotate-recovery': { minTier: 1 },\n 'enroll-authenticator': { minTier: 1 },\n 'remove-authenticator': { minTier: 1 },\n // update-authenticator: meta-only mutation (slot rename, label\n // changes). Symmetric with enroll/remove under PERSONAL — tier-1\n // unlock alone. The structural anti-slot-swap guard inside the\n // implementation enforces wrap-material/id/method immutability\n // regardless of this gate's settings.\n 'update-authenticator': { minTier: 1 },\n 'rotate-unlock': { minTier: 2 },\n 'enroll-user': { minTier: 1 },\n 'revoke-user': { minTier: 1 },\n // Peer-recovery is a high-trust intentional op — co-owners\n // recovering each other should not need an off-device factor in\n // the personal/SMB threat model (the partner is already vetted by\n // virtue of being a co-owner). Tier-1 unlock is the floor; the\n // STRICT preset adds a recovery/email-OTP requirement.\n 'peer-recover-user': { minTier: 1 },\n // update-user: post-grant identity mutation (role/displayName/\n // permissions). PERSONAL_POLICY treats this on par with enroll-user\n // / revoke-user — tier-1 unlock alone. The role-elevation guard\n // inside the implementation is the structural backstop that this\n // gate's settings cannot weaken.\n 'update-user': { minTier: 1 },\n 'export-bundle': { minTier: 1 },\n 'export-plaintext': {\n minTier: 1,\n factors: [{ anyOf: ['totp', 'email-otp'] }],\n },\n 'view-user-auth': {\n minTier: 1,\n enabled: false,\n },\n // ─── User envelope gates ──────────────────────────────────────────\n // edit-own-profile: tier 3 floor — any active session can edit their\n // own profile/preferences. Tightening to require a TOTP for\n // profile changes is a one-line override.\n // view-team-profiles: tier 2 floor — an authenticated session can\n // read teammates' profiles (display names, avatars, locales).\n // Setting `enabled: false` makes vault.user.list() return only\n // self (privacy-strict opt-out).\n 'edit-own-profile': { minTier: 3 },\n 'view-team-profiles': { minTier: 2 },\n // client-unilateral-withdraw: a non-owner's self-service DESTRUCTIVE\n // withdrawal (export-and-delete/freeze). Fail-closed by default —\n // the firm opts in per jurisdiction/contract (e.g. GDPR Art. 17).\n // Listed explicitly (not just relying on the built-in default) so it is\n // discoverable in describeGate / policy dumps.\n 'client-unilateral-withdraw': { minTier: 1, enabled: false },\n // Two-party withdrawal: filing a request is non-destructive\n // (tier-1, enabled so a read-only client can ask); deciding it is the\n // destructive step (tier-2 floor + owner/admin role, enforced in code).\n 'user-request-withdrawal': { minTier: 1 },\n 'approve-user-withdrawal': { minTier: 2 },\n },\n}) as VaultPolicy\n\n/**\n * Strict policy for regulated deployments and shared workstations —\n * raises the phrase floor to 8 words, demands two distinct factors for\n * exports, and blocks export-on-shared-device. Use as a base for\n * `policy: { ...STRICT_POLICY, gates: { ...STRICT_POLICY.gates, ... } }`\n * tweaks.\n */\nexport const STRICT_POLICY: VaultPolicy = Object.freeze({\n secret: {\n minWords: 8,\n minWordLength: 3,\n rejectRepeatedAdjacent: true,\n },\n gates: {\n 'rotate-secret': {\n minTier: 1,\n factors: [{ anyOf: ['totp', 'email-otp', 'recovery'], count: 2 }],\n },\n 'recover-secret': {\n minTier: 1,\n enabled: true,\n },\n // rotate-recovery: STRICT requires an off-device factor —\n // rotating recovery is an off-site-trust event; a stolen unlocked\n // laptop must not be able to silently mint a new sheet for the\n // attacker. Matches the `peer-recover-user` STRICT default.\n 'rotate-recovery': {\n minTier: 1,\n factors: [{ anyOf: ['totp', 'email-otp', 'webauthn-roaming'] }],\n },\n 'enroll-authenticator': {\n minTier: 1,\n factors: [{ anyOf: ['totp', 'email-otp'] }],\n },\n 'remove-authenticator': {\n minTier: 1,\n factors: [{ anyOf: ['totp', 'email-otp'] }],\n },\n // STRICT update-authenticator: same factor floor as enroll/remove.\n // Even though meta changes don't touch wrap material, a malicious\n // rename could mislead the user about which device a slot\n // corresponds to (\"MacBook Touch ID\" → \"iPhone Touch ID\" on a\n // shared workstation). STRICT requires a fresh factor proof.\n 'update-authenticator': {\n minTier: 1,\n factors: [{ anyOf: ['totp', 'email-otp'] }],\n },\n 'rotate-unlock': { minTier: 1 },\n 'enroll-user': {\n minTier: 1,\n factors: [{ anyOf: ['totp', 'email-otp'] }],\n },\n 'revoke-user': {\n minTier: 1,\n factors: [{ anyOf: ['totp', 'email-otp'] }],\n },\n // STRICT peer-recovery: the issuer must present a recovery code\n // OR a fresh off-device second factor at the moment of recovery.\n // This binds the high-trust operation to a verifiable proof\n // (recovery sheet photographed by an attacker won't suffice —\n // they'd also need tier-1 unlock first; this gate is the freshness\n // binding on top). Roaming WebAuthn (YubiKey-class hardware key)\n // accepted; platform-bound kinds (Touch ID, password, PIN)\n // intentionally excluded under STRICT because they don't survive\n // device theft — the off-device requirement is the whole point.\n 'peer-recover-user': {\n minTier: 1,\n factors: [{ anyOf: ['recovery', 'totp', 'email-otp', 'webauthn-roaming'] }],\n },\n // STRICT update-user: matches the enroll-user / revoke-user shape\n // (off-device factor required). Update-user is admin-shaped — it\n // mutates someone else's role/permissions; STRICT requires a fresh\n // off-device factor proof so the operator affirmatively re-asserts\n // identity at the moment of mutation. Platform-bound factors\n // (Touch ID / password / PIN) intentionally excluded: same logic as\n // peer-recover-user — the off-device requirement is the whole\n // point under STRICT.\n 'update-user': {\n minTier: 1,\n factors: [{ anyOf: ['totp', 'email-otp'] }],\n },\n 'export-bundle': {\n minTier: 1,\n factors: [{ anyOf: ['totp', 'email-otp'] }],\n warn: { sharedDevice: 'block' },\n },\n 'export-plaintext': {\n minTier: 1,\n factors: [{ anyOf: ['totp', 'email-otp'], count: 2 }],\n warn: { sharedDevice: 'block' },\n },\n 'view-user-auth': {\n minTier: 1,\n enabled: false,\n },\n // ─── User envelope gates ──────────────────────────────────────────\n // STRICT: profile edits require a TOTP/email-OTP factor (typical\n // shared-workstation hardening — your name/avatar shouldn't change\n // without a fresh second-factor proof).\n 'edit-own-profile': {\n minTier: 2,\n factors: [{ anyOf: ['totp', 'email-otp'] }],\n },\n 'view-team-profiles': { minTier: 2 },\n // STRICT: still fail-closed, but if a regulated firm flips enabled:true\n // they inherit a two-factor proof + shared-device block for the\n // destructive withdrawal (mirrors export-plaintext's hardening).\n 'client-unilateral-withdraw': {\n minTier: 1,\n enabled: false,\n factors: [{ anyOf: ['totp', 'email-otp'], count: 2 }],\n warn: { sharedDevice: 'block' },\n },\n // STRICT: filing stays tier-1; the destructive APPROVE demands an\n // off-device factor + shared-device block (mirrors export-bundle).\n 'user-request-withdrawal': { minTier: 1 },\n 'approve-user-withdrawal': {\n minTier: 2,\n factors: [{ anyOf: ['totp', 'email-otp'] }],\n warn: { sharedDevice: 'block' },\n },\n },\n}) as VaultPolicy\n\n/**\n * Merge a developer override onto a preset. Unspecified gates inherit;\n * specified gates fully replace the preset's entry for that gate.\n *\n * Example:\n *\n * ```ts\n * mergePolicy(PERSONAL_POLICY, {\n * gates: {\n * 'app:approve-large-payment': { minTier: 2, factors: [{ anyOf: ['totp'] }] },\n * },\n * })\n * // → PERSONAL_POLICY plus the new app gate; existing gates intact.\n * ```\n */\nexport function mergePolicy(\n base: VaultPolicy,\n override?: Partial<VaultPolicy>,\n): VaultPolicy {\n if (!override) return base\n const secret = override.secret ?? base.secret\n return {\n ...(secret !== undefined ? { secret } : {}),\n gates: {\n ...base.gates,\n ...(override.gates ?? {}),\n },\n }\n}\n","/**\n * Policy gate engine — the {@link checkGate} entry point.\n *\n * Given a configured {@link VaultPolicy}, an active session tier, and\n * the factor proofs an actor is presenting, decide whether the gate\n * permits the action. On denial, throws {@link PolicyDeniedError} with\n * a stable {@link PolicyDenyReason} so consumers can branch in error\n * UIs.\n *\n * @see https://github.com/vLannaAi/noy-db-docs/blob/main/content/docs/services/session-tiers.md → checkGate() API\n *\n * @module\n */\nimport { PolicyDeniedError, type PolicyDenyReason } from '../../kernel/errors.js'\nimport type {\n ActiveTier,\n FactorProof,\n GateName,\n GatePolicy,\n VaultPolicy,\n FactorRequirement,\n} from '../../kernel/types.js'\n\n/** Default freshness window — 5 minutes. */\nexport const DEFAULT_FRESHNESS_MS = 5 * 60 * 1000\n\n/** Caller-supplied context for one `checkGate` invocation. */\nexport interface CheckGateContext {\n /** Tier the active session currently holds. */\n readonly activeTier: ActiveTier\n /** Proofs the actor is presenting for this gate. */\n readonly factors?: ReadonlyArray<FactorProof>\n /**\n * If the host knows the actor is on a shared device, set this to\n * `true` so the engine can apply `warn.sharedDevice` rules. Defaults\n * to `false`.\n */\n readonly sharedDevice?: boolean\n /**\n * Override `now()` for tests. Defaults to `Date.now()`.\n * @internal\n */\n readonly now?: number\n}\n\n/**\n * Decide whether `gate` permits the action under `context`. Throws\n * {@link PolicyDeniedError} on denial; resolves with `void` on success.\n *\n * Lookup rules:\n * - **Built-in gates** without a configured policy fail closed\n * (`enabled: false`).\n * - **App-defined gates** (`app:*`) without a configured policy are\n * treated as no-op (allow). The developer registered the policy if\n * they wanted enforcement; absence means the gate is informational.\n */\nexport async function checkGate(\n policy: VaultPolicy,\n gate: GateName,\n context: CheckGateContext,\n): Promise<void> {\n const configured = policy.gates[gate]\n if (!configured) {\n if (gate.startsWith('app:')) {\n // Custom app gate without a policy — the developer hasn't\n // registered one; engine treats it as an unenforced label.\n return\n }\n // Built-in gate without a policy — fail closed.\n throw deny(gate, 'disabled', { minTier: 1, enabled: false })\n }\n\n if (configured.enabled === false) {\n throw deny(gate, 'disabled', configured)\n }\n\n // Tier check first — cheap and a hard prerequisite.\n if (context.activeTier > configured.minTier) {\n // Higher number is a LOWER tier in this model (1 is most privileged).\n throw deny(gate, 'insufficient-tier', configured)\n }\n\n // Factor checks — every requirement entry must be satisfied.\n if (configured.factors && configured.factors.length > 0) {\n const presented = context.factors ?? []\n const now = context.now ?? Date.now()\n for (const requirement of configured.factors) {\n const matches = countMatchingFactors(presented, requirement, now)\n const need = requirement.count ?? 1\n if (matches.fresh < need) {\n if (matches.totalKindMatches < need) {\n throw deny(gate, 'missing-factor', configured)\n }\n // Some matched the kind list but not the freshness window.\n throw deny(gate, 'stale-proof', configured)\n }\n }\n }\n\n // Soft signals — only `'block'` raises here.\n if (configured.warn?.sharedDevice === 'block' && context.sharedDevice === true) {\n throw deny(gate, 'shared-device-blocked', configured)\n }\n}\n\n/**\n * Same as {@link checkGate} but returns a structured verdict instead\n * of throwing. Useful when an error UI wants to show the user\n * \"you'll need TOTP plus a recovery code to do that\" without first\n * triggering the action.\n */\nexport async function describeGate(\n policy: VaultPolicy,\n gate: GateName,\n context: CheckGateContext,\n): Promise<{ ok: true } | { ok: false; reason: PolicyDenyReason; required: GatePolicy }> {\n try {\n await checkGate(policy, gate, context)\n return { ok: true }\n } catch (err) {\n if (err instanceof PolicyDeniedError) {\n return { ok: false, reason: err.reason, required: err.required }\n }\n throw err\n }\n}\n\nfunction countMatchingFactors(\n presented: ReadonlyArray<FactorProof>,\n requirement: FactorRequirement,\n now: number,\n): { totalKindMatches: number; fresh: number } {\n const freshnessMs = requirement.freshnessMs ?? DEFAULT_FRESHNESS_MS\n let totalKindMatches = 0\n let fresh = 0\n for (const proof of presented) {\n if (!requirement.anyOf.includes(proof.kind)) continue\n totalKindMatches += 1\n const minted = proof.mintedAt ? Date.parse(proof.mintedAt) : now\n if (Number.isFinite(minted) && now - minted <= freshnessMs) {\n fresh += 1\n }\n }\n return { totalKindMatches, fresh }\n}\n\nfunction deny(gate: GateName, reason: PolicyDenyReason, required: GatePolicy): PolicyDeniedError {\n return new PolicyDeniedError(gate, reason, required)\n}\n","/**\n * Noydb-side policy / session-policy facade.\n *\n * Holds the vault-policy read/update/bootstrap logic (`getPolicy`,\n * `updatePolicy`, `bootstrapPolicy`) and the per-vault session-policy\n * enforcer wiring (`touchPolicy`, `checkPolicyOperation`). The session\n * *timer* and the managed-recovery enrolment check stay kernel-resident on\n * `Noydb` (interleaved with the instance lifecycle) and arrive here as the\n * `resetSessionTimer` / `assertRecoveryEnrolled` callbacks. The policy cache\n * and the enforcer map stay `Noydb`-resident too (touched by\n * `openVault`/`close`) and arrive by reference; behaviour is byte-identical\n * to the inline `Noydb` methods it replaced — every other dependency the\n * moving code touched on `this.*` arrives via {@link NoydbPolicyDeps}.\n *\n * Internal service — reached through `noydb.getPolicy(...)` etc. Public\n * contract ({@link NoydbPolicyApi} / {@link NoydbPolicyDeps} /\n * {@link NoydbPolicyFactory}) lives in the kernel spine; `createNoydb()`\n * wires this file's {@link createNoydbPolicy} in via a pre-resolved dynamic\n * import (the S4 gate recipe).\n */\nimport { ValidationError } from '../../kernel/errors.js'\nimport { PERSONAL_POLICY, mergePolicy } from './presets.js'\nimport { loadVaultPolicy, saveVaultPolicy } from './storage.js'\nimport type { VaultPolicy, ReAuthOperation, NoydbPolicyApi, NoydbPolicyDeps, NoydbPolicyFactory } from '../../kernel/types.js'\n\nexport class NoydbPolicy implements NoydbPolicyApi {\n constructor(private readonly deps: NoydbPolicyDeps) {}\n\n /**\n * Touch the policy enforcer for a vault (records activity, resets\n * idle timer). Also touches the legacy session timer. No-op if no enforcer.\n */\n touchPolicy(vault?: string): void {\n this.deps.resetSessionTimer()\n if (vault) {\n this.deps.policyEnforcers.get(vault)?.touch()\n }\n }\n\n /**\n * Check that a policy-guarded operation is permitted.\n * Throws `SessionPolicyError` if re-auth is required.\n */\n checkPolicyOperation(vault: string, op: ReAuthOperation): void {\n this.deps.policyEnforcers.get(vault)?.checkOperation(op)\n }\n\n /**\n * Read the active policy for a vault. Loads from `_meta/policy` on\n * first call; subsequent calls hit the in-memory cache. Throws\n * `ValidationError` if the vault has not been opened.\n */\n async getPolicy(vault: string): Promise<VaultPolicy> {\n if (this.deps.isClosed()) throw new ValidationError('Instance is closed')\n const cached = this.deps.policyCache.get(vault)\n if (cached) return cached\n await this.bootstrapPolicy(vault)\n return this.deps.policyCache.get(vault) ?? PERSONAL_POLICY\n }\n\n /**\n * Replace the policy document at `_meta/policy` and update the\n * in-memory cache. Gated by the `enroll-user` policy (a policy\n * change is fundamentally a privilege-management action).\n */\n async updatePolicy(vault: string, override: Partial<VaultPolicy>): Promise<VaultPolicy> {\n if (this.deps.isClosed()) throw new ValidationError('Instance is closed')\n const current = await this.getPolicy(vault)\n const merged = mergePolicy(current, override)\n if (this.deps.encrypted) {\n await saveVaultPolicy(this.deps.store, vault, merged)\n }\n this.deps.policyCache.set(vault, merged)\n return merged\n }\n\n /** Read or persist the vault policy at `_meta/policy` on first open. */\n async bootstrapPolicy(\n vault: string,\n opts?: { skipManagedCheck?: boolean },\n ): Promise<void> {\n const onDisk = await loadVaultPolicy(this.deps.store, vault)\n if (onDisk) {\n // Honour the on-disk document; developer overrides cannot\n // weaken what the vault committed to at creation time.\n this.deps.policyCache.set(vault, onDisk)\n await this.deps.assertRecoveryEnrolled(vault, onDisk, opts)\n return\n }\n // First time — persist the developer's policy (or default preset).\n const initial = this.deps.policyOption\n ? mergePolicy(PERSONAL_POLICY, this.deps.policyOption)\n : PERSONAL_POLICY\n await saveVaultPolicy(this.deps.store, vault, initial)\n this.deps.policyCache.set(vault, initial)\n await this.deps.assertRecoveryEnrolled(vault, initial, opts)\n }\n}\n\n/**\n * Factory that builds the `NoydbPolicy` service. `createNoydb()`\n * pre-resolves this via a dynamic import (mirrors\n * `with-party/directory/user-envelope/api.js#createUserApi`) and threads\n * it through `NoydbOptions.policyFactory` so `Noydb`'s constructor can\n * build `this.policyManager` synchronously.\n */\nexport const createNoydbPolicy: NoydbPolicyFactory = (deps) => new NoydbPolicy(deps)\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/with-lookup/search/collection-facade.ts"],"sourcesContent":["/**\n * Collection-level search / retrieval (`search` / `retrieve` / `similarTo` +\n * the lexical-index build/flush/warm machinery).\n *\n * This is the retrieval surface: a pure client-side lexical scan\n * (`search`), the persisted-or-in-memory inverted-index lifecycle\n * (`flushIndex` / `warmIndex` / `buildRetrievalDocs` + the dict-label / blob-\n * filename resolvers that feed it), and the lexical / semantic / hybrid\n * `retrieve` fan-out plus raw-vector kNN (`similarTo`). None of it touches the\n * write path — it reads the live eager cache and the encrypted `_vec` / `_ftindex`\n * side-cars.\n *\n * Every function takes a small {@link SearchContext} instead of `this`,\n * mirroring the `record-keys/` siblings.\n *\n * The `cache` is the SAME `Map` reference `Collection` owns (passed by\n * reference, never copied) so the index always builds over the live working\n * set. {@link buildPersistedIndexCallbacks} is special: it is invoked from the\n * `Collection` constructor *before* `this.codec` exists, so it takes a context\n * THUNK and resolves the context lazily at each callback invocation.\n *\n * Internal service — not exported as a `@noy-db/hub/*` subpath.\n */\nimport type { NoydbStore } from '../../kernel/types.js'\nimport type { RecordCodec } from '../../kernel/enclave/index.js'\nimport { stripI18nFilled, type I18nTextDescriptor } from '../../via/i18n/core.js'\nimport { isStaticDictDescriptor, type DictKeyDescriptor, type StaticDictDescriptor, type DictionaryHandle } from '../../via/i18n/dictionary.js'\nimport type { BlobSet } from '../../with-shape/blobs/blob-set.js'\nimport type { BlobFieldsConfig } from '../../with-shape/blobs/blob-compaction.js'\nimport type { Query } from '../../kernel/query/index.js'\nimport { embeddingSourceText, type VectorSet, type EmbeddingDescriptor, type StoredVector } from '../embeddings/index.js'\nimport { encodeVecId, decodeVecId, isVecIdFor } from '../embeddings/vec-id.js'\nimport { EmbeddingDimMismatchError } from '../../kernel/errors.js'\nimport { liveRecordIsElevated } from '../../kernel/tier-visibility.js'\nimport { searchScan, fuseRetrieval, type SearchOptions, type SearchResult } from './index.js'\nimport type { IndexStore } from './index-store.js'\nimport type { PersistedIndexCallbacks } from './persisted-index-store.js'\nimport { extractSnippet } from './snippet.js'\nimport { buildStringFieldEntries, buildI18nFieldEntries, buildDictKeyFieldEntries, buildBlobFieldEntries } from './build-docs.js'\nimport type { IndexDoc, IndexHit } from './inverted-index.js'\nimport type { RetrieveOptions, RetrieveHit } from './retrieve-types.js'\n\n/** Everything the moving search/retrieval methods touched on `this.*`. */\nexport interface SearchContext<T> {\n /** Collection name — error context + `_ftindex` row key. */\n readonly name: string\n /** Vault namespace the side-cars (`_vec`, `_ftindex`) live under. */\n readonly vault: string\n /** The ciphertext store. */\n readonly adapter: NoydbStore\n /** The record codec — decrypts the `_vec` / `_ftindex` side-car bodies. */\n readonly codec: RecordCodec<T>\n /** The eager working-set cache (SHARED `Map` reference, never copied). */\n readonly cache: Map<string, { record: T; version: number }>\n /** True in lazy mode — search/retrieve/warm require eager mode. */\n readonly lazy: boolean\n /** Declared text-index fields, or undefined. */\n readonly textIndexes: readonly string[] | undefined\n /** Declared i18n fields, or undefined. */\n readonly i18nFields: Record<string, I18nTextDescriptor> | undefined\n /** Declared dictionary-key fields, or undefined. */\n readonly dictKeyFields: Record<string, DictKeyDescriptor | StaticDictDescriptor> | undefined\n /** Declared blob fields, or undefined. */\n readonly blobFields: BlobFieldsConfig | undefined\n /** Dictionary handle resolver (dynamic dict-key labels), or undefined. */\n readonly getDictionary: ((name: string) => Promise<DictionaryHandle>) | undefined\n /** The lexical inverted-index store (in-memory or persisted), or undefined. */\n readonly searchIndexStore: IndexStore | undefined\n /** The vector set for semantic retrieval, or undefined. */\n readonly vectorSet: VectorSet | undefined\n /** The embeddings descriptor, or undefined. */\n readonly embeddings: EmbeddingDescriptor | undefined\n /** Hydrate the eager cache before reading it. */\n ensureHydrated(): Promise<void>\n /** Open the blob facade for a record (used to list indexed blob filenames). */\n blob(id: string): BlobSet\n}\n\n/**\n * Client-side lexical scan over the live eager cache. Eager mode only;\n * nothing searchable is written to the store.\n */\nexport async function search<T>(ctx: SearchContext<T>, field: string, query: string, opts: SearchOptions = {}): Promise<SearchResult<T>[]> {\n if (ctx.lazy) {\n throw new Error(\n `Collection \"${ctx.name}\": search() (scan mode) requires eager mode (prefetch: true). ` +\n `A store-usable blind index for lazy / at-scale search is a separate gated opt-in (#308).`,\n )\n }\n await ctx.ensureHydrated()\n const entries: { id: string; record: T }[] = []\n // Strip the internal densify marker from the user-facing records.\n // Non-mutating: never touches the cached record object. The search index\n // is built over the same (marker-free) record, which is fine — the marker\n // is never a searchable field.\n for (const [id, e] of ctx.cache) entries.push({ id, record: stripI18nFilled(e.record as Record<string, unknown>) as T })\n return searchScan(entries, field, query, opts)\n}\n\n/** L1 — build IndexDoc[] for the configured text fields over the live cache. */\nexport function buildRetrievalDocs<T>(\n ctx: SearchContext<T>,\n labelMaps: Map<string, Map<string, Record<string, string>>>,\n blobFilenames: Map<string, Map<string, string[]>>,\n only?: readonly string[],\n): IndexDoc[] {\n const docs: IndexDoc[] = []\n for (const [id, e] of ctx.cache) {\n const rec = stripI18nFilled(e.record as Record<string, unknown>)\n const fields = buildStringFieldEntries(rec, ctx.textIndexes ?? [], only)\n if (ctx.i18nFields) fields.push(...buildI18nFieldEntries(rec, ctx.i18nFields, ctx.textIndexes ?? [], only))\n if (ctx.dictKeyFields) fields.push(...buildDictKeyFieldEntries(rec, ctx.dictKeyFields, labelMaps, ctx.textIndexes ?? [], only))\n const blobNames = blobFilenames.get(id)\n if (blobNames) fields.push(...buildBlobFieldEntries(blobNames))\n if (fields.length > 0) docs.push({ id, fields })\n }\n return docs\n}\n\n/** L1 — true iff any configured text index is also a blob field (gates ALL slot I/O). */\nexport function hasIndexedBlobFields<T>(ctx: SearchContext<T>, only?: readonly string[]): boolean {\n if (!ctx.blobFields || !ctx.textIndexes) return false\n const fields = only ? ctx.textIndexes.filter((f) => only.includes(f)) : ctx.textIndexes\n return fields.some((f) => f in ctx.blobFields!)\n}\n\n/**\n * L1 — resolve `recordId -> (blobField -> filenames[])` by listing slots\n * for the configured blob fields of each cached record. Blob slot metadata is\n * NOT inline on the record: it lives in a separate `_blob_slots_*` collection,\n * so this costs ONE `blob(id).list()` (a `listSlots`) per record at build time\n * — the heaviest indexing source. Fully gated by {@link hasIndexedBlobFields};\n * non-blob (and blob-but-not-indexed) collections do ZERO slot I/O.\n */\nasync function resolveBlobFilenames<T>(ctx: SearchContext<T>, only?: readonly string[]): Promise<Map<string, Map<string, string[]>>> {\n const out = new Map<string, Map<string, string[]>>()\n if (!hasIndexedBlobFields(ctx, only)) return out\n const indexed = (only ? ctx.textIndexes!.filter((f) => only.includes(f)) : ctx.textIndexes!)\n .filter((f) => f in ctx.blobFields!)\n const indexedSet = new Set(indexed)\n for (const id of ctx.cache.keys()) {\n let slots\n try {\n slots = await ctx.blob(id).list()\n } catch {\n continue\n }\n let byField: Map<string, string[]> | undefined\n for (const slot of slots) {\n if (!indexedSet.has(slot.name) || !slot.filename) continue\n if (!byField) { byField = new Map(); out.set(id, byField) }\n const names = byField.get(slot.name)\n if (names) names.push(slot.filename)\n else byField.set(slot.name, [slot.filename])\n }\n }\n return out\n}\n\n/** L1 — field -> (key -> {locale->label}) for dictKey fields; static from table, dynamic via getDictionary().list(). */\nasync function resolveDictLabelMaps<T>(ctx: SearchContext<T>): Promise<Map<string, Map<string, Record<string, string>>>> {\n const maps = new Map<string, Map<string, Record<string, string>>>()\n if (!ctx.dictKeyFields || !ctx.textIndexes) return maps\n for (const field of ctx.textIndexes) {\n const desc = ctx.dictKeyFields[field]\n if (!desc) continue\n const m = new Map<string, Record<string, string>>()\n if (isStaticDictDescriptor(desc)) {\n for (const [key, labels] of Object.entries(desc.table)) m.set(key, labels as Record<string, string>)\n } else {\n if (ctx.getDictionary) {\n const handle = await ctx.getDictionary(desc.name)\n for (const e of await handle.list()) m.set(e.key, e.labels)\n }\n }\n maps.set(field, m)\n }\n return maps\n}\n\n/** L1.5 — force-persist the lexical index now (e.g. on save/idle). Persists only when textIndexPersist is enabled; a no-op otherwise. */\nexport async function flushIndex<T>(ctx: SearchContext<T>): Promise<void> {\n if (!ctx.searchIndexStore) return\n await ctx.ensureHydrated()\n const labelMaps = await resolveDictLabelMaps(ctx)\n const blobFilenames = await resolveBlobFilenames(ctx)\n await ctx.searchIndexStore.ensureBuilt(() => buildRetrievalDocs(ctx, labelMaps, blobFilenames))\n await ctx.searchIndexStore.flush?.()\n}\n\n/** L2 — load + decrypt all _vec sidecars into StoredVector[] for the VectorSet. */\nfunction buildVectorLoad<T>(ctx: SearchContext<T>): () => Promise<StoredVector[]> {\n return async () => {\n const ids = await ctx.adapter.list(ctx.vault, '_vec')\n const out: StoredVector[] = []\n for (const vecId of ids) {\n // #726: _vec is a vault-wide bucket namespaced by collection prefix —\n // skip rows belonging to other collections before touching this one's.\n if (!isVecIdFor(ctx.name, vecId)) continue\n const id = decodeVecId(ctx.name, vecId)!\n // #721 defense-in-depth: a _vec row carries no _tier of its own; the purge\n // on elevate is best-effort and cannot reach a legacy sidecar, so gate on\n // the owning record's live tier. Envelope peek, no decryption.\n if (await liveRecordIsElevated(ctx.adapter, ctx.vault, ctx.name, id)) continue\n const env = await ctx.adapter.get(ctx.vault, '_vec', vecId)\n if (!env) continue\n // #726 fails-safe: a row can pass isVecIdFor's prefix filter yet still\n // be undecryptable under THIS collection's DEK — a surviving legacy\n // bare-id row whose record id happens to start with `<thisCollection>/`,\n // or plain corruption. _vec sidecars are derived, re-derivable\n // artifacts (embedOnWrite regenerates them on the record's next put()),\n // so best-effort skip is correct: never let one poison row crash\n // similarTo()/retrieve() for the whole collection.\n let body: string | null\n try {\n body = await ctx.codec.decryptJsonString({ collection: '_vec', id: vecId }, env)\n } catch {\n continue\n }\n if (body === null) continue\n const parsed = JSON.parse(body) as { vec: number[]; model: string }\n out.push({ id, vec: new Float32Array(parsed.vec), model: parsed.model })\n }\n return out\n }\n}\n\n/**\n * L1.5 — build the PersistedIndexCallbacks bridge: crypto lives here\n * (collection has getDEK / encryptJsonString / decryptJsonString / adapter),\n * the index store itself is crypto-free.\n *\n * Fingerprint encoding: body-wrap approach — save(json, fp) stores\n * JSON.stringify({ fp, idx: json }) as the encrypted body so the standard\n * EncryptedEnvelope shape is never extended. load() decrypts and JSON.parses\n * the wrapper back out.\n *\n * Cache shape: ctx.cache stores { record, version } — currentFingerprint()\n * iterates over e.version.\n *\n * NOTE: this factory is invoked from the `Collection` constructor *before*\n * `this.codec` is assigned, so it takes a context THUNK and resolves the\n * context lazily inside each callback — by the time a callback actually runs,\n * the codec and cache are fully wired.\n */\nexport function buildPersistedIndexCallbacks<T>(provideCtx: () => SearchContext<T>): PersistedIndexCallbacks {\n const FT = '_ftindex'\n return {\n load: async () => {\n const ctx = provideCtx()\n const env = await ctx.adapter.get(ctx.vault, FT, ctx.name)\n if (!env) return null\n const body = await ctx.codec.decryptJsonString({ collection: FT, id: ctx.name }, env)\n if (body === null) return null\n try {\n const wrapped = JSON.parse(body) as { fp: { count: number; maxVersion: number }; idx: string }\n return { json: wrapped.idx, fingerprint: wrapped.fp }\n } catch {\n return null\n }\n },\n save: async (json, fp, isStale) => {\n const ctx = provideCtx()\n const body = JSON.stringify({ fp, idx: json })\n const env = await ctx.codec.encryptJsonString({ collection: FT, id: ctx.name }, body, fp.count)\n // #725 review: a purge (removePersisted) can land while the encrypt above was\n // in flight — check right before the write and skip it rather than resurrect a\n // purged/forgotten record's blob. PersistedIndexStore's own post-save epoch\n // check is the backstop for every other ordering (incl. a purge landing during\n // this very put).\n if (isStale()) return\n await ctx.adapter.put(ctx.vault, FT, ctx.name, env)\n },\n remove: async () => { const ctx = provideCtx(); await ctx.adapter.delete(ctx.vault, FT, ctx.name) },\n currentFingerprint: () => {\n const ctx = provideCtx()\n let maxVersion = 0\n for (const e of ctx.cache.values()) if (e.version > maxVersion) maxVersion = e.version\n return { count: ctx.cache.size, maxVersion }\n },\n }\n}\n\n/** L1 — pre-build the lexical index (e.g. on open) so the first retrieve() pays no build scan. */\nexport async function warmIndex<T>(ctx: SearchContext<T>): Promise<void> {\n if (!ctx.searchIndexStore) return\n if (ctx.lazy) {\n throw new Error(\n `Collection \"${ctx.name}\": warmIndex() requires eager mode (prefetch: true).`,\n )\n }\n await ctx.ensureHydrated()\n const built = ctx.searchIndexStore.built\n const labelMaps = built ? new Map() : await resolveDictLabelMaps(ctx)\n const blobFilenames = built ? new Map() : await resolveBlobFilenames(ctx)\n await ctx.searchIndexStore.ensureBuilt(() => buildRetrievalDocs(ctx, labelMaps, blobFilenames))\n}\n\n/** Retrieval. mode: 'lexical' (default) | 'semantic' (L2) | 'hybrid' (L3). */\nexport async function retrieve<T>(ctx: SearchContext<T>, query: string, opts: RetrieveOptions<T> = {}): Promise<RetrieveHit<T>[]> {\n const hits =\n opts.mode === 'semantic' ? await retrieveSemantic(ctx, query, opts)\n : opts.mode === 'hybrid' ? await retrieveHybrid(ctx, query, opts)\n : await retrieveLexical(ctx, query, opts)\n return opts.within ? applyWithin(hits, opts.within) : hits\n}\n\n/** L3 — keep only hits whose id matches the structured query, re-rank 1-based. */\nfunction applyWithin<T>(hits: RetrieveHit<T>[], within: Query<T>): RetrieveHit<T>[] {\n const ids = new Set(within._idArray())\n return hits.filter(h => ids.has(h.id)).map((h, i) => ({ ...h, rank: i + 1 }))\n}\n\n/** L1 — client-side lexical retrieval; ranked { id, score, field, snippet, locale? }. */\nasync function retrieveLexical<T>(ctx: SearchContext<T>, query: string, opts: RetrieveOptions<T>): Promise<RetrieveHit<T>[]> {\n if (!ctx.searchIndexStore) {\n throw new Error(`Collection \"${ctx.name}\": retrieve() requires a textIndexes config.`)\n }\n if (ctx.lazy) {\n throw new Error(\n `Collection \"${ctx.name}\": retrieve() requires eager mode (prefetch: true).`,\n )\n }\n await ctx.ensureHydrated()\n const built = ctx.searchIndexStore.built\n const labelMaps = built ? new Map() : await resolveDictLabelMaps(ctx)\n const blobFilenames = built ? new Map() : await resolveBlobFilenames(ctx)\n const index = await ctx.searchIndexStore.ensureBuilt(() => buildRetrievalDocs(ctx, labelMaps, blobFilenames))\n const hits = index.query(query, {\n ...(opts.limit !== undefined ? { limit: opts.limit } : {}),\n ...(opts.match ? { match: opts.match } : {}),\n ...(opts.prefix ? { prefix: opts.prefix } : {}),\n ...(opts.fields ? { fields: opts.fields } : {}),\n })\n const window = opts.snippetWindow ?? 80\n return hits.map((h: IndexHit, i: number) => {\n const base: RetrieveHit<T> = {\n id: h.id,\n score: h.score,\n rank: i + 1,\n field: h.field,\n snippet: extractSnippet(h.text, h.offset, window),\n ...(h.locale !== undefined ? { locale: h.locale } : {}),\n ...(opts.includeRecord\n ? (() => {\n const e = ctx.cache.get(h.id)\n return e ? { record: stripI18nFilled(e.record as Record<string, unknown>) as T } : {}\n })()\n : {}),\n }\n return base\n })\n}\n\n/** L3 — hybrid: fuse lexical (L1) + semantic (L2) by RRF. Requires embeddings. */\nasync function retrieveHybrid<T>(ctx: SearchContext<T>, query: string, opts: RetrieveOptions<T>): Promise<RetrieveHit<T>[]> {\n if (!ctx.embeddings) {\n throw new Error(`Collection \"${ctx.name}\": retrieve({mode:'hybrid'}) requires an embeddings config.`)\n }\n const [lex, sem] = await Promise.all([\n retrieveLexical(ctx, query, opts),\n retrieveSemantic(ctx, query, opts),\n ])\n return fuseRetrieval([lex, sem], opts.limit !== undefined ? { limit: opts.limit } : {})\n}\n\n/** L2 — semantic branch of retrieve(): encode query → similarTo(). */\nasync function retrieveSemantic<T>(ctx: SearchContext<T>, query: string, opts: RetrieveOptions<T>): Promise<RetrieveHit<T>[]> {\n if (!ctx.embeddings) throw new Error(`Collection \"${ctx.name}\": retrieve({mode:'semantic'}) requires an embeddings config.`)\n if (ctx.lazy) throw new Error(`Collection \"${ctx.name}\": retrieve() requires eager mode (prefetch: true).`)\n const qVec = await ctx.embeddings.encode(query)\n return similarTo(ctx, qVec, {\n ...(opts.limit !== undefined ? { k: opts.limit } : {}),\n ...(opts.minScore !== undefined ? { minScore: opts.minScore } : {}),\n ...(opts.includeRecord ? { includeRecord: true } : {}),\n })\n}\n\n/** L2 — raw-vector kNN over the encrypted vector set (decrypted in the trusted tier).\n * Snippet is '' for vector hits in v1 (semantic match isn't span-located). */\nexport async function similarTo<T>(ctx: SearchContext<T>, vector: Float32Array, opts: { k?: number; minScore?: number; includeRecord?: boolean } = {}): Promise<RetrieveHit<T>[]> {\n if (!ctx.embeddings || !ctx.vectorSet) throw new Error(`Collection \"${ctx.name}\": similarTo() requires an embeddings config.`)\n if (ctx.lazy) throw new Error(`Collection \"${ctx.name}\": similarTo() requires eager mode (prefetch: true).`)\n await ctx.ensureHydrated()\n await ctx.vectorSet.ensureLoaded(buildVectorLoad(ctx))\n const hits = ctx.vectorSet.cosineTopK(vector, opts.k ?? 10, {\n ...(opts.minScore !== undefined ? { minScore: opts.minScore } : {}),\n expectModel: ctx.embeddings.model,\n })\n return hits.map((h, i) => {\n const base: RetrieveHit<T> = { id: h.id, score: h.score, rank: i + 1, field: '(vector)', snippet: '' }\n if (opts.includeRecord) { const e = ctx.cache.get(h.id); if (e) (base as { record?: T }).record = stripI18nFilled(e.record as Record<string, unknown>) as T }\n return base\n })\n}\n\n/**\n * L2 — the embedding write-hook: derive a record's embedding vector at\n * write and persist it as the encrypted `_vec` side-car. Routed through the\n * search strategy so it runs only when `withSearch()` is opted in — computing\n * vectors that no gated `similarTo` / semantic `retrieve` could query would be\n * dead weight, so the compute is paired with the search capability. The caller\n * (`Collection.put`) only invokes this when `embeddings` is declared.\n */\nexport async function embedOnWrite<T>(ctx: SearchContext<T>, id: string, record: T, version: number): Promise<void> {\n if (!ctx.embeddings) return\n const text = embeddingSourceText(record as Record<string, unknown>, ctx.embeddings.source)\n const vec = await ctx.embeddings.encode(text)\n if (vec.length !== ctx.embeddings.dim) throw new EmbeddingDimMismatchError('embeddings', ctx.embeddings.dim, vec.length)\n const body = JSON.stringify({ vec: Array.from(vec), model: ctx.embeddings.model, dim: ctx.embeddings.dim })\n const vecEnv = await ctx.codec.encryptJsonString({ collection: '_vec', id: encodeVecId(ctx.name, id) }, body, version)\n await ctx.adapter.put(ctx.vault, '_vec', encodeVecId(ctx.name, id), vecEnv)\n ctx.vectorSet?.markDirty()\n}\n\n/**\n * Force-re-derive every eligible tier-0 record's `_vec` sidecar once (#788).\n * Opt-in bulk repair for the #726 re-namespace: legacy bare-id rows are\n * unreachable to `buildVectorLoad` (it only recognises `<collection>/<id>`\n * keys) and otherwise self-heal only when a record is next `put()` — this\n * lets an adopter recover recall immediately instead of waiting on writes.\n *\n * **Skips elevated records** (`liveRecordIsElevated`) rather than refusing\n * the whole walk — the OPPOSITE of `_applyCutoverTransform`'s\n * `assertCutoverTierSafe` refuse-whole-batch precedent. An elevated record is\n * SUPPOSED to have no `_vec` (`syncTierSearch` purges it on elevate);\n * re-embedding one here would write searchable plaintext-derived data above\n * tier 0. Load-bearing: never write a `_vec` row for an elevated record.\n *\n * Tombstones, delete markers, and a raw `get` racing a delete between `list`\n * and `get` all decrypt to `null` (`decryptRecord` already folds\n * tombstone/delete-marker into that null) and are skipped the same way.\n * Unconditional re-derive, no already-migrated check — safe to re-run after\n * a partial failure (each id is independently idempotent).\n */\nexport async function rebuildEmbeddings<T>(ctx: SearchContext<T>): Promise<{ rebuilt: number; skipped: number }> {\n if (!ctx.embeddings) return { rebuilt: 0, skipped: 0 }\n const ids = await ctx.adapter.list(ctx.vault, ctx.name)\n let rebuilt = 0\n let skipped = 0\n for (const id of ids) {\n if (await liveRecordIsElevated(ctx.adapter, ctx.vault, ctx.name, id)) { skipped++; continue }\n const env = await ctx.adapter.get(ctx.vault, ctx.name, id)\n if (!env) { skipped++; continue }\n const decoded = await ctx.codec.decryptRecord({ collection: ctx.name, id }, env)\n if (decoded === null) { skipped++; continue }\n await embedOnWrite(ctx, id, decoded, env._v ?? 1)\n rebuilt++\n }\n return { rebuilt, skipped }\n}\n\n/**\n * Sync the collection's SEARCH artifacts after a tier move (#721). Both the\n * lexical `_ftindex` blob and the `_vec/<id>` embedding are encrypted under\n * the tier-0 DEK and hold the record's derived plaintext (full field text /\n * a text-invertible vector), so leaving them means elevation never hid what\n * the record was searchable by — the `forget()` precedent, unapplied to\n * elevate. `null` → the record left tier 0: purge its `_vec` sidecar (mirrors\n * `Collection._purgeVector`), and invalidate the `_ftindex` blob (mirrors\n * `Collection._purgeSearchIndex`: deletes the persisted blob when persisted,\n * else drops the in-memory index) so the next `retrieve()` rebuilds from the\n * elevated-free `ctx.cache`. A record → it is tier-0 again: re-embed it via\n * {@link embedOnWrite}, then invalidate `_ftindex` so the rebuild includes it\n * again. No-op fast when the collection has neither a lexical index nor a\n * vector set.\n */\nexport async function syncTierSearch<T>(\n ctx: SearchContext<T>,\n id: string,\n record: T | null,\n version?: number,\n): Promise<void> {\n if (!ctx.searchIndexStore && !ctx.vectorSet) return\n if (record === null) {\n await ctx.adapter.delete(ctx.vault, '_vec', encodeVecId(ctx.name, id))\n ctx.vectorSet?.markDirty()\n } else {\n await embedOnWrite(ctx, id, record, version ?? 1)\n }\n const store = ctx.searchIndexStore\n if (store && 'removePersisted' in store) await (store as { removePersisted(): Promise<void> }).removePersisted()\n else store?.markDirty()\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/kernel/via/index.ts"],"sourcesContent":["// kernel/via/index.ts — the ONLY kernel-resident via surface.\nimport { NoydbError } from '../errors.js'\nimport type { EncryptedEnvelope } from '../types.js'\n\n/** Awaitable type for potentially async results. */\ntype Awaitable<T> = T | Promise<T>\n\n/** Declared security posture — a property the kernel enforces (enforcement activates in phases B/C). */\nexport interface ViaPosture {\n readonly encryptedAtRest: 'envelope' | 'sealed'\n readonly queryable: 'none' | 'det-exact' | 'ordered' | 'full'\n readonly exportable: boolean\n readonly forgettable: boolean\n}\n\n/** Opaque marker every feature descriptor extends; the kernel never sees concrete descriptor types. */\nexport interface ViaDescriptor { readonly _viaBrand: string }\n\n/** Per-call write context (A: minimal; B/C extend). */\nexport interface ViaWriteCtx {\n readonly id: string\n /** Owning vault name (event payload identity — e.g. i18n:script-violation). */\n readonly vault: string\n /** Prior stored record (decoded), lazily resolved. Null when creating. */\n readonly prior: () => Promise<Record<string, unknown> | null>\n /** Typed event emission (e.g. i18n:script-violation). */\n readonly emit: (event: string, payload: unknown) => void\n}\n\n/** Per-call read context — mirrors LocaleReadOptions loosely; features narrow. */\nexport interface ViaReadCtx {\n readonly locale?: unknown\n readonly fallback?: unknown\n readonly layer: string\n}\n\n/** One sealed slot's ciphertext — matches the existing `iv:data` sealed map entries (seam map §2 step 2). */\nexport interface SealedSlotRef { readonly iv: string; readonly data: string }\n\n/**\n * A scoped crypto capability handed to a `via` feature's `encodeAtRest`/\n * `decodeAtRest`/`erase` hooks — never the keyring, never the enclave.\n * `sealedSlots` is pre-bound to one `(collection, recordId)`; `reservedEnvelopes`\n * is a whole-envelope encrypt/decrypt door scoped to collection names under a\n * declared prefix (e.g. `_dict_`).\n */\nexport interface ViaCryptoCtx {\n readonly sealedSlots: {\n seal(field: string, plaintext: unknown): Promise<SealedSlotRef>\n unseal(field: string, ref: SealedSlotRef): Promise<unknown>\n delete(field: string): Promise<void>\n }\n reservedEnvelopes(prefix: string): {\n /**\n * `id` is the record id the envelope will be stored under. Required\n * (#1051) because this function holds the DEK, so it is where record-identity\n * AAD is applied — a caller that cannot name the id cannot be bound.\n */\n encrypt(\n identity: { readonly collection: string; readonly id: string; readonly by?: string },\n json: string,\n v: number,\n ): Promise<EncryptedEnvelope>\n decrypt(collection: string, id: string, env: EncryptedEnvelope): Promise<string>\n }\n}\n\n/** Per-call erase context — `forget()`'s per-ref participation door (phase C). */\nexport interface ViaEraseCtx { readonly id: string; readonly vault: string; readonly live: unknown /* EncryptedEnvelope */; readonly crypto: ViaCryptoCtx }\n/**\n * What an `erase` hook reports back to `forget()`'s summary ledger entry.\n * `retainedShared` is additive (#629 Task 10) — content NOT erased because\n * still referenced by another live record (blob's shared-chunk dual\n * accounting, `shredAllForRecord()`'s `retainedShared` count). Absent/0 for\n * bindings with no such concept (a sealed field is never \"shared\").\n */\nexport interface ViaEraseReport { readonly shredded: number; readonly residue: readonly unknown[]; readonly retainedShared?: number }\n\n/**\n * A feature bound to one collection's declared config. Record-grain hooks —\n * every hook receives the whole record (matches the real engine signatures,\n * e.g. quantizeMoneyFields(record, moneyFields)). All hooks optional;\n * absent = passthrough. Query-participation hooks are SYNC (#553).\n */\nexport interface NoydbVia {\n readonly brand: string\n readonly posture: ViaPosture\n /** Declared dependencies (field paths / cross-record specs). MANDATORY for any future\n * derive-bearing binding — phase C validates well-formedness (strings, non-empty,\n * reference declared fields) and graph-registers a derived edge for each covered\n * field at declare time, right after `compileVias` builds the bindings\n * (unknown source field throws `ValidationError`). See\n * `kernel/collection-config.ts`'s `resolveViaDepsEdges`. */\n readonly deps?: readonly string[]\n /** Collection-name prefixes this binding's `reservedEnvelopes` capability may address (e.g. `_dict_`). */\n readonly reservedPrefixes?: readonly string[]\n /**\n * Does this binding own `field`? Backs `ViaPipeline.postureFor` (#629 Task\n * 8's posture consumer) — a passive coverage check, independent of\n * `buildClause`/`compareForOrder` (which some bindings, e.g. classified and\n * blob, never define). SYNC, no side effects.\n *\n * Contract (documentation only — not enforced at runtime, future work):\n * any binding declaring a non-default posture value — `queryable: 'none'`\n * (#629 Task 8) or `exportable: false` (#629 Task 9's `redactForExport`)\n * — MUST implement `covers()`. `postureFor`'s consumers only engage for\n * fields a binding actively claims via `covers()`; a binding that omits\n * it would silently fall through to the generic (unrefused/unredacted)\n * path instead.\n */\n covers?(field: string): boolean\n // NOTE: phase C adds a `derive` hook ADDITIVELY — do not stub it now.\n // ── write pipeline ──\n /** Refuse a write before crypto runs (classified step-3 slot: storage:'never' rejection + validators). Throws to refuse. */\n enforceWrite?(record: Record<string, unknown>, ctx: ViaWriteCtx): void | Promise<void>\n /** First pipeline stage (money canonicalizeIncomingMoney). SYNC. */\n ingest?(record: Record<string, unknown>): Record<string, unknown>\n /** Decode STORED form to canonical for internal boundaries (gates, derivations, patch bases). SYNC. */\n canonicalizeStored?(record: Record<string, unknown>): Record<string, unknown>\n /** Post-validation write encoding (money quantize; i18n translate→script→validate→densify). May be async. */\n encodeWrite?(record: Record<string, unknown>, ctx: ViaWriteCtx): Awaitable<Record<string, unknown>>\n /** Final write-pipeline stage: seal/encrypt declared fields via `crypto` before the envelope body is built (classified step-2 slot). */\n encodeAtRest?(record: Record<string, unknown>, crypto: ViaCryptoCtx): Promise<{ record: Record<string, unknown>; sealed?: Record<string, SealedSlotRef> }>\n // ── read pipeline ──\n /** First read-pipeline stage: unseal/decrypt declared fields via `crypto` before `present` runs (classified sealed-handle slot). */\n decodeAtRest?(record: Record<string, unknown>, sealed: Record<string, SealedSlotRef>, crypto: ViaCryptoCtx, opts: { asHandles: boolean }): Promise<Record<string, unknown>>\n /** Read-time presentation (money decode+virtuals; i18n locale/labels/strip). May be async. */\n present?(record: Record<string, unknown>, ctx: ViaReadCtx): Awaitable<Record<string, unknown>>\n /**\n * Late read-time presentation (#669) — runs AFTER every binding's `present()` in the\n * money+computed present-order segment (`ViaPipeline`'s `_presentOrder`, `kernel/via/\n * pipeline.ts`), BEFORE the \"everything else\" segment (i18n/lookup dressing, taint\n * redaction) runs. Exists for a binding that needs to react to a virtual computed\n * field's fresh OWN-field output before anything dresses it (money's MAJOR-UNITS\n * quantize-and-present for a field that is BOTH money AND `mode:'virtual'` computed) —\n * `present()` alone can't express \"run after computed for THESE fields only, before\n * computed for all others\", since it's a per-BINDING fold, not per-field. Folded over\n * `bindings` in declaration order (mirrors every other per-binding fold), so lookup/\n * i18n dressing and taint/redaction (both in the \"everything else\" segment) still see\n * the already-dressed value.\n */\n presentLate?(record: Record<string, unknown>, ctx: ViaReadCtx): Awaitable<Record<string, unknown>>\n // ── query participation (ALL SYNC — #553) ──\n /** Returns an opaque clause payload when this binding covers `field`, else undefined. */\n // eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents\n buildClause?(field: string, op: string, value: unknown): unknown | undefined\n /** Evaluate a payload produced by buildClause against a raw stored value. */\n evaluateClause?(actual: unknown, op: string, payload: unknown): boolean\n /**\n * Optional: the STORED-form operand for a direct secondary-index probe\n * against a payload produced by `buildClause` (#625) — lets\n * `candidateRecords()` (`query/builder.ts`) hit `CollectionIndexes.\n * lookupEqual`/`lookupIn` for `==`/`in` clauses instead of falling back\n * to a linear scan + per-record `evaluateClause`. Returning `undefined`\n * means \"no sound probe for this op/payload\" (e.g. a comparison whose\n * stored form isn't a single index-bucketable value, or an op the index\n * can't serve) — the caller falls back to the scan. A binding that\n * never implements this hook always falls back, unchanged from before\n * this hook existed.\n */\n // eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents\n indexProbe?(op: string, payload: unknown): unknown | undefined\n /**\n * Optional: canonicalize a raw STORED field value into the bucket key an\n * eager index should use (#672) — lets `CollectionIndexes` group a\n * pre-declaration / non-canonical stored value (e.g. a money field's\n * leftover `'0100'` written before its `money()` declaration) under the\n * SAME key a canonical write produces (`'100'`), so the index-probe fast\n * path (`indexProbe` above) and the fallback scan (`evaluateClause`)\n * agree on which records match. `undefined` means \"not mine / can't\n * canonicalize this value\" — the caller buckets the raw stringified\n * value, unchanged from before this hook existed. MUST agree with what\n * this binding's own `evaluateClause`/`indexProbe` treat as equal, or\n * the fast path and the scan will disagree.\n */\n canonicalizeIndexKey?(field: string, rawValue: unknown): string | undefined\n /** Decode a raw stored record for query/scan results and callback views ('raw' — no virtuals). */\n decodeResults?(record: unknown): unknown\n /** Exact ordering for a covered field; undefined when the field is not covered. */\n compareForOrder?(field: string, a: unknown, b: unknown): number | undefined\n /**\n * Per-key, PER-CALL-locale label resolution for `orderBy(field, dir,\n * { by: 'label' })` (#650 Task 7) — the sibling `compareForOrder` above\n * structurally cannot serve, since it carries no locale parameter.\n * `locale` is the query's per-call locale (`undefined` for a locale-less\n * query — a binding may fall back to its own descriptor-level default,\n * mirroring `present`'s displayLocale hinge). `undefined` return = this\n * binding doesn't resolve a label for `key` at `field` — caller falls\n * back to the raw stored value, same graceful-degrade discipline every\n * other via query hook uses. SYNC (#553 — query participation).\n */\n resolveOrderLabel?(field: string, key: string, locale: string | undefined): string | undefined\n /** Rewrite an aggregate spec (money exact reducers). */\n wrapReducers?(spec: unknown): unknown\n // ── forget participation ──\n /** `forget()`'s per-ref erasure door — shred/report this binding's residue for one record (classified/blob forget participation). */\n erase?(ctx: ViaEraseCtx): Promise<ViaEraseReport>\n // ── introspection ──\n describeFragment?(): Record<string, unknown>\n}\n\n/** Binder: constructs a binding from a collection's declared config. Installed by the feature's declaration factory. */\nexport type ViaBinder = (config: unknown) => NoydbVia\n\nconst binders = new Map<string, ViaBinder>()\n\n/** @internal — called (idempotently, first-wins) by a feature's declaration factory, e.g. money(). */\nexport function installViaBinder(brand: string, binder: ViaBinder): void {\n if (!binders.has(brand)) binders.set(brand, binder)\n}\n\n/** @internal — registry presence check. Used by tests (mirrors isMoneyEngineInstalled) and by vault's i18n validator delegators as a no-i18n-ever-declared fast path. */\nexport function isViaInstalled(brand: string): boolean {\n return binders.has(brand)\n}\n\n/** @internal — resolve a binder; throws when the declaration factory never ran (hand-rolled descriptors). */\nexport function viaBinder(brand: string): ViaBinder {\n const b = binders.get(brand)\n if (!b) {\n throw new NoydbError(\n 'VIA_NOT_LINKED',\n `via feature \"${brand}\" requires descriptors created via its declaration factory from @noy-db/hub`,\n )\n }\n return b\n}\n"],"mappings":";;;;;AA4MA,IAAM,UAAU,oBAAI,IAAuB;AAGpC,SAAS,iBAAiB,OAAe,QAAyB;AACvE,MAAI,CAAC,QAAQ,IAAI,KAAK,EAAG,SAAQ,IAAI,OAAO,MAAM;AACpD;AAGO,SAAS,eAAe,OAAwB;AACrD,SAAO,QAAQ,IAAI,KAAK;AAC1B;AAGO,SAAS,UAAU,OAA0B;AAClD,QAAM,IAAI,QAAQ,IAAI,KAAK;AAC3B,MAAI,CAAC,GAAG;AACN,UAAM,IAAI;AAAA,MACR;AAAA,MACA,gBAAgB,KAAK;AAAA,IACvB;AAAA,EACF;AACA,SAAO;AACT;","names":[]}
|