@dooboostore/simple-boot-http-server 1.0.23 → 1.0.24

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 (167) hide show
  1. package/README.MD +27 -1
  2. package/dist/cjs/SimpleBootHttpServer.js +79 -39
  3. package/dist/cjs/SimpleBootHttpServer.js.map +3 -3
  4. package/dist/cjs/codes/HttpHeaders.js +14 -3
  5. package/dist/cjs/codes/HttpHeaders.js.map +2 -2
  6. package/dist/cjs/codes/Mimes.js +2 -0
  7. package/dist/cjs/codes/Mimes.js.map +2 -2
  8. package/dist/cjs/decorators/MethodMapping.js +7 -6
  9. package/dist/cjs/decorators/MethodMapping.js.map +3 -3
  10. package/dist/cjs/endpoints/WebSocketEndPoint.js +16 -0
  11. package/dist/cjs/endpoints/WebSocketEndPoint.js.map +7 -0
  12. package/dist/cjs/filters/CacheFilter.js +75 -35
  13. package/dist/cjs/filters/CacheFilter.js.map +3 -3
  14. package/dist/cjs/filters/IntentSchemeFilter.js +98 -0
  15. package/dist/cjs/filters/IntentSchemeFilter.js.map +7 -0
  16. package/dist/cjs/filters/ResourceFilter.js +4 -1
  17. package/dist/cjs/filters/ResourceFilter.js.map +2 -2
  18. package/dist/cjs/filters/TopicProtocolFilter.js +343 -0
  19. package/dist/cjs/filters/TopicProtocolFilter.js.map +7 -0
  20. package/dist/cjs/filters/index.js +2 -0
  21. package/dist/cjs/filters/index.js.map +2 -2
  22. package/dist/cjs/index.js +28 -0
  23. package/dist/cjs/index.js.map +2 -2
  24. package/dist/cjs/models/RequestResponse.js +51 -89
  25. package/dist/cjs/models/RequestResponse.js.map +3 -3
  26. package/dist/cjs/models/datas/body/ReqPathData.js +29 -0
  27. package/dist/cjs/models/datas/body/ReqPathData.js.map +7 -0
  28. package/dist/cjs/option/HttpServerOption.js +25 -5
  29. package/dist/cjs/option/HttpServerOption.js.map +2 -2
  30. package/dist/cjs/proxy/SymbolIntentApiServiceProxy.js +141 -0
  31. package/dist/cjs/proxy/SymbolIntentApiServiceProxy.js.map +7 -0
  32. package/dist/cjs/proxy/SymbolIntentApiServiceProxyBase.js +35 -0
  33. package/dist/cjs/proxy/SymbolIntentApiServiceProxyBase.js.map +7 -0
  34. package/dist/cjs/proxy/TopicProtocolApiServiceProxy.js +324 -0
  35. package/dist/cjs/proxy/TopicProtocolApiServiceProxy.js.map +7 -0
  36. package/dist/cjs/proxy/index.js +26 -0
  37. package/dist/cjs/proxy/index.js.map +7 -0
  38. package/dist/cjs/resolvers/ResourceResolver.js +2 -2
  39. package/dist/cjs/resolvers/ResourceResolver.js.map +2 -2
  40. package/dist/cjs/session/SessionManager.js +2 -2
  41. package/dist/cjs/session/SessionManager.js.map +2 -2
  42. package/dist/cjs/websocket/WebSocketClient.js +554 -0
  43. package/dist/cjs/websocket/WebSocketClient.js.map +7 -0
  44. package/dist/cjs/websocket/WebSocketManager.js +652 -0
  45. package/dist/cjs/websocket/WebSocketManager.js.map +7 -0
  46. package/dist/cjs/websocket/index.js +24 -0
  47. package/dist/cjs/websocket/index.js.map +7 -0
  48. package/dist/esm/SimpleBootHttpServer.js +59 -19
  49. package/dist/esm/SimpleBootHttpServer.js.map +2 -2
  50. package/dist/esm/codes/HttpHeaders.js +12 -2
  51. package/dist/esm/codes/HttpHeaders.js.map +2 -2
  52. package/dist/esm/codes/Mimes.js +2 -0
  53. package/dist/esm/codes/Mimes.js.map +2 -2
  54. package/dist/esm/decorators/MethodMapping.js +2 -1
  55. package/dist/esm/decorators/MethodMapping.js.map +2 -2
  56. package/dist/esm/endpoints/WebSocketEndPoint.js +1 -0
  57. package/dist/esm/endpoints/WebSocketEndPoint.js.map +7 -0
  58. package/dist/esm/filters/CacheFilter.js +67 -27
  59. package/dist/esm/filters/CacheFilter.js.map +2 -2
  60. package/dist/esm/filters/IntentSchemeFilter.js +75 -0
  61. package/dist/esm/filters/IntentSchemeFilter.js.map +7 -0
  62. package/dist/esm/filters/ResourceFilter.js +4 -1
  63. package/dist/esm/filters/ResourceFilter.js.map +2 -2
  64. package/dist/esm/filters/TopicProtocolFilter.js +310 -0
  65. package/dist/esm/filters/TopicProtocolFilter.js.map +7 -0
  66. package/dist/esm/filters/index.js +1 -0
  67. package/dist/esm/filters/index.js.map +2 -2
  68. package/dist/esm/index.js +12 -0
  69. package/dist/esm/index.js.map +2 -2
  70. package/dist/esm/models/RequestResponse.js +46 -84
  71. package/dist/esm/models/RequestResponse.js.map +2 -2
  72. package/dist/esm/models/datas/body/ReqPathData.js +6 -0
  73. package/dist/esm/models/datas/body/ReqPathData.js.map +7 -0
  74. package/dist/esm/option/HttpServerOption.js +24 -4
  75. package/dist/esm/option/HttpServerOption.js.map +2 -2
  76. package/dist/esm/proxy/SymbolIntentApiServiceProxy.js +118 -0
  77. package/dist/esm/proxy/SymbolIntentApiServiceProxy.js.map +7 -0
  78. package/dist/esm/proxy/SymbolIntentApiServiceProxyBase.js +12 -0
  79. package/dist/esm/proxy/SymbolIntentApiServiceProxyBase.js.map +7 -0
  80. package/dist/esm/proxy/TopicProtocolApiServiceProxy.js +301 -0
  81. package/dist/esm/proxy/TopicProtocolApiServiceProxy.js.map +7 -0
  82. package/dist/esm/proxy/index.js +4 -0
  83. package/dist/esm/proxy/index.js.map +7 -0
  84. package/dist/esm/resolvers/ResourceResolver.js +1 -1
  85. package/dist/esm/resolvers/ResourceResolver.js.map +1 -1
  86. package/dist/esm/session/SessionManager.js +1 -1
  87. package/dist/esm/session/SessionManager.js.map +1 -1
  88. package/dist/esm/websocket/WebSocketClient.js +529 -0
  89. package/dist/esm/websocket/WebSocketClient.js.map +7 -0
  90. package/dist/esm/websocket/WebSocketManager.js +622 -0
  91. package/dist/esm/websocket/WebSocketManager.js.map +7 -0
  92. package/dist/esm/websocket/index.js +3 -0
  93. package/dist/esm/websocket/index.js.map +7 -0
  94. package/dist/esm-bundle/dooboostore-simple-boot-http-server.esm.js +13190 -4886
  95. package/dist/esm-bundle/dooboostore-simple-boot-http-server.esm.js.map +4 -4
  96. package/dist/types/SimpleBootHttpServer.d.ts +5 -3
  97. package/dist/types/SimpleBootHttpServer.d.ts.map +1 -1
  98. package/dist/types/codes/HttpHeaders.d.ts +3 -0
  99. package/dist/types/codes/HttpHeaders.d.ts.map +1 -1
  100. package/dist/types/codes/Mimes.d.ts +3 -1
  101. package/dist/types/codes/Mimes.d.ts.map +1 -1
  102. package/dist/types/decorators/MethodMapping.d.ts +3 -2
  103. package/dist/types/decorators/MethodMapping.d.ts.map +1 -1
  104. package/dist/types/endpoints/WebSocketEndPoint.d.ts +17 -0
  105. package/dist/types/endpoints/WebSocketEndPoint.d.ts.map +1 -0
  106. package/dist/types/filters/CacheFilter.d.ts +6 -0
  107. package/dist/types/filters/CacheFilter.d.ts.map +1 -1
  108. package/dist/types/filters/IntentSchemeFilter.d.ts +20 -0
  109. package/dist/types/filters/IntentSchemeFilter.d.ts.map +1 -0
  110. package/dist/types/filters/ResourceFilter.d.ts.map +1 -1
  111. package/dist/types/filters/TopicProtocolFilter.d.ts +34 -0
  112. package/dist/types/filters/TopicProtocolFilter.d.ts.map +1 -0
  113. package/dist/types/filters/index.d.ts +1 -0
  114. package/dist/types/filters/index.d.ts.map +1 -1
  115. package/dist/types/index.d.ts +12 -0
  116. package/dist/types/index.d.ts.map +1 -1
  117. package/dist/types/models/RequestResponse.d.ts +9 -6
  118. package/dist/types/models/RequestResponse.d.ts.map +1 -1
  119. package/dist/types/models/datas/body/ReqPathData.d.ts +4 -0
  120. package/dist/types/models/datas/body/ReqPathData.d.ts.map +1 -0
  121. package/dist/types/option/HttpServerOption.d.ts +30 -20
  122. package/dist/types/option/HttpServerOption.d.ts.map +1 -1
  123. package/dist/types/proxy/SymbolIntentApiServiceProxy.d.ts +18 -0
  124. package/dist/types/proxy/SymbolIntentApiServiceProxy.d.ts.map +1 -0
  125. package/dist/types/proxy/SymbolIntentApiServiceProxyBase.d.ts +5 -0
  126. package/dist/types/proxy/SymbolIntentApiServiceProxyBase.d.ts.map +1 -0
  127. package/dist/types/proxy/TopicProtocolApiServiceProxy.d.ts +28 -0
  128. package/dist/types/proxy/TopicProtocolApiServiceProxy.d.ts.map +1 -0
  129. package/dist/types/proxy/index.d.ts +4 -0
  130. package/dist/types/proxy/index.d.ts.map +1 -0
  131. package/dist/types/session/SessionManager.d.ts +2 -17
  132. package/dist/types/session/SessionManager.d.ts.map +1 -1
  133. package/dist/types/websocket/WebSocketClient.d.ts +88 -0
  134. package/dist/types/websocket/WebSocketClient.d.ts.map +1 -0
  135. package/dist/types/websocket/WebSocketManager.d.ts +163 -0
  136. package/dist/types/websocket/WebSocketManager.d.ts.map +1 -0
  137. package/dist/types/websocket/index.d.ts +3 -0
  138. package/dist/types/websocket/index.d.ts.map +1 -0
  139. package/dist/umd-bundle/dooboostore-simple-boot-http-server.umd.js +13262 -4958
  140. package/dist/umd-bundle/dooboostore-simple-boot-http-server.umd.js.map +4 -4
  141. package/dist/umd-bundle/websocket-client.umd.js +11194 -0
  142. package/dist/umd-bundle/websocket-client.umd.js.map +7 -0
  143. package/package.json +24 -15
  144. package/src/SimpleBootHttpServer.ts +366 -312
  145. package/src/codes/HttpHeaders.ts +13 -2
  146. package/src/codes/Mimes.ts +27 -25
  147. package/src/decorators/MethodMapping.ts +4 -3
  148. package/src/endpoints/WebSocketEndPoint.ts +12 -0
  149. package/src/filters/CacheFilter.ts +112 -67
  150. package/src/filters/IntentSchemeFilter.ts +69 -0
  151. package/src/filters/ResourceFilter.ts +6 -1
  152. package/src/filters/TopicProtocolFilter.ts +349 -0
  153. package/src/filters/index.ts +1 -0
  154. package/src/index.ts +12 -12
  155. package/src/models/RequestResponse.ts +108 -240
  156. package/src/models/datas/body/ReqPathData.ts +3 -0
  157. package/src/option/HttpServerOption.ts +73 -23
  158. package/src/proxy/SymbolIntentApiServiceProxy.ts +120 -0
  159. package/src/proxy/SymbolIntentApiServiceProxyBase.ts +16 -0
  160. package/src/proxy/TopicProtocolApiServiceProxy.ts +328 -0
  161. package/src/proxy/index.ts +3 -0
  162. package/src/resolvers/ResourceResolver.ts +1 -1
  163. package/src/session/SessionManager.ts +3 -3
  164. package/src/websocket/WebSocketClient.ts +637 -0
  165. package/src/websocket/WebSocketManager.ts +713 -0
  166. package/src/websocket/index.ts +2 -0
  167. package/tsconfig.json +3 -1
@@ -0,0 +1,622 @@
1
+ var __decorate = function(decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = function(k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ var _a, _b;
11
+ import { Sim } from "@dooboostore/simple-boot";
12
+ import { WebSocket } from "ws";
13
+ import { IntentManager } from "@dooboostore/simple-boot";
14
+ import { RouterManager } from "@dooboostore/simple-boot";
15
+ import { Intent } from "@dooboostore/simple-boot";
16
+ import { RandomUtils } from "@dooboostore/core";
17
+ import { Subject } from "@dooboostore/core";
18
+ const isTopicRequest = (obj) => {
19
+ return typeof obj === "object" && obj !== null && "uuid" in obj && typeof obj.uuid === "string" && (obj.type === void 0 || obj.type === "intent" || obj.type === "router") && (obj.body === void 0 || true);
20
+ };
21
+ const isTopicSubscribeRequest = (obj) => {
22
+ return typeof obj === "object" && obj !== null && "type" in obj && obj.type === "subscribe" && "target" in obj && typeof obj.target === "string" && "uuid" in obj && typeof obj.uuid === "string" && (obj.body === void 0 || true);
23
+ };
24
+ const isTopicUnsubscribeRequest = (obj) => {
25
+ return typeof obj === "object" && obj !== null && "type" in obj && obj.type === "unsubscribe" && "uuid" in obj && typeof obj.uuid === "string";
26
+ };
27
+ const isTopicResponse = (obj) => {
28
+ return typeof obj === "object" && obj !== null && "state" in obj && (obj.state === "success" || obj.state === "error") && "target" in obj && typeof obj.target === "string" && "uuid" in obj && typeof obj.uuid === "string" && "body" in obj;
29
+ };
30
+ const isTopicServerEventRequest = (obj) => {
31
+ return typeof obj === "object" && obj !== null && "type" in obj && obj.type === "event" && "uuid" in obj && typeof obj.uuid === "string" && "eventUUID" in obj && typeof obj.eventUUID === "string" && "event" in obj && typeof obj.event === "string" && (obj.body === void 0 || true);
32
+ };
33
+ const isTopicServerEventResponse = (obj) => {
34
+ return typeof obj === "object" && obj !== null && "type" in obj && obj.type === "event" && "uuid" in obj && typeof obj.uuid === "string" && "eventUUID" in obj && typeof obj.eventUUID === "string" && (obj.body === void 0 || true);
35
+ };
36
+ const isTopicServerEventUnSubscribeRequest = (obj) => {
37
+ return typeof obj === "object" && obj !== null && "type" in obj && obj.type === "unsubscribe" && "uuid" in obj && typeof obj.uuid === "string";
38
+ };
39
+ let WebSocketManager = class WebSocketManager2 {
40
+ constructor(intentManager, routerManager) {
41
+ this.intentManager = intentManager;
42
+ this.routerManager = routerManager;
43
+ this.clients = /* @__PURE__ */ new Map();
44
+ this.eventSubscriptions = /* @__PURE__ */ new Map();
45
+ this.subject = new Subject();
46
+ }
47
+ get observable() {
48
+ return this.subject.asObservable();
49
+ }
50
+ connect(wsSet) {
51
+ this.clients.set(wsSet, []);
52
+ console.log("WebSocket connected:", wsSet.request.url);
53
+ }
54
+ close(wsSet) {
55
+ this.removeAllClientsByWebSocketSet(wsSet);
56
+ this.clients.delete(wsSet);
57
+ console.log("WebSocket disconnected:", wsSet.request.url);
58
+ }
59
+ setClientTopic(wsSet, uuid, target, subscribeBody) {
60
+ const clientTopics = this.clients.get(wsSet);
61
+ if (clientTopics && !clientTopics.find((it) => it.uuid === uuid)) {
62
+ clientTopics.push({ uuid, target, subscribeBody });
63
+ this.clients.set(wsSet, clientTopics);
64
+ } else if (clientTopics) {
65
+ throw { message: "Already subscribed topic" };
66
+ }
67
+ }
68
+ findAllClientsByTarget(target) {
69
+ const results = [];
70
+ for (const [wsSet, topics] of Array.from(this.clients.entries())) {
71
+ const find = topics.find((it) => it.target === target);
72
+ if (find) {
73
+ results.push({ ...find, webSocketSet: wsSet });
74
+ }
75
+ }
76
+ return results;
77
+ }
78
+ findClientsByTarget(target) {
79
+ for (const [wsSet, topics] of Array.from(this.clients.entries())) {
80
+ const find = topics.find((it) => it.target === target);
81
+ if (find) {
82
+ return { ...find, webSocketSet: wsSet };
83
+ }
84
+ }
85
+ }
86
+ removeClientByUUID(uuid) {
87
+ for (const [wsSet, topics] of Array.from(this.clients.entries())) {
88
+ const findIndex = topics.findIndex((it) => it.uuid === uuid);
89
+ if (findIndex >= 0) {
90
+ topics.splice(findIndex, 1);
91
+ this.clients.set(wsSet, topics);
92
+ this.eventSubscriptions.delete(uuid);
93
+ return true;
94
+ }
95
+ }
96
+ return false;
97
+ }
98
+ findClientByUUID(uuid) {
99
+ for (const [wsSet, topics] of Array.from(this.clients.entries())) {
100
+ const find = topics.find((it) => it.uuid === uuid);
101
+ if (find) {
102
+ return { ...find, webSocketSet: wsSet };
103
+ }
104
+ }
105
+ return void 0;
106
+ }
107
+ sendDataByUUID({ uuid, body }) {
108
+ const client = this.findClientByUUID(uuid);
109
+ if (client) {
110
+ const data = {
111
+ state: "success",
112
+ target: client.target,
113
+ uuid,
114
+ body
115
+ };
116
+ this.sendTopic(client.webSocketSet, data);
117
+ return true;
118
+ }
119
+ return false;
120
+ }
121
+ sendUnSubscribeByUUID({ uuid }) {
122
+ const client = this.findClientByUUID(uuid);
123
+ if (client) {
124
+ const data = {
125
+ type: "unsubscribe",
126
+ uuid
127
+ };
128
+ this.removeClientByUUID(uuid);
129
+ this.sendTopic(client.webSocketSet, data);
130
+ return true;
131
+ }
132
+ return false;
133
+ }
134
+ sendAllDataByTarget({ target, body }) {
135
+ const clients = this.findAllClientsByTarget(target);
136
+ clients.forEach((it) => {
137
+ const data = {
138
+ state: "success",
139
+ target: it.target,
140
+ uuid: it.uuid,
141
+ body
142
+ };
143
+ this.sendTopic(it.webSocketSet, data);
144
+ });
145
+ return clients.length;
146
+ }
147
+ sendAllUnSubscribeByTarget({ target }) {
148
+ const clients = this.findAllClientsByTarget(target);
149
+ clients.forEach((it) => {
150
+ const data = {
151
+ type: "unsubscribe",
152
+ uuid: it.uuid
153
+ };
154
+ this.removeClientByUUID(it.uuid);
155
+ this.sendTopic(it.webSocketSet, data);
156
+ });
157
+ return clients.length;
158
+ }
159
+ sendEventDataByUUID({ uuid, event, body }, config) {
160
+ const client = this.findClientByUUID(uuid);
161
+ if (client) {
162
+ const eventUUID = RandomUtils.uuid4();
163
+ const eventTopic = {
164
+ type: "event",
165
+ uuid,
166
+ // target: client.target,
167
+ eventUUID,
168
+ event,
169
+ body
170
+ };
171
+ if (config.responseCallBack) {
172
+ this.addEventSubscribes(uuid, eventUUID, config.responseCallBack);
173
+ }
174
+ this.sendTopic(client.webSocketSet, eventTopic);
175
+ return eventUUID;
176
+ }
177
+ return void 0;
178
+ }
179
+ sendEventDataByUUIDPromise({ uuid, event, body }, config) {
180
+ return new Promise((resolve, reject) => {
181
+ let timeoutId;
182
+ let eventUUIDForCleanup;
183
+ if (config?.responseTimeout !== void 0) {
184
+ timeoutId = setTimeout(() => {
185
+ if (eventUUIDForCleanup) {
186
+ const subscriptions = this.eventSubscriptions.get(uuid);
187
+ if (subscriptions) {
188
+ subscriptions.delete(eventUUIDForCleanup);
189
+ if (subscriptions.size <= 0) {
190
+ this.eventSubscriptions.delete(uuid);
191
+ }
192
+ }
193
+ }
194
+ reject(new Error("WebSocket event response timeout for UUID: " + uuid));
195
+ }, config.responseTimeout);
196
+ }
197
+ const eventUUID = this.sendEventDataByUUID({ uuid, event, body }, {
198
+ responseCallBack: (data) => {
199
+ if (timeoutId)
200
+ clearTimeout(timeoutId);
201
+ resolve(data);
202
+ }
203
+ });
204
+ eventUUIDForCleanup = eventUUID;
205
+ if (!eventUUID) {
206
+ if (timeoutId)
207
+ clearTimeout(timeoutId);
208
+ reject(new Error("WebSocket client not found for UUID: " + uuid));
209
+ }
210
+ });
211
+ }
212
+ async sendEventDataByUUIDPromiseSettled({ uuid, event, body }, config) {
213
+ try {
214
+ const value = await this.sendEventDataByUUIDPromise({ uuid, event, body }, config);
215
+ return { status: "fulfilled", value };
216
+ } catch (reason) {
217
+ return { status: "rejected", reason };
218
+ }
219
+ }
220
+ sendAllEventDataByTargetPromise({ target, event, body }, config) {
221
+ const clients = this.findAllClientsByTarget(target);
222
+ const promises = clients.map((it) => {
223
+ return this.sendEventDataByUUIDPromise({ uuid: it.uuid, event, body }, config).then((result) => ({
224
+ body: result,
225
+ uuid: it.uuid
226
+ }));
227
+ });
228
+ return Promise.all(promises);
229
+ }
230
+ sendAllEventDataByTargetPromiseSettled({ target, event, body }, config) {
231
+ const clients = this.findAllClientsByTarget(target);
232
+ const promises = clients.map((it) => {
233
+ return this.sendEventDataByUUIDPromise({ uuid: it.uuid, event, body }, config).then((result) => ({
234
+ body: result,
235
+ uuid: it.uuid
236
+ }));
237
+ });
238
+ return Promise.allSettled(promises);
239
+ }
240
+ sendAllEventDataByTarget({ target, event, body }, config) {
241
+ const clients = this.findAllClientsByTarget(target);
242
+ clients.forEach((it) => {
243
+ const eventUUID = RandomUtils.uuid4();
244
+ const eventTopic = {
245
+ type: "event",
246
+ uuid: it.uuid,
247
+ // target: it.target,
248
+ eventUUID,
249
+ event,
250
+ body
251
+ };
252
+ if (config?.responseCallBack) {
253
+ this.addEventSubscribes(it.uuid, eventUUID, config?.responseCallBack);
254
+ }
255
+ this.sendTopic(it.webSocketSet, eventTopic);
256
+ });
257
+ return clients.length;
258
+ }
259
+ addEventSubscribes(uuid, eventUUID, eventResponseCallBack) {
260
+ let eventMap = this.eventSubscriptions.get(uuid);
261
+ if (eventMap) {
262
+ eventMap.set(eventUUID, eventResponseCallBack);
263
+ } else {
264
+ eventMap = /* @__PURE__ */ new Map();
265
+ eventMap.set(eventUUID, eventResponseCallBack);
266
+ this.eventSubscriptions.set(uuid, eventMap);
267
+ }
268
+ }
269
+ getOpenClients() {
270
+ return Array.from(this.clients.keys()).filter((it) => it.socket.readyState === WebSocket.OPEN);
271
+ }
272
+ isBinaryPayload(value) {
273
+ if (!value) {
274
+ return false;
275
+ }
276
+ if (Buffer.isBuffer(value)) {
277
+ return true;
278
+ }
279
+ if (typeof Uint8Array !== "undefined" && value instanceof Uint8Array) {
280
+ return true;
281
+ }
282
+ if (typeof ArrayBuffer !== "undefined" && value instanceof ArrayBuffer) {
283
+ return true;
284
+ }
285
+ if (value && typeof value === "object" && "buffer" in value) {
286
+ const bufferValue = value.buffer;
287
+ return Buffer.isBuffer(bufferValue) || bufferValue instanceof Uint8Array || bufferValue instanceof ArrayBuffer;
288
+ }
289
+ return false;
290
+ }
291
+ hasBinaryPayload(value) {
292
+ if (this.isBinaryPayload(value)) {
293
+ return true;
294
+ }
295
+ if (Array.isArray(value)) {
296
+ return value.some((item) => this.hasBinaryPayload(item));
297
+ }
298
+ if (value && typeof value === "object") {
299
+ return Object.keys(value).some((key) => this.hasBinaryPayload(value[key]));
300
+ }
301
+ return false;
302
+ }
303
+ buildBinaryTopic(topic) {
304
+ const fileRefs = /* @__PURE__ */ new Map();
305
+ const fileEntries = [];
306
+ let fileIndex = 0;
307
+ const registerFile = (value) => {
308
+ const existing = fileRefs.get(value);
309
+ if (existing) {
310
+ return existing;
311
+ }
312
+ const id = `f${++fileIndex}`;
313
+ fileRefs.set(value, id);
314
+ let name = "file";
315
+ let mime = "application/octet-stream";
316
+ let buffer = Buffer.alloc(0);
317
+ if (Buffer.isBuffer(value)) {
318
+ buffer = value;
319
+ } else if (value instanceof Uint8Array) {
320
+ buffer = Buffer.from(value);
321
+ } else if (value instanceof ArrayBuffer) {
322
+ buffer = Buffer.from(value);
323
+ } else if (value && typeof value === "object" && "buffer" in value) {
324
+ const fileLike = value;
325
+ if (typeof fileLike.name === "string") {
326
+ name = fileLike.name || name;
327
+ }
328
+ if (typeof fileLike.mime === "string") {
329
+ mime = fileLike.mime || mime;
330
+ }
331
+ const innerBuffer = fileLike.buffer;
332
+ if (Buffer.isBuffer(innerBuffer)) {
333
+ buffer = innerBuffer;
334
+ } else if (innerBuffer instanceof Uint8Array) {
335
+ buffer = Buffer.from(innerBuffer);
336
+ } else if (innerBuffer instanceof ArrayBuffer) {
337
+ buffer = Buffer.from(innerBuffer);
338
+ }
339
+ }
340
+ fileEntries.push({ id, name, mime, buffer });
341
+ return id;
342
+ };
343
+ const replaceFiles = (value) => {
344
+ if (this.isBinaryPayload(value)) {
345
+ const id = registerFile(value);
346
+ return { $file: id };
347
+ }
348
+ if (Array.isArray(value)) {
349
+ return value.map((item) => replaceFiles(item));
350
+ }
351
+ if (value && typeof value === "object") {
352
+ const result = {};
353
+ Object.keys(value).forEach((key) => {
354
+ result[key] = replaceFiles(value[key]);
355
+ });
356
+ return result;
357
+ }
358
+ return value;
359
+ };
360
+ const payload = replaceFiles(topic.body);
361
+ let offset = 0;
362
+ const files = fileEntries.map((entry) => {
363
+ const size = entry.buffer.length;
364
+ const meta2 = {
365
+ id: entry.id,
366
+ name: entry.name,
367
+ mime: entry.mime,
368
+ size,
369
+ offset
370
+ };
371
+ offset += size;
372
+ return meta2;
373
+ });
374
+ const meta = { ...topic, body: payload, files };
375
+ const json = Buffer.from(JSON.stringify(meta), "utf8");
376
+ const header = Buffer.alloc(4);
377
+ header.writeUInt32LE(json.length, 0);
378
+ const buffers = [header, json, ...fileEntries.map((entry) => entry.buffer)];
379
+ return Buffer.concat(buffers);
380
+ }
381
+ sendTopic(wsSet, topic) {
382
+ if (this.hasBinaryPayload(topic?.body)) {
383
+ const buffer = this.buildBinaryTopic(topic);
384
+ wsSet.socket.send(buffer, { binary: true });
385
+ return;
386
+ }
387
+ wsSet.socket.send(JSON.stringify(topic), { binary: false });
388
+ }
389
+ parseBinaryTopic(data) {
390
+ let buffer;
391
+ if (Buffer.isBuffer(data)) {
392
+ buffer = data;
393
+ } else if (data instanceof ArrayBuffer) {
394
+ buffer = Buffer.from(data);
395
+ } else if (Array.isArray(data)) {
396
+ buffer = Buffer.concat(data.map((item) => Buffer.isBuffer(item) ? item : Buffer.from(item)));
397
+ } else {
398
+ return void 0;
399
+ }
400
+ if (buffer.length < 4) {
401
+ return void 0;
402
+ }
403
+ const jsonLength = buffer.readUInt32LE(0);
404
+ const jsonStart = 4;
405
+ const jsonEnd = jsonStart + jsonLength;
406
+ if (buffer.length < jsonEnd) {
407
+ return void 0;
408
+ }
409
+ const jsonText = buffer.slice(jsonStart, jsonEnd).toString("utf8");
410
+ let meta;
411
+ try {
412
+ meta = JSON.parse(jsonText);
413
+ } catch (error) {
414
+ console.warn("Invalid WebSocket binary payload:", error);
415
+ return void 0;
416
+ }
417
+ const filesMeta = Array.isArray(meta.files) ? meta.files : [];
418
+ const fileMap = /* @__PURE__ */ new Map();
419
+ filesMeta.forEach((file) => {
420
+ if (!file || typeof file.id !== "string" || typeof file.size !== "number" || typeof file.offset !== "number") {
421
+ return;
422
+ }
423
+ const start = jsonEnd + file.offset;
424
+ const end = start + file.size;
425
+ if (start < jsonEnd || end > buffer.length) {
426
+ return;
427
+ }
428
+ const slice = buffer.slice(start, end);
429
+ fileMap.set(file.id, {
430
+ name: file.name || "file",
431
+ mime: file.mime || "application/octet-stream",
432
+ size: file.size,
433
+ buffer: slice
434
+ });
435
+ });
436
+ const replaceFileRefs = (value) => {
437
+ if (value && typeof value === "object" && "$file" in value && typeof value.$file === "string") {
438
+ const file = fileMap.get(value.$file);
439
+ if (file) {
440
+ return file;
441
+ }
442
+ }
443
+ if (Array.isArray(value)) {
444
+ return value.map((item) => replaceFileRefs(item));
445
+ }
446
+ if (value && typeof value === "object") {
447
+ const result = {};
448
+ Object.keys(value).forEach((key) => {
449
+ result[key] = replaceFileRefs(value[key]);
450
+ });
451
+ return result;
452
+ }
453
+ return value;
454
+ };
455
+ const body = replaceFileRefs(meta.body);
456
+ return {
457
+ type: meta.type,
458
+ uuid: meta.uuid,
459
+ requestUUID: meta.requestUUID,
460
+ body
461
+ };
462
+ }
463
+ message(wsSet, data) {
464
+ let topic;
465
+ if (data.isBinary) {
466
+ topic = this.parseBinaryTopic(data.data);
467
+ if (!topic) {
468
+ return;
469
+ }
470
+ } else {
471
+ try {
472
+ topic = JSON.parse(data.data.toString());
473
+ } catch (error) {
474
+ console.warn("Invalid WebSocket payload:", error);
475
+ return;
476
+ }
477
+ }
478
+ this.subject.next(topic);
479
+ const uuid = topic.uuid;
480
+ if (topic.type === "subscribe") {
481
+ try {
482
+ this.setClientTopic(wsSet, topic.uuid, topic.target, topic.body);
483
+ } catch (err) {
484
+ const responseTopic = {
485
+ state: "error",
486
+ // type: topic.type,
487
+ target: topic.target,
488
+ uuid: topic.uuid,
489
+ body: { message: err.message || "Error subscribing topic" }
490
+ };
491
+ wsSet.socket.send(JSON.stringify(responseTopic), { binary: false });
492
+ }
493
+ return;
494
+ } else if (topic.type === "unsubscribe") {
495
+ this.removeClientByUUID(uuid);
496
+ return;
497
+ } else if (topic.type === "event") {
498
+ const subscriptions = this.eventSubscriptions.get(topic.uuid);
499
+ if (subscriptions) {
500
+ const eventCallback = subscriptions.get(topic.eventUUID);
501
+ if (eventCallback) {
502
+ eventCallback(topic.body, wsSet);
503
+ subscriptions.delete(topic.eventUUID);
504
+ }
505
+ if (subscriptions.size <= 0) {
506
+ this.eventSubscriptions.delete(topic.uuid);
507
+ }
508
+ }
509
+ return;
510
+ } else {
511
+ const clientTopics = this.findClientByUUID(uuid);
512
+ if (!clientTopics) {
513
+ const responseTopic = {
514
+ state: "error",
515
+ uuid: topic.uuid,
516
+ requestUUID: topic.requestUUID,
517
+ target: "",
518
+ body: { message: "WebSocket client not registered" }
519
+ };
520
+ this.sendTopic(wsSet, responseTopic);
521
+ return;
522
+ }
523
+ const intent = new Intent(clientTopics.target);
524
+ const webSocketRequest = {
525
+ webSocketSet: wsSet,
526
+ uuid: clientTopics.uuid,
527
+ webSocketManager: this,
528
+ sendEvent: (event, body, config) => this.sendEventDataByUUIDPromise({ uuid: clientTopics.uuid, event, body }, config)
529
+ };
530
+ intent.data = [topic.body, webSocketRequest];
531
+ if (topic.type === "intent") {
532
+ this.intentManager.publishMeta(intent).then(async (it) => {
533
+ if (it.target.length <= 0) {
534
+ const responseTopic = {
535
+ state: "error",
536
+ // type: topic.type,
537
+ target: clientTopics.target,
538
+ uuid: topic.uuid,
539
+ requestUUID: topic.requestUUID,
540
+ body: { message: "Not found intent target" }
541
+ };
542
+ this.sendTopic(wsSet, responseTopic);
543
+ } else {
544
+ const rdata = it.return[0];
545
+ const wdata = rdata instanceof Promise ? await rdata : rdata;
546
+ const responseTopic = {
547
+ state: "success",
548
+ uuid: topic.uuid,
549
+ requestUUID: topic.requestUUID,
550
+ target: clientTopics.target,
551
+ body: wdata
552
+ };
553
+ this.sendTopic(wsSet, responseTopic);
554
+ }
555
+ });
556
+ } else if (topic.type === "router") {
557
+ this.routerManager.routing(intent).then(async (routerModule) => {
558
+ const moduleInstance = routerModule.getModuleInstance?.();
559
+ if (routerModule && moduleInstance) {
560
+ if (routerModule.propertyKeys) {
561
+ for (const it of routerModule.propertyKeys) {
562
+ let r = moduleInstance[it]?.(topic.body, webSocketRequest);
563
+ r = r instanceof Promise ? await r : r;
564
+ const responseTopic = {
565
+ state: "success",
566
+ requestUUID: topic.requestUUID,
567
+ uuid: topic.uuid,
568
+ target: clientTopics.target,
569
+ body: r
570
+ };
571
+ this.sendTopic(wsSet, responseTopic);
572
+ }
573
+ } else {
574
+ const responseTopic = {
575
+ state: "error",
576
+ uuid: topic.uuid,
577
+ requestUUID: topic.requestUUID,
578
+ target: clientTopics.target,
579
+ body: { message: "Not found router target" }
580
+ };
581
+ this.sendTopic(wsSet, responseTopic);
582
+ }
583
+ } else {
584
+ const responseTopic = {
585
+ state: "error",
586
+ uuid: topic.uuid,
587
+ requestUUID: topic.requestUUID,
588
+ target: clientTopics.target,
589
+ body: { message: "Not found router target" }
590
+ };
591
+ this.sendTopic(wsSet, responseTopic);
592
+ }
593
+ });
594
+ }
595
+ }
596
+ }
597
+ removeAllClientsByWebSocketSet(wsSet) {
598
+ const topics = this.clients.get(wsSet);
599
+ if (!topics) {
600
+ return;
601
+ }
602
+ for (const topic of topics) {
603
+ this.eventSubscriptions.delete(topic.uuid);
604
+ }
605
+ this.clients.set(wsSet, []);
606
+ }
607
+ };
608
+ WebSocketManager = __decorate([
609
+ Sim,
610
+ __metadata("design:paramtypes", [typeof (_a = typeof IntentManager !== "undefined" && IntentManager) === "function" ? _a : Object, typeof (_b = typeof RouterManager !== "undefined" && RouterManager) === "function" ? _b : Object])
611
+ ], WebSocketManager);
612
+ export {
613
+ WebSocketManager,
614
+ isTopicRequest,
615
+ isTopicResponse,
616
+ isTopicServerEventRequest,
617
+ isTopicServerEventResponse,
618
+ isTopicServerEventUnSubscribeRequest,
619
+ isTopicSubscribeRequest,
620
+ isTopicUnsubscribeRequest
621
+ };
622
+ //# sourceMappingURL=WebSocketManager.js.map