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.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
- /** Vertex methods (prefixed with $ to avoid conflicts) */
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 object that proxies reads/writes to a vertex.
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
- /** Vertex methods (prefixed with $ to avoid conflicts) */
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 object that proxies reads/writes to a vertex.
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 includeInternalKeys = options.includeInternalKeys ?? false;
399
- const { publicToInternal, internalToPublic } = buildAliasMaps(aliases);
400
- const cachedMethods = /* @__PURE__ */ new Map();
401
- return new Proxy({}, {
402
- get(_target, prop) {
403
- if (prop === RESERVED_METHOD_USE_TRANSIENT) {
404
- return (fn) => {
405
- const transientProxy = new Proxy({}, {
406
- get(_t, p) {
407
- if (typeof p !== "string") return void 0;
408
- const rule2 = publicToInternal.get(p);
409
- if (rule2) {
410
- const raw = tree.getVertexProperty(id, rule2.internalKey);
411
- return rule2.toPublic ? rule2.toPublic(raw) : raw;
412
- }
413
- return tree.getVertexProperty(id, p);
414
- },
415
- set(_t, p, value) {
416
- if (typeof p !== "string") return true;
417
- if (schema?.shape && schema.shape[p]) {
418
- const field = schema.shape[p];
419
- if (field.safeParse) {
420
- const res = field.safeParse(value);
421
- if (!res.success) throw new Error(`Invalid value for ${String(p)}`);
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
- if (prop === "$newNamedChild") {
541
- if (!cachedMethods.has(prop)) {
542
- cachedMethods.set(prop, (name, props) => {
543
- const vertex = tree.getVertex(id);
544
- return vertex?.newNamedChild(name, props);
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
- return cachedMethods.get(prop);
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 (typeof prop !== "string") return void 0;
551
- const rule = publicToInternal.get(prop);
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
- return tree.getVertexProperty(id, prop);
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(_target, prop, value) {
559
- if (typeof prop !== "string") return true;
560
- if (prop === RESERVED_METHOD_USE_TRANSIENT || prop === RESERVED_METHOD_COMMIT_TRANSIENTS) {
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 ${String(prop)}`);
574
- value = res.data ?? value;
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
- if (rule) {
587
- const converted = rule.toInternal ? rule.toInternal(value) : value;
588
- tree.setVertexProperty(id, rule.internalKey, converted);
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") return true;
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
- if (rule) {
607
- tree.setVertexProperty(id, rule.internalKey, void 0);
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;