elysia 2.0.0-beta.16 → 2.0.0-beta.18
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.
- package/dist/adapter/bun/index.d.ts +15 -2
- package/dist/adapter/bun/index.js +115 -37
- package/dist/adapter/bun/index.mjs +114 -36
- package/dist/adapter/types.d.ts +2 -21
- package/dist/adapter/utils.d.ts +14 -3
- package/dist/adapter/utils.js +83 -35
- package/dist/adapter/utils.mjs +84 -37
- package/dist/adapter/web-standard/handler.d.ts +1 -1
- package/dist/adapter/web-standard/handler.js +34 -33
- package/dist/adapter/web-standard/handler.mjs +35 -34
- package/dist/adapter/web-standard/index.js +2 -30
- package/dist/adapter/web-standard/index.mjs +2 -30
- package/dist/adapter/web-standard/utils.js +5 -18
- package/dist/adapter/web-standard/utils.mjs +5 -18
- package/dist/base.d.ts +37 -70
- package/dist/base.js +164 -330
- package/dist/base.mjs +165 -331
- package/dist/compile/aot-capture.js +19 -40
- package/dist/compile/aot-capture.mjs +19 -40
- package/dist/compile/aot-emit.js +1 -9
- package/dist/compile/aot-emit.mjs +1 -9
- package/dist/compile/aot.d.ts +2 -5
- package/dist/compile/aot.js +7 -20
- package/dist/compile/aot.mjs +8 -20
- package/dist/compile/handler/descriptor.d.ts +8 -7
- package/dist/compile/handler/descriptor.js +10 -21
- package/dist/compile/handler/descriptor.mjs +11 -20
- package/dist/compile/handler/frozen-validator.d.ts +2 -10
- package/dist/compile/handler/frozen-validator.js +25 -89
- package/dist/compile/handler/frozen-validator.mjs +27 -90
- package/dist/compile/handler/index.d.ts +1 -1
- package/dist/compile/handler/index.js +70 -76
- package/dist/compile/handler/index.mjs +71 -77
- package/dist/compile/handler/jit.d.ts +12 -17
- package/dist/compile/handler/jit.js +133 -84
- package/dist/compile/handler/jit.mjs +134 -86
- package/dist/compile/handler/params.js +1 -2
- package/dist/compile/handler/params.mjs +3 -4
- package/dist/compile/handler/utils.d.ts +21 -11
- package/dist/compile/handler/utils.js +113 -223
- package/dist/compile/handler/utils.mjs +110 -220
- package/dist/compile/jit-probe.js +2 -3
- package/dist/compile/jit-probe.mjs +2 -3
- package/dist/compile/lexer.d.ts +7 -4
- package/dist/compile/lexer.js +268 -6
- package/dist/compile/lexer.mjs +268 -4
- package/dist/compiled.d.ts +0 -1
- package/dist/compiled.js +0 -1
- package/dist/compiled.mjs +0 -1
- package/dist/context.d.ts +11 -3
- package/dist/context.js +8 -10
- package/dist/context.mjs +8 -10
- package/dist/cookie/cookie.d.ts +0 -1
- package/dist/cookie/cookie.js +2 -5
- package/dist/cookie/cookie.mjs +2 -5
- package/dist/cookie/crypto.js +13 -9
- package/dist/cookie/crypto.mjs +13 -9
- package/dist/cookie/utils.d.ts +3 -3
- package/dist/cookie/utils.js +54 -15
- package/dist/cookie/utils.mjs +54 -15
- package/dist/error.d.ts +6 -13
- package/dist/error.js +38 -71
- package/dist/error.mjs +38 -71
- package/dist/generation.d.ts +2 -2
- package/dist/handler/error.d.ts +3 -3
- package/dist/handler/error.js +45 -69
- package/dist/handler/error.mjs +46 -70
- package/dist/handler/fetch.js +53 -88
- package/dist/handler/fetch.mjs +54 -89
- package/dist/handler/utils.d.ts +4 -4
- package/dist/handler/utils.js +22 -21
- package/dist/handler/utils.mjs +22 -21
- package/dist/index.d.ts +10 -10
- package/dist/memory.js +1 -1
- package/dist/memory.mjs +1 -1
- package/dist/package.js +1 -1
- package/dist/package.mjs +1 -1
- package/dist/plugin/aot/bun.js +1 -4
- package/dist/plugin/aot/bun.mjs +1 -4
- package/dist/plugin/aot/core.d.ts +11 -27
- package/dist/plugin/aot/core.js +30 -29
- package/dist/plugin/aot/core.mjs +28 -30
- package/dist/plugin/aot/esbuild.js +1 -4
- package/dist/plugin/aot/esbuild.mjs +1 -4
- package/dist/plugin/aot/hooks.d.ts +3 -16
- package/dist/plugin/aot/hooks.js +7 -8
- package/dist/plugin/aot/hooks.mjs +8 -9
- package/dist/plugin/aot/rspack-loader.d.ts +1 -5
- package/dist/plugin/aot/rspack-loader.js +1 -10
- package/dist/plugin/aot/rspack-loader.mjs +1 -10
- package/dist/plugin/aot/rspack.js +2 -5
- package/dist/plugin/aot/rspack.mjs +3 -6
- package/dist/plugin/aot/source.d.ts +2 -41
- package/dist/plugin/aot/source.js +33 -55
- package/dist/plugin/aot/source.mjs +34 -56
- package/dist/plugin/aot/treeshake.js +2 -6
- package/dist/plugin/aot/treeshake.mjs +2 -6
- package/dist/plugin/aot/unplugin.d.ts +1 -4
- package/dist/plugin/aot/unplugin.js +4 -13
- package/dist/plugin/aot/unplugin.mjs +4 -13
- package/dist/plugin/aot/vite.d.ts +2 -6
- package/dist/plugin/auto-head.js +1 -10
- package/dist/plugin/auto-head.mjs +1 -10
- package/dist/plugin/trace.d.ts +2 -1
- package/dist/schema-snapshot.d.ts +0 -4
- package/dist/schema-snapshot.js +14 -27
- package/dist/schema-snapshot.mjs +14 -27
- package/dist/sucrose.d.ts +6 -55
- package/dist/sucrose.js +95 -735
- package/dist/sucrose.mjs +94 -728
- package/dist/trace.d.ts +5 -8
- package/dist/trace.js +13 -134
- package/dist/trace.mjs +14 -135
- package/dist/type/bridge-live.d.ts +4 -3
- package/dist/type/bridge-live.js +4 -3
- package/dist/type/bridge-live.mjs +4 -3
- package/dist/type/bridge.d.ts +7 -7
- package/dist/type/bridge.js +8 -8
- package/dist/type/bridge.mjs +3 -3
- package/dist/type/coerce-plan.d.ts +2 -2
- package/dist/type/coerce-plan.js +10 -12
- package/dist/type/coerce-plan.mjs +10 -12
- package/dist/type/coerce.d.ts +0 -4
- package/dist/type/coerce.js +17 -74
- package/dist/type/coerce.mjs +17 -74
- package/dist/type/compat.js +9 -19
- package/dist/type/compat.mjs +10 -20
- package/dist/type/elysia/array-buffer.d.ts +4 -1
- package/dist/type/elysia/array-buffer.js +16 -15
- package/dist/type/elysia/array-buffer.mjs +16 -16
- package/dist/type/elysia/array-string.js +2 -43
- package/dist/type/elysia/array-string.mjs +2 -43
- package/dist/type/elysia/array.js +5 -9
- package/dist/type/elysia/array.mjs +5 -9
- package/dist/type/elysia/boolean.js +3 -13
- package/dist/type/elysia/boolean.mjs +3 -13
- package/dist/type/elysia/cookie.d.ts +3 -4
- package/dist/type/elysia/cookie.js +4 -6
- package/dist/type/elysia/cookie.mjs +4 -6
- package/dist/type/elysia/date.js +7 -13
- package/dist/type/elysia/date.mjs +7 -13
- package/dist/type/elysia/file-type.d.ts +1 -1
- package/dist/type/elysia/file.d.ts +1 -3
- package/dist/type/elysia/file.js +2 -22
- package/dist/type/elysia/file.mjs +4 -10
- package/dist/type/elysia/files.js +1 -7
- package/dist/type/elysia/files.mjs +2 -8
- package/dist/type/elysia/integer-string.d.ts +1 -1
- package/dist/type/elysia/integer-string.js +3 -28
- package/dist/type/elysia/integer-string.mjs +4 -29
- package/dist/type/elysia/integer.js +3 -13
- package/dist/type/elysia/integer.mjs +3 -13
- package/dist/type/elysia/intersect.js +0 -5
- package/dist/type/elysia/intersect.mjs +0 -5
- package/dist/type/elysia/json-string.d.ts +7 -0
- package/dist/type/elysia/json-string.js +47 -0
- package/dist/type/elysia/json-string.mjs +46 -0
- package/dist/type/elysia/number.d.ts +2 -1
- package/dist/type/elysia/number.js +19 -12
- package/dist/type/elysia/number.mjs +18 -12
- package/dist/type/elysia/numeric-enum.d.ts +1 -1
- package/dist/type/elysia/numeric-enum.js +2 -2
- package/dist/type/elysia/numeric-enum.mjs +2 -2
- package/dist/type/elysia/numeric.d.ts +4 -2
- package/dist/type/elysia/numeric.js +24 -20
- package/dist/type/elysia/numeric.mjs +23 -20
- package/dist/type/elysia/object-string.js +2 -40
- package/dist/type/elysia/object-string.mjs +2 -40
- package/dist/type/elysia/object.js +5 -9
- package/dist/type/elysia/object.mjs +5 -9
- package/dist/type/elysia/optional.js +8 -8
- package/dist/type/elysia/optional.mjs +7 -7
- package/dist/type/elysia/uint8-array.d.ts +1 -1
- package/dist/type/elysia/uint8-array.js +4 -18
- package/dist/type/elysia/uint8-array.mjs +4 -18
- package/dist/type/elysia/union-enum.js +5 -5
- package/dist/type/elysia/union-enum.mjs +5 -5
- package/dist/type/elysia/union.js +0 -5
- package/dist/type/elysia/union.mjs +0 -5
- package/dist/type/elysia/utils.d.ts +2 -4
- package/dist/type/elysia/utils.js +8 -18
- package/dist/type/elysia/utils.mjs +6 -14
- package/dist/type/exports.js +1 -1
- package/dist/type/exports.mjs +1 -1
- package/dist/type/index.d.ts +1 -1
- package/dist/type/index.js +10 -10
- package/dist/type/index.mjs +11 -11
- package/dist/type/shared.d.ts +3 -7
- package/dist/type/shared.js +44 -94
- package/dist/type/shared.mjs +43 -95
- package/dist/type/sync-require.d.ts +11 -0
- package/dist/type/sync-require.js +14 -0
- package/dist/type/sync-require.mjs +12 -0
- package/dist/type/typebox-type-live.d.ts +4 -2
- package/dist/type/typebox-type-live.js +7 -3
- package/dist/type/typebox-type-live.mjs +4 -2
- package/dist/type/typebox-type.d.ts +4 -2
- package/dist/type/typebox-type.js +20 -15
- package/dist/type/typebox-type.mjs +18 -14
- package/dist/type/typebox-value-live.d.ts +3 -2
- package/dist/type/typebox-value-live.js +4 -2
- package/dist/type/typebox-value-live.mjs +4 -3
- package/dist/type/typebox-value-require.d.ts +19 -0
- package/dist/type/typebox-value-require.js +30 -0
- package/dist/type/typebox-value-require.mjs +27 -0
- package/dist/type/typebox-value.d.ts +4 -3
- package/dist/type/typebox-value.js +24 -4
- package/dist/type/typebox-value.mjs +25 -6
- package/dist/type/utils.js +1 -10
- package/dist/type/utils.mjs +1 -10
- package/dist/type/validator/clean-safe.d.ts +2 -3
- package/dist/type/validator/clean-safe.js +15 -9
- package/dist/type/validator/clean-safe.mjs +16 -9
- package/dist/type/validator/custom-error.js +26 -40
- package/dist/type/validator/custom-error.mjs +26 -40
- package/dist/type/validator/default-precompute.js +6 -52
- package/dist/type/validator/default-precompute.mjs +6 -52
- package/dist/type/validator/exact-mirror-require.d.ts +4 -0
- package/dist/type/validator/exact-mirror-require.js +11 -0
- package/dist/type/validator/exact-mirror-require.mjs +9 -0
- package/dist/type/validator/exact-mirror.js +3 -1
- package/dist/type/validator/exact-mirror.mjs +4 -1
- package/dist/type/validator/index.d.ts +1 -1
- package/dist/type/validator/index.js +43 -77
- package/dist/type/validator/index.mjs +44 -78
- package/dist/type/validator/validator-cache.d.ts +4 -3
- package/dist/type/validator/validator-cache.js +8 -1
- package/dist/type/validator/validator-cache.mjs +8 -1
- package/dist/types.d.ts +26 -45
- package/dist/universal/env.js +2 -3
- package/dist/universal/env.mjs +2 -3
- package/dist/universal/file.d.ts +5 -1
- package/dist/universal/file.js +9 -8
- package/dist/universal/file.mjs +9 -8
- package/dist/universal/index.d.ts +2 -2
- package/dist/universal/server.d.ts +0 -272
- package/dist/utils.d.ts +8 -13
- package/dist/utils.js +51 -93
- package/dist/utils.mjs +50 -92
- package/dist/validator/index.d.ts +1 -1
- package/dist/validator/index.js +2 -11
- package/dist/validator/index.mjs +3 -12
- package/dist/validator/route.js +2 -1
- package/dist/validator/route.mjs +2 -1
- package/dist/ws/context.js +7 -17
- package/dist/ws/context.mjs +7 -17
- package/dist/ws/parser.js +9 -22
- package/dist/ws/parser.mjs +9 -22
- package/dist/ws/route.d.ts +2 -2
- package/dist/ws/route.js +23 -103
- package/dist/ws/route.mjs +24 -104
- package/dist/ws/types.d.ts +2 -2
- package/package.json +2 -42
- package/dist/compile/analysis-cache.d.ts +0 -6
- package/dist/compile/analysis-cache.js +0 -12
- package/dist/compile/analysis-cache.mjs +0 -11
- package/dist/cookie/index.d.ts +0 -6
- package/dist/cookie/index.js +0 -11
- package/dist/cookie/index.mjs +0 -6
- package/dist/handler/index.d.ts +0 -2
- package/dist/handler/index.js +0 -5
- package/dist/handler/index.mjs +0 -3
|
@@ -1,9 +1,22 @@
|
|
|
1
|
+
import { isHTMLBundle } from "../../utils.js";
|
|
1
2
|
import { BunHTMLBundlelike } from "../../types.js";
|
|
2
3
|
import { AnyElysia } from "../../base.js";
|
|
3
4
|
import { ElysiaAdapterOptions } from "../types.js";
|
|
4
5
|
//#region src/adapter/bun/index.d.ts
|
|
5
|
-
|
|
6
|
-
|
|
6
|
+
type NativeRoutes = Record<string, Record<string, unknown>>;
|
|
7
|
+
/**
|
|
8
|
+
* HTML bundles served by Bun's native router.
|
|
9
|
+
*
|
|
10
|
+
* A `:param` / `*` bundle (SPA fallback) matches before `fetch`, so with a
|
|
11
|
+
* `handoff` every other route of that method is registered natively too,
|
|
12
|
+
* handing off to `fetch`: Bun's specificity (exact > param > wildcard) then
|
|
13
|
+
* picks the Elysia route, and only unmatched paths reach the bundle (Elysia's
|
|
14
|
+
* own router leaves these bundles out, see `#buildRouterUnsafe`).
|
|
15
|
+
*
|
|
16
|
+
* All or nothing: when any route cannot be expressed in Bun's router, dynamic
|
|
17
|
+
* bundles are not served natively at all, since that route would be shadowed.
|
|
18
|
+
*/
|
|
19
|
+
declare function collectHTMLBundleRoutes(app: AnyElysia, handoff?: (request: Request, server: unknown) => unknown, routes?: NativeRoutes): NativeRoutes | undefined;
|
|
7
20
|
declare function collectStaticRoutes(app: AnyElysia): Record<string, Record<string, Response | BunHTMLBundlelike>> | undefined;
|
|
8
21
|
declare const BunAdapter: ElysiaAdapterOptions<void>;
|
|
9
22
|
//#endregion
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
2
|
const require_adapter_index = require('../index.js');
|
|
3
3
|
const require_utils = require('../../utils.js');
|
|
4
|
+
const require_type_bridge = require('../../type/bridge.js');
|
|
5
|
+
const require_universal_is_production = require('../../universal/is-production.js');
|
|
4
6
|
const require_adapter_web_standard_index = require('../web-standard/index.js');
|
|
5
7
|
const require_generation = require('../../generation.js');
|
|
6
8
|
const require_adapter_origin = require('../origin.js');
|
|
@@ -68,13 +70,81 @@ const withOrigin = (fetch) => (request, server) => {
|
|
|
68
70
|
}
|
|
69
71
|
};
|
|
70
72
|
const isNativeStaticMethod = (method) => method === "GET" || method === "POST" || method === "PUT" || method === "DELETE" || method === "PATCH" || method === "HEAD" || method === "OPTIONS";
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
73
|
+
function expandOptional(path) {
|
|
74
|
+
const at = path.indexOf("?");
|
|
75
|
+
if (at === -1) return [path];
|
|
76
|
+
const start = path.lastIndexOf("/", at);
|
|
77
|
+
const rest = path.slice(at + 1);
|
|
78
|
+
return [...expandOptional(path.slice(0, start) + rest), ...expandOptional(path.slice(0, at) + rest)].map((variant) => variant || "/");
|
|
79
|
+
}
|
|
80
|
+
function isNativePath(path) {
|
|
81
|
+
const names = /* @__PURE__ */ new Set();
|
|
82
|
+
const segments = path.split("/");
|
|
83
|
+
for (let i = 0; i < segments.length; i++) {
|
|
84
|
+
const segment = segments[i];
|
|
85
|
+
if (segment.indexOf("*") !== -1) {
|
|
86
|
+
if (segment !== "*" || i !== segments.length - 1) return false;
|
|
87
|
+
} else if (segment.indexOf(":") !== -1) {
|
|
88
|
+
if (!/^:[A-Za-z_$][\w$]*$/.test(segment)) return false;
|
|
89
|
+
if (names.has(segment)) return false;
|
|
90
|
+
names.add(segment);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return true;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* HTML bundles served by Bun's native router.
|
|
97
|
+
*
|
|
98
|
+
* A `:param` / `*` bundle (SPA fallback) matches before `fetch`, so with a
|
|
99
|
+
* `handoff` every other route of that method is registered natively too,
|
|
100
|
+
* handing off to `fetch`: Bun's specificity (exact > param > wildcard) then
|
|
101
|
+
* picks the Elysia route, and only unmatched paths reach the bundle (Elysia's
|
|
102
|
+
* own router leaves these bundles out, see `#buildRouterUnsafe`).
|
|
103
|
+
*
|
|
104
|
+
* All or nothing: when any route cannot be expressed in Bun's router, dynamic
|
|
105
|
+
* bundles are not served natively at all, since that route would be shadowed.
|
|
106
|
+
*/
|
|
107
|
+
function collectHTMLBundleRoutes(app, handoff, routes) {
|
|
108
|
+
let dynamic;
|
|
109
|
+
let bundles;
|
|
110
|
+
for (const route of app["~routes"]) {
|
|
111
|
+
const [method, path, handler] = route;
|
|
112
|
+
if (!isNativeStaticMethod(method) || !require_utils.isHTMLBundle(handler)) continue;
|
|
113
|
+
if (path.indexOf(":") !== -1 || path.indexOf("*") !== -1) {
|
|
114
|
+
if (!handoff) continue;
|
|
115
|
+
(dynamic ??= /* @__PURE__ */ new Set()).add(method);
|
|
116
|
+
(bundles ??= []).push([
|
|
117
|
+
method,
|
|
118
|
+
path,
|
|
119
|
+
handler
|
|
120
|
+
]);
|
|
121
|
+
} else ((routes ??= require_utils.nullObject())[path] ??= require_utils.nullObject())[method] = handler;
|
|
122
|
+
if (!require_universal_is_production.isProduction() && (route[4] || route[5] || route[6])) console.warn(`[Elysia] ${method} ${path} is an HTML bundle served natively, hooks do not run for it`);
|
|
123
|
+
}
|
|
124
|
+
if (!dynamic) return routes;
|
|
125
|
+
const strictPath = app["~config"]?.strictPath === true;
|
|
126
|
+
const handoffs = [];
|
|
74
127
|
for (const [method, path, handler] of app["~routes"]) {
|
|
75
|
-
if (
|
|
76
|
-
|
|
128
|
+
if (require_utils.isHTMLBundle(handler)) continue;
|
|
129
|
+
const targets = method === "*" ? dynamic : dynamic.has(method) ? [method] : void 0;
|
|
130
|
+
if (!targets) continue;
|
|
131
|
+
for (const variant of expandOptional(path)) {
|
|
132
|
+
const loose = strictPath || variant.endsWith("*") ? variant : require_utils.getLoosePath(variant);
|
|
133
|
+
for (const raw of loose === variant ? [variant] : [variant, loose]) {
|
|
134
|
+
if (!isNativePath(raw)) {
|
|
135
|
+
if (!require_universal_is_production.isProduction()) console.warn(`[Elysia] ${method} ${path} cannot be expressed in Bun's router, so :param / * HTML bundles are not served natively (they would shadow it)`);
|
|
136
|
+
return routes;
|
|
137
|
+
}
|
|
138
|
+
const encoded = encodeURI(raw);
|
|
139
|
+
for (const target of targets) {
|
|
140
|
+
if (!/[^ -~]/.test(raw)) handoffs.push([raw, target]);
|
|
141
|
+
if (encoded !== raw) handoffs.push([encoded, target]);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
77
145
|
}
|
|
146
|
+
for (const [method, path, bundle] of bundles) ((routes ??= require_utils.nullObject())[path] ??= require_utils.nullObject())[method] = bundle;
|
|
147
|
+
for (const [key, method] of handoffs) (routes[key] ??= require_utils.nullObject())[method] ??= handoff;
|
|
78
148
|
return routes;
|
|
79
149
|
}
|
|
80
150
|
function collectStaticRoutes(app) {
|
|
@@ -86,11 +156,13 @@ function collectStaticRoutes(app) {
|
|
|
86
156
|
const length = table?.length ?? 0;
|
|
87
157
|
if (!table || !length) return;
|
|
88
158
|
const { method: methods, path: paths, handler: handlers, flags } = table;
|
|
159
|
+
const isStatic = (i) => isNativeStaticMethod(methods[i]) && (flags[i] & require_route_table.RouteFlag.Dynamic) === 0;
|
|
160
|
+
const isPromotable = (h) => promoteResponses && typeof h !== "function" && !(h instanceof Error) && !(h instanceof Promise);
|
|
89
161
|
let hasCandidate = false;
|
|
90
162
|
for (let i = 0; i < length; i++) {
|
|
91
|
-
if (!
|
|
163
|
+
if (!isStatic(i)) continue;
|
|
92
164
|
const h = handlers[i];
|
|
93
|
-
if (isHTMLBundle(h) ||
|
|
165
|
+
if (require_utils.isHTMLBundle(h) || isPromotable(h)) {
|
|
94
166
|
hasCandidate = true;
|
|
95
167
|
break;
|
|
96
168
|
}
|
|
@@ -99,8 +171,8 @@ function collectStaticRoutes(app) {
|
|
|
99
171
|
const strictPath = frozenRoot["~config"]?.strictPath === true;
|
|
100
172
|
const routeIndex = /* @__PURE__ */ new Map();
|
|
101
173
|
for (let i = 0; i < length; i++) {
|
|
174
|
+
if (!isStatic(i)) continue;
|
|
102
175
|
const method = methods[i];
|
|
103
|
-
if (!isNativeStaticMethod(method) || (flags[i] & require_route_table.RouteFlag.Dynamic) !== 0) continue;
|
|
104
176
|
const path = paths[i];
|
|
105
177
|
let pathsByMethod = routeIndex.get(method);
|
|
106
178
|
if (!pathsByMethod) routeIndex.set(method, pathsByMethod = /* @__PURE__ */ new Map());
|
|
@@ -118,19 +190,18 @@ function collectStaticRoutes(app) {
|
|
|
118
190
|
hasReady = true;
|
|
119
191
|
};
|
|
120
192
|
for (let i = 0; i < length; i++) {
|
|
193
|
+
if (!isStatic(i)) continue;
|
|
121
194
|
const method = methods[i];
|
|
122
|
-
const routeFlags = flags[i];
|
|
123
|
-
if (!isNativeStaticMethod(method) || (routeFlags & require_route_table.RouteFlag.Dynamic) !== 0) continue;
|
|
124
195
|
const pathsByMethod = routeIndex.get(method);
|
|
125
196
|
const path = paths[i];
|
|
126
197
|
if (pathsByMethod.get(path) !== i) continue;
|
|
127
198
|
const h = handlers[i];
|
|
128
199
|
let value;
|
|
129
|
-
if (isHTMLBundle(h)) value = h;
|
|
130
|
-
else if (!
|
|
200
|
+
if (require_utils.isHTMLBundle(h)) value = h;
|
|
201
|
+
else if (!isPromotable(h)) continue;
|
|
131
202
|
else value = require_compile_handler_index.buildNativeStaticResponse(require_route_table.routeRow(table, i), app);
|
|
132
203
|
if (!value) continue;
|
|
133
|
-
const needsEncode = (
|
|
204
|
+
const needsEncode = (flags[i] & require_route_table.RouteFlag.Encode) !== 0;
|
|
134
205
|
add(method, path, value, needsEncode);
|
|
135
206
|
if (!strictPath) {
|
|
136
207
|
const loose = require_utils.getLoosePath(path);
|
|
@@ -141,9 +212,6 @@ function collectStaticRoutes(app) {
|
|
|
141
212
|
return ready;
|
|
142
213
|
}
|
|
143
214
|
const BunAdapter = require_adapter_index.createAdapter({
|
|
144
|
-
name: "bun",
|
|
145
|
-
runtime: "bun",
|
|
146
|
-
isWebStandard: true,
|
|
147
215
|
parse: require_adapter_web_standard_index.WebStandardAdapter.parse,
|
|
148
216
|
response: require_adapter_web_standard_index.WebStandardAdapter.response,
|
|
149
217
|
listen(app, options, callback) {
|
|
@@ -155,18 +223,20 @@ const BunAdapter = require_adapter_index.createAdapter({
|
|
|
155
223
|
return live(request, server);
|
|
156
224
|
});
|
|
157
225
|
}
|
|
158
|
-
const
|
|
159
|
-
|
|
226
|
+
const _options = typeof options === "object" ? {
|
|
227
|
+
...options,
|
|
228
|
+
fetch: gatedFetch
|
|
229
|
+
} : {
|
|
160
230
|
port: +options,
|
|
161
231
|
fetch: gatedFetch
|
|
162
232
|
};
|
|
163
|
-
if (optionsIsObject) _options.fetch = gatedFetch;
|
|
164
233
|
const _config = app["~config"]?.serve;
|
|
165
234
|
const serve = _config ? {
|
|
166
235
|
..._config,
|
|
167
236
|
..._options
|
|
168
237
|
} : _options;
|
|
169
|
-
const
|
|
238
|
+
const handoff = (request, server) => serve.fetch(request, server);
|
|
239
|
+
const htmlRoutes = collectHTMLBundleRoutes(app, app.pending ? void 0 : handoff);
|
|
170
240
|
const server = app.server = Bun.serve(serve.routes || serve.error || htmlRoutes ? {
|
|
171
241
|
...serve,
|
|
172
242
|
error: unavailableFetch,
|
|
@@ -175,11 +245,10 @@ const BunAdapter = require_adapter_index.createAdapter({
|
|
|
175
245
|
let live;
|
|
176
246
|
let cancelled = false;
|
|
177
247
|
let shutdownAttempt;
|
|
178
|
-
let ready;
|
|
179
248
|
let wsLifecycle;
|
|
180
249
|
let modulesReady;
|
|
181
|
-
let built;
|
|
182
250
|
let pendingSetups;
|
|
251
|
+
let setupsSettled;
|
|
183
252
|
const build = () => {
|
|
184
253
|
const fetch = app.fetch;
|
|
185
254
|
let routes;
|
|
@@ -188,6 +257,7 @@ const BunAdapter = require_adapter_index.createAdapter({
|
|
|
188
257
|
} catch (error) {
|
|
189
258
|
console.warn("[Elysia] Native static promotion was skipped:", error);
|
|
190
259
|
}
|
|
260
|
+
routes = collectHTMLBundleRoutes(app, handoff, routes);
|
|
191
261
|
let websocket;
|
|
192
262
|
if (app["~hasWS"]) {
|
|
193
263
|
const resolved = require_generation.resolvedWsOf(app);
|
|
@@ -213,6 +283,7 @@ const BunAdapter = require_adapter_index.createAdapter({
|
|
|
213
283
|
let startupFailure;
|
|
214
284
|
let forceRequested = false;
|
|
215
285
|
const force = Promise.withResolvers();
|
|
286
|
+
const abandon = Promise.withResolvers();
|
|
216
287
|
let forceDone = false;
|
|
217
288
|
let nativeStopped = false;
|
|
218
289
|
let abandoned = false;
|
|
@@ -344,7 +415,10 @@ const BunAdapter = require_adapter_index.createAdapter({
|
|
|
344
415
|
throw error;
|
|
345
416
|
}
|
|
346
417
|
}
|
|
347
|
-
if (pendingSetups)
|
|
418
|
+
if (pendingSetups) {
|
|
419
|
+
setupsSettled = Promise.allSettled(pendingSetups);
|
|
420
|
+
return Promise.all(pendingSetups).then(() => epoch.setup = false);
|
|
421
|
+
}
|
|
348
422
|
epoch.setup = false;
|
|
349
423
|
};
|
|
350
424
|
const stop = (closeActiveConnections, failure) => {
|
|
@@ -352,6 +426,7 @@ const BunAdapter = require_adapter_index.createAdapter({
|
|
|
352
426
|
if (failure) startupFailure ??= failure;
|
|
353
427
|
if (closeActiveConnections === true) {
|
|
354
428
|
force.resolve();
|
|
429
|
+
if (!failure) abandon.resolve();
|
|
355
430
|
if (!forceDone) forceRequested = true;
|
|
356
431
|
}
|
|
357
432
|
cancelled = true;
|
|
@@ -369,6 +444,7 @@ const BunAdapter = require_adapter_index.createAdapter({
|
|
|
369
444
|
outcome = shutdownAttempt = promise;
|
|
370
445
|
const quiescence = quiesce(forceRequested || !published);
|
|
371
446
|
let releasable = false;
|
|
447
|
+
let abandonedSetups;
|
|
372
448
|
(async () => {
|
|
373
449
|
try {
|
|
374
450
|
await Promise.resolve();
|
|
@@ -377,9 +453,10 @@ const BunAdapter = require_adapter_index.createAdapter({
|
|
|
377
453
|
} catch (error) {
|
|
378
454
|
startupFailure ??= { error };
|
|
379
455
|
}
|
|
380
|
-
if (
|
|
381
|
-
const setupResults = await Promise.
|
|
382
|
-
if (!
|
|
456
|
+
if (setupsSettled) {
|
|
457
|
+
const setupResults = await Promise.race([setupsSettled, abandon.promise]);
|
|
458
|
+
if (!setupResults) abandonedSetups = setupsSettled;
|
|
459
|
+
else if (!startupFailure) for (let i = 0; i < setupResults.length; i++) {
|
|
383
460
|
const result = setupResults[i];
|
|
384
461
|
if (result.status === "rejected") {
|
|
385
462
|
startupFailure = { error: result.reason };
|
|
@@ -411,17 +488,17 @@ const BunAdapter = require_adapter_index.createAdapter({
|
|
|
411
488
|
(cleanupFailures ??= []).push(error);
|
|
412
489
|
}
|
|
413
490
|
}
|
|
414
|
-
try {
|
|
415
|
-
await require_utils.disposeDecorators(app);
|
|
416
|
-
} catch (error) {
|
|
417
|
-
(cleanupFailures ??= []).push(error);
|
|
418
|
-
}
|
|
419
491
|
}
|
|
420
492
|
cleanupCompleted = true;
|
|
421
493
|
epochCleanup.length = 0;
|
|
422
494
|
}
|
|
423
495
|
if (cleanupFailures) errors.push(...cleanupFailures);
|
|
424
|
-
|
|
496
|
+
const release = () => releaseLifecycle(app, ext, createdExt, stop, registerCleanup);
|
|
497
|
+
if (releasable && abandonedSetups) abandonedSetups.then((results) => {
|
|
498
|
+
for (const result of results) if (result.status === "rejected") console.error("[Elysia] setup abandoned by stop(true) failed:", result.reason);
|
|
499
|
+
release();
|
|
500
|
+
});
|
|
501
|
+
else if (releasable) release();
|
|
425
502
|
require_utils.throwLifecycleErrors(errors);
|
|
426
503
|
} finally {
|
|
427
504
|
epoch.setup = false;
|
|
@@ -445,7 +522,7 @@ const BunAdapter = require_adapter_index.createAdapter({
|
|
|
445
522
|
return;
|
|
446
523
|
}
|
|
447
524
|
try {
|
|
448
|
-
built
|
|
525
|
+
const built = build();
|
|
449
526
|
live = serve.fetch = withOrigin(built.fetch);
|
|
450
527
|
published = true;
|
|
451
528
|
if (built.websocket) serve.websocket = built.websocket;
|
|
@@ -477,12 +554,13 @@ const BunAdapter = require_adapter_index.createAdapter({
|
|
|
477
554
|
return;
|
|
478
555
|
}
|
|
479
556
|
const setupReady = setup();
|
|
480
|
-
if (setupReady
|
|
557
|
+
if (setupReady) return setupReady.then(publish);
|
|
481
558
|
publish();
|
|
482
559
|
};
|
|
483
560
|
try {
|
|
484
|
-
|
|
485
|
-
|
|
561
|
+
const modules = modulesReady = app.modules;
|
|
562
|
+
const preload = require_type_bridge.preloadTypebox();
|
|
563
|
+
(preload ? Promise.all([modules, preload]) : modules).then(start).catch((error) => stop(true, { error })).catch((error) => {
|
|
486
564
|
console.error("[Elysia] listen() failed:", error);
|
|
487
565
|
if (typeof process !== "undefined") process.exitCode = 1;
|
|
488
566
|
});
|
|
@@ -497,4 +575,4 @@ const BunAdapter = require_adapter_index.createAdapter({
|
|
|
497
575
|
exports.BunAdapter = BunAdapter;
|
|
498
576
|
exports.collectHTMLBundleRoutes = collectHTMLBundleRoutes;
|
|
499
577
|
exports.collectStaticRoutes = collectStaticRoutes;
|
|
500
|
-
exports.isHTMLBundle = isHTMLBundle;
|
|
578
|
+
exports.isHTMLBundle = require_utils.isHTMLBundle;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { createAdapter } from "../index.mjs";
|
|
2
|
-
import {
|
|
2
|
+
import { flattenChain, getLoosePath, isHTMLBundle, isSocketQuiet, nullObject, throwLifecycleErrors } from "../../utils.mjs";
|
|
3
|
+
import { preloadTypebox } from "../../type/bridge.mjs";
|
|
4
|
+
import { isProduction } from "../../universal/is-production.mjs";
|
|
3
5
|
import { WebStandardAdapter } from "../web-standard/index.mjs";
|
|
4
6
|
import { frozenRootOf, resolvedWsOf } from "../../generation.mjs";
|
|
5
7
|
import { origin } from "../origin.mjs";
|
|
@@ -67,13 +69,81 @@ const withOrigin = (fetch) => (request, server) => {
|
|
|
67
69
|
}
|
|
68
70
|
};
|
|
69
71
|
const isNativeStaticMethod = (method) => method === "GET" || method === "POST" || method === "PUT" || method === "DELETE" || method === "PATCH" || method === "HEAD" || method === "OPTIONS";
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
72
|
+
function expandOptional(path) {
|
|
73
|
+
const at = path.indexOf("?");
|
|
74
|
+
if (at === -1) return [path];
|
|
75
|
+
const start = path.lastIndexOf("/", at);
|
|
76
|
+
const rest = path.slice(at + 1);
|
|
77
|
+
return [...expandOptional(path.slice(0, start) + rest), ...expandOptional(path.slice(0, at) + rest)].map((variant) => variant || "/");
|
|
78
|
+
}
|
|
79
|
+
function isNativePath(path) {
|
|
80
|
+
const names = /* @__PURE__ */ new Set();
|
|
81
|
+
const segments = path.split("/");
|
|
82
|
+
for (let i = 0; i < segments.length; i++) {
|
|
83
|
+
const segment = segments[i];
|
|
84
|
+
if (segment.indexOf("*") !== -1) {
|
|
85
|
+
if (segment !== "*" || i !== segments.length - 1) return false;
|
|
86
|
+
} else if (segment.indexOf(":") !== -1) {
|
|
87
|
+
if (!/^:[A-Za-z_$][\w$]*$/.test(segment)) return false;
|
|
88
|
+
if (names.has(segment)) return false;
|
|
89
|
+
names.add(segment);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return true;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* HTML bundles served by Bun's native router.
|
|
96
|
+
*
|
|
97
|
+
* A `:param` / `*` bundle (SPA fallback) matches before `fetch`, so with a
|
|
98
|
+
* `handoff` every other route of that method is registered natively too,
|
|
99
|
+
* handing off to `fetch`: Bun's specificity (exact > param > wildcard) then
|
|
100
|
+
* picks the Elysia route, and only unmatched paths reach the bundle (Elysia's
|
|
101
|
+
* own router leaves these bundles out, see `#buildRouterUnsafe`).
|
|
102
|
+
*
|
|
103
|
+
* All or nothing: when any route cannot be expressed in Bun's router, dynamic
|
|
104
|
+
* bundles are not served natively at all, since that route would be shadowed.
|
|
105
|
+
*/
|
|
106
|
+
function collectHTMLBundleRoutes(app, handoff, routes) {
|
|
107
|
+
let dynamic;
|
|
108
|
+
let bundles;
|
|
109
|
+
for (const route of app["~routes"]) {
|
|
110
|
+
const [method, path, handler] = route;
|
|
111
|
+
if (!isNativeStaticMethod(method) || !isHTMLBundle(handler)) continue;
|
|
112
|
+
if (path.indexOf(":") !== -1 || path.indexOf("*") !== -1) {
|
|
113
|
+
if (!handoff) continue;
|
|
114
|
+
(dynamic ??= /* @__PURE__ */ new Set()).add(method);
|
|
115
|
+
(bundles ??= []).push([
|
|
116
|
+
method,
|
|
117
|
+
path,
|
|
118
|
+
handler
|
|
119
|
+
]);
|
|
120
|
+
} else ((routes ??= nullObject())[path] ??= nullObject())[method] = handler;
|
|
121
|
+
if (!isProduction() && (route[4] || route[5] || route[6])) console.warn(`[Elysia] ${method} ${path} is an HTML bundle served natively, hooks do not run for it`);
|
|
122
|
+
}
|
|
123
|
+
if (!dynamic) return routes;
|
|
124
|
+
const strictPath = app["~config"]?.strictPath === true;
|
|
125
|
+
const handoffs = [];
|
|
73
126
|
for (const [method, path, handler] of app["~routes"]) {
|
|
74
|
-
if (
|
|
75
|
-
|
|
127
|
+
if (isHTMLBundle(handler)) continue;
|
|
128
|
+
const targets = method === "*" ? dynamic : dynamic.has(method) ? [method] : void 0;
|
|
129
|
+
if (!targets) continue;
|
|
130
|
+
for (const variant of expandOptional(path)) {
|
|
131
|
+
const loose = strictPath || variant.endsWith("*") ? variant : getLoosePath(variant);
|
|
132
|
+
for (const raw of loose === variant ? [variant] : [variant, loose]) {
|
|
133
|
+
if (!isNativePath(raw)) {
|
|
134
|
+
if (!isProduction()) console.warn(`[Elysia] ${method} ${path} cannot be expressed in Bun's router, so :param / * HTML bundles are not served natively (they would shadow it)`);
|
|
135
|
+
return routes;
|
|
136
|
+
}
|
|
137
|
+
const encoded = encodeURI(raw);
|
|
138
|
+
for (const target of targets) {
|
|
139
|
+
if (!/[^ -~]/.test(raw)) handoffs.push([raw, target]);
|
|
140
|
+
if (encoded !== raw) handoffs.push([encoded, target]);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
76
144
|
}
|
|
145
|
+
for (const [method, path, bundle] of bundles) ((routes ??= nullObject())[path] ??= nullObject())[method] = bundle;
|
|
146
|
+
for (const [key, method] of handoffs) (routes[key] ??= nullObject())[method] ??= handoff;
|
|
77
147
|
return routes;
|
|
78
148
|
}
|
|
79
149
|
function collectStaticRoutes(app) {
|
|
@@ -85,11 +155,13 @@ function collectStaticRoutes(app) {
|
|
|
85
155
|
const length = table?.length ?? 0;
|
|
86
156
|
if (!table || !length) return;
|
|
87
157
|
const { method: methods, path: paths, handler: handlers, flags } = table;
|
|
158
|
+
const isStatic = (i) => isNativeStaticMethod(methods[i]) && (flags[i] & RouteFlag.Dynamic) === 0;
|
|
159
|
+
const isPromotable = (h) => promoteResponses && typeof h !== "function" && !(h instanceof Error) && !(h instanceof Promise);
|
|
88
160
|
let hasCandidate = false;
|
|
89
161
|
for (let i = 0; i < length; i++) {
|
|
90
|
-
if (!
|
|
162
|
+
if (!isStatic(i)) continue;
|
|
91
163
|
const h = handlers[i];
|
|
92
|
-
if (isHTMLBundle(h) ||
|
|
164
|
+
if (isHTMLBundle(h) || isPromotable(h)) {
|
|
93
165
|
hasCandidate = true;
|
|
94
166
|
break;
|
|
95
167
|
}
|
|
@@ -98,8 +170,8 @@ function collectStaticRoutes(app) {
|
|
|
98
170
|
const strictPath = frozenRoot["~config"]?.strictPath === true;
|
|
99
171
|
const routeIndex = /* @__PURE__ */ new Map();
|
|
100
172
|
for (let i = 0; i < length; i++) {
|
|
173
|
+
if (!isStatic(i)) continue;
|
|
101
174
|
const method = methods[i];
|
|
102
|
-
if (!isNativeStaticMethod(method) || (flags[i] & RouteFlag.Dynamic) !== 0) continue;
|
|
103
175
|
const path = paths[i];
|
|
104
176
|
let pathsByMethod = routeIndex.get(method);
|
|
105
177
|
if (!pathsByMethod) routeIndex.set(method, pathsByMethod = /* @__PURE__ */ new Map());
|
|
@@ -117,19 +189,18 @@ function collectStaticRoutes(app) {
|
|
|
117
189
|
hasReady = true;
|
|
118
190
|
};
|
|
119
191
|
for (let i = 0; i < length; i++) {
|
|
192
|
+
if (!isStatic(i)) continue;
|
|
120
193
|
const method = methods[i];
|
|
121
|
-
const routeFlags = flags[i];
|
|
122
|
-
if (!isNativeStaticMethod(method) || (routeFlags & RouteFlag.Dynamic) !== 0) continue;
|
|
123
194
|
const pathsByMethod = routeIndex.get(method);
|
|
124
195
|
const path = paths[i];
|
|
125
196
|
if (pathsByMethod.get(path) !== i) continue;
|
|
126
197
|
const h = handlers[i];
|
|
127
198
|
let value;
|
|
128
199
|
if (isHTMLBundle(h)) value = h;
|
|
129
|
-
else if (!
|
|
200
|
+
else if (!isPromotable(h)) continue;
|
|
130
201
|
else value = buildNativeStaticResponse(routeRow(table, i), app);
|
|
131
202
|
if (!value) continue;
|
|
132
|
-
const needsEncode = (
|
|
203
|
+
const needsEncode = (flags[i] & RouteFlag.Encode) !== 0;
|
|
133
204
|
add(method, path, value, needsEncode);
|
|
134
205
|
if (!strictPath) {
|
|
135
206
|
const loose = getLoosePath(path);
|
|
@@ -140,9 +211,6 @@ function collectStaticRoutes(app) {
|
|
|
140
211
|
return ready;
|
|
141
212
|
}
|
|
142
213
|
const BunAdapter = createAdapter({
|
|
143
|
-
name: "bun",
|
|
144
|
-
runtime: "bun",
|
|
145
|
-
isWebStandard: true,
|
|
146
214
|
parse: WebStandardAdapter.parse,
|
|
147
215
|
response: WebStandardAdapter.response,
|
|
148
216
|
listen(app, options, callback) {
|
|
@@ -154,18 +222,20 @@ const BunAdapter = createAdapter({
|
|
|
154
222
|
return live(request, server);
|
|
155
223
|
});
|
|
156
224
|
}
|
|
157
|
-
const
|
|
158
|
-
|
|
225
|
+
const _options = typeof options === "object" ? {
|
|
226
|
+
...options,
|
|
227
|
+
fetch: gatedFetch
|
|
228
|
+
} : {
|
|
159
229
|
port: +options,
|
|
160
230
|
fetch: gatedFetch
|
|
161
231
|
};
|
|
162
|
-
if (optionsIsObject) _options.fetch = gatedFetch;
|
|
163
232
|
const _config = app["~config"]?.serve;
|
|
164
233
|
const serve = _config ? {
|
|
165
234
|
..._config,
|
|
166
235
|
..._options
|
|
167
236
|
} : _options;
|
|
168
|
-
const
|
|
237
|
+
const handoff = (request, server) => serve.fetch(request, server);
|
|
238
|
+
const htmlRoutes = collectHTMLBundleRoutes(app, app.pending ? void 0 : handoff);
|
|
169
239
|
const server = app.server = Bun.serve(serve.routes || serve.error || htmlRoutes ? {
|
|
170
240
|
...serve,
|
|
171
241
|
error: unavailableFetch,
|
|
@@ -174,11 +244,10 @@ const BunAdapter = createAdapter({
|
|
|
174
244
|
let live;
|
|
175
245
|
let cancelled = false;
|
|
176
246
|
let shutdownAttempt;
|
|
177
|
-
let ready;
|
|
178
247
|
let wsLifecycle;
|
|
179
248
|
let modulesReady;
|
|
180
|
-
let built;
|
|
181
249
|
let pendingSetups;
|
|
250
|
+
let setupsSettled;
|
|
182
251
|
const build = () => {
|
|
183
252
|
const fetch = app.fetch;
|
|
184
253
|
let routes;
|
|
@@ -187,6 +256,7 @@ const BunAdapter = createAdapter({
|
|
|
187
256
|
} catch (error) {
|
|
188
257
|
console.warn("[Elysia] Native static promotion was skipped:", error);
|
|
189
258
|
}
|
|
259
|
+
routes = collectHTMLBundleRoutes(app, handoff, routes);
|
|
190
260
|
let websocket;
|
|
191
261
|
if (app["~hasWS"]) {
|
|
192
262
|
const resolved = resolvedWsOf(app);
|
|
@@ -212,6 +282,7 @@ const BunAdapter = createAdapter({
|
|
|
212
282
|
let startupFailure;
|
|
213
283
|
let forceRequested = false;
|
|
214
284
|
const force = Promise.withResolvers();
|
|
285
|
+
const abandon = Promise.withResolvers();
|
|
215
286
|
let forceDone = false;
|
|
216
287
|
let nativeStopped = false;
|
|
217
288
|
let abandoned = false;
|
|
@@ -343,7 +414,10 @@ const BunAdapter = createAdapter({
|
|
|
343
414
|
throw error;
|
|
344
415
|
}
|
|
345
416
|
}
|
|
346
|
-
if (pendingSetups)
|
|
417
|
+
if (pendingSetups) {
|
|
418
|
+
setupsSettled = Promise.allSettled(pendingSetups);
|
|
419
|
+
return Promise.all(pendingSetups).then(() => epoch.setup = false);
|
|
420
|
+
}
|
|
347
421
|
epoch.setup = false;
|
|
348
422
|
};
|
|
349
423
|
const stop = (closeActiveConnections, failure) => {
|
|
@@ -351,6 +425,7 @@ const BunAdapter = createAdapter({
|
|
|
351
425
|
if (failure) startupFailure ??= failure;
|
|
352
426
|
if (closeActiveConnections === true) {
|
|
353
427
|
force.resolve();
|
|
428
|
+
if (!failure) abandon.resolve();
|
|
354
429
|
if (!forceDone) forceRequested = true;
|
|
355
430
|
}
|
|
356
431
|
cancelled = true;
|
|
@@ -368,6 +443,7 @@ const BunAdapter = createAdapter({
|
|
|
368
443
|
outcome = shutdownAttempt = promise;
|
|
369
444
|
const quiescence = quiesce(forceRequested || !published);
|
|
370
445
|
let releasable = false;
|
|
446
|
+
let abandonedSetups;
|
|
371
447
|
(async () => {
|
|
372
448
|
try {
|
|
373
449
|
await Promise.resolve();
|
|
@@ -376,9 +452,10 @@ const BunAdapter = createAdapter({
|
|
|
376
452
|
} catch (error) {
|
|
377
453
|
startupFailure ??= { error };
|
|
378
454
|
}
|
|
379
|
-
if (
|
|
380
|
-
const setupResults = await Promise.
|
|
381
|
-
if (!
|
|
455
|
+
if (setupsSettled) {
|
|
456
|
+
const setupResults = await Promise.race([setupsSettled, abandon.promise]);
|
|
457
|
+
if (!setupResults) abandonedSetups = setupsSettled;
|
|
458
|
+
else if (!startupFailure) for (let i = 0; i < setupResults.length; i++) {
|
|
382
459
|
const result = setupResults[i];
|
|
383
460
|
if (result.status === "rejected") {
|
|
384
461
|
startupFailure = { error: result.reason };
|
|
@@ -410,17 +487,17 @@ const BunAdapter = createAdapter({
|
|
|
410
487
|
(cleanupFailures ??= []).push(error);
|
|
411
488
|
}
|
|
412
489
|
}
|
|
413
|
-
try {
|
|
414
|
-
await disposeDecorators(app);
|
|
415
|
-
} catch (error) {
|
|
416
|
-
(cleanupFailures ??= []).push(error);
|
|
417
|
-
}
|
|
418
490
|
}
|
|
419
491
|
cleanupCompleted = true;
|
|
420
492
|
epochCleanup.length = 0;
|
|
421
493
|
}
|
|
422
494
|
if (cleanupFailures) errors.push(...cleanupFailures);
|
|
423
|
-
|
|
495
|
+
const release = () => releaseLifecycle(app, ext, createdExt, stop, registerCleanup);
|
|
496
|
+
if (releasable && abandonedSetups) abandonedSetups.then((results) => {
|
|
497
|
+
for (const result of results) if (result.status === "rejected") console.error("[Elysia] setup abandoned by stop(true) failed:", result.reason);
|
|
498
|
+
release();
|
|
499
|
+
});
|
|
500
|
+
else if (releasable) release();
|
|
424
501
|
throwLifecycleErrors(errors);
|
|
425
502
|
} finally {
|
|
426
503
|
epoch.setup = false;
|
|
@@ -444,7 +521,7 @@ const BunAdapter = createAdapter({
|
|
|
444
521
|
return;
|
|
445
522
|
}
|
|
446
523
|
try {
|
|
447
|
-
built
|
|
524
|
+
const built = build();
|
|
448
525
|
live = serve.fetch = withOrigin(built.fetch);
|
|
449
526
|
published = true;
|
|
450
527
|
if (built.websocket) serve.websocket = built.websocket;
|
|
@@ -476,12 +553,13 @@ const BunAdapter = createAdapter({
|
|
|
476
553
|
return;
|
|
477
554
|
}
|
|
478
555
|
const setupReady = setup();
|
|
479
|
-
if (setupReady
|
|
556
|
+
if (setupReady) return setupReady.then(publish);
|
|
480
557
|
publish();
|
|
481
558
|
};
|
|
482
559
|
try {
|
|
483
|
-
|
|
484
|
-
|
|
560
|
+
const modules = modulesReady = app.modules;
|
|
561
|
+
const preload = preloadTypebox();
|
|
562
|
+
(preload ? Promise.all([modules, preload]) : modules).then(start).catch((error) => stop(true, { error })).catch((error) => {
|
|
485
563
|
console.error("[Elysia] listen() failed:", error);
|
|
486
564
|
if (typeof process !== "undefined") process.exitCode = 1;
|
|
487
565
|
});
|
package/dist/adapter/types.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ListenCallback, Serve } from "../universal/server.js";
|
|
2
|
-
import { MaybePromise } from "../types.js";
|
|
3
2
|
import { Context } from "../context.js";
|
|
3
|
+
import { MaybePromise } from "../types.js";
|
|
4
4
|
import { AnyElysia } from "../base.js";
|
|
5
5
|
|
|
6
6
|
//#region src/adapter/types.d.ts
|
|
@@ -10,25 +10,6 @@ import { AnyElysia } from "../base.js";
|
|
|
10
10
|
* @since 2.0.0
|
|
11
11
|
*/
|
|
12
12
|
interface ElysiaAdapterOptions<App extends AnyElysia | void = void> {
|
|
13
|
-
/**
|
|
14
|
-
* Name of the adapter, preferably runtime
|
|
15
|
-
*/
|
|
16
|
-
name: string;
|
|
17
|
-
/**
|
|
18
|
-
*
|
|
19
|
-
* @param app
|
|
20
|
-
*/
|
|
21
|
-
runtime: 'node' | 'deno' | 'bun' | 'cloudflare-worker' | 'browser' | 'vercel' | 'netlify' | 'lambda' | 'fastly' | 'edge' | 'unknown' | (string & {});
|
|
22
|
-
/**
|
|
23
|
-
* Whether this adapter is web standard
|
|
24
|
-
*/
|
|
25
|
-
isWebStandard: boolean;
|
|
26
|
-
/**
|
|
27
|
-
* Whether this adapter supports WebSocket.
|
|
28
|
-
*
|
|
29
|
-
* `.ws()` throws on non-Bun runtimes unless this is set.
|
|
30
|
-
*/
|
|
31
|
-
websocket?: boolean;
|
|
32
13
|
listen?(app: AnyElysia, options: string | number | Partial<Serve>, callback?: ListenCallback): void;
|
|
33
14
|
parse: {
|
|
34
15
|
json: (context: Context) => MaybePromise<Record<keyof any, undefined> | unknown[]>;
|
|
@@ -36,7 +17,7 @@ interface ElysiaAdapterOptions<App extends AnyElysia | void = void> {
|
|
|
36
17
|
urlencoded: (context: Context) => MaybePromise<Record<string, string | string[]>>;
|
|
37
18
|
arrayBuffer: (context: Context) => MaybePromise<ArrayBuffer>;
|
|
38
19
|
formData: (context: Context) => MaybePromise<Record<string, unknown>>;
|
|
39
|
-
default: (context: Context, contentType: string
|
|
20
|
+
default: (context: Context, contentType: string) => MaybePromise<any>;
|
|
40
21
|
};
|
|
41
22
|
response: {
|
|
42
23
|
/**
|