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