@noony-serverless/core 0.3.4 → 0.4.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 (51) hide show
  1. package/build/core/containerPool.d.ts +129 -26
  2. package/build/core/containerPool.js +213 -68
  3. package/build/core/handler.d.ts +2 -2
  4. package/build/core/handler.js +6 -12
  5. package/build/core/index.d.ts +1 -0
  6. package/build/core/index.js +1 -0
  7. package/build/core/logger.d.ts +89 -1
  8. package/build/core/logger.js +136 -5
  9. package/build/core/telemetry/config.d.ts +331 -0
  10. package/build/core/telemetry/config.js +153 -0
  11. package/build/core/telemetry/index.d.ts +22 -0
  12. package/build/core/telemetry/index.js +45 -0
  13. package/build/core/telemetry/provider.d.ts +203 -0
  14. package/build/core/telemetry/provider.js +3 -0
  15. package/build/core/telemetry/providers/console-provider.d.ts +54 -0
  16. package/build/core/telemetry/providers/console-provider.js +124 -0
  17. package/build/core/telemetry/providers/index.d.ts +10 -0
  18. package/build/core/telemetry/providers/index.js +19 -0
  19. package/build/core/telemetry/providers/noop-provider.d.ts +51 -0
  20. package/build/core/telemetry/providers/noop-provider.js +67 -0
  21. package/build/core/telemetry/providers/opentelemetry-provider.d.ts +102 -0
  22. package/build/core/telemetry/providers/opentelemetry-provider.js +342 -0
  23. package/build/middlewares/dependencyInjectionMiddleware.d.ts +16 -8
  24. package/build/middlewares/dependencyInjectionMiddleware.js +31 -11
  25. package/build/middlewares/guards/adapters/CustomTokenVerificationPortAdapter.d.ts +1 -1
  26. package/build/middlewares/guards/guards/FastAuthGuard.d.ts +5 -5
  27. package/build/middlewares/guards/guards/FastAuthGuard.js +3 -2
  28. package/build/middlewares/guards/guards/PermissionGuardFactory.d.ts +7 -9
  29. package/build/middlewares/guards/resolvers/ExpressionPermissionResolver.d.ts +1 -1
  30. package/build/middlewares/guards/resolvers/ExpressionPermissionResolver.js +1 -1
  31. package/build/middlewares/guards/resolvers/PermissionResolver.d.ts +1 -1
  32. package/build/middlewares/guards/resolvers/PlainPermissionResolver.d.ts +1 -1
  33. package/build/middlewares/guards/resolvers/WildcardPermissionResolver.d.ts +1 -1
  34. package/build/middlewares/guards/services/FastUserContextService.d.ts +11 -32
  35. package/build/middlewares/index.d.ts +1 -0
  36. package/build/middlewares/index.js +1 -0
  37. package/build/middlewares/openTelemetryMiddleware.d.ts +162 -0
  38. package/build/middlewares/openTelemetryMiddleware.js +359 -0
  39. package/build/middlewares/rateLimitingMiddleware.js +16 -5
  40. package/build/utils/container.utils.js +4 -1
  41. package/build/utils/fastify-wrapper.d.ts +74 -0
  42. package/build/utils/fastify-wrapper.js +175 -0
  43. package/build/utils/index.d.ts +4 -0
  44. package/build/utils/index.js +23 -1
  45. package/build/utils/otel.helper.d.ts +122 -0
  46. package/build/utils/otel.helper.js +258 -0
  47. package/build/utils/pubsub-trace.utils.d.ts +102 -0
  48. package/build/utils/pubsub-trace.utils.js +155 -0
  49. package/build/utils/wrapper-utils.d.ts +177 -0
  50. package/build/utils/wrapper-utils.js +236 -0
  51. package/package.json +61 -2
@@ -1,44 +1,147 @@
1
1
  import { ContainerInstance } from 'typedi';
2
2
  /**
3
- * Performance optimization: Container Pool for reusing TypeDI containers
4
- * This reduces object creation overhead and improves memory efficiency
3
+ * Service definition for container registration
5
4
  */
6
- declare class ContainerPool {
7
- private availableContainers;
8
- private maxPoolSize;
9
- private createdContainers;
10
- constructor(maxPoolSize?: number);
5
+ export interface ServiceDefinition {
6
+ id: any;
7
+ value: any;
8
+ }
9
+ /**
10
+ * Options for container pool initialization
11
+ */
12
+ export interface ContainerPoolOptions {
11
13
  /**
12
- * Get a container from the pool or create a new one
14
+ * Enable hybrid proxy container (default: true)
15
+ * Set to false to use legacy pooling behavior
13
16
  */
14
- acquire(): ContainerInstance;
17
+ useProxy?: boolean;
18
+ }
19
+ /**
20
+ * Hybrid Proxy Container Pool for serverless environments
21
+ *
22
+ * This implementation uses a zero-copy proxy pattern that provides:
23
+ * - Process Lifetime (Global): Services initialized once and shared across requests
24
+ * - Request Lifetime (Local): Services isolated per request with zero overhead
25
+ *
26
+ * Architecture:
27
+ * - Global Container: Singleton with process-lifetime services (DB, Logger, etc.)
28
+ * - Proxy Container: Lightweight wrapper per-request that shadows local overrides
29
+ * - Memory: O(1) per request (just the proxy + local overrides Map)
30
+ * - Performance: ~99% memory reduction vs traditional container pooling
31
+ *
32
+ * @example
33
+ * Basic usage with global services:
34
+ * ```typescript
35
+ * // Initialize global services once at startup
36
+ * containerPool.initializeGlobal([
37
+ * { id: 'Database', value: new DatabaseService() },
38
+ * { id: 'Logger', value: new LoggerService() }
39
+ * ]);
40
+ *
41
+ * // Per-request: Create lightweight proxy
42
+ * const container = containerPool.createProxyContainer();
43
+ * const db = container.get('Database'); // From global
44
+ * ```
45
+ *
46
+ * @example
47
+ * Request-scoped services with local overrides:
48
+ * ```typescript
49
+ * // Global services
50
+ * containerPool.initializeGlobal([
51
+ * { id: UserService, value: new UserService() }
52
+ * ]);
53
+ *
54
+ * // Per-request: Add request-scoped data
55
+ * const container = containerPool.createProxyContainer();
56
+ * container.set('RequestId', 'req-123'); // Local scope only
57
+ * container.set('CurrentUser', currentUser); // Local scope only
58
+ *
59
+ * const userService = container.get(UserService); // From global
60
+ * const requestId = container.get('RequestId'); // From local
61
+ * ```
62
+ */
63
+ declare class ContainerPool {
64
+ private static globalContainer;
65
+ private static useProxy;
15
66
  /**
16
- * Return a container to the pool for reuse
67
+ * Initialize the global container with process-lifetime services
68
+ * This should be called once at application startup
69
+ *
70
+ * @param services - Array of service definitions to register globally
71
+ * @param options - Configuration options
72
+ *
73
+ * @example
74
+ * ```typescript
75
+ * containerPool.initializeGlobal([
76
+ * { id: 'config', value: { apiUrl: 'https://api.example.com' } },
77
+ * { id: DatabaseService, value: new DatabaseService() },
78
+ * { id: LoggerService, value: new LoggerService() }
79
+ * ]);
80
+ * ```
17
81
  */
18
- release(container: ContainerInstance): void;
82
+ static initializeGlobal(services?: ServiceDefinition[], options?: ContainerPoolOptions): void;
19
83
  /**
20
- * Reset container state to prevent cross-request contamination
21
- * Note: TypeDI containers are isolated by default, so we mainly need
22
- * to clear any manually set values
84
+ * Create a lightweight proxy container for a single request
85
+ *
86
+ * The proxy provides:
87
+ * - Read access to global services (zero-copy)
88
+ * - Local overrides for request-scoped data
89
+ * - Automatic garbage collection (no manual cleanup needed)
90
+ *
91
+ * @returns A proxy container instance with request-local scope
92
+ *
93
+ * @example
94
+ * ```typescript
95
+ * async function handleRequest(req, res) {
96
+ * const container = containerPool.createProxyContainer();
97
+ *
98
+ * // Add request-specific data
99
+ * container.set('TraceId', req.headers['x-trace-id']);
100
+ *
101
+ * // Access global services
102
+ * const db = container.get(DatabaseService);
103
+ *
104
+ * // No cleanup needed - auto GC'd
105
+ * }
106
+ * ```
23
107
  */
24
- private resetContainer;
108
+ static createProxyContainer(): ContainerInstance;
25
109
  /**
26
- * Get pool statistics for monitoring
110
+ * Create a middleware-compatible container factory
111
+ *
112
+ * @param services - Optional services to set as local overrides per-request
113
+ * @returns Function that creates proxy container with optional local services
114
+ *
115
+ * @example
116
+ * ```typescript
117
+ * const handler = new Handler()
118
+ * .use(containerPool.asMiddleware([
119
+ * { id: 'RequestId', value: 'req-123' }
120
+ * ]))
121
+ * .handle(async (context) => {
122
+ * const requestId = context.container.get('RequestId');
123
+ * });
124
+ * ```
27
125
  */
28
- getStats(): {
29
- available: number;
30
- created: number;
31
- maxSize: number;
32
- };
126
+ static asMiddleware(services?: ServiceDefinition[]): (container?: ContainerInstance) => ContainerInstance;
33
127
  /**
34
- * Warm up the pool by pre-creating containers
128
+ * Get statistics about the container pool
129
+ * (Maintained for backward compatibility)
35
130
  */
36
- warmUp(count?: number): void;
131
+ static getStats(): {
132
+ useProxy: boolean;
133
+ globalInitialized: boolean;
134
+ };
37
135
  /**
38
- * Clear all containers from the pool
136
+ * Clear the global container (useful for testing)
137
+ * ⚠️ WARNING: This resets ALL global services
39
138
  */
40
- clear(): void;
139
+ static clear(): void;
41
140
  }
42
- declare const containerPool: ContainerPool;
141
+ /**
142
+ * Global container pool instance
143
+ * Pre-initialized for immediate use in serverless environments
144
+ */
145
+ declare const containerPool: typeof ContainerPool;
43
146
  export { ContainerPool, containerPool };
44
147
  //# sourceMappingURL=containerPool.d.ts.map
@@ -3,98 +3,243 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.containerPool = exports.ContainerPool = void 0;
4
4
  const typedi_1 = require("typedi");
5
5
  /**
6
- * Performance optimization: Container Pool for reusing TypeDI containers
7
- * This reduces object creation overhead and improves memory efficiency
6
+ * Symbol used to mark services as "deleted" in request-local scope
7
+ * @internal
8
+ */
9
+ const TOMBSTONE = Symbol('TOMBSTONE');
10
+ /**
11
+ * Hybrid Proxy Container Pool for serverless environments
12
+ *
13
+ * This implementation uses a zero-copy proxy pattern that provides:
14
+ * - Process Lifetime (Global): Services initialized once and shared across requests
15
+ * - Request Lifetime (Local): Services isolated per request with zero overhead
16
+ *
17
+ * Architecture:
18
+ * - Global Container: Singleton with process-lifetime services (DB, Logger, etc.)
19
+ * - Proxy Container: Lightweight wrapper per-request that shadows local overrides
20
+ * - Memory: O(1) per request (just the proxy + local overrides Map)
21
+ * - Performance: ~99% memory reduction vs traditional container pooling
22
+ *
23
+ * @example
24
+ * Basic usage with global services:
25
+ * ```typescript
26
+ * // Initialize global services once at startup
27
+ * containerPool.initializeGlobal([
28
+ * { id: 'Database', value: new DatabaseService() },
29
+ * { id: 'Logger', value: new LoggerService() }
30
+ * ]);
31
+ *
32
+ * // Per-request: Create lightweight proxy
33
+ * const container = containerPool.createProxyContainer();
34
+ * const db = container.get('Database'); // From global
35
+ * ```
36
+ *
37
+ * @example
38
+ * Request-scoped services with local overrides:
39
+ * ```typescript
40
+ * // Global services
41
+ * containerPool.initializeGlobal([
42
+ * { id: UserService, value: new UserService() }
43
+ * ]);
44
+ *
45
+ * // Per-request: Add request-scoped data
46
+ * const container = containerPool.createProxyContainer();
47
+ * container.set('RequestId', 'req-123'); // Local scope only
48
+ * container.set('CurrentUser', currentUser); // Local scope only
49
+ *
50
+ * const userService = container.get(UserService); // From global
51
+ * const requestId = container.get('RequestId'); // From local
52
+ * ```
8
53
  */
9
54
  class ContainerPool {
10
- availableContainers = [];
11
- maxPoolSize = 10;
12
- createdContainers = 0;
13
- constructor(maxPoolSize = 10) {
14
- this.maxPoolSize = maxPoolSize;
15
- }
55
+ static globalContainer = null;
56
+ static useProxy = true;
16
57
  /**
17
- * Get a container from the pool or create a new one
58
+ * Initialize the global container with process-lifetime services
59
+ * This should be called once at application startup
60
+ *
61
+ * @param services - Array of service definitions to register globally
62
+ * @param options - Configuration options
63
+ *
64
+ * @example
65
+ * ```typescript
66
+ * containerPool.initializeGlobal([
67
+ * { id: 'config', value: { apiUrl: 'https://api.example.com' } },
68
+ * { id: DatabaseService, value: new DatabaseService() },
69
+ * { id: LoggerService, value: new LoggerService() }
70
+ * ]);
71
+ * ```
18
72
  */
19
- acquire() {
20
- if (this.availableContainers.length > 0) {
21
- return this.availableContainers.pop();
73
+ static initializeGlobal(services = [], options) {
74
+ if (options?.useProxy !== undefined) {
75
+ this.useProxy = options.useProxy;
22
76
  }
23
- // Create new container if pool is empty and under limit
24
- if (this.createdContainers < this.maxPoolSize) {
25
- this.createdContainers++;
26
- return typedi_1.Container.of();
77
+ // Create global container if not exists
78
+ if (!this.globalContainer) {
79
+ this.globalContainer = typedi_1.Container.of('__noony_global__');
27
80
  }
28
- // If pool is at capacity, create a temporary container
29
- // This should rarely happen in normal usage
30
- return typedi_1.Container.of();
81
+ // Register all global services
82
+ services.forEach((service) => {
83
+ this.globalContainer.set(service.id, service.value);
84
+ });
31
85
  }
32
86
  /**
33
- * Return a container to the pool for reuse
87
+ * Create a lightweight proxy container for a single request
88
+ *
89
+ * The proxy provides:
90
+ * - Read access to global services (zero-copy)
91
+ * - Local overrides for request-scoped data
92
+ * - Automatic garbage collection (no manual cleanup needed)
93
+ *
94
+ * @returns A proxy container instance with request-local scope
95
+ *
96
+ * @example
97
+ * ```typescript
98
+ * async function handleRequest(req, res) {
99
+ * const container = containerPool.createProxyContainer();
100
+ *
101
+ * // Add request-specific data
102
+ * container.set('TraceId', req.headers['x-trace-id']);
103
+ *
104
+ * // Access global services
105
+ * const db = container.get(DatabaseService);
106
+ *
107
+ * // No cleanup needed - auto GC'd
108
+ * }
109
+ * ```
34
110
  */
35
- release(container) {
36
- if (this.availableContainers.length < this.maxPoolSize) {
37
- // Reset container state by removing all instances
38
- // This prevents memory leaks and cross-request contamination
39
- this.resetContainer(container);
40
- this.availableContainers.push(container);
111
+ static createProxyContainer() {
112
+ // Ensure global container is initialized
113
+ if (!this.globalContainer) {
114
+ this.initializeGlobal([]);
41
115
  }
42
- // If pool is full, let the container be garbage collected
116
+ // Request-local overrides Map (only allocates if services are set)
117
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
118
+ const localOverrides = new Map();
119
+ // Create proxy that intercepts container operations
120
+ const proxyContainer = new Proxy(this.globalContainer, {
121
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
122
+ get(target, prop, receiver) {
123
+ // Intercept 'get' method for service resolution
124
+ if (prop === 'get') {
125
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
126
+ return function (serviceId) {
127
+ // 1. Check local overrides first (request scope)
128
+ if (localOverrides.has(serviceId)) {
129
+ const value = localOverrides.get(serviceId);
130
+ // Handle tombstone (service marked as "deleted")
131
+ if (value === TOMBSTONE) {
132
+ throw new Error(`Service "${String(serviceId)}" not found (removed in request scope)`);
133
+ }
134
+ return value;
135
+ }
136
+ // 2. Fallback to global container (process scope)
137
+ return target.get(serviceId);
138
+ };
139
+ }
140
+ // Intercept 'set' method to write to local scope only
141
+ if (prop === 'set') {
142
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
143
+ return function (serviceId, value) {
144
+ // ✅ Write to local scope ONLY - never mutate global
145
+ localOverrides.set(serviceId, value);
146
+ return proxyContainer;
147
+ };
148
+ }
149
+ // Intercept 'remove' method to mark as deleted locally
150
+ if (prop === 'remove') {
151
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
152
+ return function (serviceId) {
153
+ // Mark service as "deleted" in local scope using tombstone
154
+ localOverrides.set(serviceId, TOMBSTONE);
155
+ return proxyContainer;
156
+ };
157
+ }
158
+ // Intercept 'reset' method to clear local overrides
159
+ if (prop === 'reset') {
160
+ return function () {
161
+ // Clear local overrides - revert to pure global state
162
+ localOverrides.clear();
163
+ };
164
+ }
165
+ // Intercept 'has' method for service existence check
166
+ if (prop === 'has') {
167
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
168
+ return function (serviceId) {
169
+ // Check local overrides first
170
+ if (localOverrides.has(serviceId)) {
171
+ const value = localOverrides.get(serviceId);
172
+ // Tombstone means service is "deleted"
173
+ return value !== TOMBSTONE;
174
+ }
175
+ // Fallback to global container
176
+ return target.has(serviceId);
177
+ };
178
+ }
179
+ // For all other properties/methods, delegate to global container
180
+ const value = Reflect.get(target, prop, receiver);
181
+ // Bind methods to target to preserve 'this' context
182
+ if (typeof value === 'function') {
183
+ return value.bind(target);
184
+ }
185
+ return value;
186
+ },
187
+ });
188
+ return proxyContainer;
43
189
  }
44
190
  /**
45
- * Reset container state to prevent cross-request contamination
46
- * Note: TypeDI containers are isolated by default, so we mainly need
47
- * to clear any manually set values
191
+ * Create a middleware-compatible container factory
192
+ *
193
+ * @param services - Optional services to set as local overrides per-request
194
+ * @returns Function that creates proxy container with optional local services
195
+ *
196
+ * @example
197
+ * ```typescript
198
+ * const handler = new Handler()
199
+ * .use(containerPool.asMiddleware([
200
+ * { id: 'RequestId', value: 'req-123' }
201
+ * ]))
202
+ * .handle(async (context) => {
203
+ * const requestId = context.container.get('RequestId');
204
+ * });
205
+ * ```
48
206
  */
49
- resetContainer(_container) {
50
- try {
51
- // For TypeDI containers created with Container.of(), each container
52
- // is already isolated. We just need to ensure no memory leaks.
53
- // The container will be garbage collected when released from pool
54
- // if it contains too much data
55
- // TypeDI containers are self-contained and don't need explicit reset
56
- // This is a placeholder for future enhancements if needed
57
- }
58
- catch (error) {
59
- // If any issues occur, don't add back to pool
60
- console.warn('Failed to reset container, discarding:', error);
61
- }
207
+ static asMiddleware(services = []) {
208
+ return (existingContainer) => {
209
+ const container = existingContainer || this.createProxyContainer();
210
+ // Set local services if provided
211
+ services.forEach((service) => {
212
+ container.set(service.id, service.value);
213
+ });
214
+ return container;
215
+ };
62
216
  }
63
217
  /**
64
- * Get pool statistics for monitoring
218
+ * Get statistics about the container pool
219
+ * (Maintained for backward compatibility)
65
220
  */
66
- getStats() {
221
+ static getStats() {
67
222
  return {
68
- available: this.availableContainers.length,
69
- created: this.createdContainers,
70
- maxSize: this.maxPoolSize,
223
+ useProxy: this.useProxy,
224
+ globalInitialized: this.globalContainer !== null,
71
225
  };
72
226
  }
73
227
  /**
74
- * Warm up the pool by pre-creating containers
228
+ * Clear the global container (useful for testing)
229
+ * ⚠️ WARNING: This resets ALL global services
75
230
  */
76
- warmUp(count = 5) {
77
- const warmUpCount = Math.min(count, this.maxPoolSize);
78
- for (let i = 0; i < warmUpCount; i++) {
79
- if (this.createdContainers < this.maxPoolSize) {
80
- const container = typedi_1.Container.of();
81
- this.createdContainers++;
82
- this.availableContainers.push(container);
83
- }
231
+ static clear() {
232
+ if (this.globalContainer) {
233
+ this.globalContainer.reset();
234
+ this.globalContainer = null;
84
235
  }
85
236
  }
86
- /**
87
- * Clear all containers from the pool
88
- */
89
- clear() {
90
- this.availableContainers = [];
91
- this.createdContainers = 0;
92
- }
93
237
  }
94
238
  exports.ContainerPool = ContainerPool;
95
- // Global container pool instance
96
- const containerPool = new ContainerPool(15); // Slightly higher limit for serverless
239
+ /**
240
+ * Global container pool instance
241
+ * Pre-initialized for immediate use in serverless environments
242
+ */
243
+ const containerPool = ContainerPool;
97
244
  exports.containerPool = containerPool;
98
- // Warm up the pool for better cold start performance
99
- containerPool.warmUp(3);
100
245
  //# sourceMappingURL=containerPool.js.map
@@ -1,4 +1,4 @@
1
- import { Context, CustomRequest, CustomResponse, GenericRequest, GenericResponse } from './core';
1
+ import { Context, GenericRequest, GenericResponse } from './core';
2
2
  /**
3
3
  * Interface representing a base structure for middleware with optional lifecycle methods.
4
4
  *
@@ -51,7 +51,7 @@ export declare class Handler<T = unknown, U = unknown> {
51
51
  * Performance optimization: Pre-compute middleware arrays to avoid runtime array operations
52
52
  */
53
53
  private precomputeMiddlewareArrays;
54
- execute(req: CustomRequest<T>, res: CustomResponse): Promise<void>;
54
+ execute(req: GenericRequest<T>, res: GenericResponse): Promise<void>;
55
55
  /**
56
56
  * Execute before middlewares with optimized batching for independent middlewares
57
57
  */
@@ -66,8 +66,8 @@ class Handler {
66
66
  async execute(req, res) {
67
67
  const genericReq = (0, core_1.adaptGCPRequest)(req);
68
68
  const genericRes = (0, core_1.adaptGCPResponse)(res);
69
- // Performance optimization: Use container pool instead of creating new containers
70
- const container = containerPool_1.containerPool.acquire();
69
+ // Hybrid Proxy Container: Lightweight zero-copy container per request
70
+ const container = containerPool_1.containerPool.createProxyContainer();
71
71
  const context = (0, core_1.createContext)(genericReq, genericRes, {
72
72
  container,
73
73
  });
@@ -83,10 +83,7 @@ class Handler {
83
83
  // Execute error handlers using pre-computed array
84
84
  await this.executeErrorMiddlewares(error, context);
85
85
  }
86
- finally {
87
- // Always return container to pool for reuse
88
- containerPool_1.containerPool.release(container);
89
- }
86
+ // No finally block needed - proxy container is auto-GC'd
90
87
  }
91
88
  /**
92
89
  * Execute before middlewares with optimized batching for independent middlewares
@@ -124,8 +121,8 @@ class Handler {
124
121
  * Framework-agnostic execute method that works with GenericRequest/GenericResponse
125
122
  */
126
123
  async executeGeneric(req, res) {
127
- // Performance optimization: Use container pool instead of creating new containers
128
- const container = containerPool_1.containerPool.acquire();
124
+ // Hybrid Proxy Container: Lightweight zero-copy container per request
125
+ const container = containerPool_1.containerPool.createProxyContainer();
129
126
  const context = (0, core_1.createContext)(req, res, {
130
127
  container,
131
128
  });
@@ -141,10 +138,7 @@ class Handler {
141
138
  // Execute error handlers using pre-computed array
142
139
  await this.executeErrorMiddlewares(error, context);
143
140
  }
144
- finally {
145
- // Always return container to pool for reuse
146
- containerPool_1.containerPool.release(container);
147
- }
141
+ // No finally block needed - proxy container is auto-GC'd
148
142
  }
149
143
  }
150
144
  exports.Handler = Handler;
@@ -4,5 +4,6 @@ export * from './handler';
4
4
  export * from './logger';
5
5
  export * from './containerPool';
6
6
  export * from './performanceMonitor';
7
+ export * from './telemetry';
7
8
  export * from '../middlewares';
8
9
  //# sourceMappingURL=index.d.ts.map
@@ -20,5 +20,6 @@ __exportStar(require("./handler"), exports);
20
20
  __exportStar(require("./logger"), exports);
21
21
  __exportStar(require("./containerPool"), exports);
22
22
  __exportStar(require("./performanceMonitor"), exports);
23
+ __exportStar(require("./telemetry"), exports);
23
24
  __exportStar(require("../middlewares"), exports);
24
25
  //# sourceMappingURL=index.js.map