@sovereignbase/convergent-replicated-list 1.3.4 → 1.3.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -294,8 +294,17 @@ function trySpliceReplacement(crListReplica, insertedEntries, reparentedEntries,
294
294
  } else if (_optionalChain([crListReplica, 'access', _23 => _23.childrenMap, 'access', _24 => _24.get, 'call', _25 => _25(inserted.uuidv7), 'optionalAccess', _26 => _26.length])) {
295
295
  return false;
296
296
  }
297
- if (_optionalChain([predecessor, 'optionalAccess', _27 => _27.next]) !== next) return false;
298
- if (!predecessor && crListReplica.cursor !== next) return false;
297
+ if (predecessor) {
298
+ if (predecessor.next !== next) return false;
299
+ } else {
300
+ let reachable = 0;
301
+ let current2 = next;
302
+ while (current2) {
303
+ reachable++;
304
+ current2 = current2.next;
305
+ }
306
+ if (reachable !== crListReplica.parentMap.size - 1) return false;
307
+ }
299
308
  const expectedIndex = predecessor ? predecessor.index + 1 : 0;
300
309
  void linkEntryBetween(predecessor, inserted, next);
301
310
  let current = inserted;
@@ -312,6 +321,48 @@ function trySpliceReplacement(crListReplica, insertedEntries, reparentedEntries,
312
321
  return true;
313
322
  }
314
323
 
324
+ // src/.helpers/trySpliceSiblingInsert/index.ts
325
+ function trySpliceSiblingInsert(crListReplica, insertedEntries, reparentedEntries, tombstoneCount) {
326
+ if (tombstoneCount !== 0 || insertedEntries.length !== 1 || reparentedEntries.length !== 0)
327
+ return false;
328
+ const inserted = insertedEntries[0];
329
+ if (inserted.predecessor === "\0") return false;
330
+ if (_optionalChain([crListReplica, 'access', _27 => _27.childrenMap, 'access', _28 => _28.get, 'call', _29 => _29(inserted.uuidv7), 'optionalAccess', _30 => _30.length])) return false;
331
+ const predecessor = crListReplica.parentMap.get(inserted.predecessor);
332
+ const siblings = crListReplica.childrenMap.get(inserted.predecessor);
333
+ if (!predecessor || !siblings || siblings.length < 2) return false;
334
+ void siblings.sort((a, b) => a.uuidv7 > b.uuidv7 ? 1 : -1);
335
+ const siblingIndex = siblings.indexOf(inserted);
336
+ if (siblingIndex === -1) return false;
337
+ const lastSibling = siblings[siblings.length - 1];
338
+ if (lastSibling !== inserted && lastSibling.next) return false;
339
+ const previousSibling = siblings[siblingIndex - 1];
340
+ const nextSibling = siblings[siblingIndex + 1];
341
+ if (_optionalChain([previousSibling, 'optionalAccess', _31 => _31.uuidv7])) {
342
+ if (_optionalChain([crListReplica, 'access', _32 => _32.childrenMap, 'access', _33 => _33.get, 'call', _34 => _34(previousSibling.uuidv7), 'optionalAccess', _35 => _35.length]))
343
+ return false;
344
+ if (previousSibling.next !== nextSibling) return false;
345
+ } else if (predecessor.next !== nextSibling) {
346
+ return false;
347
+ }
348
+ const prev = _nullishCoalesce(previousSibling, () => ( predecessor));
349
+ const next = nextSibling;
350
+ if (next && next.prev !== prev) return false;
351
+ void linkEntryBetween(prev, inserted, next);
352
+ let current = inserted;
353
+ let index = prev.index + 1;
354
+ while (current) {
355
+ current.index = index;
356
+ index++;
357
+ current = current.next;
358
+ }
359
+ crListReplica.index = /* @__PURE__ */ new Map([[inserted.index, inserted]]);
360
+ crListReplica.cursor = inserted;
361
+ crListReplica.cursorIndex = inserted.index;
362
+ crListReplica.size = crListReplica.parentMap.size;
363
+ return true;
364
+ }
365
+
315
366
  // src/core/crud/create/index.ts
316
367
 
317
368
  function __create(snapshot) {
@@ -343,11 +394,11 @@ function __create(snapshot) {
343
394
  );
344
395
  if (!linkedListEntry) continue;
345
396
  void attachEntryToIndexes(crListReplica, linkedListEntry);
346
- if (canUseLinearProjection && linkedListEntry.predecessor === (_nullishCoalesce(_optionalChain([previous, 'optionalAccess', _28 => _28.uuidv7]), () => ( "\0")))) {
397
+ if (canUseLinearProjection && linkedListEntry.predecessor === (_nullishCoalesce(_optionalChain([previous, 'optionalAccess', _36 => _36.uuidv7]), () => ( "\0")))) {
347
398
  linkedListEntry.index = crListReplica.parentMap.size - 1;
348
399
  void linkEntryBetween(previous, linkedListEntry, void 0);
349
400
  previous = linkedListEntry;
350
- void _optionalChain([crListReplica, 'access', _29 => _29.index, 'optionalAccess', _30 => _30.set, 'call', _31 => _31(linkedListEntry.index, linkedListEntry)]);
401
+ void _optionalChain([crListReplica, 'access', _37 => _37.index, 'optionalAccess', _38 => _38.set, 'call', _39 => _39(linkedListEntry.index, linkedListEntry)]);
351
402
  continue;
352
403
  }
353
404
  canUseLinearProjection = false;
@@ -366,7 +417,7 @@ function __create(snapshot) {
366
417
  function __read(targetIndex, crListReplica) {
367
418
  try {
368
419
  void seekCursorToIndex(targetIndex, crListReplica);
369
- return _optionalChain([crListReplica, 'access', _32 => _32.cursor, 'optionalAccess', _33 => _33.value]);
420
+ return _optionalChain([crListReplica, 'access', _40 => _40.cursor, 'optionalAccess', _41 => _41.value]);
370
421
  } catch (e) {
371
422
  return void 0;
372
423
  }
@@ -402,7 +453,7 @@ function __update(listIndex, listValues, crListReplica, mode) {
402
453
  crListReplica.cursor = linkedListEntry;
403
454
  crListReplica.cursorIndex = linkedListEntry.index;
404
455
  void attachEntryToIndexes(crListReplica, linkedListEntry, delta);
405
- _optionalChain([crListReplica, 'access', _34 => _34.index, 'optionalAccess', _35 => _35.set, 'call', _36 => _36(linkedListEntry.index, linkedListEntry)]);
456
+ _optionalChain([crListReplica, 'access', _42 => _42.index, 'optionalAccess', _43 => _43.set, 'call', _44 => _44(linkedListEntry.index, linkedListEntry)]);
406
457
  change[linkedListEntry.index] = linkedListEntry.value;
407
458
  break;
408
459
  }
@@ -418,7 +469,7 @@ function __update(listIndex, listValues, crListReplica, mode) {
418
469
  void attachEntryToIndexes(crListReplica, linkedListEntry, delta);
419
470
  crListReplica.cursor = linkedListEntry;
420
471
  crListReplica.cursorIndex = linkedListEntry.index;
421
- void _optionalChain([crListReplica, 'access', _37 => _37.index, 'optionalAccess', _38 => _38.set, 'call', _39 => _39(linkedListEntry.index, linkedListEntry)]);
472
+ void _optionalChain([crListReplica, 'access', _45 => _45.index, 'optionalAccess', _46 => _46.set, 'call', _47 => _47(linkedListEntry.index, linkedListEntry)]);
422
473
  change[linkedListEntry.index] = linkedListEntry.value;
423
474
  break;
424
475
  }
@@ -445,13 +496,13 @@ function __update(listIndex, listValues, crListReplica, mode) {
445
496
  }
446
497
  void attachEntryToIndexes(crListReplica, linkedListEntry, delta);
447
498
  void crListReplica.tombstones.add(entryToOverwrite.uuidv7);
448
- void _optionalChain([delta, 'access', _40 => _40.tombstones, 'optionalAccess', _41 => _41.push, 'call', _42 => _42(entryToOverwrite.uuidv7)]);
499
+ void _optionalChain([delta, 'access', _48 => _48.tombstones, 'optionalAccess', _49 => _49.push, 'call', _50 => _50(entryToOverwrite.uuidv7)]);
449
500
  void detachEntryFromIndexes(crListReplica, entryToOverwrite);
450
501
  entryToOverwrite.next = void 0;
451
502
  entryToOverwrite.prev = void 0;
452
503
  crListReplica.cursor = linkedListEntry;
453
504
  crListReplica.cursorIndex = actualIndex;
454
- void _optionalChain([crListReplica, 'access', _43 => _43.index, 'optionalAccess', _44 => _44.set, 'call', _45 => _45(linkedListEntry.index, linkedListEntry)]);
505
+ void _optionalChain([crListReplica, 'access', _51 => _51.index, 'optionalAccess', _52 => _52.set, 'call', _53 => _53(linkedListEntry.index, linkedListEntry)]);
455
506
  change[actualIndex] = linkedListEntry.value;
456
507
  break;
457
508
  }
@@ -460,7 +511,7 @@ function __update(listIndex, listValues, crListReplica, mode) {
460
511
  crListReplica.cursor = linkedListEntry;
461
512
  crListReplica.cursorIndex = linkedListEntry.index;
462
513
  void attachEntryToIndexes(crListReplica, linkedListEntry, delta);
463
- void _optionalChain([crListReplica, 'access', _46 => _46.index, 'optionalAccess', _47 => _47.set, 'call', _48 => _48(linkedListEntry.index, linkedListEntry)]);
514
+ void _optionalChain([crListReplica, 'access', _54 => _54.index, 'optionalAccess', _55 => _55.set, 'call', _56 => _56(linkedListEntry.index, linkedListEntry)]);
464
515
  change[linkedListEntry.index] = linkedListEntry.value;
465
516
  break;
466
517
  }
@@ -489,7 +540,7 @@ function __update(listIndex, listValues, crListReplica, mode) {
489
540
  crListReplica.cursor = linkedListEntry;
490
541
  crListReplica.cursorIndex = linkedListEntry.index;
491
542
  if (next) crListReplica.index = /* @__PURE__ */ new Map();
492
- void _optionalChain([crListReplica, 'access', _49 => _49.index, 'optionalAccess', _50 => _50.set, 'call', _51 => _51(linkedListEntry.index, linkedListEntry)]);
543
+ void _optionalChain([crListReplica, 'access', _57 => _57.index, 'optionalAccess', _58 => _58.set, 'call', _59 => _59(linkedListEntry.index, linkedListEntry)]);
493
544
  change[linkedListEntry.index] = linkedListEntry.value;
494
545
  break;
495
546
  }
@@ -498,7 +549,7 @@ function __update(listIndex, listValues, crListReplica, mode) {
498
549
  crListReplica.cursor = linkedListEntry;
499
550
  crListReplica.cursorIndex = linkedListEntry.index;
500
551
  void attachEntryToIndexes(crListReplica, linkedListEntry, delta);
501
- void _optionalChain([crListReplica, 'access', _52 => _52.index, 'optionalAccess', _53 => _53.set, 'call', _54 => _54(linkedListEntry.index, linkedListEntry)]);
552
+ void _optionalChain([crListReplica, 'access', _60 => _60.index, 'optionalAccess', _61 => _61.set, 'call', _62 => _62(linkedListEntry.index, linkedListEntry)]);
502
553
  change[linkedListEntry.index] = linkedListEntry.value;
503
554
  mode = "after";
504
555
  listIndex = linkedListEntry.index - 1;
@@ -509,7 +560,7 @@ function __update(listIndex, listValues, crListReplica, mode) {
509
560
  const actualIndex = _nullishCoalesce(crListReplica.cursorIndex, () => ( listIndex));
510
561
  const prev = crListReplica.cursor.prev;
511
562
  linkedListEntry.index = actualIndex;
512
- linkedListEntry.predecessor = _nullishCoalesce(_optionalChain([prev, 'optionalAccess', _55 => _55.uuidv7]), () => ( "\0"));
563
+ linkedListEntry.predecessor = _nullishCoalesce(_optionalChain([prev, 'optionalAccess', _63 => _63.uuidv7]), () => ( "\0"));
513
564
  void linkEntryBetween(prev, linkedListEntry, crListReplica.cursor);
514
565
  if (crListReplica.cursor.predecessor === linkedListEntry.predecessor) {
515
566
  void moveEntryToPredecessor(
@@ -523,7 +574,7 @@ function __update(listIndex, listValues, crListReplica, mode) {
523
574
  crListReplica.cursor = linkedListEntry;
524
575
  crListReplica.cursorIndex = actualIndex;
525
576
  crListReplica.index = /* @__PURE__ */ new Map();
526
- void _optionalChain([crListReplica, 'access', _56 => _56.index, 'optionalAccess', _57 => _57.set, 'call', _58 => _58(linkedListEntry.index, linkedListEntry)]);
577
+ void _optionalChain([crListReplica, 'access', _64 => _64.index, 'optionalAccess', _65 => _65.set, 'call', _66 => _66(linkedListEntry.index, linkedListEntry)]);
527
578
  change[actualIndex] = linkedListEntry.value;
528
579
  mode = "after";
529
580
  listIndex = linkedListEntry.index - 1;
@@ -550,7 +601,7 @@ function __delete(crListReplica, startIndex, endIndex) {
550
601
  void seekCursorToIndex(listIndex, crListReplica);
551
602
  if (!crListReplica.cursor) return false;
552
603
  let current = crListReplica.cursor;
553
- const predecessor = _nullishCoalesce(_optionalChain([current, 'access', _59 => _59.prev, 'optionalAccess', _60 => _60.uuidv7]), () => ( "\0"));
604
+ const predecessor = _nullishCoalesce(_optionalChain([current, 'access', _67 => _67.prev, 'optionalAccess', _68 => _68.uuidv7]), () => ( "\0"));
554
605
  const deletedIds = /* @__PURE__ */ new Set();
555
606
  let deleted = 0;
556
607
  let currentIndex = _nullishCoalesce(crListReplica.cursorIndex, () => ( listIndex));
@@ -558,7 +609,7 @@ function __delete(crListReplica, startIndex, endIndex) {
558
609
  const next = current.next;
559
610
  change[currentIndex] = void 0;
560
611
  void deletedIds.add(current.uuidv7);
561
- void _optionalChain([crListReplica, 'access', _61 => _61.index, 'optionalAccess', _62 => _62.delete, 'call', _63 => _63(currentIndex)]);
612
+ void _optionalChain([crListReplica, 'access', _69 => _69.index, 'optionalAccess', _70 => _70.delete, 'call', _71 => _71(currentIndex)]);
562
613
  void deleteLiveEntry(crListReplica, current, delta);
563
614
  current = next;
564
615
  currentIndex++;
@@ -578,7 +629,7 @@ function __delete(crListReplica, startIndex, endIndex) {
578
629
  void deleteLiveEntry(crListReplica, current, delta);
579
630
  void linkEntryBetween(prev, replacement, next);
580
631
  void attachEntryToIndexes(crListReplica, replacement, delta);
581
- if (_optionalChain([next, 'optionalAccess', _64 => _64.predecessor]) === current.uuidv7)
632
+ if (_optionalChain([next, 'optionalAccess', _72 => _72.predecessor]) === current.uuidv7)
582
633
  void moveEntryToPredecessor(
583
634
  crListReplica,
584
635
  next,
@@ -624,7 +675,7 @@ function __merge(crListReplica, crListDelta) {
624
675
  crListReplica.cursorIndex = linkedListEntry.index;
625
676
  void attachEntryToIndexes(crListReplica, linkedListEntry);
626
677
  crListReplica.size = crListReplica.parentMap.size;
627
- void _optionalChain([crListReplica, 'access', _65 => _65.index, 'optionalAccess', _66 => _66.set, 'call', _67 => _67(linkedListEntry.index, linkedListEntry)]);
678
+ void _optionalChain([crListReplica, 'access', _73 => _73.index, 'optionalAccess', _74 => _74.set, 'call', _75 => _75(linkedListEntry.index, linkedListEntry)]);
628
679
  return { [linkedListEntry.index]: linkedListEntry.value };
629
680
  }
630
681
  }
@@ -638,19 +689,19 @@ function __merge(crListReplica, crListDelta) {
638
689
  const wasTail = linkedListEntry.next === void 0;
639
690
  const wasCursor = crListReplica.cursor === linkedListEntry;
640
691
  void newTombsIndices.push(linkedListEntry.index);
641
- void _optionalChain([crListReplica, 'access', _68 => _68.index, 'optionalAccess', _69 => _69.delete, 'call', _70 => _70(linkedListEntry.index)]);
692
+ void _optionalChain([crListReplica, 'access', _76 => _76.index, 'optionalAccess', _77 => _77.delete, 'call', _78 => _78(linkedListEntry.index)]);
642
693
  void deleteLiveEntry(crListReplica, linkedListEntry);
643
694
  tailTombstoneMovedCursor = wasTail && wasCursor;
644
695
  needsRelink = true;
645
696
  }
646
697
  }
647
698
  }
648
- if (!Object.hasOwn(crListDelta, "values") || !Array.isArray(crListDelta.values)) {
699
+ if (!Object.hasOwn(crListDelta, "values") || !Array.isArray(crListDelta.values) || crListDelta.values.length === 0 && tailTombstoneMovedCursor) {
649
700
  if (newTombsIndices.length === 0) return false;
650
701
  if (newTombsIndices.length === 1 && tailTombstoneMovedCursor) {
651
702
  if (crListReplica.cursor) {
652
703
  crListReplica.cursorIndex = crListReplica.size - 1;
653
- void _optionalChain([crListReplica, 'access', _71 => _71.index, 'optionalAccess', _72 => _72.set, 'call', _73 => _73(
704
+ void _optionalChain([crListReplica, 'access', _79 => _79.index, 'optionalAccess', _80 => _80.set, 'call', _81 => _81(
654
705
  crListReplica.cursorIndex,
655
706
  crListReplica.cursor
656
707
  )]);
@@ -697,7 +748,7 @@ function __merge(crListReplica, crListDelta) {
697
748
  crListReplica.cursor = linkedListEntry;
698
749
  crListReplica.cursorIndex = linkedListEntry.index;
699
750
  crListReplica.size = crListReplica.parentMap.size;
700
- void _optionalChain([crListReplica, 'access', _74 => _74.index, 'optionalAccess', _75 => _75.set, 'call', _76 => _76(linkedListEntry.index, linkedListEntry)]);
751
+ void _optionalChain([crListReplica, 'access', _82 => _82.index, 'optionalAccess', _83 => _83.set, 'call', _84 => _84(linkedListEntry.index, linkedListEntry)]);
701
752
  } else {
702
753
  needsRelink = true;
703
754
  }
@@ -708,13 +759,18 @@ function __merge(crListReplica, crListDelta) {
708
759
  crListReplica.cursor = linkedListEntry;
709
760
  crListReplica.cursorIndex = linkedListEntry.index;
710
761
  crListReplica.size = crListReplica.parentMap.size;
711
- void _optionalChain([crListReplica, 'access', _77 => _77.index, 'optionalAccess', _78 => _78.set, 'call', _79 => _79(linkedListEntry.index, linkedListEntry)]);
762
+ void _optionalChain([crListReplica, 'access', _85 => _85.index, 'optionalAccess', _86 => _86.set, 'call', _87 => _87(linkedListEntry.index, linkedListEntry)]);
712
763
  } else {
713
764
  needsRelink = true;
714
765
  }
715
766
  }
716
767
  if (needsRelink) {
717
- if (!trySpliceInsertedParent(crListReplica, newVals, reparentedVals) && !trySpliceReplacement(
768
+ if (!trySpliceSiblingInsert(
769
+ crListReplica,
770
+ newVals,
771
+ reparentedVals,
772
+ newTombsIndices.length
773
+ ) && !trySpliceInsertedParent(crListReplica, newVals, reparentedVals) && !trySpliceReplacement(
718
774
  crListReplica,
719
775
  newVals,
720
776
  reparentedVals,
@@ -903,12 +959,13 @@ var CRList = class {
903
959
  if (change) void dispatchCRListEvent(this.eventTarget, "change", change);
904
960
  }
905
961
  /**
906
- * Removes the entry at an index.
962
+ * Removes one or more entries starting at an index.
907
963
  *
908
- * @param index - The index to remove.
964
+ * @param index - The first index to remove.
965
+ * @param count - Number of entries to remove. Defaults to `1`.
909
966
  */
910
- remove(index) {
911
- const result = __delete(this.state, index, index + 1);
967
+ remove(index, count = 1) {
968
+ const result = __delete(this.state, index, index + count);
912
969
  if (!result) return;
913
970
  const { delta, change } = result;
914
971
  if (delta) void dispatchCRListEvent(this.eventTarget, "delta", delta);
@@ -924,8 +981,8 @@ var CRList = class {
924
981
  * @param thisArg - Optional `this` value for the predicate.
925
982
  */
926
983
  find(predicate, thisArg) {
927
- let linkedListEntry = _nullishCoalesce(_optionalChain([this, 'access', _80 => _80.state, 'access', _81 => _81.index, 'optionalAccess', _82 => _82.get, 'call', _83 => _83(0)]), () => ( this.state.cursor));
928
- while (_optionalChain([linkedListEntry, 'optionalAccess', _84 => _84.prev])) linkedListEntry = linkedListEntry.prev;
984
+ let linkedListEntry = _nullishCoalesce(_optionalChain([this, 'access', _88 => _88.state, 'access', _89 => _89.index, 'optionalAccess', _90 => _90.get, 'call', _91 => _91(0)]), () => ( this.state.cursor));
985
+ while (_optionalChain([linkedListEntry, 'optionalAccess', _92 => _92.prev])) linkedListEntry = linkedListEntry.prev;
929
986
  let index = 0;
930
987
  while (linkedListEntry) {
931
988
  if (predicate.call(thisArg, linkedListEntry.value, index, this))
@@ -1035,8 +1092,8 @@ var CRList = class {
1035
1092
  * Iterates over current live values in index order.
1036
1093
  */
1037
1094
  *[Symbol.iterator]() {
1038
- let linkedListEntry = _nullishCoalesce(_optionalChain([this, 'access', _85 => _85.state, 'access', _86 => _86.index, 'optionalAccess', _87 => _87.get, 'call', _88 => _88(0)]), () => ( this.state.cursor));
1039
- while (_optionalChain([linkedListEntry, 'optionalAccess', _89 => _89.prev])) linkedListEntry = linkedListEntry.prev;
1095
+ let linkedListEntry = _nullishCoalesce(_optionalChain([this, 'access', _93 => _93.state, 'access', _94 => _94.index, 'optionalAccess', _95 => _95.get, 'call', _96 => _96(0)]), () => ( this.state.cursor));
1096
+ while (_optionalChain([linkedListEntry, 'optionalAccess', _97 => _97.prev])) linkedListEntry = linkedListEntry.prev;
1040
1097
  while (linkedListEntry) {
1041
1098
  yield linkedListEntry.value;
1042
1099
  linkedListEntry = linkedListEntry.next;
@@ -1052,8 +1109,8 @@ var CRList = class {
1052
1109
  * @param thisArg - Optional `this` value for the callback.
1053
1110
  */
1054
1111
  forEach(callback, thisArg) {
1055
- let linkedListEntry = _nullishCoalesce(_optionalChain([this, 'access', _90 => _90.state, 'access', _91 => _91.index, 'optionalAccess', _92 => _92.get, 'call', _93 => _93(0)]), () => ( this.state.cursor));
1056
- while (_optionalChain([linkedListEntry, 'optionalAccess', _94 => _94.prev])) linkedListEntry = linkedListEntry.prev;
1112
+ let linkedListEntry = _nullishCoalesce(_optionalChain([this, 'access', _98 => _98.state, 'access', _99 => _99.index, 'optionalAccess', _100 => _100.get, 'call', _101 => _101(0)]), () => ( this.state.cursor));
1113
+ while (_optionalChain([linkedListEntry, 'optionalAccess', _102 => _102.prev])) linkedListEntry = linkedListEntry.prev;
1057
1114
  let index = 0;
1058
1115
  while (linkedListEntry) {
1059
1116
  void callback.call(thisArg, linkedListEntry.value, index, this);