@tanstack/db 0.5.11 → 0.5.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/SortedMap.cjs +40 -26
- package/dist/cjs/SortedMap.cjs.map +1 -1
- package/dist/cjs/SortedMap.d.cts +10 -15
- package/dist/cjs/collection/change-events.cjs.map +1 -1
- package/dist/cjs/collection/changes.cjs +2 -0
- package/dist/cjs/collection/changes.cjs.map +1 -1
- package/dist/cjs/collection/events.cjs.map +1 -1
- package/dist/cjs/collection/events.d.cts +12 -4
- package/dist/cjs/collection/index.cjs +2 -1
- package/dist/cjs/collection/index.cjs.map +1 -1
- package/dist/cjs/collection/indexes.cjs.map +1 -1
- package/dist/cjs/collection/lifecycle.cjs.map +1 -1
- package/dist/cjs/collection/mutations.cjs +5 -2
- package/dist/cjs/collection/mutations.cjs.map +1 -1
- package/dist/cjs/collection/state.cjs +6 -5
- package/dist/cjs/collection/state.cjs.map +1 -1
- package/dist/cjs/collection/state.d.cts +4 -1
- package/dist/cjs/collection/subscription.cjs +91 -57
- package/dist/cjs/collection/subscription.cjs.map +1 -1
- package/dist/cjs/collection/subscription.d.cts +26 -4
- package/dist/cjs/collection/sync.cjs +11 -6
- package/dist/cjs/collection/sync.cjs.map +1 -1
- package/dist/cjs/errors.cjs +9 -0
- package/dist/cjs/errors.cjs.map +1 -1
- package/dist/cjs/errors.d.cts +3 -0
- package/dist/cjs/event-emitter.cjs.map +1 -1
- package/dist/cjs/index.cjs +2 -0
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.cts +1 -1
- package/dist/cjs/indexes/auto-index.cjs.map +1 -1
- package/dist/cjs/indexes/base-index.cjs.map +1 -1
- package/dist/cjs/indexes/btree-index.cjs +8 -6
- package/dist/cjs/indexes/btree-index.cjs.map +1 -1
- package/dist/cjs/indexes/lazy-index.cjs.map +1 -1
- package/dist/cjs/indexes/reverse-index.cjs.map +1 -1
- package/dist/cjs/local-only.cjs.map +1 -1
- package/dist/cjs/local-storage.cjs.map +1 -1
- package/dist/cjs/optimistic-action.cjs.map +1 -1
- package/dist/cjs/paced-mutations.cjs.map +1 -1
- package/dist/cjs/proxy.cjs.map +1 -1
- package/dist/cjs/query/builder/functions.cjs.map +1 -1
- package/dist/cjs/query/builder/index.cjs.map +1 -1
- package/dist/cjs/query/builder/ref-proxy.cjs.map +1 -1
- package/dist/cjs/query/compiler/evaluators.cjs.map +1 -1
- package/dist/cjs/query/compiler/expressions.cjs.map +1 -1
- package/dist/cjs/query/compiler/group-by.cjs.map +1 -1
- package/dist/cjs/query/compiler/index.cjs.map +1 -1
- package/dist/cjs/query/compiler/joins.cjs.map +1 -1
- package/dist/cjs/query/compiler/order-by.cjs +91 -38
- package/dist/cjs/query/compiler/order-by.cjs.map +1 -1
- package/dist/cjs/query/compiler/order-by.d.cts +6 -2
- package/dist/cjs/query/compiler/select.cjs.map +1 -1
- package/dist/cjs/query/expression-helpers.cjs.map +1 -1
- package/dist/cjs/query/index.d.cts +1 -1
- package/dist/cjs/query/ir.cjs.map +1 -1
- package/dist/cjs/query/live/collection-config-builder.cjs.map +1 -1
- package/dist/cjs/query/live/collection-registry.cjs.map +1 -1
- package/dist/cjs/query/live/collection-subscriber.cjs +30 -15
- package/dist/cjs/query/live/collection-subscriber.cjs.map +1 -1
- package/dist/cjs/query/live/internal.cjs.map +1 -1
- package/dist/cjs/query/live-query-collection.cjs.map +1 -1
- package/dist/cjs/query/optimizer.cjs.map +1 -1
- package/dist/cjs/query/predicate-utils.cjs +19 -2
- package/dist/cjs/query/predicate-utils.cjs.map +1 -1
- package/dist/cjs/query/predicate-utils.d.cts +32 -1
- package/dist/cjs/query/subset-dedupe.cjs.map +1 -1
- package/dist/cjs/scheduler.cjs.map +1 -1
- package/dist/cjs/strategies/debounceStrategy.cjs.map +1 -1
- package/dist/cjs/strategies/queueStrategy.cjs.map +1 -1
- package/dist/cjs/strategies/throttleStrategy.cjs.map +1 -1
- package/dist/cjs/transactions.cjs.map +1 -1
- package/dist/cjs/types.d.cts +53 -8
- package/dist/cjs/utils/browser-polyfills.cjs.map +1 -1
- package/dist/cjs/utils/btree.cjs.map +1 -1
- package/dist/cjs/utils/comparison.cjs.map +1 -1
- package/dist/cjs/utils/cursor.cjs +39 -0
- package/dist/cjs/utils/cursor.cjs.map +1 -0
- package/dist/cjs/utils/cursor.d.cts +18 -0
- package/dist/cjs/utils/index-optimization.cjs.map +1 -1
- package/dist/cjs/utils.cjs.map +1 -1
- package/dist/esm/SortedMap.d.ts +10 -15
- package/dist/esm/SortedMap.js +40 -26
- package/dist/esm/SortedMap.js.map +1 -1
- package/dist/esm/collection/change-events.js.map +1 -1
- package/dist/esm/collection/changes.js +2 -0
- package/dist/esm/collection/changes.js.map +1 -1
- package/dist/esm/collection/events.d.ts +12 -4
- package/dist/esm/collection/events.js.map +1 -1
- package/dist/esm/collection/index.js +2 -1
- package/dist/esm/collection/index.js.map +1 -1
- package/dist/esm/collection/indexes.js.map +1 -1
- package/dist/esm/collection/lifecycle.js.map +1 -1
- package/dist/esm/collection/mutations.js +6 -3
- package/dist/esm/collection/mutations.js.map +1 -1
- package/dist/esm/collection/state.d.ts +4 -1
- package/dist/esm/collection/state.js +6 -5
- package/dist/esm/collection/state.js.map +1 -1
- package/dist/esm/collection/subscription.d.ts +26 -4
- package/dist/esm/collection/subscription.js +92 -58
- package/dist/esm/collection/subscription.js.map +1 -1
- package/dist/esm/collection/sync.js +11 -6
- package/dist/esm/collection/sync.js.map +1 -1
- package/dist/esm/errors.d.ts +3 -0
- package/dist/esm/errors.js +9 -0
- package/dist/esm/errors.js.map +1 -1
- package/dist/esm/event-emitter.js.map +1 -1
- package/dist/esm/index.d.ts +1 -1
- package/dist/esm/index.js +4 -2
- package/dist/esm/indexes/auto-index.js.map +1 -1
- package/dist/esm/indexes/base-index.js.map +1 -1
- package/dist/esm/indexes/btree-index.js +8 -6
- package/dist/esm/indexes/btree-index.js.map +1 -1
- package/dist/esm/indexes/lazy-index.js.map +1 -1
- package/dist/esm/indexes/reverse-index.js.map +1 -1
- package/dist/esm/local-only.js.map +1 -1
- package/dist/esm/local-storage.js.map +1 -1
- package/dist/esm/optimistic-action.js.map +1 -1
- package/dist/esm/paced-mutations.js.map +1 -1
- package/dist/esm/proxy.js.map +1 -1
- package/dist/esm/query/builder/functions.js.map +1 -1
- package/dist/esm/query/builder/index.js.map +1 -1
- package/dist/esm/query/builder/ref-proxy.js.map +1 -1
- package/dist/esm/query/compiler/evaluators.js.map +1 -1
- package/dist/esm/query/compiler/expressions.js.map +1 -1
- package/dist/esm/query/compiler/group-by.js.map +1 -1
- package/dist/esm/query/compiler/index.js.map +1 -1
- package/dist/esm/query/compiler/joins.js.map +1 -1
- package/dist/esm/query/compiler/order-by.d.ts +6 -2
- package/dist/esm/query/compiler/order-by.js +91 -38
- package/dist/esm/query/compiler/order-by.js.map +1 -1
- package/dist/esm/query/compiler/select.js.map +1 -1
- package/dist/esm/query/expression-helpers.js.map +1 -1
- package/dist/esm/query/index.d.ts +1 -1
- package/dist/esm/query/ir.js.map +1 -1
- package/dist/esm/query/live/collection-config-builder.js.map +1 -1
- package/dist/esm/query/live/collection-registry.js.map +1 -1
- package/dist/esm/query/live/collection-subscriber.js +30 -15
- package/dist/esm/query/live/collection-subscriber.js.map +1 -1
- package/dist/esm/query/live/internal.js.map +1 -1
- package/dist/esm/query/live-query-collection.js.map +1 -1
- package/dist/esm/query/optimizer.js.map +1 -1
- package/dist/esm/query/predicate-utils.d.ts +32 -1
- package/dist/esm/query/predicate-utils.js +19 -2
- package/dist/esm/query/predicate-utils.js.map +1 -1
- package/dist/esm/query/subset-dedupe.js.map +1 -1
- package/dist/esm/scheduler.js.map +1 -1
- package/dist/esm/strategies/debounceStrategy.js.map +1 -1
- package/dist/esm/strategies/queueStrategy.js.map +1 -1
- package/dist/esm/strategies/throttleStrategy.js.map +1 -1
- package/dist/esm/transactions.js.map +1 -1
- package/dist/esm/types.d.ts +53 -8
- package/dist/esm/utils/browser-polyfills.js.map +1 -1
- package/dist/esm/utils/btree.js.map +1 -1
- package/dist/esm/utils/comparison.js.map +1 -1
- package/dist/esm/utils/cursor.d.ts +18 -0
- package/dist/esm/utils/cursor.js +39 -0
- package/dist/esm/utils/cursor.js.map +1 -0
- package/dist/esm/utils/index-optimization.js.map +1 -1
- package/dist/esm/utils.js.map +1 -1
- package/package.json +30 -28
- package/src/SortedMap.ts +50 -31
- package/src/collection/change-events.ts +20 -20
- package/src/collection/changes.ts +16 -12
- package/src/collection/events.ts +20 -10
- package/src/collection/index.ts +47 -46
- package/src/collection/indexes.ts +14 -14
- package/src/collection/lifecycle.ts +16 -16
- package/src/collection/mutations.ts +25 -20
- package/src/collection/state.ts +43 -36
- package/src/collection/subscription.ts +171 -90
- package/src/collection/sync.ts +34 -22
- package/src/duplicate-instance-check.ts +1 -1
- package/src/errors.ts +49 -40
- package/src/event-emitter.ts +5 -5
- package/src/index.ts +21 -21
- package/src/indexes/auto-index.ts +11 -11
- package/src/indexes/base-index.ts +13 -13
- package/src/indexes/btree-index.ts +21 -17
- package/src/indexes/index-options.ts +3 -3
- package/src/indexes/lazy-index.ts +8 -8
- package/src/indexes/reverse-index.ts +5 -5
- package/src/local-only.ts +12 -12
- package/src/local-storage.ts +17 -17
- package/src/optimistic-action.ts +5 -5
- package/src/paced-mutations.ts +6 -6
- package/src/proxy.ts +43 -43
- package/src/query/builder/functions.ts +28 -28
- package/src/query/builder/index.ts +22 -22
- package/src/query/builder/ref-proxy.ts +4 -4
- package/src/query/builder/types.ts +8 -8
- package/src/query/compiler/evaluators.ts +9 -9
- package/src/query/compiler/expressions.ts +6 -6
- package/src/query/compiler/group-by.ts +24 -24
- package/src/query/compiler/index.ts +44 -44
- package/src/query/compiler/joins.ts +37 -37
- package/src/query/compiler/order-by.ts +170 -77
- package/src/query/compiler/select.ts +13 -13
- package/src/query/compiler/types.ts +2 -2
- package/src/query/expression-helpers.ts +16 -16
- package/src/query/index.ts +10 -9
- package/src/query/ir.ts +13 -13
- package/src/query/live/collection-config-builder.ts +53 -53
- package/src/query/live/collection-registry.ts +6 -6
- package/src/query/live/collection-subscriber.ts +87 -48
- package/src/query/live/internal.ts +1 -1
- package/src/query/live/types.ts +4 -4
- package/src/query/live-query-collection.ts +15 -15
- package/src/query/optimizer.ts +29 -29
- package/src/query/predicate-utils.ts +105 -50
- package/src/query/subset-dedupe.ts +6 -6
- package/src/scheduler.ts +3 -3
- package/src/strategies/debounceStrategy.ts +6 -6
- package/src/strategies/index.ts +4 -4
- package/src/strategies/queueStrategy.ts +5 -5
- package/src/strategies/throttleStrategy.ts +6 -6
- package/src/strategies/types.ts +2 -2
- package/src/transactions.ts +9 -9
- package/src/types.ts +76 -18
- package/src/utils/array-utils.ts +1 -1
- package/src/utils/browser-polyfills.ts +2 -2
- package/src/utils/btree.ts +22 -22
- package/src/utils/comparison.ts +3 -3
- package/src/utils/cursor.ts +78 -0
- package/src/utils/index-optimization.ts +14 -14
- package/src/utils.ts +4 -4
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CollectionImpl } from
|
|
1
|
+
import { CollectionImpl } from '../../collection/index.js'
|
|
2
2
|
import {
|
|
3
3
|
Aggregate as AggregateExpr,
|
|
4
4
|
CollectionRef,
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
QueryRef,
|
|
8
8
|
Value as ValueExpr,
|
|
9
9
|
isExpressionLike,
|
|
10
|
-
} from
|
|
10
|
+
} from '../ir.js'
|
|
11
11
|
import {
|
|
12
12
|
InvalidSourceError,
|
|
13
13
|
InvalidSourceTypeError,
|
|
@@ -15,9 +15,9 @@ import {
|
|
|
15
15
|
OnlyOneSourceAllowedError,
|
|
16
16
|
QueryMustHaveFromClauseError,
|
|
17
17
|
SubQueryMustHaveFromClauseError,
|
|
18
|
-
} from
|
|
19
|
-
import { createRefProxy, toExpression } from
|
|
20
|
-
import type { NamespacedRow, SingleResult } from
|
|
18
|
+
} from '../../errors.js'
|
|
19
|
+
import { createRefProxy, toExpression } from './ref-proxy.js'
|
|
20
|
+
import type { NamespacedRow, SingleResult } from '../../types.js'
|
|
21
21
|
import type {
|
|
22
22
|
Aggregate,
|
|
23
23
|
BasicExpression,
|
|
@@ -25,7 +25,7 @@ import type {
|
|
|
25
25
|
OrderBy,
|
|
26
26
|
OrderByDirection,
|
|
27
27
|
QueryIR,
|
|
28
|
-
} from
|
|
28
|
+
} from '../ir.js'
|
|
29
29
|
import type {
|
|
30
30
|
CompareOptions,
|
|
31
31
|
Context,
|
|
@@ -42,7 +42,7 @@ import type {
|
|
|
42
42
|
Source,
|
|
43
43
|
WhereCallback,
|
|
44
44
|
WithResult,
|
|
45
|
-
} from
|
|
45
|
+
} from './types.js'
|
|
46
46
|
|
|
47
47
|
export class BaseQueryBuilder<TContext extends Context = Context> {
|
|
48
48
|
private readonly query: Partial<QueryIR> = {}
|
|
@@ -59,7 +59,7 @@ export class BaseQueryBuilder<TContext extends Context = Context> {
|
|
|
59
59
|
*/
|
|
60
60
|
private _createRefForSource<TSource extends Source>(
|
|
61
61
|
source: TSource,
|
|
62
|
-
context: string
|
|
62
|
+
context: string,
|
|
63
63
|
): [string, CollectionRef | QueryRef] {
|
|
64
64
|
// Validate source is a plain object (not null, array, string, etc.)
|
|
65
65
|
// We use try-catch to handle null/undefined gracefully
|
|
@@ -127,7 +127,7 @@ export class BaseQueryBuilder<TContext extends Context = Context> {
|
|
|
127
127
|
* ```
|
|
128
128
|
*/
|
|
129
129
|
from<TSource extends Source>(
|
|
130
|
-
source: TSource
|
|
130
|
+
source: TSource,
|
|
131
131
|
): QueryBuilder<{
|
|
132
132
|
baseSchema: SchemaFromSource<TSource>
|
|
133
133
|
schema: SchemaFromSource<TSource>
|
|
@@ -177,7 +177,7 @@ export class BaseQueryBuilder<TContext extends Context = Context> {
|
|
|
177
177
|
onCallback: JoinOnCallback<
|
|
178
178
|
MergeContextForJoinCallback<TContext, SchemaFromSource<TSource>>
|
|
179
179
|
>,
|
|
180
|
-
type: TJoinType = `left` as TJoinType
|
|
180
|
+
type: TJoinType = `left` as TJoinType,
|
|
181
181
|
): QueryBuilder<
|
|
182
182
|
MergeContextWithJoinType<TContext, SchemaFromSource<TSource>, TJoinType>
|
|
183
183
|
> {
|
|
@@ -243,7 +243,7 @@ export class BaseQueryBuilder<TContext extends Context = Context> {
|
|
|
243
243
|
source: TSource,
|
|
244
244
|
onCallback: JoinOnCallback<
|
|
245
245
|
MergeContextForJoinCallback<TContext, SchemaFromSource<TSource>>
|
|
246
|
-
|
|
246
|
+
>,
|
|
247
247
|
): QueryBuilder<
|
|
248
248
|
MergeContextWithJoinType<TContext, SchemaFromSource<TSource>, `left`>
|
|
249
249
|
> {
|
|
@@ -269,7 +269,7 @@ export class BaseQueryBuilder<TContext extends Context = Context> {
|
|
|
269
269
|
source: TSource,
|
|
270
270
|
onCallback: JoinOnCallback<
|
|
271
271
|
MergeContextForJoinCallback<TContext, SchemaFromSource<TSource>>
|
|
272
|
-
|
|
272
|
+
>,
|
|
273
273
|
): QueryBuilder<
|
|
274
274
|
MergeContextWithJoinType<TContext, SchemaFromSource<TSource>, `right`>
|
|
275
275
|
> {
|
|
@@ -295,7 +295,7 @@ export class BaseQueryBuilder<TContext extends Context = Context> {
|
|
|
295
295
|
source: TSource,
|
|
296
296
|
onCallback: JoinOnCallback<
|
|
297
297
|
MergeContextForJoinCallback<TContext, SchemaFromSource<TSource>>
|
|
298
|
-
|
|
298
|
+
>,
|
|
299
299
|
): QueryBuilder<
|
|
300
300
|
MergeContextWithJoinType<TContext, SchemaFromSource<TSource>, `inner`>
|
|
301
301
|
> {
|
|
@@ -321,7 +321,7 @@ export class BaseQueryBuilder<TContext extends Context = Context> {
|
|
|
321
321
|
source: TSource,
|
|
322
322
|
onCallback: JoinOnCallback<
|
|
323
323
|
MergeContextForJoinCallback<TContext, SchemaFromSource<TSource>>
|
|
324
|
-
|
|
324
|
+
>,
|
|
325
325
|
): QueryBuilder<
|
|
326
326
|
MergeContextWithJoinType<TContext, SchemaFromSource<TSource>, `full`>
|
|
327
327
|
> {
|
|
@@ -445,7 +445,7 @@ export class BaseQueryBuilder<TContext extends Context = Context> {
|
|
|
445
445
|
* ```
|
|
446
446
|
*/
|
|
447
447
|
select<TSelectObject extends SelectObject>(
|
|
448
|
-
callback: (refs: RefsForContext<TContext>) => TSelectObject
|
|
448
|
+
callback: (refs: RefsForContext<TContext>) => TSelectObject,
|
|
449
449
|
): QueryBuilder<WithResult<TContext, ResultTypeFromSelect<TSelectObject>>> {
|
|
450
450
|
const aliases = this._getCurrentAliases()
|
|
451
451
|
const refProxy = createRefProxy(aliases) as RefsForContext<TContext>
|
|
@@ -487,7 +487,7 @@ export class BaseQueryBuilder<TContext extends Context = Context> {
|
|
|
487
487
|
*/
|
|
488
488
|
orderBy(
|
|
489
489
|
callback: OrderByCallback<TContext>,
|
|
490
|
-
options: OrderByDirection | OrderByOptions = `asc
|
|
490
|
+
options: OrderByDirection | OrderByOptions = `asc`,
|
|
491
491
|
): QueryBuilder<TContext> {
|
|
492
492
|
const aliases = this._getCurrentAliases()
|
|
493
493
|
const refProxy = createRefProxy(aliases) as RefsForContext<TContext>
|
|
@@ -717,7 +717,7 @@ export class BaseQueryBuilder<TContext extends Context = Context> {
|
|
|
717
717
|
* ```
|
|
718
718
|
*/
|
|
719
719
|
select<TFuncSelectResult>(
|
|
720
|
-
callback: (row: TContext[`schema`]) => TFuncSelectResult
|
|
720
|
+
callback: (row: TContext[`schema`]) => TFuncSelectResult,
|
|
721
721
|
): QueryBuilder<WithResult<TContext, TFuncSelectResult>> {
|
|
722
722
|
return new BaseQueryBuilder({
|
|
723
723
|
...builder.query,
|
|
@@ -741,7 +741,7 @@ export class BaseQueryBuilder<TContext extends Context = Context> {
|
|
|
741
741
|
* ```
|
|
742
742
|
*/
|
|
743
743
|
where(
|
|
744
|
-
callback: (row: TContext[`schema`]) => any
|
|
744
|
+
callback: (row: TContext[`schema`]) => any,
|
|
745
745
|
): QueryBuilder<TContext> {
|
|
746
746
|
return new BaseQueryBuilder({
|
|
747
747
|
...builder.query,
|
|
@@ -768,7 +768,7 @@ export class BaseQueryBuilder<TContext extends Context = Context> {
|
|
|
768
768
|
* ```
|
|
769
769
|
*/
|
|
770
770
|
having(
|
|
771
|
-
callback: (row: TContext[`schema`]) => any
|
|
771
|
+
callback: (row: TContext[`schema`]) => any,
|
|
772
772
|
): QueryBuilder<TContext> {
|
|
773
773
|
return new BaseQueryBuilder({
|
|
774
774
|
...builder.query,
|
|
@@ -829,7 +829,7 @@ function buildNestedSelect(obj: any): any {
|
|
|
829
829
|
// Internal function to build a query from a callback
|
|
830
830
|
// used by liveQueryCollectionOptions.query
|
|
831
831
|
export function buildQuery<TContext extends Context>(
|
|
832
|
-
fn: (builder: InitialQueryBuilder) => QueryBuilder<TContext
|
|
832
|
+
fn: (builder: InitialQueryBuilder) => QueryBuilder<TContext>,
|
|
833
833
|
): QueryIR {
|
|
834
834
|
const result = fn(new BaseQueryBuilder())
|
|
835
835
|
return getQueryIR(result)
|
|
@@ -837,7 +837,7 @@ export function buildQuery<TContext extends Context>(
|
|
|
837
837
|
|
|
838
838
|
// Internal function to get the QueryIR from a builder
|
|
839
839
|
export function getQueryIR(
|
|
840
|
-
builder: BaseQueryBuilder | QueryBuilder<any> | InitialQueryBuilder
|
|
840
|
+
builder: BaseQueryBuilder | QueryBuilder<any> | InitialQueryBuilder,
|
|
841
841
|
): QueryIR {
|
|
842
842
|
return (builder as unknown as BaseQueryBuilder)._getQuery()
|
|
843
843
|
}
|
|
@@ -871,4 +871,4 @@ export type {
|
|
|
871
871
|
GetResult,
|
|
872
872
|
RefLeaf as Ref,
|
|
873
873
|
InferResultType,
|
|
874
|
-
} from
|
|
874
|
+
} from './types.js'
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { PropRef, Value } from
|
|
2
|
-
import type { BasicExpression } from
|
|
3
|
-
import type { RefLeaf } from
|
|
1
|
+
import { PropRef, Value } from '../ir.js'
|
|
2
|
+
import type { BasicExpression } from '../ir.js'
|
|
3
|
+
import type { RefLeaf } from './types.js'
|
|
4
4
|
|
|
5
5
|
export interface RefProxy<T = any> {
|
|
6
6
|
/** @internal */
|
|
@@ -81,7 +81,7 @@ export function createSingleRowRefProxy<
|
|
|
81
81
|
* Used in callbacks like where, select, etc. to create type-safe references
|
|
82
82
|
*/
|
|
83
83
|
export function createRefProxy<T extends Record<string, any>>(
|
|
84
|
-
aliases: Array<string
|
|
84
|
+
aliases: Array<string>,
|
|
85
85
|
): RefProxy<T> & T {
|
|
86
86
|
const cache = new Map<string, any>()
|
|
87
87
|
let accessId = 0 // Monotonic counter to record evaluation order
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { CollectionImpl } from
|
|
2
|
-
import type { SingleResult, StringCollationConfig } from
|
|
1
|
+
import type { CollectionImpl } from '../../collection/index.js'
|
|
2
|
+
import type { SingleResult, StringCollationConfig } from '../../types.js'
|
|
3
3
|
import type {
|
|
4
4
|
Aggregate,
|
|
5
5
|
BasicExpression,
|
|
@@ -7,8 +7,8 @@ import type {
|
|
|
7
7
|
OrderByDirection,
|
|
8
8
|
PropRef,
|
|
9
9
|
Value,
|
|
10
|
-
} from
|
|
11
|
-
import type { QueryBuilder } from
|
|
10
|
+
} from '../ir.js'
|
|
11
|
+
import type { QueryBuilder } from './index.js'
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* Context - The central state container for query builder operations
|
|
@@ -121,7 +121,7 @@ export type GetAliases<TContext extends Context> = keyof TContext[`schema`]
|
|
|
121
121
|
* Example: `(refs) => eq(refs.users.age, 25)`
|
|
122
122
|
*/
|
|
123
123
|
export type WhereCallback<TContext extends Context> = (
|
|
124
|
-
refs: RefsForContext<TContext
|
|
124
|
+
refs: RefsForContext<TContext>,
|
|
125
125
|
) => any
|
|
126
126
|
|
|
127
127
|
/**
|
|
@@ -290,7 +290,7 @@ type NeedsExtraction<T> = T extends
|
|
|
290
290
|
* Example: `(refs) => refs.users.createdAt`
|
|
291
291
|
*/
|
|
292
292
|
export type OrderByCallback<TContext extends Context> = (
|
|
293
|
-
refs: RefsForContext<TContext
|
|
293
|
+
refs: RefsForContext<TContext>,
|
|
294
294
|
) => any
|
|
295
295
|
|
|
296
296
|
/**
|
|
@@ -326,7 +326,7 @@ export type CompareOptions = StringCollationConfig & {
|
|
|
326
326
|
* Example: `(refs) => refs.orders.status`
|
|
327
327
|
*/
|
|
328
328
|
export type GroupByCallback<TContext extends Context> = (
|
|
329
|
-
refs: RefsForContext<TContext
|
|
329
|
+
refs: RefsForContext<TContext>,
|
|
330
330
|
) => any
|
|
331
331
|
|
|
332
332
|
/**
|
|
@@ -342,7 +342,7 @@ export type GroupByCallback<TContext extends Context> = (
|
|
|
342
342
|
* Example: `(refs) => eq(refs.users.id, refs.orders.userId)`
|
|
343
343
|
*/
|
|
344
344
|
export type JoinOnCallback<TContext extends Context> = (
|
|
345
|
-
refs: RefsForContext<TContext
|
|
345
|
+
refs: RefsForContext<TContext>,
|
|
346
346
|
) => any
|
|
347
347
|
|
|
348
348
|
/**
|
|
@@ -2,10 +2,10 @@ import {
|
|
|
2
2
|
EmptyReferencePathError,
|
|
3
3
|
UnknownExpressionTypeError,
|
|
4
4
|
UnknownFunctionError,
|
|
5
|
-
} from
|
|
6
|
-
import { areValuesEqual, normalizeValue } from
|
|
7
|
-
import type { BasicExpression, Func, PropRef } from
|
|
8
|
-
import type { NamespacedRow } from
|
|
5
|
+
} from '../../errors.js'
|
|
6
|
+
import { areValuesEqual, normalizeValue } from '../../utils/comparison.js'
|
|
7
|
+
import type { BasicExpression, Func, PropRef } from '../ir.js'
|
|
8
|
+
import type { NamespacedRow } from '../../types.js'
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* Helper function to check if a value is null or undefined (represents UNKNOWN in 3-valued logic)
|
|
@@ -46,7 +46,7 @@ export type CompiledSingleRowExpression = (item: Record<string, unknown>) => any
|
|
|
46
46
|
*/
|
|
47
47
|
export function compileExpression(
|
|
48
48
|
expr: BasicExpression,
|
|
49
|
-
isSingleRow: boolean = false
|
|
49
|
+
isSingleRow: boolean = false,
|
|
50
50
|
): CompiledExpression | CompiledSingleRowExpression {
|
|
51
51
|
const compiledFn = compileExpressionInternal(expr, isSingleRow)
|
|
52
52
|
return compiledFn
|
|
@@ -56,7 +56,7 @@ export function compileExpression(
|
|
|
56
56
|
* Compiles a single-row expression into an optimized evaluator function.
|
|
57
57
|
*/
|
|
58
58
|
export function compileSingleRowExpression(
|
|
59
|
-
expr: BasicExpression
|
|
59
|
+
expr: BasicExpression,
|
|
60
60
|
): CompiledSingleRowExpression {
|
|
61
61
|
const compiledFn = compileExpressionInternal(expr, true)
|
|
62
62
|
return compiledFn as CompiledSingleRowExpression
|
|
@@ -67,7 +67,7 @@ export function compileSingleRowExpression(
|
|
|
67
67
|
*/
|
|
68
68
|
function compileExpressionInternal(
|
|
69
69
|
expr: BasicExpression,
|
|
70
|
-
isSingleRow: boolean
|
|
70
|
+
isSingleRow: boolean,
|
|
71
71
|
): (data: any) => any {
|
|
72
72
|
switch (expr.type) {
|
|
73
73
|
case `val`: {
|
|
@@ -157,7 +157,7 @@ function compileSingleRowRef(ref: PropRef): CompiledSingleRowExpression {
|
|
|
157
157
|
function compileFunction(func: Func, isSingleRow: boolean): (data: any) => any {
|
|
158
158
|
// Pre-compile all arguments using the appropriate compiler
|
|
159
159
|
const compiledArgs = func.args.map((arg) =>
|
|
160
|
-
compileExpressionInternal(arg, isSingleRow)
|
|
160
|
+
compileExpressionInternal(arg, isSingleRow),
|
|
161
161
|
)
|
|
162
162
|
|
|
163
163
|
switch (func.name) {
|
|
@@ -463,7 +463,7 @@ function compileFunction(func: Func, isSingleRow: boolean): (data: any) => any {
|
|
|
463
463
|
function evaluateLike(
|
|
464
464
|
value: any,
|
|
465
465
|
pattern: any,
|
|
466
|
-
caseInsensitive: boolean
|
|
466
|
+
caseInsensitive: boolean,
|
|
467
467
|
): boolean {
|
|
468
468
|
if (typeof value !== `string` || typeof pattern !== `string`) {
|
|
469
469
|
return false
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Func, PropRef, Value } from
|
|
2
|
-
import type { BasicExpression, OrderBy } from
|
|
1
|
+
import { Func, PropRef, Value } from '../ir.js'
|
|
2
|
+
import type { BasicExpression, OrderBy } from '../ir.js'
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Normalizes a WHERE clause expression by removing table aliases from property references.
|
|
@@ -20,7 +20,7 @@ import type { BasicExpression, OrderBy } from "../ir.js"
|
|
|
20
20
|
*/
|
|
21
21
|
export function normalizeExpressionPaths(
|
|
22
22
|
whereClause: BasicExpression<boolean>,
|
|
23
|
-
collectionAlias: string
|
|
23
|
+
collectionAlias: string,
|
|
24
24
|
): BasicExpression<boolean> {
|
|
25
25
|
const tpe = whereClause.type
|
|
26
26
|
if (tpe === `val`) {
|
|
@@ -44,7 +44,7 @@ export function normalizeExpressionPaths(
|
|
|
44
44
|
for (const arg of whereClause.args) {
|
|
45
45
|
const convertedArg = normalizeExpressionPaths(
|
|
46
46
|
arg as BasicExpression<boolean>,
|
|
47
|
-
collectionAlias
|
|
47
|
+
collectionAlias,
|
|
48
48
|
)
|
|
49
49
|
args.push(convertedArg)
|
|
50
50
|
}
|
|
@@ -54,12 +54,12 @@ export function normalizeExpressionPaths(
|
|
|
54
54
|
|
|
55
55
|
export function normalizeOrderByPaths(
|
|
56
56
|
orderBy: OrderBy,
|
|
57
|
-
collectionAlias: string
|
|
57
|
+
collectionAlias: string,
|
|
58
58
|
): OrderBy {
|
|
59
59
|
const normalizedOrderBy = orderBy.map((clause) => {
|
|
60
60
|
const basicExp = normalizeExpressionPaths(
|
|
61
61
|
clause.expression,
|
|
62
|
-
collectionAlias
|
|
62
|
+
collectionAlias,
|
|
63
63
|
)
|
|
64
64
|
|
|
65
65
|
return {
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
import { filter, groupBy, groupByOperators, map } from
|
|
2
|
-
import { Func, PropRef, getHavingExpression } from
|
|
1
|
+
import { filter, groupBy, groupByOperators, map } from '@tanstack/db-ivm'
|
|
2
|
+
import { Func, PropRef, getHavingExpression } from '../ir.js'
|
|
3
3
|
import {
|
|
4
4
|
AggregateFunctionNotInSelectError,
|
|
5
5
|
NonAggregateExpressionNotInGroupByError,
|
|
6
6
|
UnknownHavingExpressionTypeError,
|
|
7
7
|
UnsupportedAggregateFunctionError,
|
|
8
|
-
} from
|
|
9
|
-
import { compileExpression, toBooleanPredicate } from
|
|
8
|
+
} from '../../errors.js'
|
|
9
|
+
import { compileExpression, toBooleanPredicate } from './evaluators.js'
|
|
10
10
|
import type {
|
|
11
11
|
Aggregate,
|
|
12
12
|
BasicExpression,
|
|
13
13
|
GroupBy,
|
|
14
14
|
Having,
|
|
15
15
|
Select,
|
|
16
|
-
} from
|
|
17
|
-
import type { NamespacedAndKeyedStream, NamespacedRow } from
|
|
16
|
+
} from '../ir.js'
|
|
17
|
+
import type { NamespacedAndKeyedStream, NamespacedRow } from '../../types.js'
|
|
18
18
|
|
|
19
19
|
const { sum, count, avg, min, max } = groupByOperators
|
|
20
20
|
|
|
@@ -32,7 +32,7 @@ interface GroupBySelectMapping {
|
|
|
32
32
|
*/
|
|
33
33
|
function validateAndCreateMapping(
|
|
34
34
|
groupByClause: GroupBy,
|
|
35
|
-
selectClause?: Select
|
|
35
|
+
selectClause?: Select,
|
|
36
36
|
): GroupBySelectMapping {
|
|
37
37
|
const selectToGroupByIndex = new Map<string, number>()
|
|
38
38
|
const groupByExpressions = [...groupByClause]
|
|
@@ -50,7 +50,7 @@ function validateAndCreateMapping(
|
|
|
50
50
|
|
|
51
51
|
// Non-aggregate expression must be in GROUP BY
|
|
52
52
|
const groupIndex = groupByExpressions.findIndex((groupExpr) =>
|
|
53
|
-
expressionsEqual(expr, groupExpr)
|
|
53
|
+
expressionsEqual(expr, groupExpr),
|
|
54
54
|
)
|
|
55
55
|
|
|
56
56
|
if (groupIndex === -1) {
|
|
@@ -73,7 +73,7 @@ export function processGroupBy(
|
|
|
73
73
|
groupByClause: GroupBy,
|
|
74
74
|
havingClauses?: Array<Having>,
|
|
75
75
|
selectClause?: Select,
|
|
76
|
-
fnHavingClauses?: Array<(row: any) => any
|
|
76
|
+
fnHavingClauses?: Array<(row: any) => any>,
|
|
77
77
|
): NamespacedAndKeyedStream {
|
|
78
78
|
// Handle empty GROUP BY (single-group aggregation)
|
|
79
79
|
if (groupByClause.length === 0) {
|
|
@@ -95,7 +95,7 @@ export function processGroupBy(
|
|
|
95
95
|
|
|
96
96
|
// Apply the groupBy operator with single group
|
|
97
97
|
pipeline = pipeline.pipe(
|
|
98
|
-
groupBy(keyExtractor, aggregates)
|
|
98
|
+
groupBy(keyExtractor, aggregates),
|
|
99
99
|
) as NamespacedAndKeyedStream
|
|
100
100
|
|
|
101
101
|
// Update __select_results to include aggregate values
|
|
@@ -123,7 +123,7 @@ export function processGroupBy(
|
|
|
123
123
|
__select_results: finalResults,
|
|
124
124
|
},
|
|
125
125
|
] as [unknown, Record<string, any>]
|
|
126
|
-
})
|
|
126
|
+
}),
|
|
127
127
|
)
|
|
128
128
|
|
|
129
129
|
// Apply HAVING clauses if present
|
|
@@ -132,7 +132,7 @@ export function processGroupBy(
|
|
|
132
132
|
const havingExpression = getHavingExpression(havingClause)
|
|
133
133
|
const transformedHavingClause = replaceAggregatesByRefs(
|
|
134
134
|
havingExpression,
|
|
135
|
-
selectClause || {}
|
|
135
|
+
selectClause || {},
|
|
136
136
|
)
|
|
137
137
|
const compiledHaving = compileExpression(transformedHavingClause)
|
|
138
138
|
|
|
@@ -141,7 +141,7 @@ export function processGroupBy(
|
|
|
141
141
|
// Create a namespaced row structure for HAVING evaluation
|
|
142
142
|
const namespacedRow = { result: (row as any).__select_results }
|
|
143
143
|
return toBooleanPredicate(compiledHaving(namespacedRow))
|
|
144
|
-
})
|
|
144
|
+
}),
|
|
145
145
|
)
|
|
146
146
|
}
|
|
147
147
|
}
|
|
@@ -154,7 +154,7 @@ export function processGroupBy(
|
|
|
154
154
|
// Create a namespaced row structure for functional HAVING evaluation
|
|
155
155
|
const namespacedRow = { result: (row as any).__select_results }
|
|
156
156
|
return toBooleanPredicate(fnHaving(namespacedRow))
|
|
157
|
-
})
|
|
157
|
+
}),
|
|
158
158
|
)
|
|
159
159
|
}
|
|
160
160
|
}
|
|
@@ -168,7 +168,7 @@ export function processGroupBy(
|
|
|
168
168
|
|
|
169
169
|
// Pre-compile groupBy expressions
|
|
170
170
|
const compiledGroupByExpressions = groupByClause.map((e) =>
|
|
171
|
-
compileExpression(e)
|
|
171
|
+
compileExpression(e),
|
|
172
172
|
)
|
|
173
173
|
|
|
174
174
|
// Create a key extractor function using simple __key_X format
|
|
@@ -258,7 +258,7 @@ export function processGroupBy(
|
|
|
258
258
|
__select_results: finalResults,
|
|
259
259
|
},
|
|
260
260
|
] as [unknown, Record<string, any>]
|
|
261
|
-
})
|
|
261
|
+
}),
|
|
262
262
|
)
|
|
263
263
|
|
|
264
264
|
// Apply HAVING clauses if present
|
|
@@ -267,7 +267,7 @@ export function processGroupBy(
|
|
|
267
267
|
const havingExpression = getHavingExpression(havingClause)
|
|
268
268
|
const transformedHavingClause = replaceAggregatesByRefs(
|
|
269
269
|
havingExpression,
|
|
270
|
-
selectClause || {}
|
|
270
|
+
selectClause || {},
|
|
271
271
|
)
|
|
272
272
|
const compiledHaving = compileExpression(transformedHavingClause)
|
|
273
273
|
|
|
@@ -276,7 +276,7 @@ export function processGroupBy(
|
|
|
276
276
|
// Create a namespaced row structure for HAVING evaluation
|
|
277
277
|
const namespacedRow = { result: (row as any).__select_results }
|
|
278
278
|
return compiledHaving(namespacedRow)
|
|
279
|
-
})
|
|
279
|
+
}),
|
|
280
280
|
)
|
|
281
281
|
}
|
|
282
282
|
}
|
|
@@ -289,7 +289,7 @@ export function processGroupBy(
|
|
|
289
289
|
// Create a namespaced row structure for functional HAVING evaluation
|
|
290
290
|
const namespacedRow = { result: (row as any).__select_results }
|
|
291
291
|
return toBooleanPredicate(fnHaving(namespacedRow))
|
|
292
|
-
})
|
|
292
|
+
}),
|
|
293
293
|
)
|
|
294
294
|
}
|
|
295
295
|
}
|
|
@@ -310,7 +310,7 @@ function expressionsEqual(expr1: any, expr2: any): boolean {
|
|
|
310
310
|
if (!expr1.path || !expr2.path) return false
|
|
311
311
|
if (expr1.path.length !== expr2.path.length) return false
|
|
312
312
|
return expr1.path.every(
|
|
313
|
-
(segment: string, i: number) => segment === expr2.path[i]
|
|
313
|
+
(segment: string, i: number) => segment === expr2.path[i],
|
|
314
314
|
)
|
|
315
315
|
case `val`:
|
|
316
316
|
return expr1.value === expr2.value
|
|
@@ -319,7 +319,7 @@ function expressionsEqual(expr1: any, expr2: any): boolean {
|
|
|
319
319
|
expr1.name === expr2.name &&
|
|
320
320
|
expr1.args?.length === expr2.args?.length &&
|
|
321
321
|
(expr1.args || []).every((arg: any, i: number) =>
|
|
322
|
-
expressionsEqual(arg, expr2.args[i])
|
|
322
|
+
expressionsEqual(arg, expr2.args[i]),
|
|
323
323
|
)
|
|
324
324
|
)
|
|
325
325
|
case `agg`:
|
|
@@ -327,7 +327,7 @@ function expressionsEqual(expr1: any, expr2: any): boolean {
|
|
|
327
327
|
expr1.name === expr2.name &&
|
|
328
328
|
expr1.args?.length === expr2.args?.length &&
|
|
329
329
|
(expr1.args || []).every((arg: any, i: number) =>
|
|
330
|
-
expressionsEqual(arg, expr2.args[i])
|
|
330
|
+
expressionsEqual(arg, expr2.args[i]),
|
|
331
331
|
)
|
|
332
332
|
)
|
|
333
333
|
default:
|
|
@@ -390,7 +390,7 @@ function getAggregateFunction(aggExpr: Aggregate) {
|
|
|
390
390
|
export function replaceAggregatesByRefs(
|
|
391
391
|
havingExpr: BasicExpression | Aggregate,
|
|
392
392
|
selectClause: Select,
|
|
393
|
-
resultAlias: string = `result
|
|
393
|
+
resultAlias: string = `result`,
|
|
394
394
|
): BasicExpression {
|
|
395
395
|
switch (havingExpr.type) {
|
|
396
396
|
case `agg`: {
|
|
@@ -411,7 +411,7 @@ export function replaceAggregatesByRefs(
|
|
|
411
411
|
// Transform function arguments recursively
|
|
412
412
|
const transformedArgs = funcExpr.args.map(
|
|
413
413
|
(arg: BasicExpression | Aggregate) =>
|
|
414
|
-
replaceAggregatesByRefs(arg, selectClause)
|
|
414
|
+
replaceAggregatesByRefs(arg, selectClause),
|
|
415
415
|
)
|
|
416
416
|
return new Func(funcExpr.name, transformedArgs)
|
|
417
417
|
}
|