systemlynx 1.5.0 → 1.6.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 +1 -1
- package/index.test.js +1 -8
- package/package.json +1 -1
- package/systemlynx/App/App.js +10 -13
- package/systemlynx/App/components/initializeApp.js +4 -4
- package/systemlynx/App/components/loadModules.js +2 -4
- package/systemlynx/App/components/loadServices.js +9 -6
- package/systemlynx/App/tests/App.test.js +64 -3
- package/systemlynx/Client/Client.js +10 -4
- package/systemlynx/Client/components/ClientModule.js +3 -2
- package/systemlynx/Client/components/SocketDispatcher.js +2 -2
- package/systemlynx/Client/tests/Client.test.js +20 -17
- package/systemlynx/Dispatcher/Dispatcher.js +5 -2
- package/systemlynx/LoadBalancer/tests/LoadBalancer.test.js +1 -8
- package/systemlynx/ServerManager/ServerManager.js +8 -8
- package/systemlynx/ServerManager/components/Router.js +4 -4
- package/systemlynx/Service/Service.js +17 -10
- package/systemlynx/Service/Service.test.js +5 -3
- package/systemlynx/utils/System.js +7 -0
- package/systemlynx/utils/SystemContext.js +10 -0
- package/systemlynx/App/components/SystemObject.js +0 -9
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# SystemLynx JS   
|
|
2
2
|
|
|
3
|
-
SystemLynx is a framework for developing modular web APIs in NodeJS. It's a wrapper on top of ExpressJS and Socket.io. With SystemLynx, instead of developing a server with endpoints, you can simply
|
|
3
|
+
SystemLynx is a framework for developing modular web APIs in NodeJS. It's a wrapper on top of ExpressJS and Socket.io. With SystemLynx, instead of developing a server with endpoints, you can simply import objects from a server into a client application. Basically any objects hosted by a SystemLynx Service can be loaded and used by a SystemLynx Client.
|
|
4
4
|
|
|
5
5
|
SystemLynx comes with the following objects that are used for web app development:
|
|
6
6
|
|
package/index.test.js
CHANGED
|
@@ -67,14 +67,7 @@ describe("SystemLynx Objects", () => {
|
|
|
67
67
|
it("should return a SystemLynx LoadBalancer", () => {
|
|
68
68
|
expect(LoadBalancer)
|
|
69
69
|
.to.be.an("object")
|
|
70
|
-
.that.has.all.keys(
|
|
71
|
-
"startService",
|
|
72
|
-
"Server",
|
|
73
|
-
"WebSocket",
|
|
74
|
-
"defaultModule",
|
|
75
|
-
"clones",
|
|
76
|
-
"module"
|
|
77
|
-
)
|
|
70
|
+
.that.has.all.keys("startService", "Server", "WebSocket", "clones", "module")
|
|
78
71
|
.that.respondsTo("startService")
|
|
79
72
|
.that.respondsTo("Server")
|
|
80
73
|
.that.respondsTo("WebSocket")
|
package/package.json
CHANGED
package/systemlynx/App/App.js
CHANGED
|
@@ -1,22 +1,19 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
const { isNode } = require("../../utils/ProcessChecker");
|
|
3
|
-
const
|
|
4
|
-
const
|
|
5
|
-
const Dispatcher = require("../Dispatcher/Dispatcher");
|
|
3
|
+
const SystemLynxService = require("../Service/Service");
|
|
4
|
+
const SystemLynxDispatcher = require("../Dispatcher/Dispatcher");
|
|
6
5
|
const initializeApp = require("./components/initializeApp");
|
|
6
|
+
const SystemContext = require("../utils/SystemContext");
|
|
7
|
+
const System = require("../utils/System");
|
|
7
8
|
|
|
8
9
|
module.exports = function SystemLynxApp() {
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
setTimeout(() => initializeApp(system), 0);
|
|
14
|
-
|
|
15
|
-
App.on = (name, callback) => on(name, callback.bind(systemObject));
|
|
10
|
+
const system = new System();
|
|
11
|
+
const systemContext = SystemContext(system);
|
|
12
|
+
const App = SystemLynxDispatcher(undefined, systemContext);
|
|
13
|
+
setTimeout(() => initializeApp(system, App, systemContext), 0);
|
|
16
14
|
|
|
17
15
|
if (isNode) {
|
|
18
|
-
system.Service =
|
|
19
|
-
system.Service.defaultModule = systemObject;
|
|
16
|
+
system.Service = SystemLynxService(systemContext);
|
|
20
17
|
|
|
21
18
|
App.startService = (options) => {
|
|
22
19
|
system.routing = options;
|
|
@@ -50,7 +47,7 @@ module.exports = function SystemLynxApp() {
|
|
|
50
47
|
|
|
51
48
|
App.config = (__constructor) => {
|
|
52
49
|
if (typeof __constructor === "function")
|
|
53
|
-
system.configurations = { __constructor, module:
|
|
50
|
+
system.configurations = { __constructor, module: SystemContext(system) };
|
|
54
51
|
else
|
|
55
52
|
throw Error(
|
|
56
53
|
"[SystemLynx][App][Error]: App.config(...) methods requires a constructor function as its first parameter."
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const loadModules = require("./loadModules");
|
|
2
2
|
const loadServices = require("./loadServices");
|
|
3
3
|
|
|
4
|
-
module.exports = async function initApp(system) {
|
|
4
|
+
module.exports = async function initApp(system, App, systemContext) {
|
|
5
5
|
let configComplete = false;
|
|
6
6
|
const continuationERROR = () => {
|
|
7
7
|
if (!configComplete)
|
|
@@ -16,7 +16,7 @@ module.exports = async function initApp(system) {
|
|
|
16
16
|
};
|
|
17
17
|
|
|
18
18
|
try {
|
|
19
|
-
await loadServices(system);
|
|
19
|
+
await loadServices(system, App, systemContext);
|
|
20
20
|
} catch (err) {
|
|
21
21
|
throw `[SystemLynx][App][Error]: Initialization Error - failed to load all services`;
|
|
22
22
|
}
|
|
@@ -26,8 +26,8 @@ module.exports = async function initApp(system) {
|
|
|
26
26
|
system.configurations.__constructor.apply(system.configurations.module, [
|
|
27
27
|
() => {
|
|
28
28
|
configComplete = true;
|
|
29
|
-
loadModules(system);
|
|
29
|
+
loadModules(system, App);
|
|
30
30
|
},
|
|
31
31
|
]);
|
|
32
|
-
} else loadModules(system);
|
|
32
|
+
} else loadModules(system, App);
|
|
33
33
|
};
|
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
module.exports = async function loadModules(system) {
|
|
1
|
+
module.exports = async function loadModules(system, App) {
|
|
4
2
|
system.Modules.forEach(
|
|
5
3
|
(mod) => (mod.module = system.Service.module(mod.name, mod.__constructor))
|
|
6
4
|
);
|
|
7
5
|
|
|
8
6
|
if (system.routing) await system.Service.startService(system.routing);
|
|
9
|
-
|
|
7
|
+
App.emit("ready", system);
|
|
10
8
|
};
|
|
@@ -1,11 +1,14 @@
|
|
|
1
|
-
const
|
|
2
|
-
|
|
1
|
+
const SystemLynxClient = require("../../Client/Client");
|
|
2
|
+
|
|
3
|
+
module.exports = ({ Services }, App, systemContext) => {
|
|
4
|
+
const Client = SystemLynxClient(systemContext);
|
|
5
|
+
|
|
3
6
|
return Promise.all(
|
|
4
|
-
Services.map(serviceData => {
|
|
7
|
+
Services.map((serviceData) => {
|
|
5
8
|
const { url, limit, wait, name, onLoad } = serviceData;
|
|
6
|
-
return new Promise(resolve => {
|
|
9
|
+
return new Promise((resolve) => {
|
|
7
10
|
Client.loadService(url, { limit, wait })
|
|
8
|
-
.then(service => {
|
|
11
|
+
.then((service) => {
|
|
9
12
|
serviceData.client = service;
|
|
10
13
|
if (typeof onLoad === "function") {
|
|
11
14
|
onLoad(serviceData.client);
|
|
@@ -17,7 +20,7 @@ module.exports = ({ Services, App }) => {
|
|
|
17
20
|
);
|
|
18
21
|
resolve();
|
|
19
22
|
})
|
|
20
|
-
.catch(err => {
|
|
23
|
+
.catch((err) => {
|
|
21
24
|
console.warn(err);
|
|
22
25
|
App.emit("failed_connection", { err, ...serviceData });
|
|
23
26
|
resolve();
|
|
@@ -271,7 +271,6 @@ describe("App SystemObjects: Initializing Modules, Modules and configurations",
|
|
|
271
271
|
"Service",
|
|
272
272
|
"Modules",
|
|
273
273
|
"configurations",
|
|
274
|
-
"App",
|
|
275
274
|
"routing"
|
|
276
275
|
);
|
|
277
276
|
resolve();
|
|
@@ -279,7 +278,7 @@ describe("App SystemObjects: Initializing Modules, Modules and configurations",
|
|
|
279
278
|
);
|
|
280
279
|
});
|
|
281
280
|
|
|
282
|
-
it("should be able to use App.config(constructor) to construct a
|
|
281
|
+
it("should be able to use App.config(constructor) to construct a configuration module", async () => {
|
|
283
282
|
const App = AppFactory();
|
|
284
283
|
|
|
285
284
|
App.module("mod", function () {
|
|
@@ -311,7 +310,7 @@ describe("App SystemObjects: Initializing Modules, Modules and configurations",
|
|
|
311
310
|
});
|
|
312
311
|
});
|
|
313
312
|
|
|
314
|
-
describe("
|
|
313
|
+
describe("SystemContext", () => {
|
|
315
314
|
it("should be able to use this.useModule and this.useService within modules and Module", () => {
|
|
316
315
|
const App = AppFactory();
|
|
317
316
|
App.module("mod1", function () {
|
|
@@ -333,6 +332,7 @@ describe("SystemObjects", () => {
|
|
|
333
332
|
const config = this.useConfig();
|
|
334
333
|
expect(mod1.testPassed).to.equal(true);
|
|
335
334
|
expect(config.configPassed).to.equal(true);
|
|
335
|
+
this.testPassed = true;
|
|
336
336
|
})
|
|
337
337
|
.config(function (next) {
|
|
338
338
|
expect(this)
|
|
@@ -353,7 +353,68 @@ describe("SystemObjects", () => {
|
|
|
353
353
|
const config = this.useConfig();
|
|
354
354
|
expect(mod1.testPassed).to.equal(true);
|
|
355
355
|
expect(config.configPassed).to.equal(true);
|
|
356
|
+
})
|
|
357
|
+
.on("ready", function () {
|
|
358
|
+
expect(this)
|
|
359
|
+
.to.be.an("object")
|
|
360
|
+
.that.respondsTo("useService")
|
|
361
|
+
.that.respondsTo("useModule")
|
|
362
|
+
.that.respondsTo("useConfig");
|
|
363
|
+
const mod2 = this.useModule("mod2");
|
|
364
|
+
const config = this.useConfig();
|
|
365
|
+
expect(mod2.testPassed).to.equal(true);
|
|
366
|
+
expect(config.configPassed).to.equal(true);
|
|
356
367
|
});
|
|
357
368
|
return new Promise((resolve) => App.on("ready", () => resolve()));
|
|
358
369
|
});
|
|
370
|
+
it("[SystemLynx][App][Client][on] should have access to systemContext during event callbacks.", async () => {
|
|
371
|
+
const AppBackend = AppFactory();
|
|
372
|
+
const eventName = "testing-this";
|
|
373
|
+
const _route = "test-service";
|
|
374
|
+
const _port = "8900";
|
|
375
|
+
const _url = `http://localhost:${_port}/${_route}`;
|
|
376
|
+
AppBackend.module("EventTesterModule", function () {
|
|
377
|
+
this.sendEvent = () => this.emit(eventName, { testPassed: true });
|
|
378
|
+
|
|
379
|
+
//testing local event callback context
|
|
380
|
+
this.on(eventName, function () {
|
|
381
|
+
console.log("Aww man... here we go again!", this);
|
|
382
|
+
expect(this)
|
|
383
|
+
.to.be.an("object")
|
|
384
|
+
.that.respondsTo("useService")
|
|
385
|
+
.that.respondsTo("useModule")
|
|
386
|
+
.that.respondsTo("useConfig");
|
|
387
|
+
});
|
|
388
|
+
});
|
|
389
|
+
await AppBackend.startService({ route: _route, port: _port });
|
|
390
|
+
|
|
391
|
+
const AppClient = AppFactory();
|
|
392
|
+
const route = "test-service";
|
|
393
|
+
const port = "8901";
|
|
394
|
+
|
|
395
|
+
AppClient.startService({ route, port }).loadService("buAPI", _url);
|
|
396
|
+
await new Promise((resolve) =>
|
|
397
|
+
AppClient.on("ready", function () {
|
|
398
|
+
const { EventTesterModule } = this.useService("buAPI");
|
|
399
|
+
EventTesterModule.on(eventName, function (data, event) {
|
|
400
|
+
console.log("Ladies and gentleman... another one!");
|
|
401
|
+
expect(this)
|
|
402
|
+
.to.be.an("object")
|
|
403
|
+
.that.respondsTo("useService")
|
|
404
|
+
.that.respondsTo("useModule")
|
|
405
|
+
.that.respondsTo("useConfig");
|
|
406
|
+
expect(data).to.deep.equal({ testPassed: true });
|
|
407
|
+
expect(event)
|
|
408
|
+
.to.be.an("object")
|
|
409
|
+
.that.has.all.keys("id", "name", "data", "type");
|
|
410
|
+
expect(event.name).to.equal(eventName);
|
|
411
|
+
expect(event.data).to.deep.equal({ testPassed: true });
|
|
412
|
+
expect(event.id).to.be.a("string");
|
|
413
|
+
expect(event.type).to.equal("WebSocket");
|
|
414
|
+
resolve();
|
|
415
|
+
});
|
|
416
|
+
EventTesterModule.sendEvent(eventName);
|
|
417
|
+
})
|
|
418
|
+
);
|
|
419
|
+
});
|
|
359
420
|
});
|
|
@@ -3,7 +3,7 @@ const loadConnectionData = require("./components/loadConnectionData");
|
|
|
3
3
|
const SocketDispatcher = require("./components/SocketDispatcher");
|
|
4
4
|
const ClientModule = require("./components/ClientModule");
|
|
5
5
|
|
|
6
|
-
module.exports = function SystemLynxClient() {
|
|
6
|
+
module.exports = function SystemLynxClient(systemContext) {
|
|
7
7
|
const Client = {};
|
|
8
8
|
Client.loadedServices = {};
|
|
9
9
|
|
|
@@ -12,14 +12,14 @@ module.exports = function SystemLynxClient() {
|
|
|
12
12
|
return Client.loadedServices[url];
|
|
13
13
|
|
|
14
14
|
const connData = await loadConnectionData(url, options);
|
|
15
|
-
const Service = SocketDispatcher(connData.namespace);
|
|
15
|
+
const Service = SocketDispatcher(connData.namespace, undefined, systemContext);
|
|
16
16
|
Client.loadedServices[url] = Service;
|
|
17
17
|
if (options.name) Client[options.name] = Service;
|
|
18
18
|
|
|
19
19
|
Service.resetConnection = async (cb) => {
|
|
20
20
|
const { modules, host, port, namespace } = await loadConnectionData(url, options);
|
|
21
21
|
|
|
22
|
-
SocketDispatcher.apply(Service, [namespace]);
|
|
22
|
+
SocketDispatcher.apply(Service, [namespace, undefined, systemContext]);
|
|
23
23
|
|
|
24
24
|
modules.forEach(({ namespace, route, name }) =>
|
|
25
25
|
Service[name].__setConnection(host, port, route, namespace)
|
|
@@ -29,7 +29,13 @@ module.exports = function SystemLynxClient() {
|
|
|
29
29
|
};
|
|
30
30
|
|
|
31
31
|
connData.modules.forEach(
|
|
32
|
-
(mod) =>
|
|
32
|
+
(mod) =>
|
|
33
|
+
(Service[mod.name] = ClientModule(
|
|
34
|
+
mod,
|
|
35
|
+
connData,
|
|
36
|
+
Service.resetConnection,
|
|
37
|
+
systemContext
|
|
38
|
+
))
|
|
33
39
|
);
|
|
34
40
|
|
|
35
41
|
Service.on("disconnect", Service.resetConnection);
|
|
@@ -4,14 +4,15 @@ const SocketDispatcher = require("./SocketDispatcher");
|
|
|
4
4
|
module.exports = function SystemLynxClientModule(
|
|
5
5
|
{ methods, namespace, route },
|
|
6
6
|
{ port, host },
|
|
7
|
-
resetConnection
|
|
7
|
+
resetConnection,
|
|
8
|
+
systemContext
|
|
8
9
|
) {
|
|
9
10
|
const events = {};
|
|
10
11
|
const ClientModule = this || {};
|
|
11
12
|
|
|
12
13
|
ClientModule.__setConnection = (host, port, route, namespace) => {
|
|
13
14
|
ClientModule.__connectionData = () => ({ route, host, port });
|
|
14
|
-
SocketDispatcher.apply(ClientModule, [namespace, events]);
|
|
15
|
+
SocketDispatcher.apply(ClientModule, [namespace, events, systemContext]);
|
|
15
16
|
};
|
|
16
17
|
|
|
17
18
|
ClientModule.__setConnection(host, port, route, namespace);
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
const io = require("socket.io-client");
|
|
3
3
|
const SystemLynxDispatcher = require("../../Dispatcher/Dispatcher");
|
|
4
4
|
|
|
5
|
-
module.exports = function SocketDispatcher(namespace, events = {}) {
|
|
5
|
+
module.exports = function SocketDispatcher(namespace, events = {}, systemContext) {
|
|
6
6
|
const dispatcher =
|
|
7
7
|
(this || {}).on && (this || {}).emit
|
|
8
8
|
? this
|
|
9
|
-
: SystemLynxDispatcher.apply(this, [events]);
|
|
9
|
+
: SystemLynxDispatcher.apply(this, [events, systemContext]);
|
|
10
10
|
const socket = io.connect(namespace);
|
|
11
11
|
socket.on("dispatch", (event) => dispatcher.emit(event.name, event.data, event));
|
|
12
12
|
socket.on("disconnect", () => {
|
|
@@ -119,27 +119,32 @@ describe("Service", () => {
|
|
|
119
119
|
|
|
120
120
|
it("should be able to receive events emitted from the backend Client", async () => {
|
|
121
121
|
const eventName = "testing";
|
|
122
|
+
const route = "test-service";
|
|
123
|
+
const port = "8980";
|
|
124
|
+
const url = `http://localhost:${port}/${route}`;
|
|
125
|
+
const Service = ServiceFactory();
|
|
122
126
|
const eventTester = Service.module("eventTester", function () {
|
|
123
|
-
|
|
124
|
-
eventTester.sendEvent = () => eventTester.emit(eventName, { testPassed: true });
|
|
127
|
+
this.sendEvent = () => this.emit(eventName, { testPassed: true });
|
|
125
128
|
});
|
|
129
|
+
await Service.startService({ route, port });
|
|
126
130
|
|
|
127
131
|
const Client = ClientFactory();
|
|
128
|
-
const buAPI = await Client.loadService(url);
|
|
129
132
|
|
|
130
|
-
buAPI.
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
133
|
+
const buAPI = await Client.loadService(url);
|
|
134
|
+
setTimeout(() => eventTester.emit(eventName, { testPassed: true }), 500);
|
|
135
|
+
|
|
136
|
+
await new Promise((resolve) => {
|
|
137
|
+
buAPI.eventTester.on(eventName, (data, event) => {
|
|
138
|
+
console.log("Ladies and gentleman... mission accomplish!");
|
|
139
|
+
expect(data).to.deep.equal({ testPassed: true });
|
|
140
|
+
expect(event).to.be.an("object").that.has.all.keys("id", "name", "data", "type");
|
|
141
|
+
expect(event.name).to.equal(eventName);
|
|
142
|
+
expect(event.data).to.deep.equal({ testPassed: true });
|
|
143
|
+
expect(event.id).to.be.a("string");
|
|
144
|
+
expect(event.type).to.equal("WebSocket");
|
|
145
|
+
resolve();
|
|
146
|
+
});
|
|
140
147
|
});
|
|
141
|
-
|
|
142
|
-
eventTester.emit(eventName, { testPassed: true });
|
|
143
148
|
});
|
|
144
149
|
|
|
145
150
|
it("should be able to send REST http requests", async () => {
|
|
@@ -193,8 +198,6 @@ describe("Service", () => {
|
|
|
193
198
|
route,
|
|
194
199
|
port,
|
|
195
200
|
host,
|
|
196
|
-
useReturnValues: true,
|
|
197
|
-
useCallbacks: false,
|
|
198
201
|
});
|
|
199
202
|
const Client = ClientFactory();
|
|
200
203
|
const { AsyncMath } = await Client.loadService(url);
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
module.exports = function SystemLynxDispatcher(events = {}) {
|
|
2
|
+
module.exports = function SystemLynxDispatcher(events = {}, systemContext) {
|
|
3
3
|
const Dispatcher = this || {};
|
|
4
4
|
|
|
5
5
|
Dispatcher.emit = (eventName, data, event) => {
|
|
6
|
-
if (events[eventName])
|
|
6
|
+
if (events[eventName])
|
|
7
|
+
events[eventName].forEach((callback) =>
|
|
8
|
+
callback.apply(systemContext, [data, event])
|
|
9
|
+
);
|
|
7
10
|
return Dispatcher;
|
|
8
11
|
};
|
|
9
12
|
|
|
@@ -9,14 +9,7 @@ describe("LoadBalancerFactory", () => {
|
|
|
9
9
|
it("should return a SystemLynx LoadBalancer", () => {
|
|
10
10
|
expect(LoadBalancer)
|
|
11
11
|
.to.be.an("object")
|
|
12
|
-
.that.has.all.keys(
|
|
13
|
-
"startService",
|
|
14
|
-
"Server",
|
|
15
|
-
"WebSocket",
|
|
16
|
-
"defaultModule",
|
|
17
|
-
"module",
|
|
18
|
-
"clones"
|
|
19
|
-
)
|
|
12
|
+
.that.has.all.keys("startService", "Server", "WebSocket", "module", "clones")
|
|
20
13
|
.that.respondsTo("startService")
|
|
21
14
|
.that.respondsTo("Server")
|
|
22
15
|
.that.respondsTo("WebSocket")
|
|
@@ -64,8 +64,8 @@ module.exports = function SystemLynxServerManager() {
|
|
|
64
64
|
return new Promise((resolve) =>
|
|
65
65
|
server.listen(port, () => {
|
|
66
66
|
console.log(`[SystemLynx][Service]: Listening on ${serviceUrl}`);
|
|
67
|
-
moduleQueue.forEach(({ name,
|
|
68
|
-
ServerManager.addModule(name,
|
|
67
|
+
moduleQueue.forEach(({ name, Module, reserved_methods }) =>
|
|
68
|
+
ServerManager.addModule(name, Module, reserved_methods)
|
|
69
69
|
);
|
|
70
70
|
moduleQueue.length = 0;
|
|
71
71
|
resolve(ServerManager);
|
|
@@ -73,15 +73,15 @@ module.exports = function SystemLynxServerManager() {
|
|
|
73
73
|
);
|
|
74
74
|
};
|
|
75
75
|
|
|
76
|
-
ServerManager.addModule = (name,
|
|
76
|
+
ServerManager.addModule = (name, Module, reserved_methods = []) => {
|
|
77
77
|
const { host, route, serviceUrl, staticRouting, useService, useREST, socketPort } =
|
|
78
78
|
serverConfigurations;
|
|
79
79
|
|
|
80
|
-
if (!serviceUrl) return moduleQueue.push({ name,
|
|
81
|
-
const methods = parseMethods(
|
|
80
|
+
if (!serviceUrl) return moduleQueue.push({ name, Module, reserved_methods });
|
|
81
|
+
const methods = parseMethods(Module, ["on", "emit", ...reserved_methods], useREST);
|
|
82
82
|
const namespace = staticRouting ? name : shortId();
|
|
83
83
|
|
|
84
|
-
SocketEmitter.apply(
|
|
84
|
+
SocketEmitter.apply(Module, [namespace, WebSocket]);
|
|
85
85
|
|
|
86
86
|
if (useService) {
|
|
87
87
|
const path = staticRouting ? `${route}/${name}` : `${shortId()}/${shortId()}`;
|
|
@@ -92,7 +92,7 @@ module.exports = function SystemLynxServerManager() {
|
|
|
92
92
|
name,
|
|
93
93
|
methods,
|
|
94
94
|
});
|
|
95
|
-
methods.forEach((method) => router.addService(
|
|
95
|
+
methods.forEach((method) => router.addService(Module, path, method, name));
|
|
96
96
|
}
|
|
97
97
|
if (useREST)
|
|
98
98
|
methods.forEach((method) => {
|
|
@@ -101,7 +101,7 @@ module.exports = function SystemLynxServerManager() {
|
|
|
101
101
|
case "put":
|
|
102
102
|
case "post":
|
|
103
103
|
case "delete":
|
|
104
|
-
router.addREST(
|
|
104
|
+
router.addREST(Module, `${route}/${name}`, method, name);
|
|
105
105
|
}
|
|
106
106
|
});
|
|
107
107
|
};
|
|
@@ -36,8 +36,8 @@ module.exports = function SystemLynxRouter(server, config) {
|
|
|
36
36
|
const presets = { serviceUrl, module_name, fn };
|
|
37
37
|
|
|
38
38
|
const sendError = (error) => {
|
|
39
|
-
const status = error.status || 500;
|
|
40
|
-
const message = error.message || "Unexpected error";
|
|
39
|
+
const status = (error || {}).status || 500;
|
|
40
|
+
const message = (error || {}).message || "Unexpected error";
|
|
41
41
|
const unhandledMessage = status === 500 ? "Unhandled error" : "Error";
|
|
42
42
|
res.status(status).json({
|
|
43
43
|
...presets,
|
|
@@ -49,13 +49,13 @@ module.exports = function SystemLynxRouter(server, config) {
|
|
|
49
49
|
};
|
|
50
50
|
|
|
51
51
|
const sendResponse = (returnValue) => {
|
|
52
|
-
const status = returnValue.status || 200;
|
|
52
|
+
const status = (returnValue || {}).status || 200;
|
|
53
53
|
if (status < 400) {
|
|
54
54
|
res.status(status).json({
|
|
55
55
|
...presets,
|
|
56
56
|
status,
|
|
57
57
|
message:
|
|
58
|
-
returnValue.message ||
|
|
58
|
+
(returnValue || {}).message ||
|
|
59
59
|
`[SystemLynx][response]: ${module_name}.${fn}(...) returned successfully`,
|
|
60
60
|
returnValue,
|
|
61
61
|
});
|
|
@@ -1,27 +1,34 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
const ServerManagerFactory = require("../ServerManager/ServerManager");
|
|
3
|
-
const
|
|
3
|
+
const SystemLynxDispatcher = require("../Dispatcher/Dispatcher");
|
|
4
4
|
|
|
5
|
-
module.exports = function ServiceFactory(
|
|
5
|
+
module.exports = function ServiceFactory(systemContext = {}) {
|
|
6
6
|
const ServerManager = ServerManagerFactory();
|
|
7
7
|
const { startService, Server, WebSocket } = ServerManager;
|
|
8
|
-
const Service = { startService, Server, WebSocket
|
|
8
|
+
const Service = { startService, Server, WebSocket };
|
|
9
9
|
|
|
10
10
|
Service.module = function (name, constructor, reserved_methods = []) {
|
|
11
|
+
const exclude_methods = reserved_methods.concat(
|
|
12
|
+
Object.getOwnPropertyNames(systemContext)
|
|
13
|
+
);
|
|
14
|
+
|
|
11
15
|
if (typeof constructor === "object" && constructor instanceof Object) {
|
|
12
|
-
|
|
13
|
-
|
|
16
|
+
const Module = SystemLynxDispatcher.apply({ ...constructor, ...systemContext }, [
|
|
17
|
+
undefined,
|
|
18
|
+
systemContext,
|
|
19
|
+
]);
|
|
20
|
+
ServerManager.addModule(name, Module, exclude_methods);
|
|
21
|
+
return Module;
|
|
14
22
|
}
|
|
15
23
|
|
|
16
24
|
if (typeof constructor === "function") {
|
|
17
25
|
if (constructor.constructor.name === "AsyncFunction")
|
|
18
26
|
throw `[SystemLynx][Module][Error]: Module(name, constructor) function cannot receive an async function as the constructor`;
|
|
19
27
|
|
|
20
|
-
const Module =
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
];
|
|
28
|
+
const Module = SystemLynxDispatcher.apply(systemContext, [
|
|
29
|
+
undefined,
|
|
30
|
+
systemContext,
|
|
31
|
+
]);
|
|
25
32
|
constructor.apply(Module, [ServerManager.Server(), ServerManager.WebSocket()]);
|
|
26
33
|
ServerManager.addModule(name, Module, exclude_methods);
|
|
27
34
|
return Module;
|
|
@@ -7,7 +7,7 @@ describe("SystemLynxService", () => {
|
|
|
7
7
|
const Service = ServiceFactory();
|
|
8
8
|
expect(Service)
|
|
9
9
|
.to.be.an("object")
|
|
10
|
-
.that.has.all.keys("startService", "module", "Server", "WebSocket"
|
|
10
|
+
.that.has.all.keys("startService", "module", "Server", "WebSocket")
|
|
11
11
|
.that.respondsTo("startService")
|
|
12
12
|
.that.respondsTo("module")
|
|
13
13
|
.that.respondsTo("Server")
|
|
@@ -123,9 +123,11 @@ describe("Service.module(object)", () => {
|
|
|
123
123
|
|
|
124
124
|
expect(mod)
|
|
125
125
|
.to.be.an("Object")
|
|
126
|
-
.that.has.all.keys("action1", "action2")
|
|
126
|
+
.that.has.all.keys("action1", "action2", "on", "emit")
|
|
127
127
|
.that.respondsTo("action1")
|
|
128
|
-
.that.respondsTo("action2")
|
|
128
|
+
.that.respondsTo("action2")
|
|
129
|
+
.that.respondsTo("on")
|
|
130
|
+
.that.respondsTo("emit");
|
|
129
131
|
});
|
|
130
132
|
it("should 'Serve' Service connection data created using an object as the constructor", async () => {
|
|
131
133
|
await Service.startService({ route, port });
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
module.exports = function SystemObject(system) {
|
|
3
|
+
const context = this || {};
|
|
4
|
+
context.useModule = (modName) =>
|
|
5
|
+
(system.Modules.find((mod) => mod.name === modName) || {}).module || {};
|
|
6
|
+
context.useService = (serviceName) =>
|
|
7
|
+
(system.Services.find((mod) => mod.name === serviceName) || {}).client || {};
|
|
8
|
+
context.useConfig = () => system.configurations.module || {};
|
|
9
|
+
return context;
|
|
10
|
+
};
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
module.exports = function SystemObject(system) {
|
|
3
|
-
const App = this || {};
|
|
4
|
-
App.useModule = modName => (system.Modules.find(mod => mod.name === modName) || {}).module || {};
|
|
5
|
-
App.useService = serviceName =>
|
|
6
|
-
(system.Services.find(mod => mod.name === serviceName) || {}).client || {};
|
|
7
|
-
App.useConfig = () => system.configurations.module || {};
|
|
8
|
-
return App;
|
|
9
|
-
};
|