noflo 1.5.0 → 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/CHANGELOG.md +7 -0
- package/bin/noflo-cache-preheat +1 -1
- package/lib/NoFlo.d.ts +35 -0
- package/lib/NoFlo.js +26 -0
- package/lib/loader/NodeJs.js +51 -59
- package/package.json +14 -10
- package/spec/ComponentLoader.js +17 -5
- package/spec/fixtures/componentloader/package.json +1 -0
- package/spec/utils/inject.js +1 -1
- package/src/lib/AsComponent.js +1 -1
- package/src/lib/NoFlo.js +29 -1
- package/src/lib/loader/NodeJs.js +66 -65
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
5
5
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
+
## [1.5.1] - 2026-06-20
|
|
8
|
+
### Changed
|
|
9
|
+
- NoFlo can now be imported either ES Module or CommonJS
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
- Basic smoketests for running from both ESM and CommonJS
|
|
13
|
+
|
|
7
14
|
## [1.5.0] - 2026-06-20
|
|
8
15
|
### Changed
|
|
9
16
|
- Improved using NoFlo directly as ES Module dependency
|
package/bin/noflo-cache-preheat
CHANGED
package/lib/NoFlo.d.ts
CHANGED
|
@@ -40,6 +40,30 @@ export { default as OutPort } from "./OutPort.js";
|
|
|
40
40
|
export { internalSocket };
|
|
41
41
|
export { default as IP } from "./IP.js";
|
|
42
42
|
export { asComponent } from "./AsComponent.js";
|
|
43
|
+
declare const _default: {
|
|
44
|
+
isBrowser: typeof isBrowser;
|
|
45
|
+
ComponentLoader: typeof ComponentLoader;
|
|
46
|
+
Component: typeof Component;
|
|
47
|
+
InPorts: typeof InPorts;
|
|
48
|
+
OutPorts: typeof OutPorts;
|
|
49
|
+
InPort: typeof InPort;
|
|
50
|
+
OutPort: typeof OutPort;
|
|
51
|
+
internalSocket: typeof internalSocket;
|
|
52
|
+
IP: typeof IP;
|
|
53
|
+
createNetwork: typeof createNetwork;
|
|
54
|
+
loadFile: typeof loadFile;
|
|
55
|
+
saveFile: typeof saveFile;
|
|
56
|
+
asCallback: typeof asCallback;
|
|
57
|
+
asPromise: typeof asPromise;
|
|
58
|
+
asComponent: typeof asComponent;
|
|
59
|
+
Graph: typeof graph.Graph;
|
|
60
|
+
createGraph: typeof graph.createGraph;
|
|
61
|
+
loadJSON: typeof graph.loadJSON;
|
|
62
|
+
loadFBP: typeof graph.loadFBP;
|
|
63
|
+
equivalent: typeof graph.equivalent;
|
|
64
|
+
mergeResolveTheirs: typeof graph.mergeResolveTheirs;
|
|
65
|
+
};
|
|
66
|
+
export default _default;
|
|
43
67
|
export type NetworkCallback = (err: Error | null, network?: Network | LegacyNetwork) => any;
|
|
44
68
|
export type CreateNetworkOptions = {
|
|
45
69
|
/**
|
|
@@ -56,6 +80,17 @@ import { Network } from "./Network.js";
|
|
|
56
80
|
import { LegacyNetwork } from "./LegacyNetwork.js";
|
|
57
81
|
import { graph } from "fbp-graph";
|
|
58
82
|
import * as internalSocket from "./InternalSocket.js";
|
|
83
|
+
import { isBrowser } from "./Platform.js";
|
|
84
|
+
import { ComponentLoader } from "./ComponentLoader.js";
|
|
85
|
+
import { Component } from "./Component.js";
|
|
86
|
+
import { InPorts } from "./Ports.js";
|
|
87
|
+
import { OutPorts } from "./Ports.js";
|
|
88
|
+
import InPort from "./InPort.js";
|
|
89
|
+
import OutPort from "./OutPort.js";
|
|
90
|
+
import IP from "./IP.js";
|
|
91
|
+
import { asCallback } from "./AsCallback.js";
|
|
92
|
+
import { asPromise } from "./AsCallback.js";
|
|
93
|
+
import { asComponent } from "./AsComponent.js";
|
|
59
94
|
export { graph, Graph, journal, Journal } from "fbp-graph";
|
|
60
95
|
export { InPorts, OutPorts } from "./Ports.js";
|
|
61
96
|
export { asCallback, asPromise } from "./AsCallback.js";
|
package/lib/NoFlo.js
CHANGED
|
@@ -85,21 +85,26 @@ Object.defineProperty(exports, "isBrowser", { enumerable: true, get: function ()
|
|
|
85
85
|
// directory on the file system.
|
|
86
86
|
var ComponentLoader_js_1 = require("./ComponentLoader.js");
|
|
87
87
|
Object.defineProperty(exports, "ComponentLoader", { enumerable: true, get: function () { return ComponentLoader_js_1.ComponentLoader; } });
|
|
88
|
+
const ComponentLoader_js_2 = require("./ComponentLoader.js");
|
|
88
89
|
// ### Component baseclasses
|
|
89
90
|
//
|
|
90
91
|
// These baseclasses can be used for defining NoFlo components.
|
|
91
92
|
var Component_js_1 = require("./Component.js");
|
|
92
93
|
Object.defineProperty(exports, "Component", { enumerable: true, get: function () { return Component_js_1.Component; } });
|
|
94
|
+
const Component_js_2 = require("./Component.js");
|
|
93
95
|
// ### NoFlo ports
|
|
94
96
|
//
|
|
95
97
|
// These classes are used for instantiating ports on NoFlo components.
|
|
96
98
|
var Ports_js_1 = require("./Ports.js");
|
|
97
99
|
Object.defineProperty(exports, "InPorts", { enumerable: true, get: function () { return Ports_js_1.InPorts; } });
|
|
98
100
|
Object.defineProperty(exports, "OutPorts", { enumerable: true, get: function () { return Ports_js_1.OutPorts; } });
|
|
101
|
+
const Ports_js_2 = require("./Ports.js");
|
|
99
102
|
var InPort_js_1 = require("./InPort.js");
|
|
100
103
|
Object.defineProperty(exports, "InPort", { enumerable: true, get: function () { return InPort_js_1.default; } });
|
|
104
|
+
const InPort_js_2 = require("./InPort.js");
|
|
101
105
|
var OutPort_js_1 = require("./OutPort.js");
|
|
102
106
|
Object.defineProperty(exports, "OutPort", { enumerable: true, get: function () { return OutPort_js_1.default; } });
|
|
107
|
+
const OutPort_js_2 = require("./OutPort.js");
|
|
103
108
|
// ### NoFlo sockets
|
|
104
109
|
//
|
|
105
110
|
// The NoFlo [internalSocket](InternalSocket.html) is used for connecting ports of
|
|
@@ -111,6 +116,7 @@ exports.internalSocket = internalSocket;
|
|
|
111
116
|
// NoFlo Information Packets are defined as "IP" objects.
|
|
112
117
|
var IP_js_1 = require("./IP.js");
|
|
113
118
|
Object.defineProperty(exports, "IP", { enumerable: true, get: function () { return IP_js_1.default; } });
|
|
119
|
+
const IP_js_2 = require("./IP.js");
|
|
114
120
|
/**
|
|
115
121
|
* @callback NetworkCallback
|
|
116
122
|
* @param {Error | null} err
|
|
@@ -218,6 +224,7 @@ exports.saveFile = saveFile;
|
|
|
218
224
|
var AsCallback_js_1 = require("./AsCallback.js");
|
|
219
225
|
Object.defineProperty(exports, "asCallback", { enumerable: true, get: function () { return AsCallback_js_1.asCallback; } });
|
|
220
226
|
Object.defineProperty(exports, "asPromise", { enumerable: true, get: function () { return AsCallback_js_1.asPromise; } });
|
|
227
|
+
const AsCallback_js_2 = require("./AsCallback.js");
|
|
221
228
|
// ## Generating components from JavaScript functions
|
|
222
229
|
//
|
|
223
230
|
// The `asComponent` helper makes it easy to expose a JavaScript function as a
|
|
@@ -232,3 +239,22 @@ Object.defineProperty(exports, "asPromise", { enumerable: true, get: function ()
|
|
|
232
239
|
//
|
|
233
240
|
var AsComponent_js_1 = require("./AsComponent.js");
|
|
234
241
|
Object.defineProperty(exports, "asComponent", { enumerable: true, get: function () { return AsComponent_js_1.asComponent; } });
|
|
242
|
+
const AsComponent_js_2 = require("./AsComponent.js");
|
|
243
|
+
exports.default = {
|
|
244
|
+
...fbp_graph_1.graph,
|
|
245
|
+
isBrowser: Platform_js_1.isBrowser,
|
|
246
|
+
ComponentLoader: ComponentLoader_js_2.ComponentLoader,
|
|
247
|
+
Component: Component_js_2.Component,
|
|
248
|
+
InPorts: Ports_js_2.InPorts,
|
|
249
|
+
OutPorts: Ports_js_2.OutPorts,
|
|
250
|
+
InPort: InPort_js_2.default,
|
|
251
|
+
OutPort: OutPort_js_2.default,
|
|
252
|
+
internalSocket,
|
|
253
|
+
IP: IP_js_2.default,
|
|
254
|
+
createNetwork,
|
|
255
|
+
loadFile,
|
|
256
|
+
saveFile,
|
|
257
|
+
asCallback: AsCallback_js_2.asCallback,
|
|
258
|
+
asPromise: AsCallback_js_2.asPromise,
|
|
259
|
+
asComponent: AsComponent_js_2.asComponent,
|
|
260
|
+
};
|
package/lib/loader/NodeJs.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var _a;
|
|
2
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
4
|
exports.dynamicLoad = exports.register = exports.getLanguages = exports.getSource = exports.setSource = void 0;
|
|
4
5
|
/* eslint-disable
|
|
@@ -17,22 +18,23 @@ const writeFile = (0, util_1.promisify)(fs.writeFile);
|
|
|
17
18
|
const readFile = (0, util_1.promisify)(fs.readFile);
|
|
18
19
|
// Type loading CoffeeScript compiler
|
|
19
20
|
let CoffeeScript;
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
CoffeeScript =
|
|
23
|
-
}
|
|
24
|
-
catch
|
|
21
|
+
// eslint-disable-next-line import/no-unresolved,import/no-extraneous-dependencies
|
|
22
|
+
Promise.resolve().then(() => require('coffeescript')).then((compiler) => {
|
|
23
|
+
CoffeeScript = compiler;
|
|
24
|
+
})
|
|
25
|
+
.catch((e) => {
|
|
25
26
|
// If there is no CoffeeScript compiler installed, we simply don't support compiling
|
|
26
|
-
}
|
|
27
|
+
});
|
|
27
28
|
// Try loading TypeScript compiler
|
|
28
29
|
let typescript;
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
30
|
+
// eslint-disable-next-line import/no-unresolved,import/no-extraneous-dependencies
|
|
31
|
+
Promise.resolve().then(() => require('typescript')).then((compiler) => {
|
|
32
|
+
// @ts-ignore
|
|
33
|
+
typescript = compiler.default;
|
|
34
|
+
})
|
|
35
|
+
.catch((e) => {
|
|
34
36
|
// If there is no TypeScript compiler installed, we simply don't support compiling
|
|
35
|
-
}
|
|
37
|
+
});
|
|
36
38
|
/**
|
|
37
39
|
* @callback ErrorableCallback
|
|
38
40
|
* @param {Error|null} error
|
|
@@ -74,7 +76,7 @@ function transpileSource(packageId, name, source, language) {
|
|
|
74
76
|
try {
|
|
75
77
|
src = typescript.transpile(source, {
|
|
76
78
|
module: typescript.ModuleKind.CommonJS,
|
|
77
|
-
target: typescript.ScriptTarget.
|
|
79
|
+
target: typescript.ScriptTarget.ES2020,
|
|
78
80
|
});
|
|
79
81
|
}
|
|
80
82
|
catch (err) {
|
|
@@ -103,26 +105,27 @@ function transpileSource(packageId, name, source, language) {
|
|
|
103
105
|
* @returns {Promise<Object|Function>}
|
|
104
106
|
*/
|
|
105
107
|
function evaluateModule(baseDir, packageId, name, source) {
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
try {
|
|
108
|
+
return Promise.resolve().then(() => require('module')).then(({ Module }) => {
|
|
109
|
+
let implementation;
|
|
109
110
|
// Use the Node.js module API to evaluate in the correct directory context
|
|
110
|
-
|
|
111
|
-
|
|
111
|
+
let extension = '.js';
|
|
112
|
+
if (source.indexOf('require(') !== -1) {
|
|
113
|
+
// CommonJS
|
|
114
|
+
extension = '.cjs';
|
|
115
|
+
}
|
|
116
|
+
const modulePath = path.resolve(baseDir, `./components/${name}${extension}`);
|
|
117
|
+
const moduleImpl = new Module(modulePath);
|
|
112
118
|
// @ts-ignore
|
|
113
119
|
moduleImpl.paths = Module._nodeModulePaths(path.dirname(modulePath));
|
|
114
120
|
moduleImpl.filename = modulePath;
|
|
115
121
|
// @ts-ignore
|
|
116
122
|
moduleImpl._compile(source, modulePath);
|
|
117
123
|
implementation = moduleImpl.exports;
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
return Promise.reject(new Error(`Provided source for ${packageId}/${name} failed to create a runnable component`));
|
|
124
|
-
}
|
|
125
|
-
return Promise.resolve(implementation);
|
|
124
|
+
if ((typeof implementation !== 'function') && (typeof implementation.getComponent !== 'function')) {
|
|
125
|
+
return Promise.reject(new Error(`Provided source for ${packageId}/${name} failed to create a runnable component`));
|
|
126
|
+
}
|
|
127
|
+
return Promise.resolve(implementation);
|
|
128
|
+
});
|
|
126
129
|
}
|
|
127
130
|
/**
|
|
128
131
|
* @param {import("../ComponentLoader").ComponentLoader} loader
|
|
@@ -362,9 +365,14 @@ exports.getLanguages = getLanguages;
|
|
|
362
365
|
*/
|
|
363
366
|
function registerCustomLoaders(loader, componentLoaders, callback) {
|
|
364
367
|
componentLoaders.reduce((chain, componentLoader) => chain
|
|
365
|
-
.then(() =>
|
|
366
|
-
|
|
367
|
-
|
|
368
|
+
.then(() => { var _a; return _a = componentLoader, Promise.resolve().then(() => require(_a)); })
|
|
369
|
+
.then((customLoader) => new Promise((resolve, reject) => {
|
|
370
|
+
let loaderFunc = customLoader;
|
|
371
|
+
if (typeof customLoader === 'object' && customLoader.default) {
|
|
372
|
+
// CommonJS loader
|
|
373
|
+
loaderFunc = customLoader.default;
|
|
374
|
+
}
|
|
375
|
+
loader.registerLoader(loaderFunc, (err) => {
|
|
368
376
|
if (err) {
|
|
369
377
|
reject(err);
|
|
370
378
|
return;
|
|
@@ -584,40 +592,24 @@ exports.register = register;
|
|
|
584
592
|
* @param {ModuleLoadingCallback} callback
|
|
585
593
|
*/
|
|
586
594
|
function dynamicLoad(name, cPath, metadata, callback) {
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
implementation = require(cPath);
|
|
591
|
-
}
|
|
592
|
-
catch (err) {
|
|
593
|
-
callback(err);
|
|
594
|
-
return;
|
|
595
|
-
}
|
|
596
|
-
if (typeof implementation.getComponent === 'function') {
|
|
597
|
-
try {
|
|
595
|
+
(_a = cPath, Promise.resolve().then(() => require(_a))).then((implementation) => {
|
|
596
|
+
let instance;
|
|
597
|
+
if (typeof implementation.getComponent === 'function') {
|
|
598
598
|
instance = implementation.getComponent(metadata);
|
|
599
599
|
}
|
|
600
|
-
|
|
601
|
-
callback(err);
|
|
602
|
-
return;
|
|
603
|
-
}
|
|
604
|
-
}
|
|
605
|
-
else if (typeof implementation === 'function') {
|
|
606
|
-
try {
|
|
600
|
+
else if (typeof implementation === 'function') {
|
|
607
601
|
instance = implementation(metadata);
|
|
608
602
|
}
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
return;
|
|
603
|
+
else {
|
|
604
|
+
throw new Error(`Unable to instantiate ${cPath}`);
|
|
612
605
|
}
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
}
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
}
|
|
621
|
-
callback(null, instance);
|
|
606
|
+
if (typeof name === 'string') {
|
|
607
|
+
instance.componentName = name;
|
|
608
|
+
}
|
|
609
|
+
callback(null, instance);
|
|
610
|
+
})
|
|
611
|
+
.catch((e) => {
|
|
612
|
+
callback(e);
|
|
613
|
+
});
|
|
622
614
|
}
|
|
623
615
|
exports.dynamicLoad = dynamicLoad;
|
package/package.json
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"noflo"
|
|
9
9
|
],
|
|
10
10
|
"author": "Henri Bergius <henri.bergius@iki.fi>",
|
|
11
|
-
"version": "1.5.
|
|
11
|
+
"version": "1.5.1",
|
|
12
12
|
"license": "MIT",
|
|
13
13
|
"engines": {
|
|
14
14
|
"node": ">= 6"
|
|
@@ -38,17 +38,21 @@
|
|
|
38
38
|
"karma-mocha-reporter": "^2.2.5",
|
|
39
39
|
"mocha": "^8.1.3",
|
|
40
40
|
"noflo-component-loader": "^0.4.0",
|
|
41
|
-
"nyc": "^
|
|
41
|
+
"nyc": "^14.1.1",
|
|
42
42
|
"path-browserify": "^1.0.1",
|
|
43
43
|
"process": "^0.11.10",
|
|
44
|
-
"replace": "^
|
|
44
|
+
"replace": "^0.2.2",
|
|
45
45
|
"typescript": "^4.0.2",
|
|
46
46
|
"util": "^0.12.3",
|
|
47
47
|
"webpack": "^5.0.0",
|
|
48
48
|
"webpack-cli": "^4.0.0"
|
|
49
49
|
},
|
|
50
|
-
"main": "./lib/NoFlo",
|
|
50
|
+
"main": "./src/lib/NoFlo",
|
|
51
51
|
"module": "./src/lib/NoFlo.js",
|
|
52
|
+
"exports": {
|
|
53
|
+
"import": "./src/lib/NoFlo.js",
|
|
54
|
+
"require": "./lib/NoFlo.js"
|
|
55
|
+
},
|
|
52
56
|
"types": "./lib/NoFlo.d.ts",
|
|
53
57
|
"bin": {
|
|
54
58
|
"noflo": "./bin/noflo",
|
|
@@ -61,9 +65,9 @@
|
|
|
61
65
|
},
|
|
62
66
|
"scripts": {
|
|
63
67
|
"lint": "eslint .",
|
|
64
|
-
"
|
|
65
|
-
"build:node": "
|
|
66
|
-
"
|
|
68
|
+
"prebuild:node": "replace 'import.meta.dirname' '__dirname' src/lib/loader/NodeJs.js && replace 'import getParams from' 'import * as getParams from' src/lib/AsComponent.js",
|
|
69
|
+
"build:node": "tsc",
|
|
70
|
+
"postbuild:node": "replace '__dirname' 'import.meta.dirname' src/lib/loader/NodeJs.js && replace 'import \\* as getParams from' 'import getParams from' src/lib/AsComponent.js",
|
|
67
71
|
"build:browser": "webpack --config webpack.config.cjs",
|
|
68
72
|
"build": "npm run build:node && npm run build:browser",
|
|
69
73
|
"postbuild": "replace 'node/events' 'events' lib -r",
|
|
@@ -80,9 +84,9 @@
|
|
|
80
84
|
},
|
|
81
85
|
"nyc": {
|
|
82
86
|
"include": [
|
|
83
|
-
"components/*.js",
|
|
84
|
-
"lib/*.js",
|
|
85
|
-
"lib/**/*.js"
|
|
87
|
+
"src/components/*.js",
|
|
88
|
+
"src/lib/*.js",
|
|
89
|
+
"src/lib/**/*.js"
|
|
86
90
|
]
|
|
87
91
|
}
|
|
88
92
|
}
|
package/spec/ComponentLoader.js
CHANGED
|
@@ -286,7 +286,7 @@ describe('ComponentLoader with no external packages installed', () => {
|
|
|
286
286
|
if (noflo.isBrowser()) {
|
|
287
287
|
str = 'Dynamic loading of';
|
|
288
288
|
} else {
|
|
289
|
-
str = 'Cannot find
|
|
289
|
+
str = 'Cannot find package';
|
|
290
290
|
}
|
|
291
291
|
loader.load('InvalidComponent', (err) => {
|
|
292
292
|
chai.expect(err).to.be.an('error');
|
|
@@ -379,7 +379,13 @@ describe('ComponentLoader with no external packages installed', () => {
|
|
|
379
379
|
chai.expect(component).to.be.an('object');
|
|
380
380
|
chai.expect(component.code).to.be.a('string');
|
|
381
381
|
chai.expect(component.code.indexOf('Component')).to.not.equal(-1);
|
|
382
|
-
|
|
382
|
+
|
|
383
|
+
if (!noflo.isBrowser()) {
|
|
384
|
+
chai.expect(component.code.indexOf('export function getComponent')).to.not.equal(-1);
|
|
385
|
+
} else {
|
|
386
|
+
chai.expect(component.code.indexOf('exports.getComponent')).to.not.equal(-1);
|
|
387
|
+
}
|
|
388
|
+
|
|
383
389
|
chai.expect(component.name).to.equal('Graph');
|
|
384
390
|
chai.expect(component.library).to.equal('');
|
|
385
391
|
chai.expect(component.language).to.equal(shippingLanguage);
|
|
@@ -445,7 +451,11 @@ describe('ComponentLoader with no external packages installed', () => {
|
|
|
445
451
|
chai.expect(component).to.be.an('object');
|
|
446
452
|
chai.expect(component.code).to.be.a('string');
|
|
447
453
|
chai.expect(component.code.indexOf('Component')).to.not.equal(-1);
|
|
448
|
-
|
|
454
|
+
if (!noflo.isBrowser()) {
|
|
455
|
+
chai.expect(component.code.indexOf('export function getComponent')).to.not.equal(-1);
|
|
456
|
+
} else {
|
|
457
|
+
chai.expect(component.code.indexOf('exports.getComponent')).to.not.equal(-1);
|
|
458
|
+
}
|
|
449
459
|
chai.expect(component.name).to.equal('Graph');
|
|
450
460
|
chai.expect(component.library).to.equal('');
|
|
451
461
|
chai.expect(component.language).to.equal(shippingLanguage);
|
|
@@ -975,9 +985,11 @@ describe('ComponentLoader with a fixture project and caching', () => {
|
|
|
975
985
|
it('should be possible to pre-heat the cache file', function (done) {
|
|
976
986
|
this.timeout(8000);
|
|
977
987
|
const { exec } = require('child_process');
|
|
978
|
-
exec(
|
|
988
|
+
exec(
|
|
989
|
+
`node ${path.resolve(__dirname, '../bin/noflo-cache-preheat')}`,
|
|
979
990
|
{ cwd: fixtureRoot },
|
|
980
|
-
done
|
|
991
|
+
done,
|
|
992
|
+
);
|
|
981
993
|
});
|
|
982
994
|
it('should have populated a fbp-manifest file', (done) => {
|
|
983
995
|
const manifestPath = path.resolve(fixtureRoot, 'fbp.json');
|
package/spec/utils/inject.js
CHANGED
|
@@ -3,7 +3,7 @@ if (typeof global !== 'undefined') {
|
|
|
3
3
|
// Node.js injections for Mocha tests
|
|
4
4
|
global.chai = require('chai');
|
|
5
5
|
global.path = require('path');
|
|
6
|
-
global.noflo = require('../../lib/NoFlo');
|
|
6
|
+
global.noflo = require('../../src/lib/NoFlo');
|
|
7
7
|
global.flowtrace = require('flowtrace');
|
|
8
8
|
global.baseDir = process.cwd();
|
|
9
9
|
} else {
|
package/src/lib/AsComponent.js
CHANGED
package/src/lib/NoFlo.js
CHANGED
|
@@ -65,7 +65,7 @@ import { graph } from 'fbp-graph';
|
|
|
65
65
|
// network.
|
|
66
66
|
import { Network } from './Network.js';
|
|
67
67
|
import { LegacyNetwork } from './LegacyNetwork.js';
|
|
68
|
-
import { deprecated } from './Platform.js';
|
|
68
|
+
import { deprecated, isBrowser } from './Platform.js';
|
|
69
69
|
|
|
70
70
|
export {
|
|
71
71
|
graph,
|
|
@@ -87,19 +87,25 @@ export { isBrowser } from './Platform.js';
|
|
|
87
87
|
// to find components and graphs by traversing the NPM dependency tree from a given root
|
|
88
88
|
// directory on the file system.
|
|
89
89
|
export { ComponentLoader } from './ComponentLoader.js';
|
|
90
|
+
import { ComponentLoader } from './ComponentLoader.js';
|
|
90
91
|
|
|
91
92
|
// ### Component baseclasses
|
|
92
93
|
//
|
|
93
94
|
// These baseclasses can be used for defining NoFlo components.
|
|
94
95
|
export { Component } from './Component.js';
|
|
96
|
+
import { Component } from './Component.js';
|
|
95
97
|
|
|
96
98
|
// ### NoFlo ports
|
|
97
99
|
//
|
|
98
100
|
// These classes are used for instantiating ports on NoFlo components.
|
|
99
101
|
export { InPorts, OutPorts } from './Ports.js';
|
|
102
|
+
import { InPorts, OutPorts } from './Ports.js';
|
|
100
103
|
|
|
101
104
|
export { default as InPort } from './InPort.js';
|
|
105
|
+
import InPort from './InPort.js';
|
|
106
|
+
|
|
102
107
|
export { default as OutPort } from './OutPort.js';
|
|
108
|
+
import OutPort from './OutPort.js';
|
|
103
109
|
|
|
104
110
|
// ### NoFlo sockets
|
|
105
111
|
//
|
|
@@ -113,6 +119,7 @@ export { internalSocket };
|
|
|
113
119
|
//
|
|
114
120
|
// NoFlo Information Packets are defined as "IP" objects.
|
|
115
121
|
export { default as IP } from './IP.js';
|
|
122
|
+
import IP from './IP.js';
|
|
116
123
|
|
|
117
124
|
/**
|
|
118
125
|
* @callback NetworkCallback
|
|
@@ -224,6 +231,7 @@ export function saveFile(graphInstance, file, callback) {
|
|
|
224
231
|
// });
|
|
225
232
|
//
|
|
226
233
|
export { asCallback, asPromise } from './AsCallback.js';
|
|
234
|
+
import { asCallback, asPromise } from './AsCallback.js';
|
|
227
235
|
|
|
228
236
|
// ## Generating components from JavaScript functions
|
|
229
237
|
//
|
|
@@ -238,3 +246,23 @@ export { asCallback, asPromise } from './AsCallback.js';
|
|
|
238
246
|
// };
|
|
239
247
|
//
|
|
240
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/loader/NodeJs.js
CHANGED
|
@@ -16,21 +16,26 @@ const readFile = promisify(fs.readFile);
|
|
|
16
16
|
|
|
17
17
|
// Type loading CoffeeScript compiler
|
|
18
18
|
let CoffeeScript;
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
19
|
+
// eslint-disable-next-line import/no-unresolved,import/no-extraneous-dependencies
|
|
20
|
+
import('coffeescript')
|
|
21
|
+
.then((compiler) => {
|
|
22
|
+
CoffeeScript = compiler;
|
|
23
|
+
})
|
|
24
|
+
.catch((e) => {
|
|
25
|
+
// If there is no CoffeeScript compiler installed, we simply don't support compiling
|
|
26
|
+
});
|
|
25
27
|
|
|
26
28
|
// Try loading TypeScript compiler
|
|
27
29
|
let typescript;
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
}
|
|
30
|
+
// eslint-disable-next-line import/no-unresolved,import/no-extraneous-dependencies
|
|
31
|
+
import('typescript')
|
|
32
|
+
.then((compiler) => {
|
|
33
|
+
// @ts-ignore
|
|
34
|
+
typescript = compiler.default;
|
|
35
|
+
})
|
|
36
|
+
.catch((e) => {
|
|
37
|
+
// If there is no TypeScript compiler installed, we simply don't support compiling
|
|
38
|
+
});
|
|
34
39
|
|
|
35
40
|
/**
|
|
36
41
|
* @callback ErrorableCallback
|
|
@@ -72,7 +77,7 @@ function transpileSource(packageId, name, source, language) {
|
|
|
72
77
|
try {
|
|
73
78
|
src = typescript.transpile(source, {
|
|
74
79
|
module: typescript.ModuleKind.CommonJS,
|
|
75
|
-
target: typescript.ScriptTarget.
|
|
80
|
+
target: typescript.ScriptTarget.ES2020,
|
|
76
81
|
});
|
|
77
82
|
} catch (err) {
|
|
78
83
|
return Promise.reject(err);
|
|
@@ -101,25 +106,28 @@ function transpileSource(packageId, name, source, language) {
|
|
|
101
106
|
* @returns {Promise<Object|Function>}
|
|
102
107
|
*/
|
|
103
108
|
function evaluateModule(baseDir, packageId, name, source) {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
109
|
+
return import('module')
|
|
110
|
+
.then(({ Module }) => {
|
|
111
|
+
let implementation;
|
|
112
|
+
// Use the Node.js module API to evaluate in the correct directory context
|
|
113
|
+
let extension = '.js';
|
|
114
|
+
if (source.indexOf('require(') !== -1) {
|
|
115
|
+
// CommonJS
|
|
116
|
+
extension = '.cjs';
|
|
117
|
+
}
|
|
118
|
+
const modulePath = path.resolve(baseDir, `./components/${name}${extension}`);
|
|
119
|
+
const moduleImpl = new Module(modulePath);
|
|
120
|
+
// @ts-ignore
|
|
121
|
+
moduleImpl.paths = Module._nodeModulePaths(path.dirname(modulePath));
|
|
122
|
+
moduleImpl.filename = modulePath;
|
|
123
|
+
// @ts-ignore
|
|
124
|
+
moduleImpl._compile(source, modulePath);
|
|
125
|
+
implementation = moduleImpl.exports;
|
|
126
|
+
if ((typeof implementation !== 'function') && (typeof implementation.getComponent !== 'function')) {
|
|
127
|
+
return Promise.reject(new Error(`Provided source for ${packageId}/${name} failed to create a runnable component`));
|
|
128
|
+
}
|
|
129
|
+
return Promise.resolve(implementation);
|
|
130
|
+
});
|
|
123
131
|
}
|
|
124
132
|
|
|
125
133
|
/**
|
|
@@ -368,9 +376,14 @@ export function getLanguages() {
|
|
|
368
376
|
*/
|
|
369
377
|
function registerCustomLoaders(loader, componentLoaders, callback) {
|
|
370
378
|
componentLoaders.reduce((chain, componentLoader) => chain
|
|
371
|
-
.then(() =>
|
|
372
|
-
|
|
373
|
-
|
|
379
|
+
.then(() => import(componentLoader))
|
|
380
|
+
.then((customLoader) => new Promise((resolve, reject) => {
|
|
381
|
+
let loaderFunc = customLoader;
|
|
382
|
+
if (typeof customLoader === 'object' && customLoader.default) {
|
|
383
|
+
// CommonJS loader
|
|
384
|
+
loaderFunc = customLoader.default;
|
|
385
|
+
}
|
|
386
|
+
loader.registerLoader(loaderFunc, (err) => {
|
|
374
387
|
if (err) {
|
|
375
388
|
reject(err);
|
|
376
389
|
return;
|
|
@@ -611,34 +624,22 @@ export function register(loader, callback) {
|
|
|
611
624
|
* @param {ModuleLoadingCallback} callback
|
|
612
625
|
*/
|
|
613
626
|
export function dynamicLoad(name, cPath, metadata, callback) {
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
}
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
} catch (err) {
|
|
633
|
-
callback(err);
|
|
634
|
-
return;
|
|
635
|
-
}
|
|
636
|
-
} else {
|
|
637
|
-
callback(new Error(`Unable to instantiate ${cPath}`));
|
|
638
|
-
return;
|
|
639
|
-
}
|
|
640
|
-
if (typeof name === 'string') {
|
|
641
|
-
instance.componentName = name;
|
|
642
|
-
}
|
|
643
|
-
callback(null, instance);
|
|
627
|
+
import(cPath)
|
|
628
|
+
.then((implementation) => {
|
|
629
|
+
let instance;
|
|
630
|
+
if (typeof implementation.getComponent === 'function') {
|
|
631
|
+
instance = implementation.getComponent(metadata);
|
|
632
|
+
} else if (typeof implementation === 'function') {
|
|
633
|
+
instance = implementation(metadata);
|
|
634
|
+
} else {
|
|
635
|
+
throw new Error(`Unable to instantiate ${cPath}`);
|
|
636
|
+
}
|
|
637
|
+
if (typeof name === 'string') {
|
|
638
|
+
instance.componentName = name;
|
|
639
|
+
}
|
|
640
|
+
callback(null, instance);
|
|
641
|
+
})
|
|
642
|
+
.catch((e) => {
|
|
643
|
+
callback(e)
|
|
644
|
+
});
|
|
644
645
|
}
|