reptree 0.6.0 → 0.7.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 +3 -3
- package/dist/index.cjs +103 -25
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +11 -10
- package/dist/index.d.ts +11 -10
- package/dist/index.js +103 -25
- package/dist/index.js.map +1 -1
- package/package.json +2 -4
package/README.md
CHANGED
|
@@ -33,9 +33,10 @@ const qa = company.newNamedChild("qa");
|
|
|
33
33
|
// Create a vertex in another vertex
|
|
34
34
|
const alice = qa.newChild();
|
|
35
35
|
|
|
36
|
-
// Set properties
|
|
36
|
+
// Set properties (supports any JSON-serializable values)
|
|
37
37
|
alice.setProperty("name", "Alice");
|
|
38
38
|
alice.setProperty("age", 32);
|
|
39
|
+
alice.setProperty("meta", { department: "QA", skills: ["cypress", "playwright"], flags: { lead: false } });
|
|
39
40
|
|
|
40
41
|
// Move the vertex inside a different vertex
|
|
41
42
|
alice.moveTo(devs);
|
|
@@ -89,8 +90,7 @@ const logoFile = imagesFolder.newNamedChild("logo.png");
|
|
|
89
90
|
logoFile.setProperties({
|
|
90
91
|
type: "file",
|
|
91
92
|
size: 15360,
|
|
92
|
-
dimensions: "512x512",
|
|
93
|
-
format: "png",
|
|
93
|
+
meta: { dimensions: "512x512", format: "png" },
|
|
94
94
|
s3Path: "s3://my-bucket/images/logo.png",
|
|
95
95
|
});
|
|
96
96
|
|
package/dist/index.cjs
CHANGED
|
@@ -385,7 +385,7 @@ var TreeState = class {
|
|
|
385
385
|
}
|
|
386
386
|
};
|
|
387
387
|
|
|
388
|
-
// src/uuid.ts
|
|
388
|
+
// src/utils/uuid.ts
|
|
389
389
|
var removeDashes = (guid) => guid.replace(/-/g, "");
|
|
390
390
|
function uuid() {
|
|
391
391
|
return removeDashes(crypto.randomUUID());
|
|
@@ -555,7 +555,7 @@ var Vertex = class _Vertex {
|
|
|
555
555
|
if (props && typeof props === "object" && "children" in props) {
|
|
556
556
|
throw new Error("Passing children inside props is not supported at the moment");
|
|
557
557
|
}
|
|
558
|
-
const normalized = _Vertex.normalizePropsForCreation(props
|
|
558
|
+
const normalized = _Vertex.normalizePropsForCreation(props);
|
|
559
559
|
return this.tree.newNamedVertex(this.id, name, normalized);
|
|
560
560
|
}
|
|
561
561
|
setProperty(key, value) {
|
|
@@ -634,21 +634,32 @@ var Vertex = class _Vertex {
|
|
|
634
634
|
* - Filters unsupported field types with a console warning
|
|
635
635
|
* - When a name param is provided to newNamedChild, ignores conflicting name in props
|
|
636
636
|
*/
|
|
637
|
-
static normalizePropsForCreation(props
|
|
637
|
+
static normalizePropsForCreation(props) {
|
|
638
638
|
if (!props) return null;
|
|
639
639
|
const input = props;
|
|
640
640
|
const out = {};
|
|
641
641
|
const skipped = [];
|
|
642
|
+
const isJsonValue2 = (v) => {
|
|
643
|
+
if (v === null) return true;
|
|
644
|
+
const t = typeof v;
|
|
645
|
+
if (t === "string" || t === "number" || t === "boolean") return true;
|
|
646
|
+
if (Array.isArray(v)) return v.every(isJsonValue2);
|
|
647
|
+
if (t === "object") {
|
|
648
|
+
const proto = Object.getPrototypeOf(v);
|
|
649
|
+
if (proto !== Object.prototype && proto !== null) return false;
|
|
650
|
+
for (const val of Object.values(v)) {
|
|
651
|
+
if (!isJsonValue2(val)) return false;
|
|
652
|
+
}
|
|
653
|
+
return true;
|
|
654
|
+
}
|
|
655
|
+
return false;
|
|
656
|
+
};
|
|
642
657
|
for (const [rawKey, rawValue] of Object.entries(input)) {
|
|
643
658
|
if (rawValue === void 0) {
|
|
644
659
|
continue;
|
|
645
660
|
}
|
|
646
661
|
if (rawKey === "children") continue;
|
|
647
662
|
let key = rawKey;
|
|
648
|
-
if (rawKey === "name" && explicitName !== void 0) {
|
|
649
|
-
console.warn('newNamedChild: "name" in props is ignored because a name argument was provided');
|
|
650
|
-
continue;
|
|
651
|
-
}
|
|
652
663
|
let value = rawValue;
|
|
653
664
|
if (key === "_c") {
|
|
654
665
|
if (value instanceof Date) {
|
|
@@ -659,23 +670,14 @@ var Vertex = class _Vertex {
|
|
|
659
670
|
continue;
|
|
660
671
|
}
|
|
661
672
|
}
|
|
662
|
-
|
|
663
|
-
if (Array.isArray(value)) {
|
|
664
|
-
if (!value.every(isPrimitive)) {
|
|
665
|
-
skipped.push(rawKey);
|
|
666
|
-
continue;
|
|
667
|
-
}
|
|
668
|
-
} else if (typeof value === "object" && value !== null) {
|
|
669
|
-
skipped.push(rawKey);
|
|
670
|
-
continue;
|
|
671
|
-
} else if (!isPrimitive(value)) {
|
|
673
|
+
if (!isJsonValue2(value)) {
|
|
672
674
|
skipped.push(rawKey);
|
|
673
675
|
continue;
|
|
674
676
|
}
|
|
675
677
|
out[key] = value;
|
|
676
678
|
}
|
|
677
679
|
if (skipped.length > 0) {
|
|
678
|
-
|
|
680
|
+
throw new Error(`Unsupported property types for keys: ${skipped.join(", ")}`);
|
|
679
681
|
}
|
|
680
682
|
return Object.keys(out).length > 0 ? out : null;
|
|
681
683
|
}
|
|
@@ -866,6 +868,61 @@ var StateVector = class _StateVector {
|
|
|
866
868
|
}
|
|
867
869
|
};
|
|
868
870
|
|
|
871
|
+
// src/utils/deepEqual.ts
|
|
872
|
+
function deepEqual(a, b) {
|
|
873
|
+
if (a === b) return true;
|
|
874
|
+
if (a === null || b === null) return a === b;
|
|
875
|
+
const ta = typeof a;
|
|
876
|
+
const tb = typeof b;
|
|
877
|
+
if (ta !== tb) return false;
|
|
878
|
+
if (ta !== "object") return false;
|
|
879
|
+
const aIsArr = Array.isArray(a);
|
|
880
|
+
const bIsArr = Array.isArray(b);
|
|
881
|
+
if (aIsArr || bIsArr) {
|
|
882
|
+
if (!(aIsArr && bIsArr)) return false;
|
|
883
|
+
if (a.length !== b.length) return false;
|
|
884
|
+
for (let i = 0; i < a.length; i++) {
|
|
885
|
+
if (!deepEqual(a[i], b[i])) return false;
|
|
886
|
+
}
|
|
887
|
+
return true;
|
|
888
|
+
}
|
|
889
|
+
const aProto = Object.getPrototypeOf(a);
|
|
890
|
+
const bProto = Object.getPrototypeOf(b);
|
|
891
|
+
if (aProto !== Object.prototype && aProto !== null || bProto !== Object.prototype && bProto !== null) {
|
|
892
|
+
return false;
|
|
893
|
+
}
|
|
894
|
+
const aKeys = Object.keys(a);
|
|
895
|
+
const bKeys = Object.keys(b);
|
|
896
|
+
if (aKeys.length !== bKeys.length) return false;
|
|
897
|
+
for (const key of aKeys) {
|
|
898
|
+
if (!Object.prototype.hasOwnProperty.call(b, key)) return false;
|
|
899
|
+
if (!deepEqual(a[key], b[key])) return false;
|
|
900
|
+
}
|
|
901
|
+
return true;
|
|
902
|
+
}
|
|
903
|
+
|
|
904
|
+
// src/utils/isJsonValue.ts
|
|
905
|
+
function isJsonValue(v) {
|
|
906
|
+
if (v === void 0) return true;
|
|
907
|
+
if (v === null) return true;
|
|
908
|
+
const t = typeof v;
|
|
909
|
+
if (t === "string" || t === "number" || t === "boolean") return true;
|
|
910
|
+
if (t === "bigint" || t === "function" || t === "symbol") return false;
|
|
911
|
+
if (Array.isArray(v)) return v.every(isJsonValue);
|
|
912
|
+
if (t === "object") {
|
|
913
|
+
if (v instanceof Date) return false;
|
|
914
|
+
if (v instanceof Map || v instanceof Set || v instanceof RegExp) return false;
|
|
915
|
+
if (ArrayBuffer.isView(v)) return false;
|
|
916
|
+
const proto = Object.getPrototypeOf(v);
|
|
917
|
+
if (proto !== Object.prototype && proto !== null) return false;
|
|
918
|
+
for (const val of Object.values(v)) {
|
|
919
|
+
if (!isJsonValue(val)) return false;
|
|
920
|
+
}
|
|
921
|
+
return true;
|
|
922
|
+
}
|
|
923
|
+
return false;
|
|
924
|
+
}
|
|
925
|
+
|
|
869
926
|
// src/RepTree.ts
|
|
870
927
|
var _RepTree = class _RepTree {
|
|
871
928
|
/**
|
|
@@ -1032,6 +1089,9 @@ var _RepTree = class _RepTree {
|
|
|
1032
1089
|
this.moveVertex(vertexId, _RepTree.NULL_VERTEX_ID);
|
|
1033
1090
|
}
|
|
1034
1091
|
setTransientVertexProperty(vertexId, key, value) {
|
|
1092
|
+
if (!isJsonValue(value)) {
|
|
1093
|
+
throw new Error(`Unsupported transient property value for key "${key}"`);
|
|
1094
|
+
}
|
|
1035
1095
|
this.lamportClock++;
|
|
1036
1096
|
const op = newSetTransientVertexPropertyOp(this.lamportClock, this.peerId, vertexId, key, value);
|
|
1037
1097
|
this.localOps.push(op);
|
|
@@ -1057,6 +1117,29 @@ var _RepTree = class _RepTree {
|
|
|
1057
1117
|
vertex.clearAllTransientProperties();
|
|
1058
1118
|
}
|
|
1059
1119
|
setVertexProperty(vertexId, key, value) {
|
|
1120
|
+
const isJsonValue2 = (v) => {
|
|
1121
|
+
if (v === void 0) return true;
|
|
1122
|
+
if (v === null) return true;
|
|
1123
|
+
const t = typeof v;
|
|
1124
|
+
if (t === "string" || t === "number" || t === "boolean") return true;
|
|
1125
|
+
if (t === "bigint" || t === "function" || t === "symbol") return false;
|
|
1126
|
+
if (Array.isArray(v)) return v.every(isJsonValue2);
|
|
1127
|
+
if (t === "object") {
|
|
1128
|
+
if (v instanceof Date) return false;
|
|
1129
|
+
if (v instanceof Map || v instanceof Set || v instanceof RegExp) return false;
|
|
1130
|
+
if (ArrayBuffer.isView(v)) return false;
|
|
1131
|
+
const proto = Object.getPrototypeOf(v);
|
|
1132
|
+
if (proto !== Object.prototype && proto !== null) return false;
|
|
1133
|
+
for (const val of Object.values(v)) {
|
|
1134
|
+
if (!isJsonValue2(val)) return false;
|
|
1135
|
+
}
|
|
1136
|
+
return true;
|
|
1137
|
+
}
|
|
1138
|
+
return false;
|
|
1139
|
+
};
|
|
1140
|
+
if (!isJsonValue2(value)) {
|
|
1141
|
+
throw new Error(`Unsupported property value for key "${key}"`);
|
|
1142
|
+
}
|
|
1060
1143
|
this.lamportClock++;
|
|
1061
1144
|
const op = newSetVertexPropertyOp(this.lamportClock, this.peerId, vertexId, key, value);
|
|
1062
1145
|
this.localOps.push(op);
|
|
@@ -1218,12 +1301,8 @@ var _RepTree = class _RepTree {
|
|
|
1218
1301
|
}
|
|
1219
1302
|
for (const propA of propertiesA) {
|
|
1220
1303
|
const propB = propertiesB.find((p) => p.key === propA.key);
|
|
1221
|
-
if (!propB)
|
|
1222
|
-
|
|
1223
|
-
}
|
|
1224
|
-
if (propA.value !== propB.value) {
|
|
1225
|
-
return false;
|
|
1226
|
-
}
|
|
1304
|
+
if (!propB) return false;
|
|
1305
|
+
if (!deepEqual(propA.value, propB.value)) return false;
|
|
1227
1306
|
}
|
|
1228
1307
|
}
|
|
1229
1308
|
for (const childId of childrenA) {
|
|
@@ -1353,7 +1432,6 @@ var _RepTree = class _RepTree {
|
|
|
1353
1432
|
}
|
|
1354
1433
|
}
|
|
1355
1434
|
}
|
|
1356
|
-
// Non-LWW modify-property flow removed
|
|
1357
1435
|
applyOperation(op) {
|
|
1358
1436
|
if (isMoveVertexOp(op)) {
|
|
1359
1437
|
this.applyMove(op);
|