document-model 1.6.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.
Files changed (69) hide show
  1. package/dist/browser/cjs/document-model.js +2 -2
  2. package/dist/browser/cjs/document.js +2 -2
  3. package/dist/browser/cjs/index.js +2 -2
  4. package/dist/browser/cjs/internal/{index-vlbA6Asd.js → index-UG6TQ_ad.js} +5 -10
  5. package/dist/browser/{es/internal/index-CuhiYn-8.js.map → cjs/internal/index-UG6TQ_ad.js.map} +1 -1
  6. package/dist/browser/cjs/internal/{index-BImZF-Wk.js → index-jRdLtWv9.js} +12 -4
  7. package/dist/browser/cjs/internal/index-jRdLtWv9.js.map +1 -0
  8. package/dist/browser/cjs/internal/{object-9Wvjprnm.js → object-CCclzskm.js} +640 -2287
  9. package/dist/browser/cjs/internal/object-CCclzskm.js.map +1 -0
  10. package/dist/browser/es/document-model.js +2 -2
  11. package/dist/browser/es/document.js +8 -8
  12. package/dist/browser/es/index.js +2 -2
  13. package/dist/browser/es/internal/{index-CuhiYn-8.js → index-CDwXQBxG.js} +5 -10
  14. package/dist/{node/es/internal/index-BNAE-_Hg.js.map → browser/es/internal/index-CDwXQBxG.js.map} +1 -1
  15. package/dist/browser/es/internal/index-v4H3kbAF.js +58 -0
  16. package/dist/browser/es/internal/index-v4H3kbAF.js.map +1 -0
  17. package/dist/browser/es/internal/{object-CyAog_F_.js → object-CU5T1DpX.js} +664 -2311
  18. package/dist/browser/es/internal/object-CU5T1DpX.js.map +1 -0
  19. package/dist/browser/src/document/actions/creators.d.ts +1 -1
  20. package/dist/browser/src/document/reducer.d.ts +4 -1
  21. package/dist/browser/src/document/schema/zod.d.ts +18 -18
  22. package/dist/browser/src/document/types.d.ts +13 -1
  23. package/dist/browser/src/document/utils/base.d.ts +3 -3
  24. package/dist/browser/src/document/utils/crypto.d.ts +10 -0
  25. package/dist/browser/src/document/utils/document-helpers.d.ts +10 -0
  26. package/dist/browser/src/document/utils/index.d.ts +1 -0
  27. package/dist/browser/src/document/utils/node.d.ts +3 -2
  28. package/dist/browser/src/document-model/gen/schema/zod.d.ts +169 -169
  29. package/dist/browser/src/document-model/index.d.ts +3 -3
  30. package/dist/node/cjs/document-model.js +2 -2
  31. package/dist/node/cjs/document.js +2 -2
  32. package/dist/node/cjs/index.js +2 -2
  33. package/dist/node/cjs/internal/{index-CJIU8iX-.js → index-5qN282Jw.js} +12 -4
  34. package/dist/node/cjs/internal/index-5qN282Jw.js.map +1 -0
  35. package/dist/node/cjs/internal/{index-DWeC8dwW.js → index-Bm-pIfaz.js} +5 -10
  36. package/dist/node/cjs/internal/{index-DWeC8dwW.js.map → index-Bm-pIfaz.js.map} +1 -1
  37. package/dist/node/cjs/internal/{object-op6YzhH1.js → object-BMOaYPkd.js} +381 -244
  38. package/dist/node/cjs/internal/object-BMOaYPkd.js.map +1 -0
  39. package/dist/node/es/document-model.js +2 -2
  40. package/dist/node/es/document.js +8 -8
  41. package/dist/node/es/index.js +2 -2
  42. package/dist/node/es/internal/{index-BNAE-_Hg.js → index-CAjAt1Xx.js} +5 -10
  43. package/dist/{browser/cjs/internal/index-vlbA6Asd.js.map → node/es/internal/index-CAjAt1Xx.js.map} +1 -1
  44. package/dist/node/es/internal/index-CVuLZAmf.js +58 -0
  45. package/dist/node/es/internal/index-CVuLZAmf.js.map +1 -0
  46. package/dist/node/es/internal/{object-BuK9PFjs.js → object-COSf2HUT.js} +405 -268
  47. package/dist/node/es/internal/object-COSf2HUT.js.map +1 -0
  48. package/dist/node/src/document/actions/creators.d.ts +1 -1
  49. package/dist/node/src/document/reducer.d.ts +4 -1
  50. package/dist/node/src/document/schema/zod.d.ts +18 -18
  51. package/dist/node/src/document/types.d.ts +13 -1
  52. package/dist/node/src/document/utils/base.d.ts +3 -3
  53. package/dist/node/src/document/utils/crypto.d.ts +10 -0
  54. package/dist/node/src/document/utils/document-helpers.d.ts +10 -0
  55. package/dist/node/src/document/utils/index.d.ts +1 -0
  56. package/dist/node/src/document/utils/node.d.ts +3 -2
  57. package/dist/node/src/document-model/gen/schema/zod.d.ts +169 -169
  58. package/dist/node/src/document-model/index.d.ts +3 -3
  59. package/package.json +6 -3
  60. package/dist/browser/cjs/internal/index-BImZF-Wk.js.map +0 -1
  61. package/dist/browser/cjs/internal/object-9Wvjprnm.js.map +0 -1
  62. package/dist/browser/es/internal/index-Drp90r05.js +0 -50
  63. package/dist/browser/es/internal/index-Drp90r05.js.map +0 -1
  64. package/dist/browser/es/internal/object-CyAog_F_.js.map +0 -1
  65. package/dist/node/cjs/internal/index-CJIU8iX-.js.map +0 -1
  66. package/dist/node/cjs/internal/object-op6YzhH1.js.map +0 -1
  67. package/dist/node/es/internal/index-B_7z_4EV.js +0 -50
  68. package/dist/node/es/internal/index-B_7z_4EV.js.map +0 -1
  69. package/dist/node/es/internal/object-BuK9PFjs.js.map +0 -1
@@ -1,17 +1,14 @@
1
1
  "use strict";
2
2
  var __defProp = Object.defineProperty;
3
3
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
4
- var __publicField = (obj, key, value) => {
5
- __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
6
- return value;
7
- };
4
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
8
5
  const mutative = require("mutative");
9
6
  const zod$1 = require("zod");
10
- const JSZip = require("jszip");
11
7
  const crypto$1 = require("crypto");
12
8
  const fs = require("fs");
13
9
  const https = require("https");
14
10
  const path = require("path");
11
+ const JSZip = require("jszip");
15
12
  const isDefinedNonNullAny = (v) => v !== void 0 && v !== null;
16
13
  const definedNonNullAnySchema = zod$1.z.any().refine((v) => isDefinedNonNullAny(v));
17
14
  const Load_StateSchema = zod$1.z.enum(["LOAD_STATE"]);
@@ -161,16 +158,16 @@ var safeStableStringify = { exports: {} };
161
158
  exports2.stringify = stringify;
162
159
  exports2.configure = configure;
163
160
  module2.exports = stringify;
164
- const strEscapeSequencesRegExp = /[\u0000-\u001f\u0022\u005c\ud800-\udfff]|[\ud800-\udbff](?![\udc00-\udfff])|(?:[^\ud800-\udbff]|^)[\udc00-\udfff]/;
161
+ const strEscapeSequencesRegExp = /[\u0000-\u001f\u0022\u005c\ud800-\udfff]/;
165
162
  function strEscape(str) {
166
163
  if (str.length < 5e3 && !strEscapeSequencesRegExp.test(str)) {
167
164
  return `"${str}"`;
168
165
  }
169
166
  return JSON.stringify(str);
170
167
  }
171
- function insertSort(array) {
172
- if (array.length > 200) {
173
- return array.sort();
168
+ function sort(array, comparator) {
169
+ if (array.length > 200 || comparator) {
170
+ return array.sort(comparator);
174
171
  }
175
172
  for (let i = 1; i < array.length; i++) {
176
173
  const currentValue = array[i];
@@ -225,6 +222,16 @@ var safeStableStringify = { exports: {} };
225
222
  }
226
223
  return '"[Circular]"';
227
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
+ }
228
235
  function getBooleanOption(options, key) {
229
236
  let value;
230
237
  if (hasOwnProperty.call(options, key)) {
@@ -275,8 +282,7 @@ var safeStableStringify = { exports: {} };
275
282
  if (value) {
276
283
  return (value2) => {
277
284
  let message = `Object can not safely be stringified. Received type ${typeof value2}`;
278
- if (typeof value2 !== "function")
279
- message += ` (${value2.toString()})`;
285
+ if (typeof value2 !== "function") message += ` (${value2.toString()})`;
280
286
  throw new Error(message);
281
287
  };
282
288
  }
@@ -295,7 +301,8 @@ var safeStableStringify = { exports: {} };
295
301
  }
296
302
  const circularValue = getCircularValueOption(options);
297
303
  const bigint = getBooleanOption(options, "bigint");
298
- const deterministic = getBooleanOption(options, "deterministic");
304
+ const deterministic = getDeterministicOption(options);
305
+ const comparator = typeof deterministic === "function" ? deterministic : void 0;
299
306
  const maximumDepth = getPositiveIntegerOption(options, "maximumDepth");
300
307
  const maximumBreadth = getPositiveIntegerOption(options, "maximumBreadth");
301
308
  function stringifyFnReplacer(key, parent, stack, replacer, spacer, indentation) {
@@ -370,7 +377,7 @@ ${indentation}`;
370
377
  }
371
378
  const maximumPropertiesToStringify = Math.min(keyLength, maximumBreadth);
372
379
  if (deterministic && !isTypedArrayWithEntries(value)) {
373
- keys = insertSort(keys);
380
+ keys = sort(keys, comparator);
374
381
  }
375
382
  stack.push(value);
376
383
  for (let i = 0; i < maximumPropertiesToStringify; i++) {
@@ -571,7 +578,7 @@ ${indentation}`;
571
578
  separator = join;
572
579
  }
573
580
  if (deterministic) {
574
- keys = insertSort(keys);
581
+ keys = sort(keys, comparator);
575
582
  }
576
583
  stack.push(value);
577
584
  for (let i = 0; i < maximumPropertiesToStringify; i++) {
@@ -630,7 +637,8 @@ ${originalIndentation}`;
630
637
  return circularValue;
631
638
  }
632
639
  let res = "";
633
- if (Array.isArray(value)) {
640
+ const hasLength = value.length !== void 0;
641
+ if (hasLength && Array.isArray(value)) {
634
642
  if (value.length === 0) {
635
643
  return "[]";
636
644
  }
@@ -664,14 +672,14 @@ ${originalIndentation}`;
664
672
  }
665
673
  let separator = "";
666
674
  let maximumPropertiesToStringify = Math.min(keyLength, maximumBreadth);
667
- if (isTypedArrayWithEntries(value)) {
675
+ if (hasLength && isTypedArrayWithEntries(value)) {
668
676
  res += stringifyTypedArray(value, ",", maximumBreadth);
669
677
  keys = keys.slice(value.length);
670
678
  maximumPropertiesToStringify -= value.length;
671
679
  separator = ",";
672
680
  }
673
681
  if (deterministic) {
674
- keys = insertSort(keys);
682
+ keys = sort(keys, comparator);
675
683
  }
676
684
  stack.push(value);
677
685
  for (let i = 0; i < maximumPropertiesToStringify; i++) {
@@ -763,175 +771,142 @@ function v4(options, buf, offset) {
763
771
  rnds[8] = rnds[8] & 63 | 128;
764
772
  return unsafeStringify(rnds);
765
773
  }
766
- function setNameOperation(document, name) {
767
- return { ...document, name };
768
- }
769
- function undoOperation(document, action, skip) {
770
- const { scope, input } = action;
771
- const defaultResult = {
772
- document,
773
- action,
774
- skip
775
- };
776
- return mutative.create(defaultResult, (draft) => {
777
- if (draft.document.operations[scope].length < 1) {
778
- throw new Error(
779
- `Cannot undo: no operations in history for scope "${scope}"`
780
- );
781
- }
782
- if (input < 1) {
783
- throw new Error(
784
- `Invalid UNDO action: input value must be greater than 0`
785
- );
786
- }
787
- if (draft.skip > 0) {
788
- throw new Error(
789
- `Cannot undo: skip value from reducer cannot be used with UNDO action`
790
- );
791
- }
792
- const lastOperation = draft.document.operations[scope].at(-1);
793
- const isLatestOpNOOP = lastOperation && lastOperation.type === "NOOP" && lastOperation.skip > 0;
794
- draft.skip += input;
795
- if (isLatestOpNOOP) {
796
- draft.skip += lastOperation.skip;
797
- const preLastOperation = draft.document.operations[scope][draft.document.operations[scope].length - 2];
798
- if (preLastOperation && lastOperation.index - preLastOperation.index === 1) {
799
- draft.document.operations[scope].pop();
800
- }
801
- }
802
- if (draft.document.operations[scope].length < draft.skip) {
803
- throw new Error(
804
- `Cannot undo: you can't undo more operations than the ones in the scope history`
805
- );
806
- }
807
- const operationsLastIndex = draft.document.operations[scope].length - 1;
808
- let skippedOpsLeft = input;
809
- let index = isLatestOpNOOP ? operationsLastIndex - lastOperation.skip : operationsLastIndex;
810
- while (skippedOpsLeft > 0 && index >= 0) {
811
- const op = draft.document.operations[scope][index];
812
- if (!op) {
813
- skippedOpsLeft--;
814
- index--;
815
- continue;
816
- }
817
- if (op.type === "NOOP" && op.skip > 0) {
818
- index = index - (op.skip + 1);
819
- draft.skip += op.skip + 1;
820
- } else {
821
- draft.document.clipboard.push({ ...op });
822
- skippedOpsLeft--;
823
- index--;
824
- }
774
+ function writeFile(path$1, name, data) {
775
+ const filePath = path.join(path$1, name);
776
+ fs.mkdirSync(path$1, { recursive: true });
777
+ return new Promise((resolve, reject) => {
778
+ try {
779
+ fs.writeFile(filePath, data, {}, (err) => {
780
+ if (err) {
781
+ reject(err);
782
+ } else {
783
+ resolve(filePath);
784
+ }
785
+ });
786
+ } catch (error) {
787
+ reject(error);
825
788
  }
826
- draft.action = noop(scope);
827
789
  });
828
790
  }
829
- function redoOperation(document, action, skip) {
830
- const { scope, input } = action;
831
- const defaultResult = {
832
- document,
833
- action,
834
- skip
835
- };
836
- return mutative.create(defaultResult, (draft) => {
837
- if (draft.skip > 0) {
838
- throw new Error(
839
- `Cannot redo: skip value from reducer cannot be used with REDO action`
840
- );
841
- }
842
- if (input > 1) {
843
- throw new Error(
844
- `Cannot redo: you can only redo one operation at a time`
845
- );
846
- }
847
- if (input < 1) {
848
- throw new Error(`Invalid REDO action: invalid redo input value`);
849
- }
850
- if (draft.document.clipboard.length < 1) {
851
- throw new Error(`Cannot redo: no operations in the clipboard`);
852
- }
853
- const operationIndex = draft.document.clipboard.findLastIndex(
854
- (op) => op.scope === scope
855
- );
856
- if (operationIndex < 0) {
857
- throw new Error(
858
- `Cannot redo: no operations in clipboard for scope "${scope}"`
859
- );
860
- }
861
- const operation = draft.document.clipboard.splice(operationIndex, 1)[0];
862
- draft.action = mutative.castDraft({
863
- type: operation.type,
864
- scope: operation.scope,
865
- input: operation.input
791
+ function readFile(path2) {
792
+ return fs.readFileSync(path2);
793
+ }
794
+ function fetchFile(url) {
795
+ return new Promise((resolve, reject) => {
796
+ https.get(url, (resp) => {
797
+ const data = [];
798
+ const mimeType = resp.headers["content-type"];
799
+ resp.on("data", (chunk) => {
800
+ data.push(chunk);
801
+ });
802
+ resp.on("end", () => {
803
+ resolve({ buffer: Buffer.concat(data), mimeType });
804
+ });
805
+ }).on("error", (err) => {
806
+ reject(err);
866
807
  });
867
808
  });
868
809
  }
869
- function pruneOperation(document, action, wrappedReducer) {
870
- const { scope } = action;
871
- const operations = document.operations[scope];
872
- let {
873
- input: { start, end }
874
- } = action;
875
- start = start || 0;
876
- end = end || operations.length;
877
- const actionsToPrune = operations.slice(start, end);
878
- const actionsToKeepStart = operations.slice(0, start);
879
- const actionsToKeepEnd = operations.slice(end);
880
- const newDocument = replayOperations(
881
- document.initialState,
882
- {
883
- ...document.operations,
884
- [scope]: actionsToKeepStart.concat(actionsToPrune)
885
- },
886
- wrappedReducer
810
+ const getFile = async (file) => {
811
+ return readFile(file);
812
+ };
813
+ const hash = (data, algorithm = "sha1") => {
814
+ return crypto$1.createHash(algorithm).update(data).digest("base64");
815
+ };
816
+ function getUnixTimestamp(date) {
817
+ return (new Date(date).getTime() / 1e3).toFixed(0);
818
+ }
819
+ function buildOperationSignatureParams({
820
+ documentId,
821
+ signer,
822
+ operation,
823
+ previousStateHash
824
+ }) {
825
+ const { timestamp, scope, id, type } = operation;
826
+ return [
827
+ getUnixTimestamp(timestamp),
828
+ // timestamp,
829
+ signer.app.key,
830
+ // signer public key
831
+ hash(
832
+ // hash (docID, scope, operationID, operationName, operationInput)
833
+ [documentId, scope, id, type, cjsModule(operation.input)].join(
834
+ ""
835
+ )
836
+ ),
837
+ previousStateHash
838
+ // state hash that the operation was applied to
839
+ ];
840
+ }
841
+ const textEncode = new TextEncoder();
842
+ function buildOperationSignatureMessage(params) {
843
+ const message = params.join("");
844
+ const prefix = "Signed Operation:\n" + message.length.toString();
845
+ return textEncode.encode(prefix + message);
846
+ }
847
+ function ab2hex(ab) {
848
+ return Array.prototype.map.call(
849
+ new Uint8Array(ab),
850
+ (x) => ("00" + x.toString(16)).slice(-2)
851
+ ).join("");
852
+ }
853
+ function hex2ab(hex) {
854
+ var _a;
855
+ return new Uint8Array(
856
+ ((_a = hex.match(/[\da-f]{2}/gi)) == null ? void 0 : _a.map(function(h) {
857
+ return parseInt(h, 16);
858
+ })) ?? []
887
859
  );
888
- const { name, state: newState } = newDocument;
889
- const loadStateIndex = actionsToKeepStart.length;
890
- const loadStateTimestamp = actionsToKeepStart.length ? actionsToKeepStart[actionsToKeepStart.length - 1].timestamp : actionsToKeepEnd.length ? actionsToKeepEnd[0].timestamp : (/* @__PURE__ */ new Date()).toISOString();
891
- return replayOperations(
892
- document.initialState,
860
+ }
861
+ async function buildOperationSignature(context, signMethod) {
862
+ const params = buildOperationSignatureParams(context);
863
+ const message = buildOperationSignatureMessage(params);
864
+ const signature = await signMethod(message);
865
+ return [...params, `0x${ab2hex(signature)}`];
866
+ }
867
+ async function buildSignedOperation(action, reducer, document, context, signHandler) {
868
+ var _a, _b;
869
+ const result = reducer(document, action, void 0, {
870
+ reuseHash: true,
871
+ reuseOperationResultingState: true
872
+ });
873
+ const operation = result.operations[action.scope].at(-1);
874
+ if (!operation) {
875
+ throw new Error("Action was not applied");
876
+ }
877
+ const previousStateHash = ((_a = result.operations[action.scope].at(-2)) == null ? void 0 : _a.hash) ?? "";
878
+ const signature = await buildOperationSignature(
893
879
  {
894
- ...document.operations,
895
- [scope]: [
896
- ...actionsToKeepStart,
897
- {
898
- ...loadState(
899
- { name, state: newState },
900
- actionsToPrune.length
901
- ),
902
- timestamp: loadStateTimestamp,
903
- index: loadStateIndex,
904
- hash: hashDocument({ state: newState }, "global")
905
- },
906
- ...actionsToKeepEnd.map((action2, index) => ({
907
- ...action2,
908
- index: loadStateIndex + index + 1
909
- }))
910
- ]
880
+ ...context,
881
+ operation,
882
+ previousStateHash
911
883
  },
912
- wrappedReducer
884
+ signHandler
913
885
  );
914
- }
915
- function loadStateOperation(oldDocument, newDocument) {
916
886
  return {
917
- ...oldDocument,
918
- name: newDocument.name,
919
- state: newDocument.state ?? { global: {}, local: {} }
887
+ ...operation,
888
+ context: {
889
+ ...operation.context,
890
+ signer: {
891
+ ...(_b = operation.context) == null ? void 0 : _b.signer,
892
+ ...context.signer,
893
+ signatures: [...context.signer.signatures ?? [], signature]
894
+ }
895
+ }
920
896
  };
921
897
  }
922
- const SET_NAME = "SET_NAME";
923
- const UNDO = "UNDO";
924
- const REDO = "REDO";
925
- const PRUNE = "PRUNE";
926
- const LOAD_STATE = "LOAD_STATE";
927
- const NOOP = "NOOP";
898
+ async function verifyOperationSignature(signature, signer, verifyHandler) {
899
+ const publicKey = signer.app.key;
900
+ const params = signature.slice(0, 4);
901
+ const signatureBytes = hex2ab(signature[4]);
902
+ const expectedMessage = buildOperationSignatureMessage(params);
903
+ return verifyHandler(publicKey, signatureBytes, expectedMessage);
904
+ }
928
905
  const types = { "application/andrew-inset": ["ez"], "application/appinstaller": ["appinstaller"], "application/applixware": ["aw"], "application/appx": ["appx"], "application/appxbundle": ["appxbundle"], "application/atom+xml": ["atom"], "application/atomcat+xml": ["atomcat"], "application/atomdeleted+xml": ["atomdeleted"], "application/atomsvc+xml": ["atomsvc"], "application/atsc-dwd+xml": ["dwd"], "application/atsc-held+xml": ["held"], "application/atsc-rsat+xml": ["rsat"], "application/automationml-aml+xml": ["aml"], "application/automationml-amlx+zip": ["amlx"], "application/bdoc": ["bdoc"], "application/calendar+xml": ["xcs"], "application/ccxml+xml": ["ccxml"], "application/cdfx+xml": ["cdfx"], "application/cdmi-capability": ["cdmia"], "application/cdmi-container": ["cdmic"], "application/cdmi-domain": ["cdmid"], "application/cdmi-object": ["cdmio"], "application/cdmi-queue": ["cdmiq"], "application/cpl+xml": ["cpl"], "application/cu-seeme": ["cu"], "application/cwl": ["cwl"], "application/dash+xml": ["mpd"], "application/dash-patch+xml": ["mpp"], "application/davmount+xml": ["davmount"], "application/docbook+xml": ["dbk"], "application/dssc+der": ["dssc"], "application/dssc+xml": ["xdssc"], "application/ecmascript": ["ecma"], "application/emma+xml": ["emma"], "application/emotionml+xml": ["emotionml"], "application/epub+zip": ["epub"], "application/exi": ["exi"], "application/express": ["exp"], "application/fdf": ["fdf"], "application/fdt+xml": ["fdt"], "application/font-tdpfr": ["pfr"], "application/geo+json": ["geojson"], "application/gml+xml": ["gml"], "application/gpx+xml": ["gpx"], "application/gxf": ["gxf"], "application/gzip": ["gz"], "application/hjson": ["hjson"], "application/hyperstudio": ["stk"], "application/inkml+xml": ["ink", "inkml"], "application/ipfix": ["ipfix"], "application/its+xml": ["its"], "application/java-archive": ["jar", "war", "ear"], "application/java-serialized-object": ["ser"], "application/java-vm": ["class"], "application/javascript": ["*js"], "application/json": ["json", "map"], "application/json5": ["json5"], "application/jsonml+json": ["jsonml"], "application/ld+json": ["jsonld"], "application/lgr+xml": ["lgr"], "application/lost+xml": ["lostxml"], "application/mac-binhex40": ["hqx"], "application/mac-compactpro": ["cpt"], "application/mads+xml": ["mads"], "application/manifest+json": ["webmanifest"], "application/marc": ["mrc"], "application/marcxml+xml": ["mrcx"], "application/mathematica": ["ma", "nb", "mb"], "application/mathml+xml": ["mathml"], "application/mbox": ["mbox"], "application/media-policy-dataset+xml": ["mpf"], "application/mediaservercontrol+xml": ["mscml"], "application/metalink+xml": ["metalink"], "application/metalink4+xml": ["meta4"], "application/mets+xml": ["mets"], "application/mmt-aei+xml": ["maei"], "application/mmt-usd+xml": ["musd"], "application/mods+xml": ["mods"], "application/mp21": ["m21", "mp21"], "application/mp4": ["*mp4", "*mpg4", "mp4s", "m4p"], "application/msix": ["msix"], "application/msixbundle": ["msixbundle"], "application/msword": ["doc", "dot"], "application/mxf": ["mxf"], "application/n-quads": ["nq"], "application/n-triples": ["nt"], "application/node": ["cjs"], "application/octet-stream": ["bin", "dms", "lrf", "mar", "so", "dist", "distz", "pkg", "bpk", "dump", "elc", "deploy", "exe", "dll", "deb", "dmg", "iso", "img", "msi", "msp", "msm", "buffer"], "application/oda": ["oda"], "application/oebps-package+xml": ["opf"], "application/ogg": ["ogx"], "application/omdoc+xml": ["omdoc"], "application/onenote": ["onetoc", "onetoc2", "onetmp", "onepkg"], "application/oxps": ["oxps"], "application/p2p-overlay+xml": ["relo"], "application/patch-ops-error+xml": ["xer"], "application/pdf": ["pdf"], "application/pgp-encrypted": ["pgp"], "application/pgp-keys": ["asc"], "application/pgp-signature": ["sig", "*asc"], "application/pics-rules": ["prf"], "application/pkcs10": ["p10"], "application/pkcs7-mime": ["p7m", "p7c"], "application/pkcs7-signature": ["p7s"], "application/pkcs8": ["p8"], "application/pkix-attr-cert": ["ac"], "application/pkix-cert": ["cer"], "application/pkix-crl": ["crl"], "application/pkix-pkipath": ["pkipath"], "application/pkixcmp": ["pki"], "application/pls+xml": ["pls"], "application/postscript": ["ai", "eps", "ps"], "application/provenance+xml": ["provx"], "application/pskc+xml": ["pskcxml"], "application/raml+yaml": ["raml"], "application/rdf+xml": ["rdf", "owl"], "application/reginfo+xml": ["rif"], "application/relax-ng-compact-syntax": ["rnc"], "application/resource-lists+xml": ["rl"], "application/resource-lists-diff+xml": ["rld"], "application/rls-services+xml": ["rs"], "application/route-apd+xml": ["rapd"], "application/route-s-tsid+xml": ["sls"], "application/route-usd+xml": ["rusd"], "application/rpki-ghostbusters": ["gbr"], "application/rpki-manifest": ["mft"], "application/rpki-roa": ["roa"], "application/rsd+xml": ["rsd"], "application/rss+xml": ["rss"], "application/rtf": ["rtf"], "application/sbml+xml": ["sbml"], "application/scvp-cv-request": ["scq"], "application/scvp-cv-response": ["scs"], "application/scvp-vp-request": ["spq"], "application/scvp-vp-response": ["spp"], "application/sdp": ["sdp"], "application/senml+xml": ["senmlx"], "application/sensml+xml": ["sensmlx"], "application/set-payment-initiation": ["setpay"], "application/set-registration-initiation": ["setreg"], "application/shf+xml": ["shf"], "application/sieve": ["siv", "sieve"], "application/smil+xml": ["smi", "smil"], "application/sparql-query": ["rq"], "application/sparql-results+xml": ["srx"], "application/sql": ["sql"], "application/srgs": ["gram"], "application/srgs+xml": ["grxml"], "application/sru+xml": ["sru"], "application/ssdl+xml": ["ssdl"], "application/ssml+xml": ["ssml"], "application/swid+xml": ["swidtag"], "application/tei+xml": ["tei", "teicorpus"], "application/thraud+xml": ["tfi"], "application/timestamped-data": ["tsd"], "application/toml": ["toml"], "application/trig": ["trig"], "application/ttml+xml": ["ttml"], "application/ubjson": ["ubj"], "application/urc-ressheet+xml": ["rsheet"], "application/urc-targetdesc+xml": ["td"], "application/voicexml+xml": ["vxml"], "application/wasm": ["wasm"], "application/watcherinfo+xml": ["wif"], "application/widget": ["wgt"], "application/winhlp": ["hlp"], "application/wsdl+xml": ["wsdl"], "application/wspolicy+xml": ["wspolicy"], "application/xaml+xml": ["xaml"], "application/xcap-att+xml": ["xav"], "application/xcap-caps+xml": ["xca"], "application/xcap-diff+xml": ["xdf"], "application/xcap-el+xml": ["xel"], "application/xcap-ns+xml": ["xns"], "application/xenc+xml": ["xenc"], "application/xfdf": ["xfdf"], "application/xhtml+xml": ["xhtml", "xht"], "application/xliff+xml": ["xlf"], "application/xml": ["xml", "xsl", "xsd", "rng"], "application/xml-dtd": ["dtd"], "application/xop+xml": ["xop"], "application/xproc+xml": ["xpl"], "application/xslt+xml": ["*xsl", "xslt"], "application/xspf+xml": ["xspf"], "application/xv+xml": ["mxml", "xhvml", "xvml", "xvm"], "application/yang": ["yang"], "application/yin+xml": ["yin"], "application/zip": ["zip"], "audio/3gpp": ["*3gpp"], "audio/aac": ["adts", "aac"], "audio/adpcm": ["adp"], "audio/amr": ["amr"], "audio/basic": ["au", "snd"], "audio/midi": ["mid", "midi", "kar", "rmi"], "audio/mobile-xmf": ["mxmf"], "audio/mp3": ["*mp3"], "audio/mp4": ["m4a", "mp4a"], "audio/mpeg": ["mpga", "mp2", "mp2a", "mp3", "m2a", "m3a"], "audio/ogg": ["oga", "ogg", "spx", "opus"], "audio/s3m": ["s3m"], "audio/silk": ["sil"], "audio/wav": ["wav"], "audio/wave": ["*wav"], "audio/webm": ["weba"], "audio/xm": ["xm"], "font/collection": ["ttc"], "font/otf": ["otf"], "font/ttf": ["ttf"], "font/woff": ["woff"], "font/woff2": ["woff2"], "image/aces": ["exr"], "image/apng": ["apng"], "image/avci": ["avci"], "image/avcs": ["avcs"], "image/avif": ["avif"], "image/bmp": ["bmp", "dib"], "image/cgm": ["cgm"], "image/dicom-rle": ["drle"], "image/dpx": ["dpx"], "image/emf": ["emf"], "image/fits": ["fits"], "image/g3fax": ["g3"], "image/gif": ["gif"], "image/heic": ["heic"], "image/heic-sequence": ["heics"], "image/heif": ["heif"], "image/heif-sequence": ["heifs"], "image/hej2k": ["hej2"], "image/hsj2": ["hsj2"], "image/ief": ["ief"], "image/jls": ["jls"], "image/jp2": ["jp2", "jpg2"], "image/jpeg": ["jpeg", "jpg", "jpe"], "image/jph": ["jph"], "image/jphc": ["jhc"], "image/jpm": ["jpm", "jpgm"], "image/jpx": ["jpx", "jpf"], "image/jxr": ["jxr"], "image/jxra": ["jxra"], "image/jxrs": ["jxrs"], "image/jxs": ["jxs"], "image/jxsc": ["jxsc"], "image/jxsi": ["jxsi"], "image/jxss": ["jxss"], "image/ktx": ["ktx"], "image/ktx2": ["ktx2"], "image/png": ["png"], "image/sgi": ["sgi"], "image/svg+xml": ["svg", "svgz"], "image/t38": ["t38"], "image/tiff": ["tif", "tiff"], "image/tiff-fx": ["tfx"], "image/webp": ["webp"], "image/wmf": ["wmf"], "message/disposition-notification": ["disposition-notification"], "message/global": ["u8msg"], "message/global-delivery-status": ["u8dsn"], "message/global-disposition-notification": ["u8mdn"], "message/global-headers": ["u8hdr"], "message/rfc822": ["eml", "mime"], "model/3mf": ["3mf"], "model/gltf+json": ["gltf"], "model/gltf-binary": ["glb"], "model/iges": ["igs", "iges"], "model/jt": ["jt"], "model/mesh": ["msh", "mesh", "silo"], "model/mtl": ["mtl"], "model/obj": ["obj"], "model/prc": ["prc"], "model/step+xml": ["stpx"], "model/step+zip": ["stpz"], "model/step-xml+zip": ["stpxz"], "model/stl": ["stl"], "model/u3d": ["u3d"], "model/vrml": ["wrl", "vrml"], "model/x3d+binary": ["*x3db", "x3dbz"], "model/x3d+fastinfoset": ["x3db"], "model/x3d+vrml": ["*x3dv", "x3dvz"], "model/x3d+xml": ["x3d", "x3dz"], "model/x3d-vrml": ["x3dv"], "text/cache-manifest": ["appcache", "manifest"], "text/calendar": ["ics", "ifb"], "text/coffeescript": ["coffee", "litcoffee"], "text/css": ["css"], "text/csv": ["csv"], "text/html": ["html", "htm", "shtml"], "text/jade": ["jade"], "text/javascript": ["js", "mjs"], "text/jsx": ["jsx"], "text/less": ["less"], "text/markdown": ["md", "markdown"], "text/mathml": ["mml"], "text/mdx": ["mdx"], "text/n3": ["n3"], "text/plain": ["txt", "text", "conf", "def", "list", "log", "in", "ini"], "text/richtext": ["rtx"], "text/rtf": ["*rtf"], "text/sgml": ["sgml", "sgm"], "text/shex": ["shex"], "text/slim": ["slim", "slm"], "text/spdx": ["spdx"], "text/stylus": ["stylus", "styl"], "text/tab-separated-values": ["tsv"], "text/troff": ["t", "tr", "roff", "man", "me", "ms"], "text/turtle": ["ttl"], "text/uri-list": ["uri", "uris", "urls"], "text/vcard": ["vcard"], "text/vtt": ["vtt"], "text/wgsl": ["wgsl"], "text/xml": ["*xml"], "text/yaml": ["yaml", "yml"], "video/3gpp": ["3gp", "3gpp"], "video/3gpp2": ["3g2"], "video/h261": ["h261"], "video/h263": ["h263"], "video/h264": ["h264"], "video/iso.segment": ["m4s"], "video/jpeg": ["jpgv"], "video/jpm": ["*jpm", "*jpgm"], "video/mj2": ["mj2", "mjp2"], "video/mp2t": ["ts"], "video/mp4": ["mp4", "mp4v", "mpg4"], "video/mpeg": ["mpeg", "mpg", "mpe", "m1v", "m2v"], "video/ogg": ["ogv"], "video/quicktime": ["qt", "mov"], "video/webm": ["webm"] };
929
906
  Object.freeze(types);
930
907
  var __classPrivateFieldGet = function(receiver, state, kind, f) {
931
- if (kind === "a" && !f)
932
- throw new TypeError("Private accessor was defined without a getter");
933
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver))
934
- throw new TypeError("Cannot read private member from an object whose class did not declare it");
908
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
909
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
935
910
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
936
911
  };
937
912
  var _Mime_extensionToType, _Mime_typeToExtension, _Mime_typeToExtensions;
@@ -1014,48 +989,6 @@ class Mime {
1014
989
  }
1015
990
  _Mime_extensionToType = /* @__PURE__ */ new WeakMap(), _Mime_typeToExtension = /* @__PURE__ */ new WeakMap(), _Mime_typeToExtensions = /* @__PURE__ */ new WeakMap();
1016
991
  const mime = new Mime(types)._freeze();
1017
- function writeFile(path$1, name, data) {
1018
- const filePath = path.join(path$1, name);
1019
- fs.mkdirSync(path$1, { recursive: true });
1020
- return new Promise((resolve, reject) => {
1021
- try {
1022
- fs.writeFile(filePath, data, {}, (err) => {
1023
- if (err) {
1024
- reject(err);
1025
- } else {
1026
- resolve(filePath);
1027
- }
1028
- });
1029
- } catch (error) {
1030
- reject(error);
1031
- }
1032
- });
1033
- }
1034
- function readFile(path2) {
1035
- return fs.readFileSync(path2);
1036
- }
1037
- function fetchFile(url) {
1038
- return new Promise((resolve, reject) => {
1039
- https.get(url, (resp) => {
1040
- const data = [];
1041
- const mimeType = resp.headers["content-type"];
1042
- resp.on("data", (chunk) => {
1043
- data.push(chunk);
1044
- });
1045
- resp.on("end", () => {
1046
- resolve({ buffer: Buffer.concat(data), mimeType });
1047
- });
1048
- }).on("error", (err) => {
1049
- reject(err);
1050
- });
1051
- });
1052
- }
1053
- const getFile = async (file) => {
1054
- return readFile(file);
1055
- };
1056
- const hash = (data, algorithm = "sha1") => {
1057
- return crypto$1.createHash(algorithm).update(data).digest("base64");
1058
- };
1059
992
  function validateOperations(operations) {
1060
993
  const errors = [];
1061
994
  const scopes = Object.keys(operations);
@@ -1125,8 +1058,7 @@ function garbageCollect(sortedOperations) {
1125
1058
  function addUndo(sortedOperations) {
1126
1059
  const operationsCopy = [...sortedOperations];
1127
1060
  const latestOperation = operationsCopy[operationsCopy.length - 1];
1128
- if (!latestOperation)
1129
- return operationsCopy;
1061
+ if (!latestOperation) return operationsCopy;
1130
1062
  if (latestOperation.type === "NOOP") {
1131
1063
  operationsCopy.push({
1132
1064
  ...latestOperation,
@@ -1405,6 +1337,13 @@ function filterDocumentOperationsResultingState(documentOperations) {
1405
1337
  {}
1406
1338
  );
1407
1339
  }
1340
+ function diffOperations(clearedOperationsA, clearedOperationsB) {
1341
+ return clearedOperationsA.filter(
1342
+ (operationA) => !clearedOperationsB.some(
1343
+ (operationB) => operationA.index === operationB.index
1344
+ )
1345
+ );
1346
+ }
1408
1347
  const documentHelpers = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
1409
1348
  __proto__: null,
1410
1349
  IntegrityIssueSubType,
@@ -1413,6 +1352,7 @@ const documentHelpers = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.def
1413
1352
  attachBranch,
1414
1353
  checkCleanedOperationsIntegrity,
1415
1354
  checkOperationsIntegrity,
1355
+ diffOperations,
1416
1356
  filterDocumentOperationsResultingState,
1417
1357
  filterDuplicatedOperations,
1418
1358
  garbageCollect,
@@ -1561,6 +1501,141 @@ async function getLocalFile(path2) {
1561
1501
  const data = buffer.toString("base64");
1562
1502
  return { data, hash: hash(data), mimeType, ...attributes };
1563
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";
1564
1639
  function getNextRevision(document, action) {
1565
1640
  let latestOperation;
1566
1641
  if ("index" in action) {
@@ -1580,7 +1655,7 @@ function updateHeader(document, action) {
1580
1655
  lastModified: (/* @__PURE__ */ new Date()).toISOString()
1581
1656
  };
1582
1657
  }
1583
- function updateOperations(document, action, skip = 0) {
1658
+ function updateOperations(document, action, skip = 0, reuseLastOperationIndex = false) {
1584
1659
  if ([UNDO, REDO, PRUNE].includes(action.type)) {
1585
1660
  return document;
1586
1661
  }
@@ -1588,7 +1663,8 @@ function updateOperations(document, action, skip = 0) {
1588
1663
  const operations = document.operations[scope].slice();
1589
1664
  let operationId;
1590
1665
  const latestOperation = operations.at(-1);
1591
- let nextIndex = ((latestOperation == null ? void 0 : latestOperation.index) ?? -1) + 1;
1666
+ const lastOperationIndex = (latestOperation == null ? void 0 : latestOperation.index) ?? -1;
1667
+ let nextIndex = reuseLastOperationIndex ? lastOperationIndex : lastOperationIndex + 1;
1592
1668
  if ("index" in action) {
1593
1669
  if (action.index - skip > nextIndex) {
1594
1670
  throw new Error(
@@ -1598,7 +1674,7 @@ function updateOperations(document, action, skip = 0) {
1598
1674
  nextIndex = action.index;
1599
1675
  operationId = action.id;
1600
1676
  } else {
1601
- operationId = v4();
1677
+ operationId = "id" in action ? action.id : v4();
1602
1678
  }
1603
1679
  operations.push({
1604
1680
  ...action,
@@ -1615,8 +1691,13 @@ function updateOperations(document, action, skip = 0) {
1615
1691
  operations: { ...document.operations, [scope]: operations }
1616
1692
  };
1617
1693
  }
1618
- function updateDocument(document, action, skip = 0) {
1619
- let newDocument = updateOperations(document, action, skip);
1694
+ function updateDocument(document, action, skip = 0, reuseLastOperationIndex = false) {
1695
+ let newDocument = updateOperations(
1696
+ document,
1697
+ action,
1698
+ skip,
1699
+ reuseLastOperationIndex
1700
+ );
1620
1701
  newDocument = updateHeader(newDocument, action);
1621
1702
  return newDocument;
1622
1703
  }
@@ -1640,14 +1721,13 @@ function processUndoRedo(document, action, skip) {
1640
1721
  case REDO:
1641
1722
  return redoOperation(document, action, skip);
1642
1723
  default:
1643
- return { document, action, skip };
1724
+ return { document, action, skip, reuseLastOperationIndex: false };
1644
1725
  }
1645
1726
  }
1646
1727
  function processSkipOperation(document, action, customReducer, skipValue, reuseOperationResultingState = false, resultingStateParser = parseResultingState) {
1647
1728
  const scope = action.scope;
1648
1729
  const latestOperation = document.operations[scope].at(-1);
1649
- if (!latestOperation)
1650
- return document;
1730
+ if (!latestOperation) return document;
1651
1731
  const documentOperations = garbageCollectDocumentOperations(
1652
1732
  {
1653
1733
  ...document.operations,
@@ -1691,6 +1771,37 @@ function processSkipOperation(document, action, customReducer, skipValue, reuseO
1691
1771
  })
1692
1772
  };
1693
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
+ }
1694
1805
  function baseReducer(document, action, customReducer, dispatch, options = {}) {
1695
1806
  const {
1696
1807
  skip,
@@ -1699,14 +1810,46 @@ function baseReducer(document, action, customReducer, dispatch, options = {}) {
1699
1810
  reuseOperationResultingState = false,
1700
1811
  operationResultingStateParser
1701
1812
  } = options;
1702
- const _action = { ...action };
1703
- const skipValue = skip || 0;
1813
+ let _action = { ...action };
1814
+ let skipValue = skip || 0;
1704
1815
  let newDocument = { ...document };
1816
+ let reuseLastOperationIndex = false;
1705
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
+ }
1706
1835
  if (isBaseAction(_action)) {
1707
1836
  newDocument = _baseReducer(newDocument, _action, customReducer);
1708
1837
  }
1709
- newDocument = updateDocument(newDocument, _action, skipValue);
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
+ }
1710
1853
  if (shouldProcessSkipOperation) {
1711
1854
  newDocument = processSkipOperation(
1712
1855
  newDocument,
@@ -1846,6 +1989,9 @@ function isNoopOperation(op) {
1846
1989
  function isUndoRedo(action) {
1847
1990
  return [UNDO, REDO].includes(action.type);
1848
1991
  }
1992
+ function isUndo(action) {
1993
+ return action.type === UNDO;
1994
+ }
1849
1995
  function isBaseAction(action) {
1850
1996
  return [SET_NAME, UNDO, REDO, PRUNE, LOAD_STATE].includes(action.type);
1851
1997
  }
@@ -1941,23 +2087,6 @@ function mapSkippedOperations(operations, skippedHeadOperations) {
1941
2087
  }
1942
2088
  return scopeOpsWithIgnore.reverse();
1943
2089
  }
1944
- function calculateSkipsLeft(operations, currentIndex, skip) {
1945
- const sortedOperations = operations.slice().sort((a, b) => a.skip - b.skip).sort((a, b) => a.index - b.index);
1946
- let skipsLeft = skip;
1947
- let skipsToPerform = 0;
1948
- let lastIndex = currentIndex;
1949
- for (const operation of sortedOperations.reverse()) {
1950
- const distance = lastIndex - operation.index;
1951
- skipsLeft = skipsLeft - distance;
1952
- if (skipsLeft > -1) {
1953
- skipsToPerform++;
1954
- lastIndex = operation.index;
1955
- } else {
1956
- break;
1957
- }
1958
- }
1959
- return skipsToPerform;
1960
- }
1961
2090
  function sortOperations(operations) {
1962
2091
  return Object.values(operations).flatMap((array) => array).sort(
1963
2092
  (a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime()
@@ -2324,9 +2453,13 @@ function applyMixins(derivedCtor, constructors) {
2324
2453
  }
2325
2454
  exports.BaseActions = BaseActions;
2326
2455
  exports.BaseDocument = BaseDocument;
2456
+ exports.ab2hex = ab2hex;
2327
2457
  exports.applyMixins = applyMixins;
2328
2458
  exports.baseReducer = baseReducer;
2329
- exports.calculateSkipsLeft = calculateSkipsLeft;
2459
+ exports.buildOperationSignature = buildOperationSignature;
2460
+ exports.buildOperationSignatureMessage = buildOperationSignatureMessage;
2461
+ exports.buildOperationSignatureParams = buildOperationSignatureParams;
2462
+ exports.buildSignedOperation = buildSignedOperation;
2330
2463
  exports.createAction = createAction;
2331
2464
  exports.createDocument = createDocument;
2332
2465
  exports.createExtendedState = createExtendedState;
@@ -2336,11 +2469,14 @@ exports.createZip = createZip;
2336
2469
  exports.documentHelpers = documentHelpers;
2337
2470
  exports.getLocalFile = getLocalFile;
2338
2471
  exports.getRemoteFile = getRemoteFile;
2472
+ exports.getUnixTimestamp = getUnixTimestamp;
2339
2473
  exports.hashDocument = hashDocument;
2340
2474
  exports.hashKey = hashKey;
2475
+ exports.hex2ab = hex2ab;
2341
2476
  exports.isBaseAction = isBaseAction;
2342
2477
  exports.isNoopOperation = isNoopOperation;
2343
2478
  exports.isSameDocument = isSameDocument;
2479
+ exports.isUndo = isUndo;
2344
2480
  exports.isUndoRedo = isUndoRedo;
2345
2481
  exports.loadFromFile = loadFromFile;
2346
2482
  exports.loadFromInput = loadFromInput;
@@ -2358,5 +2494,6 @@ exports.sortOperations = sortOperations;
2358
2494
  exports.updateDocument = updateDocument;
2359
2495
  exports.updateHeader = updateHeader;
2360
2496
  exports.validateOperations = validateOperations;
2497
+ exports.verifyOperationSignature = verifyOperationSignature;
2361
2498
  exports.zod = zod;
2362
- //# sourceMappingURL=object-op6YzhH1.js.map
2499
+ //# sourceMappingURL=object-BMOaYPkd.js.map