elysia 2.0.0-beta.2 → 2.0.0-beta.20

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 (337) hide show
  1. package/dist/adapter/bun/index.d.ts +18 -2
  2. package/dist/adapter/bun/index.js +467 -110
  3. package/dist/adapter/bun/index.mjs +467 -112
  4. package/dist/adapter/types.d.ts +2 -21
  5. package/dist/adapter/utils.d.ts +14 -3
  6. package/dist/adapter/utils.js +146 -87
  7. package/dist/adapter/utils.mjs +148 -90
  8. package/dist/adapter/web-standard/handler.d.ts +1 -1
  9. package/dist/adapter/web-standard/handler.js +47 -36
  10. package/dist/adapter/web-standard/handler.mjs +48 -37
  11. package/dist/adapter/web-standard/index.js +2 -30
  12. package/dist/adapter/web-standard/index.mjs +2 -30
  13. package/dist/adapter/web-standard/utils.js +5 -18
  14. package/dist/adapter/web-standard/utils.mjs +5 -18
  15. package/dist/base.d.ts +99 -67
  16. package/dist/base.js +678 -510
  17. package/dist/base.mjs +682 -514
  18. package/dist/compile/aot-capture.d.ts +2 -13
  19. package/dist/compile/aot-capture.js +26 -69
  20. package/dist/compile/aot-capture.mjs +28 -67
  21. package/dist/compile/aot-emit.d.ts +9 -7
  22. package/dist/compile/aot-emit.js +42 -19
  23. package/dist/compile/aot-emit.mjs +42 -20
  24. package/dist/compile/aot.d.ts +11 -13
  25. package/dist/compile/aot.js +34 -46
  26. package/dist/compile/aot.mjs +35 -45
  27. package/dist/compile/handler/descriptor.d.ts +9 -12
  28. package/dist/compile/handler/descriptor.js +17 -41
  29. package/dist/compile/handler/descriptor.mjs +18 -39
  30. package/dist/compile/handler/frozen-validator.d.ts +5 -10
  31. package/dist/compile/handler/frozen-validator.js +55 -105
  32. package/dist/compile/handler/frozen-validator.mjs +53 -105
  33. package/dist/compile/handler/index.d.ts +6 -5
  34. package/dist/compile/handler/index.js +148 -109
  35. package/dist/compile/handler/index.mjs +149 -111
  36. package/dist/compile/handler/jit.d.ts +17 -17
  37. package/dist/compile/handler/jit.js +220 -148
  38. package/dist/compile/handler/jit.mjs +222 -151
  39. package/dist/compile/handler/params.d.ts +1 -4
  40. package/dist/compile/handler/params.js +10 -5
  41. package/dist/compile/handler/params.mjs +14 -8
  42. package/dist/compile/handler/reconstruct.d.ts +2 -2
  43. package/dist/compile/handler/reconstruct.js +4 -3
  44. package/dist/compile/handler/reconstruct.mjs +4 -3
  45. package/dist/compile/handler/static-clone-resolver.d.ts +6 -0
  46. package/dist/compile/handler/static-clone-resolver.js +8 -0
  47. package/dist/compile/handler/static-clone-resolver.mjs +7 -0
  48. package/dist/compile/handler/utils.d.ts +22 -11
  49. package/dist/compile/handler/utils.js +159 -253
  50. package/dist/compile/handler/utils.mjs +155 -252
  51. package/dist/compile/jit-probe.d.ts +2 -2
  52. package/dist/compile/jit-probe.js +2 -3
  53. package/dist/compile/jit-probe.mjs +2 -3
  54. package/dist/compile/lexer.d.ts +7 -4
  55. package/dist/compile/lexer.js +268 -6
  56. package/dist/compile/lexer.mjs +268 -4
  57. package/dist/compile/utils.js +7 -4
  58. package/dist/compile/utils.mjs +7 -4
  59. package/dist/compiled.d.ts +0 -1
  60. package/dist/compiled.js +0 -1
  61. package/dist/compiled.mjs +0 -1
  62. package/dist/context.d.ts +14 -4
  63. package/dist/context.js +17 -32
  64. package/dist/context.mjs +19 -34
  65. package/dist/cookie/config.d.ts +1 -0
  66. package/dist/cookie/config.js +9 -9
  67. package/dist/cookie/config.mjs +9 -9
  68. package/dist/cookie/cookie.d.ts +1 -1
  69. package/dist/cookie/cookie.js +8 -10
  70. package/dist/cookie/cookie.mjs +8 -10
  71. package/dist/cookie/crypto.d.ts +8 -7
  72. package/dist/cookie/crypto.js +51 -40
  73. package/dist/cookie/crypto.mjs +51 -41
  74. package/dist/cookie/error.d.ts +1 -2
  75. package/dist/cookie/error.js +6 -4
  76. package/dist/cookie/error.mjs +6 -4
  77. package/dist/cookie/lib.js +7 -2
  78. package/dist/cookie/lib.mjs +7 -2
  79. package/dist/cookie/serialize.js +1 -1
  80. package/dist/cookie/serialize.mjs +1 -1
  81. package/dist/cookie/types.d.ts +10 -0
  82. package/dist/cookie/utils.d.ts +4 -8
  83. package/dist/cookie/utils.js +86 -52
  84. package/dist/cookie/utils.mjs +89 -54
  85. package/dist/error.d.ts +113 -103
  86. package/dist/error.js +181 -117
  87. package/dist/error.mjs +179 -118
  88. package/dist/generation.d.ts +2 -2
  89. package/dist/handler/error.d.ts +26 -15
  90. package/dist/handler/error.js +77 -96
  91. package/dist/handler/error.mjs +74 -97
  92. package/dist/handler/fetch.js +87 -108
  93. package/dist/handler/fetch.mjs +89 -110
  94. package/dist/handler/utils.d.ts +12 -6
  95. package/dist/handler/utils.js +84 -28
  96. package/dist/handler/utils.mjs +80 -28
  97. package/dist/index.d.ts +12 -12
  98. package/dist/index.js +2 -9
  99. package/dist/index.mjs +1 -1
  100. package/dist/memory.js +1 -1
  101. package/dist/memory.mjs +1 -1
  102. package/dist/package.js +1 -1
  103. package/dist/package.mjs +1 -1
  104. package/dist/plugin/aot/bun.d.ts +8 -1
  105. package/dist/plugin/aot/bun.js +16 -9
  106. package/dist/plugin/aot/bun.mjs +17 -10
  107. package/dist/plugin/aot/core.d.ts +47 -60
  108. package/dist/plugin/aot/core.js +172 -109
  109. package/dist/plugin/aot/core.mjs +169 -111
  110. package/dist/plugin/aot/esbuild.js +8 -5
  111. package/dist/plugin/aot/esbuild.mjs +9 -6
  112. package/dist/plugin/aot/hooks.d.ts +6 -17
  113. package/dist/plugin/aot/hooks.js +36 -14
  114. package/dist/plugin/aot/hooks.mjs +37 -16
  115. package/dist/plugin/aot/rspack-loader.d.ts +1 -5
  116. package/dist/plugin/aot/rspack-loader.js +1 -10
  117. package/dist/plugin/aot/rspack-loader.mjs +1 -10
  118. package/dist/plugin/aot/rspack.js +2 -5
  119. package/dist/plugin/aot/rspack.mjs +3 -6
  120. package/dist/plugin/aot/source.d.ts +6 -42
  121. package/dist/plugin/aot/source.js +47 -62
  122. package/dist/plugin/aot/source.mjs +48 -63
  123. package/dist/plugin/aot/treeshake.js +2 -6
  124. package/dist/plugin/aot/treeshake.mjs +2 -6
  125. package/dist/plugin/aot/unplugin.d.ts +1 -4
  126. package/dist/plugin/aot/unplugin.js +4 -13
  127. package/dist/plugin/aot/unplugin.mjs +4 -13
  128. package/dist/plugin/aot/vite.d.ts +2 -6
  129. package/dist/plugin/aot/worker.js +2 -2
  130. package/dist/plugin/aot/worker.mjs +2 -2
  131. package/dist/plugin/auto-head.js +1 -10
  132. package/dist/plugin/auto-head.mjs +1 -10
  133. package/dist/plugin/trace.d.ts +2 -1
  134. package/dist/route-table.d.ts +3 -0
  135. package/dist/route-table.js +16 -11
  136. package/dist/route-table.mjs +16 -11
  137. package/dist/schema-snapshot.d.ts +0 -4
  138. package/dist/schema-snapshot.js +29 -47
  139. package/dist/schema-snapshot.mjs +29 -47
  140. package/dist/sucrose.d.ts +6 -55
  141. package/dist/sucrose.js +103 -731
  142. package/dist/sucrose.mjs +102 -724
  143. package/dist/trace.d.ts +5 -8
  144. package/dist/trace.js +23 -134
  145. package/dist/trace.mjs +24 -135
  146. package/dist/type/bridge-live.d.ts +4 -2
  147. package/dist/type/bridge-live.js +6 -3
  148. package/dist/type/bridge-live.mjs +4 -2
  149. package/dist/type/bridge.d.ts +6 -4
  150. package/dist/type/bridge.js +17 -9
  151. package/dist/type/bridge.mjs +5 -3
  152. package/dist/type/coerce-plan.d.ts +5 -5
  153. package/dist/type/coerce-plan.js +41 -39
  154. package/dist/type/coerce-plan.mjs +43 -39
  155. package/dist/type/coerce.d.ts +2 -6
  156. package/dist/type/coerce.js +18 -75
  157. package/dist/type/coerce.mjs +19 -76
  158. package/dist/type/compat.d.ts +3 -0
  159. package/dist/type/compat.js +23 -14
  160. package/dist/type/compat.mjs +20 -10
  161. package/dist/type/constants.d.ts +1 -1
  162. package/dist/type/elysia/array-buffer.d.ts +4 -1
  163. package/dist/type/elysia/array-buffer.js +17 -17
  164. package/dist/type/elysia/array-buffer.mjs +17 -17
  165. package/dist/type/elysia/array-string.js +2 -40
  166. package/dist/type/elysia/array-string.mjs +2 -39
  167. package/dist/type/elysia/array.js +5 -9
  168. package/dist/type/elysia/array.mjs +5 -9
  169. package/dist/type/elysia/boolean-string.js +2 -3
  170. package/dist/type/elysia/boolean-string.mjs +1 -1
  171. package/dist/type/elysia/boolean.js +3 -12
  172. package/dist/type/elysia/boolean.mjs +3 -11
  173. package/dist/type/elysia/cookie.d.ts +3 -4
  174. package/dist/type/elysia/cookie.js +5 -15
  175. package/dist/type/elysia/cookie.mjs +5 -15
  176. package/dist/type/elysia/date.js +13 -20
  177. package/dist/type/elysia/date.mjs +10 -16
  178. package/dist/type/elysia/file-type.d.ts +11 -4
  179. package/dist/type/elysia/file-type.js +17 -2
  180. package/dist/type/elysia/file-type.mjs +17 -3
  181. package/dist/type/elysia/file.d.ts +1 -3
  182. package/dist/type/elysia/file.js +11 -27
  183. package/dist/type/elysia/file.mjs +11 -12
  184. package/dist/type/elysia/files.js +7 -11
  185. package/dist/type/elysia/files.mjs +7 -10
  186. package/dist/type/elysia/form.js +2 -3
  187. package/dist/type/elysia/form.mjs +3 -3
  188. package/dist/type/elysia/integer-string.d.ts +1 -1
  189. package/dist/type/elysia/integer-string.js +4 -30
  190. package/dist/type/elysia/integer-string.mjs +5 -30
  191. package/dist/type/elysia/integer.js +3 -12
  192. package/dist/type/elysia/integer.mjs +3 -11
  193. package/dist/type/elysia/intersect.js +0 -5
  194. package/dist/type/elysia/intersect.mjs +0 -5
  195. package/dist/type/elysia/json-string.d.ts +7 -0
  196. package/dist/type/elysia/json-string.js +47 -0
  197. package/dist/type/elysia/json-string.mjs +46 -0
  198. package/dist/type/elysia/maybe-empty.js +3 -4
  199. package/dist/type/elysia/maybe-empty.mjs +1 -1
  200. package/dist/type/elysia/nullable.js +2 -3
  201. package/dist/type/elysia/nullable.mjs +1 -1
  202. package/dist/type/elysia/number.d.ts +2 -1
  203. package/dist/type/elysia/number.js +19 -11
  204. package/dist/type/elysia/number.mjs +18 -10
  205. package/dist/type/elysia/numeric-enum.d.ts +1 -1
  206. package/dist/type/elysia/numeric-enum.js +4 -5
  207. package/dist/type/elysia/numeric-enum.mjs +3 -3
  208. package/dist/type/elysia/numeric.d.ts +4 -2
  209. package/dist/type/elysia/numeric.js +20 -17
  210. package/dist/type/elysia/numeric.mjs +19 -16
  211. package/dist/type/elysia/object-string.js +2 -37
  212. package/dist/type/elysia/object-string.mjs +2 -36
  213. package/dist/type/elysia/object.js +5 -9
  214. package/dist/type/elysia/object.mjs +5 -9
  215. package/dist/type/elysia/optional.js +8 -8
  216. package/dist/type/elysia/optional.mjs +7 -7
  217. package/dist/type/elysia/problem.d.ts +20 -0
  218. package/dist/type/elysia/problem.js +25 -0
  219. package/dist/type/elysia/problem.mjs +24 -0
  220. package/dist/type/elysia/string.js +4 -3
  221. package/dist/type/elysia/string.mjs +4 -2
  222. package/dist/type/elysia/uint8-array.d.ts +1 -1
  223. package/dist/type/elysia/uint8-array.js +5 -20
  224. package/dist/type/elysia/uint8-array.mjs +5 -19
  225. package/dist/type/elysia/union-enum.js +7 -8
  226. package/dist/type/elysia/union-enum.mjs +6 -6
  227. package/dist/type/elysia/union.js +0 -5
  228. package/dist/type/elysia/union.mjs +0 -5
  229. package/dist/type/elysia/utils.d.ts +2 -4
  230. package/dist/type/elysia/utils.js +10 -21
  231. package/dist/type/elysia/utils.mjs +7 -15
  232. package/dist/type/exports.d.ts +3 -2
  233. package/dist/type/exports.js +13 -2
  234. package/dist/type/exports.mjs +10 -2
  235. package/dist/type/index.d.ts +10 -2
  236. package/dist/type/index.js +52 -15
  237. package/dist/type/index.mjs +55 -11
  238. package/dist/type/shared.d.ts +3 -9
  239. package/dist/type/shared.js +44 -97
  240. package/dist/type/shared.mjs +43 -97
  241. package/dist/type/sync-require.d.ts +11 -0
  242. package/dist/type/sync-require.js +14 -0
  243. package/dist/type/sync-require.mjs +12 -0
  244. package/dist/type/typebox-system-lite.d.ts +2 -0
  245. package/dist/type/typebox-system-lite.js +34 -0
  246. package/dist/type/typebox-system-lite.mjs +3 -0
  247. package/dist/type/typebox-system-require.d.ts +7 -0
  248. package/dist/type/typebox-system-require.js +24 -0
  249. package/dist/type/typebox-system-require.mjs +23 -0
  250. package/dist/type/typebox-type-live.d.ts +11 -0
  251. package/dist/type/typebox-type-live.js +37 -0
  252. package/dist/type/typebox-type-live.mjs +20 -0
  253. package/dist/type/typebox-type.d.ts +26 -0
  254. package/dist/type/typebox-type.js +135 -0
  255. package/dist/type/typebox-type.mjs +70 -0
  256. package/dist/type/typebox-value-live.d.ts +11 -0
  257. package/dist/type/typebox-value-live.js +31 -0
  258. package/dist/type/typebox-value-live.mjs +13 -0
  259. package/dist/type/typebox-value-ops.d.ts +4 -0
  260. package/dist/type/typebox-value-ops.js +90 -0
  261. package/dist/type/typebox-value-ops.mjs +5 -0
  262. package/dist/type/typebox-value-require.d.ts +8 -0
  263. package/dist/type/typebox-value-require.js +28 -0
  264. package/dist/type/typebox-value-require.mjs +25 -0
  265. package/dist/type/typebox-value.d.ts +35 -0
  266. package/dist/type/typebox-value.js +161 -0
  267. package/dist/type/typebox-value.mjs +74 -0
  268. package/dist/type/utils.js +1 -10
  269. package/dist/type/utils.mjs +1 -10
  270. package/dist/type/validator/clean-safe.d.ts +2 -4
  271. package/dist/type/validator/clean-safe.js +15 -11
  272. package/dist/type/validator/clean-safe.mjs +16 -10
  273. package/dist/type/validator/custom-error.js +12 -16
  274. package/dist/type/validator/custom-error.mjs +11 -14
  275. package/dist/type/validator/default-precompute.d.ts +9 -1
  276. package/dist/type/validator/default-precompute.js +40 -77
  277. package/dist/type/validator/default-precompute.mjs +37 -74
  278. package/dist/type/validator/exact-mirror-live.d.ts +8 -0
  279. package/dist/type/validator/exact-mirror-live.js +22 -0
  280. package/dist/type/validator/exact-mirror-live.mjs +17 -0
  281. package/dist/type/validator/exact-mirror-require.d.ts +4 -0
  282. package/dist/type/validator/exact-mirror-require.js +11 -0
  283. package/dist/type/validator/exact-mirror-require.mjs +9 -0
  284. package/dist/type/validator/exact-mirror.js +8 -8
  285. package/dist/type/validator/exact-mirror.mjs +9 -8
  286. package/dist/type/validator/frozen-check.js +5 -6
  287. package/dist/type/validator/frozen-check.mjs +6 -7
  288. package/dist/type/validator/index.d.ts +1 -0
  289. package/dist/type/validator/index.js +169 -166
  290. package/dist/type/validator/index.mjs +162 -158
  291. package/dist/type/validator/string-codec-aot.d.ts +2 -1
  292. package/dist/type/validator/string-codec-aot.js +8 -2
  293. package/dist/type/validator/string-codec-aot.mjs +7 -2
  294. package/dist/type/validator/validator-cache.d.ts +5 -4
  295. package/dist/type/validator/validator-cache.js +41 -24
  296. package/dist/type/validator/validator-cache.mjs +40 -22
  297. package/dist/types.d.ts +261 -94
  298. package/dist/universal/constants.d.ts +2 -1
  299. package/dist/universal/constants.js +3 -1
  300. package/dist/universal/constants.mjs +2 -1
  301. package/dist/universal/env.js +2 -3
  302. package/dist/universal/env.mjs +2 -3
  303. package/dist/universal/file.d.ts +6 -4
  304. package/dist/universal/file.js +11 -16
  305. package/dist/universal/file.mjs +12 -16
  306. package/dist/universal/index.d.ts +2 -2
  307. package/dist/universal/is-production.d.ts +1 -2
  308. package/dist/universal/is-production.js +1 -3
  309. package/dist/universal/is-production.mjs +2 -3
  310. package/dist/universal/server.d.ts +0 -272
  311. package/dist/utils.d.ts +41 -7
  312. package/dist/utils.js +158 -126
  313. package/dist/utils.mjs +147 -126
  314. package/dist/validator/index.d.ts +1 -1
  315. package/dist/validator/index.js +17 -30
  316. package/dist/validator/index.mjs +18 -31
  317. package/dist/validator/route.js +2 -1
  318. package/dist/validator/route.mjs +2 -1
  319. package/dist/ws/context.d.ts +8 -1
  320. package/dist/ws/context.js +68 -44
  321. package/dist/ws/context.mjs +67 -44
  322. package/dist/ws/parser.js +10 -20
  323. package/dist/ws/parser.mjs +10 -20
  324. package/dist/ws/route.d.ts +2 -2
  325. package/dist/ws/route.js +219 -139
  326. package/dist/ws/route.mjs +223 -143
  327. package/dist/ws/types.d.ts +2 -2
  328. package/package.json +23 -49
  329. package/dist/compile/analysis-cache.d.ts +0 -6
  330. package/dist/compile/analysis-cache.js +0 -12
  331. package/dist/compile/analysis-cache.mjs +0 -11
  332. package/dist/cookie/index.d.ts +0 -7
  333. package/dist/cookie/index.js +0 -13
  334. package/dist/cookie/index.mjs +0 -7
  335. package/dist/handler/index.d.ts +0 -2
  336. package/dist/handler/index.js +0 -5
  337. package/dist/handler/index.mjs +0 -3
@@ -6,7 +6,7 @@ const require_plugin_aot_treeshake = require('./treeshake.js');
6
6
  const toPosix = (path) => path.replace(/\\/g, "/");
7
7
  const VIRTUAL = "\0elysia/compiled";
8
8
  const VIRTUAL_TYPE = "\0elysia/type";
9
- const createAotPluginHooks = (entry, options) => {
9
+ const createAotPluginHooks = (entry, options, moduleCondition = require_plugin_aot_core.resolveEntryModuleKind(entry)) => {
10
10
  const entryPath = require_plugin_aot_core.resolveEntry(entry);
11
11
  const entryPosix = toPosix(entryPath);
12
12
  const entryRealPosix = toPosix(require_plugin_aot_core.realPath(entryPath));
@@ -22,14 +22,17 @@ const createAotPluginHooks = (entry, options) => {
22
22
  let virtualType;
23
23
  let stub = { ...require_plugin_aot_core.NO_STUB };
24
24
  let isElysiaModule = (_path) => false;
25
+ let packageRoot = "";
25
26
  return {
26
27
  async buildStart() {
27
- const generated = initial ? await require_plugin_aot_core.generateCompiledArtifacts(entry, options) : await require_plugin_aot_core.generateCompiledArtifactsIsolated(entry, options);
28
+ const generated = initial ? await require_plugin_aot_core.generateCompiledArtifacts(entry, options, moduleCondition) : await require_plugin_aot_core.generateCompiledArtifactsIsolated(entry, options, moduleCondition);
28
29
  initial = false;
29
30
  source = generated.source;
30
31
  stub = generated.stub;
31
32
  virtualType = generated.virtualType;
32
- isElysiaModule = require_plugin_aot_core.makeIsElysiaModule(require_plugin_aot_core.resolveElysiaRoot(entryPath));
33
+ const pkgRoot = require_plugin_aot_core.resolveElysiaRoot(entryPath);
34
+ isElysiaModule = require_plugin_aot_core.makeIsElysiaModule(pkgRoot);
35
+ packageRoot = toPosix(pkgRoot);
33
36
  },
34
37
  buildEnd() {
35
38
  if (!entryMatched) throw new Error(`[elysia-aot] entry "${entry}" never appeared in the Vite module graph. Compiled manifest was not injected. Check that the plugin entry matches a build input.`);
@@ -42,12 +45,17 @@ const createAotPluginHooks = (entry, options) => {
42
45
  if (id === VIRTUAL) return source;
43
46
  if (id === VIRTUAL_TYPE) return virtualType;
44
47
  },
45
- async transform(code, id) {
48
+ transform(code, id) {
46
49
  const cleanId = id.split("?", 1)[0];
47
50
  for (const key of Object.keys(require_plugin_aot_core.STUB_SOURCES)) {
48
51
  if (!stub[key]) continue;
52
+ if (key === "staticClone" && (!isElysiaModule(cleanId) || !/^(dist|src)\/compile\/handler\/static-clone-resolver\.(m?js|ts)$/.test(toPosix(cleanId).slice(packageRoot.length + 1)))) continue;
49
53
  for (const { filter, source: stubSource } of require_plugin_aot_core.STUB_SOURCES[key]) if (filter.test(cleanId)) return require_plugin_aot_core.alignStubExtensions(stubSource, cleanId);
50
54
  }
55
+ if (require_plugin_aot_core.TYPEBOX_REQUIRE_FILTER.test(cleanId)) return `export const requireTypebox = () => undefined\nexport const importTypebox = () => undefined\n`;
56
+ if (require_plugin_aot_core.EXACT_MIRROR_REQUIRE_FILTER.test(cleanId)) return `export const requireExactMirror = () => undefined\n`;
57
+ if (require_plugin_aot_core.TYPEBOX_TYPE_FILTER.test(cleanId)) return require_plugin_aot_core.alignStubExtensions(`export * from './typebox-type-live'\n`, cleanId);
58
+ if (require_plugin_aot_core.TYPEBOX_SYSTEM_LITE_FILTER.test(cleanId)) return `export * from 'typebox/system'\n`;
51
59
  if (stub.adapter !== false && require_plugin_aot_core.ADAPTER_CONSTANTS_FILTER.test(cleanId)) return require_plugin_aot_core.alignStubExtensions(require_plugin_aot_core.adapterConstantsSource(stub.adapter), cleanId);
52
60
  if (stub.adapter === "web-standard" && require_plugin_aot_core.ADAPTER_BUN_FILTER.test(cleanId)) return require_plugin_aot_core.alignStubExtensions(require_plugin_aot_core.bunAdapterStubSource, cleanId);
53
61
  if (stub.isProduction && require_plugin_aot_core.IS_PRODUCTION_FILTER.test(cleanId)) return require_plugin_aot_core.alignStubExtensions(`export const isProduction = () => true\n`, cleanId);
@@ -56,17 +64,30 @@ const createAotPluginHooks = (entry, options) => {
56
64
  if (stub.isProduction && isElysiaModule(cleanId)) out = require_plugin_aot_core.rewriteIsProductionCalls(out);
57
65
  if (isEntry(cleanId)) {
58
66
  entryMatched = true;
59
- out = `import 'elysia/compiled'\n${out}`;
67
+ out = (moduleCondition === "cjs" ? `require('elysia/compiled')\n` : `import 'elysia/compiled'\n`) + out;
60
68
  }
61
69
  return out === code ? void 0 : out;
62
70
  },
63
71
  isTransformCandidate(id) {
64
72
  const cleanId = id.split("?", 1)[0];
65
- if (isEntry(cleanId)) return true;
66
- if (require_plugin_aot_core.ELYSIA_MODULE_FILTER.test(cleanId) || require_plugin_aot_core.ADAPTER_CONSTANTS_FILTER.test(cleanId) || require_plugin_aot_core.ADAPTER_BUN_FILTER.test(cleanId) || require_plugin_aot_core.IS_PRODUCTION_FILTER.test(cleanId)) return true;
67
- for (const key of Object.keys(require_plugin_aot_core.STUB_SOURCES)) for (const { filter } of require_plugin_aot_core.STUB_SOURCES[key]) if (filter.test(cleanId)) return true;
68
- if (require_plugin_aot_core.SOURCE_REGEX.test(cleanId) && !cleanId.includes("node_modules")) return true;
69
- return false;
73
+ return isEntry(cleanId) || require_plugin_aot_core.ELYSIA_MODULE_FILTER.test(cleanId) || require_plugin_aot_core.SOURCE_REGEX.test(cleanId) && !cleanId.includes("node_modules");
74
+ }
75
+ };
76
+ };
77
+ const createTypeboxWiringHooks = () => {
78
+ return {
79
+ async buildStart() {},
80
+ buildEnd() {},
81
+ resolveId() {},
82
+ load() {},
83
+ transform(_code, id) {
84
+ const cleanId = id.split("?", 1)[0];
85
+ if (cleanId.endsWith(".js")) return void 0;
86
+ if (require_plugin_aot_core.TYPEBOX_TYPE_FILTER.test(cleanId)) return require_plugin_aot_core.alignStubExtensions(`export * from './typebox-type-live'\n`, cleanId);
87
+ for (const { filter, source } of require_plugin_aot_core.STUB_SOURCES.typeboxValue) if (filter.test(cleanId)) return require_plugin_aot_core.alignStubExtensions(source, cleanId);
88
+ },
89
+ isTransformCandidate(id) {
90
+ return require_plugin_aot_core.ELYSIA_MODULE_FILTER.test(id.split("?", 1)[0]);
70
91
  }
71
92
  };
72
93
  };
@@ -74,17 +95,17 @@ const resolveLoader = (path) => {
74
95
  const ext = path.slice(path.lastIndexOf("."));
75
96
  return ext === ".js" || ext === ".mjs" || ext === ".cjs" ? "js" : ext === ".jsx" ? "jsx" : ext === ".tsx" ? "tsx" : "ts";
76
97
  };
77
- async function setupAotOnLoad(build, hooks, { readText, resolveDir }) {
98
+ async function setupAotOnLoad(build, hooks, readText, resolveDir) {
78
99
  await hooks.buildStart();
79
100
  const virtualLoad = (id) => () => ({
80
101
  contents: hooks.load(id),
81
102
  loader: "js",
82
103
  ...resolveDir !== void 0 ? { resolveDir } : {}
83
104
  });
84
- build.onResolve({ filter: /^elysia\/compiled$/ }, () => ({
105
+ build.onResolve({ filter: /^elysia\/compiled$/ }, () => hooks.resolveId("elysia/compiled") !== void 0 ? {
85
106
  path: "manifest",
86
107
  namespace: "elysia-aot"
87
- }));
108
+ } : void 0);
88
109
  build.onLoad({
89
110
  filter: /.*/,
90
111
  namespace: "elysia-aot"
@@ -100,7 +121,7 @@ async function setupAotOnLoad(build, hooks, { readText, resolveDir }) {
100
121
  build.onLoad({ filter: require_plugin_aot_core.SOURCE_REGEX }, async (args) => {
101
122
  if (!hooks.isTransformCandidate(args.path)) return void 0;
102
123
  const original = await readText(args.path);
103
- const contents = await hooks.transform(original, args.path);
124
+ const contents = hooks.transform(original, args.path);
104
125
  if (contents === void 0) return void 0;
105
126
  return {
106
127
  contents,
@@ -111,4 +132,5 @@ async function setupAotOnLoad(build, hooks, { readText, resolveDir }) {
111
132
 
112
133
  //#endregion
113
134
  exports.createAotPluginHooks = createAotPluginHooks;
135
+ exports.createTypeboxWiringHooks = createTypeboxWiringHooks;
114
136
  exports.setupAotOnLoad = setupAotOnLoad;
@@ -1,11 +1,11 @@
1
- import { ADAPTER_BUN_FILTER, ADAPTER_CONSTANTS_FILTER, ELYSIA_MODULE_FILTER, IS_PRODUCTION_FILTER, NO_STUB, SOURCE_REGEX, STUB_SOURCES, adapterConstantsSource, alignStubExtensions, bunAdapterStubSource, generateCompiledArtifacts, generateCompiledArtifactsIsolated, makeIsElysiaModule, realPath, resolveElysiaRoot, resolveEntry, rewriteIsProductionCalls } from "./core.mjs";
1
+ import { ADAPTER_BUN_FILTER, ADAPTER_CONSTANTS_FILTER, ELYSIA_MODULE_FILTER, EXACT_MIRROR_REQUIRE_FILTER, IS_PRODUCTION_FILTER, NO_STUB, SOURCE_REGEX, STUB_SOURCES, TYPEBOX_REQUIRE_FILTER, TYPEBOX_SYSTEM_LITE_FILTER, TYPEBOX_TYPE_FILTER, adapterConstantsSource, alignStubExtensions, bunAdapterStubSource, generateCompiledArtifacts, generateCompiledArtifactsIsolated, makeIsElysiaModule, realPath, resolveElysiaRoot, resolveEntry, resolveEntryModuleKind, rewriteIsProductionCalls } from "./core.mjs";
2
2
  import { rewriteTypeImport } from "./treeshake.mjs";
3
3
 
4
4
  //#region src/plugin/aot/hooks.ts
5
5
  const toPosix = (path) => path.replace(/\\/g, "/");
6
6
  const VIRTUAL = "\0elysia/compiled";
7
7
  const VIRTUAL_TYPE = "\0elysia/type";
8
- const createAotPluginHooks = (entry, options) => {
8
+ const createAotPluginHooks = (entry, options, moduleCondition = resolveEntryModuleKind(entry)) => {
9
9
  const entryPath = resolveEntry(entry);
10
10
  const entryPosix = toPosix(entryPath);
11
11
  const entryRealPosix = toPosix(realPath(entryPath));
@@ -21,14 +21,17 @@ const createAotPluginHooks = (entry, options) => {
21
21
  let virtualType;
22
22
  let stub = { ...NO_STUB };
23
23
  let isElysiaModule = (_path) => false;
24
+ let packageRoot = "";
24
25
  return {
25
26
  async buildStart() {
26
- const generated = initial ? await generateCompiledArtifacts(entry, options) : await generateCompiledArtifactsIsolated(entry, options);
27
+ const generated = initial ? await generateCompiledArtifacts(entry, options, moduleCondition) : await generateCompiledArtifactsIsolated(entry, options, moduleCondition);
27
28
  initial = false;
28
29
  source = generated.source;
29
30
  stub = generated.stub;
30
31
  virtualType = generated.virtualType;
31
- isElysiaModule = makeIsElysiaModule(resolveElysiaRoot(entryPath));
32
+ const pkgRoot = resolveElysiaRoot(entryPath);
33
+ isElysiaModule = makeIsElysiaModule(pkgRoot);
34
+ packageRoot = toPosix(pkgRoot);
32
35
  },
33
36
  buildEnd() {
34
37
  if (!entryMatched) throw new Error(`[elysia-aot] entry "${entry}" never appeared in the Vite module graph. Compiled manifest was not injected. Check that the plugin entry matches a build input.`);
@@ -41,12 +44,17 @@ const createAotPluginHooks = (entry, options) => {
41
44
  if (id === VIRTUAL) return source;
42
45
  if (id === VIRTUAL_TYPE) return virtualType;
43
46
  },
44
- async transform(code, id) {
47
+ transform(code, id) {
45
48
  const cleanId = id.split("?", 1)[0];
46
49
  for (const key of Object.keys(STUB_SOURCES)) {
47
50
  if (!stub[key]) continue;
51
+ if (key === "staticClone" && (!isElysiaModule(cleanId) || !/^(dist|src)\/compile\/handler\/static-clone-resolver\.(m?js|ts)$/.test(toPosix(cleanId).slice(packageRoot.length + 1)))) continue;
48
52
  for (const { filter, source: stubSource } of STUB_SOURCES[key]) if (filter.test(cleanId)) return alignStubExtensions(stubSource, cleanId);
49
53
  }
54
+ if (TYPEBOX_REQUIRE_FILTER.test(cleanId)) return `export const requireTypebox = () => undefined\nexport const importTypebox = () => undefined\n`;
55
+ if (EXACT_MIRROR_REQUIRE_FILTER.test(cleanId)) return `export const requireExactMirror = () => undefined\n`;
56
+ if (TYPEBOX_TYPE_FILTER.test(cleanId)) return alignStubExtensions(`export * from './typebox-type-live'\n`, cleanId);
57
+ if (TYPEBOX_SYSTEM_LITE_FILTER.test(cleanId)) return `export * from 'typebox/system'\n`;
50
58
  if (stub.adapter !== false && ADAPTER_CONSTANTS_FILTER.test(cleanId)) return alignStubExtensions(adapterConstantsSource(stub.adapter), cleanId);
51
59
  if (stub.adapter === "web-standard" && ADAPTER_BUN_FILTER.test(cleanId)) return alignStubExtensions(bunAdapterStubSource, cleanId);
52
60
  if (stub.isProduction && IS_PRODUCTION_FILTER.test(cleanId)) return alignStubExtensions(`export const isProduction = () => true\n`, cleanId);
@@ -55,17 +63,30 @@ const createAotPluginHooks = (entry, options) => {
55
63
  if (stub.isProduction && isElysiaModule(cleanId)) out = rewriteIsProductionCalls(out);
56
64
  if (isEntry(cleanId)) {
57
65
  entryMatched = true;
58
- out = `import 'elysia/compiled'\n${out}`;
66
+ out = (moduleCondition === "cjs" ? `require('elysia/compiled')\n` : `import 'elysia/compiled'\n`) + out;
59
67
  }
60
68
  return out === code ? void 0 : out;
61
69
  },
62
70
  isTransformCandidate(id) {
63
71
  const cleanId = id.split("?", 1)[0];
64
- if (isEntry(cleanId)) return true;
65
- if (ELYSIA_MODULE_FILTER.test(cleanId) || ADAPTER_CONSTANTS_FILTER.test(cleanId) || ADAPTER_BUN_FILTER.test(cleanId) || IS_PRODUCTION_FILTER.test(cleanId)) return true;
66
- for (const key of Object.keys(STUB_SOURCES)) for (const { filter } of STUB_SOURCES[key]) if (filter.test(cleanId)) return true;
67
- if (SOURCE_REGEX.test(cleanId) && !cleanId.includes("node_modules")) return true;
68
- return false;
72
+ return isEntry(cleanId) || ELYSIA_MODULE_FILTER.test(cleanId) || SOURCE_REGEX.test(cleanId) && !cleanId.includes("node_modules");
73
+ }
74
+ };
75
+ };
76
+ const createTypeboxWiringHooks = () => {
77
+ return {
78
+ async buildStart() {},
79
+ buildEnd() {},
80
+ resolveId() {},
81
+ load() {},
82
+ transform(_code, id) {
83
+ const cleanId = id.split("?", 1)[0];
84
+ if (cleanId.endsWith(".js")) return void 0;
85
+ if (TYPEBOX_TYPE_FILTER.test(cleanId)) return alignStubExtensions(`export * from './typebox-type-live'\n`, cleanId);
86
+ for (const { filter, source } of STUB_SOURCES.typeboxValue) if (filter.test(cleanId)) return alignStubExtensions(source, cleanId);
87
+ },
88
+ isTransformCandidate(id) {
89
+ return ELYSIA_MODULE_FILTER.test(id.split("?", 1)[0]);
69
90
  }
70
91
  };
71
92
  };
@@ -73,17 +94,17 @@ const resolveLoader = (path) => {
73
94
  const ext = path.slice(path.lastIndexOf("."));
74
95
  return ext === ".js" || ext === ".mjs" || ext === ".cjs" ? "js" : ext === ".jsx" ? "jsx" : ext === ".tsx" ? "tsx" : "ts";
75
96
  };
76
- async function setupAotOnLoad(build, hooks, { readText, resolveDir }) {
97
+ async function setupAotOnLoad(build, hooks, readText, resolveDir) {
77
98
  await hooks.buildStart();
78
99
  const virtualLoad = (id) => () => ({
79
100
  contents: hooks.load(id),
80
101
  loader: "js",
81
102
  ...resolveDir !== void 0 ? { resolveDir } : {}
82
103
  });
83
- build.onResolve({ filter: /^elysia\/compiled$/ }, () => ({
104
+ build.onResolve({ filter: /^elysia\/compiled$/ }, () => hooks.resolveId("elysia/compiled") !== void 0 ? {
84
105
  path: "manifest",
85
106
  namespace: "elysia-aot"
86
- }));
107
+ } : void 0);
87
108
  build.onLoad({
88
109
  filter: /.*/,
89
110
  namespace: "elysia-aot"
@@ -99,7 +120,7 @@ async function setupAotOnLoad(build, hooks, { readText, resolveDir }) {
99
120
  build.onLoad({ filter: SOURCE_REGEX }, async (args) => {
100
121
  if (!hooks.isTransformCandidate(args.path)) return void 0;
101
122
  const original = await readText(args.path);
102
- const contents = await hooks.transform(original, args.path);
123
+ const contents = hooks.transform(original, args.path);
103
124
  if (contents === void 0) return void 0;
104
125
  return {
105
126
  contents,
@@ -109,4 +130,4 @@ async function setupAotOnLoad(build, hooks, { readText, resolveDir }) {
109
130
  }
110
131
 
111
132
  //#endregion
112
- export { createAotPluginHooks, setupAotOnLoad };
133
+ export { createAotPluginHooks, createTypeboxWiringHooks, setupAotOnLoad };
@@ -8,16 +8,12 @@ interface AotLoaderContext {
8
8
  getOptions(): {
9
9
  token?: string;
10
10
  } | undefined;
11
- async(): (err: Error | null | undefined, content?: string, sourceMap?: unknown) => void;
12
11
  }
13
12
  /**
14
13
  * webpack/rspack-style JS loader. Delegates to `hooks.transform`, which returns
15
14
  * `undefined` for any module it doesn't rewrite so the loader passes the source through unchanged.
16
15
  * `enforce: 'pre'` runs this before the swc/babel loaders, mirroring unplugin's `enforce: 'pre'`.
17
- *
18
- * Uses `this.async()` because `hooks.transform` can be async (isolated
19
- * regeneration in watch flows).
20
16
  */
21
- declare function elysiaAotLoader(this: AotLoaderContext, source: string): void;
17
+ declare function elysiaAotLoader(this: AotLoaderContext, source: string): string;
22
18
  //#endregion
23
19
  export { elysiaAotLoader as default, registerAotHooks, unregisterAotHooks };
@@ -23,19 +23,10 @@ function unregisterAotHooks(token) {
23
23
  * webpack/rspack-style JS loader. Delegates to `hooks.transform`, which returns
24
24
  * `undefined` for any module it doesn't rewrite so the loader passes the source through unchanged.
25
25
  * `enforce: 'pre'` runs this before the swc/babel loaders, mirroring unplugin's `enforce: 'pre'`.
26
- *
27
- * Uses `this.async()` because `hooks.transform` can be async (isolated
28
- * regeneration in watch flows).
29
26
  */
30
27
  function elysiaAotLoader(source) {
31
- const callback = this.async();
32
28
  const token = this.getOptions()?.token;
33
- const hooks = token ? registry.get(token) : void 0;
34
- if (!hooks) {
35
- callback(null, source);
36
- return;
37
- }
38
- Promise.resolve(hooks.transform(source, this.resourcePath)).then((out) => callback(null, out === void 0 ? source : out), (error) => callback(error));
29
+ return (token ? registry.get(token) : void 0)?.transform(source, this.resourcePath) ?? source;
39
30
  }
40
31
 
41
32
  //#endregion
@@ -21,19 +21,10 @@ function unregisterAotHooks(token) {
21
21
  * webpack/rspack-style JS loader. Delegates to `hooks.transform`, which returns
22
22
  * `undefined` for any module it doesn't rewrite so the loader passes the source through unchanged.
23
23
  * `enforce: 'pre'` runs this before the swc/babel loaders, mirroring unplugin's `enforce: 'pre'`.
24
- *
25
- * Uses `this.async()` because `hooks.transform` can be async (isolated
26
- * regeneration in watch flows).
27
24
  */
28
25
  function elysiaAotLoader(source) {
29
- const callback = this.async();
30
26
  const token = this.getOptions()?.token;
31
- const hooks = token ? registry.get(token) : void 0;
32
- if (!hooks) {
33
- callback(null, source);
34
- return;
35
- }
36
- Promise.resolve(hooks.transform(source, this.resourcePath)).then((out) => callback(null, out === void 0 ? source : out), (error) => callback(error));
27
+ return (token ? registry.get(token) : void 0)?.transform(source, this.resourcePath) ?? source;
37
28
  }
38
29
 
39
30
  //#endregion
@@ -11,10 +11,7 @@ let node_crypto = require("node:crypto");
11
11
  //#region src/plugin/aot/rspack.ts
12
12
  const PLUGIN = "elysia-aot";
13
13
  let tokenCounter = 0;
14
- function loaderPath() {
15
- const moduleUrl = require("url").pathToFileURL(__filename).href;
16
- return (0, node_path.resolve)((0, node_path.dirname)((0, node_url.fileURLToPath)(moduleUrl)), "rspack-loader" + require_plugin_aot_core.siblingModuleExt(moduleUrl));
17
- }
14
+ const loaderPath = () => (0, node_url.fileURLToPath)(new URL("./rspack-loader" + require_plugin_aot_core.siblingModuleExt(require("url").pathToFileURL(__filename).href), require("url").pathToFileURL(__filename).href));
18
15
  /**
19
16
  * Elysia AOT build plugin
20
17
  *
@@ -39,7 +36,7 @@ const aot = (entry, options) => {
39
36
  const apply = (rawCompiler) => {
40
37
  const compiler = rawCompiler;
41
38
  compiler.options.module.rules.push({
42
- test: (id) => hooks.isTransformCandidate(id.split("?", 1)[0]),
39
+ test: hooks.isTransformCandidate,
43
40
  enforce: "pre",
44
41
  use: [{
45
42
  loader: loaderPath(),
@@ -2,17 +2,14 @@ import { resolveEntry, siblingModuleExt } from "./core.mjs";
2
2
  import { createAotPluginHooks } from "./hooks.mjs";
3
3
  import { registerAotHooks, unregisterAotHooks } from "./rspack-loader.mjs";
4
4
  import { mkdirSync, writeFileSync } from "node:fs";
5
- import { dirname, join, resolve } from "node:path";
5
+ import { join } from "node:path";
6
6
  import { fileURLToPath } from "node:url";
7
7
  import { createHash } from "node:crypto";
8
8
 
9
9
  //#region src/plugin/aot/rspack.ts
10
10
  const PLUGIN = "elysia-aot";
11
11
  let tokenCounter = 0;
12
- function loaderPath() {
13
- const moduleUrl = import.meta.url;
14
- return resolve(dirname(fileURLToPath(moduleUrl)), "rspack-loader" + siblingModuleExt(moduleUrl));
15
- }
12
+ const loaderPath = () => fileURLToPath(new URL("./rspack-loader" + siblingModuleExt(import.meta.url), import.meta.url));
16
13
  /**
17
14
  * Elysia AOT build plugin
18
15
  *
@@ -37,7 +34,7 @@ const aot = (entry, options) => {
37
34
  const apply = (rawCompiler) => {
38
35
  const compiler = rawCompiler;
39
36
  compiler.options.module.rules.push({
40
- test: (id) => hooks.isTransformCandidate(id.split("?", 1)[0]),
37
+ test: hooks.isTransformCandidate,
41
38
  enforce: "pre",
42
39
  use: [{
43
40
  loader: loaderPath(),
@@ -1,50 +1,14 @@
1
1
  import { AotFingerprint, CapturedHandler, CapturedValidator } from "../../compile/aot.js";
2
2
  import { AnyElysia } from "../../base.js";
3
3
  import { JITProbeResult } from "../../compile/jit-probe.js";
4
+ import { ElysiaAotOptions } from "./core.js";
4
5
 
5
6
  //#region src/plugin/aot/source.d.ts
6
7
  type AotTarget = 'bun' | 'node' | 'workerd';
7
- interface CompileToSourceOptions {
8
- /** Emit a self-registering fingerprinted program (`Compiled.register(...)`). */
9
- register?: boolean;
10
- /**
11
- * Deploy target for build-time-baked codegen consts. Lets you build on one
12
- * runtime and deploy to another e.g. build under Bun with
13
- * `target: 'workerd'` so the manifest bakes `Object.fromEntries(...)` instead
14
- * of the Bun-only `Headers.toJSON()`. Removes the need to generate the
15
- * manifest under Node for a workerd deploy.
16
- *
17
- * @default the build runtime
18
- */
19
- target?: AotTarget;
20
- /**
21
- * Split the emitted validator manifest into lazily-materialized groups
22
- *
23
- * Validator entries are registered as grouped thunks: a group's
24
- * validators are constructed on the first request to any route in that
25
- * group, trading first-request latency in unbuilt groups for lower
26
- * startup cost. Handlers are always eager. Only validator construction
27
- * is deferred. Pass a number to set the group size explicitly.
28
- *
29
- * @default decided by Elysia based on route batch scale
30
- */
31
- lazy?: boolean | number;
32
- /**
33
- * Specifier the generated module imports `Compiled` from
34
- * Must resolve to the same `elysia` instance the app runs
35
- *
36
- * @default 'elysia'
37
- */
38
- registerFrom?: string;
39
- /**
40
- * Specifier the generated module imports the `Reconstruct` table from,
41
- * only emitted when the manifest carries validators. The table is pure,
42
- * so unlike `registerFrom` it may resolve to any elysia copy the
43
- * registration itself goes through `Compiled` (from `registerFrom`)
44
- *
45
- * @default 'elysia/reconstruct'
46
- */
47
- reconstructFrom?: string;
8
+ type AotModuleCondition = 'esm' | 'cjs';
9
+ interface CompileToSourceOptions extends Pick<ElysiaAotOptions, 'registerFrom' | 'reconstructFrom' | 'lazy' | 'target'> {
10
+ /** @internal Package condition used by the entry that owns this manifest. */
11
+ moduleCondition?: AotModuleCondition;
48
12
  }
49
13
  declare const autoGroupSize: (routes: number) => number;
50
14
  declare function compileToSource(app: AnyElysia, options?: CompileToSourceOptions): Promise<string>;
@@ -57,4 +21,4 @@ interface CapturedArtifacts {
57
21
  declare function captureArtifacts(app: AnyElysia, options?: CompileToSourceOptions): Promise<CapturedArtifacts>;
58
22
  declare function replayStubbability(app: AnyElysia, handlers: CapturedHandler[]): JITProbeResult;
59
23
  //#endregion
60
- export { AotTarget, CapturedArtifacts, CompileToSourceOptions, autoGroupSize, captureArtifacts, compileToSource, replayStubbability };
24
+ export { AotModuleCondition, AotTarget, CapturedArtifacts, CompileToSourceOptions, autoGroupSize, captureArtifacts, compileToSource, replayStubbability };
@@ -18,10 +18,8 @@ async function captureArtifacts(app, options) {
18
18
  const previousAotBuild = require_universal_env.env.ELYSIA_AOT_BUILD;
19
19
  require_universal_env.env.ELYSIA_AOT_BUILD = "1";
20
20
  try {
21
- if (!require_compile_aot.Capture.isCapturing()) throw new Error("[elysia-aot]: ELYSIA_AOT_BUILD=1 must be set to enable AOT capture mode");
22
21
  require_compile_aot_capture.beginValidatorCapture();
23
- const modules = app.modules;
24
- if (modules) await modules;
22
+ await app.modules;
25
23
  if (options?.target !== void 0) require_compile_handler_jit.setCaptureHeaderShorthand(options.target === "bun");
26
24
  app.compile();
27
25
  const captured = require_compile_aot_capture.endValidatorCapture();
@@ -56,23 +54,28 @@ function replayStubbability(app, handlers) {
56
54
  require_compile_aot.Compiled.clear();
57
55
  const fingerprint = require_compile_aot.createAotFingerprint();
58
56
  require_compile_aot.Compiled.register({
59
- bf: 1,
60
57
  fingerprint,
61
58
  handlers: materialiseHandlersForReplay(handlers)
62
59
  });
63
60
  require_compile_aot.Compiled.claim(app["~programId"], fingerprint);
64
61
  require_validator_index.Validator.clear();
65
- const history = app["~routes"] ?? [];
62
+ const history = app["~routes"];
66
63
  require_compile_jit_probe.JITProbe.begin();
64
+ const exact = /* @__PURE__ */ new Map();
65
+ for (const route of history) {
66
+ const method = route[0];
67
+ if (method === "WS") continue;
68
+ let paths = exact.get(method);
69
+ if (!paths) exact.set(method, paths = /* @__PURE__ */ new Set());
70
+ if (paths.has(route[1])) require_compile_jit_probe.JITProbe.record("handler:indexed-duplicate");
71
+ else paths.add(route[1]);
72
+ }
67
73
  for (const route of history) try {
68
74
  if (route[0] === "WS") continue;
69
75
  require_compile_handler_index.compileHandler(route, app);
70
76
  } catch {
71
- require_compile_jit_probe.JITProbe.end();
72
- return {
73
- jit: false,
74
- reasons: ["handler:new-function"]
75
- };
77
+ require_compile_jit_probe.JITProbe.record("handler:new-function");
78
+ return require_compile_jit_probe.JITProbe.end();
76
79
  }
77
80
  return require_compile_jit_probe.JITProbe.end();
78
81
  } finally {
@@ -95,45 +98,33 @@ const normalizeCheckIdentifiers = (src) => {
95
98
  };
96
99
  function createEntryEncoder() {
97
100
  const branchRef = /* @__PURE__ */ new Map();
98
- let branchDecls = "";
99
101
  const branchTable = (u) => "[" + u.map((branch) => "[" + branch.map((b) => {
100
102
  const src = normalizeCheckIdentifiers(require_compile_aot_emit.Source.checkFactory(b.identifier, b.code));
101
103
  let ref = branchRef.get(src);
102
104
  if (ref === void 0) {
103
105
  ref = `_b${branchRef.size}`;
104
106
  branchRef.set(src, ref);
105
- branchDecls += `const ${ref} = ${src}\n`;
107
+ enc.branchDecls += `const ${ref} = ${src}\n`;
106
108
  }
107
109
  return ref;
108
110
  }).join(", ") + "]").join(", ") + "]";
109
111
  const unionRef = /* @__PURE__ */ new Map();
110
- let unionDecls = "";
111
- let hasCoercePlan = false;
112
- const unionTable = (u) => {
113
- const str = branchTable(u);
114
- let ref = unionRef.get(str);
115
- if (ref === void 0) {
116
- ref = `_u${unionRef.size}`;
117
- unionRef.set(str, ref);
118
- unionDecls += `const ${ref} = ${str}\n`;
119
- }
120
- return ref;
121
- };
122
- return {
123
- unionTable,
124
- setCoercePlan() {
125
- hasCoercePlan = true;
126
- },
127
- get branchDecls() {
128
- return branchDecls;
129
- },
130
- get unionDecls() {
131
- return unionDecls;
132
- },
133
- get hasCoercePlan() {
134
- return hasCoercePlan;
112
+ const enc = {
113
+ branchDecls: "",
114
+ unionDecls: "",
115
+ hasCoercePlan: false,
116
+ unionTable(u) {
117
+ const str = branchTable(u);
118
+ let ref = unionRef.get(str);
119
+ if (ref === void 0) {
120
+ ref = `_u${unionRef.size}`;
121
+ unionRef.set(str, ref);
122
+ enc.unionDecls += `const ${ref} = ${str}\n`;
123
+ }
124
+ return ref;
135
125
  }
136
126
  };
127
+ return enc;
137
128
  }
138
129
  function entryParts(c, enc) {
139
130
  const parts = [];
@@ -193,14 +184,15 @@ function entryParts(c, enc) {
193
184
  parts.push(`ic: [${ic}]`);
194
185
  }
195
186
  if (c.coercePlan) {
196
- enc.setCoercePlan();
187
+ enc.hasCoercePlan = true;
197
188
  parts.push(`cp: ${JSON.stringify(c.coercePlan)}`);
198
189
  }
199
190
  return parts;
200
191
  }
201
192
  function emitModule(captured, handlers, fingerprint, options) {
202
193
  const enc = createEntryEncoder();
203
- const treeToSource = (tree, slotRef, sink) => {
194
+ const treeToSource = (tree) => {
195
+ const slotRef = /* @__PURE__ */ new Map();
204
196
  const methods = [];
205
197
  for (const method in tree) {
206
198
  const paths = [];
@@ -210,7 +202,7 @@ function emitModule(captured, handlers, fingerprint, options) {
210
202
  if (ref === void 0) {
211
203
  ref = `_s${slotRef.size}`;
212
204
  slotRef.set(slotObj, ref);
213
- sink(`const ${ref} = ${slotObj}\n`);
205
+ validatorDecls += `const ${ref} = ${slotObj}\n`;
214
206
  }
215
207
  paths.push(`${JSON.stringify(path)}:${ref}`);
216
208
  }
@@ -342,7 +334,6 @@ function emitModule(captured, handlers, fingerprint, options) {
342
334
  }
343
335
  validatorDecls += `const _groups = [${thunks.join(", ")}]\n`;
344
336
  validatorDecls += `const _groupOf = ${JSON.stringify(groupOf)}\n`;
345
- validatorExport = options?.register ? "" : "export const groups = _groups\nexport const groupOf = _groupOf\n";
346
337
  } else {
347
338
  const factoryRef = /* @__PURE__ */ new Map();
348
339
  const tree = require_utils.nullObject();
@@ -359,10 +350,7 @@ function emitModule(captured, handlers, fingerprint, options) {
359
350
  const byPath = tree[c.method] ??= require_utils.nullObject();
360
351
  (byPath[c.path] ??= require_utils.nullObject())[c.slot] = ref;
361
352
  }
362
- const treeStr = treeToSource(tree, /* @__PURE__ */ new Map(), (d) => {
363
- validatorDecls += d;
364
- });
365
- validatorExport = options?.register ? `const validators = ${treeStr}\n` : `export const validators = ${treeStr}\n`;
353
+ validatorExport = `const validators = ${treeToSource(tree)}\n`;
366
354
  }
367
355
  const aliasRef = /* @__PURE__ */ new Map();
368
356
  const handlerRef = /* @__PURE__ */ new Map();
@@ -385,33 +373,30 @@ function emitModule(captured, handlers, fingerprint, options) {
385
373
  }
386
374
  (handlerTree[h.method] ??= {})[h.path] = wref;
387
375
  }
388
- let handlerExport = options?.register ? "const handlers = {\n" : "export const handlers = {\n";
376
+ let handlerExport = "const handlers = {\n";
389
377
  for (const method in handlerTree) {
390
378
  handlerExport += `\t${JSON.stringify(method)}: {\n`;
391
379
  for (const path in handlerTree[method]) handlerExport += `\t\t${JSON.stringify(path)}: ${handlerTree[method][path]},\n`;
392
380
  handlerExport += " },\n";
393
381
  }
394
382
  handlerExport += "}\n";
395
- const fingerprintExport = options?.register ? `export const fingerprint = ${JSON.stringify(fingerprint)}\n` : "";
396
383
  let body = "// Generated by Elysia build plugin. Do not edit.\n";
397
- if (options?.register) body += `import { Compiled } from ${JSON.stringify(options.registerFrom ?? "elysia")}\n`;
398
- if (options?.register && enc.hasCoercePlan) body += `import { buildCoercedFromPlan } from ${JSON.stringify("elysia/coerce-plan")}\n`;
399
- if (options?.register && captured.length) body += `import { Reconstruct } from ${JSON.stringify(options.reconstructFrom ?? "elysia/reconstruct")}\n`;
384
+ const moduleCondition = options?.moduleCondition ?? "esm";
385
+ const importNamed = (name, specifier) => moduleCondition === "cjs" ? `const { ${name} } = require(${JSON.stringify(specifier)})\n` : `import { ${name} } from ${JSON.stringify(specifier)}\n`;
386
+ body += importNamed("Compiled", options?.registerFrom ?? "elysia");
387
+ if (enc.hasCoercePlan) body += importNamed("buildCoercedFromPlan", "elysia/coerce-plan");
388
+ if (captured.length) body += importNamed("Reconstruct", options?.reconstructFrom ?? "elysia/reconstruct");
400
389
  const generated = enc.branchDecls + enc.unionDecls + validatorDecls + handlerDecls;
401
390
  const needs = (symbol) => new RegExp(`\\b${symbol}\\b`).test(generated);
402
- if (needs("CheckContext")) body += "import { CheckContext } from 'typebox/schema'\n";
403
- if (needs("Guard")) body += "import { Guard } from 'typebox/guard'\n";
404
- if (needs("Format")) body += "import { Format } from 'typebox/format'\n";
405
- if (needs("Hashing")) body += "import { Hashing } from 'typebox/system'\n";
406
- if (options?.register) {
407
- body += "\n";
408
- if (captured.length) body += "Compiled.reconstruct = Reconstruct\n";
409
- body += fingerprintExport + "Compiled.register((() => {\n" + enc.branchDecls + (enc.branchDecls && "\n") + enc.unionDecls + (enc.unionDecls && "\n") + validatorDecls + handlerDecls + "\n" + validatorExport + "\n" + handlerExport + "\nreturn { bf: 1, fingerprint, " + (lazy ? "lazyGroups: _groups, lazyGroupOf: _groupOf, " : "validators, ") + `handlers${enc.hasCoercePlan ? ", planRebuilder: buildCoercedFromPlan" : ""} }\n})())
391
+ if (needs("CheckContext")) body += importNamed("CheckContext", "typebox/schema");
392
+ if (needs("Guard")) body += importNamed("Guard", "typebox/guard");
393
+ if (needs("Format")) body += importNamed("Format", "typebox/format");
394
+ if (needs("Hashing")) body += importNamed("Hashing", "typebox/system");
395
+ body += "\n";
396
+ if (captured.length) body += "Compiled.reconstruct = Reconstruct\n";
397
+ body += `export const fingerprint = ${JSON.stringify(fingerprint)}\nCompiled.register((() => {
398
+ ` + enc.branchDecls + (enc.branchDecls && "\n") + enc.unionDecls + (enc.unionDecls && "\n") + validatorDecls + handlerDecls + "\n" + validatorExport + "\n" + handlerExport + "\nreturn { fingerprint, " + (lazy ? "lazyGroups: _groups, lazyGroupOf: _groupOf, " : "validators, ") + `handlers${enc.hasCoercePlan ? ", planRebuilder: buildCoercedFromPlan" : ""} }\n})())
410
399
  `;
411
- } else {
412
- body += "\n" + enc.branchDecls + (enc.branchDecls && "\n") + enc.unionDecls + (enc.unionDecls && "\n") + validatorDecls + handlerDecls + "\n" + validatorExport + "\n" + handlerExport + "\n";
413
- if (!lazy) body += "\nexport default validators\n";
414
- }
415
400
  return body;
416
401
  }
417
402