noflo 1.4.3 → 1.5.1
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/.ecrc +3 -0
- package/.eslintignore +2 -0
- package/{CHANGES.md → CHANGELOG.md} +527 -527
- package/README.md +1 -1
- package/bin/noflo-cache-preheat +4 -4
- package/components/Graph.d.ts +50 -15
- package/components/Graph.js +94 -68
- package/examples/http/HelloController.js +9 -6
- package/examples/spreadsheet/parse.fbp +3 -3
- package/lib/AsCallback.d.ts +22 -9
- package/lib/AsCallback.js +69 -18
- package/lib/AsComponent.d.ts +1 -1
- package/lib/AsComponent.js +5 -3
- package/lib/BaseNetwork.d.ts +16 -6
- package/lib/BaseNetwork.js +65 -31
- package/lib/BasePort.d.ts +39 -12
- package/lib/BasePort.js +34 -6
- package/lib/Component.d.ts +8 -8
- package/lib/Component.js +23 -20
- package/lib/ComponentLoader.d.ts +3 -4
- package/lib/ComponentLoader.js +9 -10
- package/lib/IP.d.ts +12 -8
- package/lib/IP.js +6 -4
- package/lib/InPort.d.ts +64 -9
- package/lib/InPort.js +72 -13
- package/lib/InternalSocket.d.ts +53 -7
- package/lib/InternalSocket.js +51 -14
- package/lib/LegacyNetwork.d.ts +12 -2
- package/lib/LegacyNetwork.js +5 -5
- package/lib/Network.d.ts +13 -2
- package/lib/Network.js +10 -10
- package/lib/NoFlo.d.ts +48 -13
- package/lib/NoFlo.js +55 -27
- package/lib/OutPort.d.ts +64 -13
- package/lib/OutPort.js +73 -15
- package/lib/Platform.d.ts +1 -1
- package/lib/Platform.js +9 -4
- package/lib/Ports.d.ts +11 -12
- package/lib/Ports.js +8 -4
- package/lib/ProcessInput.d.ts +5 -9
- package/lib/ProcessInput.js +8 -9
- package/lib/ProcessOutput.d.ts +2 -2
- package/lib/ProcessOutput.js +5 -5
- package/lib/loader/NodeJs.d.ts +0 -1
- package/lib/loader/NodeJs.js +152 -161
- package/lib/loader/register.d.ts +1 -1
- package/lib/loader/register.js +8 -4
- package/package.json +25 -16
- package/spec/.eslintrc +5 -2
- package/spec/AsCallback.js +9 -13
- package/spec/AsComponent.js +10 -4
- package/spec/AsPromise.js +38 -0
- package/spec/CommonJS.cjs +10 -0
- package/spec/ComponentLoader.js +19 -7
- package/spec/ESModule.mjs +11 -0
- package/spec/Network.js +32 -11
- package/spec/NetworkSync.js +892 -0
- package/spec/Scoping.js +27 -42
- package/spec/Subgraph.js +6 -11
- package/spec/fixtures/componentloader/components/Output.js +1 -1
- package/spec/fixtures/componentloader/components/Repeat.ts +1 -1
- package/spec/fixtures/componentloader/components/RepeatAsync.coffee +1 -1
- package/spec/fixtures/componentloader/node_modules/example/components/Forward.js +1 -1
- package/spec/fixtures/componentloader/node_modules/example/package.json +1 -1
- package/spec/fixtures/componentloader/package.json +2 -1
- package/spec/fixtures/componentloader/spec/Repeat.yaml +1 -1
- package/spec/utils/inject.js +1 -1
- package/src/.eslintrc +9 -2
- package/src/components/Graph.js +105 -71
- package/src/lib/AsCallback.js +71 -16
- package/src/lib/AsComponent.js +5 -4
- package/src/lib/BaseNetwork.js +48 -15
- package/src/lib/BasePort.js +43 -9
- package/src/lib/Component.js +8 -8
- package/src/lib/ComponentLoader.js +3 -4
- package/src/lib/IP.js +7 -4
- package/src/lib/InPort.js +74 -13
- package/src/lib/InternalSocket.js +49 -9
- package/src/lib/LegacyNetwork.js +2 -2
- package/src/lib/Network.js +2 -2
- package/src/lib/NoFlo.js +43 -13
- package/src/lib/OutPort.js +77 -14
- package/src/lib/Platform.js +9 -4
- package/src/lib/Ports.js +6 -2
- package/src/lib/ProcessInput.js +7 -9
- package/src/lib/ProcessOutput.js +1 -1
- package/src/lib/loader/NodeJs.js +185 -178
- package/src/lib/loader/register.js +2 -2
- /package/{karma.config.js → karma.config.cjs} +0 -0
- /package/{webpack.config.js → webpack.config.cjs} +0 -0
package/src/lib/InPort.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// NoFlo - Flow-Based Programming for JavaScript
|
|
2
2
|
// (c) 2014-2017 Flowhub UG
|
|
3
3
|
// NoFlo may be freely distributed under the MIT license
|
|
4
|
-
import BasePort from './BasePort';
|
|
4
|
+
import BasePort from './BasePort.js';
|
|
5
5
|
|
|
6
6
|
// ## NoFlo inport
|
|
7
7
|
//
|
|
@@ -9,9 +9,16 @@ import BasePort from './BasePort';
|
|
|
9
9
|
// ports are the way a component receives Information Packets.
|
|
10
10
|
/**
|
|
11
11
|
* @typedef InPortOptions
|
|
12
|
+
* @property {any} [default]
|
|
13
|
+
* @property {Array<any>} [values]
|
|
12
14
|
* @property {boolean} [control]
|
|
13
15
|
* @property {boolean} [triggering]
|
|
14
16
|
*/
|
|
17
|
+
/**
|
|
18
|
+
* @callback HasValidationCallback
|
|
19
|
+
* @param {import("./IP").default} ip
|
|
20
|
+
* @returns {boolean}
|
|
21
|
+
*/
|
|
15
22
|
/**
|
|
16
23
|
* @typedef {import("./BasePort").BaseOptions & InPortOptions} PortOptions
|
|
17
24
|
*/
|
|
@@ -28,12 +35,21 @@ export default class InPort extends BasePort {
|
|
|
28
35
|
|
|
29
36
|
super(opts);
|
|
30
37
|
|
|
38
|
+
const baseOptions = this.options;
|
|
39
|
+
this.options = /** @type {PortOptions} */ (baseOptions);
|
|
40
|
+
|
|
41
|
+
/** @type {import("./Component").Component|null} */
|
|
31
42
|
this.nodeInstance = null;
|
|
32
43
|
|
|
33
44
|
this.prepareBuffer();
|
|
34
45
|
}
|
|
35
46
|
|
|
36
|
-
|
|
47
|
+
/**
|
|
48
|
+
* Assign a delegate for retrieving data should this inPort
|
|
49
|
+
*
|
|
50
|
+
* @param {import("./InternalSocket").InternalSocket} socket
|
|
51
|
+
* @param {number|null} [localId]
|
|
52
|
+
*/
|
|
37
53
|
attachSocket(socket, localId = null) {
|
|
38
54
|
// have a default value.
|
|
39
55
|
if (this.hasDefault()) {
|
|
@@ -51,11 +67,17 @@ export default class InPort extends BasePort {
|
|
|
51
67
|
socket.on('ip', (ip) => this.handleIP(ip, localId));
|
|
52
68
|
}
|
|
53
69
|
|
|
54
|
-
|
|
70
|
+
/**
|
|
71
|
+
* @param {import("./IP").default} packet
|
|
72
|
+
* @param {number|null} [index]
|
|
73
|
+
*/
|
|
74
|
+
handleIP(packet, index = null) {
|
|
55
75
|
if (this.options.control && (packet.type !== 'data')) { return; }
|
|
56
76
|
const ip = packet;
|
|
57
77
|
ip.owner = this.nodeInstance;
|
|
58
|
-
if (this.isAddressable()) {
|
|
78
|
+
if (this.isAddressable()) {
|
|
79
|
+
ip.index = index;
|
|
80
|
+
}
|
|
59
81
|
if (ip.datatype === 'all') {
|
|
60
82
|
// Stamp non-specific IP objects with port datatype
|
|
61
83
|
ip.datatype = this.getDataType();
|
|
@@ -72,6 +94,11 @@ export default class InPort extends BasePort {
|
|
|
72
94
|
this.emit('ip', ip, index);
|
|
73
95
|
}
|
|
74
96
|
|
|
97
|
+
/**
|
|
98
|
+
* @param {string} event
|
|
99
|
+
* @param {any} payload
|
|
100
|
+
* @param {number} [id]
|
|
101
|
+
*/
|
|
75
102
|
handleSocketEvent(event, payload, id) {
|
|
76
103
|
// Emit port event
|
|
77
104
|
if (this.isAddressable()) {
|
|
@@ -138,6 +165,9 @@ export default class InPort extends BasePort {
|
|
|
138
165
|
return this.buffer;
|
|
139
166
|
}
|
|
140
167
|
|
|
168
|
+
/**
|
|
169
|
+
* @param {any} data
|
|
170
|
+
*/
|
|
141
171
|
validateData(data) {
|
|
142
172
|
if (!this.options.values) { return; }
|
|
143
173
|
if (this.options.values.indexOf(data) === -1) {
|
|
@@ -192,14 +222,25 @@ export default class InPort extends BasePort {
|
|
|
192
222
|
return buf.shift();
|
|
193
223
|
}
|
|
194
224
|
|
|
195
|
-
|
|
196
|
-
|
|
225
|
+
/**
|
|
226
|
+
* Fetches a packet from the port
|
|
227
|
+
* @param {string|null} scope
|
|
228
|
+
* @param {number|null} [index]
|
|
229
|
+
*/
|
|
230
|
+
get(scope, index = null) {
|
|
197
231
|
const res = this.getFromBuffer(scope, index);
|
|
198
232
|
if (res !== undefined) { return res; }
|
|
199
233
|
// Try to find an IIP instead
|
|
200
234
|
return this.getFromBuffer(null, index, true);
|
|
201
235
|
}
|
|
202
236
|
|
|
237
|
+
/**
|
|
238
|
+
* Fetches a packet from the port
|
|
239
|
+
* @param {string|null} scope
|
|
240
|
+
* @param {number|null} index
|
|
241
|
+
* @param {HasValidationCallback} validate
|
|
242
|
+
* @param {boolean} [initial]
|
|
243
|
+
*/
|
|
203
244
|
hasIPinBuffer(scope, index, validate, initial = false) {
|
|
204
245
|
const buf = this.getBuffer(scope, index, initial);
|
|
205
246
|
if (!(buf != null ? buf.length : undefined)) { return false; }
|
|
@@ -209,31 +250,51 @@ export default class InPort extends BasePort {
|
|
|
209
250
|
return false;
|
|
210
251
|
}
|
|
211
252
|
|
|
253
|
+
/**
|
|
254
|
+
* @param {number|null} index
|
|
255
|
+
* @param {HasValidationCallback} validate
|
|
256
|
+
*/
|
|
212
257
|
hasIIP(index, validate) {
|
|
213
258
|
return this.hasIPinBuffer(null, index, validate, true);
|
|
214
259
|
}
|
|
215
260
|
|
|
216
|
-
|
|
261
|
+
/**
|
|
262
|
+
* Returns true if port contains packet(s) matching the validator
|
|
263
|
+
* @param {string|null} scope
|
|
264
|
+
* @param {number|null|HasValidationCallback} index
|
|
265
|
+
* @param {HasValidationCallback} [validate]
|
|
266
|
+
*/
|
|
217
267
|
has(scope, index, validate) {
|
|
218
268
|
let valid = validate;
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
269
|
+
/** @type {number|null} */
|
|
270
|
+
let idx;
|
|
271
|
+
if (typeof index === 'function') {
|
|
272
|
+
valid = /** @type {HasValidationCallback} */ (index);
|
|
222
273
|
idx = null;
|
|
274
|
+
} else {
|
|
275
|
+
idx = index;
|
|
223
276
|
}
|
|
224
277
|
if (this.hasIPinBuffer(scope, idx, valid)) { return true; }
|
|
225
278
|
if (this.hasIIP(idx, valid)) { return true; }
|
|
226
279
|
return false;
|
|
227
280
|
}
|
|
228
281
|
|
|
229
|
-
|
|
230
|
-
|
|
282
|
+
/**
|
|
283
|
+
* Returns the number of data packets in an inport
|
|
284
|
+
* @param {string|null} scope
|
|
285
|
+
* @param {number|null} [index]
|
|
286
|
+
* @returns {number}
|
|
287
|
+
*/
|
|
288
|
+
length(scope, index = null) {
|
|
231
289
|
const buf = this.getBuffer(scope, index);
|
|
232
290
|
if (!buf) { return 0; }
|
|
233
291
|
return buf.length;
|
|
234
292
|
}
|
|
235
293
|
|
|
236
|
-
|
|
294
|
+
/**
|
|
295
|
+
* Tells if buffer has packets or not
|
|
296
|
+
* @param {string|null} scope
|
|
297
|
+
*/
|
|
237
298
|
ready(scope) {
|
|
238
299
|
return this.length(scope) > 0;
|
|
239
300
|
}
|
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
// (c) 2011-2012 Henri Bergius, Nemein
|
|
4
4
|
// NoFlo may be freely distributed under the MIT license
|
|
5
5
|
import { EventEmitter } from 'events';
|
|
6
|
-
import IP from './IP';
|
|
6
|
+
import IP from './IP.js';
|
|
7
|
+
import { makeAsync } from './Platform.js';
|
|
7
8
|
|
|
8
9
|
function legacyToIp(event, payload) {
|
|
9
10
|
// No need to wrap modern IP Objects
|
|
@@ -44,6 +45,13 @@ function ipToLegacy(ip) {
|
|
|
44
45
|
}
|
|
45
46
|
}
|
|
46
47
|
|
|
48
|
+
/**
|
|
49
|
+
* @typedef SocketError
|
|
50
|
+
* @property {Error} error
|
|
51
|
+
* @property {string} [id]
|
|
52
|
+
* @property {import("fbp-graph/lib/Types").GraphNodeMetadata} [metadata]
|
|
53
|
+
*/
|
|
54
|
+
|
|
47
55
|
// ## Internal Sockets
|
|
48
56
|
//
|
|
49
57
|
// The default communications mechanism between NoFlo processes is
|
|
@@ -52,10 +60,16 @@ function ipToLegacy(ip) {
|
|
|
52
60
|
// events so that the packets can be caught to the inport of the
|
|
53
61
|
// connected process.
|
|
54
62
|
export class InternalSocket extends EventEmitter {
|
|
63
|
+
/**
|
|
64
|
+
* @private
|
|
65
|
+
*/
|
|
55
66
|
regularEmitEvent(event, data) {
|
|
56
67
|
this.emit(event, data);
|
|
57
68
|
}
|
|
58
69
|
|
|
70
|
+
/**
|
|
71
|
+
* @private
|
|
72
|
+
*/
|
|
59
73
|
debugEmitEvent(event, data) {
|
|
60
74
|
try {
|
|
61
75
|
this.emit(event, data);
|
|
@@ -70,25 +84,51 @@ export class InternalSocket extends EventEmitter {
|
|
|
70
84
|
if (this.listeners('error').length === 0) { throw error; }
|
|
71
85
|
|
|
72
86
|
this.emit('error', {
|
|
73
|
-
id: this.to.process.id,
|
|
87
|
+
id: this.to ? this.to.process.id : null,
|
|
74
88
|
error,
|
|
75
89
|
metadata: this.metadata,
|
|
76
90
|
});
|
|
77
91
|
}
|
|
78
92
|
}
|
|
79
93
|
|
|
80
|
-
|
|
94
|
+
/**
|
|
95
|
+
* @typedef InternalSocketOptions
|
|
96
|
+
* @property {boolean} [debug] - Whether to catch exceptions caused by IP transmission
|
|
97
|
+
* @property {boolean} [async] - Whether IP transmission should be asynchronous
|
|
98
|
+
*/
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* @param {import("fbp-graph/lib/Types").GraphEdgeMetadata} [metadata]
|
|
102
|
+
* @param {InternalSocketOptions} [options]
|
|
103
|
+
*/
|
|
104
|
+
constructor(metadata = {}, options = {}) {
|
|
81
105
|
super();
|
|
82
106
|
this.metadata = metadata;
|
|
83
107
|
this.brackets = [];
|
|
84
108
|
this.connected = false;
|
|
85
109
|
this.dataDelegate = null;
|
|
86
|
-
this.debug = false;
|
|
87
|
-
this.
|
|
110
|
+
this.debug = options.debug || false;
|
|
111
|
+
this.async = options.async || false;
|
|
88
112
|
this.from = null;
|
|
89
113
|
this.to = null;
|
|
90
114
|
}
|
|
91
115
|
|
|
116
|
+
emitEvent(event, data) {
|
|
117
|
+
if (this.debug) {
|
|
118
|
+
if (this.async) {
|
|
119
|
+
makeAsync(() => this.debugEmitEvent(event, data));
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
this.debugEmitEvent(event, data);
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
if (this.async) {
|
|
126
|
+
makeAsync(() => this.regularEmitEvent(event, data));
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
this.regularEmitEvent(event, data);
|
|
130
|
+
}
|
|
131
|
+
|
|
92
132
|
// ## Socket connections
|
|
93
133
|
//
|
|
94
134
|
// Sockets that are attached to the ports of processes may be
|
|
@@ -223,7 +263,6 @@ export class InternalSocket extends EventEmitter {
|
|
|
223
263
|
// notification to the developer.
|
|
224
264
|
setDebug(active) {
|
|
225
265
|
this.debug = active;
|
|
226
|
-
this.emitEvent = this.debug ? this.debugEmitEvent : this.regularEmitEvent;
|
|
227
266
|
}
|
|
228
267
|
|
|
229
268
|
// ## Socket identifiers
|
|
@@ -291,9 +330,10 @@ export class InternalSocket extends EventEmitter {
|
|
|
291
330
|
}
|
|
292
331
|
|
|
293
332
|
/**
|
|
294
|
-
* @param {
|
|
333
|
+
* @param {import("fbp-graph/lib/Types").GraphEdgeMetadata} [metadata]
|
|
334
|
+
* @param {InternalSocketOptions} [options]
|
|
295
335
|
* @returns {InternalSocket}
|
|
296
336
|
*/
|
|
297
|
-
export function createSocket(metadata = {}) {
|
|
298
|
-
return new InternalSocket(metadata);
|
|
337
|
+
export function createSocket(metadata = {}, options = {}) {
|
|
338
|
+
return new InternalSocket(metadata, options);
|
|
299
339
|
}
|
package/src/lib/LegacyNetwork.js
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
// (c) 2013-2018 Flowhub UG
|
|
3
3
|
// (c) 2011-2012 Henri Bergius, Nemein
|
|
4
4
|
// NoFlo may be freely distributed under the MIT license
|
|
5
|
-
import { BaseNetwork } from './BaseNetwork';
|
|
6
|
-
import { deprecated } from './Platform';
|
|
5
|
+
import { BaseNetwork } from './BaseNetwork.js';
|
|
6
|
+
import { deprecated } from './Platform.js';
|
|
7
7
|
|
|
8
8
|
/* eslint-disable
|
|
9
9
|
import/prefer-default-export,
|
package/src/lib/Network.js
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
// (c) 2013-2018 Flowhub UG
|
|
3
3
|
// (c) 2011-2012 Henri Bergius, Nemein
|
|
4
4
|
// NoFlo may be freely distributed under the MIT license
|
|
5
|
-
import { BaseNetwork } from './BaseNetwork';
|
|
6
|
-
import { deprecated } from './Platform';
|
|
5
|
+
import { BaseNetwork } from './BaseNetwork.js';
|
|
6
|
+
import { deprecated } from './Platform.js';
|
|
7
7
|
|
|
8
8
|
/* eslint-disable
|
|
9
9
|
no-param-reassign,
|
package/src/lib/NoFlo.js
CHANGED
|
@@ -52,6 +52,8 @@ import { graph } from 'fbp-graph';
|
|
|
52
52
|
// immediate execution
|
|
53
53
|
// * `flowtrace`: (default: NULL) Flowtrace instance to create a retroactive debugging
|
|
54
54
|
// trace of the network run.
|
|
55
|
+
// * `asyncDelivery`: (default: FALSE) Whether Information Packets should be
|
|
56
|
+
// delivered asynchronously.
|
|
55
57
|
// * `subscribeGraph`: (default: FALSE) Whether the network should monitor the underlying
|
|
56
58
|
// graph for changes
|
|
57
59
|
//
|
|
@@ -61,9 +63,9 @@ import { graph } from 'fbp-graph';
|
|
|
61
63
|
//
|
|
62
64
|
// The options object can also be used for setting ComponentLoader options in this
|
|
63
65
|
// network.
|
|
64
|
-
import { Network } from './Network';
|
|
65
|
-
import { LegacyNetwork } from './LegacyNetwork';
|
|
66
|
-
import { deprecated } from './Platform';
|
|
66
|
+
import { Network } from './Network.js';
|
|
67
|
+
import { LegacyNetwork } from './LegacyNetwork.js';
|
|
68
|
+
import { deprecated, isBrowser } from './Platform.js';
|
|
67
69
|
|
|
68
70
|
export {
|
|
69
71
|
graph,
|
|
@@ -76,7 +78,7 @@ export {
|
|
|
76
78
|
//
|
|
77
79
|
// NoFlo works on both Node.js and the browser. Because some dependencies are different,
|
|
78
80
|
// we need a way to detect which we're on.
|
|
79
|
-
export { isBrowser } from './Platform';
|
|
81
|
+
export { isBrowser } from './Platform.js';
|
|
80
82
|
|
|
81
83
|
// ### Component Loader
|
|
82
84
|
//
|
|
@@ -84,33 +86,40 @@ export { isBrowser } from './Platform';
|
|
|
84
86
|
// NoFlo components. Component Loader uses [fbp-manifest](https://github.com/flowbased/fbp-manifest)
|
|
85
87
|
// to find components and graphs by traversing the NPM dependency tree from a given root
|
|
86
88
|
// directory on the file system.
|
|
87
|
-
export { ComponentLoader } from './ComponentLoader';
|
|
89
|
+
export { ComponentLoader } from './ComponentLoader.js';
|
|
90
|
+
import { ComponentLoader } from './ComponentLoader.js';
|
|
88
91
|
|
|
89
92
|
// ### Component baseclasses
|
|
90
93
|
//
|
|
91
94
|
// These baseclasses can be used for defining NoFlo components.
|
|
92
|
-
export { Component } from './Component';
|
|
95
|
+
export { Component } from './Component.js';
|
|
96
|
+
import { Component } from './Component.js';
|
|
93
97
|
|
|
94
98
|
// ### NoFlo ports
|
|
95
99
|
//
|
|
96
100
|
// These classes are used for instantiating ports on NoFlo components.
|
|
97
|
-
export { InPorts, OutPorts } from './Ports';
|
|
101
|
+
export { InPorts, OutPorts } from './Ports.js';
|
|
102
|
+
import { InPorts, OutPorts } from './Ports.js';
|
|
98
103
|
|
|
99
|
-
export { default as InPort } from './InPort';
|
|
100
|
-
|
|
104
|
+
export { default as InPort } from './InPort.js';
|
|
105
|
+
import InPort from './InPort.js';
|
|
106
|
+
|
|
107
|
+
export { default as OutPort } from './OutPort.js';
|
|
108
|
+
import OutPort from './OutPort.js';
|
|
101
109
|
|
|
102
110
|
// ### NoFlo sockets
|
|
103
111
|
//
|
|
104
112
|
// The NoFlo [internalSocket](InternalSocket.html) is used for connecting ports of
|
|
105
113
|
// different components together in a network.
|
|
106
|
-
import * as internalSocket from './InternalSocket';
|
|
114
|
+
import * as internalSocket from './InternalSocket.js';
|
|
107
115
|
|
|
108
116
|
export { internalSocket };
|
|
109
117
|
|
|
110
118
|
// ### Information Packets
|
|
111
119
|
//
|
|
112
120
|
// NoFlo Information Packets are defined as "IP" objects.
|
|
113
|
-
export { default as IP } from './IP';
|
|
121
|
+
export { default as IP } from './IP.js';
|
|
122
|
+
import IP from './IP.js';
|
|
114
123
|
|
|
115
124
|
/**
|
|
116
125
|
* @callback NetworkCallback
|
|
@@ -221,7 +230,8 @@ export function saveFile(graphInstance, file, callback) {
|
|
|
221
230
|
// // Do something with results
|
|
222
231
|
// });
|
|
223
232
|
//
|
|
224
|
-
export { asCallback, asPromise } from './AsCallback';
|
|
233
|
+
export { asCallback, asPromise } from './AsCallback.js';
|
|
234
|
+
import { asCallback, asPromise } from './AsCallback.js';
|
|
225
235
|
|
|
226
236
|
// ## Generating components from JavaScript functions
|
|
227
237
|
//
|
|
@@ -235,4 +245,24 @@ export { asCallback, asPromise } from './AsCallback';
|
|
|
235
245
|
// });
|
|
236
246
|
// };
|
|
237
247
|
//
|
|
238
|
-
export { asComponent } from './AsComponent';
|
|
248
|
+
export { asComponent } from './AsComponent.js';
|
|
249
|
+
import { asComponent } from './AsComponent.js';
|
|
250
|
+
|
|
251
|
+
export default {
|
|
252
|
+
...graph,
|
|
253
|
+
isBrowser,
|
|
254
|
+
ComponentLoader,
|
|
255
|
+
Component,
|
|
256
|
+
InPorts,
|
|
257
|
+
OutPorts,
|
|
258
|
+
InPort,
|
|
259
|
+
OutPort,
|
|
260
|
+
internalSocket,
|
|
261
|
+
IP,
|
|
262
|
+
createNetwork,
|
|
263
|
+
loadFile,
|
|
264
|
+
saveFile,
|
|
265
|
+
asCallback,
|
|
266
|
+
asPromise,
|
|
267
|
+
asComponent,
|
|
268
|
+
};
|
package/src/lib/OutPort.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// NoFlo - Flow-Based Programming for JavaScript
|
|
2
2
|
// (c) 2014-2017 Flowhub UG
|
|
3
3
|
// NoFlo may be freely distributed under the MIT license
|
|
4
|
-
import BasePort from './BasePort';
|
|
5
|
-
import IP from './IP';
|
|
4
|
+
import BasePort from './BasePort.js';
|
|
5
|
+
import IP from './IP.js';
|
|
6
6
|
|
|
7
7
|
// ## NoFlo outport
|
|
8
8
|
//
|
|
@@ -27,16 +27,28 @@ export default class OutPort extends BasePort {
|
|
|
27
27
|
opts.caching = false;
|
|
28
28
|
}
|
|
29
29
|
super(opts);
|
|
30
|
+
|
|
31
|
+
const baseOptions = this.options;
|
|
32
|
+
this.options = /** @type {PortOptions} */ (baseOptions);
|
|
33
|
+
|
|
34
|
+
/** @type {Object<string, IP>} */
|
|
30
35
|
this.cache = {};
|
|
31
36
|
}
|
|
32
37
|
|
|
38
|
+
/**
|
|
39
|
+
* @param {import("./InternalSocket").InternalSocket} socket
|
|
40
|
+
* @param {number|null} [index]
|
|
41
|
+
*/
|
|
33
42
|
attach(socket, index = null) {
|
|
34
43
|
super.attach(socket, index);
|
|
35
|
-
if (this.isCaching() && (this.cache[index] != null)) {
|
|
36
|
-
this.send(this.cache[index], index);
|
|
44
|
+
if (this.isCaching() && (this.cache[`${index}`] != null)) {
|
|
45
|
+
this.send(this.cache[`${index}`], index);
|
|
37
46
|
}
|
|
38
47
|
}
|
|
39
48
|
|
|
49
|
+
/**
|
|
50
|
+
* @param {number|null} [index]
|
|
51
|
+
*/
|
|
40
52
|
connect(index = null) {
|
|
41
53
|
const sockets = this.getSockets(index);
|
|
42
54
|
this.checkRequired(sockets);
|
|
@@ -46,6 +58,10 @@ export default class OutPort extends BasePort {
|
|
|
46
58
|
});
|
|
47
59
|
}
|
|
48
60
|
|
|
61
|
+
/**
|
|
62
|
+
* @param {string} group
|
|
63
|
+
* @param {number|null} [index]
|
|
64
|
+
*/
|
|
49
65
|
beginGroup(group, index = null) {
|
|
50
66
|
const sockets = this.getSockets(index);
|
|
51
67
|
this.checkRequired(sockets);
|
|
@@ -55,11 +71,15 @@ export default class OutPort extends BasePort {
|
|
|
55
71
|
});
|
|
56
72
|
}
|
|
57
73
|
|
|
74
|
+
/**
|
|
75
|
+
* @param {any} data
|
|
76
|
+
* @param {number|null} [index]
|
|
77
|
+
*/
|
|
58
78
|
send(data, index = null) {
|
|
59
79
|
const sockets = this.getSockets(index);
|
|
60
80
|
this.checkRequired(sockets);
|
|
61
|
-
if (this.isCaching() && (data !== this.cache[index])) {
|
|
62
|
-
this.cache[index] = data;
|
|
81
|
+
if (this.isCaching() && (data !== this.cache[`${index}`])) {
|
|
82
|
+
this.cache[`${index}`] = data;
|
|
63
83
|
}
|
|
64
84
|
sockets.forEach((socket) => {
|
|
65
85
|
if (!socket) { return; }
|
|
@@ -67,6 +87,9 @@ export default class OutPort extends BasePort {
|
|
|
67
87
|
});
|
|
68
88
|
}
|
|
69
89
|
|
|
90
|
+
/**
|
|
91
|
+
* @param {number|null} [index]
|
|
92
|
+
*/
|
|
70
93
|
endGroup(index = null) {
|
|
71
94
|
const sockets = this.getSockets(index);
|
|
72
95
|
this.checkRequired(sockets);
|
|
@@ -76,6 +99,9 @@ export default class OutPort extends BasePort {
|
|
|
76
99
|
});
|
|
77
100
|
}
|
|
78
101
|
|
|
102
|
+
/**
|
|
103
|
+
* @param {number|null} [index]
|
|
104
|
+
*/
|
|
79
105
|
disconnect(index = null) {
|
|
80
106
|
const sockets = this.getSockets(index);
|
|
81
107
|
this.checkRequired(sockets);
|
|
@@ -85,14 +111,24 @@ export default class OutPort extends BasePort {
|
|
|
85
111
|
});
|
|
86
112
|
}
|
|
87
113
|
|
|
88
|
-
|
|
114
|
+
/**
|
|
115
|
+
* @param {string|IP} type
|
|
116
|
+
* @param {any} [data]
|
|
117
|
+
* @param {import("./IP").IPOptions} [options]
|
|
118
|
+
* @param {number|null} [index]
|
|
119
|
+
* @param {boolean} [autoConnect]
|
|
120
|
+
*/
|
|
121
|
+
sendIP(type, data, options, index = null, autoConnect = true) {
|
|
122
|
+
/** @type {IP} */
|
|
89
123
|
let ip;
|
|
90
124
|
let idx = index;
|
|
91
125
|
if (IP.isIP(type)) {
|
|
92
|
-
ip = type;
|
|
126
|
+
ip = /** @type {IP} */ (type);
|
|
93
127
|
idx = ip.index;
|
|
94
|
-
} else {
|
|
128
|
+
} else if (typeof type === 'string') {
|
|
95
129
|
ip = new IP(type, data, options);
|
|
130
|
+
} else {
|
|
131
|
+
throw new Error('Unknown type for IP type');
|
|
96
132
|
}
|
|
97
133
|
const sockets = this.getSockets(idx);
|
|
98
134
|
this.checkRequired(sockets);
|
|
@@ -106,9 +142,9 @@ export default class OutPort extends BasePort {
|
|
|
106
142
|
ip.schema = this.getSchema();
|
|
107
143
|
}
|
|
108
144
|
|
|
109
|
-
const cachedData = this.cache[idx] != null ? this.cache[idx].data : undefined;
|
|
145
|
+
const cachedData = this.cache[`${idx}`] != null ? this.cache[`${idx}`].data : undefined;
|
|
110
146
|
if (this.isCaching() && data !== cachedData) {
|
|
111
|
-
this.cache[idx] = ip;
|
|
147
|
+
this.cache[`${idx}`] = ip;
|
|
112
148
|
}
|
|
113
149
|
let pristine = true;
|
|
114
150
|
sockets.forEach((socket) => {
|
|
@@ -124,30 +160,57 @@ export default class OutPort extends BasePort {
|
|
|
124
160
|
return this;
|
|
125
161
|
}
|
|
126
162
|
|
|
163
|
+
/**
|
|
164
|
+
* @param {string|null} data
|
|
165
|
+
* @param {import("./IP").IPOptions} options
|
|
166
|
+
* @param {number|null} [index]
|
|
167
|
+
*/
|
|
127
168
|
openBracket(data = null, options = {}, index = null) {
|
|
128
169
|
return this.sendIP('openBracket', data, options, index);
|
|
129
170
|
}
|
|
130
171
|
|
|
172
|
+
/**
|
|
173
|
+
* @param {any} data
|
|
174
|
+
* @param {import("./IP").IPOptions} options
|
|
175
|
+
* @param {number|null} [index]
|
|
176
|
+
*/
|
|
131
177
|
data(data, options = {}, index = null) {
|
|
132
178
|
return this.sendIP('data', data, options, index);
|
|
133
179
|
}
|
|
134
180
|
|
|
181
|
+
/**
|
|
182
|
+
* @param {string|null} data
|
|
183
|
+
* @param {import("./IP").IPOptions} options
|
|
184
|
+
* @param {number|null} [index]
|
|
185
|
+
*/
|
|
135
186
|
closeBracket(data = null, options = {}, index = null) {
|
|
136
187
|
return this.sendIP('closeBracket', data, options, index);
|
|
137
188
|
}
|
|
138
189
|
|
|
190
|
+
/**
|
|
191
|
+
* @param {Array<import("./InternalSocket").InternalSocket|void>} sockets
|
|
192
|
+
*/
|
|
139
193
|
checkRequired(sockets) {
|
|
140
194
|
if ((sockets.length === 0) && this.isRequired()) {
|
|
141
195
|
throw new Error(`${this.getId()}: No connections available`);
|
|
142
196
|
}
|
|
143
197
|
}
|
|
144
198
|
|
|
199
|
+
/**
|
|
200
|
+
* @param {number|null} index
|
|
201
|
+
* @returns {Array<import("./InternalSocket").InternalSocket|void>}
|
|
202
|
+
*/
|
|
145
203
|
getSockets(index) {
|
|
146
204
|
// Addressable sockets affect only one connection at time
|
|
147
205
|
if (this.isAddressable()) {
|
|
148
|
-
if (index === null) {
|
|
149
|
-
|
|
150
|
-
|
|
206
|
+
if (index === null) {
|
|
207
|
+
throw new Error(`${this.getId()} Socket ID required`);
|
|
208
|
+
}
|
|
209
|
+
const idx = /** @type {number} */ (index);
|
|
210
|
+
if (!this.sockets[idx]) {
|
|
211
|
+
return [];
|
|
212
|
+
}
|
|
213
|
+
return [this.sockets[idx]];
|
|
151
214
|
}
|
|
152
215
|
// Regular sockets affect all outbound connections
|
|
153
216
|
return this.sockets;
|
package/src/lib/Platform.js
CHANGED
|
@@ -41,12 +41,17 @@ export function deprecated(message) {
|
|
|
41
41
|
* @param {Function} func
|
|
42
42
|
* @returns {void}
|
|
43
43
|
*/
|
|
44
|
-
export function makeAsync(func) {
|
|
44
|
+
export function makeAsync(func, sameLoop = false) {
|
|
45
45
|
if (isBrowser()) {
|
|
46
|
+
// FIXME: Browsers don't have setImmediate yet so can't do same loop
|
|
46
47
|
setTimeout(func, 0);
|
|
47
48
|
return;
|
|
48
49
|
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
50
|
+
if (sameLoop) {
|
|
51
|
+
setImmediate(() => {
|
|
52
|
+
func();
|
|
53
|
+
});
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
process.nextTick(func);
|
|
52
57
|
}
|
package/src/lib/Ports.js
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
// (c) 2014-2017 Flowhub UG
|
|
4
4
|
// NoFlo may be freely distributed under the MIT license
|
|
5
5
|
import { EventEmitter } from 'events';
|
|
6
|
-
import InPort from './InPort';
|
|
7
|
-
import OutPort from './OutPort';
|
|
6
|
+
import InPort from './InPort.js';
|
|
7
|
+
import OutPort from './OutPort.js';
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* @typedef {import("./BasePort").BaseOptions} PortOptions
|
|
@@ -85,6 +85,8 @@ export class InPorts extends Ports {
|
|
|
85
85
|
*/
|
|
86
86
|
constructor(ports = {}) {
|
|
87
87
|
super(ports, InPort);
|
|
88
|
+
const basePorts = this.ports;
|
|
89
|
+
this.ports = /** @type {Object<string, InPort>} */ (basePorts);
|
|
88
90
|
}
|
|
89
91
|
}
|
|
90
92
|
|
|
@@ -97,6 +99,8 @@ export class OutPorts extends Ports {
|
|
|
97
99
|
*/
|
|
98
100
|
constructor(ports = {}) {
|
|
99
101
|
super(ports, OutPort);
|
|
102
|
+
const basePorts = this.ports;
|
|
103
|
+
this.ports = /** @type {Object<string, OutPort>} */ (basePorts);
|
|
100
104
|
}
|
|
101
105
|
|
|
102
106
|
connect(name, socketId) {
|