@nsshunt/stsappframework 3.1.241 → 3.2.1

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 (108) hide show
  1. package/.github/dependabot.yml +13 -0
  2. package/.github/workflows/npm-publish.yml +47 -0
  3. package/.gitignore copy +108 -0
  4. package/build.sh +37 -0
  5. package/dist/index.js +30 -0
  6. package/esbuild.config.js +81 -0
  7. package/eslint.config.mjs +55 -0
  8. package/jest/setEnvVars.js +19 -0
  9. package/keys/server.cert +21 -0
  10. package/keys/server.key +28 -0
  11. package/local-redis-stack.conf +2 -0
  12. package/package.json +10 -23
  13. package/run-grpc-client.sh +2 -0
  14. package/run-grpc-server.sh +2 -0
  15. package/run1.sh +20 -0
  16. package/run2.sh +20 -0
  17. package/run3.sh +20 -0
  18. package/runc1.sh +19 -0
  19. package/runc2.sh +19 -0
  20. package/runkafka.sh +19 -0
  21. package/runkafkaconsume01.sh +21 -0
  22. package/runkafkaconsume02.sh +21 -0
  23. package/runpromise.sh +5 -0
  24. package/runredis.sh +5 -0
  25. package/runredis1.sh +4 -0
  26. package/runredis2.sh +24 -0
  27. package/runredis3.sh +4 -0
  28. package/runtest1.sh +19 -0
  29. package/runtest2.sh +19 -0
  30. package/runtest_ipc_legacy.sh +19 -0
  31. package/runtest_ipcex.sh +19 -0
  32. package/runtest_redis.sh +19 -0
  33. package/runtest_ww.sh +19 -0
  34. package/src/commonTypes.ts +374 -0
  35. package/src/controller/stscontrollerbase.ts +14 -0
  36. package/src/controller/stslatencycontroller.ts +26 -0
  37. package/src/index.ts +13 -0
  38. package/src/logger/stsTransportLoggerWinston.ts +24 -0
  39. package/src/logger/stsTransportWinston.ts +48 -0
  40. package/src/middleware/serverNetworkMiddleware.ts +243 -0
  41. package/src/network.ts +36 -0
  42. package/src/process/masterprocessbase.ts +674 -0
  43. package/src/process/processbase.ts +483 -0
  44. package/src/process/serverprocessbase.ts +455 -0
  45. package/src/process/singleprocessbase.ts +63 -0
  46. package/src/process/workerprocessbase.ts +224 -0
  47. package/src/publishertransports/publishTransportUtils.ts +53 -0
  48. package/src/route/stslatencyroute.ts +15 -0
  49. package/src/route/stsrouterbase.ts +21 -0
  50. package/src/stsexpressserver.ts +137 -0
  51. package/src/validation/errors.ts +6 -0
  52. package/src/vitesttesting/appConfig.ts +111 -0
  53. package/src/vitesttesting/appSingleWSS.ts +142 -0
  54. package/src/vitesttesting/server.ts +17 -0
  55. package/src/vitesttesting/singleservertest.test.ts +352 -0
  56. package/src/vitesttesting/wsevents.ts +44 -0
  57. package/tsconfig.json +42 -0
  58. package/types/commonTypes.d.ts +230 -0
  59. package/types/commonTypes.d.ts.map +1 -0
  60. package/types/controller/stscontrollerbase.d.ts +7 -0
  61. package/types/controller/stscontrollerbase.d.ts.map +1 -0
  62. package/types/controller/stslatencycontroller.d.ts +7 -0
  63. package/types/controller/stslatencycontroller.d.ts.map +1 -0
  64. package/types/index.d.ts +14 -0
  65. package/types/index.d.ts.map +1 -0
  66. package/types/logger/stsTransportLoggerWinston.d.ts +11 -0
  67. package/types/logger/stsTransportLoggerWinston.d.ts.map +1 -0
  68. package/types/logger/stsTransportWinston.d.ts +15 -0
  69. package/types/logger/stsTransportWinston.d.ts.map +1 -0
  70. package/types/middleware/serverNetworkMiddleware.d.ts +33 -0
  71. package/types/middleware/serverNetworkMiddleware.d.ts.map +1 -0
  72. package/types/network.d.ts +4 -0
  73. package/types/network.d.ts.map +1 -0
  74. package/types/process/masterprocessbase.d.ts +27 -0
  75. package/types/process/masterprocessbase.d.ts.map +1 -0
  76. package/types/process/processbase.d.ts +44 -0
  77. package/types/process/processbase.d.ts.map +1 -0
  78. package/types/process/serverprocessbase.d.ts +26 -0
  79. package/types/process/serverprocessbase.d.ts.map +1 -0
  80. package/types/process/singleprocessbase.d.ts +21 -0
  81. package/types/process/singleprocessbase.d.ts.map +1 -0
  82. package/types/process/workerprocessbase.d.ts +35 -0
  83. package/types/process/workerprocessbase.d.ts.map +1 -0
  84. package/types/publishertransports/publishTransportUtils.d.ts +5 -0
  85. package/types/publishertransports/publishTransportUtils.d.ts.map +1 -0
  86. package/types/route/stslatencyroute.d.ts +6 -0
  87. package/types/route/stslatencyroute.d.ts.map +1 -0
  88. package/types/route/stsrouterbase.d.ts +9 -0
  89. package/types/route/stsrouterbase.d.ts.map +1 -0
  90. package/types/stsexpressserver.d.ts +8 -0
  91. package/types/stsexpressserver.d.ts.map +1 -0
  92. package/types/validation/errors.d.ts +7 -0
  93. package/types/validation/errors.d.ts.map +1 -0
  94. package/types/vitesttesting/appConfig.d.ts +3 -0
  95. package/types/vitesttesting/appConfig.d.ts.map +1 -0
  96. package/types/vitesttesting/appSingleWSS.d.ts +7 -0
  97. package/types/vitesttesting/appSingleWSS.d.ts.map +1 -0
  98. package/types/vitesttesting/server.d.ts +6 -0
  99. package/types/vitesttesting/server.d.ts.map +1 -0
  100. package/types/vitesttesting/singleservertest.test.d.ts +2 -0
  101. package/types/vitesttesting/singleservertest.test.d.ts.map +1 -0
  102. package/types/vitesttesting/wsevents.d.ts +29 -0
  103. package/types/vitesttesting/wsevents.d.ts.map +1 -0
  104. package/vite.config.ts +19 -0
  105. package/dist/stsappframework.mjs +0 -156498
  106. package/dist/stsappframework.mjs.map +0 -7
  107. package/dist/stsappframework.umd.js +0 -156516
  108. package/dist/stsappframework.umd.js.map +0 -7
@@ -0,0 +1,142 @@
1
+ /* eslint @typescript-eslint/no-explicit-any: 0 */ // --> OFF
2
+ import chalk from 'chalk';
3
+
4
+ import { SingleProcessBase, ProcessOptions } from './../index'
5
+ import { SocketIoServerHelper, STSNamespace, STSRoom, InterServerEvents } from '@nsshunt/stssocketioutils'
6
+
7
+ import { Namespace, Socket } from "socket.io";
8
+
9
+ import { ClientToServerEvents, ServerToClientEvents } from './wsevents'
10
+ import { JSONObject } from '@nsshunt/stsutils';
11
+
12
+ export class AppSingleWSS extends SingleProcessBase
13
+ {
14
+ constructor(options: ProcessOptions) {
15
+ super(options);
16
+ }
17
+
18
+ #LogInfoMessage(message: any) {
19
+ this.options.logger.info(message);
20
+ }
21
+
22
+ #SetupWSSServer = (namespace: STSNamespace) => {
23
+
24
+
25
+
26
+ this.socketIoServerHelper = new SocketIoServerHelper<ClientToServerEvents, ServerToClientEvents>({
27
+ logger: this.options.logger
28
+ });
29
+
30
+
31
+ //this.io?.of('/stsinstrumentmanager/stsmonitor/');
32
+ //return;
33
+
34
+ //this.socketIoServerHelper.SetupNamespaceEx(this.io as any, '/stsinstrumentmanager/stsmonitor/' as any);
35
+ //return;
36
+
37
+
38
+ this.socketIoServerHelper.SetupNamespace(this.io as any, namespace,
39
+ // Auto joinn room list
40
+ [
41
+ STSRoom.STSInstrumentDataRoom,
42
+ STSRoom.STSRunnerRoom,
43
+ 'room3'
44
+ ],
45
+ true, // Make any connecting client automatically join the room list above
46
+
47
+ // Connect call back when a client connects
48
+ (socket: Socket<ClientToServerEvents, ServerToClientEvents, InterServerEvents>) => {
49
+ this.#LogInfoMessage(chalk.gray(`AppSingleWSS.#SetupWSSServer: Id: [${socket.id}] eventName: [connect]`));
50
+ },
51
+
52
+ // Custom client to server events
53
+ (socket: Socket<ClientToServerEvents, ServerToClientEvents, InterServerEvents>) => {
54
+ socket.on('subscribe', (data: any) => {
55
+ socket.emit('subscribeAck', data);
56
+ });
57
+ socket.on('unsubscribe', (data: any) => {
58
+ socket.emit('unsubscribeAck', data);
59
+ });
60
+ socket.on('subscribeKeepAlive', (data: any) => {
61
+ socket.emit('subscribeKeepAliveAck', data);
62
+ });
63
+ socket.on('done', () => {
64
+ socket.emit('doneAck');
65
+ });
66
+ socket.on('compute', (arg: number, cb) => {
67
+ const res = arg * 2;
68
+ cb(res.toString());
69
+ });
70
+ socket.on('compute2', (arg, cb) => {
71
+ cb({data: arg*2});
72
+ });
73
+ socket.on('broadcast', () => {
74
+
75
+ if (this.socketIoServerHelper) {
76
+ const namespaceIo = this.socketIoServerHelper
77
+ .GetSTSSocketIONamespace(namespace).socketionamespace as Namespace<ClientToServerEvents, ServerToClientEvents, InterServerEvents>
78
+
79
+ namespaceIo.to("room3").timeout(5000).emit("compute3", 10, (err: Error, data: JSONObject[]) => {
80
+ if (err) {
81
+ console.log(`room3 broadcast: [${chalk.red(JSON.stringify(err))}]`)
82
+ } else {
83
+ console.log(`room3 broadcast: [${chalk.blue(JSON.stringify(data))}]`)
84
+ }
85
+ });
86
+ }
87
+ });
88
+
89
+ socket.on('__STSsendToRoomWithCB', (rooms: string[], payload: { command: string, payload: JSONObject }): void => {
90
+ rooms.forEach((room) => {
91
+ //this.LogMessage(namespace, `${namespace.socketionamespace.name}:socket.on:sendToRoom: __STSsendToRoom: Sending to room [${room}], ID: [${socket.id}]`);
92
+
93
+ if (this.socketIoServerHelper) {
94
+ const namespaceIo = this.socketIoServerHelper
95
+ .GetSTSSocketIONamespace(namespace).socketionamespace as Namespace<ClientToServerEvents, ServerToClientEvents, InterServerEvents>
96
+
97
+ namespaceIo.to(room).timeout(5000).emit(payload.command as any, payload, (err: Error, data: JSONObject[]) => {
98
+ if (err) {
99
+ console.error(err);
100
+ console.log(`__STSsendToRoomWithCB broadcast: [${chalk.red(JSON.stringify(err))}]`)
101
+ } else {
102
+ console.log(`__STSsendToRoomWithCB broadcast: [${chalk.blue(JSON.stringify(data))}]`)
103
+ }
104
+ });
105
+ }
106
+ });
107
+ });
108
+
109
+ socket.on('GetThreadDetails', (inputThreaddata: JSONObject, cb: (data: JSONObject) => void) => {
110
+ if (this.socketIoServerHelper) {
111
+ const namespaceIo = this.socketIoServerHelper
112
+ .GetSTSSocketIONamespace(namespace).socketionamespace as Namespace<ClientToServerEvents, ServerToClientEvents, InterServerEvents>
113
+
114
+ namespaceIo.to(inputThreaddata.room).timeout(5000).emit('GetThreadDetailsFromService', { data: inputThreaddata }, (err: Error, data: JSONObject[]) => {
115
+ if (err) {
116
+ console.error(err);
117
+ console.log(`__STSsendToRoomWithCB broadcast: [${chalk.red(JSON.stringify(err))}]`)
118
+ } else {
119
+ console.log(`__STSsendToRoomWithCB broadcast: [${chalk.blue(JSON.stringify(data))}]`)
120
+ cb(data);
121
+ }
122
+ });
123
+ }
124
+ });
125
+ })
126
+ }
127
+
128
+ override ProcessStarted() {
129
+ super.ProcessStarted();
130
+
131
+ /*
132
+ const nsp = this.io?.of('/stsinstrumentmanager/stsmonitor');
133
+ nsp?.on("connection", socket => {
134
+
135
+ });
136
+ this.#SetupConnectionMiddleware(nsp);
137
+ */
138
+
139
+ this.#SetupWSSServer(STSNamespace.STSMonitor);
140
+ //this.#SetupWSSServer('stsinstrumentmanager/stsmonitor' as any);
141
+ }
142
+ }
@@ -0,0 +1,17 @@
1
+ import express from 'express';
2
+
3
+ import { STSLatencyRoute, IProcessBase } from './..'
4
+
5
+ import { goptions } from '@nsshunt/stsconfig'
6
+
7
+ export class STSExpressRouteFactory
8
+ {
9
+ constructor(app: express.Express, stsApp: IProcessBase)
10
+ {
11
+ const stslatency = new STSLatencyRoute(stsApp);
12
+
13
+ // Note: This MUST come first as the latency end point is on the same path as the reosurce path.
14
+ // If stsresourceRouter came first, it would think that /latency was a resource name.
15
+ app.use(`${goptions.rest01apiroot}`, stslatency.router);
16
+ }
17
+ }
@@ -0,0 +1,352 @@
1
+ /* eslint @typescript-eslint/no-explicit-any: 0 */ // --> OFF
2
+ import chalk from 'chalk';
3
+
4
+ import axios, { AxiosError, AxiosResponse } from 'axios';
5
+
6
+ import { JSONObject, Sleep } from '@nsshunt/stsutils'
7
+ //import { SingleProcessBase, MasterProcessBase } from './..'
8
+
9
+ import { AppSingleWSS } from './appSingleWSS'
10
+
11
+ import { ServiceConfigOptions } from './appConfig'
12
+
13
+ import { goptions, $ResetOptions, STSAxiosConfig, AgentManager } from '@nsshunt/stsconfig'
14
+
15
+ import { beforeAll, afterAll, test, describe, expect } from 'vitest';
16
+
17
+ import { SocketIoClientHelper, ISocketIoClientHelperOptions } from '@nsshunt/stssocketioutils'
18
+
19
+ import { STSNamespace } from '@nsshunt/stssocketioutils'
20
+
21
+ import { ServerToClientEvents, ClientToServerEvents } from './wsevents'
22
+ import { Socket } from 'socket.io-client'
23
+
24
+ //import { GenericContainer, Network, Wait } from "testcontainers";
25
+ import { GenericContainer, Network } from "testcontainers";
26
+
27
+ describe("Single Server Test", () =>
28
+ {
29
+ let app: AppSingleWSS | null = null;
30
+ let ioRedisMessageProcessorUrl = '';
31
+ let ioRedisContainer: any = null;
32
+ let network: any;
33
+
34
+ const agentManager = new AgentManager({});
35
+
36
+ const endpoint = 'https://localhost'
37
+
38
+ const socketUtilsoptions: ISocketIoClientHelperOptions = {
39
+ agentOptions: {
40
+ keepAlive: goptions.keepAlive,
41
+ maxSockets: goptions.maxSockets,
42
+ maxTotalSockets: goptions.maxTotalSockets,
43
+ maxFreeSockets: goptions.maxFreeSockets,
44
+ timeout: 30000, //@@ config
45
+ rejectUnauthorized: goptions.isProduction // Allows self signed certs in non production mode(s)
46
+ }
47
+ }
48
+
49
+ const socketUtils = new SocketIoClientHelper<ServerToClientEvents, ClientToServerEvents>(socketUtilsoptions);
50
+
51
+ const instrumentManagerAddress =
52
+ `${endpoint}:${goptions.rest01port}/${STSNamespace.STSMonitor}/`;
53
+
54
+ const LogInfoMessage = (message: any) => console.log(chalk.green(`info: ${message}`));
55
+ const LogErrorMessage = (message: any) => console.error(chalk.red(`error: ${message}`));
56
+ const LogDebugMessage = (message: any) => console.log(chalk.blue(`debug: ${message}`));
57
+
58
+ const HandleError = (error: any) => {
59
+ LogDebugMessage(chalk.red(`HandleError(): Error: [${error}]`));
60
+ if (axios.isAxiosError(error)) {
61
+ const axiosError: AxiosError = error;
62
+ if (axiosError.response) {
63
+ LogDebugMessage(chalk.red(`AXIOS Error Response.Status = [${axiosError.response.status}]`));
64
+ if (axiosError.response.headers) {
65
+ LogInfoMessage(chalk.red(` headers: [${JSON.stringify(axiosError.response.headers)}]`));
66
+ }
67
+ if (axiosError.response.data) {
68
+ LogInfoMessage(chalk.red(` data: [${JSON.stringify(axiosError.response.data)}]`));
69
+ }
70
+ try {
71
+ if (axiosError.response.config) {
72
+ LogInfoMessage(chalk.red(` config: [${JSON.stringify(axiosError.response.config)}]`));
73
+ }
74
+ } catch (innererror: any) {
75
+ LogInfoMessage(chalk.red(` could not get response config, error: [${innererror}]`));
76
+ }
77
+ } else {
78
+ LogDebugMessage(chalk.red(`HandleError(): AXIOS Error = [${axiosError}]`));
79
+ }
80
+ }
81
+ }
82
+
83
+ const getLatency = async (): Promise<AxiosResponse | null> => {
84
+ const url = `${endpoint}:${goptions.rest01port}${goptions.rest01apiroot}/latency`;
85
+ try {
86
+ const retVal = await axios(new STSAxiosConfig(url, 'get')
87
+ .withDefaultHeaders()
88
+ .withAgentManager(agentManager).config);
89
+ return retVal;
90
+ } catch (error: any) {
91
+ HandleError(error);
92
+ return null;
93
+ }
94
+ }
95
+
96
+ const StartNetwork = async () => {
97
+ network = await new Network().start();
98
+ }
99
+
100
+ const StopNetwork = async () => {
101
+ await network.stop();
102
+ }
103
+
104
+ const StartRedis = async () => {
105
+ ioRedisContainer = await new GenericContainer("redis/redis-stack-server")
106
+ .withEnvironment({
107
+ REDIS_ARGS: "--save \"\" --appendonly no",
108
+ })
109
+ .withExposedPorts(6379)
110
+ .withNetwork(network)
111
+ .withNetworkAliases("redisstackserver")
112
+ //.withWaitStrategy(Wait.forLogMessage(`Ready to accept connections tcp`))
113
+ .start();
114
+
115
+ ioRedisMessageProcessorUrl = `redis://${ioRedisContainer.getHost()}:${ioRedisContainer.getMappedPort(6379)}`;
116
+
117
+ await Sleep(2000);
118
+ //expect(goptions.imRedisMessageProcessorUrl).toEqual('redis://localhost:6379');
119
+ // IM_REDIS_MESSAGE_PROCESSOR_URL
120
+
121
+ console.log(chalk.green(`redis/redis-stack-server Started. docker [${ioRedisMessageProcessorUrl}]`));
122
+ }
123
+
124
+ const StopRedis = async () => {
125
+ await ioRedisContainer.stop();
126
+ await Sleep(200);
127
+ }
128
+
129
+ beforeAll(async () => {
130
+
131
+ await StartNetwork();
132
+ await StartRedis();
133
+
134
+ process.env.IM_REDIS_MESSAGE_PROCESSOR_URL = ioRedisMessageProcessorUrl;
135
+ process.env.SOCKET_IO_REDIS_ADAPTOR_URL = ioRedisMessageProcessorUrl;
136
+
137
+ $ResetOptions();
138
+
139
+ const appOptions = ServiceConfigOptions(false, true);
140
+ appOptions.processExitOnTerminate = false;
141
+ app = new AppSingleWSS(appOptions)
142
+ await app.SetupServer();
143
+ await Sleep(3000);
144
+ }, 120000);
145
+
146
+ afterAll(async () => {
147
+ agentManager.Terminate();
148
+ await Sleep(500);
149
+ await app?.TerminateApplication();
150
+
151
+ await Sleep(2000);
152
+
153
+ app = null;
154
+
155
+ await StopRedis();
156
+ await StopNetwork();
157
+
158
+ await Sleep(2000);
159
+ }, 120000);
160
+
161
+ test('Testing Module', async () => {
162
+ expect.assertions(1);
163
+ expect(1).toEqual(1);
164
+ });
165
+
166
+ test('GET /latency', async () => {
167
+ const num = 50;
168
+ expect.assertions(num * 2);
169
+ for (let i=0; i < num; i++) {
170
+ const retVal = await getLatency();
171
+ const retValObj = retVal?.data.data;
172
+ expect(retValObj).toMatch('Ping Completed At:');
173
+ expect(retVal && retVal.status).toEqual(200);
174
+ }
175
+ }, 10000);
176
+
177
+ test('client socket testing', async () => {
178
+ expect.assertions(29);
179
+
180
+ let connectCount = 0;
181
+ let subscribeAckCount = 0;
182
+ let unsubscribeAckCount = 0;
183
+ let subscribeKeepAliveAckCount = 0;
184
+ let doneAckCount = 0;
185
+
186
+ const SetupClient = async (clientName: string, joinRooms: string[]): Promise<Socket<ServerToClientEvents, ClientToServerEvents>> => {
187
+
188
+ const socket = socketUtils.SetupClientSideSocket('STSUITerm',
189
+ // The address defines the namespace to connect to (i.e. io.of('/address'))
190
+ instrumentManagerAddress,
191
+ // Connected call back
192
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
193
+ (socket: Socket<ServerToClientEvents, ClientToServerEvents>) => {
194
+ LogDebugMessage(chalk.green(`${clientName}: connected - 1`));
195
+ connectCount++;
196
+ expect(1).toEqual(1);
197
+ },
198
+ // Custom Events
199
+ (socket: Socket<ServerToClientEvents, ClientToServerEvents>) => {
200
+ socket.on('subscribeAck', (data: any) => {
201
+ LogDebugMessage(chalk.yellow(`${clientName}: subscribeAck`));
202
+ subscribeAckCount++;
203
+ expect(data.data).toMatch(/(subject01|subject02)/i);
204
+ });
205
+ socket.on('unsubscribeAck', (data: any) => {
206
+ unsubscribeAckCount++;
207
+ LogDebugMessage(chalk.yellow(`${clientName}: unsubscribeAck`));
208
+ expect(data.data).toMatch(/(subject02)/i);
209
+ });
210
+ socket.on('subscribeKeepAliveAck', (data: any) => {
211
+ subscribeKeepAliveAckCount++;
212
+ LogDebugMessage(chalk.yellow(`${clientName}: subscribeKeepAliveAck`));
213
+ expect(data.data).toMatch(/(ok)/i);
214
+ });
215
+ socket.on('doneAck', async () => {
216
+ doneAckCount++;
217
+ LogDebugMessage(chalk.yellow(`${clientName}: doneAck`));
218
+ expect(1).toEqual(1);
219
+ });
220
+ socket.on('compute3', async (arg: number, cb) => {
221
+ LogDebugMessage(chalk.yellow(`${clientName}: compute3`));
222
+ cb({arg, clientName});
223
+ });
224
+
225
+ socket.on('ServiceCommandGetThreads', async (arg) => {
226
+ LogDebugMessage(chalk.yellow(`${clientName}: ServiceCommandGetThreads: [${JSON.stringify(arg)}]`));
227
+ });
228
+
229
+ socket.on('ServiceCommandGetThreadsEx', async (arg: any, cb) => {
230
+ LogDebugMessage(chalk.green(`${clientName}: ServiceCommandGetThreadsEx: [${JSON.stringify(arg)}]`));
231
+ cb({arg, clientName});
232
+ });
233
+
234
+ socket.on('GetThreadDetailsFromService', async (arg: any, cb) => {
235
+ LogDebugMessage(chalk.green(`${clientName}: ServiceCommandGetThreadsEx: [${JSON.stringify(arg)}]`));
236
+ cb({
237
+ threadData: { id: 'someid', extraData: 'someextradata' },
238
+ arg,
239
+ clientName
240
+ });
241
+ });
242
+
243
+ },
244
+ (error: Error) => {
245
+ LogErrorMessage(`${clientName}: SetupClientSideSocket call back: [${error}]`);
246
+ }
247
+ )
248
+
249
+ socket.emit('__STSjoinRoom', joinRooms);
250
+
251
+ socket.emit('__STSjoinRoom', ['room1']).emit('__STSjoinRoom', ['room2']);
252
+
253
+ socket.emit('subscribe', { data: 'subject01 '});
254
+ socket.emit('subscribe', { data: 'subject02 '});
255
+
256
+ socket.emit('unsubscribe', { data: 'subject02 '});
257
+
258
+ socket.emit('subscribeKeepAlive', { data: 'ok'});
259
+
260
+ socket.timeout(250).emit('compute', 10, (err, arg) => {
261
+ if (err) {
262
+ LogInfoMessage(err);
263
+ } else {
264
+ console.log(`${clientName}: compute: [${chalk.magenta(JSON.stringify(arg))}]`)
265
+ expect(arg).toEqual('20');
266
+ }
267
+ });
268
+
269
+ socket.timeout(250).emit('compute2', 10, (err, arg) => {
270
+ if (err) {
271
+ LogInfoMessage(err);
272
+ } else {
273
+ console.log(`${clientName}: compute2: [${chalk.magenta(JSON.stringify(arg))}]`)
274
+ expect(arg.data).toEqual(20);
275
+ }
276
+ });
277
+
278
+ return socket;
279
+ }
280
+
281
+ const client1 = await SetupClient('client1', [ 'service' ]);
282
+ const client2 = await SetupClient('client2', [ 'service', 'service_instance1' ]);
283
+ const client3 = await SetupClient('client3', [ 'service', 'service_instance2' ]);
284
+
285
+ await Sleep(1000);
286
+
287
+ //client1.emit('broadcast');
288
+
289
+ //client2.emit('__STSsendToRoom', ['service'], { command: 'ServiceCommandGetThreads', payload: { room: 'service', somedata: 1 }});
290
+
291
+ client2.emit('__STSsendToRoomWithCB',
292
+ ['service_instance1'],
293
+ { command: 'ServiceCommandGetThreadsEx', payload: { room: 'service_instance1', somedata: 1 } }
294
+ );
295
+
296
+ client3.emit('GetThreadDetails', {
297
+ room: 'service_instance1',
298
+ threadInput: 500
299
+ }, (data: JSONObject) => {
300
+ console.log(chalk.magenta(JSON.stringify(data)))
301
+ });
302
+
303
+ const start = performance.now();
304
+ const promArray: Promise<JSONObject>[] = [ ];
305
+ for (let i=0; i < 20; i++) {
306
+ const prom = new Promise<JSONObject>((res, rej) => {
307
+ try {
308
+ client1.emit('GetThreadDetails', {
309
+ room: 'service',
310
+ threadInput: 500,
311
+ iteration: i
312
+ }, (data: JSONObject) => {
313
+ console.log(chalk.rgb(100, 240, 20)(JSON.stringify(data)))
314
+ res(data);
315
+ });
316
+ } catch (error) {
317
+ rej(error);
318
+ }
319
+ });
320
+ promArray.push(prom);
321
+ }
322
+ await Promise.all(promArray);
323
+ const end = performance.now();
324
+ console.log(chalk.magenta(`Total Time: [${end-start}]`));
325
+
326
+ await Sleep(1000);
327
+
328
+ client1.emit('__STSsendToRoom', ['room3'], { command: 'doneAck', payload: { somedata: 1 }})
329
+
330
+ //while (!complete) {
331
+ while (doneAckCount < 3) {
332
+ await Sleep(100);
333
+ }
334
+ await Sleep(500);
335
+
336
+ console.log(chalk.green(`connectCount: [${connectCount}]`));
337
+ console.log(chalk.green(`subscribeAckCount: [${subscribeAckCount}]`));
338
+ console.log(chalk.green(`unsubscribeAckCount: [${unsubscribeAckCount}]`));
339
+ console.log(chalk.green(`subscribeKeepAliveAckCount: [${subscribeKeepAliveAckCount}]`));
340
+ console.log(chalk.green(`doneAckCount: [${doneAckCount}]`));
341
+
342
+ expect(connectCount).toEqual(3);
343
+ expect(subscribeAckCount).toEqual(6);
344
+ expect(unsubscribeAckCount).toEqual(3);
345
+ expect(subscribeKeepAliveAckCount).toEqual(3);
346
+ expect(doneAckCount).toEqual(3);
347
+
348
+ console.log(chalk.green(`All Done...`));
349
+
350
+ }, 60000);
351
+ });
352
+
@@ -0,0 +1,44 @@
1
+ /* eslint @typescript-eslint/no-explicit-any: 0 */ // --> OFF
2
+ import { STSDefaultServerToClientEvents, STSDefaultClientToServerEvents } from '@nsshunt/stssocketioutils'
3
+ import { JSONObject } from '@nsshunt/stsutils';
4
+
5
+ // Syntax sugar from socket.io
6
+ // https://socket.io/docs/v4/typescript/#emitting-with-a-timeout
7
+ //type WithTimeoutAck<isSender extends boolean, args extends any[]> = isSender extends true ? [Error, ...args] : args;
8
+
9
+ //export interface ServerToClientEvents<isSender extends boolean = false> extends STSServerToClientEvents {
10
+ export interface ServerToClientEvents extends STSDefaultServerToClientEvents {
11
+ /*
12
+ noArg: () => void;
13
+ basicEmit: (a: number, b: string, c: Buffer) => void;
14
+ withAck: (d: string, callback: (e: number) => void) => void;
15
+ */
16
+
17
+ subscribeAck: (data: any) => void;
18
+ unsubscribeAck: (data: any) => void;
19
+ subscribeKeepAliveAck: (data: any) => void;
20
+ doneAck: () => void;
21
+ compute3: (arg: number, callback: (data: JSONObject) => void) => void;
22
+ ServiceCommandGetThreads: (data: any) => void;
23
+ ServiceCommandGetThreadsEx: (data: any, callback: (data: JSONObject) => void) => void;
24
+
25
+ GetThreadDetailsFromService: (data: any, callback: (data: JSONObject) => void) => void;
26
+ }
27
+
28
+ //export interface ClientToServerEvents<isSender extends boolean = false> extends STSClientToServerEvents {
29
+ export interface ClientToServerEvents extends STSDefaultClientToServerEvents {
30
+ subscribe: (data: any) => void;
31
+ unsubscribe: (data: any) => void;
32
+ subscribeKeepAlive: (data: any) => void;
33
+ done: () => void;
34
+
35
+ //compute: (arg: number, callback: (...args: WithTimeoutAck<isSender, [string]>) => void) => void;
36
+ //compute2: (arg: number, callback: (...args: WithTimeoutAck<isSender, [{ data: any}]>) => void) => void;
37
+ compute: (arg: number, callback: (data: string) => void) => void;
38
+ compute2: (arg: number, callback: (data: { data: any}) => void) => void;
39
+ broadcast: () => void;
40
+
41
+ GetThreadDetails: (arg: JSONObject, callback: (data: JSONObject) => void) => void;
42
+
43
+ __STSsendToRoomWithCB: (rooms: string[], payload: { command: string, payload: any }) => void;
44
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "extends": "@tsconfig/node20/tsconfig.json",
3
+ "include": ["src/**/*"],
4
+ "exclude": ["node_modules", "**/node_modules/**/*", "**/*.spec.ts"],
5
+ "compilerOptions": {
6
+ // sts custom compiler options
7
+ "sourceMap": true,
8
+ "outDir": "dist",
9
+ "declaration": true,
10
+ "declarationDir": "./types",
11
+ "declarationMap": true,
12
+
13
+ "module": "commonjs",
14
+ //"module": "ES2022",
15
+ "moduleResolution": "node"
16
+ //"isolatedModules": true,
17
+ //"allowSyntheticDefaultImports": true
18
+ //"types": ["vite/client", "node"],
19
+ //"resolveJsonModule": true,
20
+ //"allowJs": true,
21
+
22
+ // The following are from :- @tsconfig/node20/tsconfig.json
23
+ //"lib": ["es2023"],
24
+ //"module": "commonjs",
25
+ //"target": "es2022",
26
+ //"strict": true,
27
+ //"esModuleInterop": true,
28
+ //"skipLibCheck": true,
29
+ //"forceConsistentCasingInFileNames": true,
30
+ //"moduleResolution": "node"
31
+
32
+ // The following where from previous sts builds ( <= 1.15.45 )
33
+ //"lib": ["DOM", "DOM.Iterable", "ES2021", "ESNext"],
34
+ //"module": "ESNext",
35
+ //"target": "ESNext",
36
+ //"strict": true,
37
+ //"esModuleInterop": false,
38
+ //"skipLibCheck": true,
39
+ //"forceConsistentCasingInFileNames": true,
40
+ //"moduleResolution": "node"
41
+ }
42
+ }