TLDR: statestore
is for overriding Node-RED config, and the updated (including dynamic updates) config is sent on the ui-config
event. The datastore
tracks msg
objects, generally only the last received message, but can support a history of messages if required using datastore.append
in the case of charts (as an example).
Server-Side Stores
Docs: State Management | Node-RED Dashboard 2.0
datastore
: A map of each widget to the latestmsg
received by a respective node in the Editor.statestore
: A store for all dynamic properties set on widgets (e.g. visibility or setting a property at runtime). Often, these values are overrides of the base configuration defined in Node-RED. (This is our equivalent of FlexDash's state store.)
The pattern we've implemented in core is that the statestore
is populated when a node receives messages, and detects a property in that message that it is interested in, e.g in ui-button.js
:
Loading Events
Docs: Events Architecture | Node-RED Dashboard 2.0
UI Config/State
When the Dashboard is first loaded on a page refresh or navigation, we send a ui-config
event, which details every widget, page, theme, etc. This contains the specification for each node (which is the Node-RED config schema), but with the relevant values overriden by the widget's statestore
.
This is the single source of truth for the state of a widget at that time.
When building your own node, in the Node-RED .js
file, copy the pattern seen in the buttons above. To access the stores from within a third-party node, you can call:
const group = RED.nodes.getNode(config.group)
const base = group.getBase()
base.stores.<data/state>
I don't have an example in ui-example
node for dynamic properties yet, so I'll try and get something added.
Anything you put into the statestore
will be merged with the config of your node and transmitted for ui-config
.
Widget Load
For each widget, when that itself loads, we send a widget-load(msg)
event, which passes the latest received msg
from the datastore
.
The widget does not need to do anything with this if it's not appropriate. The dynamic/updated state would already have been sent to the widget from the statestore
via the merged ui-config
schema.
Updates Required
- I had a mis-typed statement in the
statestore
description, which claimed " Often, these values are overrides of the base configuration found in thedatastore
.". This is not true, and I corrected above, it should read: "Often, these values are overrides of the base configuration defined in Node-RED. " - On my side, I do need to update the "Input" events architecture diagram to show an example of the Dynamic Properties approach we now have
Ideas for Improvement:
Alongside the msg
being sent in widget-load
, I could also pass the config
? It's already sent with the ui-config
event, but for peace of mind, it's a lightweight addition, that makes sense to include?