reptree 0.4.0 → 0.6.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/README.md +59 -108
- package/dist/index.cjs +37 -177
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +17 -32
- package/dist/index.d.ts +17 -32
- package/dist/index.js +37 -164
- package/dist/index.js.map +1 -1
- package/package.json +2 -3
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import * as Y from 'yjs';
|
|
2
|
-
|
|
3
1
|
interface OpId {
|
|
4
2
|
readonly counter: number;
|
|
5
3
|
readonly peerId: string;
|
|
@@ -26,18 +24,8 @@ type TreeVertexId = string;
|
|
|
26
24
|
/**
|
|
27
25
|
* Serializable CRDT data for operations
|
|
28
26
|
*/
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
value: Uint8Array;
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Property type for state - includes Y.Doc for runtime usage
|
|
35
|
-
*/
|
|
36
|
-
type VertexPropertyType = string | number | boolean | string[] | number[] | boolean[] | undefined | Y.Doc;
|
|
37
|
-
/**
|
|
38
|
-
* Property type for operations - includes CRDTType instead of Y.Doc
|
|
39
|
-
*/
|
|
40
|
-
type VertexPropertyTypeInOperation = string | number | boolean | string[] | number[] | boolean[] | undefined | CRDTType;
|
|
27
|
+
/** Property type for state */
|
|
28
|
+
type VertexPropertyType = string | number | boolean | string[] | number[] | boolean[] | undefined;
|
|
41
29
|
type TreeVertexProperty = {
|
|
42
30
|
readonly key: string;
|
|
43
31
|
readonly value: VertexPropertyType;
|
|
@@ -79,17 +67,15 @@ interface SetVertexProperty {
|
|
|
79
67
|
id: OpId;
|
|
80
68
|
targetId: string;
|
|
81
69
|
key: string;
|
|
82
|
-
value:
|
|
70
|
+
value: VertexPropertyType;
|
|
83
71
|
transient: boolean;
|
|
84
72
|
}
|
|
85
73
|
type VertexOperation = MoveVertex | SetVertexProperty;
|
|
86
74
|
declare function isMoveVertexOp(op: VertexOperation): op is MoveVertex;
|
|
87
75
|
declare function isAnyPropertyOp(op: VertexOperation): op is SetVertexProperty;
|
|
88
|
-
declare function isLWWPropertyOp(op: VertexOperation): op is SetVertexProperty;
|
|
89
|
-
declare function isModifyPropertyOp(op: VertexOperation): op is SetVertexProperty;
|
|
90
76
|
declare function newMoveVertexOp(clock: number, peerId: string, targetId: string, parentId: string | null): MoveVertex;
|
|
91
|
-
declare function newSetVertexPropertyOp(clock: number, peerId: string, targetId: string, key: string, value:
|
|
92
|
-
declare function newSetTransientVertexPropertyOp(clock: number, peerId: string, targetId: string, key: string, value:
|
|
77
|
+
declare function newSetVertexPropertyOp(clock: number, peerId: string, targetId: string, key: string, value: VertexPropertyType): SetVertexProperty;
|
|
78
|
+
declare function newSetTransientVertexPropertyOp(clock: number, peerId: string, targetId: string, key: string, value: VertexPropertyType): SetVertexProperty;
|
|
93
79
|
|
|
94
80
|
type FieldSchemaLike = {
|
|
95
81
|
safeParse?: (input: unknown) => {
|
|
@@ -109,16 +95,8 @@ type SchemaLike<T> = {
|
|
|
109
95
|
parse?: (input: unknown) => T;
|
|
110
96
|
shape?: Record<string, FieldSchemaLike>;
|
|
111
97
|
};
|
|
112
|
-
type AliasRule = {
|
|
113
|
-
publicKey: string;
|
|
114
|
-
internalKey: string;
|
|
115
|
-
toPublic?: (value: unknown) => unknown;
|
|
116
|
-
toInternal?: (value: unknown) => unknown;
|
|
117
|
-
};
|
|
118
|
-
declare const defaultAliases: AliasRule[];
|
|
119
98
|
type BindOptions<T> = {
|
|
120
99
|
schema?: SchemaLike<T>;
|
|
121
|
-
aliases?: AliasRule[];
|
|
122
100
|
includeInternalKeys?: boolean;
|
|
123
101
|
};
|
|
124
102
|
/**
|
|
@@ -219,7 +197,6 @@ declare class Vertex {
|
|
|
219
197
|
bind<T extends Record<string, unknown>>(schemaOrOptions?: SchemaLike<T> | BindOptions<T>): BindedVertex<T>;
|
|
220
198
|
/**
|
|
221
199
|
* Normalizes an input props object for vertex creation:
|
|
222
|
-
* - Aliases name -> _n, createdAt -> _c (Date -> ISO string)
|
|
223
200
|
* - Filters unsupported field types with a console warning
|
|
224
201
|
* - When a name param is provided to newNamedChild, ignores conflicting name in props
|
|
225
202
|
*/
|
|
@@ -242,7 +219,6 @@ declare class RepTree {
|
|
|
242
219
|
private setPropertyOps;
|
|
243
220
|
private propertiesAndTheirOpIds;
|
|
244
221
|
private transientPropertiesAndTheirOpIds;
|
|
245
|
-
private yjsObservers;
|
|
246
222
|
private localOps;
|
|
247
223
|
private pendingMovesWithMissingParent;
|
|
248
224
|
private pendingPropertiesWithMissingVertex;
|
|
@@ -273,12 +249,23 @@ declare class RepTree {
|
|
|
273
249
|
* Can be used to get all operations that were generated from this peer and need to be sent to other peers.
|
|
274
250
|
*/
|
|
275
251
|
popLocalOps(): VertexOperation[];
|
|
252
|
+
/**
|
|
253
|
+
* This is the first vertex that will contain all other vertices.
|
|
254
|
+
* If you plan to replicate a tree then don't use this method and instead merge
|
|
255
|
+
* in the ops from another tree (that will also contain the root vertex).
|
|
256
|
+
* @returns The root vertex
|
|
257
|
+
*/
|
|
276
258
|
createRoot(): Vertex;
|
|
277
259
|
newVertex(parentId: string, props?: Record<string, VertexPropertyType> | object | null): Vertex;
|
|
278
260
|
newNamedVertex(parentId: string, name: string, props?: Record<string, VertexPropertyType> | object | null): Vertex;
|
|
279
261
|
moveVertex(vertexId: string, parentId: string): void;
|
|
280
262
|
deleteVertex(vertexId: string): void;
|
|
281
263
|
setTransientVertexProperty(vertexId: string, key: string, value: VertexPropertyType): void;
|
|
264
|
+
/**
|
|
265
|
+
* Promotes all transient (temporary) properties to persistent properties.
|
|
266
|
+
* @param vertexId - The ID of the vertex to commit transients for.
|
|
267
|
+
* @returns
|
|
268
|
+
*/
|
|
282
269
|
commitTransients(vertexId: string): void;
|
|
283
270
|
setVertexProperty(vertexId: string, key: string, value: VertexPropertyType): void;
|
|
284
271
|
setVertexProperties(vertexId: string, props: Record<string, VertexPropertyType> | object): void;
|
|
@@ -307,10 +294,8 @@ declare class RepTree {
|
|
|
307
294
|
private applyMove;
|
|
308
295
|
private setLLWPropertyAndItsOpId;
|
|
309
296
|
private setTransientPropertyAndItsOpId;
|
|
310
|
-
private setupYjsObserver;
|
|
311
297
|
private applyProperty;
|
|
312
298
|
private applyLLWProperty;
|
|
313
|
-
private applyModifyProperty;
|
|
314
299
|
private applyOperation;
|
|
315
300
|
private reportOpAsApplied;
|
|
316
301
|
private tryToMove;
|
|
@@ -428,4 +413,4 @@ declare class StateVector {
|
|
|
428
413
|
|
|
429
414
|
declare function uuid(): string;
|
|
430
415
|
|
|
431
|
-
export { type
|
|
416
|
+
export { type BindOptions, type BindedVertex, type MoveVertex, type OpId, type OpIdRange, RepTree, type SchemaLike, type SetVertexProperty, StateVector, TreeState, type TreeVertexId, type TreeVertexProperty, Vertex, type VertexChangeEvent, type VertexChildrenChangeEvent, type VertexMoveEvent, type VertexOperation, type VertexPropertyChangeEvent, type VertexPropertyType, VertexState, bindVertex, isAnyPropertyOp, isMoveVertexOp, newMoveVertexOp, newSetTransientVertexPropertyOp, newSetVertexPropertyOp, uuid };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import * as Y from 'yjs';
|
|
2
|
-
|
|
3
1
|
interface OpId {
|
|
4
2
|
readonly counter: number;
|
|
5
3
|
readonly peerId: string;
|
|
@@ -26,18 +24,8 @@ type TreeVertexId = string;
|
|
|
26
24
|
/**
|
|
27
25
|
* Serializable CRDT data for operations
|
|
28
26
|
*/
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
value: Uint8Array;
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Property type for state - includes Y.Doc for runtime usage
|
|
35
|
-
*/
|
|
36
|
-
type VertexPropertyType = string | number | boolean | string[] | number[] | boolean[] | undefined | Y.Doc;
|
|
37
|
-
/**
|
|
38
|
-
* Property type for operations - includes CRDTType instead of Y.Doc
|
|
39
|
-
*/
|
|
40
|
-
type VertexPropertyTypeInOperation = string | number | boolean | string[] | number[] | boolean[] | undefined | CRDTType;
|
|
27
|
+
/** Property type for state */
|
|
28
|
+
type VertexPropertyType = string | number | boolean | string[] | number[] | boolean[] | undefined;
|
|
41
29
|
type TreeVertexProperty = {
|
|
42
30
|
readonly key: string;
|
|
43
31
|
readonly value: VertexPropertyType;
|
|
@@ -79,17 +67,15 @@ interface SetVertexProperty {
|
|
|
79
67
|
id: OpId;
|
|
80
68
|
targetId: string;
|
|
81
69
|
key: string;
|
|
82
|
-
value:
|
|
70
|
+
value: VertexPropertyType;
|
|
83
71
|
transient: boolean;
|
|
84
72
|
}
|
|
85
73
|
type VertexOperation = MoveVertex | SetVertexProperty;
|
|
86
74
|
declare function isMoveVertexOp(op: VertexOperation): op is MoveVertex;
|
|
87
75
|
declare function isAnyPropertyOp(op: VertexOperation): op is SetVertexProperty;
|
|
88
|
-
declare function isLWWPropertyOp(op: VertexOperation): op is SetVertexProperty;
|
|
89
|
-
declare function isModifyPropertyOp(op: VertexOperation): op is SetVertexProperty;
|
|
90
76
|
declare function newMoveVertexOp(clock: number, peerId: string, targetId: string, parentId: string | null): MoveVertex;
|
|
91
|
-
declare function newSetVertexPropertyOp(clock: number, peerId: string, targetId: string, key: string, value:
|
|
92
|
-
declare function newSetTransientVertexPropertyOp(clock: number, peerId: string, targetId: string, key: string, value:
|
|
77
|
+
declare function newSetVertexPropertyOp(clock: number, peerId: string, targetId: string, key: string, value: VertexPropertyType): SetVertexProperty;
|
|
78
|
+
declare function newSetTransientVertexPropertyOp(clock: number, peerId: string, targetId: string, key: string, value: VertexPropertyType): SetVertexProperty;
|
|
93
79
|
|
|
94
80
|
type FieldSchemaLike = {
|
|
95
81
|
safeParse?: (input: unknown) => {
|
|
@@ -109,16 +95,8 @@ type SchemaLike<T> = {
|
|
|
109
95
|
parse?: (input: unknown) => T;
|
|
110
96
|
shape?: Record<string, FieldSchemaLike>;
|
|
111
97
|
};
|
|
112
|
-
type AliasRule = {
|
|
113
|
-
publicKey: string;
|
|
114
|
-
internalKey: string;
|
|
115
|
-
toPublic?: (value: unknown) => unknown;
|
|
116
|
-
toInternal?: (value: unknown) => unknown;
|
|
117
|
-
};
|
|
118
|
-
declare const defaultAliases: AliasRule[];
|
|
119
98
|
type BindOptions<T> = {
|
|
120
99
|
schema?: SchemaLike<T>;
|
|
121
|
-
aliases?: AliasRule[];
|
|
122
100
|
includeInternalKeys?: boolean;
|
|
123
101
|
};
|
|
124
102
|
/**
|
|
@@ -219,7 +197,6 @@ declare class Vertex {
|
|
|
219
197
|
bind<T extends Record<string, unknown>>(schemaOrOptions?: SchemaLike<T> | BindOptions<T>): BindedVertex<T>;
|
|
220
198
|
/**
|
|
221
199
|
* Normalizes an input props object for vertex creation:
|
|
222
|
-
* - Aliases name -> _n, createdAt -> _c (Date -> ISO string)
|
|
223
200
|
* - Filters unsupported field types with a console warning
|
|
224
201
|
* - When a name param is provided to newNamedChild, ignores conflicting name in props
|
|
225
202
|
*/
|
|
@@ -242,7 +219,6 @@ declare class RepTree {
|
|
|
242
219
|
private setPropertyOps;
|
|
243
220
|
private propertiesAndTheirOpIds;
|
|
244
221
|
private transientPropertiesAndTheirOpIds;
|
|
245
|
-
private yjsObservers;
|
|
246
222
|
private localOps;
|
|
247
223
|
private pendingMovesWithMissingParent;
|
|
248
224
|
private pendingPropertiesWithMissingVertex;
|
|
@@ -273,12 +249,23 @@ declare class RepTree {
|
|
|
273
249
|
* Can be used to get all operations that were generated from this peer and need to be sent to other peers.
|
|
274
250
|
*/
|
|
275
251
|
popLocalOps(): VertexOperation[];
|
|
252
|
+
/**
|
|
253
|
+
* This is the first vertex that will contain all other vertices.
|
|
254
|
+
* If you plan to replicate a tree then don't use this method and instead merge
|
|
255
|
+
* in the ops from another tree (that will also contain the root vertex).
|
|
256
|
+
* @returns The root vertex
|
|
257
|
+
*/
|
|
276
258
|
createRoot(): Vertex;
|
|
277
259
|
newVertex(parentId: string, props?: Record<string, VertexPropertyType> | object | null): Vertex;
|
|
278
260
|
newNamedVertex(parentId: string, name: string, props?: Record<string, VertexPropertyType> | object | null): Vertex;
|
|
279
261
|
moveVertex(vertexId: string, parentId: string): void;
|
|
280
262
|
deleteVertex(vertexId: string): void;
|
|
281
263
|
setTransientVertexProperty(vertexId: string, key: string, value: VertexPropertyType): void;
|
|
264
|
+
/**
|
|
265
|
+
* Promotes all transient (temporary) properties to persistent properties.
|
|
266
|
+
* @param vertexId - The ID of the vertex to commit transients for.
|
|
267
|
+
* @returns
|
|
268
|
+
*/
|
|
282
269
|
commitTransients(vertexId: string): void;
|
|
283
270
|
setVertexProperty(vertexId: string, key: string, value: VertexPropertyType): void;
|
|
284
271
|
setVertexProperties(vertexId: string, props: Record<string, VertexPropertyType> | object): void;
|
|
@@ -307,10 +294,8 @@ declare class RepTree {
|
|
|
307
294
|
private applyMove;
|
|
308
295
|
private setLLWPropertyAndItsOpId;
|
|
309
296
|
private setTransientPropertyAndItsOpId;
|
|
310
|
-
private setupYjsObserver;
|
|
311
297
|
private applyProperty;
|
|
312
298
|
private applyLLWProperty;
|
|
313
|
-
private applyModifyProperty;
|
|
314
299
|
private applyOperation;
|
|
315
300
|
private reportOpAsApplied;
|
|
316
301
|
private tryToMove;
|
|
@@ -428,4 +413,4 @@ declare class StateVector {
|
|
|
428
413
|
|
|
429
414
|
declare function uuid(): string;
|
|
430
415
|
|
|
431
|
-
export { type
|
|
416
|
+
export { type BindOptions, type BindedVertex, type MoveVertex, type OpId, type OpIdRange, RepTree, type SchemaLike, type SetVertexProperty, StateVector, TreeState, type TreeVertexId, type TreeVertexProperty, Vertex, type VertexChangeEvent, type VertexChildrenChangeEvent, type VertexMoveEvent, type VertexOperation, type VertexPropertyChangeEvent, type VertexPropertyType, VertexState, bindVertex, isAnyPropertyOp, isMoveVertexOp, newMoveVertexOp, newSetTransientVertexPropertyOp, newSetVertexPropertyOp, uuid };
|
package/dist/index.js
CHANGED
|
@@ -52,12 +52,6 @@ function isMoveVertexOp(op) {
|
|
|
52
52
|
function isAnyPropertyOp(op) {
|
|
53
53
|
return "key" in op;
|
|
54
54
|
}
|
|
55
|
-
function isLWWPropertyOp(op) {
|
|
56
|
-
return "key" in op && "value" in op && (!op.value || typeof op.value !== "object" || !("type" in op.value));
|
|
57
|
-
}
|
|
58
|
-
function isModifyPropertyOp(op) {
|
|
59
|
-
return "key" in op && "value" in op && typeof op.value === "object" && op.value !== null && "type" in op.value;
|
|
60
|
-
}
|
|
61
55
|
function newMoveVertexOp(clock, peerId, targetId, parentId) {
|
|
62
56
|
return { id: createOpId(clock, peerId), targetId, parentId };
|
|
63
57
|
}
|
|
@@ -323,7 +317,7 @@ var TreeState = class {
|
|
|
323
317
|
const vertex = this.getVertex(vertexId);
|
|
324
318
|
if (vertex) {
|
|
325
319
|
for (const prop of vertex.getAllProperties()) {
|
|
326
|
-
if (prop.key === "
|
|
320
|
+
if (prop.key === "name") {
|
|
327
321
|
vertexName = prop.value;
|
|
328
322
|
}
|
|
329
323
|
const propPrefix = indent + (isLast ? " " : "\u2502 ") + "\u2022 ";
|
|
@@ -336,8 +330,8 @@ var TreeState = class {
|
|
|
336
330
|
const sortedChildren = [...children].sort((a, b) => {
|
|
337
331
|
const vertexA = this.getVertex(a);
|
|
338
332
|
const vertexB = this.getVertex(b);
|
|
339
|
-
const nameA = vertexA?.getProperty("
|
|
340
|
-
const nameB = vertexB?.getProperty("
|
|
333
|
+
const nameA = vertexA?.getProperty("name");
|
|
334
|
+
const nameB = vertexB?.getProperty("name");
|
|
341
335
|
if (nameA && nameB) {
|
|
342
336
|
return nameA.localeCompare(nameB);
|
|
343
337
|
}
|
|
@@ -361,30 +355,10 @@ function uuid() {
|
|
|
361
355
|
}
|
|
362
356
|
|
|
363
357
|
// src/reactive.ts
|
|
364
|
-
var defaultAliases = [
|
|
365
|
-
{ publicKey: "name", internalKey: "_n" },
|
|
366
|
-
{
|
|
367
|
-
publicKey: "createdAt",
|
|
368
|
-
internalKey: "_c",
|
|
369
|
-
toPublic: (v) => typeof v === "string" ? new Date(v) : v,
|
|
370
|
-
toInternal: (v) => v instanceof Date ? v.toISOString() : v
|
|
371
|
-
}
|
|
372
|
-
];
|
|
373
|
-
function buildAliasMaps(aliases) {
|
|
374
|
-
const publicToInternal = /* @__PURE__ */ new Map();
|
|
375
|
-
const internalToPublic = /* @__PURE__ */ new Map();
|
|
376
|
-
for (const rule of aliases) {
|
|
377
|
-
publicToInternal.set(rule.publicKey, rule);
|
|
378
|
-
internalToPublic.set(rule.internalKey, rule);
|
|
379
|
-
}
|
|
380
|
-
return { publicToInternal, internalToPublic };
|
|
381
|
-
}
|
|
382
358
|
function bindVertex(tree, id, schemaOrOptions) {
|
|
383
|
-
const isOptions = typeof schemaOrOptions === "object" && schemaOrOptions !== null && (Object.prototype.hasOwnProperty.call(schemaOrOptions, "
|
|
359
|
+
const isOptions = typeof schemaOrOptions === "object" && schemaOrOptions !== null && (Object.prototype.hasOwnProperty.call(schemaOrOptions, "includeInternalKeys") || Object.prototype.hasOwnProperty.call(schemaOrOptions, "schema"));
|
|
384
360
|
const options = isOptions ? schemaOrOptions : { schema: schemaOrOptions };
|
|
385
361
|
const schema = options.schema;
|
|
386
|
-
const aliases = options.aliases ?? defaultAliases;
|
|
387
|
-
const { publicToInternal } = buildAliasMaps(aliases);
|
|
388
362
|
const obj = {};
|
|
389
363
|
Object.defineProperties(obj, {
|
|
390
364
|
$vertex: { get: () => tree.getVertex(id), enumerable: false, configurable: true },
|
|
@@ -421,19 +395,14 @@ function bindVertex(tree, id, schemaOrOptions) {
|
|
|
421
395
|
const transientProxy = new Proxy({}, {
|
|
422
396
|
set(_, prop, value) {
|
|
423
397
|
if (typeof prop === "string") {
|
|
424
|
-
|
|
425
|
-
const internalKey = rule?.internalKey ?? prop;
|
|
426
|
-
const internalValue = rule?.toInternal ? rule.toInternal(value) : value;
|
|
427
|
-
tree.setTransientVertexProperty(id, internalKey, internalValue);
|
|
398
|
+
tree.setTransientVertexProperty(id, prop, value);
|
|
428
399
|
}
|
|
429
400
|
return true;
|
|
430
401
|
},
|
|
431
402
|
get(_, prop) {
|
|
432
403
|
if (typeof prop !== "string") return void 0;
|
|
433
|
-
const
|
|
434
|
-
|
|
435
|
-
const rawValue = tree.getVertexProperty(id, internalKey, true);
|
|
436
|
-
return rule?.toPublic ? rule.toPublic(rawValue) : rawValue;
|
|
404
|
+
const rawValue = tree.getVertexProperty(id, prop, true);
|
|
405
|
+
return rawValue;
|
|
437
406
|
}
|
|
438
407
|
});
|
|
439
408
|
fn(transientProxy);
|
|
@@ -463,10 +432,8 @@ function bindVertex(tree, id, schemaOrOptions) {
|
|
|
463
432
|
if (prop in target) {
|
|
464
433
|
return Reflect.get(target, prop, receiver);
|
|
465
434
|
}
|
|
466
|
-
const
|
|
467
|
-
|
|
468
|
-
const rawValue = tree.getVertexProperty(id, internalKey, true);
|
|
469
|
-
return rule?.toPublic ? rule.toPublic(rawValue) : rawValue;
|
|
435
|
+
const rawValue = tree.getVertexProperty(id, prop, true);
|
|
436
|
+
return rawValue;
|
|
470
437
|
},
|
|
471
438
|
set(target, prop, value) {
|
|
472
439
|
if (typeof prop !== "string") {
|
|
@@ -480,19 +447,14 @@ function bindVertex(tree, id, schemaOrOptions) {
|
|
|
480
447
|
value = res.data;
|
|
481
448
|
}
|
|
482
449
|
}
|
|
483
|
-
|
|
484
|
-
const internalKey = rule?.internalKey ?? prop;
|
|
485
|
-
const internalValue = rule?.toInternal ? rule.toInternal(value) : value;
|
|
486
|
-
tree.setVertexProperty(id, internalKey, internalValue);
|
|
450
|
+
tree.setVertexProperty(id, prop, value);
|
|
487
451
|
return true;
|
|
488
452
|
},
|
|
489
453
|
deleteProperty(_target, prop) {
|
|
490
454
|
if (typeof prop !== "string") {
|
|
491
455
|
return true;
|
|
492
456
|
}
|
|
493
|
-
|
|
494
|
-
const internalKey = rule?.internalKey ?? prop;
|
|
495
|
-
tree.setVertexProperty(id, internalKey, void 0);
|
|
457
|
+
tree.setVertexProperty(id, prop, void 0);
|
|
496
458
|
return true;
|
|
497
459
|
}
|
|
498
460
|
});
|
|
@@ -500,7 +462,6 @@ function bindVertex(tree, id, schemaOrOptions) {
|
|
|
500
462
|
}
|
|
501
463
|
|
|
502
464
|
// src/Vertex.ts
|
|
503
|
-
import * as Y from "yjs";
|
|
504
465
|
var Vertex = class _Vertex {
|
|
505
466
|
constructor(tree, state) {
|
|
506
467
|
this.tree = tree;
|
|
@@ -510,10 +471,10 @@ var Vertex = class _Vertex {
|
|
|
510
471
|
return this.state.id;
|
|
511
472
|
}
|
|
512
473
|
get name() {
|
|
513
|
-
return this.getProperty("
|
|
474
|
+
return this.getProperty("name");
|
|
514
475
|
}
|
|
515
476
|
set name(name) {
|
|
516
|
-
this.tree.setVertexProperty(this.id, "
|
|
477
|
+
this.tree.setVertexProperty(this.id, "name", name);
|
|
517
478
|
}
|
|
518
479
|
get createdAt() {
|
|
519
480
|
const createdAt = this.getProperty("_c");
|
|
@@ -633,7 +594,6 @@ var Vertex = class _Vertex {
|
|
|
633
594
|
}
|
|
634
595
|
/**
|
|
635
596
|
* Normalizes an input props object for vertex creation:
|
|
636
|
-
* - Aliases name -> _n, createdAt -> _c (Date -> ISO string)
|
|
637
597
|
* - Filters unsupported field types with a console warning
|
|
638
598
|
* - When a name param is provided to newNamedChild, ignores conflicting name in props
|
|
639
599
|
*/
|
|
@@ -648,14 +608,9 @@ var Vertex = class _Vertex {
|
|
|
648
608
|
}
|
|
649
609
|
if (rawKey === "children") continue;
|
|
650
610
|
let key = rawKey;
|
|
651
|
-
if (rawKey === "name") {
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
continue;
|
|
655
|
-
}
|
|
656
|
-
key = "_n";
|
|
657
|
-
} else if (rawKey === "createdAt") {
|
|
658
|
-
key = "_c";
|
|
611
|
+
if (rawKey === "name" && explicitName !== void 0) {
|
|
612
|
+
console.warn('newNamedChild: "name" in props is ignored because a name argument was provided');
|
|
613
|
+
continue;
|
|
659
614
|
}
|
|
660
615
|
let value = rawValue;
|
|
661
616
|
if (key === "_c") {
|
|
@@ -674,10 +629,8 @@ var Vertex = class _Vertex {
|
|
|
674
629
|
continue;
|
|
675
630
|
}
|
|
676
631
|
} else if (typeof value === "object" && value !== null) {
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
continue;
|
|
680
|
-
}
|
|
632
|
+
skipped.push(rawKey);
|
|
633
|
+
continue;
|
|
681
634
|
} else if (!isPrimitive(value)) {
|
|
682
635
|
skipped.push(rawKey);
|
|
683
636
|
continue;
|
|
@@ -877,7 +830,6 @@ var StateVector = class _StateVector {
|
|
|
877
830
|
};
|
|
878
831
|
|
|
879
832
|
// src/RepTree.ts
|
|
880
|
-
import * as Y2 from "yjs";
|
|
881
833
|
var _RepTree = class _RepTree {
|
|
882
834
|
/**
|
|
883
835
|
* @param peerId - The peer ID of the current client. Should be unique across all peers.
|
|
@@ -889,7 +841,7 @@ var _RepTree = class _RepTree {
|
|
|
889
841
|
this.setPropertyOps = [];
|
|
890
842
|
this.propertiesAndTheirOpIds = /* @__PURE__ */ new Map();
|
|
891
843
|
this.transientPropertiesAndTheirOpIds = /* @__PURE__ */ new Map();
|
|
892
|
-
|
|
844
|
+
// Observers for non-structural properties are not used
|
|
893
845
|
this.localOps = [];
|
|
894
846
|
this.pendingMovesWithMissingParent = /* @__PURE__ */ new Map();
|
|
895
847
|
this.pendingPropertiesWithMissingVertex = /* @__PURE__ */ new Map();
|
|
@@ -991,6 +943,12 @@ var _RepTree = class _RepTree {
|
|
|
991
943
|
this.localOps = [];
|
|
992
944
|
return ops;
|
|
993
945
|
}
|
|
946
|
+
/**
|
|
947
|
+
* This is the first vertex that will contain all other vertices.
|
|
948
|
+
* If you plan to replicate a tree then don't use this method and instead merge
|
|
949
|
+
* in the ops from another tree (that will also contain the root vertex).
|
|
950
|
+
* @returns The root vertex
|
|
951
|
+
*/
|
|
994
952
|
createRoot() {
|
|
995
953
|
if (this.rootVertexId) {
|
|
996
954
|
throw new Error("Root vertex already exists");
|
|
@@ -1020,7 +978,7 @@ var _RepTree = class _RepTree {
|
|
|
1020
978
|
if (typedProps) {
|
|
1021
979
|
this.setVertexProperties(vertexId, typedProps);
|
|
1022
980
|
}
|
|
1023
|
-
this.setVertexProperty(vertexId, "
|
|
981
|
+
this.setVertexProperty(vertexId, "name", name);
|
|
1024
982
|
const vertex = this.state.getVertex(vertexId);
|
|
1025
983
|
if (!vertex) {
|
|
1026
984
|
throw new Error("Failed to create named vertex");
|
|
@@ -1038,21 +996,15 @@ var _RepTree = class _RepTree {
|
|
|
1038
996
|
}
|
|
1039
997
|
setTransientVertexProperty(vertexId, key, value) {
|
|
1040
998
|
this.lamportClock++;
|
|
1041
|
-
|
|
1042
|
-
if (value instanceof Y2.Doc) {
|
|
1043
|
-
const state = Y2.encodeStateAsUpdate(value);
|
|
1044
|
-
opValue = {
|
|
1045
|
-
type: "yjs",
|
|
1046
|
-
value: state
|
|
1047
|
-
};
|
|
1048
|
-
this.setupYjsObserver(value, vertexId, key);
|
|
1049
|
-
} else {
|
|
1050
|
-
opValue = value;
|
|
1051
|
-
}
|
|
1052
|
-
const op = newSetTransientVertexPropertyOp(this.lamportClock, this.peerId, vertexId, key, opValue);
|
|
999
|
+
const op = newSetTransientVertexPropertyOp(this.lamportClock, this.peerId, vertexId, key, value);
|
|
1053
1000
|
this.localOps.push(op);
|
|
1054
1001
|
this.applyProperty(op);
|
|
1055
1002
|
}
|
|
1003
|
+
/**
|
|
1004
|
+
* Promotes all transient (temporary) properties to persistent properties.
|
|
1005
|
+
* @param vertexId - The ID of the vertex to commit transients for.
|
|
1006
|
+
* @returns
|
|
1007
|
+
*/
|
|
1056
1008
|
commitTransients(vertexId) {
|
|
1057
1009
|
const vertex = this.state.getVertex(vertexId);
|
|
1058
1010
|
if (!vertex) {
|
|
@@ -1069,18 +1021,7 @@ var _RepTree = class _RepTree {
|
|
|
1069
1021
|
}
|
|
1070
1022
|
setVertexProperty(vertexId, key, value) {
|
|
1071
1023
|
this.lamportClock++;
|
|
1072
|
-
|
|
1073
|
-
if (value instanceof Y2.Doc) {
|
|
1074
|
-
const state = Y2.encodeStateAsUpdate(value);
|
|
1075
|
-
opValue = {
|
|
1076
|
-
type: "yjs",
|
|
1077
|
-
value: state
|
|
1078
|
-
};
|
|
1079
|
-
this.setupYjsObserver(value, vertexId, key);
|
|
1080
|
-
} else {
|
|
1081
|
-
opValue = value;
|
|
1082
|
-
}
|
|
1083
|
-
const op = newSetVertexPropertyOp(this.lamportClock, this.peerId, vertexId, key, opValue);
|
|
1024
|
+
const op = newSetVertexPropertyOp(this.lamportClock, this.peerId, vertexId, key, value);
|
|
1084
1025
|
this.localOps.push(op);
|
|
1085
1026
|
this.applyProperty(op);
|
|
1086
1027
|
}
|
|
@@ -1111,7 +1052,7 @@ var _RepTree = class _RepTree {
|
|
|
1111
1052
|
const targetName = path[0];
|
|
1112
1053
|
const children = this.getChildren(vertex.id);
|
|
1113
1054
|
for (const child of children) {
|
|
1114
|
-
if (child.getProperty("
|
|
1055
|
+
if (child.getProperty("name") === targetName) {
|
|
1115
1056
|
return this.getVertexByPathArray(child, path.slice(1));
|
|
1116
1057
|
}
|
|
1117
1058
|
}
|
|
@@ -1243,13 +1184,7 @@ var _RepTree = class _RepTree {
|
|
|
1243
1184
|
if (!propB) {
|
|
1244
1185
|
return false;
|
|
1245
1186
|
}
|
|
1246
|
-
if (propA.value
|
|
1247
|
-
const snapshotA = Y2.snapshot(propA.value);
|
|
1248
|
-
const snapshotB = Y2.snapshot(propB.value);
|
|
1249
|
-
if (!Y2.equalSnapshots(snapshotA, snapshotB)) {
|
|
1250
|
-
return false;
|
|
1251
|
-
}
|
|
1252
|
-
} else if (propA.value !== propB.value) {
|
|
1187
|
+
if (propA.value !== propB.value) {
|
|
1253
1188
|
return false;
|
|
1254
1189
|
}
|
|
1255
1190
|
}
|
|
@@ -1346,40 +1281,6 @@ var _RepTree = class _RepTree {
|
|
|
1346
1281
|
this.state.setTransientProperty(op.targetId, op.key, op.value);
|
|
1347
1282
|
this.reportOpAsApplied(op);
|
|
1348
1283
|
}
|
|
1349
|
-
setupYjsObserver(doc, vertexId, key) {
|
|
1350
|
-
const propertyKey = `${key}@${vertexId}`;
|
|
1351
|
-
if (this.yjsObservers.has(propertyKey)) {
|
|
1352
|
-
const existingDoc = this.getVertexProperty(vertexId, key);
|
|
1353
|
-
if (existingDoc instanceof Y2.Doc) {
|
|
1354
|
-
existingDoc.off("update", this.yjsObservers.get(propertyKey));
|
|
1355
|
-
}
|
|
1356
|
-
this.yjsObservers.delete(propertyKey);
|
|
1357
|
-
}
|
|
1358
|
-
const ydocObserver = (update, origin, doc2, transaction) => {
|
|
1359
|
-
if (!transaction.local) {
|
|
1360
|
-
return;
|
|
1361
|
-
}
|
|
1362
|
-
const crdtValue = {
|
|
1363
|
-
type: "yjs",
|
|
1364
|
-
value: update
|
|
1365
|
-
};
|
|
1366
|
-
this.lamportClock++;
|
|
1367
|
-
const op = newSetVertexPropertyOp(
|
|
1368
|
-
this.lamportClock,
|
|
1369
|
-
this.peerId,
|
|
1370
|
-
vertexId,
|
|
1371
|
-
key,
|
|
1372
|
-
crdtValue
|
|
1373
|
-
);
|
|
1374
|
-
this.localOps.push(op);
|
|
1375
|
-
this.applyProperty(op);
|
|
1376
|
-
if (this._stateVectorEnabled) {
|
|
1377
|
-
this.stateVector.updateFromOp(op);
|
|
1378
|
-
}
|
|
1379
|
-
};
|
|
1380
|
-
doc.on("update", ydocObserver);
|
|
1381
|
-
this.yjsObservers.set(propertyKey, ydocObserver);
|
|
1382
|
-
}
|
|
1383
1284
|
applyProperty(op) {
|
|
1384
1285
|
const targetVertex = this.state.getVertex(op.targetId);
|
|
1385
1286
|
if (!targetVertex) {
|
|
@@ -1393,11 +1294,7 @@ var _RepTree = class _RepTree {
|
|
|
1393
1294
|
return;
|
|
1394
1295
|
}
|
|
1395
1296
|
this.updateLamportClock(op);
|
|
1396
|
-
|
|
1397
|
-
this.applyModifyProperty(op, targetVertex);
|
|
1398
|
-
} else {
|
|
1399
|
-
this.applyLLWProperty(op, targetVertex);
|
|
1400
|
-
}
|
|
1297
|
+
this.applyLLWProperty(op, targetVertex);
|
|
1401
1298
|
}
|
|
1402
1299
|
applyLLWProperty(op, targetVertex) {
|
|
1403
1300
|
const prevTransientOpId = this.transientPropertiesAndTheirOpIds.get(`${op.key}@${op.targetId}`);
|
|
@@ -1419,28 +1316,7 @@ var _RepTree = class _RepTree {
|
|
|
1419
1316
|
}
|
|
1420
1317
|
}
|
|
1421
1318
|
}
|
|
1422
|
-
|
|
1423
|
-
if (op.transient) {
|
|
1424
|
-
console.warn("Not implemented: transient non LWW property");
|
|
1425
|
-
return;
|
|
1426
|
-
}
|
|
1427
|
-
this.setPropertyOps.push(op);
|
|
1428
|
-
const crdtValue = op.value;
|
|
1429
|
-
if (crdtValue.type !== "yjs") {
|
|
1430
|
-
throw new Error("Unknown CRDT type");
|
|
1431
|
-
}
|
|
1432
|
-
const ydoc = targetVertex.getProperty(op.key);
|
|
1433
|
-
if (ydoc instanceof Y2.Doc) {
|
|
1434
|
-
Y2.applyUpdate(ydoc, crdtValue.value);
|
|
1435
|
-
} else {
|
|
1436
|
-
const newDoc = new Y2.Doc();
|
|
1437
|
-
this.setupYjsObserver(newDoc, op.targetId, op.key);
|
|
1438
|
-
this.state.setProperty(op.targetId, op.key, newDoc);
|
|
1439
|
-
Y2.applyUpdate(newDoc, crdtValue.value);
|
|
1440
|
-
}
|
|
1441
|
-
this.propertiesAndTheirOpIds.set(`${op.key}@${op.targetId}`, op.id);
|
|
1442
|
-
this.reportOpAsApplied(op);
|
|
1443
|
-
}
|
|
1319
|
+
// Non-LWW modify-property flow removed
|
|
1444
1320
|
applyOperation(op) {
|
|
1445
1321
|
if (isMoveVertexOp(op)) {
|
|
1446
1322
|
this.applyMove(op);
|
|
@@ -1563,10 +1439,7 @@ export {
|
|
|
1563
1439
|
Vertex,
|
|
1564
1440
|
VertexState,
|
|
1565
1441
|
bindVertex,
|
|
1566
|
-
defaultAliases,
|
|
1567
1442
|
isAnyPropertyOp,
|
|
1568
|
-
isLWWPropertyOp,
|
|
1569
|
-
isModifyPropertyOp,
|
|
1570
1443
|
isMoveVertexOp,
|
|
1571
1444
|
newMoveVertexOp,
|
|
1572
1445
|
newSetTransientVertexPropertyOp,
|