elysia 2.0.0-beta.24 → 2.0.0-beta.26

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.
@@ -105,7 +105,10 @@ function isNativePath(path) {
105
105
  function collectHTMLBundleRoutes(app, handoff, routes) {
106
106
  let dynamic;
107
107
  let bundles;
108
- for (const route of app["~routes"]) {
108
+ const table = app["~generation"]?.routeTable;
109
+ if (table && !table.handler.some((h, i) => isNativeStaticMethod(table.method[i]) && require_utils.isHTMLBundle(h))) return routes;
110
+ const declared = table ? table.method.map((_, i) => require_route_table.routeRow(table, i)) : app["~routes"];
111
+ for (const route of declared) {
109
112
  const [method, path, handler] = route;
110
113
  if (!isNativeStaticMethod(method) || !require_utils.isHTMLBundle(handler)) continue;
111
114
  if (path.indexOf(":") !== -1 || path.indexOf("*") !== -1) {
@@ -122,7 +125,7 @@ function collectHTMLBundleRoutes(app, handoff, routes) {
122
125
  if (!dynamic) return routes;
123
126
  const strictPath = app["~config"]?.strictPath === true;
124
127
  const handoffs = [];
125
- for (const [method, path, handler] of app["~routes"]) {
128
+ for (const [method, path, handler] of declared) {
126
129
  if (require_utils.isHTMLBundle(handler)) continue;
127
130
  const targets = method === "*" ? dynamic : dynamic.has(method) ? [method] : void 0;
128
131
  if (!targets) continue;
@@ -105,7 +105,10 @@ function isNativePath(path) {
105
105
  function collectHTMLBundleRoutes(app, handoff, routes) {
106
106
  let dynamic;
107
107
  let bundles;
108
- for (const route of app["~routes"]) {
108
+ const table = app["~generation"]?.routeTable;
109
+ if (table && !table.handler.some((h, i) => isNativeStaticMethod(table.method[i]) && isHTMLBundle(h))) return routes;
110
+ const declared = table ? table.method.map((_, i) => routeRow(table, i)) : app["~routes"];
111
+ for (const route of declared) {
109
112
  const [method, path, handler] = route;
110
113
  if (!isNativeStaticMethod(method) || !isHTMLBundle(handler)) continue;
111
114
  if (path.indexOf(":") !== -1 || path.indexOf("*") !== -1) {
@@ -122,7 +125,7 @@ function collectHTMLBundleRoutes(app, handoff, routes) {
122
125
  if (!dynamic) return routes;
123
126
  const strictPath = app["~config"]?.strictPath === true;
124
127
  const handoffs = [];
125
- for (const [method, path, handler] of app["~routes"]) {
128
+ for (const [method, path, handler] of declared) {
126
129
  if (isHTMLBundle(handler)) continue;
127
130
  const targets = method === "*" ? dynamic : dynamic.has(method) ? [method] : void 0;
128
131
  if (!targets) continue;
package/dist/base.d.ts CHANGED
@@ -84,8 +84,11 @@ declare class Elysia<const in out BasePath extends string = '', const in out Sco
84
84
  '~router'?: Memoirist<CompiledHandler | number>;
85
85
  '~map'?: {
86
86
  [method: string]: {
87
- [path: string]: CompiledHandler;
87
+ [path: string]: CompiledHandler | number;
88
88
  } | undefined;
89
+ WS?: {
90
+ [path: string]: CompiledHandler;
91
+ };
89
92
  };
90
93
  '~routeTable'?: RouteTable;
91
94
  '~hasWS'?: boolean;
@@ -102,8 +105,9 @@ declare class Elysia<const in out BasePath extends string = '', const in out Sco
102
105
  constructor(config?: ElysiaConfig<BasePath, Scope>);
103
106
  /**
104
107
  * Every registered route with its merged hooks.
105
- * Development shares a frozen cache. Production rebuilds the list so its
106
- * metadata can be released after startup.
108
+ * Development shares a frozen cache.
109
+ * Production rebuilds the list on every read
110
+ * so its metadata can be released after startup.
107
111
  */
108
112
  get routes(): PublicRoute[];
109
113
  /**
package/dist/base.js CHANGED
@@ -224,8 +224,9 @@ var Elysia = class Elysia {
224
224
  }
225
225
  /**
226
226
  * Every registered route with its merged hooks.
227
- * Development shares a frozen cache. Production rebuilds the list so its
228
- * metadata can be released after startup.
227
+ * Development shares a frozen cache.
228
+ * Production rebuilds the list on every read
229
+ * so its metadata can be released after startup.
229
230
  */
230
231
  get routes() {
231
232
  const generation = this["~generation"];
@@ -1517,7 +1518,7 @@ var Elysia = class Elysia {
1517
1518
  const satisfied = (table.flags[i] & require_route_table.RouteFlag.JITSatisfied) !== 0;
1518
1519
  table.flags[i] &= ~(require_route_table.RouteFlag.JITCold | require_route_table.RouteFlag.JITSatisfied);
1519
1520
  const flags = table.flags[i];
1520
- if (satisfied || (flags & (require_route_table.RouteFlag.WS | require_route_table.RouteFlag.ExactDuplicate)) !== 0 || compiled?.[i] !== void 0) continue;
1521
+ if (satisfied || (flags & (require_route_table.RouteFlag.WS | require_route_table.RouteFlag.ExactDuplicate)) !== 0 || compiled?.[i] !== void 0 || require_utils.isHTMLBundle(table.handler[i])) continue;
1521
1522
  table.flags[i] |= require_route_table.RouteFlag.JITCold;
1522
1523
  cold++;
1523
1524
  }
@@ -1526,8 +1527,8 @@ var Elysia = class Elysia {
1526
1527
  }
1527
1528
  require_compile_handler_index.clearHandlerAnalysisCaches(this);
1528
1529
  require_utils.clearFlattenChainMemo(this);
1529
- if (!this["~ext"]?.macro && !this["~scopeChildren"]) this.declaredRoutes = void 0;
1530
1530
  }
1531
+ if (!this["~ext"]?.macro && !this["~scopeChildren"] && !require_compile_aot.Capture.isAotBuildEnv()) this.declaredRoutes = void 0;
1531
1532
  const ext = this["~ext"];
1532
1533
  if (ext?.setup) extCallbackIndexes.delete(ext.setup);
1533
1534
  if (ext?.cleanup) extCallbackIndexes.delete(ext.cleanup);
@@ -1623,32 +1624,32 @@ var Elysia = class Elysia {
1623
1624
  }
1624
1625
  continue;
1625
1626
  }
1627
+ const lazy = !precompile && !this.compiled?.[i];
1628
+ if (lazy) {
1629
+ this.compiled ??= new Array(length);
1630
+ this.jitTable = table;
1631
+ }
1626
1632
  const isDynamic = (routeFlags & require_route_table.RouteFlag.Dynamic) !== 0;
1627
1633
  const needsEncode = (routeFlags & require_route_table.RouteFlag.Encode) !== 0;
1628
1634
  const registerLoose = isLoose && canRegisterLoose(routePath, isDynamic);
1629
1635
  if (!isDynamic && !needsEncode && !registerLoose) {
1630
1636
  const map = methods[routeMethod] ??= require_utils.nullObject();
1631
- map[routePath] = this.handler(i, precompile, void 0, void 0, table);
1637
+ map[routePath] = lazy ? ~i : this.handler(i, precompile, void 0, void 0, table);
1632
1638
  continue;
1633
1639
  }
1634
1640
  const paths = expandPaths(routePath, needsEncode, registerLoose, registerLoose ? explicitPaths?.get(routeMethod) : void 0);
1635
1641
  if (isDynamic) {
1636
1642
  if (require_utils.isHTMLBundle(table.handler[i])) continue;
1637
1643
  const router = this["~router"] ??= new memoirist.default({ loosePath: isLoose });
1638
- let store;
1639
- if (precompile || this.compiled?.[i]) store = this.handler(i, precompile, void 0, void 0, table);
1640
- else {
1641
- this.compiled ??= new Array(length);
1642
- this.jitTable = table;
1643
- store = i;
1644
- }
1644
+ const store = lazy ? i : this.handler(i, precompile, void 0, void 0, table);
1645
1645
  for (let p = 0; p < paths.length; p++) router.add(routeMethod, paths[p], store);
1646
1646
  } else {
1647
1647
  const map = methods[routeMethod] ??= require_utils.nullObject();
1648
- const handler = this.handler(i, precompile, void 0, {
1648
+ if (lazy) (this.jitAliases ??= [])[i] = {
1649
1649
  method: routeMethod,
1650
1650
  paths
1651
- }, table);
1651
+ };
1652
+ const handler = lazy ? ~i : this.handler(i, precompile, void 0, void 0, table);
1652
1653
  for (let p = 0; p < paths.length; p++) map[paths[p]] = handler;
1653
1654
  }
1654
1655
  }
package/dist/base.mjs CHANGED
@@ -222,8 +222,9 @@ var Elysia = class Elysia {
222
222
  }
223
223
  /**
224
224
  * Every registered route with its merged hooks.
225
- * Development shares a frozen cache. Production rebuilds the list so its
226
- * metadata can be released after startup.
225
+ * Development shares a frozen cache.
226
+ * Production rebuilds the list on every read
227
+ * so its metadata can be released after startup.
227
228
  */
228
229
  get routes() {
229
230
  const generation = this["~generation"];
@@ -1515,7 +1516,7 @@ var Elysia = class Elysia {
1515
1516
  const satisfied = (table.flags[i] & RouteFlag.JITSatisfied) !== 0;
1516
1517
  table.flags[i] &= ~(RouteFlag.JITCold | RouteFlag.JITSatisfied);
1517
1518
  const flags = table.flags[i];
1518
- if (satisfied || (flags & (RouteFlag.WS | RouteFlag.ExactDuplicate)) !== 0 || compiled?.[i] !== void 0) continue;
1519
+ if (satisfied || (flags & (RouteFlag.WS | RouteFlag.ExactDuplicate)) !== 0 || compiled?.[i] !== void 0 || isHTMLBundle(table.handler[i])) continue;
1519
1520
  table.flags[i] |= RouteFlag.JITCold;
1520
1521
  cold++;
1521
1522
  }
@@ -1524,8 +1525,8 @@ var Elysia = class Elysia {
1524
1525
  }
1525
1526
  clearHandlerAnalysisCaches(this);
1526
1527
  clearFlattenChainMemo(this);
1527
- if (!this["~ext"]?.macro && !this["~scopeChildren"]) this.declaredRoutes = void 0;
1528
1528
  }
1529
+ if (!this["~ext"]?.macro && !this["~scopeChildren"] && !Capture.isAotBuildEnv()) this.declaredRoutes = void 0;
1529
1530
  const ext = this["~ext"];
1530
1531
  if (ext?.setup) extCallbackIndexes.delete(ext.setup);
1531
1532
  if (ext?.cleanup) extCallbackIndexes.delete(ext.cleanup);
@@ -1621,32 +1622,32 @@ var Elysia = class Elysia {
1621
1622
  }
1622
1623
  continue;
1623
1624
  }
1625
+ const lazy = !precompile && !this.compiled?.[i];
1626
+ if (lazy) {
1627
+ this.compiled ??= new Array(length);
1628
+ this.jitTable = table;
1629
+ }
1624
1630
  const isDynamic = (routeFlags & RouteFlag.Dynamic) !== 0;
1625
1631
  const needsEncode = (routeFlags & RouteFlag.Encode) !== 0;
1626
1632
  const registerLoose = isLoose && canRegisterLoose(routePath, isDynamic);
1627
1633
  if (!isDynamic && !needsEncode && !registerLoose) {
1628
1634
  const map = methods[routeMethod] ??= nullObject();
1629
- map[routePath] = this.handler(i, precompile, void 0, void 0, table);
1635
+ map[routePath] = lazy ? ~i : this.handler(i, precompile, void 0, void 0, table);
1630
1636
  continue;
1631
1637
  }
1632
1638
  const paths = expandPaths(routePath, needsEncode, registerLoose, registerLoose ? explicitPaths?.get(routeMethod) : void 0);
1633
1639
  if (isDynamic) {
1634
1640
  if (isHTMLBundle(table.handler[i])) continue;
1635
1641
  const router = this["~router"] ??= new Memoirist({ loosePath: isLoose });
1636
- let store;
1637
- if (precompile || this.compiled?.[i]) store = this.handler(i, precompile, void 0, void 0, table);
1638
- else {
1639
- this.compiled ??= new Array(length);
1640
- this.jitTable = table;
1641
- store = i;
1642
- }
1642
+ const store = lazy ? i : this.handler(i, precompile, void 0, void 0, table);
1643
1643
  for (let p = 0; p < paths.length; p++) router.add(routeMethod, paths[p], store);
1644
1644
  } else {
1645
1645
  const map = methods[routeMethod] ??= nullObject();
1646
- const handler = this.handler(i, precompile, void 0, {
1646
+ if (lazy) (this.jitAliases ??= [])[i] = {
1647
1647
  method: routeMethod,
1648
1648
  paths
1649
- }, table);
1649
+ };
1650
+ const handler = lazy ? ~i : this.handler(i, precompile, void 0, void 0, table);
1650
1651
  for (let p = 0; p < paths.length; p++) map[paths[p]] = handler;
1651
1652
  }
1652
1653
  }
@@ -13,8 +13,8 @@ const require_type_validator_frozen_check = require('../type/validator/frozen-ch
13
13
  const require_type_validator_custom_error = require('../type/validator/custom-error.js');
14
14
  const require_type_validator_exact_mirror = require('../type/validator/exact-mirror.js');
15
15
  const require_type_validator_string_codec_aot = require('../type/validator/string-codec-aot.js');
16
- let typebox_value = require("typebox/value");
17
16
  let typebox_schema = require("typebox/schema");
17
+ let typebox_value = require("typebox/value");
18
18
 
19
19
  //#region src/compile/aot-capture.ts
20
20
  function emptyContainers(node, depth) {
@@ -12,8 +12,8 @@ import { buildFrozenCheck } from "../type/validator/frozen-check.mjs";
12
12
  import { captureCustomErrors } from "../type/validator/custom-error.mjs";
13
13
  import { getExactMirror } from "../type/validator/exact-mirror.mjs";
14
14
  import { captureStringCodecEntries, compileWithBuild } from "../type/validator/string-codec-aot.mjs";
15
- import { Default } from "typebox/value";
16
15
  import { Build, Compile } from "typebox/schema";
16
+ import { Default } from "typebox/value";
17
17
 
18
18
  //#region src/compile/aot-capture.ts
19
19
  function emptyContainers(node, depth) {
@@ -562,9 +562,11 @@ function compileHandlerJit(options, tailPass) {
562
562
  ], abortChainGuard(), require_compile_handler_utils.asyncTail(asyncMode)) + endTrace("error") + (hasDeriveDispose ? schedule + abortCatch : abortCatch + schedule) + `return _efb(e,c)\n`;
563
563
  } else body += endTrace("error") + freThenSchedule("e");
564
564
  const hookThrew = `catch(_ee){${freThenSchedule("_ee").trimEnd()}}}\n`;
565
- if (syncErrorHook) {
566
- factoryHelpers += `function _ce(e,c){${abortOn ? "let _as\n" : ""}try{\n${body}}${hookThrew}`;
567
- code += `}catch(e){return _ce(e,c)}\n`;
565
+ const syncFirst = typeof asyncMode === "object" && !asyncMode.async;
566
+ if (syncErrorHook || syncFirst) {
567
+ const live = syncFirst ? asyncMode.live : "";
568
+ factoryHelpers += `function _ce(e,c${live}){${abortOn ? "let _as\n" : ""}try{\n${body}}${hookThrew}`;
569
+ code += `}catch(e){return _ce(e,c${live})}\n`;
568
570
  } else code += `}catch(e){try{\n${body}}${hookThrew}`;
569
571
  } else code += catchSchedule ? `}catch(e){${freThenSchedule("e")}}\n` : `}catch(e){return fre(rt,c,e)}\n`;
570
572
  if (tailPass) return code;
@@ -562,9 +562,11 @@ function compileHandlerJit(options, tailPass) {
562
562
  ], abortChainGuard(), asyncTail(asyncMode)) + endTrace("error") + (hasDeriveDispose ? schedule + abortCatch : abortCatch + schedule) + `return _efb(e,c)\n`;
563
563
  } else body += endTrace("error") + freThenSchedule("e");
564
564
  const hookThrew = `catch(_ee){${freThenSchedule("_ee").trimEnd()}}}\n`;
565
- if (syncErrorHook) {
566
- factoryHelpers += `function _ce(e,c){${abortOn ? "let _as\n" : ""}try{\n${body}}${hookThrew}`;
567
- code += `}catch(e){return _ce(e,c)}\n`;
565
+ const syncFirst = typeof asyncMode === "object" && !asyncMode.async;
566
+ if (syncErrorHook || syncFirst) {
567
+ const live = syncFirst ? asyncMode.live : "";
568
+ factoryHelpers += `function _ce(e,c${live}){${abortOn ? "let _as\n" : ""}try{\n${body}}${hookThrew}`;
569
+ code += `}catch(e){return _ce(e,c${live})}\n`;
568
570
  } else code += `}catch(e){try{\n${body}}${hookThrew}`;
569
571
  } else code += catchSchedule ? `}catch(e){${freThenSchedule("e")}}\n` : `}catch(e){return fre(rt,c,e)}\n`;
570
572
  if (tailPass) return code;
@@ -219,16 +219,12 @@ function mapBeforeHandle(_hooks, derive, link, mode, report, abortGuard, arm) {
219
219
  const modes = deriveModes(hooks, derive);
220
220
  const tail = asyncTail(mode);
221
221
  let code = "";
222
- let depth = 0;
223
222
  let needsEs = false;
224
223
  for (let i = 0; i < hooks.length; i++) {
225
224
  const fn = hooks[i];
226
225
  const guard = i > 0 ? `${abortGuard ? `!${abortGuard}&&` : ""}_r===undefined` : void 0;
227
226
  if (tail) code += tailStage(tail, guard);
228
- else if (guard) {
229
- code += `if(${guard}){\n`;
230
- depth++;
231
- }
227
+ else if (guard) code += `if(${guard}){\n`;
232
228
  const t = traceChild(report, fn);
233
229
  code += t.begin;
234
230
  code += awaitSite(`bf${at(i)}(c)`, fn, mode, "tmp", arm);
@@ -246,9 +242,8 @@ else if(tmp){${merge};tmp=undefined}\n`;
246
242
  }
247
243
  } else code += "if(tmp!==undefined)_r=tmp\n";
248
244
  code += t.end("tmp");
249
- if (tail) code += "}\n";
245
+ if (tail || guard) code += "}\n";
250
246
  }
251
- code += "}".repeat(depth);
252
247
  if (needsEs) link(require_error.ElysiaStatus, "es");
253
248
  return code;
254
249
  }
@@ -291,22 +286,17 @@ function mapChainHook(_hooks, prefix, mode, report, abortGuard, arm) {
291
286
  const hooks = toArray(_hooks);
292
287
  const tail = asyncTail(mode);
293
288
  let code = "";
294
- let depth = 0;
295
289
  for (let i = 0; i < hooks.length; i++) {
296
290
  const fn = hooks[i];
297
291
  const guard = i > 0 ? `${abortGuard ? `!${abortGuard}&&` : ""}tmp===undefined` : void 0;
298
292
  if (tail) code += tailStage(tail, guard);
299
- else if (guard) {
300
- code += `if(${guard}){\n`;
301
- depth++;
302
- }
293
+ else if (guard) code += `if(${guard}){\n`;
303
294
  const t = traceChild(report, fn);
304
295
  code += t.begin;
305
296
  code += awaitSite(`${prefix}${at(i)}(c)`, fn, mode, "tmp", arm);
306
297
  code += t.end("tmp");
307
- if (tail) code += "}\n";
298
+ if (tail || guard) code += "}\n";
308
299
  }
309
- code += "}".repeat(depth);
310
300
  code += tailPlain(mode, `if(tmp!==undefined)_r=c.responseValue=tmp\n`);
311
301
  return code;
312
302
  }
@@ -324,18 +314,13 @@ function map(map) {
324
314
  return function(event, rest, abortGuard, tail) {
325
315
  if (Array.isArray(event)) {
326
316
  let code = "";
327
- let depth = 0;
328
317
  for (let i = 0; i < event.length; i++) {
329
318
  const guard = i > 0 && abortGuard ? `!${abortGuard}` : void 0;
330
319
  if (tail) code += tailStage(tail, guard);
331
- else if (guard) {
332
- code += `if(${guard}){\n`;
333
- depth++;
334
- }
320
+ else if (guard) code += `if(${guard}){\n`;
335
321
  code += map(i, event[i], rest);
336
- if (tail) code += "}\n";
322
+ if (tail || guard) code += "}\n";
337
323
  }
338
- code += "}".repeat(depth);
339
324
  return code;
340
325
  } else if (tail) return tailStage(tail) + map(void 0, event, rest) + "}\n";
341
326
  else return map(void 0, event, rest);
@@ -219,16 +219,12 @@ function mapBeforeHandle(_hooks, derive, link, mode, report, abortGuard, arm) {
219
219
  const modes = deriveModes(hooks, derive);
220
220
  const tail = asyncTail(mode);
221
221
  let code = "";
222
- let depth = 0;
223
222
  let needsEs = false;
224
223
  for (let i = 0; i < hooks.length; i++) {
225
224
  const fn = hooks[i];
226
225
  const guard = i > 0 ? `${abortGuard ? `!${abortGuard}&&` : ""}_r===undefined` : void 0;
227
226
  if (tail) code += tailStage(tail, guard);
228
- else if (guard) {
229
- code += `if(${guard}){\n`;
230
- depth++;
231
- }
227
+ else if (guard) code += `if(${guard}){\n`;
232
228
  const t = traceChild(report, fn);
233
229
  code += t.begin;
234
230
  code += awaitSite(`bf${at(i)}(c)`, fn, mode, "tmp", arm);
@@ -246,9 +242,8 @@ else if(tmp){${merge};tmp=undefined}\n`;
246
242
  }
247
243
  } else code += "if(tmp!==undefined)_r=tmp\n";
248
244
  code += t.end("tmp");
249
- if (tail) code += "}\n";
245
+ if (tail || guard) code += "}\n";
250
246
  }
251
- code += "}".repeat(depth);
252
247
  if (needsEs) link(ElysiaStatus, "es");
253
248
  return code;
254
249
  }
@@ -291,22 +286,17 @@ function mapChainHook(_hooks, prefix, mode, report, abortGuard, arm) {
291
286
  const hooks = toArray(_hooks);
292
287
  const tail = asyncTail(mode);
293
288
  let code = "";
294
- let depth = 0;
295
289
  for (let i = 0; i < hooks.length; i++) {
296
290
  const fn = hooks[i];
297
291
  const guard = i > 0 ? `${abortGuard ? `!${abortGuard}&&` : ""}tmp===undefined` : void 0;
298
292
  if (tail) code += tailStage(tail, guard);
299
- else if (guard) {
300
- code += `if(${guard}){\n`;
301
- depth++;
302
- }
293
+ else if (guard) code += `if(${guard}){\n`;
303
294
  const t = traceChild(report, fn);
304
295
  code += t.begin;
305
296
  code += awaitSite(`${prefix}${at(i)}(c)`, fn, mode, "tmp", arm);
306
297
  code += t.end("tmp");
307
- if (tail) code += "}\n";
298
+ if (tail || guard) code += "}\n";
308
299
  }
309
- code += "}".repeat(depth);
310
300
  code += tailPlain(mode, `if(tmp!==undefined)_r=c.responseValue=tmp\n`);
311
301
  return code;
312
302
  }
@@ -324,18 +314,13 @@ function map(map) {
324
314
  return function(event, rest, abortGuard, tail) {
325
315
  if (Array.isArray(event)) {
326
316
  let code = "";
327
- let depth = 0;
328
317
  for (let i = 0; i < event.length; i++) {
329
318
  const guard = i > 0 && abortGuard ? `!${abortGuard}` : void 0;
330
319
  if (tail) code += tailStage(tail, guard);
331
- else if (guard) {
332
- code += `if(${guard}){\n`;
333
- depth++;
334
- }
320
+ else if (guard) code += `if(${guard}){\n`;
335
321
  code += map(i, event[i], rest);
336
- if (tail) code += "}\n";
322
+ if (tail || guard) code += "}\n";
337
323
  }
338
- code += "}".repeat(depth);
339
324
  return code;
340
325
  } else if (tail) return tailStage(tail) + map(void 0, event, rest) + "}\n";
341
326
  else return map(void 0, event, rest);
@@ -72,34 +72,40 @@ function dispatchResult(result, context, handleError, afterResponse) {
72
72
  function findRoute(context, request, map, router, onNotFound, handleError, afterResponse, strictPath, hasWS, hasDynamicWS, app) {
73
73
  const path = context.path;
74
74
  const method = request.method;
75
- if (hasWS && method === "GET") {
76
- const handler = map["WS"]?.[path];
77
- const found = handler === void 0 && hasDynamicWS ? router?.find("WS", path) : void 0;
78
- if (handler !== void 0 || found) {
79
- const upgrade = request.headers.get("upgrade");
80
- if (upgrade && upgrade.toLowerCase() === "websocket") {
81
- if (handler) return dispatchResult(handler(context), context, handleError, afterResponse);
82
- context.params = path.indexOf("%") === -1 ? found.params : decodeParams(found.params);
83
- return dispatchResult(found.store(context), context, handleError, afterResponse);
75
+ if (hasWS) {
76
+ const wsMap = map["WS"];
77
+ if (method === "GET") {
78
+ const handler = path.length === 1 && path === "/" ? wsMap?.["/"] : wsMap?.[path];
79
+ const found = handler === void 0 && hasDynamicWS ? router?.find("WS", path) : void 0;
80
+ if (handler !== void 0 || found) {
81
+ const upgrade = request.headers.get("upgrade");
82
+ if (upgrade && upgrade.toLowerCase() === "websocket") {
83
+ if (handler) return dispatchResult(handler(context), context, handleError, afterResponse);
84
+ context.params = path.indexOf("%") === -1 ? found.params : decodeParams(found.params);
85
+ return dispatchResult(found.store(context), context, handleError, afterResponse);
86
+ }
84
87
  }
85
88
  }
86
89
  }
87
90
  const methodMap = map[method];
88
- let handler = methodMap?.[path];
89
- if (!handler) if (!strictPath && path.length > 1 && path.charCodeAt(path.length - 1) === 47) {
90
- const loose = path.slice(0, -1);
91
- handler = methodMap?.[loose];
92
- if (!handler) {
93
- const anyMap = map["*"];
94
- handler = anyMap?.[path] ?? anyMap?.[loose];
95
- }
96
- } else handler = map["*"]?.[path];
97
- if (handler) return dispatchResult(handler(context), context, handleError, afterResponse);
91
+ let handler;
92
+ if (path.length > 1) {
93
+ handler = methodMap?.[path];
94
+ if (!handler) if (!strictPath && path.charCodeAt(path.length - 1) === 47) {
95
+ const loose = path.slice(0, -1);
96
+ handler = loose.length > 1 ? methodMap?.[loose] : methodMap?.[path[0]];
97
+ if (!handler) {
98
+ const anyMap = map["*"];
99
+ handler = anyMap?.[path] ?? anyMap?.[loose];
100
+ }
101
+ } else handler = map["*"]?.[path];
102
+ } else handler = methodMap?.[context.path] || map["*"]?.[path];
103
+ if (handler) return dispatchResult(typeof handler === "number" ? app["~dispatch"](~handler, context) : handler(context), context, handleError, afterResponse);
98
104
  const found = router?.find(method, path) ?? router?.find("*", path);
99
105
  if (found) {
100
106
  context.params = path.indexOf("%") === -1 ? found.params : decodeParams(found.params);
101
107
  const store = found.store;
102
- const dynamic = typeof store === "number" ? app["compiled"]?.[store] : store;
108
+ const dynamic = typeof store === "number" ? void 0 : store;
103
109
  return dispatchResult(dynamic ? dynamic(context) : app["~dispatch"](store, context), context, handleError, afterResponse);
104
110
  }
105
111
  return onNotFound(context);
@@ -70,34 +70,40 @@ function dispatchResult(result, context, handleError, afterResponse) {
70
70
  function findRoute(context, request, map, router, onNotFound, handleError, afterResponse, strictPath, hasWS, hasDynamicWS, app) {
71
71
  const path = context.path;
72
72
  const method = request.method;
73
- if (hasWS && method === "GET") {
74
- const handler = map["WS"]?.[path];
75
- const found = handler === void 0 && hasDynamicWS ? router?.find("WS", path) : void 0;
76
- if (handler !== void 0 || found) {
77
- const upgrade = request.headers.get("upgrade");
78
- if (upgrade && upgrade.toLowerCase() === "websocket") {
79
- if (handler) return dispatchResult(handler(context), context, handleError, afterResponse);
80
- context.params = path.indexOf("%") === -1 ? found.params : decodeParams(found.params);
81
- return dispatchResult(found.store(context), context, handleError, afterResponse);
73
+ if (hasWS) {
74
+ const wsMap = map["WS"];
75
+ if (method === "GET") {
76
+ const handler = path.length === 1 && path === "/" ? wsMap?.["/"] : wsMap?.[path];
77
+ const found = handler === void 0 && hasDynamicWS ? router?.find("WS", path) : void 0;
78
+ if (handler !== void 0 || found) {
79
+ const upgrade = request.headers.get("upgrade");
80
+ if (upgrade && upgrade.toLowerCase() === "websocket") {
81
+ if (handler) return dispatchResult(handler(context), context, handleError, afterResponse);
82
+ context.params = path.indexOf("%") === -1 ? found.params : decodeParams(found.params);
83
+ return dispatchResult(found.store(context), context, handleError, afterResponse);
84
+ }
82
85
  }
83
86
  }
84
87
  }
85
88
  const methodMap = map[method];
86
- let handler = methodMap?.[path];
87
- if (!handler) if (!strictPath && path.length > 1 && path.charCodeAt(path.length - 1) === 47) {
88
- const loose = path.slice(0, -1);
89
- handler = methodMap?.[loose];
90
- if (!handler) {
91
- const anyMap = map["*"];
92
- handler = anyMap?.[path] ?? anyMap?.[loose];
93
- }
94
- } else handler = map["*"]?.[path];
95
- if (handler) return dispatchResult(handler(context), context, handleError, afterResponse);
89
+ let handler;
90
+ if (path.length > 1) {
91
+ handler = methodMap?.[path];
92
+ if (!handler) if (!strictPath && path.charCodeAt(path.length - 1) === 47) {
93
+ const loose = path.slice(0, -1);
94
+ handler = loose.length > 1 ? methodMap?.[loose] : methodMap?.[path[0]];
95
+ if (!handler) {
96
+ const anyMap = map["*"];
97
+ handler = anyMap?.[path] ?? anyMap?.[loose];
98
+ }
99
+ } else handler = map["*"]?.[path];
100
+ } else handler = methodMap?.[context.path] || map["*"]?.[path];
101
+ if (handler) return dispatchResult(typeof handler === "number" ? app["~dispatch"](~handler, context) : handler(context), context, handleError, afterResponse);
96
102
  const found = router?.find(method, path) ?? router?.find("*", path);
97
103
  if (found) {
98
104
  context.params = path.indexOf("%") === -1 ? found.params : decodeParams(found.params);
99
105
  const store = found.store;
100
- const dynamic = typeof store === "number" ? app["compiled"]?.[store] : store;
106
+ const dynamic = typeof store === "number" ? void 0 : store;
101
107
  return dispatchResult(dynamic ? dynamic(context) : app["~dispatch"](store, context), context, handleError, afterResponse);
102
108
  }
103
109
  return onNotFound(context);
package/dist/package.js CHANGED
@@ -1,6 +1,6 @@
1
1
 
2
2
  //#region package.json
3
- var version = "2.0.0-beta.24";
3
+ var version = "2.0.0-beta.26";
4
4
 
5
5
  //#endregion
6
6
  Object.defineProperty(exports, 'version', {
package/dist/package.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  // @bun
2
2
  //#region package.json
3
- var version = "2.0.0-beta.24";
3
+ var version = "2.0.0-beta.26";
4
4
 
5
5
  //#endregion
6
6
  export { version };
@@ -463,8 +463,14 @@ async function generateCompiledArtifacts(file, options, moduleCondition = resolv
463
463
  if (_importedEntries.has(entryReal)) return generateCompiledArtifactsIsolated(file, options, moduleCondition);
464
464
  _importedEntries.add(entryReal);
465
465
  const mod = await import(entry);
466
- const app = mod.app ?? mod.default;
467
- if (!app || typeof app.compile !== "function") throw new Error(`[elysia-aot] "${entry}" must export an Elysia app`);
466
+ const isApp = (value) => typeof value?.compile === "function";
467
+ let app = isApp(mod.app) ? mod.app : mod.default;
468
+ if (!isApp(app)) {
469
+ const names = Object.keys(mod).filter((name) => isApp(mod[name]));
470
+ if (new Set(names.map((name) => mod[name])).size > 1) throw new Error(`[elysia-aot] "${entry}" exports multiple Elysia apps (${names.join(", ")}). Export the one to compile as \`app\` or default`);
471
+ app = names[0] ? mod[names[0]] : void 0;
472
+ }
473
+ if (!isApp(app)) throw new Error(`[elysia-aot] "${entry}" must export an Elysia app`);
468
474
  const typedApp = app;
469
475
  assertNoMount(typedApp, entry);
470
476
  const sourceOptions = {
@@ -461,8 +461,14 @@ async function generateCompiledArtifacts(file, options, moduleCondition = resolv
461
461
  if (_importedEntries.has(entryReal)) return generateCompiledArtifactsIsolated(file, options, moduleCondition);
462
462
  _importedEntries.add(entryReal);
463
463
  const mod = await import(entry);
464
- const app = mod.app ?? mod.default;
465
- if (!app || typeof app.compile !== "function") throw new Error(`[elysia-aot] "${entry}" must export an Elysia app`);
464
+ const isApp = (value) => typeof value?.compile === "function";
465
+ let app = isApp(mod.app) ? mod.app : mod.default;
466
+ if (!isApp(app)) {
467
+ const names = Object.keys(mod).filter((name) => isApp(mod[name]));
468
+ if (new Set(names.map((name) => mod[name])).size > 1) throw new Error(`[elysia-aot] "${entry}" exports multiple Elysia apps (${names.join(", ")}). Export the one to compile as \`app\` or default`);
469
+ app = names[0] ? mod[names[0]] : void 0;
470
+ }
471
+ if (!isApp(app)) throw new Error(`[elysia-aot] "${entry}" must export an Elysia app`);
466
472
  const typedApp = app;
467
473
  assertNoMount(typedApp, entry);
468
474
  const sourceOptions = {
@@ -5,8 +5,8 @@ import { useTypebox as useTypebox$1 } from "./bridge.js";
5
5
  import { TypeBoxValidatorCache, mayHaveFileType } from "./validator/validator-cache.js";
6
6
  import { TypeBoxValidator } from "./validator/index.js";
7
7
  import { Ref } from "typebox/type";
8
- import { Compile } from "typebox/compile";
9
8
  import { Check, Clone, Create, Decode, HasCodec } from "typebox/value";
9
+ import { Compile } from "typebox/compile";
10
10
 
11
11
  //#region src/type/bridge-live.d.ts
12
12
  declare function useTypebox(_mod?: Parameters<typeof useTypebox$1>[0]): void;
@@ -6,8 +6,8 @@ const require_type_validator_validator_cache = require('./validator/validator-ca
6
6
  const require_type_validator_index = require('./validator/index.js');
7
7
  const require_type_elysia_intersect = require('./elysia/intersect.js');
8
8
  let typebox_type = require("typebox/type");
9
- let typebox_compile = require("typebox/compile");
10
9
  let typebox_value = require("typebox/value");
10
+ let typebox_compile = require("typebox/compile");
11
11
  let typebox_system = require("typebox/system");
12
12
 
13
13
  //#region src/type/bridge-live.ts
@@ -5,8 +5,8 @@ import { TypeBoxValidatorCache, mayHaveFileType } from "./validator/validator-ca
5
5
  import { TypeBoxValidator } from "./validator/index.mjs";
6
6
  import { Intersect } from "./elysia/intersect.mjs";
7
7
  import { Ref } from "typebox/type";
8
- import { Compile } from "typebox/compile";
9
8
  import { Check, Clone, Create, Decode, HasCodec } from "typebox/value";
9
+ import { Compile } from "typebox/compile";
10
10
  import { Settings } from "typebox/system";
11
11
 
12
12
  //#region src/type/bridge-live.ts
@@ -4,8 +4,8 @@ import { hasTypes as hasTypes$1 } from "./utils.js";
4
4
  import { TypeBoxValidatorCache as TypeBoxValidatorCache$1, mayHaveFileType as mayHaveFileType$1 } from "./validator/validator-cache.js";
5
5
  import { TypeBoxValidator as TypeBoxValidator$1 } from "./validator/index.js";
6
6
  import { Ref as Ref$1, TAny, TSchema } from "typebox/type";
7
- import { Compile as Compile$1 } from "typebox/compile";
8
7
  import { Check as Check$1, Clone as Clone$1, Create as Create$1, Decode as Decode$2, HasCodec as HasCodec$1 } from "typebox/value";
8
+ import { Compile as Compile$1 } from "typebox/compile";
9
9
 
10
10
  //#region src/type/bridge.d.ts
11
11
  interface TypeboxModule {
@@ -17,7 +17,7 @@ declare const ELYSIA_TYPES: {
17
17
  readonly NoValidate: 15;
18
18
  };
19
19
  type ELYSIA_TYPES = typeof ELYSIA_TYPES;
20
- declare const primitiveElysiaTypes: Set<1 | 2 | 6 | 3 | 10 | 11 | 13 | 14>;
20
+ declare const primitiveElysiaTypes: Set<6 | 1 | 2 | 3 | 10 | 11 | 13 | 14>;
21
21
  declare const noEnumerable: {
22
22
  readonly enumerable: false;
23
23
  };
@@ -1,7 +1,7 @@
1
1
  import { TypeboxNamespaces } from "./typebox-value.js";
2
- import { Compile } from "typebox/compile";
3
- import { Check, Clean, Clone, Create, Decode, DecodeUnsafe, Default, Encode, EncodeUnsafe, Errors, HasCodec } from "typebox/value";
4
2
  import { Build, Compile as SchemaCompile } from "typebox/schema";
3
+ import { Check, Clean, Clone, Create, Decode, DecodeUnsafe, Default, Encode, EncodeUnsafe, Errors, HasCodec } from "typebox/value";
4
+ import { Compile } from "typebox/compile";
5
5
 
6
6
  //#region src/type/typebox-value-live.d.ts
7
7
  declare function injectTypebox(_typebox?: TypeboxNamespaces): void;
@@ -1,9 +1,9 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
  const require_runtime = require('../_virtual/_rolldown/runtime.js');
3
- let typebox_compile = require("typebox/compile");
3
+ let typebox_schema = require("typebox/schema");
4
4
  let typebox_value = require("typebox/value");
5
+ let typebox_compile = require("typebox/compile");
5
6
  let typebox_system = require("typebox/system");
6
- let typebox_schema = require("typebox/schema");
7
7
 
8
8
  //#region src/type/typebox-value-live.ts
9
9
  typebox_system.Settings.Set({ unionPrioritySort: false });
@@ -1,8 +1,8 @@
1
1
  // @bun
2
- import { Compile } from "typebox/compile";
2
+ import { Build, Compile as SchemaCompile } from "typebox/schema";
3
3
  import { Check, Clean, Clone, Create, Decode, DecodeUnsafe, Default, Encode, EncodeUnsafe, Errors, HasCodec } from "typebox/value";
4
+ import { Compile } from "typebox/compile";
4
5
  import { Settings } from "typebox/system";
5
- import { Build, Compile as SchemaCompile } from "typebox/schema";
6
6
 
7
7
  //#region src/type/typebox-value-live.ts
8
8
  Settings.Set({ unionPrioritySort: false });
@@ -1,4 +1,4 @@
1
- import { Compile } from "typebox/compile";
2
- import { Check, Clean, Clone, Create, Decode, DecodeUnsafe, Default, Encode, EncodeUnsafe, Errors, HasCodec } from "typebox/value";
3
1
  import { Build, Compile as SchemaCompile } from "typebox/schema";
2
+ import { Check, Clean, Clone, Create, Decode, DecodeUnsafe, Default, Encode, EncodeUnsafe, Errors, HasCodec } from "typebox/value";
3
+ import { Compile } from "typebox/compile";
4
4
  export { Build, Check, Clean, Clone, Compile, Create, Decode, DecodeUnsafe, Default, Encode, EncodeUnsafe, Errors, HasCodec, SchemaCompile };
@@ -1,8 +1,8 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
  const require_runtime = require('../_virtual/_rolldown/runtime.js');
3
- let typebox_compile = require("typebox/compile");
4
- let typebox_value = require("typebox/value");
5
3
  let typebox_schema = require("typebox/schema");
4
+ let typebox_value = require("typebox/value");
5
+ let typebox_compile = require("typebox/compile");
6
6
 
7
7
  Object.defineProperty(exports, 'Build', {
8
8
  enumerable: true,
@@ -1,6 +1,6 @@
1
1
  // @bun
2
- import { Compile } from "typebox/compile";
3
- import { Check, Clean, Clone, Create, Decode, DecodeUnsafe, Default, Encode, EncodeUnsafe, Errors, HasCodec } from "typebox/value";
4
2
  import { Build, Compile as SchemaCompile } from "typebox/schema";
3
+ import { Check, Clean, Clone, Create, Decode, DecodeUnsafe, Default, Encode, EncodeUnsafe, Errors, HasCodec } from "typebox/value";
4
+ import { Compile } from "typebox/compile";
5
5
 
6
6
  export { Build, Check, Clean, Clone, Compile, Create, Decode, DecodeUnsafe, Default, Encode, EncodeUnsafe, Errors, HasCodec, SchemaCompile };
@@ -1,9 +1,9 @@
1
- import * as _$typebox_compile0 from "typebox/compile";
2
- import { Compile as Compile$1 } from "typebox/compile";
1
+ import * as _$typebox_schema0 from "typebox/schema";
2
+ import { Build as Build$1, Compile as Compile$1 } from "typebox/schema";
3
3
  import * as _$typebox_value0 from "typebox/value";
4
4
  import { Check as Check$1, Clean as Clean$1, Clone as Clone$1, Create as Create$1, Decode as Decode$1, DecodeUnsafe as DecodeUnsafe$1, Default as Default$1, Encode as Encode$1, EncodeUnsafe as EncodeUnsafe$1, Errors as Errors$1, HasCodec as HasCodec$1 } from "typebox/value";
5
- import * as _$typebox_schema0 from "typebox/schema";
6
- import { Build as Build$1, Compile as Compile$2 } from "typebox/schema";
5
+ import * as _$typebox_compile0 from "typebox/compile";
6
+ import { Compile as Compile$2 } from "typebox/compile";
7
7
 
8
8
  //#region src/type/typebox-value.d.ts
9
9
  interface TypeboxNamespaces {
@@ -27,9 +27,9 @@ declare let Encode: typeof Encode$1;
27
27
  declare let EncodeUnsafe: typeof EncodeUnsafe$1;
28
28
  declare let Errors: typeof Errors$1;
29
29
  declare let HasCodec: typeof HasCodec$1;
30
- declare let SchemaCompile: typeof Compile$2;
30
+ declare let SchemaCompile: typeof Compile$1;
31
31
  declare let Build: typeof Build$1;
32
- declare let Compile: typeof Compile$1;
32
+ declare let Compile: typeof Compile$2;
33
33
  declare function injectTypebox(typebox: TypeboxNamespaces): void;
34
34
  //#endregion
35
35
  export { Build, Check, Clean, Clone, Compile, Create, Decode, DecodeUnsafe, Default, Encode, EncodeUnsafe, Errors, HasCodec, SchemaCompile, TypeboxNamespaces, injectTypebox, preloadTypebox, load as warmTypebox };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "elysia",
3
3
  "description": "Ergonomic Framework for Human",
4
- "version": "2.0.0-beta.24",
4
+ "version": "2.0.0-beta.26",
5
5
  "author": {
6
6
  "name": "saltyAom",
7
7
  "url": "https://github.com/SaltyAom",