document-model 1.7.0 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser/cjs/document-model.js +2 -2
- package/dist/browser/cjs/document.js +2 -2
- package/dist/browser/cjs/index.js +2 -2
- package/dist/browser/cjs/internal/{index-DTRXQ2Nf.js → index-UG6TQ_ad.js} +2 -2
- package/dist/browser/cjs/internal/{index-DTRXQ2Nf.js.map → index-UG6TQ_ad.js.map} +1 -1
- package/dist/browser/cjs/internal/{index-BllCzBc9.js → index-jRdLtWv9.js} +3 -3
- package/dist/browser/cjs/internal/index-jRdLtWv9.js.map +1 -0
- package/dist/browser/cjs/internal/{object-Bf9_woMQ.js → object-CCclzskm.js} +480 -2109
- package/dist/browser/cjs/internal/object-CCclzskm.js.map +1 -0
- package/dist/browser/es/document-model.js +2 -2
- package/dist/browser/es/document.js +2 -2
- package/dist/browser/es/index.js +2 -2
- package/dist/browser/es/internal/{index-BAvDobTr.js → index-CDwXQBxG.js} +2 -2
- package/dist/browser/es/internal/{index-BAvDobTr.js.map → index-CDwXQBxG.js.map} +1 -1
- package/dist/browser/es/internal/{index-Db40bdYP.js → index-v4H3kbAF.js} +3 -3
- package/dist/browser/es/internal/index-v4H3kbAF.js.map +1 -0
- package/dist/browser/es/internal/{object-CY74acQg.js → object-CU5T1DpX.js} +491 -2120
- package/dist/browser/es/internal/object-CU5T1DpX.js.map +1 -0
- package/dist/browser/src/document/reducer.d.ts +4 -1
- package/dist/browser/src/document/types.d.ts +1 -0
- package/dist/browser/src/document/utils/base.d.ts +2 -2
- package/dist/browser/src/document/utils/document-helpers.d.ts +10 -0
- package/dist/browser/src/document-model/gen/schema/zod.d.ts +8 -8
- package/dist/node/cjs/document-model.js +2 -2
- package/dist/node/cjs/document.js +2 -2
- package/dist/node/cjs/index.js +2 -2
- package/dist/node/cjs/internal/{index-kI4cPPpE.js → index-5qN282Jw.js} +3 -3
- package/dist/node/cjs/internal/index-5qN282Jw.js.map +1 -0
- package/dist/node/cjs/internal/{index-aABa-Hb0.js → index-Bm-pIfaz.js} +2 -2
- package/dist/node/cjs/internal/{index-aABa-Hb0.js.map → index-Bm-pIfaz.js.map} +1 -1
- package/dist/node/cjs/internal/{object-BMm0OLWL.js → object-BMOaYPkd.js} +247 -199
- package/dist/node/cjs/internal/object-BMOaYPkd.js.map +1 -0
- package/dist/node/es/document-model.js +2 -2
- package/dist/node/es/document.js +2 -2
- package/dist/node/es/index.js +2 -2
- package/dist/node/es/internal/{index-B0WPutmO.js → index-CAjAt1Xx.js} +2 -2
- package/dist/node/es/internal/{index-B0WPutmO.js.map → index-CAjAt1Xx.js.map} +1 -1
- package/dist/node/es/internal/{index-MkEgGMJR.js → index-CVuLZAmf.js} +3 -3
- package/dist/node/es/internal/index-CVuLZAmf.js.map +1 -0
- package/dist/node/es/internal/{object-VZ_AS47_.js → object-COSf2HUT.js} +258 -210
- package/dist/node/es/internal/object-COSf2HUT.js.map +1 -0
- package/dist/node/src/document/reducer.d.ts +4 -1
- package/dist/node/src/document/types.d.ts +1 -0
- package/dist/node/src/document/utils/base.d.ts +2 -2
- package/dist/node/src/document/utils/document-helpers.d.ts +10 -0
- package/dist/node/src/document-model/gen/schema/zod.d.ts +8 -8
- package/package.json +6 -4
- package/dist/browser/cjs/internal/index-BllCzBc9.js.map +0 -1
- package/dist/browser/cjs/internal/object-Bf9_woMQ.js.map +0 -1
- package/dist/browser/es/internal/index-Db40bdYP.js.map +0 -1
- package/dist/browser/es/internal/object-CY74acQg.js.map +0 -1
- package/dist/node/cjs/internal/index-kI4cPPpE.js.map +0 -1
- package/dist/node/cjs/internal/object-BMm0OLWL.js.map +0 -1
- package/dist/node/es/internal/index-MkEgGMJR.js.map +0 -1
- package/dist/node/es/internal/object-VZ_AS47_.js.map +0 -1
|
@@ -158,16 +158,16 @@ var safeStableStringify = { exports: {} };
|
|
|
158
158
|
exports2.stringify = stringify;
|
|
159
159
|
exports2.configure = configure;
|
|
160
160
|
module2.exports = stringify;
|
|
161
|
-
const strEscapeSequencesRegExp = /[\u0000-\u001f\u0022\u005c\ud800-\udfff]
|
|
161
|
+
const strEscapeSequencesRegExp = /[\u0000-\u001f\u0022\u005c\ud800-\udfff]/;
|
|
162
162
|
function strEscape(str) {
|
|
163
163
|
if (str.length < 5e3 && !strEscapeSequencesRegExp.test(str)) {
|
|
164
164
|
return `"${str}"`;
|
|
165
165
|
}
|
|
166
166
|
return JSON.stringify(str);
|
|
167
167
|
}
|
|
168
|
-
function
|
|
169
|
-
if (array.length > 200) {
|
|
170
|
-
return array.sort();
|
|
168
|
+
function sort(array, comparator) {
|
|
169
|
+
if (array.length > 200 || comparator) {
|
|
170
|
+
return array.sort(comparator);
|
|
171
171
|
}
|
|
172
172
|
for (let i = 1; i < array.length; i++) {
|
|
173
173
|
const currentValue = array[i];
|
|
@@ -222,6 +222,16 @@ var safeStableStringify = { exports: {} };
|
|
|
222
222
|
}
|
|
223
223
|
return '"[Circular]"';
|
|
224
224
|
}
|
|
225
|
+
function getDeterministicOption(options) {
|
|
226
|
+
let value;
|
|
227
|
+
if (hasOwnProperty.call(options, "deterministic")) {
|
|
228
|
+
value = options.deterministic;
|
|
229
|
+
if (typeof value !== "boolean" && typeof value !== "function") {
|
|
230
|
+
throw new TypeError('The "deterministic" argument must be of type boolean or comparator function');
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
return value === void 0 ? true : value;
|
|
234
|
+
}
|
|
225
235
|
function getBooleanOption(options, key) {
|
|
226
236
|
let value;
|
|
227
237
|
if (hasOwnProperty.call(options, key)) {
|
|
@@ -291,7 +301,8 @@ var safeStableStringify = { exports: {} };
|
|
|
291
301
|
}
|
|
292
302
|
const circularValue = getCircularValueOption(options);
|
|
293
303
|
const bigint = getBooleanOption(options, "bigint");
|
|
294
|
-
const deterministic =
|
|
304
|
+
const deterministic = getDeterministicOption(options);
|
|
305
|
+
const comparator = typeof deterministic === "function" ? deterministic : void 0;
|
|
295
306
|
const maximumDepth = getPositiveIntegerOption(options, "maximumDepth");
|
|
296
307
|
const maximumBreadth = getPositiveIntegerOption(options, "maximumBreadth");
|
|
297
308
|
function stringifyFnReplacer(key, parent, stack, replacer, spacer, indentation) {
|
|
@@ -366,7 +377,7 @@ ${indentation}`;
|
|
|
366
377
|
}
|
|
367
378
|
const maximumPropertiesToStringify = Math.min(keyLength, maximumBreadth);
|
|
368
379
|
if (deterministic && !isTypedArrayWithEntries(value)) {
|
|
369
|
-
keys =
|
|
380
|
+
keys = sort(keys, comparator);
|
|
370
381
|
}
|
|
371
382
|
stack.push(value);
|
|
372
383
|
for (let i = 0; i < maximumPropertiesToStringify; i++) {
|
|
@@ -567,7 +578,7 @@ ${indentation}`;
|
|
|
567
578
|
separator = join;
|
|
568
579
|
}
|
|
569
580
|
if (deterministic) {
|
|
570
|
-
keys =
|
|
581
|
+
keys = sort(keys, comparator);
|
|
571
582
|
}
|
|
572
583
|
stack.push(value);
|
|
573
584
|
for (let i = 0; i < maximumPropertiesToStringify; i++) {
|
|
@@ -626,7 +637,8 @@ ${originalIndentation}`;
|
|
|
626
637
|
return circularValue;
|
|
627
638
|
}
|
|
628
639
|
let res = "";
|
|
629
|
-
|
|
640
|
+
const hasLength = value.length !== void 0;
|
|
641
|
+
if (hasLength && Array.isArray(value)) {
|
|
630
642
|
if (value.length === 0) {
|
|
631
643
|
return "[]";
|
|
632
644
|
}
|
|
@@ -660,14 +672,14 @@ ${originalIndentation}`;
|
|
|
660
672
|
}
|
|
661
673
|
let separator = "";
|
|
662
674
|
let maximumPropertiesToStringify = Math.min(keyLength, maximumBreadth);
|
|
663
|
-
if (isTypedArrayWithEntries(value)) {
|
|
675
|
+
if (hasLength && isTypedArrayWithEntries(value)) {
|
|
664
676
|
res += stringifyTypedArray(value, ",", maximumBreadth);
|
|
665
677
|
keys = keys.slice(value.length);
|
|
666
678
|
maximumPropertiesToStringify -= value.length;
|
|
667
679
|
separator = ",";
|
|
668
680
|
}
|
|
669
681
|
if (deterministic) {
|
|
670
|
-
keys =
|
|
682
|
+
keys = sort(keys, comparator);
|
|
671
683
|
}
|
|
672
684
|
stack.push(value);
|
|
673
685
|
for (let i = 0; i < maximumPropertiesToStringify; i++) {
|
|
@@ -759,168 +771,6 @@ function v4(options, buf, offset) {
|
|
|
759
771
|
rnds[8] = rnds[8] & 63 | 128;
|
|
760
772
|
return unsafeStringify(rnds);
|
|
761
773
|
}
|
|
762
|
-
function setNameOperation(document, name) {
|
|
763
|
-
return { ...document, name };
|
|
764
|
-
}
|
|
765
|
-
function undoOperation(document, action, skip) {
|
|
766
|
-
const { scope, input } = action;
|
|
767
|
-
const defaultResult = {
|
|
768
|
-
document,
|
|
769
|
-
action,
|
|
770
|
-
skip
|
|
771
|
-
};
|
|
772
|
-
return mutative.create(defaultResult, (draft) => {
|
|
773
|
-
if (draft.document.operations[scope].length < 1) {
|
|
774
|
-
throw new Error(
|
|
775
|
-
`Cannot undo: no operations in history for scope "${scope}"`
|
|
776
|
-
);
|
|
777
|
-
}
|
|
778
|
-
if (input < 1) {
|
|
779
|
-
throw new Error(
|
|
780
|
-
`Invalid UNDO action: input value must be greater than 0`
|
|
781
|
-
);
|
|
782
|
-
}
|
|
783
|
-
if (draft.skip > 0) {
|
|
784
|
-
throw new Error(
|
|
785
|
-
`Cannot undo: skip value from reducer cannot be used with UNDO action`
|
|
786
|
-
);
|
|
787
|
-
}
|
|
788
|
-
const lastOperation = draft.document.operations[scope].at(-1);
|
|
789
|
-
const isLatestOpNOOP = lastOperation && lastOperation.type === "NOOP" && lastOperation.skip > 0;
|
|
790
|
-
draft.skip += input;
|
|
791
|
-
if (isLatestOpNOOP) {
|
|
792
|
-
draft.skip += lastOperation.skip;
|
|
793
|
-
const preLastOperation = draft.document.operations[scope][draft.document.operations[scope].length - 2];
|
|
794
|
-
if (preLastOperation && lastOperation.index - preLastOperation.index === 1) {
|
|
795
|
-
draft.document.operations[scope].pop();
|
|
796
|
-
}
|
|
797
|
-
}
|
|
798
|
-
if (draft.document.operations[scope].length < draft.skip) {
|
|
799
|
-
throw new Error(
|
|
800
|
-
`Cannot undo: you can't undo more operations than the ones in the scope history`
|
|
801
|
-
);
|
|
802
|
-
}
|
|
803
|
-
const operationsLastIndex = draft.document.operations[scope].length - 1;
|
|
804
|
-
let skippedOpsLeft = input;
|
|
805
|
-
let index = isLatestOpNOOP ? operationsLastIndex - lastOperation.skip : operationsLastIndex;
|
|
806
|
-
while (skippedOpsLeft > 0 && index >= 0) {
|
|
807
|
-
const op = draft.document.operations[scope][index];
|
|
808
|
-
if (!op) {
|
|
809
|
-
skippedOpsLeft--;
|
|
810
|
-
index--;
|
|
811
|
-
continue;
|
|
812
|
-
}
|
|
813
|
-
if (op.type === "NOOP" && op.skip > 0) {
|
|
814
|
-
index = index - (op.skip + 1);
|
|
815
|
-
draft.skip += op.skip + 1;
|
|
816
|
-
} else {
|
|
817
|
-
draft.document.clipboard.push({ ...op });
|
|
818
|
-
skippedOpsLeft--;
|
|
819
|
-
index--;
|
|
820
|
-
}
|
|
821
|
-
}
|
|
822
|
-
draft.action = noop(scope);
|
|
823
|
-
});
|
|
824
|
-
}
|
|
825
|
-
function redoOperation(document, action, skip) {
|
|
826
|
-
const { scope, input } = action;
|
|
827
|
-
const defaultResult = {
|
|
828
|
-
document,
|
|
829
|
-
action,
|
|
830
|
-
skip
|
|
831
|
-
};
|
|
832
|
-
return mutative.create(defaultResult, (draft) => {
|
|
833
|
-
if (draft.skip > 0) {
|
|
834
|
-
throw new Error(
|
|
835
|
-
`Cannot redo: skip value from reducer cannot be used with REDO action`
|
|
836
|
-
);
|
|
837
|
-
}
|
|
838
|
-
if (input > 1) {
|
|
839
|
-
throw new Error(
|
|
840
|
-
`Cannot redo: you can only redo one operation at a time`
|
|
841
|
-
);
|
|
842
|
-
}
|
|
843
|
-
if (input < 1) {
|
|
844
|
-
throw new Error(`Invalid REDO action: invalid redo input value`);
|
|
845
|
-
}
|
|
846
|
-
if (draft.document.clipboard.length < 1) {
|
|
847
|
-
throw new Error(`Cannot redo: no operations in the clipboard`);
|
|
848
|
-
}
|
|
849
|
-
const operationIndex = draft.document.clipboard.findLastIndex(
|
|
850
|
-
(op) => op.scope === scope
|
|
851
|
-
);
|
|
852
|
-
if (operationIndex < 0) {
|
|
853
|
-
throw new Error(
|
|
854
|
-
`Cannot redo: no operations in clipboard for scope "${scope}"`
|
|
855
|
-
);
|
|
856
|
-
}
|
|
857
|
-
const operation = draft.document.clipboard.splice(operationIndex, 1)[0];
|
|
858
|
-
draft.action = mutative.castDraft({
|
|
859
|
-
type: operation.type,
|
|
860
|
-
scope: operation.scope,
|
|
861
|
-
input: operation.input
|
|
862
|
-
});
|
|
863
|
-
});
|
|
864
|
-
}
|
|
865
|
-
function pruneOperation(document, action, wrappedReducer) {
|
|
866
|
-
const { scope } = action;
|
|
867
|
-
const operations = document.operations[scope];
|
|
868
|
-
let {
|
|
869
|
-
input: { start, end }
|
|
870
|
-
} = action;
|
|
871
|
-
start = start || 0;
|
|
872
|
-
end = end || operations.length;
|
|
873
|
-
const actionsToPrune = operations.slice(start, end);
|
|
874
|
-
const actionsToKeepStart = operations.slice(0, start);
|
|
875
|
-
const actionsToKeepEnd = operations.slice(end);
|
|
876
|
-
const newDocument = replayOperations(
|
|
877
|
-
document.initialState,
|
|
878
|
-
{
|
|
879
|
-
...document.operations,
|
|
880
|
-
[scope]: actionsToKeepStart.concat(actionsToPrune)
|
|
881
|
-
},
|
|
882
|
-
wrappedReducer
|
|
883
|
-
);
|
|
884
|
-
const { name, state: newState } = newDocument;
|
|
885
|
-
const loadStateIndex = actionsToKeepStart.length;
|
|
886
|
-
const loadStateTimestamp = actionsToKeepStart.length ? actionsToKeepStart[actionsToKeepStart.length - 1].timestamp : actionsToKeepEnd.length ? actionsToKeepEnd[0].timestamp : (/* @__PURE__ */ new Date()).toISOString();
|
|
887
|
-
return replayOperations(
|
|
888
|
-
document.initialState,
|
|
889
|
-
{
|
|
890
|
-
...document.operations,
|
|
891
|
-
[scope]: [
|
|
892
|
-
...actionsToKeepStart,
|
|
893
|
-
{
|
|
894
|
-
...loadState(
|
|
895
|
-
{ name, state: newState },
|
|
896
|
-
actionsToPrune.length
|
|
897
|
-
),
|
|
898
|
-
timestamp: loadStateTimestamp,
|
|
899
|
-
index: loadStateIndex,
|
|
900
|
-
hash: hashDocument({ state: newState }, "global")
|
|
901
|
-
},
|
|
902
|
-
...actionsToKeepEnd.map((action2, index) => ({
|
|
903
|
-
...action2,
|
|
904
|
-
index: loadStateIndex + index + 1
|
|
905
|
-
}))
|
|
906
|
-
]
|
|
907
|
-
},
|
|
908
|
-
wrappedReducer
|
|
909
|
-
);
|
|
910
|
-
}
|
|
911
|
-
function loadStateOperation(oldDocument, newDocument) {
|
|
912
|
-
return {
|
|
913
|
-
...oldDocument,
|
|
914
|
-
name: newDocument.name,
|
|
915
|
-
state: newDocument.state ?? { global: {}, local: {} }
|
|
916
|
-
};
|
|
917
|
-
}
|
|
918
|
-
const SET_NAME = "SET_NAME";
|
|
919
|
-
const UNDO = "UNDO";
|
|
920
|
-
const REDO = "REDO";
|
|
921
|
-
const PRUNE = "PRUNE";
|
|
922
|
-
const LOAD_STATE = "LOAD_STATE";
|
|
923
|
-
const NOOP = "NOOP";
|
|
924
774
|
function writeFile(path$1, name, data) {
|
|
925
775
|
const filePath = path.join(path$1, name);
|
|
926
776
|
fs.mkdirSync(path$1, { recursive: true });
|
|
@@ -1487,6 +1337,13 @@ function filterDocumentOperationsResultingState(documentOperations) {
|
|
|
1487
1337
|
{}
|
|
1488
1338
|
);
|
|
1489
1339
|
}
|
|
1340
|
+
function diffOperations(clearedOperationsA, clearedOperationsB) {
|
|
1341
|
+
return clearedOperationsA.filter(
|
|
1342
|
+
(operationA) => !clearedOperationsB.some(
|
|
1343
|
+
(operationB) => operationA.index === operationB.index
|
|
1344
|
+
)
|
|
1345
|
+
);
|
|
1346
|
+
}
|
|
1490
1347
|
const documentHelpers = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
1491
1348
|
__proto__: null,
|
|
1492
1349
|
IntegrityIssueSubType,
|
|
@@ -1495,6 +1352,7 @@ const documentHelpers = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.def
|
|
|
1495
1352
|
attachBranch,
|
|
1496
1353
|
checkCleanedOperationsIntegrity,
|
|
1497
1354
|
checkOperationsIntegrity,
|
|
1355
|
+
diffOperations,
|
|
1498
1356
|
filterDocumentOperationsResultingState,
|
|
1499
1357
|
filterDuplicatedOperations,
|
|
1500
1358
|
garbageCollect,
|
|
@@ -1643,6 +1501,141 @@ async function getLocalFile(path2) {
|
|
|
1643
1501
|
const data = buffer.toString("base64");
|
|
1644
1502
|
return { data, hash: hash(data), mimeType, ...attributes };
|
|
1645
1503
|
}
|
|
1504
|
+
function setNameOperation(document, name) {
|
|
1505
|
+
return { ...document, name };
|
|
1506
|
+
}
|
|
1507
|
+
function undoOperation(document, action, skip) {
|
|
1508
|
+
const { scope, input } = action;
|
|
1509
|
+
const defaultResult = {
|
|
1510
|
+
document,
|
|
1511
|
+
action,
|
|
1512
|
+
skip,
|
|
1513
|
+
reuseLastOperationIndex: false
|
|
1514
|
+
};
|
|
1515
|
+
return mutative.create(defaultResult, (draft) => {
|
|
1516
|
+
const operations = [...document.operations[scope]];
|
|
1517
|
+
const sortedOperations = sortOperations$1(operations);
|
|
1518
|
+
draft.action = noop(scope);
|
|
1519
|
+
const lastOperation = sortedOperations.at(-1);
|
|
1520
|
+
let nextIndex = (lastOperation == null ? void 0 : lastOperation.index) ?? -1;
|
|
1521
|
+
const isNewNoop = (lastOperation == null ? void 0 : lastOperation.type) !== "NOOP";
|
|
1522
|
+
if (isNewNoop) {
|
|
1523
|
+
nextIndex = nextIndex + 1;
|
|
1524
|
+
} else {
|
|
1525
|
+
draft.reuseLastOperationIndex = true;
|
|
1526
|
+
}
|
|
1527
|
+
const nextOperationHistory = isNewNoop ? [...sortedOperations, { index: nextIndex, skip: 0 }] : sortedOperations;
|
|
1528
|
+
draft.skip = nextSkipNumber(nextOperationHistory);
|
|
1529
|
+
if (lastOperation && draft.skip > lastOperation.skip + 1) {
|
|
1530
|
+
draft.skip = draft.skip + 1;
|
|
1531
|
+
}
|
|
1532
|
+
if (draft.skip < 0) {
|
|
1533
|
+
throw new Error(
|
|
1534
|
+
`Cannot undo: you can't undo more operations than the ones in the scope history`
|
|
1535
|
+
);
|
|
1536
|
+
}
|
|
1537
|
+
});
|
|
1538
|
+
}
|
|
1539
|
+
function redoOperation(document, action, skip) {
|
|
1540
|
+
const { scope, input } = action;
|
|
1541
|
+
const defaultResult = {
|
|
1542
|
+
document,
|
|
1543
|
+
action,
|
|
1544
|
+
skip,
|
|
1545
|
+
reuseLastOperationIndex: false
|
|
1546
|
+
};
|
|
1547
|
+
return mutative.create(defaultResult, (draft) => {
|
|
1548
|
+
if (draft.skip > 0) {
|
|
1549
|
+
throw new Error(
|
|
1550
|
+
`Cannot redo: skip value from reducer cannot be used with REDO action`
|
|
1551
|
+
);
|
|
1552
|
+
}
|
|
1553
|
+
if (input > 1) {
|
|
1554
|
+
throw new Error(
|
|
1555
|
+
`Cannot redo: you can only redo one operation at a time`
|
|
1556
|
+
);
|
|
1557
|
+
}
|
|
1558
|
+
if (input < 1) {
|
|
1559
|
+
throw new Error(`Invalid REDO action: invalid redo input value`);
|
|
1560
|
+
}
|
|
1561
|
+
if (draft.document.clipboard.length < 1) {
|
|
1562
|
+
throw new Error(`Cannot redo: no operations in the clipboard`);
|
|
1563
|
+
}
|
|
1564
|
+
const operationIndex = draft.document.clipboard.findLastIndex(
|
|
1565
|
+
(op) => op.scope === scope
|
|
1566
|
+
);
|
|
1567
|
+
if (operationIndex < 0) {
|
|
1568
|
+
throw new Error(
|
|
1569
|
+
`Cannot redo: no operations in clipboard for scope "${scope}"`
|
|
1570
|
+
);
|
|
1571
|
+
}
|
|
1572
|
+
const operation = draft.document.clipboard.splice(operationIndex, 1)[0];
|
|
1573
|
+
draft.action = mutative.castDraft({
|
|
1574
|
+
type: operation.type,
|
|
1575
|
+
scope: operation.scope,
|
|
1576
|
+
input: operation.input
|
|
1577
|
+
});
|
|
1578
|
+
});
|
|
1579
|
+
}
|
|
1580
|
+
function pruneOperation(document, action, wrappedReducer) {
|
|
1581
|
+
const { scope } = action;
|
|
1582
|
+
const operations = document.operations[scope];
|
|
1583
|
+
let {
|
|
1584
|
+
input: { start, end }
|
|
1585
|
+
} = action;
|
|
1586
|
+
start = start || 0;
|
|
1587
|
+
end = end || operations.length;
|
|
1588
|
+
const actionsToPrune = operations.slice(start, end);
|
|
1589
|
+
const actionsToKeepStart = operations.slice(0, start);
|
|
1590
|
+
const actionsToKeepEnd = operations.slice(end);
|
|
1591
|
+
const newDocument = replayOperations(
|
|
1592
|
+
document.initialState,
|
|
1593
|
+
{
|
|
1594
|
+
...document.operations,
|
|
1595
|
+
[scope]: actionsToKeepStart.concat(actionsToPrune)
|
|
1596
|
+
},
|
|
1597
|
+
wrappedReducer
|
|
1598
|
+
);
|
|
1599
|
+
const { name, state: newState } = newDocument;
|
|
1600
|
+
const loadStateIndex = actionsToKeepStart.length;
|
|
1601
|
+
const loadStateTimestamp = actionsToKeepStart.length ? actionsToKeepStart[actionsToKeepStart.length - 1].timestamp : actionsToKeepEnd.length ? actionsToKeepEnd[0].timestamp : (/* @__PURE__ */ new Date()).toISOString();
|
|
1602
|
+
return replayOperations(
|
|
1603
|
+
document.initialState,
|
|
1604
|
+
{
|
|
1605
|
+
...document.operations,
|
|
1606
|
+
[scope]: [
|
|
1607
|
+
...actionsToKeepStart,
|
|
1608
|
+
{
|
|
1609
|
+
...loadState(
|
|
1610
|
+
{ name, state: newState },
|
|
1611
|
+
actionsToPrune.length
|
|
1612
|
+
),
|
|
1613
|
+
timestamp: loadStateTimestamp,
|
|
1614
|
+
index: loadStateIndex,
|
|
1615
|
+
hash: hashDocument({ state: newState }, "global")
|
|
1616
|
+
},
|
|
1617
|
+
...actionsToKeepEnd.map((action2, index) => ({
|
|
1618
|
+
...action2,
|
|
1619
|
+
index: loadStateIndex + index + 1
|
|
1620
|
+
}))
|
|
1621
|
+
]
|
|
1622
|
+
},
|
|
1623
|
+
wrappedReducer
|
|
1624
|
+
);
|
|
1625
|
+
}
|
|
1626
|
+
function loadStateOperation(oldDocument, newDocument) {
|
|
1627
|
+
return {
|
|
1628
|
+
...oldDocument,
|
|
1629
|
+
name: newDocument.name,
|
|
1630
|
+
state: newDocument.state ?? { global: {}, local: {} }
|
|
1631
|
+
};
|
|
1632
|
+
}
|
|
1633
|
+
const SET_NAME = "SET_NAME";
|
|
1634
|
+
const UNDO = "UNDO";
|
|
1635
|
+
const REDO = "REDO";
|
|
1636
|
+
const PRUNE = "PRUNE";
|
|
1637
|
+
const LOAD_STATE = "LOAD_STATE";
|
|
1638
|
+
const NOOP = "NOOP";
|
|
1646
1639
|
function getNextRevision(document, action) {
|
|
1647
1640
|
let latestOperation;
|
|
1648
1641
|
if ("index" in action) {
|
|
@@ -1662,7 +1655,7 @@ function updateHeader(document, action) {
|
|
|
1662
1655
|
lastModified: (/* @__PURE__ */ new Date()).toISOString()
|
|
1663
1656
|
};
|
|
1664
1657
|
}
|
|
1665
|
-
function updateOperations(document, action, skip = 0) {
|
|
1658
|
+
function updateOperations(document, action, skip = 0, reuseLastOperationIndex = false) {
|
|
1666
1659
|
if ([UNDO, REDO, PRUNE].includes(action.type)) {
|
|
1667
1660
|
return document;
|
|
1668
1661
|
}
|
|
@@ -1670,7 +1663,8 @@ function updateOperations(document, action, skip = 0) {
|
|
|
1670
1663
|
const operations = document.operations[scope].slice();
|
|
1671
1664
|
let operationId;
|
|
1672
1665
|
const latestOperation = operations.at(-1);
|
|
1673
|
-
|
|
1666
|
+
const lastOperationIndex = (latestOperation == null ? void 0 : latestOperation.index) ?? -1;
|
|
1667
|
+
let nextIndex = reuseLastOperationIndex ? lastOperationIndex : lastOperationIndex + 1;
|
|
1674
1668
|
if ("index" in action) {
|
|
1675
1669
|
if (action.index - skip > nextIndex) {
|
|
1676
1670
|
throw new Error(
|
|
@@ -1697,8 +1691,13 @@ function updateOperations(document, action, skip = 0) {
|
|
|
1697
1691
|
operations: { ...document.operations, [scope]: operations }
|
|
1698
1692
|
};
|
|
1699
1693
|
}
|
|
1700
|
-
function updateDocument(document, action, skip = 0) {
|
|
1701
|
-
let newDocument = updateOperations(
|
|
1694
|
+
function updateDocument(document, action, skip = 0, reuseLastOperationIndex = false) {
|
|
1695
|
+
let newDocument = updateOperations(
|
|
1696
|
+
document,
|
|
1697
|
+
action,
|
|
1698
|
+
skip,
|
|
1699
|
+
reuseLastOperationIndex
|
|
1700
|
+
);
|
|
1702
1701
|
newDocument = updateHeader(newDocument, action);
|
|
1703
1702
|
return newDocument;
|
|
1704
1703
|
}
|
|
@@ -1722,7 +1721,7 @@ function processUndoRedo(document, action, skip) {
|
|
|
1722
1721
|
case REDO:
|
|
1723
1722
|
return redoOperation(document, action, skip);
|
|
1724
1723
|
default:
|
|
1725
|
-
return { document, action, skip };
|
|
1724
|
+
return { document, action, skip, reuseLastOperationIndex: false };
|
|
1726
1725
|
}
|
|
1727
1726
|
}
|
|
1728
1727
|
function processSkipOperation(document, action, customReducer, skipValue, reuseOperationResultingState = false, resultingStateParser = parseResultingState) {
|
|
@@ -1772,6 +1771,37 @@ function processSkipOperation(document, action, customReducer, skipValue, reuseO
|
|
|
1772
1771
|
})
|
|
1773
1772
|
};
|
|
1774
1773
|
}
|
|
1774
|
+
function processUndoOperation(document, scope, customReducer, reuseOperationResultingState = false, resultingStateParser = parseResultingState) {
|
|
1775
|
+
const operations = [...document.operations[scope]];
|
|
1776
|
+
const sortedOperations = sortOperations$1(operations);
|
|
1777
|
+
sortedOperations.pop();
|
|
1778
|
+
const documentOperations = garbageCollectDocumentOperations(
|
|
1779
|
+
{ ...document.operations }
|
|
1780
|
+
);
|
|
1781
|
+
const clearedOperations = [...documentOperations[scope]];
|
|
1782
|
+
const diff = diffOperations(
|
|
1783
|
+
garbageCollect(sortedOperations),
|
|
1784
|
+
clearedOperations
|
|
1785
|
+
);
|
|
1786
|
+
const doc = replayOperations(
|
|
1787
|
+
document.initialState,
|
|
1788
|
+
documentOperations,
|
|
1789
|
+
customReducer,
|
|
1790
|
+
void 0,
|
|
1791
|
+
void 0,
|
|
1792
|
+
void 0,
|
|
1793
|
+
void 0,
|
|
1794
|
+
{
|
|
1795
|
+
reuseHash: true,
|
|
1796
|
+
reuseOperationResultingState,
|
|
1797
|
+
operationResultingStateParser: resultingStateParser
|
|
1798
|
+
}
|
|
1799
|
+
);
|
|
1800
|
+
const clipboard = sortOperations$1(
|
|
1801
|
+
[...document.clipboard, ...diff].filter((op) => op.type !== "NOOP")
|
|
1802
|
+
).reverse();
|
|
1803
|
+
return { ...doc, clipboard };
|
|
1804
|
+
}
|
|
1775
1805
|
function baseReducer(document, action, customReducer, dispatch, options = {}) {
|
|
1776
1806
|
const {
|
|
1777
1807
|
skip,
|
|
@@ -1780,14 +1810,46 @@ function baseReducer(document, action, customReducer, dispatch, options = {}) {
|
|
|
1780
1810
|
reuseOperationResultingState = false,
|
|
1781
1811
|
operationResultingStateParser
|
|
1782
1812
|
} = options;
|
|
1783
|
-
|
|
1784
|
-
|
|
1813
|
+
let _action = { ...action };
|
|
1814
|
+
let skipValue = skip || 0;
|
|
1785
1815
|
let newDocument = { ...document };
|
|
1816
|
+
let reuseLastOperationIndex = false;
|
|
1786
1817
|
const shouldProcessSkipOperation = !ignoreSkipOperations && (skipValue > 0 || "index" in _action && _action.skip > 0);
|
|
1818
|
+
if (isUndoRedo(_action)) {
|
|
1819
|
+
const {
|
|
1820
|
+
skip: calculatedSkip,
|
|
1821
|
+
action: transformedAction,
|
|
1822
|
+
document: processedDocument,
|
|
1823
|
+
reuseLastOperationIndex: reuseIndex
|
|
1824
|
+
} = processUndoRedo(document, _action, skipValue);
|
|
1825
|
+
_action = transformedAction;
|
|
1826
|
+
skipValue = calculatedSkip;
|
|
1827
|
+
newDocument = processedDocument;
|
|
1828
|
+
reuseLastOperationIndex = reuseIndex;
|
|
1829
|
+
} else {
|
|
1830
|
+
newDocument = {
|
|
1831
|
+
...newDocument,
|
|
1832
|
+
clipboard: []
|
|
1833
|
+
};
|
|
1834
|
+
}
|
|
1787
1835
|
if (isBaseAction(_action)) {
|
|
1788
1836
|
newDocument = _baseReducer(newDocument, _action, customReducer);
|
|
1789
1837
|
}
|
|
1790
|
-
newDocument = updateDocument(
|
|
1838
|
+
newDocument = updateDocument(
|
|
1839
|
+
newDocument,
|
|
1840
|
+
_action,
|
|
1841
|
+
skipValue,
|
|
1842
|
+
reuseLastOperationIndex
|
|
1843
|
+
);
|
|
1844
|
+
const isUndoAction = isUndo(action);
|
|
1845
|
+
if (isUndoAction) {
|
|
1846
|
+
const result = processUndoOperation(
|
|
1847
|
+
newDocument,
|
|
1848
|
+
action.scope,
|
|
1849
|
+
customReducer
|
|
1850
|
+
);
|
|
1851
|
+
return result;
|
|
1852
|
+
}
|
|
1791
1853
|
if (shouldProcessSkipOperation) {
|
|
1792
1854
|
newDocument = processSkipOperation(
|
|
1793
1855
|
newDocument,
|
|
@@ -1927,6 +1989,9 @@ function isNoopOperation(op) {
|
|
|
1927
1989
|
function isUndoRedo(action) {
|
|
1928
1990
|
return [UNDO, REDO].includes(action.type);
|
|
1929
1991
|
}
|
|
1992
|
+
function isUndo(action) {
|
|
1993
|
+
return action.type === UNDO;
|
|
1994
|
+
}
|
|
1930
1995
|
function isBaseAction(action) {
|
|
1931
1996
|
return [SET_NAME, UNDO, REDO, PRUNE, LOAD_STATE].includes(action.type);
|
|
1932
1997
|
}
|
|
@@ -2022,23 +2087,6 @@ function mapSkippedOperations(operations, skippedHeadOperations) {
|
|
|
2022
2087
|
}
|
|
2023
2088
|
return scopeOpsWithIgnore.reverse();
|
|
2024
2089
|
}
|
|
2025
|
-
function calculateSkipsLeft(operations, currentIndex, skip) {
|
|
2026
|
-
const sortedOperations = operations.slice().sort((a, b) => a.skip - b.skip).sort((a, b) => a.index - b.index);
|
|
2027
|
-
let skipsLeft = skip;
|
|
2028
|
-
let skipsToPerform = 0;
|
|
2029
|
-
let lastIndex = currentIndex;
|
|
2030
|
-
for (const operation of sortedOperations.reverse()) {
|
|
2031
|
-
const distance = lastIndex - operation.index;
|
|
2032
|
-
skipsLeft = skipsLeft - distance;
|
|
2033
|
-
if (skipsLeft > -1) {
|
|
2034
|
-
skipsToPerform++;
|
|
2035
|
-
lastIndex = operation.index;
|
|
2036
|
-
} else {
|
|
2037
|
-
break;
|
|
2038
|
-
}
|
|
2039
|
-
}
|
|
2040
|
-
return skipsToPerform;
|
|
2041
|
-
}
|
|
2042
2090
|
function sortOperations(operations) {
|
|
2043
2091
|
return Object.values(operations).flatMap((array) => array).sort(
|
|
2044
2092
|
(a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime()
|
|
@@ -2412,7 +2460,6 @@ exports.buildOperationSignature = buildOperationSignature;
|
|
|
2412
2460
|
exports.buildOperationSignatureMessage = buildOperationSignatureMessage;
|
|
2413
2461
|
exports.buildOperationSignatureParams = buildOperationSignatureParams;
|
|
2414
2462
|
exports.buildSignedOperation = buildSignedOperation;
|
|
2415
|
-
exports.calculateSkipsLeft = calculateSkipsLeft;
|
|
2416
2463
|
exports.createAction = createAction;
|
|
2417
2464
|
exports.createDocument = createDocument;
|
|
2418
2465
|
exports.createExtendedState = createExtendedState;
|
|
@@ -2429,6 +2476,7 @@ exports.hex2ab = hex2ab;
|
|
|
2429
2476
|
exports.isBaseAction = isBaseAction;
|
|
2430
2477
|
exports.isNoopOperation = isNoopOperation;
|
|
2431
2478
|
exports.isSameDocument = isSameDocument;
|
|
2479
|
+
exports.isUndo = isUndo;
|
|
2432
2480
|
exports.isUndoRedo = isUndoRedo;
|
|
2433
2481
|
exports.loadFromFile = loadFromFile;
|
|
2434
2482
|
exports.loadFromInput = loadFromInput;
|
|
@@ -2448,4 +2496,4 @@ exports.updateHeader = updateHeader;
|
|
|
2448
2496
|
exports.validateOperations = validateOperations;
|
|
2449
2497
|
exports.verifyOperationSignature = verifyOperationSignature;
|
|
2450
2498
|
exports.zod = zod;
|
|
2451
|
-
//# sourceMappingURL=object-
|
|
2499
|
+
//# sourceMappingURL=object-BMOaYPkd.js.map
|