systemlynx 1.3.0 → 1.5.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 +10 -11
- package/README.md +16 -17
- package/index.js +21 -21
- package/index.test.js +17 -27
- package/package.json +1 -1
- package/systemlynx/App/App.js +10 -24
- package/systemlynx/App/components/initializeApp.js +2 -2
- package/systemlynx/App/components/loadModules.js +3 -7
- package/systemlynx/App/tests/App.test.js +23 -18
- package/systemlynx/Client/components/ServiceRequestHandler.js +1 -1
- package/systemlynx/Client/components/loadConnectionData.js +1 -1
- package/systemlynx/Client/tests/Client.test.js +7 -7
- package/systemlynx/Dispatcher/Dispatcher.js +1 -1
- package/systemlynx/LoadBalancer/LoadBalancer.js +1 -1
- package/systemlynx/LoadBalancer/tests/LoadBalancer.test.js +3 -3
- package/systemlynx/ServerManager/ServerManager.js +1 -1
- package/systemlynx/ServerManager/components/Router.js +7 -7
- package/systemlynx/ServerManager/tests/ServerManager.test.js +2 -2
- package/systemlynx/Service/Service.js +10 -7
- package/systemlynx/Service/Service.test.js +6 -12
package/API.md
CHANGED
|
@@ -10,8 +10,7 @@ Welcome to the docs! Following is a list of the objects used and created when de
|
|
|
10
10
|
- [**startService(options)**](https://github.com/Odion100/SystemLynx/blob/tasksjs2.0/API.md#appstartserviceoptions)
|
|
11
11
|
- [**loadService(name, url)**](https://github.com/Odion100/SystemLynx/blob/tasksjs2.0/API.md#apploadserviceurl)
|
|
12
12
|
- [**onLoad(callback)**](https://github.com/Odion100/SystemLynx/tasksjs2.0/API.md#apponloadcallback)
|
|
13
|
-
- [**
|
|
14
|
-
- [**Module(name, constructor)**](https://github.com/Odion100/SystemLynx/tasksjs2.0/API.md#appmodulename-constructor)
|
|
13
|
+
- [**module(name, constructor [,reserved_methods])**]()
|
|
15
14
|
- [**config(constructor)**](https://github.com/Odion100/SystemLynx/tasksjs2.0/API.md#appconfigconstructor)
|
|
16
15
|
- [**on(event, callback)**]()
|
|
17
16
|
- [**emit(event, payload)**]()
|
|
@@ -29,7 +28,7 @@ Welcome to the docs! Following is a list of the objects used and created when de
|
|
|
29
28
|
<summary><b><a href="https://github.com/Odion100/SystemLynx/tasksjs2.0/API.md#service">Service</a></b></summary>
|
|
30
29
|
|
|
31
30
|
- [**startService(options)**]()
|
|
32
|
-
- [**
|
|
31
|
+
- [**module(name, constructor [,options])**]()
|
|
33
32
|
- [**Server()**]()
|
|
34
33
|
- [**WebSocket()**]()
|
|
35
34
|
|
|
@@ -39,7 +38,7 @@ Welcome to the docs! Following is a list of the objects used and created when de
|
|
|
39
38
|
<summary><b><a href="https://github.com/Odion100/SystemLynx/tasksjs2.0/API.md#service">LoadBalancer</a></b></summary>
|
|
40
39
|
|
|
41
40
|
- [**startService(options)**]()
|
|
42
|
-
- [**
|
|
41
|
+
- [**module(name, constructor [,options])**]()
|
|
43
42
|
- [**Server()**]()
|
|
44
43
|
- [**WebSocket()**]()
|
|
45
44
|
- [**clones**]()
|
|
@@ -61,7 +60,7 @@ Welcome to the docs! Following is a list of the objects used and created when de
|
|
|
61
60
|
</details>
|
|
62
61
|
|
|
63
62
|
<details>
|
|
64
|
-
<summary><b><a href="https://github.com/Odion100/SystemLynx/tasksjs2.0/API.md">
|
|
63
|
+
<summary><b><a href="https://github.com/Odion100/SystemLynx/tasksjs2.0/API.md">module</a></b></summary>
|
|
65
64
|
|
|
66
65
|
- [**[created_method]([args...] [,callback])**]()
|
|
67
66
|
- [**on(name, constructor [,options])**]()
|
|
@@ -79,9 +78,9 @@ Welcome to the docs! Following is a list of the objects used and created when de
|
|
|
79
78
|
const { App } = require("systemlynx");
|
|
80
79
|
```
|
|
81
80
|
|
|
82
|
-
## App.
|
|
81
|
+
## App.module(name, constructor [,reserved_methods])
|
|
83
82
|
|
|
84
|
-
Use **App.
|
|
83
|
+
Use **App.module(name, constructor)** function to create or pass an object that can be loaded by a SystemLynx Client.
|
|
85
84
|
|
|
86
85
|
- **_name_** (string) - name assigned to the module or object
|
|
87
86
|
- **_constructor_** (object/function) -
|
|
@@ -92,7 +91,7 @@ Use **App.ServerModule(name, constructor)** function to create or pass an object
|
|
|
92
91
|
|
|
93
92
|
## App.onLoad(callback)
|
|
94
93
|
|
|
95
|
-
## App.
|
|
94
|
+
## App.module(name, constructor)
|
|
96
95
|
|
|
97
96
|
## App.config(constructor)
|
|
98
97
|
|
|
@@ -116,15 +115,15 @@ const { Service } = require("systemlynx");
|
|
|
116
115
|
|
|
117
116
|
The Service object has the following methods:
|
|
118
117
|
|
|
119
|
-
- **_Service.
|
|
118
|
+
- **_Service.module(name, constructor [,reserved_methods])_** - Used to create or pass an object that is hosted by the Service.
|
|
120
119
|
- **_Service.startService(options)_** - Used
|
|
121
120
|
- **_Service.Server()_** - Returns the expressJS app instance used to handle routing to the _Services_.
|
|
122
121
|
- **_Service.WebSocket()_** - Returns socket.io WebSocket instance used to emit events from the _Services_.
|
|
123
122
|
|
|
124
|
-
## Service.
|
|
123
|
+
## Service.module(name, constructor [,reserved_methods])
|
|
125
124
|
|
|
126
125
|
- **Name** - String -
|
|
127
|
-
Use the `Service.
|
|
126
|
+
Use the `Service.module(name, constructor, [,options])` method to register an object to be hosted by a _SystemLynx Service_. This will allows you to load an instance of that object onto a client application, and call any methods on that object remotely.
|
|
128
127
|
|
|
129
128
|
```javascript
|
|
130
129
|
const { Service } = require("systemlynx");
|
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
# SystemLynx   
|
|
1
|
+
# SystemLynx JS   
|
|
2
2
|
|
|
3
|
-
SystemLynx is a framework for developing modular web APIs. It's a wrapper on top of ExpressJS and Socket.io. With SystemLynx, instead of
|
|
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 export 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
|
-
SystemLynx comes with the following objects that are used for web
|
|
5
|
+
SystemLynx comes with the following objects that are used for web app development:
|
|
6
6
|
|
|
7
7
|
```javascript
|
|
8
8
|
const { App, Service, Client, LoadBalancer } = require("systemlynx");
|
|
@@ -20,9 +20,9 @@ Find the full [API Documentation](https://github.com/Odion100/SystemLynx/blob/ta
|
|
|
20
20
|
|
|
21
21
|
# Quick Start
|
|
22
22
|
|
|
23
|
-
## Service.
|
|
23
|
+
## Service.module(name, constructor [,options])
|
|
24
24
|
|
|
25
|
-
Use the `Service.
|
|
25
|
+
Use the `Service.module(name, constructor/object)` method to add an object to be hosted by a **SystemLynx Service**. This will allows you to load an instance of that object into a client application, and call any methods on that object remotely.
|
|
26
26
|
|
|
27
27
|
```javascript
|
|
28
28
|
const { Service } = require("systemlynx");
|
|
@@ -34,13 +34,12 @@ Users.add = function (data) {
|
|
|
34
34
|
return { message: "You have successfully called the Users.add method" };
|
|
35
35
|
};
|
|
36
36
|
|
|
37
|
-
Service.
|
|
37
|
+
Service.module("Users", Users);
|
|
38
38
|
```
|
|
39
39
|
|
|
40
|
-
In the code above we assigned an object to the variable `Users` and gave it an add method. The `Service.
|
|
40
|
+
In the code above we assigned an object to the variable `Users` and gave it an add method. The `Service.module(name, constructor/object)` function takes the name assigned to the object as the first argument and the object itself as the second argument.
|
|
41
41
|
|
|
42
|
-
Alternatively, you can use a constructor function instead of an object as the second argument. In the example below we create another **
|
|
43
|
-
"Orders". This time we use a constructor function as the second argument of the to **ServerModule** function. The `this` value is the initial instance of the **ServerModule** object. Every method added to the `this` value will be accessible when the object is loaded by a **SystemLynx Client**. Note: **ServerModule** methods can be synchronous or asynchronous functions.
|
|
42
|
+
Alternatively, you can use a constructor function instead of an object as the second argument. In the example below we create another **Module** called "Orders". This time we use a constructor function as the second argument of the to **Service.module** function. The `this` value is the initial instance of the **Module** object. Every method added to the `this` value will be accessible when the object is loaded by a **SystemLynx Client**. Note: **Module** methods can be synchronous or asynchronous functions.
|
|
44
43
|
|
|
45
44
|
```javascript
|
|
46
45
|
const { Service } = require("systemlynx");
|
|
@@ -52,9 +51,9 @@ Users.add = function (data) {
|
|
|
52
51
|
return { message: "You have successfully called the Users.add method" };
|
|
53
52
|
};
|
|
54
53
|
|
|
55
|
-
Service.
|
|
54
|
+
Service.module("Users", Users);
|
|
56
55
|
|
|
57
|
-
Service.
|
|
56
|
+
Service.module("Orders", function () {
|
|
58
57
|
const Orders = this;
|
|
59
58
|
|
|
60
59
|
Orders.find = async function (arg1, arg2) {
|
|
@@ -78,9 +77,9 @@ Users.add = function (data) {
|
|
|
78
77
|
return { message: "You have successfully called the Users.add method" };
|
|
79
78
|
};
|
|
80
79
|
|
|
81
|
-
Service.
|
|
80
|
+
Service.module("Users", Users);
|
|
82
81
|
|
|
83
|
-
Service.
|
|
82
|
+
Service.module("Orders", function () {
|
|
84
83
|
const Orders = this;
|
|
85
84
|
|
|
86
85
|
Orders.find = function (arg1, arg2) {
|
|
@@ -126,7 +125,7 @@ console.log(response);
|
|
|
126
125
|
|
|
127
126
|
## Sending and Receiving Websocket Events
|
|
128
127
|
|
|
129
|
-
We can also receive WebSocket events emitted from the remote objects we've loaded using the `Client.loadService(url)` function. In the example below we're using the `Users.on(event_name, callback)` method to listen for events coming from the "Users" **
|
|
128
|
+
We can also receive WebSocket events emitted from the remote objects we've loaded using the `Client.loadService(url)` function. In the example below we're using the `Users.on(event_name, callback)` method to listen for events coming from the "Users" **Module**.
|
|
130
129
|
|
|
131
130
|
```javascript
|
|
132
131
|
const { Client } = require("systemlynx");
|
|
@@ -148,7 +147,7 @@ const response = await Orders.find("hello", "world");
|
|
|
148
147
|
console.log(response);
|
|
149
148
|
```
|
|
150
149
|
|
|
151
|
-
Now let's go to our server application and call the `
|
|
150
|
+
Now let's go to our server application and call the `Users.emit(event_name, data)` method to emit a websocket event that can be received by its corresponding Clients. Below, notice that we've added `this.emit("new_user", { message:"new_user event test" })` at the end of the `Users.add` method, so the `new_user` event will be emitted every time this method is called. The `this` value of a **Module** method will always be scoped to the **Module** itself.
|
|
152
151
|
|
|
153
152
|
```javascript
|
|
154
153
|
const { Service } = require("systemlynx");
|
|
@@ -161,9 +160,9 @@ Users.add = function (data) {
|
|
|
161
160
|
this.emit("new_user", { message: "new_user event test" });
|
|
162
161
|
};
|
|
163
162
|
|
|
164
|
-
Service.
|
|
163
|
+
Service.module("Users", Users);
|
|
165
164
|
|
|
166
|
-
Service.
|
|
165
|
+
Service.module("Orders", function () {
|
|
167
166
|
const Orders = this;
|
|
168
167
|
|
|
169
168
|
Orders.find = function (arg1, arg2) {
|
package/index.js
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
//These are all the abstractions that make up SystemLynx
|
|
2
2
|
const { isNode } = require("./utils/ProcessChecker");
|
|
3
|
-
const
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
const
|
|
3
|
+
const SystemLynxApp = require("./systemlynx/App/App");
|
|
4
|
+
const SystemLynxLoadBalancer = require("./systemlynx/LoadBalancer/LoadBalancer");
|
|
5
|
+
const SystemLynxService = require("./systemlynx/Service/Service");
|
|
6
|
+
const SystemLynxServerManager = require("./systemlynx/ServerManager/ServerManager");
|
|
7
|
+
const SystemLynxClient = require("./systemlynx/Client/Client");
|
|
8
|
+
const SystemLynxHttpClient = require("./systemlynx/HttpClient/HttpClient");
|
|
9
|
+
const SystemLynxDispatcher = require("./systemlynx/Dispatcher/Dispatcher");
|
|
10
10
|
|
|
11
|
-
const ServerManager = isNode ?
|
|
12
|
-
const Service = isNode ?
|
|
13
|
-
const LoadBalancer = isNode ?
|
|
11
|
+
const ServerManager = isNode ? SystemLynxServerManager() : null;
|
|
12
|
+
const Service = isNode ? SystemLynxService() : null;
|
|
13
|
+
const LoadBalancer = isNode ? SystemLynxLoadBalancer() : null;
|
|
14
14
|
|
|
15
|
-
const App =
|
|
16
|
-
const HttpClient =
|
|
17
|
-
const Client =
|
|
18
|
-
const Dispatcher =
|
|
15
|
+
const App = SystemLynxApp();
|
|
16
|
+
const HttpClient = SystemLynxHttpClient();
|
|
17
|
+
const Client = SystemLynxClient();
|
|
18
|
+
const Dispatcher = SystemLynxDispatcher();
|
|
19
19
|
|
|
20
20
|
module.exports = {
|
|
21
21
|
//Export these pre-created objects for convenient object destructuring
|
|
@@ -30,11 +30,11 @@ module.exports = {
|
|
|
30
30
|
//export all modules themselves
|
|
31
31
|
//all these modules export factory functions
|
|
32
32
|
//to ensure non-singleton behavior
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
33
|
+
SystemLynxApp,
|
|
34
|
+
SystemLynxLoadBalancer,
|
|
35
|
+
SystemLynxService,
|
|
36
|
+
SystemLynxClient,
|
|
37
|
+
SystemLynxHttpClient,
|
|
38
|
+
SystemLynxServerManager,
|
|
39
|
+
SystemLynxDispatcher,
|
|
40
40
|
};
|
package/index.test.js
CHANGED
|
@@ -6,22 +6,22 @@ const {
|
|
|
6
6
|
Client,
|
|
7
7
|
Service,
|
|
8
8
|
ServerManager,
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
9
|
+
SystemLynxApp,
|
|
10
|
+
SystemLynxLoadBalancer,
|
|
11
|
+
SystemLynxService,
|
|
12
|
+
SystemLynxClient,
|
|
13
|
+
SystemLynxHttpClient,
|
|
14
|
+
SystemLynxServerManager,
|
|
15
15
|
} = require("./index");
|
|
16
16
|
|
|
17
|
-
describe("
|
|
18
|
-
it("should return
|
|
19
|
-
expect(
|
|
20
|
-
expect(
|
|
21
|
-
expect(
|
|
22
|
-
expect(
|
|
23
|
-
expect(
|
|
24
|
-
expect(
|
|
17
|
+
describe("SystemLynxSystemLynx functions", () => {
|
|
18
|
+
it("should return aSystemLynx functions for each SystemLynx abstraction", () => {
|
|
19
|
+
expect(SystemLynxApp).to.be.a("function");
|
|
20
|
+
expect(SystemLynxLoadBalancer).to.be.a("function");
|
|
21
|
+
expect(SystemLynxService).to.be.a("function");
|
|
22
|
+
expect(SystemLynxClient).to.be.a("function");
|
|
23
|
+
expect(SystemLynxHttpClient).to.be.a("function");
|
|
24
|
+
expect(SystemLynxServerManager).to.be.a("function");
|
|
25
25
|
});
|
|
26
26
|
|
|
27
27
|
it("should return an instance of each SystemLynx abstraction", () => {});
|
|
@@ -33,7 +33,6 @@ describe("SystemLynx Objects", () => {
|
|
|
33
33
|
.to.be.an("object")
|
|
34
34
|
.that.has.all.keys(
|
|
35
35
|
"module",
|
|
36
|
-
"ServerModule",
|
|
37
36
|
"on",
|
|
38
37
|
"emit",
|
|
39
38
|
"startService",
|
|
@@ -42,7 +41,6 @@ describe("SystemLynx Objects", () => {
|
|
|
42
41
|
"config"
|
|
43
42
|
)
|
|
44
43
|
.that.respondsTo("module")
|
|
45
|
-
.that.respondsTo("ServerModule")
|
|
46
44
|
.that.respondsTo("on")
|
|
47
45
|
.that.respondsTo("emit")
|
|
48
46
|
.that.respondsTo("startService")
|
|
@@ -74,13 +72,13 @@ describe("SystemLynx Objects", () => {
|
|
|
74
72
|
"Server",
|
|
75
73
|
"WebSocket",
|
|
76
74
|
"defaultModule",
|
|
77
|
-
"
|
|
78
|
-
"
|
|
75
|
+
"clones",
|
|
76
|
+
"module"
|
|
79
77
|
)
|
|
80
78
|
.that.respondsTo("startService")
|
|
81
79
|
.that.respondsTo("Server")
|
|
82
80
|
.that.respondsTo("WebSocket")
|
|
83
|
-
.that.respondsTo("
|
|
81
|
+
.that.respondsTo("module");
|
|
84
82
|
expect(LoadBalancer.clones)
|
|
85
83
|
.to.be.an("object")
|
|
86
84
|
.that.has.all.keys("on", "emit", "clones", "register", "dispatch", "assignDispatch")
|
|
@@ -106,15 +104,7 @@ describe("SystemLynx Objects", () => {
|
|
|
106
104
|
it("should return a new instance of a Service", () => {
|
|
107
105
|
expect(Service)
|
|
108
106
|
.to.be.an("object")
|
|
109
|
-
.that.has.all.keys(
|
|
110
|
-
"startService",
|
|
111
|
-
"ServerModule",
|
|
112
|
-
"Server",
|
|
113
|
-
"WebSocket",
|
|
114
|
-
"defaultModule"
|
|
115
|
-
)
|
|
116
107
|
.that.respondsTo("startService")
|
|
117
|
-
.that.respondsTo("ServerModule")
|
|
118
108
|
.that.respondsTo("Server")
|
|
119
109
|
.that.respondsTo("WebSocket");
|
|
120
110
|
});
|
package/package.json
CHANGED
package/systemlynx/App/App.js
CHANGED
|
@@ -4,32 +4,27 @@ const ServiceFactory = require("../Service/Service");
|
|
|
4
4
|
const SystemObject = require("./components/SystemObject");
|
|
5
5
|
const Dispatcher = require("../Dispatcher/Dispatcher");
|
|
6
6
|
const initializeApp = require("./components/initializeApp");
|
|
7
|
-
const URL = require("url");
|
|
8
7
|
|
|
9
8
|
module.exports = function SystemLynxApp() {
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
ServerModules: [],
|
|
15
|
-
configurations: {},
|
|
16
|
-
App,
|
|
17
|
-
routing: null,
|
|
18
|
-
};
|
|
19
|
-
SystemObject.apply(system, [system]);
|
|
9
|
+
const { on, emit } = Dispatcher();
|
|
10
|
+
const App = { emit };
|
|
11
|
+
const system = { Services: [], Modules: [], configurations: {}, App, routing: null };
|
|
12
|
+
const systemObject = SystemObject(system);
|
|
20
13
|
setTimeout(() => initializeApp(system), 0);
|
|
21
14
|
|
|
15
|
+
App.on = (name, callback) => on(name, callback.bind(systemObject));
|
|
16
|
+
|
|
22
17
|
if (isNode) {
|
|
23
18
|
system.Service = ServiceFactory();
|
|
24
|
-
system.Service.defaultModule =
|
|
19
|
+
system.Service.defaultModule = systemObject;
|
|
25
20
|
|
|
26
21
|
App.startService = (options) => {
|
|
27
22
|
system.routing = options;
|
|
28
23
|
return App;
|
|
29
24
|
};
|
|
30
25
|
|
|
31
|
-
App.
|
|
32
|
-
system.
|
|
26
|
+
App.module = (name, __constructor) => {
|
|
27
|
+
system.Modules.push({
|
|
33
28
|
name,
|
|
34
29
|
__constructor,
|
|
35
30
|
});
|
|
@@ -53,21 +48,12 @@ module.exports = function SystemLynxApp() {
|
|
|
53
48
|
return App;
|
|
54
49
|
};
|
|
55
50
|
|
|
56
|
-
App.module = (name, __constructor) => {
|
|
57
|
-
system.Modules.push({
|
|
58
|
-
name,
|
|
59
|
-
__constructor,
|
|
60
|
-
module: SystemObject(system),
|
|
61
|
-
});
|
|
62
|
-
return App;
|
|
63
|
-
};
|
|
64
|
-
|
|
65
51
|
App.config = (__constructor) => {
|
|
66
52
|
if (typeof __constructor === "function")
|
|
67
53
|
system.configurations = { __constructor, module: SystemObject(system) };
|
|
68
54
|
else
|
|
69
55
|
throw Error(
|
|
70
|
-
"App.config methods requires a constructor function as
|
|
56
|
+
"[SystemLynx][App][Error]: App.config(...) methods requires a constructor function as its first parameter."
|
|
71
57
|
);
|
|
72
58
|
return App;
|
|
73
59
|
};
|
|
@@ -18,7 +18,7 @@ module.exports = async function initApp(system) {
|
|
|
18
18
|
try {
|
|
19
19
|
await loadServices(system);
|
|
20
20
|
} catch (err) {
|
|
21
|
-
throw `
|
|
21
|
+
throw `[SystemLynx][App][Error]: Initialization Error - failed to load all services`;
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
if (typeof system.configurations.__constructor === "function") {
|
|
@@ -27,7 +27,7 @@ module.exports = async function initApp(system) {
|
|
|
27
27
|
() => {
|
|
28
28
|
configComplete = true;
|
|
29
29
|
loadModules(system);
|
|
30
|
-
}
|
|
30
|
+
},
|
|
31
31
|
]);
|
|
32
32
|
} else loadModules(system);
|
|
33
33
|
};
|
|
@@ -1,14 +1,10 @@
|
|
|
1
1
|
const Dispatcher = require("../../Dispatcher/Dispatcher");
|
|
2
2
|
|
|
3
3
|
module.exports = async function loadModules(system) {
|
|
4
|
-
system.Modules.forEach(
|
|
5
|
-
|
|
6
|
-
mod.__constructor.apply(mod.module);
|
|
7
|
-
});
|
|
8
|
-
|
|
9
|
-
system.ServerModules.forEach(({ name, __constructor }) =>
|
|
10
|
-
system.Service.ServerModule(name, __constructor)
|
|
4
|
+
system.Modules.forEach(
|
|
5
|
+
(mod) => (mod.module = system.Service.module(mod.name, mod.__constructor))
|
|
11
6
|
);
|
|
7
|
+
|
|
12
8
|
if (system.routing) await system.Service.startService(system.routing);
|
|
13
9
|
system.App.emit("ready", system);
|
|
14
10
|
};
|
|
@@ -11,7 +11,6 @@ describe("App Factory", () => {
|
|
|
11
11
|
.to.be.an("object")
|
|
12
12
|
.that.has.all.keys(
|
|
13
13
|
"module",
|
|
14
|
-
"ServerModule",
|
|
15
14
|
"on",
|
|
16
15
|
"emit",
|
|
17
16
|
"startService",
|
|
@@ -20,7 +19,6 @@ describe("App Factory", () => {
|
|
|
20
19
|
"config"
|
|
21
20
|
)
|
|
22
21
|
.that.respondsTo("module")
|
|
23
|
-
.that.respondsTo("ServerModule")
|
|
24
22
|
.that.respondsTo("on")
|
|
25
23
|
.that.respondsTo("emit")
|
|
26
24
|
.that.respondsTo("startService")
|
|
@@ -35,7 +33,7 @@ describe("App: Loading Services", () => {
|
|
|
35
33
|
const route = "test-service";
|
|
36
34
|
const port = "8503";
|
|
37
35
|
|
|
38
|
-
Service.
|
|
36
|
+
Service.module("mod", function () {
|
|
39
37
|
this.test = () => {};
|
|
40
38
|
this.test2 = () => {};
|
|
41
39
|
});
|
|
@@ -68,7 +66,7 @@ describe("App: Loading Services", () => {
|
|
|
68
66
|
const port = "8422";
|
|
69
67
|
const url = `http://localhost:${port}/${route}`;
|
|
70
68
|
|
|
71
|
-
Service.
|
|
69
|
+
Service.module("mod", function () {
|
|
72
70
|
this.test = () => {};
|
|
73
71
|
this.test2 = () => {};
|
|
74
72
|
});
|
|
@@ -95,7 +93,7 @@ describe("App: Loading Services", () => {
|
|
|
95
93
|
const route = "test-service";
|
|
96
94
|
const port = "8423";
|
|
97
95
|
const url = `http://localhost:${port}/${route}`;
|
|
98
|
-
Service.
|
|
96
|
+
Service.module("mod", function () {
|
|
99
97
|
this.test = () => {};
|
|
100
98
|
this.test2 = () => {};
|
|
101
99
|
});
|
|
@@ -131,7 +129,7 @@ describe("App: Loading Services", () => {
|
|
|
131
129
|
const port = "8442";
|
|
132
130
|
const url = `http://localhost:${port}/${route}`;
|
|
133
131
|
|
|
134
|
-
Service.
|
|
132
|
+
Service.module("mod", function () {
|
|
135
133
|
this.test = () => {};
|
|
136
134
|
this.test2 = () => {};
|
|
137
135
|
});
|
|
@@ -156,7 +154,7 @@ describe("App: Loading Services", () => {
|
|
|
156
154
|
});
|
|
157
155
|
});
|
|
158
156
|
|
|
159
|
-
describe("App SystemObjects: Initializing Modules,
|
|
157
|
+
describe("App SystemObjects: Initializing Modules, Modules and configurations", () => {
|
|
160
158
|
it("should be able to use App.module to initialize a module", async () => {
|
|
161
159
|
const App = AppFactory();
|
|
162
160
|
return new Promise((resolve) =>
|
|
@@ -208,18 +206,18 @@ describe("App SystemObjects: Initializing Modules, ServerModules and configurat
|
|
|
208
206
|
.that.is.an("array").that.is.empty;
|
|
209
207
|
expect(connData.serviceUrl).to.equal(url);
|
|
210
208
|
});
|
|
211
|
-
it("should be able to use App.
|
|
209
|
+
it("should be able to use App.module to add a hosted Module to the Service", async () => {
|
|
212
210
|
const App = AppFactory();
|
|
213
211
|
const route = "test-service";
|
|
214
212
|
const port = "8494";
|
|
215
213
|
const url = `http://localhost:${port}/${route}`;
|
|
216
214
|
await new Promise((resolve) =>
|
|
217
215
|
App.startService({ route, port })
|
|
218
|
-
.
|
|
216
|
+
.module("mod", function () {
|
|
219
217
|
this.test = () => {};
|
|
220
218
|
this.test2 = () => {};
|
|
221
219
|
})
|
|
222
|
-
.
|
|
220
|
+
.module("mod2", function () {
|
|
223
221
|
this.test = () => {};
|
|
224
222
|
this.test2 = () => {};
|
|
225
223
|
})
|
|
@@ -256,7 +254,7 @@ describe("App SystemObjects: Initializing Modules, ServerModules and configurat
|
|
|
256
254
|
it('should be able to use App.on("ready", callback) fire a callback when App initialization is complete', async () => {
|
|
257
255
|
const App = AppFactory();
|
|
258
256
|
|
|
259
|
-
App.
|
|
257
|
+
App.module("mod", function () {
|
|
260
258
|
this.test = () => {};
|
|
261
259
|
this.test2 = () => {};
|
|
262
260
|
}).module("mod", function () {
|
|
@@ -272,13 +270,9 @@ describe("App SystemObjects: Initializing Modules, ServerModules and configurat
|
|
|
272
270
|
"Services",
|
|
273
271
|
"Service",
|
|
274
272
|
"Modules",
|
|
275
|
-
"ServerModules",
|
|
276
273
|
"configurations",
|
|
277
274
|
"App",
|
|
278
|
-
"routing"
|
|
279
|
-
"useService",
|
|
280
|
-
"useModule",
|
|
281
|
-
"useConfig"
|
|
275
|
+
"routing"
|
|
282
276
|
);
|
|
283
277
|
resolve();
|
|
284
278
|
})
|
|
@@ -288,7 +282,7 @@ describe("App SystemObjects: Initializing Modules, ServerModules and configurat
|
|
|
288
282
|
it("should be able to use App.config(constructor) to construct a configuartion module", async () => {
|
|
289
283
|
const App = AppFactory();
|
|
290
284
|
|
|
291
|
-
App.
|
|
285
|
+
App.module("mod", function () {
|
|
292
286
|
this.test = () => {};
|
|
293
287
|
this.test2 = () => {};
|
|
294
288
|
})
|
|
@@ -318,7 +312,7 @@ describe("App SystemObjects: Initializing Modules, ServerModules and configurat
|
|
|
318
312
|
});
|
|
319
313
|
|
|
320
314
|
describe("SystemObjects", () => {
|
|
321
|
-
it("should be able to use this.useModule and this.useService within modules and
|
|
315
|
+
it("should be able to use this.useModule and this.useService within modules and Module", () => {
|
|
322
316
|
const App = AppFactory();
|
|
323
317
|
App.module("mod1", function () {
|
|
324
318
|
expect(this)
|
|
@@ -348,6 +342,17 @@ describe("SystemObjects", () => {
|
|
|
348
342
|
.that.respondsTo("useConfig");
|
|
349
343
|
this.configPassed = true;
|
|
350
344
|
next();
|
|
345
|
+
})
|
|
346
|
+
.on("ready", function () {
|
|
347
|
+
expect(this)
|
|
348
|
+
.to.be.an("object")
|
|
349
|
+
.that.respondsTo("useService")
|
|
350
|
+
.that.respondsTo("useModule")
|
|
351
|
+
.that.respondsTo("useConfig");
|
|
352
|
+
const mod1 = this.useModule("mod1");
|
|
353
|
+
const config = this.useConfig();
|
|
354
|
+
expect(mod1.testPassed).to.equal(true);
|
|
355
|
+
expect(config.configPassed).to.equal(true);
|
|
351
356
|
});
|
|
352
357
|
return new Promise((resolve) => App.on("ready", () => resolve()));
|
|
353
358
|
});
|
|
@@ -49,7 +49,7 @@ module.exports = function ServiceRequestHandler(method, fn, resetConnection) {
|
|
|
49
49
|
console.log(err);
|
|
50
50
|
errCount++;
|
|
51
51
|
resetConnection(() => tryRequest(cb, errCount));
|
|
52
|
-
} else throw Error(`
|
|
52
|
+
} else throw Error(`[SystemLynx][Service][Error]: Invalid route:${err}`);
|
|
53
53
|
};
|
|
54
54
|
|
|
55
55
|
return new Promise((resolve, reject) =>
|
|
@@ -11,7 +11,7 @@ module.exports = function loadConnectionData(url, { limit = 10, wait = 150 } = {
|
|
|
11
11
|
if (errors.length < limit)
|
|
12
12
|
setTimeout(() => getData(resolve), errors.length * wait);
|
|
13
13
|
else
|
|
14
|
-
throw `SystemLynx
|
|
14
|
+
throw `[SystemLynx][Client][Error]: Failed to load Service @${url} after ${errors.length} attempts.`;
|
|
15
15
|
} else resolve(results);
|
|
16
16
|
});
|
|
17
17
|
});
|
|
@@ -17,7 +17,7 @@ describe("Client Factory", () => {
|
|
|
17
17
|
});
|
|
18
18
|
describe("Client", () => {
|
|
19
19
|
it("should be able to use Client.loadService(url, options) to return a promise that resolve into a backend service", async () => {
|
|
20
|
-
Service.
|
|
20
|
+
Service.module(
|
|
21
21
|
"orders",
|
|
22
22
|
function () {
|
|
23
23
|
this.action1 = (data) => ({ SERVICE_TEST_PASSED: true, ...data, action1: true });
|
|
@@ -73,7 +73,7 @@ describe("Client", () => {
|
|
|
73
73
|
});
|
|
74
74
|
|
|
75
75
|
describe("Service", () => {
|
|
76
|
-
it("should be able to call methods from the frontend client to the backend
|
|
76
|
+
it("should be able to call methods from the frontend client to the backend Module", async () => {
|
|
77
77
|
const Client = ClientFactory();
|
|
78
78
|
const buAPI = await Client.loadService(url);
|
|
79
79
|
|
|
@@ -88,7 +88,7 @@ describe("Service", () => {
|
|
|
88
88
|
action2: true,
|
|
89
89
|
});
|
|
90
90
|
});
|
|
91
|
-
it("should be able to send multiple arguments to the backend
|
|
91
|
+
it("should be able to send multiple arguments to the backend Module", async () => {
|
|
92
92
|
const Client = ClientFactory();
|
|
93
93
|
const buAPI = await Client.loadService(url);
|
|
94
94
|
const arg1 = 4,
|
|
@@ -119,7 +119,7 @@ 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 eventTester = Service.
|
|
122
|
+
const eventTester = Service.module("eventTester", function () {
|
|
123
123
|
const eventTester = this;
|
|
124
124
|
eventTester.sendEvent = () => eventTester.emit(eventName, { testPassed: true });
|
|
125
125
|
});
|
|
@@ -149,7 +149,7 @@ describe("Service", () => {
|
|
|
149
149
|
const port = "8492";
|
|
150
150
|
const url = `http://localhost:${port}/${route}`;
|
|
151
151
|
const useREST = true;
|
|
152
|
-
Service.
|
|
152
|
+
Service.module("restTester", function () {
|
|
153
153
|
this.get = (data) => ({ REST_TEST_PASSED: true, getResponse: true, ...data });
|
|
154
154
|
this.put = () => ({ REST_TEST_PASSED: true, putResponse: true });
|
|
155
155
|
this.post = () => ({ REST_TEST_PASSED: true, postResponse: true });
|
|
@@ -177,13 +177,13 @@ describe("Service", () => {
|
|
|
177
177
|
});
|
|
178
178
|
});
|
|
179
179
|
|
|
180
|
-
it("should be able to use 'useReturnValue' configuration option to enable synchronous return values from
|
|
180
|
+
it("should be able to use 'useReturnValue' configuration option to enable synchronous return values from Module methods", async () => {
|
|
181
181
|
const service = ServiceFactory();
|
|
182
182
|
const route = "sync/test";
|
|
183
183
|
const port = 4920;
|
|
184
184
|
const host = "localhost";
|
|
185
185
|
const url = `http://localhost:${port}/${route}`;
|
|
186
|
-
service.
|
|
186
|
+
service.module("AsyncMath", function () {
|
|
187
187
|
this.max = Math.max;
|
|
188
188
|
this.min = Math.min;
|
|
189
189
|
this.round = Math.round;
|
|
@@ -10,7 +10,7 @@ module.exports = function SystemLynxDispatcher(events = {}) {
|
|
|
10
10
|
Dispatcher.on = (eventName, callback) => {
|
|
11
11
|
if (typeof callback !== "function")
|
|
12
12
|
throw Error(
|
|
13
|
-
"
|
|
13
|
+
"[SystemLynx][EventHandler][Error]: EventHandler.on(eventName, callback) received invalid parameters"
|
|
14
14
|
);
|
|
15
15
|
if (!events[eventName]) events[eventName] = [];
|
|
16
16
|
events[eventName].push(callback);
|
|
@@ -2,6 +2,6 @@ const Service = require("../Service/Service");
|
|
|
2
2
|
const CloneManager = require("./components/CloneManager");
|
|
3
3
|
module.exports = function LoadBalancer() {
|
|
4
4
|
const LoadBalancer = Service();
|
|
5
|
-
const clones = LoadBalancer.
|
|
5
|
+
const clones = LoadBalancer.module("clones", CloneManager);
|
|
6
6
|
return { ...LoadBalancer, clones };
|
|
7
7
|
};
|
|
@@ -14,13 +14,13 @@ describe("LoadBalancerFactory", () => {
|
|
|
14
14
|
"Server",
|
|
15
15
|
"WebSocket",
|
|
16
16
|
"defaultModule",
|
|
17
|
-
"
|
|
17
|
+
"module",
|
|
18
18
|
"clones"
|
|
19
19
|
)
|
|
20
20
|
.that.respondsTo("startService")
|
|
21
21
|
.that.respondsTo("Server")
|
|
22
22
|
.that.respondsTo("WebSocket")
|
|
23
|
-
.that.respondsTo("
|
|
23
|
+
.that.respondsTo("module");
|
|
24
24
|
expect(LoadBalancer.clones)
|
|
25
25
|
.to.be.an("object")
|
|
26
26
|
.that.has.all.keys("on", "emit", "clones", "register", "dispatch", "assignDispatch")
|
|
@@ -60,7 +60,7 @@ describe("LoadBalancer", () => {
|
|
|
60
60
|
.to.has.a.lengthOf(1);
|
|
61
61
|
});
|
|
62
62
|
});
|
|
63
|
-
describe("LoadBalancer.clones (
|
|
63
|
+
describe("LoadBalancer.clones (Module)", () => {
|
|
64
64
|
const test_service1 = {
|
|
65
65
|
route: "test-service1",
|
|
66
66
|
port: 5393,
|
|
@@ -63,7 +63,7 @@ module.exports = function SystemLynxServerManager() {
|
|
|
63
63
|
|
|
64
64
|
return new Promise((resolve) =>
|
|
65
65
|
server.listen(port, () => {
|
|
66
|
-
console.log(`
|
|
66
|
+
console.log(`[SystemLynx][Service]: Listening on ${serviceUrl}`);
|
|
67
67
|
moduleQueue.forEach(({ name, object, reserved_methods }) =>
|
|
68
68
|
ServerManager.addModule(name, object, reserved_methods)
|
|
69
69
|
);
|
|
@@ -4,26 +4,26 @@ const isEmpty = (obj) => Object.getOwnPropertyNames(obj).length === 0;
|
|
|
4
4
|
const isPromise = (p) => typeof p === "object" && typeof p.then === "function";
|
|
5
5
|
|
|
6
6
|
module.exports = function SystemLynxRouter(server, config) {
|
|
7
|
-
const addService = (
|
|
7
|
+
const addService = (Module, route, { fn, method }, module_name) => {
|
|
8
8
|
server[method](
|
|
9
9
|
[`/${route}/${fn}`, `/sf/${route}/${fn}`, `/mf/${route}/${fn}`],
|
|
10
10
|
(req, res, next) => {
|
|
11
11
|
req.module_name = module_name;
|
|
12
12
|
req.fn = fn;
|
|
13
|
-
req.
|
|
13
|
+
req.Module = Module;
|
|
14
14
|
next();
|
|
15
15
|
},
|
|
16
16
|
routeHandler
|
|
17
17
|
);
|
|
18
18
|
};
|
|
19
19
|
|
|
20
|
-
const addREST = (
|
|
20
|
+
const addREST = (Module, route, { method }, module_name) => {
|
|
21
21
|
server[method](
|
|
22
22
|
[`/${route}`],
|
|
23
23
|
(req, res, next) => {
|
|
24
24
|
req.module_name = module_name;
|
|
25
25
|
req.fn = method;
|
|
26
|
-
req.
|
|
26
|
+
req.Module = Module;
|
|
27
27
|
next();
|
|
28
28
|
},
|
|
29
29
|
routeHandler
|
|
@@ -31,7 +31,7 @@ module.exports = function SystemLynxRouter(server, config) {
|
|
|
31
31
|
};
|
|
32
32
|
|
|
33
33
|
const routeHandler = (req, res) => {
|
|
34
|
-
const { query, file, files, body, fn,
|
|
34
|
+
const { query, file, files, body, fn, Module, module_name, method } = req;
|
|
35
35
|
const { serviceUrl } = config();
|
|
36
36
|
const presets = { serviceUrl, module_name, fn };
|
|
37
37
|
|
|
@@ -62,7 +62,7 @@ module.exports = function SystemLynxRouter(server, config) {
|
|
|
62
62
|
} else sendError(returnValue);
|
|
63
63
|
};
|
|
64
64
|
|
|
65
|
-
if (typeof
|
|
65
|
+
if (typeof Module[fn] !== "function")
|
|
66
66
|
return sendResponse({
|
|
67
67
|
message: `[SystemLynx][error]:${module_name}.${fn} method not found`,
|
|
68
68
|
status: 404,
|
|
@@ -73,7 +73,7 @@ module.exports = function SystemLynxRouter(server, config) {
|
|
|
73
73
|
if (!isEmpty(query) && !args.length) args.push(query);
|
|
74
74
|
if (isObject(args[0]) && method === "PUT") args[0] = { ...args[0], file, files };
|
|
75
75
|
|
|
76
|
-
const results =
|
|
76
|
+
const results = Module[fn].apply(Module, args);
|
|
77
77
|
|
|
78
78
|
if (isPromise(results)) {
|
|
79
79
|
results.then(sendResponse).catch(sendError);
|
|
@@ -16,7 +16,7 @@ describe("SystemLynxServerManager function", () => {
|
|
|
16
16
|
});
|
|
17
17
|
});
|
|
18
18
|
describe("ServerManager", () => {
|
|
19
|
-
it("should be able use ServerManager.startService to start a server that will accept requests for
|
|
19
|
+
it("should be able use ServerManager.startService to start a server that will accept requests for Module Connection Data on the given route", async () => {
|
|
20
20
|
const ServerManager = SystemLynxServerManager();
|
|
21
21
|
const route = "/testService";
|
|
22
22
|
const port = 4400;
|
|
@@ -157,7 +157,7 @@ describe("ServerManager.startService(ServerConfiguration)", () => {
|
|
|
157
157
|
});
|
|
158
158
|
});
|
|
159
159
|
|
|
160
|
-
it("should be able to use the staticRouting=true property to create static routes to the
|
|
160
|
+
it("should be able to use the staticRouting=true property to create static routes to the Modules", async () => {
|
|
161
161
|
const ServerManager = SystemLynxServerManager();
|
|
162
162
|
const route = "/testAPI";
|
|
163
163
|
const port = 2233;
|
|
@@ -7,7 +7,7 @@ module.exports = function ServiceFactory({ defaultModule = {} } = {}) {
|
|
|
7
7
|
const { startService, Server, WebSocket } = ServerManager;
|
|
8
8
|
const Service = { startService, Server, WebSocket, defaultModule };
|
|
9
9
|
|
|
10
|
-
Service.
|
|
10
|
+
Service.module = function (name, constructor, reserved_methods = []) {
|
|
11
11
|
if (typeof constructor === "object" && constructor instanceof Object) {
|
|
12
12
|
ServerManager.addModule(name, constructor, reserved_methods);
|
|
13
13
|
return constructor;
|
|
@@ -15,13 +15,16 @@ module.exports = function ServiceFactory({ defaultModule = {} } = {}) {
|
|
|
15
15
|
|
|
16
16
|
if (typeof constructor === "function") {
|
|
17
17
|
if (constructor.constructor.name === "AsyncFunction")
|
|
18
|
-
throw `
|
|
18
|
+
throw `[SystemLynx][Module][Error]: Module(name, constructor) function cannot receive an async function as the constructor`;
|
|
19
19
|
|
|
20
|
-
const
|
|
21
|
-
const exclude_methods = [
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
20
|
+
const Module = Dispatcher.apply({ ...Service.defaultModule });
|
|
21
|
+
const exclude_methods = [
|
|
22
|
+
...reserved_methods,
|
|
23
|
+
...Object.getOwnPropertyNames(Module),
|
|
24
|
+
];
|
|
25
|
+
constructor.apply(Module, [ServerManager.Server(), ServerManager.WebSocket()]);
|
|
26
|
+
ServerManager.addModule(name, Module, exclude_methods);
|
|
27
|
+
return Module;
|
|
25
28
|
}
|
|
26
29
|
};
|
|
27
30
|
return Service;
|
|
@@ -7,15 +7,9 @@ describe("SystemLynxService", () => {
|
|
|
7
7
|
const Service = ServiceFactory();
|
|
8
8
|
expect(Service)
|
|
9
9
|
.to.be.an("object")
|
|
10
|
-
.that.has.all.keys(
|
|
11
|
-
"startService",
|
|
12
|
-
"ServerModule",
|
|
13
|
-
"Server",
|
|
14
|
-
"WebSocket",
|
|
15
|
-
"defaultModule"
|
|
16
|
-
)
|
|
10
|
+
.that.has.all.keys("startService", "module", "Server", "WebSocket", "defaultModule")
|
|
17
11
|
.that.respondsTo("startService")
|
|
18
|
-
.that.respondsTo("
|
|
12
|
+
.that.respondsTo("module")
|
|
19
13
|
.that.respondsTo("Server")
|
|
20
14
|
.that.respondsTo("WebSocket");
|
|
21
15
|
});
|
|
@@ -54,14 +48,14 @@ describe("Service factory", () => {
|
|
|
54
48
|
it("should throw an Error if Service.startService(options) is called twice", () => {});
|
|
55
49
|
});
|
|
56
50
|
|
|
57
|
-
describe("Service.
|
|
51
|
+
describe("Service.module(constructor)", () => {
|
|
58
52
|
const Service = ServiceFactory();
|
|
59
53
|
const port = 6542;
|
|
60
54
|
const route = "test/service";
|
|
61
55
|
const url = `http://localhost:${port}/${route}`;
|
|
62
56
|
|
|
63
57
|
it("should be able to return a Service instance constructed using the 'this' value in the constructor function", () => {
|
|
64
|
-
const mod = Service.
|
|
58
|
+
const mod = Service.module("mod", function () {
|
|
65
59
|
this.test = () => {};
|
|
66
60
|
this.test2 = () => {};
|
|
67
61
|
});
|
|
@@ -116,13 +110,13 @@ describe("Service.ServerModule(constructor)", () => {
|
|
|
116
110
|
});
|
|
117
111
|
});
|
|
118
112
|
|
|
119
|
-
describe("Service.
|
|
113
|
+
describe("Service.module(object)", () => {
|
|
120
114
|
const Service = ServiceFactory();
|
|
121
115
|
const port = 6543;
|
|
122
116
|
const route = "test/service2";
|
|
123
117
|
const url = `http://localhost:${port}/${route}`;
|
|
124
118
|
it("should be able to return a Service instance created using an object as the constructor", () => {
|
|
125
|
-
const mod = Service.
|
|
119
|
+
const mod = Service.module("mod", {
|
|
126
120
|
action1: () => {},
|
|
127
121
|
action2: () => {},
|
|
128
122
|
});
|