@rosepetal/node-red-contrib-async-function 1.0.3 → 1.1.0

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 CHANGED
@@ -20,7 +20,7 @@ Run heavy computations in Node-RED without slowing down your flows. This node wo
20
20
 
21
21
  ## How It Works
22
22
 
23
- Drop an **async function** node into your flow. Write your code just like you would in a regular function node. The difference? Your code runs in a separate worker thread by default (or a child process if configured), so heavy operations won't freeze Node-RED.
23
+ Drop a **worker function** node into your flow. Write your code just like you would in a regular function node. The difference? Your code runs in a separate worker thread by default (or a child process if configured), so heavy operations won't freeze Node-RED.
24
24
 
25
25
  ## When to Use This
26
26
 
@@ -66,7 +66,7 @@ return msg;
66
66
 
67
67
  ## Typical Flow
68
68
 
69
- 1. Add an **async function** node to your workspace.
69
+ 1. Add a **worker function** node to your workspace.
70
70
  2. Connect an Inject node (input) and a Debug node (output).
71
71
  3. Write a simple script:
72
72
  ```javascript
@@ -194,7 +194,9 @@ npm install @rosepetal/node-red-contrib-async-function
194
194
 
195
195
  Restart Node-RED and find the node in the **function** category.
196
196
 
197
- ## Migration from Earlier Versions
197
+ ## Migration
198
+
199
+ ### From minWorkers/maxWorkers
198
200
 
199
201
  If you're upgrading from a version that used `minWorkers` and `maxWorkers`:
200
202
  - Your existing flows will automatically migrate to use the new `numWorkers` parameter
@@ -226,7 +226,7 @@ async function loadConfiguredModules(libs) {
226
226
  moduleVars.push(lib.var);
227
227
  moduleValues.push(loadedModules[lib.var]);
228
228
  } catch (err) {
229
- console.error(`[async-function] Failed to load module ${lib.module}: ${err.message}`);
229
+ console.error(`[worker-function] Failed to load module ${lib.module}: ${err.message}`);
230
230
  failedModules.push({ module: lib.module, var: lib.var, error: err.message });
231
231
  }
232
232
  }
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Module Installer
3
3
  *
4
- * Handles automatic installation of npm modules for the async-function node.
4
+ * Handles automatic installation of npm modules for the worker-function node.
5
5
  * Modules are installed in the Node-RED user directory (~/.node-red).
6
6
  */
7
7
 
@@ -43,21 +43,21 @@ async function getNodeRedUserDir() {
43
43
  */
44
44
  async function installModule(moduleName) {
45
45
  if (!moduleName || typeof moduleName !== 'string') {
46
- console.error('[async-function] Invalid module name');
46
+ console.error('[worker-function] Invalid module name');
47
47
  return false;
48
48
  }
49
49
 
50
50
  // Sanitize module name to prevent command injection
51
51
  const sanitizedName = moduleName.trim();
52
52
  if (!/^(@[\w-]+\/)?[\w.-]+(@[\w.-]+)?$/.test(sanitizedName)) {
53
- console.error(`[async-function] Invalid module name format: ${sanitizedName}`);
53
+ console.error(`[worker-function] Invalid module name format: ${sanitizedName}`);
54
54
  return false;
55
55
  }
56
56
 
57
57
  const userDir = await getNodeRedUserDir();
58
58
 
59
59
  try {
60
- console.log(`[async-function] Installing module: ${sanitizedName} in ${userDir}`);
60
+ console.log(`[worker-function] Installing module: ${sanitizedName} in ${userDir}`);
61
61
 
62
62
  await new Promise((resolve, reject) => {
63
63
  const child = spawn('npm', ['install', sanitizedName], {
@@ -98,11 +98,11 @@ async function installModule(moduleName) {
98
98
  });
99
99
  });
100
100
 
101
- console.log(`[async-function] Successfully installed: ${sanitizedName}`);
101
+ console.log(`[worker-function] Successfully installed: ${sanitizedName}`);
102
102
  return true;
103
103
 
104
104
  } catch (err) {
105
- console.error(`[async-function] Failed to install ${sanitizedName}: ${err.message}`);
105
+ console.error(`[worker-function] Failed to install ${sanitizedName}: ${err.message}`);
106
106
  return false;
107
107
  }
108
108
  }
@@ -233,7 +233,7 @@ async function loadConfiguredModules() {
233
233
  moduleVars.push(lib.var);
234
234
  moduleValues.push(loadedModules[lib.var]);
235
235
  } catch (err) {
236
- console.error(`[async-function] Failed to load module ${lib.module}: ${err.message}`);
236
+ console.error(`[worker-function] Failed to load module ${lib.module}: ${err.message}`);
237
237
  failedModules.push({ module: lib.module, var: lib.var, error: err.message });
238
238
  }
239
239
  }
@@ -1,13 +1,13 @@
1
- <!-- Async Function Node - Node-RED Editor Configuration -->
1
+ <!-- Worker Function Node - Node-RED Editor Configuration -->
2
2
 
3
3
  <script type="text/javascript">
4
- RED.nodes.registerType('async-function', {
4
+ RED.nodes.registerType('worker-function', {
5
5
  category: 'function',
6
6
  color: '#d7d9dc',
7
7
  defaults: {
8
8
  name: { value: '' },
9
9
  func: {
10
- value: '// Write your async code here\n// The code runs in a worker thread or child process\n// Available: msg, return, async/await, require(), node.warn/error/log,\n// flow/global/context (snapshot-based)\n\nreturn msg;'
10
+ value: '// Write your code here\n// The code runs in a worker thread or child process\n// Available: msg, return, async/await, require(), node.warn/error/log,\n// flow/global/context (snapshot-based)\n\nreturn msg;'
11
11
  },
12
12
  outputs: { value: 1, validate: RED.validators.number() },
13
13
  timeout: { value: 30000, validate: RED.validators.number() },
@@ -21,7 +21,7 @@
21
21
  outputs: 1,
22
22
  icon: 'function.svg',
23
23
  label: function() {
24
- return this.name || 'async function';
24
+ return this.name || 'worker function';
25
25
  },
26
26
  labelStyle: function() {
27
27
  return this.name ? 'node_label_italic' : '';
@@ -250,7 +250,7 @@
250
250
  status.text('Restarting...').css('color', '#666');
251
251
 
252
252
  $.ajax({
253
- url: 'async-function/' + nodeId + '/restart',
253
+ url: 'worker-function/' + nodeId + '/restart',
254
254
  type: 'POST',
255
255
  success: function(data) {
256
256
  status.text('✓ Workers restarted').css('color', 'green');
@@ -346,7 +346,7 @@
346
346
  });
347
347
  </script>
348
348
 
349
- <script type="text/html" data-template-name="async-function">
349
+ <script type="text/html" data-template-name="worker-function">
350
350
  <style>
351
351
  .async-func-tabs-row {
352
352
  margin-bottom: 0;
@@ -519,7 +519,7 @@
519
519
  </div>
520
520
  </script>
521
521
 
522
- <script type="text/html" data-help-name="async-function">
522
+ <script type="text/html" data-help-name="worker-function">
523
523
  <p>Execute custom JavaScript code in a worker thread or child process to prevent event loop blocking.</p>
524
524
 
525
525
  <h3>Inputs</h3>
@@ -1,8 +1,8 @@
1
1
  /**
2
- * Async Function Node
2
+ * Worker Function Node
3
3
  *
4
4
  * A Node-RED function node that executes user code in worker threads
5
- * to prevent event loop blocking.
5
+ * or child processes to prevent event loop blocking.
6
6
  */
7
7
 
8
8
  const path = require('path');
@@ -387,7 +387,7 @@ function applyPerformanceMetrics(node, originalMsg, targetMsg, performance) {
387
387
  return;
388
388
  }
389
389
 
390
- const label = (typeof node.name === 'string' && node.name.trim()) ? node.name.trim() : 'async function';
390
+ const label = (typeof node.name === 'string' && node.name.trim()) ? node.name.trim() : 'worker function';
391
391
  if (!label) {
392
392
  return;
393
393
  }
@@ -656,7 +656,7 @@ module.exports = function(RED) {
656
656
  }
657
657
 
658
658
  // Log error
659
- node.error(`Async function error: ${err.message}`, msg);
659
+ node.error(`Worker function error: ${err.message}`, msg);
660
660
 
661
661
  // Propagate error to Catch node
662
662
  done(err);
@@ -703,12 +703,12 @@ module.exports = function(RED) {
703
703
  }
704
704
 
705
705
  // Register the node type
706
- RED.nodes.registerType('async-function', AsyncFunctionNode, {
706
+ RED.nodes.registerType('worker-function', AsyncFunctionNode, {
707
707
  dynamicModuleList: 'libs'
708
708
  });
709
709
 
710
710
  // HTTP endpoint to restart workers for a specific node
711
- RED.httpAdmin.post('/async-function/:id/restart', async function(req, res) {
711
+ RED.httpAdmin.post('/worker-function/:id/restart', async function(req, res) {
712
712
  const node = RED.nodes.getNode(req.params.id);
713
713
  if (!node || !node.pool) {
714
714
  return res.status(404).json({ error: 'Node not found or pool not initialized' });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rosepetal/node-red-contrib-async-function",
3
- "version": "1.0.3",
3
+ "version": "1.1.0",
4
4
  "description": "A Node-RED function node that runs code in worker threads to keep your flows responsive",
5
5
  "repository": {
6
6
  "type": "git",
@@ -9,7 +9,7 @@
9
9
  "keywords": [
10
10
  "node-red",
11
11
  "function",
12
- "async",
12
+ "worker-function",
13
13
  "worker-threads",
14
14
  "non-blocking",
15
15
  "performance",
@@ -34,7 +34,7 @@
34
34
  "node-red": {
35
35
  "version": ">=2.0.0",
36
36
  "nodes": {
37
- "async-function": "nodes/async-function.js"
37
+ "worker-function": "nodes/worker-function.js"
38
38
  }
39
39
  },
40
40
  "dependencies": {}