@oimdb/core 4.0.1 → 4.1.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.js CHANGED
@@ -1,12 +1,9 @@
1
1
  // src/engine/schedule/OIMFlushSchedulerService.ts
2
- var OIMFlushSchedulerService = class {
3
- onSchedulerTimerFired(flushSchedulerSlot) {
4
- this.flush(flushSchedulerSlot);
5
- }
2
+ var _OIMFlushSchedulerService = class _OIMFlushSchedulerService {
6
3
  isScheduled(flushSchedulerSlot) {
7
4
  return flushSchedulerSlot.scheduledCallback !== void 0;
8
5
  }
9
- schedule(flushSchedulerSlot, delayMs) {
6
+ schedule(flushSchedulerSlot, delayMs, flushSchedulerListener) {
10
7
  if (flushSchedulerSlot.scheduledCallback !== void 0) return;
11
8
  const timer = flushSchedulerSlot.timer;
12
9
  if (timer === void 0) return;
@@ -14,7 +11,7 @@ var OIMFlushSchedulerService = class {
14
11
  if (flushSchedulerSlot.scheduledCallback !== scheduledCallback) return;
15
12
  flushSchedulerSlot.scheduledCallback = void 0;
16
13
  flushSchedulerSlot.timerDisposer = void 0;
17
- this.onSchedulerTimerFired(flushSchedulerSlot);
14
+ flushSchedulerListener.onSchedulerTimerFired(flushSchedulerSlot);
18
15
  };
19
16
  flushSchedulerSlot.scheduledCallback = scheduledCallback;
20
17
  let timerDisposer;
@@ -33,6 +30,8 @@ var OIMFlushSchedulerService = class {
33
30
  timerDisposer?.();
34
31
  }
35
32
  };
33
+ _OIMFlushSchedulerService.INSTANCE = new _OIMFlushSchedulerService();
34
+ var OIMFlushSchedulerService = _OIMFlushSchedulerService;
36
35
 
37
36
  // src/engine/slot/constants/OIM_SLOT_FLAG_RELEASED.ts
38
37
  var OIM_SLOT_FLAG_RELEASED = 2;
@@ -98,7 +97,7 @@ function oimIsRevisionAfter(revision, epoch, sinceRevision, sinceEpoch) {
98
97
  }
99
98
 
100
99
  // src/engine/channel/OIMChannelService.ts
101
- var _OIMChannelService = class _OIMChannelService extends OIMFlushSchedulerService {
100
+ var _OIMChannelService = class _OIMChannelService {
102
101
  scheduleEffectRun(channelSlot, effect) {
103
102
  channelSlot.effectChannelQueue.enqueueEntry(effect);
104
103
  this.requestFlush(channelSlot);
@@ -113,45 +112,6 @@ var _OIMChannelService = class _OIMChannelService extends OIMFlushSchedulerServi
113
112
  );
114
113
  }
115
114
  }
116
- isSubframeOpen(channelSlot) {
117
- return channelSlot.subframesOpen > 0;
118
- }
119
- listChangedStoreSlot(channelSlot, storeSlot, subframeCloseListener) {
120
- channelSlot.changedStoreSlotChannelQueue.enqueueEntry(storeSlot);
121
- channelSlot.changedStoreSlotOwnerChannelQueue.enqueueEntry(subframeCloseListener);
122
- }
123
- openSubframe(channelSlot) {
124
- channelSlot.subframesOpen++;
125
- }
126
- closeSubframe(channelSlot) {
127
- if (channelSlot.subframesOpen > 1) {
128
- channelSlot.subframesOpen--;
129
- return;
130
- }
131
- let hasFailed = false;
132
- let firstFailure;
133
- const changedStoreSlotChannelQueue = channelSlot.changedStoreSlotChannelQueue;
134
- const changedStoreSlotOwnerChannelQueue = channelSlot.changedStoreSlotOwnerChannelQueue;
135
- try {
136
- for (let i = 0; i < changedStoreSlotChannelQueue.getEntryCount(); i++) {
137
- try {
138
- changedStoreSlotOwnerChannelQueue.getEntryAt(i).onStoreSlotSubframeClosed(changedStoreSlotChannelQueue.getEntryAt(i));
139
- } catch (failure) {
140
- if (!hasFailed) firstFailure = failure;
141
- hasFailed = true;
142
- }
143
- }
144
- } finally {
145
- changedStoreSlotChannelQueue.keepFirstEntries(0);
146
- changedStoreSlotOwnerChannelQueue.keepFirstEntries(0);
147
- channelSlot.subframesOpen--;
148
- }
149
- if (channelSlot.flushRequestedInSubframe) {
150
- channelSlot.flushRequestedInSubframe = false;
151
- this.requestFlush(channelSlot);
152
- }
153
- if (hasFailed) throw firstFailure;
154
- }
155
115
  subscribeAfterEachFrame(channelSlot, handler) {
156
116
  const afterEachFrame = channelSlot.frame.afterEachFrame;
157
117
  const subscription = () => {
@@ -220,14 +180,10 @@ var _OIMChannelService = class _OIMChannelService extends OIMFlushSchedulerServi
220
180
  }
221
181
  requestFlush(channelSlot) {
222
182
  if (channelSlot.dropped) return;
223
- if (channelSlot.subframesOpen !== 0) {
224
- channelSlot.flushRequestedInSubframe = true;
225
- return;
226
- }
227
183
  if (channelSlot.flushRequested || channelSlot.timer === void 0 || channelSlot.frame.isRunning) return;
228
184
  channelSlot.flushRequested = true;
229
185
  try {
230
- this.schedule(channelSlot, 0);
186
+ OIMFlushSchedulerService.INSTANCE.schedule(channelSlot, 0, this);
231
187
  } catch (failure) {
232
188
  channelSlot.flushRequested = false;
233
189
  throw failure;
@@ -235,12 +191,15 @@ var _OIMChannelService = class _OIMChannelService extends OIMFlushSchedulerServi
235
191
  }
236
192
  dropChannelSlot(channelSlot) {
237
193
  channelSlot.dropped = true;
238
- this.cancelSchedule(channelSlot);
194
+ OIMFlushSchedulerService.INSTANCE.cancelSchedule(channelSlot);
239
195
  if (!channelSlot.isFlushing) OIMUnusedSlotCollectorService.INSTANCE.flush(channelSlot.collectorSlot.unusedSlotCollectorSlot);
240
196
  channelSlot.effectChannelQueue.keepFirstEntries(0);
241
197
  channelSlot.frame.afterEachFrame.clear();
242
198
  channelSlot.afterEachFlush.clear();
243
199
  }
200
+ onSchedulerTimerFired(channelSlot) {
201
+ this.flush(channelSlot);
202
+ }
244
203
  flush(channelSlot) {
245
204
  if (channelSlot.dropped) return;
246
205
  if (channelSlot.frame.isRunning) {
@@ -248,11 +207,6 @@ var _OIMChannelService = class _OIMChannelService extends OIMFlushSchedulerServi
248
207
  "OIMChannelService.flush: a frame is already running, and a second one inside it would end the first. A subscriber is told during the frame; to do work after it, subscribe with subscribeAfterEachFrame."
249
208
  );
250
209
  }
251
- if (channelSlot.subframesOpen > 0) {
252
- throw new Error(
253
- "OIMChannelService.flush: a subframe is open \u2014 a write is still landing (or openSubframe() was called and closeSubframe() was not yet), and the frame cannot close while a subframe is open. Flush after the write returns; the outermost closeSubframe asks for the frame it owes by itself."
254
- );
255
- }
256
210
  if (channelSlot.isFlushing) return;
257
211
  channelSlot.isFlushing = true;
258
212
  try {
@@ -262,7 +216,7 @@ var _OIMChannelService = class _OIMChannelService extends OIMFlushSchedulerServi
262
216
  this.runFrame(channelSlot);
263
217
  } else {
264
218
  channelSlot.flushRequested = false;
265
- this.cancelSchedule(channelSlot);
219
+ OIMFlushSchedulerService.INSTANCE.cancelSchedule(channelSlot);
266
220
  frame.openedAtRevision = clock.revision;
267
221
  frame.openedAtEpoch = clock.epoch;
268
222
  }
@@ -279,7 +233,7 @@ var _OIMChannelService = class _OIMChannelService extends OIMFlushSchedulerServi
279
233
  }
280
234
  runFrame(channelSlot) {
281
235
  channelSlot.flushRequested = false;
282
- this.cancelSchedule(channelSlot);
236
+ OIMFlushSchedulerService.INSTANCE.cancelSchedule(channelSlot);
283
237
  const onBeforeFlush = channelSlot.onBeforeFlush;
284
238
  if (onBeforeFlush !== void 0) {
285
239
  try {
@@ -392,15 +346,8 @@ function createOIMChannelSlot(options) {
392
346
  effectChannelQueue: new OIMChannelQueue(),
393
347
  afterEachFlush: /* @__PURE__ */ new Set(),
394
348
  afterEachFrameHandlerChannelQueue: new OIMChannelQueue(),
395
- subframeStoreSlotChannelQueues: [],
396
- changedStoreSlotChannelQueue: new OIMChannelQueue(),
397
- changedStoreSlotOwnerChannelQueue: new OIMChannelQueue(),
398
349
  commandsStoreSlotChannelQueue: void 0,
399
350
  changedColumnNames: void 0,
400
- subframesOpen: 0,
401
- contentSubframeDepth: 0,
402
- subframeDeliveryDepth: 0,
403
- flushRequestedInSubframe: false,
404
351
  flushRequested: false,
405
352
  isFlushing: false,
406
353
  dropped: false
@@ -412,30 +359,14 @@ function createOIMUnusedSlotCollectorSlot() {
412
359
  return { unusedSlotChannelQueue: new OIMChannelQueue(), openDepth: 0, isFlushing: false };
413
360
  }
414
361
 
415
- // src/engine/collector/utils/createOIMReleaseSlotCollectorSlot.ts
416
- function createOIMReleaseSlotCollectorSlot(options) {
417
- return {
418
- timer: options.releaseTimer,
419
- scheduledCallback: void 0,
420
- timerDisposer: void 0,
421
- getNowMs: options.getNowMs,
422
- errorPolicy: options.errorPolicy,
423
- scheduledUntilMs: Number.POSITIVE_INFINITY,
424
- slotsBySliceNumber: /* @__PURE__ */ new Map(),
425
- sliceNumberBySlot: /* @__PURE__ */ new Map(),
426
- floorSliceNumber: Number.NEGATIVE_INFINITY,
427
- nextSliceNumber: void 0,
428
- nextSliceNumberNeedsRescan: false
429
- };
430
- }
431
-
432
362
  // src/engine/collector/utils/createOIMCollectorSlot.ts
433
363
  function createOIMCollectorSlot(options) {
434
364
  return {
435
365
  unusedSlotCollectorSlot: createOIMUnusedSlotCollectorSlot(),
436
- afterIdleReleaseSlotCollectorSlot: createOIMReleaseSlotCollectorSlot(options),
437
- afterWriteReleaseSlotCollectorSlot: createOIMReleaseSlotCollectorSlot(options),
438
- afterUnholdReleaseSlotCollectorSlot: createOIMReleaseSlotCollectorSlot(options)
366
+ slotWheelOptions: { getNowMs: options.getNowMs, timer: options.releaseTimer, errorPolicy: options.errorPolicy },
367
+ afterIdleSlotReleaseWheel: void 0,
368
+ afterWriteSlotReleaseWheel: void 0,
369
+ afterUnholdSlotReleaseWheel: void 0
439
370
  };
440
371
  }
441
372
 
@@ -459,8 +390,8 @@ var OIM_TIMER_ON_TIMEOUT = (run, inMs) => {
459
390
  };
460
391
  };
461
392
 
462
- // src/engine/error/OIMErrorPolicyLogAndContinue.ts
463
- var _OIMErrorPolicyLogAndContinue = class _OIMErrorPolicyLogAndContinue {
393
+ // src/engine/error/OIMLogAndContinueErrorPolicy.ts
394
+ var _OIMLogAndContinueErrorPolicy = class _OIMLogAndContinueErrorPolicy {
464
395
  constructor(options) {
465
396
  this.onError = options?.onError;
466
397
  }
@@ -469,14 +400,14 @@ var _OIMErrorPolicyLogAndContinue = class _OIMErrorPolicyLogAndContinue {
469
400
  this.onError?.(error);
470
401
  }
471
402
  };
472
- _OIMErrorPolicyLogAndContinue.INSTANCE = new _OIMErrorPolicyLogAndContinue();
473
- var OIMErrorPolicyLogAndContinue = _OIMErrorPolicyLogAndContinue;
403
+ _OIMLogAndContinueErrorPolicy.INSTANCE = new _OIMLogAndContinueErrorPolicy();
404
+ var OIMLogAndContinueErrorPolicy = _OIMLogAndContinueErrorPolicy;
474
405
 
475
406
  // src/factories/OIMDB.ts
476
407
  var OIMDB = class {
477
408
  constructor(options) {
478
409
  this.clock = { revision: 0, epoch: 0 };
479
- const errorPolicy = options?.errorPolicy ?? OIMErrorPolicyLogAndContinue.INSTANCE;
410
+ const errorPolicy = options?.errorPolicy ?? OIMLogAndContinueErrorPolicy.INSTANCE;
480
411
  this.collectorSlot = createOIMCollectorSlot({
481
412
  getNowMs: options?.getNowMs ?? Date.now,
482
413
  releaseTimer: options?.releaseTimer ?? OIM_TIMER_ON_TIMEOUT,
@@ -515,14 +446,26 @@ function oimRegisterCoreInstance(coreInstance) {
515
446
  );
516
447
  }
517
448
 
518
- // src/engine/slot/OIMStoreSlotListenerNone.ts
519
- var _OIMStoreSlotListenerNone = class _OIMStoreSlotListenerNone {
449
+ // src/engine/slot/OIMNoStoreSlotListener.ts
450
+ var _OIMNoStoreSlotListener = class _OIMNoStoreSlotListener {
520
451
  onStoreSlotCreated() {
521
452
  return;
522
453
  }
523
454
  };
524
- _OIMStoreSlotListenerNone.INSTANCE = new _OIMStoreSlotListenerNone();
525
- var OIMStoreSlotListenerNone = _OIMStoreSlotListenerNone;
455
+ _OIMNoStoreSlotListener.INSTANCE = new _OIMNoStoreSlotListener();
456
+ var OIMNoStoreSlotListener = _OIMNoStoreSlotListener;
457
+
458
+ // src/engine/slot/OIMNoSlotSubscriptionListener.ts
459
+ var _OIMNoSlotSubscriptionListener = class _OIMNoSlotSubscriptionListener {
460
+ onSlotFirstSubscribed() {
461
+ return;
462
+ }
463
+ onSlotLastUnsubscribed() {
464
+ return;
465
+ }
466
+ };
467
+ _OIMNoSlotSubscriptionListener.INSTANCE = new _OIMNoSlotSubscriptionListener();
468
+ var OIMNoSlotSubscriptionListener = _OIMNoSlotSubscriptionListener;
526
469
 
527
470
  // src/engine/slot/constants/OIM_SLOT_FLAG_EMPTY.ts
528
471
  var OIM_SLOT_FLAG_EMPTY = 1;
@@ -569,6 +512,7 @@ var OIMSlotOwner = class {
569
512
  const subscribers = slotEditable.effects ?? (slotEditable.effects = []);
570
513
  subscribers.push(effect);
571
514
  (slotEditable.effectEdges ?? (slotEditable.effectEdges = [])).push(edge);
515
+ if (subscribers.length === 1) this.onSlotFirstSubscribed(slot);
572
516
  return subscribers.length - 1;
573
517
  }
574
518
  unsubscribeFromSlot(slot, positionInSlot, effect) {
@@ -584,13 +528,25 @@ var OIMSlotOwner = class {
584
528
  subscribers.pop();
585
529
  effectEdges.pop();
586
530
  if (last !== positionInSlot) tailEffect.effectService.setPositionInSubscribedSlot(tailEffect, tailEdge, positionInSlot);
587
- if (last === 0) this.onSlotIdle(slot);
531
+ if (last === 0) {
532
+ this.onSlotIdle(slot);
533
+ this.onSlotLastUnsubscribed(slot);
534
+ }
588
535
  this.unholdSlot(slot);
589
536
  return true;
590
537
  }
591
538
  releaseSlotIfUnheld(_slot) {
592
539
  return;
593
540
  }
541
+ unsafeMutateSlot(slot, mutateSlot) {
542
+ mutateSlot(slot);
543
+ }
544
+ onSlotFirstSubscribed(_slot) {
545
+ return;
546
+ }
547
+ onSlotLastUnsubscribed(_slot) {
548
+ return;
549
+ }
594
550
  onSlotIdle(_slot) {
595
551
  return;
596
552
  }
@@ -625,8 +581,8 @@ function oimMarkSlotReleased(slot) {
625
581
  slot.slotFlags |= OIM_SLOT_FLAG_RELEASED;
626
582
  }
627
583
 
628
- // src/engine/column/OIMColumnOwner.ts
629
- var OIMColumnOwner = class extends OIMSlotOwner {
584
+ // src/engine/column/OIMColumnSlotOwner.ts
585
+ var OIMColumnSlotOwner = class extends OIMSlotOwner {
630
586
  constructor(columnSlotStoreService) {
631
587
  super();
632
588
  this.columnSlotStoreService = columnSlotStoreService;
@@ -634,7 +590,7 @@ var OIMColumnOwner = class extends OIMSlotOwner {
634
590
  getColumnGroup(columnNames) {
635
591
  if (columnNames.length === 0) {
636
592
  throw new Error(
637
- "OIMColumnOwner.getColumnGroup: a column group names at least one column. A slot that hears every column is the any-column slot: holdAnyColumn."
593
+ "OIMColumnSlotOwner.getColumnGroup: a column group names at least one column. A slot that hears every column is the any-column slot: holdAnyColumn."
638
594
  );
639
595
  }
640
596
  const sortedColumnNames = [...new Set(columnNames)].sort();
@@ -688,6 +644,12 @@ var OIMColumnOwner = class extends OIMSlotOwner {
688
644
  oimMarkSlotReleased(columnSlot);
689
645
  carrierSlot.owner.releaseSlotIfUnheld(carrierSlot);
690
646
  }
647
+ onSlotFirstSubscribed(slot) {
648
+ this.carrierSlotOf(slot).owner.onSlotFirstSubscribed(slot);
649
+ }
650
+ onSlotLastUnsubscribed(slot) {
651
+ this.carrierSlotOf(slot).owner.onSlotLastUnsubscribed(slot);
652
+ }
691
653
  getColumnGroupsByKeyOf(carrierSlot) {
692
654
  return carrierSlot.storeSlot.columnGroupsByKey;
693
655
  }
@@ -704,7 +666,7 @@ var OIMColumnOwner = class extends OIMSlotOwner {
704
666
  const registeredColumnGroup = columnGroupsByKey.get(columnGroup.key);
705
667
  if (registeredColumnGroup !== columnGroup && (columnGroup.key !== oimColumnGroupKeyOfColumnNames(columnGroup.columnNames) || columnGroup.key === OIM_ANY_COLUMN_KEY)) {
706
668
  throw new Error(
707
- `OIMColumnOwner.holdColumnGroup: "${columnGroup.key}" is not the key of its columns. A column group comes from getColumnGroup, which builds the key from the names.`
669
+ `OIMColumnSlotOwner.holdColumnGroup: "${columnGroup.key}" is not the key of its columns. A column group comes from getColumnGroup, which builds the key from the names.`
708
670
  );
709
671
  }
710
672
  if (registeredColumnGroup === void 0) {
@@ -783,8 +745,8 @@ function forgetColumnReadersIfUnread(storeSlot, columnName, columnReaders) {
783
745
  storeSlot.columnReadersByColumnName.delete(columnName);
784
746
  }
785
747
 
786
- // src/engine/column/OIMColumnSlotStoreServiceOrdinalDriven.ts
787
- var OIMColumnSlotStoreServiceOrdinalDriven = class {
748
+ // src/engine/column/OIMColumnSlotOrdinalStoreService.ts
749
+ var OIMColumnSlotOrdinalStoreService = class {
788
750
  constructor(options) {
789
751
  this.ordinalsByColumnName = /* @__PURE__ */ new Map();
790
752
  this.declaredColumnNames = new Set(options.columnNames);
@@ -819,6 +781,12 @@ var OIMColumnSlotStoreServiceOrdinalDriven = class {
819
781
  columnSlots[ordinal] = void 0;
820
782
  store.slotCount--;
821
783
  }
784
+ fileSlot(store, slot) {
785
+ this.set(store, slot.key, slot);
786
+ }
787
+ unfileSlot(store, slot) {
788
+ this.remove(store, slot.key);
789
+ }
822
790
  *getSlots(store) {
823
791
  const columnSlots = store.columnSlots;
824
792
  for (let i = 0; i < columnSlots.length; i++) {
@@ -834,7 +802,7 @@ var OIMColumnSlotStoreServiceOrdinalDriven = class {
834
802
  for (let i = 0; i < columnNames.length; i++) {
835
803
  if (this.declaredColumnNames.has(columnNames[i])) continue;
836
804
  throw new Error(
837
- `OIMColumnSlotStoreServiceOrdinalDriven: the column "${columnNames[i]}" is not among the columns this collection was created with, so no slot can be filed for it. Name it in \`columns\`.`
805
+ `OIMColumnSlotOrdinalStoreService: the column "${columnNames[i]}" is not among the columns this collection was created with, so no slot can be filed for it. Name it in \`columns\`.`
838
806
  );
839
807
  }
840
808
  const ordinal = this.ordinalsByColumnName.size;
@@ -844,15 +812,18 @@ var OIMColumnSlotStoreServiceOrdinalDriven = class {
844
812
  };
845
813
 
846
814
  // src/engine/column/utils/oimColumnSlotStoreServiceOfColumnOwnerOptions.ts
847
- function oimColumnSlotStoreServiceOfColumnOwnerOptions(columnOwnerOptions) {
848
- if (columnOwnerOptions.columnNames !== void 0) {
849
- return new OIMColumnSlotStoreServiceOrdinalDriven({ columnNames: columnOwnerOptions.columnNames });
815
+ function oimColumnSlotStoreServiceOfColumnOwnerOptions(columnSlotOwnerOptions) {
816
+ if (columnSlotOwnerOptions.columnNames !== void 0) {
817
+ return new OIMColumnSlotOrdinalStoreService({ columnNames: columnSlotOwnerOptions.columnNames });
850
818
  }
851
- return columnOwnerOptions.columnSlotStoreService;
819
+ return columnSlotOwnerOptions.columnSlotStoreService;
852
820
  }
853
821
 
822
+ // src/engine/computed/constants/OIM_FROZEN_EMPTY_COMPUTED_SLOTS.ts
823
+ var OIM_FROZEN_EMPTY_COMPUTED_SLOTS = Object.freeze([]);
824
+
854
825
  // src/engine/computed/utils/createOIMComputedSlot.ts
855
- function createOIMComputedSlot(key, owner, computedValueService, sourceSlots, sourceComputeds, initialValue, storeSlot = void 0) {
826
+ function createOIMComputedSlot(key, owner, computedValueService, initialValue, storeSlot = void 0) {
856
827
  return {
857
828
  effects: void 0,
858
829
  changedAtRevision: 0,
@@ -869,8 +840,8 @@ function createOIMComputedSlot(key, owner, computedValueService, sourceSlots, so
869
840
  computedValueService,
870
841
  key,
871
842
  indexKeys: void 0,
872
- sourceSlots,
873
- sourceComputeds,
843
+ sourceSlots: OIM_FROZEN_EMPTY_COMPUTED_SLOTS,
844
+ sourceComputeds: OIM_FROZEN_EMPTY_COMPUTED_SLOTS,
874
845
  value: initialValue,
875
846
  ranAtRevision: -1,
876
847
  ranAtEpoch: -1,
@@ -881,9 +852,6 @@ function createOIMComputedSlot(key, owner, computedValueService, sourceSlots, so
881
852
  };
882
853
  }
883
854
 
884
- // src/engine/computed/constants/OIM_FROZEN_EMPTY_COMPUTED_SLOTS.ts
885
- var OIM_FROZEN_EMPTY_COMPUTED_SLOTS = Object.freeze([]);
886
-
887
855
  // src/engine/computed/utils/oimRefreshSourceComputeds.ts
888
856
  function oimRefreshSourceComputeds(sourceComputeds) {
889
857
  for (let i = 0; i < sourceComputeds.length; i++) {
@@ -946,7 +914,7 @@ function oimRefreshComputedSlot(computedSlot, derive, sameValueGuard, channelClo
946
914
  computedSlotEditable.changedAtEpoch = sourceCount === 0 ? channelClock.epoch : newestSourceEpoch;
947
915
  }
948
916
 
949
- // src/engine/column/OIMColumnOwnerPullDriven.ts
917
+ // src/engine/column/OIMPullColumnSlotOwner.ts
950
918
  var columnValueOf = (value, columnName) => typeof value === "object" && value !== null ? value[columnName] : void 0;
951
919
  var isSameColumnValues = (prevColumnValues, nextColumnValues) => {
952
920
  if (!Array.isArray(prevColumnValues) || !Array.isArray(nextColumnValues)) return false;
@@ -956,7 +924,7 @@ var isSameColumnValues = (prevColumnValues, nextColumnValues) => {
956
924
  }
957
925
  return true;
958
926
  };
959
- var OIMColumnOwnerPullDriven = class extends OIMColumnOwner {
927
+ var OIMPullColumnSlotOwner = class extends OIMColumnSlotOwner {
960
928
  constructor(options) {
961
929
  super(oimColumnSlotStoreServiceOfColumnOwnerOptions(options));
962
930
  this.deriveColumnSlotValue = (columnSlot) => {
@@ -977,14 +945,8 @@ var OIMColumnOwnerPullDriven = class extends OIMColumnOwner {
977
945
  return columnSlot.value;
978
946
  }
979
947
  createColumnSlot(carrierSlot, key) {
980
- const columnSlot = createOIMComputedSlot(
981
- key,
982
- this,
983
- this,
984
- OIM_FROZEN_EMPTY_COMPUTED_SLOTS,
985
- [carrierSlot],
986
- void 0
987
- );
948
+ const columnSlot = createOIMComputedSlot(key, this, this, void 0);
949
+ columnSlot.sourceComputeds = [carrierSlot];
988
950
  this.getValueForSlot(columnSlot);
989
951
  return columnSlot;
990
952
  }
@@ -1035,8 +997,8 @@ function oimUnholdSlotsIfAlive(slots) {
1035
997
  for (let i = 0; i < slots.length; i++) oimUnholdSlotIfAlive(slots[i]);
1036
998
  }
1037
999
 
1038
- // src/engine/error/OIMErrorPolicyThrowAtOnce.ts
1039
- var OIMErrorPolicyThrowAtOnce = class {
1000
+ // src/engine/error/OIMThrowAtOnceErrorPolicy.ts
1001
+ var OIMThrowAtOnceErrorPolicy = class {
1040
1002
  onErrorCaught(error) {
1041
1003
  throw error;
1042
1004
  }
@@ -1485,9 +1447,6 @@ var _OIMContentChangeListenerService = class _OIMContentChangeListenerService {
1485
1447
  if (storeSlotEditable.contentChangeListeners === void 0) {
1486
1448
  storeSlotEditable.contentChangeListeners = [];
1487
1449
  storeSlotEditable.contentChangeListenerReadColumnNames = [];
1488
- storeSlotEditable.subframeSlotChannelQueues = [];
1489
- storeSlotEditable.subframePatchChannelQueues = [];
1490
- storeSlotEditable.subframeChangedColumnsChannelQueues = [];
1491
1450
  }
1492
1451
  storeSlotEditable.contentChangeListeners.push(listener);
1493
1452
  storeSlotEditable.contentChangeListenerReadColumnNames.push(readColumnNames);
@@ -1534,290 +1493,87 @@ function oimGetChannelSlot(slot) {
1534
1493
  return slot.storeSlot.channelSlot;
1535
1494
  }
1536
1495
 
1537
- // src/facade/slot/OIMSlotColumnService.ts
1538
- var OIMSlotColumnService = class {
1539
- constructor(columnOwner) {
1540
- this.columnOwner = columnOwner;
1496
+ // src/facade/column/OIMColumnSlotService.ts
1497
+ var OIMColumnSlotService = class {
1498
+ constructor(columnSlotOwner) {
1499
+ this.columnSlotOwner = columnSlotOwner;
1541
1500
  }
1542
1501
  getColumn(slot, columnName) {
1543
- return this.columnOwner.getColumn(slot, columnName, oimGetChannelSlot(slot).collectorSlot.unusedSlotCollectorSlot);
1502
+ return this.columnSlotOwner.getColumn(slot, columnName, oimGetChannelSlot(slot).collectorSlot.unusedSlotCollectorSlot);
1544
1503
  }
1545
1504
  holdColumn(slot, columnName) {
1546
- return this.columnOwner.holdColumn(slot, columnName);
1505
+ return this.columnSlotOwner.holdColumn(slot, columnName);
1547
1506
  }
1548
1507
  getAnyColumn(slot) {
1549
- return this.columnOwner.getAnyColumn(slot, oimGetChannelSlot(slot).collectorSlot.unusedSlotCollectorSlot);
1508
+ return this.columnSlotOwner.getAnyColumn(slot, oimGetChannelSlot(slot).collectorSlot.unusedSlotCollectorSlot);
1550
1509
  }
1551
1510
  holdAnyColumn(slot) {
1552
- return this.columnOwner.holdAnyColumn(slot);
1511
+ return this.columnSlotOwner.holdAnyColumn(slot);
1553
1512
  }
1554
1513
  getColumnGroup(columnNames) {
1555
- return this.columnOwner.getColumnGroup(columnNames);
1514
+ return this.columnSlotOwner.getColumnGroup(columnNames);
1556
1515
  }
1557
1516
  holdColumnGroup(slot, columnGroup) {
1558
- return this.columnOwner.holdColumnGroup(slot, columnGroup);
1517
+ return this.columnSlotOwner.holdColumnGroup(slot, columnGroup);
1559
1518
  }
1560
1519
  unholdColumn(columnSlot) {
1561
- this.columnOwner.unholdSlot(columnSlot);
1562
- }
1563
- };
1564
-
1565
- // src/engine/slot/utils/createOIMStoreSlot.ts
1566
- function createOIMStoreSlot(store, channelSlot, sourceStoreSlot) {
1567
- return {
1568
- store,
1569
- channelSlot,
1570
- contentChangeListeners: void 0,
1571
- contentChangeListenerReadColumnNames: void 0,
1572
- indexKeysPositions: void 0,
1573
- columnListenerCountsByColumnName: void 0,
1574
- allColumnsListenerCount: 0,
1575
- columnGroupsByKey: void 0,
1576
- columnGroupSlotCountsByKey: void 0,
1577
- columnReadersByColumnName: void 0,
1578
- anyColumnSlotCount: 0,
1579
- subframeSlotChannelQueues: void 0,
1580
- subframePatchChannelQueues: void 0,
1581
- subframeChangedColumnsChannelQueues: void 0,
1582
- changedBucketSlotChannelQueue: void 0,
1583
- arrivedBucketMemberSlotChannelQueues: void 0,
1584
- departedBucketMemberSlotChannelQueues: void 0,
1585
- removedAtChannelQueues: void 0,
1586
- writeDepth: 0,
1587
- commandsBucketSlotChannelQueue: void 0,
1588
- sourceStoreSlot,
1589
- keptStampedEntitySlots: void 0,
1590
- derive: void 0,
1591
- createSources: void 0,
1592
- indexKeysPosition: -1,
1593
- contentChangeListener: void 0,
1594
- requestedKeys: void 0,
1595
- bucketColumnNames: void 0,
1596
- isAnyBucketColumnRead: false,
1597
- isDisposed: false
1598
- };
1599
- }
1600
-
1601
- // src/facade/slot/OIMSlotCollectionService.ts
1602
- var OIMSlotCollectionService = class extends OIMSlotColumnService {
1603
- constructor(options) {
1604
- super(options.slotOwnerService.columnOwner);
1605
- this.slotOwnerService = options.slotOwnerService;
1606
- this.slotStoreService = options.slotStoreService;
1607
- this.slotContentService = options.slotContentService;
1608
- this.storeSlotListener = options.storeSlotListener;
1609
- }
1610
- createStoreSlot(channelMap) {
1611
- const channelSlot = channelMap.defaultChannelSlot;
1612
- return this.createStoreSlotWith((store) => createOIMStoreSlot(store, channelSlot));
1613
- }
1614
- createStoreSlotFrom(sourceStoreSlot) {
1615
- return this.createStoreSlotWith((store) => createOIMStoreSlot(store, sourceStoreSlot.channelSlot, sourceStoreSlot));
1616
- }
1617
- createStoreSlotWith(createStoreSlotLiteral) {
1618
- const storeSlot = createStoreSlotLiteral(this.slotStoreService.createStore());
1619
- if (this.storeSlotListener !== void 0) this.storeSlotListener.onStoreSlotCreated(storeSlot);
1620
- return storeSlot;
1621
- }
1622
- findSlotByKey(storeSlot, key) {
1623
- return this.slotStoreService.get(storeSlot.store, key);
1624
- }
1625
- hasSlotContentByKey(storeSlot, key) {
1626
- const slot = this.slotStoreService.get(storeSlot.store, key);
1627
- return slot !== void 0 && !oimIsSlotEmpty(slot);
1628
- }
1629
- getSlotByKey(storeSlot, key) {
1630
- const found = this.slotStoreService.get(storeSlot.store, key);
1631
- if (found !== void 0) return found;
1632
- const slot = this.mintSlotByKey(storeSlot, key);
1633
- OIMUnusedSlotCollectorService.INSTANCE.holdSlotUntilFlush(storeSlot.channelSlot.collectorSlot.unusedSlotCollectorSlot, slot);
1634
- return slot;
1635
- }
1636
- holdSlotByKey(storeSlot, key) {
1637
- const slot = this.slotStoreService.get(storeSlot.store, key) ?? this.mintSlotByKey(storeSlot, key);
1638
- this.slotOwnerService.holdSlot(slot);
1639
- return slot;
1640
- }
1641
- getSlots(storeSlot) {
1642
- return this.slotStoreService.getSlots(storeSlot.store);
1643
- }
1644
- getSlotCount(storeSlot) {
1645
- return this.slotStoreService.getSlotCount(storeSlot.store);
1646
- }
1647
- isSameKey(key, otherKey) {
1648
- return this.slotStoreService.isSameKey(key, otherKey);
1649
- }
1650
- onSlotMinted(_storeSlot, _slot) {
1651
- return;
1652
- }
1653
- mintSlotByKey(storeSlot, key) {
1654
- const slotOwnerService = this.slotOwnerService;
1655
- const slot = slotOwnerService.createSlot(this.slotStoreService.ownKey(key), storeSlot);
1656
- this.onSlotMinted(storeSlot, slot);
1657
- slotOwnerService.settleEmptiness(slot, slotOwnerService.isSlotEmpty(slot));
1658
- slotOwnerService.fileSlot(storeSlot, slot);
1659
- return slot;
1660
- }
1661
- };
1662
-
1663
- // src/facade/slot/OIMSingleSlotService.ts
1664
- var OIMSingleSlotService = class extends OIMSlotColumnService {
1665
- constructor(options) {
1666
- super(options.slotOwnerService.columnOwner);
1667
- this.slotOwnerService = options.slotOwnerService;
1668
- this.slotStoreService = options.slotStoreService;
1669
- this.slotContentService = options.slotContentService;
1670
- this.storeSlotListener = options.storeSlotListener;
1671
- }
1672
- createStoreSlot(channelMap) {
1673
- const storeSlot = createOIMStoreSlot(
1674
- this.slotStoreService.createStore(),
1675
- channelMap.defaultChannelSlot
1676
- );
1677
- if (this.storeSlotListener !== void 0) this.storeSlotListener.onStoreSlotCreated(storeSlot);
1678
- return storeSlot;
1679
- }
1680
- findSingleSlot(storeSlot) {
1681
- return this.slotStoreService.get(storeSlot.store);
1682
- }
1683
- hasSingleSlotContent(storeSlot) {
1684
- const slot = this.slotStoreService.get(storeSlot.store);
1685
- return slot !== void 0 && !oimIsSlotEmpty(slot);
1686
- }
1687
- getSingleSlot(storeSlot) {
1688
- const found = this.slotStoreService.get(storeSlot.store);
1689
- if (found !== void 0) return found;
1690
- const slot = this.mintSingleSlot(storeSlot);
1691
- OIMUnusedSlotCollectorService.INSTANCE.holdSlotUntilFlush(storeSlot.channelSlot.collectorSlot.unusedSlotCollectorSlot, slot);
1692
- return slot;
1693
- }
1694
- holdSingleSlot(storeSlot) {
1695
- const slot = this.slotStoreService.get(storeSlot.store) ?? this.mintSingleSlot(storeSlot);
1696
- this.slotOwnerService.holdSlot(slot);
1697
- return slot;
1698
- }
1699
- mintSingleSlot(storeSlot) {
1700
- const slotOwnerService = this.slotOwnerService;
1701
- const slot = slotOwnerService.createSlot(void 0, storeSlot);
1702
- slotOwnerService.settleEmptiness(slot, slotOwnerService.isSlotEmpty(slot));
1703
- slotOwnerService.fileSlot(storeSlot, slot);
1704
- return slot;
1520
+ this.columnSlotOwner.unholdSlot(columnSlot);
1705
1521
  }
1706
1522
  };
1707
1523
 
1708
- // src/engine/channel/utils/oimGetChannelQueueAtDepth.ts
1709
- function oimGetChannelQueueAtDepth(channelQueues, depth) {
1710
- const found = channelQueues[depth];
1711
- if (found !== void 0) return found;
1712
- const made = new OIMChannelQueue();
1713
- channelQueues[depth] = made;
1714
- return made;
1715
- }
1716
-
1717
1524
  // src/engine/slot/OIMContentChangeDeliveryService.ts
1718
1525
  var _OIMContentChangeDeliveryService = class _OIMContentChangeDeliveryService {
1719
- isDeliveryDeferred(channelSlot) {
1720
- return channelSlot.contentSubframeDepth > 0 || channelSlot.subframeDeliveryDepth > 0;
1526
+ isBatchOpen(storeSlot) {
1527
+ return storeSlot.batchDepth > 0;
1721
1528
  }
1722
- openContentSubframe(channelSlot) {
1723
- OIMChannelService.INSTANCE.openSubframe(channelSlot);
1724
- channelSlot.contentSubframeDepth++;
1529
+ openBatch(storeSlot) {
1530
+ storeSlot.batchDepth++;
1725
1531
  }
1726
- closeContentSubframe(channelSlot) {
1727
- try {
1728
- if (--channelSlot.contentSubframeDepth > 0 || channelSlot.subframeDeliveryDepth > 0) return;
1729
- this.deliverEnqueuedContentChanges(channelSlot);
1730
- } finally {
1731
- OIMChannelService.INSTANCE.closeSubframe(channelSlot);
1732
- }
1733
- }
1734
- enqueueContentChange(channelSlot, storeSlot, slot, patch, changedColumns) {
1735
- const subframeDeliveryDepth = channelSlot.subframeDeliveryDepth;
1736
- const subframeSlotChannelQueue = oimGetChannelQueueAtDepth(
1737
- storeSlot.subframeSlotChannelQueues,
1738
- subframeDeliveryDepth
1739
- );
1740
- if (subframeSlotChannelQueue.getEntryCount() === 0) {
1741
- oimGetChannelQueueAtDepth(channelSlot.subframeStoreSlotChannelQueues, subframeDeliveryDepth).enqueueEntry(storeSlot);
1742
- }
1743
- subframeSlotChannelQueue.enqueueEntry(slot);
1744
- oimGetChannelQueueAtDepth(
1745
- storeSlot.subframePatchChannelQueues,
1746
- subframeDeliveryDepth
1747
- ).enqueueEntry(patch);
1748
- oimGetChannelQueueAtDepth(
1749
- storeSlot.subframeChangedColumnsChannelQueues,
1750
- subframeDeliveryDepth
1751
- ).enqueueEntry(changedColumns === void 0 ? void 0 : changedColumns.slice());
1752
- }
1753
- isLastEnqueuedSlot(channelSlot, storeSlot, slot) {
1754
- const subframeSlotChannelQueues = storeSlot.subframeSlotChannelQueues;
1755
- if (subframeSlotChannelQueues === void 0) return false;
1756
- const subframeSlotChannelQueue = subframeSlotChannelQueues[channelSlot.subframeDeliveryDepth];
1757
- if (subframeSlotChannelQueue === void 0) return false;
1758
- const subframeSlotCount = subframeSlotChannelQueue.getEntryCount();
1759
- return subframeSlotCount !== 0 && subframeSlotChannelQueue.getEntryAt(subframeSlotCount - 1) === slot;
1760
- }
1761
- deliverEnqueuedContentChanges(channelSlot) {
1762
- const storeSlotChannelQueue = channelSlot.subframeStoreSlotChannelQueues[channelSlot.subframeDeliveryDepth];
1763
- if (storeSlotChannelQueue === void 0 || storeSlotChannelQueue.getEntryCount() === 0) return;
1764
- this.deliverSubframeContentChanges(channelSlot, storeSlotChannelQueue);
1765
- }
1766
- deliverSubframeContentChanges(channelSlot, storeSlotChannelQueue) {
1767
- const subframeDeliveryDepth = channelSlot.subframeDeliveryDepth;
1768
- channelSlot.subframeDeliveryDepth = subframeDeliveryDepth + 1;
1769
- let isRefused = false;
1770
- let refusal;
1771
- try {
1772
- for (let i = 0; i < storeSlotChannelQueue.getEntryCount(); i++) {
1773
- try {
1774
- this.deliverStoreSlotContentChanges(storeSlotChannelQueue.getEntryAt(i), subframeDeliveryDepth);
1775
- } catch (error) {
1776
- if (!isRefused) refusal = error;
1777
- isRefused = true;
1778
- }
1779
- }
1780
- const nextStoreSlotChannelQueue = channelSlot.subframeStoreSlotChannelQueues[subframeDeliveryDepth + 1];
1781
- if (nextStoreSlotChannelQueue !== void 0 && nextStoreSlotChannelQueue.getEntryCount() !== 0) {
1782
- try {
1783
- this.deliverSubframeContentChanges(channelSlot, nextStoreSlotChannelQueue);
1784
- } catch (error) {
1785
- if (!isRefused) refusal = error;
1786
- isRefused = true;
1787
- }
1788
- }
1789
- } finally {
1790
- storeSlotChannelQueue.keepFirstEntries(0);
1791
- channelSlot.subframeDeliveryDepth = subframeDeliveryDepth;
1792
- }
1793
- if (isRefused) throw refusal;
1532
+ closeBatch(storeSlot) {
1533
+ const storeSlotEditable = storeSlot;
1534
+ if (--storeSlotEditable.batchDepth > 0) return;
1535
+ const batchSlotChannelQueue = storeSlot.batchSlotChannelQueue;
1536
+ if (batchSlotChannelQueue === void 0 || batchSlotChannelQueue.getEntryCount() === 0) return;
1537
+ this.deliverBatch(storeSlot, batchSlotChannelQueue);
1794
1538
  }
1795
- deliverStoreSlotContentChanges(storeSlot, subframeDeliveryDepth) {
1796
- const subframeSlotChannelQueue = storeSlot.subframeSlotChannelQueues[subframeDeliveryDepth];
1797
- const subframePatchChannelQueue = storeSlot.subframePatchChannelQueues[subframeDeliveryDepth];
1798
- const subframeChangedColumnsChannelQueue = storeSlot.subframeChangedColumnsChannelQueues[subframeDeliveryDepth];
1539
+ enqueueContentChange(storeSlot, slot, patch, changedColumns) {
1540
+ const storeSlotEditable = storeSlot;
1541
+ (storeSlotEditable.batchSlotChannelQueue ?? (storeSlotEditable.batchSlotChannelQueue = new OIMChannelQueue())).enqueueEntry(slot);
1542
+ (storeSlotEditable.batchPatchChannelQueue ?? (storeSlotEditable.batchPatchChannelQueue = new OIMChannelQueue())).enqueueEntry(patch);
1543
+ (storeSlotEditable.batchChangedColumnsChannelQueue ?? (storeSlotEditable.batchChangedColumnsChannelQueue = new OIMChannelQueue())).enqueueEntry(changedColumns === void 0 ? void 0 : changedColumns.slice());
1544
+ }
1545
+ isLastEnqueuedSlot(storeSlot, slot) {
1546
+ const batchSlotChannelQueue = storeSlot.batchSlotChannelQueue;
1547
+ if (batchSlotChannelQueue === void 0) return false;
1548
+ const batchSlotCount = batchSlotChannelQueue.getEntryCount();
1549
+ return batchSlotCount !== 0 && batchSlotChannelQueue.getEntryAt(batchSlotCount - 1) === slot;
1550
+ }
1551
+ deliverBatch(storeSlot, batchSlotChannelQueue) {
1552
+ const batchPatchChannelQueue = storeSlot.batchPatchChannelQueue;
1553
+ const batchChangedColumnsChannelQueue = storeSlot.batchChangedColumnsChannelQueue;
1799
1554
  const listeners = storeSlot.contentChangeListeners;
1800
1555
  try {
1801
- if (subframeSlotChannelQueue.getEntryCount() === 1) {
1802
- const slot = subframeSlotChannelQueue.getEntryAt(0);
1803
- const patch = subframePatchChannelQueue.getEntryAt(0);
1804
- const changedColumns = subframeChangedColumnsChannelQueue.getEntryAt(0);
1556
+ if (listeners === void 0) return;
1557
+ if (batchSlotChannelQueue.getEntryCount() === 1) {
1558
+ const slot = batchSlotChannelQueue.getEntryAt(0);
1559
+ const patch = batchPatchChannelQueue.getEntryAt(0);
1560
+ const changedColumns = batchChangedColumnsChannelQueue.getEntryAt(0);
1805
1561
  for (let i = 0; i < listeners.length; i++) listeners[i].onContentChanged(slot, patch, changedColumns);
1806
1562
  } else {
1807
1563
  for (let i = 0; i < listeners.length; i++) {
1808
- listeners[i].onContentChangedMany(subframeSlotChannelQueue, subframePatchChannelQueue, subframeChangedColumnsChannelQueue);
1564
+ listeners[i].onContentChangedMany(batchSlotChannelQueue, batchPatchChannelQueue, batchChangedColumnsChannelQueue);
1809
1565
  }
1810
1566
  }
1811
1567
  } finally {
1812
1568
  try {
1813
- for (let i = 0; i < subframeSlotChannelQueue.getEntryCount(); i++) {
1814
- const slot = subframeSlotChannelQueue.getEntryAt(i);
1569
+ for (let i = 0; i < batchSlotChannelQueue.getEntryCount(); i++) {
1570
+ const slot = batchSlotChannelQueue.getEntryAt(i);
1815
1571
  slot.owner.releaseSlotIfUnheld(slot);
1816
1572
  }
1817
1573
  } finally {
1818
- subframeSlotChannelQueue.keepFirstEntries(0);
1819
- subframePatchChannelQueue.keepFirstEntries(0);
1820
- subframeChangedColumnsChannelQueue.keepFirstEntries(0);
1574
+ batchSlotChannelQueue.keepFirstEntries(0);
1575
+ batchPatchChannelQueue.keepFirstEntries(0);
1576
+ batchChangedColumnsChannelQueue.keepFirstEntries(0);
1821
1577
  }
1822
1578
  }
1823
1579
  }
@@ -1825,8 +1581,8 @@ var _OIMContentChangeDeliveryService = class _OIMContentChangeDeliveryService {
1825
1581
  _OIMContentChangeDeliveryService.INSTANCE = new _OIMContentChangeDeliveryService();
1826
1582
  var OIMContentChangeDeliveryService = _OIMContentChangeDeliveryService;
1827
1583
 
1828
- // src/engine/collector/OIMSlotReleasePolicyAtEmpty.ts
1829
- var _OIMSlotReleasePolicyAtEmpty = class _OIMSlotReleasePolicyAtEmpty {
1584
+ // src/engine/collector/OIMSlotAtEmptyReleasePolicy.ts
1585
+ var _OIMSlotAtEmptyReleasePolicy = class _OIMSlotAtEmptyReleasePolicy {
1830
1586
  constructor() {
1831
1587
  this.releasesWrittenSlots = false;
1832
1588
  this.schedulesReleaseOnWrite = false;
@@ -1850,34 +1606,26 @@ var _OIMSlotReleasePolicyAtEmpty = class _OIMSlotReleasePolicyAtEmpty {
1850
1606
  return;
1851
1607
  }
1852
1608
  };
1853
- _OIMSlotReleasePolicyAtEmpty.INSTANCE = new _OIMSlotReleasePolicyAtEmpty();
1854
- var OIMSlotReleasePolicyAtEmpty = _OIMSlotReleasePolicyAtEmpty;
1609
+ _OIMSlotAtEmptyReleasePolicy.INSTANCE = new _OIMSlotAtEmptyReleasePolicy();
1610
+ var OIMSlotAtEmptyReleasePolicy = _OIMSlotAtEmptyReleasePolicy;
1855
1611
 
1856
1612
  // src/engine/slot/OIMSlotOwnerService.ts
1857
1613
  var OIMSlotOwnerService = class extends OIMSlotOwner {
1858
1614
  constructor(options) {
1859
1615
  super();
1860
- this.slotContentStrategy = options.slotContentStrategy;
1861
- this.slotStoreService = options.slotStoreService;
1616
+ this.slotContentService = options.slotContentService;
1617
+ this.slotFilingService = options.slotFilingService;
1862
1618
  this.slotStamp = options.slotStamp;
1863
- const slotReleasePolicy = options.slotReleasePolicy ?? OIMSlotReleasePolicyAtEmpty.INSTANCE;
1619
+ const slotReleasePolicy = options.slotReleasePolicy ?? OIMSlotAtEmptyReleasePolicy.INSTANCE;
1864
1620
  this.slotReleasePolicy = slotReleasePolicy;
1865
1621
  this.releasesWrittenSlots = slotReleasePolicy.releasesWrittenSlots;
1866
1622
  this.schedulesReleaseOnWrite = slotReleasePolicy.schedulesReleaseOnWrite;
1867
- this.columnOwner = options.createColumnOwner(options.columnOwnerOptions);
1868
- this.slotContentFlushStrategy = options.slotContentFlushStrategy;
1869
- }
1870
- listChangedStoreSlot(storeSlot) {
1871
- OIMChannelService.INSTANCE.listChangedStoreSlot(storeSlot.channelSlot, storeSlot, this);
1872
- }
1873
- onStoreSlotSubframeClosed(storeSlot) {
1874
- this.slotContentFlushStrategy?.onSubframeClosed(storeSlot, this);
1875
- }
1876
- createSlot(key, storeSlot) {
1877
- return this.slotContentStrategy.createSlot(key, storeSlot, this);
1623
+ this.settlesWrittenSlots = this.releasesWrittenSlots || this.schedulesReleaseOnWrite || options.slotStamp !== void 0;
1624
+ this.slotSubscriptionListener = options.slotSubscriptionListener ?? OIMNoSlotSubscriptionListener.INSTANCE;
1625
+ this.columnSlotOwner = options.createColumnSlotOwner(options.columnSlotOwnerOptions);
1878
1626
  }
1879
1627
  isSlotEmpty(slot) {
1880
- return this.slotContentStrategy.isSlotEmpty(slot);
1628
+ return this.slotContentService.isSlotEmpty(slot);
1881
1629
  }
1882
1630
  hasColumnSlots(slot) {
1883
1631
  return slot.columnSlotStore !== void 0;
@@ -1894,10 +1642,8 @@ var OIMSlotOwnerService = class extends OIMSlotOwner {
1894
1642
  const listeners = storeSlot.contentChangeListeners;
1895
1643
  if (listeners === void 0 || listeners.length === 0) return;
1896
1644
  if (changedColumns !== void 0 && !this.isAnyColumnRead(storeSlot, changedColumns)) return;
1897
- const channelSlot = storeSlot.channelSlot;
1898
- const contentChangeDeliveryService = OIMContentChangeDeliveryService.INSTANCE;
1899
- if (contentChangeDeliveryService.isDeliveryDeferred(channelSlot)) {
1900
- contentChangeDeliveryService.enqueueContentChange(channelSlot, storeSlot, slot, patch, changedColumns);
1645
+ if (storeSlot.batchDepth > 0) {
1646
+ OIMContentChangeDeliveryService.INSTANCE.enqueueContentChange(storeSlot, slot, patch, changedColumns);
1901
1647
  return;
1902
1648
  }
1903
1649
  for (let i = 0; i < listeners.length; i++) listeners[i].onContentChanged(slot, patch, changedColumns);
@@ -1905,7 +1651,7 @@ var OIMSlotOwnerService = class extends OIMSlotOwner {
1905
1651
  isAnyColumnReferenced(slot, changedColumns) {
1906
1652
  const storeSlot = slot.storeSlot;
1907
1653
  if (storeSlot === void 0) return false;
1908
- return slot.columnSlotStore !== void 0 && this.columnOwner.isAnyColumnReferenced(storeSlot, changedColumns) || this.isAnyColumnRead(storeSlot, changedColumns);
1654
+ return slot.columnSlotStore !== void 0 && this.columnSlotOwner.isAnyColumnReferenced(storeSlot, changedColumns) || this.isAnyColumnRead(storeSlot, changedColumns);
1909
1655
  }
1910
1656
  isAnyColumnRead(storeSlot, changedColumns) {
1911
1657
  if (storeSlot.allColumnsListenerCount !== 0) return true;
@@ -1924,11 +1670,7 @@ var OIMSlotOwnerService = class extends OIMSlotOwner {
1924
1670
  }
1925
1671
  releaseSlotIfUnheldAfterListeners(slot) {
1926
1672
  const storeSlot = slot.storeSlot;
1927
- if (storeSlot !== void 0) {
1928
- const contentChangeDeliveryService = OIMContentChangeDeliveryService.INSTANCE;
1929
- const channelSlot = storeSlot.channelSlot;
1930
- if (contentChangeDeliveryService.isDeliveryDeferred(channelSlot) && contentChangeDeliveryService.isLastEnqueuedSlot(channelSlot, storeSlot, slot)) return;
1931
- }
1673
+ if (storeSlot !== void 0 && storeSlot.batchDepth > 0 && OIMContentChangeDeliveryService.INSTANCE.isLastEnqueuedSlot(storeSlot, slot)) return;
1932
1674
  this.releaseSlotIfUnheld(slot);
1933
1675
  }
1934
1676
  releaseWrittenSlotIfUnheld(slot) {
@@ -1938,8 +1680,8 @@ var OIMSlotOwnerService = class extends OIMSlotOwner {
1938
1680
  OIMChannelService.INSTANCE.assertNotFlushing(oimGetChannelSlot(slot));
1939
1681
  oimAssertSlotNotReleased(slot);
1940
1682
  }
1941
- fileSlot(storeSlot, slot) {
1942
- this.slotStoreService.set(storeSlot.store, slot.key, slot);
1683
+ fileSlot(slot) {
1684
+ this.slotFilingService.fileSlot(slot.storeSlot.store, slot);
1943
1685
  }
1944
1686
  writeSlotToChannelAndSettle(slot, wasEmpty) {
1945
1687
  OIMChannelService.INSTANCE.writeWithoutFlushCheck(oimGetChannelSlot(slot), slot);
@@ -1969,6 +1711,12 @@ var OIMSlotOwnerService = class extends OIMSlotOwner {
1969
1711
  if (oimIsSlotEmpty(slot)) return;
1970
1712
  if (this.slotReleasePolicy.onSlotIdle(slot)) this.releaseSlotIfUnheld(slot);
1971
1713
  }
1714
+ onSlotFirstSubscribed(slot) {
1715
+ this.slotSubscriptionListener.onSlotFirstSubscribed(slot);
1716
+ }
1717
+ onSlotLastUnsubscribed(slot) {
1718
+ this.slotSubscriptionListener.onSlotLastUnsubscribed(slot);
1719
+ }
1972
1720
  onSlotUnheld(slot) {
1973
1721
  this.slotReleasePolicy.onSlotUnheld(slot);
1974
1722
  }
@@ -1993,222 +1741,320 @@ var OIMSlotOwnerService = class extends OIMSlotOwner {
1993
1741
  if (slot.holdCount > 0) return false;
1994
1742
  if (slot.owner !== this) return false;
1995
1743
  if (slot.columnSlotStore !== void 0) return false;
1996
- return !this.slotContentStrategy.hasReference(slot);
1744
+ return !this.slotContentService.hasReference(slot);
1997
1745
  }
1998
1746
  releaseSlot(slot, isEmpty) {
1999
1747
  if (!isEmpty) this.assertWritable(slot);
2000
- this.slotContentStrategy.releaseSlotContent(slot, this);
1748
+ this.slotContentService.releaseSlotContent(slot, this);
2001
1749
  slot.slotFlags |= OIM_SLOT_FLAG_EMPTY;
2002
1750
  this.slotReleasePolicy.cancelSlotRelease(slot);
2003
1751
  const storeSlot = slot.storeSlot;
2004
- if (storeSlot !== void 0) this.slotStoreService.remove(storeSlot.store, slot.key);
1752
+ if (storeSlot !== void 0) this.slotFilingService.unfileSlot(storeSlot.store, slot);
2005
1753
  oimMarkSlotReleased(slot);
2006
1754
  }
2007
1755
  };
2008
1756
 
2009
- // src/engine/entity/utils/createOIMEntitySlot.ts
2010
- function createOIMEntitySlot(key, owner, storeSlot = void 0) {
1757
+ // src/engine/slot/utils/createOIMStoreSlot.ts
1758
+ function createOIMStoreSlot(store, channelSlot, slotService, sourceStoreSlot) {
2011
1759
  return {
2012
- effects: void 0,
2013
- changedAtRevision: 0,
2014
- changedAtEpoch: 0,
2015
- effectEdges: void 0,
2016
- holdCount: 0,
2017
- releaseDueAfterWriteMs: -1,
2018
- releaseDueAfterIdleMs: -1,
2019
- releaseDueAfterUnholdMs: -1,
2020
- slotFlags: OIM_SLOT_FLAG_EMPTY,
2021
- owner,
2022
- key,
2023
- entity: void 0,
2024
- columnSlotStore: void 0,
2025
- storeSlot,
2026
- data: void 0,
2027
- indexKeys: void 0
2028
- };
2029
- }
2030
-
2031
- // src/engine/slot/utils/oimFillEntitiesLengthMismatchError.ts
2032
- function oimFillEntitiesLengthMismatchError(collectionName, keyCount, contentCount) {
2033
- return new Error(
2034
- `${collectionName}.fillEntities: ${keyCount} keys against ${contentCount} contents. The two run in step \u2014 the content at a position is filed under the key at that same position \u2014 so lists of different lengths name either a key with nothing to file or a content with nowhere to go, and which of the two it is cannot be guessed.`
2035
- );
2036
- }
2037
-
2038
- // src/engine/slot/utils/oimFillEntitiesIntoFilledCollectionError.ts
2039
- function oimFillEntitiesIntoFilledCollectionError(collectionName) {
2040
- return new Error(
2041
- `${collectionName}.fillEntities: this collection already holds identities, and fillEntities files every key without asking whether it is taken \u2014 which would mint a second identity under a key that has one and strand every effect on the first. Use \`upsertEntity\` per entry, which asks; it is one hash more and correct at any moment.`
2042
- );
2043
- }
2044
-
2045
- // src/engine/slot/utils/oimFillEntitiesKeyNamedTwiceError.ts
2046
- function oimFillEntitiesKeyNamedTwiceError(collectionName) {
2047
- return new Error(
2048
- `${collectionName}.fillEntities: the pairs name one key more than once. Filing the second would take the identity the first is under and strand every effect on it, and nothing could reach the stranded one again. The collection is left as fillEntities found it. Use \`upsertEntity\` per entry, which asks.`
2049
- );
2050
- }
2051
-
2052
- // src/engine/entity/OIMSlotEmptinessByEntityPresence.ts
2053
- var _OIMSlotEmptinessByEntityPresence = class _OIMSlotEmptinessByEntityPresence {
2054
- isEmpty(entitySlot) {
2055
- return entitySlot.entity === void 0;
2056
- }
2057
- };
2058
- _OIMSlotEmptinessByEntityPresence.INSTANCE = new _OIMSlotEmptinessByEntityPresence();
2059
- var OIMSlotEmptinessByEntityPresence = _OIMSlotEmptinessByEntityPresence;
2060
-
2061
- // src/engine/entity/OIMSlotContentEntityService.ts
2062
- var OIMSlotContentEntityService = class {
2063
- constructor(options) {
2064
- this.keyOf = options.keyOf;
2065
- this.slotStoreService = options.slotStoreService;
2066
- this.entityWriter = options.entityWriter;
2067
- this.slotEmptiness = options.slotEmptiness;
2068
- this.updatesEmptinessOnColumnWrite = options.slotEmptiness !== OIMSlotEmptinessByEntityPresence.INSTANCE || options.slotReleasePolicy?.schedulesReleaseOnWrite === true || options.slotReleasePolicy?.releasesWrittenSlots === true || options.slotStamp !== void 0;
2069
- this.slotOwnerService = new OIMSlotOwnerService({
2070
- slotStamp: options.slotStamp,
2071
- slotReleasePolicy: options.slotReleasePolicy,
2072
- slotStoreService: options.slotStoreService,
2073
- slotContentStrategy: {
2074
- createSlot: (key, storeSlot, slotOwnerService) => createOIMEntitySlot(key, slotOwnerService, storeSlot),
2075
- isSlotEmpty: (entitySlot) => this.slotEmptiness.isEmpty(entitySlot),
2076
- hasReference: () => false,
2077
- releaseSlotContent: (entitySlot) => {
2078
- this.releaseSlotContent(entitySlot);
2079
- }
2080
- },
2081
- columnOwnerOptions: options.columnOwnerOptions,
2082
- createColumnOwner: options.createColumnOwner
2083
- });
1760
+ store,
1761
+ slotService,
1762
+ channelSlot,
1763
+ contentChangeListeners: void 0,
1764
+ contentChangeListenerReadColumnNames: void 0,
1765
+ indexKeysPositions: void 0,
1766
+ columnListenerCountsByColumnName: void 0,
1767
+ allColumnsListenerCount: 0,
1768
+ columnGroupsByKey: void 0,
1769
+ columnGroupSlotCountsByKey: void 0,
1770
+ columnReadersByColumnName: void 0,
1771
+ anyColumnSlotCount: 0,
1772
+ batchDepth: 0,
1773
+ batchSlotChannelQueue: void 0,
1774
+ batchPatchChannelQueue: void 0,
1775
+ batchChangedColumnsChannelQueue: void 0,
1776
+ arrivedBucketMemberSlotChannelQueues: void 0,
1777
+ departedBucketMemberSlotChannelQueues: void 0,
1778
+ removedAtChannelQueues: void 0,
1779
+ writeDepth: 0,
1780
+ commandsBucketSlotChannelQueue: void 0,
1781
+ sourceStoreSlot,
1782
+ keptStampedEntitySlots: void 0,
1783
+ derive: void 0,
1784
+ createSources: void 0,
1785
+ indexKeysPosition: -1,
1786
+ contentChangeListener: void 0,
1787
+ requestedKeys: void 0,
1788
+ bucketColumnNames: void 0,
1789
+ isAnyBucketColumnRead: false,
1790
+ isDisposed: false
1791
+ };
1792
+ }
1793
+
1794
+ // src/facade/slot/OIMSlotCollectionService.ts
1795
+ var OIMSlotCollectionService = class {
1796
+ constructor(options) {
1797
+ const slotOwnerService = new OIMSlotOwnerService({ ...options, slotFilingService: options.slotStoreService });
1798
+ this.slotOwnerService = slotOwnerService;
1799
+ this.columnSlotService = new OIMColumnSlotService(slotOwnerService.columnSlotOwner);
1800
+ this.slotStoreService = options.slotStoreService;
1801
+ this.keyedSlotCreator = options.slotContentService;
1802
+ this.slotContentService = options.slotContentService;
1803
+ this.storeSlotListener = options.storeSlotListener;
2084
1804
  }
2085
1805
  get slotOwner() {
2086
1806
  return this.slotOwnerService;
2087
1807
  }
2088
- findEntityByKey(storeSlot, key) {
2089
- return this.slotStoreService.get(storeSlot.store, key)?.entity;
1808
+ createStoreSlot(channelMap) {
1809
+ const channelSlot = channelMap.defaultChannelSlot;
1810
+ return this.createStoreSlotWith((store) => createOIMStoreSlot(store, channelSlot, this));
1811
+ }
1812
+ createStoreSlotFrom(sourceStoreSlot) {
1813
+ return this.createStoreSlotWith((store) => createOIMStoreSlot(
1814
+ store,
1815
+ sourceStoreSlot.channelSlot,
1816
+ this,
1817
+ sourceStoreSlot
1818
+ ));
1819
+ }
1820
+ createStoreSlotWith(createStoreSlotLiteral) {
1821
+ const storeSlot = createStoreSlotLiteral(this.slotStoreService.createStore());
1822
+ if (this.storeSlotListener !== void 0) this.storeSlotListener.onStoreSlotCreated(storeSlot);
1823
+ return storeSlot;
1824
+ }
1825
+ findSlotByKey(storeSlot, key) {
1826
+ return this.slotStoreService.get(storeSlot.store, key);
1827
+ }
1828
+ hasSlotContentByKey(storeSlot, key) {
1829
+ const slot = this.slotStoreService.get(storeSlot.store, key);
1830
+ return slot !== void 0 && !oimIsSlotEmpty(slot);
1831
+ }
1832
+ getSlotByKey(storeSlot, key) {
1833
+ const found = this.slotStoreService.get(storeSlot.store, key);
1834
+ if (found !== void 0) return found;
1835
+ const slot = this.mintSlotByKey(storeSlot, key);
1836
+ OIMUnusedSlotCollectorService.INSTANCE.holdSlotUntilFlush(storeSlot.channelSlot.collectorSlot.unusedSlotCollectorSlot, slot);
1837
+ return slot;
1838
+ }
1839
+ holdSlotByKey(storeSlot, key) {
1840
+ const slot = this.slotStoreService.get(storeSlot.store, key) ?? this.mintSlotByKey(storeSlot, key);
1841
+ this.slotOwnerService.holdSlot(slot);
1842
+ return slot;
1843
+ }
1844
+ getSlots(storeSlot) {
1845
+ return this.slotStoreService.getSlots(storeSlot.store);
1846
+ }
1847
+ getSlotCount(storeSlot) {
1848
+ return this.slotStoreService.getSlotCount(storeSlot.store);
1849
+ }
1850
+ isSameKey(key, otherKey) {
1851
+ return this.slotStoreService.isSameKey(key, otherKey);
1852
+ }
1853
+ openBatch(storeSlot) {
1854
+ OIMContentChangeDeliveryService.INSTANCE.openBatch(storeSlot);
2090
1855
  }
2091
- upsertEntity(storeSlot, entity, changedEntitySlots) {
2092
- return this.insertEntity(storeSlot, this.keyOf(entity), entity, changedEntitySlots);
1856
+ closeBatch(storeSlot) {
1857
+ OIMContentChangeDeliveryService.INSTANCE.closeBatch(storeSlot);
2093
1858
  }
2094
- upsertEntities(storeSlot, entities, changedEntitySlots) {
2095
- const entitySlots = [];
2096
- const channelSlot = storeSlot.channelSlot;
2097
- OIMContentChangeDeliveryService.INSTANCE.openContentSubframe(channelSlot);
1859
+ writeInBatch(storeSlot, write) {
1860
+ const contentChangeDeliveryService = OIMContentChangeDeliveryService.INSTANCE;
1861
+ contentChangeDeliveryService.openBatch(storeSlot);
2098
1862
  try {
2099
- for (let i = 0; i < entities.length; i++) entitySlots.push(this.upsertEntity(storeSlot, entities[i], changedEntitySlots));
2100
- return entitySlots;
1863
+ return write();
2101
1864
  } finally {
2102
- OIMContentChangeDeliveryService.INSTANCE.closeContentSubframe(channelSlot);
1865
+ contentChangeDeliveryService.closeBatch(storeSlot);
2103
1866
  }
2104
1867
  }
2105
- insertEntity(storeSlot, key, entity, changedEntitySlots) {
1868
+ onSlotMinted(_storeSlot, _slot) {
1869
+ return;
1870
+ }
1871
+ mintSlotByKey(storeSlot, key) {
1872
+ const slotOwnerService = this.slotOwnerService;
1873
+ const slot = this.keyedSlotCreator.createSlot(this.slotStoreService.ownKey(key), storeSlot, slotOwnerService);
1874
+ this.onSlotMinted(storeSlot, slot);
1875
+ slotOwnerService.settleEmptiness(slot, slotOwnerService.isSlotEmpty(slot));
1876
+ slotOwnerService.fileSlot(slot);
1877
+ return slot;
1878
+ }
1879
+ };
1880
+
1881
+ // src/facade/slot/OIMWritableSlotCollectionService.ts
1882
+ var OIMWritableSlotCollectionService = class extends OIMSlotCollectionService {
1883
+ writeSlotContentByKey(storeSlot, key, content, changedSlots) {
2106
1884
  const filed = this.slotStoreService.get(storeSlot.store, key);
2107
1885
  if (filed !== void 0) {
2108
- const landedOnFiled = this.writeEntity(filed, entity);
2109
- if (landedOnFiled && changedEntitySlots !== void 0) changedEntitySlots.push(filed);
1886
+ if (this.slotContentService.writeSlotContent(filed, content) && changedSlots !== void 0) changedSlots.push(filed);
2110
1887
  return filed;
2111
1888
  }
2112
- const entitySlot = this.slotOwnerService.createSlot(this.slotStoreService.ownKey(key), storeSlot);
2113
- if (this.isOnFastPath(entitySlot)) return this.insertEntityOnFastPath(storeSlot, entitySlot, entity, changedEntitySlots);
2114
- return this.insertEntityInSubframe(storeSlot, entitySlot, entity, changedEntitySlots);
1889
+ const slot = this.slotContentService.createSlot(this.slotStoreService.ownKey(key), storeSlot, this.slotOwnerService);
1890
+ this.slotContentService.insertSlotContent(slot, content, changedSlots);
1891
+ return slot;
1892
+ }
1893
+ };
1894
+
1895
+ // src/facade/slot/OIMSingleSlotService.ts
1896
+ var OIMSingleSlotService = class {
1897
+ constructor(options) {
1898
+ const slotOwnerService = new OIMSlotOwnerService({ ...options, slotFilingService: options.slotStoreService });
1899
+ this.slotOwnerService = slotOwnerService;
1900
+ this.columnSlotService = new OIMColumnSlotService(slotOwnerService.columnSlotOwner);
1901
+ this.slotStoreService = options.slotStoreService;
1902
+ this.singleSlotCreator = options.slotContentService;
1903
+ this.slotContentService = options.slotContentService;
1904
+ this.storeSlotListener = options.storeSlotListener;
2115
1905
  }
2116
- insertEntities(storeSlot, entities) {
2117
- this.fillEntitiesUnderKeys(storeSlot, void 0, entities);
1906
+ get slotOwner() {
1907
+ return this.slotOwnerService;
2118
1908
  }
2119
- fillEntities(storeSlot, keys, entities) {
2120
- if (keys.length !== entities.length) {
2121
- throw oimFillEntitiesLengthMismatchError("OIMSlotContentEntityService", keys.length, entities.length);
2122
- }
2123
- if (this.slotStoreService.getSlotCount(storeSlot.store) !== 0) throw oimFillEntitiesIntoFilledCollectionError("OIMSlotContentEntityService");
2124
- this.fillEntitiesUnderKeys(storeSlot, keys, entities);
1909
+ createStoreSlot(channelMap) {
1910
+ const storeSlot = createOIMStoreSlot(
1911
+ this.slotStoreService.createStore(),
1912
+ channelMap.defaultChannelSlot,
1913
+ this
1914
+ );
1915
+ if (this.storeSlotListener !== void 0) this.storeSlotListener.onStoreSlotCreated(storeSlot);
1916
+ return storeSlot;
2125
1917
  }
2126
- fillEntitiesUnderKeys(storeSlot, keys, entities) {
2127
- const channelSlot = storeSlot.channelSlot;
2128
- OIMContentChangeDeliveryService.INSTANCE.openContentSubframe(channelSlot);
2129
- try {
2130
- const filedCount = this.fillEachEntity(storeSlot, keys, entities);
2131
- if (filedCount === entities.length) return;
2132
- const slotOwnerService = this.slotOwnerService;
2133
- for (let i = 0; i < filedCount; i++) {
2134
- const entitySlot = this.slotStoreService.get(storeSlot.store, keys === void 0 ? this.keyOf(entities[i]) : keys[i]);
2135
- if (entitySlot === void 0) continue;
2136
- slotOwnerService.assertWritable(entitySlot);
2137
- this.clearSlotContent(entitySlot);
2138
- }
2139
- throw oimFillEntitiesKeyNamedTwiceError("OIMSlotContentEntityService");
2140
- } finally {
2141
- OIMContentChangeDeliveryService.INSTANCE.closeContentSubframe(channelSlot);
2142
- }
1918
+ findSingleSlot(storeSlot) {
1919
+ return this.slotStoreService.getSingleSlot(storeSlot.store);
2143
1920
  }
2144
- clearAllEntities(storeSlot) {
2145
- const slotOwnerService = this.slotOwnerService;
2146
- const channelSlot = storeSlot.channelSlot;
2147
- OIMContentChangeDeliveryService.INSTANCE.openContentSubframe(channelSlot);
2148
- try {
2149
- for (const entitySlot of this.slotStoreService.getSlots(storeSlot.store)) {
2150
- slotOwnerService.assertWritable(entitySlot);
2151
- this.clearSlotContent(entitySlot);
2152
- }
2153
- } finally {
2154
- OIMContentChangeDeliveryService.INSTANCE.closeContentSubframe(channelSlot);
2155
- }
1921
+ hasSingleSlotContent(storeSlot) {
1922
+ const slot = this.slotStoreService.getSingleSlot(storeSlot.store);
1923
+ return slot !== void 0 && !oimIsSlotEmpty(slot);
1924
+ }
1925
+ getSingleSlot(storeSlot) {
1926
+ const found = this.slotStoreService.getSingleSlot(storeSlot.store);
1927
+ if (found !== void 0) return found;
1928
+ const slot = this.mintSingleSlot(storeSlot);
1929
+ OIMUnusedSlotCollectorService.INSTANCE.holdSlotUntilFlush(storeSlot.channelSlot.collectorSlot.unusedSlotCollectorSlot, slot);
1930
+ return slot;
1931
+ }
1932
+ holdSingleSlot(storeSlot) {
1933
+ const slot = this.slotStoreService.getSingleSlot(storeSlot.store) ?? this.mintSingleSlot(storeSlot);
1934
+ this.slotOwnerService.holdSlot(slot);
1935
+ return slot;
2156
1936
  }
2157
- fillEachEntity(storeSlot, keys, entities) {
2158
- const slotStoreService = this.slotStoreService;
1937
+ mintSingleSlot(storeSlot) {
2159
1938
  const slotOwnerService = this.slotOwnerService;
2160
- const store = storeSlot.store;
2161
- const isStoreEmptyAtStart = slotStoreService.getSlotCount(store) === 0;
2162
- const filedEntitySlots = isStoreEmptyAtStart ? [] : void 0;
2163
- let i = 0;
2164
- let filingEntitySlot;
2165
- try {
2166
- for (; i < entities.length; i++) {
2167
- filingEntitySlot = void 0;
2168
- const key = keys === void 0 ? this.keyOf(entities[i]) : keys[i];
2169
- if (filedEntitySlots === void 0 && slotStoreService.get(store, key) !== void 0) return i;
2170
- const entitySlot = slotOwnerService.createSlot(slotStoreService.ownKey(key), storeSlot);
2171
- slotOwnerService.assertWritable(entitySlot);
2172
- slotOwnerService.fileSlot(storeSlot, entitySlot);
2173
- if (filedEntitySlots !== void 0) {
2174
- if (slotStoreService.getSlotCount(store) === filedEntitySlots.length) {
2175
- this.refileRepeatedKey(storeSlot, filedEntitySlots, entitySlot);
2176
- return i;
2177
- }
2178
- filedEntitySlots.push(entitySlot);
2179
- }
2180
- filingEntitySlot = entitySlot;
2181
- this.fillSlotContent(entitySlot, entities[i]);
2182
- if (oimIsSlotEmpty(entitySlot)) slotOwnerService.releaseSlotIfUnheld(entitySlot);
2183
- else slotOwnerService.releaseWrittenSlotIfUnheld(entitySlot);
2184
- }
2185
- } catch (refusal) {
2186
- for (let j = 0; j < i; j++) {
2187
- const entitySlot = slotStoreService.get(store, keys === void 0 ? this.keyOf(entities[j]) : keys[j]);
2188
- if (entitySlot !== void 0) slotOwnerService.releaseSlotIfUnheld(entitySlot);
2189
- }
2190
- if (filingEntitySlot !== void 0) slotOwnerService.releaseSlotIfUnheld(filingEntitySlot);
2191
- throw refusal;
1939
+ const slot = this.singleSlotCreator.createSingleSlot(storeSlot, slotOwnerService);
1940
+ slotOwnerService.settleEmptiness(slot, slotOwnerService.isSlotEmpty(slot));
1941
+ slotOwnerService.fileSlot(slot);
1942
+ return slot;
1943
+ }
1944
+ };
1945
+
1946
+ // src/facade/slot/OIMWritableSingleSlotService.ts
1947
+ var OIMWritableSingleSlotService = class extends OIMSingleSlotService {
1948
+ writeSingleSlotContent(storeSlot, content, changedSlots) {
1949
+ const filed = this.slotStoreService.getSingleSlot(storeSlot.store);
1950
+ if (filed !== void 0) {
1951
+ if (this.slotContentService.writeSlotContent(filed, content) && changedSlots !== void 0) changedSlots.push(filed);
1952
+ return filed;
2192
1953
  }
2193
- return entities.length;
1954
+ const slot = this.slotContentService.createSingleSlot(storeSlot, this.slotOwnerService);
1955
+ this.slotContentService.insertSlotContent(slot, content, changedSlots);
1956
+ return slot;
1957
+ }
1958
+ clearSingleSlotContent(storeSlot) {
1959
+ const slot = this.slotStoreService.getSingleSlot(storeSlot.store);
1960
+ if (slot !== void 0) this.slotContentService.clearSlotContent(slot);
1961
+ }
1962
+ };
1963
+
1964
+ // src/engine/entity/OIMSlotEntityPresenceEmptinessPolicy.ts
1965
+ var _OIMSlotEntityPresenceEmptinessPolicy = class _OIMSlotEntityPresenceEmptinessPolicy {
1966
+ isEmpty(entitySlot) {
1967
+ return entitySlot.entity === void 0;
1968
+ }
1969
+ };
1970
+ _OIMSlotEntityPresenceEmptinessPolicy.INSTANCE = new _OIMSlotEntityPresenceEmptinessPolicy();
1971
+ var OIMSlotEntityPresenceEmptinessPolicy = _OIMSlotEntityPresenceEmptinessPolicy;
1972
+
1973
+ // src/engine/entity/utils/createOIMEntitySlot.ts
1974
+ function createOIMEntitySlot(key, owner, storeSlot = void 0) {
1975
+ return {
1976
+ effects: void 0,
1977
+ changedAtRevision: 0,
1978
+ changedAtEpoch: 0,
1979
+ effectEdges: void 0,
1980
+ holdCount: 0,
1981
+ releaseDueAfterWriteMs: -1,
1982
+ releaseDueAfterIdleMs: -1,
1983
+ releaseDueAfterUnholdMs: -1,
1984
+ slotFlags: OIM_SLOT_FLAG_EMPTY,
1985
+ owner,
1986
+ key,
1987
+ entity: void 0,
1988
+ columnSlotStore: void 0,
1989
+ storeSlot,
1990
+ data: void 0,
1991
+ indexKeys: void 0
1992
+ };
1993
+ }
1994
+
1995
+ // src/engine/entity/utils/createOIMSingleEntitySlot.ts
1996
+ function createOIMSingleEntitySlot(owner, storeSlot) {
1997
+ const singleEntitySlot = {
1998
+ effects: void 0,
1999
+ changedAtRevision: 0,
2000
+ changedAtEpoch: 0,
2001
+ effectEdges: void 0,
2002
+ holdCount: 0,
2003
+ releaseDueAfterWriteMs: -1,
2004
+ releaseDueAfterIdleMs: -1,
2005
+ releaseDueAfterUnholdMs: -1,
2006
+ slotFlags: OIM_SLOT_FLAG_EMPTY,
2007
+ owner,
2008
+ key: void 0,
2009
+ entity: void 0,
2010
+ columnSlotStore: void 0,
2011
+ storeSlot,
2012
+ data: void 0,
2013
+ indexKeys: void 0
2014
+ };
2015
+ return singleEntitySlot;
2016
+ }
2017
+
2018
+ // src/engine/entity/OIMSlotContentEntityService.ts
2019
+ var OIMSlotContentEntityService = class {
2020
+ constructor(options) {
2021
+ this.entityWriter = options.entityWriter;
2022
+ this.slotEmptinessPolicy = options.slotEmptinessPolicy;
2023
+ this.isSlotEmptinessCustom = options.slotEmptinessPolicy !== OIMSlotEntityPresenceEmptinessPolicy.INSTANCE;
2024
+ }
2025
+ createSlot(key, storeSlot, slotOwner) {
2026
+ return createOIMEntitySlot(key, slotOwner, storeSlot);
2027
+ }
2028
+ createSingleSlot(storeSlot, slotOwner) {
2029
+ return createOIMSingleEntitySlot(slotOwner, storeSlot);
2194
2030
  }
2195
- refileRepeatedKey(storeSlot, filedEntitySlots, repeatingEntitySlot) {
2196
- const slotStoreService = this.slotStoreService;
2197
- for (let j = 0; j < filedEntitySlots.length; j++) {
2198
- const filedEntitySlot = filedEntitySlots[j];
2199
- if (!slotStoreService.isSameKey(filedEntitySlot.key, repeatingEntitySlot.key)) continue;
2200
- this.slotOwnerService.fileSlot(storeSlot, filedEntitySlot);
2031
+ isSlotEmpty(entitySlot) {
2032
+ return this.slotEmptinessPolicy.isEmpty(entitySlot);
2033
+ }
2034
+ hasReference() {
2035
+ return false;
2036
+ }
2037
+ updatesEmptinessOnColumnWriteOf(entitySlot) {
2038
+ return this.isSlotEmptinessCustom || this.slotOwnerServiceOf(entitySlot).settlesWrittenSlots;
2039
+ }
2040
+ slotOwnerServiceOf(entitySlot) {
2041
+ return entitySlot.owner;
2042
+ }
2043
+ insertSlotContent(entitySlot, entity, changedEntitySlots) {
2044
+ if (this.isOnFastPath(entitySlot)) {
2045
+ this.insertEntityOnFastPath(entitySlot, entity, changedEntitySlots);
2201
2046
  return;
2202
2047
  }
2048
+ this.insertEntityOffFastPath(entitySlot, entity, changedEntitySlots);
2203
2049
  }
2204
- insertEntityOnFastPath(storeSlot, entitySlot, entity, changedEntitySlots) {
2205
- const slotOwnerService = this.slotOwnerService;
2050
+ insertEntityOnFastPath(entitySlot, entity, changedEntitySlots) {
2051
+ const slotOwnerService = this.slotOwnerServiceOf(entitySlot);
2206
2052
  try {
2207
2053
  slotOwnerService.assertWritable(entitySlot);
2208
2054
  this.entityWriter.fillEntity(entitySlot, entity);
2209
2055
  this.updateEntitySlotEmptiness(entitySlot);
2210
- slotOwnerService.fileSlot(storeSlot, entitySlot);
2211
- const channelSlot = storeSlot.channelSlot;
2056
+ slotOwnerService.fileSlot(entitySlot);
2057
+ const channelSlot = oimGetChannelSlot(entitySlot);
2212
2058
  if (oimIsSlotEmpty(entitySlot)) OIMUnusedSlotCollectorService.INSTANCE.holdSlotUntilFlush(channelSlot.collectorSlot.unusedSlotCollectorSlot, entitySlot);
2213
2059
  OIMChannelService.INSTANCE.writeWithoutFlushCheck(channelSlot, entitySlot);
2214
2060
  } catch (refusal) {
@@ -2216,170 +2062,137 @@ var OIMSlotContentEntityService = class {
2216
2062
  throw refusal;
2217
2063
  }
2218
2064
  if (changedEntitySlots !== void 0) changedEntitySlots.push(entitySlot);
2219
- return entitySlot;
2220
2065
  }
2221
- insertEntityInSubframe(storeSlot, entitySlot, entity, changedEntitySlots) {
2222
- const slotOwnerService = this.slotOwnerService;
2223
- let isAnnounced = false;
2224
- const channelSlot = storeSlot.channelSlot;
2225
- OIMContentChangeDeliveryService.INSTANCE.openContentSubframe(channelSlot);
2066
+ insertEntityOffFastPath(entitySlot, entity, changedEntitySlots) {
2067
+ const slotOwnerService = this.slotOwnerServiceOf(entitySlot);
2068
+ let isLanded;
2226
2069
  try {
2227
2070
  slotOwnerService.assertWritable(entitySlot);
2228
- isAnnounced = this.fillSlotContent(entitySlot, entity);
2229
- slotOwnerService.fileSlot(storeSlot, entitySlot);
2230
- if (oimIsSlotEmpty(entitySlot)) OIMUnusedSlotCollectorService.INSTANCE.holdSlotUntilFlush(channelSlot.collectorSlot.unusedSlotCollectorSlot, entitySlot);
2231
- else slotOwnerService.releaseWrittenSlotIfUnheld(entitySlot);
2071
+ isLanded = this.writeEntityToSlot(entitySlot, entity, void 0);
2072
+ this.updateEntitySlotEmptiness(entitySlot);
2073
+ slotOwnerService.fileSlot(entitySlot);
2232
2074
  } catch (refusal) {
2233
- this.withdrawSlotContent(entitySlot, isAnnounced);
2234
- OIMContentChangeDeliveryService.INSTANCE.closeContentSubframe(channelSlot);
2075
+ slotOwnerService.releaseSlotIfUnheld(entitySlot);
2235
2076
  throw refusal;
2236
2077
  }
2237
- try {
2238
- OIMContentChangeDeliveryService.INSTANCE.closeContentSubframe(channelSlot);
2239
- } catch (refusal) {
2240
- this.withdrawSlotContent(entitySlot, isAnnounced);
2241
- throw refusal;
2078
+ if (oimIsSlotEmpty(entitySlot)) {
2079
+ const unusedSlotCollectorSlot = oimGetChannelSlot(entitySlot).collectorSlot.unusedSlotCollectorSlot;
2080
+ OIMUnusedSlotCollectorService.INSTANCE.holdSlotUntilFlush(unusedSlotCollectorSlot, entitySlot);
2242
2081
  }
2243
- if (isAnnounced && changedEntitySlots !== void 0) changedEntitySlots.push(entitySlot);
2244
- return entitySlot;
2082
+ if (!isLanded) return;
2083
+ slotOwnerService.dispatchContentChange(entitySlot, entity);
2084
+ if (!oimIsSlotEmpty(entitySlot)) slotOwnerService.releaseWrittenSlotIfUnheld(entitySlot);
2085
+ if (changedEntitySlots !== void 0) changedEntitySlots.push(entitySlot);
2245
2086
  }
2246
- writeEntity(entitySlot, entity) {
2247
- const slotOwnerService = this.slotOwnerService;
2087
+ writeSlotContent(entitySlot, entity) {
2088
+ const slotOwnerService = this.slotOwnerServiceOf(entitySlot);
2248
2089
  slotOwnerService.assertWritable(entitySlot);
2249
2090
  if (entitySlot.entity !== void 0 && this.isOnFastPath(entitySlot)) {
2250
2091
  if (!this.entityWriter.putEntity(entitySlot, entity, void 0)) return false;
2251
2092
  this.writeSlotToChannelAndReleaseIfUnheld(entitySlot);
2252
2093
  return true;
2253
2094
  }
2254
- if (entitySlot.entity !== void 0 && !this.updatesEmptinessOnColumnWrite) {
2095
+ if (entitySlot.entity !== void 0 && !this.updatesEmptinessOnColumnWriteOf(entitySlot)) {
2255
2096
  const channelSlot2 = oimGetChannelSlot(entitySlot);
2256
- const changedColumnNames = slotOwnerService.takeChangedColumnNames(channelSlot2);
2257
- if (!this.entityWriter.putEntity(entitySlot, entity, changedColumnNames)) return false;
2258
- if (!slotOwnerService.isAnyColumnReferenced(entitySlot, changedColumnNames)) {
2097
+ const changedColumnNames2 = slotOwnerService.takeChangedColumnNames(channelSlot2);
2098
+ if (!this.entityWriter.putEntity(entitySlot, entity, changedColumnNames2)) return false;
2099
+ if (!slotOwnerService.isAnyColumnReferenced(entitySlot, changedColumnNames2)) {
2259
2100
  this.writeSlotToChannelAndReleaseIfUnheld(entitySlot);
2260
2101
  return true;
2261
2102
  }
2103
+ this.dispatchColumnsChanged(entitySlot, void 0, changedColumnNames2);
2262
2104
  if (!slotOwnerService.hasContentChangeListeners(entitySlot)) {
2263
- OIMContentChangeDeliveryService.INSTANCE.openContentSubframe(channelSlot2);
2264
- try {
2265
- this.dispatchColumnsChanged(entitySlot, void 0, changedColumnNames);
2266
- } finally {
2267
- OIMContentChangeDeliveryService.INSTANCE.closeContentSubframe(channelSlot2);
2268
- }
2269
2105
  slotOwnerService.releaseWrittenSlotIfUnheld(entitySlot);
2270
2106
  return true;
2271
2107
  }
2272
- OIMContentChangeDeliveryService.INSTANCE.openContentSubframe(channelSlot2);
2273
- try {
2274
- this.dispatchColumnsChanged(entitySlot, void 0, changedColumnNames);
2275
- this.dispatchContentChangeAndReleaseIfUnheld(entitySlot, entity, changedColumnNames);
2276
- } finally {
2277
- OIMContentChangeDeliveryService.INSTANCE.closeContentSubframe(channelSlot2);
2278
- }
2108
+ this.dispatchContentChangeAndReleaseIfUnheld(entitySlot, entity, changedColumnNames2);
2279
2109
  return true;
2280
2110
  }
2281
2111
  const channelSlot = oimGetChannelSlot(entitySlot);
2282
- OIMContentChangeDeliveryService.INSTANCE.openContentSubframe(channelSlot);
2283
- try {
2284
- const wasEmpty = oimIsSlotEmpty(entitySlot);
2285
- const changedColumnNames = this.hasChangedColumnReaders(entitySlot) ? slotOwnerService.takeChangedColumnNames(channelSlot) : void 0;
2286
- const landed = this.writeEntityWithoutSubframe(entitySlot, entity, changedColumnNames);
2287
- if (landed) {
2288
- this.updateEntitySlotEmptiness(entitySlot);
2289
- this.dispatchContentChangeAndReleaseIfUnheld(entitySlot, entity, wasEmpty ? void 0 : changedColumnNames);
2290
- }
2291
- return landed;
2292
- } finally {
2293
- OIMContentChangeDeliveryService.INSTANCE.closeContentSubframe(channelSlot);
2112
+ const wasEmpty = oimIsSlotEmpty(entitySlot);
2113
+ const changedColumnNames = this.hasChangedColumnReaders(entitySlot) ? slotOwnerService.takeChangedColumnNames(channelSlot) : void 0;
2114
+ const isLanded = this.writeEntityToSlot(entitySlot, entity, changedColumnNames);
2115
+ if (isLanded) {
2116
+ this.updateEntitySlotEmptiness(entitySlot);
2117
+ this.dispatchContentChangeAndReleaseIfUnheld(entitySlot, entity, wasEmpty ? void 0 : changedColumnNames);
2294
2118
  }
2119
+ return isLanded;
2295
2120
  }
2296
2121
  updateEntity(entitySlot, patch) {
2297
- this.slotOwnerService.assertWritable(entitySlot);
2298
- if (!this.isOnFastPath(entitySlot)) return this.updateEntityInSubframe(entitySlot, patch);
2122
+ this.slotOwnerServiceOf(entitySlot).assertWritable(entitySlot);
2123
+ if (!this.isOnFastPath(entitySlot)) return this.updateEntityOffFastPath(entitySlot, patch);
2299
2124
  if (!this.entityWriter.patchEntity(entitySlot, patch, void 0)) return entitySlot;
2300
2125
  this.writeSlotToChannelAndReleaseIfUnheld(entitySlot);
2301
2126
  return entitySlot;
2302
2127
  }
2303
2128
  updateEntityColumn(entitySlot, columnName, value) {
2304
- this.slotOwnerService.assertWritable(entitySlot);
2129
+ this.slotOwnerServiceOf(entitySlot).assertWritable(entitySlot);
2305
2130
  if (!this.isOnFastPath(entitySlot)) return this.updateEntityColumnOffFastPath(entitySlot, columnName, value);
2306
2131
  if (!this.entityWriter.patchColumn(entitySlot, columnName, value, void 0)) return entitySlot;
2307
2132
  this.writeSlotToChannelAndReleaseIfUnheld(entitySlot);
2308
2133
  return entitySlot;
2309
2134
  }
2310
2135
  deleteEntityColumns(entitySlot, columnNames) {
2311
- this.slotOwnerService.assertWritable(entitySlot);
2312
- const channelSlot = oimGetChannelSlot(entitySlot);
2313
- OIMContentChangeDeliveryService.INSTANCE.openContentSubframe(channelSlot);
2314
- try {
2315
- const deletedColumnNames = this.entityWriter.deleteColumns(entitySlot, columnNames);
2316
- if (deletedColumnNames.length !== 0) {
2317
- this.dispatchColumnsChanged(entitySlot, void 0, deletedColumnNames);
2318
- this.updateEntitySlotEmptiness(entitySlot);
2319
- this.dispatchContentChangeAndReleaseIfUnheld(entitySlot, void 0, deletedColumnNames);
2320
- }
2321
- } finally {
2322
- OIMContentChangeDeliveryService.INSTANCE.closeContentSubframe(channelSlot);
2136
+ this.slotOwnerServiceOf(entitySlot).assertWritable(entitySlot);
2137
+ const deletedColumnNames = this.entityWriter.deleteColumns(entitySlot, columnNames);
2138
+ if (deletedColumnNames.length !== 0) {
2139
+ this.dispatchColumnsChanged(entitySlot, void 0, deletedColumnNames);
2140
+ this.updateEntitySlotEmptiness(entitySlot);
2141
+ this.dispatchContentChangeAndReleaseIfUnheld(entitySlot, void 0, deletedColumnNames);
2323
2142
  }
2324
2143
  return entitySlot;
2325
2144
  }
2326
2145
  markEntityChanged(entitySlot, changedColumns) {
2327
- const slotOwnerService = this.slotOwnerService;
2146
+ const slotOwnerService = this.slotOwnerServiceOf(entitySlot);
2328
2147
  slotOwnerService.assertWritable(entitySlot);
2329
2148
  if (changedColumns !== void 0 && changedColumns.length === 0) return;
2330
- if (changedColumns !== void 0 && !this.updatesEmptinessOnColumnWrite && entitySlot.entity !== void 0 && !slotOwnerService.isAnyColumnReferenced(entitySlot, changedColumns)) {
2149
+ if (changedColumns !== void 0 && !this.updatesEmptinessOnColumnWriteOf(entitySlot) && entitySlot.entity !== void 0 && !slotOwnerService.isAnyColumnReferenced(entitySlot, changedColumns)) {
2331
2150
  this.writeSlotToChannelAndReleaseIfUnheld(entitySlot);
2332
2151
  return;
2333
2152
  }
2334
2153
  const channelSlot = oimGetChannelSlot(entitySlot);
2335
- OIMContentChangeDeliveryService.INSTANCE.openContentSubframe(channelSlot);
2336
- try {
2337
- const hasColumnSlots = slotOwnerService.hasColumnSlots(entitySlot);
2338
- const isObserved = changedColumns === void 0 || !hasColumnSlots || slotOwnerService.isAnyColumnReferenced(entitySlot, changedColumns);
2339
- if (hasColumnSlots && isObserved) {
2340
- slotOwnerService.columnOwner.markColumnsChanged(entitySlot, void 0, changedColumns, channelSlot);
2341
- }
2342
- OIMChannelService.INSTANCE.writeWithoutFlushCheck(channelSlot, entitySlot);
2343
- if (this.updatesEmptinessOnColumnWrite || changedColumns === void 0 || entitySlot.entity === void 0) {
2344
- this.updateEntitySlotEmptiness(entitySlot);
2345
- }
2346
- if (isObserved) slotOwnerService.dispatchContentChange(entitySlot, void 0, changedColumns);
2347
- slotOwnerService.releaseSlotIfUnheldAfterListeners(entitySlot);
2348
- } finally {
2349
- OIMContentChangeDeliveryService.INSTANCE.closeContentSubframe(channelSlot);
2154
+ const hasColumnSlots = slotOwnerService.hasColumnSlots(entitySlot);
2155
+ const isObserved = changedColumns === void 0 || !hasColumnSlots || slotOwnerService.isAnyColumnReferenced(entitySlot, changedColumns);
2156
+ if (hasColumnSlots && isObserved) {
2157
+ slotOwnerService.columnSlotOwner.markColumnsChanged(entitySlot, void 0, changedColumns, channelSlot);
2350
2158
  }
2351
- }
2352
- deleteEntity(entitySlot) {
2353
- this.slotOwnerService.assertWritable(entitySlot);
2354
- this.clearSlotContent(entitySlot);
2355
- }
2356
- deleteEntities(storeSlot, entitySlots) {
2357
- const channelSlot = storeSlot.channelSlot;
2358
- OIMContentChangeDeliveryService.INSTANCE.openContentSubframe(channelSlot);
2359
- try {
2360
- for (let i = 0; i < entitySlots.length; i++) this.deleteEntity(entitySlots[i]);
2361
- } finally {
2362
- OIMContentChangeDeliveryService.INSTANCE.closeContentSubframe(channelSlot);
2159
+ OIMChannelService.INSTANCE.writeWithoutFlushCheck(channelSlot, entitySlot);
2160
+ if (this.updatesEmptinessOnColumnWriteOf(entitySlot) || changedColumns === void 0 || entitySlot.entity === void 0) {
2161
+ this.updateEntitySlotEmptiness(entitySlot);
2363
2162
  }
2163
+ if (isObserved) slotOwnerService.dispatchContentChange(entitySlot, void 0, changedColumns);
2164
+ slotOwnerService.releaseSlotIfUnheldAfterListeners(entitySlot);
2364
2165
  }
2365
- updateEntityInSubframe(entitySlot, patch) {
2166
+ clearSlotContent(entitySlot) {
2167
+ const slotOwnerService = this.slotOwnerServiceOf(entitySlot);
2168
+ slotOwnerService.assertWritable(entitySlot);
2366
2169
  const channelSlot = oimGetChannelSlot(entitySlot);
2367
- OIMContentChangeDeliveryService.INSTANCE.openContentSubframe(channelSlot);
2368
- try {
2369
- const changedColumnNames = this.hasChangedColumnReaders(entitySlot) ? this.slotOwnerService.takeChangedColumnNames(channelSlot) : void 0;
2370
- if (this.entityWriter.patchEntity(entitySlot, patch, changedColumnNames)) {
2371
- this.dispatchPatchWritten(entitySlot, patch, changedColumnNames);
2372
- }
2373
- } finally {
2374
- OIMContentChangeDeliveryService.INSTANCE.closeContentSubframe(channelSlot);
2170
+ if (!this.isOnFastPath(entitySlot)) {
2171
+ this.releaseSlotContent(entitySlot);
2172
+ slotOwnerService.settleEmptiness(entitySlot, this.slotEmptinessPolicy.isEmpty(entitySlot));
2173
+ slotOwnerService.dispatchContentChange(entitySlot);
2174
+ slotOwnerService.releaseSlotIfUnheldAfterListeners(entitySlot);
2175
+ return;
2176
+ }
2177
+ if (entitySlot.entity !== void 0) {
2178
+ this.entityWriter.clearEntity(entitySlot);
2179
+ OIMChannelService.INSTANCE.writeWithoutFlushCheck(channelSlot, entitySlot);
2180
+ slotOwnerService.markEmptiness(entitySlot, this.slotEmptinessPolicy.isEmpty(entitySlot));
2181
+ }
2182
+ slotOwnerService.releaseSlotIfUnheld(entitySlot);
2183
+ }
2184
+ updateEntityOffFastPath(entitySlot, patch) {
2185
+ const changedColumnNames = this.hasChangedColumnReaders(entitySlot) ? this.slotOwnerServiceOf(entitySlot).takeChangedColumnNames(oimGetChannelSlot(entitySlot)) : void 0;
2186
+ if (this.entityWriter.patchEntity(entitySlot, patch, changedColumnNames)) {
2187
+ this.dispatchPatchWritten(entitySlot, patch, changedColumnNames);
2375
2188
  }
2376
2189
  return entitySlot;
2377
2190
  }
2378
2191
  updateEntityColumnOffFastPath(entitySlot, columnName, value) {
2379
- if (this.updatesEmptinessOnColumnWrite || entitySlot.entity === void 0) {
2380
- return this.updateEntityColumnInSubframe(entitySlot, columnName, value);
2192
+ if (this.updatesEmptinessOnColumnWriteOf(entitySlot) || entitySlot.entity === void 0) {
2193
+ return this.updateEntityColumnAndDispatch(entitySlot, columnName, value);
2381
2194
  }
2382
- const slotOwnerService = this.slotOwnerService;
2195
+ const slotOwnerService = this.slotOwnerServiceOf(entitySlot);
2383
2196
  const channelSlot = oimGetChannelSlot(entitySlot);
2384
2197
  const columnNames = slotOwnerService.takeChangedColumnNames(channelSlot);
2385
2198
  columnNames.push(columnName);
@@ -2389,105 +2202,51 @@ var OIMSlotContentEntityService = class {
2389
2202
  return entitySlot;
2390
2203
  }
2391
2204
  if (slotOwnerService.hasContentChangeListeners(entitySlot)) {
2392
- return this.updateEntityColumnInSubframe(entitySlot, columnName, value);
2205
+ return this.updateEntityColumnAndDispatch(entitySlot, columnName, value);
2393
2206
  }
2394
2207
  if (!this.entityWriter.patchColumn(entitySlot, columnName, value, void 0)) return entitySlot;
2395
- OIMContentChangeDeliveryService.INSTANCE.openContentSubframe(channelSlot);
2396
- try {
2397
- this.dispatchColumnsChanged(entitySlot, void 0, columnNames);
2398
- } finally {
2399
- OIMContentChangeDeliveryService.INSTANCE.closeContentSubframe(channelSlot);
2400
- }
2208
+ this.dispatchColumnsChanged(entitySlot, void 0, columnNames);
2401
2209
  slotOwnerService.releaseWrittenSlotIfUnheld(entitySlot);
2402
2210
  return entitySlot;
2403
2211
  }
2404
- updateEntityColumnInSubframe(entitySlot, columnName, value) {
2405
- const channelSlot = oimGetChannelSlot(entitySlot);
2406
- OIMContentChangeDeliveryService.INSTANCE.openContentSubframe(channelSlot);
2407
- try {
2408
- const changedColumnNames = this.hasChangedColumnReaders(entitySlot) ? this.slotOwnerService.takeChangedColumnNames(channelSlot) : void 0;
2409
- if (this.entityWriter.patchColumn(entitySlot, columnName, value, changedColumnNames)) {
2410
- this.dispatchPatchWritten(entitySlot, void 0, changedColumnNames);
2411
- }
2412
- } finally {
2413
- OIMContentChangeDeliveryService.INSTANCE.closeContentSubframe(channelSlot);
2212
+ updateEntityColumnAndDispatch(entitySlot, columnName, value) {
2213
+ const changedColumnNames = this.hasChangedColumnReaders(entitySlot) ? this.slotOwnerServiceOf(entitySlot).takeChangedColumnNames(oimGetChannelSlot(entitySlot)) : void 0;
2214
+ if (this.entityWriter.patchColumn(entitySlot, columnName, value, changedColumnNames)) {
2215
+ this.dispatchPatchWritten(entitySlot, void 0, changedColumnNames);
2414
2216
  }
2415
2217
  return entitySlot;
2416
2218
  }
2417
2219
  dispatchPatchWritten(entitySlot, patch, changedColumnNames) {
2418
2220
  this.dispatchColumnsChanged(entitySlot, void 0, changedColumnNames);
2419
- if (this.updatesEmptinessOnColumnWrite) this.updateEntitySlotEmptiness(entitySlot);
2221
+ if (this.updatesEmptinessOnColumnWriteOf(entitySlot)) this.updateEntitySlotEmptiness(entitySlot);
2420
2222
  this.dispatchContentChangeAndReleaseIfUnheld(entitySlot, patch, changedColumnNames);
2421
2223
  }
2422
2224
  writeSlotToChannelAndReleaseIfUnheld(entitySlot) {
2423
2225
  OIMChannelService.INSTANCE.writeWithoutFlushCheck(oimGetChannelSlot(entitySlot), entitySlot);
2424
- this.slotOwnerService.releaseWrittenSlotIfUnheld(entitySlot);
2226
+ this.slotOwnerServiceOf(entitySlot).releaseWrittenSlotIfUnheld(entitySlot);
2425
2227
  }
2426
2228
  dispatchContentChangeAndReleaseIfUnheld(entitySlot, patch, changedColumnNames) {
2427
- const slotOwnerService = this.slotOwnerService;
2229
+ const slotOwnerService = this.slotOwnerServiceOf(entitySlot);
2428
2230
  slotOwnerService.dispatchContentChange(entitySlot, patch, changedColumnNames);
2429
2231
  slotOwnerService.releaseSlotIfUnheldAfterListeners(entitySlot);
2430
2232
  }
2431
2233
  releaseSlotContent(entitySlot) {
2432
2234
  const entity = entitySlot.entity;
2433
2235
  if (entity === void 0) return;
2434
- const channelSlot = oimGetChannelSlot(entitySlot);
2435
- OIMContentChangeDeliveryService.INSTANCE.openContentSubframe(channelSlot);
2436
- try {
2437
- this.entityWriter.clearEntity(entitySlot);
2438
- this.dispatchColumnsChanged(entitySlot, entity, void 0);
2439
- } finally {
2440
- OIMContentChangeDeliveryService.INSTANCE.closeContentSubframe(channelSlot);
2441
- }
2442
- }
2443
- fillSlotContent(entitySlot, entity) {
2444
- const slotOwnerService = this.slotOwnerService;
2445
- const landed = this.writeEntityWithoutSubframe(entitySlot, entity, void 0);
2446
- slotOwnerService.settleEmptiness(entitySlot, this.slotEmptiness.isEmpty(entitySlot));
2447
- if (landed) slotOwnerService.dispatchContentChange(entitySlot, entity);
2448
- return landed;
2449
- }
2450
- withdrawSlotContent(entitySlot, isAnnounced) {
2451
- const slotOwnerService = this.slotOwnerService;
2452
- if (isAnnounced) {
2453
- this.releaseSlotContent(entitySlot);
2454
- slotOwnerService.markEmptiness(entitySlot, this.slotEmptiness.isEmpty(entitySlot));
2455
- slotOwnerService.dispatchContentChange(entitySlot);
2456
- }
2457
- slotOwnerService.releaseSlotIfUnheld(entitySlot);
2458
- }
2459
- clearSlotContent(entitySlot) {
2460
- const slotOwnerService = this.slotOwnerService;
2461
- const channelSlot = oimGetChannelSlot(entitySlot);
2462
- if (!this.isOnFastPath(entitySlot)) {
2463
- OIMContentChangeDeliveryService.INSTANCE.openContentSubframe(channelSlot);
2464
- try {
2465
- this.releaseSlotContent(entitySlot);
2466
- slotOwnerService.settleEmptiness(entitySlot, this.slotEmptiness.isEmpty(entitySlot));
2467
- slotOwnerService.dispatchContentChange(entitySlot);
2468
- slotOwnerService.releaseSlotIfUnheldAfterListeners(entitySlot);
2469
- } finally {
2470
- OIMContentChangeDeliveryService.INSTANCE.closeContentSubframe(channelSlot);
2471
- }
2472
- return;
2473
- }
2474
- if (entitySlot.entity !== void 0) {
2475
- this.entityWriter.clearEntity(entitySlot);
2476
- OIMChannelService.INSTANCE.writeWithoutFlushCheck(channelSlot, entitySlot);
2477
- slotOwnerService.markEmptiness(entitySlot, this.slotEmptiness.isEmpty(entitySlot));
2478
- }
2479
- slotOwnerService.releaseSlotIfUnheld(entitySlot);
2236
+ this.slotOwnerServiceOf(entitySlot).assertWritable(entitySlot);
2237
+ this.entityWriter.clearEntity(entitySlot);
2238
+ this.dispatchColumnsChanged(entitySlot, entity, void 0);
2480
2239
  }
2481
2240
  isOnFastPath(entitySlot) {
2482
- return !this.updatesEmptinessOnColumnWrite && !this.hasChangedColumnReaders(entitySlot);
2241
+ return !this.updatesEmptinessOnColumnWriteOf(entitySlot) && !this.hasChangedColumnReaders(entitySlot);
2483
2242
  }
2484
2243
  hasChangedColumnReaders(entitySlot) {
2485
- return entitySlot.columnSlotStore !== void 0 || this.slotOwnerService.hasContentChangeListeners(entitySlot);
2244
+ return entitySlot.columnSlotStore !== void 0 || this.slotOwnerServiceOf(entitySlot).hasContentChangeListeners(entitySlot);
2486
2245
  }
2487
2246
  updateEntitySlotEmptiness(entitySlot) {
2488
- this.slotOwnerService.settleEmptiness(entitySlot, this.slotEmptiness.isEmpty(entitySlot));
2247
+ this.slotOwnerServiceOf(entitySlot).settleEmptiness(entitySlot, this.slotEmptinessPolicy.isEmpty(entitySlot));
2489
2248
  }
2490
- writeEntityWithoutSubframe(entitySlot, entity, changedColumnNames) {
2249
+ writeEntityToSlot(entitySlot, entity, changedColumnNames) {
2491
2250
  if (entitySlot.entity === void 0) {
2492
2251
  this.entityWriter.fillEntity(entitySlot, entity);
2493
2252
  this.dispatchColumnsChanged(entitySlot, entitySlot.entity, void 0);
@@ -2500,7 +2259,7 @@ var OIMSlotContentEntityService = class {
2500
2259
  dispatchColumnsChanged(entitySlot, entity, changedColumnNames) {
2501
2260
  const channelSlot = oimGetChannelSlot(entitySlot);
2502
2261
  if (entitySlot.columnSlotStore !== void 0 && (entity !== void 0 || changedColumnNames !== void 0)) {
2503
- this.slotOwnerService.columnOwner.markColumnsChanged(entitySlot, entity, changedColumnNames, channelSlot);
2262
+ this.slotOwnerServiceOf(entitySlot).columnSlotOwner.markColumnsChanged(entitySlot, entity, changedColumnNames, channelSlot);
2504
2263
  }
2505
2264
  OIMChannelService.INSTANCE.writeWithoutFlushCheck(channelSlot, entitySlot);
2506
2265
  }
@@ -2531,33 +2290,52 @@ var OIMDefaultValue = class {
2531
2290
  };
2532
2291
 
2533
2292
  // src/factories/defaults/OIM_DEFAULT_STORE_SLOT_LISTENER.ts
2534
- var OIM_DEFAULT_STORE_SLOT_LISTENER = /* @__PURE__ */ new OIMDefaultValue("STORE_SLOT_LISTENER", () => OIMStoreSlotListenerNone.INSTANCE);
2293
+ var OIM_DEFAULT_STORE_SLOT_LISTENER = /* @__PURE__ */ new OIMDefaultValue("STORE_SLOT_LISTENER", () => OIMNoStoreSlotListener.INSTANCE);
2535
2294
 
2536
- // src/factories/createOIMSlotCollectionService.ts
2537
- function createOIMSlotCollectionService(options) {
2538
- const slotContentService = options.slotContentService;
2539
- return new OIMSlotCollectionService({
2540
- slotOwnerService: slotContentService.slotOwner,
2541
- slotStoreService: slotContentService.slotStoreService,
2542
- slotContentService,
2543
- storeSlotListener: OIM_DEFAULT_STORE_SLOT_LISTENER.getValue()
2544
- });
2545
- }
2295
+ // src/engine/store/OIMSlotMapStoreService.ts
2296
+ var _OIMSlotMapStoreService = class _OIMSlotMapStoreService {
2297
+ createStore() {
2298
+ return /* @__PURE__ */ new Map();
2299
+ }
2300
+ ownKey(key) {
2301
+ return key;
2302
+ }
2303
+ isSameKey(key, otherKey) {
2304
+ return oimSameValueZeroGuard(key, otherKey);
2305
+ }
2306
+ get(store, key) {
2307
+ return store.get(key);
2308
+ }
2309
+ set(store, key, slot) {
2310
+ store.set(key, slot);
2311
+ }
2312
+ remove(store, key) {
2313
+ store.delete(key);
2314
+ }
2315
+ fileSlot(store, slot) {
2316
+ store.set(slot.key, slot);
2317
+ }
2318
+ unfileSlot(store, slot) {
2319
+ store.delete(slot.key);
2320
+ }
2321
+ getSlots(store) {
2322
+ return store.values();
2323
+ }
2324
+ getSlotCount(store) {
2325
+ return store.size;
2326
+ }
2327
+ };
2328
+ _OIMSlotMapStoreService.INSTANCE = new _OIMSlotMapStoreService();
2329
+ var OIMSlotMapStoreService = _OIMSlotMapStoreService;
2546
2330
 
2547
- // src/factories/createOIMSingleSlotService.ts
2548
- function createOIMSingleSlotService(options) {
2549
- const slotContentService = options.slotContentService;
2550
- return new OIMSingleSlotService({
2551
- slotOwnerService: slotContentService.slotOwner,
2552
- slotStoreService: slotContentService.slotStoreService,
2553
- slotContentService,
2554
- storeSlotListener: OIM_DEFAULT_STORE_SLOT_LISTENER.getValue()
2555
- });
2331
+ // src/factories/utils/oimSlotStoreServiceWithDefault.ts
2332
+ function oimSlotStoreServiceWithDefault(slotStoreService) {
2333
+ return slotStoreService ?? OIMSlotMapStoreService.INSTANCE;
2556
2334
  }
2557
2335
 
2558
- // src/engine/column/OIMColumnOwnerPushDriven.ts
2336
+ // src/engine/column/OIMPushColumnSlotOwner.ts
2559
2337
  var hasValueColumn = (value, columnName) => Object.prototype.hasOwnProperty.call(value, columnName) && value[columnName] !== void 0;
2560
- var OIMColumnOwnerPushDriven = class extends OIMColumnOwner {
2338
+ var OIMPushColumnSlotOwner = class extends OIMColumnSlotOwner {
2561
2339
  constructor(options) {
2562
2340
  super(oimColumnSlotStoreServiceOfColumnOwnerOptions(options));
2563
2341
  }
@@ -2642,44 +2420,87 @@ var OIMColumnOwnerPushDriven = class extends OIMColumnOwner {
2642
2420
  }
2643
2421
  };
2644
2422
 
2645
- // src/engine/column/utils/createOIMColumnOwnerPushDriven.ts
2646
- var createOIMColumnOwnerPushDriven = (columnOwnerOptions) => new OIMColumnOwnerPushDriven(columnOwnerOptions);
2423
+ // src/engine/column/utils/createOIMPushColumnSlotOwner.ts
2424
+ var createOIMPushColumnSlotOwner = (columnSlotOwnerOptions) => new OIMPushColumnSlotOwner(columnSlotOwnerOptions);
2425
+
2426
+ // src/factories/defaults/OIM_DEFAULT_COLUMN_SLOT_STORE_SERVICE.ts
2427
+ var OIM_DEFAULT_COLUMN_SLOT_STORE_SERVICE = /* @__PURE__ */ new OIMDefaultValue("COLUMN_SLOT_STORE_SERVICE", () => OIMSlotMapStoreService.INSTANCE);
2428
+
2429
+ // src/engine/column/utils/oimColumnOwnerOptions.ts
2430
+ function oimColumnOwnerOptions(columnSlotOwnerOptions) {
2431
+ return columnSlotOwnerOptions.columnNames !== void 0 ? { columnNames: columnSlotOwnerOptions.columnNames } : { columnSlotStoreService: columnSlotOwnerOptions.columnSlotStoreService };
2432
+ }
2433
+
2434
+ // src/factories/utils/oimColumnOwnerOptionsWithDefault.ts
2435
+ function oimColumnOwnerOptionsWithDefault(columnSlotStoreService, columnNames, defaultColumnSlotStoreService) {
2436
+ return oimColumnOwnerOptions({ columnNames, columnSlotStoreService: columnSlotStoreService ?? defaultColumnSlotStoreService });
2437
+ }
2438
+
2439
+ // src/factories/utils/oimSlotOwnerOptionsWithDefault.ts
2440
+ function oimSlotOwnerOptionsWithDefault(db, options) {
2441
+ return {
2442
+ slotStamp: db.slotStamp,
2443
+ slotReleasePolicy: options.slotReleasePolicy ?? db.slotReleasePolicy,
2444
+ slotSubscriptionListener: options.slotSubscriptionListener,
2445
+ columnSlotOwnerOptions: oimColumnOwnerOptionsWithDefault(
2446
+ options.columnSlotStoreService,
2447
+ options.columnNames,
2448
+ OIM_DEFAULT_COLUMN_SLOT_STORE_SERVICE.getValue()
2449
+ ),
2450
+ createColumnSlotOwner: createOIMPushColumnSlotOwner
2451
+ };
2452
+ }
2453
+
2454
+ // src/factories/createOIMSlotCollectionService.ts
2455
+ function createOIMSlotCollectionService(db, options) {
2456
+ return new OIMWritableSlotCollectionService({
2457
+ ...oimSlotOwnerOptionsWithDefault(db, options),
2458
+ slotStoreService: oimSlotStoreServiceWithDefault(options.slotStoreService),
2459
+ slotContentService: options.slotContentService,
2460
+ storeSlotListener: OIM_DEFAULT_STORE_SLOT_LISTENER.getValue()
2461
+ });
2462
+ }
2463
+
2464
+ // src/engine/slot/constants/OIM_FROZEN_EMPTY_SLOTS.ts
2465
+ var OIM_FROZEN_EMPTY_SLOTS = Object.freeze([]);
2647
2466
 
2648
- // src/engine/store/OIMSlotStoreServiceMapDriven.ts
2649
- var _OIMSlotStoreServiceMapDriven = class _OIMSlotStoreServiceMapDriven {
2467
+ // src/engine/store/OIMSingleSlotStoreService.ts
2468
+ var _OIMSingleSlotStoreService = class _OIMSingleSlotStoreService {
2650
2469
  createStore() {
2651
- return /* @__PURE__ */ new Map();
2652
- }
2653
- ownKey(key) {
2654
- return key;
2655
- }
2656
- isSameKey(key, otherKey) {
2657
- return oimSameValueZeroGuard(key, otherKey);
2470
+ return { slot: void 0 };
2658
2471
  }
2659
- get(store, key) {
2660
- return store.get(key);
2472
+ getSingleSlot(store) {
2473
+ return store.slot;
2661
2474
  }
2662
- set(store, key, slot) {
2663
- store.set(key, slot);
2475
+ fileSlot(store, slot) {
2476
+ store.slot = slot;
2664
2477
  }
2665
- remove(store, key) {
2666
- store.delete(key);
2478
+ unfileSlot(store) {
2479
+ store.slot = void 0;
2667
2480
  }
2668
2481
  getSlots(store) {
2669
- return store.values();
2482
+ const slot = store.slot;
2483
+ return slot === void 0 ? OIM_FROZEN_EMPTY_SLOTS.values() : [slot].values();
2670
2484
  }
2671
2485
  getSlotCount(store) {
2672
- return store.size;
2486
+ return store.slot === void 0 ? 0 : 1;
2673
2487
  }
2674
2488
  };
2675
- _OIMSlotStoreServiceMapDriven.INSTANCE = new _OIMSlotStoreServiceMapDriven();
2676
- var OIMSlotStoreServiceMapDriven = _OIMSlotStoreServiceMapDriven;
2489
+ _OIMSingleSlotStoreService.INSTANCE = new _OIMSingleSlotStoreService();
2490
+ var OIMSingleSlotStoreService = _OIMSingleSlotStoreService;
2677
2491
 
2678
- // src/factories/defaults/OIM_DEFAULT_COLUMN_SLOT_STORE_SERVICE.ts
2679
- var OIM_DEFAULT_COLUMN_SLOT_STORE_SERVICE = /* @__PURE__ */ new OIMDefaultValue("COLUMN_SLOT_STORE_SERVICE", () => OIMSlotStoreServiceMapDriven.INSTANCE);
2492
+ // src/factories/createOIMSingleSlotService.ts
2493
+ function createOIMSingleSlotService(db, options) {
2494
+ return new OIMWritableSingleSlotService({
2495
+ ...oimSlotOwnerOptionsWithDefault(db, options),
2496
+ slotStoreService: OIMSingleSlotStoreService.INSTANCE,
2497
+ slotContentService: options.slotContentService,
2498
+ storeSlotListener: OIM_DEFAULT_STORE_SLOT_LISTENER.getValue()
2499
+ });
2500
+ }
2680
2501
 
2681
2502
  // src/factories/defaults/OIM_DEFAULT_ENTITY_SLOT_EMPTINESS.ts
2682
- var OIM_DEFAULT_ENTITY_SLOT_EMPTINESS = /* @__PURE__ */ new OIMDefaultValue("ENTITY_SLOT_EMPTINESS", () => OIMSlotEmptinessByEntityPresence.INSTANCE);
2503
+ var OIM_DEFAULT_ENTITY_SLOT_EMPTINESS = /* @__PURE__ */ new OIMDefaultValue("ENTITY_SLOT_EMPTINESS", () => OIMSlotEntityPresenceEmptinessPolicy.INSTANCE);
2683
2504
 
2684
2505
  // src/engine/entity/utils/oimClearEntity.ts
2685
2506
  function oimClearEntity(entitySlot) {
@@ -2765,7 +2586,7 @@ function oimPutEntityColumns(slot, entity, sameValueGuard, changedColumnNames, t
2765
2586
  function oimEntityWriterOptionsWithDefault(options) {
2766
2587
  return {
2767
2588
  sameValueGuard: options?.sameValueGuard ?? oimSameValueZeroGuard,
2768
- entityInsertStrategy: options?.entityInsertStrategy ?? oimInsertEntityWithoutCopy,
2589
+ entityInserter: options?.entityInserter ?? oimInsertEntityWithoutCopy,
2769
2590
  putEntityColumns: options?.putEntityColumns ?? oimPutEntityColumns,
2770
2591
  patchEntityColumns: options?.patchEntityColumns ?? oimPatchEntityColumns,
2771
2592
  patchEntityColumn: options?.patchEntityColumn ?? oimPatchEntityColumn
@@ -2784,13 +2605,13 @@ function deleteColumnsInPlace(slot, names) {
2784
2605
  function createOIMEntityWriterInPlace(options) {
2785
2606
  const {
2786
2607
  sameValueGuard,
2787
- entityInsertStrategy,
2608
+ entityInserter,
2788
2609
  putEntityColumns,
2789
2610
  patchEntityColumns,
2790
2611
  patchEntityColumn
2791
2612
  } = oimEntityWriterOptionsWithDefault(options);
2792
2613
  return {
2793
- fillEntity: entityInsertStrategy,
2614
+ fillEntity: entityInserter,
2794
2615
  clearEntity: oimClearEntity,
2795
2616
  putEntity: (slot, entity, changedColumnNames) => putEntityColumns(slot, entity, sameValueGuard, changedColumnNames, theEntityItself) !== void 0,
2796
2617
  patchEntity: (slot, patch, changedColumnNames) => patchEntityColumns(slot, patch, sameValueGuard, changedColumnNames, theEntityItself) !== void 0,
@@ -2802,96 +2623,42 @@ function createOIMEntityWriterInPlace(options) {
2802
2623
  // src/factories/defaults/OIM_DEFAULT_ENTITY_WRITER.ts
2803
2624
  var OIM_DEFAULT_ENTITY_WRITER = /* @__PURE__ */ new OIMDefaultValue("ENTITY_WRITER", () => createOIMEntityWriterInPlace());
2804
2625
 
2805
- // src/engine/column/utils/oimColumnOwnerOptions.ts
2806
- function oimColumnOwnerOptions(columnOwnerOptions) {
2807
- return columnOwnerOptions.columnNames !== void 0 ? { columnNames: columnOwnerOptions.columnNames } : { columnSlotStoreService: columnOwnerOptions.columnSlotStoreService };
2808
- }
2809
-
2810
- // src/factories/utils/oimColumnOwnerOptionsWithDefault.ts
2811
- function oimColumnOwnerOptionsWithDefault(columnSlotStoreService, columnNames, defaultColumnSlotStoreService) {
2812
- return oimColumnOwnerOptions({ columnNames, columnSlotStoreService: columnSlotStoreService ?? defaultColumnSlotStoreService });
2813
- }
2814
-
2815
- // src/factories/utils/oimSlotStoreServiceWithDefault.ts
2816
- function oimSlotStoreServiceWithDefault(slotStoreService) {
2817
- return slotStoreService ?? OIMSlotStoreServiceMapDriven.INSTANCE;
2818
- }
2819
-
2820
2626
  // src/factories/createOIMSlotContentEntityService.ts
2821
- var keyOfNothing = () => void 0;
2822
- function createOIMSlotContentEntityService(db, options) {
2627
+ function createOIMSlotContentEntityService(db, options = {}) {
2823
2628
  return new OIMSlotContentEntityService({
2824
- keyOf: options.keyOf ?? keyOfNothing,
2825
2629
  entityWriter: options.entityWriter ?? db.entityWriter ?? OIM_DEFAULT_ENTITY_WRITER.getValue(),
2826
- slotEmptiness: options.slotEmptiness ?? OIM_DEFAULT_ENTITY_SLOT_EMPTINESS.getValue(),
2827
- slotStoreService: oimSlotStoreServiceWithDefault(options.slotStoreService),
2828
- slotStamp: db.slotStamp,
2829
- slotReleasePolicy: options.slotReleasePolicy ?? db.slotReleasePolicy,
2830
- columnOwnerOptions: oimColumnOwnerOptionsWithDefault(
2831
- options.columnSlotStoreService,
2832
- options.columnNames,
2833
- OIM_DEFAULT_COLUMN_SLOT_STORE_SERVICE.getValue()
2834
- ),
2835
- createColumnOwner: createOIMColumnOwnerPushDriven
2836
- });
2837
- }
2838
-
2839
- // src/factories/createOIMEntityService.ts
2840
- function createOIMEntityService(db, options) {
2841
- return createOIMSlotCollectionService({
2842
- slotContentService: createOIMSlotContentEntityService(db, {
2843
- ...options,
2844
- slotStoreService: oimSlotStoreServiceWithDefault(options.entitySlotStoreService)
2845
- })
2630
+ slotEmptinessPolicy: options.slotEmptinessPolicy ?? OIM_DEFAULT_ENTITY_SLOT_EMPTINESS.getValue()
2846
2631
  });
2847
2632
  }
2848
2633
 
2849
- // src/engine/slot/constants/OIM_FROZEN_EMPTY_SLOTS.ts
2850
- var OIM_FROZEN_EMPTY_SLOTS = Object.freeze([]);
2851
-
2852
- // src/engine/store/OIMSlotStoreServiceSingleSlotDriven.ts
2853
- var _OIMSlotStoreServiceSingleSlotDriven = class _OIMSlotStoreServiceSingleSlotDriven {
2854
- createStore() {
2855
- return { slot: void 0 };
2856
- }
2857
- ownKey(key) {
2858
- return key;
2859
- }
2860
- isSameKey() {
2861
- return true;
2862
- }
2863
- get(store) {
2864
- return store.slot;
2865
- }
2866
- set(store, _key, slot) {
2867
- store.slot = slot;
2868
- }
2869
- remove(store) {
2870
- store.slot = void 0;
2871
- }
2872
- getSlots(store) {
2873
- const slot = store.slot;
2874
- return slot === void 0 ? OIM_FROZEN_EMPTY_SLOTS.values() : [slot].values();
2875
- }
2876
- getSlotCount(store) {
2877
- return store.slot === void 0 ? 0 : 1;
2878
- }
2879
- };
2880
- _OIMSlotStoreServiceSingleSlotDriven.INSTANCE = new _OIMSlotStoreServiceSingleSlotDriven();
2881
- var OIMSlotStoreServiceSingleSlotDriven = _OIMSlotStoreServiceSingleSlotDriven;
2882
-
2883
- // src/factories/createOIMSingleEntityService.ts
2884
- function createOIMSingleEntityService(db, options = {}) {
2885
- return createOIMSingleSlotService({
2886
- slotContentService: createOIMSlotContentEntityService(db, {
2887
- ...options,
2888
- slotStoreService: OIMSlotStoreServiceSingleSlotDriven.INSTANCE
2889
- })
2890
- });
2634
+ // src/engine/bucket/utils/createOIMSingleBucketSlot.ts
2635
+ function createOIMSingleBucketSlot(owner, bucketSlotsStore, storeSlot) {
2636
+ const singleBucketSlot = {
2637
+ effects: void 0,
2638
+ changedAtRevision: 0,
2639
+ changedAtEpoch: 0,
2640
+ effectEdges: void 0,
2641
+ holdCount: 0,
2642
+ releaseDueAfterWriteMs: -1,
2643
+ releaseDueAfterIdleMs: -1,
2644
+ releaseDueAfterUnholdMs: -1,
2645
+ slotFlags: OIM_SLOT_FLAG_EMPTY,
2646
+ columnSlotStore: void 0,
2647
+ storeSlot,
2648
+ owner,
2649
+ key: void 0,
2650
+ indexKeys: void 0,
2651
+ bucketSlotsStore,
2652
+ commands: void 0,
2653
+ isWholeListRecorded: false,
2654
+ commandsStartedAtRevision: 0,
2655
+ commandsStartedAtEpoch: 0
2656
+ };
2657
+ return singleBucketSlot;
2891
2658
  }
2892
2659
 
2893
- // src/engine/bucket/commands/OIMBucketCommandsNone.ts
2894
- var _OIMBucketCommandsNone = class _OIMBucketCommandsNone {
2660
+ // src/engine/bucket/commands/OIMNoBucketCommands.ts
2661
+ var _OIMNoBucketCommands = class _OIMNoBucketCommands {
2895
2662
  recordInsert() {
2896
2663
  return;
2897
2664
  }
@@ -2905,8 +2672,8 @@ var _OIMBucketCommandsNone = class _OIMBucketCommandsNone {
2905
2672
  return;
2906
2673
  }
2907
2674
  };
2908
- _OIMBucketCommandsNone.INSTANCE = new _OIMBucketCommandsNone();
2909
- var OIMBucketCommandsNone = _OIMBucketCommandsNone;
2675
+ _OIMNoBucketCommands.INSTANCE = new _OIMNoBucketCommands();
2676
+ var OIMNoBucketCommands = _OIMNoBucketCommands;
2910
2677
 
2911
2678
  // src/engine/bucket/constants/OIM_NOTHING_WAS_REMOVED.ts
2912
2679
  var OIM_NOTHING_WAS_REMOVED = -1;
@@ -2935,44 +2702,43 @@ function createOIMBucketSlot(key, owner, bucketSlotsStore, storeSlot) {
2935
2702
  commands: void 0,
2936
2703
  isWholeListRecorded: false,
2937
2704
  commandsStartedAtRevision: 0,
2938
- commandsStartedAtEpoch: 0,
2939
- wasEmptyBeforeChange: void 0,
2940
- isChangedAgainInSubframe: false
2705
+ commandsStartedAtEpoch: 0
2941
2706
  };
2942
2707
  }
2943
2708
 
2709
+ // src/engine/channel/utils/oimGetChannelQueueAtDepth.ts
2710
+ function oimGetChannelQueueAtDepth(channelQueues, depth) {
2711
+ const found = channelQueues[depth];
2712
+ if (found !== void 0) return found;
2713
+ const made = new OIMChannelQueue();
2714
+ channelQueues[depth] = made;
2715
+ return made;
2716
+ }
2717
+
2944
2718
  // src/facade/bucket/OIMSlotContentBucketService.ts
2945
2719
  var OIMSlotContentBucketService = class {
2946
2720
  constructor(options) {
2947
- this.bucketCommands = options.bucketCommands ?? OIMBucketCommandsNone.INSTANCE;
2948
- this.slotContentStrategy = {
2949
- createSlot: (key, storeSlot, slotOwnerService) => this.createSlot(key, storeSlot, slotOwnerService),
2950
- isSlotEmpty: (bucketSlot) => this.isSlotEmpty(bucketSlot),
2951
- hasReference: (bucketSlot) => this.hasReference(bucketSlot),
2952
- releaseSlotContent: (bucketSlot, slotOwnerService) => {
2953
- this.releaseSlotContent(bucketSlot, slotOwnerService);
2954
- },
2955
- onSubframeClosed: (storeSlot, slotOwnerService) => {
2956
- this.onSubframeClosed(storeSlot, slotOwnerService);
2957
- }
2958
- };
2959
- }
2960
- createSlotOwnerService(slotOwnerServiceOptions) {
2961
- return new OIMSlotOwnerService({
2962
- ...slotOwnerServiceOptions,
2963
- slotContentStrategy: this.slotContentStrategy,
2964
- slotContentFlushStrategy: this.slotContentStrategy
2965
- });
2721
+ this.bucketCommands = options.bucketCommands ?? OIMNoBucketCommands.INSTANCE;
2966
2722
  }
2967
- createSlot(key, storeSlot, slotOwnerService) {
2968
- if (storeSlot === void 0) {
2969
- throw new Error(
2970
- "OIMSlotContentBucketService: a bucket is minted into a store slot and none was given. Mint it through its collection or single service."
2971
- );
2723
+ getBucketMemberSlotsMissingFrom(bucketSlot, bucketMemberSlots) {
2724
+ const givenBucketMemberSlots = new Set(bucketMemberSlots);
2725
+ const missingBucketMemberSlots = [];
2726
+ for (const bucketMemberSlot of this.getBucketMemberSlots(bucketSlot)) {
2727
+ if (!givenBucketMemberSlots.has(bucketMemberSlot)) missingBucketMemberSlots.push(bucketMemberSlot);
2972
2728
  }
2729
+ return missingBucketMemberSlots;
2730
+ }
2731
+ createSlot(key, storeSlot, slotOwner) {
2973
2732
  return createOIMBucketSlot(
2974
2733
  key,
2975
- slotOwnerService,
2734
+ slotOwner,
2735
+ this.createBucketMemberSlotsStore(),
2736
+ storeSlot
2737
+ );
2738
+ }
2739
+ createSingleSlot(storeSlot, slotOwner) {
2740
+ return createOIMSingleBucketSlot(
2741
+ slotOwner,
2976
2742
  this.createBucketMemberSlotsStore(),
2977
2743
  storeSlot
2978
2744
  );
@@ -2980,43 +2746,15 @@ var OIMSlotContentBucketService = class {
2980
2746
  isSlotEmpty(bucketSlot) {
2981
2747
  return this.getBucketMemberSlotCount(bucketSlot) === 0;
2982
2748
  }
2983
- hasReference(bucketSlot) {
2984
- return bucketSlot.wasEmptyBeforeChange !== void 0;
2749
+ hasReference() {
2750
+ return false;
2985
2751
  }
2986
2752
  releaseSlotContent(bucketSlot, slotOwnerService) {
2987
- if (this.unholdAllBucketMemberSlots(bucketSlot) === 0) return;
2753
+ if (this.getBucketMemberSlotCount(bucketSlot) === 0) return;
2754
+ slotOwnerService.assertWritable(bucketSlot);
2755
+ this.unholdAllBucketMemberSlots(bucketSlot);
2988
2756
  slotOwnerService.dispatchContentChange(bucketSlot);
2989
2757
  }
2990
- onSubframeClosed(storeSlot, slotOwnerService) {
2991
- const changedBucketSlotChannelQueue = storeSlot.changedBucketSlotChannelQueue;
2992
- if (changedBucketSlotChannelQueue === void 0) return;
2993
- let isRefused = false;
2994
- let refusal;
2995
- try {
2996
- for (let i = 0; i < changedBucketSlotChannelQueue.getEntryCount(); i++) {
2997
- const bucketSlot = changedBucketSlotChannelQueue.getEntryAt(i);
2998
- const bucketSlotEditable = bucketSlot;
2999
- const isChangedAgain = bucketSlot.isChangedAgainInSubframe;
3000
- bucketSlotEditable.isChangedAgainInSubframe = false;
3001
- bucketSlotEditable.wasEmptyBeforeChange = void 0;
3002
- try {
3003
- if (isChangedAgain && !oimIsSlotReleased(bucketSlot)) this.writeChangedBucketSlot(bucketSlot, false, slotOwnerService);
3004
- } catch (error) {
3005
- if (!isRefused) refusal = error;
3006
- isRefused = true;
3007
- }
3008
- try {
3009
- slotOwnerService.releaseSlotIfUnheld(bucketSlot);
3010
- } catch (error) {
3011
- if (!isRefused) refusal = error;
3012
- isRefused = true;
3013
- }
3014
- }
3015
- } finally {
3016
- changedBucketSlotChannelQueue.keepFirstEntries(0);
3017
- }
3018
- if (isRefused) throw refusal;
3019
- }
3020
2758
  markContentChanged(bucketSlot) {
3021
2759
  bucketSlot.owner.assertWritable(bucketSlot);
3022
2760
  this.markBucketSlotChanged(bucketSlot);
@@ -3025,105 +2763,82 @@ var OIMSlotContentBucketService = class {
3025
2763
  const slotOwnerService = bucketSlot.owner;
3026
2764
  slotOwnerService.assertWritable(bucketSlot);
3027
2765
  if (!slotOwnerService.hasColumnSlots(bucketSlot)) return;
3028
- slotOwnerService.columnOwner.markColumnsChanged(bucketSlot, patch, changedColumns, oimGetChannelSlot(bucketSlot));
2766
+ slotOwnerService.columnSlotOwner.markColumnsChanged(bucketSlot, patch, changedColumns, oimGetChannelSlot(bucketSlot));
3029
2767
  }
3030
2768
  addBucketMemberSlot(bucketSlot, bucketMemberSlot) {
3031
2769
  const slotOwnerService = bucketSlot.owner;
3032
2770
  slotOwnerService.assertWritable(bucketSlot);
3033
2771
  this.assertBucketMemberSlotNotReleased(bucketMemberSlot);
3034
- const channelSlot = oimGetChannelSlot(bucketSlot);
3035
- OIMContentChangeDeliveryService.INSTANCE.openContentSubframe(channelSlot);
3036
- try {
3037
- if (this.addBucketMemberSlotWithoutSubframe(bucketSlot, bucketMemberSlot)) this.markBucketSlotChanged(bucketSlot);
3038
- } finally {
3039
- OIMContentChangeDeliveryService.INSTANCE.closeContentSubframe(channelSlot);
3040
- }
2772
+ if (this.addBucketMemberSlotUnannounced(bucketSlot, bucketMemberSlot)) this.markBucketSlotChanged(bucketSlot);
3041
2773
  }
3042
2774
  removeBucketMemberSlot(bucketSlot, bucketMemberSlot) {
3043
2775
  const slotOwnerService = bucketSlot.owner;
3044
2776
  slotOwnerService.assertWritable(bucketSlot);
3045
- const channelSlot = oimGetChannelSlot(bucketSlot);
3046
- OIMContentChangeDeliveryService.INSTANCE.openContentSubframe(channelSlot);
3047
- try {
3048
- const at = this.removeSlot(bucketSlot, bucketMemberSlot);
3049
- if (at === OIM_NOTHING_WAS_REMOVED) return;
3050
- this.letGoOfRemovedBucketMemberSlot(bucketSlot, bucketMemberSlot, at);
3051
- this.markBucketSlotChanged(bucketSlot);
3052
- } finally {
3053
- OIMContentChangeDeliveryService.INSTANCE.closeContentSubframe(channelSlot);
3054
- }
2777
+ const at = this.removeSlot(bucketSlot, bucketMemberSlot);
2778
+ if (at === OIM_NOTHING_WAS_REMOVED) return;
2779
+ this.letGoOfRemovedBucketMemberSlot(bucketSlot, bucketMemberSlot, at);
2780
+ this.markBucketSlotChanged(bucketSlot);
3055
2781
  }
3056
2782
  addBucketMemberSlots(bucketSlot, bucketMemberSlots) {
3057
2783
  const slotOwnerService = bucketSlot.owner;
3058
2784
  slotOwnerService.assertWritable(bucketSlot);
3059
2785
  this.assertBucketMemberSlotsNotReleased(bucketMemberSlots);
3060
- const channelSlot = oimGetChannelSlot(bucketSlot);
3061
- OIMContentChangeDeliveryService.INSTANCE.openContentSubframe(channelSlot);
3062
- try {
3063
- let isAnyAdded = false;
3064
- for (let i = 0; i < bucketMemberSlots.length; i++) {
3065
- if (this.addBucketMemberSlotWithoutSubframe(bucketSlot, bucketMemberSlots[i])) isAnyAdded = true;
3066
- }
3067
- if (isAnyAdded) this.markBucketSlotChanged(bucketSlot);
3068
- } finally {
3069
- OIMContentChangeDeliveryService.INSTANCE.closeContentSubframe(channelSlot);
2786
+ let isAnyAdded = false;
2787
+ for (let i = 0; i < bucketMemberSlots.length; i++) {
2788
+ if (this.addBucketMemberSlotUnannounced(bucketSlot, bucketMemberSlots[i])) isAnyAdded = true;
3070
2789
  }
2790
+ if (isAnyAdded) this.markBucketSlotChanged(bucketSlot);
3071
2791
  }
3072
2792
  removeBucketMemberSlots(bucketSlot, bucketMemberSlots) {
3073
2793
  const slotOwnerService = bucketSlot.owner;
3074
2794
  slotOwnerService.assertWritable(bucketSlot);
3075
2795
  const storeSlotEditable = bucketSlot.storeSlot;
3076
- const channelSlot = oimGetChannelSlot(bucketSlot);
3077
- OIMContentChangeDeliveryService.INSTANCE.openContentSubframe(channelSlot);
2796
+ const writeDepth = storeSlotEditable.writeDepth++;
2797
+ const removedChannelQueue = oimGetChannelQueueAtDepth(storeSlotEditable.departedBucketMemberSlotChannelQueues ?? (storeSlotEditable.departedBucketMemberSlotChannelQueues = []), writeDepth);
2798
+ const removedAtChannelQueue = oimGetChannelQueueAtDepth(storeSlotEditable.removedAtChannelQueues ?? (storeSlotEditable.removedAtChannelQueues = []), writeDepth);
3078
2799
  try {
3079
- const writeDepth = storeSlotEditable.writeDepth++;
3080
- const removedChannelQueue = oimGetChannelQueueAtDepth(storeSlotEditable.departedBucketMemberSlotChannelQueues ?? (storeSlotEditable.departedBucketMemberSlotChannelQueues = []), writeDepth);
3081
- const removedAtChannelQueue = oimGetChannelQueueAtDepth(storeSlotEditable.removedAtChannelQueues ?? (storeSlotEditable.removedAtChannelQueues = []), writeDepth);
3082
- try {
3083
- this.removeSlots(bucketSlot, bucketMemberSlots, removedChannelQueue, removedAtChannelQueue);
3084
- const removedCount = removedChannelQueue.getEntryCount();
3085
- for (let i = 0; i < removedCount; i++) {
3086
- this.letGoOfRemovedBucketMemberSlot(bucketSlot, removedChannelQueue.getEntryAt(i), removedAtChannelQueue.getEntryAt(i));
3087
- }
3088
- if (removedCount !== 0) this.markBucketSlotChanged(bucketSlot);
3089
- } finally {
3090
- removedChannelQueue.keepFirstEntries(0);
3091
- removedAtChannelQueue.keepFirstEntries(0);
3092
- storeSlotEditable.writeDepth = writeDepth;
2800
+ this.removeSlots(bucketSlot, bucketMemberSlots, removedChannelQueue, removedAtChannelQueue);
2801
+ const removedCount = removedChannelQueue.getEntryCount();
2802
+ for (let i = 0; i < removedCount; i++) {
2803
+ this.letGoOfRemovedBucketMemberSlot(bucketSlot, removedChannelQueue.getEntryAt(i), removedAtChannelQueue.getEntryAt(i));
3093
2804
  }
2805
+ if (removedCount !== 0) this.markBucketSlotChanged(bucketSlot);
3094
2806
  } finally {
3095
- OIMContentChangeDeliveryService.INSTANCE.closeContentSubframe(channelSlot);
2807
+ removedChannelQueue.keepFirstEntries(0);
2808
+ removedAtChannelQueue.keepFirstEntries(0);
2809
+ storeSlotEditable.writeDepth = writeDepth;
3096
2810
  }
3097
2811
  }
3098
- writeBucketMemberSlots(bucketSlot, bucketMemberSlots) {
2812
+ insertSlotContent(bucketSlot, bucketMemberSlots, changedBucketSlots) {
3099
2813
  const slotOwnerService = bucketSlot.owner;
3100
- slotOwnerService.assertWritable(bucketSlot);
3101
- const channelSlot = oimGetChannelSlot(bucketSlot);
3102
- OIMContentChangeDeliveryService.INSTANCE.openContentSubframe(channelSlot);
2814
+ slotOwnerService.fileSlot(bucketSlot);
2815
+ let isWritten;
3103
2816
  try {
3104
- if (!this.reconcileBucketMemberSlots(bucketSlot, bucketMemberSlots)) return false;
3105
- this.markBucketSlotChanged(bucketSlot);
3106
- return true;
3107
- } finally {
3108
- OIMContentChangeDeliveryService.INSTANCE.closeContentSubframe(channelSlot);
2817
+ isWritten = this.writeSlotContent(bucketSlot, bucketMemberSlots);
2818
+ } catch (refusal) {
2819
+ slotOwnerService.releaseSlotIfUnheld(bucketSlot);
2820
+ throw refusal;
3109
2821
  }
2822
+ if (!isWritten) slotOwnerService.releaseSlotIfUnheld(bucketSlot);
2823
+ else if (changedBucketSlots !== void 0) changedBucketSlots.push(bucketSlot);
3110
2824
  }
3111
- clearBucketMemberSlots(bucketSlot) {
2825
+ writeSlotContent(bucketSlot, bucketMemberSlots) {
3112
2826
  const slotOwnerService = bucketSlot.owner;
3113
2827
  slotOwnerService.assertWritable(bucketSlot);
3114
- const channelSlot = oimGetChannelSlot(bucketSlot);
3115
- OIMContentChangeDeliveryService.INSTANCE.openContentSubframe(channelSlot);
3116
- try {
3117
- if (this.drainBucketMemberSlots(bucketSlot)) this.markBucketSlotChanged(bucketSlot);
3118
- else slotOwnerService.releaseSlotIfUnheld(bucketSlot);
3119
- } finally {
3120
- OIMContentChangeDeliveryService.INSTANCE.closeContentSubframe(channelSlot);
3121
- }
2828
+ if (!this.reconcileBucketMemberSlots(bucketSlot, bucketMemberSlots)) return false;
2829
+ this.markBucketSlotChanged(bucketSlot);
2830
+ return true;
2831
+ }
2832
+ clearSlotContent(bucketSlot) {
2833
+ const slotOwnerService = bucketSlot.owner;
2834
+ slotOwnerService.assertWritable(bucketSlot);
2835
+ if (this.drainBucketMemberSlots(bucketSlot)) this.markBucketSlotChanged(bucketSlot);
2836
+ else slotOwnerService.releaseSlotIfUnheld(bucketSlot);
3122
2837
  }
3123
2838
  fillBucketMemberSlots(bucketSlot, bucketMemberSlots) {
3124
- if (bucketSlot.changedAtRevision !== 0 || bucketSlot.wasEmptyBeforeChange !== void 0) {
2839
+ if (bucketSlot.changedAtRevision !== 0) {
3125
2840
  throw new Error(
3126
- "OIMSlotContentBucketService: fillBucketMemberSlots fills only a bucket nobody was told about yet, and this one was announced. Use addBucketMemberSlots or writeBucketMemberSlots, which tell its listeners."
2841
+ "OIMSlotContentBucketService: fillBucketMemberSlots fills only a bucket nobody was told about yet, and this one was announced. Use addBucketMemberSlots or writeSlotContent, which tell its listeners."
3127
2842
  );
3128
2843
  }
3129
2844
  this.assertBucketMemberSlotsNotReleased(bucketMemberSlots);
@@ -3134,23 +2849,12 @@ var OIMSlotContentBucketService = class {
3134
2849
  }
3135
2850
  markBucketSlotChanged(bucketSlot) {
3136
2851
  const slotOwnerService = bucketSlot.owner;
3137
- const bucketSlotEditable = bucketSlot;
3138
- const isFirstChange = bucketSlot.wasEmptyBeforeChange === void 0;
3139
- if (isFirstChange) bucketSlotEditable.wasEmptyBeforeChange = oimIsSlotEmpty(bucketSlot);
2852
+ const wasEmpty = oimIsSlotEmpty(bucketSlot);
3140
2853
  slotOwnerService.markEmptiness(bucketSlot, this.isSlotEmpty(bucketSlot));
3141
- if (!OIMChannelService.INSTANCE.isSubframeOpen(oimGetChannelSlot(bucketSlot)) || bucketSlot.holdCount > 0 && !slotOwnerService.hasContentChangeListeners(bucketSlot)) {
3142
- this.flushChangedBucketSlot(bucketSlot, slotOwnerService);
3143
- return;
3144
- }
3145
- if (!isFirstChange) {
3146
- bucketSlotEditable.isChangedAgainInSubframe = true;
3147
- return;
3148
- }
3149
- const storeSlot = bucketSlot.storeSlot;
3150
- const changedBucketSlotChannelQueue = storeSlot.changedBucketSlotChannelQueue ?? (storeSlot.changedBucketSlotChannelQueue = new OIMChannelQueue());
3151
- if (changedBucketSlotChannelQueue.getEntryCount() === 0) slotOwnerService.listChangedStoreSlot(storeSlot);
3152
- changedBucketSlotChannelQueue.enqueueEntry(bucketSlot);
3153
- this.writeChangedBucketSlot(bucketSlot, bucketSlot.wasEmptyBeforeChange === true, slotOwnerService);
2854
+ if (oimIsSlotReleased(bucketSlot)) return;
2855
+ slotOwnerService.writeSlotToChannelAndSettle(bucketSlot, wasEmpty);
2856
+ slotOwnerService.dispatchContentChange(bucketSlot);
2857
+ slotOwnerService.releaseSlotIfUnheldAfterListeners(bucketSlot);
3154
2858
  }
3155
2859
  letGoOfRemovedBucketMemberSlot(bucketSlot, bucketMemberSlot, at) {
3156
2860
  oimUnholdSlotIfAlive(bucketMemberSlot);
@@ -3166,7 +2870,7 @@ var OIMSlotContentBucketService = class {
3166
2870
  assertBucketMemberSlotsNotReleased(bucketMemberSlots) {
3167
2871
  for (let i = 0; i < bucketMemberSlots.length; i++) this.assertBucketMemberSlotNotReleased(bucketMemberSlots[i]);
3168
2872
  }
3169
- addBucketMemberSlotWithoutSubframe(bucketSlot, bucketMemberSlot) {
2873
+ addBucketMemberSlotUnannounced(bucketSlot, bucketMemberSlot) {
3170
2874
  if (!this.addSlot(bucketSlot, bucketMemberSlot)) return false;
3171
2875
  bucketMemberSlot.owner.holdSlot(bucketMemberSlot);
3172
2876
  const bucketMemberSlotCount = this.getBucketMemberSlotCount(bucketSlot);
@@ -3217,21 +2921,10 @@ var OIMSlotContentBucketService = class {
3217
2921
  storeSlotEditable.writeDepth = writeDepth;
3218
2922
  }
3219
2923
  }
3220
- writeChangedBucketSlot(bucketSlot, wasEmpty, slotOwnerService) {
3221
- slotOwnerService.writeSlotToChannelAndSettle(bucketSlot, wasEmpty);
3222
- slotOwnerService.dispatchContentChange(bucketSlot);
3223
- }
3224
- flushChangedBucketSlot(bucketSlot, slotOwnerService) {
3225
- const wasEmpty = bucketSlot.wasEmptyBeforeChange;
3226
- if (wasEmpty === void 0) return;
3227
- bucketSlot.wasEmptyBeforeChange = void 0;
3228
- if (oimIsSlotReleased(bucketSlot)) return;
3229
- this.writeChangedBucketSlot(bucketSlot, wasEmpty, slotOwnerService);
3230
- }
3231
2924
  };
3232
2925
 
3233
- // src/facade/bucket/OIMSlotContentBucketServiceSetDriven.ts
3234
- var OIMSlotContentBucketServiceSetDriven = class extends OIMSlotContentBucketService {
2926
+ // src/facade/bucket/OIMSlotContentSetBucketService.ts
2927
+ var OIMSlotContentSetBucketService = class extends OIMSlotContentBucketService {
3235
2928
  constructor(options = {}) {
3236
2929
  super(options);
3237
2930
  }
@@ -3285,35 +2978,53 @@ var OIMSlotContentBucketServiceSetDriven = class extends OIMSlotContentBucketSer
3285
2978
  }
3286
2979
  };
3287
2980
 
3288
- // src/facade/bucket/OIMSlotContentBucketServiceArrayBased.ts
3289
- var OIMSlotContentBucketServiceArrayBased = class extends OIMSlotContentBucketService {
3290
- constructor(options, bucketArrayMembership) {
3291
- super(options);
3292
- this.bucketArrayMembership = bucketArrayMembership;
2981
+ // src/engine/bucket/array/OIMBucketMemberSlotsArrayService.ts
2982
+ var insertionTailLimit = 8;
2983
+ var _OIMBucketMemberSlotsArrayService = class _OIMBucketMemberSlotsArrayService {
2984
+ createBucketSlotsArrayStore() {
2985
+ return { bucketMemberSlots: [], uniqueBucketMemberSlots: void 0, sortedCount: 0 };
3293
2986
  }
3294
- addSlot(bucketSlot, bucketMemberSlot) {
3295
- const bucketMemberSlotsArrayStore = bucketSlot.bucketSlotsStore;
3296
- if (!this.bucketArrayMembership.addSlot(bucketMemberSlotsArrayStore, bucketMemberSlot)) return false;
3297
- bucketMemberSlotsArrayStore.bucketMemberSlots.push(bucketMemberSlot);
2987
+ hasBucketMemberSlot(bucketSlotsArrayStore, bucketMemberSlot) {
2988
+ return bucketSlotsArrayStore.bucketMemberSlots.indexOf(bucketMemberSlot) >= 0;
2989
+ }
2990
+ appendBucketMemberSlot(bucketSlotsArrayStore, bucketMemberSlot) {
2991
+ bucketSlotsArrayStore.bucketMemberSlots.push(bucketMemberSlot);
3298
2992
  return true;
3299
2993
  }
3300
- removeSlot(bucketSlot, bucketMemberSlot) {
3301
- const bucketMemberSlotsArrayStore = bucketSlot.bucketSlotsStore;
3302
- if (!this.bucketArrayMembership.removeSlot(bucketMemberSlotsArrayStore, bucketMemberSlot)) return OIM_NOTHING_WAS_REMOVED;
3303
- const bucketMemberSlots = bucketMemberSlotsArrayStore.bucketMemberSlots;
2994
+ insertBucketMemberSlotAt(bucketSlotsArrayStore, at, bucketMemberSlot) {
2995
+ const bucketMemberSlots = bucketSlotsArrayStore.bucketMemberSlots;
2996
+ const landing = at < 0 ? 0 : at > bucketMemberSlots.length ? bucketMemberSlots.length : at;
2997
+ bucketMemberSlots.splice(landing, 0, bucketMemberSlot);
2998
+ return landing;
2999
+ }
3000
+ removeBucketMemberSlot(bucketSlotsArrayStore, bucketMemberSlot) {
3001
+ const bucketMemberSlots = bucketSlotsArrayStore.bucketMemberSlots;
3304
3002
  const at = bucketMemberSlots.indexOf(bucketMemberSlot);
3305
- if (at >= 0) bucketMemberSlots.splice(at, 1);
3003
+ if (at < 0) return OIM_NOTHING_WAS_REMOVED;
3004
+ bucketMemberSlots.splice(at, 1);
3005
+ if (at < bucketSlotsArrayStore.sortedCount) bucketSlotsArrayStore.sortedCount--;
3306
3006
  return at;
3307
3007
  }
3308
- removeSlots(bucketSlot, bucketMemberSlots, removedChannelQueue, removedAtChannelQueue) {
3008
+ removeBucketMemberSlotAt(bucketSlotsArrayStore, at) {
3009
+ if (at < bucketSlotsArrayStore.sortedCount) bucketSlotsArrayStore.sortedCount--;
3010
+ return bucketSlotsArrayStore.bucketMemberSlots.splice(at, 1)[0];
3011
+ }
3012
+ removeBucketMemberSlotRange(bucketSlotsArrayStore, at, count) {
3013
+ const removedBucketMemberSlots = bucketSlotsArrayStore.bucketMemberSlots.splice(at, count);
3014
+ const sortedCount = bucketSlotsArrayStore.sortedCount;
3015
+ if (at < sortedCount) bucketSlotsArrayStore.sortedCount = sortedCount - Math.min(removedBucketMemberSlots.length, sortedCount - at);
3016
+ return removedBucketMemberSlots;
3017
+ }
3018
+ removeBucketMemberSlots(bucketSlotsArrayStore, bucketMemberSlots, removedChannelQueue, removedAtChannelQueue) {
3309
3019
  if (bucketMemberSlots.length === 0) return;
3310
- const bucketMemberSlotsArrayStore = bucketSlot.bucketSlotsStore;
3311
3020
  const leavingCounts = /* @__PURE__ */ new Map();
3312
3021
  for (let i = 0; i < bucketMemberSlots.length; i++) {
3313
3022
  leavingCounts.set(bucketMemberSlots[i], (leavingCounts.get(bucketMemberSlots[i]) ?? 0) + 1);
3314
3023
  }
3315
- const heldBucketMemberSlots = bucketMemberSlotsArrayStore.bucketMemberSlots;
3024
+ const heldBucketMemberSlots = bucketSlotsArrayStore.bucketMemberSlots;
3025
+ const sortedCount = bucketSlotsArrayStore.sortedCount;
3316
3026
  const length = heldBucketMemberSlots.length;
3027
+ let removedFromSortedCount = 0;
3317
3028
  let kept = 0;
3318
3029
  for (let read = 0; read < length; read++) {
3319
3030
  const bucketMemberSlot = heldBucketMemberSlots[read];
@@ -3324,303 +3035,42 @@ var OIMSlotContentBucketServiceArrayBased = class extends OIMSlotContentBucketSe
3324
3035
  continue;
3325
3036
  }
3326
3037
  leavingCounts.set(bucketMemberSlot, leavingCount - 1);
3327
- this.bucketArrayMembership.removeSlot(bucketMemberSlotsArrayStore, bucketMemberSlot);
3038
+ if (read < sortedCount) removedFromSortedCount++;
3328
3039
  removedChannelQueue.enqueueEntry(bucketMemberSlot);
3329
3040
  removedAtChannelQueue.enqueueEntry(kept);
3330
3041
  }
3331
3042
  if (kept !== length) heldBucketMemberSlots.length = kept;
3332
- }
3333
- reconcileSlots(bucketSlot, bucketMemberSlots, arrivedChannelQueue, departedChannelQueue) {
3334
- const bucketMemberSlotsArrayStore = bucketSlot.bucketSlotsStore;
3335
- if (this.bucketArrayMembership.containsTheSameSequence(bucketMemberSlotsArrayStore, bucketMemberSlots)) return;
3336
- arrivedChannelQueue.keepFirstEntries(0);
3337
- departedChannelQueue.keepFirstEntries(0);
3338
- const heldBucketMemberSlots = bucketMemberSlotsArrayStore.bucketMemberSlots;
3339
- for (let i = 0; i < heldBucketMemberSlots.length; i++) departedChannelQueue.enqueueEntry(heldBucketMemberSlots[i]);
3340
- this.emptyBucketMemberSlotsStore(bucketMemberSlotsArrayStore);
3341
- for (let i = 0; i < bucketMemberSlots.length; i++) {
3342
- if (this.addSlot(bucketSlot, bucketMemberSlots[i])) arrivedChannelQueue.enqueueEntry(bucketMemberSlots[i]);
3343
- }
3344
- }
3345
- drainSlots(bucketSlot, departedChannelQueue) {
3346
- const bucketMemberSlotsArrayStore = bucketSlot.bucketSlotsStore;
3347
- const heldBucketMemberSlots = bucketMemberSlotsArrayStore.bucketMemberSlots;
3348
- for (let i = 0; i < heldBucketMemberSlots.length; i++) departedChannelQueue.enqueueEntry(heldBucketMemberSlots[i]);
3349
- this.emptyBucketMemberSlotsStore(bucketMemberSlotsArrayStore);
3350
- }
3351
- hasBucketMemberSlot(bucketSlot, bucketMemberSlot) {
3352
- return this.bucketArrayMembership.hasSlot(bucketSlot.bucketSlotsStore, bucketMemberSlot);
3353
- }
3354
- getBucketMemberSlotCount(bucketSlot) {
3355
- return bucketSlot.bucketSlotsStore.bucketMemberSlots.length;
3356
- }
3357
- getBucketMemberSlots(bucketSlot) {
3358
- return bucketSlot.bucketSlotsStore.bucketMemberSlots;
3359
- }
3360
- getBucketMemberSlotAt(bucketSlot, at) {
3361
- return bucketSlot.bucketSlotsStore.bucketMemberSlots[at];
3362
- }
3363
- getBucketMemberSlotPosition(bucketSlot, bucketMemberSlot) {
3364
- return bucketSlot.bucketSlotsStore.bucketMemberSlots.indexOf(bucketMemberSlot);
3365
- }
3366
- emptyBucketMemberSlotsStore(bucketMemberSlotsArrayStore) {
3367
- const bucketMemberSlots = bucketMemberSlotsArrayStore.bucketMemberSlots;
3368
- if (bucketMemberSlots.length !== 0) bucketMemberSlots.length = 0;
3369
- this.bucketArrayMembership.clearSlots(bucketMemberSlotsArrayStore);
3370
- }
3371
- };
3372
-
3373
- // src/engine/bucket/array/OIMBucketArrayMembershipNonUnique.ts
3374
- var _OIMBucketArrayMembershipNonUnique = class _OIMBucketArrayMembershipNonUnique {
3375
- createStore() {
3376
- return { bucketMemberSlots: [] };
3377
- }
3378
- addSlot() {
3379
- return true;
3380
- }
3381
- removeSlot() {
3382
- return true;
3383
- }
3384
- hasSlot(bucketSlotsArrayStore, bucketMemberSlot) {
3385
- return bucketSlotsArrayStore.bucketMemberSlots.indexOf(bucketMemberSlot) >= 0;
3386
- }
3387
- clearSlots() {
3388
- return;
3389
- }
3390
- containsTheSameSequence(bucketSlotsArrayStore, bucketMemberSlots) {
3391
- return oimSameSlotSequence(bucketSlotsArrayStore.bucketMemberSlots, bucketMemberSlots);
3392
- }
3393
- };
3394
- _OIMBucketArrayMembershipNonUnique.INSTANCE = new _OIMBucketArrayMembershipNonUnique();
3395
- var OIMBucketArrayMembershipNonUnique = _OIMBucketArrayMembershipNonUnique;
3396
-
3397
- // src/engine/bucket/array/utils/oimAssertWholePosition.ts
3398
- function oimAssertWholePosition(position) {
3399
- if (position === Math.trunc(position)) return;
3400
- throw new Error(
3401
- `OIMSlotContentBucketServiceArrayDriven: a position must be a whole number, got ${position}. A fraction or NaN would be read one way by the list and another by splice.`
3402
- );
3403
- }
3404
-
3405
- // src/facade/bucket/OIMSlotContentBucketServiceArrayDriven.ts
3406
- var OIMSlotContentBucketServiceArrayDriven = class extends OIMSlotContentBucketServiceArrayBased {
3407
- constructor(options = {}) {
3408
- super(
3409
- options,
3410
- options.bucketArrayMembership ?? OIMBucketArrayMembershipNonUnique.INSTANCE
3411
- );
3412
- }
3413
- createBucketMemberSlotsStore() {
3414
- return this.bucketArrayMembership.createStore();
3415
- }
3416
- insertBucketMemberSlotAt(bucketSlot, at, bucketMemberSlot) {
3417
- const slotOwnerService = bucketSlot.owner;
3418
- slotOwnerService.assertWritable(bucketSlot);
3419
- oimAssertWholePosition(at);
3420
- this.assertBucketMemberSlotNotReleased(bucketMemberSlot);
3421
- const channelSlot = oimGetChannelSlot(bucketSlot);
3422
- OIMContentChangeDeliveryService.INSTANCE.openContentSubframe(channelSlot);
3423
- try {
3424
- const bucketMemberSlotsArrayStore = bucketSlot.bucketSlotsStore;
3425
- if (!this.bucketArrayMembership.addSlot(bucketMemberSlotsArrayStore, bucketMemberSlot)) return;
3426
- const bucketMemberSlots = bucketMemberSlotsArrayStore.bucketMemberSlots;
3427
- const landing = clampPosition(bucketMemberSlots.length, at);
3428
- bucketMemberSlots.splice(landing, 0, bucketMemberSlot);
3429
- bucketMemberSlot.owner.holdSlot(bucketMemberSlot);
3430
- this.bucketCommands.recordInsert(bucketSlot, landing, bucketMemberSlot, bucketMemberSlots.length);
3431
- this.markBucketSlotChanged(bucketSlot);
3432
- } finally {
3433
- OIMContentChangeDeliveryService.INSTANCE.closeContentSubframe(channelSlot);
3434
- }
3435
- }
3436
- removeBucketMemberSlotAt(bucketSlot, at) {
3437
- const slotOwnerService = bucketSlot.owner;
3438
- slotOwnerService.assertWritable(bucketSlot);
3439
- oimAssertWholePosition(at);
3440
- const channelSlot = oimGetChannelSlot(bucketSlot);
3441
- OIMContentChangeDeliveryService.INSTANCE.openContentSubframe(channelSlot);
3442
- try {
3443
- const bucketMemberSlotsArrayStore = bucketSlot.bucketSlotsStore;
3444
- const bucketMemberSlots = bucketMemberSlotsArrayStore.bucketMemberSlots;
3445
- if (at < 0 || at >= bucketMemberSlots.length) return void 0;
3446
- const removedBucketMemberSlot = bucketMemberSlots[at];
3447
- bucketMemberSlots.splice(at, 1);
3448
- this.bucketArrayMembership.removeSlot(bucketMemberSlotsArrayStore, removedBucketMemberSlot);
3449
- oimUnholdSlotIfAlive(removedBucketMemberSlot);
3450
- this.bucketCommands.recordRemove(bucketSlot, at, 1, bucketMemberSlots.length);
3451
- this.markBucketSlotChanged(bucketSlot);
3452
- return removedBucketMemberSlot;
3453
- } finally {
3454
- OIMContentChangeDeliveryService.INSTANCE.closeContentSubframe(channelSlot);
3455
- }
3456
- }
3457
- removeBucketMemberSlotRange(bucketSlot, at, count) {
3458
- const slotOwnerService = bucketSlot.owner;
3459
- slotOwnerService.assertWritable(bucketSlot);
3460
- oimAssertWholePosition(at);
3461
- oimAssertWholePosition(count);
3462
- const channelSlot = oimGetChannelSlot(bucketSlot);
3463
- OIMContentChangeDeliveryService.INSTANCE.openContentSubframe(channelSlot);
3464
- try {
3465
- const bucketMemberSlotsArrayStore = bucketSlot.bucketSlotsStore;
3466
- const bucketMemberSlots = bucketMemberSlotsArrayStore.bucketMemberSlots;
3467
- if (at < 0 || count <= 0 || at >= bucketMemberSlots.length) return OIM_FROZEN_EMPTY_SLOTS;
3468
- const removedBucketMemberSlots = bucketMemberSlots.splice(at, count);
3469
- for (let i = 0; i < removedBucketMemberSlots.length; i++) {
3470
- this.bucketArrayMembership.removeSlot(bucketMemberSlotsArrayStore, removedBucketMemberSlots[i]);
3471
- oimUnholdSlotIfAlive(removedBucketMemberSlots[i]);
3043
+ bucketSlotsArrayStore.sortedCount = sortedCount - removedFromSortedCount;
3044
+ }
3045
+ moveBucketMemberSlotRange(bucketSlotsArrayStore, from, count, landing) {
3046
+ const bucketMemberSlots = bucketSlotsArrayStore.bucketMemberSlots;
3047
+ const firstTouched = from < landing ? from : landing;
3048
+ const pastTouched = (from > landing ? from : landing) + count;
3049
+ const touched = pastTouched - firstTouched;
3050
+ const leftShift = from < landing ? count : touched - count;
3051
+ if (leftShift === 0 || leftShift === touched) return false;
3052
+ let isChanged = false;
3053
+ for (let at = firstTouched; at < pastTouched; at++) {
3054
+ const after = firstTouched + (at - firstTouched + leftShift) % touched;
3055
+ if (bucketMemberSlots[at] !== bucketMemberSlots[after]) {
3056
+ isChanged = true;
3057
+ break;
3472
3058
  }
3473
- this.bucketCommands.recordRemove(bucketSlot, at, removedBucketMemberSlots.length, bucketMemberSlots.length);
3474
- this.markBucketSlotChanged(bucketSlot);
3475
- return removedBucketMemberSlots;
3476
- } finally {
3477
- OIMContentChangeDeliveryService.INSTANCE.closeContentSubframe(channelSlot);
3478
- }
3479
- }
3480
- moveBucketMemberSlotToPosition(bucketSlot, from, to) {
3481
- const slotOwnerService = bucketSlot.owner;
3482
- slotOwnerService.assertWritable(bucketSlot);
3483
- oimAssertWholePosition(from);
3484
- oimAssertWholePosition(to);
3485
- const channelSlot = oimGetChannelSlot(bucketSlot);
3486
- OIMContentChangeDeliveryService.INSTANCE.openContentSubframe(channelSlot);
3487
- try {
3488
- const bucketMemberSlots = bucketSlot.bucketSlotsStore.bucketMemberSlots;
3489
- if (from < 0 || from >= bucketMemberSlots.length || to < 0 || to >= bucketMemberSlots.length || from === to) return void 0;
3490
- if (!moveRange(bucketMemberSlots, from, 1, to)) return void 0;
3491
- this.bucketCommands.recordMove(bucketSlot, from, to, bucketMemberSlots.length);
3492
- this.markBucketSlotChanged(bucketSlot);
3493
- return bucketMemberSlots[to];
3494
- } finally {
3495
- OIMContentChangeDeliveryService.INSTANCE.closeContentSubframe(channelSlot);
3496
- }
3497
- }
3498
- moveBucketMemberSlotRangeToPosition(bucketSlot, from, count, to) {
3499
- const slotOwnerService = bucketSlot.owner;
3500
- slotOwnerService.assertWritable(bucketSlot);
3501
- oimAssertWholePosition(from);
3502
- oimAssertWholePosition(count);
3503
- oimAssertWholePosition(to);
3504
- const channelSlot = oimGetChannelSlot(bucketSlot);
3505
- OIMContentChangeDeliveryService.INSTANCE.openContentSubframe(channelSlot);
3506
- try {
3507
- const bucketMemberSlots = bucketSlot.bucketSlotsStore.bucketMemberSlots;
3508
- if (from < 0 || count <= 0 || from >= bucketMemberSlots.length) return;
3509
- const taking = from + count > bucketMemberSlots.length ? bucketMemberSlots.length - from : count;
3510
- const landing = clampPosition(bucketMemberSlots.length - taking, to);
3511
- if (!moveRange(bucketMemberSlots, from, taking, landing)) return;
3512
- this.bucketCommands.recordWholeList(bucketSlot);
3513
- this.markBucketSlotChanged(bucketSlot);
3514
- } finally {
3515
- OIMContentChangeDeliveryService.INSTANCE.closeContentSubframe(channelSlot);
3516
- }
3517
- }
3518
- };
3519
- function clampPosition(length, at) {
3520
- return at < 0 ? 0 : at > length ? length : at;
3521
- }
3522
- function moveRange(bucketMemberSlots, from, count, landing) {
3523
- const firstTouched = from < landing ? from : landing;
3524
- const pastTouched = (from > landing ? from : landing) + count;
3525
- const touched = pastTouched - firstTouched;
3526
- const leftShift = from < landing ? count : touched - count;
3527
- if (leftShift === 0 || leftShift === touched) return false;
3528
- let changes = false;
3529
- for (let at = firstTouched; at < pastTouched; at++) {
3530
- const after = firstTouched + (at - firstTouched + leftShift) % touched;
3531
- if (bucketMemberSlots[at] !== bucketMemberSlots[after]) {
3532
- changes = true;
3533
- break;
3534
- }
3535
- }
3536
- if (!changes) return false;
3537
- reverse(bucketMemberSlots, firstTouched, firstTouched + leftShift - 1);
3538
- reverse(bucketMemberSlots, firstTouched + leftShift, pastTouched - 1);
3539
- reverse(bucketMemberSlots, firstTouched, pastTouched - 1);
3540
- return true;
3541
- }
3542
- function reverse(bucketMemberSlots, first, last) {
3543
- for (let low = first, high = last; low < high; low++, high--) {
3544
- const bucketMemberSlot = bucketMemberSlots[low];
3545
- bucketMemberSlots[low] = bucketMemberSlots[high];
3546
- bucketMemberSlots[high] = bucketMemberSlot;
3547
- }
3548
- }
3549
-
3550
- // src/facade/bucket/OIMSlotContentBucketServiceSortedArrayDriven.ts
3551
- var insertionTailLimit = 8;
3552
- var OIMSlotContentBucketServiceSortedArrayDriven = class extends OIMSlotContentBucketServiceArrayBased {
3553
- constructor(options) {
3554
- super({}, OIMBucketArrayMembershipNonUnique.INSTANCE);
3555
- this.compareBucketMemberSlots = options.compareBucketMemberSlots;
3556
- }
3557
- createBucketMemberSlotsStore() {
3558
- return { bucketMemberSlots: [], sortedCount: 0 };
3559
- }
3560
- removeSlot(bucketSlot, bucketMemberSlot) {
3561
- const at = super.removeSlot(bucketSlot, bucketMemberSlot);
3562
- if (at === OIM_NOTHING_WAS_REMOVED) return OIM_NOTHING_WAS_REMOVED;
3563
- const bucketMemberSlotsSortedArrayStore = bucketSlot.bucketSlotsStore;
3564
- if (at < bucketMemberSlotsSortedArrayStore.sortedCount) bucketMemberSlotsSortedArrayStore.sortedCount--;
3565
- return at;
3566
- }
3567
- removeSlots(bucketSlot, bucketMemberSlots, removedChannelQueue, removedAtChannelQueue) {
3568
- const bucketMemberSlotsSortedArrayStore = bucketSlot.bucketSlotsStore;
3569
- const sortedCount = bucketMemberSlotsSortedArrayStore.sortedCount;
3570
- const removedCountBefore = removedChannelQueue.getEntryCount();
3571
- const removedAtCountBefore = removedAtChannelQueue.getEntryCount();
3572
- super.removeSlots(bucketSlot, bucketMemberSlots, removedChannelQueue, removedAtChannelQueue);
3573
- const removedCount = removedChannelQueue.getEntryCount() - removedCountBefore;
3574
- let removedFromSortedCount = 0;
3575
- for (let i = 0; i < removedCount; i++) {
3576
- if (removedAtChannelQueue.getEntryAt(removedAtCountBefore + i) + i >= sortedCount) break;
3577
- removedFromSortedCount++;
3578
- }
3579
- bucketMemberSlotsSortedArrayStore.sortedCount = sortedCount - removedFromSortedCount;
3580
- }
3581
- reconcileSlots(bucketSlot, bucketMemberSlots, arrivedChannelQueue, departedChannelQueue) {
3582
- super.reconcileSlots(bucketSlot, bucketMemberSlots, arrivedChannelQueue, departedChannelQueue);
3583
- bucketSlot.bucketSlotsStore.sortedCount = 0;
3584
- }
3585
- drainSlots(bucketSlot, departedChannelQueue) {
3586
- const bucketMemberSlotsSortedArrayStore = bucketSlot.bucketSlotsStore;
3587
- this.settle(bucketMemberSlotsSortedArrayStore);
3588
- super.drainSlots(bucketSlot, departedChannelQueue);
3589
- bucketMemberSlotsSortedArrayStore.sortedCount = 0;
3590
- }
3591
- getBucketMemberSlots(bucketSlot) {
3592
- this.settle(bucketSlot.bucketSlotsStore);
3593
- return super.getBucketMemberSlots(bucketSlot);
3594
- }
3595
- getBucketMemberSlotAt(bucketSlot, at) {
3596
- this.settle(bucketSlot.bucketSlotsStore);
3597
- return super.getBucketMemberSlotAt(bucketSlot, at);
3598
- }
3599
- getBucketMemberSlotPosition(bucketSlot, bucketMemberSlot) {
3600
- this.settle(bucketSlot.bucketSlotsStore);
3601
- return super.getBucketMemberSlotPosition(bucketSlot, bucketMemberSlot);
3602
- }
3603
- repositionBucketMemberSlot(bucketSlot, bucketMemberSlot) {
3604
- const slotOwnerService = bucketSlot.owner;
3605
- slotOwnerService.assertWritable(bucketSlot);
3606
- const channelSlot = oimGetChannelSlot(bucketSlot);
3607
- OIMContentChangeDeliveryService.INSTANCE.openContentSubframe(channelSlot);
3608
- try {
3609
- if (this.removeSlot(bucketSlot, bucketMemberSlot) === OIM_NOTHING_WAS_REMOVED) return;
3610
- if (this.addSlot(bucketSlot, bucketMemberSlot)) this.markBucketSlotChanged(bucketSlot);
3611
- } finally {
3612
- OIMContentChangeDeliveryService.INSTANCE.closeContentSubframe(channelSlot);
3613
3059
  }
3060
+ if (!isChanged) return false;
3061
+ reverseRange(bucketMemberSlots, firstTouched, firstTouched + leftShift - 1);
3062
+ reverseRange(bucketMemberSlots, firstTouched + leftShift, pastTouched - 1);
3063
+ reverseRange(bucketMemberSlots, firstTouched, pastTouched - 1);
3064
+ return true;
3614
3065
  }
3615
- settle(bucketMemberSlotsSortedArrayStore) {
3616
- const bucketMemberSlots = bucketMemberSlotsSortedArrayStore.bucketMemberSlots;
3066
+ sortBucketMemberSlots(bucketSlotsArrayStore, compareBucketMemberSlots) {
3067
+ const bucketMemberSlots = bucketSlotsArrayStore.bucketMemberSlots;
3617
3068
  const length = bucketMemberSlots.length;
3618
- const sortedCount = bucketMemberSlotsSortedArrayStore.sortedCount;
3069
+ const sortedCount = bucketSlotsArrayStore.sortedCount;
3619
3070
  if (length === sortedCount) return;
3620
- const compareBucketMemberSlots = this.compareBucketMemberSlots;
3621
3071
  if (length - sortedCount > insertionTailLimit) {
3622
3072
  bucketMemberSlots.sort(compareBucketMemberSlots);
3623
- bucketMemberSlotsSortedArrayStore.sortedCount = length;
3073
+ bucketSlotsArrayStore.sortedCount = length;
3624
3074
  return;
3625
3075
  }
3626
3076
  for (let at = sortedCount; at < length; at++) {
@@ -3636,164 +3086,277 @@ var OIMSlotContentBucketServiceSortedArrayDriven = class extends OIMSlotContentB
3636
3086
  bucketMemberSlots.splice(at, 1);
3637
3087
  bucketMemberSlots.splice(low, 0, bucketMemberSlot);
3638
3088
  }
3639
- bucketMemberSlotsSortedArrayStore.sortedCount = length;
3089
+ bucketSlotsArrayStore.sortedCount = length;
3090
+ }
3091
+ isSameBucketMemberSlotSequence(bucketSlotsArrayStore, bucketMemberSlots) {
3092
+ return oimSameSlotSequence(bucketSlotsArrayStore.bucketMemberSlots, bucketMemberSlots);
3093
+ }
3094
+ clearBucketMemberSlots(bucketSlotsArrayStore) {
3095
+ const bucketMemberSlots = bucketSlotsArrayStore.bucketMemberSlots;
3096
+ if (bucketMemberSlots.length !== 0) bucketMemberSlots.length = 0;
3097
+ bucketSlotsArrayStore.sortedCount = 0;
3640
3098
  }
3641
3099
  };
3100
+ _OIMBucketMemberSlotsArrayService.INSTANCE = new _OIMBucketMemberSlotsArrayService();
3101
+ var OIMBucketMemberSlotsArrayService = _OIMBucketMemberSlotsArrayService;
3102
+ function reverseRange(bucketMemberSlots, first, last) {
3103
+ for (let low = first, high = last; low < high; low++, high--) {
3104
+ const bucketMemberSlot = bucketMemberSlots[low];
3105
+ bucketMemberSlots[low] = bucketMemberSlots[high];
3106
+ bucketMemberSlots[high] = bucketMemberSlot;
3107
+ }
3108
+ }
3642
3109
 
3643
- // src/engine/bucket/commands/constants/OIM_MAX_COMMANDS_PER_SLOT.ts
3644
- var OIM_MAX_COMMANDS_PER_SLOT = 1;
3645
-
3646
- // src/facade/bucket/OIMBucketCommands.ts
3647
- var OIMBucketCommands = class {
3110
+ // src/facade/bucket/OIMSlotContentArrayBucketService.ts
3111
+ var OIMSlotContentArrayBucketService = class extends OIMSlotContentBucketService {
3648
3112
  constructor(options) {
3649
- this.maxCommandsPerSlot = options.maxCommandsPerSlot ?? OIM_MAX_COMMANDS_PER_SLOT;
3113
+ super(options);
3114
+ this.bucketMemberSlotsArrayService = options.bucketMemberSlotsArrayService ?? OIMBucketMemberSlotsArrayService.INSTANCE;
3650
3115
  }
3651
- recordInsert(bucketSlot, index, bucketMemberSlot, bucketMemberSlotCount) {
3652
- this.recordCommand(bucketSlot, { type: "insert", index, slot: bucketMemberSlot }, bucketMemberSlotCount);
3116
+ createBucketMemberSlotsStore() {
3117
+ return this.bucketMemberSlotsArrayService.createBucketSlotsArrayStore();
3653
3118
  }
3654
- recordRemove(bucketSlot, index, count, bucketMemberSlotCount) {
3655
- for (let i = 0; i < count; i++) this.recordCommand(bucketSlot, { type: "remove", index }, bucketMemberSlotCount);
3119
+ addSlot(bucketSlot, bucketMemberSlot) {
3120
+ return this.bucketMemberSlotsArrayService.appendBucketMemberSlot(bucketSlot.bucketSlotsStore, bucketMemberSlot);
3656
3121
  }
3657
- recordMove(bucketSlot, from, to, bucketMemberSlotCount) {
3658
- this.recordCommand(bucketSlot, { type: "move", from, to }, bucketMemberSlotCount);
3122
+ removeSlot(bucketSlot, bucketMemberSlot) {
3123
+ return this.bucketMemberSlotsArrayService.removeBucketMemberSlot(bucketSlot.bucketSlotsStore, bucketMemberSlot);
3659
3124
  }
3660
- recordWholeList(bucketSlot) {
3661
- const bucketSlotEditable = enlistInFlush(bucketSlot);
3662
- const commands = bucketSlotEditable.commands;
3663
- if (commands !== void 0 && commands.length !== 0) commands.length = 0;
3664
- bucketSlotEditable.isWholeListRecorded = true;
3125
+ removeSlots(bucketSlot, bucketMemberSlots, removedChannelQueue, removedAtChannelQueue) {
3126
+ this.bucketMemberSlotsArrayService.removeBucketMemberSlots(
3127
+ bucketSlot.bucketSlotsStore,
3128
+ bucketMemberSlots,
3129
+ removedChannelQueue,
3130
+ removedAtChannelQueue
3131
+ );
3665
3132
  }
3666
- recordCommand(bucketSlot, orderedListCommand, bucketMemberSlotCount) {
3667
- const bucketSlotEditable = enlistInFlush(bucketSlot);
3668
- if (bucketSlotEditable.isWholeListRecorded) return;
3669
- const commands = bucketSlotEditable.commands ?? (bucketSlotEditable.commands = []);
3670
- commands.push(orderedListCommand);
3671
- if (commands.length > this.maxCommandsPerSlot * bucketMemberSlotCount) {
3672
- commands.length = 0;
3673
- bucketSlotEditable.isWholeListRecorded = true;
3133
+ reconcileSlots(bucketSlot, bucketMemberSlots, arrivedChannelQueue, departedChannelQueue) {
3134
+ const bucketMemberSlotsArrayService = this.bucketMemberSlotsArrayService;
3135
+ const bucketSlotsArrayStore = bucketSlot.bucketSlotsStore;
3136
+ if (bucketMemberSlotsArrayService.isSameBucketMemberSlotSequence(bucketSlotsArrayStore, bucketMemberSlots)) return;
3137
+ arrivedChannelQueue.keepFirstEntries(0);
3138
+ departedChannelQueue.keepFirstEntries(0);
3139
+ const heldBucketMemberSlots = bucketSlotsArrayStore.bucketMemberSlots;
3140
+ for (let i = 0; i < heldBucketMemberSlots.length; i++) departedChannelQueue.enqueueEntry(heldBucketMemberSlots[i]);
3141
+ bucketMemberSlotsArrayService.clearBucketMemberSlots(bucketSlotsArrayStore);
3142
+ for (let i = 0; i < bucketMemberSlots.length; i++) {
3143
+ if (bucketMemberSlotsArrayService.appendBucketMemberSlot(bucketSlotsArrayStore, bucketMemberSlots[i])) {
3144
+ arrivedChannelQueue.enqueueEntry(bucketMemberSlots[i]);
3145
+ }
3674
3146
  }
3675
3147
  }
3676
- };
3677
- function enlistInFlush(bucketSlot) {
3678
- const bucketSlotEditable = bucketSlot;
3679
- const storeSlot = bucketSlot.storeSlot;
3680
- const channelSlot = storeSlot.channelSlot;
3681
- const commands = bucketSlotEditable.commands;
3682
- const hasScript = commands !== void 0 && commands.length > 0 || bucketSlotEditable.isWholeListRecorded;
3683
- if (hasScript && !isScriptStale(channelSlot, bucketSlotEditable)) return bucketSlotEditable;
3684
- if (hasScript) {
3685
- clearScript(bucketSlotEditable);
3686
- } else {
3687
- const commandsBucketSlotChannelQueue = storeSlot.commandsBucketSlotChannelQueue ?? (storeSlot.commandsBucketSlotChannelQueue = new OIMChannelQueue());
3688
- if (commandsBucketSlotChannelQueue.getEntryCount() === 0) getCommandsStoreSlotChannelQueue(channelSlot).enqueueEntry(storeSlot);
3689
- commandsBucketSlotChannelQueue.enqueueEntry(bucketSlotEditable);
3148
+ drainSlots(bucketSlot, departedChannelQueue) {
3149
+ const bucketSlotsArrayStore = bucketSlot.bucketSlotsStore;
3150
+ const heldBucketMemberSlots = bucketSlotsArrayStore.bucketMemberSlots;
3151
+ for (let i = 0; i < heldBucketMemberSlots.length; i++) departedChannelQueue.enqueueEntry(heldBucketMemberSlots[i]);
3152
+ this.bucketMemberSlotsArrayService.clearBucketMemberSlots(bucketSlotsArrayStore);
3690
3153
  }
3691
- const clock = channelSlot.clock;
3692
- bucketSlotEditable.commandsStartedAtRevision = clock.revision;
3693
- bucketSlotEditable.commandsStartedAtEpoch = clock.epoch;
3694
- return bucketSlotEditable;
3695
- }
3696
- function getCommandsStoreSlotChannelQueue(channelSlot) {
3697
- const commandsStoreSlotChannelQueue = channelSlot.commandsStoreSlotChannelQueue;
3698
- if (commandsStoreSlotChannelQueue !== void 0) return commandsStoreSlotChannelQueue;
3699
- const createdCommandsStoreSlotChannelQueue = new OIMChannelQueue();
3700
- channelSlot.commandsStoreSlotChannelQueue = createdCommandsStoreSlotChannelQueue;
3701
- OIMChannelService.INSTANCE.subscribeAfterEachFlush(channelSlot, () => {
3702
- clearStaleScripts(channelSlot, createdCommandsStoreSlotChannelQueue);
3703
- });
3704
- return createdCommandsStoreSlotChannelQueue;
3705
- }
3706
- function isScriptStale(channelSlot, bucketSlot) {
3707
- const frame = channelSlot.frame;
3708
- return oimIsRevisionAfter(
3709
- frame.openedAtRevision,
3710
- frame.openedAtEpoch,
3711
- bucketSlot.commandsStartedAtRevision,
3712
- bucketSlot.commandsStartedAtEpoch
3713
- );
3714
- }
3715
- function clearScript(bucketSlotEditable) {
3716
- const commands = bucketSlotEditable.commands;
3717
- if (commands !== void 0 && commands.length !== 0) commands.length = 0;
3718
- bucketSlotEditable.isWholeListRecorded = false;
3719
- }
3720
- function clearStaleScripts(channelSlot, commandsStoreSlotChannelQueue) {
3721
- let keptStoreSlotCount = 0;
3722
- for (let i = 0; i < commandsStoreSlotChannelQueue.getEntryCount(); i++) {
3723
- const storeSlot = commandsStoreSlotChannelQueue.getEntryAt(i);
3724
- const commandsBucketSlotChannelQueue = storeSlot.commandsBucketSlotChannelQueue;
3725
- let keptBucketSlotCount = 0;
3726
- for (let j = 0; j < commandsBucketSlotChannelQueue.getEntryCount(); j++) {
3727
- const bucketSlotEditable = commandsBucketSlotChannelQueue.getEntryAt(j);
3728
- if (!isScriptStale(channelSlot, bucketSlotEditable)) {
3729
- commandsBucketSlotChannelQueue.setEntryAt(keptBucketSlotCount++, bucketSlotEditable);
3730
- continue;
3731
- }
3732
- clearScript(bucketSlotEditable);
3733
- }
3734
- commandsBucketSlotChannelQueue.keepFirstEntries(keptBucketSlotCount);
3735
- if (keptBucketSlotCount !== 0) commandsStoreSlotChannelQueue.setEntryAt(keptStoreSlotCount++, storeSlot);
3154
+ hasBucketMemberSlot(bucketSlot, bucketMemberSlot) {
3155
+ return this.bucketMemberSlotsArrayService.hasBucketMemberSlot(bucketSlot.bucketSlotsStore, bucketMemberSlot);
3736
3156
  }
3737
- commandsStoreSlotChannelQueue.keepFirstEntries(keptStoreSlotCount);
3738
- }
3157
+ getBucketMemberSlotCount(bucketSlot) {
3158
+ return bucketSlot.bucketSlotsStore.bucketMemberSlots.length;
3159
+ }
3160
+ getBucketMemberSlots(bucketSlot) {
3161
+ return bucketSlot.bucketSlotsStore.bucketMemberSlots;
3162
+ }
3163
+ getBucketMemberSlotAt(bucketSlot, at) {
3164
+ return bucketSlot.bucketSlotsStore.bucketMemberSlots[at];
3165
+ }
3166
+ getBucketMemberSlotPosition(bucketSlot, bucketMemberSlot) {
3167
+ return bucketSlot.bucketSlotsStore.bucketMemberSlots.indexOf(bucketMemberSlot);
3168
+ }
3169
+ };
3739
3170
 
3740
- // src/factories/utils/createOIMBucketSlotOwnerService.ts
3741
- function createOIMBucketSlotOwnerService(db, options) {
3742
- return options.slotContentService.createSlotOwnerService({
3743
- slotStamp: db.slotStamp,
3744
- slotReleasePolicy: options.slotReleasePolicy ?? db.slotReleasePolicy,
3745
- slotStoreService: options.slotStoreService,
3746
- columnOwnerOptions: oimColumnOwnerOptionsWithDefault(
3747
- options.columnSlotStoreService,
3748
- options.columnNames,
3749
- OIM_DEFAULT_COLUMN_SLOT_STORE_SERVICE.getValue()
3750
- ),
3751
- createColumnOwner: createOIMColumnOwnerPushDriven
3752
- });
3171
+ // src/engine/bucket/constants/OIM_NOTHING_WAS_INSERTED.ts
3172
+ var OIM_NOTHING_WAS_INSERTED = -1;
3173
+
3174
+ // src/engine/bucket/array/utils/oimAssertWholePosition.ts
3175
+ function oimAssertWholePosition(position) {
3176
+ if (position === Math.trunc(position)) return;
3177
+ throw new Error(
3178
+ `OIMSlotContentPositionalArrayBucketService: a position must be a whole number, got ${position}. A fraction or NaN would be read one way by the list and another by splice.`
3179
+ );
3753
3180
  }
3754
3181
 
3755
- // src/factories/createOIMBucketService.ts
3756
- function createOIMBucketService(db, ...[options = {}]) {
3757
- const slotStoreService = oimSlotStoreServiceWithDefault(options.bucketSlotStoreService);
3758
- const slotContentService = options.slotContentService ?? new OIMSlotContentBucketServiceArrayDriven({
3759
- bucketCommands: new OIMBucketCommands({ maxCommandsPerSlot: options.maxCommandsPerSlot })
3760
- });
3761
- return new OIMSlotCollectionService({
3762
- slotOwnerService: createOIMBucketSlotOwnerService(db, {
3763
- slotStoreService,
3764
- slotContentService,
3765
- slotReleasePolicy: options.slotReleasePolicy,
3766
- columnSlotStoreService: options.columnSlotStoreService,
3767
- columnNames: options.columnNames
3768
- }),
3769
- slotStoreService,
3770
- slotContentService,
3771
- storeSlotListener: OIM_DEFAULT_STORE_SLOT_LISTENER.getValue()
3772
- });
3182
+ // src/facade/bucket/OIMSlotContentPositionalArrayBucketService.ts
3183
+ var OIMSlotContentPositionalArrayBucketService = class extends OIMSlotContentArrayBucketService {
3184
+ constructor(options = {}) {
3185
+ super(options);
3186
+ }
3187
+ insertBucketMemberSlotAt(bucketSlot, at, bucketMemberSlot) {
3188
+ const slotOwnerService = bucketSlot.owner;
3189
+ slotOwnerService.assertWritable(bucketSlot);
3190
+ oimAssertWholePosition(at);
3191
+ this.assertBucketMemberSlotNotReleased(bucketMemberSlot);
3192
+ const bucketSlotsArrayStore = bucketSlot.bucketSlotsStore;
3193
+ const landing = this.bucketMemberSlotsArrayService.insertBucketMemberSlotAt(bucketSlotsArrayStore, at, bucketMemberSlot);
3194
+ if (landing === OIM_NOTHING_WAS_INSERTED) return;
3195
+ bucketMemberSlot.owner.holdSlot(bucketMemberSlot);
3196
+ this.bucketCommands.recordInsert(bucketSlot, landing, bucketMemberSlot, bucketSlotsArrayStore.bucketMemberSlots.length);
3197
+ this.markBucketSlotChanged(bucketSlot);
3198
+ }
3199
+ removeBucketMemberSlotAt(bucketSlot, at) {
3200
+ const slotOwnerService = bucketSlot.owner;
3201
+ slotOwnerService.assertWritable(bucketSlot);
3202
+ oimAssertWholePosition(at);
3203
+ const bucketSlotsArrayStore = bucketSlot.bucketSlotsStore;
3204
+ if (at < 0 || at >= bucketSlotsArrayStore.bucketMemberSlots.length) return void 0;
3205
+ const removedBucketMemberSlot = this.bucketMemberSlotsArrayService.removeBucketMemberSlotAt(bucketSlotsArrayStore, at);
3206
+ oimUnholdSlotIfAlive(removedBucketMemberSlot);
3207
+ this.bucketCommands.recordRemove(bucketSlot, at, 1, bucketSlotsArrayStore.bucketMemberSlots.length);
3208
+ this.markBucketSlotChanged(bucketSlot);
3209
+ return removedBucketMemberSlot;
3210
+ }
3211
+ removeBucketMemberSlotRange(bucketSlot, at, count) {
3212
+ const slotOwnerService = bucketSlot.owner;
3213
+ slotOwnerService.assertWritable(bucketSlot);
3214
+ oimAssertWholePosition(at);
3215
+ oimAssertWholePosition(count);
3216
+ const bucketSlotsArrayStore = bucketSlot.bucketSlotsStore;
3217
+ if (at < 0 || count <= 0 || at >= bucketSlotsArrayStore.bucketMemberSlots.length) return OIM_FROZEN_EMPTY_SLOTS;
3218
+ const removedBucketMemberSlots = this.bucketMemberSlotsArrayService.removeBucketMemberSlotRange(bucketSlotsArrayStore, at, count);
3219
+ for (let i = 0; i < removedBucketMemberSlots.length; i++) oimUnholdSlotIfAlive(removedBucketMemberSlots[i]);
3220
+ this.bucketCommands.recordRemove(bucketSlot, at, removedBucketMemberSlots.length, bucketSlotsArrayStore.bucketMemberSlots.length);
3221
+ this.markBucketSlotChanged(bucketSlot);
3222
+ return removedBucketMemberSlots;
3223
+ }
3224
+ moveBucketMemberSlotToPosition(bucketSlot, from, to) {
3225
+ const slotOwnerService = bucketSlot.owner;
3226
+ slotOwnerService.assertWritable(bucketSlot);
3227
+ oimAssertWholePosition(from);
3228
+ oimAssertWholePosition(to);
3229
+ const bucketSlotsArrayStore = bucketSlot.bucketSlotsStore;
3230
+ const bucketMemberSlotCount = bucketSlotsArrayStore.bucketMemberSlots.length;
3231
+ if (from < 0 || from >= bucketMemberSlotCount || to < 0 || to >= bucketMemberSlotCount || from === to) return void 0;
3232
+ if (!this.bucketMemberSlotsArrayService.moveBucketMemberSlotRange(bucketSlotsArrayStore, from, 1, to)) return void 0;
3233
+ this.bucketCommands.recordMove(bucketSlot, from, to, bucketMemberSlotCount);
3234
+ this.markBucketSlotChanged(bucketSlot);
3235
+ return bucketSlotsArrayStore.bucketMemberSlots[to];
3236
+ }
3237
+ moveBucketMemberSlotRangeToPosition(bucketSlot, from, count, to) {
3238
+ const slotOwnerService = bucketSlot.owner;
3239
+ slotOwnerService.assertWritable(bucketSlot);
3240
+ oimAssertWholePosition(from);
3241
+ oimAssertWholePosition(count);
3242
+ oimAssertWholePosition(to);
3243
+ const bucketSlotsArrayStore = bucketSlot.bucketSlotsStore;
3244
+ const bucketMemberSlotCount = bucketSlotsArrayStore.bucketMemberSlots.length;
3245
+ if (from < 0 || count <= 0 || from >= bucketMemberSlotCount) return;
3246
+ const taking = from + count > bucketMemberSlotCount ? bucketMemberSlotCount - from : count;
3247
+ const remaining = bucketMemberSlotCount - taking;
3248
+ const landing = to < 0 ? 0 : to > remaining ? remaining : to;
3249
+ if (!this.bucketMemberSlotsArrayService.moveBucketMemberSlotRange(bucketSlotsArrayStore, from, taking, landing)) return;
3250
+ this.bucketCommands.recordWholeList(bucketSlot);
3251
+ this.markBucketSlotChanged(bucketSlot);
3252
+ }
3253
+ };
3254
+
3255
+ // src/engine/bucket/utils/oimSameUniqueSlotSequence.ts
3256
+ function oimSameUniqueSlotSequence(heldBucketMemberSlots, bucketMemberSlots) {
3257
+ const seenBucketMemberSlots = /* @__PURE__ */ new Set();
3258
+ let at = 0;
3259
+ for (let i = 0; i < bucketMemberSlots.length; i++) {
3260
+ const bucketMemberSlot = bucketMemberSlots[i];
3261
+ if (seenBucketMemberSlots.has(bucketMemberSlot)) continue;
3262
+ seenBucketMemberSlots.add(bucketMemberSlot);
3263
+ if (at >= heldBucketMemberSlots.length || heldBucketMemberSlots[at] !== bucketMemberSlot) return false;
3264
+ at++;
3265
+ }
3266
+ return at === heldBucketMemberSlots.length;
3773
3267
  }
3774
3268
 
3775
- // src/factories/createOIMSingleBucketService.ts
3776
- function createOIMSingleBucketService(db, options = {}) {
3777
- const slotStoreService = OIMSlotStoreServiceSingleSlotDriven.INSTANCE;
3778
- const slotContentService = options.slotContentService ?? new OIMSlotContentBucketServiceArrayDriven({
3779
- bucketCommands: new OIMBucketCommands({ maxCommandsPerSlot: options.maxCommandsPerSlot })
3780
- });
3781
- return new OIMSingleSlotService({
3782
- slotOwnerService: createOIMBucketSlotOwnerService(db, {
3783
- slotStoreService,
3784
- slotContentService,
3785
- slotReleasePolicy: options.slotReleasePolicy,
3786
- columnSlotStoreService: options.columnSlotStoreService,
3787
- columnNames: options.columnNames
3788
- }),
3789
- slotStoreService,
3790
- slotContentService,
3791
- storeSlotListener: OIM_DEFAULT_STORE_SLOT_LISTENER.getValue()
3792
- });
3269
+ // src/engine/bucket/array/OIMBucketUniqueMemberSlotsArrayService.ts
3270
+ var _OIMBucketUniqueMemberSlotsArrayService = class _OIMBucketUniqueMemberSlotsArrayService extends OIMBucketMemberSlotsArrayService {
3271
+ createBucketSlotsArrayStore() {
3272
+ return { bucketMemberSlots: [], uniqueBucketMemberSlots: /* @__PURE__ */ new Set(), sortedCount: 0 };
3273
+ }
3274
+ hasBucketMemberSlot(bucketSlotsArrayStore, bucketMemberSlot) {
3275
+ return uniqueBucketMemberSlotsOf(bucketSlotsArrayStore).has(bucketMemberSlot);
3276
+ }
3277
+ appendBucketMemberSlot(bucketSlotsArrayStore, bucketMemberSlot) {
3278
+ const uniqueBucketMemberSlots = uniqueBucketMemberSlotsOf(bucketSlotsArrayStore);
3279
+ if (uniqueBucketMemberSlots.has(bucketMemberSlot)) return false;
3280
+ uniqueBucketMemberSlots.add(bucketMemberSlot);
3281
+ return super.appendBucketMemberSlot(bucketSlotsArrayStore, bucketMemberSlot);
3282
+ }
3283
+ insertBucketMemberSlotAt(bucketSlotsArrayStore, at, bucketMemberSlot) {
3284
+ const uniqueBucketMemberSlots = uniqueBucketMemberSlotsOf(bucketSlotsArrayStore);
3285
+ if (uniqueBucketMemberSlots.has(bucketMemberSlot)) return OIM_NOTHING_WAS_INSERTED;
3286
+ uniqueBucketMemberSlots.add(bucketMemberSlot);
3287
+ return super.insertBucketMemberSlotAt(bucketSlotsArrayStore, at, bucketMemberSlot);
3288
+ }
3289
+ removeBucketMemberSlot(bucketSlotsArrayStore, bucketMemberSlot) {
3290
+ if (!uniqueBucketMemberSlotsOf(bucketSlotsArrayStore).delete(bucketMemberSlot)) return OIM_NOTHING_WAS_REMOVED;
3291
+ return super.removeBucketMemberSlot(bucketSlotsArrayStore, bucketMemberSlot);
3292
+ }
3293
+ removeBucketMemberSlotAt(bucketSlotsArrayStore, at) {
3294
+ const removedBucketMemberSlot = super.removeBucketMemberSlotAt(bucketSlotsArrayStore, at);
3295
+ uniqueBucketMemberSlotsOf(bucketSlotsArrayStore).delete(removedBucketMemberSlot);
3296
+ return removedBucketMemberSlot;
3297
+ }
3298
+ removeBucketMemberSlotRange(bucketSlotsArrayStore, at, count) {
3299
+ const removedBucketMemberSlots = super.removeBucketMemberSlotRange(bucketSlotsArrayStore, at, count);
3300
+ const uniqueBucketMemberSlots = uniqueBucketMemberSlotsOf(bucketSlotsArrayStore);
3301
+ for (let i = 0; i < removedBucketMemberSlots.length; i++) uniqueBucketMemberSlots.delete(removedBucketMemberSlots[i]);
3302
+ return removedBucketMemberSlots;
3303
+ }
3304
+ removeBucketMemberSlots(bucketSlotsArrayStore, bucketMemberSlots, removedChannelQueue, removedAtChannelQueue) {
3305
+ const removedCountBefore = removedChannelQueue.getEntryCount();
3306
+ super.removeBucketMemberSlots(bucketSlotsArrayStore, bucketMemberSlots, removedChannelQueue, removedAtChannelQueue);
3307
+ const uniqueBucketMemberSlots = uniqueBucketMemberSlotsOf(bucketSlotsArrayStore);
3308
+ for (let i = removedCountBefore; i < removedChannelQueue.getEntryCount(); i++) {
3309
+ uniqueBucketMemberSlots.delete(removedChannelQueue.getEntryAt(i));
3310
+ }
3311
+ }
3312
+ isSameBucketMemberSlotSequence(bucketSlotsArrayStore, bucketMemberSlots) {
3313
+ const heldBucketMemberSlots = bucketSlotsArrayStore.bucketMemberSlots;
3314
+ if (bucketMemberSlots.length < heldBucketMemberSlots.length) return false;
3315
+ return oimSameUniqueSlotSequence(heldBucketMemberSlots, bucketMemberSlots);
3316
+ }
3317
+ clearBucketMemberSlots(bucketSlotsArrayStore) {
3318
+ super.clearBucketMemberSlots(bucketSlotsArrayStore);
3319
+ uniqueBucketMemberSlotsOf(bucketSlotsArrayStore).clear();
3320
+ }
3321
+ };
3322
+ _OIMBucketUniqueMemberSlotsArrayService.INSTANCE = new _OIMBucketUniqueMemberSlotsArrayService();
3323
+ var OIMBucketUniqueMemberSlotsArrayService = _OIMBucketUniqueMemberSlotsArrayService;
3324
+ function uniqueBucketMemberSlotsOf(bucketSlotsArrayStore) {
3325
+ return bucketSlotsArrayStore.uniqueBucketMemberSlots;
3793
3326
  }
3794
3327
 
3328
+ // src/facade/bucket/OIMSlotContentSortedArrayBucketService.ts
3329
+ var OIMSlotContentSortedArrayBucketService = class extends OIMSlotContentArrayBucketService {
3330
+ constructor(options) {
3331
+ super(options);
3332
+ this.compareBucketMemberSlots = options.compareBucketMemberSlots;
3333
+ }
3334
+ drainSlots(bucketSlot, departedChannelQueue) {
3335
+ this.bucketMemberSlotsArrayService.sortBucketMemberSlots(bucketSlot.bucketSlotsStore, this.compareBucketMemberSlots);
3336
+ super.drainSlots(bucketSlot, departedChannelQueue);
3337
+ }
3338
+ getBucketMemberSlots(bucketSlot) {
3339
+ this.bucketMemberSlotsArrayService.sortBucketMemberSlots(bucketSlot.bucketSlotsStore, this.compareBucketMemberSlots);
3340
+ return super.getBucketMemberSlots(bucketSlot);
3341
+ }
3342
+ getBucketMemberSlotAt(bucketSlot, at) {
3343
+ this.bucketMemberSlotsArrayService.sortBucketMemberSlots(bucketSlot.bucketSlotsStore, this.compareBucketMemberSlots);
3344
+ return super.getBucketMemberSlotAt(bucketSlot, at);
3345
+ }
3346
+ getBucketMemberSlotPosition(bucketSlot, bucketMemberSlot) {
3347
+ this.bucketMemberSlotsArrayService.sortBucketMemberSlots(bucketSlot.bucketSlotsStore, this.compareBucketMemberSlots);
3348
+ return super.getBucketMemberSlotPosition(bucketSlot, bucketMemberSlot);
3349
+ }
3350
+ repositionBucketMemberSlot(bucketSlot, bucketMemberSlot) {
3351
+ const slotOwnerService = bucketSlot.owner;
3352
+ slotOwnerService.assertWritable(bucketSlot);
3353
+ if (this.removeSlot(bucketSlot, bucketMemberSlot) === OIM_NOTHING_WAS_REMOVED) return;
3354
+ if (this.addSlot(bucketSlot, bucketMemberSlot)) this.markBucketSlotChanged(bucketSlot);
3355
+ }
3356
+ };
3357
+
3795
3358
  // src/factories/defaults/OIM_DEFAULT_COMPUTED_COLUMN_SLOT_STORE_SERVICE.ts
3796
- var OIM_DEFAULT_COMPUTED_COLUMN_SLOT_STORE_SERVICE = /* @__PURE__ */ new OIMDefaultValue("COMPUTED_COLUMN_SLOT_STORE_SERVICE", () => OIMSlotStoreServiceMapDriven.INSTANCE);
3359
+ var OIM_DEFAULT_COMPUTED_COLUMN_SLOT_STORE_SERVICE = /* @__PURE__ */ new OIMDefaultValue("COMPUTED_COLUMN_SLOT_STORE_SERVICE", () => OIMSlotMapStoreService.INSTANCE);
3797
3360
 
3798
3361
  // src/engine/index/OIMIndexKeysService.ts
3799
3362
  var OIMIndexKeysService = class {
@@ -3824,8 +3387,8 @@ var OIMIndexKeysService = class {
3824
3387
  }
3825
3388
  };
3826
3389
 
3827
- // src/engine/index/OIMIndexKeysServiceAppending.ts
3828
- var _OIMIndexKeysServiceAppending = class _OIMIndexKeysServiceAppending extends OIMIndexKeysService {
3390
+ // src/engine/index/OIMAppendingIndexKeysService.ts
3391
+ var _OIMAppendingIndexKeysService = class _OIMAppendingIndexKeysService extends OIMIndexKeysService {
3829
3392
  allocatePosition(positions) {
3830
3393
  return positions.nextPosition++;
3831
3394
  }
@@ -3833,11 +3396,11 @@ var _OIMIndexKeysServiceAppending = class _OIMIndexKeysServiceAppending extends
3833
3396
  return;
3834
3397
  }
3835
3398
  };
3836
- _OIMIndexKeysServiceAppending.INSTANCE = new _OIMIndexKeysServiceAppending();
3837
- var OIMIndexKeysServiceAppending = _OIMIndexKeysServiceAppending;
3399
+ _OIMAppendingIndexKeysService.INSTANCE = new _OIMAppendingIndexKeysService();
3400
+ var OIMAppendingIndexKeysService = _OIMAppendingIndexKeysService;
3838
3401
 
3839
3402
  // src/factories/defaults/OIM_DEFAULT_INDEX_KEYS_SERVICE.ts
3840
- var OIM_DEFAULT_INDEX_KEYS_SERVICE = /* @__PURE__ */ new OIMDefaultValue("INDEX_KEYS_SERVICE", () => OIMIndexKeysServiceAppending.INSTANCE);
3403
+ var OIM_DEFAULT_INDEX_KEYS_SERVICE = /* @__PURE__ */ new OIMDefaultValue("INDEX_KEYS_SERVICE", () => OIMAppendingIndexKeysService.INSTANCE);
3841
3404
 
3842
3405
  // src/engine/key/OIMKeyTreeWalk.ts
3843
3406
  var OIMKeyTreeWalk = class {
@@ -3905,8 +3468,8 @@ var OIMKeyTreeWalk = class {
3905
3468
  }
3906
3469
  };
3907
3470
 
3908
- // src/engine/key/OIMKeyTreeWalkComposite.ts
3909
- var _OIMKeyTreeWalkComposite = class _OIMKeyTreeWalkComposite extends OIMKeyTreeWalk {
3471
+ // src/engine/key/OIMCompositeKeyTreeWalk.ts
3472
+ var _OIMCompositeKeyTreeWalk = class _OIMCompositeKeyTreeWalk extends OIMKeyTreeWalk {
3910
3473
  holdCompositeKeyPart(entitySlot) {
3911
3474
  entitySlot.owner.holdSlot(entitySlot);
3912
3475
  }
@@ -3914,14 +3477,14 @@ var _OIMKeyTreeWalkComposite = class _OIMKeyTreeWalkComposite extends OIMKeyTree
3914
3477
  oimUnholdSlotIfAlive(entitySlot);
3915
3478
  }
3916
3479
  };
3917
- _OIMKeyTreeWalkComposite.INSTANCE = new _OIMKeyTreeWalkComposite();
3918
- var OIMKeyTreeWalkComposite = _OIMKeyTreeWalkComposite;
3480
+ _OIMCompositeKeyTreeWalk.INSTANCE = new _OIMCompositeKeyTreeWalk();
3481
+ var OIMCompositeKeyTreeWalk = _OIMCompositeKeyTreeWalk;
3919
3482
 
3920
3483
  // src/factories/defaults/OIM_DEFAULT_KEY_TREE_WALK_COMPOSITE.ts
3921
- var OIM_DEFAULT_KEY_TREE_WALK_COMPOSITE = /* @__PURE__ */ new OIMDefaultValue("KEY_TREE_WALK_COMPOSITE", () => OIMKeyTreeWalkComposite.INSTANCE);
3484
+ var OIM_DEFAULT_KEY_TREE_WALK_COMPOSITE = /* @__PURE__ */ new OIMDefaultValue("KEY_TREE_WALK_COMPOSITE", () => OIMCompositeKeyTreeWalk.INSTANCE);
3922
3485
 
3923
- // src/engine/key/OIMKeyTreeWalkScalar.ts
3924
- var _OIMKeyTreeWalkScalar = class _OIMKeyTreeWalkScalar extends OIMKeyTreeWalk {
3486
+ // src/engine/key/OIMScalarKeyTreeWalk.ts
3487
+ var _OIMScalarKeyTreeWalk = class _OIMScalarKeyTreeWalk extends OIMKeyTreeWalk {
3925
3488
  holdCompositeKeyPart() {
3926
3489
  return;
3927
3490
  }
@@ -3929,11 +3492,11 @@ var _OIMKeyTreeWalkScalar = class _OIMKeyTreeWalkScalar extends OIMKeyTreeWalk {
3929
3492
  return;
3930
3493
  }
3931
3494
  };
3932
- _OIMKeyTreeWalkScalar.INSTANCE = new _OIMKeyTreeWalkScalar();
3933
- var OIMKeyTreeWalkScalar = _OIMKeyTreeWalkScalar;
3495
+ _OIMScalarKeyTreeWalk.INSTANCE = new _OIMScalarKeyTreeWalk();
3496
+ var OIMScalarKeyTreeWalk = _OIMScalarKeyTreeWalk;
3934
3497
 
3935
3498
  // src/factories/defaults/OIM_DEFAULT_KEY_TREE_WALK_SCALAR.ts
3936
- var OIM_DEFAULT_KEY_TREE_WALK_SCALAR = /* @__PURE__ */ new OIMDefaultValue("KEY_TREE_WALK_SCALAR", () => OIMKeyTreeWalkScalar.INSTANCE);
3499
+ var OIM_DEFAULT_KEY_TREE_WALK_SCALAR = /* @__PURE__ */ new OIMDefaultValue("KEY_TREE_WALK_SCALAR", () => OIMScalarKeyTreeWalk.INSTANCE);
3937
3500
 
3938
3501
  // src/factories/defaults/OIM_DEFAULT_STANDALONE_SLOT_OWNER.ts
3939
3502
  var OIM_DEFAULT_STANDALONE_SLOT_OWNER = /* @__PURE__ */ new OIMDefaultValue("STANDALONE_SLOT_OWNER", () => new OIMSlotOwner());
@@ -3951,8 +3514,8 @@ OIMDefaults.ENTITY_SLOT_EMPTINESS = OIM_DEFAULT_ENTITY_SLOT_EMPTINESS;
3951
3514
  OIMDefaults.INDEX_KEYS_SERVICE = OIM_DEFAULT_INDEX_KEYS_SERVICE;
3952
3515
  OIMDefaults.STORE_SLOT_LISTENER = OIM_DEFAULT_STORE_SLOT_LISTENER;
3953
3516
 
3954
- // src/engine/column/utils/createOIMColumnOwnerPullDriven.ts
3955
- var createOIMColumnOwnerPullDriven = (columnOwnerOptions) => new OIMColumnOwnerPullDriven(columnOwnerOptions);
3517
+ // src/engine/column/utils/createOIMPullColumnSlotOwner.ts
3518
+ var createOIMPullColumnSlotOwner = (columnSlotOwnerOptions) => new OIMPullColumnSlotOwner(columnSlotOwnerOptions);
3956
3519
 
3957
3520
  // src/engine/computed/OIMComputedSourcesService.ts
3958
3521
  var _OIMComputedSourcesService = class _OIMComputedSourcesService {
@@ -3970,29 +3533,58 @@ var _OIMComputedSourcesService = class _OIMComputedSourcesService {
3970
3533
  _OIMComputedSourcesService.INSTANCE = new _OIMComputedSourcesService();
3971
3534
  var OIMComputedSourcesService = _OIMComputedSourcesService;
3972
3535
 
3973
- // src/engine/computed/OIMSlotContentComputedStrategy.ts
3974
- var OIMSlotContentComputedStrategy = class {
3536
+ // src/engine/computed/utils/createOIMSingleComputedSlot.ts
3537
+ function createOIMSingleComputedSlot(owner, computedValueService, initialValue, storeSlot) {
3538
+ const singleComputedSlot = {
3539
+ effects: void 0,
3540
+ changedAtRevision: 0,
3541
+ changedAtEpoch: 0,
3542
+ effectEdges: void 0,
3543
+ holdCount: 0,
3544
+ releaseDueAfterWriteMs: -1,
3545
+ releaseDueAfterIdleMs: -1,
3546
+ releaseDueAfterUnholdMs: -1,
3547
+ slotFlags: OIM_SLOT_FLAG_EMPTY,
3548
+ columnSlotStore: void 0,
3549
+ storeSlot,
3550
+ owner,
3551
+ computedValueService,
3552
+ key: void 0,
3553
+ indexKeys: void 0,
3554
+ sourceSlots: OIM_FROZEN_EMPTY_COMPUTED_SLOTS,
3555
+ sourceComputeds: OIM_FROZEN_EMPTY_COMPUTED_SLOTS,
3556
+ value: initialValue,
3557
+ ranAtRevision: -1,
3558
+ ranAtEpoch: -1,
3559
+ checkedAtRevision: -1,
3560
+ checkedAtEpoch: -1,
3561
+ isDeriving: false,
3562
+ allRootSlots: void 0
3563
+ };
3564
+ return singleComputedSlot;
3565
+ }
3566
+
3567
+ // src/engine/computed/OIMSlotContentComputedService.ts
3568
+ var OIMSlotContentComputedService = class {
3975
3569
  constructor(options) {
3976
3570
  this.computedValueService = options.computedValueService;
3977
3571
  this.createSources = options.createSources;
3978
3572
  this.initialValue = options.initialValue;
3979
3573
  }
3980
- createSlot(key, storeSlot, slotOwnerService) {
3981
- const createSources = storeSlot?.createSources ?? this.createSources;
3982
- const computedSources = createSources(
3983
- key,
3984
- storeSlot
3985
- );
3574
+ createSlot(key, storeSlot, slotOwner) {
3986
3575
  const computedSlot = createOIMComputedSlot(
3987
3576
  key,
3988
- slotOwnerService,
3577
+ slotOwner,
3989
3578
  this.computedValueService,
3990
- computedSources.sourceSlots ?? OIM_FROZEN_EMPTY_COMPUTED_SLOTS,
3991
- computedSources.sourceComputeds ?? OIM_FROZEN_EMPTY_COMPUTED_SLOTS,
3992
3579
  this.initialValue,
3993
3580
  storeSlot
3994
3581
  );
3995
- OIMComputedSourcesService.INSTANCE.holdSources(computedSlot);
3582
+ this.attachSources(computedSlot, storeSlot);
3583
+ return computedSlot;
3584
+ }
3585
+ createSingleSlot(storeSlot, slotOwner) {
3586
+ const computedSlot = createOIMSingleComputedSlot(slotOwner, this.computedValueService, this.initialValue, storeSlot);
3587
+ this.attachSources(computedSlot, storeSlot);
3996
3588
  return computedSlot;
3997
3589
  }
3998
3590
  isSlotEmpty() {
@@ -4004,61 +3596,72 @@ var OIMSlotContentComputedStrategy = class {
4004
3596
  hasReference() {
4005
3597
  return false;
4006
3598
  }
3599
+ attachSources(computedSlot, storeSlot) {
3600
+ const createSources = storeSlot.createSources ?? this.createSources;
3601
+ const computedSources = createSources(computedSlot);
3602
+ const computedSlotEditable = computedSlot;
3603
+ computedSlotEditable.sourceSlots = computedSources.sourceSlots ?? OIM_FROZEN_EMPTY_COMPUTED_SLOTS;
3604
+ computedSlotEditable.sourceComputeds = computedSources.sourceComputeds ?? OIM_FROZEN_EMPTY_COMPUTED_SLOTS;
3605
+ OIMComputedSourcesService.INSTANCE.holdSources(computedSlot);
3606
+ }
4007
3607
  };
4008
3608
 
4009
3609
  // src/facade/computed/utils/createOIMComputedCollectionService.ts
4010
3610
  function createOIMComputedCollectionService(options) {
4011
- const slotOwnerService = new OIMSlotOwnerService({
4012
- slotReleasePolicy: options.slotReleasePolicy,
4013
- slotStoreService: options.computedSlotStoreService,
4014
- slotContentStrategy: new OIMSlotContentComputedStrategy(options),
4015
- columnOwnerOptions: options.columnOwnerOptions,
4016
- createColumnOwner: createOIMColumnOwnerPullDriven
4017
- });
4018
3611
  return new OIMSlotCollectionService({
4019
- slotOwnerService,
3612
+ slotReleasePolicy: options.slotReleasePolicy,
4020
3613
  slotStoreService: options.computedSlotStoreService,
4021
- slotContentService: options.computedValueService,
3614
+ slotContentService: new OIMSlotContentComputedService(options),
3615
+ columnSlotOwnerOptions: options.columnSlotOwnerOptions,
3616
+ createColumnSlotOwner: createOIMPullColumnSlotOwner,
4022
3617
  storeSlotListener: options.storeSlotListener
4023
3618
  });
4024
3619
  }
4025
3620
 
3621
+ // src/facade/computed/utils/oimAttachComputedDerivation.ts
3622
+ function oimAttachComputedDerivation(computedStoreSlot, hasServiceDerive, hasServiceCreateSources, derive, createSources) {
3623
+ if (derive === void 0 && !hasServiceDerive || createSources === void 0 && !hasServiceCreateSources) {
3624
+ throw new Error(
3625
+ "A computed store slot needs a derive and a createSources, from the store slot or from the service options. Pass the missing one when creating the store slot or to the service."
3626
+ );
3627
+ }
3628
+ const computedStoreSlotEditable = computedStoreSlot;
3629
+ computedStoreSlotEditable.derive = derive;
3630
+ computedStoreSlotEditable.createSources = createSources;
3631
+ return computedStoreSlot;
3632
+ }
3633
+
4026
3634
  // src/facade/computed/OIMComputedService.ts
4027
3635
  var OIMComputedService = class {
4028
3636
  constructor(options) {
4029
- const computedValueService = new OIMComputedValueService({
4030
- derive: options.derive,
4031
- sameValueGuard: options.sameValueGuard
4032
- });
4033
3637
  this.computedCollectionService = createOIMComputedCollectionService({
4034
- computedValueService,
3638
+ computedValueService: new OIMComputedValueService({
3639
+ derive: options.derive,
3640
+ sameValueGuard: options.sameValueGuard
3641
+ }),
4035
3642
  createSources: options.createSources,
4036
3643
  initialValue: options.initialValue,
4037
3644
  slotReleasePolicy: options.slotReleasePolicy,
4038
3645
  computedSlotStoreService: options.computedSlotStoreService,
4039
- columnOwnerOptions: options.columnOwnerOptions,
3646
+ columnSlotOwnerOptions: options.columnSlotOwnerOptions,
4040
3647
  storeSlotListener: options.storeSlotListener
4041
3648
  });
4042
3649
  this.hasDerive = options.derive !== void 0;
4043
3650
  this.hasCreateSources = options.createSources !== void 0;
4044
3651
  }
4045
3652
  createComputedStoreSlot(channelMap, derive, createSources) {
4046
- this.assertDeriveAndCreateSources(derive !== void 0, createSources !== void 0);
4047
- const computedStoreSlot = this.computedCollectionService.createStoreSlot(channelMap);
4048
- computedStoreSlot.derive = derive;
4049
- computedStoreSlot.createSources = createSources;
4050
- return computedStoreSlot;
4051
- }
4052
- assertDeriveAndCreateSources(hasStoreSlotDerive, hasStoreSlotCreateSources) {
4053
- if ((hasStoreSlotDerive || this.hasDerive) && (hasStoreSlotCreateSources || this.hasCreateSources)) return;
4054
- throw new Error(
4055
- "OIMComputedService: a computed store slot needs a derive and a createSources, from the store slot or from the service options. Pass the missing one to createComputedStoreSlot or to the service."
3653
+ return oimAttachComputedDerivation(
3654
+ this.computedCollectionService.createStoreSlot(channelMap),
3655
+ this.hasDerive,
3656
+ this.hasCreateSources,
3657
+ derive,
3658
+ createSources
4056
3659
  );
4057
3660
  }
4058
3661
  };
4059
3662
 
4060
- // src/engine/collector/OIMSlotReleasePolicyAtUnhold.ts
4061
- var _OIMSlotReleasePolicyAtUnhold = class _OIMSlotReleasePolicyAtUnhold {
3663
+ // src/engine/collector/OIMSlotAtUnholdReleasePolicy.ts
3664
+ var _OIMSlotAtUnholdReleasePolicy = class _OIMSlotAtUnholdReleasePolicy {
4062
3665
  constructor() {
4063
3666
  this.releasesWrittenSlots = true;
4064
3667
  this.schedulesReleaseOnWrite = false;
@@ -4082,19 +3685,68 @@ var _OIMSlotReleasePolicyAtUnhold = class _OIMSlotReleasePolicyAtUnhold {
4082
3685
  return;
4083
3686
  }
4084
3687
  };
4085
- _OIMSlotReleasePolicyAtUnhold.INSTANCE = new _OIMSlotReleasePolicyAtUnhold();
4086
- var OIMSlotReleasePolicyAtUnhold = _OIMSlotReleasePolicyAtUnhold;
3688
+ _OIMSlotAtUnholdReleasePolicy.INSTANCE = new _OIMSlotAtUnholdReleasePolicy();
3689
+ var OIMSlotAtUnholdReleasePolicy = _OIMSlotAtUnholdReleasePolicy;
4087
3690
 
4088
3691
  // src/factories/createOIMComputedService.ts
4089
3692
  function createOIMComputedService(options) {
4090
3693
  return new OIMComputedService({
4091
3694
  computedSlotStoreService: oimSlotStoreServiceWithDefault(options.computedSlotStoreService),
4092
- columnOwnerOptions: oimColumnOwnerOptionsWithDefault(
3695
+ columnSlotOwnerOptions: oimColumnOwnerOptionsWithDefault(
3696
+ options.columnSlotStoreService,
3697
+ options.columnNames,
3698
+ OIM_DEFAULT_COMPUTED_COLUMN_SLOT_STORE_SERVICE.getValue()
3699
+ ),
3700
+ slotReleasePolicy: options.slotReleasePolicy ?? OIMSlotAtUnholdReleasePolicy.INSTANCE,
3701
+ storeSlotListener: OIM_DEFAULT_STORE_SLOT_LISTENER.getValue(),
3702
+ createSources: options.createSources,
3703
+ derive: options.derive,
3704
+ sameValueGuard: options.sameValueGuard,
3705
+ initialValue: options.initialValue
3706
+ });
3707
+ }
3708
+
3709
+ // src/facade/computed/OIMSingleComputedService.ts
3710
+ var OIMSingleComputedService = class {
3711
+ constructor(options) {
3712
+ this.computedSingleSlotService = new OIMSingleSlotService({
3713
+ slotReleasePolicy: options.slotReleasePolicy,
3714
+ slotStoreService: OIMSingleSlotStoreService.INSTANCE,
3715
+ slotContentService: new OIMSlotContentComputedService({
3716
+ computedValueService: new OIMComputedValueService({
3717
+ derive: options.derive,
3718
+ sameValueGuard: options.sameValueGuard
3719
+ }),
3720
+ createSources: options.createSources,
3721
+ initialValue: options.initialValue
3722
+ }),
3723
+ columnSlotOwnerOptions: options.columnSlotOwnerOptions,
3724
+ createColumnSlotOwner: createOIMPullColumnSlotOwner,
3725
+ storeSlotListener: options.storeSlotListener
3726
+ });
3727
+ this.hasDerive = options.derive !== void 0;
3728
+ this.hasCreateSources = options.createSources !== void 0;
3729
+ }
3730
+ createComputedStoreSlot(channelMap, derive, createSources) {
3731
+ return oimAttachComputedDerivation(
3732
+ this.computedSingleSlotService.createStoreSlot(channelMap),
3733
+ this.hasDerive,
3734
+ this.hasCreateSources,
3735
+ derive,
3736
+ createSources
3737
+ );
3738
+ }
3739
+ };
3740
+
3741
+ // src/factories/createOIMSingleComputedService.ts
3742
+ function createOIMSingleComputedService(options = {}) {
3743
+ return new OIMSingleComputedService({
3744
+ columnSlotOwnerOptions: oimColumnOwnerOptionsWithDefault(
4093
3745
  options.columnSlotStoreService,
4094
3746
  options.columnNames,
4095
3747
  OIM_DEFAULT_COMPUTED_COLUMN_SLOT_STORE_SERVICE.getValue()
4096
3748
  ),
4097
- slotReleasePolicy: options.slotReleasePolicy ?? OIMSlotReleasePolicyAtUnhold.INSTANCE,
3749
+ slotReleasePolicy: options.slotReleasePolicy ?? OIMSlotAtUnholdReleasePolicy.INSTANCE,
4098
3750
  storeSlotListener: OIM_DEFAULT_STORE_SLOT_LISTENER.getValue(),
4099
3751
  createSources: options.createSources,
4100
3752
  derive: options.derive,
@@ -4134,8 +3786,8 @@ function oimEntitySlotsComparator(compareEntities) {
4134
3786
  };
4135
3787
  }
4136
3788
 
4137
- // src/facade/computed/OIMComputedServiceSorted.ts
4138
- var OIMComputedServiceSorted = class {
3789
+ // src/facade/computed/OIMSortedComputedService.ts
3790
+ var OIMSortedComputedService = class {
4139
3791
  constructor(options) {
4140
3792
  const indexService = options.indexService;
4141
3793
  const bucketContentService = indexService.slotContentService;
@@ -4150,11 +3802,17 @@ var OIMComputedServiceSorted = class {
4150
3802
  });
4151
3803
  this.computedCollectionService = createOIMComputedCollectionService({
4152
3804
  computedValueService,
4153
- createSources: (key, storeSlot) => createSortedSources(key, storeSlot, indexService, sortColumns, hasComparator),
3805
+ createSources: (computedSlot) => createSortedSources(
3806
+ computedSlot.key,
3807
+ computedSlot.storeSlot,
3808
+ indexService,
3809
+ sortColumns,
3810
+ hasComparator
3811
+ ),
4154
3812
  initialValue: OIM_FROZEN_EMPTY_SLOTS,
4155
3813
  slotReleasePolicy: options.slotReleasePolicy,
4156
3814
  computedSlotStoreService: options.computedSlotStoreService,
4157
- columnOwnerOptions: { columnSlotStoreService: options.columnSlotStoreService },
3815
+ columnSlotOwnerOptions: { columnSlotStoreService: options.columnSlotStoreService },
4158
3816
  storeSlotListener: options.storeSlotListener
4159
3817
  });
4160
3818
  }
@@ -4235,21 +3893,21 @@ function reconcileArrayWithEveryBucketMemberSlot(entitySlots, bucketMemberSlots)
4235
3893
  return next;
4236
3894
  }
4237
3895
 
4238
- // src/factories/createOIMComputedServiceSorted.ts
4239
- function createOIMComputedServiceSorted(options) {
4240
- return new OIMComputedServiceSorted({
3896
+ // src/factories/createOIMSortedComputedService.ts
3897
+ function createOIMSortedComputedService(options) {
3898
+ return new OIMSortedComputedService({
4241
3899
  indexService: options.indexService,
4242
3900
  computedSlotStoreService: oimSlotStoreServiceWithDefault(options.computedSlotStoreService),
4243
3901
  columnSlotStoreService: options.columnSlotStoreService ?? OIM_DEFAULT_COMPUTED_COLUMN_SLOT_STORE_SERVICE.getValue(),
4244
3902
  sortColumns: options.sortColumns,
4245
3903
  comparator: options.comparator,
4246
- slotReleasePolicy: options.slotReleasePolicy ?? OIMSlotReleasePolicyAtUnhold.INSTANCE,
3904
+ slotReleasePolicy: options.slotReleasePolicy ?? OIMSlotAtUnholdReleasePolicy.INSTANCE,
4247
3905
  storeSlotListener: OIM_DEFAULT_STORE_SLOT_LISTENER.getValue()
4248
3906
  });
4249
3907
  }
4250
3908
 
4251
- // src/facade/computed/OIMComputedServiceBucketMemo.ts
4252
- var OIMComputedServiceBucketMemo = class {
3909
+ // src/facade/computed/OIMBucketMemoComputedService.ts
3910
+ var OIMBucketMemoComputedService = class {
4253
3911
  constructor(options) {
4254
3912
  const bucketCollectionService = options.bucketCollectionService;
4255
3913
  const bucketContentService = bucketCollectionService.slotContentService;
@@ -4259,11 +3917,11 @@ var OIMComputedServiceBucketMemo = class {
4259
3917
  });
4260
3918
  this.computedCollectionService = createOIMComputedCollectionService({
4261
3919
  computedValueService,
4262
- createSources: (key, storeSlot) => createBucketMemoSources(key, storeSlot, bucketCollectionService),
3920
+ createSources: (computedSlot) => createBucketMemoSources(computedSlot.key, computedSlot.storeSlot, bucketCollectionService),
4263
3921
  initialValue: OIM_FROZEN_EMPTY_SLOTS,
4264
3922
  slotReleasePolicy: options.slotReleasePolicy,
4265
3923
  computedSlotStoreService: options.computedSlotStoreService,
4266
- columnOwnerOptions: { columnSlotStoreService: options.columnSlotStoreService },
3924
+ columnSlotOwnerOptions: { columnSlotStoreService: options.columnSlotStoreService },
4267
3925
  storeSlotListener: options.storeSlotListener
4268
3926
  });
4269
3927
  }
@@ -4274,26 +3932,123 @@ var OIMComputedServiceBucketMemo = class {
4274
3932
  function deriveBucketMemo(computedSlot, bucketContentService) {
4275
3933
  return Array.from(bucketContentService.getBucketMemberSlots(computedSlot.sourceSlots[0]));
4276
3934
  }
4277
- function createBucketMemoSources(key, storeSlot, bucketCollectionService) {
4278
- const bucketStoreSlot = storeSlot.sourceStoreSlot;
4279
- return { sourceSlots: [bucketCollectionService.getSlotByKey(bucketStoreSlot, key)] };
3935
+ function createBucketMemoSources(key, storeSlot, bucketCollectionService) {
3936
+ const bucketStoreSlot = storeSlot.sourceStoreSlot;
3937
+ return { sourceSlots: [bucketCollectionService.getSlotByKey(bucketStoreSlot, key)] };
3938
+ }
3939
+
3940
+ // src/factories/createOIMBucketMemoComputedService.ts
3941
+ function createOIMBucketMemoComputedService(options) {
3942
+ return new OIMBucketMemoComputedService({
3943
+ bucketCollectionService: options.bucketCollectionService,
3944
+ computedSlotStoreService: oimSlotStoreServiceWithDefault(options.computedSlotStoreService),
3945
+ columnSlotStoreService: options.columnSlotStoreService ?? OIM_DEFAULT_COMPUTED_COLUMN_SLOT_STORE_SERVICE.getValue(),
3946
+ slotReleasePolicy: options.slotReleasePolicy ?? OIMSlotAtUnholdReleasePolicy.INSTANCE,
3947
+ storeSlotListener: OIM_DEFAULT_STORE_SLOT_LISTENER.getValue()
3948
+ });
3949
+ }
3950
+
3951
+ // src/engine/bucket/commands/constants/OIM_MAX_COMMANDS_PER_SLOT.ts
3952
+ var OIM_MAX_COMMANDS_PER_SLOT = 1;
3953
+
3954
+ // src/facade/bucket/OIMBucketCommands.ts
3955
+ var OIMBucketCommands = class {
3956
+ constructor(options) {
3957
+ this.maxCommandsPerSlot = options.maxCommandsPerSlot ?? OIM_MAX_COMMANDS_PER_SLOT;
3958
+ }
3959
+ recordInsert(bucketSlot, index, bucketMemberSlot, bucketMemberSlotCount) {
3960
+ this.recordCommand(bucketSlot, { type: "insert", index, slot: bucketMemberSlot }, bucketMemberSlotCount);
3961
+ }
3962
+ recordRemove(bucketSlot, index, count, bucketMemberSlotCount) {
3963
+ for (let i = 0; i < count; i++) this.recordCommand(bucketSlot, { type: "remove", index }, bucketMemberSlotCount);
3964
+ }
3965
+ recordMove(bucketSlot, from, to, bucketMemberSlotCount) {
3966
+ this.recordCommand(bucketSlot, { type: "move", from, to }, bucketMemberSlotCount);
3967
+ }
3968
+ recordWholeList(bucketSlot) {
3969
+ const bucketSlotEditable = enlistInFlush(bucketSlot);
3970
+ const commands = bucketSlotEditable.commands;
3971
+ if (commands !== void 0 && commands.length !== 0) commands.length = 0;
3972
+ bucketSlotEditable.isWholeListRecorded = true;
3973
+ }
3974
+ recordCommand(bucketSlot, orderedListCommand, bucketMemberSlotCount) {
3975
+ const bucketSlotEditable = enlistInFlush(bucketSlot);
3976
+ if (bucketSlotEditable.isWholeListRecorded) return;
3977
+ const commands = bucketSlotEditable.commands ?? (bucketSlotEditable.commands = []);
3978
+ commands.push(orderedListCommand);
3979
+ if (commands.length > this.maxCommandsPerSlot * bucketMemberSlotCount) {
3980
+ commands.length = 0;
3981
+ bucketSlotEditable.isWholeListRecorded = true;
3982
+ }
3983
+ }
3984
+ };
3985
+ function enlistInFlush(bucketSlot) {
3986
+ const bucketSlotEditable = bucketSlot;
3987
+ const storeSlot = bucketSlot.storeSlot;
3988
+ const channelSlot = storeSlot.channelSlot;
3989
+ const commands = bucketSlotEditable.commands;
3990
+ const hasScript = commands !== void 0 && commands.length > 0 || bucketSlotEditable.isWholeListRecorded;
3991
+ if (hasScript && !isScriptStale(channelSlot, bucketSlotEditable)) return bucketSlotEditable;
3992
+ if (hasScript) {
3993
+ clearScript(bucketSlotEditable);
3994
+ } else {
3995
+ const commandsBucketSlotChannelQueue = storeSlot.commandsBucketSlotChannelQueue ?? (storeSlot.commandsBucketSlotChannelQueue = new OIMChannelQueue());
3996
+ if (commandsBucketSlotChannelQueue.getEntryCount() === 0) getCommandsStoreSlotChannelQueue(channelSlot).enqueueEntry(storeSlot);
3997
+ commandsBucketSlotChannelQueue.enqueueEntry(bucketSlotEditable);
3998
+ }
3999
+ const clock = channelSlot.clock;
4000
+ bucketSlotEditable.commandsStartedAtRevision = clock.revision;
4001
+ bucketSlotEditable.commandsStartedAtEpoch = clock.epoch;
4002
+ return bucketSlotEditable;
4003
+ }
4004
+ function getCommandsStoreSlotChannelQueue(channelSlot) {
4005
+ const commandsStoreSlotChannelQueue = channelSlot.commandsStoreSlotChannelQueue;
4006
+ if (commandsStoreSlotChannelQueue !== void 0) return commandsStoreSlotChannelQueue;
4007
+ const createdCommandsStoreSlotChannelQueue = new OIMChannelQueue();
4008
+ channelSlot.commandsStoreSlotChannelQueue = createdCommandsStoreSlotChannelQueue;
4009
+ OIMChannelService.INSTANCE.subscribeAfterEachFlush(channelSlot, () => {
4010
+ clearStaleScripts(channelSlot, createdCommandsStoreSlotChannelQueue);
4011
+ });
4012
+ return createdCommandsStoreSlotChannelQueue;
4013
+ }
4014
+ function isScriptStale(channelSlot, bucketSlot) {
4015
+ const frame = channelSlot.frame;
4016
+ return oimIsRevisionAfter(
4017
+ frame.openedAtRevision,
4018
+ frame.openedAtEpoch,
4019
+ bucketSlot.commandsStartedAtRevision,
4020
+ bucketSlot.commandsStartedAtEpoch
4021
+ );
4280
4022
  }
4281
-
4282
- // src/factories/createOIMComputedServiceBucketMemo.ts
4283
- function createOIMComputedServiceBucketMemo(options) {
4284
- return new OIMComputedServiceBucketMemo({
4285
- bucketCollectionService: options.bucketCollectionService,
4286
- computedSlotStoreService: oimSlotStoreServiceWithDefault(options.computedSlotStoreService),
4287
- columnSlotStoreService: options.columnSlotStoreService ?? OIM_DEFAULT_COMPUTED_COLUMN_SLOT_STORE_SERVICE.getValue(),
4288
- slotReleasePolicy: options.slotReleasePolicy ?? OIMSlotReleasePolicyAtUnhold.INSTANCE,
4289
- storeSlotListener: OIM_DEFAULT_STORE_SLOT_LISTENER.getValue()
4290
- });
4023
+ function clearScript(bucketSlotEditable) {
4024
+ const commands = bucketSlotEditable.commands;
4025
+ if (commands !== void 0 && commands.length !== 0) commands.length = 0;
4026
+ bucketSlotEditable.isWholeListRecorded = false;
4027
+ }
4028
+ function clearStaleScripts(channelSlot, commandsStoreSlotChannelQueue) {
4029
+ let keptStoreSlotCount = 0;
4030
+ for (let i = 0; i < commandsStoreSlotChannelQueue.getEntryCount(); i++) {
4031
+ const storeSlot = commandsStoreSlotChannelQueue.getEntryAt(i);
4032
+ const commandsBucketSlotChannelQueue = storeSlot.commandsBucketSlotChannelQueue;
4033
+ let keptBucketSlotCount = 0;
4034
+ for (let j = 0; j < commandsBucketSlotChannelQueue.getEntryCount(); j++) {
4035
+ const bucketSlotEditable = commandsBucketSlotChannelQueue.getEntryAt(j);
4036
+ if (!isScriptStale(channelSlot, bucketSlotEditable)) {
4037
+ commandsBucketSlotChannelQueue.setEntryAt(keptBucketSlotCount++, bucketSlotEditable);
4038
+ continue;
4039
+ }
4040
+ clearScript(bucketSlotEditable);
4041
+ }
4042
+ commandsBucketSlotChannelQueue.keepFirstEntries(keptBucketSlotCount);
4043
+ if (keptBucketSlotCount !== 0) commandsStoreSlotChannelQueue.setEntryAt(keptStoreSlotCount++, storeSlot);
4044
+ }
4045
+ commandsStoreSlotChannelQueue.keepFirstEntries(keptStoreSlotCount);
4291
4046
  }
4292
4047
 
4293
4048
  // src/engine/index/utils/createOIMIndexStoreSlot.ts
4294
- function createOIMIndexStoreSlot(store, sourceStoreSlot, contentChangeListener) {
4049
+ function createOIMIndexStoreSlot(store, slotService, sourceStoreSlot, contentChangeListener) {
4295
4050
  return {
4296
- ...createOIMStoreSlot(store, sourceStoreSlot.channelSlot),
4051
+ ...createOIMStoreSlot(store, sourceStoreSlot.channelSlot, slotService),
4297
4052
  sourceStoreSlot,
4298
4053
  indexKeysPosition: -1,
4299
4054
  contentChangeListener,
@@ -4304,8 +4059,8 @@ function createOIMIndexStoreSlot(store, sourceStoreSlot, contentChangeListener)
4304
4059
  };
4305
4060
  }
4306
4061
 
4307
- // src/facade/index/OIMIndexService.ts
4308
- var OIMIndexService = class extends OIMSlotCollectionService {
4062
+ // src/facade/index/OIMSlotCollectionIndexService.ts
4063
+ var OIMSlotCollectionIndexService = class extends OIMSlotCollectionService {
4309
4064
  constructor(options) {
4310
4065
  super(options);
4311
4066
  this.slotContentBucketService = options.slotContentService;
@@ -4323,7 +4078,7 @@ var OIMIndexService = class extends OIMSlotCollectionService {
4323
4078
  this.updateIndexKeysForSlots(indexStoreSlot, entitySlotChannelQueue, patchChannelQueue, changedColumnsChannelQueue);
4324
4079
  }
4325
4080
  };
4326
- const indexStoreSlot = this.createStoreSlotWith((store) => createOIMIndexStoreSlot(store, sourceStoreSlot, contentChangeListener));
4081
+ const indexStoreSlot = this.createStoreSlotWith((store) => createOIMIndexStoreSlot(store, this, sourceStoreSlot, contentChangeListener));
4327
4082
  const indexKeysService = this.indexKeysService;
4328
4083
  const indexKeysPositions = sourceStoreSlot.indexKeysPositions ?? (sourceStoreSlot.indexKeysPositions = indexKeysService.createPositions());
4329
4084
  indexStoreSlot.indexKeysPosition = indexKeysService.allocatePosition(indexKeysPositions);
@@ -4351,7 +4106,7 @@ var OIMIndexService = class extends OIMSlotCollectionService {
4351
4106
  const bucketSlots = Array.from(this.getSlots(indexStoreSlot));
4352
4107
  for (let i = 0; i < bucketSlots.length; i++) {
4353
4108
  if (oimIsSlotReleased(bucketSlots[i])) continue;
4354
- slotContentService.clearBucketMemberSlots(bucketSlots[i]);
4109
+ slotContentService.clearSlotContent(bucketSlots[i]);
4355
4110
  }
4356
4111
  indexStoreSlot.isDisposed = true;
4357
4112
  }
@@ -4409,18 +4164,18 @@ var OIMIndexService = class extends OIMSlotCollectionService {
4409
4164
  }
4410
4165
  getAnyBucketColumnByKey(indexStoreSlot, key) {
4411
4166
  this.addAnyBucketColumnRead(indexStoreSlot);
4412
- return this.slotOwnerService.columnOwner.getAnyColumn(
4167
+ return this.slotOwnerService.columnSlotOwner.getAnyColumn(
4413
4168
  this.getSlotByKey(indexStoreSlot, key),
4414
4169
  indexStoreSlot.channelSlot.collectorSlot.unusedSlotCollectorSlot
4415
4170
  );
4416
4171
  }
4417
4172
  holdAnyBucketColumnByKey(indexStoreSlot, key) {
4418
4173
  this.addAnyBucketColumnRead(indexStoreSlot);
4419
- return this.slotOwnerService.columnOwner.holdAnyColumn(this.getSlotByKey(indexStoreSlot, key));
4174
+ return this.slotOwnerService.columnSlotOwner.holdAnyColumn(this.getSlotByKey(indexStoreSlot, key));
4420
4175
  }
4421
4176
  getBucketColumnByKey(indexStoreSlot, key, columnName) {
4422
4177
  this.addBucketColumnName(indexStoreSlot, columnName);
4423
- return this.slotOwnerService.columnOwner.getColumn(
4178
+ return this.slotOwnerService.columnSlotOwner.getColumn(
4424
4179
  this.getSlotByKey(indexStoreSlot, key),
4425
4180
  columnName,
4426
4181
  indexStoreSlot.channelSlot.collectorSlot.unusedSlotCollectorSlot
@@ -4428,7 +4183,7 @@ var OIMIndexService = class extends OIMSlotCollectionService {
4428
4183
  }
4429
4184
  holdBucketColumnByKey(indexStoreSlot, key, columnName) {
4430
4185
  this.addBucketColumnName(indexStoreSlot, columnName);
4431
- return this.slotOwnerService.columnOwner.holdColumn(this.getSlotByKey(indexStoreSlot, key), columnName);
4186
+ return this.slotOwnerService.columnSlotOwner.holdColumn(this.getSlotByKey(indexStoreSlot, key), columnName);
4432
4187
  }
4433
4188
  addBucketColumnName(indexStoreSlot, columnName) {
4434
4189
  const bucketColumnNames = indexStoreSlot.bucketColumnNames;
@@ -4450,7 +4205,7 @@ var OIMIndexService = class extends OIMSlotCollectionService {
4450
4205
  assertNotDisposed(storeSlot) {
4451
4206
  if (!storeSlot.isDisposed) return;
4452
4207
  throw new Error(
4453
- "OIMIndexService: this index store slot was disposed. It no longer hears its source store slot and its buckets were emptied, so anything it answered now would be stale. Create a new store slot."
4208
+ "OIMSlotCollectionIndexService: this index store slot was disposed. It no longer hears its source store slot and its buckets were emptied, so anything it answered now would be stale. Create a new store slot."
4454
4209
  );
4455
4210
  }
4456
4211
  addAnyBucketColumnRead(indexStoreSlot) {
@@ -4636,8 +4391,8 @@ function takeNothing() {
4636
4391
  return;
4637
4392
  }
4638
4393
 
4639
- // src/facade/index/OIMIndexServiceSortedArrayDriven.ts
4640
- var OIMIndexServiceSortedArrayDriven = class extends OIMIndexService {
4394
+ // src/facade/index/OIMSlotCollectionSortedArrayIndexService.ts
4395
+ var OIMSlotCollectionSortedArrayIndexService = class extends OIMSlotCollectionIndexService {
4641
4396
  constructor(options) {
4642
4397
  super(options);
4643
4398
  const sortColumnNames = /* @__PURE__ */ new Set();
@@ -4676,16 +4431,10 @@ function oimKeyOfColumns(columns) {
4676
4431
  };
4677
4432
  }
4678
4433
 
4679
- // src/factories/utils/oimIndexServiceOptionsWithDefault.ts
4680
- function oimIndexServiceOptionsWithDefault(db, options, slotStoreService, slotContentService) {
4434
+ // src/factories/utils/oimSlotCollectionIndexServiceOptionsWithDefault.ts
4435
+ function oimSlotCollectionIndexServiceOptionsWithDefault(db, options, slotStoreService, slotContentService) {
4681
4436
  return {
4682
- slotOwnerService: createOIMBucketSlotOwnerService(db, {
4683
- slotStoreService,
4684
- slotContentService,
4685
- slotReleasePolicy: options.slotReleasePolicy,
4686
- columnSlotStoreService: options.columnSlotStoreService,
4687
- columnNames: options.columnNames
4688
- }),
4437
+ ...oimSlotOwnerOptionsWithDefault(db, options),
4689
4438
  slotStoreService,
4690
4439
  slotContentService,
4691
4440
  storeSlotListener: OIM_DEFAULT_STORE_SLOT_LISTENER.getValue(),
@@ -4696,70 +4445,23 @@ function oimIndexServiceOptionsWithDefault(db, options, slotStoreService, slotCo
4696
4445
  };
4697
4446
  }
4698
4447
 
4699
- // src/factories/createOIMIndexService.ts
4700
- function createOIMIndexService(db, options) {
4701
- return new OIMIndexService(oimIndexServiceOptionsWithDefault(
4448
+ // src/factories/createOIMSlotCollectionIndexService.ts
4449
+ function createOIMSlotCollectionIndexService(db, options) {
4450
+ return new OIMSlotCollectionIndexService(oimSlotCollectionIndexServiceOptionsWithDefault(
4702
4451
  db,
4703
4452
  options,
4704
4453
  oimSlotStoreServiceWithDefault(options.bucketSlotStoreService),
4705
- options.slotContentService ?? new OIMSlotContentBucketServiceArrayDriven()
4454
+ options.slotContentService ?? new OIMSlotContentPositionalArrayBucketService()
4706
4455
  ));
4707
4456
  }
4708
4457
 
4709
- // src/engine/store/OIMSlotStoreServiceTreeDriven.ts
4710
- var OIMSlotStoreServiceTreeDriven = class {
4711
- constructor(keyTreeWalk) {
4712
- this.keyTreeWalk = keyTreeWalk;
4713
- }
4714
- createStore() {
4715
- return { root: { childNodes: void 0, atThisKey: void 0 }, slots: /* @__PURE__ */ new Set() };
4716
- }
4717
- ownKey(compositeKey) {
4718
- return compositeKey.slice();
4719
- }
4720
- isSameKey(compositeKey, otherCompositeKey) {
4721
- return oimSameKeySequence(compositeKey, otherCompositeKey);
4722
- }
4723
- get(slotStoreTree, compositeKey) {
4724
- return this.keyTreeWalk.nodeAt(slotStoreTree.root, compositeKey)?.atThisKey;
4725
- }
4726
- set(slotStoreTree, compositeKey, slot) {
4727
- const compositeKeyNode = this.keyTreeWalk.mintNodeAt(slotStoreTree.root, compositeKey);
4728
- const filedSlot = compositeKeyNode.atThisKey;
4729
- if (filedSlot !== void 0 && filedSlot !== slot) slotStoreTree.slots.delete(filedSlot);
4730
- compositeKeyNode.atThisKey = slot;
4731
- slotStoreTree.slots.add(slot);
4732
- }
4733
- remove(slotStoreTree, compositeKey) {
4734
- const slot = this.keyTreeWalk.deleteKey(slotStoreTree.root, compositeKey);
4735
- if (slot !== void 0) slotStoreTree.slots.delete(slot);
4736
- }
4737
- getSlots(slotStoreTree) {
4738
- return slotStoreTree.slots.values();
4739
- }
4740
- getSlotCount(slotStoreTree) {
4741
- return slotStoreTree.slots.size;
4742
- }
4743
- };
4744
-
4745
- // src/factories/createOIMIndexServiceByCompositeKey.ts
4746
- function createOIMIndexServiceByCompositeKey(db, options) {
4747
- return createOIMIndexService(db, {
4748
- ...options,
4749
- keyOf: oimKeyOfColumns(options.columns),
4750
- bucketSlotStoreService: new OIMSlotStoreServiceTreeDriven(
4751
- OIM_DEFAULT_KEY_TREE_WALK_SCALAR.getValue()
4752
- )
4753
- });
4754
- }
4755
-
4756
- // src/factories/createOIMIndexServiceSortedArrayDriven.ts
4757
- function createOIMIndexServiceSortedArrayDriven(db, options) {
4758
- const slotContentService = new OIMSlotContentBucketServiceSortedArrayDriven({
4458
+ // src/factories/createOIMSlotCollectionSortedArrayIndexService.ts
4459
+ function createOIMSlotCollectionSortedArrayIndexService(db, options) {
4460
+ const slotContentService = new OIMSlotContentSortedArrayBucketService({
4759
4461
  compareBucketMemberSlots: oimEntitySlotsComparator(oimColumnsComparator(options.sortColumns))
4760
4462
  });
4761
- return new OIMIndexServiceSortedArrayDriven({
4762
- ...oimIndexServiceOptionsWithDefault(
4463
+ return new OIMSlotCollectionSortedArrayIndexService({
4464
+ ...oimSlotCollectionIndexServiceOptionsWithDefault(
4763
4465
  db,
4764
4466
  options,
4765
4467
  oimSlotStoreServiceWithDefault(options.bucketSlotStoreService),
@@ -4769,8 +4471,8 @@ function createOIMIndexServiceSortedArrayDriven(db, options) {
4769
4471
  });
4770
4472
  }
4771
4473
 
4772
- // src/engine/index/OIMIndexKeysServiceReclaiming.ts
4773
- var OIMIndexKeysServiceReclaiming = class extends OIMIndexKeysService {
4474
+ // src/engine/index/OIMReclaimingIndexKeysService.ts
4475
+ var OIMReclaimingIndexKeysService = class extends OIMIndexKeysService {
4774
4476
  allocatePosition(positions) {
4775
4477
  const freePosition = positions.freePositions.pop();
4776
4478
  return freePosition === void 0 ? positions.nextPosition++ : freePosition;
@@ -4806,13 +4508,13 @@ function deleteColumnsReplacing(slot, names) {
4806
4508
  function createOIMEntityWriterReplacing(options) {
4807
4509
  const {
4808
4510
  sameValueGuard,
4809
- entityInsertStrategy,
4511
+ entityInserter,
4810
4512
  putEntityColumns,
4811
4513
  patchEntityColumns,
4812
4514
  patchEntityColumn
4813
4515
  } = oimEntityWriterOptionsWithDefault(options);
4814
4516
  return {
4815
- fillEntity: entityInsertStrategy,
4517
+ fillEntity: entityInserter,
4816
4518
  clearEntity: oimClearEntity,
4817
4519
  putEntity: (slot, entity, changedColumnNames) => storeReplacement(slot, putEntityColumns(slot, entity, sameValueGuard, changedColumnNames, oimCopyEntity)),
4818
4520
  patchEntity: (slot, patch, changedColumnNames) => storeReplacement(slot, patchEntityColumns(slot, patch, sameValueGuard, changedColumnNames, oimCopyEntity)),
@@ -4878,191 +4580,231 @@ var OIM_SLICE_LENGTH_MS = 1024;
4878
4580
  // src/engine/collector/utils/oimSliceOfMs.ts
4879
4581
  var oimSliceOfMs = (ms) => Math.floor(ms / OIM_SLICE_LENGTH_MS);
4880
4582
 
4881
- // src/engine/collector/OIMReleaseSlotQueueService.ts
4882
- var _OIMReleaseSlotQueueService = class _OIMReleaseSlotQueueService {
4883
- scheduleSlotRelease(releaseSlotCollectorSlot, releaseSlotCollectorService, slot, nowMs) {
4884
- const releaseDueMs = releaseSlotCollectorService.getReleaseDueMs(slot);
4885
- if (releaseDueMs < 0) return;
4886
- const queuedSliceNumber = releaseSlotCollectorSlot.sliceNumberBySlot.get(slot);
4887
- if (queuedSliceNumber !== void 0 && queuedSliceNumber <= oimSliceOfMs(releaseDueMs)) return;
4888
- this.addToSliceNumber(releaseSlotCollectorSlot, oimSliceOfMs(Math.max(releaseDueMs, nowMs)), slot);
4889
- releaseSlotCollectorService.scheduleNextRelease(releaseSlotCollectorSlot);
4890
- }
4891
- cancelSlotRelease(releaseSlotCollectorSlot, slot) {
4892
- const sliceNumber = releaseSlotCollectorSlot.sliceNumberBySlot.get(slot);
4893
- if (sliceNumber === void 0) return;
4894
- releaseSlotCollectorSlot.sliceNumberBySlot.delete(slot);
4895
- this.removeFromSliceNumber(releaseSlotCollectorSlot, sliceNumber, slot);
4896
- }
4897
- getNextReleaseSliceNumber(releaseSlotCollectorSlot) {
4898
- if (releaseSlotCollectorSlot.nextSliceNumberNeedsRescan) {
4583
+ // src/engine/collector/OIMSlotWheel.ts
4584
+ var OIMSlotWheel = class {
4585
+ constructor(options) {
4586
+ this.scheduledCallback = void 0;
4587
+ this.timerDisposer = void 0;
4588
+ this.scheduledUntilMs = Number.POSITIVE_INFINITY;
4589
+ this.slotsBySliceNumber = /* @__PURE__ */ new Map();
4590
+ this.lastFiledSliceNumber = Number.NaN;
4591
+ this.lastFiledSliceSlots = void 0;
4592
+ this.floorSliceNumber = Number.NEGATIVE_INFINITY;
4593
+ this.nextSliceNumber = void 0;
4594
+ this.nextSliceNumberNeedsRescan = false;
4595
+ this.timer = options.timer;
4596
+ this.getNowMs = options.getNowMs;
4597
+ this.errorPolicy = options.errorPolicy;
4598
+ }
4599
+ getNextSliceNumber() {
4600
+ if (this.nextSliceNumberNeedsRescan) {
4899
4601
  let nextSliceNumber;
4900
- for (const sliceNumber of releaseSlotCollectorSlot.slotsBySliceNumber.keys()) {
4602
+ for (const sliceNumber of this.slotsBySliceNumber.keys()) {
4901
4603
  if (nextSliceNumber === void 0 || sliceNumber < nextSliceNumber) nextSliceNumber = sliceNumber;
4902
4604
  }
4903
- releaseSlotCollectorSlot.nextSliceNumber = nextSliceNumber;
4904
- releaseSlotCollectorSlot.nextSliceNumberNeedsRescan = false;
4605
+ this.nextSliceNumber = nextSliceNumber;
4606
+ this.nextSliceNumberNeedsRescan = false;
4905
4607
  }
4906
- return releaseSlotCollectorSlot.nextSliceNumber;
4907
- }
4908
- cancelAllSlotReleases(releaseSlotCollectorSlot) {
4909
- releaseSlotCollectorSlot.slotsBySliceNumber.clear();
4910
- releaseSlotCollectorSlot.sliceNumberBySlot.clear();
4911
- releaseSlotCollectorSlot.nextSliceNumber = void 0;
4912
- releaseSlotCollectorSlot.nextSliceNumberNeedsRescan = false;
4608
+ return this.nextSliceNumber;
4913
4609
  }
4914
- isSlotReleaseScheduled(releaseSlotCollectorSlot, slot) {
4915
- return releaseSlotCollectorSlot.sliceNumberBySlot.has(slot);
4916
- }
4917
- releaseDueUpToSliceNumber(releaseSlotCollectorSlot, releaseSlotCollectorService, upToSliceNumber) {
4918
- const nextSliceNumber = this.getNextReleaseSliceNumber(releaseSlotCollectorSlot);
4610
+ sweepUpToSliceNumber(upToSliceNumber) {
4611
+ const nextSliceNumber = this.getNextSliceNumber();
4919
4612
  if (nextSliceNumber === void 0 || nextSliceNumber > upToSliceNumber) return;
4920
- const outerFloor = releaseSlotCollectorSlot.floorSliceNumber;
4921
- releaseSlotCollectorSlot.floorSliceNumber = upToSliceNumber + 1;
4922
- const slotsBySliceNumber = releaseSlotCollectorSlot.slotsBySliceNumber;
4613
+ const outerFloor = this.floorSliceNumber;
4614
+ this.floorSliceNumber = upToSliceNumber + 1;
4615
+ const slotsBySliceNumber = this.slotsBySliceNumber;
4923
4616
  try {
4924
4617
  if (upToSliceNumber - nextSliceNumber < slotsBySliceNumber.size) {
4925
4618
  for (let sliceNumber = nextSliceNumber; sliceNumber <= upToSliceNumber; sliceNumber++) {
4926
4619
  const sliceSlots = slotsBySliceNumber.get(sliceNumber);
4927
- if (sliceSlots !== void 0) this.releaseSlice(releaseSlotCollectorSlot, releaseSlotCollectorService, sliceNumber, sliceSlots);
4620
+ if (sliceSlots !== void 0) this.sweepSlice(sliceNumber, sliceSlots);
4928
4621
  }
4929
4622
  } else {
4930
4623
  for (const [sliceNumber, sliceSlots] of slotsBySliceNumber) {
4931
- if (sliceNumber <= upToSliceNumber) this.releaseSlice(releaseSlotCollectorSlot, releaseSlotCollectorService, sliceNumber, sliceSlots);
4624
+ if (sliceNumber <= upToSliceNumber) this.sweepSlice(sliceNumber, sliceSlots);
4932
4625
  }
4933
4626
  }
4934
4627
  } finally {
4935
- releaseSlotCollectorSlot.floorSliceNumber = outerFloor;
4628
+ this.floorSliceNumber = outerFloor;
4936
4629
  }
4630
+ this.onSweepFinished();
4937
4631
  }
4938
- releaseSlice(releaseSlotCollectorSlot, releaseSlotCollectorService, sliceNumber, sliceSlots) {
4939
- releaseSlotCollectorSlot.slotsBySliceNumber.delete(sliceNumber);
4940
- this.invalidateNextSliceNumber(releaseSlotCollectorSlot, sliceNumber);
4941
- const nowMs = releaseSlotCollectorSlot.getNowMs();
4942
- const sliceNumberBySlot = releaseSlotCollectorSlot.sliceNumberBySlot;
4632
+ flush() {
4633
+ this.cancelSlotWheelSchedule();
4943
4634
  try {
4944
- for (const slot of sliceSlots) {
4945
- sliceSlots.delete(slot);
4946
- if (sliceNumberBySlot.get(slot) === sliceNumber) sliceNumberBySlot.delete(slot);
4947
- if (oimIsSlotReleased(slot)) continue;
4948
- const releaseDueMs = releaseSlotCollectorService.getReleaseDueMs(slot);
4949
- if (releaseDueMs < 0) continue;
4950
- if (releaseDueMs > nowMs) {
4951
- this.addToSliceNumber(releaseSlotCollectorSlot, oimSliceOfMs(releaseDueMs), slot);
4952
- continue;
4953
- }
4954
- slot.owner.releaseSlotIfUnheld(slot);
4955
- }
4635
+ this.sweepUpToSliceNumber(this.getSweptSliceNumberAt(this.getNowMs()));
4956
4636
  } finally {
4957
- if (sliceSlots.size !== 0) {
4958
- releaseSlotCollectorSlot.slotsBySliceNumber.set(sliceNumber, sliceSlots);
4959
- this.updateNextSliceNumber(releaseSlotCollectorSlot, sliceNumber);
4637
+ this.scheduleNextSweep();
4638
+ }
4639
+ }
4640
+ cancelAllSlots() {
4641
+ this.cancelSlotWheelSchedule();
4642
+ for (const sliceSlots of this.slotsBySliceNumber.values()) {
4643
+ for (let index = 0; index < sliceSlots.length; index++) this.onSlotDropped(sliceSlots[index]);
4644
+ }
4645
+ this.slotsBySliceNumber.clear();
4646
+ this.lastFiledSliceSlots = void 0;
4647
+ this.nextSliceNumber = void 0;
4648
+ this.nextSliceNumberNeedsRescan = false;
4649
+ }
4650
+ fileSlot(sliceNumber, slot) {
4651
+ const flooredSliceNumber = Math.max(sliceNumber, this.floorSliceNumber);
4652
+ let sliceSlots = flooredSliceNumber === this.lastFiledSliceNumber ? this.lastFiledSliceSlots : void 0;
4653
+ if (sliceSlots === void 0) {
4654
+ sliceSlots = this.slotsBySliceNumber.get(flooredSliceNumber);
4655
+ if (sliceSlots === void 0) {
4656
+ sliceSlots = [];
4657
+ this.slotsBySliceNumber.set(flooredSliceNumber, sliceSlots);
4960
4658
  }
4659
+ this.lastFiledSliceNumber = flooredSliceNumber;
4660
+ this.lastFiledSliceSlots = sliceSlots;
4661
+ }
4662
+ sliceSlots.push(slot);
4663
+ this.lowerNextSliceNumber(flooredSliceNumber);
4664
+ }
4665
+ scheduleNextSweep() {
4666
+ const nextSliceNumber = this.getNextSliceNumber();
4667
+ if (nextSliceNumber === void 0) return;
4668
+ const nowMs = this.getNowMs();
4669
+ const untilMs = Math.max(nowMs, (nextSliceNumber + 1) * OIM_SLICE_LENGTH_MS);
4670
+ if (OIMFlushSchedulerService.INSTANCE.isScheduled(this)) {
4671
+ if (untilMs >= this.scheduledUntilMs) return;
4672
+ this.cancelSlotWheelSchedule();
4961
4673
  }
4674
+ this.scheduledUntilMs = untilMs;
4675
+ OIMFlushSchedulerService.INSTANCE.schedule(this, untilMs - nowMs, this);
4962
4676
  }
4963
- removeFromSliceNumber(releaseSlotCollectorSlot, sliceNumber, slot) {
4964
- const sliceSlots = releaseSlotCollectorSlot.slotsBySliceNumber.get(sliceNumber);
4965
- if (sliceSlots === void 0) return;
4966
- sliceSlots.delete(slot);
4967
- if (sliceSlots.size !== 0) return;
4968
- releaseSlotCollectorSlot.slotsBySliceNumber.delete(sliceNumber);
4969
- this.invalidateNextSliceNumber(releaseSlotCollectorSlot, sliceNumber);
4677
+ cancelSlotWheelSchedule() {
4678
+ this.scheduledUntilMs = Number.POSITIVE_INFINITY;
4679
+ OIMFlushSchedulerService.INSTANCE.cancelSchedule(this);
4970
4680
  }
4971
- updateNextSliceNumber(releaseSlotCollectorSlot, sliceNumber) {
4972
- const nextSliceNumber = releaseSlotCollectorSlot.nextSliceNumber;
4973
- if (nextSliceNumber === void 0 || sliceNumber <= nextSliceNumber) {
4974
- releaseSlotCollectorSlot.nextSliceNumber = sliceNumber;
4975
- releaseSlotCollectorSlot.nextSliceNumberNeedsRescan = false;
4681
+ onSchedulerTimerFired() {
4682
+ try {
4683
+ this.flush();
4684
+ } catch (error) {
4685
+ this.errorPolicy.onErrorCaught(error);
4976
4686
  }
4977
4687
  }
4978
- invalidateNextSliceNumber(releaseSlotCollectorSlot, sliceNumber) {
4979
- if (sliceNumber === releaseSlotCollectorSlot.nextSliceNumber) releaseSlotCollectorSlot.nextSliceNumberNeedsRescan = true;
4688
+ getSweptSliceNumberAt(nowMs) {
4689
+ return oimSliceOfMs(nowMs);
4980
4690
  }
4981
- addToSliceNumber(releaseSlotCollectorSlot, sliceNumber, slot) {
4982
- const flooredSliceNumber = Math.max(sliceNumber, releaseSlotCollectorSlot.floorSliceNumber);
4983
- const sliceNumberBySlot = releaseSlotCollectorSlot.sliceNumberBySlot;
4984
- const prevSliceNumber = sliceNumberBySlot.get(slot);
4985
- if (prevSliceNumber !== void 0) this.removeFromSliceNumber(releaseSlotCollectorSlot, prevSliceNumber, slot);
4986
- const slotsBySliceNumber = releaseSlotCollectorSlot.slotsBySliceNumber;
4987
- let sliceSlots = slotsBySliceNumber.get(flooredSliceNumber);
4988
- if (sliceSlots === void 0) {
4989
- sliceSlots = /* @__PURE__ */ new Set();
4990
- slotsBySliceNumber.set(flooredSliceNumber, sliceSlots);
4691
+ onSlotDropped(_slot) {
4692
+ return;
4693
+ }
4694
+ onSweepFinished() {
4695
+ return;
4696
+ }
4697
+ lowerNextSliceNumber(sliceNumber) {
4698
+ const nextSliceNumber = this.nextSliceNumber;
4699
+ if (nextSliceNumber === void 0 || sliceNumber <= nextSliceNumber) {
4700
+ this.nextSliceNumber = sliceNumber;
4701
+ this.nextSliceNumberNeedsRescan = false;
4702
+ }
4703
+ }
4704
+ sweepSlice(sliceNumber, sliceSlots) {
4705
+ this.slotsBySliceNumber.delete(sliceNumber);
4706
+ if (this.lastFiledSliceSlots === sliceSlots) this.lastFiledSliceSlots = void 0;
4707
+ if (sliceNumber === this.nextSliceNumber) this.nextSliceNumberNeedsRescan = true;
4708
+ const nowMs = this.getNowMs();
4709
+ let index = 0;
4710
+ try {
4711
+ for (; index < sliceSlots.length; index++) this.onSlotDue(sliceSlots[index], nowMs);
4712
+ } finally {
4713
+ if (index < sliceSlots.length - 1) {
4714
+ this.slotsBySliceNumber.set(sliceNumber, sliceSlots.slice(index + 1));
4715
+ this.lowerNextSliceNumber(sliceNumber);
4716
+ }
4991
4717
  }
4992
- sliceSlots.add(slot);
4993
- sliceNumberBySlot.set(slot, flooredSliceNumber);
4994
- this.updateNextSliceNumber(releaseSlotCollectorSlot, flooredSliceNumber);
4995
4718
  }
4996
4719
  };
4997
- _OIMReleaseSlotQueueService.INSTANCE = new _OIMReleaseSlotQueueService();
4998
- var OIMReleaseSlotQueueService = _OIMReleaseSlotQueueService;
4999
4720
 
5000
- // src/engine/collector/OIMReleaseSlotCollectorService.ts
5001
- var OIMReleaseSlotCollectorService = class extends OIMFlushSchedulerService {
5002
- getReleaseSlotCollectorSlotOf(slot) {
5003
- return this.getReleaseSlotCollectorSlot(oimGetChannelSlot(slot).collectorSlot);
4721
+ // src/engine/collector/OIMSlotReleaseWheel.ts
4722
+ var OIMSlotReleaseWheel = class extends OIMSlotWheel {
4723
+ constructor(options) {
4724
+ super(options);
4725
+ this.getReleaseDueMs = options.getReleaseDueMs;
4726
+ this.setReleaseDueMs = options.setReleaseDueMs;
4727
+ this.releaseScheduledSlotFlag = options.releaseScheduledSlotFlag;
5004
4728
  }
5005
- markSlotReleaseDue(releaseSlotCollectorSlot, slot, keepMs) {
5006
- const nowMs = releaseSlotCollectorSlot.getNowMs();
4729
+ markSlotReleaseDue(slot, keepMs) {
4730
+ const nowMs = this.getNowMs();
5007
4731
  this.setReleaseDueMs(slot, nowMs + keepMs);
5008
4732
  return nowMs;
5009
4733
  }
5010
- scheduleSlotRelease(releaseSlotCollectorSlot, slot, nowMs) {
5011
- OIMReleaseSlotQueueService.INSTANCE.scheduleSlotRelease(releaseSlotCollectorSlot, this, slot, nowMs);
4734
+ markSlotReleaseDueNow(slot) {
4735
+ this.setReleaseDueMs(slot, this.getNowMs());
4736
+ slot.owner.releaseSlotIfUnheld(slot);
4737
+ }
4738
+ scheduleSlotRelease(slot, nowMs) {
4739
+ const releaseDueMs = this.getReleaseDueMs(slot);
4740
+ if (releaseDueMs < 0) return;
4741
+ if ((slot.slotFlags & this.releaseScheduledSlotFlag) !== 0) return;
4742
+ this.fileReleaseSlot(oimSliceOfMs(Math.max(releaseDueMs, nowMs)), slot);
4743
+ this.scheduleNextSweep();
5012
4744
  }
5013
- isSlotReleasable(releaseSlotCollectorSlot, slot) {
4745
+ isSlotReleasable(slot) {
5014
4746
  const releaseDueMs = this.getReleaseDueMs(slot);
5015
4747
  if (releaseDueMs < 0) return false;
5016
- const nowMs = releaseSlotCollectorSlot.getNowMs();
4748
+ const nowMs = this.getNowMs();
5017
4749
  if (releaseDueMs <= nowMs) return true;
5018
- OIMReleaseSlotQueueService.INSTANCE.scheduleSlotRelease(releaseSlotCollectorSlot, this, slot, nowMs);
4750
+ this.scheduleSlotRelease(slot, nowMs);
5019
4751
  return false;
5020
4752
  }
5021
- cancelSlotRelease(releaseSlotCollectorSlot, slot) {
4753
+ cancelSlotRelease(slot) {
5022
4754
  if (this.getReleaseDueMs(slot) < 0) return;
5023
- OIMReleaseSlotQueueService.INSTANCE.cancelSlotRelease(releaseSlotCollectorSlot, slot);
5024
- }
5025
- scheduleNextRelease(releaseSlotCollectorSlot) {
5026
- const nextSliceNumber = OIMReleaseSlotQueueService.INSTANCE.getNextReleaseSliceNumber(releaseSlotCollectorSlot);
5027
- if (nextSliceNumber === void 0) return;
5028
- const nowMs = releaseSlotCollectorSlot.getNowMs();
5029
- const untilMs = Math.max(nowMs, (nextSliceNumber + 1) * OIM_SLICE_LENGTH_MS);
5030
- if (this.isScheduled(releaseSlotCollectorSlot)) {
5031
- if (untilMs >= releaseSlotCollectorSlot.scheduledUntilMs) return;
5032
- this.cancelSchedule(releaseSlotCollectorSlot);
5033
- }
5034
- releaseSlotCollectorSlot.scheduledUntilMs = untilMs;
5035
- this.schedule(releaseSlotCollectorSlot, untilMs - nowMs);
4755
+ slot.slotFlags &= ~this.releaseScheduledSlotFlag;
5036
4756
  }
5037
- cancelSchedule(releaseSlotCollectorSlot) {
5038
- releaseSlotCollectorSlot.scheduledUntilMs = Number.POSITIVE_INFINITY;
5039
- super.cancelSchedule(releaseSlotCollectorSlot);
4757
+ isSlotReleaseScheduled(slot) {
4758
+ return (slot.slotFlags & this.releaseScheduledSlotFlag) !== 0;
5040
4759
  }
5041
- flush(releaseSlotCollectorSlot) {
5042
- this.cancelSchedule(releaseSlotCollectorSlot);
5043
- try {
5044
- OIMReleaseSlotQueueService.INSTANCE.releaseDueUpToSliceNumber(
5045
- releaseSlotCollectorSlot,
5046
- this,
5047
- oimSliceOfMs(releaseSlotCollectorSlot.getNowMs())
5048
- );
5049
- } finally {
5050
- this.scheduleNextRelease(releaseSlotCollectorSlot);
4760
+ onSlotDue(slot, nowMs) {
4761
+ const slotFlags = slot.slotFlags;
4762
+ if ((slotFlags & this.releaseScheduledSlotFlag) === 0) return;
4763
+ slot.slotFlags = slotFlags & ~this.releaseScheduledSlotFlag;
4764
+ if (oimIsSlotReleased(slot)) return;
4765
+ const releaseDueMs = this.getReleaseDueMs(slot);
4766
+ if (releaseDueMs < 0) return;
4767
+ if (releaseDueMs > nowMs) {
4768
+ this.fileReleaseSlot(oimSliceOfMs(releaseDueMs), slot);
4769
+ return;
5051
4770
  }
4771
+ slot.owner.releaseSlotIfUnheld(slot);
5052
4772
  }
5053
- onSchedulerTimerFired(releaseSlotCollectorSlot) {
5054
- try {
5055
- this.flush(releaseSlotCollectorSlot);
5056
- } catch (error) {
5057
- releaseSlotCollectorSlot.errorPolicy.onErrorCaught(error);
5058
- }
4773
+ onSlotDropped(slot) {
4774
+ slot.slotFlags &= ~this.releaseScheduledSlotFlag;
5059
4775
  }
5060
- cancelAllSlotReleases(releaseSlotCollectorSlot) {
5061
- this.cancelSchedule(releaseSlotCollectorSlot);
5062
- OIMReleaseSlotQueueService.INSTANCE.cancelAllSlotReleases(releaseSlotCollectorSlot);
4776
+ fileReleaseSlot(sliceNumber, slot) {
4777
+ this.fileSlot(sliceNumber, slot);
4778
+ slot.slotFlags |= this.releaseScheduledSlotFlag;
5063
4779
  }
5064
4780
  };
5065
4781
 
4782
+ // src/engine/collector/constants/OIM_SLOT_FLAG_RELEASE_SCHEDULED_AFTER_WRITE.ts
4783
+ var OIM_SLOT_FLAG_RELEASE_SCHEDULED_AFTER_WRITE = 8;
4784
+
4785
+ // src/engine/slot/utils/oimGetReleaseDueAfterWriteMs.ts
4786
+ function oimGetReleaseDueAfterWriteMs(slot) {
4787
+ return slot.releaseDueAfterWriteMs;
4788
+ }
4789
+
4790
+ // src/engine/slot/utils/oimSetReleaseDueAfterWriteMs.ts
4791
+ function oimSetReleaseDueAfterWriteMs(slot, releaseDueMs) {
4792
+ slot.releaseDueAfterWriteMs = releaseDueMs;
4793
+ }
4794
+
4795
+ // src/engine/collector/utils/oimMintAfterWriteSlotReleaseWheel.ts
4796
+ function oimMintAfterWriteSlotReleaseWheel(collectorSlot) {
4797
+ return collectorSlot.afterWriteSlotReleaseWheel ?? (collectorSlot.afterWriteSlotReleaseWheel = new OIMSlotReleaseWheel({
4798
+ ...collectorSlot.slotWheelOptions,
4799
+ getReleaseDueMs: oimGetReleaseDueAfterWriteMs,
4800
+ setReleaseDueMs: oimSetReleaseDueAfterWriteMs,
4801
+ releaseScheduledSlotFlag: OIM_SLOT_FLAG_RELEASE_SCHEDULED_AFTER_WRITE
4802
+ }));
4803
+ }
4804
+
4805
+ // src/engine/collector/constants/OIM_SLOT_FLAG_RELEASE_SCHEDULED_AFTER_IDLE.ts
4806
+ var OIM_SLOT_FLAG_RELEASE_SCHEDULED_AFTER_IDLE = 4;
4807
+
5066
4808
  // src/engine/slot/utils/oimGetReleaseDueAfterIdleMs.ts
5067
4809
  function oimGetReleaseDueAfterIdleMs(slot) {
5068
4810
  return slot.releaseDueAfterIdleMs;
@@ -5073,73 +4815,142 @@ function oimSetReleaseDueAfterIdleMs(slot, releaseDueMs) {
5073
4815
  slot.releaseDueAfterIdleMs = releaseDueMs;
5074
4816
  }
5075
4817
 
5076
- // src/engine/collector/OIMReleaseSlotCollectorServiceAfterIdle.ts
5077
- var _OIMReleaseSlotCollectorServiceAfterIdle = class _OIMReleaseSlotCollectorServiceAfterIdle extends OIMReleaseSlotCollectorService {
5078
- constructor() {
5079
- super(...arguments);
5080
- this.getReleaseDueMs = oimGetReleaseDueAfterIdleMs;
5081
- this.setReleaseDueMs = oimSetReleaseDueAfterIdleMs;
5082
- }
5083
- getReleaseSlotCollectorSlot(collectorSlot) {
5084
- return collectorSlot.afterIdleReleaseSlotCollectorSlot;
5085
- }
5086
- };
5087
- _OIMReleaseSlotCollectorServiceAfterIdle.INSTANCE = new _OIMReleaseSlotCollectorServiceAfterIdle();
5088
- var OIMReleaseSlotCollectorServiceAfterIdle = _OIMReleaseSlotCollectorServiceAfterIdle;
4818
+ // src/engine/collector/utils/oimMintAfterIdleSlotReleaseWheel.ts
4819
+ function oimMintAfterIdleSlotReleaseWheel(collectorSlot) {
4820
+ return collectorSlot.afterIdleSlotReleaseWheel ?? (collectorSlot.afterIdleSlotReleaseWheel = new OIMSlotReleaseWheel({
4821
+ ...collectorSlot.slotWheelOptions,
4822
+ getReleaseDueMs: oimGetReleaseDueAfterIdleMs,
4823
+ setReleaseDueMs: oimSetReleaseDueAfterIdleMs,
4824
+ releaseScheduledSlotFlag: OIM_SLOT_FLAG_RELEASE_SCHEDULED_AFTER_IDLE
4825
+ }));
4826
+ }
5089
4827
 
5090
- // src/engine/slot/utils/oimGetReleaseDueAfterWriteMs.ts
5091
- function oimGetReleaseDueAfterWriteMs(slot) {
5092
- return slot.releaseDueAfterWriteMs;
4828
+ // src/engine/collector/constants/OIM_SLOT_FLAG_RELEASE_SCHEDULED_AFTER_UNHOLD.ts
4829
+ var OIM_SLOT_FLAG_RELEASE_SCHEDULED_AFTER_UNHOLD = 16;
4830
+
4831
+ // src/engine/slot/utils/oimGetReleaseDueAfterUnholdMs.ts
4832
+ function oimGetReleaseDueAfterUnholdMs(slot) {
4833
+ return slot.releaseDueAfterUnholdMs;
5093
4834
  }
5094
4835
 
5095
- // src/engine/slot/utils/oimSetReleaseDueAfterWriteMs.ts
5096
- function oimSetReleaseDueAfterWriteMs(slot, releaseDueMs) {
5097
- slot.releaseDueAfterWriteMs = releaseDueMs;
4836
+ // src/engine/slot/utils/oimSetReleaseDueAfterUnholdMs.ts
4837
+ function oimSetReleaseDueAfterUnholdMs(slot, releaseDueMs) {
4838
+ slot.releaseDueAfterUnholdMs = releaseDueMs;
5098
4839
  }
5099
4840
 
5100
- // src/engine/collector/OIMReleaseSlotCollectorServiceAfterWrite.ts
5101
- var _OIMReleaseSlotCollectorServiceAfterWrite = class _OIMReleaseSlotCollectorServiceAfterWrite extends OIMReleaseSlotCollectorService {
5102
- constructor() {
5103
- super(...arguments);
5104
- this.getReleaseDueMs = oimGetReleaseDueAfterWriteMs;
5105
- this.setReleaseDueMs = oimSetReleaseDueAfterWriteMs;
4841
+ // src/engine/collector/utils/oimMintAfterUnholdSlotReleaseWheel.ts
4842
+ function oimMintAfterUnholdSlotReleaseWheel(collectorSlot) {
4843
+ return collectorSlot.afterUnholdSlotReleaseWheel ?? (collectorSlot.afterUnholdSlotReleaseWheel = new OIMSlotReleaseWheel({
4844
+ ...collectorSlot.slotWheelOptions,
4845
+ getReleaseDueMs: oimGetReleaseDueAfterUnholdMs,
4846
+ setReleaseDueMs: oimSetReleaseDueAfterUnholdMs,
4847
+ releaseScheduledSlotFlag: OIM_SLOT_FLAG_RELEASE_SCHEDULED_AFTER_UNHOLD
4848
+ }));
4849
+ }
4850
+
4851
+ // src/engine/collector/OIMSlotRefetchWheel.ts
4852
+ var OIMSlotRefetchWheel = class extends OIMSlotWheel {
4853
+ constructor(options) {
4854
+ super({
4855
+ getNowMs: options.getNowMs ?? Date.now,
4856
+ timer: options.timer ?? OIM_TIMER_ON_TIMEOUT,
4857
+ errorPolicy: options.errorPolicy ?? OIMLogAndContinueErrorPolicy.INSTANCE
4858
+ });
4859
+ this.refetchDueSlots = [];
4860
+ this.slotRefetchListener = options.slotRefetchListener;
4861
+ }
4862
+ scheduleSlotRefetchAt(slot, atMs) {
4863
+ this.fileSlot(oimSliceOfMs(atMs), slot);
4864
+ this.scheduleNextSweep();
4865
+ }
4866
+ getSweptSliceNumberAt(nowMs) {
4867
+ return oimSliceOfMs(nowMs) - 1;
4868
+ }
4869
+ onSlotDue(slot) {
4870
+ if (oimIsSlotReleased(slot)) return;
4871
+ if (slot.effects === void 0 || slot.effects.length === 0) return;
4872
+ this.refetchDueSlots.push(slot);
4873
+ }
4874
+ onSweepFinished() {
4875
+ const refetchDueSlots = this.refetchDueSlots;
4876
+ if (refetchDueSlots.length === 0) return;
4877
+ try {
4878
+ this.slotRefetchListener.onSlotsRefetchDue(refetchDueSlots);
4879
+ } finally {
4880
+ refetchDueSlots.length = 0;
4881
+ }
5106
4882
  }
5107
- getReleaseSlotCollectorSlot(collectorSlot) {
5108
- return collectorSlot.afterWriteReleaseSlotCollectorSlot;
4883
+ };
4884
+
4885
+ // src/engine/collector/OIMSlotReleaseAutoDueFramePolicy.ts
4886
+ var _OIMSlotReleaseAutoDueFramePolicy = class _OIMSlotReleaseAutoDueFramePolicy {
4887
+ isSlotReleaseDueFrameOpen() {
4888
+ return true;
5109
4889
  }
5110
4890
  };
5111
- _OIMReleaseSlotCollectorServiceAfterWrite.INSTANCE = new _OIMReleaseSlotCollectorServiceAfterWrite();
5112
- var OIMReleaseSlotCollectorServiceAfterWrite = _OIMReleaseSlotCollectorServiceAfterWrite;
4891
+ _OIMSlotReleaseAutoDueFramePolicy.INSTANCE = new _OIMSlotReleaseAutoDueFramePolicy();
4892
+ var OIMSlotReleaseAutoDueFramePolicy = _OIMSlotReleaseAutoDueFramePolicy;
5113
4893
 
5114
- // src/engine/collector/OIMSlotReleasePolicyAfterWrite.ts
5115
- var OIMSlotReleasePolicyAfterWrite = class {
4894
+ // src/engine/collector/OIMSlotAfterWriteReleasePolicy.ts
4895
+ var OIMSlotAfterWriteReleasePolicy = class {
5116
4896
  constructor(options) {
5117
4897
  this.releasesWrittenSlots = true;
5118
4898
  this.schedulesReleaseOnWrite = true;
5119
4899
  this.keepAfterWriteMs = options.keepAfterWriteMs;
4900
+ this.slotReleaseDueFramePolicy = options.slotReleaseDueFramePolicy ?? OIMSlotReleaseAutoDueFramePolicy.INSTANCE;
5120
4901
  }
5121
4902
  onSlotWritten(slot) {
5122
- OIMReleaseSlotCollectorServiceAfterWrite.INSTANCE.markSlotReleaseDue(OIMReleaseSlotCollectorServiceAfterWrite.INSTANCE.getReleaseSlotCollectorSlotOf(slot), slot, this.keepAfterWriteMs);
4903
+ if (!this.slotReleaseDueFramePolicy.isSlotReleaseDueFrameOpen()) return;
4904
+ oimMintAfterWriteSlotReleaseWheel(oimGetChannelSlot(slot).collectorSlot).markSlotReleaseDue(slot, this.keepAfterWriteMs);
5123
4905
  }
5124
4906
  onSlotIdle(slot) {
5125
- return OIMReleaseSlotCollectorServiceAfterWrite.INSTANCE.isSlotReleasable(OIMReleaseSlotCollectorServiceAfterWrite.INSTANCE.getReleaseSlotCollectorSlotOf(slot), slot);
4907
+ return oimMintAfterWriteSlotReleaseWheel(oimGetChannelSlot(slot).collectorSlot).isSlotReleasable(slot);
5126
4908
  }
5127
4909
  onSlotUnheld() {
5128
4910
  return;
5129
4911
  }
5130
4912
  isSlotReleasable(slot) {
5131
- return OIMReleaseSlotCollectorServiceAfterWrite.INSTANCE.isSlotReleasable(OIMReleaseSlotCollectorServiceAfterWrite.INSTANCE.getReleaseSlotCollectorSlotOf(slot), slot);
4913
+ return oimMintAfterWriteSlotReleaseWheel(oimGetChannelSlot(slot).collectorSlot).isSlotReleasable(slot);
5132
4914
  }
5133
4915
  isEmptySlotReleasable() {
5134
4916
  return true;
5135
4917
  }
5136
4918
  cancelSlotRelease(slot) {
5137
- OIMReleaseSlotCollectorServiceAfterWrite.INSTANCE.cancelSlotRelease(OIMReleaseSlotCollectorServiceAfterWrite.INSTANCE.getReleaseSlotCollectorSlotOf(slot), slot);
4919
+ oimMintAfterWriteSlotReleaseWheel(oimGetChannelSlot(slot).collectorSlot).cancelSlotRelease(slot);
4920
+ }
4921
+ };
4922
+
4923
+ // src/engine/collector/OIMSlotReleaseManualDueFramePolicy.ts
4924
+ var OIMSlotReleaseManualDueFramePolicy = class {
4925
+ constructor() {
4926
+ this.slotReleaseDueFrameDepth = 0;
4927
+ }
4928
+ isSlotReleaseDueFrameOpen() {
4929
+ return this.slotReleaseDueFrameDepth !== 0;
4930
+ }
4931
+ openSlotReleaseDueFrame() {
4932
+ this.slotReleaseDueFrameDepth++;
4933
+ }
4934
+ closeSlotReleaseDueFrame() {
4935
+ if (this.slotReleaseDueFrameDepth === 0) {
4936
+ throw new Error(
4937
+ "OIMSlotReleaseManualDueFramePolicy.closeSlotReleaseDueFrame: no frame is open. Every closeSlotReleaseDueFrame answers one openSlotReleaseDueFrame."
4938
+ );
4939
+ }
4940
+ this.slotReleaseDueFrameDepth--;
4941
+ }
4942
+ writeInSlotReleaseDueFrame(write) {
4943
+ this.openSlotReleaseDueFrame();
4944
+ try {
4945
+ write();
4946
+ } finally {
4947
+ this.closeSlotReleaseDueFrame();
4948
+ }
5138
4949
  }
5139
4950
  };
5140
4951
 
5141
- // src/engine/collector/OIMSlotReleasePolicyAfterIdle.ts
5142
- var OIMSlotReleasePolicyAfterIdle = class {
4952
+ // src/engine/collector/OIMSlotAfterIdleReleasePolicy.ts
4953
+ var OIMSlotAfterIdleReleasePolicy = class {
5143
4954
  constructor(options) {
5144
4955
  this.releasesWrittenSlots = true;
5145
4956
  this.schedulesReleaseOnWrite = true;
@@ -5149,29 +4960,28 @@ var OIMSlotReleasePolicyAfterIdle = class {
5149
4960
  return;
5150
4961
  }
5151
4962
  onSlotIdle(slot) {
5152
- const releaseSlotCollectorService = OIMReleaseSlotCollectorServiceAfterIdle.INSTANCE;
5153
- const releaseSlotCollectorSlot = OIMReleaseSlotCollectorServiceAfterIdle.INSTANCE.getReleaseSlotCollectorSlotOf(slot);
5154
- const nowMs = releaseSlotCollectorService.markSlotReleaseDue(releaseSlotCollectorSlot, slot, this.keepAfterIdleMs);
4963
+ const afterIdleSlotReleaseWheel = oimMintAfterIdleSlotReleaseWheel(oimGetChannelSlot(slot).collectorSlot);
4964
+ const nowMs = afterIdleSlotReleaseWheel.markSlotReleaseDue(slot, this.keepAfterIdleMs);
5155
4965
  if (this.keepAfterIdleMs <= 0) return true;
5156
- releaseSlotCollectorService.scheduleSlotRelease(releaseSlotCollectorSlot, slot, nowMs);
4966
+ afterIdleSlotReleaseWheel.scheduleSlotRelease(slot, nowMs);
5157
4967
  return false;
5158
4968
  }
5159
4969
  onSlotUnheld() {
5160
4970
  return;
5161
4971
  }
5162
4972
  isSlotReleasable(slot) {
5163
- return OIMReleaseSlotCollectorServiceAfterIdle.INSTANCE.isSlotReleasable(OIMReleaseSlotCollectorServiceAfterIdle.INSTANCE.getReleaseSlotCollectorSlotOf(slot), slot);
4973
+ return oimMintAfterIdleSlotReleaseWheel(oimGetChannelSlot(slot).collectorSlot).isSlotReleasable(slot);
5164
4974
  }
5165
4975
  isEmptySlotReleasable() {
5166
4976
  return true;
5167
4977
  }
5168
4978
  cancelSlotRelease(slot) {
5169
- OIMReleaseSlotCollectorServiceAfterIdle.INSTANCE.cancelSlotRelease(OIMReleaseSlotCollectorServiceAfterIdle.INSTANCE.getReleaseSlotCollectorSlotOf(slot), slot);
4979
+ oimMintAfterIdleSlotReleaseWheel(oimGetChannelSlot(slot).collectorSlot).cancelSlotRelease(slot);
5170
4980
  }
5171
4981
  };
5172
4982
 
5173
- // src/engine/collector/OIMSlotReleasePolicyNever.ts
5174
- var _OIMSlotReleasePolicyNever = class _OIMSlotReleasePolicyNever {
4983
+ // src/engine/collector/OIMSlotNeverReleasePolicy.ts
4984
+ var _OIMSlotNeverReleasePolicy = class _OIMSlotNeverReleasePolicy {
5175
4985
  constructor() {
5176
4986
  this.releasesWrittenSlots = false;
5177
4987
  this.schedulesReleaseOnWrite = false;
@@ -5195,35 +5005,11 @@ var _OIMSlotReleasePolicyNever = class _OIMSlotReleasePolicyNever {
5195
5005
  return;
5196
5006
  }
5197
5007
  };
5198
- _OIMSlotReleasePolicyNever.INSTANCE = new _OIMSlotReleasePolicyNever();
5199
- var OIMSlotReleasePolicyNever = _OIMSlotReleasePolicyNever;
5200
-
5201
- // src/engine/slot/utils/oimGetReleaseDueAfterUnholdMs.ts
5202
- function oimGetReleaseDueAfterUnholdMs(slot) {
5203
- return slot.releaseDueAfterUnholdMs;
5204
- }
5205
-
5206
- // src/engine/slot/utils/oimSetReleaseDueAfterUnholdMs.ts
5207
- function oimSetReleaseDueAfterUnholdMs(slot, releaseDueMs) {
5208
- slot.releaseDueAfterUnholdMs = releaseDueMs;
5209
- }
5210
-
5211
- // src/engine/collector/OIMReleaseSlotCollectorServiceAfterUnhold.ts
5212
- var _OIMReleaseSlotCollectorServiceAfterUnhold = class _OIMReleaseSlotCollectorServiceAfterUnhold extends OIMReleaseSlotCollectorService {
5213
- constructor() {
5214
- super(...arguments);
5215
- this.getReleaseDueMs = oimGetReleaseDueAfterUnholdMs;
5216
- this.setReleaseDueMs = oimSetReleaseDueAfterUnholdMs;
5217
- }
5218
- getReleaseSlotCollectorSlot(collectorSlot) {
5219
- return collectorSlot.afterUnholdReleaseSlotCollectorSlot;
5220
- }
5221
- };
5222
- _OIMReleaseSlotCollectorServiceAfterUnhold.INSTANCE = new _OIMReleaseSlotCollectorServiceAfterUnhold();
5223
- var OIMReleaseSlotCollectorServiceAfterUnhold = _OIMReleaseSlotCollectorServiceAfterUnhold;
5008
+ _OIMSlotNeverReleasePolicy.INSTANCE = new _OIMSlotNeverReleasePolicy();
5009
+ var OIMSlotNeverReleasePolicy = _OIMSlotNeverReleasePolicy;
5224
5010
 
5225
- // src/engine/collector/OIMSlotReleasePolicyAfterUnhold.ts
5226
- var OIMSlotReleasePolicyAfterUnhold = class {
5011
+ // src/engine/collector/OIMSlotAfterUnholdReleasePolicy.ts
5012
+ var OIMSlotAfterUnholdReleasePolicy = class {
5227
5013
  constructor(options) {
5228
5014
  this.releasesWrittenSlots = true;
5229
5015
  this.schedulesReleaseOnWrite = false;
@@ -5236,24 +5022,24 @@ var OIMSlotReleasePolicyAfterUnhold = class {
5236
5022
  return false;
5237
5023
  }
5238
5024
  onSlotUnheld(slot) {
5239
- OIMReleaseSlotCollectorServiceAfterUnhold.INSTANCE.markSlotReleaseDue(OIMReleaseSlotCollectorServiceAfterUnhold.INSTANCE.getReleaseSlotCollectorSlotOf(slot), slot, this.keepAfterUnholdMs);
5025
+ oimMintAfterUnholdSlotReleaseWheel(oimGetChannelSlot(slot).collectorSlot).markSlotReleaseDue(slot, this.keepAfterUnholdMs);
5240
5026
  }
5241
5027
  isSlotReleasable(slot) {
5242
- return OIMReleaseSlotCollectorServiceAfterUnhold.INSTANCE.isSlotReleasable(OIMReleaseSlotCollectorServiceAfterUnhold.INSTANCE.getReleaseSlotCollectorSlotOf(slot), slot);
5028
+ return oimMintAfterUnholdSlotReleaseWheel(oimGetChannelSlot(slot).collectorSlot).isSlotReleasable(slot);
5243
5029
  }
5244
5030
  isEmptySlotReleasable() {
5245
5031
  return true;
5246
5032
  }
5247
5033
  cancelSlotRelease(slot) {
5248
- OIMReleaseSlotCollectorServiceAfterUnhold.INSTANCE.cancelSlotRelease(OIMReleaseSlotCollectorServiceAfterUnhold.INSTANCE.getReleaseSlotCollectorSlotOf(slot), slot);
5034
+ oimMintAfterUnholdSlotReleaseWheel(oimGetChannelSlot(slot).collectorSlot).cancelSlotRelease(slot);
5249
5035
  }
5250
5036
  };
5251
5037
 
5252
- // src/engine/collector/OIMSlotReleasePolicyEarliest.ts
5038
+ // src/engine/collector/OIMSlotEarliestReleasePolicy.ts
5253
5039
  var askOnSlotIdle = (slotReleasePolicy, slot) => slotReleasePolicy.onSlotIdle(slot);
5254
5040
  var askIsSlotReleasable = (slotReleasePolicy, slot) => slotReleasePolicy.isSlotReleasable(slot);
5255
5041
  var askIsEmptySlotReleasable = (slotReleasePolicy, slot) => slotReleasePolicy.isEmptySlotReleasable(slot);
5256
- var OIMSlotReleasePolicyEarliest = class {
5042
+ var OIMSlotEarliestReleasePolicy = class {
5257
5043
  constructor(slotReleasePolicies) {
5258
5044
  this.slotReleasePolicies = slotReleasePolicies;
5259
5045
  let releasesWrittenSlots = false;
@@ -5296,52 +5082,48 @@ var OIMSlotReleasePolicyEarliest = class {
5296
5082
  }
5297
5083
  };
5298
5084
 
5299
- // src/engine/bucket/utils/oimSameUniqueSlotSequence.ts
5300
- function oimSameUniqueSlotSequence(heldBucketMemberSlots, bucketMemberSlots) {
5301
- const seenBucketMemberSlots = /* @__PURE__ */ new Set();
5302
- let at = 0;
5303
- for (let i = 0; i < bucketMemberSlots.length; i++) {
5304
- const bucketMemberSlot = bucketMemberSlots[i];
5305
- if (seenBucketMemberSlots.has(bucketMemberSlot)) continue;
5306
- seenBucketMemberSlots.add(bucketMemberSlot);
5307
- if (at >= heldBucketMemberSlots.length || heldBucketMemberSlots[at] !== bucketMemberSlot) return false;
5308
- at++;
5085
+ // src/engine/store/OIMSlotTreeStoreService.ts
5086
+ var OIMSlotTreeStoreService = class {
5087
+ constructor(keyTreeWalk) {
5088
+ this.keyTreeWalk = keyTreeWalk;
5309
5089
  }
5310
- return at === heldBucketMemberSlots.length;
5311
- }
5312
-
5313
- // src/engine/bucket/array/OIMBucketArrayMembershipUnique.ts
5314
- var OIMBucketArrayMembershipUnique = class {
5315
5090
  createStore() {
5316
- return {
5317
- bucketMemberSlots: [],
5318
- uniqueBucketMemberSlots: /* @__PURE__ */ new Set()
5319
- };
5091
+ return { root: { childNodes: void 0, atThisKey: void 0 }, slots: /* @__PURE__ */ new Set() };
5320
5092
  }
5321
- addSlot(bucketSlotsArrayUniqueStore, bucketMemberSlot) {
5322
- if (bucketSlotsArrayUniqueStore.uniqueBucketMemberSlots.has(bucketMemberSlot)) return false;
5323
- bucketSlotsArrayUniqueStore.uniqueBucketMemberSlots.add(bucketMemberSlot);
5324
- return true;
5093
+ ownKey(compositeKey) {
5094
+ return compositeKey.slice();
5095
+ }
5096
+ isSameKey(compositeKey, otherCompositeKey) {
5097
+ return oimSameKeySequence(compositeKey, otherCompositeKey);
5098
+ }
5099
+ get(slotStoreTree, compositeKey) {
5100
+ return this.keyTreeWalk.nodeAt(slotStoreTree.root, compositeKey)?.atThisKey;
5101
+ }
5102
+ set(slotStoreTree, compositeKey, slot) {
5103
+ const compositeKeyNode = this.keyTreeWalk.mintNodeAt(slotStoreTree.root, compositeKey);
5104
+ const filedSlot = compositeKeyNode.atThisKey;
5105
+ if (filedSlot !== void 0 && filedSlot !== slot) slotStoreTree.slots.delete(filedSlot);
5106
+ compositeKeyNode.atThisKey = slot;
5107
+ slotStoreTree.slots.add(slot);
5325
5108
  }
5326
- removeSlot(bucketSlotsArrayUniqueStore, bucketMemberSlot) {
5327
- return bucketSlotsArrayUniqueStore.uniqueBucketMemberSlots.delete(bucketMemberSlot);
5109
+ remove(slotStoreTree, compositeKey) {
5110
+ const slot = this.keyTreeWalk.deleteKey(slotStoreTree.root, compositeKey);
5111
+ if (slot !== void 0) slotStoreTree.slots.delete(slot);
5328
5112
  }
5329
- hasSlot(bucketSlotsArrayUniqueStore, bucketMemberSlot) {
5330
- return bucketSlotsArrayUniqueStore.uniqueBucketMemberSlots.has(bucketMemberSlot);
5113
+ fileSlot(slotStoreTree, slot) {
5114
+ this.set(slotStoreTree, slot.key, slot);
5331
5115
  }
5332
- clearSlots(bucketSlotsArrayUniqueStore) {
5333
- bucketSlotsArrayUniqueStore.uniqueBucketMemberSlots.clear();
5116
+ unfileSlot(slotStoreTree, slot) {
5117
+ this.remove(slotStoreTree, slot.key);
5334
5118
  }
5335
- containsTheSameSequence(bucketSlotsArrayUniqueStore, bucketMemberSlots) {
5336
- const heldBucketMemberSlots = bucketSlotsArrayUniqueStore.bucketMemberSlots;
5337
- if (bucketMemberSlots.length < heldBucketMemberSlots.length) return false;
5338
- return oimSameUniqueSlotSequence(heldBucketMemberSlots, bucketMemberSlots);
5119
+ getSlots(slotStoreTree) {
5120
+ return slotStoreTree.slots.values();
5121
+ }
5122
+ getSlotCount(slotStoreTree) {
5123
+ return slotStoreTree.slots.size;
5339
5124
  }
5340
5125
  };
5341
5126
 
5342
- // src/engine/bucket/constants/OIM_NOTHING_WAS_INSERTED.ts
5343
- var OIM_NOTHING_WAS_INSERTED = -1;
5344
-
5345
5127
  // src/engine/bucket/commands/constants/OIM_MAX_DIFF_SCRATCH_SLOTS.ts
5346
5128
  var OIM_MAX_DIFF_SCRATCH_SLOTS = 4096;
5347
5129
 
@@ -5446,82 +5228,81 @@ function collectAnchors(sequence, count, anchorBuffer) {
5446
5228
  // src/index.ts
5447
5229
  oimRegisterCoreInstance(OIMDB);
5448
5230
  export {
5449
- OIMBucketArrayMembershipNonUnique,
5450
- OIMBucketArrayMembershipUnique,
5231
+ OIMAppendingIndexKeysService,
5451
5232
  OIMBucketCommands,
5233
+ OIMBucketMemberSlotsArrayService,
5234
+ OIMBucketMemoComputedService,
5235
+ OIMBucketUniqueMemberSlotsArrayService,
5452
5236
  OIMChannelService,
5453
- OIMColumnOwner,
5454
- OIMColumnOwnerPullDriven,
5237
+ OIMColumnSlotOwner,
5238
+ OIMColumnSlotService,
5239
+ OIMCompositeKeyTreeWalk,
5455
5240
  OIMComputedService,
5456
- OIMComputedServiceBucketMemo,
5457
- OIMComputedServiceSorted,
5458
5241
  OIMComputedValueService,
5459
5242
  OIMContentChangeListenerService,
5460
5243
  OIMDB,
5461
5244
  OIMDefaultValue,
5462
5245
  OIMDefaults,
5463
5246
  OIMEffectService,
5464
- OIMErrorPolicyLogAndContinue,
5465
- OIMErrorPolicyThrowAtOnce,
5466
5247
  OIMFlushSchedulerService,
5467
5248
  OIMIndexKeysService,
5468
- OIMIndexKeysServiceAppending,
5469
- OIMIndexKeysServiceReclaiming,
5470
- OIMIndexService,
5471
- OIMIndexServiceSortedArrayDriven,
5472
5249
  OIMKeyTreeWalk,
5473
- OIMKeyTreeWalkComposite,
5474
- OIMKeyTreeWalkScalar,
5475
- OIMReleaseSlotCollectorService,
5476
- OIMReleaseSlotCollectorServiceAfterIdle,
5477
- OIMReleaseSlotCollectorServiceAfterUnhold,
5478
- OIMReleaseSlotCollectorServiceAfterWrite,
5479
- OIMReleaseSlotQueueService,
5250
+ OIMLogAndContinueErrorPolicy,
5251
+ OIMNoSlotSubscriptionListener,
5252
+ OIMNoStoreSlotListener,
5253
+ OIMPullColumnSlotOwner,
5254
+ OIMReclaimingIndexKeysService,
5255
+ OIMScalarKeyTreeWalk,
5256
+ OIMSingleComputedService,
5480
5257
  OIMSingleSlotService,
5258
+ OIMSingleSlotStoreService,
5259
+ OIMSlotAfterIdleReleasePolicy,
5260
+ OIMSlotAfterUnholdReleasePolicy,
5261
+ OIMSlotAfterWriteReleasePolicy,
5262
+ OIMSlotAtEmptyReleasePolicy,
5263
+ OIMSlotAtUnholdReleasePolicy,
5264
+ OIMSlotCollectionIndexService,
5481
5265
  OIMSlotCollectionService,
5482
- OIMSlotColumnService,
5266
+ OIMSlotCollectionSortedArrayIndexService,
5267
+ OIMSlotContentArrayBucketService,
5483
5268
  OIMSlotContentBucketService,
5484
- OIMSlotContentBucketServiceArrayBased,
5485
- OIMSlotContentBucketServiceArrayDriven,
5486
- OIMSlotContentBucketServiceSetDriven,
5487
- OIMSlotContentBucketServiceSortedArrayDriven,
5488
5269
  OIMSlotContentEntityService,
5270
+ OIMSlotContentPositionalArrayBucketService,
5271
+ OIMSlotContentSetBucketService,
5272
+ OIMSlotContentSortedArrayBucketService,
5273
+ OIMSlotEarliestReleasePolicy,
5274
+ OIMSlotMapStoreService,
5275
+ OIMSlotNeverReleasePolicy,
5489
5276
  OIMSlotOwner,
5490
- OIMSlotReleasePolicyAfterIdle,
5491
- OIMSlotReleasePolicyAfterUnhold,
5492
- OIMSlotReleasePolicyAfterWrite,
5493
- OIMSlotReleasePolicyAtEmpty,
5494
- OIMSlotReleasePolicyAtUnhold,
5495
- OIMSlotReleasePolicyEarliest,
5496
- OIMSlotReleasePolicyNever,
5497
- OIMSlotStoreServiceMapDriven,
5498
- OIMSlotStoreServiceSingleSlotDriven,
5499
- OIMSlotStoreServiceTreeDriven,
5500
- OIMStoreSlotListenerNone,
5277
+ OIMSlotRefetchWheel,
5278
+ OIMSlotReleaseAutoDueFramePolicy,
5279
+ OIMSlotReleaseManualDueFramePolicy,
5280
+ OIMSlotReleaseWheel,
5281
+ OIMSlotTreeStoreService,
5282
+ OIMSlotWheel,
5283
+ OIMSortedComputedService,
5284
+ OIMThrowAtOnceErrorPolicy,
5501
5285
  OIMUnusedSlotCollectorService,
5286
+ OIMWritableSingleSlotService,
5287
+ OIMWritableSlotCollectionService,
5502
5288
  OIM_FROZEN_EMPTY_SLOTS,
5503
5289
  OIM_NOTHING_WAS_INSERTED,
5504
5290
  OIM_NOTHING_WAS_REMOVED,
5505
5291
  OIM_REMOVED_WITHOUT_A_POSITION,
5506
5292
  OIM_SLICE_LENGTH_MS,
5507
- createOIMBucketService,
5293
+ createOIMBucketMemoComputedService,
5508
5294
  createOIMChannelSlot,
5509
5295
  createOIMCollectorSlot,
5510
5296
  createOIMComputedService,
5511
- createOIMComputedServiceBucketMemo,
5512
- createOIMComputedServiceSorted,
5513
- createOIMEntityService,
5514
5297
  createOIMEntityWriterInPlace,
5515
5298
  createOIMEntityWriterReplacing,
5516
- createOIMIndexService,
5517
- createOIMIndexServiceByCompositeKey,
5518
- createOIMIndexServiceSortedArrayDriven,
5519
- createOIMReleaseSlotCollectorSlot,
5520
- createOIMSingleBucketService,
5521
- createOIMSingleEntityService,
5299
+ createOIMSingleComputedService,
5522
5300
  createOIMSingleSlotService,
5301
+ createOIMSlotCollectionIndexService,
5523
5302
  createOIMSlotCollectionService,
5303
+ createOIMSlotCollectionSortedArrayIndexService,
5524
5304
  createOIMSlotContentEntityService,
5305
+ createOIMSortedComputedService,
5525
5306
  createOIMUnusedSlotCollectorSlot,
5526
5307
  oimColumnsComparator,
5527
5308
  oimHoldSlots,
@@ -5531,6 +5312,9 @@ export {
5531
5312
  oimIsAnySlotChangedAfter,
5532
5313
  oimIsSlotEmpty,
5533
5314
  oimIsSlotReleased,
5315
+ oimMintAfterIdleSlotReleaseWheel,
5316
+ oimMintAfterUnholdSlotReleaseWheel,
5317
+ oimMintAfterWriteSlotReleaseWheel,
5534
5318
  oimOrderedListCommandsOfTransition,
5535
5319
  oimPatchEntityColumn,
5536
5320
  oimPatchEntityColumnGuarded,