@noy-db/hub 0.2.0-pre.21 → 0.2.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/dist/aggregate/index.cjs.map +1 -1
- package/dist/aggregate/index.d.cts +3 -3
- package/dist/aggregate/index.d.ts +3 -3
- package/dist/aggregate/index.js +5 -5
- package/dist/attestation/index.cjs.map +1 -1
- package/dist/attestation/index.d.cts +4 -4
- package/dist/attestation/index.d.ts +4 -4
- package/dist/attestation/index.js +6 -6
- package/dist/blobs/index.cjs.map +1 -1
- package/dist/blobs/index.d.cts +6 -6
- package/dist/blobs/index.d.ts +6 -6
- package/dist/blobs/index.js +6 -6
- package/dist/bundle/index.cjs +21173 -21341
- package/dist/bundle/index.cjs.map +1 -1
- package/dist/bundle/index.d.cts +15 -6
- package/dist/bundle/index.d.ts +15 -6
- package/dist/bundle/index.js +58 -193
- package/dist/bundle/index.js.map +1 -1
- package/dist/{chunk-CQYEDODS.js → chunk-35U5YNRR.js} +3 -3
- package/dist/{chunk-NV4IHBZS.js → chunk-3XJU3OHE.js} +5 -5
- package/dist/{chunk-OTWT6BAJ.js → chunk-4BB4T3O7.js} +12 -2
- package/dist/chunk-4BB4T3O7.js.map +1 -0
- package/dist/{chunk-IVZWHIEK.js → chunk-4HEGG5NJ.js} +5 -5
- package/dist/{chunk-WE2BUQD2.js → chunk-4TCMCCC3.js} +5 -3
- package/dist/{chunk-5YTXYPES.js → chunk-5A2FVGHT.js} +5 -5
- package/dist/{chunk-NSXNXLYM.js → chunk-5GZC2ZM3.js} +2 -2
- package/dist/{chunk-JYNH4FIM.js → chunk-77WF53XY.js} +4 -4
- package/dist/{chunk-O5XKZCUD.js → chunk-7X4EF35A.js} +5 -5
- package/dist/{chunk-SQKAECUL.js → chunk-7ZCTUI26.js} +2 -2
- package/dist/{chunk-J6RGRZOY.js → chunk-AO3QSMCU.js} +2 -2
- package/dist/{chunk-JDCPRJVS.js → chunk-AONK5GCC.js} +4 -4
- package/dist/{chunk-FRRJIUSI.js → chunk-B5CSNGSE.js} +17 -9
- package/dist/chunk-B5CSNGSE.js.map +1 -0
- package/dist/{chunk-IY24WS2P.js → chunk-BCMHJYVT.js} +4 -4
- package/dist/{chunk-IY24WS2P.js.map → chunk-BCMHJYVT.js.map} +1 -1
- package/dist/{chunk-TYMDCIQM.js → chunk-C472BRJ4.js} +4 -4
- package/dist/{chunk-MBXKRHSS.js → chunk-CCNRFAL3.js} +2 -2
- package/dist/{chunk-BZW5IL43.js → chunk-DCA2BDHA.js} +4 -4
- package/dist/{chunk-JBBWALNI.js → chunk-DCICHSRS.js} +2 -2
- package/dist/{chunk-2XA2ZML4.js → chunk-FG6IQ3ZL.js} +3 -3
- package/dist/{chunk-C2RJVZZL.js → chunk-G4GW5VOS.js} +2 -2
- package/dist/{chunk-U2XSUCDF.js → chunk-GEWIFM4J.js} +2 -2
- package/dist/{chunk-TNH5SLCD.js → chunk-HD4QCT2O.js} +2 -2
- package/dist/{chunk-I3IYTUUI.js → chunk-HHJ5DZCZ.js} +3 -3
- package/dist/{chunk-6QAZ5O6X.js → chunk-IEIADIPM.js} +2 -2
- package/dist/{chunk-YPIOFSN3.js → chunk-IHAISFXP.js} +2 -2
- package/dist/{chunk-GJTKMME7.js → chunk-JKM2AVVH.js} +2 -2
- package/dist/{chunk-EYK72OTL.js → chunk-JRMOSIH4.js} +5 -5
- package/dist/chunk-JRMOSIH4.js.map +1 -0
- package/dist/{chunk-S45MDEEF.js → chunk-LMWVNF6X.js} +2 -2
- package/dist/{chunk-TA6HPKWQ.js → chunk-LR7CODVN.js} +1 -1
- package/dist/chunk-LR7CODVN.js.map +1 -0
- package/dist/{chunk-TAMRU7A2.js → chunk-OKV7S356.js} +4 -4
- package/dist/{chunk-HYJMAV53.js → chunk-OWAMTSAI.js} +93 -93
- package/dist/chunk-OWAMTSAI.js.map +1 -0
- package/dist/{chunk-IW4L4X65.js → chunk-P5A4E53B.js} +2 -2
- package/dist/{chunk-JOK73NDT.js → chunk-P7OL22JP.js} +3 -3
- package/dist/{chunk-7PH4OPBZ.js → chunk-QOXZM3L2.js} +762 -134
- package/dist/chunk-QOXZM3L2.js.map +1 -0
- package/dist/chunk-R43KS34V.js +399 -0
- package/dist/chunk-R43KS34V.js.map +1 -0
- package/dist/{chunk-TGIJTNM3.js → chunk-R5ZECURV.js} +2 -2
- package/dist/{chunk-KOAJ3TZM.js → chunk-RFEXGW3L.js} +2 -2
- package/dist/{chunk-F5ILTHMU.js → chunk-RNQPDV75.js} +5 -5
- package/dist/{chunk-WWVJXBOT.js → chunk-SGM7CK7R.js} +5 -5
- package/dist/{chunk-7MRT7EPB.js → chunk-SOQE5DUV.js} +3 -3
- package/dist/{chunk-F5GWNSE2.js → chunk-TOMSCJRV.js} +3 -3
- package/dist/{chunk-F5GWNSE2.js.map → chunk-TOMSCJRV.js.map} +1 -1
- package/dist/{chunk-ZONKSLF2.js → chunk-TQMQZOMX.js} +2 -2
- package/dist/{chunk-3HNKR65T.js → chunk-U6LTLN7O.js} +3 -3
- package/dist/{chunk-UU6M64HI.js → chunk-UAK2AMO2.js} +4 -4
- package/dist/{chunk-37VGJM3T.js → chunk-WQ3KAGOV.js} +2 -2
- package/dist/{chunk-C6W5KVDV.js → chunk-XC32SZPW.js} +35 -35
- package/dist/chunk-XC32SZPW.js.map +1 -0
- package/dist/{chunk-AI4USDRI.js → chunk-XQO4TAJS.js} +4 -4
- package/dist/{chunk-SQOK5UM6.js → chunk-ZBENTRFS.js} +2 -2
- package/dist/{chunk-6QE4DUYC.js → chunk-ZDITTESU.js} +2 -2
- package/dist/consent/index.cjs.map +1 -1
- package/dist/consent/index.d.cts +5 -5
- package/dist/consent/index.d.ts +5 -5
- package/dist/consent/index.js +3 -3
- package/dist/{crypto-456N7UVX.js → crypto-2LU6XUFF.js} +3 -3
- package/dist/{delegation-DP4COTXB.js → delegation-6ABSJGXV.js} +5 -5
- package/dist/derivations/index.cjs.map +1 -1
- package/dist/derivations/index.d.cts +6 -6
- package/dist/derivations/index.d.ts +6 -6
- package/dist/derivations/index.js +4 -4
- package/dist/{dev-unlock-CpKSkl2c.d.ts → dev-unlock-BlhRHr6p.d.ts} +1 -1
- package/dist/{dev-unlock-CY0HIZA0.d.cts → dev-unlock-DURe4IvF.d.cts} +1 -1
- package/dist/{errors-Dkc_fi-S.d.cts → errors-B2tUcRPg.d.cts} +19 -5
- package/dist/{errors-Dkc_fi-S.d.ts → errors-B2tUcRPg.d.ts} +19 -5
- package/dist/executor-JKMSEB34.js +8 -0
- package/dist/executor-UYXSQB4D.js +12 -0
- package/dist/executor-VJSCTBWY.js +8 -0
- package/dist/{fanout-sidecar-YXNAEZ33.js → fanout-sidecar-ZQT4Y7PF.js} +2 -2
- package/dist/forget/index.js +4 -4
- package/dist/guards/index.cjs.map +1 -1
- package/dist/guards/index.d.cts +6 -6
- package/dist/guards/index.d.ts +6 -6
- package/dist/guards/index.js +6 -6
- package/dist/{hash-BSd0-_L8.d.cts → hash-CqRZfDZH.d.cts} +1 -1
- package/dist/{hash-BnBQx39y.d.ts → hash-cF4iWaBV.d.ts} +1 -1
- package/dist/history/index.cjs.map +1 -1
- package/dist/history/index.d.cts +6 -6
- package/dist/history/index.d.ts +6 -6
- package/dist/history/index.js +5 -5
- package/dist/i18n/index.cjs.map +1 -1
- package/dist/i18n/index.d.cts +5 -5
- package/dist/i18n/index.d.ts +5 -5
- package/dist/i18n/index.js +6 -6
- package/dist/index-B8MoIS7B.d.ts +70 -0
- package/dist/{index-Bm9hIY7t.d.ts → index-BLff_E35.d.ts} +2 -2
- package/dist/{index-tZqVB9g5.d.cts → index-BthnP2MA.d.cts} +2 -2
- package/dist/index-da0M3NnR.d.cts +70 -0
- package/dist/index.cjs +25861 -25119
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +135 -80
- package/dist/index.d.ts +135 -80
- package/dist/index.js +93 -52
- package/dist/index.js.map +1 -1
- package/dist/indexing/index.cjs.map +1 -1
- package/dist/indexing/index.js +4 -4
- package/dist/issue-KLRMW5DH.js +12 -0
- package/dist/kernel/index.cjs +657 -0
- package/dist/kernel/index.cjs.map +1 -0
- package/dist/kernel/index.d.cts +11 -0
- package/dist/kernel/index.d.ts +11 -0
- package/dist/kernel/index.js +40 -0
- package/dist/{ledger-I7JUYP4L.js → ledger-VOS2X3WJ.js} +5 -5
- package/dist/materialized-views/index.cjs.map +1 -1
- package/dist/materialized-views/index.d.cts +6 -6
- package/dist/materialized-views/index.d.ts +6 -6
- package/dist/materialized-views/index.js +8 -8
- package/dist/{mime-magic-CjSyakO4.d.ts → mime-magic-BswIvWkR.d.ts} +1 -1
- package/dist/{mime-magic-BnJCGJzB.d.cts → mime-magic-CCrP-iXJ.d.cts} +1 -1
- package/dist/{ulid-B2L_aqVA.d.ts → multi-bundle-6s5nKAZX.d.ts} +114 -58
- package/dist/{ulid-LaxfH2tK.d.cts → multi-bundle-WhYiJEgV.d.cts} +114 -58
- package/dist/noydb-2PI2ZBX6.js +38 -0
- package/dist/overlay-views/index.cjs.map +1 -1
- package/dist/overlay-views/index.d.cts +6 -6
- package/dist/overlay-views/index.d.ts +6 -6
- package/dist/overlay-views/index.js +4 -4
- package/dist/periods/index.cjs.map +1 -1
- package/dist/periods/index.d.cts +5 -5
- package/dist/periods/index.d.ts +5 -5
- package/dist/periods/index.js +5 -5
- package/dist/{public-envelope-5XRTUNKF.js → public-envelope-IJJMWSTJ.js} +4 -4
- package/dist/query/index.cjs.map +1 -1
- package/dist/query/index.d.cts +3 -3
- package/dist/query/index.d.ts +3 -3
- package/dist/query/index.js +7 -7
- package/dist/registry-GAIFVWXF.js +8 -0
- package/dist/registry-J77ZUQ7G.js +8 -0
- package/dist/{registry-NWHOLD5M.js → registry-JGEVJ6YC.js} +3 -3
- package/dist/{revoke-5IEK22KT.js → revoke-WUY4AYRJ.js} +6 -6
- package/dist/sealed-record/index.cjs.map +1 -1
- package/dist/sealed-record/index.d.cts +1 -1
- package/dist/sealed-record/index.d.ts +1 -1
- package/dist/sealed-record/index.js +2 -2
- package/dist/session/index.cjs.map +1 -1
- package/dist/session/index.d.cts +6 -6
- package/dist/session/index.d.ts +6 -6
- package/dist/session/index.js +3 -3
- package/dist/shadow/index.cjs.map +1 -1
- package/dist/shadow/index.d.cts +5 -5
- package/dist/shadow/index.d.ts +5 -5
- package/dist/shadow/index.js +2 -2
- package/dist/{signer-I6YARZQA.js → signer-UJF3CFDC.js} +5 -5
- package/dist/snapshots/index.cjs.map +1 -1
- package/dist/snapshots/index.d.cts +5 -5
- package/dist/snapshots/index.d.ts +5 -5
- package/dist/snapshots/index.js +4 -4
- package/dist/{stale-CPESGAPL.js → stale-PW6VBGSP.js} +2 -2
- package/dist/store/index.cjs.map +1 -1
- package/dist/store/index.d.cts +5 -5
- package/dist/store/index.d.ts +5 -5
- package/dist/store/index.js +2 -2
- package/dist/{strategy-WtB-jXYv.d.cts → strategy-BWmgRPA2.d.cts} +1 -1
- package/dist/{strategy-54eIwox5.d.ts → strategy-D47TC5X6.d.ts} +1 -1
- package/dist/sync/index.cjs.map +1 -1
- package/dist/sync/index.d.cts +4 -4
- package/dist/sync/index.d.ts +4 -4
- package/dist/sync/index.js +4 -4
- package/dist/team/index.cjs +10 -3
- package/dist/team/index.cjs.map +1 -1
- package/dist/team/index.d.cts +5 -5
- package/dist/team/index.d.ts +5 -5
- package/dist/team/index.js +8 -8
- package/dist/{transition-guard-Dmpqzg-_.d.cts → transition-guard-C3NxfVKk.d.cts} +1 -1
- package/dist/{transition-guard-D4bfIAiW.d.ts → transition-guard-CQH5263l.d.ts} +1 -1
- package/dist/tx/index.cjs +1 -1
- package/dist/tx/index.cjs.map +1 -1
- package/dist/tx/index.d.cts +5 -5
- package/dist/tx/index.d.ts +5 -5
- package/dist/tx/index.js +3 -3
- package/dist/{types-DLfWFr6U.d.ts → types-BGRX6sPT.d.ts} +546 -580
- package/dist/{types-DyOI6XZ_.d.cts → types-COQ6qJZh.d.cts} +546 -580
- package/dist/ulid-DRH25k3y.d.cts +66 -0
- package/dist/ulid-DRH25k3y.d.ts +66 -0
- package/dist/util/index.cjs.map +1 -1
- package/dist/util/index.js +1 -1
- package/dist/{with-materialized-view-DNULSxoP.d.ts → with-materialized-view-Cj-6fuav.d.ts} +1 -1
- package/dist/{with-materialized-view-CeZYGJVf.d.cts → with-materialized-view-D4U-KrBH.d.cts} +1 -1
- package/dist/{with-overlayed-view-kdcPGHih.d.cts → with-overlayed-view-BKjdUPRx.d.cts} +1 -1
- package/dist/{with-overlayed-view-C9joG7UZ.d.ts → with-overlayed-view-COp_7EEy.d.ts} +1 -1
- package/dist/{with-rollup-DJDbrxjf.d.ts → with-rollup-B1_ZjG02.d.ts} +1 -1
- package/dist/{with-rollup-s58XAeWO.d.cts → with-rollup-C-Bok_o2.d.cts} +1 -1
- package/package.json +13 -3
- package/dist/chunk-7PH4OPBZ.js.map +0 -1
- package/dist/chunk-C6W5KVDV.js.map +0 -1
- package/dist/chunk-EYK72OTL.js.map +0 -1
- package/dist/chunk-FRRJIUSI.js.map +0 -1
- package/dist/chunk-HYJMAV53.js.map +0 -1
- package/dist/chunk-JTI57WRT.js +0 -164
- package/dist/chunk-JTI57WRT.js.map +0 -1
- package/dist/chunk-OTWT6BAJ.js.map +0 -1
- package/dist/chunk-TA6HPKWQ.js.map +0 -1
- package/dist/chunk-ZC7J6ZYV.js +0 -7
- package/dist/chunk-ZC7J6ZYV.js.map +0 -1
- package/dist/executor-4IEW4KG5.js +0 -8
- package/dist/executor-KYJCJCIN.js +0 -12
- package/dist/executor-W7VIBOBZ.js +0 -8
- package/dist/issue-JXC6T2QR.js +0 -12
- package/dist/noydb-ZZCRF6TE.js +0 -38
- package/dist/registry-ATRHOG5B.js +0 -8
- package/dist/registry-LEHB26TY.js +0 -8
- package/dist/state-vault-JR3CFGNP.js +0 -14
- package/dist/vault-group-BB246VIM.js +0 -804
- package/dist/vault-group-BB246VIM.js.map +0 -1
- /package/dist/{chunk-CQYEDODS.js.map → chunk-35U5YNRR.js.map} +0 -0
- /package/dist/{chunk-NV4IHBZS.js.map → chunk-3XJU3OHE.js.map} +0 -0
- /package/dist/{chunk-IVZWHIEK.js.map → chunk-4HEGG5NJ.js.map} +0 -0
- /package/dist/{chunk-WE2BUQD2.js.map → chunk-4TCMCCC3.js.map} +0 -0
- /package/dist/{chunk-5YTXYPES.js.map → chunk-5A2FVGHT.js.map} +0 -0
- /package/dist/{chunk-NSXNXLYM.js.map → chunk-5GZC2ZM3.js.map} +0 -0
- /package/dist/{chunk-JYNH4FIM.js.map → chunk-77WF53XY.js.map} +0 -0
- /package/dist/{chunk-O5XKZCUD.js.map → chunk-7X4EF35A.js.map} +0 -0
- /package/dist/{chunk-SQKAECUL.js.map → chunk-7ZCTUI26.js.map} +0 -0
- /package/dist/{chunk-J6RGRZOY.js.map → chunk-AO3QSMCU.js.map} +0 -0
- /package/dist/{chunk-JDCPRJVS.js.map → chunk-AONK5GCC.js.map} +0 -0
- /package/dist/{chunk-TYMDCIQM.js.map → chunk-C472BRJ4.js.map} +0 -0
- /package/dist/{chunk-MBXKRHSS.js.map → chunk-CCNRFAL3.js.map} +0 -0
- /package/dist/{chunk-BZW5IL43.js.map → chunk-DCA2BDHA.js.map} +0 -0
- /package/dist/{chunk-JBBWALNI.js.map → chunk-DCICHSRS.js.map} +0 -0
- /package/dist/{chunk-2XA2ZML4.js.map → chunk-FG6IQ3ZL.js.map} +0 -0
- /package/dist/{chunk-C2RJVZZL.js.map → chunk-G4GW5VOS.js.map} +0 -0
- /package/dist/{chunk-U2XSUCDF.js.map → chunk-GEWIFM4J.js.map} +0 -0
- /package/dist/{chunk-TNH5SLCD.js.map → chunk-HD4QCT2O.js.map} +0 -0
- /package/dist/{chunk-I3IYTUUI.js.map → chunk-HHJ5DZCZ.js.map} +0 -0
- /package/dist/{chunk-6QAZ5O6X.js.map → chunk-IEIADIPM.js.map} +0 -0
- /package/dist/{chunk-YPIOFSN3.js.map → chunk-IHAISFXP.js.map} +0 -0
- /package/dist/{chunk-GJTKMME7.js.map → chunk-JKM2AVVH.js.map} +0 -0
- /package/dist/{chunk-S45MDEEF.js.map → chunk-LMWVNF6X.js.map} +0 -0
- /package/dist/{chunk-TAMRU7A2.js.map → chunk-OKV7S356.js.map} +0 -0
- /package/dist/{chunk-IW4L4X65.js.map → chunk-P5A4E53B.js.map} +0 -0
- /package/dist/{chunk-JOK73NDT.js.map → chunk-P7OL22JP.js.map} +0 -0
- /package/dist/{chunk-TGIJTNM3.js.map → chunk-R5ZECURV.js.map} +0 -0
- /package/dist/{chunk-KOAJ3TZM.js.map → chunk-RFEXGW3L.js.map} +0 -0
- /package/dist/{chunk-F5ILTHMU.js.map → chunk-RNQPDV75.js.map} +0 -0
- /package/dist/{chunk-WWVJXBOT.js.map → chunk-SGM7CK7R.js.map} +0 -0
- /package/dist/{chunk-7MRT7EPB.js.map → chunk-SOQE5DUV.js.map} +0 -0
- /package/dist/{chunk-ZONKSLF2.js.map → chunk-TQMQZOMX.js.map} +0 -0
- /package/dist/{chunk-3HNKR65T.js.map → chunk-U6LTLN7O.js.map} +0 -0
- /package/dist/{chunk-UU6M64HI.js.map → chunk-UAK2AMO2.js.map} +0 -0
- /package/dist/{chunk-37VGJM3T.js.map → chunk-WQ3KAGOV.js.map} +0 -0
- /package/dist/{chunk-AI4USDRI.js.map → chunk-XQO4TAJS.js.map} +0 -0
- /package/dist/{chunk-SQOK5UM6.js.map → chunk-ZBENTRFS.js.map} +0 -0
- /package/dist/{chunk-6QE4DUYC.js.map → chunk-ZDITTESU.js.map} +0 -0
- /package/dist/{crypto-456N7UVX.js.map → crypto-2LU6XUFF.js.map} +0 -0
- /package/dist/{delegation-DP4COTXB.js.map → delegation-6ABSJGXV.js.map} +0 -0
- /package/dist/{executor-4IEW4KG5.js.map → executor-JKMSEB34.js.map} +0 -0
- /package/dist/{executor-KYJCJCIN.js.map → executor-UYXSQB4D.js.map} +0 -0
- /package/dist/{executor-W7VIBOBZ.js.map → executor-VJSCTBWY.js.map} +0 -0
- /package/dist/{fanout-sidecar-YXNAEZ33.js.map → fanout-sidecar-ZQT4Y7PF.js.map} +0 -0
- /package/dist/{issue-JXC6T2QR.js.map → issue-KLRMW5DH.js.map} +0 -0
- /package/dist/{ledger-I7JUYP4L.js.map → kernel/index.js.map} +0 -0
- /package/dist/{noydb-ZZCRF6TE.js.map → ledger-VOS2X3WJ.js.map} +0 -0
- /package/dist/{public-envelope-5XRTUNKF.js.map → noydb-2PI2ZBX6.js.map} +0 -0
- /package/dist/{registry-ATRHOG5B.js.map → public-envelope-IJJMWSTJ.js.map} +0 -0
- /package/dist/{registry-LEHB26TY.js.map → registry-GAIFVWXF.js.map} +0 -0
- /package/dist/{registry-NWHOLD5M.js.map → registry-J77ZUQ7G.js.map} +0 -0
- /package/dist/{revoke-5IEK22KT.js.map → registry-JGEVJ6YC.js.map} +0 -0
- /package/dist/{signer-I6YARZQA.js.map → revoke-WUY4AYRJ.js.map} +0 -0
- /package/dist/{stale-CPESGAPL.js.map → signer-UJF3CFDC.js.map} +0 -0
- /package/dist/{state-vault-JR3CFGNP.js.map → stale-PW6VBGSP.js.map} +0 -0
|
@@ -1,804 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
StateManagementVault
|
|
3
|
-
} from "./chunk-JTI57WRT.js";
|
|
4
|
-
import {
|
|
5
|
-
STATE_VAULT_NAME
|
|
6
|
-
} from "./chunk-ZC7J6ZYV.js";
|
|
7
|
-
import {
|
|
8
|
-
groupAndReduce,
|
|
9
|
-
reduceRecords
|
|
10
|
-
} from "./chunk-JYNH4FIM.js";
|
|
11
|
-
import {
|
|
12
|
-
readPath
|
|
13
|
-
} from "./chunk-U2XSUCDF.js";
|
|
14
|
-
import "./chunk-TNH5SLCD.js";
|
|
15
|
-
import "./chunk-FZU343FL.js";
|
|
16
|
-
import "./chunk-37VGJM3T.js";
|
|
17
|
-
import {
|
|
18
|
-
CrossShardJoinError,
|
|
19
|
-
DataResidencyError,
|
|
20
|
-
NoAccessError,
|
|
21
|
-
ReservedVaultNameError,
|
|
22
|
-
ShardProvisioningError,
|
|
23
|
-
UnknownShardError,
|
|
24
|
-
ValidationError
|
|
25
|
-
} from "./chunk-OTWT6BAJ.js";
|
|
26
|
-
|
|
27
|
-
// src/federation/classify-skip.ts
|
|
28
|
-
function classifyShardSkip(err) {
|
|
29
|
-
return err instanceof NoAccessError ? "no-grant" : "error";
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
// src/federation/cross-shard-join.ts
|
|
33
|
-
function coerceKey(value) {
|
|
34
|
-
if (value === null || value === void 0) return null;
|
|
35
|
-
if (typeof value === "string") return value;
|
|
36
|
-
if (typeof value === "number" || typeof value === "bigint") return String(value);
|
|
37
|
-
return null;
|
|
38
|
-
}
|
|
39
|
-
var warnedBroadcastKeys = /* @__PURE__ */ new Set();
|
|
40
|
-
function warnOnceBroadcastMiss(field, as, key) {
|
|
41
|
-
const dedup = `${field}\u2192${as}:${key}`;
|
|
42
|
-
if (warnedBroadcastKeys.has(dedup)) return;
|
|
43
|
-
warnedBroadcastKeys.add(dedup);
|
|
44
|
-
console.warn(
|
|
45
|
-
`[noy-db] broadcastJoin: no "${as}" dimension row for ${field}="${key}". Attaching null. Use mode: 'cascade' to silence.`
|
|
46
|
-
);
|
|
47
|
-
}
|
|
48
|
-
async function applyBroadcastLegs(rows, legs) {
|
|
49
|
-
if (legs.length === 0) return [...rows];
|
|
50
|
-
const indexes = [];
|
|
51
|
-
for (const leg of legs) {
|
|
52
|
-
const map = /* @__PURE__ */ new Map();
|
|
53
|
-
for (const rec of await leg.from.list()) {
|
|
54
|
-
const k = coerceKey(readPath(rec, leg.on));
|
|
55
|
-
if (k !== null && !map.has(k)) map.set(k, rec);
|
|
56
|
-
}
|
|
57
|
-
indexes.push({ leg, map });
|
|
58
|
-
}
|
|
59
|
-
return rows.map((row) => {
|
|
60
|
-
const out = { ...row };
|
|
61
|
-
for (const { leg, map } of indexes) {
|
|
62
|
-
const key = coerceKey(readPath(row, leg.field));
|
|
63
|
-
const match = key === null ? null : map.get(key) ?? null;
|
|
64
|
-
if (match === null && leg.mode === "warn") {
|
|
65
|
-
warnOnceBroadcastMiss(leg.field, leg.as, key ?? "<null>");
|
|
66
|
-
}
|
|
67
|
-
out[leg.as] = match;
|
|
68
|
-
}
|
|
69
|
-
return out;
|
|
70
|
-
});
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
// src/federation/cross-vault-live.ts
|
|
74
|
-
var CrossVaultLive = class {
|
|
75
|
-
snapshot;
|
|
76
|
-
error = null;
|
|
77
|
-
ready;
|
|
78
|
-
subs = /* @__PURE__ */ new Set();
|
|
79
|
-
unsubChange;
|
|
80
|
-
opts;
|
|
81
|
-
stopped = false;
|
|
82
|
-
computing = false;
|
|
83
|
-
dirty = false;
|
|
84
|
-
scheduled = false;
|
|
85
|
-
timer = null;
|
|
86
|
-
resolveReady;
|
|
87
|
-
settledOnce = false;
|
|
88
|
-
constructor(opts) {
|
|
89
|
-
this.opts = opts;
|
|
90
|
-
this.snapshot = opts.initialSnapshot;
|
|
91
|
-
this.ready = new Promise((res) => {
|
|
92
|
-
this.resolveReady = res;
|
|
93
|
-
});
|
|
94
|
-
this.unsubChange = opts.subscribeToChanges((e) => {
|
|
95
|
-
if (this.stopped || !opts.isRelevant(e)) return;
|
|
96
|
-
this.schedule();
|
|
97
|
-
});
|
|
98
|
-
this.schedule();
|
|
99
|
-
}
|
|
100
|
-
subscribe(cb) {
|
|
101
|
-
if (this.stopped) return () => {
|
|
102
|
-
};
|
|
103
|
-
this.subs.add(cb);
|
|
104
|
-
return () => this.subs.delete(cb);
|
|
105
|
-
}
|
|
106
|
-
stop() {
|
|
107
|
-
if (this.stopped) return;
|
|
108
|
-
this.stopped = true;
|
|
109
|
-
this.unsubChange();
|
|
110
|
-
if (this.timer !== null) clearTimeout(this.timer);
|
|
111
|
-
this.subs.clear();
|
|
112
|
-
if (!this.settledOnce) this.resolveReady();
|
|
113
|
-
}
|
|
114
|
-
schedule() {
|
|
115
|
-
if (this.stopped) return;
|
|
116
|
-
if (this.computing) {
|
|
117
|
-
this.dirty = true;
|
|
118
|
-
return;
|
|
119
|
-
}
|
|
120
|
-
if (this.scheduled) return;
|
|
121
|
-
this.scheduled = true;
|
|
122
|
-
const run = () => {
|
|
123
|
-
this.scheduled = false;
|
|
124
|
-
void this.runCompute();
|
|
125
|
-
};
|
|
126
|
-
const ms = this.opts.debounceMs ?? 0;
|
|
127
|
-
if (ms > 0) this.timer = setTimeout(run, ms);
|
|
128
|
-
else queueMicrotask(run);
|
|
129
|
-
}
|
|
130
|
-
async runCompute() {
|
|
131
|
-
if (this.stopped) return;
|
|
132
|
-
this.computing = true;
|
|
133
|
-
this.dirty = false;
|
|
134
|
-
try {
|
|
135
|
-
const next = await this.opts.compute();
|
|
136
|
-
if (this.stopped) return;
|
|
137
|
-
this.snapshot = next;
|
|
138
|
-
this.error = null;
|
|
139
|
-
} catch (err) {
|
|
140
|
-
if (this.stopped) return;
|
|
141
|
-
this.error = err instanceof Error ? err : new Error(String(err));
|
|
142
|
-
} finally {
|
|
143
|
-
this.computing = false;
|
|
144
|
-
if (!this.stopped) {
|
|
145
|
-
if (!this.settledOnce) {
|
|
146
|
-
this.settledOnce = true;
|
|
147
|
-
this.resolveReady();
|
|
148
|
-
}
|
|
149
|
-
for (const cb of this.subs) cb();
|
|
150
|
-
if (this.dirty) this.schedule();
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
};
|
|
155
|
-
|
|
156
|
-
// src/federation/aggregate-across.ts
|
|
157
|
-
var CrossVaultAggregation = class {
|
|
158
|
-
constructor(src, spec, bind) {
|
|
159
|
-
this.src = src;
|
|
160
|
-
this.spec = spec;
|
|
161
|
-
this.bind = bind;
|
|
162
|
-
}
|
|
163
|
-
src;
|
|
164
|
-
spec;
|
|
165
|
-
bind;
|
|
166
|
-
async run(options = {}) {
|
|
167
|
-
const { records, skippedVaults } = await this.src.fanoutRecords(options);
|
|
168
|
-
return { result: reduceRecords(records, this.spec), skippedVaults };
|
|
169
|
-
}
|
|
170
|
-
live(options = {}) {
|
|
171
|
-
if (!this.bind) throw new Error("CrossVaultAggregation: live() requires a LiveBinding \u2014 use ShardedQuery.aggregate()");
|
|
172
|
-
const spec = this.spec;
|
|
173
|
-
const src = this.src;
|
|
174
|
-
const core = new CrossVaultLive({
|
|
175
|
-
subscribeToChanges: this.bind.subscribeToChanges,
|
|
176
|
-
isRelevant: this.bind.isRelevant,
|
|
177
|
-
compute: async () => {
|
|
178
|
-
const { records, skippedVaults } = await src.fanoutRecords(options);
|
|
179
|
-
return { value: reduceRecords(records, spec), skipped: skippedVaults };
|
|
180
|
-
},
|
|
181
|
-
initialSnapshot: { value: void 0, skipped: [] },
|
|
182
|
-
...options.debounceMs !== void 0 ? { debounceMs: options.debounceMs } : {}
|
|
183
|
-
});
|
|
184
|
-
return {
|
|
185
|
-
get value() {
|
|
186
|
-
return core.snapshot.value;
|
|
187
|
-
},
|
|
188
|
-
get skippedVaults() {
|
|
189
|
-
return core.snapshot.skipped;
|
|
190
|
-
},
|
|
191
|
-
get error() {
|
|
192
|
-
return core.error;
|
|
193
|
-
},
|
|
194
|
-
ready: core.ready,
|
|
195
|
-
subscribe: (cb) => core.subscribe(cb),
|
|
196
|
-
stop: () => core.stop()
|
|
197
|
-
};
|
|
198
|
-
}
|
|
199
|
-
};
|
|
200
|
-
var CrossVaultGroupedAggregation = class {
|
|
201
|
-
constructor(src, field, spec, bind) {
|
|
202
|
-
this.src = src;
|
|
203
|
-
this.field = field;
|
|
204
|
-
this.spec = spec;
|
|
205
|
-
this.bind = bind;
|
|
206
|
-
}
|
|
207
|
-
src;
|
|
208
|
-
field;
|
|
209
|
-
spec;
|
|
210
|
-
bind;
|
|
211
|
-
async run(options = {}) {
|
|
212
|
-
const { records, skippedVaults } = await this.src.fanoutRecords(options);
|
|
213
|
-
return {
|
|
214
|
-
results: groupAndReduce(records, this.field, this.spec),
|
|
215
|
-
skippedVaults
|
|
216
|
-
};
|
|
217
|
-
}
|
|
218
|
-
live(options = {}) {
|
|
219
|
-
if (!this.bind) throw new Error("CrossVaultGroupedAggregation: live() requires a LiveBinding \u2014 use ShardedQuery.groupBy().aggregate()");
|
|
220
|
-
const field = this.field;
|
|
221
|
-
const spec = this.spec;
|
|
222
|
-
const src = this.src;
|
|
223
|
-
const core = new CrossVaultLive({
|
|
224
|
-
subscribeToChanges: this.bind.subscribeToChanges,
|
|
225
|
-
isRelevant: this.bind.isRelevant,
|
|
226
|
-
compute: async () => {
|
|
227
|
-
const { records, skippedVaults } = await src.fanoutRecords(options);
|
|
228
|
-
return {
|
|
229
|
-
records: groupAndReduce(records, field, spec),
|
|
230
|
-
skipped: skippedVaults
|
|
231
|
-
};
|
|
232
|
-
},
|
|
233
|
-
initialSnapshot: { records: [], skipped: [] },
|
|
234
|
-
...options.debounceMs !== void 0 ? { debounceMs: options.debounceMs } : {}
|
|
235
|
-
});
|
|
236
|
-
return {
|
|
237
|
-
get value() {
|
|
238
|
-
return core.snapshot.records;
|
|
239
|
-
},
|
|
240
|
-
get skippedVaults() {
|
|
241
|
-
return core.snapshot.skipped;
|
|
242
|
-
},
|
|
243
|
-
get error() {
|
|
244
|
-
return core.error;
|
|
245
|
-
},
|
|
246
|
-
ready: core.ready,
|
|
247
|
-
subscribe: (cb) => core.subscribe(cb),
|
|
248
|
-
stop: () => core.stop()
|
|
249
|
-
};
|
|
250
|
-
}
|
|
251
|
-
};
|
|
252
|
-
|
|
253
|
-
// src/federation/vault-group.ts
|
|
254
|
-
var SHARD_SEPARATOR = "--";
|
|
255
|
-
var SAFE_PARTITION_KEY = /^[A-Za-z0-9._-]+$/;
|
|
256
|
-
function assertSafePartitionKey(partitionKey) {
|
|
257
|
-
if (partitionKey.length === 0) {
|
|
258
|
-
throw new ValidationError("partitionKey must be a non-empty string");
|
|
259
|
-
}
|
|
260
|
-
if (partitionKey === STATE_VAULT_NAME) {
|
|
261
|
-
throw new ReservedVaultNameError(partitionKey);
|
|
262
|
-
}
|
|
263
|
-
if (!SAFE_PARTITION_KEY.test(partitionKey)) {
|
|
264
|
-
throw new ValidationError(
|
|
265
|
-
`partitionKey "${partitionKey}" contains characters outside [A-Za-z0-9._-]. Map your records to a store-safe key in sharding.keyOf.`
|
|
266
|
-
);
|
|
267
|
-
}
|
|
268
|
-
if (partitionKey.includes(SHARD_SEPARATOR)) {
|
|
269
|
-
throw new ValidationError(
|
|
270
|
-
`partitionKey "${partitionKey}" must not contain "--" \u2014 it is reserved as the shard vault-id separator and would risk shard-id collisions.`
|
|
271
|
-
);
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
var VaultGroup = class {
|
|
275
|
-
constructor(db, name, registry, sharding, template, migrateOnOpen = false) {
|
|
276
|
-
this.db = db;
|
|
277
|
-
this.name = name;
|
|
278
|
-
this.registry = registry;
|
|
279
|
-
this.sharding = sharding;
|
|
280
|
-
this.template = template;
|
|
281
|
-
this.migrateOnOpen = migrateOnOpen;
|
|
282
|
-
if (name.includes(SHARD_SEPARATOR)) {
|
|
283
|
-
throw new ValidationError(
|
|
284
|
-
`VaultGroup name "${name}" must not contain "--" (reserved shard vault-id separator).`
|
|
285
|
-
);
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
db;
|
|
289
|
-
name;
|
|
290
|
-
registry;
|
|
291
|
-
sharding;
|
|
292
|
-
template;
|
|
293
|
-
migrateOnOpen;
|
|
294
|
-
/** @internal — set when the group is managed (no explicit registry). */
|
|
295
|
-
stateVault;
|
|
296
|
-
/** @internal */
|
|
297
|
-
_attachStateVault(sv) {
|
|
298
|
-
this.stateVault = sv;
|
|
299
|
-
}
|
|
300
|
-
/** Deterministic vault name for a partition key, namespaced by the group. */
|
|
301
|
-
shardVaultId(partitionKey) {
|
|
302
|
-
assertSafePartitionKey(partitionKey);
|
|
303
|
-
return `${this.name}${SHARD_SEPARATOR}${partitionKey}`;
|
|
304
|
-
}
|
|
305
|
-
/**
|
|
306
|
-
* @internal — group-qualified registry record key (avoids cross-group key
|
|
307
|
-
* collisions). Identical to the shard vault id by design — the registry row
|
|
308
|
-
* for a shard is keyed by that shard's vault id — so it delegates to
|
|
309
|
-
* `shardVaultId`, reusing its partition-key validation.
|
|
310
|
-
*/
|
|
311
|
-
registryId(partitionKey) {
|
|
312
|
-
return this.shardVaultId(partitionKey);
|
|
313
|
-
}
|
|
314
|
-
/**
|
|
315
|
-
* Registry rows for THIS group (hydrates the registry collection first).
|
|
316
|
-
* The registry may be shared across groups (the auto-wired StateManagement
|
|
317
|
-
* vault holds one `vaultRegistry` for the whole instance), so rows are
|
|
318
|
-
* filtered by `group` — without this, a group's fan-out reads would leak
|
|
319
|
-
* across into other groups' shards. Mirrors the `${group}--` scoping that
|
|
320
|
-
* `liveBinding().isRelevant` already applies to the reactive path.
|
|
321
|
-
*/
|
|
322
|
-
async allRows() {
|
|
323
|
-
await this.registry.list();
|
|
324
|
-
const rows = this.registry.query().toArray();
|
|
325
|
-
return rows.filter((r) => r.group === this.name);
|
|
326
|
-
}
|
|
327
|
-
/**
|
|
328
|
-
* Open an existing shard and apply the template. When `migrateOnOpen` is set
|
|
329
|
-
* (#271) and the shard's registry version is behind the template, its cutover
|
|
330
|
-
* runs inline first — so a behind shard never surfaces a stale handle.
|
|
331
|
-
*/
|
|
332
|
-
async openShard(partitionKey) {
|
|
333
|
-
if (this.migrateOnOpen) {
|
|
334
|
-
const row = await this.registry.get(this.registryId(partitionKey));
|
|
335
|
-
if (row && row.schemaVersion < this.template.version) {
|
|
336
|
-
await this.migrateShard(partitionKey);
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
return this._openShardRaw(partitionKey);
|
|
340
|
-
}
|
|
341
|
-
/** @internal — open + configure with no migrate-on-open hook (used by the migration path itself to avoid recursion). */
|
|
342
|
-
async _openShardRaw(partitionKey) {
|
|
343
|
-
const vault = await this.db.openVault(this.shardVaultId(partitionKey), { create: false });
|
|
344
|
-
this.template.configure(vault);
|
|
345
|
-
return vault;
|
|
346
|
-
}
|
|
347
|
-
/**
|
|
348
|
-
* Idempotently provision a shard for `partitionKey`. Returns the
|
|
349
|
-
* configured vault handle.
|
|
350
|
-
*
|
|
351
|
-
* - row + vault present → no-op, return handle
|
|
352
|
-
* - row present, vault gone → ShardProvisioningError
|
|
353
|
-
* - row absent (vault present or not) → open-or-create, configure, write row
|
|
354
|
-
*
|
|
355
|
-
* When `region` is given (the routing `put` passes `sharding.regionOf(record)`),
|
|
356
|
-
* the candidate backend's `capabilities.region` must match or this throws
|
|
357
|
-
* `DataResidencyError` BEFORE provisioning (#271 data-residency guard).
|
|
358
|
-
*/
|
|
359
|
-
async createShard(partitionKey, region) {
|
|
360
|
-
const vaultId = this.shardVaultId(partitionKey);
|
|
361
|
-
const row = await this.registry.get(this.registryId(partitionKey));
|
|
362
|
-
const provisioned = await this.db._shardVaultProvisioned(vaultId);
|
|
363
|
-
if (row && !provisioned) throw new ShardProvisioningError(vaultId, partitionKey);
|
|
364
|
-
if (row && provisioned) return this.openShard(partitionKey);
|
|
365
|
-
if (region !== void 0) {
|
|
366
|
-
const backendRegion = this.db._resolveBackend(vaultId).capabilities?.region;
|
|
367
|
-
if (backendRegion !== region) throw new DataResidencyError(vaultId, region, backendRegion);
|
|
368
|
-
}
|
|
369
|
-
const vault = await this.db.openVault(vaultId);
|
|
370
|
-
this.template.configure(vault);
|
|
371
|
-
await this.registry.put(this.registryId(partitionKey), {
|
|
372
|
-
vaultId,
|
|
373
|
-
partitionKey,
|
|
374
|
-
templateName: this.sharding.vaultTemplate,
|
|
375
|
-
schemaVersion: this.template.version,
|
|
376
|
-
createdAt: Date.now(),
|
|
377
|
-
group: this.name
|
|
378
|
-
});
|
|
379
|
-
if (this.stateVault) {
|
|
380
|
-
try {
|
|
381
|
-
await this.stateVault.appendEvent({
|
|
382
|
-
type: "shard-created",
|
|
383
|
-
group: this.name,
|
|
384
|
-
vaultId,
|
|
385
|
-
templateName: this.sharding.vaultTemplate,
|
|
386
|
-
version: this.template.version
|
|
387
|
-
});
|
|
388
|
-
} catch {
|
|
389
|
-
}
|
|
390
|
-
}
|
|
391
|
-
return vault;
|
|
392
|
-
}
|
|
393
|
-
/**
|
|
394
|
-
* Drill down to a single shard's full Collection API. Throws if the shard is unknown.
|
|
395
|
-
* Also throws ShardProvisioningError if the registry row exists but the vault has been deleted
|
|
396
|
-
* (registry/store divergence).
|
|
397
|
-
*/
|
|
398
|
-
async shard(partitionKey) {
|
|
399
|
-
const vaultId = this.shardVaultId(partitionKey);
|
|
400
|
-
const row = await this.registry.get(this.registryId(partitionKey));
|
|
401
|
-
if (!row) throw new UnknownShardError(partitionKey, this.name);
|
|
402
|
-
const provisioned = await this.db._shardVaultProvisioned(vaultId);
|
|
403
|
-
if (!provisioned) throw new ShardProvisioningError(vaultId, partitionKey);
|
|
404
|
-
return this.openShard(partitionKey);
|
|
405
|
-
}
|
|
406
|
-
/** A sharded view over one logical collection across all shards. */
|
|
407
|
-
collection(collectionName) {
|
|
408
|
-
return new ShardedCollection(this, collectionName);
|
|
409
|
-
}
|
|
410
|
-
/** @internal — eligible (openable-candidate) rows + drift/divergence skips. */
|
|
411
|
-
async resolveEligible(options = {}) {
|
|
412
|
-
const rows = await this.allRows();
|
|
413
|
-
const skipped = [];
|
|
414
|
-
const versionOk = [];
|
|
415
|
-
for (const row of rows) {
|
|
416
|
-
if (options.minVersion !== void 0 && row.schemaVersion < options.minVersion) {
|
|
417
|
-
skipped.push({ vaultId: row.vaultId, reason: "schema-drift" });
|
|
418
|
-
} else versionOk.push(row);
|
|
419
|
-
}
|
|
420
|
-
const provisioned = await Promise.all(versionOk.map((r) => this.db._shardVaultProvisioned(r.vaultId)));
|
|
421
|
-
const eligible = [];
|
|
422
|
-
versionOk.forEach((row, i) => {
|
|
423
|
-
if (provisioned[i]) eligible.push(row);
|
|
424
|
-
else skipped.push({ vaultId: row.vaultId, reason: "error", error: new ShardProvisioningError(row.vaultId, row.partitionKey) });
|
|
425
|
-
});
|
|
426
|
-
return { eligible, skipped };
|
|
427
|
-
}
|
|
428
|
-
/** @internal — registered push-model cross-vault derivations (#271 Insight Vault). */
|
|
429
|
-
crossVaultDerivations = [];
|
|
430
|
-
/**
|
|
431
|
-
* Register a push-model cross-vault derivation — the Insight Vault pattern
|
|
432
|
-
* (#271, Layer 4). Drive it with {@link refreshInsights}.
|
|
433
|
-
*
|
|
434
|
-
* For each shard, `derive(records, ctx)` runs on that shard's `source`
|
|
435
|
-
* records and its return value is written into the analytics
|
|
436
|
-
* (`target.vault` / `target.collection`) vault, keyed by partition key —
|
|
437
|
-
* one summary row per shard. The derivation runs in-process under THIS
|
|
438
|
-
* group's `Noydb` (which already holds both the shard and Insight Vault
|
|
439
|
-
* keyrings); the shard's decrypted records are reduced to a summary that is
|
|
440
|
-
* re-encrypted under the Insight Vault's own DEK, so no shard ciphertext
|
|
441
|
-
* crosses a DEK boundary.
|
|
442
|
-
*
|
|
443
|
-
* **Zero-knowledge note:** the Insight Vault backend sees aggregated
|
|
444
|
-
* structure (totals, counts, timestamps) drawn from many shards — a weaker
|
|
445
|
-
* ZK profile than the per-shard vaults. Opt-in; keep summaries to aggregate
|
|
446
|
-
* scalars (no embeddings / no raw records).
|
|
447
|
-
*
|
|
448
|
-
* v1 is explicit-refresh (no write-path push); call `refreshInsights()`
|
|
449
|
-
* after a batch of writes, or on a schedule.
|
|
450
|
-
*
|
|
451
|
-
* The `target.vault` must NOT be the group itself or one of its shards —
|
|
452
|
-
* a summary writing back into client-shard data would breach the Insight
|
|
453
|
-
* Vault's separate-DEK-boundary contract. Such a target throws a
|
|
454
|
-
* `ValidationError` at registration (#271 Insight-write isolation).
|
|
455
|
-
*/
|
|
456
|
-
withCrossVaultDerivation(spec) {
|
|
457
|
-
const target = spec.target.vault;
|
|
458
|
-
if (target === this.name || target.startsWith(`${this.name}${SHARD_SEPARATOR}`)) {
|
|
459
|
-
throw new ValidationError(
|
|
460
|
-
`withCrossVaultDerivation: target.vault "${target}" is the "${this.name}" group itself or one of its shards \u2014 an Insight summary must target a SEPARATE analytics vault, never write back into client-shard data (it would breach the per-shard DEK boundary). Use a distinct vault name.`
|
|
461
|
-
);
|
|
462
|
-
}
|
|
463
|
-
this.crossVaultDerivations.push(spec);
|
|
464
|
-
}
|
|
465
|
-
/**
|
|
466
|
-
* Run every registered {@link withCrossVaultDerivation}: read each eligible
|
|
467
|
-
* shard's source records, derive a per-shard summary, and write it into the
|
|
468
|
-
* Insight Vault keyed by partition key. Shards behind `minVersion`,
|
|
469
|
-
* unprovisioned, or whose read errors are reported in `skippedVaults` and
|
|
470
|
-
* are not written (a stale summary is never left behind for a failed shard).
|
|
471
|
-
*/
|
|
472
|
-
async refreshInsights(options = {}) {
|
|
473
|
-
if (this.crossVaultDerivations.length === 0) return { written: 0, skippedVaults: [] };
|
|
474
|
-
const { eligible, skipped } = await this.resolveEligible(
|
|
475
|
-
options.minVersion !== void 0 ? { minVersion: options.minVersion } : {}
|
|
476
|
-
);
|
|
477
|
-
let written = 0;
|
|
478
|
-
for (const spec of this.crossVaultDerivations) {
|
|
479
|
-
const results = await this.db.queryAcross(
|
|
480
|
-
eligible.map((r) => r.vaultId),
|
|
481
|
-
async (vault) => {
|
|
482
|
-
this.template.configure(vault);
|
|
483
|
-
return vault.collection(spec.source).list();
|
|
484
|
-
},
|
|
485
|
-
{ create: false, ...options.concurrency !== void 0 ? { concurrency: options.concurrency } : {} }
|
|
486
|
-
);
|
|
487
|
-
const insight = await this.db.openVault(spec.target.vault);
|
|
488
|
-
const out = insight.collection(spec.target.collection);
|
|
489
|
-
for (let i = 0; i < eligible.length; i++) {
|
|
490
|
-
const row = eligible[i];
|
|
491
|
-
const res = results[i];
|
|
492
|
-
if (!res || res.result === void 0) {
|
|
493
|
-
skipped.push({ vaultId: row.vaultId, reason: "error", ...res?.error ? { error: res.error } : {} });
|
|
494
|
-
continue;
|
|
495
|
-
}
|
|
496
|
-
const ctx = {
|
|
497
|
-
vaultId: row.vaultId,
|
|
498
|
-
partitionKey: row.partitionKey,
|
|
499
|
-
schemaVersion: row.schemaVersion
|
|
500
|
-
};
|
|
501
|
-
const summary = spec.derive(res.result, ctx);
|
|
502
|
-
await out.put(row.partitionKey, summary);
|
|
503
|
-
written++;
|
|
504
|
-
}
|
|
505
|
-
}
|
|
506
|
-
return { written, skippedVaults: skipped };
|
|
507
|
-
}
|
|
508
|
-
/** @internal — the control-plane vault for migration status; lazily opened. */
|
|
509
|
-
async ensureStateVault() {
|
|
510
|
-
if (!this.stateVault) this.stateVault = await StateManagementVault.open(this.db);
|
|
511
|
-
return this.stateVault;
|
|
512
|
-
}
|
|
513
|
-
/**
|
|
514
|
-
* Migrate ONE shard to the template's current version (#271 fleet runner,
|
|
515
|
-
* per-shard step). Opens the shard (applying the template, which arms the
|
|
516
|
-
* M12 cutover), drains schema-write detection, runs `vault.runSchemaCutover()`
|
|
517
|
-
* (the per-vault drain-barrier-transform protocol), then advances the
|
|
518
|
-
* registry row's `schemaVersion` and records `migration-status`. A shard
|
|
519
|
-
* already at the template version is a no-op (`status: 'done'`, migrated 0).
|
|
520
|
-
* Never throws on a cutover failure — it records `status: 'failed'` and
|
|
521
|
-
* returns the row, so a fleet run continues past a bad shard.
|
|
522
|
-
*/
|
|
523
|
-
async migrateShard(partitionKey) {
|
|
524
|
-
const vaultId = this.shardVaultId(partitionKey);
|
|
525
|
-
const row = await this.registry.get(this.registryId(partitionKey));
|
|
526
|
-
if (!row) throw new UnknownShardError(partitionKey, this.name);
|
|
527
|
-
const target = this.template.version;
|
|
528
|
-
const sv = await this.ensureStateVault();
|
|
529
|
-
const base = { vaultId, group: this.name, currentVersion: row.schemaVersion, targetVersion: target };
|
|
530
|
-
if (row.schemaVersion >= target) {
|
|
531
|
-
const done = { ...base, status: "done", migrated: 0, finishedAt: Date.now() };
|
|
532
|
-
await sv.upsertMigrationStatus(done);
|
|
533
|
-
return done;
|
|
534
|
-
}
|
|
535
|
-
await sv.upsertMigrationStatus({ ...base, status: "running", startedAt: Date.now() });
|
|
536
|
-
try {
|
|
537
|
-
await sv.appendEvent({ type: "migration-started", group: this.name, vaultId, version: target });
|
|
538
|
-
} catch {
|
|
539
|
-
}
|
|
540
|
-
try {
|
|
541
|
-
const vault = await this._openShardRaw(partitionKey);
|
|
542
|
-
await vault._drainPendingSchemaWrites();
|
|
543
|
-
const { migrated } = await vault.runSchemaCutover();
|
|
544
|
-
await this.registry.put(this.registryId(partitionKey), { ...row, schemaVersion: target });
|
|
545
|
-
const done = { ...base, currentVersion: target, status: "done", migrated, finishedAt: Date.now() };
|
|
546
|
-
await sv.upsertMigrationStatus(done);
|
|
547
|
-
try {
|
|
548
|
-
await sv.appendEvent({ type: "migration-completed", group: this.name, vaultId, version: target });
|
|
549
|
-
} catch {
|
|
550
|
-
}
|
|
551
|
-
return done;
|
|
552
|
-
} catch (err) {
|
|
553
|
-
const error = err instanceof Error ? err.message : String(err);
|
|
554
|
-
const failed = { ...base, status: "failed", error, finishedAt: Date.now() };
|
|
555
|
-
await sv.upsertMigrationStatus(failed);
|
|
556
|
-
try {
|
|
557
|
-
await sv.appendEvent({ type: "migration-failed", group: this.name, vaultId, version: target, detail: error });
|
|
558
|
-
} catch {
|
|
559
|
-
}
|
|
560
|
-
return failed;
|
|
561
|
-
}
|
|
562
|
-
}
|
|
563
|
-
/**
|
|
564
|
-
* Active batch runner (#271): migrate every shard behind the template version
|
|
565
|
-
* to it, in controlled batches. **Resumable + crash-safe** — shards already at
|
|
566
|
-
* the target are skipped (the registry version is the source of truth), so a
|
|
567
|
-
* re-run after a crash only picks up the unfinished + previously-failed shards.
|
|
568
|
-
*
|
|
569
|
-
* - `cohort` — restrict to these partition keys (the staged / canary rollout:
|
|
570
|
-
* migrate a small cohort, verify the Insight Vault, then run the rest).
|
|
571
|
-
* - `batchSize` — max shards migrated concurrently per batch (back-pressure).
|
|
572
|
-
* Default 4. Batches run sequentially; shards within a batch run in parallel.
|
|
573
|
-
*/
|
|
574
|
-
async migrateFleet(options = {}) {
|
|
575
|
-
const target = this.template.version;
|
|
576
|
-
const rows = await this.allRows();
|
|
577
|
-
const cohort = options.cohort;
|
|
578
|
-
const todo = rows.filter(
|
|
579
|
-
(r) => r.schemaVersion < target && (cohort === void 0 || cohort.includes(r.partitionKey))
|
|
580
|
-
);
|
|
581
|
-
const batchSize = Math.max(1, options.batchSize ?? 4);
|
|
582
|
-
const migrated = [];
|
|
583
|
-
const failed = [];
|
|
584
|
-
for (let i = 0; i < todo.length; i += batchSize) {
|
|
585
|
-
const batch = todo.slice(i, i + batchSize);
|
|
586
|
-
const settled = await Promise.all(batch.map((r) => this.migrateShard(r.partitionKey)));
|
|
587
|
-
for (const res of settled) {
|
|
588
|
-
if (res.status === "done") migrated.push(res.vaultId);
|
|
589
|
-
else failed.push({ vaultId: res.vaultId, error: res.error ?? "unknown" });
|
|
590
|
-
}
|
|
591
|
-
}
|
|
592
|
-
return { target, migrated, failed };
|
|
593
|
-
}
|
|
594
|
-
};
|
|
595
|
-
var ShardedCollection = class {
|
|
596
|
-
constructor(group, collectionName) {
|
|
597
|
-
this.group = group;
|
|
598
|
-
this.collectionName = collectionName;
|
|
599
|
-
}
|
|
600
|
-
group;
|
|
601
|
-
collectionName;
|
|
602
|
-
/** Route a write to the shard owning `keyOf(record)`. */
|
|
603
|
-
async put(id, record) {
|
|
604
|
-
const key = this.group.sharding.keyOf(record);
|
|
605
|
-
const row = await this.group.registry.get(this.group.registryId(key));
|
|
606
|
-
let vault;
|
|
607
|
-
if (!row) {
|
|
608
|
-
if (this.group.sharding.autoCreate === false) {
|
|
609
|
-
throw new UnknownShardError(key, this.group.name);
|
|
610
|
-
}
|
|
611
|
-
vault = await this.group.createShard(key, this.group.sharding.regionOf?.(record));
|
|
612
|
-
} else {
|
|
613
|
-
vault = await this.group.openShard(key);
|
|
614
|
-
}
|
|
615
|
-
await vault.collection(this.collectionName).put(id, record);
|
|
616
|
-
}
|
|
617
|
-
/** Begin a cross-shard fan-out query. */
|
|
618
|
-
query() {
|
|
619
|
-
return new ShardedQuery(this.group, this.collectionName, []);
|
|
620
|
-
}
|
|
621
|
-
};
|
|
622
|
-
var ShardedQuery = class _ShardedQuery {
|
|
623
|
-
constructor(group, collectionName, clauses, coPartitionedLegs = [], broadcastLegs = []) {
|
|
624
|
-
this.group = group;
|
|
625
|
-
this.collectionName = collectionName;
|
|
626
|
-
this.clauses = clauses;
|
|
627
|
-
this.coPartitionedLegs = coPartitionedLegs;
|
|
628
|
-
this.broadcastLegs = broadcastLegs;
|
|
629
|
-
}
|
|
630
|
-
group;
|
|
631
|
-
collectionName;
|
|
632
|
-
clauses;
|
|
633
|
-
coPartitionedLegs;
|
|
634
|
-
broadcastLegs;
|
|
635
|
-
where(field, op, value) {
|
|
636
|
-
return new _ShardedQuery(
|
|
637
|
-
this.group,
|
|
638
|
-
this.collectionName,
|
|
639
|
-
[...this.clauses, { field, op, value }],
|
|
640
|
-
this.coPartitionedLegs,
|
|
641
|
-
this.broadcastLegs
|
|
642
|
-
);
|
|
643
|
-
}
|
|
644
|
-
/** Co-partitioned join: each shard joins its own same-vault right collection (resolved via ref()), then union. */
|
|
645
|
-
crossShardJoin(field, opts) {
|
|
646
|
-
const leg = { field, as: opts.as, maxRows: opts.maxRows, strategy: opts.strategy };
|
|
647
|
-
return new _ShardedQuery(
|
|
648
|
-
this.group,
|
|
649
|
-
this.collectionName,
|
|
650
|
-
this.clauses,
|
|
651
|
-
[...this.coPartitionedLegs, leg],
|
|
652
|
-
this.broadcastLegs
|
|
653
|
-
);
|
|
654
|
-
}
|
|
655
|
-
/** Broadcast dimension join: enrich every merged row from a single shared collection. */
|
|
656
|
-
broadcastJoin(field, opts) {
|
|
657
|
-
const leg = {
|
|
658
|
-
field,
|
|
659
|
-
as: opts.as,
|
|
660
|
-
from: opts.from,
|
|
661
|
-
on: opts.on ?? "id",
|
|
662
|
-
mode: opts.mode ?? "warn"
|
|
663
|
-
};
|
|
664
|
-
return new _ShardedQuery(
|
|
665
|
-
this.group,
|
|
666
|
-
this.collectionName,
|
|
667
|
-
this.clauses,
|
|
668
|
-
this.coPartitionedLegs,
|
|
669
|
-
[...this.broadcastLegs, leg]
|
|
670
|
-
);
|
|
671
|
-
}
|
|
672
|
-
/** @internal — fan out the where-filtered records across eligible shards. */
|
|
673
|
-
async fanoutRecords(options = {}) {
|
|
674
|
-
const { eligible, skipped } = await this.group.resolveEligible(options);
|
|
675
|
-
const probeRow = eligible[0];
|
|
676
|
-
if (this.coPartitionedLegs.length > 0 && probeRow) {
|
|
677
|
-
const probe = await this.group.openShard(probeRow.partitionKey);
|
|
678
|
-
this.group.template.configure(probe);
|
|
679
|
-
for (const leg of this.coPartitionedLegs) {
|
|
680
|
-
if (!probe.resolveRef(this.collectionName, leg.field)) {
|
|
681
|
-
throw new CrossShardJoinError(
|
|
682
|
-
`crossShardJoin("${leg.field}"): no ref() declared for "${leg.field}" on collection "${this.collectionName}" in template "${this.group.sharding.vaultTemplate}". Add refs: { ${leg.field}: ref('<target>') } to the template's collection options.`
|
|
683
|
-
);
|
|
684
|
-
}
|
|
685
|
-
}
|
|
686
|
-
}
|
|
687
|
-
const across = await this.group.db.queryAcross(
|
|
688
|
-
eligible.map((r) => r.vaultId),
|
|
689
|
-
async (vault) => {
|
|
690
|
-
this.group.template.configure(vault);
|
|
691
|
-
const coll = vault.collection(this.collectionName);
|
|
692
|
-
await coll.list();
|
|
693
|
-
for (const leg of this.coPartitionedLegs) {
|
|
694
|
-
const desc = vault.resolveRef(this.collectionName, leg.field);
|
|
695
|
-
if (desc) await vault.collection(desc.target).list();
|
|
696
|
-
}
|
|
697
|
-
let q = coll.query();
|
|
698
|
-
for (const c of this.clauses) q = q.where(c.field, c.op, c.value);
|
|
699
|
-
for (const leg of this.coPartitionedLegs) {
|
|
700
|
-
q = q.join(leg.field, {
|
|
701
|
-
as: leg.as,
|
|
702
|
-
...leg.maxRows !== void 0 ? { maxRows: leg.maxRows } : {},
|
|
703
|
-
...leg.strategy ? { strategy: leg.strategy } : {}
|
|
704
|
-
});
|
|
705
|
-
}
|
|
706
|
-
return q.toArray();
|
|
707
|
-
},
|
|
708
|
-
{ concurrency: options.concurrency ?? 1, create: false }
|
|
709
|
-
);
|
|
710
|
-
const results = [];
|
|
711
|
-
for (const r of across) {
|
|
712
|
-
if (r.error) skipped.push({ vaultId: r.vault, reason: classifyShardSkip(r.error), error: r.error });
|
|
713
|
-
else for (const item of r.result) results.push(item);
|
|
714
|
-
}
|
|
715
|
-
return { records: results, skippedVaults: skipped };
|
|
716
|
-
}
|
|
717
|
-
/** Fan out across eligible shards, merge, then apply any broadcast dimension legs. */
|
|
718
|
-
async toArray(options = {}) {
|
|
719
|
-
const { records, skippedVaults } = await this.fanoutRecords(options);
|
|
720
|
-
const results = await applyBroadcastLegs(records, this.broadcastLegs);
|
|
721
|
-
return { results, skippedVaults };
|
|
722
|
-
}
|
|
723
|
-
/** @internal — build the change-subscription + relevance binding for this query's group+collection. */
|
|
724
|
-
liveBinding() {
|
|
725
|
-
const group = this.group;
|
|
726
|
-
const collectionName = this.collectionName;
|
|
727
|
-
return {
|
|
728
|
-
subscribeToChanges: (h) => {
|
|
729
|
-
group.db.on("change", h);
|
|
730
|
-
return () => group.db.off("change", h);
|
|
731
|
-
},
|
|
732
|
-
isRelevant: (e) => e.collection === collectionName && e.vault.startsWith(`${group.name}--`)
|
|
733
|
-
};
|
|
734
|
-
}
|
|
735
|
-
/** @internal — joined queries don't support reactive/aggregate surfaces in v1. */
|
|
736
|
-
assertNoJoinLegs(surface) {
|
|
737
|
-
if (this.coPartitionedLegs.length || this.broadcastLegs.length) {
|
|
738
|
-
throw new CrossShardJoinError(
|
|
739
|
-
`${surface}() is not supported on a ShardedQuery with crossShardJoin/broadcastJoin legs in v1. Use toArray() for joined cross-shard queries.`
|
|
740
|
-
);
|
|
741
|
-
}
|
|
742
|
-
}
|
|
743
|
-
/** Returns a reactive cross-shard live query — a facade over CrossVaultLive. */
|
|
744
|
-
live(options = {}) {
|
|
745
|
-
this.assertNoJoinLegs("live");
|
|
746
|
-
const bind = this.liveBinding();
|
|
747
|
-
const core = new CrossVaultLive({
|
|
748
|
-
...bind,
|
|
749
|
-
compute: async () => {
|
|
750
|
-
const { records, skippedVaults } = await this.fanoutRecords(options);
|
|
751
|
-
return { records, skipped: skippedVaults };
|
|
752
|
-
},
|
|
753
|
-
initialSnapshot: { records: [], skipped: [] },
|
|
754
|
-
...options.debounceMs !== void 0 ? { debounceMs: options.debounceMs } : {}
|
|
755
|
-
});
|
|
756
|
-
return {
|
|
757
|
-
get value() {
|
|
758
|
-
return core.snapshot.records;
|
|
759
|
-
},
|
|
760
|
-
get skippedVaults() {
|
|
761
|
-
return core.snapshot.skipped;
|
|
762
|
-
},
|
|
763
|
-
get error() {
|
|
764
|
-
return core.error;
|
|
765
|
-
},
|
|
766
|
-
ready: core.ready,
|
|
767
|
-
subscribe: (cb) => core.subscribe(cb),
|
|
768
|
-
stop: () => core.stop()
|
|
769
|
-
};
|
|
770
|
-
}
|
|
771
|
-
/** One-shot distributed aggregate — central reduce over all shard records. */
|
|
772
|
-
aggregate(spec) {
|
|
773
|
-
this.assertNoJoinLegs("aggregate");
|
|
774
|
-
return new CrossVaultAggregation(this, spec, this.liveBinding());
|
|
775
|
-
}
|
|
776
|
-
/** Begin a grouped cross-shard aggregate. */
|
|
777
|
-
groupBy(field) {
|
|
778
|
-
this.assertNoJoinLegs("groupBy");
|
|
779
|
-
return new ShardedGroupedQuery(this, field);
|
|
780
|
-
}
|
|
781
|
-
};
|
|
782
|
-
var ShardedGroupedQuery = class {
|
|
783
|
-
constructor(query, field) {
|
|
784
|
-
this.query = query;
|
|
785
|
-
this.field = field;
|
|
786
|
-
}
|
|
787
|
-
query;
|
|
788
|
-
field;
|
|
789
|
-
aggregate(spec) {
|
|
790
|
-
return new CrossVaultGroupedAggregation(
|
|
791
|
-
{ fanoutRecords: (o) => this.query.fanoutRecords(o) },
|
|
792
|
-
this.field,
|
|
793
|
-
spec,
|
|
794
|
-
this.query.liveBinding()
|
|
795
|
-
);
|
|
796
|
-
}
|
|
797
|
-
};
|
|
798
|
-
export {
|
|
799
|
-
ShardedCollection,
|
|
800
|
-
ShardedGroupedQuery,
|
|
801
|
-
ShardedQuery,
|
|
802
|
-
VaultGroup
|
|
803
|
-
};
|
|
804
|
-
//# sourceMappingURL=vault-group-BB246VIM.js.map
|