@oimdb/core 3.0.1 → 3.2.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.cjs +581 -498
- package/dist/index.d.cts +138 -71
- package/dist/index.d.ts +138 -71
- package/dist/index.js +581 -498
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -197,6 +197,33 @@ declare abstract class OIMIndexArrayBased<TKey extends TOIMPk, TPk extends TOIMP
|
|
|
197
197
|
protected setSlotsWithComparison(key: TKey, newSlots: TOIMAnyEntitySlot<TPk>[]): boolean;
|
|
198
198
|
}
|
|
199
199
|
|
|
200
|
+
/**
|
|
201
|
+
* The keyed pub/sub surface a reactive node needs from its update emitter:
|
|
202
|
+
* per-key subscribe/unsubscribe plus batched "mark updated" delivery.
|
|
203
|
+
*
|
|
204
|
+
* Both keyed emitters implement it — `OIMUpdateEventEmitter` (Map of handlers)
|
|
205
|
+
* and `OIMCarrierKeyedEmitter` (handlers on a per-key carrier). Typing the node
|
|
206
|
+
* against this interface lets either back the node without leaking the carrier
|
|
207
|
+
* generic into the node's signatures.
|
|
208
|
+
*/
|
|
209
|
+
interface IOIMKeyedUpdateEmitter<TKey extends TOIMPk> {
|
|
210
|
+
subscribeOnKey(key: TKey, handler: TOIMEventHandler<void>): () => void;
|
|
211
|
+
subscribeOnKeys(keys: readonly TKey[], handler: TOIMEventHandler<void>): () => void;
|
|
212
|
+
unsubscribeFromKey(key: TKey, handler: TOIMEventHandler<void>): void;
|
|
213
|
+
unsubscribeFromKeys(keys: readonly TKey[], handler: TOIMEventHandler<void>): void;
|
|
214
|
+
markUpdatedKey(key: TKey): void;
|
|
215
|
+
markUpdatedKeys(keys: readonly TKey[]): void;
|
|
216
|
+
hasSubscriptions(): boolean;
|
|
217
|
+
getHandlerCount(key: TKey): number;
|
|
218
|
+
getMetrics(): {
|
|
219
|
+
totalKeys: number;
|
|
220
|
+
totalHandlers: number;
|
|
221
|
+
averageHandlersPerKey: number;
|
|
222
|
+
queueLength: number;
|
|
223
|
+
};
|
|
224
|
+
destroy(): void;
|
|
225
|
+
}
|
|
226
|
+
|
|
200
227
|
/**
|
|
201
228
|
* Configuration options for event queue initialization.
|
|
202
229
|
*/
|
|
@@ -220,6 +247,8 @@ declare enum EOIMEventQueueEventType {
|
|
|
220
247
|
declare class OIMEventQueue {
|
|
221
248
|
readonly emitter: OIMEventEmitter<Record<EOIMEventQueueEventType, void>>;
|
|
222
249
|
protected tasks: Set<() => void>;
|
|
250
|
+
protected tasksSpare: Set<() => void>;
|
|
251
|
+
protected flushing?: Set<() => void>;
|
|
223
252
|
protected readonly scheduler?: OIMEventQueueScheduler;
|
|
224
253
|
protected flushBound?: () => void;
|
|
225
254
|
protected isFlushing: boolean;
|
|
@@ -229,6 +258,16 @@ declare class OIMEventQueue {
|
|
|
229
258
|
* Returns a dequeue function that can be called to cancel the task before it runs.
|
|
230
259
|
*/
|
|
231
260
|
enqueue(fn: () => void): () => void;
|
|
261
|
+
/**
|
|
262
|
+
* Allocation-free enqueue for a **stable** function reference (e.g. a bound
|
|
263
|
+
* `onFlush` method). The function is stored directly — no wrapper, no
|
|
264
|
+
* returned closure — and cancelled via {@link cancelTask}. Enqueuing the
|
|
265
|
+
* same reference twice is idempotent (Set-deduped); callers that may run a
|
|
266
|
+
* task more than once per flush should use {@link enqueue} instead.
|
|
267
|
+
*/
|
|
268
|
+
enqueueTask(fn: () => void): void;
|
|
269
|
+
/** Cancel a task scheduled via {@link enqueueTask}; safe to call mid-flush. */
|
|
270
|
+
cancelTask(fn: () => void): void;
|
|
232
271
|
get isInFlush(): boolean;
|
|
233
272
|
/**
|
|
234
273
|
* Dequeue (cancel) a previously enqueued task by its dequeue function.
|
|
@@ -260,68 +299,6 @@ declare class OIMEventQueue {
|
|
|
260
299
|
destroy(): void;
|
|
261
300
|
}
|
|
262
301
|
|
|
263
|
-
type TOIMUpdateEventEmitterDeliveryMode = 'queue' | 'after_flush' | 'immediate';
|
|
264
|
-
/**
|
|
265
|
-
* Universal event emitter that handles subscriptions and notifications for any key type.
|
|
266
|
-
* Optimized for performance with adaptive algorithms and memory management.
|
|
267
|
-
*/
|
|
268
|
-
declare class OIMUpdateEventEmitter<TKey extends TOIMPk> {
|
|
269
|
-
protected keyHandlers: Map<TKey, Set<TOIMEventHandler<void>>>;
|
|
270
|
-
protected queue: OIMEventQueue;
|
|
271
|
-
private readonly deliveryMode;
|
|
272
|
-
private isFlushEnqueued;
|
|
273
|
-
private dequeueFlush?;
|
|
274
|
-
private updatedKeys;
|
|
275
|
-
private isAfterFlushDeliveryScheduled;
|
|
276
|
-
private unsubscribeAfterFlushDelivery?;
|
|
277
|
-
constructor(queue: OIMEventQueue, deliveryMode?: TOIMUpdateEventEmitterDeliveryMode);
|
|
278
|
-
/**
|
|
279
|
-
* Mark keys as updated and schedule delivery.
|
|
280
|
-
*
|
|
281
|
-
* If there are no subscriptions, this is a no-op and does not allocate or retain keys.
|
|
282
|
-
*/
|
|
283
|
-
markUpdatedKeys(keys: readonly TKey[]): void;
|
|
284
|
-
markUpdatedKey(key: TKey): void;
|
|
285
|
-
markAllUpdated(): void;
|
|
286
|
-
protected readonly onFlush: () => void;
|
|
287
|
-
private deliverImmediate;
|
|
288
|
-
/**
|
|
289
|
-
* Notifies all handlers for a key. The overwhelmingly common case is a
|
|
290
|
-
* single subscriber per key (one component per pk), handled without any
|
|
291
|
-
* allocation. For multiple subscribers a snapshot is taken so a handler may
|
|
292
|
-
* (un)subscribe during iteration without corrupting the walk.
|
|
293
|
-
*/
|
|
294
|
-
private notifyHandlers;
|
|
295
|
-
private readonly onAfterFlush;
|
|
296
|
-
/**
|
|
297
|
-
* Deliver updated keys and notify handlers once.
|
|
298
|
-
* Re-entrant updates during delivery are forbidden and will throw in markUpdatedKeys().
|
|
299
|
-
*/
|
|
300
|
-
protected runSinglePass(): void;
|
|
301
|
-
destroy(): void;
|
|
302
|
-
/**
|
|
303
|
-
* Get performance metrics for monitoring and debugging
|
|
304
|
-
*/
|
|
305
|
-
getMetrics(): {
|
|
306
|
-
totalKeys: number;
|
|
307
|
-
totalHandlers: number;
|
|
308
|
-
averageHandlersPerKey: number;
|
|
309
|
-
queueLength: number;
|
|
310
|
-
};
|
|
311
|
-
/**
|
|
312
|
-
* Check if there are any active subscriptions
|
|
313
|
-
*/
|
|
314
|
-
hasSubscriptions(): boolean;
|
|
315
|
-
/**
|
|
316
|
-
* Get the number of handlers for a specific key
|
|
317
|
-
*/
|
|
318
|
-
getHandlerCount(key: TKey): number;
|
|
319
|
-
subscribeOnKey(key: TKey, handler: TOIMEventHandler<void>): () => void;
|
|
320
|
-
unsubscribeFromKey(key: TKey, handler: TOIMEventHandler<void>): void;
|
|
321
|
-
subscribeOnKeys(keys: readonly TKey[], handler: TOIMEventHandler<void>): () => void;
|
|
322
|
-
unsubscribeFromKeys(keys: readonly TKey[], handler: TOIMEventHandler<void>): void;
|
|
323
|
-
}
|
|
324
|
-
|
|
325
302
|
interface IOIMKeyedSubscription<TKey extends TOIMPk> {
|
|
326
303
|
subscribeOnKey(key: TKey, handler: TOIMEventHandler<void>): () => void;
|
|
327
304
|
subscribeOnKeys(keys: readonly TKey[], handler: TOIMEventHandler<void>): () => void;
|
|
@@ -329,8 +306,8 @@ interface IOIMKeyedSubscription<TKey extends TOIMPk> {
|
|
|
329
306
|
|
|
330
307
|
declare abstract class OIMReactiveIndex<TKey extends TOIMPk, TPk extends TOIMPk, TIndex extends OIMIndex<TKey, TPk, Iterable<TOIMAnyEntitySlot<TPk>>>> implements IOIMKeyedSubscription<TKey> {
|
|
331
308
|
readonly index: TIndex;
|
|
332
|
-
protected readonly updateEmitter:
|
|
333
|
-
constructor(queue: OIMEventQueue, createIndex: (updateEmitter:
|
|
309
|
+
protected readonly updateEmitter: IOIMKeyedUpdateEmitter<TKey>;
|
|
310
|
+
constructor(queue: OIMEventQueue, createIndex: (updateEmitter: IOIMKeyedUpdateEmitter<TKey>) => TIndex);
|
|
334
311
|
getEntitiesByKey<TEntity extends object = object>(key: TKey): (TEntity | undefined)[];
|
|
335
312
|
getEntitiesByKeys<TEntity extends object = object>(keys: readonly TKey[]): Map<TKey, (TEntity | undefined)[]>;
|
|
336
313
|
hasKey(key: TKey): boolean;
|
|
@@ -361,7 +338,7 @@ declare abstract class OIMReactiveIndex<TKey extends TOIMPk, TPk extends TOIMPk,
|
|
|
361
338
|
}
|
|
362
339
|
|
|
363
340
|
declare abstract class OIMReactiveIndexSetBased<TKey extends TOIMPk, TPk extends TOIMPk, TIndex extends OIMIndexSetBased<TKey, TPk>> extends OIMReactiveIndex<TKey, TPk, TIndex> {
|
|
364
|
-
constructor(queue: OIMEventQueue, createIndex: (updateEmitter:
|
|
341
|
+
constructor(queue: OIMEventQueue, createIndex: (updateEmitter: IOIMKeyedUpdateEmitter<TKey>) => TIndex);
|
|
365
342
|
getPksByKey(key: TKey): Set<TPk>;
|
|
366
343
|
getPksByKeys(keys: readonly TKey[]): Map<TKey, Set<TPk>>;
|
|
367
344
|
getSlotsByKey(key: TKey): ReadonlySet<TOIMAnyEntitySlot<TPk>>;
|
|
@@ -369,7 +346,7 @@ declare abstract class OIMReactiveIndexSetBased<TKey extends TOIMPk, TPk extends
|
|
|
369
346
|
}
|
|
370
347
|
|
|
371
348
|
declare abstract class OIMReactiveIndexArrayBased<TKey extends TOIMPk, TPk extends TOIMPk, TIndex extends OIMIndexArrayBased<TKey, TPk>> extends OIMReactiveIndex<TKey, TPk, TIndex> {
|
|
372
|
-
constructor(queue: OIMEventQueue, createIndex: (updateEmitter:
|
|
349
|
+
constructor(queue: OIMEventQueue, createIndex: (updateEmitter: IOIMKeyedUpdateEmitter<TKey>) => TIndex);
|
|
373
350
|
getPksByKey(key: TKey): TPk[];
|
|
374
351
|
getPksByKeys(keys: readonly TKey[]): Map<TKey, TPk[]>;
|
|
375
352
|
getSlotsByKey(key: TKey): readonly TOIMAnyEntitySlot<TPk>[];
|
|
@@ -442,6 +419,14 @@ declare class OIMCollection<TEntity extends object, TPk extends TOIMPk> {
|
|
|
442
419
|
*/
|
|
443
420
|
interface IOIMSubscribable {
|
|
444
421
|
subscribers?: Set<() => void>;
|
|
422
|
+
/**
|
|
423
|
+
* Dirty-batch membership flag, owned by the keyed emitter. `true` while the
|
|
424
|
+
* carrier sits in the pending flush batch — lets the emitter dedup marks with
|
|
425
|
+
* an O(1) boolean check instead of a `Set` identity-hash lookup. Reset to
|
|
426
|
+
* `false` as the carrier is delivered (or on flush teardown). Do not read or
|
|
427
|
+
* write outside the emitter.
|
|
428
|
+
*/
|
|
429
|
+
dirty?: boolean;
|
|
445
430
|
}
|
|
446
431
|
|
|
447
432
|
/**
|
|
@@ -456,6 +441,13 @@ interface IOIMSubscribable {
|
|
|
456
441
|
interface IOIMCarrierResolver<TKey extends TOIMPk, TCarrier> {
|
|
457
442
|
getOrReserveCarrier(key: TKey): TCarrier;
|
|
458
443
|
findCarrier(key: TKey): TCarrier | undefined;
|
|
444
|
+
/**
|
|
445
|
+
* Optional: called when a carrier loses its last subscriber, so a resolver
|
|
446
|
+
* that owns standalone carriers (e.g. the index's key→carrier map) can prune
|
|
447
|
+
* it and not leak the key space. Resolvers whose carriers are owned
|
|
448
|
+
* elsewhere (e.g. the collection's slots) leave this unset.
|
|
449
|
+
*/
|
|
450
|
+
onCarrierEmptied?(carrier: TCarrier): void;
|
|
459
451
|
}
|
|
460
452
|
/**
|
|
461
453
|
* Keyed (per-key) pub/sub that stores handlers ON the carrier object
|
|
@@ -468,13 +460,12 @@ interface IOIMCarrierResolver<TKey extends TOIMPk, TCarrier> {
|
|
|
468
460
|
* index's keyed emitter. Reused with carrier = slot (collection) or carrier =
|
|
469
461
|
* bucket (index).
|
|
470
462
|
*/
|
|
471
|
-
declare class OIMCarrierKeyedEmitter<TKey extends TOIMPk, TCarrier extends IOIMSubscribable> {
|
|
463
|
+
declare class OIMCarrierKeyedEmitter<TKey extends TOIMPk, TCarrier extends IOIMSubscribable> implements IOIMKeyedUpdateEmitter<TKey> {
|
|
472
464
|
private readonly queue;
|
|
473
465
|
private readonly resolver;
|
|
474
466
|
private readonly subscribedCarriers;
|
|
475
467
|
private dirtyCarriers;
|
|
476
468
|
private isFlushEnqueued;
|
|
477
|
-
private dequeueFlush?;
|
|
478
469
|
constructor(queue: OIMEventQueue, resolver: IOIMCarrierResolver<TKey, TCarrier>);
|
|
479
470
|
subscribeOnKey(key: TKey, handler: TOIMEventHandler<void>): () => void;
|
|
480
471
|
subscribeOnKeys(keys: readonly TKey[], handler: TOIMEventHandler<void>): () => void;
|
|
@@ -509,7 +500,6 @@ declare class OIMReactiveCollection<TEntity extends object, TPk extends TOIMPk>
|
|
|
509
500
|
private pendingAnyUpdatePks;
|
|
510
501
|
private isAnyUpdateClearPending;
|
|
511
502
|
private isAnyUpdateScheduled;
|
|
512
|
-
private dequeueAnyUpdate?;
|
|
513
503
|
constructor(queue: OIMEventQueue, opts?: TOIMCollectionOptions<TEntity, TPk>);
|
|
514
504
|
subscribeOnKey(pk: TPk, handler: TOIMEventHandler<void>): () => void;
|
|
515
505
|
subscribeOnKeys(pks: readonly TPk[], handler: TOIMEventHandler<void>): () => void;
|
|
@@ -671,6 +661,67 @@ declare class OIMCollectionIndexManualOrderedArrayBased<TKey extends TOIMPk, TPk
|
|
|
671
661
|
private resolveRequiredSlot;
|
|
672
662
|
}
|
|
673
663
|
|
|
664
|
+
type TOIMUpdateEventEmitterDeliveryMode = 'queue' | 'after_flush' | 'immediate';
|
|
665
|
+
/**
|
|
666
|
+
* Universal event emitter that handles subscriptions and notifications for any key type.
|
|
667
|
+
* Optimized for performance with adaptive algorithms and memory management.
|
|
668
|
+
*/
|
|
669
|
+
declare class OIMUpdateEventEmitter<TKey extends TOIMPk> {
|
|
670
|
+
protected keyHandlers: Map<TKey, Set<TOIMEventHandler<void>>>;
|
|
671
|
+
protected queue: OIMEventQueue;
|
|
672
|
+
private readonly deliveryMode;
|
|
673
|
+
private isFlushEnqueued;
|
|
674
|
+
private updatedKeys;
|
|
675
|
+
private isAfterFlushDeliveryScheduled;
|
|
676
|
+
private unsubscribeAfterFlushDelivery?;
|
|
677
|
+
constructor(queue: OIMEventQueue, deliveryMode?: TOIMUpdateEventEmitterDeliveryMode);
|
|
678
|
+
/**
|
|
679
|
+
* Mark keys as updated and schedule delivery.
|
|
680
|
+
*
|
|
681
|
+
* If there are no subscriptions, this is a no-op and does not allocate or retain keys.
|
|
682
|
+
*/
|
|
683
|
+
markUpdatedKeys(keys: readonly TKey[]): void;
|
|
684
|
+
markUpdatedKey(key: TKey): void;
|
|
685
|
+
markAllUpdated(): void;
|
|
686
|
+
protected readonly onFlush: () => void;
|
|
687
|
+
private deliverImmediate;
|
|
688
|
+
/**
|
|
689
|
+
* Notifies all handlers for a key. The overwhelmingly common case is a
|
|
690
|
+
* single subscriber per key (one component per pk), handled without any
|
|
691
|
+
* allocation. For multiple subscribers a snapshot is taken so a handler may
|
|
692
|
+
* (un)subscribe during iteration without corrupting the walk.
|
|
693
|
+
*/
|
|
694
|
+
private notifyHandlers;
|
|
695
|
+
private readonly onAfterFlush;
|
|
696
|
+
/**
|
|
697
|
+
* Deliver updated keys and notify handlers once.
|
|
698
|
+
* Re-entrant updates during delivery are forbidden and will throw in markUpdatedKeys().
|
|
699
|
+
*/
|
|
700
|
+
protected runSinglePass(): void;
|
|
701
|
+
destroy(): void;
|
|
702
|
+
/**
|
|
703
|
+
* Get performance metrics for monitoring and debugging
|
|
704
|
+
*/
|
|
705
|
+
getMetrics(): {
|
|
706
|
+
totalKeys: number;
|
|
707
|
+
totalHandlers: number;
|
|
708
|
+
averageHandlersPerKey: number;
|
|
709
|
+
queueLength: number;
|
|
710
|
+
};
|
|
711
|
+
/**
|
|
712
|
+
* Check if there are any active subscriptions
|
|
713
|
+
*/
|
|
714
|
+
hasSubscriptions(): boolean;
|
|
715
|
+
/**
|
|
716
|
+
* Get the number of handlers for a specific key
|
|
717
|
+
*/
|
|
718
|
+
getHandlerCount(key: TKey): number;
|
|
719
|
+
subscribeOnKey(key: TKey, handler: TOIMEventHandler<void>): () => void;
|
|
720
|
+
unsubscribeFromKey(key: TKey, handler: TOIMEventHandler<void>): void;
|
|
721
|
+
subscribeOnKeys(keys: readonly TKey[], handler: TOIMEventHandler<void>): () => void;
|
|
722
|
+
unsubscribeFromKeys(keys: readonly TKey[], handler: TOIMEventHandler<void>): void;
|
|
723
|
+
}
|
|
724
|
+
|
|
674
725
|
type TOIMOrderedListCommand<TPk extends TOIMPk, TEntity extends object = object> = {
|
|
675
726
|
type: 'insert';
|
|
676
727
|
pk: TPk;
|
|
@@ -957,6 +1008,15 @@ declare class OIMObject<TKey extends string, TValue> {
|
|
|
957
1008
|
get(key: TKey): TValue | undefined;
|
|
958
1009
|
getAll(): Record<TKey, TValue>;
|
|
959
1010
|
clear(): void;
|
|
1011
|
+
/**
|
|
1012
|
+
* Write fan-out hooks. Split single-key vs multi-key so a reactive subclass
|
|
1013
|
+
* can mark its keyed emitter on the hot single-property path without
|
|
1014
|
+
* allocating a `{ keys: [key] }` payload. The base only fires the general
|
|
1015
|
+
* UPDATE event, and only when something is actually subscribed to it — so an
|
|
1016
|
+
* unobserved write skips the payload allocation entirely.
|
|
1017
|
+
*/
|
|
1018
|
+
protected onUpdatedKey(key: TKey): void;
|
|
1019
|
+
protected onUpdatedKeys(keys: TKey[]): void;
|
|
960
1020
|
count(): number;
|
|
961
1021
|
keys(): TKey[];
|
|
962
1022
|
values(): TValue[];
|
|
@@ -965,8 +1025,15 @@ declare class OIMObject<TKey extends string, TValue> {
|
|
|
965
1025
|
}
|
|
966
1026
|
|
|
967
1027
|
declare class OIMReactiveObject<TKey extends string, TValue> extends OIMObject<TKey, TValue> implements IOIMKeyedSubscription<TKey> {
|
|
968
|
-
protected readonly updateEmitter:
|
|
1028
|
+
protected readonly updateEmitter: IOIMKeyedUpdateEmitter<TKey>;
|
|
969
1029
|
constructor(queue: OIMEventQueue, opts?: TOIMObjectOptions<TKey, TValue>);
|
|
1030
|
+
/**
|
|
1031
|
+
* Mark the written key(s) on the keyed emitter directly — no general-event
|
|
1032
|
+
* bridge, no `{ keys }` payload on the single-key path. `super` still fires
|
|
1033
|
+
* the general UPDATE event for any low-level `emitter` subscribers.
|
|
1034
|
+
*/
|
|
1035
|
+
protected onUpdatedKey(key: TKey): void;
|
|
1036
|
+
protected onUpdatedKeys(keys: TKey[]): void;
|
|
970
1037
|
subscribeOnKey(key: TKey, handler: TOIMEventHandler<void>): () => void;
|
|
971
1038
|
subscribeOnKeys(keys: readonly TKey[], handler: TOIMEventHandler<void>): () => void;
|
|
972
1039
|
unsubscribeFromKey(key: TKey, handler: TOIMEventHandler<void>): void;
|
|
@@ -1633,4 +1700,4 @@ declare class OIMEntitiesByIndexKeyArrayBasedSelector<TEntity extends object, TP
|
|
|
1633
1700
|
protected areEqual(prev: readonly (TEntity | undefined)[], next: readonly (TEntity | undefined)[]): boolean;
|
|
1634
1701
|
}
|
|
1635
1702
|
|
|
1636
|
-
export { EOIMCollectionEventType, EOIMComputedEventType, EOIMEventQueueEventType, EOIMEventQueueSchedulerEventType, EOIMIndexEventType, EOIMObjectEventType, type IOIMCarrierResolver, type IOIMComputedEventSource, type IOIMEffectDependency, type IOIMEventQueueSchedulerEvents, type IOIMIndexStore, type IOIMSubscribable, OIMCarrierKeyedEmitter, OIMCollection, OIMCollectionByPkSelector, OIMCollectionByPksSelector, OIMCollectionChangedFields, OIMCollectionIndexFactory, OIMCollectionIndexManualOrderedArrayBased, OIMCollectionOrderedListCommandStream, OIMCollectionSelectors, OIMCollectionStore, OIMCollectionStoreMapDriven, OIMComparatorFactory, OIMComputeRuntime, OIMComputed, OIMDBSettings, OIMDerivedCollectionIndexArrayBased, OIMDerivedCollectionIndexSetBased, OIMEffect, OIMEffectDependencyComputed, OIMEffectDependencyKeyed, OIMEffectDependencyKeyedCollection, OIMEffectDependencyKeyedIndex, OIMEffectDependencyKeyedObject, OIMEntitiesByIndexKeyArrayBasedSelector, OIMEntitiesByIndexKeySetBasedSelector, OIMEntityUpdaterFactory, OIMEventEmitter, OIMEventQueue, OIMEventQueueScheduler, OIMEventQueueSchedulerAnimationFrame, OIMEventQueueSchedulerFactory, OIMEventQueueSchedulerImmediate, OIMEventQueueSchedulerMicrotask, OIMEventQueueSchedulerTimeout, OIMIndex, OIMIndexArrayBased, OIMIndexComparatorFactory, OIMIndexManualArrayBased, OIMIndexManualOrderedArrayBased, OIMIndexManualSetBased, OIMIndexPksByKeyArrayBasedSelector, OIMIndexPksByKeySetBasedSelector, OIMIndexPksByKeysArrayBasedSelector, OIMIndexPksByKeysSetBasedSelector, OIMIndexSetBased, OIMIndexStoreArrayBased, OIMIndexStoreMapDrivenArrayBased, OIMIndexStoreMapDrivenSetBased, OIMIndexStoreSetBased, OIMMap2Keys, OIMObject, OIMObjectStore, OIMObjectStoreMapDriven, OIMObjectStoreRecordDriven, OIMObjectValueByKeySelector, OIMObjectValuesByKeysSelector, OIMOrderedListCommandStream, OIMPkSelectorFactory, OIMReactiveCollection, OIMReactiveCollectionIndexManualArrayBased, OIMReactiveCollectionIndexManualSetBased, OIMReactiveIndex, OIMReactiveIndexArrayBased, OIMReactiveIndexManualArrayBased, OIMReactiveIndexManualSetBased, OIMReactiveIndexSetBased, OIMReactiveObject, OIMSelector, type TOIMAnyEntitySlot, type TOIMCollectionEntitiesSelector, type TOIMCollectionEntitySelector, type TOIMCollectionIndexArrayBasedOptions, type TOIMCollectionIndexSetBasedOptions, type TOIMCollectionKit, type TOIMCollectionOptions, type TOIMCollectionOrderedIndexOptions, type TOIMCollectionOrderedListCommandStreamOptions, type TOIMCollectionUpdatePayload, type TOIMComparator, type TOIMComputedOptions, type TOIMComputedUpdatePayload, type TOIMDerivedCollectionIndexArrayBasedOptions, type TOIMDerivedCollectionIndexSetBasedOptions, type TOIMDerivedEntityComparator, type TOIMDerivedEntityOrderSelector, type TOIMDerivedEntityOrderValue, type TOIMDerivedIndexKeySelector, type TOIMEffectOptions, type TOIMEntitySlot, type TOIMEntitySlotResolver, type TOIMEntityUpdater, type TOIMEventHandler, type TOIMEventQueueOptions, type TOIMIndexComparator, type TOIMIndexKey, type TOIMIndexOptionsArrayBased, type TOIMIndexOptionsSetBased, type TOIMIndexPksUpdatePayload, type TOIMIndexUpdatePayload, type TOIMObjectOptions, type TOIMOrderedListCommand, type TOIMPk, type TOIMPkSelector, type TOIMReactiveCollectionFactoryOptions, type TOIMRelationsArrayIndexOptions, type TOIMRelationsDerivedArrayIndexOptions, type TOIMRelationsDerivedSetIndexOptions, type TOIMRelationsOrderedListOptions, type TOIMRelationsSetIndexOptions, type TOIMSchedulerOptions, type TOIMSchedulerType, type TOIMUpdatePayload, createInPlaceEntityUpdater, createOIMCollectionIndexFactory, createOIMCollectionKit };
|
|
1703
|
+
export { EOIMCollectionEventType, EOIMComputedEventType, EOIMEventQueueEventType, EOIMEventQueueSchedulerEventType, EOIMIndexEventType, EOIMObjectEventType, type IOIMCarrierResolver, type IOIMComputedEventSource, type IOIMEffectDependency, type IOIMEventQueueSchedulerEvents, type IOIMIndexStore, type IOIMKeyedUpdateEmitter, type IOIMSubscribable, OIMCarrierKeyedEmitter, OIMCollection, OIMCollectionByPkSelector, OIMCollectionByPksSelector, OIMCollectionChangedFields, OIMCollectionIndexFactory, OIMCollectionIndexManualOrderedArrayBased, OIMCollectionOrderedListCommandStream, OIMCollectionSelectors, OIMCollectionStore, OIMCollectionStoreMapDriven, OIMComparatorFactory, OIMComputeRuntime, OIMComputed, OIMDBSettings, OIMDerivedCollectionIndexArrayBased, OIMDerivedCollectionIndexSetBased, OIMEffect, OIMEffectDependencyComputed, OIMEffectDependencyKeyed, OIMEffectDependencyKeyedCollection, OIMEffectDependencyKeyedIndex, OIMEffectDependencyKeyedObject, OIMEntitiesByIndexKeyArrayBasedSelector, OIMEntitiesByIndexKeySetBasedSelector, OIMEntityUpdaterFactory, OIMEventEmitter, OIMEventQueue, OIMEventQueueScheduler, OIMEventQueueSchedulerAnimationFrame, OIMEventQueueSchedulerFactory, OIMEventQueueSchedulerImmediate, OIMEventQueueSchedulerMicrotask, OIMEventQueueSchedulerTimeout, OIMIndex, OIMIndexArrayBased, OIMIndexComparatorFactory, OIMIndexManualArrayBased, OIMIndexManualOrderedArrayBased, OIMIndexManualSetBased, OIMIndexPksByKeyArrayBasedSelector, OIMIndexPksByKeySetBasedSelector, OIMIndexPksByKeysArrayBasedSelector, OIMIndexPksByKeysSetBasedSelector, OIMIndexSetBased, OIMIndexStoreArrayBased, OIMIndexStoreMapDrivenArrayBased, OIMIndexStoreMapDrivenSetBased, OIMIndexStoreSetBased, OIMMap2Keys, OIMObject, OIMObjectStore, OIMObjectStoreMapDriven, OIMObjectStoreRecordDriven, OIMObjectValueByKeySelector, OIMObjectValuesByKeysSelector, OIMOrderedListCommandStream, OIMPkSelectorFactory, OIMReactiveCollection, OIMReactiveCollectionIndexManualArrayBased, OIMReactiveCollectionIndexManualSetBased, OIMReactiveIndex, OIMReactiveIndexArrayBased, OIMReactiveIndexManualArrayBased, OIMReactiveIndexManualSetBased, OIMReactiveIndexSetBased, OIMReactiveObject, OIMSelector, type TOIMAnyEntitySlot, type TOIMCollectionEntitiesSelector, type TOIMCollectionEntitySelector, type TOIMCollectionIndexArrayBasedOptions, type TOIMCollectionIndexSetBasedOptions, type TOIMCollectionKit, type TOIMCollectionOptions, type TOIMCollectionOrderedIndexOptions, type TOIMCollectionOrderedListCommandStreamOptions, type TOIMCollectionUpdatePayload, type TOIMComparator, type TOIMComputedOptions, type TOIMComputedUpdatePayload, type TOIMDerivedCollectionIndexArrayBasedOptions, type TOIMDerivedCollectionIndexSetBasedOptions, type TOIMDerivedEntityComparator, type TOIMDerivedEntityOrderSelector, type TOIMDerivedEntityOrderValue, type TOIMDerivedIndexKeySelector, type TOIMEffectOptions, type TOIMEntitySlot, type TOIMEntitySlotResolver, type TOIMEntityUpdater, type TOIMEventHandler, type TOIMEventQueueOptions, type TOIMIndexComparator, type TOIMIndexKey, type TOIMIndexOptionsArrayBased, type TOIMIndexOptionsSetBased, type TOIMIndexPksUpdatePayload, type TOIMIndexUpdatePayload, type TOIMObjectOptions, type TOIMOrderedListCommand, type TOIMPk, type TOIMPkSelector, type TOIMReactiveCollectionFactoryOptions, type TOIMRelationsArrayIndexOptions, type TOIMRelationsDerivedArrayIndexOptions, type TOIMRelationsDerivedSetIndexOptions, type TOIMRelationsOrderedListOptions, type TOIMRelationsSetIndexOptions, type TOIMSchedulerOptions, type TOIMSchedulerType, type TOIMUpdatePayload, createInPlaceEntityUpdater, createOIMCollectionIndexFactory, createOIMCollectionKit };
|
package/dist/index.d.ts
CHANGED
|
@@ -197,6 +197,33 @@ declare abstract class OIMIndexArrayBased<TKey extends TOIMPk, TPk extends TOIMP
|
|
|
197
197
|
protected setSlotsWithComparison(key: TKey, newSlots: TOIMAnyEntitySlot<TPk>[]): boolean;
|
|
198
198
|
}
|
|
199
199
|
|
|
200
|
+
/**
|
|
201
|
+
* The keyed pub/sub surface a reactive node needs from its update emitter:
|
|
202
|
+
* per-key subscribe/unsubscribe plus batched "mark updated" delivery.
|
|
203
|
+
*
|
|
204
|
+
* Both keyed emitters implement it — `OIMUpdateEventEmitter` (Map of handlers)
|
|
205
|
+
* and `OIMCarrierKeyedEmitter` (handlers on a per-key carrier). Typing the node
|
|
206
|
+
* against this interface lets either back the node without leaking the carrier
|
|
207
|
+
* generic into the node's signatures.
|
|
208
|
+
*/
|
|
209
|
+
interface IOIMKeyedUpdateEmitter<TKey extends TOIMPk> {
|
|
210
|
+
subscribeOnKey(key: TKey, handler: TOIMEventHandler<void>): () => void;
|
|
211
|
+
subscribeOnKeys(keys: readonly TKey[], handler: TOIMEventHandler<void>): () => void;
|
|
212
|
+
unsubscribeFromKey(key: TKey, handler: TOIMEventHandler<void>): void;
|
|
213
|
+
unsubscribeFromKeys(keys: readonly TKey[], handler: TOIMEventHandler<void>): void;
|
|
214
|
+
markUpdatedKey(key: TKey): void;
|
|
215
|
+
markUpdatedKeys(keys: readonly TKey[]): void;
|
|
216
|
+
hasSubscriptions(): boolean;
|
|
217
|
+
getHandlerCount(key: TKey): number;
|
|
218
|
+
getMetrics(): {
|
|
219
|
+
totalKeys: number;
|
|
220
|
+
totalHandlers: number;
|
|
221
|
+
averageHandlersPerKey: number;
|
|
222
|
+
queueLength: number;
|
|
223
|
+
};
|
|
224
|
+
destroy(): void;
|
|
225
|
+
}
|
|
226
|
+
|
|
200
227
|
/**
|
|
201
228
|
* Configuration options for event queue initialization.
|
|
202
229
|
*/
|
|
@@ -220,6 +247,8 @@ declare enum EOIMEventQueueEventType {
|
|
|
220
247
|
declare class OIMEventQueue {
|
|
221
248
|
readonly emitter: OIMEventEmitter<Record<EOIMEventQueueEventType, void>>;
|
|
222
249
|
protected tasks: Set<() => void>;
|
|
250
|
+
protected tasksSpare: Set<() => void>;
|
|
251
|
+
protected flushing?: Set<() => void>;
|
|
223
252
|
protected readonly scheduler?: OIMEventQueueScheduler;
|
|
224
253
|
protected flushBound?: () => void;
|
|
225
254
|
protected isFlushing: boolean;
|
|
@@ -229,6 +258,16 @@ declare class OIMEventQueue {
|
|
|
229
258
|
* Returns a dequeue function that can be called to cancel the task before it runs.
|
|
230
259
|
*/
|
|
231
260
|
enqueue(fn: () => void): () => void;
|
|
261
|
+
/**
|
|
262
|
+
* Allocation-free enqueue for a **stable** function reference (e.g. a bound
|
|
263
|
+
* `onFlush` method). The function is stored directly — no wrapper, no
|
|
264
|
+
* returned closure — and cancelled via {@link cancelTask}. Enqueuing the
|
|
265
|
+
* same reference twice is idempotent (Set-deduped); callers that may run a
|
|
266
|
+
* task more than once per flush should use {@link enqueue} instead.
|
|
267
|
+
*/
|
|
268
|
+
enqueueTask(fn: () => void): void;
|
|
269
|
+
/** Cancel a task scheduled via {@link enqueueTask}; safe to call mid-flush. */
|
|
270
|
+
cancelTask(fn: () => void): void;
|
|
232
271
|
get isInFlush(): boolean;
|
|
233
272
|
/**
|
|
234
273
|
* Dequeue (cancel) a previously enqueued task by its dequeue function.
|
|
@@ -260,68 +299,6 @@ declare class OIMEventQueue {
|
|
|
260
299
|
destroy(): void;
|
|
261
300
|
}
|
|
262
301
|
|
|
263
|
-
type TOIMUpdateEventEmitterDeliveryMode = 'queue' | 'after_flush' | 'immediate';
|
|
264
|
-
/**
|
|
265
|
-
* Universal event emitter that handles subscriptions and notifications for any key type.
|
|
266
|
-
* Optimized for performance with adaptive algorithms and memory management.
|
|
267
|
-
*/
|
|
268
|
-
declare class OIMUpdateEventEmitter<TKey extends TOIMPk> {
|
|
269
|
-
protected keyHandlers: Map<TKey, Set<TOIMEventHandler<void>>>;
|
|
270
|
-
protected queue: OIMEventQueue;
|
|
271
|
-
private readonly deliveryMode;
|
|
272
|
-
private isFlushEnqueued;
|
|
273
|
-
private dequeueFlush?;
|
|
274
|
-
private updatedKeys;
|
|
275
|
-
private isAfterFlushDeliveryScheduled;
|
|
276
|
-
private unsubscribeAfterFlushDelivery?;
|
|
277
|
-
constructor(queue: OIMEventQueue, deliveryMode?: TOIMUpdateEventEmitterDeliveryMode);
|
|
278
|
-
/**
|
|
279
|
-
* Mark keys as updated and schedule delivery.
|
|
280
|
-
*
|
|
281
|
-
* If there are no subscriptions, this is a no-op and does not allocate or retain keys.
|
|
282
|
-
*/
|
|
283
|
-
markUpdatedKeys(keys: readonly TKey[]): void;
|
|
284
|
-
markUpdatedKey(key: TKey): void;
|
|
285
|
-
markAllUpdated(): void;
|
|
286
|
-
protected readonly onFlush: () => void;
|
|
287
|
-
private deliverImmediate;
|
|
288
|
-
/**
|
|
289
|
-
* Notifies all handlers for a key. The overwhelmingly common case is a
|
|
290
|
-
* single subscriber per key (one component per pk), handled without any
|
|
291
|
-
* allocation. For multiple subscribers a snapshot is taken so a handler may
|
|
292
|
-
* (un)subscribe during iteration without corrupting the walk.
|
|
293
|
-
*/
|
|
294
|
-
private notifyHandlers;
|
|
295
|
-
private readonly onAfterFlush;
|
|
296
|
-
/**
|
|
297
|
-
* Deliver updated keys and notify handlers once.
|
|
298
|
-
* Re-entrant updates during delivery are forbidden and will throw in markUpdatedKeys().
|
|
299
|
-
*/
|
|
300
|
-
protected runSinglePass(): void;
|
|
301
|
-
destroy(): void;
|
|
302
|
-
/**
|
|
303
|
-
* Get performance metrics for monitoring and debugging
|
|
304
|
-
*/
|
|
305
|
-
getMetrics(): {
|
|
306
|
-
totalKeys: number;
|
|
307
|
-
totalHandlers: number;
|
|
308
|
-
averageHandlersPerKey: number;
|
|
309
|
-
queueLength: number;
|
|
310
|
-
};
|
|
311
|
-
/**
|
|
312
|
-
* Check if there are any active subscriptions
|
|
313
|
-
*/
|
|
314
|
-
hasSubscriptions(): boolean;
|
|
315
|
-
/**
|
|
316
|
-
* Get the number of handlers for a specific key
|
|
317
|
-
*/
|
|
318
|
-
getHandlerCount(key: TKey): number;
|
|
319
|
-
subscribeOnKey(key: TKey, handler: TOIMEventHandler<void>): () => void;
|
|
320
|
-
unsubscribeFromKey(key: TKey, handler: TOIMEventHandler<void>): void;
|
|
321
|
-
subscribeOnKeys(keys: readonly TKey[], handler: TOIMEventHandler<void>): () => void;
|
|
322
|
-
unsubscribeFromKeys(keys: readonly TKey[], handler: TOIMEventHandler<void>): void;
|
|
323
|
-
}
|
|
324
|
-
|
|
325
302
|
interface IOIMKeyedSubscription<TKey extends TOIMPk> {
|
|
326
303
|
subscribeOnKey(key: TKey, handler: TOIMEventHandler<void>): () => void;
|
|
327
304
|
subscribeOnKeys(keys: readonly TKey[], handler: TOIMEventHandler<void>): () => void;
|
|
@@ -329,8 +306,8 @@ interface IOIMKeyedSubscription<TKey extends TOIMPk> {
|
|
|
329
306
|
|
|
330
307
|
declare abstract class OIMReactiveIndex<TKey extends TOIMPk, TPk extends TOIMPk, TIndex extends OIMIndex<TKey, TPk, Iterable<TOIMAnyEntitySlot<TPk>>>> implements IOIMKeyedSubscription<TKey> {
|
|
331
308
|
readonly index: TIndex;
|
|
332
|
-
protected readonly updateEmitter:
|
|
333
|
-
constructor(queue: OIMEventQueue, createIndex: (updateEmitter:
|
|
309
|
+
protected readonly updateEmitter: IOIMKeyedUpdateEmitter<TKey>;
|
|
310
|
+
constructor(queue: OIMEventQueue, createIndex: (updateEmitter: IOIMKeyedUpdateEmitter<TKey>) => TIndex);
|
|
334
311
|
getEntitiesByKey<TEntity extends object = object>(key: TKey): (TEntity | undefined)[];
|
|
335
312
|
getEntitiesByKeys<TEntity extends object = object>(keys: readonly TKey[]): Map<TKey, (TEntity | undefined)[]>;
|
|
336
313
|
hasKey(key: TKey): boolean;
|
|
@@ -361,7 +338,7 @@ declare abstract class OIMReactiveIndex<TKey extends TOIMPk, TPk extends TOIMPk,
|
|
|
361
338
|
}
|
|
362
339
|
|
|
363
340
|
declare abstract class OIMReactiveIndexSetBased<TKey extends TOIMPk, TPk extends TOIMPk, TIndex extends OIMIndexSetBased<TKey, TPk>> extends OIMReactiveIndex<TKey, TPk, TIndex> {
|
|
364
|
-
constructor(queue: OIMEventQueue, createIndex: (updateEmitter:
|
|
341
|
+
constructor(queue: OIMEventQueue, createIndex: (updateEmitter: IOIMKeyedUpdateEmitter<TKey>) => TIndex);
|
|
365
342
|
getPksByKey(key: TKey): Set<TPk>;
|
|
366
343
|
getPksByKeys(keys: readonly TKey[]): Map<TKey, Set<TPk>>;
|
|
367
344
|
getSlotsByKey(key: TKey): ReadonlySet<TOIMAnyEntitySlot<TPk>>;
|
|
@@ -369,7 +346,7 @@ declare abstract class OIMReactiveIndexSetBased<TKey extends TOIMPk, TPk extends
|
|
|
369
346
|
}
|
|
370
347
|
|
|
371
348
|
declare abstract class OIMReactiveIndexArrayBased<TKey extends TOIMPk, TPk extends TOIMPk, TIndex extends OIMIndexArrayBased<TKey, TPk>> extends OIMReactiveIndex<TKey, TPk, TIndex> {
|
|
372
|
-
constructor(queue: OIMEventQueue, createIndex: (updateEmitter:
|
|
349
|
+
constructor(queue: OIMEventQueue, createIndex: (updateEmitter: IOIMKeyedUpdateEmitter<TKey>) => TIndex);
|
|
373
350
|
getPksByKey(key: TKey): TPk[];
|
|
374
351
|
getPksByKeys(keys: readonly TKey[]): Map<TKey, TPk[]>;
|
|
375
352
|
getSlotsByKey(key: TKey): readonly TOIMAnyEntitySlot<TPk>[];
|
|
@@ -442,6 +419,14 @@ declare class OIMCollection<TEntity extends object, TPk extends TOIMPk> {
|
|
|
442
419
|
*/
|
|
443
420
|
interface IOIMSubscribable {
|
|
444
421
|
subscribers?: Set<() => void>;
|
|
422
|
+
/**
|
|
423
|
+
* Dirty-batch membership flag, owned by the keyed emitter. `true` while the
|
|
424
|
+
* carrier sits in the pending flush batch — lets the emitter dedup marks with
|
|
425
|
+
* an O(1) boolean check instead of a `Set` identity-hash lookup. Reset to
|
|
426
|
+
* `false` as the carrier is delivered (or on flush teardown). Do not read or
|
|
427
|
+
* write outside the emitter.
|
|
428
|
+
*/
|
|
429
|
+
dirty?: boolean;
|
|
445
430
|
}
|
|
446
431
|
|
|
447
432
|
/**
|
|
@@ -456,6 +441,13 @@ interface IOIMSubscribable {
|
|
|
456
441
|
interface IOIMCarrierResolver<TKey extends TOIMPk, TCarrier> {
|
|
457
442
|
getOrReserveCarrier(key: TKey): TCarrier;
|
|
458
443
|
findCarrier(key: TKey): TCarrier | undefined;
|
|
444
|
+
/**
|
|
445
|
+
* Optional: called when a carrier loses its last subscriber, so a resolver
|
|
446
|
+
* that owns standalone carriers (e.g. the index's key→carrier map) can prune
|
|
447
|
+
* it and not leak the key space. Resolvers whose carriers are owned
|
|
448
|
+
* elsewhere (e.g. the collection's slots) leave this unset.
|
|
449
|
+
*/
|
|
450
|
+
onCarrierEmptied?(carrier: TCarrier): void;
|
|
459
451
|
}
|
|
460
452
|
/**
|
|
461
453
|
* Keyed (per-key) pub/sub that stores handlers ON the carrier object
|
|
@@ -468,13 +460,12 @@ interface IOIMCarrierResolver<TKey extends TOIMPk, TCarrier> {
|
|
|
468
460
|
* index's keyed emitter. Reused with carrier = slot (collection) or carrier =
|
|
469
461
|
* bucket (index).
|
|
470
462
|
*/
|
|
471
|
-
declare class OIMCarrierKeyedEmitter<TKey extends TOIMPk, TCarrier extends IOIMSubscribable> {
|
|
463
|
+
declare class OIMCarrierKeyedEmitter<TKey extends TOIMPk, TCarrier extends IOIMSubscribable> implements IOIMKeyedUpdateEmitter<TKey> {
|
|
472
464
|
private readonly queue;
|
|
473
465
|
private readonly resolver;
|
|
474
466
|
private readonly subscribedCarriers;
|
|
475
467
|
private dirtyCarriers;
|
|
476
468
|
private isFlushEnqueued;
|
|
477
|
-
private dequeueFlush?;
|
|
478
469
|
constructor(queue: OIMEventQueue, resolver: IOIMCarrierResolver<TKey, TCarrier>);
|
|
479
470
|
subscribeOnKey(key: TKey, handler: TOIMEventHandler<void>): () => void;
|
|
480
471
|
subscribeOnKeys(keys: readonly TKey[], handler: TOIMEventHandler<void>): () => void;
|
|
@@ -509,7 +500,6 @@ declare class OIMReactiveCollection<TEntity extends object, TPk extends TOIMPk>
|
|
|
509
500
|
private pendingAnyUpdatePks;
|
|
510
501
|
private isAnyUpdateClearPending;
|
|
511
502
|
private isAnyUpdateScheduled;
|
|
512
|
-
private dequeueAnyUpdate?;
|
|
513
503
|
constructor(queue: OIMEventQueue, opts?: TOIMCollectionOptions<TEntity, TPk>);
|
|
514
504
|
subscribeOnKey(pk: TPk, handler: TOIMEventHandler<void>): () => void;
|
|
515
505
|
subscribeOnKeys(pks: readonly TPk[], handler: TOIMEventHandler<void>): () => void;
|
|
@@ -671,6 +661,67 @@ declare class OIMCollectionIndexManualOrderedArrayBased<TKey extends TOIMPk, TPk
|
|
|
671
661
|
private resolveRequiredSlot;
|
|
672
662
|
}
|
|
673
663
|
|
|
664
|
+
type TOIMUpdateEventEmitterDeliveryMode = 'queue' | 'after_flush' | 'immediate';
|
|
665
|
+
/**
|
|
666
|
+
* Universal event emitter that handles subscriptions and notifications for any key type.
|
|
667
|
+
* Optimized for performance with adaptive algorithms and memory management.
|
|
668
|
+
*/
|
|
669
|
+
declare class OIMUpdateEventEmitter<TKey extends TOIMPk> {
|
|
670
|
+
protected keyHandlers: Map<TKey, Set<TOIMEventHandler<void>>>;
|
|
671
|
+
protected queue: OIMEventQueue;
|
|
672
|
+
private readonly deliveryMode;
|
|
673
|
+
private isFlushEnqueued;
|
|
674
|
+
private updatedKeys;
|
|
675
|
+
private isAfterFlushDeliveryScheduled;
|
|
676
|
+
private unsubscribeAfterFlushDelivery?;
|
|
677
|
+
constructor(queue: OIMEventQueue, deliveryMode?: TOIMUpdateEventEmitterDeliveryMode);
|
|
678
|
+
/**
|
|
679
|
+
* Mark keys as updated and schedule delivery.
|
|
680
|
+
*
|
|
681
|
+
* If there are no subscriptions, this is a no-op and does not allocate or retain keys.
|
|
682
|
+
*/
|
|
683
|
+
markUpdatedKeys(keys: readonly TKey[]): void;
|
|
684
|
+
markUpdatedKey(key: TKey): void;
|
|
685
|
+
markAllUpdated(): void;
|
|
686
|
+
protected readonly onFlush: () => void;
|
|
687
|
+
private deliverImmediate;
|
|
688
|
+
/**
|
|
689
|
+
* Notifies all handlers for a key. The overwhelmingly common case is a
|
|
690
|
+
* single subscriber per key (one component per pk), handled without any
|
|
691
|
+
* allocation. For multiple subscribers a snapshot is taken so a handler may
|
|
692
|
+
* (un)subscribe during iteration without corrupting the walk.
|
|
693
|
+
*/
|
|
694
|
+
private notifyHandlers;
|
|
695
|
+
private readonly onAfterFlush;
|
|
696
|
+
/**
|
|
697
|
+
* Deliver updated keys and notify handlers once.
|
|
698
|
+
* Re-entrant updates during delivery are forbidden and will throw in markUpdatedKeys().
|
|
699
|
+
*/
|
|
700
|
+
protected runSinglePass(): void;
|
|
701
|
+
destroy(): void;
|
|
702
|
+
/**
|
|
703
|
+
* Get performance metrics for monitoring and debugging
|
|
704
|
+
*/
|
|
705
|
+
getMetrics(): {
|
|
706
|
+
totalKeys: number;
|
|
707
|
+
totalHandlers: number;
|
|
708
|
+
averageHandlersPerKey: number;
|
|
709
|
+
queueLength: number;
|
|
710
|
+
};
|
|
711
|
+
/**
|
|
712
|
+
* Check if there are any active subscriptions
|
|
713
|
+
*/
|
|
714
|
+
hasSubscriptions(): boolean;
|
|
715
|
+
/**
|
|
716
|
+
* Get the number of handlers for a specific key
|
|
717
|
+
*/
|
|
718
|
+
getHandlerCount(key: TKey): number;
|
|
719
|
+
subscribeOnKey(key: TKey, handler: TOIMEventHandler<void>): () => void;
|
|
720
|
+
unsubscribeFromKey(key: TKey, handler: TOIMEventHandler<void>): void;
|
|
721
|
+
subscribeOnKeys(keys: readonly TKey[], handler: TOIMEventHandler<void>): () => void;
|
|
722
|
+
unsubscribeFromKeys(keys: readonly TKey[], handler: TOIMEventHandler<void>): void;
|
|
723
|
+
}
|
|
724
|
+
|
|
674
725
|
type TOIMOrderedListCommand<TPk extends TOIMPk, TEntity extends object = object> = {
|
|
675
726
|
type: 'insert';
|
|
676
727
|
pk: TPk;
|
|
@@ -957,6 +1008,15 @@ declare class OIMObject<TKey extends string, TValue> {
|
|
|
957
1008
|
get(key: TKey): TValue | undefined;
|
|
958
1009
|
getAll(): Record<TKey, TValue>;
|
|
959
1010
|
clear(): void;
|
|
1011
|
+
/**
|
|
1012
|
+
* Write fan-out hooks. Split single-key vs multi-key so a reactive subclass
|
|
1013
|
+
* can mark its keyed emitter on the hot single-property path without
|
|
1014
|
+
* allocating a `{ keys: [key] }` payload. The base only fires the general
|
|
1015
|
+
* UPDATE event, and only when something is actually subscribed to it — so an
|
|
1016
|
+
* unobserved write skips the payload allocation entirely.
|
|
1017
|
+
*/
|
|
1018
|
+
protected onUpdatedKey(key: TKey): void;
|
|
1019
|
+
protected onUpdatedKeys(keys: TKey[]): void;
|
|
960
1020
|
count(): number;
|
|
961
1021
|
keys(): TKey[];
|
|
962
1022
|
values(): TValue[];
|
|
@@ -965,8 +1025,15 @@ declare class OIMObject<TKey extends string, TValue> {
|
|
|
965
1025
|
}
|
|
966
1026
|
|
|
967
1027
|
declare class OIMReactiveObject<TKey extends string, TValue> extends OIMObject<TKey, TValue> implements IOIMKeyedSubscription<TKey> {
|
|
968
|
-
protected readonly updateEmitter:
|
|
1028
|
+
protected readonly updateEmitter: IOIMKeyedUpdateEmitter<TKey>;
|
|
969
1029
|
constructor(queue: OIMEventQueue, opts?: TOIMObjectOptions<TKey, TValue>);
|
|
1030
|
+
/**
|
|
1031
|
+
* Mark the written key(s) on the keyed emitter directly — no general-event
|
|
1032
|
+
* bridge, no `{ keys }` payload on the single-key path. `super` still fires
|
|
1033
|
+
* the general UPDATE event for any low-level `emitter` subscribers.
|
|
1034
|
+
*/
|
|
1035
|
+
protected onUpdatedKey(key: TKey): void;
|
|
1036
|
+
protected onUpdatedKeys(keys: TKey[]): void;
|
|
970
1037
|
subscribeOnKey(key: TKey, handler: TOIMEventHandler<void>): () => void;
|
|
971
1038
|
subscribeOnKeys(keys: readonly TKey[], handler: TOIMEventHandler<void>): () => void;
|
|
972
1039
|
unsubscribeFromKey(key: TKey, handler: TOIMEventHandler<void>): void;
|
|
@@ -1633,4 +1700,4 @@ declare class OIMEntitiesByIndexKeyArrayBasedSelector<TEntity extends object, TP
|
|
|
1633
1700
|
protected areEqual(prev: readonly (TEntity | undefined)[], next: readonly (TEntity | undefined)[]): boolean;
|
|
1634
1701
|
}
|
|
1635
1702
|
|
|
1636
|
-
export { EOIMCollectionEventType, EOIMComputedEventType, EOIMEventQueueEventType, EOIMEventQueueSchedulerEventType, EOIMIndexEventType, EOIMObjectEventType, type IOIMCarrierResolver, type IOIMComputedEventSource, type IOIMEffectDependency, type IOIMEventQueueSchedulerEvents, type IOIMIndexStore, type IOIMSubscribable, OIMCarrierKeyedEmitter, OIMCollection, OIMCollectionByPkSelector, OIMCollectionByPksSelector, OIMCollectionChangedFields, OIMCollectionIndexFactory, OIMCollectionIndexManualOrderedArrayBased, OIMCollectionOrderedListCommandStream, OIMCollectionSelectors, OIMCollectionStore, OIMCollectionStoreMapDriven, OIMComparatorFactory, OIMComputeRuntime, OIMComputed, OIMDBSettings, OIMDerivedCollectionIndexArrayBased, OIMDerivedCollectionIndexSetBased, OIMEffect, OIMEffectDependencyComputed, OIMEffectDependencyKeyed, OIMEffectDependencyKeyedCollection, OIMEffectDependencyKeyedIndex, OIMEffectDependencyKeyedObject, OIMEntitiesByIndexKeyArrayBasedSelector, OIMEntitiesByIndexKeySetBasedSelector, OIMEntityUpdaterFactory, OIMEventEmitter, OIMEventQueue, OIMEventQueueScheduler, OIMEventQueueSchedulerAnimationFrame, OIMEventQueueSchedulerFactory, OIMEventQueueSchedulerImmediate, OIMEventQueueSchedulerMicrotask, OIMEventQueueSchedulerTimeout, OIMIndex, OIMIndexArrayBased, OIMIndexComparatorFactory, OIMIndexManualArrayBased, OIMIndexManualOrderedArrayBased, OIMIndexManualSetBased, OIMIndexPksByKeyArrayBasedSelector, OIMIndexPksByKeySetBasedSelector, OIMIndexPksByKeysArrayBasedSelector, OIMIndexPksByKeysSetBasedSelector, OIMIndexSetBased, OIMIndexStoreArrayBased, OIMIndexStoreMapDrivenArrayBased, OIMIndexStoreMapDrivenSetBased, OIMIndexStoreSetBased, OIMMap2Keys, OIMObject, OIMObjectStore, OIMObjectStoreMapDriven, OIMObjectStoreRecordDriven, OIMObjectValueByKeySelector, OIMObjectValuesByKeysSelector, OIMOrderedListCommandStream, OIMPkSelectorFactory, OIMReactiveCollection, OIMReactiveCollectionIndexManualArrayBased, OIMReactiveCollectionIndexManualSetBased, OIMReactiveIndex, OIMReactiveIndexArrayBased, OIMReactiveIndexManualArrayBased, OIMReactiveIndexManualSetBased, OIMReactiveIndexSetBased, OIMReactiveObject, OIMSelector, type TOIMAnyEntitySlot, type TOIMCollectionEntitiesSelector, type TOIMCollectionEntitySelector, type TOIMCollectionIndexArrayBasedOptions, type TOIMCollectionIndexSetBasedOptions, type TOIMCollectionKit, type TOIMCollectionOptions, type TOIMCollectionOrderedIndexOptions, type TOIMCollectionOrderedListCommandStreamOptions, type TOIMCollectionUpdatePayload, type TOIMComparator, type TOIMComputedOptions, type TOIMComputedUpdatePayload, type TOIMDerivedCollectionIndexArrayBasedOptions, type TOIMDerivedCollectionIndexSetBasedOptions, type TOIMDerivedEntityComparator, type TOIMDerivedEntityOrderSelector, type TOIMDerivedEntityOrderValue, type TOIMDerivedIndexKeySelector, type TOIMEffectOptions, type TOIMEntitySlot, type TOIMEntitySlotResolver, type TOIMEntityUpdater, type TOIMEventHandler, type TOIMEventQueueOptions, type TOIMIndexComparator, type TOIMIndexKey, type TOIMIndexOptionsArrayBased, type TOIMIndexOptionsSetBased, type TOIMIndexPksUpdatePayload, type TOIMIndexUpdatePayload, type TOIMObjectOptions, type TOIMOrderedListCommand, type TOIMPk, type TOIMPkSelector, type TOIMReactiveCollectionFactoryOptions, type TOIMRelationsArrayIndexOptions, type TOIMRelationsDerivedArrayIndexOptions, type TOIMRelationsDerivedSetIndexOptions, type TOIMRelationsOrderedListOptions, type TOIMRelationsSetIndexOptions, type TOIMSchedulerOptions, type TOIMSchedulerType, type TOIMUpdatePayload, createInPlaceEntityUpdater, createOIMCollectionIndexFactory, createOIMCollectionKit };
|
|
1703
|
+
export { EOIMCollectionEventType, EOIMComputedEventType, EOIMEventQueueEventType, EOIMEventQueueSchedulerEventType, EOIMIndexEventType, EOIMObjectEventType, type IOIMCarrierResolver, type IOIMComputedEventSource, type IOIMEffectDependency, type IOIMEventQueueSchedulerEvents, type IOIMIndexStore, type IOIMKeyedUpdateEmitter, type IOIMSubscribable, OIMCarrierKeyedEmitter, OIMCollection, OIMCollectionByPkSelector, OIMCollectionByPksSelector, OIMCollectionChangedFields, OIMCollectionIndexFactory, OIMCollectionIndexManualOrderedArrayBased, OIMCollectionOrderedListCommandStream, OIMCollectionSelectors, OIMCollectionStore, OIMCollectionStoreMapDriven, OIMComparatorFactory, OIMComputeRuntime, OIMComputed, OIMDBSettings, OIMDerivedCollectionIndexArrayBased, OIMDerivedCollectionIndexSetBased, OIMEffect, OIMEffectDependencyComputed, OIMEffectDependencyKeyed, OIMEffectDependencyKeyedCollection, OIMEffectDependencyKeyedIndex, OIMEffectDependencyKeyedObject, OIMEntitiesByIndexKeyArrayBasedSelector, OIMEntitiesByIndexKeySetBasedSelector, OIMEntityUpdaterFactory, OIMEventEmitter, OIMEventQueue, OIMEventQueueScheduler, OIMEventQueueSchedulerAnimationFrame, OIMEventQueueSchedulerFactory, OIMEventQueueSchedulerImmediate, OIMEventQueueSchedulerMicrotask, OIMEventQueueSchedulerTimeout, OIMIndex, OIMIndexArrayBased, OIMIndexComparatorFactory, OIMIndexManualArrayBased, OIMIndexManualOrderedArrayBased, OIMIndexManualSetBased, OIMIndexPksByKeyArrayBasedSelector, OIMIndexPksByKeySetBasedSelector, OIMIndexPksByKeysArrayBasedSelector, OIMIndexPksByKeysSetBasedSelector, OIMIndexSetBased, OIMIndexStoreArrayBased, OIMIndexStoreMapDrivenArrayBased, OIMIndexStoreMapDrivenSetBased, OIMIndexStoreSetBased, OIMMap2Keys, OIMObject, OIMObjectStore, OIMObjectStoreMapDriven, OIMObjectStoreRecordDriven, OIMObjectValueByKeySelector, OIMObjectValuesByKeysSelector, OIMOrderedListCommandStream, OIMPkSelectorFactory, OIMReactiveCollection, OIMReactiveCollectionIndexManualArrayBased, OIMReactiveCollectionIndexManualSetBased, OIMReactiveIndex, OIMReactiveIndexArrayBased, OIMReactiveIndexManualArrayBased, OIMReactiveIndexManualSetBased, OIMReactiveIndexSetBased, OIMReactiveObject, OIMSelector, type TOIMAnyEntitySlot, type TOIMCollectionEntitiesSelector, type TOIMCollectionEntitySelector, type TOIMCollectionIndexArrayBasedOptions, type TOIMCollectionIndexSetBasedOptions, type TOIMCollectionKit, type TOIMCollectionOptions, type TOIMCollectionOrderedIndexOptions, type TOIMCollectionOrderedListCommandStreamOptions, type TOIMCollectionUpdatePayload, type TOIMComparator, type TOIMComputedOptions, type TOIMComputedUpdatePayload, type TOIMDerivedCollectionIndexArrayBasedOptions, type TOIMDerivedCollectionIndexSetBasedOptions, type TOIMDerivedEntityComparator, type TOIMDerivedEntityOrderSelector, type TOIMDerivedEntityOrderValue, type TOIMDerivedIndexKeySelector, type TOIMEffectOptions, type TOIMEntitySlot, type TOIMEntitySlotResolver, type TOIMEntityUpdater, type TOIMEventHandler, type TOIMEventQueueOptions, type TOIMIndexComparator, type TOIMIndexKey, type TOIMIndexOptionsArrayBased, type TOIMIndexOptionsSetBased, type TOIMIndexPksUpdatePayload, type TOIMIndexUpdatePayload, type TOIMObjectOptions, type TOIMOrderedListCommand, type TOIMPk, type TOIMPkSelector, type TOIMReactiveCollectionFactoryOptions, type TOIMRelationsArrayIndexOptions, type TOIMRelationsDerivedArrayIndexOptions, type TOIMRelationsDerivedSetIndexOptions, type TOIMRelationsOrderedListOptions, type TOIMRelationsSetIndexOptions, type TOIMSchedulerOptions, type TOIMSchedulerType, type TOIMUpdatePayload, createInPlaceEntityUpdater, createOIMCollectionIndexFactory, createOIMCollectionKit };
|