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,16 +1,13 @@
1
1
  var __defProp = Object.defineProperty;
2
2
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
- var __publicField = (obj, key, value) => {
4
- __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
5
- return value;
6
- };
3
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
7
4
  import { create, castDraft, unsafe } from "mutative";
8
5
  import { z } from "zod";
9
- import JSZip from "jszip";
10
6
  import crypto$1 from "crypto";
11
7
  import fs from "fs";
12
8
  import https from "https";
13
9
  import { join } from "path";
10
+ import JSZip from "jszip";
14
11
  const isDefinedNonNullAny = (v) => v !== void 0 && v !== null;
15
12
  const definedNonNullAnySchema = z.any().refine((v) => isDefinedNonNullAny(v));
16
13
  const Load_StateSchema = z.enum(["LOAD_STATE"]);
@@ -160,16 +157,16 @@ var safeStableStringify = { exports: {} };
160
157
  exports.stringify = stringify;
161
158
  exports.configure = configure;
162
159
  module.exports = stringify;
163
- const strEscapeSequencesRegExp = /[\u0000-\u001f\u0022\u005c\ud800-\udfff]|[\ud800-\udbff](?![\udc00-\udfff])|(?:[^\ud800-\udbff]|^)[\udc00-\udfff]/;
160
+ const strEscapeSequencesRegExp = /[\u0000-\u001f\u0022\u005c\ud800-\udfff]/;
164
161
  function strEscape(str) {
165
162
  if (str.length < 5e3 && !strEscapeSequencesRegExp.test(str)) {
166
163
  return `"${str}"`;
167
164
  }
168
165
  return JSON.stringify(str);
169
166
  }
170
- function insertSort(array) {
171
- if (array.length > 200) {
172
- return array.sort();
167
+ function sort(array, comparator) {
168
+ if (array.length > 200 || comparator) {
169
+ return array.sort(comparator);
173
170
  }
174
171
  for (let i = 1; i < array.length; i++) {
175
172
  const currentValue = array[i];
@@ -224,6 +221,16 @@ var safeStableStringify = { exports: {} };
224
221
  }
225
222
  return '"[Circular]"';
226
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
+ }
227
234
  function getBooleanOption(options, key) {
228
235
  let value;
229
236
  if (hasOwnProperty.call(options, key)) {
@@ -274,8 +281,7 @@ var safeStableStringify = { exports: {} };
274
281
  if (value) {
275
282
  return (value2) => {
276
283
  let message = `Object can not safely be stringified. Received type ${typeof value2}`;
277
- if (typeof value2 !== "function")
278
- message += ` (${value2.toString()})`;
284
+ if (typeof value2 !== "function") message += ` (${value2.toString()})`;
279
285
  throw new Error(message);
280
286
  };
281
287
  }
@@ -294,7 +300,8 @@ var safeStableStringify = { exports: {} };
294
300
  }
295
301
  const circularValue = getCircularValueOption(options);
296
302
  const bigint = getBooleanOption(options, "bigint");
297
- const deterministic = getBooleanOption(options, "deterministic");
303
+ const deterministic = getDeterministicOption(options);
304
+ const comparator = typeof deterministic === "function" ? deterministic : void 0;
298
305
  const maximumDepth = getPositiveIntegerOption(options, "maximumDepth");
299
306
  const maximumBreadth = getPositiveIntegerOption(options, "maximumBreadth");
300
307
  function stringifyFnReplacer(key, parent, stack, replacer, spacer, indentation) {
@@ -369,7 +376,7 @@ ${indentation}`;
369
376
  }
370
377
  const maximumPropertiesToStringify = Math.min(keyLength, maximumBreadth);
371
378
  if (deterministic && !isTypedArrayWithEntries(value)) {
372
- keys = insertSort(keys);
379
+ keys = sort(keys, comparator);
373
380
  }
374
381
  stack.push(value);
375
382
  for (let i = 0; i < maximumPropertiesToStringify; i++) {
@@ -570,7 +577,7 @@ ${indentation}`;
570
577
  separator = join2;
571
578
  }
572
579
  if (deterministic) {
573
- keys = insertSort(keys);
580
+ keys = sort(keys, comparator);
574
581
  }
575
582
  stack.push(value);
576
583
  for (let i = 0; i < maximumPropertiesToStringify; i++) {
@@ -629,7 +636,8 @@ ${originalIndentation}`;
629
636
  return circularValue;
630
637
  }
631
638
  let res = "";
632
- if (Array.isArray(value)) {
639
+ const hasLength = value.length !== void 0;
640
+ if (hasLength && Array.isArray(value)) {
633
641
  if (value.length === 0) {
634
642
  return "[]";
635
643
  }
@@ -663,14 +671,14 @@ ${originalIndentation}`;
663
671
  }
664
672
  let separator = "";
665
673
  let maximumPropertiesToStringify = Math.min(keyLength, maximumBreadth);
666
- if (isTypedArrayWithEntries(value)) {
674
+ if (hasLength && isTypedArrayWithEntries(value)) {
667
675
  res += stringifyTypedArray(value, ",", maximumBreadth);
668
676
  keys = keys.slice(value.length);
669
677
  maximumPropertiesToStringify -= value.length;
670
678
  separator = ",";
671
679
  }
672
680
  if (deterministic) {
673
- keys = insertSort(keys);
681
+ keys = sort(keys, comparator);
674
682
  }
675
683
  stack.push(value);
676
684
  for (let i = 0; i < maximumPropertiesToStringify; i++) {
@@ -762,175 +770,142 @@ function v4(options, buf, offset) {
762
770
  rnds[8] = rnds[8] & 63 | 128;
763
771
  return unsafeStringify(rnds);
764
772
  }
765
- function setNameOperation(document, name) {
766
- return { ...document, name };
767
- }
768
- function undoOperation(document, action, skip) {
769
- const { scope, input } = action;
770
- const defaultResult = {
771
- document,
772
- action,
773
- skip
774
- };
775
- return create(defaultResult, (draft) => {
776
- if (draft.document.operations[scope].length < 1) {
777
- throw new Error(
778
- `Cannot undo: no operations in history for scope "${scope}"`
779
- );
780
- }
781
- if (input < 1) {
782
- throw new Error(
783
- `Invalid UNDO action: input value must be greater than 0`
784
- );
785
- }
786
- if (draft.skip > 0) {
787
- throw new Error(
788
- `Cannot undo: skip value from reducer cannot be used with UNDO action`
789
- );
790
- }
791
- const lastOperation = draft.document.operations[scope].at(-1);
792
- const isLatestOpNOOP = lastOperation && lastOperation.type === "NOOP" && lastOperation.skip > 0;
793
- draft.skip += input;
794
- if (isLatestOpNOOP) {
795
- draft.skip += lastOperation.skip;
796
- const preLastOperation = draft.document.operations[scope][draft.document.operations[scope].length - 2];
797
- if (preLastOperation && lastOperation.index - preLastOperation.index === 1) {
798
- draft.document.operations[scope].pop();
799
- }
800
- }
801
- if (draft.document.operations[scope].length < draft.skip) {
802
- throw new Error(
803
- `Cannot undo: you can't undo more operations than the ones in the scope history`
804
- );
805
- }
806
- const operationsLastIndex = draft.document.operations[scope].length - 1;
807
- let skippedOpsLeft = input;
808
- let index = isLatestOpNOOP ? operationsLastIndex - lastOperation.skip : operationsLastIndex;
809
- while (skippedOpsLeft > 0 && index >= 0) {
810
- const op = draft.document.operations[scope][index];
811
- if (!op) {
812
- skippedOpsLeft--;
813
- index--;
814
- continue;
815
- }
816
- if (op.type === "NOOP" && op.skip > 0) {
817
- index = index - (op.skip + 1);
818
- draft.skip += op.skip + 1;
819
- } else {
820
- draft.document.clipboard.push({ ...op });
821
- skippedOpsLeft--;
822
- index--;
823
- }
773
+ function writeFile(path, name, data) {
774
+ const filePath = join(path, name);
775
+ fs.mkdirSync(path, { recursive: true });
776
+ return new Promise((resolve, reject) => {
777
+ try {
778
+ fs.writeFile(filePath, data, {}, (err) => {
779
+ if (err) {
780
+ reject(err);
781
+ } else {
782
+ resolve(filePath);
783
+ }
784
+ });
785
+ } catch (error) {
786
+ reject(error);
824
787
  }
825
- draft.action = noop(scope);
826
788
  });
827
789
  }
828
- function redoOperation(document, action, skip) {
829
- const { scope, input } = action;
830
- const defaultResult = {
831
- document,
832
- action,
833
- skip
834
- };
835
- return create(defaultResult, (draft) => {
836
- if (draft.skip > 0) {
837
- throw new Error(
838
- `Cannot redo: skip value from reducer cannot be used with REDO action`
839
- );
840
- }
841
- if (input > 1) {
842
- throw new Error(
843
- `Cannot redo: you can only redo one operation at a time`
844
- );
845
- }
846
- if (input < 1) {
847
- throw new Error(`Invalid REDO action: invalid redo input value`);
848
- }
849
- if (draft.document.clipboard.length < 1) {
850
- throw new Error(`Cannot redo: no operations in the clipboard`);
851
- }
852
- const operationIndex = draft.document.clipboard.findLastIndex(
853
- (op) => op.scope === scope
854
- );
855
- if (operationIndex < 0) {
856
- throw new Error(
857
- `Cannot redo: no operations in clipboard for scope "${scope}"`
858
- );
859
- }
860
- const operation = draft.document.clipboard.splice(operationIndex, 1)[0];
861
- draft.action = castDraft({
862
- type: operation.type,
863
- scope: operation.scope,
864
- input: operation.input
790
+ function readFile(path) {
791
+ return fs.readFileSync(path);
792
+ }
793
+ function fetchFile(url) {
794
+ return new Promise((resolve, reject) => {
795
+ https.get(url, (resp) => {
796
+ const data = [];
797
+ const mimeType = resp.headers["content-type"];
798
+ resp.on("data", (chunk) => {
799
+ data.push(chunk);
800
+ });
801
+ resp.on("end", () => {
802
+ resolve({ buffer: Buffer.concat(data), mimeType });
803
+ });
804
+ }).on("error", (err) => {
805
+ reject(err);
865
806
  });
866
807
  });
867
808
  }
868
- function pruneOperation(document, action, wrappedReducer) {
869
- const { scope } = action;
870
- const operations = document.operations[scope];
871
- let {
872
- input: { start, end }
873
- } = action;
874
- start = start || 0;
875
- end = end || operations.length;
876
- const actionsToPrune = operations.slice(start, end);
877
- const actionsToKeepStart = operations.slice(0, start);
878
- const actionsToKeepEnd = operations.slice(end);
879
- const newDocument = replayOperations(
880
- document.initialState,
881
- {
882
- ...document.operations,
883
- [scope]: actionsToKeepStart.concat(actionsToPrune)
884
- },
885
- wrappedReducer
809
+ const getFile = async (file) => {
810
+ return readFile(file);
811
+ };
812
+ const hash = (data, algorithm = "sha1") => {
813
+ return crypto$1.createHash(algorithm).update(data).digest("base64");
814
+ };
815
+ function getUnixTimestamp(date) {
816
+ return (new Date(date).getTime() / 1e3).toFixed(0);
817
+ }
818
+ function buildOperationSignatureParams({
819
+ documentId,
820
+ signer,
821
+ operation,
822
+ previousStateHash
823
+ }) {
824
+ const { timestamp, scope, id, type } = operation;
825
+ return [
826
+ getUnixTimestamp(timestamp),
827
+ // timestamp,
828
+ signer.app.key,
829
+ // signer public key
830
+ hash(
831
+ // hash (docID, scope, operationID, operationName, operationInput)
832
+ [documentId, scope, id, type, cjsModule(operation.input)].join(
833
+ ""
834
+ )
835
+ ),
836
+ previousStateHash
837
+ // state hash that the operation was applied to
838
+ ];
839
+ }
840
+ const textEncode = new TextEncoder();
841
+ function buildOperationSignatureMessage(params) {
842
+ const message = params.join("");
843
+ const prefix = "Signed Operation:\n" + message.length.toString();
844
+ return textEncode.encode(prefix + message);
845
+ }
846
+ function ab2hex(ab) {
847
+ return Array.prototype.map.call(
848
+ new Uint8Array(ab),
849
+ (x) => ("00" + x.toString(16)).slice(-2)
850
+ ).join("");
851
+ }
852
+ function hex2ab(hex) {
853
+ var _a;
854
+ return new Uint8Array(
855
+ ((_a = hex.match(/[\da-f]{2}/gi)) == null ? void 0 : _a.map(function(h) {
856
+ return parseInt(h, 16);
857
+ })) ?? []
886
858
  );
887
- const { name, state: newState } = newDocument;
888
- const loadStateIndex = actionsToKeepStart.length;
889
- const loadStateTimestamp = actionsToKeepStart.length ? actionsToKeepStart[actionsToKeepStart.length - 1].timestamp : actionsToKeepEnd.length ? actionsToKeepEnd[0].timestamp : (/* @__PURE__ */ new Date()).toISOString();
890
- return replayOperations(
891
- document.initialState,
859
+ }
860
+ async function buildOperationSignature(context, signMethod) {
861
+ const params = buildOperationSignatureParams(context);
862
+ const message = buildOperationSignatureMessage(params);
863
+ const signature = await signMethod(message);
864
+ return [...params, `0x${ab2hex(signature)}`];
865
+ }
866
+ async function buildSignedOperation(action, reducer, document, context, signHandler) {
867
+ var _a, _b;
868
+ const result = reducer(document, action, void 0, {
869
+ reuseHash: true,
870
+ reuseOperationResultingState: true
871
+ });
872
+ const operation = result.operations[action.scope].at(-1);
873
+ if (!operation) {
874
+ throw new Error("Action was not applied");
875
+ }
876
+ const previousStateHash = ((_a = result.operations[action.scope].at(-2)) == null ? void 0 : _a.hash) ?? "";
877
+ const signature = await buildOperationSignature(
892
878
  {
893
- ...document.operations,
894
- [scope]: [
895
- ...actionsToKeepStart,
896
- {
897
- ...loadState(
898
- { name, state: newState },
899
- actionsToPrune.length
900
- ),
901
- timestamp: loadStateTimestamp,
902
- index: loadStateIndex,
903
- hash: hashDocument({ state: newState }, "global")
904
- },
905
- ...actionsToKeepEnd.map((action2, index) => ({
906
- ...action2,
907
- index: loadStateIndex + index + 1
908
- }))
909
- ]
879
+ ...context,
880
+ operation,
881
+ previousStateHash
910
882
  },
911
- wrappedReducer
883
+ signHandler
912
884
  );
913
- }
914
- function loadStateOperation(oldDocument, newDocument) {
915
885
  return {
916
- ...oldDocument,
917
- name: newDocument.name,
918
- state: newDocument.state ?? { global: {}, local: {} }
886
+ ...operation,
887
+ context: {
888
+ ...operation.context,
889
+ signer: {
890
+ ...(_b = operation.context) == null ? void 0 : _b.signer,
891
+ ...context.signer,
892
+ signatures: [...context.signer.signatures ?? [], signature]
893
+ }
894
+ }
919
895
  };
920
896
  }
921
- const SET_NAME = "SET_NAME";
922
- const UNDO = "UNDO";
923
- const REDO = "REDO";
924
- const PRUNE = "PRUNE";
925
- const LOAD_STATE = "LOAD_STATE";
926
- const NOOP = "NOOP";
897
+ async function verifyOperationSignature(signature, signer, verifyHandler) {
898
+ const publicKey = signer.app.key;
899
+ const params = signature.slice(0, 4);
900
+ const signatureBytes = hex2ab(signature[4]);
901
+ const expectedMessage = buildOperationSignatureMessage(params);
902
+ return verifyHandler(publicKey, signatureBytes, expectedMessage);
903
+ }
927
904
  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"] };
928
905
  Object.freeze(types);
929
906
  var __classPrivateFieldGet = function(receiver, state, kind, f) {
930
- if (kind === "a" && !f)
931
- throw new TypeError("Private accessor was defined without a getter");
932
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver))
933
- throw new TypeError("Cannot read private member from an object whose class did not declare it");
907
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
908
+ 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");
934
909
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
935
910
  };
936
911
  var _Mime_extensionToType, _Mime_typeToExtension, _Mime_typeToExtensions;
@@ -1013,48 +988,6 @@ class Mime {
1013
988
  }
1014
989
  _Mime_extensionToType = /* @__PURE__ */ new WeakMap(), _Mime_typeToExtension = /* @__PURE__ */ new WeakMap(), _Mime_typeToExtensions = /* @__PURE__ */ new WeakMap();
1015
990
  const mime = new Mime(types)._freeze();
1016
- function writeFile(path, name, data) {
1017
- const filePath = join(path, name);
1018
- fs.mkdirSync(path, { recursive: true });
1019
- return new Promise((resolve, reject) => {
1020
- try {
1021
- fs.writeFile(filePath, data, {}, (err) => {
1022
- if (err) {
1023
- reject(err);
1024
- } else {
1025
- resolve(filePath);
1026
- }
1027
- });
1028
- } catch (error) {
1029
- reject(error);
1030
- }
1031
- });
1032
- }
1033
- function readFile(path) {
1034
- return fs.readFileSync(path);
1035
- }
1036
- function fetchFile(url) {
1037
- return new Promise((resolve, reject) => {
1038
- https.get(url, (resp) => {
1039
- const data = [];
1040
- const mimeType = resp.headers["content-type"];
1041
- resp.on("data", (chunk) => {
1042
- data.push(chunk);
1043
- });
1044
- resp.on("end", () => {
1045
- resolve({ buffer: Buffer.concat(data), mimeType });
1046
- });
1047
- }).on("error", (err) => {
1048
- reject(err);
1049
- });
1050
- });
1051
- }
1052
- const getFile = async (file) => {
1053
- return readFile(file);
1054
- };
1055
- const hash = (data, algorithm = "sha1") => {
1056
- return crypto$1.createHash(algorithm).update(data).digest("base64");
1057
- };
1058
991
  function validateOperations(operations) {
1059
992
  const errors = [];
1060
993
  const scopes = Object.keys(operations);
@@ -1124,8 +1057,7 @@ function garbageCollect(sortedOperations) {
1124
1057
  function addUndo(sortedOperations) {
1125
1058
  const operationsCopy = [...sortedOperations];
1126
1059
  const latestOperation = operationsCopy[operationsCopy.length - 1];
1127
- if (!latestOperation)
1128
- return operationsCopy;
1060
+ if (!latestOperation) return operationsCopy;
1129
1061
  if (latestOperation.type === "NOOP") {
1130
1062
  operationsCopy.push({
1131
1063
  ...latestOperation,
@@ -1404,6 +1336,13 @@ function filterDocumentOperationsResultingState(documentOperations) {
1404
1336
  {}
1405
1337
  );
1406
1338
  }
1339
+ function diffOperations(clearedOperationsA, clearedOperationsB) {
1340
+ return clearedOperationsA.filter(
1341
+ (operationA) => !clearedOperationsB.some(
1342
+ (operationB) => operationA.index === operationB.index
1343
+ )
1344
+ );
1345
+ }
1407
1346
  const documentHelpers = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
1408
1347
  __proto__: null,
1409
1348
  IntegrityIssueSubType,
@@ -1412,6 +1351,7 @@ const documentHelpers = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.def
1412
1351
  attachBranch,
1413
1352
  checkCleanedOperationsIntegrity,
1414
1353
  checkOperationsIntegrity,
1354
+ diffOperations,
1415
1355
  filterDocumentOperationsResultingState,
1416
1356
  filterDuplicatedOperations,
1417
1357
  garbageCollect,
@@ -1560,6 +1500,141 @@ async function getLocalFile(path) {
1560
1500
  const data = buffer.toString("base64");
1561
1501
  return { data, hash: hash(data), mimeType, ...attributes };
1562
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";
1563
1638
  function getNextRevision(document, action) {
1564
1639
  let latestOperation;
1565
1640
  if ("index" in action) {
@@ -1579,7 +1654,7 @@ function updateHeader(document, action) {
1579
1654
  lastModified: (/* @__PURE__ */ new Date()).toISOString()
1580
1655
  };
1581
1656
  }
1582
- function updateOperations(document, action, skip = 0) {
1657
+ function updateOperations(document, action, skip = 0, reuseLastOperationIndex = false) {
1583
1658
  if ([UNDO, REDO, PRUNE].includes(action.type)) {
1584
1659
  return document;
1585
1660
  }
@@ -1587,7 +1662,8 @@ function updateOperations(document, action, skip = 0) {
1587
1662
  const operations = document.operations[scope].slice();
1588
1663
  let operationId;
1589
1664
  const latestOperation = operations.at(-1);
1590
- let nextIndex = ((latestOperation == null ? void 0 : latestOperation.index) ?? -1) + 1;
1665
+ const lastOperationIndex = (latestOperation == null ? void 0 : latestOperation.index) ?? -1;
1666
+ let nextIndex = reuseLastOperationIndex ? lastOperationIndex : lastOperationIndex + 1;
1591
1667
  if ("index" in action) {
1592
1668
  if (action.index - skip > nextIndex) {
1593
1669
  throw new Error(
@@ -1597,7 +1673,7 @@ function updateOperations(document, action, skip = 0) {
1597
1673
  nextIndex = action.index;
1598
1674
  operationId = action.id;
1599
1675
  } else {
1600
- operationId = v4();
1676
+ operationId = "id" in action ? action.id : v4();
1601
1677
  }
1602
1678
  operations.push({
1603
1679
  ...action,
@@ -1614,8 +1690,13 @@ function updateOperations(document, action, skip = 0) {
1614
1690
  operations: { ...document.operations, [scope]: operations }
1615
1691
  };
1616
1692
  }
1617
- function updateDocument(document, action, skip = 0) {
1618
- let newDocument = updateOperations(document, action, skip);
1693
+ function updateDocument(document, action, skip = 0, reuseLastOperationIndex = false) {
1694
+ let newDocument = updateOperations(
1695
+ document,
1696
+ action,
1697
+ skip,
1698
+ reuseLastOperationIndex
1699
+ );
1619
1700
  newDocument = updateHeader(newDocument, action);
1620
1701
  return newDocument;
1621
1702
  }
@@ -1639,14 +1720,13 @@ function processUndoRedo(document, action, skip) {
1639
1720
  case REDO:
1640
1721
  return redoOperation(document, action, skip);
1641
1722
  default:
1642
- return { document, action, skip };
1723
+ return { document, action, skip, reuseLastOperationIndex: false };
1643
1724
  }
1644
1725
  }
1645
1726
  function processSkipOperation(document, action, customReducer, skipValue, reuseOperationResultingState = false, resultingStateParser = parseResultingState) {
1646
1727
  const scope = action.scope;
1647
1728
  const latestOperation = document.operations[scope].at(-1);
1648
- if (!latestOperation)
1649
- return document;
1729
+ if (!latestOperation) return document;
1650
1730
  const documentOperations = garbageCollectDocumentOperations(
1651
1731
  {
1652
1732
  ...document.operations,
@@ -1690,6 +1770,37 @@ function processSkipOperation(document, action, customReducer, skipValue, reuseO
1690
1770
  })
1691
1771
  };
1692
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
+ }
1693
1804
  function baseReducer(document, action, customReducer, dispatch, options = {}) {
1694
1805
  const {
1695
1806
  skip,
@@ -1698,14 +1809,46 @@ function baseReducer(document, action, customReducer, dispatch, options = {}) {
1698
1809
  reuseOperationResultingState = false,
1699
1810
  operationResultingStateParser
1700
1811
  } = options;
1701
- const _action = { ...action };
1702
- const skipValue = skip || 0;
1812
+ let _action = { ...action };
1813
+ let skipValue = skip || 0;
1703
1814
  let newDocument = { ...document };
1815
+ let reuseLastOperationIndex = false;
1704
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
+ }
1705
1834
  if (isBaseAction(_action)) {
1706
1835
  newDocument = _baseReducer(newDocument, _action, customReducer);
1707
1836
  }
1708
- newDocument = updateDocument(newDocument, _action, skipValue);
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
+ }
1709
1852
  if (shouldProcessSkipOperation) {
1710
1853
  newDocument = processSkipOperation(
1711
1854
  newDocument,
@@ -1845,6 +1988,9 @@ function isNoopOperation(op) {
1845
1988
  function isUndoRedo(action) {
1846
1989
  return [UNDO, REDO].includes(action.type);
1847
1990
  }
1991
+ function isUndo(action) {
1992
+ return action.type === UNDO;
1993
+ }
1848
1994
  function isBaseAction(action) {
1849
1995
  return [SET_NAME, UNDO, REDO, PRUNE, LOAD_STATE].includes(action.type);
1850
1996
  }
@@ -1940,23 +2086,6 @@ function mapSkippedOperations(operations, skippedHeadOperations) {
1940
2086
  }
1941
2087
  return scopeOpsWithIgnore.reverse();
1942
2088
  }
1943
- function calculateSkipsLeft(operations, currentIndex, skip) {
1944
- const sortedOperations = operations.slice().sort((a, b) => a.skip - b.skip).sort((a, b) => a.index - b.index);
1945
- let skipsLeft = skip;
1946
- let skipsToPerform = 0;
1947
- let lastIndex = currentIndex;
1948
- for (const operation of sortedOperations.reverse()) {
1949
- const distance = lastIndex - operation.index;
1950
- skipsLeft = skipsLeft - distance;
1951
- if (skipsLeft > -1) {
1952
- skipsToPerform++;
1953
- lastIndex = operation.index;
1954
- } else {
1955
- break;
1956
- }
1957
- }
1958
- return skipsToPerform;
1959
- }
1960
2089
  function sortOperations(operations) {
1961
2090
  return Object.values(operations).flatMap((array) => array).sort(
1962
2091
  (a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime()
@@ -2322,17 +2451,25 @@ function applyMixins(derivedCtor, constructors) {
2322
2451
  });
2323
2452
  }
2324
2453
  export {
2325
- replayOperations as A,
2454
+ isSameDocument as A,
2326
2455
  BaseDocument as B,
2327
- sortMappedOperations as C,
2328
- sortOperations as D,
2329
- validateOperations as E,
2330
- baseReducer as F,
2331
- mutableBaseReducer as G,
2332
- processUndoRedo as H,
2333
- updateDocument as I,
2334
- updateHeader as J,
2335
- zod as K,
2456
+ isUndo as C,
2457
+ isUndoRedo as D,
2458
+ mapSkippedOperations as E,
2459
+ parseResultingState as F,
2460
+ readOnly as G,
2461
+ replayDocument as H,
2462
+ replayOperations as I,
2463
+ sortMappedOperations as J,
2464
+ sortOperations as K,
2465
+ validateOperations as L,
2466
+ verifyOperationSignature as M,
2467
+ baseReducer as N,
2468
+ mutableBaseReducer as O,
2469
+ processUndoRedo as P,
2470
+ updateDocument as Q,
2471
+ updateHeader as R,
2472
+ zod as S,
2336
2473
  createExtendedState as a,
2337
2474
  createDocument as b,
2338
2475
  createReducer as c,
@@ -2342,22 +2479,22 @@ export {
2342
2479
  applyMixins as g,
2343
2480
  BaseActions as h,
2344
2481
  isBaseAction as i,
2345
- calculateSkipsLeft as j,
2346
- createUnsafeReducer as k,
2482
+ ab2hex as j,
2483
+ buildOperationSignature as k,
2347
2484
  loadFromFile as l,
2348
- createZip as m,
2349
- documentHelpers as n,
2350
- getLocalFile as o,
2351
- getRemoteFile as p,
2352
- hashDocument as q,
2353
- hashKey as r,
2485
+ buildOperationSignatureMessage as m,
2486
+ buildOperationSignatureParams as n,
2487
+ buildSignedOperation as o,
2488
+ createUnsafeReducer as p,
2489
+ createZip as q,
2490
+ documentHelpers as r,
2354
2491
  saveToFile as s,
2355
- isNoopOperation as t,
2356
- isSameDocument as u,
2357
- isUndoRedo as v,
2358
- mapSkippedOperations as w,
2359
- parseResultingState as x,
2360
- readOnly as y,
2361
- replayDocument as z
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
2362
2499
  };
2363
- //# sourceMappingURL=object-BuK9PFjs.js.map
2500
+ //# sourceMappingURL=object-COSf2HUT.js.map