@oimdb/core 1.4.0 → 1.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/index.d.ts CHANGED
@@ -1,7 +1,17 @@
1
1
  type TOIMPk = string | number;
2
2
 
3
+ type TOIMEntitySlot<TEntity extends object, TPk extends TOIMPk> = {
4
+ pk: TPk;
5
+ item: TEntity | undefined;
6
+ };
7
+ type TOIMAnyEntitySlot<TPk extends TOIMPk> = TOIMEntitySlot<object, TPk>;
8
+ type TOIMEntitySlotResolver<TPk extends TOIMPk> = (pk: TPk) => TOIMAnyEntitySlot<TPk> | undefined;
9
+
3
10
  declare abstract class OIMCollectionStore<TEntity extends object, TPk extends TOIMPk> {
4
11
  abstract setOneByPk(pk: TPk, entity: TEntity): void;
12
+ abstract getSlotByPk(pk: TPk): TOIMEntitySlot<TEntity, TPk> | undefined;
13
+ abstract getSlotsByPks(pks: readonly TPk[]): TOIMEntitySlot<TEntity, TPk>[];
14
+ abstract getAllSlots(): TOIMEntitySlot<TEntity, TPk>[];
5
15
  abstract removeOneByPk(pk: TPk): void;
6
16
  abstract removeManyByPks(pks: readonly TPk[]): void;
7
17
  abstract getOneByPk(pk: TPk): TEntity | undefined;
@@ -14,25 +24,25 @@ declare abstract class OIMCollectionStore<TEntity extends object, TPk extends TO
14
24
  }
15
25
 
16
26
  declare abstract class OIMIndexStoreSetBased<TKey extends TOIMPk, TPk extends TOIMPk> {
17
- abstract setOneByKey(key: TKey, pks: Set<TPk>): void;
27
+ abstract setOneByKey(key: TKey, slots: Set<TOIMAnyEntitySlot<TPk>>): void;
18
28
  abstract removeOneByKey(key: TKey): void;
19
29
  abstract removeManyByKeys(keys: readonly TKey[]): void;
20
- abstract getOneByKey(key: TKey): Set<TPk> | undefined;
21
- abstract getManyByKeys(keys: readonly TKey[]): Map<TKey, Set<TPk>>;
30
+ abstract getOneByKey(key: TKey): Set<TOIMAnyEntitySlot<TPk>> | undefined;
31
+ abstract getManyByKeys(keys: readonly TKey[]): Map<TKey, Set<TOIMAnyEntitySlot<TPk>>>;
22
32
  abstract getAllKeys(): TKey[];
23
- abstract getAll(): Map<TKey, Set<TPk>>;
33
+ abstract getAll(): Map<TKey, Set<TOIMAnyEntitySlot<TPk>>>;
24
34
  abstract countAll(): number;
25
35
  abstract clear(): void;
26
36
  }
27
37
 
28
38
  declare abstract class OIMIndexStoreArrayBased<TKey extends TOIMPk, TPk extends TOIMPk> {
29
- abstract setOneByKey(key: TKey, pks: TPk[]): void;
39
+ abstract setOneByKey(key: TKey, slots: TOIMAnyEntitySlot<TPk>[]): void;
30
40
  abstract removeOneByKey(key: TKey): void;
31
41
  abstract removeManyByKeys(keys: readonly TKey[]): void;
32
- abstract getOneByKey(key: TKey): TPk[] | undefined;
33
- abstract getManyByKeys(keys: readonly TKey[]): Map<TKey, TPk[]>;
42
+ abstract getOneByKey(key: TKey): TOIMAnyEntitySlot<TPk>[] | undefined;
43
+ abstract getManyByKeys(keys: readonly TKey[]): Map<TKey, TOIMAnyEntitySlot<TPk>[]>;
34
44
  abstract getAllKeys(): TKey[];
35
- abstract getAll(): Map<TKey, TPk[]>;
45
+ abstract getAll(): Map<TKey, TOIMAnyEntitySlot<TPk>[]>;
36
46
  abstract countAll(): number;
37
47
  abstract clear(): void;
38
48
  }
@@ -41,6 +51,7 @@ type TOIMEventHandler<T> = (payload: T) => void;
41
51
 
42
52
  declare class OIMEventEmitter<T extends Record<string, unknown>> {
43
53
  private buckets;
54
+ hasHandlers<K extends keyof T>(event: K): boolean;
44
55
  private getOrCreateBucket;
45
56
  /**
46
57
  * Compacts the handlers array by removing null entries (tombstones) left by handler removal.
@@ -98,17 +109,21 @@ type TOIMIndexComparator<TPk extends TOIMPk> = (existingPks: readonly TPk[], new
98
109
  declare abstract class OIMIndexSetBased<TKey extends TOIMPk, TPk extends TOIMPk> {
99
110
  protected readonly comparePks?: TOIMIndexComparator<TPk>;
100
111
  protected readonly store: OIMIndexStoreSetBased<TKey, TPk>;
112
+ protected resolveSlot?: TOIMEntitySlotResolver<TPk>;
113
+ private readonly fallbackSlots;
101
114
  readonly emitter: OIMEventEmitter<{
102
115
  0: TOIMIndexUpdatePayload<TKey>;
103
116
  }>;
104
117
  constructor(options?: {
105
118
  comparePks?: TOIMIndexComparator<TPk>;
106
119
  store?: OIMIndexStoreSetBased<TKey, TPk>;
120
+ resolveSlot?: TOIMEntitySlotResolver<TPk>;
107
121
  });
108
122
  /**
109
123
  * Get primary keys for multiple index keys
110
124
  */
111
125
  getPksByKeys(keys: readonly TKey[]): Map<TKey, Set<TPk>>;
126
+ setSlotResolver(resolveSlot: TOIMEntitySlotResolver<TPk>): void;
112
127
  /**
113
128
  * @deprecated Use getPksByKey instead
114
129
  * Get primary keys for a specific index key
@@ -118,6 +133,8 @@ declare abstract class OIMIndexSetBased<TKey extends TOIMPk, TPk extends TOIMPk>
118
133
  * Get primary keys for a specific index key
119
134
  */
120
135
  getPksByKey(key: TKey): Set<TPk>;
136
+ getSlotsByKey(key: TKey): ReadonlySet<TOIMAnyEntitySlot<TPk>>;
137
+ getSlotsByKeys(keys: readonly TKey[]): Map<TKey, ReadonlySet<TOIMAnyEntitySlot<TPk>>>;
121
138
  /**
122
139
  * Check if an index key exists
123
140
  */
@@ -157,10 +174,18 @@ declare abstract class OIMIndexSetBased<TKey extends TOIMPk, TPk extends TOIMPk>
157
174
  * If comparator is provided and returns true (no changes), skip the update.
158
175
  */
159
176
  protected setPksWithComparison(key: TKey, newPks: Set<TPk>): boolean;
177
+ protected setSlotsWithComparison(key: TKey, newSlots: Set<TOIMAnyEntitySlot<TPk>>): boolean;
178
+ protected resolveSlots(pks: Iterable<TPk>): Set<TOIMAnyEntitySlot<TPk>>;
179
+ protected getOrCreateSlot(pk: TPk): TOIMAnyEntitySlot<TPk>;
180
+ protected slotsToPks(slots: Iterable<TOIMAnyEntitySlot<TPk>>): Set<TPk>;
160
181
  /**
161
182
  * Emit update event with changed keys
162
183
  */
163
184
  protected emitUpdate(keys: TKey[]): void;
185
+ /**
186
+ * Emit update event for a single key (fast-path override point).
187
+ */
188
+ protected emitUpdateOne(key: TKey): void;
164
189
  }
165
190
 
166
191
  /**
@@ -170,21 +195,27 @@ declare abstract class OIMIndexSetBased<TKey extends TOIMPk, TPk extends TOIMPk>
170
195
  declare abstract class OIMIndexArrayBased<TKey extends TOIMPk, TPk extends TOIMPk> {
171
196
  protected readonly comparePks?: TOIMIndexComparator<TPk>;
172
197
  protected readonly store: OIMIndexStoreArrayBased<TKey, TPk>;
198
+ protected resolveSlot?: TOIMEntitySlotResolver<TPk>;
199
+ private readonly fallbackSlots;
173
200
  readonly emitter: OIMEventEmitter<{
174
201
  0: TOIMIndexUpdatePayload<TKey>;
175
202
  }>;
176
203
  constructor(options?: {
177
204
  comparePks?: TOIMIndexComparator<TPk>;
178
205
  store?: OIMIndexStoreArrayBased<TKey, TPk>;
206
+ resolveSlot?: TOIMEntitySlotResolver<TPk>;
179
207
  });
180
208
  /**
181
209
  * Get primary keys for multiple index keys
182
210
  */
183
211
  getPksByKeys(keys: readonly TKey[]): Map<TKey, TPk[]>;
212
+ setSlotResolver(resolveSlot: TOIMEntitySlotResolver<TPk>): void;
184
213
  /**
185
214
  * Get primary keys for a specific index key
186
215
  */
187
216
  getPksByKey(key: TKey): TPk[];
217
+ getSlotsByKey(key: TKey): readonly TOIMAnyEntitySlot<TPk>[];
218
+ getSlotsByKeys(keys: readonly TKey[]): Map<TKey, readonly TOIMAnyEntitySlot<TPk>[]>;
188
219
  /**
189
220
  * Check if an index key exists
190
221
  */
@@ -224,87 +255,18 @@ declare abstract class OIMIndexArrayBased<TKey extends TOIMPk, TPk extends TOIMP
224
255
  * If comparator is provided and returns true (no changes), skip the update.
225
256
  */
226
257
  protected setPksWithComparison(key: TKey, newPks: TPk[]): boolean;
258
+ protected setSlotsWithComparison(key: TKey, newSlots: TOIMAnyEntitySlot<TPk>[]): boolean;
259
+ protected resolveSlots(pks: readonly TPk[]): TOIMAnyEntitySlot<TPk>[];
260
+ protected getOrCreateSlot(pk: TPk): TOIMAnyEntitySlot<TPk>;
261
+ protected slotsToPks(slots: readonly TOIMAnyEntitySlot<TPk>[]): TPk[];
227
262
  /**
228
263
  * Emit update event with changed keys
229
264
  */
230
265
  protected emitUpdate(keys: TKey[]): void;
231
- }
232
-
233
- /**
234
- * Manual Set-based index that allows direct manipulation of key-to-primary-keys mappings.
235
- * Extends the abstract OIMIndexSetBased with manual control methods and optional comparison.
236
- */
237
- declare class OIMIndexManualSetBased<TIndexKey extends TOIMPk, TPk extends TOIMPk> extends OIMIndexSetBased<TIndexKey, TPk> {
238
- constructor(options?: {
239
- comparePks?: TOIMIndexComparator<TPk>;
240
- store?: OIMIndexStoreSetBased<TIndexKey, TPk>;
241
- });
242
- /**
243
- * Set primary keys for a specific index key, replacing any existing values.
244
- * Uses optional comparator to skip updates if PKs haven't actually changed.
245
- */
246
- setPks(key: TIndexKey, pks: TPk[]): void;
247
- /**
248
- * Add primary keys to a specific index key
249
- */
250
- addPks(key: TIndexKey, pks: readonly TPk[]): void;
251
266
  /**
252
- * Remove primary keys from a specific index key
253
- */
254
- removePks(key: TIndexKey, pks: readonly TPk[]): void;
255
- /**
256
- * Clear all primary keys for a specific index key, or all keys if no key specified
267
+ * Emit update event for a single key (fast-path override point).
257
268
  */
258
- clear(key?: TIndexKey): void;
259
- }
260
-
261
- /**
262
- * Static class containing OIMDB settings and constants.
263
- * Provides access to configuration values used throughout the library.
264
- */
265
- declare class OIMDBSettings {
266
- /**
267
- * Fixed key used in the manual index to store updated keys set in coalescers.
268
- * This constant is exported so users can create their own indexes and pass them to coalescers.
269
- */
270
- static readonly UPDATED_KEYS_INDEX_KEY: "__updatedKeys__";
271
- static readonly FLUSHING_KEYS_INDEX_KEY: "__flushingKeys__";
272
- }
273
-
274
- /**
275
- * Base abstract coalescer that groups updates by keys and emits consolidated events.
276
- * Designed to be extended for different entity types (collections, indexes, etc.).
277
- * Uses SetBased indexes for efficient key tracking.
278
- */
279
- declare abstract class OIMUpdateEventCoalescer<TKey extends TOIMPk> {
280
- readonly emitter: OIMEventEmitter<{
281
- 0: void;
282
- 1: void;
283
- 2: void;
284
- }>;
285
- protected readonly updatedKeysIndex: OIMIndexManualSetBased<typeof OIMDBSettings.UPDATED_KEYS_INDEX_KEY, TKey>;
286
- protected readonly flushingUpdatedKeysIndex: OIMIndexManualSetBased<typeof OIMDBSettings.FLUSHING_KEYS_INDEX_KEY, TKey>;
287
- private hasEmittedChanges;
288
- constructor(index?: OIMIndexManualSetBased<typeof OIMDBSettings.UPDATED_KEYS_INDEX_KEY, TKey>, flushingIndex?: OIMIndexManualSetBased<typeof OIMDBSettings.FLUSHING_KEYS_INDEX_KEY, TKey>);
289
- /**
290
- * Get the set of keys that have been updated since last clear
291
- */
292
- getUpdatedKeys(): Set<TKey>;
293
- getFlushingUpdatedKeys(): Set<TKey>;
294
- markUpdatedKeysAsFlushing(): void;
295
- /**
296
- * Clear all updated keys and reset the changed state
297
- */
298
- clearUpdatedKeys(): void;
299
- clearFlushingUpdatedKeys(): void;
300
- /**
301
- * Add keys to the updated set and emit HAS_CHANGES event if needed
302
- */
303
- protected addUpdatedKeys(keys: readonly TKey[]): void;
304
- /**
305
- * Clean up event listeners when coalescer is no longer needed
306
- */
307
- abstract destroy(): void;
269
+ protected emitUpdateOne(key: TKey): void;
308
270
  }
309
271
 
310
272
  /**
@@ -329,20 +291,26 @@ declare enum EOIMEventQueueEventType {
329
291
  */
330
292
  declare class OIMEventQueue {
331
293
  readonly emitter: OIMEventEmitter<Record<EOIMEventQueueEventType, void>>;
332
- protected queue: (() => void)[];
294
+ protected tasks: Set<() => void>;
333
295
  protected readonly scheduler?: OIMEventQueueScheduler;
334
296
  protected flushBound?: () => void;
335
297
  protected isFlushing: boolean;
336
- protected pendingSchedule: boolean;
337
298
  constructor(options?: TOIMEventQueueOptions);
338
299
  /**
339
- * Add a function to the queue. If scheduler is configured and autoSchedule is enabled,
340
- * automatically schedules a flush operation.
300
+ * Enqueue a one-shot task to be executed on the next flush.
301
+ * Returns a dequeue function that can be called to cancel the task before it runs.
302
+ */
303
+ enqueue(fn: () => void): () => void;
304
+ get isInFlush(): boolean;
305
+ /**
306
+ * Dequeue (cancel) a previously enqueued task by its dequeue function.
341
307
  */
342
- enqueue(fn: () => void): void;
308
+ dequeue(dequeueFn: () => void): void;
343
309
  /**
344
- * Execute all queued functions and clear the queue.
345
- * This method is safe to call multiple times and handles reentrancy.
310
+ * Execute all pending tasks.
311
+ *
312
+ * This flush drains until the queue is empty. If tasks enqueue more tasks, they will be
313
+ * executed within the same flush.
346
314
  */
347
315
  flush(): void;
348
316
  /**
@@ -357,41 +325,44 @@ declare class OIMEventQueue {
357
325
  * Clear the queue without executing functions and cancel any scheduled flush.
358
326
  */
359
327
  clear(): void;
328
+ protected ensureScheduled(): void;
360
329
  /**
361
330
  * Clean up scheduler subscription when queue is no longer needed.
362
331
  */
363
332
  destroy(): void;
364
333
  }
365
334
 
366
- /**
367
- * Options for creating an update event emitter */
368
- type TOIMUpdateEventEmitterOptions<TKey extends TOIMPk> = {
369
- coalescer: OIMUpdateEventCoalescer<TKey>;
370
- queue: OIMEventQueue;
371
- };
372
-
335
+ type TOIMUpdateEventEmitterDeliveryMode = 'queue' | 'after_flush' | 'immediate';
373
336
  /**
374
337
  * Universal event emitter that handles subscriptions and notifications for any key type.
375
338
  * Optimized for performance with adaptive algorithms and memory management.
376
339
  */
377
340
  declare class OIMUpdateEventEmitter<TKey extends TOIMPk> {
378
- protected keyHandlersBeforeFlush: Map<TKey, Set<TOIMEventHandler<void>>>;
379
341
  protected keyHandlers: Map<TKey, Set<TOIMEventHandler<void>>>;
380
- protected coalescer: OIMUpdateEventCoalescer<TKey>;
381
342
  protected queue: OIMEventQueue;
382
- private isDestroyed;
383
- private isDispatching;
384
- private isInPrePhase;
385
- private hasPendingDuringPrePhase;
343
+ private readonly deliveryMode;
386
344
  private isFlushEnqueued;
387
- constructor(opts: TOIMUpdateEventEmitterOptions<TKey>);
388
- protected handleHasChanges: () => void;
345
+ private dequeueFlush?;
346
+ private updatedKeys;
347
+ private isAfterFlushDeliveryScheduled;
348
+ private unsubscribeAfterFlushDelivery?;
349
+ constructor(queue: OIMEventQueue, deliveryMode?: TOIMUpdateEventEmitterDeliveryMode);
350
+ /**
351
+ * Mark keys as updated and schedule delivery.
352
+ *
353
+ * If there are no subscriptions, this is a no-op and does not allocate or retain keys.
354
+ */
355
+ markUpdatedKeys(keys: readonly TKey[]): void;
356
+ markUpdatedKey(key: TKey): void;
357
+ markAllUpdated(): void;
389
358
  protected readonly onFlush: () => void;
359
+ private deliverImmediate;
360
+ private readonly onAfterFlush;
390
361
  /**
391
- * Helps to run computed values etc.
362
+ * Deliver updated keys and notify handlers once.
363
+ * Re-entrant updates during delivery are forbidden and will throw in markUpdatedKeys().
392
364
  */
393
- protected runPrePhaseDrain(makeHandlerSnapshot: (handlers: Set<TOIMEventHandler<void>>) => TOIMEventHandler<void>[]): Set<TKey>;
394
- protected runHandlersPhase(allKeysForNormalPhase: ReadonlySet<TKey>, makeHandlerSnapshot: (handlers: Set<TOIMEventHandler<void>>) => TOIMEventHandler<void>[]): void;
365
+ protected runSinglePass(makeHandlerSnapshot: (handlers: Set<TOIMEventHandler<void>>) => TOIMEventHandler<void>[]): void;
395
366
  destroy(): void;
396
367
  /**
397
368
  * Get performance metrics for monitoring and debugging
@@ -410,46 +381,25 @@ declare class OIMUpdateEventEmitter<TKey extends TOIMPk> {
410
381
  * Get the number of handlers for a specific key
411
382
  */
412
383
  getHandlerCount(key: TKey): number;
413
- subscribeOnKeyBeforeFlush(key: TKey, handler: TOIMEventHandler<void>): () => void;
414
- unsubscribeFromKeyBeforeFlush(key: TKey, handler: TOIMEventHandler<void>): void;
415
384
  subscribeOnKey(key: TKey, handler: TOIMEventHandler<void>): () => void;
416
385
  unsubscribeFromKey(key: TKey, handler: TOIMEventHandler<void>): void;
417
386
  subscribeOnKeys(keys: readonly TKey[], handler: TOIMEventHandler<void>): () => void;
418
- subscribeOnKeysBeforeFlush(keys: readonly TKey[], handler: TOIMEventHandler<void>): () => void;
419
- unsubscribeFromKeysBeforeFlush(keys: readonly TKey[], handler: TOIMEventHandler<void>): void;
420
387
  unsubscribeFromKeys(keys: readonly TKey[], handler: TOIMEventHandler<void>): void;
421
388
  }
422
389
 
423
- declare enum EOIMIndexEventType {
424
- UPDATE = 0
425
- }
426
-
427
- /**
428
- * Index-specific coalescer that tracks index key updates and emits consolidated change events.
429
- * Takes an event emitter directly instead of the whole index to avoid circular dependencies.
430
- */
431
- declare class OIMUpdateEventCoalescerIndex<TIndexKey extends TOIMPk> extends OIMUpdateEventCoalescer<TIndexKey> {
432
- private readonly indexEmitter;
433
- constructor(indexEmitter: OIMEventEmitter<{
434
- [EOIMIndexEventType.UPDATE]: TOIMIndexUpdatePayload<TIndexKey>;
435
- }>);
436
- destroy(): void;
437
- /**
438
- * When the index is updated, we keep track of the updated keys.
439
- */
440
- private handleUpdate;
390
+ interface IOIMKeyedSubscription<TKey extends TOIMPk> {
391
+ subscribeOnKey(key: TKey, handler: TOIMEventHandler<void>): () => void;
392
+ subscribeOnKeys(keys: readonly TKey[], handler: TOIMEventHandler<void>): () => void;
441
393
  }
442
394
 
443
- declare abstract class OIMReactiveIndexSetBased<TKey extends TOIMPk, TPk extends TOIMPk, TIndex extends OIMIndexSetBased<TKey, TPk>> {
395
+ declare abstract class OIMReactiveIndexSetBased<TKey extends TOIMPk, TPk extends TOIMPk, TIndex extends OIMIndexSetBased<TKey, TPk>> implements IOIMKeyedSubscription<TKey> {
444
396
  readonly index: TIndex;
445
- readonly updateEventEmitter: OIMUpdateEventEmitter<TKey>;
446
- readonly coalescer: OIMUpdateEventCoalescerIndex<TKey>;
447
- constructor(queue: OIMEventQueue, opts?: {
448
- index: TIndex;
449
- });
450
- protected abstract createDefaultIndex(): TIndex;
397
+ protected readonly updateEmitter: OIMUpdateEventEmitter<TKey>;
398
+ constructor(queue: OIMEventQueue, createIndex: (updateEmitter: OIMUpdateEventEmitter<TKey>) => TIndex);
451
399
  getPksByKey(key: TKey): Set<TPk>;
452
400
  getPksByKeys(keys: readonly TKey[]): Map<TKey, Set<TPk>>;
401
+ getSlotsByKey(key: TKey): ReadonlySet<TOIMAnyEntitySlot<TPk>>;
402
+ getSlotsByKeys(keys: readonly TKey[]): Map<TKey, ReadonlySet<TOIMAnyEntitySlot<TPk>>>;
453
403
  hasKey(key: TKey): boolean;
454
404
  getKeys(): readonly TKey[];
455
405
  getKeySize(key: TKey): number;
@@ -462,19 +412,29 @@ declare abstract class OIMReactiveIndexSetBased<TKey extends TOIMPk, TPk extends
462
412
  maxBucketSize: number;
463
413
  minBucketSize: number;
464
414
  };
415
+ subscribeOnKey(key: TKey, handler: TOIMEventHandler<void>): () => void;
416
+ subscribeOnKeys(keys: readonly TKey[], handler: TOIMEventHandler<void>): () => void;
417
+ unsubscribeFromKey(key: TKey, handler: TOIMEventHandler<void>): void;
418
+ unsubscribeFromKeys(keys: readonly TKey[], handler: TOIMEventHandler<void>): void;
419
+ hasSubscriptions(): boolean;
420
+ getHandlerCount(key: TKey): number;
421
+ getSubscriptionMetrics(): {
422
+ totalKeys: number;
423
+ totalHandlers: number;
424
+ averageHandlersPerKey: number;
425
+ queueLength: number;
426
+ };
465
427
  destroy(): void;
466
428
  }
467
429
 
468
- declare abstract class OIMReactiveIndexArrayBased<TKey extends TOIMPk, TPk extends TOIMPk, TIndex extends OIMIndexArrayBased<TKey, TPk>> {
430
+ declare abstract class OIMReactiveIndexArrayBased<TKey extends TOIMPk, TPk extends TOIMPk, TIndex extends OIMIndexArrayBased<TKey, TPk>> implements IOIMKeyedSubscription<TKey> {
469
431
  readonly index: TIndex;
470
- readonly updateEventEmitter: OIMUpdateEventEmitter<TKey>;
471
- readonly coalescer: OIMUpdateEventCoalescerIndex<TKey>;
472
- constructor(queue: OIMEventQueue, opts?: {
473
- index: TIndex;
474
- });
475
- protected abstract createDefaultIndex(): TIndex;
432
+ protected readonly updateEmitter: OIMUpdateEventEmitter<TKey>;
433
+ constructor(queue: OIMEventQueue, createIndex: (updateEmitter: OIMUpdateEventEmitter<TKey>) => TIndex);
476
434
  getPksByKey(key: TKey): TPk[];
477
435
  getPksByKeys(keys: readonly TKey[]): Map<TKey, TPk[]>;
436
+ getSlotsByKey(key: TKey): readonly TOIMAnyEntitySlot<TPk>[];
437
+ getSlotsByKeys(keys: readonly TKey[]): Map<TKey, readonly TOIMAnyEntitySlot<TPk>[]>;
478
438
  hasKey(key: TKey): boolean;
479
439
  getKeys(): readonly TKey[];
480
440
  getKeySize(key: TKey): number;
@@ -487,6 +447,18 @@ declare abstract class OIMReactiveIndexArrayBased<TKey extends TOIMPk, TPk exten
487
447
  maxBucketSize: number;
488
448
  minBucketSize: number;
489
449
  };
450
+ subscribeOnKey(key: TKey, handler: TOIMEventHandler<void>): () => void;
451
+ subscribeOnKeys(keys: readonly TKey[], handler: TOIMEventHandler<void>): () => void;
452
+ unsubscribeFromKey(key: TKey, handler: TOIMEventHandler<void>): void;
453
+ unsubscribeFromKeys(keys: readonly TKey[], handler: TOIMEventHandler<void>): void;
454
+ hasSubscriptions(): boolean;
455
+ getHandlerCount(key: TKey): number;
456
+ getSubscriptionMetrics(): {
457
+ totalKeys: number;
458
+ totalHandlers: number;
459
+ averageHandlersPerKey: number;
460
+ queueLength: number;
461
+ };
490
462
  destroy(): void;
491
463
  }
492
464
 
@@ -523,12 +495,15 @@ declare class OIMCollection<TEntity extends object, TPk extends TOIMPk> {
523
495
  readonly emitter: OIMEventEmitter<{
524
496
  0: TOIMCollectionUpdatePayload<TPk>;
525
497
  }>;
526
- protected readonly selectPk: TOIMPkSelector<TEntity, TPk>;
498
+ readonly selectPk: TOIMPkSelector<TEntity, TPk>;
527
499
  protected readonly store: OIMCollectionStore<TEntity, TPk>;
528
500
  protected readonly updateEntity: TOIMEntityUpdater<TEntity>;
529
501
  constructor(opts?: TOIMCollectionOptions<TEntity, TPk>);
530
502
  getOneByPk(pk: TPk): TEntity | undefined;
531
503
  getManyByPks(pks: readonly TPk[]): TEntity[];
504
+ getSlotByPk(pk: TPk): TOIMEntitySlot<TEntity, TPk> | undefined;
505
+ getSlotsByPks(pks: readonly TPk[]): TOIMEntitySlot<TEntity, TPk>[];
506
+ getAllSlots(): TOIMEntitySlot<TEntity, TPk>[];
532
507
  upsertOneByPk(pk: TPk, entity: Partial<TEntity>): void;
533
508
  upsertOne(entity: TEntity | Partial<TEntity>): void;
534
509
  upsertMany(entities: (TEntity | Partial<TEntity>)[]): void;
@@ -545,30 +520,42 @@ declare class OIMCollection<TEntity extends object, TPk extends TOIMPk> {
545
520
  destroy(): void;
546
521
  }
547
522
 
548
- declare enum EOIMCollectionEventType {
549
- UPDATE = 0
550
- }
551
-
552
- /**
553
- * Collection-specific coalescer that tracks primary key updates and emits consolidated change events.
554
- * Takes an event emitter directly instead of the whole collection to avoid circular dependencies.
555
- */
556
- declare class OIMUpdateEventCoalescerCollection<TPk extends TOIMPk> extends OIMUpdateEventCoalescer<TPk> {
557
- private readonly collectionEmitter;
558
- constructor(collectionEmitter: OIMEventEmitter<{
559
- [EOIMCollectionEventType.UPDATE]: TOIMCollectionUpdatePayload<TPk>;
560
- }>);
561
- destroy(): void;
562
- /**
563
- * When the collection is updated, we keep track of the updated pks.
564
- */
565
- private handleUpdate;
566
- }
567
-
568
- declare class OIMReactiveCollection<TEntity extends object, TPk extends TOIMPk> extends OIMCollection<TEntity, TPk> {
569
- readonly updateEventEmitter: OIMUpdateEventEmitter<TPk>;
570
- readonly coalescer: OIMUpdateEventCoalescerCollection<TPk>;
523
+ declare class OIMReactiveCollection<TEntity extends object, TPk extends TOIMPk> extends OIMCollection<TEntity, TPk> implements IOIMKeyedSubscription<TPk> {
524
+ private readonly queue;
525
+ protected readonly updateEmitter: OIMUpdateEventEmitter<TPk>;
526
+ private readonly anyUpdateHandlers;
527
+ private pendingAnyUpdatePks;
528
+ private isAnyUpdateClearPending;
529
+ private isAnyUpdateScheduled;
530
+ private dequeueAnyUpdate?;
571
531
  constructor(queue: OIMEventQueue, opts?: TOIMCollectionOptions<TEntity, TPk>);
532
+ subscribeOnKey(pk: TPk, handler: TOIMEventHandler<void>): () => void;
533
+ subscribeOnKeys(pks: readonly TPk[], handler: TOIMEventHandler<void>): () => void;
534
+ unsubscribeFromKey(pk: TPk, handler: TOIMEventHandler<void>): void;
535
+ unsubscribeFromKeys(pks: readonly TPk[], handler: TOIMEventHandler<void>): void;
536
+ destroySubscriptions(): void;
537
+ hasSubscriptions(): boolean;
538
+ getHandlerCount(pk: TPk): number;
539
+ getMetrics(): {
540
+ totalKeys: number;
541
+ totalHandlers: number;
542
+ averageHandlersPerKey: number;
543
+ queueLength: number;
544
+ };
545
+ subscribeOnAnyUpdate(handler: (pks: readonly TPk[]) => void): () => void;
546
+ upsertOneByPk(pk: TPk, entity: Partial<TEntity>): void;
547
+ upsertOne(entity: TEntity | Partial<TEntity>): void;
548
+ upsertMany(entities: (TEntity | Partial<TEntity>)[]): void;
549
+ removeOne(entity: TEntity): void;
550
+ removeMany(entities: TEntity[]): void;
551
+ removeOneByPk(pk: TPk): void;
552
+ removeManyByPks(pks: readonly TPk[]): void;
553
+ clear(): void;
554
+ private trackAnyUpdatePk;
555
+ private trackAnyUpdatePks;
556
+ private trackAnyUpdateClear;
557
+ private ensureAnyUpdateEnqueued;
558
+ private readonly runAnyUpdate;
572
559
  destroy(): void;
573
560
  }
574
561
 
@@ -602,39 +589,64 @@ declare class OIMObject<TKey extends string, TValue> {
602
589
  destroy(): void;
603
590
  }
604
591
 
605
- declare enum EOIMObjectEventType {
606
- UPDATE = 0
592
+ declare class OIMReactiveObject<TKey extends string, TValue> extends OIMObject<TKey, TValue> implements IOIMKeyedSubscription<TKey> {
593
+ protected readonly updateEmitter: OIMUpdateEventEmitter<TKey>;
594
+ constructor(queue: OIMEventQueue, opts?: TOIMObjectOptions<TKey, TValue>);
595
+ subscribeOnKey(key: TKey, handler: TOIMEventHandler<void>): () => void;
596
+ subscribeOnKeys(keys: readonly TKey[], handler: TOIMEventHandler<void>): () => void;
597
+ unsubscribeFromKey(key: TKey, handler: TOIMEventHandler<void>): void;
598
+ unsubscribeFromKeys(keys: readonly TKey[], handler: TOIMEventHandler<void>): void;
599
+ hasSubscriptions(): boolean;
600
+ getHandlerCount(key: TKey): number;
601
+ getMetrics(): {
602
+ totalKeys: number;
603
+ totalHandlers: number;
604
+ averageHandlersPerKey: number;
605
+ queueLength: number;
606
+ };
607
+ destroy(): void;
607
608
  }
608
609
 
609
610
  /**
610
- * Object-specific coalescer that tracks property key updates and emits consolidated change events.
611
- * Takes an event emitter directly instead of the whole object to avoid circular dependencies.
611
+ * Manual Set-based index that allows direct manipulation of key-to-primary-keys mappings.
612
+ * Extends the abstract OIMIndexSetBased with manual control methods and optional comparison.
612
613
  */
613
- declare class OIMUpdateEventCoalescerObject<TKey extends string> extends OIMUpdateEventCoalescer<TKey> {
614
- private readonly objectEmitter;
615
- constructor(objectEmitter: OIMEventEmitter<{
616
- [EOIMObjectEventType.UPDATE]: TOIMUpdatePayload<TKey>;
617
- }>);
618
- destroy(): void;
614
+ declare class OIMIndexManualSetBased<TIndexKey extends TOIMPk, TPk extends TOIMPk> extends OIMIndexSetBased<TIndexKey, TPk> {
615
+ constructor(options?: {
616
+ comparePks?: TOIMIndexComparator<TPk>;
617
+ store?: OIMIndexStoreSetBased<TIndexKey, TPk>;
618
+ resolveSlot?: TOIMEntitySlotResolver<TPk>;
619
+ });
619
620
  /**
620
- * When the object is updated, we keep track of the updated keys.
621
+ * Set primary keys for a specific index key, replacing any existing values.
622
+ * Uses optional comparator to skip updates if PKs haven't actually changed.
621
623
  */
622
- private handleUpdate;
623
- }
624
-
625
- declare class OIMReactiveObject<TKey extends string, TValue> extends OIMObject<TKey, TValue> {
626
- readonly updateEventEmitter: OIMUpdateEventEmitter<TKey>;
627
- readonly coalescer: OIMUpdateEventCoalescerObject<TKey>;
628
- constructor(queue: OIMEventQueue, opts?: TOIMObjectOptions<TKey, TValue>);
629
- destroy(): void;
624
+ setPks(key: TIndexKey, pks: TPk[]): void;
625
+ setSlots(key: TIndexKey, slots: Iterable<TOIMAnyEntitySlot<TPk>>): void;
626
+ /**
627
+ * Add primary keys to a specific index key
628
+ */
629
+ addPks(key: TIndexKey, pks: readonly TPk[]): void;
630
+ /**
631
+ * Remove primary keys from a specific index key
632
+ */
633
+ removePks(key: TIndexKey, pks: readonly TPk[]): void;
634
+ /**
635
+ * Clear all primary keys for a specific index key, or all keys if no key specified
636
+ */
637
+ clear(key?: TIndexKey): void;
630
638
  }
631
639
 
632
640
  declare class OIMReactiveIndexManualSetBased<TKey extends TOIMPk, TPk extends TOIMPk> extends OIMReactiveIndexSetBased<TKey, TPk, OIMIndexManualSetBased<TKey, TPk>> {
633
641
  constructor(queue: OIMEventQueue, opts?: {
634
- index: OIMIndexManualSetBased<TKey, TPk>;
642
+ indexOptions?: {
643
+ comparePks?: TOIMIndexComparator<TPk>;
644
+ store?: OIMIndexStoreSetBased<TKey, TPk>;
645
+ resolveSlot?: TOIMEntitySlotResolver<TPk>;
646
+ };
635
647
  });
636
- protected createDefaultIndex(): OIMIndexManualSetBased<TKey, TPk>;
637
648
  setPks(key: TKey, pks: TPk[]): void;
649
+ setSlots(key: TKey, slots: Iterable<TOIMAnyEntitySlot<TPk>>): void;
638
650
  addPks(key: TKey, pks: readonly TPk[]): void;
639
651
  removePks(key: TKey, pks: readonly TPk[]): void;
640
652
  clear(key?: TKey): void;
@@ -648,12 +660,14 @@ declare class OIMIndexManualArrayBased<TIndexKey extends TOIMPk, TPk extends TOI
648
660
  constructor(options?: {
649
661
  comparePks?: TOIMIndexComparator<TPk>;
650
662
  store?: OIMIndexStoreArrayBased<TIndexKey, TPk>;
663
+ resolveSlot?: TOIMEntitySlotResolver<TPk>;
651
664
  });
652
665
  /**
653
666
  * Set primary keys for a specific index key, replacing any existing values.
654
667
  * Uses optional comparator to skip updates if PKs haven't actually changed.
655
668
  */
656
669
  setPks(key: TIndexKey, pks: TPk[]): void;
670
+ setSlots(key: TIndexKey, slots: TOIMAnyEntitySlot<TPk>[]): void;
657
671
  /**
658
672
  * Add primary keys to a specific index key
659
673
  */
@@ -670,10 +684,14 @@ declare class OIMIndexManualArrayBased<TIndexKey extends TOIMPk, TPk extends TOI
670
684
 
671
685
  declare class OIMReactiveIndexManualArrayBased<TKey extends TOIMPk, TPk extends TOIMPk> extends OIMReactiveIndexArrayBased<TKey, TPk, OIMIndexManualArrayBased<TKey, TPk>> {
672
686
  constructor(queue: OIMEventQueue, opts?: {
673
- index: OIMIndexManualArrayBased<TKey, TPk>;
687
+ indexOptions?: {
688
+ comparePks?: TOIMIndexComparator<TPk>;
689
+ store?: OIMIndexStoreArrayBased<TKey, TPk>;
690
+ resolveSlot?: TOIMEntitySlotResolver<TPk>;
691
+ };
674
692
  });
675
- protected createDefaultIndex(): OIMIndexManualArrayBased<TKey, TPk>;
676
693
  setPks(key: TKey, pks: TPk[]): void;
694
+ setSlots(key: TKey, slots: TOIMAnyEntitySlot<TPk>[]): void;
677
695
  addPks(key: TKey, pks: readonly TPk[]): void;
678
696
  removePks(key: TKey, pks: readonly TPk[]): void;
679
697
  clear(key?: TKey): void;
@@ -689,9 +707,12 @@ declare class OIMRICollection<TEntity extends object, TPk extends TOIMPk, TIndex
689
707
  }
690
708
 
691
709
  declare class OIMCollectionStoreMapDriven<TEntity extends object, TPk extends TOIMPk> extends OIMCollectionStore<TEntity, TPk> {
692
- protected readonly entities: Map<TPk, TEntity>;
710
+ protected readonly slots: Map<TPk, TOIMEntitySlot<TEntity, TPk>>;
693
711
  setOneByPk(pk: TPk, entity: TEntity): void;
694
712
  setManyByPks(pks: readonly TPk[], entities: TEntity[]): void;
713
+ getSlotByPk(pk: TPk): TOIMEntitySlot<TEntity, TPk> | undefined;
714
+ getSlotsByPks(pks: readonly TPk[]): TOIMEntitySlot<TEntity, TPk>[];
715
+ getAllSlots(): TOIMEntitySlot<TEntity, TPk>[];
695
716
  removeOneByPk(pk: TPk): void;
696
717
  removeManyByPks(pks: readonly TPk[]): void;
697
718
  getOneByPk(pk: TPk): TEntity | undefined;
@@ -741,27 +762,27 @@ declare class OIMObjectStoreRecordDriven<TKey extends string, TValue> extends OI
741
762
  }
742
763
 
743
764
  declare class OIMIndexStoreMapDrivenSetBased<TKey extends TOIMPk, TPk extends TOIMPk> extends OIMIndexStoreSetBased<TKey, TPk> {
744
- protected readonly pks: Map<TKey, Set<TPk>>;
745
- setOneByKey(key: TKey, pks: Set<TPk>): void;
765
+ protected readonly slots: Map<TKey, Set<TOIMAnyEntitySlot<TPk>>>;
766
+ setOneByKey(key: TKey, slots: Set<TOIMAnyEntitySlot<TPk>>): void;
746
767
  removeOneByKey(key: TKey): void;
747
768
  removeManyByKeys(keys: readonly TKey[]): void;
748
- getOneByKey(key: TKey): Set<TPk> | undefined;
749
- getManyByKeys(keys: readonly TKey[]): Map<TKey, Set<TPk>>;
769
+ getOneByKey(key: TKey): Set<TOIMAnyEntitySlot<TPk>> | undefined;
770
+ getManyByKeys(keys: readonly TKey[]): Map<TKey, Set<TOIMAnyEntitySlot<TPk>>>;
750
771
  getAllKeys(): TKey[];
751
- getAll(): Map<TKey, Set<TPk>>;
772
+ getAll(): Map<TKey, Set<TOIMAnyEntitySlot<TPk>>>;
752
773
  countAll(): number;
753
774
  clear(): void;
754
775
  }
755
776
 
756
777
  declare class OIMIndexStoreMapDrivenArrayBased<TKey extends TOIMPk, TPk extends TOIMPk> extends OIMIndexStoreArrayBased<TKey, TPk> {
757
- protected readonly pks: Map<TKey, TPk[]>;
758
- setOneByKey(key: TKey, pks: TPk[]): void;
778
+ protected readonly slots: Map<TKey, TOIMAnyEntitySlot<TPk>[]>;
779
+ setOneByKey(key: TKey, slots: TOIMAnyEntitySlot<TPk>[]): void;
759
780
  removeOneByKey(key: TKey): void;
760
781
  removeManyByKeys(keys: readonly TKey[]): void;
761
- getOneByKey(key: TKey): TPk[] | undefined;
762
- getManyByKeys(keys: readonly TKey[]): Map<TKey, TPk[]>;
782
+ getOneByKey(key: TKey): TOIMAnyEntitySlot<TPk>[] | undefined;
783
+ getManyByKeys(keys: readonly TKey[]): Map<TKey, TOIMAnyEntitySlot<TPk>[]>;
763
784
  getAllKeys(): TKey[];
764
- getAll(): Map<TKey, TPk[]>;
785
+ getAll(): Map<TKey, TOIMAnyEntitySlot<TPk>[]>;
765
786
  countAll(): number;
766
787
  clear(): void;
767
788
  }
@@ -820,29 +841,22 @@ declare class OIMPkSelectorFactory<TEntity extends object, TPk extends TOIMPk> {
820
841
  }, TPk>;
821
842
  }
822
843
 
823
- /**
824
- * Manual coalescer: you mark keys as updated explicitly.
825
- *
826
- * Useful for wrappers that maintain their own "derived" state (e.g. change-sets, command streams)
827
- * and want to reuse `OIMUpdateEventEmitter` batching/reentrancy semantics without piggybacking
828
- * on a collection/index/object emitter payload.
829
- */
830
- declare class OIMUpdateEventCoalescerManual<TKey extends TOIMPk> extends OIMUpdateEventCoalescer<TKey> {
831
- markUpdatedKeys(keys: readonly TKey[]): void;
832
- destroy(): void;
833
- }
834
-
835
844
  type TOIMFieldKey<TEntity extends object> = keyof TEntity & string;
836
845
  /**
837
- * Wrapper around `OIMReactiveCollection` that tracks "changed fields" per entity PK.
846
+ * Wrapper around `OIMCollection` that tracks "changed fields" per entity PK.
838
847
  *
839
848
  * Important: to get field-level info, you must perform writes through this wrapper.
840
- * If you mutate the underlying collection directly, this wrapper will not be able
841
- * to infer which fields changed (core update payloads carry only PKs).
849
+ *
850
+ * DX: if the underlying collection is mutated directly (bypassing this wrapper), we detect it
851
+ * via collection update events and infer changed fields by diffing the last observed entity snapshot.
842
852
  */
843
853
  declare class OIMCollectionChangedFieldsWrapper<TEntity extends object, TPk extends TOIMPk> {
844
- readonly collection: OIMReactiveCollection<TEntity, TPk>;
854
+ readonly collection: OIMCollection<TEntity, TPk>;
845
855
  private readonly selectPk;
856
+ private readonly unsubscribeAfterFlush;
857
+ private readonly unsubscribeFromCollectionEmitter;
858
+ private isInWrite;
859
+ private readonly lastEntitySnapshotByPk;
846
860
  /**
847
861
  * Emits updates scoped by PK. Subscribe, then read state via `getChangedFieldsByPk(...)`
848
862
  * or drain via `consumeChangedFieldsByPk(...)`.
@@ -855,9 +869,7 @@ declare class OIMCollectionChangedFieldsWrapper<TEntity extends object, TPk exte
855
869
  readonly changedFieldsEventEmitter: OIMUpdateEventEmitter<TOIMFieldKey<TEntity>>;
856
870
  private readonly changedFieldsByPk;
857
871
  private readonly changedPksByField;
858
- private readonly changedPksCoalescer;
859
- private readonly changedFieldsCoalescer;
860
- constructor(queue: OIMEventQueue, collection: OIMReactiveCollection<TEntity, TPk>, opts?: {
872
+ constructor(queue: OIMEventQueue, collection: OIMCollection<TEntity, TPk>, opts?: {
861
873
  /**
862
874
  * Optional PK selector for convenience APIs like `upsertOne(...)`.
863
875
  * If not provided, only `upsertOneByPk(...)` should be used.
@@ -873,6 +885,13 @@ declare class OIMCollectionChangedFieldsWrapper<TEntity extends object, TPk exte
873
885
  consumeChangedPksByField(field: TOIMFieldKey<TEntity>): Set<TPk>;
874
886
  clear(): void;
875
887
  destroy(): void;
888
+ private readonly onAfterFlush;
889
+ private readonly onCollectionUpdate;
890
+ private withWrite;
891
+ private trackExternalMutationByPk;
892
+ private diffChangedKeys;
893
+ private updateEntitySnapshot;
894
+ private trackChangedKeys;
876
895
  private trackPatch;
877
896
  }
878
897
 
@@ -910,7 +929,10 @@ type TOIMOrderedListCommand<TPk extends TOIMPk> = {
910
929
  fromIndex: number;
911
930
  toIndex: number;
912
931
  } | {
913
- type: 'reset';
932
+ /**
933
+ * Replace the whole list for this key (preferred name).
934
+ */
935
+ type: 'set';
914
936
  keys: readonly TPk[];
915
937
  };
916
938
 
@@ -923,11 +945,13 @@ type TOIMOrderedListCommand<TPk extends TOIMPk> = {
923
945
  * Notes:
924
946
  * - Commands are buffered per key and delivered batched per queue flush.
925
947
  * - Order of commands is preserved.
926
- * - A future optimizer can collapse the command buffer into `reset(...)` if needed.
948
+ * - A future optimizer can collapse the command buffer into `set(...)` if needed.
927
949
  */
928
950
  declare class OIMOrderedListIndexCommandStreamWrapper<TKey extends TOIMPk, TItemKey extends TOIMPk> {
929
951
  readonly commandsEventEmitter: OIMUpdateEventEmitter<TKey>;
930
- private readonly coalescer;
952
+ private readonly unsubscribeAfterFlush;
953
+ private readonly unsubscribeFromIndexEmitter;
954
+ private isInWrite;
931
955
  private readonly commandsByKey;
932
956
  /** Underlying ordered index (source of truth for the list). */
933
957
  readonly index: OIMIndexManualOrderedArrayBased<TKey, TItemKey>;
@@ -938,7 +962,7 @@ declare class OIMOrderedListIndexCommandStreamWrapper<TKey extends TOIMPk, TItem
938
962
  push(key: TKey, itemKey: TItemKey): void;
939
963
  removeAt(key: TKey, index: number): void;
940
964
  move(key: TKey, fromIndex: number, toIndex: number): void;
941
- reset(key: TKey, keys: readonly TItemKey[]): void;
965
+ set(key: TKey, keys: readonly TItemKey[]): void;
942
966
  /**
943
967
  * Read-only peek at buffered commands without clearing them.
944
968
  */
@@ -950,6 +974,9 @@ declare class OIMOrderedListIndexCommandStreamWrapper<TKey extends TOIMPk, TItem
950
974
  consumeCommands(key: TKey): TOIMOrderedListCommand<TItemKey>[];
951
975
  clear(key?: TKey): void;
952
976
  destroy(): void;
977
+ private readonly onAfterFlush;
978
+ private readonly onIndexUpdate;
979
+ private withWrite;
953
980
  private appendCommand;
954
981
  }
955
982
 
@@ -1050,21 +1077,16 @@ declare class OIMEventQueueSchedulerFactory {
1050
1077
  static createImmediate(): OIMEventQueueSchedulerImmediate;
1051
1078
  }
1052
1079
 
1053
- /**
1054
- * Event types for update coalescers */
1055
- declare enum EOIMUpdateEventCoalescerEventType {
1056
- /**
1057
- * @description Emitted when there are any first changes to the updated keys
1058
- */
1059
- HAS_CHANGES = 0,
1060
- /**
1061
- * @description Emitted before the flush of the updated keys
1062
- */
1063
- BEFORE_FLUSH = 1,
1064
- /**
1065
- * @description Emitted after the flush of the updated keys
1066
- */
1067
- AFTER_FLUSH = 2
1080
+ declare enum EOIMCollectionEventType {
1081
+ UPDATE = 0
1082
+ }
1083
+
1084
+ declare enum EOIMIndexEventType {
1085
+ UPDATE = 0
1086
+ }
1087
+
1088
+ declare enum EOIMObjectEventType {
1089
+ UPDATE = 0
1068
1090
  }
1069
1091
 
1070
1092
  type TOIMIndexKey = string | number | bigint;
@@ -1074,12 +1096,14 @@ type TOIMIndexKey = string | number | bigint;
1074
1096
  type TOIMIndexOptionsSetBased<TIndexKey extends TOIMPk, TPk extends TOIMPk> = {
1075
1097
  comparePks?: TOIMIndexComparator<TPk>;
1076
1098
  store?: OIMIndexStoreSetBased<TIndexKey, TPk>;
1099
+ resolveSlot?: TOIMEntitySlotResolver<TPk>;
1077
1100
  };
1078
1101
  /**
1079
1102
  * Configuration options for Array-based index instances */
1080
1103
  type TOIMIndexOptionsArrayBased<TIndexKey extends TOIMPk, TPk extends TOIMPk> = {
1081
1104
  comparePks?: TOIMIndexComparator<TPk>;
1082
1105
  store?: OIMIndexStoreArrayBased<TIndexKey, TPk>;
1106
+ resolveSlot?: TOIMEntitySlotResolver<TPk>;
1083
1107
  };
1084
1108
  /**
1085
1109
  * @deprecated Use TOIMIndexOptionsSetBased or TOIMIndexOptionsArrayBased instead
@@ -1091,13 +1115,21 @@ type TOIMIndexPksUpdatePayload<TKey extends TOIMPk, TPk extends TOIMPk> = {
1091
1115
  pks: readonly TPk[];
1092
1116
  };
1093
1117
 
1094
- declare enum EOIMEffectPhase {
1095
- PRE = "pre",
1096
- HANDLERS = "handlers"
1118
+ /**
1119
+ * Static class containing OIMDB settings and constants.
1120
+ * Provides access to configuration values used throughout the library.
1121
+ */
1122
+ declare class OIMDBSettings {
1123
+ /**
1124
+ * Fixed key used in the manual index to store updated keys set in coalescers.
1125
+ * This constant is exported so users can create their own indexes and pass them to coalescers.
1126
+ */
1127
+ static readonly UPDATED_KEYS_INDEX_KEY: "__updatedKeys__";
1128
+ static readonly FLUSHING_KEYS_INDEX_KEY: "__flushingKeys__";
1097
1129
  }
1098
1130
 
1099
1131
  interface IOIMEffectDependency {
1100
- subscribe(phase: EOIMEffectPhase, onInvalidate: () => void): () => void;
1132
+ subscribe(onUpdate: () => void): () => void;
1101
1133
  }
1102
1134
 
1103
1135
  type TOIMComputedOptions<TValue> = {
@@ -1110,17 +1142,30 @@ type TOIMComputedUpdatePayload<TKey extends TOIMPk> = {
1110
1142
  keys: readonly TKey[];
1111
1143
  };
1112
1144
 
1113
- declare enum EOIMComputedEventType {
1114
- UPDATE = "update"
1115
- }
1116
-
1117
- declare class OIMUpdateEventCoalescerComputed<TKey extends TOIMPk> extends OIMUpdateEventCoalescer<TKey> {
1118
- private readonly computedEmitter;
1119
- constructor(computedEmitter: OIMEventEmitter<{
1120
- [EOIMComputedEventType.UPDATE]: TOIMComputedUpdatePayload<TKey>;
1121
- }>);
1122
- destroy(): void;
1123
- private handleUpdate;
1145
+ /**
1146
+ * Computative runtime that schedules derived computations by levels and runs them
1147
+ * on `queue.flush()` boundary (AFTER_FLUSH).
1148
+ */
1149
+ declare class OIMComputativeRuntime {
1150
+ readonly queue: OIMEventQueue;
1151
+ private isFlushScheduled;
1152
+ private isFlushing;
1153
+ private minLevel;
1154
+ private maxLevel;
1155
+ private readonly dirtyByLevel;
1156
+ private readonly afterFlushTasks;
1157
+ constructor(queue: OIMEventQueue);
1158
+ /**
1159
+ * Schedule a one-shot task to run on the next `queue.flush()` (AFTER_FLUSH),
1160
+ * ordered by `level` ascending.
1161
+ */
1162
+ schedule(task: () => void, level?: number): () => void;
1163
+ /**
1164
+ * Run once at the start of the next runtime flush (i.e. after queue.flush()).
1165
+ * Useful for resubscribing dependencies exactly once per source flush.
1166
+ */
1167
+ scheduleAfterFlush(task: () => void): () => void;
1168
+ private flush;
1124
1169
  }
1125
1170
 
1126
1171
  type TOIMComputedKey$2 = 'value';
@@ -1128,27 +1173,26 @@ declare class OIMComputed<TValue> {
1128
1173
  readonly emitter: OIMEventEmitter<{
1129
1174
  update: TOIMComputedUpdatePayload<TOIMComputedKey$2>;
1130
1175
  }>;
1131
- readonly coalescer: OIMUpdateEventCoalescerComputed<TOIMComputedKey$2>;
1132
1176
  readonly updateEventEmitter: OIMUpdateEventEmitter<TOIMComputedKey$2>;
1133
- private readonly queue;
1177
+ private readonly runtime;
1134
1178
  private readonly compute;
1135
1179
  private readonly compare;
1136
1180
  private readonly deps;
1137
1181
  private value;
1138
1182
  private hasValue;
1139
1183
  private isDirty;
1140
- private isInFlush;
1141
- private hasRecomputedInThisFlush;
1142
1184
  private readonly effect;
1143
- private readonly handleQueueBeforeFlush;
1144
- private readonly handleQueueAfterFlush;
1145
- constructor(queue: OIMEventQueue, opts: TOIMComputedOptions<TValue>);
1185
+ constructor(runtime: OIMComputativeRuntime, opts: TOIMComputedOptions<TValue>);
1146
1186
  get(): TValue;
1147
1187
  getIfReady(): TValue | undefined;
1148
1188
  destroy(): void;
1149
1189
  private recomputeAndEmitIfChanged;
1150
1190
  }
1151
1191
 
1192
+ declare enum EOIMComputedEventType {
1193
+ UPDATE = "update"
1194
+ }
1195
+
1152
1196
  type TOIMComputedKey$1 = 'value';
1153
1197
  interface IOIMComputedEventSource {
1154
1198
  emitter: OIMEventEmitter<{
@@ -1158,62 +1202,64 @@ interface IOIMComputedEventSource {
1158
1202
 
1159
1203
  type TOIMEffectOptions = {
1160
1204
  deps?: readonly IOIMEffectDependency[];
1161
- phase: EOIMEffectPhase;
1162
- onInvalidate?: () => void;
1205
+ onUpdate?: () => void;
1163
1206
  run: () => void;
1164
1207
  };
1165
1208
 
1166
1209
  declare class OIMEffect {
1167
- private readonly queue;
1168
- private readonly phase;
1169
- private readonly onInvalidate?;
1210
+ private readonly runtime;
1211
+ private readonly onUpdate?;
1170
1212
  private readonly run;
1171
1213
  private readonly deps;
1172
- private unsubscribers;
1173
- private isDestroyed;
1174
- private isInFlush;
1175
- private hasRunInThisFlush;
1214
+ private readonly sourceDeps;
1215
+ private readonly computedDeps;
1216
+ private sourceUnsubscribers;
1217
+ private computedUnsubscribers;
1218
+ private dequeueResubscribe?;
1219
+ private isResubscribeEnqueued;
1220
+ private isTemporarilyUnsubscribedForFlush;
1176
1221
  private isScheduled;
1177
- private readonly handleQueueBeforeFlush;
1178
- private readonly handleQueueAfterFlush;
1222
+ private dequeueScheduled?;
1179
1223
  private readonly runTask;
1180
- constructor(queue: OIMEventQueue, opts: TOIMEffectOptions);
1224
+ constructor(runtime: OIMComputativeRuntime, opts: TOIMEffectOptions);
1181
1225
  destroy(): void;
1182
- private invalidate;
1226
+ private onSourceInvalidate;
1227
+ private onComputedInvalidate;
1183
1228
  private runOnce;
1229
+ private subscribeToDeps;
1230
+ private unsubscribeFromSourceDeps;
1231
+ private unsubscribeFromAllDeps;
1232
+ private ensureResubscribeAfterFlush;
1233
+ private readonly onAfterFlush;
1184
1234
  }
1185
1235
 
1186
1236
  declare class OIMEffectDependencyKeyed<TKey extends TOIMPk> implements IOIMEffectDependency {
1187
- private readonly updateEventEmitter;
1237
+ private readonly subscription;
1188
1238
  private readonly key;
1189
1239
  private readonly keys;
1190
- constructor(updateEventEmitter: OIMUpdateEventEmitter<TKey>, keyOrKeys: TKey | readonly TKey[]);
1191
- subscribe(phase: EOIMEffectPhase, onInvalidate: () => void): () => void;
1240
+ constructor(subscription: IOIMKeyedSubscription<TKey>, keyOrKeys: TKey | readonly TKey[]);
1241
+ subscribe(onUpdate: () => void): () => void;
1192
1242
  }
1193
1243
 
1194
1244
  declare class OIMEffectDependencyKeyedObject<TKey extends string, TValue> implements IOIMEffectDependency {
1195
1245
  private readonly dep;
1196
1246
  constructor(object: OIMReactiveObject<TKey, TValue>, key: TKey);
1197
1247
  constructor(object: OIMReactiveObject<TKey, TValue>, keys: readonly TKey[]);
1198
- subscribe(phase: EOIMEffectPhase, onInvalidate: () => void): () => void;
1248
+ subscribe(onUpdate: () => void): () => void;
1199
1249
  }
1200
1250
 
1201
1251
  declare class OIMEffectDependencyKeyedCollection<TEntity extends object, TPk extends TOIMPk> implements IOIMEffectDependency {
1202
1252
  private readonly dep;
1203
1253
  constructor(collection: OIMReactiveCollection<TEntity, TPk>, pk: TPk);
1204
1254
  constructor(collection: OIMReactiveCollection<TEntity, TPk>, pks: readonly TPk[]);
1205
- subscribe(phase: EOIMEffectPhase, onInvalidate: () => void): () => void;
1255
+ subscribe(onUpdate: () => void): () => void;
1206
1256
  }
1207
1257
 
1208
1258
  declare class OIMEffectDependencyKeyedIndex<TKey extends TOIMPk> implements IOIMEffectDependency {
1209
1259
  private readonly dep;
1210
- constructor(index: {
1211
- updateEventEmitter: OIMUpdateEventEmitter<TKey>;
1212
- }, key: TKey);
1213
- constructor(index: {
1214
- updateEventEmitter: OIMUpdateEventEmitter<TKey>;
1215
- }, keys: readonly TKey[]);
1216
- subscribe(phase: EOIMEffectPhase, onInvalidate: () => void): () => void;
1260
+ constructor(index: IOIMKeyedSubscription<TKey>, key: TKey);
1261
+ constructor(index: IOIMKeyedSubscription<TKey>, keys: readonly TKey[]);
1262
+ subscribe(onUpdate: () => void): () => void;
1217
1263
  }
1218
1264
 
1219
1265
  type TOIMComputedKey = 'value';
@@ -1225,14 +1271,132 @@ type TOIMComputedLike = {
1225
1271
  };
1226
1272
  /**
1227
1273
  * Effect dependency on a computed.
1228
- *
1229
- * - PRE: subscribe directly to computed.emitter for immediate invalidation during pre-drain.
1230
- * - HANDLERS: subscribe via computed.updateEventEmitter (normal handlers) which is delivered through queue.
1231
1274
  */
1232
1275
  declare class OIMEffectDependencyComputed implements IOIMEffectDependency {
1233
1276
  private readonly computed;
1234
1277
  constructor(computed: TOIMComputedLike);
1235
- subscribe(phase: EOIMEffectPhase, onInvalidate: () => void): () => void;
1278
+ subscribe(onUpdate: () => void): () => void;
1279
+ }
1280
+
1281
+ interface IOIMSelectorComputedDependency {
1282
+ subscribe(onUpdate: () => void): () => void;
1283
+ }
1284
+
1285
+ interface IOIMSelectorSourceDependency {
1286
+ subscribe(onUpdate: () => void): () => void;
1287
+ }
1288
+
1289
+ declare abstract class OIMSelector<TValue> {
1290
+ protected readonly runtime: OIMComputativeRuntime;
1291
+ protected readonly sourceDeps: readonly IOIMSelectorSourceDependency[];
1292
+ protected readonly computedDeps: readonly IOIMSelectorComputedDependency[];
1293
+ private readonly listeners;
1294
+ private sourceUnsubscribers;
1295
+ private computedUnsubscribers;
1296
+ private dequeueResubscribe?;
1297
+ private isResubscribeEnqueued;
1298
+ private isTemporarilyUnsubscribedForFlush;
1299
+ private isDeliveryEnqueued;
1300
+ private dequeueDelivery?;
1301
+ private hasLastValue;
1302
+ private lastValue;
1303
+ protected get queue(): OIMEventQueue;
1304
+ protected constructor(runtime: OIMComputativeRuntime, sourceDeps: readonly IOIMSelectorSourceDependency[], computedDeps?: readonly IOIMSelectorComputedDependency[]);
1305
+ abstract getValue(): TValue;
1306
+ /**
1307
+ * Start watching this selector. The callback is called immediately with the current value,
1308
+ * then coalesced and delivered on `queue.flush()` when the selector invalidates.
1309
+ */
1310
+ watch(onValue: (value: TValue) => void): () => void;
1311
+ protected areEqual(prev: TValue, next: TValue): boolean;
1312
+ private readonly onSourceInvalidate;
1313
+ private readonly onComputedInvalidate;
1314
+ private readonly deliver;
1315
+ private setLastValue;
1316
+ private subscribeToDeps;
1317
+ private unsubscribeFromSourceDeps;
1318
+ private unsubscribeFromAllDeps;
1319
+ private ensureResubscribeAfterFlush;
1320
+ private readonly onAfterFlush;
1321
+ }
1322
+
1323
+ declare class OIMCollectionByPkSelector<TEntity extends object, TPk extends TOIMPk> extends OIMSelector<TEntity | undefined> {
1324
+ private readonly collection;
1325
+ private readonly pk;
1326
+ constructor(runtime: OIMComputativeRuntime, collection: OIMReactiveCollection<TEntity, TPk>, pk: TPk);
1327
+ getValue(): TEntity | undefined;
1328
+ }
1329
+
1330
+ declare class OIMCollectionByPksSelector<TEntity extends object, TPk extends TOIMPk> extends OIMSelector<readonly (TEntity | undefined)[]> {
1331
+ private readonly collection;
1332
+ private readonly pks;
1333
+ constructor(runtime: OIMComputativeRuntime, collection: OIMReactiveCollection<TEntity, TPk>, pks: readonly TPk[]);
1334
+ getValue(): readonly (TEntity | undefined)[];
1335
+ protected areEqual(prev: readonly (TEntity | undefined)[], next: readonly (TEntity | undefined)[]): boolean;
1336
+ }
1337
+
1338
+ declare class OIMObjectValueByKeySelector<TKey extends string, TValue> extends OIMSelector<TValue | undefined> {
1339
+ private readonly obj;
1340
+ private readonly key;
1341
+ constructor(runtime: OIMComputativeRuntime, obj: OIMReactiveObject<TKey, TValue>, key: TKey);
1342
+ getValue(): TValue | undefined;
1343
+ }
1344
+
1345
+ declare class OIMObjectValuesByKeysSelector<TKey extends string, TValue> extends OIMSelector<readonly (TValue | undefined)[]> {
1346
+ private readonly obj;
1347
+ private readonly keys;
1348
+ constructor(runtime: OIMComputativeRuntime, obj: OIMReactiveObject<TKey, TValue>, keys: readonly TKey[]);
1349
+ getValue(): readonly (TValue | undefined)[];
1350
+ protected areEqual(prev: readonly (TValue | undefined)[], next: readonly (TValue | undefined)[]): boolean;
1351
+ }
1352
+
1353
+ declare class OIMIndexPksByKeySetBasedSelector<TKey extends TOIMPk, TPk extends TOIMPk, TIndex extends OIMIndexSetBased<TKey, TPk>> extends OIMSelector<Set<TPk>> {
1354
+ private readonly reactiveIndex;
1355
+ private readonly key;
1356
+ constructor(runtime: OIMComputativeRuntime, reactiveIndex: OIMReactiveIndexSetBased<TKey, TPk, TIndex>, key: TKey);
1357
+ getValue(): Set<TPk>;
1358
+ }
1359
+
1360
+ declare class OIMIndexPksByKeyArrayBasedSelector<TKey extends TOIMPk, TPk extends TOIMPk, TIndex extends OIMIndexArrayBased<TKey, TPk>> extends OIMSelector<readonly TPk[]> {
1361
+ private readonly reactiveIndex;
1362
+ private readonly key;
1363
+ constructor(runtime: OIMComputativeRuntime, reactiveIndex: OIMReactiveIndexArrayBased<TKey, TPk, TIndex>, key: TKey);
1364
+ getValue(): readonly TPk[];
1365
+ protected areEqual(prev: readonly TPk[], next: readonly TPk[]): boolean;
1366
+ }
1367
+
1368
+ declare class OIMIndexPksByKeysSetBasedSelector<TKey extends TOIMPk, TPk extends TOIMPk, TIndex extends OIMIndexSetBased<TKey, TPk>> extends OIMSelector<readonly TPk[]> {
1369
+ private readonly reactiveIndex;
1370
+ private readonly keys;
1371
+ constructor(runtime: OIMComputativeRuntime, reactiveIndex: OIMReactiveIndexSetBased<TKey, TPk, TIndex>, keys: readonly TKey[]);
1372
+ getValue(): readonly TPk[];
1373
+ protected areEqual(prev: readonly TPk[], next: readonly TPk[]): boolean;
1374
+ }
1375
+
1376
+ declare class OIMIndexPksByKeysArrayBasedSelector<TKey extends TOIMPk, TPk extends TOIMPk, TIndex extends OIMIndexArrayBased<TKey, TPk>> extends OIMSelector<readonly TPk[]> {
1377
+ private readonly reactiveIndex;
1378
+ private readonly keys;
1379
+ constructor(runtime: OIMComputativeRuntime, reactiveIndex: OIMReactiveIndexArrayBased<TKey, TPk, TIndex>, keys: readonly TKey[]);
1380
+ getValue(): readonly TPk[];
1381
+ protected areEqual(prev: readonly TPk[], next: readonly TPk[]): boolean;
1382
+ }
1383
+
1384
+ declare class OIMEntitiesByIndexKeySetBasedSelector<TEntity extends object, TPk extends TOIMPk, TKey extends TOIMPk, TIndex extends OIMIndexSetBased<TKey, TPk>> extends OIMSelector<readonly (TEntity | undefined)[]> {
1385
+ private readonly collection;
1386
+ private readonly reactiveIndex;
1387
+ private readonly key;
1388
+ constructor(runtime: OIMComputativeRuntime, collection: OIMReactiveCollection<TEntity, TPk>, reactiveIndex: OIMReactiveIndexSetBased<TKey, TPk, TIndex>, key: TKey);
1389
+ getValue(): readonly (TEntity | undefined)[];
1390
+ protected areEqual(prev: readonly (TEntity | undefined)[], next: readonly (TEntity | undefined)[]): boolean;
1391
+ }
1392
+
1393
+ declare class OIMEntitiesByIndexKeyArrayBasedSelector<TEntity extends object, TPk extends TOIMPk, TKey extends TOIMPk, TIndex extends OIMIndexArrayBased<TKey, TPk>> extends OIMSelector<readonly (TEntity | undefined)[]> {
1394
+ private readonly collection;
1395
+ private readonly reactiveIndex;
1396
+ private readonly key;
1397
+ constructor(runtime: OIMComputativeRuntime, collection: OIMReactiveCollection<TEntity, TPk>, reactiveIndex: OIMReactiveIndexArrayBased<TKey, TPk, TIndex>, key: TKey);
1398
+ getValue(): readonly (TEntity | undefined)[];
1399
+ protected areEqual(prev: readonly (TEntity | undefined)[], next: readonly (TEntity | undefined)[]): boolean;
1236
1400
  }
1237
1401
 
1238
- export { EOIMCollectionEventType, EOIMComputedEventType, EOIMEffectPhase, EOIMEventQueueEventType, EOIMEventQueueSchedulerEventType, EOIMIndexEventType, EOIMObjectEventType, EOIMUpdateEventCoalescerEventType, type IOIMComputedEventSource, type IOIMEffectDependency, type IOIMEventQueueSchedulerEvents, OIMCollection, OIMCollectionChangedFieldsWrapper, OIMCollectionStore, OIMCollectionStoreMapDriven, OIMComparatorFactory, OIMComputed, OIMDBSettings, OIMEffect, OIMEffectDependencyComputed, OIMEffectDependencyKeyed, OIMEffectDependencyKeyedCollection, OIMEffectDependencyKeyedIndex, OIMEffectDependencyKeyedObject, OIMEntityUpdaterFactory, OIMEventEmitter, OIMEventQueue, OIMEventQueueScheduler, OIMEventQueueSchedulerAnimationFrame, OIMEventQueueSchedulerFactory, OIMEventQueueSchedulerImmediate, OIMEventQueueSchedulerMicrotask, OIMEventQueueSchedulerTimeout, OIMIndexArrayBased, OIMIndexComparatorFactory, OIMIndexManualArrayBased, OIMIndexManualOrderedArrayBased, OIMIndexManualSetBased, OIMIndexSetBased, OIMIndexStoreArrayBased, OIMIndexStoreMapDrivenArrayBased, OIMIndexStoreMapDrivenSetBased, OIMIndexStoreSetBased, OIMMap2Keys, OIMObject, OIMObjectStore, OIMObjectStoreMapDriven, OIMObjectStoreRecordDriven, OIMOrderedListIndexCommandStreamWrapper, OIMPkSelectorFactory, OIMRICollection, OIMReactiveCollection, OIMReactiveIndexArrayBased, OIMReactiveIndexManualArrayBased, OIMReactiveIndexManualSetBased, OIMReactiveIndexSetBased, OIMReactiveObject, OIMUpdateEventCoalescer, OIMUpdateEventCoalescerCollection, OIMUpdateEventCoalescerComputed, OIMUpdateEventCoalescerIndex, OIMUpdateEventCoalescerManual, OIMUpdateEventCoalescerObject, OIMUpdateEventEmitter, type TOIMCollectionOptions, type TOIMCollectionUpdatePayload, type TOIMComparator, type TOIMComputedOptions, type TOIMComputedUpdatePayload, type TOIMEffectOptions, type TOIMEntityUpdater, type TOIMEventHandler, type TOIMEventQueueOptions, type TOIMIndexComparator, type TOIMIndexKey, type TOIMIndexOptions, type TOIMIndexOptionsArrayBased, type TOIMIndexOptionsSetBased, type TOIMIndexPksUpdatePayload, type TOIMIndexUpdatePayload, type TOIMObjectOptions, type TOIMOrderedListCommand, type TOIMPk, type TOIMPkSelector, type TOIMSchedulerOptions, type TOIMSchedulerType, type TOIMUpdateEventEmitterOptions, type TOIMUpdatePayload };
1402
+ export { EOIMCollectionEventType, EOIMComputedEventType, EOIMEventQueueEventType, EOIMEventQueueSchedulerEventType, EOIMIndexEventType, EOIMObjectEventType, type IOIMComputedEventSource, type IOIMEffectDependency, type IOIMEventQueueSchedulerEvents, OIMCollection, OIMCollectionByPkSelector, OIMCollectionByPksSelector, OIMCollectionChangedFieldsWrapper, OIMCollectionStore, OIMCollectionStoreMapDriven, OIMComparatorFactory, OIMComputativeRuntime, OIMComputed, OIMDBSettings, OIMEffect, OIMEffectDependencyComputed, OIMEffectDependencyKeyed, OIMEffectDependencyKeyedCollection, OIMEffectDependencyKeyedIndex, OIMEffectDependencyKeyedObject, OIMEntitiesByIndexKeyArrayBasedSelector, OIMEntitiesByIndexKeySetBasedSelector, OIMEntityUpdaterFactory, OIMEventEmitter, OIMEventQueue, OIMEventQueueScheduler, OIMEventQueueSchedulerAnimationFrame, OIMEventQueueSchedulerFactory, OIMEventQueueSchedulerImmediate, OIMEventQueueSchedulerMicrotask, OIMEventQueueSchedulerTimeout, OIMIndexArrayBased, OIMIndexComparatorFactory, OIMIndexManualArrayBased, OIMIndexManualOrderedArrayBased, OIMIndexManualSetBased, OIMIndexPksByKeyArrayBasedSelector, OIMIndexPksByKeySetBasedSelector, OIMIndexPksByKeysArrayBasedSelector, OIMIndexPksByKeysSetBasedSelector, OIMIndexSetBased, OIMIndexStoreArrayBased, OIMIndexStoreMapDrivenArrayBased, OIMIndexStoreMapDrivenSetBased, OIMIndexStoreSetBased, OIMMap2Keys, OIMObject, OIMObjectStore, OIMObjectStoreMapDriven, OIMObjectStoreRecordDriven, OIMObjectValueByKeySelector, OIMObjectValuesByKeysSelector, OIMOrderedListIndexCommandStreamWrapper, OIMPkSelectorFactory, OIMRICollection, OIMReactiveCollection, OIMReactiveIndexArrayBased, OIMReactiveIndexManualArrayBased, OIMReactiveIndexManualSetBased, OIMReactiveIndexSetBased, OIMReactiveObject, OIMSelector, type TOIMAnyEntitySlot, type TOIMCollectionOptions, type TOIMCollectionUpdatePayload, type TOIMComparator, type TOIMComputedOptions, type TOIMComputedUpdatePayload, type TOIMEffectOptions, type TOIMEntitySlot, type TOIMEntitySlotResolver, type TOIMEntityUpdater, type TOIMEventHandler, type TOIMEventQueueOptions, type TOIMIndexComparator, type TOIMIndexKey, type TOIMIndexOptions, type TOIMIndexOptionsArrayBased, type TOIMIndexOptionsSetBased, type TOIMIndexPksUpdatePayload, type TOIMIndexUpdatePayload, type TOIMObjectOptions, type TOIMOrderedListCommand, type TOIMPk, type TOIMPkSelector, type TOIMSchedulerOptions, type TOIMSchedulerType, type TOIMUpdatePayload };