@loro-extended/change 5.4.0 → 5.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +56 -36
- package/dist/index.d.ts +132 -109
- package/dist/index.js +192 -16
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/change.test.ts +1 -1
- package/src/diff-overlay.test.ts +95 -0
- package/src/diff-overlay.ts +10 -0
- package/src/discriminated-union-tojson.test.ts +2 -2
- package/src/fork-at.test.ts +1 -1
- package/src/functional-helpers.test.ts +50 -1
- package/src/functional-helpers.ts +33 -3
- package/src/index.ts +37 -13
- package/src/overlay-recursion.test.ts +8 -8
- package/src/shallow-fork.test.ts +1 -1
- package/src/shape.ts +7 -7
- package/src/typed-doc.ts +23 -6
- package/src/typed-refs/base.ts +16 -1
- package/src/typed-refs/counter-ref-internals.ts +9 -0
- package/src/typed-refs/doc-ref-internals.ts +1 -0
- package/src/typed-refs/index.ts +17 -0
- package/src/typed-refs/json-compatibility.test.ts +1 -1
- package/src/typed-refs/list-ref-base.ts +87 -3
- package/src/typed-refs/movable-list-ref.test.ts +93 -0
- package/src/typed-refs/record-ref-internals.ts +12 -0
- package/src/typed-refs/struct-ref-internals.ts +12 -0
- package/src/typed-refs/text-ref-internals.ts +69 -3
package/README.md
CHANGED
|
@@ -37,7 +37,7 @@ const schema = Shape.doc({
|
|
|
37
37
|
users: Shape.record(
|
|
38
38
|
Shape.plain.struct({
|
|
39
39
|
name: Shape.plain.string(),
|
|
40
|
-
})
|
|
40
|
+
}),
|
|
41
41
|
),
|
|
42
42
|
});
|
|
43
43
|
|
|
@@ -103,7 +103,7 @@ const blogSchema = Shape.doc({
|
|
|
103
103
|
heading: Shape.text(), // Collaborative headings
|
|
104
104
|
content: Shape.text(), // Collaborative content
|
|
105
105
|
order: Shape.plain.number(), // Plain metadata
|
|
106
|
-
})
|
|
106
|
+
}),
|
|
107
107
|
),
|
|
108
108
|
});
|
|
109
109
|
```
|
|
@@ -141,7 +141,7 @@ const blogSchemaWithDefaults = Shape.doc({
|
|
|
141
141
|
heading: Shape.text(),
|
|
142
142
|
content: Shape.text(),
|
|
143
143
|
order: Shape.plain.number(),
|
|
144
|
-
})
|
|
144
|
+
}),
|
|
145
145
|
),
|
|
146
146
|
});
|
|
147
147
|
|
|
@@ -228,7 +228,7 @@ import { change } from "@loro-extended/change";
|
|
|
228
228
|
// Library code - expose only the ref, not the doc
|
|
229
229
|
class StateMachine {
|
|
230
230
|
private doc: TypedDoc<...>;
|
|
231
|
-
|
|
231
|
+
|
|
232
232
|
get states(): TreeRef<StateNodeShape> {
|
|
233
233
|
return this.doc.states;
|
|
234
234
|
}
|
|
@@ -239,7 +239,7 @@ function addStates(states: TreeRef<StateNodeShape>) {
|
|
|
239
239
|
change(states, draft => {
|
|
240
240
|
const idle = draft.createNode();
|
|
241
241
|
idle.data.name.insert(0, "idle");
|
|
242
|
-
|
|
242
|
+
|
|
243
243
|
const running = draft.createNode();
|
|
244
244
|
running.data.name.insert(0, "running");
|
|
245
245
|
});
|
|
@@ -251,6 +251,7 @@ addStates(machine.states); // No access to the underlying doc needed!
|
|
|
251
251
|
```
|
|
252
252
|
|
|
253
253
|
This pattern is useful for:
|
|
254
|
+
|
|
254
255
|
- **Library APIs**: Expose typed refs without leaking document structure
|
|
255
256
|
- **Component isolation**: Pass refs to components that only need partial access
|
|
256
257
|
- **Testing**: Mock or stub individual refs without full document setup
|
|
@@ -259,37 +260,37 @@ All ref types support `change()`:
|
|
|
259
260
|
|
|
260
261
|
```typescript
|
|
261
262
|
// ListRef
|
|
262
|
-
change(doc.items, draft => {
|
|
263
|
+
change(doc.items, (draft) => {
|
|
263
264
|
draft.push("item1");
|
|
264
265
|
draft.push("item2");
|
|
265
266
|
});
|
|
266
267
|
|
|
267
268
|
// TextRef
|
|
268
|
-
change(doc.title, draft => {
|
|
269
|
+
change(doc.title, (draft) => {
|
|
269
270
|
draft.insert(0, "Hello ");
|
|
270
271
|
draft.insert(6, "World");
|
|
271
272
|
});
|
|
272
273
|
|
|
273
274
|
// CounterRef
|
|
274
|
-
change(doc.count, draft => {
|
|
275
|
+
change(doc.count, (draft) => {
|
|
275
276
|
draft.increment(5);
|
|
276
277
|
draft.decrement(2);
|
|
277
278
|
});
|
|
278
279
|
|
|
279
280
|
// StructRef
|
|
280
|
-
change(doc.profile, draft => {
|
|
281
|
+
change(doc.profile, (draft) => {
|
|
281
282
|
draft.bio.insert(0, "Hello");
|
|
282
283
|
draft.age.increment(1);
|
|
283
284
|
});
|
|
284
285
|
|
|
285
286
|
// RecordRef
|
|
286
|
-
change(doc.users, draft => {
|
|
287
|
+
change(doc.users, (draft) => {
|
|
287
288
|
draft.set("alice", { name: "Alice" });
|
|
288
289
|
draft.set("bob", { name: "Bob" });
|
|
289
290
|
});
|
|
290
291
|
|
|
291
292
|
// TreeRef
|
|
292
|
-
change(doc.tree, draft => {
|
|
293
|
+
change(doc.tree, (draft) => {
|
|
293
294
|
const node = draft.createNode();
|
|
294
295
|
node.data.name.insert(0, "root");
|
|
295
296
|
});
|
|
@@ -298,14 +299,14 @@ change(doc.tree, draft => {
|
|
|
298
299
|
Nested `change()` calls are safe - Loro's commit is idempotent:
|
|
299
300
|
|
|
300
301
|
```typescript
|
|
301
|
-
change(doc.items, outer => {
|
|
302
|
+
change(doc.items, (outer) => {
|
|
302
303
|
outer.push("from outer");
|
|
303
|
-
|
|
304
|
+
|
|
304
305
|
// Nested change on a different ref - works correctly
|
|
305
|
-
change(doc.count, inner => {
|
|
306
|
+
change(doc.count, (inner) => {
|
|
306
307
|
inner.increment(10);
|
|
307
308
|
});
|
|
308
|
-
|
|
309
|
+
|
|
309
310
|
outer.push("still in outer");
|
|
310
311
|
});
|
|
311
312
|
// All mutations are committed
|
|
@@ -336,7 +337,7 @@ const ServerPresenceShape = Shape.plain.struct({
|
|
|
336
337
|
Shape.plain.struct({
|
|
337
338
|
x: Shape.plain.number(),
|
|
338
339
|
y: Shape.plain.number(),
|
|
339
|
-
})
|
|
340
|
+
}),
|
|
340
341
|
),
|
|
341
342
|
tick: Shape.plain.number(),
|
|
342
343
|
});
|
|
@@ -516,7 +517,7 @@ handle.subscribe(
|
|
|
516
517
|
(titles, prev) => {
|
|
517
518
|
// titles: string[], prev: string[] | undefined
|
|
518
519
|
console.log("Titles changed:", titles);
|
|
519
|
-
}
|
|
520
|
+
},
|
|
520
521
|
);
|
|
521
522
|
|
|
522
523
|
// DSL constructs:
|
|
@@ -605,18 +606,18 @@ loro(doc).rawValue; // Unmerged CRDT value
|
|
|
605
606
|
|
|
606
607
|
**RecordRef** (Map-like interface)
|
|
607
608
|
|
|
608
|
-
| Direct Access
|
|
609
|
-
|
|
|
610
|
-
| `get(key)`
|
|
611
|
-
| `set(key, value)`
|
|
612
|
-
| `delete(key)`
|
|
613
|
-
| `has(key)`
|
|
614
|
-
| `keys()`, `values()`, `entries()
|
|
615
|
-
| `size`
|
|
616
|
-
| `replace(values)`
|
|
617
|
-
| `merge(values)`
|
|
618
|
-
| `clear()`
|
|
619
|
-
| `toJSON()`
|
|
609
|
+
| Direct Access | Only via `loro()` |
|
|
610
|
+
| --------------------------------- | ------------------------------ |
|
|
611
|
+
| `get(key)` | `setContainer(key, container)` |
|
|
612
|
+
| `set(key, value)` | `subscribe(callback)` |
|
|
613
|
+
| `delete(key)` | `doc` |
|
|
614
|
+
| `has(key)` | `container` |
|
|
615
|
+
| `keys()`, `values()`, `entries()` | |
|
|
616
|
+
| `size` | |
|
|
617
|
+
| `replace(values)` | |
|
|
618
|
+
| `merge(values)` | |
|
|
619
|
+
| `clear()` | |
|
|
620
|
+
| `toJSON()` | |
|
|
620
621
|
|
|
621
622
|
**TextRef**
|
|
622
623
|
|
|
@@ -668,6 +669,25 @@ function TextEditor({ textRef }: { textRef: TextRef }) {
|
|
|
668
669
|
}
|
|
669
670
|
```
|
|
670
671
|
|
|
672
|
+
### Subscribing to Document Transitions
|
|
673
|
+
|
|
674
|
+
Use `getTransition()` to build `{ before, after }` TypedDocs from a
|
|
675
|
+
subscription event using the diff overlay (no checkout or fork required):
|
|
676
|
+
|
|
677
|
+
```typescript
|
|
678
|
+
import { getTransition, loro } from "@loro-extended/change";
|
|
679
|
+
|
|
680
|
+
const unsubscribe = loro(doc).subscribe((event) => {
|
|
681
|
+
if (event.by === "checkout") return;
|
|
682
|
+
|
|
683
|
+
const { before, after } = getTransition(doc, event);
|
|
684
|
+
|
|
685
|
+
if (!before.users.has("alice") && after.users.has("alice")) {
|
|
686
|
+
console.log("Alice just joined");
|
|
687
|
+
}
|
|
688
|
+
});
|
|
689
|
+
```
|
|
690
|
+
|
|
671
691
|
### Schema Builders
|
|
672
692
|
|
|
673
693
|
#### `Shape.doc(shape)`
|
|
@@ -935,11 +955,11 @@ draft.history.clear();
|
|
|
935
955
|
|
|
936
956
|
**Method semantics:**
|
|
937
957
|
|
|
938
|
-
| Method
|
|
939
|
-
|
|
|
940
|
-
| `replace(values)`
|
|
941
|
-
| `merge(values)`
|
|
942
|
-
| `clear()`
|
|
958
|
+
| Method | Adds new | Updates existing | Removes absent |
|
|
959
|
+
| ----------------- | -------- | ---------------- | -------------- |
|
|
960
|
+
| `replace(values)` | ✅ | ✅ | ✅ |
|
|
961
|
+
| `merge(values)` | ✅ | ✅ | ❌ |
|
|
962
|
+
| `clear()` | ❌ | ❌ | ✅ (all) |
|
|
943
963
|
|
|
944
964
|
These methods batch all operations into a single commit, avoiding multiple subscription notifications.
|
|
945
965
|
|
|
@@ -957,7 +977,7 @@ const StateNodeDataShape = Shape.struct({
|
|
|
957
977
|
name: Shape.plain.string(),
|
|
958
978
|
rego: Shape.plain.string(),
|
|
959
979
|
description: Shape.plain.string().nullable(),
|
|
960
|
-
})
|
|
980
|
+
}),
|
|
961
981
|
),
|
|
962
982
|
});
|
|
963
983
|
|
|
@@ -1099,7 +1119,7 @@ const todoSchema = Shape.doc({
|
|
|
1099
1119
|
id: Shape.plain.string(),
|
|
1100
1120
|
text: Shape.plain.string(),
|
|
1101
1121
|
done: Shape.plain.boolean(),
|
|
1102
|
-
})
|
|
1122
|
+
}),
|
|
1103
1123
|
),
|
|
1104
1124
|
});
|
|
1105
1125
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { LoroDoc, ContainerID, Diff, PeerID, Container, LoroTreeNode, TreeID, LoroEventBatch, Subscription, LoroText, LoroList, LoroMovableList, LoroMap, LoroTree, LoroCounter, Value } from 'loro-crdt';
|
|
2
2
|
|
|
3
3
|
type Prev = [never, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
|
|
4
4
|
/**
|
|
@@ -105,6 +105,114 @@ type JsonPatchTestOperation = {
|
|
|
105
105
|
type JsonPatchOperation = JsonPatchAddOperation | JsonPatchRemoveOperation | JsonPatchReplaceOperation | JsonPatchMoveOperation | JsonPatchCopyOperation | JsonPatchTestOperation;
|
|
106
106
|
type JsonPatch = JsonPatchOperation[];
|
|
107
107
|
|
|
108
|
+
/**
|
|
109
|
+
* Symbol for internal methods that should not be enumerable or accessible to users.
|
|
110
|
+
* Used to hide implementation details like absorbPlainValues(), getTypedRefParams(), etc.
|
|
111
|
+
*
|
|
112
|
+
* This achieves Success Criteria #7 from loro-api-refactor.md:
|
|
113
|
+
* "Internal methods hidden - Via Symbol, not enumerable"
|
|
114
|
+
*/
|
|
115
|
+
declare const INTERNAL_SYMBOL: unique symbol;
|
|
116
|
+
/**
|
|
117
|
+
* Minimal interface for refs that only need absorbPlainValues.
|
|
118
|
+
* Used by TreeNodeRef which doesn't extend TypedRef.
|
|
119
|
+
*/
|
|
120
|
+
interface RefInternalsBase {
|
|
121
|
+
/** Absorb mutated plain values back into Loro containers */
|
|
122
|
+
absorbPlainValues(): void;
|
|
123
|
+
/** Force materialization of the container and its nested containers */
|
|
124
|
+
materialize(): void;
|
|
125
|
+
}
|
|
126
|
+
type DiffOverlay$1 = ReadonlyMap<ContainerID, Diff>;
|
|
127
|
+
type TypedRefParams<Shape extends DocShape | ContainerShape> = {
|
|
128
|
+
shape: Shape;
|
|
129
|
+
placeholder?: Infer<Shape>;
|
|
130
|
+
getContainer: () => ShapeToContainer<Shape>;
|
|
131
|
+
autoCommit?: boolean;
|
|
132
|
+
batchedMutation?: boolean;
|
|
133
|
+
getDoc: () => LoroDoc;
|
|
134
|
+
overlay?: DiffOverlay$1;
|
|
135
|
+
};
|
|
136
|
+
/**
|
|
137
|
+
* Abstract base class for all ref internal implementations.
|
|
138
|
+
* Contains shared logic that was previously in TypedRef.createBaseInternals().
|
|
139
|
+
*
|
|
140
|
+
* Subclasses implement specific behavior for each ref type.
|
|
141
|
+
*/
|
|
142
|
+
declare abstract class BaseRefInternals<Shape extends DocShape | ContainerShape> implements RefInternalsBase {
|
|
143
|
+
protected readonly params: TypedRefParams<Shape>;
|
|
144
|
+
protected cachedContainer: ShapeToContainer<Shape> | undefined;
|
|
145
|
+
protected loroNamespace: LoroRefBase | undefined;
|
|
146
|
+
private _suppressAutoCommit;
|
|
147
|
+
constructor(params: TypedRefParams<Shape>);
|
|
148
|
+
/** Get the underlying Loro container (cached) */
|
|
149
|
+
getContainer(): ShapeToContainer<Shape>;
|
|
150
|
+
/** Commit changes if autoCommit is enabled and not suppressed */
|
|
151
|
+
commitIfAuto(): void;
|
|
152
|
+
/**
|
|
153
|
+
* Temporarily suppress auto-commit during batch operations.
|
|
154
|
+
* Used by assignPlainValueToTypedRef() to batch multiple property assignments.
|
|
155
|
+
*/
|
|
156
|
+
setSuppressAutoCommit(suppress: boolean): void;
|
|
157
|
+
/** Check if auto-commit is currently suppressed */
|
|
158
|
+
isSuppressAutoCommit(): boolean;
|
|
159
|
+
/** Get the shape for this ref */
|
|
160
|
+
getShape(): Shape;
|
|
161
|
+
/** Get the placeholder value */
|
|
162
|
+
getPlaceholder(): Infer<Shape> | undefined;
|
|
163
|
+
/** Check if autoCommit is enabled */
|
|
164
|
+
getAutoCommit(): boolean;
|
|
165
|
+
/** Check if in batched mutation mode */
|
|
166
|
+
getBatchedMutation(): boolean;
|
|
167
|
+
/** Get the LoroDoc */
|
|
168
|
+
getDoc(): LoroDoc;
|
|
169
|
+
/** Get the diff overlay map (if provided) */
|
|
170
|
+
getOverlay(): DiffOverlay$1 | undefined;
|
|
171
|
+
/**
|
|
172
|
+
* Get the TypedRefParams needed to recreate this ref.
|
|
173
|
+
* Used by change() to create draft refs with modified params.
|
|
174
|
+
*
|
|
175
|
+
* Returns a new params object with the same shape, placeholder, getContainer, and getDoc,
|
|
176
|
+
* but allows overriding autoCommit and batchedMutation for draft creation.
|
|
177
|
+
*/
|
|
178
|
+
getTypedRefParams(): TypedRefParams<Shape>;
|
|
179
|
+
/** Get the loro namespace (cached) */
|
|
180
|
+
getLoroNamespace(): LoroRefBase;
|
|
181
|
+
/** Absorb mutated plain values back into Loro containers - subclasses override */
|
|
182
|
+
abstract absorbPlainValues(): void;
|
|
183
|
+
/** Force materialization of the container and its nested containers */
|
|
184
|
+
materialize(): void;
|
|
185
|
+
/** Create the loro() namespace object - subclasses override for specific types */
|
|
186
|
+
protected createLoroNamespace(): LoroRefBase;
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Base class for all typed refs.
|
|
190
|
+
*
|
|
191
|
+
* All internal methods are accessed via [INTERNAL_SYMBOL] to prevent
|
|
192
|
+
* namespace collisions with user data properties.
|
|
193
|
+
*
|
|
194
|
+
* Uses the Facade + Implementation pattern:
|
|
195
|
+
* - TypedRef is the thin public facade
|
|
196
|
+
* - BaseRefInternals subclasses contain all implementation logic
|
|
197
|
+
*/
|
|
198
|
+
declare abstract class TypedRef<Shape extends DocShape | ContainerShape> {
|
|
199
|
+
/**
|
|
200
|
+
* Internal implementation accessed via Symbol.
|
|
201
|
+
* Subclasses must set this to their specific internals class instance.
|
|
202
|
+
*/
|
|
203
|
+
abstract [INTERNAL_SYMBOL]: BaseRefInternals<Shape>;
|
|
204
|
+
/**
|
|
205
|
+
* Serializes the ref to a plain JSON-compatible value.
|
|
206
|
+
* Returns the plain type inferred from the shape.
|
|
207
|
+
*/
|
|
208
|
+
abstract toJSON(): Infer<Shape>;
|
|
209
|
+
/**
|
|
210
|
+
* Access the loro() namespace via the well-known symbol.
|
|
211
|
+
* This is used by the loro() function to access CRDT internals.
|
|
212
|
+
*/
|
|
213
|
+
get [LORO_SYMBOL](): LoroRefBase;
|
|
214
|
+
}
|
|
215
|
+
|
|
108
216
|
/** biome-ignore-all lint/suspicious/noExplicitAny: fix later */
|
|
109
217
|
|
|
110
218
|
/**
|
|
@@ -143,6 +251,10 @@ type Frontiers = {
|
|
|
143
251
|
peer: PeerID;
|
|
144
252
|
counter: number;
|
|
145
253
|
}[];
|
|
254
|
+
type CreateTypedDocOptions = {
|
|
255
|
+
doc?: LoroDoc;
|
|
256
|
+
overlay?: DiffOverlay$1;
|
|
257
|
+
};
|
|
146
258
|
type TypedDoc<Shape extends DocShape> = Mutable<Shape> & {
|
|
147
259
|
/**
|
|
148
260
|
* The primary method of mutating typed documents.
|
|
@@ -208,7 +320,7 @@ type TypedDoc<Shape extends DocShape> = Mutable<Shape> & {
|
|
|
208
320
|
* Returns a proxied document where schema properties are accessed directly.
|
|
209
321
|
*
|
|
210
322
|
* @param shape - The document schema (with optional .placeholder() values)
|
|
211
|
-
* @param
|
|
323
|
+
* @param options - Optional existing LoroDoc or diff overlay
|
|
212
324
|
* @returns A proxied TypedDoc with direct schema access
|
|
213
325
|
*
|
|
214
326
|
* @example
|
|
@@ -239,111 +351,7 @@ type TypedDoc<Shape extends DocShape> = Mutable<Shape> & {
|
|
|
239
351
|
* loro(doc).subscribe(callback);
|
|
240
352
|
* ```
|
|
241
353
|
*/
|
|
242
|
-
declare function createTypedDoc<Shape extends DocShape>(shape: Shape,
|
|
243
|
-
|
|
244
|
-
/**
|
|
245
|
-
* Symbol for internal methods that should not be enumerable or accessible to users.
|
|
246
|
-
* Used to hide implementation details like absorbPlainValues(), getTypedRefParams(), etc.
|
|
247
|
-
*
|
|
248
|
-
* This achieves Success Criteria #7 from loro-api-refactor.md:
|
|
249
|
-
* "Internal methods hidden - Via Symbol, not enumerable"
|
|
250
|
-
*/
|
|
251
|
-
declare const INTERNAL_SYMBOL: unique symbol;
|
|
252
|
-
/**
|
|
253
|
-
* Minimal interface for refs that only need absorbPlainValues.
|
|
254
|
-
* Used by TreeNodeRef which doesn't extend TypedRef.
|
|
255
|
-
*/
|
|
256
|
-
interface RefInternalsBase {
|
|
257
|
-
/** Absorb mutated plain values back into Loro containers */
|
|
258
|
-
absorbPlainValues(): void;
|
|
259
|
-
/** Force materialization of the container and its nested containers */
|
|
260
|
-
materialize(): void;
|
|
261
|
-
}
|
|
262
|
-
type TypedRefParams<Shape extends DocShape | ContainerShape> = {
|
|
263
|
-
shape: Shape;
|
|
264
|
-
placeholder?: Infer<Shape>;
|
|
265
|
-
getContainer: () => ShapeToContainer<Shape>;
|
|
266
|
-
autoCommit?: boolean;
|
|
267
|
-
batchedMutation?: boolean;
|
|
268
|
-
getDoc: () => LoroDoc;
|
|
269
|
-
};
|
|
270
|
-
/**
|
|
271
|
-
* Abstract base class for all ref internal implementations.
|
|
272
|
-
* Contains shared logic that was previously in TypedRef.createBaseInternals().
|
|
273
|
-
*
|
|
274
|
-
* Subclasses implement specific behavior for each ref type.
|
|
275
|
-
*/
|
|
276
|
-
declare abstract class BaseRefInternals<Shape extends DocShape | ContainerShape> implements RefInternalsBase {
|
|
277
|
-
protected readonly params: TypedRefParams<Shape>;
|
|
278
|
-
protected cachedContainer: ShapeToContainer<Shape> | undefined;
|
|
279
|
-
protected loroNamespace: LoroRefBase | undefined;
|
|
280
|
-
private _suppressAutoCommit;
|
|
281
|
-
constructor(params: TypedRefParams<Shape>);
|
|
282
|
-
/** Get the underlying Loro container (cached) */
|
|
283
|
-
getContainer(): ShapeToContainer<Shape>;
|
|
284
|
-
/** Commit changes if autoCommit is enabled and not suppressed */
|
|
285
|
-
commitIfAuto(): void;
|
|
286
|
-
/**
|
|
287
|
-
* Temporarily suppress auto-commit during batch operations.
|
|
288
|
-
* Used by assignPlainValueToTypedRef() to batch multiple property assignments.
|
|
289
|
-
*/
|
|
290
|
-
setSuppressAutoCommit(suppress: boolean): void;
|
|
291
|
-
/** Check if auto-commit is currently suppressed */
|
|
292
|
-
isSuppressAutoCommit(): boolean;
|
|
293
|
-
/** Get the shape for this ref */
|
|
294
|
-
getShape(): Shape;
|
|
295
|
-
/** Get the placeholder value */
|
|
296
|
-
getPlaceholder(): Infer<Shape> | undefined;
|
|
297
|
-
/** Check if autoCommit is enabled */
|
|
298
|
-
getAutoCommit(): boolean;
|
|
299
|
-
/** Check if in batched mutation mode */
|
|
300
|
-
getBatchedMutation(): boolean;
|
|
301
|
-
/** Get the LoroDoc */
|
|
302
|
-
getDoc(): LoroDoc;
|
|
303
|
-
/**
|
|
304
|
-
* Get the TypedRefParams needed to recreate this ref.
|
|
305
|
-
* Used by change() to create draft refs with modified params.
|
|
306
|
-
*
|
|
307
|
-
* Returns a new params object with the same shape, placeholder, getContainer, and getDoc,
|
|
308
|
-
* but allows overriding autoCommit and batchedMutation for draft creation.
|
|
309
|
-
*/
|
|
310
|
-
getTypedRefParams(): TypedRefParams<Shape>;
|
|
311
|
-
/** Get the loro namespace (cached) */
|
|
312
|
-
getLoroNamespace(): LoroRefBase;
|
|
313
|
-
/** Absorb mutated plain values back into Loro containers - subclasses override */
|
|
314
|
-
abstract absorbPlainValues(): void;
|
|
315
|
-
/** Force materialization of the container and its nested containers */
|
|
316
|
-
materialize(): void;
|
|
317
|
-
/** Create the loro() namespace object - subclasses override for specific types */
|
|
318
|
-
protected createLoroNamespace(): LoroRefBase;
|
|
319
|
-
}
|
|
320
|
-
/**
|
|
321
|
-
* Base class for all typed refs.
|
|
322
|
-
*
|
|
323
|
-
* All internal methods are accessed via [INTERNAL_SYMBOL] to prevent
|
|
324
|
-
* namespace collisions with user data properties.
|
|
325
|
-
*
|
|
326
|
-
* Uses the Facade + Implementation pattern:
|
|
327
|
-
* - TypedRef is the thin public facade
|
|
328
|
-
* - BaseRefInternals subclasses contain all implementation logic
|
|
329
|
-
*/
|
|
330
|
-
declare abstract class TypedRef<Shape extends DocShape | ContainerShape> {
|
|
331
|
-
/**
|
|
332
|
-
* Internal implementation accessed via Symbol.
|
|
333
|
-
* Subclasses must set this to their specific internals class instance.
|
|
334
|
-
*/
|
|
335
|
-
abstract [INTERNAL_SYMBOL]: BaseRefInternals<Shape>;
|
|
336
|
-
/**
|
|
337
|
-
* Serializes the ref to a plain JSON-compatible value.
|
|
338
|
-
* Returns the plain type inferred from the shape.
|
|
339
|
-
*/
|
|
340
|
-
abstract toJSON(): Infer<Shape>;
|
|
341
|
-
/**
|
|
342
|
-
* Access the loro() namespace via the well-known symbol.
|
|
343
|
-
* This is used by the loro() function to access CRDT internals.
|
|
344
|
-
*/
|
|
345
|
-
get [LORO_SYMBOL](): LoroRefBase;
|
|
346
|
-
}
|
|
354
|
+
declare function createTypedDoc<Shape extends DocShape>(shape: Shape, options?: CreateTypedDocOptions): TypedDoc<Shape>;
|
|
347
355
|
|
|
348
356
|
/**
|
|
349
357
|
* Internal implementation for CounterRef.
|
|
@@ -386,6 +394,8 @@ declare class CounterRef extends TypedRef<CounterContainerShape> {
|
|
|
386
394
|
*/
|
|
387
395
|
declare class ListRefBaseInternals<NestedShape extends ContainerOrValueShape, Item = NestedShape["_plain"], MutableItem = NestedShape["_mutable"]> extends BaseRefInternals<any> {
|
|
388
396
|
private itemCache;
|
|
397
|
+
private overlayListCache?;
|
|
398
|
+
getOverlayList(): Item[] | undefined;
|
|
389
399
|
/** Get typed ref params for creating child refs at an index */
|
|
390
400
|
getChildTypedRefParams(index: number, shape: ContainerShape): TypedRefParams<ContainerShape>;
|
|
391
401
|
/** Get item for predicate functions (returns plain value) */
|
|
@@ -1383,7 +1393,7 @@ interface AnyValueShape extends Shape<Value, Value, undefined> {
|
|
|
1383
1393
|
readonly _type: "value";
|
|
1384
1394
|
readonly valueType: "any";
|
|
1385
1395
|
}
|
|
1386
|
-
type ValueShape = AnyValueShape |
|
|
1396
|
+
type ValueShape = AnyValueShape | ArrayValueShape | BooleanValueShape | DiscriminatedUnionValueShape | NullValueShape | NumberValueShape | RecordValueShape | StringValueShape | StructValueShape | Uint8ArrayValueShape | UndefinedValueShape | UnionValueShape;
|
|
1387
1397
|
type ContainerOrValueShape = ContainerShape | ValueShape;
|
|
1388
1398
|
interface Shape<Plain, Mutable, Placeholder = Plain> {
|
|
1389
1399
|
readonly _type: string;
|
|
@@ -1561,6 +1571,9 @@ declare function derivePlaceholder<T extends DocShape>(schema: T): InferPlacehol
|
|
|
1561
1571
|
*/
|
|
1562
1572
|
declare function deriveShapePlaceholder(shape: ContainerOrValueShape): unknown;
|
|
1563
1573
|
|
|
1574
|
+
type DiffOverlay = ReadonlyMap<ContainerID, Diff>;
|
|
1575
|
+
declare function createDiffOverlay(doc: LoroDoc, batch: LoroEventBatch): DiffOverlay;
|
|
1576
|
+
|
|
1564
1577
|
/**
|
|
1565
1578
|
* The primary method of mutating typed documents and refs.
|
|
1566
1579
|
* Batches multiple mutations into a single transaction.
|
|
@@ -1777,6 +1790,16 @@ declare function forkAt<Shape extends DocShape>(doc: TypedDoc<Shape>, frontiers:
|
|
|
1777
1790
|
declare function shallowForkAt<Shape extends DocShape>(doc: TypedDoc<Shape>, frontiers: Frontiers, options?: {
|
|
1778
1791
|
preservePeerId?: boolean;
|
|
1779
1792
|
}): TypedDoc<Shape>;
|
|
1793
|
+
type Transition<Shape extends DocShape> = {
|
|
1794
|
+
before: TypedDoc<Shape>;
|
|
1795
|
+
after: TypedDoc<Shape>;
|
|
1796
|
+
};
|
|
1797
|
+
/**
|
|
1798
|
+
* Build a `{ before, after }` transition from a TypedDoc and a Loro event batch.
|
|
1799
|
+
* Uses a reverse diff overlay to compute the "before" view without checkout.
|
|
1800
|
+
* Throws on checkout events to avoid time-travel transitions.
|
|
1801
|
+
*/
|
|
1802
|
+
declare function getTransition<Shape extends DocShape>(doc: TypedDoc<Shape>, event: LoroEventBatch): Transition<Shape>;
|
|
1780
1803
|
|
|
1781
1804
|
/**
|
|
1782
1805
|
* Overlays CRDT state with placeholder defaults
|
|
@@ -1930,4 +1953,4 @@ declare function replayDiff(doc: LoroDoc, diff: [ContainerID, Diff][]): void;
|
|
|
1930
1953
|
*/
|
|
1931
1954
|
declare function validatePlaceholder<T extends DocShape>(placeholder: unknown, schema: T): Infer<T>;
|
|
1932
1955
|
|
|
1933
|
-
export { type AnyContainerShape, type AnyValueShape, type ArrayValueShape, type ContainerOrValueShape, type ContainerShape, type CounterContainerShape, CounterRef, type DiscriminatedUnionValueShape, type DocShape, type Frontiers, type Infer, type InferMutableType, type InferPlaceholderType, type InferRaw, LORO_SYMBOL, type ListContainerShape, ListRef, type LoroCounterRef, type LoroListRef, type LoroMapRef, type LoroRefBase, type LoroTextRef, type LoroTreeRef, type LoroTypedDocRef, type MovableListContainerShape, MovableListRef, type Mutable, type NumberValueShape, type PathBuilder, type PathNode, type PathSegment, type PathSelector, type RecordContainerShape, RecordRef, type RecordValueShape, type ContainerType as RootContainerType, Shape, type StringValueShape, type StructContainerShape, type StructRef, type StructValueShape, type TextContainerShape, TextRef, type TreeContainerShape, type TreeNodeJSON, TreeNodeRef, TreeRef, type TreeRefInterface, type TypedDoc, type UnionValueShape, type ValueShape, type WithNullable, type WithPlaceholder, change, compileToJsonPath, createPathBuilder, createPlaceholderProxy, createTypedDoc, derivePlaceholder, deriveShapePlaceholder, evaluatePath, evaluatePathOnValue, fork, forkAt, getLoroContainer, getLoroDoc, hasWildcard, loro, mergeValue, overlayPlaceholder, replayDiff, shallowForkAt, validatePlaceholder };
|
|
1956
|
+
export { type AnyContainerShape, type AnyValueShape, type ArrayValueShape, type BooleanValueShape, type ContainerOrValueShape, type ContainerShape, type CounterContainerShape, CounterRef, type DiffOverlay$1 as DiffOverlay, type DiscriminatedUnionValueShape, type DocShape, type Frontiers, type Infer, type InferMutableType, type InferPlaceholderType, type InferRaw, LORO_SYMBOL, type ListContainerShape, ListRef, type LoroCounterRef, type LoroListRef, type LoroMapRef, type LoroRefBase, type LoroTextRef, type LoroTreeRef, type LoroTypedDocRef, type MovableListContainerShape, MovableListRef, type Mutable, type NullValueShape, type NumberValueShape, type PathBuilder, type PathNode, type PathSegment, type PathSelector, type RecordContainerShape, RecordRef, type RecordValueShape, type ContainerType as RootContainerType, Shape, type StringValueShape, type StructContainerShape, type StructRef, type StructValueShape, type TextContainerShape, TextRef, type Transition, type TreeContainerShape, type TreeNodeJSON, TreeNodeRef, TreeRef, type TreeRefInterface, type TypedDoc, type Uint8ArrayValueShape, type UndefinedValueShape, type UnionValueShape, type ValueShape, type WithNullable, type WithPlaceholder, change, compileToJsonPath, createDiffOverlay, createPathBuilder, createPlaceholderProxy, createTypedDoc, derivePlaceholder, deriveShapePlaceholder, evaluatePath, evaluatePathOnValue, fork, forkAt, getLoroContainer, getLoroDoc, getTransition, hasWildcard, loro, mergeValue, overlayPlaceholder, replayDiff, shallowForkAt, validatePlaceholder };
|