@module-federation/dts-plugin 0.0.0-chore-bump-node-22-20260710161714

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.
@@ -0,0 +1,718 @@
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 * as fs$1 from "fs";
3
+ import { parse } from "url";
4
+ import * as path$1 from "path";
5
+ import { SEPARATOR, createLogger } from "@module-federation/sdk";
6
+ import net from "net";
7
+ import os from "os";
8
+ import WebSocket from "isomorphic-ws";
9
+ import { createServer } from "http";
10
+ import schedule from "node-schedule";
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
+ try {
97
+ const logDir = ".mf";
98
+ const logFile = path$1.join(logDir, "typesGenerate.log");
99
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString();
100
+ if (!fs$1.existsSync(logDir)) fs$1.mkdirSync(logDir, { recursive: true });
101
+ fs$1.appendFileSync(logFile, `[${timestamp}] [${level.toUpperCase()}] ${module} - ${msg}\n`);
102
+ } catch {}
103
+ }
104
+ function error(error, action, from) {
105
+ const err = error instanceof Error ? error : /* @__PURE__ */ new Error(`${action} error`);
106
+ fileLog(`[${action}] error: ${err}`, from, "fatal");
107
+ return err.toString();
108
+ }
109
+
110
+ //#endregion
111
+ //#region src/server/utils/getIPV4.ts
112
+ const localIpv4 = "127.0.0.1";
113
+ const getIpv4Interfaces = () => {
114
+ try {
115
+ const interfaces = os.networkInterfaces();
116
+ const ipv4Interfaces = [];
117
+ Object.values(interfaces).forEach((detail) => {
118
+ detail?.forEach((detail) => {
119
+ const familyV4Value = typeof detail.family === "string" ? "IPv4" : 4;
120
+ if (detail.family === familyV4Value && detail.address !== localIpv4) ipv4Interfaces.push(detail);
121
+ });
122
+ });
123
+ return ipv4Interfaces;
124
+ } catch (_err) {
125
+ return [];
126
+ }
127
+ };
128
+ const getIPV4 = () => {
129
+ return (getIpv4Interfaces()[0] || { address: localIpv4 }).address;
130
+ };
131
+
132
+ //#endregion
133
+ //#region src/server/utils/index.ts
134
+ function getIdentifier(options) {
135
+ const { ip, name } = options;
136
+ return `mf ${SEPARATOR}${name}${ip ? `${SEPARATOR}${ip}` : ""}`;
137
+ }
138
+ function fib(n) {
139
+ let i = 2;
140
+ const res = [
141
+ 0,
142
+ 1,
143
+ 1
144
+ ];
145
+ while (i <= n) {
146
+ res[i] = res[i - 1] + res[i - 2];
147
+ i++;
148
+ }
149
+ return res[n];
150
+ }
151
+ function getFreePort() {
152
+ return new Promise((resolve, reject) => {
153
+ const server = net.createServer();
154
+ server.unref();
155
+ server.on("error", reject);
156
+ server.listen(0, () => {
157
+ const { port } = server.address();
158
+ server.close(() => {
159
+ resolve(port);
160
+ });
161
+ });
162
+ });
163
+ }
164
+
165
+ //#endregion
166
+ //#region src/server/Publisher.ts
167
+ var Publisher = class {
168
+ constructor(ctx) {
169
+ this._name = ctx.name;
170
+ this._ip = ctx.ip;
171
+ this._remoteTypeTarPath = ctx.remoteTypeTarPath;
172
+ this._subscribers = /* @__PURE__ */ new Map();
173
+ this._ws = ctx.ws;
174
+ this.dynamicRemoteMap = /* @__PURE__ */ new Map();
175
+ }
176
+ get identifier() {
177
+ return getIdentifier({
178
+ name: this._name,
179
+ ip: this._ip
180
+ });
181
+ }
182
+ get name() {
183
+ return this._name;
184
+ }
185
+ get ip() {
186
+ return this._ip;
187
+ }
188
+ get remoteTypeTarPath() {
189
+ return this._remoteTypeTarPath;
190
+ }
191
+ get hasSubscribes() {
192
+ return Boolean(this._subscribers.size);
193
+ }
194
+ get subscribers() {
195
+ return this._subscribers;
196
+ }
197
+ addSubscriber(identifier, subscriber) {
198
+ fileLog(`${this.name} set subscriber: ${identifier}`, "Publisher", "info");
199
+ this._subscribers.set(identifier, subscriber);
200
+ }
201
+ removeSubscriber(identifier) {
202
+ if (this._subscribers.has(identifier)) {
203
+ fileLog(`${this.name} removeSubscriber: ${identifier}`, "Publisher", "warn");
204
+ this._subscribers.delete(identifier);
205
+ }
206
+ }
207
+ notifySubscriber(subscriberIdentifier, options) {
208
+ const subscriber = this._subscribers.get(subscriberIdentifier);
209
+ if (!subscriber) {
210
+ fileLog(`[notifySubscriber] ${this.name} notifySubscriber: ${subscriberIdentifier}, does not exits`, "Publisher", "error");
211
+ return;
212
+ }
213
+ const api = new UpdateSubscriberAPI(options);
214
+ subscriber.send(JSON.stringify(api));
215
+ fileLog(`[notifySubscriber] ${this.name} notifySubscriber: ${JSON.stringify(subscriberIdentifier)}, message: ${JSON.stringify(api)}`, "Publisher", "info");
216
+ }
217
+ fetchRemoteTypes(options) {
218
+ fileLog(`[fetchRemoteTypes] ${this.name} fetchRemoteTypes, options: ${JSON.stringify(options)}, ws: ${Boolean(this._ws)}`, "Publisher", "info");
219
+ if (!this._ws) return;
220
+ const api = new FetchTypesAPI(options);
221
+ this._ws.send(JSON.stringify(api));
222
+ }
223
+ notifySubscribers(options) {
224
+ const api = new UpdateSubscriberAPI(options);
225
+ this.broadcast(api);
226
+ }
227
+ broadcast(message) {
228
+ if (this.hasSubscribes) this._subscribers.forEach((subscriber, key) => {
229
+ fileLog(`[BroadCast] ${this.name} notifySubscriber: ${key}, PID: ${process.pid}, message: ${JSON.stringify(message)}`, "Publisher", "info");
230
+ subscriber.send(JSON.stringify(message));
231
+ });
232
+ else fileLog(`[BroadCast] ${this.name}'s subscribe is empty`, "Publisher", "warn");
233
+ }
234
+ close() {
235
+ this._ws = void 0;
236
+ this._subscribers.forEach((_subscriber, identifier) => {
237
+ fileLog(`[BroadCast] close ${this.name} remove: ${identifier}`, "Publisher", "warn");
238
+ this.removeSubscriber(identifier);
239
+ });
240
+ }
241
+ };
242
+
243
+ //#endregion
244
+ //#region src/server/message/Action/Update.ts
245
+ let UpdateKind = /* @__PURE__ */ function(UpdateKind) {
246
+ UpdateKind["UPDATE_TYPE"] = "UPDATE_TYPE";
247
+ UpdateKind["RELOAD_PAGE"] = "RELOAD_PAGE";
248
+ return UpdateKind;
249
+ }({});
250
+
251
+ //#endregion
252
+ //#region src/server/broker/Broker.ts
253
+ var Broker = class Broker {
254
+ static {
255
+ this.WEB_SOCKET_CONNECT_MAGIC_ID = WEB_SOCKET_CONNECT_MAGIC_ID;
256
+ }
257
+ static {
258
+ this.DEFAULT_WEB_SOCKET_PORT = DEFAULT_WEB_SOCKET_PORT;
259
+ }
260
+ static {
261
+ this.DEFAULT_SECURE_WEB_SOCKET_PORT = 16324;
262
+ }
263
+ static {
264
+ this.DEFAULT_WAITING_TIME = 1.5 * 60 * 60 * 1e3;
265
+ }
266
+ constructor() {
267
+ this._publisherMap = /* @__PURE__ */ new Map();
268
+ this._webClientMap = /* @__PURE__ */ new Map();
269
+ this._tmpSubscriberShelter = /* @__PURE__ */ new Map();
270
+ this._scheduleJob = null;
271
+ this._setSchedule();
272
+ this._startWsServer();
273
+ this._stopWhenSIGTERMOrSIGINT();
274
+ this._handleUnexpectedExit();
275
+ }
276
+ get hasPublishers() {
277
+ return Boolean(this._publisherMap.size);
278
+ }
279
+ async _startWsServer() {
280
+ const wsHandler = (ws, req) => {
281
+ const { url: reqUrl = "" } = req;
282
+ const { query } = parse(reqUrl, true);
283
+ const { WEB_SOCKET_CONNECT_MAGIC_ID } = query;
284
+ if (WEB_SOCKET_CONNECT_MAGIC_ID === Broker.WEB_SOCKET_CONNECT_MAGIC_ID) {
285
+ ws.on("message", (message) => {
286
+ try {
287
+ const text = message.toString();
288
+ const action = JSON.parse(text);
289
+ fileLog(`${action?.kind} action received `, "Broker", "info");
290
+ this._takeAction(action, ws);
291
+ } catch (error) {
292
+ fileLog(`parse action message error: ${error}`, "Broker", "error");
293
+ }
294
+ });
295
+ ws.on("error", (e) => {
296
+ fileLog(`parse action message error: ${e}`, "Broker", "error");
297
+ });
298
+ } else {
299
+ ws.send("Invalid CONNECT ID.");
300
+ fileLog("Invalid CONNECT ID.", "Broker", "warn");
301
+ ws.close();
302
+ }
303
+ };
304
+ const server = createServer();
305
+ this._webSocketServer = new WebSocket.Server({ noServer: true });
306
+ this._webSocketServer.on("error", (err) => {
307
+ fileLog(`ws error: \n${err.message}\n ${err.stack}`, "Broker", "error");
308
+ });
309
+ this._webSocketServer.on("listening", () => {
310
+ fileLog(`WebSocket server is listening on port ${Broker.DEFAULT_WEB_SOCKET_PORT}`, "Broker", "info");
311
+ });
312
+ this._webSocketServer.on("connection", wsHandler);
313
+ this._webSocketServer.on("close", (code) => {
314
+ fileLog(`WebSocket Server Close with Code ${code}`, "Broker", "warn");
315
+ this._webSocketServer && this._webSocketServer.close();
316
+ this._webSocketServer = void 0;
317
+ });
318
+ server.on("upgrade", (req, socket, head) => {
319
+ if (req.url) {
320
+ const { pathname } = parse(req.url);
321
+ if (pathname === "/") this._webSocketServer?.handleUpgrade(req, socket, head, (ws) => {
322
+ this._webSocketServer?.emit("connection", ws, req);
323
+ });
324
+ }
325
+ });
326
+ server.listen(Broker.DEFAULT_WEB_SOCKET_PORT);
327
+ }
328
+ async _takeAction(action, client) {
329
+ const { kind, payload } = action;
330
+ if (kind === ActionKind.ADD_PUBLISHER) await this._addPublisher(payload, client);
331
+ if (kind === ActionKind.UPDATE_PUBLISHER) await this._updatePublisher(payload, client);
332
+ if (kind === ActionKind.ADD_SUBSCRIBER) await this._addSubscriber(payload, client);
333
+ if (kind === ActionKind.EXIT_SUBSCRIBER) await this._removeSubscriber(payload, client);
334
+ if (kind === ActionKind.EXIT_PUBLISHER) await this._removePublisher(payload, client);
335
+ if (kind === ActionKind.ADD_WEB_CLIENT) await this._addWebClient(payload, client);
336
+ if (kind === ActionKind.NOTIFY_WEB_CLIENT) await this._notifyWebClient(payload, client);
337
+ if (kind === ActionKind.FETCH_TYPES) await this._fetchTypes(payload, client);
338
+ if (kind === ActionKind.ADD_DYNAMIC_REMOTE) this._addDynamicRemote(payload);
339
+ }
340
+ async _addPublisher(context, client) {
341
+ const { name, ip, remoteTypeTarPath } = context ?? {};
342
+ const identifier = getIdentifier({
343
+ name,
344
+ ip
345
+ });
346
+ if (this._publisherMap.has(identifier)) {
347
+ fileLog(`[${ActionKind.ADD_PUBLISHER}] ${identifier} has been added, this action will be ignored`, "Broker", "warn");
348
+ return;
349
+ }
350
+ try {
351
+ const publisher = new Publisher({
352
+ name,
353
+ ip,
354
+ remoteTypeTarPath,
355
+ ws: client
356
+ });
357
+ this._publisherMap.set(identifier, publisher);
358
+ fileLog(`[${ActionKind.ADD_PUBLISHER}] ${identifier} Adding Publisher Succeed`, "Broker", "info");
359
+ const tmpSubScribers = this._getTmpSubScribers(identifier);
360
+ if (tmpSubScribers) {
361
+ fileLog(`[${ActionKind.ADD_PUBLISHER}] consumeTmpSubscriber set ${publisher.name}’s subscribers `, "Broker", "info");
362
+ this._consumeTmpSubScribers(publisher, tmpSubScribers);
363
+ this._clearTmpSubScriberRelation(identifier);
364
+ }
365
+ } catch (err) {
366
+ const msg = error(err, ActionKind.ADD_PUBLISHER, "Broker");
367
+ client.send(msg);
368
+ client.close();
369
+ }
370
+ }
371
+ async _updatePublisher(context, client) {
372
+ const { name, updateMode, updateKind, updateSourcePaths, remoteTypeTarPath, ip } = context ?? {};
373
+ const identifier = getIdentifier({
374
+ name,
375
+ ip
376
+ });
377
+ if (!this._publisherMap.has(identifier)) {
378
+ fileLog(`[${ActionKind.UPDATE_PUBLISHER}] ${identifier} has not been started, this action will be ignored
379
+ this._publisherMap: ${JSON.stringify(this._publisherMap.entries())}
380
+ `, "Broker", "warn");
381
+ return;
382
+ }
383
+ try {
384
+ const publisher = this._publisherMap.get(identifier);
385
+ fileLog(`[${ActionKind.UPDATE_PUBLISHER}] ${identifier} update, and notify subscribers to update`, "Broker", "info");
386
+ if (publisher) {
387
+ publisher.notifySubscribers({
388
+ remoteTypeTarPath,
389
+ name,
390
+ updateMode,
391
+ updateKind,
392
+ updateSourcePaths: updateSourcePaths || []
393
+ });
394
+ this._publisherMap.forEach((p) => {
395
+ if (p.name === publisher.name) return;
396
+ const dynamicRemoteInfo = p.dynamicRemoteMap.get(identifier);
397
+ if (dynamicRemoteInfo) {
398
+ fileLog(`dynamicRemoteInfo: ${JSON.stringify(dynamicRemoteInfo)}, identifier:${identifier} publish: ${p.name}`, "Broker", "info");
399
+ p.fetchRemoteTypes({
400
+ remoteInfo: dynamicRemoteInfo,
401
+ once: false
402
+ });
403
+ }
404
+ });
405
+ }
406
+ } catch (err) {
407
+ const msg = error(err, ActionKind.UPDATE_PUBLISHER, "Broker");
408
+ client.send(msg);
409
+ client.close();
410
+ }
411
+ }
412
+ async _fetchTypes(context, _client) {
413
+ const { name, ip, remoteInfo } = context ?? {};
414
+ const identifier = getIdentifier({
415
+ name,
416
+ ip
417
+ });
418
+ try {
419
+ const publisher = this._publisherMap.get(identifier);
420
+ fileLog(`[${ActionKind.FETCH_TYPES}] ${identifier} fetch types`, "Broker", "info");
421
+ if (publisher) publisher.fetchRemoteTypes({
422
+ remoteInfo,
423
+ once: true
424
+ });
425
+ } catch (err) {
426
+ fileLog(`[${ActionKind.FETCH_TYPES}] ${identifier} fetch types fail , error info: ${err}`, "Broker", "error");
427
+ }
428
+ }
429
+ _addDynamicRemote(context) {
430
+ const { name, ip, remoteInfo, remoteIp } = context ?? {};
431
+ const identifier = getIdentifier({
432
+ name,
433
+ ip
434
+ });
435
+ const publisher = this._publisherMap.get(identifier);
436
+ const remoteId = getIdentifier({
437
+ name: remoteInfo.name,
438
+ ip: remoteIp
439
+ });
440
+ fileLog(`[${ActionKind.ADD_DYNAMIC_REMOTE}] identifier:${identifier},publisher: ${publisher.name}, remoteId:${remoteId}`, "Broker", "error");
441
+ if (!publisher || publisher.dynamicRemoteMap.has(remoteId)) return;
442
+ publisher.dynamicRemoteMap.set(remoteId, remoteInfo);
443
+ }
444
+ async _addSubscriber(context, client) {
445
+ const { publishers, name: subscriberName } = context ?? {};
446
+ publishers.forEach((publisher) => {
447
+ const { name, ip } = publisher;
448
+ const identifier = getIdentifier({
449
+ name,
450
+ ip
451
+ });
452
+ if (!this._publisherMap.has(identifier)) {
453
+ fileLog(`[${ActionKind.ADD_SUBSCRIBER}]: ${identifier} has not been started, ${subscriberName} will add the relation to tmp shelter`, "Broker", "warn");
454
+ this._addTmpSubScriberRelation({
455
+ name: getIdentifier({
456
+ name: context.name,
457
+ ip: context.ip
458
+ }),
459
+ client
460
+ }, publisher);
461
+ return;
462
+ }
463
+ try {
464
+ const registeredPublisher = this._publisherMap.get(identifier);
465
+ if (registeredPublisher) {
466
+ registeredPublisher.addSubscriber(getIdentifier({
467
+ name: subscriberName,
468
+ ip: context.ip
469
+ }), client);
470
+ fileLog(`[${ActionKind.ADD_SUBSCRIBER}]: ${identifier} has been started, Adding Subscriber ${subscriberName} Succeed, this.__publisherMap are: ${JSON.stringify(Array.from(this._publisherMap.entries()))}`, "Broker", "info");
471
+ registeredPublisher.notifySubscriber(getIdentifier({
472
+ name: subscriberName,
473
+ ip: context.ip
474
+ }), {
475
+ updateKind: UpdateKind.UPDATE_TYPE,
476
+ updateMode: UpdateMode.PASSIVE,
477
+ updateSourcePaths: [registeredPublisher.name],
478
+ remoteTypeTarPath: registeredPublisher.remoteTypeTarPath,
479
+ name: registeredPublisher.name
480
+ });
481
+ fileLog(`[${ActionKind.ADD_SUBSCRIBER}]: notifySubscriber Subscriber ${subscriberName}, updateMode: "PASSIVE", updateSourcePaths: ${registeredPublisher.name}`, "Broker", "info");
482
+ }
483
+ } catch (err) {
484
+ const msg = error(err, ActionKind.ADD_SUBSCRIBER, "Broker");
485
+ client.send(msg);
486
+ client.close();
487
+ }
488
+ });
489
+ }
490
+ async _removeSubscriber(context, client) {
491
+ const { publishers } = context ?? {};
492
+ const subscriberIdentifier = getIdentifier({
493
+ name: context?.name,
494
+ ip: context?.ip
495
+ });
496
+ publishers.forEach((publisher) => {
497
+ const { name, ip } = publisher;
498
+ const identifier = getIdentifier({
499
+ name,
500
+ ip
501
+ });
502
+ const registeredPublisher = this._publisherMap.get(identifier);
503
+ if (!registeredPublisher) {
504
+ fileLog(`[${ActionKind.EXIT_SUBSCRIBER}], ${identifier} does not exit `, "Broker", "warn");
505
+ return;
506
+ }
507
+ try {
508
+ fileLog(`[${ActionKind.EXIT_SUBSCRIBER}], ${identifier} will exit `, "Broker", "INFO");
509
+ registeredPublisher.removeSubscriber(subscriberIdentifier);
510
+ this._clearTmpSubScriberRelation(identifier);
511
+ if (!registeredPublisher.hasSubscribes) this._publisherMap.delete(identifier);
512
+ if (!this.hasPublishers) this.exit();
513
+ } catch (err) {
514
+ const msg = error(err, ActionKind.EXIT_SUBSCRIBER, "Broker");
515
+ client.send(msg);
516
+ client.close();
517
+ }
518
+ });
519
+ }
520
+ async _removePublisher(context, client) {
521
+ const { name, ip } = context ?? {};
522
+ const identifier = getIdentifier({
523
+ name,
524
+ ip
525
+ });
526
+ const publisher = this._publisherMap.get(identifier);
527
+ if (!publisher) {
528
+ fileLog(`[${ActionKind.EXIT_PUBLISHER}]: ${identifier}} has not been added, this action will be ingored`, "Broker", "warn");
529
+ return;
530
+ }
531
+ try {
532
+ const { subscribers } = publisher;
533
+ subscribers.forEach((subscriber, subscriberIdentifier) => {
534
+ this._addTmpSubScriberRelation({
535
+ name: subscriberIdentifier,
536
+ client: subscriber
537
+ }, {
538
+ name: publisher.name,
539
+ ip: publisher.ip
540
+ });
541
+ fileLog(`[${ActionKind.EXIT_PUBLISHER}]: ${identifier} is removing , subscriber: ${subscriberIdentifier} will be add tmpSubScriberRelation`, "Broker", "info");
542
+ });
543
+ this._publisherMap.delete(identifier);
544
+ fileLog(`[${ActionKind.EXIT_PUBLISHER}]: ${identifier} is removed `, "Broker", "info");
545
+ if (!this.hasPublishers) {
546
+ fileLog(`[${ActionKind.EXIT_PUBLISHER}]: _publisherMap is empty, all server will exit `, "Broker", "warn");
547
+ this.exit();
548
+ }
549
+ } catch (err) {
550
+ const msg = error(err, ActionKind.EXIT_PUBLISHER, "Broker");
551
+ client.send(msg);
552
+ client.close();
553
+ }
554
+ }
555
+ async _addWebClient(context, client) {
556
+ const { name } = context ?? {};
557
+ const identifier = getIdentifier({ name });
558
+ if (this._webClientMap.has(identifier)) fileLog(`${identifier}} has been added, this action will override prev WebClient`, "Broker", "warn");
559
+ try {
560
+ this._webClientMap.set(identifier, client);
561
+ fileLog(`${identifier} adding WebClient Succeed`, "Broker", "info");
562
+ } catch (err) {
563
+ const msg = error(err, ActionKind.ADD_WEB_CLIENT, "Broker");
564
+ client.send(msg);
565
+ client.close();
566
+ }
567
+ }
568
+ async _notifyWebClient(context, client) {
569
+ const { name, updateMode } = context ?? {};
570
+ const identifier = getIdentifier({ name });
571
+ const webClient = this._webClientMap.get(identifier);
572
+ if (!webClient) {
573
+ fileLog(`[${ActionKind.NOTIFY_WEB_CLIENT}] ${identifier} has not been added, this action will be ignored`, "Broker", "warn");
574
+ return;
575
+ }
576
+ try {
577
+ const api = new ReloadWebClientAPI({
578
+ name,
579
+ updateMode
580
+ });
581
+ webClient.send(JSON.stringify(api));
582
+ fileLog(`[${ActionKind.NOTIFY_WEB_CLIENT}] Notify ${name} WebClient Succeed`, "Broker", "info");
583
+ } catch (err) {
584
+ const msg = error(err, ActionKind.NOTIFY_WEB_CLIENT, "Broker");
585
+ client.send(msg);
586
+ client.close();
587
+ }
588
+ }
589
+ _addTmpSubScriberRelation(subscriber, publisher) {
590
+ const publisherIdentifier = getIdentifier({
591
+ name: publisher.name,
592
+ ip: publisher.ip
593
+ });
594
+ const subscriberIdentifier = subscriber.name;
595
+ const shelter = this._tmpSubscriberShelter.get(publisherIdentifier);
596
+ if (!shelter) {
597
+ const map = /* @__PURE__ */ new Map();
598
+ map.set(subscriberIdentifier, subscriber);
599
+ this._tmpSubscriberShelter.set(publisherIdentifier, {
600
+ subscribers: map,
601
+ timestamp: Date.now()
602
+ });
603
+ fileLog(`[AddTmpSubscriberRelation] ${publisherIdentifier}'s subscriber has ${subscriberIdentifier} `, "Broker", "info");
604
+ return;
605
+ }
606
+ if (shelter.subscribers.get(subscriberIdentifier)) {
607
+ fileLog(`[AddTmpSubscriberRelation] ${publisherIdentifier} and ${subscriberIdentifier} relation has been added`, "Broker", "warn");
608
+ shelter.subscribers.set(subscriberIdentifier, subscriber);
609
+ shelter.timestamp = Date.now();
610
+ } else {
611
+ fileLog(`AddTmpSubscriberLog ${publisherIdentifier}'s shelter has been added, update shelter.subscribers ${subscriberIdentifier}`, "Broker", "warn");
612
+ shelter.subscribers.set(subscriberIdentifier, subscriber);
613
+ }
614
+ }
615
+ _getTmpSubScribers(publisherIdentifier) {
616
+ return this._tmpSubscriberShelter.get(publisherIdentifier)?.subscribers;
617
+ }
618
+ _consumeTmpSubScribers(publisher, tmpSubScribers) {
619
+ tmpSubScribers.forEach((tmpSubScriber, identifier) => {
620
+ fileLog(`notifyTmpSubScribers ${publisher.name} will be add a subscriber: ${identifier} `, "Broker", "warn");
621
+ publisher.addSubscriber(identifier, tmpSubScriber.client);
622
+ publisher.notifySubscriber(identifier, {
623
+ updateKind: UpdateKind.UPDATE_TYPE,
624
+ updateMode: UpdateMode.PASSIVE,
625
+ updateSourcePaths: [publisher.name],
626
+ remoteTypeTarPath: publisher.remoteTypeTarPath,
627
+ name: publisher.name
628
+ });
629
+ });
630
+ }
631
+ _clearTmpSubScriberRelation(identifier) {
632
+ this._tmpSubscriberShelter.delete(identifier);
633
+ }
634
+ _clearTmpSubScriberRelations() {
635
+ this._tmpSubscriberShelter.clear();
636
+ }
637
+ _disconnect() {
638
+ this._publisherMap.forEach((publisher) => {
639
+ publisher.close();
640
+ });
641
+ }
642
+ _setSchedule() {
643
+ const rule = new schedule.RecurrenceRule();
644
+ if (Number(process.env["FEDERATION_SERVER_TEST"])) {
645
+ const interval = Number(process.env["FEDERATION_SERVER_TEST"]) / 1e3;
646
+ const second = [];
647
+ for (let i = 0; i < 60; i = i + interval) second.push(i);
648
+ rule.second = second;
649
+ } else {
650
+ rule.second = 0;
651
+ rule.hour = [
652
+ 0,
653
+ 3,
654
+ 6,
655
+ 9,
656
+ 12,
657
+ 15,
658
+ 18
659
+ ];
660
+ rule.minute = 0;
661
+ }
662
+ const serverTest = Number(process.env["FEDERATION_SERVER_TEST"]);
663
+ this._scheduleJob = schedule.scheduleJob(rule, () => {
664
+ this._tmpSubscriberShelter.forEach((tmpSubscriber, identifier) => {
665
+ fileLog(` _clearTmpSubScriberRelation ${identifier}, ${Date.now() - tmpSubscriber.timestamp >= (process.env["GARFISH_MODULE_SERVER_TEST"] ? serverTest : Broker.DEFAULT_WAITING_TIME)}`, "Broker", "info");
666
+ if (Date.now() - tmpSubscriber.timestamp >= (process.env["FEDERATION_SERVER_TEST"] ? serverTest : Broker.DEFAULT_WAITING_TIME)) this._clearTmpSubScriberRelation(identifier);
667
+ });
668
+ });
669
+ }
670
+ _clearSchedule() {
671
+ if (!this._scheduleJob) return;
672
+ this._scheduleJob.cancel();
673
+ this._scheduleJob = null;
674
+ }
675
+ _stopWhenSIGTERMOrSIGINT() {
676
+ process.on("SIGTERM", () => {
677
+ this.exit();
678
+ });
679
+ process.on("SIGINT", () => {
680
+ this.exit();
681
+ });
682
+ }
683
+ _handleUnexpectedExit() {
684
+ process.on("unhandledRejection", (error) => {
685
+ console.error("Unhandled Rejection Error: ", error);
686
+ fileLog(`Unhandled Rejection Error: ${error}`, "Broker", "fatal");
687
+ process.exit(1);
688
+ });
689
+ process.on("uncaughtException", (error) => {
690
+ console.error("Unhandled Exception Error: ", error);
691
+ fileLog(`Unhandled Rejection Error: ${error}`, "Broker", "fatal");
692
+ process.exit(1);
693
+ });
694
+ }
695
+ async start() {}
696
+ exit() {
697
+ const brokerExitLog = new BrokerExitLog();
698
+ this.broadcast(JSON.stringify(brokerExitLog));
699
+ this._disconnect();
700
+ this._clearSchedule();
701
+ this._clearTmpSubScriberRelations();
702
+ this._webSocketServer && this._webSocketServer.close();
703
+ this._secureWebSocketServer && this._secureWebSocketServer.close();
704
+ process.exit(0);
705
+ }
706
+ broadcast(message) {
707
+ fileLog(`[broadcast] exit info : ${JSON.stringify(message)}`, "Broker", "warn");
708
+ this._webSocketServer?.clients.forEach((client) => {
709
+ client.send(JSON.stringify(message));
710
+ });
711
+ this._secureWebSocketServer?.clients.forEach((client) => {
712
+ client.send(JSON.stringify(message));
713
+ });
714
+ }
715
+ };
716
+
717
+ //#endregion
718
+ 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 };