@sovereignbase/convergent-replicated-list 1.2.0 → 1.2.1
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 +27 -26
- package/dist/index.cjs +25 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +25 -7
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -313,31 +313,32 @@ npm run bench
|
|
|
313
313
|
|
|
314
314
|
Last measured on Node `v22.14.0` (`win32 x64`):
|
|
315
315
|
|
|
316
|
-
| group | scenario
|
|
317
|
-
|
|
318
|
-
| crud
|
|
319
|
-
| crud
|
|
320
|
-
| crud
|
|
321
|
-
| crud
|
|
322
|
-
| crud
|
|
323
|
-
| crud
|
|
324
|
-
| crud
|
|
325
|
-
| crud
|
|
326
|
-
| mags
|
|
327
|
-
| mags
|
|
328
|
-
| mags
|
|
329
|
-
| mags
|
|
330
|
-
| mags
|
|
331
|
-
| class | constructor / hydrate snapshot
|
|
332
|
-
| class | append after tail
|
|
333
|
-
| class | prepend before middle
|
|
334
|
-
| class | remove from middle
|
|
335
|
-
| class | find near tail
|
|
336
|
-
| class | snapshot
|
|
337
|
-
| class | acknowledge
|
|
338
|
-
| class | garbage collect
|
|
339
|
-
| class | merge ordered deltas
|
|
340
|
-
| class | merge shuffled gossip
|
|
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
|
+
|
|
341
342
|
|
|
|
342
343
|
|
|
343
344
|
These benchmarks compare the work a JavaScript consumer asks each library to do:
|
|
@@ -364,7 +365,7 @@ indexed reads to its WASM-backed document store and lazy proxies, explaining its
|
|
|
364
365
|
very fast random reads and `find` path; its local writes are slower here because
|
|
365
366
|
each write goes through immutable document changes and change generation.
|
|
366
367
|
|
|
367
|
-
Analysis
|
|
368
|
+
Analysis made using ChatGPT-5.5.
|
|
368
369
|
|
|
369
370
|
## License
|
|
370
371
|
|
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
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
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
|
|
138
|
+
void stack.push({
|
|
139
|
+
predecessorIdentifier: sibling.uuidv7,
|
|
140
|
+
siblingIndex: 0
|
|
141
|
+
});
|
|
124
142
|
}
|
|
125
143
|
};
|
|
126
144
|
void appendChildren("\0");
|
package/dist/index.cjs.map
CHANGED
|
@@ -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/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":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACZO,SAAS,gBAAA,CAAoB,aAAA,EAAqC;AACvE,EAAA,GAAA,CAAI,CAAC,aAAA,CAAc,MAAA,EAAQ;AACzB,oBAAA,aAAA,qBAAc,KAAA,6BAAO,KAAA,mBAAM,GAAA;AAC3B,IAAA,aAAA,CAAc,YAAA,EAAc,KAAA,CAAA;AAC5B,IAAA,MAAA;AAAA,EACF;AACA,EAAA,IAAI,MAAA,EAAQ,aAAA,CAAc,IAAA;AAC1B,EAAA,MAAM,QAAA,mBAAU,aAAA,CAAc,KAAA,0BAAS,IAAI,GAAA,CAAI,GAAA;AAC/C,EAAA,KAAK,OAAA,CAAQ,KAAA,CAAM,CAAA;AACnB,EAAA,MAAA,CAAO,aAAA,CAAc,MAAA,CAAO,IAAA;AAC1B,IAAA,aAAA,CAAc,OAAA,EAAS,aAAA,CAAc,MAAA,CAAO,IAAA;AAE9C,EAAA,MAAA,CAAO,MAAA,GAAS,CAAA,EAAG;AACjB,IAAA,KAAA,EAAA;AACA,IAAA,aAAA,CAAc,MAAA,CAAO,MAAA,EAAQ,KAAA;AAC7B,IAAA,KAAK,OAAA,CAAQ,GAAA,CAAI,KAAA,EAAO,aAAA,CAAc,MAAM,CAAA;AAC5C,IAAA,GAAA,CAAI,aAAA,CAAc,MAAA,CAAO,KAAA,IAAS,KAAA,CAAA,EAAW,KAAA;AAC7C,IAAA,aAAA,CAAc,OAAA,EAAS,aAAA,CAAc,MAAA,CAAO,IAAA;AAAA,EAC9C;AACA,EAAA,aAAA,CAAc,MAAA,EAAQ,OAAA;AACtB,EAAA,aAAA,CAAc,YAAA,EAAc,CAAA;AAC9B;ADaA;AACA;AE3BO,IAAM,YAAA,EAAN,MAAA,QAA0B,MAAM;AAAA;AAAA;AAAA;AAAA,EAI5B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQT,WAAA,CAAY,IAAA,EAAuB,OAAA,EAAkB;AACnD,IAAA,MAAM,OAAA,mBAAS,OAAA,UAAW,MAAA;AAC1B,IAAA,KAAA,CAAM,CAAA,4CAAA,EAA+C,MAAM,CAAA,CAAA;AAC/C,IAAA;AACA,IAAA;AACd,EAAA;AACF;AF4BgE;AACA;AG/CxD;AAC8C,EAAA;AACL,IAAA;AACU,EAAA;AACvC,EAAA;AACyC,IAAA;AAChC,MAAA;AACK,MAAA;AAC5B,MAAA;AACK,IAAA;AACuC,MAAA;AAC9C,IAAA;AACF,EAAA;AACmB,EAAA;AACkC,IAAA;AACQ,EAAA;AACN,EAAA;AACK,EAAA;AACL,IAAA;AACX,IAAA;AAC5C,EAAA;AAC0B,EAAA;AACI,IAAA;AAC6B,IAAA;AAC3D,EAAA;AACF;AHiDgE;AACA;AI/ExD;AACiB,EAAA;AACA,EAAA;AACD,EAAA;AACA,EAAA;AACxB;AJiFgE;AACA;AKvFQ;AAC/C,EAAA;AACoB,EAAA;AACxB,EAAA;AACmC,EAAA;AACxC,IAAA;AACC,IAAA;AACA,IAAA;AACf,EAAA;AACoC,EAAA;AACH,EAAA;AACrB,EAAA;AACoD,EAAA;AAKd,IAAA;AAEvB,IAAA;AACa,MAAA;AAEf,MAAA;AACwB,QAAA;AACnC,UAAA;AACR,QAAA;AACqB,QAAA;AACJ,UAAA;AACf,UAAA;AACF,QAAA;AAC4B,QAAA;AACuB,UAAA;AACrD,MAAA;AAEiD,MAAA;AAChC,QAAA;AACf,QAAA;AACF,MAAA;AAEiD,MAAA;AAC3C,MAAA;AACQ,MAAA;AACsC,MAAA;AAEpC,MAAA;AAChB,MAAA;AACqD,MAAA;AACjC,MAAA;AACT,MAAA;AACK,MAAA;AACiB,QAAA;AACjB,QAAA;AACf,MAAA;AACH,IAAA;AACF,EAAA;AACwB,EAAA;AACqB,EAAA;AACiB,EAAA;AAG3C,IAAA;AAEqC,MAAA;AACxD,EAAA;AACkC,EAAA;AACoB,IAAA;AAClB,EAAA;AACO,IAAA;AACpB,EAAA;AACiB,EAAA;AACJ,EAAA;AACd,EAAA;AACuB,EAAA;AAC/C;AL6EgE;AACA;AM3JvC;AAWF;AACuC,EAAA;AAGjC,EAAA;AAMlB,IAAA;AAEF,EAAA;AACc,IAAA;AACD,IAAA;AACM,IAAA;AACjB,IAAA;AACD,IAAA;AACA,IAAA;AACR,EAAA;AACF;AN2IgE;AACA;AOjK9D;AAEyD,EAAA;AACV,EAAA;AACjC,EAAA;AACsB,IAAA;AAC7B,EAAA;AAC8C,IAAA;AACjD,MAAA;AACD,IAAA;AACH,EAAA;AAC0D,EAAA;AAC5C,EAAA;AACc,IAAA;AACA,MAAA;AACD,MAAA;AACM,MAAA;AAC9B,IAAA;AACL;APkKgE;AACA;AQ5LxD;AACoD,EAAA;AACX,EAAA;AAChC,EAAA;AAC+B,EAAA;AACC,EAAA;AACjD;AR8LgE;AACA;AShM9D;AAE6B,EAAA;AACA,EAAA;AAC2B,EAAA;AACM,EAAA;AACR,EAAA;AAChC,EAAA;AACZ,EAAA;AACI,IAAA;AACd,EAAA;AAC6D,EAAA;AAChC,EAAA;AACI,IAAA;AACsB,EAAA;AAChC,EAAA;AACA,EAAA;AACsB,EAAA;AAC/C;ATiMgE;AACA;AUxNxD;AACwD,EAAA;AAChE;AV0NgE;AACA;AWxN9D;AAG6D,EAAA;AAC/B,EAAA;AAC+B,EAAA;AAC/D;AXwNgE;AACA;AYxO1C;AACyC,EAAA;AACpD,IAAA;AACqB,EAAA;AACuB,EAAA;AACvD;AZ0OgE;AACA;AarP5B;AA6BsC;AAClC,EAAA;AAC9B,IAAA;AACE,IAAA;AACK,IAAA;AACE,IAAA;AACa,IAAA;AACiC,IAAA;AACS,IAAA;AACxE,EAAA;AAC0D,EAAA;AAK1C,EAAA;AAE+B,IAAA;AACc,MAAA;AACvD,QAAA;AACyC,MAAA;AAC7C,IAAA;AACF,EAAA;AAGyD,EAAA;AAChD,IAAA;AAEoB,EAAA;AACO,EAAA;AACM,EAAA;AAChB,IAAA;AACtB,MAAA;AACA,MAAA;AACF,IAAA;AACsB,IAAA;AACqC,IAAA;AAGzC,IAAA;AAEuC,MAAA;AACM,MAAA;AAClD,MAAA;AAC0C,MAAA;AACrD,MAAA;AACF,IAAA;AACyB,IAAA;AAC3B,EAAA;AAC4B,EAAA;AACH,IAAA;AAEL,IAAA;AAE2B,IAAA;AACtC,IAAA;AACT,EAAA;AAE2C,EAAA;AAEpC,EAAA;AACT;Ab4MgE;AACA;Ac7Q/C;AACX,EAAA;AACkD,IAAA;AACvB,IAAA;AACvB,EAAA;AACC,IAAA;AACT,EAAA;AACF;Ad+QgE;AACA;AezSnC;AAiCiC;AACb,EAAA;AACF,IAAA;AAChB,EAAA;AACjB,IAAA;AACR,MAAA;AACA,MAAA;AACF,IAAA;AACkC,EAAA;AACH,EAAA;AAC0B,EAAA;AACvB,EAAA;AAChB,IAAA;AAEwC,IAAA;AAChD,MAAA;AACD,MAAA;AACM,MAAA;AACN,MAAA;AACD,MAAA;AACA,MAAA;AACR,IAAA;AAEc,IAAA;AACM,MAAA;AACsB,QAAA;AACN,UAAA;AACL,YAAA;AACqB,YAAA;AACA,YAAA;AACI,4BAAA;AACA,YAAA;AAChD,YAAA;AACF,UAAA;AACkD,UAAA;AAChB,UAAA;AACoB,UAAA;AACH,UAAA;AAC9C,UAAA;AACW,YAAA;AACd,YAAA;AACA,YAAA;AACF,UAAA;AAC4C,UAAA;AACrB,UAAA;AACqB,UAAA;AACS,UAAA;AACL,UAAA;AAChD,UAAA;AACF,QAAA;AACkD,QAAA;AAChB,QAAA;AACK,QAAA;AACU,QAAA;AAEF,QAAA;AACvB,QAAA;AACnB,QAAA;AACc,UAAA;AACjB,UAAA;AACiB,UAAA;AACnB,QAAA;AAC2B,QAAA;AACiB,UAAA;AACnC,YAAA;AACH,cAAA;AACiB,cAAA;AACD,cAAA;AAChB,cAAA;AACF,YAAA;AACF,UAAA;AACF,QAAA;AAC4C,QAAA;AACO,QAAA;AACA,QAAA;AACL,QAAA;AACtB,QAAA;AACA,QAAA;AACD,QAAA;AACK,QAAA;AACyB,QAAA;AACf,QAAA;AACtC,QAAA;AACF,MAAA;AACc,MAAA;AACqC,QAAA;AACxB,UAAA;AACqB,UAAA;AACA,UAAA;AACS,UAAA;AACL,UAAA;AAChD,UAAA;AACF,QAAA;AACsC,QAAA;AACc,UAAA;AAC7C,QAAA;AAC6C,UAAA;AACpD,QAAA;AACkC,QAAA;AACe,QAAA;AAG3C,QAAA;AAEgC,QAAA;AACa,QAAA;AACJ,QAAA;AACrC,QAAA;AAC8C,UAAA;AAC/C,YAAA;AACH,cAAA;AACA,cAAA;AACgB,cAAA;AAChB,cAAA;AACF,YAAA;AACF,UAAA;AACF,QAAA;AAC4C,QAAA;AACrB,QAAA;AACqB,QAAA;AACJ,QAAA;AACa,QAAA;AACL,QAAA;AAChD,QAAA;AACF,MAAA;AACe,MAAA;AACoC,QAAA;AACxB,UAAA;AACqB,UAAA;AACA,UAAA;AACS,UAAA;AACL,UAAA;AACzC,UAAA;AAC6B,UAAA;AACpC,UAAA;AACF,QAAA;AACkD,QAAA;AAChB,QAAA;AACe,QAAA;AACf,QAAA;AACV,QAAA;AACsB,QAAA;AACE,QAAA;AACP,QAAA;AAClC,UAAA;AACH,YAAA;AACc,YAAA;AACE,YAAA;AAChB,YAAA;AACF,UAAA;AACF,QAAA;AAC4C,QAAA;AACrB,QAAA;AACK,QAAA;AACE,QAAA;AACuB,QAAA;AACf,QAAA;AAC/B,QAAA;AAC6B,QAAA;AAEpC,QAAA;AACF,MAAA;AACF,IAAA;AAC6C,IAAA;AAC7C,IAAA;AACF,EAAA;AACuB,EAAA;AACzB;AfoQgE;AACA;AgBpbF;AAC3B,EAAA;AAC0B,EAAA;AAC3B,EAAA;AACiB,EAAA;AAI/C,EAAA;AAE2C,IAAA;AACc,EAAA;AAC9B,EAAA;AAEqB,EAAA;AAChB,EAAA;AAEe,EAAA;AACnC,EAAA;AACkC,EAAA;AAEP,EAAA;AACG,IAAA;AACnB,IAAA;AACsB,IAAA;AACQ,IAAA;AAC3C,IAAA;AACV,IAAA;AACA,IAAA;AACF,EAAA;AAE6C,EAAA;AACG,EAAA;AAG5C,EAAA;AAG0B,EAAA;AAC4B,EAAA;AAC/B,IAAA;AACT,MAAA;AACA,MAAA;AAChB,IAAA;AAEqB,EAAA;AACzB;AhByagE;AACA;AiB3e5B;AA2BT;AACgC,EAAA;AACC,EAAA;AAClB,EAAA;AACP,EAAA;AACf,EAAA;AAGF,EAAA;AAMU,IAAA;AACF,MAAA;AACpB,MAAA;AACF,IAAA;AAC6B,IAAA;AAGvB,IAAA;AAGmD,IAAA;AAGhC,MAAA;AACe,MAAA;AACF,MAAA;AACb,MAAA;AACqB,MAAA;AACe,MAAA;AACd,MAAA;AACQ,MAAA;AACG,MAAA;AAC1D,IAAA;AACF,EAAA;AAKgB,EAAA;AAEkC,IAAA;AACW,MAAA;AACvD,QAAA;AACyC,MAAA;AACS,MAAA;AAC/B,MAAA;AAC4B,QAAA;AACO,QAAA;AACA,QAAA;AACxC,QAAA;AAChB,MAAA;AACF,IAAA;AACF,EAAA;AAKiB,EAAA;AAE0B,IAAA;AACH,IAAA;AACD,IAAA;AACnB,MAAA;AAClB,IAAA;AACO,IAAA;AACT,EAAA;AAE6C,EAAA;AACU,IAAA;AACH,IAAA;AAC/B,IAAA;AACoC,MAAA;AACJ,MAAA;AAC/C,QAAA;AACuD,MAAA;AACpD,MAAA;AACH,QAAA;AACA,QAAA;AACW,QAAA;AACb,MAAA;AACc,MAAA;AACd,MAAA;AACF,IAAA;AACwB,IAAA;AACtB,MAAA;AACA,MAAA;AACF,IAAA;AACsB,IAAA;AAGhB,IAAA;AAEqD,IAAA;AAC1B,IAAA;AACyB,IAAA;AAC1B,MAAA;AACL,QAAA;AACqB,QAAA;AACC,QAAA;AACQ,QAAA;AAChD,MAAA;AACS,QAAA;AAChB,MAAA;AACqD,IAAA;AAC9B,MAAA;AACe,MAAA;AACnB,MAAA;AACI,MAAA;AACqB,MAAA;AACC,MAAA;AACQ,MAAA;AAChD,IAAA;AACS,MAAA;AAChB,IAAA;AACF,EAAA;AACiB,EAAA;AAE4B,IAAA;AAC7C,EAAA;AAE0D,EAAA;AAErB,EAAA;AACnB,IAAA;AAClB,EAAA;AAC2B,EAAA;AACD,IAAA;AAC1B,EAAA;AAEO,EAAA;AACT;AjBobgE;AACA;AkBllB3C;AACc,EAAA;AACoB,EAAA;AACK,IAAA;AACzD,EAAA;AACuC,EAAA;AACjC,EAAA;AACT;AlBolBgE;AACA;AmB9mBvC;AAsBjB;AACyB,EAAA;AACX,EAAA;AACmC,EAAA;AACrB,EAAA;AACoB,EAAA;AACzB,IAAA;AACO,MAAA;AAClC,IAAA;AACD,EAAA;AACH;AnB2lBgE;AACA;AoBvmB3C;AACZ,EAAA;AACgD,IAAA;AAC9B,MAAA;AACyB,QAAA;AACrC,QAAA;AACmB,UAAA;AACD,UAAA;AACM,UAAA;AAC/B,QAAA;AACF,MAAA;AACF,IAAA;AAC+C,IAAA;AACjD,EAAA;AACF;ApBymBgE;AACA;AqB9mBzC;AAAA;AAAA;AAAA;AAAA;AAAA;AAeqB,EAAA;AACL,IAAA;AAC1B,MAAA;AACsB,QAAA;AACf,QAAA;AACE,QAAA;AACJ,QAAA;AACZ,MAAA;AACa,MAAA;AACY,QAAA;AACX,QAAA;AACE,QAAA;AACJ,QAAA;AACZ,MAAA;AACD,IAAA;AAEsB,IAAA;AACQ,MAAA;AACiB,QAAA;AAEY,QAAA;AACnB,QAAA;AACvC,MAAA;AACmB,MAAA;AAC2B,QAAA;AAEY,QAAA;AACN,QAAA;AACpD,MAAA;AAC0B,MAAA;AACoB,QAAA;AACR,QAAA;AAChC,QAAA;AACiD,UAAA;AAC/B,UAAA;AACM,UAAA;AACtB,UAAA;AAC2C,YAAA;AAC3C,UAAA;AAC2C,YAAA;AACxC,UAAA;AACO,QAAA;AAC0B,UAAA;AACjC,UAAA;AACT,QAAA;AACF,MAAA;AAC8B,MAAA;AACgB,QAAA;AACR,QAAA;AAChC,QAAA;AAC+C,UAAA;AAC7B,UAAA;AACM,UAAA;AACtB,UAAA;AAC2C,YAAA;AAC3C,UAAA;AAC2C,YAAA;AACxC,UAAA;AACO,QAAA;AAC0B,UAAA;AACjC,UAAA;AACT,QAAA;AACF,MAAA;AACgB,MAAA;AACP,QAAA;AACoB,UAAA;AAC4B,UAAA;AACvD,QAAA;AACF,MAAA;AAEwC,MAAA;AACM,QAAA;AAEY,QAAA;AAC/C,UAAA;AACgC,YAAA;AAC3B,YAAA;AACE,YAAA;AACE,YAAA;AAChB,UAAA;AACF,QAAA;AAEqD,QAAA;AACvD,MAAA;AACD,IAAA;AACH,EAAA;AAAA;AAAA;AAAA;AAKmB,EAAA;AACC,IAAA;AACpB,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAS8C,EAAA;AACe,IAAA;AAC9C,IAAA;AACa,IAAA;AAC4B,IAAA;AACC,IAAA;AACzD,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAS4C,EAAA;AAC3B,IAAA;AACY,uBAAA;AACnB,MAAA;AACD,MAAA;AACL,MAAA;AACF,IAAA;AACa,IAAA;AACa,IAAA;AAC4B,IAAA;AACC,IAAA;AACzD,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAM4B,EAAA;AAC0B,IAAA;AACvC,IAAA;AACa,IAAA;AAC4B,IAAA;AACC,IAAA;AACzD,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAciB,EAAA;AACwC,IAAA;AACP,IAAA;AACpC,IAAA;AACY,IAAA;AACoC,MAAA;AACjC,QAAA;AACS,MAAA;AAClC,MAAA;AACF,IAAA;AAEO,IAAA;AACT,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AASmC,EAAA;AACO,IAAA;AACe,IAAA;AACzD,EAAA;AAAA;AAAA;AAAA;AAIoB,EAAA;AACkB,IAAA;AACuB,IAAA;AAC7D,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAMkD,EAAA;AACL,IAAA;AAC7C,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAOiB,EAAA;AAC0B,IAAA;AACrC,IAAA;AACqD,MAAA;AAC3D,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAYQ,EAAA;AACgB,IAAA;AACpB,MAAA;AACA,MAAA;AACA,MAAA;AACF,IAAA;AACF,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAaQ,EAAA;AACgB,IAAA;AACpB,MAAA;AACA,MAAA;AACA,MAAA;AACF,IAAA;AACF,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAS4B,EAAA;AACK,IAAA;AACjC,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAMmB,EAAA;AACS,IAAA;AAC5B,EAAA;AAAA;AAAA;AAAA;AAIgE,EAAA;AAC3C,IAAA;AACrB,EAAA;AAAA;AAAA;AAAA;AAIwD,EAAA;AACnC,IAAA;AACrB,EAAA;AAAA;AAAA;AAAA;AAI0C,EAAA;AACQ,IAAA;AACtB,MAAA;AAClB,MAAA;AACR,IAAA;AACF,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAaQ,EAAA;AAC0C,IAAA;AACM,MAAA;AACtD,IAAA;AACF,EAAA;AACF;ArB8kBgE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","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 { 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"]}
|
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
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
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
|
|
138
|
+
void stack.push({
|
|
139
|
+
predecessorIdentifier: sibling.uuidv7,
|
|
140
|
+
siblingIndex: 0
|
|
141
|
+
});
|
|
124
142
|
}
|
|
125
143
|
};
|
|
126
144
|
void appendChildren("\0");
|
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/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 { 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"]}
|
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.
|
|
5
|
+
"version": "1.2.1",
|
|
6
6
|
"description": "Convergent Replicated List (CR-List), a delta CRDT for an ordered sequence of entries.",
|
|
7
7
|
"keywords": [
|
|
8
8
|
"crdt",
|