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