@tanstack/db 0.4.19 → 0.5.0
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/cjs/collection/change-events.cjs +10 -12
- package/dist/cjs/collection/change-events.cjs.map +1 -1
- package/dist/cjs/collection/change-events.d.cts +1 -8
- package/dist/cjs/collection/index.cjs +19 -1
- package/dist/cjs/collection/index.cjs.map +1 -1
- package/dist/cjs/collection/index.d.cts +7 -5
- package/dist/cjs/collection/sync.cjs +7 -1
- package/dist/cjs/collection/sync.cjs.map +1 -1
- package/dist/cjs/errors.cjs +9 -4
- package/dist/cjs/errors.cjs.map +1 -1
- package/dist/cjs/errors.d.cts +4 -1
- package/dist/cjs/index.cjs +21 -3
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.cts +2 -0
- package/dist/cjs/indexes/auto-index.cjs +7 -3
- package/dist/cjs/indexes/auto-index.cjs.map +1 -1
- package/dist/cjs/local-storage.cjs.map +1 -1
- package/dist/cjs/local-storage.d.cts +2 -2
- package/dist/cjs/query/builder/functions.cjs +34 -0
- package/dist/cjs/query/builder/functions.cjs.map +1 -1
- package/dist/cjs/query/builder/functions.d.cts +5 -0
- package/dist/cjs/query/builder/index.cjs +2 -2
- package/dist/cjs/query/builder/index.cjs.map +1 -1
- package/dist/cjs/query/builder/types.d.cts +18 -24
- package/dist/cjs/query/compiler/evaluators.cjs +57 -4
- package/dist/cjs/query/compiler/evaluators.cjs.map +1 -1
- package/dist/cjs/query/compiler/evaluators.d.cts +13 -0
- package/dist/cjs/query/compiler/expressions.cjs +4 -1
- package/dist/cjs/query/compiler/expressions.cjs.map +1 -1
- package/dist/cjs/query/compiler/group-by.cjs +3 -3
- package/dist/cjs/query/compiler/group-by.cjs.map +1 -1
- package/dist/cjs/query/compiler/index.cjs +2 -2
- package/dist/cjs/query/compiler/index.cjs.map +1 -1
- package/dist/cjs/query/compiler/order-by.cjs +18 -6
- package/dist/cjs/query/compiler/order-by.cjs.map +1 -1
- package/dist/cjs/query/compiler/order-by.d.cts +7 -1
- package/dist/cjs/query/expression-helpers.cjs +217 -0
- package/dist/cjs/query/expression-helpers.cjs.map +1 -0
- package/dist/cjs/query/expression-helpers.d.cts +216 -0
- package/dist/cjs/query/index.d.cts +2 -0
- package/dist/cjs/query/live/collection-config-builder.cjs +34 -2
- package/dist/cjs/query/live/collection-config-builder.cjs.map +1 -1
- package/dist/cjs/query/live/collection-config-builder.d.cts +7 -1
- package/dist/cjs/query/live/collection-registry.cjs +2 -1
- package/dist/cjs/query/live/collection-registry.cjs.map +1 -1
- package/dist/cjs/query/live/collection-registry.d.cts +1 -1
- package/dist/cjs/query/live/internal.cjs +5 -0
- package/dist/cjs/query/live/internal.cjs.map +1 -0
- package/dist/cjs/query/live/internal.d.cts +13 -0
- package/dist/cjs/query/live/types.d.cts +6 -1
- package/dist/cjs/query/predicate-utils.cjs +816 -0
- package/dist/cjs/query/predicate-utils.cjs.map +1 -0
- package/dist/cjs/query/predicate-utils.d.cts +116 -0
- package/dist/cjs/query/subset-dedupe.cjs +111 -0
- package/dist/cjs/query/subset-dedupe.cjs.map +1 -0
- package/dist/cjs/query/subset-dedupe.d.cts +66 -0
- package/dist/cjs/types.d.cts +31 -2
- package/dist/cjs/utils/comparison.cjs +30 -0
- package/dist/cjs/utils/comparison.cjs.map +1 -1
- package/dist/cjs/utils/comparison.d.cts +7 -1
- package/dist/cjs/utils/index-optimization.cjs +26 -22
- package/dist/cjs/utils/index-optimization.cjs.map +1 -1
- package/dist/cjs/utils/index-optimization.d.cts +5 -4
- package/dist/esm/collection/change-events.d.ts +1 -8
- package/dist/esm/collection/change-events.js +7 -9
- package/dist/esm/collection/change-events.js.map +1 -1
- package/dist/esm/collection/index.d.ts +7 -5
- package/dist/esm/collection/index.js +19 -1
- package/dist/esm/collection/index.js.map +1 -1
- package/dist/esm/collection/sync.js +7 -1
- package/dist/esm/collection/sync.js.map +1 -1
- package/dist/esm/errors.d.ts +4 -1
- package/dist/esm/errors.js +9 -4
- package/dist/esm/errors.js.map +1 -1
- package/dist/esm/index.d.ts +2 -0
- package/dist/esm/index.js +19 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/indexes/auto-index.js +7 -3
- package/dist/esm/indexes/auto-index.js.map +1 -1
- package/dist/esm/local-storage.d.ts +2 -2
- package/dist/esm/local-storage.js.map +1 -1
- package/dist/esm/query/builder/functions.d.ts +5 -0
- package/dist/esm/query/builder/functions.js +34 -0
- package/dist/esm/query/builder/functions.js.map +1 -1
- package/dist/esm/query/builder/index.js +2 -2
- package/dist/esm/query/builder/index.js.map +1 -1
- package/dist/esm/query/builder/types.d.ts +18 -24
- package/dist/esm/query/compiler/evaluators.d.ts +13 -0
- package/dist/esm/query/compiler/evaluators.js +59 -6
- package/dist/esm/query/compiler/evaluators.js.map +1 -1
- package/dist/esm/query/compiler/expressions.js +4 -1
- package/dist/esm/query/compiler/expressions.js.map +1 -1
- package/dist/esm/query/compiler/group-by.js +4 -4
- package/dist/esm/query/compiler/group-by.js.map +1 -1
- package/dist/esm/query/compiler/index.js +3 -3
- package/dist/esm/query/compiler/index.js.map +1 -1
- package/dist/esm/query/compiler/order-by.d.ts +7 -1
- package/dist/esm/query/compiler/order-by.js +18 -6
- package/dist/esm/query/compiler/order-by.js.map +1 -1
- package/dist/esm/query/expression-helpers.d.ts +216 -0
- package/dist/esm/query/expression-helpers.js +217 -0
- package/dist/esm/query/expression-helpers.js.map +1 -0
- package/dist/esm/query/index.d.ts +2 -0
- package/dist/esm/query/live/collection-config-builder.d.ts +7 -1
- package/dist/esm/query/live/collection-config-builder.js +34 -2
- package/dist/esm/query/live/collection-config-builder.js.map +1 -1
- package/dist/esm/query/live/collection-registry.d.ts +1 -1
- package/dist/esm/query/live/collection-registry.js +2 -1
- package/dist/esm/query/live/collection-registry.js.map +1 -1
- package/dist/esm/query/live/internal.d.ts +13 -0
- package/dist/esm/query/live/internal.js +5 -0
- package/dist/esm/query/live/internal.js.map +1 -0
- package/dist/esm/query/live/types.d.ts +6 -1
- package/dist/esm/query/predicate-utils.d.ts +116 -0
- package/dist/esm/query/predicate-utils.js +816 -0
- package/dist/esm/query/predicate-utils.js.map +1 -0
- package/dist/esm/query/subset-dedupe.d.ts +66 -0
- package/dist/esm/query/subset-dedupe.js +111 -0
- package/dist/esm/query/subset-dedupe.js.map +1 -0
- package/dist/esm/types.d.ts +31 -2
- package/dist/esm/utils/comparison.d.ts +7 -1
- package/dist/esm/utils/comparison.js +30 -0
- package/dist/esm/utils/comparison.js.map +1 -1
- package/dist/esm/utils/index-optimization.d.ts +5 -4
- package/dist/esm/utils/index-optimization.js +26 -22
- package/dist/esm/utils/index-optimization.js.map +1 -1
- package/package.json +2 -2
- package/src/collection/change-events.ts +14 -24
- package/src/collection/index.ts +34 -6
- package/src/collection/sync.ts +9 -1
- package/src/errors.ts +20 -4
- package/src/index.ts +4 -0
- package/src/indexes/auto-index.ts +8 -4
- package/src/local-storage.ts +11 -3
- package/src/query/builder/functions.ts +39 -0
- package/src/query/builder/index.ts +2 -2
- package/src/query/builder/types.ts +19 -27
- package/src/query/compiler/evaluators.ts +103 -5
- package/src/query/compiler/expressions.ts +3 -0
- package/src/query/compiler/group-by.ts +4 -4
- package/src/query/compiler/index.ts +3 -3
- package/src/query/compiler/order-by.ts +33 -7
- package/src/query/expression-helpers.ts +522 -0
- package/src/query/index.ts +12 -0
- package/src/query/live/collection-config-builder.ts +54 -2
- package/src/query/live/collection-registry.ts +3 -2
- package/src/query/live/internal.ts +15 -0
- package/src/query/live/types.ts +11 -1
- package/src/query/predicate-utils.ts +1415 -0
- package/src/query/subset-dedupe.ts +243 -0
- package/src/types.ts +41 -2
- package/src/utils/comparison.ts +70 -1
- package/src/utils/index-optimization.ts +77 -63
|
@@ -18,12 +18,9 @@
|
|
|
18
18
|
import { DEFAULT_COMPARE_OPTIONS } from "../utils.js"
|
|
19
19
|
import { ReverseIndex } from "../indexes/reverse-index.js"
|
|
20
20
|
import type { CompareOptions } from "../query/builder/types.js"
|
|
21
|
-
import type {
|
|
22
|
-
BaseIndex,
|
|
23
|
-
IndexInterface,
|
|
24
|
-
IndexOperation,
|
|
25
|
-
} from "../indexes/base-index.js"
|
|
21
|
+
import type { IndexInterface, IndexOperation } from "../indexes/base-index.js"
|
|
26
22
|
import type { BasicExpression } from "../query/ir.js"
|
|
23
|
+
import type { CollectionLike } from "../types.js"
|
|
27
24
|
|
|
28
25
|
/**
|
|
29
26
|
* Result of index-based query optimization
|
|
@@ -37,16 +34,21 @@ export interface OptimizationResult<TKey> {
|
|
|
37
34
|
* Finds an index that matches a given field path
|
|
38
35
|
*/
|
|
39
36
|
export function findIndexForField<TKey extends string | number>(
|
|
40
|
-
|
|
37
|
+
collection: CollectionLike<any, TKey>,
|
|
41
38
|
fieldPath: Array<string>,
|
|
42
|
-
compareOptions
|
|
39
|
+
compareOptions?: CompareOptions
|
|
43
40
|
): IndexInterface<TKey> | undefined {
|
|
44
|
-
|
|
41
|
+
const compareOpts = compareOptions ?? {
|
|
42
|
+
...DEFAULT_COMPARE_OPTIONS,
|
|
43
|
+
...collection.compareOptions,
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
for (const index of collection.indexes.values()) {
|
|
45
47
|
if (
|
|
46
48
|
index.matchesField(fieldPath) &&
|
|
47
|
-
index.matchesCompareOptions(
|
|
49
|
+
index.matchesCompareOptions(compareOpts)
|
|
48
50
|
) {
|
|
49
|
-
if (!index.matchesDirection(
|
|
51
|
+
if (!index.matchesDirection(compareOpts.direction)) {
|
|
50
52
|
return new ReverseIndex(index)
|
|
51
53
|
}
|
|
52
54
|
return index
|
|
@@ -91,19 +93,22 @@ export function unionSets<T>(sets: Array<Set<T>>): Set<T> {
|
|
|
91
93
|
/**
|
|
92
94
|
* Optimizes a query expression using available indexes to find matching keys
|
|
93
95
|
*/
|
|
94
|
-
export function optimizeExpressionWithIndexes<
|
|
96
|
+
export function optimizeExpressionWithIndexes<
|
|
97
|
+
T extends object,
|
|
98
|
+
TKey extends string | number,
|
|
99
|
+
>(
|
|
95
100
|
expression: BasicExpression,
|
|
96
|
-
|
|
101
|
+
collection: CollectionLike<T, TKey>
|
|
97
102
|
): OptimizationResult<TKey> {
|
|
98
|
-
return optimizeQueryRecursive(expression,
|
|
103
|
+
return optimizeQueryRecursive(expression, collection)
|
|
99
104
|
}
|
|
100
105
|
|
|
101
106
|
/**
|
|
102
107
|
* Recursively optimizes query expressions
|
|
103
108
|
*/
|
|
104
|
-
function optimizeQueryRecursive<TKey extends string | number>(
|
|
109
|
+
function optimizeQueryRecursive<T extends object, TKey extends string | number>(
|
|
105
110
|
expression: BasicExpression,
|
|
106
|
-
|
|
111
|
+
collection: CollectionLike<T, TKey>
|
|
107
112
|
): OptimizationResult<TKey> {
|
|
108
113
|
if (expression.type === `func`) {
|
|
109
114
|
switch (expression.name) {
|
|
@@ -112,16 +117,16 @@ function optimizeQueryRecursive<TKey extends string | number>(
|
|
|
112
117
|
case `gte`:
|
|
113
118
|
case `lt`:
|
|
114
119
|
case `lte`:
|
|
115
|
-
return optimizeSimpleComparison(expression,
|
|
120
|
+
return optimizeSimpleComparison(expression, collection)
|
|
116
121
|
|
|
117
122
|
case `and`:
|
|
118
|
-
return optimizeAndExpression(expression,
|
|
123
|
+
return optimizeAndExpression(expression, collection)
|
|
119
124
|
|
|
120
125
|
case `or`:
|
|
121
|
-
return optimizeOrExpression(expression,
|
|
126
|
+
return optimizeOrExpression(expression, collection)
|
|
122
127
|
|
|
123
128
|
case `in`:
|
|
124
|
-
return optimizeInArrayExpression(expression,
|
|
129
|
+
return optimizeInArrayExpression(expression, collection)
|
|
125
130
|
}
|
|
126
131
|
}
|
|
127
132
|
|
|
@@ -131,10 +136,10 @@ function optimizeQueryRecursive<TKey extends string | number>(
|
|
|
131
136
|
/**
|
|
132
137
|
* Checks if an expression can be optimized
|
|
133
138
|
*/
|
|
134
|
-
export function canOptimizeExpression<
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
): boolean {
|
|
139
|
+
export function canOptimizeExpression<
|
|
140
|
+
T extends object,
|
|
141
|
+
TKey extends string | number,
|
|
142
|
+
>(expression: BasicExpression, collection: CollectionLike<T, TKey>): boolean {
|
|
138
143
|
if (expression.type === `func`) {
|
|
139
144
|
switch (expression.name) {
|
|
140
145
|
case `eq`:
|
|
@@ -142,16 +147,16 @@ export function canOptimizeExpression<TKey extends string | number>(
|
|
|
142
147
|
case `gte`:
|
|
143
148
|
case `lt`:
|
|
144
149
|
case `lte`:
|
|
145
|
-
return canOptimizeSimpleComparison(expression,
|
|
150
|
+
return canOptimizeSimpleComparison(expression, collection)
|
|
146
151
|
|
|
147
152
|
case `and`:
|
|
148
|
-
return canOptimizeAndExpression(expression,
|
|
153
|
+
return canOptimizeAndExpression(expression, collection)
|
|
149
154
|
|
|
150
155
|
case `or`:
|
|
151
|
-
return canOptimizeOrExpression(expression,
|
|
156
|
+
return canOptimizeOrExpression(expression, collection)
|
|
152
157
|
|
|
153
158
|
case `in`:
|
|
154
|
-
return canOptimizeInArrayExpression(expression,
|
|
159
|
+
return canOptimizeInArrayExpression(expression, collection)
|
|
155
160
|
}
|
|
156
161
|
}
|
|
157
162
|
|
|
@@ -162,9 +167,12 @@ export function canOptimizeExpression<TKey extends string | number>(
|
|
|
162
167
|
* Optimizes compound range queries on the same field
|
|
163
168
|
* Example: WHERE age > 5 AND age < 10
|
|
164
169
|
*/
|
|
165
|
-
function optimizeCompoundRangeQuery<
|
|
170
|
+
function optimizeCompoundRangeQuery<
|
|
171
|
+
T extends object,
|
|
172
|
+
TKey extends string | number,
|
|
173
|
+
>(
|
|
166
174
|
expression: BasicExpression,
|
|
167
|
-
|
|
175
|
+
collection: CollectionLike<T, TKey>
|
|
168
176
|
): OptimizationResult<TKey> {
|
|
169
177
|
if (expression.type !== `func` || expression.args.length < 2) {
|
|
170
178
|
return { canOptimize: false, matchingKeys: new Set() }
|
|
@@ -236,7 +244,7 @@ function optimizeCompoundRangeQuery<TKey extends string | number>(
|
|
|
236
244
|
for (const [fieldKey, operations] of fieldOperations) {
|
|
237
245
|
if (operations.length >= 2) {
|
|
238
246
|
const fieldPath = fieldKey.split(`.`)
|
|
239
|
-
const index = findIndexForField(
|
|
247
|
+
const index = findIndexForField(collection, fieldPath)
|
|
240
248
|
|
|
241
249
|
if (index && index.supports(`gt`) && index.supports(`lt`)) {
|
|
242
250
|
// Build range query options
|
|
@@ -292,9 +300,12 @@ function optimizeCompoundRangeQuery<TKey extends string | number>(
|
|
|
292
300
|
/**
|
|
293
301
|
* Optimizes simple comparison expressions (eq, gt, gte, lt, lte)
|
|
294
302
|
*/
|
|
295
|
-
function optimizeSimpleComparison<
|
|
303
|
+
function optimizeSimpleComparison<
|
|
304
|
+
T extends object,
|
|
305
|
+
TKey extends string | number,
|
|
306
|
+
>(
|
|
296
307
|
expression: BasicExpression,
|
|
297
|
-
|
|
308
|
+
collection: CollectionLike<T, TKey>
|
|
298
309
|
): OptimizationResult<TKey> {
|
|
299
310
|
if (expression.type !== `func` || expression.args.length !== 2) {
|
|
300
311
|
return { canOptimize: false, matchingKeys: new Set() }
|
|
@@ -337,7 +348,7 @@ function optimizeSimpleComparison<TKey extends string | number>(
|
|
|
337
348
|
|
|
338
349
|
if (fieldArg && valueArg) {
|
|
339
350
|
const fieldPath = (fieldArg as any).path
|
|
340
|
-
const index = findIndexForField(
|
|
351
|
+
const index = findIndexForField(collection, fieldPath)
|
|
341
352
|
|
|
342
353
|
if (index) {
|
|
343
354
|
const queryValue = (valueArg as any).value
|
|
@@ -361,10 +372,10 @@ function optimizeSimpleComparison<TKey extends string | number>(
|
|
|
361
372
|
/**
|
|
362
373
|
* Checks if a simple comparison can be optimized
|
|
363
374
|
*/
|
|
364
|
-
function canOptimizeSimpleComparison<
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
): boolean {
|
|
375
|
+
function canOptimizeSimpleComparison<
|
|
376
|
+
T extends object,
|
|
377
|
+
TKey extends string | number,
|
|
378
|
+
>(expression: BasicExpression, collection: CollectionLike<T, TKey>): boolean {
|
|
368
379
|
if (expression.type !== `func` || expression.args.length !== 2) {
|
|
369
380
|
return false
|
|
370
381
|
}
|
|
@@ -382,7 +393,7 @@ function canOptimizeSimpleComparison<TKey extends string | number>(
|
|
|
382
393
|
}
|
|
383
394
|
|
|
384
395
|
if (fieldPath) {
|
|
385
|
-
const index = findIndexForField(
|
|
396
|
+
const index = findIndexForField(collection, fieldPath)
|
|
386
397
|
return index !== undefined
|
|
387
398
|
}
|
|
388
399
|
|
|
@@ -392,16 +403,16 @@ function canOptimizeSimpleComparison<TKey extends string | number>(
|
|
|
392
403
|
/**
|
|
393
404
|
* Optimizes AND expressions
|
|
394
405
|
*/
|
|
395
|
-
function optimizeAndExpression<TKey extends string | number>(
|
|
406
|
+
function optimizeAndExpression<T extends object, TKey extends string | number>(
|
|
396
407
|
expression: BasicExpression,
|
|
397
|
-
|
|
408
|
+
collection: CollectionLike<T, TKey>
|
|
398
409
|
): OptimizationResult<TKey> {
|
|
399
410
|
if (expression.type !== `func` || expression.args.length < 2) {
|
|
400
411
|
return { canOptimize: false, matchingKeys: new Set() }
|
|
401
412
|
}
|
|
402
413
|
|
|
403
414
|
// First, try to optimize compound range queries on the same field
|
|
404
|
-
const compoundRangeResult = optimizeCompoundRangeQuery(expression,
|
|
415
|
+
const compoundRangeResult = optimizeCompoundRangeQuery(expression, collection)
|
|
405
416
|
if (compoundRangeResult.canOptimize) {
|
|
406
417
|
return compoundRangeResult
|
|
407
418
|
}
|
|
@@ -410,7 +421,7 @@ function optimizeAndExpression<TKey extends string | number>(
|
|
|
410
421
|
|
|
411
422
|
// Try to optimize each part, keep the optimizable ones
|
|
412
423
|
for (const arg of expression.args) {
|
|
413
|
-
const result = optimizeQueryRecursive(arg,
|
|
424
|
+
const result = optimizeQueryRecursive(arg, collection)
|
|
414
425
|
if (result.canOptimize) {
|
|
415
426
|
results.push(result)
|
|
416
427
|
}
|
|
@@ -429,24 +440,24 @@ function optimizeAndExpression<TKey extends string | number>(
|
|
|
429
440
|
/**
|
|
430
441
|
* Checks if an AND expression can be optimized
|
|
431
442
|
*/
|
|
432
|
-
function canOptimizeAndExpression<
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
): boolean {
|
|
443
|
+
function canOptimizeAndExpression<
|
|
444
|
+
T extends object,
|
|
445
|
+
TKey extends string | number,
|
|
446
|
+
>(expression: BasicExpression, collection: CollectionLike<T, TKey>): boolean {
|
|
436
447
|
if (expression.type !== `func` || expression.args.length < 2) {
|
|
437
448
|
return false
|
|
438
449
|
}
|
|
439
450
|
|
|
440
451
|
// If any argument can be optimized, we can gain some speedup
|
|
441
|
-
return expression.args.some((arg) => canOptimizeExpression(arg,
|
|
452
|
+
return expression.args.some((arg) => canOptimizeExpression(arg, collection))
|
|
442
453
|
}
|
|
443
454
|
|
|
444
455
|
/**
|
|
445
456
|
* Optimizes OR expressions
|
|
446
457
|
*/
|
|
447
|
-
function optimizeOrExpression<TKey extends string | number>(
|
|
458
|
+
function optimizeOrExpression<T extends object, TKey extends string | number>(
|
|
448
459
|
expression: BasicExpression,
|
|
449
|
-
|
|
460
|
+
collection: CollectionLike<T, TKey>
|
|
450
461
|
): OptimizationResult<TKey> {
|
|
451
462
|
if (expression.type !== `func` || expression.args.length < 2) {
|
|
452
463
|
return { canOptimize: false, matchingKeys: new Set() }
|
|
@@ -456,7 +467,7 @@ function optimizeOrExpression<TKey extends string | number>(
|
|
|
456
467
|
|
|
457
468
|
// Try to optimize each part, keep the optimizable ones
|
|
458
469
|
for (const arg of expression.args) {
|
|
459
|
-
const result = optimizeQueryRecursive(arg,
|
|
470
|
+
const result = optimizeQueryRecursive(arg, collection)
|
|
460
471
|
if (result.canOptimize) {
|
|
461
472
|
results.push(result)
|
|
462
473
|
}
|
|
@@ -475,24 +486,27 @@ function optimizeOrExpression<TKey extends string | number>(
|
|
|
475
486
|
/**
|
|
476
487
|
* Checks if an OR expression can be optimized
|
|
477
488
|
*/
|
|
478
|
-
function canOptimizeOrExpression<
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
): boolean {
|
|
489
|
+
function canOptimizeOrExpression<
|
|
490
|
+
T extends object,
|
|
491
|
+
TKey extends string | number,
|
|
492
|
+
>(expression: BasicExpression, collection: CollectionLike<T, TKey>): boolean {
|
|
482
493
|
if (expression.type !== `func` || expression.args.length < 2) {
|
|
483
494
|
return false
|
|
484
495
|
}
|
|
485
496
|
|
|
486
497
|
// If any argument can be optimized, we can gain some speedup
|
|
487
|
-
return expression.args.some((arg) => canOptimizeExpression(arg,
|
|
498
|
+
return expression.args.some((arg) => canOptimizeExpression(arg, collection))
|
|
488
499
|
}
|
|
489
500
|
|
|
490
501
|
/**
|
|
491
502
|
* Optimizes IN array expressions
|
|
492
503
|
*/
|
|
493
|
-
function optimizeInArrayExpression<
|
|
504
|
+
function optimizeInArrayExpression<
|
|
505
|
+
T extends object,
|
|
506
|
+
TKey extends string | number,
|
|
507
|
+
>(
|
|
494
508
|
expression: BasicExpression,
|
|
495
|
-
|
|
509
|
+
collection: CollectionLike<T, TKey>
|
|
496
510
|
): OptimizationResult<TKey> {
|
|
497
511
|
if (expression.type !== `func` || expression.args.length !== 2) {
|
|
498
512
|
return { canOptimize: false, matchingKeys: new Set() }
|
|
@@ -508,7 +522,7 @@ function optimizeInArrayExpression<TKey extends string | number>(
|
|
|
508
522
|
) {
|
|
509
523
|
const fieldPath = (fieldArg as any).path
|
|
510
524
|
const values = (arrayArg as any).value
|
|
511
|
-
const index = findIndexForField(
|
|
525
|
+
const index = findIndexForField(collection, fieldPath)
|
|
512
526
|
|
|
513
527
|
if (index) {
|
|
514
528
|
// Check if the index supports IN operation
|
|
@@ -535,10 +549,10 @@ function optimizeInArrayExpression<TKey extends string | number>(
|
|
|
535
549
|
/**
|
|
536
550
|
* Checks if an IN array expression can be optimized
|
|
537
551
|
*/
|
|
538
|
-
function canOptimizeInArrayExpression<
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
): boolean {
|
|
552
|
+
function canOptimizeInArrayExpression<
|
|
553
|
+
T extends object,
|
|
554
|
+
TKey extends string | number,
|
|
555
|
+
>(expression: BasicExpression, collection: CollectionLike<T, TKey>): boolean {
|
|
542
556
|
if (expression.type !== `func` || expression.args.length !== 2) {
|
|
543
557
|
return false
|
|
544
558
|
}
|
|
@@ -552,7 +566,7 @@ function canOptimizeInArrayExpression<TKey extends string | number>(
|
|
|
552
566
|
Array.isArray((arrayArg as any).value)
|
|
553
567
|
) {
|
|
554
568
|
const fieldPath = (fieldArg as any).path
|
|
555
|
-
const index = findIndexForField(
|
|
569
|
+
const index = findIndexForField(collection, fieldPath)
|
|
556
570
|
return index !== undefined
|
|
557
571
|
}
|
|
558
572
|
|