I was not talking about saving and restoring state, but that is interesting in itself of course.
Now you mention this, that was actually really easy in the old days where you had full control over the heap. I just incrementally saved writes to the heap memory pages, and that was also very fast, because the MMU of the CPU has hardware support for watching memory pages being written The beauty of "pure" imperative programming
The Redux approach of course works, but immutable data-structures are not that handy for cyclic data structures like graphs. Maybe some good approaches exists here, but I always end up with using identifiers and lookups, and that gives the same problems as null pointers. It's better than having potential null pointers everywhere, but not ideal.
It would be very interesting to see how a Sodium FRP circuit could be saved and restored!
I tried to implement undo/redo myself after my UI was working with Sodium, but I ended up with a Redux approach where Sodium was only used to build and merge all user commands (aka 'action' in Redux) into a command-stream, apply the command to an immutable-data-model, and using Sodium again to split the new data-model into the Sodium cells. In that case just using Redux would indeed be easier