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.
Files changed (41) hide show
  1. package/API.md +142 -0
  2. package/LICENSE +21 -0
  3. package/README.md +180 -0
  4. package/index.js +40 -0
  5. package/index.test.js +121 -0
  6. package/package.json +41 -0
  7. package/systemlynx/App/App.js +76 -0
  8. package/systemlynx/App/components/SystemObject.js +9 -0
  9. package/systemlynx/App/components/initializeApp.js +33 -0
  10. package/systemlynx/App/components/loadModules.js +14 -0
  11. package/systemlynx/App/components/loadServices.js +28 -0
  12. package/systemlynx/App/tests/App.test.js +354 -0
  13. package/systemlynx/Client/Client.js +42 -0
  14. package/systemlynx/Client/components/ClientModule.js +28 -0
  15. package/systemlynx/Client/components/ServiceRequestHandler.js +62 -0
  16. package/systemlynx/Client/components/SocketDispatcher.js +20 -0
  17. package/systemlynx/Client/components/loadConnectionData.js +18 -0
  18. package/systemlynx/Client/tests/Client.test.js +208 -0
  19. package/systemlynx/Client/tests/SocketDispatcher.test.js +54 -0
  20. package/systemlynx/Dispatcher/Dispatcher.js +21 -0
  21. package/systemlynx/Dispatcher/Dispatcher.test.js +21 -0
  22. package/systemlynx/HttpClient/HttpClient.js +44 -0
  23. package/systemlynx/HttpClient/HttpClient.test.js +143 -0
  24. package/systemlynx/HttpClient/test.file.json +1 -0
  25. package/systemlynx/HttpClient/test.server.js +34 -0
  26. package/systemlynx/LoadBalancer/LoadBalancer.js +7 -0
  27. package/systemlynx/LoadBalancer/components/CloneManager.js +49 -0
  28. package/systemlynx/LoadBalancer/components/Router.js +37 -0
  29. package/systemlynx/LoadBalancer/tests/LoadBalancer.test.js +142 -0
  30. package/systemlynx/ServerManager/ServerManager.js +113 -0
  31. package/systemlynx/ServerManager/components/Router.js +89 -0
  32. package/systemlynx/ServerManager/components/Server.js +52 -0
  33. package/systemlynx/ServerManager/components/SocketEmitter.js +19 -0
  34. package/systemlynx/ServerManager/components/WebSocketServer.js +7 -0
  35. package/systemlynx/ServerManager/components/parseMethods.js +19 -0
  36. package/systemlynx/ServerManager/tests/ServerManager.test.js +197 -0
  37. package/systemlynx/ServerManager/tests/SocketEmitter.test.js +29 -0
  38. package/systemlynx/Service/Service.js +28 -0
  39. package/systemlynx/Service/Service.test.js +176 -0
  40. package/temp/.gitignore +4 -0
  41. package/utils/ProcessChecker.js +18 -0
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ const ServerManagerFactory = require("../ServerManager/ServerManager");
3
+ const Dispatcher = require("../Dispatcher/Dispatcher");
4
+
5
+ module.exports = function ServiceFactory({ defaultModule = {} } = {}) {
6
+ const ServerManager = ServerManagerFactory();
7
+ const { startService, Server, WebSocket } = ServerManager;
8
+ const Service = { startService, Server, WebSocket, defaultModule };
9
+
10
+ Service.ServerModule = function (name, constructor, reserved_methods = []) {
11
+ if (typeof constructor === "object" && constructor instanceof Object) {
12
+ ServerManager.addModule(name, constructor, reserved_methods);
13
+ return constructor;
14
+ }
15
+
16
+ if (typeof constructor === "function") {
17
+ if (constructor.constructor.name === "AsyncFunction")
18
+ throw `(ServerModule Error): ServerModule(name, constructor) function requires a non-async function as the constructor`;
19
+
20
+ const ServerModule = Dispatcher.apply({ ...Service.defaultModule });
21
+ const exclude_methods = [...reserved_methods, ...Object.getOwnPropertyNames(ServerModule)];
22
+ constructor.apply(ServerModule, [ServerManager.Server(), ServerManager.WebSocket()]);
23
+ ServerManager.addModule(name, ServerModule, exclude_methods);
24
+ return ServerModule;
25
+ }
26
+ };
27
+ return Service;
28
+ };
@@ -0,0 +1,176 @@
1
+ const { expect } = require("chai");
2
+ const request = require("request");
3
+ const ServiceFactory = require("./Service");
4
+
5
+ describe("SystemLynxService", () => {
6
+ it("should return a new instance of a Service", () => {
7
+ const Service = ServiceFactory();
8
+ expect(Service)
9
+ .to.be.an("object")
10
+ .that.has.all.keys(
11
+ "startService",
12
+ "ServerModule",
13
+ "Server",
14
+ "WebSocket",
15
+ "defaultModule"
16
+ )
17
+ .that.respondsTo("startService")
18
+ .that.respondsTo("ServerModule")
19
+ .that.respondsTo("Server")
20
+ .that.respondsTo("WebSocket");
21
+ });
22
+ });
23
+
24
+ describe("Service factory", () => {
25
+ it("should be able to use Service.startService to initiate a ServerManager instance that hosts the Service Connection Data", async () => {
26
+ const Service = ServiceFactory();
27
+ const route = "/testService";
28
+ const port = 5500;
29
+ const url = `http://localhost:${port}${route}`;
30
+
31
+ await Service.startService({ route, port });
32
+ const results = await new Promise((resolve) => {
33
+ request({ url, json: true }, (err, res, body) => {
34
+ resolve(body);
35
+ });
36
+ });
37
+
38
+ expect(results)
39
+ .to.be.an("Object")
40
+ .that.has.all.keys(
41
+ "SystemLynxService",
42
+ "host",
43
+ "port",
44
+ "modules",
45
+ "route",
46
+ "namespace",
47
+ "serviceUrl"
48
+ )
49
+ .that.has.property("modules")
50
+ .that.is.an("array").that.is.empty;
51
+ });
52
+
53
+ it("should throw an Error if the first parameter (the constructor function) is not a normal function or object", () => {});
54
+ it("should throw an Error if Service.startService(options) is called twice", () => {});
55
+ });
56
+
57
+ describe("Service.ServerModule(constructor)", () => {
58
+ const Service = ServiceFactory();
59
+ const port = 6542;
60
+ const route = "test/service";
61
+ const url = `http://localhost:${port}/${route}`;
62
+
63
+ it("should be able to return a Service instance constructed using the 'this' value in the constructor function", () => {
64
+ const mod = Service.ServerModule("mod", function () {
65
+ this.test = () => {};
66
+ this.test2 = () => {};
67
+ });
68
+
69
+ expect(mod)
70
+ .to.be.an("Object")
71
+ .that.has.all.keys("on", "emit", "test", "test2")
72
+ .that.respondsTo("on")
73
+ .that.respondsTo("emit")
74
+ .that.respondsTo("test")
75
+ .that.respondsTo("test2");
76
+ });
77
+ it("should 'Serve' Service connection data created using the 'this' value of the constructor function", async () => {
78
+ await Service.startService({ route, port });
79
+
80
+ const results = await new Promise((resolve) =>
81
+ request({ url, json: true }, (err, res, body) => resolve(body))
82
+ );
83
+
84
+ expect(results)
85
+ .to.be.an("Object")
86
+ .that.has.all.keys(
87
+ "SystemLynxService",
88
+ "host",
89
+ "port",
90
+ "modules",
91
+ "route",
92
+ "namespace",
93
+ "serviceUrl"
94
+ )
95
+ .that.has.property("modules")
96
+ .that.is.an("array");
97
+ expect(results.modules[0])
98
+ .to.be.an("Object")
99
+ .that.has.all.keys("namespace", "route", "name", "methods")
100
+ .that.has.property("methods")
101
+ .that.is.an("Array");
102
+ expect(results.modules[0].methods, [
103
+ { method: "PUT", name: "test" },
104
+ { method: "PUT", name: "test2" },
105
+ ]);
106
+ expect(results.modules[0].name, "mod");
107
+ expect(results.modules[0].route).to.be.a("String");
108
+ expect(results.modules[0].namespace).to.match(
109
+ new RegExp("https?://localhost:\\d+/.+")
110
+ );
111
+ expect(results.SystemLynxServerService, {
112
+ serviceUrl: "localhost:6542/test/service",
113
+ });
114
+ expect(results.host, "localhost");
115
+ expect(results.port, port);
116
+ });
117
+ });
118
+
119
+ describe("Service.ServerModule(object)", () => {
120
+ const Service = ServiceFactory();
121
+ const port = 6543;
122
+ const route = "test/service2";
123
+ const url = `http://localhost:${port}/${route}`;
124
+ it("should be able to return a Service instance created using an object as the constructor", () => {
125
+ const mod = Service.ServerModule("mod", {
126
+ action1: () => {},
127
+ action2: () => {},
128
+ });
129
+
130
+ expect(mod)
131
+ .to.be.an("Object")
132
+ .that.has.all.keys("action1", "action2")
133
+ .that.respondsTo("action1")
134
+ .that.respondsTo("action2");
135
+ });
136
+ it("should 'Serve' Service connection data created using an object as the constructor", async () => {
137
+ await Service.startService({ route, port });
138
+
139
+ const results = await new Promise((resolve) =>
140
+ request({ url, json: true }, (err, res, body) => resolve(body))
141
+ );
142
+
143
+ expect(results)
144
+ .to.be.an("Object")
145
+ .that.has.all.keys(
146
+ "SystemLynxService",
147
+ "host",
148
+ "port",
149
+ "modules",
150
+ "route",
151
+ "namespace",
152
+ "serviceUrl"
153
+ )
154
+ .that.has.property("modules")
155
+ .that.is.an("array");
156
+ expect(results.modules[0])
157
+ .to.be.an("Object")
158
+ .that.has.all.keys("namespace", "route", "name", "methods")
159
+ .that.has.property("methods")
160
+ .that.is.an("Array");
161
+ expect(results.modules[0].methods, [
162
+ { method: "PUT", name: "test" },
163
+ { method: "PUT", name: "test2" },
164
+ ]);
165
+ expect(results.modules[0].name, "mod");
166
+ expect(results.modules[0].route).to.be.a("String");
167
+ expect(results.modules[0].namespace).to.match(
168
+ new RegExp("https?://localhost:\\d+/.+")
169
+ );
170
+ expect(results.SystemLynxServerService, {
171
+ serviceUrl: "localhost:6542/test/service",
172
+ });
173
+ expect(results.host, "localhost");
174
+ expect(results.port, port);
175
+ });
176
+ });
@@ -0,0 +1,4 @@
1
+ # Ignore everything in this directory
2
+ *
3
+ # Except this file
4
+ !.gitignore
@@ -0,0 +1,18 @@
1
+ const isBrowser = typeof window !== "undefined" && typeof window.document !== "undefined";
2
+
3
+ const isNode =
4
+ typeof process !== "undefined" && process.versions != null && process.versions.node != null;
5
+
6
+ const isWebWorker =
7
+ typeof self === "object" &&
8
+ self.constructor &&
9
+ self.constructor.name === "DedicatedWorkerGlobalScope";
10
+
11
+ const isJsDom =
12
+ (typeof window !== "undefined" && window.name === "nodejs") ||
13
+ (typeof navigator !== "undefined" &&
14
+ (navigator.userAgent.includes("Node.js") || navigator.userAgent.includes("jsdom")));
15
+
16
+ const isDeno = typeof Deno !== "undefined" && typeof Deno.core !== "undefined";
17
+
18
+ module.exports = { isBrowser, isWebWorker, isNode, isJsDom, isDeno };