@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.
- package/build/core/containerPool.d.ts +129 -26
- package/build/core/containerPool.js +213 -68
- package/build/core/handler.d.ts +2 -2
- package/build/core/handler.js +6 -12
- package/build/core/index.d.ts +1 -0
- package/build/core/index.js +1 -0
- package/build/core/logger.d.ts +89 -1
- package/build/core/logger.js +136 -5
- package/build/core/telemetry/config.d.ts +331 -0
- package/build/core/telemetry/config.js +153 -0
- package/build/core/telemetry/index.d.ts +22 -0
- package/build/core/telemetry/index.js +45 -0
- package/build/core/telemetry/provider.d.ts +203 -0
- package/build/core/telemetry/provider.js +3 -0
- package/build/core/telemetry/providers/console-provider.d.ts +54 -0
- package/build/core/telemetry/providers/console-provider.js +124 -0
- package/build/core/telemetry/providers/index.d.ts +10 -0
- package/build/core/telemetry/providers/index.js +19 -0
- package/build/core/telemetry/providers/noop-provider.d.ts +51 -0
- package/build/core/telemetry/providers/noop-provider.js +67 -0
- package/build/core/telemetry/providers/opentelemetry-provider.d.ts +102 -0
- package/build/core/telemetry/providers/opentelemetry-provider.js +342 -0
- package/build/middlewares/dependencyInjectionMiddleware.d.ts +16 -8
- package/build/middlewares/dependencyInjectionMiddleware.js +31 -11
- package/build/middlewares/guards/adapters/CustomTokenVerificationPortAdapter.d.ts +1 -1
- package/build/middlewares/guards/guards/FastAuthGuard.d.ts +5 -5
- package/build/middlewares/guards/guards/FastAuthGuard.js +3 -2
- package/build/middlewares/guards/guards/PermissionGuardFactory.d.ts +7 -9
- package/build/middlewares/guards/resolvers/ExpressionPermissionResolver.d.ts +1 -1
- package/build/middlewares/guards/resolvers/ExpressionPermissionResolver.js +1 -1
- package/build/middlewares/guards/resolvers/PermissionResolver.d.ts +1 -1
- package/build/middlewares/guards/resolvers/PlainPermissionResolver.d.ts +1 -1
- package/build/middlewares/guards/resolvers/WildcardPermissionResolver.d.ts +1 -1
- package/build/middlewares/guards/services/FastUserContextService.d.ts +11 -32
- package/build/middlewares/index.d.ts +1 -0
- package/build/middlewares/index.js +1 -0
- package/build/middlewares/openTelemetryMiddleware.d.ts +162 -0
- package/build/middlewares/openTelemetryMiddleware.js +359 -0
- package/build/middlewares/rateLimitingMiddleware.js +16 -5
- package/build/utils/container.utils.js +4 -1
- package/build/utils/fastify-wrapper.d.ts +74 -0
- package/build/utils/fastify-wrapper.js +175 -0
- package/build/utils/index.d.ts +4 -0
- package/build/utils/index.js +23 -1
- package/build/utils/otel.helper.d.ts +122 -0
- package/build/utils/otel.helper.js +258 -0
- package/build/utils/pubsub-trace.utils.d.ts +102 -0
- package/build/utils/pubsub-trace.utils.js +155 -0
- package/build/utils/wrapper-utils.d.ts +177 -0
- package/build/utils/wrapper-utils.js +236 -0
- package/package.json +61 -2
|
@@ -1,44 +1,147 @@
|
|
|
1
1
|
import { ContainerInstance } from 'typedi';
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
* This reduces object creation overhead and improves memory efficiency
|
|
3
|
+
* Service definition for container registration
|
|
5
4
|
*/
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
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
|
-
*
|
|
14
|
+
* Enable hybrid proxy container (default: true)
|
|
15
|
+
* Set to false to use legacy pooling behavior
|
|
13
16
|
*/
|
|
14
|
-
|
|
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
|
-
*
|
|
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
|
-
|
|
82
|
+
static initializeGlobal(services?: ServiceDefinition[], options?: ContainerPoolOptions): void;
|
|
19
83
|
/**
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
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
|
-
|
|
108
|
+
static createProxyContainer(): ContainerInstance;
|
|
25
109
|
/**
|
|
26
|
-
*
|
|
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
|
-
|
|
29
|
-
available: number;
|
|
30
|
-
created: number;
|
|
31
|
-
maxSize: number;
|
|
32
|
-
};
|
|
126
|
+
static asMiddleware(services?: ServiceDefinition[]): (container?: ContainerInstance) => ContainerInstance;
|
|
33
127
|
/**
|
|
34
|
-
*
|
|
128
|
+
* Get statistics about the container pool
|
|
129
|
+
* (Maintained for backward compatibility)
|
|
35
130
|
*/
|
|
36
|
-
|
|
131
|
+
static getStats(): {
|
|
132
|
+
useProxy: boolean;
|
|
133
|
+
globalInitialized: boolean;
|
|
134
|
+
};
|
|
37
135
|
/**
|
|
38
|
-
* Clear
|
|
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
|
-
|
|
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
|
-
*
|
|
7
|
-
*
|
|
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
|
-
|
|
11
|
-
|
|
12
|
-
createdContainers = 0;
|
|
13
|
-
constructor(maxPoolSize = 10) {
|
|
14
|
-
this.maxPoolSize = maxPoolSize;
|
|
15
|
-
}
|
|
55
|
+
static globalContainer = null;
|
|
56
|
+
static useProxy = true;
|
|
16
57
|
/**
|
|
17
|
-
*
|
|
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
|
-
|
|
20
|
-
if (
|
|
21
|
-
|
|
73
|
+
static initializeGlobal(services = [], options) {
|
|
74
|
+
if (options?.useProxy !== undefined) {
|
|
75
|
+
this.useProxy = options.useProxy;
|
|
22
76
|
}
|
|
23
|
-
// Create
|
|
24
|
-
if (this.
|
|
25
|
-
this.
|
|
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
|
-
//
|
|
29
|
-
|
|
30
|
-
|
|
81
|
+
// Register all global services
|
|
82
|
+
services.forEach((service) => {
|
|
83
|
+
this.globalContainer.set(service.id, service.value);
|
|
84
|
+
});
|
|
31
85
|
}
|
|
32
86
|
/**
|
|
33
|
-
*
|
|
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
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
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
|
-
//
|
|
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
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
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
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
//
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
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
|
|
218
|
+
* Get statistics about the container pool
|
|
219
|
+
* (Maintained for backward compatibility)
|
|
65
220
|
*/
|
|
66
|
-
getStats() {
|
|
221
|
+
static getStats() {
|
|
67
222
|
return {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
maxSize: this.maxPoolSize,
|
|
223
|
+
useProxy: this.useProxy,
|
|
224
|
+
globalInitialized: this.globalContainer !== null,
|
|
71
225
|
};
|
|
72
226
|
}
|
|
73
227
|
/**
|
|
74
|
-
*
|
|
228
|
+
* Clear the global container (useful for testing)
|
|
229
|
+
* ⚠️ WARNING: This resets ALL global services
|
|
75
230
|
*/
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
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
|
-
|
|
96
|
-
|
|
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
|
package/build/core/handler.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Context,
|
|
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:
|
|
54
|
+
execute(req: GenericRequest<T>, res: GenericResponse): Promise<void>;
|
|
55
55
|
/**
|
|
56
56
|
* Execute before middlewares with optimized batching for independent middlewares
|
|
57
57
|
*/
|
package/build/core/handler.js
CHANGED
|
@@ -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
|
-
//
|
|
70
|
-
const container = containerPool_1.containerPool.
|
|
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
|
-
//
|
|
128
|
-
const container = containerPool_1.containerPool.
|
|
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;
|
package/build/core/index.d.ts
CHANGED
package/build/core/index.js
CHANGED
|
@@ -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
|