document-model 6.0.0-dev.104 → 6.0.0-dev.106

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 (289) hide show
  1. package/dist/index.d.ts +81 -0
  2. package/dist/index.d.ts.map +1 -0
  3. package/dist/index.js +216 -0
  4. package/dist/index.js.map +1 -0
  5. package/dist/{src/core/node.d.ts → node.d.mts} +25 -23
  6. package/dist/node.d.mts.map +1 -0
  7. package/dist/node.mjs +151 -0
  8. package/dist/node.mjs.map +1 -0
  9. package/package.json +11 -15
  10. package/dist/src/core/actions.d.ts +0 -87
  11. package/dist/src/core/actions.d.ts.map +0 -1
  12. package/dist/src/core/actions.js +0 -187
  13. package/dist/src/core/actions.js.map +0 -1
  14. package/dist/src/core/controller.d.ts +0 -30
  15. package/dist/src/core/controller.d.ts.map +0 -1
  16. package/dist/src/core/controller.js +0 -60
  17. package/dist/src/core/controller.js.map +0 -1
  18. package/dist/src/core/crypto.d.ts +0 -8
  19. package/dist/src/core/crypto.d.ts.map +0 -1
  20. package/dist/src/core/crypto.js +0 -68
  21. package/dist/src/core/crypto.js.map +0 -1
  22. package/dist/src/core/documents.d.ts +0 -147
  23. package/dist/src/core/documents.d.ts.map +0 -1
  24. package/dist/src/core/documents.js +0 -845
  25. package/dist/src/core/documents.js.map +0 -1
  26. package/dist/src/core/errors.d.ts +0 -21
  27. package/dist/src/core/errors.d.ts.map +0 -1
  28. package/dist/src/core/errors.js +0 -46
  29. package/dist/src/core/errors.js.map +0 -1
  30. package/dist/src/core/files.d.ts +0 -27
  31. package/dist/src/core/files.d.ts.map +0 -1
  32. package/dist/src/core/files.js +0 -90
  33. package/dist/src/core/files.js.map +0 -1
  34. package/dist/src/core/header.d.ts +0 -63
  35. package/dist/src/core/header.d.ts.map +0 -1
  36. package/dist/src/core/header.js +0 -173
  37. package/dist/src/core/header.js.map +0 -1
  38. package/dist/src/core/index.d.ts +0 -16
  39. package/dist/src/core/index.d.ts.map +0 -1
  40. package/dist/src/core/index.js +0 -16
  41. package/dist/src/core/index.js.map +0 -1
  42. package/dist/src/core/logger-types.d.ts +0 -12
  43. package/dist/src/core/logger-types.d.ts.map +0 -1
  44. package/dist/src/core/logger-types.js +0 -2
  45. package/dist/src/core/logger-types.js.map +0 -1
  46. package/dist/src/core/logger.d.ts +0 -27
  47. package/dist/src/core/logger.d.ts.map +0 -1
  48. package/dist/src/core/logger.js +0 -127
  49. package/dist/src/core/logger.js.map +0 -1
  50. package/dist/src/core/node.d.ts.map +0 -1
  51. package/dist/src/core/node.js +0 -155
  52. package/dist/src/core/node.js.map +0 -1
  53. package/dist/src/core/operations.d.ts +0 -50
  54. package/dist/src/core/operations.d.ts.map +0 -1
  55. package/dist/src/core/operations.js +0 -126
  56. package/dist/src/core/operations.js.map +0 -1
  57. package/dist/src/core/ph-types.d.ts +0 -2
  58. package/dist/src/core/ph-types.d.ts.map +0 -1
  59. package/dist/src/core/ph-types.js +0 -2
  60. package/dist/src/core/ph-types.js.map +0 -1
  61. package/dist/src/core/reducer.d.ts +0 -63
  62. package/dist/src/core/reducer.d.ts.map +0 -1
  63. package/dist/src/core/reducer.js +0 -446
  64. package/dist/src/core/reducer.js.map +0 -1
  65. package/dist/src/core/schemas.d.ts +0 -75
  66. package/dist/src/core/schemas.d.ts.map +0 -1
  67. package/dist/src/core/schemas.js +0 -116
  68. package/dist/src/core/schemas.js.map +0 -1
  69. package/dist/src/core/state.d.ts +0 -26
  70. package/dist/src/core/state.d.ts.map +0 -1
  71. package/dist/src/core/state.js +0 -56
  72. package/dist/src/core/state.js.map +0 -1
  73. package/dist/src/core/types.d.ts +0 -2
  74. package/dist/src/core/types.d.ts.map +0 -1
  75. package/dist/src/core/types.js +0 -2
  76. package/dist/src/core/types.js.map +0 -1
  77. package/dist/src/core/utils.d.ts +0 -6
  78. package/dist/src/core/utils.d.ts.map +0 -1
  79. package/dist/src/core/utils.js +0 -15
  80. package/dist/src/core/utils.js.map +0 -1
  81. package/dist/src/core/validation.d.ts +0 -4
  82. package/dist/src/core/validation.d.ts.map +0 -1
  83. package/dist/src/core/validation.js +0 -27
  84. package/dist/src/core/validation.js.map +0 -1
  85. package/dist/src/document-model/actions.d.ts +0 -164
  86. package/dist/src/document-model/actions.d.ts.map +0 -1
  87. package/dist/src/document-model/actions.js +0 -111
  88. package/dist/src/document-model/actions.js.map +0 -1
  89. package/dist/src/document-model/constants.d.ts +0 -6
  90. package/dist/src/document-model/constants.d.ts.map +0 -1
  91. package/dist/src/document-model/constants.js +0 -584
  92. package/dist/src/document-model/constants.js.map +0 -1
  93. package/dist/src/document-model/controller.d.ts +0 -5
  94. package/dist/src/document-model/controller.d.ts.map +0 -1
  95. package/dist/src/document-model/controller.js +0 -5
  96. package/dist/src/document-model/controller.js.map +0 -1
  97. package/dist/src/document-model/document-schema.d.ts +0 -69
  98. package/dist/src/document-model/document-schema.d.ts.map +0 -1
  99. package/dist/src/document-model/document-schema.js +0 -43
  100. package/dist/src/document-model/document-schema.js.map +0 -1
  101. package/dist/src/document-model/document-type.d.ts +0 -2
  102. package/dist/src/document-model/document-type.d.ts.map +0 -1
  103. package/dist/src/document-model/document-type.js +0 -2
  104. package/dist/src/document-model/document-type.js.map +0 -1
  105. package/dist/src/document-model/files.d.ts +0 -5
  106. package/dist/src/document-model/files.d.ts.map +0 -1
  107. package/dist/src/document-model/files.js +0 -9
  108. package/dist/src/document-model/files.js.map +0 -1
  109. package/dist/src/document-model/index.d.ts +0 -12
  110. package/dist/src/document-model/index.d.ts.map +0 -1
  111. package/dist/src/document-model/index.js +0 -12
  112. package/dist/src/document-model/index.js.map +0 -1
  113. package/dist/src/document-model/module.d.ts +0 -3
  114. package/dist/src/document-model/module.d.ts.map +0 -1
  115. package/dist/src/document-model/module.js +0 -24
  116. package/dist/src/document-model/module.js.map +0 -1
  117. package/dist/src/document-model/reducers.d.ts +0 -11
  118. package/dist/src/document-model/reducers.d.ts.map +0 -1
  119. package/dist/src/document-model/reducers.js +0 -618
  120. package/dist/src/document-model/reducers.js.map +0 -1
  121. package/dist/src/document-model/schemas.d.ts +0 -189
  122. package/dist/src/document-model/schemas.d.ts.map +0 -1
  123. package/dist/src/document-model/schemas.js +0 -388
  124. package/dist/src/document-model/schemas.js.map +0 -1
  125. package/dist/src/document-model/state.d.ts +0 -15
  126. package/dist/src/document-model/state.d.ts.map +0 -1
  127. package/dist/src/document-model/state.js +0 -75
  128. package/dist/src/document-model/state.js.map +0 -1
  129. package/dist/src/document-model/types.d.ts +0 -584
  130. package/dist/src/document-model/types.d.ts.map +0 -1
  131. package/dist/src/document-model/types.js +0 -2
  132. package/dist/src/document-model/types.js.map +0 -1
  133. package/dist/src/document-model/validation.d.ts +0 -32
  134. package/dist/src/document-model/validation.d.ts.map +0 -1
  135. package/dist/src/document-model/validation.js +0 -166
  136. package/dist/src/document-model/validation.js.map +0 -1
  137. package/dist/src/index.d.ts +0 -6
  138. package/dist/src/index.d.ts.map +0 -1
  139. package/dist/src/index.js +0 -3
  140. package/dist/src/index.js.map +0 -1
  141. package/dist/test/document/crypto.test.d.ts +0 -2
  142. package/dist/test/document/crypto.test.d.ts.map +0 -1
  143. package/dist/test/document/crypto.test.js +0 -192
  144. package/dist/test/document/crypto.test.js.map +0 -1
  145. package/dist/test/document/event-vs-command.test.d.ts +0 -2
  146. package/dist/test/document/event-vs-command.test.d.ts.map +0 -1
  147. package/dist/test/document/event-vs-command.test.js +0 -202
  148. package/dist/test/document/event-vs-command.test.js.map +0 -1
  149. package/dist/test/document/local.test.d.ts +0 -2
  150. package/dist/test/document/local.test.d.ts.map +0 -1
  151. package/dist/test/document/local.test.js +0 -226
  152. package/dist/test/document/local.test.js.map +0 -1
  153. package/dist/test/document/operation-id.test.d.ts +0 -2
  154. package/dist/test/document/operation-id.test.d.ts.map +0 -1
  155. package/dist/test/document/operation-id.test.js +0 -118
  156. package/dist/test/document/operation-id.test.js.map +0 -1
  157. package/dist/test/document/prune.test.d.ts +0 -2
  158. package/dist/test/document/prune.test.d.ts.map +0 -1
  159. package/dist/test/document/prune.test.js +0 -159
  160. package/dist/test/document/prune.test.js.map +0 -1
  161. package/dist/test/document/reducer.test.d.ts +0 -2
  162. package/dist/test/document/reducer.test.d.ts.map +0 -1
  163. package/dist/test/document/reducer.test.js +0 -284
  164. package/dist/test/document/reducer.test.js.map +0 -1
  165. package/dist/test/document/skip-operations.test.d.ts +0 -2
  166. package/dist/test/document/skip-operations.test.d.ts.map +0 -1
  167. package/dist/test/document/skip-operations.test.js +0 -495
  168. package/dist/test/document/skip-operations.test.js.map +0 -1
  169. package/dist/test/document/undo-redo-v2.test.d.ts +0 -2
  170. package/dist/test/document/undo-redo-v2.test.d.ts.map +0 -1
  171. package/dist/test/document/undo-redo-v2.test.js +0 -207
  172. package/dist/test/document/undo-redo-v2.test.js.map +0 -1
  173. package/dist/test/document/undo-redo.test.d.ts +0 -2
  174. package/dist/test/document/undo-redo.test.d.ts.map +0 -1
  175. package/dist/test/document/undo-redo.test.js +0 -413
  176. package/dist/test/document/undo-redo.test.js.map +0 -1
  177. package/dist/test/document/utils.test.d.ts +0 -2
  178. package/dist/test/document/utils.test.d.ts.map +0 -1
  179. package/dist/test/document/utils.test.js +0 -172
  180. package/dist/test/document/utils.test.js.map +0 -1
  181. package/dist/test/document-helpers/addUndo.test.d.ts +0 -2
  182. package/dist/test/document-helpers/addUndo.test.d.ts.map +0 -1
  183. package/dist/test/document-helpers/addUndo.test.js +0 -120
  184. package/dist/test/document-helpers/addUndo.test.js.map +0 -1
  185. package/dist/test/document-helpers/attachBranch.test.d.ts +0 -2
  186. package/dist/test/document-helpers/attachBranch.test.d.ts.map +0 -1
  187. package/dist/test/document-helpers/attachBranch.test.js +0 -364
  188. package/dist/test/document-helpers/attachBranch.test.js.map +0 -1
  189. package/dist/test/document-helpers/checkCleanedOperationsIntegrity.test.d.ts +0 -2
  190. package/dist/test/document-helpers/checkCleanedOperationsIntegrity.test.d.ts.map +0 -1
  191. package/dist/test/document-helpers/checkCleanedOperationsIntegrity.test.js +0 -252
  192. package/dist/test/document-helpers/checkCleanedOperationsIntegrity.test.js.map +0 -1
  193. package/dist/test/document-helpers/conflictResolution.test.d.ts +0 -2
  194. package/dist/test/document-helpers/conflictResolution.test.d.ts.map +0 -1
  195. package/dist/test/document-helpers/conflictResolution.test.js +0 -109
  196. package/dist/test/document-helpers/conflictResolution.test.js.map +0 -1
  197. package/dist/test/document-helpers/filterDuplicatedOperations.test.d.ts +0 -2
  198. package/dist/test/document-helpers/filterDuplicatedOperations.test.d.ts.map +0 -1
  199. package/dist/test/document-helpers/filterDuplicatedOperations.test.js +0 -126
  200. package/dist/test/document-helpers/filterDuplicatedOperations.test.js.map +0 -1
  201. package/dist/test/document-helpers/garbageCollect.test.d.ts +0 -2
  202. package/dist/test/document-helpers/garbageCollect.test.d.ts.map +0 -1
  203. package/dist/test/document-helpers/garbageCollect.test.js +0 -136
  204. package/dist/test/document-helpers/garbageCollect.test.js.map +0 -1
  205. package/dist/test/document-helpers/groupOperationsByScope.test.d.ts +0 -2
  206. package/dist/test/document-helpers/groupOperationsByScope.test.d.ts.map +0 -1
  207. package/dist/test/document-helpers/groupOperationsByScope.test.js +0 -102
  208. package/dist/test/document-helpers/groupOperationsByScope.test.js.map +0 -1
  209. package/dist/test/document-helpers/headerRevision.test.d.ts +0 -2
  210. package/dist/test/document-helpers/headerRevision.test.d.ts.map +0 -1
  211. package/dist/test/document-helpers/headerRevision.test.js +0 -203
  212. package/dist/test/document-helpers/headerRevision.test.js.map +0 -1
  213. package/dist/test/document-helpers/merge.test.d.ts +0 -2
  214. package/dist/test/document-helpers/merge.test.d.ts.map +0 -1
  215. package/dist/test/document-helpers/merge.test.js +0 -906
  216. package/dist/test/document-helpers/merge.test.js.map +0 -1
  217. package/dist/test/document-helpers/nextSkipNumber.test.d.ts +0 -2
  218. package/dist/test/document-helpers/nextSkipNumber.test.d.ts.map +0 -1
  219. package/dist/test/document-helpers/nextSkipNumber.test.js +0 -135
  220. package/dist/test/document-helpers/nextSkipNumber.test.js.map +0 -1
  221. package/dist/test/document-helpers/prepareOperations.test.d.ts +0 -2
  222. package/dist/test/document-helpers/prepareOperations.test.d.ts.map +0 -1
  223. package/dist/test/document-helpers/prepareOperations.test.js +0 -304
  224. package/dist/test/document-helpers/prepareOperations.test.js.map +0 -1
  225. package/dist/test/document-helpers/removeExistingOperations.test.d.ts +0 -2
  226. package/dist/test/document-helpers/removeExistingOperations.test.d.ts.map +0 -1
  227. package/dist/test/document-helpers/removeExistingOperations.test.js +0 -177
  228. package/dist/test/document-helpers/removeExistingOperations.test.js.map +0 -1
  229. package/dist/test/document-helpers/reshuffleByTimestamp.test.d.ts +0 -2
  230. package/dist/test/document-helpers/reshuffleByTimestamp.test.d.ts.map +0 -1
  231. package/dist/test/document-helpers/reshuffleByTimestamp.test.js +0 -148
  232. package/dist/test/document-helpers/reshuffleByTimestamp.test.js.map +0 -1
  233. package/dist/test/document-helpers/reshuffleByTimestampAndIndex.test.d.ts +0 -2
  234. package/dist/test/document-helpers/reshuffleByTimestampAndIndex.test.d.ts.map +0 -1
  235. package/dist/test/document-helpers/reshuffleByTimestampAndIndex.test.js +0 -200
  236. package/dist/test/document-helpers/reshuffleByTimestampAndIndex.test.js.map +0 -1
  237. package/dist/test/document-helpers/skipHeaderOperations.test.d.ts +0 -2
  238. package/dist/test/document-helpers/skipHeaderOperations.test.d.ts.map +0 -1
  239. package/dist/test/document-helpers/skipHeaderOperations.test.js +0 -72
  240. package/dist/test/document-helpers/skipHeaderOperations.test.js.map +0 -1
  241. package/dist/test/document-helpers/sortOperations.test.d.ts +0 -2
  242. package/dist/test/document-helpers/sortOperations.test.d.ts.map +0 -1
  243. package/dist/test/document-helpers/sortOperations.test.js +0 -101
  244. package/dist/test/document-helpers/sortOperations.test.js.map +0 -1
  245. package/dist/test/document-helpers/split.test.d.ts +0 -2
  246. package/dist/test/document-helpers/split.test.d.ts.map +0 -1
  247. package/dist/test/document-helpers/split.test.js +0 -121
  248. package/dist/test/document-helpers/split.test.js.map +0 -1
  249. package/dist/test/document-helpers/utils.d.ts +0 -15
  250. package/dist/test/document-helpers/utils.d.ts.map +0 -1
  251. package/dist/test/document-helpers/utils.js +0 -61
  252. package/dist/test/document-helpers/utils.js.map +0 -1
  253. package/dist/test/document-model/replay.test.d.ts +0 -2
  254. package/dist/test/document-model/replay.test.d.ts.map +0 -1
  255. package/dist/test/document-model/replay.test.js +0 -139
  256. package/dist/test/document-model/replay.test.js.map +0 -1
  257. package/dist/test/document-model/skip-operations.test.d.ts +0 -2
  258. package/dist/test/document-model/skip-operations.test.d.ts.map +0 -1
  259. package/dist/test/document-model/skip-operations.test.js +0 -214
  260. package/dist/test/document-model/skip-operations.test.js.map +0 -1
  261. package/dist/test/document-model/validation.test.d.ts +0 -2
  262. package/dist/test/document-model/validation.test.d.ts.map +0 -1
  263. package/dist/test/document-model/validation.test.js +0 -451
  264. package/dist/test/document-model/validation.test.js.map +0 -1
  265. package/dist/test/document-model/versioning.test.d.ts +0 -2
  266. package/dist/test/document-model/versioning.test.d.ts.map +0 -1
  267. package/dist/test/document-model/versioning.test.js +0 -93
  268. package/dist/test/document-model/versioning.test.js.map +0 -1
  269. package/dist/test/document-model/zip.test.d.ts +0 -2
  270. package/dist/test/document-model/zip.test.d.ts.map +0 -1
  271. package/dist/test/document-model/zip.test.js +0 -79
  272. package/dist/test/document-model/zip.test.js.map +0 -1
  273. package/dist/test/helpers.d.ts +0 -79
  274. package/dist/test/helpers.d.ts.map +0 -1
  275. package/dist/test/helpers.js +0 -121
  276. package/dist/test/helpers.js.map +0 -1
  277. package/dist/test/index.d.ts +0 -4
  278. package/dist/test/index.d.ts.map +0 -1
  279. package/dist/test/index.js +0 -3
  280. package/dist/test/index.js.map +0 -1
  281. package/dist/test/types.d.ts +0 -6
  282. package/dist/test/types.d.ts.map +0 -1
  283. package/dist/test/types.js +0 -2
  284. package/dist/test/types.js.map +0 -1
  285. package/dist/tsconfig.tsbuildinfo +0 -1
  286. package/dist/vitest.config.d.ts +0 -3
  287. package/dist/vitest.config.d.ts.map +0 -1
  288. package/dist/vitest.config.js +0 -7
  289. package/dist/vitest.config.js.map +0 -1
@@ -1,207 +0,0 @@
1
- import { baseCreateDocument, processUndoRedo, undo } from "document-model/core";
2
- import { countReducer, createCountDocumentState, increment, testCreateBaseState, } from "document-model/test";
3
- import { beforeEach, describe, expect, it } from "vitest";
4
- describe("UNDO/REDO with protocolVersion: 2", () => {
5
- let document;
6
- beforeEach(() => {
7
- const initialState = testCreateBaseState({ count: 0 }, { name: "" });
8
- document = baseCreateDocument(createCountDocumentState, initialState);
9
- document = countReducer(document, increment());
10
- document = countReducer(document, increment());
11
- document = countReducer(document, increment());
12
- });
13
- describe("processUndoRedo with protocolVersion: 2", () => {
14
- it("should return reuseLastOperationIndex: false", () => {
15
- const undoAction = undo();
16
- const result = processUndoRedo(document, undoAction, 0, 2);
17
- expect(result.reuseLastOperationIndex).toBe(false);
18
- });
19
- it("should always return skip=1 for v2", () => {
20
- const undoAction = undo();
21
- const result = processUndoRedo(document, undoAction, 0, 2);
22
- expect(result.skip).toBe(1);
23
- expect(result.action.type).toBe("NOOP");
24
- });
25
- it("should always return reuseLastOperationIndex: false even after NOOP", () => {
26
- document = countReducer(document, undo());
27
- const undoAction = undo();
28
- const result = processUndoRedo(document, undoAction, 0, 2);
29
- expect(result.reuseLastOperationIndex).toBe(false);
30
- });
31
- });
32
- describe("comparison: protocolVersion 1 vs 2", () => {
33
- it("protocolVersion 1 allows index reuse after NOOP", () => {
34
- document = countReducer(document, undo());
35
- const undoAction = undo();
36
- const resultV1 = processUndoRedo(document, undoAction, 0, 1);
37
- expect(resultV1.reuseLastOperationIndex).toBe(true);
38
- });
39
- it("protocolVersion 2 never allows index reuse", () => {
40
- document = countReducer(document, undo());
41
- const undoAction = undo();
42
- const resultV2 = processUndoRedo(document, undoAction, 0, 2);
43
- expect(resultV2.reuseLastOperationIndex).toBe(false);
44
- });
45
- });
46
- describe("end-to-end with protocolVersion: 2 in reducer", () => {
47
- it("should create NOOP operations with correct skip value", () => {
48
- document = countReducer(document, undo(), undefined, {
49
- protocolVersion: 2,
50
- });
51
- const ops = document.operations.global;
52
- const lastOp = ops[ops.length - 1];
53
- expect(lastOp.action.type).toBe("NOOP");
54
- expect(lastOp.skip).toBe(1);
55
- expect(lastOp.index).toBe(3);
56
- });
57
- it("protocolVersion 2 always creates NOOPs with skip=1", () => {
58
- document = countReducer(document, undo(), undefined, {
59
- protocolVersion: 2,
60
- });
61
- const ops = document.operations.global;
62
- const noopOp = ops.find((op) => op.action.type === "NOOP");
63
- expect(noopOp).toBeDefined();
64
- expect(noopOp.skip).toBe(1);
65
- });
66
- it("should correctly undo state with protocolVersion 2", () => {
67
- expect(document.state.global.count).toBe(3);
68
- document = countReducer(document, undo(), undefined, {
69
- protocolVersion: 2,
70
- });
71
- expect(document.state.global.count).toBe(2);
72
- });
73
- it("consecutive undos should all have skip=1 and incrementing indices", () => {
74
- // First undo
75
- document = countReducer(document, undo(), undefined, {
76
- protocolVersion: 2,
77
- });
78
- const ops1 = document.operations.global;
79
- const noop1 = ops1[ops1.length - 1];
80
- expect(noop1.action.type).toBe("NOOP");
81
- expect(noop1.skip).toBe(1);
82
- expect(noop1.index).toBe(3);
83
- expect(document.state.global.count).toBe(2);
84
- // Second undo
85
- document = countReducer(document, undo(), undefined, {
86
- protocolVersion: 2,
87
- });
88
- const ops2 = document.operations.global;
89
- const noop2 = ops2[ops2.length - 1];
90
- expect(noop2.action.type).toBe("NOOP");
91
- expect(noop2.skip).toBe(1);
92
- expect(noop2.index).toBe(4); // Should increment, not reuse
93
- expect(document.state.global.count).toBe(1);
94
- // Third undo
95
- document = countReducer(document, undo(), undefined, {
96
- protocolVersion: 2,
97
- });
98
- const ops3 = document.operations.global;
99
- const noop3 = ops3[ops3.length - 1];
100
- expect(noop3.action.type).toBe("NOOP");
101
- expect(noop3.skip).toBe(1);
102
- expect(noop3.index).toBe(5); // Should increment, not reuse
103
- expect(document.state.global.count).toBe(0);
104
- });
105
- it("should throw when trying to undo more than available", () => {
106
- // Undo all 3 increments
107
- document = countReducer(document, undo(), undefined, {
108
- protocolVersion: 2,
109
- });
110
- document = countReducer(document, undo(), undefined, {
111
- protocolVersion: 2,
112
- });
113
- document = countReducer(document, undo(), undefined, {
114
- protocolVersion: 2,
115
- });
116
- expect(document.state.global.count).toBe(0);
117
- // Try to undo when there's nothing left
118
- expect(() => countReducer(document, undo(), undefined, {
119
- protocolVersion: 2,
120
- })).toThrow("Cannot undo: no more operations to undo in scope history");
121
- });
122
- it("operations list should preserve all operations including NOOPs", () => {
123
- document = countReducer(document, undo(), undefined, {
124
- protocolVersion: 2,
125
- });
126
- document = countReducer(document, undo(), undefined, {
127
- protocolVersion: 2,
128
- });
129
- const ops = document.operations.global;
130
- // Should have: 3 increments + 2 NOOPs = 5 operations
131
- expect(ops.length).toBe(5);
132
- expect(ops.map((op) => op.action.type)).toEqual([
133
- "INCREMENT",
134
- "INCREMENT",
135
- "INCREMENT",
136
- "NOOP",
137
- "NOOP",
138
- ]);
139
- expect(ops.map((op) => op.index)).toEqual([0, 1, 2, 3, 4]);
140
- });
141
- it("should handle undo after new operations added following undos (gapped indices)", () => {
142
- // This test reproduces the bug where undo fails after:
143
- // 1. Multiple undos create NOOPs
144
- // 2. New operations are added after the undos
145
- // 3. Undo is triggered again
146
- //
147
- // The issue is that garbageCollectV2 creates a set of effective operations
148
- // with gaps in indices (e.g., [0, 5, 6] instead of [0, 1, 2, 3, 4, 5, 6])
149
- // and the state rebuild fails due to index validation.
150
- // Initial state: count = 3 with operations [0: INC, 1: INC, 2: INC]
151
- expect(document.state.global.count).toBe(3);
152
- // Undo twice: count = 1
153
- // Operations: [0: INC, 1: INC, 2: INC, 3: NOOP(skip=1), 4: NOOP(skip=1)]
154
- document = countReducer(document, undo(), undefined, {
155
- protocolVersion: 2,
156
- });
157
- document = countReducer(document, undo(), undefined, {
158
- protocolVersion: 2,
159
- });
160
- expect(document.state.global.count).toBe(1);
161
- // Add new operations after undos: count = 3
162
- // Operations: [0: INC, 1: INC, 2: INC, 3: NOOP, 4: NOOP, 5: INC, 6: INC]
163
- document = countReducer(document, increment(), undefined, {
164
- protocolVersion: 2,
165
- });
166
- document = countReducer(document, increment(), undefined, {
167
- protocolVersion: 2,
168
- });
169
- expect(document.state.global.count).toBe(3);
170
- const opsBeforeUndo = document.operations.global;
171
- expect(opsBeforeUndo.map((op) => op.action.type)).toEqual([
172
- "INCREMENT",
173
- "INCREMENT",
174
- "INCREMENT",
175
- "NOOP",
176
- "NOOP",
177
- "INCREMENT",
178
- "INCREMENT",
179
- ]);
180
- expect(opsBeforeUndo.map((op) => op.index)).toEqual([
181
- 0, 1, 2, 3, 4, 5, 6,
182
- ]);
183
- // Now undo - this is where the bug occurs
184
- // garbageCollectV2 will return effective operations with gapped indices
185
- // (operations 1, 2 are "undone" by NOOPs at 3, 4)
186
- // Effective non-NOOP ops: indices [0, 5, 6] - there's a gap!
187
- document = countReducer(document, undo(), undefined, {
188
- protocolVersion: 2,
189
- });
190
- // Should have undone the last increment
191
- expect(document.state.global.count).toBe(2);
192
- const opsAfterUndo = document.operations.global;
193
- expect(opsAfterUndo.length).toBe(8);
194
- expect(opsAfterUndo.map((op) => op.action.type)).toEqual([
195
- "INCREMENT",
196
- "INCREMENT",
197
- "INCREMENT",
198
- "NOOP",
199
- "NOOP",
200
- "INCREMENT",
201
- "INCREMENT",
202
- "NOOP",
203
- ]);
204
- });
205
- });
206
- });
207
- //# sourceMappingURL=undo-redo-v2.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"undo-redo-v2.test.js","sourceRoot":"","sources":["../../../test/document/undo-redo-v2.test.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=undo-redo.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"undo-redo.test.d.ts","sourceRoot":"","sources":["../../../test/document/undo-redo.test.ts"],"names":[],"mappings":""}
@@ -1,413 +0,0 @@
1
- import { baseCreateDocument, deriveOperationId, noop, processUndoRedo, redo, undo, } from "document-model/core";
2
- import { countReducer, createCountDocumentState, increment, testCreateBaseState, } from "document-model/test";
3
- import { beforeEach, describe, expect, it } from "vitest";
4
- describe("UNDO/REDO", () => {
5
- let document;
6
- beforeEach(() => {
7
- const initialState = testCreateBaseState({ count: 0 }, { name: "" });
8
- document = baseCreateDocument(createCountDocumentState, initialState);
9
- document = countReducer(document, increment());
10
- document = countReducer(document, increment());
11
- document = countReducer(document, increment());
12
- document = countReducer(document, increment());
13
- document = countReducer(document, increment());
14
- });
15
- describe("processUndoRedo -> UNDO", () => {
16
- it("should return a NOOP action when an UNDO action is dispatched", () => {
17
- const skip = 0;
18
- const undoAction = undo();
19
- const result = processUndoRedo(document, undoAction, skip);
20
- expect(result.action.type).toBe("NOOP");
21
- });
22
- it("should return skip = undo value if there's no skip value passed to the reducer", () => {
23
- const skip = 0;
24
- const undoAction = undo();
25
- const result = processUndoRedo(document, undoAction, skip);
26
- expect(result.skip).toBe(1);
27
- expect(result.action.type).toBe("NOOP");
28
- });
29
- it("should return skip = undo value + previous NOOP skip value, when latest action is NOOP with skip > 0", () => {
30
- const skip = 0;
31
- const undoAction = undo();
32
- document = countReducer(document, noop(), undefined, {
33
- skip: 3,
34
- ignoreSkipOperations: true,
35
- });
36
- const result = processUndoRedo(document, undoAction, skip);
37
- expect(result.skip).toBe(4);
38
- expect(result.action.type).toBe("NOOP");
39
- });
40
- it("should NOT remove latest operation if !== NOOP", () => {
41
- const skip = 0;
42
- const undoAction = undo();
43
- const result = processUndoRedo(document, undoAction, skip);
44
- expect(result.skip).toBe(1);
45
- expect(result.document.operations.global.length).toBe(5);
46
- expect(result.document.operations.global[4].action.type).toBe("INCREMENT");
47
- });
48
- it("should NOT remove latest operation if is a NOOP with skip = 0", () => {
49
- const skip = 0;
50
- const undoAction = undo();
51
- document = countReducer(document, noop(), undefined, {
52
- skip: 0,
53
- ignoreSkipOperations: true,
54
- });
55
- const result = processUndoRedo(document, undoAction, skip);
56
- expect(result.skip).toBe(1);
57
- expect(result.document.operations.global.length).toBe(6);
58
- expect(result.document.operations.global[5].action.type).toBe("NOOP");
59
- });
60
- it("should throw an error if you try to undone more operations than the ones available", () => {
61
- const initialState = testCreateBaseState({ count: 0 }, { name: "" });
62
- document = baseCreateDocument(createCountDocumentState, initialState);
63
- const skip = 0;
64
- const undoAction = undo();
65
- const throwErrorFunc = () => processUndoRedo(document, undoAction, skip);
66
- expect(throwErrorFunc).toThrow("Cannot undo: you can't undo more operations than the ones in the scope history");
67
- });
68
- });
69
- describe("processUndoRedo -> REDO", () => {
70
- it("should throw an error when there's no operation to redo in the clipboard", () => {
71
- const initialState = testCreateBaseState({ count: 0 }, { name: "" });
72
- document = baseCreateDocument(createCountDocumentState, initialState);
73
- const skip = 0;
74
- const redoAction = redo();
75
- const throwErrorFunc = () => processUndoRedo(document, redoAction, skip);
76
- expect(throwErrorFunc).toThrow("Cannot redo: no operations in the clipboard");
77
- });
78
- it("should throw an error if you try to redo more than 1 operation", () => {
79
- const skip = 0;
80
- const redoAction = redo(2);
81
- const throwErrorFunc = () => processUndoRedo(document, redoAction, skip);
82
- expect(throwErrorFunc).toThrow("Cannot redo: you can only redo one operation at a time");
83
- });
84
- it("should throw an error if you try to redo with an skip value", () => {
85
- const skip = 1;
86
- const redoAction = redo(1);
87
- const throwErrorFunc = () => processUndoRedo(document, redoAction, skip);
88
- expect(throwErrorFunc).toThrow("Cannot redo: skip value from reducer cannot be used with REDO action");
89
- });
90
- it("should throw an error if there's no operations for the scope in the clipboard", () => {
91
- const skip = 0;
92
- const redoAction = redo(1, "local");
93
- document = countReducer(document, undo(1));
94
- const throwErrorFunc = () => processUndoRedo(document, redoAction, skip);
95
- expect(throwErrorFunc).toThrow('Cannot redo: no operations in clipboard for scope "local"');
96
- });
97
- it("should transform REDO action into the latest valid action stored in the clipboard", () => {
98
- const skip = 0;
99
- const redoAction = redo(1);
100
- document = countReducer(document, undo(1));
101
- const result = processUndoRedo(document, redoAction, skip);
102
- expect(result.action.type).toBe("INCREMENT");
103
- expect(result.action.scope).toBe("global");
104
- expect(result.action.input).toStrictEqual({});
105
- });
106
- it("should remove the latest valid action from the clipboard", () => {
107
- const skip = 0;
108
- const redoAction = redo(1);
109
- document = countReducer(document, undo(1));
110
- expect(document.clipboard.length).toBe(1);
111
- const result = processUndoRedo(document, redoAction, skip);
112
- expect(result.document.clipboard.length).toBe(0);
113
- });
114
- });
115
- describe("UNDO", () => {
116
- it("should undo operations", () => {
117
- document = countReducer(document, undo(1));
118
- expect(document.header.revision.global).toBe(6);
119
- expect(document.state.global.count).toBe(4);
120
- expect(document.clipboard.length).toBe(1);
121
- expect(document.clipboard[0].action.type).toBe("INCREMENT");
122
- expect(document.clipboard[0].index).toBe(4);
123
- expect(document.operations.global.length).toBe(5);
124
- expect(document.operations.global[4]).toMatchObject({
125
- type: "NOOP",
126
- index: 5,
127
- skip: 1,
128
- });
129
- expect(document.operations.global[3]).toMatchObject({
130
- type: "INCREMENT",
131
- index: 3,
132
- skip: 0,
133
- });
134
- expect(document.operations.global[2]).toMatchObject({
135
- type: "INCREMENT",
136
- index: 2,
137
- skip: 0,
138
- });
139
- });
140
- it("should increase skip value of a previous undo Operation", () => {
141
- document = countReducer(document, undo());
142
- document = countReducer(document, undo());
143
- document = countReducer(document, undo());
144
- expect(document.header.revision.global).toBe(6);
145
- expect(document.state.global.count).toBe(2);
146
- expect(document.clipboard.length).toBe(3);
147
- expect(document.clipboard[0].action.type).toBe("INCREMENT");
148
- expect(document.clipboard[0].index).toBe(4);
149
- expect(document.clipboard[1].action.type).toBe("INCREMENT");
150
- expect(document.clipboard[1].index).toBe(3);
151
- expect(document.clipboard[2].action.type).toBe("INCREMENT");
152
- expect(document.clipboard[2].index).toBe(2);
153
- expect(document.operations.global.length).toBe(3);
154
- expect(document.operations.global[2]).toMatchObject({
155
- type: "NOOP",
156
- index: 5,
157
- skip: 3,
158
- });
159
- expect(document.operations.global[1]).toMatchObject({
160
- type: "INCREMENT",
161
- index: 1,
162
- skip: 0,
163
- });
164
- expect(document.operations.global[0]).toMatchObject({
165
- type: "INCREMENT",
166
- index: 0,
167
- skip: 0,
168
- });
169
- });
170
- it("should undo the latest valid operation if undo overlaps with a previous undo operation", () => {
171
- document = countReducer(document, undo());
172
- document = countReducer(document, undo());
173
- document = countReducer(document, undo());
174
- document = countReducer(document, increment());
175
- document = countReducer(document, increment());
176
- document = countReducer(document, undo());
177
- document = countReducer(document, undo());
178
- document = countReducer(document, undo());
179
- expect(document.header.revision.global).toBe(9);
180
- expect(document.state.global.count).toBe(1);
181
- expect(document.clipboard.length).toBe(3);
182
- expect(document.clipboard[0].action.type).toBe("INCREMENT");
183
- expect(document.clipboard[0].index).toBe(7);
184
- expect(document.clipboard[1].action.type).toBe("INCREMENT");
185
- expect(document.clipboard[1].index).toBe(6);
186
- expect(document.clipboard[2].action.type).toBe("INCREMENT");
187
- expect(document.clipboard[2].index).toBe(1);
188
- expect(document.operations.global.length).toBe(2);
189
- expect(document.operations.global).toMatchObject([
190
- {
191
- type: "INCREMENT",
192
- index: 0,
193
- skip: 0,
194
- },
195
- {
196
- type: "NOOP",
197
- index: 8,
198
- skip: 7,
199
- },
200
- ]);
201
- });
202
- it("should undo the latest valid operation if undo overlaps with 2 previous undo operations", () => {
203
- document = countReducer(document, undo());
204
- document = countReducer(document, increment());
205
- document = countReducer(document, undo());
206
- document = countReducer(document, undo());
207
- document = countReducer(document, increment());
208
- document = countReducer(document, undo());
209
- document = countReducer(document, undo());
210
- expect(document.header.revision.global).toBe(10);
211
- expect(document.state.global.count).toBe(2);
212
- expect(document.clipboard.length).toBe(2);
213
- expect(document.clipboard[0].action.type).toBe("INCREMENT");
214
- expect(document.clipboard[0].index).toBe(8);
215
- expect(document.clipboard[1].action.type).toBe("INCREMENT");
216
- expect(document.clipboard[1].index).toBe(2);
217
- expect(document.operations.global.length).toBe(3);
218
- expect(document.operations.global).toMatchObject([
219
- {
220
- type: "INCREMENT",
221
- index: 0,
222
- skip: 0,
223
- },
224
- {
225
- type: "INCREMENT",
226
- index: 1,
227
- skip: 0,
228
- },
229
- {
230
- type: "NOOP",
231
- index: 9,
232
- skip: 7,
233
- },
234
- ]);
235
- });
236
- });
237
- describe("REDO", () => {
238
- it("should redo the latest operation", () => {
239
- document = countReducer(document, undo());
240
- document = countReducer(document, undo());
241
- document = countReducer(document, redo());
242
- expect(document.header.revision.global).toBe(7);
243
- expect(document.state.global.count).toBe(4);
244
- expect(document.operations.global.length).toBe(5);
245
- expect(document.clipboard.length).toBe(1);
246
- expect(document.operations.global[4]).toMatchObject({
247
- type: "INCREMENT",
248
- index: 6,
249
- });
250
- });
251
- it("should revert document state to the latest state before applying an undo", () => {
252
- document = countReducer(document, undo());
253
- document = countReducer(document, undo());
254
- document = countReducer(document, redo());
255
- document = countReducer(document, redo());
256
- expect(document.header.revision.global).toBe(8);
257
- expect(document.state.global.count).toBe(5);
258
- expect(document.operations.global.length).toBe(6);
259
- expect(document.clipboard.length).toBe(0);
260
- expect(document.operations.global[5]).toMatchObject({
261
- type: "INCREMENT",
262
- index: 7,
263
- skip: 0,
264
- });
265
- expect(document.operations.global[4]).toMatchObject({
266
- type: "INCREMENT",
267
- index: 6,
268
- skip: 0,
269
- });
270
- expect(document.operations.global[3]).toMatchObject({
271
- type: "NOOP",
272
- index: 5,
273
- skip: 2,
274
- });
275
- expect(document.operations.global[2]).toMatchObject({
276
- type: "INCREMENT",
277
- index: 2,
278
- skip: 0,
279
- });
280
- expect(document.operations.global[1]).toMatchObject({
281
- type: "INCREMENT",
282
- index: 1,
283
- skip: 0,
284
- });
285
- expect(document.operations.global[0]).toMatchObject({
286
- type: "INCREMENT",
287
- index: 0,
288
- skip: 0,
289
- });
290
- });
291
- it("should clean clipboard after applying an action that's not UNDO/REDO", () => {
292
- document = countReducer(document, undo());
293
- document = countReducer(document, undo());
294
- document = countReducer(document, increment());
295
- expect(document.header.revision.global).toBe(7);
296
- expect(document.state.global.count).toBe(4);
297
- expect(document.operations.global.length).toBe(5);
298
- expect(document.clipboard.length).toBe(0);
299
- });
300
- });
301
- describe("NOOP operations", () => {
302
- it("should apply NOOP operations", () => {
303
- const op = {
304
- // using a fixed id, even though Action ids and Operation ids are different
305
- id: "noop-1",
306
- timestampUtcMs: new Date().toISOString(),
307
- input: {},
308
- type: "NOOP",
309
- skip: 1,
310
- index: 5,
311
- scope: "global",
312
- hash: "Ki38EB6gkUcnU3ceRsc88njPo3U=",
313
- };
314
- document = countReducer(document, op, undefined, {
315
- skip: 1,
316
- });
317
- expect(document.header.revision.global).toBe(6);
318
- expect(document.state.global.count).toBe(4);
319
- expect(document.operations.global.length).toBe(5);
320
- expect(document.operations.global[4]).toMatchObject({
321
- type: "NOOP",
322
- index: 5,
323
- skip: 1,
324
- });
325
- });
326
- it("should replace previous noop operation and update skip number when a new noop is dispatched after another one", () => {
327
- const baseAction = {
328
- id: "noop-2",
329
- timestampUtcMs: new Date().toISOString(),
330
- input: {},
331
- type: "NOOP",
332
- scope: "global",
333
- };
334
- const baseOperation = {
335
- id: undefined,
336
- skip: 0,
337
- index: 5,
338
- hash: "Ki38EB6gkUcnU3ceRsc88njPo3U=",
339
- timestampUtcMs: new Date().toISOString(),
340
- action: baseAction,
341
- };
342
- const action1 = { ...baseAction, id: "noop-1" };
343
- const action2 = { ...baseAction, id: "noop-2" };
344
- const action3 = { ...baseAction, id: "noop-3" };
345
- const op1 = {
346
- ...baseOperation,
347
- id: deriveOperationId(document.header.id, "global", "main", action1.id),
348
- skip: 1,
349
- action: action1,
350
- };
351
- const op2 = {
352
- ...baseOperation,
353
- id: deriveOperationId(document.header.id, "global", "main", action2.id),
354
- skip: 2,
355
- action: action2,
356
- };
357
- const op3 = {
358
- ...baseOperation,
359
- id: deriveOperationId(document.header.id, "global", "main", action3.id),
360
- skip: 3,
361
- action: action3,
362
- };
363
- document = countReducer(document, action1, undefined, {
364
- pruneOnSkip: true,
365
- skip: 1,
366
- replayOptions: {
367
- operation: op1,
368
- },
369
- });
370
- document = countReducer(document, action2, undefined, {
371
- pruneOnSkip: true,
372
- skip: 2,
373
- replayOptions: {
374
- operation: op2,
375
- },
376
- });
377
- document = countReducer(document, action3, undefined, {
378
- pruneOnSkip: true,
379
- skip: 3,
380
- replayOptions: {
381
- operation: op3,
382
- },
383
- });
384
- expect(document.header.revision.global).toBe(6);
385
- expect(document.state.global.count).toBe(2);
386
- expect(document.operations.global.length).toBe(3);
387
- expect(document.operations.global[2]).toMatchObject({
388
- index: 5,
389
- skip: 3,
390
- });
391
- expect(document.operations.global[2].action).toMatchObject({
392
- type: "NOOP",
393
- });
394
- });
395
- it("NOOP operation should not add skipped operation to the clipboard", () => {
396
- const op = {
397
- id: "noop-3",
398
- input: {},
399
- type: "NOOP",
400
- skip: 1,
401
- index: 5,
402
- scope: "global",
403
- hash: "Ki38EB6gkUcnU3ceRsc88njPo3U=",
404
- timestampUtcMs: new Date().toISOString(),
405
- };
406
- document = countReducer(document, op, undefined, {
407
- skip: 1,
408
- });
409
- expect(document.clipboard.length).toBe(0);
410
- });
411
- });
412
- });
413
- //# sourceMappingURL=undo-redo.test.js.map