reptree 0.3.0 → 0.4.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.cjs +113 -229
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +45 -14
- package/dist/index.d.ts +45 -14
- package/dist/index.js +113 -229
- package/dist/index.js.map +1 -1
- package/package.json +4 -3
package/dist/index.d.cts
CHANGED
|
@@ -18,6 +18,8 @@ declare class VertexState {
|
|
|
18
18
|
getAllProperties(includingTransient?: boolean): ReadonlyArray<TreeVertexProperty>;
|
|
19
19
|
removeProperty(key: string): void;
|
|
20
20
|
removeTransientProperty(key: string): void;
|
|
21
|
+
getTransientProperties(): ReadonlyArray<TreeVertexProperty>;
|
|
22
|
+
clearAllTransientProperties(): void;
|
|
21
23
|
}
|
|
22
24
|
|
|
23
25
|
type TreeVertexId = string;
|
|
@@ -119,34 +121,61 @@ type BindOptions<T> = {
|
|
|
119
121
|
aliases?: AliasRule[];
|
|
120
122
|
includeInternalKeys?: boolean;
|
|
121
123
|
};
|
|
124
|
+
/**
|
|
125
|
+
* A bound vertex object that forwards reads/writes to a vertex.
|
|
126
|
+
* @param T - The type of the vertex.
|
|
127
|
+
*/
|
|
122
128
|
type BindedVertex<T> = T & {
|
|
123
|
-
|
|
124
|
-
* Create a transient proxy that can be used to write transient properties.
|
|
125
|
-
*/
|
|
126
|
-
useTransient(fn: (t: T) => void): void;
|
|
127
|
-
/**
|
|
128
|
-
* Promote transient properties to persistent.
|
|
129
|
-
*/
|
|
130
|
-
commitTransients(): void;
|
|
131
|
-
/** Vertex properties (prefixed with $ to avoid conflicts) */
|
|
129
|
+
$vertex: Vertex;
|
|
132
130
|
$id: string;
|
|
133
131
|
$parentId: string | null;
|
|
134
132
|
$parent: Vertex | undefined;
|
|
135
133
|
$children: Vertex[];
|
|
136
134
|
$childrenIds: string[];
|
|
137
|
-
/**
|
|
135
|
+
/**
|
|
136
|
+
* Apply transient edits that override reads but do not persist yet.
|
|
137
|
+
* @param fn
|
|
138
|
+
*/
|
|
139
|
+
$useTransients(fn: (t: T) => void): void;
|
|
140
|
+
/**
|
|
141
|
+
* Promote current transient overlays to persistent values.
|
|
142
|
+
*/
|
|
143
|
+
$commitTransients(): void;
|
|
144
|
+
/**
|
|
145
|
+
* Move the vertex to a new parent.
|
|
146
|
+
* @param parent - The new parent vertex or ID.
|
|
147
|
+
*/
|
|
138
148
|
$moveTo(parent: Vertex | BindedVertex<any> | string): void;
|
|
149
|
+
/**
|
|
150
|
+
* Delete the vertex.
|
|
151
|
+
*/
|
|
139
152
|
$delete(): void;
|
|
153
|
+
/**
|
|
154
|
+
* Observe changes to the vertex.
|
|
155
|
+
* @param listener - The listener function to call when changes occur.
|
|
156
|
+
*/
|
|
140
157
|
$observe(listener: (events: any[]) => void): () => void;
|
|
158
|
+
/**
|
|
159
|
+
* Observe changes to the children of the vertex.
|
|
160
|
+
* @param listener - The listener function to call when children change.
|
|
161
|
+
*/
|
|
141
162
|
$observeChildren(listener: (children: Vertex[]) => void): () => void;
|
|
163
|
+
/**
|
|
164
|
+
* Create a new child vertex.
|
|
165
|
+
* @param props - The properties to set on the new child vertex.
|
|
166
|
+
*/
|
|
142
167
|
$newChild(props?: Record<string, any> | object | null): Vertex;
|
|
168
|
+
/**
|
|
169
|
+
* Create a new named child vertex.
|
|
170
|
+
* @param name - The name of the new child vertex.
|
|
171
|
+
* @param props - The properties to set on the new child vertex.
|
|
172
|
+
*/
|
|
143
173
|
$newNamedChild(name: string, props?: Record<string, any> | object | null): Vertex;
|
|
144
174
|
};
|
|
145
175
|
/**
|
|
146
|
-
* Returns a live
|
|
147
|
-
* - Reads reflect the latest CRDT state
|
|
148
|
-
* - Writes persist to the CRDT
|
|
149
|
-
* - If a schema is provided, writes are validated. If a field schema exists in `schema.shape`, field-level validation is applied.
|
|
176
|
+
* Returns a live Proxy that forwards reads/writes to a vertex.
|
|
177
|
+
* - Reads reflect the latest CRDT state (including transients by default)
|
|
178
|
+
* - Writes persist to the CRDT with optional schema validation
|
|
150
179
|
*/
|
|
151
180
|
declare function bindVertex<T extends Record<string, unknown>>(tree: RepTree, id: string, schemaOrOptions?: SchemaLike<T> | BindOptions<T>): BindedVertex<T>;
|
|
152
181
|
|
|
@@ -173,6 +202,7 @@ declare class Vertex {
|
|
|
173
202
|
newNamedChild(name: string, props?: Record<string, VertexPropertyType> | object | null): Vertex;
|
|
174
203
|
setProperty(key: string, value: VertexPropertyType): void;
|
|
175
204
|
setTransientProperty(key: string, value: VertexPropertyType): void;
|
|
205
|
+
commitTransients(): void;
|
|
176
206
|
setProperties(props: Record<string, VertexPropertyType> | object): void;
|
|
177
207
|
getProperty(key: string, includingTransient?: boolean): VertexPropertyType | undefined;
|
|
178
208
|
getProperties(): Record<string, VertexPropertyType>;
|
|
@@ -249,6 +279,7 @@ declare class RepTree {
|
|
|
249
279
|
moveVertex(vertexId: string, parentId: string): void;
|
|
250
280
|
deleteVertex(vertexId: string): void;
|
|
251
281
|
setTransientVertexProperty(vertexId: string, key: string, value: VertexPropertyType): void;
|
|
282
|
+
commitTransients(vertexId: string): void;
|
|
252
283
|
setVertexProperty(vertexId: string, key: string, value: VertexPropertyType): void;
|
|
253
284
|
setVertexProperties(vertexId: string, props: Record<string, VertexPropertyType> | object): void;
|
|
254
285
|
getVertexByPath(path: string): Vertex | undefined;
|
package/dist/index.d.ts
CHANGED
|
@@ -18,6 +18,8 @@ declare class VertexState {
|
|
|
18
18
|
getAllProperties(includingTransient?: boolean): ReadonlyArray<TreeVertexProperty>;
|
|
19
19
|
removeProperty(key: string): void;
|
|
20
20
|
removeTransientProperty(key: string): void;
|
|
21
|
+
getTransientProperties(): ReadonlyArray<TreeVertexProperty>;
|
|
22
|
+
clearAllTransientProperties(): void;
|
|
21
23
|
}
|
|
22
24
|
|
|
23
25
|
type TreeVertexId = string;
|
|
@@ -119,34 +121,61 @@ type BindOptions<T> = {
|
|
|
119
121
|
aliases?: AliasRule[];
|
|
120
122
|
includeInternalKeys?: boolean;
|
|
121
123
|
};
|
|
124
|
+
/**
|
|
125
|
+
* A bound vertex object that forwards reads/writes to a vertex.
|
|
126
|
+
* @param T - The type of the vertex.
|
|
127
|
+
*/
|
|
122
128
|
type BindedVertex<T> = T & {
|
|
123
|
-
|
|
124
|
-
* Create a transient proxy that can be used to write transient properties.
|
|
125
|
-
*/
|
|
126
|
-
useTransient(fn: (t: T) => void): void;
|
|
127
|
-
/**
|
|
128
|
-
* Promote transient properties to persistent.
|
|
129
|
-
*/
|
|
130
|
-
commitTransients(): void;
|
|
131
|
-
/** Vertex properties (prefixed with $ to avoid conflicts) */
|
|
129
|
+
$vertex: Vertex;
|
|
132
130
|
$id: string;
|
|
133
131
|
$parentId: string | null;
|
|
134
132
|
$parent: Vertex | undefined;
|
|
135
133
|
$children: Vertex[];
|
|
136
134
|
$childrenIds: string[];
|
|
137
|
-
/**
|
|
135
|
+
/**
|
|
136
|
+
* Apply transient edits that override reads but do not persist yet.
|
|
137
|
+
* @param fn
|
|
138
|
+
*/
|
|
139
|
+
$useTransients(fn: (t: T) => void): void;
|
|
140
|
+
/**
|
|
141
|
+
* Promote current transient overlays to persistent values.
|
|
142
|
+
*/
|
|
143
|
+
$commitTransients(): void;
|
|
144
|
+
/**
|
|
145
|
+
* Move the vertex to a new parent.
|
|
146
|
+
* @param parent - The new parent vertex or ID.
|
|
147
|
+
*/
|
|
138
148
|
$moveTo(parent: Vertex | BindedVertex<any> | string): void;
|
|
149
|
+
/**
|
|
150
|
+
* Delete the vertex.
|
|
151
|
+
*/
|
|
139
152
|
$delete(): void;
|
|
153
|
+
/**
|
|
154
|
+
* Observe changes to the vertex.
|
|
155
|
+
* @param listener - The listener function to call when changes occur.
|
|
156
|
+
*/
|
|
140
157
|
$observe(listener: (events: any[]) => void): () => void;
|
|
158
|
+
/**
|
|
159
|
+
* Observe changes to the children of the vertex.
|
|
160
|
+
* @param listener - The listener function to call when children change.
|
|
161
|
+
*/
|
|
141
162
|
$observeChildren(listener: (children: Vertex[]) => void): () => void;
|
|
163
|
+
/**
|
|
164
|
+
* Create a new child vertex.
|
|
165
|
+
* @param props - The properties to set on the new child vertex.
|
|
166
|
+
*/
|
|
142
167
|
$newChild(props?: Record<string, any> | object | null): Vertex;
|
|
168
|
+
/**
|
|
169
|
+
* Create a new named child vertex.
|
|
170
|
+
* @param name - The name of the new child vertex.
|
|
171
|
+
* @param props - The properties to set on the new child vertex.
|
|
172
|
+
*/
|
|
143
173
|
$newNamedChild(name: string, props?: Record<string, any> | object | null): Vertex;
|
|
144
174
|
};
|
|
145
175
|
/**
|
|
146
|
-
* Returns a live
|
|
147
|
-
* - Reads reflect the latest CRDT state
|
|
148
|
-
* - Writes persist to the CRDT
|
|
149
|
-
* - If a schema is provided, writes are validated. If a field schema exists in `schema.shape`, field-level validation is applied.
|
|
176
|
+
* Returns a live Proxy that forwards reads/writes to a vertex.
|
|
177
|
+
* - Reads reflect the latest CRDT state (including transients by default)
|
|
178
|
+
* - Writes persist to the CRDT with optional schema validation
|
|
150
179
|
*/
|
|
151
180
|
declare function bindVertex<T extends Record<string, unknown>>(tree: RepTree, id: string, schemaOrOptions?: SchemaLike<T> | BindOptions<T>): BindedVertex<T>;
|
|
152
181
|
|
|
@@ -173,6 +202,7 @@ declare class Vertex {
|
|
|
173
202
|
newNamedChild(name: string, props?: Record<string, VertexPropertyType> | object | null): Vertex;
|
|
174
203
|
setProperty(key: string, value: VertexPropertyType): void;
|
|
175
204
|
setTransientProperty(key: string, value: VertexPropertyType): void;
|
|
205
|
+
commitTransients(): void;
|
|
176
206
|
setProperties(props: Record<string, VertexPropertyType> | object): void;
|
|
177
207
|
getProperty(key: string, includingTransient?: boolean): VertexPropertyType | undefined;
|
|
178
208
|
getProperties(): Record<string, VertexPropertyType>;
|
|
@@ -249,6 +279,7 @@ declare class RepTree {
|
|
|
249
279
|
moveVertex(vertexId: string, parentId: string): void;
|
|
250
280
|
deleteVertex(vertexId: string): void;
|
|
251
281
|
setTransientVertexProperty(vertexId: string, key: string, value: VertexPropertyType): void;
|
|
282
|
+
commitTransients(vertexId: string): void;
|
|
252
283
|
setVertexProperty(vertexId: string, key: string, value: VertexPropertyType): void;
|
|
253
284
|
setVertexProperties(vertexId: string, props: Record<string, VertexPropertyType> | object): void;
|
|
254
285
|
getVertexByPath(path: string): Vertex | undefined;
|
package/dist/index.js
CHANGED
|
@@ -137,6 +137,12 @@ var VertexState = class {
|
|
|
137
137
|
removeTransientProperty(key) {
|
|
138
138
|
this.transientProperties = this.transientProperties.filter((p) => p.key !== key);
|
|
139
139
|
}
|
|
140
|
+
getTransientProperties() {
|
|
141
|
+
return this.transientProperties;
|
|
142
|
+
}
|
|
143
|
+
clearAllTransientProperties() {
|
|
144
|
+
this.transientProperties = [];
|
|
145
|
+
}
|
|
140
146
|
};
|
|
141
147
|
|
|
142
148
|
// src/TreeState.ts
|
|
@@ -373,263 +379,124 @@ function buildAliasMaps(aliases) {
|
|
|
373
379
|
}
|
|
374
380
|
return { publicToInternal, internalToPublic };
|
|
375
381
|
}
|
|
376
|
-
function toPublicObject(tree, id, internalToPublic) {
|
|
377
|
-
const obj = {};
|
|
378
|
-
for (const { key, value } of tree.getVertexProperties(id)) {
|
|
379
|
-
const rule = internalToPublic.get(key);
|
|
380
|
-
if (rule) {
|
|
381
|
-
const converted = rule.toPublic ? rule.toPublic(value) : value;
|
|
382
|
-
obj[rule.publicKey] = converted;
|
|
383
|
-
} else {
|
|
384
|
-
obj[key] = value;
|
|
385
|
-
}
|
|
386
|
-
}
|
|
387
|
-
return obj;
|
|
388
|
-
}
|
|
389
|
-
var RESERVED_METHOD_USE_TRANSIENT = "useTransient";
|
|
390
|
-
var RESERVED_METHOD_COMMIT_TRANSIENTS = "commitTransients";
|
|
391
|
-
var VERTEX_PROPS = ["$id", "$parentId", "$parent", "$children", "$childrenIds"];
|
|
392
|
-
var VERTEX_METHODS = ["$moveTo", "$delete", "$observe", "$observeChildren", "$newChild", "$newNamedChild"];
|
|
393
382
|
function bindVertex(tree, id, schemaOrOptions) {
|
|
394
383
|
const isOptions = typeof schemaOrOptions === "object" && schemaOrOptions !== null && (Object.prototype.hasOwnProperty.call(schemaOrOptions, "aliases") || Object.prototype.hasOwnProperty.call(schemaOrOptions, "includeInternalKeys") || Object.prototype.hasOwnProperty.call(schemaOrOptions, "schema"));
|
|
395
384
|
const options = isOptions ? schemaOrOptions : { schema: schemaOrOptions };
|
|
396
385
|
const schema = options.schema;
|
|
397
386
|
const aliases = options.aliases ?? defaultAliases;
|
|
398
|
-
const
|
|
399
|
-
const
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
get(
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
value = res.data ?? value;
|
|
423
|
-
}
|
|
424
|
-
} else if (schema?.safeParse) {
|
|
425
|
-
const next = { ...toPublicObject(tree, id, internalToPublic), [p]: value };
|
|
426
|
-
const res = schema.safeParse(next);
|
|
427
|
-
if (!res.success) throw new Error(`Invalid value for ${String(p)}`);
|
|
428
|
-
const parsed = res.data;
|
|
429
|
-
if (parsed && Object.prototype.hasOwnProperty.call(parsed, p)) {
|
|
430
|
-
value = parsed[p];
|
|
431
|
-
}
|
|
432
|
-
}
|
|
433
|
-
const rule2 = publicToInternal.get(p);
|
|
434
|
-
if (rule2) {
|
|
435
|
-
const converted = rule2.toInternal ? rule2.toInternal(value) : value;
|
|
436
|
-
tree.setTransientVertexProperty(id, rule2.internalKey, converted);
|
|
437
|
-
return true;
|
|
438
|
-
}
|
|
439
|
-
tree.setTransientVertexProperty(id, p, value);
|
|
440
|
-
return true;
|
|
441
|
-
},
|
|
442
|
-
deleteProperty(_t, p) {
|
|
443
|
-
if (typeof p !== "string") return true;
|
|
444
|
-
const rule2 = publicToInternal.get(p);
|
|
445
|
-
if (rule2) {
|
|
446
|
-
tree.setTransientVertexProperty(id, rule2.internalKey, void 0);
|
|
447
|
-
return true;
|
|
448
|
-
}
|
|
449
|
-
tree.setTransientVertexProperty(id, p, void 0);
|
|
450
|
-
return true;
|
|
451
|
-
}
|
|
452
|
-
});
|
|
453
|
-
fn(transientProxy);
|
|
454
|
-
};
|
|
455
|
-
}
|
|
456
|
-
if (prop === RESERVED_METHOD_COMMIT_TRANSIENTS) {
|
|
457
|
-
return () => {
|
|
458
|
-
const entries = tree.getVertexProperties(id);
|
|
459
|
-
const currentPublic = schema?.safeParse ? toPublicObject(tree, id, internalToPublic) : void 0;
|
|
460
|
-
for (const { key: internalKey, value: overlayValue } of entries) {
|
|
461
|
-
const persistentValue = tree.getVertexProperty(id, internalKey, false);
|
|
462
|
-
if (overlayValue === persistentValue) continue;
|
|
463
|
-
const aliasRule = internalToPublic.get(internalKey);
|
|
464
|
-
const publicKey = aliasRule ? aliasRule.publicKey : internalKey;
|
|
465
|
-
const publicValue = aliasRule && aliasRule.toPublic ? aliasRule.toPublic(overlayValue) : overlayValue;
|
|
466
|
-
let valueToPersistInternal = overlayValue;
|
|
467
|
-
if (schema?.shape && schema.shape[publicKey]) {
|
|
468
|
-
const field = schema.shape[publicKey];
|
|
469
|
-
if (field.safeParse) {
|
|
470
|
-
const res = field.safeParse(publicValue);
|
|
471
|
-
if (!res.success) throw new Error(`Invalid value for ${String(publicKey)}`);
|
|
472
|
-
const coerced = res.data;
|
|
473
|
-
const maybeInternal = aliasRule && aliasRule.toInternal ? aliasRule.toInternal(coerced) : coerced;
|
|
474
|
-
valueToPersistInternal = maybeInternal;
|
|
475
|
-
}
|
|
476
|
-
} else if (schema?.safeParse && currentPublic) {
|
|
477
|
-
const nextPublic = { ...currentPublic, [publicKey]: publicValue };
|
|
478
|
-
const res = schema.safeParse(nextPublic);
|
|
479
|
-
if (!res.success) throw new Error("Invalid values for commitTransients");
|
|
480
|
-
const parsed = res.data;
|
|
481
|
-
const parsedPublic = Object.prototype.hasOwnProperty.call(parsed, publicKey) ? parsed[publicKey] : publicValue;
|
|
482
|
-
const maybeInternal = aliasRule && aliasRule.toInternal ? aliasRule.toInternal(parsedPublic) : parsedPublic;
|
|
483
|
-
valueToPersistInternal = maybeInternal;
|
|
484
|
-
}
|
|
485
|
-
tree.setVertexProperty(id, internalKey, valueToPersistInternal);
|
|
486
|
-
}
|
|
487
|
-
};
|
|
488
|
-
}
|
|
489
|
-
if (typeof prop === "string") {
|
|
490
|
-
if (prop === "$id") return id;
|
|
491
|
-
if (prop === "$parentId") return tree.getVertex(id)?.parentId ?? null;
|
|
492
|
-
if (prop === "$parent") {
|
|
493
|
-
const vertex = tree.getVertex(id);
|
|
494
|
-
return vertex?.parent;
|
|
495
|
-
}
|
|
496
|
-
if (prop === "$children") return tree.getChildren(id);
|
|
497
|
-
if (prop === "$childrenIds") return tree.getChildrenIds(id);
|
|
498
|
-
if (prop === "$moveTo") {
|
|
499
|
-
if (!cachedMethods.has(prop)) {
|
|
500
|
-
cachedMethods.set(prop, (parent) => {
|
|
501
|
-
const parentId = typeof parent === "object" && parent !== null ? parent.id || parent.$id : parent;
|
|
502
|
-
tree.moveVertex(id, parentId);
|
|
503
|
-
});
|
|
504
|
-
}
|
|
505
|
-
return cachedMethods.get(prop);
|
|
506
|
-
}
|
|
507
|
-
if (prop === "$delete") {
|
|
508
|
-
if (!cachedMethods.has(prop)) {
|
|
509
|
-
cachedMethods.set(prop, () => tree.deleteVertex(id));
|
|
510
|
-
}
|
|
511
|
-
return cachedMethods.get(prop);
|
|
512
|
-
}
|
|
513
|
-
if (prop === "$observe") {
|
|
514
|
-
if (!cachedMethods.has(prop)) {
|
|
515
|
-
cachedMethods.set(prop, (listener) => tree.observe(id, listener));
|
|
516
|
-
}
|
|
517
|
-
return cachedMethods.get(prop);
|
|
518
|
-
}
|
|
519
|
-
if (prop === "$observeChildren") {
|
|
520
|
-
if (!cachedMethods.has(prop)) {
|
|
521
|
-
cachedMethods.set(prop, (listener) => {
|
|
522
|
-
return tree.observe(id, (events) => {
|
|
523
|
-
if (events.some((e) => e.type === "children")) {
|
|
524
|
-
listener(tree.getChildren(id));
|
|
525
|
-
}
|
|
526
|
-
});
|
|
527
|
-
});
|
|
528
|
-
}
|
|
529
|
-
return cachedMethods.get(prop);
|
|
530
|
-
}
|
|
531
|
-
if (prop === "$newChild") {
|
|
532
|
-
if (!cachedMethods.has(prop)) {
|
|
533
|
-
cachedMethods.set(prop, (props) => {
|
|
534
|
-
const vertex = tree.getVertex(id);
|
|
535
|
-
return vertex?.newChild(props);
|
|
536
|
-
});
|
|
537
|
-
}
|
|
538
|
-
return cachedMethods.get(prop);
|
|
387
|
+
const { publicToInternal } = buildAliasMaps(aliases);
|
|
388
|
+
const obj = {};
|
|
389
|
+
Object.defineProperties(obj, {
|
|
390
|
+
$vertex: { get: () => tree.getVertex(id), enumerable: false, configurable: true },
|
|
391
|
+
$id: { get: () => id, enumerable: false, configurable: true },
|
|
392
|
+
$parentId: { get: () => tree.getVertex(id)?.parentId ?? null, enumerable: false, configurable: true },
|
|
393
|
+
$parent: { get: () => tree.getVertex(id)?.parent, enumerable: false, configurable: true },
|
|
394
|
+
$children: { get: () => tree.getChildren(id), enumerable: false, configurable: true },
|
|
395
|
+
$childrenIds: { get: () => tree.getChildrenIds(id), enumerable: false, configurable: true },
|
|
396
|
+
$moveTo: {
|
|
397
|
+
value: (parent) => {
|
|
398
|
+
const parentId = typeof parent === "object" && parent !== null ? parent.id || parent.$id : parent;
|
|
399
|
+
tree.moveVertex(id, parentId);
|
|
400
|
+
},
|
|
401
|
+
enumerable: false,
|
|
402
|
+
configurable: true,
|
|
403
|
+
writable: false
|
|
404
|
+
},
|
|
405
|
+
$delete: { value: () => tree.deleteVertex(id), enumerable: false, configurable: true, writable: false },
|
|
406
|
+
$observe: { value: (listener) => tree.observe(id, listener), enumerable: false, configurable: true, writable: false },
|
|
407
|
+
$observeChildren: {
|
|
408
|
+
value: (listener) => tree.observe(id, (events) => {
|
|
409
|
+
if (events.some((e) => e.type === "children")) {
|
|
410
|
+
listener(tree.getChildren(id));
|
|
539
411
|
}
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
412
|
+
}),
|
|
413
|
+
enumerable: false,
|
|
414
|
+
configurable: true,
|
|
415
|
+
writable: false
|
|
416
|
+
},
|
|
417
|
+
$newChild: { value: (props) => tree.getVertex(id).newChild(props), enumerable: false, configurable: true, writable: false },
|
|
418
|
+
$newNamedChild: { value: (name, props) => tree.getVertex(id).newNamedChild(name, props), enumerable: false, configurable: true, writable: false },
|
|
419
|
+
$useTransients: {
|
|
420
|
+
value: function(fn) {
|
|
421
|
+
const transientProxy = new Proxy({}, {
|
|
422
|
+
set(_, prop, value) {
|
|
423
|
+
if (typeof prop === "string") {
|
|
424
|
+
const rule = publicToInternal.get(prop);
|
|
425
|
+
const internalKey = rule?.internalKey ?? prop;
|
|
426
|
+
const internalValue = rule?.toInternal ? rule.toInternal(value) : value;
|
|
427
|
+
tree.setTransientVertexProperty(id, internalKey, internalValue);
|
|
428
|
+
}
|
|
429
|
+
return true;
|
|
430
|
+
},
|
|
431
|
+
get(_, prop) {
|
|
432
|
+
if (typeof prop !== "string") return void 0;
|
|
433
|
+
const rule = publicToInternal.get(prop);
|
|
434
|
+
const internalKey = rule?.internalKey ?? prop;
|
|
435
|
+
const rawValue = tree.getVertexProperty(id, internalKey, true);
|
|
436
|
+
return rule?.toPublic ? rule.toPublic(rawValue) : rawValue;
|
|
546
437
|
}
|
|
547
|
-
|
|
438
|
+
});
|
|
439
|
+
fn(transientProxy);
|
|
440
|
+
},
|
|
441
|
+
enumerable: false,
|
|
442
|
+
configurable: true,
|
|
443
|
+
writable: false
|
|
444
|
+
},
|
|
445
|
+
$commitTransients: { value: () => tree.commitTransients(id), enumerable: false, configurable: true, writable: false },
|
|
446
|
+
equals: {
|
|
447
|
+
value: function(other) {
|
|
448
|
+
if (other && typeof other === "object" && "$id" in other) {
|
|
449
|
+
return other.$id === id;
|
|
548
450
|
}
|
|
451
|
+
return false;
|
|
452
|
+
},
|
|
453
|
+
enumerable: false,
|
|
454
|
+
configurable: true,
|
|
455
|
+
writable: false
|
|
456
|
+
}
|
|
457
|
+
});
|
|
458
|
+
const proxy = new Proxy(obj, {
|
|
459
|
+
get(target, prop, receiver) {
|
|
460
|
+
if (typeof prop !== "string") {
|
|
461
|
+
return Reflect.get(target, prop, receiver);
|
|
549
462
|
}
|
|
550
|
-
if (
|
|
551
|
-
|
|
552
|
-
if (rule) {
|
|
553
|
-
const raw = tree.getVertexProperty(id, rule.internalKey);
|
|
554
|
-
return rule.toPublic ? rule.toPublic(raw) : raw;
|
|
463
|
+
if (prop in target) {
|
|
464
|
+
return Reflect.get(target, prop, receiver);
|
|
555
465
|
}
|
|
556
|
-
|
|
466
|
+
const rule = publicToInternal.get(prop);
|
|
467
|
+
const internalKey = rule?.internalKey ?? prop;
|
|
468
|
+
const rawValue = tree.getVertexProperty(id, internalKey, true);
|
|
469
|
+
return rule?.toPublic ? rule.toPublic(rawValue) : rawValue;
|
|
557
470
|
},
|
|
558
|
-
set(
|
|
559
|
-
if (typeof prop !== "string")
|
|
560
|
-
|
|
561
|
-
return true;
|
|
562
|
-
}
|
|
563
|
-
if (VERTEX_PROPS.includes(prop)) {
|
|
564
|
-
return true;
|
|
565
|
-
}
|
|
566
|
-
if (VERTEX_METHODS.includes(prop)) {
|
|
567
|
-
return true;
|
|
471
|
+
set(target, prop, value) {
|
|
472
|
+
if (typeof prop !== "string") {
|
|
473
|
+
return Reflect.set(target, prop, value);
|
|
568
474
|
}
|
|
569
475
|
if (schema?.shape && schema.shape[prop]) {
|
|
570
476
|
const field = schema.shape[prop];
|
|
571
477
|
if (field.safeParse) {
|
|
572
478
|
const res = field.safeParse(value);
|
|
573
|
-
if (!res.success) throw new Error(`Invalid value for ${
|
|
574
|
-
value = res.data
|
|
575
|
-
}
|
|
576
|
-
} else if (schema?.safeParse) {
|
|
577
|
-
const next = { ...toPublicObject(tree, id, internalToPublic), [prop]: value };
|
|
578
|
-
const res = schema.safeParse(next);
|
|
579
|
-
if (!res.success) throw new Error(`Invalid value for ${String(prop)}`);
|
|
580
|
-
const parsed = res.data;
|
|
581
|
-
if (parsed && Object.prototype.hasOwnProperty.call(parsed, prop)) {
|
|
582
|
-
value = parsed[prop];
|
|
479
|
+
if (!res.success) throw new Error(`Invalid value for ${prop}`);
|
|
480
|
+
value = res.data;
|
|
583
481
|
}
|
|
584
482
|
}
|
|
585
483
|
const rule = publicToInternal.get(prop);
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
return true;
|
|
590
|
-
}
|
|
591
|
-
tree.setVertexProperty(id, prop, value);
|
|
484
|
+
const internalKey = rule?.internalKey ?? prop;
|
|
485
|
+
const internalValue = rule?.toInternal ? rule.toInternal(value) : value;
|
|
486
|
+
tree.setVertexProperty(id, internalKey, internalValue);
|
|
592
487
|
return true;
|
|
593
488
|
},
|
|
594
489
|
deleteProperty(_target, prop) {
|
|
595
|
-
if (typeof prop !== "string")
|
|
596
|
-
if (prop === RESERVED_METHOD_USE_TRANSIENT || prop === RESERVED_METHOD_COMMIT_TRANSIENTS) {
|
|
597
|
-
return true;
|
|
598
|
-
}
|
|
599
|
-
if (VERTEX_PROPS.includes(prop)) {
|
|
600
|
-
return true;
|
|
601
|
-
}
|
|
602
|
-
if (VERTEX_METHODS.includes(prop)) {
|
|
490
|
+
if (typeof prop !== "string") {
|
|
603
491
|
return true;
|
|
604
492
|
}
|
|
605
493
|
const rule = publicToInternal.get(prop);
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
return true;
|
|
609
|
-
}
|
|
610
|
-
tree.setVertexProperty(id, prop, void 0);
|
|
494
|
+
const internalKey = rule?.internalKey ?? prop;
|
|
495
|
+
tree.setVertexProperty(id, internalKey, void 0);
|
|
611
496
|
return true;
|
|
612
|
-
},
|
|
613
|
-
has(_target, prop) {
|
|
614
|
-
if (typeof prop !== "string") return false;
|
|
615
|
-
if (schema?.shape && Object.prototype.hasOwnProperty.call(schema.shape, prop)) return true;
|
|
616
|
-
if (includeInternalKeys) {
|
|
617
|
-
return publicToInternal.has(prop) || internalToPublic.has(prop);
|
|
618
|
-
}
|
|
619
|
-
return false;
|
|
620
|
-
},
|
|
621
|
-
ownKeys() {
|
|
622
|
-
const keys = /* @__PURE__ */ new Set();
|
|
623
|
-
for (const k of Object.keys(schema?.shape ?? {})) keys.add(k);
|
|
624
|
-
if (includeInternalKeys) {
|
|
625
|
-
for (const rule of aliases) keys.add(rule.internalKey);
|
|
626
|
-
}
|
|
627
|
-
return Array.from(keys);
|
|
628
|
-
},
|
|
629
|
-
getOwnPropertyDescriptor() {
|
|
630
|
-
return { enumerable: true, configurable: true };
|
|
631
497
|
}
|
|
632
498
|
});
|
|
499
|
+
return proxy;
|
|
633
500
|
}
|
|
634
501
|
|
|
635
502
|
// src/Vertex.ts
|
|
@@ -707,6 +574,9 @@ var Vertex = class _Vertex {
|
|
|
707
574
|
}
|
|
708
575
|
this.tree.setTransientVertexProperty(this.id, key, value);
|
|
709
576
|
}
|
|
577
|
+
commitTransients() {
|
|
578
|
+
this.tree.commitTransients(this.id);
|
|
579
|
+
}
|
|
710
580
|
setProperties(props) {
|
|
711
581
|
for (const [key, value] of Object.entries(props)) {
|
|
712
582
|
this.setProperty(key, value);
|
|
@@ -1183,6 +1053,20 @@ var _RepTree = class _RepTree {
|
|
|
1183
1053
|
this.localOps.push(op);
|
|
1184
1054
|
this.applyProperty(op);
|
|
1185
1055
|
}
|
|
1056
|
+
commitTransients(vertexId) {
|
|
1057
|
+
const vertex = this.state.getVertex(vertexId);
|
|
1058
|
+
if (!vertex) {
|
|
1059
|
+
return;
|
|
1060
|
+
}
|
|
1061
|
+
const transientProps = vertex.getTransientProperties();
|
|
1062
|
+
for (const prop of transientProps) {
|
|
1063
|
+
this.setVertexProperty(vertexId, prop.key, prop.value);
|
|
1064
|
+
}
|
|
1065
|
+
for (const prop of transientProps) {
|
|
1066
|
+
this.transientPropertiesAndTheirOpIds.delete(`${prop.key}@${vertexId}`);
|
|
1067
|
+
}
|
|
1068
|
+
vertex.clearAllTransientProperties();
|
|
1069
|
+
}
|
|
1186
1070
|
setVertexProperty(vertexId, key, value) {
|
|
1187
1071
|
this.lamportClock++;
|
|
1188
1072
|
let opValue;
|