reptree 0.2.3 → 0.3.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 CHANGED
@@ -26,7 +26,7 @@ npm install reptree
26
26
  ### Reactive vertex with Zod (optional)
27
27
 
28
28
  ```ts
29
- import { RepTree, bindVertex } from 'reptree';
29
+ import { RepTree } from 'reptree';
30
30
  import { z } from 'zod';
31
31
 
32
32
  const tree = new RepTree('peer1');
@@ -35,16 +35,25 @@ const v = root.newChild();
35
35
 
36
36
  const Person = z.object({ name: z.string(), age: z.number().int().min(0) });
37
37
 
38
- // Helper function form
39
- const person = bindVertex(tree, v.id, Person);
40
-
41
- // Or via instance method on Vertex
42
- // const person = v.bind(Person);
38
+ const person = v.bind(Person);
43
39
 
44
40
  person.name = 'Alice'; // validated and persisted
45
41
  person.age = 33; // validated and persisted
46
42
  ```
47
43
 
44
+ #### Aliases for internal fields
45
+
46
+ - `name` ↔ `_n`
47
+ - `createdAt` ↔ `_c` (Date exposed, ISO stored)
48
+
49
+ These aliases are applied by default when using `vertex.bind()`.
50
+
51
+ ```ts
52
+ person.name = 'Alice'; // writes _n
53
+ person.createdAt = new Date(); // writes _c (ISO)
54
+ console.log(person.createdAt instanceof Date); // true
55
+ ```
56
+
48
57
  For more, see `docs/reactive-vertices.md`.
49
58
 
50
59
  ```typescript
@@ -98,6 +107,15 @@ const ops = tree.getAllOps();
98
107
  otherTree.merge(ops);
99
108
  ```
100
109
 
110
+ ### Creating children with normalized props
111
+
112
+ `vertex.newChild(props)` and `vertex.newNamedChild(name, props)` accept plain objects. RepTree will:
113
+
114
+ - Map `name` → `_n`, `createdAt` (Date) → `_c` (ISO)
115
+ - Filter unsupported types (non-primitive objects except Y.Doc)
116
+ - Ignore `props.name` if `newNamedChild` has an explicit `name`
117
+ - Forbid nested children in props for now
118
+
101
119
  ## Yjs Integration
102
120
 
103
121
  RepTree supports [Yjs](https://github.com/yjs/yjs) documents as vertex properties, enabling real-time collaborative editing with a variety of shared data types:
package/dist/index.cjs CHANGED
@@ -36,6 +36,7 @@ __export(index_exports, {
36
36
  Vertex: () => Vertex,
37
37
  VertexState: () => VertexState,
38
38
  bindVertex: () => bindVertex,
39
+ defaultAliases: () => defaultAliases,
39
40
  isAnyPropertyOp: () => isAnyPropertyOp,
40
41
  isLWWPropertyOp: () => isLWWPropertyOp,
41
42
  isModifyPropertyOp: () => isModifyPropertyOp,
@@ -404,19 +405,217 @@ function uuid() {
404
405
  }
405
406
 
406
407
  // src/reactive.ts
407
- function toObject(tree, id) {
408
+ var defaultAliases = [
409
+ { publicKey: "name", internalKey: "_n" },
410
+ {
411
+ publicKey: "createdAt",
412
+ internalKey: "_c",
413
+ toPublic: (v) => typeof v === "string" ? new Date(v) : v,
414
+ toInternal: (v) => v instanceof Date ? v.toISOString() : v
415
+ }
416
+ ];
417
+ function buildAliasMaps(aliases) {
418
+ const publicToInternal = /* @__PURE__ */ new Map();
419
+ const internalToPublic = /* @__PURE__ */ new Map();
420
+ for (const rule of aliases) {
421
+ publicToInternal.set(rule.publicKey, rule);
422
+ internalToPublic.set(rule.internalKey, rule);
423
+ }
424
+ return { publicToInternal, internalToPublic };
425
+ }
426
+ function toPublicObject(tree, id, internalToPublic) {
408
427
  const obj = {};
409
- for (const { key, value } of tree.getVertexProperties(id)) obj[key] = value;
428
+ for (const { key, value } of tree.getVertexProperties(id)) {
429
+ const rule = internalToPublic.get(key);
430
+ if (rule) {
431
+ const converted = rule.toPublic ? rule.toPublic(value) : value;
432
+ obj[rule.publicKey] = converted;
433
+ } else {
434
+ obj[key] = value;
435
+ }
436
+ }
410
437
  return obj;
411
438
  }
412
- function bindVertex(tree, id, schema) {
439
+ var RESERVED_METHOD_USE_TRANSIENT = "useTransient";
440
+ var RESERVED_METHOD_COMMIT_TRANSIENTS = "commitTransients";
441
+ var VERTEX_PROPS = ["$id", "$parentId", "$parent", "$children", "$childrenIds"];
442
+ var VERTEX_METHODS = ["$moveTo", "$delete", "$observe", "$observeChildren", "$newChild", "$newNamedChild"];
443
+ function bindVertex(tree, id, schemaOrOptions) {
444
+ 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"));
445
+ const options = isOptions ? schemaOrOptions : { schema: schemaOrOptions };
446
+ const schema = options.schema;
447
+ const aliases = options.aliases ?? defaultAliases;
448
+ const includeInternalKeys = options.includeInternalKeys ?? false;
449
+ const { publicToInternal, internalToPublic } = buildAliasMaps(aliases);
450
+ const cachedMethods = /* @__PURE__ */ new Map();
413
451
  return new Proxy({}, {
414
452
  get(_target, prop) {
453
+ if (prop === RESERVED_METHOD_USE_TRANSIENT) {
454
+ return (fn) => {
455
+ const transientProxy = new Proxy({}, {
456
+ get(_t, p) {
457
+ if (typeof p !== "string") return void 0;
458
+ const rule2 = publicToInternal.get(p);
459
+ if (rule2) {
460
+ const raw = tree.getVertexProperty(id, rule2.internalKey);
461
+ return rule2.toPublic ? rule2.toPublic(raw) : raw;
462
+ }
463
+ return tree.getVertexProperty(id, p);
464
+ },
465
+ set(_t, p, value) {
466
+ if (typeof p !== "string") return true;
467
+ if (schema?.shape && schema.shape[p]) {
468
+ const field = schema.shape[p];
469
+ if (field.safeParse) {
470
+ const res = field.safeParse(value);
471
+ if (!res.success) throw new Error(`Invalid value for ${String(p)}`);
472
+ value = res.data ?? value;
473
+ }
474
+ } else if (schema?.safeParse) {
475
+ const next = { ...toPublicObject(tree, id, internalToPublic), [p]: value };
476
+ const res = schema.safeParse(next);
477
+ if (!res.success) throw new Error(`Invalid value for ${String(p)}`);
478
+ const parsed = res.data;
479
+ if (parsed && Object.prototype.hasOwnProperty.call(parsed, p)) {
480
+ value = parsed[p];
481
+ }
482
+ }
483
+ const rule2 = publicToInternal.get(p);
484
+ if (rule2) {
485
+ const converted = rule2.toInternal ? rule2.toInternal(value) : value;
486
+ tree.setTransientVertexProperty(id, rule2.internalKey, converted);
487
+ return true;
488
+ }
489
+ tree.setTransientVertexProperty(id, p, value);
490
+ return true;
491
+ },
492
+ deleteProperty(_t, p) {
493
+ if (typeof p !== "string") return true;
494
+ const rule2 = publicToInternal.get(p);
495
+ if (rule2) {
496
+ tree.setTransientVertexProperty(id, rule2.internalKey, void 0);
497
+ return true;
498
+ }
499
+ tree.setTransientVertexProperty(id, p, void 0);
500
+ return true;
501
+ }
502
+ });
503
+ fn(transientProxy);
504
+ };
505
+ }
506
+ if (prop === RESERVED_METHOD_COMMIT_TRANSIENTS) {
507
+ return () => {
508
+ const entries = tree.getVertexProperties(id);
509
+ const currentPublic = schema?.safeParse ? toPublicObject(tree, id, internalToPublic) : void 0;
510
+ for (const { key: internalKey, value: overlayValue } of entries) {
511
+ const persistentValue = tree.getVertexProperty(id, internalKey, false);
512
+ if (overlayValue === persistentValue) continue;
513
+ const aliasRule = internalToPublic.get(internalKey);
514
+ const publicKey = aliasRule ? aliasRule.publicKey : internalKey;
515
+ const publicValue = aliasRule && aliasRule.toPublic ? aliasRule.toPublic(overlayValue) : overlayValue;
516
+ let valueToPersistInternal = overlayValue;
517
+ if (schema?.shape && schema.shape[publicKey]) {
518
+ const field = schema.shape[publicKey];
519
+ if (field.safeParse) {
520
+ const res = field.safeParse(publicValue);
521
+ if (!res.success) throw new Error(`Invalid value for ${String(publicKey)}`);
522
+ const coerced = res.data;
523
+ const maybeInternal = aliasRule && aliasRule.toInternal ? aliasRule.toInternal(coerced) : coerced;
524
+ valueToPersistInternal = maybeInternal;
525
+ }
526
+ } else if (schema?.safeParse && currentPublic) {
527
+ const nextPublic = { ...currentPublic, [publicKey]: publicValue };
528
+ const res = schema.safeParse(nextPublic);
529
+ if (!res.success) throw new Error("Invalid values for commitTransients");
530
+ const parsed = res.data;
531
+ const parsedPublic = Object.prototype.hasOwnProperty.call(parsed, publicKey) ? parsed[publicKey] : publicValue;
532
+ const maybeInternal = aliasRule && aliasRule.toInternal ? aliasRule.toInternal(parsedPublic) : parsedPublic;
533
+ valueToPersistInternal = maybeInternal;
534
+ }
535
+ tree.setVertexProperty(id, internalKey, valueToPersistInternal);
536
+ }
537
+ };
538
+ }
539
+ if (typeof prop === "string") {
540
+ if (prop === "$id") return id;
541
+ if (prop === "$parentId") return tree.getVertex(id)?.parentId ?? null;
542
+ if (prop === "$parent") {
543
+ const vertex = tree.getVertex(id);
544
+ return vertex?.parent;
545
+ }
546
+ if (prop === "$children") return tree.getChildren(id);
547
+ if (prop === "$childrenIds") return tree.getChildrenIds(id);
548
+ if (prop === "$moveTo") {
549
+ if (!cachedMethods.has(prop)) {
550
+ cachedMethods.set(prop, (parent) => {
551
+ const parentId = typeof parent === "object" && parent !== null ? parent.id || parent.$id : parent;
552
+ tree.moveVertex(id, parentId);
553
+ });
554
+ }
555
+ return cachedMethods.get(prop);
556
+ }
557
+ if (prop === "$delete") {
558
+ if (!cachedMethods.has(prop)) {
559
+ cachedMethods.set(prop, () => tree.deleteVertex(id));
560
+ }
561
+ return cachedMethods.get(prop);
562
+ }
563
+ if (prop === "$observe") {
564
+ if (!cachedMethods.has(prop)) {
565
+ cachedMethods.set(prop, (listener) => tree.observe(id, listener));
566
+ }
567
+ return cachedMethods.get(prop);
568
+ }
569
+ if (prop === "$observeChildren") {
570
+ if (!cachedMethods.has(prop)) {
571
+ cachedMethods.set(prop, (listener) => {
572
+ return tree.observe(id, (events) => {
573
+ if (events.some((e) => e.type === "children")) {
574
+ listener(tree.getChildren(id));
575
+ }
576
+ });
577
+ });
578
+ }
579
+ return cachedMethods.get(prop);
580
+ }
581
+ if (prop === "$newChild") {
582
+ if (!cachedMethods.has(prop)) {
583
+ cachedMethods.set(prop, (props) => {
584
+ const vertex = tree.getVertex(id);
585
+ return vertex?.newChild(props);
586
+ });
587
+ }
588
+ return cachedMethods.get(prop);
589
+ }
590
+ if (prop === "$newNamedChild") {
591
+ if (!cachedMethods.has(prop)) {
592
+ cachedMethods.set(prop, (name, props) => {
593
+ const vertex = tree.getVertex(id);
594
+ return vertex?.newNamedChild(name, props);
595
+ });
596
+ }
597
+ return cachedMethods.get(prop);
598
+ }
599
+ }
415
600
  if (typeof prop !== "string") return void 0;
601
+ const rule = publicToInternal.get(prop);
602
+ if (rule) {
603
+ const raw = tree.getVertexProperty(id, rule.internalKey);
604
+ return rule.toPublic ? rule.toPublic(raw) : raw;
605
+ }
416
606
  return tree.getVertexProperty(id, prop);
417
607
  },
418
608
  set(_target, prop, value) {
419
609
  if (typeof prop !== "string") return true;
610
+ if (prop === RESERVED_METHOD_USE_TRANSIENT || prop === RESERVED_METHOD_COMMIT_TRANSIENTS) {
611
+ return true;
612
+ }
613
+ if (VERTEX_PROPS.includes(prop)) {
614
+ return true;
615
+ }
616
+ if (VERTEX_METHODS.includes(prop)) {
617
+ return true;
618
+ }
420
619
  if (schema?.shape && schema.shape[prop]) {
421
620
  const field = schema.shape[prop];
422
621
  if (field.safeParse) {
@@ -425,7 +624,7 @@ function bindVertex(tree, id, schema) {
425
624
  value = res.data ?? value;
426
625
  }
427
626
  } else if (schema?.safeParse) {
428
- const next = { ...toObject(tree, id), [prop]: value };
627
+ const next = { ...toPublicObject(tree, id, internalToPublic), [prop]: value };
429
628
  const res = schema.safeParse(next);
430
629
  if (!res.success) throw new Error(`Invalid value for ${String(prop)}`);
431
630
  const parsed = res.data;
@@ -433,20 +632,49 @@ function bindVertex(tree, id, schema) {
433
632
  value = parsed[prop];
434
633
  }
435
634
  }
635
+ const rule = publicToInternal.get(prop);
636
+ if (rule) {
637
+ const converted = rule.toInternal ? rule.toInternal(value) : value;
638
+ tree.setVertexProperty(id, rule.internalKey, converted);
639
+ return true;
640
+ }
436
641
  tree.setVertexProperty(id, prop, value);
437
642
  return true;
438
643
  },
439
644
  deleteProperty(_target, prop) {
440
645
  if (typeof prop !== "string") return true;
646
+ if (prop === RESERVED_METHOD_USE_TRANSIENT || prop === RESERVED_METHOD_COMMIT_TRANSIENTS) {
647
+ return true;
648
+ }
649
+ if (VERTEX_PROPS.includes(prop)) {
650
+ return true;
651
+ }
652
+ if (VERTEX_METHODS.includes(prop)) {
653
+ return true;
654
+ }
655
+ const rule = publicToInternal.get(prop);
656
+ if (rule) {
657
+ tree.setVertexProperty(id, rule.internalKey, void 0);
658
+ return true;
659
+ }
441
660
  tree.setVertexProperty(id, prop, void 0);
442
661
  return true;
443
662
  },
444
663
  has(_target, prop) {
445
664
  if (typeof prop !== "string") return false;
446
- return !!schema?.shape && Object.prototype.hasOwnProperty.call(schema.shape, prop);
665
+ if (schema?.shape && Object.prototype.hasOwnProperty.call(schema.shape, prop)) return true;
666
+ if (includeInternalKeys) {
667
+ return publicToInternal.has(prop) || internalToPublic.has(prop);
668
+ }
669
+ return false;
447
670
  },
448
671
  ownKeys() {
449
- return Object.keys(schema?.shape ?? {});
672
+ const keys = /* @__PURE__ */ new Set();
673
+ for (const k of Object.keys(schema?.shape ?? {})) keys.add(k);
674
+ if (includeInternalKeys) {
675
+ for (const rule of aliases) keys.add(rule.internalKey);
676
+ }
677
+ return Array.from(keys);
450
678
  },
451
679
  getOwnPropertyDescriptor() {
452
680
  return { enumerable: true, configurable: true };
@@ -455,7 +683,8 @@ function bindVertex(tree, id, schema) {
455
683
  }
456
684
 
457
685
  // src/Vertex.ts
458
- var Vertex = class {
686
+ var Y = __toESM(require("yjs"), 1);
687
+ var Vertex = class _Vertex {
459
688
  constructor(tree, state) {
460
689
  this.tree = tree;
461
690
  this.state = state;
@@ -501,12 +730,18 @@ var Vertex = class {
501
730
  return this.children.map((v) => v.getAsTypedObject());
502
731
  }
503
732
  newChild(props) {
504
- const typedProps = props;
505
- return this.tree.newVertex(this.id, typedProps);
733
+ if (props && typeof props === "object" && "children" in props) {
734
+ throw new Error("Passing children inside props is not supported at the moment");
735
+ }
736
+ const normalized = _Vertex.normalizePropsForCreation(props);
737
+ return this.tree.newVertex(this.id, normalized);
506
738
  }
507
739
  newNamedChild(name, props) {
508
- const typedProps = props;
509
- return this.tree.newNamedVertex(this.id, name, typedProps);
740
+ if (props && typeof props === "object" && "children" in props) {
741
+ throw new Error("Passing children inside props is not supported at the moment");
742
+ }
743
+ const normalized = _Vertex.normalizePropsForCreation(props, name);
744
+ return this.tree.newNamedVertex(this.id, name, normalized);
510
745
  }
511
746
  setProperty(key, value) {
512
747
  const existingValue = this.getProperty(key, false);
@@ -572,9 +807,67 @@ var Vertex = class {
572
807
  moveTo(parent) {
573
808
  this.tree.moveVertex(this.id, parent.id);
574
809
  }
575
- /** Returns a live reactive object bound to this vertex. Optional schema validates writes. */
576
- bind(schema) {
577
- return bindVertex(this.tree, this.id, schema);
810
+ /** Returns a live reactive object bound to this vertex. Accepts schema or options. */
811
+ bind(schemaOrOptions) {
812
+ return bindVertex(this.tree, this.id, schemaOrOptions);
813
+ }
814
+ /**
815
+ * Normalizes an input props object for vertex creation:
816
+ * - Aliases name -> _n, createdAt -> _c (Date -> ISO string)
817
+ * - Filters unsupported field types with a console warning
818
+ * - When a name param is provided to newNamedChild, ignores conflicting name in props
819
+ */
820
+ static normalizePropsForCreation(props, explicitName) {
821
+ if (!props) return null;
822
+ const input = props;
823
+ const out = {};
824
+ const skipped = [];
825
+ for (const [rawKey, rawValue] of Object.entries(input)) {
826
+ if (rawValue === void 0) {
827
+ continue;
828
+ }
829
+ if (rawKey === "children") continue;
830
+ let key = rawKey;
831
+ if (rawKey === "name") {
832
+ if (explicitName !== void 0) {
833
+ console.warn('newNamedChild: "name" in props is ignored because a name argument was provided');
834
+ continue;
835
+ }
836
+ key = "_n";
837
+ } else if (rawKey === "createdAt") {
838
+ key = "_c";
839
+ }
840
+ let value = rawValue;
841
+ if (key === "_c") {
842
+ if (value instanceof Date) {
843
+ value = value.toISOString();
844
+ } else if (typeof value === "string") {
845
+ } else {
846
+ skipped.push(rawKey);
847
+ continue;
848
+ }
849
+ }
850
+ const isPrimitive = (v) => typeof v === "string" || typeof v === "number" || typeof v === "boolean";
851
+ if (Array.isArray(value)) {
852
+ if (!value.every(isPrimitive)) {
853
+ skipped.push(rawKey);
854
+ continue;
855
+ }
856
+ } else if (typeof value === "object" && value !== null) {
857
+ if (!(value instanceof Y.Doc)) {
858
+ skipped.push(rawKey);
859
+ continue;
860
+ }
861
+ } else if (!isPrimitive(value)) {
862
+ skipped.push(rawKey);
863
+ continue;
864
+ }
865
+ out[key] = value;
866
+ }
867
+ if (skipped.length > 0) {
868
+ console.warn(`Some fields were skipped due to unsupported types: ${skipped.join(", ")}`);
869
+ }
870
+ return Object.keys(out).length > 0 ? out : null;
578
871
  }
579
872
  };
580
873
 
@@ -764,7 +1057,7 @@ var StateVector = class _StateVector {
764
1057
  };
765
1058
 
766
1059
  // src/RepTree.ts
767
- var Y = __toESM(require("yjs"), 1);
1060
+ var Y2 = __toESM(require("yjs"), 1);
768
1061
  var _RepTree = class _RepTree {
769
1062
  /**
770
1063
  * @param peerId - The peer ID of the current client. Should be unique across all peers.
@@ -926,8 +1219,8 @@ var _RepTree = class _RepTree {
926
1219
  setTransientVertexProperty(vertexId, key, value) {
927
1220
  this.lamportClock++;
928
1221
  let opValue;
929
- if (value instanceof Y.Doc) {
930
- const state = Y.encodeStateAsUpdate(value);
1222
+ if (value instanceof Y2.Doc) {
1223
+ const state = Y2.encodeStateAsUpdate(value);
931
1224
  opValue = {
932
1225
  type: "yjs",
933
1226
  value: state
@@ -943,8 +1236,8 @@ var _RepTree = class _RepTree {
943
1236
  setVertexProperty(vertexId, key, value) {
944
1237
  this.lamportClock++;
945
1238
  let opValue;
946
- if (value instanceof Y.Doc) {
947
- const state = Y.encodeStateAsUpdate(value);
1239
+ if (value instanceof Y2.Doc) {
1240
+ const state = Y2.encodeStateAsUpdate(value);
948
1241
  opValue = {
949
1242
  type: "yjs",
950
1243
  value: state
@@ -1116,10 +1409,10 @@ var _RepTree = class _RepTree {
1116
1409
  if (!propB) {
1117
1410
  return false;
1118
1411
  }
1119
- if (propA.value instanceof Y.Doc && propB.value instanceof Y.Doc) {
1120
- const snapshotA = Y.snapshot(propA.value);
1121
- const snapshotB = Y.snapshot(propB.value);
1122
- if (!Y.equalSnapshots(snapshotA, snapshotB)) {
1412
+ if (propA.value instanceof Y2.Doc && propB.value instanceof Y2.Doc) {
1413
+ const snapshotA = Y2.snapshot(propA.value);
1414
+ const snapshotB = Y2.snapshot(propB.value);
1415
+ if (!Y2.equalSnapshots(snapshotA, snapshotB)) {
1123
1416
  return false;
1124
1417
  }
1125
1418
  } else if (propA.value !== propB.value) {
@@ -1223,7 +1516,7 @@ var _RepTree = class _RepTree {
1223
1516
  const propertyKey = `${key}@${vertexId}`;
1224
1517
  if (this.yjsObservers.has(propertyKey)) {
1225
1518
  const existingDoc = this.getVertexProperty(vertexId, key);
1226
- if (existingDoc instanceof Y.Doc) {
1519
+ if (existingDoc instanceof Y2.Doc) {
1227
1520
  existingDoc.off("update", this.yjsObservers.get(propertyKey));
1228
1521
  }
1229
1522
  this.yjsObservers.delete(propertyKey);
@@ -1303,13 +1596,13 @@ var _RepTree = class _RepTree {
1303
1596
  throw new Error("Unknown CRDT type");
1304
1597
  }
1305
1598
  const ydoc = targetVertex.getProperty(op.key);
1306
- if (ydoc instanceof Y.Doc) {
1307
- Y.applyUpdate(ydoc, crdtValue.value);
1599
+ if (ydoc instanceof Y2.Doc) {
1600
+ Y2.applyUpdate(ydoc, crdtValue.value);
1308
1601
  } else {
1309
- const newDoc = new Y.Doc();
1602
+ const newDoc = new Y2.Doc();
1310
1603
  this.setupYjsObserver(newDoc, op.targetId, op.key);
1311
1604
  this.state.setProperty(op.targetId, op.key, newDoc);
1312
- Y.applyUpdate(newDoc, crdtValue.value);
1605
+ Y2.applyUpdate(newDoc, crdtValue.value);
1313
1606
  }
1314
1607
  this.propertiesAndTheirOpIds.set(`${op.key}@${op.targetId}`, op.id);
1315
1608
  this.reportOpAsApplied(op);
@@ -1437,6 +1730,7 @@ var RepTree = _RepTree;
1437
1730
  Vertex,
1438
1731
  VertexState,
1439
1732
  bindVertex,
1733
+ defaultAliases,
1440
1734
  isAnyPropertyOp,
1441
1735
  isLWWPropertyOp,
1442
1736
  isModifyPropertyOp,