Imlement simple history manager in core package#145
Conversation
|
⏭️ No files to mutate for |
|
⏭️ No files to mutate for |
|
⏭️ No files to mutate for |
Coverage report for
|
St.❔ |
Category | Percentage | Covered / Total |
|---|---|---|---|
| 🟢 | Statements | 99.8% (+0% 🔼) |
989/991 |
| 🟢 | Branches | 98.98% | 292/295 |
| 🟢 | Functions | 97.45% | 229/235 |
| 🟢 | Lines | 99.79% (+0% 🔼) |
949/951 |
Test suite run success
538 tests passing in 25 suites.
Report generated by 🧪jest coverage report action from 969637a
Coverage report for
|
St.❔ |
Category | Percentage | Covered / Total |
|---|---|---|---|
| 🟢 | Statements | 93.28% (+1.19% 🔼) |
236/253 |
| 🟢 | Branches | 91.58% (-0.36% 🔻) |
87/95 |
| 🟡 | Functions | 72.73% (+1.3% 🔼) |
40/55 |
| 🟢 | Lines | 92.89% (+1.28% 🔼) |
222/239 |
Show new covered files 🐣
St.❔ |
File | Statements | Branches | Functions | Lines |
|---|---|---|---|---|---|
| 🟢 | ... / UndoRedoManager.ts |
100% | 100% | 100% | 100% |
| 🔴 | ... / DocumentAPI.ts |
57.14% | 0% | 44.44% | 53.85% |
Test suite run success
115 tests passing in 8 suites.
Report generated by 🧪jest coverage report action from 969637a
Coverage report for
|
St.❔ |
Category | Percentage | Covered / Total |
|---|---|---|---|
| 🟢 | Statements | 96.43% | 27/28 |
| 🟢 | Branches | 86.96% | 20/23 |
| 🟢 | Functions | 100% | 5/5 |
| 🟢 | Lines | 96.43% | 27/28 |
Test suite run success
11 tests passing in 2 suites.
Report generated by 🧪jest coverage report action from 969637a
Coverage report for
|
St.❔ |
Category | Percentage | Covered / Total |
|---|---|---|---|
| 🟡 | Statements | 70.97% | 22/31 |
| 🔴 | Branches | 20% | 1/5 |
| 🔴 | Functions | 50% | 6/12 |
| 🟡 | Lines | 68.97% | 20/29 |
Test suite run success
4 tests passing in 1 suite.
Report generated by 🧪jest coverage report action from 969637a
Coverage report for
|
St.❔ |
Category | Percentage | Covered / Total |
|---|---|---|---|
| 🟢 | Statements | 91.84% (-0.95% 🔻) |
394/429 |
| 🟢 | Branches | 85.51% (+2.17% 🔼) |
118/138 |
| 🟢 | Functions | 88.16% (-11.84% 🔻) |
67/76 |
| 🟢 | Lines | 91.67% (-1.02% 🔻) |
385/420 |
Show new covered files 🐣
St.❔ |
File | Statements | Branches | Functions | Lines |
|---|---|---|---|---|---|
| 🟢 | ... / codex-tooltip.ts |
100% | 100% | 0% | 100% |
| 🟢 | ... / CollaborationManager.ts |
87.39% | 83.33% | 73.33% | 86.92% |
| 🟢 | ... / createManager.ts |
92.31% | 100% | 88.89% | 91.67% |
Test suite run success
127 tests passing in 7 suites.
Report generated by 🧪jest coverage report action from 969637a
There was a problem hiding this comment.
Pull request overview
Adds a local (single-user) undo/redo history implementation to core, exposes it via the SDK DocumentAPI, and makes undo/redo events cancelable so plugins (notably CollaborationManager) can override default behavior.
Changes:
- Added
UndoRedoManagercore component that records model change events and applies undo/redo via core events. - Extended
DocumentAPI(SDK + core implementation) withundo()/redo()and updated UI keyboard handling to call it. - Made
UndoCoreEvent/RedoCoreEventcancelable and updated CollaborationManager to prevent default undo/redo handling.
Reviewed changes
Copilot reviewed 15 out of 15 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/ui/src/Blocks/Blocks.ts | Switch keyboard shortcuts from manual event dispatch to api.document.undo()/redo(). |
| packages/sdk/src/entities/EventBus/events/core/UndoCoreEvent.ts | Make Undo event cancelable so plugins can prevent default handling. |
| packages/sdk/src/entities/EventBus/events/core/RedoCoreEvent.ts | Make Redo event cancelable so plugins can prevent default handling. |
| packages/sdk/src/entities/EventBus/events/core/CoreEventBase.ts | Allow passing CustomEventInit options (e.g., cancelable). |
| packages/sdk/src/api/DocumentAPI.ts | Add undo() / redo() to public SDK Document API surface. |
| packages/model/src/EventBus/types/EventPayloadBase.ts | Remove old common payload interface content; keep Modified payload shape. |
| packages/model/src/EventBus/index.ts | Stop re-exporting the old EventPayloadBase types file. |
| packages/model/src/EventBus/events/index.ts | Export new BaseEvent definitions (payload base + base document event). |
| packages/core/src/index.ts | Instantiate the new UndoRedoManager as part of core initialization. |
| packages/core/src/components/UndoRedoManager.ts | New core local undo/redo manager implementation. |
| packages/core/src/components/UndoRedoManager.spec.ts | New unit test coverage for UndoRedoManager behavior (batching, stacks, cancelation). |
| packages/core/src/api/DocumentAPI/DocumentAPI.ts | Dispatch undo/redo core events via DocumentAPI.undo/redo(). |
| packages/core/src/api/DocumentAPI/DocumentAPI.spec.ts | Update DocumentAPI construction to provide EventBus. |
| packages/collaboration-manager/src/CollaborationManager.ts | Prevent default core undo/redo to use collaboration undo/redo logic. |
| packages/collaboration-manager/src/BatchedOperation.ts | Add TODO note about delete batching. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const onRedo = (e: UndoCoreEvent): void => { | ||
| e.preventDefault(); | ||
|
|
||
| this.redo(); | ||
| }; |
| } | ||
|
|
||
| this.#redoStack.push(events.map(this.#inverse).reverse()); | ||
| } |
| case EventAction.Modified: | ||
| this.#model.modifyData( | ||
| event.userId, | ||
| event.index, | ||
| { | ||
| value: (event as EventPayloadBase<EventAction.Modified, ModifiedEventData>).data.previous, | ||
| previous: (event as EventPayloadBase<EventAction.Modified, ModifiedEventData>).data.value, | ||
| } | ||
| ); | ||
| break; |
| model.addEventListener(EventType.Changed, (e: ModelEvents) => { | ||
| this.#handleEvent(e); | ||
| }); | ||
|
|
||
| eventBus.addEventListener(`core:${CoreEventType.Undo}`, this.#undoListener); | ||
| eventBus.addEventListener(`core:${CoreEventType.Redo}`, this.#redoListener); | ||
| } |
| public undo(): void { | ||
| this.#eventBus.dispatchEvent(new UndoCoreEvent()); | ||
| } | ||
|
|
||
| /** | ||
| * Redoes the last undone change in the document | ||
| */ | ||
| public redo(): void { | ||
| this.#eventBus.dispatchEvent(new RedoCoreEvent()); | ||
| } |
…ocument-model into feature/internal-undo-redo
|
|
||
| const api: EditorAPI = { | ||
| document: createMockDocumentAPI(model), | ||
| // eslint-disable-next-line @typescript-eslint/no-explicit-any |
There was a problem hiding this comment.
seems like any is gone, strange that eslint does not complain about redundant ignore
| @@ -0,0 +1,344 @@ | |||
| import 'reflect-metadata'; | |||
There was a problem hiding this comment.
maybe we could import it once in the core src/index?
There was a problem hiding this comment.
Best practice is to include it in each file. During the build it just needs to be optimised to be included in the bundle only once
| /** | ||
| * Moves the batch to the undo stack and cancels the debounce timer. | ||
| */ | ||
| #flushBatch(): void { |
There was a problem hiding this comment.
i remember we discussed the same naming CollaborationManager
| #flushBatch(): void { | |
| #putBatchToUndo(): void { |
There was a problem hiding this comment.
i suppose that the file should be renamed then
Core now has simple undo redo manager for single-user use case.
Plugins can prevent default undo behaviour by cancelling UndoCore and RedoCore events. CollaborationManager prevents default behaviour to use it's own implementation instead