const data = {} const config = { RED: null } /** * Checks if a Client/Socket ID has been assigned to this message, * and whether the node type is being scoped to a specific client. * If so, do not store this in our centralised datastore * @param {*} msg * @returns */ function canSaveInStore (base, node, msg) { // gets a list of node types that allow for client configuration/limits const constrained = base.acceptsClientConfig const checks = [] if (constrained.includes(node.type)) { // core check if (msg._client?.socketId) { // we are in a node type that allows for definition of specific clients, // and a client has been defined checks.push(false) } // plugin checks // loop over plugins and check if any have defined a custom isValidConnection function // if so, use that to determine if the connection is valid for (const plugin of config.RED.plugins.getByType('node-red-dashboard-2')) { if (plugin.hooks?.onCanSaveInStore) { checks.push(plugin.hooks.onCanSaveInStore(msg)) } } } return checks.length === 0 || !checks.includes(false) } const getters = { RED () { return config.RED }, // given a widget id, return the latest msg received msg (id) { return config.RED.util.cloneMessage(data[id]) } } const setters = { // map the instance of Node-RED to this module setConfig (RED) { config.RED = RED }, // remove data associated to a given widget clear (id) { delete data[id] }, /** * * @param {*} base - the ui-base node associated with this widget * @param {*} node - the UI node for which we are storing data * @param {*} msg - the msg to be stored */ save (base, node, msg) { if (Array.isArray(msg)) { /// need to check msg by msg const filtered = [] for (const m of msg) { if (canSaveInStore(base, node, m)) { filtered.push(config.RED.util.cloneMessage(m)) } } data[node.id] = filtered } else { if (canSaveInStore(base, node, msg)) { data[node.id] = config.RED.util.cloneMessage(msg) } } }, // given a widget id, and msg, store in an array of history of values // useful for charting widgets append (base, node, msg) { if (canSaveInStore(base, node, msg)) { if (!data[node.id]) { data[node.id] = [] } data[node.id].push(config.RED.util.cloneMessage(msg)) } } } module.exports = { get: getters.msg, RED: getters.RED, setConfig: setters.setConfig, save: setters.save, append: setters.append, clear: setters.clear }