@tanstack/db 0.4.5 → 0.4.6
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 +1 -1
- package/dist/cjs/collection/change-events.cjs.map +1 -1
- package/dist/cjs/collection/change-events.d.cts +1 -1
- package/dist/cjs/collection/index.cjs +11 -0
- package/dist/cjs/collection/index.cjs.map +1 -1
- package/dist/cjs/collection/index.d.cts +8 -1
- package/dist/cjs/collection/lifecycle.cjs +4 -1
- package/dist/cjs/collection/lifecycle.cjs.map +1 -1
- package/dist/cjs/collection/subscription.cjs +21 -1
- package/dist/cjs/collection/subscription.cjs.map +1 -1
- package/dist/cjs/collection/subscription.d.cts +4 -3
- package/dist/cjs/collection/sync.cjs +94 -71
- package/dist/cjs/collection/sync.cjs.map +1 -1
- package/dist/cjs/collection/sync.d.cts +9 -1
- package/dist/cjs/index.cjs +2 -0
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.cts +2 -0
- package/dist/cjs/indexes/auto-index.cjs +4 -1
- package/dist/cjs/indexes/auto-index.cjs.map +1 -1
- package/dist/cjs/query/compiler/expressions.cjs +19 -0
- package/dist/cjs/query/compiler/expressions.cjs.map +1 -1
- package/dist/cjs/query/compiler/expressions.d.cts +2 -1
- package/dist/cjs/query/compiler/order-by.cjs +2 -1
- package/dist/cjs/query/compiler/order-by.cjs.map +1 -1
- package/dist/cjs/query/compiler/order-by.d.cts +2 -1
- package/dist/cjs/query/live/collection-subscriber.cjs +18 -8
- package/dist/cjs/query/live/collection-subscriber.cjs.map +1 -1
- package/dist/cjs/query/live/collection-subscriber.d.cts +1 -0
- package/dist/cjs/types.d.cts +11 -1
- package/dist/esm/collection/change-events.d.ts +1 -1
- package/dist/esm/collection/change-events.js +1 -1
- package/dist/esm/collection/change-events.js.map +1 -1
- package/dist/esm/collection/index.d.ts +8 -1
- package/dist/esm/collection/index.js +11 -0
- package/dist/esm/collection/index.js.map +1 -1
- package/dist/esm/collection/lifecycle.js +4 -1
- package/dist/esm/collection/lifecycle.js.map +1 -1
- package/dist/esm/collection/subscription.d.ts +4 -3
- package/dist/esm/collection/subscription.js +22 -2
- package/dist/esm/collection/subscription.js.map +1 -1
- package/dist/esm/collection/sync.d.ts +9 -1
- package/dist/esm/collection/sync.js +94 -71
- package/dist/esm/collection/sync.js.map +1 -1
- package/dist/esm/index.d.ts +2 -0
- package/dist/esm/index.js +2 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/indexes/auto-index.js +4 -1
- package/dist/esm/indexes/auto-index.js.map +1 -1
- package/dist/esm/query/compiler/expressions.d.ts +2 -1
- package/dist/esm/query/compiler/expressions.js +19 -0
- package/dist/esm/query/compiler/expressions.js.map +1 -1
- package/dist/esm/query/compiler/order-by.d.ts +2 -1
- package/dist/esm/query/compiler/order-by.js +2 -1
- package/dist/esm/query/compiler/order-by.js.map +1 -1
- package/dist/esm/query/live/collection-subscriber.d.ts +1 -0
- package/dist/esm/query/live/collection-subscriber.js +19 -9
- package/dist/esm/query/live/collection-subscriber.js.map +1 -1
- package/dist/esm/types.d.ts +11 -1
- package/package.json +1 -1
- package/src/collection/change-events.ts +5 -2
- package/src/collection/index.ts +13 -0
- package/src/collection/lifecycle.ts +4 -1
- package/src/collection/subscription.ts +34 -4
- package/src/collection/sync.ts +147 -110
- package/src/index.ts +5 -0
- package/src/indexes/auto-index.ts +4 -1
- package/src/query/compiler/expressions.ts +26 -1
- package/src/query/compiler/order-by.ts +3 -1
- package/src/query/live/collection-subscriber.ts +31 -10
- package/src/types.ts +13 -1
|
@@ -58,7 +58,10 @@ export function ensureIndexForField<
|
|
|
58
58
|
options: compareFn ? { compareFn, compareOptions } : {},
|
|
59
59
|
})
|
|
60
60
|
} catch (error) {
|
|
61
|
-
console.warn(
|
|
61
|
+
console.warn(
|
|
62
|
+
`${collection.id ? `[${collection.id}] ` : ``}Failed to create auto-index for field "${fieldName}":`,
|
|
63
|
+
error
|
|
64
|
+
)
|
|
62
65
|
}
|
|
63
66
|
}
|
|
64
67
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Func, PropRef, Value } from "../ir.js"
|
|
2
|
-
import type { BasicExpression } from "../ir.js"
|
|
2
|
+
import type { BasicExpression, OrderBy } from "../ir.js"
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Functions supported by the collection index system.
|
|
@@ -90,3 +90,28 @@ export function convertToBasicExpression(
|
|
|
90
90
|
return new Func(whereClause.name, args)
|
|
91
91
|
}
|
|
92
92
|
}
|
|
93
|
+
|
|
94
|
+
export function convertOrderByToBasicExpression(
|
|
95
|
+
orderBy: OrderBy,
|
|
96
|
+
collectionAlias: string
|
|
97
|
+
): OrderBy {
|
|
98
|
+
const normalizedOrderBy = orderBy.map((clause) => {
|
|
99
|
+
const basicExp = convertToBasicExpression(
|
|
100
|
+
clause.expression,
|
|
101
|
+
collectionAlias
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
if (!basicExp) {
|
|
105
|
+
throw new Error(
|
|
106
|
+
`Failed to convert orderBy expression to a basic expression: ${clause.expression}`
|
|
107
|
+
)
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return {
|
|
111
|
+
...clause,
|
|
112
|
+
expression: basicExp,
|
|
113
|
+
}
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
return normalizedOrderBy
|
|
117
|
+
}
|
|
@@ -6,13 +6,14 @@ import { findIndexForField } from "../../utils/index-optimization.js"
|
|
|
6
6
|
import { compileExpression } from "./evaluators.js"
|
|
7
7
|
import { replaceAggregatesByRefs } from "./group-by.js"
|
|
8
8
|
import type { CompiledSingleRowExpression } from "./evaluators.js"
|
|
9
|
-
import type { OrderByClause, QueryIR, Select } from "../ir.js"
|
|
9
|
+
import type { OrderBy, OrderByClause, QueryIR, Select } from "../ir.js"
|
|
10
10
|
import type { NamespacedAndKeyedStream, NamespacedRow } from "../../types.js"
|
|
11
11
|
import type { IStreamBuilder, KeyValue } from "@tanstack/db-ivm"
|
|
12
12
|
import type { IndexInterface } from "../../indexes/base-index.js"
|
|
13
13
|
import type { Collection } from "../../collection/index.js"
|
|
14
14
|
|
|
15
15
|
export type OrderByOptimizationInfo = {
|
|
16
|
+
orderBy: OrderBy
|
|
16
17
|
offset: number
|
|
17
18
|
limit: number
|
|
18
19
|
comparator: (
|
|
@@ -160,6 +161,7 @@ export function processOrderBy(
|
|
|
160
161
|
comparator,
|
|
161
162
|
valueExtractorForRawRow,
|
|
162
163
|
index,
|
|
164
|
+
orderBy: orderByClause,
|
|
163
165
|
}
|
|
164
166
|
|
|
165
167
|
optimizableOrderByCollections[followRefCollection.id] =
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { MultiSet } from "@tanstack/db-ivm"
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
convertOrderByToBasicExpression,
|
|
4
|
+
convertToBasicExpression,
|
|
5
|
+
} from "../compiler/expressions.js"
|
|
3
6
|
import type { FullSyncState } from "./types.js"
|
|
4
7
|
import type { MultiSetArray, RootStreamBuilder } from "@tanstack/db-ivm"
|
|
5
8
|
import type { Collection } from "../../collection/index.js"
|
|
@@ -16,26 +19,29 @@ export class CollectionSubscriber<
|
|
|
16
19
|
// Keep track of the biggest value we've sent so far (needed for orderBy optimization)
|
|
17
20
|
private biggest: any = undefined
|
|
18
21
|
|
|
22
|
+
private collectionAlias: string
|
|
23
|
+
|
|
19
24
|
constructor(
|
|
20
25
|
private collectionId: string,
|
|
21
26
|
private collection: Collection,
|
|
22
27
|
private config: Parameters<SyncConfig<TResult>[`sync`]>[0],
|
|
23
28
|
private syncState: FullSyncState,
|
|
24
29
|
private collectionConfigBuilder: CollectionConfigBuilder<TContext, TResult>
|
|
25
|
-
) {
|
|
26
|
-
|
|
27
|
-
subscribe(): CollectionSubscription {
|
|
28
|
-
const collectionAlias = findCollectionAlias(
|
|
30
|
+
) {
|
|
31
|
+
this.collectionAlias = findCollectionAlias(
|
|
29
32
|
this.collectionId,
|
|
30
33
|
this.collectionConfigBuilder.query
|
|
31
|
-
)
|
|
32
|
-
|
|
34
|
+
)!
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
subscribe(): CollectionSubscription {
|
|
38
|
+
const whereClause = this.getWhereClauseFromAlias(this.collectionAlias)
|
|
33
39
|
|
|
34
40
|
if (whereClause) {
|
|
35
41
|
// Convert WHERE clause to BasicExpression format for collection subscription
|
|
36
42
|
const whereExpression = convertToBasicExpression(
|
|
37
43
|
whereClause,
|
|
38
|
-
collectionAlias
|
|
44
|
+
this.collectionAlias
|
|
39
45
|
)
|
|
40
46
|
|
|
41
47
|
if (whereExpression) {
|
|
@@ -128,7 +134,7 @@ export class CollectionSubscriber<
|
|
|
128
134
|
private subscribeToOrderedChanges(
|
|
129
135
|
whereExpression: BasicExpression<boolean> | undefined
|
|
130
136
|
) {
|
|
131
|
-
const { offset, limit, comparator, dataNeeded, index } =
|
|
137
|
+
const { orderBy, offset, limit, comparator, dataNeeded, index } =
|
|
132
138
|
this.collectionConfigBuilder.optimizableOrderByCollections[
|
|
133
139
|
this.collectionId
|
|
134
140
|
]!
|
|
@@ -164,10 +170,17 @@ export class CollectionSubscriber<
|
|
|
164
170
|
|
|
165
171
|
subscription.setOrderByIndex(index)
|
|
166
172
|
|
|
173
|
+
// Normalize the orderBy clauses such that the references are relative to the collection
|
|
174
|
+
const normalizedOrderBy = convertOrderByToBasicExpression(
|
|
175
|
+
orderBy,
|
|
176
|
+
this.collectionAlias
|
|
177
|
+
)
|
|
178
|
+
|
|
167
179
|
// Load the first `offset + limit` values from the index
|
|
168
180
|
// i.e. the K items from the collection that fall into the requested range: [offset, offset + limit[
|
|
169
181
|
subscription.requestLimitedSnapshot({
|
|
170
182
|
limit: offset + limit,
|
|
183
|
+
orderBy: normalizedOrderBy,
|
|
171
184
|
})
|
|
172
185
|
|
|
173
186
|
return subscription
|
|
@@ -225,7 +238,7 @@ export class CollectionSubscriber<
|
|
|
225
238
|
// Loads the next `n` items from the collection
|
|
226
239
|
// starting from the biggest item it has sent
|
|
227
240
|
private loadNextItems(n: number, subscription: CollectionSubscription) {
|
|
228
|
-
const { valueExtractorForRawRow } =
|
|
241
|
+
const { orderBy, valueExtractorForRawRow } =
|
|
229
242
|
this.collectionConfigBuilder.optimizableOrderByCollections[
|
|
230
243
|
this.collectionId
|
|
231
244
|
]!
|
|
@@ -233,8 +246,16 @@ export class CollectionSubscriber<
|
|
|
233
246
|
const biggestSentValue = biggestSentRow
|
|
234
247
|
? valueExtractorForRawRow(biggestSentRow)
|
|
235
248
|
: biggestSentRow
|
|
249
|
+
|
|
250
|
+
// Normalize the orderBy clauses such that the references are relative to the collection
|
|
251
|
+
const normalizedOrderBy = convertOrderByToBasicExpression(
|
|
252
|
+
orderBy,
|
|
253
|
+
this.collectionAlias
|
|
254
|
+
)
|
|
255
|
+
|
|
236
256
|
// Take the `n` items after the biggest sent value
|
|
237
257
|
subscription.requestLimitedSnapshot({
|
|
258
|
+
orderBy: normalizedOrderBy,
|
|
238
259
|
limit: n,
|
|
239
260
|
minValue: biggestSentValue,
|
|
240
261
|
})
|
package/src/types.ts
CHANGED
|
@@ -150,6 +150,18 @@ export type Row<TExtensions = never> = Record<string, Value<TExtensions>>
|
|
|
150
150
|
|
|
151
151
|
export type OperationType = `insert` | `update` | `delete`
|
|
152
152
|
|
|
153
|
+
export type OnLoadMoreOptions = {
|
|
154
|
+
where?: BasicExpression<boolean>
|
|
155
|
+
orderBy?: OrderBy
|
|
156
|
+
limit?: number
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export type CleanupFn = () => void
|
|
160
|
+
|
|
161
|
+
export type SyncConfigRes = {
|
|
162
|
+
cleanup?: CleanupFn
|
|
163
|
+
onLoadMore?: (options: OnLoadMoreOptions) => void | Promise<void>
|
|
164
|
+
}
|
|
153
165
|
export interface SyncConfig<
|
|
154
166
|
T extends object = Record<string, unknown>,
|
|
155
167
|
TKey extends string | number = string | number,
|
|
@@ -161,7 +173,7 @@ export interface SyncConfig<
|
|
|
161
173
|
commit: () => void
|
|
162
174
|
markReady: () => void
|
|
163
175
|
truncate: () => void
|
|
164
|
-
}) => void
|
|
176
|
+
}) => void | CleanupFn | SyncConfigRes
|
|
165
177
|
|
|
166
178
|
/**
|
|
167
179
|
* Get the sync metadata for insert operations
|