@noy-db/hub 0.1.0-pre.9 → 0.2.0-pre.10
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 +100 -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 +19121 -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-26NK23DZ.js +296 -0
- package/dist/chunk-26NK23DZ.js.map +1 -0
- package/dist/{chunk-TDR6T5CJ.js → chunk-2LPPNWF6.js} +91 -132
- package/dist/chunk-2LPPNWF6.js.map +1 -0
- package/dist/{chunk-PTVMYYON.js → chunk-2N62W5YP.js} +3 -3
- package/dist/{chunk-QGZRWRSL.js → chunk-3LPV6BXR.js} +4 -4
- package/dist/{chunk-QAVUREFT.js → chunk-4CLICFEY.js} +12 -6
- package/dist/chunk-4CLICFEY.js.map +1 -0
- package/dist/chunk-4USCAEDT.js +10529 -0
- package/dist/chunk-4USCAEDT.js.map +1 -0
- package/dist/chunk-5IXJGFF2.js +83 -0
- package/dist/chunk-5IXJGFF2.js.map +1 -0
- package/dist/chunk-5OEJ6GOT.js +124 -0
- package/dist/chunk-5OEJ6GOT.js.map +1 -0
- package/dist/{chunk-4PWAI7Q4.js → chunk-5OX6XVNS.js} +5 -5
- package/dist/{chunk-2CSJGFCB.js → chunk-6EOXTJS2.js} +6 -229
- package/dist/chunk-6EOXTJS2.js.map +1 -0
- package/dist/chunk-6T2UDBKG.js +53 -0
- package/dist/chunk-6T2UDBKG.js.map +1 -0
- package/dist/{chunk-GOUT6DND.js → chunk-6YLPHBKR.js} +382 -95
- package/dist/chunk-6YLPHBKR.js.map +1 -0
- package/dist/chunk-7CEGU63S.js +179 -0
- package/dist/chunk-7CEGU63S.js.map +1 -0
- package/dist/chunk-A3JMGXPG.js +125 -0
- package/dist/chunk-A3JMGXPG.js.map +1 -0
- package/dist/chunk-BB27JMWB.js +795 -0
- package/dist/chunk-BB27JMWB.js.map +1 -0
- package/dist/{chunk-SCZXXXU4.js → chunk-BDV7INMP.js} +7 -32
- package/dist/chunk-BDV7INMP.js.map +1 -0
- package/dist/chunk-C3WE6UJY.js +19 -0
- package/dist/chunk-C3WE6UJY.js.map +1 -0
- package/dist/chunk-CH22FZHT.js +96 -0
- package/dist/chunk-CH22FZHT.js.map +1 -0
- package/dist/chunk-CXFOITNS.js +34 -0
- package/dist/chunk-CXFOITNS.js.map +1 -0
- package/dist/chunk-CXJG63MA.js +109 -0
- package/dist/chunk-CXJG63MA.js.map +1 -0
- package/dist/chunk-DAP2XL7Q.js +51 -0
- package/dist/chunk-DAP2XL7Q.js.map +1 -0
- package/dist/{chunk-AVVPZ4BC.js → chunk-DJRWA3Q5.js} +4 -4
- package/dist/chunk-DRXIZOFV.js +233 -0
- package/dist/chunk-DRXIZOFV.js.map +1 -0
- package/dist/chunk-FO3UEG4S.js +313 -0
- package/dist/chunk-FO3UEG4S.js.map +1 -0
- package/dist/chunk-GAUEWM7D.js +147 -0
- package/dist/chunk-GAUEWM7D.js.map +1 -0
- package/dist/{chunk-MDDTIZUO.js → chunk-GNHAC43Q.js} +218 -119
- package/dist/chunk-GNHAC43Q.js.map +1 -0
- package/dist/chunk-HHOO7HGH.js +57 -0
- package/dist/chunk-HHOO7HGH.js.map +1 -0
- package/dist/{chunk-WDM5XGGS.js → chunk-HQSQC2XL.js} +182 -12
- package/dist/chunk-HQSQC2XL.js.map +1 -0
- package/dist/chunk-IMYKDWB4.js +139 -0
- package/dist/chunk-IMYKDWB4.js.map +1 -0
- package/dist/{chunk-M62XNWRA.js → chunk-LSTBFLL2.js} +2 -2
- package/dist/{chunk-ACLDOTNQ.js → chunk-O6EJ6WTI.js} +436 -3
- package/dist/chunk-O6EJ6WTI.js.map +1 -0
- package/dist/chunk-PC6ZEDRL.js +71 -0
- package/dist/chunk-PC6ZEDRL.js.map +1 -0
- package/dist/chunk-PM3QYWUU.js +251 -0
- package/dist/chunk-PM3QYWUU.js.map +1 -0
- package/dist/chunk-PVUUIWHY.js +73 -0
- package/dist/chunk-PVUUIWHY.js.map +1 -0
- package/dist/chunk-PXTQPZO4.js +830 -0
- package/dist/chunk-PXTQPZO4.js.map +1 -0
- package/dist/{chunk-ZFKD4QMV.js → chunk-QSOYKKMD.js} +4 -4
- package/dist/chunk-QSOYKKMD.js.map +1 -0
- package/dist/{chunk-MR4424N3.js → chunk-R233SLY3.js} +2 -2
- package/dist/chunk-RC6SU5NO.js +36 -0
- package/dist/chunk-RC6SU5NO.js.map +1 -0
- package/dist/{chunk-USKYUS74.js → chunk-RRNA5GKT.js} +2 -2
- package/dist/{chunk-R36SIKES.js → chunk-RYIL3PI2.js} +2 -2
- package/dist/chunk-STNPB3UM.js +9 -0
- package/dist/chunk-STNPB3UM.js.map +1 -0
- package/dist/{chunk-M5INGEFC.js → chunk-TV3YZ35S.js} +7 -1
- package/dist/chunk-TV3YZ35S.js.map +1 -0
- package/dist/chunk-TY32C732.js +59 -0
- package/dist/chunk-TY32C732.js.map +1 -0
- package/dist/chunk-UMLVJTYV.js +20 -0
- package/dist/chunk-UMLVJTYV.js.map +1 -0
- package/dist/{chunk-NPC4LFV5.js → chunk-WIBHRONM.js} +2 -2
- package/dist/chunk-WIBHRONM.js.map +1 -0
- package/dist/{chunk-RKJ6OL7K.js → chunk-WIRRPTFH.js} +1 -1
- package/dist/chunk-WIRRPTFH.js.map +1 -0
- package/dist/{chunk-VQBTTTUN.js → chunk-Y26YV5R3.js} +4 -4
- package/dist/{chunk-VQBTTTUN.js.map → chunk-Y26YV5R3.js.map} +1 -1
- package/dist/{chunk-NXFEYLVG.js → chunk-YM7LFCG7.js} +5 -4
- package/dist/{chunk-NXFEYLVG.js.map → chunk-YM7LFCG7.js.map} +1 -1
- package/dist/{chunk-CIMZBAZB.js → chunk-Z6FNBOTC.js} +1 -1
- package/dist/chunk-Z6FNBOTC.js.map +1 -0
- package/dist/chunk-ZROPXHJY.js +82 -0
- package/dist/chunk-ZROPXHJY.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-2CRLG4F4.js} +3 -3
- package/dist/{delegation-2DBS2EOH.js → delegation-ZTRT2PRV.js} +5 -4
- package/dist/derivations/index.cjs +368 -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-AglVnkPY.d.cts} +1 -1
- package/dist/{dev-unlock-BdPp68qn.d.ts → dev-unlock-BOEYl1xl.d.ts} +1 -1
- package/dist/discriminant-BN9REW3o.d.cts +60 -0
- package/dist/discriminant-BN9REW3o.d.ts +60 -0
- package/dist/executor-S76VN45G.js +8 -0
- package/dist/executor-UCXLIGLW.js +11 -0
- package/dist/executor-UCXLIGLW.js.map +1 -0
- package/dist/executor-ZCNZJMGR.js +8 -0
- package/dist/executor-ZCNZJMGR.js.map +1 -0
- package/dist/fanout-sidecar-OKPMMPLG.js +51 -0
- package/dist/fanout-sidecar-OKPMMPLG.js.map +1 -0
- package/dist/guards/index.cjs +322 -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-B9m3_fhj.d.ts} +1 -1
- package/dist/{hash-BEfzPKwo.d.cts → hash-RVqz2zi8.d.cts} +1 -1
- package/dist/history/index.cjs +9 -2
- 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 +368 -27
- 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 +34 -6
- package/dist/i18n/index.js.map +1 -1
- package/dist/{index-DJTf9yxn.d.ts → index-B8bjExET.d.cts} +508 -14
- package/dist/{index-6xNpPsxR.d.cts → index-DfUbNad8.d.ts} +508 -14
- package/dist/index.cjs +8779 -1260
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +231 -19
- package/dist/index.d.ts +231 -19
- package/dist/index.js +311 -7370
- package/dist/index.js.map +1 -1
- package/dist/indexing/index.cjs +7 -1
- 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-3W6IVLKH.js +12 -0
- package/dist/issue-3W6IVLKH.js.map +1 -0
- package/dist/{lazy-builder-BwEoBQZ9.d.ts → lazy-builder-Ci5_YG73.d.cts} +2 -2
- package/dist/{lazy-builder-CZVLKh0Z.d.cts → lazy-builder-D5GU14TS.d.ts} +2 -2
- package/dist/{ledger-QZTTHQAQ.js → ledger-O7FXOG3D.js} +6 -6
- package/dist/ledger-O7FXOG3D.js.map +1 -0
- package/dist/materialized-views/index.cjs +856 -0
- package/dist/materialized-views/index.cjs.map +1 -0
- package/dist/materialized-views/index.d.cts +186 -0
- package/dist/materialized-views/index.d.ts +186 -0
- package/dist/materialized-views/index.js +45 -0
- package/dist/materialized-views/index.js.map +1 -0
- package/dist/noydb-YAZNH5TI.js +34 -0
- package/dist/noydb-YAZNH5TI.js.map +1 -0
- package/dist/overlay-views/index.cjs +369 -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-Bt5ft-9c.d.cts} +51 -2
- package/dist/{predicate-SBHmi6D0.d.ts → predicate-Bt5ft-9c.d.ts} +51 -2
- package/dist/{public-envelope-6JTACYJV.js → public-envelope-HMYHZIRH.js} +4 -4
- package/dist/public-envelope-HMYHZIRH.js.map +1 -0
- package/dist/query/index.cjs +555 -128
- 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 +32 -11
- package/dist/read-only-facade-ITU6L7BL.js +7 -0
- package/dist/read-only-facade-ITU6L7BL.js.map +1 -0
- package/dist/registry-DKEXOJVO.js +7 -0
- package/dist/registry-DKEXOJVO.js.map +1 -0
- package/dist/registry-ST2VNFZC.js +10 -0
- package/dist/registry-ST2VNFZC.js.map +1 -0
- package/dist/registry-UFIK7CSR.js +8 -0
- package/dist/registry-UFIK7CSR.js.map +1 -0
- package/dist/registry-ZGYYSM5I.js +8 -0
- package/dist/registry-ZGYYSM5I.js.map +1 -0
- package/dist/revoke-S6JMSLUN.js +17 -0
- package/dist/revoke-S6JMSLUN.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-7NPTB3SQ.js +18 -0
- package/dist/signer-7NPTB3SQ.js.map +1 -0
- package/dist/snapshots/index.cjs +937 -0
- package/dist/snapshots/index.cjs.map +1 -0
- package/dist/snapshots/index.d.cts +28 -0
- package/dist/snapshots/index.d.ts +28 -0
- package/dist/snapshots/index.js +152 -0
- package/dist/snapshots/index.js.map +1 -0
- package/dist/stale-VKXSXJF4.js +13 -0
- package/dist/stale-VKXSXJF4.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.ts → strategy-CT2LCKAX.d.cts} +84 -19
- package/dist/{strategy-D-SrOLCl.d.cts → strategy-CT2LCKAX.d.ts} +84 -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 +375 -43
- package/dist/tx/index.cjs.map +1 -1
- package/dist/tx/index.d.cts +8 -7
- package/dist/tx/index.d.ts +8 -7
- package/dist/tx/index.js +56 -3
- package/dist/tx/index.js.map +1 -1
- package/dist/{types-Bo7NSXJr.d.ts → types-CaNQm4i8.d.ts} +3902 -614
- package/dist/{types-Bnb82f5R.d.cts → types-n2_IfwlQ.d.cts} +3902 -614
- package/dist/{index-CywCC1qZ.d.cts → ulid-B9SMWj5i.d.ts} +216 -27
- package/dist/{index-8QDuznDr.d.ts → ulid-CLMjmyhG.d.cts} +216 -27
- package/dist/util/index.cjs +7 -0
- package/dist/util/index.cjs.map +1 -1
- package/dist/util/index.d.cts +2 -0
- package/dist/util/index.d.ts +2 -0
- package/dist/util/index.js +5 -1
- package/dist/util/index.js.map +1 -1
- package/dist/with-derivation-CVIOPTUf.d.ts +13 -0
- package/dist/with-derivation-aKrtS7Jj.d.cts +13 -0
- package/dist/with-guard-DZQbPzoP.d.cts +18 -0
- package/dist/with-guard-DseETUrF.d.ts +18 -0
- package/dist/with-materialized-view-C1eA1_T_.d.cts +27 -0
- package/dist/with-materialized-view-DaYaE8-Q.d.ts +27 -0
- package/dist/with-overlayed-view-DQsh2p8H.d.ts +13 -0
- package/dist/with-overlayed-view-DleJfKcV.d.cts +13 -0
- package/package.json +77 -3
- 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-NPC4LFV5.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-ZFKD4QMV.js.map +0 -1
- /package/dist/{chunk-PTVMYYON.js.map → chunk-2N62W5YP.js.map} +0 -0
- /package/dist/{chunk-QGZRWRSL.js.map → chunk-3LPV6BXR.js.map} +0 -0
- /package/dist/{chunk-4PWAI7Q4.js.map → chunk-5OX6XVNS.js.map} +0 -0
- /package/dist/{chunk-AVVPZ4BC.js.map → chunk-DJRWA3Q5.js.map} +0 -0
- /package/dist/{chunk-M62XNWRA.js.map → chunk-LSTBFLL2.js.map} +0 -0
- /package/dist/{chunk-MR4424N3.js.map → chunk-R233SLY3.js.map} +0 -0
- /package/dist/{chunk-USKYUS74.js.map → chunk-RRNA5GKT.js.map} +0 -0
- /package/dist/{chunk-R36SIKES.js.map → chunk-RYIL3PI2.js.map} +0 -0
- /package/dist/{crypto-IVKU7YTT.js.map → crypto-2CRLG4F4.js.map} +0 -0
- /package/dist/{delegation-2DBS2EOH.js.map → delegation-ZTRT2PRV.js.map} +0 -0
- /package/dist/{ledger-QZTTHQAQ.js.map → derivations/index.js.map} +0 -0
- /package/dist/{public-envelope-6JTACYJV.js.map → executor-S76VN45G.js.map} +0 -0
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
evaluateClause,
|
|
3
3
|
readPath
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-TV3YZ35S.js";
|
|
5
5
|
import {
|
|
6
|
+
CrossJoinSourceUnknownError,
|
|
7
|
+
CrossJoinTooLargeError,
|
|
6
8
|
DanglingReferenceError,
|
|
7
9
|
JoinTooLargeError
|
|
8
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-O6EJ6WTI.js";
|
|
9
11
|
|
|
10
12
|
// src/query/join.ts
|
|
11
13
|
var DEFAULT_JOIN_MAX_ROWS = 5e4;
|
|
@@ -244,6 +246,9 @@ var NO_AGGREGATE = {
|
|
|
244
246
|
groupBy() {
|
|
245
247
|
throw NOT_ENABLED;
|
|
246
248
|
},
|
|
249
|
+
groupByN() {
|
|
250
|
+
throw NOT_ENABLED;
|
|
251
|
+
},
|
|
247
252
|
scanAggregate() {
|
|
248
253
|
throw NOT_ENABLED;
|
|
249
254
|
}
|
|
@@ -257,16 +262,89 @@ var EMPTY_PLAN = {
|
|
|
257
262
|
offset: 0,
|
|
258
263
|
joins: []
|
|
259
264
|
};
|
|
265
|
+
var DEFAULT_CROSS_JOIN_MAX_ROWS = 5e4;
|
|
260
266
|
var Query = class _Query {
|
|
261
267
|
source;
|
|
262
268
|
plan;
|
|
263
269
|
joinContext;
|
|
264
270
|
aggregateStrategy;
|
|
265
|
-
|
|
271
|
+
predicates;
|
|
272
|
+
constructor(source, plan = EMPTY_PLAN, joinContext, aggregateStrategy = NO_AGGREGATE, predicates) {
|
|
266
273
|
this.source = source;
|
|
267
274
|
this.plan = plan;
|
|
268
275
|
this.joinContext = joinContext;
|
|
269
276
|
this.aggregateStrategy = aggregateStrategy;
|
|
277
|
+
this.predicates = predicates;
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* @internal — accessor for the materialized-view dependency
|
|
281
|
+
* analyzer. Not part of the public API; consumers should use the
|
|
282
|
+
* builder methods, not inspect the plan directly.
|
|
283
|
+
*/
|
|
284
|
+
_plan() {
|
|
285
|
+
return this.plan;
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* @internal — accessor for the materialized-view dependency
|
|
289
|
+
* analyzer. Returns the join resolution context (or `undefined` for
|
|
290
|
+
* queries constructed without a Collection backing).
|
|
291
|
+
*/
|
|
292
|
+
_joinContext() {
|
|
293
|
+
return this.joinContext;
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* @internal — clone this Query with a declared-predicate map
|
|
297
|
+
* attached. Used by the materialized-view registry to enable
|
|
298
|
+
* `.wherePredicate(name, ctx?)` for the MV's query callback.
|
|
299
|
+
* Consumers don't call this directly.
|
|
300
|
+
*/
|
|
301
|
+
_withPredicates(predicates) {
|
|
302
|
+
return new _Query(
|
|
303
|
+
this.source,
|
|
304
|
+
this.plan,
|
|
305
|
+
this.joinContext,
|
|
306
|
+
this.aggregateStrategy,
|
|
307
|
+
predicates
|
|
308
|
+
);
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Filter by a registered deterministic predicate. Requires
|
|
312
|
+
* the Query to have been augmented with a predicates map (typically
|
|
313
|
+
* via the materialized-view registry — bare Queries constructed
|
|
314
|
+
* outside an MV throw on `.wherePredicate()`).
|
|
315
|
+
*
|
|
316
|
+
* `ctx` is an optional opaque value passed verbatim to the predicate
|
|
317
|
+
* function. Both `predicateHash` (from the registration) and a
|
|
318
|
+
* canonical-JSON hash of `ctx` fold into the MV's `queryHash`, so
|
|
319
|
+
* either changing forces refresh on next visit.
|
|
320
|
+
*/
|
|
321
|
+
wherePredicate(name, ctx) {
|
|
322
|
+
if (!this.predicates) {
|
|
323
|
+
throw new Error(
|
|
324
|
+
`.wherePredicate("${name}"): no predicates registered on this Query. Function-based predicates require the Query to be obtained from inside a materialized-view query() callback whose strategy declares \`predicates: { ${name}: { hash, fn } }\`.`
|
|
325
|
+
);
|
|
326
|
+
}
|
|
327
|
+
const decl = this.predicates.get(name);
|
|
328
|
+
if (!decl) {
|
|
329
|
+
throw new Error(
|
|
330
|
+
`.wherePredicate("${name}"): predicate not registered. Available: ${[...this.predicates.keys()].join(", ") || "(none)"}.`
|
|
331
|
+
);
|
|
332
|
+
}
|
|
333
|
+
const clause = {
|
|
334
|
+
type: "wherePredicate",
|
|
335
|
+
name,
|
|
336
|
+
ctx,
|
|
337
|
+
predicateHash: decl.hash,
|
|
338
|
+
ctxHash: canonicalCtxHash(ctx),
|
|
339
|
+
fn: decl.fn
|
|
340
|
+
};
|
|
341
|
+
return new _Query(
|
|
342
|
+
this.source,
|
|
343
|
+
{ ...this.plan, clauses: [...this.plan.clauses, clause] },
|
|
344
|
+
this.joinContext,
|
|
345
|
+
this.aggregateStrategy,
|
|
346
|
+
this.predicates
|
|
347
|
+
);
|
|
270
348
|
}
|
|
271
349
|
/** Add a field comparison. Multiple where() calls are AND-combined. */
|
|
272
350
|
where(field, op, value) {
|
|
@@ -275,7 +353,8 @@ var Query = class _Query {
|
|
|
275
353
|
this.source,
|
|
276
354
|
{ ...this.plan, clauses: [...this.plan.clauses, clause] },
|
|
277
355
|
this.joinContext,
|
|
278
|
-
this.aggregateStrategy
|
|
356
|
+
this.aggregateStrategy,
|
|
357
|
+
this.predicates
|
|
279
358
|
);
|
|
280
359
|
}
|
|
281
360
|
/**
|
|
@@ -285,7 +364,7 @@ var Query = class _Query {
|
|
|
285
364
|
*/
|
|
286
365
|
or(builder) {
|
|
287
366
|
const sub = builder(
|
|
288
|
-
new _Query(this.source, EMPTY_PLAN, this.joinContext, this.aggregateStrategy)
|
|
367
|
+
new _Query(this.source, EMPTY_PLAN, this.joinContext, this.aggregateStrategy, this.predicates)
|
|
289
368
|
);
|
|
290
369
|
const group = {
|
|
291
370
|
type: "group",
|
|
@@ -296,7 +375,8 @@ var Query = class _Query {
|
|
|
296
375
|
this.source,
|
|
297
376
|
{ ...this.plan, clauses: [...this.plan.clauses, group] },
|
|
298
377
|
this.joinContext,
|
|
299
|
-
this.aggregateStrategy
|
|
378
|
+
this.aggregateStrategy,
|
|
379
|
+
this.predicates
|
|
300
380
|
);
|
|
301
381
|
}
|
|
302
382
|
/**
|
|
@@ -305,7 +385,7 @@ var Query = class _Query {
|
|
|
305
385
|
*/
|
|
306
386
|
and(builder) {
|
|
307
387
|
const sub = builder(
|
|
308
|
-
new _Query(this.source, EMPTY_PLAN, this.joinContext, this.aggregateStrategy)
|
|
388
|
+
new _Query(this.source, EMPTY_PLAN, this.joinContext, this.aggregateStrategy, this.predicates)
|
|
309
389
|
);
|
|
310
390
|
const group = {
|
|
311
391
|
type: "group",
|
|
@@ -316,7 +396,8 @@ var Query = class _Query {
|
|
|
316
396
|
this.source,
|
|
317
397
|
{ ...this.plan, clauses: [...this.plan.clauses, group] },
|
|
318
398
|
this.joinContext,
|
|
319
|
-
this.aggregateStrategy
|
|
399
|
+
this.aggregateStrategy,
|
|
400
|
+
this.predicates
|
|
320
401
|
);
|
|
321
402
|
}
|
|
322
403
|
/** Escape hatch: add an arbitrary predicate function. Not serializable. */
|
|
@@ -329,7 +410,8 @@ var Query = class _Query {
|
|
|
329
410
|
this.source,
|
|
330
411
|
{ ...this.plan, clauses: [...this.plan.clauses, clause] },
|
|
331
412
|
this.joinContext,
|
|
332
|
-
this.aggregateStrategy
|
|
413
|
+
this.aggregateStrategy,
|
|
414
|
+
this.predicates
|
|
333
415
|
);
|
|
334
416
|
}
|
|
335
417
|
/** Sort by a field. Subsequent calls are tie-breakers. */
|
|
@@ -338,7 +420,8 @@ var Query = class _Query {
|
|
|
338
420
|
this.source,
|
|
339
421
|
{ ...this.plan, orderBy: [...this.plan.orderBy, { field, direction }] },
|
|
340
422
|
this.joinContext,
|
|
341
|
-
this.aggregateStrategy
|
|
423
|
+
this.aggregateStrategy,
|
|
424
|
+
this.predicates
|
|
342
425
|
);
|
|
343
426
|
}
|
|
344
427
|
/** Cap the result size. */
|
|
@@ -347,7 +430,8 @@ var Query = class _Query {
|
|
|
347
430
|
this.source,
|
|
348
431
|
{ ...this.plan, limit: n },
|
|
349
432
|
this.joinContext,
|
|
350
|
-
this.aggregateStrategy
|
|
433
|
+
this.aggregateStrategy,
|
|
434
|
+
this.predicates
|
|
351
435
|
);
|
|
352
436
|
}
|
|
353
437
|
/** Skip the first N matching records (after ordering). */
|
|
@@ -356,7 +440,8 @@ var Query = class _Query {
|
|
|
356
440
|
this.source,
|
|
357
441
|
{ ...this.plan, offset: n },
|
|
358
442
|
this.joinContext,
|
|
359
|
-
this.aggregateStrategy
|
|
443
|
+
this.aggregateStrategy,
|
|
444
|
+
this.predicates
|
|
360
445
|
);
|
|
361
446
|
}
|
|
362
447
|
/**
|
|
@@ -455,7 +540,80 @@ var Query = class _Query {
|
|
|
455
540
|
this.source,
|
|
456
541
|
{ ...this.plan, joins: [...this.plan.joins, leg] },
|
|
457
542
|
this.joinContext,
|
|
458
|
-
this.aggregateStrategy
|
|
543
|
+
this.aggregateStrategy,
|
|
544
|
+
this.predicates
|
|
545
|
+
);
|
|
546
|
+
}
|
|
547
|
+
/**
|
|
548
|
+
* Cartesian-product cross-join against `target` collection. Each result row
|
|
549
|
+
* carries the original `T` fields plus `result[as]` populated from every
|
|
550
|
+
* right-side row (or the filtered subset when `on:` is supplied).
|
|
551
|
+
*
|
|
552
|
+
* **Order matters:** `.where().crossJoin()` filters BEFORE expanding (cheaper);
|
|
553
|
+
* `.crossJoin().where('alias.field', ...)` filters AFTER (required when the
|
|
554
|
+
* where clause references the aliased fields).
|
|
555
|
+
*
|
|
556
|
+
* **Cost ceiling:** `CrossJoinTooLargeError` fires before allocation when
|
|
557
|
+
* `leftRows × rightRows` (or the cumulative lateral count) exceeds the limit.
|
|
558
|
+
* Default: 50,000 rows. Override per-clause with `{ maxRows: N }`.
|
|
559
|
+
*
|
|
560
|
+
* **`on:` shapes:**
|
|
561
|
+
* - `on: (left) => TTarget[]` — subset form (most efficient)
|
|
562
|
+
* - `on: (left) => (right) => boolean` — predicate form
|
|
563
|
+
* - `on: { predicate: 'name' }` — MV-safe, hash-tracked form
|
|
564
|
+
* (requires the Query to have been augmented via `_withPredicates`)
|
|
565
|
+
*
|
|
566
|
+
* Requires a JoinContext (constructed via `collection.query()`).
|
|
567
|
+
*/
|
|
568
|
+
crossJoin(target, opts) {
|
|
569
|
+
if (!this.joinContext) {
|
|
570
|
+
throw new Error(
|
|
571
|
+
`Query.crossJoin("${target}"): requires a join context. Use collection.query() to construct a cross-join-capable Query instead of the Query constructor directly.`
|
|
572
|
+
);
|
|
573
|
+
}
|
|
574
|
+
let onFn;
|
|
575
|
+
let onPredicateName;
|
|
576
|
+
if (opts.on !== void 0) {
|
|
577
|
+
if (typeof opts.on === "function") {
|
|
578
|
+
onFn = opts.on;
|
|
579
|
+
if (this.predicates) {
|
|
580
|
+
console.warn(
|
|
581
|
+
`Query.crossJoin("${target}", { on: callback }): inline on: callback inside a withMaterializedView query() disables queryHash drift detection for this cross-join. Use on: { predicate: '<name>' } to enable it.`
|
|
582
|
+
);
|
|
583
|
+
}
|
|
584
|
+
} else {
|
|
585
|
+
const predName = opts.on.predicate;
|
|
586
|
+
if (!this.predicates) {
|
|
587
|
+
throw new Error(
|
|
588
|
+
`Query.crossJoin("${target}", { on: { predicate: "${predName}" } }): the { predicate } form requires a predicates map. Use this form inside a withMaterializedView query() callback that declares predicates: { ${predName}: { hash, fn } }.`
|
|
589
|
+
);
|
|
590
|
+
}
|
|
591
|
+
const decl = this.predicates.get(predName);
|
|
592
|
+
if (!decl) {
|
|
593
|
+
throw new Error(
|
|
594
|
+
`Query.crossJoin("${target}"): predicate "${predName}" not registered. Available: ${[...this.predicates.keys()].join(", ") || "(none)"}.`
|
|
595
|
+
);
|
|
596
|
+
}
|
|
597
|
+
const as = opts.as;
|
|
598
|
+
const predicateFn = decl.fn;
|
|
599
|
+
onFn = (_left) => (right) => predicateFn({ ..._left, [as]: right });
|
|
600
|
+
onPredicateName = predName;
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
const clause = {
|
|
604
|
+
type: "crossJoin",
|
|
605
|
+
target,
|
|
606
|
+
as: opts.as,
|
|
607
|
+
...onFn !== void 0 && { on: onFn },
|
|
608
|
+
...onPredicateName !== void 0 && { onPredicateName },
|
|
609
|
+
...opts.maxRows !== void 0 && { maxRows: opts.maxRows }
|
|
610
|
+
};
|
|
611
|
+
return new _Query(
|
|
612
|
+
this.source,
|
|
613
|
+
{ ...this.plan, clauses: [...this.plan.clauses, clause] },
|
|
614
|
+
this.joinContext,
|
|
615
|
+
this.aggregateStrategy,
|
|
616
|
+
this.predicates
|
|
459
617
|
);
|
|
460
618
|
}
|
|
461
619
|
/**
|
|
@@ -465,7 +623,7 @@ var Query = class _Query {
|
|
|
465
623
|
* for the ordering rationale.
|
|
466
624
|
*/
|
|
467
625
|
toArray() {
|
|
468
|
-
const base = executePlanWithSource(this.source, this.plan);
|
|
626
|
+
const base = executePlanWithSource(this.source, this.plan, this.joinContext);
|
|
469
627
|
if (this.plan.joins.length === 0) return base;
|
|
470
628
|
if (!this.joinContext) {
|
|
471
629
|
throw new Error(
|
|
@@ -489,6 +647,14 @@ var Query = class _Query {
|
|
|
489
647
|
* intent is purely to count.
|
|
490
648
|
*/
|
|
491
649
|
count() {
|
|
650
|
+
if (this.plan.clauses.some((c) => c.type === "crossJoin")) {
|
|
651
|
+
if (!this.joinContext) {
|
|
652
|
+
throw new Error(
|
|
653
|
+
`Query.count(): plan contains crossJoin clauses but no JoinContext is attached.`
|
|
654
|
+
);
|
|
655
|
+
}
|
|
656
|
+
return executeClausePipeline(this.source, this.plan.clauses, this.joinContext).length;
|
|
657
|
+
}
|
|
492
658
|
const { candidates, remainingClauses } = candidateRecords(this.source, this.plan.clauses);
|
|
493
659
|
if (remainingClauses.length === 0) return candidates.length;
|
|
494
660
|
return filterRecords(candidates, remainingClauses).length;
|
|
@@ -536,7 +702,13 @@ var Query = class _Query {
|
|
|
536
702
|
aggregate(spec) {
|
|
537
703
|
const source = this.source;
|
|
538
704
|
const clauses = this.plan.clauses;
|
|
705
|
+
const joinCtx = this.joinContext;
|
|
706
|
+
const hasCrossJoins = clauses.some((c) => c.type === "crossJoin");
|
|
539
707
|
const executeRecords = () => {
|
|
708
|
+
if (hasCrossJoins) {
|
|
709
|
+
if (!joinCtx) throw new Error("Query.aggregate(): crossJoin requires a join context");
|
|
710
|
+
return executeClausePipeline(source, clauses, joinCtx);
|
|
711
|
+
}
|
|
540
712
|
const { candidates, remainingClauses } = candidateRecords(source, clauses);
|
|
541
713
|
return remainingClauses.length === 0 ? candidates : filterRecords(candidates, remainingClauses);
|
|
542
714
|
};
|
|
@@ -547,56 +719,19 @@ var Query = class _Query {
|
|
|
547
719
|
}
|
|
548
720
|
return this.aggregateStrategy.aggregate(executeRecords, spec, upstreams);
|
|
549
721
|
}
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
*
|
|
555
|
-
* ```ts
|
|
556
|
-
* const byClient = invoices.query()
|
|
557
|
-
* .where('status', '==', 'open')
|
|
558
|
-
* .groupBy('clientId')
|
|
559
|
-
* .aggregate({ total: sum('amount'), n: count() })
|
|
560
|
-
* .run()
|
|
561
|
-
* // → [ { clientId: 'c1', total: 5250, n: 3 }, … ]
|
|
562
|
-
* ```
|
|
563
|
-
*
|
|
564
|
-
* Result rows carry the group key value under the grouping field
|
|
565
|
-
* name plus every reducer output from the spec. Buckets are
|
|
566
|
-
* emitted in first-seen order — consumers who want a specific
|
|
567
|
-
* ordering should `.sort()` downstream.
|
|
568
|
-
*
|
|
569
|
-
* **Cardinality caps:** a one-shot warning fires at 10_000
|
|
570
|
-
* distinct groups; `GroupCardinalityError` throws at 100_000.
|
|
571
|
-
* Grouping on a high-uniqueness field like `id` or `createdAt` is
|
|
572
|
-
* almost always a query mistake — the error message names the
|
|
573
|
-
* field and observed cardinality and suggests narrowing with
|
|
574
|
-
* `.where()` first.
|
|
575
|
-
*
|
|
576
|
-
* **Null / undefined keys:** records with a missing or explicitly
|
|
577
|
-
* `null` group field get their own buckets. `Map`-based
|
|
578
|
-
* partitioning distinguishes `undefined` from `null`, so the two
|
|
579
|
-
* cases do NOT merge. Consumers who want them merged should
|
|
580
|
-
* coalesce upstream with `.filter()`.
|
|
581
|
-
*
|
|
582
|
-
* **Joins are not applied** — same rationale as `.count()` and
|
|
583
|
-
* `.aggregate()`. Joined fields in are projection-only, so
|
|
584
|
-
* running a join inside a grouping pipeline would be wasteful and
|
|
585
|
-
* could trigger `DanglingReferenceError` in strict mode for a
|
|
586
|
-
* call whose intent is purely to bucket-and-reduce. Grouping by
|
|
587
|
-
* a joined field is explicitly out of scope for — file an
|
|
588
|
-
* issue if a real consumer needs it.
|
|
589
|
-
*
|
|
590
|
-
* **Filter clauses (`.filter(fn)`):** grouped queries still
|
|
591
|
-
* support filter clauses in the underlying plan — they run in
|
|
592
|
-
* the same candidate/filter pipeline that `.aggregate()` uses.
|
|
593
|
-
* The performance caveat is the same: filter clauses cost O(N)
|
|
594
|
-
* per record and can't be index-accelerated.
|
|
595
|
-
*/
|
|
596
|
-
groupBy(field) {
|
|
722
|
+
groupBy(...fields) {
|
|
723
|
+
if (fields.length === 0) {
|
|
724
|
+
throw new Error(".groupBy() requires at least one field");
|
|
725
|
+
}
|
|
597
726
|
const source = this.source;
|
|
598
727
|
const clauses = this.plan.clauses;
|
|
728
|
+
const joinCtx = this.joinContext;
|
|
729
|
+
const hasCrossJoins = clauses.some((c) => c.type === "crossJoin");
|
|
599
730
|
const executeRecords = () => {
|
|
731
|
+
if (hasCrossJoins) {
|
|
732
|
+
if (!joinCtx) throw new Error("Query.groupBy(): crossJoin requires a join context");
|
|
733
|
+
return executeClausePipeline(source, clauses, joinCtx);
|
|
734
|
+
}
|
|
600
735
|
const { candidates, remainingClauses } = candidateRecords(source, clauses);
|
|
601
736
|
return remainingClauses.length === 0 ? candidates : filterRecords(candidates, remainingClauses);
|
|
602
737
|
};
|
|
@@ -605,36 +740,21 @@ var Query = class _Query {
|
|
|
605
740
|
const subscribe = source.subscribe.bind(source);
|
|
606
741
|
upstreams.push({ subscribe: (cb) => subscribe(cb) });
|
|
607
742
|
}
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
const
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
if (!labels) return void 0;
|
|
624
|
-
if (labels[locale] !== void 0) return labels[locale];
|
|
625
|
-
const chain = Array.isArray(fallback) ? fallback : fallback ? [fallback] : [];
|
|
626
|
-
for (const fb of chain) {
|
|
627
|
-
if (fb === "any") {
|
|
628
|
-
const any = Object.values(labels)[0];
|
|
629
|
-
if (any !== void 0) return any;
|
|
630
|
-
} else if (labels[fb] !== void 0) {
|
|
631
|
-
return labels[fb];
|
|
632
|
-
}
|
|
633
|
-
}
|
|
634
|
-
return void 0;
|
|
635
|
-
};
|
|
636
|
-
})() : void 0;
|
|
637
|
-
return this.aggregateStrategy.groupBy(executeRecords, field, upstreams, dictLabelResolver);
|
|
743
|
+
if (fields.length === 1) {
|
|
744
|
+
const field = fields[0];
|
|
745
|
+
const dictLabelResolver = buildDictLabelResolver(this.joinContext, field);
|
|
746
|
+
return this.aggregateStrategy.groupBy(
|
|
747
|
+
executeRecords,
|
|
748
|
+
field,
|
|
749
|
+
upstreams,
|
|
750
|
+
dictLabelResolver
|
|
751
|
+
);
|
|
752
|
+
}
|
|
753
|
+
return this.aggregateStrategy.groupByN(
|
|
754
|
+
executeRecords,
|
|
755
|
+
fields,
|
|
756
|
+
upstreams
|
|
757
|
+
);
|
|
638
758
|
}
|
|
639
759
|
/**
|
|
640
760
|
* Re-run the query whenever the source notifies of changes.
|
|
@@ -725,6 +845,21 @@ var Query = class _Query {
|
|
|
725
845
|
}
|
|
726
846
|
}
|
|
727
847
|
}
|
|
848
|
+
if (this.joinContext) {
|
|
849
|
+
const subscribedCross = /* @__PURE__ */ new Set();
|
|
850
|
+
for (const clause of this.plan.clauses) {
|
|
851
|
+
if (clause.type !== "crossJoin") continue;
|
|
852
|
+
if (subscribedCross.has(clause.target)) continue;
|
|
853
|
+
subscribedCross.add(clause.target);
|
|
854
|
+
const rightSource = this.joinContext.resolveSource(clause.target);
|
|
855
|
+
if (rightSource?.subscribe) {
|
|
856
|
+
const rightSubscribe = rightSource.subscribe.bind(rightSource);
|
|
857
|
+
upstreams.push({
|
|
858
|
+
subscribe: (cb) => rightSubscribe(cb)
|
|
859
|
+
});
|
|
860
|
+
}
|
|
861
|
+
}
|
|
862
|
+
}
|
|
728
863
|
return buildLiveQuery(() => this.toArray(), upstreams);
|
|
729
864
|
}
|
|
730
865
|
/**
|
|
@@ -736,9 +871,20 @@ var Query = class _Query {
|
|
|
736
871
|
return serializePlan(this.plan);
|
|
737
872
|
}
|
|
738
873
|
};
|
|
739
|
-
function executePlanWithSource(source, plan) {
|
|
740
|
-
const
|
|
741
|
-
let result
|
|
874
|
+
function executePlanWithSource(source, plan, joinContext) {
|
|
875
|
+
const hasCrossJoins = plan.clauses.some((c) => c.type === "crossJoin");
|
|
876
|
+
let result;
|
|
877
|
+
if (hasCrossJoins) {
|
|
878
|
+
if (!joinContext) {
|
|
879
|
+
throw new Error(
|
|
880
|
+
`Query.toArray(): plan contains crossJoin clauses but no JoinContext is attached. Use collection.query() instead of new Query() for cross-join support.`
|
|
881
|
+
);
|
|
882
|
+
}
|
|
883
|
+
result = executeClausePipeline(source, plan.clauses, joinContext);
|
|
884
|
+
} else {
|
|
885
|
+
const { candidates, remainingClauses } = candidateRecords(source, plan.clauses);
|
|
886
|
+
result = remainingClauses.length === 0 ? [...candidates] : filterRecords(candidates, remainingClauses);
|
|
887
|
+
}
|
|
742
888
|
if (plan.orderBy.length > 0) {
|
|
743
889
|
result = sortRecords(result, plan.orderBy);
|
|
744
890
|
}
|
|
@@ -788,6 +934,11 @@ function materializeIds(ids, lookupById) {
|
|
|
788
934
|
return out;
|
|
789
935
|
}
|
|
790
936
|
function executePlan(records, plan) {
|
|
937
|
+
if (plan.clauses.some((c) => c.type === "crossJoin")) {
|
|
938
|
+
throw new Error(
|
|
939
|
+
`executePlan(): does not support crossJoin clauses. executePlan is a stateless pure function \u2014 it cannot resolve cross-join right-side collections. Use Query.toArray() (via collection.query()) instead.`
|
|
940
|
+
);
|
|
941
|
+
}
|
|
791
942
|
let result = filterRecords(records, plan.clauses);
|
|
792
943
|
if (plan.orderBy.length > 0) {
|
|
793
944
|
result = sortRecords(result, plan.orderBy);
|
|
@@ -815,6 +966,74 @@ function filterRecords(records, clauses) {
|
|
|
815
966
|
}
|
|
816
967
|
return out;
|
|
817
968
|
}
|
|
969
|
+
function executeClausePipeline(source, clauses, joinContext) {
|
|
970
|
+
let rel = [...source.snapshot()];
|
|
971
|
+
let filterBatch = [];
|
|
972
|
+
for (const clause of clauses) {
|
|
973
|
+
if (clause.type === "crossJoin") {
|
|
974
|
+
if (filterBatch.length > 0) {
|
|
975
|
+
rel = filterRecords(rel, filterBatch);
|
|
976
|
+
filterBatch = [];
|
|
977
|
+
}
|
|
978
|
+
const rightSource = joinContext.resolveSource(clause.target);
|
|
979
|
+
if (!rightSource) {
|
|
980
|
+
throw new CrossJoinSourceUnknownError(clause.target, joinContext.leftCollection);
|
|
981
|
+
}
|
|
982
|
+
rel = applyCrossJoin(rel, clause, rightSource);
|
|
983
|
+
} else {
|
|
984
|
+
filterBatch.push(clause);
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
if (filterBatch.length > 0) {
|
|
988
|
+
rel = filterRecords(rel, filterBatch);
|
|
989
|
+
}
|
|
990
|
+
return rel;
|
|
991
|
+
}
|
|
992
|
+
function applyCrossJoin(leftRel, clause, rightSource) {
|
|
993
|
+
const rightRows = rightSource.snapshot();
|
|
994
|
+
const maxRows = clause.maxRows ?? DEFAULT_CROSS_JOIN_MAX_ROWS;
|
|
995
|
+
const { as } = clause;
|
|
996
|
+
if (!clause.on) {
|
|
997
|
+
const product = leftRel.length * rightRows.length;
|
|
998
|
+
if (product > maxRows) {
|
|
999
|
+
throw new CrossJoinTooLargeError({ target: clause.target, expected: product, limit: maxRows });
|
|
1000
|
+
}
|
|
1001
|
+
const expanded2 = [];
|
|
1002
|
+
for (const left of leftRel) {
|
|
1003
|
+
const leftObj = left;
|
|
1004
|
+
for (const right of rightRows) {
|
|
1005
|
+
expanded2.push({ ...leftObj, [as]: right });
|
|
1006
|
+
}
|
|
1007
|
+
}
|
|
1008
|
+
return expanded2;
|
|
1009
|
+
}
|
|
1010
|
+
const expanded = [];
|
|
1011
|
+
let cumulative = 0;
|
|
1012
|
+
for (const left of leftRel) {
|
|
1013
|
+
const callbackResult = clause.on(left);
|
|
1014
|
+
let filteredRight;
|
|
1015
|
+
if (Array.isArray(callbackResult)) {
|
|
1016
|
+
filteredRight = callbackResult;
|
|
1017
|
+
} else {
|
|
1018
|
+
filteredRight = rightRows.filter(
|
|
1019
|
+
callbackResult
|
|
1020
|
+
);
|
|
1021
|
+
}
|
|
1022
|
+
cumulative += filteredRight.length;
|
|
1023
|
+
if (cumulative > maxRows) {
|
|
1024
|
+
throw new CrossJoinTooLargeError({
|
|
1025
|
+
target: clause.target,
|
|
1026
|
+
expected: cumulative,
|
|
1027
|
+
limit: maxRows
|
|
1028
|
+
});
|
|
1029
|
+
}
|
|
1030
|
+
const leftObj = left;
|
|
1031
|
+
for (const right of filteredRight) {
|
|
1032
|
+
expanded.push({ ...leftObj, [as]: right });
|
|
1033
|
+
}
|
|
1034
|
+
}
|
|
1035
|
+
return expanded;
|
|
1036
|
+
}
|
|
818
1037
|
function sortRecords(records, orderBy) {
|
|
819
1038
|
return [...records].sort((a, b) => {
|
|
820
1039
|
for (const { field, direction } of orderBy) {
|
|
@@ -860,6 +1079,16 @@ function serializeClause(clause) {
|
|
|
860
1079
|
if (clause.type === "filter") {
|
|
861
1080
|
return { type: "filter", fn: "[function]" };
|
|
862
1081
|
}
|
|
1082
|
+
if (clause.type === "wherePredicate") {
|
|
1083
|
+
return {
|
|
1084
|
+
type: "wherePredicate",
|
|
1085
|
+
name: clause.name,
|
|
1086
|
+
ctx: clause.ctx,
|
|
1087
|
+
predicateHash: clause.predicateHash,
|
|
1088
|
+
ctxHash: clause.ctxHash,
|
|
1089
|
+
fn: "[function]"
|
|
1090
|
+
};
|
|
1091
|
+
}
|
|
863
1092
|
if (clause.type === "group") {
|
|
864
1093
|
return {
|
|
865
1094
|
type: "group",
|
|
@@ -867,8 +1096,65 @@ function serializeClause(clause) {
|
|
|
867
1096
|
clauses: clause.clauses.map(serializeClause)
|
|
868
1097
|
};
|
|
869
1098
|
}
|
|
1099
|
+
if (clause.type === "crossJoin") {
|
|
1100
|
+
return {
|
|
1101
|
+
type: "crossJoin",
|
|
1102
|
+
target: clause.target,
|
|
1103
|
+
as: clause.as,
|
|
1104
|
+
on: clause.on ? "[function]" : void 0,
|
|
1105
|
+
onPredicateName: clause.onPredicateName,
|
|
1106
|
+
maxRows: clause.maxRows
|
|
1107
|
+
};
|
|
1108
|
+
}
|
|
870
1109
|
return clause;
|
|
871
1110
|
}
|
|
1111
|
+
function canonicalCtxHash(ctx) {
|
|
1112
|
+
if (ctx === void 0) return "";
|
|
1113
|
+
const canonical = JSON.stringify(ctx, (_key, value) => {
|
|
1114
|
+
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
1115
|
+
const sorted = {};
|
|
1116
|
+
for (const k of Object.keys(value).sort()) {
|
|
1117
|
+
sorted[k] = value[k];
|
|
1118
|
+
}
|
|
1119
|
+
return sorted;
|
|
1120
|
+
}
|
|
1121
|
+
return value;
|
|
1122
|
+
});
|
|
1123
|
+
let h = 5381;
|
|
1124
|
+
for (let i = 0; i < canonical.length; i++) {
|
|
1125
|
+
h = (h << 5) + h ^ canonical.charCodeAt(i);
|
|
1126
|
+
}
|
|
1127
|
+
return (h >>> 0).toString(16).padStart(8, "0");
|
|
1128
|
+
}
|
|
1129
|
+
function buildDictLabelResolver(joinCtx, field) {
|
|
1130
|
+
if (!joinCtx?.resolveDictSource) return void 0;
|
|
1131
|
+
const dictSource = joinCtx.resolveDictSource(field);
|
|
1132
|
+
if (!dictSource) return void 0;
|
|
1133
|
+
const snapshot = dictSource.snapshot();
|
|
1134
|
+
const dictMap = /* @__PURE__ */ new Map();
|
|
1135
|
+
for (const entry of snapshot) {
|
|
1136
|
+
const k = entry["key"];
|
|
1137
|
+
const labels = entry["labels"];
|
|
1138
|
+
if (typeof k === "string" && labels && typeof labels === "object") {
|
|
1139
|
+
dictMap.set(k, labels);
|
|
1140
|
+
}
|
|
1141
|
+
}
|
|
1142
|
+
return async (key, locale, fallback) => {
|
|
1143
|
+
const labels = dictMap.get(key);
|
|
1144
|
+
if (!labels) return void 0;
|
|
1145
|
+
if (labels[locale] !== void 0) return labels[locale];
|
|
1146
|
+
const chain = Array.isArray(fallback) ? fallback : fallback ? [fallback] : [];
|
|
1147
|
+
for (const fb of chain) {
|
|
1148
|
+
if (fb === "any") {
|
|
1149
|
+
const any = Object.values(labels)[0];
|
|
1150
|
+
if (any !== void 0) return any;
|
|
1151
|
+
} else if (labels[fb] !== void 0) {
|
|
1152
|
+
return labels[fb];
|
|
1153
|
+
}
|
|
1154
|
+
}
|
|
1155
|
+
return void 0;
|
|
1156
|
+
};
|
|
1157
|
+
}
|
|
872
1158
|
|
|
873
1159
|
// src/query/scan-builder.ts
|
|
874
1160
|
var DEFAULT_SCAN_PAGE_SIZE = 100;
|
|
@@ -1278,8 +1564,9 @@ export {
|
|
|
1278
1564
|
resetJoinWarnings,
|
|
1279
1565
|
buildLiveQuery,
|
|
1280
1566
|
NO_AGGREGATE,
|
|
1567
|
+
DEFAULT_CROSS_JOIN_MAX_ROWS,
|
|
1281
1568
|
Query,
|
|
1282
1569
|
executePlan,
|
|
1283
1570
|
ScanBuilder
|
|
1284
1571
|
};
|
|
1285
|
-
//# sourceMappingURL=chunk-
|
|
1572
|
+
//# sourceMappingURL=chunk-6YLPHBKR.js.map
|