@noy-db/hub 0.2.0-pre.12 → 0.2.0-pre.14
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 +2 -2
- package/dist/aggregate/index.d.ts +2 -2
- package/dist/aggregate/index.js +2 -2
- 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.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 +683 -39
- 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-OPDTLHFA.js → chunk-3EWA37FV.js} +2 -2
- package/dist/{chunk-ZCFS7U4J.js → chunk-4PEFEETV.js} +2 -2
- package/dist/{chunk-ZC7MNVYN.js → chunk-4TBBMHVC.js} +2 -2
- package/dist/{chunk-AGRC7NQQ.js → chunk-535SSHBS.js} +33 -1
- package/dist/chunk-535SSHBS.js.map +1 -0
- package/dist/{chunk-SJJQKNMP.js → chunk-56DJ7JVK.js} +4 -4
- package/dist/{chunk-C2CIIQRG.js → chunk-5LQG6ZO2.js} +2 -2
- package/dist/{chunk-6AD5TBF2.js → chunk-6AJBSQU4.js} +3 -3
- package/dist/{chunk-LWSD4QPT.js → chunk-6RR3MNMG.js} +3 -3
- package/dist/{chunk-O53RIZCC.js → chunk-7HT2MEZ5.js} +5 -5
- package/dist/{chunk-7LVRIW4G.js → chunk-7PS7EOCF.js} +4 -4
- package/dist/{chunk-GFPR7VJS.js → chunk-A5ZOOZFB.js} +4 -4
- package/dist/{chunk-B7GGYNKQ.js → chunk-AAVWKNZW.js} +2 -2
- package/dist/{chunk-TMHJEYW7.js → chunk-ACKFRSAH.js} +302 -137
- package/dist/chunk-ACKFRSAH.js.map +1 -0
- package/dist/{chunk-SZ4N3IL5.js → chunk-BIYRQQV6.js} +5 -5
- package/dist/{chunk-CILT6V3V.js → chunk-BQ65SS5A.js} +2 -2
- package/dist/{chunk-DLTU4M2I.js → chunk-COFPAMX6.js} +6 -6
- package/dist/{chunk-UA6G45ME.js → chunk-DKO2QFSA.js} +3 -3
- package/dist/{chunk-L6BYRCYB.js → chunk-DQU36Q7I.js} +2 -2
- package/dist/{chunk-VOXMU6LB.js → chunk-EGD5DXFT.js} +2 -2
- package/dist/{chunk-BXOUVUES.js → chunk-F4OJZIWQ.js} +4 -4
- package/dist/{chunk-P3Z5Y2TS.js → chunk-FWPKCXTN.js} +2 -2
- package/dist/{chunk-LYNNZEQD.js → chunk-GC4V7RU7.js} +1 -1
- package/dist/chunk-GC4V7RU7.js.map +1 -0
- package/dist/{chunk-6BYBVRZU.js → chunk-HOR4R722.js} +3 -3
- package/dist/{chunk-XSIFXX54.js → chunk-JD3OZAI4.js} +2 -2
- package/dist/{chunk-UOC7JMZO.js → chunk-KGCORI4L.js} +135 -10
- package/dist/chunk-KGCORI4L.js.map +1 -0
- package/dist/{chunk-RRDWXNBQ.js → chunk-KI6HAJWL.js} +3 -3
- package/dist/{chunk-LSEW3ZZ2.js → chunk-L2FE64BU.js} +3 -3
- package/dist/{chunk-HBAJDI2N.js → chunk-LX3CB26H.js} +5 -5
- package/dist/{chunk-LOA2VCMS.js → chunk-NSCVNK5K.js} +5 -5
- package/dist/{chunk-4BHFNKTP.js → chunk-OHVFWCJP.js} +2 -2
- package/dist/{chunk-7JJE3OMJ.js → chunk-PE4AQGFH.js} +5 -5
- package/dist/{chunk-RHQYVHFH.js → chunk-TS26M2SB.js} +2 -2
- package/dist/{chunk-EKNUBIIQ.js → chunk-UWNYBOOO.js} +4 -4
- package/dist/{chunk-WNRGOVLG.js → chunk-VU7SWWT5.js} +2 -2
- package/dist/{chunk-WUG3E423.js → chunk-WBAYSNUQ.js} +4 -4
- package/dist/{chunk-XHM2SARW.js → chunk-WGHU7BLI.js} +3 -3
- package/dist/{chunk-5ARRXIVR.js → chunk-X73VS74Y.js} +2 -2
- package/dist/{chunk-M45IRXDM.js → chunk-YHPM5D7Y.js} +3 -3
- package/dist/{chunk-P4EDT5ZP.js → chunk-YNTBADIY.js} +2 -2
- package/dist/{chunk-IUBHXEPJ.js → chunk-YULZKK4F.js} +2 -2
- package/dist/{chunk-IEPT7HVP.js → chunk-Z4DO7YSI.js} +2 -2
- package/dist/chunk-ZC7J6ZYV.js +7 -0
- package/dist/chunk-ZC7J6ZYV.js.map +1 -0
- package/dist/{chunk-HLGDYFWR.js → chunk-ZNQYHJXX.js} +2 -2
- package/dist/{chunk-CHBXWJZQ.js → chunk-ZWTNWAO4.js} +2 -2
- 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-AJB72OKN.js → crypto-QXQOHMHF.js} +3 -3
- package/dist/{delegation-6FCWDRUS.js → delegation-NIQ43IPU.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-ckqa_Nso.d.cts → dev-unlock-BF4OSxRv.d.cts} +1 -1
- package/dist/{dev-unlock-D3mpVFRc.d.ts → dev-unlock-DV7ujTCI.d.ts} +1 -1
- package/dist/executor-6ZDSDZ6V.js +8 -0
- package/dist/executor-723ZP6TH.js +11 -0
- package/dist/executor-IDZDAFNH.js +8 -0
- package/dist/{fanout-sidecar-ZSKEQ6NI.js → fanout-sidecar-N6OJX6QR.js} +2 -2
- package/dist/guards/index.cjs.map +1 -1
- package/dist/guards/index.d.cts +5 -5
- package/dist/guards/index.d.ts +5 -5
- package/dist/guards/index.js +3 -3
- package/dist/{hash-rDSSd_oW.d.cts → hash-BcF5WQXl.d.cts} +1 -1
- package/dist/{hash-CTZVkXLx.d.ts → hash-DswxkLtW.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-C51vAHuh.d.cts → immutable-guard-7KqslW2K.d.cts} +1 -1
- package/dist/{immutable-guard-DyD0qg2k.d.ts → immutable-guard-C8IYdzfu.d.ts} +1 -1
- package/dist/{index-Cmop06zJ.d.cts → index-CUVOMtgg.d.cts} +28 -2
- package/dist/{index-CkFHr4OP.d.ts → index-Cqzp4tt9.d.ts} +28 -2
- package/dist/index.cjs +699 -42
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +22 -13
- package/dist/index.d.ts +22 -13
- package/dist/index.js +59 -40
- 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-ADVS4OVP.js +12 -0
- package/dist/{ledger-5JMVF7PY.js → ledger-CWSE3BLF.js} +5 -5
- package/dist/materialized-views/index.cjs.map +1 -1
- package/dist/materialized-views/index.d.cts +5 -5
- package/dist/materialized-views/index.d.ts +5 -5
- package/dist/materialized-views/index.js +6 -6
- package/dist/noydb-VZ4JVW55.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-PFLZI5MO.js → public-envelope-SYHEYQ3X.js} +4 -4
- package/dist/query/index.cjs +89 -7
- 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 +3 -3
- package/dist/{registry-NCY445U5.js → registry-DK5YWAAA.js} +3 -3
- package/dist/registry-IUZQVVBB.js +8 -0
- package/dist/registry-XGLNADIE.js +8 -0
- package/dist/{revoke-7RLGQWZ7.js → revoke-ZDFKMR5E.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-6JF44I4A.js → signer-P5D7Y72U.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-UBLP3RJ3.js → stale-7FRJVHN6.js} +2 -2
- package/dist/state-vault-TMXZRTY5.js +147 -0
- package/dist/state-vault-TMXZRTY5.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-rtpKDfTC.d.ts → strategy-CrS7PnbE.d.cts} +20 -1
- package/dist/{strategy-rtpKDfTC.d.cts → strategy-CrS7PnbE.d.ts} +20 -1
- 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.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-DRdfwgTG.d.ts → types-BFHQUjdy.d.ts} +341 -90
- package/dist/{types-BGwjsDef.d.cts → types-V5R2-pd4.d.cts} +341 -90
- package/dist/{ulid-D4d0Xto3.d.cts → ulid-CwNf9e6-.d.cts} +1 -1
- package/dist/{ulid-DOTPZ5_h.d.ts → ulid-p2nKiiKg.d.ts} +1 -1
- package/dist/util/index.cjs.map +1 -1
- package/dist/util/index.js +1 -1
- package/dist/{vault-group-Z4KB75ZH.js → vault-group-W7QC4UYW.js} +175 -18
- package/dist/vault-group-W7QC4UYW.js.map +1 -0
- package/dist/{with-derivation-CB1EdcFF.d.cts → with-derivation-C9K43BOB.d.cts} +1 -1
- package/dist/{with-derivation-B082Y_WQ.d.ts → with-derivation-Ds9yZgCj.d.ts} +1 -1
- package/dist/{with-materialized-view-CzRg1Dpr.d.cts → with-materialized-view-DgQcAjYv.d.cts} +1 -1
- package/dist/{with-materialized-view-Dw4SwjKl.d.ts → with-materialized-view-DwR4jkV5.d.ts} +1 -1
- package/dist/{with-overlayed-view-C9YFKXzn.d.cts → with-overlayed-view-7-rUB3vD.d.cts} +1 -1
- package/dist/{with-overlayed-view-CaCXeW26.d.ts → with-overlayed-view-ByyhHdVr.d.ts} +1 -1
- package/package.json +3 -3
- package/dist/chunk-AGRC7NQQ.js.map +0 -1
- package/dist/chunk-LYNNZEQD.js.map +0 -1
- package/dist/chunk-TMHJEYW7.js.map +0 -1
- package/dist/chunk-UOC7JMZO.js.map +0 -1
- package/dist/executor-7KSCEIFA.js +0 -8
- package/dist/executor-D2QMNGRJ.js +0 -8
- package/dist/executor-O5AZK7UW.js +0 -11
- package/dist/issue-YIYG4OW5.js +0 -12
- package/dist/noydb-D5SLAJ6V.js +0 -34
- package/dist/registry-BVQ5ITMF.js +0 -8
- package/dist/registry-JLP3QOLD.js +0 -8
- package/dist/vault-group-Z4KB75ZH.js.map +0 -1
- /package/dist/{chunk-OPDTLHFA.js.map → chunk-3EWA37FV.js.map} +0 -0
- /package/dist/{chunk-ZCFS7U4J.js.map → chunk-4PEFEETV.js.map} +0 -0
- /package/dist/{chunk-ZC7MNVYN.js.map → chunk-4TBBMHVC.js.map} +0 -0
- /package/dist/{chunk-SJJQKNMP.js.map → chunk-56DJ7JVK.js.map} +0 -0
- /package/dist/{chunk-C2CIIQRG.js.map → chunk-5LQG6ZO2.js.map} +0 -0
- /package/dist/{chunk-6AD5TBF2.js.map → chunk-6AJBSQU4.js.map} +0 -0
- /package/dist/{chunk-LWSD4QPT.js.map → chunk-6RR3MNMG.js.map} +0 -0
- /package/dist/{chunk-O53RIZCC.js.map → chunk-7HT2MEZ5.js.map} +0 -0
- /package/dist/{chunk-7LVRIW4G.js.map → chunk-7PS7EOCF.js.map} +0 -0
- /package/dist/{chunk-GFPR7VJS.js.map → chunk-A5ZOOZFB.js.map} +0 -0
- /package/dist/{chunk-B7GGYNKQ.js.map → chunk-AAVWKNZW.js.map} +0 -0
- /package/dist/{chunk-SZ4N3IL5.js.map → chunk-BIYRQQV6.js.map} +0 -0
- /package/dist/{chunk-CILT6V3V.js.map → chunk-BQ65SS5A.js.map} +0 -0
- /package/dist/{chunk-DLTU4M2I.js.map → chunk-COFPAMX6.js.map} +0 -0
- /package/dist/{chunk-UA6G45ME.js.map → chunk-DKO2QFSA.js.map} +0 -0
- /package/dist/{chunk-L6BYRCYB.js.map → chunk-DQU36Q7I.js.map} +0 -0
- /package/dist/{chunk-VOXMU6LB.js.map → chunk-EGD5DXFT.js.map} +0 -0
- /package/dist/{chunk-BXOUVUES.js.map → chunk-F4OJZIWQ.js.map} +0 -0
- /package/dist/{chunk-P3Z5Y2TS.js.map → chunk-FWPKCXTN.js.map} +0 -0
- /package/dist/{chunk-6BYBVRZU.js.map → chunk-HOR4R722.js.map} +0 -0
- /package/dist/{chunk-XSIFXX54.js.map → chunk-JD3OZAI4.js.map} +0 -0
- /package/dist/{chunk-RRDWXNBQ.js.map → chunk-KI6HAJWL.js.map} +0 -0
- /package/dist/{chunk-LSEW3ZZ2.js.map → chunk-L2FE64BU.js.map} +0 -0
- /package/dist/{chunk-HBAJDI2N.js.map → chunk-LX3CB26H.js.map} +0 -0
- /package/dist/{chunk-LOA2VCMS.js.map → chunk-NSCVNK5K.js.map} +0 -0
- /package/dist/{chunk-4BHFNKTP.js.map → chunk-OHVFWCJP.js.map} +0 -0
- /package/dist/{chunk-7JJE3OMJ.js.map → chunk-PE4AQGFH.js.map} +0 -0
- /package/dist/{chunk-RHQYVHFH.js.map → chunk-TS26M2SB.js.map} +0 -0
- /package/dist/{chunk-EKNUBIIQ.js.map → chunk-UWNYBOOO.js.map} +0 -0
- /package/dist/{chunk-WNRGOVLG.js.map → chunk-VU7SWWT5.js.map} +0 -0
- /package/dist/{chunk-WUG3E423.js.map → chunk-WBAYSNUQ.js.map} +0 -0
- /package/dist/{chunk-XHM2SARW.js.map → chunk-WGHU7BLI.js.map} +0 -0
- /package/dist/{chunk-5ARRXIVR.js.map → chunk-X73VS74Y.js.map} +0 -0
- /package/dist/{chunk-M45IRXDM.js.map → chunk-YHPM5D7Y.js.map} +0 -0
- /package/dist/{chunk-P4EDT5ZP.js.map → chunk-YNTBADIY.js.map} +0 -0
- /package/dist/{chunk-IUBHXEPJ.js.map → chunk-YULZKK4F.js.map} +0 -0
- /package/dist/{chunk-IEPT7HVP.js.map → chunk-Z4DO7YSI.js.map} +0 -0
- /package/dist/{chunk-HLGDYFWR.js.map → chunk-ZNQYHJXX.js.map} +0 -0
- /package/dist/{chunk-CHBXWJZQ.js.map → chunk-ZWTNWAO4.js.map} +0 -0
- /package/dist/{crypto-AJB72OKN.js.map → crypto-QXQOHMHF.js.map} +0 -0
- /package/dist/{delegation-6FCWDRUS.js.map → delegation-NIQ43IPU.js.map} +0 -0
- /package/dist/{executor-7KSCEIFA.js.map → executor-6ZDSDZ6V.js.map} +0 -0
- /package/dist/{executor-D2QMNGRJ.js.map → executor-723ZP6TH.js.map} +0 -0
- /package/dist/{executor-O5AZK7UW.js.map → executor-IDZDAFNH.js.map} +0 -0
- /package/dist/{fanout-sidecar-ZSKEQ6NI.js.map → fanout-sidecar-N6OJX6QR.js.map} +0 -0
- /package/dist/{issue-YIYG4OW5.js.map → issue-ADVS4OVP.js.map} +0 -0
- /package/dist/{ledger-5JMVF7PY.js.map → ledger-CWSE3BLF.js.map} +0 -0
- /package/dist/{noydb-D5SLAJ6V.js.map → noydb-VZ4JVW55.js.map} +0 -0
- /package/dist/{public-envelope-PFLZI5MO.js.map → public-envelope-SYHEYQ3X.js.map} +0 -0
- /package/dist/{registry-BVQ5ITMF.js.map → registry-DK5YWAAA.js.map} +0 -0
- /package/dist/{registry-JLP3QOLD.js.map → registry-IUZQVVBB.js.map} +0 -0
- /package/dist/{registry-NCY445U5.js.map → registry-XGLNADIE.js.map} +0 -0
- /package/dist/{revoke-7RLGQWZ7.js.map → revoke-ZDFKMR5E.js.map} +0 -0
- /package/dist/{signer-6JF44I4A.js.map → signer-P5D7Y72U.js.map} +0 -0
- /package/dist/{stale-UBLP3RJ3.js.map → stale-7FRJVHN6.js.map} +0 -0
|
@@ -1,20 +1,68 @@
|
|
|
1
|
+
import {
|
|
2
|
+
STATE_VAULT_NAME
|
|
3
|
+
} from "./chunk-ZC7J6ZYV.js";
|
|
1
4
|
import {
|
|
2
5
|
groupAndReduce,
|
|
3
6
|
reduceRecords
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import
|
|
7
|
+
} from "./chunk-3EWA37FV.js";
|
|
8
|
+
import {
|
|
9
|
+
readPath
|
|
10
|
+
} from "./chunk-TV3YZ35S.js";
|
|
6
11
|
import {
|
|
12
|
+
CrossShardJoinError,
|
|
7
13
|
NoAccessError,
|
|
14
|
+
ReservedVaultNameError,
|
|
8
15
|
ShardProvisioningError,
|
|
9
16
|
UnknownShardError,
|
|
10
17
|
ValidationError
|
|
11
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-535SSHBS.js";
|
|
12
19
|
|
|
13
20
|
// src/federation/classify-skip.ts
|
|
14
21
|
function classifyShardSkip(err) {
|
|
15
22
|
return err instanceof NoAccessError ? "no-grant" : "error";
|
|
16
23
|
}
|
|
17
24
|
|
|
25
|
+
// src/federation/cross-shard-join.ts
|
|
26
|
+
function coerceKey(value) {
|
|
27
|
+
if (value === null || value === void 0) return null;
|
|
28
|
+
if (typeof value === "string") return value;
|
|
29
|
+
if (typeof value === "number" || typeof value === "bigint") return String(value);
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
var warnedBroadcastKeys = /* @__PURE__ */ new Set();
|
|
33
|
+
function warnOnceBroadcastMiss(field, as, key) {
|
|
34
|
+
const dedup = `${field}\u2192${as}:${key}`;
|
|
35
|
+
if (warnedBroadcastKeys.has(dedup)) return;
|
|
36
|
+
warnedBroadcastKeys.add(dedup);
|
|
37
|
+
console.warn(
|
|
38
|
+
`[noy-db] broadcastJoin: no "${as}" dimension row for ${field}="${key}". Attaching null. Use mode: 'cascade' to silence.`
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
async function applyBroadcastLegs(rows, legs) {
|
|
42
|
+
if (legs.length === 0) return [...rows];
|
|
43
|
+
const indexes = [];
|
|
44
|
+
for (const leg of legs) {
|
|
45
|
+
const map = /* @__PURE__ */ new Map();
|
|
46
|
+
for (const rec of await leg.from.list()) {
|
|
47
|
+
const k = coerceKey(readPath(rec, leg.on));
|
|
48
|
+
if (k !== null && !map.has(k)) map.set(k, rec);
|
|
49
|
+
}
|
|
50
|
+
indexes.push({ leg, map });
|
|
51
|
+
}
|
|
52
|
+
return rows.map((row) => {
|
|
53
|
+
const out = { ...row };
|
|
54
|
+
for (const { leg, map } of indexes) {
|
|
55
|
+
const key = coerceKey(readPath(row, leg.field));
|
|
56
|
+
const match = key === null ? null : map.get(key) ?? null;
|
|
57
|
+
if (match === null && leg.mode === "warn") {
|
|
58
|
+
warnOnceBroadcastMiss(leg.field, leg.as, key ?? "<null>");
|
|
59
|
+
}
|
|
60
|
+
out[leg.as] = match;
|
|
61
|
+
}
|
|
62
|
+
return out;
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
|
|
18
66
|
// src/federation/cross-vault-live.ts
|
|
19
67
|
var CrossVaultLive = class {
|
|
20
68
|
snapshot;
|
|
@@ -202,6 +250,9 @@ function assertSafePartitionKey(partitionKey) {
|
|
|
202
250
|
if (partitionKey.length === 0) {
|
|
203
251
|
throw new ValidationError("partitionKey must be a non-empty string");
|
|
204
252
|
}
|
|
253
|
+
if (partitionKey === STATE_VAULT_NAME) {
|
|
254
|
+
throw new ReservedVaultNameError(partitionKey);
|
|
255
|
+
}
|
|
205
256
|
if (!SAFE_PARTITION_KEY.test(partitionKey)) {
|
|
206
257
|
throw new ValidationError(
|
|
207
258
|
`partitionKey "${partitionKey}" contains characters outside [A-Za-z0-9._-]. Map your records to a store-safe key in sharding.keyOf.`
|
|
@@ -231,15 +282,38 @@ var VaultGroup = class {
|
|
|
231
282
|
registry;
|
|
232
283
|
sharding;
|
|
233
284
|
template;
|
|
285
|
+
/** @internal — set when the group is managed (no explicit registry). */
|
|
286
|
+
stateVault;
|
|
287
|
+
/** @internal */
|
|
288
|
+
_attachStateVault(sv) {
|
|
289
|
+
this.stateVault = sv;
|
|
290
|
+
}
|
|
234
291
|
/** Deterministic vault name for a partition key, namespaced by the group. */
|
|
235
292
|
shardVaultId(partitionKey) {
|
|
236
293
|
assertSafePartitionKey(partitionKey);
|
|
237
294
|
return `${this.name}${SHARD_SEPARATOR}${partitionKey}`;
|
|
238
295
|
}
|
|
239
|
-
/**
|
|
296
|
+
/**
|
|
297
|
+
* @internal — group-qualified registry record key (avoids cross-group key
|
|
298
|
+
* collisions). Identical to the shard vault id by design — the registry row
|
|
299
|
+
* for a shard is keyed by that shard's vault id — so it delegates to
|
|
300
|
+
* `shardVaultId`, reusing its partition-key validation.
|
|
301
|
+
*/
|
|
302
|
+
registryId(partitionKey) {
|
|
303
|
+
return this.shardVaultId(partitionKey);
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* Registry rows for THIS group (hydrates the registry collection first).
|
|
307
|
+
* The registry may be shared across groups (the auto-wired StateManagement
|
|
308
|
+
* vault holds one `vaultRegistry` for the whole instance), so rows are
|
|
309
|
+
* filtered by `group` — without this, a group's fan-out reads would leak
|
|
310
|
+
* across into other groups' shards. Mirrors the `${group}--` scoping that
|
|
311
|
+
* `liveBinding().isRelevant` already applies to the reactive path.
|
|
312
|
+
*/
|
|
240
313
|
async allRows() {
|
|
241
314
|
await this.registry.list();
|
|
242
|
-
|
|
315
|
+
const rows = this.registry.query().toArray();
|
|
316
|
+
return rows.filter((r) => r.group === this.name);
|
|
243
317
|
}
|
|
244
318
|
/** Open an existing shard and apply the template. */
|
|
245
319
|
async openShard(partitionKey) {
|
|
@@ -257,19 +331,32 @@ var VaultGroup = class {
|
|
|
257
331
|
*/
|
|
258
332
|
async createShard(partitionKey) {
|
|
259
333
|
const vaultId = this.shardVaultId(partitionKey);
|
|
260
|
-
const row = await this.registry.get(partitionKey);
|
|
334
|
+
const row = await this.registry.get(this.registryId(partitionKey));
|
|
261
335
|
const provisioned = await this.db._shardVaultProvisioned(vaultId);
|
|
262
336
|
if (row && !provisioned) throw new ShardProvisioningError(vaultId, partitionKey);
|
|
263
337
|
if (row && provisioned) return this.openShard(partitionKey);
|
|
264
338
|
const vault = await this.db.openVault(vaultId);
|
|
265
339
|
this.template.configure(vault);
|
|
266
|
-
await this.registry.put(partitionKey, {
|
|
340
|
+
await this.registry.put(this.registryId(partitionKey), {
|
|
267
341
|
vaultId,
|
|
268
342
|
partitionKey,
|
|
269
343
|
templateName: this.sharding.vaultTemplate,
|
|
270
344
|
schemaVersion: this.template.version,
|
|
271
|
-
createdAt: Date.now()
|
|
345
|
+
createdAt: Date.now(),
|
|
346
|
+
group: this.name
|
|
272
347
|
});
|
|
348
|
+
if (this.stateVault) {
|
|
349
|
+
try {
|
|
350
|
+
await this.stateVault.appendEvent({
|
|
351
|
+
type: "shard-created",
|
|
352
|
+
group: this.name,
|
|
353
|
+
vaultId,
|
|
354
|
+
templateName: this.sharding.vaultTemplate,
|
|
355
|
+
version: this.template.version
|
|
356
|
+
});
|
|
357
|
+
} catch {
|
|
358
|
+
}
|
|
359
|
+
}
|
|
273
360
|
return vault;
|
|
274
361
|
}
|
|
275
362
|
/**
|
|
@@ -279,7 +366,7 @@ var VaultGroup = class {
|
|
|
279
366
|
*/
|
|
280
367
|
async shard(partitionKey) {
|
|
281
368
|
const vaultId = this.shardVaultId(partitionKey);
|
|
282
|
-
const row = await this.registry.get(partitionKey);
|
|
369
|
+
const row = await this.registry.get(this.registryId(partitionKey));
|
|
283
370
|
if (!row) throw new UnknownShardError(partitionKey, this.name);
|
|
284
371
|
const provisioned = await this.db._shardVaultProvisioned(vaultId);
|
|
285
372
|
if (!provisioned) throw new ShardProvisioningError(vaultId, partitionKey);
|
|
@@ -318,7 +405,7 @@ var ShardedCollection = class {
|
|
|
318
405
|
/** Route a write to the shard owning `keyOf(record)`. */
|
|
319
406
|
async put(id, record) {
|
|
320
407
|
const key = this.group.sharding.keyOf(record);
|
|
321
|
-
const row = await this.group.registry.get(key);
|
|
408
|
+
const row = await this.group.registry.get(this.group.registryId(key));
|
|
322
409
|
let vault;
|
|
323
410
|
if (!row) {
|
|
324
411
|
if (this.group.sharding.autoCreate === false) {
|
|
@@ -336,31 +423,89 @@ var ShardedCollection = class {
|
|
|
336
423
|
}
|
|
337
424
|
};
|
|
338
425
|
var ShardedQuery = class _ShardedQuery {
|
|
339
|
-
constructor(group, collectionName, clauses) {
|
|
426
|
+
constructor(group, collectionName, clauses, coPartitionedLegs = [], broadcastLegs = []) {
|
|
340
427
|
this.group = group;
|
|
341
428
|
this.collectionName = collectionName;
|
|
342
429
|
this.clauses = clauses;
|
|
430
|
+
this.coPartitionedLegs = coPartitionedLegs;
|
|
431
|
+
this.broadcastLegs = broadcastLegs;
|
|
343
432
|
}
|
|
344
433
|
group;
|
|
345
434
|
collectionName;
|
|
346
435
|
clauses;
|
|
436
|
+
coPartitionedLegs;
|
|
437
|
+
broadcastLegs;
|
|
347
438
|
where(field, op, value) {
|
|
348
|
-
return new _ShardedQuery(
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
439
|
+
return new _ShardedQuery(
|
|
440
|
+
this.group,
|
|
441
|
+
this.collectionName,
|
|
442
|
+
[...this.clauses, { field, op, value }],
|
|
443
|
+
this.coPartitionedLegs,
|
|
444
|
+
this.broadcastLegs
|
|
445
|
+
);
|
|
446
|
+
}
|
|
447
|
+
/** Co-partitioned join: each shard joins its own same-vault right collection (resolved via ref()), then union. */
|
|
448
|
+
crossShardJoin(field, opts) {
|
|
449
|
+
const leg = { field, as: opts.as, maxRows: opts.maxRows, strategy: opts.strategy };
|
|
450
|
+
return new _ShardedQuery(
|
|
451
|
+
this.group,
|
|
452
|
+
this.collectionName,
|
|
453
|
+
this.clauses,
|
|
454
|
+
[...this.coPartitionedLegs, leg],
|
|
455
|
+
this.broadcastLegs
|
|
456
|
+
);
|
|
457
|
+
}
|
|
458
|
+
/** Broadcast dimension join: enrich every merged row from a single shared collection. */
|
|
459
|
+
broadcastJoin(field, opts) {
|
|
460
|
+
const leg = {
|
|
461
|
+
field,
|
|
462
|
+
as: opts.as,
|
|
463
|
+
from: opts.from,
|
|
464
|
+
on: opts.on ?? "id",
|
|
465
|
+
mode: opts.mode ?? "warn"
|
|
466
|
+
};
|
|
467
|
+
return new _ShardedQuery(
|
|
468
|
+
this.group,
|
|
469
|
+
this.collectionName,
|
|
470
|
+
this.clauses,
|
|
471
|
+
this.coPartitionedLegs,
|
|
472
|
+
[...this.broadcastLegs, leg]
|
|
473
|
+
);
|
|
352
474
|
}
|
|
353
475
|
/** @internal — fan out the where-filtered records across eligible shards. */
|
|
354
476
|
async fanoutRecords(options = {}) {
|
|
355
477
|
const { eligible, skipped } = await this.group.resolveEligible(options);
|
|
478
|
+
const probeRow = eligible[0];
|
|
479
|
+
if (this.coPartitionedLegs.length > 0 && probeRow) {
|
|
480
|
+
const probe = await this.group.openShard(probeRow.partitionKey);
|
|
481
|
+
this.group.template.configure(probe);
|
|
482
|
+
for (const leg of this.coPartitionedLegs) {
|
|
483
|
+
if (!probe.resolveRef(this.collectionName, leg.field)) {
|
|
484
|
+
throw new CrossShardJoinError(
|
|
485
|
+
`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.`
|
|
486
|
+
);
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
}
|
|
356
490
|
const across = await this.group.db.queryAcross(
|
|
357
491
|
eligible.map((r) => r.vaultId),
|
|
358
492
|
async (vault) => {
|
|
359
493
|
this.group.template.configure(vault);
|
|
360
494
|
const coll = vault.collection(this.collectionName);
|
|
361
495
|
await coll.list();
|
|
496
|
+
for (const leg of this.coPartitionedLegs) {
|
|
497
|
+
const desc = vault.resolveRef(this.collectionName, leg.field);
|
|
498
|
+
if (desc) await vault.collection(desc.target).list();
|
|
499
|
+
}
|
|
362
500
|
let q = coll.query();
|
|
363
501
|
for (const c of this.clauses) q = q.where(c.field, c.op, c.value);
|
|
502
|
+
for (const leg of this.coPartitionedLegs) {
|
|
503
|
+
q = q.join(leg.field, {
|
|
504
|
+
as: leg.as,
|
|
505
|
+
...leg.maxRows !== void 0 ? { maxRows: leg.maxRows } : {},
|
|
506
|
+
...leg.strategy ? { strategy: leg.strategy } : {}
|
|
507
|
+
});
|
|
508
|
+
}
|
|
364
509
|
return q.toArray();
|
|
365
510
|
},
|
|
366
511
|
{ concurrency: options.concurrency ?? 1, create: false }
|
|
@@ -372,10 +517,11 @@ var ShardedQuery = class _ShardedQuery {
|
|
|
372
517
|
}
|
|
373
518
|
return { records: results, skippedVaults: skipped };
|
|
374
519
|
}
|
|
375
|
-
/** Fan out across eligible shards
|
|
520
|
+
/** Fan out across eligible shards, merge, then apply any broadcast dimension legs. */
|
|
376
521
|
async toArray(options = {}) {
|
|
377
522
|
const { records, skippedVaults } = await this.fanoutRecords(options);
|
|
378
|
-
|
|
523
|
+
const results = await applyBroadcastLegs(records, this.broadcastLegs);
|
|
524
|
+
return { results, skippedVaults };
|
|
379
525
|
}
|
|
380
526
|
/** @internal — build the change-subscription + relevance binding for this query's group+collection. */
|
|
381
527
|
liveBinding() {
|
|
@@ -389,8 +535,17 @@ var ShardedQuery = class _ShardedQuery {
|
|
|
389
535
|
isRelevant: (e) => e.collection === collectionName && e.vault.startsWith(`${group.name}--`)
|
|
390
536
|
};
|
|
391
537
|
}
|
|
538
|
+
/** @internal — joined queries don't support reactive/aggregate surfaces in v1. */
|
|
539
|
+
assertNoJoinLegs(surface) {
|
|
540
|
+
if (this.coPartitionedLegs.length || this.broadcastLegs.length) {
|
|
541
|
+
throw new CrossShardJoinError(
|
|
542
|
+
`${surface}() is not supported on a ShardedQuery with crossShardJoin/broadcastJoin legs in v1. Use toArray() for joined cross-shard queries.`
|
|
543
|
+
);
|
|
544
|
+
}
|
|
545
|
+
}
|
|
392
546
|
/** Returns a reactive cross-shard live query — a facade over CrossVaultLive. */
|
|
393
547
|
live(options = {}) {
|
|
548
|
+
this.assertNoJoinLegs("live");
|
|
394
549
|
const bind = this.liveBinding();
|
|
395
550
|
const core = new CrossVaultLive({
|
|
396
551
|
...bind,
|
|
@@ -418,10 +573,12 @@ var ShardedQuery = class _ShardedQuery {
|
|
|
418
573
|
}
|
|
419
574
|
/** One-shot distributed aggregate — central reduce over all shard records. */
|
|
420
575
|
aggregate(spec) {
|
|
576
|
+
this.assertNoJoinLegs("aggregate");
|
|
421
577
|
return new CrossVaultAggregation(this, spec, this.liveBinding());
|
|
422
578
|
}
|
|
423
579
|
/** Begin a grouped cross-shard aggregate. */
|
|
424
580
|
groupBy(field) {
|
|
581
|
+
this.assertNoJoinLegs("groupBy");
|
|
425
582
|
return new ShardedGroupedQuery(this, field);
|
|
426
583
|
}
|
|
427
584
|
};
|
|
@@ -447,4 +604,4 @@ export {
|
|
|
447
604
|
ShardedQuery,
|
|
448
605
|
VaultGroup
|
|
449
606
|
};
|
|
450
|
-
//# sourceMappingURL=vault-group-
|
|
607
|
+
//# sourceMappingURL=vault-group-W7QC4UYW.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/federation/classify-skip.ts","../src/federation/cross-shard-join.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 * crossShardJoin — co-partitioned + broadcast dimension join for\n * ShardedQuery. Spec:\n * docs/superpowers/specs/2026-06-09-cross-shard-join-design.md.\n *\n * This module owns the BROADCAST half (central, post-merge map-attach)\n * and the leg type definitions. The CO-PARTITIONED half is threaded\n * into the existing intra-vault `.join()` from vault-group.ts — see\n * ShardedQuery.fanoutRecords. join.ts is deliberately untouched.\n */\nimport { readPath } from '../query/predicate.js'\nimport type { JoinStrategy } from '../query/join.js'\n\n/** Public options for `ShardedQuery.crossShardJoin`. */\nexport interface CrossShardJoinOptions {\n /** Alias key under which the joined same-shard record attaches. */\n readonly as: string\n /** Per-shard row ceiling override (default DEFAULT_JOIN_MAX_ROWS). */\n readonly maxRows?: number\n /** Planner strategy override, passed through to intra-vault `.join()`. */\n readonly strategy?: JoinStrategy\n}\n\n/**\n * Minimal structural shape of a broadcast dimension source. A\n * `Collection` satisfies this natively: `list()` hydrates and returns\n * the decoded records. Kept as a one-method interface so plain test\n * sources are trivial to construct.\n */\nexport interface BroadcastSource {\n list(): Promise<readonly unknown[]>\n}\n\n/** Public options for `ShardedQuery.broadcastJoin`. */\nexport interface BroadcastJoinOptions {\n /** Alias key under which the dimension record attaches. */\n readonly as: string\n /** The shared dimension collection (an opened handle in another vault). */\n readonly from: BroadcastSource\n /** Right-side key to match `field` against. Default 'id'. */\n readonly on?: string\n /** Miss behavior. 'warn' (default) attaches null + one-shot warning; 'cascade' is silent. */\n readonly mode?: 'warn' | 'cascade'\n}\n\n/** Internal co-partitioned leg carried on ShardedQuery. */\nexport interface CoPartitionedLeg {\n readonly field: string\n readonly as: string\n readonly maxRows: number | undefined\n readonly strategy: JoinStrategy | undefined\n}\n\n/** Internal broadcast leg carried on ShardedQuery. */\nexport interface BroadcastLeg {\n readonly field: string\n readonly as: string\n readonly from: BroadcastSource\n readonly on: string\n readonly mode: 'warn' | 'cascade'\n}\n\n/**\n * Coerce an unknown key value into a lookup string. Mirrors join.ts's\n * private `coerceRefKey` (string → string; number/bigint → String;\n * else null) — re-implemented locally to keep join.ts literally\n * untouched.\n */\nfunction coerceKey(value: unknown): string | null {\n if (value === null || value === undefined) return null\n if (typeof value === 'string') return value\n if (typeof value === 'number' || typeof value === 'bigint') return String(value)\n return null\n}\n\n/** One-shot warn dedup for broadcast misses, keyed by `field→as`. */\nconst warnedBroadcastKeys = new Set<string>()\nfunction warnOnceBroadcastMiss(field: string, as: string, key: string): void {\n const dedup = `${field}→${as}:${key}`\n if (warnedBroadcastKeys.has(dedup)) return\n warnedBroadcastKeys.add(dedup)\n console.warn(\n `[noy-db] broadcastJoin: no \"${as}\" dimension row for ${field}=\"${key}\". ` +\n `Attaching null. Use mode: 'cascade' to silence.`,\n )\n}\n\n/** Test-only reset for the broadcast warn dedup set. */\nexport function resetBroadcastWarnings(): void {\n warnedBroadcastKeys.clear()\n}\n\n/**\n * Apply every broadcast leg to a merged row set, centrally. Each leg's\n * source is snapshotted ONCE, indexed by its `on` key, then every row\n * gets `{ [as]: match ?? null }`. Returns fresh top-level objects.\n */\nexport async function applyBroadcastLegs(\n rows: readonly unknown[],\n legs: readonly BroadcastLeg[],\n): Promise<unknown[]> {\n if (legs.length === 0) return [...rows]\n\n // Build one index per leg (list() once per source).\n const indexes: { leg: BroadcastLeg; map: Map<string, unknown> }[] = []\n for (const leg of legs) {\n const map = new Map<string, unknown>()\n for (const rec of await leg.from.list()) {\n const k = coerceKey(readPath(rec, leg.on))\n if (k !== null && !map.has(k)) map.set(k, rec)\n }\n indexes.push({ leg, map })\n }\n\n return rows.map((row) => {\n const out = { ...(row as Record<string, unknown>) }\n for (const { leg, map } of indexes) {\n const key = coerceKey(readPath(row, leg.field))\n const match = key === null ? null : map.get(key) ?? null\n if (match === null && leg.mode === 'warn') {\n warnOnceBroadcastMiss(leg.field, leg.as, key ?? '<null>')\n }\n out[leg.as] = match\n }\n return out\n })\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 { CrossShardJoinError, ReservedVaultNameError, ShardProvisioningError, UnknownShardError, ValidationError } from '../errors.js'\nimport { STATE_VAULT_NAME } from './constants.js'\nimport { classifyShardSkip } from './classify-skip.js'\nimport { applyBroadcastLegs } from './cross-shard-join.js'\nimport type { CoPartitionedLeg, BroadcastLeg, CrossShardJoinOptions, BroadcastJoinOptions } from './cross-shard-join.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 private readonly coPartitionedLegs: readonly CoPartitionedLeg[] = [],\n private readonly broadcastLegs: readonly BroadcastLeg[] = [],\n ) {}\n\n where(field: string, op: WhereClause['op'], value: unknown): ShardedQuery<T, R> {\n return new ShardedQuery<T, R>(\n this.group,\n this.collectionName,\n [...this.clauses, { field, op, value }],\n this.coPartitionedLegs,\n this.broadcastLegs,\n )\n }\n\n /** Co-partitioned join: each shard joins its own same-vault right collection (resolved via ref()), then union. */\n crossShardJoin(field: string, opts: CrossShardJoinOptions): ShardedQuery<T, R> {\n const leg: CoPartitionedLeg = { field, as: opts.as, maxRows: opts.maxRows, strategy: opts.strategy }\n return new ShardedQuery<T, R>(\n this.group,\n this.collectionName,\n this.clauses,\n [...this.coPartitionedLegs, leg],\n this.broadcastLegs,\n )\n }\n\n /** Broadcast dimension join: enrich every merged row from a single shared collection. */\n broadcastJoin(field: string, opts: BroadcastJoinOptions): ShardedQuery<T, R> {\n const leg: BroadcastLeg = {\n field,\n as: opts.as,\n from: opts.from,\n on: opts.on ?? 'id',\n mode: opts.mode ?? 'warn',\n }\n return new ShardedQuery<T, R>(\n this.group,\n this.collectionName,\n this.clauses,\n this.coPartitionedLegs,\n [...this.broadcastLegs, leg],\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 // Deterministic pre-check: an undeclared co-partitioned join ref fails\n // identically on every shard, so surface it as ONE CrossShardJoinError\n // rather than N identical skips. Probe the first eligible shard.\n const probeRow = eligible[0]\n if (this.coPartitionedLegs.length > 0 && probeRow) {\n const probe = await this.group.openShard(probeRow.partitionKey)\n this.group.template.configure(probe)\n for (const leg of this.coPartitionedLegs) {\n if (!probe.resolveRef(this.collectionName, leg.field)) {\n throw new CrossShardJoinError(\n `crossShardJoin(\"${leg.field}\"): no ref() declared for \"${leg.field}\" on ` +\n `collection \"${this.collectionName}\" in template \"${this.group.sharding.vaultTemplate}\". ` +\n `Add refs: { ${leg.field}: ref('<target>') } to the template's collection options.`,\n )\n }\n }\n }\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 // Hydrate each co-partitioned join target — resolveSource reads the\n // in-memory cache, so an unopened right collection would join to an\n // empty snapshot (every row → null).\n for (const leg of this.coPartitionedLegs) {\n const desc = vault.resolveRef(this.collectionName, leg.field)\n if (desc) await vault.collection(desc.target).list()\n }\n let q = coll.query()\n for (const c of this.clauses) q = q.where(c.field, c.op, c.value)\n for (const leg of this.coPartitionedLegs) {\n q = q.join(leg.field, {\n as: leg.as,\n ...(leg.maxRows !== undefined ? { maxRows: leg.maxRows } : {}),\n ...(leg.strategy ? { strategy: leg.strategy } : {}),\n })\n }\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, merge, then apply any broadcast dimension legs. */\n async toArray(options: FanoutQueryOptions = {}): Promise<FanoutResult<R>> {\n const { records, skippedVaults } = await this.fanoutRecords(options)\n const results = (await applyBroadcastLegs(records, this.broadcastLegs)) as R[]\n return { results, 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 /** @internal — joined queries don't support reactive/aggregate surfaces in v1. */\n private assertNoJoinLegs(surface: string): void {\n if (this.coPartitionedLegs.length || this.broadcastLegs.length) {\n throw new CrossShardJoinError(\n `${surface}() is not supported on a ShardedQuery with crossShardJoin/broadcastJoin ` +\n `legs in v1. Use toArray() for joined cross-shard queries.`,\n )\n }\n }\n\n /** Returns a reactive cross-shard live query — a facade over CrossVaultLive. */\n live(options: LiveQueryOptions = {}): CrossVaultLiveQuery<R> {\n this.assertNoJoinLegs('live')\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 this.assertNoJoinLegs('aggregate')\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 this.assertNoJoinLegs('groupBy')\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-V5R2-pd4.cjs';
|
|
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-BFHQUjdy.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Register a deterministic derivation: one source collection → one or
|
package/dist/{with-materialized-view-CzRg1Dpr.d.cts → with-materialized-view-DgQcAjYv.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-V5R2-pd4.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-BFHQUjdy.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-V5R2-pd4.cjs';
|
|
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-BFHQUjdy.js';
|
|
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.14",
|
|
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.14"
|
|
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.14"
|
|
280
280
|
},
|
|
281
281
|
"peerDependencies": {
|
|
282
282
|
"zod-to-json-schema": "^3.25.0"
|