egg 4.1.2-beta.2 → 4.1.2-beta.22

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/README.md CHANGED
@@ -21,14 +21,17 @@
21
21
  Follow the commands listed below.
22
22
 
23
23
  ```bash
24
+ $ corepack enable utoo
24
25
  $ mkdir showcase && cd showcase
25
- $ npm init egg --type=simple # Optionally pnpm create egg --type=simple
26
- $ pnpm install
27
- $ pnpm run dev
26
+ $ ut create egg@beta
27
+ # Or with npm:
28
+ $ npm init egg --type=simple
29
+ $ ut install
30
+ $ ut run dev
28
31
  $ open http://localhost:7001
29
32
  ```
30
33
 
31
- > Node.js >= 20.19.0 required, [supports `require(esm)` by default](https://nodejs.org/en/blog/release/v20.19.0).
34
+ > Node.js >= 22.18.0 required.
32
35
 
33
36
  ## Documentations
34
37
 
package/dist/index.d.ts CHANGED
@@ -14,11 +14,37 @@ import { BaseContextClass } from "./lib/core/base_context_class.js";
14
14
  import Helper from "./app/extend/helper.js";
15
15
  import { SingleModeAgent, SingleModeApplication, StartEggOptions, startEgg } from "./lib/start.js";
16
16
  import { EggConfigFactory, EggPluginFactory, EggPluginMeta, EggPluginOptions, PartialEggConfig, defineConfig, defineConfigFactory, definePluginFactory } from "./lib/define.js";
17
+ import { buildSnapshot, restoreSnapshot } from "./lib/snapshot.js";
17
18
  import { CookieLimitExceedError } from "./lib/error/CookieLimitExceedError.js";
18
19
  import { MessageUnhandledRejectionError } from "./lib/error/MessageUnhandledRejectionError.js";
20
+ import { CreateTransparentProxyOptions, createTransparentProxy } from "./lib/core/utils.js";
19
21
  import { BaseHookClass } from "./lib/core/base_hook_class.js";
20
22
  import { Singleton, SingletonCreateMethod, SingletonOptions } from "@eggjs/core";
21
23
  import { EggLogger, EggLogger as Logger, LoggerLevel } from "egg-logger";
22
24
  import { AccessLevel, Acl, BackgroundTaskHelper, ContextEventBus, ContextProto, Cookies, EggObjectFactory, EggObjectLifecycle, EggProtoImplClass, EggQualifier, EggType, Event, EventBus, EventContext, Events, HTTPBody, HTTPContext, HTTPController, HTTPCookies, HTTPHeaders, HTTPMethod, HTTPMethodEnum, HTTPParam, HTTPParamType, HTTPQueries, HTTPQuery, HTTPRequest, Host, ImplDecorator, IncomingHttpHeaders, Inject, InjectOptional, LifecycleDestroy, LifecycleInit, LifecyclePostConstruct, LifecyclePostInject, LifecyclePreDestroy, LifecyclePreInject, LifecyclePreLoad, MetadataUtil, Middleware, MultiInstanceProto, MultiInstancePrototypeGetObjectsContext, ObjectInfo, ObjectInitType, ObjectInitTypeLike, QualifierImplDecoratorUtil, QualifierUtil, SingletonProto } from "@eggjs/tegg";
23
25
  export * from "@eggjs/cluster";
24
- export { AccessLevel, Acl, Agent, AgentWorkerLoader, AppWorkerLoader, Application, BackgroundTaskHelper, BaseContextClass, BaseHookClass as Boot, ClientErrorResponse, type EggAppConfig as Config, Context, type ContextEventBus, ContextHttpClient, ContextProto, BaseContextClass as Controller, BaseContextClass as Service, BaseContextClass as Subscription, CookieLimitExceedError, Cookies, CustomLoaderConfig, EggAppConfig, EggAppInfo, EggApplicationCore, EggApplicationCoreOptions, EggConfigFactory, EggContext, HttpClient as EggContextHttpClient, HttpClient as EggHttpClient, HttpClient, EggEnvType, type EggLogger, EggLoggerConfig, type EggObjectFactory, type EggObjectLifecycle, EggPlugin, EggPluginFactory, EggPluginItem, EggPluginMeta, EggPluginOptions, type EggProtoImplClass, EggQualifier, EggType, Event, type EventBus, EventContext, type Events, HTTPBody, HTTPContext, HTTPController, HTTPCookies, HTTPHeaders, HTTPMethod, HTTPMethodEnum, HTTPParam, HTTPParamType, HTTPQueries, HTTPQuery, HTTPRequest, Helper, type Helper as IHelper, Host, HttpClientConfig, HttpClientOptions, HttpClientRequestOptions, HttpClientRequestURL, HttpClientResponse, ILifecycleBoot as IBoot, ILifecycleBoot, IController, IEggPluginItem, IService, type ImplDecorator, type IncomingHttpHeaders, Inject, InjectOptional, LifecycleDestroy, LifecycleInit, LifecyclePostConstruct, LifecyclePostInject, LifecyclePreDestroy, LifecyclePreInject, LifecyclePreLoad, type Logger, type LoggerLevel, MessageUnhandledRejectionError, MetadataUtil, Middleware, MiddlewareFunc, MultiInstanceProto, type MultiInstancePrototypeGetObjectsContext, Next, type ObjectInfo, ObjectInitType, type ObjectInitTypeLike, PartialDeep, PartialEggConfig, PowerPartial, QualifierImplDecoratorUtil, QualifierUtil, Request, RequestObjectBody, Response, Router, type SingleModeAgent, type SingleModeApplication, Singleton, type SingletonCreateMethod, type SingletonOptions, SingletonProto, StartEggOptions, defineConfig, defineConfigFactory, definePluginFactory, startEgg as start, startEgg };
26
+
27
+ //#region src/index.d.ts
28
+ declare const Config: typeof EggAppConfig;
29
+ /**
30
+ * Egg Application Config, can be injected into Proto, e.g. SingletonProto/ContextProto/HttpController.
31
+ *
32
+ * Usage:
33
+ * ```ts
34
+ * import { Inject, Config } from 'egg';
35
+ *
36
+ * @SingletonProto()
37
+ * class FooService {
38
+ * @Inject()
39
+ * config: Config;
40
+ *
41
+ * async bar() {
42
+ * console.log(this.config.env);
43
+ * }
44
+ * }
45
+ * ```
46
+ * @since 4.1.0
47
+ */
48
+ type Config = EggAppConfig;
49
+ //#endregion
50
+ export { AccessLevel, Acl, Agent, AgentWorkerLoader, AppWorkerLoader, Application, BackgroundTaskHelper, BaseContextClass, BaseHookClass as Boot, ClientErrorResponse, Config, Context, type ContextEventBus, ContextHttpClient, ContextProto, BaseContextClass as Controller, BaseContextClass as Service, BaseContextClass as Subscription, CookieLimitExceedError, Cookies, type CreateTransparentProxyOptions, CustomLoaderConfig, EggAppConfig, EggAppInfo, EggApplicationCore, EggApplicationCoreOptions, EggConfigFactory, EggContext, HttpClient as EggContextHttpClient, HttpClient as EggHttpClient, HttpClient, EggEnvType, type EggLogger, EggLoggerConfig, type EggObjectFactory, type EggObjectLifecycle, EggPlugin, EggPluginFactory, EggPluginItem, EggPluginMeta, EggPluginOptions, type EggProtoImplClass, EggQualifier, EggType, Event, type EventBus, EventContext, type Events, HTTPBody, HTTPContext, HTTPController, HTTPCookies, HTTPHeaders, HTTPMethod, HTTPMethodEnum, HTTPParam, HTTPParamType, HTTPQueries, HTTPQuery, HTTPRequest, Helper, type Helper as IHelper, Host, HttpClientConfig, HttpClientOptions, HttpClientRequestOptions, HttpClientRequestURL, HttpClientResponse, ILifecycleBoot as IBoot, ILifecycleBoot, IController, IEggPluginItem, IService, type ImplDecorator, type IncomingHttpHeaders, Inject, InjectOptional, LifecycleDestroy, LifecycleInit, LifecyclePostConstruct, LifecyclePostInject, LifecyclePreDestroy, LifecyclePreInject, LifecyclePreLoad, Logger, type LoggerLevel, MessageUnhandledRejectionError, MetadataUtil, Middleware, MiddlewareFunc, MultiInstanceProto, type MultiInstancePrototypeGetObjectsContext, Next, type ObjectInfo, ObjectInitType, type ObjectInitTypeLike, PartialDeep, PartialEggConfig, PowerPartial, QualifierImplDecoratorUtil, QualifierUtil, Request, RequestObjectBody, Response, Router, type SingleModeAgent, type SingleModeApplication, Singleton, type SingletonCreateMethod, type SingletonOptions, SingletonProto, StartEggOptions, buildSnapshot, createTransparentProxy, defineConfig, defineConfigFactory, definePluginFactory, restoreSnapshot, startEgg as start, startEgg };
package/dist/index.js CHANGED
@@ -8,18 +8,25 @@ import { ContextHttpClient } from "./lib/core/context_httpclient.js";
8
8
  import { HttpClient } from "./lib/core/httpclient.js";
9
9
  import { CookieLimitExceedError } from "./lib/error/CookieLimitExceedError.js";
10
10
  import { MessageUnhandledRejectionError } from "./lib/error/MessageUnhandledRejectionError.js";
11
+ import { createTransparentProxy } from "./lib/core/utils.js";
11
12
  import { EggApplicationCore, Router } from "./lib/egg.js";
12
13
  import { AppWorkerLoader } from "./lib/loader/AppWorkerLoader.js";
13
14
  import { AgentWorkerLoader } from "./lib/loader/AgentWorkerLoader.js";
14
15
  import "./lib/loader/index.js";
15
16
  import { Agent } from "./lib/agent.js";
16
17
  import { Application } from "./lib/application.js";
17
- import "./lib/types.js";
18
+ import { EggAppConfig } from "./lib/types.js";
18
19
  import { startEgg } from "./lib/start.js";
19
20
  import { defineConfig, defineConfigFactory, definePluginFactory } from "./lib/define.js";
21
+ import { buildSnapshot, restoreSnapshot } from "./lib/snapshot.js";
20
22
  import { Singleton } from "@eggjs/core";
23
+ import { EggLogger as Logger } from "egg-logger";
21
24
  import { AccessLevel, Acl, BackgroundTaskHelper, ContextProto, Cookies, EggQualifier, EggType, Event, EventContext, HTTPBody, HTTPContext, HTTPController, HTTPCookies, HTTPHeaders, HTTPMethod, HTTPMethodEnum, HTTPParam, HTTPParamType, HTTPQueries, HTTPQuery, HTTPRequest, Host, Inject, InjectOptional, LifecycleDestroy, LifecycleInit, LifecyclePostConstruct, LifecyclePostInject, LifecyclePreDestroy, LifecyclePreInject, LifecyclePreLoad, MetadataUtil, Middleware, MultiInstanceProto, ObjectInitType, QualifierImplDecoratorUtil, QualifierUtil, SingletonProto } from "@eggjs/tegg";
22
25
 
23
26
  export * from "@eggjs/cluster"
24
27
 
25
- export { AccessLevel, Acl, Agent, AgentWorkerLoader, AppWorkerLoader, Application, BackgroundTaskHelper, BaseContextClass, BaseHookClass as Boot, Context, ContextHttpClient, ContextProto, BaseContextClass as Controller, BaseContextClass as Service, BaseContextClass as Subscription, CookieLimitExceedError, Cookies, EggApplicationCore, EggQualifier, EggType, Event, EventContext, HTTPBody, HTTPContext, HTTPController, HTTPCookies, HTTPHeaders, HTTPMethod, HTTPMethodEnum, HTTPParam, HTTPParamType, HTTPQueries, HTTPQuery, HTTPRequest, Helper, Host, HttpClient, Inject, InjectOptional, LifecycleDestroy, LifecycleInit, LifecyclePostConstruct, LifecyclePostInject, LifecyclePreDestroy, LifecyclePreInject, LifecyclePreLoad, MessageUnhandledRejectionError, MetadataUtil, Middleware, MultiInstanceProto, ObjectInitType, QualifierImplDecoratorUtil, QualifierUtil, Request, Response, Router, Singleton, SingletonProto, defineConfig, defineConfigFactory, definePluginFactory, startEgg as start, startEgg };
28
+ //#region src/index.ts
29
+ const Config = EggAppConfig;
30
+
31
+ //#endregion
32
+ export { AccessLevel, Acl, Agent, AgentWorkerLoader, AppWorkerLoader, Application, BackgroundTaskHelper, BaseContextClass, BaseHookClass as Boot, Config, Context, ContextHttpClient, ContextProto, BaseContextClass as Controller, BaseContextClass as Service, BaseContextClass as Subscription, CookieLimitExceedError, Cookies, EggAppConfig, EggApplicationCore, EggQualifier, EggType, Event, EventContext, HTTPBody, HTTPContext, HTTPController, HTTPCookies, HTTPHeaders, HTTPMethod, HTTPMethodEnum, HTTPParam, HTTPParamType, HTTPQueries, HTTPQuery, HTTPRequest, Helper, Host, HttpClient, Inject, InjectOptional, LifecycleDestroy, LifecycleInit, LifecyclePostConstruct, LifecyclePostInject, LifecyclePreDestroy, LifecyclePreInject, LifecyclePreLoad, Logger, MessageUnhandledRejectionError, MetadataUtil, Middleware, MultiInstanceProto, ObjectInitType, QualifierImplDecoratorUtil, QualifierUtil, Request, Response, Router, Singleton, SingletonProto, buildSnapshot, createTransparentProxy, defineConfig, defineConfigFactory, definePluginFactory, restoreSnapshot, startEgg as start, startEgg };
@@ -15,6 +15,12 @@ declare class Agent extends EggApplicationCore {
15
15
  * @param {Object} options - see {@link EggApplicationCore}
16
16
  */
17
17
  constructor(options?: Omit<EggApplicationCoreOptions, "type">);
18
+ /**
19
+ * Start the keepalive timer that prevents the agent process from exiting
20
+ * when it has no pending I/O. Called from configDidLoad so that the timer
21
+ * is not created during snapshot build (configDidLoad is skipped in snapshot mode).
22
+ */
23
+ protected startKeepAlive(): void;
18
24
  protected customEggLoader(): typeof AgentWorkerLoader;
19
25
  _wrapMessenger(): void;
20
26
  close(): Promise<void>;
package/dist/lib/agent.js CHANGED
@@ -18,6 +18,15 @@ var Agent = class extends EggApplicationCore {
18
18
  ...options,
19
19
  type: "agent"
20
20
  });
21
+ this.lifecycle.addBootHook({ configDidLoad: () => this.startKeepAlive() });
22
+ }
23
+ /**
24
+ * Start the keepalive timer that prevents the agent process from exiting
25
+ * when it has no pending I/O. Called from configDidLoad so that the timer
26
+ * is not created during snapshot build (configDidLoad is skipped in snapshot mode).
27
+ */
28
+ startKeepAlive() {
29
+ if (this.#agentAliveHandler) return;
21
30
  this.#agentAliveHandler = setInterval(() => {
22
31
  this.coreLogger.info("[]");
23
32
  }, 1440 * 60 * 1e3);
@@ -46,7 +55,10 @@ var Agent = class extends EggApplicationCore {
46
55
  }
47
56
  }
48
57
  async close() {
49
- clearInterval(this.#agentAliveHandler);
58
+ if (this.#agentAliveHandler) {
59
+ clearInterval(this.#agentAliveHandler);
60
+ this.#agentAliveHandler = void 0;
61
+ }
50
62
  await super.close();
51
63
  }
52
64
  };
@@ -17,6 +17,10 @@ var HttpClient = class extends HttpClient$1 {
17
17
  };
18
18
  super(initOptions);
19
19
  this.#app = app;
20
+ if (config.interceptors?.length) {
21
+ const originalDispatcher = this.getDispatcher();
22
+ this.setDispatcher(originalDispatcher.compose(...config.interceptors));
23
+ }
20
24
  }
21
25
  async request(url, options) {
22
26
  options = options ?? {};
@@ -1,5 +1,30 @@
1
1
  //#region src/lib/core/utils.d.ts
2
2
  declare function convertObject(obj: any, ignore?: string | RegExp | (string | RegExp)[]): any;
3
3
  declare function safeParseURL(url: string): URL | null;
4
+ interface CreateTransparentProxyOptions<T> {
5
+ /**
6
+ * Factory function to lazily create the real object.
7
+ * Called at most once, on first property access.
8
+ */
9
+ createReal: () => T;
10
+ /**
11
+ * Whether to bind functions from the real object to the real instance.
12
+ * Defaults to true.
13
+ */
14
+ bindFunctions?: boolean;
15
+ }
16
+ /**
17
+ * Create a Proxy that behaves like the real object, but remains transparent to
18
+ * monkeypatch libraries (e.g. defineProperty-based overrides like egg-mock's `mm()`).
19
+ *
20
+ * - Lazily creates the real object on first access.
21
+ * - Allows overriding properties on the proxy target (overlay) — e.g. via `Object.defineProperty`.
22
+ * - Delegates everything else to the real object.
23
+ *
24
+ * This is used to defer HttpClient construction so plugins can modify
25
+ * `config.httpclient.lookup` after the first access to `app.httpClient` but
26
+ * before any actual HTTP request is made.
27
+ */
28
+ declare function createTransparentProxy<T extends object>(options: CreateTransparentProxyOptions<T>): T;
4
29
  //#endregion
5
- export { convertObject, safeParseURL };
30
+ export { CreateTransparentProxyOptions, convertObject, createTransparentProxy, safeParseURL };
@@ -43,6 +43,76 @@ function safeParseURL(url) {
43
43
  return null;
44
44
  }
45
45
  }
46
+ /**
47
+ * Create a Proxy that behaves like the real object, but remains transparent to
48
+ * monkeypatch libraries (e.g. defineProperty-based overrides like egg-mock's `mm()`).
49
+ *
50
+ * - Lazily creates the real object on first access.
51
+ * - Allows overriding properties on the proxy target (overlay) — e.g. via `Object.defineProperty`.
52
+ * - Delegates everything else to the real object.
53
+ *
54
+ * This is used to defer HttpClient construction so plugins can modify
55
+ * `config.httpclient.lookup` after the first access to `app.httpClient` but
56
+ * before any actual HTTP request is made.
57
+ */
58
+ function createTransparentProxy(options) {
59
+ const { createReal, bindFunctions = true } = options;
60
+ if (typeof createReal !== "function") throw new TypeError("createReal must be a function");
61
+ let real;
62
+ let cachedError;
63
+ const boundFnCache = /* @__PURE__ */ new WeakMap();
64
+ const getReal = () => {
65
+ if (real) return real;
66
+ if (cachedError) throw cachedError;
67
+ try {
68
+ return real = createReal();
69
+ } catch (err) {
70
+ cachedError = err;
71
+ throw err;
72
+ }
73
+ };
74
+ const hasOwn = (obj, prop) => Reflect.getOwnPropertyDescriptor(obj, prop) !== void 0;
75
+ return new Proxy({}, {
76
+ get(target, prop, receiver) {
77
+ const r = getReal();
78
+ if (hasOwn(target, prop)) return Reflect.get(target, prop, receiver);
79
+ const value = Reflect.get(r, prop);
80
+ if (bindFunctions && typeof value === "function") {
81
+ let bound = boundFnCache.get(value);
82
+ if (!bound) {
83
+ bound = value.bind(r);
84
+ boundFnCache.set(value, bound);
85
+ }
86
+ return bound;
87
+ }
88
+ return value;
89
+ },
90
+ set(target, prop, value) {
91
+ const r = getReal();
92
+ if (hasOwn(target, prop)) return Reflect.set(target, prop, value);
93
+ return Reflect.set(r, prop, value);
94
+ },
95
+ has(target, prop) {
96
+ return Reflect.has(target, prop) || Reflect.has(getReal(), prop);
97
+ },
98
+ ownKeys(target) {
99
+ return [...new Set([...Reflect.ownKeys(getReal()), ...Reflect.ownKeys(target)])];
100
+ },
101
+ getOwnPropertyDescriptor(target, prop) {
102
+ return Reflect.getOwnPropertyDescriptor(target, prop) ?? Reflect.getOwnPropertyDescriptor(getReal(), prop);
103
+ },
104
+ deleteProperty(target, prop) {
105
+ if (hasOwn(target, prop)) return Reflect.deleteProperty(target, prop);
106
+ return Reflect.deleteProperty(getReal(), prop);
107
+ },
108
+ getPrototypeOf() {
109
+ return Reflect.getPrototypeOf(getReal());
110
+ },
111
+ defineProperty(target, prop, descriptor) {
112
+ return Reflect.defineProperty(target, prop, descriptor);
113
+ }
114
+ });
115
+ }
46
116
 
47
117
  //#endregion
48
- export { convertObject, safeParseURL };
118
+ export { convertObject, createTransparentProxy, safeParseURL };
package/dist/lib/egg.d.ts CHANGED
@@ -82,6 +82,12 @@ declare class EggApplicationCore extends EggCore {
82
82
  */
83
83
  Boot: typeof BaseHookClass;
84
84
  options: Required<EggApplicationCoreOptions>;
85
+ /**
86
+ * Promise that resolves when the `load()` method has finished.
87
+ * This is useful for callers that need to ensure config and metadata
88
+ * are fully loaded before proceeding.
89
+ */
90
+ readonly loadFinished: Promise<void>;
85
91
  readonly messenger: IMessenger;
86
92
  agent?: Agent;
87
93
  application?: Application;
@@ -194,6 +200,13 @@ declare class EggApplicationCore extends EggCore {
194
200
  createHttpClient(options?: HttpClientOptions): HttpClient;
195
201
  /**
196
202
  * HttpClient instance
203
+ *
204
+ * Returns a transparent proxy that defers actual HttpClient construction
205
+ * until a method/property is first accessed. This allows plugins to modify
206
+ * `config.httpclient.lookup` or other options during lifecycle hooks
207
+ * (e.g. `configWillLoad`, `didLoad`) even after `app.httpClient` is
208
+ * first referenced.
209
+ *
197
210
  * @see https://github.com/node-modules/urllib
198
211
  * @member {HttpClient}
199
212
  */
@@ -231,6 +244,27 @@ declare class EggApplicationCore extends EggCore {
231
244
  get coreLogger(): EggLogger;
232
245
  _unhandledRejectionHandler(err: any): void;
233
246
  /**
247
+ * Clean up non-serializable resources before V8 heap serialization.
248
+ * Closes messenger (IPC listeners), logger streams and flush timers
249
+ * (file descriptors), and removes the process-level unhandledRejection
250
+ * listener.
251
+ *
252
+ * The `EggLoggers` instance is intentionally kept (not discarded): plugins
253
+ * such as `@eggjs/schedule` capture individual logger references during the
254
+ * load phase, before serialization. Replacing them with a fresh `EggLoggers`
255
+ * on restore would leave those captured references pointing at closed
256
+ * streams (`... log stream had been closed`). Instead, `snapshotDidDeserialize`
257
+ * reopens these same logger objects in place.
258
+ */
259
+ protected snapshotWillSerialize(): void;
260
+ /**
261
+ * Restore non-serializable resources after V8 heap deserialization.
262
+ * Recreates messenger, re-registers the egg-ready listener, reopens the
263
+ * logger streams closed during serialize, and re-attaches the process-level
264
+ * unhandledRejection listener.
265
+ */
266
+ protected snapshotDidDeserialize(): void;
267
+ /**
234
268
  * dump out the config and meta object
235
269
  * @private
236
270
  */
@@ -244,6 +278,11 @@ declare class EggApplicationCore extends EggCore {
244
278
  */
245
279
  dumpConfig(): void;
246
280
  dumpTiming(): void;
281
+ /**
282
+ * Generate and save startup manifest for faster subsequent startups.
283
+ * Only generates when no valid manifest was loaded (avoids overwriting during manifest-accelerated starts).
284
+ */
285
+ dumpManifest(): void;
247
286
  protected customEggPaths(): string[];
248
287
  get config(): EggAppConfig$1;
249
288
  /**
package/dist/lib/egg.js CHANGED
@@ -7,9 +7,9 @@ import { ContextHttpClient } from "./core/context_httpclient.js";
7
7
  import { HttpClient } from "./core/httpclient.js";
8
8
  import { createLoggers } from "./core/logger.js";
9
9
  import { create } from "./core/messenger/index.js";
10
- import { convertObject } from "./core/utils.js";
10
+ import { convertObject, createTransparentProxy } from "./core/utils.js";
11
11
  import assert from "node:assert";
12
- import { EggCore, Router, utils } from "@eggjs/core";
12
+ import { EggCore, ManifestStore, Router, utils } from "@eggjs/core";
13
13
  import path from "node:path";
14
14
  import fs from "node:fs";
15
15
  import http from "node:http";
@@ -79,7 +79,16 @@ var EggApplicationCore = class extends EggCore {
79
79
  Boot = BaseHookClass;
80
80
  #httpClient;
81
81
  #loggers;
82
+ #startTimeoutTimer;
82
83
  #clusterClients = [];
84
+ #loadFinishedResolve;
85
+ #loadFinishedReject;
86
+ /**
87
+ * Promise that resolves when the `load()` method has finished.
88
+ * This is useful for callers that need to ensure config and metadata
89
+ * are fully loaded before proceeding.
90
+ */
91
+ loadFinished;
83
92
  messenger;
84
93
  agent;
85
94
  application;
@@ -99,6 +108,10 @@ var EggApplicationCore = class extends EggCore {
99
108
  ...options
100
109
  };
101
110
  super(options);
111
+ this.loadFinished = new Promise((resolve, reject) => {
112
+ this.#loadFinishedResolve = resolve;
113
+ this.#loadFinishedReject = reject;
114
+ });
102
115
  /**
103
116
  * messenger instance
104
117
  * @member {Messenger}
@@ -108,8 +121,18 @@ var EggApplicationCore = class extends EggCore {
108
121
  this.messenger.once("egg-ready", () => {
109
122
  this.lifecycle.triggerServerDidReady();
110
123
  });
124
+ this.lifecycle.addBootHook({
125
+ snapshotWillSerialize: () => this.snapshotWillSerialize(),
126
+ snapshotDidDeserialize: () => this.snapshotDidDeserialize()
127
+ });
111
128
  this.lifecycle.registerBeforeStart(async () => {
112
- await this.load();
129
+ try {
130
+ await this.load();
131
+ this.#loadFinishedResolve();
132
+ } catch (err) {
133
+ this.#loadFinishedReject(err);
134
+ throw err;
135
+ }
113
136
  }, "load files");
114
137
  }
115
138
  /**
@@ -123,27 +146,38 @@ var EggApplicationCore = class extends EggCore {
123
146
  }
124
147
  async load() {
125
148
  await this.loadConfig();
126
- this.ready(() => process.nextTick(() => {
127
- const dumpStartTime = Date.now();
128
- this.dumpConfig();
129
- this.dumpTiming();
130
- this.coreLogger.info("[egg] dump config after ready, %sms", Date.now() - dumpStartTime);
131
- }));
132
- this.#setupTimeoutTimer();
149
+ if (!this.options.snapshot) {
150
+ this.ready(() => process.nextTick(() => {
151
+ const dumpStartTime = Date.now();
152
+ this.dumpConfig();
153
+ this.dumpTiming();
154
+ this.dumpManifest();
155
+ ManifestStore.flushCompileCache();
156
+ this.coreLogger.info("[egg] dump config after ready, %sms", Date.now() - dumpStartTime);
157
+ }));
158
+ this.#setupTimeoutTimer();
159
+ }
133
160
  this.console.info("[egg] App root: %s", this.baseDir);
134
161
  this.console.info("[egg] All *.log files save on %j", this.config.logger.dir);
135
162
  assert(this.config.logger.dir, "logger.dir is required");
136
163
  this.console.info("[egg] Loaded enabled plugin %j", this.loader.orderPlugins);
137
164
  this._unhandledRejectionHandler = this._unhandledRejectionHandler.bind(this);
138
165
  process.on("unhandledRejection", this._unhandledRejectionHandler);
139
- this.lifecycle.registerBeforeClose(async () => {
166
+ if (!this.lifecycle.registerBeforeClose(async () => {
140
167
  for (const clusterClient of this.#clusterClients) await close(clusterClient);
141
168
  this.#clusterClients = [];
142
- if (this.type === "application" && this.options.mode === "single") await this.agent.close();
169
+ if (this.type === "application" && this.options.mode === "single") await this.agent?.close();
170
+ ManifestStore.flushCompileCache();
143
171
  for (const logger of this.loggers.values()) logger.close();
144
172
  this.messenger.close();
145
173
  process.removeListener("unhandledRejection", this._unhandledRejectionHandler);
146
- });
174
+ })) {
175
+ this.#clearStartTimeoutTimer();
176
+ process.removeListener("unhandledRejection", this._unhandledRejectionHandler);
177
+ this.messenger.close();
178
+ if (this.#loggers) for (const logger of this.#loggers.values()) logger.close();
179
+ return;
180
+ }
147
181
  await this.loader.load();
148
182
  }
149
183
  /**
@@ -282,11 +316,18 @@ var EggApplicationCore = class extends EggCore {
282
316
  }
283
317
  /**
284
318
  * HttpClient instance
319
+ *
320
+ * Returns a transparent proxy that defers actual HttpClient construction
321
+ * until a method/property is first accessed. This allows plugins to modify
322
+ * `config.httpclient.lookup` or other options during lifecycle hooks
323
+ * (e.g. `configWillLoad`, `didLoad`) even after `app.httpClient` is
324
+ * first referenced.
325
+ *
285
326
  * @see https://github.com/node-modules/urllib
286
327
  * @member {HttpClient}
287
328
  */
288
329
  get httpClient() {
289
- if (!this.#httpClient) this.#httpClient = this.createHttpClient();
330
+ if (!this.#httpClient) this.#httpClient = createTransparentProxy({ createReal: () => this.createHttpClient() });
290
331
  return this.#httpClient;
291
332
  }
292
333
  /**
@@ -346,6 +387,56 @@ var EggApplicationCore = class extends EggCore {
346
387
  this.coreLogger.error(err);
347
388
  }
348
389
  /**
390
+ * Clean up non-serializable resources before V8 heap serialization.
391
+ * Closes messenger (IPC listeners), logger streams and flush timers
392
+ * (file descriptors), and removes the process-level unhandledRejection
393
+ * listener.
394
+ *
395
+ * The `EggLoggers` instance is intentionally kept (not discarded): plugins
396
+ * such as `@eggjs/schedule` capture individual logger references during the
397
+ * load phase, before serialization. Replacing them with a fresh `EggLoggers`
398
+ * on restore would leave those captured references pointing at closed
399
+ * streams (`... log stream had been closed`). Instead, `snapshotDidDeserialize`
400
+ * reopens these same logger objects in place.
401
+ */
402
+ snapshotWillSerialize() {
403
+ this.messenger.close();
404
+ if (this.#loggers) for (const logger of this.#loggers.values()) logger.close();
405
+ process.removeListener("unhandledRejection", this._unhandledRejectionHandler);
406
+ }
407
+ /**
408
+ * Restore non-serializable resources after V8 heap deserialization.
409
+ * Recreates messenger, re-registers the egg-ready listener, reopens the
410
+ * logger streams closed during serialize, and re-attaches the process-level
411
+ * unhandledRejection listener.
412
+ */
413
+ snapshotDidDeserialize() {
414
+ this.messenger = create(this);
415
+ this.messenger.once("egg-ready", () => {
416
+ this.lifecycle.triggerServerDidReady();
417
+ });
418
+ this.#reopenLoggers();
419
+ process.on("unhandledRejection", this._unhandledRejectionHandler);
420
+ }
421
+ /**
422
+ * Reopen logger resources that `snapshotWillSerialize` released.
423
+ *
424
+ * `transport.reload()` reopens each `FileTransport` stream on the existing
425
+ * logger objects (so references captured before the snapshot keep working).
426
+ * `FileBufferTransport`, however, clears its flush interval in `close()` and
427
+ * does not restart it in `reload()`, so buffered logs would never flush after
428
+ * restore. Restart that interval explicitly to keep the willSerialize /
429
+ * didDeserialize resource pairing complete.
430
+ */
431
+ #reopenLoggers() {
432
+ if (!this.#loggers) return;
433
+ for (const logger of this.#loggers.values()) for (const transport of logger.values()) {
434
+ transport.reload();
435
+ const bufferTransport = transport;
436
+ if (typeof bufferTransport._createInterval === "function" && !bufferTransport._timer) bufferTransport._timer = bufferTransport._createInterval();
437
+ }
438
+ }
439
+ /**
349
440
  * dump out the config and meta object
350
441
  * @private
351
442
  */
@@ -397,11 +488,40 @@ var EggApplicationCore = class extends EggCore {
397
488
  this.coreLogger.warn(`[egg] dumpTiming error: ${err.message}`);
398
489
  }
399
490
  }
491
+ /**
492
+ * Generate and save startup manifest for faster subsequent startups.
493
+ * Only generates when no valid manifest was loaded (avoids overwriting during manifest-accelerated starts).
494
+ */
495
+ dumpManifest() {
496
+ try {
497
+ if (this.loader.serverEnv === "local" && process.env.EGG_MANIFEST !== "true") return;
498
+ if (this.loader.manifest.data.generatedAt) return;
499
+ const manifest = this.loader.generateManifest();
500
+ ManifestStore.enableCompileCache(this.baseDir);
501
+ ManifestStore.write(this.baseDir, manifest).catch((err) => {
502
+ this.coreLogger.warn("[egg] dumpManifest write error: %s", err.message);
503
+ });
504
+ } catch (err) {
505
+ this.coreLogger.warn("[egg] dumpManifest error: %s", err.message);
506
+ }
507
+ }
400
508
  customEggPaths() {
509
+ const bundleStore = ManifestStore.getBundleStore();
510
+ if (bundleStore && path.resolve(bundleStore.baseDir) === path.resolve(this.baseDir)) {
511
+ const bundledFrameworkDir = path.join(bundleStore.baseDir, "node_modules", "egg", "dist");
512
+ const importMetaRewritten = !!import.meta.dirname && path.resolve(import.meta.dirname) === path.resolve(bundleStore.baseDir);
513
+ if (fs.existsSync(bundledFrameworkDir) || importMetaRewritten) return [bundledFrameworkDir, ...super.customEggPaths()];
514
+ }
401
515
  return [path.dirname(import.meta.dirname), ...super.customEggPaths()];
402
516
  }
517
+ #clearStartTimeoutTimer() {
518
+ if (this.#startTimeoutTimer) {
519
+ clearTimeout(this.#startTimeoutTimer);
520
+ this.#startTimeoutTimer = void 0;
521
+ }
522
+ }
403
523
  #setupTimeoutTimer() {
404
- const startTimeoutTimer = setTimeout(() => {
524
+ this.#startTimeoutTimer = setTimeout(() => {
405
525
  this.coreLogger.error(this.timing.toString());
406
526
  this.coreLogger.error(`${this.type} still doesn't ready after ${this.config.workerStartTimeout} ms.`);
407
527
  const items = this.timing.toJSON();
@@ -414,7 +534,7 @@ var EggApplicationCore = class extends EggCore {
414
534
  this.dumpConfig();
415
535
  this.dumpTiming();
416
536
  }, this.config.workerStartTimeout);
417
- this.ready(() => clearTimeout(startTimeoutTimer));
537
+ this.ready(() => this.#clearStartTimeoutTimer());
418
538
  }
419
539
  get config() {
420
540
  return super.config;
@@ -29,7 +29,7 @@ var AppWorkerLoader = class extends EggApplicationLoader {
29
29
  await this.loadService();
30
30
  await this.loadMiddleware();
31
31
  await this.loadController();
32
- await this.loadRouter();
32
+ if (!this.options.metadataOnly) await this.loadRouter();
33
33
  }
34
34
  };
35
35
 
@@ -0,0 +1,46 @@
1
+ import { Application } from "./application.js";
2
+ import { StartEggOptions } from "./start.js";
3
+
4
+ //#region src/lib/snapshot.d.ts
5
+
6
+ /**
7
+ * Build a V8 startup snapshot of an egg application.
8
+ *
9
+ * Call this from the snapshot entry script passed to
10
+ * `node --snapshot-blob=snapshot.blob --build-snapshot snapshot_entry.js`.
11
+ *
12
+ * It loads all metadata (plugins, configs, extensions, services, controllers,
13
+ * router, tegg modules), triggers snapshotWillSerialize hooks to clean up
14
+ * non-serializable resources (file handles, timers, process listeners),
15
+ * then registers a V8 deserialize callback to stash the app for later restore.
16
+ *
17
+ * Example snapshot entry script:
18
+ * ```ts
19
+ * import { buildSnapshot } from 'egg';
20
+ * await buildSnapshot({ baseDir: __dirname });
21
+ * ```
22
+ *
23
+ * Example restoring from snapshot:
24
+ * ```ts
25
+ * import { restoreSnapshot } from 'egg';
26
+ * const app = await restoreSnapshot();
27
+ * // app is fully restored with resources recreated, ready for server creation
28
+ * ```
29
+ */
30
+ declare function buildSnapshot(options?: Pick<StartEggOptions, "framework" | "baseDir" | "env" | "plugins">): Promise<void>;
31
+ /**
32
+ * Restore an egg application from a V8 startup snapshot.
33
+ *
34
+ * Triggers the snapshotDidDeserialize lifecycle hooks to recreate
35
+ * non-serializable resources (messenger, loggers, process listeners)
36
+ * and resumes the lifecycle from configDidLoad through didReady.
37
+ *
38
+ * Returns the fully restored Application instance with all metadata
39
+ * pre-loaded (plugins, configs, extensions, services, controllers, router).
40
+ */
41
+ declare function restoreSnapshot(): Promise<Application>;
42
+ declare global {
43
+ var __egg_snapshot_app: unknown;
44
+ }
45
+ //#endregion
46
+ export { buildSnapshot, restoreSnapshot };
@@ -0,0 +1,59 @@
1
+ import { startEgg } from "./start.js";
2
+ import v8 from "node:v8";
3
+
4
+ //#region src/lib/snapshot.ts
5
+ /**
6
+ * Build a V8 startup snapshot of an egg application.
7
+ *
8
+ * Call this from the snapshot entry script passed to
9
+ * `node --snapshot-blob=snapshot.blob --build-snapshot snapshot_entry.js`.
10
+ *
11
+ * It loads all metadata (plugins, configs, extensions, services, controllers,
12
+ * router, tegg modules), triggers snapshotWillSerialize hooks to clean up
13
+ * non-serializable resources (file handles, timers, process listeners),
14
+ * then registers a V8 deserialize callback to stash the app for later restore.
15
+ *
16
+ * Example snapshot entry script:
17
+ * ```ts
18
+ * import { buildSnapshot } from 'egg';
19
+ * await buildSnapshot({ baseDir: __dirname });
20
+ * ```
21
+ *
22
+ * Example restoring from snapshot:
23
+ * ```ts
24
+ * import { restoreSnapshot } from 'egg';
25
+ * const app = await restoreSnapshot();
26
+ * // app is fully restored with resources recreated, ready for server creation
27
+ * ```
28
+ */
29
+ async function buildSnapshot(options = {}) {
30
+ const app = await startEgg({
31
+ ...options,
32
+ snapshot: true
33
+ });
34
+ if (app.agent) await app.agent.triggerSnapshotWillSerialize();
35
+ await app.triggerSnapshotWillSerialize();
36
+ v8.startupSnapshot.setDeserializeMainFunction((snapshotData) => {
37
+ globalThis.__egg_snapshot_app = snapshotData.app;
38
+ }, { app });
39
+ }
40
+ /**
41
+ * Restore an egg application from a V8 startup snapshot.
42
+ *
43
+ * Triggers the snapshotDidDeserialize lifecycle hooks to recreate
44
+ * non-serializable resources (messenger, loggers, process listeners)
45
+ * and resumes the lifecycle from configDidLoad through didReady.
46
+ *
47
+ * Returns the fully restored Application instance with all metadata
48
+ * pre-loaded (plugins, configs, extensions, services, controllers, router).
49
+ */
50
+ async function restoreSnapshot() {
51
+ const app = globalThis.__egg_snapshot_app;
52
+ if (!app) throw new Error("No egg application found in snapshot. Ensure the process was started from a snapshot built with buildSnapshot().");
53
+ if (app.agent) await app.agent.triggerSnapshotDidDeserialize();
54
+ await app.triggerSnapshotDidDeserialize();
55
+ return app;
56
+ }
57
+
58
+ //#endregion
59
+ export { buildSnapshot, restoreSnapshot };
@@ -1,6 +1,7 @@
1
1
  import { EggPlugin } from "./types.js";
2
2
  import { Agent } from "./agent.js";
3
3
  import { Application } from "./application.js";
4
+ import { LoaderFS } from "@eggjs/core";
4
5
 
5
6
  //#region src/lib/start.d.ts
6
7
  interface StartEggOptions {
@@ -13,6 +14,16 @@ interface StartEggOptions {
13
14
  mode?: "single";
14
15
  env?: string;
15
16
  plugins?: EggPlugin;
17
+ /** Skip lifecycle hooks, only trigger loadMetadata for manifest generation */
18
+ metadataOnly?: boolean;
19
+ /** Loader-facing filesystem abstraction */
20
+ loaderFS?: LoaderFS;
21
+ /**
22
+ * When true, load application metadata for V8 startup snapshot construction.
23
+ * The lifecycle stops after configWillLoad (no servers, timers, or connections)
24
+ * and skips `egg-ready` broadcast. `ready()` resolves when loading completes.
25
+ */
26
+ snapshot?: boolean;
16
27
  }
17
28
  interface SingleModeApplication extends Application {
18
29
  agent: SingleModeAgent;
@@ -21,7 +32,11 @@ interface SingleModeAgent extends Agent {
21
32
  app: SingleModeApplication;
22
33
  }
23
34
  /**
24
- * Start egg with single process
35
+ * Start egg with single process.
36
+ *
37
+ * When `options.snapshot` is true, loads application metadata for V8 startup
38
+ * snapshot construction. The lifecycle stops after `configWillLoad` (no servers,
39
+ * timers, or connections) and skips `egg-ready` broadcast.
25
40
  */
26
41
  declare function startEgg(options?: StartEggOptions): Promise<SingleModeApplication>;
27
42
  //#endregion
package/dist/lib/start.js CHANGED
@@ -1,17 +1,13 @@
1
1
  import { Agent } from "./agent.js";
2
2
  import { Application } from "./application.js";
3
3
  import "./types.js";
4
+ import { ManifestStore } from "@eggjs/core";
4
5
  import path from "node:path";
5
6
  import { importModule } from "@eggjs/utils";
6
7
  import { readJSON } from "utility";
7
8
 
8
9
  //#region src/lib/start.ts
9
- /**
10
- * Start egg with single process
11
- */
12
- async function startEgg(options = {}) {
13
- options.baseDir = options.baseDir ?? process.cwd();
14
- options.mode = "single";
10
+ async function resolveFrameworkClasses(options) {
15
11
  if (!options.framework) try {
16
12
  options.framework = (await readJSON(path.join(options.baseDir, "package.json"))).egg.framework;
17
13
  } catch {}
@@ -22,13 +18,35 @@ async function startEgg(options = {}) {
22
18
  AgentClass = framework.Agent;
23
19
  ApplicationClass = framework.Application;
24
20
  }
25
- const agent = new AgentClass({ ...options });
26
- await agent.ready();
21
+ return {
22
+ AgentClass,
23
+ ApplicationClass
24
+ };
25
+ }
26
+ /**
27
+ * Start egg with single process.
28
+ *
29
+ * When `options.snapshot` is true, loads application metadata for V8 startup
30
+ * snapshot construction. The lifecycle stops after `configWillLoad` (no servers,
31
+ * timers, or connections) and skips `egg-ready` broadcast.
32
+ */
33
+ async function startEgg(options = {}) {
34
+ options.baseDir = options.baseDir ?? process.cwd();
35
+ options.mode = "single";
36
+ if (!options.snapshot) ManifestStore.enableCompileCache(options.baseDir);
37
+ const { AgentClass, ApplicationClass } = await resolveFrameworkClasses(options);
38
+ let agent;
39
+ if (!options.metadataOnly) {
40
+ agent = new AgentClass({ ...options });
41
+ await agent.ready();
42
+ }
27
43
  const application = new ApplicationClass({ ...options });
28
- application.agent = agent;
29
- agent.application = application;
44
+ if (agent) {
45
+ application.agent = agent;
46
+ agent.application = application;
47
+ }
30
48
  await application.ready();
31
- application.messenger.broadcast("egg-ready");
49
+ if (!options.metadataOnly && !options.snapshot) application.messenger.broadcast("egg-ready");
32
50
  return application;
33
51
  }
34
52
 
@@ -7,7 +7,7 @@ import "./egg.js";
7
7
  import { Application } from "./application.js";
8
8
  import { EggAppConfig as EggAppConfig$1, EggAppInfo, FileLoaderOptions } from "@eggjs/core";
9
9
  import { EggLoggerOptions, EggLoggersOptions } from "egg-logger";
10
- import { RequestOptions } from "urllib";
10
+ import { Dispatcher, RequestOptions } from "urllib";
11
11
  import { LookupFunction, Socket } from "node:net";
12
12
  import { PartialDeep } from "type-fest";
13
13
 
@@ -61,6 +61,24 @@ interface HttpClientConfig {
61
61
  */
62
62
  allowH2?: boolean;
63
63
  lookup?: LookupFunction;
64
+ /**
65
+ * Interceptors for request composition, applied via `Dispatcher.compose()`.
66
+ * Each interceptor receives a `dispatch` function and returns a new `dispatch` function.
67
+ *
68
+ * @example
69
+ * ```ts
70
+ * // config.default.ts
71
+ * config.httpclient = {
72
+ * interceptors: [
73
+ * (dispatch) => (opts, handler) => {
74
+ * opts.headers = { ...opts.headers, 'x-trace-id': generateTraceId() };
75
+ * return dispatch(opts, handler);
76
+ * },
77
+ * ],
78
+ * };
79
+ * ```
80
+ */
81
+ interceptors?: Dispatcher.DispatcherComposeInterceptor[];
64
82
  }
65
83
  /**
66
84
  * Powerful Partial, Support adding ? modifier to a mapped property in deep level
@@ -73,6 +91,7 @@ interface HttpClientConfig {
73
91
  * @deprecated use `PartialDeep` instead
74
92
  */
75
93
  type PowerPartial<T> = PartialDeep<T>;
94
+ declare const EggAppConfig: ObjectConstructor;
76
95
  interface EggAppConfig extends EggAppConfig$1 {
77
96
  workerStartTimeout: number;
78
97
  baseDir: string;
package/dist/lib/types.js CHANGED
@@ -1,3 +1,7 @@
1
1
  import "./types.plugin.js";
2
2
 
3
- export { };
3
+ //#region src/lib/types.ts
4
+ const EggAppConfig = Object;
5
+
6
+ //#endregion
7
+ export { EggAppConfig };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "egg",
3
- "version": "4.1.2-beta.2",
3
+ "version": "4.1.2-beta.22",
4
4
  "description": "A web application framework for Node.js",
5
5
  "keywords": [
6
6
  "app",
@@ -70,6 +70,7 @@
70
70
  "./lib/loader/AgentWorkerLoader": "./dist/lib/loader/AgentWorkerLoader.js",
71
71
  "./lib/loader/AppWorkerLoader": "./dist/lib/loader/AppWorkerLoader.js",
72
72
  "./lib/loader/EggApplicationLoader": "./dist/lib/loader/EggApplicationLoader.js",
73
+ "./lib/snapshot": "./dist/lib/snapshot.js",
73
74
  "./lib/start": "./dist/lib/start.js",
74
75
  "./lib/types": "./dist/lib/types.js",
75
76
  "./lib/types.plugin": "./dist/lib/types.plugin.js",
@@ -81,9 +82,94 @@
81
82
  },
82
83
  "publishConfig": {
83
84
  "access": "public",
85
+ "exports": {
86
+ ".": "./dist/index.js",
87
+ "./agent": "./dist/agent.js",
88
+ "./ajv": "./dist/ajv.js",
89
+ "./aop": "./dist/aop.js",
90
+ "./app/extend/context": "./dist/app/extend/context.js",
91
+ "./app/extend/helper": "./dist/app/extend/helper.js",
92
+ "./app/extend/request": "./dist/app/extend/request.js",
93
+ "./app/extend/response": "./dist/app/extend/response.js",
94
+ "./app/middleware/body_parser": "./dist/app/middleware/body_parser.js",
95
+ "./app/middleware/meta": "./dist/app/middleware/meta.js",
96
+ "./app/middleware/notfound": "./dist/app/middleware/notfound.js",
97
+ "./app/middleware/override_method": "./dist/app/middleware/override_method.js",
98
+ "./app/middleware/site_file": "./dist/app/middleware/site_file.js",
99
+ "./config/config.default": "./dist/config/config.default.js",
100
+ "./config/config.local": "./dist/config/config.local.js",
101
+ "./config/config.unittest": "./dist/config/config.unittest.js",
102
+ "./config/plugin": "./dist/config/plugin.js",
103
+ "./dal": "./dist/dal.js",
104
+ "./errors": "./dist/errors.js",
105
+ "./helper": "./dist/helper.js",
106
+ "./lib/agent": "./dist/lib/agent.js",
107
+ "./lib/application": "./dist/lib/application.js",
108
+ "./lib/core/base_context_class": "./dist/lib/core/base_context_class.js",
109
+ "./lib/core/base_context_logger": "./dist/lib/core/base_context_logger.js",
110
+ "./lib/core/base_hook_class": "./dist/lib/core/base_hook_class.js",
111
+ "./lib/core/context_httpclient": "./dist/lib/core/context_httpclient.js",
112
+ "./lib/core/httpclient": "./dist/lib/core/httpclient.js",
113
+ "./lib/core/logger": "./dist/lib/core/logger.js",
114
+ "./lib/core/messenger": "./dist/lib/core/messenger/index.js",
115
+ "./lib/core/messenger/base": "./dist/lib/core/messenger/base.js",
116
+ "./lib/core/messenger/IMessenger": "./dist/lib/core/messenger/IMessenger.js",
117
+ "./lib/core/messenger/ipc": "./dist/lib/core/messenger/ipc.js",
118
+ "./lib/core/messenger/local": "./dist/lib/core/messenger/local.js",
119
+ "./lib/core/utils": "./dist/lib/core/utils.js",
120
+ "./lib/define": "./dist/lib/define.js",
121
+ "./lib/egg": "./dist/lib/egg.js",
122
+ "./lib/error": "./dist/lib/error/index.js",
123
+ "./lib/error/CookieLimitExceedError": "./dist/lib/error/CookieLimitExceedError.js",
124
+ "./lib/error/MessageUnhandledRejectionError": "./dist/lib/error/MessageUnhandledRejectionError.js",
125
+ "./lib/loader": "./dist/lib/loader/index.js",
126
+ "./lib/loader/AgentWorkerLoader": "./dist/lib/loader/AgentWorkerLoader.js",
127
+ "./lib/loader/AppWorkerLoader": "./dist/lib/loader/AppWorkerLoader.js",
128
+ "./lib/loader/EggApplicationLoader": "./dist/lib/loader/EggApplicationLoader.js",
129
+ "./lib/snapshot": "./dist/lib/snapshot.js",
130
+ "./lib/start": "./dist/lib/start.js",
131
+ "./lib/types": "./dist/lib/types.js",
132
+ "./lib/types.plugin": "./dist/lib/types.plugin.js",
133
+ "./orm": "./dist/orm.js",
134
+ "./schedule": "./dist/schedule.js",
135
+ "./transaction": "./dist/transaction.js",
136
+ "./urllib": "./dist/urllib.js",
137
+ "./package.json": "./package.json"
138
+ },
84
139
  "tag": "beta"
85
140
  },
141
+ "scripts": {
142
+ "typecheck": "tsgo --noEmit"
143
+ },
86
144
  "dependencies": {
145
+ "@eggjs/ajv-plugin": "4.0.2-beta.22",
146
+ "@eggjs/aop-plugin": "4.0.2-beta.22",
147
+ "@eggjs/cluster": "4.0.2-beta.22",
148
+ "@eggjs/controller-plugin": "4.0.2-beta.22",
149
+ "@eggjs/cookies": "4.0.2-beta.22",
150
+ "@eggjs/core": "7.0.2-beta.22",
151
+ "@eggjs/dal-plugin": "4.0.2-beta.22",
152
+ "@eggjs/development": "5.0.2-beta.22",
153
+ "@eggjs/errors": "3.0.2-beta.22",
154
+ "@eggjs/eventbus-plugin": "4.0.2-beta.22",
155
+ "@eggjs/extend2": "5.0.2-beta.22",
156
+ "@eggjs/i18n": "4.0.2-beta.22",
157
+ "@eggjs/jsonp": "4.0.2-beta.22",
158
+ "@eggjs/logrotator": "5.0.2-beta.22",
159
+ "@eggjs/multipart": "5.0.2-beta.22",
160
+ "@eggjs/onerror": "4.0.2-beta.22",
161
+ "@eggjs/orm-plugin": "4.0.2-beta.22",
162
+ "@eggjs/schedule": "6.0.2-beta.22",
163
+ "@eggjs/schedule-plugin": "4.0.2-beta.22",
164
+ "@eggjs/security": "5.0.2-beta.22",
165
+ "@eggjs/session": "5.0.2-beta.22",
166
+ "@eggjs/static": "4.0.2-beta.22",
167
+ "@eggjs/tegg": "4.0.2-beta.22",
168
+ "@eggjs/tegg-config": "4.0.2-beta.22",
169
+ "@eggjs/tegg-plugin": "4.0.2-beta.22",
170
+ "@eggjs/utils": "5.0.2-beta.22",
171
+ "@eggjs/view": "4.0.2-beta.22",
172
+ "@eggjs/watcher": "5.0.2-beta.22",
87
173
  "circular-json-for-egg": "^1.0.0",
88
174
  "cluster-client": "^3.7.0",
89
175
  "egg-logger": "^3.5.0",
@@ -97,37 +183,13 @@
97
183
  "sendmessage": "^3.0.1",
98
184
  "type-fest": "^5.0.1",
99
185
  "urllib": "^4.8.2",
100
- "utility": "^2.5.0",
101
- "@eggjs/ajv-plugin": "4.0.2-beta.2",
102
- "@eggjs/cluster": "4.0.2-beta.2",
103
- "@eggjs/aop-plugin": "4.0.2-beta.2",
104
- "@eggjs/controller-plugin": "4.0.2-beta.2",
105
- "@eggjs/core": "7.0.2-beta.2",
106
- "@eggjs/cookies": "4.0.2-beta.2",
107
- "@eggjs/dal-plugin": "4.0.2-beta.2",
108
- "@eggjs/development": "5.0.2-beta.2",
109
- "@eggjs/errors": "3.0.2-beta.2",
110
- "@eggjs/eventbus-plugin": "4.0.2-beta.2",
111
- "@eggjs/i18n": "4.0.2-beta.2",
112
- "@eggjs/extend2": "5.0.2-beta.2",
113
- "@eggjs/jsonp": "4.0.2-beta.2",
114
- "@eggjs/logrotator": "5.0.2-beta.2",
115
- "@eggjs/multipart": "5.0.2-beta.2",
116
- "@eggjs/onerror": "4.0.2-beta.2",
117
- "@eggjs/orm-plugin": "4.0.2-beta.2",
118
- "@eggjs/schedule": "6.0.2-beta.2",
119
- "@eggjs/schedule-plugin": "4.0.2-beta.2",
120
- "@eggjs/security": "5.0.2-beta.2",
121
- "@eggjs/session": "5.0.2-beta.2",
122
- "@eggjs/static": "4.0.2-beta.2",
123
- "@eggjs/tegg-config": "4.0.2-beta.2",
124
- "@eggjs/tegg-plugin": "4.0.2-beta.2",
125
- "@eggjs/utils": "5.0.2-beta.2",
126
- "@eggjs/view": "4.0.2-beta.2",
127
- "@eggjs/tegg": "4.0.2-beta.2",
128
- "@eggjs/watcher": "5.0.2-beta.2"
186
+ "utility": "^2.5.0"
129
187
  },
130
188
  "devDependencies": {
189
+ "@eggjs/koa": "3.1.2-beta.22",
190
+ "@eggjs/mock": "7.0.2-beta.22",
191
+ "@eggjs/supertest": "9.0.2-beta.22",
192
+ "@eggjs/tracer": "4.0.2-beta.22",
131
193
  "@types/koa-bodyparser": "^4.3.12",
132
194
  "address": "2",
133
195
  "assert-file": "1",
@@ -140,19 +202,12 @@
140
202
  "runscript": "^2.0.1",
141
203
  "sdk-base": "^5.0.1",
142
204
  "spy": "^1.0.0",
143
- "typescript": "^5.9.3",
144
- "@eggjs/koa": "3.1.2-beta.2",
145
- "@eggjs/supertest": "9.0.2-beta.2",
146
- "@eggjs/tracer": "4.0.2-beta.2",
147
- "@eggjs/mock": "7.0.2-beta.2"
205
+ "typescript": "^5.9.3"
148
206
  },
149
207
  "engines": {
150
208
  "node": ">=22.18.0"
151
209
  },
152
210
  "egg": {
153
211
  "framework": true
154
- },
155
- "scripts": {
156
- "typecheck": "tsgo --noEmit"
157
212
  }
158
- }
213
+ }