@nocobase/server 2.0.0-beta.9 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/lib/aes-encryptor.d.ts +1 -0
  2. package/lib/aes-encryptor.js +8 -5
  3. package/lib/ai/create-docs-index.d.ts +13 -0
  4. package/lib/ai/create-docs-index.js +892 -0
  5. package/lib/app-supervisor/app-options-factory.d.ts +80 -0
  6. package/lib/app-supervisor/app-options-factory.js +91 -0
  7. package/lib/app-supervisor/condition-registry.d.ts +18 -0
  8. package/lib/app-supervisor/condition-registry.js +60 -0
  9. package/lib/app-supervisor/db-creator.d.ts +16 -0
  10. package/lib/app-supervisor/db-creator.js +163 -0
  11. package/lib/app-supervisor/db-drivers.d.ts +11 -0
  12. package/lib/app-supervisor/db-drivers.js +52 -0
  13. package/lib/app-supervisor/index.d.ts +161 -0
  14. package/lib/app-supervisor/index.js +690 -0
  15. package/lib/app-supervisor/main-only-adapter.d.ts +37 -0
  16. package/lib/app-supervisor/main-only-adapter.js +156 -0
  17. package/lib/app-supervisor/types.d.ts +161 -0
  18. package/lib/app-supervisor/types.js +24 -0
  19. package/lib/application.d.ts +3 -1
  20. package/lib/application.js +10 -6
  21. package/lib/commands/ai.d.ts +11 -0
  22. package/lib/commands/ai.js +40 -0
  23. package/lib/commands/console.js +1 -1
  24. package/lib/commands/index.js +2 -0
  25. package/lib/commands/install.js +2 -0
  26. package/lib/commands/start.js +3 -0
  27. package/lib/commands/upgrade.js +2 -0
  28. package/lib/gateway/errors.js +1 -1
  29. package/lib/gateway/index.js +64 -15
  30. package/lib/gateway/ipc-socket-server.js +1 -1
  31. package/lib/gateway/ws-server.js +3 -2
  32. package/lib/helper.js +20 -3
  33. package/lib/plugin-manager/deps.js +1 -1
  34. package/lib/plugin-manager/plugin-manager.js +2 -0
  35. package/lib/plugin.d.ts +5 -0
  36. package/lib/plugin.js +25 -0
  37. package/lib/redis-connection-manager.d.ts +15 -5
  38. package/lib/redis-connection-manager.js +117 -24
  39. package/package.json +18 -17
  40. package/lib/app-supervisor.d.ts +0 -74
  41. package/lib/app-supervisor.js +0 -338
@@ -0,0 +1,690 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+
10
+ var __create = Object.create;
11
+ var __defProp = Object.defineProperty;
12
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
13
+ var __getOwnPropNames = Object.getOwnPropertyNames;
14
+ var __getProtoOf = Object.getPrototypeOf;
15
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
16
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
17
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
18
+ var __export = (target, all) => {
19
+ for (var name in all)
20
+ __defProp(target, name, { get: all[name], enumerable: true });
21
+ };
22
+ var __copyProps = (to, from, except, desc) => {
23
+ if (from && typeof from === "object" || typeof from === "function") {
24
+ for (let key of __getOwnPropNames(from))
25
+ if (!__hasOwnProp.call(to, key) && key !== except)
26
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
27
+ }
28
+ return to;
29
+ };
30
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
31
+ // If the importer is in node compatibility mode or this is not an ESM
32
+ // file that has been converted to a CommonJS file using a Babel-
33
+ // compatible transform (i.e. "__esModule" has not been set), then set
34
+ // "default" to the CommonJS "module.exports" for node compatibility.
35
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
36
+ mod
37
+ ));
38
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
39
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
40
+ var app_supervisor_exports = {};
41
+ __export(app_supervisor_exports, {
42
+ AppSupervisor: () => AppSupervisor,
43
+ MainOnlyAdapter: () => import_main_only_adapter2.MainOnlyAdapter
44
+ });
45
+ module.exports = __toCommonJS(app_supervisor_exports);
46
+ var import_lodash = __toESM(require("lodash"));
47
+ var import_utils = require("@nocobase/utils");
48
+ var import_events = require("events");
49
+ var import_application = __toESM(require("../application"));
50
+ var import_main_only_adapter = require("./main-only-adapter");
51
+ var import_handler = require("../errors/handler");
52
+ var import_condition_registry = require("./condition-registry");
53
+ var import_db_creator = require("./db-creator");
54
+ var import_app_options_factory = require("./app-options-factory");
55
+ var import_logger = require("@nocobase/logger");
56
+ var import_aes_encryptor = __toESM(require("../aes-encryptor"));
57
+ var import_lodash2 = __toESM(require("lodash"));
58
+ var import_main_only_adapter2 = require("./main-only-adapter");
59
+ const _AppSupervisor = class _AppSupervisor extends import_events.EventEmitter {
60
+ runningMode = "multiple";
61
+ singleAppName = null;
62
+ logger;
63
+ aesEncryptor;
64
+ discoveryAdapter;
65
+ processAdapter;
66
+ commandAdapter;
67
+ discoveryAdapterName;
68
+ processAdapterName;
69
+ commandAdapterName;
70
+ appDbCreator = new import_condition_registry.ConditionalRegistry();
71
+ appOptionsFactory = import_app_options_factory.appOptionsFactory;
72
+ environmentHeartbeatInterval = 2 * 60 * 1e3;
73
+ environmentHeartbeatTimer = null;
74
+ constructor() {
75
+ super();
76
+ if (process.env.STARTUP_SUBAPP) {
77
+ this.runningMode = "single";
78
+ this.singleAppName = process.env.STARTUP_SUBAPP;
79
+ }
80
+ this.logger = (0, import_logger.createSystemLogger)({
81
+ dirname: (0, import_logger.getLoggerFilePath)("main"),
82
+ filename: "system",
83
+ level: (0, import_logger.getLoggerLevel)(),
84
+ seperateError: true,
85
+ defaultMeta: {
86
+ app: "main",
87
+ module: "app-supervisor"
88
+ }
89
+ });
90
+ this.discoveryAdapterName = this.resolveDiscoveryAdapterName();
91
+ this.processAdapterName = this.resolveProcessAdapterName();
92
+ this.commandAdapterName = this.resolveCommandAdapterName();
93
+ this.logger.info(`App supervisor initialized`, {
94
+ discoveryAdapter: this.discoveryAdapterName,
95
+ processAdapter: this.processAdapterName,
96
+ commandAdapter: this.commandAdapterName || ""
97
+ });
98
+ this.discoveryAdapter = this.createDiscoveryAdapter();
99
+ this.processAdapter = this.createProcessAdapter();
100
+ this.commandAdapter = this.createCommandAdapter();
101
+ this.registerAppDbCreator(import_db_creator.createDatabaseCondition, import_db_creator.createDatabase);
102
+ this.registerAppDbCreator(import_db_creator.createConnectionCondition, import_db_creator.createConnection);
103
+ this.registerAppDbCreator(import_db_creator.createSchemaCondition, import_db_creator.createSchema);
104
+ if (process.env.APP_SUPERVISOR_AES_SECRET_KEY) {
105
+ try {
106
+ const key = Buffer.from(process.env.APP_SUPERVISOR_AES_SECRET_KEY, "hex");
107
+ this.aesEncryptor = new import_aes_encryptor.default(key);
108
+ } catch (error) {
109
+ this.logger.warn("Failed to initialize APP_SUPERVISOR_AES_SECRET_KEY encryptor", {
110
+ error: error.message
111
+ });
112
+ }
113
+ }
114
+ }
115
+ resolveDiscoveryAdapterName() {
116
+ return process.env.APP_DISCOVERY_ADAPTER || _AppSupervisor.defaultDiscoveryAdapterName;
117
+ }
118
+ resolveProcessAdapterName() {
119
+ return process.env.APP_PROCESS_ADAPTER || _AppSupervisor.defaultProcessAdapterName;
120
+ }
121
+ resolveCommandAdapterName() {
122
+ return process.env.APP_COMMAND_ADAPTER || _AppSupervisor.defaultCommandAdapterName;
123
+ }
124
+ createDiscoveryAdapter() {
125
+ const adapterName = this.discoveryAdapterName;
126
+ let factory = adapterName ? _AppSupervisor.discoveryAdapterFactories.get(adapterName) : null;
127
+ if (!factory && _AppSupervisor.defaultDiscoveryAdapterName && adapterName !== _AppSupervisor.defaultDiscoveryAdapterName) {
128
+ factory = _AppSupervisor.discoveryAdapterFactories.get(_AppSupervisor.defaultDiscoveryAdapterName);
129
+ }
130
+ if (!factory) {
131
+ throw new Error("No AppDiscovery adapter available");
132
+ }
133
+ return factory({ supervisor: this });
134
+ }
135
+ isProcessCapableAdapter(adapter) {
136
+ return adapter && typeof adapter.addApp === "function" && typeof adapter.startApp === "function";
137
+ }
138
+ createProcessAdapter() {
139
+ const adapterName = this.processAdapterName;
140
+ if (adapterName && adapterName === this.discoveryAdapterName && this.isProcessCapableAdapter(this.discoveryAdapter)) {
141
+ return this.discoveryAdapter;
142
+ }
143
+ let factory = adapterName ? _AppSupervisor.processAdapterFactories.get(adapterName) : null;
144
+ if (!factory && _AppSupervisor.defaultProcessAdapterName && adapterName !== _AppSupervisor.defaultProcessAdapterName) {
145
+ factory = _AppSupervisor.processAdapterFactories.get(_AppSupervisor.defaultProcessAdapterName);
146
+ }
147
+ if (!factory) {
148
+ throw new Error("No AppProcess adapter available");
149
+ }
150
+ return factory({ supervisor: this });
151
+ }
152
+ createCommandAdapter() {
153
+ const adapterName = this.commandAdapterName;
154
+ let factory = adapterName ? _AppSupervisor.commandAdapterFactories.get(adapterName) : null;
155
+ if (!factory && _AppSupervisor.defaultCommandAdapterName && adapterName !== _AppSupervisor.defaultCommandAdapterName) {
156
+ factory = _AppSupervisor.commandAdapterFactories.get(_AppSupervisor.defaultCommandAdapterName);
157
+ }
158
+ if (!factory) {
159
+ return;
160
+ }
161
+ return factory({ supervisor: this });
162
+ }
163
+ static registerDiscoveryAdapter(name, factory) {
164
+ _AppSupervisor.discoveryAdapterFactories.set(name, factory);
165
+ }
166
+ static registerProcessAdapter(name, factory) {
167
+ _AppSupervisor.processAdapterFactories.set(name, factory);
168
+ }
169
+ static registerCommandAdapter(name, factory) {
170
+ _AppSupervisor.commandAdapterFactories.set(name, factory);
171
+ }
172
+ static setDefaultDiscoveryAdapter(name) {
173
+ _AppSupervisor.defaultDiscoveryAdapterName = name;
174
+ }
175
+ static setDefaultProcessAdapter(name) {
176
+ _AppSupervisor.defaultProcessAdapterName = name;
177
+ }
178
+ static setDefaultCommandAdapter(name) {
179
+ _AppSupervisor.defaultCommandAdapterName = name;
180
+ }
181
+ static getInstance() {
182
+ if (!_AppSupervisor.instance) {
183
+ _AppSupervisor.instance = new _AppSupervisor();
184
+ }
185
+ return _AppSupervisor.instance;
186
+ }
187
+ get apps() {
188
+ return this.processAdapter.apps ?? /* @__PURE__ */ Object.create(null);
189
+ }
190
+ get appStatus() {
191
+ return this.discoveryAdapter.appStatus ?? /* @__PURE__ */ Object.create(null);
192
+ }
193
+ get appErrors() {
194
+ return this.processAdapter.appErrors ?? /* @__PURE__ */ Object.create(null);
195
+ }
196
+ get lastSeenAt() {
197
+ return this.discoveryAdapter.lastSeenAt ?? /* @__PURE__ */ new Map();
198
+ }
199
+ get lastMaintainingMessage() {
200
+ return this.processAdapter.lastMaintainingMessage ?? /* @__PURE__ */ Object.create(null);
201
+ }
202
+ get statusBeforeCommanding() {
203
+ return this.processAdapter.statusBeforeCommanding ?? /* @__PURE__ */ Object.create(null);
204
+ }
205
+ get environmentName() {
206
+ return this.discoveryAdapter.environmentName;
207
+ }
208
+ get environmentUrl() {
209
+ return this.discoveryAdapter.environmentUrl;
210
+ }
211
+ get environmentProxyUrl() {
212
+ return this.discoveryAdapter.environmentProxyUrl;
213
+ }
214
+ getProcessAdapter() {
215
+ return this.processAdapter;
216
+ }
217
+ getDiscoveryAdapter() {
218
+ return this.discoveryAdapter;
219
+ }
220
+ registerAppDbCreator(condition, creator, priority) {
221
+ this.appDbCreator.register(condition, creator, priority);
222
+ }
223
+ async createDatabase(options) {
224
+ return this.appDbCreator.run(options);
225
+ }
226
+ setAppOptionsFactory(factory) {
227
+ this.appOptionsFactory = factory ?? import_app_options_factory.appOptionsFactory;
228
+ }
229
+ async bootstrapApp(appName) {
230
+ return this.processAdapter.bootstrapApp(appName);
231
+ }
232
+ async initApp({ appName, options }) {
233
+ const loadButNotStart = options == null ? void 0 : options.upgrading;
234
+ const mainApp = await this.getApp("main");
235
+ if (!mainApp) {
236
+ return;
237
+ }
238
+ const appModel = await this.getAppModel(appName);
239
+ if (!appModel) {
240
+ this.logger.error(`App model ${appName} not found`);
241
+ return;
242
+ }
243
+ if (appModel.environments && !appModel.environments.includes(this.environmentName)) {
244
+ this.logger.error(`App model ${appName} is not available in environment ${this.environmentName}`);
245
+ return;
246
+ }
247
+ const appOptions = appModel.options;
248
+ if (!appOptions) {
249
+ this.logger.error(`App options ${appName} not found`);
250
+ return;
251
+ }
252
+ if ((appOptions == null ? void 0 : appOptions.standaloneDeployment) && this.runningMode !== "single") {
253
+ return;
254
+ }
255
+ if (this.hasApp(appName)) {
256
+ return;
257
+ }
258
+ this.registerApp({ appModel, mainApp });
259
+ if (!loadButNotStart) {
260
+ await this.startApp(appName);
261
+ }
262
+ }
263
+ setAppError(appName, error) {
264
+ this.processAdapter.setAppError(appName, error);
265
+ }
266
+ hasAppError(appName) {
267
+ return this.processAdapter.hasAppError(appName);
268
+ }
269
+ clearAppError(appName) {
270
+ this.processAdapter.clearAppError(appName);
271
+ }
272
+ async reset() {
273
+ var _a, _b, _c, _d;
274
+ await this.processAdapter.removeAllApps();
275
+ await ((_b = (_a = this.discoveryAdapter).dispose) == null ? void 0 : _b.call(_a));
276
+ await ((_d = (_c = this.commandAdapter) == null ? void 0 : _c.dispose) == null ? void 0 : _d.call(_c));
277
+ if (this.environmentHeartbeatTimer) {
278
+ this.environmentHeartbeatTimer = null;
279
+ }
280
+ this.removeAllListeners();
281
+ this.logger.close();
282
+ }
283
+ async destroy() {
284
+ await this.reset();
285
+ _AppSupervisor.instance = null;
286
+ }
287
+ async getAppStatus(appName, defaultStatus) {
288
+ return this.discoveryAdapter.getAppStatus(appName, defaultStatus);
289
+ }
290
+ async setAppStatus(appName, status, options = {}) {
291
+ this.logger.debug("Setting app status", { appName, status });
292
+ return this.discoveryAdapter.setAppStatus(appName, status, options);
293
+ }
294
+ async clearAppStatus(appName) {
295
+ if (typeof this.discoveryAdapter.clearAppStatus !== "function") {
296
+ return;
297
+ }
298
+ return this.discoveryAdapter.clearAppStatus(appName);
299
+ }
300
+ async getAppsStatuses(appNames) {
301
+ var _a, _b;
302
+ return ((_b = (_a = this.discoveryAdapter).getAppsStatuses) == null ? void 0 : _b.call(_a, appNames)) ?? {};
303
+ }
304
+ async getBootstrapLock(appName) {
305
+ if (typeof this.discoveryAdapter.getBootstrapLock !== "function") {
306
+ return null;
307
+ }
308
+ return this.discoveryAdapter.getBootstrapLock(appName);
309
+ }
310
+ registerApp({ appModel, mainApp, hook }) {
311
+ const appName = appModel.name;
312
+ const appOptions = import_lodash.default.cloneDeep(appModel.options || {});
313
+ if (this.aesEncryptor && (appOptions == null ? void 0 : appOptions.encryptedDbPassword)) {
314
+ try {
315
+ import_lodash2.default.set(appOptions, "database.password", this.aesEncryptor.decryptSync(appOptions.database.password));
316
+ } catch (error) {
317
+ this.logger.warn("Failed to decrypt database password for app registration", {
318
+ appName,
319
+ error: error.message
320
+ });
321
+ }
322
+ }
323
+ let options = appOptions;
324
+ if (mainApp) {
325
+ const defaultAppOptions = this.appOptionsFactory(appName, mainApp, appOptions);
326
+ options = {
327
+ ...import_lodash.default.merge({}, defaultAppOptions, appOptions),
328
+ name: appName
329
+ };
330
+ }
331
+ const app = new import_application.default(options);
332
+ if (hook !== false) {
333
+ app.on("afterStart", async () => {
334
+ await this.sendSyncMessage(mainApp, {
335
+ type: "app:started",
336
+ appName
337
+ });
338
+ });
339
+ app.on("afterStop", async () => {
340
+ await this.sendSyncMessage(mainApp, {
341
+ type: "app:stopped",
342
+ appName
343
+ });
344
+ });
345
+ app.on("afterDestroy", async () => {
346
+ await this.sendSyncMessage(mainApp, {
347
+ type: "app:removed",
348
+ appName
349
+ });
350
+ });
351
+ }
352
+ return app;
353
+ }
354
+ bootMainApp(options) {
355
+ const app = new import_application.default(options);
356
+ this.registerCommandHandler(app);
357
+ app.on("afterStart", async (app2) => {
358
+ var _a, _b;
359
+ await app2.syncMessageManager.subscribe(
360
+ "app_supervisor:sync",
361
+ async (message) => {
362
+ const { type } = message;
363
+ if (type === "app:started") {
364
+ const { appName } = message;
365
+ if (this.hasApp(appName)) {
366
+ return;
367
+ }
368
+ const appModel = await this.getAppModel(appName);
369
+ const appOptions = appModel == null ? void 0 : appModel.options;
370
+ if (!appOptions) {
371
+ return;
372
+ }
373
+ const newApp = this.registerApp({ appModel, mainApp: app2 });
374
+ newApp.runCommand("start", "--quickstart");
375
+ }
376
+ if (type === "app:stopped") {
377
+ const { appName } = message;
378
+ await this.stopApp(appName);
379
+ }
380
+ if (type === "app:removed") {
381
+ const { appName } = message;
382
+ await this.removeApp(appName);
383
+ }
384
+ }
385
+ );
386
+ await this.registerEnvironment(app2);
387
+ if (process.env.APP_MODE === "supervisor") {
388
+ this.logger.info("Loading app models...");
389
+ (_b = (_a = this.discoveryAdapter).loadAppModels) == null ? void 0 : _b.call(_a, app2);
390
+ }
391
+ });
392
+ app.on("afterDestroy", async (app2) => {
393
+ await this.unregisterEnvironment();
394
+ });
395
+ return app;
396
+ }
397
+ async setAppLastSeenAt(appName) {
398
+ return this.discoveryAdapter.setAppLastSeenAt(appName);
399
+ }
400
+ async getAppLastSeenAt(appName) {
401
+ return this.discoveryAdapter.getAppLastSeenAt(appName);
402
+ }
403
+ async addAppModel(appModel) {
404
+ if (typeof this.discoveryAdapter.addAppModel !== "function") {
405
+ return;
406
+ }
407
+ return this.discoveryAdapter.addAppModel(appModel);
408
+ }
409
+ async getAppModel(appName) {
410
+ return this.discoveryAdapter.getAppModel(appName);
411
+ }
412
+ async removeAppModel(appName) {
413
+ if (typeof this.discoveryAdapter.removeAppModel !== "function") {
414
+ return;
415
+ }
416
+ return this.discoveryAdapter.removeAppModel(appName);
417
+ }
418
+ async getAppNameByCName(cname) {
419
+ if (typeof this.discoveryAdapter.getAppNameByCName !== "function") {
420
+ return null;
421
+ }
422
+ return this.discoveryAdapter.getAppNameByCName(cname);
423
+ }
424
+ async addAutoStartApps(environmentName, appNames) {
425
+ if (typeof this.discoveryAdapter.addAutoStartApps !== "function") {
426
+ return;
427
+ }
428
+ return this.discoveryAdapter.addAutoStartApps(environmentName, appNames);
429
+ }
430
+ async getAutoStartApps() {
431
+ if (typeof this.discoveryAdapter.getAutoStartApps === "function") {
432
+ return this.discoveryAdapter.getAutoStartApps(this.environmentName);
433
+ }
434
+ return [];
435
+ }
436
+ async removeAutoStartApps(environmentName, appNames) {
437
+ if (typeof this.discoveryAdapter.addAutoStartApps !== "function") {
438
+ return;
439
+ }
440
+ return this.discoveryAdapter.removeAutoStartApps(environmentName, appNames);
441
+ }
442
+ addApp(app) {
443
+ this.processAdapter.addApp(app);
444
+ this.bindAppEvents(app);
445
+ this.emit("afterAppAdded", app);
446
+ return app;
447
+ }
448
+ async getApp(appName, options = {}) {
449
+ return this.processAdapter.getApp(appName, options);
450
+ }
451
+ hasApp(appName) {
452
+ return this.processAdapter.hasApp(appName);
453
+ }
454
+ async createApp(options, context) {
455
+ await this.processAdapter.createApp(options, context);
456
+ }
457
+ async startApp(appName, context) {
458
+ await this.processAdapter.startApp(appName, context);
459
+ }
460
+ async stopApp(appName, context) {
461
+ await this.processAdapter.stopApp(appName, context);
462
+ }
463
+ async removeApp(appName, context) {
464
+ await this.processAdapter.removeApp(appName, context);
465
+ }
466
+ async upgradeApp(appName, context) {
467
+ await this.processAdapter.upgradeApp(appName, context);
468
+ }
469
+ /**
470
+ * @deprecated
471
+ * use {#getApps} instead
472
+ */
473
+ subApps() {
474
+ return this.processAdapter.getApps();
475
+ }
476
+ getApps() {
477
+ return this.processAdapter.getApps();
478
+ }
479
+ async proxyWeb(appName, req, res) {
480
+ if (process.env.APP_MODE !== "supervisor") {
481
+ return false;
482
+ }
483
+ if (typeof this.discoveryAdapter.proxyWeb !== "function") {
484
+ return false;
485
+ }
486
+ return this.discoveryAdapter.proxyWeb(appName, req, res);
487
+ }
488
+ async proxyWs(req, socket, head) {
489
+ if (process.env.APP_MODE !== "supervisor") {
490
+ return false;
491
+ }
492
+ if (typeof this.discoveryAdapter.proxyWs !== "function") {
493
+ return false;
494
+ }
495
+ return this.discoveryAdapter.proxyWs(req, socket, head);
496
+ }
497
+ async registerEnvironment(mainApp) {
498
+ if (!this.environmentName || typeof this.discoveryAdapter.registerEnvironment !== "function") {
499
+ return;
500
+ }
501
+ const registered = await this.discoveryAdapter.registerEnvironment({
502
+ name: this.environmentName,
503
+ url: this.environmentUrl || "",
504
+ proxyUrl: this.environmentProxyUrl || this.environmentUrl || "",
505
+ appVersion: mainApp.getPackageVersion(),
506
+ lastHeartbeatAt: Date.now()
507
+ });
508
+ if (registered) {
509
+ this.heartbeatEnvironment();
510
+ }
511
+ }
512
+ async unregisterEnvironment() {
513
+ if (this.environmentName && typeof this.discoveryAdapter.unregisterEnvironment === "function") {
514
+ await this.discoveryAdapter.unregisterEnvironment();
515
+ }
516
+ if (this.environmentHeartbeatTimer) {
517
+ this.environmentHeartbeatTimer = null;
518
+ }
519
+ }
520
+ normalizeEnvInfo(environment) {
521
+ if (typeof environment.available === "boolean") {
522
+ return environment;
523
+ }
524
+ const lastHeartbeatAt = environment.lastHeartbeatAt;
525
+ if (!Number.isFinite(lastHeartbeatAt) || lastHeartbeatAt <= 0) {
526
+ return {
527
+ ...environment,
528
+ available: false
529
+ };
530
+ }
531
+ const available = Date.now() - lastHeartbeatAt <= this.environmentHeartbeatInterval;
532
+ return {
533
+ ...environment,
534
+ available
535
+ };
536
+ }
537
+ async listEnvironments() {
538
+ if (typeof this.discoveryAdapter.listEnvironments !== "function") {
539
+ return [];
540
+ }
541
+ const environments = await this.discoveryAdapter.listEnvironments();
542
+ return environments.map((env) => this.normalizeEnvInfo(env));
543
+ }
544
+ async getEnvironment(environmentName) {
545
+ if (typeof this.discoveryAdapter.getEnvironment !== "function") {
546
+ return null;
547
+ }
548
+ const environment = await this.discoveryAdapter.getEnvironment(environmentName);
549
+ if (!environment) {
550
+ return null;
551
+ }
552
+ return this.normalizeEnvInfo(environment);
553
+ }
554
+ async heartbeatEnvironment() {
555
+ if (typeof this.discoveryAdapter.heartbeatEnvironment !== "function") {
556
+ return;
557
+ }
558
+ if (this.environmentHeartbeatTimer) {
559
+ return;
560
+ }
561
+ this.environmentHeartbeatTimer = setInterval(
562
+ () => this.discoveryAdapter.heartbeatEnvironment(),
563
+ this.environmentHeartbeatInterval
564
+ );
565
+ }
566
+ async dispatchCommand(command) {
567
+ var _a;
568
+ return (_a = this.commandAdapter) == null ? void 0 : _a.dispatchCommand(command);
569
+ }
570
+ registerCommandHandler(mainApp) {
571
+ var _a;
572
+ (_a = this.commandAdapter) == null ? void 0 : _a.registerCommandHandler(mainApp);
573
+ }
574
+ async sendSyncMessage(mainApp, message, options) {
575
+ await mainApp.syncMessageManager.publish("app_supervisor:sync", message, options);
576
+ }
577
+ on(eventName, listener) {
578
+ const listeners = this.listeners(eventName);
579
+ const listenerName = listener.name;
580
+ if (listenerName !== "") {
581
+ const exists = listeners.find((l) => l.name === listenerName);
582
+ if (exists) {
583
+ super.removeListener(eventName, exists);
584
+ }
585
+ }
586
+ return super.on(eventName, listener);
587
+ }
588
+ bindAppEvents(app) {
589
+ app.on("afterDestroy", async () => {
590
+ delete this.apps[app.name];
591
+ delete this.appStatus[app.name];
592
+ delete this.appErrors[app.name];
593
+ delete this.lastMaintainingMessage[app.name];
594
+ delete this.statusBeforeCommanding[app.name];
595
+ this.lastSeenAt.delete(app.name);
596
+ await this.clearAppStatus(app.name);
597
+ });
598
+ app.on("maintainingMessageChanged", async ({ message, maintainingStatus }) => {
599
+ if (this.lastMaintainingMessage[app.name] === message) {
600
+ return;
601
+ }
602
+ this.lastMaintainingMessage[app.name] = message;
603
+ const appStatus = await this.getAppStatus(app.name);
604
+ if (!maintainingStatus && appStatus !== "running") {
605
+ return;
606
+ }
607
+ this.emit("appMaintainingMessageChanged", {
608
+ appName: app.name,
609
+ message,
610
+ status: appStatus,
611
+ command: appStatus == "running" ? null : maintainingStatus.command
612
+ });
613
+ });
614
+ app.on("__started", async (_app, options) => {
615
+ const { maintainingStatus, options: startOptions } = options;
616
+ if (maintainingStatus && [
617
+ "install",
618
+ "upgrade",
619
+ "refresh",
620
+ "restore",
621
+ "pm.add",
622
+ "pm.update",
623
+ "pm.enable",
624
+ "pm.disable",
625
+ "pm.remove"
626
+ ].includes(maintainingStatus.command.name) && !startOptions.recover) {
627
+ void this.setAppStatus(app.name, "running", { refresh: true });
628
+ } else {
629
+ void this.setAppStatus(app.name, "running");
630
+ }
631
+ });
632
+ app.on("__stopped", async () => {
633
+ await this.setAppStatus(app.name, "stopped");
634
+ });
635
+ app.on("maintaining", async (maintainingStatus) => {
636
+ const { status } = maintainingStatus;
637
+ switch (status) {
638
+ case "command_begin":
639
+ this.statusBeforeCommanding[app.name] = await this.getAppStatus(app.name);
640
+ await this.setAppStatus(app.name, "commanding");
641
+ break;
642
+ case "command_running":
643
+ break;
644
+ case "command_end":
645
+ {
646
+ const appStatus = await this.getAppStatus(app.name);
647
+ this.emit("appMaintainingStatusChanged", maintainingStatus);
648
+ if (appStatus == "commanding") {
649
+ await this.setAppStatus(app.name, this.statusBeforeCommanding[app.name]);
650
+ }
651
+ }
652
+ break;
653
+ case "command_error":
654
+ {
655
+ const errorLevel = (0, import_handler.getErrorLevel)(maintainingStatus.error);
656
+ if (errorLevel === "fatal") {
657
+ this.setAppError(app.name, maintainingStatus.error);
658
+ await this.setAppStatus(app.name, "error");
659
+ break;
660
+ }
661
+ if (errorLevel === "warn") {
662
+ this.emit("appError", {
663
+ appName: app.name,
664
+ error: maintainingStatus.error
665
+ });
666
+ }
667
+ await this.setAppStatus(app.name, this.statusBeforeCommanding[app.name]);
668
+ }
669
+ break;
670
+ }
671
+ });
672
+ }
673
+ };
674
+ __name(_AppSupervisor, "AppSupervisor");
675
+ __publicField(_AppSupervisor, "instance");
676
+ __publicField(_AppSupervisor, "discoveryAdapterFactories", /* @__PURE__ */ new Map());
677
+ __publicField(_AppSupervisor, "processAdapterFactories", /* @__PURE__ */ new Map());
678
+ __publicField(_AppSupervisor, "commandAdapterFactories", /* @__PURE__ */ new Map());
679
+ __publicField(_AppSupervisor, "defaultDiscoveryAdapterName", "main-only");
680
+ __publicField(_AppSupervisor, "defaultProcessAdapterName", "main-only");
681
+ __publicField(_AppSupervisor, "defaultCommandAdapterName");
682
+ let AppSupervisor = _AppSupervisor;
683
+ (0, import_utils.applyMixins)(AppSupervisor, [import_utils.AsyncEmitter]);
684
+ AppSupervisor.registerDiscoveryAdapter("main-only", ({ supervisor }) => new import_main_only_adapter.MainOnlyAdapter(supervisor));
685
+ AppSupervisor.registerProcessAdapter("main-only", ({ supervisor }) => new import_main_only_adapter.MainOnlyAdapter(supervisor));
686
+ // Annotate the CommonJS export names for ESM import in node:
687
+ 0 && (module.exports = {
688
+ AppSupervisor,
689
+ MainOnlyAdapter
690
+ });