@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.
package/dist/index.js ADDED
@@ -0,0 +1,1136 @@
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/index.ts
31
+ var src_exports = {};
32
+ __export(src_exports, {
33
+ DtsPlugin: () => DtsPlugin
34
+ });
35
+ module.exports = __toCommonJS(src_exports);
36
+
37
+ // packages/dts-plugin/src/plugins/DevPlugin.ts
38
+ var import_fs_extra2 = __toESM(require("fs-extra"));
39
+ var import_chalk3 = __toESM(require("chalk"));
40
+
41
+ // packages/dts-plugin/src/dev-worker/createDevWorker.ts
42
+ var path2 = __toESM(require("path"));
43
+ var fse = __toESM(require("fs-extra"));
44
+
45
+ // packages/dts-plugin/src/dev-worker/DevWorker.ts
46
+ var import_path = __toESM(require("path"));
47
+ var import_lodash = __toESM(require("lodash.clonedeepwith"));
48
+ var import_helpers = require("@module-federation/native-federation-typescript/helpers");
49
+ var DevWorker = class {
50
+ constructor(options) {
51
+ this._options = (0, import_lodash.default)(options, (_value, key) => {
52
+ if (key === "manifest") {
53
+ return false;
54
+ }
55
+ });
56
+ this.removeUnSerializationOptions();
57
+ this._rpcWorker = import_helpers.rpc.createRpcWorker(
58
+ import_path.default.resolve(__dirname, "./forkDevWorker.js"),
59
+ {},
60
+ void 0,
61
+ false
62
+ );
63
+ this._res = this._rpcWorker.connect(this._options);
64
+ }
65
+ // moduleFederationConfig.manifest may have un serialization options
66
+ removeUnSerializationOptions() {
67
+ var _a, _b, _c, _d;
68
+ (_b = (_a = this._options.host) == null ? void 0 : _a.moduleFederationConfig) == null ? true : delete _b.manifest;
69
+ (_d = (_c = this._options.remote) == null ? void 0 : _c.moduleFederationConfig) == null ? true : delete _d.manifest;
70
+ }
71
+ get controlledPromise() {
72
+ return this._res;
73
+ }
74
+ update() {
75
+ var _a, _b;
76
+ (_b = (_a = this._rpcWorker.process) == null ? void 0 : _a.send) == null ? void 0 : _b.call(_a, {
77
+ type: import_helpers.rpc.RpcGMCallTypes.CALL,
78
+ id: this._rpcWorker.id,
79
+ args: [void 0, "update"]
80
+ });
81
+ }
82
+ exit() {
83
+ var _a;
84
+ (_a = this._rpcWorker) == null ? void 0 : _a.terminate();
85
+ }
86
+ };
87
+
88
+ // packages/dts-plugin/src/dev-worker/createDevWorker.ts
89
+ async function removeLogFile() {
90
+ try {
91
+ const logDir = path2.resolve(process.cwd(), ".mf/typesGenerate.log");
92
+ await fse.remove(logDir);
93
+ } catch (err) {
94
+ console.error("removeLogFile error", "forkDevWorker", err);
95
+ }
96
+ }
97
+ function createDevWorker(options) {
98
+ removeLogFile();
99
+ return new DevWorker({ ...options });
100
+ }
101
+
102
+ // packages/dts-plugin/src/plugins/DevPlugin.ts
103
+ var import_sdk3 = require("@module-federation/sdk");
104
+
105
+ // packages/dts-plugin/src/server/message/Message.ts
106
+ var Message = class {
107
+ constructor(type, kind) {
108
+ this.type = type;
109
+ this.kind = kind;
110
+ this.time = Date.now();
111
+ }
112
+ };
113
+
114
+ // packages/dts-plugin/src/server/message/API/API.ts
115
+ var API = class extends Message {
116
+ constructor(content, kind) {
117
+ super("API", kind);
118
+ const { code, payload } = content;
119
+ this.code = code;
120
+ this.payload = payload;
121
+ }
122
+ };
123
+
124
+ // packages/dts-plugin/src/server/message/API/UpdateSubscriber.ts
125
+ var UpdateSubscriberAPI = class extends API {
126
+ constructor(payload) {
127
+ super(
128
+ {
129
+ code: 0,
130
+ payload
131
+ },
132
+ "UPDATE_SUBSCRIBER" /* UPDATE_SUBSCRIBER */
133
+ );
134
+ }
135
+ };
136
+
137
+ // packages/dts-plugin/src/server/message/API/ReloadWebClient.ts
138
+ var ReloadWebClientAPI = class extends API {
139
+ constructor(payload) {
140
+ super(
141
+ {
142
+ code: 0,
143
+ payload
144
+ },
145
+ "RELOAD_WEB_CLIENT" /* RELOAD_WEB_CLIENT */
146
+ );
147
+ }
148
+ };
149
+
150
+ // packages/dts-plugin/src/server/utils/index.ts
151
+ var import_sdk2 = require("@module-federation/sdk");
152
+
153
+ // packages/dts-plugin/src/server/utils/logTransform.ts
154
+ var import_chalk = __toESM(require("chalk"));
155
+
156
+ // packages/dts-plugin/src/server/message/Log/Log.ts
157
+ var Log = class extends Message {
158
+ constructor(level, kind, ignoreVerbose = false) {
159
+ super("Log", kind);
160
+ this.ignoreVerbose = false;
161
+ this.level = level;
162
+ this.ignoreVerbose = ignoreVerbose;
163
+ }
164
+ };
165
+
166
+ // packages/dts-plugin/src/server/message/Log/BrokerExitLog.ts
167
+ var BrokerExitLog = class extends Log {
168
+ constructor() {
169
+ super("LOG" /* LOG */, "BrokerExitLog" /* BrokerExitLog */);
170
+ }
171
+ };
172
+
173
+ // packages/dts-plugin/src/server/utils/log.ts
174
+ var import_sdk = require("@module-federation/sdk");
175
+ var log4js = __toESM(require("log4js"));
176
+ var import_chalk2 = __toESM(require("chalk"));
177
+
178
+ // packages/dts-plugin/src/server/constant.ts
179
+ var DEFAULT_WEB_SOCKET_PORT = 16322;
180
+ var WEB_SOCKET_CONNECT_MAGIC_ID = "1hpzW-zo2z-o8io-gfmV1-2cb1d82";
181
+ var WEB_CLIENT_OPTIONS_IDENTIFIER = "__WEB_CLIENT_OPTIONS__";
182
+
183
+ // packages/dts-plugin/src/server/utils/log.ts
184
+ function fileLog(msg, module2, level) {
185
+ var _a, _b;
186
+ if (!((_a = process == null ? void 0 : process.env) == null ? void 0 : _a["FEDERATION_DEBUG"])) {
187
+ return;
188
+ }
189
+ log4js.configure({
190
+ appenders: {
191
+ [module2]: { type: "file", filename: ".mf/typesGenerate.log" },
192
+ default: { type: "file", filename: ".mf/typesGenerate.log" }
193
+ },
194
+ categories: {
195
+ [module2]: { appenders: [module2], level: "error" },
196
+ default: { appenders: ["default"], level: "trace" }
197
+ }
198
+ });
199
+ const logger4 = log4js.getLogger(module2);
200
+ logger4.level = "debug";
201
+ (_b = logger4[level]) == null ? void 0 : _b.call(logger4, msg);
202
+ }
203
+ function error(error2, action, from) {
204
+ const err = error2 instanceof Error ? error2 : new Error(`${action} error`);
205
+ fileLog(`[${action}] error: ${err}`, from, "fatal");
206
+ return err.toString();
207
+ }
208
+
209
+ // packages/dts-plugin/src/server/utils/index.ts
210
+ function getIdentifier(options) {
211
+ const { ip, name } = options;
212
+ return `mf ${import_sdk2.SEPARATOR}${name}${ip ? `${import_sdk2.SEPARATOR}${ip}` : ""}`;
213
+ }
214
+
215
+ // packages/dts-plugin/src/server/Publisher.ts
216
+ var Publisher = class {
217
+ constructor(ctx) {
218
+ this._name = ctx.name;
219
+ this._ip = ctx.ip;
220
+ this._remoteTypeTarPath = ctx.remoteTypeTarPath;
221
+ this._subscribers = /* @__PURE__ */ new Map();
222
+ }
223
+ get identifier() {
224
+ return getIdentifier({
225
+ name: this._name,
226
+ ip: this._ip
227
+ });
228
+ }
229
+ get name() {
230
+ return this._name;
231
+ }
232
+ get ip() {
233
+ return this._ip;
234
+ }
235
+ get remoteTypeTarPath() {
236
+ return this._remoteTypeTarPath;
237
+ }
238
+ get hasSubscribes() {
239
+ return Boolean(this._subscribers.size);
240
+ }
241
+ get subscribers() {
242
+ return this._subscribers;
243
+ }
244
+ addSubscriber(identifier, subscriber) {
245
+ fileLog(`${this.name} set subscriber: ${identifier}`, "Publisher", "info");
246
+ this._subscribers.set(identifier, subscriber);
247
+ }
248
+ removeSubscriber(identifier) {
249
+ if (this._subscribers.has(identifier)) {
250
+ fileLog(
251
+ `${this.name} removeSubscriber: ${identifier}`,
252
+ "Publisher",
253
+ "warn"
254
+ );
255
+ this._subscribers.delete(identifier);
256
+ }
257
+ }
258
+ notifySubscriber(subscriberIdentifier, options) {
259
+ const subscriber = this._subscribers.get(subscriberIdentifier);
260
+ if (!subscriber) {
261
+ fileLog(
262
+ `[notifySubscriber] ${this.name} notifySubscriber: ${subscriberIdentifier}, does not exits`,
263
+ "Publisher",
264
+ "error"
265
+ );
266
+ return;
267
+ }
268
+ const api = new UpdateSubscriberAPI(options);
269
+ subscriber.send(JSON.stringify(api));
270
+ fileLog(
271
+ `[notifySubscriber] ${this.name} notifySubscriber: ${JSON.stringify(
272
+ subscriberIdentifier
273
+ )}, message: ${JSON.stringify(api)}`,
274
+ "Publisher",
275
+ "info"
276
+ );
277
+ }
278
+ notifySubscribers(options) {
279
+ const api = new UpdateSubscriberAPI(options);
280
+ this.broadcast(api);
281
+ }
282
+ broadcast(message) {
283
+ if (this.hasSubscribes) {
284
+ this._subscribers.forEach((subscriber, key) => {
285
+ fileLog(
286
+ `[BroadCast] ${this.name} notifySubscriber: ${key}, PID: ${process.pid}, message: ${JSON.stringify(message)}`,
287
+ "Publisher",
288
+ "info"
289
+ );
290
+ subscriber.send(JSON.stringify(message));
291
+ });
292
+ } else {
293
+ fileLog(
294
+ `[BroadCast] ${this.name}'s subscribe is empty`,
295
+ "Publisher",
296
+ "warn"
297
+ );
298
+ }
299
+ }
300
+ close() {
301
+ this._subscribers.forEach((_subscriber, identifier) => {
302
+ fileLog(
303
+ `[BroadCast] close ${this.name} remove: ${identifier}`,
304
+ "Publisher",
305
+ "warn"
306
+ );
307
+ this.removeSubscriber(identifier);
308
+ });
309
+ }
310
+ };
311
+
312
+ // packages/dts-plugin/src/server/DevServer.ts
313
+ var import_isomorphic_ws2 = __toESM(require("isomorphic-ws"));
314
+ var import_helpers3 = require("@module-federation/native-federation-typescript/helpers");
315
+
316
+ // packages/dts-plugin/src/server/broker/Broker.ts
317
+ var import_http = require("http");
318
+ var import_helpers2 = require("@module-federation/native-federation-typescript/helpers");
319
+ var import_isomorphic_ws = __toESM(require("isomorphic-ws"));
320
+ var import_node_schedule = __toESM(require("node-schedule"));
321
+ var import_url = require("url");
322
+ var _Broker = class _Broker {
323
+ constructor() {
324
+ // 1.5h
325
+ this._publisherMap = /* @__PURE__ */ new Map();
326
+ this._webClientMap = /* @__PURE__ */ new Map();
327
+ this._tmpSubscriberShelter = /* @__PURE__ */ new Map();
328
+ this._scheduleJob = null;
329
+ this._setSchedule();
330
+ this._startWsServer();
331
+ this._stopWhenSIGTERMOrSIGINT();
332
+ this._handleUnexpectedExit();
333
+ }
334
+ get hasPublishers() {
335
+ return Boolean(this._publisherMap.size);
336
+ }
337
+ async _startWsServer() {
338
+ const wsHandler = (ws, req) => {
339
+ const { url: reqUrl = "" } = req;
340
+ const { query } = (0, import_url.parse)(reqUrl, true);
341
+ const { WEB_SOCKET_CONNECT_MAGIC_ID: WEB_SOCKET_CONNECT_MAGIC_ID2 } = query;
342
+ if (WEB_SOCKET_CONNECT_MAGIC_ID2 === _Broker.WEB_SOCKET_CONNECT_MAGIC_ID) {
343
+ ws.on("message", (message) => {
344
+ try {
345
+ const text = message.toString();
346
+ const action = JSON.parse(text);
347
+ fileLog(`${action == null ? void 0 : action.kind} action received `, "Broker", "info");
348
+ this._takeAction(action, ws);
349
+ } catch (error2) {
350
+ fileLog(`parse action message error: ${error2}`, "Broker", "error");
351
+ }
352
+ });
353
+ ws.on("error", (e) => {
354
+ fileLog(`parse action message error: ${e}`, "Broker", "error");
355
+ });
356
+ } else {
357
+ ws.send("Invalid CONNECT ID.");
358
+ fileLog("Invalid CONNECT ID.", "Broker", "warn");
359
+ ws.close();
360
+ }
361
+ };
362
+ const server = (0, import_http.createServer)();
363
+ this._webSocketServer = new import_isomorphic_ws.default.Server({ noServer: true });
364
+ this._webSocketServer.on("error", (err) => {
365
+ fileLog(`ws error:
366
+ ${err.message}
367
+ ${err.stack}`, "Broker", "error");
368
+ });
369
+ this._webSocketServer.on("listening", () => {
370
+ fileLog(
371
+ `WebSocket server is listening on port ${_Broker.DEFAULT_WEB_SOCKET_PORT}`,
372
+ "Broker",
373
+ "info"
374
+ );
375
+ });
376
+ this._webSocketServer.on("connection", wsHandler);
377
+ this._webSocketServer.on("close", (code) => {
378
+ fileLog(`WebSocket Server Close with Code ${code}`, "Broker", "warn");
379
+ this._webSocketServer && this._webSocketServer.close();
380
+ this._webSocketServer = void 0;
381
+ });
382
+ server.on("upgrade", (req, socket, head) => {
383
+ var _a;
384
+ if (req.url) {
385
+ const { pathname } = (0, import_url.parse)(req.url);
386
+ if (pathname === "/") {
387
+ (_a = this._webSocketServer) == null ? void 0 : _a.handleUpgrade(req, socket, head, (ws) => {
388
+ var _a2;
389
+ (_a2 = this._webSocketServer) == null ? void 0 : _a2.emit("connection", ws, req);
390
+ });
391
+ }
392
+ }
393
+ });
394
+ server.listen(_Broker.DEFAULT_WEB_SOCKET_PORT);
395
+ }
396
+ async _takeAction(action, client) {
397
+ const { kind, payload } = action;
398
+ if (kind === "ADD_PUBLISHER" /* ADD_PUBLISHER */) {
399
+ await this._addPublisher(payload, client);
400
+ }
401
+ if (kind === "UPDATE_PUBLISHER" /* UPDATE_PUBLISHER */) {
402
+ await this._updatePublisher(
403
+ payload,
404
+ client
405
+ );
406
+ }
407
+ if (kind === "ADD_SUBSCRIBER" /* ADD_SUBSCRIBER */) {
408
+ await this._addSubscriber(payload, client);
409
+ }
410
+ if (kind === "EXIT_SUBSCRIBER" /* EXIT_SUBSCRIBER */) {
411
+ await this._removeSubscriber(
412
+ payload,
413
+ client
414
+ );
415
+ }
416
+ if (kind === "EXIT_PUBLISHER" /* EXIT_PUBLISHER */) {
417
+ await this._removePublisher(payload, client);
418
+ }
419
+ if (kind === "ADD_WEB_CLIENT" /* ADD_WEB_CLIENT */) {
420
+ await this._addWebClient(payload, client);
421
+ }
422
+ if (kind === "NOTIFY_WEB_CLIENT" /* NOTIFY_WEB_CLIENT */) {
423
+ await this._notifyWebClient(
424
+ payload,
425
+ client
426
+ );
427
+ }
428
+ }
429
+ async _addPublisher(context, client) {
430
+ const { name, ip, remoteTypeTarPath } = context ?? {};
431
+ const identifier = getIdentifier({ name, ip });
432
+ if (this._publisherMap.has(identifier)) {
433
+ fileLog(
434
+ `[${"ADD_PUBLISHER" /* ADD_PUBLISHER */}] ${identifier} has been added, this action will be ignored`,
435
+ "Broker",
436
+ "warn"
437
+ );
438
+ return;
439
+ }
440
+ try {
441
+ const publisher = new Publisher({ name, ip, remoteTypeTarPath });
442
+ this._publisherMap.set(identifier, publisher);
443
+ fileLog(
444
+ `[${"ADD_PUBLISHER" /* ADD_PUBLISHER */}] ${identifier} Adding Publisher Succeed`,
445
+ "Broker",
446
+ "info"
447
+ );
448
+ const tmpSubScribers = this._getTmpSubScribers(identifier);
449
+ if (tmpSubScribers) {
450
+ fileLog(
451
+ `[${"ADD_PUBLISHER" /* ADD_PUBLISHER */}] consumeTmpSubscriber set ${publisher.name}\u2019s subscribers `,
452
+ "Broker",
453
+ "info"
454
+ );
455
+ this._consumeTmpSubScribers(publisher, tmpSubScribers);
456
+ this._clearTmpSubScriberRelation(identifier);
457
+ }
458
+ } catch (err) {
459
+ const msg = error(err, "ADD_PUBLISHER" /* ADD_PUBLISHER */, "Broker");
460
+ client.send(msg);
461
+ client.close();
462
+ }
463
+ }
464
+ async _updatePublisher(context, client) {
465
+ const {
466
+ name,
467
+ updateMode,
468
+ updateKind,
469
+ updateSourcePaths,
470
+ remoteTypeTarPath,
471
+ ip
472
+ } = context ?? {};
473
+ const identifier = getIdentifier({ name, ip });
474
+ if (!this._publisherMap.has(identifier)) {
475
+ fileLog(
476
+ `[${"UPDATE_PUBLISHER" /* UPDATE_PUBLISHER */}] ${identifier} has not been started, this action will be ignored
477
+ this._publisherMap: ${JSON.stringify(this._publisherMap.entries())}
478
+ `,
479
+ "Broker",
480
+ "warn"
481
+ );
482
+ return;
483
+ }
484
+ try {
485
+ const publisher = this._publisherMap.get(identifier);
486
+ fileLog(
487
+ // eslint-disable-next-line max-len
488
+ `[${"UPDATE_PUBLISHER" /* UPDATE_PUBLISHER */}] ${identifier} update, and notify subscribers to update`,
489
+ "Broker",
490
+ "info"
491
+ );
492
+ if (publisher) {
493
+ publisher.notifySubscribers({
494
+ remoteTypeTarPath,
495
+ name,
496
+ updateMode,
497
+ updateKind,
498
+ updateSourcePaths: updateSourcePaths || []
499
+ });
500
+ }
501
+ } catch (err) {
502
+ const msg = error(err, "UPDATE_PUBLISHER" /* UPDATE_PUBLISHER */, "Broker");
503
+ client.send(msg);
504
+ client.close();
505
+ }
506
+ }
507
+ // app1 consumes provider1,provider2. Dependencies at this time: publishers: [provider1, provider2], subscriberName: app1
508
+ // provider1 is app1's remote
509
+ async _addSubscriber(context, client) {
510
+ const { publishers, name: subscriberName } = context ?? {};
511
+ publishers.forEach((publisher) => {
512
+ const { name, ip } = publisher;
513
+ const identifier = getIdentifier({ name, ip });
514
+ if (!this._publisherMap.has(identifier)) {
515
+ fileLog(
516
+ `[${"ADD_SUBSCRIBER" /* ADD_SUBSCRIBER */}]: ${identifier} has not been started, ${subscriberName} will add the relation to tmp shelter`,
517
+ "Broker",
518
+ "warn"
519
+ );
520
+ this._addTmpSubScriberRelation(
521
+ {
522
+ name: getIdentifier({
523
+ name: context.name,
524
+ ip: context.ip
525
+ }),
526
+ client
527
+ },
528
+ publisher
529
+ );
530
+ return;
531
+ }
532
+ try {
533
+ const registeredPublisher = this._publisherMap.get(identifier);
534
+ if (registeredPublisher) {
535
+ registeredPublisher.addSubscriber(
536
+ getIdentifier({
537
+ name: subscriberName,
538
+ ip: context.ip
539
+ }),
540
+ client
541
+ );
542
+ fileLog(
543
+ // eslint-disable-next-line @ies/eden/max-calls-in-template
544
+ `[${"ADD_SUBSCRIBER" /* ADD_SUBSCRIBER */}]: ${identifier} has been started, Adding Subscriber ${subscriberName} Succeed, this.__publisherMap are: ${JSON.stringify(
545
+ Array.from(this._publisherMap.entries())
546
+ )}`,
547
+ "Broker",
548
+ "info"
549
+ );
550
+ registeredPublisher.notifySubscriber(
551
+ getIdentifier({
552
+ name: subscriberName,
553
+ ip: context.ip
554
+ }),
555
+ {
556
+ updateKind: "UPDATE_TYPE" /* UPDATE_TYPE */,
557
+ updateMode: import_helpers2.UpdateMode.PASSIVE,
558
+ updateSourcePaths: [registeredPublisher.name],
559
+ remoteTypeTarPath: registeredPublisher.remoteTypeTarPath,
560
+ name: registeredPublisher.name
561
+ }
562
+ );
563
+ fileLog(
564
+ // eslint-disable-next-line @ies/eden/max-calls-in-template
565
+ `[${"ADD_SUBSCRIBER" /* ADD_SUBSCRIBER */}]: notifySubscriber Subscriber ${subscriberName}, updateMode: "PASSIVE", updateSourcePaths: ${registeredPublisher.name}`,
566
+ "Broker",
567
+ "info"
568
+ );
569
+ }
570
+ } catch (err) {
571
+ const msg = error(err, "ADD_SUBSCRIBER" /* ADD_SUBSCRIBER */, "Broker");
572
+ client.send(msg);
573
+ client.close();
574
+ }
575
+ });
576
+ }
577
+ // Trigger while consumer exit
578
+ async _removeSubscriber(context, client) {
579
+ const { publishers } = context ?? {};
580
+ const subscriberIdentifier = getIdentifier({
581
+ name: context == null ? void 0 : context.name,
582
+ ip: context == null ? void 0 : context.ip
583
+ });
584
+ publishers.forEach((publisher) => {
585
+ const { name, ip } = publisher;
586
+ const identifier = getIdentifier({
587
+ name,
588
+ ip
589
+ });
590
+ const registeredPublisher = this._publisherMap.get(identifier);
591
+ if (!registeredPublisher) {
592
+ fileLog(
593
+ `[${"EXIT_SUBSCRIBER" /* EXIT_SUBSCRIBER */}], ${identifier} does not exit `,
594
+ "Broker",
595
+ "warn"
596
+ );
597
+ return;
598
+ }
599
+ try {
600
+ fileLog(
601
+ `[${"EXIT_SUBSCRIBER" /* EXIT_SUBSCRIBER */}], ${identifier} will exit `,
602
+ "Broker",
603
+ "INFO"
604
+ );
605
+ registeredPublisher.removeSubscriber(subscriberIdentifier);
606
+ this._clearTmpSubScriberRelation(identifier);
607
+ if (!registeredPublisher.hasSubscribes) {
608
+ this._publisherMap.delete(identifier);
609
+ }
610
+ if (!this.hasPublishers) {
611
+ this.exit();
612
+ }
613
+ } catch (err) {
614
+ const msg = error(err, "EXIT_SUBSCRIBER" /* EXIT_SUBSCRIBER */, "Broker");
615
+ client.send(msg);
616
+ client.close();
617
+ }
618
+ });
619
+ }
620
+ async _removePublisher(context, client) {
621
+ const { name, ip } = context ?? {};
622
+ const identifier = getIdentifier({
623
+ name,
624
+ ip
625
+ });
626
+ const publisher = this._publisherMap.get(identifier);
627
+ if (!publisher) {
628
+ fileLog(
629
+ `[${"EXIT_PUBLISHER" /* EXIT_PUBLISHER */}]: ${identifier}} has not been added, this action will be ingored`,
630
+ "Broker",
631
+ "warn"
632
+ );
633
+ return;
634
+ }
635
+ try {
636
+ const { subscribers } = publisher;
637
+ subscribers.forEach((subscriber, subscriberIdentifier) => {
638
+ this._addTmpSubScriberRelation(
639
+ {
640
+ name: subscriberIdentifier,
641
+ client: subscriber
642
+ },
643
+ { name: publisher.name, ip: publisher.ip }
644
+ );
645
+ fileLog(
646
+ // eslint-disable-next-line max-len
647
+ `[${"EXIT_PUBLISHER" /* EXIT_PUBLISHER */}]: ${identifier} is removing , subscriber: ${subscriberIdentifier} will be add tmpSubScriberRelation`,
648
+ "Broker",
649
+ "info"
650
+ );
651
+ });
652
+ this._publisherMap.delete(identifier);
653
+ fileLog(
654
+ `[${"EXIT_PUBLISHER" /* EXIT_PUBLISHER */}]: ${identifier} is removed `,
655
+ "Broker",
656
+ "info"
657
+ );
658
+ if (!this.hasPublishers) {
659
+ fileLog(
660
+ `[${"EXIT_PUBLISHER" /* EXIT_PUBLISHER */}]: _publisherMap is empty, all server will exit `,
661
+ "Broker",
662
+ "warn"
663
+ );
664
+ this.exit();
665
+ }
666
+ } catch (err) {
667
+ const msg = error(err, "EXIT_PUBLISHER" /* EXIT_PUBLISHER */, "Broker");
668
+ client.send(msg);
669
+ client.close();
670
+ }
671
+ }
672
+ async _addWebClient(context, client) {
673
+ const { name } = context ?? {};
674
+ const identifier = getIdentifier({
675
+ name
676
+ });
677
+ if (this._webClientMap.has(identifier)) {
678
+ fileLog(
679
+ `${identifier}} has been added, this action will override prev WebClient`,
680
+ "Broker",
681
+ "warn"
682
+ );
683
+ }
684
+ try {
685
+ this._webClientMap.set(identifier, client);
686
+ fileLog(`${identifier} adding WebClient Succeed`, "Broker", "info");
687
+ } catch (err) {
688
+ const msg = error(err, "ADD_WEB_CLIENT" /* ADD_WEB_CLIENT */, "Broker");
689
+ client.send(msg);
690
+ client.close();
691
+ }
692
+ }
693
+ async _notifyWebClient(context, client) {
694
+ const { name, updateMode } = context ?? {};
695
+ const identifier = getIdentifier({
696
+ name
697
+ });
698
+ const webClient = this._webClientMap.get(identifier);
699
+ if (!webClient) {
700
+ fileLog(
701
+ `[${"NOTIFY_WEB_CLIENT" /* NOTIFY_WEB_CLIENT */}] ${identifier} has not been added, this action will be ignored`,
702
+ "Broker",
703
+ "warn"
704
+ );
705
+ return;
706
+ }
707
+ try {
708
+ const api = new ReloadWebClientAPI({ name, updateMode });
709
+ webClient.send(JSON.stringify(api));
710
+ fileLog(
711
+ `[${"NOTIFY_WEB_CLIENT" /* NOTIFY_WEB_CLIENT */}] Notify ${name} WebClient Succeed`,
712
+ "Broker",
713
+ "info"
714
+ );
715
+ } catch (err) {
716
+ const msg = error(err, "NOTIFY_WEB_CLIENT" /* NOTIFY_WEB_CLIENT */, "Broker");
717
+ client.send(msg);
718
+ client.close();
719
+ }
720
+ }
721
+ // app1 consumes provider1, and provider1 not launch. this._tmpSubscriberShelter at this time: {provider1: Map{subscribers: Map{app1: app1+ip+client'}, timestamp: 'xx'} }
722
+ _addTmpSubScriberRelation(subscriber, publisher) {
723
+ const publisherIdentifier = getIdentifier({
724
+ name: publisher.name,
725
+ ip: publisher.ip
726
+ });
727
+ const subscriberIdentifier = subscriber.name;
728
+ const shelter = this._tmpSubscriberShelter.get(publisherIdentifier);
729
+ if (!shelter) {
730
+ const map = /* @__PURE__ */ new Map();
731
+ map.set(subscriberIdentifier, subscriber);
732
+ this._tmpSubscriberShelter.set(publisherIdentifier, {
733
+ subscribers: map,
734
+ timestamp: Date.now()
735
+ });
736
+ fileLog(
737
+ `[AddTmpSubscriberRelation] ${publisherIdentifier}'s subscriber has ${subscriberIdentifier} `,
738
+ "Broker",
739
+ "info"
740
+ );
741
+ return;
742
+ }
743
+ const tmpSubScriberShelterSubscriber = shelter.subscribers.get(subscriberIdentifier);
744
+ if (tmpSubScriberShelterSubscriber) {
745
+ fileLog(
746
+ `[AddTmpSubscriberRelation] ${publisherIdentifier} and ${subscriberIdentifier} relation has been added`,
747
+ "Broker",
748
+ "warn"
749
+ );
750
+ shelter.subscribers.set(subscriberIdentifier, subscriber);
751
+ shelter.timestamp = Date.now();
752
+ } else {
753
+ fileLog(
754
+ // eslint-disable-next-line max-len
755
+ `AddTmpSubscriberLog ${publisherIdentifier}'s shelter has been added, update shelter.subscribers ${subscriberIdentifier}`,
756
+ "Broker",
757
+ "warn"
758
+ );
759
+ shelter.subscribers.set(subscriberIdentifier, subscriber);
760
+ }
761
+ }
762
+ _getTmpSubScribers(publisherIdentifier) {
763
+ var _a;
764
+ return (_a = this._tmpSubscriberShelter.get(publisherIdentifier)) == null ? void 0 : _a.subscribers;
765
+ }
766
+ // after adding publisher, it will change the temp subscriber to regular subscriber
767
+ _consumeTmpSubScribers(publisher, tmpSubScribers) {
768
+ tmpSubScribers.forEach((tmpSubScriber, identifier) => {
769
+ fileLog(
770
+ `notifyTmpSubScribers ${publisher.name} will be add a subscriber: ${identifier} `,
771
+ "Broker",
772
+ "warn"
773
+ );
774
+ publisher.addSubscriber(identifier, tmpSubScriber.client);
775
+ publisher.notifySubscriber(identifier, {
776
+ updateKind: "UPDATE_TYPE" /* UPDATE_TYPE */,
777
+ updateMode: import_helpers2.UpdateMode.PASSIVE,
778
+ updateSourcePaths: [publisher.name],
779
+ remoteTypeTarPath: publisher.remoteTypeTarPath,
780
+ name: publisher.name
781
+ });
782
+ });
783
+ }
784
+ _clearTmpSubScriberRelation(identifier) {
785
+ this._tmpSubscriberShelter.delete(identifier);
786
+ }
787
+ _clearTmpSubScriberRelations() {
788
+ this._tmpSubscriberShelter.clear();
789
+ }
790
+ _disconnect() {
791
+ this._publisherMap.forEach((publisher) => {
792
+ publisher.close();
793
+ });
794
+ }
795
+ // Every day on 0/6/9/12/15//18, Publishers that have not been connected within 1.5 hours will be cleared regularly.
796
+ // If process.env.FEDERATION_SERVER_TEST is set, it will be read at a specified time.
797
+ _setSchedule() {
798
+ const rule = new import_node_schedule.default.RecurrenceRule();
799
+ if (Number(process.env["FEDERATION_SERVER_TEST"])) {
800
+ const interval = Number(process.env["FEDERATION_SERVER_TEST"]) / 1e3;
801
+ const second = [];
802
+ for (let i = 0; i < 60; i = i + interval) {
803
+ second.push(i);
804
+ }
805
+ rule.second = second;
806
+ } else {
807
+ rule.second = 0;
808
+ rule.hour = [0, 3, 6, 9, 12, 15, 18];
809
+ rule.minute = 0;
810
+ }
811
+ const serverTest = Number(process.env["FEDERATION_SERVER_TEST"]);
812
+ this._scheduleJob = import_node_schedule.default.scheduleJob(rule, () => {
813
+ this._tmpSubscriberShelter.forEach((tmpSubscriber, identifier) => {
814
+ fileLog(
815
+ ` _clearTmpSubScriberRelation ${identifier}, ${Date.now() - tmpSubscriber.timestamp >= (process.env["GARFISH_MODULE_SERVER_TEST"] ? serverTest : _Broker.DEFAULT_WAITING_TIME)}`,
816
+ "Broker",
817
+ "info"
818
+ );
819
+ if (Date.now() - tmpSubscriber.timestamp >= (process.env["FEDERATION_SERVER_TEST"] ? serverTest : _Broker.DEFAULT_WAITING_TIME)) {
820
+ this._clearTmpSubScriberRelation(identifier);
821
+ }
822
+ });
823
+ });
824
+ }
825
+ _clearSchedule() {
826
+ if (!this._scheduleJob) {
827
+ return;
828
+ }
829
+ this._scheduleJob.cancel();
830
+ this._scheduleJob = null;
831
+ }
832
+ _stopWhenSIGTERMOrSIGINT() {
833
+ process.on("SIGTERM", () => {
834
+ this.exit();
835
+ });
836
+ process.on("SIGINT", () => {
837
+ this.exit();
838
+ });
839
+ }
840
+ _handleUnexpectedExit() {
841
+ process.on("unhandledRejection", (error2) => {
842
+ console.error("Unhandled Rejection Error: ", error2);
843
+ fileLog(`Unhandled Rejection Error: ${error2}`, "Broker", "fatal");
844
+ process.exit(1);
845
+ });
846
+ process.on("uncaughtException", (error2) => {
847
+ console.error("Unhandled Exception Error: ", error2);
848
+ fileLog(`Unhandled Rejection Error: ${error2}`, "Broker", "fatal");
849
+ process.exit(1);
850
+ });
851
+ }
852
+ async start() {
853
+ }
854
+ exit() {
855
+ const brokerExitLog = new BrokerExitLog();
856
+ this.broadcast(JSON.stringify(brokerExitLog));
857
+ this._disconnect();
858
+ this._clearSchedule();
859
+ this._clearTmpSubScriberRelations();
860
+ this._webSocketServer && this._webSocketServer.close();
861
+ this._secureWebSocketServer && this._secureWebSocketServer.close();
862
+ process.exit(0);
863
+ }
864
+ broadcast(message) {
865
+ var _a, _b;
866
+ fileLog(
867
+ `[broadcast] exit info : ${JSON.stringify(message)}`,
868
+ "Broker",
869
+ "warn"
870
+ );
871
+ (_a = this._webSocketServer) == null ? void 0 : _a.clients.forEach((client) => {
872
+ client.send(JSON.stringify(message));
873
+ });
874
+ (_b = this._secureWebSocketServer) == null ? void 0 : _b.clients.forEach((client) => {
875
+ client.send(JSON.stringify(message));
876
+ });
877
+ }
878
+ };
879
+ _Broker.WEB_SOCKET_CONNECT_MAGIC_ID = WEB_SOCKET_CONNECT_MAGIC_ID;
880
+ _Broker.DEFAULT_WEB_SOCKET_PORT = DEFAULT_WEB_SOCKET_PORT;
881
+ _Broker.DEFAULT_SECURE_WEB_SOCKET_PORT = 16324;
882
+ _Broker.DEFAULT_WAITING_TIME = 1.5 * 60 * 60 * 1e3;
883
+ var Broker = _Broker;
884
+
885
+ // packages/dts-plugin/src/server/createKoaServer.ts
886
+ var import_fs_extra = __toESM(require("fs-extra"));
887
+ var import_koa = __toESM(require("koa"));
888
+
889
+ // packages/dts-plugin/src/plugins/DevPlugin.ts
890
+ var import_path2 = __toESM(require("path"));
891
+ function ensureTempDir(filePath) {
892
+ try {
893
+ const dir = import_path2.default.dirname(filePath);
894
+ import_fs_extra2.default.ensureDirSync(dir);
895
+ } catch (_err) {
896
+ }
897
+ }
898
+ function isDev() {
899
+ return process.env["NODE_ENV"] === "development";
900
+ }
901
+ var DevPlugin = class _DevPlugin {
902
+ constructor(options) {
903
+ this.name = "MFDevPlugin";
904
+ this._options = options;
905
+ }
906
+ static ensureLiveReloadEntry(options, filePath) {
907
+ ensureTempDir(filePath);
908
+ const liveReloadEntry = import_fs_extra2.default.readFileSync(import_path2.default.join(__dirname, "./iife/launch-web-client.js")).toString("utf-8");
909
+ const liveReloadEntryWithOptions = liveReloadEntry.replace(
910
+ WEB_CLIENT_OPTIONS_IDENTIFIER,
911
+ JSON.stringify(options)
912
+ );
913
+ import_fs_extra2.default.writeFileSync(filePath, liveReloadEntryWithOptions);
914
+ }
915
+ _stopWhenSIGTERMOrSIGINT() {
916
+ process.on("SIGTERM", () => {
917
+ console.log(
918
+ import_chalk3.default`{cyan ${this._options.name} Process(${process.pid}) SIGTERM, mf server will exit...}`
919
+ );
920
+ this._exit(0 /* SUCCESS */);
921
+ });
922
+ process.on("SIGINT", () => {
923
+ console.log(
924
+ import_chalk3.default`{cyan ${this._options.name} Process(${process.pid}) SIGINT, mf server will exit...}`
925
+ );
926
+ this._exit(0 /* SUCCESS */);
927
+ });
928
+ }
929
+ _handleUnexpectedExit() {
930
+ process.on("unhandledRejection", (error2) => {
931
+ console.error("Unhandled Rejection Error: ", error2);
932
+ console.log(
933
+ import_chalk3.default`{cyan ${this._options.name} Process(${process.pid}) unhandledRejection, mf server will exit...}`
934
+ );
935
+ this._exit(1 /* FAILURE */);
936
+ });
937
+ process.on("uncaughtException", (error2) => {
938
+ console.error("Unhandled Rejection Error: ", error2);
939
+ console.log(
940
+ import_chalk3.default`{cyan ${this._options.name} Process(${process.pid}) uncaughtException, mf server will exit...}`
941
+ );
942
+ this._exit(1 /* FAILURE */);
943
+ });
944
+ }
945
+ _exit(exitCode = 0) {
946
+ var _a;
947
+ (_a = this._devWorker) == null ? void 0 : _a.exit();
948
+ process.exit(exitCode);
949
+ }
950
+ _afterEmit() {
951
+ var _a;
952
+ (_a = this._devWorker) == null ? void 0 : _a.update();
953
+ }
954
+ apply(compiler) {
955
+ var _a;
956
+ const {
957
+ _options: { name, dev, dts }
958
+ } = this;
959
+ const normalizedDev = (0, import_sdk3.normalizeOptions)(
960
+ true,
961
+ {
962
+ devServer: {
963
+ disableLiveReload: true,
964
+ disableHotTypesReload: false
965
+ }
966
+ },
967
+ "mfOptions.dev"
968
+ )(dev);
969
+ if (!isDev() || normalizedDev === false) {
970
+ return;
971
+ }
972
+ const normalizedDevServer = (0, import_sdk3.normalizeOptions)(
973
+ true,
974
+ {
975
+ disableLiveReload: true,
976
+ disableHotTypesReload: false
977
+ },
978
+ "mfOptions.dev.devServer"
979
+ )(normalizedDev.devServer);
980
+ if (!normalizedDevServer || normalizedDevServer.disableHotTypesReload && normalizedDevServer.disableLiveReload) {
981
+ return;
982
+ }
983
+ if (!name) {
984
+ throw new Error("name is required if you want to enable dev server!");
985
+ }
986
+ if (!normalizedDevServer.disableLiveReload) {
987
+ const TEMP_DIR = import_path2.default.join(
988
+ `${process.cwd()}/node_modules`,
989
+ `.federation`
990
+ );
991
+ const filepath = import_path2.default.join(TEMP_DIR, `live-reload.js`);
992
+ _DevPlugin.ensureLiveReloadEntry({ name }, filepath);
993
+ compiler.hooks.afterPlugins.tap("MFDevPlugin", () => {
994
+ new compiler.webpack.EntryPlugin(compiler.context, filepath, {
995
+ name
996
+ }).apply(compiler);
997
+ });
998
+ }
999
+ const isTSProject = (tsConfigPath, context = process.cwd()) => {
1000
+ try {
1001
+ let filepath = tsConfigPath ?? import_path2.default.resolve(context, "./tsconfig.json");
1002
+ if (!import_path2.default.isAbsolute(filepath)) {
1003
+ filepath = import_path2.default.resolve(context, filepath);
1004
+ }
1005
+ return import_fs_extra2.default.existsSync(filepath);
1006
+ } catch (err) {
1007
+ return false;
1008
+ }
1009
+ };
1010
+ const normalizedDtsOptions = (0, import_sdk3.normalizeOptions)(
1011
+ isTSProject(void 0, compiler.context),
1012
+ {
1013
+ disableGenerateTypes: false,
1014
+ // remote types dist(.dev-server) not be used currently, so no need to set extractThirdParty etc
1015
+ remote: { compileInChildProcess: true },
1016
+ host: { consumeAPITypes: true },
1017
+ extraOptions: {}
1018
+ },
1019
+ "mfOptions.dts"
1020
+ )(dts);
1021
+ const remote = normalizedDtsOptions === false ? void 0 : normalizedDtsOptions.disableGenerateTypes ? void 0 : {
1022
+ implementation: normalizedDtsOptions.implementation,
1023
+ context: compiler.context,
1024
+ moduleFederationConfig: {
1025
+ ...this._options
1026
+ },
1027
+ hostRemoteTypesFolder: ((_a = normalizedDtsOptions.remote) == null ? void 0 : _a.typesFolder) || "@mf-types",
1028
+ ...normalizedDtsOptions.remote,
1029
+ typesFolder: `.dev-server`
1030
+ };
1031
+ const host = normalizedDtsOptions === false ? void 0 : normalizedDtsOptions.disableConsumeTypes ? void 0 : {
1032
+ implementation: normalizedDtsOptions.implementation,
1033
+ context: compiler.context,
1034
+ moduleFederationConfig: this._options,
1035
+ typesFolder: "@mf-types",
1036
+ abortOnError: false,
1037
+ ...normalizedDtsOptions.host
1038
+ };
1039
+ const extraOptions = normalizedDtsOptions ? normalizedDtsOptions.extraOptions || {} : {};
1040
+ this._devWorker = createDevWorker({
1041
+ name,
1042
+ remote,
1043
+ host,
1044
+ extraOptions,
1045
+ disableLiveReload: normalizedDevServer.disableHotTypesReload,
1046
+ disableHotTypesReload: normalizedDevServer.disableHotTypesReload
1047
+ });
1048
+ this._stopWhenSIGTERMOrSIGINT();
1049
+ this._handleUnexpectedExit();
1050
+ compiler.hooks.afterEmit.tap(this.name, this._afterEmit.bind(this));
1051
+ }
1052
+ };
1053
+
1054
+ // packages/dts-plugin/src/plugins/TypesPlugin.ts
1055
+ var import_path3 = __toESM(require("path"));
1056
+ var import_fs = __toESM(require("fs"));
1057
+ var import_sdk4 = require("@module-federation/sdk");
1058
+ var import_webpack = require("@module-federation/native-federation-typescript/webpack");
1059
+ var TypesPlugin = class {
1060
+ constructor(options) {
1061
+ this.options = options;
1062
+ }
1063
+ apply(compiler) {
1064
+ const { options } = this;
1065
+ const isTSProject = (tsConfigPath, context = process.cwd()) => {
1066
+ try {
1067
+ let filepath = tsConfigPath ? tsConfigPath : import_path3.default.resolve(context, "./tsconfig.json");
1068
+ if (!import_path3.default.isAbsolute(filepath)) {
1069
+ filepath = import_path3.default.resolve(context, filepath);
1070
+ }
1071
+ return import_fs.default.existsSync(filepath);
1072
+ } catch (err) {
1073
+ return false;
1074
+ }
1075
+ };
1076
+ const normalizedDtsOptions = (0, import_sdk4.normalizeOptions)(
1077
+ isTSProject(void 0, compiler.context),
1078
+ {
1079
+ disableGenerateTypes: false,
1080
+ disableConsumeTypes: false,
1081
+ remote: {
1082
+ generateAPITypes: true,
1083
+ compileInChildProcess: true,
1084
+ abortOnError: false,
1085
+ extractThirdParty: true,
1086
+ extractRemoteTypes: true
1087
+ },
1088
+ host: { abortOnError: false, consumeAPITypes: true },
1089
+ extraOptions: {}
1090
+ },
1091
+ "mfOptions.dts"
1092
+ )(options.dts);
1093
+ if (typeof normalizedDtsOptions === "object") {
1094
+ if (!normalizedDtsOptions.disableGenerateTypes) {
1095
+ (0, import_webpack.NativeFederationTypeScriptRemote)({
1096
+ remote: {
1097
+ implementation: normalizedDtsOptions.implementation,
1098
+ context: compiler.context,
1099
+ moduleFederationConfig: options,
1100
+ ...normalizedDtsOptions.remote
1101
+ },
1102
+ extraOptions: normalizedDtsOptions.extraOptions || {}
1103
+ // @ts-ignore
1104
+ }).apply(compiler);
1105
+ }
1106
+ if (!normalizedDtsOptions.disableConsumeTypes) {
1107
+ (0, import_webpack.NativeFederationTypeScriptHost)({
1108
+ host: {
1109
+ implementation: normalizedDtsOptions.implementation,
1110
+ context: compiler.context,
1111
+ moduleFederationConfig: options,
1112
+ ...normalizedDtsOptions.host
1113
+ },
1114
+ extraOptions: normalizedDtsOptions.extraOptions || {}
1115
+ // @ts-ignore
1116
+ }).apply(compiler);
1117
+ }
1118
+ }
1119
+ }
1120
+ };
1121
+
1122
+ // packages/dts-plugin/src/plugins/DtsPlugin.ts
1123
+ var DtsPlugin = class {
1124
+ constructor(options) {
1125
+ this.options = options;
1126
+ }
1127
+ apply(compiler) {
1128
+ const { options } = this;
1129
+ new DevPlugin(options).apply(compiler);
1130
+ new TypesPlugin(options).apply(compiler);
1131
+ }
1132
+ };
1133
+ // Annotate the CommonJS export names for ESM import in node:
1134
+ 0 && (module.exports = {
1135
+ DtsPlugin
1136
+ });