elysia 2.0.0-beta.15 → 2.0.0-beta.17
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 +16 -2
- package/dist/adapter/bun/index.js +122 -34
- package/dist/adapter/bun/index.mjs +121 -34
- 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 +18 -39
- package/dist/compile/aot-capture.mjs +18 -39
- 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 +5 -5
- 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/constants.d.ts +1 -1
- 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 +12 -0
- package/dist/type/typebox-value-require.js +21 -0
- package/dist/type/typebox-value-require.mjs +19 -0
- package/dist/type/typebox-value.d.ts +7 -6
- package/dist/type/typebox-value.js +35 -4
- package/dist/type/typebox-value.mjs +36 -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.js +43 -77
- package/dist/type/validator/index.mjs +44 -78
- package/dist/type/validator/validator-cache.d.ts +3 -2
- 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 -12
- 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,23 @@
|
|
|
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
|
+
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;
|
|
6
20
|
declare function collectStaticRoutes(app: AnyElysia): Record<string, Record<string, Response | BunHTMLBundlelike>> | undefined;
|
|
7
21
|
declare const BunAdapter: ElysiaAdapterOptions<void>;
|
|
8
22
|
//#endregion
|
|
9
|
-
export { BunAdapter, collectStaticRoutes, isHTMLBundle };
|
|
23
|
+
export { BunAdapter, collectHTMLBundleRoutes, collectStaticRoutes, isHTMLBundle };
|
|
@@ -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,7 +70,83 @@ 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
|
-
|
|
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 = [];
|
|
127
|
+
for (const [method, path, handler] of app["~routes"]) {
|
|
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
|
+
}
|
|
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;
|
|
148
|
+
return routes;
|
|
149
|
+
}
|
|
72
150
|
function collectStaticRoutes(app) {
|
|
73
151
|
app.fetch;
|
|
74
152
|
const frozenRoot = require_generation.frozenRootOf(app);
|
|
@@ -78,11 +156,13 @@ function collectStaticRoutes(app) {
|
|
|
78
156
|
const length = table?.length ?? 0;
|
|
79
157
|
if (!table || !length) return;
|
|
80
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);
|
|
81
161
|
let hasCandidate = false;
|
|
82
162
|
for (let i = 0; i < length; i++) {
|
|
83
|
-
if (!
|
|
163
|
+
if (!isStatic(i)) continue;
|
|
84
164
|
const h = handlers[i];
|
|
85
|
-
if (isHTMLBundle(h) ||
|
|
165
|
+
if (require_utils.isHTMLBundle(h) || isPromotable(h)) {
|
|
86
166
|
hasCandidate = true;
|
|
87
167
|
break;
|
|
88
168
|
}
|
|
@@ -91,8 +171,8 @@ function collectStaticRoutes(app) {
|
|
|
91
171
|
const strictPath = frozenRoot["~config"]?.strictPath === true;
|
|
92
172
|
const routeIndex = /* @__PURE__ */ new Map();
|
|
93
173
|
for (let i = 0; i < length; i++) {
|
|
174
|
+
if (!isStatic(i)) continue;
|
|
94
175
|
const method = methods[i];
|
|
95
|
-
if (!isNativeStaticMethod(method) || (flags[i] & require_route_table.RouteFlag.Dynamic) !== 0) continue;
|
|
96
176
|
const path = paths[i];
|
|
97
177
|
let pathsByMethod = routeIndex.get(method);
|
|
98
178
|
if (!pathsByMethod) routeIndex.set(method, pathsByMethod = /* @__PURE__ */ new Map());
|
|
@@ -110,19 +190,18 @@ function collectStaticRoutes(app) {
|
|
|
110
190
|
hasReady = true;
|
|
111
191
|
};
|
|
112
192
|
for (let i = 0; i < length; i++) {
|
|
193
|
+
if (!isStatic(i)) continue;
|
|
113
194
|
const method = methods[i];
|
|
114
|
-
const routeFlags = flags[i];
|
|
115
|
-
if (!isNativeStaticMethod(method) || (routeFlags & require_route_table.RouteFlag.Dynamic) !== 0) continue;
|
|
116
195
|
const pathsByMethod = routeIndex.get(method);
|
|
117
196
|
const path = paths[i];
|
|
118
197
|
if (pathsByMethod.get(path) !== i) continue;
|
|
119
198
|
const h = handlers[i];
|
|
120
199
|
let value;
|
|
121
|
-
if (isHTMLBundle(h)) value = h;
|
|
122
|
-
else if (!
|
|
200
|
+
if (require_utils.isHTMLBundle(h)) value = h;
|
|
201
|
+
else if (!isPromotable(h)) continue;
|
|
123
202
|
else value = require_compile_handler_index.buildNativeStaticResponse(require_route_table.routeRow(table, i), app);
|
|
124
203
|
if (!value) continue;
|
|
125
|
-
const needsEncode = (
|
|
204
|
+
const needsEncode = (flags[i] & require_route_table.RouteFlag.Encode) !== 0;
|
|
126
205
|
add(method, path, value, needsEncode);
|
|
127
206
|
if (!strictPath) {
|
|
128
207
|
const loose = require_utils.getLoosePath(path);
|
|
@@ -133,9 +212,6 @@ function collectStaticRoutes(app) {
|
|
|
133
212
|
return ready;
|
|
134
213
|
}
|
|
135
214
|
const BunAdapter = require_adapter_index.createAdapter({
|
|
136
|
-
name: "bun",
|
|
137
|
-
runtime: "bun",
|
|
138
|
-
isWebStandard: true,
|
|
139
215
|
parse: require_adapter_web_standard_index.WebStandardAdapter.parse,
|
|
140
216
|
response: require_adapter_web_standard_index.WebStandardAdapter.response,
|
|
141
217
|
listen(app, options, callback) {
|
|
@@ -147,30 +223,32 @@ const BunAdapter = require_adapter_index.createAdapter({
|
|
|
147
223
|
return live(request, server);
|
|
148
224
|
});
|
|
149
225
|
}
|
|
150
|
-
const
|
|
151
|
-
|
|
226
|
+
const _options = typeof options === "object" ? {
|
|
227
|
+
...options,
|
|
228
|
+
fetch: gatedFetch
|
|
229
|
+
} : {
|
|
152
230
|
port: +options,
|
|
153
231
|
fetch: gatedFetch
|
|
154
232
|
};
|
|
155
|
-
if (optionsIsObject) _options.fetch = gatedFetch;
|
|
156
233
|
const _config = app["~config"]?.serve;
|
|
157
234
|
const serve = _config ? {
|
|
158
235
|
..._config,
|
|
159
236
|
..._options
|
|
160
237
|
} : _options;
|
|
161
|
-
const
|
|
238
|
+
const handoff = (request, server) => serve.fetch(request, server);
|
|
239
|
+
const htmlRoutes = collectHTMLBundleRoutes(app, app.pending ? void 0 : handoff);
|
|
240
|
+
const server = app.server = Bun.serve(serve.routes || serve.error || htmlRoutes ? {
|
|
162
241
|
...serve,
|
|
163
242
|
error: unavailableFetch,
|
|
164
|
-
routes: {}
|
|
243
|
+
routes: htmlRoutes ?? {}
|
|
165
244
|
} : serve);
|
|
166
245
|
let live;
|
|
167
246
|
let cancelled = false;
|
|
168
247
|
let shutdownAttempt;
|
|
169
|
-
let ready;
|
|
170
248
|
let wsLifecycle;
|
|
171
249
|
let modulesReady;
|
|
172
|
-
let built;
|
|
173
250
|
let pendingSetups;
|
|
251
|
+
let setupsSettled;
|
|
174
252
|
const build = () => {
|
|
175
253
|
const fetch = app.fetch;
|
|
176
254
|
let routes;
|
|
@@ -179,6 +257,7 @@ const BunAdapter = require_adapter_index.createAdapter({
|
|
|
179
257
|
} catch (error) {
|
|
180
258
|
console.warn("[Elysia] Native static promotion was skipped:", error);
|
|
181
259
|
}
|
|
260
|
+
routes = collectHTMLBundleRoutes(app, handoff, routes);
|
|
182
261
|
let websocket;
|
|
183
262
|
if (app["~hasWS"]) {
|
|
184
263
|
const resolved = require_generation.resolvedWsOf(app);
|
|
@@ -204,6 +283,7 @@ const BunAdapter = require_adapter_index.createAdapter({
|
|
|
204
283
|
let startupFailure;
|
|
205
284
|
let forceRequested = false;
|
|
206
285
|
const force = Promise.withResolvers();
|
|
286
|
+
const abandon = Promise.withResolvers();
|
|
207
287
|
let forceDone = false;
|
|
208
288
|
let nativeStopped = false;
|
|
209
289
|
let abandoned = false;
|
|
@@ -335,7 +415,10 @@ const BunAdapter = require_adapter_index.createAdapter({
|
|
|
335
415
|
throw error;
|
|
336
416
|
}
|
|
337
417
|
}
|
|
338
|
-
if (pendingSetups)
|
|
418
|
+
if (pendingSetups) {
|
|
419
|
+
setupsSettled = Promise.allSettled(pendingSetups);
|
|
420
|
+
return Promise.all(pendingSetups).then(() => epoch.setup = false);
|
|
421
|
+
}
|
|
339
422
|
epoch.setup = false;
|
|
340
423
|
};
|
|
341
424
|
const stop = (closeActiveConnections, failure) => {
|
|
@@ -343,6 +426,7 @@ const BunAdapter = require_adapter_index.createAdapter({
|
|
|
343
426
|
if (failure) startupFailure ??= failure;
|
|
344
427
|
if (closeActiveConnections === true) {
|
|
345
428
|
force.resolve();
|
|
429
|
+
if (!failure) abandon.resolve();
|
|
346
430
|
if (!forceDone) forceRequested = true;
|
|
347
431
|
}
|
|
348
432
|
cancelled = true;
|
|
@@ -360,6 +444,7 @@ const BunAdapter = require_adapter_index.createAdapter({
|
|
|
360
444
|
outcome = shutdownAttempt = promise;
|
|
361
445
|
const quiescence = quiesce(forceRequested || !published);
|
|
362
446
|
let releasable = false;
|
|
447
|
+
let abandonedSetups;
|
|
363
448
|
(async () => {
|
|
364
449
|
try {
|
|
365
450
|
await Promise.resolve();
|
|
@@ -368,9 +453,10 @@ const BunAdapter = require_adapter_index.createAdapter({
|
|
|
368
453
|
} catch (error) {
|
|
369
454
|
startupFailure ??= { error };
|
|
370
455
|
}
|
|
371
|
-
if (
|
|
372
|
-
const setupResults = await Promise.
|
|
373
|
-
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++) {
|
|
374
460
|
const result = setupResults[i];
|
|
375
461
|
if (result.status === "rejected") {
|
|
376
462
|
startupFailure = { error: result.reason };
|
|
@@ -402,17 +488,17 @@ const BunAdapter = require_adapter_index.createAdapter({
|
|
|
402
488
|
(cleanupFailures ??= []).push(error);
|
|
403
489
|
}
|
|
404
490
|
}
|
|
405
|
-
try {
|
|
406
|
-
await require_utils.disposeDecorators(app);
|
|
407
|
-
} catch (error) {
|
|
408
|
-
(cleanupFailures ??= []).push(error);
|
|
409
|
-
}
|
|
410
491
|
}
|
|
411
492
|
cleanupCompleted = true;
|
|
412
493
|
epochCleanup.length = 0;
|
|
413
494
|
}
|
|
414
495
|
if (cleanupFailures) errors.push(...cleanupFailures);
|
|
415
|
-
|
|
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();
|
|
416
502
|
require_utils.throwLifecycleErrors(errors);
|
|
417
503
|
} finally {
|
|
418
504
|
epoch.setup = false;
|
|
@@ -436,7 +522,7 @@ const BunAdapter = require_adapter_index.createAdapter({
|
|
|
436
522
|
return;
|
|
437
523
|
}
|
|
438
524
|
try {
|
|
439
|
-
built
|
|
525
|
+
const built = build();
|
|
440
526
|
live = serve.fetch = withOrigin(built.fetch);
|
|
441
527
|
published = true;
|
|
442
528
|
if (built.websocket) serve.websocket = built.websocket;
|
|
@@ -468,12 +554,13 @@ const BunAdapter = require_adapter_index.createAdapter({
|
|
|
468
554
|
return;
|
|
469
555
|
}
|
|
470
556
|
const setupReady = setup();
|
|
471
|
-
if (setupReady
|
|
557
|
+
if (setupReady) return setupReady.then(publish);
|
|
472
558
|
publish();
|
|
473
559
|
};
|
|
474
560
|
try {
|
|
475
|
-
|
|
476
|
-
|
|
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) => {
|
|
477
564
|
console.error("[Elysia] listen() failed:", error);
|
|
478
565
|
if (typeof process !== "undefined") process.exitCode = 1;
|
|
479
566
|
});
|
|
@@ -486,5 +573,6 @@ const BunAdapter = require_adapter_index.createAdapter({
|
|
|
486
573
|
|
|
487
574
|
//#endregion
|
|
488
575
|
exports.BunAdapter = BunAdapter;
|
|
576
|
+
exports.collectHTMLBundleRoutes = collectHTMLBundleRoutes;
|
|
489
577
|
exports.collectStaticRoutes = collectStaticRoutes;
|
|
490
|
-
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,7 +69,83 @@ 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
|
-
|
|
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 = [];
|
|
126
|
+
for (const [method, path, handler] of app["~routes"]) {
|
|
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
|
+
}
|
|
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;
|
|
147
|
+
return routes;
|
|
148
|
+
}
|
|
71
149
|
function collectStaticRoutes(app) {
|
|
72
150
|
app.fetch;
|
|
73
151
|
const frozenRoot = frozenRootOf(app);
|
|
@@ -77,11 +155,13 @@ function collectStaticRoutes(app) {
|
|
|
77
155
|
const length = table?.length ?? 0;
|
|
78
156
|
if (!table || !length) return;
|
|
79
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);
|
|
80
160
|
let hasCandidate = false;
|
|
81
161
|
for (let i = 0; i < length; i++) {
|
|
82
|
-
if (!
|
|
162
|
+
if (!isStatic(i)) continue;
|
|
83
163
|
const h = handlers[i];
|
|
84
|
-
if (isHTMLBundle(h) ||
|
|
164
|
+
if (isHTMLBundle(h) || isPromotable(h)) {
|
|
85
165
|
hasCandidate = true;
|
|
86
166
|
break;
|
|
87
167
|
}
|
|
@@ -90,8 +170,8 @@ function collectStaticRoutes(app) {
|
|
|
90
170
|
const strictPath = frozenRoot["~config"]?.strictPath === true;
|
|
91
171
|
const routeIndex = /* @__PURE__ */ new Map();
|
|
92
172
|
for (let i = 0; i < length; i++) {
|
|
173
|
+
if (!isStatic(i)) continue;
|
|
93
174
|
const method = methods[i];
|
|
94
|
-
if (!isNativeStaticMethod(method) || (flags[i] & RouteFlag.Dynamic) !== 0) continue;
|
|
95
175
|
const path = paths[i];
|
|
96
176
|
let pathsByMethod = routeIndex.get(method);
|
|
97
177
|
if (!pathsByMethod) routeIndex.set(method, pathsByMethod = /* @__PURE__ */ new Map());
|
|
@@ -109,19 +189,18 @@ function collectStaticRoutes(app) {
|
|
|
109
189
|
hasReady = true;
|
|
110
190
|
};
|
|
111
191
|
for (let i = 0; i < length; i++) {
|
|
192
|
+
if (!isStatic(i)) continue;
|
|
112
193
|
const method = methods[i];
|
|
113
|
-
const routeFlags = flags[i];
|
|
114
|
-
if (!isNativeStaticMethod(method) || (routeFlags & RouteFlag.Dynamic) !== 0) continue;
|
|
115
194
|
const pathsByMethod = routeIndex.get(method);
|
|
116
195
|
const path = paths[i];
|
|
117
196
|
if (pathsByMethod.get(path) !== i) continue;
|
|
118
197
|
const h = handlers[i];
|
|
119
198
|
let value;
|
|
120
199
|
if (isHTMLBundle(h)) value = h;
|
|
121
|
-
else if (!
|
|
200
|
+
else if (!isPromotable(h)) continue;
|
|
122
201
|
else value = buildNativeStaticResponse(routeRow(table, i), app);
|
|
123
202
|
if (!value) continue;
|
|
124
|
-
const needsEncode = (
|
|
203
|
+
const needsEncode = (flags[i] & RouteFlag.Encode) !== 0;
|
|
125
204
|
add(method, path, value, needsEncode);
|
|
126
205
|
if (!strictPath) {
|
|
127
206
|
const loose = getLoosePath(path);
|
|
@@ -132,9 +211,6 @@ function collectStaticRoutes(app) {
|
|
|
132
211
|
return ready;
|
|
133
212
|
}
|
|
134
213
|
const BunAdapter = createAdapter({
|
|
135
|
-
name: "bun",
|
|
136
|
-
runtime: "bun",
|
|
137
|
-
isWebStandard: true,
|
|
138
214
|
parse: WebStandardAdapter.parse,
|
|
139
215
|
response: WebStandardAdapter.response,
|
|
140
216
|
listen(app, options, callback) {
|
|
@@ -146,30 +222,32 @@ const BunAdapter = createAdapter({
|
|
|
146
222
|
return live(request, server);
|
|
147
223
|
});
|
|
148
224
|
}
|
|
149
|
-
const
|
|
150
|
-
|
|
225
|
+
const _options = typeof options === "object" ? {
|
|
226
|
+
...options,
|
|
227
|
+
fetch: gatedFetch
|
|
228
|
+
} : {
|
|
151
229
|
port: +options,
|
|
152
230
|
fetch: gatedFetch
|
|
153
231
|
};
|
|
154
|
-
if (optionsIsObject) _options.fetch = gatedFetch;
|
|
155
232
|
const _config = app["~config"]?.serve;
|
|
156
233
|
const serve = _config ? {
|
|
157
234
|
..._config,
|
|
158
235
|
..._options
|
|
159
236
|
} : _options;
|
|
160
|
-
const
|
|
237
|
+
const handoff = (request, server) => serve.fetch(request, server);
|
|
238
|
+
const htmlRoutes = collectHTMLBundleRoutes(app, app.pending ? void 0 : handoff);
|
|
239
|
+
const server = app.server = Bun.serve(serve.routes || serve.error || htmlRoutes ? {
|
|
161
240
|
...serve,
|
|
162
241
|
error: unavailableFetch,
|
|
163
|
-
routes: {}
|
|
242
|
+
routes: htmlRoutes ?? {}
|
|
164
243
|
} : serve);
|
|
165
244
|
let live;
|
|
166
245
|
let cancelled = false;
|
|
167
246
|
let shutdownAttempt;
|
|
168
|
-
let ready;
|
|
169
247
|
let wsLifecycle;
|
|
170
248
|
let modulesReady;
|
|
171
|
-
let built;
|
|
172
249
|
let pendingSetups;
|
|
250
|
+
let setupsSettled;
|
|
173
251
|
const build = () => {
|
|
174
252
|
const fetch = app.fetch;
|
|
175
253
|
let routes;
|
|
@@ -178,6 +256,7 @@ const BunAdapter = createAdapter({
|
|
|
178
256
|
} catch (error) {
|
|
179
257
|
console.warn("[Elysia] Native static promotion was skipped:", error);
|
|
180
258
|
}
|
|
259
|
+
routes = collectHTMLBundleRoutes(app, handoff, routes);
|
|
181
260
|
let websocket;
|
|
182
261
|
if (app["~hasWS"]) {
|
|
183
262
|
const resolved = resolvedWsOf(app);
|
|
@@ -203,6 +282,7 @@ const BunAdapter = createAdapter({
|
|
|
203
282
|
let startupFailure;
|
|
204
283
|
let forceRequested = false;
|
|
205
284
|
const force = Promise.withResolvers();
|
|
285
|
+
const abandon = Promise.withResolvers();
|
|
206
286
|
let forceDone = false;
|
|
207
287
|
let nativeStopped = false;
|
|
208
288
|
let abandoned = false;
|
|
@@ -334,7 +414,10 @@ const BunAdapter = createAdapter({
|
|
|
334
414
|
throw error;
|
|
335
415
|
}
|
|
336
416
|
}
|
|
337
|
-
if (pendingSetups)
|
|
417
|
+
if (pendingSetups) {
|
|
418
|
+
setupsSettled = Promise.allSettled(pendingSetups);
|
|
419
|
+
return Promise.all(pendingSetups).then(() => epoch.setup = false);
|
|
420
|
+
}
|
|
338
421
|
epoch.setup = false;
|
|
339
422
|
};
|
|
340
423
|
const stop = (closeActiveConnections, failure) => {
|
|
@@ -342,6 +425,7 @@ const BunAdapter = createAdapter({
|
|
|
342
425
|
if (failure) startupFailure ??= failure;
|
|
343
426
|
if (closeActiveConnections === true) {
|
|
344
427
|
force.resolve();
|
|
428
|
+
if (!failure) abandon.resolve();
|
|
345
429
|
if (!forceDone) forceRequested = true;
|
|
346
430
|
}
|
|
347
431
|
cancelled = true;
|
|
@@ -359,6 +443,7 @@ const BunAdapter = createAdapter({
|
|
|
359
443
|
outcome = shutdownAttempt = promise;
|
|
360
444
|
const quiescence = quiesce(forceRequested || !published);
|
|
361
445
|
let releasable = false;
|
|
446
|
+
let abandonedSetups;
|
|
362
447
|
(async () => {
|
|
363
448
|
try {
|
|
364
449
|
await Promise.resolve();
|
|
@@ -367,9 +452,10 @@ const BunAdapter = createAdapter({
|
|
|
367
452
|
} catch (error) {
|
|
368
453
|
startupFailure ??= { error };
|
|
369
454
|
}
|
|
370
|
-
if (
|
|
371
|
-
const setupResults = await Promise.
|
|
372
|
-
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++) {
|
|
373
459
|
const result = setupResults[i];
|
|
374
460
|
if (result.status === "rejected") {
|
|
375
461
|
startupFailure = { error: result.reason };
|
|
@@ -401,17 +487,17 @@ const BunAdapter = createAdapter({
|
|
|
401
487
|
(cleanupFailures ??= []).push(error);
|
|
402
488
|
}
|
|
403
489
|
}
|
|
404
|
-
try {
|
|
405
|
-
await disposeDecorators(app);
|
|
406
|
-
} catch (error) {
|
|
407
|
-
(cleanupFailures ??= []).push(error);
|
|
408
|
-
}
|
|
409
490
|
}
|
|
410
491
|
cleanupCompleted = true;
|
|
411
492
|
epochCleanup.length = 0;
|
|
412
493
|
}
|
|
413
494
|
if (cleanupFailures) errors.push(...cleanupFailures);
|
|
414
|
-
|
|
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();
|
|
415
501
|
throwLifecycleErrors(errors);
|
|
416
502
|
} finally {
|
|
417
503
|
epoch.setup = false;
|
|
@@ -435,7 +521,7 @@ const BunAdapter = createAdapter({
|
|
|
435
521
|
return;
|
|
436
522
|
}
|
|
437
523
|
try {
|
|
438
|
-
built
|
|
524
|
+
const built = build();
|
|
439
525
|
live = serve.fetch = withOrigin(built.fetch);
|
|
440
526
|
published = true;
|
|
441
527
|
if (built.websocket) serve.websocket = built.websocket;
|
|
@@ -467,12 +553,13 @@ const BunAdapter = createAdapter({
|
|
|
467
553
|
return;
|
|
468
554
|
}
|
|
469
555
|
const setupReady = setup();
|
|
470
|
-
if (setupReady
|
|
556
|
+
if (setupReady) return setupReady.then(publish);
|
|
471
557
|
publish();
|
|
472
558
|
};
|
|
473
559
|
try {
|
|
474
|
-
|
|
475
|
-
|
|
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) => {
|
|
476
563
|
console.error("[Elysia] listen() failed:", error);
|
|
477
564
|
if (typeof process !== "undefined") process.exitCode = 1;
|
|
478
565
|
});
|
|
@@ -484,4 +571,4 @@ const BunAdapter = createAdapter({
|
|
|
484
571
|
});
|
|
485
572
|
|
|
486
573
|
//#endregion
|
|
487
|
-
export { BunAdapter, collectStaticRoutes, isHTMLBundle };
|
|
574
|
+
export { BunAdapter, collectHTMLBundleRoutes, collectStaticRoutes, isHTMLBundle };
|
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
|
/**
|