@gravito/core 1.6.1 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +100 -6
- package/README.zh-TW.md +101 -6
- package/dist/Application.d.ts +256 -0
- package/dist/CommandKernel.d.ts +33 -0
- package/dist/ConfigManager.d.ts +65 -0
- package/dist/Container/RequestScopeManager.d.ts +62 -0
- package/dist/Container/RequestScopeMetrics.d.ts +144 -0
- package/dist/Container.d.ts +153 -0
- package/dist/ErrorHandler.d.ts +66 -0
- package/dist/Event.d.ts +5 -0
- package/dist/EventManager.d.ts +123 -0
- package/dist/GlobalErrorHandlers.d.ts +47 -0
- package/dist/GravitoServer.d.ts +28 -0
- package/dist/HookManager.d.ts +435 -0
- package/dist/Listener.d.ts +4 -0
- package/dist/Logger.d.ts +20 -0
- package/dist/PlanetCore.d.ts +402 -0
- package/dist/RequestContext.d.ts +97 -0
- package/dist/Route.d.ts +36 -0
- package/dist/Router.d.ts +270 -0
- package/dist/ServiceProvider.d.ts +178 -0
- package/dist/adapters/GravitoEngineAdapter.d.ts +27 -0
- package/dist/adapters/bun/AdaptiveAdapter.d.ts +99 -0
- package/dist/adapters/bun/BunContext.d.ts +54 -0
- package/dist/adapters/bun/BunNativeAdapter.d.ts +66 -0
- package/dist/adapters/bun/BunRequest.d.ts +31 -0
- package/dist/adapters/bun/BunWebSocketHandler.d.ts +48 -0
- package/dist/adapters/bun/RadixNode.d.ts +19 -0
- package/dist/adapters/bun/RadixRouter.d.ts +32 -0
- package/dist/adapters/bun/index.d.ts +7 -0
- package/dist/adapters/bun/types.d.ts +20 -0
- package/dist/adapters/index.d.ts +12 -0
- package/dist/adapters/types.d.ts +235 -0
- package/dist/binary/BinaryUtils.d.ts +105 -0
- package/dist/binary/index.d.ts +5 -0
- package/dist/cli/queue-commands.d.ts +6 -0
- package/dist/compat/async-local-storage.browser.d.ts +9 -0
- package/dist/compat/async-local-storage.d.ts +7 -0
- package/dist/compat/crypto.browser.d.ts +5 -0
- package/dist/compat/crypto.d.ts +6 -0
- package/dist/compat.cjs +42 -11
- package/dist/compat.cjs.map +9 -0
- package/dist/compat.d.ts +23 -1
- package/dist/compat.js +3 -0
- package/dist/compat.js.map +9 -0
- package/dist/engine/AOTRouter.d.ts +139 -0
- package/dist/engine/FastContext.d.ts +141 -0
- package/dist/engine/Gravito.d.ts +131 -0
- package/dist/engine/MinimalContext.d.ts +102 -0
- package/dist/engine/analyzer.d.ts +113 -0
- package/dist/engine/constants.d.ts +23 -0
- package/dist/engine/index.cjs +576 -647
- package/dist/engine/index.cjs.map +22 -0
- package/dist/engine/index.d.ts +14 -910
- package/dist/engine/index.js +576 -623
- package/dist/engine/index.js.map +22 -0
- package/dist/engine/path.d.ts +26 -0
- package/dist/engine/pool.d.ts +83 -0
- package/dist/engine/types.d.ts +149 -0
- package/dist/error-handling/RequestScopeErrorContext.d.ts +126 -0
- package/dist/events/BackpressureManager.d.ts +215 -0
- package/dist/events/CircuitBreaker.d.ts +229 -0
- package/dist/events/DeadLetterQueue.d.ts +219 -0
- package/dist/events/EventBackend.d.ts +12 -0
- package/dist/events/EventOptions.d.ts +204 -0
- package/dist/events/EventPriorityQueue.d.ts +63 -0
- package/dist/events/FlowControlStrategy.d.ts +109 -0
- package/dist/events/IdempotencyCache.d.ts +60 -0
- package/dist/events/MessageQueueBridge.d.ts +184 -0
- package/dist/events/PriorityEscalationManager.d.ts +82 -0
- package/dist/events/RetryScheduler.d.ts +104 -0
- package/dist/events/WorkerPool.d.ts +98 -0
- package/dist/events/WorkerPoolConfig.d.ts +153 -0
- package/dist/events/WorkerPoolMetrics.d.ts +65 -0
- package/dist/events/aggregation/AggregationWindow.d.ts +77 -0
- package/dist/events/aggregation/DeduplicationManager.d.ts +135 -0
- package/dist/events/aggregation/EventAggregationManager.d.ts +108 -0
- package/dist/events/aggregation/EventBatcher.d.ts +99 -0
- package/dist/events/aggregation/index.d.ts +10 -0
- package/dist/events/aggregation/types.d.ts +117 -0
- package/dist/events/index.d.ts +26 -0
- package/dist/events/observability/EventMetrics.d.ts +132 -0
- package/dist/events/observability/EventTracer.d.ts +68 -0
- package/dist/events/observability/EventTracing.d.ts +161 -0
- package/dist/events/observability/OTelEventMetrics.d.ts +332 -0
- package/dist/events/observability/ObservableHookManager.d.ts +108 -0
- package/dist/events/observability/StreamWorkerMetrics.d.ts +76 -0
- package/dist/events/observability/index.d.ts +24 -0
- package/dist/events/observability/metrics-types.d.ts +16 -0
- package/dist/events/queue-core.d.ts +77 -0
- package/dist/events/task-executor.d.ts +51 -0
- package/dist/events/types.d.ts +134 -0
- package/dist/exceptions/AuthenticationException.d.ts +8 -0
- package/dist/exceptions/AuthorizationException.d.ts +8 -0
- package/dist/exceptions/CircularDependencyException.d.ts +9 -0
- package/dist/exceptions/GravitoException.d.ts +23 -0
- package/dist/exceptions/HttpException.d.ts +9 -0
- package/dist/exceptions/ModelNotFoundException.d.ts +10 -0
- package/dist/exceptions/ValidationException.d.ts +22 -0
- package/dist/exceptions/index.d.ts +7 -0
- package/dist/ffi/NativeAccelerator.d.ts +69 -0
- package/dist/ffi/NativeHasher.d.ts +139 -0
- package/dist/ffi/cbor-fallback.d.ts +96 -0
- package/dist/ffi/hash-fallback.d.ts +33 -0
- package/dist/ffi/index.cjs +621 -0
- package/dist/ffi/index.cjs.map +14 -0
- package/dist/ffi/index.d.ts +10 -0
- package/dist/ffi/index.js +602 -0
- package/dist/ffi/index.js.map +14 -0
- package/dist/ffi/types.d.ts +135 -0
- package/dist/health/HealthProvider.d.ts +67 -0
- package/dist/helpers/Arr.d.ts +19 -0
- package/dist/helpers/Str.d.ts +38 -0
- package/dist/helpers/data.d.ts +25 -0
- package/dist/helpers/errors.d.ts +34 -0
- package/dist/helpers/response.d.ts +41 -0
- package/dist/helpers.d.ts +338 -0
- package/dist/hooks/ActionManager.d.ts +132 -0
- package/dist/hooks/AsyncDetector.d.ts +84 -0
- package/dist/hooks/FilterManager.d.ts +71 -0
- package/dist/hooks/MigrationWarner.d.ts +24 -0
- package/dist/hooks/dlq-operations.d.ts +60 -0
- package/dist/hooks/index.d.ts +11 -0
- package/dist/hooks/types.d.ts +107 -0
- package/dist/http/CookieJar.d.ts +51 -0
- package/dist/http/cookie.d.ts +29 -0
- package/dist/http/index.d.ts +12 -0
- package/dist/{compat-CI8hiulX.d.cts → http/types.d.ts} +29 -16
- package/dist/index.browser.d.ts +34 -0
- package/dist/index.cjs +10525 -11171
- package/dist/index.cjs.map +168 -0
- package/dist/index.d.ts +58 -10981
- package/dist/index.js +10861 -10997
- package/dist/index.js.map +168 -0
- package/dist/observability/QueueDashboard.d.ts +136 -0
- package/dist/observability/contracts.d.ts +137 -0
- package/dist/observability/index.d.ts +13 -0
- package/dist/reliability/DeadLetterQueueManager.d.ts +349 -0
- package/dist/reliability/RetryPolicy.d.ts +217 -0
- package/dist/reliability/index.d.ts +6 -0
- package/dist/router/ControllerDispatcher.d.ts +12 -0
- package/dist/router/RequestValidator.d.ts +20 -0
- package/dist/runtime/adapter-bun.d.ts +12 -0
- package/dist/runtime/adapter-deno.d.ts +12 -0
- package/dist/runtime/adapter-node.d.ts +12 -0
- package/dist/runtime/adapter-unknown.d.ts +13 -0
- package/dist/runtime/archive.d.ts +17 -0
- package/dist/runtime/compression.d.ts +21 -0
- package/dist/runtime/deep-equals.d.ts +56 -0
- package/dist/runtime/detection.d.ts +22 -0
- package/dist/runtime/escape.d.ts +34 -0
- package/dist/runtime/index.browser.d.ts +20 -0
- package/dist/runtime/index.d.ts +44 -0
- package/dist/runtime/markdown.d.ts +44 -0
- package/dist/runtime/types.d.ts +436 -0
- package/dist/runtime-helpers.d.ts +67 -0
- package/dist/runtime.d.ts +11 -0
- package/dist/security/Encrypter.d.ts +33 -0
- package/dist/security/Hasher.d.ts +29 -0
- package/dist/testing/HttpTester.d.ts +39 -0
- package/dist/testing/TestResponse.d.ts +78 -0
- package/dist/testing/index.d.ts +2 -0
- package/dist/transpiler-utils.d.ts +170 -0
- package/dist/types/events.d.ts +94 -0
- package/dist/types.d.ts +13 -0
- package/package.json +21 -52
- package/src/ffi/native/cbor.c +1148 -0
- package/dist/Metrics-VOWWRNNR.js +0 -219
- package/dist/chunk-R5U7XKVJ.js +0 -16
- package/dist/compat-CI8hiulX.d.ts +0 -376
- package/dist/compat.d.cts +0 -1
- package/dist/engine/index.d.cts +0 -922
- package/dist/index.d.cts +0 -11008
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/adapters/bun/RadixNode.ts", "../src/adapters/bun/RadixRouter.ts", "../src/engine/AOTRouter.ts", "../src/transpiler-utils.ts", "../src/engine/analyzer.ts", "../src/engine/constants.ts", "../src/Container/RequestScopeMetrics.ts", "../src/Container/RequestScopeManager.ts", "../src/engine/FastContext.ts", "../src/engine/MinimalContext.ts", "../src/engine/path.ts", "../src/engine/pool.ts", "../src/engine/Gravito.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import type { HttpMethod } from '../../http/types'\nimport { NodeType, type RouteHandler } from './types'\n\n/**\n * Node in the Radix Router tree.\n * @internal\n */\nexport class RadixNode {\n // Path segment for this node (e.g., \"users\", \":id\")\n public segment: string\n\n // Node type (Static, Param, Wildcard)\n public type: NodeType\n\n // Children nodes (mapped by segment for fast lookup)\n public children: Map<string, RadixNode> = new Map()\n\n // Specialized child for parameter node (only one per level allowed usually to avoid ambiguity, though some routers support multiple)\n public paramChild: RadixNode | null = null\n\n // Specialized child for wildcard node\n public wildcardChild: RadixNode | null = null\n\n // Handlers registered at this node (keyed by HTTP method)\n public handlers: Map<HttpMethod, RouteHandler[]> = new Map()\n\n // Parameter name if this is a PARAM node (e.g., \"id\" for \":id\")\n public paramName: string | null = null\n\n // Parameter constraints (regex) - only applicable if this is a PARAM node\n // If we support per-route constraints, they might need to be stored differently,\n // but for now assume constraints are defined at node level (uncommon) or checked at match time.\n // Laravel allows global pattern constraints or per-route.\n // Ideally, constraints should be stored with the handler or part of matching logic.\n // For a Radix tree, if we have constraints, we might need to backtrack if constraint fails?\n // Or simply store constraint with the param node.\n public regex: RegExp | null = null\n\n constructor(segment = '', type: NodeType = NodeType.STATIC) {\n this.segment = segment\n this.type = type\n }\n\n toJSON(): any {\n return {\n segment: this.segment,\n type: this.type,\n children: Array.from(this.children.entries()).map(([k, v]) => [k, v.toJSON()]),\n paramChild: this.paramChild?.toJSON() || null,\n wildcardChild: this.wildcardChild?.toJSON() || null,\n paramName: this.paramName,\n regex: this.regex ? this.regex.source : null,\n }\n }\n\n static fromJSON(json: any): RadixNode {\n const node = new RadixNode(json.segment, json.type)\n node.paramName = json.paramName\n if (json.regex) {\n node.regex = new RegExp(json.regex)\n }\n if (json.children) {\n for (const [key, childJson] of json.children) {\n node.children.set(key, RadixNode.fromJSON(childJson))\n }\n }\n if (json.paramChild) {\n node.paramChild = RadixNode.fromJSON(json.paramChild)\n }\n if (json.wildcardChild) {\n node.wildcardChild = RadixNode.fromJSON(json.wildcardChild)\n }\n return node\n }\n}\n",
|
|
6
|
+
"import type { HttpMethod } from '../../http/types'\nimport { RadixNode } from './RadixNode'\nimport { NodeType, type RouteHandler, type RouteMatch } from './types'\n\n/**\n * Simple LRU Cache for route matching\n * @internal\n */\nclass RouteCache {\n private cache = new Map<string, RouteMatch | null>()\n private readonly maxSize = 10000\n\n get(key: string): RouteMatch | null | undefined {\n return this.cache.get(key)\n }\n\n set(key: string, value: RouteMatch | null): void {\n if (this.cache.size >= this.maxSize) {\n // Remove first (oldest) entry\n const firstKey = this.cache.keys().next().value\n if (firstKey) {\n this.cache.delete(firstKey)\n }\n }\n this.cache.set(key, value)\n }\n\n clear(): void {\n this.cache.clear()\n }\n\n has(key: string): boolean {\n return this.cache.has(key)\n }\n}\n\n/**\n * High-performance Radix Tree Router for Bun\n */\nexport class RadixRouter {\n private root: RadixNode = new RadixNode()\n\n // Global parameter constraints (e.g., id => /^\\d+$/)\n private globalConstraints: Map<string, RegExp> = new Map()\n\n // Route cache (P2 optimization)\n private routeCache = new RouteCache()\n\n /**\n * Add a generic parameter constraint\n */\n where(param: string, regex: RegExp): void {\n this.globalConstraints.set(param, regex)\n }\n\n /**\n * Register a route\n */\n add(method: HttpMethod, path: string, handlers: RouteHandler[]): void {\n let node = this.root\n const segments = this.splitPath(path)\n\n for (let i = 0; i < segments.length; i++) {\n const segment = segments[i]!\n\n // Determine node type\n if (segment === '*') {\n // Wildcard\n if (!node.wildcardChild) {\n node.wildcardChild = new RadixNode('*', NodeType.WILDCARD)\n }\n node = node.wildcardChild\n break\n } else if (segment.startsWith(':')) {\n // Parameter\n const paramName = segment.slice(1)\n if (!node.paramChild) {\n const child = new RadixNode(segment, NodeType.PARAM)\n child.paramName = paramName\n // Apply global constraint if exists\n const constraint = this.globalConstraints.get(paramName)\n if (constraint) {\n child.regex = constraint\n }\n node.paramChild = child\n }\n node = node.paramChild!\n } else {\n // Static\n if (!node.children.has(segment)) {\n node.children.set(segment, new RadixNode(segment, NodeType.STATIC))\n }\n node = node.children.get(segment)!\n }\n }\n\n // Ensure we store handlers for lowercase method\n node.handlers.set(method.toLowerCase() as HttpMethod, handlers)\n\n // P2 optimization: Clear cache when new route added\n this.routeCache.clear()\n }\n\n /**\n * Match a request\n */\n match(method: string, path: string): RouteMatch | null {\n const normalizedMethod = method.toLowerCase() as HttpMethod\n\n // Fast path for root\n if (path === '/' || path === '') {\n const handlers = this.root.handlers.get(normalizedMethod)\n if (handlers) {\n return { handlers, params: {} }\n }\n return null\n }\n\n // P2 optimization: Check route cache first\n const cacheKey = `${normalizedMethod}:${path}`\n if (this.routeCache.has(cacheKey)) {\n return this.routeCache.get(cacheKey) ?? null\n }\n\n // Removing leading slash for faster segmenting\n const searchPath = path.startsWith('/') ? path.slice(1) : path\n const segments = searchPath.split('/')\n\n const result = this.matchRecursive(this.root, segments, 0, {}, normalizedMethod)\n\n // P2 optimization: Cache the result\n this.routeCache.set(cacheKey, result)\n\n return result\n }\n\n private matchRecursive(\n node: RadixNode,\n segments: string[],\n depth: number,\n params: Record<string, string>,\n method: HttpMethod\n ): RouteMatch | null {\n // 1. Check if we reached end of path\n if (depth >= segments.length) {\n let handlers = node.handlers.get(method)\n if (!handlers) {\n handlers = node.handlers.get('all' as HttpMethod)\n }\n if (handlers) {\n return { handlers, params }\n }\n return null\n }\n\n const segment = segments[depth]!\n\n // 2. Try Static Match\n const staticChild = node.children.get(segment)\n if (staticChild) {\n const match = this.matchRecursive(staticChild, segments, depth + 1, params, method)\n if (match) {\n return match\n }\n }\n\n // 3. Try Param Match\n const paramChild = node.paramChild\n if (paramChild) {\n // Check constraints\n if (paramChild.regex && !paramChild.regex.test(segment)) {\n // Constraint failed, continue to wildcard\n } else {\n // Capture param\n if (paramChild.paramName) {\n params[paramChild.paramName] = decodeURIComponent(segment)\n const match = this.matchRecursive(paramChild, segments, depth + 1, params, method)\n if (match) {\n return match\n }\n // Backtrack\n delete params[paramChild.paramName]\n }\n }\n }\n\n // 4. Try Wildcard Match\n if (node.wildcardChild) {\n let handlers = node.wildcardChild.handlers.get(method)\n if (!handlers) {\n handlers = node.wildcardChild.handlers.get('all' as HttpMethod)\n }\n if (handlers) {\n return { handlers, params }\n }\n }\n\n return null\n }\n\n private splitPath(path: string): string[] {\n if (path === '/' || path === '') {\n return []\n }\n let p = path\n if (p.startsWith('/')) {\n p = p.slice(1)\n }\n if (p.endsWith('/')) {\n p = p.slice(0, -1)\n }\n return p.split('/')\n }\n\n /**\n * Serialize the router to a JSON string\n */\n serialize(): string {\n return JSON.stringify({\n root: this.root.toJSON(),\n globalConstraints: Array.from(this.globalConstraints.entries()).map(([k, v]) => [\n k,\n v.source,\n ]),\n })\n }\n\n /**\n * Restore a router from a serialized JSON string\n */\n static fromSerialized(json: string): RadixRouter {\n const data = JSON.parse(json)\n const router = new RadixRouter()\n\n router.root = RadixNode.fromJSON(data.root)\n\n if (data.globalConstraints) {\n for (const [key, source] of data.globalConstraints) {\n router.globalConstraints.set(key, new RegExp(source))\n }\n }\n\n return router\n }\n}\n",
|
|
7
|
+
"/**\n * @fileoverview AOT (Ahead-of-Time) Router\n *\n * Hybrid routing strategy:\n * - Static routes: O(1) Map lookup\n * - Dynamic routes: Optimized Radix Tree\n *\n * The key optimization is separating static from dynamic routes at registration time,\n * not at match time. This eliminates unnecessary tree traversal for static paths.\n *\n * @module @gravito/core/engine\n */\n\nimport { RadixRouter } from '../adapters/bun/RadixRouter'\nimport type { HttpMethod } from '../http/types'\nimport type { Handler, Middleware, RouteMatch, RouteMetadata } from './types'\n\n/**\n * Route definition for re-playing routes (mounting)\n */\ninterface RouteDefinition {\n method: HttpMethod\n path: string\n handler: Handler\n middleware: Middleware[]\n}\n\n/**\n * AOT Router - Optimized for Bun\n */\nexport class AOTRouter {\n // Static route cache: \"METHOD:PATH\" -> RouteMetadata\n /** @internal */\n public readonly staticRoutes = new Map<string, RouteMetadata>()\n\n // Dynamic route handler (Radix Tree)\n private dynamicRouter = new RadixRouter()\n\n // Store all route definitions to support mounting/merging\n /** @internal */\n public readonly routeDefinitions: RouteDefinition[] = []\n\n // Global middleware (applies to all routes)\n /** @internal */\n public readonly globalMiddleware: Middleware[] = []\n\n // Path-based middleware: pattern -> middleware[]\n /** @internal */\n public readonly pathMiddleware = new Map<string, Middleware[]>()\n\n // Dynamic route patterns: handler function -> route pattern\n // 用於追蹤動態路由的模式,防止高基數問題\n private dynamicRoutePatterns = new Map<Function, string>()\n\n private middlewareCache = new Map<string, { data: Middleware[]; version: number }>()\n private cacheMaxSize = 1000\n private _version = 0\n\n /**\n * Get the current version for cache invalidation\n * Incremented whenever middleware or routes are modified\n */\n public get version(): number {\n return this._version\n }\n\n /**\n * Register a route\n *\n * Automatically determines if route is static or dynamic.\n * Static routes are stored in a Map for O(1) lookup.\n * Dynamic routes use the Radix Tree.\n *\n * @param method - HTTP method\n * @param path - Route path\n * @param handler - Route handler\n * @param middleware - Route-specific middleware\n */\n add(method: HttpMethod, path: string, handler: Handler, middleware: Middleware[] = []): void {\n // Store definition for mounting support\n this.routeDefinitions.push({ method, path, handler, middleware })\n\n const normalizedMethod = method.toLowerCase() as HttpMethod\n\n if (this.isStaticPath(path)) {\n // Static route - use Map\n const key = `${normalizedMethod}:${path}`\n this.staticRoutes.set(key, { handler, middleware })\n } else {\n // Dynamic route - use Radix Tree\n // Wrap handler to match our Handler type\n const wrappedHandler = handler as unknown as Function\n this.dynamicRouter.add(normalizedMethod, path, [wrappedHandler])\n\n // Store route pattern for this handler\n this.dynamicRoutePatterns.set(wrappedHandler, path)\n\n // Store middleware separately\n if (middleware.length > 0) {\n this.pathMiddleware.set(`${normalizedMethod}:${path}`, middleware)\n }\n }\n }\n\n /**\n * Mount another router at a prefix\n */\n mount(prefix: string, other: AOTRouter): void {\n // 1. Convert other's global middleware to pattern middleware\n if (other.globalMiddleware.length > 0) {\n // Apply to both /prefix and /prefix/*\n this.usePattern(prefix, ...other.globalMiddleware)\n\n const wildcard = prefix === '/' ? '/*' : `${prefix}/*`\n this.usePattern(wildcard, ...other.globalMiddleware)\n }\n\n // 2. Transfer pattern-based middleware (only user-defined patterns, not route-specific)\n for (const [pattern, mws] of other.pathMiddleware) {\n // Skip route-specific middleware entries (they have method prefix like \"get:/path/:id\")\n // These are stored by add() with format \"method:path\"\n const hasMethodPrefix = /^(get|post|put|delete|patch|options|head):/.test(pattern)\n if (hasMethodPrefix) {\n continue\n }\n\n // Normalize pattern\n let newPattern: string\n if (pattern === '*') {\n newPattern = prefix === '/' ? '/*' : `${prefix}/*`\n } else if (pattern.startsWith('/')) {\n newPattern = prefix === '/' ? pattern : `${prefix}${pattern}`\n } else {\n newPattern = prefix === '/' ? `/${pattern}` : `${prefix}/${pattern}`\n }\n\n this.usePattern(newPattern, ...mws)\n }\n\n // 3. Transfer all routes\n for (const def of other.routeDefinitions) {\n // Calculate new path\n let newPath: string\n if (prefix === '/') {\n newPath = def.path\n } else if (def.path === '/') {\n newPath = prefix\n } else {\n newPath = `${prefix}${def.path}`\n }\n\n this.add(def.method, newPath, def.handler, def.middleware)\n }\n }\n\n /**\n * Add global middleware\n *\n * These run for every request, before route-specific middleware.\n *\n * @param middleware - Middleware functions\n */\n use(...middleware: Middleware[]): void {\n this.globalMiddleware.push(...middleware)\n this._version++\n }\n\n /**\n * Add path-based middleware\n *\n * Supports wildcard patterns like '/api/*'\n *\n * @param pattern - Path pattern\n * @param middleware - Middleware functions\n */\n usePattern(pattern: string, ...middleware: Middleware[]): void {\n // Special case: '*' pattern should be treated as global middleware\n if (pattern === '*') {\n this.globalMiddleware.push(...middleware)\n } else {\n const existing = this.pathMiddleware.get(pattern) ?? []\n this.pathMiddleware.set(pattern, [...existing, ...middleware])\n }\n this._version++\n }\n\n /**\n * Match a request to a route\n *\n * Returns the handler, params, and all applicable middleware.\n *\n * @param method - HTTP method\n * @param path - Request path\n * @returns Route match or null if not found\n */\n match(method: string, path: string): RouteMatch {\n const normalizedMethod = method.toLowerCase() as HttpMethod\n\n // Try static route first (O(1))\n const staticKey = `${normalizedMethod}:${path}`\n const staticRoute = this.staticRoutes.get(staticKey)\n\n if (staticRoute) {\n return {\n handler: staticRoute.handler,\n params: {},\n middleware: this.collectMiddleware(path, staticRoute.middleware),\n routePattern: path,\n }\n }\n\n // Try dynamic route (Radix Tree)\n const match = this.dynamicRouter.match(normalizedMethod, path)\n\n if (match && match.handlers.length > 0) {\n const handler = match.handlers[0] as unknown as Handler\n const wrappedHandler = match.handlers[0]\n\n // 從 Map 中取得路由模式\n const routePattern = this.dynamicRoutePatterns.get(wrappedHandler)\n const routeKey = routePattern ? `${normalizedMethod}:${routePattern}` : null\n const routeMiddleware = routeKey ? (this.pathMiddleware.get(routeKey) ?? []) : []\n\n return {\n handler,\n params: match.params,\n middleware: this.collectMiddleware(path, routeMiddleware),\n routePattern,\n }\n }\n\n // No match\n return {\n handler: null,\n params: {},\n middleware: [],\n }\n }\n\n /**\n * Public wrapper for collectMiddleware (used by Gravito for optimization)\n */\n collectMiddlewarePublic(path: string, routeMiddleware: Middleware[]): Middleware[] {\n return this.collectMiddleware(path, routeMiddleware)\n }\n\n /**\n * Collect all applicable middleware for a path\n *\n * Order: global -> pattern-based -> route-specific\n *\n * @param path - Request path\n * @param routeMiddleware - Route-specific middleware\n * @returns Combined middleware array\n */\n private collectMiddleware(path: string, routeMiddleware: Middleware[]): Middleware[] {\n // Fast path: no middleware at all\n if (\n this.globalMiddleware.length === 0 &&\n this.pathMiddleware.size === 0 &&\n routeMiddleware.length === 0\n ) {\n return []\n }\n\n // Optimized cache key: use path directly for O(1) lookups\n // Cache format: path -> { middleware array, version }\n const cacheKey = path\n const cached = this.middlewareCache.get(cacheKey)\n\n // Cache hit: return immediately (same path gets same middleware)\n if (cached !== undefined && cached.version === this._version) {\n return cached.data\n }\n\n const middleware: Middleware[] = []\n\n // 1. Global middleware (most common case)\n if (this.globalMiddleware.length > 0) {\n middleware.push(...this.globalMiddleware)\n }\n\n // 2. Pattern-based middleware (check only if pathMiddleware exists)\n if (this.pathMiddleware.size > 0) {\n for (const [pattern, mw] of this.pathMiddleware) {\n // Skip route-specific entries (they have method prefix)\n if (pattern.includes(':')) {\n continue\n }\n\n if (this.matchPattern(pattern, path)) {\n middleware.push(...mw)\n }\n }\n }\n\n // 3. Route-specific middleware\n if (routeMiddleware.length > 0) {\n middleware.push(...routeMiddleware)\n }\n\n // LRU cache: only cache if under max size\n if (this.middlewareCache.size < this.cacheMaxSize) {\n this.middlewareCache.set(cacheKey, { data: middleware, version: this._version })\n } else if (this.middlewareCache.has(cacheKey)) {\n // Update existing cache entry\n this.middlewareCache.set(cacheKey, { data: middleware, version: this._version })\n }\n\n return middleware\n }\n\n /**\n * Get all static routes optimized for Bun's native router.\n *\n * Unlike basic offloading, this version supports routes with middleware\n * by pre-compiling the middleware chain into a single native handler.\n *\n * @param onMatch - Factory to wrap handler and middleware into a Bun-compatible function\n * @returns Record of path -> Handler (Bun-compatible)\n */\n getNativeRoutes(\n onMatch: (\n handler: Handler,\n middleware: Middleware[],\n path: string\n ) => (req: Request) => Response | Promise<Response>\n ): Record<string, any> {\n const routes: Record<string, any> = {}\n\n for (const [key, metadata] of this.staticRoutes) {\n const [method, path] = key.split(':')\n if (method !== 'get') {\n continue // Bun's native routes primarily focus on GET for Response objects\n }\n\n // Collect all applicable middleware (Global + Pattern + Route-specific)\n const allMiddleware = this.collectMiddleware(path!, metadata.middleware)\n\n // Map to Bun's native router format\n // The middleware chain is compiled and wrapped by the caller (Gravito)\n routes[path!] = onMatch(metadata.handler, allMiddleware, path!)\n }\n\n return routes\n }\n\n /**\n * Check if a path is static (no parameters or wildcards)\n */\n private isStaticPath(path: string): boolean {\n return !path.includes(':') && !path.includes('*')\n }\n\n /**\n * Match a pattern against a path\n *\n * Supports:\n * - Exact match: '/api/users'\n * - Wildcard suffix: '/api/*'\n *\n * @param pattern - Pattern to match\n * @param path - Path to test\n * @returns True if pattern matches\n */\n private matchPattern(pattern: string, path: string): boolean {\n if (pattern === '*') {\n return true\n }\n if (pattern === path) {\n return true\n }\n\n if (pattern.endsWith('/*')) {\n const prefix = pattern.slice(0, -2)\n return path.startsWith(prefix)\n }\n\n return false\n }\n\n /**\n * Get all registered routes (for debugging)\n */\n getRoutes(): Array<{ method: string; path: string; type: 'static' | 'dynamic' }> {\n const routes: Array<{ method: string; path: string; type: 'static' | 'dynamic' }> = []\n\n // Static routes\n for (const key of this.staticRoutes.keys()) {\n const [method, path] = key.split(':')\n routes.push({ method: method!, path: path!, type: 'static' })\n }\n\n // Dynamic routes (harder to enumerate from Radix Tree)\n // For now, we'll skip this - it's mainly for debugging anyway\n\n return routes\n }\n}\n",
|
|
8
|
+
"/**\n * @fileoverview Transpiler 工具庫 - AST 層級代碼分析\n *\n * 使用 Bun.Transpiler API 進行精確的 handler 函式分析,\n * 相比傳統字串匹配,精確度從 ~85% 提升至 ~99%。\n *\n * 核心策略:\n * 1. 使用 transformSync() 標準化代碼格式(統一縮排、引號等)\n * 2. 對轉換後的代碼使用精確的正規表達式匹配 member expression\n * 3. 區分 API 呼叫(.req.header())與變數名稱(const header = ...)\n * 4. 支援解構賦值模式(const { header } = ctx.req)\n * 5. 快取 Transpiler 實例(性能提升 5.9x)+ LRU 快取結果(額外 128x)\n *\n * @module @gravito/core/transpiler-utils\n * @since 3.1.0\n */\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Transpiler 快取類別\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Transpiler 分析結果的快取鍵對應值\n * 儲存轉換後的代碼字串\n */\ninterface TranspilerCacheEntry {\n /** 轉換後的標準化代碼 */\n transformed: string\n /** 快取建立時間(ms,用於 TTL 過期) */\n createdAt: number\n}\n\n/**\n * TranspilerCache - 管理 Bun.Transpiler 實例與結果快取\n *\n * 避免重複建立 Transpiler(每次建立約需 40µs),\n * 並快取 transformSync 結果(重用快取比每次 transform 快 128x)。\n *\n * @example\n * ```typescript\n * const cache = TranspilerCache.getInstance()\n * const transformed = cache.transform(handlerSource)\n * ```\n */\nexport class TranspilerCache {\n private static instance: TranspilerCache | null = null\n\n /** 共享的 Bun.Transpiler 實例(避免重複建立) */\n private readonly transpiler: Bun.Transpiler\n\n /** LRU 快取:原始代碼 → 轉換結果 */\n private readonly cache: Map<string, TranspilerCacheEntry>\n\n /** 快取大小上限 */\n private readonly maxSize: number\n\n /** 快取 TTL(毫秒),預設 5 分鐘 */\n private readonly ttlMs: number\n\n private constructor(maxSize = 512, ttlMs = 5 * 60 * 1000) {\n // 使用 'ts' loader 以支援 TypeScript 語法\n this.transpiler = new Bun.Transpiler({ loader: 'ts' })\n this.cache = new Map()\n this.maxSize = maxSize\n this.ttlMs = ttlMs\n }\n\n /**\n * 取得單例實例\n * 確保全程只建立一個 Transpiler 實例\n */\n static getInstance(): TranspilerCache {\n TranspilerCache.instance ??= new TranspilerCache()\n return TranspilerCache.instance\n }\n\n /**\n * 重置單例(主要用於測試)\n */\n static resetInstance(): void {\n TranspilerCache.instance = null\n }\n\n /**\n * 轉換代碼並快取結果\n *\n * 先嘗試從快取取得,若未命中則呼叫 transformSync 並儲存結果。\n * 快取已滿時淘汰最舊的條目(近似 LRU)。\n *\n * 處理兩個 Bun.Transpiler 邊緣案例:\n * 1. 箭頭函式表達式:`async (ctx) => ...` → transformSync 返回空字串\n * 解法:包裝成 `const __fn = <source>` 後再轉換\n * 2. 匿名函式表達式:`function(ctx) {...}` → transformSync 拋出 Parse error\n * 解法:同樣包裝後轉換\n *\n * @param source - 原始 handler 函式字串\n * @returns 轉換後的標準化代碼,若完全失敗則回傳 null\n */\n transform(source: string): string | null {\n // 1. 快取命中\n const cached = this.cache.get(source)\n if (cached !== undefined) {\n // 檢查 TTL\n if (Date.now() - cached.createdAt < this.ttlMs) {\n return cached.transformed\n }\n // 過期,移除\n this.cache.delete(source)\n }\n\n // 2. 執行 transform(含邊緣案例處理)\n const transformed = this.doTransform(source)\n if (transformed === null) {\n // 完全失敗,不快取,讓呼叫方 fallback\n return null\n }\n\n // 3. 淘汰舊條目(若已達上限)\n if (this.cache.size >= this.maxSize) {\n // 刪除最舊的條目(Map 迭代順序即插入順序)\n const firstKey = this.cache.keys().next().value\n if (firstKey !== undefined) {\n this.cache.delete(firstKey)\n }\n }\n\n // 4. 存入快取\n this.cache.set(source, { transformed, createdAt: Date.now() })\n return transformed\n }\n\n /**\n * 實際執行 transformSync,處理箭頭函式和匿名函式的邊緣案例\n *\n * @param source - 原始代碼字串\n * @returns 轉換後的代碼,或失敗時回傳 null\n */\n private doTransform(source: string): string | null {\n // 嘗試直接 transform\n try {\n const out = this.transpiler.transformSync(source)\n // 若輸出非空,直接使用(named function / async function 正常情況)\n if (out.trim().length > 0) {\n return out\n }\n // 空字串輸出 = 箭頭函式表達式(如 `async (ctx) => ctx.json({})`)\n // 嘗試包裝後再 transform\n return this.transformWrapped(source)\n } catch {\n // Parse error = 匿名函式表達式(如 `function(ctx) {...}`)\n // 嘗試包裝後再 transform\n return this.transformWrapped(source)\n }\n }\n\n /**\n * 將代碼包裝成賦值語句後再 transform\n *\n * 用於處理無法直接 transform 的函式表達式。\n * 包裝格式:`const __fn = <source>`\n *\n * @param source - 原始函式字串\n * @returns 包裝後的轉換結果,或失敗時回傳 null\n */\n private transformWrapped(source: string): string | null {\n try {\n const wrapped = `const __fn = ${source}`\n const out = this.transpiler.transformSync(wrapped)\n return out.trim().length > 0 ? out : null\n } catch {\n return null\n }\n }\n\n /**\n * 取得目前快取大小\n */\n get size(): number {\n return this.cache.size\n }\n\n /**\n * 清除所有快取條目\n */\n clear(): void {\n this.cache.clear()\n }\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// 精確模式偵測正規表達式\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * 所有偵測模式集中定義,方便維護與測試\n *\n * 設計原則:\n * - Member access: 匹配 `.req.<方法名>(` 形式(函式呼叫)\n * - Destructure: 匹配 `{ <屬性名> } = <任意>.<req前綴>` 形式(解構賦值)\n * - 排除字串賦值:轉換後的字串賦值格式為 `= \"...\"` 或 `= '...'`,\n * 正規表達式只匹配 `.req.` 開頭的 member access,因此自然排除\n */\nconst PATTERNS = {\n /**\n * 偵測 headers/header 的成員存取\n *\n * 匹配:\n * - `.req.header(` 或 `.req.headers(`\n * - `{ header } = *.req` 或 `{ headers } = *.req`\n */\n HEADERS_CALL: /\\.req\\.headers?\\s*\\(/,\n HEADERS_DESTR: /\\{[^}]*\\bheaders?\\b[^}]*\\}\\s*=\\s*\\w+\\.req/,\n\n /**\n * 偵測 query/queries 的成員存取\n *\n * 匹配:\n * - `.req.query(` 或 `.req.queries(`\n * - `{ query } = *.req` 或 `{ queries } = *.req`\n */\n QUERY_CALL: /\\.req\\.quer(?:y|ies)\\s*\\(/,\n QUERY_DESTR: /\\{[^}]*\\bquer(?:y|ies)\\b[^}]*\\}\\s*=\\s*\\w+\\.req/,\n\n /**\n * 偵測 body 相關的成員存取\n *\n * 匹配:\n * - `.req.json(` `.req.text(` `.req.formData(` `.req.blob(` `.req.arrayBuffer(`\n * - `{ body } = *.req`\n * - `.req.body`(直接屬性存取)\n */\n BODY_CALL: /\\.req\\.(?:json|text|formData|blob|arrayBuffer)\\s*\\(/,\n BODY_DESTR: /\\{[^}]*\\bbody\\b[^}]*\\}\\s*=\\s*\\w+\\.req/,\n BODY_PROP: /\\.req\\.body\\b/,\n\n /**\n * 偵測 param/params 的成員存取\n *\n * 匹配:\n * - `.req.param(` 或 `.req.params(`\n * - `{ param } = *.req` 或 `{ params } = *.req`\n */\n PARAMS_CALL: /\\.req\\.params?\\s*\\(/,\n PARAMS_DESTR: /\\{[^}]*\\bparams?\\b[^}]*\\}\\s*=\\s*\\w+\\.req/,\n\n /**\n * 偵測非同步函式(用於原始碼)\n *\n * 直接匹配原始碼中的 async 關鍵字。\n * 注意:isAsync 不用 transformSync 結果,因為:\n * 1. 箭頭函式 `async (ctx) => ...` 的 transformSync 返回空字串\n * 2. `async` 關鍵字本身不存在假陽性問題(沒有 API 叫做 async)\n *\n * 匹配:\n * - `async function` - async 具名/匿名函式\n * - `async (` - async 箭頭函式(括號形式)\n * - `async ctx` - async 箭頭函式(無括號單參數)\n */\n IS_ASYNC: /\\basync\\b/,\n} as const\n\n// ─────────────────────────────────────────────────────────────────────────────\n// 核心分析函式\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Transpiler 分析的返回結果\n * 與 HandlerAnalysis 介面對應\n */\nexport interface TranspilerAnalysisResult {\n usesHeaders: boolean\n usesQuery: boolean\n usesBody: boolean\n usesParams: boolean\n isAsync: boolean\n}\n\n/**\n * 使用 Bun.Transpiler 進行精確的 handler 靜態分析\n *\n * 相比字串匹配,此函式能正確區分:\n * - API 呼叫(`ctx.req.header(name)`)vs 變數名稱(`const header = '...'`)\n * - 解構賦值(`const { header } = ctx.req`)\n * - Minified 代碼(transformSync 先標準化)\n * - 箭頭函式與匿名函式(包裝策略處理 Bun.Transpiler 邊緣案例)\n *\n * 若 Transpiler 轉換失敗,會自動 fallback 到字串匹配模式。\n *\n * ## isAsync 特殊處理\n *\n * `isAsync` 直接從原始碼偵測 `async` 關鍵字,而不是從 transformSync 結果:\n * - 箭頭函式 `async (ctx) => ...` 的 transformSync 返回空字串\n * - `async` 關鍵字本身不存在假陽性問題\n *\n * @param source - handler 函式的字串表示(通常來自 handler.toString())\n * @returns 分析結果,或在 fallback 模式下的近似結果\n *\n * @example\n * ```typescript\n * const handler = async (ctx) => {\n * const name = ctx.req.query('name')\n * return ctx.json({ name })\n * }\n * const result = analyzeHandlerWithTranspiler(handler.toString())\n * // result.usesQuery === true\n * // result.usesHeaders === false(即使有 'header' 字串,也不會誤判)\n * // result.isAsync === true(即使是箭頭函式也能正確偵測)\n * ```\n */\nexport function analyzeHandlerWithTranspiler(source: string): TranspilerAnalysisResult {\n const cache = TranspilerCache.getInstance()\n const transformed = cache.transform(source)\n\n // isAsync 直接從原始碼偵測(不依賴 transformSync 結果)\n // 因為箭頭函式的 transformSync 返回空字串,且 async 關鍵字無假陽性問題\n const isAsync = PATTERNS.IS_ASYNC.test(source)\n\n // 若 Transpiler 成功,使用精確的 AST 級別模式分析其他屬性\n if (transformed !== null) {\n return { ...analyzeTransformedCode(transformed), isAsync }\n }\n\n // Fallback:Transpiler 失敗時使用字串匹配(保守估計)\n return { ...fallbackStringAnalysis(source), isAsync }\n}\n\n/**\n * 對 Transpiler 轉換後的代碼進行精確模式分析(不含 isAsync)\n *\n * @param code - transformSync() 返回的標準化代碼\n * @returns 分析結果(isAsync 由呼叫方根據原始碼設定)\n */\nfunction analyzeTransformedCode(\n code: string\n): Omit<TranspilerAnalysisResult, 'isAsync'> & { isAsync: boolean } {\n return {\n usesHeaders: PATTERNS.HEADERS_CALL.test(code) || PATTERNS.HEADERS_DESTR.test(code),\n usesQuery: PATTERNS.QUERY_CALL.test(code) || PATTERNS.QUERY_DESTR.test(code),\n usesBody:\n PATTERNS.BODY_CALL.test(code) ||\n PATTERNS.BODY_DESTR.test(code) ||\n PATTERNS.BODY_PROP.test(code),\n usesParams: PATTERNS.PARAMS_CALL.test(code) || PATTERNS.PARAMS_DESTR.test(code),\n // 這個值會被呼叫方覆蓋,這裡保留是為了型別完整性\n isAsync: PATTERNS.IS_ASYNC.test(code),\n }\n}\n\n/**\n * 字串匹配 Fallback 分析\n *\n * 當 Bun.Transpiler 不可用或轉換失敗時使用,\n * 比原始實現略為保守(寬鬆匹配以減少假陰性)。\n *\n * @param source - 原始 handler 函式字串\n * @returns 分析結果(精確度較低,~85%)\n */\nfunction fallbackStringAnalysis(source: string): TranspilerAnalysisResult {\n return {\n usesHeaders:\n source.includes('.header(') ||\n source.includes('.header)') ||\n source.includes('.headers(') ||\n source.includes('.headers)'),\n usesQuery:\n source.includes('.query(') ||\n source.includes('.query)') ||\n source.includes('.queries(') ||\n source.includes('.queries)'),\n usesBody:\n source.includes('.json()') ||\n source.includes('.text()') ||\n source.includes('.formData()') ||\n source.includes('.body'),\n usesParams:\n source.includes('.param(') ||\n source.includes('.param)') ||\n source.includes('.params(') ||\n source.includes('.params)'),\n isAsync: source.includes('async') || source.includes('await'),\n }\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// 輔助工具函式\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * 測試 handler 源代碼是否存取特定的 req 成員屬性\n *\n * 工具函式,方便在 Gravito.ts 等地方進行特定屬性的快速檢測。\n *\n * @param source - handler 函式的字串表示\n * @param property - 要測試的屬性名稱(如 'header', 'query', 'body')\n * @returns 若該屬性被存取則回傳 true\n *\n * @example\n * ```typescript\n * const src = handler.toString()\n * if (hasReqMemberAccess(src, 'header')) {\n * // handler 存取了 header\n * }\n * ```\n */\nexport function hasReqMemberAccess(source: string, property: string): boolean {\n const cache = TranspilerCache.getInstance()\n const transformed = cache.transform(source)\n const code = transformed ?? source\n\n // 成員函式呼叫:.req.<property>(\n const callPattern = new RegExp(`\\\\.req\\\\.${property}\\\\s*\\\\(`)\n // 解構賦值:{ <property> } = *.req\n const destrPattern = new RegExp(`\\\\{[^}]*\\\\b${property}\\\\b[^}]*\\\\}\\\\s*=\\\\s*\\\\w+\\\\.req`)\n // 直接屬性存取:.req.<property>(用於 .body 等)\n const propPattern = new RegExp(`\\\\.req\\\\.${property}\\\\b`)\n\n return callPattern.test(code) || destrPattern.test(code) || propPattern.test(code)\n}\n\n/**\n * 判斷 handler 是否為非同步函式\n *\n * 直接從原始碼偵測 `async` 關鍵字,不依賴 transformSync 結果,\n * 因為箭頭函式的 transformSync 返回空字串。\n * `async` 關鍵字本身不存在假陽性問題。\n *\n * @param source - handler 函式的字串表示\n * @returns 若為 async 函式則回傳 true\n */\nexport function isAsyncHandler(source: string): boolean {\n return PATTERNS.IS_ASYNC.test(source)\n}\n\n/**\n * 預熱 Transpiler 快取\n *\n * 在應用啟動時呼叫,觸發 Transpiler 實例建立,\n * 避免第一個請求時的冷啟動延遲。\n */\nexport function warmupTranspilerCache(): void {\n const cache = TranspilerCache.getInstance()\n // 轉換一個簡單的 handler 觸發初始化\n cache.transform('function warmup(ctx) { return ctx.json({}) }')\n}\n",
|
|
9
|
+
"/**\n * @fileoverview Handler 靜態分析器(Elysia-inspired,升級版)\n *\n * 分析 handler 函式,偵測其存取了哪些請求屬性,\n * 以選擇最優化的 Context 類型(minimal/fast/full)。\n *\n * ## 版本歷史\n *\n * ### v2(目前版本)- 使用 Bun.Transpiler\n * - 精確度:~99%(AST 層級分析)\n * - 正確處理假陽性:`const header = '...'` 不再誤判\n * - 支援解構賦值:`const { header } = ctx.req`\n * - 支援 Minified 代碼(transformSync 先標準化)\n * - Fallback:若 Transpiler 失敗,退回字串匹配\n *\n * ### v1(原版本)- 字串匹配\n * - 精確度:~85%\n * - 假陽性:變數名稱包含目標字串會誤判\n * - 假陰性:解構賦值無法偵測\n * - Minified 代碼可能失效\n *\n * @module @gravito/core/engine/analyzer\n * @since 3.0.0\n */\n\nimport { analyzeHandlerWithTranspiler } from '../transpiler-utils'\n\n// ─────────────────────────────────────────────────────────────────────────────\n// 公開介面(向後相容,未改變)\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Handler 靜態分析結果\n *\n * 記錄 handler 函式使用了哪些請求屬性,\n * 用於選擇最優化的 Context 類型。\n *\n * @public\n * @since 3.0.0\n */\nexport interface HandlerAnalysis {\n /** 是否存取了 request headers */\n usesHeaders: boolean\n /** 是否存取了 query string 參數 */\n usesQuery: boolean\n /** 是否存取了 request body */\n usesBody: boolean\n /** 是否存取了 route 路徑參數 */\n usesParams: boolean\n /** 是否為非同步函式(含 async/await) */\n isAsync: boolean\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// 主要分析函式(升級版)\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * 分析 handler 函式,偵測其使用了哪些請求屬性\n *\n * 使用 Bun.Transpiler 進行 AST 層級的精確分析(精確度 ~99%)。\n * 若 Transpiler 不可用,自動 fallback 到字串匹配(精確度 ~85%)。\n *\n * ## 精確度提升說明\n *\n * **假陽性修復**(原本誤判,現在正確):\n * ```typescript\n * // 這個 handler 原本會誤判 usesHeaders = true\n * // 因為字串 'header' 出現在變數名稱中\n * function handler(ctx) {\n * const header = 'Content-Type' // ← 變數名稱,不是 API 呼叫\n * return ctx.json({ header })\n * }\n * // 現在:usesHeaders = false ✅\n * ```\n *\n * **假陰性修復**(原本漏偵測,現在正確):\n * ```typescript\n * // 這個 handler 原本會漏偵測解構賦值\n * function handler(ctx) {\n * const { header, query } = ctx.req // ← 解構賦值\n * return ctx.json({ header })\n * }\n * // 現在:usesHeaders = true, usesQuery = true ✅\n * ```\n *\n * @param handler - 要分析的 handler 函式\n * @returns HandlerAnalysis 分析結果\n *\n * @example\n * ```typescript\n * const handler = async (ctx) => {\n * const name = ctx.req.query('name')\n * return ctx.json({ name })\n * }\n *\n * const analysis = analyzeHandler(handler)\n * // analysis.usesQuery === true\n * // analysis.usesHeaders === false\n * // analysis.isAsync === true\n *\n * const type = getOptimalContextType(analysis)\n * // type === 'fast'\n * ```\n */\n// biome-ignore lint/complexity/noBannedTypes: 保持 public API 向後相容,handler 可以是任意 callable\nexport function analyzeHandler(handler: Function): HandlerAnalysis {\n const source = handler.toString()\n // 委派給 Transpiler 版本(含快取與 fallback)\n return analyzeHandlerWithTranspiler(source)\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Context 類型選擇(不變,保持向後相容)\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * 根據分析結果決定最優化的 Context 類型\n *\n * Context 類型由輕到重:\n * - `minimal`:僅支援路徑參數與靜態回應,零 overhead\n * - `fast`:支援 headers 與 query,使用物件池\n * - `full`:支援完整功能含 body 解析(async)\n *\n * 選擇邏輯(優先順序):\n * 1. 若存取 headers → `fast`(header 設置需要完整支援)\n * 2. 若不存取任何屬性 → `minimal`\n * 3. 若僅存取 params → `minimal`(params 在 minimal 中也可用)\n * 4. 若存取 body → `full`(async body 解析需要完整 context)\n * 5. 其他 → `fast`\n *\n * @param analysis - HandlerAnalysis 分析結果\n * @returns 最優化的 context 類型\n */\nexport function getOptimalContextType(analysis: HandlerAnalysis): 'minimal' | 'fast' | 'full' {\n // 存取 headers → 需要 fast context(header 設定功能)\n if (analysis.usesHeaders) {\n return 'fast'\n }\n\n // 不存取任何請求屬性 → 可使用 minimal context\n if (!analysis.usesQuery && !analysis.usesBody && !analysis.usesParams) {\n return 'minimal'\n }\n\n // 僅存取 params → minimal context 已有路徑參數支援\n if (!analysis.usesQuery && !analysis.usesBody && analysis.usesParams) {\n return 'minimal'\n }\n\n // 存取 body → 需要 full context(async body 解析)\n if (analysis.usesBody) {\n return 'full'\n }\n\n return 'fast'\n}\n",
|
|
10
|
+
"/**\n * @fileoverview Engine Constants & Cached Buffers\n *\n * Pre-allocated resources to minimize runtime allocation overhead.\n * Specifically targets Bun's zero-copy capabilities.\n */\n\nconst encoder = new TextEncoder()\n\n// Pre-encoded JSON responses for common scenarios\nexport const CACHED_RESPONSES = {\n NOT_FOUND: encoder.encode('{\"error\":\"Not Found\"}'),\n INTERNAL_ERROR: encoder.encode('{\"error\":\"Internal Server Error\"}'),\n OK: encoder.encode('{\"ok\":true}'),\n EMPTY: new Uint8Array(0),\n} as const\n\n// Content-Type constants (avoid string allocation)\nexport const HEADERS = {\n JSON: { 'Content-Type': 'application/json; charset=utf-8' },\n TEXT: { 'Content-Type': 'text/plain; charset=utf-8' },\n HTML: { 'Content-Type': 'text/html; charset=utf-8' },\n} as const\n",
|
|
11
|
+
"/**\n * RequestScopeMetrics - Observability for RequestScope lifecycle\n *\n * Tracks cleanup execution time, scope size, and service counts\n * for performance monitoring and diagnostics.\n *\n * @example\n * ```typescript\n * const metrics = new RequestScopeMetrics()\n * metrics.recordCleanupStart()\n * await scope.cleanup()\n * metrics.recordCleanupEnd()\n *\n * console.log(metrics.toJSON())\n * // { cleanupDuration: 2.5, scopeSize: 3, servicesCleaned: 3 }\n * ```\n */\nexport class RequestScopeMetrics {\n private cleanupStartTime: number | null = null\n private cleanupDuration: number | null = null\n private scopeSize = 0\n private servicesCleaned = 0\n private errorsOccurred = 0\n\n /**\n * Record start of cleanup operation\n */\n recordCleanupStart(): void {\n this.cleanupStartTime = performance.now()\n }\n\n /**\n * Record end of cleanup operation\n *\n * @param scopeSize - Number of services in the scope\n * @param servicesCleaned - Number of services that had cleanup called\n * @param errorsOccurred - Number of cleanup errors\n */\n recordCleanupEnd(scopeSize: number, servicesCleaned: number, errorsOccurred = 0): void {\n if (this.cleanupStartTime !== null) {\n this.cleanupDuration = performance.now() - this.cleanupStartTime\n this.cleanupStartTime = null\n }\n\n this.scopeSize = scopeSize\n this.servicesCleaned = servicesCleaned\n this.errorsOccurred = errorsOccurred\n }\n\n /**\n * Get cleanup duration in milliseconds\n *\n * @returns Duration in ms, or null if cleanup not completed\n */\n getCleanupDuration(): number | null {\n return this.cleanupDuration\n }\n\n /**\n * Check if cleanup took longer than threshold (default 2ms)\n * Useful for detecting slow cleanups\n *\n * @param thresholdMs - Threshold in milliseconds\n * @returns True if cleanup exceeded threshold\n */\n isSlowCleanup(thresholdMs = 2): boolean {\n if (this.cleanupDuration === null) {\n return false\n }\n return this.cleanupDuration > thresholdMs\n }\n\n /**\n * Export metrics as JSON for logging/monitoring\n */\n toJSON() {\n return {\n cleanupDuration: this.cleanupDuration,\n scopeSize: this.scopeSize,\n servicesCleaned: this.servicesCleaned,\n errorsOccurred: this.errorsOccurred,\n hasErrors: this.errorsOccurred > 0,\n isSlowCleanup: this.isSlowCleanup(),\n }\n }\n\n /**\n * Export metrics as compact string for logging\n */\n toString(): string {\n const duration = this.cleanupDuration ?? 'pending'\n return (\n `cleanup: ${duration}ms, ` +\n `scope: ${this.scopeSize}, ` +\n `cleaned: ${this.servicesCleaned}, ` +\n `errors: ${this.errorsOccurred}`\n )\n }\n}\n\n/**\n * RequestScopeObserver - Hook for monitoring RequestScope lifecycle\n *\n * Implement this interface to receive callbacks during scope operations\n */\nexport interface RequestScopeObserver {\n /**\n * Called when a service is resolved in the scope\n */\n onServiceResolved?(key: string | symbol, isFromCache: boolean): void\n\n /**\n * Called when cleanup starts\n */\n onCleanupStart?(): void\n\n /**\n * Called when cleanup completes\n */\n onCleanupEnd?(metrics: RequestScopeMetrics): void\n\n /**\n * Called when cleanup encounters an error\n */\n onCleanupError?(error: Error): void\n}\n\n/**\n * RequestScopeMetricsCollector - Aggregates metrics across multiple scopes\n *\n * Used for application-level monitoring and performance tracking\n *\n * @example\n * ```typescript\n * const collector = new RequestScopeMetricsCollector()\n *\n * // Record metrics from multiple requests\n * collector.record(metrics1)\n * collector.record(metrics2)\n * collector.record(metrics3)\n *\n * // Get aggregated stats\n * const stats = collector.getStats()\n * console.log(stats.averageCleanupTime) // 3.5ms\n * ```\n */\nexport class RequestScopeMetricsCollector {\n private metrics: RequestScopeMetrics[] = []\n\n /**\n * Record metrics from a request scope\n */\n record(metrics: RequestScopeMetrics): void {\n this.metrics.push(metrics)\n }\n\n /**\n * Get aggregated statistics\n */\n getStats() {\n if (this.metrics.length === 0) {\n return {\n count: 0,\n averageCleanupTime: null,\n maxCleanupTime: null,\n minCleanupTime: null,\n totalErrorCount: 0,\n errorRate: 0,\n }\n }\n\n const durations = this.metrics\n .map((m) => m.getCleanupDuration())\n .filter((d): d is number => d !== null)\n\n const errorCounts = this.metrics.map((m) => m.toJSON().errorsOccurred)\n const totalErrors = errorCounts.reduce((a, b) => a + b, 0)\n\n return {\n count: this.metrics.length,\n averageCleanupTime:\n durations.length > 0 ? durations.reduce((a, b) => a + b) / durations.length : null,\n maxCleanupTime: durations.length > 0 ? Math.max(...durations) : null,\n minCleanupTime: durations.length > 0 ? Math.min(...durations) : null,\n totalErrorCount: totalErrors,\n errorRate: totalErrors / this.metrics.length,\n }\n }\n\n /**\n * Clear collected metrics\n */\n clear(): void {\n this.metrics = []\n }\n\n /**\n * Get number of recorded metrics\n */\n size(): number {\n return this.metrics.length\n }\n\n /**\n * Export metrics as JSON array\n */\n toJSON() {\n return this.metrics.map((m) => m.toJSON())\n }\n}\n",
|
|
12
|
+
"import type { ServiceKey } from '../Container'\nimport { RequestScopeMetrics, type RequestScopeObserver } from './RequestScopeMetrics'\n\n/**\n * Manages request-scoped service instances within a single HTTP request.\n *\n * Each request gets its own RequestScopeManager instance with isolated state.\n * Services are cached within the request and automatically cleaned up when\n * the request ends.\n *\n * @example\n * ```typescript\n * const scope = new RequestScopeManager()\n * const cache = scope.resolve('productCache', () => new ProductCache())\n * // ... use cache ...\n * await scope.cleanup() // Called automatically by Gravito engine\n * ```\n */\nexport class RequestScopeManager {\n private scoped = new Map<string, unknown>()\n private metadata = new Map<string, Record<string, unknown>>()\n private metrics = new RequestScopeMetrics()\n private observer: RequestScopeObserver | null = null\n\n constructor(observer?: RequestScopeObserver) {\n this.observer = observer || null\n }\n\n /**\n * Set observer for monitoring scope lifecycle\n */\n setObserver(observer: RequestScopeObserver): void {\n this.observer = observer\n }\n\n /**\n * Get metrics for this scope\n */\n getMetrics(): RequestScopeMetrics {\n return this.metrics\n }\n\n /**\n * Resolve or retrieve a request-scoped service instance.\n *\n * If the service already exists in this scope, returns the cached instance.\n * Otherwise, calls the factory function to create a new instance and caches it.\n *\n * Automatically detects and records services with cleanup methods.\n *\n * @template T - The type of the service.\n * @param key - The service key (for caching).\n * @param factory - Factory function to create the instance if not cached.\n * @returns The cached or newly created instance.\n */\n resolve<T>(key: ServiceKey, factory: () => T): T {\n const keyStr = String(key)\n const isFromCache = this.scoped.has(keyStr)\n\n if (!isFromCache) {\n const instance = factory()\n this.scoped.set(keyStr, instance)\n\n // Record metadata for cleanup detection\n if (instance && typeof instance === 'object' && 'cleanup' in instance) {\n this.metadata.set(keyStr, { hasCleanup: true })\n }\n }\n\n // Notify observer\n this.observer?.onServiceResolved?.(key, isFromCache)\n\n return this.scoped.get(keyStr) as T\n }\n\n /**\n * Clean up all request-scoped instances.\n *\n * Calls the cleanup() method on each service that has one.\n * Silently ignores cleanup errors to prevent cascading failures.\n * Called automatically by the Gravito engine in the request finally block.\n *\n * @returns Promise that resolves when all cleanup is complete.\n */\n async cleanup(): Promise<void> {\n this.metrics.recordCleanupStart()\n this.observer?.onCleanupStart?.()\n\n const errors: unknown[] = []\n let servicesCleaned = 0\n\n for (const [, instance] of this.scoped) {\n if (instance && typeof instance === 'object' && 'cleanup' in instance) {\n const fn = (instance as any).cleanup\n if (typeof fn === 'function') {\n try {\n await fn.call(instance)\n servicesCleaned++\n } catch (error) {\n // Collect errors but continue cleanup\n errors.push(error)\n this.observer?.onCleanupError?.(\n error instanceof Error ? error : new Error(String(error))\n )\n }\n }\n }\n }\n\n const scopeSize = this.scoped.size\n this.scoped.clear()\n this.metadata.clear()\n\n // Record metrics\n this.metrics.recordCleanupEnd(scopeSize, servicesCleaned, errors.length)\n this.observer?.onCleanupEnd?.(this.metrics)\n\n // Log errors if any occurred\n if (errors.length > 0) {\n console.error('RequestScope cleanup errors:', errors)\n }\n }\n\n /**\n * Get the number of services in this scope (for monitoring).\n *\n * @returns The count of cached services.\n */\n size(): number {\n return this.scoped.size\n }\n}\n",
|
|
13
|
+
"/**\n * @fileoverview FastContext - Pooled Request Context\n *\n * Minimal, high-performance context implementation designed for object pooling.\n * Lazy parsing strategy: only parse what's actually accessed.\n *\n * @module @gravito/core/engine\n */\n\nimport { RequestScopeManager } from '../Container/RequestScopeManager'\nimport type { FastRequest, FastContext as IFastContext } from './types'\n\n// Bun runtime optimization: cache frequently used functions\nconst bunEscapeHTML = require('bun').escapeHTML\n\n/**\n * Lazy-parsed request wrapper\n *\n * Delays parsing of query params, headers, and body until accessed.\n * This is a key optimization for requests that don't need all data.\n */\nclass FastRequestImpl implements FastRequest {\n private _request!: Request\n private _params!: Record<string, string>\n private _path!: string\n private _routePattern?: string\n private _url: URL | null = null\n private _query: URLSearchParams | null = null\n private _headers: Record<string, string> | null = null\n private _cachedJson: unknown = undefined\n private _jsonParsed = false\n private _cachedText: string | undefined = undefined\n private _textParsed = false\n private _cachedFormData: FormData | undefined = undefined\n private _formDataParsed = false\n private _cachedQueries: Record<string, string | string[]> | null = null\n private _cachedCookies: Record<string, string> | null = null\n // Back-reference for release check optimization\n private _ctx: FastContext\n\n constructor(ctx: FastContext) {\n this._ctx = ctx\n }\n\n /**\n * Initialize for new request\n */\n init(\n request: Request,\n params: Record<string, string> = {},\n path = '',\n routePattern?: string\n ): this {\n this._request = request\n this._params = params\n this._path = path\n this._routePattern = routePattern\n this._url = null\n this._query = null\n this._headers = null\n this._cachedJson = undefined\n this._jsonParsed = false\n this._cachedText = undefined\n this._textParsed = false\n this._cachedFormData = undefined\n this._formDataParsed = false\n this._cachedQueries = null\n this._cachedCookies = null\n return this\n }\n\n /**\n * Reset for pooling\n */\n reset(): void {\n // Release references to allow GC\n this._request = undefined as any\n this._params = undefined as any\n this._url = null\n this._query = null\n this._headers = null\n this._cachedJson = undefined\n this._jsonParsed = false\n this._cachedText = undefined\n this._textParsed = false\n this._cachedFormData = undefined\n this._formDataParsed = false\n this._cachedQueries = null\n this._cachedCookies = null\n }\n\n private checkReleased(): void {\n if (this._ctx._isReleased) {\n throw new Error(\n 'FastContext usage after release detected! (Object Pool Strict Lifecycle Guard)'\n )\n }\n }\n\n get url(): string {\n this.checkReleased()\n return this._request.url\n }\n\n get method(): string {\n this.checkReleased()\n return this._request.method\n }\n\n get path(): string {\n this.checkReleased()\n return this._path\n }\n\n get routePattern(): string | undefined {\n this.checkReleased()\n return this._routePattern\n }\n\n param(name: string): string | undefined {\n this.checkReleased()\n return this._params[name]\n }\n\n params(): Record<string, string> {\n this.checkReleased()\n return { ...this._params }\n }\n\n private getUrl(): URL {\n if (!this._url) {\n this._url = new URL(this._request.url)\n }\n return this._url\n }\n\n query(name: string): string | undefined {\n this.checkReleased()\n if (!this._query) {\n this._query = this.getUrl().searchParams\n }\n return this._query.get(name) ?? undefined\n }\n\n queries(): Record<string, string | string[]> {\n this.checkReleased()\n // Return cached queries object if available\n if (this._cachedQueries !== null) {\n return this._cachedQueries\n }\n\n if (!this._query) {\n this._query = this.getUrl().searchParams\n }\n\n const result: Record<string, string | string[]> = {}\n for (const [key, value] of this._query.entries()) {\n const existing = result[key]\n if (existing === undefined) {\n result[key] = value\n } else if (Array.isArray(existing)) {\n existing.push(value)\n } else {\n result[key] = [existing, value]\n }\n }\n this._cachedQueries = result\n return result\n }\n\n header(name: string): string | undefined {\n this.checkReleased()\n return this._request.headers.get(name) ?? undefined\n }\n\n headers(): Record<string, string> {\n this.checkReleased()\n if (!this._headers) {\n this._headers = {}\n for (const [key, value] of this._request.headers.entries()) {\n this._headers[key] = value\n }\n }\n return { ...this._headers }\n }\n\n get cookies(): Record<string, string> {\n this.checkReleased()\n // Return cached cookies if available\n if (this._cachedCookies !== null) {\n return this._cachedCookies\n }\n\n // 1. Try Bun Native CookieMap (Injected in Bun.serve routes API)\n const nativeCookies = (this._request as any).cookies\n if (nativeCookies) {\n this._cachedCookies = nativeCookies\n return nativeCookies\n }\n\n // 2. Fallback: Parse from Header manually (Lazy Parsed)\n const cookieHeader = this._request.headers.get('cookie')\n if (!cookieHeader) {\n this._cachedCookies = {}\n return {}\n }\n\n // Manual parse implementation (optimized for speed)\n // Handles URL-encoded values and flexible separators ('; ' or ';')\n const cookies: Record<string, string> = {}\n const pairs = cookieHeader.split(/;\\s*/)\n for (let i = 0; i < pairs.length; i++) {\n const pair = pairs[i]!\n const idx = pair.indexOf('=')\n if (idx > 0) {\n const name = pair.substring(0, idx)\n const value = pair.substring(idx + 1)\n // Decode value if URL-encoded, fallback to raw value on decode error\n try {\n cookies[name] = decodeURIComponent(value)\n } catch {\n cookies[name] = value\n }\n }\n }\n this._cachedCookies = cookies\n return cookies\n }\n\n async json<T = unknown>(): Promise<T> {\n this.checkReleased()\n if (!this._jsonParsed) {\n this._cachedJson = await this._request.json()\n this._jsonParsed = true\n }\n return this._cachedJson as T\n }\n\n async text(): Promise<string> {\n this.checkReleased()\n if (!this._textParsed) {\n this._cachedText = await this._request.text()\n this._textParsed = true\n }\n return this._cachedText!\n }\n\n async formData(): Promise<FormData> {\n this.checkReleased()\n if (!this._formDataParsed) {\n this._cachedFormData = await this._request.formData()\n this._formDataParsed = true\n }\n return this._cachedFormData!\n }\n\n get raw(): Request {\n this.checkReleased()\n return this._request\n }\n}\n\n/**\n * FastContext - Pooled request context\n *\n * Designed for minimal memory allocation and maximum reuse.\n * All response helpers create Response objects directly without intermediate wrappers.\n */\nexport class FastContext implements IFastContext {\n public readonly req: FastRequestImpl = new FastRequestImpl(this)\n // private _statusCode = 200\n private _headers = new Headers() // Reuse this object\n\n public _isReleased = false // Made public for internal check access\n private _requestScope: RequestScopeManager | null = null // Request-scoped services\n\n /**\n * Initialize context for a new request\n *\n * This is called when acquiring from the pool.\n */\n init(\n request: Request,\n params: Record<string, string> = {},\n path = '',\n routePattern?: string\n ): this {\n this._isReleased = false\n this.req.init(request, params, path, routePattern)\n // Optimization: Creating new Headers is faster than iterating to delete in Bun\n // But for strict object pooling, we might want to reconsider.\n // For now, new Headers() is safe and fast enough.\n this._headers = new Headers()\n this._requestScope = new RequestScopeManager() // Initialize request scope\n return this\n }\n\n /**\n * Reset context for pooling (Cleanup)\n *\n * This is called when releasing back to the pool.\n * Implements \"Deep-Reset Protocol\" and \"Release Guard\".\n */\n reset(): void {\n this._isReleased = true\n this.req.reset()\n // We don't clear _headers here because init() will create a new one.\n // If we wanted to reuse, we would clear it here.\n this._store.clear()\n this._requestScope = null // Release reference for GC\n }\n\n /**\n * Check if context is released\n */\n private checkReleased(): void {\n if (this._isReleased) {\n throw new Error(\n 'FastContext usage after release detected! (Object Pool Strict Lifecycle Guard)'\n )\n }\n }\n\n // ─────────────────────────────────────────────────────────────────────────\n // Response Helpers\n // ─────────────────────────────────────────────────────────────────────────\n\n json<T>(data: T, status = 200): Response {\n this.checkReleased()\n // Merge custom headers with Content-Type\n const headers = new Headers(this._headers)\n headers.set('Content-Type', 'application/json; charset=utf-8')\n return Response.json(data, { status, headers })\n }\n\n text(text: string, status = 200): Response {\n this.checkReleased()\n // Merge custom headers with Content-Type\n const headers = new Headers(this._headers)\n headers.set('Content-Type', 'text/plain; charset=utf-8')\n return new Response(text, { status, headers })\n }\n\n html(html: string, status = 200): Response {\n this.checkReleased()\n // Merge custom headers with Content-Type\n const headers = new Headers(this._headers)\n headers.set('Content-Type', 'text/html; charset=utf-8')\n return new Response(html, { status, headers })\n }\n\n /**\n * Escape HTML using Bun's SIMD-accelerated native implementation\n */\n escape(html: string): string {\n return bunEscapeHTML(html)\n }\n\n redirect(url: string, status: 301 | 302 | 303 | 307 | 308 = 302): Response {\n this.checkReleased()\n return new Response(null, {\n status,\n headers: { Location: url },\n })\n }\n\n body(data: BodyInit | null, status = 200): Response {\n this.checkReleased()\n return new Response(data, {\n status,\n headers: this._headers,\n })\n }\n\n /**\n * Send high-performance binary response (e.g. CBOR, Protobuf)\n * Utilizing Bun's native ArrayBufferSink for zero-allocation construction.\n */\n binary(data: Uint8Array | ArrayBuffer, status = 200): Response {\n this.checkReleased()\n const body = data instanceof ArrayBuffer ? new Uint8Array(data) : data\n return new Response(body as any, {\n status,\n headers: { 'Content-Type': 'application/octet-stream' },\n })\n }\n\n stream(stream: any, status = 200): Response {\n this.checkReleased()\n // Direct streaming for zero-copy socket transfers\n return new Response(stream, {\n status,\n headers: { 'Content-Type': 'application/octet-stream' },\n })\n }\n\n notFound(message = 'Not Found'): Response {\n return this.text(message, 404)\n }\n\n forbidden(message = 'Forbidden'): Response {\n return this.text(message, 403)\n }\n\n unauthorized(message = 'Unauthorized'): Response {\n return this.text(message, 401)\n }\n\n badRequest(message = 'Bad Request'): Response {\n return this.text(message, 400)\n }\n\n async forward(target: string, _options: any = {}): Promise<Response> {\n this.checkReleased()\n // Minimal implementation of forwarding\n const url = new URL(this.req.url)\n const targetUrl = new URL(\n target.startsWith('http') ? target : `${url.protocol}//${target}${this.req.path}`\n )\n\n // Copy query params\n const searchParams = new URLSearchParams(url.search)\n searchParams.forEach((v, k) => {\n targetUrl.searchParams.set(k, v)\n })\n\n return fetch(targetUrl.toString(), {\n method: this.req.method,\n headers: this.req.raw.headers,\n body: this.req.method !== 'GET' && this.req.method !== 'HEAD' ? this.req.raw.body : null,\n // @ts-expect-error - Bun/Fetch specific\n duplex: 'half',\n })\n }\n\n // ─────────────────────────────────────────────────────────────────────────\n // Header Management\n // ─────────────────────────────────────────────────────────────────────────\n\n header(name: string): string | undefined\n header(name: string, value: string): void\n header(name: string, value?: string): string | undefined | undefined {\n this.checkReleased()\n if (value !== undefined) {\n this._headers.set(name, value)\n return\n }\n return this.req.header(name)\n }\n\n /**\n * Status code setter (no-op)\n *\n * Note: Since all response helpers accept a `status` parameter,\n * this method is not actively used. Status should be set directly\n * in the response helper call (e.g., `ctx.json({}, 201)`).\n */\n status(_code: number): void {\n this.checkReleased()\n // Status is set per-response, not stored on context\n }\n\n // ─────────────────────────────────────────────────────────────────────────\n // Context Variables\n // ─────────────────────────────────────────────────────────────────────────\n\n private _store = new Map<string, any>()\n\n get<T>(key: string): T {\n return this._store.get(key)\n }\n\n set(key: string, value: any): void {\n this._store.set(key, value)\n }\n\n // ─────────────────────────────────────────────────────────────────────────\n // Request Scope Management\n // ─────────────────────────────────────────────────────────────────────────\n\n /**\n * Get the request-scoped service manager for this request.\n *\n * @returns The RequestScopeManager for this request.\n * @throws Error if called before init() or after reset().\n */\n requestScope(): RequestScopeManager {\n if (!this._requestScope) {\n throw new Error('RequestScope not initialized. Call init() first.')\n }\n return this._requestScope\n }\n\n /**\n * Resolve a request-scoped service (convenience method).\n *\n * @template T - The service type.\n * @param key - The service key for caching.\n * @param factory - Factory function to create the service.\n * @returns The cached or newly created service instance.\n */\n scoped<T>(key: string | symbol, factory: () => T): T {\n return this.requestScope().resolve(key, factory)\n }\n\n // ─────────────────────────────────────────────────────────────────────────\n // Lifecycle helpers\n // ─────────────────────────────────────────────────────────────────────────\n\n public route: (name: string, params?: any, query?: any) => string = () => ''\n\n get native(): this {\n return this\n }\n}\n",
|
|
14
|
+
"/**\n * @fileoverview MinimalContext - Ultra-lightweight Request Context\n *\n * Designed for zero-middleware static routes where pool overhead\n * exceeds the cost of creating a new object.\n *\n * Key difference from FastContext:\n * - No object pooling (direct instantiation is faster for simple cases)\n * - No Headers object reuse (creates inline)\n * - Minimal memory footprint\n *\n * @module @gravito/core/engine\n */\n\nimport { RequestScopeManager } from '../Container/RequestScopeManager'\nimport type { FastRequest, FastContext as IFastContext } from './types'\n\n// Bun runtime optimization: cache frequently used functions\nconst bunEscapeHTML = require('bun').escapeHTML\n\n/**\n * Minimal request wrapper\n */\nclass MinimalRequest implements FastRequest {\n private _searchParams: URLSearchParams | null = null\n private _cachedQueries: Record<string, string | string[]> | null = null\n private _cachedJsonPromise: Promise<unknown> | null = null\n private _cachedTextPromise: Promise<string> | null = null\n private _cachedFormDataPromise: Promise<FormData> | null = null\n\n constructor(\n private readonly _request: Request,\n private readonly _params: Record<string, string>,\n private readonly _path: string,\n private readonly _routePattern?: string\n ) {}\n\n get url(): string {\n return this._request.url\n }\n\n get method(): string {\n return this._request.method\n }\n\n get path(): string {\n return this._path\n }\n\n get routePattern(): string | undefined {\n return this._routePattern\n }\n\n param(name: string): string | undefined {\n return this._params[name]\n }\n\n params(): Record<string, string> {\n return { ...this._params }\n }\n\n /**\n * Lazy-initialize searchParams, only parse once\n */\n private getSearchParams(): URLSearchParams {\n if (this._searchParams === null) {\n const url = this._request.url\n const queryStart = url.indexOf('?')\n if (queryStart === -1) {\n this._searchParams = new URLSearchParams()\n } else {\n const hashStart = url.indexOf('#', queryStart)\n const queryString =\n hashStart === -1 ? url.slice(queryStart + 1) : url.slice(queryStart + 1, hashStart)\n this._searchParams = new URLSearchParams(queryString)\n }\n }\n return this._searchParams\n }\n\n query(name: string): string | undefined {\n return this.getSearchParams().get(name) ?? undefined\n }\n\n queries(): Record<string, string | string[]> {\n // Cache the parsed queries object to avoid repeated parsing\n if (this._cachedQueries !== null) {\n return this._cachedQueries\n }\n\n const params = this.getSearchParams()\n const result: Record<string, string | string[]> = {}\n for (const [key, value] of params.entries()) {\n const existing = result[key]\n if (existing === undefined) {\n result[key] = value\n } else if (Array.isArray(existing)) {\n existing.push(value)\n } else {\n result[key] = [existing, value]\n }\n }\n this._cachedQueries = result\n return result\n }\n\n header(name: string): string | undefined {\n return this._request.headers.get(name) ?? undefined\n }\n\n headers(): Record<string, string> {\n const result: Record<string, string> = {}\n for (const [key, value] of this._request.headers.entries()) {\n result[key] = value\n }\n return result\n }\n\n async json<T = unknown>(): Promise<T> {\n // Cache the json promise to prevent \"Body has already been consumed\" errors\n // when multiple handlers or middleware try to read the body\n if (this._cachedJsonPromise === null) {\n this._cachedJsonPromise = this._request.json()\n }\n return this._cachedJsonPromise as Promise<T>\n }\n\n async text(): Promise<string> {\n // Cache the text promise to prevent \"Body has already been consumed\" errors\n if (this._cachedTextPromise === null) {\n this._cachedTextPromise = this._request.text()\n }\n return this._cachedTextPromise\n }\n\n async formData(): Promise<FormData> {\n // Cache the formData promise to prevent \"Body has already been consumed\" errors\n if (this._cachedFormDataPromise === null) {\n this._cachedFormDataPromise = this._request.formData()\n }\n return this._cachedFormDataPromise\n }\n\n get cookies(): Record<string, string> {\n // 1. Try Bun Native CookieMap (Injected in Bun.serve routes API)\n const nativeCookies = (this._request as any).cookies\n if (nativeCookies) {\n return nativeCookies\n }\n\n // 2. Fallback: Parse from Header manually\n const cookieHeader = this._request.headers.get('cookie')\n if (!cookieHeader) {\n return {}\n }\n\n // Manual parse implementation (optimized for speed)\n // Handles URL-encoded values and flexible separators ('; ' or ';')\n const cookies: Record<string, string> = {}\n const pairs = cookieHeader.split(/;\\s*/)\n for (let i = 0; i < pairs.length; i++) {\n const pair = pairs[i]!\n const idx = pair.indexOf('=')\n if (idx > 0) {\n const name = pair.substring(0, idx)\n const value = pair.substring(idx + 1)\n // Decode value if URL-encoded, fallback to raw value on decode error\n try {\n cookies[name] = decodeURIComponent(value)\n } catch {\n cookies[name] = value\n }\n }\n }\n return cookies\n }\n\n get raw(): Request {\n return this._request\n }\n}\n\n/**\n * MinimalContext - Optimized for simple, fast responses\n *\n * Use when:\n * - No middleware\n * - Static routes\n * - Simple JSON/text responses\n * - No custom headers needed\n */\nexport class MinimalContext implements IFastContext {\n public readonly req: MinimalRequest\n private _resHeaders: Record<string, string> = {}\n private _requestScope: RequestScopeManager\n\n constructor(\n request: Request,\n params: Record<string, string>,\n path: string,\n routePattern?: string\n ) {\n this.req = new MinimalRequest(request, params, path, routePattern)\n this._requestScope = new RequestScopeManager()\n }\n\n // get req(): FastRequest {\n // return this._req\n // }\n\n // Response helpers - merge custom headers with defaults\n // Optimized: use Object.assign instead of spread to avoid shallow copy overhead\n private getHeaders(contentType: string): Record<string, string> {\n const headers = Object.assign({ 'Content-Type': contentType }, this._resHeaders)\n return headers\n }\n\n json<T>(data: T, status = 200): Response {\n return new Response(JSON.stringify(data), {\n status,\n headers: this.getHeaders('application/json; charset=utf-8'),\n })\n }\n\n text(text: string, status = 200): Response {\n return new Response(text, {\n status,\n headers: this.getHeaders('text/plain; charset=utf-8'),\n })\n }\n\n html(html: string, status = 200): Response {\n return new Response(html, {\n status,\n headers: this.getHeaders('text/html; charset=utf-8'),\n })\n }\n\n redirect(url: string, status: 301 | 302 | 303 | 307 | 308 = 302): Response {\n return new Response(null, {\n status,\n headers: { ...this._resHeaders, Location: url },\n })\n }\n\n body(data: BodyInit | null, status = 200): Response {\n return new Response(data, {\n status,\n headers: this._resHeaders,\n })\n }\n\n header(name: string): string | undefined\n header(name: string, value: string): void\n header(name: string, value?: string): string | undefined | undefined {\n if (value !== undefined) {\n this._resHeaders[name] = value\n return\n }\n return this.req.header(name)\n }\n\n status(_code: number): void {\n // Status is set per response helper call, not stored on context\n }\n\n stream(stream: ReadableStream, status = 200): Response {\n return new Response(stream, {\n status,\n headers: this.getHeaders('application/octet-stream'),\n })\n }\n\n notFound(message = 'Not Found'): Response {\n return this.text(message, 404)\n }\n\n forbidden(message = 'Forbidden'): Response {\n return this.text(message, 403)\n }\n\n unauthorized(message = 'Unauthorized'): Response {\n return this.text(message, 401)\n }\n\n badRequest(message = 'Bad Request'): Response {\n return this.text(message, 400)\n }\n\n async forward(target: string, _options: any = {}): Promise<Response> {\n const url = new URL(this.req.url)\n const targetUrl = new URL(\n target.startsWith('http') ? target : `${url.protocol}//${target}${this.req.path}`\n )\n return fetch(targetUrl.toString(), {\n method: this.req.method,\n headers: this.req.raw.headers,\n })\n }\n\n escape(html: string): string {\n return bunEscapeHTML(html)\n }\n\n get<T>(_key: string): T {\n return undefined as any\n }\n\n set(_key: string, _value: any): void {}\n\n /**\n * Get the request-scoped service manager for this request.\n *\n * @returns The RequestScopeManager for this request.\n */\n requestScope(): RequestScopeManager {\n return this._requestScope\n }\n\n /**\n * Resolve a request-scoped service (convenience method).\n *\n * @template T - The service type.\n * @param key - The service key for caching.\n * @param factory - Factory function to create the service.\n * @returns The cached or newly created service instance.\n */\n scoped<T>(key: string | symbol, factory: () => T): T {\n return this._requestScope.resolve(key, factory)\n }\n\n public route: (name: string, params?: any, query?: any) => string = () => ''\n\n get native(): this {\n return this\n }\n\n // Required for interface compatibility\n init(_request: Request, _params?: Record<string, string>, _path?: string): this {\n throw new Error('MinimalContext does not support init. Create a new instance instead.')\n }\n\n // Required for interface compatibility\n reset(): void {\n // MinimalContext is not pooled, so no-op\n }\n}\n",
|
|
15
|
+
"/**\n * @fileoverview Lightweight Path Utilities\n *\n * High-performance path extraction without creating URL objects.\n * Performance critical - every optimization matters.\n *\n * @module @gravito/core/engine\n */\n\n/**\n * Extract pathname from URL string without creating URL object\n *\n * @param url - Full URL string (e.g., \"http://localhost:3000/api/users?id=1\")\n * @returns pathname (e.g., \"/api/users\")\n *\n * @example\n * ```typescript\n * extractPath(\"http://localhost:3000/api/users?id=1\") // \"/api/users\"\n * extractPath(\"https://example.com/\") // \"/\"\n * ```\n */\nexport function extractPath(url: string): string {\n // Optimization: use indexOf which is typically faster than JS loops\n // Find \"://\" to skip protocol\n const protocolEnd = url.indexOf('://')\n\n // Start searching after \"://\" (add 3)\n // If no \"://\", start from 0 (relative implementation or malformed)\n const searchStart = protocolEnd === -1 ? 0 : protocolEnd + 3\n\n const pathStart = url.indexOf('/', searchStart)\n\n // If no slash found after protocol, it's root \"/\" (e.g. http://localhost)\n if (pathStart === -1) {\n return '/'\n }\n\n const queryStart = url.indexOf('?', pathStart)\n\n if (queryStart === -1) {\n return url.slice(pathStart)\n }\n\n return url.slice(pathStart, queryStart)\n}\n\n/**\n * Extract pathname using simpler logic (alternative implementation)\n * Use this if the above doesn't cover edge cases\n */\nexport function extractPathSimple(url: string): string {\n // Find \"://\" then find next \"/\"\n const protocolEnd = url.indexOf('://')\n if (protocolEnd === -1) {\n // Relative URL or malformed\n const queryStart = url.indexOf('?')\n return queryStart === -1 ? url : url.slice(0, queryStart)\n }\n\n const pathStart = url.indexOf('/', protocolEnd + 3)\n if (pathStart === -1) {\n return '/'\n }\n\n const queryStart = url.indexOf('?', pathStart)\n return queryStart === -1 ? url.slice(pathStart) : url.slice(pathStart, queryStart)\n}\n",
|
|
16
|
+
"/**\n * @fileoverview Generic Object Pool Implementation\n *\n * High-performance object pooling to reduce GC pressure.\n * Implements \"fixed pool + overflow fallback\" strategy.\n *\n * @module @gravito/core/engine\n */\n\n/**\n * Generic object pool with fixed size and overflow handling\n *\n * @typeParam T - Type of objects to pool\n *\n * @example\n * ```typescript\n * const pool = new ObjectPool(\n * () => new MyObject(),\n * (obj) => obj.reset(),\n * 256\n * )\n *\n * const obj = pool.acquire()\n * try {\n * // Use object\n * } finally {\n * pool.release(obj)\n * }\n * ```\n */\nexport class ObjectPool<T> {\n private pool: T[] = []\n private readonly factory: () => T\n private readonly reset: (obj: T) => void\n private readonly maxSize: number\n\n /**\n * Create a new object pool\n *\n * @param factory - Function to create new objects\n * @param reset - Function to reset objects before reuse\n * @param maxSize - Maximum pool size (default: 256)\n */\n constructor(factory: () => T, reset: (obj: T) => void, maxSize = 256) {\n this.factory = factory\n this.reset = reset\n this.maxSize = maxSize\n }\n\n /**\n * Acquire an object from the pool\n *\n * If the pool is empty, creates a new object (overflow strategy).\n * This ensures the pool never blocks under high load.\n *\n * @returns Object from pool or newly created\n */\n acquire(): T {\n const obj = this.pool.pop()\n if (obj !== undefined) {\n return obj\n }\n\n // Pool exhausted - create new object (overflow)\n return this.factory()\n }\n\n /**\n * Release an object back to the pool\n *\n * If the pool is full, the object is discarded (will be GC'd).\n * This prevents unbounded memory growth.\n *\n * @param obj - Object to release\n */\n release(obj: T): void {\n if (this.pool.length < this.maxSize) {\n this.reset(obj)\n this.pool.push(obj)\n }\n // else: pool is full, let object be GC'd\n }\n\n /**\n * Clear all objects from the pool\n *\n * Useful for testing or when you need to force a clean slate.\n */\n clear(): void {\n this.pool = []\n }\n\n /**\n * Get current pool size\n */\n get size(): number {\n return this.pool.length\n }\n\n /**\n * Get maximum pool size\n */\n get capacity(): number {\n return this.maxSize\n }\n\n /**\n * Pre-warm the pool by creating objects in advance\n *\n * This can reduce latency for the first N requests.\n *\n * @param count - Number of objects to pre-create\n */\n prewarm(count: number): void {\n const targetSize = Math.min(count, this.maxSize)\n while (this.pool.length < targetSize) {\n const obj = this.factory()\n this.reset(obj)\n this.pool.push(obj)\n }\n }\n}\n",
|
|
17
|
+
"/**\n * @fileoverview Gravito - High-Performance Web Engine for Bun\n *\n * The standalone engine optimized exclusively for Bun runtime.\n * 99% API-compatible with Hono, but faster through Bun-specific optimizations.\n *\n * Key optimizations:\n * 1. Object pooling for zero-allocation request handling\n * 2. AOT router with O(1) static route lookup\n * 3. Lazy parsing - only parse what's accessed\n * 4. Direct Bun.serve integration without wrapper layers\n *\n * @module @gravito/core/engine\n */\n\nimport type { HttpMethod } from '../http/types'\nimport { AOTRouter } from './AOTRouter'\nimport { analyzeHandler, getOptimalContextType } from './analyzer'\nimport { CACHED_RESPONSES, HEADERS } from './constants'\nimport { FastContext as FastContextImpl } from './FastContext'\nimport { MinimalContext } from './MinimalContext'\nimport { extractPath } from './path'\nimport { ObjectPool } from './pool'\nimport type {\n CompiledHandler,\n EngineOptions,\n ErrorHandler,\n Handler,\n Middleware,\n NotFoundHandler,\n RouteMetadata,\n} from './types'\n\n// Bun runtime optimization: cache frequently used functions\nconst bunPeek = require('bun').peek\n\n/**\n * Precompile middleware chain into a single function\n */\nfunction compileMiddlewareChain(middleware: Middleware[], handler: Handler): CompiledHandler {\n // Fast path: no middleware\n if (middleware.length === 0) {\n return handler as CompiledHandler\n }\n\n // Single middleware optimization - avoid wrapping overhead\n if (middleware.length === 1) {\n const mw = middleware[0]!\n return async (ctx) => {\n let nextCalled = false\n const result = mw(ctx, async () => {\n nextCalled = true\n return undefined\n })\n\n // Optimization: Only use peek/await if result is truly a Promise\n let finalResult: any\n if (result instanceof Promise) {\n const peeked = bunPeek(result)\n finalResult = peeked === result ? await result : peeked\n } else {\n finalResult = result\n }\n\n if (finalResult instanceof Response) {\n return finalResult\n }\n\n if (nextCalled) {\n const hResult = handler(ctx)\n if (hResult instanceof Promise) {\n const p = bunPeek(hResult)\n return p === hResult ? await hResult : p\n }\n return hResult\n }\n return ctx.json({ error: 'Middleware did not call next or return response' }, 500)\n }\n }\n\n // Multiple middleware: compile right-to-left into a chain\n let compiled: CompiledHandler = handler as CompiledHandler\n\n for (let i = middleware.length - 1; i >= 0; i--) {\n const mw = middleware[i]!\n const nextHandler = compiled\n compiled = async (ctx) => {\n let nextCalled = false\n const result = mw(ctx, async () => {\n nextCalled = true\n return undefined\n })\n\n // Optimization: Only use peek/await if result is truly a Promise\n let finalResult: any\n if (result instanceof Promise) {\n const peeked = bunPeek(result)\n finalResult = peeked === result ? await result : peeked\n } else {\n finalResult = result\n }\n\n if (finalResult instanceof Response) {\n return finalResult\n }\n\n if (nextCalled) {\n const nextResult = nextHandler(ctx)\n if (nextResult instanceof Promise) {\n const p = bunPeek(nextResult)\n return p === nextResult ? await nextResult : p\n }\n return nextResult\n }\n\n return ctx.json({ error: 'Middleware did not call next or return response' }, 500)\n }\n }\n\n return compiled\n}\n\n/**\n * Gravito - The High-Performance Web Engine\n */\nexport class Gravito {\n private router = new AOTRouter()\n private contextPool: ObjectPool<FastContextImpl>\n private errorHandler?: ErrorHandler\n private notFoundHandler?: NotFoundHandler\n\n // Direct reference to static routes Map (O(1) access)\n /** @internal */\n public staticRoutes!: Map<string, RouteMetadata>\n // Flag: pure static app (no middleware at all) allows ultra-fast path\n private isPureStaticApp = true\n\n // Cache for precompiled dynamic routes\n private compiledDynamicRoutes = new Map<string, { compiled: CompiledHandler; version: number }>()\n\n /**\n * Create a new Gravito instance\n *\n * @param options - Engine configuration options\n */\n constructor(options: EngineOptions = {}) {\n const poolSize = options.poolSize ?? 256\n\n // Initialize context pool\n this.contextPool = new ObjectPool(\n () => new FastContextImpl(),\n (ctx) => ctx.reset(),\n poolSize\n )\n\n // Pre-warm pool for lower first-request latency\n this.contextPool.prewarm(Math.min(32, poolSize))\n\n // Set custom handlers if provided\n if (options.onError) {\n this.errorHandler = options.onError\n }\n if (options.onNotFound) {\n this.notFoundHandler = options.onNotFound\n }\n\n // Initialize route compilation\n this.compileRoutes()\n }\n\n // ─────────────────────────────────────────────────────────────────────────\n // HTTP Method Registration\n // ─────────────────────────────────────────────────────────────────────────\n\n /**\n * Register a GET route\n */\n get(path: string, ...handlers: Handler[]): this {\n return this.addRoute('get', path, handlers)\n }\n\n /**\n * Register a POST route\n */\n post(path: string, ...handlers: Handler[]): this {\n return this.addRoute('post', path, handlers)\n }\n\n /**\n * Register a PUT route\n */\n put(path: string, ...handlers: Handler[]): this {\n return this.addRoute('put', path, handlers)\n }\n\n /**\n * Register a DELETE route\n */\n delete(path: string, ...handlers: Handler[]): this {\n return this.addRoute('delete', path, handlers)\n }\n\n /**\n * Register a PATCH route\n */\n patch(path: string, ...handlers: Handler[]): this {\n return this.addRoute('patch', path, handlers)\n }\n\n /**\n * Register an OPTIONS route\n */\n options(path: string, ...handlers: Handler[]): this {\n return this.addRoute('options', path, handlers)\n }\n\n /**\n * Register a HEAD route\n */\n head(path: string, ...handlers: Handler[]): this {\n return this.addRoute('head', path, handlers)\n }\n\n /**\n * Register a route for all HTTP methods\n */\n all(path: string, ...handlers: Handler[]): this {\n const methods: HttpMethod[] = ['get', 'post', 'put', 'delete', 'patch', 'options', 'head']\n for (const method of methods) {\n this.addRoute(method, path, handlers)\n }\n return this\n }\n\n // ─────────────────────────────────────────────────────────────────────────\n // Middleware Registration\n // ─────────────────────────────────────────────────────────────────────────\n\n /**\n * Register global or path-based middleware\n */\n use(path: string, ...middleware: Middleware[]): this\n use(...middleware: Middleware[]): this\n use(pathOrMiddleware: string | Middleware, ...middleware: Middleware[]): this {\n // Mark as not pure static since we have middleware\n this.isPureStaticApp = false\n\n if (typeof pathOrMiddleware === 'string') {\n // Path-based middleware\n this.router.usePattern(pathOrMiddleware, ...middleware)\n } else {\n // Global middleware\n this.router.use(pathOrMiddleware, ...middleware)\n }\n\n this.compileRoutes()\n return this\n }\n\n // ─────────────────────────────────────────────────────────────────────────\n // Route Grouping\n // ─────────────────────────────────────────────────────────────────────────\n\n /**\n * Mount a sub-application at a path prefix\n */\n route(path: string, app: Gravito): this {\n // Mount the sub-application's router using the AOTRouter optimization\n this.router.mount(path, app.router)\n\n // Re-compile routes to update the static route map and optimizations\n this.compileRoutes()\n\n return this\n }\n\n // ─────────────────────────────────────────────────────────────────────────\n // Error Handling\n // ─────────────────────────────────────────────────────────────────────────\n\n /**\n * Set custom error handler\n */\n onError(handler: ErrorHandler): this {\n this.errorHandler = handler\n return this\n }\n\n /**\n * Set custom 404 handler\n */\n notFound(handler: NotFoundHandler): this {\n this.notFoundHandler = handler\n return this\n }\n\n // ─────────────────────────────────────────────────────────────────────────\n // Request Handling (Bun.serve integration)\n // ─────────────────────────────────────────────────────────────────────────\n\n /**\n * Predictive Route Warming (JIT Optimization)\n *\n * Simulates requests to specified routes to trigger JIT compilation (FTL)\n * before real traffic arrives.\n *\n * @param paths List of paths to warm up (e.g. ['/api/users', '/health'])\n */\n async warmup(paths: string[]): Promise<void> {\n const dummyReqOpts = { headers: { 'User-Agent': 'Gravito-Warmup/1.0' } }\n\n for (const path of paths) {\n const req = new Request(`http://localhost${path}`, dummyReqOpts)\n await this.fetch(req)\n }\n }\n\n /**\n * Generate Native Bun.serve Configuration\n *\n * Offloads static routes to Bun's SIMD-accelerated native router.\n * Supports pre-compiled middleware chains for zero runtime lookup.\n */\n serveConfig(baseConfig: Record<string, unknown> = {}): Record<string, unknown> {\n // 1. Extract and pre-compile routes for Bun's native router\n const nativeRoutes = this.router.getNativeRoutes((handler, middleware, path) => {\n // Pre-compile the middleware chain for this specific static route\n const compiled = compileMiddlewareChain(middleware, handler)\n\n // Create a native request handler that uses our pooling\n return async (req: Request) => {\n const ctx = this.contextPool.acquire()\n ctx.init(req, {}, path, path)\n\n try {\n const result = compiled(ctx)\n\n // Pro-level optimization: skip await if synchronous\n let response: Response\n if (result instanceof Promise) {\n const peeked = bunPeek(result)\n response = peeked === result ? await result : peeked\n } else {\n response = result\n }\n\n // Cleanup and release\n const cleanup = ctx.requestScope().cleanup()\n if (cleanup instanceof Promise) await cleanup\n this.contextPool.release(ctx)\n return response\n } catch (error) {\n // Cleanup even on error\n const cleanup = ctx.requestScope().cleanup()\n if (cleanup instanceof Promise) await cleanup\n this.contextPool.release(ctx)\n return this.handleErrorSync(error as Error, req, path)\n }\n }\n })\n\n return {\n ...baseConfig,\n routes: nativeRoutes,\n fetch: this.fetch, // Fallback for dynamic routes\n // Optimize TLS if provided in baseConfig\n tls: baseConfig.tls ? this.optimizeTLS(baseConfig.tls) : undefined,\n error: (error: Error) => {\n console.error('Native route error:', error)\n return new Response(CACHED_RESPONSES.INTERNAL_ERROR, {\n status: 500,\n headers: HEADERS.JSON,\n })\n },\n }\n }\n\n /**\n * Optimize TLS Configuration for Bun 1.39+\n */\n private optimizeTLS(tls: any): any {\n const isProd = process.env.NODE_ENV === 'production'\n\n const optimizeEntry = (entry: any) => {\n const optimized = { ...entry }\n if (typeof optimized.key === 'string' && !optimized.key.startsWith('-----BEGIN')) {\n optimized.key = require('bun').file(optimized.key)\n }\n if (typeof optimized.cert === 'string' && !optimized.cert.startsWith('-----BEGIN')) {\n optimized.cert = require('bun').file(optimized.cert)\n }\n if (isProd && optimized.lowMemoryMode === undefined) {\n optimized.lowMemoryMode = true\n }\n return optimized\n }\n\n return Array.isArray(tls) ? tls.map(optimizeEntry) : optimizeEntry(tls)\n }\n\n /**\n * Handle an incoming request\n */\n fetch = async (request: Request): Promise<Response> => {\n // Fast path: extract pathname without creating URL object\n const path = extractPath(request.url)\n const method = request.method.toLowerCase()\n\n // Try static route first (O(1) lookup, inlined for performance)\n const staticKey = `${method}:${path}`\n const staticRoute = this.staticRoutes.get(staticKey)\n\n if (staticRoute) {\n const ctx = this.contextPool.acquire()\n ctx.init(request, {}, path, path)\n\n try {\n const compiled =\n staticRoute.compiled ||\n compileMiddlewareChain(staticRoute.middleware, staticRoute.handler)\n const result = compiled(ctx)\n\n let response: Response\n if (result instanceof Promise) {\n const peeked = bunPeek(result)\n response = peeked === result ? await result : peeked\n } else {\n response = result\n }\n\n const cleanup = ctx.requestScope().cleanup()\n if (cleanup instanceof Promise) await cleanup\n this.contextPool.release(ctx)\n return response\n } catch (error) {\n const cleanup = ctx.requestScope().cleanup()\n if (cleanup instanceof Promise) await cleanup\n this.contextPool.release(ctx)\n return this.handleErrorSync(error as Error, request, path)\n }\n }\n\n // Dynamic route: use Radix Tree\n return await this.handleDynamicRoute(request, method, path)\n }\n\n /**\n * Handle dynamic routes with Radix Tree\n */\n private async handleDynamicRoute(\n request: Request,\n method: string,\n path: string\n ): Promise<Response> {\n const match = this.router.match(method, path)\n\n if (match.handler) {\n const ctx = this.contextPool.acquire()\n ctx.init(request, match.params, path, match.routePattern)\n\n try {\n // Use cached compilation if available\n const routeKey = `${method}:${match.routePattern}`\n let compiledObj = this.compiledDynamicRoutes.get(routeKey)\n\n if (!compiledObj || compiledObj.version !== this.router.version) {\n const compiled = compileMiddlewareChain(match.middleware, match.handler)\n compiledObj = { compiled, version: this.router.version }\n this.compiledDynamicRoutes.set(routeKey, compiledObj)\n }\n\n const result = compiledObj.compiled(ctx)\n\n let response: Response\n if (result instanceof Promise) {\n const peeked = bunPeek(result)\n response = peeked === result ? await result : peeked\n } else {\n response = result\n }\n\n const cleanup = ctx.requestScope().cleanup()\n if (cleanup instanceof Promise) await cleanup\n this.contextPool.release(ctx)\n return response\n } catch (error) {\n const cleanup = ctx.requestScope().cleanup()\n if (cleanup instanceof Promise) await cleanup\n this.contextPool.release(ctx)\n return this.handleErrorSync(error as Error, request, path)\n }\n }\n\n // 404\n return this.handleNotFoundSync(request, path)\n }\n\n /**\n * Sync error handler (for ultra-fast path)\n */\n private handleErrorSync(\n error: Error,\n request: Request,\n path: string\n ): Response | Promise<Response> {\n if (this.errorHandler) {\n const ctx = new MinimalContext(request, {}, path)\n const result = this.errorHandler(error, ctx)\n if (result instanceof Response) {\n return result\n }\n return result as Promise<Response>\n }\n\n console.error('Unhandled error:', error)\n return new Response(CACHED_RESPONSES.INTERNAL_ERROR, {\n status: 500,\n headers: HEADERS.JSON,\n })\n }\n\n /**\n * Sync 404 handler (for ultra-fast path)\n */\n private handleNotFoundSync(request: Request, path: string): Response | Promise<Response> {\n if (this.notFoundHandler) {\n const ctx = new MinimalContext(request, {}, path)\n const result = this.notFoundHandler(ctx)\n if (result instanceof Response) {\n return result\n }\n return result as Promise<Response>\n }\n\n return new Response(CACHED_RESPONSES.NOT_FOUND, {\n status: 404,\n headers: HEADERS.JSON,\n })\n }\n\n /**\n * Collect middleware for a specific path\n */\n private collectMiddlewareForPath(path: string, routeMiddleware: Middleware[]): Middleware[] {\n if (this.router.globalMiddleware.length === 0 && this.router.pathMiddleware.size === 0) {\n return routeMiddleware\n }\n\n return this.router.collectMiddlewarePublic(path, routeMiddleware)\n }\n\n /**\n * Compile routes for optimization\n */\n private compileRoutes(): void {\n this.staticRoutes = this.router.staticRoutes\n\n // Check if pure static app\n const hasGlobalMiddleware = this.router.globalMiddleware.length > 0\n const hasPathMiddleware = this.router.pathMiddleware.size > 0\n\n this.isPureStaticApp = !hasGlobalMiddleware && !hasPathMiddleware\n\n // Pre-mark routes\n for (const [key, route] of this.staticRoutes) {\n // Skip if already compiled for this version\n if (route.compiledVersion === this.router.version) {\n continue\n }\n\n const analysis = analyzeHandler(route.handler)\n const optimalType = getOptimalContextType(analysis)\n\n route.useMinimal =\n this.isPureStaticApp && route.middleware.length === 0 && optimalType === 'minimal'\n\n // Precompile middleware chain\n if (!route.useMinimal) {\n const allMiddleware = this.collectMiddlewareForPath(key.split(':')[1]!, route.middleware)\n route.compiled = compileMiddlewareChain(allMiddleware, route.handler)\n }\n\n route.compiledVersion = this.router.version\n }\n }\n\n /**\n * Add a route to the router\n */\n private addRoute(method: string, path: string, handlers: Handler[]): this {\n if (handlers.length === 0) {\n throw new Error(`No handler provided for ${method.toUpperCase()} ${path}`)\n }\n\n const handler = handlers[handlers.length - 1]!\n const middleware = handlers.slice(0, -1) as unknown as Middleware[]\n\n this.router.add(method as HttpMethod, path, handler, middleware)\n\n // Re-compile routes when new ones are added\n this.compileRoutes()\n\n return this\n }\n}\n"
|
|
18
|
+
],
|
|
19
|
+
"mappings": "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",
|
|
20
|
+
"debugId": "46FB5CAED852799864756E2164756E21",
|
|
21
|
+
"names": []
|
|
22
|
+
}
|