@gravito/core 1.6.0 → 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.
@@ -52,6 +52,9 @@ interface FastContext$1 {
52
52
  /** Context Variables */
53
53
  get<T>(key: string): T;
54
54
  set(key: string, value: any): void;
55
+ /** Request Scope Management */
56
+ requestScope(): any;
57
+ scoped<T>(key: string | symbol, factory: () => T): T;
55
58
  /** Lifecycle helpers */
56
59
  route: (name: string, params?: any, query?: any) => string;
57
60
  readonly native: any;
@@ -180,7 +183,6 @@ declare class Gravito {
180
183
  staticRoutes: Map<string, RouteMetadata>;
181
184
  private isPureStaticApp;
182
185
  private compiledDynamicRoutes;
183
- private middlewareVersion;
184
186
  /**
185
187
  * Create a new Gravito instance
186
188
  *
@@ -329,7 +331,12 @@ declare class AOTRouter {
329
331
  private dynamicRoutePatterns;
330
332
  private middlewareCache;
331
333
  private cacheMaxSize;
332
- private version;
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;
333
340
  /**
334
341
  * Register a route
335
342
  *
@@ -414,6 +421,177 @@ declare class AOTRouter {
414
421
  }>;
415
422
  }
416
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
+
417
595
  /**
418
596
  * @fileoverview FastContext - Pooled Request Context
419
597
  *
@@ -439,6 +617,11 @@ declare class FastRequestImpl implements FastRequest {
439
617
  private _headers;
440
618
  private _cachedJson;
441
619
  private _jsonParsed;
620
+ private _cachedText;
621
+ private _textParsed;
622
+ private _cachedFormData;
623
+ private _formDataParsed;
624
+ private _cachedQueries;
442
625
  private _ctx;
443
626
  constructor(ctx: FastContext);
444
627
  /**
@@ -476,6 +659,7 @@ declare class FastContext implements FastContext$1 {
476
659
  readonly req: FastRequestImpl;
477
660
  private _headers;
478
661
  _isReleased: boolean;
662
+ private _requestScope;
479
663
  /**
480
664
  * Initialize context for a new request
481
665
  *
@@ -510,6 +694,22 @@ declare class FastContext implements FastContext$1 {
510
694
  private _store;
511
695
  get<T>(key: string): T;
512
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;
513
713
  route: (name: string, params?: any, query?: any) => string;
514
714
  get native(): this;
515
715
  }
@@ -537,6 +737,10 @@ declare class MinimalRequest implements FastRequest {
537
737
  private readonly _path;
538
738
  private readonly _routePattern?;
539
739
  private _searchParams;
740
+ private _cachedQueries;
741
+ private _cachedJsonPromise;
742
+ private _cachedTextPromise;
743
+ private _cachedFormDataPromise;
540
744
  constructor(_request: Request, _params: Record<string, string>, _path: string, _routePattern?: string | undefined);
541
745
  get url(): string;
542
746
  get method(): string;
@@ -569,6 +773,7 @@ declare class MinimalRequest implements FastRequest {
569
773
  declare class MinimalContext implements FastContext$1 {
570
774
  readonly req: MinimalRequest;
571
775
  private _resHeaders;
776
+ private _requestScope;
572
777
  constructor(request: Request, params: Record<string, string>, path: string, routePattern?: string);
573
778
  private getHeaders;
574
779
  json<T>(data: T, status?: number): Response;
@@ -587,6 +792,21 @@ declare class MinimalContext implements FastContext$1 {
587
792
  forward(target: string, _options?: any): Promise<Response>;
588
793
  get<T>(_key: string): T;
589
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;
590
810
  route: (name: string, params?: any, query?: any) => string;
591
811
  get native(): this;
592
812
  init(_request: Request, _params?: Record<string, string>, _path?: string): this;
@@ -52,6 +52,9 @@ interface FastContext$1 {
52
52
  /** Context Variables */
53
53
  get<T>(key: string): T;
54
54
  set(key: string, value: any): void;
55
+ /** Request Scope Management */
56
+ requestScope(): any;
57
+ scoped<T>(key: string | symbol, factory: () => T): T;
55
58
  /** Lifecycle helpers */
56
59
  route: (name: string, params?: any, query?: any) => string;
57
60
  readonly native: any;
@@ -180,7 +183,6 @@ declare class Gravito {
180
183
  staticRoutes: Map<string, RouteMetadata>;
181
184
  private isPureStaticApp;
182
185
  private compiledDynamicRoutes;
183
- private middlewareVersion;
184
186
  /**
185
187
  * Create a new Gravito instance
186
188
  *
@@ -329,7 +331,12 @@ declare class AOTRouter {
329
331
  private dynamicRoutePatterns;
330
332
  private middlewareCache;
331
333
  private cacheMaxSize;
332
- private version;
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;
333
340
  /**
334
341
  * Register a route
335
342
  *
@@ -414,6 +421,177 @@ declare class AOTRouter {
414
421
  }>;
415
422
  }
416
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
+
417
595
  /**
418
596
  * @fileoverview FastContext - Pooled Request Context
419
597
  *
@@ -439,6 +617,11 @@ declare class FastRequestImpl implements FastRequest {
439
617
  private _headers;
440
618
  private _cachedJson;
441
619
  private _jsonParsed;
620
+ private _cachedText;
621
+ private _textParsed;
622
+ private _cachedFormData;
623
+ private _formDataParsed;
624
+ private _cachedQueries;
442
625
  private _ctx;
443
626
  constructor(ctx: FastContext);
444
627
  /**
@@ -476,6 +659,7 @@ declare class FastContext implements FastContext$1 {
476
659
  readonly req: FastRequestImpl;
477
660
  private _headers;
478
661
  _isReleased: boolean;
662
+ private _requestScope;
479
663
  /**
480
664
  * Initialize context for a new request
481
665
  *
@@ -510,6 +694,22 @@ declare class FastContext implements FastContext$1 {
510
694
  private _store;
511
695
  get<T>(key: string): T;
512
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;
513
713
  route: (name: string, params?: any, query?: any) => string;
514
714
  get native(): this;
515
715
  }
@@ -537,6 +737,10 @@ declare class MinimalRequest implements FastRequest {
537
737
  private readonly _path;
538
738
  private readonly _routePattern?;
539
739
  private _searchParams;
740
+ private _cachedQueries;
741
+ private _cachedJsonPromise;
742
+ private _cachedTextPromise;
743
+ private _cachedFormDataPromise;
540
744
  constructor(_request: Request, _params: Record<string, string>, _path: string, _routePattern?: string | undefined);
541
745
  get url(): string;
542
746
  get method(): string;
@@ -569,6 +773,7 @@ declare class MinimalRequest implements FastRequest {
569
773
  declare class MinimalContext implements FastContext$1 {
570
774
  readonly req: MinimalRequest;
571
775
  private _resHeaders;
776
+ private _requestScope;
572
777
  constructor(request: Request, params: Record<string, string>, path: string, routePattern?: string);
573
778
  private getHeaders;
574
779
  json<T>(data: T, status?: number): Response;
@@ -587,6 +792,21 @@ declare class MinimalContext implements FastContext$1 {
587
792
  forward(target: string, _options?: any): Promise<Response>;
588
793
  get<T>(_key: string): T;
589
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;
590
810
  route: (name: string, params?: any, query?: any) => string;
591
811
  get native(): this;
592
812
  init(_request: Request, _params?: Record<string, string>, _path?: string): this;