@sovereignbase/convergent-replicated-list 1.0.3 → 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -114,7 +114,7 @@ declare class CRList<T> {
114
114
  private readonly state;
115
115
  private readonly eventTarget;
116
116
  /**
117
- * Creates a replicated list from an optional serializable snapshot.
117
+ * Creates a replicated list from an optional detached structured-clone-compatible snapshot.
118
118
  *
119
119
  * @param snapshot - A previously emitted CRList snapshot.
120
120
  */
@@ -166,7 +166,7 @@ declare class CRList<T> {
166
166
  */
167
167
  garbageCollect(frontiers: Array<CRListAck>): void;
168
168
  /**
169
- * Emits the current serializable list snapshot.
169
+ * Emits the current detached structured-clone-compatible list snapshot.
170
170
  */
171
171
  snapshot(): void;
172
172
  /**
@@ -186,13 +186,15 @@ declare class CRList<T> {
186
186
  */
187
187
  removeEventListener<K extends keyof CRListEventMap<T>>(type: K, listener: CRListEventListenerFor<T, K> | null, options?: boolean | EventListenerOptions): void;
188
188
  /**
189
- * Returns a serializable snapshot representation of this list.
189
+ * Returns a detached structured-clone-compatible snapshot of this list.
190
190
  *
191
191
  * Called automatically by `JSON.stringify`.
192
192
  */
193
193
  toJSON(): CRListSnapshot<T>;
194
194
  /**
195
- * Returns this list as a JSON string.
195
+ * Attempts to return this list snapshot as a JSON string.
196
+ *
197
+ * This can fail when list values are not JSON-compatible.
196
198
  */
197
199
  toString(): string;
198
200
  /**
@@ -215,6 +217,22 @@ declare class CRList<T> {
215
217
  * Error codes thrown by {@link CRList}.
216
218
  */
217
219
  type CRListErrorCode = 'VALUE_NOT_CLONEABLE' | 'INDEX_OUT_OF_BOUNDS' | 'LIST_EMPTY' | 'LIST_INTEGRITY_VIOLATION' | 'UPDATE_EXPECTED_AN_ARRAY';
220
+ /**
221
+ * Represents a typed CRList runtime error.
222
+ */
223
+ declare class CRListError extends Error {
224
+ /**
225
+ * The semantic error code for the failure.
226
+ */
227
+ readonly code: CRListErrorCode;
228
+ /**
229
+ * Creates a typed CRList error.
230
+ *
231
+ * @param code - The semantic error code.
232
+ * @param message - An optional human-readable detail message.
233
+ */
234
+ constructor(code: CRListErrorCode, message?: string);
235
+ }
218
236
 
219
237
  /**
220
238
  * Creates a local CRList replica from an optional snapshot.
@@ -223,8 +241,8 @@ type CRListErrorCode = 'VALUE_NOT_CLONEABLE' | 'INDEX_OUT_OF_BOUNDS' | 'LIST_EMP
223
241
  * UUIDv7, linked through their predecessor buckets, and exposed as a live
224
242
  * doubly-linked list.
225
243
  *
226
- * @param snapshot Optional serializable CRList state.
227
- * @returns A hydrated CRList replica.
244
+ * @param snapshot - Optional detached structured-clone-compatible CRList snapshot.
245
+ * @returns - A hydrated CRList replica.
228
246
  *
229
247
  * Time complexity: O(n log n + t + c), worst case O(n^2 + t + c)
230
248
  * - n = snapshot value entry count
@@ -243,9 +261,9 @@ declare function __create<T>(snapshot?: CRListSnapshot<T>): CRListState<T>;
243
261
  * value does not mutate the replica itself. Out-of-bounds and empty list reads
244
262
  * resolve to `undefined` instead of throwing.
245
263
  *
246
- * @param targetIndex Index in the live list.
247
- * @param crListReplica Replica to read from.
248
- * @returns A detached copy of the value at `targetIndex`, or `undefined` when
264
+ * @param targetIndex - Index in the live list.
265
+ * @param crListReplica - Replica to read from.
266
+ * @returns - A detached copy of the value at `targetIndex`, or `undefined` when
249
267
  * no value is present.
250
268
  *
251
269
  * Time complexity: O(d), worst case O(n)
@@ -263,11 +281,11 @@ declare function __read<T>(targetIndex: number, crListReplica: CRListState<T>):
263
281
  * before it, or insert values after it. The returned delta is suitable for
264
282
  * gossip and the returned change describes the local live-view patch.
265
283
  *
266
- * @param listIndex Target index in the live list.
267
- * @param listValues Values to insert or overwrite.
268
- * @param crListReplica Replica to mutate.
269
- * @param mode Mutation mode relative to `listIndex`.
270
- * @returns A local change and gossip delta, or `false` if no mutation occurred.
284
+ * @param listIndex - Target index in the live list.
285
+ * @param listValues - Values to insert or overwrite.
286
+ * @param crListReplica - Replica to mutate.
287
+ * @param mode - Mutation mode relative to `listIndex`.
288
+ * @returns - A local change and gossip delta, or `false` if no mutation occurred.
271
289
  *
272
290
  * Time complexity: O(d + v + r + vk + c), worst case O(vn + c)
273
291
  * - d = distance from cursor to target index
@@ -290,10 +308,10 @@ declare function __update<T>(listIndex: number, listValues: Array<T>, crListRepl
290
308
  * from `startIndex` onward are deleted. With both indexes, the deleted range is
291
309
  * `[startIndex, endIndex)`.
292
310
  *
293
- * @param crListReplica Replica to mutate.
294
- * @param startIndex Inclusive start index. Defaults to `0`.
295
- * @param endIndex Exclusive end index. Defaults to the current list size.
296
- * @returns A local change and gossip delta, or `false` if nothing was deleted.
311
+ * @param crListReplica - Replica to mutate.
312
+ * @param startIndex - Inclusive start index. Defaults to `0`.
313
+ * @param endIndex - Exclusive end index. Defaults to the current list size.
314
+ * @returns - A local change and gossip delta, or `false` if nothing was deleted.
297
315
  *
298
316
  * Time complexity: O(d + qk + r), worst case O(n^2)
299
317
  * - d = distance from cursor to target index
@@ -315,9 +333,9 @@ declare function __delete<T>(crListReplica: CRListState<T>, startIndex?: number,
315
333
  * to the predecessor tree. Tail-append deltas are linked incrementally; deltas
316
334
  * that can affect ordering fall back to deterministic relinking.
317
335
  *
318
- * @param crListReplica Replica to mutate.
319
- * @param crListDelta Remote gossip delta.
320
- * @returns A minimal local change patch, or `false` when the delta is ignored.
336
+ * @param crListReplica - Replica to mutate.
337
+ * @param crListDelta - Remote gossip delta.
338
+ * @returns - A minimal local change patch, or `false` when the delta is ignored.
321
339
  *
322
340
  * Time complexity: O(v + t + c) for tail-append deltas; O(n + t + qk) for tombstone-only deletes; otherwise O(n log n + v + t + m*k + c)
323
341
  * Worst case: O(n^2 + (v + t)n + c)
@@ -339,8 +357,8 @@ declare function __merge<T>(crListReplica: CRListState<T>, crListDelta: CRListDe
339
357
  * The frontier is the greatest tombstone identifier currently retained by the
340
358
  * replica. Peers can use it as input for tombstone garbage collection.
341
359
  *
342
- * @param crListReplica Replica to acknowledge.
343
- * @returns The acknowledgement frontier, or `false` when there are no tombstones.
360
+ * @param crListReplica - Replica to acknowledge.
361
+ * @returns - The acknowledgement frontier, or `false` when there are no tombstones.
344
362
  *
345
363
  * Time complexity: O(t)
346
364
  * - t = replica tombstone count
@@ -355,8 +373,8 @@ declare function __acknowledge<T>(crListReplica: CRListState<T>): CRListAck | fa
355
373
  * The minimum frontier is used as the safe collection boundary. Tombstones less
356
374
  * than or equal to that boundary are removed from the local replica.
357
375
  *
358
- * @param frontiers Acknowledgement frontiers received from peers.
359
- * @param crListReplica Replica whose tombstones will be collected.
376
+ * @param frontiers - Acknowledgement frontiers received from peers.
377
+ * @param crListReplica - Replica whose tombstones will be collected.
360
378
  *
361
379
  * Time complexity: O(f log f + t)
362
380
  * - f = frontier count
@@ -367,13 +385,13 @@ declare function __acknowledge<T>(crListReplica: CRListState<T>): CRListAck | fa
367
385
  declare function __garbageCollect<T>(frontiers: Array<CRListAck>, crListReplica: CRListState<T>): void;
368
386
 
369
387
  /**
370
- * Creates a full serializable CRList snapshot from the current replica state.
388
+ * Creates a full detached structured-clone-compatible CRList snapshot from the current replica state.
371
389
  *
372
390
  * The snapshot contains every live value entry and all retained tombstones. Value
373
391
  * payloads are cloned so callers cannot mutate the replica through the snapshot.
374
392
  *
375
- * @param crListReplica Replica to snapshot.
376
- * @returns A full snapshot suitable for hydration or transport.
393
+ * @param crListReplica - Replica to snapshot.
394
+ * @returns - A full snapshot suitable for hydration or transport.
377
395
  *
378
396
  * Time complexity: O(n + t + c)
379
397
  * - n = replica value entry count
@@ -384,4 +402,4 @@ declare function __garbageCollect<T>(frontiers: Array<CRListAck>, crListReplica:
384
402
  */
385
403
  declare function __snapshot<T>(crListReplica: CRListState<T>): CRListSnapshot<T>;
386
404
 
387
- export { CRList, type CRListAck, type CRListChange, type CRListDelta, type CRListErrorCode, type CRListEventListener, type CRListEventListenerFor, type CRListEventMap, type CRListSnapshot, type CRListSnapshotEntry, type CRListState, type CRListStateEntry, __acknowledge, __create, __delete, __garbageCollect, __merge, __read, __snapshot, __update };
405
+ export { CRList, type CRListAck, type CRListChange, type CRListDelta, CRListError, type CRListErrorCode, type CRListEventListener, type CRListEventListenerFor, type CRListEventMap, type CRListSnapshot, type CRListSnapshotEntry, type CRListState, type CRListStateEntry, __acknowledge, __create, __delete, __garbageCollect, __merge, __read, __snapshot, __update };
package/dist/index.d.ts CHANGED
@@ -114,7 +114,7 @@ declare class CRList<T> {
114
114
  private readonly state;
115
115
  private readonly eventTarget;
116
116
  /**
117
- * Creates a replicated list from an optional serializable snapshot.
117
+ * Creates a replicated list from an optional detached structured-clone-compatible snapshot.
118
118
  *
119
119
  * @param snapshot - A previously emitted CRList snapshot.
120
120
  */
@@ -166,7 +166,7 @@ declare class CRList<T> {
166
166
  */
167
167
  garbageCollect(frontiers: Array<CRListAck>): void;
168
168
  /**
169
- * Emits the current serializable list snapshot.
169
+ * Emits the current detached structured-clone-compatible list snapshot.
170
170
  */
171
171
  snapshot(): void;
172
172
  /**
@@ -186,13 +186,15 @@ declare class CRList<T> {
186
186
  */
187
187
  removeEventListener<K extends keyof CRListEventMap<T>>(type: K, listener: CRListEventListenerFor<T, K> | null, options?: boolean | EventListenerOptions): void;
188
188
  /**
189
- * Returns a serializable snapshot representation of this list.
189
+ * Returns a detached structured-clone-compatible snapshot of this list.
190
190
  *
191
191
  * Called automatically by `JSON.stringify`.
192
192
  */
193
193
  toJSON(): CRListSnapshot<T>;
194
194
  /**
195
- * Returns this list as a JSON string.
195
+ * Attempts to return this list snapshot as a JSON string.
196
+ *
197
+ * This can fail when list values are not JSON-compatible.
196
198
  */
197
199
  toString(): string;
198
200
  /**
@@ -215,6 +217,22 @@ declare class CRList<T> {
215
217
  * Error codes thrown by {@link CRList}.
216
218
  */
217
219
  type CRListErrorCode = 'VALUE_NOT_CLONEABLE' | 'INDEX_OUT_OF_BOUNDS' | 'LIST_EMPTY' | 'LIST_INTEGRITY_VIOLATION' | 'UPDATE_EXPECTED_AN_ARRAY';
220
+ /**
221
+ * Represents a typed CRList runtime error.
222
+ */
223
+ declare class CRListError extends Error {
224
+ /**
225
+ * The semantic error code for the failure.
226
+ */
227
+ readonly code: CRListErrorCode;
228
+ /**
229
+ * Creates a typed CRList error.
230
+ *
231
+ * @param code - The semantic error code.
232
+ * @param message - An optional human-readable detail message.
233
+ */
234
+ constructor(code: CRListErrorCode, message?: string);
235
+ }
218
236
 
219
237
  /**
220
238
  * Creates a local CRList replica from an optional snapshot.
@@ -223,8 +241,8 @@ type CRListErrorCode = 'VALUE_NOT_CLONEABLE' | 'INDEX_OUT_OF_BOUNDS' | 'LIST_EMP
223
241
  * UUIDv7, linked through their predecessor buckets, and exposed as a live
224
242
  * doubly-linked list.
225
243
  *
226
- * @param snapshot Optional serializable CRList state.
227
- * @returns A hydrated CRList replica.
244
+ * @param snapshot - Optional detached structured-clone-compatible CRList snapshot.
245
+ * @returns - A hydrated CRList replica.
228
246
  *
229
247
  * Time complexity: O(n log n + t + c), worst case O(n^2 + t + c)
230
248
  * - n = snapshot value entry count
@@ -243,9 +261,9 @@ declare function __create<T>(snapshot?: CRListSnapshot<T>): CRListState<T>;
243
261
  * value does not mutate the replica itself. Out-of-bounds and empty list reads
244
262
  * resolve to `undefined` instead of throwing.
245
263
  *
246
- * @param targetIndex Index in the live list.
247
- * @param crListReplica Replica to read from.
248
- * @returns A detached copy of the value at `targetIndex`, or `undefined` when
264
+ * @param targetIndex - Index in the live list.
265
+ * @param crListReplica - Replica to read from.
266
+ * @returns - A detached copy of the value at `targetIndex`, or `undefined` when
249
267
  * no value is present.
250
268
  *
251
269
  * Time complexity: O(d), worst case O(n)
@@ -263,11 +281,11 @@ declare function __read<T>(targetIndex: number, crListReplica: CRListState<T>):
263
281
  * before it, or insert values after it. The returned delta is suitable for
264
282
  * gossip and the returned change describes the local live-view patch.
265
283
  *
266
- * @param listIndex Target index in the live list.
267
- * @param listValues Values to insert or overwrite.
268
- * @param crListReplica Replica to mutate.
269
- * @param mode Mutation mode relative to `listIndex`.
270
- * @returns A local change and gossip delta, or `false` if no mutation occurred.
284
+ * @param listIndex - Target index in the live list.
285
+ * @param listValues - Values to insert or overwrite.
286
+ * @param crListReplica - Replica to mutate.
287
+ * @param mode - Mutation mode relative to `listIndex`.
288
+ * @returns - A local change and gossip delta, or `false` if no mutation occurred.
271
289
  *
272
290
  * Time complexity: O(d + v + r + vk + c), worst case O(vn + c)
273
291
  * - d = distance from cursor to target index
@@ -290,10 +308,10 @@ declare function __update<T>(listIndex: number, listValues: Array<T>, crListRepl
290
308
  * from `startIndex` onward are deleted. With both indexes, the deleted range is
291
309
  * `[startIndex, endIndex)`.
292
310
  *
293
- * @param crListReplica Replica to mutate.
294
- * @param startIndex Inclusive start index. Defaults to `0`.
295
- * @param endIndex Exclusive end index. Defaults to the current list size.
296
- * @returns A local change and gossip delta, or `false` if nothing was deleted.
311
+ * @param crListReplica - Replica to mutate.
312
+ * @param startIndex - Inclusive start index. Defaults to `0`.
313
+ * @param endIndex - Exclusive end index. Defaults to the current list size.
314
+ * @returns - A local change and gossip delta, or `false` if nothing was deleted.
297
315
  *
298
316
  * Time complexity: O(d + qk + r), worst case O(n^2)
299
317
  * - d = distance from cursor to target index
@@ -315,9 +333,9 @@ declare function __delete<T>(crListReplica: CRListState<T>, startIndex?: number,
315
333
  * to the predecessor tree. Tail-append deltas are linked incrementally; deltas
316
334
  * that can affect ordering fall back to deterministic relinking.
317
335
  *
318
- * @param crListReplica Replica to mutate.
319
- * @param crListDelta Remote gossip delta.
320
- * @returns A minimal local change patch, or `false` when the delta is ignored.
336
+ * @param crListReplica - Replica to mutate.
337
+ * @param crListDelta - Remote gossip delta.
338
+ * @returns - A minimal local change patch, or `false` when the delta is ignored.
321
339
  *
322
340
  * Time complexity: O(v + t + c) for tail-append deltas; O(n + t + qk) for tombstone-only deletes; otherwise O(n log n + v + t + m*k + c)
323
341
  * Worst case: O(n^2 + (v + t)n + c)
@@ -339,8 +357,8 @@ declare function __merge<T>(crListReplica: CRListState<T>, crListDelta: CRListDe
339
357
  * The frontier is the greatest tombstone identifier currently retained by the
340
358
  * replica. Peers can use it as input for tombstone garbage collection.
341
359
  *
342
- * @param crListReplica Replica to acknowledge.
343
- * @returns The acknowledgement frontier, or `false` when there are no tombstones.
360
+ * @param crListReplica - Replica to acknowledge.
361
+ * @returns - The acknowledgement frontier, or `false` when there are no tombstones.
344
362
  *
345
363
  * Time complexity: O(t)
346
364
  * - t = replica tombstone count
@@ -355,8 +373,8 @@ declare function __acknowledge<T>(crListReplica: CRListState<T>): CRListAck | fa
355
373
  * The minimum frontier is used as the safe collection boundary. Tombstones less
356
374
  * than or equal to that boundary are removed from the local replica.
357
375
  *
358
- * @param frontiers Acknowledgement frontiers received from peers.
359
- * @param crListReplica Replica whose tombstones will be collected.
376
+ * @param frontiers - Acknowledgement frontiers received from peers.
377
+ * @param crListReplica - Replica whose tombstones will be collected.
360
378
  *
361
379
  * Time complexity: O(f log f + t)
362
380
  * - f = frontier count
@@ -367,13 +385,13 @@ declare function __acknowledge<T>(crListReplica: CRListState<T>): CRListAck | fa
367
385
  declare function __garbageCollect<T>(frontiers: Array<CRListAck>, crListReplica: CRListState<T>): void;
368
386
 
369
387
  /**
370
- * Creates a full serializable CRList snapshot from the current replica state.
388
+ * Creates a full detached structured-clone-compatible CRList snapshot from the current replica state.
371
389
  *
372
390
  * The snapshot contains every live value entry and all retained tombstones. Value
373
391
  * payloads are cloned so callers cannot mutate the replica through the snapshot.
374
392
  *
375
- * @param crListReplica Replica to snapshot.
376
- * @returns A full snapshot suitable for hydration or transport.
393
+ * @param crListReplica - Replica to snapshot.
394
+ * @returns - A full snapshot suitable for hydration or transport.
377
395
  *
378
396
  * Time complexity: O(n + t + c)
379
397
  * - n = replica value entry count
@@ -384,4 +402,4 @@ declare function __garbageCollect<T>(frontiers: Array<CRListAck>, crListReplica:
384
402
  */
385
403
  declare function __snapshot<T>(crListReplica: CRListState<T>): CRListSnapshot<T>;
386
404
 
387
- export { CRList, type CRListAck, type CRListChange, type CRListDelta, type CRListErrorCode, type CRListEventListener, type CRListEventListenerFor, type CRListEventMap, type CRListSnapshot, type CRListSnapshotEntry, type CRListState, type CRListStateEntry, __acknowledge, __create, __delete, __garbageCollect, __merge, __read, __snapshot, __update };
405
+ export { CRList, type CRListAck, type CRListChange, type CRListDelta, CRListError, type CRListErrorCode, type CRListEventListener, type CRListEventListenerFor, type CRListEventMap, type CRListSnapshot, type CRListSnapshotEntry, type CRListState, type CRListStateEntry, __acknowledge, __create, __delete, __garbageCollect, __merge, __read, __snapshot, __update };
package/dist/index.js CHANGED
@@ -134,9 +134,10 @@ function flattenAndLinkTrustedState(crListReplica) {
134
134
  crListReplica.size = crListReplica.parentMap.size;
135
135
  }
136
136
 
137
- // src/.helpers/snapshotValueToLinkedListValue/index.ts
137
+ // src/.helpers/transformSnapshotEntryToStateEntry/index.ts
138
138
  import { isUuidV7, safeStructuredClone } from "@sovereignbase/utils";
139
- function snapshotValueToLinkedListValue(valueEntry, crListReplica) {
139
+ function transformSnapshotEntryToStateEntry(valueEntry, crListReplica) {
140
+ if (valueEntry === null || valueEntry === void 0) return void 0;
140
141
  if (!isUuidV7(valueEntry.uuidv7) || crListReplica.tombstones.has(valueEntry.uuidv7) || crListReplica.parentMap.has(valueEntry.uuidv7) || !isUuidV7(valueEntry.predecessor) && valueEntry.predecessor !== "\0" && !crListReplica.tombstones.has(valueEntry.predecessor))
141
142
  return void 0;
142
143
  const [cloned, copiedValue] = safeStructuredClone(valueEntry.value);
@@ -235,7 +236,7 @@ function __create(snapshot) {
235
236
  if (!Object.hasOwn(snapshot, "values") || !Array.isArray(snapshot.values))
236
237
  return crListReplica;
237
238
  for (const valueEntry of snapshot.values) {
238
- const linkedListEntry = snapshotValueToLinkedListValue(
239
+ const linkedListEntry = transformSnapshotEntryToStateEntry(
239
240
  valueEntry,
240
241
  crListReplica
241
242
  );
@@ -300,7 +301,7 @@ function __update(listIndex, listValues, crListReplica, mode) {
300
301
  insertBetween(crListReplica.cursor, linkedListEntry, void 0);
301
302
  void updateEntryToMaps(crListReplica, linkedListEntry, delta);
302
303
  crListReplica.cursor = linkedListEntry;
303
- change[linkedListEntry.index] = linkedListEntry.value;
304
+ change[linkedListEntry.index] = structuredClone(linkedListEntry.value);
304
305
  break;
305
306
  }
306
307
  void walkToIndex(listIndex, crListReplica);
@@ -330,14 +331,14 @@ function __update(listIndex, listValues, crListReplica, mode) {
330
331
  entryToOverwrite.next = void 0;
331
332
  entryToOverwrite.prev = void 0;
332
333
  crListReplica.cursor = linkedListEntry;
333
- change[linkedListEntry.index] = linkedListEntry.value;
334
+ change[linkedListEntry.index] = structuredClone(linkedListEntry.value);
334
335
  break;
335
336
  }
336
337
  case "after": {
337
338
  if (crListReplica.size === 0 && listIndex === 0) {
338
339
  crListReplica.cursor = linkedListEntry;
339
340
  void updateEntryToMaps(crListReplica, linkedListEntry, delta);
340
- change[linkedListEntry.index] = linkedListEntry.value;
341
+ change[linkedListEntry.index] = structuredClone(linkedListEntry.value);
341
342
  break;
342
343
  }
343
344
  if (listIndex === crListReplica.size) {
@@ -363,14 +364,14 @@ function __update(listIndex, listValues, crListReplica, mode) {
363
364
  }
364
365
  void updateEntryToMaps(crListReplica, linkedListEntry, delta);
365
366
  crListReplica.cursor = linkedListEntry;
366
- change[linkedListEntry.index] = linkedListEntry.value;
367
+ change[linkedListEntry.index] = structuredClone(linkedListEntry.value);
367
368
  break;
368
369
  }
369
370
  case "before": {
370
371
  if (crListReplica.size === 0 && listIndex === 0) {
371
372
  crListReplica.cursor = linkedListEntry;
372
373
  void updateEntryToMaps(crListReplica, linkedListEntry, delta);
373
- change[linkedListEntry.index] = linkedListEntry.value;
374
+ change[linkedListEntry.index] = structuredClone(linkedListEntry.value);
374
375
  mode = "after";
375
376
  listIndex = linkedListEntry.index - 1;
376
377
  break;
@@ -392,7 +393,7 @@ function __update(listIndex, listValues, crListReplica, mode) {
392
393
  }
393
394
  void updateEntryToMaps(crListReplica, linkedListEntry, delta);
394
395
  crListReplica.cursor = linkedListEntry;
395
- change[linkedListEntry.index] = linkedListEntry.value;
396
+ change[linkedListEntry.index] = structuredClone(linkedListEntry.value);
396
397
  mode = "after";
397
398
  listIndex = linkedListEntry.index - 1;
398
399
  break;
@@ -468,6 +469,7 @@ function __merge(crListReplica, crListDelta) {
468
469
  return change;
469
470
  }
470
471
  for (const valueEntry of crListDelta.values) {
472
+ if (valueEntry === null || valueEntry === void 0) continue;
471
473
  const existingEntry = crListReplica.parentMap.get(valueEntry.uuidv7);
472
474
  if (existingEntry) {
473
475
  if (crListReplica.tombstones.has(valueEntry.uuidv7) || !isUuidV73(valueEntry.predecessor) && valueEntry.predecessor !== "\0")
@@ -482,7 +484,7 @@ function __merge(crListReplica, crListDelta) {
482
484
  void newVals.push(existingEntry);
483
485
  continue;
484
486
  }
485
- const linkedListEntry = snapshotValueToLinkedListValue(
487
+ const linkedListEntry = transformSnapshotEntryToStateEntry(
486
488
  valueEntry,
487
489
  crListReplica
488
490
  );
@@ -516,28 +518,30 @@ function __merge(crListReplica, crListDelta) {
516
518
  change[index] = void 0;
517
519
  }
518
520
  for (const val of newVals) {
519
- change[val.index] = val.value;
521
+ change[val.index] = structuredClone(val.value);
520
522
  }
521
523
  return change;
522
524
  }
523
525
 
524
526
  // src/core/mags/acknowledge/index.ts
525
527
  function __acknowledge(crListReplica) {
526
- let frontier = false;
528
+ let largest = false;
527
529
  crListReplica.tombstones.forEach((tombstone) => {
528
- if (frontier === false || frontier < tombstone) frontier = tombstone;
530
+ if (largest === false || largest < tombstone) largest = tombstone;
529
531
  });
530
- if (typeof frontier === "string") return frontier;
532
+ if (typeof largest === "string") return largest;
531
533
  return false;
532
534
  }
533
535
 
534
536
  // src/core/mags/garbageCollect/index.ts
537
+ import { isUuidV7 as isUuidV74 } from "@sovereignbase/utils";
535
538
  function __garbageCollect(frontiers, crListReplica) {
536
539
  if (!Array.isArray(frontiers)) return;
537
- const frontier = frontiers.sort().shift();
538
- if (typeof frontier !== "string") return;
540
+ frontiers.sort();
541
+ const smallest = frontiers.find((frontier) => isUuidV74(frontier));
542
+ if (typeof smallest !== "string") return;
539
543
  crListReplica.tombstones.forEach((tombstone, __, tombstones) => {
540
- if (tombstone <= frontier) {
544
+ if (tombstone <= smallest) {
541
545
  tombstones.delete(tombstone);
542
546
  }
543
547
  });
@@ -563,7 +567,7 @@ function __snapshot(crListReplica) {
563
567
  // src/CRList/class.ts
564
568
  var CRList = class {
565
569
  /**
566
- * Creates a replicated list from an optional serializable snapshot.
570
+ * Creates a replicated list from an optional detached structured-clone-compatible snapshot.
567
571
  *
568
572
  * @param snapshot - A previously emitted CRList snapshot.
569
573
  */
@@ -609,7 +613,8 @@ var CRList = class {
609
613
  new CustomEvent("change", { detail: change })
610
614
  );
611
615
  return true;
612
- } catch {
616
+ } catch (error) {
617
+ if (error instanceof CRListError) throw error;
613
618
  return false;
614
619
  }
615
620
  },
@@ -631,7 +636,8 @@ var CRList = class {
631
636
  );
632
637
  }
633
638
  return true;
634
- } catch {
639
+ } catch (error) {
640
+ if (error instanceof CRListError) throw error;
635
641
  return false;
636
642
  }
637
643
  },
@@ -759,7 +765,7 @@ var CRList = class {
759
765
  void __garbageCollect(frontiers, this.state);
760
766
  }
761
767
  /**
762
- * Emits the current serializable list snapshot.
768
+ * Emits the current detached structured-clone-compatible list snapshot.
763
769
  */
764
770
  snapshot() {
765
771
  const snapshot = __snapshot(this.state);
@@ -797,7 +803,7 @@ var CRList = class {
797
803
  );
798
804
  }
799
805
  /**
800
- * Returns a serializable snapshot representation of this list.
806
+ * Returns a detached structured-clone-compatible snapshot of this list.
801
807
  *
802
808
  * Called automatically by `JSON.stringify`.
803
809
  */
@@ -805,7 +811,9 @@ var CRList = class {
805
811
  return __snapshot(this.state);
806
812
  }
807
813
  /**
808
- * Returns this list as a JSON string.
814
+ * Attempts to return this list snapshot as a JSON string.
815
+ *
816
+ * This can fail when list values are not JSON-compatible.
809
817
  */
810
818
  toString() {
811
819
  return JSON.stringify(this);
@@ -848,6 +856,7 @@ var CRList = class {
848
856
  };
849
857
  export {
850
858
  CRList,
859
+ CRListError,
851
860
  __acknowledge,
852
861
  __create,
853
862
  __delete,