@loro-extended/change 4.0.0 → 5.0.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 +173 -149
- package/dist/index.d.ts +962 -335
- package/dist/index.js +1040 -598
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
- package/src/change.test.ts +51 -52
- package/src/functional-helpers.test.ts +316 -4
- package/src/functional-helpers.ts +96 -6
- package/src/grand-unified-api.test.ts +35 -29
- package/src/index.ts +25 -1
- package/src/json-patch.test.ts +46 -27
- package/src/loro.test.ts +449 -0
- package/src/loro.ts +273 -0
- package/src/overlay-recursion.test.ts +1 -1
- package/src/path-evaluator.ts +1 -1
- package/src/path-selector.test.ts +94 -1
- package/src/shape.ts +47 -15
- package/src/typed-doc.ts +99 -98
- package/src/typed-refs/base.ts +126 -35
- package/src/typed-refs/counter-ref-internals.ts +62 -0
- package/src/typed-refs/{counter.test.ts → counter-ref.test.ts} +5 -4
- package/src/typed-refs/counter-ref.ts +45 -0
- package/src/typed-refs/{doc.ts → doc-ref-internals.ts} +33 -38
- package/src/typed-refs/doc-ref.ts +47 -0
- package/src/typed-refs/encapsulation.test.ts +226 -0
- package/src/typed-refs/list-ref-base-internals.ts +280 -0
- package/src/typed-refs/{list-base.ts → list-ref-base.ts} +255 -160
- package/src/typed-refs/list-ref-internals.ts +21 -0
- package/src/typed-refs/{list.ts → list-ref.ts} +10 -11
- package/src/typed-refs/movable-list-ref-internals.ts +38 -0
- package/src/typed-refs/movable-list-ref.ts +31 -0
- package/src/typed-refs/proxy-handlers.ts +13 -4
- package/src/typed-refs/{record.ts → record-ref-internals.ts} +78 -79
- package/src/typed-refs/{record.test.ts → record-ref.test.ts} +21 -16
- package/src/typed-refs/record-ref.ts +80 -0
- package/src/typed-refs/struct-ref-internals.ts +195 -0
- package/src/typed-refs/{struct-value-updates.test.ts → struct-ref.test.ts} +5 -3
- package/src/typed-refs/struct-ref.ts +257 -0
- package/src/typed-refs/text-ref-internals.ts +100 -0
- package/src/typed-refs/text-ref.ts +72 -0
- package/src/typed-refs/tree-node-ref-internals.ts +111 -0
- package/src/typed-refs/{tree-node.ts → tree-node-ref.ts} +58 -94
- package/src/typed-refs/tree-ref-internals.ts +110 -0
- package/src/typed-refs/tree-ref.ts +194 -0
- package/src/typed-refs/utils.ts +21 -23
- package/src/typed-refs/counter.ts +0 -62
- package/src/typed-refs/movable-list.ts +0 -32
- package/src/typed-refs/struct.ts +0 -201
- package/src/typed-refs/text.ts +0 -91
- package/src/typed-refs/tree.ts +0 -268
- /package/src/typed-refs/{list-value-updates.test.ts → list-ref-value-updates.test.ts} +0 -0
- /package/src/typed-refs/{list.test.ts → list-ref.test.ts} +0 -0
- /package/src/typed-refs/{movable-list.test.ts → movable-list-ref.test.ts} +0 -0
- /package/src/typed-refs/{record-value-updates.test.ts → record-ref-value-updates.test.ts} +0 -0
- /package/src/typed-refs/{tree-node-value-updates.test.ts → tree-node-ref.test.ts} +0 -0
- /package/src/typed-refs/{tree.test.ts → tree-node.test.ts} +0 -0
package/dist/index.js
CHANGED
|
@@ -99,12 +99,27 @@ function deriveValueShapePlaceholder(shape) {
|
|
|
99
99
|
}
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
+
// src/loro.ts
|
|
103
|
+
var LORO_SYMBOL = /* @__PURE__ */ Symbol.for("loro-extended:loro");
|
|
104
|
+
function loro(refOrDoc) {
|
|
105
|
+
const loroNamespace = refOrDoc[LORO_SYMBOL];
|
|
106
|
+
if (!loroNamespace) {
|
|
107
|
+
throw new Error(
|
|
108
|
+
"Invalid argument: expected TypedRef, TreeRef, or TypedDoc with loro() support"
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
return loroNamespace;
|
|
112
|
+
}
|
|
113
|
+
|
|
102
114
|
// src/functional-helpers.ts
|
|
103
115
|
function change(doc, fn) {
|
|
104
|
-
return doc
|
|
116
|
+
return doc.change(fn);
|
|
105
117
|
}
|
|
106
|
-
function getLoroDoc(
|
|
107
|
-
return doc
|
|
118
|
+
function getLoroDoc(docOrRef) {
|
|
119
|
+
return loro(docOrRef).doc;
|
|
120
|
+
}
|
|
121
|
+
function getLoroContainer(ref) {
|
|
122
|
+
return loro(ref).container;
|
|
108
123
|
}
|
|
109
124
|
|
|
110
125
|
// src/utils/type-guards.ts
|
|
@@ -396,7 +411,7 @@ function hasWildcard(segments) {
|
|
|
396
411
|
|
|
397
412
|
// src/path-evaluator.ts
|
|
398
413
|
function evaluatePath(doc, selector) {
|
|
399
|
-
const json = doc
|
|
414
|
+
const json = doc.toJSON();
|
|
400
415
|
return evaluatePathOnValue(json, selector.__segments);
|
|
401
416
|
}
|
|
402
417
|
function evaluatePathOnValue(value, segments) {
|
|
@@ -600,7 +615,7 @@ var Shape = {
|
|
|
600
615
|
* states: Shape.tree(StateNodeDataShape),
|
|
601
616
|
* })
|
|
602
617
|
*
|
|
603
|
-
* doc
|
|
618
|
+
* doc.change(draft => {
|
|
604
619
|
* const root = draft.states.createNode({ name: "idle", facts: {} })
|
|
605
620
|
* const child = root.createNode({ name: "running", facts: {} })
|
|
606
621
|
* child.data.name = "active"
|
|
@@ -1082,42 +1097,76 @@ var JsonPatchApplicator = class {
|
|
|
1082
1097
|
};
|
|
1083
1098
|
|
|
1084
1099
|
// src/typed-refs/base.ts
|
|
1085
|
-
var
|
|
1086
|
-
|
|
1087
|
-
|
|
1100
|
+
var INTERNAL_SYMBOL = /* @__PURE__ */ Symbol.for("loro-extended:internal");
|
|
1101
|
+
var BaseRefInternals = class {
|
|
1102
|
+
constructor(params) {
|
|
1103
|
+
this.params = params;
|
|
1104
|
+
}
|
|
1105
|
+
cachedContainer;
|
|
1106
|
+
loroNamespace;
|
|
1107
|
+
/** Get the underlying Loro container (cached) */
|
|
1108
|
+
getContainer() {
|
|
1109
|
+
if (!this.cachedContainer) {
|
|
1110
|
+
this.cachedContainer = this.params.getContainer();
|
|
1111
|
+
}
|
|
1112
|
+
return this.cachedContainer;
|
|
1088
1113
|
}
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1114
|
+
/** Commit changes if autoCommit is enabled */
|
|
1115
|
+
commitIfAuto() {
|
|
1116
|
+
if (this.params.autoCommit) {
|
|
1117
|
+
this.params.getDoc().commit();
|
|
1118
|
+
}
|
|
1092
1119
|
}
|
|
1093
|
-
|
|
1094
|
-
|
|
1120
|
+
/** Get the shape for this ref */
|
|
1121
|
+
getShape() {
|
|
1122
|
+
return this.params.shape;
|
|
1095
1123
|
}
|
|
1096
|
-
|
|
1097
|
-
|
|
1124
|
+
/** Get the placeholder value */
|
|
1125
|
+
getPlaceholder() {
|
|
1126
|
+
return this.params.placeholder;
|
|
1098
1127
|
}
|
|
1099
|
-
|
|
1100
|
-
|
|
1128
|
+
/** Check if autoCommit is enabled */
|
|
1129
|
+
getAutoCommit() {
|
|
1130
|
+
return !!this.params.autoCommit;
|
|
1101
1131
|
}
|
|
1102
|
-
|
|
1103
|
-
|
|
1132
|
+
/** Check if in batched mutation mode */
|
|
1133
|
+
getBatchedMutation() {
|
|
1134
|
+
return !!this.params.batchedMutation;
|
|
1104
1135
|
}
|
|
1105
|
-
/**
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
*/
|
|
1109
|
-
commitIfAuto() {
|
|
1110
|
-
if (this.autoCommit && this.doc) {
|
|
1111
|
-
this.doc.commit();
|
|
1112
|
-
}
|
|
1136
|
+
/** Get the LoroDoc */
|
|
1137
|
+
getDoc() {
|
|
1138
|
+
return this.params.getDoc();
|
|
1113
1139
|
}
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
this.
|
|
1118
|
-
return container;
|
|
1140
|
+
/** Get the loro namespace (cached) */
|
|
1141
|
+
getLoroNamespace() {
|
|
1142
|
+
if (!this.loroNamespace) {
|
|
1143
|
+
this.loroNamespace = this.createLoroNamespace();
|
|
1119
1144
|
}
|
|
1120
|
-
return this.
|
|
1145
|
+
return this.loroNamespace;
|
|
1146
|
+
}
|
|
1147
|
+
/** Create the loro() namespace object - subclasses override for specific types */
|
|
1148
|
+
createLoroNamespace() {
|
|
1149
|
+
const self = this;
|
|
1150
|
+
return {
|
|
1151
|
+
get doc() {
|
|
1152
|
+
return self.params.getDoc();
|
|
1153
|
+
},
|
|
1154
|
+
get container() {
|
|
1155
|
+
return self.getContainer();
|
|
1156
|
+
},
|
|
1157
|
+
subscribe(callback) {
|
|
1158
|
+
return self.getContainer().subscribe(callback);
|
|
1159
|
+
}
|
|
1160
|
+
};
|
|
1161
|
+
}
|
|
1162
|
+
};
|
|
1163
|
+
var TypedRef = class {
|
|
1164
|
+
/**
|
|
1165
|
+
* Access the loro() namespace via the well-known symbol.
|
|
1166
|
+
* This is used by the loro() function to access CRDT internals.
|
|
1167
|
+
*/
|
|
1168
|
+
get [LORO_SYMBOL]() {
|
|
1169
|
+
return this[INTERNAL_SYMBOL].getLoroNamespace();
|
|
1121
1170
|
}
|
|
1122
1171
|
};
|
|
1123
1172
|
|
|
@@ -1131,40 +1180,73 @@ import {
|
|
|
1131
1180
|
LoroTree
|
|
1132
1181
|
} from "loro-crdt";
|
|
1133
1182
|
|
|
1134
|
-
// src/typed-refs/counter.ts
|
|
1135
|
-
var
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
get container() {
|
|
1139
|
-
return super.container;
|
|
1140
|
-
}
|
|
1141
|
-
absorbPlainValues() {
|
|
1142
|
-
}
|
|
1183
|
+
// src/typed-refs/counter-ref-internals.ts
|
|
1184
|
+
var CounterRefInternals = class extends BaseRefInternals {
|
|
1185
|
+
materialized = false;
|
|
1186
|
+
/** Increment the counter value */
|
|
1143
1187
|
increment(value = 1) {
|
|
1144
|
-
this.
|
|
1145
|
-
this.
|
|
1188
|
+
this.materialized = true;
|
|
1189
|
+
this.getContainer().increment(value);
|
|
1146
1190
|
this.commitIfAuto();
|
|
1147
1191
|
}
|
|
1192
|
+
/** Decrement the counter value */
|
|
1148
1193
|
decrement(value = 1) {
|
|
1149
|
-
this.
|
|
1150
|
-
this.
|
|
1194
|
+
this.materialized = true;
|
|
1195
|
+
this.getContainer().decrement(value);
|
|
1151
1196
|
this.commitIfAuto();
|
|
1152
1197
|
}
|
|
1153
|
-
/**
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
get value() {
|
|
1159
|
-
const containerValue = this.container.value;
|
|
1160
|
-
if (containerValue !== 0 || this._materialized) {
|
|
1198
|
+
/** Get the current counter value */
|
|
1199
|
+
getValue() {
|
|
1200
|
+
const container = this.getContainer();
|
|
1201
|
+
const containerValue = container.value;
|
|
1202
|
+
if (containerValue !== 0 || this.materialized) {
|
|
1161
1203
|
return containerValue;
|
|
1162
1204
|
}
|
|
1163
|
-
|
|
1164
|
-
|
|
1205
|
+
const placeholder = this.getPlaceholder();
|
|
1206
|
+
if (placeholder !== void 0) {
|
|
1207
|
+
return placeholder;
|
|
1165
1208
|
}
|
|
1166
1209
|
return containerValue;
|
|
1167
1210
|
}
|
|
1211
|
+
/** No plain values in counter */
|
|
1212
|
+
absorbPlainValues() {
|
|
1213
|
+
}
|
|
1214
|
+
/** Create the loro namespace for counter */
|
|
1215
|
+
createLoroNamespace() {
|
|
1216
|
+
const self = this;
|
|
1217
|
+
return {
|
|
1218
|
+
get doc() {
|
|
1219
|
+
return self.getDoc();
|
|
1220
|
+
},
|
|
1221
|
+
get container() {
|
|
1222
|
+
return self.getContainer();
|
|
1223
|
+
},
|
|
1224
|
+
subscribe(callback) {
|
|
1225
|
+
return self.getContainer().subscribe(callback);
|
|
1226
|
+
}
|
|
1227
|
+
};
|
|
1228
|
+
}
|
|
1229
|
+
};
|
|
1230
|
+
|
|
1231
|
+
// src/typed-refs/counter-ref.ts
|
|
1232
|
+
var CounterRef = class extends TypedRef {
|
|
1233
|
+
[INTERNAL_SYMBOL];
|
|
1234
|
+
constructor(params) {
|
|
1235
|
+
super();
|
|
1236
|
+
this[INTERNAL_SYMBOL] = new CounterRefInternals(params);
|
|
1237
|
+
}
|
|
1238
|
+
/** Increment the counter by the given value (default 1) */
|
|
1239
|
+
increment(value) {
|
|
1240
|
+
this[INTERNAL_SYMBOL].increment(value);
|
|
1241
|
+
}
|
|
1242
|
+
/** Decrement the counter by the given value (default 1) */
|
|
1243
|
+
decrement(value) {
|
|
1244
|
+
this[INTERNAL_SYMBOL].decrement(value);
|
|
1245
|
+
}
|
|
1246
|
+
/** Get the current counter value */
|
|
1247
|
+
get value() {
|
|
1248
|
+
return this[INTERNAL_SYMBOL].getValue();
|
|
1249
|
+
}
|
|
1168
1250
|
valueOf() {
|
|
1169
1251
|
return this.value;
|
|
1170
1252
|
}
|
|
@@ -1313,75 +1395,41 @@ function convertInputToRef(value, shape) {
|
|
|
1313
1395
|
}
|
|
1314
1396
|
}
|
|
1315
1397
|
|
|
1316
|
-
// src/typed-refs/list-base.ts
|
|
1317
|
-
var
|
|
1318
|
-
// Cache for items returned by array methods to track mutations
|
|
1398
|
+
// src/typed-refs/list-ref-base.ts
|
|
1399
|
+
var ListRefBaseInternals = class extends BaseRefInternals {
|
|
1319
1400
|
itemCache = /* @__PURE__ */ new Map();
|
|
1320
|
-
|
|
1321
|
-
return super.container;
|
|
1322
|
-
}
|
|
1323
|
-
get shape() {
|
|
1324
|
-
return super.shape;
|
|
1325
|
-
}
|
|
1326
|
-
absorbPlainValues() {
|
|
1327
|
-
for (const [index, cachedItem] of this.itemCache.entries()) {
|
|
1328
|
-
if (cachedItem) {
|
|
1329
|
-
if (isValueShape(this.shape.shape)) {
|
|
1330
|
-
this.absorbValueAtIndex(index, cachedItem);
|
|
1331
|
-
} else {
|
|
1332
|
-
if (cachedItem && typeof cachedItem === "object" && "absorbPlainValues" in cachedItem) {
|
|
1333
|
-
;
|
|
1334
|
-
cachedItem.absorbPlainValues();
|
|
1335
|
-
}
|
|
1336
|
-
}
|
|
1337
|
-
}
|
|
1338
|
-
}
|
|
1339
|
-
this.itemCache.clear();
|
|
1340
|
-
}
|
|
1341
|
-
insertWithConversion(index, item) {
|
|
1342
|
-
const convertedItem = convertInputToRef(item, this.shape.shape);
|
|
1343
|
-
if (isContainer(convertedItem)) {
|
|
1344
|
-
this.container.insertContainer(index, convertedItem);
|
|
1345
|
-
} else {
|
|
1346
|
-
this.container.insert(index, convertedItem);
|
|
1347
|
-
}
|
|
1348
|
-
}
|
|
1349
|
-
pushWithConversion(item) {
|
|
1350
|
-
const convertedItem = convertInputToRef(item, this.shape.shape);
|
|
1351
|
-
if (isContainer(convertedItem)) {
|
|
1352
|
-
this.container.pushContainer(convertedItem);
|
|
1353
|
-
} else {
|
|
1354
|
-
this.container.push(convertedItem);
|
|
1355
|
-
}
|
|
1356
|
-
}
|
|
1401
|
+
/** Get typed ref params for creating child refs at an index */
|
|
1357
1402
|
getTypedRefParams(index, shape) {
|
|
1358
1403
|
return {
|
|
1359
1404
|
shape,
|
|
1360
1405
|
placeholder: void 0,
|
|
1361
1406
|
// List items don't have placeholder
|
|
1362
1407
|
getContainer: () => {
|
|
1363
|
-
const
|
|
1408
|
+
const container = this.getContainer();
|
|
1409
|
+
const containerItem = container.get(index);
|
|
1364
1410
|
if (!containerItem || !isContainer(containerItem)) {
|
|
1365
1411
|
throw new Error(`No container found at index ${index}`);
|
|
1366
1412
|
}
|
|
1367
1413
|
return containerItem;
|
|
1368
1414
|
},
|
|
1369
|
-
autoCommit: this.
|
|
1370
|
-
batchedMutation: this.
|
|
1371
|
-
getDoc: this.
|
|
1415
|
+
autoCommit: this.getAutoCommit(),
|
|
1416
|
+
batchedMutation: this.getBatchedMutation(),
|
|
1417
|
+
getDoc: () => this.getDoc()
|
|
1372
1418
|
};
|
|
1373
1419
|
}
|
|
1374
|
-
|
|
1420
|
+
/** Get item for predicate functions (returns plain value) */
|
|
1375
1421
|
getPredicateItem(index) {
|
|
1422
|
+
const shape = this.getShape();
|
|
1423
|
+
const container = this.getContainer();
|
|
1376
1424
|
const cachedItem = this.itemCache.get(index);
|
|
1377
|
-
if (cachedItem && isValueShape(
|
|
1425
|
+
if (cachedItem && isValueShape(shape.shape)) {
|
|
1378
1426
|
return cachedItem;
|
|
1379
1427
|
}
|
|
1380
|
-
const containerItem =
|
|
1428
|
+
const containerItem = container.get(index);
|
|
1381
1429
|
if (containerItem === void 0) {
|
|
1382
1430
|
return void 0;
|
|
1383
1431
|
}
|
|
1384
|
-
if (isValueShape(
|
|
1432
|
+
if (isValueShape(shape.shape)) {
|
|
1385
1433
|
return containerItem;
|
|
1386
1434
|
} else {
|
|
1387
1435
|
if (isContainer(containerItem)) {
|
|
@@ -1396,14 +1444,16 @@ var ListRefBase = class extends TypedRef {
|
|
|
1396
1444
|
return containerItem;
|
|
1397
1445
|
}
|
|
1398
1446
|
}
|
|
1399
|
-
|
|
1447
|
+
/** Get mutable item for return values (returns ref or cached value) */
|
|
1400
1448
|
getMutableItem(index) {
|
|
1401
|
-
const
|
|
1449
|
+
const shape = this.getShape();
|
|
1450
|
+
const container = this.getContainer();
|
|
1451
|
+
const containerItem = container.get(index);
|
|
1402
1452
|
if (containerItem === void 0) {
|
|
1403
1453
|
return void 0;
|
|
1404
1454
|
}
|
|
1405
|
-
if (isValueShape(
|
|
1406
|
-
if (!this.
|
|
1455
|
+
if (isValueShape(shape.shape)) {
|
|
1456
|
+
if (!this.getBatchedMutation()) {
|
|
1407
1457
|
return containerItem;
|
|
1408
1458
|
}
|
|
1409
1459
|
let cachedItem2 = this.itemCache.get(index);
|
|
@@ -1421,26 +1471,127 @@ var ListRefBase = class extends TypedRef {
|
|
|
1421
1471
|
let cachedItem = this.itemCache.get(index);
|
|
1422
1472
|
if (!cachedItem) {
|
|
1423
1473
|
cachedItem = createContainerTypedRef(
|
|
1424
|
-
this.getTypedRefParams(index,
|
|
1474
|
+
this.getTypedRefParams(index, shape.shape)
|
|
1425
1475
|
);
|
|
1426
1476
|
this.itemCache.set(index, cachedItem);
|
|
1427
1477
|
}
|
|
1428
1478
|
return cachedItem;
|
|
1429
1479
|
}
|
|
1480
|
+
/** Insert with automatic conversion */
|
|
1481
|
+
insertWithConversion(index, item) {
|
|
1482
|
+
const shape = this.getShape();
|
|
1483
|
+
const container = this.getContainer();
|
|
1484
|
+
const convertedItem = convertInputToRef(item, shape.shape);
|
|
1485
|
+
if (isContainer(convertedItem)) {
|
|
1486
|
+
container.insertContainer(index, convertedItem);
|
|
1487
|
+
} else {
|
|
1488
|
+
container.insert(index, convertedItem);
|
|
1489
|
+
}
|
|
1490
|
+
}
|
|
1491
|
+
/** Push with automatic conversion */
|
|
1492
|
+
pushWithConversion(item) {
|
|
1493
|
+
const shape = this.getShape();
|
|
1494
|
+
const container = this.getContainer();
|
|
1495
|
+
const convertedItem = convertInputToRef(item, shape.shape);
|
|
1496
|
+
if (isContainer(convertedItem)) {
|
|
1497
|
+
container.pushContainer(convertedItem);
|
|
1498
|
+
} else {
|
|
1499
|
+
container.push(convertedItem);
|
|
1500
|
+
}
|
|
1501
|
+
}
|
|
1502
|
+
/** Absorb value at specific index (for value shapes) - subclasses override */
|
|
1503
|
+
absorbValueAtIndex(_index, _value) {
|
|
1504
|
+
throw new Error("absorbValueAtIndex must be implemented by subclass");
|
|
1505
|
+
}
|
|
1506
|
+
/** Update cache indices after a delete operation */
|
|
1507
|
+
updateCacheForDelete(deleteIndex, deleteLen) {
|
|
1508
|
+
const newCache = /* @__PURE__ */ new Map();
|
|
1509
|
+
for (const [cachedIndex, cachedItem] of this.itemCache.entries()) {
|
|
1510
|
+
if (cachedIndex < deleteIndex) {
|
|
1511
|
+
newCache.set(cachedIndex, cachedItem);
|
|
1512
|
+
} else if (cachedIndex >= deleteIndex + deleteLen) {
|
|
1513
|
+
newCache.set(cachedIndex - deleteLen, cachedItem);
|
|
1514
|
+
}
|
|
1515
|
+
}
|
|
1516
|
+
this.itemCache = newCache;
|
|
1517
|
+
}
|
|
1518
|
+
/** Update cache indices after an insert operation */
|
|
1519
|
+
updateCacheForInsert(insertIndex) {
|
|
1520
|
+
const newCache = /* @__PURE__ */ new Map();
|
|
1521
|
+
for (const [cachedIndex, cachedItem] of this.itemCache.entries()) {
|
|
1522
|
+
if (cachedIndex < insertIndex) {
|
|
1523
|
+
newCache.set(cachedIndex, cachedItem);
|
|
1524
|
+
} else {
|
|
1525
|
+
newCache.set(cachedIndex + 1, cachedItem);
|
|
1526
|
+
}
|
|
1527
|
+
}
|
|
1528
|
+
this.itemCache = newCache;
|
|
1529
|
+
}
|
|
1530
|
+
/** Absorb mutated plain values back into Loro containers */
|
|
1531
|
+
absorbPlainValues() {
|
|
1532
|
+
const shape = this.getShape();
|
|
1533
|
+
for (const [index, cachedItem] of this.itemCache.entries()) {
|
|
1534
|
+
if (cachedItem) {
|
|
1535
|
+
if (isValueShape(shape.shape)) {
|
|
1536
|
+
this.absorbValueAtIndex(index, cachedItem);
|
|
1537
|
+
} else {
|
|
1538
|
+
if (cachedItem && typeof cachedItem === "object" && INTERNAL_SYMBOL in cachedItem) {
|
|
1539
|
+
;
|
|
1540
|
+
cachedItem[INTERNAL_SYMBOL].absorbPlainValues();
|
|
1541
|
+
}
|
|
1542
|
+
}
|
|
1543
|
+
}
|
|
1544
|
+
}
|
|
1545
|
+
this.itemCache.clear();
|
|
1546
|
+
}
|
|
1547
|
+
/** Create the loro namespace for list */
|
|
1548
|
+
createLoroNamespace() {
|
|
1549
|
+
const self = this;
|
|
1550
|
+
return {
|
|
1551
|
+
get doc() {
|
|
1552
|
+
return self.getDoc();
|
|
1553
|
+
},
|
|
1554
|
+
get container() {
|
|
1555
|
+
return self.getContainer();
|
|
1556
|
+
},
|
|
1557
|
+
subscribe(callback) {
|
|
1558
|
+
return self.getContainer().subscribe(
|
|
1559
|
+
callback
|
|
1560
|
+
);
|
|
1561
|
+
},
|
|
1562
|
+
pushContainer(container) {
|
|
1563
|
+
const result = self.getContainer().pushContainer(container);
|
|
1564
|
+
self.commitIfAuto();
|
|
1565
|
+
return result;
|
|
1566
|
+
},
|
|
1567
|
+
insertContainer(index, container) {
|
|
1568
|
+
const result = self.getContainer().insertContainer(index, container);
|
|
1569
|
+
self.commitIfAuto();
|
|
1570
|
+
return result;
|
|
1571
|
+
}
|
|
1572
|
+
};
|
|
1573
|
+
}
|
|
1574
|
+
};
|
|
1575
|
+
var ListRefBase = class extends TypedRef {
|
|
1576
|
+
[INTERNAL_SYMBOL];
|
|
1577
|
+
constructor(params) {
|
|
1578
|
+
super();
|
|
1579
|
+
this[INTERNAL_SYMBOL] = this.createInternals(params);
|
|
1580
|
+
}
|
|
1430
1581
|
// Array-like methods for better developer experience
|
|
1431
1582
|
// DUAL INTERFACE: Predicates get Item (plain data), return values are MutableItem (mutable)
|
|
1432
1583
|
find(predicate) {
|
|
1433
1584
|
for (let i = 0; i < this.length; i++) {
|
|
1434
|
-
const predicateItem = this.getPredicateItem(i);
|
|
1585
|
+
const predicateItem = this[INTERNAL_SYMBOL].getPredicateItem(i);
|
|
1435
1586
|
if (predicate(predicateItem, i)) {
|
|
1436
|
-
return this.getMutableItem(i);
|
|
1587
|
+
return this[INTERNAL_SYMBOL].getMutableItem(i);
|
|
1437
1588
|
}
|
|
1438
1589
|
}
|
|
1439
1590
|
return void 0;
|
|
1440
1591
|
}
|
|
1441
1592
|
findIndex(predicate) {
|
|
1442
1593
|
for (let i = 0; i < this.length; i++) {
|
|
1443
|
-
const predicateItem = this.getPredicateItem(i);
|
|
1594
|
+
const predicateItem = this[INTERNAL_SYMBOL].getPredicateItem(i);
|
|
1444
1595
|
if (predicate(predicateItem, i)) {
|
|
1445
1596
|
return i;
|
|
1446
1597
|
}
|
|
@@ -1450,7 +1601,7 @@ var ListRefBase = class extends TypedRef {
|
|
|
1450
1601
|
map(callback) {
|
|
1451
1602
|
const result = [];
|
|
1452
1603
|
for (let i = 0; i < this.length; i++) {
|
|
1453
|
-
const predicateItem = this.getPredicateItem(i);
|
|
1604
|
+
const predicateItem = this[INTERNAL_SYMBOL].getPredicateItem(i);
|
|
1454
1605
|
result.push(callback(predicateItem, i));
|
|
1455
1606
|
}
|
|
1456
1607
|
return result;
|
|
@@ -1458,22 +1609,22 @@ var ListRefBase = class extends TypedRef {
|
|
|
1458
1609
|
filter(predicate) {
|
|
1459
1610
|
const result = [];
|
|
1460
1611
|
for (let i = 0; i < this.length; i++) {
|
|
1461
|
-
const predicateItem = this.getPredicateItem(i);
|
|
1612
|
+
const predicateItem = this[INTERNAL_SYMBOL].getPredicateItem(i);
|
|
1462
1613
|
if (predicate(predicateItem, i)) {
|
|
1463
|
-
result.push(this.getMutableItem(i));
|
|
1614
|
+
result.push(this[INTERNAL_SYMBOL].getMutableItem(i));
|
|
1464
1615
|
}
|
|
1465
1616
|
}
|
|
1466
1617
|
return result;
|
|
1467
1618
|
}
|
|
1468
1619
|
forEach(callback) {
|
|
1469
1620
|
for (let i = 0; i < this.length; i++) {
|
|
1470
|
-
const predicateItem = this.getPredicateItem(i);
|
|
1621
|
+
const predicateItem = this[INTERNAL_SYMBOL].getPredicateItem(i);
|
|
1471
1622
|
callback(predicateItem, i);
|
|
1472
1623
|
}
|
|
1473
1624
|
}
|
|
1474
1625
|
some(predicate) {
|
|
1475
1626
|
for (let i = 0; i < this.length; i++) {
|
|
1476
|
-
const predicateItem = this.getPredicateItem(i);
|
|
1627
|
+
const predicateItem = this[INTERNAL_SYMBOL].getPredicateItem(i);
|
|
1477
1628
|
if (predicate(predicateItem, i)) {
|
|
1478
1629
|
return true;
|
|
1479
1630
|
}
|
|
@@ -1482,7 +1633,7 @@ var ListRefBase = class extends TypedRef {
|
|
|
1482
1633
|
}
|
|
1483
1634
|
every(predicate) {
|
|
1484
1635
|
for (let i = 0; i < this.length; i++) {
|
|
1485
|
-
const predicateItem = this.getPredicateItem(i);
|
|
1636
|
+
const predicateItem = this[INTERNAL_SYMBOL].getPredicateItem(i);
|
|
1486
1637
|
if (!predicate(predicateItem, i)) {
|
|
1487
1638
|
return false;
|
|
1488
1639
|
}
|
|
@@ -1495,50 +1646,55 @@ var ListRefBase = class extends TypedRef {
|
|
|
1495
1646
|
const endIndex = end === void 0 ? len : end < 0 ? Math.max(len + end, 0) : Math.min(end, len);
|
|
1496
1647
|
const result = [];
|
|
1497
1648
|
for (let i = startIndex; i < endIndex; i++) {
|
|
1498
|
-
result.push(this.getMutableItem(i));
|
|
1649
|
+
result.push(this[INTERNAL_SYMBOL].getMutableItem(i));
|
|
1499
1650
|
}
|
|
1500
1651
|
return result;
|
|
1501
1652
|
}
|
|
1502
1653
|
insert(index, item) {
|
|
1503
|
-
this.updateCacheForInsert(index);
|
|
1504
|
-
this.insertWithConversion(index, item);
|
|
1505
|
-
this.commitIfAuto();
|
|
1654
|
+
this[INTERNAL_SYMBOL].updateCacheForInsert(index);
|
|
1655
|
+
this[INTERNAL_SYMBOL].insertWithConversion(index, item);
|
|
1656
|
+
this[INTERNAL_SYMBOL].commitIfAuto();
|
|
1506
1657
|
}
|
|
1507
1658
|
delete(index, len) {
|
|
1508
|
-
this.updateCacheForDelete(index, len);
|
|
1509
|
-
this.
|
|
1510
|
-
|
|
1659
|
+
this[INTERNAL_SYMBOL].updateCacheForDelete(index, len);
|
|
1660
|
+
const container = this[INTERNAL_SYMBOL].getContainer();
|
|
1661
|
+
container.delete(index, len);
|
|
1662
|
+
this[INTERNAL_SYMBOL].commitIfAuto();
|
|
1511
1663
|
}
|
|
1512
1664
|
push(item) {
|
|
1513
|
-
this.pushWithConversion(item);
|
|
1514
|
-
this.commitIfAuto();
|
|
1665
|
+
this[INTERNAL_SYMBOL].pushWithConversion(item);
|
|
1666
|
+
this[INTERNAL_SYMBOL].commitIfAuto();
|
|
1515
1667
|
}
|
|
1516
1668
|
pushContainer(container) {
|
|
1517
|
-
const
|
|
1518
|
-
|
|
1669
|
+
const loroContainer = this[INTERNAL_SYMBOL].getContainer();
|
|
1670
|
+
const result = loroContainer.pushContainer(container);
|
|
1671
|
+
this[INTERNAL_SYMBOL].commitIfAuto();
|
|
1519
1672
|
return result;
|
|
1520
1673
|
}
|
|
1521
1674
|
insertContainer(index, container) {
|
|
1522
|
-
const
|
|
1523
|
-
|
|
1675
|
+
const loroContainer = this[INTERNAL_SYMBOL].getContainer();
|
|
1676
|
+
const result = loroContainer.insertContainer(index, container);
|
|
1677
|
+
this[INTERNAL_SYMBOL].commitIfAuto();
|
|
1524
1678
|
return result;
|
|
1525
1679
|
}
|
|
1526
1680
|
get(index) {
|
|
1527
|
-
return this.getMutableItem(index);
|
|
1681
|
+
return this[INTERNAL_SYMBOL].getMutableItem(index);
|
|
1528
1682
|
}
|
|
1529
1683
|
toArray() {
|
|
1530
1684
|
const result = [];
|
|
1531
1685
|
for (let i = 0; i < this.length; i++) {
|
|
1532
|
-
result.push(this.getPredicateItem(i));
|
|
1686
|
+
result.push(this[INTERNAL_SYMBOL].getPredicateItem(i));
|
|
1533
1687
|
}
|
|
1534
1688
|
return result;
|
|
1535
1689
|
}
|
|
1536
1690
|
toJSON() {
|
|
1537
|
-
const
|
|
1538
|
-
|
|
1539
|
-
|
|
1691
|
+
const shape = this[INTERNAL_SYMBOL].getShape();
|
|
1692
|
+
const container = this[INTERNAL_SYMBOL].getContainer();
|
|
1693
|
+
const nativeJson = container.toJSON();
|
|
1694
|
+
if (isContainerShape(shape.shape) || isValueShape(shape.shape) && shape.shape.valueType === "struct") {
|
|
1695
|
+
const itemPlaceholder = deriveShapePlaceholder(shape.shape);
|
|
1540
1696
|
return nativeJson.map(
|
|
1541
|
-
(item) => mergeValue(
|
|
1697
|
+
(item) => mergeValue(shape.shape, item, itemPlaceholder)
|
|
1542
1698
|
);
|
|
1543
1699
|
}
|
|
1544
1700
|
return nativeJson ?? [];
|
|
@@ -1548,7 +1704,10 @@ var ListRefBase = class extends TypedRef {
|
|
|
1548
1704
|
return {
|
|
1549
1705
|
next: () => {
|
|
1550
1706
|
if (index < this.length) {
|
|
1551
|
-
return {
|
|
1707
|
+
return {
|
|
1708
|
+
value: this[INTERNAL_SYMBOL].getMutableItem(index++),
|
|
1709
|
+
done: false
|
|
1710
|
+
};
|
|
1552
1711
|
}
|
|
1553
1712
|
return { value: void 0, done: true };
|
|
1554
1713
|
},
|
|
@@ -1558,61 +1717,59 @@ var ListRefBase = class extends TypedRef {
|
|
|
1558
1717
|
};
|
|
1559
1718
|
}
|
|
1560
1719
|
get length() {
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
// Update cache indices when items are deleted
|
|
1564
|
-
updateCacheForDelete(deleteIndex, deleteLen) {
|
|
1565
|
-
const newCache = /* @__PURE__ */ new Map();
|
|
1566
|
-
for (const [cachedIndex, cachedItem] of this.itemCache.entries()) {
|
|
1567
|
-
if (cachedIndex < deleteIndex) {
|
|
1568
|
-
newCache.set(cachedIndex, cachedItem);
|
|
1569
|
-
} else if (cachedIndex >= deleteIndex + deleteLen) {
|
|
1570
|
-
newCache.set(cachedIndex - deleteLen, cachedItem);
|
|
1571
|
-
}
|
|
1572
|
-
}
|
|
1573
|
-
this.itemCache = newCache;
|
|
1574
|
-
}
|
|
1575
|
-
// Update cache indices when items are inserted
|
|
1576
|
-
updateCacheForInsert(insertIndex) {
|
|
1577
|
-
const newCache = /* @__PURE__ */ new Map();
|
|
1578
|
-
for (const [cachedIndex, cachedItem] of this.itemCache.entries()) {
|
|
1579
|
-
if (cachedIndex < insertIndex) {
|
|
1580
|
-
newCache.set(cachedIndex, cachedItem);
|
|
1581
|
-
} else {
|
|
1582
|
-
newCache.set(cachedIndex + 1, cachedItem);
|
|
1583
|
-
}
|
|
1584
|
-
}
|
|
1585
|
-
this.itemCache = newCache;
|
|
1720
|
+
const container = this[INTERNAL_SYMBOL].getContainer();
|
|
1721
|
+
return container.length;
|
|
1586
1722
|
}
|
|
1587
1723
|
};
|
|
1588
1724
|
|
|
1589
|
-
// src/typed-refs/list.ts
|
|
1590
|
-
var
|
|
1591
|
-
|
|
1592
|
-
return super.container;
|
|
1593
|
-
}
|
|
1725
|
+
// src/typed-refs/list-ref-internals.ts
|
|
1726
|
+
var ListRefInternals = class extends ListRefBaseInternals {
|
|
1727
|
+
/** Absorb value at specific index for LoroList */
|
|
1594
1728
|
absorbValueAtIndex(index, value) {
|
|
1595
|
-
this.
|
|
1596
|
-
|
|
1729
|
+
const container = this.getContainer();
|
|
1730
|
+
container.delete(index, 1);
|
|
1731
|
+
container.insert(index, value);
|
|
1597
1732
|
}
|
|
1598
1733
|
};
|
|
1599
1734
|
|
|
1600
|
-
// src/typed-refs/
|
|
1601
|
-
var
|
|
1602
|
-
|
|
1603
|
-
return
|
|
1735
|
+
// src/typed-refs/list-ref.ts
|
|
1736
|
+
var ListRef = class extends ListRefBase {
|
|
1737
|
+
createInternals(params) {
|
|
1738
|
+
return new ListRefInternals(params);
|
|
1604
1739
|
}
|
|
1740
|
+
};
|
|
1741
|
+
|
|
1742
|
+
// src/typed-refs/movable-list-ref-internals.ts
|
|
1743
|
+
var MovableListRefInternals = class extends ListRefBaseInternals {
|
|
1744
|
+
/** Absorb value at specific index for LoroMovableList */
|
|
1605
1745
|
absorbValueAtIndex(index, value) {
|
|
1606
|
-
this.
|
|
1746
|
+
const container = this.getContainer();
|
|
1747
|
+
container.set(index, value);
|
|
1607
1748
|
}
|
|
1749
|
+
/** Move an item from one index to another */
|
|
1608
1750
|
move(from, to) {
|
|
1609
|
-
this.
|
|
1751
|
+
const container = this.getContainer();
|
|
1752
|
+
container.move(from, to);
|
|
1610
1753
|
this.commitIfAuto();
|
|
1611
1754
|
}
|
|
1755
|
+
/** Set an item at a specific index */
|
|
1612
1756
|
set(index, item) {
|
|
1613
|
-
const
|
|
1757
|
+
const container = this.getContainer();
|
|
1758
|
+
container.set(index, item);
|
|
1614
1759
|
this.commitIfAuto();
|
|
1615
|
-
|
|
1760
|
+
}
|
|
1761
|
+
};
|
|
1762
|
+
|
|
1763
|
+
// src/typed-refs/movable-list-ref.ts
|
|
1764
|
+
var MovableListRef = class extends ListRefBase {
|
|
1765
|
+
createInternals(params) {
|
|
1766
|
+
return new MovableListRefInternals(params);
|
|
1767
|
+
}
|
|
1768
|
+
move(from, to) {
|
|
1769
|
+
this[INTERNAL_SYMBOL].move(from, to);
|
|
1770
|
+
}
|
|
1771
|
+
set(index, item) {
|
|
1772
|
+
this[INTERNAL_SYMBOL].set(index, item);
|
|
1616
1773
|
}
|
|
1617
1774
|
};
|
|
1618
1775
|
|
|
@@ -1620,7 +1777,7 @@ var MovableListRef = class extends ListRefBase {
|
|
|
1620
1777
|
var recordProxyHandler = {
|
|
1621
1778
|
get: (target, prop) => {
|
|
1622
1779
|
if (typeof prop === "string" && !(prop in target)) {
|
|
1623
|
-
return target.getRef(prop);
|
|
1780
|
+
return target[INTERNAL_SYMBOL].getRef(prop);
|
|
1624
1781
|
}
|
|
1625
1782
|
return Reflect.get(target, prop);
|
|
1626
1783
|
},
|
|
@@ -1706,20 +1863,12 @@ var movableListProxyHandler = {
|
|
|
1706
1863
|
}
|
|
1707
1864
|
};
|
|
1708
1865
|
|
|
1709
|
-
// src/typed-refs/record.ts
|
|
1710
|
-
var
|
|
1866
|
+
// src/typed-refs/record-ref-internals.ts
|
|
1867
|
+
var RecordRefInternals = class extends BaseRefInternals {
|
|
1711
1868
|
refCache = /* @__PURE__ */ new Map();
|
|
1712
|
-
|
|
1713
|
-
return super.shape;
|
|
1714
|
-
}
|
|
1715
|
-
get container() {
|
|
1716
|
-
return super.container;
|
|
1717
|
-
}
|
|
1718
|
-
absorbPlainValues() {
|
|
1719
|
-
absorbCachedPlainValues(this.refCache, () => this.container);
|
|
1720
|
-
}
|
|
1869
|
+
/** Get typed ref params for creating child refs at a key */
|
|
1721
1870
|
getTypedRefParams(key, shape) {
|
|
1722
|
-
let placeholder = this.
|
|
1871
|
+
let placeholder = this.getPlaceholder()?.[key];
|
|
1723
1872
|
if (placeholder === void 0) {
|
|
1724
1873
|
placeholder = deriveShapePlaceholder(shape);
|
|
1725
1874
|
}
|
|
@@ -1729,42 +1878,41 @@ var RecordRef = class extends TypedRef {
|
|
|
1729
1878
|
);
|
|
1730
1879
|
}
|
|
1731
1880
|
const LoroContainer = containerConstructor[shape._type];
|
|
1881
|
+
const container = this.getContainer();
|
|
1732
1882
|
return {
|
|
1733
1883
|
shape,
|
|
1734
1884
|
placeholder,
|
|
1735
|
-
getContainer: () =>
|
|
1736
|
-
autoCommit: this.
|
|
1737
|
-
batchedMutation: this.
|
|
1738
|
-
getDoc: this.
|
|
1885
|
+
getContainer: () => container.getOrCreateContainer(key, new LoroContainer()),
|
|
1886
|
+
autoCommit: this.getAutoCommit(),
|
|
1887
|
+
batchedMutation: this.getBatchedMutation(),
|
|
1888
|
+
getDoc: () => this.getDoc()
|
|
1739
1889
|
};
|
|
1740
1890
|
}
|
|
1741
|
-
/**
|
|
1742
|
-
* Gets an existing ref for a key, or returns undefined if the key doesn't exist.
|
|
1743
|
-
* Used for reading operations where we want optional chaining to work.
|
|
1744
|
-
*/
|
|
1891
|
+
/** Get a ref for a key without creating (returns undefined for non-existent container keys) */
|
|
1745
1892
|
getRef(key) {
|
|
1746
|
-
|
|
1747
|
-
|
|
1893
|
+
const recordShape = this.getShape();
|
|
1894
|
+
const shape = recordShape.shape;
|
|
1895
|
+
const container = this.getContainer();
|
|
1896
|
+
if (isContainerShape(shape)) {
|
|
1897
|
+
const existing = container.get(key);
|
|
1748
1898
|
if (existing === void 0) {
|
|
1749
1899
|
return void 0;
|
|
1750
1900
|
}
|
|
1751
1901
|
}
|
|
1752
1902
|
return this.getOrCreateRef(key);
|
|
1753
1903
|
}
|
|
1754
|
-
/**
|
|
1755
|
-
* Gets or creates a ref for a key.
|
|
1756
|
-
* Always creates the container if it doesn't exist.
|
|
1757
|
-
* This is the method used for write operations.
|
|
1758
|
-
*/
|
|
1904
|
+
/** Get or create a ref for a key (always creates for container shapes) */
|
|
1759
1905
|
getOrCreateRef(key) {
|
|
1760
|
-
const
|
|
1906
|
+
const recordShape = this.getShape();
|
|
1907
|
+
const shape = recordShape.shape;
|
|
1908
|
+
const container = this.getContainer();
|
|
1761
1909
|
if (isValueShape(shape)) {
|
|
1762
|
-
if (!this.
|
|
1763
|
-
const containerValue =
|
|
1910
|
+
if (!this.getBatchedMutation()) {
|
|
1911
|
+
const containerValue = container.get(key);
|
|
1764
1912
|
if (containerValue !== void 0) {
|
|
1765
1913
|
return containerValue;
|
|
1766
1914
|
}
|
|
1767
|
-
const placeholder = this.
|
|
1915
|
+
const placeholder = this.getPlaceholder()?.[key];
|
|
1768
1916
|
if (placeholder !== void 0) {
|
|
1769
1917
|
return placeholder;
|
|
1770
1918
|
}
|
|
@@ -1772,7 +1920,7 @@ var RecordRef = class extends TypedRef {
|
|
|
1772
1920
|
}
|
|
1773
1921
|
let ref2 = this.refCache.get(key);
|
|
1774
1922
|
if (!ref2) {
|
|
1775
|
-
const containerValue =
|
|
1923
|
+
const containerValue = container.get(key);
|
|
1776
1924
|
if (containerValue !== void 0) {
|
|
1777
1925
|
if (typeof containerValue === "object" && containerValue !== null) {
|
|
1778
1926
|
ref2 = JSON.parse(JSON.stringify(containerValue));
|
|
@@ -1780,7 +1928,7 @@ var RecordRef = class extends TypedRef {
|
|
|
1780
1928
|
ref2 = containerValue;
|
|
1781
1929
|
}
|
|
1782
1930
|
} else {
|
|
1783
|
-
const placeholder = this.
|
|
1931
|
+
const placeholder = this.getPlaceholder()?.[key];
|
|
1784
1932
|
if (placeholder !== void 0) {
|
|
1785
1933
|
ref2 = placeholder;
|
|
1786
1934
|
} else {
|
|
@@ -1800,12 +1948,13 @@ var RecordRef = class extends TypedRef {
|
|
|
1800
1948
|
}
|
|
1801
1949
|
return ref;
|
|
1802
1950
|
}
|
|
1803
|
-
|
|
1804
|
-
return this.getRef(key);
|
|
1805
|
-
}
|
|
1951
|
+
/** Set a value at a key */
|
|
1806
1952
|
set(key, value) {
|
|
1807
|
-
|
|
1808
|
-
|
|
1953
|
+
const recordShape = this.getShape();
|
|
1954
|
+
const shape = recordShape.shape;
|
|
1955
|
+
const container = this.getContainer();
|
|
1956
|
+
if (isValueShape(shape)) {
|
|
1957
|
+
container.set(key, value);
|
|
1809
1958
|
this.refCache.set(key, value);
|
|
1810
1959
|
this.commitIfAuto();
|
|
1811
1960
|
} else {
|
|
@@ -1819,74 +1968,124 @@ var RecordRef = class extends TypedRef {
|
|
|
1819
1968
|
);
|
|
1820
1969
|
}
|
|
1821
1970
|
}
|
|
1822
|
-
|
|
1823
|
-
const result = this.container.setContainer(key, container);
|
|
1824
|
-
this.commitIfAuto();
|
|
1825
|
-
return result;
|
|
1826
|
-
}
|
|
1971
|
+
/** Delete a key */
|
|
1827
1972
|
delete(key) {
|
|
1828
|
-
this.
|
|
1973
|
+
const container = this.getContainer();
|
|
1974
|
+
container.delete(key);
|
|
1829
1975
|
this.refCache.delete(key);
|
|
1830
1976
|
this.commitIfAuto();
|
|
1831
1977
|
}
|
|
1978
|
+
/** Absorb mutated plain values back into Loro containers */
|
|
1979
|
+
absorbPlainValues() {
|
|
1980
|
+
absorbCachedPlainValues(this.refCache, () => this.getContainer());
|
|
1981
|
+
}
|
|
1982
|
+
/** Create the loro namespace for record */
|
|
1983
|
+
createLoroNamespace() {
|
|
1984
|
+
const self = this;
|
|
1985
|
+
return {
|
|
1986
|
+
get doc() {
|
|
1987
|
+
return self.getDoc();
|
|
1988
|
+
},
|
|
1989
|
+
get container() {
|
|
1990
|
+
return self.getContainer();
|
|
1991
|
+
},
|
|
1992
|
+
subscribe(callback) {
|
|
1993
|
+
return self.getContainer().subscribe(callback);
|
|
1994
|
+
},
|
|
1995
|
+
setContainer(key, container) {
|
|
1996
|
+
const result = self.getContainer().setContainer(
|
|
1997
|
+
key,
|
|
1998
|
+
container
|
|
1999
|
+
);
|
|
2000
|
+
self.commitIfAuto();
|
|
2001
|
+
return result;
|
|
2002
|
+
}
|
|
2003
|
+
};
|
|
2004
|
+
}
|
|
2005
|
+
};
|
|
2006
|
+
|
|
2007
|
+
// src/typed-refs/record-ref.ts
|
|
2008
|
+
var RecordRef = class extends TypedRef {
|
|
2009
|
+
[INTERNAL_SYMBOL];
|
|
2010
|
+
constructor(params) {
|
|
2011
|
+
super();
|
|
2012
|
+
this[INTERNAL_SYMBOL] = new RecordRefInternals(params);
|
|
2013
|
+
}
|
|
2014
|
+
/** Set a value at a key */
|
|
2015
|
+
set(key, value) {
|
|
2016
|
+
this[INTERNAL_SYMBOL].set(key, value);
|
|
2017
|
+
}
|
|
2018
|
+
/** Delete a key */
|
|
2019
|
+
delete(key) {
|
|
2020
|
+
this[INTERNAL_SYMBOL].delete(key);
|
|
2021
|
+
}
|
|
2022
|
+
get(key) {
|
|
2023
|
+
if (this[INTERNAL_SYMBOL].getBatchedMutation()) {
|
|
2024
|
+
return this[INTERNAL_SYMBOL].getOrCreateRef(key);
|
|
2025
|
+
}
|
|
2026
|
+
return this[INTERNAL_SYMBOL].getRef(key);
|
|
2027
|
+
}
|
|
2028
|
+
setContainer(key, container) {
|
|
2029
|
+
const loroContainer = this[INTERNAL_SYMBOL].getContainer();
|
|
2030
|
+
const result = loroContainer.setContainer(key, container);
|
|
2031
|
+
this[INTERNAL_SYMBOL].commitIfAuto();
|
|
2032
|
+
return result;
|
|
2033
|
+
}
|
|
1832
2034
|
has(key) {
|
|
1833
|
-
|
|
2035
|
+
const container = this[INTERNAL_SYMBOL].getContainer();
|
|
2036
|
+
return container.get(key) !== void 0;
|
|
1834
2037
|
}
|
|
1835
2038
|
keys() {
|
|
1836
|
-
|
|
2039
|
+
const container = this[INTERNAL_SYMBOL].getContainer();
|
|
2040
|
+
return container.keys();
|
|
1837
2041
|
}
|
|
1838
2042
|
values() {
|
|
1839
|
-
|
|
2043
|
+
const container = this[INTERNAL_SYMBOL].getContainer();
|
|
2044
|
+
return container.values();
|
|
1840
2045
|
}
|
|
1841
2046
|
get size() {
|
|
1842
|
-
|
|
2047
|
+
const container = this[INTERNAL_SYMBOL].getContainer();
|
|
2048
|
+
return container.size;
|
|
1843
2049
|
}
|
|
1844
2050
|
toJSON() {
|
|
1845
2051
|
return serializeRefToJSON(this, this.keys());
|
|
1846
2052
|
}
|
|
1847
2053
|
};
|
|
1848
2054
|
|
|
1849
|
-
// src/typed-refs/struct.ts
|
|
1850
|
-
var
|
|
2055
|
+
// src/typed-refs/struct-ref-internals.ts
|
|
2056
|
+
var StructRefInternals = class extends BaseRefInternals {
|
|
1851
2057
|
propertyCache = /* @__PURE__ */ new Map();
|
|
1852
|
-
|
|
1853
|
-
super(params);
|
|
1854
|
-
this.createLazyProperties();
|
|
1855
|
-
}
|
|
1856
|
-
get shape() {
|
|
1857
|
-
return super.shape;
|
|
1858
|
-
}
|
|
1859
|
-
get container() {
|
|
1860
|
-
return super.container;
|
|
1861
|
-
}
|
|
1862
|
-
absorbPlainValues() {
|
|
1863
|
-
absorbCachedPlainValues(this.propertyCache, () => this.container);
|
|
1864
|
-
}
|
|
2058
|
+
/** Get typed ref params for creating child refs at a key */
|
|
1865
2059
|
getTypedRefParams(key, shape) {
|
|
1866
|
-
const placeholder = this.
|
|
2060
|
+
const placeholder = this.getPlaceholder()?.[key];
|
|
1867
2061
|
if (!hasContainerConstructor(shape._type)) {
|
|
1868
2062
|
throw new Error(
|
|
1869
2063
|
`Cannot create typed ref for shape type "${shape._type}". Use Shape.any() only at the document root level.`
|
|
1870
2064
|
);
|
|
1871
2065
|
}
|
|
1872
2066
|
const LoroContainer = containerConstructor[shape._type];
|
|
2067
|
+
const container = this.getContainer();
|
|
1873
2068
|
return {
|
|
1874
2069
|
shape,
|
|
1875
2070
|
placeholder,
|
|
1876
|
-
getContainer: () =>
|
|
1877
|
-
autoCommit: this.
|
|
1878
|
-
batchedMutation: this.
|
|
1879
|
-
getDoc: this.
|
|
2071
|
+
getContainer: () => container.getOrCreateContainer(key, new LoroContainer()),
|
|
2072
|
+
autoCommit: this.getAutoCommit(),
|
|
2073
|
+
batchedMutation: this.getBatchedMutation(),
|
|
2074
|
+
getDoc: () => this.getDoc()
|
|
1880
2075
|
};
|
|
1881
2076
|
}
|
|
2077
|
+
/** Get or create a ref for a key */
|
|
1882
2078
|
getOrCreateRef(key, shape) {
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
2079
|
+
const structShape = this.getShape();
|
|
2080
|
+
const actualShape = shape || structShape.shapes[key];
|
|
2081
|
+
const container = this.getContainer();
|
|
2082
|
+
if (isValueShape(actualShape)) {
|
|
2083
|
+
if (!this.getBatchedMutation()) {
|
|
2084
|
+
const containerValue = container.get(key);
|
|
1886
2085
|
if (containerValue !== void 0) {
|
|
1887
2086
|
return containerValue;
|
|
1888
2087
|
}
|
|
1889
|
-
const placeholder = this.
|
|
2088
|
+
const placeholder = this.getPlaceholder()?.[key];
|
|
1890
2089
|
if (placeholder === void 0) {
|
|
1891
2090
|
throw new Error("placeholder required");
|
|
1892
2091
|
}
|
|
@@ -1894,7 +2093,7 @@ var StructRef = class extends TypedRef {
|
|
|
1894
2093
|
}
|
|
1895
2094
|
let ref2 = this.propertyCache.get(key);
|
|
1896
2095
|
if (!ref2) {
|
|
1897
|
-
const containerValue =
|
|
2096
|
+
const containerValue = container.get(key);
|
|
1898
2097
|
if (containerValue !== void 0) {
|
|
1899
2098
|
if (typeof containerValue === "object" && containerValue !== null) {
|
|
1900
2099
|
ref2 = JSON.parse(JSON.stringify(containerValue));
|
|
@@ -1902,7 +2101,7 @@ var StructRef = class extends TypedRef {
|
|
|
1902
2101
|
ref2 = containerValue;
|
|
1903
2102
|
}
|
|
1904
2103
|
} else {
|
|
1905
|
-
const placeholder = this.
|
|
2104
|
+
const placeholder = this.getPlaceholder()?.[key];
|
|
1906
2105
|
if (placeholder === void 0) {
|
|
1907
2106
|
throw new Error("placeholder required");
|
|
1908
2107
|
}
|
|
@@ -1914,196 +2113,424 @@ var StructRef = class extends TypedRef {
|
|
|
1914
2113
|
}
|
|
1915
2114
|
let ref = this.propertyCache.get(key);
|
|
1916
2115
|
if (!ref) {
|
|
1917
|
-
ref = createContainerTypedRef(
|
|
2116
|
+
ref = createContainerTypedRef(
|
|
2117
|
+
this.getTypedRefParams(key, actualShape)
|
|
2118
|
+
);
|
|
1918
2119
|
this.propertyCache.set(key, ref);
|
|
1919
2120
|
}
|
|
1920
2121
|
return ref;
|
|
1921
2122
|
}
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
2123
|
+
/** Set a property value */
|
|
2124
|
+
setPropertyValue(key, value) {
|
|
2125
|
+
const structShape = this.getShape();
|
|
2126
|
+
const shape = structShape.shapes[key];
|
|
2127
|
+
const container = this.getContainer();
|
|
2128
|
+
if (!shape) {
|
|
2129
|
+
throw new Error(`Unknown property: ${key}`);
|
|
2130
|
+
}
|
|
2131
|
+
if (isValueShape(shape)) {
|
|
2132
|
+
container.set(key, value);
|
|
2133
|
+
this.propertyCache.set(key, value);
|
|
2134
|
+
this.commitIfAuto();
|
|
2135
|
+
} else {
|
|
2136
|
+
const ref = this.getOrCreateRef(key, shape);
|
|
2137
|
+
if (assignPlainValueToTypedRef(ref, value)) {
|
|
2138
|
+
this.commitIfAuto();
|
|
2139
|
+
return;
|
|
2140
|
+
}
|
|
2141
|
+
throw new Error(
|
|
2142
|
+
"Cannot set container directly, modify the typed ref instead"
|
|
2143
|
+
);
|
|
1943
2144
|
}
|
|
1944
2145
|
}
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
2146
|
+
/** Delete a property */
|
|
2147
|
+
deleteProperty(key) {
|
|
2148
|
+
const container = this.getContainer();
|
|
2149
|
+
container.delete(key);
|
|
2150
|
+
this.propertyCache.delete(key);
|
|
2151
|
+
this.commitIfAuto();
|
|
2152
|
+
}
|
|
2153
|
+
/** Absorb mutated plain values back into Loro containers */
|
|
2154
|
+
absorbPlainValues() {
|
|
2155
|
+
absorbCachedPlainValues(
|
|
2156
|
+
this.propertyCache,
|
|
2157
|
+
() => this.getContainer()
|
|
1949
2158
|
);
|
|
1950
2159
|
}
|
|
1951
|
-
|
|
2160
|
+
/** Create the loro namespace for struct */
|
|
2161
|
+
createLoroNamespace() {
|
|
2162
|
+
const self = this;
|
|
2163
|
+
return {
|
|
2164
|
+
get doc() {
|
|
2165
|
+
return self.getDoc();
|
|
2166
|
+
},
|
|
2167
|
+
get container() {
|
|
2168
|
+
return self.getContainer();
|
|
2169
|
+
},
|
|
2170
|
+
subscribe(callback) {
|
|
2171
|
+
return self.getContainer().subscribe(callback);
|
|
2172
|
+
},
|
|
2173
|
+
setContainer(key, container) {
|
|
2174
|
+
const result = self.getContainer().setContainer(
|
|
2175
|
+
key,
|
|
2176
|
+
container
|
|
2177
|
+
);
|
|
2178
|
+
self.commitIfAuto();
|
|
2179
|
+
return result;
|
|
2180
|
+
}
|
|
2181
|
+
};
|
|
2182
|
+
}
|
|
2183
|
+
};
|
|
2184
|
+
|
|
2185
|
+
// src/typed-refs/struct-ref.ts
|
|
2186
|
+
var StructRefImpl = class extends TypedRef {
|
|
2187
|
+
[INTERNAL_SYMBOL];
|
|
2188
|
+
constructor(params) {
|
|
2189
|
+
super();
|
|
2190
|
+
this[INTERNAL_SYMBOL] = new StructRefInternals(params);
|
|
2191
|
+
}
|
|
2192
|
+
get structShape() {
|
|
2193
|
+
return this[INTERNAL_SYMBOL].getShape();
|
|
2194
|
+
}
|
|
2195
|
+
toJSON() {
|
|
2196
|
+
return serializeRefToJSON(
|
|
2197
|
+
this,
|
|
2198
|
+
Object.keys(this.structShape.shapes)
|
|
2199
|
+
);
|
|
2200
|
+
}
|
|
2201
|
+
// Deprecated methods - kept for backward compatibility
|
|
2202
|
+
// @deprecated Use property access instead: obj.key
|
|
1952
2203
|
get(key) {
|
|
1953
|
-
|
|
2204
|
+
const container = this[INTERNAL_SYMBOL].getContainer();
|
|
2205
|
+
return container.get(key);
|
|
1954
2206
|
}
|
|
2207
|
+
// @deprecated Use property assignment instead: obj.key = value
|
|
1955
2208
|
set(key, value) {
|
|
1956
|
-
this.
|
|
1957
|
-
|
|
2209
|
+
const container = this[INTERNAL_SYMBOL].getContainer();
|
|
2210
|
+
container.set(key, value);
|
|
2211
|
+
this[INTERNAL_SYMBOL].commitIfAuto();
|
|
1958
2212
|
}
|
|
2213
|
+
// @deprecated Use loro(struct).setContainer() instead
|
|
1959
2214
|
setContainer(key, container) {
|
|
1960
|
-
const
|
|
1961
|
-
|
|
2215
|
+
const loroContainer = this[INTERNAL_SYMBOL].getContainer();
|
|
2216
|
+
const result = loroContainer.setContainer(key, container);
|
|
2217
|
+
this[INTERNAL_SYMBOL].commitIfAuto();
|
|
1962
2218
|
return result;
|
|
1963
2219
|
}
|
|
2220
|
+
// @deprecated Use delete obj.key instead
|
|
1964
2221
|
delete(key) {
|
|
1965
|
-
this.
|
|
1966
|
-
|
|
2222
|
+
const container = this[INTERNAL_SYMBOL].getContainer();
|
|
2223
|
+
container.delete(key);
|
|
2224
|
+
this[INTERNAL_SYMBOL].commitIfAuto();
|
|
1967
2225
|
}
|
|
2226
|
+
// @deprecated Use 'key' in obj instead
|
|
1968
2227
|
has(key) {
|
|
1969
|
-
|
|
2228
|
+
const container = this[INTERNAL_SYMBOL].getContainer();
|
|
2229
|
+
return container.get(key) !== void 0;
|
|
1970
2230
|
}
|
|
2231
|
+
// @deprecated Use Object.keys(obj) instead
|
|
1971
2232
|
keys() {
|
|
1972
|
-
|
|
2233
|
+
const container = this[INTERNAL_SYMBOL].getContainer();
|
|
2234
|
+
return container.keys();
|
|
1973
2235
|
}
|
|
2236
|
+
// @deprecated Use Object.values(obj) instead
|
|
1974
2237
|
values() {
|
|
1975
|
-
|
|
2238
|
+
const container = this[INTERNAL_SYMBOL].getContainer();
|
|
2239
|
+
return container.values();
|
|
1976
2240
|
}
|
|
2241
|
+
// @deprecated Not standard for objects
|
|
1977
2242
|
get size() {
|
|
1978
|
-
|
|
2243
|
+
const container = this[INTERNAL_SYMBOL].getContainer();
|
|
2244
|
+
return container.size;
|
|
1979
2245
|
}
|
|
1980
2246
|
};
|
|
2247
|
+
function createStructRef(params) {
|
|
2248
|
+
const impl = new StructRefImpl(params);
|
|
2249
|
+
const proxy = new Proxy(impl, {
|
|
2250
|
+
get(target, prop, receiver) {
|
|
2251
|
+
if (prop === LORO_SYMBOL) {
|
|
2252
|
+
return target[INTERNAL_SYMBOL].getLoroNamespace();
|
|
2253
|
+
}
|
|
2254
|
+
if (prop === INTERNAL_SYMBOL) {
|
|
2255
|
+
return target[INTERNAL_SYMBOL];
|
|
2256
|
+
}
|
|
2257
|
+
if (prop === "toJSON") {
|
|
2258
|
+
return () => serializeRefToJSON(receiver, Object.keys(target.structShape.shapes));
|
|
2259
|
+
}
|
|
2260
|
+
if (prop === "shape") {
|
|
2261
|
+
return target.structShape;
|
|
2262
|
+
}
|
|
2263
|
+
if (typeof prop === "string" && prop in target.structShape.shapes) {
|
|
2264
|
+
const shape = target.structShape.shapes[prop];
|
|
2265
|
+
return target[INTERNAL_SYMBOL].getOrCreateRef(prop, shape);
|
|
2266
|
+
}
|
|
2267
|
+
return void 0;
|
|
2268
|
+
},
|
|
2269
|
+
set(target, prop, value) {
|
|
2270
|
+
if (typeof prop === "string" && prop in target.structShape.shapes) {
|
|
2271
|
+
target[INTERNAL_SYMBOL].setPropertyValue(prop, value);
|
|
2272
|
+
return true;
|
|
2273
|
+
}
|
|
2274
|
+
return false;
|
|
2275
|
+
},
|
|
2276
|
+
has(target, prop) {
|
|
2277
|
+
if (prop === LORO_SYMBOL || prop === INTERNAL_SYMBOL || prop === "toJSON" || prop === "shape") {
|
|
2278
|
+
return true;
|
|
2279
|
+
}
|
|
2280
|
+
if (typeof prop === "string") {
|
|
2281
|
+
return prop in target.structShape.shapes;
|
|
2282
|
+
}
|
|
2283
|
+
return false;
|
|
2284
|
+
},
|
|
2285
|
+
deleteProperty(target, prop) {
|
|
2286
|
+
if (typeof prop === "string" && prop in target.structShape.shapes) {
|
|
2287
|
+
target[INTERNAL_SYMBOL].deleteProperty(prop);
|
|
2288
|
+
return true;
|
|
2289
|
+
}
|
|
2290
|
+
return false;
|
|
2291
|
+
},
|
|
2292
|
+
ownKeys(target) {
|
|
2293
|
+
return Object.keys(target.structShape.shapes);
|
|
2294
|
+
},
|
|
2295
|
+
getOwnPropertyDescriptor(target, prop) {
|
|
2296
|
+
if (typeof prop === "string" && prop in target.structShape.shapes) {
|
|
2297
|
+
const shape = target.structShape.shapes[prop];
|
|
2298
|
+
return {
|
|
2299
|
+
configurable: true,
|
|
2300
|
+
enumerable: true,
|
|
2301
|
+
value: target[INTERNAL_SYMBOL].getOrCreateRef(prop, shape)
|
|
2302
|
+
};
|
|
2303
|
+
}
|
|
2304
|
+
return void 0;
|
|
2305
|
+
}
|
|
2306
|
+
});
|
|
2307
|
+
return proxy;
|
|
2308
|
+
}
|
|
1981
2309
|
|
|
1982
|
-
// src/typed-refs/text.ts
|
|
1983
|
-
var
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
get container() {
|
|
1987
|
-
return super.container;
|
|
1988
|
-
}
|
|
1989
|
-
absorbPlainValues() {
|
|
1990
|
-
}
|
|
1991
|
-
// Text methods
|
|
2310
|
+
// src/typed-refs/text-ref-internals.ts
|
|
2311
|
+
var TextRefInternals = class extends BaseRefInternals {
|
|
2312
|
+
materialized = false;
|
|
2313
|
+
/** Insert text at the given index */
|
|
1992
2314
|
insert(index, content) {
|
|
1993
|
-
this.
|
|
1994
|
-
this.
|
|
2315
|
+
this.materialized = true;
|
|
2316
|
+
this.getContainer().insert(index, content);
|
|
1995
2317
|
this.commitIfAuto();
|
|
1996
2318
|
}
|
|
2319
|
+
/** Delete text at the given index */
|
|
1997
2320
|
delete(index, len) {
|
|
1998
|
-
this.
|
|
1999
|
-
this.
|
|
2321
|
+
this.materialized = true;
|
|
2322
|
+
this.getContainer().delete(index, len);
|
|
2000
2323
|
this.commitIfAuto();
|
|
2001
2324
|
}
|
|
2002
|
-
/**
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2325
|
+
/** Update the entire text content */
|
|
2326
|
+
update(text) {
|
|
2327
|
+
this.materialized = true;
|
|
2328
|
+
this.getContainer().update(text);
|
|
2329
|
+
this.commitIfAuto();
|
|
2330
|
+
}
|
|
2331
|
+
/** Mark a range of text with a key-value pair */
|
|
2332
|
+
mark(range, key, value) {
|
|
2333
|
+
this.materialized = true;
|
|
2334
|
+
this.getContainer().mark(range, key, value);
|
|
2335
|
+
this.commitIfAuto();
|
|
2336
|
+
}
|
|
2337
|
+
/** Remove a mark from a range of text */
|
|
2338
|
+
unmark(range, key) {
|
|
2339
|
+
this.materialized = true;
|
|
2340
|
+
this.getContainer().unmark(range, key);
|
|
2341
|
+
this.commitIfAuto();
|
|
2342
|
+
}
|
|
2343
|
+
/** Apply a delta to the text */
|
|
2344
|
+
applyDelta(delta) {
|
|
2345
|
+
this.materialized = true;
|
|
2346
|
+
this.getContainer().applyDelta(delta);
|
|
2347
|
+
this.commitIfAuto();
|
|
2348
|
+
}
|
|
2349
|
+
/** Get the text as a string */
|
|
2350
|
+
getStringValue() {
|
|
2351
|
+
const container = this.getContainer();
|
|
2352
|
+
const containerValue = container.toString();
|
|
2353
|
+
if (containerValue !== "" || this.materialized) {
|
|
2010
2354
|
return containerValue;
|
|
2011
2355
|
}
|
|
2012
|
-
|
|
2013
|
-
|
|
2356
|
+
const placeholder = this.getPlaceholder();
|
|
2357
|
+
if (placeholder !== void 0) {
|
|
2358
|
+
return placeholder;
|
|
2014
2359
|
}
|
|
2015
2360
|
return containerValue;
|
|
2016
2361
|
}
|
|
2017
|
-
|
|
2018
|
-
|
|
2362
|
+
/** Get the text as a delta */
|
|
2363
|
+
toDelta() {
|
|
2364
|
+
return this.getContainer().toDelta();
|
|
2019
2365
|
}
|
|
2020
|
-
|
|
2021
|
-
|
|
2366
|
+
/** Get the length of the text */
|
|
2367
|
+
getLength() {
|
|
2368
|
+
return this.getContainer().length;
|
|
2022
2369
|
}
|
|
2023
|
-
|
|
2024
|
-
|
|
2370
|
+
/** No plain values in text */
|
|
2371
|
+
absorbPlainValues() {
|
|
2372
|
+
}
|
|
2373
|
+
/** Create the loro namespace for text */
|
|
2374
|
+
createLoroNamespace() {
|
|
2375
|
+
const self = this;
|
|
2376
|
+
return {
|
|
2377
|
+
get doc() {
|
|
2378
|
+
return self.getDoc();
|
|
2379
|
+
},
|
|
2380
|
+
get container() {
|
|
2381
|
+
return self.getContainer();
|
|
2382
|
+
},
|
|
2383
|
+
subscribe(callback) {
|
|
2384
|
+
return self.getContainer().subscribe(callback);
|
|
2385
|
+
}
|
|
2386
|
+
};
|
|
2387
|
+
}
|
|
2388
|
+
};
|
|
2389
|
+
|
|
2390
|
+
// src/typed-refs/text-ref.ts
|
|
2391
|
+
var TextRef = class extends TypedRef {
|
|
2392
|
+
[INTERNAL_SYMBOL];
|
|
2393
|
+
constructor(params) {
|
|
2394
|
+
super();
|
|
2395
|
+
this[INTERNAL_SYMBOL] = new TextRefInternals(params);
|
|
2396
|
+
}
|
|
2397
|
+
/** Insert text at the given index */
|
|
2398
|
+
insert(index, content) {
|
|
2399
|
+
this[INTERNAL_SYMBOL].insert(index, content);
|
|
2400
|
+
}
|
|
2401
|
+
/** Delete text at the given index */
|
|
2402
|
+
delete(index, len) {
|
|
2403
|
+
this[INTERNAL_SYMBOL].delete(index, len);
|
|
2025
2404
|
}
|
|
2405
|
+
/** Update the entire text content */
|
|
2026
2406
|
update(text) {
|
|
2027
|
-
this.
|
|
2028
|
-
this.container.update(text);
|
|
2029
|
-
this.commitIfAuto();
|
|
2407
|
+
this[INTERNAL_SYMBOL].update(text);
|
|
2030
2408
|
}
|
|
2409
|
+
/** Mark a range of text with a key-value pair */
|
|
2031
2410
|
mark(range, key, value) {
|
|
2032
|
-
this.
|
|
2033
|
-
this.container.mark(range, key, value);
|
|
2034
|
-
this.commitIfAuto();
|
|
2411
|
+
this[INTERNAL_SYMBOL].mark(range, key, value);
|
|
2035
2412
|
}
|
|
2413
|
+
/** Remove a mark from a range of text */
|
|
2036
2414
|
unmark(range, key) {
|
|
2037
|
-
this.
|
|
2038
|
-
this.container.unmark(range, key);
|
|
2039
|
-
this.commitIfAuto();
|
|
2040
|
-
}
|
|
2041
|
-
toDelta() {
|
|
2042
|
-
return this.container.toDelta();
|
|
2415
|
+
this[INTERNAL_SYMBOL].unmark(range, key);
|
|
2043
2416
|
}
|
|
2417
|
+
/** Apply a delta to the text */
|
|
2044
2418
|
applyDelta(delta) {
|
|
2045
|
-
this.
|
|
2046
|
-
|
|
2047
|
-
|
|
2419
|
+
this[INTERNAL_SYMBOL].applyDelta(delta);
|
|
2420
|
+
}
|
|
2421
|
+
/** Get the text as a string */
|
|
2422
|
+
toString() {
|
|
2423
|
+
return this[INTERNAL_SYMBOL].getStringValue();
|
|
2424
|
+
}
|
|
2425
|
+
valueOf() {
|
|
2426
|
+
return this.toString();
|
|
2427
|
+
}
|
|
2428
|
+
toJSON() {
|
|
2429
|
+
return this.toString();
|
|
2048
2430
|
}
|
|
2431
|
+
[Symbol.toPrimitive](_hint) {
|
|
2432
|
+
return this.toString();
|
|
2433
|
+
}
|
|
2434
|
+
/** Get the text as a delta */
|
|
2435
|
+
toDelta() {
|
|
2436
|
+
return this[INTERNAL_SYMBOL].toDelta();
|
|
2437
|
+
}
|
|
2438
|
+
/** Get the length of the text */
|
|
2049
2439
|
get length() {
|
|
2050
|
-
return this.
|
|
2440
|
+
return this[INTERNAL_SYMBOL].getLength();
|
|
2051
2441
|
}
|
|
2052
2442
|
};
|
|
2053
2443
|
|
|
2054
|
-
// src/typed-refs/tree-node.ts
|
|
2055
|
-
var
|
|
2056
|
-
_node;
|
|
2057
|
-
_dataShape;
|
|
2058
|
-
_treeRef;
|
|
2059
|
-
_dataRef;
|
|
2060
|
-
_autoCommit;
|
|
2061
|
-
_batchedMutation;
|
|
2062
|
-
_getDoc;
|
|
2444
|
+
// src/typed-refs/tree-node-ref-internals.ts
|
|
2445
|
+
var TreeNodeRefInternals = class {
|
|
2063
2446
|
constructor(params) {
|
|
2064
|
-
this.
|
|
2065
|
-
this._dataShape = params.dataShape;
|
|
2066
|
-
this._treeRef = params.treeRef;
|
|
2067
|
-
this._autoCommit = params.autoCommit ?? false;
|
|
2068
|
-
this._batchedMutation = params.batchedMutation ?? false;
|
|
2069
|
-
this._getDoc = params.getDoc;
|
|
2447
|
+
this.params = params;
|
|
2070
2448
|
}
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
return this._node.id;
|
|
2449
|
+
dataRef;
|
|
2450
|
+
/** Get the underlying LoroTreeNode */
|
|
2451
|
+
getNode() {
|
|
2452
|
+
return this.params.node;
|
|
2076
2453
|
}
|
|
2077
|
-
/**
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2454
|
+
/** Get the data shape for this node */
|
|
2455
|
+
getDataShape() {
|
|
2456
|
+
return this.params.dataShape;
|
|
2457
|
+
}
|
|
2458
|
+
/** Get the parent TreeRef */
|
|
2459
|
+
getTreeRef() {
|
|
2460
|
+
return this.params.treeRef;
|
|
2461
|
+
}
|
|
2462
|
+
/** Check if autoCommit is enabled */
|
|
2463
|
+
getAutoCommit() {
|
|
2464
|
+
return this.params.autoCommit ?? false;
|
|
2465
|
+
}
|
|
2466
|
+
/** Check if in batched mutation mode */
|
|
2467
|
+
getBatchedMutation() {
|
|
2468
|
+
return this.params.batchedMutation ?? false;
|
|
2469
|
+
}
|
|
2470
|
+
/** Get the LoroDoc */
|
|
2471
|
+
getDoc() {
|
|
2472
|
+
return this.params.getDoc();
|
|
2473
|
+
}
|
|
2474
|
+
/** Commit changes if autoCommit is enabled */
|
|
2475
|
+
commitIfAuto() {
|
|
2476
|
+
if (this.params.autoCommit) {
|
|
2477
|
+
this.params.getDoc().commit();
|
|
2478
|
+
}
|
|
2479
|
+
}
|
|
2480
|
+
/** Get or create the data StructRef */
|
|
2481
|
+
getOrCreateDataRef() {
|
|
2482
|
+
if (!this.dataRef) {
|
|
2483
|
+
const node = this.getNode();
|
|
2484
|
+
const dataShape = this.getDataShape();
|
|
2485
|
+
const dataContainer = node.data;
|
|
2084
2486
|
if (!dataContainer) {
|
|
2085
|
-
throw new Error(`Node ${
|
|
2487
|
+
throw new Error(`Node ${node.id} has no data container`);
|
|
2086
2488
|
}
|
|
2087
|
-
const placeholder = deriveShapePlaceholder(
|
|
2088
|
-
|
|
2089
|
-
);
|
|
2090
|
-
const params = {
|
|
2489
|
+
const placeholder = deriveShapePlaceholder(dataShape);
|
|
2490
|
+
const refParams = {
|
|
2091
2491
|
shape: {
|
|
2092
2492
|
_type: "struct",
|
|
2093
|
-
shapes:
|
|
2493
|
+
shapes: dataShape.shapes,
|
|
2094
2494
|
_plain: {},
|
|
2095
2495
|
_mutable: {},
|
|
2096
2496
|
_placeholder: {}
|
|
2097
2497
|
},
|
|
2098
2498
|
placeholder,
|
|
2099
2499
|
getContainer: () => dataContainer,
|
|
2100
|
-
autoCommit: this.
|
|
2101
|
-
batchedMutation: this.
|
|
2102
|
-
getDoc: this.
|
|
2500
|
+
autoCommit: this.getAutoCommit(),
|
|
2501
|
+
batchedMutation: this.getBatchedMutation(),
|
|
2502
|
+
getDoc: this.params.getDoc
|
|
2103
2503
|
};
|
|
2104
|
-
this.
|
|
2504
|
+
this.dataRef = createStructRef(refParams);
|
|
2505
|
+
}
|
|
2506
|
+
return this.dataRef;
|
|
2507
|
+
}
|
|
2508
|
+
/** Absorb mutated plain values back into Loro containers */
|
|
2509
|
+
absorbPlainValues() {
|
|
2510
|
+
if (this.dataRef) {
|
|
2511
|
+
this.dataRef[INTERNAL_SYMBOL].absorbPlainValues();
|
|
2105
2512
|
}
|
|
2106
|
-
|
|
2513
|
+
}
|
|
2514
|
+
};
|
|
2515
|
+
|
|
2516
|
+
// src/typed-refs/tree-node-ref.ts
|
|
2517
|
+
var TreeNodeRef = class {
|
|
2518
|
+
[INTERNAL_SYMBOL];
|
|
2519
|
+
constructor(params) {
|
|
2520
|
+
this[INTERNAL_SYMBOL] = new TreeNodeRefInternals(params);
|
|
2521
|
+
}
|
|
2522
|
+
/**
|
|
2523
|
+
* The unique TreeID of this node.
|
|
2524
|
+
*/
|
|
2525
|
+
get id() {
|
|
2526
|
+
return this[INTERNAL_SYMBOL].getNode().id;
|
|
2527
|
+
}
|
|
2528
|
+
/**
|
|
2529
|
+
* Typed access to the node's metadata.
|
|
2530
|
+
* This is a StructRef wrapping the node's LoroMap data container.
|
|
2531
|
+
*/
|
|
2532
|
+
get data() {
|
|
2533
|
+
return this[INTERNAL_SYMBOL].getOrCreateDataRef();
|
|
2107
2534
|
}
|
|
2108
2535
|
/**
|
|
2109
2536
|
* Create a child node under this node.
|
|
@@ -2113,33 +2540,37 @@ var TreeNodeRef = class {
|
|
|
2113
2540
|
* @returns The created child TreeNodeRef
|
|
2114
2541
|
*/
|
|
2115
2542
|
createNode(initialData, index) {
|
|
2116
|
-
const
|
|
2117
|
-
const
|
|
2543
|
+
const node = this[INTERNAL_SYMBOL].getNode();
|
|
2544
|
+
const treeRef = this[INTERNAL_SYMBOL].getTreeRef();
|
|
2545
|
+
const loroNode = node.createNode(index);
|
|
2546
|
+
const nodeRef = treeRef.getOrCreateNodeRef(loroNode);
|
|
2118
2547
|
if (initialData) {
|
|
2119
2548
|
for (const [key, value] of Object.entries(initialData)) {
|
|
2120
2549
|
;
|
|
2121
2550
|
nodeRef.data[key] = value;
|
|
2122
2551
|
}
|
|
2123
2552
|
}
|
|
2124
|
-
this.commitIfAuto();
|
|
2553
|
+
this[INTERNAL_SYMBOL].commitIfAuto();
|
|
2125
2554
|
return nodeRef;
|
|
2126
2555
|
}
|
|
2127
2556
|
/**
|
|
2128
2557
|
* Get the parent node, if any.
|
|
2129
2558
|
*/
|
|
2130
2559
|
parent() {
|
|
2131
|
-
const
|
|
2560
|
+
const node = this[INTERNAL_SYMBOL].getNode();
|
|
2561
|
+
const treeRef = this[INTERNAL_SYMBOL].getTreeRef();
|
|
2562
|
+
const parentNode = node.parent?.();
|
|
2132
2563
|
if (!parentNode) return void 0;
|
|
2133
|
-
return
|
|
2564
|
+
return treeRef.getOrCreateNodeRef(parentNode);
|
|
2134
2565
|
}
|
|
2135
2566
|
/**
|
|
2136
2567
|
* Get all child nodes in order.
|
|
2137
2568
|
*/
|
|
2138
2569
|
children() {
|
|
2139
|
-
const
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
);
|
|
2570
|
+
const node = this[INTERNAL_SYMBOL].getNode();
|
|
2571
|
+
const treeRef = this[INTERNAL_SYMBOL].getTreeRef();
|
|
2572
|
+
const childNodes = node.children?.() || [];
|
|
2573
|
+
return childNodes.map((n) => treeRef.getOrCreateNodeRef(n));
|
|
2143
2574
|
}
|
|
2144
2575
|
/**
|
|
2145
2576
|
* Move this node to a new parent.
|
|
@@ -2148,49 +2579,49 @@ var TreeNodeRef = class {
|
|
|
2148
2579
|
* @param index - Optional position among siblings
|
|
2149
2580
|
*/
|
|
2150
2581
|
move(newParent, index) {
|
|
2151
|
-
const
|
|
2152
|
-
|
|
2153
|
-
|
|
2582
|
+
const node = this[INTERNAL_SYMBOL].getNode();
|
|
2583
|
+
const parentNode = newParent ? newParent[INTERNAL_SYMBOL].getNode() : void 0;
|
|
2584
|
+
node.move?.(parentNode, index);
|
|
2585
|
+
this[INTERNAL_SYMBOL].commitIfAuto();
|
|
2154
2586
|
}
|
|
2155
2587
|
/**
|
|
2156
2588
|
* Move this node to be after the given sibling.
|
|
2157
2589
|
*/
|
|
2158
2590
|
moveAfter(sibling) {
|
|
2159
|
-
this.
|
|
2160
|
-
|
|
2591
|
+
const node = this[INTERNAL_SYMBOL].getNode();
|
|
2592
|
+
const siblingNode = sibling[INTERNAL_SYMBOL].getNode();
|
|
2593
|
+
node.moveAfter(siblingNode);
|
|
2594
|
+
this[INTERNAL_SYMBOL].commitIfAuto();
|
|
2161
2595
|
}
|
|
2162
2596
|
/**
|
|
2163
2597
|
* Move this node to be before the given sibling.
|
|
2164
2598
|
*/
|
|
2165
2599
|
moveBefore(sibling) {
|
|
2166
|
-
this.
|
|
2167
|
-
|
|
2600
|
+
const node = this[INTERNAL_SYMBOL].getNode();
|
|
2601
|
+
const siblingNode = sibling[INTERNAL_SYMBOL].getNode();
|
|
2602
|
+
node.moveBefore(siblingNode);
|
|
2603
|
+
this[INTERNAL_SYMBOL].commitIfAuto();
|
|
2168
2604
|
}
|
|
2169
2605
|
/**
|
|
2170
2606
|
* Get the index of this node among its siblings.
|
|
2171
2607
|
*/
|
|
2172
2608
|
index() {
|
|
2173
|
-
|
|
2609
|
+
const node = this[INTERNAL_SYMBOL].getNode();
|
|
2610
|
+
return node.index();
|
|
2174
2611
|
}
|
|
2175
2612
|
/**
|
|
2176
2613
|
* Get the fractional index string for ordering.
|
|
2177
2614
|
*/
|
|
2178
2615
|
fractionalIndex() {
|
|
2179
|
-
|
|
2616
|
+
const node = this[INTERNAL_SYMBOL].getNode();
|
|
2617
|
+
return node.fractionalIndex();
|
|
2180
2618
|
}
|
|
2181
2619
|
/**
|
|
2182
2620
|
* Check if this node has been deleted.
|
|
2183
2621
|
*/
|
|
2184
2622
|
isDeleted() {
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
/**
|
|
2188
|
-
* Absorb plain values from the data StructRef.
|
|
2189
|
-
*/
|
|
2190
|
-
absorbPlainValues() {
|
|
2191
|
-
if (this._dataRef) {
|
|
2192
|
-
this._dataRef.absorbPlainValues();
|
|
2193
|
-
}
|
|
2623
|
+
const node = this[INTERNAL_SYMBOL].getNode();
|
|
2624
|
+
return node.isDeleted();
|
|
2194
2625
|
}
|
|
2195
2626
|
/**
|
|
2196
2627
|
* Serialize this node and its descendants to JSON.
|
|
@@ -2206,78 +2637,123 @@ var TreeNodeRef = class {
|
|
|
2206
2637
|
children: children.map((child) => child.toJSON())
|
|
2207
2638
|
};
|
|
2208
2639
|
}
|
|
2209
|
-
commitIfAuto() {
|
|
2210
|
-
if (this._autoCommit && this._getDoc) {
|
|
2211
|
-
this._getDoc().commit();
|
|
2212
|
-
}
|
|
2213
|
-
}
|
|
2214
2640
|
};
|
|
2215
2641
|
|
|
2216
|
-
// src/typed-refs/tree.ts
|
|
2217
|
-
var
|
|
2642
|
+
// src/typed-refs/tree-ref-internals.ts
|
|
2643
|
+
var TreeRefInternals = class extends BaseRefInternals {
|
|
2218
2644
|
nodeCache = /* @__PURE__ */ new Map();
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
this.
|
|
2645
|
+
treeRef = null;
|
|
2646
|
+
/** Set the parent TreeRef (needed for creating node refs) */
|
|
2647
|
+
setTreeRef(treeRef) {
|
|
2648
|
+
this.treeRef = treeRef;
|
|
2223
2649
|
}
|
|
2224
|
-
|
|
2225
|
-
|
|
2650
|
+
/** Get the data shape for tree nodes */
|
|
2651
|
+
getDataShape() {
|
|
2652
|
+
const shape = this.getShape();
|
|
2653
|
+
return shape.shape;
|
|
2226
2654
|
}
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2655
|
+
/** Get or create a node ref for a LoroTreeNode */
|
|
2656
|
+
getOrCreateNodeRef(node) {
|
|
2657
|
+
const id = node.id;
|
|
2658
|
+
if (!this.treeRef) {
|
|
2659
|
+
throw new Error("treeRef required");
|
|
2230
2660
|
}
|
|
2231
|
-
|
|
2661
|
+
let nodeRef = this.nodeCache.get(id);
|
|
2662
|
+
if (!nodeRef) {
|
|
2663
|
+
nodeRef = new TreeNodeRef({
|
|
2664
|
+
node,
|
|
2665
|
+
dataShape: this.getDataShape(),
|
|
2666
|
+
treeRef: this.treeRef,
|
|
2667
|
+
autoCommit: this.getAutoCommit(),
|
|
2668
|
+
batchedMutation: this.getBatchedMutation(),
|
|
2669
|
+
getDoc: () => this.getDoc()
|
|
2670
|
+
});
|
|
2671
|
+
this.nodeCache.set(id, nodeRef);
|
|
2672
|
+
}
|
|
2673
|
+
return nodeRef;
|
|
2232
2674
|
}
|
|
2233
|
-
|
|
2234
|
-
|
|
2675
|
+
/** Get a node by its ID */
|
|
2676
|
+
getNodeByID(id) {
|
|
2677
|
+
const cached = this.nodeCache.get(id);
|
|
2678
|
+
if (cached) return cached;
|
|
2679
|
+
const container = this.getContainer();
|
|
2680
|
+
if (!container.has(id)) return void 0;
|
|
2681
|
+
const nodes = container.nodes();
|
|
2682
|
+
const node = nodes.find((n) => n.id === id);
|
|
2683
|
+
if (!node) return void 0;
|
|
2684
|
+
return this.getOrCreateNodeRef(node);
|
|
2685
|
+
}
|
|
2686
|
+
/** Delete a node from the tree */
|
|
2687
|
+
delete(target) {
|
|
2688
|
+
const id = typeof target === "string" ? target : target.id;
|
|
2689
|
+
const container = this.getContainer();
|
|
2690
|
+
container.delete(id);
|
|
2691
|
+
this.nodeCache.delete(id);
|
|
2692
|
+
this.commitIfAuto();
|
|
2693
|
+
}
|
|
2694
|
+
/** Absorb mutated plain values back into Loro containers */
|
|
2695
|
+
absorbPlainValues() {
|
|
2696
|
+
for (const nodeRef of this.nodeCache.values()) {
|
|
2697
|
+
nodeRef[INTERNAL_SYMBOL].absorbPlainValues();
|
|
2698
|
+
}
|
|
2699
|
+
}
|
|
2700
|
+
/** Create the loro namespace for tree */
|
|
2701
|
+
createLoroNamespace() {
|
|
2702
|
+
const self = this;
|
|
2703
|
+
return {
|
|
2704
|
+
get doc() {
|
|
2705
|
+
return self.getDoc();
|
|
2706
|
+
},
|
|
2707
|
+
get container() {
|
|
2708
|
+
return self.getContainer();
|
|
2709
|
+
},
|
|
2710
|
+
subscribe(callback) {
|
|
2711
|
+
return self.getContainer().subscribe(callback);
|
|
2712
|
+
}
|
|
2713
|
+
};
|
|
2235
2714
|
}
|
|
2236
|
-
|
|
2237
|
-
|
|
2715
|
+
};
|
|
2716
|
+
|
|
2717
|
+
// src/typed-refs/tree-ref.ts
|
|
2718
|
+
var TreeRef = class extends TypedRef {
|
|
2719
|
+
[INTERNAL_SYMBOL];
|
|
2720
|
+
constructor(params) {
|
|
2721
|
+
super();
|
|
2722
|
+
this[INTERNAL_SYMBOL] = new TreeRefInternals(params);
|
|
2723
|
+
this[INTERNAL_SYMBOL].setTreeRef(this);
|
|
2238
2724
|
}
|
|
2239
|
-
|
|
2240
|
-
|
|
2725
|
+
/**
|
|
2726
|
+
* Get the data shape for tree nodes.
|
|
2727
|
+
*/
|
|
2728
|
+
get dataShape() {
|
|
2729
|
+
return this[INTERNAL_SYMBOL].getDataShape();
|
|
2241
2730
|
}
|
|
2242
|
-
|
|
2243
|
-
|
|
2731
|
+
/**
|
|
2732
|
+
* Get or create a node ref for a LoroTreeNode.
|
|
2733
|
+
*/
|
|
2734
|
+
getOrCreateNodeRef(node) {
|
|
2735
|
+
return this[INTERNAL_SYMBOL].getOrCreateNodeRef(node);
|
|
2244
2736
|
}
|
|
2245
2737
|
/**
|
|
2246
|
-
*
|
|
2738
|
+
* Get a node by its ID.
|
|
2247
2739
|
*/
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
this.doc.commit();
|
|
2251
|
-
}
|
|
2740
|
+
getNodeByID(id) {
|
|
2741
|
+
return this[INTERNAL_SYMBOL].getNodeByID(id);
|
|
2252
2742
|
}
|
|
2253
2743
|
/**
|
|
2254
|
-
*
|
|
2255
|
-
* Called before committing changes to ensure all pending values are written.
|
|
2744
|
+
* Delete a node from the tree.
|
|
2256
2745
|
*/
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
nodeRef.absorbPlainValues();
|
|
2260
|
-
}
|
|
2746
|
+
delete(target) {
|
|
2747
|
+
this[INTERNAL_SYMBOL].delete(target);
|
|
2261
2748
|
}
|
|
2262
2749
|
/**
|
|
2263
|
-
*
|
|
2264
|
-
*
|
|
2750
|
+
* Serialize the tree to a nested JSON structure.
|
|
2751
|
+
* Each node includes its data and children recursively.
|
|
2265
2752
|
*/
|
|
2266
|
-
|
|
2267
|
-
const
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
nodeRef = new TreeNodeRef({
|
|
2271
|
-
node,
|
|
2272
|
-
dataShape: this.dataShape,
|
|
2273
|
-
treeRef: this,
|
|
2274
|
-
autoCommit: this.autoCommit,
|
|
2275
|
-
batchedMutation: this.batchedMutation,
|
|
2276
|
-
getDoc: this._params.getDoc
|
|
2277
|
-
});
|
|
2278
|
-
this.nodeCache.set(id, nodeRef);
|
|
2279
|
-
}
|
|
2280
|
-
return nodeRef;
|
|
2753
|
+
toJSON() {
|
|
2754
|
+
const container = this[INTERNAL_SYMBOL].getContainer();
|
|
2755
|
+
const nativeJson = container.toJSON();
|
|
2756
|
+
return this.transformNativeJson(nativeJson);
|
|
2281
2757
|
}
|
|
2282
2758
|
/**
|
|
2283
2759
|
* Create a new root node with optional initial data.
|
|
@@ -2286,7 +2762,8 @@ var TreeRef = class {
|
|
|
2286
2762
|
* @returns The created TreeNodeRef
|
|
2287
2763
|
*/
|
|
2288
2764
|
createNode(initialData) {
|
|
2289
|
-
const
|
|
2765
|
+
const container = this[INTERNAL_SYMBOL].getContainer();
|
|
2766
|
+
const loroNode = container.createNode();
|
|
2290
2767
|
const nodeRef = this.getOrCreateNodeRef(loroNode);
|
|
2291
2768
|
if (initialData) {
|
|
2292
2769
|
for (const [key, value] of Object.entries(initialData)) {
|
|
@@ -2294,7 +2771,7 @@ var TreeRef = class {
|
|
|
2294
2771
|
nodeRef.data[key] = value;
|
|
2295
2772
|
}
|
|
2296
2773
|
}
|
|
2297
|
-
this.commitIfAuto();
|
|
2774
|
+
this[INTERNAL_SYMBOL].commitIfAuto();
|
|
2298
2775
|
return nodeRef;
|
|
2299
2776
|
}
|
|
2300
2777
|
/**
|
|
@@ -2302,47 +2779,23 @@ var TreeRef = class {
|
|
|
2302
2779
|
* Returns nodes in their fractional index order.
|
|
2303
2780
|
*/
|
|
2304
2781
|
roots() {
|
|
2305
|
-
|
|
2782
|
+
const container = this[INTERNAL_SYMBOL].getContainer();
|
|
2783
|
+
return container.roots().map((node) => this.getOrCreateNodeRef(node));
|
|
2306
2784
|
}
|
|
2307
2785
|
/**
|
|
2308
2786
|
* Get all nodes in the tree (unordered).
|
|
2309
2787
|
* Includes all nodes, not just roots.
|
|
2310
2788
|
*/
|
|
2311
2789
|
nodes() {
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
/**
|
|
2315
|
-
* Get a node by its TreeID.
|
|
2316
|
-
*
|
|
2317
|
-
* @param id - The TreeID of the node to find
|
|
2318
|
-
* @returns The TreeNodeRef if found, undefined otherwise
|
|
2319
|
-
*/
|
|
2320
|
-
getNodeByID(id) {
|
|
2321
|
-
const cached = this.nodeCache.get(id);
|
|
2322
|
-
if (cached) return cached;
|
|
2323
|
-
if (!this.container.has(id)) return void 0;
|
|
2324
|
-
const nodes = this.container.nodes();
|
|
2325
|
-
const node = nodes.find((n) => n.id === id);
|
|
2326
|
-
if (!node) return void 0;
|
|
2327
|
-
return this.getOrCreateNodeRef(node);
|
|
2790
|
+
const container = this[INTERNAL_SYMBOL].getContainer();
|
|
2791
|
+
return container.nodes().map((node) => this.getOrCreateNodeRef(node));
|
|
2328
2792
|
}
|
|
2329
2793
|
/**
|
|
2330
2794
|
* Check if a node with the given ID exists in the tree.
|
|
2331
2795
|
*/
|
|
2332
2796
|
has(id) {
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
/**
|
|
2336
|
-
* Delete a node and all its descendants.
|
|
2337
|
-
* Also removes the node from the cache.
|
|
2338
|
-
*
|
|
2339
|
-
* @param target - The TreeID or TreeNodeRef to delete
|
|
2340
|
-
*/
|
|
2341
|
-
delete(target) {
|
|
2342
|
-
const id = typeof target === "string" ? target : target.id;
|
|
2343
|
-
this.container.delete(id);
|
|
2344
|
-
this.nodeCache.delete(id);
|
|
2345
|
-
this.commitIfAuto();
|
|
2797
|
+
const container = this[INTERNAL_SYMBOL].getContainer();
|
|
2798
|
+
return container.has(id);
|
|
2346
2799
|
}
|
|
2347
2800
|
/**
|
|
2348
2801
|
* Enable fractional index generation for ordering.
|
|
@@ -2350,15 +2803,8 @@ var TreeRef = class {
|
|
|
2350
2803
|
* @param jitter - Optional jitter value to avoid conflicts (0 = no jitter)
|
|
2351
2804
|
*/
|
|
2352
2805
|
enableFractionalIndex(jitter = 0) {
|
|
2353
|
-
this.
|
|
2354
|
-
|
|
2355
|
-
/**
|
|
2356
|
-
* Serialize the tree to a nested JSON structure.
|
|
2357
|
-
* Each node includes its data and children recursively.
|
|
2358
|
-
*/
|
|
2359
|
-
toJSON() {
|
|
2360
|
-
const nativeJson = this.container.toJSON();
|
|
2361
|
-
return this.transformNativeJson(nativeJson);
|
|
2806
|
+
const container = this[INTERNAL_SYMBOL].getContainer();
|
|
2807
|
+
container.enableFractionalIndex(jitter);
|
|
2362
2808
|
}
|
|
2363
2809
|
/**
|
|
2364
2810
|
* Transform Loro's native JSON format to our typed format.
|
|
@@ -2393,7 +2839,8 @@ var TreeRef = class {
|
|
|
2393
2839
|
}
|
|
2394
2840
|
}
|
|
2395
2841
|
};
|
|
2396
|
-
const
|
|
2842
|
+
const container = this[INTERNAL_SYMBOL].getContainer();
|
|
2843
|
+
const nativeJson = container.toJSON();
|
|
2397
2844
|
flattenNodes(nativeJson);
|
|
2398
2845
|
return result;
|
|
2399
2846
|
}
|
|
@@ -2414,14 +2861,14 @@ var containerConstructor = {
|
|
|
2414
2861
|
function hasContainerConstructor(type) {
|
|
2415
2862
|
return type in containerConstructor;
|
|
2416
2863
|
}
|
|
2417
|
-
function
|
|
2418
|
-
return value !== null && typeof value === "object" &&
|
|
2864
|
+
function hasInternalSymbol(value) {
|
|
2865
|
+
return value !== null && typeof value === "object" && INTERNAL_SYMBOL in value;
|
|
2419
2866
|
}
|
|
2420
2867
|
function absorbCachedPlainValues(cache, getContainer) {
|
|
2421
2868
|
let container;
|
|
2422
2869
|
for (const [key, ref] of cache.entries()) {
|
|
2423
|
-
if (
|
|
2424
|
-
ref.absorbPlainValues();
|
|
2870
|
+
if (hasInternalSymbol(ref)) {
|
|
2871
|
+
ref[INTERNAL_SYMBOL].absorbPlainValues();
|
|
2425
2872
|
} else {
|
|
2426
2873
|
if (!container) container = getContainer();
|
|
2427
2874
|
container.set(key, ref);
|
|
@@ -2450,7 +2897,9 @@ function createContainerTypedRef(params) {
|
|
|
2450
2897
|
listProxyHandler
|
|
2451
2898
|
);
|
|
2452
2899
|
case "struct":
|
|
2453
|
-
return
|
|
2900
|
+
return createStructRef(
|
|
2901
|
+
params
|
|
2902
|
+
);
|
|
2454
2903
|
case "movableList":
|
|
2455
2904
|
return new Proxy(
|
|
2456
2905
|
new MovableListRef(params),
|
|
@@ -2469,7 +2918,6 @@ function createContainerTypedRef(params) {
|
|
|
2469
2918
|
shape: treeShape,
|
|
2470
2919
|
placeholder: params.placeholder,
|
|
2471
2920
|
getContainer: params.getContainer,
|
|
2472
|
-
readonly: params.readonly,
|
|
2473
2921
|
autoCommit: params.autoCommit,
|
|
2474
2922
|
getDoc: params.getDoc
|
|
2475
2923
|
});
|
|
@@ -2481,7 +2929,8 @@ function createContainerTypedRef(params) {
|
|
|
2481
2929
|
}
|
|
2482
2930
|
}
|
|
2483
2931
|
function assignPlainValueToTypedRef(ref, value) {
|
|
2484
|
-
const
|
|
2932
|
+
const shape = ref[INTERNAL_SYMBOL]?.getShape?.() ?? ref.shape;
|
|
2933
|
+
const shapeType = shape?._type;
|
|
2485
2934
|
if (shapeType === "struct" || shapeType === "record") {
|
|
2486
2935
|
for (const k in value) {
|
|
2487
2936
|
;
|
|
@@ -2527,7 +2976,7 @@ function assignPlainValueToTypedRef(ref, value) {
|
|
|
2527
2976
|
return false;
|
|
2528
2977
|
}
|
|
2529
2978
|
|
|
2530
|
-
// src/typed-refs/doc.ts
|
|
2979
|
+
// src/typed-refs/doc-ref-internals.ts
|
|
2531
2980
|
var containerGetter = {
|
|
2532
2981
|
counter: "getCounter",
|
|
2533
2982
|
list: "getList",
|
|
@@ -2538,23 +2987,22 @@ var containerGetter = {
|
|
|
2538
2987
|
text: "getText",
|
|
2539
2988
|
tree: "getTree"
|
|
2540
2989
|
};
|
|
2541
|
-
var
|
|
2542
|
-
_doc;
|
|
2990
|
+
var DocRefInternals = class extends BaseRefInternals {
|
|
2543
2991
|
propertyCache = /* @__PURE__ */ new Map();
|
|
2992
|
+
doc;
|
|
2544
2993
|
requiredPlaceholder;
|
|
2545
|
-
constructor(
|
|
2994
|
+
constructor(params) {
|
|
2546
2995
|
super({
|
|
2547
|
-
...
|
|
2996
|
+
...params,
|
|
2548
2997
|
getContainer: () => {
|
|
2549
2998
|
throw new Error("can't get container on DocRef");
|
|
2550
2999
|
},
|
|
2551
|
-
getDoc: () =>
|
|
3000
|
+
getDoc: () => params.doc
|
|
2552
3001
|
});
|
|
2553
|
-
|
|
2554
|
-
this.
|
|
2555
|
-
this.requiredPlaceholder = _params.placeholder;
|
|
2556
|
-
this.createLazyProperties();
|
|
3002
|
+
this.doc = params.doc;
|
|
3003
|
+
this.requiredPlaceholder = params.placeholder;
|
|
2557
3004
|
}
|
|
3005
|
+
/** Get typed ref params for creating child refs at a key */
|
|
2558
3006
|
getTypedRefParams(key, shape) {
|
|
2559
3007
|
if (shape._type === "any") {
|
|
2560
3008
|
throw new Error(
|
|
@@ -2562,16 +3010,17 @@ var DocRef = class extends TypedRef {
|
|
|
2562
3010
|
);
|
|
2563
3011
|
}
|
|
2564
3012
|
const getterName = containerGetter[shape._type];
|
|
2565
|
-
const getter = this.
|
|
3013
|
+
const getter = this.doc[getterName].bind(this.doc);
|
|
2566
3014
|
return {
|
|
2567
3015
|
shape,
|
|
2568
3016
|
placeholder: this.requiredPlaceholder[key],
|
|
2569
3017
|
getContainer: () => getter(key),
|
|
2570
|
-
autoCommit: this.
|
|
2571
|
-
batchedMutation: this.
|
|
2572
|
-
getDoc: () => this.
|
|
3018
|
+
autoCommit: this.getAutoCommit(),
|
|
3019
|
+
batchedMutation: this.getBatchedMutation(),
|
|
3020
|
+
getDoc: () => this.doc
|
|
2573
3021
|
};
|
|
2574
3022
|
}
|
|
3023
|
+
/** Get or create a typed ref for a key */
|
|
2575
3024
|
getOrCreateTypedRef(key, shape) {
|
|
2576
3025
|
let ref = this.propertyCache.get(key);
|
|
2577
3026
|
if (!ref) {
|
|
@@ -2580,26 +3029,40 @@ var DocRef = class extends TypedRef {
|
|
|
2580
3029
|
}
|
|
2581
3030
|
return ref;
|
|
2582
3031
|
}
|
|
3032
|
+
/** Absorb mutated plain values back into Loro containers */
|
|
3033
|
+
absorbPlainValues() {
|
|
3034
|
+
for (const [, ref] of this.propertyCache.entries()) {
|
|
3035
|
+
ref[INTERNAL_SYMBOL].absorbPlainValues();
|
|
3036
|
+
}
|
|
3037
|
+
}
|
|
3038
|
+
};
|
|
3039
|
+
|
|
3040
|
+
// src/typed-refs/doc-ref.ts
|
|
3041
|
+
var DocRef = class extends TypedRef {
|
|
3042
|
+
[INTERNAL_SYMBOL];
|
|
3043
|
+
constructor(params) {
|
|
3044
|
+
super();
|
|
3045
|
+
if (!params.placeholder) throw new Error("placeholder required");
|
|
3046
|
+
this[INTERNAL_SYMBOL] = new DocRefInternals(params);
|
|
3047
|
+
this.createLazyProperties();
|
|
3048
|
+
}
|
|
2583
3049
|
createLazyProperties() {
|
|
2584
|
-
|
|
2585
|
-
|
|
3050
|
+
const shape = this[INTERNAL_SYMBOL].getShape();
|
|
3051
|
+
for (const key in shape.shapes) {
|
|
3052
|
+
const containerShape = shape.shapes[key];
|
|
2586
3053
|
Object.defineProperty(this, key, {
|
|
2587
|
-
get: () => this.getOrCreateTypedRef(key,
|
|
3054
|
+
get: () => this[INTERNAL_SYMBOL].getOrCreateTypedRef(key, containerShape),
|
|
2588
3055
|
enumerable: true
|
|
2589
3056
|
});
|
|
2590
3057
|
}
|
|
2591
3058
|
}
|
|
2592
3059
|
toJSON() {
|
|
3060
|
+
const shape = this[INTERNAL_SYMBOL].getShape();
|
|
2593
3061
|
return serializeRefToJSON(
|
|
2594
3062
|
this,
|
|
2595
|
-
Object.keys(
|
|
3063
|
+
Object.keys(shape.shapes)
|
|
2596
3064
|
);
|
|
2597
3065
|
}
|
|
2598
|
-
absorbPlainValues() {
|
|
2599
|
-
for (const [, ref] of this.propertyCache.entries()) {
|
|
2600
|
-
ref.absorbPlainValues();
|
|
2601
|
-
}
|
|
2602
|
-
}
|
|
2603
3066
|
};
|
|
2604
3067
|
|
|
2605
3068
|
// src/validation.ts
|
|
@@ -2831,68 +3294,11 @@ function validatePlaceholder(placeholder, schema) {
|
|
|
2831
3294
|
}
|
|
2832
3295
|
|
|
2833
3296
|
// src/typed-doc.ts
|
|
2834
|
-
var TypedDocMeta = class {
|
|
2835
|
-
constructor(internal) {
|
|
2836
|
-
this.internal = internal;
|
|
2837
|
-
}
|
|
2838
|
-
/**
|
|
2839
|
-
* The primary method of mutating typed documents.
|
|
2840
|
-
* Batches multiple mutations into a single transaction.
|
|
2841
|
-
* All changes commit together at the end.
|
|
2842
|
-
*
|
|
2843
|
-
* Use this for:
|
|
2844
|
-
* - Find-and-mutate operations (required due to JS limitations)
|
|
2845
|
-
* - Performance (fewer commits)
|
|
2846
|
-
* - Atomic undo (all changes = one undo step)
|
|
2847
|
-
*
|
|
2848
|
-
* Returns the doc for chaining.
|
|
2849
|
-
*/
|
|
2850
|
-
change(fn) {
|
|
2851
|
-
this.internal.change(fn);
|
|
2852
|
-
return this.internal.proxy;
|
|
2853
|
-
}
|
|
2854
|
-
/**
|
|
2855
|
-
* Returns the full plain JavaScript object representation of the document.
|
|
2856
|
-
* This is an expensive O(N) operation that serializes the entire document.
|
|
2857
|
-
*/
|
|
2858
|
-
toJSON() {
|
|
2859
|
-
return this.internal.toJSON();
|
|
2860
|
-
}
|
|
2861
|
-
/**
|
|
2862
|
-
* Apply JSON Patch operations to the document
|
|
2863
|
-
*
|
|
2864
|
-
* @param patch - Array of JSON Patch operations (RFC 6902)
|
|
2865
|
-
* @param pathPrefix - Optional path prefix for scoped operations
|
|
2866
|
-
* @returns Updated document value
|
|
2867
|
-
*/
|
|
2868
|
-
applyPatch(patch, pathPrefix) {
|
|
2869
|
-
this.internal.applyPatch(patch, pathPrefix);
|
|
2870
|
-
return this.internal.proxy;
|
|
2871
|
-
}
|
|
2872
|
-
/**
|
|
2873
|
-
* Access the underlying LoroDoc for advanced operations.
|
|
2874
|
-
*/
|
|
2875
|
-
get loroDoc() {
|
|
2876
|
-
return this.internal.loroDoc;
|
|
2877
|
-
}
|
|
2878
|
-
/**
|
|
2879
|
-
* Access the document schema shape.
|
|
2880
|
-
*/
|
|
2881
|
-
get docShape() {
|
|
2882
|
-
return this.internal.docShape;
|
|
2883
|
-
}
|
|
2884
|
-
/**
|
|
2885
|
-
* Get raw CRDT value without placeholder overlay.
|
|
2886
|
-
*/
|
|
2887
|
-
get rawValue() {
|
|
2888
|
-
return this.internal.rawValue;
|
|
2889
|
-
}
|
|
2890
|
-
};
|
|
2891
3297
|
var TypedDocInternal = class {
|
|
2892
3298
|
shape;
|
|
2893
3299
|
placeholder;
|
|
2894
3300
|
doc;
|
|
2895
|
-
|
|
3301
|
+
valueRef = null;
|
|
2896
3302
|
// Reference to the proxy for returning from change()
|
|
2897
3303
|
proxy = null;
|
|
2898
3304
|
constructor(shape, doc = new LoroDoc()) {
|
|
@@ -2902,15 +3308,15 @@ var TypedDocInternal = class {
|
|
|
2902
3308
|
validatePlaceholder(this.placeholder, this.shape);
|
|
2903
3309
|
}
|
|
2904
3310
|
get value() {
|
|
2905
|
-
if (!this.
|
|
2906
|
-
this.
|
|
3311
|
+
if (!this.valueRef) {
|
|
3312
|
+
this.valueRef = new DocRef({
|
|
2907
3313
|
shape: this.shape,
|
|
2908
3314
|
placeholder: this.placeholder,
|
|
2909
3315
|
doc: this.doc,
|
|
2910
3316
|
autoCommit: true
|
|
2911
3317
|
});
|
|
2912
3318
|
}
|
|
2913
|
-
return this.
|
|
3319
|
+
return this.valueRef;
|
|
2914
3320
|
}
|
|
2915
3321
|
toJSON() {
|
|
2916
3322
|
const crdtValue = this.doc.toJSON();
|
|
@@ -2930,9 +3336,9 @@ var TypedDocInternal = class {
|
|
|
2930
3336
|
// Enable value shape caching for find-and-mutate patterns
|
|
2931
3337
|
});
|
|
2932
3338
|
fn(draft);
|
|
2933
|
-
draft.absorbPlainValues();
|
|
3339
|
+
draft[INTERNAL_SYMBOL].absorbPlainValues();
|
|
2934
3340
|
this.doc.commit();
|
|
2935
|
-
this.
|
|
3341
|
+
this.valueRef = null;
|
|
2936
3342
|
}
|
|
2937
3343
|
applyPatch(patch, pathPrefix) {
|
|
2938
3344
|
this.change((draft) => {
|
|
@@ -2956,11 +3362,37 @@ var TypedDocInternal = class {
|
|
|
2956
3362
|
};
|
|
2957
3363
|
function createTypedDoc(shape, existingDoc) {
|
|
2958
3364
|
const internal = new TypedDocInternal(shape, existingDoc || new LoroDoc());
|
|
2959
|
-
const
|
|
3365
|
+
const loroNamespace = {
|
|
3366
|
+
get doc() {
|
|
3367
|
+
return internal.loroDoc;
|
|
3368
|
+
},
|
|
3369
|
+
get container() {
|
|
3370
|
+
return internal.loroDoc;
|
|
3371
|
+
},
|
|
3372
|
+
subscribe(callback) {
|
|
3373
|
+
return internal.loroDoc.subscribe(callback);
|
|
3374
|
+
},
|
|
3375
|
+
applyPatch(patch, pathPrefix) {
|
|
3376
|
+
internal.applyPatch(patch, pathPrefix);
|
|
3377
|
+
},
|
|
3378
|
+
get docShape() {
|
|
3379
|
+
return internal.docShape;
|
|
3380
|
+
},
|
|
3381
|
+
get rawValue() {
|
|
3382
|
+
return internal.rawValue;
|
|
3383
|
+
}
|
|
3384
|
+
};
|
|
3385
|
+
const changeFunction = (fn) => {
|
|
3386
|
+
internal.change(fn);
|
|
3387
|
+
return proxy;
|
|
3388
|
+
};
|
|
2960
3389
|
const proxy = new Proxy(internal.value, {
|
|
2961
3390
|
get(target, prop, receiver) {
|
|
2962
|
-
if (prop ===
|
|
2963
|
-
return
|
|
3391
|
+
if (prop === LORO_SYMBOL) {
|
|
3392
|
+
return loroNamespace;
|
|
3393
|
+
}
|
|
3394
|
+
if (prop === "change") {
|
|
3395
|
+
return changeFunction;
|
|
2964
3396
|
}
|
|
2965
3397
|
if (prop === "toJSON") {
|
|
2966
3398
|
return () => internal.toJSON();
|
|
@@ -2968,26 +3400,33 @@ function createTypedDoc(shape, existingDoc) {
|
|
|
2968
3400
|
return Reflect.get(target, prop, receiver);
|
|
2969
3401
|
},
|
|
2970
3402
|
set(target, prop, value, receiver) {
|
|
2971
|
-
if (prop === "
|
|
3403
|
+
if (prop === LORO_SYMBOL || prop === "change") {
|
|
2972
3404
|
return false;
|
|
2973
3405
|
}
|
|
2974
3406
|
return Reflect.set(target, prop, value, receiver);
|
|
2975
3407
|
},
|
|
2976
3408
|
// Support 'in' operator
|
|
2977
3409
|
has(target, prop) {
|
|
2978
|
-
if (prop === "
|
|
3410
|
+
if (prop === LORO_SYMBOL || prop === "change") return true;
|
|
2979
3411
|
return Reflect.has(target, prop);
|
|
2980
3412
|
},
|
|
2981
|
-
// Support Object.keys() - don't include
|
|
3413
|
+
// Support Object.keys() - don't include change or LORO_SYMBOL in enumeration
|
|
2982
3414
|
ownKeys(target) {
|
|
2983
3415
|
return Reflect.ownKeys(target);
|
|
2984
3416
|
},
|
|
2985
3417
|
getOwnPropertyDescriptor(target, prop) {
|
|
2986
|
-
if (prop === "
|
|
3418
|
+
if (prop === "change") {
|
|
3419
|
+
return {
|
|
3420
|
+
configurable: true,
|
|
3421
|
+
enumerable: false,
|
|
3422
|
+
value: changeFunction
|
|
3423
|
+
};
|
|
3424
|
+
}
|
|
3425
|
+
if (prop === LORO_SYMBOL) {
|
|
2987
3426
|
return {
|
|
2988
3427
|
configurable: true,
|
|
2989
3428
|
enumerable: false,
|
|
2990
|
-
value:
|
|
3429
|
+
value: loroNamespace
|
|
2991
3430
|
};
|
|
2992
3431
|
}
|
|
2993
3432
|
return Reflect.getOwnPropertyDescriptor(target, prop);
|
|
@@ -2997,6 +3436,7 @@ function createTypedDoc(shape, existingDoc) {
|
|
|
2997
3436
|
return proxy;
|
|
2998
3437
|
}
|
|
2999
3438
|
export {
|
|
3439
|
+
LORO_SYMBOL,
|
|
3000
3440
|
Shape,
|
|
3001
3441
|
change,
|
|
3002
3442
|
compileToJsonPath,
|
|
@@ -3007,8 +3447,10 @@ export {
|
|
|
3007
3447
|
deriveShapePlaceholder,
|
|
3008
3448
|
evaluatePath,
|
|
3009
3449
|
evaluatePathOnValue,
|
|
3450
|
+
getLoroContainer,
|
|
3010
3451
|
getLoroDoc,
|
|
3011
3452
|
hasWildcard,
|
|
3453
|
+
loro,
|
|
3012
3454
|
mergeValue,
|
|
3013
3455
|
overlayPlaceholder,
|
|
3014
3456
|
validatePlaceholder
|