@nocobase/server 2.0.0-alpha.7 → 2.0.0-alpha.71
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/lib/acl/available-action.js +1 -1
- package/lib/aes-encryptor.d.ts +1 -0
- package/lib/aes-encryptor.js +12 -5
- package/lib/app-command.d.ts +1 -0
- package/lib/app-command.js +3 -0
- package/lib/app-supervisor/app-options-factory.d.ts +80 -0
- package/lib/app-supervisor/app-options-factory.js +91 -0
- package/lib/app-supervisor/condition-registry.d.ts +18 -0
- package/lib/app-supervisor/condition-registry.js +60 -0
- package/lib/app-supervisor/db-creator.d.ts +16 -0
- package/lib/app-supervisor/db-creator.js +163 -0
- package/lib/app-supervisor/db-drivers.d.ts +11 -0
- package/lib/app-supervisor/db-drivers.js +52 -0
- package/lib/app-supervisor/index.d.ts +161 -0
- package/lib/app-supervisor/index.js +690 -0
- package/lib/app-supervisor/main-only-adapter.d.ts +37 -0
- package/lib/app-supervisor/main-only-adapter.js +156 -0
- package/lib/app-supervisor/types.d.ts +161 -0
- package/lib/app-supervisor/types.js +24 -0
- package/lib/application.d.ts +10 -7
- package/lib/application.js +30 -18
- package/lib/commands/index.js +2 -0
- package/lib/commands/pm.js +11 -0
- package/lib/commands/repair.d.ts +11 -0
- package/lib/commands/repair.js +43 -0
- package/lib/commands/start.js +1 -1
- package/lib/event-queue.d.ts +8 -1
- package/lib/event-queue.js +25 -22
- package/lib/gateway/errors.js +50 -12
- package/lib/gateway/index.d.ts +8 -0
- package/lib/gateway/index.js +80 -16
- package/lib/gateway/ipc-socket-server.js +1 -1
- package/lib/gateway/ws-server.js +6 -2
- package/lib/helper.d.ts +359 -0
- package/lib/helper.js +78 -3
- package/lib/index.d.ts +2 -1
- package/lib/index.js +6 -3
- package/lib/locale/locale.js +1 -1
- package/lib/locale/resource.js +6 -9
- package/lib/main-data-source.d.ts +11 -0
- package/lib/main-data-source.js +128 -0
- package/lib/middlewares/data-template.js +1 -6
- package/lib/middlewares/parse-variables.js +2 -49
- package/lib/plugin-manager/deps.js +2 -2
- package/lib/plugin-manager/options/resource.js +52 -25
- package/lib/plugin-manager/plugin-manager.d.ts +1 -0
- package/lib/plugin-manager/plugin-manager.js +36 -1
- package/lib/pub-sub-manager/pub-sub-manager.d.ts +1 -1
- package/lib/pub-sub-manager/pub-sub-manager.js +14 -20
- package/lib/redis-connection-manager.d.ts +15 -5
- package/lib/redis-connection-manager.js +117 -24
- package/lib/snowflake-id-field.d.ts +2 -1
- package/lib/snowflake-id-field.js +2 -2
- package/package.json +18 -17
- package/lib/app-supervisor.d.ts +0 -69
- package/lib/app-supervisor.js +0 -299
- package/lib/background-job-manager.d.ts +0 -40
- package/lib/background-job-manager.js +0 -111
|
@@ -0,0 +1,43 @@
|
|
|
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 __defProp = Object.defineProperty;
|
|
11
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
12
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
13
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
14
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
15
|
+
var __export = (target, all) => {
|
|
16
|
+
for (var name in all)
|
|
17
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
18
|
+
};
|
|
19
|
+
var __copyProps = (to, from, except, desc) => {
|
|
20
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
21
|
+
for (let key of __getOwnPropNames(from))
|
|
22
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
23
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
24
|
+
}
|
|
25
|
+
return to;
|
|
26
|
+
};
|
|
27
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
28
|
+
var repair_exports = {};
|
|
29
|
+
__export(repair_exports, {
|
|
30
|
+
default: () => repair_default
|
|
31
|
+
});
|
|
32
|
+
module.exports = __toCommonJS(repair_exports);
|
|
33
|
+
var repair_default = /* @__PURE__ */ __name((app) => {
|
|
34
|
+
app.command("repair").auth().preload().action(async (options) => {
|
|
35
|
+
app.log.info("start repair data...");
|
|
36
|
+
const Collection = app.db.getCollection("collections");
|
|
37
|
+
if (Collection) {
|
|
38
|
+
await Collection.repository.setApp(app);
|
|
39
|
+
await Collection.repository.load();
|
|
40
|
+
}
|
|
41
|
+
await app.emitAsync("repair", options);
|
|
42
|
+
});
|
|
43
|
+
}, "default");
|
package/lib/commands/start.js
CHANGED
package/lib/event-queue.d.ts
CHANGED
|
@@ -15,6 +15,7 @@ export type QueueCallbackOptions = {
|
|
|
15
15
|
id?: string;
|
|
16
16
|
retried?: number;
|
|
17
17
|
signal?: AbortSignal;
|
|
18
|
+
queueOptions?: QueueMessageOptions;
|
|
18
19
|
};
|
|
19
20
|
export type QueueCallback = (message: any, options: QueueCallbackOptions) => Promise<void>;
|
|
20
21
|
export type QueueEventOptions = {
|
|
@@ -23,6 +24,12 @@ export type QueueEventOptions = {
|
|
|
23
24
|
*/
|
|
24
25
|
interval?: number;
|
|
25
26
|
concurrency?: number;
|
|
27
|
+
/**
|
|
28
|
+
* Shared across multiple applications.
|
|
29
|
+
* Will not use app prefix for channel name.
|
|
30
|
+
* @experimental
|
|
31
|
+
*/
|
|
32
|
+
shared?: boolean;
|
|
26
33
|
idle(): boolean;
|
|
27
34
|
process: QueueCallback;
|
|
28
35
|
};
|
|
@@ -84,7 +91,7 @@ export declare class EventQueue {
|
|
|
84
91
|
protected events: Map<string, QueueEventOptions>;
|
|
85
92
|
get channelPrefix(): string;
|
|
86
93
|
constructor(app: Application, options?: EventQueueOptions);
|
|
87
|
-
getFullChannel(channel: string): string;
|
|
94
|
+
getFullChannel(channel: string, shared?: boolean): string;
|
|
88
95
|
setAdapter<A extends IEventQueueAdapter>(adapter: A): void;
|
|
89
96
|
isConnected(): boolean;
|
|
90
97
|
connect(): Promise<void>;
|
package/lib/event-queue.js
CHANGED
|
@@ -245,7 +245,8 @@ const _MemoryEventQueueAdapter = class _MemoryEventQueueAdapter {
|
|
|
245
245
|
return (async () => event.process(content, {
|
|
246
246
|
id,
|
|
247
247
|
retried,
|
|
248
|
-
signal: AbortSignal.timeout(timeout)
|
|
248
|
+
signal: AbortSignal.timeout(timeout),
|
|
249
|
+
queueOptions: message.options
|
|
249
250
|
}))().then(() => {
|
|
250
251
|
logger.debug(`memory queue (${channel}) consumed message (${id})`);
|
|
251
252
|
}).catch((ex) => {
|
|
@@ -270,16 +271,14 @@ const _EventQueue = class _EventQueue {
|
|
|
270
271
|
constructor(app, options = {}) {
|
|
271
272
|
this.app = app;
|
|
272
273
|
this.options = options;
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
app.
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
});
|
|
282
|
-
}
|
|
274
|
+
this.setAdapter(new MemoryEventQueueAdapter({ appName: this.app.name, logger: this.app.logger }));
|
|
275
|
+
app.on("afterStart", async () => {
|
|
276
|
+
await this.connect();
|
|
277
|
+
});
|
|
278
|
+
app.on("afterStop", async () => {
|
|
279
|
+
app.logger.info("[queue] gracefully shutting down...");
|
|
280
|
+
await this.close();
|
|
281
|
+
});
|
|
283
282
|
}
|
|
284
283
|
adapter;
|
|
285
284
|
events = /* @__PURE__ */ new Map();
|
|
@@ -287,7 +286,10 @@ const _EventQueue = class _EventQueue {
|
|
|
287
286
|
var _a;
|
|
288
287
|
return (_a = this.options) == null ? void 0 : _a.channelPrefix;
|
|
289
288
|
}
|
|
290
|
-
getFullChannel(channel) {
|
|
289
|
+
getFullChannel(channel, shared = false) {
|
|
290
|
+
if (shared) {
|
|
291
|
+
return [this.channelPrefix, channel].filter(Boolean).join(".");
|
|
292
|
+
}
|
|
291
293
|
return [this.app.name, this.channelPrefix, channel].filter(Boolean).join(".");
|
|
292
294
|
}
|
|
293
295
|
setAdapter(adapter) {
|
|
@@ -303,14 +305,10 @@ const _EventQueue = class _EventQueue {
|
|
|
303
305
|
if (!this.adapter) {
|
|
304
306
|
throw new Error("no adapter set, cannot connect");
|
|
305
307
|
}
|
|
306
|
-
if (!this.app.serving()) {
|
|
307
|
-
this.app.logger.warn("app is not serving, will not connect to event queue");
|
|
308
|
-
return;
|
|
309
|
-
}
|
|
310
308
|
await this.adapter.connect();
|
|
311
309
|
this.app.logger.debug(`connected to adapter, using memory? ${this.adapter instanceof MemoryEventQueueAdapter}`);
|
|
312
310
|
for (const [channel, event] of this.events.entries()) {
|
|
313
|
-
this.adapter.subscribe(this.getFullChannel(channel), event);
|
|
311
|
+
this.adapter.subscribe(this.getFullChannel(channel, event.shared), event);
|
|
314
312
|
}
|
|
315
313
|
}
|
|
316
314
|
async close() {
|
|
@@ -318,8 +316,8 @@ const _EventQueue = class _EventQueue {
|
|
|
318
316
|
return;
|
|
319
317
|
}
|
|
320
318
|
await this.adapter.close();
|
|
321
|
-
for (const channel of this.events.
|
|
322
|
-
this.adapter.unsubscribe(this.getFullChannel(channel));
|
|
319
|
+
for (const [channel, event] of this.events.entries()) {
|
|
320
|
+
this.adapter.unsubscribe(this.getFullChannel(channel, event.shared));
|
|
323
321
|
}
|
|
324
322
|
}
|
|
325
323
|
subscribe(channel, options) {
|
|
@@ -329,16 +327,17 @@ const _EventQueue = class _EventQueue {
|
|
|
329
327
|
}
|
|
330
328
|
this.events.set(channel, options);
|
|
331
329
|
if (this.isConnected()) {
|
|
332
|
-
this.adapter.subscribe(this.getFullChannel(channel
|
|
330
|
+
this.adapter.subscribe(this.getFullChannel(channel, options.shared), this.events.get(channel));
|
|
333
331
|
}
|
|
334
332
|
}
|
|
335
333
|
unsubscribe(channel) {
|
|
334
|
+
var _a;
|
|
336
335
|
if (!this.events.has(channel)) {
|
|
337
336
|
return;
|
|
338
337
|
}
|
|
339
338
|
this.events.delete(channel);
|
|
340
339
|
if (this.isConnected()) {
|
|
341
|
-
this.adapter.unsubscribe(this.getFullChannel(channel));
|
|
340
|
+
this.adapter.unsubscribe(this.getFullChannel(channel, (_a = this.events.get(channel)) == null ? void 0 : _a.shared));
|
|
342
341
|
}
|
|
343
342
|
}
|
|
344
343
|
async publish(channel, message, options = {}) {
|
|
@@ -348,7 +347,11 @@ const _EventQueue = class _EventQueue {
|
|
|
348
347
|
if (!this.isConnected()) {
|
|
349
348
|
throw new Error("event queue not connected, cannot publish");
|
|
350
349
|
}
|
|
351
|
-
const
|
|
350
|
+
const event = this.events.get(channel);
|
|
351
|
+
if (!event) {
|
|
352
|
+
throw new Error(`event queue not subscribed on channel "${channel}", cannot publish`);
|
|
353
|
+
}
|
|
354
|
+
const c = this.getFullChannel(channel, event.shared);
|
|
352
355
|
this.app.logger.debug(`event queue publishing to channel(${c})`, { message });
|
|
353
356
|
await this.adapter.publish(c, message, {
|
|
354
357
|
timeout: QUEUE_DEFAULT_ACK_TIMEOUT,
|
package/lib/gateway/errors.js
CHANGED
|
@@ -44,6 +44,15 @@ __export(errors_exports, {
|
|
|
44
44
|
module.exports = __toCommonJS(errors_exports);
|
|
45
45
|
var import_app_supervisor = require("../app-supervisor");
|
|
46
46
|
var import_lodash = __toESM(require("lodash"));
|
|
47
|
+
function getMaintaining(app) {
|
|
48
|
+
var _a;
|
|
49
|
+
return (_a = app == null ? void 0 : app.getMaintaining) == null ? void 0 : _a.call(app);
|
|
50
|
+
}
|
|
51
|
+
__name(getMaintaining, "getMaintaining");
|
|
52
|
+
function getAppName(app) {
|
|
53
|
+
return (app == null ? void 0 : app.name) || "unknown";
|
|
54
|
+
}
|
|
55
|
+
__name(getAppName, "getAppName");
|
|
47
56
|
const errors = {
|
|
48
57
|
APP_NOT_FOUND: {
|
|
49
58
|
status: 404,
|
|
@@ -53,6 +62,9 @@ const errors = {
|
|
|
53
62
|
APP_ERROR: {
|
|
54
63
|
status: 503,
|
|
55
64
|
message: /* @__PURE__ */ __name(({ app }) => {
|
|
65
|
+
if (!(app == null ? void 0 : app.name)) {
|
|
66
|
+
return "";
|
|
67
|
+
}
|
|
56
68
|
const error = import_app_supervisor.AppSupervisor.getInstance().appErrors[app.name];
|
|
57
69
|
if (!error) {
|
|
58
70
|
return "";
|
|
@@ -64,25 +76,36 @@ const errors = {
|
|
|
64
76
|
return message;
|
|
65
77
|
}, "message"),
|
|
66
78
|
code: /* @__PURE__ */ __name(({ app }) => {
|
|
79
|
+
if (!(app == null ? void 0 : app.name)) {
|
|
80
|
+
return "APP_ERROR";
|
|
81
|
+
}
|
|
67
82
|
const error = import_app_supervisor.AppSupervisor.getInstance().appErrors[app.name];
|
|
68
|
-
return error["code"] || "APP_ERROR";
|
|
83
|
+
return (error == null ? void 0 : error["code"]) || "APP_ERROR";
|
|
69
84
|
}, "code"),
|
|
70
|
-
command: /* @__PURE__ */ __name(({ app }) =>
|
|
85
|
+
command: /* @__PURE__ */ __name(({ app }) => {
|
|
86
|
+
var _a;
|
|
87
|
+
return (_a = getMaintaining(app)) == null ? void 0 : _a.command;
|
|
88
|
+
}, "command"),
|
|
89
|
+
maintaining: true
|
|
90
|
+
},
|
|
91
|
+
APP_PREPARING: {
|
|
92
|
+
status: 503,
|
|
93
|
+
message: /* @__PURE__ */ __name(({ appName }) => `application ${appName} is preparing, please wait patiently`, "message"),
|
|
71
94
|
maintaining: true
|
|
72
95
|
},
|
|
73
96
|
APP_STARTING: {
|
|
74
97
|
status: 503,
|
|
75
|
-
message: /* @__PURE__ */ __name(({ app }) => app.maintainingMessage, "message"),
|
|
98
|
+
message: /* @__PURE__ */ __name(({ app }) => (app == null ? void 0 : app.maintainingMessage) || "", "message"),
|
|
76
99
|
maintaining: true
|
|
77
100
|
},
|
|
78
101
|
APP_STOPPED: {
|
|
79
102
|
status: 503,
|
|
80
|
-
message: /* @__PURE__ */ __name(({ app }) => `application ${app
|
|
103
|
+
message: /* @__PURE__ */ __name(({ app, appName }) => `application ${appName || getAppName(app)} is stopped`, "message"),
|
|
81
104
|
maintaining: true
|
|
82
105
|
},
|
|
83
106
|
APP_INITIALIZED: {
|
|
84
107
|
status: 503,
|
|
85
|
-
message: /* @__PURE__ */ __name(({ app }) => `application ${app
|
|
108
|
+
message: /* @__PURE__ */ __name(({ app }) => `application ${getAppName(app)} is initialized, waiting for command`, "message"),
|
|
86
109
|
maintaining: true
|
|
87
110
|
},
|
|
88
111
|
APP_INITIALIZING: {
|
|
@@ -93,25 +116,40 @@ const errors = {
|
|
|
93
116
|
COMMAND_ERROR: {
|
|
94
117
|
status: 503,
|
|
95
118
|
maintaining: true,
|
|
96
|
-
message: /* @__PURE__ */ __name(({ app }) =>
|
|
97
|
-
|
|
119
|
+
message: /* @__PURE__ */ __name(({ app }) => {
|
|
120
|
+
var _a, _b;
|
|
121
|
+
return ((_b = (_a = getMaintaining(app)) == null ? void 0 : _a.error) == null ? void 0 : _b.message) || "";
|
|
122
|
+
}, "message"),
|
|
123
|
+
command: /* @__PURE__ */ __name(({ app }) => {
|
|
124
|
+
var _a;
|
|
125
|
+
return (_a = getMaintaining(app)) == null ? void 0 : _a.command;
|
|
126
|
+
}, "command")
|
|
98
127
|
},
|
|
99
128
|
COMMAND_END: {
|
|
100
129
|
status: 503,
|
|
101
130
|
maintaining: true,
|
|
102
|
-
message: /* @__PURE__ */ __name(({ app }) =>
|
|
103
|
-
|
|
131
|
+
message: /* @__PURE__ */ __name(({ app }) => {
|
|
132
|
+
var _a, _b;
|
|
133
|
+
return `${((_b = (_a = getMaintaining(app)) == null ? void 0 : _a.command) == null ? void 0 : _b.name) || "command"} running end`;
|
|
134
|
+
}, "message"),
|
|
135
|
+
command: /* @__PURE__ */ __name(({ app }) => {
|
|
136
|
+
var _a;
|
|
137
|
+
return (_a = getMaintaining(app)) == null ? void 0 : _a.command;
|
|
138
|
+
}, "command")
|
|
104
139
|
},
|
|
105
140
|
APP_COMMANDING: {
|
|
106
141
|
status: 503,
|
|
107
142
|
maintaining: true,
|
|
108
|
-
message: /* @__PURE__ */ __name(({ app, message }) => message || app.maintainingMessage, "message"),
|
|
109
|
-
command: /* @__PURE__ */ __name(({ app, command }) =>
|
|
143
|
+
message: /* @__PURE__ */ __name(({ app, message }) => message || (app == null ? void 0 : app.maintainingMessage) || "", "message"),
|
|
144
|
+
command: /* @__PURE__ */ __name(({ app, command }) => {
|
|
145
|
+
var _a;
|
|
146
|
+
return command || ((_a = getMaintaining(app)) == null ? void 0 : _a.command);
|
|
147
|
+
}, "command")
|
|
110
148
|
},
|
|
111
149
|
APP_RUNNING: {
|
|
112
150
|
status: 200,
|
|
113
151
|
maintaining: false,
|
|
114
|
-
message: /* @__PURE__ */ __name(({ message, app }) => message || `application ${app
|
|
152
|
+
message: /* @__PURE__ */ __name(({ message, app }) => message || `application ${getAppName(app)} is running`, "message")
|
|
115
153
|
},
|
|
116
154
|
UNKNOWN_ERROR: {
|
|
117
155
|
status: 500,
|
package/lib/gateway/index.d.ts
CHANGED
|
@@ -23,6 +23,12 @@ export interface IncomingRequest {
|
|
|
23
23
|
url: string;
|
|
24
24
|
headers: any;
|
|
25
25
|
}
|
|
26
|
+
export interface GatewayRequestContext {
|
|
27
|
+
req: IncomingMessage;
|
|
28
|
+
res: ServerResponse;
|
|
29
|
+
appName: string;
|
|
30
|
+
}
|
|
31
|
+
type GatewayMiddleware = (ctx: GatewayRequestContext, next: () => Promise<void>) => Promise<void> | void;
|
|
26
32
|
export type AppSelector = (req: IncomingRequest) => string | Promise<string>;
|
|
27
33
|
export type AppSelectorMiddleware = (ctx: AppSelectorMiddlewareContext, next: () => Promise<void>) => void;
|
|
28
34
|
interface StartHttpServerOptions {
|
|
@@ -39,6 +45,7 @@ export interface AppSelectorMiddlewareContext {
|
|
|
39
45
|
}
|
|
40
46
|
export declare class Gateway extends EventEmitter {
|
|
41
47
|
private static instance;
|
|
48
|
+
middlewares: Toposort<GatewayMiddleware>;
|
|
42
49
|
/**
|
|
43
50
|
* use main app as default app to handle request
|
|
44
51
|
*/
|
|
@@ -54,6 +61,7 @@ export declare class Gateway extends EventEmitter {
|
|
|
54
61
|
private onTerminate;
|
|
55
62
|
private constructor();
|
|
56
63
|
static getInstance(options?: any): Gateway;
|
|
64
|
+
use(middleware: GatewayMiddleware, options?: ToposortOptions): void;
|
|
57
65
|
static getIPCSocketClient(): Promise<false | IPCSocketClient>;
|
|
58
66
|
destroy(): void;
|
|
59
67
|
reset(): void;
|
package/lib/gateway/index.js
CHANGED
|
@@ -75,6 +75,7 @@ function getSocketPath() {
|
|
|
75
75
|
}
|
|
76
76
|
__name(getSocketPath, "getSocketPath");
|
|
77
77
|
const _Gateway = class _Gateway extends import_events.EventEmitter {
|
|
78
|
+
middlewares;
|
|
78
79
|
/**
|
|
79
80
|
* use main app as default app to handle request
|
|
80
81
|
*/
|
|
@@ -98,6 +99,9 @@ const _Gateway = class _Gateway extends import_events.EventEmitter {
|
|
|
98
99
|
try {
|
|
99
100
|
for (const app of apps) {
|
|
100
101
|
try {
|
|
102
|
+
if (!app) {
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
101
105
|
await app.destroy({ signal });
|
|
102
106
|
} catch (error) {
|
|
103
107
|
const logger = (app == null ? void 0 : app.log) ?? console;
|
|
@@ -124,6 +128,9 @@ const _Gateway = class _Gateway extends import_events.EventEmitter {
|
|
|
124
128
|
}
|
|
125
129
|
return _Gateway.instance;
|
|
126
130
|
}
|
|
131
|
+
use(middleware, options) {
|
|
132
|
+
this.middlewares.add(middleware, options);
|
|
133
|
+
}
|
|
127
134
|
static async getIPCSocketClient() {
|
|
128
135
|
const socketPath = getSocketPath();
|
|
129
136
|
try {
|
|
@@ -139,6 +146,7 @@ const _Gateway = class _Gateway extends import_events.EventEmitter {
|
|
|
139
146
|
_Gateway.instance = null;
|
|
140
147
|
}
|
|
141
148
|
reset() {
|
|
149
|
+
this.middlewares = new import_utils.Toposort();
|
|
142
150
|
this.selectorMiddlewares = new import_utils.Toposort();
|
|
143
151
|
this.addAppSelectorMiddleware(
|
|
144
152
|
async (ctx, next) => {
|
|
@@ -202,7 +210,15 @@ const _Gateway = class _Gateway extends import_events.EventEmitter {
|
|
|
202
210
|
res.end(JSON.stringify({ error }));
|
|
203
211
|
}
|
|
204
212
|
responseErrorWithCode(code, res, options) {
|
|
213
|
+
const log = this.getLogger(options.appName, res);
|
|
205
214
|
const error = (0, import_errors.applyErrorWithArgs)((0, import_errors.getErrorWithCode)(code), options);
|
|
215
|
+
log.error(error.message, {
|
|
216
|
+
method: "responseErrorWithCode",
|
|
217
|
+
code,
|
|
218
|
+
error,
|
|
219
|
+
statusCode: res.statusCode,
|
|
220
|
+
appName: options.appName
|
|
221
|
+
});
|
|
206
222
|
this.responseError(res, error);
|
|
207
223
|
}
|
|
208
224
|
async requestHandler(req, res) {
|
|
@@ -213,7 +229,22 @@ const _Gateway = class _Gateway extends import_events.EventEmitter {
|
|
|
213
229
|
res.end("ok");
|
|
214
230
|
return;
|
|
215
231
|
}
|
|
232
|
+
const supervisor = import_app_supervisor.AppSupervisor.getInstance();
|
|
233
|
+
let handleApp = "main";
|
|
234
|
+
try {
|
|
235
|
+
handleApp = await this.getRequestHandleAppName(req);
|
|
236
|
+
} catch (error) {
|
|
237
|
+
this.getLogger("main", res).error("Failed to get handle app name", { error });
|
|
238
|
+
this.responseErrorWithCode("APP_INITIALIZING", res, { appName: handleApp });
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
216
241
|
if (pathname.startsWith(APP_PUBLIC_PATH + "storage/uploads/")) {
|
|
242
|
+
if (handleApp !== "main") {
|
|
243
|
+
const isProxy = await supervisor.proxyWeb(handleApp, req, res);
|
|
244
|
+
if (isProxy) {
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
217
248
|
req.url = req.url.substring(APP_PUBLIC_PATH.length - 1);
|
|
218
249
|
await compress(req, res);
|
|
219
250
|
return (0, import_serve_handler.default)(req, res, {
|
|
@@ -222,6 +253,12 @@ const _Gateway = class _Gateway extends import_events.EventEmitter {
|
|
|
222
253
|
});
|
|
223
254
|
}
|
|
224
255
|
if (pathname.startsWith(PLUGIN_STATICS_PATH) && !pathname.includes("/server/")) {
|
|
256
|
+
if (handleApp !== "main") {
|
|
257
|
+
const isProxy = await supervisor.proxyWeb(handleApp, req, res);
|
|
258
|
+
if (isProxy) {
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
225
262
|
await compress(req, res);
|
|
226
263
|
const packageName = (0, import_plugin_manager.getPackageNameByExposeUrl)(pathname);
|
|
227
264
|
const publicDir = (0, import_plugin_manager.getPackageDirByExposeUrl)(pathname);
|
|
@@ -237,6 +274,12 @@ const _Gateway = class _Gateway extends import_events.EventEmitter {
|
|
|
237
274
|
});
|
|
238
275
|
}
|
|
239
276
|
if (!pathname.startsWith(import_node_process.default.env.API_BASE_PATH)) {
|
|
277
|
+
if (handleApp !== "main") {
|
|
278
|
+
const isProxy = await supervisor.proxyWeb(handleApp, req, res);
|
|
279
|
+
if (isProxy) {
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
240
283
|
req.url = req.url.substring(APP_PUBLIC_PATH.length - 1);
|
|
241
284
|
await compress(req, res);
|
|
242
285
|
return (0, import_serve_handler.default)(req, res, {
|
|
@@ -244,33 +287,43 @@ const _Gateway = class _Gateway extends import_events.EventEmitter {
|
|
|
244
287
|
rewrites: [{ source: "/**", destination: "/index.html" }]
|
|
245
288
|
});
|
|
246
289
|
}
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
this.responseErrorWithCode("APP_INITIALIZING", res, { appName: handleApp });
|
|
253
|
-
return;
|
|
290
|
+
if (handleApp !== "main") {
|
|
291
|
+
const isProxy = await supervisor.proxyWeb(handleApp, req, res);
|
|
292
|
+
if (isProxy) {
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
254
295
|
}
|
|
255
|
-
const hasApp =
|
|
296
|
+
const hasApp = supervisor.hasApp(handleApp);
|
|
256
297
|
if (!hasApp) {
|
|
257
|
-
void
|
|
298
|
+
void supervisor.bootstrapApp(handleApp);
|
|
258
299
|
}
|
|
259
|
-
let appStatus =
|
|
300
|
+
let appStatus = await supervisor.getAppStatus(handleApp, "preparing");
|
|
260
301
|
if (appStatus === "not_found") {
|
|
261
302
|
this.responseErrorWithCode("APP_NOT_FOUND", res, { appName: handleApp });
|
|
262
303
|
return;
|
|
263
304
|
}
|
|
305
|
+
if (appStatus === "preparing") {
|
|
306
|
+
this.responseErrorWithCode("APP_PREPARING", res, { appName: handleApp });
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
264
309
|
if (appStatus === "initializing") {
|
|
265
310
|
this.responseErrorWithCode("APP_INITIALIZING", res, { appName: handleApp });
|
|
266
311
|
return;
|
|
267
312
|
}
|
|
268
313
|
if (appStatus === "initialized") {
|
|
269
|
-
const appInstance = await
|
|
270
|
-
appInstance
|
|
271
|
-
|
|
314
|
+
const appInstance = await supervisor.getApp(handleApp);
|
|
315
|
+
if (!appInstance) {
|
|
316
|
+
this.responseErrorWithCode("APP_NOT_FOUND", res, { appName: handleApp });
|
|
317
|
+
return;
|
|
318
|
+
}
|
|
319
|
+
supervisor.startApp(handleApp);
|
|
320
|
+
appStatus = await supervisor.getAppStatus(handleApp);
|
|
321
|
+
}
|
|
322
|
+
const app = await supervisor.getApp(handleApp);
|
|
323
|
+
if (!app) {
|
|
324
|
+
this.responseErrorWithCode("APP_NOT_FOUND", res, { appName: handleApp });
|
|
325
|
+
return;
|
|
272
326
|
}
|
|
273
|
-
const app = await import_app_supervisor.AppSupervisor.getInstance().getApp(handleApp);
|
|
274
327
|
if (appStatus !== "running") {
|
|
275
328
|
this.responseErrorWithCode(`${appStatus}`, res, { app, appName: handleApp });
|
|
276
329
|
return;
|
|
@@ -281,9 +334,16 @@ const _Gateway = class _Gateway extends import_events.EventEmitter {
|
|
|
281
334
|
return;
|
|
282
335
|
}
|
|
283
336
|
if (handleApp !== "main") {
|
|
284
|
-
|
|
337
|
+
await supervisor.setAppLastSeenAt(handleApp);
|
|
285
338
|
}
|
|
286
|
-
|
|
339
|
+
const ctx = { req, res, appName: handleApp };
|
|
340
|
+
const fn = (0, import_koa_compose.default)([
|
|
341
|
+
...this.middlewares.nodes,
|
|
342
|
+
async (_ctx) => {
|
|
343
|
+
await app.callback()(req, res);
|
|
344
|
+
}
|
|
345
|
+
]);
|
|
346
|
+
await fn(ctx);
|
|
287
347
|
}
|
|
288
348
|
getAppSelectorMiddlewares() {
|
|
289
349
|
return this.selectorMiddlewares;
|
|
@@ -409,6 +469,10 @@ const _Gateway = class _Gateway extends import_events.EventEmitter {
|
|
|
409
469
|
});
|
|
410
470
|
this.wsServer = new import_ws_server.WSServer();
|
|
411
471
|
this.server.on("upgrade", async (request, socket, head) => {
|
|
472
|
+
const isProxy = await import_app_supervisor.AppSupervisor.getInstance().proxyWs(request, socket, head);
|
|
473
|
+
if (isProxy) {
|
|
474
|
+
return;
|
|
475
|
+
}
|
|
412
476
|
const appInstance = await import_app_supervisor.AppSupervisor.getInstance().getApp("main");
|
|
413
477
|
for (const handle of _Gateway.wsServers) {
|
|
414
478
|
const result = await handle(request, socket, head, appInstance);
|
|
@@ -104,7 +104,7 @@ const _IPCSocketServer = class _IPCSocketServer {
|
|
|
104
104
|
const max = 300;
|
|
105
105
|
let count = 0;
|
|
106
106
|
const timer = setInterval(async () => {
|
|
107
|
-
status2 = import_app_supervisor.AppSupervisor.getInstance().getAppStatus("main");
|
|
107
|
+
status2 = await import_app_supervisor.AppSupervisor.getInstance().getAppStatus("main");
|
|
108
108
|
if (status2 === "running") {
|
|
109
109
|
clearInterval(timer);
|
|
110
110
|
resolve(status2);
|
package/lib/gateway/ws-server.js
CHANGED
|
@@ -90,7 +90,7 @@ const _WSServer = class _WSServer extends import_events.default {
|
|
|
90
90
|
}
|
|
91
91
|
}
|
|
92
92
|
client.tags.add(`app#${handleAppName}`);
|
|
93
|
-
import_app_supervisor.AppSupervisor.getInstance().
|
|
93
|
+
import_app_supervisor.AppSupervisor.getInstance().bootstrapApp(handleAppName);
|
|
94
94
|
});
|
|
95
95
|
});
|
|
96
96
|
import_app_supervisor.AppSupervisor.getInstance().on("appError", async ({ appName, error }) => {
|
|
@@ -112,6 +112,7 @@ const _WSServer = class _WSServer extends import_events.default {
|
|
|
112
112
|
});
|
|
113
113
|
const payload = getPayloadByErrorCode(status, {
|
|
114
114
|
app,
|
|
115
|
+
appName,
|
|
115
116
|
message,
|
|
116
117
|
command
|
|
117
118
|
});
|
|
@@ -228,6 +229,9 @@ const _WSServer = class _WSServer extends import_events.default {
|
|
|
228
229
|
}
|
|
229
230
|
removeClientTag(clientId, tagKey) {
|
|
230
231
|
const client = this.webSocketClients.get(clientId);
|
|
232
|
+
if (!client) {
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
231
235
|
client.tags.forEach((tag) => {
|
|
232
236
|
if (tag.startsWith(`${tagKey}#`)) {
|
|
233
237
|
client.tags.delete(tag);
|
|
@@ -245,7 +249,7 @@ const _WSServer = class _WSServer extends import_events.default {
|
|
|
245
249
|
client.tags.add(`app#${handleAppName}`);
|
|
246
250
|
const hasApp = import_app_supervisor.AppSupervisor.getInstance().hasApp(handleAppName);
|
|
247
251
|
if (!hasApp) {
|
|
248
|
-
import_app_supervisor.AppSupervisor.getInstance().
|
|
252
|
+
import_app_supervisor.AppSupervisor.getInstance().bootstrapApp(handleAppName);
|
|
249
253
|
}
|
|
250
254
|
}
|
|
251
255
|
removeConnection(id) {
|