@gravito/core 1.2.1 → 1.6.1
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 +57 -6
- package/README.zh-TW.md +197 -6
- package/dist/Metrics-VOWWRNNR.js +219 -0
- package/dist/chunk-R5U7XKVJ.js +16 -0
- package/dist/compat-CI8hiulX.d.cts +376 -0
- package/dist/compat-CI8hiulX.d.ts +376 -0
- package/dist/compat.cjs +18 -0
- package/dist/compat.d.cts +1 -0
- package/dist/compat.d.ts +1 -0
- package/dist/compat.js +0 -0
- package/dist/engine/index.cjs +1764 -0
- package/dist/engine/index.d.cts +922 -0
- package/dist/engine/index.d.ts +922 -0
- package/dist/engine/index.js +1732 -0
- package/dist/index.cjs +14906 -0
- package/dist/index.d.cts +11008 -0
- package/dist/index.d.ts +11008 -0
- package/dist/index.js +14363 -0
- package/package.json +60 -7
|
@@ -0,0 +1,922 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Core HTTP Types for Gravito Framework
|
|
3
|
+
*
|
|
4
|
+
* These types provide a unified abstraction layer that decouples the framework
|
|
5
|
+
* from any specific HTTP engine (Photon, Express, custom, etc.).
|
|
6
|
+
*
|
|
7
|
+
* @module @gravito/core/http
|
|
8
|
+
* @since 2.0.0
|
|
9
|
+
*/
|
|
10
|
+
declare global {
|
|
11
|
+
interface ExecutionContext {
|
|
12
|
+
waitUntil(promise: Promise<unknown>): void;
|
|
13
|
+
passThroughOnException(): void;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Standard HTTP methods supported by Gravito
|
|
18
|
+
*/
|
|
19
|
+
type HttpMethod = 'get' | 'post' | 'put' | 'delete' | 'patch' | 'options' | 'head';
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @fileoverview Gravito Core Engine Types
|
|
23
|
+
*
|
|
24
|
+
* Minimal, high-performance types for the standalone engine.
|
|
25
|
+
* These are intentionally simpler than the full framework types.
|
|
26
|
+
*
|
|
27
|
+
* @module @gravito/core/engine
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* FastContext - The pooled request context
|
|
32
|
+
*/
|
|
33
|
+
interface FastContext$1 {
|
|
34
|
+
/** Request accessor */
|
|
35
|
+
readonly req: FastRequest;
|
|
36
|
+
/** Response helpers */
|
|
37
|
+
json<T>(data: T, status?: number): Response;
|
|
38
|
+
text(text: string, status?: number): Response;
|
|
39
|
+
html(html: string, status?: number): Response;
|
|
40
|
+
redirect(url: string, status?: 301 | 302 | 303 | 307 | 308): Response;
|
|
41
|
+
body(data: BodyInit | null, status?: number): Response;
|
|
42
|
+
stream(stream: ReadableStream, status?: number): Response;
|
|
43
|
+
notFound(message?: string): Response;
|
|
44
|
+
forbidden(message?: string): Response;
|
|
45
|
+
unauthorized(message?: string): Response;
|
|
46
|
+
badRequest(message?: string): Response;
|
|
47
|
+
forward(target: string, options?: any): Promise<Response>;
|
|
48
|
+
/** Header management */
|
|
49
|
+
header(name: string): string | undefined;
|
|
50
|
+
header(name: string, value: string): void;
|
|
51
|
+
status(code: number): void;
|
|
52
|
+
/** Context Variables */
|
|
53
|
+
get<T>(key: string): T;
|
|
54
|
+
set(key: string, value: any): void;
|
|
55
|
+
/** Request Scope Management */
|
|
56
|
+
requestScope(): any;
|
|
57
|
+
scoped<T>(key: string | symbol, factory: () => T): T;
|
|
58
|
+
/** Lifecycle helpers */
|
|
59
|
+
route: (name: string, params?: any, query?: any) => string;
|
|
60
|
+
readonly native: any;
|
|
61
|
+
/** Internal initialization for pooling */
|
|
62
|
+
init(request: Request, params?: Record<string, string>, path?: string, routePattern?: string): this;
|
|
63
|
+
/** Internal cleanup for pooling */
|
|
64
|
+
reset(): void;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* FastRequest - Minimal request interface
|
|
68
|
+
*/
|
|
69
|
+
interface FastRequest {
|
|
70
|
+
/** Full URL */
|
|
71
|
+
readonly url: string;
|
|
72
|
+
/** HTTP method */
|
|
73
|
+
readonly method: string;
|
|
74
|
+
/** Path without query */
|
|
75
|
+
readonly path: string;
|
|
76
|
+
/**
|
|
77
|
+
* Route pattern (e.g., /users/:id) for metrics labeling
|
|
78
|
+
* Prevents high cardinality issues in monitoring systems
|
|
79
|
+
*/
|
|
80
|
+
readonly routePattern?: string;
|
|
81
|
+
/** Get route parameter */
|
|
82
|
+
param(name: string): string | undefined;
|
|
83
|
+
/** Get all route parameters */
|
|
84
|
+
params(): Record<string, string>;
|
|
85
|
+
/** Get query parameter */
|
|
86
|
+
query(name: string): string | undefined;
|
|
87
|
+
/** Get all query parameters */
|
|
88
|
+
queries(): Record<string, string | string[]>;
|
|
89
|
+
/** Get header */
|
|
90
|
+
header(name: string): string | undefined;
|
|
91
|
+
/** Get all headers */
|
|
92
|
+
headers(): Record<string, string>;
|
|
93
|
+
/** Parse JSON body */
|
|
94
|
+
json<T = unknown>(): Promise<T>;
|
|
95
|
+
/** Parse text body */
|
|
96
|
+
text(): Promise<string>;
|
|
97
|
+
/** Parse form data */
|
|
98
|
+
formData(): Promise<FormData>;
|
|
99
|
+
/** Raw Request object */
|
|
100
|
+
readonly raw: Request;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Route handler function
|
|
104
|
+
*/
|
|
105
|
+
type Handler = (ctx: FastContext$1) => Response | Promise<Response>;
|
|
106
|
+
/**
|
|
107
|
+
* Middleware function
|
|
108
|
+
*/
|
|
109
|
+
type Middleware = (ctx: FastContext$1, next: () => Promise<Response | undefined>) => Response | undefined | Promise<Response | undefined>;
|
|
110
|
+
/**
|
|
111
|
+
* Error handler function
|
|
112
|
+
*/
|
|
113
|
+
type ErrorHandler = (error: Error, ctx: FastContext$1) => Response | Promise<Response>;
|
|
114
|
+
/**
|
|
115
|
+
* Not found handler function
|
|
116
|
+
*/
|
|
117
|
+
type NotFoundHandler = (ctx: FastContext$1) => Response | Promise<Response>;
|
|
118
|
+
/**
|
|
119
|
+
* Route metadata for middleware management
|
|
120
|
+
*/
|
|
121
|
+
interface RouteMetadata {
|
|
122
|
+
handler: Handler;
|
|
123
|
+
middleware: Middleware[];
|
|
124
|
+
compiled?: CompiledHandler;
|
|
125
|
+
useMinimal?: boolean;
|
|
126
|
+
compiledVersion?: number;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Compiled handler function
|
|
130
|
+
*/
|
|
131
|
+
type CompiledHandler = (ctx: FastContext$1) => Promise<Response>;
|
|
132
|
+
/**
|
|
133
|
+
* Route match result from router
|
|
134
|
+
*/
|
|
135
|
+
interface RouteMatch {
|
|
136
|
+
/** Matched handler */
|
|
137
|
+
handler: Handler | null;
|
|
138
|
+
/** Extracted route parameters */
|
|
139
|
+
params: Record<string, string>;
|
|
140
|
+
/** Middleware to execute */
|
|
141
|
+
middleware: Middleware[];
|
|
142
|
+
/** Optional stable route pattern for caching */
|
|
143
|
+
routePattern?: string;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Engine configuration options
|
|
147
|
+
*/
|
|
148
|
+
interface EngineOptions {
|
|
149
|
+
/** Context pool size (default: 256) */
|
|
150
|
+
poolSize?: number;
|
|
151
|
+
/** Enable route compilation optimization (default: true) */
|
|
152
|
+
enableAOT?: boolean;
|
|
153
|
+
/** Custom error handler */
|
|
154
|
+
onError?: ErrorHandler;
|
|
155
|
+
/** Custom 404 handler */
|
|
156
|
+
onNotFound?: NotFoundHandler;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* @fileoverview Gravito - High-Performance Web Engine for Bun
|
|
161
|
+
*
|
|
162
|
+
* The standalone engine optimized exclusively for Bun runtime.
|
|
163
|
+
* 99% API-compatible with Hono, but faster through Bun-specific optimizations.
|
|
164
|
+
*
|
|
165
|
+
* Key optimizations:
|
|
166
|
+
* 1. Object pooling for zero-allocation request handling
|
|
167
|
+
* 2. AOT router with O(1) static route lookup
|
|
168
|
+
* 3. Lazy parsing - only parse what's accessed
|
|
169
|
+
* 4. Direct Bun.serve integration without wrapper layers
|
|
170
|
+
*
|
|
171
|
+
* @module @gravito/core/engine
|
|
172
|
+
*/
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Gravito - The High-Performance Web Engine
|
|
176
|
+
*/
|
|
177
|
+
declare class Gravito {
|
|
178
|
+
private router;
|
|
179
|
+
private contextPool;
|
|
180
|
+
private errorHandler?;
|
|
181
|
+
private notFoundHandler?;
|
|
182
|
+
/** @internal */
|
|
183
|
+
staticRoutes: Map<string, RouteMetadata>;
|
|
184
|
+
private isPureStaticApp;
|
|
185
|
+
private compiledDynamicRoutes;
|
|
186
|
+
/**
|
|
187
|
+
* Create a new Gravito instance
|
|
188
|
+
*
|
|
189
|
+
* @param options - Engine configuration options
|
|
190
|
+
*/
|
|
191
|
+
constructor(options?: EngineOptions);
|
|
192
|
+
/**
|
|
193
|
+
* Register a GET route
|
|
194
|
+
*
|
|
195
|
+
* @param path - Route path (e.g., '/users/:id')
|
|
196
|
+
* @param handlers - Handler and optional middleware
|
|
197
|
+
* @returns This instance for chaining
|
|
198
|
+
*/
|
|
199
|
+
get(path: string, ...handlers: Handler[]): this;
|
|
200
|
+
/**
|
|
201
|
+
* Register a POST route
|
|
202
|
+
*/
|
|
203
|
+
post(path: string, ...handlers: Handler[]): this;
|
|
204
|
+
/**
|
|
205
|
+
* Register a PUT route
|
|
206
|
+
*/
|
|
207
|
+
put(path: string, ...handlers: Handler[]): this;
|
|
208
|
+
/**
|
|
209
|
+
* Register a DELETE route
|
|
210
|
+
*/
|
|
211
|
+
delete(path: string, ...handlers: Handler[]): this;
|
|
212
|
+
/**
|
|
213
|
+
* Register a PDF route
|
|
214
|
+
*/
|
|
215
|
+
patch(path: string, ...handlers: Handler[]): this;
|
|
216
|
+
/**
|
|
217
|
+
* Register an OPTIONS route
|
|
218
|
+
*/
|
|
219
|
+
options(path: string, ...handlers: Handler[]): this;
|
|
220
|
+
/**
|
|
221
|
+
* Register a HEAD route
|
|
222
|
+
*/
|
|
223
|
+
head(path: string, ...handlers: Handler[]): this;
|
|
224
|
+
/**
|
|
225
|
+
* Register a route for all HTTP methods
|
|
226
|
+
*/
|
|
227
|
+
all(path: string, ...handlers: Handler[]): this;
|
|
228
|
+
/**
|
|
229
|
+
* Register global or path-based middleware
|
|
230
|
+
*/
|
|
231
|
+
use(path: string, ...middleware: Middleware[]): this;
|
|
232
|
+
use(...middleware: Middleware[]): this;
|
|
233
|
+
/**
|
|
234
|
+
* Mount a sub-application at a path prefix
|
|
235
|
+
*/
|
|
236
|
+
route(path: string, app: Gravito): this;
|
|
237
|
+
/**
|
|
238
|
+
* Set custom error handler
|
|
239
|
+
*/
|
|
240
|
+
onError(handler: ErrorHandler): this;
|
|
241
|
+
/**
|
|
242
|
+
* Set custom 404 handler
|
|
243
|
+
*/
|
|
244
|
+
notFound(handler: NotFoundHandler): this;
|
|
245
|
+
/**
|
|
246
|
+
* Predictive Route Warming (JIT Optimization)
|
|
247
|
+
*
|
|
248
|
+
* Simulates requests to specified routes to trigger JIT compilation (FTL)
|
|
249
|
+
* before real traffic arrives.
|
|
250
|
+
*
|
|
251
|
+
* @param paths List of paths to warm up (e.g. ['/api/users', '/health'])
|
|
252
|
+
*/
|
|
253
|
+
warmup(paths: string[]): Promise<void>;
|
|
254
|
+
/**
|
|
255
|
+
* Handle an incoming request
|
|
256
|
+
*/
|
|
257
|
+
fetch: (request: Request) => Promise<Response>;
|
|
258
|
+
/**
|
|
259
|
+
* Handle routes with middleware (async path)
|
|
260
|
+
*/
|
|
261
|
+
private handleWithMiddleware;
|
|
262
|
+
/**
|
|
263
|
+
* Handle dynamic routes (Radix Tree lookup)
|
|
264
|
+
*/
|
|
265
|
+
private handleDynamicRoute;
|
|
266
|
+
/**
|
|
267
|
+
* Sync error handler (for ultra-fast path)
|
|
268
|
+
*/
|
|
269
|
+
private handleErrorSync;
|
|
270
|
+
/**
|
|
271
|
+
* Sync 404 handler (for ultra-fast path)
|
|
272
|
+
*/
|
|
273
|
+
private handleNotFoundSync;
|
|
274
|
+
/**
|
|
275
|
+
* Collect middleware for a specific path
|
|
276
|
+
*/
|
|
277
|
+
private collectMiddlewareForPath;
|
|
278
|
+
/**
|
|
279
|
+
* Compile routes for optimization
|
|
280
|
+
*/
|
|
281
|
+
private compileRoutes;
|
|
282
|
+
/**
|
|
283
|
+
* Add a route to the router
|
|
284
|
+
*/
|
|
285
|
+
private addRoute;
|
|
286
|
+
/**
|
|
287
|
+
* Execute middleware chain followed by handler
|
|
288
|
+
*/
|
|
289
|
+
private executeMiddleware;
|
|
290
|
+
/**
|
|
291
|
+
* Handle errors (Async version for dynamic/middleware paths)
|
|
292
|
+
*/
|
|
293
|
+
private handleError;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* @fileoverview AOT (Ahead-of-Time) Router
|
|
298
|
+
*
|
|
299
|
+
* Hybrid routing strategy:
|
|
300
|
+
* - Static routes: O(1) Map lookup
|
|
301
|
+
* - Dynamic routes: Optimized Radix Tree
|
|
302
|
+
*
|
|
303
|
+
* The key optimization is separating static from dynamic routes at registration time,
|
|
304
|
+
* not at match time. This eliminates unnecessary tree traversal for static paths.
|
|
305
|
+
*
|
|
306
|
+
* @module @gravito/core/engine
|
|
307
|
+
*/
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* Route definition for re-playing routes (mounting)
|
|
311
|
+
*/
|
|
312
|
+
interface RouteDefinition {
|
|
313
|
+
method: HttpMethod;
|
|
314
|
+
path: string;
|
|
315
|
+
handler: Handler;
|
|
316
|
+
middleware: Middleware[];
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* AOT Router - Optimized for Bun
|
|
320
|
+
*/
|
|
321
|
+
declare class AOTRouter {
|
|
322
|
+
/** @internal */
|
|
323
|
+
readonly staticRoutes: Map<string, RouteMetadata>;
|
|
324
|
+
private dynamicRouter;
|
|
325
|
+
/** @internal */
|
|
326
|
+
readonly routeDefinitions: RouteDefinition[];
|
|
327
|
+
/** @internal */
|
|
328
|
+
readonly globalMiddleware: Middleware[];
|
|
329
|
+
/** @internal */
|
|
330
|
+
readonly pathMiddleware: Map<string, Middleware[]>;
|
|
331
|
+
private dynamicRoutePatterns;
|
|
332
|
+
private middlewareCache;
|
|
333
|
+
private cacheMaxSize;
|
|
334
|
+
private _version;
|
|
335
|
+
/**
|
|
336
|
+
* Get the current version for cache invalidation
|
|
337
|
+
* Incremented whenever middleware or routes are modified
|
|
338
|
+
*/
|
|
339
|
+
get version(): number;
|
|
340
|
+
/**
|
|
341
|
+
* Register a route
|
|
342
|
+
*
|
|
343
|
+
* Automatically determines if route is static or dynamic.
|
|
344
|
+
* Static routes are stored in a Map for O(1) lookup.
|
|
345
|
+
* Dynamic routes use the Radix Tree.
|
|
346
|
+
*
|
|
347
|
+
* @param method - HTTP method
|
|
348
|
+
* @param path - Route path
|
|
349
|
+
* @param handler - Route handler
|
|
350
|
+
* @param middleware - Route-specific middleware
|
|
351
|
+
*/
|
|
352
|
+
add(method: HttpMethod, path: string, handler: Handler, middleware?: Middleware[]): void;
|
|
353
|
+
/**
|
|
354
|
+
* Mount another router at a prefix
|
|
355
|
+
*/
|
|
356
|
+
mount(prefix: string, other: AOTRouter): void;
|
|
357
|
+
/**
|
|
358
|
+
* Add global middleware
|
|
359
|
+
*
|
|
360
|
+
* These run for every request, before route-specific middleware.
|
|
361
|
+
*
|
|
362
|
+
* @param middleware - Middleware functions
|
|
363
|
+
*/
|
|
364
|
+
use(...middleware: Middleware[]): void;
|
|
365
|
+
/**
|
|
366
|
+
* Add path-based middleware
|
|
367
|
+
*
|
|
368
|
+
* Supports wildcard patterns like '/api/*'
|
|
369
|
+
*
|
|
370
|
+
* @param pattern - Path pattern
|
|
371
|
+
* @param middleware - Middleware functions
|
|
372
|
+
*/
|
|
373
|
+
usePattern(pattern: string, ...middleware: Middleware[]): void;
|
|
374
|
+
/**
|
|
375
|
+
* Match a request to a route
|
|
376
|
+
*
|
|
377
|
+
* Returns the handler, params, and all applicable middleware.
|
|
378
|
+
*
|
|
379
|
+
* @param method - HTTP method
|
|
380
|
+
* @param path - Request path
|
|
381
|
+
* @returns Route match or null if not found
|
|
382
|
+
*/
|
|
383
|
+
match(method: string, path: string): RouteMatch;
|
|
384
|
+
/**
|
|
385
|
+
* Public wrapper for collectMiddleware (used by Gravito for optimization)
|
|
386
|
+
*/
|
|
387
|
+
collectMiddlewarePublic(path: string, routeMiddleware: Middleware[]): Middleware[];
|
|
388
|
+
/**
|
|
389
|
+
* Collect all applicable middleware for a path
|
|
390
|
+
*
|
|
391
|
+
* Order: global -> pattern-based -> route-specific
|
|
392
|
+
*
|
|
393
|
+
* @param path - Request path
|
|
394
|
+
* @param routeMiddleware - Route-specific middleware
|
|
395
|
+
* @returns Combined middleware array
|
|
396
|
+
*/
|
|
397
|
+
private collectMiddleware;
|
|
398
|
+
/**
|
|
399
|
+
* Check if a path is static (no parameters or wildcards)
|
|
400
|
+
*/
|
|
401
|
+
private isStaticPath;
|
|
402
|
+
/**
|
|
403
|
+
* Match a pattern against a path
|
|
404
|
+
*
|
|
405
|
+
* Supports:
|
|
406
|
+
* - Exact match: '/api/users'
|
|
407
|
+
* - Wildcard suffix: '/api/*'
|
|
408
|
+
*
|
|
409
|
+
* @param pattern - Pattern to match
|
|
410
|
+
* @param path - Path to test
|
|
411
|
+
* @returns True if pattern matches
|
|
412
|
+
*/
|
|
413
|
+
private matchPattern;
|
|
414
|
+
/**
|
|
415
|
+
* Get all registered routes (for debugging)
|
|
416
|
+
*/
|
|
417
|
+
getRoutes(): Array<{
|
|
418
|
+
method: string;
|
|
419
|
+
path: string;
|
|
420
|
+
type: 'static' | 'dynamic';
|
|
421
|
+
}>;
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
/**
|
|
425
|
+
* ServiceMap interface for type-safe IoC resolution.
|
|
426
|
+
*
|
|
427
|
+
* Extend this interface via module augmentation to get type inference:
|
|
428
|
+
* @example
|
|
429
|
+
* ```typescript
|
|
430
|
+
* declare module '@gravito/core' {
|
|
431
|
+
* interface ServiceMap {
|
|
432
|
+
* logger: Logger
|
|
433
|
+
* db: DatabaseConnection
|
|
434
|
+
* }
|
|
435
|
+
* }
|
|
436
|
+
* ```
|
|
437
|
+
*/
|
|
438
|
+
type ServiceMap = {};
|
|
439
|
+
/**
|
|
440
|
+
* ServiceKey represents the allowed keys for service resolution.
|
|
441
|
+
* Includes keys from ServiceMap, generic strings, or symbols.
|
|
442
|
+
*/
|
|
443
|
+
type ServiceKey = keyof ServiceMap | (string & {}) | symbol;
|
|
444
|
+
|
|
445
|
+
/**
|
|
446
|
+
* RequestScopeMetrics - Observability for RequestScope lifecycle
|
|
447
|
+
*
|
|
448
|
+
* Tracks cleanup execution time, scope size, and service counts
|
|
449
|
+
* for performance monitoring and diagnostics.
|
|
450
|
+
*
|
|
451
|
+
* @example
|
|
452
|
+
* ```typescript
|
|
453
|
+
* const metrics = new RequestScopeMetrics()
|
|
454
|
+
* metrics.recordCleanupStart()
|
|
455
|
+
* await scope.cleanup()
|
|
456
|
+
* metrics.recordCleanupEnd()
|
|
457
|
+
*
|
|
458
|
+
* console.log(metrics.toJSON())
|
|
459
|
+
* // { cleanupDuration: 2.5, scopeSize: 3, servicesCleaned: 3 }
|
|
460
|
+
* ```
|
|
461
|
+
*/
|
|
462
|
+
declare class RequestScopeMetrics {
|
|
463
|
+
private cleanupStartTime;
|
|
464
|
+
private cleanupDuration;
|
|
465
|
+
private scopeSize;
|
|
466
|
+
private servicesCleaned;
|
|
467
|
+
private errorsOccurred;
|
|
468
|
+
/**
|
|
469
|
+
* Record start of cleanup operation
|
|
470
|
+
*/
|
|
471
|
+
recordCleanupStart(): void;
|
|
472
|
+
/**
|
|
473
|
+
* Record end of cleanup operation
|
|
474
|
+
*
|
|
475
|
+
* @param scopeSize - Number of services in the scope
|
|
476
|
+
* @param servicesCleaned - Number of services that had cleanup called
|
|
477
|
+
* @param errorsOccurred - Number of cleanup errors
|
|
478
|
+
*/
|
|
479
|
+
recordCleanupEnd(scopeSize: number, servicesCleaned: number, errorsOccurred?: number): void;
|
|
480
|
+
/**
|
|
481
|
+
* Get cleanup duration in milliseconds
|
|
482
|
+
*
|
|
483
|
+
* @returns Duration in ms, or null if cleanup not completed
|
|
484
|
+
*/
|
|
485
|
+
getCleanupDuration(): number | null;
|
|
486
|
+
/**
|
|
487
|
+
* Check if cleanup took longer than threshold (default 2ms)
|
|
488
|
+
* Useful for detecting slow cleanups
|
|
489
|
+
*
|
|
490
|
+
* @param thresholdMs - Threshold in milliseconds
|
|
491
|
+
* @returns True if cleanup exceeded threshold
|
|
492
|
+
*/
|
|
493
|
+
isSlowCleanup(thresholdMs?: number): boolean;
|
|
494
|
+
/**
|
|
495
|
+
* Export metrics as JSON for logging/monitoring
|
|
496
|
+
*/
|
|
497
|
+
toJSON(): {
|
|
498
|
+
cleanupDuration: number | null;
|
|
499
|
+
scopeSize: number;
|
|
500
|
+
servicesCleaned: number;
|
|
501
|
+
errorsOccurred: number;
|
|
502
|
+
hasErrors: boolean;
|
|
503
|
+
isSlowCleanup: boolean;
|
|
504
|
+
};
|
|
505
|
+
/**
|
|
506
|
+
* Export metrics as compact string for logging
|
|
507
|
+
*/
|
|
508
|
+
toString(): string;
|
|
509
|
+
}
|
|
510
|
+
/**
|
|
511
|
+
* RequestScopeObserver - Hook for monitoring RequestScope lifecycle
|
|
512
|
+
*
|
|
513
|
+
* Implement this interface to receive callbacks during scope operations
|
|
514
|
+
*/
|
|
515
|
+
interface RequestScopeObserver {
|
|
516
|
+
/**
|
|
517
|
+
* Called when a service is resolved in the scope
|
|
518
|
+
*/
|
|
519
|
+
onServiceResolved?(key: string | symbol, isFromCache: boolean): void;
|
|
520
|
+
/**
|
|
521
|
+
* Called when cleanup starts
|
|
522
|
+
*/
|
|
523
|
+
onCleanupStart?(): void;
|
|
524
|
+
/**
|
|
525
|
+
* Called when cleanup completes
|
|
526
|
+
*/
|
|
527
|
+
onCleanupEnd?(metrics: RequestScopeMetrics): void;
|
|
528
|
+
/**
|
|
529
|
+
* Called when cleanup encounters an error
|
|
530
|
+
*/
|
|
531
|
+
onCleanupError?(error: Error): void;
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
/**
|
|
535
|
+
* Manages request-scoped service instances within a single HTTP request.
|
|
536
|
+
*
|
|
537
|
+
* Each request gets its own RequestScopeManager instance with isolated state.
|
|
538
|
+
* Services are cached within the request and automatically cleaned up when
|
|
539
|
+
* the request ends.
|
|
540
|
+
*
|
|
541
|
+
* @example
|
|
542
|
+
* ```typescript
|
|
543
|
+
* const scope = new RequestScopeManager()
|
|
544
|
+
* const cache = scope.resolve('productCache', () => new ProductCache())
|
|
545
|
+
* // ... use cache ...
|
|
546
|
+
* await scope.cleanup() // Called automatically by Gravito engine
|
|
547
|
+
* ```
|
|
548
|
+
*/
|
|
549
|
+
declare class RequestScopeManager {
|
|
550
|
+
private scoped;
|
|
551
|
+
private metadata;
|
|
552
|
+
private metrics;
|
|
553
|
+
private observer;
|
|
554
|
+
constructor(observer?: RequestScopeObserver);
|
|
555
|
+
/**
|
|
556
|
+
* Set observer for monitoring scope lifecycle
|
|
557
|
+
*/
|
|
558
|
+
setObserver(observer: RequestScopeObserver): void;
|
|
559
|
+
/**
|
|
560
|
+
* Get metrics for this scope
|
|
561
|
+
*/
|
|
562
|
+
getMetrics(): RequestScopeMetrics;
|
|
563
|
+
/**
|
|
564
|
+
* Resolve or retrieve a request-scoped service instance.
|
|
565
|
+
*
|
|
566
|
+
* If the service already exists in this scope, returns the cached instance.
|
|
567
|
+
* Otherwise, calls the factory function to create a new instance and caches it.
|
|
568
|
+
*
|
|
569
|
+
* Automatically detects and records services with cleanup methods.
|
|
570
|
+
*
|
|
571
|
+
* @template T - The type of the service.
|
|
572
|
+
* @param key - The service key (for caching).
|
|
573
|
+
* @param factory - Factory function to create the instance if not cached.
|
|
574
|
+
* @returns The cached or newly created instance.
|
|
575
|
+
*/
|
|
576
|
+
resolve<T>(key: ServiceKey, factory: () => T): T;
|
|
577
|
+
/**
|
|
578
|
+
* Clean up all request-scoped instances.
|
|
579
|
+
*
|
|
580
|
+
* Calls the cleanup() method on each service that has one.
|
|
581
|
+
* Silently ignores cleanup errors to prevent cascading failures.
|
|
582
|
+
* Called automatically by the Gravito engine in the request finally block.
|
|
583
|
+
*
|
|
584
|
+
* @returns Promise that resolves when all cleanup is complete.
|
|
585
|
+
*/
|
|
586
|
+
cleanup(): Promise<void>;
|
|
587
|
+
/**
|
|
588
|
+
* Get the number of services in this scope (for monitoring).
|
|
589
|
+
*
|
|
590
|
+
* @returns The count of cached services.
|
|
591
|
+
*/
|
|
592
|
+
size(): number;
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
/**
|
|
596
|
+
* @fileoverview FastContext - Pooled Request Context
|
|
597
|
+
*
|
|
598
|
+
* Minimal, high-performance context implementation designed for object pooling.
|
|
599
|
+
* Lazy parsing strategy: only parse what's actually accessed.
|
|
600
|
+
*
|
|
601
|
+
* @module @gravito/core/engine
|
|
602
|
+
*/
|
|
603
|
+
|
|
604
|
+
/**
|
|
605
|
+
* Lazy-parsed request wrapper
|
|
606
|
+
*
|
|
607
|
+
* Delays parsing of query params, headers, and body until accessed.
|
|
608
|
+
* This is a key optimization for requests that don't need all data.
|
|
609
|
+
*/
|
|
610
|
+
declare class FastRequestImpl implements FastRequest {
|
|
611
|
+
private _request;
|
|
612
|
+
private _params;
|
|
613
|
+
private _path;
|
|
614
|
+
private _routePattern?;
|
|
615
|
+
private _url;
|
|
616
|
+
private _query;
|
|
617
|
+
private _headers;
|
|
618
|
+
private _cachedJson;
|
|
619
|
+
private _jsonParsed;
|
|
620
|
+
private _cachedText;
|
|
621
|
+
private _textParsed;
|
|
622
|
+
private _cachedFormData;
|
|
623
|
+
private _formDataParsed;
|
|
624
|
+
private _cachedQueries;
|
|
625
|
+
private _ctx;
|
|
626
|
+
constructor(ctx: FastContext);
|
|
627
|
+
/**
|
|
628
|
+
* Initialize for new request
|
|
629
|
+
*/
|
|
630
|
+
init(request: Request, params?: Record<string, string>, path?: string, routePattern?: string): this;
|
|
631
|
+
/**
|
|
632
|
+
* Reset for pooling
|
|
633
|
+
*/
|
|
634
|
+
reset(): void;
|
|
635
|
+
private checkReleased;
|
|
636
|
+
get url(): string;
|
|
637
|
+
get method(): string;
|
|
638
|
+
get path(): string;
|
|
639
|
+
get routePattern(): string | undefined;
|
|
640
|
+
param(name: string): string | undefined;
|
|
641
|
+
params(): Record<string, string>;
|
|
642
|
+
private getUrl;
|
|
643
|
+
query(name: string): string | undefined;
|
|
644
|
+
queries(): Record<string, string | string[]>;
|
|
645
|
+
header(name: string): string | undefined;
|
|
646
|
+
headers(): Record<string, string>;
|
|
647
|
+
json<T = unknown>(): Promise<T>;
|
|
648
|
+
text(): Promise<string>;
|
|
649
|
+
formData(): Promise<FormData>;
|
|
650
|
+
get raw(): Request;
|
|
651
|
+
}
|
|
652
|
+
/**
|
|
653
|
+
* FastContext - Pooled request context
|
|
654
|
+
*
|
|
655
|
+
* Designed for minimal memory allocation and maximum reuse.
|
|
656
|
+
* All response helpers create Response objects directly without intermediate wrappers.
|
|
657
|
+
*/
|
|
658
|
+
declare class FastContext implements FastContext$1 {
|
|
659
|
+
readonly req: FastRequestImpl;
|
|
660
|
+
private _headers;
|
|
661
|
+
_isReleased: boolean;
|
|
662
|
+
private _requestScope;
|
|
663
|
+
/**
|
|
664
|
+
* Initialize context for a new request
|
|
665
|
+
*
|
|
666
|
+
* This is called when acquiring from the pool.
|
|
667
|
+
*/
|
|
668
|
+
init(request: Request, params?: Record<string, string>, path?: string, routePattern?: string): this;
|
|
669
|
+
/**
|
|
670
|
+
* Reset context for pooling (Cleanup)
|
|
671
|
+
*
|
|
672
|
+
* This is called when releasing back to the pool.
|
|
673
|
+
* Implements "Deep-Reset Protocol" and "Release Guard".
|
|
674
|
+
*/
|
|
675
|
+
reset(): void;
|
|
676
|
+
/**
|
|
677
|
+
* Check if context is released
|
|
678
|
+
*/
|
|
679
|
+
private checkReleased;
|
|
680
|
+
json<T>(data: T, status?: number): Response;
|
|
681
|
+
text(text: string, status?: number): Response;
|
|
682
|
+
html(html: string, status?: number): Response;
|
|
683
|
+
redirect(url: string, status?: 301 | 302 | 303 | 307 | 308): Response;
|
|
684
|
+
body(data: BodyInit | null, status?: number): Response;
|
|
685
|
+
stream(stream: ReadableStream, status?: number): Response;
|
|
686
|
+
notFound(message?: string): Response;
|
|
687
|
+
forbidden(message?: string): Response;
|
|
688
|
+
unauthorized(message?: string): Response;
|
|
689
|
+
badRequest(message?: string): Response;
|
|
690
|
+
forward(target: string, _options?: any): Promise<Response>;
|
|
691
|
+
header(name: string): string | undefined;
|
|
692
|
+
header(name: string, value: string): void;
|
|
693
|
+
status(_code: number): void;
|
|
694
|
+
private _store;
|
|
695
|
+
get<T>(key: string): T;
|
|
696
|
+
set(key: string, value: any): void;
|
|
697
|
+
/**
|
|
698
|
+
* Get the request-scoped service manager for this request.
|
|
699
|
+
*
|
|
700
|
+
* @returns The RequestScopeManager for this request.
|
|
701
|
+
* @throws Error if called before init() or after reset().
|
|
702
|
+
*/
|
|
703
|
+
requestScope(): RequestScopeManager;
|
|
704
|
+
/**
|
|
705
|
+
* Resolve a request-scoped service (convenience method).
|
|
706
|
+
*
|
|
707
|
+
* @template T - The service type.
|
|
708
|
+
* @param key - The service key for caching.
|
|
709
|
+
* @param factory - Factory function to create the service.
|
|
710
|
+
* @returns The cached or newly created service instance.
|
|
711
|
+
*/
|
|
712
|
+
scoped<T>(key: string | symbol, factory: () => T): T;
|
|
713
|
+
route: (name: string, params?: any, query?: any) => string;
|
|
714
|
+
get native(): this;
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
/**
|
|
718
|
+
* @fileoverview MinimalContext - Ultra-lightweight Request Context
|
|
719
|
+
*
|
|
720
|
+
* Designed for zero-middleware static routes where pool overhead
|
|
721
|
+
* exceeds the cost of creating a new object.
|
|
722
|
+
*
|
|
723
|
+
* Key difference from FastContext:
|
|
724
|
+
* - No object pooling (direct instantiation is faster for simple cases)
|
|
725
|
+
* - No Headers object reuse (creates inline)
|
|
726
|
+
* - Minimal memory footprint
|
|
727
|
+
*
|
|
728
|
+
* @module @gravito/core/engine
|
|
729
|
+
*/
|
|
730
|
+
|
|
731
|
+
/**
|
|
732
|
+
* Minimal request wrapper
|
|
733
|
+
*/
|
|
734
|
+
declare class MinimalRequest implements FastRequest {
|
|
735
|
+
private readonly _request;
|
|
736
|
+
private readonly _params;
|
|
737
|
+
private readonly _path;
|
|
738
|
+
private readonly _routePattern?;
|
|
739
|
+
private _searchParams;
|
|
740
|
+
private _cachedQueries;
|
|
741
|
+
private _cachedJsonPromise;
|
|
742
|
+
private _cachedTextPromise;
|
|
743
|
+
private _cachedFormDataPromise;
|
|
744
|
+
constructor(_request: Request, _params: Record<string, string>, _path: string, _routePattern?: string | undefined);
|
|
745
|
+
get url(): string;
|
|
746
|
+
get method(): string;
|
|
747
|
+
get path(): string;
|
|
748
|
+
get routePattern(): string | undefined;
|
|
749
|
+
param(name: string): string | undefined;
|
|
750
|
+
params(): Record<string, string>;
|
|
751
|
+
/**
|
|
752
|
+
* Lazy-initialize searchParams, only parse once
|
|
753
|
+
*/
|
|
754
|
+
private getSearchParams;
|
|
755
|
+
query(name: string): string | undefined;
|
|
756
|
+
queries(): Record<string, string | string[]>;
|
|
757
|
+
header(name: string): string | undefined;
|
|
758
|
+
headers(): Record<string, string>;
|
|
759
|
+
json<T = unknown>(): Promise<T>;
|
|
760
|
+
text(): Promise<string>;
|
|
761
|
+
formData(): Promise<FormData>;
|
|
762
|
+
get raw(): Request;
|
|
763
|
+
}
|
|
764
|
+
/**
|
|
765
|
+
* MinimalContext - Optimized for simple, fast responses
|
|
766
|
+
*
|
|
767
|
+
* Use when:
|
|
768
|
+
* - No middleware
|
|
769
|
+
* - Static routes
|
|
770
|
+
* - Simple JSON/text responses
|
|
771
|
+
* - No custom headers needed
|
|
772
|
+
*/
|
|
773
|
+
declare class MinimalContext implements FastContext$1 {
|
|
774
|
+
readonly req: MinimalRequest;
|
|
775
|
+
private _resHeaders;
|
|
776
|
+
private _requestScope;
|
|
777
|
+
constructor(request: Request, params: Record<string, string>, path: string, routePattern?: string);
|
|
778
|
+
private getHeaders;
|
|
779
|
+
json<T>(data: T, status?: number): Response;
|
|
780
|
+
text(text: string, status?: number): Response;
|
|
781
|
+
html(html: string, status?: number): Response;
|
|
782
|
+
redirect(url: string, status?: 301 | 302 | 303 | 307 | 308): Response;
|
|
783
|
+
body(data: BodyInit | null, status?: number): Response;
|
|
784
|
+
header(name: string): string | undefined;
|
|
785
|
+
header(name: string, value: string): void;
|
|
786
|
+
status(_code: number): void;
|
|
787
|
+
stream(stream: ReadableStream, status?: number): Response;
|
|
788
|
+
notFound(message?: string): Response;
|
|
789
|
+
forbidden(message?: string): Response;
|
|
790
|
+
unauthorized(message?: string): Response;
|
|
791
|
+
badRequest(message?: string): Response;
|
|
792
|
+
forward(target: string, _options?: any): Promise<Response>;
|
|
793
|
+
get<T>(_key: string): T;
|
|
794
|
+
set(_key: string, _value: any): void;
|
|
795
|
+
/**
|
|
796
|
+
* Get the request-scoped service manager for this request.
|
|
797
|
+
*
|
|
798
|
+
* @returns The RequestScopeManager for this request.
|
|
799
|
+
*/
|
|
800
|
+
requestScope(): RequestScopeManager;
|
|
801
|
+
/**
|
|
802
|
+
* Resolve a request-scoped service (convenience method).
|
|
803
|
+
*
|
|
804
|
+
* @template T - The service type.
|
|
805
|
+
* @param key - The service key for caching.
|
|
806
|
+
* @param factory - Factory function to create the service.
|
|
807
|
+
* @returns The cached or newly created service instance.
|
|
808
|
+
*/
|
|
809
|
+
scoped<T>(key: string | symbol, factory: () => T): T;
|
|
810
|
+
route: (name: string, params?: any, query?: any) => string;
|
|
811
|
+
get native(): this;
|
|
812
|
+
init(_request: Request, _params?: Record<string, string>, _path?: string): this;
|
|
813
|
+
reset(): void;
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
/**
|
|
817
|
+
* @fileoverview Lightweight Path Utilities
|
|
818
|
+
*
|
|
819
|
+
* High-performance path extraction without creating URL objects.
|
|
820
|
+
* Performance critical - every optimization matters.
|
|
821
|
+
*
|
|
822
|
+
* @module @gravito/core/engine
|
|
823
|
+
*/
|
|
824
|
+
/**
|
|
825
|
+
* Extract pathname from URL string without creating URL object
|
|
826
|
+
*
|
|
827
|
+
* @param url - Full URL string (e.g., "http://localhost:3000/api/users?id=1")
|
|
828
|
+
* @returns pathname (e.g., "/api/users")
|
|
829
|
+
*
|
|
830
|
+
* @example
|
|
831
|
+
* ```typescript
|
|
832
|
+
* extractPath("http://localhost:3000/api/users?id=1") // "/api/users"
|
|
833
|
+
* extractPath("https://example.com/") // "/"
|
|
834
|
+
* ```
|
|
835
|
+
*/
|
|
836
|
+
declare function extractPath(url: string): string;
|
|
837
|
+
|
|
838
|
+
/**
|
|
839
|
+
* @fileoverview Generic Object Pool Implementation
|
|
840
|
+
*
|
|
841
|
+
* High-performance object pooling to reduce GC pressure.
|
|
842
|
+
* Implements "fixed pool + overflow fallback" strategy.
|
|
843
|
+
*
|
|
844
|
+
* @module @gravito/core/engine
|
|
845
|
+
*/
|
|
846
|
+
/**
|
|
847
|
+
* Generic object pool with fixed size and overflow handling
|
|
848
|
+
*
|
|
849
|
+
* @typeParam T - Type of objects to pool
|
|
850
|
+
*
|
|
851
|
+
* @example
|
|
852
|
+
* ```typescript
|
|
853
|
+
* const pool = new ObjectPool(
|
|
854
|
+
* () => new MyObject(),
|
|
855
|
+
* (obj) => obj.reset(),
|
|
856
|
+
* 256
|
|
857
|
+
* )
|
|
858
|
+
*
|
|
859
|
+
* const obj = pool.acquire()
|
|
860
|
+
* try {
|
|
861
|
+
* // Use object
|
|
862
|
+
* } finally {
|
|
863
|
+
* pool.release(obj)
|
|
864
|
+
* }
|
|
865
|
+
* ```
|
|
866
|
+
*/
|
|
867
|
+
declare class ObjectPool<T> {
|
|
868
|
+
private pool;
|
|
869
|
+
private readonly factory;
|
|
870
|
+
private readonly reset;
|
|
871
|
+
private readonly maxSize;
|
|
872
|
+
/**
|
|
873
|
+
* Create a new object pool
|
|
874
|
+
*
|
|
875
|
+
* @param factory - Function to create new objects
|
|
876
|
+
* @param reset - Function to reset objects before reuse
|
|
877
|
+
* @param maxSize - Maximum pool size (default: 256)
|
|
878
|
+
*/
|
|
879
|
+
constructor(factory: () => T, reset: (obj: T) => void, maxSize?: number);
|
|
880
|
+
/**
|
|
881
|
+
* Acquire an object from the pool
|
|
882
|
+
*
|
|
883
|
+
* If the pool is empty, creates a new object (overflow strategy).
|
|
884
|
+
* This ensures the pool never blocks under high load.
|
|
885
|
+
*
|
|
886
|
+
* @returns Object from pool or newly created
|
|
887
|
+
*/
|
|
888
|
+
acquire(): T;
|
|
889
|
+
/**
|
|
890
|
+
* Release an object back to the pool
|
|
891
|
+
*
|
|
892
|
+
* If the pool is full, the object is discarded (will be GC'd).
|
|
893
|
+
* This prevents unbounded memory growth.
|
|
894
|
+
*
|
|
895
|
+
* @param obj - Object to release
|
|
896
|
+
*/
|
|
897
|
+
release(obj: T): void;
|
|
898
|
+
/**
|
|
899
|
+
* Clear all objects from the pool
|
|
900
|
+
*
|
|
901
|
+
* Useful for testing or when you need to force a clean slate.
|
|
902
|
+
*/
|
|
903
|
+
clear(): void;
|
|
904
|
+
/**
|
|
905
|
+
* Get current pool size
|
|
906
|
+
*/
|
|
907
|
+
get size(): number;
|
|
908
|
+
/**
|
|
909
|
+
* Get maximum pool size
|
|
910
|
+
*/
|
|
911
|
+
get capacity(): number;
|
|
912
|
+
/**
|
|
913
|
+
* Pre-warm the pool by creating objects in advance
|
|
914
|
+
*
|
|
915
|
+
* This can reduce latency for the first N requests.
|
|
916
|
+
*
|
|
917
|
+
* @param count - Number of objects to pre-create
|
|
918
|
+
*/
|
|
919
|
+
prewarm(count: number): void;
|
|
920
|
+
}
|
|
921
|
+
|
|
922
|
+
export { AOTRouter, type EngineOptions, type ErrorHandler, type FastContext$1 as FastContext, FastContext as FastContextImpl, type FastRequest, Gravito, type Handler, type Middleware, MinimalContext, type NotFoundHandler, ObjectPool, type RouteMatch, extractPath };
|