I tried to get something working. Unfortunately, I wasn't successful.
The first hurdle is that every event class implements their own to/fromJson methods, deserializing would require a large switch statement on `event.type`. For now though, I tried only working with BlockMove events. Funnily enough, `event.recordUndo` does not seem to be serialized, so we have to manually set it to true. And we end up with code looking like this:
```
Blockly.serialization.registry.register("undo-history", {
save(workspace) {
return workspace
.getUndoStack()
.filter((event) => event.type === Blockly.Events.BLOCK_MOVE)
.map((event) => event.toJson());
},
load(state: any[], workspace) {
for (let eventState of state) {
const event = new Blockly.Events.BlockMove(workspace.getBlockById(eventState.blockId) as any);
event.fromJson(eventState);
event.recordUndo = true;
workspace.fireChangeListener(event);
};
},
clear(workspace) {},
priority: 10,
});
```
Trying to undo with ctrl-z, however, throws an error `Workspace is null. Event must have been generated from real Blockly events.` Manually setting `event.workspaceId =
workspace.id` throws `Cannot read properties of undefined (reading 'nextConnection') at BlockMove.run()`
Preserving undo-history is not a big priority for my project right now, so I'm going to have to leave it at that. Perhaps someone else can get it working and contribute it to Blockly core.
Also, this might already be fixed in the mass conversion to typescript, but the return type of `Event.toJson` should be `object` (or `any`), not `Object`. The first (lowercase O) is a generic object with unknown properties, while the second (uppercase O) is the default prototype of any new object with methods like `.toString()`. It's a subtle difference, but an important one :)
- Noah