@eggjs/core 7.0.0-beta.35 → 7.0.0-beta.36

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/lifecycle.js CHANGED
@@ -1,306 +1,280 @@
1
- import assert from 'node:assert';
2
- import { EventEmitter } from 'node:events';
3
- import { debuglog, format } from 'node:util';
4
- import { EggConsoleLogger } from 'egg-logger';
5
- import { Ready as ReadyObject } from 'get-ready';
6
- import { isClass } from 'is-type-of';
7
- import { Ready } from 'ready-callback';
8
- import utils from "./utils/index.js";
9
- const debug = debuglog('egg/core/lifecycle');
10
- export class Lifecycle extends EventEmitter {
11
- #init;
12
- #readyObject;
13
- #bootHooks;
14
- #boots;
15
- #isClosed;
16
- #closeFunctionSet;
17
- loadReady;
18
- bootReady;
19
- options;
20
- readyTimeout;
21
- constructor(options) {
22
- super();
23
- options.logger = options.logger ?? new EggConsoleLogger();
24
- this.options = options;
25
- this.#readyObject = new ReadyObject();
26
- this.#bootHooks = [];
27
- this.#boots = [];
28
- this.#closeFunctionSet = new Set();
29
- this.#isClosed = false;
30
- this.#init = false;
31
- this.timing.start(`${this.options.app.type} Start`);
32
- // get app timeout from env or use default timeout 10 second
33
- const eggReadyTimeoutEnv = Number.parseInt(process.env.EGG_READY_TIMEOUT_ENV || '10000');
34
- assert(Number.isInteger(eggReadyTimeoutEnv), `process.env.EGG_READY_TIMEOUT_ENV ${process.env.EGG_READY_TIMEOUT_ENV} should be able to parseInt.`);
35
- this.readyTimeout = eggReadyTimeoutEnv;
36
- this.#initReady();
37
- this.on('ready_stat', (data) => {
38
- this.logger.info('[egg/core/lifecycle:ready_stat] end ready task %s, remain %j', data.id, data.remain);
39
- }).on('ready_timeout', (id) => {
40
- this.logger.warn('[egg/core/lifecycle:ready_timeout] %s seconds later %s was still unable to finish.', this.readyTimeout / 1000, id);
41
- });
42
- this.ready((err) => {
43
- this.triggerDidReady(err);
44
- debug('app ready');
45
- this.timing.end(`${this.options.app.type} Start`);
46
- });
47
- }
48
- ready(flagOrFunction) {
49
- if (flagOrFunction === undefined) {
50
- return this.#readyObject.ready();
51
- }
52
- return this.#readyObject.ready(flagOrFunction);
53
- }
54
- get app() {
55
- return this.options.app;
56
- }
57
- get logger() {
58
- return this.options.logger;
59
- }
60
- get timing() {
61
- return this.app.timing;
62
- }
63
- legacyReadyCallback(name, opt) {
64
- const timingKeyPrefix = 'readyCallback';
65
- const timing = this.timing;
66
- const cb = this.loadReady.readyCallback(name, opt);
67
- const timingKey = `${timingKeyPrefix} in ` + utils.getResolvedFilename(name, this.app.baseDir);
68
- this.timing.start(timingKey);
69
- debug('register legacyReadyCallback');
70
- return function legacyReadyCallback(...args) {
71
- timing.end(timingKey);
72
- debug('end legacyReadyCallback');
73
- cb(...args);
74
- };
75
- }
76
- addBootHook(bootHootOrBootClass) {
77
- assert(this.#init === false, 'do not add hook when lifecycle has been initialized');
78
- this.#bootHooks.push(bootHootOrBootClass);
79
- }
80
- addFunctionAsBootHook(hook, fullPath) {
81
- assert(this.#init === false, 'do not add hook when lifecycle has been initialized');
82
- // app.js is exported as a function
83
- // call this function in configDidLoad
84
- class Boot {
85
- static fullPath;
86
- app;
87
- constructor(app) {
88
- this.app = app;
89
- }
90
- configDidLoad() {
91
- hook(this.app);
92
- }
93
- }
94
- Boot.fullPath = fullPath;
95
- this.#bootHooks.push(Boot);
96
- }
97
- /**
98
- * init boots and trigger config did config
99
- */
100
- init() {
101
- debug('%s init lifecycle', this.app.type);
102
- assert(this.#init === false, 'lifecycle have been init');
103
- this.#init = true;
104
- this.#boots = this.#bootHooks.map((BootHootOrBootClass) => {
105
- let instance = BootHootOrBootClass;
106
- if (isClass(BootHootOrBootClass)) {
107
- instance = new BootHootOrBootClass(this.app);
108
- if (!instance.fullPath && 'fullPath' in BootHootOrBootClass) {
109
- instance.fullPath = BootHootOrBootClass.fullPath;
110
- }
111
- }
112
- debug('[init] add boot instance: %o', instance.fullPath);
113
- return instance;
114
- });
115
- }
116
- registerBeforeStart(scope, name) {
117
- debug('%s add registerBeforeStart, name: %o', this.options.app.type, name);
118
- this.#registerReadyCallback({
119
- scope,
120
- ready: this.loadReady,
121
- timingKeyPrefix: 'Before Start',
122
- scopeFullName: name,
123
- });
124
- }
125
- registerBeforeClose(fn, fullPath) {
126
- assert(typeof fn === 'function', 'argument should be function');
127
- assert(this.#isClosed === false, 'app has been closed');
128
- if (fullPath) {
129
- fn.fullPath = fullPath;
130
- }
131
- this.#closeFunctionSet.add(fn);
132
- debug('%s register beforeClose at %o, count: %d', this.app.type, fullPath, this.#closeFunctionSet.size);
133
- }
134
- async close() {
135
- // close in reverse order: first created, last closed
136
- const closeFns = Array.from(this.#closeFunctionSet);
137
- debug('%s start trigger %d beforeClose functions', this.app.type, closeFns.length);
138
- for (const fn of closeFns.reverse()) {
139
- debug('%s trigger beforeClose at %o', this.app.type, fn.fullPath);
140
- await utils.callFn(fn);
141
- this.#closeFunctionSet.delete(fn);
142
- }
143
- // Be called after other close callbacks
144
- this.app.emit('close');
145
- this.removeAllListeners();
146
- this.app.removeAllListeners();
147
- this.#isClosed = true;
148
- debug('%s closed', this.app.type);
149
- }
150
- triggerConfigWillLoad() {
151
- debug('trigger configWillLoad start');
152
- for (const boot of this.#boots) {
153
- if (typeof boot.configWillLoad === 'function') {
154
- debug('trigger configWillLoad at %o', boot.fullPath);
155
- boot.configWillLoad();
156
- }
157
- }
158
- debug('trigger configWillLoad end');
159
- this.triggerConfigDidLoad();
160
- }
161
- triggerConfigDidLoad() {
162
- debug('trigger configDidLoad start');
163
- for (const boot of this.#boots) {
164
- if (typeof boot.configDidLoad === 'function') {
165
- debug('trigger configDidLoad at %o', boot.fullPath);
166
- boot.configDidLoad();
167
- }
168
- // function boot hook register after configDidLoad trigger
169
- if (typeof boot.beforeClose === 'function') {
170
- const beforeClose = boot.beforeClose.bind(boot);
171
- this.registerBeforeClose(beforeClose, boot.fullPath);
172
- }
173
- }
174
- debug('trigger configDidLoad end');
175
- this.triggerDidLoad();
176
- }
177
- triggerDidLoad() {
178
- debug('trigger didLoad start');
179
- debug('loadReady start');
180
- this.loadReady.start();
181
- for (const boot of this.#boots) {
182
- if (typeof boot.didLoad === 'function') {
183
- const didLoad = boot.didLoad.bind(boot);
184
- this.#registerReadyCallback({
185
- scope: didLoad,
186
- ready: this.loadReady,
187
- timingKeyPrefix: 'Did Load',
188
- scopeFullName: boot.fullPath + ':didLoad',
189
- });
190
- }
191
- }
192
- }
193
- triggerWillReady() {
194
- debug('trigger willReady start');
195
- debug('bootReady start');
196
- this.bootReady.start();
197
- for (const boot of this.#boots) {
198
- if (typeof boot.willReady === 'function') {
199
- const willReady = boot.willReady.bind(boot);
200
- this.#registerReadyCallback({
201
- scope: willReady,
202
- ready: this.bootReady,
203
- timingKeyPrefix: 'Will Ready',
204
- scopeFullName: boot.fullPath + ':willReady',
205
- });
206
- }
207
- }
208
- }
209
- triggerDidReady(err) {
210
- debug('trigger didReady start');
211
- return (async () => {
212
- for (const boot of this.#boots) {
213
- if (typeof boot.didReady === 'function') {
214
- debug('trigger didReady at %o', boot.fullPath);
215
- try {
216
- await boot.didReady(err);
217
- }
218
- catch (err) {
219
- debug('trigger didReady error at %o, error: %s', boot.fullPath, err);
220
- this.emit('error', err);
221
- }
222
- }
223
- }
224
- debug('trigger didReady end');
225
- })();
226
- }
227
- triggerServerDidReady() {
228
- debug('trigger serverDidReady start');
229
- return (async () => {
230
- for (const boot of this.#boots) {
231
- if (typeof boot.serverDidReady !== 'function') {
232
- continue;
233
- }
234
- debug('trigger serverDidReady at %o', boot.fullPath);
235
- try {
236
- await boot.serverDidReady();
237
- }
238
- catch (err) {
239
- debug('trigger serverDidReady error at %o, error: %s', boot.fullPath, err);
240
- this.emit('error', err);
241
- }
242
- }
243
- debug('trigger serverDidReady end');
244
- })();
245
- }
246
- #initReady() {
247
- debug('loadReady init');
248
- this.loadReady = new Ready({ timeout: this.readyTimeout, lazyStart: true });
249
- this.#delegateReadyEvent(this.loadReady);
250
- this.loadReady.ready((err) => {
251
- debug('loadReady end, err: %o', err);
252
- debug('trigger didLoad end');
253
- if (err) {
254
- this.ready(err);
255
- }
256
- else {
257
- this.triggerWillReady();
258
- }
259
- });
260
- debug('bootReady init');
261
- this.bootReady = new Ready({ timeout: this.readyTimeout, lazyStart: true });
262
- this.#delegateReadyEvent(this.bootReady);
263
- this.bootReady.ready((err) => {
264
- debug('bootReady end, err: %o', err);
265
- debug('trigger willReady end');
266
- this.ready(err || true);
267
- });
268
- }
269
- #delegateReadyEvent(ready) {
270
- ready.once('error', (err) => ready.ready(err));
271
- ready.on('ready_timeout', (id) => this.emit('ready_timeout', id));
272
- ready.on('ready_stat', (data) => this.emit('ready_stat', data));
273
- ready.on('error', (err) => this.emit('error', err));
274
- }
275
- #registerReadyCallback(args) {
276
- const { scope, ready, timingKeyPrefix, scopeFullName } = args;
277
- if (typeof scope !== 'function') {
278
- throw new TypeError('boot only support function');
279
- }
280
- // get filename from stack if scopeFullName is undefined
281
- const name = scopeFullName || utils.getCalleeFromStack(true, 4);
282
- const timingKey = `${timingKeyPrefix} in ` + utils.getResolvedFilename(name, this.app.baseDir);
283
- this.timing.start(timingKey);
284
- debug('[registerReadyCallback] start name: %o', name);
285
- const done = ready.readyCallback(name);
286
- // ensure scope executes after load completed
287
- process.nextTick(async () => {
288
- try {
289
- await utils.callFn(scope);
290
- debug('[registerReadyCallback] end name: %o', name);
291
- done();
292
- this.timing.end(timingKey);
293
- }
294
- catch (e) {
295
- let err = e;
296
- // avoid non-stringify error: TypeError: Cannot convert object to primitive value
297
- if (!(err instanceof Error)) {
298
- err = new Error(format('%s', err));
299
- }
300
- done(err);
301
- this.timing.end(timingKey);
302
- }
303
- });
304
- }
305
- }
306
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGlmZWN5Y2xlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2xpZmVjeWNsZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLE1BQU0sTUFBTSxhQUFhLENBQUM7QUFDakMsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUMzQyxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUU3QyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFDOUMsT0FBTyxFQUFFLEtBQUssSUFBSSxXQUFXLEVBQXlCLE1BQU0sV0FBVyxDQUFDO0FBQ3hFLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFDckMsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBR3ZDLE9BQU8sS0FBSyxNQUFNLGtCQUFrQixDQUFDO0FBSXJDLE1BQU0sS0FBSyxHQUFHLFFBQVEsQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO0FBc0Q3QyxNQUFNLE9BQU8sU0FBVSxTQUFRLFlBQVk7SUFDekMsS0FBSyxDQUFVO0lBQ2YsWUFBWSxDQUFjO0lBQzFCLFVBQVUsQ0FBcUM7SUFDL0MsTUFBTSxDQUFtQjtJQUN6QixTQUFTLENBQVU7SUFDbkIsaUJBQWlCLENBQXVCO0lBQ3hDLFNBQVMsQ0FBUTtJQUNqQixTQUFTLENBQVE7SUFDakIsT0FBTyxDQUFtQjtJQUMxQixZQUFZLENBQVM7SUFFckIsWUFBWSxPQUFrQztRQUM1QyxLQUFLLEVBQUUsQ0FBQztRQUNSLE9BQU8sQ0FBQyxNQUFNLEdBQUcsT0FBTyxDQUFDLE1BQU0sSUFBSSxJQUFJLGdCQUFnQixFQUFFLENBQUM7UUFDMUQsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUEyQixDQUFDO1FBQzNDLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxXQUFXLEVBQUUsQ0FBQztRQUN0QyxJQUFJLENBQUMsVUFBVSxHQUFH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
1
+ import utils_default from "./utils/index.js";
2
+ import { debuglog, format } from "node:util";
3
+ import assert from "node:assert";
4
+ import { EggConsoleLogger } from "egg-logger";
5
+ import { EventEmitter } from "node:events";
6
+ import { Ready } from "get-ready";
7
+ import { isClass } from "is-type-of";
8
+ import { Ready as Ready$1 } from "ready-callback";
9
+
10
+ //#region src/lifecycle.ts
11
+ const debug = debuglog("egg/core/lifecycle");
12
+ var Lifecycle = class extends EventEmitter {
13
+ #init;
14
+ #readyObject;
15
+ #bootHooks;
16
+ #boots;
17
+ #isClosed;
18
+ #closeFunctionSet;
19
+ loadReady;
20
+ bootReady;
21
+ options;
22
+ readyTimeout;
23
+ constructor(options) {
24
+ super();
25
+ options.logger = options.logger ?? new EggConsoleLogger();
26
+ this.options = options;
27
+ this.#readyObject = new Ready();
28
+ this.#bootHooks = [];
29
+ this.#boots = [];
30
+ this.#closeFunctionSet = /* @__PURE__ */ new Set();
31
+ this.#isClosed = false;
32
+ this.#init = false;
33
+ this.timing.start(`${this.options.app.type} Start`);
34
+ const eggReadyTimeoutEnv = Number.parseInt(process.env.EGG_READY_TIMEOUT_ENV || "10000");
35
+ assert(Number.isInteger(eggReadyTimeoutEnv), `process.env.EGG_READY_TIMEOUT_ENV ${process.env.EGG_READY_TIMEOUT_ENV} should be able to parseInt.`);
36
+ this.readyTimeout = eggReadyTimeoutEnv;
37
+ this.#initReady();
38
+ this.on("ready_stat", (data) => {
39
+ this.logger.info("[egg/core/lifecycle:ready_stat] end ready task %s, remain %j", data.id, data.remain);
40
+ }).on("ready_timeout", (id) => {
41
+ this.logger.warn("[egg/core/lifecycle:ready_timeout] %s seconds later %s was still unable to finish.", this.readyTimeout / 1e3, id);
42
+ });
43
+ this.ready((err) => {
44
+ this.triggerDidReady(err);
45
+ debug("app ready");
46
+ this.timing.end(`${this.options.app.type} Start`);
47
+ });
48
+ }
49
+ ready(flagOrFunction) {
50
+ if (flagOrFunction === void 0) return this.#readyObject.ready();
51
+ return this.#readyObject.ready(flagOrFunction);
52
+ }
53
+ get app() {
54
+ return this.options.app;
55
+ }
56
+ get logger() {
57
+ return this.options.logger;
58
+ }
59
+ get timing() {
60
+ return this.app.timing;
61
+ }
62
+ legacyReadyCallback(name, opt) {
63
+ const timingKeyPrefix = "readyCallback";
64
+ const timing = this.timing;
65
+ const cb = this.loadReady.readyCallback(name, opt);
66
+ const timingKey = `${timingKeyPrefix} in ` + utils_default.getResolvedFilename(name, this.app.baseDir);
67
+ this.timing.start(timingKey);
68
+ debug("register legacyReadyCallback");
69
+ return function legacyReadyCallback(...args) {
70
+ timing.end(timingKey);
71
+ debug("end legacyReadyCallback");
72
+ cb(...args);
73
+ };
74
+ }
75
+ addBootHook(bootHootOrBootClass) {
76
+ assert(this.#init === false, "do not add hook when lifecycle has been initialized");
77
+ this.#bootHooks.push(bootHootOrBootClass);
78
+ }
79
+ addFunctionAsBootHook(hook, fullPath) {
80
+ assert(this.#init === false, "do not add hook when lifecycle has been initialized");
81
+ class Boot {
82
+ static fullPath;
83
+ app;
84
+ constructor(app) {
85
+ this.app = app;
86
+ }
87
+ configDidLoad() {
88
+ hook(this.app);
89
+ }
90
+ }
91
+ Boot.fullPath = fullPath;
92
+ this.#bootHooks.push(Boot);
93
+ }
94
+ /**
95
+ * init boots and trigger config did config
96
+ */
97
+ init() {
98
+ debug("%s init lifecycle", this.app.type);
99
+ assert(this.#init === false, "lifecycle have been init");
100
+ this.#init = true;
101
+ this.#boots = this.#bootHooks.map((BootHootOrBootClass) => {
102
+ let instance = BootHootOrBootClass;
103
+ if (isClass(BootHootOrBootClass)) {
104
+ instance = new BootHootOrBootClass(this.app);
105
+ if (!instance.fullPath && "fullPath" in BootHootOrBootClass) instance.fullPath = BootHootOrBootClass.fullPath;
106
+ }
107
+ debug("[init] add boot instance: %o", instance.fullPath);
108
+ return instance;
109
+ });
110
+ }
111
+ registerBeforeStart(scope, name) {
112
+ debug("%s add registerBeforeStart, name: %o", this.options.app.type, name);
113
+ this.#registerReadyCallback({
114
+ scope,
115
+ ready: this.loadReady,
116
+ timingKeyPrefix: "Before Start",
117
+ scopeFullName: name
118
+ });
119
+ }
120
+ registerBeforeClose(fn, fullPath) {
121
+ assert(typeof fn === "function", "argument should be function");
122
+ assert(this.#isClosed === false, "app has been closed");
123
+ if (fullPath) fn.fullPath = fullPath;
124
+ this.#closeFunctionSet.add(fn);
125
+ debug("%s register beforeClose at %o, count: %d", this.app.type, fullPath, this.#closeFunctionSet.size);
126
+ }
127
+ async close() {
128
+ const closeFns = Array.from(this.#closeFunctionSet);
129
+ debug("%s start trigger %d beforeClose functions", this.app.type, closeFns.length);
130
+ for (const fn of closeFns.reverse()) {
131
+ debug("%s trigger beforeClose at %o", this.app.type, fn.fullPath);
132
+ await utils_default.callFn(fn);
133
+ this.#closeFunctionSet.delete(fn);
134
+ }
135
+ this.app.emit("close");
136
+ this.removeAllListeners();
137
+ this.app.removeAllListeners();
138
+ this.#isClosed = true;
139
+ debug("%s closed", this.app.type);
140
+ }
141
+ triggerConfigWillLoad() {
142
+ debug("trigger configWillLoad start");
143
+ for (const boot of this.#boots) if (typeof boot.configWillLoad === "function") {
144
+ debug("trigger configWillLoad at %o", boot.fullPath);
145
+ boot.configWillLoad();
146
+ }
147
+ debug("trigger configWillLoad end");
148
+ this.triggerConfigDidLoad();
149
+ }
150
+ triggerConfigDidLoad() {
151
+ debug("trigger configDidLoad start");
152
+ for (const boot of this.#boots) {
153
+ if (typeof boot.configDidLoad === "function") {
154
+ debug("trigger configDidLoad at %o", boot.fullPath);
155
+ boot.configDidLoad();
156
+ }
157
+ if (typeof boot.beforeClose === "function") {
158
+ const beforeClose = boot.beforeClose.bind(boot);
159
+ this.registerBeforeClose(beforeClose, boot.fullPath);
160
+ }
161
+ }
162
+ debug("trigger configDidLoad end");
163
+ this.triggerDidLoad();
164
+ }
165
+ triggerDidLoad() {
166
+ debug("trigger didLoad start");
167
+ debug("loadReady start");
168
+ this.loadReady.start();
169
+ for (const boot of this.#boots) if (typeof boot.didLoad === "function") {
170
+ const didLoad = boot.didLoad.bind(boot);
171
+ this.#registerReadyCallback({
172
+ scope: didLoad,
173
+ ready: this.loadReady,
174
+ timingKeyPrefix: "Did Load",
175
+ scopeFullName: boot.fullPath + ":didLoad"
176
+ });
177
+ }
178
+ }
179
+ triggerWillReady() {
180
+ debug("trigger willReady start");
181
+ debug("bootReady start");
182
+ this.bootReady.start();
183
+ for (const boot of this.#boots) if (typeof boot.willReady === "function") {
184
+ const willReady = boot.willReady.bind(boot);
185
+ this.#registerReadyCallback({
186
+ scope: willReady,
187
+ ready: this.bootReady,
188
+ timingKeyPrefix: "Will Ready",
189
+ scopeFullName: boot.fullPath + ":willReady"
190
+ });
191
+ }
192
+ }
193
+ triggerDidReady(err) {
194
+ debug("trigger didReady start");
195
+ return (async () => {
196
+ for (const boot of this.#boots) if (typeof boot.didReady === "function") {
197
+ debug("trigger didReady at %o", boot.fullPath);
198
+ try {
199
+ await boot.didReady(err);
200
+ } catch (err$1) {
201
+ debug("trigger didReady error at %o, error: %s", boot.fullPath, err$1);
202
+ this.emit("error", err$1);
203
+ }
204
+ }
205
+ debug("trigger didReady end");
206
+ })();
207
+ }
208
+ triggerServerDidReady() {
209
+ debug("trigger serverDidReady start");
210
+ return (async () => {
211
+ for (const boot of this.#boots) {
212
+ if (typeof boot.serverDidReady !== "function") continue;
213
+ debug("trigger serverDidReady at %o", boot.fullPath);
214
+ try {
215
+ await boot.serverDidReady();
216
+ } catch (err) {
217
+ debug("trigger serverDidReady error at %o, error: %s", boot.fullPath, err);
218
+ this.emit("error", err);
219
+ }
220
+ }
221
+ debug("trigger serverDidReady end");
222
+ })();
223
+ }
224
+ #initReady() {
225
+ debug("loadReady init");
226
+ this.loadReady = new Ready$1({
227
+ timeout: this.readyTimeout,
228
+ lazyStart: true
229
+ });
230
+ this.#delegateReadyEvent(this.loadReady);
231
+ this.loadReady.ready((err) => {
232
+ debug("loadReady end, err: %o", err);
233
+ debug("trigger didLoad end");
234
+ if (err) this.ready(err);
235
+ else this.triggerWillReady();
236
+ });
237
+ debug("bootReady init");
238
+ this.bootReady = new Ready$1({
239
+ timeout: this.readyTimeout,
240
+ lazyStart: true
241
+ });
242
+ this.#delegateReadyEvent(this.bootReady);
243
+ this.bootReady.ready((err) => {
244
+ debug("bootReady end, err: %o", err);
245
+ debug("trigger willReady end");
246
+ this.ready(err || true);
247
+ });
248
+ }
249
+ #delegateReadyEvent(ready) {
250
+ ready.once("error", (err) => ready.ready(err));
251
+ ready.on("ready_timeout", (id) => this.emit("ready_timeout", id));
252
+ ready.on("ready_stat", (data) => this.emit("ready_stat", data));
253
+ ready.on("error", (err) => this.emit("error", err));
254
+ }
255
+ #registerReadyCallback(args) {
256
+ const { scope, ready, timingKeyPrefix, scopeFullName } = args;
257
+ if (typeof scope !== "function") throw new TypeError("boot only support function");
258
+ const name = scopeFullName || utils_default.getCalleeFromStack(true, 4);
259
+ const timingKey = `${timingKeyPrefix} in ` + utils_default.getResolvedFilename(name, this.app.baseDir);
260
+ this.timing.start(timingKey);
261
+ debug("[registerReadyCallback] start name: %o", name);
262
+ const done = ready.readyCallback(name);
263
+ process.nextTick(async () => {
264
+ try {
265
+ await utils_default.callFn(scope);
266
+ debug("[registerReadyCallback] end name: %o", name);
267
+ done();
268
+ this.timing.end(timingKey);
269
+ } catch (e) {
270
+ let err = e;
271
+ if (!(err instanceof Error)) err = new Error(format("%s", err));
272
+ done(err);
273
+ this.timing.end(timingKey);
274
+ }
275
+ });
276
+ }
277
+ };
278
+
279
+ //#endregion
280
+ export { Lifecycle };