@gravito/core 1.6.1 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (168) 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.d.ts +23 -1
  42. package/dist/compat.js +3 -0
  43. package/dist/compat.js.map +9 -0
  44. package/dist/engine/AOTRouter.d.ts +139 -0
  45. package/dist/engine/FastContext.d.ts +141 -0
  46. package/dist/engine/Gravito.d.ts +131 -0
  47. package/dist/engine/MinimalContext.d.ts +102 -0
  48. package/dist/engine/analyzer.d.ts +113 -0
  49. package/dist/engine/constants.d.ts +23 -0
  50. package/dist/engine/index.d.ts +14 -910
  51. package/dist/engine/index.js +623 -622
  52. package/dist/engine/index.js.map +23 -0
  53. package/dist/engine/path.d.ts +26 -0
  54. package/dist/engine/pool.d.ts +83 -0
  55. package/dist/engine/types.d.ts +149 -0
  56. package/dist/error-handling/RequestScopeErrorContext.d.ts +126 -0
  57. package/dist/events/BackpressureManager.d.ts +215 -0
  58. package/dist/events/CircuitBreaker.d.ts +229 -0
  59. package/dist/events/DeadLetterQueue.d.ts +219 -0
  60. package/dist/events/EventBackend.d.ts +12 -0
  61. package/dist/events/EventOptions.d.ts +204 -0
  62. package/dist/events/EventPriorityQueue.d.ts +63 -0
  63. package/dist/events/FlowControlStrategy.d.ts +109 -0
  64. package/dist/events/IdempotencyCache.d.ts +60 -0
  65. package/dist/events/MessageQueueBridge.d.ts +184 -0
  66. package/dist/events/PriorityEscalationManager.d.ts +82 -0
  67. package/dist/events/RetryScheduler.d.ts +104 -0
  68. package/dist/events/WorkerPool.d.ts +98 -0
  69. package/dist/events/WorkerPoolConfig.d.ts +153 -0
  70. package/dist/events/WorkerPoolMetrics.d.ts +65 -0
  71. package/dist/events/aggregation/AggregationWindow.d.ts +77 -0
  72. package/dist/events/aggregation/DeduplicationManager.d.ts +135 -0
  73. package/dist/events/aggregation/EventAggregationManager.d.ts +108 -0
  74. package/dist/events/aggregation/EventBatcher.d.ts +99 -0
  75. package/dist/events/aggregation/index.d.ts +10 -0
  76. package/dist/events/aggregation/types.d.ts +117 -0
  77. package/dist/events/index.d.ts +26 -0
  78. package/dist/events/observability/EventMetrics.d.ts +132 -0
  79. package/dist/events/observability/EventTracer.d.ts +68 -0
  80. package/dist/events/observability/EventTracing.d.ts +161 -0
  81. package/dist/events/observability/OTelEventMetrics.d.ts +332 -0
  82. package/dist/events/observability/ObservableHookManager.d.ts +108 -0
  83. package/dist/events/observability/StreamWorkerMetrics.d.ts +76 -0
  84. package/dist/events/observability/index.d.ts +24 -0
  85. package/dist/events/observability/metrics-types.d.ts +16 -0
  86. package/dist/events/queue-core.d.ts +77 -0
  87. package/dist/events/task-executor.d.ts +51 -0
  88. package/dist/events/types.d.ts +134 -0
  89. package/dist/exceptions/AuthenticationException.d.ts +8 -0
  90. package/dist/exceptions/AuthorizationException.d.ts +8 -0
  91. package/dist/exceptions/CircularDependencyException.d.ts +9 -0
  92. package/dist/exceptions/GravitoException.d.ts +23 -0
  93. package/dist/exceptions/HttpException.d.ts +9 -0
  94. package/dist/exceptions/ModelNotFoundException.d.ts +10 -0
  95. package/dist/exceptions/ValidationException.d.ts +22 -0
  96. package/dist/exceptions/index.d.ts +7 -0
  97. package/dist/ffi/NativeAccelerator.d.ts +69 -0
  98. package/dist/ffi/NativeHasher.d.ts +139 -0
  99. package/dist/ffi/cbor-fallback.d.ts +96 -0
  100. package/dist/ffi/hash-fallback.d.ts +33 -0
  101. package/dist/ffi/index.d.ts +10 -0
  102. package/dist/ffi/index.js +131 -0
  103. package/dist/ffi/index.js.map +11 -0
  104. package/dist/ffi/types.d.ts +135 -0
  105. package/dist/health/HealthProvider.d.ts +67 -0
  106. package/dist/helpers/Arr.d.ts +19 -0
  107. package/dist/helpers/Str.d.ts +38 -0
  108. package/dist/helpers/data.d.ts +25 -0
  109. package/dist/helpers/errors.d.ts +34 -0
  110. package/dist/helpers/response.d.ts +41 -0
  111. package/dist/helpers.d.ts +338 -0
  112. package/dist/hooks/ActionManager.d.ts +132 -0
  113. package/dist/hooks/AsyncDetector.d.ts +84 -0
  114. package/dist/hooks/FilterManager.d.ts +71 -0
  115. package/dist/hooks/MigrationWarner.d.ts +24 -0
  116. package/dist/hooks/dlq-operations.d.ts +60 -0
  117. package/dist/hooks/index.d.ts +11 -0
  118. package/dist/hooks/types.d.ts +107 -0
  119. package/dist/http/CookieJar.d.ts +51 -0
  120. package/dist/http/cookie.d.ts +29 -0
  121. package/dist/http/index.d.ts +12 -0
  122. package/dist/{compat-CI8hiulX.d.cts → http/types.d.ts} +35 -16
  123. package/dist/index.browser.d.ts +34 -0
  124. package/dist/index.d.ts +60 -10981
  125. package/dist/index.js +10808 -11273
  126. package/dist/index.js.map +166 -0
  127. package/dist/observability/QueueDashboard.d.ts +136 -0
  128. package/dist/observability/contracts.d.ts +137 -0
  129. package/dist/observability/index.d.ts +13 -0
  130. package/dist/reliability/DeadLetterQueueManager.d.ts +349 -0
  131. package/dist/reliability/RetryPolicy.d.ts +217 -0
  132. package/dist/reliability/index.d.ts +6 -0
  133. package/dist/router/ControllerDispatcher.d.ts +12 -0
  134. package/dist/router/RequestValidator.d.ts +20 -0
  135. package/dist/runtime/adapter-bun.d.ts +12 -0
  136. package/dist/runtime/adapter-deno.d.ts +12 -0
  137. package/dist/runtime/adapter-node.d.ts +12 -0
  138. package/dist/runtime/adapter-unknown.d.ts +13 -0
  139. package/dist/runtime/archive.d.ts +17 -0
  140. package/dist/runtime/compression.d.ts +21 -0
  141. package/dist/runtime/deep-equals.d.ts +56 -0
  142. package/dist/runtime/detection.d.ts +22 -0
  143. package/dist/runtime/escape.d.ts +34 -0
  144. package/dist/runtime/index.browser.d.ts +20 -0
  145. package/dist/runtime/index.d.ts +44 -0
  146. package/dist/runtime/markdown.d.ts +44 -0
  147. package/dist/runtime/types.d.ts +436 -0
  148. package/dist/runtime-helpers.d.ts +67 -0
  149. package/dist/runtime.d.ts +11 -0
  150. package/dist/security/Encrypter.d.ts +33 -0
  151. package/dist/security/Hasher.d.ts +29 -0
  152. package/dist/testing/HttpTester.d.ts +39 -0
  153. package/dist/testing/TestResponse.d.ts +78 -0
  154. package/dist/testing/index.d.ts +2 -0
  155. package/dist/transpiler-utils.d.ts +170 -0
  156. package/dist/types/events.d.ts +94 -0
  157. package/dist/types.d.ts +13 -0
  158. package/package.json +25 -56
  159. package/src/ffi/native/cbor.c +1148 -0
  160. package/dist/Metrics-VOWWRNNR.js +0 -219
  161. package/dist/chunk-R5U7XKVJ.js +0 -16
  162. package/dist/compat-CI8hiulX.d.ts +0 -376
  163. package/dist/compat.cjs +0 -18
  164. package/dist/compat.d.cts +0 -1
  165. package/dist/engine/index.cjs +0 -1764
  166. package/dist/engine/index.d.cts +0 -922
  167. package/dist/index.cjs +0 -14906
  168. package/dist/index.d.cts +0 -11008
@@ -1,26 +1,78 @@
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
+ function __accessProp(key) {
8
+ return this[key];
9
+ }
10
+ var __toESMCache_node;
11
+ var __toESMCache_esm;
12
+ var __toESM = (mod, isNodeMode, target) => {
13
+ var canCache = mod != null && typeof mod === "object";
14
+ if (canCache) {
15
+ var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
16
+ var cached = cache.get(mod);
17
+ if (cached)
18
+ return cached;
19
+ }
20
+ target = mod != null ? __create(__getProtoOf(mod)) : {};
21
+ const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
22
+ for (let key of __getOwnPropNames(mod))
23
+ if (!__hasOwnProp.call(to, key))
24
+ __defProp(to, key, {
25
+ get: __accessProp.bind(mod, key),
26
+ enumerable: true
27
+ });
28
+ if (canCache)
29
+ cache.set(mod, to);
30
+ return to;
31
+ };
32
+ var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
33
+ var __returnValue = (v) => v;
34
+ function __exportSetter(name, newValue) {
35
+ this[name] = __returnValue.bind(null, newValue);
36
+ }
37
+ var __export = (target, all) => {
38
+ for (var name in all)
39
+ __defProp(target, name, {
40
+ get: all[name],
41
+ enumerable: true,
42
+ configurable: true,
43
+ set: __exportSetter.bind(all, name)
44
+ });
45
+ };
46
+ var __require = import.meta.require;
47
+
48
+ // src/engine/index.ts
49
+ var exports_engine = {};
50
+ __export(exports_engine, {
51
+ extractPath: () => extractPath,
52
+ ObjectPool: () => ObjectPool,
53
+ MinimalContext: () => MinimalContext,
54
+ Gravito: () => Gravito,
55
+ FastContextImpl: () => FastContext,
56
+ AOTRouter: () => AOTRouter
57
+ });
58
+
59
+ // src/adapters/bun/types.ts
60
+ var NodeType;
61
+ ((NodeType2) => {
62
+ NodeType2[NodeType2["STATIC"] = 0] = "STATIC";
63
+ NodeType2[NodeType2["PARAM"] = 1] = "PARAM";
64
+ NodeType2[NodeType2["WILDCARD"] = 2] = "WILDCARD";
65
+ })(NodeType ||= {});
66
+
1
67
  // src/adapters/bun/RadixNode.ts
2
- var RadixNode = class _RadixNode {
3
- // Path segment for this node (e.g., "users", ":id")
68
+ class RadixNode {
4
69
  segment;
5
- // Node type (Static, Param, Wildcard)
6
70
  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)
71
+ children = new Map;
10
72
  paramChild = null;
11
- // Specialized child for wildcard node
12
73
  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")
74
+ handlers = new Map;
16
75
  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
76
  regex = null;
25
77
  constructor(segment = "", type = 0 /* STATIC */) {
26
78
  this.segment = segment;
@@ -38,44 +90,61 @@ var RadixNode = class _RadixNode {
38
90
  };
39
91
  }
40
92
  static fromJSON(json) {
41
- const node = new _RadixNode(json.segment, json.type);
93
+ const node = new RadixNode(json.segment, json.type);
42
94
  node.paramName = json.paramName;
43
95
  if (json.regex) {
44
96
  node.regex = new RegExp(json.regex);
45
97
  }
46
98
  if (json.children) {
47
99
  for (const [key, childJson] of json.children) {
48
- node.children.set(key, _RadixNode.fromJSON(childJson));
100
+ node.children.set(key, RadixNode.fromJSON(childJson));
49
101
  }
50
102
  }
51
103
  if (json.paramChild) {
52
- node.paramChild = _RadixNode.fromJSON(json.paramChild);
104
+ node.paramChild = RadixNode.fromJSON(json.paramChild);
53
105
  }
54
106
  if (json.wildcardChild) {
55
- node.wildcardChild = _RadixNode.fromJSON(json.wildcardChild);
107
+ node.wildcardChild = RadixNode.fromJSON(json.wildcardChild);
56
108
  }
57
109
  return node;
58
110
  }
59
- };
111
+ }
60
112
 
61
113
  // 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
- */
114
+ class RouteCache {
115
+ cache = new Map;
116
+ maxSize = 1e4;
117
+ get(key) {
118
+ return this.cache.get(key);
119
+ }
120
+ set(key, value) {
121
+ if (this.cache.size >= this.maxSize) {
122
+ const firstKey = this.cache.keys().next().value;
123
+ if (firstKey) {
124
+ this.cache.delete(firstKey);
125
+ }
126
+ }
127
+ this.cache.set(key, value);
128
+ }
129
+ clear() {
130
+ this.cache.clear();
131
+ }
132
+ has(key) {
133
+ return this.cache.has(key);
134
+ }
135
+ }
136
+
137
+ class RadixRouter {
138
+ root = new RadixNode;
139
+ globalConstraints = new Map;
140
+ routeCache = new RouteCache;
69
141
  where(param, regex) {
70
142
  this.globalConstraints.set(param, regex);
71
143
  }
72
- /**
73
- * Register a route
74
- */
75
144
  add(method, path, handlers) {
76
145
  let node = this.root;
77
146
  const segments = this.splitPath(path);
78
- for (let i = 0; i < segments.length; i++) {
147
+ for (let i = 0;i < segments.length; i++) {
79
148
  const segment = segments[i];
80
149
  if (segment === "*") {
81
150
  if (!node.wildcardChild) {
@@ -103,10 +172,8 @@ var RadixRouter = class _RadixRouter {
103
172
  }
104
173
  }
105
174
  node.handlers.set(method.toLowerCase(), handlers);
175
+ this.routeCache.clear();
106
176
  }
107
- /**
108
- * Match a request
109
- */
110
177
  match(method, path) {
111
178
  const normalizedMethod = method.toLowerCase();
112
179
  if (path === "/" || path === "") {
@@ -116,9 +183,15 @@ var RadixRouter = class _RadixRouter {
116
183
  }
117
184
  return null;
118
185
  }
186
+ const cacheKey = `${normalizedMethod}:${path}`;
187
+ if (this.routeCache.has(cacheKey)) {
188
+ return this.routeCache.get(cacheKey) ?? null;
189
+ }
119
190
  const searchPath = path.startsWith("/") ? path.slice(1) : path;
120
191
  const segments = searchPath.split("/");
121
- return this.matchRecursive(this.root, segments, 0, {}, normalizedMethod);
192
+ const result = this.matchRecursive(this.root, segments, 0, {}, normalizedMethod);
193
+ this.routeCache.set(cacheKey, result);
194
+ return result;
122
195
  }
123
196
  matchRecursive(node, segments, depth, params, method) {
124
197
  if (depth >= segments.length) {
@@ -141,8 +214,7 @@ var RadixRouter = class _RadixRouter {
141
214
  }
142
215
  const paramChild = node.paramChild;
143
216
  if (paramChild) {
144
- if (paramChild.regex && !paramChild.regex.test(segment)) {
145
- } else {
217
+ if (paramChild.regex && !paramChild.regex.test(segment)) {} else {
146
218
  if (paramChild.paramName) {
147
219
  params[paramChild.paramName] = decodeURIComponent(segment);
148
220
  const match = this.matchRecursive(paramChild, segments, depth + 1, params, method);
@@ -177,9 +249,6 @@ var RadixRouter = class _RadixRouter {
177
249
  }
178
250
  return p.split("/");
179
251
  }
180
- /**
181
- * Serialize the router to a JSON string
182
- */
183
252
  serialize() {
184
253
  return JSON.stringify({
185
254
  root: this.root.toJSON(),
@@ -189,12 +258,9 @@ var RadixRouter = class _RadixRouter {
189
258
  ])
190
259
  });
191
260
  }
192
- /**
193
- * Restore a router from a serialized JSON string
194
- */
195
261
  static fromSerialized(json) {
196
262
  const data = JSON.parse(json);
197
- const router = new _RadixRouter();
263
+ const router = new RadixRouter;
198
264
  router.root = RadixNode.fromJSON(data.root);
199
265
  if (data.globalConstraints) {
200
266
  for (const [key, source] of data.globalConstraints) {
@@ -203,49 +269,22 @@ var RadixRouter = class _RadixRouter {
203
269
  }
204
270
  return router;
205
271
  }
206
- };
272
+ }
207
273
 
208
274
  // 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 */
275
+ class AOTRouter {
276
+ staticRoutes = new Map;
277
+ dynamicRouter = new RadixRouter;
217
278
  routeDefinitions = [];
218
- // Global middleware (applies to all routes)
219
- /** @internal */
220
279
  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;
280
+ pathMiddleware = new Map;
281
+ dynamicRoutePatterns = new Map;
282
+ middlewareCache = new Map;
283
+ cacheMaxSize = 1000;
229
284
  _version = 0;
230
- /**
231
- * Get the current version for cache invalidation
232
- * Incremented whenever middleware or routes are modified
233
- */
234
285
  get version() {
235
286
  return this._version;
236
287
  }
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
288
  add(method, path, handler, middleware = []) {
250
289
  this.routeDefinitions.push({ method, path, handler, middleware });
251
290
  const normalizedMethod = method.toLowerCase();
@@ -261,9 +300,6 @@ var AOTRouter = class {
261
300
  }
262
301
  }
263
302
  }
264
- /**
265
- * Mount another router at a prefix
266
- */
267
303
  mount(prefix, other) {
268
304
  if (other.globalMiddleware.length > 0) {
269
305
  this.usePattern(prefix, ...other.globalMiddleware);
@@ -271,7 +307,8 @@ var AOTRouter = class {
271
307
  this.usePattern(wildcard, ...other.globalMiddleware);
272
308
  }
273
309
  for (const [pattern, mws] of other.pathMiddleware) {
274
- if (pattern.includes(":")) {
310
+ const hasMethodPrefix = /^(get|post|put|delete|patch|options|head):/.test(pattern);
311
+ if (hasMethodPrefix) {
275
312
  continue;
276
313
  }
277
314
  let newPattern;
@@ -296,25 +333,10 @@ var AOTRouter = class {
296
333
  this.add(def.method, newPath, def.handler, def.middleware);
297
334
  }
298
335
  }
299
- /**
300
- * Add global middleware
301
- *
302
- * These run for every request, before route-specific middleware.
303
- *
304
- * @param middleware - Middleware functions
305
- */
306
336
  use(...middleware) {
307
337
  this.globalMiddleware.push(...middleware);
308
338
  this._version++;
309
339
  }
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
340
  usePattern(pattern, ...middleware) {
319
341
  if (pattern === "*") {
320
342
  this.globalMiddleware.push(...middleware);
@@ -324,15 +346,6 @@ var AOTRouter = class {
324
346
  }
325
347
  this._version++;
326
348
  }
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
349
  match(method, path) {
337
350
  const normalizedMethod = method.toLowerCase();
338
351
  const staticKey = `${normalizedMethod}:${path}`;
@@ -365,28 +378,16 @@ var AOTRouter = class {
365
378
  middleware: []
366
379
  };
367
380
  }
368
- /**
369
- * Public wrapper for collectMiddleware (used by Gravito for optimization)
370
- */
371
381
  collectMiddlewarePublic(path, routeMiddleware) {
372
382
  return this.collectMiddleware(path, routeMiddleware);
373
383
  }
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
384
  collectMiddleware(path, routeMiddleware) {
384
385
  if (this.globalMiddleware.length === 0 && this.pathMiddleware.size === 0 && routeMiddleware.length === 0) {
385
386
  return [];
386
387
  }
387
388
  const cacheKey = path;
388
389
  const cached = this.middlewareCache.get(cacheKey);
389
- if (cached !== void 0 && cached.version === this._version) {
390
+ if (cached !== undefined && cached.version === this._version) {
390
391
  return cached.data;
391
392
  }
392
393
  const middleware = [];
@@ -413,23 +414,21 @@ var AOTRouter = class {
413
414
  }
414
415
  return middleware;
415
416
  }
416
- /**
417
- * Check if a path is static (no parameters or wildcards)
418
- */
417
+ getNativeRoutes(onMatch) {
418
+ const routes = {};
419
+ for (const [key, metadata] of this.staticRoutes) {
420
+ const [method, path] = key.split(":");
421
+ if (method !== "get") {
422
+ continue;
423
+ }
424
+ const allMiddleware = this.collectMiddleware(path, metadata.middleware);
425
+ routes[path] = onMatch(metadata.handler, allMiddleware, path);
426
+ }
427
+ return routes;
428
+ }
419
429
  isStaticPath(path) {
420
430
  return !path.includes(":") && !path.includes("*");
421
431
  }
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
432
  matchPattern(pattern, path) {
434
433
  if (pattern === "*") {
435
434
  return true;
@@ -443,9 +442,6 @@ var AOTRouter = class {
443
442
  }
444
443
  return false;
445
444
  }
446
- /**
447
- * Get all registered routes (for debugging)
448
- */
449
445
  getRoutes() {
450
446
  const routes = [];
451
447
  for (const key of this.staticRoutes.keys()) {
@@ -454,11 +450,107 @@ var AOTRouter = class {
454
450
  }
455
451
  return routes;
456
452
  }
457
- };
453
+ }
458
454
 
459
- // src/engine/analyzer.ts
460
- function analyzeHandler(handler) {
461
- const source = handler.toString();
455
+ // src/transpiler-utils.ts
456
+ class TranspilerCache {
457
+ static instance = null;
458
+ transpiler;
459
+ cache;
460
+ maxSize;
461
+ ttlMs;
462
+ constructor(maxSize = 512, ttlMs = 5 * 60 * 1000) {
463
+ this.transpiler = new Bun.Transpiler({ loader: "ts" });
464
+ this.cache = new Map;
465
+ this.maxSize = maxSize;
466
+ this.ttlMs = ttlMs;
467
+ }
468
+ static getInstance() {
469
+ TranspilerCache.instance ??= new TranspilerCache;
470
+ return TranspilerCache.instance;
471
+ }
472
+ static resetInstance() {
473
+ TranspilerCache.instance = null;
474
+ }
475
+ transform(source) {
476
+ const cached = this.cache.get(source);
477
+ if (cached !== undefined) {
478
+ if (Date.now() - cached.createdAt < this.ttlMs) {
479
+ return cached.transformed;
480
+ }
481
+ this.cache.delete(source);
482
+ }
483
+ const transformed = this.doTransform(source);
484
+ if (transformed === null) {
485
+ return null;
486
+ }
487
+ if (this.cache.size >= this.maxSize) {
488
+ const firstKey = this.cache.keys().next().value;
489
+ if (firstKey !== undefined) {
490
+ this.cache.delete(firstKey);
491
+ }
492
+ }
493
+ this.cache.set(source, { transformed, createdAt: Date.now() });
494
+ return transformed;
495
+ }
496
+ doTransform(source) {
497
+ try {
498
+ const out = this.transpiler.transformSync(source);
499
+ if (out.trim().length > 0) {
500
+ return out;
501
+ }
502
+ return this.transformWrapped(source);
503
+ } catch {
504
+ return this.transformWrapped(source);
505
+ }
506
+ }
507
+ transformWrapped(source) {
508
+ try {
509
+ const wrapped = `const __fn = ${source}`;
510
+ const out = this.transpiler.transformSync(wrapped);
511
+ return out.trim().length > 0 ? out : null;
512
+ } catch {
513
+ return null;
514
+ }
515
+ }
516
+ get size() {
517
+ return this.cache.size;
518
+ }
519
+ clear() {
520
+ this.cache.clear();
521
+ }
522
+ }
523
+ var PATTERNS = {
524
+ HEADERS_CALL: /\.req\.headers?\s*\(/,
525
+ HEADERS_DESTR: /\{[^}]*\bheaders?\b[^}]*\}\s*=\s*\w+\.req/,
526
+ QUERY_CALL: /\.req\.quer(?:y|ies)\s*\(/,
527
+ QUERY_DESTR: /\{[^}]*\bquer(?:y|ies)\b[^}]*\}\s*=\s*\w+\.req/,
528
+ BODY_CALL: /\.req\.(?:json|text|formData|blob|arrayBuffer)\s*\(/,
529
+ BODY_DESTR: /\{[^}]*\bbody\b[^}]*\}\s*=\s*\w+\.req/,
530
+ BODY_PROP: /\.req\.body\b/,
531
+ PARAMS_CALL: /\.req\.params?\s*\(/,
532
+ PARAMS_DESTR: /\{[^}]*\bparams?\b[^}]*\}\s*=\s*\w+\.req/,
533
+ IS_ASYNC: /\basync\b/
534
+ };
535
+ function analyzeHandlerWithTranspiler(source) {
536
+ const cache = TranspilerCache.getInstance();
537
+ const transformed = cache.transform(source);
538
+ const isAsync = PATTERNS.IS_ASYNC.test(source);
539
+ if (transformed !== null) {
540
+ return { ...analyzeTransformedCode(transformed), isAsync };
541
+ }
542
+ return { ...fallbackStringAnalysis(source), isAsync };
543
+ }
544
+ function analyzeTransformedCode(code) {
545
+ return {
546
+ usesHeaders: PATTERNS.HEADERS_CALL.test(code) || PATTERNS.HEADERS_DESTR.test(code),
547
+ usesQuery: PATTERNS.QUERY_CALL.test(code) || PATTERNS.QUERY_DESTR.test(code),
548
+ usesBody: PATTERNS.BODY_CALL.test(code) || PATTERNS.BODY_DESTR.test(code) || PATTERNS.BODY_PROP.test(code),
549
+ usesParams: PATTERNS.PARAMS_CALL.test(code) || PATTERNS.PARAMS_DESTR.test(code),
550
+ isAsync: PATTERNS.IS_ASYNC.test(code)
551
+ };
552
+ }
553
+ function fallbackStringAnalysis(source) {
462
554
  return {
463
555
  usesHeaders: source.includes(".header(") || source.includes(".header)") || source.includes(".headers(") || source.includes(".headers)"),
464
556
  usesQuery: source.includes(".query(") || source.includes(".query)") || source.includes(".queries(") || source.includes(".queries)"),
@@ -467,6 +559,12 @@ function analyzeHandler(handler) {
467
559
  isAsync: source.includes("async") || source.includes("await")
468
560
  };
469
561
  }
562
+
563
+ // src/engine/analyzer.ts
564
+ function analyzeHandler(handler) {
565
+ const source = handler.toString();
566
+ return analyzeHandlerWithTranspiler(source);
567
+ }
470
568
  function getOptimalContextType(analysis) {
471
569
  if (analysis.usesHeaders) {
472
570
  return "fast";
@@ -484,7 +582,7 @@ function getOptimalContextType(analysis) {
484
582
  }
485
583
 
486
584
  // src/engine/constants.ts
487
- var encoder = new TextEncoder();
585
+ var encoder = new TextEncoder;
488
586
  var CACHED_RESPONSES = {
489
587
  NOT_FOUND: encoder.encode('{"error":"Not Found"}'),
490
588
  INTERNAL_ERROR: encoder.encode('{"error":"Internal Server Error"}'),
@@ -498,25 +596,15 @@ var HEADERS = {
498
596
  };
499
597
 
500
598
  // src/Container/RequestScopeMetrics.ts
501
- var RequestScopeMetrics = class {
599
+ class RequestScopeMetrics {
502
600
  cleanupStartTime = null;
503
601
  cleanupDuration = null;
504
602
  scopeSize = 0;
505
603
  servicesCleaned = 0;
506
604
  errorsOccurred = 0;
507
- /**
508
- * Record start of cleanup operation
509
- */
510
605
  recordCleanupStart() {
511
606
  this.cleanupStartTime = performance.now();
512
607
  }
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
608
  recordCleanupEnd(scopeSize, servicesCleaned, errorsOccurred = 0) {
521
609
  if (this.cleanupStartTime !== null) {
522
610
  this.cleanupDuration = performance.now() - this.cleanupStartTime;
@@ -526,28 +614,15 @@ var RequestScopeMetrics = class {
526
614
  this.servicesCleaned = servicesCleaned;
527
615
  this.errorsOccurred = errorsOccurred;
528
616
  }
529
- /**
530
- * Get cleanup duration in milliseconds
531
- *
532
- * @returns Duration in ms, or null if cleanup not completed
533
- */
534
617
  getCleanupDuration() {
535
618
  return this.cleanupDuration;
536
619
  }
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
620
  isSlowCleanup(thresholdMs = 2) {
545
- if (this.cleanupDuration === null) return false;
621
+ if (this.cleanupDuration === null) {
622
+ return false;
623
+ }
546
624
  return this.cleanupDuration > thresholdMs;
547
625
  }
548
- /**
549
- * Export metrics as JSON for logging/monitoring
550
- */
551
626
  toJSON() {
552
627
  return {
553
628
  cleanupDuration: this.cleanupDuration,
@@ -558,49 +633,66 @@ var RequestScopeMetrics = class {
558
633
  isSlowCleanup: this.isSlowCleanup()
559
634
  };
560
635
  }
561
- /**
562
- * Export metrics as compact string for logging
563
- */
564
636
  toString() {
565
637
  const duration = this.cleanupDuration ?? "pending";
566
- return `cleanup: ${duration}ms, scope: ${this.scopeSize}, cleaned: ${this.servicesCleaned}, errors: ${this.errorsOccurred}`;
638
+ return `cleanup: ${duration}ms, ` + `scope: ${this.scopeSize}, ` + `cleaned: ${this.servicesCleaned}, ` + `errors: ${this.errorsOccurred}`;
567
639
  }
568
- };
640
+ }
641
+
642
+ class RequestScopeMetricsCollector {
643
+ metrics = [];
644
+ record(metrics) {
645
+ this.metrics.push(metrics);
646
+ }
647
+ getStats() {
648
+ if (this.metrics.length === 0) {
649
+ return {
650
+ count: 0,
651
+ averageCleanupTime: null,
652
+ maxCleanupTime: null,
653
+ minCleanupTime: null,
654
+ totalErrorCount: 0,
655
+ errorRate: 0
656
+ };
657
+ }
658
+ const durations = this.metrics.map((m) => m.getCleanupDuration()).filter((d) => d !== null);
659
+ const errorCounts = this.metrics.map((m) => m.toJSON().errorsOccurred);
660
+ const totalErrors = errorCounts.reduce((a, b) => a + b, 0);
661
+ return {
662
+ count: this.metrics.length,
663
+ averageCleanupTime: durations.length > 0 ? durations.reduce((a, b) => a + b) / durations.length : null,
664
+ maxCleanupTime: durations.length > 0 ? Math.max(...durations) : null,
665
+ minCleanupTime: durations.length > 0 ? Math.min(...durations) : null,
666
+ totalErrorCount: totalErrors,
667
+ errorRate: totalErrors / this.metrics.length
668
+ };
669
+ }
670
+ clear() {
671
+ this.metrics = [];
672
+ }
673
+ size() {
674
+ return this.metrics.length;
675
+ }
676
+ toJSON() {
677
+ return this.metrics.map((m) => m.toJSON());
678
+ }
679
+ }
569
680
 
570
681
  // src/Container/RequestScopeManager.ts
571
- var RequestScopeManager = class {
572
- scoped = /* @__PURE__ */ new Map();
573
- metadata = /* @__PURE__ */ new Map();
574
- metrics = new RequestScopeMetrics();
682
+ class RequestScopeManager {
683
+ scoped = new Map;
684
+ metadata = new Map;
685
+ metrics = new RequestScopeMetrics;
575
686
  observer = null;
576
687
  constructor(observer) {
577
688
  this.observer = observer || null;
578
689
  }
579
- /**
580
- * Set observer for monitoring scope lifecycle
581
- */
582
690
  setObserver(observer) {
583
691
  this.observer = observer;
584
692
  }
585
- /**
586
- * Get metrics for this scope
587
- */
588
693
  getMetrics() {
589
694
  return this.metrics;
590
695
  }
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
696
  resolve(key, factory) {
605
697
  const keyStr = String(key);
606
698
  const isFromCache = this.scoped.has(keyStr);
@@ -614,15 +706,6 @@ var RequestScopeManager = class {
614
706
  this.observer?.onServiceResolved?.(key, isFromCache);
615
707
  return this.scoped.get(keyStr);
616
708
  }
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
709
  async cleanup() {
627
710
  this.metrics.recordCleanupStart();
628
711
  this.observer?.onCleanupStart?.();
@@ -637,9 +720,7 @@ var RequestScopeManager = class {
637
720
  servicesCleaned++;
638
721
  } catch (error) {
639
722
  errors.push(error);
640
- this.observer?.onCleanupError?.(
641
- error instanceof Error ? error : new Error(String(error))
642
- );
723
+ this.observer?.onCleanupError?.(error instanceof Error ? error : new Error(String(error)));
643
724
  }
644
725
  }
645
726
  }
@@ -653,18 +734,20 @@ var RequestScopeManager = class {
653
734
  console.error("RequestScope cleanup errors:", errors);
654
735
  }
655
736
  }
656
- /**
657
- * Get the number of services in this scope (for monitoring).
658
- *
659
- * @returns The count of cached services.
660
- */
661
737
  size() {
662
738
  return this.scoped.size;
663
739
  }
664
- };
740
+ }
665
741
 
666
742
  // src/engine/FastContext.ts
667
- var FastRequestImpl = class {
743
+ var bunEscapeHTML = (html) => {
744
+ return html.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
745
+ };
746
+ try {
747
+ bunEscapeHTML = globalThis.Bun.escapeHTML;
748
+ } catch {}
749
+
750
+ class FastRequestImpl {
668
751
  _request;
669
752
  _params;
670
753
  _path;
@@ -672,21 +755,18 @@ var FastRequestImpl = class {
672
755
  _url = null;
673
756
  _query = null;
674
757
  _headers = null;
675
- _cachedJson = void 0;
758
+ _cachedJson = undefined;
676
759
  _jsonParsed = false;
677
- _cachedText = void 0;
760
+ _cachedText = undefined;
678
761
  _textParsed = false;
679
- _cachedFormData = void 0;
762
+ _cachedFormData = undefined;
680
763
  _formDataParsed = false;
681
764
  _cachedQueries = null;
682
- // Back-reference for release check optimization
765
+ _cachedCookies = null;
683
766
  _ctx;
684
767
  constructor(ctx) {
685
768
  this._ctx = ctx;
686
769
  }
687
- /**
688
- * Initialize for new request
689
- */
690
770
  init(request, params = {}, path = "", routePattern) {
691
771
  this._request = request;
692
772
  this._params = params;
@@ -695,37 +775,34 @@ var FastRequestImpl = class {
695
775
  this._url = null;
696
776
  this._query = null;
697
777
  this._headers = null;
698
- this._cachedJson = void 0;
778
+ this._cachedJson = undefined;
699
779
  this._jsonParsed = false;
700
- this._cachedText = void 0;
780
+ this._cachedText = undefined;
701
781
  this._textParsed = false;
702
- this._cachedFormData = void 0;
782
+ this._cachedFormData = undefined;
703
783
  this._formDataParsed = false;
704
784
  this._cachedQueries = null;
785
+ this._cachedCookies = null;
705
786
  return this;
706
787
  }
707
- /**
708
- * Reset for pooling
709
- */
710
788
  reset() {
711
- this._request = void 0;
712
- this._params = void 0;
789
+ this._request = undefined;
790
+ this._params = undefined;
713
791
  this._url = null;
714
792
  this._query = null;
715
793
  this._headers = null;
716
- this._cachedJson = void 0;
794
+ this._cachedJson = undefined;
717
795
  this._jsonParsed = false;
718
- this._cachedText = void 0;
796
+ this._cachedText = undefined;
719
797
  this._textParsed = false;
720
- this._cachedFormData = void 0;
798
+ this._cachedFormData = undefined;
721
799
  this._formDataParsed = false;
722
800
  this._cachedQueries = null;
801
+ this._cachedCookies = null;
723
802
  }
724
803
  checkReleased() {
725
804
  if (this._ctx._isReleased) {
726
- throw new Error(
727
- "FastContext usage after release detected! (Object Pool Strict Lifecycle Guard)"
728
- );
805
+ throw new Error("FastContext usage after release detected! (Object Pool Strict Lifecycle Guard)");
729
806
  }
730
807
  }
731
808
  get url() {
@@ -763,7 +840,7 @@ var FastRequestImpl = class {
763
840
  if (!this._query) {
764
841
  this._query = this.getUrl().searchParams;
765
842
  }
766
- return this._query.get(name) ?? void 0;
843
+ return this._query.get(name) ?? undefined;
767
844
  }
768
845
  queries() {
769
846
  this.checkReleased();
@@ -776,7 +853,7 @@ var FastRequestImpl = class {
776
853
  const result = {};
777
854
  for (const [key, value] of this._query.entries()) {
778
855
  const existing = result[key];
779
- if (existing === void 0) {
856
+ if (existing === undefined) {
780
857
  result[key] = value;
781
858
  } else if (Array.isArray(existing)) {
782
859
  existing.push(value);
@@ -789,7 +866,7 @@ var FastRequestImpl = class {
789
866
  }
790
867
  header(name) {
791
868
  this.checkReleased();
792
- return this._request.headers.get(name) ?? void 0;
869
+ return this._request.headers.get(name) ?? undefined;
793
870
  }
794
871
  headers() {
795
872
  this.checkReleased();
@@ -801,6 +878,39 @@ var FastRequestImpl = class {
801
878
  }
802
879
  return { ...this._headers };
803
880
  }
881
+ get cookies() {
882
+ this.checkReleased();
883
+ if (this._cachedCookies !== null) {
884
+ return this._cachedCookies;
885
+ }
886
+ const nativeCookies = this._request.cookies;
887
+ if (nativeCookies) {
888
+ this._cachedCookies = nativeCookies;
889
+ return nativeCookies;
890
+ }
891
+ const cookieHeader = this._request.headers.get("cookie");
892
+ if (!cookieHeader) {
893
+ this._cachedCookies = {};
894
+ return {};
895
+ }
896
+ const cookies = {};
897
+ const pairs = cookieHeader.split(/;\s*/);
898
+ for (let i = 0;i < pairs.length; i++) {
899
+ const pair = pairs[i];
900
+ const idx = pair.indexOf("=");
901
+ if (idx > 0) {
902
+ const name = pair.substring(0, idx);
903
+ const value = pair.substring(idx + 1);
904
+ try {
905
+ cookies[name] = decodeURIComponent(value);
906
+ } catch {
907
+ cookies[name] = value;
908
+ }
909
+ }
910
+ }
911
+ this._cachedCookies = cookies;
912
+ return cookies;
913
+ }
804
914
  async json() {
805
915
  this.checkReleased();
806
916
  if (!this._jsonParsed) {
@@ -829,82 +939,57 @@ var FastRequestImpl = class {
829
939
  this.checkReleased();
830
940
  return this._request;
831
941
  }
832
- };
833
- var FastContext = class {
942
+ }
943
+
944
+ class FastContext {
834
945
  req = new FastRequestImpl(this);
835
- // private _statusCode = 200
836
- _headers = new Headers();
837
- // Reuse this object
946
+ _headers = new Headers;
838
947
  _isReleased = false;
839
- // Made public for internal check access
840
948
  _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
949
  init(request, params = {}, path = "", routePattern) {
848
950
  this._isReleased = false;
849
951
  this.req.init(request, params, path, routePattern);
850
- this._headers = new Headers();
851
- this._requestScope = new RequestScopeManager();
952
+ this._headers = new Headers;
953
+ this._requestScope = new RequestScopeManager;
852
954
  return this;
853
955
  }
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
956
  reset() {
861
957
  this._isReleased = true;
862
958
  this.req.reset();
863
959
  this._store.clear();
960
+ this._requestScope = null;
864
961
  }
865
- /**
866
- * Check if context is released
867
- */
868
962
  checkReleased() {
869
963
  if (this._isReleased) {
870
- throw new Error(
871
- "FastContext usage after release detected! (Object Pool Strict Lifecycle Guard)"
872
- );
964
+ throw new Error("FastContext usage after release detected! (Object Pool Strict Lifecycle Guard)");
873
965
  }
874
966
  }
875
- // ─────────────────────────────────────────────────────────────────────────
876
- // Response Helpers
877
- // ─────────────────────────────────────────────────────────────────────────
878
967
  json(data, status = 200) {
879
968
  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
- });
969
+ const headers = new Headers(this._headers);
970
+ headers.set("Content-Type", "application/json; charset=utf-8");
971
+ return Response.json(data, { status, headers });
885
972
  }
886
973
  text(text, status = 200) {
887
974
  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
- });
975
+ const headers = new Headers(this._headers);
976
+ headers.set("Content-Type", "text/plain; charset=utf-8");
977
+ return new Response(text, { status, headers });
893
978
  }
894
979
  html(html, status = 200) {
895
980
  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
- });
981
+ const headers = new Headers(this._headers);
982
+ headers.set("Content-Type", "text/html; charset=utf-8");
983
+ return new Response(html, { status, headers });
984
+ }
985
+ escape(html) {
986
+ return bunEscapeHTML(html);
901
987
  }
902
988
  redirect(url, status = 302) {
903
989
  this.checkReleased();
904
- this._headers.set("Location", url);
905
990
  return new Response(null, {
906
991
  status,
907
- headers: this._headers
992
+ headers: { Location: url }
908
993
  });
909
994
  }
910
995
  body(data, status = 200) {
@@ -914,12 +999,19 @@ var FastContext = class {
914
999
  headers: this._headers
915
1000
  });
916
1001
  }
1002
+ binary(data, status = 200) {
1003
+ this.checkReleased();
1004
+ const body = data instanceof ArrayBuffer ? new Uint8Array(data) : data;
1005
+ return new Response(body, {
1006
+ status,
1007
+ headers: { "Content-Type": "application/octet-stream" }
1008
+ });
1009
+ }
917
1010
  stream(stream, status = 200) {
918
1011
  this.checkReleased();
919
- this._headers.set("Content-Type", "application/octet-stream");
920
1012
  return new Response(stream, {
921
1013
  status,
922
- headers: this._headers
1014
+ headers: { "Content-Type": "application/octet-stream" }
923
1015
  });
924
1016
  }
925
1017
  notFound(message = "Not Found") {
@@ -937,9 +1029,7 @@ var FastContext = class {
937
1029
  async forward(target, _options = {}) {
938
1030
  this.checkReleased();
939
1031
  const url = new URL(this.req.url);
940
- const targetUrl = new URL(
941
- target.startsWith("http") ? target : `${url.protocol}//${target}${this.req.path}`
942
- );
1032
+ const targetUrl = new URL(target.startsWith("http") ? target : `${url.protocol}//${target}${this.req.path}`);
943
1033
  const searchParams = new URLSearchParams(url.search);
944
1034
  searchParams.forEach((v, k) => {
945
1035
  targetUrl.searchParams.set(k, v);
@@ -948,13 +1038,12 @@ var FastContext = class {
948
1038
  method: this.req.method,
949
1039
  headers: this.req.raw.headers,
950
1040
  body: this.req.method !== "GET" && this.req.method !== "HEAD" ? this.req.raw.body : null,
951
- // @ts-expect-error - Bun/Fetch specific
952
1041
  duplex: "half"
953
1042
  });
954
1043
  }
955
1044
  header(name, value) {
956
1045
  this.checkReleased();
957
- if (value !== void 0) {
1046
+ if (value !== undefined) {
958
1047
  this._headers.set(name, value);
959
1048
  return;
960
1049
  }
@@ -963,64 +1052,52 @@ var FastContext = class {
963
1052
  status(_code) {
964
1053
  this.checkReleased();
965
1054
  }
966
- // ─────────────────────────────────────────────────────────────────────────
967
- // Context Variables
968
- // ─────────────────────────────────────────────────────────────────────────
969
- _store = /* @__PURE__ */ new Map();
1055
+ _store = new Map;
970
1056
  get(key) {
971
1057
  return this._store.get(key);
972
1058
  }
973
1059
  set(key, value) {
974
1060
  this._store.set(key, value);
975
1061
  }
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
1062
  requestScope() {
986
1063
  if (!this._requestScope) {
987
1064
  throw new Error("RequestScope not initialized. Call init() first.");
988
1065
  }
989
1066
  return this._requestScope;
990
1067
  }
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
1068
  scoped(key, factory) {
1000
1069
  return this.requestScope().resolve(key, factory);
1001
1070
  }
1002
- // ─────────────────────────────────────────────────────────────────────────
1003
- // Lifecycle helpers
1004
- // ─────────────────────────────────────────────────────────────────────────
1005
1071
  route = () => "";
1006
1072
  get native() {
1007
1073
  return this;
1008
1074
  }
1009
- };
1075
+ }
1010
1076
 
1011
1077
  // src/engine/MinimalContext.ts
1012
- var MinimalRequest = class {
1078
+ var bunEscapeHTML2 = (html) => {
1079
+ return html.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
1080
+ };
1081
+ try {
1082
+ bunEscapeHTML2 = globalThis.Bun.escapeHTML;
1083
+ } catch {}
1084
+
1085
+ class MinimalRequest {
1086
+ _request;
1087
+ _params;
1088
+ _path;
1089
+ _routePattern;
1090
+ _searchParams = null;
1091
+ _cachedQueries = null;
1092
+ _cachedJsonPromise = null;
1093
+ _cachedTextPromise = null;
1094
+ _cachedFormDataPromise = null;
1013
1095
  constructor(_request, _params, _path, _routePattern) {
1014
1096
  this._request = _request;
1015
1097
  this._params = _params;
1016
1098
  this._path = _path;
1017
1099
  this._routePattern = _routePattern;
1018
1100
  }
1019
- _searchParams = null;
1020
- _cachedQueries = null;
1021
- _cachedJsonPromise = null;
1022
- _cachedTextPromise = null;
1023
- _cachedFormDataPromise = null;
1024
1101
  get url() {
1025
1102
  return this._request.url;
1026
1103
  }
@@ -1039,15 +1116,12 @@ var MinimalRequest = class {
1039
1116
  params() {
1040
1117
  return { ...this._params };
1041
1118
  }
1042
- /**
1043
- * Lazy-initialize searchParams, only parse once
1044
- */
1045
1119
  getSearchParams() {
1046
1120
  if (this._searchParams === null) {
1047
1121
  const url = this._request.url;
1048
1122
  const queryStart = url.indexOf("?");
1049
1123
  if (queryStart === -1) {
1050
- this._searchParams = new URLSearchParams();
1124
+ this._searchParams = new URLSearchParams;
1051
1125
  } else {
1052
1126
  const hashStart = url.indexOf("#", queryStart);
1053
1127
  const queryString = hashStart === -1 ? url.slice(queryStart + 1) : url.slice(queryStart + 1, hashStart);
@@ -1057,7 +1131,7 @@ var MinimalRequest = class {
1057
1131
  return this._searchParams;
1058
1132
  }
1059
1133
  query(name) {
1060
- return this.getSearchParams().get(name) ?? void 0;
1134
+ return this.getSearchParams().get(name) ?? undefined;
1061
1135
  }
1062
1136
  queries() {
1063
1137
  if (this._cachedQueries !== null) {
@@ -1067,7 +1141,7 @@ var MinimalRequest = class {
1067
1141
  const result = {};
1068
1142
  for (const [key, value] of params.entries()) {
1069
1143
  const existing = result[key];
1070
- if (existing === void 0) {
1144
+ if (existing === undefined) {
1071
1145
  result[key] = value;
1072
1146
  } else if (Array.isArray(existing)) {
1073
1147
  existing.push(value);
@@ -1079,7 +1153,7 @@ var MinimalRequest = class {
1079
1153
  return result;
1080
1154
  }
1081
1155
  header(name) {
1082
- return this._request.headers.get(name) ?? void 0;
1156
+ return this._request.headers.get(name) ?? undefined;
1083
1157
  }
1084
1158
  headers() {
1085
1159
  const result = {};
@@ -1106,23 +1180,45 @@ var MinimalRequest = class {
1106
1180
  }
1107
1181
  return this._cachedFormDataPromise;
1108
1182
  }
1183
+ get cookies() {
1184
+ const nativeCookies = this._request.cookies;
1185
+ if (nativeCookies) {
1186
+ return nativeCookies;
1187
+ }
1188
+ const cookieHeader = this._request.headers.get("cookie");
1189
+ if (!cookieHeader) {
1190
+ return {};
1191
+ }
1192
+ const cookies = {};
1193
+ const pairs = cookieHeader.split(/;\s*/);
1194
+ for (let i = 0;i < pairs.length; i++) {
1195
+ const pair = pairs[i];
1196
+ const idx = pair.indexOf("=");
1197
+ if (idx > 0) {
1198
+ const name = pair.substring(0, idx);
1199
+ const value = pair.substring(idx + 1);
1200
+ try {
1201
+ cookies[name] = decodeURIComponent(value);
1202
+ } catch {
1203
+ cookies[name] = value;
1204
+ }
1205
+ }
1206
+ }
1207
+ return cookies;
1208
+ }
1109
1209
  get raw() {
1110
1210
  return this._request;
1111
1211
  }
1112
- };
1113
- var MinimalContext = class {
1212
+ }
1213
+
1214
+ class MinimalContext {
1114
1215
  req;
1115
1216
  _resHeaders = {};
1116
1217
  _requestScope;
1117
1218
  constructor(request, params, path, routePattern) {
1118
1219
  this.req = new MinimalRequest(request, params, path, routePattern);
1119
- this._requestScope = new RequestScopeManager();
1220
+ this._requestScope = new RequestScopeManager;
1120
1221
  }
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
1222
  getHeaders(contentType) {
1127
1223
  const headers = Object.assign({ "Content-Type": contentType }, this._resHeaders);
1128
1224
  return headers;
@@ -1158,14 +1254,13 @@ var MinimalContext = class {
1158
1254
  });
1159
1255
  }
1160
1256
  header(name, value) {
1161
- if (value !== void 0) {
1257
+ if (value !== undefined) {
1162
1258
  this._resHeaders[name] = value;
1163
1259
  return;
1164
1260
  }
1165
1261
  return this.req.header(name);
1166
1262
  }
1167
- status(_code) {
1168
- }
1263
+ status(_code) {}
1169
1264
  stream(stream, status = 200) {
1170
1265
  return new Response(stream, {
1171
1266
  status,
@@ -1186,35 +1281,22 @@ var MinimalContext = class {
1186
1281
  }
1187
1282
  async forward(target, _options = {}) {
1188
1283
  const url = new URL(this.req.url);
1189
- const targetUrl = new URL(
1190
- target.startsWith("http") ? target : `${url.protocol}//${target}${this.req.path}`
1191
- );
1284
+ const targetUrl = new URL(target.startsWith("http") ? target : `${url.protocol}//${target}${this.req.path}`);
1192
1285
  return fetch(targetUrl.toString(), {
1193
1286
  method: this.req.method,
1194
1287
  headers: this.req.raw.headers
1195
1288
  });
1196
1289
  }
1197
- get(_key) {
1198
- return void 0;
1290
+ escape(html) {
1291
+ return bunEscapeHTML2(html);
1199
1292
  }
1200
- set(_key, _value) {
1293
+ get(_key) {
1294
+ return;
1201
1295
  }
1202
- /**
1203
- * Get the request-scoped service manager for this request.
1204
- *
1205
- * @returns The RequestScopeManager for this request.
1206
- */
1296
+ set(_key, _value) {}
1207
1297
  requestScope() {
1208
1298
  return this._requestScope;
1209
1299
  }
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
1300
  scoped(key, factory) {
1219
1301
  return this._requestScope.resolve(key, factory);
1220
1302
  }
@@ -1222,14 +1304,11 @@ var MinimalContext = class {
1222
1304
  get native() {
1223
1305
  return this;
1224
1306
  }
1225
- // Required for interface compatibility
1226
1307
  init(_request, _params, _path) {
1227
1308
  throw new Error("MinimalContext does not support init. Create a new instance instead.");
1228
1309
  }
1229
- // Required for interface compatibility
1230
- reset() {
1231
- }
1232
- };
1310
+ reset() {}
1311
+ }
1233
1312
 
1234
1313
  // src/engine/path.ts
1235
1314
  function extractPath(url) {
@@ -1247,79 +1326,38 @@ function extractPath(url) {
1247
1326
  }
1248
1327
 
1249
1328
  // src/engine/pool.ts
1250
- var ObjectPool = class {
1329
+ class ObjectPool {
1251
1330
  pool = [];
1252
1331
  factory;
1253
1332
  reset;
1254
1333
  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
1334
  constructor(factory, reset, maxSize = 256) {
1263
1335
  this.factory = factory;
1264
1336
  this.reset = reset;
1265
1337
  this.maxSize = maxSize;
1266
1338
  }
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
1339
  acquire() {
1276
1340
  const obj = this.pool.pop();
1277
- if (obj !== void 0) {
1341
+ if (obj !== undefined) {
1278
1342
  return obj;
1279
1343
  }
1280
1344
  return this.factory();
1281
1345
  }
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
1346
  release(obj) {
1291
1347
  if (this.pool.length < this.maxSize) {
1292
1348
  this.reset(obj);
1293
1349
  this.pool.push(obj);
1294
1350
  }
1295
1351
  }
1296
- /**
1297
- * Clear all objects from the pool
1298
- *
1299
- * Useful for testing or when you need to force a clean slate.
1300
- */
1301
1352
  clear() {
1302
1353
  this.pool = [];
1303
1354
  }
1304
- /**
1305
- * Get current pool size
1306
- */
1307
1355
  get size() {
1308
1356
  return this.pool.length;
1309
1357
  }
1310
- /**
1311
- * Get maximum pool size
1312
- */
1313
1358
  get capacity() {
1314
1359
  return this.maxSize;
1315
1360
  }
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
1361
  prewarm(count) {
1324
1362
  const targetSize = Math.min(count, this.maxSize);
1325
1363
  while (this.pool.length < targetSize) {
@@ -1328,9 +1366,16 @@ var ObjectPool = class {
1328
1366
  this.pool.push(obj);
1329
1367
  }
1330
1368
  }
1331
- };
1369
+ }
1332
1370
 
1333
1371
  // src/engine/Gravito.ts
1372
+ var bunPeek = (promise) => promise;
1373
+ var bunFile = (path) => path;
1374
+ try {
1375
+ const bunModule = globalThis.Bun;
1376
+ bunPeek = bunModule.peek;
1377
+ bunFile = bunModule.file;
1378
+ } catch {}
1334
1379
  function compileMiddlewareChain(middleware, handler) {
1335
1380
  if (middleware.length === 0) {
1336
1381
  return handler;
@@ -1339,64 +1384,76 @@ function compileMiddlewareChain(middleware, handler) {
1339
1384
  const mw = middleware[0];
1340
1385
  return async (ctx) => {
1341
1386
  let nextCalled = false;
1342
- const result = await mw(ctx, async () => {
1387
+ const result = mw(ctx, async () => {
1343
1388
  nextCalled = true;
1344
- return void 0;
1389
+ return;
1345
1390
  });
1346
- if (result instanceof Response) {
1347
- return result;
1391
+ let finalResult;
1392
+ if (result instanceof Promise) {
1393
+ const peeked = bunPeek(result);
1394
+ finalResult = peeked === result ? await result : peeked;
1395
+ } else {
1396
+ finalResult = result;
1397
+ }
1398
+ if (finalResult instanceof Response) {
1399
+ return finalResult;
1348
1400
  }
1349
1401
  if (nextCalled) {
1350
- return await handler(ctx);
1402
+ const hResult = handler(ctx);
1403
+ if (hResult instanceof Promise) {
1404
+ const p = bunPeek(hResult);
1405
+ return p === hResult ? await hResult : p;
1406
+ }
1407
+ return hResult;
1351
1408
  }
1352
1409
  return ctx.json({ error: "Middleware did not call next or return response" }, 500);
1353
1410
  };
1354
1411
  }
1355
1412
  let compiled = handler;
1356
- for (let i = middleware.length - 1; i >= 0; i--) {
1413
+ for (let i = middleware.length - 1;i >= 0; i--) {
1357
1414
  const mw = middleware[i];
1358
1415
  const nextHandler = compiled;
1359
1416
  compiled = async (ctx) => {
1360
1417
  let nextCalled = false;
1361
- const result = await mw(ctx, async () => {
1418
+ const result = mw(ctx, async () => {
1362
1419
  nextCalled = true;
1363
- return void 0;
1420
+ return;
1364
1421
  });
1365
- if (result instanceof Response) {
1366
- return result;
1422
+ let finalResult;
1423
+ if (result instanceof Promise) {
1424
+ const peeked = bunPeek(result);
1425
+ finalResult = peeked === result ? await result : peeked;
1426
+ } else {
1427
+ finalResult = result;
1428
+ }
1429
+ if (finalResult instanceof Response) {
1430
+ return finalResult;
1367
1431
  }
1368
1432
  if (nextCalled) {
1369
- return await nextHandler(ctx);
1433
+ const nextResult = nextHandler(ctx);
1434
+ if (nextResult instanceof Promise) {
1435
+ const p = bunPeek(nextResult);
1436
+ return p === nextResult ? await nextResult : p;
1437
+ }
1438
+ return nextResult;
1370
1439
  }
1371
1440
  return ctx.json({ error: "Middleware did not call next or return response" }, 500);
1372
1441
  };
1373
1442
  }
1374
1443
  return compiled;
1375
1444
  }
1376
- var Gravito = class {
1377
- router = new AOTRouter();
1445
+
1446
+ class Gravito {
1447
+ router = new AOTRouter;
1378
1448
  contextPool;
1379
1449
  errorHandler;
1380
1450
  notFoundHandler;
1381
- // Direct reference to static routes Map (O(1) access)
1382
- /** @internal */
1383
1451
  staticRoutes;
1384
- // Flag: pure static app (no middleware at all) allows ultra-fast path
1385
1452
  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
- */
1453
+ compiledDynamicRoutes = new Map;
1393
1454
  constructor(options = {}) {
1394
1455
  const poolSize = options.poolSize ?? 256;
1395
- this.contextPool = new ObjectPool(
1396
- () => new FastContext(),
1397
- (ctx) => ctx.reset(),
1398
- poolSize
1399
- );
1456
+ this.contextPool = new ObjectPool(() => new FastContext, (ctx) => ctx.reset(), poolSize);
1400
1457
  this.contextPool.prewarm(Math.min(32, poolSize));
1401
1458
  if (options.onError) {
1402
1459
  this.errorHandler = options.onError;
@@ -1406,58 +1463,27 @@ var Gravito = class {
1406
1463
  }
1407
1464
  this.compileRoutes();
1408
1465
  }
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
1466
  get(path, ...handlers) {
1420
1467
  return this.addRoute("get", path, handlers);
1421
1468
  }
1422
- /**
1423
- * Register a POST route
1424
- */
1425
1469
  post(path, ...handlers) {
1426
1470
  return this.addRoute("post", path, handlers);
1427
1471
  }
1428
- /**
1429
- * Register a PUT route
1430
- */
1431
1472
  put(path, ...handlers) {
1432
1473
  return this.addRoute("put", path, handlers);
1433
1474
  }
1434
- /**
1435
- * Register a DELETE route
1436
- */
1437
1475
  delete(path, ...handlers) {
1438
1476
  return this.addRoute("delete", path, handlers);
1439
1477
  }
1440
- /**
1441
- * Register a PDF route
1442
- */
1443
1478
  patch(path, ...handlers) {
1444
1479
  return this.addRoute("patch", path, handlers);
1445
1480
  }
1446
- /**
1447
- * Register an OPTIONS route
1448
- */
1449
1481
  options(path, ...handlers) {
1450
1482
  return this.addRoute("options", path, handlers);
1451
1483
  }
1452
- /**
1453
- * Register a HEAD route
1454
- */
1455
1484
  head(path, ...handlers) {
1456
1485
  return this.addRoute("head", path, handlers);
1457
1486
  }
1458
- /**
1459
- * Register a route for all HTTP methods
1460
- */
1461
1487
  all(path, ...handlers) {
1462
1488
  const methods = ["get", "post", "put", "delete", "patch", "options", "head"];
1463
1489
  for (const method of methods) {
@@ -1475,45 +1501,19 @@ var Gravito = class {
1475
1501
  this.compileRoutes();
1476
1502
  return this;
1477
1503
  }
1478
- // ─────────────────────────────────────────────────────────────────────────
1479
- // Route Grouping
1480
- // ─────────────────────────────────────────────────────────────────────────
1481
- /**
1482
- * Mount a sub-application at a path prefix
1483
- */
1484
1504
  route(path, app) {
1485
1505
  this.router.mount(path, app.router);
1486
1506
  this.compileRoutes();
1487
1507
  return this;
1488
1508
  }
1489
- // ─────────────────────────────────────────────────────────────────────────
1490
- // Error Handling
1491
- // ─────────────────────────────────────────────────────────────────────────
1492
- /**
1493
- * Set custom error handler
1494
- */
1495
1509
  onError(handler) {
1496
1510
  this.errorHandler = handler;
1497
1511
  return this;
1498
1512
  }
1499
- /**
1500
- * Set custom 404 handler
1501
- */
1502
1513
  notFound(handler) {
1503
1514
  this.notFoundHandler = handler;
1504
1515
  return this;
1505
1516
  }
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
1517
  async warmup(paths) {
1518
1518
  const dummyReqOpts = { headers: { "User-Agent": "Gravito-Warmup/1.0" } };
1519
1519
  for (const path of paths) {
@@ -1521,96 +1521,141 @@ var Gravito = class {
1521
1521
  await this.fetch(req);
1522
1522
  }
1523
1523
  }
1524
- /**
1525
- * Handle an incoming request
1526
- */
1524
+ serveConfig(baseConfig = {}) {
1525
+ const nativeRoutes = this.router.getNativeRoutes((handler, middleware, path) => {
1526
+ const compiled = compileMiddlewareChain(middleware, handler);
1527
+ return async (req) => {
1528
+ const ctx = this.contextPool.acquire();
1529
+ ctx.init(req, {}, path, path);
1530
+ try {
1531
+ const result = compiled(ctx);
1532
+ let response;
1533
+ if (result instanceof Promise) {
1534
+ const peeked = bunPeek(result);
1535
+ response = peeked === result ? await result : peeked;
1536
+ } else {
1537
+ response = result;
1538
+ }
1539
+ const cleanup = ctx.requestScope().cleanup();
1540
+ if (cleanup instanceof Promise) {
1541
+ await cleanup;
1542
+ }
1543
+ this.contextPool.release(ctx);
1544
+ return response;
1545
+ } catch (error) {
1546
+ const cleanup = ctx.requestScope().cleanup();
1547
+ if (cleanup instanceof Promise) {
1548
+ await cleanup;
1549
+ }
1550
+ this.contextPool.release(ctx);
1551
+ return this.handleErrorSync(error, req, path);
1552
+ }
1553
+ };
1554
+ });
1555
+ return {
1556
+ ...baseConfig,
1557
+ routes: nativeRoutes,
1558
+ fetch: this.fetch,
1559
+ tls: baseConfig.tls ? this.optimizeTLS(baseConfig.tls) : undefined,
1560
+ error: (error) => {
1561
+ console.error("Native route error:", error);
1562
+ return new Response(CACHED_RESPONSES.INTERNAL_ERROR, {
1563
+ status: 500,
1564
+ headers: HEADERS.JSON
1565
+ });
1566
+ }
1567
+ };
1568
+ }
1569
+ optimizeTLS(tls) {
1570
+ const isProd = false;
1571
+ const optimizeEntry = (entry) => {
1572
+ const optimized = { ...entry };
1573
+ if (typeof optimized.key === "string" && !optimized.key.startsWith("-----BEGIN")) {
1574
+ optimized.key = bunFile(optimized.key);
1575
+ }
1576
+ if (typeof optimized.cert === "string" && !optimized.cert.startsWith("-----BEGIN")) {
1577
+ optimized.cert = bunFile(optimized.cert);
1578
+ }
1579
+ if (isProd && optimized.lowMemoryMode === undefined) {
1580
+ optimized.lowMemoryMode = true;
1581
+ }
1582
+ return optimized;
1583
+ };
1584
+ return Array.isArray(tls) ? tls.map(optimizeEntry) : optimizeEntry(tls);
1585
+ }
1527
1586
  fetch = async (request) => {
1528
1587
  const path = extractPath(request.url);
1529
1588
  const method = request.method.toLowerCase();
1530
1589
  const staticKey = `${method}:${path}`;
1531
1590
  const staticRoute = this.staticRoutes.get(staticKey);
1532
1591
  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);
1592
+ const ctx = this.contextPool.acquire();
1593
+ ctx.init(request, {}, path, path);
1594
+ try {
1595
+ const compiled = staticRoute.compiled || compileMiddlewareChain(staticRoute.middleware, staticRoute.handler);
1596
+ const result = compiled(ctx);
1597
+ let response;
1598
+ if (result instanceof Promise) {
1599
+ const peeked = bunPeek(result);
1600
+ response = peeked === result ? await result : peeked;
1601
+ } else {
1602
+ response = result;
1603
+ }
1604
+ const cleanup = ctx.requestScope().cleanup();
1605
+ if (cleanup instanceof Promise) {
1606
+ await cleanup;
1607
+ }
1608
+ this.contextPool.release(ctx);
1609
+ return response;
1610
+ } catch (error) {
1611
+ const cleanup = ctx.requestScope().cleanup();
1612
+ if (cleanup instanceof Promise) {
1613
+ await cleanup;
1543
1614
  }
1615
+ this.contextPool.release(ctx);
1616
+ return this.handleErrorSync(error, request, path);
1544
1617
  }
1545
- return await this.handleWithMiddleware(request, path, staticRoute);
1546
1618
  }
1547
1619
  return await this.handleDynamicRoute(request, method, path);
1548
1620
  };
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 {
1621
+ async handleDynamicRoute(request, method, path) {
1622
+ const match = this.router.match(method, path);
1623
+ if (match.handler) {
1624
+ const ctx = this.contextPool.acquire();
1625
+ ctx.init(request, match.params, path, match.routePattern);
1567
1626
  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);
1627
+ const routeKey = `${method}:${match.routePattern}`;
1628
+ let compiledObj = this.compiledDynamicRoutes.get(routeKey);
1629
+ if (!compiledObj || compiledObj.version !== this.router.version) {
1630
+ const compiled = compileMiddlewareChain(match.middleware, match.handler);
1631
+ compiledObj = { compiled, version: this.router.version };
1632
+ this.compiledDynamicRoutes.set(routeKey, compiledObj);
1633
+ }
1634
+ const result = compiledObj.compiled(ctx);
1635
+ let response;
1636
+ if (result instanceof Promise) {
1637
+ const peeked = bunPeek(result);
1638
+ response = peeked === result ? await result : peeked;
1639
+ } else {
1640
+ response = result;
1641
+ }
1642
+ const cleanup = ctx.requestScope().cleanup();
1643
+ if (cleanup instanceof Promise) {
1644
+ await cleanup;
1645
+ }
1646
+ this.contextPool.release(ctx);
1647
+ return response;
1598
1648
  } 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);
1649
+ const cleanup = ctx.requestScope().cleanup();
1650
+ if (cleanup instanceof Promise) {
1651
+ await cleanup;
1605
1652
  }
1606
1653
  this.contextPool.release(ctx);
1654
+ return this.handleErrorSync(error, request, path);
1607
1655
  }
1608
- };
1609
- return execute();
1656
+ }
1657
+ return this.handleNotFoundSync(request, path);
1610
1658
  }
1611
- /**
1612
- * Sync error handler (for ultra-fast path)
1613
- */
1614
1659
  handleErrorSync(error, request, path) {
1615
1660
  if (this.errorHandler) {
1616
1661
  const ctx = new MinimalContext(request, {}, path);
@@ -1626,9 +1671,6 @@ var Gravito = class {
1626
1671
  headers: HEADERS.JSON
1627
1672
  });
1628
1673
  }
1629
- /**
1630
- * Sync 404 handler (for ultra-fast path)
1631
- */
1632
1674
  handleNotFoundSync(request, path) {
1633
1675
  if (this.notFoundHandler) {
1634
1676
  const ctx = new MinimalContext(request, {}, path);
@@ -1643,18 +1685,12 @@ var Gravito = class {
1643
1685
  headers: HEADERS.JSON
1644
1686
  });
1645
1687
  }
1646
- /**
1647
- * Collect middleware for a specific path
1648
- */
1649
1688
  collectMiddlewareForPath(path, routeMiddleware) {
1650
1689
  if (this.router.globalMiddleware.length === 0 && this.router.pathMiddleware.size === 0) {
1651
1690
  return routeMiddleware;
1652
1691
  }
1653
1692
  return this.router.collectMiddlewarePublic(path, routeMiddleware);
1654
1693
  }
1655
- /**
1656
- * Compile routes for optimization
1657
- */
1658
1694
  compileRoutes() {
1659
1695
  this.staticRoutes = this.router.staticRoutes;
1660
1696
  const hasGlobalMiddleware = this.router.globalMiddleware.length > 0;
@@ -1674,9 +1710,6 @@ var Gravito = class {
1674
1710
  route.compiledVersion = this.router.version;
1675
1711
  }
1676
1712
  }
1677
- /**
1678
- * Add a route to the router
1679
- */
1680
1713
  addRoute(method, path, handlers) {
1681
1714
  if (handlers.length === 0) {
1682
1715
  throw new Error(`No handler provided for ${method.toUpperCase()} ${path}`);
@@ -1687,46 +1720,14 @@ var Gravito = class {
1687
1720
  this.compileRoutes();
1688
1721
  return this;
1689
1722
  }
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
- };
1723
+ }
1725
1724
  export {
1726
- AOTRouter,
1727
- FastContext as FastContextImpl,
1728
- Gravito,
1729
- MinimalContext,
1725
+ extractPath,
1730
1726
  ObjectPool,
1731
- extractPath
1727
+ MinimalContext,
1728
+ Gravito,
1729
+ FastContext as FastContextImpl,
1730
+ AOTRouter
1732
1731
  };
1732
+
1733
+ //# debugId=1A9EA2323316056B64756E2164756E21