@noy-db/hub 0.2.0-pre.11 → 0.2.0-pre.13
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/README.md +126 -0
- package/dist/aggregate/index.cjs +289 -12
- package/dist/aggregate/index.cjs.map +1 -1
- package/dist/aggregate/index.d.cts +2 -2
- package/dist/aggregate/index.d.ts +2 -2
- package/dist/aggregate/index.js +7 -7
- package/dist/aggregate/index.js.map +1 -1
- package/dist/attestation/index.cjs.map +1 -1
- package/dist/attestation/index.d.cts +3 -3
- package/dist/attestation/index.d.ts +3 -3
- package/dist/attestation/index.js +6 -6
- package/dist/blobs/index.cjs +28 -0
- package/dist/blobs/index.cjs.map +1 -1
- package/dist/blobs/index.d.cts +4 -4
- package/dist/blobs/index.d.ts +4 -4
- package/dist/blobs/index.js +5 -5
- package/dist/bundle/index.cjs +2024 -69
- package/dist/bundle/index.cjs.map +1 -1
- package/dist/bundle/index.d.cts +5 -5
- package/dist/bundle/index.d.ts +5 -5
- package/dist/bundle/index.js +9 -9
- package/dist/{chunk-LSTBFLL2.js → chunk-3OUCWHV6.js} +2 -2
- package/dist/{chunk-7CEGU63S.js → chunk-3XZRRBFW.js} +2 -2
- package/dist/{chunk-RC6SU5NO.js → chunk-4VCQH32J.js} +2 -2
- package/dist/{chunk-ZROPXHJY.js → chunk-4YDZ7JPZ.js} +2 -2
- package/dist/{chunk-IMYKDWB4.js → chunk-5NISHSBO.js} +2 -2
- package/dist/{chunk-ZBBW7YQN.js → chunk-7TEI2K2A.js} +5 -5
- package/dist/{chunk-6T2UDBKG.js → chunk-AYNF7PVX.js} +2 -2
- package/dist/{chunk-QCXNMCHN.js → chunk-C3WRKABE.js} +4 -4
- package/dist/{chunk-GAUEWM7D.js → chunk-CWFQTAD4.js} +4 -4
- package/dist/{chunk-QSOYKKMD.js → chunk-D5Y3HIC6.js} +2 -2
- package/dist/{chunk-R233SLY3.js → chunk-E3DIBDKA.js} +2 -2
- package/dist/chunk-FNVFT4HZ.js +64 -0
- package/dist/chunk-FNVFT4HZ.js.map +1 -0
- package/dist/{chunk-SLV4LAKX.js → chunk-GC4V7RU7.js} +1 -1
- package/dist/chunk-GC4V7RU7.js.map +1 -0
- package/dist/{chunk-5OEJ6GOT.js → chunk-GL3Z7LH7.js} +2 -2
- package/dist/{chunk-YW5DBAPG.js → chunk-GZJ5JBED.js} +4 -4
- package/dist/{chunk-LJXYPGRH.js → chunk-HHZ77DHM.js} +3 -3
- package/dist/{chunk-6MFH4BMK.js → chunk-HQXOEWLZ.js} +4 -4
- package/dist/{chunk-RYIL3PI2.js → chunk-ILWQGTNH.js} +2 -2
- package/dist/{chunk-3DGHRDCX.js → chunk-J67BP5EP.js} +3 -3
- package/dist/{chunk-PVUUIWHY.js → chunk-JPOQMXGT.js} +10 -3
- package/dist/chunk-JPOQMXGT.js.map +1 -0
- package/dist/{chunk-RRNA5GKT.js → chunk-JWFNOD2T.js} +2 -2
- package/dist/{chunk-BDV7INMP.js → chunk-KHQ3N5AB.js} +4 -4
- package/dist/{chunk-JQ4NEJJ6.js → chunk-KJF7EPUE.js} +3 -3
- package/dist/{chunk-FO3UEG4S.js → chunk-KKB42D3Q.js} +2 -2
- package/dist/{chunk-26NK23DZ.js → chunk-M6KXHRIA.js} +3 -3
- package/dist/{chunk-DAP2XL7Q.js → chunk-NIUXQDWD.js} +2 -2
- package/dist/{chunk-6YLPHBKR.js → chunk-NJMKHRQI.js} +145 -11
- package/dist/chunk-NJMKHRQI.js.map +1 -0
- package/dist/{chunk-O6EJ6WTI.js → chunk-NKGY3C53.js} +87 -2
- package/dist/chunk-NKGY3C53.js.map +1 -0
- package/dist/{chunk-CXJG63MA.js → chunk-NP6EZT44.js} +20 -6
- package/dist/chunk-NP6EZT44.js.map +1 -0
- package/dist/{chunk-Y26YV5R3.js → chunk-O2JW656W.js} +3 -3
- package/dist/{chunk-MPOLUAMI.js → chunk-P5MW7BG2.js} +665 -60
- package/dist/chunk-P5MW7BG2.js.map +1 -0
- package/dist/{chunk-TGALXXLV.js → chunk-PW26DAXS.js} +3 -3
- package/dist/{chunk-V2PZC6AW.js → chunk-QAWCVWCX.js} +5 -5
- package/dist/{chunk-CH22FZHT.js → chunk-QFYVGJLI.js} +2 -2
- package/dist/{chunk-YM7LFCG7.js → chunk-QIVFGU2M.js} +3 -3
- package/dist/{chunk-CXFOITNS.js → chunk-SJ24GHID.js} +2 -2
- package/dist/{chunk-EBVBE7UK.js → chunk-SOU42FGB.js} +5 -5
- package/dist/{chunk-YVZRTCGG.js → chunk-SYSKC237.js} +6 -6
- package/dist/{chunk-77DWLQRY.js → chunk-TDECYU4Y.js} +31 -3
- package/dist/chunk-TDECYU4Y.js.map +1 -0
- package/dist/{chunk-73YLDCNF.js → chunk-TEQGXA7L.js} +5 -5
- package/dist/{chunk-PC6ZEDRL.js → chunk-UNQEWORI.js} +2 -2
- package/dist/{chunk-PC3ZZBTO.js → chunk-VAK6NQAK.js} +5 -5
- package/dist/{chunk-GKI4SDP7.js → chunk-WQKZIQIL.js} +4 -4
- package/dist/chunk-YWBHS25M.js +783 -0
- package/dist/chunk-YWBHS25M.js.map +1 -0
- package/dist/chunk-ZC7J6ZYV.js +7 -0
- package/dist/chunk-ZC7J6ZYV.js.map +1 -0
- package/dist/consent/index.cjs.map +1 -1
- package/dist/consent/index.d.cts +4 -4
- package/dist/consent/index.d.ts +4 -4
- package/dist/consent/index.js +3 -3
- package/dist/{crypto-2CRLG4F4.js → crypto-YXH6SAOW.js} +3 -3
- package/dist/{delegation-ZTRT2PRV.js → delegation-K5ERUH6A.js} +5 -5
- package/dist/derivations/index.cjs.map +1 -1
- package/dist/derivations/index.d.cts +5 -5
- package/dist/derivations/index.d.ts +5 -5
- package/dist/derivations/index.js +4 -4
- package/dist/{dev-unlock-BH6y3Hx0.d.ts → dev-unlock-BW0GNBEV.d.ts} +1 -1
- package/dist/{dev-unlock-H1Xwxc3U.d.cts → dev-unlock-a7SOtaV0.d.cts} +1 -1
- package/dist/executor-AVJ7UEWA.js +8 -0
- package/dist/executor-IQO3KGXQ.js +11 -0
- package/dist/executor-VT7TKGE4.js +8 -0
- package/dist/{fanout-sidecar-F3ZRFU4H.js → fanout-sidecar-N6OJX6QR.js} +2 -2
- package/dist/guards/index.cjs +53 -1
- package/dist/guards/index.cjs.map +1 -1
- package/dist/guards/index.d.cts +12 -6
- package/dist/guards/index.d.ts +12 -6
- package/dist/guards/index.js +5 -3
- package/dist/{hash-_sDFvtmX.d.cts → hash-B0cLQcq_.d.cts} +1 -1
- package/dist/{hash-D89JdDbj.d.ts → hash-uMNIAAW8.d.ts} +1 -1
- package/dist/history/index.cjs.map +1 -1
- package/dist/history/index.d.cts +5 -5
- package/dist/history/index.d.ts +5 -5
- package/dist/history/index.js +5 -5
- package/dist/i18n/index.cjs.map +1 -1
- package/dist/i18n/index.d.cts +4 -4
- package/dist/i18n/index.d.ts +4 -4
- package/dist/i18n/index.js +6 -6
- package/dist/immutable-guard-B0h-ipLz.d.ts +67 -0
- package/dist/immutable-guard-BZIcYhYX.d.cts +67 -0
- package/dist/index-CUVOMtgg.d.cts +1216 -0
- package/dist/index-Cqzp4tt9.d.ts +1216 -0
- package/dist/index.cjs +2200 -106
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +55 -13
- package/dist/index.d.ts +55 -13
- package/dist/index.js +95 -44
- package/dist/index.js.map +1 -1
- package/dist/indexing/index.cjs.map +1 -1
- package/dist/indexing/index.js +2 -2
- package/dist/issue-ZH27C23Y.js +12 -0
- package/dist/{ledger-NYCGJX2D.js → ledger-64TTQMRS.js} +5 -5
- package/dist/materialized-views/index.cjs.map +1 -1
- package/dist/materialized-views/index.d.cts +5 -6
- package/dist/materialized-views/index.d.ts +5 -6
- package/dist/materialized-views/index.js +6 -6
- package/dist/noydb-O76SKBST.js +35 -0
- package/dist/overlay-views/index.cjs.map +1 -1
- package/dist/overlay-views/index.d.cts +5 -5
- package/dist/overlay-views/index.d.ts +5 -5
- package/dist/overlay-views/index.js +4 -4
- package/dist/periods/index.cjs.map +1 -1
- package/dist/periods/index.d.cts +4 -4
- package/dist/periods/index.d.ts +4 -4
- package/dist/periods/index.js +5 -5
- package/dist/{public-envelope-QOXZEHKH.js → public-envelope-MHG6YVXW.js} +4 -4
- package/dist/query/index.cjs +382 -17
- package/dist/query/index.cjs.map +1 -1
- package/dist/query/index.d.cts +2 -2
- package/dist/query/index.d.ts +2 -2
- package/dist/query/index.js +4 -4
- package/dist/registry-2PKBQDCH.js +8 -0
- package/dist/registry-4VXFKCBJ.js +8 -0
- package/dist/{registry-ST2VNFZC.js → registry-PV4G3OPA.js} +3 -3
- package/dist/{revoke-RT7QYB4G.js → revoke-5BOLVJ3N.js} +6 -6
- package/dist/session/index.cjs.map +1 -1
- package/dist/session/index.d.cts +5 -5
- package/dist/session/index.d.ts +5 -5
- package/dist/session/index.js +3 -3
- package/dist/shadow/index.cjs.map +1 -1
- package/dist/shadow/index.d.cts +4 -4
- package/dist/shadow/index.d.ts +4 -4
- package/dist/shadow/index.js +2 -2
- package/dist/{signer-QNU66JF5.js → signer-GRIYBA22.js} +5 -5
- package/dist/snapshots/index.cjs.map +1 -1
- package/dist/snapshots/index.d.cts +4 -4
- package/dist/snapshots/index.d.ts +4 -4
- package/dist/snapshots/index.js +4 -4
- package/dist/{stale-VKXSXJF4.js → stale-LZYMMDDS.js} +2 -2
- package/dist/state-vault-QFJWU23A.js +147 -0
- package/dist/state-vault-QFJWU23A.js.map +1 -0
- package/dist/store/index.cjs.map +1 -1
- package/dist/store/index.d.cts +4 -4
- package/dist/store/index.d.ts +4 -4
- package/dist/store/index.js +2 -2
- package/dist/strategy-CrS7PnbE.d.cts +2048 -0
- package/dist/strategy-CrS7PnbE.d.ts +2048 -0
- package/dist/sync/index.cjs.map +1 -1
- package/dist/sync/index.d.cts +3 -3
- package/dist/sync/index.d.ts +3 -3
- package/dist/sync/index.js +4 -4
- package/dist/team/index.cjs.map +1 -1
- package/dist/team/index.d.cts +4 -4
- package/dist/team/index.d.ts +4 -4
- package/dist/team/index.js +8 -8
- package/dist/tx/index.cjs +8 -1
- package/dist/tx/index.cjs.map +1 -1
- package/dist/tx/index.d.cts +4 -4
- package/dist/tx/index.d.ts +4 -4
- package/dist/tx/index.js +3 -3
- package/dist/{types-DiSXn3a4.d.cts → types-CDwSSXiI.d.cts} +709 -6
- package/dist/{types-CD8mc8zR.d.ts → types-pax34sec.d.ts} +709 -6
- package/dist/{ulid-DQ1hcJvZ.d.cts → ulid-7bCSgIgb.d.cts} +1 -1
- package/dist/{ulid-8p83wbR4.d.ts → ulid-C_t4hL3d.d.ts} +1 -1
- package/dist/util/index.cjs.map +1 -1
- package/dist/util/index.js +1 -1
- package/dist/vault-group-UO4YUZOG.js +493 -0
- package/dist/vault-group-UO4YUZOG.js.map +1 -0
- package/dist/{with-derivation-DWMTpgEH.d.ts → with-derivation-BjdOxUBn.d.ts} +1 -1
- package/dist/{with-derivation-CVT7-dUt.d.cts → with-derivation-D8wFlb6V.d.cts} +1 -1
- package/dist/{with-materialized-view-BTTU3BNK.d.cts → with-materialized-view-5QMF1rS_.d.cts} +1 -1
- package/dist/{with-materialized-view-X0CoL8-L.d.ts → with-materialized-view-DJb-HO65.d.ts} +1 -1
- package/dist/{with-overlayed-view-DQjO_DSG.d.ts → with-overlayed-view-CkqTefbz.d.ts} +1 -1
- package/dist/{with-overlayed-view-DcacRRsS.d.cts → with-overlayed-view-DDNflPvC.d.cts} +1 -1
- package/package.json +3 -3
- package/dist/chunk-2LPPNWF6.js +0 -340
- package/dist/chunk-2LPPNWF6.js.map +0 -1
- package/dist/chunk-6YLPHBKR.js.map +0 -1
- package/dist/chunk-77DWLQRY.js.map +0 -1
- package/dist/chunk-C3WE6UJY.js +0 -19
- package/dist/chunk-C3WE6UJY.js.map +0 -1
- package/dist/chunk-CXJG63MA.js.map +0 -1
- package/dist/chunk-MPOLUAMI.js.map +0 -1
- package/dist/chunk-O6EJ6WTI.js.map +0 -1
- package/dist/chunk-PVUUIWHY.js.map +0 -1
- package/dist/chunk-SLV4LAKX.js.map +0 -1
- package/dist/executor-S76VN45G.js +0 -8
- package/dist/executor-UCXLIGLW.js +0 -11
- package/dist/executor-ZCNZJMGR.js +0 -8
- package/dist/index-B8bjExET.d.cts +0 -2434
- package/dist/index-DfUbNad8.d.ts +0 -2434
- package/dist/issue-IVTVSKWW.js +0 -12
- package/dist/noydb-SH4RLE47.js +0 -34
- package/dist/registry-UFIK7CSR.js +0 -8
- package/dist/registry-ZGYYSM5I.js +0 -8
- package/dist/strategy-CT2LCKAX.d.cts +0 -613
- package/dist/strategy-CT2LCKAX.d.ts +0 -613
- package/dist/with-guard-BRvt53da.d.ts +0 -18
- package/dist/with-guard-Dx2zZnTA.d.cts +0 -18
- /package/dist/{chunk-LSTBFLL2.js.map → chunk-3OUCWHV6.js.map} +0 -0
- /package/dist/{chunk-7CEGU63S.js.map → chunk-3XZRRBFW.js.map} +0 -0
- /package/dist/{chunk-RC6SU5NO.js.map → chunk-4VCQH32J.js.map} +0 -0
- /package/dist/{chunk-ZROPXHJY.js.map → chunk-4YDZ7JPZ.js.map} +0 -0
- /package/dist/{chunk-IMYKDWB4.js.map → chunk-5NISHSBO.js.map} +0 -0
- /package/dist/{chunk-ZBBW7YQN.js.map → chunk-7TEI2K2A.js.map} +0 -0
- /package/dist/{chunk-6T2UDBKG.js.map → chunk-AYNF7PVX.js.map} +0 -0
- /package/dist/{chunk-QCXNMCHN.js.map → chunk-C3WRKABE.js.map} +0 -0
- /package/dist/{chunk-GAUEWM7D.js.map → chunk-CWFQTAD4.js.map} +0 -0
- /package/dist/{chunk-QSOYKKMD.js.map → chunk-D5Y3HIC6.js.map} +0 -0
- /package/dist/{chunk-R233SLY3.js.map → chunk-E3DIBDKA.js.map} +0 -0
- /package/dist/{chunk-5OEJ6GOT.js.map → chunk-GL3Z7LH7.js.map} +0 -0
- /package/dist/{chunk-YW5DBAPG.js.map → chunk-GZJ5JBED.js.map} +0 -0
- /package/dist/{chunk-LJXYPGRH.js.map → chunk-HHZ77DHM.js.map} +0 -0
- /package/dist/{chunk-6MFH4BMK.js.map → chunk-HQXOEWLZ.js.map} +0 -0
- /package/dist/{chunk-RYIL3PI2.js.map → chunk-ILWQGTNH.js.map} +0 -0
- /package/dist/{chunk-3DGHRDCX.js.map → chunk-J67BP5EP.js.map} +0 -0
- /package/dist/{chunk-RRNA5GKT.js.map → chunk-JWFNOD2T.js.map} +0 -0
- /package/dist/{chunk-BDV7INMP.js.map → chunk-KHQ3N5AB.js.map} +0 -0
- /package/dist/{chunk-JQ4NEJJ6.js.map → chunk-KJF7EPUE.js.map} +0 -0
- /package/dist/{chunk-FO3UEG4S.js.map → chunk-KKB42D3Q.js.map} +0 -0
- /package/dist/{chunk-26NK23DZ.js.map → chunk-M6KXHRIA.js.map} +0 -0
- /package/dist/{chunk-DAP2XL7Q.js.map → chunk-NIUXQDWD.js.map} +0 -0
- /package/dist/{chunk-Y26YV5R3.js.map → chunk-O2JW656W.js.map} +0 -0
- /package/dist/{chunk-TGALXXLV.js.map → chunk-PW26DAXS.js.map} +0 -0
- /package/dist/{chunk-V2PZC6AW.js.map → chunk-QAWCVWCX.js.map} +0 -0
- /package/dist/{chunk-CH22FZHT.js.map → chunk-QFYVGJLI.js.map} +0 -0
- /package/dist/{chunk-YM7LFCG7.js.map → chunk-QIVFGU2M.js.map} +0 -0
- /package/dist/{chunk-CXFOITNS.js.map → chunk-SJ24GHID.js.map} +0 -0
- /package/dist/{chunk-EBVBE7UK.js.map → chunk-SOU42FGB.js.map} +0 -0
- /package/dist/{chunk-YVZRTCGG.js.map → chunk-SYSKC237.js.map} +0 -0
- /package/dist/{chunk-73YLDCNF.js.map → chunk-TEQGXA7L.js.map} +0 -0
- /package/dist/{chunk-PC6ZEDRL.js.map → chunk-UNQEWORI.js.map} +0 -0
- /package/dist/{chunk-PC3ZZBTO.js.map → chunk-VAK6NQAK.js.map} +0 -0
- /package/dist/{chunk-GKI4SDP7.js.map → chunk-WQKZIQIL.js.map} +0 -0
- /package/dist/{crypto-2CRLG4F4.js.map → crypto-YXH6SAOW.js.map} +0 -0
- /package/dist/{delegation-ZTRT2PRV.js.map → delegation-K5ERUH6A.js.map} +0 -0
- /package/dist/{executor-S76VN45G.js.map → executor-AVJ7UEWA.js.map} +0 -0
- /package/dist/{executor-UCXLIGLW.js.map → executor-IQO3KGXQ.js.map} +0 -0
- /package/dist/{executor-ZCNZJMGR.js.map → executor-VT7TKGE4.js.map} +0 -0
- /package/dist/{fanout-sidecar-F3ZRFU4H.js.map → fanout-sidecar-N6OJX6QR.js.map} +0 -0
- /package/dist/{issue-IVTVSKWW.js.map → issue-ZH27C23Y.js.map} +0 -0
- /package/dist/{ledger-NYCGJX2D.js.map → ledger-64TTQMRS.js.map} +0 -0
- /package/dist/{noydb-SH4RLE47.js.map → noydb-O76SKBST.js.map} +0 -0
- /package/dist/{public-envelope-QOXZEHKH.js.map → public-envelope-MHG6YVXW.js.map} +0 -0
- /package/dist/{registry-ST2VNFZC.js.map → registry-2PKBQDCH.js.map} +0 -0
- /package/dist/{registry-UFIK7CSR.js.map → registry-4VXFKCBJ.js.map} +0 -0
- /package/dist/{registry-ZGYYSM5I.js.map → registry-PV4G3OPA.js.map} +0 -0
- /package/dist/{revoke-RT7QYB4G.js.map → revoke-5BOLVJ3N.js.map} +0 -0
- /package/dist/{signer-QNU66JF5.js.map → signer-GRIYBA22.js.map} +0 -0
- /package/dist/{stale-VKXSXJF4.js.map → stale-LZYMMDDS.js.map} +0 -0
|
@@ -0,0 +1,493 @@
|
|
|
1
|
+
import {
|
|
2
|
+
STATE_VAULT_NAME
|
|
3
|
+
} from "./chunk-ZC7J6ZYV.js";
|
|
4
|
+
import {
|
|
5
|
+
groupAndReduce,
|
|
6
|
+
reduceRecords
|
|
7
|
+
} from "./chunk-YWBHS25M.js";
|
|
8
|
+
import "./chunk-TV3YZ35S.js";
|
|
9
|
+
import {
|
|
10
|
+
NoAccessError,
|
|
11
|
+
ReservedVaultNameError,
|
|
12
|
+
ShardProvisioningError,
|
|
13
|
+
UnknownShardError,
|
|
14
|
+
ValidationError
|
|
15
|
+
} from "./chunk-NKGY3C53.js";
|
|
16
|
+
|
|
17
|
+
// src/federation/classify-skip.ts
|
|
18
|
+
function classifyShardSkip(err) {
|
|
19
|
+
return err instanceof NoAccessError ? "no-grant" : "error";
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// src/federation/cross-vault-live.ts
|
|
23
|
+
var CrossVaultLive = class {
|
|
24
|
+
snapshot;
|
|
25
|
+
error = null;
|
|
26
|
+
ready;
|
|
27
|
+
subs = /* @__PURE__ */ new Set();
|
|
28
|
+
unsubChange;
|
|
29
|
+
opts;
|
|
30
|
+
stopped = false;
|
|
31
|
+
computing = false;
|
|
32
|
+
dirty = false;
|
|
33
|
+
scheduled = false;
|
|
34
|
+
timer = null;
|
|
35
|
+
resolveReady;
|
|
36
|
+
settledOnce = false;
|
|
37
|
+
constructor(opts) {
|
|
38
|
+
this.opts = opts;
|
|
39
|
+
this.snapshot = opts.initialSnapshot;
|
|
40
|
+
this.ready = new Promise((res) => {
|
|
41
|
+
this.resolveReady = res;
|
|
42
|
+
});
|
|
43
|
+
this.unsubChange = opts.subscribeToChanges((e) => {
|
|
44
|
+
if (this.stopped || !opts.isRelevant(e)) return;
|
|
45
|
+
this.schedule();
|
|
46
|
+
});
|
|
47
|
+
this.schedule();
|
|
48
|
+
}
|
|
49
|
+
subscribe(cb) {
|
|
50
|
+
if (this.stopped) return () => {
|
|
51
|
+
};
|
|
52
|
+
this.subs.add(cb);
|
|
53
|
+
return () => this.subs.delete(cb);
|
|
54
|
+
}
|
|
55
|
+
stop() {
|
|
56
|
+
if (this.stopped) return;
|
|
57
|
+
this.stopped = true;
|
|
58
|
+
this.unsubChange();
|
|
59
|
+
if (this.timer !== null) clearTimeout(this.timer);
|
|
60
|
+
this.subs.clear();
|
|
61
|
+
if (!this.settledOnce) this.resolveReady();
|
|
62
|
+
}
|
|
63
|
+
schedule() {
|
|
64
|
+
if (this.stopped) return;
|
|
65
|
+
if (this.computing) {
|
|
66
|
+
this.dirty = true;
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
if (this.scheduled) return;
|
|
70
|
+
this.scheduled = true;
|
|
71
|
+
const run = () => {
|
|
72
|
+
this.scheduled = false;
|
|
73
|
+
void this.runCompute();
|
|
74
|
+
};
|
|
75
|
+
const ms = this.opts.debounceMs ?? 0;
|
|
76
|
+
if (ms > 0) this.timer = setTimeout(run, ms);
|
|
77
|
+
else queueMicrotask(run);
|
|
78
|
+
}
|
|
79
|
+
async runCompute() {
|
|
80
|
+
if (this.stopped) return;
|
|
81
|
+
this.computing = true;
|
|
82
|
+
this.dirty = false;
|
|
83
|
+
try {
|
|
84
|
+
const next = await this.opts.compute();
|
|
85
|
+
if (this.stopped) return;
|
|
86
|
+
this.snapshot = next;
|
|
87
|
+
this.error = null;
|
|
88
|
+
} catch (err) {
|
|
89
|
+
if (this.stopped) return;
|
|
90
|
+
this.error = err instanceof Error ? err : new Error(String(err));
|
|
91
|
+
} finally {
|
|
92
|
+
this.computing = false;
|
|
93
|
+
if (!this.stopped) {
|
|
94
|
+
if (!this.settledOnce) {
|
|
95
|
+
this.settledOnce = true;
|
|
96
|
+
this.resolveReady();
|
|
97
|
+
}
|
|
98
|
+
for (const cb of this.subs) cb();
|
|
99
|
+
if (this.dirty) this.schedule();
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
// src/federation/aggregate-across.ts
|
|
106
|
+
var CrossVaultAggregation = class {
|
|
107
|
+
constructor(src, spec, bind) {
|
|
108
|
+
this.src = src;
|
|
109
|
+
this.spec = spec;
|
|
110
|
+
this.bind = bind;
|
|
111
|
+
}
|
|
112
|
+
src;
|
|
113
|
+
spec;
|
|
114
|
+
bind;
|
|
115
|
+
async run(options = {}) {
|
|
116
|
+
const { records, skippedVaults } = await this.src.fanoutRecords(options);
|
|
117
|
+
return { result: reduceRecords(records, this.spec), skippedVaults };
|
|
118
|
+
}
|
|
119
|
+
live(options = {}) {
|
|
120
|
+
if (!this.bind) throw new Error("CrossVaultAggregation: live() requires a LiveBinding \u2014 use ShardedQuery.aggregate()");
|
|
121
|
+
const spec = this.spec;
|
|
122
|
+
const src = this.src;
|
|
123
|
+
const core = new CrossVaultLive({
|
|
124
|
+
subscribeToChanges: this.bind.subscribeToChanges,
|
|
125
|
+
isRelevant: this.bind.isRelevant,
|
|
126
|
+
compute: async () => {
|
|
127
|
+
const { records, skippedVaults } = await src.fanoutRecords(options);
|
|
128
|
+
return { value: reduceRecords(records, spec), skipped: skippedVaults };
|
|
129
|
+
},
|
|
130
|
+
initialSnapshot: { value: void 0, skipped: [] },
|
|
131
|
+
...options.debounceMs !== void 0 ? { debounceMs: options.debounceMs } : {}
|
|
132
|
+
});
|
|
133
|
+
return {
|
|
134
|
+
get value() {
|
|
135
|
+
return core.snapshot.value;
|
|
136
|
+
},
|
|
137
|
+
get skippedVaults() {
|
|
138
|
+
return core.snapshot.skipped;
|
|
139
|
+
},
|
|
140
|
+
get error() {
|
|
141
|
+
return core.error;
|
|
142
|
+
},
|
|
143
|
+
ready: core.ready,
|
|
144
|
+
subscribe: (cb) => core.subscribe(cb),
|
|
145
|
+
stop: () => core.stop()
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
var CrossVaultGroupedAggregation = class {
|
|
150
|
+
constructor(src, field, spec, bind) {
|
|
151
|
+
this.src = src;
|
|
152
|
+
this.field = field;
|
|
153
|
+
this.spec = spec;
|
|
154
|
+
this.bind = bind;
|
|
155
|
+
}
|
|
156
|
+
src;
|
|
157
|
+
field;
|
|
158
|
+
spec;
|
|
159
|
+
bind;
|
|
160
|
+
async run(options = {}) {
|
|
161
|
+
const { records, skippedVaults } = await this.src.fanoutRecords(options);
|
|
162
|
+
return {
|
|
163
|
+
results: groupAndReduce(records, this.field, this.spec),
|
|
164
|
+
skippedVaults
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
live(options = {}) {
|
|
168
|
+
if (!this.bind) throw new Error("CrossVaultGroupedAggregation: live() requires a LiveBinding \u2014 use ShardedQuery.groupBy().aggregate()");
|
|
169
|
+
const field = this.field;
|
|
170
|
+
const spec = this.spec;
|
|
171
|
+
const src = this.src;
|
|
172
|
+
const core = new CrossVaultLive({
|
|
173
|
+
subscribeToChanges: this.bind.subscribeToChanges,
|
|
174
|
+
isRelevant: this.bind.isRelevant,
|
|
175
|
+
compute: async () => {
|
|
176
|
+
const { records, skippedVaults } = await src.fanoutRecords(options);
|
|
177
|
+
return {
|
|
178
|
+
records: groupAndReduce(records, field, spec),
|
|
179
|
+
skipped: skippedVaults
|
|
180
|
+
};
|
|
181
|
+
},
|
|
182
|
+
initialSnapshot: { records: [], skipped: [] },
|
|
183
|
+
...options.debounceMs !== void 0 ? { debounceMs: options.debounceMs } : {}
|
|
184
|
+
});
|
|
185
|
+
return {
|
|
186
|
+
get value() {
|
|
187
|
+
return core.snapshot.records;
|
|
188
|
+
},
|
|
189
|
+
get skippedVaults() {
|
|
190
|
+
return core.snapshot.skipped;
|
|
191
|
+
},
|
|
192
|
+
get error() {
|
|
193
|
+
return core.error;
|
|
194
|
+
},
|
|
195
|
+
ready: core.ready,
|
|
196
|
+
subscribe: (cb) => core.subscribe(cb),
|
|
197
|
+
stop: () => core.stop()
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
// src/federation/vault-group.ts
|
|
203
|
+
var SHARD_SEPARATOR = "--";
|
|
204
|
+
var SAFE_PARTITION_KEY = /^[A-Za-z0-9._-]+$/;
|
|
205
|
+
function assertSafePartitionKey(partitionKey) {
|
|
206
|
+
if (partitionKey.length === 0) {
|
|
207
|
+
throw new ValidationError("partitionKey must be a non-empty string");
|
|
208
|
+
}
|
|
209
|
+
if (partitionKey === STATE_VAULT_NAME) {
|
|
210
|
+
throw new ReservedVaultNameError(partitionKey);
|
|
211
|
+
}
|
|
212
|
+
if (!SAFE_PARTITION_KEY.test(partitionKey)) {
|
|
213
|
+
throw new ValidationError(
|
|
214
|
+
`partitionKey "${partitionKey}" contains characters outside [A-Za-z0-9._-]. Map your records to a store-safe key in sharding.keyOf.`
|
|
215
|
+
);
|
|
216
|
+
}
|
|
217
|
+
if (partitionKey.includes(SHARD_SEPARATOR)) {
|
|
218
|
+
throw new ValidationError(
|
|
219
|
+
`partitionKey "${partitionKey}" must not contain "--" \u2014 it is reserved as the shard vault-id separator and would risk shard-id collisions.`
|
|
220
|
+
);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
var VaultGroup = class {
|
|
224
|
+
constructor(db, name, registry, sharding, template) {
|
|
225
|
+
this.db = db;
|
|
226
|
+
this.name = name;
|
|
227
|
+
this.registry = registry;
|
|
228
|
+
this.sharding = sharding;
|
|
229
|
+
this.template = template;
|
|
230
|
+
if (name.includes(SHARD_SEPARATOR)) {
|
|
231
|
+
throw new ValidationError(
|
|
232
|
+
`VaultGroup name "${name}" must not contain "--" (reserved shard vault-id separator).`
|
|
233
|
+
);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
db;
|
|
237
|
+
name;
|
|
238
|
+
registry;
|
|
239
|
+
sharding;
|
|
240
|
+
template;
|
|
241
|
+
/** @internal — set when the group is managed (no explicit registry). */
|
|
242
|
+
stateVault;
|
|
243
|
+
/** @internal */
|
|
244
|
+
_attachStateVault(sv) {
|
|
245
|
+
this.stateVault = sv;
|
|
246
|
+
}
|
|
247
|
+
/** Deterministic vault name for a partition key, namespaced by the group. */
|
|
248
|
+
shardVaultId(partitionKey) {
|
|
249
|
+
assertSafePartitionKey(partitionKey);
|
|
250
|
+
return `${this.name}${SHARD_SEPARATOR}${partitionKey}`;
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* @internal — group-qualified registry record key (avoids cross-group key
|
|
254
|
+
* collisions). Identical to the shard vault id by design — the registry row
|
|
255
|
+
* for a shard is keyed by that shard's vault id — so it delegates to
|
|
256
|
+
* `shardVaultId`, reusing its partition-key validation.
|
|
257
|
+
*/
|
|
258
|
+
registryId(partitionKey) {
|
|
259
|
+
return this.shardVaultId(partitionKey);
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Registry rows for THIS group (hydrates the registry collection first).
|
|
263
|
+
* The registry may be shared across groups (the auto-wired StateManagement
|
|
264
|
+
* vault holds one `vaultRegistry` for the whole instance), so rows are
|
|
265
|
+
* filtered by `group` — without this, a group's fan-out reads would leak
|
|
266
|
+
* across into other groups' shards. Mirrors the `${group}--` scoping that
|
|
267
|
+
* `liveBinding().isRelevant` already applies to the reactive path.
|
|
268
|
+
*/
|
|
269
|
+
async allRows() {
|
|
270
|
+
await this.registry.list();
|
|
271
|
+
const rows = this.registry.query().toArray();
|
|
272
|
+
return rows.filter((r) => r.group === this.name);
|
|
273
|
+
}
|
|
274
|
+
/** Open an existing shard and apply the template. */
|
|
275
|
+
async openShard(partitionKey) {
|
|
276
|
+
const vault = await this.db.openVault(this.shardVaultId(partitionKey), { create: false });
|
|
277
|
+
this.template.configure(vault);
|
|
278
|
+
return vault;
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Idempotently provision a shard for `partitionKey`. Returns the
|
|
282
|
+
* configured vault handle.
|
|
283
|
+
*
|
|
284
|
+
* - row + vault present → no-op, return handle
|
|
285
|
+
* - row present, vault gone → ShardProvisioningError
|
|
286
|
+
* - row absent (vault present or not) → open-or-create, configure, write row
|
|
287
|
+
*/
|
|
288
|
+
async createShard(partitionKey) {
|
|
289
|
+
const vaultId = this.shardVaultId(partitionKey);
|
|
290
|
+
const row = await this.registry.get(this.registryId(partitionKey));
|
|
291
|
+
const provisioned = await this.db._shardVaultProvisioned(vaultId);
|
|
292
|
+
if (row && !provisioned) throw new ShardProvisioningError(vaultId, partitionKey);
|
|
293
|
+
if (row && provisioned) return this.openShard(partitionKey);
|
|
294
|
+
const vault = await this.db.openVault(vaultId);
|
|
295
|
+
this.template.configure(vault);
|
|
296
|
+
await this.registry.put(this.registryId(partitionKey), {
|
|
297
|
+
vaultId,
|
|
298
|
+
partitionKey,
|
|
299
|
+
templateName: this.sharding.vaultTemplate,
|
|
300
|
+
schemaVersion: this.template.version,
|
|
301
|
+
createdAt: Date.now(),
|
|
302
|
+
group: this.name
|
|
303
|
+
});
|
|
304
|
+
if (this.stateVault) {
|
|
305
|
+
try {
|
|
306
|
+
await this.stateVault.appendEvent({
|
|
307
|
+
type: "shard-created",
|
|
308
|
+
group: this.name,
|
|
309
|
+
vaultId,
|
|
310
|
+
templateName: this.sharding.vaultTemplate,
|
|
311
|
+
version: this.template.version
|
|
312
|
+
});
|
|
313
|
+
} catch {
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
return vault;
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* Drill down to a single shard's full Collection API. Throws if the shard is unknown.
|
|
320
|
+
* Also throws ShardProvisioningError if the registry row exists but the vault has been deleted
|
|
321
|
+
* (registry/store divergence).
|
|
322
|
+
*/
|
|
323
|
+
async shard(partitionKey) {
|
|
324
|
+
const vaultId = this.shardVaultId(partitionKey);
|
|
325
|
+
const row = await this.registry.get(this.registryId(partitionKey));
|
|
326
|
+
if (!row) throw new UnknownShardError(partitionKey, this.name);
|
|
327
|
+
const provisioned = await this.db._shardVaultProvisioned(vaultId);
|
|
328
|
+
if (!provisioned) throw new ShardProvisioningError(vaultId, partitionKey);
|
|
329
|
+
return this.openShard(partitionKey);
|
|
330
|
+
}
|
|
331
|
+
/** A sharded view over one logical collection across all shards. */
|
|
332
|
+
collection(collectionName) {
|
|
333
|
+
return new ShardedCollection(this, collectionName);
|
|
334
|
+
}
|
|
335
|
+
/** @internal — eligible (openable-candidate) rows + drift/divergence skips. */
|
|
336
|
+
async resolveEligible(options = {}) {
|
|
337
|
+
const rows = await this.allRows();
|
|
338
|
+
const skipped = [];
|
|
339
|
+
const versionOk = [];
|
|
340
|
+
for (const row of rows) {
|
|
341
|
+
if (options.minVersion !== void 0 && row.schemaVersion < options.minVersion) {
|
|
342
|
+
skipped.push({ vaultId: row.vaultId, reason: "schema-drift" });
|
|
343
|
+
} else versionOk.push(row);
|
|
344
|
+
}
|
|
345
|
+
const provisioned = await Promise.all(versionOk.map((r) => this.db._shardVaultProvisioned(r.vaultId)));
|
|
346
|
+
const eligible = [];
|
|
347
|
+
versionOk.forEach((row, i) => {
|
|
348
|
+
if (provisioned[i]) eligible.push(row);
|
|
349
|
+
else skipped.push({ vaultId: row.vaultId, reason: "error", error: new ShardProvisioningError(row.vaultId, row.partitionKey) });
|
|
350
|
+
});
|
|
351
|
+
return { eligible, skipped };
|
|
352
|
+
}
|
|
353
|
+
};
|
|
354
|
+
var ShardedCollection = class {
|
|
355
|
+
constructor(group, collectionName) {
|
|
356
|
+
this.group = group;
|
|
357
|
+
this.collectionName = collectionName;
|
|
358
|
+
}
|
|
359
|
+
group;
|
|
360
|
+
collectionName;
|
|
361
|
+
/** Route a write to the shard owning `keyOf(record)`. */
|
|
362
|
+
async put(id, record) {
|
|
363
|
+
const key = this.group.sharding.keyOf(record);
|
|
364
|
+
const row = await this.group.registry.get(this.group.registryId(key));
|
|
365
|
+
let vault;
|
|
366
|
+
if (!row) {
|
|
367
|
+
if (this.group.sharding.autoCreate === false) {
|
|
368
|
+
throw new UnknownShardError(key, this.group.name);
|
|
369
|
+
}
|
|
370
|
+
vault = await this.group.createShard(key);
|
|
371
|
+
} else {
|
|
372
|
+
vault = await this.group.openShard(key);
|
|
373
|
+
}
|
|
374
|
+
await vault.collection(this.collectionName).put(id, record);
|
|
375
|
+
}
|
|
376
|
+
/** Begin a cross-shard fan-out query. */
|
|
377
|
+
query() {
|
|
378
|
+
return new ShardedQuery(this.group, this.collectionName, []);
|
|
379
|
+
}
|
|
380
|
+
};
|
|
381
|
+
var ShardedQuery = class _ShardedQuery {
|
|
382
|
+
constructor(group, collectionName, clauses) {
|
|
383
|
+
this.group = group;
|
|
384
|
+
this.collectionName = collectionName;
|
|
385
|
+
this.clauses = clauses;
|
|
386
|
+
}
|
|
387
|
+
group;
|
|
388
|
+
collectionName;
|
|
389
|
+
clauses;
|
|
390
|
+
where(field, op, value) {
|
|
391
|
+
return new _ShardedQuery(this.group, this.collectionName, [
|
|
392
|
+
...this.clauses,
|
|
393
|
+
{ field, op, value }
|
|
394
|
+
]);
|
|
395
|
+
}
|
|
396
|
+
/** @internal — fan out the where-filtered records across eligible shards. */
|
|
397
|
+
async fanoutRecords(options = {}) {
|
|
398
|
+
const { eligible, skipped } = await this.group.resolveEligible(options);
|
|
399
|
+
const across = await this.group.db.queryAcross(
|
|
400
|
+
eligible.map((r) => r.vaultId),
|
|
401
|
+
async (vault) => {
|
|
402
|
+
this.group.template.configure(vault);
|
|
403
|
+
const coll = vault.collection(this.collectionName);
|
|
404
|
+
await coll.list();
|
|
405
|
+
let q = coll.query();
|
|
406
|
+
for (const c of this.clauses) q = q.where(c.field, c.op, c.value);
|
|
407
|
+
return q.toArray();
|
|
408
|
+
},
|
|
409
|
+
{ concurrency: options.concurrency ?? 1, create: false }
|
|
410
|
+
);
|
|
411
|
+
const results = [];
|
|
412
|
+
for (const r of across) {
|
|
413
|
+
if (r.error) skipped.push({ vaultId: r.vault, reason: classifyShardSkip(r.error), error: r.error });
|
|
414
|
+
else for (const item of r.result) results.push(item);
|
|
415
|
+
}
|
|
416
|
+
return { records: results, skippedVaults: skipped };
|
|
417
|
+
}
|
|
418
|
+
/** Fan out across eligible shards and merge results. */
|
|
419
|
+
async toArray(options = {}) {
|
|
420
|
+
const { records, skippedVaults } = await this.fanoutRecords(options);
|
|
421
|
+
return { results: records, skippedVaults };
|
|
422
|
+
}
|
|
423
|
+
/** @internal — build the change-subscription + relevance binding for this query's group+collection. */
|
|
424
|
+
liveBinding() {
|
|
425
|
+
const group = this.group;
|
|
426
|
+
const collectionName = this.collectionName;
|
|
427
|
+
return {
|
|
428
|
+
subscribeToChanges: (h) => {
|
|
429
|
+
group.db.on("change", h);
|
|
430
|
+
return () => group.db.off("change", h);
|
|
431
|
+
},
|
|
432
|
+
isRelevant: (e) => e.collection === collectionName && e.vault.startsWith(`${group.name}--`)
|
|
433
|
+
};
|
|
434
|
+
}
|
|
435
|
+
/** Returns a reactive cross-shard live query — a facade over CrossVaultLive. */
|
|
436
|
+
live(options = {}) {
|
|
437
|
+
const bind = this.liveBinding();
|
|
438
|
+
const core = new CrossVaultLive({
|
|
439
|
+
...bind,
|
|
440
|
+
compute: async () => {
|
|
441
|
+
const { records, skippedVaults } = await this.fanoutRecords(options);
|
|
442
|
+
return { records, skipped: skippedVaults };
|
|
443
|
+
},
|
|
444
|
+
initialSnapshot: { records: [], skipped: [] },
|
|
445
|
+
...options.debounceMs !== void 0 ? { debounceMs: options.debounceMs } : {}
|
|
446
|
+
});
|
|
447
|
+
return {
|
|
448
|
+
get value() {
|
|
449
|
+
return core.snapshot.records;
|
|
450
|
+
},
|
|
451
|
+
get skippedVaults() {
|
|
452
|
+
return core.snapshot.skipped;
|
|
453
|
+
},
|
|
454
|
+
get error() {
|
|
455
|
+
return core.error;
|
|
456
|
+
},
|
|
457
|
+
ready: core.ready,
|
|
458
|
+
subscribe: (cb) => core.subscribe(cb),
|
|
459
|
+
stop: () => core.stop()
|
|
460
|
+
};
|
|
461
|
+
}
|
|
462
|
+
/** One-shot distributed aggregate — central reduce over all shard records. */
|
|
463
|
+
aggregate(spec) {
|
|
464
|
+
return new CrossVaultAggregation(this, spec, this.liveBinding());
|
|
465
|
+
}
|
|
466
|
+
/** Begin a grouped cross-shard aggregate. */
|
|
467
|
+
groupBy(field) {
|
|
468
|
+
return new ShardedGroupedQuery(this, field);
|
|
469
|
+
}
|
|
470
|
+
};
|
|
471
|
+
var ShardedGroupedQuery = class {
|
|
472
|
+
constructor(query, field) {
|
|
473
|
+
this.query = query;
|
|
474
|
+
this.field = field;
|
|
475
|
+
}
|
|
476
|
+
query;
|
|
477
|
+
field;
|
|
478
|
+
aggregate(spec) {
|
|
479
|
+
return new CrossVaultGroupedAggregation(
|
|
480
|
+
{ fanoutRecords: (o) => this.query.fanoutRecords(o) },
|
|
481
|
+
this.field,
|
|
482
|
+
spec,
|
|
483
|
+
this.query.liveBinding()
|
|
484
|
+
);
|
|
485
|
+
}
|
|
486
|
+
};
|
|
487
|
+
export {
|
|
488
|
+
ShardedCollection,
|
|
489
|
+
ShardedGroupedQuery,
|
|
490
|
+
ShardedQuery,
|
|
491
|
+
VaultGroup
|
|
492
|
+
};
|
|
493
|
+
//# sourceMappingURL=vault-group-UO4YUZOG.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/federation/classify-skip.ts","../src/federation/cross-vault-live.ts","../src/federation/aggregate-across.ts","../src/federation/vault-group.ts"],"sourcesContent":["import { NoAccessError } from '../errors.js'\nimport type { SkippedVault } from './types.js'\n\n/**\n * Classify a per-shard fan-out failure. `NoAccessError` (no keyring envelope for\n * the calling identity) is the unambiguous not-granted signal → `'no-grant'`\n * (expected under scoped access, not a fault). Everything else → `'error'` —\n * `InvalidKeyError`/`DecryptionError`/`KeyringCorruptError` can mean \"wrong KEK\n * OR whole-file corruption\" per loadKeyring, so they must not hide as no-grant.\n */\nexport function classifyShardSkip(err: Error): Exclude<SkippedVault['reason'], 'schema-drift'> {\n return err instanceof NoAccessError ? 'no-grant' : 'error'\n}\n","/**\n * @category capability\n * Reactive core for cross-vault live queries/aggregations. Generic over a\n * snapshot S. Single-flight + microtask-coalesced recompute on relevant\n * change. Mirrors the LiveQuery/LiveAggregation contracts via facades.\n * Spec: docs/superpowers/specs/2026-06-07-cross-vault-live-and-aggregate-design.md.\n */\nimport type { ChangeEvent } from '../types.js'\n\nexport interface CrossVaultLiveOptions<S> {\n readonly subscribeToChanges: (handler: (e: ChangeEvent) => void) => () => void\n readonly isRelevant: (e: ChangeEvent) => boolean\n readonly compute: () => Promise<S>\n readonly initialSnapshot: S\n readonly debounceMs?: number\n}\n\nexport class CrossVaultLive<S> {\n snapshot: S\n error: Error | null = null\n readonly ready: Promise<void>\n\n private readonly subs = new Set<() => void>()\n private readonly unsubChange: () => void\n private readonly opts: CrossVaultLiveOptions<S>\n private stopped = false\n private computing = false\n private dirty = false\n private scheduled = false\n private timer: ReturnType<typeof setTimeout> | null = null\n private resolveReady!: () => void\n private settledOnce = false\n\n constructor(opts: CrossVaultLiveOptions<S>) {\n this.opts = opts\n this.snapshot = opts.initialSnapshot\n this.ready = new Promise<void>((res) => { this.resolveReady = res })\n this.unsubChange = opts.subscribeToChanges((e) => {\n if (this.stopped || !opts.isRelevant(e)) return\n this.schedule()\n })\n this.schedule() // initial compute\n }\n\n subscribe(cb: () => void): () => void {\n if (this.stopped) return () => {}\n this.subs.add(cb)\n return () => this.subs.delete(cb)\n }\n\n stop(): void {\n if (this.stopped) return\n this.stopped = true\n this.unsubChange()\n if (this.timer !== null) clearTimeout(this.timer)\n this.subs.clear()\n if (!this.settledOnce) this.resolveReady() // never leave ready dangling\n }\n\n private schedule(): void {\n if (this.stopped) return\n if (this.computing) { this.dirty = true; return }\n if (this.scheduled) return\n this.scheduled = true\n const run = () => { this.scheduled = false; void this.runCompute() }\n const ms = this.opts.debounceMs ?? 0\n if (ms > 0) this.timer = setTimeout(run, ms)\n // queueMicrotask is non-cancellable; the `if (this.stopped) return` guard at the top of runCompute makes a post-stop fire a no-op.\n else queueMicrotask(run)\n }\n\n private async runCompute(): Promise<void> {\n if (this.stopped) return\n this.computing = true\n this.dirty = false\n try {\n const next = await this.opts.compute()\n if (this.stopped) return\n this.snapshot = next\n this.error = null\n } catch (err) {\n if (this.stopped) return\n this.error = err instanceof Error ? err : new Error(String(err))\n } finally {\n this.computing = false\n if (!this.stopped) {\n if (!this.settledOnce) { this.settledOnce = true; this.resolveReady() }\n for (const cb of this.subs) cb()\n if (this.dirty) this.schedule()\n }\n }\n }\n}\n","/**\n * @category capability\n * One-shot distributed aggregate wrappers for cross-vault fan-out.\n * Central-reduce: all shard records are concatenated and reduced in one pass\n * so avg/mean values are computed over the full union, not as avg-of-avgs.\n * Spec: docs/superpowers/specs/2026-06-07-cross-vault-live-and-aggregate-design.md.\n */\nimport { reduceRecords } from '../aggregate/aggregation.js'\nimport { groupAndReduce } from '../aggregate/groupby.js'\nimport type { AggregateResult, AggregateSpec } from '../aggregate/aggregation.js'\nimport type {\n FanoutQueryOptions,\n SkippedVault,\n GroupedRow,\n LiveQueryOptions,\n CrossVaultLiveAggregation,\n CrossVaultLiveQuery,\n} from './types.js'\nimport { CrossVaultLive } from './cross-vault-live.js'\nimport type { ChangeEvent } from '../types.js'\n\n/** A source that can fan out records across shards. Satisfied by ShardedQuery. */\nexport interface FanoutRecordSource<R> {\n fanoutRecords(options: FanoutQueryOptions): Promise<{ records: R[]; skippedVaults: SkippedVault[] }>\n}\n\n/** Live-binding hooks (change subscription + relevance) threaded from ShardedQuery. */\nexport interface LiveBinding {\n subscribeToChanges: (handler: (e: ChangeEvent) => void) => () => void\n isRelevant: (e: ChangeEvent) => boolean\n}\n\n/**\n * One-shot cross-vault aggregate. Concatenates all shard records and runs a\n * single central reduce, ensuring correct avg/mean values.\n */\nexport class CrossVaultAggregation<R, Spec extends AggregateSpec> {\n constructor(\n private readonly src: FanoutRecordSource<R>,\n private readonly spec: Spec,\n private readonly bind?: LiveBinding,\n ) {}\n\n async run(options: FanoutQueryOptions = {}): Promise<{\n result: AggregateResult<Spec>\n skippedVaults: SkippedVault[]\n }> {\n const { records, skippedVaults } = await this.src.fanoutRecords(options)\n return { result: reduceRecords(records, this.spec), skippedVaults }\n }\n\n live(options: LiveQueryOptions = {}): CrossVaultLiveAggregation<AggregateResult<Spec>> {\n if (!this.bind) throw new Error('CrossVaultAggregation: live() requires a LiveBinding — use ShardedQuery.aggregate()')\n const spec = this.spec\n const src = this.src\n const core = new CrossVaultLive<{ value: AggregateResult<Spec> | undefined; skipped: SkippedVault[] }>({\n subscribeToChanges: this.bind.subscribeToChanges,\n isRelevant: this.bind.isRelevant,\n compute: async () => {\n const { records, skippedVaults } = await src.fanoutRecords(options)\n return { value: reduceRecords(records, spec), skipped: skippedVaults }\n },\n initialSnapshot: { value: undefined, skipped: [] },\n ...(options.debounceMs !== undefined ? { debounceMs: options.debounceMs } : {}),\n })\n return {\n get value() { return core.snapshot.value },\n get skippedVaults() { return core.snapshot.skipped as readonly SkippedVault[] },\n get error() { return core.error },\n ready: core.ready,\n subscribe: (cb) => core.subscribe(cb),\n stop: () => core.stop(),\n }\n }\n}\n\n/**\n * One-shot cross-vault grouped aggregate. Concatenates all shard records and\n * runs a single central group-and-reduce, emitting one row per bucket.\n */\nexport class CrossVaultGroupedAggregation<R, F extends string, Spec extends AggregateSpec> {\n constructor(\n private readonly src: FanoutRecordSource<R>,\n private readonly field: F,\n private readonly spec: Spec,\n private readonly bind?: LiveBinding,\n ) {}\n\n async run(options: FanoutQueryOptions = {}): Promise<{\n results: GroupedRow<F, Spec>[]\n skippedVaults: SkippedVault[]\n }> {\n const { records, skippedVaults } = await this.src.fanoutRecords(options)\n return {\n results: groupAndReduce<GroupedRow<F, Spec>>(records, this.field, this.spec),\n skippedVaults,\n }\n }\n\n live(options: LiveQueryOptions = {}): CrossVaultLiveQuery<GroupedRow<F, Spec>> {\n if (!this.bind) throw new Error('CrossVaultGroupedAggregation: live() requires a LiveBinding — use ShardedQuery.groupBy().aggregate()')\n const field = this.field\n const spec = this.spec\n const src = this.src\n const core = new CrossVaultLive<{ records: GroupedRow<F, Spec>[]; skipped: SkippedVault[] }>({\n subscribeToChanges: this.bind.subscribeToChanges,\n isRelevant: this.bind.isRelevant,\n compute: async () => {\n const { records, skippedVaults } = await src.fanoutRecords(options)\n return {\n records: groupAndReduce<GroupedRow<F, Spec>>(records, field, spec),\n skipped: skippedVaults,\n }\n },\n initialSnapshot: { records: [], skipped: [] },\n ...(options.debounceMs !== undefined ? { debounceMs: options.debounceMs } : {}),\n })\n return {\n get value() { return core.snapshot.records as readonly GroupedRow<F, Spec>[] },\n get skippedVaults() { return core.snapshot.skipped as readonly SkippedVault[] },\n get error() { return core.error },\n ready: core.ready,\n subscribe: (cb) => core.subscribe(cb),\n stop: () => core.stop(),\n }\n }\n}\n","/**\n * @category capability\n * Multi-vault partition federation — VaultGroup transparent shard\n * routing. Spec:\n * docs/superpowers/specs/2026-06-07-mvf-vaultgroup-routing-mvp-design.md.\n */\nimport type { Noydb } from '../noydb.js'\nimport type { Vault } from '../vault.js'\nimport type { Collection } from '../collection.js'\nimport type { StateManagementVault } from './state-vault.js'\nimport { ReservedVaultNameError, ShardProvisioningError, UnknownShardError, ValidationError } from '../errors.js'\nimport { STATE_VAULT_NAME } from './constants.js'\nimport { classifyShardSkip } from './classify-skip.js'\nimport { CrossVaultLive } from './cross-vault-live.js'\nimport { CrossVaultAggregation, CrossVaultGroupedAggregation } from './aggregate-across.js'\nimport type { FanoutRecordSource, LiveBinding } from './aggregate-across.js'\nimport type { AggregateSpec } from '../aggregate/aggregation.js'\nimport type {\n ShardingConfig,\n VaultRegistryRow,\n VaultTemplate,\n FanoutQueryOptions,\n FanoutResult,\n SkippedVault,\n WhereClause,\n LiveQueryOptions,\n CrossVaultLiveQuery,\n} from './types.js'\n\n/** Reserved separator between group name and partition key in a shard vault id. */\nconst SHARD_SEPARATOR = '--'\n/** Store-safe partition-key charset (single hyphens OK; '--' is the reserved separator). */\nconst SAFE_PARTITION_KEY = /^[A-Za-z0-9._-]+$/\n\nfunction assertSafePartitionKey(partitionKey: string): void {\n if (partitionKey.length === 0) {\n throw new ValidationError('partitionKey must be a non-empty string')\n }\n if (partitionKey === STATE_VAULT_NAME) {\n throw new ReservedVaultNameError(partitionKey)\n }\n if (!SAFE_PARTITION_KEY.test(partitionKey)) {\n throw new ValidationError(\n `partitionKey \"${partitionKey}\" contains characters outside [A-Za-z0-9._-]. ` +\n `Map your records to a store-safe key in sharding.keyOf.`,\n )\n }\n if (partitionKey.includes(SHARD_SEPARATOR)) {\n throw new ValidationError(\n `partitionKey \"${partitionKey}\" must not contain \"--\" — it is reserved as the ` +\n `shard vault-id separator and would risk shard-id collisions.`,\n )\n }\n}\n\nexport class VaultGroup<T> {\n constructor(\n /** @internal */ readonly db: Noydb,\n /** @internal */ readonly name: string,\n /** @internal */ readonly registry: Collection<VaultRegistryRow>,\n /** @internal */ readonly sharding: ShardingConfig<T>,\n /** @internal */ readonly template: VaultTemplate,\n ) {\n if (name.includes(SHARD_SEPARATOR)) {\n throw new ValidationError(\n `VaultGroup name \"${name}\" must not contain \"--\" (reserved shard vault-id separator).`,\n )\n }\n }\n\n /** @internal — set when the group is managed (no explicit registry). */\n private stateVault: StateManagementVault | undefined\n\n /** @internal */\n _attachStateVault(sv: StateManagementVault): void {\n this.stateVault = sv\n }\n\n /** Deterministic vault name for a partition key, namespaced by the group. */\n shardVaultId(partitionKey: string): string {\n assertSafePartitionKey(partitionKey)\n return `${this.name}${SHARD_SEPARATOR}${partitionKey}`\n }\n\n /**\n * @internal — group-qualified registry record key (avoids cross-group key\n * collisions). Identical to the shard vault id by design — the registry row\n * for a shard is keyed by that shard's vault id — so it delegates to\n * `shardVaultId`, reusing its partition-key validation.\n */\n registryId(partitionKey: string): string {\n return this.shardVaultId(partitionKey)\n }\n\n /**\n * Registry rows for THIS group (hydrates the registry collection first).\n * The registry may be shared across groups (the auto-wired StateManagement\n * vault holds one `vaultRegistry` for the whole instance), so rows are\n * filtered by `group` — without this, a group's fan-out reads would leak\n * across into other groups' shards. Mirrors the `${group}--` scoping that\n * `liveBinding().isRelevant` already applies to the reactive path.\n */\n async allRows(): Promise<VaultRegistryRow[]> {\n await this.registry.list()\n const rows = this.registry.query().toArray() // toArray() is synchronous\n return rows.filter((r) => r.group === this.name)\n }\n\n /** Open an existing shard and apply the template. */\n async openShard(partitionKey: string): Promise<Vault> {\n const vault = await this.db.openVault(this.shardVaultId(partitionKey), { create: false })\n this.template.configure(vault)\n return vault\n }\n\n /**\n * Idempotently provision a shard for `partitionKey`. Returns the\n * configured vault handle.\n *\n * - row + vault present → no-op, return handle\n * - row present, vault gone → ShardProvisioningError\n * - row absent (vault present or not) → open-or-create, configure, write row\n */\n async createShard(partitionKey: string): Promise<Vault> {\n const vaultId = this.shardVaultId(partitionKey)\n const row = await this.registry.get(this.registryId(partitionKey))\n const provisioned = await this.db._shardVaultProvisioned(vaultId)\n\n if (row && !provisioned) throw new ShardProvisioningError(vaultId, partitionKey)\n if (row && provisioned) return this.openShard(partitionKey)\n\n // Row absent → create (or reconcile a provisioned-but-unregistered vault).\n const vault = await this.db.openVault(vaultId)\n this.template.configure(vault)\n await this.registry.put(this.registryId(partitionKey), {\n vaultId,\n partitionKey,\n templateName: this.sharding.vaultTemplate,\n schemaVersion: this.template.version,\n createdAt: Date.now(),\n group: this.name,\n })\n if (this.stateVault) {\n try {\n await this.stateVault.appendEvent({\n type: 'shard-created',\n group: this.name,\n vaultId,\n templateName: this.sharding.vaultTemplate,\n version: this.template.version,\n })\n } catch {\n /* best-effort: event logging never fails the shard write */\n }\n }\n return vault\n }\n\n /**\n * Drill down to a single shard's full Collection API. Throws if the shard is unknown.\n * Also throws ShardProvisioningError if the registry row exists but the vault has been deleted\n * (registry/store divergence).\n */\n async shard(partitionKey: string): Promise<Vault> {\n const vaultId = this.shardVaultId(partitionKey)\n const row = await this.registry.get(this.registryId(partitionKey))\n if (!row) throw new UnknownShardError(partitionKey, this.name)\n const provisioned = await this.db._shardVaultProvisioned(vaultId)\n if (!provisioned) throw new ShardProvisioningError(vaultId, partitionKey)\n return this.openShard(partitionKey)\n }\n\n /** A sharded view over one logical collection across all shards. */\n collection<R = T>(collectionName: string): ShardedCollection<T, R> {\n return new ShardedCollection<T, R>(this, collectionName)\n }\n\n /** @internal — eligible (openable-candidate) rows + drift/divergence skips. */\n async resolveEligible(options: { minVersion?: number } = {}): Promise<{\n eligible: VaultRegistryRow[]\n skipped: SkippedVault[]\n }> {\n const rows = await this.allRows()\n const skipped: SkippedVault[] = []\n const versionOk: VaultRegistryRow[] = []\n for (const row of rows) {\n if (options.minVersion !== undefined && row.schemaVersion < options.minVersion) {\n skipped.push({ vaultId: row.vaultId, reason: 'schema-drift' })\n } else versionOk.push(row)\n }\n const provisioned = await Promise.all(versionOk.map((r) => this.db._shardVaultProvisioned(r.vaultId)))\n const eligible: VaultRegistryRow[] = []\n versionOk.forEach((row, i) => {\n if (provisioned[i]) eligible.push(row)\n else skipped.push({ vaultId: row.vaultId, reason: 'error', error: new ShardProvisioningError(row.vaultId, row.partitionKey) })\n })\n return { eligible, skipped }\n }\n}\n\nexport class ShardedCollection<T, R = T> {\n constructor(\n private readonly group: VaultGroup<T>,\n private readonly collectionName: string,\n ) {}\n\n /** Route a write to the shard owning `keyOf(record)`. */\n async put(id: string, record: T): Promise<void> {\n const key = this.group.sharding.keyOf(record)\n const row = await this.group.registry.get(this.group.registryId(key))\n let vault: Vault\n if (!row) {\n if (this.group.sharding.autoCreate === false) {\n throw new UnknownShardError(key, this.group.name)\n }\n vault = await this.group.createShard(key)\n } else {\n vault = await this.group.openShard(key)\n }\n await vault.collection<T>(this.collectionName).put(id, record)\n }\n\n /** Begin a cross-shard fan-out query. */\n query(): ShardedQuery<T, R> {\n return new ShardedQuery<T, R>(this.group, this.collectionName, [])\n }\n}\n\nexport class ShardedQuery<T, R = T> {\n constructor(\n private readonly group: VaultGroup<T>,\n private readonly collectionName: string,\n private readonly clauses: readonly WhereClause[],\n ) {}\n\n where(field: string, op: WhereClause['op'], value: unknown): ShardedQuery<T, R> {\n return new ShardedQuery<T, R>(this.group, this.collectionName, [\n ...this.clauses,\n { field, op, value },\n ])\n }\n\n /** @internal — fan out the where-filtered records across eligible shards. */\n async fanoutRecords(options: FanoutQueryOptions = {}): Promise<{ records: R[]; skippedVaults: SkippedVault[] }> {\n const { eligible, skipped } = await this.group.resolveEligible(options)\n const across = await this.group.db.queryAcross<R[]>(\n eligible.map((r) => r.vaultId),\n async (vault) => {\n this.group.template.configure(vault)\n const coll = vault.collection<R>(this.collectionName)\n await coll.list() // hydrate the in-memory cache before the sync query\n let q = coll.query()\n for (const c of this.clauses) q = q.where(c.field, c.op, c.value)\n return q.toArray()\n },\n { concurrency: options.concurrency ?? 1, create: false },\n )\n const results: R[] = []\n for (const r of across) {\n if (r.error) skipped.push({ vaultId: r.vault, reason: classifyShardSkip(r.error), error: r.error })\n else for (const item of r.result) results.push(item)\n }\n return { records: results, skippedVaults: skipped }\n }\n\n /** Fan out across eligible shards and merge results. */\n async toArray(options: FanoutQueryOptions = {}): Promise<FanoutResult<R>> {\n const { records, skippedVaults } = await this.fanoutRecords(options)\n return { results: records, skippedVaults }\n }\n\n /** @internal — build the change-subscription + relevance binding for this query's group+collection. */\n liveBinding(): LiveBinding {\n const group = this.group\n const collectionName = this.collectionName\n return {\n subscribeToChanges: (h) => { group.db.on('change', h); return () => group.db.off('change', h) },\n isRelevant: (e) => e.collection === collectionName && e.vault.startsWith(`${group.name}--`),\n }\n }\n\n /** Returns a reactive cross-shard live query — a facade over CrossVaultLive. */\n live(options: LiveQueryOptions = {}): CrossVaultLiveQuery<R> {\n const bind = this.liveBinding()\n const core = new CrossVaultLive<{ records: R[]; skipped: SkippedVault[] }>({\n ...bind,\n compute: async () => {\n const { records, skippedVaults } = await this.fanoutRecords(options)\n return { records, skipped: skippedVaults }\n },\n initialSnapshot: { records: [], skipped: [] },\n ...(options.debounceMs !== undefined ? { debounceMs: options.debounceMs } : {}),\n })\n return {\n get value() { return core.snapshot.records as readonly R[] },\n get skippedVaults() { return core.snapshot.skipped as readonly SkippedVault[] },\n get error() { return core.error },\n ready: core.ready,\n subscribe: (cb) => core.subscribe(cb),\n stop: () => core.stop(),\n }\n }\n\n /** One-shot distributed aggregate — central reduce over all shard records. */\n aggregate<Spec extends AggregateSpec>(spec: Spec): CrossVaultAggregation<R, Spec> {\n return new CrossVaultAggregation<R, Spec>(this, spec, this.liveBinding())\n }\n\n /** Begin a grouped cross-shard aggregate. */\n groupBy<F extends string>(field: F): ShardedGroupedQuery<T, R, F> {\n return new ShardedGroupedQuery<T, R, F>(this, field)\n }\n}\n\n/** Grouped cross-shard query — intermediate after `.groupBy(field)`, terminates with `.aggregate(spec)`. */\nexport class ShardedGroupedQuery<T, R, F extends string> {\n constructor(\n private readonly query: ShardedQuery<T, R>,\n private readonly field: F,\n ) {}\n\n aggregate<Spec extends AggregateSpec>(spec: Spec): CrossVaultGroupedAggregation<R, F, Spec> {\n return new CrossVaultGroupedAggregation<R, F, Spec>(\n { fanoutRecords: (o) => this.query.fanoutRecords(o) } satisfies FanoutRecordSource<R>,\n this.field,\n spec,\n this.query.liveBinding(),\n )\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { aN as DerivationStrategy, aR as DerivationStrategyHandle } from './types-
|
|
1
|
+
import { aN as DerivationStrategy, aR as DerivationStrategyHandle } from './types-pax34sec.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Register a deterministic derivation: one source collection → one or
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { aN as DerivationStrategy, aR as DerivationStrategyHandle } from './types-
|
|
1
|
+
import { aN as DerivationStrategy, aR as DerivationStrategyHandle } from './types-CDwSSXiI.cjs';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Register a deterministic derivation: one source collection → one or
|
package/dist/{with-materialized-view-BTTU3BNK.d.cts → with-materialized-view-5QMF1rS_.d.cts}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { aV as MaterializedViewStrategy, aW as MaterializedViewStrategyHandle } from './types-
|
|
1
|
+
import { aV as MaterializedViewStrategy, aW as MaterializedViewStrategyHandle } from './types-CDwSSXiI.cjs';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Register a materialized view: a declared query whose result is
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { aV as MaterializedViewStrategy, aW as MaterializedViewStrategyHandle } from './types-
|
|
1
|
+
import { aV as MaterializedViewStrategy, aW as MaterializedViewStrategyHandle } from './types-pax34sec.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Register a materialized view: a declared query whose result is
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { aX as OverlayedViewStrategy, a_ as OverlayedViewStrategyHandle } from './types-
|
|
1
|
+
import { aX as OverlayedViewStrategy, a_ as OverlayedViewStrategyHandle } from './types-pax34sec.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Register a read-shadow overlay: bind an MV-owned base collection to
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { aX as OverlayedViewStrategy, a_ as OverlayedViewStrategyHandle } from './types-
|
|
1
|
+
import { aX as OverlayedViewStrategy, a_ as OverlayedViewStrategyHandle } from './types-CDwSSXiI.cjs';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Register a read-shadow overlay: bind an MV-owned base collection to
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@noy-db/hub",
|
|
3
|
-
"version": "0.2.0-pre.
|
|
3
|
+
"version": "0.2.0-pre.13",
|
|
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>",
|
|
@@ -269,14 +269,14 @@
|
|
|
269
269
|
"node": ">=18.0.0"
|
|
270
270
|
},
|
|
271
271
|
"dependencies": {
|
|
272
|
-
"@noy-db/attestation": "0.2.0-pre.
|
|
272
|
+
"@noy-db/attestation": "0.2.0-pre.13"
|
|
273
273
|
},
|
|
274
274
|
"devDependencies": {
|
|
275
275
|
"@types/node": "^22.0.0",
|
|
276
276
|
"esbuild": "^0.25.0",
|
|
277
277
|
"zod": "^3.23.0",
|
|
278
278
|
"zod-to-json-schema": "^3.25.2",
|
|
279
|
-
"@noy-db/on-shamir": "0.2.0-pre.
|
|
279
|
+
"@noy-db/on-shamir": "0.2.0-pre.13"
|
|
280
280
|
},
|
|
281
281
|
"peerDependencies": {
|
|
282
282
|
"zod-to-json-schema": "^3.25.0"
|