@noy-db/hub 0.1.0-pre.9 → 0.2.0-pre.2
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 +91 -36
- 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 +16 -9
- package/dist/aggregate/index.js.map +1 -1
- package/dist/attestation/index.cjs +305 -0
- package/dist/attestation/index.cjs.map +1 -0
- package/dist/attestation/index.d.cts +52 -0
- package/dist/attestation/index.d.ts +52 -0
- package/dist/attestation/index.js +36 -0
- package/dist/attestation/index.js.map +1 -0
- package/dist/blobs/index.cjs.map +1 -1
- package/dist/blobs/index.d.cts +7 -6
- package/dist/blobs/index.d.ts +7 -6
- package/dist/blobs/index.js +10 -8
- package/dist/blobs/index.js.map +1 -1
- package/dist/bundle/index.cjs +16923 -60
- package/dist/bundle/index.cjs.map +1 -1
- package/dist/bundle/index.d.cts +175 -6
- package/dist/bundle/index.d.ts +175 -6
- package/dist/bundle/index.js +543 -4
- package/dist/bundle/index.js.map +1 -1
- package/dist/{chunk-PTVMYYON.js → chunk-243PNUA6.js} +3 -3
- package/dist/{chunk-MR4424N3.js → chunk-2PAQNPE3.js} +2 -2
- package/dist/chunk-3QAKZ37R.js +83 -0
- package/dist/chunk-3QAKZ37R.js.map +1 -0
- package/dist/chunk-3S4BJX25.js +36 -0
- package/dist/chunk-3S4BJX25.js.map +1 -0
- package/dist/chunk-3XHOCQK4.js +118 -0
- package/dist/chunk-3XHOCQK4.js.map +1 -0
- package/dist/{chunk-AVVPZ4BC.js → chunk-3Y53S2SA.js} +4 -4
- package/dist/chunk-3Z2TPHC4.js +291 -0
- package/dist/chunk-3Z2TPHC4.js.map +1 -0
- package/dist/chunk-4HIL6AHQ.js +57 -0
- package/dist/chunk-4HIL6AHQ.js.map +1 -0
- package/dist/chunk-5ZGZ6HIZ.js +100 -0
- package/dist/chunk-5ZGZ6HIZ.js.map +1 -0
- package/dist/{chunk-ZFKD4QMV.js → chunk-7BRE6EUA.js} +3 -3
- package/dist/chunk-7BUTTVMR.js +34 -0
- package/dist/chunk-7BUTTVMR.js.map +1 -0
- package/dist/{chunk-VQBTTTUN.js → chunk-7Q5PLD5C.js} +4 -4
- package/dist/{chunk-VQBTTTUN.js.map → chunk-7Q5PLD5C.js.map} +1 -1
- package/dist/{chunk-QAVUREFT.js → chunk-7Z23ZFLV.js} +12 -6
- package/dist/chunk-7Z23ZFLV.js.map +1 -0
- package/dist/chunk-AHPFONIL.js +59 -0
- package/dist/chunk-AHPFONIL.js.map +1 -0
- package/dist/chunk-CXSCDO5T.js +51 -0
- package/dist/chunk-CXSCDO5T.js.map +1 -0
- package/dist/chunk-E535SAN4.js +8834 -0
- package/dist/chunk-E535SAN4.js.map +1 -0
- package/dist/chunk-EUYOGYGV.js +830 -0
- package/dist/chunk-EUYOGYGV.js.map +1 -0
- package/dist/chunk-FAQVNJD4.js +61 -0
- package/dist/chunk-FAQVNJD4.js.map +1 -0
- package/dist/{chunk-SCZXXXU4.js → chunk-G6FRSBKK.js} +7 -32
- package/dist/chunk-G6FRSBKK.js.map +1 -0
- package/dist/chunk-GIV6DWBG.js +79 -0
- package/dist/chunk-GIV6DWBG.js.map +1 -0
- package/dist/chunk-HXJXPZRE.js +73 -0
- package/dist/chunk-HXJXPZRE.js.map +1 -0
- package/dist/{chunk-GOUT6DND.js → chunk-J4KLMEUL.js} +173 -91
- package/dist/chunk-J4KLMEUL.js.map +1 -0
- package/dist/{chunk-2CSJGFCB.js → chunk-JYQTXEIO.js} +6 -229
- package/dist/chunk-JYQTXEIO.js.map +1 -0
- package/dist/{chunk-MDDTIZUO.js → chunk-LRAZDV5X.js} +7 -119
- package/dist/chunk-LRAZDV5X.js.map +1 -0
- package/dist/{chunk-M5INGEFC.js → chunk-MRIBLZL3.js} +3 -1
- package/dist/chunk-MRIBLZL3.js.map +1 -0
- package/dist/{chunk-USKYUS74.js → chunk-MUWOSVEP.js} +2 -2
- package/dist/{chunk-4PWAI7Q4.js → chunk-NWZ3I6R6.js} +5 -5
- package/dist/chunk-OVZDFEOR.js +124 -0
- package/dist/chunk-OVZDFEOR.js.map +1 -0
- package/dist/chunk-PEULZC6M.js +118 -0
- package/dist/chunk-PEULZC6M.js.map +1 -0
- package/dist/chunk-PFSNOPBQ.js +233 -0
- package/dist/chunk-PFSNOPBQ.js.map +1 -0
- package/dist/chunk-PLI5TV7N.js +53 -0
- package/dist/chunk-PLI5TV7N.js.map +1 -0
- package/dist/{chunk-WDM5XGGS.js → chunk-Q6W2CMEJ.js} +181 -11
- package/dist/chunk-Q6W2CMEJ.js.map +1 -0
- package/dist/{chunk-QGZRWRSL.js → chunk-QPEXPHJR.js} +4 -4
- package/dist/{chunk-R36SIKES.js → chunk-QXQRKXCU.js} +2 -2
- package/dist/chunk-RTZVQAJ7.js +82 -0
- package/dist/chunk-RTZVQAJ7.js.map +1 -0
- package/dist/chunk-TBKOGSYR.js +296 -0
- package/dist/chunk-TBKOGSYR.js.map +1 -0
- package/dist/chunk-UMLVJTYV.js +20 -0
- package/dist/chunk-UMLVJTYV.js.map +1 -0
- package/dist/chunk-UND4XIB6.js +251 -0
- package/dist/chunk-UND4XIB6.js.map +1 -0
- package/dist/chunk-VCGTOS2A.js +795 -0
- package/dist/chunk-VCGTOS2A.js.map +1 -0
- package/dist/chunk-VE6YVP32.js +19 -0
- package/dist/chunk-VE6YVP32.js.map +1 -0
- package/dist/{chunk-M62XNWRA.js → chunk-VK5EER6C.js} +2 -2
- package/dist/{chunk-NXFEYLVG.js → chunk-VPSUZLOJ.js} +4 -3
- package/dist/{chunk-NXFEYLVG.js.map → chunk-VPSUZLOJ.js.map} +1 -1
- package/dist/{chunk-TDR6T5CJ.js → chunk-VRBCTEKQ.js} +91 -132
- package/dist/chunk-VRBCTEKQ.js.map +1 -0
- package/dist/{chunk-ACLDOTNQ.js → chunk-W3XXT26A.js} +303 -3
- package/dist/chunk-W3XXT26A.js.map +1 -0
- package/dist/{chunk-CIMZBAZB.js → chunk-XG3PTSCD.js} +1 -1
- package/dist/chunk-XG3PTSCD.js.map +1 -0
- package/dist/chunk-Y2RKOPNC.js +145 -0
- package/dist/chunk-Y2RKOPNC.js.map +1 -0
- package/dist/{chunk-NPC4LFV5.js → chunk-YMYK7US4.js} +2 -2
- package/dist/{chunk-RKJ6OL7K.js → chunk-YS3POABP.js} +1 -1
- package/dist/chunk-YS3POABP.js.map +1 -0
- package/dist/chunk-YTXSFG3C.js +179 -0
- package/dist/chunk-YTXSFG3C.js.map +1 -0
- package/dist/consent/index.cjs.map +1 -1
- package/dist/consent/index.d.cts +7 -6
- package/dist/consent/index.d.ts +7 -6
- package/dist/consent/index.js +3 -3
- package/dist/{crypto-IVKU7YTT.js → crypto-5ZDIY3NG.js} +3 -3
- package/dist/{delegation-2DBS2EOH.js → delegation-QYXZW25W.js} +5 -4
- package/dist/derivations/index.cjs +351 -0
- package/dist/derivations/index.cjs.map +1 -0
- package/dist/derivations/index.d.cts +72 -0
- package/dist/derivations/index.d.ts +72 -0
- package/dist/derivations/index.js +27 -0
- package/dist/{dev-unlock-Da1B0TIK.d.cts → dev-unlock-DQCNDfFp.d.cts} +1 -1
- package/dist/{dev-unlock-BdPp68qn.d.ts → dev-unlock-utkybTKb.d.ts} +1 -1
- package/dist/executor-AS2IDHKZ.js +11 -0
- package/dist/executor-HLXFXNFM.js +8 -0
- package/dist/executor-HLXFXNFM.js.map +1 -0
- package/dist/executor-HN6YBHZ5.js +8 -0
- package/dist/executor-HN6YBHZ5.js.map +1 -0
- package/dist/fanout-sidecar-VJ52RIEY.js +51 -0
- package/dist/fanout-sidecar-VJ52RIEY.js.map +1 -0
- package/dist/guards/index.cjs +315 -0
- package/dist/guards/index.cjs.map +1 -0
- package/dist/guards/index.d.cts +31 -0
- package/dist/guards/index.d.ts +31 -0
- package/dist/guards/index.js +29 -0
- package/dist/guards/index.js.map +1 -0
- package/dist/{hash-lsoL3eEW.d.ts → hash-DcoYWfJ_.d.ts} +1 -1
- package/dist/{hash-BEfzPKwo.d.cts → hash-jDowCrK2.d.cts} +1 -1
- package/dist/history/index.cjs +8 -1
- package/dist/history/index.cjs.map +1 -1
- package/dist/history/index.d.cts +8 -7
- package/dist/history/index.d.ts +8 -7
- package/dist/history/index.js +6 -6
- package/dist/i18n/index.cjs +81 -0
- package/dist/i18n/index.cjs.map +1 -1
- package/dist/i18n/index.d.cts +7 -6
- package/dist/i18n/index.d.ts +7 -6
- package/dist/i18n/index.js +27 -12
- package/dist/i18n/index.js.map +1 -1
- package/dist/{index-6xNpPsxR.d.cts → index-BCKdioeh.d.ts} +331 -5
- package/dist/{index-DJTf9yxn.d.ts → index-BMjrzNZr.d.cts} +331 -5
- package/dist/index.cjs +6065 -959
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +208 -16
- package/dist/index.d.ts +208 -16
- package/dist/index.js +242 -7392
- package/dist/index.js.map +1 -1
- package/dist/indexing/index.cjs +2 -0
- package/dist/indexing/index.cjs.map +1 -1
- package/dist/indexing/index.d.cts +3 -3
- package/dist/indexing/index.d.ts +3 -3
- package/dist/indexing/index.js +4 -4
- package/dist/issue-ORP37MVW.js +12 -0
- package/dist/issue-ORP37MVW.js.map +1 -0
- package/dist/{lazy-builder-CZVLKh0Z.d.cts → lazy-builder-C-rPfWG0.d.cts} +1 -1
- package/dist/{lazy-builder-BwEoBQZ9.d.ts → lazy-builder-Rpd-V3jP.d.ts} +1 -1
- package/dist/{ledger-QZTTHQAQ.js → ledger-3IU5GMXA.js} +6 -6
- package/dist/ledger-3IU5GMXA.js.map +1 -0
- package/dist/materialized-views/index.cjs +837 -0
- package/dist/materialized-views/index.cjs.map +1 -0
- package/dist/materialized-views/index.d.cts +184 -0
- package/dist/materialized-views/index.d.ts +184 -0
- package/dist/materialized-views/index.js +45 -0
- package/dist/materialized-views/index.js.map +1 -0
- package/dist/noydb-5H3C24GG.js +34 -0
- package/dist/noydb-5H3C24GG.js.map +1 -0
- package/dist/overlay-views/index.cjs +359 -0
- package/dist/overlay-views/index.cjs.map +1 -0
- package/dist/overlay-views/index.d.cts +82 -0
- package/dist/overlay-views/index.d.ts +82 -0
- package/dist/overlay-views/index.js +25 -0
- package/dist/overlay-views/index.js.map +1 -0
- package/dist/periods/index.cjs +7 -1
- package/dist/periods/index.cjs.map +1 -1
- package/dist/periods/index.d.cts +7 -6
- package/dist/periods/index.d.ts +7 -6
- package/dist/periods/index.js +6 -6
- package/dist/{predicate-SBHmi6D0.d.cts → predicate-Dnu81tsS.d.cts} +25 -1
- package/dist/{predicate-SBHmi6D0.d.ts → predicate-Dnu81tsS.d.ts} +25 -1
- package/dist/{public-envelope-6JTACYJV.js → public-envelope-U3CMEOMV.js} +4 -4
- package/dist/public-envelope-U3CMEOMV.js.map +1 -0
- package/dist/query/index.cjs +302 -124
- package/dist/query/index.cjs.map +1 -1
- package/dist/query/index.d.cts +3 -3
- package/dist/query/index.d.ts +3 -3
- package/dist/query/index.js +26 -11
- package/dist/read-only-facade-ITU6L7BL.js +7 -0
- package/dist/read-only-facade-ITU6L7BL.js.map +1 -0
- package/dist/registry-3ALP62P6.js +10 -0
- package/dist/registry-3ALP62P6.js.map +1 -0
- package/dist/registry-7HE6VJGC.js +8 -0
- package/dist/registry-7HE6VJGC.js.map +1 -0
- package/dist/registry-PSIPG2QR.js +8 -0
- package/dist/registry-PSIPG2QR.js.map +1 -0
- package/dist/registry-RFGGMVNJ.js +7 -0
- package/dist/registry-RFGGMVNJ.js.map +1 -0
- package/dist/revoke-KY2GB4KP.js +17 -0
- package/dist/revoke-KY2GB4KP.js.map +1 -0
- package/dist/session/index.cjs +7 -1
- package/dist/session/index.cjs.map +1 -1
- package/dist/session/index.d.cts +8 -7
- package/dist/session/index.d.ts +8 -7
- package/dist/session/index.js +10 -3
- package/dist/session/index.js.map +1 -1
- package/dist/shadow/index.cjs.map +1 -1
- package/dist/shadow/index.d.cts +7 -6
- package/dist/shadow/index.d.ts +7 -6
- package/dist/shadow/index.js +2 -2
- package/dist/signer-GRI5TZKH.js +18 -0
- package/dist/signer-GRI5TZKH.js.map +1 -0
- package/dist/stale-OTOF3FH7.js +13 -0
- package/dist/stale-OTOF3FH7.js.map +1 -0
- package/dist/store/index.cjs +14 -0
- package/dist/store/index.cjs.map +1 -1
- package/dist/store/index.d.cts +7 -6
- package/dist/store/index.d.ts +7 -6
- package/dist/store/index.js +5 -2
- package/dist/{strategy-D-SrOLCl.d.cts → strategy-DSTrsZ8t.d.cts} +72 -19
- package/dist/{strategy-D-SrOLCl.d.ts → strategy-DSTrsZ8t.d.ts} +72 -19
- package/dist/sync/index.cjs.map +1 -1
- package/dist/sync/index.d.cts +6 -5
- package/dist/sync/index.d.ts +6 -5
- package/dist/sync/index.js +4 -4
- package/dist/team/index.cjs +1554 -2
- package/dist/team/index.cjs.map +1 -1
- package/dist/team/index.d.cts +7 -6
- package/dist/team/index.d.ts +7 -6
- package/dist/team/index.js +77 -8
- package/dist/tx/index.cjs +296 -44
- package/dist/tx/index.cjs.map +1 -1
- package/dist/tx/index.d.cts +7 -6
- package/dist/tx/index.d.ts +7 -6
- package/dist/tx/index.js +2 -2
- package/dist/{types-Bo7NSXJr.d.ts → types-BoFFiskX.d.ts} +2714 -321
- package/dist/{types-Bnb82f5R.d.cts → types-DJG8HG6F.d.cts} +2714 -321
- package/dist/{index-CywCC1qZ.d.cts → ulid-BmBgooGm.d.ts} +215 -26
- package/dist/{index-8QDuznDr.d.ts → ulid-C7ms9oli.d.cts} +215 -26
- package/dist/util/index.cjs.map +1 -1
- package/dist/util/index.js +1 -1
- package/dist/with-derivation-BKXXa8Vt.d.ts +13 -0
- package/dist/with-derivation-BjQ7q4NE.d.cts +13 -0
- package/dist/with-guard-C25yNjzd.d.ts +18 -0
- package/dist/with-guard-DQme5DKE.d.cts +18 -0
- package/dist/with-materialized-view-BbEPFIIJ.d.cts +27 -0
- package/dist/with-materialized-view-CqnRwI2S.d.ts +27 -0
- package/dist/with-overlayed-view-Ct1fSJt-.d.ts +13 -0
- package/dist/with-overlayed-view-bwlmmFjx.d.cts +13 -0
- package/package.json +65 -2
- package/dist/chunk-2CSJGFCB.js.map +0 -1
- package/dist/chunk-ACLDOTNQ.js.map +0 -1
- package/dist/chunk-BTDCBVJW.js +0 -160
- package/dist/chunk-BTDCBVJW.js.map +0 -1
- package/dist/chunk-CIMZBAZB.js.map +0 -1
- package/dist/chunk-EXHNQEV4.js +0 -392
- package/dist/chunk-EXHNQEV4.js.map +0 -1
- package/dist/chunk-GOUT6DND.js.map +0 -1
- package/dist/chunk-M5INGEFC.js.map +0 -1
- package/dist/chunk-MDDTIZUO.js.map +0 -1
- package/dist/chunk-QAVUREFT.js.map +0 -1
- package/dist/chunk-RKJ6OL7K.js.map +0 -1
- package/dist/chunk-SCZXXXU4.js.map +0 -1
- package/dist/chunk-TDR6T5CJ.js.map +0 -1
- package/dist/chunk-WDM5XGGS.js.map +0 -1
- /package/dist/{chunk-PTVMYYON.js.map → chunk-243PNUA6.js.map} +0 -0
- /package/dist/{chunk-MR4424N3.js.map → chunk-2PAQNPE3.js.map} +0 -0
- /package/dist/{chunk-AVVPZ4BC.js.map → chunk-3Y53S2SA.js.map} +0 -0
- /package/dist/{chunk-ZFKD4QMV.js.map → chunk-7BRE6EUA.js.map} +0 -0
- /package/dist/{chunk-USKYUS74.js.map → chunk-MUWOSVEP.js.map} +0 -0
- /package/dist/{chunk-4PWAI7Q4.js.map → chunk-NWZ3I6R6.js.map} +0 -0
- /package/dist/{chunk-QGZRWRSL.js.map → chunk-QPEXPHJR.js.map} +0 -0
- /package/dist/{chunk-R36SIKES.js.map → chunk-QXQRKXCU.js.map} +0 -0
- /package/dist/{chunk-M62XNWRA.js.map → chunk-VK5EER6C.js.map} +0 -0
- /package/dist/{chunk-NPC4LFV5.js.map → chunk-YMYK7US4.js.map} +0 -0
- /package/dist/{crypto-IVKU7YTT.js.map → crypto-5ZDIY3NG.js.map} +0 -0
- /package/dist/{delegation-2DBS2EOH.js.map → delegation-QYXZW25W.js.map} +0 -0
- /package/dist/{ledger-QZTTHQAQ.js.map → derivations/index.js.map} +0 -0
- /package/dist/{public-envelope-6JTACYJV.js.map → executor-AS2IDHKZ.js.map} +0 -0
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
export { w as withMaterializedView } from '../with-materialized-view-CqnRwI2S.js';
|
|
2
|
+
import { aH as Collection, at as TxContext, bi as MVQueryContext, bj as RegisteredMV, bk as MaterializedViewRegistry } from '../types-BoFFiskX.js';
|
|
3
|
+
export { bl as MaterializedFromMeta, bm as MaterializedViewOutput, aE as MaterializedViewStrategy, aF as MaterializedViewStrategyHandle, bn as UnionSource } from '../types-BoFFiskX.js';
|
|
4
|
+
import { Q as Query } from '../index-BCKdioeh.js';
|
|
5
|
+
export { t as MaterializedViewConfigError, u as MaterializedViewCycleError, v as MaterializedViewSourceUnknownError, w as MaterializedViewTooLargeError } from '../index-BCKdioeh.js';
|
|
6
|
+
import '../lazy-builder-Rpd-V3jP.js';
|
|
7
|
+
import '../predicate-Dnu81tsS.js';
|
|
8
|
+
import '../strategy-DSTrsZ8t.js';
|
|
9
|
+
import '../strategy-BSxFXGzb.js';
|
|
10
|
+
import '@noy-db/attestation';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Accessor shape passed in from the owning Vault. Mirrors v1's
|
|
14
|
+
* `DerivationStaleAccessor` — provides the per-collection resolver
|
|
15
|
+
* and the active TxContext so refresh writes/tombstones register on
|
|
16
|
+
* `_executed` for #133-style rollback symmetry.
|
|
17
|
+
*/
|
|
18
|
+
interface MVExecutorAccessor {
|
|
19
|
+
getCollection(name: string): Collection<any>;
|
|
20
|
+
getActiveTxContext(): TxContext | null;
|
|
21
|
+
/**
|
|
22
|
+
* Vault-shaped accessor passed to the MV's `query()` callback at
|
|
23
|
+
* each refresh. Same instance the registry used at registration
|
|
24
|
+
* time; threading through the executor lets the refresh path
|
|
25
|
+
* re-evaluate the closure against the live vault state.
|
|
26
|
+
*/
|
|
27
|
+
getQueryContext(): MVQueryContext;
|
|
28
|
+
}
|
|
29
|
+
interface RefreshResult {
|
|
30
|
+
/** Rows newly written / overwritten. */
|
|
31
|
+
written: number;
|
|
32
|
+
/** Rows tombstoned via `_internalDelete` (only when `onEmpty: 'delete'`). */
|
|
33
|
+
deleted: number;
|
|
34
|
+
/** Failed row writes (non-strict mode). */
|
|
35
|
+
failed: number;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Run an MV's `query()` and write the result rows to the output
|
|
39
|
+
* collection. Same-DEK encryption: routes through the standard
|
|
40
|
+
* `Collection.put` pipeline, so the output collection's DEK is what
|
|
41
|
+
* gets used (matches the v2 spec's "same DEK as the left-most source"
|
|
42
|
+
* invariant — `Collection.put` looks up the DEK by collection name,
|
|
43
|
+
* and the output collection IS the MV's owned collection).
|
|
44
|
+
*
|
|
45
|
+
* Stamps `_materializedFrom` onto every emitted row.
|
|
46
|
+
*
|
|
47
|
+
* **Tombstoning** (#152): when `spec.onEmpty: 'delete'` (default), rows
|
|
48
|
+
* that existed in a prior refresh but no longer appear in the new
|
|
49
|
+
* materialized result are deleted via `Collection._internalDelete` —
|
|
50
|
+
* the housekeeping bypass primitive added in PR #148 prevents user
|
|
51
|
+
* `onDelete` guards on the output collection from firing on these
|
|
52
|
+
* system-internal deletes. `onEmpty: 'keep'` opts out (rows from
|
|
53
|
+
* prior refreshes linger even when the new result lacks them).
|
|
54
|
+
*
|
|
55
|
+
* **Cost ceiling** (#152): if the materialized row count exceeds
|
|
56
|
+
* `spec.maxRows` (default 100k), throws `MaterializedViewTooLargeError`
|
|
57
|
+
* before any writes hit the store — so strict-mode rollback is
|
|
58
|
+
* clean.
|
|
59
|
+
*
|
|
60
|
+
* **Strict mode** (#152): `spec.strict === true` re-throws on any
|
|
61
|
+
* row-write failure; the active TxContext registration means the
|
|
62
|
+
* source-write rolls back atomically via `revertExecuted` (#133).
|
|
63
|
+
*
|
|
64
|
+
* @internal
|
|
65
|
+
*/
|
|
66
|
+
declare const MaterializedViewExecutor: {
|
|
67
|
+
refresh(reg: RegisteredMV, accessor: MVExecutorAccessor): Promise<RefreshResult>;
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Walks a `Query<T>` plan and returns the set of source collection
|
|
72
|
+
* names that any source-write should trigger a refresh on.
|
|
73
|
+
*
|
|
74
|
+
* Foundation sub-issue (#150) handles:
|
|
75
|
+
* - root collection (the one the query was built from)
|
|
76
|
+
* - FK join targets (`.join(field, { as })`)
|
|
77
|
+
*
|
|
78
|
+
* Deferred to later sub-issues:
|
|
79
|
+
* - `.crossJoin()` — v3 cross-join spec (separate primitive)
|
|
80
|
+
* - `.wherePredicate(name)` — v2 predicate primitive, sub-issue #153
|
|
81
|
+
* - Overlay-name expansion to {base, overlay} — sub-issue #154
|
|
82
|
+
*
|
|
83
|
+
* The set is materialized at MV registration time. The MV registry
|
|
84
|
+
* uses it to (a) dispatch `onSourceWrite` only to MVs that actually
|
|
85
|
+
* care, and (b) contribute edges to the shared cycle-detection graph.
|
|
86
|
+
*/
|
|
87
|
+
declare function analyzeDependencies(query: Query<any>): Set<string>;
|
|
88
|
+
/**
|
|
89
|
+
* Convenience: produce a stable string summary of the query plan
|
|
90
|
+
* suitable for `queryHash` derivation. Captures everything the
|
|
91
|
+
* dependency analyzer reads + the where/orderBy/limit/offset
|
|
92
|
+
* structure that affects materialized rows.
|
|
93
|
+
*
|
|
94
|
+
* `joinContext` is intentionally NOT included — the join-resolution
|
|
95
|
+
* function references would defeat hash determinism. The set of join
|
|
96
|
+
* TARGETS (collection names) IS included via the plan.joins legs.
|
|
97
|
+
*/
|
|
98
|
+
declare function summarizeQueryPlan(query: Query<any>): string;
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Deterministic hash of a materialized view strategy's "shape": MV
|
|
102
|
+
* name + canonical query-plan summary + sorted dependency-set.
|
|
103
|
+
*
|
|
104
|
+
* Used to detect strategy drift: a row whose `_materializedFrom.queryHash`
|
|
105
|
+
* doesn't match the current strategy is considered stale.
|
|
106
|
+
*
|
|
107
|
+
* Web Crypto SHA-256 — no extra deps. Mirrors the v1
|
|
108
|
+
* `computeStrategyHash` pattern.
|
|
109
|
+
*/
|
|
110
|
+
declare function computeQueryHash(mvName: string,
|
|
111
|
+
/**
|
|
112
|
+
* Source-collection set the query depends on. Sorted before
|
|
113
|
+
* canonicalization so set iteration order doesn't affect the hash.
|
|
114
|
+
*/
|
|
115
|
+
dependencies: ReadonlySet<string>,
|
|
116
|
+
/**
|
|
117
|
+
* Stringified query-plan summary. The caller produces this from the
|
|
118
|
+
* `Query<T>` builder — concretely: a JSON serialization of clauses +
|
|
119
|
+
* orderBy + limit + offset + joins. Function bodies inside
|
|
120
|
+
* `wherePredicate` are NOT included here (those carry their own
|
|
121
|
+
* `predicateHash` to be folded in by a later sub-issue).
|
|
122
|
+
*/
|
|
123
|
+
queryPlanSummary: string): Promise<string>;
|
|
124
|
+
/**
|
|
125
|
+
* Canonicalize a query plan for hashing. Walks the plan structure
|
|
126
|
+
* with sorted keys so insertion order doesn't perturb the result.
|
|
127
|
+
* Lives here rather than in `query/builder.ts` to keep that module
|
|
128
|
+
* stable across MV-specific evolutions.
|
|
129
|
+
*
|
|
130
|
+
* @internal exported for testing
|
|
131
|
+
*/
|
|
132
|
+
declare function canonicalizeQueryPlan(plan: unknown): string;
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Accessor shape passed in from the owning Vault. Provides the
|
|
136
|
+
* registry (used as a stable WeakMap key + to look up MVs by output
|
|
137
|
+
* collection) and the runtime context the lazy refresh needs.
|
|
138
|
+
* Mirrors v1's `DerivationStaleAccessor`.
|
|
139
|
+
*/
|
|
140
|
+
interface MVStaleAccessor {
|
|
141
|
+
registry(): MaterializedViewRegistry;
|
|
142
|
+
getCollection(name: string): Collection<any>;
|
|
143
|
+
getActiveTxContext(): TxContext | null;
|
|
144
|
+
getQueryContext(): MVQueryContext;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Mark an MV as stale. Called from `Collection.dispatchMaterializedViews`
|
|
148
|
+
* when a source-write fires for a `refresh: 'lazy'` MV.
|
|
149
|
+
*
|
|
150
|
+
* @internal
|
|
151
|
+
*/
|
|
152
|
+
declare function markMVStale(registry: MaterializedViewRegistry, mvName: string): void;
|
|
153
|
+
/**
|
|
154
|
+
* Test-only: check whether a given MV name is currently flagged stale
|
|
155
|
+
* against a registry. Exported so the regression suite can pin the
|
|
156
|
+
* stale-bit lifecycle without touching the internal `WeakMap`.
|
|
157
|
+
*
|
|
158
|
+
* @internal
|
|
159
|
+
*/
|
|
160
|
+
declare function isMVStale(registry: MaterializedViewRegistry, mvName: string): boolean;
|
|
161
|
+
/**
|
|
162
|
+
* Called from `Collection.get` (and any reader that materializes the
|
|
163
|
+
* MV's output collection). If any MV producing `outputCollection` is
|
|
164
|
+
* flagged stale, runs the executor against the live source state
|
|
165
|
+
* before returning. No-op when there is no pending work — keeps the
|
|
166
|
+
* read fast path negligible.
|
|
167
|
+
*
|
|
168
|
+
* Dynamic-imports the executor only when a stale flag actually fires
|
|
169
|
+
* (the floor-bundle isolation pattern v1 derivations established in
|
|
170
|
+
* #130).
|
|
171
|
+
*/
|
|
172
|
+
declare function resolveStaleMVOnRead(accessor: MVStaleAccessor, outputCollection: string): Promise<void>;
|
|
173
|
+
/**
|
|
174
|
+
* Drop every stale flag for a registry. Used after a manual
|
|
175
|
+
* `vault.refreshView(name)` runs the executor explicitly — the
|
|
176
|
+
* post-refresh state matches the registered strategies, so
|
|
177
|
+
* lingering stale bits would force a redundant refresh on the next
|
|
178
|
+
* read.
|
|
179
|
+
*
|
|
180
|
+
* @internal
|
|
181
|
+
*/
|
|
182
|
+
declare function clearMVStale(registry: MaterializedViewRegistry, mvName: string): void;
|
|
183
|
+
|
|
184
|
+
export { type MVExecutorAccessor, type MVStaleAccessor, MaterializedViewExecutor, MaterializedViewRegistry, type RefreshResult, RegisteredMV, analyzeDependencies, canonicalizeQueryPlan, clearMVStale, computeQueryHash, isMVStale, markMVStale, resolveStaleMVOnRead, summarizeQueryPlan };
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import {
|
|
2
|
+
withMaterializedView
|
|
3
|
+
} from "../chunk-RTZVQAJ7.js";
|
|
4
|
+
import {
|
|
5
|
+
MaterializedViewExecutor
|
|
6
|
+
} from "../chunk-Y2RKOPNC.js";
|
|
7
|
+
import {
|
|
8
|
+
MaterializedViewRegistry,
|
|
9
|
+
analyzeDependencies,
|
|
10
|
+
canonicalizeQueryPlan,
|
|
11
|
+
computeQueryHash,
|
|
12
|
+
summarizeQueryPlan
|
|
13
|
+
} from "../chunk-TBKOGSYR.js";
|
|
14
|
+
import {
|
|
15
|
+
clearMVStale,
|
|
16
|
+
isMVStale,
|
|
17
|
+
markMVStale,
|
|
18
|
+
resolveStaleMVOnRead
|
|
19
|
+
} from "../chunk-PLI5TV7N.js";
|
|
20
|
+
import "../chunk-VRBCTEKQ.js";
|
|
21
|
+
import "../chunk-MRIBLZL3.js";
|
|
22
|
+
import {
|
|
23
|
+
MaterializedViewConfigError,
|
|
24
|
+
MaterializedViewCycleError,
|
|
25
|
+
MaterializedViewSourceUnknownError,
|
|
26
|
+
MaterializedViewTooLargeError
|
|
27
|
+
} from "../chunk-W3XXT26A.js";
|
|
28
|
+
export {
|
|
29
|
+
MaterializedViewConfigError,
|
|
30
|
+
MaterializedViewCycleError,
|
|
31
|
+
MaterializedViewExecutor,
|
|
32
|
+
MaterializedViewRegistry,
|
|
33
|
+
MaterializedViewSourceUnknownError,
|
|
34
|
+
MaterializedViewTooLargeError,
|
|
35
|
+
analyzeDependencies,
|
|
36
|
+
canonicalizeQueryPlan,
|
|
37
|
+
clearMVStale,
|
|
38
|
+
computeQueryHash,
|
|
39
|
+
isMVStale,
|
|
40
|
+
markMVStale,
|
|
41
|
+
resolveStaleMVOnRead,
|
|
42
|
+
summarizeQueryPlan,
|
|
43
|
+
withMaterializedView
|
|
44
|
+
};
|
|
45
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Noydb,
|
|
3
|
+
createNoydb
|
|
4
|
+
} from "./chunk-E535SAN4.js";
|
|
5
|
+
import "./chunk-EMIGCR7X.js";
|
|
6
|
+
import "./chunk-3Z2TPHC4.js";
|
|
7
|
+
import "./chunk-YTXSFG3C.js";
|
|
8
|
+
import "./chunk-7BRE6EUA.js";
|
|
9
|
+
import "./chunk-UND4XIB6.js";
|
|
10
|
+
import "./chunk-243PNUA6.js";
|
|
11
|
+
import "./chunk-QPEXPHJR.js";
|
|
12
|
+
import "./chunk-UF3BUNQZ.js";
|
|
13
|
+
import "./chunk-LRAZDV5X.js";
|
|
14
|
+
import "./chunk-EUYOGYGV.js";
|
|
15
|
+
import "./chunk-7BUTTVMR.js";
|
|
16
|
+
import "./chunk-Q6W2CMEJ.js";
|
|
17
|
+
import "./chunk-2QR2PQTT.js";
|
|
18
|
+
import "./chunk-FZU343FL.js";
|
|
19
|
+
import "./chunk-7Z23ZFLV.js";
|
|
20
|
+
import "./chunk-XG3PTSCD.js";
|
|
21
|
+
import "./chunk-J4KLMEUL.js";
|
|
22
|
+
import "./chunk-YMYK7US4.js";
|
|
23
|
+
import "./chunk-5ZGZ6HIZ.js";
|
|
24
|
+
import "./chunk-VRBCTEKQ.js";
|
|
25
|
+
import "./chunk-MRIBLZL3.js";
|
|
26
|
+
import "./chunk-PFSNOPBQ.js";
|
|
27
|
+
import "./chunk-YS3POABP.js";
|
|
28
|
+
import "./chunk-2PAQNPE3.js";
|
|
29
|
+
import "./chunk-W3XXT26A.js";
|
|
30
|
+
export {
|
|
31
|
+
Noydb,
|
|
32
|
+
createNoydb
|
|
33
|
+
};
|
|
34
|
+
//# sourceMappingURL=noydb-5H3C24GG.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/overlay-views/index.ts
|
|
21
|
+
var overlay_views_exports = {};
|
|
22
|
+
__export(overlay_views_exports, {
|
|
23
|
+
OverlayBaseIsVirtualError: () => OverlayBaseIsVirtualError,
|
|
24
|
+
OverlayCollectionUnavailableError: () => OverlayCollectionUnavailableError,
|
|
25
|
+
OverlayIdMismatchError: () => OverlayIdMismatchError,
|
|
26
|
+
OverlayNameCollisionError: () => OverlayNameCollisionError,
|
|
27
|
+
OverlayedCollection: () => OverlayedCollection,
|
|
28
|
+
OverlayedViewRegistry: () => OverlayedViewRegistry,
|
|
29
|
+
withOverlayedView: () => withOverlayedView
|
|
30
|
+
});
|
|
31
|
+
module.exports = __toCommonJS(overlay_views_exports);
|
|
32
|
+
|
|
33
|
+
// src/errors.ts
|
|
34
|
+
var NoydbError = class extends Error {
|
|
35
|
+
/** Machine-readable error code. Stable across library versions. */
|
|
36
|
+
code;
|
|
37
|
+
constructor(code, message) {
|
|
38
|
+
super(message);
|
|
39
|
+
this.name = "NoydbError";
|
|
40
|
+
this.code = code;
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
var ValidationError = class extends NoydbError {
|
|
44
|
+
constructor(message = "Validation error") {
|
|
45
|
+
super("VALIDATION_ERROR", message);
|
|
46
|
+
this.name = "ValidationError";
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
var OverlayBaseIsVirtualError = class extends NoydbError {
|
|
50
|
+
overlayName;
|
|
51
|
+
base;
|
|
52
|
+
constructor(overlayName, base) {
|
|
53
|
+
super(
|
|
54
|
+
"OVERLAY_BASE_IS_VIRTUAL",
|
|
55
|
+
`withOverlayedView "${overlayName}": base "${base}" is another overlay's virtual name. Multi-overlay stacking is a v3 feature; base must reference a concrete collection (a real source or an MV output).`
|
|
56
|
+
);
|
|
57
|
+
this.name = "OverlayBaseIsVirtualError";
|
|
58
|
+
this.overlayName = overlayName;
|
|
59
|
+
this.base = base;
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
var OverlayCollectionUnavailableError = class extends NoydbError {
|
|
63
|
+
overlayName;
|
|
64
|
+
overlay;
|
|
65
|
+
constructor(overlayName, overlay) {
|
|
66
|
+
super(
|
|
67
|
+
"OVERLAY_COLLECTION_UNAVAILABLE",
|
|
68
|
+
`withOverlayedView "${overlayName}": overlay collection "${overlay}" is unavailable. It must be a real vault-known collection that is NOT itself an MV output collection.`
|
|
69
|
+
);
|
|
70
|
+
this.name = "OverlayCollectionUnavailableError";
|
|
71
|
+
this.overlayName = overlayName;
|
|
72
|
+
this.overlay = overlay;
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
var OverlayNameCollisionError = class extends NoydbError {
|
|
76
|
+
overlayName;
|
|
77
|
+
constructor(overlayName) {
|
|
78
|
+
super(
|
|
79
|
+
"OVERLAY_NAME_COLLISION",
|
|
80
|
+
`withOverlayedView "${overlayName}": virtual name collides with an MV output or a concrete source collection. Pick a unique name for the virtual collection.`
|
|
81
|
+
);
|
|
82
|
+
this.name = "OverlayNameCollisionError";
|
|
83
|
+
this.overlayName = overlayName;
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
var OverlayIdMismatchError = class extends NoydbError {
|
|
87
|
+
actual;
|
|
88
|
+
expected;
|
|
89
|
+
constructor(actual, expected) {
|
|
90
|
+
super(
|
|
91
|
+
"OVERLAY_ID_MISMATCH",
|
|
92
|
+
`Overlay put(id, record): id "${actual}" does not match the base MV's rowKey(record) \u2192 "${expected}". Pass the row directly via .put(record) to derive the id, or fix the id to match the base MV's rowKey output.`
|
|
93
|
+
);
|
|
94
|
+
this.name = "OverlayIdMismatchError";
|
|
95
|
+
this.actual = actual;
|
|
96
|
+
this.expected = expected;
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
// src/overlay-views/with-overlayed-view.ts
|
|
101
|
+
function withOverlayedView(spec) {
|
|
102
|
+
if (!spec.name || spec.name.length === 0) {
|
|
103
|
+
throw new ValidationError("withOverlayedView: name is required");
|
|
104
|
+
}
|
|
105
|
+
if (!spec.base || spec.base.length === 0) {
|
|
106
|
+
throw new ValidationError("withOverlayedView: base is required");
|
|
107
|
+
}
|
|
108
|
+
if (!spec.overlay || spec.overlay.length === 0) {
|
|
109
|
+
throw new ValidationError("withOverlayedView: overlay is required");
|
|
110
|
+
}
|
|
111
|
+
if (spec.base === spec.overlay) {
|
|
112
|
+
throw new ValidationError("withOverlayedView: base and overlay must be different collections");
|
|
113
|
+
}
|
|
114
|
+
if (spec.base === spec.name || spec.overlay === spec.name) {
|
|
115
|
+
throw new ValidationError(
|
|
116
|
+
"withOverlayedView: virtual name must differ from both base and overlay collection names"
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
if (!spec.shadowField || spec.shadowField.length === 0) {
|
|
120
|
+
throw new ValidationError("withOverlayedView: shadowField is required");
|
|
121
|
+
}
|
|
122
|
+
return {
|
|
123
|
+
__noydb_strategy: "overlayed-view",
|
|
124
|
+
spec
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// src/overlay-views/registry.ts
|
|
129
|
+
var OverlayedViewRegistry = class {
|
|
130
|
+
_byName = /* @__PURE__ */ new Map();
|
|
131
|
+
/**
|
|
132
|
+
* Register an overlay. Validates name uniqueness, base concreteness,
|
|
133
|
+
* and overlay availability AGAINST the MV registry — overlays
|
|
134
|
+
* declared without the MV registry context skip cross-registry
|
|
135
|
+
* checks but still validate self-consistency.
|
|
136
|
+
*/
|
|
137
|
+
register(spec, options) {
|
|
138
|
+
const { isOverlayName, isMVOutput, isKnownCollection } = options;
|
|
139
|
+
if (isMVOutput?.(spec.name) || isOverlayName?.(spec.name)) {
|
|
140
|
+
throw new OverlayNameCollisionError(spec.name);
|
|
141
|
+
}
|
|
142
|
+
if (isOverlayName?.(spec.base)) {
|
|
143
|
+
throw new OverlayBaseIsVirtualError(spec.name, spec.base);
|
|
144
|
+
}
|
|
145
|
+
if (isMVOutput?.(spec.overlay)) {
|
|
146
|
+
throw new OverlayCollectionUnavailableError(spec.name, spec.overlay);
|
|
147
|
+
}
|
|
148
|
+
void isKnownCollection;
|
|
149
|
+
this._byName.set(spec.name, spec);
|
|
150
|
+
}
|
|
151
|
+
byName(name) {
|
|
152
|
+
return this._byName.get(name);
|
|
153
|
+
}
|
|
154
|
+
/** All overlay virtual names. */
|
|
155
|
+
names() {
|
|
156
|
+
return new Set(this._byName.keys());
|
|
157
|
+
}
|
|
158
|
+
isOverlay(name) {
|
|
159
|
+
return this._byName.has(name);
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Resolve the `rowKey` function for an overlay's base MV. Returns
|
|
163
|
+
* `undefined` if the base isn't an MV (raw source collection) or
|
|
164
|
+
* if the MV registry isn't supplied. Used by the virtual-collection
|
|
165
|
+
* proxy to derive ids from `put(record)` calls.
|
|
166
|
+
*/
|
|
167
|
+
resolveBaseRowKey(name, mvRegistry) {
|
|
168
|
+
const spec = this._byName.get(name);
|
|
169
|
+
if (!spec || !mvRegistry) return void 0;
|
|
170
|
+
for (const reg of mvRegistry.all()) {
|
|
171
|
+
if (reg.outputCollection === spec.base || reg.spec.name === spec.base) {
|
|
172
|
+
return (row) => reg.spec.rowKey(row);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
return void 0;
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
// src/overlay-views/virtual-collection.ts
|
|
180
|
+
var OverlayedCollection = class {
|
|
181
|
+
constructor(spec, baseCollection, overlayCollection, baseRowKey) {
|
|
182
|
+
this.spec = spec;
|
|
183
|
+
this.baseCollection = baseCollection;
|
|
184
|
+
this.overlayCollection = overlayCollection;
|
|
185
|
+
this.baseRowKey = baseRowKey;
|
|
186
|
+
}
|
|
187
|
+
spec;
|
|
188
|
+
baseCollection;
|
|
189
|
+
overlayCollection;
|
|
190
|
+
baseRowKey;
|
|
191
|
+
/**
|
|
192
|
+
* Convenience accessors for advanced callers that need to bypass the
|
|
193
|
+
* virtual layer (bulk imports, direct overlay queries). Mirrors the
|
|
194
|
+
* spec's "direct writes to the underlying overlay collection skip
|
|
195
|
+
* the validation" escape hatch.
|
|
196
|
+
*/
|
|
197
|
+
overlay = {
|
|
198
|
+
rowKey: (row) => {
|
|
199
|
+
if (!this.baseRowKey) {
|
|
200
|
+
throw new Error(
|
|
201
|
+
`Overlay "${this.spec.name}": base "${this.spec.base}" is not an MV \u2014 cannot auto-derive id from the row. Use \`put(id, record)\` instead.`
|
|
202
|
+
);
|
|
203
|
+
}
|
|
204
|
+
return this.baseRowKey(row);
|
|
205
|
+
}
|
|
206
|
+
};
|
|
207
|
+
/** Get the merged row by id. */
|
|
208
|
+
async get(id) {
|
|
209
|
+
const overlayRow = await this.overlayCollection.get(id);
|
|
210
|
+
if (overlayRow !== null && this.shadowPredicateApplies(overlayRow)) {
|
|
211
|
+
return overlayRow;
|
|
212
|
+
}
|
|
213
|
+
const baseRow = await this.baseCollection.get(id);
|
|
214
|
+
if (baseRow !== null) return baseRow;
|
|
215
|
+
return null;
|
|
216
|
+
}
|
|
217
|
+
/** List union of base + overlay ids, applying the merge per row. */
|
|
218
|
+
async list() {
|
|
219
|
+
const baseRows = await this.baseCollection.list();
|
|
220
|
+
const overlayRows = await this.overlayCollection.list();
|
|
221
|
+
const merged = /* @__PURE__ */ new Map();
|
|
222
|
+
const idOf = (row) => {
|
|
223
|
+
if (this.baseRowKey) return this.baseRowKey(row);
|
|
224
|
+
const idField = row.id;
|
|
225
|
+
return typeof idField === "string" ? idField : "";
|
|
226
|
+
};
|
|
227
|
+
for (const row of baseRows) {
|
|
228
|
+
const id = idOf(row);
|
|
229
|
+
if (id) merged.set(id, row);
|
|
230
|
+
}
|
|
231
|
+
for (const row of overlayRows) {
|
|
232
|
+
const id = idOf(row);
|
|
233
|
+
if (!id) continue;
|
|
234
|
+
if (this.shadowPredicateApplies(row)) {
|
|
235
|
+
merged.set(id, row);
|
|
236
|
+
} else if (!merged.has(id)) {
|
|
237
|
+
continue;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
return [...merged.values()];
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Write to the overlay. Two forms:
|
|
244
|
+
* - `put(record)`: id is derived via the base MV's `rowKey(record)`.
|
|
245
|
+
* Throws if the base isn't an MV.
|
|
246
|
+
* - `put(id, record)`: validates `id === rowKey(record)`; throws
|
|
247
|
+
* `OverlayIdMismatchError` on mismatch.
|
|
248
|
+
*/
|
|
249
|
+
async put(idOrRecord, maybeRecord) {
|
|
250
|
+
let id;
|
|
251
|
+
let record;
|
|
252
|
+
if (maybeRecord === void 0) {
|
|
253
|
+
record = idOrRecord;
|
|
254
|
+
if (!this.baseRowKey) {
|
|
255
|
+
throw new Error(
|
|
256
|
+
`Overlay "${this.spec.name}".put(record): base "${this.spec.base}" is not an MV. Use put(id, record) explicitly.`
|
|
257
|
+
);
|
|
258
|
+
}
|
|
259
|
+
id = this.baseRowKey(record);
|
|
260
|
+
} else {
|
|
261
|
+
id = idOrRecord;
|
|
262
|
+
record = maybeRecord;
|
|
263
|
+
if (this.baseRowKey) {
|
|
264
|
+
const expected = this.baseRowKey(record);
|
|
265
|
+
if (id !== expected) {
|
|
266
|
+
throw new OverlayIdMismatchError(id, expected);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
await this.overlayCollection.put(id, record);
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Remove the overlay row only. Idempotent (no-op on absent).
|
|
274
|
+
* The base row is untouched — if a base row exists for `id`,
|
|
275
|
+
* subsequent reads return it.
|
|
276
|
+
*/
|
|
277
|
+
async delete(id) {
|
|
278
|
+
await this.overlayCollection.delete(id);
|
|
279
|
+
}
|
|
280
|
+
/** True when `overlay[shadowField] === shadowValue`. */
|
|
281
|
+
shadowPredicateApplies(row) {
|
|
282
|
+
return row[this.spec.shadowField] === this.spec.shadowValue;
|
|
283
|
+
}
|
|
284
|
+
// ─── Throw-stubs for the unimplemented Collection<T> surface ───────
|
|
285
|
+
//
|
|
286
|
+
// `Vault.collection(name)` widens the return type to `Collection<T>`
|
|
287
|
+
// for the overlay intercept, but `OverlayedCollection` doesn't
|
|
288
|
+
// implement the full surface. These stubs catch the common
|
|
289
|
+
// reactive / chainable APIs with a clear "not yet implemented"
|
|
290
|
+
// error pointing at the relevant issue — so consumers don't hit a
|
|
291
|
+
// cryptic `undefined is not a function` runtime crash.
|
|
292
|
+
//
|
|
293
|
+
// Closes niwat-review of PR #160.
|
|
294
|
+
/** @throws — chainable Query<T> over a virtual collection is deferred. */
|
|
295
|
+
query() {
|
|
296
|
+
throw new Error(
|
|
297
|
+
`OverlayedCollection "${this.spec.name}".query() is not yet implemented for overlay views (#154). Use \`list()\` + filter for now, or read from the underlying \`${this.spec.base}\` / \`${this.spec.overlay}\` collections directly. Reactive APIs land in a future MV sub-issue.`
|
|
298
|
+
);
|
|
299
|
+
}
|
|
300
|
+
/** @throws — change-stream subscription over a virtual collection is deferred. */
|
|
301
|
+
subscribe() {
|
|
302
|
+
throw new Error(
|
|
303
|
+
`OverlayedCollection "${this.spec.name}".subscribe() is not yet implemented for overlay views (#154). Subscribe to the underlying \`${this.spec.base}\` / \`${this.spec.overlay}\` collections individually for now. Merged change-stream lands in a future MV sub-issue.`
|
|
304
|
+
);
|
|
305
|
+
}
|
|
306
|
+
/** @throws — live query over a virtual collection is deferred. */
|
|
307
|
+
live() {
|
|
308
|
+
throw new Error(
|
|
309
|
+
`OverlayedCollection "${this.spec.name}".live() is not yet implemented for overlay views (#154). Reactive APIs land in a future MV sub-issue.`
|
|
310
|
+
);
|
|
311
|
+
}
|
|
312
|
+
/** @throws — async iteration over a virtual collection is deferred. */
|
|
313
|
+
scan() {
|
|
314
|
+
throw new Error(
|
|
315
|
+
`OverlayedCollection "${this.spec.name}".scan() is not yet implemented for overlay views (#154). Use \`list()\` for now (no row-count ceiling at niwat scale), or scan the underlying collections directly.`
|
|
316
|
+
);
|
|
317
|
+
}
|
|
318
|
+
/** @throws — lazy-mode query is not applicable to virtual collections. */
|
|
319
|
+
lazyQuery() {
|
|
320
|
+
throw new Error(
|
|
321
|
+
`OverlayedCollection "${this.spec.name}".lazyQuery() is not supported. Virtual collections always materialize through base + overlay reads \u2014 lazy-mode indexed lookups don't apply.`
|
|
322
|
+
);
|
|
323
|
+
}
|
|
324
|
+
/** @throws — bulk-atomic put is deferred to a future MV sub-issue. */
|
|
325
|
+
putManyAtomic() {
|
|
326
|
+
throw new Error(
|
|
327
|
+
`OverlayedCollection "${this.spec.name}".putManyAtomic() is not yet implemented for overlay views (#154). Use sequential \`.put(record)\` calls for now, or write to \`${this.spec.overlay}\` directly.`
|
|
328
|
+
);
|
|
329
|
+
}
|
|
330
|
+
/** @throws — bulk delete is deferred to a future MV sub-issue. */
|
|
331
|
+
deleteMany() {
|
|
332
|
+
throw new Error(
|
|
333
|
+
`OverlayedCollection "${this.spec.name}".deleteMany() is not yet implemented for overlay views (#154). Use sequential \`.delete(id)\` calls for now, or operate on \`${this.spec.overlay}\` directly.`
|
|
334
|
+
);
|
|
335
|
+
}
|
|
336
|
+
/** @throws — `.first()` over a virtual collection is deferred. */
|
|
337
|
+
first() {
|
|
338
|
+
throw new Error(
|
|
339
|
+
`OverlayedCollection "${this.spec.name}".first() is not yet implemented for overlay views (#154). Use \`(await list())[0]\` for now.`
|
|
340
|
+
);
|
|
341
|
+
}
|
|
342
|
+
/** @throws — `.count()` over a virtual collection is deferred. */
|
|
343
|
+
count() {
|
|
344
|
+
throw new Error(
|
|
345
|
+
`OverlayedCollection "${this.spec.name}".count() is not yet implemented for overlay views (#154). Use \`(await list()).length\` for now.`
|
|
346
|
+
);
|
|
347
|
+
}
|
|
348
|
+
};
|
|
349
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
350
|
+
0 && (module.exports = {
|
|
351
|
+
OverlayBaseIsVirtualError,
|
|
352
|
+
OverlayCollectionUnavailableError,
|
|
353
|
+
OverlayIdMismatchError,
|
|
354
|
+
OverlayNameCollisionError,
|
|
355
|
+
OverlayedCollection,
|
|
356
|
+
OverlayedViewRegistry,
|
|
357
|
+
withOverlayedView
|
|
358
|
+
});
|
|
359
|
+
//# sourceMappingURL=index.cjs.map
|