@module-federation/dts-plugin 0.0.0-next-20240401122911

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,1565 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // packages/dts-plugin/src/dev-worker/forkDevWorker.ts
31
+ var forkDevWorker_exports = {};
32
+ __export(forkDevWorker_exports, {
33
+ forkDevWorker: () => forkDevWorker
34
+ });
35
+ module.exports = __toCommonJS(forkDevWorker_exports);
36
+ var import_helpers3 = require("@module-federation/native-federation-typescript/helpers");
37
+ var import_sdk3 = require("@module-federation/sdk");
38
+
39
+ // packages/dts-plugin/src/server/message/Message.ts
40
+ var Message = class {
41
+ constructor(type, kind) {
42
+ this.type = type;
43
+ this.kind = kind;
44
+ this.time = Date.now();
45
+ }
46
+ };
47
+
48
+ // packages/dts-plugin/src/server/message/API/API.ts
49
+ var API = class extends Message {
50
+ constructor(content, kind) {
51
+ super("API", kind);
52
+ const { code, payload } = content;
53
+ this.code = code;
54
+ this.payload = payload;
55
+ }
56
+ };
57
+
58
+ // packages/dts-plugin/src/server/message/API/UpdateSubscriber.ts
59
+ var UpdateSubscriberAPI = class extends API {
60
+ constructor(payload) {
61
+ super(
62
+ {
63
+ code: 0,
64
+ payload
65
+ },
66
+ "UPDATE_SUBSCRIBER" /* UPDATE_SUBSCRIBER */
67
+ );
68
+ }
69
+ };
70
+
71
+ // packages/dts-plugin/src/server/message/API/ReloadWebClient.ts
72
+ var ReloadWebClientAPI = class extends API {
73
+ constructor(payload) {
74
+ super(
75
+ {
76
+ code: 0,
77
+ payload
78
+ },
79
+ "RELOAD_WEB_CLIENT" /* RELOAD_WEB_CLIENT */
80
+ );
81
+ }
82
+ };
83
+
84
+ // packages/dts-plugin/src/server/utils/index.ts
85
+ var import_net = __toESM(require("net"));
86
+ var import_sdk2 = require("@module-federation/sdk");
87
+
88
+ // packages/dts-plugin/src/server/utils/logTransform.ts
89
+ var import_chalk = __toESM(require("chalk"));
90
+
91
+ // packages/dts-plugin/src/server/message/Log/Log.ts
92
+ var Log = class extends Message {
93
+ constructor(level, kind, ignoreVerbose = false) {
94
+ super("Log", kind);
95
+ this.ignoreVerbose = false;
96
+ this.level = level;
97
+ this.ignoreVerbose = ignoreVerbose;
98
+ }
99
+ };
100
+
101
+ // packages/dts-plugin/src/server/message/Log/BrokerExitLog.ts
102
+ var BrokerExitLog = class extends Log {
103
+ constructor() {
104
+ super("LOG" /* LOG */, "BrokerExitLog" /* BrokerExitLog */);
105
+ }
106
+ };
107
+
108
+ // packages/dts-plugin/src/server/utils/log.ts
109
+ var import_sdk = require("@module-federation/sdk");
110
+ var log4js = __toESM(require("log4js"));
111
+ var import_chalk2 = __toESM(require("chalk"));
112
+
113
+ // packages/dts-plugin/src/server/constant.ts
114
+ var DEFAULT_WEB_SOCKET_PORT = 16322;
115
+ var WEB_SOCKET_CONNECT_MAGIC_ID = "1hpzW-zo2z-o8io-gfmV1-2cb1d82";
116
+ var MF_SERVER_IDENTIFIER = "Module Federation Dev Server";
117
+ var DEFAULT_TAR_NAME = "@mf-types.zip";
118
+
119
+ // packages/dts-plugin/src/server/utils/log.ts
120
+ function fileLog(msg, module2, level) {
121
+ var _a, _b;
122
+ if (!((_a = process == null ? void 0 : process.env) == null ? void 0 : _a["FEDERATION_DEBUG"])) {
123
+ return;
124
+ }
125
+ log4js.configure({
126
+ appenders: {
127
+ [module2]: { type: "file", filename: ".mf/typesGenerate.log" },
128
+ default: { type: "file", filename: ".mf/typesGenerate.log" }
129
+ },
130
+ categories: {
131
+ [module2]: { appenders: [module2], level: "error" },
132
+ default: { appenders: ["default"], level: "trace" }
133
+ }
134
+ });
135
+ const logger4 = log4js.getLogger(module2);
136
+ logger4.level = "debug";
137
+ (_b = logger4[level]) == null ? void 0 : _b.call(logger4, msg);
138
+ }
139
+ function error(error2, action, from) {
140
+ const err = error2 instanceof Error ? error2 : new Error(`${action} error`);
141
+ fileLog(`[${action}] error: ${err}`, from, "fatal");
142
+ return err.toString();
143
+ }
144
+
145
+ // packages/dts-plugin/src/server/utils/getIPV4.ts
146
+ var import_os = __toESM(require("os"));
147
+ var localIpv4 = "127.0.0.1";
148
+ var getIpv4Interfaces = () => {
149
+ try {
150
+ const interfaces = import_os.default.networkInterfaces();
151
+ const ipv4Interfaces = [];
152
+ Object.values(interfaces).forEach((detail) => {
153
+ detail == null ? void 0 : detail.forEach((detail2) => {
154
+ const familyV4Value = typeof detail2.family === "string" ? "IPv4" : 4;
155
+ if (detail2.family === familyV4Value && detail2.address !== localIpv4) {
156
+ ipv4Interfaces.push(detail2);
157
+ }
158
+ });
159
+ });
160
+ return ipv4Interfaces;
161
+ } catch (_err) {
162
+ return [];
163
+ }
164
+ };
165
+ var getIPV4 = () => {
166
+ const ipv4Interfaces = getIpv4Interfaces();
167
+ const ipv4Interface = ipv4Interfaces[0] || { address: localIpv4 };
168
+ return ipv4Interface.address;
169
+ };
170
+
171
+ // packages/dts-plugin/src/server/utils/index.ts
172
+ function getIdentifier(options) {
173
+ const { ip, name } = options;
174
+ return `mf ${import_sdk2.SEPARATOR}${name}${ip ? `${import_sdk2.SEPARATOR}${ip}` : ""}`;
175
+ }
176
+ function fib(n) {
177
+ let i = 2;
178
+ const res = [0, 1, 1];
179
+ while (i <= n) {
180
+ res[i] = res[i - 1] + res[i - 2];
181
+ i++;
182
+ }
183
+ return res[n];
184
+ }
185
+ function getFreePort() {
186
+ return new Promise((resolve, reject) => {
187
+ const server = import_net.default.createServer();
188
+ server.unref();
189
+ server.on("error", reject);
190
+ server.listen(0, () => {
191
+ const { port } = server.address();
192
+ server.close(() => {
193
+ resolve(port);
194
+ });
195
+ });
196
+ });
197
+ }
198
+
199
+ // packages/dts-plugin/src/server/Publisher.ts
200
+ var Publisher = class {
201
+ constructor(ctx) {
202
+ this._name = ctx.name;
203
+ this._ip = ctx.ip;
204
+ this._remoteTypeTarPath = ctx.remoteTypeTarPath;
205
+ this._subscribers = /* @__PURE__ */ new Map();
206
+ }
207
+ get identifier() {
208
+ return getIdentifier({
209
+ name: this._name,
210
+ ip: this._ip
211
+ });
212
+ }
213
+ get name() {
214
+ return this._name;
215
+ }
216
+ get ip() {
217
+ return this._ip;
218
+ }
219
+ get remoteTypeTarPath() {
220
+ return this._remoteTypeTarPath;
221
+ }
222
+ get hasSubscribes() {
223
+ return Boolean(this._subscribers.size);
224
+ }
225
+ get subscribers() {
226
+ return this._subscribers;
227
+ }
228
+ addSubscriber(identifier, subscriber) {
229
+ fileLog(`${this.name} set subscriber: ${identifier}`, "Publisher", "info");
230
+ this._subscribers.set(identifier, subscriber);
231
+ }
232
+ removeSubscriber(identifier) {
233
+ if (this._subscribers.has(identifier)) {
234
+ fileLog(
235
+ `${this.name} removeSubscriber: ${identifier}`,
236
+ "Publisher",
237
+ "warn"
238
+ );
239
+ this._subscribers.delete(identifier);
240
+ }
241
+ }
242
+ notifySubscriber(subscriberIdentifier, options) {
243
+ const subscriber = this._subscribers.get(subscriberIdentifier);
244
+ if (!subscriber) {
245
+ fileLog(
246
+ `[notifySubscriber] ${this.name} notifySubscriber: ${subscriberIdentifier}, does not exits`,
247
+ "Publisher",
248
+ "error"
249
+ );
250
+ return;
251
+ }
252
+ const api = new UpdateSubscriberAPI(options);
253
+ subscriber.send(JSON.stringify(api));
254
+ fileLog(
255
+ `[notifySubscriber] ${this.name} notifySubscriber: ${JSON.stringify(
256
+ subscriberIdentifier
257
+ )}, message: ${JSON.stringify(api)}`,
258
+ "Publisher",
259
+ "info"
260
+ );
261
+ }
262
+ notifySubscribers(options) {
263
+ const api = new UpdateSubscriberAPI(options);
264
+ this.broadcast(api);
265
+ }
266
+ broadcast(message) {
267
+ if (this.hasSubscribes) {
268
+ this._subscribers.forEach((subscriber, key) => {
269
+ fileLog(
270
+ `[BroadCast] ${this.name} notifySubscriber: ${key}, PID: ${process.pid}, message: ${JSON.stringify(message)}`,
271
+ "Publisher",
272
+ "info"
273
+ );
274
+ subscriber.send(JSON.stringify(message));
275
+ });
276
+ } else {
277
+ fileLog(
278
+ `[BroadCast] ${this.name}'s subscribe is empty`,
279
+ "Publisher",
280
+ "warn"
281
+ );
282
+ }
283
+ }
284
+ close() {
285
+ this._subscribers.forEach((_subscriber, identifier) => {
286
+ fileLog(
287
+ `[BroadCast] close ${this.name} remove: ${identifier}`,
288
+ "Publisher",
289
+ "warn"
290
+ );
291
+ this.removeSubscriber(identifier);
292
+ });
293
+ }
294
+ };
295
+
296
+ // packages/dts-plugin/src/server/DevServer.ts
297
+ var import_isomorphic_ws2 = __toESM(require("isomorphic-ws"));
298
+ var import_helpers2 = require("@module-federation/native-federation-typescript/helpers");
299
+
300
+ // packages/dts-plugin/src/server/broker/Broker.ts
301
+ var import_http = require("http");
302
+ var import_helpers = require("@module-federation/native-federation-typescript/helpers");
303
+ var import_isomorphic_ws = __toESM(require("isomorphic-ws"));
304
+ var import_node_schedule = __toESM(require("node-schedule"));
305
+ var import_url = require("url");
306
+
307
+ // packages/dts-plugin/src/server/message/Action/Action.ts
308
+ var Action = class extends Message {
309
+ constructor(content, kind) {
310
+ super("Action", kind);
311
+ const { payload } = content;
312
+ this.payload = payload;
313
+ }
314
+ };
315
+
316
+ // packages/dts-plugin/src/server/message/Action/AddPublisher.ts
317
+ var AddPublisherAction = class extends Action {
318
+ constructor(payload) {
319
+ super(
320
+ {
321
+ payload
322
+ },
323
+ "ADD_PUBLISHER" /* ADD_PUBLISHER */
324
+ );
325
+ }
326
+ };
327
+
328
+ // packages/dts-plugin/src/server/message/Action/AddSubscriber.ts
329
+ var AddSubscriberAction = class extends Action {
330
+ constructor(payload) {
331
+ super(
332
+ {
333
+ payload
334
+ },
335
+ "ADD_SUBSCRIBER" /* ADD_SUBSCRIBER */
336
+ );
337
+ }
338
+ };
339
+
340
+ // packages/dts-plugin/src/server/message/Action/ExitSubscriber.ts
341
+ var ExitSubscriberAction = class extends Action {
342
+ constructor(payload) {
343
+ super(
344
+ {
345
+ payload
346
+ },
347
+ "EXIT_SUBSCRIBER" /* EXIT_SUBSCRIBER */
348
+ );
349
+ }
350
+ };
351
+
352
+ // packages/dts-plugin/src/server/message/Action/ExitPublisher.ts
353
+ var ExitPublisherAction = class extends Action {
354
+ constructor(payload) {
355
+ super(
356
+ {
357
+ payload
358
+ },
359
+ "EXIT_PUBLISHER" /* EXIT_PUBLISHER */
360
+ );
361
+ }
362
+ };
363
+
364
+ // packages/dts-plugin/src/server/message/Action/NotifyWebClient.ts
365
+ var NotifyWebClientAction = class extends Action {
366
+ constructor(payload) {
367
+ super(
368
+ {
369
+ payload
370
+ },
371
+ "NOTIFY_WEB_CLIENT" /* NOTIFY_WEB_CLIENT */
372
+ );
373
+ }
374
+ };
375
+
376
+ // packages/dts-plugin/src/server/message/Action/UpdatePublisher.ts
377
+ var UpdatePublisherAction = class extends Action {
378
+ constructor(payload) {
379
+ super(
380
+ {
381
+ payload
382
+ },
383
+ "UPDATE_PUBLISHER" /* UPDATE_PUBLISHER */
384
+ );
385
+ }
386
+ };
387
+
388
+ // packages/dts-plugin/src/server/broker/Broker.ts
389
+ var _Broker = class _Broker {
390
+ constructor() {
391
+ // 1.5h
392
+ this._publisherMap = /* @__PURE__ */ new Map();
393
+ this._webClientMap = /* @__PURE__ */ new Map();
394
+ this._tmpSubscriberShelter = /* @__PURE__ */ new Map();
395
+ this._scheduleJob = null;
396
+ this._setSchedule();
397
+ this._startWsServer();
398
+ this._stopWhenSIGTERMOrSIGINT();
399
+ this._handleUnexpectedExit();
400
+ }
401
+ get hasPublishers() {
402
+ return Boolean(this._publisherMap.size);
403
+ }
404
+ async _startWsServer() {
405
+ const wsHandler = (ws, req) => {
406
+ const { url: reqUrl = "" } = req;
407
+ const { query } = (0, import_url.parse)(reqUrl, true);
408
+ const { WEB_SOCKET_CONNECT_MAGIC_ID: WEB_SOCKET_CONNECT_MAGIC_ID2 } = query;
409
+ if (WEB_SOCKET_CONNECT_MAGIC_ID2 === _Broker.WEB_SOCKET_CONNECT_MAGIC_ID) {
410
+ ws.on("message", (message) => {
411
+ try {
412
+ const text = message.toString();
413
+ const action = JSON.parse(text);
414
+ fileLog(`${action == null ? void 0 : action.kind} action received `, "Broker", "info");
415
+ this._takeAction(action, ws);
416
+ } catch (error2) {
417
+ fileLog(`parse action message error: ${error2}`, "Broker", "error");
418
+ }
419
+ });
420
+ ws.on("error", (e) => {
421
+ fileLog(`parse action message error: ${e}`, "Broker", "error");
422
+ });
423
+ } else {
424
+ ws.send("Invalid CONNECT ID.");
425
+ fileLog("Invalid CONNECT ID.", "Broker", "warn");
426
+ ws.close();
427
+ }
428
+ };
429
+ const server = (0, import_http.createServer)();
430
+ this._webSocketServer = new import_isomorphic_ws.default.Server({ noServer: true });
431
+ this._webSocketServer.on("error", (err) => {
432
+ fileLog(`ws error:
433
+ ${err.message}
434
+ ${err.stack}`, "Broker", "error");
435
+ });
436
+ this._webSocketServer.on("listening", () => {
437
+ fileLog(
438
+ `WebSocket server is listening on port ${_Broker.DEFAULT_WEB_SOCKET_PORT}`,
439
+ "Broker",
440
+ "info"
441
+ );
442
+ });
443
+ this._webSocketServer.on("connection", wsHandler);
444
+ this._webSocketServer.on("close", (code) => {
445
+ fileLog(`WebSocket Server Close with Code ${code}`, "Broker", "warn");
446
+ this._webSocketServer && this._webSocketServer.close();
447
+ this._webSocketServer = void 0;
448
+ });
449
+ server.on("upgrade", (req, socket, head) => {
450
+ var _a;
451
+ if (req.url) {
452
+ const { pathname } = (0, import_url.parse)(req.url);
453
+ if (pathname === "/") {
454
+ (_a = this._webSocketServer) == null ? void 0 : _a.handleUpgrade(req, socket, head, (ws) => {
455
+ var _a2;
456
+ (_a2 = this._webSocketServer) == null ? void 0 : _a2.emit("connection", ws, req);
457
+ });
458
+ }
459
+ }
460
+ });
461
+ server.listen(_Broker.DEFAULT_WEB_SOCKET_PORT);
462
+ }
463
+ async _takeAction(action, client) {
464
+ const { kind, payload } = action;
465
+ if (kind === "ADD_PUBLISHER" /* ADD_PUBLISHER */) {
466
+ await this._addPublisher(payload, client);
467
+ }
468
+ if (kind === "UPDATE_PUBLISHER" /* UPDATE_PUBLISHER */) {
469
+ await this._updatePublisher(
470
+ payload,
471
+ client
472
+ );
473
+ }
474
+ if (kind === "ADD_SUBSCRIBER" /* ADD_SUBSCRIBER */) {
475
+ await this._addSubscriber(payload, client);
476
+ }
477
+ if (kind === "EXIT_SUBSCRIBER" /* EXIT_SUBSCRIBER */) {
478
+ await this._removeSubscriber(
479
+ payload,
480
+ client
481
+ );
482
+ }
483
+ if (kind === "EXIT_PUBLISHER" /* EXIT_PUBLISHER */) {
484
+ await this._removePublisher(payload, client);
485
+ }
486
+ if (kind === "ADD_WEB_CLIENT" /* ADD_WEB_CLIENT */) {
487
+ await this._addWebClient(payload, client);
488
+ }
489
+ if (kind === "NOTIFY_WEB_CLIENT" /* NOTIFY_WEB_CLIENT */) {
490
+ await this._notifyWebClient(
491
+ payload,
492
+ client
493
+ );
494
+ }
495
+ }
496
+ async _addPublisher(context, client) {
497
+ const { name, ip, remoteTypeTarPath } = context ?? {};
498
+ const identifier = getIdentifier({ name, ip });
499
+ if (this._publisherMap.has(identifier)) {
500
+ fileLog(
501
+ `[${"ADD_PUBLISHER" /* ADD_PUBLISHER */}] ${identifier} has been added, this action will be ignored`,
502
+ "Broker",
503
+ "warn"
504
+ );
505
+ return;
506
+ }
507
+ try {
508
+ const publisher = new Publisher({ name, ip, remoteTypeTarPath });
509
+ this._publisherMap.set(identifier, publisher);
510
+ fileLog(
511
+ `[${"ADD_PUBLISHER" /* ADD_PUBLISHER */}] ${identifier} Adding Publisher Succeed`,
512
+ "Broker",
513
+ "info"
514
+ );
515
+ const tmpSubScribers = this._getTmpSubScribers(identifier);
516
+ if (tmpSubScribers) {
517
+ fileLog(
518
+ `[${"ADD_PUBLISHER" /* ADD_PUBLISHER */}] consumeTmpSubscriber set ${publisher.name}\u2019s subscribers `,
519
+ "Broker",
520
+ "info"
521
+ );
522
+ this._consumeTmpSubScribers(publisher, tmpSubScribers);
523
+ this._clearTmpSubScriberRelation(identifier);
524
+ }
525
+ } catch (err) {
526
+ const msg = error(err, "ADD_PUBLISHER" /* ADD_PUBLISHER */, "Broker");
527
+ client.send(msg);
528
+ client.close();
529
+ }
530
+ }
531
+ async _updatePublisher(context, client) {
532
+ const {
533
+ name,
534
+ updateMode,
535
+ updateKind,
536
+ updateSourcePaths,
537
+ remoteTypeTarPath,
538
+ ip
539
+ } = context ?? {};
540
+ const identifier = getIdentifier({ name, ip });
541
+ if (!this._publisherMap.has(identifier)) {
542
+ fileLog(
543
+ `[${"UPDATE_PUBLISHER" /* UPDATE_PUBLISHER */}] ${identifier} has not been started, this action will be ignored
544
+ this._publisherMap: ${JSON.stringify(this._publisherMap.entries())}
545
+ `,
546
+ "Broker",
547
+ "warn"
548
+ );
549
+ return;
550
+ }
551
+ try {
552
+ const publisher = this._publisherMap.get(identifier);
553
+ fileLog(
554
+ // eslint-disable-next-line max-len
555
+ `[${"UPDATE_PUBLISHER" /* UPDATE_PUBLISHER */}] ${identifier} update, and notify subscribers to update`,
556
+ "Broker",
557
+ "info"
558
+ );
559
+ if (publisher) {
560
+ publisher.notifySubscribers({
561
+ remoteTypeTarPath,
562
+ name,
563
+ updateMode,
564
+ updateKind,
565
+ updateSourcePaths: updateSourcePaths || []
566
+ });
567
+ }
568
+ } catch (err) {
569
+ const msg = error(err, "UPDATE_PUBLISHER" /* UPDATE_PUBLISHER */, "Broker");
570
+ client.send(msg);
571
+ client.close();
572
+ }
573
+ }
574
+ // app1 consumes provider1,provider2. Dependencies at this time: publishers: [provider1, provider2], subscriberName: app1
575
+ // provider1 is app1's remote
576
+ async _addSubscriber(context, client) {
577
+ const { publishers, name: subscriberName } = context ?? {};
578
+ publishers.forEach((publisher) => {
579
+ const { name, ip } = publisher;
580
+ const identifier = getIdentifier({ name, ip });
581
+ if (!this._publisherMap.has(identifier)) {
582
+ fileLog(
583
+ `[${"ADD_SUBSCRIBER" /* ADD_SUBSCRIBER */}]: ${identifier} has not been started, ${subscriberName} will add the relation to tmp shelter`,
584
+ "Broker",
585
+ "warn"
586
+ );
587
+ this._addTmpSubScriberRelation(
588
+ {
589
+ name: getIdentifier({
590
+ name: context.name,
591
+ ip: context.ip
592
+ }),
593
+ client
594
+ },
595
+ publisher
596
+ );
597
+ return;
598
+ }
599
+ try {
600
+ const registeredPublisher = this._publisherMap.get(identifier);
601
+ if (registeredPublisher) {
602
+ registeredPublisher.addSubscriber(
603
+ getIdentifier({
604
+ name: subscriberName,
605
+ ip: context.ip
606
+ }),
607
+ client
608
+ );
609
+ fileLog(
610
+ // eslint-disable-next-line @ies/eden/max-calls-in-template
611
+ `[${"ADD_SUBSCRIBER" /* ADD_SUBSCRIBER */}]: ${identifier} has been started, Adding Subscriber ${subscriberName} Succeed, this.__publisherMap are: ${JSON.stringify(
612
+ Array.from(this._publisherMap.entries())
613
+ )}`,
614
+ "Broker",
615
+ "info"
616
+ );
617
+ registeredPublisher.notifySubscriber(
618
+ getIdentifier({
619
+ name: subscriberName,
620
+ ip: context.ip
621
+ }),
622
+ {
623
+ updateKind: "UPDATE_TYPE" /* UPDATE_TYPE */,
624
+ updateMode: import_helpers.UpdateMode.PASSIVE,
625
+ updateSourcePaths: [registeredPublisher.name],
626
+ remoteTypeTarPath: registeredPublisher.remoteTypeTarPath,
627
+ name: registeredPublisher.name
628
+ }
629
+ );
630
+ fileLog(
631
+ // eslint-disable-next-line @ies/eden/max-calls-in-template
632
+ `[${"ADD_SUBSCRIBER" /* ADD_SUBSCRIBER */}]: notifySubscriber Subscriber ${subscriberName}, updateMode: "PASSIVE", updateSourcePaths: ${registeredPublisher.name}`,
633
+ "Broker",
634
+ "info"
635
+ );
636
+ }
637
+ } catch (err) {
638
+ const msg = error(err, "ADD_SUBSCRIBER" /* ADD_SUBSCRIBER */, "Broker");
639
+ client.send(msg);
640
+ client.close();
641
+ }
642
+ });
643
+ }
644
+ // Trigger while consumer exit
645
+ async _removeSubscriber(context, client) {
646
+ const { publishers } = context ?? {};
647
+ const subscriberIdentifier = getIdentifier({
648
+ name: context == null ? void 0 : context.name,
649
+ ip: context == null ? void 0 : context.ip
650
+ });
651
+ publishers.forEach((publisher) => {
652
+ const { name, ip } = publisher;
653
+ const identifier = getIdentifier({
654
+ name,
655
+ ip
656
+ });
657
+ const registeredPublisher = this._publisherMap.get(identifier);
658
+ if (!registeredPublisher) {
659
+ fileLog(
660
+ `[${"EXIT_SUBSCRIBER" /* EXIT_SUBSCRIBER */}], ${identifier} does not exit `,
661
+ "Broker",
662
+ "warn"
663
+ );
664
+ return;
665
+ }
666
+ try {
667
+ fileLog(
668
+ `[${"EXIT_SUBSCRIBER" /* EXIT_SUBSCRIBER */}], ${identifier} will exit `,
669
+ "Broker",
670
+ "INFO"
671
+ );
672
+ registeredPublisher.removeSubscriber(subscriberIdentifier);
673
+ this._clearTmpSubScriberRelation(identifier);
674
+ if (!registeredPublisher.hasSubscribes) {
675
+ this._publisherMap.delete(identifier);
676
+ }
677
+ if (!this.hasPublishers) {
678
+ this.exit();
679
+ }
680
+ } catch (err) {
681
+ const msg = error(err, "EXIT_SUBSCRIBER" /* EXIT_SUBSCRIBER */, "Broker");
682
+ client.send(msg);
683
+ client.close();
684
+ }
685
+ });
686
+ }
687
+ async _removePublisher(context, client) {
688
+ const { name, ip } = context ?? {};
689
+ const identifier = getIdentifier({
690
+ name,
691
+ ip
692
+ });
693
+ const publisher = this._publisherMap.get(identifier);
694
+ if (!publisher) {
695
+ fileLog(
696
+ `[${"EXIT_PUBLISHER" /* EXIT_PUBLISHER */}]: ${identifier}} has not been added, this action will be ingored`,
697
+ "Broker",
698
+ "warn"
699
+ );
700
+ return;
701
+ }
702
+ try {
703
+ const { subscribers } = publisher;
704
+ subscribers.forEach((subscriber, subscriberIdentifier) => {
705
+ this._addTmpSubScriberRelation(
706
+ {
707
+ name: subscriberIdentifier,
708
+ client: subscriber
709
+ },
710
+ { name: publisher.name, ip: publisher.ip }
711
+ );
712
+ fileLog(
713
+ // eslint-disable-next-line max-len
714
+ `[${"EXIT_PUBLISHER" /* EXIT_PUBLISHER */}]: ${identifier} is removing , subscriber: ${subscriberIdentifier} will be add tmpSubScriberRelation`,
715
+ "Broker",
716
+ "info"
717
+ );
718
+ });
719
+ this._publisherMap.delete(identifier);
720
+ fileLog(
721
+ `[${"EXIT_PUBLISHER" /* EXIT_PUBLISHER */}]: ${identifier} is removed `,
722
+ "Broker",
723
+ "info"
724
+ );
725
+ if (!this.hasPublishers) {
726
+ fileLog(
727
+ `[${"EXIT_PUBLISHER" /* EXIT_PUBLISHER */}]: _publisherMap is empty, all server will exit `,
728
+ "Broker",
729
+ "warn"
730
+ );
731
+ this.exit();
732
+ }
733
+ } catch (err) {
734
+ const msg = error(err, "EXIT_PUBLISHER" /* EXIT_PUBLISHER */, "Broker");
735
+ client.send(msg);
736
+ client.close();
737
+ }
738
+ }
739
+ async _addWebClient(context, client) {
740
+ const { name } = context ?? {};
741
+ const identifier = getIdentifier({
742
+ name
743
+ });
744
+ if (this._webClientMap.has(identifier)) {
745
+ fileLog(
746
+ `${identifier}} has been added, this action will override prev WebClient`,
747
+ "Broker",
748
+ "warn"
749
+ );
750
+ }
751
+ try {
752
+ this._webClientMap.set(identifier, client);
753
+ fileLog(`${identifier} adding WebClient Succeed`, "Broker", "info");
754
+ } catch (err) {
755
+ const msg = error(err, "ADD_WEB_CLIENT" /* ADD_WEB_CLIENT */, "Broker");
756
+ client.send(msg);
757
+ client.close();
758
+ }
759
+ }
760
+ async _notifyWebClient(context, client) {
761
+ const { name, updateMode } = context ?? {};
762
+ const identifier = getIdentifier({
763
+ name
764
+ });
765
+ const webClient = this._webClientMap.get(identifier);
766
+ if (!webClient) {
767
+ fileLog(
768
+ `[${"NOTIFY_WEB_CLIENT" /* NOTIFY_WEB_CLIENT */}] ${identifier} has not been added, this action will be ignored`,
769
+ "Broker",
770
+ "warn"
771
+ );
772
+ return;
773
+ }
774
+ try {
775
+ const api = new ReloadWebClientAPI({ name, updateMode });
776
+ webClient.send(JSON.stringify(api));
777
+ fileLog(
778
+ `[${"NOTIFY_WEB_CLIENT" /* NOTIFY_WEB_CLIENT */}] Notify ${name} WebClient Succeed`,
779
+ "Broker",
780
+ "info"
781
+ );
782
+ } catch (err) {
783
+ const msg = error(err, "NOTIFY_WEB_CLIENT" /* NOTIFY_WEB_CLIENT */, "Broker");
784
+ client.send(msg);
785
+ client.close();
786
+ }
787
+ }
788
+ // app1 consumes provider1, and provider1 not launch. this._tmpSubscriberShelter at this time: {provider1: Map{subscribers: Map{app1: app1+ip+client'}, timestamp: 'xx'} }
789
+ _addTmpSubScriberRelation(subscriber, publisher) {
790
+ const publisherIdentifier = getIdentifier({
791
+ name: publisher.name,
792
+ ip: publisher.ip
793
+ });
794
+ const subscriberIdentifier = subscriber.name;
795
+ const shelter = this._tmpSubscriberShelter.get(publisherIdentifier);
796
+ if (!shelter) {
797
+ const map = /* @__PURE__ */ new Map();
798
+ map.set(subscriberIdentifier, subscriber);
799
+ this._tmpSubscriberShelter.set(publisherIdentifier, {
800
+ subscribers: map,
801
+ timestamp: Date.now()
802
+ });
803
+ fileLog(
804
+ `[AddTmpSubscriberRelation] ${publisherIdentifier}'s subscriber has ${subscriberIdentifier} `,
805
+ "Broker",
806
+ "info"
807
+ );
808
+ return;
809
+ }
810
+ const tmpSubScriberShelterSubscriber = shelter.subscribers.get(subscriberIdentifier);
811
+ if (tmpSubScriberShelterSubscriber) {
812
+ fileLog(
813
+ `[AddTmpSubscriberRelation] ${publisherIdentifier} and ${subscriberIdentifier} relation has been added`,
814
+ "Broker",
815
+ "warn"
816
+ );
817
+ shelter.subscribers.set(subscriberIdentifier, subscriber);
818
+ shelter.timestamp = Date.now();
819
+ } else {
820
+ fileLog(
821
+ // eslint-disable-next-line max-len
822
+ `AddTmpSubscriberLog ${publisherIdentifier}'s shelter has been added, update shelter.subscribers ${subscriberIdentifier}`,
823
+ "Broker",
824
+ "warn"
825
+ );
826
+ shelter.subscribers.set(subscriberIdentifier, subscriber);
827
+ }
828
+ }
829
+ _getTmpSubScribers(publisherIdentifier) {
830
+ var _a;
831
+ return (_a = this._tmpSubscriberShelter.get(publisherIdentifier)) == null ? void 0 : _a.subscribers;
832
+ }
833
+ // after adding publisher, it will change the temp subscriber to regular subscriber
834
+ _consumeTmpSubScribers(publisher, tmpSubScribers) {
835
+ tmpSubScribers.forEach((tmpSubScriber, identifier) => {
836
+ fileLog(
837
+ `notifyTmpSubScribers ${publisher.name} will be add a subscriber: ${identifier} `,
838
+ "Broker",
839
+ "warn"
840
+ );
841
+ publisher.addSubscriber(identifier, tmpSubScriber.client);
842
+ publisher.notifySubscriber(identifier, {
843
+ updateKind: "UPDATE_TYPE" /* UPDATE_TYPE */,
844
+ updateMode: import_helpers.UpdateMode.PASSIVE,
845
+ updateSourcePaths: [publisher.name],
846
+ remoteTypeTarPath: publisher.remoteTypeTarPath,
847
+ name: publisher.name
848
+ });
849
+ });
850
+ }
851
+ _clearTmpSubScriberRelation(identifier) {
852
+ this._tmpSubscriberShelter.delete(identifier);
853
+ }
854
+ _clearTmpSubScriberRelations() {
855
+ this._tmpSubscriberShelter.clear();
856
+ }
857
+ _disconnect() {
858
+ this._publisherMap.forEach((publisher) => {
859
+ publisher.close();
860
+ });
861
+ }
862
+ // Every day on 0/6/9/12/15//18, Publishers that have not been connected within 1.5 hours will be cleared regularly.
863
+ // If process.env.FEDERATION_SERVER_TEST is set, it will be read at a specified time.
864
+ _setSchedule() {
865
+ const rule = new import_node_schedule.default.RecurrenceRule();
866
+ if (Number(process.env["FEDERATION_SERVER_TEST"])) {
867
+ const interval = Number(process.env["FEDERATION_SERVER_TEST"]) / 1e3;
868
+ const second = [];
869
+ for (let i = 0; i < 60; i = i + interval) {
870
+ second.push(i);
871
+ }
872
+ rule.second = second;
873
+ } else {
874
+ rule.second = 0;
875
+ rule.hour = [0, 3, 6, 9, 12, 15, 18];
876
+ rule.minute = 0;
877
+ }
878
+ const serverTest = Number(process.env["FEDERATION_SERVER_TEST"]);
879
+ this._scheduleJob = import_node_schedule.default.scheduleJob(rule, () => {
880
+ this._tmpSubscriberShelter.forEach((tmpSubscriber, identifier) => {
881
+ fileLog(
882
+ ` _clearTmpSubScriberRelation ${identifier}, ${Date.now() - tmpSubscriber.timestamp >= (process.env["GARFISH_MODULE_SERVER_TEST"] ? serverTest : _Broker.DEFAULT_WAITING_TIME)}`,
883
+ "Broker",
884
+ "info"
885
+ );
886
+ if (Date.now() - tmpSubscriber.timestamp >= (process.env["FEDERATION_SERVER_TEST"] ? serverTest : _Broker.DEFAULT_WAITING_TIME)) {
887
+ this._clearTmpSubScriberRelation(identifier);
888
+ }
889
+ });
890
+ });
891
+ }
892
+ _clearSchedule() {
893
+ if (!this._scheduleJob) {
894
+ return;
895
+ }
896
+ this._scheduleJob.cancel();
897
+ this._scheduleJob = null;
898
+ }
899
+ _stopWhenSIGTERMOrSIGINT() {
900
+ process.on("SIGTERM", () => {
901
+ this.exit();
902
+ });
903
+ process.on("SIGINT", () => {
904
+ this.exit();
905
+ });
906
+ }
907
+ _handleUnexpectedExit() {
908
+ process.on("unhandledRejection", (error2) => {
909
+ console.error("Unhandled Rejection Error: ", error2);
910
+ fileLog(`Unhandled Rejection Error: ${error2}`, "Broker", "fatal");
911
+ process.exit(1);
912
+ });
913
+ process.on("uncaughtException", (error2) => {
914
+ console.error("Unhandled Exception Error: ", error2);
915
+ fileLog(`Unhandled Rejection Error: ${error2}`, "Broker", "fatal");
916
+ process.exit(1);
917
+ });
918
+ }
919
+ async start() {
920
+ }
921
+ exit() {
922
+ const brokerExitLog = new BrokerExitLog();
923
+ this.broadcast(JSON.stringify(brokerExitLog));
924
+ this._disconnect();
925
+ this._clearSchedule();
926
+ this._clearTmpSubScriberRelations();
927
+ this._webSocketServer && this._webSocketServer.close();
928
+ this._secureWebSocketServer && this._secureWebSocketServer.close();
929
+ process.exit(0);
930
+ }
931
+ broadcast(message) {
932
+ var _a, _b;
933
+ fileLog(
934
+ `[broadcast] exit info : ${JSON.stringify(message)}`,
935
+ "Broker",
936
+ "warn"
937
+ );
938
+ (_a = this._webSocketServer) == null ? void 0 : _a.clients.forEach((client) => {
939
+ client.send(JSON.stringify(message));
940
+ });
941
+ (_b = this._secureWebSocketServer) == null ? void 0 : _b.clients.forEach((client) => {
942
+ client.send(JSON.stringify(message));
943
+ });
944
+ }
945
+ };
946
+ _Broker.WEB_SOCKET_CONNECT_MAGIC_ID = WEB_SOCKET_CONNECT_MAGIC_ID;
947
+ _Broker.DEFAULT_WEB_SOCKET_PORT = DEFAULT_WEB_SOCKET_PORT;
948
+ _Broker.DEFAULT_SECURE_WEB_SOCKET_PORT = 16324;
949
+ _Broker.DEFAULT_WAITING_TIME = 1.5 * 60 * 60 * 1e3;
950
+ var Broker = _Broker;
951
+
952
+ // packages/dts-plugin/src/server/broker/createBroker.ts
953
+ var import_child_process = require("child_process");
954
+ var import_path = __toESM(require("path"));
955
+ function createBroker() {
956
+ const startBrokerPath = import_path.default.resolve(__dirname, "./startBroker.js");
957
+ const sub = (0, import_child_process.fork)(startBrokerPath, [], {
958
+ detached: true,
959
+ stdio: "ignore",
960
+ env: process.env
961
+ });
962
+ sub.send("start");
963
+ sub.unref();
964
+ return sub;
965
+ }
966
+
967
+ // packages/dts-plugin/src/server/DevServer.ts
968
+ var ModuleFederationDevServer = class {
969
+ constructor(ctx) {
970
+ this._publishWebSocket = null;
971
+ this._subscriberWebsocketMap = {};
972
+ this._reconnect = true;
973
+ this._reconnectTimes = 0;
974
+ this._isConnected = false;
975
+ this._isReconnecting = false;
976
+ this._updateCallback = () => Promise.resolve(void 0);
977
+ const { name, remotes, remoteTypeTarPath, updateCallback: updateCallback2 } = ctx;
978
+ this._ip = getIPV4();
979
+ this._name = name;
980
+ this._remotes = remotes;
981
+ this._remoteTypeTarPath = remoteTypeTarPath;
982
+ this._updateCallback = updateCallback2;
983
+ this._stopWhenSIGTERMOrSIGINT();
984
+ this._handleUnexpectedExit();
985
+ this._connectPublishToServer();
986
+ }
987
+ _connectPublishToServer() {
988
+ if (!this._reconnect) {
989
+ return;
990
+ }
991
+ fileLog(
992
+ `Publisher:${this._name} Trying to connect to ws://${this._ip}:${Broker.DEFAULT_WEB_SOCKET_PORT}...`,
993
+ MF_SERVER_IDENTIFIER,
994
+ "info"
995
+ );
996
+ this._publishWebSocket = new import_isomorphic_ws2.default(
997
+ `ws://${this._ip}:${Broker.DEFAULT_WEB_SOCKET_PORT}?WEB_SOCKET_CONNECT_MAGIC_ID=${Broker.WEB_SOCKET_CONNECT_MAGIC_ID}`
998
+ );
999
+ this._publishWebSocket.on("open", () => {
1000
+ var _a;
1001
+ fileLog(
1002
+ `Current pid: ${process.pid}, publisher:${this._name} connected to ws://${this._ip}:${Broker.DEFAULT_WEB_SOCKET_PORT}, starting service...`,
1003
+ MF_SERVER_IDENTIFIER,
1004
+ "info"
1005
+ );
1006
+ this._isConnected = true;
1007
+ const startGarfishModule = new AddPublisherAction({
1008
+ name: this._name,
1009
+ ip: this._ip,
1010
+ remoteTypeTarPath: this._remoteTypeTarPath
1011
+ });
1012
+ (_a = this._publishWebSocket) == null ? void 0 : _a.send(JSON.stringify(startGarfishModule));
1013
+ this._connectSubscribers();
1014
+ });
1015
+ this._publishWebSocket.on("message", (message) => {
1016
+ var _a, _b;
1017
+ try {
1018
+ const parsedMessage = JSON.parse(
1019
+ message.toString()
1020
+ );
1021
+ if (parsedMessage.type === "Log") {
1022
+ if (parsedMessage.kind === "BrokerExitLog" /* BrokerExitLog */) {
1023
+ fileLog(
1024
+ `Receive broker exit signal, ${this._name} service will exit...`,
1025
+ MF_SERVER_IDENTIFIER,
1026
+ "warn"
1027
+ );
1028
+ this._exit();
1029
+ }
1030
+ }
1031
+ } catch (err) {
1032
+ console.error(err);
1033
+ const exitPublisher = new ExitPublisherAction({
1034
+ name: this._name,
1035
+ ip: this._ip
1036
+ });
1037
+ const exitSubscriber = new ExitSubscriberAction({
1038
+ name: this._name,
1039
+ ip: this._ip,
1040
+ publishers: this._remotes.map((remote) => ({
1041
+ name: remote.name,
1042
+ ip: remote.ip
1043
+ }))
1044
+ });
1045
+ (_a = this._publishWebSocket) == null ? void 0 : _a.send(JSON.stringify(exitPublisher));
1046
+ (_b = this._publishWebSocket) == null ? void 0 : _b.send(JSON.stringify(exitSubscriber));
1047
+ fileLog(
1048
+ "Parse messages error, ModuleFederationDevServer will exit...",
1049
+ MF_SERVER_IDENTIFIER,
1050
+ "fatal"
1051
+ );
1052
+ this._exit();
1053
+ }
1054
+ });
1055
+ this._publishWebSocket.on("close", (code) => {
1056
+ fileLog(
1057
+ `Connection closed with code ${code}.`,
1058
+ MF_SERVER_IDENTIFIER,
1059
+ "warn"
1060
+ );
1061
+ this._publishWebSocket && this._publishWebSocket.close();
1062
+ this._publishWebSocket = null;
1063
+ if (!this._reconnect) {
1064
+ return;
1065
+ }
1066
+ const reconnectTime = fib(++this._reconnectTimes);
1067
+ fileLog(
1068
+ `start reconnecting to server after ${reconnectTime}s.`,
1069
+ MF_SERVER_IDENTIFIER,
1070
+ "info"
1071
+ );
1072
+ setTimeout(() => this._connectPublishToServer(), reconnectTime * 1e3);
1073
+ });
1074
+ this._publishWebSocket.on(
1075
+ "error",
1076
+ this._tryCreateBackgroundBroker.bind(this)
1077
+ );
1078
+ }
1079
+ // Associate the remotes(Subscriber) to the Broker
1080
+ _connectSubscriberToServer(remote) {
1081
+ const { name, ip } = remote;
1082
+ fileLog(
1083
+ `remote module:${name} trying to connect to ws://${ip}:${Broker.DEFAULT_WEB_SOCKET_PORT}...`,
1084
+ MF_SERVER_IDENTIFIER,
1085
+ "info"
1086
+ );
1087
+ const identifier = getIdentifier({
1088
+ name,
1089
+ ip
1090
+ });
1091
+ this._subscriberWebsocketMap[identifier] = new import_isomorphic_ws2.default(
1092
+ `ws://${ip}:${Broker.DEFAULT_WEB_SOCKET_PORT}?WEB_SOCKET_CONNECT_MAGIC_ID=${Broker.WEB_SOCKET_CONNECT_MAGIC_ID}`
1093
+ );
1094
+ this._subscriberWebsocketMap[identifier].on("open", () => {
1095
+ fileLog(
1096
+ `Current pid: ${process.pid} remote module: ${name} connected to ws://${ip}:${Broker.DEFAULT_WEB_SOCKET_PORT}, starting service...`,
1097
+ MF_SERVER_IDENTIFIER,
1098
+ "info"
1099
+ );
1100
+ const addSubscriber = new AddSubscriberAction({
1101
+ name: this._name,
1102
+ // module self name
1103
+ ip: this._ip,
1104
+ publishers: [
1105
+ {
1106
+ name,
1107
+ // remote's name
1108
+ ip
1109
+ }
1110
+ ]
1111
+ });
1112
+ this._subscriberWebsocketMap[identifier].send(
1113
+ JSON.stringify(addSubscriber)
1114
+ );
1115
+ });
1116
+ this._subscriberWebsocketMap[identifier].on("message", async (message) => {
1117
+ try {
1118
+ const parsedMessage = JSON.parse(
1119
+ message.toString()
1120
+ );
1121
+ if (parsedMessage.type === "Log") {
1122
+ if (parsedMessage.kind === "BrokerExitLog" /* BrokerExitLog */) {
1123
+ fileLog(
1124
+ `${identifier}'s Server exit, thus ${identifier} will no longer has reload ability.`,
1125
+ MF_SERVER_IDENTIFIER,
1126
+ "warn"
1127
+ );
1128
+ this._exit();
1129
+ }
1130
+ }
1131
+ if (parsedMessage.type === "API") {
1132
+ if (parsedMessage.kind === "UPDATE_SUBSCRIBER" /* UPDATE_SUBSCRIBER */) {
1133
+ const {
1134
+ payload: {
1135
+ updateKind,
1136
+ updateSourcePaths,
1137
+ name: subscribeName,
1138
+ remoteTypeTarPath,
1139
+ updateMode
1140
+ }
1141
+ } = parsedMessage;
1142
+ await this._updateSubscriber({
1143
+ remoteTypeTarPath,
1144
+ name: subscribeName,
1145
+ updateKind,
1146
+ updateMode,
1147
+ updateSourcePaths
1148
+ });
1149
+ }
1150
+ }
1151
+ } catch (err) {
1152
+ console.error(err);
1153
+ const exitSubscriber = new ExitSubscriberAction({
1154
+ name: this._name,
1155
+ ip: this._ip,
1156
+ publishers: [
1157
+ {
1158
+ name,
1159
+ ip
1160
+ }
1161
+ ]
1162
+ });
1163
+ this._subscriberWebsocketMap[identifier].send(
1164
+ JSON.stringify(exitSubscriber)
1165
+ );
1166
+ fileLog(
1167
+ `${identifier} exit,
1168
+ error: ${err instanceof Error ? err.toString() : JSON.stringify(err)}
1169
+ `,
1170
+ MF_SERVER_IDENTIFIER,
1171
+ "warn"
1172
+ );
1173
+ }
1174
+ });
1175
+ this._subscriberWebsocketMap[identifier].on("close", (code) => {
1176
+ fileLog(
1177
+ `Connection closed with code ${code}.`,
1178
+ MF_SERVER_IDENTIFIER,
1179
+ "warn"
1180
+ );
1181
+ this._subscriberWebsocketMap[identifier] && this._subscriberWebsocketMap[identifier].close();
1182
+ delete this._subscriberWebsocketMap[identifier];
1183
+ });
1184
+ }
1185
+ _connectSubscribers() {
1186
+ this._remotes.forEach((remote) => {
1187
+ this._connectSubscriberToServer(remote);
1188
+ });
1189
+ }
1190
+ // app1 consumes provider1. And the function will be triggered when provider1 code change.
1191
+ async _updateSubscriber(options) {
1192
+ var _a;
1193
+ const {
1194
+ updateMode,
1195
+ updateKind,
1196
+ updateSourcePaths,
1197
+ name,
1198
+ remoteTypeTarPath
1199
+ } = options;
1200
+ if (updateMode === import_helpers2.UpdateMode.PASSIVE && updateSourcePaths.includes(this._name)) {
1201
+ fileLog(
1202
+ // eslint-disable-next-line max-len
1203
+ `[_updateSubscriber] run, updateSourcePaths:${updateSourcePaths} includes ${this._name}, update ignore!`,
1204
+ MF_SERVER_IDENTIFIER,
1205
+ "warn"
1206
+ );
1207
+ return;
1208
+ }
1209
+ if (updateSourcePaths.slice(-1)[0] === this._name) {
1210
+ fileLog(
1211
+ `[_updateSubscriber] run, updateSourcePaths:${updateSourcePaths} ends is ${this._name}, update ignore!`,
1212
+ MF_SERVER_IDENTIFIER,
1213
+ "warn"
1214
+ );
1215
+ return;
1216
+ }
1217
+ fileLog(
1218
+ // eslint-disable-next-line max-len
1219
+ `[_updateSubscriber] run, updateSourcePaths:${updateSourcePaths}, current module:${this._name}, update start...`,
1220
+ MF_SERVER_IDENTIFIER,
1221
+ "info"
1222
+ );
1223
+ await this._updateCallback({
1224
+ name,
1225
+ updateMode,
1226
+ updateKind,
1227
+ updateSourcePaths,
1228
+ remoteTypeTarPath
1229
+ });
1230
+ const newUpdateSourcePaths = updateSourcePaths.concat(this._name);
1231
+ const updatePublisher = new UpdatePublisherAction({
1232
+ name: this._name,
1233
+ ip: this._ip,
1234
+ updateMode: import_helpers2.UpdateMode.PASSIVE,
1235
+ updateKind,
1236
+ updateSourcePaths: newUpdateSourcePaths,
1237
+ remoteTypeTarPath: this._remoteTypeTarPath
1238
+ });
1239
+ fileLog(
1240
+ // eslint-disable-next-line max-len
1241
+ `[_updateSubscriber] run, updateSourcePaths:${newUpdateSourcePaths}, update publisher ${this._name} start...`,
1242
+ MF_SERVER_IDENTIFIER,
1243
+ "info"
1244
+ );
1245
+ (_a = this._publishWebSocket) == null ? void 0 : _a.send(JSON.stringify(updatePublisher));
1246
+ }
1247
+ _tryCreateBackgroundBroker(err) {
1248
+ if (!((err == null ? void 0 : err.code) === "ECONNREFUSED" && err.port === Broker.DEFAULT_WEB_SOCKET_PORT)) {
1249
+ fileLog(`websocket error: ${err.stack}`, MF_SERVER_IDENTIFIER, "fatal");
1250
+ return;
1251
+ }
1252
+ fileLog(
1253
+ `Failed to connect to ws://${this._ip}:${Broker.DEFAULT_WEB_SOCKET_PORT}...`,
1254
+ MF_SERVER_IDENTIFIER,
1255
+ "fatal"
1256
+ );
1257
+ this._isReconnecting = true;
1258
+ setTimeout(
1259
+ () => {
1260
+ this._isReconnecting = false;
1261
+ if (this._reconnect === false) {
1262
+ return;
1263
+ }
1264
+ fileLog(
1265
+ "Creating new background broker...",
1266
+ MF_SERVER_IDENTIFIER,
1267
+ "warn"
1268
+ );
1269
+ const broker = createBroker();
1270
+ broker.on("message", (message) => {
1271
+ if (message === "ready") {
1272
+ fileLog("background broker started.", MF_SERVER_IDENTIFIER, "info");
1273
+ this._reconnectTimes = 1;
1274
+ if (process.send) {
1275
+ process.send("ready");
1276
+ }
1277
+ }
1278
+ });
1279
+ },
1280
+ Math.ceil(100 * Math.random())
1281
+ );
1282
+ }
1283
+ _stopWhenSIGTERMOrSIGINT() {
1284
+ process.on("SIGTERM", () => {
1285
+ fileLog(
1286
+ `Process(${process.pid}) SIGTERM, ModuleFederationDevServer will exit...`,
1287
+ MF_SERVER_IDENTIFIER,
1288
+ "warn"
1289
+ );
1290
+ this._exit();
1291
+ });
1292
+ process.on("SIGINT", () => {
1293
+ fileLog(
1294
+ `Process(${process.pid}) SIGINT, ModuleFederationDevServer will exit...`,
1295
+ MF_SERVER_IDENTIFIER,
1296
+ "warn"
1297
+ );
1298
+ this._exit();
1299
+ });
1300
+ }
1301
+ _handleUnexpectedExit() {
1302
+ process.on("unhandledRejection", (error2) => {
1303
+ if (this._isReconnecting) {
1304
+ return;
1305
+ }
1306
+ console.error("Unhandled Rejection Error: ", error2);
1307
+ fileLog(
1308
+ `Process(${process.pid}) unhandledRejection, garfishModuleServer will exit...`,
1309
+ MF_SERVER_IDENTIFIER,
1310
+ "error"
1311
+ );
1312
+ this._exit();
1313
+ });
1314
+ process.on("uncaughtException", (error2) => {
1315
+ if (this._isReconnecting) {
1316
+ return;
1317
+ }
1318
+ console.error("Unhandled Exception Error: ", error2);
1319
+ fileLog(
1320
+ `Process(${process.pid}) uncaughtException, garfishModuleServer will exit...`,
1321
+ MF_SERVER_IDENTIFIER,
1322
+ "error"
1323
+ );
1324
+ this._exit();
1325
+ });
1326
+ }
1327
+ _exit() {
1328
+ this._reconnect = false;
1329
+ if (this._publishWebSocket) {
1330
+ const exitPublisher = new ExitPublisherAction({
1331
+ name: this._name,
1332
+ ip: this._ip
1333
+ });
1334
+ this._publishWebSocket.send(JSON.stringify(exitPublisher));
1335
+ this._publishWebSocket.on("message", (message) => {
1336
+ const parsedMessage = JSON.parse(
1337
+ message.toString()
1338
+ );
1339
+ fileLog(
1340
+ `[${parsedMessage.kind}]: ${JSON.stringify(parsedMessage)}`,
1341
+ MF_SERVER_IDENTIFIER,
1342
+ "info"
1343
+ );
1344
+ });
1345
+ }
1346
+ if (this._publishWebSocket) {
1347
+ this._publishWebSocket.close();
1348
+ this._publishWebSocket = null;
1349
+ }
1350
+ process.exit(0);
1351
+ }
1352
+ exit() {
1353
+ this._exit();
1354
+ }
1355
+ update(options) {
1356
+ if (!this._publishWebSocket || !this._isConnected) {
1357
+ return;
1358
+ }
1359
+ const { updateKind, updateMode, updateSourcePaths } = options;
1360
+ fileLog(
1361
+ `update run, ${this._name} module update, updateKind: ${updateKind}, updateMode: ${updateMode}, updateSourcePaths: ${updateSourcePaths}`,
1362
+ MF_SERVER_IDENTIFIER,
1363
+ "info"
1364
+ );
1365
+ if (updateKind === "RELOAD_PAGE" /* RELOAD_PAGE */) {
1366
+ const notifyWebClient = new NotifyWebClientAction({
1367
+ name: this._name,
1368
+ updateMode
1369
+ });
1370
+ this._publishWebSocket.send(JSON.stringify(notifyWebClient));
1371
+ return;
1372
+ }
1373
+ const updatePublisher = new UpdatePublisherAction({
1374
+ name: this._name,
1375
+ ip: this._ip,
1376
+ updateMode,
1377
+ updateKind,
1378
+ updateSourcePaths: [this._name],
1379
+ remoteTypeTarPath: this._remoteTypeTarPath
1380
+ });
1381
+ this._publishWebSocket.send(JSON.stringify(updatePublisher));
1382
+ }
1383
+ };
1384
+
1385
+ // packages/dts-plugin/src/server/createKoaServer.ts
1386
+ var import_fs_extra = __toESM(require("fs-extra"));
1387
+ var import_koa = __toESM(require("koa"));
1388
+ async function createKoaServer(options) {
1389
+ const { typeTarPath } = options;
1390
+ const freeport = await getFreePort();
1391
+ const app = new import_koa.default();
1392
+ app.use(async (ctx, next) => {
1393
+ if (ctx.path === `/${DEFAULT_TAR_NAME}`) {
1394
+ ctx.status = 200;
1395
+ ctx.body = import_fs_extra.default.createReadStream(typeTarPath);
1396
+ ctx.response.type = "application/x-gzip";
1397
+ } else {
1398
+ await next();
1399
+ }
1400
+ });
1401
+ app.listen(freeport);
1402
+ return {
1403
+ server: app,
1404
+ serverAddress: `http://${getIPV4()}:${freeport}`
1405
+ };
1406
+ }
1407
+
1408
+ // packages/dts-plugin/src/dev-worker/forkDevWorker.ts
1409
+ var DEFAULT_LOCAL_IPS = ["localhost", "127.0.0.1"];
1410
+ function getIpFromEntry(entry) {
1411
+ let ip;
1412
+ entry.replace(/https?:\/\/([0-9|.]+|localhost):/, (str, matched) => {
1413
+ ip = matched;
1414
+ return str;
1415
+ });
1416
+ if (ip) {
1417
+ return DEFAULT_LOCAL_IPS.includes(ip) ? getIPV4() : ip;
1418
+ }
1419
+ }
1420
+ var typesManager;
1421
+ var serverAddress;
1422
+ var moduleServer;
1423
+ var cacheOptions;
1424
+ function getLocalRemoteNames(options, encodeNameIdentifier) {
1425
+ if (!options) {
1426
+ return [];
1427
+ }
1428
+ const { mapRemotesToDownload } = (0, import_helpers3.retrieveHostConfig)(options);
1429
+ return Object.keys(mapRemotesToDownload).reduce(
1430
+ (sum, remoteModuleName) => {
1431
+ const remoteInfo = mapRemotesToDownload[remoteModuleName];
1432
+ const name = encodeNameIdentifier ? (0, import_sdk3.decodeName)(remoteInfo.name, encodeNameIdentifier) : remoteInfo.name;
1433
+ const ip = getIpFromEntry(remoteInfo.url);
1434
+ if (!ip) {
1435
+ return sum;
1436
+ }
1437
+ sum.push({
1438
+ name,
1439
+ entry: remoteInfo.url,
1440
+ ip
1441
+ });
1442
+ return sum;
1443
+ },
1444
+ []
1445
+ );
1446
+ }
1447
+ async function updateCallback({
1448
+ updateMode,
1449
+ name,
1450
+ remoteTypeTarPath
1451
+ }) {
1452
+ const { disableHotTypesReload, disableLiveReload } = cacheOptions || {};
1453
+ fileLog(
1454
+ `sync remote module ${name}, types to vmok ${cacheOptions == null ? void 0 : cacheOptions.name},typesManager.updateTypes run`,
1455
+ "forkDevWorker",
1456
+ "info"
1457
+ );
1458
+ if (!disableLiveReload && moduleServer) {
1459
+ moduleServer.update({
1460
+ updateKind: "RELOAD_PAGE" /* RELOAD_PAGE */,
1461
+ updateMode: import_helpers3.UpdateMode.PASSIVE
1462
+ });
1463
+ }
1464
+ if (!disableHotTypesReload && typesManager) {
1465
+ await typesManager.updateTypes({
1466
+ updateMode,
1467
+ remoteName: name,
1468
+ remoteTarPath: remoteTypeTarPath
1469
+ });
1470
+ }
1471
+ }
1472
+ async function forkDevWorker(options, action) {
1473
+ if (!typesManager) {
1474
+ const { name, remote, host, extraOptions } = options;
1475
+ const DTSManagerConstructor = (0, import_helpers3.getDTSManagerConstructor)(
1476
+ remote == null ? void 0 : remote.implementation
1477
+ );
1478
+ typesManager = new DTSManagerConstructor({
1479
+ remote,
1480
+ host,
1481
+ extraOptions
1482
+ });
1483
+ if (!options.disableHotTypesReload && remote) {
1484
+ const { remoteOptions, tsConfig } = (0, import_helpers3.retrieveRemoteConfig)(remote);
1485
+ const mfTypesPath = (0, import_helpers3.retrieveMfTypesPath)(tsConfig, remoteOptions);
1486
+ const mfTypesZipPath = (0, import_helpers3.retrieveTypesZipPath)(mfTypesPath, remoteOptions);
1487
+ await Promise.all([
1488
+ createKoaServer({
1489
+ typeTarPath: mfTypesZipPath
1490
+ }).then((res) => {
1491
+ serverAddress = res.serverAddress;
1492
+ }),
1493
+ typesManager.generateTypes()
1494
+ ]).catch((err) => {
1495
+ fileLog(
1496
+ `${name} module generateTypes done, localServerAddress: ${JSON.stringify(
1497
+ err
1498
+ )}`,
1499
+ "forkDevWorker",
1500
+ "error"
1501
+ );
1502
+ });
1503
+ fileLog(
1504
+ `${name} module generateTypes done, localServerAddress: ${serverAddress}`,
1505
+ "forkDevWorker",
1506
+ "info"
1507
+ );
1508
+ }
1509
+ moduleServer = new ModuleFederationDevServer({
1510
+ name,
1511
+ remotes: getLocalRemoteNames(
1512
+ host,
1513
+ extraOptions == null ? void 0 : extraOptions["encodeNameIdentifier"]
1514
+ ),
1515
+ updateCallback,
1516
+ remoteTypeTarPath: `${serverAddress}/${DEFAULT_TAR_NAME}`
1517
+ });
1518
+ cacheOptions = options;
1519
+ }
1520
+ if (action === "update" && cacheOptions) {
1521
+ fileLog(
1522
+ `remoteModule ${cacheOptions.name} receive devWorker update, start typesManager.updateTypes `,
1523
+ "forkDevWorker",
1524
+ "info"
1525
+ );
1526
+ if (!cacheOptions.disableLiveReload) {
1527
+ moduleServer == null ? void 0 : moduleServer.update({
1528
+ updateKind: "RELOAD_PAGE" /* RELOAD_PAGE */,
1529
+ updateMode: import_helpers3.UpdateMode.POSITIVE
1530
+ });
1531
+ }
1532
+ if (!cacheOptions.disableHotTypesReload) {
1533
+ typesManager == null ? void 0 : typesManager.updateTypes({
1534
+ updateMode: import_helpers3.UpdateMode.POSITIVE,
1535
+ remoteName: cacheOptions.name
1536
+ }).then(() => {
1537
+ moduleServer == null ? void 0 : moduleServer.update({
1538
+ updateKind: "UPDATE_TYPE" /* UPDATE_TYPE */,
1539
+ updateMode: import_helpers3.UpdateMode.POSITIVE
1540
+ });
1541
+ });
1542
+ }
1543
+ }
1544
+ }
1545
+ process.on("message", (message) => {
1546
+ fileLog(
1547
+ `ChildProcess(${process.pid}), message: ${JSON.stringify(message)} `,
1548
+ "forkDevWorker",
1549
+ "info"
1550
+ );
1551
+ if (message.type === import_helpers3.rpc.RpcGMCallTypes.EXIT) {
1552
+ fileLog(
1553
+ `ChildProcess(${process.pid}) SIGTERM, Federation DevServer will exit...`,
1554
+ "forkDevWorker",
1555
+ "error"
1556
+ );
1557
+ moduleServer.exit();
1558
+ process.exit(0);
1559
+ }
1560
+ });
1561
+ import_helpers3.rpc.exposeRpc(forkDevWorker);
1562
+ // Annotate the CommonJS export names for ESM import in node:
1563
+ 0 && (module.exports = {
1564
+ forkDevWorker
1565
+ });