@zerooneit/expressive-tea 1.3.0-beta.5 → 2.0.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.
Files changed (77) hide show
  1. package/.gitattributes +4 -0
  2. package/.swcrc +61 -0
  3. package/README.md +564 -174
  4. package/classes/Boot.d.ts +94 -3
  5. package/classes/Boot.js +171 -51
  6. package/classes/Engine.d.ts +59 -10
  7. package/classes/Engine.js +72 -11
  8. package/classes/EngineRegistry.d.ts +154 -0
  9. package/classes/EngineRegistry.js +247 -0
  10. package/classes/LoadBalancer.js +2 -5
  11. package/classes/ProxyRoute.d.ts +3 -3
  12. package/classes/ProxyRoute.js +5 -5
  13. package/classes/Settings.d.ts +31 -2
  14. package/classes/Settings.js +64 -11
  15. package/decorators/annotations.d.ts +1 -1
  16. package/decorators/annotations.js +17 -17
  17. package/decorators/env.d.ts +145 -0
  18. package/decorators/env.js +177 -0
  19. package/decorators/health.d.ts +115 -0
  20. package/decorators/health.js +124 -0
  21. package/decorators/module.d.ts +15 -15
  22. package/decorators/module.js +14 -23
  23. package/decorators/proxy.d.ts +26 -11
  24. package/decorators/proxy.js +35 -45
  25. package/decorators/router.d.ts +17 -16
  26. package/decorators/router.js +32 -52
  27. package/decorators/server.d.ts +8 -8
  28. package/decorators/server.js +48 -50
  29. package/engines/health/index.d.ts +120 -0
  30. package/engines/health/index.js +179 -0
  31. package/engines/http/index.d.ts +6 -7
  32. package/engines/http/index.js +22 -17
  33. package/engines/index.d.ts +32 -0
  34. package/engines/index.js +112 -0
  35. package/engines/socketio/index.d.ts +2 -1
  36. package/engines/socketio/index.js +16 -6
  37. package/engines/teacup/index.d.ts +13 -0
  38. package/engines/teacup/index.js +61 -11
  39. package/engines/teapot/index.d.ts +15 -2
  40. package/engines/teapot/index.js +61 -13
  41. package/engines/websocket/index.d.ts +4 -1
  42. package/engines/websocket/index.js +10 -2
  43. package/eslint.config.mjs +138 -0
  44. package/exceptions/RequestExceptions.d.ts +3 -3
  45. package/helpers/boot-helper.d.ts +6 -6
  46. package/helpers/boot-helper.js +30 -24
  47. package/helpers/decorators.js +7 -6
  48. package/helpers/promise-helper.d.ts +1 -1
  49. package/helpers/promise-helper.js +1 -2
  50. package/helpers/server.d.ts +32 -6
  51. package/helpers/server.js +101 -61
  52. package/helpers/teapot-helper.d.ts +5 -8
  53. package/helpers/teapot-helper.js +39 -11
  54. package/helpers/websocket-helper.d.ts +3 -5
  55. package/helpers/websocket-helper.js +3 -3
  56. package/interfaces/index.d.ts +1 -1
  57. package/inversify.config.d.ts +4 -4
  58. package/inversify.config.js +1 -1
  59. package/libs/utilities.d.ts +21910 -0
  60. package/libs/utilities.js +420 -0
  61. package/mixins/module.d.ts +45 -0
  62. package/mixins/module.js +71 -0
  63. package/mixins/proxy.d.ts +46 -0
  64. package/mixins/proxy.js +86 -0
  65. package/mixins/route.d.ts +48 -0
  66. package/mixins/route.js +96 -0
  67. package/package.json +91 -69
  68. package/services/DependencyInjection.d.ts +95 -7
  69. package/services/DependencyInjection.js +123 -5
  70. package/services/WebsocketService.d.ts +4 -6
  71. package/services/WebsocketService.js +5 -3
  72. package/types/core.d.ts +14 -0
  73. package/types/core.js +2 -0
  74. package/types/injection-types.d.ts +6 -0
  75. package/types/injection-types.js +10 -0
  76. package/types/inversify.d.ts +5 -0
  77. package/types/inversify.js +3 -0
package/classes/Boot.d.ts CHANGED
@@ -1,7 +1,8 @@
1
1
  import 'reflect-metadata';
2
- import { Express } from 'express';
3
- import { ExpressiveTeaApplication } from '@expressive-tea/commons/interfaces';
4
- import Settings from '../classes/Settings';
2
+ import { type Express } from 'express';
3
+ import { type ExpressiveTeaApplication } from '@expressive-tea/commons';
4
+ import Settings from './Settings';
5
+ import { Container, type Newable, type ServiceIdentifier } from 'inversify';
5
6
  /**
6
7
  * Expressive Tea Application interface is the response from an started application, contains the express application
7
8
  * and a node http server instance.
@@ -36,12 +37,79 @@ declare abstract class Boot {
36
37
  * @summary Express Application instance internal property.
37
38
  */
38
39
  private readonly server;
40
+ private readonly containerDI;
41
+ /**
42
+ * Engine instances for cleanup during shutdown
43
+ * @type {ExpressiveTeaEngine[]}
44
+ * @private
45
+ * @since 2.0.0
46
+ */
47
+ private engines;
39
48
  constructor();
40
49
  /**
41
50
  * Get Express Application
42
51
  * @returns Express
43
52
  */
44
53
  getApplication(): Express;
54
+ /**
55
+ * Get the Dependency Injection container for this application instance.
56
+ * This container is scoped to the application and inherits from the global container.
57
+ *
58
+ * @returns {Container} The application's DI container
59
+ * @since 2.0.0
60
+ * @summary Get application DI container
61
+ *
62
+ * @example
63
+ * class MyApp extends Boot {
64
+ * async start() {
65
+ * const container = this.getContainer();
66
+ * container.bind(MyService).toSelf();
67
+ * return super.start();
68
+ * }
69
+ * }
70
+ */
71
+ getContainer(): Container;
72
+ /**
73
+ * Register a provider in the application's DI container.
74
+ * Providers registered here are available to all modules and engines in this application.
75
+ *
76
+ * @template T
77
+ * @param {ServiceIdentifier<T>} identifier - The service identifier (class or token)
78
+ * @param {Newable<T>} provider - The provider class to bind
79
+ * @returns {void}
80
+ * @since 2.0.0
81
+ * @summary Register a DI provider
82
+ *
83
+ * @example
84
+ * class MyApp extends Boot {
85
+ * constructor() {
86
+ * super();
87
+ * this.registerProvider(DatabaseService, DatabaseService);
88
+ * this.registerProvider('API_KEY', ApiKeyProvider);
89
+ * }
90
+ * }
91
+ */
92
+ registerProvider<T>(identifier: ServiceIdentifier<T>, provider: Newable<T>): void;
93
+ /**
94
+ * Register a constant value in the application's DI container.
95
+ *
96
+ * @template T
97
+ * @param {ServiceIdentifier<T>} identifier - The service identifier (usually a string or symbol)
98
+ * @param {T} value - The constant value to bind
99
+ * @returns {void}
100
+ * @since 2.0.0
101
+ * @summary Register a constant value
102
+ *
103
+ * @example
104
+ * class MyApp extends Boot {
105
+ * constructor() {
106
+ * super();
107
+ * this.registerConstant('DATABASE_URL', process.env.DATABASE_URL);
108
+ * this.registerConstant('MAX_CONNECTIONS', 100);
109
+ * }
110
+ * }
111
+ */
112
+ registerConstant<T>(identifier: ServiceIdentifier<T>, value: T): void;
45
113
  /**
46
114
  * Bootstrap and verify that all the required plugins are correctly configured and proceed to attach all the
47
115
  * registered modules. <b>Remember</b> this is the unique method that must be decorated for the Register Module
@@ -50,5 +118,28 @@ declare abstract class Boot {
50
118
  * @returns {Promise<ExpressiveTeaApplication>}
51
119
  */
52
120
  start(): Promise<ExpressiveTeaApplication>;
121
+ /**
122
+ * Gracefully stop the application and all engines
123
+ *
124
+ * Calls the stop() lifecycle method on all registered engines in reverse order
125
+ * (opposite of initialization order) to ensure proper cleanup.
126
+ *
127
+ * @returns {Promise<void>} Promise that resolves when all engines have stopped
128
+ * @since 2.0.0
129
+ * @summary Graceful shutdown
130
+ *
131
+ * @example
132
+ * ```typescript
133
+ * const app = new MyApp();
134
+ * await app.start();
135
+ *
136
+ * // Later, during shutdown
137
+ * await app.stop();
138
+ * ```
139
+ */
140
+ stop(): Promise<void>;
141
+ private initializeEngines;
142
+ private initializeHttp;
143
+ private initializeContainer;
53
144
  }
54
145
  export default Boot;
package/classes/Boot.js CHANGED
@@ -2,21 +2,15 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  require("reflect-metadata");
4
4
  const inversify_config_1 = require("../inversify.config");
5
- // tslint:disable-next-line:no-duplicate-imports
6
5
  const express = require("express");
7
- const constants_1 = require("@expressive-tea/commons/constants");
8
- const Metadata_1 = require("@expressive-tea/commons/classes/Metadata");
9
- const object_helper_1 = require("@expressive-tea/commons/helpers/object-helper");
10
- const http_1 = require("../engines/http");
11
- const websocket_1 = require("../engines/websocket");
12
- const index_1 = require("../engines/teapot/index");
13
- const teacup_1 = require("../engines/teacup");
14
- const Engine_1 = require("../classes/Engine");
15
- const Settings_1 = require("../classes/Settings");
16
- const index_2 = require("../engines/socketio/index");
17
- const fs = require("fs");
18
- const http = require("http");
19
- const https = require("https");
6
+ const Engine_1 = require("./Engine");
7
+ const Settings_1 = require("./Settings");
8
+ const fs = require("node:fs");
9
+ const http = require("node:http");
10
+ const https = require("node:https");
11
+ const inversify_1 = require("inversify");
12
+ const injection_types_1 = require("../types/injection-types");
13
+ const EngineRegistry_1 = require("./EngineRegistry");
20
14
  /**
21
15
  * Expressive Tea Application interface is the response from an started application, contains the express application
22
16
  * and a node http server instance.
@@ -43,6 +37,14 @@ class Boot {
43
37
  * @summary Express Application instance internal property.
44
38
  */
45
39
  this.server = express();
40
+ this.containerDI = new inversify_1.Container({ parent: inversify_config_1.default });
41
+ /**
42
+ * Engine instances for cleanup during shutdown
43
+ * @type {ExpressiveTeaEngine[]}
44
+ * @private
45
+ * @since 2.0.0
46
+ */
47
+ this.engines = [];
46
48
  this.settings = Settings_1.default.getInstance(this);
47
49
  }
48
50
  /**
@@ -52,6 +54,75 @@ class Boot {
52
54
  getApplication() {
53
55
  return this.server;
54
56
  }
57
+ /**
58
+ * Get the Dependency Injection container for this application instance.
59
+ * This container is scoped to the application and inherits from the global container.
60
+ *
61
+ * @returns {Container} The application's DI container
62
+ * @since 2.0.0
63
+ * @summary Get application DI container
64
+ *
65
+ * @example
66
+ * class MyApp extends Boot {
67
+ * async start() {
68
+ * const container = this.getContainer();
69
+ * container.bind(MyService).toSelf();
70
+ * return super.start();
71
+ * }
72
+ * }
73
+ */
74
+ getContainer() {
75
+ return this.containerDI;
76
+ }
77
+ /**
78
+ * Register a provider in the application's DI container.
79
+ * Providers registered here are available to all modules and engines in this application.
80
+ *
81
+ * @template T
82
+ * @param {ServiceIdentifier<T>} identifier - The service identifier (class or token)
83
+ * @param {Newable<T>} provider - The provider class to bind
84
+ * @returns {void}
85
+ * @since 2.0.0
86
+ * @summary Register a DI provider
87
+ *
88
+ * @example
89
+ * class MyApp extends Boot {
90
+ * constructor() {
91
+ * super();
92
+ * this.registerProvider(DatabaseService, DatabaseService);
93
+ * this.registerProvider('API_KEY', ApiKeyProvider);
94
+ * }
95
+ * }
96
+ */
97
+ registerProvider(identifier, provider) {
98
+ if (!this.containerDI.isBound(identifier)) {
99
+ this.containerDI.bind(identifier).to(provider);
100
+ }
101
+ }
102
+ /**
103
+ * Register a constant value in the application's DI container.
104
+ *
105
+ * @template T
106
+ * @param {ServiceIdentifier<T>} identifier - The service identifier (usually a string or symbol)
107
+ * @param {T} value - The constant value to bind
108
+ * @returns {void}
109
+ * @since 2.0.0
110
+ * @summary Register a constant value
111
+ *
112
+ * @example
113
+ * class MyApp extends Boot {
114
+ * constructor() {
115
+ * super();
116
+ * this.registerConstant('DATABASE_URL', process.env.DATABASE_URL);
117
+ * this.registerConstant('MAX_CONNECTIONS', 100);
118
+ * }
119
+ * }
120
+ */
121
+ registerConstant(identifier, value) {
122
+ if (!this.containerDI.isBound(identifier)) {
123
+ this.containerDI.bind(identifier).toConstantValue(value);
124
+ }
125
+ }
55
126
  /**
56
127
  * Bootstrap and verify that all the required plugins are correctly configured and proceed to attach all the
57
128
  * registered modules. <b>Remember</b> this is the unique method that must be decorated for the Register Module
@@ -60,44 +131,93 @@ class Boot {
60
131
  * @returns {Promise<ExpressiveTeaApplication>}
61
132
  */
62
133
  async start() {
63
- return new Promise(async (resolver, reject) => {
64
- try {
65
- const localContainer = inversify_config_1.default.createChild();
66
- const privateKey = this.settings.get('privateKey');
67
- const certificate = this.settings.get('certificate');
68
- const server = http.createServer(this.server);
69
- const secureServer = privateKey && certificate && https.createServer({
70
- cert: fs.readFileSync(certificate).toString('utf-8'),
71
- key: fs.readFileSync(privateKey).toString('utf-8')
72
- });
73
- // Injectables
74
- localContainer.bind('server').toConstantValue(server);
75
- localContainer.bind('secureServer').toConstantValue(secureServer || undefined);
76
- localContainer.bind('context').toConstantValue(this);
77
- localContainer.bind('settings').toConstantValue(this.settings);
78
- // Activation
79
- const isActiveTeapot = Metadata_1.default.get(constants_1.ASSIGN_TEAPOT_KEY, (0, object_helper_1.getClass)(this), 'isTeapotActive');
80
- const isActiveTeacup = Metadata_1.default.get(constants_1.ASSIGN_TEACUP_KEY, (0, object_helper_1.getClass)(this), 'isTeacupActive');
81
- const isActiveWebsockets = this.settings.get('startWebsocket');
82
- // Resolve Engines
83
- const httpEngine = localContainer.resolve(http_1.default);
84
- const availableEngines = [
85
- localContainer.resolve(index_2.default),
86
- ...isActiveWebsockets ? [localContainer.resolve(websocket_1.default)] : [],
87
- ...isActiveTeapot ? [localContainer.resolve(index_1.default)] : [],
88
- ...isActiveTeacup ? [localContainer.resolve(teacup_1.default)] : [],
89
- ];
90
- // Initialize Engines
91
- await Engine_1.default.exec(availableEngines, 'init');
92
- await httpEngine.init();
93
- await httpEngine.start();
94
- await Engine_1.default.exec(availableEngines, 'start');
95
- resolver({ application: this.server, server, secureServer });
96
- }
97
- catch (e) {
98
- return reject(e);
99
- }
134
+ // Initialize Server
135
+ const [server, secureServer] = this.initializeHttp();
136
+ // Injectables
137
+ this.initializeContainer(server, secureServer);
138
+ // Lazy load engines to avoid circular dependency
139
+ // This ensures engines are only loaded when needed
140
+ if (EngineRegistry_1.default.getAllEngines().length === 0) {
141
+ await Promise.resolve().then(() => require('../engines'));
142
+ }
143
+ // Get registered engines from EngineRegistry (automatically filtered and sorted by dependencies)
144
+ const registeredEngines = EngineRegistry_1.default.getRegisteredEngines(this, this.settings);
145
+ this.initializeEngines(registeredEngines);
146
+ // Resolve Engines
147
+ const readyEngines = registeredEngines.map(Engine => {
148
+ const instance = this.containerDI.get(Engine);
149
+ return instance;
100
150
  });
151
+ // Store engine instances for cleanup
152
+ this.engines = readyEngines;
153
+ // Initialize Engines
154
+ try {
155
+ await Engine_1.default.exec(readyEngines.reverse(), 'init');
156
+ await Engine_1.default.exec(readyEngines, 'start');
157
+ return ({ application: this.server, server, secureServer });
158
+ }
159
+ catch (e) {
160
+ // If anything failed during engine initialization or start, ensure servers are closed to avoid leaking
161
+ server === null || server === void 0 ? void 0 : server.close();
162
+ secureServer === null || secureServer === void 0 ? void 0 : secureServer.close();
163
+ throw e;
164
+ }
165
+ }
166
+ /**
167
+ * Gracefully stop the application and all engines
168
+ *
169
+ * Calls the stop() lifecycle method on all registered engines in reverse order
170
+ * (opposite of initialization order) to ensure proper cleanup.
171
+ *
172
+ * @returns {Promise<void>} Promise that resolves when all engines have stopped
173
+ * @since 2.0.0
174
+ * @summary Graceful shutdown
175
+ *
176
+ * @example
177
+ * ```typescript
178
+ * const app = new MyApp();
179
+ * await app.start();
180
+ *
181
+ * // Later, during shutdown
182
+ * await app.stop();
183
+ * ```
184
+ */
185
+ async stop() {
186
+ if (this.engines.length === 0) {
187
+ return;
188
+ }
189
+ // Stop engines in reverse order (opposite of initialization)
190
+ await Engine_1.default.exec([...this.engines].reverse(), 'stop');
191
+ // Clear engine references
192
+ this.engines = [];
193
+ }
194
+ initializeEngines(registeredEngines) {
195
+ for (const Engine of registeredEngines) {
196
+ this.containerDI.bind(Engine).to(Engine);
197
+ }
198
+ }
199
+ initializeHttp() {
200
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
201
+ const privateKey = this.settings.get('privateKey');
202
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
203
+ const certificate = this.settings.get('certificate');
204
+ const server = http.createServer(this.server);
205
+ const secureServer = privateKey &&
206
+ certificate
207
+ ? https.createServer({
208
+ cert: fs.readFileSync(certificate).toString('utf-8'),
209
+ key: fs.readFileSync(privateKey).toString('utf-8')
210
+ }, this.server)
211
+ : undefined;
212
+ return [server, secureServer];
213
+ }
214
+ initializeContainer(server, secureServer) {
215
+ this.containerDI.bind(injection_types_1.TYPES.Server).toConstantValue(server);
216
+ if (secureServer) {
217
+ this.containerDI.bind(injection_types_1.TYPES.SecureServer).toConstantValue(secureServer);
218
+ }
219
+ this.containerDI.bind(injection_types_1.TYPES.Context).toConstantValue(this);
220
+ this.containerDI.bind(injection_types_1.TYPES.Settings).toConstantValue(this.settings);
101
221
  }
102
222
  }
103
223
  exports.default = Boot;
@@ -1,14 +1,63 @@
1
- /// <reference types="node" />
2
- /// <reference types="node" />
3
1
  import Settings from './Settings';
4
- import Boot from './Boot';
5
- import http from 'http';
6
- import https from 'https';
2
+ import type Boot from './Boot';
3
+ import { Server as HttpServer } from 'node:http';
4
+ import { Server as HttpsServer } from 'node:https';
7
5
  export default class ExpressiveTeaEngine {
8
- protected readonly settings: Settings;
9
6
  protected readonly context: Boot;
10
- protected readonly server: http.Server;
11
- protected readonly serverSecure?: https.Server;
12
- constructor(ctx: any, server: any, serverSecure: any, settings: any);
13
- static exec(availableEngines: ExpressiveTeaEngine[], method: string): any;
7
+ protected readonly server: HttpServer;
8
+ protected readonly serverSecure: HttpsServer;
9
+ protected readonly settings: Settings;
10
+ constructor(context: Boot, server: HttpServer, serverSecure: HttpsServer, settings: Settings);
11
+ /**
12
+ * Execute a lifecycle method across all registered engines
13
+ *
14
+ * @param {ExpressiveTeaEngine[]} availableEngines - Array of engine instances
15
+ * @param {string} method - Method name to execute (e.g., 'init', 'start', 'stop')
16
+ * @returns {Promise<unknown[]>} Array of results from all engines
17
+ *
18
+ * @example
19
+ * ```typescript
20
+ * await ExpressiveTeaEngine.exec(engines, 'init');
21
+ * await ExpressiveTeaEngine.exec(engines, 'start');
22
+ * ```
23
+ * @since 1.0.0
24
+ */
25
+ static exec(availableEngines: ExpressiveTeaEngine[], method: string): Promise<unknown[]>;
26
+ /**
27
+ * Determine if this engine can be registered in the current context
28
+ *
29
+ * Override this method to conditionally enable/disable the engine based on
30
+ * settings or environment. Default returns false to prevent accidental registration.
31
+ *
32
+ * @param {Boot} [ctx] - Boot context
33
+ * @param {Settings} [settings] - Application settings
34
+ * @returns {boolean} True if engine can be registered
35
+ *
36
+ * @example
37
+ * ```typescript
38
+ * static canRegister(ctx?: Boot, settings?: Settings): boolean {
39
+ * return settings?.get('enableMyEngine') === true;
40
+ * }
41
+ * ```
42
+ * @since 1.0.0
43
+ */
44
+ static canRegister(ctx?: Boot, settings?: Settings): boolean;
45
+ /**
46
+ * Graceful shutdown lifecycle method
47
+ *
48
+ * Override this method to implement cleanup logic when the application stops.
49
+ * This is called during graceful shutdown to close connections, clean up resources, etc.
50
+ *
51
+ * @returns {Promise<void>} Promise that resolves when cleanup is complete
52
+ *
53
+ * @example
54
+ * ```typescript
55
+ * async stop(): Promise<void> {
56
+ * await this.closeConnections();
57
+ * await this.cleanup();
58
+ * }
59
+ * ```
60
+ * @since 2.0.0
61
+ */
62
+ stop(): Promise<void>;
14
63
  }
package/classes/Engine.js CHANGED
@@ -2,28 +2,89 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
4
  const inversify_1 = require("inversify");
5
+ const Settings_1 = require("./Settings");
6
+ const node_http_1 = require("node:http");
7
+ const node_https_1 = require("node:https");
8
+ const injection_types_1 = require("../types/injection-types");
5
9
  let ExpressiveTeaEngine = class ExpressiveTeaEngine {
6
- constructor(ctx, server, serverSecure, settings) {
7
- this.settings = settings;
8
- this.context = ctx;
10
+ constructor(context, server, serverSecure, settings) {
11
+ this.context = context;
9
12
  this.server = server;
10
13
  this.serverSecure = serverSecure;
14
+ this.settings = settings;
11
15
  }
16
+ /**
17
+ * Execute a lifecycle method across all registered engines
18
+ *
19
+ * @param {ExpressiveTeaEngine[]} availableEngines - Array of engine instances
20
+ * @param {string} method - Method name to execute (e.g., 'init', 'start', 'stop')
21
+ * @returns {Promise<unknown[]>} Array of results from all engines
22
+ *
23
+ * @example
24
+ * ```typescript
25
+ * await ExpressiveTeaEngine.exec(engines, 'init');
26
+ * await ExpressiveTeaEngine.exec(engines, 'start');
27
+ * ```
28
+ * @since 1.0.0
29
+ */
12
30
  static exec(availableEngines, method) {
13
31
  return Promise.all(availableEngines
14
- // tslint:disable-next-line:no-string-literal
15
32
  .filter(engine => typeof engine[method] === 'function')
16
- // tslint:disable-next-line:no-string-literal
17
- .map(engine => engine[method]()));
33
+ .map(engine => (engine[method])()));
34
+ }
35
+ /**
36
+ * Determine if this engine can be registered in the current context
37
+ *
38
+ * Override this method to conditionally enable/disable the engine based on
39
+ * settings or environment. Default returns false to prevent accidental registration.
40
+ *
41
+ * @param {Boot} [ctx] - Boot context
42
+ * @param {Settings} [settings] - Application settings
43
+ * @returns {boolean} True if engine can be registered
44
+ *
45
+ * @example
46
+ * ```typescript
47
+ * static canRegister(ctx?: Boot, settings?: Settings): boolean {
48
+ * return settings?.get('enableMyEngine') === true;
49
+ * }
50
+ * ```
51
+ * @since 1.0.0
52
+ */
53
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
54
+ static canRegister(ctx, settings) {
55
+ return false;
56
+ }
57
+ /**
58
+ * Graceful shutdown lifecycle method
59
+ *
60
+ * Override this method to implement cleanup logic when the application stops.
61
+ * This is called during graceful shutdown to close connections, clean up resources, etc.
62
+ *
63
+ * @returns {Promise<void>} Promise that resolves when cleanup is complete
64
+ *
65
+ * @example
66
+ * ```typescript
67
+ * async stop(): Promise<void> {
68
+ * await this.closeConnections();
69
+ * await this.cleanup();
70
+ * }
71
+ * ```
72
+ * @since 2.0.0
73
+ */
74
+ async stop() {
75
+ // Default implementation does nothing
76
+ // Engines can override to implement cleanup
18
77
  }
19
78
  };
20
79
  ExpressiveTeaEngine = tslib_1.__decorate([
21
80
  (0, inversify_1.injectable)(),
22
- tslib_1.__param(0, (0, inversify_1.inject)('context')),
23
- tslib_1.__param(1, (0, inversify_1.inject)('server')),
24
- tslib_1.__param(2, (0, inversify_1.inject)('secureServer')),
81
+ tslib_1.__param(0, (0, inversify_1.inject)(injection_types_1.TYPES.Context)),
82
+ tslib_1.__param(1, (0, inversify_1.inject)(injection_types_1.TYPES.Server)),
83
+ tslib_1.__param(2, (0, inversify_1.inject)(injection_types_1.TYPES.SecureServer)),
25
84
  tslib_1.__param(2, (0, inversify_1.optional)()),
26
- tslib_1.__param(3, (0, inversify_1.inject)('settings')),
27
- tslib_1.__metadata("design:paramtypes", [Object, Object, Object, Object])
85
+ tslib_1.__param(3, (0, inversify_1.inject)(injection_types_1.TYPES.Settings)),
86
+ tslib_1.__metadata("design:paramtypes", [Function, node_http_1.Server,
87
+ node_https_1.Server,
88
+ Settings_1.default])
28
89
  ], ExpressiveTeaEngine);
29
90
  exports.default = ExpressiveTeaEngine;