elysia 2.0.0-beta.2 → 2.0.0-beta.21
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 +18 -2
- package/dist/adapter/bun/index.js +467 -110
- package/dist/adapter/bun/index.mjs +467 -112
- package/dist/adapter/types.d.ts +2 -21
- package/dist/adapter/utils.d.ts +14 -3
- package/dist/adapter/utils.js +146 -87
- package/dist/adapter/utils.mjs +148 -90
- package/dist/adapter/web-standard/handler.d.ts +1 -1
- package/dist/adapter/web-standard/handler.js +47 -36
- package/dist/adapter/web-standard/handler.mjs +48 -37
- 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 +99 -67
- package/dist/base.js +678 -510
- package/dist/base.mjs +682 -514
- package/dist/compile/aot-capture.d.ts +2 -13
- package/dist/compile/aot-capture.js +26 -69
- package/dist/compile/aot-capture.mjs +28 -67
- package/dist/compile/aot-emit.d.ts +9 -7
- package/dist/compile/aot-emit.js +42 -19
- package/dist/compile/aot-emit.mjs +42 -20
- package/dist/compile/aot.d.ts +17 -19
- package/dist/compile/aot.js +41 -51
- package/dist/compile/aot.mjs +39 -49
- package/dist/compile/handler/descriptor.d.ts +9 -12
- package/dist/compile/handler/descriptor.js +19 -44
- package/dist/compile/handler/descriptor.mjs +20 -42
- package/dist/compile/handler/frozen-validator.d.ts +5 -10
- package/dist/compile/handler/frozen-validator.js +55 -105
- package/dist/compile/handler/frozen-validator.mjs +53 -105
- package/dist/compile/handler/index.d.ts +7 -5
- package/dist/compile/handler/index.js +270 -111
- package/dist/compile/handler/index.mjs +270 -113
- package/dist/compile/handler/jit.d.ts +19 -17
- package/dist/compile/handler/jit.js +222 -149
- package/dist/compile/handler/jit.mjs +224 -152
- package/dist/compile/handler/params.d.ts +1 -4
- package/dist/compile/handler/params.js +10 -5
- package/dist/compile/handler/params.mjs +14 -8
- package/dist/compile/handler/reconstruct.d.ts +2 -2
- package/dist/compile/handler/reconstruct.js +6 -4
- package/dist/compile/handler/reconstruct.mjs +6 -4
- package/dist/compile/handler/static-clone-resolver.d.ts +6 -0
- package/dist/compile/handler/static-clone-resolver.js +8 -0
- package/dist/compile/handler/static-clone-resolver.mjs +7 -0
- package/dist/compile/handler/utils.d.ts +22 -11
- package/dist/compile/handler/utils.js +159 -253
- package/dist/compile/handler/utils.mjs +155 -252
- package/dist/compile/jit-probe.d.ts +2 -2
- 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/compile/utils.js +7 -4
- package/dist/compile/utils.mjs +7 -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 +14 -4
- package/dist/context.js +17 -32
- package/dist/context.mjs +19 -34
- package/dist/cookie/config.d.ts +7 -2
- package/dist/cookie/config.js +76 -16
- package/dist/cookie/config.mjs +77 -18
- package/dist/cookie/cookie.d.ts +1 -1
- package/dist/cookie/cookie.js +8 -10
- package/dist/cookie/cookie.mjs +8 -10
- package/dist/cookie/crypto.d.ts +8 -7
- package/dist/cookie/crypto.js +51 -40
- package/dist/cookie/crypto.mjs +51 -41
- package/dist/cookie/error.d.ts +1 -2
- package/dist/cookie/error.js +6 -4
- package/dist/cookie/error.mjs +6 -4
- package/dist/cookie/lib.js +7 -2
- package/dist/cookie/lib.mjs +7 -2
- package/dist/cookie/serialize.js +1 -1
- package/dist/cookie/serialize.mjs +1 -1
- package/dist/cookie/types.d.ts +10 -0
- package/dist/cookie/utils.d.ts +4 -8
- package/dist/cookie/utils.js +86 -52
- package/dist/cookie/utils.mjs +89 -54
- package/dist/error.d.ts +113 -103
- package/dist/error.js +181 -117
- package/dist/error.mjs +179 -118
- package/dist/generation.d.ts +2 -2
- package/dist/handler/error.d.ts +26 -15
- package/dist/handler/error.js +77 -96
- package/dist/handler/error.mjs +74 -97
- package/dist/handler/fetch.js +87 -108
- package/dist/handler/fetch.mjs +89 -110
- package/dist/handler/utils.d.ts +12 -6
- package/dist/handler/utils.js +84 -28
- package/dist/handler/utils.mjs +80 -28
- package/dist/index.d.ts +12 -12
- package/dist/index.js +2 -9
- package/dist/index.mjs +1 -1
- 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.d.ts +8 -1
- package/dist/plugin/aot/bun.js +16 -9
- package/dist/plugin/aot/bun.mjs +17 -10
- package/dist/plugin/aot/core.d.ts +52 -60
- package/dist/plugin/aot/core.js +208 -109
- package/dist/plugin/aot/core.mjs +205 -111
- package/dist/plugin/aot/esbuild.js +8 -5
- package/dist/plugin/aot/esbuild.mjs +9 -6
- package/dist/plugin/aot/hooks.d.ts +6 -17
- package/dist/plugin/aot/hooks.js +36 -14
- package/dist/plugin/aot/hooks.mjs +37 -16
- 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 +6 -42
- package/dist/plugin/aot/source.js +71 -71
- package/dist/plugin/aot/source.mjs +72 -72
- 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/aot/worker.js +2 -2
- package/dist/plugin/aot/worker.mjs +2 -2
- 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/route-table.d.ts +3 -0
- package/dist/route-table.js +16 -11
- package/dist/route-table.mjs +16 -11
- package/dist/schema-snapshot.d.ts +0 -4
- package/dist/schema-snapshot.js +32 -49
- package/dist/schema-snapshot.mjs +32 -49
- package/dist/sucrose.d.ts +6 -55
- package/dist/sucrose.js +103 -731
- package/dist/sucrose.mjs +102 -724
- package/dist/trace.d.ts +5 -8
- package/dist/trace.js +23 -134
- package/dist/trace.mjs +24 -135
- package/dist/type/bridge-live.d.ts +4 -2
- package/dist/type/bridge-live.js +6 -3
- package/dist/type/bridge-live.mjs +4 -2
- package/dist/type/bridge.d.ts +6 -4
- package/dist/type/bridge.js +17 -9
- package/dist/type/bridge.mjs +5 -3
- package/dist/type/coerce-plan.d.ts +5 -5
- package/dist/type/coerce-plan.js +41 -39
- package/dist/type/coerce-plan.mjs +43 -39
- package/dist/type/coerce.d.ts +3 -7
- package/dist/type/coerce.js +18 -75
- package/dist/type/coerce.mjs +19 -76
- package/dist/type/compat.d.ts +3 -0
- package/dist/type/compat.js +23 -14
- package/dist/type/compat.mjs +20 -10
- package/dist/type/elysia/array-buffer.d.ts +4 -1
- package/dist/type/elysia/array-buffer.js +17 -17
- package/dist/type/elysia/array-buffer.mjs +17 -17
- package/dist/type/elysia/array-string.js +2 -40
- package/dist/type/elysia/array-string.mjs +2 -39
- package/dist/type/elysia/array.js +5 -9
- package/dist/type/elysia/array.mjs +5 -9
- package/dist/type/elysia/boolean-string.js +2 -3
- package/dist/type/elysia/boolean-string.mjs +1 -1
- package/dist/type/elysia/boolean.js +3 -12
- package/dist/type/elysia/boolean.mjs +3 -11
- package/dist/type/elysia/cookie.d.ts +3 -4
- package/dist/type/elysia/cookie.js +5 -15
- package/dist/type/elysia/cookie.mjs +5 -15
- package/dist/type/elysia/date.js +13 -20
- package/dist/type/elysia/date.mjs +10 -16
- package/dist/type/elysia/file-type.d.ts +11 -4
- package/dist/type/elysia/file-type.js +17 -2
- package/dist/type/elysia/file-type.mjs +17 -3
- package/dist/type/elysia/file.d.ts +1 -3
- package/dist/type/elysia/file.js +11 -27
- package/dist/type/elysia/file.mjs +11 -12
- package/dist/type/elysia/files.js +7 -11
- package/dist/type/elysia/files.mjs +7 -10
- package/dist/type/elysia/form.js +2 -3
- package/dist/type/elysia/form.mjs +3 -3
- package/dist/type/elysia/integer-string.d.ts +1 -1
- package/dist/type/elysia/integer-string.js +4 -30
- package/dist/type/elysia/integer-string.mjs +5 -30
- package/dist/type/elysia/integer.js +3 -12
- package/dist/type/elysia/integer.mjs +3 -11
- 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/keep-config.d.ts +14 -0
- package/dist/type/elysia/keep-config.js +62 -0
- package/dist/type/elysia/keep-config.mjs +53 -0
- package/dist/type/elysia/maybe-empty.js +3 -4
- package/dist/type/elysia/maybe-empty.mjs +1 -1
- package/dist/type/elysia/nullable.js +2 -3
- package/dist/type/elysia/nullable.mjs +1 -1
- package/dist/type/elysia/number.d.ts +2 -1
- package/dist/type/elysia/number.js +19 -11
- package/dist/type/elysia/number.mjs +18 -10
- package/dist/type/elysia/numeric-enum.d.ts +1 -1
- package/dist/type/elysia/numeric-enum.js +4 -5
- package/dist/type/elysia/numeric-enum.mjs +3 -3
- package/dist/type/elysia/numeric.d.ts +4 -2
- package/dist/type/elysia/numeric.js +20 -17
- package/dist/type/elysia/numeric.mjs +19 -16
- package/dist/type/elysia/object-string.js +2 -37
- package/dist/type/elysia/object-string.mjs +2 -36
- 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/problem.d.ts +20 -0
- package/dist/type/elysia/problem.js +25 -0
- package/dist/type/elysia/problem.mjs +24 -0
- package/dist/type/elysia/string.js +4 -3
- package/dist/type/elysia/string.mjs +4 -2
- package/dist/type/elysia/uint8-array.d.ts +1 -1
- package/dist/type/elysia/uint8-array.js +5 -20
- package/dist/type/elysia/uint8-array.mjs +5 -19
- package/dist/type/elysia/union-enum.js +7 -8
- package/dist/type/elysia/union-enum.mjs +6 -6
- 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 +10 -21
- package/dist/type/elysia/utils.mjs +7 -15
- package/dist/type/exports.d.ts +4 -2
- package/dist/type/exports.js +23 -2
- package/dist/type/exports.mjs +11 -2
- package/dist/type/index.d.ts +10 -2
- package/dist/type/index.js +62 -15
- package/dist/type/index.mjs +65 -11
- package/dist/type/shared.d.ts +3 -9
- package/dist/type/shared.js +44 -97
- package/dist/type/shared.mjs +43 -97
- 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-system-lite.d.ts +2 -0
- package/dist/type/typebox-system-lite.js +34 -0
- package/dist/type/typebox-system-lite.mjs +3 -0
- package/dist/type/typebox-system-require.d.ts +7 -0
- package/dist/type/typebox-system-require.js +24 -0
- package/dist/type/typebox-system-require.mjs +23 -0
- package/dist/type/typebox-type-live.d.ts +11 -0
- package/dist/type/typebox-type-live.js +45 -0
- package/dist/type/typebox-type-live.mjs +20 -0
- package/dist/type/typebox-type.d.ts +34 -0
- package/dist/type/typebox-type.js +199 -0
- package/dist/type/typebox-type.mjs +86 -0
- package/dist/type/typebox-value-live.d.ts +11 -0
- package/dist/type/typebox-value-live.js +31 -0
- package/dist/type/typebox-value-live.mjs +13 -0
- package/dist/type/typebox-value-ops.d.ts +4 -0
- package/dist/type/typebox-value-ops.js +90 -0
- package/dist/type/typebox-value-ops.mjs +5 -0
- package/dist/type/typebox-value-require.d.ts +8 -0
- package/dist/type/typebox-value-require.js +28 -0
- package/dist/type/typebox-value-require.mjs +25 -0
- package/dist/type/typebox-value.d.ts +35 -0
- package/dist/type/typebox-value.js +161 -0
- package/dist/type/typebox-value.mjs +74 -0
- package/dist/type/utils.js +1 -10
- package/dist/type/utils.mjs +1 -10
- package/dist/type/validator/clean-safe.d.ts +2 -4
- package/dist/type/validator/clean-safe.js +15 -11
- package/dist/type/validator/clean-safe.mjs +16 -10
- package/dist/type/validator/custom-error.js +12 -16
- package/dist/type/validator/custom-error.mjs +11 -14
- package/dist/type/validator/default-precompute.d.ts +9 -1
- package/dist/type/validator/default-precompute.js +40 -77
- package/dist/type/validator/default-precompute.mjs +37 -74
- package/dist/type/validator/exact-mirror-live.d.ts +8 -0
- package/dist/type/validator/exact-mirror-live.js +22 -0
- package/dist/type/validator/exact-mirror-live.mjs +17 -0
- 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 +8 -8
- package/dist/type/validator/exact-mirror.mjs +9 -8
- package/dist/type/validator/frozen-check.js +5 -6
- package/dist/type/validator/frozen-check.mjs +6 -7
- package/dist/type/validator/index.d.ts +1 -0
- package/dist/type/validator/index.js +169 -166
- package/dist/type/validator/index.mjs +162 -158
- package/dist/type/validator/string-codec-aot.d.ts +2 -1
- package/dist/type/validator/string-codec-aot.js +8 -2
- package/dist/type/validator/string-codec-aot.mjs +7 -2
- package/dist/type/validator/validator-cache.d.ts +5 -4
- package/dist/type/validator/validator-cache.js +41 -24
- package/dist/type/validator/validator-cache.mjs +40 -22
- package/dist/types.d.ts +263 -95
- package/dist/universal/constants.d.ts +2 -1
- package/dist/universal/constants.js +3 -1
- package/dist/universal/constants.mjs +2 -1
- package/dist/universal/env.js +2 -3
- package/dist/universal/env.mjs +2 -3
- package/dist/universal/file.d.ts +6 -4
- package/dist/universal/file.js +11 -16
- package/dist/universal/file.mjs +12 -16
- package/dist/universal/index.d.ts +2 -2
- package/dist/universal/is-production.d.ts +1 -2
- package/dist/universal/is-production.js +1 -3
- package/dist/universal/is-production.mjs +2 -3
- package/dist/universal/server.d.ts +0 -272
- package/dist/utils.d.ts +43 -7
- package/dist/utils.js +181 -126
- package/dist/utils.mjs +168 -126
- package/dist/validator/index.d.ts +1 -1
- package/dist/validator/index.js +17 -30
- package/dist/validator/index.mjs +18 -31
- package/dist/validator/route.js +2 -1
- package/dist/validator/route.mjs +2 -1
- package/dist/ws/context.d.ts +8 -1
- package/dist/ws/context.js +68 -44
- package/dist/ws/context.mjs +67 -44
- package/dist/ws/parser.js +10 -20
- package/dist/ws/parser.mjs +10 -20
- package/dist/ws/route.d.ts +2 -2
- package/dist/ws/route.js +249 -141
- package/dist/ws/route.mjs +254 -146
- package/dist/ws/types.d.ts +2 -2
- package/package.json +23 -49
- 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 -7
- package/dist/cookie/index.js +0 -13
- package/dist/cookie/index.mjs +0 -7
- package/dist/handler/index.d.ts +0 -2
- package/dist/handler/index.js +0 -5
- package/dist/handler/index.mjs +0 -3
|
@@ -1,13 +1,56 @@
|
|
|
1
1
|
import { createAdapter } from "../index.mjs";
|
|
2
|
-
import {
|
|
3
|
-
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";
|
|
4
5
|
import { WebStandardAdapter } from "../web-standard/index.mjs";
|
|
5
6
|
import { frozenRootOf, resolvedWsOf } from "../../generation.mjs";
|
|
6
7
|
import { origin } from "../origin.mjs";
|
|
7
8
|
import { buildNativeStaticResponse } from "../../compile/handler/index.mjs";
|
|
8
|
-
import { routeRow } from "../../route-table.mjs";
|
|
9
|
+
import { RouteFlag, routeRow } from "../../route-table.mjs";
|
|
9
10
|
|
|
10
11
|
//#region src/adapter/bun/index.ts
|
|
12
|
+
function runLifecycle(epoch, callback, ...args) {
|
|
13
|
+
const invoking = epoch.invoking;
|
|
14
|
+
epoch.invoking = true;
|
|
15
|
+
try {
|
|
16
|
+
return callback(...args);
|
|
17
|
+
} finally {
|
|
18
|
+
epoch.invoking = invoking;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
const unavailableFetch = () => new Response(null, {
|
|
22
|
+
headers: { connection: "close" },
|
|
23
|
+
status: 503
|
|
24
|
+
});
|
|
25
|
+
function releaseLifecycle(app, ext, createdExt, stop, registerCleanup) {
|
|
26
|
+
if (ext.stop === stop) delete ext.stop;
|
|
27
|
+
if (ext.cleanupEpoch === registerCleanup) delete ext.cleanupEpoch;
|
|
28
|
+
if (createdExt && app["~ext"] === ext && !Object.keys(ext).length) app["~ext"] = void 0;
|
|
29
|
+
}
|
|
30
|
+
async function waitForServerRequests(server, abandoned) {
|
|
31
|
+
while (server.pendingRequests && !abandoned()) await Bun.sleep(1);
|
|
32
|
+
}
|
|
33
|
+
async function settleServerWebSockets(lifecycle, errors) {
|
|
34
|
+
if (!lifecycle) return true;
|
|
35
|
+
lifecycle.closing = true;
|
|
36
|
+
let failed = false;
|
|
37
|
+
do {
|
|
38
|
+
for (const socket of lifecycle.sockets) if (socket.readyState < 3) try {
|
|
39
|
+
socket.terminate();
|
|
40
|
+
} catch (error) {
|
|
41
|
+
errors.push(error);
|
|
42
|
+
failed = true;
|
|
43
|
+
}
|
|
44
|
+
if (failed) return false;
|
|
45
|
+
await Bun.sleep(1);
|
|
46
|
+
const abandon = lifecycle.abandon === true;
|
|
47
|
+
for (const socket of lifecycle.sockets) if (abandon || isSocketQuiet(socket)) {
|
|
48
|
+
delete socket.data["~lifecycleRun"];
|
|
49
|
+
lifecycle.sockets.delete(socket);
|
|
50
|
+
}
|
|
51
|
+
} while (lifecycle.sockets.size);
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
11
54
|
/**
|
|
12
55
|
* ! This may looks like it would cause race condition, but it is not
|
|
13
56
|
* Bun is single-threaded and synchronous, so the `finally` block will
|
|
@@ -25,102 +68,186 @@ const withOrigin = (fetch) => (request, server) => {
|
|
|
25
68
|
origin.request = void 0;
|
|
26
69
|
}
|
|
27
70
|
};
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
"
|
|
31
|
-
|
|
32
|
-
"
|
|
33
|
-
|
|
34
|
-
"
|
|
35
|
-
|
|
36
|
-
|
|
71
|
+
const isNativeStaticMethod = (method) => method === "GET" || method === "POST" || method === "PUT" || method === "DELETE" || method === "PATCH" || method === "HEAD" || method === "OPTIONS";
|
|
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
|
+
}
|
|
37
149
|
function collectStaticRoutes(app) {
|
|
38
|
-
if (app["~config"]?.nativeStaticResponse === false) return;
|
|
39
150
|
app.fetch;
|
|
40
151
|
const frozenRoot = frozenRootOf(app);
|
|
41
152
|
const fetchLevelHook = flattenChain(frozenRoot["~hookChain"]);
|
|
42
|
-
|
|
153
|
+
const promoteResponses = app["~config"]?.nativeStaticResponse !== false && !fetchLevelHook?.request?.length && !fetchLevelHook?.trace?.length && !frozenRoot["~ext"]?.hoc?.length;
|
|
43
154
|
const table = app["~generation"]?.routeTable ?? app["~routeTable"];
|
|
44
155
|
const length = table?.length ?? 0;
|
|
45
156
|
if (!table || !length) return;
|
|
46
|
-
const methods = table
|
|
47
|
-
const
|
|
48
|
-
const
|
|
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);
|
|
49
160
|
let hasCandidate = false;
|
|
50
161
|
for (let i = 0; i < length; i++) {
|
|
162
|
+
if (!isStatic(i)) continue;
|
|
51
163
|
const h = handlers[i];
|
|
52
|
-
if (
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
164
|
+
if (isHTMLBundle(h) || isPromotable(h)) {
|
|
165
|
+
hasCandidate = true;
|
|
166
|
+
break;
|
|
167
|
+
}
|
|
56
168
|
}
|
|
57
169
|
if (!hasCandidate) return;
|
|
58
|
-
const ready = nullObject();
|
|
59
170
|
const strictPath = frozenRoot["~config"]?.strictPath === true;
|
|
60
|
-
const
|
|
61
|
-
for (let i = 0; i < length; i++)
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
if (needEncodeRegex.test(path)) {
|
|
72
|
-
const encoded = encodeURI(path);
|
|
73
|
-
if (encoded !== path) set.add(encoded);
|
|
74
|
-
}
|
|
171
|
+
const routeIndex = /* @__PURE__ */ new Map();
|
|
172
|
+
for (let i = 0; i < length; i++) {
|
|
173
|
+
if (!isStatic(i)) continue;
|
|
174
|
+
const method = methods[i];
|
|
175
|
+
const path = paths[i];
|
|
176
|
+
let pathsByMethod = routeIndex.get(method);
|
|
177
|
+
if (!pathsByMethod) routeIndex.set(method, pathsByMethod = /* @__PURE__ */ new Map());
|
|
178
|
+
pathsByMethod.set(path, i);
|
|
179
|
+
if (!strictPath && (flags[i] & RouteFlag.Encode) !== 0) {
|
|
180
|
+
const encoded = encodeURI(path);
|
|
181
|
+
if (encoded !== path && !pathsByMethod.has(encoded)) pathsByMethod.set(encoded, -1);
|
|
75
182
|
}
|
|
76
183
|
}
|
|
77
|
-
const
|
|
78
|
-
|
|
184
|
+
const ready = nullObject();
|
|
185
|
+
let hasReady = false;
|
|
186
|
+
const add = (method, path, value, needsEncode) => {
|
|
187
|
+
if (needsEncode) path = encodeURI(path);
|
|
79
188
|
(ready[path] ??= nullObject())[method] = value;
|
|
189
|
+
hasReady = true;
|
|
80
190
|
};
|
|
81
191
|
for (let i = 0; i < length; i++) {
|
|
192
|
+
if (!isStatic(i)) continue;
|
|
82
193
|
const method = methods[i];
|
|
83
|
-
|
|
194
|
+
const pathsByMethod = routeIndex.get(method);
|
|
84
195
|
const path = paths[i];
|
|
85
|
-
if (
|
|
86
|
-
if (!nativeStaticMethods.has(method)) continue;
|
|
196
|
+
if (pathsByMethod.get(path) !== i) continue;
|
|
87
197
|
const h = handlers[i];
|
|
88
|
-
|
|
89
|
-
|
|
198
|
+
let value;
|
|
199
|
+
if (isHTMLBundle(h)) value = h;
|
|
200
|
+
else if (!isPromotable(h)) continue;
|
|
201
|
+
else value = buildNativeStaticResponse(routeRow(table, i), app);
|
|
90
202
|
if (!value) continue;
|
|
91
|
-
|
|
92
|
-
|
|
203
|
+
const needsEncode = (flags[i] & RouteFlag.Encode) !== 0;
|
|
204
|
+
add(method, path, value, needsEncode);
|
|
205
|
+
if (!strictPath) {
|
|
93
206
|
const loose = getLoosePath(path);
|
|
94
|
-
if (loose !== path && !
|
|
207
|
+
if (loose !== path && !pathsByMethod.has(loose)) add(method, loose, value, needsEncode);
|
|
95
208
|
}
|
|
96
209
|
}
|
|
97
|
-
if (!
|
|
98
|
-
return
|
|
210
|
+
if (!hasReady) return;
|
|
211
|
+
return ready;
|
|
99
212
|
}
|
|
100
213
|
const BunAdapter = createAdapter({
|
|
101
|
-
name: "bun",
|
|
102
|
-
runtime: "bun",
|
|
103
|
-
isWebStandard: true,
|
|
104
214
|
parse: WebStandardAdapter.parse,
|
|
105
215
|
response: WebStandardAdapter.response,
|
|
106
216
|
listen(app, options, callback) {
|
|
107
|
-
|
|
108
|
-
const
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
217
|
+
if (app.server || app["~ext"]?.stop) throw new Error("[Elysia] Cannot call listen() while a server or teardown is active");
|
|
218
|
+
const requestReady = Promise.withResolvers();
|
|
219
|
+
function gatedFetch(request, server) {
|
|
220
|
+
return live && !cancelled ? live(request, server) : requestReady.promise.then(() => {
|
|
221
|
+
if (cancelled || !live) return unavailableFetch();
|
|
222
|
+
return live(request, server);
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
const _options = typeof options === "object" ? {
|
|
226
|
+
...options,
|
|
227
|
+
fetch: gatedFetch
|
|
228
|
+
} : {
|
|
115
229
|
port: +options,
|
|
116
230
|
fetch: gatedFetch
|
|
117
231
|
};
|
|
118
|
-
|
|
232
|
+
const _config = app["~config"]?.serve;
|
|
119
233
|
const serve = _config ? {
|
|
120
234
|
..._config,
|
|
121
235
|
..._options
|
|
122
236
|
} : _options;
|
|
123
|
-
|
|
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 ? {
|
|
240
|
+
...serve,
|
|
241
|
+
error: unavailableFetch,
|
|
242
|
+
routes: htmlRoutes ?? {}
|
|
243
|
+
} : serve);
|
|
244
|
+
let live;
|
|
245
|
+
let cancelled = false;
|
|
246
|
+
let shutdownAttempt;
|
|
247
|
+
let wsLifecycle;
|
|
248
|
+
let modulesReady;
|
|
249
|
+
let pendingSetups;
|
|
250
|
+
let setupsSettled;
|
|
124
251
|
const build = () => {
|
|
125
252
|
const fetch = app.fetch;
|
|
126
253
|
let routes;
|
|
@@ -129,11 +256,22 @@ const BunAdapter = createAdapter({
|
|
|
129
256
|
} catch (error) {
|
|
130
257
|
console.warn("[Elysia] Native static promotion was skipped:", error);
|
|
131
258
|
}
|
|
259
|
+
routes = collectHTMLBundleRoutes(app, handoff, routes);
|
|
132
260
|
let websocket;
|
|
133
261
|
if (app["~hasWS"]) {
|
|
134
262
|
const resolved = resolvedWsOf(app);
|
|
135
263
|
if (!resolved) throw new Error("[Elysia] internal: WebSocket routes are present but no capability provider was resolved");
|
|
136
|
-
|
|
264
|
+
const handler = resolved.provider.buildGlobalWSHandler();
|
|
265
|
+
websocket = resolved.config ? Object.assign(handler, resolved.config) : handler;
|
|
266
|
+
const setter = Object.getOwnPropertyDescriptor(handler, "~lifecycle")?.set;
|
|
267
|
+
if (setter) {
|
|
268
|
+
wsLifecycle = {
|
|
269
|
+
closing: false,
|
|
270
|
+
sockets: /* @__PURE__ */ new Set(),
|
|
271
|
+
run: runLifecycle.bind(null, epoch)
|
|
272
|
+
};
|
|
273
|
+
setter.call(handler, wsLifecycle);
|
|
274
|
+
}
|
|
137
275
|
}
|
|
138
276
|
return {
|
|
139
277
|
fetch,
|
|
@@ -141,79 +279,296 @@ const BunAdapter = createAdapter({
|
|
|
141
279
|
websocket
|
|
142
280
|
};
|
|
143
281
|
};
|
|
144
|
-
let
|
|
145
|
-
|
|
146
|
-
const
|
|
282
|
+
let startupFailure;
|
|
283
|
+
let forceRequested = false;
|
|
284
|
+
const force = Promise.withResolvers();
|
|
285
|
+
const abandon = Promise.withResolvers();
|
|
286
|
+
let forceDone = false;
|
|
287
|
+
let nativeStopped = false;
|
|
288
|
+
let abandoned = false;
|
|
289
|
+
let published = false;
|
|
290
|
+
let cleanupCompleted = false;
|
|
291
|
+
let idleRequired = false;
|
|
292
|
+
let cleanupFailures;
|
|
293
|
+
let observedOutcome;
|
|
294
|
+
let persistentCleanup;
|
|
295
|
+
let persistentCleanupLength = -1;
|
|
296
|
+
const epochCleanup = [];
|
|
297
|
+
const createdExt = app["~ext"] === void 0;
|
|
298
|
+
const ext = app["~ext"] ??= nullObject();
|
|
299
|
+
const epoch = {
|
|
300
|
+
setup: false,
|
|
301
|
+
invoking: false
|
|
302
|
+
};
|
|
303
|
+
const snapshotCleanup = () => {
|
|
304
|
+
if (persistentCleanupLength !== -1) return;
|
|
305
|
+
persistentCleanup = ext.cleanup;
|
|
306
|
+
persistentCleanupLength = persistentCleanup?.length ?? 0;
|
|
307
|
+
};
|
|
308
|
+
const registerCleanup = (handler) => {
|
|
309
|
+
if (ext.cleanupEpoch !== registerCleanup) return false;
|
|
310
|
+
if (!epoch.setup) throw new Error("[Elysia] .cleanup() called after its setup epoch settled");
|
|
311
|
+
if (Array.isArray(handler)) epochCleanup.push(...handler);
|
|
312
|
+
else epochCleanup.push(handler);
|
|
313
|
+
return true;
|
|
314
|
+
};
|
|
315
|
+
const gate = () => {
|
|
316
|
+
if (!published) return;
|
|
317
|
+
live = void 0;
|
|
318
|
+
if (wsLifecycle) wsLifecycle.closing = true;
|
|
147
319
|
try {
|
|
148
|
-
server.reload(
|
|
320
|
+
server.reload({
|
|
321
|
+
...serve,
|
|
322
|
+
fetch: unavailableFetch,
|
|
323
|
+
error: unavailableFetch,
|
|
324
|
+
routes: {}
|
|
325
|
+
});
|
|
149
326
|
} catch (error) {
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
327
|
+
return { error };
|
|
328
|
+
}
|
|
329
|
+
};
|
|
330
|
+
const nativeStop = async (closeActiveConnections, errors) => {
|
|
331
|
+
try {
|
|
332
|
+
const stopping = server.stop(closeActiveConnections);
|
|
333
|
+
await (closeActiveConnections ? stopping : Promise.race([stopping, force.promise]));
|
|
334
|
+
if (!closeActiveConnections && forceRequested && !forceDone) return false;
|
|
335
|
+
nativeStopped = true;
|
|
336
|
+
if (closeActiveConnections) {
|
|
337
|
+
forceDone = true;
|
|
338
|
+
forceRequested = false;
|
|
339
|
+
}
|
|
340
|
+
return true;
|
|
341
|
+
} catch (error) {
|
|
342
|
+
if (closeActiveConnections) forceRequested = true;
|
|
343
|
+
errors.push(error);
|
|
344
|
+
return false;
|
|
345
|
+
}
|
|
346
|
+
};
|
|
347
|
+
const isAbandoned = () => abandoned;
|
|
348
|
+
const quiesce = async (force) => {
|
|
349
|
+
const errors = [];
|
|
350
|
+
if (!published) return {
|
|
351
|
+
errors,
|
|
352
|
+
releasable: await nativeStop(true, errors),
|
|
353
|
+
safe: true
|
|
354
|
+
};
|
|
355
|
+
if (force && !idleRequired && !wsLifecycle?.closing) {
|
|
356
|
+
const stopped = await nativeStop(true, errors);
|
|
357
|
+
return {
|
|
358
|
+
errors,
|
|
359
|
+
releasable: stopped,
|
|
360
|
+
safe: stopped
|
|
361
|
+
};
|
|
362
|
+
}
|
|
363
|
+
const gateFailure = gate();
|
|
364
|
+
if (gateFailure) errors.push(gateFailure.error);
|
|
365
|
+
let socketsSettled = await settleServerWebSockets(wsLifecycle, errors);
|
|
366
|
+
await Promise.resolve();
|
|
367
|
+
let close = forceRequested || gateFailure !== void 0 || !socketsSettled;
|
|
368
|
+
if (!close && nativeStopped) await waitForServerRequests(server, isAbandoned);
|
|
369
|
+
idleRequired = true;
|
|
370
|
+
let stopped = true;
|
|
371
|
+
while (!nativeStopped || forceRequested && !forceDone) {
|
|
372
|
+
if (nativeStopped) close = true;
|
|
373
|
+
stopped = await nativeStop(close, errors);
|
|
374
|
+
if (stopped) {
|
|
375
|
+
if (socketsSettled) socketsSettled = await settleServerWebSockets(wsLifecycle, errors);
|
|
376
|
+
continue;
|
|
377
|
+
}
|
|
378
|
+
if (close) break;
|
|
379
|
+
await waitForServerRequests(server, isAbandoned);
|
|
380
|
+
close = true;
|
|
381
|
+
}
|
|
382
|
+
let idleClosed = true;
|
|
383
|
+
if (idleRequired) {
|
|
384
|
+
const closeIdle = server.closeIdleConnections;
|
|
385
|
+
if (closeIdle) try {
|
|
386
|
+
closeIdle.call(server);
|
|
387
|
+
} catch (error) {
|
|
388
|
+
errors.push(error);
|
|
389
|
+
idleClosed = false;
|
|
158
390
|
}
|
|
391
|
+
if (idleClosed && !gateFailure) idleRequired = false;
|
|
159
392
|
}
|
|
393
|
+
const safe = socketsSettled && stopped && idleClosed && (!gateFailure || forceDone);
|
|
394
|
+
return {
|
|
395
|
+
errors,
|
|
396
|
+
releasable: safe,
|
|
397
|
+
safe
|
|
398
|
+
};
|
|
160
399
|
};
|
|
161
400
|
const setup = () => {
|
|
162
|
-
|
|
401
|
+
snapshotCleanup();
|
|
402
|
+
const onSetup = ext.setup;
|
|
163
403
|
if (!onSetup) return;
|
|
164
|
-
|
|
404
|
+
epoch.setup = true;
|
|
405
|
+
ext.cleanupEpoch = registerCleanup;
|
|
165
406
|
for (let i = 0; i < onSetup.length; i++) {
|
|
166
|
-
|
|
167
|
-
|
|
407
|
+
if (cancelled) break;
|
|
408
|
+
try {
|
|
409
|
+
const result = runLifecycle(epoch, onSetup[i], app);
|
|
410
|
+
if (result && typeof result.then === "function") (pendingSetups ??= []).push(Promise.resolve(result));
|
|
411
|
+
} catch (error) {
|
|
412
|
+
if (!pendingSetups) epoch.setup = false;
|
|
413
|
+
stop(true, { error }).catch(() => {});
|
|
414
|
+
throw error;
|
|
415
|
+
}
|
|
168
416
|
}
|
|
169
|
-
if (pendingSetups)
|
|
417
|
+
if (pendingSetups) {
|
|
418
|
+
setupsSettled = Promise.allSettled(pendingSetups);
|
|
419
|
+
return Promise.all(pendingSetups).then(() => epoch.setup = false);
|
|
420
|
+
}
|
|
421
|
+
epoch.setup = false;
|
|
170
422
|
};
|
|
171
|
-
const
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
if (
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
423
|
+
const stop = (closeActiveConnections, failure) => {
|
|
424
|
+
const reentrant = epoch.invoking;
|
|
425
|
+
if (failure) startupFailure ??= failure;
|
|
426
|
+
if (closeActiveConnections === true) {
|
|
427
|
+
force.resolve();
|
|
428
|
+
if (!failure) abandon.resolve();
|
|
429
|
+
if (!forceDone) forceRequested = true;
|
|
430
|
+
}
|
|
431
|
+
cancelled = true;
|
|
432
|
+
requestReady.resolve();
|
|
433
|
+
if (app.server === server) app.server = void 0;
|
|
434
|
+
let outcome;
|
|
435
|
+
if (shutdownAttempt) {
|
|
436
|
+
if (closeActiveConnections === true && !forceDone) {
|
|
437
|
+
abandoned = true;
|
|
438
|
+
if (wsLifecycle) wsLifecycle.abandon = true;
|
|
439
|
+
}
|
|
440
|
+
outcome = shutdownAttempt;
|
|
441
|
+
} else {
|
|
442
|
+
const { promise, resolve, reject } = Promise.withResolvers();
|
|
443
|
+
outcome = shutdownAttempt = promise;
|
|
444
|
+
const quiescence = quiesce(forceRequested || !published);
|
|
445
|
+
let releasable = false;
|
|
446
|
+
let abandonedSetups;
|
|
447
|
+
(async () => {
|
|
448
|
+
try {
|
|
449
|
+
await Promise.resolve();
|
|
450
|
+
if (modulesReady) try {
|
|
451
|
+
await Promise.race([modulesReady, force.promise]);
|
|
452
|
+
} catch (error) {
|
|
453
|
+
startupFailure ??= { error };
|
|
454
|
+
}
|
|
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++) {
|
|
459
|
+
const result = setupResults[i];
|
|
460
|
+
if (result.status === "rejected") {
|
|
461
|
+
startupFailure = { error: result.reason };
|
|
462
|
+
break;
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
epoch.setup = false;
|
|
467
|
+
const errors = [];
|
|
468
|
+
const quiesced = await quiescence;
|
|
469
|
+
if (startupFailure) errors.push(startupFailure.error);
|
|
470
|
+
errors.push(...quiesced.errors);
|
|
471
|
+
releasable = quiesced.releasable;
|
|
472
|
+
if (!quiesced.safe) {
|
|
473
|
+
if (cleanupFailures) errors.push(...cleanupFailures);
|
|
474
|
+
throwLifecycleErrors(errors);
|
|
475
|
+
}
|
|
476
|
+
if (!cleanupCompleted) {
|
|
477
|
+
snapshotCleanup();
|
|
478
|
+
if (ext.stop === stop) {
|
|
479
|
+
const length = persistentCleanupLength + epochCleanup.length;
|
|
480
|
+
for (let n = 0; n < length; n++) {
|
|
481
|
+
if (ext.stop !== stop) break;
|
|
482
|
+
const i = startupFailure ? length - 1 - n : n;
|
|
483
|
+
const handler = i < persistentCleanupLength ? persistentCleanup[i] : epochCleanup[i - persistentCleanupLength];
|
|
484
|
+
try {
|
|
485
|
+
await runLifecycle(epoch, handler, app);
|
|
486
|
+
} catch (error) {
|
|
487
|
+
(cleanupFailures ??= []).push(error);
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
cleanupCompleted = true;
|
|
492
|
+
epochCleanup.length = 0;
|
|
493
|
+
}
|
|
494
|
+
if (cleanupFailures) errors.push(...cleanupFailures);
|
|
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();
|
|
501
|
+
throwLifecycleErrors(errors);
|
|
502
|
+
} finally {
|
|
503
|
+
epoch.setup = false;
|
|
504
|
+
if (!releasable) shutdownAttempt = void 0;
|
|
505
|
+
}
|
|
506
|
+
})().then(resolve, reject);
|
|
507
|
+
}
|
|
508
|
+
if (!reentrant) return outcome;
|
|
509
|
+
if (observedOutcome !== outcome) {
|
|
510
|
+
observedOutcome = outcome;
|
|
511
|
+
outcome.catch((error) => {
|
|
512
|
+
console.error("[Elysia] stop() failed:", error);
|
|
513
|
+
});
|
|
514
|
+
}
|
|
515
|
+
return Promise.resolve();
|
|
188
516
|
};
|
|
517
|
+
ext.stop = stop;
|
|
189
518
|
const publish = () => {
|
|
190
|
-
if (app.server !== server)
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
519
|
+
if (cancelled || app.server !== server) {
|
|
520
|
+
requestReady.resolve();
|
|
521
|
+
return;
|
|
522
|
+
}
|
|
523
|
+
try {
|
|
524
|
+
const built = build();
|
|
525
|
+
live = serve.fetch = withOrigin(built.fetch);
|
|
526
|
+
published = true;
|
|
527
|
+
if (built.websocket) serve.websocket = built.websocket;
|
|
528
|
+
if (built.routes) serve.routes = built.routes;
|
|
529
|
+
try {
|
|
530
|
+
server.reload(serve);
|
|
531
|
+
} catch (error) {
|
|
532
|
+
if (!serve.routes) throw error;
|
|
533
|
+
delete serve.routes;
|
|
534
|
+
console.warn("[Elysia] Native static promotion was skipped:", error);
|
|
535
|
+
try {
|
|
536
|
+
server.reload(serve);
|
|
537
|
+
} catch (fallbackError) {
|
|
538
|
+
console.error("[Elysia] Failed to reload Bun server:", fallbackError);
|
|
539
|
+
throw fallbackError;
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
if (callback) callback(server);
|
|
543
|
+
} catch (error) {
|
|
544
|
+
startupFailure ??= { error };
|
|
545
|
+
throw error;
|
|
546
|
+
}
|
|
547
|
+
requestReady.resolve();
|
|
197
548
|
};
|
|
198
549
|
const start = () => {
|
|
199
|
-
|
|
550
|
+
modulesReady = void 0;
|
|
551
|
+
if (cancelled || app.server !== server) {
|
|
552
|
+
requestReady.resolve();
|
|
553
|
+
return;
|
|
554
|
+
}
|
|
200
555
|
const setupReady = setup();
|
|
201
|
-
if (setupReady
|
|
556
|
+
if (setupReady) return setupReady.then(publish);
|
|
202
557
|
publish();
|
|
203
558
|
};
|
|
204
559
|
try {
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
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) => {
|
|
208
563
|
console.error("[Elysia] listen() failed:", error);
|
|
209
|
-
|
|
564
|
+
if (typeof process !== "undefined") process.exitCode = 1;
|
|
210
565
|
});
|
|
211
566
|
} catch (error) {
|
|
212
|
-
|
|
567
|
+
stop(true, { error }).catch(console.error);
|
|
213
568
|
throw error;
|
|
214
569
|
}
|
|
215
570
|
}
|
|
216
571
|
});
|
|
217
572
|
|
|
218
573
|
//#endregion
|
|
219
|
-
export { BunAdapter, collectStaticRoutes };
|
|
574
|
+
export { BunAdapter, collectHTMLBundleRoutes, collectStaticRoutes, isHTMLBundle };
|