elysia 2.0.0-exp.41 → 2.0.0-exp.43

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 (239) hide show
  1. package/dist/adapter/bun/index.d.ts +1 -1
  2. package/dist/adapter/bun/index.js +128 -67
  3. package/dist/adapter/bun/index.mjs +128 -67
  4. package/dist/adapter/default-headers.d.ts +4 -0
  5. package/dist/adapter/default-headers.js +7 -0
  6. package/dist/adapter/default-headers.mjs +5 -0
  7. package/dist/adapter/types.d.ts +4 -37
  8. package/dist/adapter/utils.d.ts +6 -3
  9. package/dist/adapter/utils.js +53 -15
  10. package/dist/adapter/utils.mjs +52 -16
  11. package/dist/adapter/web-standard/handler.js +39 -35
  12. package/dist/adapter/web-standard/handler.mjs +40 -36
  13. package/dist/adapter/web-standard/index.js +20 -8
  14. package/dist/adapter/web-standard/index.mjs +20 -8
  15. package/dist/adapter/web-standard/utils.js +8 -2
  16. package/dist/adapter/web-standard/utils.mjs +8 -2
  17. package/dist/base.d.ts +30 -10
  18. package/dist/base.js +500 -151
  19. package/dist/base.mjs +503 -154
  20. package/dist/compile/aot-capture.d.ts +2 -1
  21. package/dist/compile/aot-capture.js +23 -7
  22. package/dist/compile/aot-capture.mjs +22 -7
  23. package/dist/compile/aot.d.ts +55 -44
  24. package/dist/compile/aot.js +149 -32
  25. package/dist/compile/aot.mjs +141 -31
  26. package/dist/compile/handler/descriptor.d.ts +90 -0
  27. package/dist/compile/handler/descriptor.js +210 -0
  28. package/dist/compile/handler/descriptor.mjs +205 -0
  29. package/dist/compile/handler/frozen-validator.d.ts +4 -3
  30. package/dist/compile/handler/frozen-validator.js +107 -10
  31. package/dist/compile/handler/frozen-validator.mjs +107 -11
  32. package/dist/compile/handler/index.d.ts +4 -6
  33. package/dist/compile/handler/index.js +120 -63
  34. package/dist/compile/handler/index.mjs +121 -63
  35. package/dist/compile/handler/jit.d.ts +12 -5
  36. package/dist/compile/handler/jit.js +163 -130
  37. package/dist/compile/handler/jit.mjs +169 -137
  38. package/dist/compile/handler/params.d.ts +3 -0
  39. package/dist/compile/handler/params.js +8 -1
  40. package/dist/compile/handler/params.mjs +12 -5
  41. package/dist/compile/handler/reconstruct.js +7 -4
  42. package/dist/compile/handler/reconstruct.mjs +7 -4
  43. package/dist/compile/handler/utils.d.ts +8 -4
  44. package/dist/compile/handler/utils.js +37 -4
  45. package/dist/compile/handler/utils.mjs +35 -3
  46. package/dist/compile/plan/emit.d.ts +21 -0
  47. package/dist/compile/plan/emit.js +457 -0
  48. package/dist/compile/plan/emit.mjs +456 -0
  49. package/dist/compile/plan/plan.d.ts +76 -0
  50. package/dist/compile/plan/plan.js +130 -0
  51. package/dist/compile/plan/plan.mjs +128 -0
  52. package/dist/compile/utils.js +1 -1
  53. package/dist/compile/utils.mjs +1 -1
  54. package/dist/context.d.ts +4 -4
  55. package/dist/context.js +41 -9
  56. package/dist/context.mjs +42 -10
  57. package/dist/cookie/config.d.ts +2 -0
  58. package/dist/cookie/config.js +2 -1
  59. package/dist/cookie/config.mjs +2 -1
  60. package/dist/cookie/cookie.d.ts +1 -1
  61. package/dist/cookie/cookie.js +7 -2
  62. package/dist/cookie/cookie.mjs +8 -2
  63. package/dist/cookie/crypto.d.ts +15 -0
  64. package/dist/cookie/crypto.js +125 -0
  65. package/dist/cookie/crypto.mjs +113 -0
  66. package/dist/cookie/index.d.ts +3 -2
  67. package/dist/cookie/index.js +3 -3
  68. package/dist/cookie/index.mjs +3 -2
  69. package/dist/cookie/utils.d.ts +5 -15
  70. package/dist/cookie/utils.js +61 -121
  71. package/dist/cookie/utils.mjs +44 -104
  72. package/dist/error.js +58 -6
  73. package/dist/error.mjs +58 -6
  74. package/dist/experimental/resume.d.ts +11 -0
  75. package/dist/experimental/resume.js +12 -0
  76. package/dist/experimental/resume.mjs +11 -0
  77. package/dist/generation.d.ts +23 -0
  78. package/dist/generation.js +13 -0
  79. package/dist/generation.mjs +10 -0
  80. package/dist/handler/error.js +6 -6
  81. package/dist/handler/error.mjs +8 -8
  82. package/dist/handler/fetch.js +67 -78
  83. package/dist/handler/fetch.mjs +67 -78
  84. package/dist/handler/utils.d.ts +8 -1
  85. package/dist/handler/utils.js +17 -2
  86. package/dist/handler/utils.mjs +15 -3
  87. package/dist/index.d.ts +11 -11
  88. package/dist/index.js +1 -1
  89. package/dist/index.mjs +1 -1
  90. package/dist/memory.js +1 -1
  91. package/dist/memory.mjs +1 -1
  92. package/dist/package.js +11 -0
  93. package/dist/package.mjs +5 -0
  94. package/dist/parse-query.js +2 -2
  95. package/dist/parse-query.mjs +2 -2
  96. package/dist/plugin/{bun.d.ts → aot/bun.d.ts} +2 -2
  97. package/dist/plugin/{bun.js → aot/bun.js} +6 -6
  98. package/dist/plugin/{bun.mjs → aot/bun.mjs} +2 -2
  99. package/dist/plugin/{core.d.ts → aot/core.d.ts} +47 -14
  100. package/dist/plugin/{core.js → aot/core.js} +127 -35
  101. package/dist/plugin/{core.mjs → aot/core.mjs} +121 -32
  102. package/dist/plugin/{esbuild.d.ts → aot/esbuild.d.ts} +3 -3
  103. package/dist/plugin/aot/esbuild.js +79 -0
  104. package/dist/plugin/aot/esbuild.mjs +77 -0
  105. package/dist/plugin/aot/hooks.d.ts +14 -0
  106. package/dist/plugin/aot/hooks.js +75 -0
  107. package/dist/plugin/{vite.mjs → aot/hooks.mjs} +16 -35
  108. package/dist/plugin/aot/rspack-loader.d.ts +23 -0
  109. package/dist/plugin/aot/rspack-loader.js +44 -0
  110. package/dist/plugin/aot/rspack-loader.mjs +40 -0
  111. package/dist/plugin/aot/rspack.d.ts +23 -0
  112. package/dist/plugin/aot/rspack.js +86 -0
  113. package/dist/plugin/aot/rspack.mjs +83 -0
  114. package/dist/plugin/{source.d.ts → aot/source.d.ts} +7 -17
  115. package/dist/plugin/{source.js → aot/source.js} +21 -190
  116. package/dist/plugin/{source.mjs → aot/source.mjs} +22 -189
  117. package/dist/plugin/{treeshake.d.ts → aot/treeshake.d.ts} +1 -1
  118. package/dist/plugin/{treeshake.mjs → aot/treeshake.js} +8 -4
  119. package/dist/plugin/{treeshake.js → aot/treeshake.mjs} +6 -6
  120. package/dist/plugin/aot/unplugin.d.ts +54 -0
  121. package/dist/plugin/aot/unplugin.js +68 -0
  122. package/dist/plugin/aot/unplugin.mjs +66 -0
  123. package/dist/plugin/{vite.d.ts → aot/vite.d.ts} +2 -2
  124. package/dist/plugin/aot/vite.js +34 -0
  125. package/dist/plugin/aot/vite.mjs +33 -0
  126. package/dist/plugin/aot/worker.d.ts +1 -0
  127. package/dist/plugin/aot/worker.js +28 -0
  128. package/dist/plugin/aot/worker.mjs +27 -0
  129. package/dist/plugin/auto-head.d.ts +6 -0
  130. package/dist/plugin/auto-head.js +38 -0
  131. package/dist/plugin/auto-head.mjs +36 -0
  132. package/dist/route-table.d.ts +26 -0
  133. package/dist/route-table.js +63 -0
  134. package/dist/route-table.mjs +60 -0
  135. package/dist/schema-snapshot.d.ts +5 -0
  136. package/dist/schema-snapshot.js +111 -0
  137. package/dist/schema-snapshot.mjs +108 -0
  138. package/dist/sucrose.d.ts +13 -1
  139. package/dist/sucrose.js +122 -55
  140. package/dist/sucrose.mjs +121 -56
  141. package/dist/trace.d.ts +1 -1
  142. package/dist/type/bridge-live.d.ts +3 -3
  143. package/dist/type/bridge-live.js +1 -1
  144. package/dist/type/bridge-live.mjs +1 -1
  145. package/dist/type/bridge.d.ts +8 -8
  146. package/dist/type/coerce-plan.d.ts +5 -1
  147. package/dist/type/coerce-plan.js +14 -1
  148. package/dist/type/coerce-plan.mjs +13 -2
  149. package/dist/type/coerce.js +15 -0
  150. package/dist/type/coerce.mjs +15 -0
  151. package/dist/type/compat.js +1 -1
  152. package/dist/type/compat.mjs +1 -1
  153. package/dist/type/constants.d.ts +1 -1
  154. package/dist/type/elysia/accelerate.js +2 -1
  155. package/dist/type/elysia/accelerate.mjs +2 -1
  156. package/dist/type/elysia/array-buffer.js +2 -2
  157. package/dist/type/elysia/array-buffer.mjs +2 -2
  158. package/dist/type/elysia/array-string.js +1 -1
  159. package/dist/type/elysia/array-string.mjs +1 -1
  160. package/dist/type/elysia/boolean-string.js +1 -1
  161. package/dist/type/elysia/boolean-string.mjs +1 -1
  162. package/dist/type/elysia/cookie.d.ts +2 -5
  163. package/dist/type/elysia/date.js +1 -1
  164. package/dist/type/elysia/date.mjs +1 -1
  165. package/dist/type/elysia/file-type.d.ts +1 -1
  166. package/dist/type/elysia/file-type.js +3 -2
  167. package/dist/type/elysia/file-type.mjs +3 -2
  168. package/dist/type/elysia/file.js +2 -2
  169. package/dist/type/elysia/file.mjs +2 -2
  170. package/dist/type/elysia/files.js +6 -6
  171. package/dist/type/elysia/files.mjs +6 -6
  172. package/dist/type/elysia/integer-string.js +4 -4
  173. package/dist/type/elysia/integer-string.mjs +4 -4
  174. package/dist/type/elysia/maybe-empty.js +1 -1
  175. package/dist/type/elysia/maybe-empty.mjs +1 -1
  176. package/dist/type/elysia/nullable.js +1 -1
  177. package/dist/type/elysia/nullable.mjs +1 -1
  178. package/dist/type/elysia/numeric-enum.js +1 -1
  179. package/dist/type/elysia/numeric-enum.mjs +1 -1
  180. package/dist/type/elysia/numeric.js +1 -1
  181. package/dist/type/elysia/numeric.mjs +1 -1
  182. package/dist/type/elysia/object-string.js +1 -1
  183. package/dist/type/elysia/object-string.mjs +1 -1
  184. package/dist/type/elysia/string.js +16 -3
  185. package/dist/type/elysia/string.mjs +16 -3
  186. package/dist/type/elysia/uint8-array.js +3 -3
  187. package/dist/type/elysia/uint8-array.mjs +3 -3
  188. package/dist/type/elysia/utils.d.ts +7 -1
  189. package/dist/type/elysia/utils.js +36 -6
  190. package/dist/type/elysia/utils.mjs +33 -6
  191. package/dist/type/exports.d.ts +1 -1
  192. package/dist/type/index.d.ts +1 -1
  193. package/dist/type/types.d.ts +20 -8
  194. package/dist/type/validator/clean-safe.d.ts +2 -1
  195. package/dist/type/validator/clean-safe.js +9 -1
  196. package/dist/type/validator/clean-safe.mjs +10 -2
  197. package/dist/type/validator/custom-error.js +126 -41
  198. package/dist/type/validator/custom-error.mjs +126 -41
  199. package/dist/type/validator/default-precompute.js +30 -16
  200. package/dist/type/validator/default-precompute.mjs +30 -16
  201. package/dist/type/validator/index.d.ts +2 -2
  202. package/dist/type/validator/index.js +188 -60
  203. package/dist/type/validator/index.mjs +188 -60
  204. package/dist/type/validator/string-codec-aot.d.ts +1 -1
  205. package/dist/type/validator/string-codec-aot.js +2 -0
  206. package/dist/type/validator/string-codec-aot.mjs +2 -0
  207. package/dist/type/validator/validator-cache.d.ts +1 -2
  208. package/dist/type/validator/validator-cache.js +3 -13
  209. package/dist/type/validator/validator-cache.mjs +3 -13
  210. package/dist/types.d.ts +148 -23
  211. package/dist/universal/env.d.ts +3 -2
  212. package/dist/universal/env.js +6 -2
  213. package/dist/universal/env.mjs +5 -2
  214. package/dist/universal/file.d.ts +7 -4
  215. package/dist/universal/file.js +42 -26
  216. package/dist/universal/file.mjs +42 -26
  217. package/dist/universal/is-production.d.ts +2 -1
  218. package/dist/universal/is-production.js +3 -1
  219. package/dist/universal/is-production.mjs +4 -3
  220. package/dist/utils.d.ts +15 -3
  221. package/dist/utils.js +110 -8
  222. package/dist/utils.mjs +108 -8
  223. package/dist/validator/index.d.ts +6 -3
  224. package/dist/validator/index.js +101 -24
  225. package/dist/validator/index.mjs +102 -25
  226. package/dist/validator/route.d.ts +1 -1
  227. package/dist/validator/route.js +2 -1
  228. package/dist/validator/route.mjs +2 -1
  229. package/dist/ws/context.d.ts +2 -2
  230. package/dist/ws/route.d.ts +1 -1
  231. package/dist/ws/route.js +111 -20
  232. package/dist/ws/route.mjs +111 -20
  233. package/package.json +50 -18
  234. package/dist/compile/build-router.d.ts +0 -14
  235. package/dist/compile/build-router.js +0 -212
  236. package/dist/compile/build-router.mjs +0 -208
  237. package/dist/plugin/esbuild.js +0 -46
  238. package/dist/plugin/esbuild.mjs +0 -44
  239. package/dist/plugin/vite.js +0 -94
@@ -1,7 +1,7 @@
1
1
  import { AnyElysia } from "../../base.js";
2
2
  import { ElysiaAdapterOptions } from "../types.js";
3
3
  //#region src/adapter/bun/index.d.ts
4
- declare function collectStaticRoutes(app: AnyElysia): readonly [Record<string, Record<string, Response>>, Promise<void>[]] | undefined;
4
+ declare function collectStaticRoutes(app: AnyElysia): readonly [Record<string, Record<string, Response>>, readonly []] | undefined;
5
5
  declare const BunAdapter: ElysiaAdapterOptions;
6
6
  //#endregion
7
7
  export { BunAdapter, collectStaticRoutes };
@@ -3,34 +3,42 @@ const require_adapter_index = require('../index.js');
3
3
  const require_constants = require('../../constants.js');
4
4
  const require_utils = require('../../utils.js');
5
5
  const require_adapter_web_standard_index = require('../web-standard/index.js');
6
+ const require_generation = require('../../generation.js');
6
7
  const require_compile_handler_index = require('../../compile/handler/index.js');
7
- const require_memory = require('../../memory.js');
8
+ const require_route_table = require('../../route-table.js');
8
9
  const require_ws_route = require('../../ws/route.js');
9
10
 
10
11
  //#region src/adapter/bun/index.ts
12
+ const nativeStaticMethods = new Set([
13
+ "GET",
14
+ "POST",
15
+ "PUT",
16
+ "DELETE",
17
+ "PATCH",
18
+ "HEAD",
19
+ "OPTIONS"
20
+ ]);
11
21
  function collectStaticRoutes(app) {
12
22
  if (app["~config"]?.nativeStaticResponse === false) return;
13
23
  app.fetch;
14
- const fetchLevelHook = require_utils.flattenChain(app["~hookChain"]);
15
- if (fetchLevelHook?.request?.length || fetchLevelHook?.trace?.length || app["~ext"]?.hoc?.length) return;
16
- const history = app.history;
17
- if (!history?.length) return;
24
+ const frozenRoot = require_generation.frozenRootOf(app);
25
+ const fetchLevelHook = require_utils.flattenChain(frozenRoot["~hookChain"]);
26
+ if (fetchLevelHook?.request?.length || fetchLevelHook?.trace?.length || frozenRoot["~ext"]?.hoc?.length) return;
27
+ const table = app["~generation"]?.routeTable ?? app["~routeTable"];
28
+ const length = table?.length ?? 0;
29
+ if (!table || !length) return;
30
+ const methods = table.method;
31
+ const paths = table.path;
18
32
  const ready = require_utils.nullObject();
19
- const pending = [];
20
- const strictPath = app["~config"]?.strictPath === true;
33
+ const strictPath = frozenRoot["~config"]?.strictPath === true;
21
34
  const seen = /* @__PURE__ */ new Map();
22
- for (let i = 0; i < history.length; i++) {
23
- const route = history[i];
24
- const method = route[0];
25
- seen.set(method + " " + route[1], i);
26
- }
35
+ for (let i = 0; i < length; i++) seen.set(methods[i] + " " + paths[i], i);
27
36
  let explicitPaths;
28
37
  if (!strictPath) {
29
38
  explicitPaths = /* @__PURE__ */ new Map();
30
- for (let i = 0; i < history.length; i++) {
31
- const route = history[i];
32
- const method = route[0];
33
- const path = route[1];
39
+ for (let i = 0; i < length; i++) {
40
+ const method = methods[i];
41
+ const path = paths[i];
34
42
  let set = explicitPaths.get(method);
35
43
  if (!set) explicitPaths.set(method, set = /* @__PURE__ */ new Set());
36
44
  set.add(path);
@@ -42,20 +50,15 @@ function collectStaticRoutes(app) {
42
50
  }
43
51
  const add = (method, path, value) => {
44
52
  if (require_constants.needEncodeRegex.test(path)) path = encodeURI(path);
45
- if (value instanceof Promise) pending.push(value.then((resolved) => {
46
- if (resolved instanceof Response) (ready[path] ??= require_utils.nullObject())[method] = resolved;
47
- }, (err) => {
48
- console.error(`[Elysia] Static route ${method} ${path} failed to resolve:`, err);
49
- }));
50
- else (ready[path] ??= require_utils.nullObject())[method] = value;
53
+ (ready[path] ??= require_utils.nullObject())[method] = value;
51
54
  };
52
- for (let i = 0; i < history.length; i++) {
53
- const route = history[i];
54
- if (route[0] === "WS") continue;
55
- const method = route[0];
56
- const path = route[1];
55
+ for (let i = 0; i < length; i++) {
56
+ const method = methods[i];
57
+ if (method === "WS") continue;
58
+ const path = paths[i];
57
59
  if (seen.get(method + " " + path) !== i) continue;
58
- const value = require_compile_handler_index.buildNativeStaticResponse(route, app);
60
+ if (!nativeStaticMethods.has(method)) continue;
61
+ const value = require_compile_handler_index.buildNativeStaticResponse(require_route_table.routeRow(table, i), app);
59
62
  if (!value) continue;
60
63
  add(method, path, value);
61
64
  if (!strictPath && !require_constants.isDynamicRegex.test(path)) {
@@ -63,8 +66,8 @@ function collectStaticRoutes(app) {
63
66
  if (loose !== path && !explicitPaths?.get(method)?.has(loose)) add(method, loose, value);
64
67
  }
65
68
  }
66
- if (!Object.keys(ready).length && !pending.length) return;
67
- return [ready, pending];
69
+ if (!Object.keys(ready).length) return;
70
+ return [ready, []];
68
71
  }
69
72
  const BunAdapter = require_adapter_index.createAdapter({
70
73
  name: "bun",
@@ -84,46 +87,104 @@ const BunAdapter = require_adapter_index.createAdapter({
84
87
  ..._config,
85
88
  ..._options
86
89
  } : _options;
87
- const server = app.server = Bun.serve(serve);
88
90
  const onSetup = app["~ext"]?.setup;
89
- if (onSetup) for (let i = 0; i < onSetup.length; i++) onSetup[i](app);
90
- const hasWs = app["~hasWS"];
91
- if (!hasWs) callback?.(app.server);
92
- queueMicrotask(() => {
93
- if (app.server !== server) return;
94
- if (!app.pending) serve.fetch = app.fetch;
95
- const buildWebSocket = () => {
96
- const defaultConfig = app["~config"]?.websocket;
97
- serve.websocket = defaultConfig ? Object.assign(require_ws_route.buildGlobalWSHandler(), defaultConfig) : require_ws_route.buildGlobalWSHandler();
98
- };
99
- if (hasWs) buildWebSocket();
100
- const collectRoutes = () => {
101
- const staticRoutes = collectStaticRoutes(app);
102
- if (!staticRoutes) return;
103
- if (staticRoutes[1].length) return Promise.all(staticRoutes[1]).then(() => {
104
- if (app.server !== server) return;
105
- serve.routes = staticRoutes[0];
106
- app.server.reload(serve);
107
- });
108
- if (Object.keys(staticRoutes[0]).length) serve.routes = staticRoutes[0];
91
+ const needsGate = app.pending || !!onSetup?.length;
92
+ let ready;
93
+ const build = () => {
94
+ const fetch = app.fetch;
95
+ let routes;
96
+ try {
97
+ routes = collectStaticRoutes(app);
98
+ } catch (error) {
99
+ console.warn("[Elysia] Native static promotion was skipped:", error);
100
+ }
101
+ const hasWs = app["~hasWS"];
102
+ let websocket;
103
+ if (hasWs) {
104
+ const defaultConfig = require_generation.frozenRootOf(app)["~config"]?.websocket;
105
+ websocket = defaultConfig ? Object.assign(require_ws_route.buildGlobalWSHandler(), defaultConfig) : require_ws_route.buildGlobalWSHandler();
106
+ }
107
+ return {
108
+ fetch,
109
+ routes,
110
+ websocket
109
111
  };
110
- if (app.pending) {
111
- app.server.reload(serve);
112
- const reloadAfterModules = () => {
113
- if (app.server !== server) return;
114
- serve.fetch = app.fetch;
115
- if (hasWs || app["~hasWS"]) buildWebSocket();
116
- collectRoutes();
117
- app.server.reload(serve);
118
- };
119
- app.modules.then(reloadAfterModules, reloadAfterModules);
120
- } else {
121
- collectRoutes();
122
- app.server.reload(serve);
112
+ };
113
+ let built;
114
+ if (!needsGate) built = build();
115
+ if (needsGate) serve.fetch = (request, server) => ready.then(() => app.fetch(request, server));
116
+ else serve.fetch = built.fetch;
117
+ const server = app.server = Bun.serve(serve);
118
+ const reload = () => {
119
+ try {
120
+ server.reload(serve);
121
+ } catch (error) {
122
+ if (!serve.routes) throw error;
123
+ delete serve.routes;
124
+ console.warn("[Elysia] Native static promotion was skipped:", error);
125
+ try {
126
+ server.reload(serve);
127
+ } catch (fallbackError) {
128
+ console.error("[Elysia] Failed to reload Bun server:", fallbackError);
129
+ throw fallbackError;
130
+ }
123
131
  }
124
- require_memory.flushMemory();
125
- if (hasWs) callback?.(app.server);
126
- });
132
+ };
133
+ const setup = () => {
134
+ const onSetup = app["~ext"]?.setup;
135
+ if (!onSetup) return;
136
+ let pendingSetups;
137
+ for (let i = 0; i < onSetup.length; i++) {
138
+ const result = onSetup[i](app);
139
+ if (result && typeof result.then === "function") (pendingSetups ??= []).push(result);
140
+ }
141
+ if (pendingSetups) return Promise.all(pendingSetups);
142
+ };
143
+ const rollback = (error) => {
144
+ if (app.server !== server) return;
145
+ try {
146
+ server.stop(true);
147
+ } catch (stopError) {
148
+ console.error(stopError);
149
+ } finally {
150
+ app.server = void 0;
151
+ }
152
+ const cleanup = app["~ext"]?.cleanup;
153
+ if (cleanup) for (let i = cleanup.length - 1; i >= 0; i--) try {
154
+ const result = cleanup[i](app);
155
+ if (result && typeof result.then === "function") Promise.resolve(result).catch(console.error);
156
+ } catch (cleanupError) {
157
+ console.error(cleanupError);
158
+ }
159
+ return error;
160
+ };
161
+ const publish = () => {
162
+ if (app.server !== server) return;
163
+ built ??= build();
164
+ serve.fetch = built.fetch;
165
+ if (built.websocket) serve.websocket = built.websocket;
166
+ if (built.routes) serve.routes = built.routes[0];
167
+ if (needsGate || built.websocket || built.routes) reload();
168
+ if (callback) callback(server);
169
+ };
170
+ const start = () => {
171
+ if (app.server !== server) return;
172
+ const setupReady = setup();
173
+ if (setupReady && typeof setupReady.then === "function") return Promise.resolve(setupReady).then(publish);
174
+ publish();
175
+ };
176
+ try {
177
+ if (app.pending) ready = app.modules.then(start);
178
+ else {
179
+ const result = start();
180
+ if (result && typeof result.then === "function") ready = result;
181
+ else if (needsGate) ready = Promise.resolve();
182
+ }
183
+ ready?.catch(rollback);
184
+ } catch (error) {
185
+ rollback(error);
186
+ throw error;
187
+ }
127
188
  }
128
189
  });
129
190
 
@@ -2,34 +2,42 @@ import { createAdapter } from "../index.mjs";
2
2
  import { isDynamicRegex, needEncodeRegex } from "../../constants.mjs";
3
3
  import { flattenChain, getLoosePath, nullObject } from "../../utils.mjs";
4
4
  import { WebStandardAdapter } from "../web-standard/index.mjs";
5
+ import { frozenRootOf } from "../../generation.mjs";
5
6
  import { buildNativeStaticResponse } from "../../compile/handler/index.mjs";
6
- import { flushMemory } from "../../memory.mjs";
7
+ import { routeRow } from "../../route-table.mjs";
7
8
  import { buildGlobalWSHandler } from "../../ws/route.mjs";
8
9
 
9
10
  //#region src/adapter/bun/index.ts
11
+ const nativeStaticMethods = new Set([
12
+ "GET",
13
+ "POST",
14
+ "PUT",
15
+ "DELETE",
16
+ "PATCH",
17
+ "HEAD",
18
+ "OPTIONS"
19
+ ]);
10
20
  function collectStaticRoutes(app) {
11
21
  if (app["~config"]?.nativeStaticResponse === false) return;
12
22
  app.fetch;
13
- const fetchLevelHook = flattenChain(app["~hookChain"]);
14
- if (fetchLevelHook?.request?.length || fetchLevelHook?.trace?.length || app["~ext"]?.hoc?.length) return;
15
- const history = app.history;
16
- if (!history?.length) return;
23
+ const frozenRoot = frozenRootOf(app);
24
+ const fetchLevelHook = flattenChain(frozenRoot["~hookChain"]);
25
+ if (fetchLevelHook?.request?.length || fetchLevelHook?.trace?.length || frozenRoot["~ext"]?.hoc?.length) return;
26
+ const table = app["~generation"]?.routeTable ?? app["~routeTable"];
27
+ const length = table?.length ?? 0;
28
+ if (!table || !length) return;
29
+ const methods = table.method;
30
+ const paths = table.path;
17
31
  const ready = nullObject();
18
- const pending = [];
19
- const strictPath = app["~config"]?.strictPath === true;
32
+ const strictPath = frozenRoot["~config"]?.strictPath === true;
20
33
  const seen = /* @__PURE__ */ new Map();
21
- for (let i = 0; i < history.length; i++) {
22
- const route = history[i];
23
- const method = route[0];
24
- seen.set(method + " " + route[1], i);
25
- }
34
+ for (let i = 0; i < length; i++) seen.set(methods[i] + " " + paths[i], i);
26
35
  let explicitPaths;
27
36
  if (!strictPath) {
28
37
  explicitPaths = /* @__PURE__ */ new Map();
29
- for (let i = 0; i < history.length; i++) {
30
- const route = history[i];
31
- const method = route[0];
32
- const path = route[1];
38
+ for (let i = 0; i < length; i++) {
39
+ const method = methods[i];
40
+ const path = paths[i];
33
41
  let set = explicitPaths.get(method);
34
42
  if (!set) explicitPaths.set(method, set = /* @__PURE__ */ new Set());
35
43
  set.add(path);
@@ -41,20 +49,15 @@ function collectStaticRoutes(app) {
41
49
  }
42
50
  const add = (method, path, value) => {
43
51
  if (needEncodeRegex.test(path)) path = encodeURI(path);
44
- if (value instanceof Promise) pending.push(value.then((resolved) => {
45
- if (resolved instanceof Response) (ready[path] ??= nullObject())[method] = resolved;
46
- }, (err) => {
47
- console.error(`[Elysia] Static route ${method} ${path} failed to resolve:`, err);
48
- }));
49
- else (ready[path] ??= nullObject())[method] = value;
52
+ (ready[path] ??= nullObject())[method] = value;
50
53
  };
51
- for (let i = 0; i < history.length; i++) {
52
- const route = history[i];
53
- if (route[0] === "WS") continue;
54
- const method = route[0];
55
- const path = route[1];
54
+ for (let i = 0; i < length; i++) {
55
+ const method = methods[i];
56
+ if (method === "WS") continue;
57
+ const path = paths[i];
56
58
  if (seen.get(method + " " + path) !== i) continue;
57
- const value = buildNativeStaticResponse(route, app);
59
+ if (!nativeStaticMethods.has(method)) continue;
60
+ const value = buildNativeStaticResponse(routeRow(table, i), app);
58
61
  if (!value) continue;
59
62
  add(method, path, value);
60
63
  if (!strictPath && !isDynamicRegex.test(path)) {
@@ -62,8 +65,8 @@ function collectStaticRoutes(app) {
62
65
  if (loose !== path && !explicitPaths?.get(method)?.has(loose)) add(method, loose, value);
63
66
  }
64
67
  }
65
- if (!Object.keys(ready).length && !pending.length) return;
66
- return [ready, pending];
68
+ if (!Object.keys(ready).length) return;
69
+ return [ready, []];
67
70
  }
68
71
  const BunAdapter = createAdapter({
69
72
  name: "bun",
@@ -83,46 +86,104 @@ const BunAdapter = createAdapter({
83
86
  ..._config,
84
87
  ..._options
85
88
  } : _options;
86
- const server = app.server = Bun.serve(serve);
87
89
  const onSetup = app["~ext"]?.setup;
88
- if (onSetup) for (let i = 0; i < onSetup.length; i++) onSetup[i](app);
89
- const hasWs = app["~hasWS"];
90
- if (!hasWs) callback?.(app.server);
91
- queueMicrotask(() => {
92
- if (app.server !== server) return;
93
- if (!app.pending) serve.fetch = app.fetch;
94
- const buildWebSocket = () => {
95
- const defaultConfig = app["~config"]?.websocket;
96
- serve.websocket = defaultConfig ? Object.assign(buildGlobalWSHandler(), defaultConfig) : buildGlobalWSHandler();
97
- };
98
- if (hasWs) buildWebSocket();
99
- const collectRoutes = () => {
100
- const staticRoutes = collectStaticRoutes(app);
101
- if (!staticRoutes) return;
102
- if (staticRoutes[1].length) return Promise.all(staticRoutes[1]).then(() => {
103
- if (app.server !== server) return;
104
- serve.routes = staticRoutes[0];
105
- app.server.reload(serve);
106
- });
107
- if (Object.keys(staticRoutes[0]).length) serve.routes = staticRoutes[0];
90
+ const needsGate = app.pending || !!onSetup?.length;
91
+ let ready;
92
+ const build = () => {
93
+ const fetch = app.fetch;
94
+ let routes;
95
+ try {
96
+ routes = collectStaticRoutes(app);
97
+ } catch (error) {
98
+ console.warn("[Elysia] Native static promotion was skipped:", error);
99
+ }
100
+ const hasWs = app["~hasWS"];
101
+ let websocket;
102
+ if (hasWs) {
103
+ const defaultConfig = frozenRootOf(app)["~config"]?.websocket;
104
+ websocket = defaultConfig ? Object.assign(buildGlobalWSHandler(), defaultConfig) : buildGlobalWSHandler();
105
+ }
106
+ return {
107
+ fetch,
108
+ routes,
109
+ websocket
108
110
  };
109
- if (app.pending) {
110
- app.server.reload(serve);
111
- const reloadAfterModules = () => {
112
- if (app.server !== server) return;
113
- serve.fetch = app.fetch;
114
- if (hasWs || app["~hasWS"]) buildWebSocket();
115
- collectRoutes();
116
- app.server.reload(serve);
117
- };
118
- app.modules.then(reloadAfterModules, reloadAfterModules);
119
- } else {
120
- collectRoutes();
121
- app.server.reload(serve);
111
+ };
112
+ let built;
113
+ if (!needsGate) built = build();
114
+ if (needsGate) serve.fetch = (request, server) => ready.then(() => app.fetch(request, server));
115
+ else serve.fetch = built.fetch;
116
+ const server = app.server = Bun.serve(serve);
117
+ const reload = () => {
118
+ try {
119
+ server.reload(serve);
120
+ } catch (error) {
121
+ if (!serve.routes) throw error;
122
+ delete serve.routes;
123
+ console.warn("[Elysia] Native static promotion was skipped:", error);
124
+ try {
125
+ server.reload(serve);
126
+ } catch (fallbackError) {
127
+ console.error("[Elysia] Failed to reload Bun server:", fallbackError);
128
+ throw fallbackError;
129
+ }
122
130
  }
123
- flushMemory();
124
- if (hasWs) callback?.(app.server);
125
- });
131
+ };
132
+ const setup = () => {
133
+ const onSetup = app["~ext"]?.setup;
134
+ if (!onSetup) return;
135
+ let pendingSetups;
136
+ for (let i = 0; i < onSetup.length; i++) {
137
+ const result = onSetup[i](app);
138
+ if (result && typeof result.then === "function") (pendingSetups ??= []).push(result);
139
+ }
140
+ if (pendingSetups) return Promise.all(pendingSetups);
141
+ };
142
+ const rollback = (error) => {
143
+ if (app.server !== server) return;
144
+ try {
145
+ server.stop(true);
146
+ } catch (stopError) {
147
+ console.error(stopError);
148
+ } finally {
149
+ app.server = void 0;
150
+ }
151
+ const cleanup = app["~ext"]?.cleanup;
152
+ if (cleanup) for (let i = cleanup.length - 1; i >= 0; i--) try {
153
+ const result = cleanup[i](app);
154
+ if (result && typeof result.then === "function") Promise.resolve(result).catch(console.error);
155
+ } catch (cleanupError) {
156
+ console.error(cleanupError);
157
+ }
158
+ return error;
159
+ };
160
+ const publish = () => {
161
+ if (app.server !== server) return;
162
+ built ??= build();
163
+ serve.fetch = built.fetch;
164
+ if (built.websocket) serve.websocket = built.websocket;
165
+ if (built.routes) serve.routes = built.routes[0];
166
+ if (needsGate || built.websocket || built.routes) reload();
167
+ if (callback) callback(server);
168
+ };
169
+ const start = () => {
170
+ if (app.server !== server) return;
171
+ const setupReady = setup();
172
+ if (setupReady && typeof setupReady.then === "function") return Promise.resolve(setupReady).then(publish);
173
+ publish();
174
+ };
175
+ try {
176
+ if (app.pending) ready = app.modules.then(start);
177
+ else {
178
+ const result = start();
179
+ if (result && typeof result.then === "function") ready = result;
180
+ else if (needsGate) ready = Promise.resolve();
181
+ }
182
+ ready?.catch(rollback);
183
+ } catch (error) {
184
+ rollback(error);
185
+ throw error;
186
+ }
126
187
  }
127
188
  });
128
189
 
@@ -0,0 +1,4 @@
1
+ //#region src/adapter/default-headers.d.ts
2
+ declare const defaultHeaders = "\0";
3
+ //#endregion
4
+ export { defaultHeaders };
@@ -0,0 +1,7 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
+
3
+ //#region src/adapter/default-headers.ts
4
+ const defaultHeaders = "\0";
5
+
6
+ //#endregion
7
+ exports.defaultHeaders = defaultHeaders;
@@ -0,0 +1,5 @@
1
+ //#region src/adapter/default-headers.ts
2
+ const defaultHeaders = "\0";
3
+
4
+ //#endregion
5
+ export { defaultHeaders };
@@ -1,5 +1,5 @@
1
1
  import { ListenCallback, Serve } from "../universal/server.js";
2
- import { AnyLocalHook, MaybePromise } from "../types.js";
2
+ import { MaybePromise } from "../types.js";
3
3
  import { Context } from "../context.js";
4
4
  import { AnyElysia } from "../base.js";
5
5
 
@@ -30,58 +30,25 @@ interface ElysiaAdapterOptions {
30
30
  */
31
31
  websocket?: boolean;
32
32
  listen?(app: AnyElysia, options: string | number | Partial<Serve>, callback?: ListenCallback): void;
33
- /**
34
- * Stop server from serving
35
- *
36
- * ---
37
- * @example
38
- * ```typescript
39
- * app.stop()
40
- * ```
41
- *
42
- * @example
43
- * ```typescript
44
- * app.stop(true) // Abruptly any requests inflight
45
- * ```
46
- */
47
- stop?(app: AnyElysia, closeActiveConnections?: boolean): Promise<void>;
48
33
  parse: {
49
34
  json: (context: Context) => MaybePromise<Record<keyof any, undefined> | unknown[]>;
50
35
  text: (context: Context) => MaybePromise<string>;
51
36
  urlencoded: (context: Context) => MaybePromise<Record<string, string | string[]>>;
52
37
  arrayBuffer: (context: Context) => MaybePromise<ArrayBuffer>;
53
38
  formData: (context: Context) => MaybePromise<Record<string, unknown>>;
54
- default: (context: Context, contentType: string) => MaybePromise<any>;
39
+ default: (context: Context, contentType: string, normalized?: boolean) => MaybePromise<any>;
55
40
  };
56
41
  response: {
57
42
  /**
58
43
  * Map return response on every case
59
44
  */
60
- map(response: unknown, set: Context['set'], ...params: unknown[]): unknown;
45
+ map(response: unknown, set: Context['set'], ...params: unknown[]): unknown; /** Support immutable shared default headers. */
46
+ supportsDefaultHeaderSink?: true;
61
47
  /**
62
48
  * Map response without cookie, status or headers
63
49
  */
64
50
  compact?(response: unknown, ...params: unknown[]): unknown;
65
- /**
66
- * Compile inline to value
67
- *
68
- * @example
69
- * ```ts
70
- * Elysia().get('/', 'static')
71
- * ```
72
- */
73
- static?(handle: unknown, hooks: AnyLocalHook, setHeaders?: Context['set']['headers'], ...params: unknown[]): (() => unknown) | undefined;
74
- /**
75
- * If the runtime support cloning response
76
- *
77
- * eg. Bun.serve({ static })
78
- */
79
- nativeStatic?(handle: unknown, hooks: AnyLocalHook, set?: Context['set']): (() => MaybePromise<Response>) | undefined;
80
51
  };
81
- /**
82
- * override Elysia's default fetch function
83
- */
84
- fetch?(app: AnyElysia): (request: Request) => MaybePromise<Response>;
85
52
  }
86
53
  //#endregion
87
54
  export { ElysiaAdapterOptions };
@@ -1,9 +1,12 @@
1
- import { StatusMap } from "../constants.js";
2
1
  import { BaseCookie } from "../cookie/types.js";
2
+ import { StatusMap } from "../constants.js";
3
+ import { ElysiaFile } from "../universal/file.js";
3
4
  import { HTTPHeaders } from "../types.js";
4
5
  import { Context } from "../context.js";
5
6
  //#region src/adapter/utils.d.ts
6
- declare function handleFile(response: File | Blob, set?: Context['set'], request?: Request): Response;
7
+ declare function materializeSetHeaders(set: Context['set']): any;
8
+ declare function normalizeContentType(contentType: string): string;
9
+ declare function handleFile(response: File | Blob | ElysiaFile, set?: Context['set'], request?: Request, size?: number): Response;
7
10
  declare function parseSetCookies(headers: Headers, setCookie: string[]): Headers;
8
11
  declare function responseToSetHeaders(response: Response, set?: Context['set']): {
9
12
  headers: HTTPHeaders;
@@ -44,4 +47,4 @@ declare function createResponseHandler(handler: CreateHandlerParameter): (respon
44
47
  */
45
48
  declare function tee<T>(source: AsyncIterable<T>, branches?: number, cap?: number, capBytes?: number): AsyncIterableIterator<T>[];
46
49
  //#endregion
47
- export { createResponseHandler, createStreamHandler, handleFile, handleSet, parseSetCookies, responseToSetHeaders, streamResponse, tee };
50
+ export { createResponseHandler, createStreamHandler, handleFile, handleSet, materializeSetHeaders, normalizeContentType, parseSetCookies, responseToSetHeaders, streamResponse, tee };