systemlynx 1.16.11 → 1.18.11
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 +2 -0
- package/logo.png +0 -0
- package/package.json +3 -2
- package/systemlynx/App/tests/App.test.js +4 -2
- package/systemlynx/Client/Client.js +10 -7
- package/systemlynx/Client/components/ClientModule.js +11 -7
- package/systemlynx/Client/components/SocketDispatcher.js +13 -3
- package/systemlynx/Client/tests/SocketDispatcher.test.js +11 -9
- package/systemlynx/LoadBalancer/tests/LoadBalancer.test.js +4 -2
- package/systemlynx/ServerManager/ServerManager.js +25 -27
- package/systemlynx/ServerManager/components/WebSocketServer.js +3 -3
- package/systemlynx/ServerManager/tests/ServerManager.test.js +3 -0
- package/systemlynx/Service/Service.test.js +6 -3
package/README.md
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
<img src="./logo.png" alt="Alt text" style="background:white; border-radius:20px; padding:10px"/>
|
|
2
|
+
|
|
1
3
|
# SystemLynx JS   
|
|
2
4
|
|
|
3
5
|
SystemLynx is a NodeJS framework for building modular web APIs, built on top of ExpressJS and Socket.io. It allows you to create objects and load them from a server into a client application.
|
package/logo.png
ADDED
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "systemlynx",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.18.11",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"browser": {
|
|
@@ -16,7 +16,8 @@
|
|
|
16
16
|
"mime": "^2.4.0",
|
|
17
17
|
"multer": "^1.4.2",
|
|
18
18
|
"shortid": "^2.2.14",
|
|
19
|
-
"socket.io": "^
|
|
19
|
+
"socket.io": "^4.8.1",
|
|
20
|
+
"socket.io-client": "^4.8.1"
|
|
20
21
|
},
|
|
21
22
|
"repository": {
|
|
22
23
|
"type": "git",
|
|
@@ -294,7 +294,8 @@ describe("App SystemObjects: Initializing Modules, Modules and configurations",
|
|
|
294
294
|
"modules",
|
|
295
295
|
"route",
|
|
296
296
|
"namespace",
|
|
297
|
-
"serviceUrl"
|
|
297
|
+
"serviceUrl",
|
|
298
|
+
"socketPath"
|
|
298
299
|
)
|
|
299
300
|
.that.has.property("modules")
|
|
300
301
|
.that.is.an("array").that.is.empty;
|
|
@@ -329,7 +330,8 @@ describe("App SystemObjects: Initializing Modules, Modules and configurations",
|
|
|
329
330
|
"modules",
|
|
330
331
|
"route",
|
|
331
332
|
"namespace",
|
|
332
|
-
"serviceUrl"
|
|
333
|
+
"serviceUrl",
|
|
334
|
+
"socketPath"
|
|
333
335
|
)
|
|
334
336
|
.that.has.property("modules")
|
|
335
337
|
.that.is.an("array");
|
|
@@ -27,21 +27,24 @@ module.exports = function createClient(httpClient = HttpClient(), systemContext)
|
|
|
27
27
|
return Client.cachedServices[connData.serviceUrl];
|
|
28
28
|
|
|
29
29
|
const Service = {};
|
|
30
|
-
SocketDispatcher.apply(Service, [connData
|
|
30
|
+
SocketDispatcher.apply(Service, [connData, events, systemContext]);
|
|
31
31
|
HeaderSetter.apply(Service);
|
|
32
32
|
Client.cachedServices[connData.serviceUrl] = Service;
|
|
33
33
|
|
|
34
34
|
Service.resetConnection = async (cb) => {
|
|
35
35
|
try {
|
|
36
|
-
const { modules, host, port, namespace } =
|
|
37
|
-
httpClient,
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
36
|
+
const { modules, host, port, route, namespace, socketPath } =
|
|
37
|
+
await loadConnectionData(httpClient, connData.serviceUrl);
|
|
38
|
+
|
|
39
|
+
SocketDispatcher.apply(Service, [
|
|
40
|
+
{ socketPath, namespace },
|
|
41
|
+
events,
|
|
42
|
+
systemContext,
|
|
43
|
+
]);
|
|
41
44
|
|
|
42
45
|
modules.forEach(({ namespace, route, name }) => {
|
|
43
46
|
if (Service[name]) {
|
|
44
|
-
Service[name].__setConnection(host, port, route, namespace);
|
|
47
|
+
Service[name].__setConnection({ host, port, route, namespace, socketPath });
|
|
45
48
|
Service[name].emit("reconnect");
|
|
46
49
|
}
|
|
47
50
|
});
|
|
@@ -7,26 +7,30 @@ const getProtocol = (url) => url.match(/^(\w+):\/\//)[0];
|
|
|
7
7
|
module.exports = function SystemLynxClientModule(
|
|
8
8
|
httpClient,
|
|
9
9
|
{ methods, namespace, route, connectionData, name },
|
|
10
|
-
{ port, host, serviceUrl },
|
|
10
|
+
{ port, host, serviceUrl, socketPath },
|
|
11
11
|
Service,
|
|
12
12
|
systemContext
|
|
13
13
|
) {
|
|
14
14
|
const events = {};
|
|
15
15
|
const ClientModule = headerSetter.apply({});
|
|
16
16
|
|
|
17
|
-
ClientModule.__setConnection = (host, port, route, namespace) => {
|
|
17
|
+
ClientModule.__setConnection = ({ host, port, route, namespace, socketPath }) => {
|
|
18
18
|
ClientModule.__connectionData = () => ({ route, host, port });
|
|
19
19
|
|
|
20
|
-
SocketDispatcher.apply(ClientModule, [
|
|
20
|
+
SocketDispatcher.apply(ClientModule, [
|
|
21
|
+
{ namespace, socketPath },
|
|
22
|
+
events,
|
|
23
|
+
systemContext,
|
|
24
|
+
]);
|
|
21
25
|
};
|
|
22
|
-
ClientModule.__setConnection(host, port, route, namespace);
|
|
26
|
+
ClientModule.__setConnection({ host, port, route, namespace, socketPath });
|
|
23
27
|
|
|
24
28
|
const reconnectModule = async (cb) => {
|
|
25
29
|
try {
|
|
26
30
|
const url = connectionData.serviceUrl + `?modules=${name}`;
|
|
27
|
-
const { modules, port, host } = await loadConnectionData(url);
|
|
28
|
-
const {
|
|
29
|
-
ClientModule.__setConnection(host, port, route, namespace);
|
|
31
|
+
const { modules, port, host, socketPath } = await loadConnectionData(url);
|
|
32
|
+
const { route, namespace } = modules[0];
|
|
33
|
+
ClientModule.__setConnection({ host, port, route, namespace, socketPath });
|
|
30
34
|
|
|
31
35
|
if (typeof cb === "function") cb();
|
|
32
36
|
} catch (error) {
|
|
@@ -2,18 +2,28 @@
|
|
|
2
2
|
const io = require("socket.io-client");
|
|
3
3
|
const createDispatcher = require("../../Dispatcher/Dispatcher");
|
|
4
4
|
|
|
5
|
-
module.exports = function SocketDispatcher(
|
|
5
|
+
module.exports = function SocketDispatcher(
|
|
6
|
+
{ namespace, socketPath: path },
|
|
7
|
+
events = {},
|
|
8
|
+
systemContext
|
|
9
|
+
) {
|
|
6
10
|
const dispatcher =
|
|
7
11
|
(this || {}).on && (this || {}).emit
|
|
8
12
|
? this
|
|
9
13
|
: createDispatcher.apply(this, [events, systemContext]);
|
|
10
|
-
|
|
14
|
+
|
|
15
|
+
const socket = io.connect(namespace, { path });
|
|
16
|
+
|
|
11
17
|
socket.on("dispatch", (event) => dispatcher.emit(event.name, event.data, event));
|
|
18
|
+
|
|
12
19
|
socket.on("disconnect", () => {
|
|
13
20
|
socket.disconnect();
|
|
14
21
|
dispatcher.emit("disconnect");
|
|
15
22
|
});
|
|
16
|
-
|
|
23
|
+
|
|
24
|
+
socket.on("connect", () => {
|
|
25
|
+
dispatcher.emit("connect");
|
|
26
|
+
});
|
|
17
27
|
|
|
18
28
|
dispatcher.disconnect = () => socket.disconnect();
|
|
19
29
|
return dispatcher;
|
|
@@ -1,17 +1,21 @@
|
|
|
1
1
|
const { expect } = require("chai");
|
|
2
2
|
const SocketDispatcher = require("../components/SocketDispatcher");
|
|
3
|
-
const { WebSocket, SocketServer } =
|
|
4
|
-
require("../../ServerManager/components/WebSocketServer")();
|
|
5
|
-
|
|
6
|
-
const namespace = "test-namespace";
|
|
7
3
|
const port = 4592;
|
|
8
|
-
const
|
|
4
|
+
const socketPath = "/test-namespace";
|
|
5
|
+
const route = `/events`;
|
|
6
|
+
const namespace = `http://localhost:${port}${route}`;
|
|
7
|
+
const { WebSocket, SocketServer } =
|
|
8
|
+
require("../../ServerManager/components/WebSocketServer")(socketPath);
|
|
9
9
|
|
|
10
|
+
const socket = WebSocket.of(route);
|
|
11
|
+
socket.on("connect", ({ id }) => {
|
|
12
|
+
console.log(`socket connected with id:${id}`);
|
|
13
|
+
});
|
|
10
14
|
SocketServer.listen(port);
|
|
11
15
|
|
|
12
16
|
describe("SocketDispatcher", () => {
|
|
13
17
|
const eventName = "test-event";
|
|
14
|
-
const dispatcher = new SocketDispatcher(
|
|
18
|
+
const dispatcher = new SocketDispatcher({ namespace, socketPath });
|
|
15
19
|
it("should return an EventDispatcher object with methods on and emit", async () => {
|
|
16
20
|
expect(dispatcher)
|
|
17
21
|
.to.be.an("object")
|
|
@@ -36,9 +40,7 @@ describe("SocketDispatcher", () => {
|
|
|
36
40
|
|
|
37
41
|
describe("SocketDispatcher.apply()", () => {
|
|
38
42
|
const eventName = "testing-event";
|
|
39
|
-
const dispatcher = SocketDispatcher.apply({}, [
|
|
40
|
-
`http://localhost:${port}/${namespace}`,
|
|
41
|
-
]);
|
|
43
|
+
const dispatcher = SocketDispatcher.apply({}, [{ namespace, socketPath }]);
|
|
42
44
|
it("should return an EventDispatcher object with methods on and emit", async () => {
|
|
43
45
|
expect(dispatcher)
|
|
44
46
|
.to.be.an("object")
|
|
@@ -67,7 +67,8 @@ describe("LoadBalancer", () => {
|
|
|
67
67
|
"modules",
|
|
68
68
|
"route",
|
|
69
69
|
"namespace",
|
|
70
|
-
"serviceUrl"
|
|
70
|
+
"serviceUrl",
|
|
71
|
+
"socketPath"
|
|
71
72
|
)
|
|
72
73
|
.that.has.property("modules")
|
|
73
74
|
.that.is.an("array")
|
|
@@ -132,7 +133,8 @@ describe("LoadBalancer.clones (Module)", () => {
|
|
|
132
133
|
"modules",
|
|
133
134
|
"route",
|
|
134
135
|
"namespace",
|
|
135
|
-
"serviceUrl"
|
|
136
|
+
"serviceUrl",
|
|
137
|
+
"socketPath"
|
|
136
138
|
)
|
|
137
139
|
.that.has.property("modules")
|
|
138
140
|
.that.is.an("array")
|
|
@@ -3,7 +3,6 @@ const createServer = require("./components/Server");
|
|
|
3
3
|
const createRouter = require("./components/Router");
|
|
4
4
|
const SocketEmitter = require("./components/SocketEmitter");
|
|
5
5
|
const parseMethods = require("./components/parseMethods");
|
|
6
|
-
const shortId = require("shortid");
|
|
7
6
|
const http = require("http");
|
|
8
7
|
const https = require("https");
|
|
9
8
|
const socketIO = require("socket.io");
|
|
@@ -19,10 +18,10 @@ module.exports = function createServerManager(customServer) {
|
|
|
19
18
|
port: null,
|
|
20
19
|
useREST: false,
|
|
21
20
|
useService: true,
|
|
22
|
-
staticRouting: false,
|
|
23
21
|
ssl: { key: "", cert: "" },
|
|
24
22
|
beforeware: { $all: [] },
|
|
25
23
|
afterware: { $all: [] },
|
|
24
|
+
protocol: "http",
|
|
26
25
|
};
|
|
27
26
|
|
|
28
27
|
const server = createServer(customServer);
|
|
@@ -33,32 +32,22 @@ module.exports = function createServerManager(customServer) {
|
|
|
33
32
|
const ServerManager = { server };
|
|
34
33
|
|
|
35
34
|
ServerManager.startService = (options) => {
|
|
36
|
-
let { route, host = "localhost", port,
|
|
35
|
+
let { route, host = "localhost", port, ssl, protocol } = options;
|
|
37
36
|
|
|
38
37
|
route = route.charAt(0) === "/" ? route.substr(1) : route;
|
|
39
38
|
route = route.charAt(route.length - 1) === "/" ? route.slice(0, -1) : route;
|
|
40
39
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
const protocol = ssl ? "https" : "http";
|
|
40
|
+
if (!["http", "https"].includes(protocol)) protocol = ssl ? "https" : "http";
|
|
44
41
|
const serviceUrl = `${protocol}://${host}:${port}/${route}`;
|
|
45
42
|
|
|
46
43
|
const httpServer = ssl ? https.createServer(ssl, server) : http.createServer(server);
|
|
44
|
+
const socketPath = `/${route}/socket.io`;
|
|
47
45
|
|
|
48
|
-
const WebSocket = socketIO(httpServer);
|
|
46
|
+
const WebSocket = socketIO(httpServer, { path: socketPath });
|
|
49
47
|
|
|
50
|
-
SocketEmitter.apply(ServerManager, [
|
|
48
|
+
SocketEmitter.apply(ServerManager, [route, WebSocket]);
|
|
51
49
|
|
|
52
|
-
|
|
53
|
-
...options,
|
|
54
|
-
server: httpServer,
|
|
55
|
-
WebSocket,
|
|
56
|
-
serviceUrl,
|
|
57
|
-
route,
|
|
58
|
-
port,
|
|
59
|
-
ssl,
|
|
60
|
-
});
|
|
61
|
-
const wsProtocol = ssl ? "wss" : "ws";
|
|
50
|
+
const wsProtocol = protocol === "https" ? "wss" : "ws";
|
|
62
51
|
|
|
63
52
|
const connectionData = {
|
|
64
53
|
modules,
|
|
@@ -66,10 +55,21 @@ module.exports = function createServerManager(customServer) {
|
|
|
66
55
|
route: `/${route}`,
|
|
67
56
|
port,
|
|
68
57
|
serviceUrl,
|
|
69
|
-
|
|
58
|
+
socketPath,
|
|
59
|
+
namespace: `${wsProtocol}://${host}:${port}/${route}`,
|
|
70
60
|
SystemLynxService: true,
|
|
71
61
|
};
|
|
72
62
|
|
|
63
|
+
Object.assign(serverConfigurations, {
|
|
64
|
+
...options,
|
|
65
|
+
server: httpServer,
|
|
66
|
+
WebSocket,
|
|
67
|
+
serviceUrl,
|
|
68
|
+
route,
|
|
69
|
+
port,
|
|
70
|
+
protocol,
|
|
71
|
+
});
|
|
72
|
+
|
|
73
73
|
server.get(`/${route}`, (req, res) => {
|
|
74
74
|
res.json({ ...connectionData, modules });
|
|
75
75
|
});
|
|
@@ -91,14 +91,13 @@ module.exports = function createServerManager(customServer) {
|
|
|
91
91
|
host,
|
|
92
92
|
route,
|
|
93
93
|
serviceUrl,
|
|
94
|
-
staticRouting,
|
|
95
94
|
useService,
|
|
96
95
|
useREST,
|
|
97
96
|
port,
|
|
98
97
|
beforeware,
|
|
99
98
|
afterware,
|
|
100
99
|
WebSocket,
|
|
101
|
-
|
|
100
|
+
protocol,
|
|
102
101
|
} = serverConfigurations;
|
|
103
102
|
|
|
104
103
|
if (!serviceUrl) return moduleQueue.push({ name, Module, reserved_methods });
|
|
@@ -112,19 +111,18 @@ module.exports = function createServerManager(customServer) {
|
|
|
112
111
|
...reserved_methods,
|
|
113
112
|
];
|
|
114
113
|
const methods = parseMethods(Module, exclude_methods, useREST);
|
|
115
|
-
const
|
|
116
|
-
|
|
117
|
-
SocketEmitter.apply(Module, [namespace, WebSocket]);
|
|
114
|
+
const path = `${route}/${name}`;
|
|
118
115
|
|
|
119
116
|
const before_validators = [...beforeware.$all, ...(beforeware[name] || [])];
|
|
120
117
|
const after_validators = [...afterware.$all, ...(afterware[name] || [])];
|
|
121
118
|
|
|
122
119
|
if (useService) {
|
|
123
|
-
|
|
124
|
-
|
|
120
|
+
SocketEmitter.apply(Module, [path, WebSocket]);
|
|
121
|
+
|
|
122
|
+
const wsProtocol = protocol === "https" ? "wss" : "ws";
|
|
125
123
|
|
|
126
124
|
modules.push({
|
|
127
|
-
namespace: `${wsProtocol}://${host}:${port}/${
|
|
125
|
+
namespace: `${wsProtocol}://${host}:${port}/${path}`,
|
|
128
126
|
route: `/${path}`,
|
|
129
127
|
name,
|
|
130
128
|
methods,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
module.exports = function createWebSocket(
|
|
1
|
+
module.exports = function createWebSocket(path) {
|
|
2
2
|
const express = require("express");
|
|
3
|
-
const SocketServer = require("http").Server(
|
|
4
|
-
const WebSocket = require("socket.io")(SocketServer);
|
|
3
|
+
const SocketServer = require("http").Server(express());
|
|
4
|
+
const WebSocket = require("socket.io")(SocketServer, { path });
|
|
5
5
|
|
|
6
6
|
return { WebSocket, SocketServer };
|
|
7
7
|
};
|
|
@@ -40,6 +40,7 @@ describe("ServerManager", () => {
|
|
|
40
40
|
.that.has.all.keys(
|
|
41
41
|
"SystemLynxService",
|
|
42
42
|
"serviceUrl",
|
|
43
|
+
"socketPath",
|
|
43
44
|
"route",
|
|
44
45
|
"host",
|
|
45
46
|
"port",
|
|
@@ -71,6 +72,7 @@ describe("ServerManager", () => {
|
|
|
71
72
|
.that.has.all.keys(
|
|
72
73
|
"SystemLynxService",
|
|
73
74
|
"serviceUrl",
|
|
75
|
+
"socketPath",
|
|
74
76
|
"route",
|
|
75
77
|
"host",
|
|
76
78
|
"port",
|
|
@@ -108,6 +110,7 @@ describe("ServerManager", () => {
|
|
|
108
110
|
.that.has.all.keys(
|
|
109
111
|
"SystemLynxService",
|
|
110
112
|
"serviceUrl",
|
|
113
|
+
"socketPath",
|
|
111
114
|
"route",
|
|
112
115
|
"host",
|
|
113
116
|
"port",
|
|
@@ -45,7 +45,8 @@ describe("Service factory", () => {
|
|
|
45
45
|
"modules",
|
|
46
46
|
"route",
|
|
47
47
|
"namespace",
|
|
48
|
-
"serviceUrl"
|
|
48
|
+
"serviceUrl",
|
|
49
|
+
"socketPath"
|
|
49
50
|
)
|
|
50
51
|
.that.has.property("modules")
|
|
51
52
|
.that.is.an("array").that.is.empty;
|
|
@@ -94,7 +95,8 @@ describe("Service.module(constructor)", () => {
|
|
|
94
95
|
"modules",
|
|
95
96
|
"route",
|
|
96
97
|
"namespace",
|
|
97
|
-
"serviceUrl"
|
|
98
|
+
"serviceUrl",
|
|
99
|
+
"socketPath"
|
|
98
100
|
)
|
|
99
101
|
.that.has.property("modules")
|
|
100
102
|
.that.is.an("array");
|
|
@@ -232,7 +234,8 @@ describe("Service.module(object)", () => {
|
|
|
232
234
|
"modules",
|
|
233
235
|
"route",
|
|
234
236
|
"namespace",
|
|
235
|
-
"serviceUrl"
|
|
237
|
+
"serviceUrl",
|
|
238
|
+
"socketPath"
|
|
236
239
|
)
|
|
237
240
|
.that.has.property("modules")
|
|
238
241
|
.that.is.an("array");
|