@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.
Files changed (173) hide show
  1. package/README.md +100 -6
  2. package/README.zh-TW.md +101 -6
  3. package/dist/Application.d.ts +256 -0
  4. package/dist/CommandKernel.d.ts +33 -0
  5. package/dist/ConfigManager.d.ts +65 -0
  6. package/dist/Container/RequestScopeManager.d.ts +62 -0
  7. package/dist/Container/RequestScopeMetrics.d.ts +144 -0
  8. package/dist/Container.d.ts +153 -0
  9. package/dist/ErrorHandler.d.ts +66 -0
  10. package/dist/Event.d.ts +5 -0
  11. package/dist/EventManager.d.ts +123 -0
  12. package/dist/GlobalErrorHandlers.d.ts +47 -0
  13. package/dist/GravitoServer.d.ts +28 -0
  14. package/dist/HookManager.d.ts +435 -0
  15. package/dist/Listener.d.ts +4 -0
  16. package/dist/Logger.d.ts +20 -0
  17. package/dist/PlanetCore.d.ts +402 -0
  18. package/dist/RequestContext.d.ts +97 -0
  19. package/dist/Route.d.ts +36 -0
  20. package/dist/Router.d.ts +270 -0
  21. package/dist/ServiceProvider.d.ts +178 -0
  22. package/dist/adapters/GravitoEngineAdapter.d.ts +27 -0
  23. package/dist/adapters/bun/AdaptiveAdapter.d.ts +99 -0
  24. package/dist/adapters/bun/BunContext.d.ts +54 -0
  25. package/dist/adapters/bun/BunNativeAdapter.d.ts +66 -0
  26. package/dist/adapters/bun/BunRequest.d.ts +31 -0
  27. package/dist/adapters/bun/BunWebSocketHandler.d.ts +48 -0
  28. package/dist/adapters/bun/RadixNode.d.ts +19 -0
  29. package/dist/adapters/bun/RadixRouter.d.ts +32 -0
  30. package/dist/adapters/bun/index.d.ts +7 -0
  31. package/dist/adapters/bun/types.d.ts +20 -0
  32. package/dist/adapters/index.d.ts +12 -0
  33. package/dist/adapters/types.d.ts +235 -0
  34. package/dist/binary/BinaryUtils.d.ts +105 -0
  35. package/dist/binary/index.d.ts +5 -0
  36. package/dist/cli/queue-commands.d.ts +6 -0
  37. package/dist/compat/async-local-storage.browser.d.ts +9 -0
  38. package/dist/compat/async-local-storage.d.ts +7 -0
  39. package/dist/compat/crypto.browser.d.ts +5 -0
  40. package/dist/compat/crypto.d.ts +6 -0
  41. package/dist/compat.cjs +42 -11
  42. package/dist/compat.cjs.map +9 -0
  43. package/dist/compat.d.ts +23 -1
  44. package/dist/compat.js +3 -0
  45. package/dist/compat.js.map +9 -0
  46. package/dist/engine/AOTRouter.d.ts +139 -0
  47. package/dist/engine/FastContext.d.ts +141 -0
  48. package/dist/engine/Gravito.d.ts +131 -0
  49. package/dist/engine/MinimalContext.d.ts +102 -0
  50. package/dist/engine/analyzer.d.ts +113 -0
  51. package/dist/engine/constants.d.ts +23 -0
  52. package/dist/engine/index.cjs +576 -647
  53. package/dist/engine/index.cjs.map +22 -0
  54. package/dist/engine/index.d.ts +14 -910
  55. package/dist/engine/index.js +576 -623
  56. package/dist/engine/index.js.map +22 -0
  57. package/dist/engine/path.d.ts +26 -0
  58. package/dist/engine/pool.d.ts +83 -0
  59. package/dist/engine/types.d.ts +149 -0
  60. package/dist/error-handling/RequestScopeErrorContext.d.ts +126 -0
  61. package/dist/events/BackpressureManager.d.ts +215 -0
  62. package/dist/events/CircuitBreaker.d.ts +229 -0
  63. package/dist/events/DeadLetterQueue.d.ts +219 -0
  64. package/dist/events/EventBackend.d.ts +12 -0
  65. package/dist/events/EventOptions.d.ts +204 -0
  66. package/dist/events/EventPriorityQueue.d.ts +63 -0
  67. package/dist/events/FlowControlStrategy.d.ts +109 -0
  68. package/dist/events/IdempotencyCache.d.ts +60 -0
  69. package/dist/events/MessageQueueBridge.d.ts +184 -0
  70. package/dist/events/PriorityEscalationManager.d.ts +82 -0
  71. package/dist/events/RetryScheduler.d.ts +104 -0
  72. package/dist/events/WorkerPool.d.ts +98 -0
  73. package/dist/events/WorkerPoolConfig.d.ts +153 -0
  74. package/dist/events/WorkerPoolMetrics.d.ts +65 -0
  75. package/dist/events/aggregation/AggregationWindow.d.ts +77 -0
  76. package/dist/events/aggregation/DeduplicationManager.d.ts +135 -0
  77. package/dist/events/aggregation/EventAggregationManager.d.ts +108 -0
  78. package/dist/events/aggregation/EventBatcher.d.ts +99 -0
  79. package/dist/events/aggregation/index.d.ts +10 -0
  80. package/dist/events/aggregation/types.d.ts +117 -0
  81. package/dist/events/index.d.ts +26 -0
  82. package/dist/events/observability/EventMetrics.d.ts +132 -0
  83. package/dist/events/observability/EventTracer.d.ts +68 -0
  84. package/dist/events/observability/EventTracing.d.ts +161 -0
  85. package/dist/events/observability/OTelEventMetrics.d.ts +332 -0
  86. package/dist/events/observability/ObservableHookManager.d.ts +108 -0
  87. package/dist/events/observability/StreamWorkerMetrics.d.ts +76 -0
  88. package/dist/events/observability/index.d.ts +24 -0
  89. package/dist/events/observability/metrics-types.d.ts +16 -0
  90. package/dist/events/queue-core.d.ts +77 -0
  91. package/dist/events/task-executor.d.ts +51 -0
  92. package/dist/events/types.d.ts +134 -0
  93. package/dist/exceptions/AuthenticationException.d.ts +8 -0
  94. package/dist/exceptions/AuthorizationException.d.ts +8 -0
  95. package/dist/exceptions/CircularDependencyException.d.ts +9 -0
  96. package/dist/exceptions/GravitoException.d.ts +23 -0
  97. package/dist/exceptions/HttpException.d.ts +9 -0
  98. package/dist/exceptions/ModelNotFoundException.d.ts +10 -0
  99. package/dist/exceptions/ValidationException.d.ts +22 -0
  100. package/dist/exceptions/index.d.ts +7 -0
  101. package/dist/ffi/NativeAccelerator.d.ts +69 -0
  102. package/dist/ffi/NativeHasher.d.ts +139 -0
  103. package/dist/ffi/cbor-fallback.d.ts +96 -0
  104. package/dist/ffi/hash-fallback.d.ts +33 -0
  105. package/dist/ffi/index.cjs +621 -0
  106. package/dist/ffi/index.cjs.map +14 -0
  107. package/dist/ffi/index.d.ts +10 -0
  108. package/dist/ffi/index.js +602 -0
  109. package/dist/ffi/index.js.map +14 -0
  110. package/dist/ffi/types.d.ts +135 -0
  111. package/dist/health/HealthProvider.d.ts +67 -0
  112. package/dist/helpers/Arr.d.ts +19 -0
  113. package/dist/helpers/Str.d.ts +38 -0
  114. package/dist/helpers/data.d.ts +25 -0
  115. package/dist/helpers/errors.d.ts +34 -0
  116. package/dist/helpers/response.d.ts +41 -0
  117. package/dist/helpers.d.ts +338 -0
  118. package/dist/hooks/ActionManager.d.ts +132 -0
  119. package/dist/hooks/AsyncDetector.d.ts +84 -0
  120. package/dist/hooks/FilterManager.d.ts +71 -0
  121. package/dist/hooks/MigrationWarner.d.ts +24 -0
  122. package/dist/hooks/dlq-operations.d.ts +60 -0
  123. package/dist/hooks/index.d.ts +11 -0
  124. package/dist/hooks/types.d.ts +107 -0
  125. package/dist/http/CookieJar.d.ts +51 -0
  126. package/dist/http/cookie.d.ts +29 -0
  127. package/dist/http/index.d.ts +12 -0
  128. package/dist/{compat-CI8hiulX.d.cts → http/types.d.ts} +29 -16
  129. package/dist/index.browser.d.ts +34 -0
  130. package/dist/index.cjs +10525 -11171
  131. package/dist/index.cjs.map +168 -0
  132. package/dist/index.d.ts +58 -10981
  133. package/dist/index.js +10861 -10997
  134. package/dist/index.js.map +168 -0
  135. package/dist/observability/QueueDashboard.d.ts +136 -0
  136. package/dist/observability/contracts.d.ts +137 -0
  137. package/dist/observability/index.d.ts +13 -0
  138. package/dist/reliability/DeadLetterQueueManager.d.ts +349 -0
  139. package/dist/reliability/RetryPolicy.d.ts +217 -0
  140. package/dist/reliability/index.d.ts +6 -0
  141. package/dist/router/ControllerDispatcher.d.ts +12 -0
  142. package/dist/router/RequestValidator.d.ts +20 -0
  143. package/dist/runtime/adapter-bun.d.ts +12 -0
  144. package/dist/runtime/adapter-deno.d.ts +12 -0
  145. package/dist/runtime/adapter-node.d.ts +12 -0
  146. package/dist/runtime/adapter-unknown.d.ts +13 -0
  147. package/dist/runtime/archive.d.ts +17 -0
  148. package/dist/runtime/compression.d.ts +21 -0
  149. package/dist/runtime/deep-equals.d.ts +56 -0
  150. package/dist/runtime/detection.d.ts +22 -0
  151. package/dist/runtime/escape.d.ts +34 -0
  152. package/dist/runtime/index.browser.d.ts +20 -0
  153. package/dist/runtime/index.d.ts +44 -0
  154. package/dist/runtime/markdown.d.ts +44 -0
  155. package/dist/runtime/types.d.ts +436 -0
  156. package/dist/runtime-helpers.d.ts +67 -0
  157. package/dist/runtime.d.ts +11 -0
  158. package/dist/security/Encrypter.d.ts +33 -0
  159. package/dist/security/Hasher.d.ts +29 -0
  160. package/dist/testing/HttpTester.d.ts +39 -0
  161. package/dist/testing/TestResponse.d.ts +78 -0
  162. package/dist/testing/index.d.ts +2 -0
  163. package/dist/transpiler-utils.d.ts +170 -0
  164. package/dist/types/events.d.ts +94 -0
  165. package/dist/types.d.ts +13 -0
  166. package/package.json +21 -52
  167. package/src/ffi/native/cbor.c +1148 -0
  168. package/dist/Metrics-VOWWRNNR.js +0 -219
  169. package/dist/chunk-R5U7XKVJ.js +0 -16
  170. package/dist/compat-CI8hiulX.d.ts +0 -376
  171. package/dist/compat.d.cts +0 -1
  172. package/dist/engine/index.d.cts +0 -922
  173. package/dist/index.d.cts +0 -11008
@@ -1,26 +1,52 @@
1
+ // @bun
2
+ var __create = Object.create;
3
+ var __getProtoOf = Object.getPrototypeOf;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __toESM = (mod, isNodeMode, target) => {
8
+ target = mod != null ? __create(__getProtoOf(mod)) : {};
9
+ const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
10
+ for (let key of __getOwnPropNames(mod))
11
+ if (!__hasOwnProp.call(to, key))
12
+ __defProp(to, key, {
13
+ get: () => mod[key],
14
+ enumerable: true
15
+ });
16
+ return to;
17
+ };
18
+ var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
19
+ var __export = (target, all) => {
20
+ for (var name in all)
21
+ __defProp(target, name, {
22
+ get: all[name],
23
+ enumerable: true,
24
+ configurable: true,
25
+ set: (newValue) => all[name] = () => newValue
26
+ });
27
+ };
28
+ var __require = import.meta.require;
29
+
30
+ // src/engine/index.ts
31
+ var exports_engine = {};
32
+ __export(exports_engine, {
33
+ extractPath: () => extractPath,
34
+ ObjectPool: () => ObjectPool,
35
+ MinimalContext: () => MinimalContext,
36
+ Gravito: () => Gravito,
37
+ FastContextImpl: () => FastContext,
38
+ AOTRouter: () => AOTRouter
39
+ });
40
+
1
41
  // src/adapters/bun/RadixNode.ts
2
- var RadixNode = class _RadixNode {
3
- // Path segment for this node (e.g., "users", ":id")
42
+ class RadixNode {
4
43
  segment;
5
- // Node type (Static, Param, Wildcard)
6
44
  type;
7
- // Children nodes (mapped by segment for fast lookup)
8
- children = /* @__PURE__ */ new Map();
9
- // Specialized child for parameter node (only one per level allowed usually to avoid ambiguity, though some routers support multiple)
45
+ children = new Map;
10
46
  paramChild = null;
11
- // Specialized child for wildcard node
12
47
  wildcardChild = null;
13
- // Handlers registered at this node (keyed by HTTP method)
14
- handlers = /* @__PURE__ */ new Map();
15
- // Parameter name if this is a PARAM node (e.g., "id" for ":id")
48
+ handlers = new Map;
16
49
  paramName = null;
17
- // Parameter constraints (regex) - only applicable if this is a PARAM node
18
- // If we support per-route constraints, they might need to be stored differently,
19
- // but for now assume constraints are defined at node level (uncommon) or checked at match time.
20
- // Laravel allows global pattern constraints or per-route.
21
- // Ideally, constraints should be stored with the handler or part of matching logic.
22
- // For a Radix tree, if we have constraints, we might need to backtrack if constraint fails?
23
- // Or simply store constraint with the param node.
24
50
  regex = null;
25
51
  constructor(segment = "", type = 0 /* STATIC */) {
26
52
  this.segment = segment;
@@ -38,44 +64,61 @@ var RadixNode = class _RadixNode {
38
64
  };
39
65
  }
40
66
  static fromJSON(json) {
41
- const node = new _RadixNode(json.segment, json.type);
67
+ const node = new RadixNode(json.segment, json.type);
42
68
  node.paramName = json.paramName;
43
69
  if (json.regex) {
44
70
  node.regex = new RegExp(json.regex);
45
71
  }
46
72
  if (json.children) {
47
73
  for (const [key, childJson] of json.children) {
48
- node.children.set(key, _RadixNode.fromJSON(childJson));
74
+ node.children.set(key, RadixNode.fromJSON(childJson));
49
75
  }
50
76
  }
51
77
  if (json.paramChild) {
52
- node.paramChild = _RadixNode.fromJSON(json.paramChild);
78
+ node.paramChild = RadixNode.fromJSON(json.paramChild);
53
79
  }
54
80
  if (json.wildcardChild) {
55
- node.wildcardChild = _RadixNode.fromJSON(json.wildcardChild);
81
+ node.wildcardChild = RadixNode.fromJSON(json.wildcardChild);
56
82
  }
57
83
  return node;
58
84
  }
59
- };
85
+ }
60
86
 
61
87
  // src/adapters/bun/RadixRouter.ts
62
- var RadixRouter = class _RadixRouter {
63
- root = new RadixNode();
64
- // Global parameter constraints (e.g., id => /^\d+$/)
65
- globalConstraints = /* @__PURE__ */ new Map();
66
- /**
67
- * Add a generic parameter constraint
68
- */
88
+ class RouteCache {
89
+ cache = new Map;
90
+ maxSize = 1e4;
91
+ get(key) {
92
+ return this.cache.get(key);
93
+ }
94
+ set(key, value) {
95
+ if (this.cache.size >= this.maxSize) {
96
+ const firstKey = this.cache.keys().next().value;
97
+ if (firstKey) {
98
+ this.cache.delete(firstKey);
99
+ }
100
+ }
101
+ this.cache.set(key, value);
102
+ }
103
+ clear() {
104
+ this.cache.clear();
105
+ }
106
+ has(key) {
107
+ return this.cache.has(key);
108
+ }
109
+ }
110
+
111
+ class RadixRouter {
112
+ root = new RadixNode;
113
+ globalConstraints = new Map;
114
+ routeCache = new RouteCache;
69
115
  where(param, regex) {
70
116
  this.globalConstraints.set(param, regex);
71
117
  }
72
- /**
73
- * Register a route
74
- */
75
118
  add(method, path, handlers) {
76
119
  let node = this.root;
77
120
  const segments = this.splitPath(path);
78
- for (let i = 0; i < segments.length; i++) {
121
+ for (let i = 0;i < segments.length; i++) {
79
122
  const segment = segments[i];
80
123
  if (segment === "*") {
81
124
  if (!node.wildcardChild) {
@@ -103,10 +146,8 @@ var RadixRouter = class _RadixRouter {
103
146
  }
104
147
  }
105
148
  node.handlers.set(method.toLowerCase(), handlers);
149
+ this.routeCache.clear();
106
150
  }
107
- /**
108
- * Match a request
109
- */
110
151
  match(method, path) {
111
152
  const normalizedMethod = method.toLowerCase();
112
153
  if (path === "/" || path === "") {
@@ -116,9 +157,15 @@ var RadixRouter = class _RadixRouter {
116
157
  }
117
158
  return null;
118
159
  }
160
+ const cacheKey = `${normalizedMethod}:${path}`;
161
+ if (this.routeCache.has(cacheKey)) {
162
+ return this.routeCache.get(cacheKey) ?? null;
163
+ }
119
164
  const searchPath = path.startsWith("/") ? path.slice(1) : path;
120
165
  const segments = searchPath.split("/");
121
- return this.matchRecursive(this.root, segments, 0, {}, normalizedMethod);
166
+ const result = this.matchRecursive(this.root, segments, 0, {}, normalizedMethod);
167
+ this.routeCache.set(cacheKey, result);
168
+ return result;
122
169
  }
123
170
  matchRecursive(node, segments, depth, params, method) {
124
171
  if (depth >= segments.length) {
@@ -141,8 +188,7 @@ var RadixRouter = class _RadixRouter {
141
188
  }
142
189
  const paramChild = node.paramChild;
143
190
  if (paramChild) {
144
- if (paramChild.regex && !paramChild.regex.test(segment)) {
145
- } else {
191
+ if (paramChild.regex && !paramChild.regex.test(segment)) {} else {
146
192
  if (paramChild.paramName) {
147
193
  params[paramChild.paramName] = decodeURIComponent(segment);
148
194
  const match = this.matchRecursive(paramChild, segments, depth + 1, params, method);
@@ -177,9 +223,6 @@ var RadixRouter = class _RadixRouter {
177
223
  }
178
224
  return p.split("/");
179
225
  }
180
- /**
181
- * Serialize the router to a JSON string
182
- */
183
226
  serialize() {
184
227
  return JSON.stringify({
185
228
  root: this.root.toJSON(),
@@ -189,12 +232,9 @@ var RadixRouter = class _RadixRouter {
189
232
  ])
190
233
  });
191
234
  }
192
- /**
193
- * Restore a router from a serialized JSON string
194
- */
195
235
  static fromSerialized(json) {
196
236
  const data = JSON.parse(json);
197
- const router = new _RadixRouter();
237
+ const router = new RadixRouter;
198
238
  router.root = RadixNode.fromJSON(data.root);
199
239
  if (data.globalConstraints) {
200
240
  for (const [key, source] of data.globalConstraints) {
@@ -203,49 +243,22 @@ var RadixRouter = class _RadixRouter {
203
243
  }
204
244
  return router;
205
245
  }
206
- };
246
+ }
207
247
 
208
248
  // src/engine/AOTRouter.ts
209
- var AOTRouter = class {
210
- // Static route cache: "METHOD:PATH" -> RouteMetadata
211
- /** @internal */
212
- staticRoutes = /* @__PURE__ */ new Map();
213
- // Dynamic route handler (Radix Tree)
214
- dynamicRouter = new RadixRouter();
215
- // Store all route definitions to support mounting/merging
216
- /** @internal */
249
+ class AOTRouter {
250
+ staticRoutes = new Map;
251
+ dynamicRouter = new RadixRouter;
217
252
  routeDefinitions = [];
218
- // Global middleware (applies to all routes)
219
- /** @internal */
220
253
  globalMiddleware = [];
221
- // Path-based middleware: pattern -> middleware[]
222
- /** @internal */
223
- pathMiddleware = /* @__PURE__ */ new Map();
224
- // Dynamic route patterns: handler function -> route pattern
225
- // 用於追蹤動態路由的模式,防止高基數問題
226
- dynamicRoutePatterns = /* @__PURE__ */ new Map();
227
- middlewareCache = /* @__PURE__ */ new Map();
228
- cacheMaxSize = 1e3;
254
+ pathMiddleware = new Map;
255
+ dynamicRoutePatterns = new Map;
256
+ middlewareCache = new Map;
257
+ cacheMaxSize = 1000;
229
258
  _version = 0;
230
- /**
231
- * Get the current version for cache invalidation
232
- * Incremented whenever middleware or routes are modified
233
- */
234
259
  get version() {
235
260
  return this._version;
236
261
  }
237
- /**
238
- * Register a route
239
- *
240
- * Automatically determines if route is static or dynamic.
241
- * Static routes are stored in a Map for O(1) lookup.
242
- * Dynamic routes use the Radix Tree.
243
- *
244
- * @param method - HTTP method
245
- * @param path - Route path
246
- * @param handler - Route handler
247
- * @param middleware - Route-specific middleware
248
- */
249
262
  add(method, path, handler, middleware = []) {
250
263
  this.routeDefinitions.push({ method, path, handler, middleware });
251
264
  const normalizedMethod = method.toLowerCase();
@@ -261,9 +274,6 @@ var AOTRouter = class {
261
274
  }
262
275
  }
263
276
  }
264
- /**
265
- * Mount another router at a prefix
266
- */
267
277
  mount(prefix, other) {
268
278
  if (other.globalMiddleware.length > 0) {
269
279
  this.usePattern(prefix, ...other.globalMiddleware);
@@ -271,7 +281,8 @@ var AOTRouter = class {
271
281
  this.usePattern(wildcard, ...other.globalMiddleware);
272
282
  }
273
283
  for (const [pattern, mws] of other.pathMiddleware) {
274
- if (pattern.includes(":")) {
284
+ const hasMethodPrefix = /^(get|post|put|delete|patch|options|head):/.test(pattern);
285
+ if (hasMethodPrefix) {
275
286
  continue;
276
287
  }
277
288
  let newPattern;
@@ -296,25 +307,10 @@ var AOTRouter = class {
296
307
  this.add(def.method, newPath, def.handler, def.middleware);
297
308
  }
298
309
  }
299
- /**
300
- * Add global middleware
301
- *
302
- * These run for every request, before route-specific middleware.
303
- *
304
- * @param middleware - Middleware functions
305
- */
306
310
  use(...middleware) {
307
311
  this.globalMiddleware.push(...middleware);
308
312
  this._version++;
309
313
  }
310
- /**
311
- * Add path-based middleware
312
- *
313
- * Supports wildcard patterns like '/api/*'
314
- *
315
- * @param pattern - Path pattern
316
- * @param middleware - Middleware functions
317
- */
318
314
  usePattern(pattern, ...middleware) {
319
315
  if (pattern === "*") {
320
316
  this.globalMiddleware.push(...middleware);
@@ -324,15 +320,6 @@ var AOTRouter = class {
324
320
  }
325
321
  this._version++;
326
322
  }
327
- /**
328
- * Match a request to a route
329
- *
330
- * Returns the handler, params, and all applicable middleware.
331
- *
332
- * @param method - HTTP method
333
- * @param path - Request path
334
- * @returns Route match or null if not found
335
- */
336
323
  match(method, path) {
337
324
  const normalizedMethod = method.toLowerCase();
338
325
  const staticKey = `${normalizedMethod}:${path}`;
@@ -365,28 +352,16 @@ var AOTRouter = class {
365
352
  middleware: []
366
353
  };
367
354
  }
368
- /**
369
- * Public wrapper for collectMiddleware (used by Gravito for optimization)
370
- */
371
355
  collectMiddlewarePublic(path, routeMiddleware) {
372
356
  return this.collectMiddleware(path, routeMiddleware);
373
357
  }
374
- /**
375
- * Collect all applicable middleware for a path
376
- *
377
- * Order: global -> pattern-based -> route-specific
378
- *
379
- * @param path - Request path
380
- * @param routeMiddleware - Route-specific middleware
381
- * @returns Combined middleware array
382
- */
383
358
  collectMiddleware(path, routeMiddleware) {
384
359
  if (this.globalMiddleware.length === 0 && this.pathMiddleware.size === 0 && routeMiddleware.length === 0) {
385
360
  return [];
386
361
  }
387
362
  const cacheKey = path;
388
363
  const cached = this.middlewareCache.get(cacheKey);
389
- if (cached !== void 0 && cached.version === this._version) {
364
+ if (cached !== undefined && cached.version === this._version) {
390
365
  return cached.data;
391
366
  }
392
367
  const middleware = [];
@@ -413,23 +388,21 @@ var AOTRouter = class {
413
388
  }
414
389
  return middleware;
415
390
  }
416
- /**
417
- * Check if a path is static (no parameters or wildcards)
418
- */
391
+ getNativeRoutes(onMatch) {
392
+ const routes = {};
393
+ for (const [key, metadata] of this.staticRoutes) {
394
+ const [method, path] = key.split(":");
395
+ if (method !== "get") {
396
+ continue;
397
+ }
398
+ const allMiddleware = this.collectMiddleware(path, metadata.middleware);
399
+ routes[path] = onMatch(metadata.handler, allMiddleware, path);
400
+ }
401
+ return routes;
402
+ }
419
403
  isStaticPath(path) {
420
404
  return !path.includes(":") && !path.includes("*");
421
405
  }
422
- /**
423
- * Match a pattern against a path
424
- *
425
- * Supports:
426
- * - Exact match: '/api/users'
427
- * - Wildcard suffix: '/api/*'
428
- *
429
- * @param pattern - Pattern to match
430
- * @param path - Path to test
431
- * @returns True if pattern matches
432
- */
433
406
  matchPattern(pattern, path) {
434
407
  if (pattern === "*") {
435
408
  return true;
@@ -443,9 +416,6 @@ var AOTRouter = class {
443
416
  }
444
417
  return false;
445
418
  }
446
- /**
447
- * Get all registered routes (for debugging)
448
- */
449
419
  getRoutes() {
450
420
  const routes = [];
451
421
  for (const key of this.staticRoutes.keys()) {
@@ -454,11 +424,107 @@ var AOTRouter = class {
454
424
  }
455
425
  return routes;
456
426
  }
457
- };
427
+ }
458
428
 
459
- // src/engine/analyzer.ts
460
- function analyzeHandler(handler) {
461
- const source = handler.toString();
429
+ // src/transpiler-utils.ts
430
+ class TranspilerCache {
431
+ static instance = null;
432
+ transpiler;
433
+ cache;
434
+ maxSize;
435
+ ttlMs;
436
+ constructor(maxSize = 512, ttlMs = 5 * 60 * 1000) {
437
+ this.transpiler = new Bun.Transpiler({ loader: "ts" });
438
+ this.cache = new Map;
439
+ this.maxSize = maxSize;
440
+ this.ttlMs = ttlMs;
441
+ }
442
+ static getInstance() {
443
+ TranspilerCache.instance ??= new TranspilerCache;
444
+ return TranspilerCache.instance;
445
+ }
446
+ static resetInstance() {
447
+ TranspilerCache.instance = null;
448
+ }
449
+ transform(source) {
450
+ const cached = this.cache.get(source);
451
+ if (cached !== undefined) {
452
+ if (Date.now() - cached.createdAt < this.ttlMs) {
453
+ return cached.transformed;
454
+ }
455
+ this.cache.delete(source);
456
+ }
457
+ const transformed = this.doTransform(source);
458
+ if (transformed === null) {
459
+ return null;
460
+ }
461
+ if (this.cache.size >= this.maxSize) {
462
+ const firstKey = this.cache.keys().next().value;
463
+ if (firstKey !== undefined) {
464
+ this.cache.delete(firstKey);
465
+ }
466
+ }
467
+ this.cache.set(source, { transformed, createdAt: Date.now() });
468
+ return transformed;
469
+ }
470
+ doTransform(source) {
471
+ try {
472
+ const out = this.transpiler.transformSync(source);
473
+ if (out.trim().length > 0) {
474
+ return out;
475
+ }
476
+ return this.transformWrapped(source);
477
+ } catch {
478
+ return this.transformWrapped(source);
479
+ }
480
+ }
481
+ transformWrapped(source) {
482
+ try {
483
+ const wrapped = `const __fn = ${source}`;
484
+ const out = this.transpiler.transformSync(wrapped);
485
+ return out.trim().length > 0 ? out : null;
486
+ } catch {
487
+ return null;
488
+ }
489
+ }
490
+ get size() {
491
+ return this.cache.size;
492
+ }
493
+ clear() {
494
+ this.cache.clear();
495
+ }
496
+ }
497
+ var PATTERNS = {
498
+ HEADERS_CALL: /\.req\.headers?\s*\(/,
499
+ HEADERS_DESTR: /\{[^}]*\bheaders?\b[^}]*\}\s*=\s*\w+\.req/,
500
+ QUERY_CALL: /\.req\.quer(?:y|ies)\s*\(/,
501
+ QUERY_DESTR: /\{[^}]*\bquer(?:y|ies)\b[^}]*\}\s*=\s*\w+\.req/,
502
+ BODY_CALL: /\.req\.(?:json|text|formData|blob|arrayBuffer)\s*\(/,
503
+ BODY_DESTR: /\{[^}]*\bbody\b[^}]*\}\s*=\s*\w+\.req/,
504
+ BODY_PROP: /\.req\.body\b/,
505
+ PARAMS_CALL: /\.req\.params?\s*\(/,
506
+ PARAMS_DESTR: /\{[^}]*\bparams?\b[^}]*\}\s*=\s*\w+\.req/,
507
+ IS_ASYNC: /\basync\b/
508
+ };
509
+ function analyzeHandlerWithTranspiler(source) {
510
+ const cache = TranspilerCache.getInstance();
511
+ const transformed = cache.transform(source);
512
+ const isAsync = PATTERNS.IS_ASYNC.test(source);
513
+ if (transformed !== null) {
514
+ return { ...analyzeTransformedCode(transformed), isAsync };
515
+ }
516
+ return { ...fallbackStringAnalysis(source), isAsync };
517
+ }
518
+ function analyzeTransformedCode(code) {
519
+ return {
520
+ usesHeaders: PATTERNS.HEADERS_CALL.test(code) || PATTERNS.HEADERS_DESTR.test(code),
521
+ usesQuery: PATTERNS.QUERY_CALL.test(code) || PATTERNS.QUERY_DESTR.test(code),
522
+ usesBody: PATTERNS.BODY_CALL.test(code) || PATTERNS.BODY_DESTR.test(code) || PATTERNS.BODY_PROP.test(code),
523
+ usesParams: PATTERNS.PARAMS_CALL.test(code) || PATTERNS.PARAMS_DESTR.test(code),
524
+ isAsync: PATTERNS.IS_ASYNC.test(code)
525
+ };
526
+ }
527
+ function fallbackStringAnalysis(source) {
462
528
  return {
463
529
  usesHeaders: source.includes(".header(") || source.includes(".header)") || source.includes(".headers(") || source.includes(".headers)"),
464
530
  usesQuery: source.includes(".query(") || source.includes(".query)") || source.includes(".queries(") || source.includes(".queries)"),
@@ -467,6 +533,12 @@ function analyzeHandler(handler) {
467
533
  isAsync: source.includes("async") || source.includes("await")
468
534
  };
469
535
  }
536
+
537
+ // src/engine/analyzer.ts
538
+ function analyzeHandler(handler) {
539
+ const source = handler.toString();
540
+ return analyzeHandlerWithTranspiler(source);
541
+ }
470
542
  function getOptimalContextType(analysis) {
471
543
  if (analysis.usesHeaders) {
472
544
  return "fast";
@@ -484,7 +556,7 @@ function getOptimalContextType(analysis) {
484
556
  }
485
557
 
486
558
  // src/engine/constants.ts
487
- var encoder = new TextEncoder();
559
+ var encoder = new TextEncoder;
488
560
  var CACHED_RESPONSES = {
489
561
  NOT_FOUND: encoder.encode('{"error":"Not Found"}'),
490
562
  INTERNAL_ERROR: encoder.encode('{"error":"Internal Server Error"}'),
@@ -498,25 +570,15 @@ var HEADERS = {
498
570
  };
499
571
 
500
572
  // src/Container/RequestScopeMetrics.ts
501
- var RequestScopeMetrics = class {
573
+ class RequestScopeMetrics {
502
574
  cleanupStartTime = null;
503
575
  cleanupDuration = null;
504
576
  scopeSize = 0;
505
577
  servicesCleaned = 0;
506
578
  errorsOccurred = 0;
507
- /**
508
- * Record start of cleanup operation
509
- */
510
579
  recordCleanupStart() {
511
580
  this.cleanupStartTime = performance.now();
512
581
  }
513
- /**
514
- * Record end of cleanup operation
515
- *
516
- * @param scopeSize - Number of services in the scope
517
- * @param servicesCleaned - Number of services that had cleanup called
518
- * @param errorsOccurred - Number of cleanup errors
519
- */
520
582
  recordCleanupEnd(scopeSize, servicesCleaned, errorsOccurred = 0) {
521
583
  if (this.cleanupStartTime !== null) {
522
584
  this.cleanupDuration = performance.now() - this.cleanupStartTime;
@@ -526,28 +588,15 @@ var RequestScopeMetrics = class {
526
588
  this.servicesCleaned = servicesCleaned;
527
589
  this.errorsOccurred = errorsOccurred;
528
590
  }
529
- /**
530
- * Get cleanup duration in milliseconds
531
- *
532
- * @returns Duration in ms, or null if cleanup not completed
533
- */
534
591
  getCleanupDuration() {
535
592
  return this.cleanupDuration;
536
593
  }
537
- /**
538
- * Check if cleanup took longer than threshold (default 2ms)
539
- * Useful for detecting slow cleanups
540
- *
541
- * @param thresholdMs - Threshold in milliseconds
542
- * @returns True if cleanup exceeded threshold
543
- */
544
594
  isSlowCleanup(thresholdMs = 2) {
545
- if (this.cleanupDuration === null) return false;
595
+ if (this.cleanupDuration === null) {
596
+ return false;
597
+ }
546
598
  return this.cleanupDuration > thresholdMs;
547
599
  }
548
- /**
549
- * Export metrics as JSON for logging/monitoring
550
- */
551
600
  toJSON() {
552
601
  return {
553
602
  cleanupDuration: this.cleanupDuration,
@@ -558,49 +607,66 @@ var RequestScopeMetrics = class {
558
607
  isSlowCleanup: this.isSlowCleanup()
559
608
  };
560
609
  }
561
- /**
562
- * Export metrics as compact string for logging
563
- */
564
610
  toString() {
565
611
  const duration = this.cleanupDuration ?? "pending";
566
- return `cleanup: ${duration}ms, scope: ${this.scopeSize}, cleaned: ${this.servicesCleaned}, errors: ${this.errorsOccurred}`;
612
+ return `cleanup: ${duration}ms, ` + `scope: ${this.scopeSize}, ` + `cleaned: ${this.servicesCleaned}, ` + `errors: ${this.errorsOccurred}`;
567
613
  }
568
- };
614
+ }
615
+
616
+ class RequestScopeMetricsCollector {
617
+ metrics = [];
618
+ record(metrics) {
619
+ this.metrics.push(metrics);
620
+ }
621
+ getStats() {
622
+ if (this.metrics.length === 0) {
623
+ return {
624
+ count: 0,
625
+ averageCleanupTime: null,
626
+ maxCleanupTime: null,
627
+ minCleanupTime: null,
628
+ totalErrorCount: 0,
629
+ errorRate: 0
630
+ };
631
+ }
632
+ const durations = this.metrics.map((m) => m.getCleanupDuration()).filter((d) => d !== null);
633
+ const errorCounts = this.metrics.map((m) => m.toJSON().errorsOccurred);
634
+ const totalErrors = errorCounts.reduce((a, b) => a + b, 0);
635
+ return {
636
+ count: this.metrics.length,
637
+ averageCleanupTime: durations.length > 0 ? durations.reduce((a, b) => a + b) / durations.length : null,
638
+ maxCleanupTime: durations.length > 0 ? Math.max(...durations) : null,
639
+ minCleanupTime: durations.length > 0 ? Math.min(...durations) : null,
640
+ totalErrorCount: totalErrors,
641
+ errorRate: totalErrors / this.metrics.length
642
+ };
643
+ }
644
+ clear() {
645
+ this.metrics = [];
646
+ }
647
+ size() {
648
+ return this.metrics.length;
649
+ }
650
+ toJSON() {
651
+ return this.metrics.map((m) => m.toJSON());
652
+ }
653
+ }
569
654
 
570
655
  // src/Container/RequestScopeManager.ts
571
- var RequestScopeManager = class {
572
- scoped = /* @__PURE__ */ new Map();
573
- metadata = /* @__PURE__ */ new Map();
574
- metrics = new RequestScopeMetrics();
656
+ class RequestScopeManager {
657
+ scoped = new Map;
658
+ metadata = new Map;
659
+ metrics = new RequestScopeMetrics;
575
660
  observer = null;
576
661
  constructor(observer) {
577
662
  this.observer = observer || null;
578
663
  }
579
- /**
580
- * Set observer for monitoring scope lifecycle
581
- */
582
664
  setObserver(observer) {
583
665
  this.observer = observer;
584
666
  }
585
- /**
586
- * Get metrics for this scope
587
- */
588
667
  getMetrics() {
589
668
  return this.metrics;
590
669
  }
591
- /**
592
- * Resolve or retrieve a request-scoped service instance.
593
- *
594
- * If the service already exists in this scope, returns the cached instance.
595
- * Otherwise, calls the factory function to create a new instance and caches it.
596
- *
597
- * Automatically detects and records services with cleanup methods.
598
- *
599
- * @template T - The type of the service.
600
- * @param key - The service key (for caching).
601
- * @param factory - Factory function to create the instance if not cached.
602
- * @returns The cached or newly created instance.
603
- */
604
670
  resolve(key, factory) {
605
671
  const keyStr = String(key);
606
672
  const isFromCache = this.scoped.has(keyStr);
@@ -614,15 +680,6 @@ var RequestScopeManager = class {
614
680
  this.observer?.onServiceResolved?.(key, isFromCache);
615
681
  return this.scoped.get(keyStr);
616
682
  }
617
- /**
618
- * Clean up all request-scoped instances.
619
- *
620
- * Calls the cleanup() method on each service that has one.
621
- * Silently ignores cleanup errors to prevent cascading failures.
622
- * Called automatically by the Gravito engine in the request finally block.
623
- *
624
- * @returns Promise that resolves when all cleanup is complete.
625
- */
626
683
  async cleanup() {
627
684
  this.metrics.recordCleanupStart();
628
685
  this.observer?.onCleanupStart?.();
@@ -637,9 +694,7 @@ var RequestScopeManager = class {
637
694
  servicesCleaned++;
638
695
  } catch (error) {
639
696
  errors.push(error);
640
- this.observer?.onCleanupError?.(
641
- error instanceof Error ? error : new Error(String(error))
642
- );
697
+ this.observer?.onCleanupError?.(error instanceof Error ? error : new Error(String(error)));
643
698
  }
644
699
  }
645
700
  }
@@ -653,18 +708,15 @@ var RequestScopeManager = class {
653
708
  console.error("RequestScope cleanup errors:", errors);
654
709
  }
655
710
  }
656
- /**
657
- * Get the number of services in this scope (for monitoring).
658
- *
659
- * @returns The count of cached services.
660
- */
661
711
  size() {
662
712
  return this.scoped.size;
663
713
  }
664
- };
714
+ }
665
715
 
666
716
  // src/engine/FastContext.ts
667
- var FastRequestImpl = class {
717
+ var bunEscapeHTML = globalThis.Bun.escapeHTML;
718
+
719
+ class FastRequestImpl {
668
720
  _request;
669
721
  _params;
670
722
  _path;
@@ -672,21 +724,18 @@ var FastRequestImpl = class {
672
724
  _url = null;
673
725
  _query = null;
674
726
  _headers = null;
675
- _cachedJson = void 0;
727
+ _cachedJson = undefined;
676
728
  _jsonParsed = false;
677
- _cachedText = void 0;
729
+ _cachedText = undefined;
678
730
  _textParsed = false;
679
- _cachedFormData = void 0;
731
+ _cachedFormData = undefined;
680
732
  _formDataParsed = false;
681
733
  _cachedQueries = null;
682
- // Back-reference for release check optimization
734
+ _cachedCookies = null;
683
735
  _ctx;
684
736
  constructor(ctx) {
685
737
  this._ctx = ctx;
686
738
  }
687
- /**
688
- * Initialize for new request
689
- */
690
739
  init(request, params = {}, path = "", routePattern) {
691
740
  this._request = request;
692
741
  this._params = params;
@@ -695,37 +744,34 @@ var FastRequestImpl = class {
695
744
  this._url = null;
696
745
  this._query = null;
697
746
  this._headers = null;
698
- this._cachedJson = void 0;
747
+ this._cachedJson = undefined;
699
748
  this._jsonParsed = false;
700
- this._cachedText = void 0;
749
+ this._cachedText = undefined;
701
750
  this._textParsed = false;
702
- this._cachedFormData = void 0;
751
+ this._cachedFormData = undefined;
703
752
  this._formDataParsed = false;
704
753
  this._cachedQueries = null;
754
+ this._cachedCookies = null;
705
755
  return this;
706
756
  }
707
- /**
708
- * Reset for pooling
709
- */
710
757
  reset() {
711
- this._request = void 0;
712
- this._params = void 0;
758
+ this._request = undefined;
759
+ this._params = undefined;
713
760
  this._url = null;
714
761
  this._query = null;
715
762
  this._headers = null;
716
- this._cachedJson = void 0;
763
+ this._cachedJson = undefined;
717
764
  this._jsonParsed = false;
718
- this._cachedText = void 0;
765
+ this._cachedText = undefined;
719
766
  this._textParsed = false;
720
- this._cachedFormData = void 0;
767
+ this._cachedFormData = undefined;
721
768
  this._formDataParsed = false;
722
769
  this._cachedQueries = null;
770
+ this._cachedCookies = null;
723
771
  }
724
772
  checkReleased() {
725
773
  if (this._ctx._isReleased) {
726
- throw new Error(
727
- "FastContext usage after release detected! (Object Pool Strict Lifecycle Guard)"
728
- );
774
+ throw new Error("FastContext usage after release detected! (Object Pool Strict Lifecycle Guard)");
729
775
  }
730
776
  }
731
777
  get url() {
@@ -763,7 +809,7 @@ var FastRequestImpl = class {
763
809
  if (!this._query) {
764
810
  this._query = this.getUrl().searchParams;
765
811
  }
766
- return this._query.get(name) ?? void 0;
812
+ return this._query.get(name) ?? undefined;
767
813
  }
768
814
  queries() {
769
815
  this.checkReleased();
@@ -776,7 +822,7 @@ var FastRequestImpl = class {
776
822
  const result = {};
777
823
  for (const [key, value] of this._query.entries()) {
778
824
  const existing = result[key];
779
- if (existing === void 0) {
825
+ if (existing === undefined) {
780
826
  result[key] = value;
781
827
  } else if (Array.isArray(existing)) {
782
828
  existing.push(value);
@@ -789,7 +835,7 @@ var FastRequestImpl = class {
789
835
  }
790
836
  header(name) {
791
837
  this.checkReleased();
792
- return this._request.headers.get(name) ?? void 0;
838
+ return this._request.headers.get(name) ?? undefined;
793
839
  }
794
840
  headers() {
795
841
  this.checkReleased();
@@ -801,6 +847,39 @@ var FastRequestImpl = class {
801
847
  }
802
848
  return { ...this._headers };
803
849
  }
850
+ get cookies() {
851
+ this.checkReleased();
852
+ if (this._cachedCookies !== null) {
853
+ return this._cachedCookies;
854
+ }
855
+ const nativeCookies = this._request.cookies;
856
+ if (nativeCookies) {
857
+ this._cachedCookies = nativeCookies;
858
+ return nativeCookies;
859
+ }
860
+ const cookieHeader = this._request.headers.get("cookie");
861
+ if (!cookieHeader) {
862
+ this._cachedCookies = {};
863
+ return {};
864
+ }
865
+ const cookies = {};
866
+ const pairs = cookieHeader.split(/;\s*/);
867
+ for (let i = 0;i < pairs.length; i++) {
868
+ const pair = pairs[i];
869
+ const idx = pair.indexOf("=");
870
+ if (idx > 0) {
871
+ const name = pair.substring(0, idx);
872
+ const value = pair.substring(idx + 1);
873
+ try {
874
+ cookies[name] = decodeURIComponent(value);
875
+ } catch {
876
+ cookies[name] = value;
877
+ }
878
+ }
879
+ }
880
+ this._cachedCookies = cookies;
881
+ return cookies;
882
+ }
804
883
  async json() {
805
884
  this.checkReleased();
806
885
  if (!this._jsonParsed) {
@@ -829,82 +908,57 @@ var FastRequestImpl = class {
829
908
  this.checkReleased();
830
909
  return this._request;
831
910
  }
832
- };
833
- var FastContext = class {
911
+ }
912
+
913
+ class FastContext {
834
914
  req = new FastRequestImpl(this);
835
- // private _statusCode = 200
836
- _headers = new Headers();
837
- // Reuse this object
915
+ _headers = new Headers;
838
916
  _isReleased = false;
839
- // Made public for internal check access
840
917
  _requestScope = null;
841
- // Request-scoped services
842
- /**
843
- * Initialize context for a new request
844
- *
845
- * This is called when acquiring from the pool.
846
- */
847
918
  init(request, params = {}, path = "", routePattern) {
848
919
  this._isReleased = false;
849
920
  this.req.init(request, params, path, routePattern);
850
- this._headers = new Headers();
851
- this._requestScope = new RequestScopeManager();
921
+ this._headers = new Headers;
922
+ this._requestScope = new RequestScopeManager;
852
923
  return this;
853
924
  }
854
- /**
855
- * Reset context for pooling (Cleanup)
856
- *
857
- * This is called when releasing back to the pool.
858
- * Implements "Deep-Reset Protocol" and "Release Guard".
859
- */
860
925
  reset() {
861
926
  this._isReleased = true;
862
927
  this.req.reset();
863
928
  this._store.clear();
929
+ this._requestScope = null;
864
930
  }
865
- /**
866
- * Check if context is released
867
- */
868
931
  checkReleased() {
869
932
  if (this._isReleased) {
870
- throw new Error(
871
- "FastContext usage after release detected! (Object Pool Strict Lifecycle Guard)"
872
- );
933
+ throw new Error("FastContext usage after release detected! (Object Pool Strict Lifecycle Guard)");
873
934
  }
874
935
  }
875
- // ─────────────────────────────────────────────────────────────────────────
876
- // Response Helpers
877
- // ─────────────────────────────────────────────────────────────────────────
878
936
  json(data, status = 200) {
879
937
  this.checkReleased();
880
- this._headers.set("Content-Type", "application/json; charset=utf-8");
881
- return new Response(JSON.stringify(data), {
882
- status,
883
- headers: this._headers
884
- });
938
+ const headers = new Headers(this._headers);
939
+ headers.set("Content-Type", "application/json; charset=utf-8");
940
+ return Response.json(data, { status, headers });
885
941
  }
886
942
  text(text, status = 200) {
887
943
  this.checkReleased();
888
- this._headers.set("Content-Type", "text/plain; charset=utf-8");
889
- return new Response(text, {
890
- status,
891
- headers: this._headers
892
- });
944
+ const headers = new Headers(this._headers);
945
+ headers.set("Content-Type", "text/plain; charset=utf-8");
946
+ return new Response(text, { status, headers });
893
947
  }
894
948
  html(html, status = 200) {
895
949
  this.checkReleased();
896
- this._headers.set("Content-Type", "text/html; charset=utf-8");
897
- return new Response(html, {
898
- status,
899
- headers: this._headers
900
- });
950
+ const headers = new Headers(this._headers);
951
+ headers.set("Content-Type", "text/html; charset=utf-8");
952
+ return new Response(html, { status, headers });
953
+ }
954
+ escape(html) {
955
+ return bunEscapeHTML(html);
901
956
  }
902
957
  redirect(url, status = 302) {
903
958
  this.checkReleased();
904
- this._headers.set("Location", url);
905
959
  return new Response(null, {
906
960
  status,
907
- headers: this._headers
961
+ headers: { Location: url }
908
962
  });
909
963
  }
910
964
  body(data, status = 200) {
@@ -914,12 +968,19 @@ var FastContext = class {
914
968
  headers: this._headers
915
969
  });
916
970
  }
971
+ binary(data, status = 200) {
972
+ this.checkReleased();
973
+ const body = data instanceof ArrayBuffer ? new Uint8Array(data) : data;
974
+ return new Response(body, {
975
+ status,
976
+ headers: { "Content-Type": "application/octet-stream" }
977
+ });
978
+ }
917
979
  stream(stream, status = 200) {
918
980
  this.checkReleased();
919
- this._headers.set("Content-Type", "application/octet-stream");
920
981
  return new Response(stream, {
921
982
  status,
922
- headers: this._headers
983
+ headers: { "Content-Type": "application/octet-stream" }
923
984
  });
924
985
  }
925
986
  notFound(message = "Not Found") {
@@ -937,9 +998,7 @@ var FastContext = class {
937
998
  async forward(target, _options = {}) {
938
999
  this.checkReleased();
939
1000
  const url = new URL(this.req.url);
940
- const targetUrl = new URL(
941
- target.startsWith("http") ? target : `${url.protocol}//${target}${this.req.path}`
942
- );
1001
+ const targetUrl = new URL(target.startsWith("http") ? target : `${url.protocol}//${target}${this.req.path}`);
943
1002
  const searchParams = new URLSearchParams(url.search);
944
1003
  searchParams.forEach((v, k) => {
945
1004
  targetUrl.searchParams.set(k, v);
@@ -948,13 +1007,12 @@ var FastContext = class {
948
1007
  method: this.req.method,
949
1008
  headers: this.req.raw.headers,
950
1009
  body: this.req.method !== "GET" && this.req.method !== "HEAD" ? this.req.raw.body : null,
951
- // @ts-expect-error - Bun/Fetch specific
952
1010
  duplex: "half"
953
1011
  });
954
1012
  }
955
1013
  header(name, value) {
956
1014
  this.checkReleased();
957
- if (value !== void 0) {
1015
+ if (value !== undefined) {
958
1016
  this._headers.set(name, value);
959
1017
  return;
960
1018
  }
@@ -963,64 +1021,47 @@ var FastContext = class {
963
1021
  status(_code) {
964
1022
  this.checkReleased();
965
1023
  }
966
- // ─────────────────────────────────────────────────────────────────────────
967
- // Context Variables
968
- // ─────────────────────────────────────────────────────────────────────────
969
- _store = /* @__PURE__ */ new Map();
1024
+ _store = new Map;
970
1025
  get(key) {
971
1026
  return this._store.get(key);
972
1027
  }
973
1028
  set(key, value) {
974
1029
  this._store.set(key, value);
975
1030
  }
976
- // ─────────────────────────────────────────────────────────────────────────
977
- // Request Scope Management
978
- // ─────────────────────────────────────────────────────────────────────────
979
- /**
980
- * Get the request-scoped service manager for this request.
981
- *
982
- * @returns The RequestScopeManager for this request.
983
- * @throws Error if called before init() or after reset().
984
- */
985
1031
  requestScope() {
986
1032
  if (!this._requestScope) {
987
1033
  throw new Error("RequestScope not initialized. Call init() first.");
988
1034
  }
989
1035
  return this._requestScope;
990
1036
  }
991
- /**
992
- * Resolve a request-scoped service (convenience method).
993
- *
994
- * @template T - The service type.
995
- * @param key - The service key for caching.
996
- * @param factory - Factory function to create the service.
997
- * @returns The cached or newly created service instance.
998
- */
999
1037
  scoped(key, factory) {
1000
1038
  return this.requestScope().resolve(key, factory);
1001
1039
  }
1002
- // ─────────────────────────────────────────────────────────────────────────
1003
- // Lifecycle helpers
1004
- // ─────────────────────────────────────────────────────────────────────────
1005
1040
  route = () => "";
1006
1041
  get native() {
1007
1042
  return this;
1008
1043
  }
1009
- };
1044
+ }
1010
1045
 
1011
1046
  // src/engine/MinimalContext.ts
1012
- var MinimalRequest = class {
1047
+ var bunEscapeHTML2 = globalThis.Bun.escapeHTML;
1048
+
1049
+ class MinimalRequest {
1050
+ _request;
1051
+ _params;
1052
+ _path;
1053
+ _routePattern;
1054
+ _searchParams = null;
1055
+ _cachedQueries = null;
1056
+ _cachedJsonPromise = null;
1057
+ _cachedTextPromise = null;
1058
+ _cachedFormDataPromise = null;
1013
1059
  constructor(_request, _params, _path, _routePattern) {
1014
1060
  this._request = _request;
1015
1061
  this._params = _params;
1016
1062
  this._path = _path;
1017
1063
  this._routePattern = _routePattern;
1018
1064
  }
1019
- _searchParams = null;
1020
- _cachedQueries = null;
1021
- _cachedJsonPromise = null;
1022
- _cachedTextPromise = null;
1023
- _cachedFormDataPromise = null;
1024
1065
  get url() {
1025
1066
  return this._request.url;
1026
1067
  }
@@ -1039,15 +1080,12 @@ var MinimalRequest = class {
1039
1080
  params() {
1040
1081
  return { ...this._params };
1041
1082
  }
1042
- /**
1043
- * Lazy-initialize searchParams, only parse once
1044
- */
1045
1083
  getSearchParams() {
1046
1084
  if (this._searchParams === null) {
1047
1085
  const url = this._request.url;
1048
1086
  const queryStart = url.indexOf("?");
1049
1087
  if (queryStart === -1) {
1050
- this._searchParams = new URLSearchParams();
1088
+ this._searchParams = new URLSearchParams;
1051
1089
  } else {
1052
1090
  const hashStart = url.indexOf("#", queryStart);
1053
1091
  const queryString = hashStart === -1 ? url.slice(queryStart + 1) : url.slice(queryStart + 1, hashStart);
@@ -1057,7 +1095,7 @@ var MinimalRequest = class {
1057
1095
  return this._searchParams;
1058
1096
  }
1059
1097
  query(name) {
1060
- return this.getSearchParams().get(name) ?? void 0;
1098
+ return this.getSearchParams().get(name) ?? undefined;
1061
1099
  }
1062
1100
  queries() {
1063
1101
  if (this._cachedQueries !== null) {
@@ -1067,7 +1105,7 @@ var MinimalRequest = class {
1067
1105
  const result = {};
1068
1106
  for (const [key, value] of params.entries()) {
1069
1107
  const existing = result[key];
1070
- if (existing === void 0) {
1108
+ if (existing === undefined) {
1071
1109
  result[key] = value;
1072
1110
  } else if (Array.isArray(existing)) {
1073
1111
  existing.push(value);
@@ -1079,7 +1117,7 @@ var MinimalRequest = class {
1079
1117
  return result;
1080
1118
  }
1081
1119
  header(name) {
1082
- return this._request.headers.get(name) ?? void 0;
1120
+ return this._request.headers.get(name) ?? undefined;
1083
1121
  }
1084
1122
  headers() {
1085
1123
  const result = {};
@@ -1106,23 +1144,45 @@ var MinimalRequest = class {
1106
1144
  }
1107
1145
  return this._cachedFormDataPromise;
1108
1146
  }
1147
+ get cookies() {
1148
+ const nativeCookies = this._request.cookies;
1149
+ if (nativeCookies) {
1150
+ return nativeCookies;
1151
+ }
1152
+ const cookieHeader = this._request.headers.get("cookie");
1153
+ if (!cookieHeader) {
1154
+ return {};
1155
+ }
1156
+ const cookies = {};
1157
+ const pairs = cookieHeader.split(/;\s*/);
1158
+ for (let i = 0;i < pairs.length; i++) {
1159
+ const pair = pairs[i];
1160
+ const idx = pair.indexOf("=");
1161
+ if (idx > 0) {
1162
+ const name = pair.substring(0, idx);
1163
+ const value = pair.substring(idx + 1);
1164
+ try {
1165
+ cookies[name] = decodeURIComponent(value);
1166
+ } catch {
1167
+ cookies[name] = value;
1168
+ }
1169
+ }
1170
+ }
1171
+ return cookies;
1172
+ }
1109
1173
  get raw() {
1110
1174
  return this._request;
1111
1175
  }
1112
- };
1113
- var MinimalContext = class {
1176
+ }
1177
+
1178
+ class MinimalContext {
1114
1179
  req;
1115
1180
  _resHeaders = {};
1116
1181
  _requestScope;
1117
1182
  constructor(request, params, path, routePattern) {
1118
1183
  this.req = new MinimalRequest(request, params, path, routePattern);
1119
- this._requestScope = new RequestScopeManager();
1184
+ this._requestScope = new RequestScopeManager;
1120
1185
  }
1121
- // get req(): FastRequest {
1122
- // return this._req
1123
- // }
1124
- // Response helpers - merge custom headers with defaults
1125
- // Optimized: use Object.assign instead of spread to avoid shallow copy overhead
1126
1186
  getHeaders(contentType) {
1127
1187
  const headers = Object.assign({ "Content-Type": contentType }, this._resHeaders);
1128
1188
  return headers;
@@ -1158,14 +1218,13 @@ var MinimalContext = class {
1158
1218
  });
1159
1219
  }
1160
1220
  header(name, value) {
1161
- if (value !== void 0) {
1221
+ if (value !== undefined) {
1162
1222
  this._resHeaders[name] = value;
1163
1223
  return;
1164
1224
  }
1165
1225
  return this.req.header(name);
1166
1226
  }
1167
- status(_code) {
1168
- }
1227
+ status(_code) {}
1169
1228
  stream(stream, status = 200) {
1170
1229
  return new Response(stream, {
1171
1230
  status,
@@ -1186,35 +1245,22 @@ var MinimalContext = class {
1186
1245
  }
1187
1246
  async forward(target, _options = {}) {
1188
1247
  const url = new URL(this.req.url);
1189
- const targetUrl = new URL(
1190
- target.startsWith("http") ? target : `${url.protocol}//${target}${this.req.path}`
1191
- );
1248
+ const targetUrl = new URL(target.startsWith("http") ? target : `${url.protocol}//${target}${this.req.path}`);
1192
1249
  return fetch(targetUrl.toString(), {
1193
1250
  method: this.req.method,
1194
1251
  headers: this.req.raw.headers
1195
1252
  });
1196
1253
  }
1197
- get(_key) {
1198
- return void 0;
1254
+ escape(html) {
1255
+ return bunEscapeHTML2(html);
1199
1256
  }
1200
- set(_key, _value) {
1257
+ get(_key) {
1258
+ return;
1201
1259
  }
1202
- /**
1203
- * Get the request-scoped service manager for this request.
1204
- *
1205
- * @returns The RequestScopeManager for this request.
1206
- */
1260
+ set(_key, _value) {}
1207
1261
  requestScope() {
1208
1262
  return this._requestScope;
1209
1263
  }
1210
- /**
1211
- * Resolve a request-scoped service (convenience method).
1212
- *
1213
- * @template T - The service type.
1214
- * @param key - The service key for caching.
1215
- * @param factory - Factory function to create the service.
1216
- * @returns The cached or newly created service instance.
1217
- */
1218
1264
  scoped(key, factory) {
1219
1265
  return this._requestScope.resolve(key, factory);
1220
1266
  }
@@ -1222,14 +1268,11 @@ var MinimalContext = class {
1222
1268
  get native() {
1223
1269
  return this;
1224
1270
  }
1225
- // Required for interface compatibility
1226
1271
  init(_request, _params, _path) {
1227
1272
  throw new Error("MinimalContext does not support init. Create a new instance instead.");
1228
1273
  }
1229
- // Required for interface compatibility
1230
- reset() {
1231
- }
1232
- };
1274
+ reset() {}
1275
+ }
1233
1276
 
1234
1277
  // src/engine/path.ts
1235
1278
  function extractPath(url) {
@@ -1247,79 +1290,38 @@ function extractPath(url) {
1247
1290
  }
1248
1291
 
1249
1292
  // src/engine/pool.ts
1250
- var ObjectPool = class {
1293
+ class ObjectPool {
1251
1294
  pool = [];
1252
1295
  factory;
1253
1296
  reset;
1254
1297
  maxSize;
1255
- /**
1256
- * Create a new object pool
1257
- *
1258
- * @param factory - Function to create new objects
1259
- * @param reset - Function to reset objects before reuse
1260
- * @param maxSize - Maximum pool size (default: 256)
1261
- */
1262
1298
  constructor(factory, reset, maxSize = 256) {
1263
1299
  this.factory = factory;
1264
1300
  this.reset = reset;
1265
1301
  this.maxSize = maxSize;
1266
1302
  }
1267
- /**
1268
- * Acquire an object from the pool
1269
- *
1270
- * If the pool is empty, creates a new object (overflow strategy).
1271
- * This ensures the pool never blocks under high load.
1272
- *
1273
- * @returns Object from pool or newly created
1274
- */
1275
1303
  acquire() {
1276
1304
  const obj = this.pool.pop();
1277
- if (obj !== void 0) {
1305
+ if (obj !== undefined) {
1278
1306
  return obj;
1279
1307
  }
1280
1308
  return this.factory();
1281
1309
  }
1282
- /**
1283
- * Release an object back to the pool
1284
- *
1285
- * If the pool is full, the object is discarded (will be GC'd).
1286
- * This prevents unbounded memory growth.
1287
- *
1288
- * @param obj - Object to release
1289
- */
1290
1310
  release(obj) {
1291
1311
  if (this.pool.length < this.maxSize) {
1292
1312
  this.reset(obj);
1293
1313
  this.pool.push(obj);
1294
1314
  }
1295
1315
  }
1296
- /**
1297
- * Clear all objects from the pool
1298
- *
1299
- * Useful for testing or when you need to force a clean slate.
1300
- */
1301
1316
  clear() {
1302
1317
  this.pool = [];
1303
1318
  }
1304
- /**
1305
- * Get current pool size
1306
- */
1307
1319
  get size() {
1308
1320
  return this.pool.length;
1309
1321
  }
1310
- /**
1311
- * Get maximum pool size
1312
- */
1313
1322
  get capacity() {
1314
1323
  return this.maxSize;
1315
1324
  }
1316
- /**
1317
- * Pre-warm the pool by creating objects in advance
1318
- *
1319
- * This can reduce latency for the first N requests.
1320
- *
1321
- * @param count - Number of objects to pre-create
1322
- */
1323
1325
  prewarm(count) {
1324
1326
  const targetSize = Math.min(count, this.maxSize);
1325
1327
  while (this.pool.length < targetSize) {
@@ -1328,9 +1330,10 @@ var ObjectPool = class {
1328
1330
  this.pool.push(obj);
1329
1331
  }
1330
1332
  }
1331
- };
1333
+ }
1332
1334
 
1333
1335
  // src/engine/Gravito.ts
1336
+ var bunPeek = globalThis.Bun.peek;
1334
1337
  function compileMiddlewareChain(middleware, handler) {
1335
1338
  if (middleware.length === 0) {
1336
1339
  return handler;
@@ -1339,64 +1342,76 @@ function compileMiddlewareChain(middleware, handler) {
1339
1342
  const mw = middleware[0];
1340
1343
  return async (ctx) => {
1341
1344
  let nextCalled = false;
1342
- const result = await mw(ctx, async () => {
1345
+ const result = mw(ctx, async () => {
1343
1346
  nextCalled = true;
1344
- return void 0;
1347
+ return;
1345
1348
  });
1346
- if (result instanceof Response) {
1347
- return result;
1349
+ let finalResult;
1350
+ if (result instanceof Promise) {
1351
+ const peeked = bunPeek(result);
1352
+ finalResult = peeked === result ? await result : peeked;
1353
+ } else {
1354
+ finalResult = result;
1355
+ }
1356
+ if (finalResult instanceof Response) {
1357
+ return finalResult;
1348
1358
  }
1349
1359
  if (nextCalled) {
1350
- return await handler(ctx);
1360
+ const hResult = handler(ctx);
1361
+ if (hResult instanceof Promise) {
1362
+ const p = bunPeek(hResult);
1363
+ return p === hResult ? await hResult : p;
1364
+ }
1365
+ return hResult;
1351
1366
  }
1352
1367
  return ctx.json({ error: "Middleware did not call next or return response" }, 500);
1353
1368
  };
1354
1369
  }
1355
1370
  let compiled = handler;
1356
- for (let i = middleware.length - 1; i >= 0; i--) {
1371
+ for (let i = middleware.length - 1;i >= 0; i--) {
1357
1372
  const mw = middleware[i];
1358
1373
  const nextHandler = compiled;
1359
1374
  compiled = async (ctx) => {
1360
1375
  let nextCalled = false;
1361
- const result = await mw(ctx, async () => {
1376
+ const result = mw(ctx, async () => {
1362
1377
  nextCalled = true;
1363
- return void 0;
1378
+ return;
1364
1379
  });
1365
- if (result instanceof Response) {
1366
- return result;
1380
+ let finalResult;
1381
+ if (result instanceof Promise) {
1382
+ const peeked = bunPeek(result);
1383
+ finalResult = peeked === result ? await result : peeked;
1384
+ } else {
1385
+ finalResult = result;
1386
+ }
1387
+ if (finalResult instanceof Response) {
1388
+ return finalResult;
1367
1389
  }
1368
1390
  if (nextCalled) {
1369
- return await nextHandler(ctx);
1391
+ const nextResult = nextHandler(ctx);
1392
+ if (nextResult instanceof Promise) {
1393
+ const p = bunPeek(nextResult);
1394
+ return p === nextResult ? await nextResult : p;
1395
+ }
1396
+ return nextResult;
1370
1397
  }
1371
1398
  return ctx.json({ error: "Middleware did not call next or return response" }, 500);
1372
1399
  };
1373
1400
  }
1374
1401
  return compiled;
1375
1402
  }
1376
- var Gravito = class {
1377
- router = new AOTRouter();
1403
+
1404
+ class Gravito {
1405
+ router = new AOTRouter;
1378
1406
  contextPool;
1379
1407
  errorHandler;
1380
1408
  notFoundHandler;
1381
- // Direct reference to static routes Map (O(1) access)
1382
- /** @internal */
1383
1409
  staticRoutes;
1384
- // Flag: pure static app (no middleware at all) allows ultra-fast path
1385
1410
  isPureStaticApp = true;
1386
- // Cache for precompiled dynamic routes
1387
- compiledDynamicRoutes = /* @__PURE__ */ new Map();
1388
- /**
1389
- * Create a new Gravito instance
1390
- *
1391
- * @param options - Engine configuration options
1392
- */
1411
+ compiledDynamicRoutes = new Map;
1393
1412
  constructor(options = {}) {
1394
1413
  const poolSize = options.poolSize ?? 256;
1395
- this.contextPool = new ObjectPool(
1396
- () => new FastContext(),
1397
- (ctx) => ctx.reset(),
1398
- poolSize
1399
- );
1414
+ this.contextPool = new ObjectPool(() => new FastContext, (ctx) => ctx.reset(), poolSize);
1400
1415
  this.contextPool.prewarm(Math.min(32, poolSize));
1401
1416
  if (options.onError) {
1402
1417
  this.errorHandler = options.onError;
@@ -1406,58 +1421,27 @@ var Gravito = class {
1406
1421
  }
1407
1422
  this.compileRoutes();
1408
1423
  }
1409
- // ─────────────────────────────────────────────────────────────────────────
1410
- // HTTP Method Registration
1411
- // ─────────────────────────────────────────────────────────────────────────
1412
- /**
1413
- * Register a GET route
1414
- *
1415
- * @param path - Route path (e.g., '/users/:id')
1416
- * @param handlers - Handler and optional middleware
1417
- * @returns This instance for chaining
1418
- */
1419
1424
  get(path, ...handlers) {
1420
1425
  return this.addRoute("get", path, handlers);
1421
1426
  }
1422
- /**
1423
- * Register a POST route
1424
- */
1425
1427
  post(path, ...handlers) {
1426
1428
  return this.addRoute("post", path, handlers);
1427
1429
  }
1428
- /**
1429
- * Register a PUT route
1430
- */
1431
1430
  put(path, ...handlers) {
1432
1431
  return this.addRoute("put", path, handlers);
1433
1432
  }
1434
- /**
1435
- * Register a DELETE route
1436
- */
1437
1433
  delete(path, ...handlers) {
1438
1434
  return this.addRoute("delete", path, handlers);
1439
1435
  }
1440
- /**
1441
- * Register a PDF route
1442
- */
1443
1436
  patch(path, ...handlers) {
1444
1437
  return this.addRoute("patch", path, handlers);
1445
1438
  }
1446
- /**
1447
- * Register an OPTIONS route
1448
- */
1449
1439
  options(path, ...handlers) {
1450
1440
  return this.addRoute("options", path, handlers);
1451
1441
  }
1452
- /**
1453
- * Register a HEAD route
1454
- */
1455
1442
  head(path, ...handlers) {
1456
1443
  return this.addRoute("head", path, handlers);
1457
1444
  }
1458
- /**
1459
- * Register a route for all HTTP methods
1460
- */
1461
1445
  all(path, ...handlers) {
1462
1446
  const methods = ["get", "post", "put", "delete", "patch", "options", "head"];
1463
1447
  for (const method of methods) {
@@ -1475,45 +1459,19 @@ var Gravito = class {
1475
1459
  this.compileRoutes();
1476
1460
  return this;
1477
1461
  }
1478
- // ─────────────────────────────────────────────────────────────────────────
1479
- // Route Grouping
1480
- // ─────────────────────────────────────────────────────────────────────────
1481
- /**
1482
- * Mount a sub-application at a path prefix
1483
- */
1484
1462
  route(path, app) {
1485
1463
  this.router.mount(path, app.router);
1486
1464
  this.compileRoutes();
1487
1465
  return this;
1488
1466
  }
1489
- // ─────────────────────────────────────────────────────────────────────────
1490
- // Error Handling
1491
- // ─────────────────────────────────────────────────────────────────────────
1492
- /**
1493
- * Set custom error handler
1494
- */
1495
1467
  onError(handler) {
1496
1468
  this.errorHandler = handler;
1497
1469
  return this;
1498
1470
  }
1499
- /**
1500
- * Set custom 404 handler
1501
- */
1502
1471
  notFound(handler) {
1503
1472
  this.notFoundHandler = handler;
1504
1473
  return this;
1505
1474
  }
1506
- // ─────────────────────────────────────────────────────────────────────────
1507
- // Request Handling (Bun.serve integration)
1508
- // ─────────────────────────────────────────────────────────────────────────
1509
- /**
1510
- * Predictive Route Warming (JIT Optimization)
1511
- *
1512
- * Simulates requests to specified routes to trigger JIT compilation (FTL)
1513
- * before real traffic arrives.
1514
- *
1515
- * @param paths List of paths to warm up (e.g. ['/api/users', '/health'])
1516
- */
1517
1475
  async warmup(paths) {
1518
1476
  const dummyReqOpts = { headers: { "User-Agent": "Gravito-Warmup/1.0" } };
1519
1477
  for (const path of paths) {
@@ -1521,96 +1479,135 @@ var Gravito = class {
1521
1479
  await this.fetch(req);
1522
1480
  }
1523
1481
  }
1524
- /**
1525
- * Handle an incoming request
1526
- */
1482
+ serveConfig(baseConfig = {}) {
1483
+ const nativeRoutes = this.router.getNativeRoutes((handler, middleware, path) => {
1484
+ const compiled = compileMiddlewareChain(middleware, handler);
1485
+ return async (req) => {
1486
+ const ctx = this.contextPool.acquire();
1487
+ ctx.init(req, {}, path, path);
1488
+ try {
1489
+ const result = compiled(ctx);
1490
+ let response;
1491
+ if (result instanceof Promise) {
1492
+ const peeked = bunPeek(result);
1493
+ response = peeked === result ? await result : peeked;
1494
+ } else {
1495
+ response = result;
1496
+ }
1497
+ const cleanup = ctx.requestScope().cleanup();
1498
+ if (cleanup instanceof Promise)
1499
+ await cleanup;
1500
+ this.contextPool.release(ctx);
1501
+ return response;
1502
+ } catch (error) {
1503
+ const cleanup = ctx.requestScope().cleanup();
1504
+ if (cleanup instanceof Promise)
1505
+ await cleanup;
1506
+ this.contextPool.release(ctx);
1507
+ return this.handleErrorSync(error, req, path);
1508
+ }
1509
+ };
1510
+ });
1511
+ return {
1512
+ ...baseConfig,
1513
+ routes: nativeRoutes,
1514
+ fetch: this.fetch,
1515
+ tls: baseConfig.tls ? this.optimizeTLS(baseConfig.tls) : undefined,
1516
+ error: (error) => {
1517
+ console.error("Native route error:", error);
1518
+ return new Response(CACHED_RESPONSES.INTERNAL_ERROR, {
1519
+ status: 500,
1520
+ headers: HEADERS.JSON
1521
+ });
1522
+ }
1523
+ };
1524
+ }
1525
+ optimizeTLS(tls) {
1526
+ const isProd = false;
1527
+ const optimizeEntry = (entry) => {
1528
+ const optimized = { ...entry };
1529
+ if (typeof optimized.key === "string" && !optimized.key.startsWith("-----BEGIN")) {
1530
+ optimized.key = globalThis.Bun.file(optimized.key);
1531
+ }
1532
+ if (typeof optimized.cert === "string" && !optimized.cert.startsWith("-----BEGIN")) {
1533
+ optimized.cert = globalThis.Bun.file(optimized.cert);
1534
+ }
1535
+ if (isProd && optimized.lowMemoryMode === undefined) {
1536
+ optimized.lowMemoryMode = true;
1537
+ }
1538
+ return optimized;
1539
+ };
1540
+ return Array.isArray(tls) ? tls.map(optimizeEntry) : optimizeEntry(tls);
1541
+ }
1527
1542
  fetch = async (request) => {
1528
1543
  const path = extractPath(request.url);
1529
1544
  const method = request.method.toLowerCase();
1530
1545
  const staticKey = `${method}:${path}`;
1531
1546
  const staticRoute = this.staticRoutes.get(staticKey);
1532
1547
  if (staticRoute) {
1533
- if (staticRoute.useMinimal) {
1534
- const ctx = new MinimalContext(request, {}, path, path);
1535
- try {
1536
- const result = staticRoute.handler(ctx);
1537
- if (result instanceof Response) {
1538
- return result;
1539
- }
1540
- return await result;
1541
- } catch (error) {
1542
- return this.handleErrorSync(error, request, path);
1548
+ const ctx = this.contextPool.acquire();
1549
+ ctx.init(request, {}, path, path);
1550
+ try {
1551
+ const compiled = staticRoute.compiled || compileMiddlewareChain(staticRoute.middleware, staticRoute.handler);
1552
+ const result = compiled(ctx);
1553
+ let response;
1554
+ if (result instanceof Promise) {
1555
+ const peeked = bunPeek(result);
1556
+ response = peeked === result ? await result : peeked;
1557
+ } else {
1558
+ response = result;
1543
1559
  }
1560
+ const cleanup = ctx.requestScope().cleanup();
1561
+ if (cleanup instanceof Promise)
1562
+ await cleanup;
1563
+ this.contextPool.release(ctx);
1564
+ return response;
1565
+ } catch (error) {
1566
+ const cleanup = ctx.requestScope().cleanup();
1567
+ if (cleanup instanceof Promise)
1568
+ await cleanup;
1569
+ this.contextPool.release(ctx);
1570
+ return this.handleErrorSync(error, request, path);
1544
1571
  }
1545
- return await this.handleWithMiddleware(request, path, staticRoute);
1546
1572
  }
1547
1573
  return await this.handleDynamicRoute(request, method, path);
1548
1574
  };
1549
- /**
1550
- * Handle routes with middleware (async path)
1551
- */
1552
- async handleWithMiddleware(request, path, route) {
1553
- const ctx = this.contextPool.acquire();
1554
- try {
1555
- ctx.init(request, {}, path, path);
1556
- if (route.compiled) {
1557
- return await route.compiled(ctx);
1558
- }
1559
- const middleware = this.collectMiddlewareForPath(path, route.middleware);
1560
- if (middleware.length === 0) {
1561
- return await route.handler(ctx);
1562
- }
1563
- return await this.executeMiddleware(ctx, middleware, route.handler);
1564
- } catch (error) {
1565
- return await this.handleError(error, ctx);
1566
- } finally {
1575
+ async handleDynamicRoute(request, method, path) {
1576
+ const match = this.router.match(method, path);
1577
+ if (match.handler) {
1578
+ const ctx = this.contextPool.acquire();
1579
+ ctx.init(request, match.params, path, match.routePattern);
1567
1580
  try {
1568
- await ctx.requestScope().cleanup();
1569
- } catch (cleanupError) {
1570
- console.error("RequestScope cleanup failed:", cleanupError);
1571
- }
1572
- this.contextPool.release(ctx);
1573
- }
1574
- }
1575
- /**
1576
- * Handle dynamic routes (Radix Tree lookup)
1577
- */
1578
- handleDynamicRoute(request, method, path) {
1579
- const match = this.router.match(method.toUpperCase(), path);
1580
- if (!match.handler) {
1581
- return this.handleNotFoundSync(request, path);
1582
- }
1583
- const cacheKey = `${method}:${match.routePattern ?? path}`;
1584
- let entry = this.compiledDynamicRoutes.get(cacheKey);
1585
- if (!entry || entry.version !== this.router.version) {
1586
- const compiled = compileMiddlewareChain(match.middleware, match.handler);
1587
- if (this.compiledDynamicRoutes.size > 1e3) {
1588
- this.compiledDynamicRoutes.clear();
1589
- }
1590
- entry = { compiled, version: this.router.version };
1591
- this.compiledDynamicRoutes.set(cacheKey, entry);
1592
- }
1593
- const ctx = this.contextPool.acquire();
1594
- const execute = async () => {
1595
- try {
1596
- ctx.init(request, match.params, path, match.routePattern);
1597
- return await entry?.compiled(ctx);
1598
- } catch (error) {
1599
- return await this.handleError(error, ctx);
1600
- } finally {
1601
- try {
1602
- await ctx.requestScope().cleanup();
1603
- } catch (cleanupError) {
1604
- console.error("RequestScope cleanup failed:", cleanupError);
1581
+ const routeKey = `${method}:${match.routePattern}`;
1582
+ let compiledObj = this.compiledDynamicRoutes.get(routeKey);
1583
+ if (!compiledObj || compiledObj.version !== this.router.version) {
1584
+ const compiled = compileMiddlewareChain(match.middleware, match.handler);
1585
+ compiledObj = { compiled, version: this.router.version };
1586
+ this.compiledDynamicRoutes.set(routeKey, compiledObj);
1605
1587
  }
1588
+ const result = compiledObj.compiled(ctx);
1589
+ let response;
1590
+ if (result instanceof Promise) {
1591
+ const peeked = bunPeek(result);
1592
+ response = peeked === result ? await result : peeked;
1593
+ } else {
1594
+ response = result;
1595
+ }
1596
+ const cleanup = ctx.requestScope().cleanup();
1597
+ if (cleanup instanceof Promise)
1598
+ await cleanup;
1599
+ this.contextPool.release(ctx);
1600
+ return response;
1601
+ } catch (error) {
1602
+ const cleanup = ctx.requestScope().cleanup();
1603
+ if (cleanup instanceof Promise)
1604
+ await cleanup;
1606
1605
  this.contextPool.release(ctx);
1606
+ return this.handleErrorSync(error, request, path);
1607
1607
  }
1608
- };
1609
- return execute();
1608
+ }
1609
+ return this.handleNotFoundSync(request, path);
1610
1610
  }
1611
- /**
1612
- * Sync error handler (for ultra-fast path)
1613
- */
1614
1611
  handleErrorSync(error, request, path) {
1615
1612
  if (this.errorHandler) {
1616
1613
  const ctx = new MinimalContext(request, {}, path);
@@ -1626,9 +1623,6 @@ var Gravito = class {
1626
1623
  headers: HEADERS.JSON
1627
1624
  });
1628
1625
  }
1629
- /**
1630
- * Sync 404 handler (for ultra-fast path)
1631
- */
1632
1626
  handleNotFoundSync(request, path) {
1633
1627
  if (this.notFoundHandler) {
1634
1628
  const ctx = new MinimalContext(request, {}, path);
@@ -1643,18 +1637,12 @@ var Gravito = class {
1643
1637
  headers: HEADERS.JSON
1644
1638
  });
1645
1639
  }
1646
- /**
1647
- * Collect middleware for a specific path
1648
- */
1649
1640
  collectMiddlewareForPath(path, routeMiddleware) {
1650
1641
  if (this.router.globalMiddleware.length === 0 && this.router.pathMiddleware.size === 0) {
1651
1642
  return routeMiddleware;
1652
1643
  }
1653
1644
  return this.router.collectMiddlewarePublic(path, routeMiddleware);
1654
1645
  }
1655
- /**
1656
- * Compile routes for optimization
1657
- */
1658
1646
  compileRoutes() {
1659
1647
  this.staticRoutes = this.router.staticRoutes;
1660
1648
  const hasGlobalMiddleware = this.router.globalMiddleware.length > 0;
@@ -1674,9 +1662,6 @@ var Gravito = class {
1674
1662
  route.compiledVersion = this.router.version;
1675
1663
  }
1676
1664
  }
1677
- /**
1678
- * Add a route to the router
1679
- */
1680
1665
  addRoute(method, path, handlers) {
1681
1666
  if (handlers.length === 0) {
1682
1667
  throw new Error(`No handler provided for ${method.toUpperCase()} ${path}`);
@@ -1687,46 +1672,14 @@ var Gravito = class {
1687
1672
  this.compileRoutes();
1688
1673
  return this;
1689
1674
  }
1690
- /**
1691
- * Execute middleware chain followed by handler
1692
- */
1693
- async executeMiddleware(ctx, middleware, handler) {
1694
- let index = 0;
1695
- const next = async () => {
1696
- if (index < middleware.length) {
1697
- const mw = middleware[index++];
1698
- return await mw(ctx, next);
1699
- }
1700
- return void 0;
1701
- };
1702
- const result = await next();
1703
- if (result instanceof Response) {
1704
- return result;
1705
- }
1706
- return await handler(ctx);
1707
- }
1708
- /**
1709
- * Handle errors (Async version for dynamic/middleware paths)
1710
- */
1711
- async handleError(error, ctx) {
1712
- if (this.errorHandler) {
1713
- return await this.errorHandler(error, ctx);
1714
- }
1715
- console.error("Unhandled error:", error);
1716
- return ctx.json(
1717
- {
1718
- error: "Internal Server Error",
1719
- message: error.message
1720
- },
1721
- 500
1722
- );
1723
- }
1724
- };
1675
+ }
1725
1676
  export {
1726
- AOTRouter,
1727
- FastContext as FastContextImpl,
1728
- Gravito,
1729
- MinimalContext,
1677
+ extractPath,
1730
1678
  ObjectPool,
1731
- extractPath
1679
+ MinimalContext,
1680
+ Gravito,
1681
+ FastContext as FastContextImpl,
1682
+ AOTRouter
1732
1683
  };
1684
+
1685
+ //# debugId=13A90DBD3E511D5864756E2164756E21