@sovereignbase/convergent-replicated-list 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -31,6 +31,10 @@ type CRListState<T> = {
31
31
  size: number;
32
32
  /** Current live entry used as the walking cursor. */
33
33
  cursor: CRListStateEntry<T>;
34
+ /** Current zero-based index of `cursor`. */
35
+ cursorIndex?: number;
36
+ /** Opportunistic live-entry cache keyed by observed zero-based index. */
37
+ index?: Map<number, NonNullable<CRListStateEntry<T>>>;
34
38
  /** Deleted UUIDv7 entries retained for gossip and convergence. */
35
39
  tombstones: Set<string>;
36
40
  /** Live entries by UUIDv7. */
@@ -39,7 +43,10 @@ type CRListState<T> = {
39
43
  childrenMap: Map<string, Array<NonNullable<CRListStateEntry<T>>>>;
40
44
  };
41
45
  /**
42
- * Serializable value entry used by snapshots and deltas.
46
+ * Value entry used by snapshots and deltas.
47
+ *
48
+ * `value` is a live payload reference. Consumers that mutate values outside
49
+ * CRList operations must provide their own isolation first.
43
50
  */
44
51
  type CRListSnapshotEntry<T> = {
45
52
  /** Stable UUIDv7 identity for this entry. */
@@ -50,10 +57,10 @@ type CRListSnapshotEntry<T> = {
50
57
  predecessor: string;
51
58
  };
52
59
  /**
53
- * Full serializable CRList state.
60
+ * Full CRList state snapshot.
54
61
  */
55
62
  type CRListSnapshot<T> = {
56
- /** Serializable live values. */
63
+ /** Live values with stable CRDT metadata. */
57
64
  values: Array<CRListSnapshotEntry<T>>;
58
65
  /** Retained deleted UUIDv7 entries. */
59
66
  tombstones: Array<string>;
@@ -67,6 +74,8 @@ type CRListSnapshot<T> = {
67
74
  type CRListChange<T> = Record<number, T | undefined>;
68
75
  /**
69
76
  * Partial CRList state gossiped between replicas.
77
+ *
78
+ * Delta value payloads are live references.
70
79
  */
71
80
  type CRListDelta<T> = Partial<CRListSnapshot<T>>;
72
81
  type CRListAck = string;
@@ -96,11 +105,12 @@ type CRListEventListenerFor<T, K extends string> = K extends keyof CRListEventMa
96
105
  * A convergent replicated list.
97
106
  *
98
107
  * Numeric property access reads and mutates the live list projection:
99
- * `list[0]` reads a detached copy of an entry, `list[0] = value` writes an
108
+ * `list[0]` reads the live value reference, `list[0] = value` writes an
100
109
  * entry, and `delete list[0]` removes one entry. Iteration, `find()`, and
101
- * `forEach()` likewise expose detached copies rather than mutable references
102
- * into the replica state. Local mutations emit `delta` and `change` events;
103
- * remote merges emit `change` events.
110
+ * `forEach()` expose the same live value references. Mutating returned objects
111
+ * directly can mutate replica state without producing a CRDT delta, so callers
112
+ * must isolate values before out-of-band mutation. Local mutations emit `delta`
113
+ * and `change` events; remote merges emit `change` events.
104
114
  *
105
115
  * @typeParam T - The value type stored in the list.
106
116
  */
@@ -108,13 +118,13 @@ declare class CRList<T> {
108
118
  /**
109
119
  * Reads or overwrites an entry in the live list projection by index.
110
120
  *
111
- * Reads return detached copies.
121
+ * Reads return live value references.
112
122
  */
113
123
  [index: number]: T;
114
124
  private readonly state;
115
125
  private readonly eventTarget;
116
126
  /**
117
- * Creates a replicated list from an optional detached structured-clone-compatible snapshot.
127
+ * Creates a replicated list from an optional CRList snapshot.
118
128
  *
119
129
  * @param snapshot - A previously emitted CRList snapshot.
120
130
  */
@@ -148,12 +158,12 @@ declare class CRList<T> {
148
158
  */
149
159
  remove(index: number): void;
150
160
  /**
151
- * Returns the first live value copy matching a predicate in index order.
161
+ * Returns the first live value matching a predicate in index order.
152
162
  *
153
- * Predicate values are detached copies, so mutating them does not mutate the
154
- * list.
163
+ * Predicate values are live references. Mutating them directly can mutate the
164
+ * list without emitting a delta.
155
165
  *
156
- * @param predicate - Function to test each value copy.
166
+ * @param predicate - Function to test each live value.
157
167
  * @param thisArg - Optional `this` value for the predicate.
158
168
  */
159
169
  find(predicate: (this: unknown, value: T, index: number, list: this) => unknown, thisArg?: unknown): T | undefined;
@@ -176,7 +186,10 @@ declare class CRList<T> {
176
186
  */
177
187
  garbageCollect(frontiers: Array<CRListAck>): void;
178
188
  /**
179
- * Emits the current detached structured-clone-compatible list snapshot.
189
+ * Emits the current CRList snapshot.
190
+ *
191
+ * Snapshot value payloads are live references. Mutating them can mutate
192
+ * replica state without emitting a delta.
180
193
  */
181
194
  snapshot(): void;
182
195
  /**
@@ -196,7 +209,10 @@ declare class CRList<T> {
196
209
  */
197
210
  removeEventListener<K extends keyof CRListEventMap<T>>(type: K, listener: CRListEventListenerFor<T, K> | null, options?: boolean | EventListenerOptions): void;
198
211
  /**
199
- * Returns a detached structured-clone-compatible snapshot of this list.
212
+ * Returns a CRList snapshot of this list.
213
+ *
214
+ * Snapshot value payloads are live references. Mutating them can mutate
215
+ * replica state without emitting a delta.
200
216
  *
201
217
  * Called automatically by `JSON.stringify`.
202
218
  */
@@ -208,16 +224,16 @@ declare class CRList<T> {
208
224
  */
209
225
  toString(): string;
210
226
  /**
211
- * Iterates over detached copies of the current live values in index order.
227
+ * Iterates over current live values in index order.
212
228
  */
213
229
  [Symbol.iterator](): IterableIterator<T>;
214
230
  /**
215
- * Calls a function once for each live value copy in index order.
231
+ * Calls a function once for each live value in index order.
216
232
  *
217
- * Callback values are detached copies, so mutating them does not mutate the
218
- * list.
233
+ * Callback values are live references. Mutating them directly can mutate the
234
+ * list without emitting a delta.
219
235
  *
220
- * @param callback - Function to call for each value copy.
236
+ * @param callback - Function to call for each live value.
221
237
  * @param thisArg - Optional `this` value for the callback.
222
238
  */
223
239
  forEach(callback: (value: T, index: number, list: this) => void, thisArg?: unknown): void;
@@ -247,33 +263,33 @@ declare class CRListError extends Error {
247
263
  /**
248
264
  * Creates a local CRList replica from an optional snapshot.
249
265
  *
250
- * Invalid snapshot records are ignored. Accepted values are cloned, indexed by
251
- * UUIDv7, linked through their predecessor buckets, and exposed as a live
252
- * doubly-linked list.
266
+ * Invalid snapshot records are ignored. Accepted values are kept by reference,
267
+ * indexed by UUIDv7, linked through their predecessor buckets, and exposed as a
268
+ * live doubly-linked list projection.
253
269
  *
254
- * @param snapshot - Optional detached structured-clone-compatible CRList snapshot.
270
+ * @param snapshot - Optional CRList snapshot.
255
271
  * @returns - A hydrated CRList replica.
256
272
  *
257
- * Time complexity: O(n log n + t + c), worst case O(n^2 + t + c)
273
+ * Time complexity: O(n log n + t), worst case O(n^2 + t)
258
274
  * - n = snapshot value entry count
259
275
  * - t = snapshot tombstone count
260
- * - c = cloned value payload
261
276
  *
262
- * Space complexity: O(n + t + c)
277
+ * Space complexity: O(n + t)
263
278
  */
264
279
  declare function __create<T>(snapshot?: CRListSnapshot<T>): CRListState<T>;
265
280
 
266
281
  /**
267
282
  * Reads the value at an index in the replica live view.
268
283
  *
269
- * The replica cursor is moved as part of the lookup. Successful reads return a
270
- * detached structured clone of the visible value, so mutating the returned
271
- * value does not mutate the replica itself. Out-of-bounds and empty list reads
272
- * resolve to `undefined` instead of throwing.
284
+ * The replica cursor is moved as part of the lookup. Successful reads return
285
+ * the live value reference stored by the replica. Mutating that value directly
286
+ * can mutate replica state and should only be done when the caller owns an
287
+ * independent value object. Out-of-bounds and empty list reads resolve to
288
+ * `undefined` instead of throwing.
273
289
  *
274
290
  * @param targetIndex - Index in the live list.
275
291
  * @param crListReplica - Replica to read from.
276
- * @returns - A detached copy of the value at `targetIndex`, or `undefined` when
292
+ * @returns - The live value at `targetIndex`, or `undefined` when
277
293
  * no value is present.
278
294
  *
279
295
  * Time complexity: O(d), worst case O(n)
@@ -297,14 +313,13 @@ declare function __read<T>(targetIndex: number, crListReplica: CRListState<T>):
297
313
  * @param mode - Mutation mode relative to `listIndex`.
298
314
  * @returns - A local change and gossip delta, or `false` if no mutation occurred.
299
315
  *
300
- * Time complexity: O(d + v + r + vk + c), worst case O(vn + c)
316
+ * Time complexity: O(d + v + r + vk), worst case O(vn)
301
317
  * - d = distance from cursor to target index
302
318
  * - v = amount of input values
303
319
  * - r = amount of nodes after inserted values whose indexes must be shifted
304
320
  * - k = sibling bucket size when predecessor bucket is updated
305
- * - c = cloned value payload size across all input values
306
321
  *
307
- * Space complexity: O(v + c)
322
+ * Space complexity: O(v)
308
323
  */
309
324
  declare function __update<T>(listIndex: number, listValues: Array<T>, crListReplica: CRListState<T>, mode: 'overwrite' | 'before' | 'after'): {
310
325
  change: CRListChange<T>;
@@ -347,17 +362,16 @@ declare function __delete<T>(crListReplica: CRListState<T>, startIndex?: number,
347
362
  * @param crListDelta - Remote gossip delta.
348
363
  * @returns - A minimal local change patch, or `false` when the delta is ignored.
349
364
  *
350
- * 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)
351
- * Worst case: O(n^2 + (v + t)n + c)
365
+ * 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)
366
+ * Worst case: O(n^2 + (v + t)n)
352
367
  * - n = replica value entry count after merge
353
368
  * - v = delta value entry count
354
369
  * - t = delta tombstone count
355
370
  * - q = amount of live entries deleted by tombstones
356
371
  * - m = entries moved between predecessor buckets
357
372
  * - k = sibling bucket size when entries are removed from buckets
358
- * - c = cloned delta value payload size
359
373
  *
360
- * Space complexity: O(n + v + t + c)
374
+ * Space complexity: O(n + v + t)
361
375
  */
362
376
  declare function __merge<T>(crListReplica: CRListState<T>, crListDelta: CRListDelta<T>): CRListChange<T> | false;
363
377
 
@@ -396,20 +410,20 @@ declare function __acknowledge<T>(crListReplica: CRListState<T>): CRListAck | fa
396
410
  declare function __garbageCollect<T>(frontiers: Array<CRListAck>, crListReplica: CRListState<T>): void;
397
411
 
398
412
  /**
399
- * Creates a full detached structured-clone-compatible CRList snapshot from the current replica state.
413
+ * Creates a full CRList snapshot from the current replica state.
400
414
  *
401
415
  * The snapshot contains every live value entry and all retained tombstones. Value
402
- * payloads are cloned so callers cannot mutate the replica through the snapshot.
416
+ * payloads are live references, so callers must not mutate snapshot values
417
+ * unless they have first isolated them from replica state.
403
418
  *
404
419
  * @param crListReplica - Replica to snapshot.
405
420
  * @returns - A full snapshot suitable for hydration or transport.
406
421
  *
407
- * Time complexity: O(n + t + c)
422
+ * Time complexity: O(n + t)
408
423
  * - n = replica value entry count
409
424
  * - t = replica tombstone count
410
- * - c = cloned value payload size
411
425
  *
412
- * Space complexity: O(n + t + c)
426
+ * Space complexity: O(n + t)
413
427
  */
414
428
  declare function __snapshot<T>(crListReplica: CRListState<T>): CRListSnapshot<T>;
415
429