@dangao/bun-server 2.0.8 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -0
- package/dist/controller/controller.d.ts.map +1 -1
- package/dist/core/application.d.ts +6 -1
- package/dist/core/application.d.ts.map +1 -1
- package/dist/core/server.d.ts +5 -0
- package/dist/core/server.d.ts.map +1 -1
- package/dist/database/database-context.d.ts +25 -0
- package/dist/database/database-context.d.ts.map +1 -0
- package/dist/database/database-extension.d.ts +8 -9
- package/dist/database/database-extension.d.ts.map +1 -1
- package/dist/database/database-module.d.ts +7 -1
- package/dist/database/database-module.d.ts.map +1 -1
- package/dist/database/db-proxy.d.ts +12 -0
- package/dist/database/db-proxy.d.ts.map +1 -0
- package/dist/database/index.d.ts +6 -1
- package/dist/database/index.d.ts.map +1 -1
- package/dist/database/orm/transaction-interceptor.d.ts +0 -16
- package/dist/database/orm/transaction-interceptor.d.ts.map +1 -1
- package/dist/database/orm/transaction-manager.d.ts +10 -61
- package/dist/database/orm/transaction-manager.d.ts.map +1 -1
- package/dist/database/service.d.ts.map +1 -1
- package/dist/database/sql-manager.d.ts +14 -0
- package/dist/database/sql-manager.d.ts.map +1 -0
- package/dist/database/sqlite-adapter.d.ts +32 -0
- package/dist/database/sqlite-adapter.d.ts.map +1 -0
- package/dist/database/strategy-decorator.d.ts +8 -0
- package/dist/database/strategy-decorator.d.ts.map +1 -0
- package/dist/database/types.d.ts +122 -1
- package/dist/database/types.d.ts.map +1 -1
- package/dist/di/container.d.ts +16 -0
- package/dist/di/container.d.ts.map +1 -1
- package/dist/di/lifecycle.d.ts +48 -0
- package/dist/di/lifecycle.d.ts.map +1 -1
- package/dist/di/module-registry.d.ts +10 -6
- package/dist/di/module-registry.d.ts.map +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3267 -2620
- package/dist/microservice/service-registry/service-registry-module.d.ts +16 -0
- package/dist/microservice/service-registry/service-registry-module.d.ts.map +1 -1
- package/dist/router/index.d.ts +1 -0
- package/dist/router/index.d.ts.map +1 -1
- package/dist/router/registry.d.ts +1 -1
- package/dist/router/registry.d.ts.map +1 -1
- package/dist/router/route.d.ts +2 -1
- package/dist/router/route.d.ts.map +1 -1
- package/dist/router/router.d.ts +1 -1
- package/dist/router/router.d.ts.map +1 -1
- package/dist/router/timeout-decorator.d.ts +6 -0
- package/dist/router/timeout-decorator.d.ts.map +1 -0
- package/docs/database.md +48 -15
- package/docs/idle-timeout.md +42 -0
- package/docs/lifecycle.md +80 -4
- package/docs/microservice-nacos.md +1 -0
- package/docs/microservice-service-registry.md +7 -0
- package/docs/zh/database.md +48 -15
- package/docs/zh/idle-timeout.md +41 -0
- package/docs/zh/lifecycle.md +49 -5
- package/docs/zh/microservice-nacos.md +1 -0
- package/docs/zh/microservice-service-registry.md +6 -0
- package/package.json +1 -1
- package/src/controller/controller.ts +11 -1
- package/src/core/application.ts +98 -26
- package/src/core/server.ts +10 -0
- package/src/database/database-context.ts +43 -0
- package/src/database/database-extension.ts +12 -45
- package/src/database/database-module.ts +254 -11
- package/src/database/db-proxy.ts +75 -0
- package/src/database/index.ts +29 -0
- package/src/database/orm/transaction-interceptor.ts +12 -149
- package/src/database/orm/transaction-manager.ts +143 -210
- package/src/database/service.ts +28 -2
- package/src/database/sql-manager.ts +62 -0
- package/src/database/sqlite-adapter.ts +121 -0
- package/src/database/strategy-decorator.ts +42 -0
- package/src/database/types.ts +133 -1
- package/src/di/container.ts +55 -1
- package/src/di/lifecycle.ts +114 -0
- package/src/di/module-registry.ts +78 -14
- package/src/index.ts +31 -1
- package/src/microservice/service-registry/service-registry-module.ts +25 -1
- package/src/router/index.ts +1 -0
- package/src/router/registry.ts +10 -1
- package/src/router/route.ts +31 -3
- package/src/router/router.ts +10 -1
- package/src/router/timeout-decorator.ts +35 -0
- package/tests/core/application.test.ts +10 -0
- package/tests/database/database-module.test.ts +91 -430
- package/tests/database/db-proxy.test.ts +93 -0
- package/tests/database/sql-manager.test.ts +43 -0
- package/tests/database/sqlite-adapter.test.ts +45 -0
- package/tests/database/strategy-decorator.test.ts +29 -0
- package/tests/database/transaction.test.ts +84 -222
- package/tests/di/lifecycle.test.ts +139 -1
- package/tests/di/scoped-lifecycle.test.ts +61 -0
- package/tests/microservice/service-registry.test.ts +15 -0
- package/tests/router/timeout-decorator.test.ts +48 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { NacosClientOptions } from '@dangao/nacos-client';
|
|
2
|
+
import { type ServiceInstance } from './types';
|
|
2
3
|
/**
|
|
3
4
|
* 服务注册中心 Provider 类型
|
|
4
5
|
*/
|
|
@@ -34,11 +35,26 @@ export interface ServiceRegistryModuleOptions {
|
|
|
34
35
|
* Nacos 配置(当 provider 为 'nacos' 时使用)
|
|
35
36
|
*/
|
|
36
37
|
nacos?: NacosServiceRegistryOptions;
|
|
38
|
+
/**
|
|
39
|
+
* 是否自动在 Application.listen 时注册带 @ServiceRegistry 的服务
|
|
40
|
+
* @default true
|
|
41
|
+
*/
|
|
42
|
+
autoRegister?: boolean;
|
|
43
|
+
/**
|
|
44
|
+
* 通过模块配置自动注册服务(无需 @ServiceRegistry 装饰器)
|
|
45
|
+
* 当 autoRegister=true 时在 Application.listen 阶段自动注册
|
|
46
|
+
*/
|
|
47
|
+
autoRegisterService?: Omit<ServiceInstance, 'ip' | 'port'> & {
|
|
48
|
+
ip?: string;
|
|
49
|
+
port?: number;
|
|
50
|
+
};
|
|
37
51
|
}
|
|
38
52
|
/**
|
|
39
53
|
* 服务注册中心模块
|
|
40
54
|
*/
|
|
41
55
|
export declare class ServiceRegistryModule {
|
|
56
|
+
static autoRegister: boolean;
|
|
57
|
+
static autoRegisterService: ServiceRegistryModuleOptions['autoRegisterService'];
|
|
42
58
|
/**
|
|
43
59
|
* 创建服务注册中心模块
|
|
44
60
|
* @param options - 模块配置
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service-registry-module.d.ts","sourceRoot":"","sources":["../../../src/microservice/service-registry/service-registry-module.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"service-registry-module.d.ts","sourceRoot":"","sources":["../../../src/microservice/service-registry/service-registry-module.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE/D,OAAO,EAGL,KAAK,eAAe,EACrB,MAAM,SAAS,CAAC;AAEjB;;GAEG;AACH,MAAM,MAAM,uBAAuB,GAAG,OAAO,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAC;AAE7E;;GAEG;AACH,MAAM,WAAW,2BAA2B;IAC1C;;OAEG;IACH,MAAM,EAAE,kBAAkB,CAAC;IAE3B;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;GAEG;AACH,MAAM,WAAW,4BAA4B;IAC3C;;OAEG;IACH,QAAQ,EAAE,uBAAuB,CAAC;IAElC;;OAEG;IACH,KAAK,CAAC,EAAE,2BAA2B,CAAC;IAEpC;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB;;;OAGG;IACH,mBAAmB,CAAC,EAAE,IAAI,CAAC,eAAe,EAAE,IAAI,GAAG,MAAM,CAAC,GAAG;QAC3D,EAAE,CAAC,EAAE,MAAM,CAAC;QACZ,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;CAKH;AAED;;GAEG;AACH,qBAGa,qBAAqB;IAChC,OAAc,YAAY,UAAQ;IAClC,OAAc,mBAAmB,EAAE,4BAA4B,CAAC,qBAAqB,CAAC,CAAC;IAEvF;;;OAGG;WACW,OAAO,CAAC,OAAO,EAAE,4BAA4B,GAAG,OAAO,qBAAqB;CA0C3F"}
|
package/dist/router/index.d.ts
CHANGED
|
@@ -2,5 +2,6 @@ export { Route } from './route';
|
|
|
2
2
|
export { Router } from './router';
|
|
3
3
|
export { RouteRegistry } from './registry';
|
|
4
4
|
export { GET, POST, PUT, DELETE, PATCH } from './decorators';
|
|
5
|
+
export { IdleTimeout, IDLE_TIMEOUT_KEY, getIdleTimeout } from './timeout-decorator';
|
|
5
6
|
export type { HttpMethod, RouteHandler, RouteMatch } from './types';
|
|
6
7
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/router/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAC7D,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/router/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACpF,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC"}
|
|
@@ -24,7 +24,7 @@ export declare class RouteRegistry {
|
|
|
24
24
|
* @param controllerClass - 控制器类(可选)
|
|
25
25
|
* @param methodName - 方法名(可选)
|
|
26
26
|
*/
|
|
27
|
-
register(method: HttpMethod, path: string, handler: RouteHandler, middlewares?: Middleware[], controllerClass?: Constructor<unknown>, methodName?: string): void;
|
|
27
|
+
register(method: HttpMethod, path: string, handler: RouteHandler, middlewares?: Middleware[], controllerClass?: Constructor<unknown>, methodName?: string, timeout?: number): void;
|
|
28
28
|
/**
|
|
29
29
|
* 注册 GET 路由
|
|
30
30
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/router/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACxD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEhD;;;GAGG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAgB;IACvC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAEhC,OAAO;IAIP;;;OAGG;WACW,WAAW,IAAI,aAAa;IAO1C;;;;;;;;OAQG;IACI,QAAQ,CACb,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,YAAY,EACrB,WAAW,GAAE,UAAU,EAAO,EAC9B,eAAe,CAAC,EAAE,WAAW,CAAC,OAAO,CAAC,EACtC,UAAU,CAAC,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/router/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACxD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEhD;;;GAGG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAgB;IACvC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAEhC,OAAO;IAIP;;;OAGG;WACW,WAAW,IAAI,aAAa;IAO1C;;;;;;;;OAQG;IACI,QAAQ,CACb,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,YAAY,EACrB,WAAW,GAAE,UAAU,EAAO,EAC9B,eAAe,CAAC,EAAE,WAAW,CAAC,OAAO,CAAC,EACtC,UAAU,CAAC,EAAE,MAAM,EACnB,OAAO,CAAC,EAAE,MAAM,GACf,IAAI;IAYP;;OAEG;IACI,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,WAAW,GAAE,UAAU,EAAO,GAAG,IAAI;IAIrF;;OAEG;IACI,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,WAAW,GAAE,UAAU,EAAO,GAAG,IAAI;IAItF;;OAEG;IACI,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,WAAW,GAAE,UAAU,EAAO,GAAG,IAAI;IAIrF;;OAEG;IACI,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,WAAW,GAAE,UAAU,EAAO,GAAG,IAAI;IAIxF;;OAEG;IACI,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,WAAW,GAAE,UAAU,EAAO,GAAG,IAAI;IAIvF;;;OAGG;IACI,SAAS,IAAI,MAAM;IAI1B;;OAEG;IACI,KAAK,IAAI,IAAI;CAGrB"}
|
package/dist/router/route.d.ts
CHANGED
|
@@ -38,7 +38,8 @@ export declare class Route {
|
|
|
38
38
|
private readonly middlewarePipeline;
|
|
39
39
|
private readonly staticKey?;
|
|
40
40
|
readonly isStatic: boolean;
|
|
41
|
-
|
|
41
|
+
private readonly timeout?;
|
|
42
|
+
constructor(method: HttpMethod, path: string, handler: RouteHandler, middlewares?: Middleware[], controllerClass?: Constructor<unknown>, methodName?: string, timeout?: number);
|
|
42
43
|
/**
|
|
43
44
|
* 解析路径,生成匹配模式和参数名列表
|
|
44
45
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../src/router/route.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAEpE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../src/router/route.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAEpE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAGhD;;;GAGG;AACH,qBAAa,KAAK;IAChB;;OAEG;IACH,SAAgB,MAAM,EAAE,UAAU,CAAC;IAEnC;;OAEG;IACH,SAAgB,IAAI,EAAE,MAAM,CAAC;IAE7B;;OAEG;IACH,SAAgB,OAAO,EAAE,YAAY,CAAC;IAEtC;;OAEG;IACH,SAAgB,eAAe,CAAC,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;IAEvD;;OAEG;IACH,SAAgB,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpC;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAS;IAElC;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAW;IAEvC,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAA4B;IAC/D,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAS;IACpC,SAAgB,QAAQ,EAAE,OAAO,CAAC;IAClC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAS;gBAGhC,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,YAAY,EACrB,WAAW,GAAE,UAAU,EAAO,EAC9B,eAAe,CAAC,EAAE,WAAW,CAAC,OAAO,CAAC,EACtC,UAAU,CAAC,EAAE,MAAM,EACnB,OAAO,CAAC,EAAE,MAAM;IAoBlB;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,SAAS;IAYxB;;;;;OAKG;IACI,KAAK,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,GAAG,UAAU;IAwB1D;;;;OAIG;IACU,OAAO,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC;IAgCzD;;OAEG;IACI,YAAY,IAAI,MAAM,GAAG,SAAS;CAG1C"}
|
package/dist/router/router.d.ts
CHANGED
|
@@ -32,7 +32,7 @@ export declare class Router {
|
|
|
32
32
|
* @param controllerClass - 控制器类(可选)
|
|
33
33
|
* @param methodName - 方法名(可选)
|
|
34
34
|
*/
|
|
35
|
-
register(method: HttpMethod, path: string, handler: RouteHandler, middlewares?: Middleware[], controllerClass?: Constructor<unknown>, methodName?: string): void;
|
|
35
|
+
register(method: HttpMethod, path: string, handler: RouteHandler, middlewares?: Middleware[], controllerClass?: Constructor<unknown>, methodName?: string, timeout?: number): void;
|
|
36
36
|
/**
|
|
37
37
|
* 注册 GET 路由
|
|
38
38
|
* @param path - 路由路径
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/router/router.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACpE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAGhD;;;GAGG;AACH,qBAAa,MAAM;IACjB;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAe;IACtC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA4B;IACzD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAe;IAE7C;;;OAGG;IACH,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA0D;IAErF;;OAEG;IACH,OAAO,CAAC,aAAa;IAOrB;;;;;;;;OAQG;IACI,QAAQ,CACb,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,YAAY,EACrB,WAAW,GAAE,UAAU,EAAO,EAC9B,eAAe,CAAC,EAAE,WAAW,CAAC,OAAO,CAAC,EACtC,UAAU,CAAC,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/router/router.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACpE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAGhD;;;GAGG;AACH,qBAAa,MAAM;IACjB;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAe;IACtC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA4B;IACzD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAe;IAE7C;;;OAGG;IACH,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA0D;IAErF;;OAEG;IACH,OAAO,CAAC,aAAa;IAOrB;;;;;;;;OAQG;IACI,QAAQ,CACb,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,YAAY,EACrB,WAAW,GAAE,UAAU,EAAO,EAC9B,eAAe,CAAC,EAAE,WAAW,CAAC,OAAO,CAAC,EACtC,UAAU,CAAC,EAAE,MAAM,EACnB,OAAO,CAAC,EAAE,MAAM,GACf,IAAI;IAwBP;;;;OAIG;IACI,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,WAAW,GAAE,UAAU,EAAO,GAAG,IAAI;IAIrF;;;;OAIG;IACI,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,WAAW,GAAE,UAAU,EAAO,GAAG,IAAI;IAItF;;;;OAIG;IACI,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,WAAW,GAAE,UAAU,EAAO,GAAG,IAAI;IAIrF;;;;OAIG;IACI,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,WAAW,GAAE,UAAU,EAAO,GAAG,IAAI;IAIxF;;;;OAIG;IACI,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,WAAW,GAAE,UAAU,EAAO,GAAG,IAAI;IAIvF;;;;;OAKG;IACI,SAAS,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS;IAKrE;;;;;OAKG;IACI,kBAAkB,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,GAAG;QAAE,KAAK,EAAE,KAAK,CAAC;QAAC,KAAK,EAAE,UAAU,CAAA;KAAE,GAAG,SAAS;IAmC5G;;;OAGG;IACU,SAAS,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAgCvD;;;;OAIG;IACU,MAAM,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC;IAmCpE;;;OAGG;IACI,SAAS,IAAI,SAAS,KAAK,EAAE;IAIpC;;OAEG;IACI,KAAK,IAAI,IAAI;CAMrB"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import 'reflect-metadata';
|
|
2
|
+
import type { Constructor } from '../core/types';
|
|
3
|
+
export declare const IDLE_TIMEOUT_KEY: unique symbol;
|
|
4
|
+
export declare function IdleTimeout(ms: number): MethodDecorator & ClassDecorator;
|
|
5
|
+
export declare function getIdleTimeout(controllerClass: Constructor<unknown>, methodName: string): number | undefined;
|
|
6
|
+
//# sourceMappingURL=timeout-decorator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"timeout-decorator.d.ts","sourceRoot":"","sources":["../../src/router/timeout-decorator.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAE1B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjD,eAAO,MAAM,gBAAgB,eAAkD,CAAC;AAEhF,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,eAAe,GAAG,cAAc,CAQxE;AAED,wBAAgB,cAAc,CAC5B,eAAe,EAAE,WAAW,CAAC,OAAO,CAAC,EACrC,UAAU,EAAE,MAAM,GACjB,MAAM,GAAG,SAAS,CAcpB"}
|
package/docs/database.md
CHANGED
|
@@ -1,23 +1,56 @@
|
|
|
1
1
|
# Database
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Database module v2 is built on top of native `Bun.SQL` and adds request-level strategy routing.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## V2 Highlights
|
|
6
6
|
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
7
|
+
- Native Bun.SQL pool passthrough (no custom physical pool implementation)
|
|
8
|
+
- `db` proxy as the preferred query entry (`import { db } from '@dangao/bun-server'`)
|
|
9
|
+
- Route strategy control with `@DbStrategy('pool' | 'session')` and `@DbSession()`
|
|
10
|
+
- Session strategy uses lazy `reserve()` + request ALS context
|
|
11
|
+
- `db.transaction()` and `@Transactional()` are unified through `TransactionManager`
|
|
12
|
+
- SQLite improvements: `WAL` mode and write-concurrency guard
|
|
10
13
|
|
|
11
|
-
##
|
|
14
|
+
## Configuration
|
|
15
|
+
|
|
16
|
+
```ts
|
|
17
|
+
DatabaseModule.forRoot({
|
|
18
|
+
type: 'postgres',
|
|
19
|
+
url: process.env.DB_URL!,
|
|
20
|
+
bunSqlPool: {
|
|
21
|
+
max: 20,
|
|
22
|
+
idleTimeout: 30,
|
|
23
|
+
},
|
|
24
|
+
defaultStrategy: 'pool',
|
|
25
|
+
});
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Route strategy
|
|
12
29
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
- [Testing](./testing.md)
|
|
16
|
-
- [Migration Guide](./migration.md)
|
|
30
|
+
```ts
|
|
31
|
+
import { Controller, GET, POST, db, DbSession } from '@dangao/bun-server';
|
|
17
32
|
|
|
18
|
-
|
|
33
|
+
@Controller('/users')
|
|
34
|
+
class UserController {
|
|
35
|
+
@GET('/')
|
|
36
|
+
public async list() {
|
|
37
|
+
return await db`SELECT * FROM users`;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
@DbSession()
|
|
41
|
+
@POST('/')
|
|
42
|
+
public async create() {
|
|
43
|
+
return await db.transaction(async () => {
|
|
44
|
+
await db`INSERT INTO users (name) VALUES (${'alice'})`;
|
|
45
|
+
await db`UPDATE stats SET user_count = user_count + 1`;
|
|
46
|
+
return { ok: true };
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Recommended Reading
|
|
19
53
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
4. Add health checks and monitor connection pool metrics.
|
|
54
|
+
- [Lifecycle](./lifecycle.md)
|
|
55
|
+
- [idleTimeout](./idle-timeout.md)
|
|
56
|
+
- [Service Registry](./microservice-service-registry.md)
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# idleTimeout
|
|
2
|
+
|
|
3
|
+
`idleTimeout` now supports both global and per-route configuration.
|
|
4
|
+
|
|
5
|
+
## Global idle timeout (milliseconds)
|
|
6
|
+
|
|
7
|
+
Set in `Application` options using milliseconds.
|
|
8
|
+
Framework converts internally before passing to `Bun.serve`.
|
|
9
|
+
|
|
10
|
+
```ts
|
|
11
|
+
const app = new Application({
|
|
12
|
+
port: 3000,
|
|
13
|
+
idleTimeout: 15000, // ms
|
|
14
|
+
});
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Per-route timeout (milliseconds)
|
|
18
|
+
|
|
19
|
+
Use `@IdleTimeout(ms)` on controller class or handler method.
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
import { Controller, GET, IdleTimeout } from '@dangao/bun-server';
|
|
23
|
+
|
|
24
|
+
@Controller('/api')
|
|
25
|
+
@IdleTimeout(5000) // class-level default
|
|
26
|
+
class ApiController {
|
|
27
|
+
@GET('/fast')
|
|
28
|
+
public fast() {
|
|
29
|
+
return { ok: true };
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
@GET('/slow')
|
|
33
|
+
@IdleTimeout(1000) // method-level overrides class-level
|
|
34
|
+
public async slow() {
|
|
35
|
+
await new Promise((resolve) => setTimeout(resolve, 2000));
|
|
36
|
+
return { ok: true };
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
When timeout is reached, Bun Server throws `HttpException(408, "Request Timeout")`.
|
|
42
|
+
|
package/docs/lifecycle.md
CHANGED
|
@@ -1,35 +1,71 @@
|
|
|
1
1
|
# Lifecycle Hooks
|
|
2
2
|
|
|
3
|
-
Bun Server supports lifecycle hooks that let
|
|
3
|
+
Bun Server supports lifecycle hooks that let components (`@Injectable` / `@Controller`) participate from creation to destruction.
|
|
4
4
|
|
|
5
5
|
## Interfaces
|
|
6
6
|
|
|
7
7
|
| Interface | Method | When Called |
|
|
8
8
|
|-----------|--------|-------------|
|
|
9
|
+
| `ComponentClassBeforeCreate` | `static onBeforeCreate()` | Right before the component instance is created |
|
|
10
|
+
| `OnAfterCreate` | `onAfterCreate()` | Right after instance creation and post processors |
|
|
9
11
|
| `OnModuleInit` | `onModuleInit()` | After all module providers are registered |
|
|
10
12
|
| `OnModuleDestroy` | `onModuleDestroy()` | During shutdown (reverse order) |
|
|
13
|
+
| `OnBeforeDestroy` | `onBeforeDestroy()` | Before `onModuleDestroy` during shutdown (reverse order) |
|
|
14
|
+
| `OnAfterDestroy` | `onAfterDestroy()` | After `onModuleDestroy` during shutdown (reverse order) |
|
|
11
15
|
| `OnApplicationBootstrap` | `onApplicationBootstrap()` | After all modules init, before server listens |
|
|
12
16
|
| `OnApplicationShutdown` | `onApplicationShutdown(signal?)` | When graceful shutdown begins |
|
|
13
17
|
|
|
14
18
|
## Execution Order
|
|
15
19
|
|
|
20
|
+
**Creation (per component instance)**: `onBeforeCreate` (static) -> instantiate -> `onAfterCreate`
|
|
21
|
+
|
|
16
22
|
**Startup**: `onModuleInit` (all modules) -> `onApplicationBootstrap` (all modules) -> server starts
|
|
17
23
|
|
|
18
|
-
**Shutdown**: `onApplicationShutdown` (reverse order) -> `onModuleDestroy` (reverse order)
|
|
24
|
+
**Shutdown**: `onApplicationShutdown` (reverse order) -> `onBeforeDestroy` (reverse order) -> `onModuleDestroy` (reverse order) -> `onAfterDestroy` (reverse order)
|
|
25
|
+
|
|
26
|
+
For `Lifecycle.Scoped` components, destroy hooks are executed automatically at the end of each request context.
|
|
27
|
+
|
|
28
|
+
## Provider Deduplication
|
|
29
|
+
|
|
30
|
+
When the same provider instance is exported or registered by multiple tokens,
|
|
31
|
+
`onModuleInit` now runs only once for that instance. This avoids duplicate
|
|
32
|
+
initialization side effects in shared singleton objects.
|
|
19
33
|
|
|
20
|
-
## Example:
|
|
34
|
+
## Example: Component hooks from create to destroy
|
|
21
35
|
|
|
22
36
|
```ts
|
|
23
37
|
import {
|
|
24
38
|
Injectable,
|
|
39
|
+
Controller,
|
|
40
|
+
GET,
|
|
41
|
+
Module,
|
|
25
42
|
OnModuleInit,
|
|
26
43
|
OnModuleDestroy,
|
|
44
|
+
type ComponentClassBeforeCreate,
|
|
45
|
+
OnAfterCreate,
|
|
46
|
+
OnBeforeDestroy,
|
|
47
|
+
OnAfterDestroy,
|
|
27
48
|
} from '@dangao/bun-server';
|
|
28
49
|
|
|
29
50
|
@Injectable()
|
|
30
|
-
class DatabaseService
|
|
51
|
+
class DatabaseService
|
|
52
|
+
implements
|
|
53
|
+
OnAfterCreate,
|
|
54
|
+
OnModuleInit,
|
|
55
|
+
OnBeforeDestroy,
|
|
56
|
+
OnModuleDestroy,
|
|
57
|
+
OnAfterDestroy
|
|
58
|
+
{
|
|
31
59
|
private connected = false;
|
|
32
60
|
|
|
61
|
+
public static onBeforeCreate(): void {
|
|
62
|
+
console.log('[DatabaseService] Before create');
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
public onAfterCreate(): void {
|
|
66
|
+
console.log('[DatabaseService] After create');
|
|
67
|
+
}
|
|
68
|
+
|
|
33
69
|
public async onModuleInit(): Promise<void> {
|
|
34
70
|
console.log('[DatabaseService] Connecting...');
|
|
35
71
|
await this.connect();
|
|
@@ -42,6 +78,14 @@ class DatabaseService implements OnModuleInit, OnModuleDestroy {
|
|
|
42
78
|
this.connected = false;
|
|
43
79
|
}
|
|
44
80
|
|
|
81
|
+
public onBeforeDestroy(): void {
|
|
82
|
+
console.log('[DatabaseService] Before destroy');
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
public onAfterDestroy(): void {
|
|
86
|
+
console.log('[DatabaseService] After destroy');
|
|
87
|
+
}
|
|
88
|
+
|
|
45
89
|
public isConnected(): boolean {
|
|
46
90
|
return this.connected;
|
|
47
91
|
}
|
|
@@ -54,6 +98,36 @@ class DatabaseService implements OnModuleInit, OnModuleDestroy {
|
|
|
54
98
|
// Close DB connection
|
|
55
99
|
}
|
|
56
100
|
}
|
|
101
|
+
|
|
102
|
+
@Controller('/health')
|
|
103
|
+
class HealthController implements OnAfterCreate, OnBeforeDestroy, OnAfterDestroy {
|
|
104
|
+
public static onBeforeCreate(): void {
|
|
105
|
+
console.log('[HealthController] Before create');
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
public onAfterCreate(): void {
|
|
109
|
+
console.log('[HealthController] After create');
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
public onBeforeDestroy(): void {
|
|
113
|
+
console.log('[HealthController] Before destroy');
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
public onAfterDestroy(): void {
|
|
117
|
+
console.log('[HealthController] After destroy');
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
@GET('/')
|
|
121
|
+
public get(): object {
|
|
122
|
+
return { ok: true };
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
@Module({
|
|
127
|
+
controllers: [HealthController],
|
|
128
|
+
providers: [DatabaseService],
|
|
129
|
+
})
|
|
130
|
+
class AppModule {}
|
|
57
131
|
```
|
|
58
132
|
|
|
59
133
|
## Example: Application-level hooks
|
|
@@ -69,4 +143,6 @@ class AppService implements OnApplicationBootstrap, OnApplicationShutdown {
|
|
|
69
143
|
console.log(`Shutting down (signal: ${signal ?? 'none'})`);
|
|
70
144
|
}
|
|
71
145
|
}
|
|
146
|
+
|
|
147
|
+
const _beforeCreateHook: ComponentClassBeforeCreate = DatabaseService;
|
|
72
148
|
```
|
|
@@ -121,6 +121,7 @@ import { ServiceRegistryModule } from '@dangao/bun-server';
|
|
|
121
121
|
app.registerModule(
|
|
122
122
|
ServiceRegistryModule.forRoot({
|
|
123
123
|
provider: 'nacos',
|
|
124
|
+
autoRegister: true, // set false to disable listen-time auto registration
|
|
124
125
|
nacos: {
|
|
125
126
|
client: {
|
|
126
127
|
serverList: ['http://localhost:8848'],
|
|
@@ -35,6 +35,7 @@ const app = new Application();
|
|
|
35
35
|
app.registerModule(
|
|
36
36
|
ServiceRegistryModule.forRoot({
|
|
37
37
|
provider: 'nacos',
|
|
38
|
+
autoRegister: true, // default true
|
|
38
39
|
nacos: {
|
|
39
40
|
client: {
|
|
40
41
|
serverList: ['http://localhost:8848'],
|
|
@@ -48,6 +49,12 @@ app.registerModule(
|
|
|
48
49
|
);
|
|
49
50
|
```
|
|
50
51
|
|
|
52
|
+
### Auto Register Switch
|
|
53
|
+
|
|
54
|
+
`ServiceRegistryModule.forRoot({ autoRegister: false })` disables automatic
|
|
55
|
+
service registration in `Application.listen()`. This is useful when you need
|
|
56
|
+
manual registration timing or custom startup orchestration.
|
|
57
|
+
|
|
51
58
|
### 2. Register Service
|
|
52
59
|
|
|
53
60
|
```typescript
|
package/docs/zh/database.md
CHANGED
|
@@ -1,23 +1,56 @@
|
|
|
1
1
|
# 数据库(Database)
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
数据库模块 V2 基于原生 `Bun.SQL` 实现,并提供请求级连接策略控制。
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## V2 关键能力
|
|
6
6
|
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
7
|
+
- 原生 Bun.SQL 连接池参数透传(不重复造物理连接池)
|
|
8
|
+
- 推荐统一入口:`import { db } from '@dangao/bun-server'`
|
|
9
|
+
- 路由级策略:`@DbStrategy('pool' | 'session')` / `@DbSession()`
|
|
10
|
+
- session 策略:首次查询惰性 `reserve()` + ALS 请求上下文绑定
|
|
11
|
+
- `db.transaction()` 与 `@Transactional()` 统一事务路径
|
|
12
|
+
- SQLite 增强:默认 `WAL` + 写并发保护
|
|
10
13
|
|
|
11
|
-
##
|
|
14
|
+
## 配置示例
|
|
15
|
+
|
|
16
|
+
```ts
|
|
17
|
+
DatabaseModule.forRoot({
|
|
18
|
+
type: 'postgres',
|
|
19
|
+
url: process.env.DB_URL!,
|
|
20
|
+
bunSqlPool: {
|
|
21
|
+
max: 20,
|
|
22
|
+
idleTimeout: 30,
|
|
23
|
+
},
|
|
24
|
+
defaultStrategy: 'pool',
|
|
25
|
+
});
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## 路由策略示例
|
|
12
29
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
- [测试指南](./testing.md)
|
|
16
|
-
- [迁移指南](./migration.md)
|
|
30
|
+
```ts
|
|
31
|
+
import { Controller, GET, POST, db, DbSession } from '@dangao/bun-server';
|
|
17
32
|
|
|
18
|
-
|
|
33
|
+
@Controller('/users')
|
|
34
|
+
class UserController {
|
|
35
|
+
@GET('/')
|
|
36
|
+
public async list() {
|
|
37
|
+
return await db`SELECT * FROM users`;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
@DbSession()
|
|
41
|
+
@POST('/')
|
|
42
|
+
public async create() {
|
|
43
|
+
return await db.transaction(async () => {
|
|
44
|
+
await db`INSERT INTO users (name) VALUES (${'alice'})`;
|
|
45
|
+
await db`UPDATE stats SET user_count = user_count + 1`;
|
|
46
|
+
return { ok: true };
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## 推荐阅读
|
|
19
53
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
4. 配置健康检查并监控连接池指标。
|
|
54
|
+
- [生命周期](./lifecycle.md)
|
|
55
|
+
- [idleTimeout](./idle-timeout.md)
|
|
56
|
+
- [服务注册与发现](./microservice-service-registry.md)
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# idleTimeout
|
|
2
|
+
|
|
3
|
+
`idleTimeout` 现已支持全局与路由级两种配置方式。
|
|
4
|
+
|
|
5
|
+
## 全局 idleTimeout(毫秒)
|
|
6
|
+
|
|
7
|
+
在 `Application` 中直接按毫秒设置,框架内部会转换后传给 `Bun.serve`。
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
const app = new Application({
|
|
11
|
+
port: 3000,
|
|
12
|
+
idleTimeout: 15000, // ms
|
|
13
|
+
});
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## 路由级超时(毫秒)
|
|
17
|
+
|
|
18
|
+
使用 `@IdleTimeout(ms)` 装饰器配置控制器级或方法级超时。
|
|
19
|
+
|
|
20
|
+
```ts
|
|
21
|
+
import { Controller, GET, IdleTimeout } from '@dangao/bun-server';
|
|
22
|
+
|
|
23
|
+
@Controller('/api')
|
|
24
|
+
@IdleTimeout(5000) // 控制器级默认值
|
|
25
|
+
class ApiController {
|
|
26
|
+
@GET('/fast')
|
|
27
|
+
public fast() {
|
|
28
|
+
return { ok: true };
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
@GET('/slow')
|
|
32
|
+
@IdleTimeout(1000) // 方法级优先
|
|
33
|
+
public async slow() {
|
|
34
|
+
await new Promise((resolve) => setTimeout(resolve, 2000));
|
|
35
|
+
return { ok: true };
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
超时后会抛出 `HttpException(408, "Request Timeout")`。
|
|
41
|
+
|
package/docs/zh/lifecycle.md
CHANGED
|
@@ -1,19 +1,31 @@
|
|
|
1
1
|
# 生命周期钩子
|
|
2
2
|
|
|
3
|
-
Bun Server
|
|
3
|
+
Bun Server 支持组件级生命周期钩子,可让 `@Injectable` / `@Controller` 从创建前到销毁后执行自定义逻辑。
|
|
4
4
|
|
|
5
5
|
## 接口定义
|
|
6
6
|
|
|
7
|
-
- **
|
|
8
|
-
- **
|
|
7
|
+
- **ComponentClassBeforeCreate**:`static onBeforeCreate()`,组件实例创建前调用
|
|
8
|
+
- **OnAfterCreate**:`onAfterCreate()`,组件实例创建并完成后处理后调用
|
|
9
|
+
- **OnModuleInit**:`onModuleInit()`,在模块所有组件初始化阶段调用
|
|
9
10
|
- **OnApplicationBootstrap**:`onApplicationBootstrap()`,在所有模块初始化完成后、服务器开始监听前调用
|
|
10
11
|
- **OnApplicationShutdown**:`onApplicationShutdown(signal?)`,在优雅停机开始时调用
|
|
12
|
+
- **OnBeforeDestroy**:`onBeforeDestroy()`,在 `onModuleDestroy()` 前调用(反向顺序)
|
|
13
|
+
- **OnModuleDestroy**:`onModuleDestroy()`,在应用关闭时调用(反向顺序)
|
|
14
|
+
- **OnAfterDestroy**:`onAfterDestroy()`,在 `onModuleDestroy()` 后调用(反向顺序)
|
|
11
15
|
|
|
12
16
|
## 执行顺序
|
|
13
17
|
|
|
18
|
+
**创建阶段(每个组件实例)**:`onBeforeCreate`(静态)→ 实例化 → `onAfterCreate`
|
|
19
|
+
|
|
14
20
|
**启动阶段**:`onModuleInit` → `onApplicationBootstrap`
|
|
15
21
|
|
|
16
|
-
**关闭阶段**:`onApplicationShutdown` → `onModuleDestroy`(均为反向顺序,即后注册的先执行)
|
|
22
|
+
**关闭阶段**:`onApplicationShutdown` → `onBeforeDestroy` → `onModuleDestroy` → `onAfterDestroy`(均为反向顺序,即后注册的先执行)
|
|
23
|
+
|
|
24
|
+
对于 `Lifecycle.Scoped` 组件,请求上下文结束时会自动触发其销毁钩子。
|
|
25
|
+
|
|
26
|
+
## 组件去重行为
|
|
27
|
+
|
|
28
|
+
当同一个组件实例通过多个 token 重复注册/导出时,生命周期钩子只会执行一次,避免共享单例出现重复副作用。
|
|
17
29
|
|
|
18
30
|
## 示例:DatabaseService 的初始化和销毁
|
|
19
31
|
|
|
@@ -36,6 +48,14 @@ import type {
|
|
|
36
48
|
class DatabaseService implements OnModuleInit, OnModuleDestroy {
|
|
37
49
|
private connected = false;
|
|
38
50
|
|
|
51
|
+
public static onBeforeCreate(): void {
|
|
52
|
+
console.log('[DatabaseService] 创建前');
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
public onAfterCreate(): void {
|
|
56
|
+
console.log('[DatabaseService] 创建后');
|
|
57
|
+
}
|
|
58
|
+
|
|
39
59
|
public async onModuleInit(): Promise<void> {
|
|
40
60
|
console.log('[DatabaseService] 正在连接数据库...');
|
|
41
61
|
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
@@ -49,6 +69,14 @@ class DatabaseService implements OnModuleInit, OnModuleDestroy {
|
|
|
49
69
|
console.log('[DatabaseService] 已断开');
|
|
50
70
|
}
|
|
51
71
|
|
|
72
|
+
public onBeforeDestroy(): void {
|
|
73
|
+
console.log('[DatabaseService] 销毁前');
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
public onAfterDestroy(): void {
|
|
77
|
+
console.log('[DatabaseService] 销毁后');
|
|
78
|
+
}
|
|
79
|
+
|
|
52
80
|
public isConnected(): boolean {
|
|
53
81
|
return this.connected;
|
|
54
82
|
}
|
|
@@ -67,6 +95,22 @@ class AppService implements OnApplicationBootstrap, OnApplicationShutdown {
|
|
|
67
95
|
|
|
68
96
|
@Controller('/api')
|
|
69
97
|
class AppController {
|
|
98
|
+
public static onBeforeCreate(): void {
|
|
99
|
+
console.log('[AppController] 创建前');
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
public onAfterCreate(): void {
|
|
103
|
+
console.log('[AppController] 创建后');
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
public onBeforeDestroy(): void {
|
|
107
|
+
console.log('[AppController] 销毁前');
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
public onAfterDestroy(): void {
|
|
111
|
+
console.log('[AppController] 销毁后');
|
|
112
|
+
}
|
|
113
|
+
|
|
70
114
|
@GET('/status')
|
|
71
115
|
public status(): object {
|
|
72
116
|
return { status: 'running', timestamp: Date.now() };
|
|
@@ -84,4 +128,4 @@ app.registerModule(AppModule);
|
|
|
84
128
|
await app.listen();
|
|
85
129
|
```
|
|
86
130
|
|
|
87
|
-
按 Ctrl+C 触发关闭时,将依次执行 `onApplicationShutdown
|
|
131
|
+
按 Ctrl+C 触发关闭时,将依次执行 `onApplicationShutdown`、`onBeforeDestroy`、`onModuleDestroy`、`onAfterDestroy`。
|
|
@@ -121,6 +121,7 @@ import { ServiceRegistryModule } from '@dangao/bun-server';
|
|
|
121
121
|
app.registerModule(
|
|
122
122
|
ServiceRegistryModule.forRoot({
|
|
123
123
|
provider: 'nacos',
|
|
124
|
+
autoRegister: true, // 设为 false 可关闭 listen 阶段自动注册
|
|
124
125
|
nacos: {
|
|
125
126
|
client: {
|
|
126
127
|
serverList: ['http://localhost:8848'],
|
|
@@ -35,6 +35,7 @@ const app = new Application();
|
|
|
35
35
|
app.registerModule(
|
|
36
36
|
ServiceRegistryModule.forRoot({
|
|
37
37
|
provider: 'nacos',
|
|
38
|
+
autoRegister: true, // 默认 true
|
|
38
39
|
nacos: {
|
|
39
40
|
client: {
|
|
40
41
|
serverList: ['http://localhost:8848'],
|
|
@@ -48,6 +49,11 @@ app.registerModule(
|
|
|
48
49
|
);
|
|
49
50
|
```
|
|
50
51
|
|
|
52
|
+
### 自动注册开关
|
|
53
|
+
|
|
54
|
+
通过 `ServiceRegistryModule.forRoot({ autoRegister: false })` 可关闭
|
|
55
|
+
`Application.listen()` 阶段的自动注册,适用于需要手动控制注册时机的场景。
|
|
56
|
+
|
|
51
57
|
### 2. 注册服务
|
|
52
58
|
|
|
53
59
|
```typescript
|