monocart-reporter 2.9.6 → 2.9.7

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.
@@ -1,194 +1,194 @@
1
- const EC = require('eight-colors');
2
- const { WebSocketServer } = require('../../packages/monocart-reporter-vendor.js');
3
- const Util = require('../../utils/util.js');
4
- const { getServerUrl, Client } = require('./client.js');
5
-
6
- // https://github.com/websockets/ws/blob/master/doc/ws.md
7
- const defaultServerOptions = {
8
- host: 'localhost',
9
- port: 8130
10
- };
11
-
12
- const defaultClientOptions = {
13
- ... defaultServerOptions,
14
- timeout: 3000
15
- };
16
-
17
- // ===============================================================================
18
-
19
- const clientMap = new Map();
20
- const useState = (options = {}) => {
21
- const clientOptions = {
22
- ... defaultClientOptions,
23
- ... options
24
- };
25
-
26
- // when used in global-setup will be override reporter (main process)
27
- Util.initLoggingLevel(clientOptions.logging, 'state');
28
-
29
- const clientKey = Object.keys(defaultClientOptions).map((k) => clientOptions[k]).join('-');
30
- // console.log('client key', clientKey);
31
-
32
- let client = clientMap.get(clientKey);
33
- if (!client) {
34
- client = new Client(clientOptions);
35
- clientMap.set(clientKey, client);
36
- }
37
-
38
- return client.state();
39
- };
40
-
41
- // ===============================================================================
42
-
43
- const getActions = (stateData) => {
44
- return {
45
- get: (... args) => {
46
- if (args.length) {
47
- const values = args.map((k) => stateData[k]);
48
- if (args.length === 1) {
49
- return values[0];
50
- }
51
- return values;
52
- }
53
- return stateData;
54
- },
55
- set: (... args) => {
56
- if (args.length) {
57
- const first = args[0];
58
- if (args.length === 1 && typeof first === 'object') {
59
- Object.keys(first).forEach((key) => {
60
- stateData[key] = first[key];
61
- });
62
- return;
63
- }
64
- stateData[first] = args[1];
65
- }
66
- },
67
- remove: (... args) => {
68
- if (args.length) {
69
- args.forEach((k) => {
70
- if (Util.hasOwn(stateData, k)) {
71
- delete stateData[k];
72
- }
73
- });
74
- }
75
- }
76
- };
77
- };
78
-
79
- const getResponseData = async (data, options) => {
80
- let res;
81
- // first argument is action name always
82
- const action = data.shift();
83
- if (action === 'send') {
84
- // EC.logCyan('send', data[0]);
85
- // send handler
86
- if (typeof options.onReceive === 'function') {
87
- res = await options.onReceive(... data);
88
- }
89
- return res;
90
- }
91
-
92
- // get/set/remove handler
93
- const actions = getActions(options.data);
94
- const handler = actions[action];
95
- if (handler) {
96
- res = handler.apply(options, data);
97
- }
98
- return res;
99
- };
100
-
101
- const onMessage = async (ws, buf, options) => {
102
- const message = JSON.parse(buf.toString());
103
- if (!message) {
104
- Util.logDebug(EC.red('invalid message buffer'));
105
- return;
106
- }
107
- const { id, data } = message;
108
- if (!id || !Array.isArray(data)) {
109
- Util.logDebug(EC.red('invalid message id or data'));
110
- return;
111
- }
112
-
113
- const resData = await getResponseData(data, options);
114
- const response = JSON.stringify({
115
- id,
116
- data: resData
117
- });
118
-
119
- // always response, like send action
120
- // otherwise the request will be timeout
121
- ws.send(response);
122
-
123
- };
124
-
125
- const createStateServer = (stateOptions) => {
126
-
127
- const defaultStateOptions = {
128
-
129
- // key-value state data
130
- data: {},
131
-
132
- server: {}
133
-
134
- // onReceive: function(... args) {
135
- // console.log('receive on server', args);
136
- // return ['custom response', ... args];
137
- // },
138
-
139
- // onClose: function(data, config) {
140
- // Object.assign(config.metadata, data);
141
- // },
142
-
143
- };
144
-
145
- const options = Util.mergeOption(defaultStateOptions, stateOptions);
146
-
147
- if (!options.data || typeof options.data !== 'object') {
148
- options.data = {};
149
- }
150
-
151
- const serverOptions = {
152
- ... defaultServerOptions,
153
- ... options.server
154
- };
155
-
156
- const wss = new WebSocketServer(serverOptions);
157
-
158
- wss.on('error', (e) => {
159
- Util.logError(`websocket server error: ${e.message}`);
160
- });
161
- wss.on('wsClientError', (e) => {
162
- Util.logError(`websocket client error: ${e.message}`);
163
- });
164
-
165
- wss.on('connection', (ws) => {
166
-
167
- // Util.logDebug('a client connected');
168
-
169
- // data {Buffer|ArrayBuffer|Buffer[]}
170
- ws.on('message', (data) => {
171
- // console.log(data, isBinary);
172
- onMessage(ws, data, options);
173
- });
174
- });
175
-
176
- wss.on('listening', () => {
177
- const serverUrl = getServerUrl(serverOptions);
178
- Util.logInfo(`state websocket server listening on ${EC.cyan(serverUrl)}`);
179
- });
180
-
181
- return {
182
- close: async (config) => {
183
- wss.close();
184
- if (typeof options.onClose === 'function') {
185
- await options.onClose(options.data, config);
186
- }
187
- }
188
- };
189
- };
190
-
191
- module.exports = {
192
- createStateServer,
193
- useState
194
- };
1
+ const EC = require('eight-colors');
2
+ const { WebSocketServer } = require('../../packages/monocart-reporter-vendor.js');
3
+ const Util = require('../../utils/util.js');
4
+ const { getServerUrl, Client } = require('./client.js');
5
+
6
+ // https://github.com/websockets/ws/blob/master/doc/ws.md
7
+ const defaultServerOptions = {
8
+ host: 'localhost',
9
+ port: 8130
10
+ };
11
+
12
+ const defaultClientOptions = {
13
+ ... defaultServerOptions,
14
+ timeout: 3000
15
+ };
16
+
17
+ // ===============================================================================
18
+
19
+ const clientMap = new Map();
20
+ const useState = (options = {}) => {
21
+ const clientOptions = {
22
+ ... defaultClientOptions,
23
+ ... options
24
+ };
25
+
26
+ // when used in global-setup will be override reporter (main process)
27
+ Util.initLoggingLevel(clientOptions.logging, 'state');
28
+
29
+ const clientKey = Object.keys(defaultClientOptions).map((k) => clientOptions[k]).join('-');
30
+ // console.log('client key', clientKey);
31
+
32
+ let client = clientMap.get(clientKey);
33
+ if (!client) {
34
+ client = new Client(clientOptions);
35
+ clientMap.set(clientKey, client);
36
+ }
37
+
38
+ return client.state();
39
+ };
40
+
41
+ // ===============================================================================
42
+
43
+ const getActions = (stateData) => {
44
+ return {
45
+ get: (... args) => {
46
+ if (args.length) {
47
+ const values = args.map((k) => stateData[k]);
48
+ if (args.length === 1) {
49
+ return values[0];
50
+ }
51
+ return values;
52
+ }
53
+ return stateData;
54
+ },
55
+ set: (... args) => {
56
+ if (args.length) {
57
+ const first = args[0];
58
+ if (args.length === 1 && typeof first === 'object') {
59
+ Object.keys(first).forEach((key) => {
60
+ stateData[key] = first[key];
61
+ });
62
+ return;
63
+ }
64
+ stateData[first] = args[1];
65
+ }
66
+ },
67
+ remove: (... args) => {
68
+ if (args.length) {
69
+ args.forEach((k) => {
70
+ if (Util.hasOwn(stateData, k)) {
71
+ delete stateData[k];
72
+ }
73
+ });
74
+ }
75
+ }
76
+ };
77
+ };
78
+
79
+ const getResponseData = async (data, options) => {
80
+ let res;
81
+ // first argument is action name always
82
+ const action = data.shift();
83
+ if (action === 'send') {
84
+ // EC.logCyan('send', data[0]);
85
+ // send handler
86
+ if (typeof options.onReceive === 'function') {
87
+ res = await options.onReceive(... data);
88
+ }
89
+ return res;
90
+ }
91
+
92
+ // get/set/remove handler
93
+ const actions = getActions(options.data);
94
+ const handler = actions[action];
95
+ if (handler) {
96
+ res = handler.apply(options, data);
97
+ }
98
+ return res;
99
+ };
100
+
101
+ const onMessage = async (ws, buf, options) => {
102
+ const message = JSON.parse(buf.toString());
103
+ if (!message) {
104
+ Util.logDebug(EC.red('invalid message buffer'));
105
+ return;
106
+ }
107
+ const { id, data } = message;
108
+ if (!id || !Array.isArray(data)) {
109
+ Util.logDebug(EC.red('invalid message id or data'));
110
+ return;
111
+ }
112
+
113
+ const resData = await getResponseData(data, options);
114
+ const response = JSON.stringify({
115
+ id,
116
+ data: resData
117
+ });
118
+
119
+ // always response, like send action
120
+ // otherwise the request will be timeout
121
+ ws.send(response);
122
+
123
+ };
124
+
125
+ const createStateServer = (stateOptions) => {
126
+
127
+ const defaultStateOptions = {
128
+
129
+ // key-value state data
130
+ data: {},
131
+
132
+ server: {}
133
+
134
+ // onReceive: function(... args) {
135
+ // console.log('receive on server', args);
136
+ // return ['custom response', ... args];
137
+ // },
138
+
139
+ // onClose: function(data, config) {
140
+ // Object.assign(config.metadata, data);
141
+ // },
142
+
143
+ };
144
+
145
+ const options = Util.mergeOption(defaultStateOptions, stateOptions);
146
+
147
+ if (!options.data || typeof options.data !== 'object') {
148
+ options.data = {};
149
+ }
150
+
151
+ const serverOptions = {
152
+ ... defaultServerOptions,
153
+ ... options.server
154
+ };
155
+
156
+ const wss = new WebSocketServer(serverOptions);
157
+
158
+ wss.on('error', (e) => {
159
+ Util.logError(`websocket server error: ${e.message}`);
160
+ });
161
+ wss.on('wsClientError', (e) => {
162
+ Util.logError(`websocket client error: ${e.message}`);
163
+ });
164
+
165
+ wss.on('connection', (ws) => {
166
+
167
+ // Util.logDebug('a client connected');
168
+
169
+ // data {Buffer|ArrayBuffer|Buffer[]}
170
+ ws.on('message', (data) => {
171
+ // console.log(data, isBinary);
172
+ onMessage(ws, data, options);
173
+ });
174
+ });
175
+
176
+ wss.on('listening', () => {
177
+ const serverUrl = getServerUrl(serverOptions);
178
+ Util.logInfo(`state websocket server listening on ${EC.cyan(serverUrl)}`);
179
+ });
180
+
181
+ return {
182
+ close: async (config) => {
183
+ wss.close();
184
+ if (typeof options.onClose === 'function') {
185
+ await options.onClose(options.data, config);
186
+ }
187
+ }
188
+ };
189
+ };
190
+
191
+ module.exports = {
192
+ createStateServer,
193
+ useState
194
+ };