@theotherwillembotha/node-red-cluster 0.0.55 → 0.4.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -15
- package/build/GenerateNodes.d.ts +2 -0
- package/build/GenerateNodes.d.ts.map +1 -0
- package/build/GenerateNodes.js +2 -1
- package/build/Nodes.html +57 -64
- package/build/Nodes.js +49745 -12
- package/build/Plugins.html +11 -0
- package/build/Plugins.js +49412 -54
- package/build/cluster/node/ClusterConfigNode.d.ts +35 -0
- package/build/cluster/node/ClusterConfigNode.d.ts.map +1 -0
- package/build/cluster/node/ClusterConfigNode.js +1 -1
- package/build/cluster/node/ClusterPublishNode.d.ts +25 -0
- package/build/cluster/node/ClusterPublishNode.d.ts.map +1 -0
- package/build/cluster/node/ClusterPublishNode.js +1 -1
- package/build/cluster/node/ClusterSubscribeNode.d.ts +17 -0
- package/build/cluster/node/ClusterSubscribeNode.d.ts.map +1 -0
- package/build/cluster/service/ClusterClient.d.ts +49 -0
- package/build/cluster/service/ClusterClient.d.ts.map +1 -0
- package/build/cluster/service/ClusterClient.js +2 -2
- package/build/cluster/service/ClusterService.d.ts +19 -0
- package/build/cluster/service/ClusterService.d.ts.map +1 -0
- package/build/cluster/service/ClusterService.js +47 -20
- package/build/index.d.ts +4 -0
- package/build/index.d.ts.map +1 -0
- package/build/runtime/NodeManagerRuntime.js +140 -0
- package/package.json +7 -4
package/README.md
CHANGED
|
@@ -4,21 +4,6 @@ Connect multiple Node-RED instances into a coordinated cluster. Instances discov
|
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
> [!IMPORTANT]
|
|
8
|
-
> **This plugin requires [`@theotherwillembotha/node-red-plugincore`](https://github.com/theotherwillembotha/nodered_plugincore) to be installed.**
|
|
9
|
-
>
|
|
10
|
-
> `node-red-plugincore` is declared as a dependency and npm will install it automatically. However, due to a [known Node-RED limitation](https://github.com/node-red/node-red/issues/3529), packages that arrive as transitive npm dependencies are only discovered by the Node-RED runtime on the **next startup**.
|
|
11
|
-
>
|
|
12
|
-
> **Two options:**
|
|
13
|
-
> - Install [`@theotherwillembotha/node-red-plugincore`](https://flows.nodered.org/node/@theotherwillembotha/node-red-plugincore) via the palette manager or `npm install` **first**, then install this plugin.
|
|
14
|
-
> - Install this plugin directly, then **restart Node-RED once** and both packages will be fully loaded.
|
|
15
|
-
|
|
16
|
-
---
|
|
17
|
-
|
|
18
|
-
> **Early development** - this package is still in development. APIs and configuration may change between releases.
|
|
19
|
-
|
|
20
|
-
---
|
|
21
|
-
|
|
22
7
|
## What it does
|
|
23
8
|
|
|
24
9
|
Each Node-RED instance in the cluster connects to a NATS server. A **Cluster Publish** node sends a message onto a named subject; any other instance with a matching **Cluster Subscribe** node receives it. Subjects are automatically namespaced by instance, so you can subscribe to `field-a.sensors.temperature` for data from one specific instance, or `*.sensors.temperature` to receive it from all of them simultaneously.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GenerateNodes.d.ts","sourceRoot":"","sources":["../src/GenerateNodes.ts"],"names":[],"mappings":""}
|
package/build/GenerateNodes.js
CHANGED
|
@@ -9,11 +9,12 @@ const ClusterPublishNode_1 = require("./cluster/node/ClusterPublishNode");
|
|
|
9
9
|
const ClusterSubscribeNode_1 = require("./cluster/node/ClusterSubscribeNode");
|
|
10
10
|
new node_red_plugincore_1.NodeGenerator("./src/")
|
|
11
11
|
// services.
|
|
12
|
+
.registerService(node_red_plugincore_1.NodeTypeService)
|
|
12
13
|
.registerService(ClusterService_1.ClusterService)
|
|
13
14
|
// nodes
|
|
14
15
|
.registerNode(ClusterConfigNode_1.ClusterConfigNode)
|
|
15
16
|
.registerNode(ClusterPublishNode_1.ClusterPublishNode)
|
|
16
17
|
.registerNode(ClusterSubscribeNode_1.ClusterSubscribeNode)
|
|
17
18
|
// done.
|
|
18
|
-
.generate("./build/Nodes", "./build/Plugins");
|
|
19
|
+
.generate("./build/Nodes", "./build/Plugins", "@theotherwillembotha/node-red-cluster");
|
|
19
20
|
process.exit(0);
|
package/build/Nodes.html
CHANGED
|
@@ -7,10 +7,52 @@
|
|
|
7
7
|
You have been warned.
|
|
8
8
|
|
|
9
9
|
-->
|
|
10
|
-
|
|
11
10
|
<!-- ClusterConfigNode -->
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
|
|
12
|
+
<style>
|
|
13
|
+
</style>
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
<!-- ClusterPublishNode -->
|
|
17
|
+
|
|
18
|
+
<style>
|
|
19
|
+
</style>
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
<!-- ClusterSubscribeNode -->
|
|
23
|
+
|
|
24
|
+
<style>
|
|
25
|
+
.cluster-sub-ac-dropdown {
|
|
26
|
+
position: fixed;
|
|
27
|
+
background: var(--red-ui-primary-background, #fff);
|
|
28
|
+
border: 1px solid var(--red-ui-form-input-border-color, #ccc);
|
|
29
|
+
border-top: none;
|
|
30
|
+
border-radius: 0 0 4px 4px;
|
|
31
|
+
max-height: 220px;
|
|
32
|
+
overflow-y: auto;
|
|
33
|
+
z-index: 2000;
|
|
34
|
+
display: none;
|
|
35
|
+
box-shadow: 0 4px 8px rgba(0,0,0,0.15);
|
|
36
|
+
}
|
|
37
|
+
.cluster-sub-ac-item {
|
|
38
|
+
padding: 5px 10px;
|
|
39
|
+
cursor: pointer;
|
|
40
|
+
display: flex;
|
|
41
|
+
justify-content: space-between;
|
|
42
|
+
align-items: center;
|
|
43
|
+
font-size: 12px;
|
|
44
|
+
border-bottom: 1px solid var(--red-ui-secondary-border-color, #eee);
|
|
45
|
+
}
|
|
46
|
+
.cluster-sub-ac-item:last-child { border-bottom: none; }
|
|
47
|
+
.cluster-sub-ac-item:hover,
|
|
48
|
+
.cluster-sub-ac-item.cluster-sub-ac-active {
|
|
49
|
+
background: var(--red-ui-secondary-background-selected, #e5f3ff);
|
|
50
|
+
}
|
|
51
|
+
.cluster-sub-ac-value { font-family: monospace; font-weight: 500; }
|
|
52
|
+
.cluster-sub-ac-desc { color: var(--red-ui-tertiary-text-color, #999); font-size: 11px; white-space: nowrap; margin-left: 8px; }
|
|
53
|
+
</style>
|
|
54
|
+
|
|
55
|
+
|
|
14
56
|
<script type="text/javascript">
|
|
15
57
|
RED.nodes.registerType('ClusterConfigNode', {
|
|
16
58
|
category: 'config',
|
|
@@ -191,9 +233,7 @@ A single Node-RED instance can belong to multiple clusters simultaneously by cre
|
|
|
191
233
|
| Red ring | Connection error or disconnected |
|
|
192
234
|
| Grey ring | Idle (not yet started) |
|
|
193
235
|
</script>
|
|
194
|
-
|
|
195
|
-
<style>
|
|
196
|
-
</style>
|
|
236
|
+
|
|
197
237
|
<script type="text/javascript">
|
|
198
238
|
RED.nodes.registerType('ClusterPublishNode', {
|
|
199
239
|
category: 'cluster',
|
|
@@ -294,7 +334,7 @@ A single Node-RED instance can belong to multiple clusters simultaneously by cre
|
|
|
294
334
|
<div id="cluster-publish-observer-warning" style="display:none;" class="form-row">
|
|
295
335
|
<div style="padding: 6px 8px; background: #fff3cd; border: 1px solid #ffc107; border-radius: 4px; color: #856404;">
|
|
296
336
|
<i class="fa fa-exclamation-triangle"></i>
|
|
297
|
-
This node is <strong>disabled</strong> the linked cluster config is set to <strong>Observer</strong> role. Publishing will be silently ignored at runtime.
|
|
337
|
+
This node is <strong>disabled</strong> - the linked cluster config is set to <strong>Observer</strong> role. Publishing will be silently ignored at runtime.
|
|
298
338
|
</div>
|
|
299
339
|
</div>
|
|
300
340
|
|
|
@@ -321,7 +361,7 @@ A single Node-RED instance can belong to multiple clusters simultaneously by cre
|
|
|
321
361
|
</script>
|
|
322
362
|
|
|
323
363
|
<script type="text/markdown" data-help-name='ClusterPublishNode'>
|
|
324
|
-
> **Early development**
|
|
364
|
+
> **Early development** - this package is still in development. APIs and configuration may change.
|
|
325
365
|
|
|
326
366
|
Publishes a Node-RED message to the cluster. Any instance with a matching **Cluster Subscribe** pattern will receive it.
|
|
327
367
|
|
|
@@ -330,75 +370,29 @@ If the linked Cluster Config is set to **Observer** role, this node displays a w
|
|
|
330
370
|
### Properties
|
|
331
371
|
|
|
332
372
|
: *cluster* (config) : The Cluster Config node that defines which cluster to publish to.
|
|
333
|
-
: *subject* (string) : Subject identifier for this publisher
|
|
334
|
-
: *mode* (select) : **Durable**
|
|
373
|
+
: *subject* (string) : Subject identifier for this publisher - e.g. `commands.opengate` or `sensors.temperature`. Dot-notation is supported.
|
|
374
|
+
: *mode* (select) : **Durable** - persisted in JetStream; delivered even if the subscriber is offline. **Ephemeral** - discarded if not consumed within the TTL window; use for time-sensitive data.
|
|
335
375
|
: *TTL* (number) : Ephemeral mode only. Seconds before an undelivered message is discarded. Default: 30.
|
|
336
376
|
|
|
337
377
|
### Subject routing
|
|
338
378
|
|
|
339
379
|
The full NATS subject is composed automatically as `<rootPath>.<instanceId>.<subject>`.
|
|
340
380
|
|
|
341
|
-
Example
|
|
381
|
+
Example - Root Path `/nodered-cluster`, Instance ID `field-a`, Subject `commands.opengate`:
|
|
342
382
|
|
|
343
383
|
```
|
|
344
384
|
nodered-cluster.field-a.commands.opengate
|
|
345
385
|
```
|
|
346
386
|
|
|
347
387
|
Subscribers use wildcards to match across instances:
|
|
348
|
-
- `*.commands.opengate`
|
|
349
|
-
- `field-a.>`
|
|
388
|
+
- `*.commands.opengate` - receives this subject from any instance
|
|
389
|
+
- `field-a.>` - receives all subjects from `field-a`
|
|
350
390
|
|
|
351
391
|
### Input
|
|
352
392
|
|
|
353
393
|
: *msg.payload* : Serialised as JSON and published to the cluster subject.
|
|
354
394
|
</script>
|
|
355
|
-
<!-- ClusterSubscribeNode -->
|
|
356
|
-
<style>
|
|
357
|
-
.cluster-sub-ac-dropdown {
|
|
358
|
-
position: fixed;
|
|
359
|
-
background: var(--red-ui-primary-background, #fff);
|
|
360
|
-
border: 1px solid var(--red-ui-form-input-border-color, #ccc);
|
|
361
|
-
border-top: none;
|
|
362
|
-
border-radius: 0 0 4px 4px;
|
|
363
|
-
max-height: 220px;
|
|
364
|
-
overflow-y: auto;
|
|
365
|
-
z-index: 2000;
|
|
366
|
-
display: none;
|
|
367
|
-
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
.cluster-sub-ac-item {
|
|
371
|
-
padding: 5px 10px;
|
|
372
|
-
cursor: pointer;
|
|
373
|
-
display: flex;
|
|
374
|
-
justify-content: space-between;
|
|
375
|
-
align-items: center;
|
|
376
|
-
font-size: 12px;
|
|
377
|
-
border-bottom: 1px solid var(--red-ui-secondary-border-color, #eee);
|
|
378
|
-
}
|
|
379
|
-
|
|
380
|
-
.cluster-sub-ac-item:last-child {
|
|
381
|
-
border-bottom: none;
|
|
382
|
-
}
|
|
383
395
|
|
|
384
|
-
.cluster-sub-ac-item:hover,
|
|
385
|
-
.cluster-sub-ac-item.cluster-sub-ac-active {
|
|
386
|
-
background: var(--red-ui-secondary-background-selected, #e5f3ff);
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
.cluster-sub-ac-value {
|
|
390
|
-
font-family: monospace;
|
|
391
|
-
font-weight: 500;
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
.cluster-sub-ac-desc {
|
|
395
|
-
color: var(--red-ui-tertiary-text-color, #999);
|
|
396
|
-
font-size: 11px;
|
|
397
|
-
white-space: nowrap;
|
|
398
|
-
margin-left: 8px;
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
</style>
|
|
402
396
|
<script type="text/javascript">
|
|
403
397
|
RED.nodes.registerType('ClusterSubscribeNode', {
|
|
404
398
|
category: 'cluster',
|
|
@@ -570,7 +564,7 @@ Subscribers use wildcards to match across instances:
|
|
|
570
564
|
_suggestions = buildSuggestions(data);
|
|
571
565
|
},
|
|
572
566
|
error: function() {
|
|
573
|
-
console.warn('[ClusterSubscribe] Discovery unavailable
|
|
567
|
+
console.warn('[ClusterSubscribe] Discovery unavailable - autocomplete disabled');
|
|
574
568
|
}
|
|
575
569
|
});
|
|
576
570
|
}
|
|
@@ -617,7 +611,7 @@ Subscribers use wildcards to match across instances:
|
|
|
617
611
|
</script>
|
|
618
612
|
|
|
619
613
|
<script type="text/markdown" data-help-name='ClusterSubscribeNode'>
|
|
620
|
-
> **Early development**
|
|
614
|
+
> **Early development** - this package is still in development. APIs and configuration may change.
|
|
621
615
|
|
|
622
616
|
Subscribes to one or more cluster subjects and emits a Node-RED message each time a matching message arrives from any instance in the cluster.
|
|
623
617
|
|
|
@@ -628,7 +622,7 @@ Subscribes to one or more cluster subjects and emits a Node-RED message each tim
|
|
|
628
622
|
|
|
629
623
|
### Subject pattern syntax
|
|
630
624
|
|
|
631
|
-
Patterns are scoped to the cluster's Root Path automatically
|
|
625
|
+
Patterns are scoped to the cluster's Root Path automatically - you only write the part after the root prefix.
|
|
632
626
|
|
|
633
627
|
| Pattern | Matches |
|
|
634
628
|
|---------|---------|
|
|
@@ -647,7 +641,6 @@ When the editor opens, the node fetches live discovery data from the cluster and
|
|
|
647
641
|
### Outputs
|
|
648
642
|
|
|
649
643
|
: *msg.payload* : The payload published by the remote Cluster Publish node.
|
|
650
|
-
: *msg.topic* : The full NATS subject the message arrived on
|
|
644
|
+
: *msg.topic* : The full NATS subject the message arrived on - use this to identify which instance sent the message.
|
|
651
645
|
</script>
|
|
652
|
-
|
|
653
646
|
|