@noy-db/hub 0.6.0-pre.22 → 0.6.0-pre.24
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 +84 -0
- package/dist/api-56KUWV6E.js +20 -0
- package/dist/attestation/index.js +18 -18
- package/dist/{backup-4PZAH67W.js → backup-WLKPDY3V.js} +12 -12
- package/dist/blobs/index.js +22 -20
- package/dist/blobs/index.js.map +1 -1
- package/dist/broker/index.js +12 -12
- package/dist/cargo/index.js +29 -29
- package/dist/{chunk-PNXJV4OS.js → chunk-24ZDSTEQ.js} +41 -17
- package/dist/chunk-24ZDSTEQ.js.map +1 -0
- package/dist/{chunk-4RZTW5JH.js → chunk-25HI46CB.js} +2 -2
- package/dist/{chunk-PWK3SSNB.js → chunk-264AKW4K.js} +4 -4
- package/dist/{chunk-7LJA7T4W.js → chunk-2CURJCLC.js} +3 -3
- package/dist/{chunk-YF3CIA6E.js → chunk-2D5NXYWY.js} +2 -2
- package/dist/{chunk-REQJLII3.js → chunk-2MYYXXVM.js} +2 -2
- package/dist/{chunk-DIYI32MG.js → chunk-2S6HROLU.js} +5 -5
- package/dist/{chunk-23XKHFNT.js → chunk-2ZSBPXFW.js} +3 -3
- package/dist/{chunk-XZZIZ544.js → chunk-34MSA4AO.js} +51 -16
- package/dist/chunk-34MSA4AO.js.map +1 -0
- package/dist/{chunk-BXHG26KN.js → chunk-35K4VWMD.js} +2 -2
- package/dist/{chunk-DIVPOJPV.js → chunk-43FOH2OK.js} +20 -8
- package/dist/chunk-43FOH2OK.js.map +1 -0
- package/dist/{chunk-UQUWSM33.js → chunk-4P3OG2AO.js} +5 -5
- package/dist/{chunk-KYUKZIW5.js → chunk-4Y7VHLCT.js} +2 -2
- package/dist/{chunk-RJYPFCID.js → chunk-576CTQ77.js} +5 -5
- package/dist/{chunk-OCW3IM2F.js → chunk-57MEX4LL.js} +3 -3
- package/dist/{chunk-PKUJ3JLQ.js → chunk-5OFC3QYL.js} +19 -2
- package/dist/chunk-5OFC3QYL.js.map +1 -0
- package/dist/{chunk-4O52JH3C.js → chunk-65WBEFVT.js} +6 -6
- package/dist/{chunk-JSTQGUE5.js → chunk-6J7SSCJW.js} +15 -10
- package/dist/chunk-6J7SSCJW.js.map +1 -0
- package/dist/{chunk-7JOXCSDU.js → chunk-6PLCNLBC.js} +2 -2
- package/dist/{chunk-QK2QAMF7.js → chunk-ACIEKVFR.js} +10 -10
- package/dist/{chunk-JPVJTTHU.js → chunk-AKPIBKHK.js} +4 -4
- package/dist/{chunk-AELW6OJZ.js → chunk-AM6V36AG.js} +2 -2
- package/dist/{chunk-DUUARUZI.js → chunk-AU45F5FD.js} +2 -2
- package/dist/{chunk-4BYZIQ5T.js → chunk-BZKQRED6.js} +2 -2
- package/dist/{chunk-OZ5QBLEL.js → chunk-C3FCXXNI.js} +6 -6
- package/dist/{chunk-FKZI4NSG.js → chunk-C4DFJ76X.js} +6 -6
- package/dist/{chunk-PGHSH4TY.js → chunk-CDHX3SRW.js} +3 -3
- package/dist/{chunk-O5QXH7U7.js → chunk-D7STIWJO.js} +11 -2
- package/dist/chunk-D7STIWJO.js.map +1 -0
- package/dist/{chunk-VMYXYFPX.js → chunk-DBPQUICN.js} +2 -2
- package/dist/{chunk-3TWEXEKX.js → chunk-DL7NXFAY.js} +2 -2
- package/dist/{chunk-2VMCJUK6.js → chunk-DM2BZDNV.js} +5 -5
- package/dist/{chunk-FFSQFH6D.js → chunk-DNKVKO7K.js} +2 -2
- package/dist/{chunk-IPA6ODWG.js → chunk-E2LYQUB7.js} +4 -4
- package/dist/{chunk-ANYVM4SX.js → chunk-ENTVT7PF.js} +2 -2
- package/dist/{chunk-M3FKPVOU.js → chunk-ESP4K32V.js} +3 -3
- package/dist/{chunk-A66LJYFG.js → chunk-FEWCVAFV.js} +131 -17
- package/dist/chunk-FEWCVAFV.js.map +1 -0
- package/dist/{chunk-H27DIXOV.js → chunk-FJGNYSB3.js} +6 -6
- package/dist/{chunk-OBPL43F3.js → chunk-FKLKAO2C.js} +54 -7
- package/dist/chunk-FKLKAO2C.js.map +1 -0
- package/dist/{chunk-PENPHA45.js → chunk-FX3UIDCS.js} +2 -2
- package/dist/{chunk-H3SEW5HB.js → chunk-G3ZMEUWD.js} +7 -7
- package/dist/{chunk-ZAZW5LLF.js → chunk-GCTZNHDO.js} +2 -2
- package/dist/{chunk-D5EXZVQC.js → chunk-GDYDYUO7.js} +6 -6
- package/dist/{chunk-47F6AI2K.js → chunk-GU5XWSH4.js} +3 -3
- package/dist/{chunk-6ZGDIN2D.js → chunk-H6J6MZ4J.js} +3 -3
- package/dist/{chunk-ZUDIY7YP.js → chunk-HMS3OCMA.js} +7 -7
- package/dist/{chunk-H6K24KLL.js → chunk-HUAAYTVS.js} +4 -4
- package/dist/{chunk-2DFE4TUE.js → chunk-HUDP5NSI.js} +4 -4
- package/dist/{chunk-VKYEEJJ2.js → chunk-HWJZCZSI.js} +2 -2
- package/dist/{chunk-NB2CKJ27.js → chunk-ICGLT356.js} +2 -2
- package/dist/{chunk-CW3VJARJ.js → chunk-IYXP6OR5.js} +3 -3
- package/dist/{chunk-A5YEUQOY.js → chunk-JSJS7RHS.js} +2 -2
- package/dist/{chunk-NHXIFF4Y.js → chunk-K6J7JKZM.js} +7 -7
- package/dist/{chunk-LLLSK7UQ.js → chunk-K7HPGV5K.js} +2 -2
- package/dist/{chunk-F3BICEMK.js → chunk-KC3S3OH6.js} +2 -2
- package/dist/{chunk-HZIIDYJV.js → chunk-KEMD6B3W.js} +4 -4
- package/dist/{chunk-SRR22EW2.js → chunk-L34HKPIS.js} +8 -8
- package/dist/{chunk-AGETRKC5.js → chunk-LG2P6S32.js} +3 -3
- package/dist/{chunk-FUIG7QSS.js → chunk-LT26SRU5.js} +4 -4
- package/dist/{chunk-6QMOJTC6.js → chunk-LTC77D4V.js} +2 -2
- package/dist/{chunk-QTWWZ25B.js → chunk-LU2HAOVP.js} +18 -14
- package/dist/chunk-LU2HAOVP.js.map +1 -0
- package/dist/{chunk-QMJI5VHV.js → chunk-M3XEJJDE.js} +2 -2
- package/dist/{chunk-VWPJX5B3.js → chunk-MGIAYREB.js} +5 -5
- package/dist/{chunk-VYLC5KAT.js → chunk-MLTGIDNB.js} +2 -2
- package/dist/{chunk-L2YYIQYR.js → chunk-MXJMCTSI.js} +2 -2
- package/dist/{chunk-F5IFR56V.js → chunk-NFARMKWK.js} +34 -12
- package/dist/chunk-NFARMKWK.js.map +1 -0
- package/dist/{chunk-IUQPNAGR.js → chunk-NK7DO6A2.js} +3 -3
- package/dist/{chunk-TKLQWOTY.js → chunk-NKND2IMW.js} +2 -2
- package/dist/{chunk-WUNRUSBJ.js → chunk-NSZGZYZL.js} +13 -3
- package/dist/{chunk-WUNRUSBJ.js.map → chunk-NSZGZYZL.js.map} +1 -1
- package/dist/{chunk-XPTYXXMD.js → chunk-NUHIPODK.js} +2 -2
- package/dist/{chunk-REKDM67V.js → chunk-ODGV6Q6U.js} +2 -2
- package/dist/{chunk-WRGNEAUZ.js → chunk-OJYLLNQN.js} +2 -2
- package/dist/{chunk-NCAMIRFB.js → chunk-OQT3G55N.js} +2 -2
- package/dist/{chunk-BPLSGN4X.js → chunk-PORGC5MH.js} +2 -2
- package/dist/{chunk-BFNBYT62.js → chunk-PRBJ4BJD.js} +2 -2
- package/dist/{chunk-4IPP2P74.js → chunk-PU5PNTE2.js} +2 -2
- package/dist/{chunk-L3AM6EGU.js → chunk-PZEDIO72.js} +7 -7
- package/dist/{chunk-M7VSXBUL.js → chunk-RTBCWDJ3.js} +10 -10
- package/dist/{chunk-OTHHO3KI.js → chunk-S2I5MYSA.js} +2 -2
- package/dist/{chunk-FHEVZQQY.js → chunk-S447GUNV.js} +4 -4
- package/dist/{chunk-WKT7NNNR.js → chunk-SP3AFEB7.js} +4 -4
- package/dist/{chunk-KMGAFLCK.js → chunk-SQWXF2HP.js} +5 -5
- package/dist/{chunk-HRSEAGLI.js → chunk-TTGZ6KGY.js} +3 -3
- package/dist/{chunk-MQFKH3ZJ.js → chunk-UHFF4G53.js} +3 -3
- package/dist/{chunk-IGNJOJEP.js → chunk-UJ4Z67UQ.js} +2 -2
- package/dist/chunk-UJ4Z67UQ.js.map +1 -0
- package/dist/{chunk-FGZ7GJXO.js → chunk-VZEBHQRT.js} +3 -3
- package/dist/{chunk-HUEG3YP4.js → chunk-VZHEFFUO.js} +97 -82
- package/dist/chunk-VZHEFFUO.js.map +1 -0
- package/dist/{chunk-OIW75CLW.js → chunk-WN377AAV.js} +6 -6
- package/dist/{chunk-ESXVNASI.js → chunk-XCNYOVFV.js} +5 -5
- package/dist/{chunk-FFESJQ5A.js → chunk-YEEV4ZXL.js} +95 -32
- package/dist/chunk-YEEV4ZXL.js.map +1 -0
- package/dist/{chunk-YOMI3ZCA.js → chunk-YIC34H3M.js} +2 -2
- package/dist/{chunk-MBZFAJKM.js → chunk-YZWRJRMF.js} +6 -2
- package/dist/chunk-YZWRJRMF.js.map +1 -0
- package/dist/{chunk-GWJJ5CK3.js → chunk-Z45PK2H5.js} +5 -5
- package/dist/{chunk-RT7CWTUG.js → chunk-ZI43U6FN.js} +6 -6
- package/dist/{chunk-WFC2GHJG.js → chunk-ZJJ46LNY.js} +3 -3
- package/dist/{chunk-3ENNPCIW.js → chunk-ZY6P7M52.js} +2 -2
- package/dist/classified/index.js +5 -5
- package/dist/{classified-marker-EPL2NX3H.js → classified-marker-DLLGRRXG.js} +3 -3
- package/dist/collection-facade-OHBCHCJV.js +45 -0
- package/dist/{computed-UXN4AMI5.js → computed-X2RKYFGX.js} +3 -3
- package/dist/consent/index.js +9 -9
- package/dist/cover/index.js +9 -9
- package/dist/custody/index.js +12 -11
- package/dist/{dead-filter-56AYTNAO.js → dead-filter-CCLDPNTJ.js} +2 -2
- package/dist/debug/index.js +1 -1
- package/dist/{delegation-MCCWCFZA.js → delegation-OSXUSSUO.js} +11 -11
- package/dist/derivations/index.js +12 -12
- package/dist/derive-6K35IOIN.js +22 -0
- package/dist/directory/index.js +10 -10
- package/dist/{dispatch-JM7X5BLP.js → dispatch-HCCQPOC7.js} +9 -6
- package/dist/dispatch-HCCQPOC7.js.map +1 -0
- package/dist/{dispatch-UPZW4MAO.js → dispatch-TRXQIBLA.js} +18 -18
- package/dist/{enclave-CCXI3WEU.js → enclave-K33BCSHB.js} +13 -9
- package/dist/executor-44ONIZTV.js +9 -0
- package/dist/executor-H7KLBIJN.js +9 -0
- package/dist/executor-PDK7IAPQ.js +29 -0
- package/dist/export-accessible-2LJH6JTI.js +23 -0
- package/dist/extract-partition-QQFOPCJ6.js +38 -0
- package/dist/{fanout-sidecar-2EHAV6UP.js → fanout-sidecar-ORVUHI3J.js} +9 -9
- package/dist/find-H6GHRBNL.js +11 -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 +1 -1
- package/dist/index.js +93 -91
- package/dist/index.js.map +1 -1
- package/dist/indexing/index.js +2 -2
- package/dist/introspection/index.js +11 -11
- package/dist/issue-LV2IWCKY.js +19 -0
- package/dist/kernel/collection.d.ts +8 -2
- package/dist/kernel/constants.d.ts +18 -0
- package/dist/kernel/enclave/crypto.d.ts +28 -0
- package/dist/kernel/enclave/index.d.ts +2 -2
- package/dist/kernel/enclave/record-keys/rekey.d.ts +23 -0
- package/dist/kernel/errors.d.ts +41 -0
- package/dist/kernel/refs.d.ts +3 -1
- package/dist/kernel/tier-visibility.d.ts +19 -0
- package/dist/kernel/types.d.ts +1 -1
- package/dist/kernel/via/reconcile.d.ts +12 -0
- package/dist/{ledger-TZIDVW22.js → ledger-RM5672K4.js} +11 -11
- package/dist/liberate-PNPIQ45H.js +25 -0
- package/dist/{link-set-VOMRQB2H.js → link-set-AZ6VDH5X.js} +11 -11
- package/dist/{managed-secret-N6FWB5LX.js → managed-secret-QZKTYCLD.js} +10 -10
- package/dist/materialized-views/index.js +20 -20
- package/dist/{migrate-cek-UEO2EUWI.js → migrate-cek-BVAPYJ5T.js} +2 -2
- package/dist/money/index.js +4 -4
- package/dist/noydb-QZN7G26J.js +85 -0
- package/dist/overlay-views/index.js +4 -4
- package/dist/periods/index.js +12 -12
- package/dist/pod/index.js +56 -55
- package/dist/{pod-handle-D6ZRTO4N.js → pod-handle-LVSMK4XC.js} +9 -9
- package/dist/policy/index.js +10 -10
- package/dist/portability/index.js +8 -8
- package/dist/{post-register-XVGHYYSB.js → post-register-TZGQ34YR.js} +6 -6
- package/dist/query/index.js +3 -3
- package/dist/reduce/index.js +4 -4
- package/dist/register-IQJGJSQQ.js +32 -0
- package/dist/registry-3JY3YSMU.js +9 -0
- package/dist/registry-G365BQDC.js +19 -0
- package/dist/registry-HVS6PGHV.js +9 -0
- package/dist/registry-TQ5FRB4T.js +18 -0
- package/dist/request-withdrawal-XQCCKMB3.js +31 -0
- package/dist/{reveal-Z62PLVJT.js → reveal-5PXWDCLZ.js} +6 -6
- package/dist/revoke-6NSQWTED.js +24 -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 +4 -4
- package/dist/{seed-R2JK2YQK.js → seed-ZLOK3Z4M.js} +12 -11
- package/dist/{seed-R2JK2YQK.js.map → seed-ZLOK3Z4M.js.map} +1 -1
- package/dist/sequence/index.js +9 -9
- package/dist/session/index.js +9 -9
- package/dist/shadow/index.js +2 -2
- package/dist/signer-AJ3MCSPI.js +25 -0
- package/dist/snapshots/index.js +10 -10
- package/dist/{stale-FVK3WRMM.js → stale-KQR5QAYJ.js} +10 -10
- package/dist/storage-GACYAH6W.js +23 -0
- package/dist/{store-coordination-provider-HIPOZMC2.js → store-coordination-provider-RII4H3PJ.js} +10 -10
- package/dist/sync/index.js +10 -10
- package/dist/team/index.js +15 -15
- package/dist/tiers/index.js +11 -11
- package/dist/to/index.js +1 -1
- 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-KYICK5IW.js → verify-OMPYUO7C.js} +5 -5
- package/dist/via/blob/index.d.ts +3 -0
- package/dist/walk-ZYC74R65.js +21 -0
- package/dist/with-formula/materialized-views/dependency-analyzer.d.ts +4 -0
- package/dist/with-formula/materialized-views/projection-legs.d.ts +59 -0
- package/dist/with-formula/materialized-views/registry.d.ts +50 -0
- package/dist/with-formula/materialized-views/types.d.ts +68 -10
- package/dist/with-party/team/roster-tag.d.ts +1 -1
- package/dist/with-shape/blobs/blob-compaction.d.ts +13 -0
- package/dist/with-shape/blobs/blob-set.d.ts +23 -3
- package/dist/with-shape/blobs/orphan-report.d.ts +62 -0
- package/dist/withdraw-accessible-MEFFAGRD.js +28 -0
- package/package.json +3 -3
- package/dist/api-D6DBNTOS.js +0 -20
- package/dist/chunk-A66LJYFG.js.map +0 -1
- package/dist/chunk-DIVPOJPV.js.map +0 -1
- package/dist/chunk-F5IFR56V.js.map +0 -1
- package/dist/chunk-FFESJQ5A.js.map +0 -1
- package/dist/chunk-HUEG3YP4.js.map +0 -1
- package/dist/chunk-IGNJOJEP.js.map +0 -1
- package/dist/chunk-JSTQGUE5.js.map +0 -1
- package/dist/chunk-MBZFAJKM.js.map +0 -1
- package/dist/chunk-O5QXH7U7.js.map +0 -1
- package/dist/chunk-OBPL43F3.js.map +0 -1
- package/dist/chunk-PKUJ3JLQ.js.map +0 -1
- package/dist/chunk-PNXJV4OS.js.map +0 -1
- package/dist/chunk-QTWWZ25B.js.map +0 -1
- package/dist/chunk-XZZIZ544.js.map +0 -1
- package/dist/collection-facade-3DN4ETEP.js +0 -45
- package/dist/derive-BSAF6N5X.js +0 -22
- package/dist/dispatch-JM7X5BLP.js.map +0 -1
- package/dist/executor-6YQYFGHK.js +0 -9
- package/dist/executor-GLKPMISJ.js +0 -9
- package/dist/executor-ZEIX7Y7I.js +0 -29
- package/dist/export-accessible-SDIQEFHQ.js +0 -23
- package/dist/extract-partition-K232SO2V.js +0 -38
- package/dist/find-GKFC5753.js +0 -11
- package/dist/issue-QTQYQJCB.js +0 -19
- package/dist/liberate-FOK7RFYQ.js +0 -24
- package/dist/noydb-3BBLBSHI.js +0 -84
- package/dist/register-FVUE46K4.js +0 -32
- package/dist/registry-7PBVHSD5.js +0 -19
- package/dist/registry-CCXD57GV.js +0 -18
- package/dist/registry-K75FRKSU.js +0 -9
- package/dist/registry-KZYPKIOF.js +0 -9
- package/dist/request-withdrawal-WS7PXD7B.js +0 -31
- package/dist/revoke-JH4VQTJ3.js +0 -24
- package/dist/signer-AFV6AXSN.js +0 -25
- package/dist/storage-EIM5HO2O.js +0 -23
- package/dist/walk-FV6JFWXV.js +0 -21
- package/dist/withdraw-accessible-JYX3SPVY.js +0 -28
- /package/dist/{api-D6DBNTOS.js.map → api-56KUWV6E.js.map} +0 -0
- /package/dist/{backup-4PZAH67W.js.map → backup-WLKPDY3V.js.map} +0 -0
- /package/dist/{chunk-4RZTW5JH.js.map → chunk-25HI46CB.js.map} +0 -0
- /package/dist/{chunk-PWK3SSNB.js.map → chunk-264AKW4K.js.map} +0 -0
- /package/dist/{chunk-7LJA7T4W.js.map → chunk-2CURJCLC.js.map} +0 -0
- /package/dist/{chunk-YF3CIA6E.js.map → chunk-2D5NXYWY.js.map} +0 -0
- /package/dist/{chunk-REQJLII3.js.map → chunk-2MYYXXVM.js.map} +0 -0
- /package/dist/{chunk-DIYI32MG.js.map → chunk-2S6HROLU.js.map} +0 -0
- /package/dist/{chunk-23XKHFNT.js.map → chunk-2ZSBPXFW.js.map} +0 -0
- /package/dist/{chunk-BXHG26KN.js.map → chunk-35K4VWMD.js.map} +0 -0
- /package/dist/{chunk-UQUWSM33.js.map → chunk-4P3OG2AO.js.map} +0 -0
- /package/dist/{chunk-KYUKZIW5.js.map → chunk-4Y7VHLCT.js.map} +0 -0
- /package/dist/{chunk-RJYPFCID.js.map → chunk-576CTQ77.js.map} +0 -0
- /package/dist/{chunk-OCW3IM2F.js.map → chunk-57MEX4LL.js.map} +0 -0
- /package/dist/{chunk-4O52JH3C.js.map → chunk-65WBEFVT.js.map} +0 -0
- /package/dist/{chunk-7JOXCSDU.js.map → chunk-6PLCNLBC.js.map} +0 -0
- /package/dist/{chunk-QK2QAMF7.js.map → chunk-ACIEKVFR.js.map} +0 -0
- /package/dist/{chunk-JPVJTTHU.js.map → chunk-AKPIBKHK.js.map} +0 -0
- /package/dist/{chunk-AELW6OJZ.js.map → chunk-AM6V36AG.js.map} +0 -0
- /package/dist/{chunk-DUUARUZI.js.map → chunk-AU45F5FD.js.map} +0 -0
- /package/dist/{chunk-4BYZIQ5T.js.map → chunk-BZKQRED6.js.map} +0 -0
- /package/dist/{chunk-OZ5QBLEL.js.map → chunk-C3FCXXNI.js.map} +0 -0
- /package/dist/{chunk-FKZI4NSG.js.map → chunk-C4DFJ76X.js.map} +0 -0
- /package/dist/{chunk-PGHSH4TY.js.map → chunk-CDHX3SRW.js.map} +0 -0
- /package/dist/{chunk-VMYXYFPX.js.map → chunk-DBPQUICN.js.map} +0 -0
- /package/dist/{chunk-3TWEXEKX.js.map → chunk-DL7NXFAY.js.map} +0 -0
- /package/dist/{chunk-2VMCJUK6.js.map → chunk-DM2BZDNV.js.map} +0 -0
- /package/dist/{chunk-FFSQFH6D.js.map → chunk-DNKVKO7K.js.map} +0 -0
- /package/dist/{chunk-IPA6ODWG.js.map → chunk-E2LYQUB7.js.map} +0 -0
- /package/dist/{chunk-ANYVM4SX.js.map → chunk-ENTVT7PF.js.map} +0 -0
- /package/dist/{chunk-M3FKPVOU.js.map → chunk-ESP4K32V.js.map} +0 -0
- /package/dist/{chunk-H27DIXOV.js.map → chunk-FJGNYSB3.js.map} +0 -0
- /package/dist/{chunk-PENPHA45.js.map → chunk-FX3UIDCS.js.map} +0 -0
- /package/dist/{chunk-H3SEW5HB.js.map → chunk-G3ZMEUWD.js.map} +0 -0
- /package/dist/{chunk-ZAZW5LLF.js.map → chunk-GCTZNHDO.js.map} +0 -0
- /package/dist/{chunk-D5EXZVQC.js.map → chunk-GDYDYUO7.js.map} +0 -0
- /package/dist/{chunk-47F6AI2K.js.map → chunk-GU5XWSH4.js.map} +0 -0
- /package/dist/{chunk-6ZGDIN2D.js.map → chunk-H6J6MZ4J.js.map} +0 -0
- /package/dist/{chunk-ZUDIY7YP.js.map → chunk-HMS3OCMA.js.map} +0 -0
- /package/dist/{chunk-H6K24KLL.js.map → chunk-HUAAYTVS.js.map} +0 -0
- /package/dist/{chunk-2DFE4TUE.js.map → chunk-HUDP5NSI.js.map} +0 -0
- /package/dist/{chunk-VKYEEJJ2.js.map → chunk-HWJZCZSI.js.map} +0 -0
- /package/dist/{chunk-NB2CKJ27.js.map → chunk-ICGLT356.js.map} +0 -0
- /package/dist/{chunk-CW3VJARJ.js.map → chunk-IYXP6OR5.js.map} +0 -0
- /package/dist/{chunk-A5YEUQOY.js.map → chunk-JSJS7RHS.js.map} +0 -0
- /package/dist/{chunk-NHXIFF4Y.js.map → chunk-K6J7JKZM.js.map} +0 -0
- /package/dist/{chunk-LLLSK7UQ.js.map → chunk-K7HPGV5K.js.map} +0 -0
- /package/dist/{chunk-F3BICEMK.js.map → chunk-KC3S3OH6.js.map} +0 -0
- /package/dist/{chunk-HZIIDYJV.js.map → chunk-KEMD6B3W.js.map} +0 -0
- /package/dist/{chunk-SRR22EW2.js.map → chunk-L34HKPIS.js.map} +0 -0
- /package/dist/{chunk-AGETRKC5.js.map → chunk-LG2P6S32.js.map} +0 -0
- /package/dist/{chunk-FUIG7QSS.js.map → chunk-LT26SRU5.js.map} +0 -0
- /package/dist/{chunk-6QMOJTC6.js.map → chunk-LTC77D4V.js.map} +0 -0
- /package/dist/{chunk-QMJI5VHV.js.map → chunk-M3XEJJDE.js.map} +0 -0
- /package/dist/{chunk-VWPJX5B3.js.map → chunk-MGIAYREB.js.map} +0 -0
- /package/dist/{chunk-VYLC5KAT.js.map → chunk-MLTGIDNB.js.map} +0 -0
- /package/dist/{chunk-L2YYIQYR.js.map → chunk-MXJMCTSI.js.map} +0 -0
- /package/dist/{chunk-IUQPNAGR.js.map → chunk-NK7DO6A2.js.map} +0 -0
- /package/dist/{chunk-TKLQWOTY.js.map → chunk-NKND2IMW.js.map} +0 -0
- /package/dist/{chunk-XPTYXXMD.js.map → chunk-NUHIPODK.js.map} +0 -0
- /package/dist/{chunk-REKDM67V.js.map → chunk-ODGV6Q6U.js.map} +0 -0
- /package/dist/{chunk-WRGNEAUZ.js.map → chunk-OJYLLNQN.js.map} +0 -0
- /package/dist/{chunk-NCAMIRFB.js.map → chunk-OQT3G55N.js.map} +0 -0
- /package/dist/{chunk-BPLSGN4X.js.map → chunk-PORGC5MH.js.map} +0 -0
- /package/dist/{chunk-BFNBYT62.js.map → chunk-PRBJ4BJD.js.map} +0 -0
- /package/dist/{chunk-4IPP2P74.js.map → chunk-PU5PNTE2.js.map} +0 -0
- /package/dist/{chunk-L3AM6EGU.js.map → chunk-PZEDIO72.js.map} +0 -0
- /package/dist/{chunk-M7VSXBUL.js.map → chunk-RTBCWDJ3.js.map} +0 -0
- /package/dist/{chunk-OTHHO3KI.js.map → chunk-S2I5MYSA.js.map} +0 -0
- /package/dist/{chunk-FHEVZQQY.js.map → chunk-S447GUNV.js.map} +0 -0
- /package/dist/{chunk-WKT7NNNR.js.map → chunk-SP3AFEB7.js.map} +0 -0
- /package/dist/{chunk-KMGAFLCK.js.map → chunk-SQWXF2HP.js.map} +0 -0
- /package/dist/{chunk-HRSEAGLI.js.map → chunk-TTGZ6KGY.js.map} +0 -0
- /package/dist/{chunk-MQFKH3ZJ.js.map → chunk-UHFF4G53.js.map} +0 -0
- /package/dist/{chunk-FGZ7GJXO.js.map → chunk-VZEBHQRT.js.map} +0 -0
- /package/dist/{chunk-OIW75CLW.js.map → chunk-WN377AAV.js.map} +0 -0
- /package/dist/{chunk-ESXVNASI.js.map → chunk-XCNYOVFV.js.map} +0 -0
- /package/dist/{chunk-YOMI3ZCA.js.map → chunk-YIC34H3M.js.map} +0 -0
- /package/dist/{chunk-GWJJ5CK3.js.map → chunk-Z45PK2H5.js.map} +0 -0
- /package/dist/{chunk-RT7CWTUG.js.map → chunk-ZI43U6FN.js.map} +0 -0
- /package/dist/{chunk-WFC2GHJG.js.map → chunk-ZJJ46LNY.js.map} +0 -0
- /package/dist/{chunk-3ENNPCIW.js.map → chunk-ZY6P7M52.js.map} +0 -0
- /package/dist/{classified-marker-EPL2NX3H.js.map → classified-marker-DLLGRRXG.js.map} +0 -0
- /package/dist/{collection-facade-3DN4ETEP.js.map → collection-facade-OHBCHCJV.js.map} +0 -0
- /package/dist/{computed-UXN4AMI5.js.map → computed-X2RKYFGX.js.map} +0 -0
- /package/dist/{dead-filter-56AYTNAO.js.map → dead-filter-CCLDPNTJ.js.map} +0 -0
- /package/dist/{delegation-MCCWCFZA.js.map → delegation-OSXUSSUO.js.map} +0 -0
- /package/dist/{derive-BSAF6N5X.js.map → derive-6K35IOIN.js.map} +0 -0
- /package/dist/{dispatch-UPZW4MAO.js.map → dispatch-TRXQIBLA.js.map} +0 -0
- /package/dist/{enclave-CCXI3WEU.js.map → enclave-K33BCSHB.js.map} +0 -0
- /package/dist/{executor-6YQYFGHK.js.map → executor-44ONIZTV.js.map} +0 -0
- /package/dist/{executor-GLKPMISJ.js.map → executor-H7KLBIJN.js.map} +0 -0
- /package/dist/{executor-ZEIX7Y7I.js.map → executor-PDK7IAPQ.js.map} +0 -0
- /package/dist/{export-accessible-SDIQEFHQ.js.map → export-accessible-2LJH6JTI.js.map} +0 -0
- /package/dist/{extract-partition-K232SO2V.js.map → extract-partition-QQFOPCJ6.js.map} +0 -0
- /package/dist/{fanout-sidecar-2EHAV6UP.js.map → fanout-sidecar-ORVUHI3J.js.map} +0 -0
- /package/dist/{find-GKFC5753.js.map → find-H6GHRBNL.js.map} +0 -0
- /package/dist/{issue-QTQYQJCB.js.map → issue-LV2IWCKY.js.map} +0 -0
- /package/dist/{ledger-TZIDVW22.js.map → ledger-RM5672K4.js.map} +0 -0
- /package/dist/{liberate-FOK7RFYQ.js.map → liberate-PNPIQ45H.js.map} +0 -0
- /package/dist/{link-set-VOMRQB2H.js.map → link-set-AZ6VDH5X.js.map} +0 -0
- /package/dist/{managed-secret-N6FWB5LX.js.map → managed-secret-QZKTYCLD.js.map} +0 -0
- /package/dist/{migrate-cek-UEO2EUWI.js.map → migrate-cek-BVAPYJ5T.js.map} +0 -0
- /package/dist/{noydb-3BBLBSHI.js.map → noydb-QZN7G26J.js.map} +0 -0
- /package/dist/{pod-handle-D6ZRTO4N.js.map → pod-handle-LVSMK4XC.js.map} +0 -0
- /package/dist/{post-register-XVGHYYSB.js.map → post-register-TZGQ34YR.js.map} +0 -0
- /package/dist/{register-FVUE46K4.js.map → register-IQJGJSQQ.js.map} +0 -0
- /package/dist/{registry-7PBVHSD5.js.map → registry-3JY3YSMU.js.map} +0 -0
- /package/dist/{registry-CCXD57GV.js.map → registry-G365BQDC.js.map} +0 -0
- /package/dist/{registry-K75FRKSU.js.map → registry-HVS6PGHV.js.map} +0 -0
- /package/dist/{registry-KZYPKIOF.js.map → registry-TQ5FRB4T.js.map} +0 -0
- /package/dist/{request-withdrawal-WS7PXD7B.js.map → request-withdrawal-XQCCKMB3.js.map} +0 -0
- /package/dist/{reveal-Z62PLVJT.js.map → reveal-5PXWDCLZ.js.map} +0 -0
- /package/dist/{revoke-JH4VQTJ3.js.map → revoke-6NSQWTED.js.map} +0 -0
- /package/dist/{signer-AFV6AXSN.js.map → signer-AJ3MCSPI.js.map} +0 -0
- /package/dist/{stale-FVK3WRMM.js.map → stale-KQR5QAYJ.js.map} +0 -0
- /package/dist/{storage-EIM5HO2O.js.map → storage-GACYAH6W.js.map} +0 -0
- /package/dist/{store-coordination-provider-HIPOZMC2.js.map → store-coordination-provider-RII4H3PJ.js.map} +0 -0
- /package/dist/{verify-KYICK5IW.js.map → verify-OMPYUO7C.js.map} +0 -0
- /package/dist/{walk-FV6JFWXV.js.map → walk-ZYC74R65.js.map} +0 -0
- /package/dist/{withdraw-accessible-JYX3SPVY.js.map → withdraw-accessible-MEFFAGRD.js.map} +0 -0
|
@@ -154,19 +154,27 @@ export interface ProjectionSpec<TRow extends Record<string, unknown>> {
|
|
|
154
154
|
* FK on the projection source into an attached right-side record
|
|
155
155
|
* (record | null) under `as`.
|
|
156
156
|
* - **Reverse "collect" leg** — every row of `collect` whose `on`
|
|
157
|
-
* field references the
|
|
157
|
+
* field references the attach point's id, attached as a
|
|
158
158
|
* possibly-empty ARRAY under `as`. `on` must carry a `ref()`
|
|
159
|
-
* declared on the `collect` collection targeting
|
|
160
|
-
*
|
|
161
|
-
*
|
|
162
|
-
*
|
|
163
|
-
*
|
|
159
|
+
* declared on the `collect` collection targeting that attach point
|
|
160
|
+
* — checked at first materialization (parity with join-time ref
|
|
161
|
+
* errors). `maxRows` here is a PER-ROW fan-out ceiling (default:
|
|
162
|
+
* the join default); exceeding it throws `JoinTooLargeError`.
|
|
163
|
+
*
|
|
164
|
+
* Both kinds attach to the primary row by default, and to a
|
|
165
|
+
* previously-declared alias when `from` is set (#1140).
|
|
164
166
|
*/
|
|
165
167
|
export type ProjectionJoinLeg = {
|
|
166
|
-
/** FK field on
|
|
168
|
+
/** FK field on this leg's attach point (must have a `ref()` declared). */
|
|
167
169
|
readonly field: string;
|
|
168
170
|
/** Alias under which the resolved right-side record attaches. */
|
|
169
171
|
readonly as: string;
|
|
172
|
+
/**
|
|
173
|
+
* Attach to a previously-declared FORWARD leg's alias instead of to the
|
|
174
|
+
* primary row (#1140) — `field` is then read off that leg's record and
|
|
175
|
+
* resolved through a `ref()` on ITS collection. See the union's doc.
|
|
176
|
+
*/
|
|
177
|
+
readonly from?: string;
|
|
170
178
|
/** Per-side row ceiling override. `undefined` → the join default. */
|
|
171
179
|
readonly maxRows?: number;
|
|
172
180
|
/** Planner strategy override. `undefined` → auto-select. */
|
|
@@ -174,11 +182,40 @@ export type ProjectionJoinLeg = {
|
|
|
174
182
|
} | {
|
|
175
183
|
/** Sibling collection to collect from. */
|
|
176
184
|
readonly collect: string;
|
|
177
|
-
/** FK field on `collect`
|
|
185
|
+
/** FK field on `collect` — a `ref()` targeting this leg's attach point. */
|
|
178
186
|
readonly on: string;
|
|
179
187
|
/** Alias under which the collected array attaches. */
|
|
180
188
|
readonly as: string;
|
|
181
|
-
/**
|
|
189
|
+
/**
|
|
190
|
+
* Attach to a previously-declared FORWARD leg's alias instead of to the
|
|
191
|
+
* primary row (#1140): `on` must then `ref()` THAT leg's collection, and
|
|
192
|
+
* rows are matched against that leg's record id.
|
|
193
|
+
*
|
|
194
|
+
* This is what makes a two-hop lookup expressible. For
|
|
195
|
+
* `bill → entity → client`, the client is not reachable from the bill: a
|
|
196
|
+
* forward leg would need a `bill.clientId` that does not exist, and a
|
|
197
|
+
* collect leg would need `clients.entityId` to ref `bills` when it refs
|
|
198
|
+
* `entities`. With `from` it is one line:
|
|
199
|
+
*
|
|
200
|
+
* ```ts
|
|
201
|
+
* joins: [
|
|
202
|
+
* { field: 'entityId', as: 'entity' },
|
|
203
|
+
* { from: 'entity', collect: 'clients', on: 'entityId', as: 'clients' },
|
|
204
|
+
* ]
|
|
205
|
+
* ```
|
|
206
|
+
*
|
|
207
|
+
* The alternatives it replaces are both bad: denormalizing a redundant FK
|
|
208
|
+
* onto the source reintroduces exactly the duplicated relationship a
|
|
209
|
+
* projection MV exists to avoid, and dropping back to app code forfeits
|
|
210
|
+
* the dependency tracking it was adopted for.
|
|
211
|
+
*
|
|
212
|
+
* `from` may only name a leg declared EARLIER, and only a FORWARD one — a
|
|
213
|
+
* collect leg holds an array, not a record. Both are refused at
|
|
214
|
+
* registration. The backward-only rule is also why no depth cap is
|
|
215
|
+
* needed: a cycle cannot be spelled.
|
|
216
|
+
*/
|
|
217
|
+
readonly from?: string;
|
|
218
|
+
/** Per-row fan-out ceiling. `undefined` → the join default. */
|
|
182
219
|
readonly maxRows?: number;
|
|
183
220
|
};
|
|
184
221
|
/**
|
|
@@ -198,6 +235,23 @@ export interface MaterializedViewSpec<TRow extends Record<string, unknown>> {
|
|
|
198
235
|
* without pre-existing in-scope references; called again at each
|
|
199
236
|
* refresh.
|
|
200
237
|
*
|
|
238
|
+
* **One exception to "at registration time" (#1139).** Registration runs
|
|
239
|
+
* inside `openVault()`, and a collection's `refs` can only be declared after
|
|
240
|
+
* that returns — so a query that `.join()`s a declared FK cannot possibly
|
|
241
|
+
* resolve it on the registration call. When that happens the strategy is
|
|
242
|
+
* PARKED rather than failed, and replanned on the first write dispatch or
|
|
243
|
+
* `vault.refreshView()` — by which time the refs exist. The callback must
|
|
244
|
+
* therefore be safe to invoke more than once before the view first
|
|
245
|
+
* materializes, which it already had to be (it runs again at every refresh).
|
|
246
|
+
*
|
|
247
|
+
* Every other planning failure — a typo'd collection, a malformed spec, a
|
|
248
|
+
* throw from your own callback — still surfaces out of `openVault()`
|
|
249
|
+
* immediately. Only a not-yet-declared ref defers.
|
|
250
|
+
*
|
|
251
|
+
* While parked, the strategy is invisible: it contributes no cycle-detection
|
|
252
|
+
* edge (that pass runs once, at vault open) and appears in neither
|
|
253
|
+
* `refreshView()` nor the source dispatch map until it resolves.
|
|
254
|
+
*
|
|
201
255
|
* Built via the same `Query<T>` chainable builder used elsewhere —
|
|
202
256
|
* `.where()`, `.join()`, `.groupBy()`, `.aggregate()`. The
|
|
203
257
|
* dependency analyzer walks the returned plan to determine source
|
|
@@ -243,10 +297,14 @@ export interface MaterializedViewSpec<TRow extends Record<string, unknown>> {
|
|
|
243
297
|
*
|
|
244
298
|
* Dependencies are all AUTO: `{source} ∪ forward ref() targets ∪
|
|
245
299
|
* collect collections` (explicit {@link sources} remains additive).
|
|
246
|
-
* Forward targets resolve from the
|
|
300
|
+
* Forward targets resolve from the attach point's `ref()`
|
|
247
301
|
* declarations; those are declared by user code AFTER the vault
|
|
248
302
|
* opens (registration time), so the registry folds them into the
|
|
249
303
|
* dependency set on the first MV dispatch that finds them declared.
|
|
304
|
+
* A leg-relative forward leg (#1140) resolves its whole `from` chain
|
|
305
|
+
* the same way, so a two-hop leg simply lands one dispatch later
|
|
306
|
+
* than a one-hop one. A collect leg needs none of this: its
|
|
307
|
+
* dependency is the literal `collect` name whatever it attaches to.
|
|
250
308
|
*/
|
|
251
309
|
projection?: ProjectionSpec<TRow>;
|
|
252
310
|
/**
|
|
@@ -44,7 +44,7 @@ export interface RosterTag {
|
|
|
44
44
|
readonly iv: string;
|
|
45
45
|
readonly data: string;
|
|
46
46
|
}
|
|
47
|
-
export type RosterAuthorityFields = Pick<KeyringFile, 'user_id' | 'role' | 'permissions' | 'granted_by' | 'expires_at' | 'export_capability' | 'import_capability'>;
|
|
47
|
+
export type RosterAuthorityFields = Pick<KeyringFile, 'user_id' | 'role' | 'permissions' | 'granted_by' | 'expires_at' | 'export_capability' | 'import_capability' | 'deks' | 'pending_deks'>;
|
|
48
48
|
export declare function rosterCanonical(file: RosterAuthorityFields): string;
|
|
49
49
|
export declare function mintRosterTag(file: RosterAuthorityFields, rosterKey: EnclaveKey): Promise<RosterTag>;
|
|
50
50
|
/**
|
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
*/
|
|
31
31
|
import type { NoydbStore, SlotInfo } from '../../kernel/types.js';
|
|
32
32
|
import { type EnclaveKey } from '../../kernel/enclave/index.js';
|
|
33
|
+
import { type OrphanChunkReport } from './orphan-report.js';
|
|
33
34
|
export interface BlobFieldPolicy<T = unknown> {
|
|
34
35
|
/**
|
|
35
36
|
* Via port brand marker — lets a `BlobFieldPolicy` satisfy the kernel's
|
|
@@ -145,6 +146,18 @@ export interface CompactionResult {
|
|
|
145
146
|
records: number;
|
|
146
147
|
evicted: number;
|
|
147
148
|
}>;
|
|
149
|
+
/**
|
|
150
|
+
* #1133 — chunk rows in `_blob_chunks` with no surviving `_blob_index` entry.
|
|
151
|
+
* Pre-#1127 residue: unreachable by every reader AND by rotation, so for a
|
|
152
|
+
* legacy blob the bytes stay openable under a retired `_blob` DEK.
|
|
153
|
+
*
|
|
154
|
+
* REPORTED, never reclaimed — deciding "orphaned" means trusting the store's
|
|
155
|
+
* `list`, and a store that withholds one index row would have us destroy a
|
|
156
|
+
* LIVE blob's chunks. See `orphan-report.ts` for the full argument. A vault
|
|
157
|
+
* that has run `migrate()` has no legacy chunks to strand, and `chunks: 0`
|
|
158
|
+
* is the expected reading everywhere else.
|
|
159
|
+
*/
|
|
160
|
+
readonly orphanBlobChunks: OrphanChunkReport;
|
|
148
161
|
}
|
|
149
162
|
export interface CompactRunOptions {
|
|
150
163
|
/** Override "now" for deterministic testing. */
|
|
@@ -46,7 +46,7 @@ export declare const DEFAULT_CHUNK_SIZE: number;
|
|
|
46
46
|
*
|
|
47
47
|
* ## Deduplication
|
|
48
48
|
*
|
|
49
|
-
* `put()` computes `eTag = HMAC-SHA-256(
|
|
49
|
+
* `put()` computes `eTag = HMAC-SHA-256(addressKey(tier), plaintext)` — keyed so the
|
|
50
50
|
* store cannot predict eTags for known content. If another record already
|
|
51
51
|
* uploaded the same bytes, the chunks are reused and `refCount` is incremented.
|
|
52
52
|
*
|
|
@@ -179,6 +179,24 @@ export declare class BlobSet {
|
|
|
179
179
|
* write throws an AEAD decrypt error rather than silently writing under
|
|
180
180
|
* the wrong key.
|
|
181
181
|
*/
|
|
182
|
+
/**
|
|
183
|
+
* The content-addressing key for `tier` (#1126).
|
|
184
|
+
*
|
|
185
|
+
* Derived from `_blob_addr`, a vault-lifetime keyring slot `rotateKeys`
|
|
186
|
+
* refuses to touch — so a rotation re-keys chunk BODIES while every stored
|
|
187
|
+
* eTag, and therefore every chunk AAD and every `_blob_index` /
|
|
188
|
+
* `_blob_slots_*` / `_blob_versions_*` row, survives it unchanged.
|
|
189
|
+
*
|
|
190
|
+
* Before this the address was keyed by the `_blob` DEK itself, so after any
|
|
191
|
+
* rotation `HMAC(live DEK, plaintext) !== storedETag` permanently, for every
|
|
192
|
+
* blob written earlier: `decryptResponse()` raised `TamperedError` on the
|
|
193
|
+
* presigned-URL path forever, and dedup split.
|
|
194
|
+
*
|
|
195
|
+
* Still derived PER TIER, because the address is meant to be tier-scoped —
|
|
196
|
+
* `rehomeForTier` re-addresses on a tier move for exactly that reason. Only
|
|
197
|
+
* the ROTATION coupling was ever wrong.
|
|
198
|
+
*/
|
|
199
|
+
private addressKey;
|
|
182
200
|
private ownerTier;
|
|
183
201
|
/**
|
|
184
202
|
* The sanctioned cleared-read path to an elevated record's blobs (#749).
|
|
@@ -483,7 +501,9 @@ export declare class BlobSet {
|
|
|
483
501
|
* store is untrusted. A store that withholds one index row could make a LIVE
|
|
484
502
|
* blob's chunks look orphaned and have us destroy them — turning withholding,
|
|
485
503
|
* which is reversible, into permanent loss. Reporting them is safe; deleting
|
|
486
|
-
* them on the store's word is not.
|
|
504
|
+
* them on the store's word is not. The report half shipped as
|
|
505
|
+
* `reportOrphanBlobChunks` (#1133), surfaced through `vault.compact()`; a
|
|
506
|
+
* reclaim pass remains deliberately unbuilt for the reason above.
|
|
487
507
|
*/
|
|
488
508
|
private deleteChunksThenIndex;
|
|
489
509
|
/**
|
|
@@ -1038,7 +1058,7 @@ export declare class BlobSet {
|
|
|
1038
1058
|
* attacker-controlled content pulled from the same forged row and would
|
|
1039
1059
|
* make the check tautological). After assembling the plaintext, we
|
|
1040
1060
|
* recompute the SAME content address every write path mints
|
|
1041
|
-
* (`hmacSha256Hex(
|
|
1061
|
+
* (`hmacSha256Hex(addressKey(tier), plaintext)` — `writeBlobContent`'s Step 1,
|
|
1042
1062
|
* unconditional on `_cek`) and compare it to that requested eTag. A
|
|
1043
1063
|
* forged row can produce valid ciphertext under the flat DEK, but can't
|
|
1044
1064
|
* produce plaintext that re-hashes to an address it doesn't control.
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Orphan blob-chunk REPORT (#1133) — the read-only half of the residue #1127
|
|
3
|
+
* stopped producing.
|
|
4
|
+
*
|
|
5
|
+
* Before #1127, `releaseRef` deleted a blob's index row BEFORE its chunks, so a
|
|
6
|
+
* crash in between stranded chunk bodies nothing can ever reach: `loadBlobObject`
|
|
7
|
+
* returns null so no reader addresses them, and `rekeyBlobSet` derives its chunk
|
|
8
|
+
* ids from each index entry's `chunkCount` so a rotation never visits them. For a
|
|
9
|
+
* LEGACY blob (bytes under the shared `_blob` DEK rather than a per-blob content
|
|
10
|
+
* CEK) those bodies then stay openable under the retired DEK indefinitely.
|
|
11
|
+
*
|
|
12
|
+
* #1127 reversed the order, which removes the class at the source. It does
|
|
13
|
+
* nothing for orphans created before the fix, and this module does not delete
|
|
14
|
+
* them either. It counts them.
|
|
15
|
+
*
|
|
16
|
+
* ## Why this REPORTS and does not RECLAIM
|
|
17
|
+
*
|
|
18
|
+
* Deciding "orphaned" requires `store.list(_blob_index)`, and the store is
|
|
19
|
+
* untrusted — that is the premise of the product, not a caveat on it. A store
|
|
20
|
+
* that withholds a single index row makes a LIVE blob's chunks look orphaned. A
|
|
21
|
+
* reclaim pass acting on that would convert **withholding**, which is reversible
|
|
22
|
+
* the moment the store stops lying, into **permanent destruction** — handing an
|
|
23
|
+
* untrusted store a data-loss primitive it does not currently have, in order to
|
|
24
|
+
* tidy up residue.
|
|
25
|
+
*
|
|
26
|
+
* Reporting inverts the risk to something harmless: a lying store can only
|
|
27
|
+
* inflate this count. Nothing is deleted on its word, so the worst outcome is an
|
|
28
|
+
* operator investigating residue that turns out not to exist.
|
|
29
|
+
*
|
|
30
|
+
* Re-keying is not an alternative either: the chunk AAD is
|
|
31
|
+
* `{eTag}:{chunkIndex}:{chunkCount}`, and `chunkCount` lives only in the index
|
|
32
|
+
* row that is already gone — an orphan's AAD is unreconstructable, so it cannot
|
|
33
|
+
* be decrypted-and-re-encrypted at all.
|
|
34
|
+
*/
|
|
35
|
+
import type { NoydbStore } from '../../kernel/types.js';
|
|
36
|
+
export interface OrphanChunkReport {
|
|
37
|
+
/** Chunk rows whose eTag has no `_blob_index` entry. */
|
|
38
|
+
readonly chunks: number;
|
|
39
|
+
/** Distinct eTags those chunks belong to. */
|
|
40
|
+
readonly eTags: number;
|
|
41
|
+
/**
|
|
42
|
+
* Up to {@link SAMPLE_LIMIT} of those eTags, so an operator can inspect a real
|
|
43
|
+
* one rather than only a count. Deterministic (store list order), not random.
|
|
44
|
+
*/
|
|
45
|
+
readonly sampleETags: readonly string[];
|
|
46
|
+
/**
|
|
47
|
+
* Chunk ids that do not match the `{eTag}_{index}` grammar at all. Counted
|
|
48
|
+
* rather than skipped: an id this module cannot parse is a thing it cannot
|
|
49
|
+
* classify either way, and reporting zero orphans while silently dropping
|
|
50
|
+
* such ids would be the reassuring-but-wrong answer.
|
|
51
|
+
*/
|
|
52
|
+
readonly unparseable: number;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Count chunk rows with no surviving index row. Read-only: two `list` calls and
|
|
56
|
+
* no `get`, no `delete`, and no decryption — an orphan cannot be opened anyway.
|
|
57
|
+
*
|
|
58
|
+
* A store that cannot list either collection yields an empty report rather than
|
|
59
|
+
* throwing: this is a diagnostic riding along with a maintenance pass, and it
|
|
60
|
+
* must not be able to fail one.
|
|
61
|
+
*/
|
|
62
|
+
export declare function reportOrphanBlobChunks(adapter: NoydbStore, vault: string): Promise<OrphanChunkReport>;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import {
|
|
2
|
+
FROZEN_SNAPSHOTS_COLLECTION,
|
|
3
|
+
freezeAndDeleteClosure,
|
|
4
|
+
freezeSnapshotOnly,
|
|
5
|
+
randomId,
|
|
6
|
+
withdrawAccessibleData
|
|
7
|
+
} from "./chunk-576CTQ77.js";
|
|
8
|
+
import "./chunk-35K4VWMD.js";
|
|
9
|
+
import "./chunk-DM2BZDNV.js";
|
|
10
|
+
import "./chunk-TTGZ6KGY.js";
|
|
11
|
+
import "./chunk-43FOH2OK.js";
|
|
12
|
+
import "./chunk-FX3UIDCS.js";
|
|
13
|
+
import "./chunk-NK7DO6A2.js";
|
|
14
|
+
import "./chunk-AM6V36AG.js";
|
|
15
|
+
import "./chunk-AU45F5FD.js";
|
|
16
|
+
import "./chunk-LP7BEXCT.js";
|
|
17
|
+
import "./chunk-D7STIWJO.js";
|
|
18
|
+
import "./chunk-UJ4Z67UQ.js";
|
|
19
|
+
import "./chunk-5OFC3QYL.js";
|
|
20
|
+
import "./chunk-PZ5AY32C.js";
|
|
21
|
+
export {
|
|
22
|
+
FROZEN_SNAPSHOTS_COLLECTION,
|
|
23
|
+
freezeAndDeleteClosure,
|
|
24
|
+
freezeSnapshotOnly,
|
|
25
|
+
randomId,
|
|
26
|
+
withdrawAccessibleData
|
|
27
|
+
};
|
|
28
|
+
//# sourceMappingURL=withdraw-accessible-MEFFAGRD.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@noy-db/hub",
|
|
3
|
-
"version": "0.6.0-pre.
|
|
3
|
+
"version": "0.6.0-pre.24",
|
|
4
4
|
"description": "Zero-knowledge, offline-first, encrypted document store — core library with AES-256-GCM, PBKDF2, multi-user keyring, and sync engine",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "vLannaAi <vicio@lanna.ai>",
|
|
@@ -216,14 +216,14 @@
|
|
|
216
216
|
"node": ">=22.0.0"
|
|
217
217
|
},
|
|
218
218
|
"dependencies": {
|
|
219
|
-
"@noy-db/attestation": "0.6.0-pre.
|
|
219
|
+
"@noy-db/attestation": "0.6.0-pre.24"
|
|
220
220
|
},
|
|
221
221
|
"devDependencies": {
|
|
222
222
|
"@types/node": "^22.0.0",
|
|
223
223
|
"esbuild": "^0.25.0",
|
|
224
224
|
"zod": "^4.0.0",
|
|
225
225
|
"zod-to-json-schema": "^3.25.2",
|
|
226
|
-
"@noy-db/on-shamir": "0.6.0-pre.
|
|
226
|
+
"@noy-db/on-shamir": "0.6.0-pre.24"
|
|
227
227
|
},
|
|
228
228
|
"peerDependencies": {
|
|
229
229
|
"zod-to-json-schema": "^3.25.0"
|
package/dist/api-D6DBNTOS.js
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
UserApi,
|
|
3
|
-
createUserApi
|
|
4
|
-
} from "./chunk-PGHSH4TY.js";
|
|
5
|
-
import "./chunk-KMGAFLCK.js";
|
|
6
|
-
import "./chunk-DIVPOJPV.js";
|
|
7
|
-
import "./chunk-PENPHA45.js";
|
|
8
|
-
import "./chunk-IUQPNAGR.js";
|
|
9
|
-
import "./chunk-AELW6OJZ.js";
|
|
10
|
-
import "./chunk-DUUARUZI.js";
|
|
11
|
-
import "./chunk-LP7BEXCT.js";
|
|
12
|
-
import "./chunk-O5QXH7U7.js";
|
|
13
|
-
import "./chunk-IGNJOJEP.js";
|
|
14
|
-
import "./chunk-PKUJ3JLQ.js";
|
|
15
|
-
import "./chunk-PZ5AY32C.js";
|
|
16
|
-
export {
|
|
17
|
-
UserApi,
|
|
18
|
-
createUserApi
|
|
19
|
-
};
|
|
20
|
-
//# sourceMappingURL=api-D6DBNTOS.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/with-formula/materialized-views/dependency-analyzer.ts","../src/with-formula/materialized-views/query-hash.ts","../src/with-formula/materialized-views/registry.ts"],"sourcesContent":["import type { Query, QueryPlan } from '../../kernel/query/builder.js'\nimport type { JoinContext } from '../../kernel/query/join.js'\nimport type { MaterializedViewSpec } from './types.js'\n\n/**\n * Walks a `Query<T>` plan and returns the set of source collection\n * names that any source-write should trigger a refresh on.\n *\n * Handles:\n * - root collection (the one the query was built from)\n * - FK join targets (`.join(field, { as })`)\n *\n * Also handles:\n * - cross-join targets (`.crossJoin(target, { as })`) — v3\n *\n * Deferred:\n * - `.wherePredicate(name)` — v2 predicate primitive\n * - Overlay-name expansion to {base, overlay}\n *\n * The set is materialized at MV registration time. The MV registry\n * uses it to (a) dispatch `onSourceWrite` only to MVs that actually\n * care, and (b) contribute edges to the shared cycle-detection graph.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function analyzeDependencies(query: Query<any>): Set<string> {\n const deps = new Set<string>()\n const plan = query._plan()\n const ctx = query._joinContext()\n\n // The root collection is always a dependency.\n if (ctx?.leftCollection) {\n deps.add(ctx.leftCollection)\n }\n\n // FK join targets contribute additional sources.\n for (const leg of plan.joins) {\n deps.add(leg.target)\n }\n\n // Cross-join targets are also dependency sources — writes to either side\n // must trigger MV refresh. Symmetric with FK-join target handling above.\n for (const clause of plan.clauses) {\n if (clause.type === 'crossJoin') {\n deps.add(clause.target)\n }\n }\n\n // Sub-plans inside OR clauses can carry nested joins. Walk them.\n // (Today only top-level `.join()` populates `plan.joins`, but the\n // OR-group machinery permits sub-plans, so we recurse defensively.)\n walkClausesForJoins(plan, deps, ctx)\n\n return deps\n}\n\nfunction walkClausesForJoins(\n plan: QueryPlan,\n deps: Set<string>,\n ctx: JoinContext | undefined,\n): void {\n void ctx\n // Today `plan.joins` carries all join legs at top level. Sub-plans\n // inside OR groups don't currently support nested joins, so the loop\n // below is a no-op safety net for future builder extensions.\n for (const clause of plan.clauses) {\n if (clause.type === 'group') {\n // Group clauses don't (yet) carry their own joins; this is a\n // forward-compat anchor for when OR-groups support nested\n // sources.\n }\n }\n}\n\n/**\n * Convenience: produce a stable string summary of the query plan\n * suitable for `queryHash` derivation. Captures everything the\n * dependency analyzer reads + the where/orderBy/limit/offset\n * structure that affects materialized rows.\n *\n * `joinContext` is intentionally NOT included — the join-resolution\n * function references would defeat hash determinism. The set of join\n * TARGETS (collection names) IS included via the plan.joins legs.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function summarizeQueryPlan(query: Query<any>): string {\n const plan = query._plan()\n const ctx = query._joinContext()\n return JSON.stringify({\n root: ctx?.leftCollection ?? null,\n clauses: plan.clauses.map(c => {\n if (c.type === 'crossJoin') {\n return {\n type: 'crossJoin',\n target: c.target,\n as: c.as,\n // Inline on: callback: use sentinel — drift detection disabled for this MV\n onPredicateName: c.onPredicateName ?? (c.on ? '[inline]' : null),\n maxRows: c.maxRows ?? null,\n // `outer` changes the row set, so it is part of the plan's identity\n // for drift detection, not decoration (#1130).\n outer: c.outer ?? false,\n }\n }\n return c\n }),\n orderBy: plan.orderBy,\n limit: plan.limit ?? null,\n offset: plan.offset,\n joins: plan.joins.map(j => ({ field: j.field, as: j.as, target: j.target, mode: j.mode })),\n })\n}\n\n/**\n * Canonical string description of a UNION MV's plan, used as input to\n * `computeQueryHash`.\n *\n * Asymmetry note:\n * - Arm collection names are NOT sorted. Declaration order is\n * semantically meaningful for the dedup-only UNION path —\n * `materializeUnionResult` iterates `spec.unionSources` in\n * declaration order and keeps the first-seen row per composite key\n * (tie-break precedence). If we sorted arms here, a consumer who\n * reordered `unionSources` to change precedence would compute the\n * same `queryHash`, refresh would be a no-op, and stale MV rows\n * would persist. Hashing in declaration order makes any reorder\n * trigger a refresh.\n * - `groupBy` fields ARE sorted. Multi-key groupBy buckets are\n * commutative (`canonicalGroupKey` produces the same composite key\n * regardless of field order in the input spec).\n * - `aggregate` keys ARE sorted. Reducer-spec keys are independent\n * of each other — order of declaration doesn't change output.\n *\n * Per-arm `map` functions are NOT fingerprinted; consumers must bump\n * the MV's `name` (or rely on application-level cache busting) when\n * `map` semantics change non-equivalently.\n */\nexport function summarizeUnionPlan<T extends Record<string, unknown>>(\n spec: MaterializedViewSpec<T>,\n): string {\n return `union(${summarizeUnionArms(spec)})${summarizeGroupingTail(spec)}`\n}\n\n/**\n * Canonical string description of a projection MV's plan (#810), used\n * as input to `computeQueryHash`.\n *\n * Leg descriptors ARE sorted (contrast with UNION arm order): every\n * leg attaches under a distinct `as` alias, forward legs are\n * one-to-one attachments and collect legs are independent\n * hash-grouped passes, so declaration order never changes the\n * materialized rows — a pure reorder must NOT force a refresh.\n *\n * The projection `map` is NOT fingerprinted (identical limitation as\n * the UNION arm `map`); consumers must bump the MV's `name` when\n * `map` semantics change non-equivalently.\n */\nexport function summarizeProjectionPlan<T extends Record<string, unknown>>(\n spec: MaterializedViewSpec<T>,\n): string {\n const projection = spec.projection!\n const legs = projection.joins\n .map(leg =>\n 'collect' in leg\n ? `collect:${leg.collect}.${leg.on}→${leg.as}`\n : `field:${leg.field}→${leg.as}`,\n )\n .sort()\n const body = JSON.stringify({ source: projection.source, legs })\n return `projection(${body})${summarizeGroupingTail(spec)}`\n}\n\n/** Arm descriptors for `summarizeUnionPlan` — declaration order preserved (see its doc). */\nfunction summarizeUnionArms<T extends Record<string, unknown>>(\n spec: MaterializedViewSpec<T>,\n): string {\n return (spec.unionSources ?? [])\n .map(s => {\n // Fold each arm's join legs into the summary so adding or\n // reordering joins (which changes the materialized rows) bumps\n // queryHash. Leg order is declaration-significant (legs chain), so\n // it is NOT sorted — same rationale as arm declaration order.\n const joins = s.join?.length\n ? `[${s.join.map(j => `${j.field}→${j.as}`).join(';')}]`\n : ''\n return `${s.collection}${joins}`\n })\n .join(',')\n}\n\n/**\n * Shared `|groupBy(…)|aggregate(…)|money(…)` tail for the UNION and\n * projection summaries — both feed the same post-map grouping pipeline,\n * so the same spec fields fold into both hashes with the same rules.\n */\nfunction summarizeGroupingTail<T extends Record<string, unknown>>(\n spec: MaterializedViewSpec<T>,\n): string {\n const groupBy: string = Array.isArray(spec.groupBy)\n ? [...spec.groupBy].sort().join(',')\n : typeof spec.groupBy === 'string'\n ? spec.groupBy\n : ''\n const aggKeys = spec.aggregate ? Object.keys(spec.aggregate).sort().join(',') : ''\n // `moneyFields` changes reducer semantics (float → exact BigInt), so\n // declaring / removing / re-keying it must bump queryHash. Keys are\n // sorted — they're independent of each other (one descriptor per\n // output field), same rationale as aggregate keys.\n const moneyKeys = spec.moneyFields ? Object.keys(spec.moneyFields).sort().join(',') : ''\n return `|groupBy(${groupBy})|aggregate(${aggKeys})|money(${moneyKeys})`\n}\n","/**\n * Deterministic hash of a materialized view strategy's \"shape\": MV\n * name + canonical query-plan summary + sorted dependency-set.\n *\n * Used to detect strategy drift: a row whose `_materializedFrom.queryHash`\n * doesn't match the current strategy is considered stale.\n *\n * Web Crypto SHA-256 — no extra deps. Mirrors the v1\n * `computeStrategyHash` pattern.\n */\nimport { sha256Hex } from '../../kernel/enclave/index.js'\n\nexport async function computeQueryHash(\n mvName: string,\n /**\n * Source-collection set the query depends on. Sorted before\n * canonicalization so set iteration order doesn't affect the hash.\n */\n dependencies: ReadonlySet<string>,\n /**\n * Stringified query-plan summary. The caller produces this from the\n * `Query<T>` builder — concretely: a JSON serialization of clauses +\n * orderBy + limit + offset + joins. Function bodies inside\n * `wherePredicate` are NOT included here (those carry their own\n * `predicateHash` to be folded in by a later sub-issue).\n */\n queryPlanSummary: string,\n): Promise<string> {\n const canonical = JSON.stringify({\n mvName,\n dependencies: [...dependencies].sort(),\n queryPlanSummary,\n })\n const bytes = new TextEncoder().encode(canonical)\n return sha256Hex(bytes)\n}\n\n/**\n * Canonicalize a query plan for hashing. Walks the plan structure\n * with sorted keys so insertion order doesn't perturb the result.\n * Lives here rather than in `query/builder.ts` to keep that module\n * stable across MV-specific evolutions.\n *\n * @internal exported for testing\n */\nexport function canonicalizeQueryPlan(plan: unknown): string {\n return JSON.stringify(plan, (_key, value) => {\n if (value && typeof value === 'object' && !Array.isArray(value)) {\n const sorted: Record<string, unknown> = {}\n for (const k of Object.keys(value as Record<string, unknown>).sort()) {\n sorted[k] = (value as Record<string, unknown>)[k]\n }\n return sorted\n }\n return value\n })\n}\n","import { MaterializedViewSourceUnknownError } from '../../kernel/errors.js'\nimport type { ViaGraph, FieldRef, EdgeKind, Grain } from '../../kernel/via/graph.js'\nimport type { Clause, FieldClause } from '../../kernel/query/predicate.js'\nimport type { DeclaredPredicate } from '../../kernel/query/builder.js'\nimport { analyzeDependencies, summarizeQueryPlan, summarizeUnionPlan, summarizeProjectionPlan } from './dependency-analyzer.js'\nimport { computeQueryHash } from './query-hash.js'\nimport type { MaterializedViewSpec, MVQueryContext } from './types.js'\n\n/**\n * Whole-record artifact-grain field marker (#638 Task 2) — MUST match\n * `derivations/registry.ts`'s and `vault.ts`'s overlay-edge marker so\n * cross-registry edges (a derivation feeding an MV, or vice versa) resolve\n * to the SAME graph node. See that file's `WHOLE_RECORD` doc comment.\n */\nconst WHOLE_RECORD = '*'\n\n/**\n * One registered MV strategy alongside its derived metadata. Stored\n * type-erased on `TRow` so the registry can hold heterogeneous MVs.\n */\nexport interface RegisteredMV {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n readonly spec: MaterializedViewSpec<any>\n /** Output collection name (`spec.output?.collection ?? spec.name`). */\n readonly outputCollection: string\n /** Set of source collections; populated at registration via the analyzer. */\n readonly dependencies: ReadonlySet<string>\n /** Canonical `queryHash` — `_materializedFrom.queryHash` for every emitted row. */\n readonly queryHash: string\n /**\n * Top-level FieldClauses on the partition field, captured at\n * registration time. Used by the cycle detector to resolve\n * same-collection-as-source edges via the partition-discriminator\n * check. Empty when `spec.output?.partition` is undefined.\n */\n readonly partitionClauses: readonly FieldClause[]\n /**\n * #638 Task 2 — `'record'` for a row-per-source-row Query<T> or\n * `unionSources` MV, `'aggregate'` for a `.groupBy().aggregate()` MV\n * (the shape that requires explicit `sources`, since the dependency\n * analyzer can't walk an aggregate plan). Feeds `edges()`'s grain.\n */\n readonly grain: Grain\n}\n\n/**\n * Vault-internal registry of MV strategies. Owned by `Vault`; not\n * exported. Parallel to v1's `DerivationRegistry`; the two graphs share\n * a single cycle-detection pass at vault open (see `validate`).\n *\n * @internal\n */\nexport class MaterializedViewRegistry {\n /** Keyed by `spec.name`. */\n private readonly _byName = new Map<string, RegisteredMV>()\n /** Keyed by dependency source-collection → MVs that depend on it. */\n private readonly _bySource = new Map<string, RegisteredMV[]>()\n /**\n * Projection MVs (#810) whose forward-leg ref() targets could not be\n * resolved at registration time. A forward leg names only the FK\n * FIELD; its dependency is the field's ref() TARGET, declared on the\n * source collection — but registration runs at vault open, BEFORE\n * user code declares collections (and their refs). Constructing the\n * source collection here to look them up would be worse: a later\n * `vault.collection(source, { refs })` call only registers refs on a\n * cache miss, so an early construction would silently drop them.\n * Instead each entry carries a non-constructive ref-registry probe;\n * `mvsForSource` retries on every dispatch until every forward\n * target has resolved (see `_resolvePendingForwardDeps`).\n */\n private readonly _pendingForwardDeps: Array<{\n reg: RegisteredMV\n fields: Set<string>\n resolveTarget: (field: string) => string | null\n }> = []\n\n /**\n * Register an MV. Invokes `spec.query()` once at registration time to\n * read the plan + join context; the resulting `Query<T>` is discarded\n * after dependency extraction. `vault.collection(...)` must therefore\n * be functional by the time this runs — typically wired from\n * `Vault._initMaterializedViews` after collection bootstrap.\n *\n * Throws `MaterializedViewSourceUnknownError` if the analyzer\n * surfaces a dependency the vault doesn't know about (when a\n * `knownCollections` checker is supplied).\n */\n async register(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n spec: MaterializedViewSpec<any>,\n db: MVQueryContext,\n options?: { knownCollections?: (name: string) => boolean },\n ): Promise<void> {\n // Build a predicate-aware db wrapper. If `spec.predicates` is\n // declared, the wrapper intercepts `.collection().query()` and\n // attaches the predicates map to the resulting Query<T>. With no\n // predicates declared, the wrapper is the original db unchanged.\n const dbForQuery = spec.predicates ? wrapDbWithPredicates(db, spec.predicates) : db\n\n // Invoke the query callback once to inspect its plan / dependencies.\n // For Query<T> shapes the analyzer extracts deps + plan summary\n // automatically. Reduction / GroupedReduction shapes don't\n // expose the underlying Query, so the spec must declare `sources`\n // explicitly. `partitionClauses` are only populated for Query<T>\n // since same-collection-partition is a non-aggregate concern.\n // UNION-form strategies: dependencies and plan summary come\n // straight off the strategy — no `query` callback to introspect.\n // The dependency-analyzer + summarizer are bypassed entirely; the\n // executor handles materialization via `materializeUnionResult`.\n let dependencies: Set<string>\n let queryPlanSummary: string\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let qAny: any = null\n let isQuery = false\n // Projection-form (#810): forward legs whose ref() target wasn't\n // resolvable at registration time — folded in lazily, see\n // `_pendingForwardDeps`.\n const pendingForwardFields: string[] = []\n if (spec.unionSources) {\n dependencies = new Set(spec.unionSources.map(s => s.collection))\n // Per-arm joins resolve right-side collections that aren't among\n // the arm `collection`s. The consumer lists those in `sources`;\n // fold them into the dependency set so a write to a join-target\n // collection triggers MV refresh (and contributes a cycle edge).\n if (spec.sources) for (const s of spec.sources) dependencies.add(s)\n queryPlanSummary = summarizeUnionPlan(spec)\n } else if (spec.projection) {\n // Projection-form (#810): dependencies are all AUTO — the primary\n // source, every collect leg's collection (both literal names), and\n // every forward leg's ref() target. Forward targets usually can't\n // resolve yet (refs are declared after vault open) — those go\n // through the pending-resolution path below. Explicit `sources`\n // remains additive, same as the other two forms.\n const projection = spec.projection\n dependencies = new Set([projection.source])\n for (const leg of projection.joins) {\n if ('collect' in leg) dependencies.add(leg.collect)\n else pendingForwardFields.push(leg.field)\n }\n if (spec.sources) for (const s of spec.sources) dependencies.add(s)\n queryPlanSummary = summarizeProjectionPlan(spec)\n } else {\n const q = spec.query!(dbForQuery)\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n qAny = q as any\n isQuery = typeof qAny._plan === 'function'\n if (isQuery) {\n // `q` is the `Query` arm of the union here (runtime-confirmed via\n // `qAny._plan` above); reuse the already-`any` `qAny` the block uses\n // for `_plan()` rather than re-narrowing.\n dependencies = analyzeDependencies(qAny)\n queryPlanSummary = summarizeQueryPlan(qAny)\n // Fold `.wherePredicate(name, ctx)` references into the plan\n // summary so predicate function or ctx changes (signalled by\n // bumping `hash` or supplying a different ctx) propagate into\n // `queryHash` and force refresh on next visit.\n const predicateRefs = extractPredicateRefs(qAny._plan())\n if (predicateRefs.length > 0) {\n queryPlanSummary = JSON.stringify({ plan: queryPlanSummary, predicates: predicateRefs })\n }\n // If `sources` is ALSO declared, take the union (consumer's\n // explicit list extends the auto-analyzed set).\n if (spec.sources) for (const s of spec.sources) dependencies.add(s)\n } else {\n // Aggregate shape: require explicit `sources`.\n if (!spec.sources || spec.sources.length === 0) {\n throw new Error(\n `withMaterializedView \"${spec.name}\": query() returned an aggregate ` +\n `(Reduction or GroupedReduction) but no \\`sources\\` field is declared. ` +\n `The dependency analyzer cannot walk through groupBy().aggregate() ` +\n `back to the source — declare sources: [...] explicitly.`,\n )\n }\n dependencies = new Set(spec.sources)\n // Aggregate plans don't carry a chainable query plan for summary\n // purposes; the dep-set + spec.name serve as the queryHash inputs.\n queryPlanSummary = JSON.stringify({ aggregate: true, sources: [...spec.sources].sort() })\n }\n }\n\n // Sanity-check declared dependencies against the vault's known\n // collections. Optional — when the checker isn't supplied (test\n // wiring, in-process composition) the registration succeeds and\n // any typo surfaces at first onSourceWrite as a no-op.\n if (options?.knownCollections) {\n for (const dep of dependencies) {\n if (!options.knownCollections(dep)) {\n throw new MaterializedViewSourceUnknownError(spec.name, dep)\n }\n }\n }\n\n const outputCollection = spec.output?.collection ?? spec.name\n const queryHash = await computeQueryHash(spec.name, dependencies, queryPlanSummary)\n // For same-collection-as-source MVs, capture the where-clauses on\n // the partition field so cycle detection can prove disjointness.\n // Only applicable to Query<T> shapes — aggregate MVs don't carry\n // a chainable plan to inspect (and same-collection aggregation\n // doesn't make sense for same-collection aggregation).\n const partitionClauses: FieldClause[] = []\n const partitionField = spec.output?.partition?.field\n if (partitionField !== undefined && isQuery) {\n const plan = qAny._plan()\n for (const clause of plan.clauses) {\n if (isFieldClauseOnField(clause, partitionField)) partitionClauses.push(clause)\n }\n }\n // #638 Task 2 — 'aggregate' only for the explicit-sources aggregate shape\n // (groupBy().aggregate() with no chainable plan); a row-per-source-row\n // Query<T>, unionSources, or projection MV is 'record'.\n const grain: Grain = spec.unionSources || spec.projection || isQuery ? 'record' : 'aggregate'\n const reg: RegisteredMV = { spec, outputCollection, dependencies, queryHash, partitionClauses, grain }\n\n this._byName.set(spec.name, reg)\n for (const dep of dependencies) {\n const arr = this._bySource.get(dep)\n if (arr) arr.push(reg)\n else this._bySource.set(dep, [reg])\n }\n if (pendingForwardFields.length > 0) {\n // Non-constructive ref-registry probe: the Vault (the real\n // MVQueryContext) carries its RefRegistry as a private field,\n // reachable structurally at runtime. Test stubs without one simply\n // never resolve — forward deps then come only from explicit `sources`.\n const refRegistry = (db as unknown as {\n refRegistry?: { getOutbound(collection: string): Record<string, { target: string }> }\n }).refRegistry\n const source = spec.projection!.source\n this._pendingForwardDeps.push({\n reg,\n fields: new Set(pendingForwardFields),\n resolveTarget: (field) => refRegistry?.getOutbound(source)[field]?.target ?? null,\n })\n // Immediate attempt — covers refs already declared by the time\n // this MV registers (re-registration flows, test wiring).\n this._resolvePendingForwardDeps()\n }\n }\n\n /** All MVs that depend on `source`, in registration order. */\n mvsForSource(source: string): ReadonlyArray<RegisteredMV> {\n if (this._pendingForwardDeps.length > 0) this._resolvePendingForwardDeps()\n return this._bySource.get(source) ?? []\n }\n\n /**\n * Retry ref() resolution for every pending projection forward leg\n * (#810). A field resolves once its source collection's refs have\n * been declared; the target then folds into the owning MV's\n * dependency set and `_bySource`, so subsequent writes to it\n * dispatch a refresh. Idempotent and cheap — the pending list\n * empties as fields resolve, and `mvsForSource` skips the call\n * entirely once it's empty.\n *\n * Late-resolved targets do NOT retro-feed `edges()` — the cycle\n * pass runs once at vault open, before refs exist. A cycle routed\n * exclusively through a forward leg is therefore not detected at\n * open (collect + source edges, the literal names, are).\n */\n private _resolvePendingForwardDeps(): void {\n for (let i = this._pendingForwardDeps.length - 1; i >= 0; i--) {\n const entry = this._pendingForwardDeps[i]!\n for (const field of [...entry.fields]) {\n const target = entry.resolveTarget(field)\n if (target === null) continue\n entry.fields.delete(field)\n if (entry.reg.dependencies.has(target)) continue\n // `dependencies` is declared ReadonlySet for consumers; the\n // registry owns the underlying Set and is the one writer.\n ;(entry.reg.dependencies as Set<string>).add(target)\n const arr = this._bySource.get(target)\n if (arr) arr.push(entry.reg)\n else this._bySource.set(target, [entry.reg])\n }\n if (entry.fields.size === 0) this._pendingForwardDeps.splice(i, 1)\n }\n }\n\n /** Single MV by name, or `undefined`. */\n byName(name: string): RegisteredMV | undefined {\n return this._byName.get(name)\n }\n\n /** Iterate over every registered MV. */\n all(): ReadonlyArray<RegisteredMV> {\n return [...this._byName.values()]\n }\n\n /**\n * Graph edges for #638 Task 2: one `'mv'` edge per registered MV — target\n * = the output collection (a `WHOLE_RECORD` artifact node), sources =\n * every dependency (also `WHOLE_RECORD` nodes). Same-collection edges\n * (`dep === outputCollection`) are skipped IFF the MV declares an\n * `output.partition` discriminator AND the query has a where-clause that\n * provably excludes the partition value (`partitionDisjoint`) — the SAME\n * condition the old local DFS used. Grain comes from the registration-time\n * `RegisteredMV.grain`.\n */\n edges(): ReadonlyArray<{ readonly target: FieldRef; readonly sources: readonly FieldRef[]; readonly kind: EdgeKind; readonly grain: Grain }> {\n const out: Array<{ target: FieldRef; sources: FieldRef[]; kind: EdgeKind; grain: Grain }> = []\n for (const reg of this._byName.values()) {\n const sources: FieldRef[] = []\n for (const dep of reg.dependencies) {\n if (dep === reg.outputCollection && partitionDisjoint(reg)) continue\n sources.push({ collection: dep, field: WHOLE_RECORD })\n }\n if (sources.length === 0) continue\n out.push({ target: { collection: reg.outputCollection, field: WHOLE_RECORD }, sources, kind: 'mv', grain: reg.grain })\n }\n return out\n }\n\n /**\n * Cycle detection, delegated to `ViaGraph.assertAcyclic()` (#638 Task 2 —\n * retires the local DFS). `graph` is the caller's shared per-vault graph,\n * ALREADY carrying this registry's `edges()` AND `DerivationRegistry`'s\n * (registered by the caller — see `Vault._initMaterializedViews`, which\n * runs after `_initDerivations`, so a pure-derivation cycle already threw\n * `DerivationCycleError` there; any cycle surfacing here necessarily\n * touches an MV edge). Throws `MaterializedViewCycleError` — SAME class as\n * before.\n */\n validate(graph: ViaGraph): void {\n graph.assertAcyclic()\n }\n}\n\n/**\n * Type guard: is the clause a top-level `FieldClause` on the given\n * field? Used by the partition-disjoint check.\n *\n * @internal\n */\nfunction isFieldClauseOnField(clause: Clause, field: string): clause is FieldClause {\n return clause.type === 'field' && clause.field === field\n}\n\n/**\n * Wrap an `MVQueryContext` so its `.collection().query()` returns a\n * Query<T> with the MV's declared predicates attached. Bare Queries\n * (outside of any MV) don't gain `.wherePredicate()` — only Queries\n * obtained through this wrapped db do.\n *\n * @internal\n */\nexport function wrapDbWithPredicates(\n db: MVQueryContext,\n predicates: NonNullable<MaterializedViewSpec<Record<string, unknown>>['predicates']>,\n): MVQueryContext {\n // Build the predicate map once — the fn signature in the MV spec\n // is row-typed but the QueryBuilder casts to unknown, so we widen\n // here for the Map.\n const map = new Map<string, DeclaredPredicate>()\n for (const [name, decl] of Object.entries(predicates)) {\n map.set(name, {\n hash: decl.hash,\n fn: decl.fn as (record: unknown, ctx?: unknown) => boolean,\n })\n }\n return {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n collection<T extends Record<string, unknown>>(name: string): any {\n const c = db.collection<T>(name)\n // Return an object that delegates everything to `c` but\n // overrides `.query()` to attach predicates via the new\n // `Query._withPredicates()` accessor.\n return new Proxy(c, {\n get(target, prop, receiver) {\n if (prop === 'query') {\n return (...args: unknown[]) => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const q = (target.query as any)(...args)\n // For non-aggregate Query<T>, attach predicates. For\n // legacy predicate-arg overload that returns T[] (sync\n // filter), pass through unchanged.\n \n if (q && typeof q._withPredicates === 'function') {\n return q._withPredicates(map)\n }\n return q\n }\n }\n return Reflect.get(target, prop, receiver)\n },\n })\n },\n }\n}\n\n/**\n * Walk a QueryPlan's clauses and collect predicate-reference markers\n * for `queryHash` derivation. Returns a sorted array (deterministic\n * order) of `{ name, predicateHash, ctxHash }` tuples — these are the\n * hashable identity of each `.wherePredicate()` call site.\n *\n * @internal\n */\nfunction extractPredicateRefs(\n plan: { clauses: readonly Clause[] },\n): Array<{ name: string; predicateHash: string; ctxHash: string }> {\n const refs: Array<{ name: string; predicateHash: string; ctxHash: string }> = []\n const walk = (clauses: readonly Clause[]): void => {\n for (const c of clauses) {\n if (c.type === 'wherePredicate') {\n refs.push({ name: c.name, predicateHash: c.predicateHash, ctxHash: c.ctxHash })\n } else if (c.type === 'group') {\n walk(c.clauses)\n }\n }\n }\n walk(plan.clauses)\n // Stable-sort by (name, predicateHash, ctxHash) — same predicate\n // appearing twice with different ctx hashes both flow through.\n refs.sort((a, b) => {\n if (a.name !== b.name) return a.name < b.name ? -1 : 1\n if (a.predicateHash !== b.predicateHash) return a.predicateHash < b.predicateHash ? -1 : 1\n return a.ctxHash < b.ctxHash ? -1 : a.ctxHash > b.ctxHash ? 1 : 0\n })\n return refs\n}\n\n/**\n * Provability check for the same-collection partition-discriminator.\n * Returns `true` when\n * the captured partition clauses on the MV's query provably exclude\n * the partition's value — meaning the input filter and the output\n * partition are disjoint and the same-collection edge isn't really a\n * cycle.\n *\n * Supported provability shapes (narrow on purpose — DERIV-PP30-001\n * is the load-bearing case):\n *\n * - `.where(field, '==', X)` where X !== partition.value → disjoint\n * - `.where(field, '!=', partition.value)` → disjoint\n * - `.where(field, 'in', [...])` where partition.value NOT in list → disjoint\n *\n * Anything else (no clause on the partition field, an 'in' list that\n * contains partition.value, unsupported operators) → not disjoint,\n * the cycle detector surfaces `MaterializedViewCycleError`.\n *\n * @internal\n */\nfunction partitionDisjoint(reg: RegisteredMV): boolean {\n const partition = reg.spec.output?.partition\n if (partition === undefined) return false\n const value = partition.value\n // The OR-semantics of multiple where-clauses on the same field\n // would muddy this check. v2 only treats AND-chained clauses;\n // any clause that proves disjoint is sufficient.\n for (const c of reg.partitionClauses) {\n if (c.op === '==' && c.value !== value) return true\n if (c.op === '!=' && c.value === value) return true\n if (c.op === 'in' && Array.isArray(c.value)) {\n const list = c.value as readonly unknown[]\n if (!list.includes(value)) return true\n }\n }\n return false\n}\n"],"mappings":"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","names":[]}
|