[Feedback Wanted]: Save change history to session storage

Hi all,

I would like your opinion on the possibility of integrating a mechanism into NR that saves the change state (history).

The goal is to avoid losing or having to deploy work in progress.

If you're working and you refresh the editor, you lose your change history. I'd like to make it persistent. It will be possible to restore the history or not.

The API could be opened to plugins to add their state to the storage.

The storage would be configurable in the settings.

Thank you for your feedback.

cc @AllanOricil

1 Like

Definitely a must have feature. Grid outages happen quite often in my city and i dont want to lose my undeployed work due it

Sounds like an interesting idea.

Personally, I would prefer such a feature to use the existing context storage library for sure, not have yet another one. You would maybe want to think about controlling how many versions are retained (should be user selectable with a sensible default).

As an alternative though, why not just extend the current flow backup feature to allow more than a single backup file? A setting in settings.js could be used to restrict the number with the default at 1 in line with the current feature.

This feature is about client-side state management.

Yes, I know. EDITOR client.

I very often find that I have broken something and not noticed, so I end up pressing ctrl-z many times.
It's an excellent idea to improve this 'backup stack', relying on the browser's cache is distinctly iffy.
.
Some ideas I've considered:

  • More flow backup files as Julian says. I'd want to retain these for a configurable duration, up to a day.
  • A backup should include the entire tab which is marked dirty but not the entire flow file? Edit - one backup file per dirty tab
  • An option on Deploy to give the deployment a name to which one might want to revert.
  • Backups would have a sequential id, timestamp and [optional] name. Edit - and the name of the tab backed up.
  • Some method to choose a backup to revert to.
  • Reverting to a backup should be reversible if it turns out not to be the one where I broke the code.

ps When one does a ctrl-z to undo a change, the Deploy button correctly lights up but the nodes rolled back do not acquire a blue dot. It would be helpful if they did.

1 Like

Hehe - that's why I use - yes my own creation - flowhub.org so that I can push out progress to github. The flowhub plugin works by sending my in-browser flow to a github repository without having to deploy the flow. (I guess I could add "save automatically every X mins" feature to get it do that automagically.)

But that's not a solution to the automatic storage of any changes in the client, it's more an approach that I take. I regularly send my in-browser changes to github (via flowhub). So github acts as storage and not a "this code is complete and working" tool.

Plus working on a laptop, I have plenty of time to react to power outages.

I think this could actually be automated using a flow even without other changes. A watch node to look for changes to the flows json file, a delay node to debounce since filing system changes can be a bit noisy, then an exec node to do a git update (or you could simply do a file copy).

Not really since we're talking about in-browser flows - the on the server side flows, certainly, that could be automated using a change node.

Which reminds me that my backup-flow flow uses crontab an is triggered every 15 mins! Ok, perhaps a change node would be better!

@GogoVega

Storing the history in Session Storage is not aligned with the goal of persisting the "undeployed state" locally. Session Storage is cleared as soon as the browser tab closes or the system restarts, meaning users would lose in-progress work during crashes or power outages. Instead, the undeployed state must be stored in persistent local storage (e.g., IndexedDB or Local Storage).
We do not need to persist the entire history locally — only the latest in-progress state, since that’s what users expect to recover if their environment unexpectedly shuts down.
This persistence should also be keyboard-driven (e.g., Ctrl+S), consistent with common productivity software behaviors, reinforcing a sense of control and reliability.

Definition — Undeployed Flow State

Represents work-in-progress that is not yet finalized or ready for deployment/versioning. Its purpose is to ensure users can safely resume editing after browser crashes, OS failures, or power outages, without risking data loss.

I remapped Ctrl-D to Ctrl-S because for me, deploying was/is like saving :wink:

How hard is it for a web-page inside a browser to write to disk? Sure I can do Ctrl-S and save the web-page as a web-page but can I write a file to disk based on a user action? I ask since I am not up-to-date with browser technology.

You would probably end up using something like a download triggered via a user action. I.e. like the "Download" button on the export flow overlay - to have this feature work across all browsers and all OSes.

Ah, I see. Personally, I'm only interested in what happens when deploy is used as that is the direct equivalent of a "save". Since most things in Node-RED don't actually change until you've done a deploy, I don't see much value in creating something complex to try and capture in-flight changes. You can always do ctrl-z a few times anyway. Or reload the Editor page to reset.

But surely, that is actually what most people DO want! As mentioned, changes between deploy being used are no different to changes to a document between saves.

In-flight, un-deployed changes typically are not very many anyway since Node-RED doesn't change process until deployed.

While it might be nice to have un-deployed changes recorded, I would think that such a feature wouldn't often be used.

I'm not necessarily against that idea but I worry about added complexity.

very hard! Deliberately so as it is a potential security nightmare.

However, the browser does, of course, have its own storage - though you do have to watch out for size limitations.

But as @AllanOricil said, that storage is wiped upon restart.

This use-case is specifically for folks who make large changes (e.g.. refactorings) but want to save these without deploying and changing the server.

I and probably you, don't work that way. I deploy my changes fairly rapidly or - as I described above - push them off to github. But others are stuck between leaving the browser open or deploying and hoping nothing breaks.

This use-case is a particular one to developers of large and complex flows that are required to work and can't just break. How do you address the problem of making changes that take several days to complete, i.e. your browser has to stay open and the deploy button isn't allowed to be pressed.

EDIT: P.s. this use-case is specifically why I created flowhub.org and also the flow compare plugin - to be able to track changes, without deploying and changing the server.

By session, I meant per user.

The concept is as follows:

Each time the history changes, its state is saved to a storage. This storage maintains the individual state for each logged-in user. The storage is persistent and modifiable in the settings.

If a user leaves a dirty workspace for any reason, his state will be restored, if the user agrees, at the next session.

Optionally, the user can choose to automatically restore the history, in this case a clean workspace containing a history will also be restored. Which means that undo will do its job.

History = CTRL-Z and CTRL-Y.

I don't see the point of using CTRL-S; if your app crashes, a recovery mode opens.

This is the fastest way to approach the functionality, but I'm not sure it's the most optimal. As a reminder, the history state changes with each manipulation.

Users don’t version every small change they make to their flows in Git — they only commit meaningful milestones. Node-RED already supports this by allowing users to Deploy when they want to save a new milestone to the server’s data storage. That’s a reliable safety net after the user explicitly decides the work is ready.
But there’s a gap: users often have work in progress — messy, experimental, not-ready-to-deploy changes. If something goes wrong (browser crash, tab closed, laptop dies), that work is gone. No deployment means no persistence.
This is why we need a local history backup feature in the client.
It continuously stores the latest working state in the browser (like VS Code autosave). It’s not a full version control system. It’s not undo/redo history. It’s just a “break glass if needed” backup so users don’t lose unfinished work.

To make it painfully simple:

Feature What it does When it helps What it does not do
:white_check_mark: Deploy (existing) Saves a milestone to the server When the change is ready and intentional Doesn’t protect draft changes
:white_check_mark: Local history backup (new) Saves the most recent draft locally When the browser or session crashes Doesn’t allow stepping back through history (Ctrl+Z)
:cross_mark: Full history snapshots Stores every action for revert Not needed here Too heavy, not the goal

Bottom line:
Deploy protects progress you meant to keep. Local backup protects progress you didn’t expect to lose.

No illusions. No over-engineering. Just resilience where it’s actually needed.

Sorry, I can't actually tell from @GogoVega's clarification what will be stored and where.
As shown by my post before, I'm very enthusiastic about improving the process of rolling back deploys.

Ah. Saving undeployed changes if the browser crashes: totally useless for me (but I agree, not useless for Allan in a land of powercuts)

Still, knock yourself out if it's something users expect. Maybe it's more important for someone working on a cloud based Flowfuse instance?

It is not only in power outages. Browser can crash, app can crash, OS can crash, NR server could he unavailable. Vscode has a restoring mechanism for unexpected crashes. Node-RED does not. All modern webapps has some state managent for this exact scenario

Sorry,

I'll use an example to explain better.

Let's say you open a clean editor and add an inject node, then a debug node, then wire nodes, and finally edit the inject node.

The history will be: [add, add, add, edit] (add inject, add debug, add link, edit node)

The goal of this is to store this history so that a user can restore it, whether because the editor was closed abruptly or the user switched sessions... I don't care.

In short, to restore the editor from the previous session.

Whether the choice of storage, the choice to restore automatically, or the choice to restore across multiple sessions and the history depth will all be configurable.

Technically, the full history since the last deployed version must be kept to accurately restore the editor from the previous session.

We won't discuss snapshots (like FF does) here; that's not the purpose.

Not so. There are several types of browser storage and some certainly persists across browser restarts. For the feature we are now talking about (in-flight, un-deployed changes in the Editor), this would be my preferred approach.

The browser navigator.storage.persist() API method asks the user if they will allow the page to persist storage.