systemlynx 1.1.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/API.md +142 -0
- package/LICENSE +21 -0
- package/README.md +180 -0
- package/index.js +40 -0
- package/index.test.js +121 -0
- package/package.json +41 -0
- package/systemlynx/App/App.js +76 -0
- package/systemlynx/App/components/SystemObject.js +9 -0
- package/systemlynx/App/components/initializeApp.js +33 -0
- package/systemlynx/App/components/loadModules.js +14 -0
- package/systemlynx/App/components/loadServices.js +28 -0
- package/systemlynx/App/tests/App.test.js +354 -0
- package/systemlynx/Client/Client.js +42 -0
- package/systemlynx/Client/components/ClientModule.js +28 -0
- package/systemlynx/Client/components/ServiceRequestHandler.js +62 -0
- package/systemlynx/Client/components/SocketDispatcher.js +20 -0
- package/systemlynx/Client/components/loadConnectionData.js +18 -0
- package/systemlynx/Client/tests/Client.test.js +208 -0
- package/systemlynx/Client/tests/SocketDispatcher.test.js +54 -0
- package/systemlynx/Dispatcher/Dispatcher.js +21 -0
- package/systemlynx/Dispatcher/Dispatcher.test.js +21 -0
- package/systemlynx/HttpClient/HttpClient.js +44 -0
- package/systemlynx/HttpClient/HttpClient.test.js +143 -0
- package/systemlynx/HttpClient/test.file.json +1 -0
- package/systemlynx/HttpClient/test.server.js +34 -0
- package/systemlynx/LoadBalancer/LoadBalancer.js +7 -0
- package/systemlynx/LoadBalancer/components/CloneManager.js +49 -0
- package/systemlynx/LoadBalancer/components/Router.js +37 -0
- package/systemlynx/LoadBalancer/tests/LoadBalancer.test.js +142 -0
- package/systemlynx/ServerManager/ServerManager.js +113 -0
- package/systemlynx/ServerManager/components/Router.js +89 -0
- package/systemlynx/ServerManager/components/Server.js +52 -0
- package/systemlynx/ServerManager/components/SocketEmitter.js +19 -0
- package/systemlynx/ServerManager/components/WebSocketServer.js +7 -0
- package/systemlynx/ServerManager/components/parseMethods.js +19 -0
- package/systemlynx/ServerManager/tests/ServerManager.test.js +197 -0
- package/systemlynx/ServerManager/tests/SocketEmitter.test.js +29 -0
- package/systemlynx/Service/Service.js +28 -0
- package/systemlynx/Service/Service.test.js +176 -0
- package/temp/.gitignore +4 -0
- package/utils/ProcessChecker.js +18 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
const Client = require("../../Client/Client")();
|
|
2
|
+
module.exports = ({ Services, App }) => {
|
|
3
|
+
return Promise.all(
|
|
4
|
+
Services.map(serviceData => {
|
|
5
|
+
const { url, limit, wait, name, onLoad } = serviceData;
|
|
6
|
+
return new Promise(resolve => {
|
|
7
|
+
Client.loadService(url, { limit, wait })
|
|
8
|
+
.then(service => {
|
|
9
|
+
serviceData.client = service;
|
|
10
|
+
if (typeof onLoad === "function") {
|
|
11
|
+
onLoad(serviceData.client);
|
|
12
|
+
serviceData.client.on("reconnect", onLoad);
|
|
13
|
+
}
|
|
14
|
+
App.emit("service_loaded", serviceData.client).emit(
|
|
15
|
+
`service_loaded:${name}`,
|
|
16
|
+
serviceData.client
|
|
17
|
+
);
|
|
18
|
+
resolve();
|
|
19
|
+
})
|
|
20
|
+
.catch(err => {
|
|
21
|
+
console.warn(err);
|
|
22
|
+
App.emit("failed_connection", { err, ...serviceData });
|
|
23
|
+
resolve();
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
})
|
|
27
|
+
);
|
|
28
|
+
};
|
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
const { expect } = require("chai");
|
|
2
|
+
const AppFactory = require("../App");
|
|
3
|
+
const HttpClient = require("../../HttpClient/HttpClient")();
|
|
4
|
+
const ServiceFactory = require("../../Service/Service");
|
|
5
|
+
|
|
6
|
+
describe("App Factory", () => {
|
|
7
|
+
it("should return a SystemLynx App", () => {
|
|
8
|
+
const App = AppFactory();
|
|
9
|
+
|
|
10
|
+
expect(App)
|
|
11
|
+
.to.be.an("object")
|
|
12
|
+
.that.has.all.keys(
|
|
13
|
+
"module",
|
|
14
|
+
"ServerModule",
|
|
15
|
+
"on",
|
|
16
|
+
"emit",
|
|
17
|
+
"startService",
|
|
18
|
+
"loadService",
|
|
19
|
+
"onLoad",
|
|
20
|
+
"config"
|
|
21
|
+
)
|
|
22
|
+
.that.respondsTo("module")
|
|
23
|
+
.that.respondsTo("ServerModule")
|
|
24
|
+
.that.respondsTo("on")
|
|
25
|
+
.that.respondsTo("emit")
|
|
26
|
+
.that.respondsTo("startService")
|
|
27
|
+
.that.respondsTo("loadService")
|
|
28
|
+
.that.respondsTo("onLoad")
|
|
29
|
+
.that.respondsTo("config");
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
describe("App: Loading Services", () => {
|
|
33
|
+
it("should be able to use App.loadService(str_url) to load as hosted Service", async () => {
|
|
34
|
+
const Service = ServiceFactory();
|
|
35
|
+
const route = "test-service";
|
|
36
|
+
const port = "8503";
|
|
37
|
+
|
|
38
|
+
Service.ServerModule("mod", function () {
|
|
39
|
+
this.test = () => {};
|
|
40
|
+
this.test2 = () => {};
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
await Service.startService({ route, port });
|
|
44
|
+
|
|
45
|
+
await new Promise((resolve) => {
|
|
46
|
+
const App = AppFactory();
|
|
47
|
+
App.loadService("test", `http://localhost:${port}/${route}`).on(
|
|
48
|
+
"init_complete",
|
|
49
|
+
(system) => {
|
|
50
|
+
expect(system.Services[0]).to.be.an("object");
|
|
51
|
+
|
|
52
|
+
expect(system.Services[0].client)
|
|
53
|
+
.to.be.an("object")
|
|
54
|
+
.that.has.all.keys("emit", "on", "resetConnection", "disconnect", "mod")
|
|
55
|
+
.that.respondsTo("emit")
|
|
56
|
+
.that.respondsTo("on")
|
|
57
|
+
.that.respondsTo("resetConnection")
|
|
58
|
+
.that.respondsTo("disconnect");
|
|
59
|
+
resolve();
|
|
60
|
+
}
|
|
61
|
+
);
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it("should be able to use App.loadService(...).onLoad(handler) to fire a callback when the Service connects", async () => {
|
|
66
|
+
const Service = ServiceFactory();
|
|
67
|
+
const route = "test-service";
|
|
68
|
+
const port = "8422";
|
|
69
|
+
const url = `http://localhost:${port}/${route}`;
|
|
70
|
+
|
|
71
|
+
Service.ServerModule("mod", function () {
|
|
72
|
+
this.test = () => {};
|
|
73
|
+
this.test2 = () => {};
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
await Service.startService({ route, port });
|
|
77
|
+
|
|
78
|
+
await new Promise((resolve) => {
|
|
79
|
+
const App = AppFactory();
|
|
80
|
+
App.loadService("test", url).onLoad((test) => {
|
|
81
|
+
expect(test)
|
|
82
|
+
.to.be.an("object")
|
|
83
|
+
.that.has.all.keys("emit", "on", "resetConnection", "disconnect", "mod")
|
|
84
|
+
.that.respondsTo("emit")
|
|
85
|
+
.that.respondsTo("on")
|
|
86
|
+
.that.respondsTo("resetConnection")
|
|
87
|
+
.that.respondsTo("disconnect");
|
|
88
|
+
resolve();
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
it('should use App.on("service_loaded[:name]", callback) to fire when a Service has loaded', async () => {
|
|
94
|
+
const Service = ServiceFactory();
|
|
95
|
+
const route = "test-service";
|
|
96
|
+
const port = "8423";
|
|
97
|
+
const url = `http://localhost:${port}/${route}`;
|
|
98
|
+
Service.ServerModule("mod", function () {
|
|
99
|
+
this.test = () => {};
|
|
100
|
+
this.test2 = () => {};
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
await Service.startService({ route, port });
|
|
104
|
+
|
|
105
|
+
await new Promise((resolve) => {
|
|
106
|
+
const App = AppFactory();
|
|
107
|
+
App.loadService("test", url)
|
|
108
|
+
.on("service_loaded", (test) => {
|
|
109
|
+
expect(test)
|
|
110
|
+
.to.be.an("object")
|
|
111
|
+
.that.has.all.keys("emit", "on", "resetConnection", "disconnect", "mod")
|
|
112
|
+
.that.respondsTo("emit")
|
|
113
|
+
.that.respondsTo("on")
|
|
114
|
+
.that.respondsTo("resetConnection");
|
|
115
|
+
})
|
|
116
|
+
.on("service_loaded:test", (test) => {
|
|
117
|
+
expect(test)
|
|
118
|
+
.to.be.an("object")
|
|
119
|
+
.that.has.all.keys("emit", "on", "resetConnection", "disconnect", "mod")
|
|
120
|
+
.that.respondsTo("emit")
|
|
121
|
+
.that.respondsTo("on")
|
|
122
|
+
.that.respondsTo("resetConnection");
|
|
123
|
+
resolve();
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
it("should be accessible to SystemObjects via the module.useService method", async () => {
|
|
129
|
+
const Service = ServiceFactory();
|
|
130
|
+
const route = "test-service";
|
|
131
|
+
const port = "8442";
|
|
132
|
+
const url = `http://localhost:${port}/${route}`;
|
|
133
|
+
|
|
134
|
+
Service.ServerModule("mod", function () {
|
|
135
|
+
this.test = () => {};
|
|
136
|
+
this.test2 = () => {};
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
await Service.startService({ route, port });
|
|
140
|
+
|
|
141
|
+
await new Promise((resolve) => {
|
|
142
|
+
const App = AppFactory();
|
|
143
|
+
App.loadService("test", url)
|
|
144
|
+
.module("module_name", function () {
|
|
145
|
+
const test = this.useService("test");
|
|
146
|
+
expect(test)
|
|
147
|
+
.to.be.an("object")
|
|
148
|
+
.that.has.all.keys("emit", "on", "resetConnection", "disconnect", "mod")
|
|
149
|
+
.that.respondsTo("emit")
|
|
150
|
+
.that.respondsTo("on")
|
|
151
|
+
.that.respondsTo("resetConnection");
|
|
152
|
+
resolve();
|
|
153
|
+
})
|
|
154
|
+
.on("init_complete", resolve);
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
describe("App SystemObjects: Initializing Modules, ServerModules and configurations", () => {
|
|
160
|
+
it("should be able to use App.module to initialize a module", async () => {
|
|
161
|
+
const App = AppFactory();
|
|
162
|
+
return new Promise((resolve) =>
|
|
163
|
+
App.module("test", function () {
|
|
164
|
+
expect(this)
|
|
165
|
+
.to.be.an("object")
|
|
166
|
+
.that.has.all.keys("useModule", "useService", "useConfig", "on", "emit")
|
|
167
|
+
.that.respondsTo("useModule")
|
|
168
|
+
.that.respondsTo("useService")
|
|
169
|
+
.that.respondsTo("useConfig")
|
|
170
|
+
.that.respondsTo("on")
|
|
171
|
+
.that.respondsTo("emit");
|
|
172
|
+
}).module("test2", function () {
|
|
173
|
+
expect(this)
|
|
174
|
+
.to.be.an("object")
|
|
175
|
+
.that.has.all.keys("useModule", "useService", "useConfig", "on", "emit")
|
|
176
|
+
.that.respondsTo("useModule")
|
|
177
|
+
.that.respondsTo("useService")
|
|
178
|
+
.that.respondsTo("useConfig")
|
|
179
|
+
.that.respondsTo("on")
|
|
180
|
+
.that.respondsTo("emit");
|
|
181
|
+
resolve();
|
|
182
|
+
})
|
|
183
|
+
);
|
|
184
|
+
});
|
|
185
|
+
it("should be able to use App.startService to start as Service", async () => {
|
|
186
|
+
const App = AppFactory();
|
|
187
|
+
const route = "test-service";
|
|
188
|
+
const port = "8493";
|
|
189
|
+
const url = `http://localhost:${port}/${route}`;
|
|
190
|
+
|
|
191
|
+
await new Promise((resolve) =>
|
|
192
|
+
App.startService({ route, port }).on("init_complete", resolve)
|
|
193
|
+
);
|
|
194
|
+
const connData = await HttpClient.request({ url });
|
|
195
|
+
|
|
196
|
+
expect(connData)
|
|
197
|
+
.to.be.an("Object")
|
|
198
|
+
.that.has.all.keys(
|
|
199
|
+
"SystemLynxService",
|
|
200
|
+
"host",
|
|
201
|
+
"port",
|
|
202
|
+
"modules",
|
|
203
|
+
"route",
|
|
204
|
+
"namespace",
|
|
205
|
+
"serviceUrl"
|
|
206
|
+
)
|
|
207
|
+
.that.has.property("modules")
|
|
208
|
+
.that.is.an("array").that.is.empty;
|
|
209
|
+
expect(connData.serviceUrl).to.equal(url);
|
|
210
|
+
});
|
|
211
|
+
it("should be able to use App.ServerModule to add a hosted ServerModule to the Service", async () => {
|
|
212
|
+
const App = AppFactory();
|
|
213
|
+
const route = "test-service";
|
|
214
|
+
const port = "8494";
|
|
215
|
+
const url = `http://localhost:${port}/${route}`;
|
|
216
|
+
await new Promise((resolve) =>
|
|
217
|
+
App.startService({ route, port })
|
|
218
|
+
.ServerModule("mod", function () {
|
|
219
|
+
this.test = () => {};
|
|
220
|
+
this.test2 = () => {};
|
|
221
|
+
})
|
|
222
|
+
.ServerModule("mod2", function () {
|
|
223
|
+
this.test = () => {};
|
|
224
|
+
this.test2 = () => {};
|
|
225
|
+
})
|
|
226
|
+
.on("init_complete", resolve)
|
|
227
|
+
);
|
|
228
|
+
|
|
229
|
+
const connData = await HttpClient.request({ url });
|
|
230
|
+
|
|
231
|
+
expect(connData)
|
|
232
|
+
.to.be.an("Object")
|
|
233
|
+
.that.has.all.keys(
|
|
234
|
+
"SystemLynxService",
|
|
235
|
+
"host",
|
|
236
|
+
"port",
|
|
237
|
+
"modules",
|
|
238
|
+
"route",
|
|
239
|
+
"namespace",
|
|
240
|
+
"serviceUrl"
|
|
241
|
+
)
|
|
242
|
+
.that.has.property("modules")
|
|
243
|
+
.that.is.an("array");
|
|
244
|
+
expect(connData.modules).to.have.a.lengthOf(2);
|
|
245
|
+
expect(connData.modules[0])
|
|
246
|
+
.to.be.an("Object")
|
|
247
|
+
.that.has.all.keys("namespace", "route", "name", "methods")
|
|
248
|
+
.that.has.property("methods")
|
|
249
|
+
.that.is.an("array");
|
|
250
|
+
expect(connData.modules[0].methods, [
|
|
251
|
+
{ method: "PUT", name: "test" },
|
|
252
|
+
{ method: "PUT", name: "test2" },
|
|
253
|
+
]);
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
it('should be able to use App.on("init_complete", callback) fire a callback when App initialization is complete', async () => {
|
|
257
|
+
const App = AppFactory();
|
|
258
|
+
|
|
259
|
+
App.ServerModule("mod", function () {
|
|
260
|
+
this.test = () => {};
|
|
261
|
+
this.test2 = () => {};
|
|
262
|
+
}).module("mod", function () {
|
|
263
|
+
this.test = () => {};
|
|
264
|
+
this.test2 = () => {};
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
await new Promise((resolve) =>
|
|
268
|
+
App.on("init_complete", (system) => {
|
|
269
|
+
expect(system)
|
|
270
|
+
.to.be.an("object")
|
|
271
|
+
.that.has.all.keys(
|
|
272
|
+
"Services",
|
|
273
|
+
"Service",
|
|
274
|
+
"Modules",
|
|
275
|
+
"ServerModules",
|
|
276
|
+
"configurations",
|
|
277
|
+
"App",
|
|
278
|
+
"routing",
|
|
279
|
+
"useService",
|
|
280
|
+
"useModule",
|
|
281
|
+
"useConfig"
|
|
282
|
+
);
|
|
283
|
+
resolve();
|
|
284
|
+
})
|
|
285
|
+
);
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
it("should be able to use App.config(constructor) to construct a configuartion module", async () => {
|
|
289
|
+
const App = AppFactory();
|
|
290
|
+
|
|
291
|
+
App.ServerModule("mod", function () {
|
|
292
|
+
this.test = () => {};
|
|
293
|
+
this.test2 = () => {};
|
|
294
|
+
})
|
|
295
|
+
.module("mod", function () {
|
|
296
|
+
this.test = () => {};
|
|
297
|
+
this.test2 = () => {};
|
|
298
|
+
})
|
|
299
|
+
.config(function (next) {
|
|
300
|
+
this.test = () => {};
|
|
301
|
+
this.test2 = () => {};
|
|
302
|
+
next();
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
await new Promise((resolve) =>
|
|
306
|
+
App.on("init_complete", ({ configurations }) => {
|
|
307
|
+
expect(configurations)
|
|
308
|
+
.to.be.an("object")
|
|
309
|
+
.that.has.all.keys("module", "__constructor")
|
|
310
|
+
.that.has.property("module")
|
|
311
|
+
.that.is.an("object")
|
|
312
|
+
.that.has.all.keys("useService", "useModule", "useConfig", "test", "test2");
|
|
313
|
+
|
|
314
|
+
resolve();
|
|
315
|
+
})
|
|
316
|
+
);
|
|
317
|
+
});
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
describe("SystemObjects", () => {
|
|
321
|
+
it("should be able to use this.useModule and this.useService within modules and ServerModule", () => {
|
|
322
|
+
const App = AppFactory();
|
|
323
|
+
App.module("mod1", function () {
|
|
324
|
+
expect(this)
|
|
325
|
+
.to.be.an("object")
|
|
326
|
+
.that.respondsTo("useService")
|
|
327
|
+
.that.respondsTo("useModule")
|
|
328
|
+
.that.respondsTo("useConfig");
|
|
329
|
+
|
|
330
|
+
this.testPassed = true;
|
|
331
|
+
})
|
|
332
|
+
.module("mod2", function () {
|
|
333
|
+
expect(this)
|
|
334
|
+
.to.be.an("object")
|
|
335
|
+
.that.respondsTo("useService")
|
|
336
|
+
.that.respondsTo("useModule")
|
|
337
|
+
.that.respondsTo("useConfig");
|
|
338
|
+
const mod1 = this.useModule("mod1");
|
|
339
|
+
const config = this.useConfig();
|
|
340
|
+
expect(mod1.testPassed).to.equal(true);
|
|
341
|
+
expect(config.configPassed).to.equal(true);
|
|
342
|
+
})
|
|
343
|
+
.config(function (next) {
|
|
344
|
+
expect(this)
|
|
345
|
+
.to.be.an("object")
|
|
346
|
+
.that.respondsTo("useService")
|
|
347
|
+
.that.respondsTo("useModule")
|
|
348
|
+
.that.respondsTo("useConfig");
|
|
349
|
+
this.configPassed = true;
|
|
350
|
+
next();
|
|
351
|
+
});
|
|
352
|
+
return new Promise((resolve) => App.on("init_complete", () => resolve()));
|
|
353
|
+
});
|
|
354
|
+
});
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const loadConnectionData = require("./components/loadConnectionData");
|
|
3
|
+
const SocketDispatcher = require("./components/SocketDispatcher");
|
|
4
|
+
const ClientModule = require("./components/ClientModule");
|
|
5
|
+
|
|
6
|
+
module.exports = function SystemLynxClient() {
|
|
7
|
+
const Client = {};
|
|
8
|
+
Client.loadedServices = {};
|
|
9
|
+
|
|
10
|
+
Client.loadService = async (url, options = {}) => {
|
|
11
|
+
if (Client.loadedServices[url] && !options.forceReload)
|
|
12
|
+
return Client.loadedServices[url];
|
|
13
|
+
|
|
14
|
+
const connData = await loadConnectionData(url, options);
|
|
15
|
+
const Service = SocketDispatcher(connData.namespace);
|
|
16
|
+
Client.loadedServices[url] = Service;
|
|
17
|
+
if (options.name) Client[options.name] = Service;
|
|
18
|
+
|
|
19
|
+
Service.resetConnection = async (cb) => {
|
|
20
|
+
const { modules, host, port, namespace } = await loadConnectionData(url, options);
|
|
21
|
+
|
|
22
|
+
SocketDispatcher.apply(Service, [namespace]);
|
|
23
|
+
|
|
24
|
+
modules.forEach(({ namespace, route, name }) =>
|
|
25
|
+
Service[name].__setConnection(host, port, route, namespace)
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
if (typeof cb === "function") cb();
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
connData.modules.forEach(
|
|
32
|
+
(mod) => (Service[mod.name] = ClientModule(mod, connData, Service.resetConnection))
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
Service.on("disconnect", Service.resetConnection);
|
|
36
|
+
|
|
37
|
+
await new Promise((resolve) => Service.on("connect", resolve));
|
|
38
|
+
return Service;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
return Client;
|
|
42
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const ServiceRequestHandler = require("./ServiceRequestHandler");
|
|
3
|
+
const SocketDispatcher = require("./SocketDispatcher");
|
|
4
|
+
module.exports = function SystemLynxClientModule(
|
|
5
|
+
{ methods, namespace, route },
|
|
6
|
+
{ port, host },
|
|
7
|
+
resetConnection
|
|
8
|
+
) {
|
|
9
|
+
const events = {};
|
|
10
|
+
const ClientModule = this || {};
|
|
11
|
+
|
|
12
|
+
ClientModule.__setConnection = (host, port, route, namespace) => {
|
|
13
|
+
ClientModule.__connectionData = () => ({ route, host, port });
|
|
14
|
+
SocketDispatcher.apply(ClientModule, [namespace, events]);
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
ClientModule.__setConnection(host, port, route, namespace);
|
|
18
|
+
|
|
19
|
+
methods.forEach(({ method, fn }) => {
|
|
20
|
+
ClientModule[fn] = ServiceRequestHandler.apply(ClientModule, [
|
|
21
|
+
method,
|
|
22
|
+
fn,
|
|
23
|
+
resetConnection,
|
|
24
|
+
]);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
return ClientModule;
|
|
28
|
+
};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const HttpClient = require("../../HttpClient/HttpClient")();
|
|
3
|
+
const isObject = (value) =>
|
|
4
|
+
typeof value === "object" ? (!value ? false : !Array.isArray(value)) : false;
|
|
5
|
+
|
|
6
|
+
const makeQuery = (data) =>
|
|
7
|
+
Object.getOwnPropertyNames(data).reduce(
|
|
8
|
+
(query, name) => (query += `${name}=${data[name]}&`),
|
|
9
|
+
"?"
|
|
10
|
+
);
|
|
11
|
+
module.exports = function ServiceRequestHandler(method, fn, resetConnection) {
|
|
12
|
+
const ClientModule = this;
|
|
13
|
+
|
|
14
|
+
return function sendRequest() {
|
|
15
|
+
const __arguments = Array.from(arguments);
|
|
16
|
+
|
|
17
|
+
const tryRequest = (cb, errCount = 0) => {
|
|
18
|
+
const { route, port, host } = ClientModule.__connectionData();
|
|
19
|
+
const singleFileURL = `http://${host}:${port}/sf${route}/${fn}`;
|
|
20
|
+
const multiFileURL = `http://${host}:${port}/mf${route}/${fn}`;
|
|
21
|
+
const defaultURL = `http://${host}:${port}${route}/${fn}`;
|
|
22
|
+
const { file, files } = __arguments[0] || {};
|
|
23
|
+
const url = file ? singleFileURL : files ? multiFileURL : defaultURL;
|
|
24
|
+
|
|
25
|
+
if (url === defaultURL)
|
|
26
|
+
HttpClient.request({
|
|
27
|
+
url: `${url}${
|
|
28
|
+
method === "get" && isObject(__arguments[0]) ? makeQuery(__arguments[0]) : ""
|
|
29
|
+
}`,
|
|
30
|
+
method,
|
|
31
|
+
body: { __arguments },
|
|
32
|
+
})
|
|
33
|
+
.then((results) => cb(null, results))
|
|
34
|
+
.catch((err) => ErrorHandler(err, errCount, cb));
|
|
35
|
+
else
|
|
36
|
+
HttpClient.upload({
|
|
37
|
+
url,
|
|
38
|
+
method,
|
|
39
|
+
formData: { ...__arguments[0], __arguments },
|
|
40
|
+
})
|
|
41
|
+
.then((results) => cb(null, results))
|
|
42
|
+
.catch((err) => ErrorHandler(err, errCount, cb));
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const ErrorHandler = (err, errCount, cb) => {
|
|
46
|
+
if (err.SystemLynxServiceError) {
|
|
47
|
+
cb(err);
|
|
48
|
+
} else if (errCount <= 3) {
|
|
49
|
+
console.log(err);
|
|
50
|
+
errCount++;
|
|
51
|
+
resetConnection(() => tryRequest(cb, errCount));
|
|
52
|
+
} else throw Error(`(SystemLynxServiceError): Invalid route:${err}`);
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
return new Promise((resolve, reject) =>
|
|
56
|
+
tryRequest((err, results) => {
|
|
57
|
+
if (err) reject(err);
|
|
58
|
+
else resolve(results.returnValue);
|
|
59
|
+
})
|
|
60
|
+
);
|
|
61
|
+
};
|
|
62
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const io = require("socket.io-client");
|
|
3
|
+
const SystemLynxDispatcher = require("../../Dispatcher/Dispatcher");
|
|
4
|
+
|
|
5
|
+
module.exports = function SocketDispatcher(namespace, events = {}) {
|
|
6
|
+
const dispatcher =
|
|
7
|
+
(this || {}).on && (this || {}).emit
|
|
8
|
+
? this
|
|
9
|
+
: SystemLynxDispatcher.apply(this, [events]);
|
|
10
|
+
const socket = io.connect(namespace);
|
|
11
|
+
socket.on("dispatch", (event) => dispatcher.emit(event.name, event.data, event));
|
|
12
|
+
socket.on("disconnect", () => {
|
|
13
|
+
socket.disconnect();
|
|
14
|
+
dispatcher.emit("disconnect");
|
|
15
|
+
});
|
|
16
|
+
socket.on("connect", () => dispatcher.emit("connect"));
|
|
17
|
+
|
|
18
|
+
dispatcher.disconnect = () => socket.disconnect();
|
|
19
|
+
return dispatcher;
|
|
20
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
const HttpClient = require("../../HttpClient/HttpClient")();
|
|
2
|
+
|
|
3
|
+
module.exports = function loadConnectionData(url, { limit = 10, wait = 150 } = {}) {
|
|
4
|
+
const errors = [];
|
|
5
|
+
|
|
6
|
+
return new Promise(function getData(resolve) {
|
|
7
|
+
HttpClient.request({ method: "GET", url }, (err, results) => {
|
|
8
|
+
if (err) {
|
|
9
|
+
errors.push(err);
|
|
10
|
+
|
|
11
|
+
if (errors.length < limit)
|
|
12
|
+
setTimeout(() => getData(resolve), errors.length * wait);
|
|
13
|
+
else
|
|
14
|
+
throw `SystemLynx loadConnectionData() Error: url:${url}, attempts:${errors.length}`;
|
|
15
|
+
} else resolve(results);
|
|
16
|
+
});
|
|
17
|
+
});
|
|
18
|
+
};
|