@tanstack/db 0.3.1 → 0.4.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.
Files changed (162) hide show
  1. package/dist/cjs/{change-events.cjs → collection/change-events.cjs} +13 -42
  2. package/dist/cjs/collection/change-events.cjs.map +1 -0
  3. package/dist/{esm/change-events.d.ts → cjs/collection/change-events.d.cts} +6 -6
  4. package/dist/cjs/collection/changes.cjs +108 -0
  5. package/dist/cjs/collection/changes.cjs.map +1 -0
  6. package/dist/cjs/collection/changes.d.cts +53 -0
  7. package/dist/cjs/collection/events.cjs +90 -0
  8. package/dist/cjs/collection/events.cjs.map +1 -0
  9. package/dist/cjs/collection/events.d.cts +53 -0
  10. package/dist/cjs/collection/index.cjs +417 -0
  11. package/dist/cjs/collection/index.cjs.map +1 -0
  12. package/dist/{esm/collection.d.ts → cjs/collection/index.d.cts} +56 -172
  13. package/dist/cjs/collection/indexes.cjs +124 -0
  14. package/dist/cjs/collection/indexes.cjs.map +1 -0
  15. package/dist/cjs/collection/indexes.d.cts +47 -0
  16. package/dist/cjs/collection/lifecycle.cjs +150 -0
  17. package/dist/cjs/collection/lifecycle.cjs.map +1 -0
  18. package/dist/cjs/collection/lifecycle.d.cts +70 -0
  19. package/dist/cjs/collection/mutations.cjs +315 -0
  20. package/dist/cjs/collection/mutations.cjs.map +1 -0
  21. package/dist/cjs/collection/mutations.d.cts +33 -0
  22. package/dist/cjs/collection/state.cjs +597 -0
  23. package/dist/cjs/collection/state.cjs.map +1 -0
  24. package/dist/cjs/collection/state.d.cts +122 -0
  25. package/dist/cjs/collection/subscription.cjs +160 -0
  26. package/dist/cjs/collection/subscription.cjs.map +1 -0
  27. package/dist/cjs/collection/subscription.d.cts +57 -0
  28. package/dist/cjs/collection/sync.cjs +154 -0
  29. package/dist/cjs/collection/sync.cjs.map +1 -0
  30. package/dist/cjs/collection/sync.d.cts +34 -0
  31. package/dist/cjs/index.cjs +8 -8
  32. package/dist/cjs/index.d.cts +2 -2
  33. package/dist/cjs/indexes/auto-index.cjs.map +1 -1
  34. package/dist/cjs/indexes/auto-index.d.cts +1 -1
  35. package/dist/cjs/indexes/base-index.cjs.map +1 -1
  36. package/dist/cjs/indexes/base-index.d.cts +2 -2
  37. package/dist/cjs/indexes/btree-index.cjs +2 -2
  38. package/dist/cjs/indexes/btree-index.cjs.map +1 -1
  39. package/dist/cjs/indexes/btree-index.d.cts +1 -1
  40. package/dist/cjs/query/builder/index.cjs +2 -2
  41. package/dist/cjs/query/builder/index.cjs.map +1 -1
  42. package/dist/cjs/query/builder/types.d.cts +1 -1
  43. package/dist/cjs/query/compiler/index.cjs +5 -2
  44. package/dist/cjs/query/compiler/index.cjs.map +1 -1
  45. package/dist/cjs/query/compiler/index.d.cts +3 -2
  46. package/dist/cjs/query/compiler/joins.cjs +22 -24
  47. package/dist/cjs/query/compiler/joins.cjs.map +1 -1
  48. package/dist/cjs/query/compiler/joins.d.cts +3 -2
  49. package/dist/cjs/query/compiler/order-by.cjs.map +1 -1
  50. package/dist/cjs/query/compiler/order-by.d.cts +1 -1
  51. package/dist/cjs/query/ir.cjs.map +1 -1
  52. package/dist/cjs/query/ir.d.cts +1 -1
  53. package/dist/cjs/query/live/collection-config-builder.cjs +29 -12
  54. package/dist/cjs/query/live/collection-config-builder.cjs.map +1 -1
  55. package/dist/cjs/query/live/collection-config-builder.d.cts +3 -0
  56. package/dist/cjs/query/live/collection-subscriber.cjs +43 -104
  57. package/dist/cjs/query/live/collection-subscriber.cjs.map +1 -1
  58. package/dist/cjs/query/live/collection-subscriber.d.cts +4 -7
  59. package/dist/cjs/query/live-query-collection.cjs +2 -2
  60. package/dist/cjs/query/live-query-collection.cjs.map +1 -1
  61. package/dist/cjs/query/live-query-collection.d.cts +1 -1
  62. package/dist/cjs/transactions.cjs +3 -3
  63. package/dist/cjs/transactions.cjs.map +1 -1
  64. package/dist/cjs/types.d.cts +12 -10
  65. package/dist/{cjs/change-events.d.cts → esm/collection/change-events.d.ts} +6 -6
  66. package/dist/esm/{change-events.js → collection/change-events.js} +13 -42
  67. package/dist/esm/collection/change-events.js.map +1 -0
  68. package/dist/esm/collection/changes.d.ts +53 -0
  69. package/dist/esm/collection/changes.js +108 -0
  70. package/dist/esm/collection/changes.js.map +1 -0
  71. package/dist/esm/collection/events.d.ts +53 -0
  72. package/dist/esm/collection/events.js +90 -0
  73. package/dist/esm/collection/events.js.map +1 -0
  74. package/dist/{cjs/collection.d.cts → esm/collection/index.d.ts} +56 -172
  75. package/dist/esm/collection/index.js +417 -0
  76. package/dist/esm/collection/index.js.map +1 -0
  77. package/dist/esm/collection/indexes.d.ts +47 -0
  78. package/dist/esm/collection/indexes.js +124 -0
  79. package/dist/esm/collection/indexes.js.map +1 -0
  80. package/dist/esm/collection/lifecycle.d.ts +70 -0
  81. package/dist/esm/collection/lifecycle.js +150 -0
  82. package/dist/esm/collection/lifecycle.js.map +1 -0
  83. package/dist/esm/collection/mutations.d.ts +33 -0
  84. package/dist/esm/collection/mutations.js +315 -0
  85. package/dist/esm/collection/mutations.js.map +1 -0
  86. package/dist/esm/collection/state.d.ts +122 -0
  87. package/dist/esm/collection/state.js +597 -0
  88. package/dist/esm/collection/state.js.map +1 -0
  89. package/dist/esm/collection/subscription.d.ts +57 -0
  90. package/dist/esm/collection/subscription.js +160 -0
  91. package/dist/esm/collection/subscription.js.map +1 -0
  92. package/dist/esm/collection/sync.d.ts +34 -0
  93. package/dist/esm/collection/sync.js +154 -0
  94. package/dist/esm/collection/sync.js.map +1 -0
  95. package/dist/esm/index.d.ts +2 -2
  96. package/dist/esm/index.js +1 -1
  97. package/dist/esm/indexes/auto-index.d.ts +1 -1
  98. package/dist/esm/indexes/auto-index.js.map +1 -1
  99. package/dist/esm/indexes/base-index.d.ts +2 -2
  100. package/dist/esm/indexes/base-index.js.map +1 -1
  101. package/dist/esm/indexes/btree-index.d.ts +1 -1
  102. package/dist/esm/indexes/btree-index.js +2 -2
  103. package/dist/esm/indexes/btree-index.js.map +1 -1
  104. package/dist/esm/proxy.js +1 -1
  105. package/dist/esm/query/builder/index.js +1 -1
  106. package/dist/esm/query/builder/index.js.map +1 -1
  107. package/dist/esm/query/builder/types.d.ts +1 -1
  108. package/dist/esm/query/compiler/index.d.ts +3 -2
  109. package/dist/esm/query/compiler/index.js +5 -2
  110. package/dist/esm/query/compiler/index.js.map +1 -1
  111. package/dist/esm/query/compiler/joins.d.ts +3 -2
  112. package/dist/esm/query/compiler/joins.js +22 -24
  113. package/dist/esm/query/compiler/joins.js.map +1 -1
  114. package/dist/esm/query/compiler/order-by.d.ts +1 -1
  115. package/dist/esm/query/compiler/order-by.js.map +1 -1
  116. package/dist/esm/query/ir.d.ts +1 -1
  117. package/dist/esm/query/ir.js.map +1 -1
  118. package/dist/esm/query/live/collection-config-builder.d.ts +3 -0
  119. package/dist/esm/query/live/collection-config-builder.js +29 -12
  120. package/dist/esm/query/live/collection-config-builder.js.map +1 -1
  121. package/dist/esm/query/live/collection-subscriber.d.ts +4 -7
  122. package/dist/esm/query/live/collection-subscriber.js +43 -104
  123. package/dist/esm/query/live/collection-subscriber.js.map +1 -1
  124. package/dist/esm/query/live-query-collection.d.ts +1 -1
  125. package/dist/esm/query/live-query-collection.js +1 -1
  126. package/dist/esm/query/live-query-collection.js.map +1 -1
  127. package/dist/esm/transactions.js +3 -3
  128. package/dist/esm/transactions.js.map +1 -1
  129. package/dist/esm/types.d.ts +12 -10
  130. package/package.json +2 -2
  131. package/src/{change-events.ts → collection/change-events.ts} +25 -39
  132. package/src/collection/changes.ts +163 -0
  133. package/src/collection/events.ts +171 -0
  134. package/src/collection/index.ts +808 -0
  135. package/src/collection/indexes.ts +172 -0
  136. package/src/collection/lifecycle.ts +221 -0
  137. package/src/collection/mutations.ts +535 -0
  138. package/src/collection/state.ts +866 -0
  139. package/src/collection/subscription.ts +239 -0
  140. package/src/collection/sync.ts +235 -0
  141. package/src/index.ts +2 -2
  142. package/src/indexes/auto-index.ts +1 -1
  143. package/src/indexes/base-index.ts +3 -3
  144. package/src/indexes/btree-index.ts +2 -2
  145. package/src/query/builder/index.ts +1 -1
  146. package/src/query/builder/types.ts +1 -1
  147. package/src/query/compiler/index.ts +7 -1
  148. package/src/query/compiler/joins.ts +28 -41
  149. package/src/query/compiler/order-by.ts +1 -1
  150. package/src/query/ir.ts +1 -1
  151. package/src/query/live/collection-config-builder.ts +48 -22
  152. package/src/query/live/collection-subscriber.ts +63 -168
  153. package/src/query/live-query-collection.ts +2 -2
  154. package/src/transactions.ts +3 -3
  155. package/src/types.ts +14 -15
  156. package/dist/cjs/change-events.cjs.map +0 -1
  157. package/dist/cjs/collection.cjs +0 -1580
  158. package/dist/cjs/collection.cjs.map +0 -1
  159. package/dist/esm/change-events.js.map +0 -1
  160. package/dist/esm/collection.js +0 -1580
  161. package/dist/esm/collection.js.map +0 -1
  162. package/src/collection.ts +0 -2488
@@ -1,18 +1,13 @@
1
- import { SortedMap } from './SortedMap.cjs';
2
- import { BTreeIndex } from './indexes/btree-index.js';
3
- import { IndexProxy } from './indexes/lazy-index.js';
4
- import { Transaction } from './transactions.cjs';
1
+ import { CollectionStateManager } from './state.js';
2
+ import { CollectionSubscription } from './subscription.js';
3
+ import { AllCollectionEvents, CollectionEventHandler } from './events.js';
4
+ import { BaseIndex, IndexResolver } from '../indexes/base-index.js';
5
+ import { IndexOptions } from '../indexes/index-options.js';
6
+ import { ChangeMessage, CollectionConfig, CollectionStatus, CurrentStateAsChangesOptions, Fn, InferSchemaInput, InferSchemaOutput, InsertConfig, OperationConfig, SubscribeChangesOptions, Transaction as TransactionType, UtilsRecord, WritableDeep } from '../types.js';
7
+ import { SingleRowRefProxy } from '../query/builder/ref-proxy.js';
5
8
  import { StandardSchemaV1 } from '@standard-schema/spec';
6
- import { SingleRowRefProxy } from './query/builder/ref-proxy.cjs';
7
- import { ChangeListener, ChangeMessage, CollectionConfig, CollectionStatus, CurrentStateAsChangesOptions, Fn, InferSchemaInput, InferSchemaOutput, InsertConfig, OperationConfig, OptimisticChangeMessage, SubscribeChangesOptions, Transaction as TransactionType, UtilsRecord, WritableDeep } from './types.cjs';
8
- import { IndexOptions } from './indexes/index-options.js';
9
- import { BaseIndex, IndexResolver } from './indexes/base-index.js';
10
- interface PendingSyncedTransaction<T extends object = Record<string, unknown>> {
11
- committed: boolean;
12
- operations: Array<OptimisticChangeMessage<T>>;
13
- truncate?: boolean;
14
- deletedKeys: Set<string | number>;
15
- }
9
+ import { BTreeIndex } from '../indexes/btree-index.js';
10
+ import { IndexProxy } from '../indexes/lazy-index.js';
16
11
  /**
17
12
  * Enhanced Collection interface that includes both data type T and utilities TUtils
18
13
  * @template T - The type of items in the collection
@@ -102,35 +97,31 @@ export declare function createCollection<T extends object, TKey extends string |
102
97
  utils?: TUtils;
103
98
  }): Collection<T, TKey, TUtils, never, T>;
104
99
  export declare class CollectionImpl<TOutput extends object = Record<string, unknown>, TKey extends string | number = string | number, TUtils extends UtilsRecord = {}, TSchema extends StandardSchemaV1 = StandardSchemaV1, TInput extends object = TOutput> {
100
+ id: string;
105
101
  config: CollectionConfig<TOutput, TKey, TSchema>;
106
- transactions: SortedMap<string, Transaction<any>>;
107
- pendingSyncedTransactions: Array<PendingSyncedTransaction<TOutput>>;
108
- syncedData: Map<TKey, TOutput> | SortedMap<TKey, TOutput>;
109
- syncedMetadata: Map<TKey, unknown>;
110
- optimisticUpserts: Map<TKey, TOutput>;
111
- optimisticDeletes: Set<TKey>;
112
- private _size;
113
- private lazyIndexes;
114
- private resolvedIndexes;
115
- private isIndexesResolved;
116
- private indexCounter;
117
- private changeListeners;
118
- private changeKeyListeners;
119
102
  utils: Record<string, Fn>;
120
- private syncedKeys;
121
- private preSyncVisibleState;
122
- private recentlySyncedKeys;
123
- private hasReceivedFirstCommit;
124
- private isCommittingSyncTransactions;
125
- private onFirstReadyCallbacks;
126
- private hasBeenReady;
127
- private batchedEvents;
128
- private shouldBatchEvents;
129
- private _status;
130
- private activeSubscribersCount;
131
- private gcTimeoutId;
132
- private preloadPromise;
133
- private syncCleanupFn;
103
+ private _events;
104
+ private _changes;
105
+ private _lifecycle;
106
+ private _sync;
107
+ private _indexes;
108
+ private _mutations;
109
+ _state: CollectionStateManager<TOutput, TKey, TSchema, TInput>;
110
+ /**
111
+ * Creates a new Collection instance
112
+ *
113
+ * @param config - Configuration object for the collection
114
+ * @throws Error if sync config is missing
115
+ */
116
+ constructor(config: CollectionConfig<TOutput, TKey, TSchema>);
117
+ /**
118
+ * Gets the current status of the collection
119
+ */
120
+ get status(): CollectionStatus;
121
+ /**
122
+ * Get the number of subscribers to the collection
123
+ */
124
+ get subscriberCount(): number;
134
125
  /**
135
126
  * Register a callback to be executed when the collection first becomes ready
136
127
  * Useful for preloading collections
@@ -155,103 +146,16 @@ export declare class CollectionImpl<TOutput extends object = Record<string, unkn
155
146
  * }
156
147
  */
157
148
  isReady(): boolean;
158
- /**
159
- * Mark the collection as ready for use
160
- * This is called by sync implementations to explicitly signal that the collection is ready,
161
- * providing a more intuitive alternative to using commits for readiness signaling
162
- * @private - Should only be called by sync implementations
163
- */
164
- private markReady;
165
- id: string;
166
- /**
167
- * Gets the current status of the collection
168
- */
169
- get status(): CollectionStatus;
170
- /**
171
- * Validates that the collection is in a usable state for data operations
172
- * @private
173
- */
174
- private validateCollectionUsable;
175
- /**
176
- * Validates state transitions to prevent invalid status changes
177
- * @private
178
- */
179
- private validateStatusTransition;
180
- /**
181
- * Safely update the collection status with validation
182
- * @private
183
- */
184
- private setStatus;
185
- /**
186
- * Creates a new Collection instance
187
- *
188
- * @param config - Configuration object for the collection
189
- * @throws Error if sync config is missing
190
- */
191
- constructor(config: CollectionConfig<TOutput, TKey, TSchema>);
192
149
  /**
193
150
  * Start sync immediately - internal method for compiled queries
194
151
  * This bypasses lazy loading for special cases like live query results
195
152
  */
196
153
  startSyncImmediate(): void;
197
- /**
198
- * Start the sync process for this collection
199
- * This is called when the collection is first accessed or preloaded
200
- */
201
- private startSync;
202
154
  /**
203
155
  * Preload the collection data by starting sync if not already started
204
156
  * Multiple concurrent calls will share the same promise
205
157
  */
206
158
  preload(): Promise<void>;
207
- /**
208
- * Clean up the collection by stopping sync and clearing data
209
- * This can be called manually or automatically by garbage collection
210
- */
211
- cleanup(): Promise<void>;
212
- /**
213
- * Start the garbage collection timer
214
- * Called when the collection becomes inactive (no subscribers)
215
- */
216
- private startGCTimer;
217
- /**
218
- * Cancel the garbage collection timer
219
- * Called when the collection becomes active again
220
- */
221
- private cancelGCTimer;
222
- /**
223
- * Increment the active subscribers count and start sync if needed
224
- */
225
- private addSubscriber;
226
- /**
227
- * Decrement the active subscribers count and start GC timer if needed
228
- */
229
- private removeSubscriber;
230
- /**
231
- * Recompute optimistic state from active transactions
232
- */
233
- private recomputeOptimisticState;
234
- /**
235
- * Calculate the current size based on synced data and optimistic changes
236
- */
237
- private calculateSize;
238
- /**
239
- * Collect events for optimistic changes
240
- */
241
- private collectOptimisticChanges;
242
- /**
243
- * Get the previous value for a key given previous optimistic state
244
- */
245
- private getPreviousValue;
246
- /**
247
- * Emit an empty ready event to notify subscribers that the collection is ready
248
- * This bypasses the normal empty array check in emitEvents
249
- */
250
- private emitEmptyReadyEvent;
251
- /**
252
- * Emit events either immediately or batch them for later emission
253
- */
254
- private emitEvents;
255
159
  /**
256
160
  * Get the current value for a key (virtual derived state)
257
161
  */
@@ -288,19 +192,7 @@ export declare class CollectionImpl<TOutput extends object = Record<string, unkn
288
192
  * Create a new array with the results of calling a function for each entry in the collection
289
193
  */
290
194
  map<U>(callbackfn: (value: TOutput, key: TKey, index: number) => U): Array<U>;
291
- /**
292
- * Attempts to commit pending synced transactions if there are no active transactions
293
- * This method processes operations from pending transactions and applies them to the synced data
294
- */
295
- commitPendingTransactions: () => void;
296
- /**
297
- * Schedule cleanup of a transaction when it completes
298
- * @private
299
- */
300
- private scheduleTransactionCleanup;
301
- private ensureStandardSchema;
302
195
  getKeyFromItem(item: TOutput): TKey;
303
- generateGlobalKey(key: any, item: any): string;
304
196
  /**
305
197
  * Creates an index on a collection for faster queries.
306
198
  * Indexes significantly improve query performance by allowing constant time lookups
@@ -332,25 +224,13 @@ export declare class CollectionImpl<TOutput extends object = Record<string, unkn
332
224
  * })
333
225
  */
334
226
  createIndex<TResolver extends IndexResolver<TKey> = typeof BTreeIndex>(indexCallback: (row: SingleRowRefProxy<TOutput>) => any, config?: IndexOptions<TResolver>): IndexProxy<TKey>;
335
- /**
336
- * Resolve all lazy indexes (called when collection first syncs)
337
- * @private
338
- */
339
- private resolveAllIndexes;
340
- /**
341
- * Resolve a single index immediately
342
- * @private
343
- */
344
- private resolveSingleIndex;
345
227
  /**
346
228
  * Get resolved indexes for query optimization
347
229
  */
348
230
  get indexes(): Map<number, BaseIndex<TKey>>;
349
231
  /**
350
- * Updates all indexes when the collection changes
351
- * @private
232
+ * Validates the data against the schema
352
233
  */
353
- private updateIndexes;
354
234
  validateData(data: unknown, type: `insert` | `update`, key?: TKey): TOutput | never;
355
235
  /**
356
236
  * Inserts one or more items into the collection
@@ -388,7 +268,7 @@ export declare class CollectionImpl<TOutput extends object = Record<string, unkn
388
268
  * console.log('Insert failed:', error)
389
269
  * }
390
270
  */
391
- insert: (data: TInput | Array<TInput>, config?: InsertConfig) => Transaction<Record<string, unknown>> | Transaction<TOutput>;
271
+ insert: (data: TInput | Array<TInput>, config?: InsertConfig) => TransactionType<Record<string, unknown>> | TransactionType<TOutput>;
392
272
  /**
393
273
  * Updates one or more items in the collection using a callback function
394
274
  * @param keys - Single key or array of keys to update
@@ -518,7 +398,7 @@ export declare class CollectionImpl<TOutput extends object = Record<string, unkn
518
398
  * whereExpression: eq(row.status, 'active')
519
399
  * })
520
400
  */
521
- currentStateAsChanges(options?: CurrentStateAsChangesOptions<TOutput>): Array<ChangeMessage<TOutput>>;
401
+ currentStateAsChanges(options?: CurrentStateAsChangesOptions): Array<ChangeMessage<TOutput>> | void;
522
402
  /**
523
403
  * Subscribe to changes in the collection
524
404
  * @param callback - Function called when items change
@@ -526,23 +406,23 @@ export declare class CollectionImpl<TOutput extends object = Record<string, unkn
526
406
  * @returns Unsubscribe function - Call this to stop listening for changes
527
407
  * @example
528
408
  * // Basic subscription
529
- * const unsubscribe = collection.subscribeChanges((changes) => {
409
+ * const subscription = collection.subscribeChanges((changes) => {
530
410
  * changes.forEach(change => {
531
411
  * console.log(`${change.type}: ${change.key}`, change.value)
532
412
  * })
533
413
  * })
534
414
  *
535
- * // Later: unsubscribe()
415
+ * // Later: subscription.unsubscribe()
536
416
  *
537
417
  * @example
538
418
  * // Include current state immediately
539
- * const unsubscribe = collection.subscribeChanges((changes) => {
419
+ * const subscription = collection.subscribeChanges((changes) => {
540
420
  * updateUI(changes)
541
421
  * }, { includeInitialState: true })
542
422
  *
543
423
  * @example
544
424
  * // Subscribe only to changes matching a condition
545
- * const unsubscribe = collection.subscribeChanges((changes) => {
425
+ * const subscription = collection.subscribeChanges((changes) => {
546
426
  * updateUI(changes)
547
427
  * }, {
548
428
  * includeInitialState: true,
@@ -551,29 +431,33 @@ export declare class CollectionImpl<TOutput extends object = Record<string, unkn
551
431
  *
552
432
  * @example
553
433
  * // Subscribe using a pre-compiled expression
554
- * const unsubscribe = collection.subscribeChanges((changes) => {
434
+ * const subscription = collection.subscribeChanges((changes) => {
555
435
  * updateUI(changes)
556
436
  * }, {
557
437
  * includeInitialState: true,
558
438
  * whereExpression: eq(row.status, 'active')
559
439
  * })
560
440
  */
561
- subscribeChanges(callback: (changes: Array<ChangeMessage<TOutput>>) => void, options?: SubscribeChangesOptions<TOutput>): () => void;
441
+ subscribeChanges(callback: (changes: Array<ChangeMessage<TOutput>>) => void, options?: SubscribeChangesOptions): CollectionSubscription;
562
442
  /**
563
- * Subscribe to changes for a specific key
443
+ * Subscribe to a collection event
564
444
  */
565
- subscribeChangesKey(key: TKey, listener: ChangeListener<TOutput, TKey>, { includeInitialState }?: {
566
- includeInitialState?: boolean;
567
- }): () => void;
445
+ on<T extends keyof AllCollectionEvents>(event: T, callback: CollectionEventHandler<T>): () => void;
568
446
  /**
569
- * Capture visible state for keys that will be affected by pending sync operations
570
- * This must be called BEFORE onTransactionStateChange clears optimistic state
447
+ * Subscribe to a collection event once
571
448
  */
572
- private capturePreSyncVisibleState;
449
+ once<T extends keyof AllCollectionEvents>(event: T, callback: CollectionEventHandler<T>): () => void;
573
450
  /**
574
- * Trigger a recomputation when transactions change
575
- * This method should be called by the Transaction class when state changes
451
+ * Unsubscribe from a collection event
576
452
  */
577
- onTransactionStateChange(): void;
453
+ off<T extends keyof AllCollectionEvents>(event: T, callback: CollectionEventHandler<T>): void;
454
+ /**
455
+ * Wait for a collection event
456
+ */
457
+ waitFor<T extends keyof AllCollectionEvents>(event: T, timeout?: number): Promise<AllCollectionEvents[T]>;
458
+ /**
459
+ * Clean up the collection by stopping sync and clearing data
460
+ * This can be called manually or automatically by garbage collection
461
+ */
462
+ cleanup(): Promise<void>;
578
463
  }
579
- export {};