@sovereignbase/convergent-replicated-list 1.2.0 → 1.3.2

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/README.md CHANGED
@@ -12,9 +12,9 @@ Convergent Replicated List (CR-List), a delta CRDT for an ordered sequence of en
12
12
 
13
13
  ## Compatibility
14
14
 
15
- - Runtimes: Node >= 20, modern browsers, Bun, Deno, Cloudflare Workers, Edge Runtime.
15
+ - Runtimes: Node >= 22, modern browsers, Bun, Deno, Cloudflare Workers, Edge Runtime.
16
16
  - Module format: ESM + CommonJS.
17
- - Required globals / APIs: `EventTarget`, `CustomEvent`, `structuredClone`.
17
+ - Required globals / APIs: `EventTarget`, `CustomEvent`.
18
18
  - TypeScript: bundled types.
19
19
 
20
20
  ## Goals
@@ -313,58 +313,39 @@ npm run bench
313
313
 
314
314
  Last measured on Node `v22.14.0` (`win32 x64`):
315
315
 
316
- | group | scenario | n | ops | crlist ms | crlist ms/op | crlist ops/sec | yjs ms/op | yjs ops/sec | json-joy ms/op | json-joy ops/sec | automerge ms/op | automerge ops/sec | winner |
317
- |---|---|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|---|
318
- | crud | create / hydrate snapshot | 5,000 | 250 | 2,096.39 | 8.39 | 119.25 | 15.07 | 66.34 | 19.3 | 51.82 | 232.99 | 4.29 | crlist |
319
- | crud | read / random indexed reads | 5,000 | 250 | 0.35 | 0 | 712,047.85 | 0 | 213,949.51 | 0.01 | 72,573.15 | 0 | 1,487,209.99 | automerge |
320
- | crud | update / append after tail | 5,000 | 250 | 3.75 | 0.01 | 66,712.92 | 0.04 | 26,447.75 | 0.03 | 34,200.66 | 2.79 | 358 | crlist |
321
- | crud | update / insert before middle | 5,000 | 250 | 3.97 | 0.02 | 62,962.78 | 0.02 | 47,542.98 | 0.02 | 59,963.54 | 2.77 | 360.61 | crlist |
322
- | crud | update / insert at head | 5,000 | 250 | 1.53 | 0.01 | 163,302.63 | 0.01 | 77,939.89 | 0.02 | 51,651.83 | 2.58 | 387.17 | crlist |
323
- | crud | update / overwrite random | 5,000 | 250 | 3.77 | 0.02 | 66,267.3 | 0.07 | 14,168.64 | 0.05 | 19,413.25 | 2.91 | 343.26 | crlist |
324
- | crud | delete / single deletes from middle | 5,000 | 250 | 1.94 | 0.01 | 129,098.89 | 0.03 | 31,265.24 | 0.13 | 7,665.23 | 0.42 | 2,369.86 | crlist |
325
- | crud | delete / range deletes | 5,000 | 250 | 5.19 | 0.02 | 48,199.28 | 0.04 | 24,172.81 | 0.25 | 3,945.2 | 0.77 | 1,295.13 | crlist |
326
- | mags | snapshot | 5,000 | 250 | 65.59 | 0.26 | 3,811.53 | 8.41 | 118.88 | 14.09 | 70.97 | 19.99 | 50.02 | crlist |
327
- | mags | acknowledge | 5,000 | 250 | 76.25 | 0.31 | 3,278.61 | n/a | n/a | n/a | n/a | n/a | n/a | n/a |
328
- | mags | garbage collect | 5,000 | 250 | 164.23 | 0.66 | 1,522.22 | n/a | n/a | n/a | n/a | n/a | n/a | n/a |
329
- | mags | merge ordered deltas | 5,000 | 250 | 4.13 | 0.02 | 60,460.95 | 0.06 | 17,959 | 0.02 | 58,147.65 | 4.68 | 213.68 | crlist |
330
- | mags | merge shuffled gossip | 5,000 | 250 | 478.37 | 1.91 | 522.61 | 0.64 | 1,555.98 | 0.09 | 11,595.98 | 0.41 | 2,456.81 | json-joy |
331
- | class | constructor / hydrate snapshot | 5,000 | 250 | 1,886.2 | 7.54 | 132.54 | 12.85 | 77.8 | 18.34 | 54.51 | 211.32 | 4.73 | crlist |
332
- | class | append after tail | 5,000 | 250 | 3.09 | 0.01 | 80,992.65 | 0.02 | 52,369.18 | 0.02 | 53,936.27 | 2.09 | 479.59 | crlist |
333
- | class | prepend before middle | 5,000 | 250 | 7.79 | 0.03 | 32,077.6 | 0.01 | 81,163.56 | 0.01 | 80,744.14 | 2.68 | 372.46 | yjs |
334
- | class | remove from middle | 5,000 | 250 | 1.82 | 0.01 | 137,287.2 | 0.03 | 37,143.24 | 0.03 | 35,865.43 | 0.57 | 1,761.16 | crlist |
335
- | class | find near tail | 5,000 | 250 | 33.64 | 0.13 | 7,431.54 | 0.44 | 2,276.89 | 5.13 | 195.02 | 0.03 | 38,407.18 | automerge |
336
- | class | snapshot | 5,000 | 250 | 83.09 | 0.33 | 3,008.93 | 7.99 | 125.19 | 14.86 | 67.28 | 19.63 | 50.93 | crlist |
337
- | class | acknowledge | 5,000 | 250 | 46.72 | 0.19 | 5,351.54 | n/a | n/a | n/a | n/a | n/a | n/a | n/a |
338
- | class | garbage collect | 5,000 | 250 | 156.68 | 0.63 | 1,595.56 | n/a | n/a | n/a | n/a | n/a | n/a | n/a |
339
- | class | merge ordered deltas | 5,000 | 250 | 2.43 | 0.01 | 102,720.03 | 0.04 | 24,436.26 | 0.01 | 79,953.95 | 4.08 | 244.99 | crlist |
340
- | class | merge shuffled gossip | 5,000 | 250 | 265.96 | 1.06 | 940 | 0.72 | 1,384.5 | 0.01 | 73,120.8 | 0.38 | 2,648.01 | json-joy |
341
- |
342
-
343
- These benchmarks compare the work a JavaScript consumer asks each library to do:
344
- hydrate state, read indexed values, mutate list position, emit or apply deltas,
345
- and materialize snapshots. CRList is strongest where its live linked projection
346
- and index cache can be updated incrementally, especially local CRUD, snapshot
347
- hydration, snapshots, and ordered append deltas.
348
-
349
- The shuffled-gossip costs more than
350
- json-joy because CRList immediately maintains a JS live projection and returns
351
- index-keyed change patches from every merge.
352
-
353
- json-joy's benchmark path applies compact JSON CRDT patches directly to its
354
- model, so shuffled patch application is extremely cheap in this scenario. That
355
- does not prove a weaker convergence model by itself, but it is a different
356
- tradeoff from CRList's immediate event/change surface.
357
-
358
- Yjs integrates updates
359
- into a mature struct store with pending update/delete-set handling, which keeps
360
- out-of-order gossip relatively cheap.
361
-
362
- Automerge delegates change application and
363
- indexed reads to its WASM-backed document store and lazy proxies, explaining its
364
- very fast random reads and `find` path; its local writes are slower here because
365
- each write goes through immutable document changes and change generation.
366
-
367
- Analysis by ChatGPT-5.5.
316
+ | group | scenario | n | ops | crlist ms | crlist ms/op | crlist ops/sec | yjs ms/op | yjs ops/sec | json-joy ms/op | json-joy ops/sec | automerge ms/op | automerge ops/sec | winner |
317
+ | ------- | -------------------------------------------------- | ----: | --: | --------: | -----------: | -------------: | --------: | ----------: | -------------: | ---------------: | --------------: | ----------------: | --------- |
318
+ | crud | create / hydrate snapshot | 5,000 | 250 | 1,196.96 | 4.79 | 208.86 | 9.27 | 107.88 | 12.86 | 77.78 | 161.27 | 6.2 | crlist |
319
+ | crud | read / random indexed reads | 5,000 | 250 | 0.69 | 0 | 359,919.38 | 0 | 250,375.56 | 0.01 | 109,938.43 | 0 | 1,445,922.5 | automerge |
320
+ | crud | update / append after tail | 5,000 | 250 | 1.8 | 0.01 | 138,557.89 | 0.02 | 40,340.8 | 0.02 | 44,789.22 | 2 | 498.99 | crlist |
321
+ | crud | update / insert before middle | 5,000 | 250 | 3.07 | 0.01 | 81,425.27 | 0.02 | 55,321.97 | 0.01 | 79,961.62 | 1.92 | 521.5 | crlist |
322
+ | crud | update / insert at head | 5,000 | 250 | 2.86 | 0.01 | 87,305.74 | 0.01 | 104,672.58 | 0.02 | 41,149.55 | 1.98 | 504.33 | yjs |
323
+ | crud | update / overwrite random | 5,000 | 250 | 5.63 | 0.02 | 44,397.09 | 0.05 | 20,391.02 | 0.03 | 34,526.57 | 2.23 | 448.79 | crlist |
324
+ | crud | delete / single deletes from middle | 5,000 | 250 | 1.77 | 0.01 | 140,924.46 | 0.02 | 56,326.6 | 0.02 | 41,923.1 | 0.33 | 3,034.57 | crlist |
325
+ | crud | delete / range deletes | 5,000 | 250 | 6.06 | 0.02 | 41,262.98 | 0.02 | 40,741.83 | 0.07 | 13,344.01 | 0.42 | 2,365.95 | crlist |
326
+ | mags | snapshot | 5,000 | 250 | 61.55 | 0.25 | 4,061.61 | 5.16 | 193.92 | 10.3 | 97.13 | 15.68 | 63.78 | crlist |
327
+ | mags | acknowledge | 5,000 | 250 | 44.79 | 0.18 | 5,582.1 | n/a | n/a | n/a | n/a | n/a | n/a | n/a |
328
+ | mags | garbage collect | 5,000 | 250 | 147.13 | 0.59 | 1,699.21 | n/a | n/a | n/a | n/a | n/a | n/a | n/a |
329
+ | mags | merge ordered deltas | 5,000 | 250 | 1.69 | 0.01 | 147,658.14 | 0.04 | 27,173.62 | 0.01 | 82,464.71 | 3.68 | 271.46 | crlist |
330
+ | mags | merge shuffled gossip | 5,000 | 250 | n/a | n/a | n/a | 0.59 | 1,685.81 | n/a | n/a | 0.33 | 3,043.22 | automerge |
331
+ | class | constructor / hydrate snapshot | 5,000 | 250 | 1,518.88 | 6.08 | 164.6 | 9.63 | 103.8 | 11.07 | 90.32 | 205 | 4.88 | crlist |
332
+ | class | append after tail | 5,000 | 250 | 2.99 | 0.01 | 83,701.62 | 0.01 | 69,074.13 | 0.01 | 162,834.63 | 2.38 | 419.43 | json-joy |
333
+ | class | prepend before middle | 5,000 | 250 | 2.86 | 0.01 | 87,284.41 | 0.01 | 129,125.56 | 0.01 | 128,218.28 | 2.08 | 481.22 | yjs |
334
+ | class | remove from middle | 5,000 | 250 | 1.99 | 0.01 | 125,514.61 | 0.01 | 76,115.09 | 0.01 | 99,407.53 | 0.37 | 2,673.64 | crlist |
335
+ | class | find near tail | 5,000 | 250 | 119.12 | 0.48 | 2,098.66 | 0.21 | 4,715.35 | 1.71 | 585.14 | 0.02 | 40,475.34 | automerge |
336
+ | class | snapshot | 5,000 | 250 | 62.59 | 0.25 | 3,994.02 | 4.88 | 205.07 | 8.26 | 121.09 | 19.84 | 50.4 | crlist |
337
+ | class | acknowledge | 5,000 | 250 | 38.72 | 0.15 | 6,456.58 | n/a | n/a | n/a | n/a | n/a | n/a | n/a |
338
+ | class | garbage collect | 5,000 | 250 | 108.65 | 0.43 | 2,301.01 | n/a | n/a | n/a | n/a | n/a | n/a | n/a |
339
+ | class | merge ordered deltas | 5,000 | 250 | 1.29 | 0.01 | 193,963.85 | 0.03 | 34,196.92 | 0 | 258,371.23 | 4.92 | 203.07 | json-joy |
340
+ | class | merge shuffled gossip | 5,000 | 250 | n/a | n/a | n/a | 0.45 | 2,221.81 | n/a | n/a | 0.71 | 1,400.93 | yjs |
341
+ | latency | append write to remote visible | 5,000 | 250 | 3.61 | 0.01 | 69,202.24 | 0.07 | 14,698.45 | 0.02 | 54,034.19 | 8.78 | 113.89 | crlist |
342
+ | latency | middle insert write to remote visible | 5,000 | 250 | 8.29 | 0.03 | 30,168.46 | 0.05 | 19,072.32 | 0.02 | 61,106.77 | 8.26 | 121.13 | json-joy |
343
+ | latency | head insert write to remote visible | 5,000 | 250 | 22.31 | 0.09 | 11,207.6 | 0.05 | 19,615.07 | 0.02 | 43,743 | 8.65 | 115.6 | json-joy |
344
+ | latency | head delete to remote hidden | 5,000 | 250 | 294.31 | 1.18 | 849.46 | 0.05 | 20,731.06 | 0.06 | 16,273.29 | 3.73 | 267.95 | yjs |
345
+ | latency | middle delete to remote hidden | 5,000 | 250 | 258.47 | 1.03 | 967.23 | 0.05 | 21,973.39 | 0.06 | 18,026.59 | 3.06 | 326.98 | yjs |
346
+ | latency | tail delete to remote hidden | 5,000 | 250 | 260.32 | 1.04 | 960.35 | 0.07 | 14,636.4 | 0.04 | 25,885.28 | 2.83 | 353.71 | json-joy |
347
+ | latency | out-of-order write delivery to remote visible | 5,000 | 250 | 36.86 | 0.15 | 6,781.7 | 207.42 | 4.82 | n/a | n/a | 224.72 | 4.45 | crlist |
348
+ | latency | out-of-order delete delivery to remote convergence | 5,000 | 250 | 327.06 | 1.31 | 764.38 | 0.03 | 30,974.71 | 0.12 | 8,192.85 | 1.03 | 968.05 | yjs |
368
349
 
369
350
  ## License
370
351
 
package/dist/index.cjs CHANGED
@@ -108,19 +108,37 @@ function rebuildLiveProjection(crListReplica) {
108
108
  let first = void 0;
109
109
  let index = 0;
110
110
  const appendChildren = (predecessorIdentifier) => {
111
- const siblings = crListReplica.childrenMap.get(predecessorIdentifier);
112
- if (!siblings) return;
113
- if (siblings.length > 1)
114
- void siblings.sort((a, b) => a.uuidv7 > b.uuidv7 ? 1 : -1);
115
- for (const sibling of siblings) {
116
- if (!sibling || crListReplica.parentMap.get(sibling.uuidv7) !== sibling)
111
+ const stack = [{ predecessorIdentifier, siblingIndex: 0 }];
112
+ while (stack.length > 0) {
113
+ const frame = stack[stack.length - 1];
114
+ if (!frame.siblings) {
115
+ frame.siblings = crListReplica.childrenMap.get(
116
+ frame.predecessorIdentifier
117
+ );
118
+ if (!frame.siblings) {
119
+ void stack.pop();
120
+ continue;
121
+ }
122
+ if (frame.siblings.length > 1)
123
+ void frame.siblings.sort((a, b) => a.uuidv7 > b.uuidv7 ? 1 : -1);
124
+ }
125
+ if (frame.siblingIndex >= frame.siblings.length) {
126
+ void stack.pop();
117
127
  continue;
128
+ }
129
+ const sibling = frame.siblings[frame.siblingIndex];
130
+ frame.siblingIndex++;
131
+ if (!sibling) continue;
132
+ if (crListReplica.parentMap.get(sibling.uuidv7) !== sibling) continue;
118
133
  sibling.index = index;
119
134
  index++;
120
135
  void linkEntryBetween(previous, sibling, void 0);
121
136
  if (!first) first = sibling;
122
137
  previous = sibling;
123
- void appendChildren(sibling.uuidv7);
138
+ void stack.push({
139
+ predecessorIdentifier: sibling.uuidv7,
140
+ siblingIndex: 0
141
+ });
124
142
  }
125
143
  };
126
144
  void appendChildren("\0");
@@ -225,6 +243,39 @@ function indexFromPropertyKey(index) {
225
243
  return Number.isSafeInteger(listIndex) ? listIndex : void 0;
226
244
  }
227
245
 
246
+ // src/.helpers/trySpliceInsertedParent/index.ts
247
+ function trySpliceInsertedParent(crListReplica, insertedEntries, reparentedEntries) {
248
+ if (insertedEntries.length !== 1 || reparentedEntries.length !== 1)
249
+ return false;
250
+ const inserted = insertedEntries[0];
251
+ const reparented = reparentedEntries[0];
252
+ const moved = reparented.entry;
253
+ if (moved.predecessor !== inserted.uuidv7 || inserted.predecessor !== reparented.previousPredecessor)
254
+ return false;
255
+ const siblings = crListReplica.childrenMap.get(inserted.predecessor);
256
+ const children = crListReplica.childrenMap.get(inserted.uuidv7);
257
+ if (_optionalChain([siblings, 'optionalAccess', _18 => _18.length]) !== 1 || siblings[0] !== inserted || _optionalChain([children, 'optionalAccess', _19 => _19.length]) !== 1 || children[0] !== moved)
258
+ return false;
259
+ const predecessor = inserted.predecessor === "\0" ? void 0 : crListReplica.parentMap.get(inserted.predecessor);
260
+ if (inserted.predecessor !== "\0" && !predecessor) return false;
261
+ const expectedIndex = predecessor ? predecessor.index + 1 : 0;
262
+ if (moved.index !== expectedIndex || moved.prev !== predecessor || predecessor && predecessor.next !== moved)
263
+ return false;
264
+ void linkEntryBetween(predecessor, inserted, moved);
265
+ let current = inserted;
266
+ let index = expectedIndex;
267
+ while (current) {
268
+ current.index = index;
269
+ index++;
270
+ current = current.next;
271
+ }
272
+ crListReplica.index = /* @__PURE__ */ new Map([[inserted.index, inserted]]);
273
+ crListReplica.cursor = inserted;
274
+ crListReplica.cursorIndex = inserted.index;
275
+ crListReplica.size = crListReplica.parentMap.size;
276
+ return true;
277
+ }
278
+
228
279
  // src/core/crud/create/index.ts
229
280
 
230
281
  function __create(snapshot) {
@@ -256,11 +307,11 @@ function __create(snapshot) {
256
307
  );
257
308
  if (!linkedListEntry) continue;
258
309
  void attachEntryToIndexes(crListReplica, linkedListEntry);
259
- if (canUseLinearProjection && linkedListEntry.predecessor === (_nullishCoalesce(_optionalChain([previous, 'optionalAccess', _18 => _18.uuidv7]), () => ( "\0")))) {
310
+ if (canUseLinearProjection && linkedListEntry.predecessor === (_nullishCoalesce(_optionalChain([previous, 'optionalAccess', _20 => _20.uuidv7]), () => ( "\0")))) {
260
311
  linkedListEntry.index = crListReplica.parentMap.size - 1;
261
312
  void linkEntryBetween(previous, linkedListEntry, void 0);
262
313
  previous = linkedListEntry;
263
- void _optionalChain([crListReplica, 'access', _19 => _19.index, 'optionalAccess', _20 => _20.set, 'call', _21 => _21(linkedListEntry.index, linkedListEntry)]);
314
+ void _optionalChain([crListReplica, 'access', _21 => _21.index, 'optionalAccess', _22 => _22.set, 'call', _23 => _23(linkedListEntry.index, linkedListEntry)]);
264
315
  continue;
265
316
  }
266
317
  canUseLinearProjection = false;
@@ -279,7 +330,7 @@ function __create(snapshot) {
279
330
  function __read(targetIndex, crListReplica) {
280
331
  try {
281
332
  void seekCursorToIndex(targetIndex, crListReplica);
282
- return _optionalChain([crListReplica, 'access', _22 => _22.cursor, 'optionalAccess', _23 => _23.value]);
333
+ return _optionalChain([crListReplica, 'access', _24 => _24.cursor, 'optionalAccess', _25 => _25.value]);
283
334
  } catch (e) {
284
335
  return void 0;
285
336
  }
@@ -315,7 +366,7 @@ function __update(listIndex, listValues, crListReplica, mode) {
315
366
  crListReplica.cursor = linkedListEntry;
316
367
  crListReplica.cursorIndex = linkedListEntry.index;
317
368
  void attachEntryToIndexes(crListReplica, linkedListEntry, delta);
318
- _optionalChain([crListReplica, 'access', _24 => _24.index, 'optionalAccess', _25 => _25.set, 'call', _26 => _26(linkedListEntry.index, linkedListEntry)]);
369
+ _optionalChain([crListReplica, 'access', _26 => _26.index, 'optionalAccess', _27 => _27.set, 'call', _28 => _28(linkedListEntry.index, linkedListEntry)]);
319
370
  change[linkedListEntry.index] = linkedListEntry.value;
320
371
  break;
321
372
  }
@@ -331,7 +382,7 @@ function __update(listIndex, listValues, crListReplica, mode) {
331
382
  void attachEntryToIndexes(crListReplica, linkedListEntry, delta);
332
383
  crListReplica.cursor = linkedListEntry;
333
384
  crListReplica.cursorIndex = linkedListEntry.index;
334
- void _optionalChain([crListReplica, 'access', _27 => _27.index, 'optionalAccess', _28 => _28.set, 'call', _29 => _29(linkedListEntry.index, linkedListEntry)]);
385
+ void _optionalChain([crListReplica, 'access', _29 => _29.index, 'optionalAccess', _30 => _30.set, 'call', _31 => _31(linkedListEntry.index, linkedListEntry)]);
335
386
  change[linkedListEntry.index] = linkedListEntry.value;
336
387
  break;
337
388
  }
@@ -358,13 +409,13 @@ function __update(listIndex, listValues, crListReplica, mode) {
358
409
  }
359
410
  void attachEntryToIndexes(crListReplica, linkedListEntry, delta);
360
411
  void crListReplica.tombstones.add(entryToOverwrite.uuidv7);
361
- void _optionalChain([delta, 'access', _30 => _30.tombstones, 'optionalAccess', _31 => _31.push, 'call', _32 => _32(entryToOverwrite.uuidv7)]);
412
+ void _optionalChain([delta, 'access', _32 => _32.tombstones, 'optionalAccess', _33 => _33.push, 'call', _34 => _34(entryToOverwrite.uuidv7)]);
362
413
  void detachEntryFromIndexes(crListReplica, entryToOverwrite);
363
414
  entryToOverwrite.next = void 0;
364
415
  entryToOverwrite.prev = void 0;
365
416
  crListReplica.cursor = linkedListEntry;
366
417
  crListReplica.cursorIndex = actualIndex;
367
- void _optionalChain([crListReplica, 'access', _33 => _33.index, 'optionalAccess', _34 => _34.set, 'call', _35 => _35(linkedListEntry.index, linkedListEntry)]);
418
+ void _optionalChain([crListReplica, 'access', _35 => _35.index, 'optionalAccess', _36 => _36.set, 'call', _37 => _37(linkedListEntry.index, linkedListEntry)]);
368
419
  change[actualIndex] = linkedListEntry.value;
369
420
  break;
370
421
  }
@@ -373,7 +424,7 @@ function __update(listIndex, listValues, crListReplica, mode) {
373
424
  crListReplica.cursor = linkedListEntry;
374
425
  crListReplica.cursorIndex = linkedListEntry.index;
375
426
  void attachEntryToIndexes(crListReplica, linkedListEntry, delta);
376
- void _optionalChain([crListReplica, 'access', _36 => _36.index, 'optionalAccess', _37 => _37.set, 'call', _38 => _38(linkedListEntry.index, linkedListEntry)]);
427
+ void _optionalChain([crListReplica, 'access', _38 => _38.index, 'optionalAccess', _39 => _39.set, 'call', _40 => _40(linkedListEntry.index, linkedListEntry)]);
377
428
  change[linkedListEntry.index] = linkedListEntry.value;
378
429
  break;
379
430
  }
@@ -402,7 +453,7 @@ function __update(listIndex, listValues, crListReplica, mode) {
402
453
  crListReplica.cursor = linkedListEntry;
403
454
  crListReplica.cursorIndex = linkedListEntry.index;
404
455
  if (next) crListReplica.index = /* @__PURE__ */ new Map();
405
- void _optionalChain([crListReplica, 'access', _39 => _39.index, 'optionalAccess', _40 => _40.set, 'call', _41 => _41(linkedListEntry.index, linkedListEntry)]);
456
+ void _optionalChain([crListReplica, 'access', _41 => _41.index, 'optionalAccess', _42 => _42.set, 'call', _43 => _43(linkedListEntry.index, linkedListEntry)]);
406
457
  change[linkedListEntry.index] = linkedListEntry.value;
407
458
  break;
408
459
  }
@@ -411,7 +462,7 @@ function __update(listIndex, listValues, crListReplica, mode) {
411
462
  crListReplica.cursor = linkedListEntry;
412
463
  crListReplica.cursorIndex = linkedListEntry.index;
413
464
  void attachEntryToIndexes(crListReplica, linkedListEntry, delta);
414
- void _optionalChain([crListReplica, 'access', _42 => _42.index, 'optionalAccess', _43 => _43.set, 'call', _44 => _44(linkedListEntry.index, linkedListEntry)]);
465
+ void _optionalChain([crListReplica, 'access', _44 => _44.index, 'optionalAccess', _45 => _45.set, 'call', _46 => _46(linkedListEntry.index, linkedListEntry)]);
415
466
  change[linkedListEntry.index] = linkedListEntry.value;
416
467
  mode = "after";
417
468
  listIndex = linkedListEntry.index - 1;
@@ -422,7 +473,7 @@ function __update(listIndex, listValues, crListReplica, mode) {
422
473
  const actualIndex = _nullishCoalesce(crListReplica.cursorIndex, () => ( listIndex));
423
474
  const prev = crListReplica.cursor.prev;
424
475
  linkedListEntry.index = actualIndex;
425
- linkedListEntry.predecessor = _nullishCoalesce(_optionalChain([prev, 'optionalAccess', _45 => _45.uuidv7]), () => ( "\0"));
476
+ linkedListEntry.predecessor = _nullishCoalesce(_optionalChain([prev, 'optionalAccess', _47 => _47.uuidv7]), () => ( "\0"));
426
477
  void linkEntryBetween(prev, linkedListEntry, crListReplica.cursor);
427
478
  if (crListReplica.cursor.predecessor === linkedListEntry.predecessor) {
428
479
  void moveEntryToPredecessor(
@@ -436,7 +487,7 @@ function __update(listIndex, listValues, crListReplica, mode) {
436
487
  crListReplica.cursor = linkedListEntry;
437
488
  crListReplica.cursorIndex = actualIndex;
438
489
  crListReplica.index = /* @__PURE__ */ new Map();
439
- void _optionalChain([crListReplica, 'access', _46 => _46.index, 'optionalAccess', _47 => _47.set, 'call', _48 => _48(linkedListEntry.index, linkedListEntry)]);
490
+ void _optionalChain([crListReplica, 'access', _48 => _48.index, 'optionalAccess', _49 => _49.set, 'call', _50 => _50(linkedListEntry.index, linkedListEntry)]);
440
491
  change[actualIndex] = linkedListEntry.value;
441
492
  mode = "after";
442
493
  listIndex = linkedListEntry.index - 1;
@@ -467,7 +518,7 @@ function __delete(crListReplica, startIndex, endIndex) {
467
518
  while (current && deleted < deleteCount) {
468
519
  const next = current.next;
469
520
  change[currentIndex] = void 0;
470
- void _optionalChain([crListReplica, 'access', _49 => _49.index, 'optionalAccess', _50 => _50.delete, 'call', _51 => _51(currentIndex)]);
521
+ void _optionalChain([crListReplica, 'access', _51 => _51.index, 'optionalAccess', _52 => _52.delete, 'call', _53 => _53(currentIndex)]);
471
522
  void deleteLiveEntry(crListReplica, current, delta);
472
523
  current = next;
473
524
  currentIndex++;
@@ -491,6 +542,7 @@ function __merge(crListReplica, crListDelta) {
491
542
  if (!crListDelta || _utils.prototype.call(void 0, crListDelta) !== "record") return false;
492
543
  const newVals = [];
493
544
  const newTombsIndices = [];
545
+ const reparentedVals = [];
494
546
  const change = {};
495
547
  let needsRelink = false;
496
548
  if (Object.hasOwn(crListDelta, "values") && Array.isArray(crListDelta.values) && crListDelta.values.length === 1 && (!Object.hasOwn(crListDelta, "tombstones") || Array.isArray(crListDelta.tombstones) && crListDelta.tombstones.length === 0)) {
@@ -508,7 +560,7 @@ function __merge(crListReplica, crListDelta) {
508
560
  crListReplica.cursorIndex = linkedListEntry.index;
509
561
  void attachEntryToIndexes(crListReplica, linkedListEntry);
510
562
  crListReplica.size = crListReplica.parentMap.size;
511
- void _optionalChain([crListReplica, 'access', _52 => _52.index, 'optionalAccess', _53 => _53.set, 'call', _54 => _54(linkedListEntry.index, linkedListEntry)]);
563
+ void _optionalChain([crListReplica, 'access', _54 => _54.index, 'optionalAccess', _55 => _55.set, 'call', _56 => _56(linkedListEntry.index, linkedListEntry)]);
512
564
  return { [linkedListEntry.index]: linkedListEntry.value };
513
565
  }
514
566
  }
@@ -520,7 +572,7 @@ function __merge(crListReplica, crListDelta) {
520
572
  const linkedListEntry = crListReplica.parentMap.get(tombstone);
521
573
  if (linkedListEntry) {
522
574
  void newTombsIndices.push(linkedListEntry.index);
523
- void _optionalChain([crListReplica, 'access', _55 => _55.index, 'optionalAccess', _56 => _56.delete, 'call', _57 => _57(linkedListEntry.index)]);
575
+ void _optionalChain([crListReplica, 'access', _57 => _57.index, 'optionalAccess', _58 => _58.delete, 'call', _59 => _59(linkedListEntry.index)]);
524
576
  void deleteLiveEntry(crListReplica, linkedListEntry);
525
577
  needsRelink = true;
526
578
  }
@@ -542,11 +594,13 @@ function __merge(crListReplica, crListDelta) {
542
594
  if (valueEntry.predecessor !== "\0" && !_utils.isUuidV7.call(void 0, valueEntry.predecessor))
543
595
  continue;
544
596
  if (existingEntry.predecessor >= valueEntry.predecessor) continue;
597
+ const previousPredecessor = existingEntry.predecessor;
545
598
  void moveEntryToPredecessor(
546
599
  crListReplica,
547
600
  existingEntry,
548
601
  valueEntry.predecessor
549
602
  );
603
+ void reparentedVals.push({ entry: existingEntry, previousPredecessor });
550
604
  needsRelink = true;
551
605
  continue;
552
606
  }
@@ -563,7 +617,7 @@ function __merge(crListReplica, crListDelta) {
563
617
  crListReplica.cursor = linkedListEntry;
564
618
  crListReplica.cursorIndex = linkedListEntry.index;
565
619
  crListReplica.size = crListReplica.parentMap.size;
566
- void _optionalChain([crListReplica, 'access', _58 => _58.index, 'optionalAccess', _59 => _59.set, 'call', _60 => _60(linkedListEntry.index, linkedListEntry)]);
620
+ void _optionalChain([crListReplica, 'access', _60 => _60.index, 'optionalAccess', _61 => _61.set, 'call', _62 => _62(linkedListEntry.index, linkedListEntry)]);
567
621
  } else {
568
622
  needsRelink = true;
569
623
  }
@@ -574,13 +628,15 @@ function __merge(crListReplica, crListDelta) {
574
628
  crListReplica.cursor = linkedListEntry;
575
629
  crListReplica.cursorIndex = linkedListEntry.index;
576
630
  crListReplica.size = crListReplica.parentMap.size;
577
- void _optionalChain([crListReplica, 'access', _61 => _61.index, 'optionalAccess', _62 => _62.set, 'call', _63 => _63(linkedListEntry.index, linkedListEntry)]);
631
+ void _optionalChain([crListReplica, 'access', _63 => _63.index, 'optionalAccess', _64 => _64.set, 'call', _65 => _65(linkedListEntry.index, linkedListEntry)]);
578
632
  } else {
579
633
  needsRelink = true;
580
634
  }
581
635
  }
582
636
  if (needsRelink) {
583
- void rebuildLiveProjection(crListReplica);
637
+ if (!trySpliceInsertedParent(crListReplica, newVals, reparentedVals)) {
638
+ void rebuildLiveProjection(crListReplica);
639
+ }
584
640
  }
585
641
  if (newTombsIndices.length === 0 && newVals.length === 0) return false;
586
642
  for (const index of newTombsIndices) {
@@ -783,8 +839,8 @@ var CRList = class {
783
839
  * @param thisArg - Optional `this` value for the predicate.
784
840
  */
785
841
  find(predicate, thisArg) {
786
- let linkedListEntry = _nullishCoalesce(_optionalChain([this, 'access', _64 => _64.state, 'access', _65 => _65.index, 'optionalAccess', _66 => _66.get, 'call', _67 => _67(0)]), () => ( this.state.cursor));
787
- while (_optionalChain([linkedListEntry, 'optionalAccess', _68 => _68.prev])) linkedListEntry = linkedListEntry.prev;
842
+ let linkedListEntry = _nullishCoalesce(_optionalChain([this, 'access', _66 => _66.state, 'access', _67 => _67.index, 'optionalAccess', _68 => _68.get, 'call', _69 => _69(0)]), () => ( this.state.cursor));
843
+ while (_optionalChain([linkedListEntry, 'optionalAccess', _70 => _70.prev])) linkedListEntry = linkedListEntry.prev;
788
844
  let index = 0;
789
845
  while (linkedListEntry) {
790
846
  if (predicate.call(thisArg, linkedListEntry.value, index, this))
@@ -1 +1 @@
1
- {"version":3,"sources":["/home/runner/work/convergent-replicated-list/convergent-replicated-list/dist/index.cjs","../src/.helpers/rebuildLiveIndex/index.ts","../src/.errors/class.ts","../src/.helpers/seekCursorToIndex/index.ts","../src/.helpers/linkEntryBetween/index.ts","../src/.helpers/rebuildLiveProjection/index.ts","../src/.helpers/materializeSnapshotEntry/index.ts","../src/.helpers/attachEntryToIndexes/index.ts","../src/.helpers/detachEntryFromIndexes/index.ts","../src/.helpers/deleteLiveEntry/index.ts","../src/.helpers/dispatchCRListEvent/index.ts","../src/.helpers/moveEntryToPredecessor/index.ts","../src/.helpers/indexFromPropertyKey/index.ts","../src/core/crud/create/index.ts","../src/core/crud/read/index.ts","../src/core/crud/update/index.ts","../src/core/crud/delete/index.ts","../src/core/mags/merge/index.ts","../src/core/mags/acknowledge/index.ts","../src/core/mags/garbageCollect/index.ts","../src/core/mags/snapshot/index.ts","../src/CRList/class.ts"],"names":[],"mappings":"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","file":"/home/runner/work/convergent-replicated-list/convergent-replicated-list/dist/index.cjs","sourcesContent":[null,"import type { CRListState } from '../../.types/index.js'\n\n/**\n * Rebuilds the opportunistic index cache from the current live projection.\n */\nexport function rebuildLiveIndex<T>(crListReplica: CRListState<T>): void {\n if (!crListReplica.cursor) {\n crListReplica.index?.clear()\n crListReplica.cursorIndex = undefined\n return\n }\n let index = crListReplica.size\n const entries = crListReplica.index ?? new Map()\n void entries.clear()\n while (crListReplica.cursor.next)\n crListReplica.cursor = crListReplica.cursor.next\n\n while (index >= 1) {\n index--\n crListReplica.cursor.index = index\n void entries.set(index, crListReplica.cursor)\n if (crListReplica.cursor.prev === undefined) break\n crListReplica.cursor = crListReplica.cursor.prev\n }\n crListReplica.index = entries\n crListReplica.cursorIndex = 0\n}\n","/**\n * Error codes thrown by {@link CRList}.\n */\nexport type CRListErrorCode =\n | 'VALUE_NOT_CLONEABLE'\n | 'INDEX_OUT_OF_BOUNDS'\n | 'LIST_EMPTY'\n | 'LIST_INTEGRITY_VIOLATION'\n | 'UPDATE_EXPECTED_AN_ARRAY'\n\n/**\n * Represents a typed CRList runtime error.\n */\nexport class CRListError extends Error {\n /**\n * The semantic error code for the failure.\n */\n readonly code: CRListErrorCode\n\n /**\n * Creates a typed CRList error.\n *\n * @param code - The semantic error code.\n * @param message - An optional human-readable detail message.\n */\n constructor(code: CRListErrorCode, message?: string) {\n const detail = message ?? code\n super(`{@sovereignbase/convergent-replicated-list} ${detail}`)\n this.code = code\n this.name = 'CRListError'\n }\n}\n","import type { CRListState } from '../../.types/index.js'\nimport { CRListError } from '../../.errors/class.js'\n\n/**\n * Moves the replica cursor to a live index.\n *\n * A valid cached index entry is used directly. Stale cache entries are dropped\n * and the cursor walks from its current position, then repairs the cache at the\n * requested index.\n */\nexport function seekCursorToIndex<T>(\n targetIndex: number,\n crListReplica: CRListState<T>\n): void {\n if (targetIndex < 0 || targetIndex >= crListReplica.size)\n throw new CRListError('INDEX_OUT_OF_BOUNDS', 'Index out of bounds')\n const indexedEntry = crListReplica.index?.get(targetIndex)\n if (indexedEntry) {\n if (crListReplica.parentMap.get(indexedEntry.uuidv7) === indexedEntry) {\n crListReplica.cursor = indexedEntry\n crListReplica.cursorIndex = targetIndex\n return\n } else {\n void crListReplica.index?.delete(targetIndex)\n }\n }\n if (!crListReplica.cursor)\n throw new CRListError('LIST_EMPTY', 'List is empty')\n let cursorIndex = crListReplica.cursorIndex ?? crListReplica.cursor.index\n const direction = cursorIndex > targetIndex ? 'prev' : 'next'\n while (crListReplica.cursor && cursorIndex !== targetIndex) {\n crListReplica.cursor = crListReplica.cursor[direction]\n cursorIndex += direction === 'next' ? 1 : -1\n }\n if (crListReplica.cursor) {\n crListReplica.cursorIndex = targetIndex\n void crListReplica.index?.set(targetIndex, crListReplica.cursor)\n }\n}\n","import type { CRListStateEntry } from '../../.types/index.js'\n\n/**\n * Links a live entry between optional neighboring projection entries.\n */\nexport function linkEntryBetween<T>(\n prev: CRListStateEntry<T>,\n linkedListEntry: NonNullable<CRListStateEntry<T>>,\n next: CRListStateEntry<T>\n): void {\n linkedListEntry.prev = prev\n linkedListEntry.next = next\n if (prev) prev.next = linkedListEntry\n if (next) next.prev = linkedListEntry\n}\n","import type { CRListState, CRListStateEntry } from '../../.types/index.js'\nimport { linkEntryBetween } from '../linkEntryBetween/index.js'\n\n/**\n * Rebuilds the live linked-list projection and index from predecessor buckets.\n *\n * Sibling order is deterministic by UUIDv7, which keeps replicas convergent even\n * when deltas arrive in different orders.\n */\nexport function rebuildLiveProjection<T>(crListReplica: CRListState<T>) {\n crListReplica.cursor = undefined\n const entries = crListReplica.index ?? new Map()\n void entries.clear()\n for (const entry of crListReplica.parentMap.values()) {\n if (!entry) continue\n entry.prev = undefined\n entry.next = undefined\n }\n let previous: CRListStateEntry<T> = undefined\n let first: CRListStateEntry<T> = undefined\n let index = 0\n const appendChildren = (predecessorIdentifier: string): void => {\n const siblings = crListReplica.childrenMap.get(predecessorIdentifier)\n if (!siblings) return\n if (siblings.length > 1)\n void siblings.sort((a, b) => (a.uuidv7 > b.uuidv7 ? 1 : -1))\n\n for (const sibling of siblings) {\n if (!sibling || crListReplica.parentMap.get(sibling.uuidv7) !== sibling)\n continue\n sibling.index = index\n index++\n void linkEntryBetween<T>(previous, sibling, undefined)\n if (!first) first = sibling\n previous = sibling\n void appendChildren(sibling.uuidv7)\n }\n }\n void appendChildren('\\0')\n const detachedPredecessors: Array<string> = []\n for (const predecessorIdentifier of crListReplica.childrenMap.keys()) {\n if (\n predecessorIdentifier !== '\\0' &&\n !crListReplica.parentMap.get(predecessorIdentifier)\n )\n void detachedPredecessors.push(predecessorIdentifier)\n }\n if (detachedPredecessors.length > 1)\n detachedPredecessors.sort((a, b) => (a > b ? 1 : -1))\n for (const predecessorIdentifier of detachedPredecessors)\n void appendChildren(predecessorIdentifier)\n crListReplica.cursor = first\n crListReplica.cursorIndex = first ? 0 : undefined\n if (first) void entries.set(0, first)\n crListReplica.index = entries\n crListReplica.size = crListReplica.parentMap.size\n}\n","import type {\n CRListState,\n CRListSnapshotEntry,\n CRListStateEntry,\n} from '../../.types/index.js'\nimport { isUuidV7 } from '@sovereignbase/utils'\n\n/**\n * Converts a snapshot or delta value entry into local mutable entry state.\n *\n * Invalid, deleted, duplicate, or currently unanchored entries are ignored.\n * Payload values are kept by reference.\n */\nexport function materializeSnapshotEntry<T>(\n valueEntry: CRListSnapshotEntry<T>,\n crListReplica: CRListState<T>\n): CRListStateEntry<T> {\n if (valueEntry === null || valueEntry === undefined) return undefined\n if (\n !isUuidV7(valueEntry.uuidv7) ||\n crListReplica.tombstones.has(valueEntry.uuidv7) ||\n crListReplica.parentMap.has(valueEntry.uuidv7) ||\n (!isUuidV7(valueEntry.predecessor) &&\n valueEntry.predecessor !== '\\0' &&\n !crListReplica.tombstones.has(valueEntry.predecessor))\n )\n return undefined\n\n return {\n uuidv7: valueEntry.uuidv7,\n value: valueEntry.value,\n predecessor: valueEntry.predecessor,\n index: 0,\n next: undefined,\n prev: undefined,\n }\n}\n","import type {\n CRListState,\n CRListStateEntry,\n CRListDelta,\n} from '../../.types/index.js'\n\n/**\n * Attaches a live entry to UUID and predecessor indexes.\n *\n * When a delta buffer is provided, the same live payload reference is appended\n * to the outgoing delta.\n */\nexport function attachEntryToIndexes<T>(\n crListReplica: CRListState<T>,\n linkedListEntry: NonNullable<CRListStateEntry<T>>,\n deltaBuf?: CRListDelta<T>\n): void {\n void crListReplica.parentMap.set(linkedListEntry.uuidv7, linkedListEntry)\n const siblings = crListReplica.childrenMap.get(linkedListEntry.predecessor)\n if (siblings) {\n void siblings.push(linkedListEntry)\n } else {\n void crListReplica.childrenMap.set(linkedListEntry.predecessor, [\n linkedListEntry,\n ])\n }\n if (deltaBuf && !Array.isArray(deltaBuf.values)) deltaBuf.values = []\n if (deltaBuf?.values)\n void deltaBuf.values.push({\n uuidv7: linkedListEntry.uuidv7,\n value: linkedListEntry.value,\n predecessor: linkedListEntry.predecessor,\n })\n}\n","import type { CRListState, CRListStateEntry } from '../../.types/index.js'\n\n/**\n * Removes a live entry from UUID and predecessor indexes.\n */\nexport function detachEntryFromIndexes<T>(\n crListReplica: CRListState<T>,\n linkedListEntry: NonNullable<CRListStateEntry<T>>\n): void {\n void crListReplica.parentMap.delete(linkedListEntry.uuidv7)\n const siblings = crListReplica.childrenMap.get(linkedListEntry.predecessor)\n if (!siblings) return\n const index = siblings.indexOf(linkedListEntry)\n if (index !== -1) void siblings.splice(index, 1)\n}\n","import type {\n CRListDelta,\n CRListState,\n CRListStateEntry,\n} from '../../.types/index.js'\nimport { detachEntryFromIndexes } from '../detachEntryFromIndexes/index.js'\n\n/**\n * Tombstones a live entry and unlinks it from the local projection.\n */\nexport function deleteLiveEntry<T>(\n crListReplica: CRListState<T>,\n linkedListEntry: NonNullable<CRListStateEntry<T>>,\n deltaBuf?: CRListDelta<T>\n): void {\n const prev = linkedListEntry.prev\n const next = linkedListEntry.next\n void crListReplica.tombstones.add(linkedListEntry.uuidv7)\n if (deltaBuf && !Array.isArray(deltaBuf.tombstones)) deltaBuf.tombstones = []\n void deltaBuf?.tombstones?.push(linkedListEntry.uuidv7)\n if (prev) prev.next = next\n if (next) {\n next.prev = prev\n }\n void detachEntryFromIndexes<T>(crListReplica, linkedListEntry)\n if (crListReplica.cursor === linkedListEntry)\n crListReplica.cursor = next ?? prev\n if (!crListReplica.cursor) crListReplica.cursorIndex = undefined\n linkedListEntry.prev = undefined\n linkedListEntry.next = undefined\n crListReplica.size = crListReplica.parentMap.size\n}\n","import type { CRListEventMap } from '../../.types/index.js'\n\n/**\n * Dispatches a typed CRList event payload through an EventTarget.\n */\nexport function dispatchCRListEvent<T, K extends keyof CRListEventMap<T>>(\n eventTarget: EventTarget,\n type: K,\n detail: CRListEventMap<T>[K]\n): void {\n void eventTarget.dispatchEvent(new CustomEvent(type, { detail }))\n}\n","import type {\n CRListDelta,\n CRListState,\n CRListStateEntry,\n} from '../../.types/index.js'\nimport { detachEntryFromIndexes } from '../detachEntryFromIndexes/index.js'\nimport { attachEntryToIndexes } from '../attachEntryToIndexes/index.js'\n\n/**\n * Reattaches an existing live entry to a newer stable predecessor.\n */\nexport function moveEntryToPredecessor<T>(\n crListReplica: CRListState<T>,\n linkedListEntry: NonNullable<CRListStateEntry<T>>,\n predecessor: string,\n deltaBuf?: CRListDelta<T>\n): void {\n void detachEntryFromIndexes<T>(crListReplica, linkedListEntry)\n linkedListEntry.predecessor = predecessor\n void attachEntryToIndexes<T>(crListReplica, linkedListEntry, deltaBuf)\n}\n","/**\n * Parses a JavaScript property key as a safe non-negative list index.\n */\nexport function indexFromPropertyKey(\n index: string | symbol\n): number | undefined {\n if (typeof index !== 'string' || !/^(0|[1-9]\\d*)$/.test(index))\n return undefined\n const listIndex = Number(index)\n return Number.isSafeInteger(listIndex) ? listIndex : undefined\n}\n","import { isUuidV7, prototype } from '@sovereignbase/utils'\nimport {\n CRListSnapshot,\n CRListState,\n CRListStateEntry,\n} from '../../../.types/index.js'\nimport {\n rebuildLiveProjection,\n materializeSnapshotEntry,\n attachEntryToIndexes,\n linkEntryBetween,\n} from '../../../.helpers/index.js'\n\n/**\n * Creates a local CRList replica from an optional snapshot.\n *\n * Invalid snapshot records are ignored. Accepted values are kept by reference,\n * indexed by UUIDv7, linked through their predecessor buckets, and exposed as a\n * live doubly-linked list projection.\n *\n * @param snapshot - Optional CRList snapshot.\n * @returns - A hydrated CRList replica.\n *\n * Time complexity: O(n log n + t), worst case O(n^2 + t)\n * - n = snapshot value entry count\n * - t = snapshot tombstone count\n *\n * Space complexity: O(n + t)\n */\nexport function __create<T>(snapshot?: CRListSnapshot<T>): CRListState<T> {\n const crListReplica: CRListState<T> = {\n size: 0,\n cursor: undefined,\n cursorIndex: undefined,\n index: new Map(),\n tombstones: new Set<string>(),\n parentMap: new Map<string, NonNullable<CRListStateEntry<T>>>(),\n childrenMap: new Map<string, Array<NonNullable<CRListStateEntry<T>>>>(),\n }\n if (!snapshot || prototype(snapshot) !== 'record') return crListReplica\n\n /** Hydrate tombstone entries. */\n if (\n Object.hasOwn(snapshot, 'tombstones') &&\n Array.isArray(snapshot.tombstones)\n ) {\n for (const tombstone of snapshot.tombstones) {\n if (crListReplica.tombstones.has(tombstone) || !isUuidV7(tombstone))\n continue\n void crListReplica.tombstones.add(tombstone)\n }\n }\n\n /** Hydrate value entries. */\n if (!Object.hasOwn(snapshot, 'values') || !Array.isArray(snapshot.values))\n return crListReplica\n // Build predecessor tree.\n let canUseLinearProjection = true\n let previous: CRListStateEntry<T> = undefined\n for (const valueEntry of snapshot.values) {\n const linkedListEntry = materializeSnapshotEntry<T>(\n valueEntry,\n crListReplica\n )\n if (!linkedListEntry) continue\n void attachEntryToIndexes<T>(crListReplica, linkedListEntry)\n if (\n canUseLinearProjection &&\n linkedListEntry.predecessor === (previous?.uuidv7 ?? '\\0')\n ) {\n linkedListEntry.index = crListReplica.parentMap.size - 1\n void linkEntryBetween<T>(previous, linkedListEntry, undefined)\n previous = linkedListEntry\n void crListReplica.index?.set(linkedListEntry.index, linkedListEntry)\n continue\n }\n canUseLinearProjection = false\n }\n if (canUseLinearProjection) {\n crListReplica.cursor = previous\n crListReplica.cursorIndex = previous\n ? crListReplica.parentMap.size - 1\n : undefined\n crListReplica.size = crListReplica.parentMap.size\n return crListReplica\n }\n // Flatten tree into a doubly linked list and write live-view indexes.\n void rebuildLiveProjection<T>(crListReplica)\n\n return crListReplica\n}\n","import { seekCursorToIndex } from '../../../.helpers/index.js'\nimport { CRListState } from '../../../.types/index.js'\n\n/**\n * Reads the value at an index in the replica live view.\n *\n * The replica cursor is moved as part of the lookup. Successful reads return\n * the live value reference stored by the replica. Mutating that value directly\n * can mutate replica state and should only be done when the caller owns an\n * independent value object. Out-of-bounds and empty list reads resolve to\n * `undefined` instead of throwing.\n *\n * @param targetIndex - Index in the live list.\n * @param crListReplica - Replica to read from.\n * @returns - The live value at `targetIndex`, or `undefined` when\n * no value is present.\n *\n * Time complexity: O(d), worst case O(n)\n * - d = distance from cursor to target index\n * - n = list size\n *\n * Space complexity: O(1)\n */\nexport function __read<T>(\n targetIndex: number,\n crListReplica: CRListState<T>\n): T | undefined {\n try {\n void seekCursorToIndex<T>(targetIndex, crListReplica)\n return crListReplica.cursor?.value\n } catch {\n return undefined\n }\n}\n","import { CRListError } from '../../../.errors/class.js'\nimport {\n attachEntryToIndexes,\n detachEntryFromIndexes,\n seekCursorToIndex,\n moveEntryToPredecessor,\n linkEntryBetween,\n} from '../../../.helpers/index.js'\nimport { v7 as uuidv7 } from 'uuid'\nimport {\n CRListChange,\n CRListDelta,\n CRListState,\n CRListStateEntry,\n} from '../../../.types/index.js'\n/**\n * Applies a local value mutation to the replica live view.\n *\n * The update can replace a range starting at the target entry, insert values\n * before it, or insert values after it. The returned delta is suitable for\n * gossip and the returned change describes the local live-view patch.\n *\n * @param listIndex - Target index in the live list.\n * @param listValues - Values to insert or overwrite.\n * @param crListReplica - Replica to mutate.\n * @param mode - Mutation mode relative to `listIndex`.\n * @returns - A local change and gossip delta, or `false` if no mutation occurred.\n *\n * Time complexity: O(d + v + r + vk), worst case O(vn)\n * - d = distance from cursor to target index\n * - v = amount of input values\n * - r = amount of nodes after inserted values whose indexes must be shifted\n * - k = sibling bucket size when predecessor bucket is updated\n *\n * Space complexity: O(v)\n */\nexport function __update<T>(\n listIndex: number,\n listValues: Array<T>,\n crListReplica: CRListState<T>,\n mode: 'overwrite' | 'before' | 'after'\n): { change: CRListChange<T>; delta: CRListDelta<T> } | false {\n if (listIndex < 0 || listIndex > crListReplica.size)\n throw new CRListError('INDEX_OUT_OF_BOUNDS')\n if (!Array.isArray(listValues))\n throw new CRListError(\n 'UPDATE_EXPECTED_AN_ARRAY',\n '`listValues` must be an Array'\n )\n if (listValues.length === 0) return false\n const change: CRListChange<T> = {}\n const delta: CRListDelta<T> = { values: [], tombstones: [] }\n for (const listValue of listValues) {\n const v7 = uuidv7()\n\n const linkedListEntry: NonNullable<CRListStateEntry<T>> = {\n uuidv7: v7,\n value: listValue,\n predecessor: '\\0',\n index: 0,\n next: undefined,\n prev: undefined,\n }\n\n switch (mode) {\n case 'overwrite': {\n if (listIndex === crListReplica.size) {\n if (crListReplica.size === 0) {\n crListReplica.cursor = linkedListEntry\n crListReplica.cursorIndex = linkedListEntry.index\n void attachEntryToIndexes<T>(crListReplica, linkedListEntry, delta)\n crListReplica.index?.set(linkedListEntry.index, linkedListEntry)\n change[linkedListEntry.index] = linkedListEntry.value\n break\n }\n void seekCursorToIndex<T>(crListReplica.size - 1, crListReplica)\n if (!crListReplica.cursor) return false\n linkedListEntry.index = (crListReplica.cursorIndex ?? 0) + 1\n linkedListEntry.predecessor = crListReplica.cursor.uuidv7\n void linkEntryBetween<T>(\n crListReplica.cursor,\n linkedListEntry,\n undefined\n )\n void attachEntryToIndexes<T>(crListReplica, linkedListEntry, delta)\n crListReplica.cursor = linkedListEntry\n crListReplica.cursorIndex = linkedListEntry.index\n void crListReplica.index?.set(linkedListEntry.index, linkedListEntry)\n change[linkedListEntry.index] = linkedListEntry.value\n break\n }\n void seekCursorToIndex<T>(listIndex, crListReplica)\n if (!crListReplica.cursor) return false\n const entryToOverwrite = crListReplica.cursor\n const actualIndex = crListReplica.cursorIndex ?? listIndex\n\n linkedListEntry.predecessor = entryToOverwrite.predecessor\n linkedListEntry.index = actualIndex\n void linkEntryBetween<T>(\n entryToOverwrite.prev,\n linkedListEntry,\n entryToOverwrite.next\n )\n if (entryToOverwrite.next) {\n if (entryToOverwrite.next.predecessor === entryToOverwrite.uuidv7) {\n void moveEntryToPredecessor<T>(\n crListReplica,\n entryToOverwrite.next,\n linkedListEntry.uuidv7,\n delta\n )\n }\n }\n void attachEntryToIndexes<T>(crListReplica, linkedListEntry, delta)\n void crListReplica.tombstones.add(entryToOverwrite.uuidv7)\n void delta.tombstones?.push(entryToOverwrite.uuidv7)\n void detachEntryFromIndexes<T>(crListReplica, entryToOverwrite)\n entryToOverwrite.next = undefined\n entryToOverwrite.prev = undefined\n crListReplica.cursor = linkedListEntry\n crListReplica.cursorIndex = actualIndex\n void crListReplica.index?.set(linkedListEntry.index, linkedListEntry)\n change[actualIndex] = linkedListEntry.value\n break\n }\n case 'after': {\n if (crListReplica.size === 0 && listIndex === 0) {\n crListReplica.cursor = linkedListEntry\n crListReplica.cursorIndex = linkedListEntry.index\n void attachEntryToIndexes<T>(crListReplica, linkedListEntry, delta)\n void crListReplica.index?.set(linkedListEntry.index, linkedListEntry)\n change[linkedListEntry.index] = linkedListEntry.value\n break\n }\n if (listIndex === crListReplica.size) {\n void seekCursorToIndex<T>(crListReplica.size - 1, crListReplica)\n } else {\n void seekCursorToIndex<T>(listIndex, crListReplica)\n }\n if (!crListReplica.cursor) return false\n const actualIndex = crListReplica.cursorIndex ?? listIndex\n const next =\n listIndex === crListReplica.size\n ? undefined\n : crListReplica.cursor.next\n linkedListEntry.index = actualIndex + 1\n linkedListEntry.predecessor = crListReplica.cursor.uuidv7\n void linkEntryBetween<T>(crListReplica.cursor, linkedListEntry, next)\n if (next) {\n if (next.predecessor === crListReplica.cursor.uuidv7) {\n void moveEntryToPredecessor<T>(\n crListReplica,\n next,\n linkedListEntry.uuidv7,\n delta\n )\n }\n }\n void attachEntryToIndexes<T>(crListReplica, linkedListEntry, delta)\n crListReplica.cursor = linkedListEntry\n crListReplica.cursorIndex = linkedListEntry.index\n if (next) crListReplica.index = new Map()\n void crListReplica.index?.set(linkedListEntry.index, linkedListEntry)\n change[linkedListEntry.index] = linkedListEntry.value\n break\n }\n case 'before': {\n if (crListReplica.size === 0 && listIndex === 0) {\n crListReplica.cursor = linkedListEntry\n crListReplica.cursorIndex = linkedListEntry.index\n void attachEntryToIndexes<T>(crListReplica, linkedListEntry, delta)\n void crListReplica.index?.set(linkedListEntry.index, linkedListEntry)\n change[linkedListEntry.index] = linkedListEntry.value\n mode = 'after'\n listIndex = linkedListEntry.index - 1\n break\n }\n void seekCursorToIndex<T>(listIndex, crListReplica)\n if (!crListReplica.cursor) return false\n const actualIndex = crListReplica.cursorIndex ?? listIndex\n const prev = crListReplica.cursor.prev\n linkedListEntry.index = actualIndex\n linkedListEntry.predecessor = prev?.uuidv7 ?? '\\0'\n void linkEntryBetween<T>(prev, linkedListEntry, crListReplica.cursor)\n if (crListReplica.cursor.predecessor === linkedListEntry.predecessor) {\n void moveEntryToPredecessor<T>(\n crListReplica,\n crListReplica.cursor,\n linkedListEntry.uuidv7,\n delta\n )\n }\n void attachEntryToIndexes<T>(crListReplica, linkedListEntry, delta)\n crListReplica.cursor = linkedListEntry\n crListReplica.cursorIndex = actualIndex\n crListReplica.index = new Map()\n void crListReplica.index?.set(linkedListEntry.index, linkedListEntry)\n change[actualIndex] = linkedListEntry.value\n mode = 'after'\n listIndex = linkedListEntry.index - 1\n\n break\n }\n }\n crListReplica.size = crListReplica.parentMap.size\n listIndex++\n }\n return { change, delta }\n}\n","import { deleteLiveEntry, seekCursorToIndex } from '../../../.helpers/index.js'\nimport { CRListError } from '../../../.errors/class.js'\nimport type {\n CRListChange,\n CRListDelta,\n CRListState,\n CRListStateEntry,\n} from '../../../.types/index.js'\n\n/**\n * Deletes a range from the replica live view.\n *\n * With no indexes, the full list is deleted. With only `startIndex`, all entries\n * from `startIndex` onward are deleted. With both indexes, the deleted range is\n * `[startIndex, endIndex)`.\n *\n * @param crListReplica - Replica to mutate.\n * @param startIndex - Inclusive start index. Defaults to `0`.\n * @param endIndex - Exclusive end index. Defaults to the current list size.\n * @returns - A local change and gossip delta, or `false` if nothing was deleted.\n *\n * Time complexity: O(d + qk + r), worst case O(n^2)\n * - d = distance from cursor to target index\n * - q = amount of deleted nodes\n * - r = amount of nodes after the deleted range whose indexes must be shifted\n * - k = sibling bucket size when deleted entries are removed from buckets\n *\n * Space complexity: O(q)\n */\nexport function __delete<T>(\n crListReplica: CRListState<T>,\n startIndex?: number,\n endIndex?: number\n): { change: CRListChange<T>; delta: CRListDelta<T> } | false {\n const change: CRListChange<T> = {}\n const delta: CRListDelta<T> = { values: [], tombstones: [] }\n const listIndex = startIndex ?? 0\n const targetEndIndex = endIndex ?? crListReplica.size\n if (\n listIndex < 0 ||\n targetEndIndex < listIndex ||\n listIndex > crListReplica.size\n )\n throw new CRListError('INDEX_OUT_OF_BOUNDS')\n const deleteCount = Math.min(targetEndIndex, crListReplica.size) - listIndex\n if (deleteCount <= 0) return false\n\n void seekCursorToIndex<T>(listIndex, crListReplica)\n if (!crListReplica.cursor) return false\n\n let current: CRListStateEntry<T> = crListReplica.cursor\n let deleted = 0\n let currentIndex = crListReplica.cursorIndex ?? listIndex\n\n while (current && deleted < deleteCount) {\n const next: CRListStateEntry<T> = current.next\n change[currentIndex] = undefined\n void crListReplica.index?.delete(currentIndex)\n void deleteLiveEntry<T>(crListReplica, current, delta)\n current = next\n currentIndex++\n deleted++\n }\n\n crListReplica.size = crListReplica.parentMap.size\n crListReplica.cursor = current ?? crListReplica.cursor\n crListReplica.cursorIndex = current\n ? listIndex\n : crListReplica.cursor\n ? Math.max(0, crListReplica.size - 1)\n : undefined\n crListReplica.index = new Map()\n if (crListReplica.cursor && crListReplica.cursorIndex !== undefined)\n void crListReplica.index.set(\n crListReplica.cursorIndex,\n crListReplica.cursor\n )\n\n return { change, delta }\n}\n","import type {\n CRListChange,\n CRListDelta,\n CRListState,\n CRListStateEntry,\n} from '../../../.types/index.js'\nimport {\n materializeSnapshotEntry,\n attachEntryToIndexes,\n rebuildLiveProjection,\n rebuildLiveIndex,\n deleteLiveEntry,\n moveEntryToPredecessor,\n} from '../../../.helpers/index.js'\nimport { prototype, isUuidV7 } from '@sovereignbase/utils'\n\n/**\n * Merges a remote CRList delta into the local replica.\n *\n * Accepted tombstones update the local live view and accepted values are attached\n * to the predecessor tree. Tail-append deltas are linked incrementally; deltas\n * that can affect ordering fall back to deterministic relinking.\n *\n * @param crListReplica - Replica to mutate.\n * @param crListDelta - Remote gossip delta.\n * @returns - A minimal local change patch, or `false` when the delta is ignored.\n *\n * Time complexity: O(v + t) for tail-append deltas; O(n + t + qk) for tombstone-only deletes; otherwise O(n log n + v + t + m*k)\n * Worst case: O(n^2 + (v + t)n)\n * - n = replica value entry count after merge\n * - v = delta value entry count\n * - t = delta tombstone count\n * - q = amount of live entries deleted by tombstones\n * - m = entries moved between predecessor buckets\n * - k = sibling bucket size when entries are removed from buckets\n *\n * Space complexity: O(n + v + t)\n */\nexport function __merge<T>(\n crListReplica: CRListState<T>,\n crListDelta: CRListDelta<T>\n): CRListChange<T> | false {\n if (!crListDelta || prototype(crListDelta) !== 'record') return false\n const newVals: Array<NonNullable<CRListStateEntry<T>>> = []\n const newTombsIndices: Array<number> = []\n const change: CRListChange<T> = {}\n let needsRelink = false\n if (\n Object.hasOwn(crListDelta, 'values') &&\n Array.isArray(crListDelta.values) &&\n crListDelta.values.length === 1 &&\n (!Object.hasOwn(crListDelta, 'tombstones') ||\n (Array.isArray(crListDelta.tombstones) &&\n crListDelta.tombstones.length === 0))\n ) {\n const linkedListEntry = materializeSnapshotEntry<T>(\n crListDelta.values[0],\n crListReplica\n )\n if (!linkedListEntry) return false\n const predecessor =\n linkedListEntry.predecessor === '\\0'\n ? undefined\n : crListReplica.parentMap.get(linkedListEntry.predecessor)\n if (\n (linkedListEntry.predecessor === '\\0' && crListReplica.size === 0) ||\n (predecessor && !predecessor.next)\n ) {\n linkedListEntry.prev = predecessor\n linkedListEntry.index = crListReplica.size\n if (predecessor) predecessor.next = linkedListEntry\n crListReplica.cursor = linkedListEntry\n crListReplica.cursorIndex = linkedListEntry.index\n void attachEntryToIndexes<T>(crListReplica, linkedListEntry)\n crListReplica.size = crListReplica.parentMap.size\n void crListReplica.index?.set(linkedListEntry.index, linkedListEntry)\n return { [linkedListEntry.index]: linkedListEntry.value }\n }\n }\n\n /** Apply tombstone entries. */\n if (\n Object.hasOwn(crListDelta, 'tombstones') &&\n Array.isArray(crListDelta.tombstones)\n ) {\n for (const tombstone of crListDelta.tombstones) {\n if (crListReplica.tombstones.has(tombstone) || !isUuidV7(tombstone))\n continue\n void crListReplica.tombstones.add(tombstone)\n const linkedListEntry = crListReplica.parentMap.get(tombstone)\n if (linkedListEntry) {\n void newTombsIndices.push(linkedListEntry.index)\n void crListReplica.index?.delete(linkedListEntry.index)\n void deleteLiveEntry<T>(crListReplica, linkedListEntry)\n needsRelink = true\n }\n }\n }\n\n /** Apply value entries. */\n if (\n !Object.hasOwn(crListDelta, 'values') ||\n !Array.isArray(crListDelta.values)\n ) {\n if (newTombsIndices.length === 0) return false\n void rebuildLiveIndex<T>(crListReplica)\n for (const index of newTombsIndices) {\n change[index] = undefined\n }\n return change\n }\n // Attach accepted values to the predecessor tree.\n for (const valueEntry of crListDelta.values) {\n if (valueEntry === null || valueEntry === undefined) continue\n const existingEntry = crListReplica.parentMap.get(valueEntry.uuidv7)\n if (existingEntry) {\n if (crListReplica.tombstones.has(valueEntry.uuidv7)) continue\n if (valueEntry.predecessor !== '\\0' && !isUuidV7(valueEntry.predecessor))\n continue\n if (existingEntry.predecessor >= valueEntry.predecessor) continue\n void moveEntryToPredecessor<T>(\n crListReplica,\n existingEntry,\n valueEntry.predecessor\n )\n needsRelink = true\n continue\n }\n const linkedListEntry = materializeSnapshotEntry<T>(\n valueEntry,\n crListReplica\n )\n if (!linkedListEntry) continue\n const predecessor =\n linkedListEntry.predecessor === '\\0'\n ? undefined\n : crListReplica.parentMap.get(linkedListEntry.predecessor)\n void attachEntryToIndexes<T>(crListReplica, linkedListEntry)\n void newVals.push(linkedListEntry)\n if (!needsRelink && linkedListEntry.predecessor === '\\0') {\n if (crListReplica.size === 0) {\n crListReplica.cursor = linkedListEntry\n crListReplica.cursorIndex = linkedListEntry.index\n crListReplica.size = crListReplica.parentMap.size\n void crListReplica.index?.set(linkedListEntry.index, linkedListEntry)\n } else {\n needsRelink = true\n }\n } else if (!needsRelink && predecessor && !predecessor.next) {\n linkedListEntry.prev = predecessor\n linkedListEntry.index = crListReplica.size\n predecessor.next = linkedListEntry\n crListReplica.cursor = linkedListEntry\n crListReplica.cursorIndex = linkedListEntry.index\n crListReplica.size = crListReplica.parentMap.size\n void crListReplica.index?.set(linkedListEntry.index, linkedListEntry)\n } else {\n needsRelink = true\n }\n }\n if (needsRelink) {\n // Flatten tree into a doubly linked list and write live-view indexes.\n void rebuildLiveProjection<T>(crListReplica)\n }\n\n if (newTombsIndices.length === 0 && newVals.length === 0) return false\n\n for (const index of newTombsIndices) {\n change[index] = undefined\n }\n for (const val of newVals) {\n change[val.index] = val.value\n }\n\n return change\n}\n","import type { CRListAck, CRListState } from '../../../.types/index.js'\n\n/**\n * Returns the replica tombstone acknowledgement frontier.\n *\n * The frontier is the greatest tombstone identifier currently retained by the\n * replica. Peers can use it as input for tombstone garbage collection.\n *\n * @param crListReplica - Replica to acknowledge.\n * @returns - The acknowledgement frontier, or `false` when there are no tombstones.\n *\n * Time complexity: O(t)\n * - t = replica tombstone count\n *\n * Space complexity: O(1)\n */\nexport function __acknowledge<T>(\n crListReplica: CRListState<T>\n): CRListAck | false {\n let largest: CRListAck | false = false\n void crListReplica.tombstones.forEach((tombstone) => {\n if (largest === false || largest < tombstone) largest = tombstone\n })\n if (typeof largest === 'string') return largest\n return false\n}\n","import { isUuidV7 } from '@sovereignbase/utils'\nimport { CRListAck, CRListState } from '../../../.types/index.js'\n\n/**\n * Removes tombstones acknowledged by all supplied frontiers.\n *\n * The smallest valid UUIDv7 frontier is used as the safe collection boundary.\n * Tombstones less than or equal to that boundary are removed from the local\n * replica.\n *\n * @param frontiers - Acknowledgement frontiers received from peers.\n * @param crListReplica - Replica whose tombstones will be collected.\n *\n * Time complexity: O(f log f + t)\n * - f = frontier count\n * - t = replica tombstone count\n *\n * Space complexity: O(1)\n */\nexport function __garbageCollect<T>(\n frontiers: Array<CRListAck>,\n crListReplica: CRListState<T>\n): void {\n if (!Array.isArray(frontiers)) return\n void frontiers.sort()\n const smallest = frontiers.find((frontier) => isUuidV7(frontier))\n if (typeof smallest !== 'string') return\n void crListReplica.tombstones.forEach((tombstone, __, tombstones) => {\n if (tombstone <= smallest) {\n void tombstones.delete(tombstone)\n }\n })\n}\n","import { CRListError } from '../../../.errors/class.js'\nimport { CRListState, CRListSnapshot } from '../../../.types/index.js'\n\n/**\n * Creates a full CRList snapshot from the current replica state.\n *\n * The snapshot contains every live value entry and all retained tombstones. Value\n * payloads are live references, so callers must not mutate snapshot values\n * unless they have first isolated them from replica state.\n *\n * @param crListReplica - Replica to snapshot.\n * @returns - A full snapshot suitable for hydration or transport.\n *\n * Time complexity: O(n + t)\n * - n = replica value entry count\n * - t = replica tombstone count\n *\n * Space complexity: O(n + t)\n */\nexport function __snapshot<T>(\n crListReplica: CRListState<T>\n): CRListSnapshot<T> {\n return {\n values: Array.from(crListReplica.parentMap.values()).map(\n (linkedListEntry) => {\n if (!linkedListEntry) throw new CRListError('LIST_INTEGRITY_VIOLATION')\n return {\n uuidv7: linkedListEntry.uuidv7,\n value: linkedListEntry.value,\n predecessor: linkedListEntry.predecessor,\n }\n }\n ),\n tombstones: Array.from(crListReplica.tombstones),\n }\n}\n","import { dispatchCRListEvent, indexFromPropertyKey } from '../.helpers/index.js'\nimport { CRListError } from '../.errors/class.js'\nimport type {\n CRListState,\n CRListSnapshot,\n CRListEventListenerFor,\n CRListEventMap,\n CRListDelta,\n CRListAck,\n} from '../.types/index.js'\nimport { __create, __read, __update, __delete } from '../core/crud/index.js'\nimport {\n __merge,\n __acknowledge,\n __garbageCollect,\n __snapshot,\n} from '../core/mags/index.js'\n\n/**\n * A convergent replicated list.\n *\n * Numeric property access reads and mutates the live list projection:\n * `list[0]` reads the live value reference, `list[0] = value` writes an\n * entry, and `delete list[0]` removes one entry. Iteration, `find()`, and\n * `forEach()` expose the same live value references. Mutating returned objects\n * directly can mutate replica state without producing a CRDT delta, so callers\n * must isolate values before out-of-band mutation. Local mutations emit `delta`\n * and `change` events; remote merges emit `change` events.\n *\n * @typeParam T - The value type stored in the list.\n */\nexport class CRList<T> {\n /**\n * Reads or overwrites an entry in the live list projection by index.\n *\n * Reads return live value references.\n */\n [index: number]: T\n declare private readonly state: CRListState<T>\n declare private readonly eventTarget: EventTarget\n\n /**\n * Creates a replicated list from an optional CRList snapshot.\n *\n * @param snapshot - A previously emitted CRList snapshot.\n */\n constructor(snapshot?: CRListSnapshot<T>) {\n void Object.defineProperties(this, {\n state: {\n value: __create<T>(snapshot),\n enumerable: false,\n configurable: false,\n writable: false,\n },\n eventTarget: {\n value: new EventTarget(),\n enumerable: false,\n configurable: false,\n writable: false,\n },\n })\n\n return new Proxy(this, {\n get(target, index, receiver) {\n const listIndex = indexFromPropertyKey(index)\n // Preserve normal property access for non-index keys.\n if (listIndex === undefined) return Reflect.get(target, index, receiver)\n return __read(listIndex, target.state)\n },\n has(target, index) {\n const listIndex = indexFromPropertyKey(index)\n // Preserve normal property checks for non-index keys.\n if (listIndex === undefined) return Reflect.has(target, index)\n return listIndex >= 0 && listIndex < target.state.size\n },\n set(target, index, value) {\n const listIndex = indexFromPropertyKey(index)\n if (listIndex === undefined) return false\n try {\n const result = __update(listIndex, [value], target.state, 'overwrite')\n if (!result) return false\n const { delta, change } = result\n if (delta)\n void dispatchCRListEvent(target.eventTarget, 'delta', delta)\n if (change)\n void dispatchCRListEvent(target.eventTarget, 'change', change)\n return true\n } catch (error) {\n if (error instanceof CRListError) throw error\n return false\n }\n },\n deleteProperty(target, index) {\n const listIndex = indexFromPropertyKey(index)\n if (listIndex === undefined) return false\n try {\n const result = __delete(target.state, listIndex, listIndex + 1)\n if (!result) return false\n const { delta, change } = result\n if (delta)\n void dispatchCRListEvent(target.eventTarget, 'delta', delta)\n if (change)\n void dispatchCRListEvent(target.eventTarget, 'change', change)\n return true\n } catch (error) {\n if (error instanceof CRListError) throw error\n return false\n }\n },\n ownKeys(target) {\n return [\n ...Reflect.ownKeys(target),\n ...Array.from({ length: target.size }, (_, index) => String(index)),\n ]\n },\n\n getOwnPropertyDescriptor(target, index) {\n const listIndex = indexFromPropertyKey(index)\n\n if (listIndex !== undefined && listIndex < target.size) {\n return {\n value: __read(listIndex, target.state),\n writable: true,\n enumerable: true,\n configurable: true,\n }\n }\n // Preserve normal property checks for non-index keys.\n return Reflect.getOwnPropertyDescriptor(target, index)\n },\n })\n }\n\n /**\n * The current number of live entries.\n */\n get size(): number {\n return this.state.size\n }\n /**\n * Inserts a value before an index.\n *\n * If `beforeIndex` is omitted, the value is inserted at the start of the list.\n *\n * @param value - The value to insert.\n * @param beforeIndex - The index to insert before.\n */\n prepend(value: T, beforeIndex?: number): void {\n const result = __update<T>(beforeIndex ?? 0, [value], this.state, 'before')\n if (!result) return\n const { delta, change } = result\n if (delta) void dispatchCRListEvent(this.eventTarget, 'delta', delta)\n if (change) void dispatchCRListEvent(this.eventTarget, 'change', change)\n }\n /**\n * Inserts a value after an index.\n *\n * If `afterIndex` is omitted, the value is appended at the end of the list.\n *\n * @param value - The value to insert.\n * @param afterIndex - The index to insert after.\n */\n append(value: T, afterIndex?: number): void {\n const result = __update<T>(\n afterIndex ?? this.state.size,\n [value],\n this.state,\n 'after'\n )\n if (!result) return\n const { delta, change } = result\n if (delta) void dispatchCRListEvent(this.eventTarget, 'delta', delta)\n if (change) void dispatchCRListEvent(this.eventTarget, 'change', change)\n }\n /**\n * Removes the entry at an index.\n *\n * @param index - The index to remove.\n */\n remove(index: number): void {\n const result = __delete(this.state, index, index + 1)\n if (!result) return\n const { delta, change } = result\n if (delta) void dispatchCRListEvent(this.eventTarget, 'delta', delta)\n if (change) void dispatchCRListEvent(this.eventTarget, 'change', change)\n }\n\n /**\n * Returns the first live value matching a predicate in index order.\n *\n * Predicate values are live references. Mutating them directly can mutate the\n * list without emitting a delta.\n *\n * @param predicate - Function to test each live value.\n * @param thisArg - Optional `this` value for the predicate.\n */\n find(\n predicate: (this: unknown, value: T, index: number, list: this) => unknown,\n thisArg?: unknown\n ): T | undefined {\n let linkedListEntry = this.state.index?.get(0) ?? this.state.cursor\n while (linkedListEntry?.prev) linkedListEntry = linkedListEntry.prev\n let index = 0\n while (linkedListEntry) {\n if (predicate.call(thisArg, linkedListEntry.value, index, this))\n return linkedListEntry.value\n linkedListEntry = linkedListEntry.next\n index++\n }\n\n return undefined\n }\n\n /**\n * Applies a remote gossip delta to this list.\n *\n * Emits a `change` event when the merge changes the live projection.\n *\n * @param delta - The remote CRList delta to merge.\n */\n merge(delta: CRListDelta<T>): void {\n const change = __merge(this.state, delta)\n if (change) void dispatchCRListEvent(this.eventTarget, 'change', change)\n }\n /**\n * Emits an acknowledgement frontier for currently retained tombstones.\n */\n acknowledge(): void {\n const ack = __acknowledge(this.state)\n if (ack) void dispatchCRListEvent(this.eventTarget, 'ack', ack)\n }\n /**\n * Garbage-collects tombstones that are covered by acknowledgement frontiers.\n *\n * @param frontiers - Replica acknowledgement frontiers.\n */\n garbageCollect(frontiers: Array<CRListAck>): void {\n void __garbageCollect(frontiers, this.state)\n }\n /**\n * Emits the current CRList snapshot.\n *\n * Snapshot value payloads are live references. Mutating them can mutate\n * replica state without emitting a delta.\n */\n snapshot(): void {\n const snapshot = __snapshot<T>(this.state)\n if (snapshot)\n void dispatchCRListEvent(this.eventTarget, 'snapshot', snapshot)\n }\n /**\n * Registers an event listener.\n *\n * @param type - The event type to listen for.\n * @param listener - The listener to register.\n * @param options - Listener registration options.\n */\n addEventListener<K extends keyof CRListEventMap<T>>(\n type: K,\n listener: CRListEventListenerFor<T, K> | null,\n options?: boolean | AddEventListenerOptions\n ): void {\n void this.eventTarget.addEventListener(\n type,\n listener as EventListenerOrEventListenerObject | null,\n options\n )\n }\n\n /**\n * Removes an event listener.\n *\n * @param type - The event type to stop listening for.\n * @param listener - The listener to remove.\n * @param options - Listener removal options.\n */\n removeEventListener<K extends keyof CRListEventMap<T>>(\n type: K,\n listener: CRListEventListenerFor<T, K> | null,\n options?: boolean | EventListenerOptions\n ): void {\n void this.eventTarget.removeEventListener(\n type,\n listener as EventListenerOrEventListenerObject | null,\n options\n )\n }\n /**\n * Returns a CRList snapshot of this list.\n *\n * Snapshot value payloads are live references. Mutating them can mutate\n * replica state without emitting a delta.\n *\n * Called automatically by `JSON.stringify`.\n */\n toJSON(): CRListSnapshot<T> {\n return __snapshot<T>(this.state)\n }\n /**\n * Attempts to return this list snapshot as a JSON string.\n *\n * This can fail when list values are not JSON-compatible.\n */\n toString(): string {\n return JSON.stringify(this)\n }\n /**\n * Returns the Node.js console inspection representation.\n */\n [Symbol.for('nodejs.util.inspect.custom')](): CRListSnapshot<T> {\n return this.toJSON()\n }\n /**\n * Returns the Deno console inspection representation.\n */\n [Symbol.for('Deno.customInspect')](): CRListSnapshot<T> {\n return this.toJSON()\n }\n /**\n * Iterates over current live values in index order.\n */\n *[Symbol.iterator](): IterableIterator<T> {\n for (let index = 0; index < this.size; index++) {\n const value = this[index]\n yield value\n }\n }\n /**\n * Calls a function once for each live value in index order.\n *\n * Callback values are live references. Mutating them directly can mutate the\n * list without emitting a delta.\n *\n * @param callback - Function to call for each live value.\n * @param thisArg - Optional `this` value for the callback.\n */\n forEach(\n callback: (value: T, index: number, list: this) => void,\n thisArg?: unknown\n ): void {\n for (let index = 0; index < this.size; index++) {\n void callback.call(thisArg, this[index], index, this)\n }\n }\n}\n"]}
1
+ {"version":3,"sources":["/home/runner/work/convergent-replicated-list/convergent-replicated-list/dist/index.cjs","../src/.helpers/rebuildLiveIndex/index.ts","../src/.errors/class.ts","../src/.helpers/seekCursorToIndex/index.ts","../src/.helpers/linkEntryBetween/index.ts","../src/.helpers/rebuildLiveProjection/index.ts","../src/.helpers/materializeSnapshotEntry/index.ts","../src/.helpers/attachEntryToIndexes/index.ts","../src/.helpers/detachEntryFromIndexes/index.ts","../src/.helpers/deleteLiveEntry/index.ts","../src/.helpers/dispatchCRListEvent/index.ts","../src/.helpers/moveEntryToPredecessor/index.ts","../src/.helpers/indexFromPropertyKey/index.ts","../src/.helpers/trySpliceInsertedParent/index.ts","../src/core/crud/create/index.ts","../src/core/crud/read/index.ts","../src/core/crud/update/index.ts","../src/core/crud/delete/index.ts","../src/core/mags/merge/index.ts","../src/core/mags/acknowledge/index.ts","../src/core/mags/garbageCollect/index.ts","../src/core/mags/snapshot/index.ts","../src/CRList/class.ts"],"names":[],"mappings":"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","file":"/home/runner/work/convergent-replicated-list/convergent-replicated-list/dist/index.cjs","sourcesContent":[null,"import type { CRListState } from '../../.types/index.js'\n\n/**\n * Rebuilds the opportunistic index cache from the current live projection.\n */\nexport function rebuildLiveIndex<T>(crListReplica: CRListState<T>): void {\n if (!crListReplica.cursor) {\n crListReplica.index?.clear()\n crListReplica.cursorIndex = undefined\n return\n }\n let index = crListReplica.size\n const entries = crListReplica.index ?? new Map()\n void entries.clear()\n while (crListReplica.cursor.next)\n crListReplica.cursor = crListReplica.cursor.next\n\n while (index >= 1) {\n index--\n crListReplica.cursor.index = index\n void entries.set(index, crListReplica.cursor)\n if (crListReplica.cursor.prev === undefined) break\n crListReplica.cursor = crListReplica.cursor.prev\n }\n crListReplica.index = entries\n crListReplica.cursorIndex = 0\n}\n","/**\n * Error codes thrown by {@link CRList}.\n */\nexport type CRListErrorCode =\n | 'VALUE_NOT_CLONEABLE'\n | 'INDEX_OUT_OF_BOUNDS'\n | 'LIST_EMPTY'\n | 'LIST_INTEGRITY_VIOLATION'\n | 'UPDATE_EXPECTED_AN_ARRAY'\n\n/**\n * Represents a typed CRList runtime error.\n */\nexport class CRListError extends Error {\n /**\n * The semantic error code for the failure.\n */\n readonly code: CRListErrorCode\n\n /**\n * Creates a typed CRList error.\n *\n * @param code - The semantic error code.\n * @param message - An optional human-readable detail message.\n */\n constructor(code: CRListErrorCode, message?: string) {\n const detail = message ?? code\n super(`{@sovereignbase/convergent-replicated-list} ${detail}`)\n this.code = code\n this.name = 'CRListError'\n }\n}\n","import type { CRListState } from '../../.types/index.js'\nimport { CRListError } from '../../.errors/class.js'\n\n/**\n * Moves the replica cursor to a live index.\n *\n * A valid cached index entry is used directly. Stale cache entries are dropped\n * and the cursor walks from its current position, then repairs the cache at the\n * requested index.\n */\nexport function seekCursorToIndex<T>(\n targetIndex: number,\n crListReplica: CRListState<T>\n): void {\n if (targetIndex < 0 || targetIndex >= crListReplica.size)\n throw new CRListError('INDEX_OUT_OF_BOUNDS', 'Index out of bounds')\n const indexedEntry = crListReplica.index?.get(targetIndex)\n if (indexedEntry) {\n if (crListReplica.parentMap.get(indexedEntry.uuidv7) === indexedEntry) {\n crListReplica.cursor = indexedEntry\n crListReplica.cursorIndex = targetIndex\n return\n } else {\n void crListReplica.index?.delete(targetIndex)\n }\n }\n if (!crListReplica.cursor)\n throw new CRListError('LIST_EMPTY', 'List is empty')\n let cursorIndex = crListReplica.cursorIndex ?? crListReplica.cursor.index\n const direction = cursorIndex > targetIndex ? 'prev' : 'next'\n while (crListReplica.cursor && cursorIndex !== targetIndex) {\n crListReplica.cursor = crListReplica.cursor[direction]\n cursorIndex += direction === 'next' ? 1 : -1\n }\n if (crListReplica.cursor) {\n crListReplica.cursorIndex = targetIndex\n void crListReplica.index?.set(targetIndex, crListReplica.cursor)\n }\n}\n","import type { CRListStateEntry } from '../../.types/index.js'\n\n/**\n * Links a live entry between optional neighboring projection entries.\n */\nexport function linkEntryBetween<T>(\n prev: CRListStateEntry<T>,\n linkedListEntry: NonNullable<CRListStateEntry<T>>,\n next: CRListStateEntry<T>\n): void {\n linkedListEntry.prev = prev\n linkedListEntry.next = next\n if (prev) prev.next = linkedListEntry\n if (next) next.prev = linkedListEntry\n}\n","import type { CRListState, CRListStateEntry } from '../../.types/index.js'\nimport { linkEntryBetween } from '../linkEntryBetween/index.js'\n\n/**\n * Rebuilds the live linked-list projection and index from predecessor buckets.\n *\n * Sibling order is deterministic by UUIDv7, which keeps replicas convergent even\n * when deltas arrive in different orders.\n */\nexport function rebuildLiveProjection<T>(crListReplica: CRListState<T>) {\n crListReplica.cursor = undefined\n const entries = crListReplica.index ?? new Map()\n void entries.clear()\n for (const entry of crListReplica.parentMap.values()) {\n if (!entry) continue\n entry.prev = undefined\n entry.next = undefined\n }\n let previous: CRListStateEntry<T> = undefined\n let first: CRListStateEntry<T> = undefined\n let index = 0\n const appendChildren = (predecessorIdentifier: string): void => {\n const stack: Array<{\n predecessorIdentifier: string\n siblingIndex: number\n siblings?: Array<NonNullable<CRListStateEntry<T>>>\n }> = [{ predecessorIdentifier, siblingIndex: 0 }]\n\n while (stack.length > 0) {\n const frame = stack[stack.length - 1]\n\n if (!frame.siblings) {\n frame.siblings = crListReplica.childrenMap.get(\n frame.predecessorIdentifier\n )\n if (!frame.siblings) {\n void stack.pop()\n continue\n }\n if (frame.siblings.length > 1)\n void frame.siblings.sort((a, b) => (a.uuidv7 > b.uuidv7 ? 1 : -1))\n }\n\n if (frame.siblingIndex >= frame.siblings.length) {\n void stack.pop()\n continue\n }\n\n const sibling = frame.siblings[frame.siblingIndex]\n frame.siblingIndex++\n if (!sibling) continue\n if (crListReplica.parentMap.get(sibling.uuidv7) !== sibling) continue\n\n sibling.index = index\n index++\n void linkEntryBetween<T>(previous, sibling, undefined)\n if (!first) first = sibling\n previous = sibling\n void stack.push({\n predecessorIdentifier: sibling.uuidv7,\n siblingIndex: 0,\n })\n }\n }\n void appendChildren('\\0')\n const detachedPredecessors: Array<string> = []\n for (const predecessorIdentifier of crListReplica.childrenMap.keys()) {\n if (\n predecessorIdentifier !== '\\0' &&\n !crListReplica.parentMap.get(predecessorIdentifier)\n )\n void detachedPredecessors.push(predecessorIdentifier)\n }\n if (detachedPredecessors.length > 1)\n detachedPredecessors.sort((a, b) => (a > b ? 1 : -1))\n for (const predecessorIdentifier of detachedPredecessors)\n void appendChildren(predecessorIdentifier)\n crListReplica.cursor = first\n crListReplica.cursorIndex = first ? 0 : undefined\n if (first) void entries.set(0, first)\n crListReplica.index = entries\n crListReplica.size = crListReplica.parentMap.size\n}\n","import type {\n CRListState,\n CRListSnapshotEntry,\n CRListStateEntry,\n} from '../../.types/index.js'\nimport { isUuidV7 } from '@sovereignbase/utils'\n\n/**\n * Converts a snapshot or delta value entry into local mutable entry state.\n *\n * Invalid, deleted, duplicate, or currently unanchored entries are ignored.\n * Payload values are kept by reference.\n */\nexport function materializeSnapshotEntry<T>(\n valueEntry: CRListSnapshotEntry<T>,\n crListReplica: CRListState<T>\n): CRListStateEntry<T> {\n if (valueEntry === null || valueEntry === undefined) return undefined\n if (\n !isUuidV7(valueEntry.uuidv7) ||\n crListReplica.tombstones.has(valueEntry.uuidv7) ||\n crListReplica.parentMap.has(valueEntry.uuidv7) ||\n (!isUuidV7(valueEntry.predecessor) &&\n valueEntry.predecessor !== '\\0' &&\n !crListReplica.tombstones.has(valueEntry.predecessor))\n )\n return undefined\n\n return {\n uuidv7: valueEntry.uuidv7,\n value: valueEntry.value,\n predecessor: valueEntry.predecessor,\n index: 0,\n next: undefined,\n prev: undefined,\n }\n}\n","import type {\n CRListState,\n CRListStateEntry,\n CRListDelta,\n} from '../../.types/index.js'\n\n/**\n * Attaches a live entry to UUID and predecessor indexes.\n *\n * When a delta buffer is provided, the same live payload reference is appended\n * to the outgoing delta.\n */\nexport function attachEntryToIndexes<T>(\n crListReplica: CRListState<T>,\n linkedListEntry: NonNullable<CRListStateEntry<T>>,\n deltaBuf?: CRListDelta<T>\n): void {\n void crListReplica.parentMap.set(linkedListEntry.uuidv7, linkedListEntry)\n const siblings = crListReplica.childrenMap.get(linkedListEntry.predecessor)\n if (siblings) {\n void siblings.push(linkedListEntry)\n } else {\n void crListReplica.childrenMap.set(linkedListEntry.predecessor, [\n linkedListEntry,\n ])\n }\n if (deltaBuf && !Array.isArray(deltaBuf.values)) deltaBuf.values = []\n if (deltaBuf?.values)\n void deltaBuf.values.push({\n uuidv7: linkedListEntry.uuidv7,\n value: linkedListEntry.value,\n predecessor: linkedListEntry.predecessor,\n })\n}\n","import type { CRListState, CRListStateEntry } from '../../.types/index.js'\n\n/**\n * Removes a live entry from UUID and predecessor indexes.\n */\nexport function detachEntryFromIndexes<T>(\n crListReplica: CRListState<T>,\n linkedListEntry: NonNullable<CRListStateEntry<T>>\n): void {\n void crListReplica.parentMap.delete(linkedListEntry.uuidv7)\n const siblings = crListReplica.childrenMap.get(linkedListEntry.predecessor)\n if (!siblings) return\n const index = siblings.indexOf(linkedListEntry)\n if (index !== -1) void siblings.splice(index, 1)\n}\n","import type {\n CRListDelta,\n CRListState,\n CRListStateEntry,\n} from '../../.types/index.js'\nimport { detachEntryFromIndexes } from '../detachEntryFromIndexes/index.js'\n\n/**\n * Tombstones a live entry and unlinks it from the local projection.\n */\nexport function deleteLiveEntry<T>(\n crListReplica: CRListState<T>,\n linkedListEntry: NonNullable<CRListStateEntry<T>>,\n deltaBuf?: CRListDelta<T>\n): void {\n const prev = linkedListEntry.prev\n const next = linkedListEntry.next\n void crListReplica.tombstones.add(linkedListEntry.uuidv7)\n if (deltaBuf && !Array.isArray(deltaBuf.tombstones)) deltaBuf.tombstones = []\n void deltaBuf?.tombstones?.push(linkedListEntry.uuidv7)\n if (prev) prev.next = next\n if (next) {\n next.prev = prev\n }\n void detachEntryFromIndexes<T>(crListReplica, linkedListEntry)\n if (crListReplica.cursor === linkedListEntry)\n crListReplica.cursor = next ?? prev\n if (!crListReplica.cursor) crListReplica.cursorIndex = undefined\n linkedListEntry.prev = undefined\n linkedListEntry.next = undefined\n crListReplica.size = crListReplica.parentMap.size\n}\n","import type { CRListEventMap } from '../../.types/index.js'\n\n/**\n * Dispatches a typed CRList event payload through an EventTarget.\n */\nexport function dispatchCRListEvent<T, K extends keyof CRListEventMap<T>>(\n eventTarget: EventTarget,\n type: K,\n detail: CRListEventMap<T>[K]\n): void {\n void eventTarget.dispatchEvent(new CustomEvent(type, { detail }))\n}\n","import type {\n CRListDelta,\n CRListState,\n CRListStateEntry,\n} from '../../.types/index.js'\nimport { detachEntryFromIndexes } from '../detachEntryFromIndexes/index.js'\nimport { attachEntryToIndexes } from '../attachEntryToIndexes/index.js'\n\n/**\n * Reattaches an existing live entry to a newer stable predecessor.\n */\nexport function moveEntryToPredecessor<T>(\n crListReplica: CRListState<T>,\n linkedListEntry: NonNullable<CRListStateEntry<T>>,\n predecessor: string,\n deltaBuf?: CRListDelta<T>\n): void {\n void detachEntryFromIndexes<T>(crListReplica, linkedListEntry)\n linkedListEntry.predecessor = predecessor\n void attachEntryToIndexes<T>(crListReplica, linkedListEntry, deltaBuf)\n}\n","/**\n * Parses a JavaScript property key as a safe non-negative list index.\n */\nexport function indexFromPropertyKey(\n index: string | symbol\n): number | undefined {\n if (typeof index !== 'string' || !/^(0|[1-9]\\d*)$/.test(index))\n return undefined\n const listIndex = Number(index)\n return Number.isSafeInteger(listIndex) ? listIndex : undefined\n}\n","import type {\n CRListState,\n CRListStateEntry,\n CRListReparentedEntry,\n} from '../../.types/index.js'\nimport { linkEntryBetween } from '../../.helpers/index.js'\n\n/**\n * Applies the common single-insert reparent delta without a full projection rebuild.\n */\nexport function trySpliceInsertedParent<T>(\n crListReplica: CRListState<T>,\n insertedEntries: Array<NonNullable<CRListStateEntry<T>>>,\n reparentedEntries: Array<CRListReparentedEntry<T>>\n): boolean {\n if (insertedEntries.length !== 1 || reparentedEntries.length !== 1)\n return false\n const inserted = insertedEntries[0]\n const reparented = reparentedEntries[0]\n const moved = reparented.entry\n if (\n moved.predecessor !== inserted.uuidv7 ||\n inserted.predecessor !== reparented.previousPredecessor\n )\n return false\n const siblings = crListReplica.childrenMap.get(inserted.predecessor)\n const children = crListReplica.childrenMap.get(inserted.uuidv7)\n if (\n siblings?.length !== 1 ||\n siblings[0] !== inserted ||\n children?.length !== 1 ||\n children[0] !== moved\n )\n return false\n const predecessor =\n inserted.predecessor === '\\0'\n ? undefined\n : crListReplica.parentMap.get(inserted.predecessor)\n if (inserted.predecessor !== '\\0' && !predecessor) return false\n const expectedIndex = predecessor ? predecessor.index + 1 : 0\n if (\n moved.index !== expectedIndex ||\n moved.prev !== predecessor ||\n (predecessor && predecessor.next !== moved)\n )\n return false\n\n void linkEntryBetween<T>(predecessor, inserted, moved)\n let current: CRListStateEntry<T> = inserted\n let index = expectedIndex\n while (current) {\n current.index = index\n index++\n current = current.next\n }\n crListReplica.index = new Map([[inserted.index, inserted]])\n crListReplica.cursor = inserted\n crListReplica.cursorIndex = inserted.index\n crListReplica.size = crListReplica.parentMap.size\n return true\n}\n","import { isUuidV7, prototype } from '@sovereignbase/utils'\nimport {\n CRListSnapshot,\n CRListState,\n CRListStateEntry,\n} from '../../../.types/index.js'\nimport {\n rebuildLiveProjection,\n materializeSnapshotEntry,\n attachEntryToIndexes,\n linkEntryBetween,\n} from '../../../.helpers/index.js'\n\n/**\n * Creates a local CRList replica from an optional snapshot.\n *\n * Invalid snapshot records are ignored. Accepted values are kept by reference,\n * indexed by UUIDv7, linked through their predecessor buckets, and exposed as a\n * live doubly-linked list projection.\n *\n * @param snapshot - Optional CRList snapshot.\n * @returns - A hydrated CRList replica.\n *\n * Time complexity: O(n log n + t), worst case O(n^2 + t)\n * - n = snapshot value entry count\n * - t = snapshot tombstone count\n *\n * Space complexity: O(n + t)\n */\nexport function __create<T>(snapshot?: CRListSnapshot<T>): CRListState<T> {\n const crListReplica: CRListState<T> = {\n size: 0,\n cursor: undefined,\n cursorIndex: undefined,\n index: new Map(),\n tombstones: new Set<string>(),\n parentMap: new Map<string, NonNullable<CRListStateEntry<T>>>(),\n childrenMap: new Map<string, Array<NonNullable<CRListStateEntry<T>>>>(),\n }\n if (!snapshot || prototype(snapshot) !== 'record') return crListReplica\n\n /** Hydrate tombstone entries. */\n if (\n Object.hasOwn(snapshot, 'tombstones') &&\n Array.isArray(snapshot.tombstones)\n ) {\n for (const tombstone of snapshot.tombstones) {\n if (crListReplica.tombstones.has(tombstone) || !isUuidV7(tombstone))\n continue\n void crListReplica.tombstones.add(tombstone)\n }\n }\n\n /** Hydrate value entries. */\n if (!Object.hasOwn(snapshot, 'values') || !Array.isArray(snapshot.values))\n return crListReplica\n // Build predecessor tree.\n let canUseLinearProjection = true\n let previous: CRListStateEntry<T> = undefined\n for (const valueEntry of snapshot.values) {\n const linkedListEntry = materializeSnapshotEntry<T>(\n valueEntry,\n crListReplica\n )\n if (!linkedListEntry) continue\n void attachEntryToIndexes<T>(crListReplica, linkedListEntry)\n if (\n canUseLinearProjection &&\n linkedListEntry.predecessor === (previous?.uuidv7 ?? '\\0')\n ) {\n linkedListEntry.index = crListReplica.parentMap.size - 1\n void linkEntryBetween<T>(previous, linkedListEntry, undefined)\n previous = linkedListEntry\n void crListReplica.index?.set(linkedListEntry.index, linkedListEntry)\n continue\n }\n canUseLinearProjection = false\n }\n if (canUseLinearProjection) {\n crListReplica.cursor = previous\n crListReplica.cursorIndex = previous\n ? crListReplica.parentMap.size - 1\n : undefined\n crListReplica.size = crListReplica.parentMap.size\n return crListReplica\n }\n // Flatten tree into a doubly linked list and write live-view indexes.\n void rebuildLiveProjection<T>(crListReplica)\n\n return crListReplica\n}\n","import { seekCursorToIndex } from '../../../.helpers/index.js'\nimport { CRListState } from '../../../.types/index.js'\n\n/**\n * Reads the value at an index in the replica live view.\n *\n * The replica cursor is moved as part of the lookup. Successful reads return\n * the live value reference stored by the replica. Mutating that value directly\n * can mutate replica state and should only be done when the caller owns an\n * independent value object. Out-of-bounds and empty list reads resolve to\n * `undefined` instead of throwing.\n *\n * @param targetIndex - Index in the live list.\n * @param crListReplica - Replica to read from.\n * @returns - The live value at `targetIndex`, or `undefined` when\n * no value is present.\n *\n * Time complexity: O(d), worst case O(n)\n * - d = distance from cursor to target index\n * - n = list size\n *\n * Space complexity: O(1)\n */\nexport function __read<T>(\n targetIndex: number,\n crListReplica: CRListState<T>\n): T | undefined {\n try {\n void seekCursorToIndex<T>(targetIndex, crListReplica)\n return crListReplica.cursor?.value\n } catch {\n return undefined\n }\n}\n","import { CRListError } from '../../../.errors/class.js'\nimport {\n attachEntryToIndexes,\n detachEntryFromIndexes,\n seekCursorToIndex,\n moveEntryToPredecessor,\n linkEntryBetween,\n} from '../../../.helpers/index.js'\nimport { v7 as uuidv7 } from 'uuid'\nimport {\n CRListChange,\n CRListDelta,\n CRListState,\n CRListStateEntry,\n} from '../../../.types/index.js'\n/**\n * Applies a local value mutation to the replica live view.\n *\n * The update can replace a range starting at the target entry, insert values\n * before it, or insert values after it. The returned delta is suitable for\n * gossip and the returned change describes the local live-view patch.\n *\n * @param listIndex - Target index in the live list.\n * @param listValues - Values to insert or overwrite.\n * @param crListReplica - Replica to mutate.\n * @param mode - Mutation mode relative to `listIndex`.\n * @returns - A local change and gossip delta, or `false` if no mutation occurred.\n *\n * Time complexity: O(d + v + r + vk), worst case O(vn)\n * - d = distance from cursor to target index\n * - v = amount of input values\n * - r = amount of nodes after inserted values whose indexes must be shifted\n * - k = sibling bucket size when predecessor bucket is updated\n *\n * Space complexity: O(v)\n */\nexport function __update<T>(\n listIndex: number,\n listValues: Array<T>,\n crListReplica: CRListState<T>,\n mode: 'overwrite' | 'before' | 'after'\n): { change: CRListChange<T>; delta: CRListDelta<T> } | false {\n if (listIndex < 0 || listIndex > crListReplica.size)\n throw new CRListError('INDEX_OUT_OF_BOUNDS')\n if (!Array.isArray(listValues))\n throw new CRListError(\n 'UPDATE_EXPECTED_AN_ARRAY',\n '`listValues` must be an Array'\n )\n if (listValues.length === 0) return false\n const change: CRListChange<T> = {}\n const delta: CRListDelta<T> = { values: [], tombstones: [] }\n for (const listValue of listValues) {\n const v7 = uuidv7()\n\n const linkedListEntry: NonNullable<CRListStateEntry<T>> = {\n uuidv7: v7,\n value: listValue,\n predecessor: '\\0',\n index: 0,\n next: undefined,\n prev: undefined,\n }\n\n switch (mode) {\n case 'overwrite': {\n if (listIndex === crListReplica.size) {\n if (crListReplica.size === 0) {\n crListReplica.cursor = linkedListEntry\n crListReplica.cursorIndex = linkedListEntry.index\n void attachEntryToIndexes<T>(crListReplica, linkedListEntry, delta)\n crListReplica.index?.set(linkedListEntry.index, linkedListEntry)\n change[linkedListEntry.index] = linkedListEntry.value\n break\n }\n void seekCursorToIndex<T>(crListReplica.size - 1, crListReplica)\n if (!crListReplica.cursor) return false\n linkedListEntry.index = (crListReplica.cursorIndex ?? 0) + 1\n linkedListEntry.predecessor = crListReplica.cursor.uuidv7\n void linkEntryBetween<T>(\n crListReplica.cursor,\n linkedListEntry,\n undefined\n )\n void attachEntryToIndexes<T>(crListReplica, linkedListEntry, delta)\n crListReplica.cursor = linkedListEntry\n crListReplica.cursorIndex = linkedListEntry.index\n void crListReplica.index?.set(linkedListEntry.index, linkedListEntry)\n change[linkedListEntry.index] = linkedListEntry.value\n break\n }\n void seekCursorToIndex<T>(listIndex, crListReplica)\n if (!crListReplica.cursor) return false\n const entryToOverwrite = crListReplica.cursor\n const actualIndex = crListReplica.cursorIndex ?? listIndex\n\n linkedListEntry.predecessor = entryToOverwrite.predecessor\n linkedListEntry.index = actualIndex\n void linkEntryBetween<T>(\n entryToOverwrite.prev,\n linkedListEntry,\n entryToOverwrite.next\n )\n if (entryToOverwrite.next) {\n if (entryToOverwrite.next.predecessor === entryToOverwrite.uuidv7) {\n void moveEntryToPredecessor<T>(\n crListReplica,\n entryToOverwrite.next,\n linkedListEntry.uuidv7,\n delta\n )\n }\n }\n void attachEntryToIndexes<T>(crListReplica, linkedListEntry, delta)\n void crListReplica.tombstones.add(entryToOverwrite.uuidv7)\n void delta.tombstones?.push(entryToOverwrite.uuidv7)\n void detachEntryFromIndexes<T>(crListReplica, entryToOverwrite)\n entryToOverwrite.next = undefined\n entryToOverwrite.prev = undefined\n crListReplica.cursor = linkedListEntry\n crListReplica.cursorIndex = actualIndex\n void crListReplica.index?.set(linkedListEntry.index, linkedListEntry)\n change[actualIndex] = linkedListEntry.value\n break\n }\n case 'after': {\n if (crListReplica.size === 0 && listIndex === 0) {\n crListReplica.cursor = linkedListEntry\n crListReplica.cursorIndex = linkedListEntry.index\n void attachEntryToIndexes<T>(crListReplica, linkedListEntry, delta)\n void crListReplica.index?.set(linkedListEntry.index, linkedListEntry)\n change[linkedListEntry.index] = linkedListEntry.value\n break\n }\n if (listIndex === crListReplica.size) {\n void seekCursorToIndex<T>(crListReplica.size - 1, crListReplica)\n } else {\n void seekCursorToIndex<T>(listIndex, crListReplica)\n }\n if (!crListReplica.cursor) return false\n const actualIndex = crListReplica.cursorIndex ?? listIndex\n const next =\n listIndex === crListReplica.size\n ? undefined\n : crListReplica.cursor.next\n linkedListEntry.index = actualIndex + 1\n linkedListEntry.predecessor = crListReplica.cursor.uuidv7\n void linkEntryBetween<T>(crListReplica.cursor, linkedListEntry, next)\n if (next) {\n if (next.predecessor === crListReplica.cursor.uuidv7) {\n void moveEntryToPredecessor<T>(\n crListReplica,\n next,\n linkedListEntry.uuidv7,\n delta\n )\n }\n }\n void attachEntryToIndexes<T>(crListReplica, linkedListEntry, delta)\n crListReplica.cursor = linkedListEntry\n crListReplica.cursorIndex = linkedListEntry.index\n if (next) crListReplica.index = new Map()\n void crListReplica.index?.set(linkedListEntry.index, linkedListEntry)\n change[linkedListEntry.index] = linkedListEntry.value\n break\n }\n case 'before': {\n if (crListReplica.size === 0 && listIndex === 0) {\n crListReplica.cursor = linkedListEntry\n crListReplica.cursorIndex = linkedListEntry.index\n void attachEntryToIndexes<T>(crListReplica, linkedListEntry, delta)\n void crListReplica.index?.set(linkedListEntry.index, linkedListEntry)\n change[linkedListEntry.index] = linkedListEntry.value\n mode = 'after'\n listIndex = linkedListEntry.index - 1\n break\n }\n void seekCursorToIndex<T>(listIndex, crListReplica)\n if (!crListReplica.cursor) return false\n const actualIndex = crListReplica.cursorIndex ?? listIndex\n const prev = crListReplica.cursor.prev\n linkedListEntry.index = actualIndex\n linkedListEntry.predecessor = prev?.uuidv7 ?? '\\0'\n void linkEntryBetween<T>(prev, linkedListEntry, crListReplica.cursor)\n if (crListReplica.cursor.predecessor === linkedListEntry.predecessor) {\n void moveEntryToPredecessor<T>(\n crListReplica,\n crListReplica.cursor,\n linkedListEntry.uuidv7,\n delta\n )\n }\n void attachEntryToIndexes<T>(crListReplica, linkedListEntry, delta)\n crListReplica.cursor = linkedListEntry\n crListReplica.cursorIndex = actualIndex\n crListReplica.index = new Map()\n void crListReplica.index?.set(linkedListEntry.index, linkedListEntry)\n change[actualIndex] = linkedListEntry.value\n mode = 'after'\n listIndex = linkedListEntry.index - 1\n\n break\n }\n }\n crListReplica.size = crListReplica.parentMap.size\n listIndex++\n }\n return { change, delta }\n}\n","import { deleteLiveEntry, seekCursorToIndex } from '../../../.helpers/index.js'\nimport { CRListError } from '../../../.errors/class.js'\nimport type {\n CRListChange,\n CRListDelta,\n CRListState,\n CRListStateEntry,\n} from '../../../.types/index.js'\n\n/**\n * Deletes a range from the replica live view.\n *\n * With no indexes, the full list is deleted. With only `startIndex`, all entries\n * from `startIndex` onward are deleted. With both indexes, the deleted range is\n * `[startIndex, endIndex)`.\n *\n * @param crListReplica - Replica to mutate.\n * @param startIndex - Inclusive start index. Defaults to `0`.\n * @param endIndex - Exclusive end index. Defaults to the current list size.\n * @returns - A local change and gossip delta, or `false` if nothing was deleted.\n *\n * Time complexity: O(d + qk + r), worst case O(n^2)\n * - d = distance from cursor to target index\n * - q = amount of deleted nodes\n * - r = amount of nodes after the deleted range whose indexes must be shifted\n * - k = sibling bucket size when deleted entries are removed from buckets\n *\n * Space complexity: O(q)\n */\nexport function __delete<T>(\n crListReplica: CRListState<T>,\n startIndex?: number,\n endIndex?: number\n): { change: CRListChange<T>; delta: CRListDelta<T> } | false {\n const change: CRListChange<T> = {}\n const delta: CRListDelta<T> = { values: [], tombstones: [] }\n const listIndex = startIndex ?? 0\n const targetEndIndex = endIndex ?? crListReplica.size\n if (\n listIndex < 0 ||\n targetEndIndex < listIndex ||\n listIndex > crListReplica.size\n )\n throw new CRListError('INDEX_OUT_OF_BOUNDS')\n const deleteCount = Math.min(targetEndIndex, crListReplica.size) - listIndex\n if (deleteCount <= 0) return false\n\n void seekCursorToIndex<T>(listIndex, crListReplica)\n if (!crListReplica.cursor) return false\n\n let current: CRListStateEntry<T> = crListReplica.cursor\n let deleted = 0\n let currentIndex = crListReplica.cursorIndex ?? listIndex\n\n while (current && deleted < deleteCount) {\n const next: CRListStateEntry<T> = current.next\n change[currentIndex] = undefined\n void crListReplica.index?.delete(currentIndex)\n void deleteLiveEntry<T>(crListReplica, current, delta)\n current = next\n currentIndex++\n deleted++\n }\n\n crListReplica.size = crListReplica.parentMap.size\n crListReplica.cursor = current ?? crListReplica.cursor\n crListReplica.cursorIndex = current\n ? listIndex\n : crListReplica.cursor\n ? Math.max(0, crListReplica.size - 1)\n : undefined\n crListReplica.index = new Map()\n if (crListReplica.cursor && crListReplica.cursorIndex !== undefined)\n void crListReplica.index.set(\n crListReplica.cursorIndex,\n crListReplica.cursor\n )\n\n return { change, delta }\n}\n","import type {\n CRListChange,\n CRListDelta,\n CRListState,\n CRListStateEntry,\n} from '../../../.types/index.js'\nimport {\n materializeSnapshotEntry,\n attachEntryToIndexes,\n rebuildLiveProjection,\n rebuildLiveIndex,\n deleteLiveEntry,\n moveEntryToPredecessor,\n} from '../../../.helpers/index.js'\nimport { prototype, isUuidV7 } from '@sovereignbase/utils'\nimport { trySpliceInsertedParent } from '../../../.helpers/trySpliceInsertedParent/index.js'\n\n/**\n * Merges a remote CRList delta into the local replica.\n *\n * Accepted tombstones update the local live view and accepted values are attached\n * to the predecessor tree. Tail-append deltas are linked incrementally; deltas\n * that can affect ordering fall back to deterministic relinking.\n *\n * @param crListReplica - Replica to mutate.\n * @param crListDelta - Remote gossip delta.\n * @returns - A minimal local change patch, or `false` when the delta is ignored.\n *\n * Time complexity: O(v + t) for tail-append deltas; O(n + t + qk) for tombstone-only deletes; otherwise O(n log n + v + t + m*k)\n * Worst case: O(n^2 + (v + t)n)\n * - n = replica value entry count after merge\n * - v = delta value entry count\n * - t = delta tombstone count\n * - q = amount of live entries deleted by tombstones\n * - m = entries moved between predecessor buckets\n * - k = sibling bucket size when entries are removed from buckets\n *\n * Space complexity: O(n + v + t)\n */\nexport function __merge<T>(\n crListReplica: CRListState<T>,\n crListDelta: CRListDelta<T>\n): CRListChange<T> | false {\n if (!crListDelta || prototype(crListDelta) !== 'record') return false\n const newVals: Array<NonNullable<CRListStateEntry<T>>> = []\n const newTombsIndices: Array<number> = []\n const reparentedVals: Array<{\n entry: NonNullable<CRListStateEntry<T>>\n previousPredecessor: string\n }> = []\n const change: CRListChange<T> = {}\n let needsRelink = false\n if (\n Object.hasOwn(crListDelta, 'values') &&\n Array.isArray(crListDelta.values) &&\n crListDelta.values.length === 1 &&\n (!Object.hasOwn(crListDelta, 'tombstones') ||\n (Array.isArray(crListDelta.tombstones) &&\n crListDelta.tombstones.length === 0))\n ) {\n const linkedListEntry = materializeSnapshotEntry<T>(\n crListDelta.values[0],\n crListReplica\n )\n if (!linkedListEntry) return false\n const predecessor =\n linkedListEntry.predecessor === '\\0'\n ? undefined\n : crListReplica.parentMap.get(linkedListEntry.predecessor)\n if (\n (linkedListEntry.predecessor === '\\0' && crListReplica.size === 0) ||\n (predecessor && !predecessor.next)\n ) {\n linkedListEntry.prev = predecessor\n linkedListEntry.index = crListReplica.size\n if (predecessor) predecessor.next = linkedListEntry\n crListReplica.cursor = linkedListEntry\n crListReplica.cursorIndex = linkedListEntry.index\n void attachEntryToIndexes<T>(crListReplica, linkedListEntry)\n crListReplica.size = crListReplica.parentMap.size\n void crListReplica.index?.set(linkedListEntry.index, linkedListEntry)\n return { [linkedListEntry.index]: linkedListEntry.value }\n }\n }\n\n /** Apply tombstone entries. */\n if (\n Object.hasOwn(crListDelta, 'tombstones') &&\n Array.isArray(crListDelta.tombstones)\n ) {\n for (const tombstone of crListDelta.tombstones) {\n if (crListReplica.tombstones.has(tombstone) || !isUuidV7(tombstone))\n continue\n void crListReplica.tombstones.add(tombstone)\n const linkedListEntry = crListReplica.parentMap.get(tombstone)\n if (linkedListEntry) {\n void newTombsIndices.push(linkedListEntry.index)\n void crListReplica.index?.delete(linkedListEntry.index)\n void deleteLiveEntry<T>(crListReplica, linkedListEntry)\n needsRelink = true\n }\n }\n }\n\n /** Apply value entries. */\n if (\n !Object.hasOwn(crListDelta, 'values') ||\n !Array.isArray(crListDelta.values)\n ) {\n if (newTombsIndices.length === 0) return false\n void rebuildLiveIndex<T>(crListReplica)\n for (const index of newTombsIndices) {\n change[index] = undefined\n }\n return change\n }\n // Attach accepted values to the predecessor tree.\n for (const valueEntry of crListDelta.values) {\n if (valueEntry === null || valueEntry === undefined) continue\n const existingEntry = crListReplica.parentMap.get(valueEntry.uuidv7)\n if (existingEntry) {\n if (crListReplica.tombstones.has(valueEntry.uuidv7)) continue\n if (valueEntry.predecessor !== '\\0' && !isUuidV7(valueEntry.predecessor))\n continue\n if (existingEntry.predecessor >= valueEntry.predecessor) continue\n const previousPredecessor = existingEntry.predecessor\n void moveEntryToPredecessor<T>(\n crListReplica,\n existingEntry,\n valueEntry.predecessor\n )\n void reparentedVals.push({ entry: existingEntry, previousPredecessor })\n needsRelink = true\n continue\n }\n const linkedListEntry = materializeSnapshotEntry<T>(\n valueEntry,\n crListReplica\n )\n if (!linkedListEntry) continue\n const predecessor =\n linkedListEntry.predecessor === '\\0'\n ? undefined\n : crListReplica.parentMap.get(linkedListEntry.predecessor)\n void attachEntryToIndexes<T>(crListReplica, linkedListEntry)\n void newVals.push(linkedListEntry)\n if (!needsRelink && linkedListEntry.predecessor === '\\0') {\n if (crListReplica.size === 0) {\n crListReplica.cursor = linkedListEntry\n crListReplica.cursorIndex = linkedListEntry.index\n crListReplica.size = crListReplica.parentMap.size\n void crListReplica.index?.set(linkedListEntry.index, linkedListEntry)\n } else {\n needsRelink = true\n }\n } else if (!needsRelink && predecessor && !predecessor.next) {\n linkedListEntry.prev = predecessor\n linkedListEntry.index = crListReplica.size\n predecessor.next = linkedListEntry\n crListReplica.cursor = linkedListEntry\n crListReplica.cursorIndex = linkedListEntry.index\n crListReplica.size = crListReplica.parentMap.size\n void crListReplica.index?.set(linkedListEntry.index, linkedListEntry)\n } else {\n needsRelink = true\n }\n }\n if (needsRelink) {\n if (!trySpliceInsertedParent<T>(crListReplica, newVals, reparentedVals)) {\n // Flatten tree into a doubly linked list and write live-view indexes.\n void rebuildLiveProjection<T>(crListReplica)\n }\n }\n\n if (newTombsIndices.length === 0 && newVals.length === 0) return false\n\n for (const index of newTombsIndices) {\n change[index] = undefined\n }\n for (const val of newVals) {\n change[val.index] = val.value\n }\n\n return change\n}\n","import type { CRListAck, CRListState } from '../../../.types/index.js'\n\n/**\n * Returns the replica tombstone acknowledgement frontier.\n *\n * The frontier is the greatest tombstone identifier currently retained by the\n * replica. Peers can use it as input for tombstone garbage collection.\n *\n * @param crListReplica - Replica to acknowledge.\n * @returns - The acknowledgement frontier, or `false` when there are no tombstones.\n *\n * Time complexity: O(t)\n * - t = replica tombstone count\n *\n * Space complexity: O(1)\n */\nexport function __acknowledge<T>(\n crListReplica: CRListState<T>\n): CRListAck | false {\n let largest: CRListAck | false = false\n void crListReplica.tombstones.forEach((tombstone) => {\n if (largest === false || largest < tombstone) largest = tombstone\n })\n if (typeof largest === 'string') return largest\n return false\n}\n","import { isUuidV7 } from '@sovereignbase/utils'\nimport { CRListAck, CRListState } from '../../../.types/index.js'\n\n/**\n * Removes tombstones acknowledged by all supplied frontiers.\n *\n * The smallest valid UUIDv7 frontier is used as the safe collection boundary.\n * Tombstones less than or equal to that boundary are removed from the local\n * replica.\n *\n * @param frontiers - Acknowledgement frontiers received from peers.\n * @param crListReplica - Replica whose tombstones will be collected.\n *\n * Time complexity: O(f log f + t)\n * - f = frontier count\n * - t = replica tombstone count\n *\n * Space complexity: O(1)\n */\nexport function __garbageCollect<T>(\n frontiers: Array<CRListAck>,\n crListReplica: CRListState<T>\n): void {\n if (!Array.isArray(frontiers)) return\n void frontiers.sort()\n const smallest = frontiers.find((frontier) => isUuidV7(frontier))\n if (typeof smallest !== 'string') return\n void crListReplica.tombstones.forEach((tombstone, __, tombstones) => {\n if (tombstone <= smallest) {\n void tombstones.delete(tombstone)\n }\n })\n}\n","import { CRListError } from '../../../.errors/class.js'\nimport { CRListState, CRListSnapshot } from '../../../.types/index.js'\n\n/**\n * Creates a full CRList snapshot from the current replica state.\n *\n * The snapshot contains every live value entry and all retained tombstones. Value\n * payloads are live references, so callers must not mutate snapshot values\n * unless they have first isolated them from replica state.\n *\n * @param crListReplica - Replica to snapshot.\n * @returns - A full snapshot suitable for hydration or transport.\n *\n * Time complexity: O(n + t)\n * - n = replica value entry count\n * - t = replica tombstone count\n *\n * Space complexity: O(n + t)\n */\nexport function __snapshot<T>(\n crListReplica: CRListState<T>\n): CRListSnapshot<T> {\n return {\n values: Array.from(crListReplica.parentMap.values()).map(\n (linkedListEntry) => {\n if (!linkedListEntry) throw new CRListError('LIST_INTEGRITY_VIOLATION')\n return {\n uuidv7: linkedListEntry.uuidv7,\n value: linkedListEntry.value,\n predecessor: linkedListEntry.predecessor,\n }\n }\n ),\n tombstones: Array.from(crListReplica.tombstones),\n }\n}\n","import { dispatchCRListEvent, indexFromPropertyKey } from '../.helpers/index.js'\nimport { CRListError } from '../.errors/class.js'\nimport type {\n CRListState,\n CRListSnapshot,\n CRListEventListenerFor,\n CRListEventMap,\n CRListDelta,\n CRListAck,\n} from '../.types/index.js'\nimport { __create, __read, __update, __delete } from '../core/crud/index.js'\nimport {\n __merge,\n __acknowledge,\n __garbageCollect,\n __snapshot,\n} from '../core/mags/index.js'\n\n/**\n * A convergent replicated list.\n *\n * Numeric property access reads and mutates the live list projection:\n * `list[0]` reads the live value reference, `list[0] = value` writes an\n * entry, and `delete list[0]` removes one entry. Iteration, `find()`, and\n * `forEach()` expose the same live value references. Mutating returned objects\n * directly can mutate replica state without producing a CRDT delta, so callers\n * must isolate values before out-of-band mutation. Local mutations emit `delta`\n * and `change` events; remote merges emit `change` events.\n *\n * @typeParam T - The value type stored in the list.\n */\nexport class CRList<T> {\n /**\n * Reads or overwrites an entry in the live list projection by index.\n *\n * Reads return live value references.\n */\n [index: number]: T\n declare private readonly state: CRListState<T>\n declare private readonly eventTarget: EventTarget\n\n /**\n * Creates a replicated list from an optional CRList snapshot.\n *\n * @param snapshot - A previously emitted CRList snapshot.\n */\n constructor(snapshot?: CRListSnapshot<T>) {\n void Object.defineProperties(this, {\n state: {\n value: __create<T>(snapshot),\n enumerable: false,\n configurable: false,\n writable: false,\n },\n eventTarget: {\n value: new EventTarget(),\n enumerable: false,\n configurable: false,\n writable: false,\n },\n })\n\n return new Proxy(this, {\n get(target, index, receiver) {\n const listIndex = indexFromPropertyKey(index)\n // Preserve normal property access for non-index keys.\n if (listIndex === undefined) return Reflect.get(target, index, receiver)\n return __read(listIndex, target.state)\n },\n has(target, index) {\n const listIndex = indexFromPropertyKey(index)\n // Preserve normal property checks for non-index keys.\n if (listIndex === undefined) return Reflect.has(target, index)\n return listIndex >= 0 && listIndex < target.state.size\n },\n set(target, index, value) {\n const listIndex = indexFromPropertyKey(index)\n if (listIndex === undefined) return false\n try {\n const result = __update(listIndex, [value], target.state, 'overwrite')\n if (!result) return false\n const { delta, change } = result\n if (delta)\n void dispatchCRListEvent(target.eventTarget, 'delta', delta)\n if (change)\n void dispatchCRListEvent(target.eventTarget, 'change', change)\n return true\n } catch (error) {\n if (error instanceof CRListError) throw error\n return false\n }\n },\n deleteProperty(target, index) {\n const listIndex = indexFromPropertyKey(index)\n if (listIndex === undefined) return false\n try {\n const result = __delete(target.state, listIndex, listIndex + 1)\n if (!result) return false\n const { delta, change } = result\n if (delta)\n void dispatchCRListEvent(target.eventTarget, 'delta', delta)\n if (change)\n void dispatchCRListEvent(target.eventTarget, 'change', change)\n return true\n } catch (error) {\n if (error instanceof CRListError) throw error\n return false\n }\n },\n ownKeys(target) {\n return [\n ...Reflect.ownKeys(target),\n ...Array.from({ length: target.size }, (_, index) => String(index)),\n ]\n },\n\n getOwnPropertyDescriptor(target, index) {\n const listIndex = indexFromPropertyKey(index)\n\n if (listIndex !== undefined && listIndex < target.size) {\n return {\n value: __read(listIndex, target.state),\n writable: true,\n enumerable: true,\n configurable: true,\n }\n }\n // Preserve normal property checks for non-index keys.\n return Reflect.getOwnPropertyDescriptor(target, index)\n },\n })\n }\n\n /**\n * The current number of live entries.\n */\n get size(): number {\n return this.state.size\n }\n /**\n * Inserts a value before an index.\n *\n * If `beforeIndex` is omitted, the value is inserted at the start of the list.\n *\n * @param value - The value to insert.\n * @param beforeIndex - The index to insert before.\n */\n prepend(value: T, beforeIndex?: number): void {\n const result = __update<T>(beforeIndex ?? 0, [value], this.state, 'before')\n if (!result) return\n const { delta, change } = result\n if (delta) void dispatchCRListEvent(this.eventTarget, 'delta', delta)\n if (change) void dispatchCRListEvent(this.eventTarget, 'change', change)\n }\n /**\n * Inserts a value after an index.\n *\n * If `afterIndex` is omitted, the value is appended at the end of the list.\n *\n * @param value - The value to insert.\n * @param afterIndex - The index to insert after.\n */\n append(value: T, afterIndex?: number): void {\n const result = __update<T>(\n afterIndex ?? this.state.size,\n [value],\n this.state,\n 'after'\n )\n if (!result) return\n const { delta, change } = result\n if (delta) void dispatchCRListEvent(this.eventTarget, 'delta', delta)\n if (change) void dispatchCRListEvent(this.eventTarget, 'change', change)\n }\n /**\n * Removes the entry at an index.\n *\n * @param index - The index to remove.\n */\n remove(index: number): void {\n const result = __delete(this.state, index, index + 1)\n if (!result) return\n const { delta, change } = result\n if (delta) void dispatchCRListEvent(this.eventTarget, 'delta', delta)\n if (change) void dispatchCRListEvent(this.eventTarget, 'change', change)\n }\n\n /**\n * Returns the first live value matching a predicate in index order.\n *\n * Predicate values are live references. Mutating them directly can mutate the\n * list without emitting a delta.\n *\n * @param predicate - Function to test each live value.\n * @param thisArg - Optional `this` value for the predicate.\n */\n find(\n predicate: (this: unknown, value: T, index: number, list: this) => unknown,\n thisArg?: unknown\n ): T | undefined {\n let linkedListEntry = this.state.index?.get(0) ?? this.state.cursor\n while (linkedListEntry?.prev) linkedListEntry = linkedListEntry.prev\n let index = 0\n while (linkedListEntry) {\n if (predicate.call(thisArg, linkedListEntry.value, index, this))\n return linkedListEntry.value\n linkedListEntry = linkedListEntry.next\n index++\n }\n\n return undefined\n }\n\n /**\n * Applies a remote gossip delta to this list.\n *\n * Emits a `change` event when the merge changes the live projection.\n *\n * @param delta - The remote CRList delta to merge.\n */\n merge(delta: CRListDelta<T>): void {\n const change = __merge(this.state, delta)\n if (change) void dispatchCRListEvent(this.eventTarget, 'change', change)\n }\n /**\n * Emits an acknowledgement frontier for currently retained tombstones.\n */\n acknowledge(): void {\n const ack = __acknowledge(this.state)\n if (ack) void dispatchCRListEvent(this.eventTarget, 'ack', ack)\n }\n /**\n * Garbage-collects tombstones that are covered by acknowledgement frontiers.\n *\n * @param frontiers - Replica acknowledgement frontiers.\n */\n garbageCollect(frontiers: Array<CRListAck>): void {\n void __garbageCollect(frontiers, this.state)\n }\n /**\n * Emits the current CRList snapshot.\n *\n * Snapshot value payloads are live references. Mutating them can mutate\n * replica state without emitting a delta.\n */\n snapshot(): void {\n const snapshot = __snapshot<T>(this.state)\n if (snapshot)\n void dispatchCRListEvent(this.eventTarget, 'snapshot', snapshot)\n }\n /**\n * Registers an event listener.\n *\n * @param type - The event type to listen for.\n * @param listener - The listener to register.\n * @param options - Listener registration options.\n */\n addEventListener<K extends keyof CRListEventMap<T>>(\n type: K,\n listener: CRListEventListenerFor<T, K> | null,\n options?: boolean | AddEventListenerOptions\n ): void {\n void this.eventTarget.addEventListener(\n type,\n listener as EventListenerOrEventListenerObject | null,\n options\n )\n }\n\n /**\n * Removes an event listener.\n *\n * @param type - The event type to stop listening for.\n * @param listener - The listener to remove.\n * @param options - Listener removal options.\n */\n removeEventListener<K extends keyof CRListEventMap<T>>(\n type: K,\n listener: CRListEventListenerFor<T, K> | null,\n options?: boolean | EventListenerOptions\n ): void {\n void this.eventTarget.removeEventListener(\n type,\n listener as EventListenerOrEventListenerObject | null,\n options\n )\n }\n /**\n * Returns a CRList snapshot of this list.\n *\n * Snapshot value payloads are live references. Mutating them can mutate\n * replica state without emitting a delta.\n *\n * Called automatically by `JSON.stringify`.\n */\n toJSON(): CRListSnapshot<T> {\n return __snapshot<T>(this.state)\n }\n /**\n * Attempts to return this list snapshot as a JSON string.\n *\n * This can fail when list values are not JSON-compatible.\n */\n toString(): string {\n return JSON.stringify(this)\n }\n /**\n * Returns the Node.js console inspection representation.\n */\n [Symbol.for('nodejs.util.inspect.custom')](): CRListSnapshot<T> {\n return this.toJSON()\n }\n /**\n * Returns the Deno console inspection representation.\n */\n [Symbol.for('Deno.customInspect')](): CRListSnapshot<T> {\n return this.toJSON()\n }\n /**\n * Iterates over current live values in index order.\n */\n *[Symbol.iterator](): IterableIterator<T> {\n for (let index = 0; index < this.size; index++) {\n const value = this[index]\n yield value\n }\n }\n /**\n * Calls a function once for each live value in index order.\n *\n * Callback values are live references. Mutating them directly can mutate the\n * list without emitting a delta.\n *\n * @param callback - Function to call for each live value.\n * @param thisArg - Optional `this` value for the callback.\n */\n forEach(\n callback: (value: T, index: number, list: this) => void,\n thisArg?: unknown\n ): void {\n for (let index = 0; index < this.size; index++) {\n void callback.call(thisArg, this[index], index, this)\n }\n }\n}\n"]}
package/dist/index.js CHANGED
@@ -108,19 +108,37 @@ function rebuildLiveProjection(crListReplica) {
108
108
  let first = void 0;
109
109
  let index = 0;
110
110
  const appendChildren = (predecessorIdentifier) => {
111
- const siblings = crListReplica.childrenMap.get(predecessorIdentifier);
112
- if (!siblings) return;
113
- if (siblings.length > 1)
114
- void siblings.sort((a, b) => a.uuidv7 > b.uuidv7 ? 1 : -1);
115
- for (const sibling of siblings) {
116
- if (!sibling || crListReplica.parentMap.get(sibling.uuidv7) !== sibling)
111
+ const stack = [{ predecessorIdentifier, siblingIndex: 0 }];
112
+ while (stack.length > 0) {
113
+ const frame = stack[stack.length - 1];
114
+ if (!frame.siblings) {
115
+ frame.siblings = crListReplica.childrenMap.get(
116
+ frame.predecessorIdentifier
117
+ );
118
+ if (!frame.siblings) {
119
+ void stack.pop();
120
+ continue;
121
+ }
122
+ if (frame.siblings.length > 1)
123
+ void frame.siblings.sort((a, b) => a.uuidv7 > b.uuidv7 ? 1 : -1);
124
+ }
125
+ if (frame.siblingIndex >= frame.siblings.length) {
126
+ void stack.pop();
117
127
  continue;
128
+ }
129
+ const sibling = frame.siblings[frame.siblingIndex];
130
+ frame.siblingIndex++;
131
+ if (!sibling) continue;
132
+ if (crListReplica.parentMap.get(sibling.uuidv7) !== sibling) continue;
118
133
  sibling.index = index;
119
134
  index++;
120
135
  void linkEntryBetween(previous, sibling, void 0);
121
136
  if (!first) first = sibling;
122
137
  previous = sibling;
123
- void appendChildren(sibling.uuidv7);
138
+ void stack.push({
139
+ predecessorIdentifier: sibling.uuidv7,
140
+ siblingIndex: 0
141
+ });
124
142
  }
125
143
  };
126
144
  void appendChildren("\0");
@@ -225,6 +243,39 @@ function indexFromPropertyKey(index) {
225
243
  return Number.isSafeInteger(listIndex) ? listIndex : void 0;
226
244
  }
227
245
 
246
+ // src/.helpers/trySpliceInsertedParent/index.ts
247
+ function trySpliceInsertedParent(crListReplica, insertedEntries, reparentedEntries) {
248
+ if (insertedEntries.length !== 1 || reparentedEntries.length !== 1)
249
+ return false;
250
+ const inserted = insertedEntries[0];
251
+ const reparented = reparentedEntries[0];
252
+ const moved = reparented.entry;
253
+ if (moved.predecessor !== inserted.uuidv7 || inserted.predecessor !== reparented.previousPredecessor)
254
+ return false;
255
+ const siblings = crListReplica.childrenMap.get(inserted.predecessor);
256
+ const children = crListReplica.childrenMap.get(inserted.uuidv7);
257
+ if (siblings?.length !== 1 || siblings[0] !== inserted || children?.length !== 1 || children[0] !== moved)
258
+ return false;
259
+ const predecessor = inserted.predecessor === "\0" ? void 0 : crListReplica.parentMap.get(inserted.predecessor);
260
+ if (inserted.predecessor !== "\0" && !predecessor) return false;
261
+ const expectedIndex = predecessor ? predecessor.index + 1 : 0;
262
+ if (moved.index !== expectedIndex || moved.prev !== predecessor || predecessor && predecessor.next !== moved)
263
+ return false;
264
+ void linkEntryBetween(predecessor, inserted, moved);
265
+ let current = inserted;
266
+ let index = expectedIndex;
267
+ while (current) {
268
+ current.index = index;
269
+ index++;
270
+ current = current.next;
271
+ }
272
+ crListReplica.index = /* @__PURE__ */ new Map([[inserted.index, inserted]]);
273
+ crListReplica.cursor = inserted;
274
+ crListReplica.cursorIndex = inserted.index;
275
+ crListReplica.size = crListReplica.parentMap.size;
276
+ return true;
277
+ }
278
+
228
279
  // src/core/crud/create/index.ts
229
280
  import { isUuidV7 as isUuidV72, prototype } from "@sovereignbase/utils";
230
281
  function __create(snapshot) {
@@ -491,6 +542,7 @@ function __merge(crListReplica, crListDelta) {
491
542
  if (!crListDelta || prototype2(crListDelta) !== "record") return false;
492
543
  const newVals = [];
493
544
  const newTombsIndices = [];
545
+ const reparentedVals = [];
494
546
  const change = {};
495
547
  let needsRelink = false;
496
548
  if (Object.hasOwn(crListDelta, "values") && Array.isArray(crListDelta.values) && crListDelta.values.length === 1 && (!Object.hasOwn(crListDelta, "tombstones") || Array.isArray(crListDelta.tombstones) && crListDelta.tombstones.length === 0)) {
@@ -542,11 +594,13 @@ function __merge(crListReplica, crListDelta) {
542
594
  if (valueEntry.predecessor !== "\0" && !isUuidV73(valueEntry.predecessor))
543
595
  continue;
544
596
  if (existingEntry.predecessor >= valueEntry.predecessor) continue;
597
+ const previousPredecessor = existingEntry.predecessor;
545
598
  void moveEntryToPredecessor(
546
599
  crListReplica,
547
600
  existingEntry,
548
601
  valueEntry.predecessor
549
602
  );
603
+ void reparentedVals.push({ entry: existingEntry, previousPredecessor });
550
604
  needsRelink = true;
551
605
  continue;
552
606
  }
@@ -580,7 +634,9 @@ function __merge(crListReplica, crListDelta) {
580
634
  }
581
635
  }
582
636
  if (needsRelink) {
583
- void rebuildLiveProjection(crListReplica);
637
+ if (!trySpliceInsertedParent(crListReplica, newVals, reparentedVals)) {
638
+ void rebuildLiveProjection(crListReplica);
639
+ }
584
640
  }
585
641
  if (newTombsIndices.length === 0 && newVals.length === 0) return false;
586
642
  for (const index of newTombsIndices) {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/.helpers/rebuildLiveIndex/index.ts","../src/.errors/class.ts","../src/.helpers/seekCursorToIndex/index.ts","../src/.helpers/linkEntryBetween/index.ts","../src/.helpers/rebuildLiveProjection/index.ts","../src/.helpers/materializeSnapshotEntry/index.ts","../src/.helpers/attachEntryToIndexes/index.ts","../src/.helpers/detachEntryFromIndexes/index.ts","../src/.helpers/deleteLiveEntry/index.ts","../src/.helpers/dispatchCRListEvent/index.ts","../src/.helpers/moveEntryToPredecessor/index.ts","../src/.helpers/indexFromPropertyKey/index.ts","../src/core/crud/create/index.ts","../src/core/crud/read/index.ts","../src/core/crud/update/index.ts","../src/core/crud/delete/index.ts","../src/core/mags/merge/index.ts","../src/core/mags/acknowledge/index.ts","../src/core/mags/garbageCollect/index.ts","../src/core/mags/snapshot/index.ts","../src/CRList/class.ts"],"sourcesContent":["import type { CRListState } from '../../.types/index.js'\n\n/**\n * Rebuilds the opportunistic index cache from the current live projection.\n */\nexport function rebuildLiveIndex<T>(crListReplica: CRListState<T>): void {\n if (!crListReplica.cursor) {\n crListReplica.index?.clear()\n crListReplica.cursorIndex = undefined\n return\n }\n let index = crListReplica.size\n const entries = crListReplica.index ?? new Map()\n void entries.clear()\n while (crListReplica.cursor.next)\n crListReplica.cursor = crListReplica.cursor.next\n\n while (index >= 1) {\n index--\n crListReplica.cursor.index = index\n void entries.set(index, crListReplica.cursor)\n if (crListReplica.cursor.prev === undefined) break\n crListReplica.cursor = crListReplica.cursor.prev\n }\n crListReplica.index = entries\n crListReplica.cursorIndex = 0\n}\n","/**\n * Error codes thrown by {@link CRList}.\n */\nexport type CRListErrorCode =\n | 'VALUE_NOT_CLONEABLE'\n | 'INDEX_OUT_OF_BOUNDS'\n | 'LIST_EMPTY'\n | 'LIST_INTEGRITY_VIOLATION'\n | 'UPDATE_EXPECTED_AN_ARRAY'\n\n/**\n * Represents a typed CRList runtime error.\n */\nexport class CRListError extends Error {\n /**\n * The semantic error code for the failure.\n */\n readonly code: CRListErrorCode\n\n /**\n * Creates a typed CRList error.\n *\n * @param code - The semantic error code.\n * @param message - An optional human-readable detail message.\n */\n constructor(code: CRListErrorCode, message?: string) {\n const detail = message ?? code\n super(`{@sovereignbase/convergent-replicated-list} ${detail}`)\n this.code = code\n this.name = 'CRListError'\n }\n}\n","import type { CRListState } from '../../.types/index.js'\nimport { CRListError } from '../../.errors/class.js'\n\n/**\n * Moves the replica cursor to a live index.\n *\n * A valid cached index entry is used directly. Stale cache entries are dropped\n * and the cursor walks from its current position, then repairs the cache at the\n * requested index.\n */\nexport function seekCursorToIndex<T>(\n targetIndex: number,\n crListReplica: CRListState<T>\n): void {\n if (targetIndex < 0 || targetIndex >= crListReplica.size)\n throw new CRListError('INDEX_OUT_OF_BOUNDS', 'Index out of bounds')\n const indexedEntry = crListReplica.index?.get(targetIndex)\n if (indexedEntry) {\n if (crListReplica.parentMap.get(indexedEntry.uuidv7) === indexedEntry) {\n crListReplica.cursor = indexedEntry\n crListReplica.cursorIndex = targetIndex\n return\n } else {\n void crListReplica.index?.delete(targetIndex)\n }\n }\n if (!crListReplica.cursor)\n throw new CRListError('LIST_EMPTY', 'List is empty')\n let cursorIndex = crListReplica.cursorIndex ?? crListReplica.cursor.index\n const direction = cursorIndex > targetIndex ? 'prev' : 'next'\n while (crListReplica.cursor && cursorIndex !== targetIndex) {\n crListReplica.cursor = crListReplica.cursor[direction]\n cursorIndex += direction === 'next' ? 1 : -1\n }\n if (crListReplica.cursor) {\n crListReplica.cursorIndex = targetIndex\n void crListReplica.index?.set(targetIndex, crListReplica.cursor)\n }\n}\n","import type { CRListStateEntry } from '../../.types/index.js'\n\n/**\n * Links a live entry between optional neighboring projection entries.\n */\nexport function linkEntryBetween<T>(\n prev: CRListStateEntry<T>,\n linkedListEntry: NonNullable<CRListStateEntry<T>>,\n next: CRListStateEntry<T>\n): void {\n linkedListEntry.prev = prev\n linkedListEntry.next = next\n if (prev) prev.next = linkedListEntry\n if (next) next.prev = linkedListEntry\n}\n","import type { CRListState, CRListStateEntry } from '../../.types/index.js'\nimport { linkEntryBetween } from '../linkEntryBetween/index.js'\n\n/**\n * Rebuilds the live linked-list projection and index from predecessor buckets.\n *\n * Sibling order is deterministic by UUIDv7, which keeps replicas convergent even\n * when deltas arrive in different orders.\n */\nexport function rebuildLiveProjection<T>(crListReplica: CRListState<T>) {\n crListReplica.cursor = undefined\n const entries = crListReplica.index ?? new Map()\n void entries.clear()\n for (const entry of crListReplica.parentMap.values()) {\n if (!entry) continue\n entry.prev = undefined\n entry.next = undefined\n }\n let previous: CRListStateEntry<T> = undefined\n let first: CRListStateEntry<T> = undefined\n let index = 0\n const appendChildren = (predecessorIdentifier: string): void => {\n const siblings = crListReplica.childrenMap.get(predecessorIdentifier)\n if (!siblings) return\n if (siblings.length > 1)\n void siblings.sort((a, b) => (a.uuidv7 > b.uuidv7 ? 1 : -1))\n\n for (const sibling of siblings) {\n if (!sibling || crListReplica.parentMap.get(sibling.uuidv7) !== sibling)\n continue\n sibling.index = index\n index++\n void linkEntryBetween<T>(previous, sibling, undefined)\n if (!first) first = sibling\n previous = sibling\n void appendChildren(sibling.uuidv7)\n }\n }\n void appendChildren('\\0')\n const detachedPredecessors: Array<string> = []\n for (const predecessorIdentifier of crListReplica.childrenMap.keys()) {\n if (\n predecessorIdentifier !== '\\0' &&\n !crListReplica.parentMap.get(predecessorIdentifier)\n )\n void detachedPredecessors.push(predecessorIdentifier)\n }\n if (detachedPredecessors.length > 1)\n detachedPredecessors.sort((a, b) => (a > b ? 1 : -1))\n for (const predecessorIdentifier of detachedPredecessors)\n void appendChildren(predecessorIdentifier)\n crListReplica.cursor = first\n crListReplica.cursorIndex = first ? 0 : undefined\n if (first) void entries.set(0, first)\n crListReplica.index = entries\n crListReplica.size = crListReplica.parentMap.size\n}\n","import type {\n CRListState,\n CRListSnapshotEntry,\n CRListStateEntry,\n} from '../../.types/index.js'\nimport { isUuidV7 } from '@sovereignbase/utils'\n\n/**\n * Converts a snapshot or delta value entry into local mutable entry state.\n *\n * Invalid, deleted, duplicate, or currently unanchored entries are ignored.\n * Payload values are kept by reference.\n */\nexport function materializeSnapshotEntry<T>(\n valueEntry: CRListSnapshotEntry<T>,\n crListReplica: CRListState<T>\n): CRListStateEntry<T> {\n if (valueEntry === null || valueEntry === undefined) return undefined\n if (\n !isUuidV7(valueEntry.uuidv7) ||\n crListReplica.tombstones.has(valueEntry.uuidv7) ||\n crListReplica.parentMap.has(valueEntry.uuidv7) ||\n (!isUuidV7(valueEntry.predecessor) &&\n valueEntry.predecessor !== '\\0' &&\n !crListReplica.tombstones.has(valueEntry.predecessor))\n )\n return undefined\n\n return {\n uuidv7: valueEntry.uuidv7,\n value: valueEntry.value,\n predecessor: valueEntry.predecessor,\n index: 0,\n next: undefined,\n prev: undefined,\n }\n}\n","import type {\n CRListState,\n CRListStateEntry,\n CRListDelta,\n} from '../../.types/index.js'\n\n/**\n * Attaches a live entry to UUID and predecessor indexes.\n *\n * When a delta buffer is provided, the same live payload reference is appended\n * to the outgoing delta.\n */\nexport function attachEntryToIndexes<T>(\n crListReplica: CRListState<T>,\n linkedListEntry: NonNullable<CRListStateEntry<T>>,\n deltaBuf?: CRListDelta<T>\n): void {\n void crListReplica.parentMap.set(linkedListEntry.uuidv7, linkedListEntry)\n const siblings = crListReplica.childrenMap.get(linkedListEntry.predecessor)\n if (siblings) {\n void siblings.push(linkedListEntry)\n } else {\n void crListReplica.childrenMap.set(linkedListEntry.predecessor, [\n linkedListEntry,\n ])\n }\n if (deltaBuf && !Array.isArray(deltaBuf.values)) deltaBuf.values = []\n if (deltaBuf?.values)\n void deltaBuf.values.push({\n uuidv7: linkedListEntry.uuidv7,\n value: linkedListEntry.value,\n predecessor: linkedListEntry.predecessor,\n })\n}\n","import type { CRListState, CRListStateEntry } from '../../.types/index.js'\n\n/**\n * Removes a live entry from UUID and predecessor indexes.\n */\nexport function detachEntryFromIndexes<T>(\n crListReplica: CRListState<T>,\n linkedListEntry: NonNullable<CRListStateEntry<T>>\n): void {\n void crListReplica.parentMap.delete(linkedListEntry.uuidv7)\n const siblings = crListReplica.childrenMap.get(linkedListEntry.predecessor)\n if (!siblings) return\n const index = siblings.indexOf(linkedListEntry)\n if (index !== -1) void siblings.splice(index, 1)\n}\n","import type {\n CRListDelta,\n CRListState,\n CRListStateEntry,\n} from '../../.types/index.js'\nimport { detachEntryFromIndexes } from '../detachEntryFromIndexes/index.js'\n\n/**\n * Tombstones a live entry and unlinks it from the local projection.\n */\nexport function deleteLiveEntry<T>(\n crListReplica: CRListState<T>,\n linkedListEntry: NonNullable<CRListStateEntry<T>>,\n deltaBuf?: CRListDelta<T>\n): void {\n const prev = linkedListEntry.prev\n const next = linkedListEntry.next\n void crListReplica.tombstones.add(linkedListEntry.uuidv7)\n if (deltaBuf && !Array.isArray(deltaBuf.tombstones)) deltaBuf.tombstones = []\n void deltaBuf?.tombstones?.push(linkedListEntry.uuidv7)\n if (prev) prev.next = next\n if (next) {\n next.prev = prev\n }\n void detachEntryFromIndexes<T>(crListReplica, linkedListEntry)\n if (crListReplica.cursor === linkedListEntry)\n crListReplica.cursor = next ?? prev\n if (!crListReplica.cursor) crListReplica.cursorIndex = undefined\n linkedListEntry.prev = undefined\n linkedListEntry.next = undefined\n crListReplica.size = crListReplica.parentMap.size\n}\n","import type { CRListEventMap } from '../../.types/index.js'\n\n/**\n * Dispatches a typed CRList event payload through an EventTarget.\n */\nexport function dispatchCRListEvent<T, K extends keyof CRListEventMap<T>>(\n eventTarget: EventTarget,\n type: K,\n detail: CRListEventMap<T>[K]\n): void {\n void eventTarget.dispatchEvent(new CustomEvent(type, { detail }))\n}\n","import type {\n CRListDelta,\n CRListState,\n CRListStateEntry,\n} from '../../.types/index.js'\nimport { detachEntryFromIndexes } from '../detachEntryFromIndexes/index.js'\nimport { attachEntryToIndexes } from '../attachEntryToIndexes/index.js'\n\n/**\n * Reattaches an existing live entry to a newer stable predecessor.\n */\nexport function moveEntryToPredecessor<T>(\n crListReplica: CRListState<T>,\n linkedListEntry: NonNullable<CRListStateEntry<T>>,\n predecessor: string,\n deltaBuf?: CRListDelta<T>\n): void {\n void detachEntryFromIndexes<T>(crListReplica, linkedListEntry)\n linkedListEntry.predecessor = predecessor\n void attachEntryToIndexes<T>(crListReplica, linkedListEntry, deltaBuf)\n}\n","/**\n * Parses a JavaScript property key as a safe non-negative list index.\n */\nexport function indexFromPropertyKey(\n index: string | symbol\n): number | undefined {\n if (typeof index !== 'string' || !/^(0|[1-9]\\d*)$/.test(index))\n return undefined\n const listIndex = Number(index)\n return Number.isSafeInteger(listIndex) ? listIndex : undefined\n}\n","import { isUuidV7, prototype } from '@sovereignbase/utils'\nimport {\n CRListSnapshot,\n CRListState,\n CRListStateEntry,\n} from '../../../.types/index.js'\nimport {\n rebuildLiveProjection,\n materializeSnapshotEntry,\n attachEntryToIndexes,\n linkEntryBetween,\n} from '../../../.helpers/index.js'\n\n/**\n * Creates a local CRList replica from an optional snapshot.\n *\n * Invalid snapshot records are ignored. Accepted values are kept by reference,\n * indexed by UUIDv7, linked through their predecessor buckets, and exposed as a\n * live doubly-linked list projection.\n *\n * @param snapshot - Optional CRList snapshot.\n * @returns - A hydrated CRList replica.\n *\n * Time complexity: O(n log n + t), worst case O(n^2 + t)\n * - n = snapshot value entry count\n * - t = snapshot tombstone count\n *\n * Space complexity: O(n + t)\n */\nexport function __create<T>(snapshot?: CRListSnapshot<T>): CRListState<T> {\n const crListReplica: CRListState<T> = {\n size: 0,\n cursor: undefined,\n cursorIndex: undefined,\n index: new Map(),\n tombstones: new Set<string>(),\n parentMap: new Map<string, NonNullable<CRListStateEntry<T>>>(),\n childrenMap: new Map<string, Array<NonNullable<CRListStateEntry<T>>>>(),\n }\n if (!snapshot || prototype(snapshot) !== 'record') return crListReplica\n\n /** Hydrate tombstone entries. */\n if (\n Object.hasOwn(snapshot, 'tombstones') &&\n Array.isArray(snapshot.tombstones)\n ) {\n for (const tombstone of snapshot.tombstones) {\n if (crListReplica.tombstones.has(tombstone) || !isUuidV7(tombstone))\n continue\n void crListReplica.tombstones.add(tombstone)\n }\n }\n\n /** Hydrate value entries. */\n if (!Object.hasOwn(snapshot, 'values') || !Array.isArray(snapshot.values))\n return crListReplica\n // Build predecessor tree.\n let canUseLinearProjection = true\n let previous: CRListStateEntry<T> = undefined\n for (const valueEntry of snapshot.values) {\n const linkedListEntry = materializeSnapshotEntry<T>(\n valueEntry,\n crListReplica\n )\n if (!linkedListEntry) continue\n void attachEntryToIndexes<T>(crListReplica, linkedListEntry)\n if (\n canUseLinearProjection &&\n linkedListEntry.predecessor === (previous?.uuidv7 ?? '\\0')\n ) {\n linkedListEntry.index = crListReplica.parentMap.size - 1\n void linkEntryBetween<T>(previous, linkedListEntry, undefined)\n previous = linkedListEntry\n void crListReplica.index?.set(linkedListEntry.index, linkedListEntry)\n continue\n }\n canUseLinearProjection = false\n }\n if (canUseLinearProjection) {\n crListReplica.cursor = previous\n crListReplica.cursorIndex = previous\n ? crListReplica.parentMap.size - 1\n : undefined\n crListReplica.size = crListReplica.parentMap.size\n return crListReplica\n }\n // Flatten tree into a doubly linked list and write live-view indexes.\n void rebuildLiveProjection<T>(crListReplica)\n\n return crListReplica\n}\n","import { seekCursorToIndex } from '../../../.helpers/index.js'\nimport { CRListState } from '../../../.types/index.js'\n\n/**\n * Reads the value at an index in the replica live view.\n *\n * The replica cursor is moved as part of the lookup. Successful reads return\n * the live value reference stored by the replica. Mutating that value directly\n * can mutate replica state and should only be done when the caller owns an\n * independent value object. Out-of-bounds and empty list reads resolve to\n * `undefined` instead of throwing.\n *\n * @param targetIndex - Index in the live list.\n * @param crListReplica - Replica to read from.\n * @returns - The live value at `targetIndex`, or `undefined` when\n * no value is present.\n *\n * Time complexity: O(d), worst case O(n)\n * - d = distance from cursor to target index\n * - n = list size\n *\n * Space complexity: O(1)\n */\nexport function __read<T>(\n targetIndex: number,\n crListReplica: CRListState<T>\n): T | undefined {\n try {\n void seekCursorToIndex<T>(targetIndex, crListReplica)\n return crListReplica.cursor?.value\n } catch {\n return undefined\n }\n}\n","import { CRListError } from '../../../.errors/class.js'\nimport {\n attachEntryToIndexes,\n detachEntryFromIndexes,\n seekCursorToIndex,\n moveEntryToPredecessor,\n linkEntryBetween,\n} from '../../../.helpers/index.js'\nimport { v7 as uuidv7 } from 'uuid'\nimport {\n CRListChange,\n CRListDelta,\n CRListState,\n CRListStateEntry,\n} from '../../../.types/index.js'\n/**\n * Applies a local value mutation to the replica live view.\n *\n * The update can replace a range starting at the target entry, insert values\n * before it, or insert values after it. The returned delta is suitable for\n * gossip and the returned change describes the local live-view patch.\n *\n * @param listIndex - Target index in the live list.\n * @param listValues - Values to insert or overwrite.\n * @param crListReplica - Replica to mutate.\n * @param mode - Mutation mode relative to `listIndex`.\n * @returns - A local change and gossip delta, or `false` if no mutation occurred.\n *\n * Time complexity: O(d + v + r + vk), worst case O(vn)\n * - d = distance from cursor to target index\n * - v = amount of input values\n * - r = amount of nodes after inserted values whose indexes must be shifted\n * - k = sibling bucket size when predecessor bucket is updated\n *\n * Space complexity: O(v)\n */\nexport function __update<T>(\n listIndex: number,\n listValues: Array<T>,\n crListReplica: CRListState<T>,\n mode: 'overwrite' | 'before' | 'after'\n): { change: CRListChange<T>; delta: CRListDelta<T> } | false {\n if (listIndex < 0 || listIndex > crListReplica.size)\n throw new CRListError('INDEX_OUT_OF_BOUNDS')\n if (!Array.isArray(listValues))\n throw new CRListError(\n 'UPDATE_EXPECTED_AN_ARRAY',\n '`listValues` must be an Array'\n )\n if (listValues.length === 0) return false\n const change: CRListChange<T> = {}\n const delta: CRListDelta<T> = { values: [], tombstones: [] }\n for (const listValue of listValues) {\n const v7 = uuidv7()\n\n const linkedListEntry: NonNullable<CRListStateEntry<T>> = {\n uuidv7: v7,\n value: listValue,\n predecessor: '\\0',\n index: 0,\n next: undefined,\n prev: undefined,\n }\n\n switch (mode) {\n case 'overwrite': {\n if (listIndex === crListReplica.size) {\n if (crListReplica.size === 0) {\n crListReplica.cursor = linkedListEntry\n crListReplica.cursorIndex = linkedListEntry.index\n void attachEntryToIndexes<T>(crListReplica, linkedListEntry, delta)\n crListReplica.index?.set(linkedListEntry.index, linkedListEntry)\n change[linkedListEntry.index] = linkedListEntry.value\n break\n }\n void seekCursorToIndex<T>(crListReplica.size - 1, crListReplica)\n if (!crListReplica.cursor) return false\n linkedListEntry.index = (crListReplica.cursorIndex ?? 0) + 1\n linkedListEntry.predecessor = crListReplica.cursor.uuidv7\n void linkEntryBetween<T>(\n crListReplica.cursor,\n linkedListEntry,\n undefined\n )\n void attachEntryToIndexes<T>(crListReplica, linkedListEntry, delta)\n crListReplica.cursor = linkedListEntry\n crListReplica.cursorIndex = linkedListEntry.index\n void crListReplica.index?.set(linkedListEntry.index, linkedListEntry)\n change[linkedListEntry.index] = linkedListEntry.value\n break\n }\n void seekCursorToIndex<T>(listIndex, crListReplica)\n if (!crListReplica.cursor) return false\n const entryToOverwrite = crListReplica.cursor\n const actualIndex = crListReplica.cursorIndex ?? listIndex\n\n linkedListEntry.predecessor = entryToOverwrite.predecessor\n linkedListEntry.index = actualIndex\n void linkEntryBetween<T>(\n entryToOverwrite.prev,\n linkedListEntry,\n entryToOverwrite.next\n )\n if (entryToOverwrite.next) {\n if (entryToOverwrite.next.predecessor === entryToOverwrite.uuidv7) {\n void moveEntryToPredecessor<T>(\n crListReplica,\n entryToOverwrite.next,\n linkedListEntry.uuidv7,\n delta\n )\n }\n }\n void attachEntryToIndexes<T>(crListReplica, linkedListEntry, delta)\n void crListReplica.tombstones.add(entryToOverwrite.uuidv7)\n void delta.tombstones?.push(entryToOverwrite.uuidv7)\n void detachEntryFromIndexes<T>(crListReplica, entryToOverwrite)\n entryToOverwrite.next = undefined\n entryToOverwrite.prev = undefined\n crListReplica.cursor = linkedListEntry\n crListReplica.cursorIndex = actualIndex\n void crListReplica.index?.set(linkedListEntry.index, linkedListEntry)\n change[actualIndex] = linkedListEntry.value\n break\n }\n case 'after': {\n if (crListReplica.size === 0 && listIndex === 0) {\n crListReplica.cursor = linkedListEntry\n crListReplica.cursorIndex = linkedListEntry.index\n void attachEntryToIndexes<T>(crListReplica, linkedListEntry, delta)\n void crListReplica.index?.set(linkedListEntry.index, linkedListEntry)\n change[linkedListEntry.index] = linkedListEntry.value\n break\n }\n if (listIndex === crListReplica.size) {\n void seekCursorToIndex<T>(crListReplica.size - 1, crListReplica)\n } else {\n void seekCursorToIndex<T>(listIndex, crListReplica)\n }\n if (!crListReplica.cursor) return false\n const actualIndex = crListReplica.cursorIndex ?? listIndex\n const next =\n listIndex === crListReplica.size\n ? undefined\n : crListReplica.cursor.next\n linkedListEntry.index = actualIndex + 1\n linkedListEntry.predecessor = crListReplica.cursor.uuidv7\n void linkEntryBetween<T>(crListReplica.cursor, linkedListEntry, next)\n if (next) {\n if (next.predecessor === crListReplica.cursor.uuidv7) {\n void moveEntryToPredecessor<T>(\n crListReplica,\n next,\n linkedListEntry.uuidv7,\n delta\n )\n }\n }\n void attachEntryToIndexes<T>(crListReplica, linkedListEntry, delta)\n crListReplica.cursor = linkedListEntry\n crListReplica.cursorIndex = linkedListEntry.index\n if (next) crListReplica.index = new Map()\n void crListReplica.index?.set(linkedListEntry.index, linkedListEntry)\n change[linkedListEntry.index] = linkedListEntry.value\n break\n }\n case 'before': {\n if (crListReplica.size === 0 && listIndex === 0) {\n crListReplica.cursor = linkedListEntry\n crListReplica.cursorIndex = linkedListEntry.index\n void attachEntryToIndexes<T>(crListReplica, linkedListEntry, delta)\n void crListReplica.index?.set(linkedListEntry.index, linkedListEntry)\n change[linkedListEntry.index] = linkedListEntry.value\n mode = 'after'\n listIndex = linkedListEntry.index - 1\n break\n }\n void seekCursorToIndex<T>(listIndex, crListReplica)\n if (!crListReplica.cursor) return false\n const actualIndex = crListReplica.cursorIndex ?? listIndex\n const prev = crListReplica.cursor.prev\n linkedListEntry.index = actualIndex\n linkedListEntry.predecessor = prev?.uuidv7 ?? '\\0'\n void linkEntryBetween<T>(prev, linkedListEntry, crListReplica.cursor)\n if (crListReplica.cursor.predecessor === linkedListEntry.predecessor) {\n void moveEntryToPredecessor<T>(\n crListReplica,\n crListReplica.cursor,\n linkedListEntry.uuidv7,\n delta\n )\n }\n void attachEntryToIndexes<T>(crListReplica, linkedListEntry, delta)\n crListReplica.cursor = linkedListEntry\n crListReplica.cursorIndex = actualIndex\n crListReplica.index = new Map()\n void crListReplica.index?.set(linkedListEntry.index, linkedListEntry)\n change[actualIndex] = linkedListEntry.value\n mode = 'after'\n listIndex = linkedListEntry.index - 1\n\n break\n }\n }\n crListReplica.size = crListReplica.parentMap.size\n listIndex++\n }\n return { change, delta }\n}\n","import { deleteLiveEntry, seekCursorToIndex } from '../../../.helpers/index.js'\nimport { CRListError } from '../../../.errors/class.js'\nimport type {\n CRListChange,\n CRListDelta,\n CRListState,\n CRListStateEntry,\n} from '../../../.types/index.js'\n\n/**\n * Deletes a range from the replica live view.\n *\n * With no indexes, the full list is deleted. With only `startIndex`, all entries\n * from `startIndex` onward are deleted. With both indexes, the deleted range is\n * `[startIndex, endIndex)`.\n *\n * @param crListReplica - Replica to mutate.\n * @param startIndex - Inclusive start index. Defaults to `0`.\n * @param endIndex - Exclusive end index. Defaults to the current list size.\n * @returns - A local change and gossip delta, or `false` if nothing was deleted.\n *\n * Time complexity: O(d + qk + r), worst case O(n^2)\n * - d = distance from cursor to target index\n * - q = amount of deleted nodes\n * - r = amount of nodes after the deleted range whose indexes must be shifted\n * - k = sibling bucket size when deleted entries are removed from buckets\n *\n * Space complexity: O(q)\n */\nexport function __delete<T>(\n crListReplica: CRListState<T>,\n startIndex?: number,\n endIndex?: number\n): { change: CRListChange<T>; delta: CRListDelta<T> } | false {\n const change: CRListChange<T> = {}\n const delta: CRListDelta<T> = { values: [], tombstones: [] }\n const listIndex = startIndex ?? 0\n const targetEndIndex = endIndex ?? crListReplica.size\n if (\n listIndex < 0 ||\n targetEndIndex < listIndex ||\n listIndex > crListReplica.size\n )\n throw new CRListError('INDEX_OUT_OF_BOUNDS')\n const deleteCount = Math.min(targetEndIndex, crListReplica.size) - listIndex\n if (deleteCount <= 0) return false\n\n void seekCursorToIndex<T>(listIndex, crListReplica)\n if (!crListReplica.cursor) return false\n\n let current: CRListStateEntry<T> = crListReplica.cursor\n let deleted = 0\n let currentIndex = crListReplica.cursorIndex ?? listIndex\n\n while (current && deleted < deleteCount) {\n const next: CRListStateEntry<T> = current.next\n change[currentIndex] = undefined\n void crListReplica.index?.delete(currentIndex)\n void deleteLiveEntry<T>(crListReplica, current, delta)\n current = next\n currentIndex++\n deleted++\n }\n\n crListReplica.size = crListReplica.parentMap.size\n crListReplica.cursor = current ?? crListReplica.cursor\n crListReplica.cursorIndex = current\n ? listIndex\n : crListReplica.cursor\n ? Math.max(0, crListReplica.size - 1)\n : undefined\n crListReplica.index = new Map()\n if (crListReplica.cursor && crListReplica.cursorIndex !== undefined)\n void crListReplica.index.set(\n crListReplica.cursorIndex,\n crListReplica.cursor\n )\n\n return { change, delta }\n}\n","import type {\n CRListChange,\n CRListDelta,\n CRListState,\n CRListStateEntry,\n} from '../../../.types/index.js'\nimport {\n materializeSnapshotEntry,\n attachEntryToIndexes,\n rebuildLiveProjection,\n rebuildLiveIndex,\n deleteLiveEntry,\n moveEntryToPredecessor,\n} from '../../../.helpers/index.js'\nimport { prototype, isUuidV7 } from '@sovereignbase/utils'\n\n/**\n * Merges a remote CRList delta into the local replica.\n *\n * Accepted tombstones update the local live view and accepted values are attached\n * to the predecessor tree. Tail-append deltas are linked incrementally; deltas\n * that can affect ordering fall back to deterministic relinking.\n *\n * @param crListReplica - Replica to mutate.\n * @param crListDelta - Remote gossip delta.\n * @returns - A minimal local change patch, or `false` when the delta is ignored.\n *\n * Time complexity: O(v + t) for tail-append deltas; O(n + t + qk) for tombstone-only deletes; otherwise O(n log n + v + t + m*k)\n * Worst case: O(n^2 + (v + t)n)\n * - n = replica value entry count after merge\n * - v = delta value entry count\n * - t = delta tombstone count\n * - q = amount of live entries deleted by tombstones\n * - m = entries moved between predecessor buckets\n * - k = sibling bucket size when entries are removed from buckets\n *\n * Space complexity: O(n + v + t)\n */\nexport function __merge<T>(\n crListReplica: CRListState<T>,\n crListDelta: CRListDelta<T>\n): CRListChange<T> | false {\n if (!crListDelta || prototype(crListDelta) !== 'record') return false\n const newVals: Array<NonNullable<CRListStateEntry<T>>> = []\n const newTombsIndices: Array<number> = []\n const change: CRListChange<T> = {}\n let needsRelink = false\n if (\n Object.hasOwn(crListDelta, 'values') &&\n Array.isArray(crListDelta.values) &&\n crListDelta.values.length === 1 &&\n (!Object.hasOwn(crListDelta, 'tombstones') ||\n (Array.isArray(crListDelta.tombstones) &&\n crListDelta.tombstones.length === 0))\n ) {\n const linkedListEntry = materializeSnapshotEntry<T>(\n crListDelta.values[0],\n crListReplica\n )\n if (!linkedListEntry) return false\n const predecessor =\n linkedListEntry.predecessor === '\\0'\n ? undefined\n : crListReplica.parentMap.get(linkedListEntry.predecessor)\n if (\n (linkedListEntry.predecessor === '\\0' && crListReplica.size === 0) ||\n (predecessor && !predecessor.next)\n ) {\n linkedListEntry.prev = predecessor\n linkedListEntry.index = crListReplica.size\n if (predecessor) predecessor.next = linkedListEntry\n crListReplica.cursor = linkedListEntry\n crListReplica.cursorIndex = linkedListEntry.index\n void attachEntryToIndexes<T>(crListReplica, linkedListEntry)\n crListReplica.size = crListReplica.parentMap.size\n void crListReplica.index?.set(linkedListEntry.index, linkedListEntry)\n return { [linkedListEntry.index]: linkedListEntry.value }\n }\n }\n\n /** Apply tombstone entries. */\n if (\n Object.hasOwn(crListDelta, 'tombstones') &&\n Array.isArray(crListDelta.tombstones)\n ) {\n for (const tombstone of crListDelta.tombstones) {\n if (crListReplica.tombstones.has(tombstone) || !isUuidV7(tombstone))\n continue\n void crListReplica.tombstones.add(tombstone)\n const linkedListEntry = crListReplica.parentMap.get(tombstone)\n if (linkedListEntry) {\n void newTombsIndices.push(linkedListEntry.index)\n void crListReplica.index?.delete(linkedListEntry.index)\n void deleteLiveEntry<T>(crListReplica, linkedListEntry)\n needsRelink = true\n }\n }\n }\n\n /** Apply value entries. */\n if (\n !Object.hasOwn(crListDelta, 'values') ||\n !Array.isArray(crListDelta.values)\n ) {\n if (newTombsIndices.length === 0) return false\n void rebuildLiveIndex<T>(crListReplica)\n for (const index of newTombsIndices) {\n change[index] = undefined\n }\n return change\n }\n // Attach accepted values to the predecessor tree.\n for (const valueEntry of crListDelta.values) {\n if (valueEntry === null || valueEntry === undefined) continue\n const existingEntry = crListReplica.parentMap.get(valueEntry.uuidv7)\n if (existingEntry) {\n if (crListReplica.tombstones.has(valueEntry.uuidv7)) continue\n if (valueEntry.predecessor !== '\\0' && !isUuidV7(valueEntry.predecessor))\n continue\n if (existingEntry.predecessor >= valueEntry.predecessor) continue\n void moveEntryToPredecessor<T>(\n crListReplica,\n existingEntry,\n valueEntry.predecessor\n )\n needsRelink = true\n continue\n }\n const linkedListEntry = materializeSnapshotEntry<T>(\n valueEntry,\n crListReplica\n )\n if (!linkedListEntry) continue\n const predecessor =\n linkedListEntry.predecessor === '\\0'\n ? undefined\n : crListReplica.parentMap.get(linkedListEntry.predecessor)\n void attachEntryToIndexes<T>(crListReplica, linkedListEntry)\n void newVals.push(linkedListEntry)\n if (!needsRelink && linkedListEntry.predecessor === '\\0') {\n if (crListReplica.size === 0) {\n crListReplica.cursor = linkedListEntry\n crListReplica.cursorIndex = linkedListEntry.index\n crListReplica.size = crListReplica.parentMap.size\n void crListReplica.index?.set(linkedListEntry.index, linkedListEntry)\n } else {\n needsRelink = true\n }\n } else if (!needsRelink && predecessor && !predecessor.next) {\n linkedListEntry.prev = predecessor\n linkedListEntry.index = crListReplica.size\n predecessor.next = linkedListEntry\n crListReplica.cursor = linkedListEntry\n crListReplica.cursorIndex = linkedListEntry.index\n crListReplica.size = crListReplica.parentMap.size\n void crListReplica.index?.set(linkedListEntry.index, linkedListEntry)\n } else {\n needsRelink = true\n }\n }\n if (needsRelink) {\n // Flatten tree into a doubly linked list and write live-view indexes.\n void rebuildLiveProjection<T>(crListReplica)\n }\n\n if (newTombsIndices.length === 0 && newVals.length === 0) return false\n\n for (const index of newTombsIndices) {\n change[index] = undefined\n }\n for (const val of newVals) {\n change[val.index] = val.value\n }\n\n return change\n}\n","import type { CRListAck, CRListState } from '../../../.types/index.js'\n\n/**\n * Returns the replica tombstone acknowledgement frontier.\n *\n * The frontier is the greatest tombstone identifier currently retained by the\n * replica. Peers can use it as input for tombstone garbage collection.\n *\n * @param crListReplica - Replica to acknowledge.\n * @returns - The acknowledgement frontier, or `false` when there are no tombstones.\n *\n * Time complexity: O(t)\n * - t = replica tombstone count\n *\n * Space complexity: O(1)\n */\nexport function __acknowledge<T>(\n crListReplica: CRListState<T>\n): CRListAck | false {\n let largest: CRListAck | false = false\n void crListReplica.tombstones.forEach((tombstone) => {\n if (largest === false || largest < tombstone) largest = tombstone\n })\n if (typeof largest === 'string') return largest\n return false\n}\n","import { isUuidV7 } from '@sovereignbase/utils'\nimport { CRListAck, CRListState } from '../../../.types/index.js'\n\n/**\n * Removes tombstones acknowledged by all supplied frontiers.\n *\n * The smallest valid UUIDv7 frontier is used as the safe collection boundary.\n * Tombstones less than or equal to that boundary are removed from the local\n * replica.\n *\n * @param frontiers - Acknowledgement frontiers received from peers.\n * @param crListReplica - Replica whose tombstones will be collected.\n *\n * Time complexity: O(f log f + t)\n * - f = frontier count\n * - t = replica tombstone count\n *\n * Space complexity: O(1)\n */\nexport function __garbageCollect<T>(\n frontiers: Array<CRListAck>,\n crListReplica: CRListState<T>\n): void {\n if (!Array.isArray(frontiers)) return\n void frontiers.sort()\n const smallest = frontiers.find((frontier) => isUuidV7(frontier))\n if (typeof smallest !== 'string') return\n void crListReplica.tombstones.forEach((tombstone, __, tombstones) => {\n if (tombstone <= smallest) {\n void tombstones.delete(tombstone)\n }\n })\n}\n","import { CRListError } from '../../../.errors/class.js'\nimport { CRListState, CRListSnapshot } from '../../../.types/index.js'\n\n/**\n * Creates a full CRList snapshot from the current replica state.\n *\n * The snapshot contains every live value entry and all retained tombstones. Value\n * payloads are live references, so callers must not mutate snapshot values\n * unless they have first isolated them from replica state.\n *\n * @param crListReplica - Replica to snapshot.\n * @returns - A full snapshot suitable for hydration or transport.\n *\n * Time complexity: O(n + t)\n * - n = replica value entry count\n * - t = replica tombstone count\n *\n * Space complexity: O(n + t)\n */\nexport function __snapshot<T>(\n crListReplica: CRListState<T>\n): CRListSnapshot<T> {\n return {\n values: Array.from(crListReplica.parentMap.values()).map(\n (linkedListEntry) => {\n if (!linkedListEntry) throw new CRListError('LIST_INTEGRITY_VIOLATION')\n return {\n uuidv7: linkedListEntry.uuidv7,\n value: linkedListEntry.value,\n predecessor: linkedListEntry.predecessor,\n }\n }\n ),\n tombstones: Array.from(crListReplica.tombstones),\n }\n}\n","import { dispatchCRListEvent, indexFromPropertyKey } from '../.helpers/index.js'\nimport { CRListError } from '../.errors/class.js'\nimport type {\n CRListState,\n CRListSnapshot,\n CRListEventListenerFor,\n CRListEventMap,\n CRListDelta,\n CRListAck,\n} from '../.types/index.js'\nimport { __create, __read, __update, __delete } from '../core/crud/index.js'\nimport {\n __merge,\n __acknowledge,\n __garbageCollect,\n __snapshot,\n} from '../core/mags/index.js'\n\n/**\n * A convergent replicated list.\n *\n * Numeric property access reads and mutates the live list projection:\n * `list[0]` reads the live value reference, `list[0] = value` writes an\n * entry, and `delete list[0]` removes one entry. Iteration, `find()`, and\n * `forEach()` expose the same live value references. Mutating returned objects\n * directly can mutate replica state without producing a CRDT delta, so callers\n * must isolate values before out-of-band mutation. Local mutations emit `delta`\n * and `change` events; remote merges emit `change` events.\n *\n * @typeParam T - The value type stored in the list.\n */\nexport class CRList<T> {\n /**\n * Reads or overwrites an entry in the live list projection by index.\n *\n * Reads return live value references.\n */\n [index: number]: T\n declare private readonly state: CRListState<T>\n declare private readonly eventTarget: EventTarget\n\n /**\n * Creates a replicated list from an optional CRList snapshot.\n *\n * @param snapshot - A previously emitted CRList snapshot.\n */\n constructor(snapshot?: CRListSnapshot<T>) {\n void Object.defineProperties(this, {\n state: {\n value: __create<T>(snapshot),\n enumerable: false,\n configurable: false,\n writable: false,\n },\n eventTarget: {\n value: new EventTarget(),\n enumerable: false,\n configurable: false,\n writable: false,\n },\n })\n\n return new Proxy(this, {\n get(target, index, receiver) {\n const listIndex = indexFromPropertyKey(index)\n // Preserve normal property access for non-index keys.\n if (listIndex === undefined) return Reflect.get(target, index, receiver)\n return __read(listIndex, target.state)\n },\n has(target, index) {\n const listIndex = indexFromPropertyKey(index)\n // Preserve normal property checks for non-index keys.\n if (listIndex === undefined) return Reflect.has(target, index)\n return listIndex >= 0 && listIndex < target.state.size\n },\n set(target, index, value) {\n const listIndex = indexFromPropertyKey(index)\n if (listIndex === undefined) return false\n try {\n const result = __update(listIndex, [value], target.state, 'overwrite')\n if (!result) return false\n const { delta, change } = result\n if (delta)\n void dispatchCRListEvent(target.eventTarget, 'delta', delta)\n if (change)\n void dispatchCRListEvent(target.eventTarget, 'change', change)\n return true\n } catch (error) {\n if (error instanceof CRListError) throw error\n return false\n }\n },\n deleteProperty(target, index) {\n const listIndex = indexFromPropertyKey(index)\n if (listIndex === undefined) return false\n try {\n const result = __delete(target.state, listIndex, listIndex + 1)\n if (!result) return false\n const { delta, change } = result\n if (delta)\n void dispatchCRListEvent(target.eventTarget, 'delta', delta)\n if (change)\n void dispatchCRListEvent(target.eventTarget, 'change', change)\n return true\n } catch (error) {\n if (error instanceof CRListError) throw error\n return false\n }\n },\n ownKeys(target) {\n return [\n ...Reflect.ownKeys(target),\n ...Array.from({ length: target.size }, (_, index) => String(index)),\n ]\n },\n\n getOwnPropertyDescriptor(target, index) {\n const listIndex = indexFromPropertyKey(index)\n\n if (listIndex !== undefined && listIndex < target.size) {\n return {\n value: __read(listIndex, target.state),\n writable: true,\n enumerable: true,\n configurable: true,\n }\n }\n // Preserve normal property checks for non-index keys.\n return Reflect.getOwnPropertyDescriptor(target, index)\n },\n })\n }\n\n /**\n * The current number of live entries.\n */\n get size(): number {\n return this.state.size\n }\n /**\n * Inserts a value before an index.\n *\n * If `beforeIndex` is omitted, the value is inserted at the start of the list.\n *\n * @param value - The value to insert.\n * @param beforeIndex - The index to insert before.\n */\n prepend(value: T, beforeIndex?: number): void {\n const result = __update<T>(beforeIndex ?? 0, [value], this.state, 'before')\n if (!result) return\n const { delta, change } = result\n if (delta) void dispatchCRListEvent(this.eventTarget, 'delta', delta)\n if (change) void dispatchCRListEvent(this.eventTarget, 'change', change)\n }\n /**\n * Inserts a value after an index.\n *\n * If `afterIndex` is omitted, the value is appended at the end of the list.\n *\n * @param value - The value to insert.\n * @param afterIndex - The index to insert after.\n */\n append(value: T, afterIndex?: number): void {\n const result = __update<T>(\n afterIndex ?? this.state.size,\n [value],\n this.state,\n 'after'\n )\n if (!result) return\n const { delta, change } = result\n if (delta) void dispatchCRListEvent(this.eventTarget, 'delta', delta)\n if (change) void dispatchCRListEvent(this.eventTarget, 'change', change)\n }\n /**\n * Removes the entry at an index.\n *\n * @param index - The index to remove.\n */\n remove(index: number): void {\n const result = __delete(this.state, index, index + 1)\n if (!result) return\n const { delta, change } = result\n if (delta) void dispatchCRListEvent(this.eventTarget, 'delta', delta)\n if (change) void dispatchCRListEvent(this.eventTarget, 'change', change)\n }\n\n /**\n * Returns the first live value matching a predicate in index order.\n *\n * Predicate values are live references. Mutating them directly can mutate the\n * list without emitting a delta.\n *\n * @param predicate - Function to test each live value.\n * @param thisArg - Optional `this` value for the predicate.\n */\n find(\n predicate: (this: unknown, value: T, index: number, list: this) => unknown,\n thisArg?: unknown\n ): T | undefined {\n let linkedListEntry = this.state.index?.get(0) ?? this.state.cursor\n while (linkedListEntry?.prev) linkedListEntry = linkedListEntry.prev\n let index = 0\n while (linkedListEntry) {\n if (predicate.call(thisArg, linkedListEntry.value, index, this))\n return linkedListEntry.value\n linkedListEntry = linkedListEntry.next\n index++\n }\n\n return undefined\n }\n\n /**\n * Applies a remote gossip delta to this list.\n *\n * Emits a `change` event when the merge changes the live projection.\n *\n * @param delta - The remote CRList delta to merge.\n */\n merge(delta: CRListDelta<T>): void {\n const change = __merge(this.state, delta)\n if (change) void dispatchCRListEvent(this.eventTarget, 'change', change)\n }\n /**\n * Emits an acknowledgement frontier for currently retained tombstones.\n */\n acknowledge(): void {\n const ack = __acknowledge(this.state)\n if (ack) void dispatchCRListEvent(this.eventTarget, 'ack', ack)\n }\n /**\n * Garbage-collects tombstones that are covered by acknowledgement frontiers.\n *\n * @param frontiers - Replica acknowledgement frontiers.\n */\n garbageCollect(frontiers: Array<CRListAck>): void {\n void __garbageCollect(frontiers, this.state)\n }\n /**\n * Emits the current CRList snapshot.\n *\n * Snapshot value payloads are live references. Mutating them can mutate\n * replica state without emitting a delta.\n */\n snapshot(): void {\n const snapshot = __snapshot<T>(this.state)\n if (snapshot)\n void dispatchCRListEvent(this.eventTarget, 'snapshot', snapshot)\n }\n /**\n * Registers an event listener.\n *\n * @param type - The event type to listen for.\n * @param listener - The listener to register.\n * @param options - Listener registration options.\n */\n addEventListener<K extends keyof CRListEventMap<T>>(\n type: K,\n listener: CRListEventListenerFor<T, K> | null,\n options?: boolean | AddEventListenerOptions\n ): void {\n void this.eventTarget.addEventListener(\n type,\n listener as EventListenerOrEventListenerObject | null,\n options\n )\n }\n\n /**\n * Removes an event listener.\n *\n * @param type - The event type to stop listening for.\n * @param listener - The listener to remove.\n * @param options - Listener removal options.\n */\n removeEventListener<K extends keyof CRListEventMap<T>>(\n type: K,\n listener: CRListEventListenerFor<T, K> | null,\n options?: boolean | EventListenerOptions\n ): void {\n void this.eventTarget.removeEventListener(\n type,\n listener as EventListenerOrEventListenerObject | null,\n options\n )\n }\n /**\n * Returns a CRList snapshot of this list.\n *\n * Snapshot value payloads are live references. Mutating them can mutate\n * replica state without emitting a delta.\n *\n * Called automatically by `JSON.stringify`.\n */\n toJSON(): CRListSnapshot<T> {\n return __snapshot<T>(this.state)\n }\n /**\n * Attempts to return this list snapshot as a JSON string.\n *\n * This can fail when list values are not JSON-compatible.\n */\n toString(): string {\n return JSON.stringify(this)\n }\n /**\n * Returns the Node.js console inspection representation.\n */\n [Symbol.for('nodejs.util.inspect.custom')](): CRListSnapshot<T> {\n return this.toJSON()\n }\n /**\n * Returns the Deno console inspection representation.\n */\n [Symbol.for('Deno.customInspect')](): CRListSnapshot<T> {\n return this.toJSON()\n }\n /**\n * Iterates over current live values in index order.\n */\n *[Symbol.iterator](): IterableIterator<T> {\n for (let index = 0; index < this.size; index++) {\n const value = this[index]\n yield value\n }\n }\n /**\n * Calls a function once for each live value in index order.\n *\n * Callback values are live references. Mutating them directly can mutate the\n * list without emitting a delta.\n *\n * @param callback - Function to call for each live value.\n * @param thisArg - Optional `this` value for the callback.\n */\n forEach(\n callback: (value: T, index: number, list: this) => void,\n thisArg?: unknown\n ): void {\n for (let index = 0; index < this.size; index++) {\n void callback.call(thisArg, this[index], index, this)\n }\n }\n}\n"],"mappings":"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","names":["isUuidV7","isUuidV7","prototype","isUuidV7","isUuidV7"]}
1
+ {"version":3,"sources":["../src/.helpers/rebuildLiveIndex/index.ts","../src/.errors/class.ts","../src/.helpers/seekCursorToIndex/index.ts","../src/.helpers/linkEntryBetween/index.ts","../src/.helpers/rebuildLiveProjection/index.ts","../src/.helpers/materializeSnapshotEntry/index.ts","../src/.helpers/attachEntryToIndexes/index.ts","../src/.helpers/detachEntryFromIndexes/index.ts","../src/.helpers/deleteLiveEntry/index.ts","../src/.helpers/dispatchCRListEvent/index.ts","../src/.helpers/moveEntryToPredecessor/index.ts","../src/.helpers/indexFromPropertyKey/index.ts","../src/.helpers/trySpliceInsertedParent/index.ts","../src/core/crud/create/index.ts","../src/core/crud/read/index.ts","../src/core/crud/update/index.ts","../src/core/crud/delete/index.ts","../src/core/mags/merge/index.ts","../src/core/mags/acknowledge/index.ts","../src/core/mags/garbageCollect/index.ts","../src/core/mags/snapshot/index.ts","../src/CRList/class.ts"],"sourcesContent":["import type { CRListState } from '../../.types/index.js'\n\n/**\n * Rebuilds the opportunistic index cache from the current live projection.\n */\nexport function rebuildLiveIndex<T>(crListReplica: CRListState<T>): void {\n if (!crListReplica.cursor) {\n crListReplica.index?.clear()\n crListReplica.cursorIndex = undefined\n return\n }\n let index = crListReplica.size\n const entries = crListReplica.index ?? new Map()\n void entries.clear()\n while (crListReplica.cursor.next)\n crListReplica.cursor = crListReplica.cursor.next\n\n while (index >= 1) {\n index--\n crListReplica.cursor.index = index\n void entries.set(index, crListReplica.cursor)\n if (crListReplica.cursor.prev === undefined) break\n crListReplica.cursor = crListReplica.cursor.prev\n }\n crListReplica.index = entries\n crListReplica.cursorIndex = 0\n}\n","/**\n * Error codes thrown by {@link CRList}.\n */\nexport type CRListErrorCode =\n | 'VALUE_NOT_CLONEABLE'\n | 'INDEX_OUT_OF_BOUNDS'\n | 'LIST_EMPTY'\n | 'LIST_INTEGRITY_VIOLATION'\n | 'UPDATE_EXPECTED_AN_ARRAY'\n\n/**\n * Represents a typed CRList runtime error.\n */\nexport class CRListError extends Error {\n /**\n * The semantic error code for the failure.\n */\n readonly code: CRListErrorCode\n\n /**\n * Creates a typed CRList error.\n *\n * @param code - The semantic error code.\n * @param message - An optional human-readable detail message.\n */\n constructor(code: CRListErrorCode, message?: string) {\n const detail = message ?? code\n super(`{@sovereignbase/convergent-replicated-list} ${detail}`)\n this.code = code\n this.name = 'CRListError'\n }\n}\n","import type { CRListState } from '../../.types/index.js'\nimport { CRListError } from '../../.errors/class.js'\n\n/**\n * Moves the replica cursor to a live index.\n *\n * A valid cached index entry is used directly. Stale cache entries are dropped\n * and the cursor walks from its current position, then repairs the cache at the\n * requested index.\n */\nexport function seekCursorToIndex<T>(\n targetIndex: number,\n crListReplica: CRListState<T>\n): void {\n if (targetIndex < 0 || targetIndex >= crListReplica.size)\n throw new CRListError('INDEX_OUT_OF_BOUNDS', 'Index out of bounds')\n const indexedEntry = crListReplica.index?.get(targetIndex)\n if (indexedEntry) {\n if (crListReplica.parentMap.get(indexedEntry.uuidv7) === indexedEntry) {\n crListReplica.cursor = indexedEntry\n crListReplica.cursorIndex = targetIndex\n return\n } else {\n void crListReplica.index?.delete(targetIndex)\n }\n }\n if (!crListReplica.cursor)\n throw new CRListError('LIST_EMPTY', 'List is empty')\n let cursorIndex = crListReplica.cursorIndex ?? crListReplica.cursor.index\n const direction = cursorIndex > targetIndex ? 'prev' : 'next'\n while (crListReplica.cursor && cursorIndex !== targetIndex) {\n crListReplica.cursor = crListReplica.cursor[direction]\n cursorIndex += direction === 'next' ? 1 : -1\n }\n if (crListReplica.cursor) {\n crListReplica.cursorIndex = targetIndex\n void crListReplica.index?.set(targetIndex, crListReplica.cursor)\n }\n}\n","import type { CRListStateEntry } from '../../.types/index.js'\n\n/**\n * Links a live entry between optional neighboring projection entries.\n */\nexport function linkEntryBetween<T>(\n prev: CRListStateEntry<T>,\n linkedListEntry: NonNullable<CRListStateEntry<T>>,\n next: CRListStateEntry<T>\n): void {\n linkedListEntry.prev = prev\n linkedListEntry.next = next\n if (prev) prev.next = linkedListEntry\n if (next) next.prev = linkedListEntry\n}\n","import type { CRListState, CRListStateEntry } from '../../.types/index.js'\nimport { linkEntryBetween } from '../linkEntryBetween/index.js'\n\n/**\n * Rebuilds the live linked-list projection and index from predecessor buckets.\n *\n * Sibling order is deterministic by UUIDv7, which keeps replicas convergent even\n * when deltas arrive in different orders.\n */\nexport function rebuildLiveProjection<T>(crListReplica: CRListState<T>) {\n crListReplica.cursor = undefined\n const entries = crListReplica.index ?? new Map()\n void entries.clear()\n for (const entry of crListReplica.parentMap.values()) {\n if (!entry) continue\n entry.prev = undefined\n entry.next = undefined\n }\n let previous: CRListStateEntry<T> = undefined\n let first: CRListStateEntry<T> = undefined\n let index = 0\n const appendChildren = (predecessorIdentifier: string): void => {\n const stack: Array<{\n predecessorIdentifier: string\n siblingIndex: number\n siblings?: Array<NonNullable<CRListStateEntry<T>>>\n }> = [{ predecessorIdentifier, siblingIndex: 0 }]\n\n while (stack.length > 0) {\n const frame = stack[stack.length - 1]\n\n if (!frame.siblings) {\n frame.siblings = crListReplica.childrenMap.get(\n frame.predecessorIdentifier\n )\n if (!frame.siblings) {\n void stack.pop()\n continue\n }\n if (frame.siblings.length > 1)\n void frame.siblings.sort((a, b) => (a.uuidv7 > b.uuidv7 ? 1 : -1))\n }\n\n if (frame.siblingIndex >= frame.siblings.length) {\n void stack.pop()\n continue\n }\n\n const sibling = frame.siblings[frame.siblingIndex]\n frame.siblingIndex++\n if (!sibling) continue\n if (crListReplica.parentMap.get(sibling.uuidv7) !== sibling) continue\n\n sibling.index = index\n index++\n void linkEntryBetween<T>(previous, sibling, undefined)\n if (!first) first = sibling\n previous = sibling\n void stack.push({\n predecessorIdentifier: sibling.uuidv7,\n siblingIndex: 0,\n })\n }\n }\n void appendChildren('\\0')\n const detachedPredecessors: Array<string> = []\n for (const predecessorIdentifier of crListReplica.childrenMap.keys()) {\n if (\n predecessorIdentifier !== '\\0' &&\n !crListReplica.parentMap.get(predecessorIdentifier)\n )\n void detachedPredecessors.push(predecessorIdentifier)\n }\n if (detachedPredecessors.length > 1)\n detachedPredecessors.sort((a, b) => (a > b ? 1 : -1))\n for (const predecessorIdentifier of detachedPredecessors)\n void appendChildren(predecessorIdentifier)\n crListReplica.cursor = first\n crListReplica.cursorIndex = first ? 0 : undefined\n if (first) void entries.set(0, first)\n crListReplica.index = entries\n crListReplica.size = crListReplica.parentMap.size\n}\n","import type {\n CRListState,\n CRListSnapshotEntry,\n CRListStateEntry,\n} from '../../.types/index.js'\nimport { isUuidV7 } from '@sovereignbase/utils'\n\n/**\n * Converts a snapshot or delta value entry into local mutable entry state.\n *\n * Invalid, deleted, duplicate, or currently unanchored entries are ignored.\n * Payload values are kept by reference.\n */\nexport function materializeSnapshotEntry<T>(\n valueEntry: CRListSnapshotEntry<T>,\n crListReplica: CRListState<T>\n): CRListStateEntry<T> {\n if (valueEntry === null || valueEntry === undefined) return undefined\n if (\n !isUuidV7(valueEntry.uuidv7) ||\n crListReplica.tombstones.has(valueEntry.uuidv7) ||\n crListReplica.parentMap.has(valueEntry.uuidv7) ||\n (!isUuidV7(valueEntry.predecessor) &&\n valueEntry.predecessor !== '\\0' &&\n !crListReplica.tombstones.has(valueEntry.predecessor))\n )\n return undefined\n\n return {\n uuidv7: valueEntry.uuidv7,\n value: valueEntry.value,\n predecessor: valueEntry.predecessor,\n index: 0,\n next: undefined,\n prev: undefined,\n }\n}\n","import type {\n CRListState,\n CRListStateEntry,\n CRListDelta,\n} from '../../.types/index.js'\n\n/**\n * Attaches a live entry to UUID and predecessor indexes.\n *\n * When a delta buffer is provided, the same live payload reference is appended\n * to the outgoing delta.\n */\nexport function attachEntryToIndexes<T>(\n crListReplica: CRListState<T>,\n linkedListEntry: NonNullable<CRListStateEntry<T>>,\n deltaBuf?: CRListDelta<T>\n): void {\n void crListReplica.parentMap.set(linkedListEntry.uuidv7, linkedListEntry)\n const siblings = crListReplica.childrenMap.get(linkedListEntry.predecessor)\n if (siblings) {\n void siblings.push(linkedListEntry)\n } else {\n void crListReplica.childrenMap.set(linkedListEntry.predecessor, [\n linkedListEntry,\n ])\n }\n if (deltaBuf && !Array.isArray(deltaBuf.values)) deltaBuf.values = []\n if (deltaBuf?.values)\n void deltaBuf.values.push({\n uuidv7: linkedListEntry.uuidv7,\n value: linkedListEntry.value,\n predecessor: linkedListEntry.predecessor,\n })\n}\n","import type { CRListState, CRListStateEntry } from '../../.types/index.js'\n\n/**\n * Removes a live entry from UUID and predecessor indexes.\n */\nexport function detachEntryFromIndexes<T>(\n crListReplica: CRListState<T>,\n linkedListEntry: NonNullable<CRListStateEntry<T>>\n): void {\n void crListReplica.parentMap.delete(linkedListEntry.uuidv7)\n const siblings = crListReplica.childrenMap.get(linkedListEntry.predecessor)\n if (!siblings) return\n const index = siblings.indexOf(linkedListEntry)\n if (index !== -1) void siblings.splice(index, 1)\n}\n","import type {\n CRListDelta,\n CRListState,\n CRListStateEntry,\n} from '../../.types/index.js'\nimport { detachEntryFromIndexes } from '../detachEntryFromIndexes/index.js'\n\n/**\n * Tombstones a live entry and unlinks it from the local projection.\n */\nexport function deleteLiveEntry<T>(\n crListReplica: CRListState<T>,\n linkedListEntry: NonNullable<CRListStateEntry<T>>,\n deltaBuf?: CRListDelta<T>\n): void {\n const prev = linkedListEntry.prev\n const next = linkedListEntry.next\n void crListReplica.tombstones.add(linkedListEntry.uuidv7)\n if (deltaBuf && !Array.isArray(deltaBuf.tombstones)) deltaBuf.tombstones = []\n void deltaBuf?.tombstones?.push(linkedListEntry.uuidv7)\n if (prev) prev.next = next\n if (next) {\n next.prev = prev\n }\n void detachEntryFromIndexes<T>(crListReplica, linkedListEntry)\n if (crListReplica.cursor === linkedListEntry)\n crListReplica.cursor = next ?? prev\n if (!crListReplica.cursor) crListReplica.cursorIndex = undefined\n linkedListEntry.prev = undefined\n linkedListEntry.next = undefined\n crListReplica.size = crListReplica.parentMap.size\n}\n","import type { CRListEventMap } from '../../.types/index.js'\n\n/**\n * Dispatches a typed CRList event payload through an EventTarget.\n */\nexport function dispatchCRListEvent<T, K extends keyof CRListEventMap<T>>(\n eventTarget: EventTarget,\n type: K,\n detail: CRListEventMap<T>[K]\n): void {\n void eventTarget.dispatchEvent(new CustomEvent(type, { detail }))\n}\n","import type {\n CRListDelta,\n CRListState,\n CRListStateEntry,\n} from '../../.types/index.js'\nimport { detachEntryFromIndexes } from '../detachEntryFromIndexes/index.js'\nimport { attachEntryToIndexes } from '../attachEntryToIndexes/index.js'\n\n/**\n * Reattaches an existing live entry to a newer stable predecessor.\n */\nexport function moveEntryToPredecessor<T>(\n crListReplica: CRListState<T>,\n linkedListEntry: NonNullable<CRListStateEntry<T>>,\n predecessor: string,\n deltaBuf?: CRListDelta<T>\n): void {\n void detachEntryFromIndexes<T>(crListReplica, linkedListEntry)\n linkedListEntry.predecessor = predecessor\n void attachEntryToIndexes<T>(crListReplica, linkedListEntry, deltaBuf)\n}\n","/**\n * Parses a JavaScript property key as a safe non-negative list index.\n */\nexport function indexFromPropertyKey(\n index: string | symbol\n): number | undefined {\n if (typeof index !== 'string' || !/^(0|[1-9]\\d*)$/.test(index))\n return undefined\n const listIndex = Number(index)\n return Number.isSafeInteger(listIndex) ? listIndex : undefined\n}\n","import type {\n CRListState,\n CRListStateEntry,\n CRListReparentedEntry,\n} from '../../.types/index.js'\nimport { linkEntryBetween } from '../../.helpers/index.js'\n\n/**\n * Applies the common single-insert reparent delta without a full projection rebuild.\n */\nexport function trySpliceInsertedParent<T>(\n crListReplica: CRListState<T>,\n insertedEntries: Array<NonNullable<CRListStateEntry<T>>>,\n reparentedEntries: Array<CRListReparentedEntry<T>>\n): boolean {\n if (insertedEntries.length !== 1 || reparentedEntries.length !== 1)\n return false\n const inserted = insertedEntries[0]\n const reparented = reparentedEntries[0]\n const moved = reparented.entry\n if (\n moved.predecessor !== inserted.uuidv7 ||\n inserted.predecessor !== reparented.previousPredecessor\n )\n return false\n const siblings = crListReplica.childrenMap.get(inserted.predecessor)\n const children = crListReplica.childrenMap.get(inserted.uuidv7)\n if (\n siblings?.length !== 1 ||\n siblings[0] !== inserted ||\n children?.length !== 1 ||\n children[0] !== moved\n )\n return false\n const predecessor =\n inserted.predecessor === '\\0'\n ? undefined\n : crListReplica.parentMap.get(inserted.predecessor)\n if (inserted.predecessor !== '\\0' && !predecessor) return false\n const expectedIndex = predecessor ? predecessor.index + 1 : 0\n if (\n moved.index !== expectedIndex ||\n moved.prev !== predecessor ||\n (predecessor && predecessor.next !== moved)\n )\n return false\n\n void linkEntryBetween<T>(predecessor, inserted, moved)\n let current: CRListStateEntry<T> = inserted\n let index = expectedIndex\n while (current) {\n current.index = index\n index++\n current = current.next\n }\n crListReplica.index = new Map([[inserted.index, inserted]])\n crListReplica.cursor = inserted\n crListReplica.cursorIndex = inserted.index\n crListReplica.size = crListReplica.parentMap.size\n return true\n}\n","import { isUuidV7, prototype } from '@sovereignbase/utils'\nimport {\n CRListSnapshot,\n CRListState,\n CRListStateEntry,\n} from '../../../.types/index.js'\nimport {\n rebuildLiveProjection,\n materializeSnapshotEntry,\n attachEntryToIndexes,\n linkEntryBetween,\n} from '../../../.helpers/index.js'\n\n/**\n * Creates a local CRList replica from an optional snapshot.\n *\n * Invalid snapshot records are ignored. Accepted values are kept by reference,\n * indexed by UUIDv7, linked through their predecessor buckets, and exposed as a\n * live doubly-linked list projection.\n *\n * @param snapshot - Optional CRList snapshot.\n * @returns - A hydrated CRList replica.\n *\n * Time complexity: O(n log n + t), worst case O(n^2 + t)\n * - n = snapshot value entry count\n * - t = snapshot tombstone count\n *\n * Space complexity: O(n + t)\n */\nexport function __create<T>(snapshot?: CRListSnapshot<T>): CRListState<T> {\n const crListReplica: CRListState<T> = {\n size: 0,\n cursor: undefined,\n cursorIndex: undefined,\n index: new Map(),\n tombstones: new Set<string>(),\n parentMap: new Map<string, NonNullable<CRListStateEntry<T>>>(),\n childrenMap: new Map<string, Array<NonNullable<CRListStateEntry<T>>>>(),\n }\n if (!snapshot || prototype(snapshot) !== 'record') return crListReplica\n\n /** Hydrate tombstone entries. */\n if (\n Object.hasOwn(snapshot, 'tombstones') &&\n Array.isArray(snapshot.tombstones)\n ) {\n for (const tombstone of snapshot.tombstones) {\n if (crListReplica.tombstones.has(tombstone) || !isUuidV7(tombstone))\n continue\n void crListReplica.tombstones.add(tombstone)\n }\n }\n\n /** Hydrate value entries. */\n if (!Object.hasOwn(snapshot, 'values') || !Array.isArray(snapshot.values))\n return crListReplica\n // Build predecessor tree.\n let canUseLinearProjection = true\n let previous: CRListStateEntry<T> = undefined\n for (const valueEntry of snapshot.values) {\n const linkedListEntry = materializeSnapshotEntry<T>(\n valueEntry,\n crListReplica\n )\n if (!linkedListEntry) continue\n void attachEntryToIndexes<T>(crListReplica, linkedListEntry)\n if (\n canUseLinearProjection &&\n linkedListEntry.predecessor === (previous?.uuidv7 ?? '\\0')\n ) {\n linkedListEntry.index = crListReplica.parentMap.size - 1\n void linkEntryBetween<T>(previous, linkedListEntry, undefined)\n previous = linkedListEntry\n void crListReplica.index?.set(linkedListEntry.index, linkedListEntry)\n continue\n }\n canUseLinearProjection = false\n }\n if (canUseLinearProjection) {\n crListReplica.cursor = previous\n crListReplica.cursorIndex = previous\n ? crListReplica.parentMap.size - 1\n : undefined\n crListReplica.size = crListReplica.parentMap.size\n return crListReplica\n }\n // Flatten tree into a doubly linked list and write live-view indexes.\n void rebuildLiveProjection<T>(crListReplica)\n\n return crListReplica\n}\n","import { seekCursorToIndex } from '../../../.helpers/index.js'\nimport { CRListState } from '../../../.types/index.js'\n\n/**\n * Reads the value at an index in the replica live view.\n *\n * The replica cursor is moved as part of the lookup. Successful reads return\n * the live value reference stored by the replica. Mutating that value directly\n * can mutate replica state and should only be done when the caller owns an\n * independent value object. Out-of-bounds and empty list reads resolve to\n * `undefined` instead of throwing.\n *\n * @param targetIndex - Index in the live list.\n * @param crListReplica - Replica to read from.\n * @returns - The live value at `targetIndex`, or `undefined` when\n * no value is present.\n *\n * Time complexity: O(d), worst case O(n)\n * - d = distance from cursor to target index\n * - n = list size\n *\n * Space complexity: O(1)\n */\nexport function __read<T>(\n targetIndex: number,\n crListReplica: CRListState<T>\n): T | undefined {\n try {\n void seekCursorToIndex<T>(targetIndex, crListReplica)\n return crListReplica.cursor?.value\n } catch {\n return undefined\n }\n}\n","import { CRListError } from '../../../.errors/class.js'\nimport {\n attachEntryToIndexes,\n detachEntryFromIndexes,\n seekCursorToIndex,\n moveEntryToPredecessor,\n linkEntryBetween,\n} from '../../../.helpers/index.js'\nimport { v7 as uuidv7 } from 'uuid'\nimport {\n CRListChange,\n CRListDelta,\n CRListState,\n CRListStateEntry,\n} from '../../../.types/index.js'\n/**\n * Applies a local value mutation to the replica live view.\n *\n * The update can replace a range starting at the target entry, insert values\n * before it, or insert values after it. The returned delta is suitable for\n * gossip and the returned change describes the local live-view patch.\n *\n * @param listIndex - Target index in the live list.\n * @param listValues - Values to insert or overwrite.\n * @param crListReplica - Replica to mutate.\n * @param mode - Mutation mode relative to `listIndex`.\n * @returns - A local change and gossip delta, or `false` if no mutation occurred.\n *\n * Time complexity: O(d + v + r + vk), worst case O(vn)\n * - d = distance from cursor to target index\n * - v = amount of input values\n * - r = amount of nodes after inserted values whose indexes must be shifted\n * - k = sibling bucket size when predecessor bucket is updated\n *\n * Space complexity: O(v)\n */\nexport function __update<T>(\n listIndex: number,\n listValues: Array<T>,\n crListReplica: CRListState<T>,\n mode: 'overwrite' | 'before' | 'after'\n): { change: CRListChange<T>; delta: CRListDelta<T> } | false {\n if (listIndex < 0 || listIndex > crListReplica.size)\n throw new CRListError('INDEX_OUT_OF_BOUNDS')\n if (!Array.isArray(listValues))\n throw new CRListError(\n 'UPDATE_EXPECTED_AN_ARRAY',\n '`listValues` must be an Array'\n )\n if (listValues.length === 0) return false\n const change: CRListChange<T> = {}\n const delta: CRListDelta<T> = { values: [], tombstones: [] }\n for (const listValue of listValues) {\n const v7 = uuidv7()\n\n const linkedListEntry: NonNullable<CRListStateEntry<T>> = {\n uuidv7: v7,\n value: listValue,\n predecessor: '\\0',\n index: 0,\n next: undefined,\n prev: undefined,\n }\n\n switch (mode) {\n case 'overwrite': {\n if (listIndex === crListReplica.size) {\n if (crListReplica.size === 0) {\n crListReplica.cursor = linkedListEntry\n crListReplica.cursorIndex = linkedListEntry.index\n void attachEntryToIndexes<T>(crListReplica, linkedListEntry, delta)\n crListReplica.index?.set(linkedListEntry.index, linkedListEntry)\n change[linkedListEntry.index] = linkedListEntry.value\n break\n }\n void seekCursorToIndex<T>(crListReplica.size - 1, crListReplica)\n if (!crListReplica.cursor) return false\n linkedListEntry.index = (crListReplica.cursorIndex ?? 0) + 1\n linkedListEntry.predecessor = crListReplica.cursor.uuidv7\n void linkEntryBetween<T>(\n crListReplica.cursor,\n linkedListEntry,\n undefined\n )\n void attachEntryToIndexes<T>(crListReplica, linkedListEntry, delta)\n crListReplica.cursor = linkedListEntry\n crListReplica.cursorIndex = linkedListEntry.index\n void crListReplica.index?.set(linkedListEntry.index, linkedListEntry)\n change[linkedListEntry.index] = linkedListEntry.value\n break\n }\n void seekCursorToIndex<T>(listIndex, crListReplica)\n if (!crListReplica.cursor) return false\n const entryToOverwrite = crListReplica.cursor\n const actualIndex = crListReplica.cursorIndex ?? listIndex\n\n linkedListEntry.predecessor = entryToOverwrite.predecessor\n linkedListEntry.index = actualIndex\n void linkEntryBetween<T>(\n entryToOverwrite.prev,\n linkedListEntry,\n entryToOverwrite.next\n )\n if (entryToOverwrite.next) {\n if (entryToOverwrite.next.predecessor === entryToOverwrite.uuidv7) {\n void moveEntryToPredecessor<T>(\n crListReplica,\n entryToOverwrite.next,\n linkedListEntry.uuidv7,\n delta\n )\n }\n }\n void attachEntryToIndexes<T>(crListReplica, linkedListEntry, delta)\n void crListReplica.tombstones.add(entryToOverwrite.uuidv7)\n void delta.tombstones?.push(entryToOverwrite.uuidv7)\n void detachEntryFromIndexes<T>(crListReplica, entryToOverwrite)\n entryToOverwrite.next = undefined\n entryToOverwrite.prev = undefined\n crListReplica.cursor = linkedListEntry\n crListReplica.cursorIndex = actualIndex\n void crListReplica.index?.set(linkedListEntry.index, linkedListEntry)\n change[actualIndex] = linkedListEntry.value\n break\n }\n case 'after': {\n if (crListReplica.size === 0 && listIndex === 0) {\n crListReplica.cursor = linkedListEntry\n crListReplica.cursorIndex = linkedListEntry.index\n void attachEntryToIndexes<T>(crListReplica, linkedListEntry, delta)\n void crListReplica.index?.set(linkedListEntry.index, linkedListEntry)\n change[linkedListEntry.index] = linkedListEntry.value\n break\n }\n if (listIndex === crListReplica.size) {\n void seekCursorToIndex<T>(crListReplica.size - 1, crListReplica)\n } else {\n void seekCursorToIndex<T>(listIndex, crListReplica)\n }\n if (!crListReplica.cursor) return false\n const actualIndex = crListReplica.cursorIndex ?? listIndex\n const next =\n listIndex === crListReplica.size\n ? undefined\n : crListReplica.cursor.next\n linkedListEntry.index = actualIndex + 1\n linkedListEntry.predecessor = crListReplica.cursor.uuidv7\n void linkEntryBetween<T>(crListReplica.cursor, linkedListEntry, next)\n if (next) {\n if (next.predecessor === crListReplica.cursor.uuidv7) {\n void moveEntryToPredecessor<T>(\n crListReplica,\n next,\n linkedListEntry.uuidv7,\n delta\n )\n }\n }\n void attachEntryToIndexes<T>(crListReplica, linkedListEntry, delta)\n crListReplica.cursor = linkedListEntry\n crListReplica.cursorIndex = linkedListEntry.index\n if (next) crListReplica.index = new Map()\n void crListReplica.index?.set(linkedListEntry.index, linkedListEntry)\n change[linkedListEntry.index] = linkedListEntry.value\n break\n }\n case 'before': {\n if (crListReplica.size === 0 && listIndex === 0) {\n crListReplica.cursor = linkedListEntry\n crListReplica.cursorIndex = linkedListEntry.index\n void attachEntryToIndexes<T>(crListReplica, linkedListEntry, delta)\n void crListReplica.index?.set(linkedListEntry.index, linkedListEntry)\n change[linkedListEntry.index] = linkedListEntry.value\n mode = 'after'\n listIndex = linkedListEntry.index - 1\n break\n }\n void seekCursorToIndex<T>(listIndex, crListReplica)\n if (!crListReplica.cursor) return false\n const actualIndex = crListReplica.cursorIndex ?? listIndex\n const prev = crListReplica.cursor.prev\n linkedListEntry.index = actualIndex\n linkedListEntry.predecessor = prev?.uuidv7 ?? '\\0'\n void linkEntryBetween<T>(prev, linkedListEntry, crListReplica.cursor)\n if (crListReplica.cursor.predecessor === linkedListEntry.predecessor) {\n void moveEntryToPredecessor<T>(\n crListReplica,\n crListReplica.cursor,\n linkedListEntry.uuidv7,\n delta\n )\n }\n void attachEntryToIndexes<T>(crListReplica, linkedListEntry, delta)\n crListReplica.cursor = linkedListEntry\n crListReplica.cursorIndex = actualIndex\n crListReplica.index = new Map()\n void crListReplica.index?.set(linkedListEntry.index, linkedListEntry)\n change[actualIndex] = linkedListEntry.value\n mode = 'after'\n listIndex = linkedListEntry.index - 1\n\n break\n }\n }\n crListReplica.size = crListReplica.parentMap.size\n listIndex++\n }\n return { change, delta }\n}\n","import { deleteLiveEntry, seekCursorToIndex } from '../../../.helpers/index.js'\nimport { CRListError } from '../../../.errors/class.js'\nimport type {\n CRListChange,\n CRListDelta,\n CRListState,\n CRListStateEntry,\n} from '../../../.types/index.js'\n\n/**\n * Deletes a range from the replica live view.\n *\n * With no indexes, the full list is deleted. With only `startIndex`, all entries\n * from `startIndex` onward are deleted. With both indexes, the deleted range is\n * `[startIndex, endIndex)`.\n *\n * @param crListReplica - Replica to mutate.\n * @param startIndex - Inclusive start index. Defaults to `0`.\n * @param endIndex - Exclusive end index. Defaults to the current list size.\n * @returns - A local change and gossip delta, or `false` if nothing was deleted.\n *\n * Time complexity: O(d + qk + r), worst case O(n^2)\n * - d = distance from cursor to target index\n * - q = amount of deleted nodes\n * - r = amount of nodes after the deleted range whose indexes must be shifted\n * - k = sibling bucket size when deleted entries are removed from buckets\n *\n * Space complexity: O(q)\n */\nexport function __delete<T>(\n crListReplica: CRListState<T>,\n startIndex?: number,\n endIndex?: number\n): { change: CRListChange<T>; delta: CRListDelta<T> } | false {\n const change: CRListChange<T> = {}\n const delta: CRListDelta<T> = { values: [], tombstones: [] }\n const listIndex = startIndex ?? 0\n const targetEndIndex = endIndex ?? crListReplica.size\n if (\n listIndex < 0 ||\n targetEndIndex < listIndex ||\n listIndex > crListReplica.size\n )\n throw new CRListError('INDEX_OUT_OF_BOUNDS')\n const deleteCount = Math.min(targetEndIndex, crListReplica.size) - listIndex\n if (deleteCount <= 0) return false\n\n void seekCursorToIndex<T>(listIndex, crListReplica)\n if (!crListReplica.cursor) return false\n\n let current: CRListStateEntry<T> = crListReplica.cursor\n let deleted = 0\n let currentIndex = crListReplica.cursorIndex ?? listIndex\n\n while (current && deleted < deleteCount) {\n const next: CRListStateEntry<T> = current.next\n change[currentIndex] = undefined\n void crListReplica.index?.delete(currentIndex)\n void deleteLiveEntry<T>(crListReplica, current, delta)\n current = next\n currentIndex++\n deleted++\n }\n\n crListReplica.size = crListReplica.parentMap.size\n crListReplica.cursor = current ?? crListReplica.cursor\n crListReplica.cursorIndex = current\n ? listIndex\n : crListReplica.cursor\n ? Math.max(0, crListReplica.size - 1)\n : undefined\n crListReplica.index = new Map()\n if (crListReplica.cursor && crListReplica.cursorIndex !== undefined)\n void crListReplica.index.set(\n crListReplica.cursorIndex,\n crListReplica.cursor\n )\n\n return { change, delta }\n}\n","import type {\n CRListChange,\n CRListDelta,\n CRListState,\n CRListStateEntry,\n} from '../../../.types/index.js'\nimport {\n materializeSnapshotEntry,\n attachEntryToIndexes,\n rebuildLiveProjection,\n rebuildLiveIndex,\n deleteLiveEntry,\n moveEntryToPredecessor,\n} from '../../../.helpers/index.js'\nimport { prototype, isUuidV7 } from '@sovereignbase/utils'\nimport { trySpliceInsertedParent } from '../../../.helpers/trySpliceInsertedParent/index.js'\n\n/**\n * Merges a remote CRList delta into the local replica.\n *\n * Accepted tombstones update the local live view and accepted values are attached\n * to the predecessor tree. Tail-append deltas are linked incrementally; deltas\n * that can affect ordering fall back to deterministic relinking.\n *\n * @param crListReplica - Replica to mutate.\n * @param crListDelta - Remote gossip delta.\n * @returns - A minimal local change patch, or `false` when the delta is ignored.\n *\n * Time complexity: O(v + t) for tail-append deltas; O(n + t + qk) for tombstone-only deletes; otherwise O(n log n + v + t + m*k)\n * Worst case: O(n^2 + (v + t)n)\n * - n = replica value entry count after merge\n * - v = delta value entry count\n * - t = delta tombstone count\n * - q = amount of live entries deleted by tombstones\n * - m = entries moved between predecessor buckets\n * - k = sibling bucket size when entries are removed from buckets\n *\n * Space complexity: O(n + v + t)\n */\nexport function __merge<T>(\n crListReplica: CRListState<T>,\n crListDelta: CRListDelta<T>\n): CRListChange<T> | false {\n if (!crListDelta || prototype(crListDelta) !== 'record') return false\n const newVals: Array<NonNullable<CRListStateEntry<T>>> = []\n const newTombsIndices: Array<number> = []\n const reparentedVals: Array<{\n entry: NonNullable<CRListStateEntry<T>>\n previousPredecessor: string\n }> = []\n const change: CRListChange<T> = {}\n let needsRelink = false\n if (\n Object.hasOwn(crListDelta, 'values') &&\n Array.isArray(crListDelta.values) &&\n crListDelta.values.length === 1 &&\n (!Object.hasOwn(crListDelta, 'tombstones') ||\n (Array.isArray(crListDelta.tombstones) &&\n crListDelta.tombstones.length === 0))\n ) {\n const linkedListEntry = materializeSnapshotEntry<T>(\n crListDelta.values[0],\n crListReplica\n )\n if (!linkedListEntry) return false\n const predecessor =\n linkedListEntry.predecessor === '\\0'\n ? undefined\n : crListReplica.parentMap.get(linkedListEntry.predecessor)\n if (\n (linkedListEntry.predecessor === '\\0' && crListReplica.size === 0) ||\n (predecessor && !predecessor.next)\n ) {\n linkedListEntry.prev = predecessor\n linkedListEntry.index = crListReplica.size\n if (predecessor) predecessor.next = linkedListEntry\n crListReplica.cursor = linkedListEntry\n crListReplica.cursorIndex = linkedListEntry.index\n void attachEntryToIndexes<T>(crListReplica, linkedListEntry)\n crListReplica.size = crListReplica.parentMap.size\n void crListReplica.index?.set(linkedListEntry.index, linkedListEntry)\n return { [linkedListEntry.index]: linkedListEntry.value }\n }\n }\n\n /** Apply tombstone entries. */\n if (\n Object.hasOwn(crListDelta, 'tombstones') &&\n Array.isArray(crListDelta.tombstones)\n ) {\n for (const tombstone of crListDelta.tombstones) {\n if (crListReplica.tombstones.has(tombstone) || !isUuidV7(tombstone))\n continue\n void crListReplica.tombstones.add(tombstone)\n const linkedListEntry = crListReplica.parentMap.get(tombstone)\n if (linkedListEntry) {\n void newTombsIndices.push(linkedListEntry.index)\n void crListReplica.index?.delete(linkedListEntry.index)\n void deleteLiveEntry<T>(crListReplica, linkedListEntry)\n needsRelink = true\n }\n }\n }\n\n /** Apply value entries. */\n if (\n !Object.hasOwn(crListDelta, 'values') ||\n !Array.isArray(crListDelta.values)\n ) {\n if (newTombsIndices.length === 0) return false\n void rebuildLiveIndex<T>(crListReplica)\n for (const index of newTombsIndices) {\n change[index] = undefined\n }\n return change\n }\n // Attach accepted values to the predecessor tree.\n for (const valueEntry of crListDelta.values) {\n if (valueEntry === null || valueEntry === undefined) continue\n const existingEntry = crListReplica.parentMap.get(valueEntry.uuidv7)\n if (existingEntry) {\n if (crListReplica.tombstones.has(valueEntry.uuidv7)) continue\n if (valueEntry.predecessor !== '\\0' && !isUuidV7(valueEntry.predecessor))\n continue\n if (existingEntry.predecessor >= valueEntry.predecessor) continue\n const previousPredecessor = existingEntry.predecessor\n void moveEntryToPredecessor<T>(\n crListReplica,\n existingEntry,\n valueEntry.predecessor\n )\n void reparentedVals.push({ entry: existingEntry, previousPredecessor })\n needsRelink = true\n continue\n }\n const linkedListEntry = materializeSnapshotEntry<T>(\n valueEntry,\n crListReplica\n )\n if (!linkedListEntry) continue\n const predecessor =\n linkedListEntry.predecessor === '\\0'\n ? undefined\n : crListReplica.parentMap.get(linkedListEntry.predecessor)\n void attachEntryToIndexes<T>(crListReplica, linkedListEntry)\n void newVals.push(linkedListEntry)\n if (!needsRelink && linkedListEntry.predecessor === '\\0') {\n if (crListReplica.size === 0) {\n crListReplica.cursor = linkedListEntry\n crListReplica.cursorIndex = linkedListEntry.index\n crListReplica.size = crListReplica.parentMap.size\n void crListReplica.index?.set(linkedListEntry.index, linkedListEntry)\n } else {\n needsRelink = true\n }\n } else if (!needsRelink && predecessor && !predecessor.next) {\n linkedListEntry.prev = predecessor\n linkedListEntry.index = crListReplica.size\n predecessor.next = linkedListEntry\n crListReplica.cursor = linkedListEntry\n crListReplica.cursorIndex = linkedListEntry.index\n crListReplica.size = crListReplica.parentMap.size\n void crListReplica.index?.set(linkedListEntry.index, linkedListEntry)\n } else {\n needsRelink = true\n }\n }\n if (needsRelink) {\n if (!trySpliceInsertedParent<T>(crListReplica, newVals, reparentedVals)) {\n // Flatten tree into a doubly linked list and write live-view indexes.\n void rebuildLiveProjection<T>(crListReplica)\n }\n }\n\n if (newTombsIndices.length === 0 && newVals.length === 0) return false\n\n for (const index of newTombsIndices) {\n change[index] = undefined\n }\n for (const val of newVals) {\n change[val.index] = val.value\n }\n\n return change\n}\n","import type { CRListAck, CRListState } from '../../../.types/index.js'\n\n/**\n * Returns the replica tombstone acknowledgement frontier.\n *\n * The frontier is the greatest tombstone identifier currently retained by the\n * replica. Peers can use it as input for tombstone garbage collection.\n *\n * @param crListReplica - Replica to acknowledge.\n * @returns - The acknowledgement frontier, or `false` when there are no tombstones.\n *\n * Time complexity: O(t)\n * - t = replica tombstone count\n *\n * Space complexity: O(1)\n */\nexport function __acknowledge<T>(\n crListReplica: CRListState<T>\n): CRListAck | false {\n let largest: CRListAck | false = false\n void crListReplica.tombstones.forEach((tombstone) => {\n if (largest === false || largest < tombstone) largest = tombstone\n })\n if (typeof largest === 'string') return largest\n return false\n}\n","import { isUuidV7 } from '@sovereignbase/utils'\nimport { CRListAck, CRListState } from '../../../.types/index.js'\n\n/**\n * Removes tombstones acknowledged by all supplied frontiers.\n *\n * The smallest valid UUIDv7 frontier is used as the safe collection boundary.\n * Tombstones less than or equal to that boundary are removed from the local\n * replica.\n *\n * @param frontiers - Acknowledgement frontiers received from peers.\n * @param crListReplica - Replica whose tombstones will be collected.\n *\n * Time complexity: O(f log f + t)\n * - f = frontier count\n * - t = replica tombstone count\n *\n * Space complexity: O(1)\n */\nexport function __garbageCollect<T>(\n frontiers: Array<CRListAck>,\n crListReplica: CRListState<T>\n): void {\n if (!Array.isArray(frontiers)) return\n void frontiers.sort()\n const smallest = frontiers.find((frontier) => isUuidV7(frontier))\n if (typeof smallest !== 'string') return\n void crListReplica.tombstones.forEach((tombstone, __, tombstones) => {\n if (tombstone <= smallest) {\n void tombstones.delete(tombstone)\n }\n })\n}\n","import { CRListError } from '../../../.errors/class.js'\nimport { CRListState, CRListSnapshot } from '../../../.types/index.js'\n\n/**\n * Creates a full CRList snapshot from the current replica state.\n *\n * The snapshot contains every live value entry and all retained tombstones. Value\n * payloads are live references, so callers must not mutate snapshot values\n * unless they have first isolated them from replica state.\n *\n * @param crListReplica - Replica to snapshot.\n * @returns - A full snapshot suitable for hydration or transport.\n *\n * Time complexity: O(n + t)\n * - n = replica value entry count\n * - t = replica tombstone count\n *\n * Space complexity: O(n + t)\n */\nexport function __snapshot<T>(\n crListReplica: CRListState<T>\n): CRListSnapshot<T> {\n return {\n values: Array.from(crListReplica.parentMap.values()).map(\n (linkedListEntry) => {\n if (!linkedListEntry) throw new CRListError('LIST_INTEGRITY_VIOLATION')\n return {\n uuidv7: linkedListEntry.uuidv7,\n value: linkedListEntry.value,\n predecessor: linkedListEntry.predecessor,\n }\n }\n ),\n tombstones: Array.from(crListReplica.tombstones),\n }\n}\n","import { dispatchCRListEvent, indexFromPropertyKey } from '../.helpers/index.js'\nimport { CRListError } from '../.errors/class.js'\nimport type {\n CRListState,\n CRListSnapshot,\n CRListEventListenerFor,\n CRListEventMap,\n CRListDelta,\n CRListAck,\n} from '../.types/index.js'\nimport { __create, __read, __update, __delete } from '../core/crud/index.js'\nimport {\n __merge,\n __acknowledge,\n __garbageCollect,\n __snapshot,\n} from '../core/mags/index.js'\n\n/**\n * A convergent replicated list.\n *\n * Numeric property access reads and mutates the live list projection:\n * `list[0]` reads the live value reference, `list[0] = value` writes an\n * entry, and `delete list[0]` removes one entry. Iteration, `find()`, and\n * `forEach()` expose the same live value references. Mutating returned objects\n * directly can mutate replica state without producing a CRDT delta, so callers\n * must isolate values before out-of-band mutation. Local mutations emit `delta`\n * and `change` events; remote merges emit `change` events.\n *\n * @typeParam T - The value type stored in the list.\n */\nexport class CRList<T> {\n /**\n * Reads or overwrites an entry in the live list projection by index.\n *\n * Reads return live value references.\n */\n [index: number]: T\n declare private readonly state: CRListState<T>\n declare private readonly eventTarget: EventTarget\n\n /**\n * Creates a replicated list from an optional CRList snapshot.\n *\n * @param snapshot - A previously emitted CRList snapshot.\n */\n constructor(snapshot?: CRListSnapshot<T>) {\n void Object.defineProperties(this, {\n state: {\n value: __create<T>(snapshot),\n enumerable: false,\n configurable: false,\n writable: false,\n },\n eventTarget: {\n value: new EventTarget(),\n enumerable: false,\n configurable: false,\n writable: false,\n },\n })\n\n return new Proxy(this, {\n get(target, index, receiver) {\n const listIndex = indexFromPropertyKey(index)\n // Preserve normal property access for non-index keys.\n if (listIndex === undefined) return Reflect.get(target, index, receiver)\n return __read(listIndex, target.state)\n },\n has(target, index) {\n const listIndex = indexFromPropertyKey(index)\n // Preserve normal property checks for non-index keys.\n if (listIndex === undefined) return Reflect.has(target, index)\n return listIndex >= 0 && listIndex < target.state.size\n },\n set(target, index, value) {\n const listIndex = indexFromPropertyKey(index)\n if (listIndex === undefined) return false\n try {\n const result = __update(listIndex, [value], target.state, 'overwrite')\n if (!result) return false\n const { delta, change } = result\n if (delta)\n void dispatchCRListEvent(target.eventTarget, 'delta', delta)\n if (change)\n void dispatchCRListEvent(target.eventTarget, 'change', change)\n return true\n } catch (error) {\n if (error instanceof CRListError) throw error\n return false\n }\n },\n deleteProperty(target, index) {\n const listIndex = indexFromPropertyKey(index)\n if (listIndex === undefined) return false\n try {\n const result = __delete(target.state, listIndex, listIndex + 1)\n if (!result) return false\n const { delta, change } = result\n if (delta)\n void dispatchCRListEvent(target.eventTarget, 'delta', delta)\n if (change)\n void dispatchCRListEvent(target.eventTarget, 'change', change)\n return true\n } catch (error) {\n if (error instanceof CRListError) throw error\n return false\n }\n },\n ownKeys(target) {\n return [\n ...Reflect.ownKeys(target),\n ...Array.from({ length: target.size }, (_, index) => String(index)),\n ]\n },\n\n getOwnPropertyDescriptor(target, index) {\n const listIndex = indexFromPropertyKey(index)\n\n if (listIndex !== undefined && listIndex < target.size) {\n return {\n value: __read(listIndex, target.state),\n writable: true,\n enumerable: true,\n configurable: true,\n }\n }\n // Preserve normal property checks for non-index keys.\n return Reflect.getOwnPropertyDescriptor(target, index)\n },\n })\n }\n\n /**\n * The current number of live entries.\n */\n get size(): number {\n return this.state.size\n }\n /**\n * Inserts a value before an index.\n *\n * If `beforeIndex` is omitted, the value is inserted at the start of the list.\n *\n * @param value - The value to insert.\n * @param beforeIndex - The index to insert before.\n */\n prepend(value: T, beforeIndex?: number): void {\n const result = __update<T>(beforeIndex ?? 0, [value], this.state, 'before')\n if (!result) return\n const { delta, change } = result\n if (delta) void dispatchCRListEvent(this.eventTarget, 'delta', delta)\n if (change) void dispatchCRListEvent(this.eventTarget, 'change', change)\n }\n /**\n * Inserts a value after an index.\n *\n * If `afterIndex` is omitted, the value is appended at the end of the list.\n *\n * @param value - The value to insert.\n * @param afterIndex - The index to insert after.\n */\n append(value: T, afterIndex?: number): void {\n const result = __update<T>(\n afterIndex ?? this.state.size,\n [value],\n this.state,\n 'after'\n )\n if (!result) return\n const { delta, change } = result\n if (delta) void dispatchCRListEvent(this.eventTarget, 'delta', delta)\n if (change) void dispatchCRListEvent(this.eventTarget, 'change', change)\n }\n /**\n * Removes the entry at an index.\n *\n * @param index - The index to remove.\n */\n remove(index: number): void {\n const result = __delete(this.state, index, index + 1)\n if (!result) return\n const { delta, change } = result\n if (delta) void dispatchCRListEvent(this.eventTarget, 'delta', delta)\n if (change) void dispatchCRListEvent(this.eventTarget, 'change', change)\n }\n\n /**\n * Returns the first live value matching a predicate in index order.\n *\n * Predicate values are live references. Mutating them directly can mutate the\n * list without emitting a delta.\n *\n * @param predicate - Function to test each live value.\n * @param thisArg - Optional `this` value for the predicate.\n */\n find(\n predicate: (this: unknown, value: T, index: number, list: this) => unknown,\n thisArg?: unknown\n ): T | undefined {\n let linkedListEntry = this.state.index?.get(0) ?? this.state.cursor\n while (linkedListEntry?.prev) linkedListEntry = linkedListEntry.prev\n let index = 0\n while (linkedListEntry) {\n if (predicate.call(thisArg, linkedListEntry.value, index, this))\n return linkedListEntry.value\n linkedListEntry = linkedListEntry.next\n index++\n }\n\n return undefined\n }\n\n /**\n * Applies a remote gossip delta to this list.\n *\n * Emits a `change` event when the merge changes the live projection.\n *\n * @param delta - The remote CRList delta to merge.\n */\n merge(delta: CRListDelta<T>): void {\n const change = __merge(this.state, delta)\n if (change) void dispatchCRListEvent(this.eventTarget, 'change', change)\n }\n /**\n * Emits an acknowledgement frontier for currently retained tombstones.\n */\n acknowledge(): void {\n const ack = __acknowledge(this.state)\n if (ack) void dispatchCRListEvent(this.eventTarget, 'ack', ack)\n }\n /**\n * Garbage-collects tombstones that are covered by acknowledgement frontiers.\n *\n * @param frontiers - Replica acknowledgement frontiers.\n */\n garbageCollect(frontiers: Array<CRListAck>): void {\n void __garbageCollect(frontiers, this.state)\n }\n /**\n * Emits the current CRList snapshot.\n *\n * Snapshot value payloads are live references. Mutating them can mutate\n * replica state without emitting a delta.\n */\n snapshot(): void {\n const snapshot = __snapshot<T>(this.state)\n if (snapshot)\n void dispatchCRListEvent(this.eventTarget, 'snapshot', snapshot)\n }\n /**\n * Registers an event listener.\n *\n * @param type - The event type to listen for.\n * @param listener - The listener to register.\n * @param options - Listener registration options.\n */\n addEventListener<K extends keyof CRListEventMap<T>>(\n type: K,\n listener: CRListEventListenerFor<T, K> | null,\n options?: boolean | AddEventListenerOptions\n ): void {\n void this.eventTarget.addEventListener(\n type,\n listener as EventListenerOrEventListenerObject | null,\n options\n )\n }\n\n /**\n * Removes an event listener.\n *\n * @param type - The event type to stop listening for.\n * @param listener - The listener to remove.\n * @param options - Listener removal options.\n */\n removeEventListener<K extends keyof CRListEventMap<T>>(\n type: K,\n listener: CRListEventListenerFor<T, K> | null,\n options?: boolean | EventListenerOptions\n ): void {\n void this.eventTarget.removeEventListener(\n type,\n listener as EventListenerOrEventListenerObject | null,\n options\n )\n }\n /**\n * Returns a CRList snapshot of this list.\n *\n * Snapshot value payloads are live references. Mutating them can mutate\n * replica state without emitting a delta.\n *\n * Called automatically by `JSON.stringify`.\n */\n toJSON(): CRListSnapshot<T> {\n return __snapshot<T>(this.state)\n }\n /**\n * Attempts to return this list snapshot as a JSON string.\n *\n * This can fail when list values are not JSON-compatible.\n */\n toString(): string {\n return JSON.stringify(this)\n }\n /**\n * Returns the Node.js console inspection representation.\n */\n [Symbol.for('nodejs.util.inspect.custom')](): CRListSnapshot<T> {\n return this.toJSON()\n }\n /**\n * Returns the Deno console inspection representation.\n */\n [Symbol.for('Deno.customInspect')](): CRListSnapshot<T> {\n return this.toJSON()\n }\n /**\n * Iterates over current live values in index order.\n */\n *[Symbol.iterator](): IterableIterator<T> {\n for (let index = 0; index < this.size; index++) {\n const value = this[index]\n yield value\n }\n }\n /**\n * Calls a function once for each live value in index order.\n *\n * Callback values are live references. Mutating them directly can mutate the\n * list without emitting a delta.\n *\n * @param callback - Function to call for each live value.\n * @param thisArg - Optional `this` value for the callback.\n */\n forEach(\n callback: (value: T, index: number, list: this) => void,\n thisArg?: unknown\n ): void {\n for (let index = 0; index < this.size; index++) {\n void callback.call(thisArg, this[index], index, this)\n }\n }\n}\n"],"mappings":"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","names":["isUuidV7","isUuidV7","prototype","isUuidV7","prototype","isUuidV7","isUuidV7"]}
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "type": "module",
3
3
  "license": "Apache-2.0",
4
4
  "name": "@sovereignbase/convergent-replicated-list",
5
- "version": "1.2.0",
5
+ "version": "1.3.2",
6
6
  "description": "Convergent Replicated List (CR-List), a delta CRDT for an ordered sequence of entries.",
7
7
  "keywords": [
8
8
  "crdt",
@@ -29,7 +29,7 @@
29
29
  "./package.json": "./package.json"
30
30
  },
31
31
  "engines": {
32
- "node": ">=20"
32
+ "node": ">=22"
33
33
  },
34
34
  "files": [
35
35
  "dist",
@@ -62,22 +62,22 @@
62
62
  "@commitlint/cli": "^21.0.1",
63
63
  "@commitlint/config-conventional": "^21.0.1",
64
64
  "@playwright/test": "^1.60.0",
65
- "@types/node": "^25.8.0",
65
+ "@types/node": "^25.9.1",
66
66
  "c8": "^11.0.0",
67
67
  "edge-runtime": "^4.0.1",
68
68
  "fast-glob": "^3.3.3",
69
69
  "husky": "^9.1.7",
70
- "json-joy": "^18.22.0",
70
+ "json-joy": "^18.24.0",
71
71
  "playwright": "^1.60.0",
72
72
  "prettier": "^3.8.3",
73
73
  "tsup": "^8.5.1",
74
74
  "typedoc": "^0.28.19",
75
75
  "typescript": "^5.9.3",
76
- "wrangler": "4.86.0",
76
+ "wrangler": "^4.94.0",
77
77
  "yjs": "^13.6.30"
78
78
  },
79
79
  "dependencies": {
80
- "@sovereignbase/utils": "^1.2.2",
80
+ "@sovereignbase/utils": "^1.3.1",
81
81
  "uuid": "^14.0.0"
82
82
  },
83
83
  "repository": {