elysia 2.0.0-exp.42 → 2.0.0-exp.43
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 +1 -1
- package/dist/adapter/bun/index.js +123 -74
- package/dist/adapter/bun/index.mjs +123 -74
- package/dist/adapter/default-headers.d.ts +4 -0
- package/dist/adapter/default-headers.js +7 -0
- package/dist/adapter/default-headers.mjs +5 -0
- package/dist/adapter/types.d.ts +4 -37
- package/dist/adapter/utils.d.ts +4 -2
- package/dist/adapter/utils.js +16 -0
- package/dist/adapter/utils.mjs +15 -1
- package/dist/adapter/web-standard/handler.js +35 -32
- package/dist/adapter/web-standard/handler.mjs +36 -33
- package/dist/adapter/web-standard/index.js +14 -10
- package/dist/adapter/web-standard/index.mjs +14 -10
- package/dist/base.d.ts +26 -7
- package/dist/base.js +258 -83
- package/dist/base.mjs +259 -84
- package/dist/compile/aot-capture.d.ts +2 -1
- package/dist/compile/aot-capture.js +22 -6
- package/dist/compile/aot-capture.mjs +22 -7
- package/dist/compile/aot.d.ts +54 -3
- package/dist/compile/aot.js +148 -19
- package/dist/compile/aot.mjs +141 -20
- package/dist/compile/handler/descriptor.d.ts +90 -0
- package/dist/compile/handler/descriptor.js +210 -0
- package/dist/compile/handler/descriptor.mjs +205 -0
- package/dist/compile/handler/frozen-validator.d.ts +4 -3
- package/dist/compile/handler/frozen-validator.js +106 -9
- package/dist/compile/handler/frozen-validator.mjs +106 -10
- package/dist/compile/handler/index.d.ts +4 -2
- package/dist/compile/handler/index.js +102 -53
- package/dist/compile/handler/index.mjs +102 -54
- package/dist/compile/handler/jit.d.ts +12 -5
- package/dist/compile/handler/jit.js +144 -186
- package/dist/compile/handler/jit.mjs +149 -192
- package/dist/compile/handler/params.d.ts +3 -0
- package/dist/compile/handler/params.js +5 -0
- package/dist/compile/handler/params.mjs +8 -3
- package/dist/compile/handler/reconstruct.js +7 -4
- package/dist/compile/handler/reconstruct.mjs +7 -4
- package/dist/compile/handler/utils.d.ts +1 -2
- package/dist/compile/handler/utils.js +1 -2
- package/dist/compile/handler/utils.mjs +2 -2
- package/dist/compile/lexer.d.ts +1 -1
- package/dist/compile/plan/emit.d.ts +21 -0
- package/dist/compile/plan/emit.js +457 -0
- package/dist/compile/plan/emit.mjs +456 -0
- package/dist/compile/plan/plan.d.ts +76 -0
- package/dist/compile/plan/plan.js +130 -0
- package/dist/compile/plan/plan.mjs +128 -0
- package/dist/context.d.ts +4 -4
- package/dist/context.js +41 -9
- package/dist/context.mjs +42 -10
- package/dist/cookie/config.d.ts +2 -0
- package/dist/cookie/config.js +2 -1
- package/dist/cookie/config.mjs +2 -1
- package/dist/cookie/cookie.js +7 -2
- package/dist/cookie/cookie.mjs +8 -2
- package/dist/cookie/crypto.d.ts +15 -0
- package/dist/cookie/crypto.js +125 -0
- package/dist/cookie/crypto.mjs +113 -0
- package/dist/cookie/index.d.ts +3 -2
- package/dist/cookie/index.js +3 -3
- package/dist/cookie/index.mjs +3 -2
- package/dist/cookie/utils.d.ts +5 -15
- package/dist/cookie/utils.js +61 -121
- package/dist/cookie/utils.mjs +44 -104
- package/dist/error.js +58 -6
- package/dist/error.mjs +58 -6
- package/dist/experimental/resume.d.ts +11 -0
- package/dist/experimental/resume.js +12 -0
- package/dist/experimental/resume.mjs +11 -0
- package/dist/generation.d.ts +23 -0
- package/dist/generation.js +13 -0
- package/dist/generation.mjs +10 -0
- package/dist/handler/error.js +4 -5
- package/dist/handler/error.mjs +6 -7
- package/dist/handler/fetch.js +65 -77
- package/dist/handler/fetch.mjs +65 -77
- package/dist/handler/utils.d.ts +8 -1
- package/dist/handler/utils.js +16 -1
- package/dist/handler/utils.mjs +13 -1
- package/dist/index.d.ts +11 -11
- package/dist/memory.js +1 -1
- package/dist/memory.mjs +1 -1
- package/dist/package.js +11 -0
- package/dist/package.mjs +5 -0
- package/dist/plugin/aot/core.d.ts +2 -1
- package/dist/plugin/aot/core.js +23 -8
- package/dist/plugin/aot/core.mjs +23 -9
- package/dist/plugin/aot/hooks.d.ts +14 -0
- package/dist/plugin/aot/hooks.js +75 -0
- package/dist/plugin/aot/hooks.mjs +74 -0
- package/dist/plugin/aot/rspack-loader.d.ts +23 -0
- package/dist/plugin/aot/rspack-loader.js +44 -0
- package/dist/plugin/aot/rspack-loader.mjs +40 -0
- package/dist/plugin/aot/rspack.d.ts +23 -0
- package/dist/plugin/aot/rspack.js +86 -0
- package/dist/plugin/aot/rspack.mjs +83 -0
- package/dist/plugin/aot/source.d.ts +3 -2
- package/dist/plugin/aot/source.js +10 -8
- package/dist/plugin/aot/source.mjs +11 -9
- package/dist/plugin/aot/unplugin.d.ts +54 -0
- package/dist/plugin/aot/unplugin.js +68 -0
- package/dist/plugin/aot/unplugin.mjs +66 -0
- package/dist/plugin/aot/vite.js +7 -68
- package/dist/plugin/aot/vite.mjs +7 -68
- package/dist/route-table.d.ts +26 -0
- package/dist/route-table.js +63 -0
- package/dist/route-table.mjs +60 -0
- package/dist/schema-snapshot.d.ts +5 -0
- package/dist/schema-snapshot.js +111 -0
- package/dist/schema-snapshot.mjs +108 -0
- package/dist/sucrose.d.ts +13 -1
- package/dist/sucrose.js +122 -55
- package/dist/sucrose.mjs +121 -56
- package/dist/type/bridge-live.d.ts +3 -3
- package/dist/type/bridge.d.ts +3 -3
- package/dist/type/coerce-plan.js +1 -1
- package/dist/type/coerce-plan.mjs +1 -1
- package/dist/type/constants.d.ts +1 -1
- package/dist/type/elysia/array-string.js +1 -1
- package/dist/type/elysia/array-string.mjs +1 -1
- package/dist/type/elysia/boolean-string.js +1 -1
- package/dist/type/elysia/boolean-string.mjs +1 -1
- package/dist/type/elysia/date.js +1 -1
- package/dist/type/elysia/date.mjs +1 -1
- package/dist/type/elysia/file-type.d.ts +1 -1
- package/dist/type/elysia/files.js +1 -1
- package/dist/type/elysia/files.mjs +1 -1
- package/dist/type/elysia/integer-string.js +1 -1
- package/dist/type/elysia/integer-string.mjs +1 -1
- package/dist/type/elysia/maybe-empty.js +1 -1
- package/dist/type/elysia/maybe-empty.mjs +1 -1
- package/dist/type/elysia/nullable.js +1 -1
- package/dist/type/elysia/nullable.mjs +1 -1
- package/dist/type/elysia/numeric-enum.js +1 -1
- package/dist/type/elysia/numeric-enum.mjs +1 -1
- package/dist/type/elysia/numeric.js +1 -1
- package/dist/type/elysia/numeric.mjs +1 -1
- package/dist/type/elysia/object-string.js +1 -1
- package/dist/type/elysia/object-string.mjs +1 -1
- package/dist/type/elysia/string.js +16 -3
- package/dist/type/elysia/string.mjs +16 -3
- package/dist/type/elysia/utils.d.ts +3 -1
- package/dist/type/elysia/utils.js +7 -2
- package/dist/type/elysia/utils.mjs +6 -2
- package/dist/type/exports.d.ts +1 -1
- package/dist/type/index.d.ts +1 -1
- package/dist/type/validator/clean-safe.d.ts +2 -1
- package/dist/type/validator/clean-safe.js +9 -1
- package/dist/type/validator/clean-safe.mjs +10 -2
- package/dist/type/validator/index.d.ts +1 -1
- package/dist/type/validator/index.js +185 -57
- package/dist/type/validator/index.mjs +186 -58
- package/dist/type/validator/string-codec-aot.d.ts +1 -1
- package/dist/type/validator/string-codec-aot.js +2 -0
- package/dist/type/validator/string-codec-aot.mjs +2 -0
- package/dist/types.d.ts +140 -5
- package/dist/utils.d.ts +2 -3
- package/dist/utils.js +0 -2
- package/dist/utils.mjs +1 -2
- package/dist/validator/index.d.ts +6 -3
- package/dist/validator/index.js +18 -11
- package/dist/validator/index.mjs +18 -11
- package/dist/validator/route.d.ts +1 -1
- package/dist/ws/context.d.ts +2 -2
- package/dist/ws/route.d.ts +1 -1
- package/dist/ws/route.js +80 -11
- package/dist/ws/route.mjs +80 -11
- package/package.json +30 -6
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { AnyElysia } from "../../base.js";
|
|
2
2
|
import { ElysiaAdapterOptions } from "../types.js";
|
|
3
3
|
//#region src/adapter/bun/index.d.ts
|
|
4
|
-
declare function collectStaticRoutes(app: AnyElysia): readonly [Record<string, Record<string, Response>>,
|
|
4
|
+
declare function collectStaticRoutes(app: AnyElysia): readonly [Record<string, Record<string, Response>>, readonly []] | undefined;
|
|
5
5
|
declare const BunAdapter: ElysiaAdapterOptions;
|
|
6
6
|
//#endregion
|
|
7
7
|
export { BunAdapter, collectStaticRoutes };
|
|
@@ -3,34 +3,42 @@ const require_adapter_index = require('../index.js');
|
|
|
3
3
|
const require_constants = require('../../constants.js');
|
|
4
4
|
const require_utils = require('../../utils.js');
|
|
5
5
|
const require_adapter_web_standard_index = require('../web-standard/index.js');
|
|
6
|
+
const require_generation = require('../../generation.js');
|
|
6
7
|
const require_compile_handler_index = require('../../compile/handler/index.js');
|
|
7
|
-
const
|
|
8
|
+
const require_route_table = require('../../route-table.js');
|
|
8
9
|
const require_ws_route = require('../../ws/route.js');
|
|
9
10
|
|
|
10
11
|
//#region src/adapter/bun/index.ts
|
|
12
|
+
const nativeStaticMethods = new Set([
|
|
13
|
+
"GET",
|
|
14
|
+
"POST",
|
|
15
|
+
"PUT",
|
|
16
|
+
"DELETE",
|
|
17
|
+
"PATCH",
|
|
18
|
+
"HEAD",
|
|
19
|
+
"OPTIONS"
|
|
20
|
+
]);
|
|
11
21
|
function collectStaticRoutes(app) {
|
|
12
22
|
if (app["~config"]?.nativeStaticResponse === false) return;
|
|
13
23
|
app.fetch;
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
24
|
+
const frozenRoot = require_generation.frozenRootOf(app);
|
|
25
|
+
const fetchLevelHook = require_utils.flattenChain(frozenRoot["~hookChain"]);
|
|
26
|
+
if (fetchLevelHook?.request?.length || fetchLevelHook?.trace?.length || frozenRoot["~ext"]?.hoc?.length) return;
|
|
27
|
+
const table = app["~generation"]?.routeTable ?? app["~routeTable"];
|
|
28
|
+
const length = table?.length ?? 0;
|
|
29
|
+
if (!table || !length) return;
|
|
30
|
+
const methods = table.method;
|
|
31
|
+
const paths = table.path;
|
|
18
32
|
const ready = require_utils.nullObject();
|
|
19
|
-
const
|
|
20
|
-
const strictPath = app["~config"]?.strictPath === true;
|
|
33
|
+
const strictPath = frozenRoot["~config"]?.strictPath === true;
|
|
21
34
|
const seen = /* @__PURE__ */ new Map();
|
|
22
|
-
for (let i = 0; i <
|
|
23
|
-
const route = history[i];
|
|
24
|
-
const method = route[0];
|
|
25
|
-
seen.set(method + " " + route[1], i);
|
|
26
|
-
}
|
|
35
|
+
for (let i = 0; i < length; i++) seen.set(methods[i] + " " + paths[i], i);
|
|
27
36
|
let explicitPaths;
|
|
28
37
|
if (!strictPath) {
|
|
29
38
|
explicitPaths = /* @__PURE__ */ new Map();
|
|
30
|
-
for (let i = 0; i <
|
|
31
|
-
const
|
|
32
|
-
const
|
|
33
|
-
const path = route[1];
|
|
39
|
+
for (let i = 0; i < length; i++) {
|
|
40
|
+
const method = methods[i];
|
|
41
|
+
const path = paths[i];
|
|
34
42
|
let set = explicitPaths.get(method);
|
|
35
43
|
if (!set) explicitPaths.set(method, set = /* @__PURE__ */ new Set());
|
|
36
44
|
set.add(path);
|
|
@@ -42,20 +50,15 @@ function collectStaticRoutes(app) {
|
|
|
42
50
|
}
|
|
43
51
|
const add = (method, path, value) => {
|
|
44
52
|
if (require_constants.needEncodeRegex.test(path)) path = encodeURI(path);
|
|
45
|
-
|
|
46
|
-
if (resolved instanceof Response) (ready[path] ??= require_utils.nullObject())[method] = resolved;
|
|
47
|
-
}, (err) => {
|
|
48
|
-
console.error(`[Elysia] Static route ${method} ${path} failed to resolve:`, err);
|
|
49
|
-
}));
|
|
50
|
-
else (ready[path] ??= require_utils.nullObject())[method] = value;
|
|
53
|
+
(ready[path] ??= require_utils.nullObject())[method] = value;
|
|
51
54
|
};
|
|
52
|
-
for (let i = 0; i <
|
|
53
|
-
const
|
|
54
|
-
if (
|
|
55
|
-
const
|
|
56
|
-
const path = route[1];
|
|
55
|
+
for (let i = 0; i < length; i++) {
|
|
56
|
+
const method = methods[i];
|
|
57
|
+
if (method === "WS") continue;
|
|
58
|
+
const path = paths[i];
|
|
57
59
|
if (seen.get(method + " " + path) !== i) continue;
|
|
58
|
-
|
|
60
|
+
if (!nativeStaticMethods.has(method)) continue;
|
|
61
|
+
const value = require_compile_handler_index.buildNativeStaticResponse(require_route_table.routeRow(table, i), app);
|
|
59
62
|
if (!value) continue;
|
|
60
63
|
add(method, path, value);
|
|
61
64
|
if (!strictPath && !require_constants.isDynamicRegex.test(path)) {
|
|
@@ -63,8 +66,8 @@ function collectStaticRoutes(app) {
|
|
|
63
66
|
if (loose !== path && !explicitPaths?.get(method)?.has(loose)) add(method, loose, value);
|
|
64
67
|
}
|
|
65
68
|
}
|
|
66
|
-
if (!Object.keys(ready).length
|
|
67
|
-
return [ready,
|
|
69
|
+
if (!Object.keys(ready).length) return;
|
|
70
|
+
return [ready, []];
|
|
68
71
|
}
|
|
69
72
|
const BunAdapter = require_adapter_index.createAdapter({
|
|
70
73
|
name: "bun",
|
|
@@ -84,58 +87,104 @@ const BunAdapter = require_adapter_index.createAdapter({
|
|
|
84
87
|
..._config,
|
|
85
88
|
..._options
|
|
86
89
|
} : _options;
|
|
87
|
-
const server = app.server = Bun.serve(serve);
|
|
88
90
|
const onSetup = app["~ext"]?.setup;
|
|
89
|
-
|
|
90
|
-
|
|
91
|
+
const needsGate = app.pending || !!onSetup?.length;
|
|
92
|
+
let ready;
|
|
93
|
+
const build = () => {
|
|
94
|
+
const fetch = app.fetch;
|
|
95
|
+
let routes;
|
|
96
|
+
try {
|
|
97
|
+
routes = collectStaticRoutes(app);
|
|
98
|
+
} catch (error) {
|
|
99
|
+
console.warn("[Elysia] Native static promotion was skipped:", error);
|
|
100
|
+
}
|
|
101
|
+
const hasWs = app["~hasWS"];
|
|
102
|
+
let websocket;
|
|
103
|
+
if (hasWs) {
|
|
104
|
+
const defaultConfig = require_generation.frozenRootOf(app)["~config"]?.websocket;
|
|
105
|
+
websocket = defaultConfig ? Object.assign(require_ws_route.buildGlobalWSHandler(), defaultConfig) : require_ws_route.buildGlobalWSHandler();
|
|
106
|
+
}
|
|
107
|
+
return {
|
|
108
|
+
fetch,
|
|
109
|
+
routes,
|
|
110
|
+
websocket
|
|
111
|
+
};
|
|
112
|
+
};
|
|
113
|
+
let built;
|
|
114
|
+
if (!needsGate) built = build();
|
|
115
|
+
if (needsGate) serve.fetch = (request, server) => ready.then(() => app.fetch(request, server));
|
|
116
|
+
else serve.fetch = built.fetch;
|
|
117
|
+
const server = app.server = Bun.serve(serve);
|
|
118
|
+
const reload = () => {
|
|
119
|
+
try {
|
|
120
|
+
server.reload(serve);
|
|
121
|
+
} catch (error) {
|
|
122
|
+
if (!serve.routes) throw error;
|
|
123
|
+
delete serve.routes;
|
|
124
|
+
console.warn("[Elysia] Native static promotion was skipped:", error);
|
|
125
|
+
try {
|
|
126
|
+
server.reload(serve);
|
|
127
|
+
} catch (fallbackError) {
|
|
128
|
+
console.error("[Elysia] Failed to reload Bun server:", fallbackError);
|
|
129
|
+
throw fallbackError;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
const setup = () => {
|
|
134
|
+
const onSetup = app["~ext"]?.setup;
|
|
135
|
+
if (!onSetup) return;
|
|
91
136
|
let pendingSetups;
|
|
92
137
|
for (let i = 0; i < onSetup.length; i++) {
|
|
93
138
|
const result = onSetup[i](app);
|
|
94
139
|
if (result && typeof result.then === "function") (pendingSetups ??= []).push(result);
|
|
95
140
|
}
|
|
96
|
-
if (pendingSetups)
|
|
97
|
-
}
|
|
98
|
-
const
|
|
99
|
-
if (!hasWs) {
|
|
100
|
-
if (callback) if (setupReady) setupReady.then(() => callback(app.server));
|
|
101
|
-
else callback(app.server);
|
|
102
|
-
}
|
|
103
|
-
queueMicrotask(() => {
|
|
141
|
+
if (pendingSetups) return Promise.all(pendingSetups);
|
|
142
|
+
};
|
|
143
|
+
const rollback = (error) => {
|
|
104
144
|
if (app.server !== server) return;
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
const collectRoutes = () => {
|
|
112
|
-
const staticRoutes = collectStaticRoutes(app);
|
|
113
|
-
if (!staticRoutes) return;
|
|
114
|
-
if (staticRoutes[1].length) return Promise.all(staticRoutes[1]).then(() => {
|
|
115
|
-
if (app.server !== server) return;
|
|
116
|
-
serve.routes = staticRoutes[0];
|
|
117
|
-
app.server.reload(serve);
|
|
118
|
-
});
|
|
119
|
-
if (Object.keys(staticRoutes[0]).length) serve.routes = staticRoutes[0];
|
|
120
|
-
};
|
|
121
|
-
if (app.pending) {
|
|
122
|
-
app.server.reload(serve);
|
|
123
|
-
const reloadAfterModules = () => {
|
|
124
|
-
if (app.server !== server) return;
|
|
125
|
-
serve.fetch = app.fetch;
|
|
126
|
-
if (hasWs || app["~hasWS"]) buildWebSocket();
|
|
127
|
-
collectRoutes();
|
|
128
|
-
app.server.reload(serve);
|
|
129
|
-
};
|
|
130
|
-
app.modules.then(reloadAfterModules, reloadAfterModules);
|
|
131
|
-
} else {
|
|
132
|
-
collectRoutes();
|
|
133
|
-
app.server.reload(serve);
|
|
145
|
+
try {
|
|
146
|
+
server.stop(true);
|
|
147
|
+
} catch (stopError) {
|
|
148
|
+
console.error(stopError);
|
|
149
|
+
} finally {
|
|
150
|
+
app.server = void 0;
|
|
134
151
|
}
|
|
135
|
-
|
|
136
|
-
if (
|
|
137
|
-
|
|
138
|
-
|
|
152
|
+
const cleanup = app["~ext"]?.cleanup;
|
|
153
|
+
if (cleanup) for (let i = cleanup.length - 1; i >= 0; i--) try {
|
|
154
|
+
const result = cleanup[i](app);
|
|
155
|
+
if (result && typeof result.then === "function") Promise.resolve(result).catch(console.error);
|
|
156
|
+
} catch (cleanupError) {
|
|
157
|
+
console.error(cleanupError);
|
|
158
|
+
}
|
|
159
|
+
return error;
|
|
160
|
+
};
|
|
161
|
+
const publish = () => {
|
|
162
|
+
if (app.server !== server) return;
|
|
163
|
+
built ??= build();
|
|
164
|
+
serve.fetch = built.fetch;
|
|
165
|
+
if (built.websocket) serve.websocket = built.websocket;
|
|
166
|
+
if (built.routes) serve.routes = built.routes[0];
|
|
167
|
+
if (needsGate || built.websocket || built.routes) reload();
|
|
168
|
+
if (callback) callback(server);
|
|
169
|
+
};
|
|
170
|
+
const start = () => {
|
|
171
|
+
if (app.server !== server) return;
|
|
172
|
+
const setupReady = setup();
|
|
173
|
+
if (setupReady && typeof setupReady.then === "function") return Promise.resolve(setupReady).then(publish);
|
|
174
|
+
publish();
|
|
175
|
+
};
|
|
176
|
+
try {
|
|
177
|
+
if (app.pending) ready = app.modules.then(start);
|
|
178
|
+
else {
|
|
179
|
+
const result = start();
|
|
180
|
+
if (result && typeof result.then === "function") ready = result;
|
|
181
|
+
else if (needsGate) ready = Promise.resolve();
|
|
182
|
+
}
|
|
183
|
+
ready?.catch(rollback);
|
|
184
|
+
} catch (error) {
|
|
185
|
+
rollback(error);
|
|
186
|
+
throw error;
|
|
187
|
+
}
|
|
139
188
|
}
|
|
140
189
|
});
|
|
141
190
|
|
|
@@ -2,34 +2,42 @@ import { createAdapter } from "../index.mjs";
|
|
|
2
2
|
import { isDynamicRegex, needEncodeRegex } from "../../constants.mjs";
|
|
3
3
|
import { flattenChain, getLoosePath, nullObject } from "../../utils.mjs";
|
|
4
4
|
import { WebStandardAdapter } from "../web-standard/index.mjs";
|
|
5
|
+
import { frozenRootOf } from "../../generation.mjs";
|
|
5
6
|
import { buildNativeStaticResponse } from "../../compile/handler/index.mjs";
|
|
6
|
-
import {
|
|
7
|
+
import { routeRow } from "../../route-table.mjs";
|
|
7
8
|
import { buildGlobalWSHandler } from "../../ws/route.mjs";
|
|
8
9
|
|
|
9
10
|
//#region src/adapter/bun/index.ts
|
|
11
|
+
const nativeStaticMethods = new Set([
|
|
12
|
+
"GET",
|
|
13
|
+
"POST",
|
|
14
|
+
"PUT",
|
|
15
|
+
"DELETE",
|
|
16
|
+
"PATCH",
|
|
17
|
+
"HEAD",
|
|
18
|
+
"OPTIONS"
|
|
19
|
+
]);
|
|
10
20
|
function collectStaticRoutes(app) {
|
|
11
21
|
if (app["~config"]?.nativeStaticResponse === false) return;
|
|
12
22
|
app.fetch;
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
23
|
+
const frozenRoot = frozenRootOf(app);
|
|
24
|
+
const fetchLevelHook = flattenChain(frozenRoot["~hookChain"]);
|
|
25
|
+
if (fetchLevelHook?.request?.length || fetchLevelHook?.trace?.length || frozenRoot["~ext"]?.hoc?.length) return;
|
|
26
|
+
const table = app["~generation"]?.routeTable ?? app["~routeTable"];
|
|
27
|
+
const length = table?.length ?? 0;
|
|
28
|
+
if (!table || !length) return;
|
|
29
|
+
const methods = table.method;
|
|
30
|
+
const paths = table.path;
|
|
17
31
|
const ready = nullObject();
|
|
18
|
-
const
|
|
19
|
-
const strictPath = app["~config"]?.strictPath === true;
|
|
32
|
+
const strictPath = frozenRoot["~config"]?.strictPath === true;
|
|
20
33
|
const seen = /* @__PURE__ */ new Map();
|
|
21
|
-
for (let i = 0; i <
|
|
22
|
-
const route = history[i];
|
|
23
|
-
const method = route[0];
|
|
24
|
-
seen.set(method + " " + route[1], i);
|
|
25
|
-
}
|
|
34
|
+
for (let i = 0; i < length; i++) seen.set(methods[i] + " " + paths[i], i);
|
|
26
35
|
let explicitPaths;
|
|
27
36
|
if (!strictPath) {
|
|
28
37
|
explicitPaths = /* @__PURE__ */ new Map();
|
|
29
|
-
for (let i = 0; i <
|
|
30
|
-
const
|
|
31
|
-
const
|
|
32
|
-
const path = route[1];
|
|
38
|
+
for (let i = 0; i < length; i++) {
|
|
39
|
+
const method = methods[i];
|
|
40
|
+
const path = paths[i];
|
|
33
41
|
let set = explicitPaths.get(method);
|
|
34
42
|
if (!set) explicitPaths.set(method, set = /* @__PURE__ */ new Set());
|
|
35
43
|
set.add(path);
|
|
@@ -41,20 +49,15 @@ function collectStaticRoutes(app) {
|
|
|
41
49
|
}
|
|
42
50
|
const add = (method, path, value) => {
|
|
43
51
|
if (needEncodeRegex.test(path)) path = encodeURI(path);
|
|
44
|
-
|
|
45
|
-
if (resolved instanceof Response) (ready[path] ??= nullObject())[method] = resolved;
|
|
46
|
-
}, (err) => {
|
|
47
|
-
console.error(`[Elysia] Static route ${method} ${path} failed to resolve:`, err);
|
|
48
|
-
}));
|
|
49
|
-
else (ready[path] ??= nullObject())[method] = value;
|
|
52
|
+
(ready[path] ??= nullObject())[method] = value;
|
|
50
53
|
};
|
|
51
|
-
for (let i = 0; i <
|
|
52
|
-
const
|
|
53
|
-
if (
|
|
54
|
-
const
|
|
55
|
-
const path = route[1];
|
|
54
|
+
for (let i = 0; i < length; i++) {
|
|
55
|
+
const method = methods[i];
|
|
56
|
+
if (method === "WS") continue;
|
|
57
|
+
const path = paths[i];
|
|
56
58
|
if (seen.get(method + " " + path) !== i) continue;
|
|
57
|
-
|
|
59
|
+
if (!nativeStaticMethods.has(method)) continue;
|
|
60
|
+
const value = buildNativeStaticResponse(routeRow(table, i), app);
|
|
58
61
|
if (!value) continue;
|
|
59
62
|
add(method, path, value);
|
|
60
63
|
if (!strictPath && !isDynamicRegex.test(path)) {
|
|
@@ -62,8 +65,8 @@ function collectStaticRoutes(app) {
|
|
|
62
65
|
if (loose !== path && !explicitPaths?.get(method)?.has(loose)) add(method, loose, value);
|
|
63
66
|
}
|
|
64
67
|
}
|
|
65
|
-
if (!Object.keys(ready).length
|
|
66
|
-
return [ready,
|
|
68
|
+
if (!Object.keys(ready).length) return;
|
|
69
|
+
return [ready, []];
|
|
67
70
|
}
|
|
68
71
|
const BunAdapter = createAdapter({
|
|
69
72
|
name: "bun",
|
|
@@ -83,58 +86,104 @@ const BunAdapter = createAdapter({
|
|
|
83
86
|
..._config,
|
|
84
87
|
..._options
|
|
85
88
|
} : _options;
|
|
86
|
-
const server = app.server = Bun.serve(serve);
|
|
87
89
|
const onSetup = app["~ext"]?.setup;
|
|
88
|
-
|
|
89
|
-
|
|
90
|
+
const needsGate = app.pending || !!onSetup?.length;
|
|
91
|
+
let ready;
|
|
92
|
+
const build = () => {
|
|
93
|
+
const fetch = app.fetch;
|
|
94
|
+
let routes;
|
|
95
|
+
try {
|
|
96
|
+
routes = collectStaticRoutes(app);
|
|
97
|
+
} catch (error) {
|
|
98
|
+
console.warn("[Elysia] Native static promotion was skipped:", error);
|
|
99
|
+
}
|
|
100
|
+
const hasWs = app["~hasWS"];
|
|
101
|
+
let websocket;
|
|
102
|
+
if (hasWs) {
|
|
103
|
+
const defaultConfig = frozenRootOf(app)["~config"]?.websocket;
|
|
104
|
+
websocket = defaultConfig ? Object.assign(buildGlobalWSHandler(), defaultConfig) : buildGlobalWSHandler();
|
|
105
|
+
}
|
|
106
|
+
return {
|
|
107
|
+
fetch,
|
|
108
|
+
routes,
|
|
109
|
+
websocket
|
|
110
|
+
};
|
|
111
|
+
};
|
|
112
|
+
let built;
|
|
113
|
+
if (!needsGate) built = build();
|
|
114
|
+
if (needsGate) serve.fetch = (request, server) => ready.then(() => app.fetch(request, server));
|
|
115
|
+
else serve.fetch = built.fetch;
|
|
116
|
+
const server = app.server = Bun.serve(serve);
|
|
117
|
+
const reload = () => {
|
|
118
|
+
try {
|
|
119
|
+
server.reload(serve);
|
|
120
|
+
} catch (error) {
|
|
121
|
+
if (!serve.routes) throw error;
|
|
122
|
+
delete serve.routes;
|
|
123
|
+
console.warn("[Elysia] Native static promotion was skipped:", error);
|
|
124
|
+
try {
|
|
125
|
+
server.reload(serve);
|
|
126
|
+
} catch (fallbackError) {
|
|
127
|
+
console.error("[Elysia] Failed to reload Bun server:", fallbackError);
|
|
128
|
+
throw fallbackError;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
const setup = () => {
|
|
133
|
+
const onSetup = app["~ext"]?.setup;
|
|
134
|
+
if (!onSetup) return;
|
|
90
135
|
let pendingSetups;
|
|
91
136
|
for (let i = 0; i < onSetup.length; i++) {
|
|
92
137
|
const result = onSetup[i](app);
|
|
93
138
|
if (result && typeof result.then === "function") (pendingSetups ??= []).push(result);
|
|
94
139
|
}
|
|
95
|
-
if (pendingSetups)
|
|
96
|
-
}
|
|
97
|
-
const
|
|
98
|
-
if (!hasWs) {
|
|
99
|
-
if (callback) if (setupReady) setupReady.then(() => callback(app.server));
|
|
100
|
-
else callback(app.server);
|
|
101
|
-
}
|
|
102
|
-
queueMicrotask(() => {
|
|
140
|
+
if (pendingSetups) return Promise.all(pendingSetups);
|
|
141
|
+
};
|
|
142
|
+
const rollback = (error) => {
|
|
103
143
|
if (app.server !== server) return;
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
const collectRoutes = () => {
|
|
111
|
-
const staticRoutes = collectStaticRoutes(app);
|
|
112
|
-
if (!staticRoutes) return;
|
|
113
|
-
if (staticRoutes[1].length) return Promise.all(staticRoutes[1]).then(() => {
|
|
114
|
-
if (app.server !== server) return;
|
|
115
|
-
serve.routes = staticRoutes[0];
|
|
116
|
-
app.server.reload(serve);
|
|
117
|
-
});
|
|
118
|
-
if (Object.keys(staticRoutes[0]).length) serve.routes = staticRoutes[0];
|
|
119
|
-
};
|
|
120
|
-
if (app.pending) {
|
|
121
|
-
app.server.reload(serve);
|
|
122
|
-
const reloadAfterModules = () => {
|
|
123
|
-
if (app.server !== server) return;
|
|
124
|
-
serve.fetch = app.fetch;
|
|
125
|
-
if (hasWs || app["~hasWS"]) buildWebSocket();
|
|
126
|
-
collectRoutes();
|
|
127
|
-
app.server.reload(serve);
|
|
128
|
-
};
|
|
129
|
-
app.modules.then(reloadAfterModules, reloadAfterModules);
|
|
130
|
-
} else {
|
|
131
|
-
collectRoutes();
|
|
132
|
-
app.server.reload(serve);
|
|
144
|
+
try {
|
|
145
|
+
server.stop(true);
|
|
146
|
+
} catch (stopError) {
|
|
147
|
+
console.error(stopError);
|
|
148
|
+
} finally {
|
|
149
|
+
app.server = void 0;
|
|
133
150
|
}
|
|
134
|
-
|
|
135
|
-
if (
|
|
136
|
-
|
|
137
|
-
|
|
151
|
+
const cleanup = app["~ext"]?.cleanup;
|
|
152
|
+
if (cleanup) for (let i = cleanup.length - 1; i >= 0; i--) try {
|
|
153
|
+
const result = cleanup[i](app);
|
|
154
|
+
if (result && typeof result.then === "function") Promise.resolve(result).catch(console.error);
|
|
155
|
+
} catch (cleanupError) {
|
|
156
|
+
console.error(cleanupError);
|
|
157
|
+
}
|
|
158
|
+
return error;
|
|
159
|
+
};
|
|
160
|
+
const publish = () => {
|
|
161
|
+
if (app.server !== server) return;
|
|
162
|
+
built ??= build();
|
|
163
|
+
serve.fetch = built.fetch;
|
|
164
|
+
if (built.websocket) serve.websocket = built.websocket;
|
|
165
|
+
if (built.routes) serve.routes = built.routes[0];
|
|
166
|
+
if (needsGate || built.websocket || built.routes) reload();
|
|
167
|
+
if (callback) callback(server);
|
|
168
|
+
};
|
|
169
|
+
const start = () => {
|
|
170
|
+
if (app.server !== server) return;
|
|
171
|
+
const setupReady = setup();
|
|
172
|
+
if (setupReady && typeof setupReady.then === "function") return Promise.resolve(setupReady).then(publish);
|
|
173
|
+
publish();
|
|
174
|
+
};
|
|
175
|
+
try {
|
|
176
|
+
if (app.pending) ready = app.modules.then(start);
|
|
177
|
+
else {
|
|
178
|
+
const result = start();
|
|
179
|
+
if (result && typeof result.then === "function") ready = result;
|
|
180
|
+
else if (needsGate) ready = Promise.resolve();
|
|
181
|
+
}
|
|
182
|
+
ready?.catch(rollback);
|
|
183
|
+
} catch (error) {
|
|
184
|
+
rollback(error);
|
|
185
|
+
throw error;
|
|
186
|
+
}
|
|
138
187
|
}
|
|
139
188
|
});
|
|
140
189
|
|
package/dist/adapter/types.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ListenCallback, Serve } from "../universal/server.js";
|
|
2
|
-
import {
|
|
2
|
+
import { MaybePromise } from "../types.js";
|
|
3
3
|
import { Context } from "../context.js";
|
|
4
4
|
import { AnyElysia } from "../base.js";
|
|
5
5
|
|
|
@@ -30,58 +30,25 @@ interface ElysiaAdapterOptions {
|
|
|
30
30
|
*/
|
|
31
31
|
websocket?: boolean;
|
|
32
32
|
listen?(app: AnyElysia, options: string | number | Partial<Serve>, callback?: ListenCallback): void;
|
|
33
|
-
/**
|
|
34
|
-
* Stop server from serving
|
|
35
|
-
*
|
|
36
|
-
* ---
|
|
37
|
-
* @example
|
|
38
|
-
* ```typescript
|
|
39
|
-
* app.stop()
|
|
40
|
-
* ```
|
|
41
|
-
*
|
|
42
|
-
* @example
|
|
43
|
-
* ```typescript
|
|
44
|
-
* app.stop(true) // Abruptly any requests inflight
|
|
45
|
-
* ```
|
|
46
|
-
*/
|
|
47
|
-
stop?(app: AnyElysia, closeActiveConnections?: boolean): Promise<void>;
|
|
48
33
|
parse: {
|
|
49
34
|
json: (context: Context) => MaybePromise<Record<keyof any, undefined> | unknown[]>;
|
|
50
35
|
text: (context: Context) => MaybePromise<string>;
|
|
51
36
|
urlencoded: (context: Context) => MaybePromise<Record<string, string | string[]>>;
|
|
52
37
|
arrayBuffer: (context: Context) => MaybePromise<ArrayBuffer>;
|
|
53
38
|
formData: (context: Context) => MaybePromise<Record<string, unknown>>;
|
|
54
|
-
default: (context: Context, contentType: string) => MaybePromise<any>;
|
|
39
|
+
default: (context: Context, contentType: string, normalized?: boolean) => MaybePromise<any>;
|
|
55
40
|
};
|
|
56
41
|
response: {
|
|
57
42
|
/**
|
|
58
43
|
* Map return response on every case
|
|
59
44
|
*/
|
|
60
|
-
map(response: unknown, set: Context['set'], ...params: unknown[]): unknown;
|
|
45
|
+
map(response: unknown, set: Context['set'], ...params: unknown[]): unknown; /** Support immutable shared default headers. */
|
|
46
|
+
supportsDefaultHeaderSink?: true;
|
|
61
47
|
/**
|
|
62
48
|
* Map response without cookie, status or headers
|
|
63
49
|
*/
|
|
64
50
|
compact?(response: unknown, ...params: unknown[]): unknown;
|
|
65
|
-
/**
|
|
66
|
-
* Compile inline to value
|
|
67
|
-
*
|
|
68
|
-
* @example
|
|
69
|
-
* ```ts
|
|
70
|
-
* Elysia().get('/', 'static')
|
|
71
|
-
* ```
|
|
72
|
-
*/
|
|
73
|
-
static?(handle: unknown, hooks: AnyLocalHook, setHeaders?: Context['set']['headers'], ...params: unknown[]): (() => unknown) | undefined;
|
|
74
|
-
/**
|
|
75
|
-
* If the runtime support cloning response
|
|
76
|
-
*
|
|
77
|
-
* eg. Bun.serve({ static })
|
|
78
|
-
*/
|
|
79
|
-
nativeStatic?(handle: unknown, hooks: AnyLocalHook, set?: Context['set']): (() => MaybePromise<Response>) | undefined;
|
|
80
51
|
};
|
|
81
|
-
/**
|
|
82
|
-
* override Elysia's default fetch function
|
|
83
|
-
*/
|
|
84
|
-
fetch?(app: AnyElysia): (request: Request) => MaybePromise<Response>;
|
|
85
52
|
}
|
|
86
53
|
//#endregion
|
|
87
54
|
export { ElysiaAdapterOptions };
|
package/dist/adapter/utils.d.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
import { BaseCookie } from "../cookie/types.js";
|
|
1
2
|
import { StatusMap } from "../constants.js";
|
|
2
3
|
import { ElysiaFile } from "../universal/file.js";
|
|
3
|
-
import { BaseCookie } from "../cookie/types.js";
|
|
4
4
|
import { HTTPHeaders } from "../types.js";
|
|
5
5
|
import { Context } from "../context.js";
|
|
6
6
|
//#region src/adapter/utils.d.ts
|
|
7
|
+
declare function materializeSetHeaders(set: Context['set']): any;
|
|
8
|
+
declare function normalizeContentType(contentType: string): string;
|
|
7
9
|
declare function handleFile(response: File | Blob | ElysiaFile, set?: Context['set'], request?: Request, size?: number): Response;
|
|
8
10
|
declare function parseSetCookies(headers: Headers, setCookie: string[]): Headers;
|
|
9
11
|
declare function responseToSetHeaders(response: Response, set?: Context['set']): {
|
|
@@ -45,4 +47,4 @@ declare function createResponseHandler(handler: CreateHandlerParameter): (respon
|
|
|
45
47
|
*/
|
|
46
48
|
declare function tee<T>(source: AsyncIterable<T>, branches?: number, cap?: number, capBytes?: number): AsyncIterableIterator<T>[];
|
|
47
49
|
//#endregion
|
|
48
|
-
export { createResponseHandler, createStreamHandler, handleFile, handleSet, parseSetCookies, responseToSetHeaders, streamResponse, tee };
|
|
50
|
+
export { createResponseHandler, createStreamHandler, handleFile, handleSet, materializeSetHeaders, normalizeContentType, parseSetCookies, responseToSetHeaders, streamResponse, tee };
|
package/dist/adapter/utils.js
CHANGED
|
@@ -4,13 +4,24 @@ const require_constants = require('../constants.js');
|
|
|
4
4
|
const require_utils = require('../utils.js');
|
|
5
5
|
const require_adapter_skip_clone = require('./skip-clone.js');
|
|
6
6
|
const require_cookie_serialize = require('../cookie/serialize.js');
|
|
7
|
+
const require_adapter_default_headers = require('./default-headers.js');
|
|
7
8
|
|
|
8
9
|
//#region src/adapter/utils.ts
|
|
9
10
|
const setCookie = "set-cookie";
|
|
11
|
+
function materializeSetHeaders(set) {
|
|
12
|
+
const headers = set.headers;
|
|
13
|
+
if (headers["\0"] !== headers) return headers;
|
|
14
|
+
return set.headers = Object.assign(require_utils.nullObject(), headers);
|
|
15
|
+
}
|
|
10
16
|
const sseFormat = (data) => `data: ${data}\n\n`;
|
|
11
17
|
const identityFormat = (data) => data;
|
|
12
18
|
const textEncoder = new TextEncoder();
|
|
13
19
|
const encodeChunk = (s) => textEncoder.encode(s);
|
|
20
|
+
function normalizeContentType(contentType) {
|
|
21
|
+
if (contentType === "application/json") return contentType;
|
|
22
|
+
const end = contentType.indexOf(";");
|
|
23
|
+
return (end === -1 ? contentType : contentType.slice(0, end)).trim().toLowerCase();
|
|
24
|
+
}
|
|
14
25
|
function handleFile(response, set, request, size = response.size) {
|
|
15
26
|
if (!require_universal_constants.isBun && response instanceof Promise) return response.then((res) => handleFile(res, set, request, size));
|
|
16
27
|
const rangeHeader = request?.headers.get("range");
|
|
@@ -92,6 +103,7 @@ function parseSetCookies(headers, setCookie) {
|
|
|
92
103
|
}
|
|
93
104
|
function responseToSetHeaders(response, set) {
|
|
94
105
|
if (set && set.headers instanceof Headers) normalizeHeaders(set);
|
|
106
|
+
if (set) materializeSetHeaders(set);
|
|
95
107
|
if (set?.headers) {
|
|
96
108
|
if (response) if (require_universal_constants.hasHeaderShorthand) Object.assign(set.headers, response.headers.toJSON());
|
|
97
109
|
else for (const [key, value] of response.headers.entries()) set.headers[key] = value;
|
|
@@ -148,6 +160,7 @@ function createStreamHandler({ mapResponse, mapCompactResponse }) {
|
|
|
148
160
|
const isSSE = !skipFormat && (init?.value?.sse ?? generator?.sse ?? (set?.headers instanceof Headers ? set.headers.get("content-type")?.startsWith("text/event-stream") : set?.headers["content-type"]?.startsWith("text/event-stream")));
|
|
149
161
|
const format = isSSE ? sseFormat : identityFormat;
|
|
150
162
|
const contentType = isSSE ? "text/event-stream" : init?.value && typeof init?.value === "object" ? ArrayBuffer.isView(init.value) ? "application/octet-stream" : "application/json" : "text/plain";
|
|
163
|
+
if (set) materializeSetHeaders(set);
|
|
151
164
|
const headers = set?.headers;
|
|
152
165
|
if (headers instanceof Headers) {
|
|
153
166
|
if (!headers.has("transfer-encoding")) headers.set("transfer-encoding", "chunked");
|
|
@@ -259,6 +272,7 @@ function handleSet(set) {
|
|
|
259
272
|
set.headers = flat;
|
|
260
273
|
}
|
|
261
274
|
if (set.cookie && require_utils.isNotEmpty(set.cookie)) {
|
|
275
|
+
materializeSetHeaders(set);
|
|
262
276
|
const cookie = require_cookie_serialize.serializeCookie(set.cookie);
|
|
263
277
|
if (cookie) {
|
|
264
278
|
const existing = set.headers[setCookie];
|
|
@@ -513,6 +527,8 @@ exports.createResponseHandler = createResponseHandler;
|
|
|
513
527
|
exports.createStreamHandler = createStreamHandler;
|
|
514
528
|
exports.handleFile = handleFile;
|
|
515
529
|
exports.handleSet = handleSet;
|
|
530
|
+
exports.materializeSetHeaders = materializeSetHeaders;
|
|
531
|
+
exports.normalizeContentType = normalizeContentType;
|
|
516
532
|
exports.parseSetCookies = parseSetCookies;
|
|
517
533
|
exports.responseToSetHeaders = responseToSetHeaders;
|
|
518
534
|
exports.streamResponse = streamResponse;
|