@module-federation/dts-plugin 2.0.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/dist/Action-CzhPMw2i.js +153 -0
  2. package/dist/Broker-DRlzScTT.js +800 -0
  3. package/dist/CHANGELOG.md +26 -0
  4. package/dist/DtsWorker-Dtem3-FM.d.ts +166 -0
  5. package/dist/constant-BwEkyidO.d.ts +42 -0
  6. package/dist/consumeTypes-AD2ig87l.js +237 -0
  7. package/dist/core.d.ts +3 -68
  8. package/dist/core.js +26 -2380
  9. package/dist/dynamic-remote-type-hints-plugin.d.ts +622 -3
  10. package/dist/dynamic-remote-type-hints-plugin.js +65 -187
  11. package/dist/esm/Action-DNNg2YDh.mjs +47 -0
  12. package/dist/esm/Broker-BU4gToNr.mjs +736 -0
  13. package/dist/esm/consumeTypes-D51rVbSt.mjs +204 -0
  14. package/dist/esm/core.mjs +5 -0
  15. package/dist/esm/dynamic-remote-type-hints-plugin.mjs +73 -0
  16. package/dist/esm/expose-rpc-DMhY1i8A.mjs +1301 -0
  17. package/dist/esm/fork-dev-worker.mjs +103 -0
  18. package/dist/esm/fork-generate-dts.mjs +14 -0
  19. package/dist/esm/index.mjs +465 -0
  20. package/dist/esm/start-broker.mjs +22 -0
  21. package/dist/esm/utils-CkPvDGOy.mjs +13 -0
  22. package/dist/expose-rpc-BLAH20uj.js +1415 -0
  23. package/dist/fork-dev-worker.d.ts +10 -9
  24. package/dist/fork-dev-worker.js +100 -2869
  25. package/dist/fork-generate-dts.d.ts +4 -8
  26. package/dist/fork-generate-dts.js +11 -2040
  27. package/dist/iife/launch-web-client.iife.js +117 -0
  28. package/dist/index.d.ts +57 -46
  29. package/dist/index.js +449 -2980
  30. package/dist/package.json +27 -12
  31. package/dist/start-broker.d.ts +41 -39
  32. package/dist/start-broker.js +17 -952
  33. package/dist/utils-7KqCZHbb.js +19 -0
  34. package/package.json +32 -17
  35. package/dist/DTSManager-b15Gfat3.d.ts +0 -53
  36. package/dist/DTSManagerOptions-QVchWb0x.d.ts +0 -32
  37. package/dist/DtsWorker-BrHsGz8C.d.ts +0 -56
  38. package/dist/core.d.mts +0 -68
  39. package/dist/dynamic-remote-type-hints-plugin.d.mts +0 -5
  40. package/dist/esm/chunk-647HGGGS.js +0 -241
  41. package/dist/esm/chunk-G65LOFTY.js +0 -24
  42. package/dist/esm/chunk-N7GTIQUA.js +0 -282
  43. package/dist/esm/chunk-RWXNVNFM.js +0 -1579
  44. package/dist/esm/chunk-WWV5RWOP.js +0 -902
  45. package/dist/esm/core.js +0 -44
  46. package/dist/esm/dynamic-remote-type-hints-plugin.js +0 -73
  47. package/dist/esm/fork-dev-worker.js +0 -145
  48. package/dist/esm/fork-generate-dts.js +0 -27
  49. package/dist/esm/index.js +0 -646
  50. package/dist/esm/start-broker.js +0 -36
  51. package/dist/fork-dev-worker.d.mts +0 -15
  52. package/dist/fork-generate-dts.d.mts +0 -10
  53. package/dist/iife/launch-web-client.js +0 -152
  54. package/dist/index.d.mts +0 -56
  55. package/dist/start-broker.d.mts +0 -42
  56. package/dist/utils-C4sQemLR.d.ts +0 -15
@@ -0,0 +1,736 @@
1
+ import { a as MF_SERVER_IDENTIFIER, c as WEB_SOCKET_CONNECT_MAGIC_ID, i as DEFAULT_WEB_SOCKET_PORT, l as Message, n as ActionKind, o as UpdateMode } from "./Action-DNNg2YDh.mjs";
2
+ import { createServer } from "http";
3
+ import { SEPARATOR, createLogger } from "@module-federation/sdk";
4
+ import net from "net";
5
+ import "chalk";
6
+ import * as log4js from "log4js";
7
+ import os from "os";
8
+ import WebSocket from "isomorphic-ws";
9
+ import schedule from "node-schedule";
10
+ import { parse } from "url";
11
+
12
+ //#region src/server/message/API/API.ts
13
+ let APIKind = /* @__PURE__ */ function(APIKind) {
14
+ APIKind["UPDATE_SUBSCRIBER"] = "UPDATE_SUBSCRIBER";
15
+ APIKind["RELOAD_WEB_CLIENT"] = "RELOAD_WEB_CLIENT";
16
+ APIKind["FETCH_TYPES"] = "FETCH_TYPES";
17
+ return APIKind;
18
+ }({});
19
+ var API = class extends Message {
20
+ constructor(content, kind) {
21
+ super("API", kind);
22
+ const { code, payload } = content;
23
+ this.code = code;
24
+ this.payload = payload;
25
+ }
26
+ };
27
+
28
+ //#endregion
29
+ //#region src/server/message/API/UpdateSubscriber.ts
30
+ var UpdateSubscriberAPI = class extends API {
31
+ constructor(payload) {
32
+ super({
33
+ code: 0,
34
+ payload
35
+ }, APIKind.UPDATE_SUBSCRIBER);
36
+ }
37
+ };
38
+
39
+ //#endregion
40
+ //#region src/server/message/API/ReloadWebClient.ts
41
+ var ReloadWebClientAPI = class extends API {
42
+ constructor(payload) {
43
+ super({
44
+ code: 0,
45
+ payload
46
+ }, APIKind.RELOAD_WEB_CLIENT);
47
+ }
48
+ };
49
+
50
+ //#endregion
51
+ //#region src/server/message/API/FetchTypes.ts
52
+ var FetchTypesAPI = class extends API {
53
+ constructor(payload) {
54
+ super({
55
+ code: 0,
56
+ payload
57
+ }, APIKind.FETCH_TYPES);
58
+ }
59
+ };
60
+
61
+ //#endregion
62
+ //#region src/server/message/Log/Log.ts
63
+ let LogLevel = /* @__PURE__ */ function(LogLevel) {
64
+ LogLevel["LOG"] = "LOG";
65
+ LogLevel["WARN"] = "WARN";
66
+ LogLevel["ERROR"] = "ERROR";
67
+ return LogLevel;
68
+ }({});
69
+ let LogKind = /* @__PURE__ */ function(LogKind) {
70
+ LogKind["BrokerExitLog"] = "BrokerExitLog";
71
+ LogKind["PublisherRegisteredLog"] = "PublisherRegisteredLog";
72
+ return LogKind;
73
+ }({});
74
+ var Log = class extends Message {
75
+ constructor(level, kind, ignoreVerbose = false) {
76
+ super("Log", kind);
77
+ this.ignoreVerbose = false;
78
+ this.level = level;
79
+ this.ignoreVerbose = ignoreVerbose;
80
+ }
81
+ };
82
+
83
+ //#endregion
84
+ //#region src/server/message/Log/BrokerExitLog.ts
85
+ var BrokerExitLog = class extends Log {
86
+ constructor() {
87
+ super(LogLevel.LOG, LogKind.BrokerExitLog);
88
+ }
89
+ };
90
+
91
+ //#endregion
92
+ //#region src/server/utils/log.ts
93
+ const logger$1 = createLogger(`[ ${MF_SERVER_IDENTIFIER} ]`);
94
+ function fileLog(msg, module, level) {
95
+ if (!process?.env?.["FEDERATION_DEBUG"]) return;
96
+ log4js.configure({
97
+ appenders: {
98
+ [module]: {
99
+ type: "file",
100
+ filename: ".mf/typesGenerate.log"
101
+ },
102
+ default: {
103
+ type: "file",
104
+ filename: ".mf/typesGenerate.log"
105
+ }
106
+ },
107
+ categories: {
108
+ [module]: {
109
+ appenders: [module],
110
+ level: "error"
111
+ },
112
+ default: {
113
+ appenders: ["default"],
114
+ level: "trace"
115
+ }
116
+ }
117
+ });
118
+ const logger4 = log4js.getLogger(module);
119
+ logger4.level = "debug";
120
+ logger4[level]?.(msg);
121
+ }
122
+ function error(error, action, from) {
123
+ const err = error instanceof Error ? error : /* @__PURE__ */ new Error(`${action} error`);
124
+ fileLog(`[${action}] error: ${err}`, from, "fatal");
125
+ return err.toString();
126
+ }
127
+
128
+ //#endregion
129
+ //#region src/server/utils/getIPV4.ts
130
+ const localIpv4 = "127.0.0.1";
131
+ const getIpv4Interfaces = () => {
132
+ try {
133
+ const interfaces = os.networkInterfaces();
134
+ const ipv4Interfaces = [];
135
+ Object.values(interfaces).forEach((detail) => {
136
+ detail?.forEach((detail) => {
137
+ const familyV4Value = typeof detail.family === "string" ? "IPv4" : 4;
138
+ if (detail.family === familyV4Value && detail.address !== localIpv4) ipv4Interfaces.push(detail);
139
+ });
140
+ });
141
+ return ipv4Interfaces;
142
+ } catch (_err) {
143
+ return [];
144
+ }
145
+ };
146
+ const getIPV4 = () => {
147
+ return (getIpv4Interfaces()[0] || { address: localIpv4 }).address;
148
+ };
149
+
150
+ //#endregion
151
+ //#region src/server/utils/index.ts
152
+ function getIdentifier(options) {
153
+ const { ip, name } = options;
154
+ return `mf ${SEPARATOR}${name}${ip ? `${SEPARATOR}${ip}` : ""}`;
155
+ }
156
+ function fib(n) {
157
+ let i = 2;
158
+ const res = [
159
+ 0,
160
+ 1,
161
+ 1
162
+ ];
163
+ while (i <= n) {
164
+ res[i] = res[i - 1] + res[i - 2];
165
+ i++;
166
+ }
167
+ return res[n];
168
+ }
169
+ function getFreePort() {
170
+ return new Promise((resolve, reject) => {
171
+ const server = net.createServer();
172
+ server.unref();
173
+ server.on("error", reject);
174
+ server.listen(0, () => {
175
+ const { port } = server.address();
176
+ server.close(() => {
177
+ resolve(port);
178
+ });
179
+ });
180
+ });
181
+ }
182
+
183
+ //#endregion
184
+ //#region src/server/Publisher.ts
185
+ var Publisher = class {
186
+ constructor(ctx) {
187
+ this._name = ctx.name;
188
+ this._ip = ctx.ip;
189
+ this._remoteTypeTarPath = ctx.remoteTypeTarPath;
190
+ this._subscribers = /* @__PURE__ */ new Map();
191
+ this._ws = ctx.ws;
192
+ this.dynamicRemoteMap = /* @__PURE__ */ new Map();
193
+ }
194
+ get identifier() {
195
+ return getIdentifier({
196
+ name: this._name,
197
+ ip: this._ip
198
+ });
199
+ }
200
+ get name() {
201
+ return this._name;
202
+ }
203
+ get ip() {
204
+ return this._ip;
205
+ }
206
+ get remoteTypeTarPath() {
207
+ return this._remoteTypeTarPath;
208
+ }
209
+ get hasSubscribes() {
210
+ return Boolean(this._subscribers.size);
211
+ }
212
+ get subscribers() {
213
+ return this._subscribers;
214
+ }
215
+ addSubscriber(identifier, subscriber) {
216
+ fileLog(`${this.name} set subscriber: ${identifier}`, "Publisher", "info");
217
+ this._subscribers.set(identifier, subscriber);
218
+ }
219
+ removeSubscriber(identifier) {
220
+ if (this._subscribers.has(identifier)) {
221
+ fileLog(`${this.name} removeSubscriber: ${identifier}`, "Publisher", "warn");
222
+ this._subscribers.delete(identifier);
223
+ }
224
+ }
225
+ notifySubscriber(subscriberIdentifier, options) {
226
+ const subscriber = this._subscribers.get(subscriberIdentifier);
227
+ if (!subscriber) {
228
+ fileLog(`[notifySubscriber] ${this.name} notifySubscriber: ${subscriberIdentifier}, does not exits`, "Publisher", "error");
229
+ return;
230
+ }
231
+ const api = new UpdateSubscriberAPI(options);
232
+ subscriber.send(JSON.stringify(api));
233
+ fileLog(`[notifySubscriber] ${this.name} notifySubscriber: ${JSON.stringify(subscriberIdentifier)}, message: ${JSON.stringify(api)}`, "Publisher", "info");
234
+ }
235
+ fetchRemoteTypes(options) {
236
+ fileLog(`[fetchRemoteTypes] ${this.name} fetchRemoteTypes, options: ${JSON.stringify(options)}, ws: ${Boolean(this._ws)}`, "Publisher", "info");
237
+ if (!this._ws) return;
238
+ const api = new FetchTypesAPI(options);
239
+ this._ws.send(JSON.stringify(api));
240
+ }
241
+ notifySubscribers(options) {
242
+ const api = new UpdateSubscriberAPI(options);
243
+ this.broadcast(api);
244
+ }
245
+ broadcast(message) {
246
+ if (this.hasSubscribes) this._subscribers.forEach((subscriber, key) => {
247
+ fileLog(`[BroadCast] ${this.name} notifySubscriber: ${key}, PID: ${process.pid}, message: ${JSON.stringify(message)}`, "Publisher", "info");
248
+ subscriber.send(JSON.stringify(message));
249
+ });
250
+ else fileLog(`[BroadCast] ${this.name}'s subscribe is empty`, "Publisher", "warn");
251
+ }
252
+ close() {
253
+ this._ws = void 0;
254
+ this._subscribers.forEach((_subscriber, identifier) => {
255
+ fileLog(`[BroadCast] close ${this.name} remove: ${identifier}`, "Publisher", "warn");
256
+ this.removeSubscriber(identifier);
257
+ });
258
+ }
259
+ };
260
+
261
+ //#endregion
262
+ //#region src/server/message/Action/Update.ts
263
+ let UpdateKind = /* @__PURE__ */ function(UpdateKind) {
264
+ UpdateKind["UPDATE_TYPE"] = "UPDATE_TYPE";
265
+ UpdateKind["RELOAD_PAGE"] = "RELOAD_PAGE";
266
+ return UpdateKind;
267
+ }({});
268
+
269
+ //#endregion
270
+ //#region src/server/broker/Broker.ts
271
+ var Broker = class Broker {
272
+ static {
273
+ this.WEB_SOCKET_CONNECT_MAGIC_ID = WEB_SOCKET_CONNECT_MAGIC_ID;
274
+ }
275
+ static {
276
+ this.DEFAULT_WEB_SOCKET_PORT = DEFAULT_WEB_SOCKET_PORT;
277
+ }
278
+ static {
279
+ this.DEFAULT_SECURE_WEB_SOCKET_PORT = 16324;
280
+ }
281
+ static {
282
+ this.DEFAULT_WAITING_TIME = 1.5 * 60 * 60 * 1e3;
283
+ }
284
+ constructor() {
285
+ this._publisherMap = /* @__PURE__ */ new Map();
286
+ this._webClientMap = /* @__PURE__ */ new Map();
287
+ this._tmpSubscriberShelter = /* @__PURE__ */ new Map();
288
+ this._scheduleJob = null;
289
+ this._setSchedule();
290
+ this._startWsServer();
291
+ this._stopWhenSIGTERMOrSIGINT();
292
+ this._handleUnexpectedExit();
293
+ }
294
+ get hasPublishers() {
295
+ return Boolean(this._publisherMap.size);
296
+ }
297
+ async _startWsServer() {
298
+ const wsHandler = (ws, req) => {
299
+ const { url: reqUrl = "" } = req;
300
+ const { query } = parse(reqUrl, true);
301
+ const { WEB_SOCKET_CONNECT_MAGIC_ID } = query;
302
+ if (WEB_SOCKET_CONNECT_MAGIC_ID === Broker.WEB_SOCKET_CONNECT_MAGIC_ID) {
303
+ ws.on("message", (message) => {
304
+ try {
305
+ const text = message.toString();
306
+ const action = JSON.parse(text);
307
+ fileLog(`${action?.kind} action received `, "Broker", "info");
308
+ this._takeAction(action, ws);
309
+ } catch (error) {
310
+ fileLog(`parse action message error: ${error}`, "Broker", "error");
311
+ }
312
+ });
313
+ ws.on("error", (e) => {
314
+ fileLog(`parse action message error: ${e}`, "Broker", "error");
315
+ });
316
+ } else {
317
+ ws.send("Invalid CONNECT ID.");
318
+ fileLog("Invalid CONNECT ID.", "Broker", "warn");
319
+ ws.close();
320
+ }
321
+ };
322
+ const server = createServer();
323
+ this._webSocketServer = new WebSocket.Server({ noServer: true });
324
+ this._webSocketServer.on("error", (err) => {
325
+ fileLog(`ws error: \n${err.message}\n ${err.stack}`, "Broker", "error");
326
+ });
327
+ this._webSocketServer.on("listening", () => {
328
+ fileLog(`WebSocket server is listening on port ${Broker.DEFAULT_WEB_SOCKET_PORT}`, "Broker", "info");
329
+ });
330
+ this._webSocketServer.on("connection", wsHandler);
331
+ this._webSocketServer.on("close", (code) => {
332
+ fileLog(`WebSocket Server Close with Code ${code}`, "Broker", "warn");
333
+ this._webSocketServer && this._webSocketServer.close();
334
+ this._webSocketServer = void 0;
335
+ });
336
+ server.on("upgrade", (req, socket, head) => {
337
+ if (req.url) {
338
+ const { pathname } = parse(req.url);
339
+ if (pathname === "/") this._webSocketServer?.handleUpgrade(req, socket, head, (ws) => {
340
+ this._webSocketServer?.emit("connection", ws, req);
341
+ });
342
+ }
343
+ });
344
+ server.listen(Broker.DEFAULT_WEB_SOCKET_PORT);
345
+ }
346
+ async _takeAction(action, client) {
347
+ const { kind, payload } = action;
348
+ if (kind === ActionKind.ADD_PUBLISHER) await this._addPublisher(payload, client);
349
+ if (kind === ActionKind.UPDATE_PUBLISHER) await this._updatePublisher(payload, client);
350
+ if (kind === ActionKind.ADD_SUBSCRIBER) await this._addSubscriber(payload, client);
351
+ if (kind === ActionKind.EXIT_SUBSCRIBER) await this._removeSubscriber(payload, client);
352
+ if (kind === ActionKind.EXIT_PUBLISHER) await this._removePublisher(payload, client);
353
+ if (kind === ActionKind.ADD_WEB_CLIENT) await this._addWebClient(payload, client);
354
+ if (kind === ActionKind.NOTIFY_WEB_CLIENT) await this._notifyWebClient(payload, client);
355
+ if (kind === ActionKind.FETCH_TYPES) await this._fetchTypes(payload, client);
356
+ if (kind === ActionKind.ADD_DYNAMIC_REMOTE) this._addDynamicRemote(payload);
357
+ }
358
+ async _addPublisher(context, client) {
359
+ const { name, ip, remoteTypeTarPath } = context ?? {};
360
+ const identifier = getIdentifier({
361
+ name,
362
+ ip
363
+ });
364
+ if (this._publisherMap.has(identifier)) {
365
+ fileLog(`[${ActionKind.ADD_PUBLISHER}] ${identifier} has been added, this action will be ignored`, "Broker", "warn");
366
+ return;
367
+ }
368
+ try {
369
+ const publisher = new Publisher({
370
+ name,
371
+ ip,
372
+ remoteTypeTarPath,
373
+ ws: client
374
+ });
375
+ this._publisherMap.set(identifier, publisher);
376
+ fileLog(`[${ActionKind.ADD_PUBLISHER}] ${identifier} Adding Publisher Succeed`, "Broker", "info");
377
+ const tmpSubScribers = this._getTmpSubScribers(identifier);
378
+ if (tmpSubScribers) {
379
+ fileLog(`[${ActionKind.ADD_PUBLISHER}] consumeTmpSubscriber set ${publisher.name}’s subscribers `, "Broker", "info");
380
+ this._consumeTmpSubScribers(publisher, tmpSubScribers);
381
+ this._clearTmpSubScriberRelation(identifier);
382
+ }
383
+ } catch (err) {
384
+ const msg = error(err, ActionKind.ADD_PUBLISHER, "Broker");
385
+ client.send(msg);
386
+ client.close();
387
+ }
388
+ }
389
+ async _updatePublisher(context, client) {
390
+ const { name, updateMode, updateKind, updateSourcePaths, remoteTypeTarPath, ip } = context ?? {};
391
+ const identifier = getIdentifier({
392
+ name,
393
+ ip
394
+ });
395
+ if (!this._publisherMap.has(identifier)) {
396
+ fileLog(`[${ActionKind.UPDATE_PUBLISHER}] ${identifier} has not been started, this action will be ignored
397
+ this._publisherMap: ${JSON.stringify(this._publisherMap.entries())}
398
+ `, "Broker", "warn");
399
+ return;
400
+ }
401
+ try {
402
+ const publisher = this._publisherMap.get(identifier);
403
+ fileLog(`[${ActionKind.UPDATE_PUBLISHER}] ${identifier} update, and notify subscribers to update`, "Broker", "info");
404
+ if (publisher) {
405
+ publisher.notifySubscribers({
406
+ remoteTypeTarPath,
407
+ name,
408
+ updateMode,
409
+ updateKind,
410
+ updateSourcePaths: updateSourcePaths || []
411
+ });
412
+ this._publisherMap.forEach((p) => {
413
+ if (p.name === publisher.name) return;
414
+ const dynamicRemoteInfo = p.dynamicRemoteMap.get(identifier);
415
+ if (dynamicRemoteInfo) {
416
+ fileLog(`dynamicRemoteInfo: ${JSON.stringify(dynamicRemoteInfo)}, identifier:${identifier} publish: ${p.name}`, "Broker", "info");
417
+ p.fetchRemoteTypes({
418
+ remoteInfo: dynamicRemoteInfo,
419
+ once: false
420
+ });
421
+ }
422
+ });
423
+ }
424
+ } catch (err) {
425
+ const msg = error(err, ActionKind.UPDATE_PUBLISHER, "Broker");
426
+ client.send(msg);
427
+ client.close();
428
+ }
429
+ }
430
+ async _fetchTypes(context, _client) {
431
+ const { name, ip, remoteInfo } = context ?? {};
432
+ const identifier = getIdentifier({
433
+ name,
434
+ ip
435
+ });
436
+ try {
437
+ const publisher = this._publisherMap.get(identifier);
438
+ fileLog(`[${ActionKind.FETCH_TYPES}] ${identifier} fetch types`, "Broker", "info");
439
+ if (publisher) publisher.fetchRemoteTypes({
440
+ remoteInfo,
441
+ once: true
442
+ });
443
+ } catch (err) {
444
+ fileLog(`[${ActionKind.FETCH_TYPES}] ${identifier} fetch types fail , error info: ${err}`, "Broker", "error");
445
+ }
446
+ }
447
+ _addDynamicRemote(context) {
448
+ const { name, ip, remoteInfo, remoteIp } = context ?? {};
449
+ const identifier = getIdentifier({
450
+ name,
451
+ ip
452
+ });
453
+ const publisher = this._publisherMap.get(identifier);
454
+ const remoteId = getIdentifier({
455
+ name: remoteInfo.name,
456
+ ip: remoteIp
457
+ });
458
+ fileLog(`[${ActionKind.ADD_DYNAMIC_REMOTE}] identifier:${identifier},publisher: ${publisher.name}, remoteId:${remoteId}`, "Broker", "error");
459
+ if (!publisher || publisher.dynamicRemoteMap.has(remoteId)) return;
460
+ publisher.dynamicRemoteMap.set(remoteId, remoteInfo);
461
+ }
462
+ async _addSubscriber(context, client) {
463
+ const { publishers, name: subscriberName } = context ?? {};
464
+ publishers.forEach((publisher) => {
465
+ const { name, ip } = publisher;
466
+ const identifier = getIdentifier({
467
+ name,
468
+ ip
469
+ });
470
+ if (!this._publisherMap.has(identifier)) {
471
+ fileLog(`[${ActionKind.ADD_SUBSCRIBER}]: ${identifier} has not been started, ${subscriberName} will add the relation to tmp shelter`, "Broker", "warn");
472
+ this._addTmpSubScriberRelation({
473
+ name: getIdentifier({
474
+ name: context.name,
475
+ ip: context.ip
476
+ }),
477
+ client
478
+ }, publisher);
479
+ return;
480
+ }
481
+ try {
482
+ const registeredPublisher = this._publisherMap.get(identifier);
483
+ if (registeredPublisher) {
484
+ registeredPublisher.addSubscriber(getIdentifier({
485
+ name: subscriberName,
486
+ ip: context.ip
487
+ }), client);
488
+ fileLog(`[${ActionKind.ADD_SUBSCRIBER}]: ${identifier} has been started, Adding Subscriber ${subscriberName} Succeed, this.__publisherMap are: ${JSON.stringify(Array.from(this._publisherMap.entries()))}`, "Broker", "info");
489
+ registeredPublisher.notifySubscriber(getIdentifier({
490
+ name: subscriberName,
491
+ ip: context.ip
492
+ }), {
493
+ updateKind: UpdateKind.UPDATE_TYPE,
494
+ updateMode: UpdateMode.PASSIVE,
495
+ updateSourcePaths: [registeredPublisher.name],
496
+ remoteTypeTarPath: registeredPublisher.remoteTypeTarPath,
497
+ name: registeredPublisher.name
498
+ });
499
+ fileLog(`[${ActionKind.ADD_SUBSCRIBER}]: notifySubscriber Subscriber ${subscriberName}, updateMode: "PASSIVE", updateSourcePaths: ${registeredPublisher.name}`, "Broker", "info");
500
+ }
501
+ } catch (err) {
502
+ const msg = error(err, ActionKind.ADD_SUBSCRIBER, "Broker");
503
+ client.send(msg);
504
+ client.close();
505
+ }
506
+ });
507
+ }
508
+ async _removeSubscriber(context, client) {
509
+ const { publishers } = context ?? {};
510
+ const subscriberIdentifier = getIdentifier({
511
+ name: context?.name,
512
+ ip: context?.ip
513
+ });
514
+ publishers.forEach((publisher) => {
515
+ const { name, ip } = publisher;
516
+ const identifier = getIdentifier({
517
+ name,
518
+ ip
519
+ });
520
+ const registeredPublisher = this._publisherMap.get(identifier);
521
+ if (!registeredPublisher) {
522
+ fileLog(`[${ActionKind.EXIT_SUBSCRIBER}], ${identifier} does not exit `, "Broker", "warn");
523
+ return;
524
+ }
525
+ try {
526
+ fileLog(`[${ActionKind.EXIT_SUBSCRIBER}], ${identifier} will exit `, "Broker", "INFO");
527
+ registeredPublisher.removeSubscriber(subscriberIdentifier);
528
+ this._clearTmpSubScriberRelation(identifier);
529
+ if (!registeredPublisher.hasSubscribes) this._publisherMap.delete(identifier);
530
+ if (!this.hasPublishers) this.exit();
531
+ } catch (err) {
532
+ const msg = error(err, ActionKind.EXIT_SUBSCRIBER, "Broker");
533
+ client.send(msg);
534
+ client.close();
535
+ }
536
+ });
537
+ }
538
+ async _removePublisher(context, client) {
539
+ const { name, ip } = context ?? {};
540
+ const identifier = getIdentifier({
541
+ name,
542
+ ip
543
+ });
544
+ const publisher = this._publisherMap.get(identifier);
545
+ if (!publisher) {
546
+ fileLog(`[${ActionKind.EXIT_PUBLISHER}]: ${identifier}} has not been added, this action will be ingored`, "Broker", "warn");
547
+ return;
548
+ }
549
+ try {
550
+ const { subscribers } = publisher;
551
+ subscribers.forEach((subscriber, subscriberIdentifier) => {
552
+ this._addTmpSubScriberRelation({
553
+ name: subscriberIdentifier,
554
+ client: subscriber
555
+ }, {
556
+ name: publisher.name,
557
+ ip: publisher.ip
558
+ });
559
+ fileLog(`[${ActionKind.EXIT_PUBLISHER}]: ${identifier} is removing , subscriber: ${subscriberIdentifier} will be add tmpSubScriberRelation`, "Broker", "info");
560
+ });
561
+ this._publisherMap.delete(identifier);
562
+ fileLog(`[${ActionKind.EXIT_PUBLISHER}]: ${identifier} is removed `, "Broker", "info");
563
+ if (!this.hasPublishers) {
564
+ fileLog(`[${ActionKind.EXIT_PUBLISHER}]: _publisherMap is empty, all server will exit `, "Broker", "warn");
565
+ this.exit();
566
+ }
567
+ } catch (err) {
568
+ const msg = error(err, ActionKind.EXIT_PUBLISHER, "Broker");
569
+ client.send(msg);
570
+ client.close();
571
+ }
572
+ }
573
+ async _addWebClient(context, client) {
574
+ const { name } = context ?? {};
575
+ const identifier = getIdentifier({ name });
576
+ if (this._webClientMap.has(identifier)) fileLog(`${identifier}} has been added, this action will override prev WebClient`, "Broker", "warn");
577
+ try {
578
+ this._webClientMap.set(identifier, client);
579
+ fileLog(`${identifier} adding WebClient Succeed`, "Broker", "info");
580
+ } catch (err) {
581
+ const msg = error(err, ActionKind.ADD_WEB_CLIENT, "Broker");
582
+ client.send(msg);
583
+ client.close();
584
+ }
585
+ }
586
+ async _notifyWebClient(context, client) {
587
+ const { name, updateMode } = context ?? {};
588
+ const identifier = getIdentifier({ name });
589
+ const webClient = this._webClientMap.get(identifier);
590
+ if (!webClient) {
591
+ fileLog(`[${ActionKind.NOTIFY_WEB_CLIENT}] ${identifier} has not been added, this action will be ignored`, "Broker", "warn");
592
+ return;
593
+ }
594
+ try {
595
+ const api = new ReloadWebClientAPI({
596
+ name,
597
+ updateMode
598
+ });
599
+ webClient.send(JSON.stringify(api));
600
+ fileLog(`[${ActionKind.NOTIFY_WEB_CLIENT}] Notify ${name} WebClient Succeed`, "Broker", "info");
601
+ } catch (err) {
602
+ const msg = error(err, ActionKind.NOTIFY_WEB_CLIENT, "Broker");
603
+ client.send(msg);
604
+ client.close();
605
+ }
606
+ }
607
+ _addTmpSubScriberRelation(subscriber, publisher) {
608
+ const publisherIdentifier = getIdentifier({
609
+ name: publisher.name,
610
+ ip: publisher.ip
611
+ });
612
+ const subscriberIdentifier = subscriber.name;
613
+ const shelter = this._tmpSubscriberShelter.get(publisherIdentifier);
614
+ if (!shelter) {
615
+ const map = /* @__PURE__ */ new Map();
616
+ map.set(subscriberIdentifier, subscriber);
617
+ this._tmpSubscriberShelter.set(publisherIdentifier, {
618
+ subscribers: map,
619
+ timestamp: Date.now()
620
+ });
621
+ fileLog(`[AddTmpSubscriberRelation] ${publisherIdentifier}'s subscriber has ${subscriberIdentifier} `, "Broker", "info");
622
+ return;
623
+ }
624
+ if (shelter.subscribers.get(subscriberIdentifier)) {
625
+ fileLog(`[AddTmpSubscriberRelation] ${publisherIdentifier} and ${subscriberIdentifier} relation has been added`, "Broker", "warn");
626
+ shelter.subscribers.set(subscriberIdentifier, subscriber);
627
+ shelter.timestamp = Date.now();
628
+ } else {
629
+ fileLog(`AddTmpSubscriberLog ${publisherIdentifier}'s shelter has been added, update shelter.subscribers ${subscriberIdentifier}`, "Broker", "warn");
630
+ shelter.subscribers.set(subscriberIdentifier, subscriber);
631
+ }
632
+ }
633
+ _getTmpSubScribers(publisherIdentifier) {
634
+ return this._tmpSubscriberShelter.get(publisherIdentifier)?.subscribers;
635
+ }
636
+ _consumeTmpSubScribers(publisher, tmpSubScribers) {
637
+ tmpSubScribers.forEach((tmpSubScriber, identifier) => {
638
+ fileLog(`notifyTmpSubScribers ${publisher.name} will be add a subscriber: ${identifier} `, "Broker", "warn");
639
+ publisher.addSubscriber(identifier, tmpSubScriber.client);
640
+ publisher.notifySubscriber(identifier, {
641
+ updateKind: UpdateKind.UPDATE_TYPE,
642
+ updateMode: UpdateMode.PASSIVE,
643
+ updateSourcePaths: [publisher.name],
644
+ remoteTypeTarPath: publisher.remoteTypeTarPath,
645
+ name: publisher.name
646
+ });
647
+ });
648
+ }
649
+ _clearTmpSubScriberRelation(identifier) {
650
+ this._tmpSubscriberShelter.delete(identifier);
651
+ }
652
+ _clearTmpSubScriberRelations() {
653
+ this._tmpSubscriberShelter.clear();
654
+ }
655
+ _disconnect() {
656
+ this._publisherMap.forEach((publisher) => {
657
+ publisher.close();
658
+ });
659
+ }
660
+ _setSchedule() {
661
+ const rule = new schedule.RecurrenceRule();
662
+ if (Number(process.env["FEDERATION_SERVER_TEST"])) {
663
+ const interval = Number(process.env["FEDERATION_SERVER_TEST"]) / 1e3;
664
+ const second = [];
665
+ for (let i = 0; i < 60; i = i + interval) second.push(i);
666
+ rule.second = second;
667
+ } else {
668
+ rule.second = 0;
669
+ rule.hour = [
670
+ 0,
671
+ 3,
672
+ 6,
673
+ 9,
674
+ 12,
675
+ 15,
676
+ 18
677
+ ];
678
+ rule.minute = 0;
679
+ }
680
+ const serverTest = Number(process.env["FEDERATION_SERVER_TEST"]);
681
+ this._scheduleJob = schedule.scheduleJob(rule, () => {
682
+ this._tmpSubscriberShelter.forEach((tmpSubscriber, identifier) => {
683
+ fileLog(` _clearTmpSubScriberRelation ${identifier}, ${Date.now() - tmpSubscriber.timestamp >= (process.env["GARFISH_MODULE_SERVER_TEST"] ? serverTest : Broker.DEFAULT_WAITING_TIME)}`, "Broker", "info");
684
+ if (Date.now() - tmpSubscriber.timestamp >= (process.env["FEDERATION_SERVER_TEST"] ? serverTest : Broker.DEFAULT_WAITING_TIME)) this._clearTmpSubScriberRelation(identifier);
685
+ });
686
+ });
687
+ }
688
+ _clearSchedule() {
689
+ if (!this._scheduleJob) return;
690
+ this._scheduleJob.cancel();
691
+ this._scheduleJob = null;
692
+ }
693
+ _stopWhenSIGTERMOrSIGINT() {
694
+ process.on("SIGTERM", () => {
695
+ this.exit();
696
+ });
697
+ process.on("SIGINT", () => {
698
+ this.exit();
699
+ });
700
+ }
701
+ _handleUnexpectedExit() {
702
+ process.on("unhandledRejection", (error) => {
703
+ console.error("Unhandled Rejection Error: ", error);
704
+ fileLog(`Unhandled Rejection Error: ${error}`, "Broker", "fatal");
705
+ process.exit(1);
706
+ });
707
+ process.on("uncaughtException", (error) => {
708
+ console.error("Unhandled Exception Error: ", error);
709
+ fileLog(`Unhandled Rejection Error: ${error}`, "Broker", "fatal");
710
+ process.exit(1);
711
+ });
712
+ }
713
+ async start() {}
714
+ exit() {
715
+ const brokerExitLog = new BrokerExitLog();
716
+ this.broadcast(JSON.stringify(brokerExitLog));
717
+ this._disconnect();
718
+ this._clearSchedule();
719
+ this._clearTmpSubScriberRelations();
720
+ this._webSocketServer && this._webSocketServer.close();
721
+ this._secureWebSocketServer && this._secureWebSocketServer.close();
722
+ process.exit(0);
723
+ }
724
+ broadcast(message) {
725
+ fileLog(`[broadcast] exit info : ${JSON.stringify(message)}`, "Broker", "warn");
726
+ this._webSocketServer?.clients.forEach((client) => {
727
+ client.send(JSON.stringify(message));
728
+ });
729
+ this._secureWebSocketServer?.clients.forEach((client) => {
730
+ client.send(JSON.stringify(message));
731
+ });
732
+ }
733
+ };
734
+
735
+ //#endregion
736
+ export { getIdentifier as a, logger$1 as c, getFreePort as i, LogKind as l, UpdateKind as n, getIPV4 as o, fib as r, fileLog as s, Broker as t, APIKind as u };