noflo 1.4.3 → 1.5.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.
Files changed (89) hide show
  1. package/.ecrc +3 -0
  2. package/.eslintignore +2 -0
  3. package/{CHANGES.md → CHANGELOG.md} +520 -527
  4. package/README.md +1 -1
  5. package/bin/noflo-cache-preheat +4 -4
  6. package/components/Graph.d.ts +50 -15
  7. package/components/Graph.js +94 -68
  8. package/examples/http/HelloController.js +9 -6
  9. package/examples/spreadsheet/parse.fbp +3 -3
  10. package/lib/AsCallback.d.ts +22 -9
  11. package/lib/AsCallback.js +69 -18
  12. package/lib/AsComponent.d.ts +1 -1
  13. package/lib/AsComponent.js +5 -3
  14. package/lib/BaseNetwork.d.ts +16 -6
  15. package/lib/BaseNetwork.js +65 -31
  16. package/lib/BasePort.d.ts +39 -12
  17. package/lib/BasePort.js +34 -6
  18. package/lib/Component.d.ts +8 -8
  19. package/lib/Component.js +23 -20
  20. package/lib/ComponentLoader.d.ts +3 -4
  21. package/lib/ComponentLoader.js +9 -10
  22. package/lib/IP.d.ts +12 -8
  23. package/lib/IP.js +6 -4
  24. package/lib/InPort.d.ts +64 -9
  25. package/lib/InPort.js +72 -13
  26. package/lib/InternalSocket.d.ts +53 -7
  27. package/lib/InternalSocket.js +51 -14
  28. package/lib/LegacyNetwork.d.ts +12 -2
  29. package/lib/LegacyNetwork.js +5 -5
  30. package/lib/Network.d.ts +13 -2
  31. package/lib/Network.js +10 -10
  32. package/lib/NoFlo.d.ts +13 -13
  33. package/lib/NoFlo.js +29 -27
  34. package/lib/OutPort.d.ts +64 -13
  35. package/lib/OutPort.js +73 -15
  36. package/lib/Platform.d.ts +1 -1
  37. package/lib/Platform.js +9 -4
  38. package/lib/Ports.d.ts +11 -12
  39. package/lib/Ports.js +8 -4
  40. package/lib/ProcessInput.d.ts +5 -9
  41. package/lib/ProcessInput.js +8 -9
  42. package/lib/ProcessOutput.d.ts +2 -2
  43. package/lib/ProcessOutput.js +5 -5
  44. package/lib/loader/NodeJs.d.ts +0 -1
  45. package/lib/loader/NodeJs.js +104 -105
  46. package/lib/loader/register.d.ts +1 -1
  47. package/lib/loader/register.js +8 -4
  48. package/package.json +16 -11
  49. package/spec/.eslintrc +5 -2
  50. package/spec/AsCallback.js +9 -13
  51. package/spec/AsComponent.js +10 -4
  52. package/spec/AsPromise.js +38 -0
  53. package/spec/CommonJS.cjs +10 -0
  54. package/spec/ComponentLoader.js +2 -2
  55. package/spec/ESModule.mjs +11 -0
  56. package/spec/Network.js +32 -11
  57. package/spec/NetworkSync.js +892 -0
  58. package/spec/Scoping.js +27 -42
  59. package/spec/Subgraph.js +6 -11
  60. package/spec/fixtures/componentloader/components/Output.js +1 -1
  61. package/spec/fixtures/componentloader/components/Repeat.ts +1 -1
  62. package/spec/fixtures/componentloader/components/RepeatAsync.coffee +1 -1
  63. package/spec/fixtures/componentloader/node_modules/example/components/Forward.js +1 -1
  64. package/spec/fixtures/componentloader/node_modules/example/package.json +1 -1
  65. package/spec/fixtures/componentloader/package.json +1 -1
  66. package/spec/fixtures/componentloader/spec/Repeat.yaml +1 -1
  67. package/src/.eslintrc +9 -2
  68. package/src/components/Graph.js +105 -71
  69. package/src/lib/AsCallback.js +71 -16
  70. package/src/lib/AsComponent.js +4 -3
  71. package/src/lib/BaseNetwork.js +48 -15
  72. package/src/lib/BasePort.js +43 -9
  73. package/src/lib/Component.js +8 -8
  74. package/src/lib/ComponentLoader.js +3 -4
  75. package/src/lib/IP.js +7 -4
  76. package/src/lib/InPort.js +74 -13
  77. package/src/lib/InternalSocket.js +49 -9
  78. package/src/lib/LegacyNetwork.js +2 -2
  79. package/src/lib/Network.js +2 -2
  80. package/src/lib/NoFlo.js +15 -13
  81. package/src/lib/OutPort.js +77 -14
  82. package/src/lib/Platform.js +9 -4
  83. package/src/lib/Ports.js +6 -2
  84. package/src/lib/ProcessInput.js +7 -9
  85. package/src/lib/ProcessOutput.js +1 -1
  86. package/src/lib/loader/NodeJs.js +122 -116
  87. package/src/lib/loader/register.js +2 -2
  88. /package/{karma.config.js → karma.config.cjs} +0 -0
  89. /package/{webpack.config.js → webpack.config.cjs} +0 -0
package/spec/Scoping.js CHANGED
@@ -346,31 +346,26 @@ describe('Scope isolation', () => {
346
346
  let in1 = null;
347
347
  let in2 = null;
348
348
  let out = null;
349
- before((done) => {
349
+ before(() => {
350
350
  const fbpData = 'INPORT=Pc1.IN:IN1\n'
351
351
  + 'INPORT=Pc2.IN:IN2\n'
352
352
  + 'OUTPORT=PcMerge.OUT:OUT\n'
353
353
  + 'Pc1(process/Async) -> IN1 PcMerge(process/MergeUnscoped)\n'
354
354
  + 'Pc2(process/Async) -> IN2 PcMerge(process/MergeUnscoped)';
355
- noflo.graph.loadFBP(fbpData, (err, g) => {
356
- if (err) {
357
- done(err);
358
- return;
359
- }
360
- loader.registerComponent('scope', 'MergeUnscoped', g);
361
- loader.load('scope/MergeUnscoped', (err, instance) => {
362
- if (err) {
363
- done(err);
364
- return;
365
- }
355
+ return noflo.graph
356
+ .loadFBP(fbpData)
357
+ .then((g) => {
358
+ loader.registerComponent('scope', 'MergeUnscoped', g);
359
+ return loader.load('scope/MergeUnscoped');
360
+ })
361
+ .then((instance) => {
366
362
  c = instance;
367
363
  in1 = noflo.internalSocket.createSocket();
368
364
  c.inPorts.in1.attach(in1);
369
365
  in2 = noflo.internalSocket.createSocket();
370
366
  c.inPorts.in2.attach(in2);
371
- c.setUp(done);
367
+ return c.setUp();
372
368
  });
373
- });
374
369
  });
375
370
  beforeEach(() => {
376
371
  out = noflo.internalSocket.createSocket();
@@ -489,31 +484,26 @@ describe('Scope isolation', () => {
489
484
  let in1 = null;
490
485
  let in2 = null;
491
486
  let out = null;
492
- before((done) => {
487
+ before(() => {
493
488
  const fbpData = 'INPORT=Pc1.IN:IN1\n'
494
489
  + 'INPORT=Pc2.IN:IN2\n'
495
490
  + 'OUTPORT=PcMerge.OUT:OUT\n'
496
491
  + 'Pc1(process/Unscope) -> IN1 PcMerge(process/Merge)\n'
497
492
  + 'Pc2(process/Unscope) -> IN2 PcMerge';
498
- noflo.graph.loadFBP(fbpData, (err, g) => {
499
- if (err) {
500
- done(err);
501
- return;
502
- }
503
- loader.registerComponent('scope', 'MergeUnscopedOut', g);
504
- loader.load('scope/MergeUnscopedOut', (err, instance) => {
505
- if (err) {
506
- done(err);
507
- return;
508
- }
493
+ return noflo.graph
494
+ .loadFBP(fbpData)
495
+ .then((g) => {
496
+ loader.registerComponent('scope', 'MergeUnscopedOut', g);
497
+ return loader.load('scope/MergeUnscopedOut');
498
+ })
499
+ .then((instance) => {
509
500
  c = instance;
510
501
  in1 = noflo.internalSocket.createSocket();
511
502
  c.inPorts.in1.attach(in1);
512
503
  in2 = noflo.internalSocket.createSocket();
513
504
  c.inPorts.in2.attach(in2);
514
- c.setUp(done);
505
+ return c.setUp();
515
506
  });
516
- });
517
507
  });
518
508
  beforeEach(() => {
519
509
  out = noflo.internalSocket.createSocket();
@@ -631,29 +621,24 @@ describe('Scope isolation', () => {
631
621
  let c = null;
632
622
  let in1 = null;
633
623
  let out = null;
634
- before((done) => {
624
+ before(() => {
635
625
  const fbpData = 'INPORT=Pc1.IN:IN1\n'
636
626
  + 'OUTPORT=PcMergeA.OUT:OUT\n'
637
627
  + 'Pc1(process/Async) -> IN1 PcMergeA(process/MergeA)\n'
638
628
  + '\'twoIIP0\' -> IN2[0] PcMergeA\n'
639
629
  + '\'twoIIP1\' -> IN2[1] PcMergeA';
640
- noflo.graph.loadFBP(fbpData, (err, g) => {
641
- if (err) {
642
- done(err);
643
- return;
644
- }
645
- loader.registerComponent('scope', 'MergeIIPA', g);
646
- loader.load('scope/MergeIIPA', (err, instance) => {
647
- if (err) {
648
- done(err);
649
- return;
650
- }
630
+ return noflo.graph
631
+ .loadFBP(fbpData)
632
+ .then((g) => {
633
+ loader.registerComponent('scope', 'MergeIIPA', g);
634
+ return loader.load('scope/MergeIIPA');
635
+ })
636
+ .then((instance) => {
651
637
  c = instance;
652
638
  in1 = noflo.internalSocket.createSocket();
653
639
  c.inPorts.in1.attach(in1);
654
- c.setUp(done);
640
+ return c.setUp();
655
641
  });
656
- });
657
642
  });
658
643
  beforeEach(() => {
659
644
  out = noflo.internalSocket.createSocket();
package/spec/Subgraph.js CHANGED
@@ -8,22 +8,17 @@ describe('NoFlo Graph component', () => {
8
8
  let c = null;
9
9
  let g = null;
10
10
  let loader = null;
11
- before((done) => {
11
+ before(() => {
12
12
  loader = new noflo.ComponentLoader(baseDir);
13
- loader.listComponents(done);
13
+ return loader.listComponents();
14
14
  });
15
- beforeEach((done) => {
16
- loader.load('Graph', (err, instance) => {
17
- if (err) {
18
- done(err);
19
- return;
20
- }
15
+ beforeEach(() => loader
16
+ .load('Graph')
17
+ .then((instance) => {
21
18
  c = instance;
22
19
  g = noflo.internalSocket.createSocket();
23
20
  c.inPorts.graph.attach(g);
24
- done();
25
- });
26
- });
21
+ }));
27
22
 
28
23
  const Split = function () {
29
24
  const inst = new noflo.Component();
@@ -1,4 +1,4 @@
1
- const noflo = require('../../../../lib/NoFlo');
1
+ const noflo = require('../../../../lib/NoFlo.js');
2
2
 
3
3
  exports.getComponent = function () {
4
4
  const c = new noflo.Component();
@@ -1,4 +1,4 @@
1
- import { Component } from '../../../../lib/NoFlo';
1
+ import { Component } from '../../../../lib/NoFlo.js';
2
2
 
3
3
  exports.getComponent = (): Component => {
4
4
  const c = new Component();
@@ -1,4 +1,4 @@
1
- noflo = require '../../../../lib/NoFlo'
1
+ noflo = require '../../../../lib/NoFlo.js'
2
2
 
3
3
  exports.getComponent = () ->
4
4
  c = new noflo.Component()
@@ -1,4 +1,4 @@
1
- const noflo = require('../../../../../../lib/NoFlo');
1
+ const noflo = require('../../../../../../lib/NoFlo.js');
2
2
 
3
3
  exports.getComponent = function () {
4
4
  const c = new noflo.Component();
@@ -7,4 +7,4 @@
7
7
  "Forward": "components/Forward.js"
8
8
  }
9
9
  }
10
- }
10
+ }
@@ -9,4 +9,4 @@
9
9
  "dependencies": {
10
10
  "example": ""
11
11
  }
12
- }
12
+ }
@@ -7,4 +7,4 @@ cases:
7
7
  in: true
8
8
  expect:
9
9
  out:
10
- equals: true
10
+ equals: true
package/src/.eslintrc CHANGED
@@ -1,3 +1,10 @@
1
1
  {
2
- "extends": "airbnb-base"
3
- }
2
+ "extends": "airbnb-base",
3
+ "rules": {
4
+ "import/extensions": [
5
+ "error", {
6
+ "js": "always"
7
+ }
8
+ ]
9
+ }
10
+ }
@@ -9,14 +9,16 @@
9
9
  import/prefer-default-export,
10
10
  */
11
11
 
12
- import * as noflo from '../lib/NoFlo';
13
- import { deprecated } from '../lib/Platform';
12
+ import { graph as fbpGraph } from 'fbp-graph';
13
+ import { Component } from '../lib/Component.js';
14
+ import { InPorts, OutPorts } from '../lib/Ports.js';
15
+ import { Network } from '../lib/Network.js';
14
16
 
15
17
  // The Graph component is used to wrap NoFlo Networks into components inside
16
18
  // another network.
17
- export class Graph extends noflo.Component {
19
+ export class Graph extends Component {
18
20
  /**
19
- * @param {Object} metadata
21
+ * @param {import("fbp-graph/lib/Types").GraphNodeMetadata} [metadata]
20
22
  */
21
23
  constructor(metadata) {
22
24
  super();
@@ -28,18 +30,18 @@ export class Graph extends noflo.Component {
28
30
  this.starting = false;
29
31
  /** @type {string|null} */
30
32
  this.baseDir = null;
31
- /** @type {noflo.ComponentLoader|null} */
33
+ /** @type {import("../lib/ComponentLoader").ComponentLoader|null} */
32
34
  this.loader = null;
33
35
  this.load = 0;
34
36
 
35
- this.inPorts = new noflo.InPorts({
37
+ this.inPorts = new InPorts({
36
38
  graph: {
37
39
  datatype: 'all',
38
40
  description: 'NoFlo graph definition to be used with the subgraph component',
39
41
  required: true,
40
42
  },
41
43
  });
42
- this.outPorts = new noflo.OutPorts();
44
+ this.outPorts = new OutPorts();
43
45
 
44
46
  this.inPorts.ports.graph.on('ip', (packet) => {
45
47
  if (packet.type !== 'data') { return; }
@@ -48,75 +50,81 @@ export class Graph extends noflo.Component {
48
50
  });
49
51
  }
50
52
 
51
- setGraph(graph, callback) {
53
+ /**
54
+ * @param {import("fbp-graph").Graph|string} graph
55
+ * @returns {Promise<void>}
56
+ */
57
+ setGraph(graph) {
52
58
  this.ready = false;
53
- let promise;
54
59
  if (typeof graph === 'object') {
55
60
  if (typeof graph.addNode === 'function') {
56
61
  // Existing Graph object
57
- promise = this.createNetwork(graph);
58
- } else {
59
- // JSON definition of a graph
60
- promise = noflo.graph.loadJSON(graph)
61
- .then((instance) => this.createNetwork(instance));
62
- }
63
- } else {
64
- let graphName = graph;
65
- if ((graphName.substr(0, 1) !== '/') && (graphName.substr(1, 1) !== ':') && process && process.cwd) {
66
- graphName = `${process.cwd()}/${graphName}`;
62
+ return this.createNetwork(graph);
67
63
  }
68
- promise = noflo.graph.loadFile(graphName)
64
+ // JSON definition of a graph
65
+ return fbpGraph.loadJSON(graph)
69
66
  .then((instance) => this.createNetwork(instance));
70
67
  }
71
- if (callback) {
72
- deprecated('Providing a callback to Graph.setGraph is deprecated, use Promises');
73
- promise.then(() => {
74
- callback(null);
75
- }, callback);
68
+ let graphName = graph;
69
+ if ((graphName.substr(0, 1) !== '/') && (graphName.substr(1, 1) !== ':') && process && process.cwd) {
70
+ graphName = `${process.cwd()}/${graphName}`;
76
71
  }
77
- return promise;
72
+ return fbpGraph.loadFile(graphName)
73
+ .then((instance) => this.createNetwork(instance));
78
74
  }
79
75
 
80
- createNetwork(graph, callback) {
76
+ /**
77
+ * @param {import("fbp-graph").Graph} graph
78
+ * @returns {Promise<void>}
79
+ */
80
+ createNetwork(graph) {
81
81
  this.description = graph.properties.description || '';
82
82
  this.icon = graph.properties.icon || this.icon;
83
83
 
84
84
  const graphObj = graph;
85
- if (!graphObj.name) { graphObj.name = this.nodeId; }
85
+ if (!graphObj.name && this.nodeId) {
86
+ graphObj.name = this.nodeId;
87
+ }
88
+
89
+ const network = new Network(graphObj, {
90
+ componentLoader: this.loader || undefined,
91
+ baseDir: this.baseDir || undefined,
92
+ });
86
93
 
87
- const promise = noflo.createNetwork(graphObj, {
88
- delay: true,
89
- subscribeGraph: false,
90
- componentLoader: this.loader,
91
- baseDir: this.baseDir,
92
- })
93
- .then((network) => {
94
+ return network
95
+ .loader.listComponents()
96
+ .then(() => {
94
97
  this.network = network;
95
- this.emit('network', this.network);
98
+ this.emit('network', network);
96
99
  // Subscribe to network lifecycle
97
- this.subscribeNetwork(this.network);
100
+ this.subscribeNetwork(network);
98
101
  // Wire the network up
99
102
  return network.connect();
100
103
  })
101
104
  .then(() => {
102
- Object.keys(this.network.processes).forEach((name) => {
105
+ Object.keys(network.processes).forEach((name) => {
103
106
  // Map exported ports to local component
104
- const node = this.network.processes[name];
107
+ const node = network.processes[name];
105
108
  this.findEdgePorts(name, node);
106
109
  });
107
110
  // Finally set ourselves as "ready"
108
111
  this.setToReady();
109
112
  });
110
- if (callback) {
111
- deprecated('Providing a callback to Graph.createNetwork is deprecated, use Promises');
112
- promise.then(() => {
113
- callback(null);
114
- }, callback);
115
- }
116
- return promise;
117
113
  }
118
114
 
115
+ /**
116
+ * @typedef SubgraphContext
117
+ * @property {boolean} activated
118
+ * @property {boolean} deactivated
119
+ */
120
+
121
+ /**
122
+ * @param {import("../lib/Network").Network} network
123
+ */
119
124
  subscribeNetwork(network) {
125
+ /**
126
+ * @type {Array<SubgraphContext>}
127
+ */
120
128
  const contexts = [];
121
129
  network.on('start', () => {
122
130
  const ctx = {
@@ -134,7 +142,16 @@ export class Graph extends noflo.Component {
134
142
  });
135
143
  }
136
144
 
145
+ /**
146
+ * @param {import("../lib/InPort").default} port
147
+ * @param {string} nodeName
148
+ * @param {string} portName
149
+ * @returns {boolean|string}
150
+ */
137
151
  isExportedInport(port, nodeName, portName) {
152
+ if (!this.network) {
153
+ return false;
154
+ }
138
155
  // First we check disambiguated exported ports
139
156
  const keys = Object.keys(this.network.graph.inports);
140
157
  for (let i = 0; i < keys.length; i += 1) {
@@ -149,7 +166,16 @@ export class Graph extends noflo.Component {
149
166
  return false;
150
167
  }
151
168
 
169
+ /**
170
+ * @param {import("../lib/OutPort").default} port
171
+ * @param {string} nodeName
172
+ * @param {string} portName
173
+ * @returns {boolean|string}
174
+ */
152
175
  isExportedOutport(port, nodeName, portName) {
176
+ if (!this.network) {
177
+ return false;
178
+ }
153
179
  // First we check disambiguated exported ports
154
180
  const keys = Object.keys(this.network.graph.outports);
155
181
  for (let i = 0; i < keys.length; i += 1) {
@@ -171,26 +197,36 @@ export class Graph extends noflo.Component {
171
197
  return this.emit('ready');
172
198
  });
173
199
  } else {
174
- setTimeout(() => {
175
- this.ready = true;
176
- return this.emit('ready');
177
- },
178
- 0);
200
+ setTimeout(
201
+ () => {
202
+ this.ready = true;
203
+ return this.emit('ready');
204
+ },
205
+ 0,
206
+ );
179
207
  }
180
208
  }
181
209
 
210
+ /**
211
+ * @param {string} name
212
+ * @param {import("../lib/BaseNetwork").NetworkProcess} process
213
+ * @returns {boolean}
214
+ */
182
215
  findEdgePorts(name, process) {
216
+ if (!process.component) {
217
+ return false;
218
+ }
183
219
  const inPorts = process.component.inPorts.ports;
184
220
  const outPorts = process.component.outPorts.ports;
185
221
 
186
222
  Object.keys(inPorts).forEach((portName) => {
187
223
  const port = inPorts[portName];
188
224
  const targetPortName = this.isExportedInport(port, name, portName);
189
- if (targetPortName === false) { return; }
225
+ if (typeof targetPortName !== 'string') { return; }
190
226
  this.inPorts.add(targetPortName, port);
191
- this.inPorts[targetPortName].on('connect', () => {
227
+ this.inPorts.ports[targetPortName].on('connect', () => {
192
228
  // Start the network implicitly if we're starting to get data
193
- if (this.starting) { return; }
229
+ if (this.starting || !this.network) { return; }
194
230
  if (this.network.isStarted()) { return; }
195
231
  if (this.network.startupDate) {
196
232
  // Network was started, but did finish. Re-start simply
@@ -198,14 +234,14 @@ export class Graph extends noflo.Component {
198
234
  return;
199
235
  }
200
236
  // Network was never started, start properly
201
- this.setUp(() => {});
237
+ this.setUp();
202
238
  });
203
239
  });
204
240
 
205
241
  Object.keys(outPorts).forEach((portName) => {
206
242
  const port = outPorts[portName];
207
243
  const targetPortName = this.isExportedOutport(port, name, portName);
208
- if (targetPortName === false) { return; }
244
+ if (typeof targetPortName !== 'string') { return; }
209
245
  this.outPorts.add(targetPortName, port);
210
246
  });
211
247
 
@@ -224,38 +260,36 @@ export class Graph extends noflo.Component {
224
260
  return false;
225
261
  }
226
262
 
227
- setUp(callback) {
263
+ setUp() {
228
264
  this.starting = true;
229
265
  if (!this.isReady()) {
230
- this.once('ready', () => {
231
- this.setUp(callback);
266
+ return new Promise((resolve, reject) => {
267
+ this.once('ready', () => {
268
+ this.setUp().then(resolve, reject);
269
+ });
232
270
  });
233
- return;
234
271
  }
235
272
  if (!this.network) {
236
- callback(null);
237
- return;
273
+ return Promise.resolve();
238
274
  }
239
- this.network.start()
275
+ return this.network.start()
240
276
  .then(() => {
241
277
  this.starting = false;
242
- callback(null);
243
- }, callback);
278
+ });
244
279
  }
245
280
 
246
- tearDown(callback) {
281
+ tearDown() {
247
282
  this.starting = false;
248
283
  if (!this.network) {
249
- callback(null);
250
- return;
284
+ return Promise.resolve();
251
285
  }
252
- this.network.stop()
253
- .then(() => callback(), callback);
286
+ return this.network.stop()
287
+ .then(() => {});
254
288
  }
255
289
  }
256
290
 
257
291
  /**
258
- * @params {Object} metadata
292
+ * @param {import("fbp-graph/lib/Types").GraphNodeMetadata} [metadata]
259
293
  */
260
294
  export function getComponent(metadata) {
261
295
  return new Graph(metadata);