@tanstack/db 0.2.2 → 0.2.4
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.cjs +6 -3
- package/dist/cjs/collection.cjs.map +1 -1
- package/dist/cjs/query/builder/types.d.cts +9 -1
- package/dist/cjs/query/compiler/joins.cjs +4 -3
- package/dist/cjs/query/compiler/joins.cjs.map +1 -1
- package/dist/cjs/query/live/collection-subscriber.cjs +5 -1
- package/dist/cjs/query/live/collection-subscriber.cjs.map +1 -1
- package/dist/cjs/utils/btree.cjs +2 -2
- package/dist/cjs/utils/btree.cjs.map +1 -1
- package/dist/esm/collection.js +6 -3
- package/dist/esm/collection.js.map +1 -1
- package/dist/esm/query/builder/types.d.ts +9 -1
- package/dist/esm/query/compiler/joins.js +4 -3
- package/dist/esm/query/compiler/joins.js.map +1 -1
- package/dist/esm/query/live/collection-subscriber.js +5 -1
- package/dist/esm/query/live/collection-subscriber.js.map +1 -1
- package/dist/esm/utils/btree.js +2 -2
- package/dist/esm/utils/btree.js.map +1 -1
- package/package.json +4 -4
- package/src/collection.ts +13 -5
- package/src/query/builder/types.ts +49 -4
- package/src/query/compiler/joins.ts +4 -3
- package/src/query/live/collection-subscriber.ts +5 -1
package/src/collection.ts
CHANGED
|
@@ -395,13 +395,14 @@ export class CollectionImpl<
|
|
|
395
395
|
const callbacks = [...this.onFirstReadyCallbacks]
|
|
396
396
|
this.onFirstReadyCallbacks = []
|
|
397
397
|
callbacks.forEach((callback) => callback())
|
|
398
|
-
|
|
399
|
-
// to notify subscribers (like LiveQueryCollection) that the collection is ready
|
|
400
|
-
if (this.changeListeners.size > 0) {
|
|
401
|
-
this.emitEmptyReadyEvent()
|
|
402
|
-
}
|
|
403
398
|
}
|
|
404
399
|
}
|
|
400
|
+
|
|
401
|
+
// Always notify dependents when markReady is called, after status is set
|
|
402
|
+
// This ensures live queries get notified when their dependencies become ready
|
|
403
|
+
if (this.changeListeners.size > 0) {
|
|
404
|
+
this.emitEmptyReadyEvent()
|
|
405
|
+
}
|
|
405
406
|
}
|
|
406
407
|
|
|
407
408
|
public id = ``
|
|
@@ -1270,6 +1271,13 @@ export class CollectionImpl<
|
|
|
1270
1271
|
this.syncedData.clear()
|
|
1271
1272
|
this.syncedMetadata.clear()
|
|
1272
1273
|
this.syncedKeys.clear()
|
|
1274
|
+
|
|
1275
|
+
// 3) Clear currentVisibleState for truncated keys to ensure subsequent operations
|
|
1276
|
+
// are compared against the post-truncate state (undefined) rather than pre-truncate state
|
|
1277
|
+
// This ensures that re-inserted keys are emitted as INSERT events, not UPDATE events
|
|
1278
|
+
for (const key of changedKeys) {
|
|
1279
|
+
currentVisibleState.delete(key)
|
|
1280
|
+
}
|
|
1273
1281
|
}
|
|
1274
1282
|
|
|
1275
1283
|
for (const operation of transaction.operations) {
|
|
@@ -500,20 +500,20 @@ export type Ref<T = any> = {
|
|
|
500
500
|
[K in keyof T]: IsNonExactOptional<T[K]> extends true
|
|
501
501
|
? IsNonExactNullable<T[K]> extends true
|
|
502
502
|
? // Both optional and nullable
|
|
503
|
-
NonNullable<T[K]
|
|
503
|
+
IsPlainObject<NonNullable<T[K]>> extends true
|
|
504
504
|
? Ref<NonNullable<T[K]>> | undefined
|
|
505
505
|
: RefLeaf<NonNullable<T[K]>> | undefined
|
|
506
506
|
: // Optional only
|
|
507
|
-
NonUndefined<T[K]
|
|
507
|
+
IsPlainObject<NonUndefined<T[K]>> extends true
|
|
508
508
|
? Ref<NonUndefined<T[K]>> | undefined
|
|
509
509
|
: RefLeaf<NonUndefined<T[K]>> | undefined
|
|
510
510
|
: IsNonExactNullable<T[K]> extends true
|
|
511
511
|
? // Nullable only
|
|
512
|
-
NonNull<T[K]
|
|
512
|
+
IsPlainObject<NonNull<T[K]>> extends true
|
|
513
513
|
? Ref<NonNull<T[K]>> | null
|
|
514
514
|
: RefLeaf<NonNull<T[K]>> | null
|
|
515
515
|
: // Required
|
|
516
|
-
T[K] extends
|
|
516
|
+
IsPlainObject<T[K]> extends true
|
|
517
517
|
? Ref<T[K]>
|
|
518
518
|
: RefLeaf<T[K]>
|
|
519
519
|
} & RefLeaf<T>
|
|
@@ -825,3 +825,48 @@ export type WithResult<TContext extends Context, TResult> = Prettify<
|
|
|
825
825
|
export type Prettify<T> = {
|
|
826
826
|
[K in keyof T]: T[K]
|
|
827
827
|
} & {}
|
|
828
|
+
|
|
829
|
+
/**
|
|
830
|
+
* IsPlainObject - Utility type to check if T is a plain object
|
|
831
|
+
*/
|
|
832
|
+
type IsPlainObject<T> = T extends unknown
|
|
833
|
+
? T extends object
|
|
834
|
+
? T extends ReadonlyArray<any>
|
|
835
|
+
? false
|
|
836
|
+
: T extends JsBuiltIns
|
|
837
|
+
? false
|
|
838
|
+
: true
|
|
839
|
+
: false
|
|
840
|
+
: false
|
|
841
|
+
|
|
842
|
+
/**
|
|
843
|
+
* JsBuiltIns - List of JavaScript built-ins
|
|
844
|
+
*/
|
|
845
|
+
type JsBuiltIns =
|
|
846
|
+
| ArrayBuffer
|
|
847
|
+
| ArrayBufferLike
|
|
848
|
+
| AsyncGenerator<any, any, any>
|
|
849
|
+
| BigInt64Array
|
|
850
|
+
| BigUint64Array
|
|
851
|
+
| DataView
|
|
852
|
+
| Date
|
|
853
|
+
| Error
|
|
854
|
+
| Float32Array
|
|
855
|
+
| Float64Array
|
|
856
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
|
|
857
|
+
| Function
|
|
858
|
+
| Generator<any, any, any>
|
|
859
|
+
| Int16Array
|
|
860
|
+
| Int32Array
|
|
861
|
+
| Int8Array
|
|
862
|
+
| Map<any, any>
|
|
863
|
+
| Promise<any>
|
|
864
|
+
| RegExp
|
|
865
|
+
| Set<any>
|
|
866
|
+
| string
|
|
867
|
+
| Uint16Array
|
|
868
|
+
| Uint32Array
|
|
869
|
+
| Uint8Array
|
|
870
|
+
| Uint8ClampedArray
|
|
871
|
+
| WeakMap<any, any>
|
|
872
|
+
| WeakSet<any>
|
|
@@ -243,7 +243,7 @@ function processJoin(
|
|
|
243
243
|
const activePipelineWithLoading: IStreamBuilder<
|
|
244
244
|
[key: unknown, [originalKey: string, namespacedRow: NamespacedRow]]
|
|
245
245
|
> = activePipeline.pipe(
|
|
246
|
-
tap((
|
|
246
|
+
tap((data) => {
|
|
247
247
|
if (deoptimized) {
|
|
248
248
|
return
|
|
249
249
|
}
|
|
@@ -270,10 +270,11 @@ function processJoin(
|
|
|
270
270
|
|
|
271
271
|
const { loadKeys, loadInitialState } = collectionCallbacks
|
|
272
272
|
|
|
273
|
-
if (index && index.supports(`
|
|
273
|
+
if (index && index.supports(`in`)) {
|
|
274
274
|
// Use the index to fetch the PKs of the rows in the lazy collection
|
|
275
275
|
// that match this row from the active collection based on the value of the joinKey
|
|
276
|
-
const
|
|
276
|
+
const joinKeys = data.getInner().map(([[joinKey]]) => joinKey)
|
|
277
|
+
const matchingKeys = index.lookup(`in`, joinKeys)
|
|
277
278
|
// Inform the lazy collection that those keys need to be loaded
|
|
278
279
|
loadKeys(matchingKeys)
|
|
279
280
|
} else {
|
|
@@ -138,6 +138,7 @@ export class CollectionSubscriber<
|
|
|
138
138
|
keys: Iterable<string | number>,
|
|
139
139
|
filterFn: (item: object) => boolean
|
|
140
140
|
) {
|
|
141
|
+
const changes: Array<ChangeMessage<any, string | number>> = []
|
|
141
142
|
for (const key of keys) {
|
|
142
143
|
// Only load the key once
|
|
143
144
|
if (this.sentKeys.has(key)) continue
|
|
@@ -145,9 +146,12 @@ export class CollectionSubscriber<
|
|
|
145
146
|
const value = this.collection.get(key)
|
|
146
147
|
if (value !== undefined && filterFn(value)) {
|
|
147
148
|
this.sentKeys.add(key)
|
|
148
|
-
|
|
149
|
+
changes.push({ type: `insert`, key, value })
|
|
149
150
|
}
|
|
150
151
|
}
|
|
152
|
+
if (changes.length > 0) {
|
|
153
|
+
this.sendChangesToPipeline(changes)
|
|
154
|
+
}
|
|
151
155
|
}
|
|
152
156
|
|
|
153
157
|
private subscribeToAllChanges(
|