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
package/dist/base.js
CHANGED
|
@@ -9,8 +9,8 @@ const require_generation = require('./generation.js');
|
|
|
9
9
|
const require_compile_handler_index = require('./compile/handler/index.js');
|
|
10
10
|
const require_route_table = require('./route-table.js');
|
|
11
11
|
const require_adapter_bun_index = require('./adapter/bun/index.js');
|
|
12
|
+
const require_context = require('./context.js');
|
|
12
13
|
const require_handler_fetch = require('./handler/fetch.js');
|
|
13
|
-
const require_compile_analysis_cache = require('./compile/analysis-cache.js');
|
|
14
14
|
const require_schema_snapshot = require('./schema-snapshot.js');
|
|
15
15
|
let memoirist = require("memoirist");
|
|
16
16
|
memoirist = require_runtime.__toESM(memoirist);
|
|
@@ -18,27 +18,105 @@ memoirist = require_runtime.__toESM(memoirist);
|
|
|
18
18
|
//#region src/base.ts
|
|
19
19
|
const useNodesBuffer = [];
|
|
20
20
|
const emptyHistory = Object.freeze([]);
|
|
21
|
+
let mutationEpoch = 0;
|
|
22
|
+
const extCallbackIndexes = /* @__PURE__ */ new WeakMap();
|
|
23
|
+
const mergeExtCallbacks = (target, incoming) => {
|
|
24
|
+
if (!target) return incoming.slice();
|
|
25
|
+
let index = extCallbackIndexes.get(target);
|
|
26
|
+
if (!index) {
|
|
27
|
+
index = {
|
|
28
|
+
indexedLength: target.length,
|
|
29
|
+
seen: new Set(target)
|
|
30
|
+
};
|
|
31
|
+
extCallbackIndexes.set(target, index);
|
|
32
|
+
} else for (let i = index.indexedLength; i < target.length; i++) index.seen.add(target[i]);
|
|
33
|
+
for (const fn of incoming) {
|
|
34
|
+
if (index.seen.has(fn)) continue;
|
|
35
|
+
target.push(fn);
|
|
36
|
+
index.seen.add(fn);
|
|
37
|
+
}
|
|
38
|
+
index.indexedLength = target.length;
|
|
39
|
+
return target;
|
|
40
|
+
};
|
|
41
|
+
const markStoredSingletons = (table, source) => {
|
|
42
|
+
if (!table) return;
|
|
43
|
+
for (const key in source) require_utils.markSingletons(table[key]);
|
|
44
|
+
};
|
|
21
45
|
const canRegisterLoose = (path, isDynamic) => !isDynamic && (path.length === 0 || path.charCodeAt(path.length - 1) === 47);
|
|
46
|
+
const isSingleSchema = (value) => "~kind" in value || "~elyAcl" in value || "~standard" in value;
|
|
47
|
+
const isSchemaValue = (value) => {
|
|
48
|
+
if (value == null || typeof value === "string") return true;
|
|
49
|
+
if (typeof value !== "object" && typeof value !== "function") return false;
|
|
50
|
+
return isSingleSchema(value) || typeof value.Check === "function";
|
|
51
|
+
};
|
|
52
|
+
const toModel = (key, value) => {
|
|
53
|
+
if ("~standard" in value) return value;
|
|
54
|
+
value = require_schema_snapshot.snapshotSchema(value);
|
|
55
|
+
value.$id ??= key;
|
|
56
|
+
return value;
|
|
57
|
+
};
|
|
58
|
+
const hookKeys = new Set([
|
|
59
|
+
...require_utils.schemaProperties,
|
|
60
|
+
...require_utils.eventProperties,
|
|
61
|
+
"detail",
|
|
62
|
+
"tags"
|
|
63
|
+
]);
|
|
64
|
+
const assertScope = (scope) => {
|
|
65
|
+
if (scope !== void 0 && scope !== "local" && scope !== "plugin" && scope !== "global") throw new Error(`[Elysia] Invalid hook scope ${JSON.stringify(scope)}, expected 'local', 'plugin' or 'global' (1.x 'scoped' is 'plugin')`);
|
|
66
|
+
};
|
|
67
|
+
const hasHookKeys = (value) => {
|
|
68
|
+
for (const key in value) if (hookKeys.has(key)) return true;
|
|
69
|
+
return false;
|
|
70
|
+
};
|
|
71
|
+
function assertSchemaShape(hook, where) {
|
|
72
|
+
for (const key in hook) {
|
|
73
|
+
if (!require_utils.schemaProperties.has(key)) continue;
|
|
74
|
+
const value = hook[key];
|
|
75
|
+
if (isSchemaValue(value)) continue;
|
|
76
|
+
if (key === "response" && require_utils.isPlainObject(value)) {
|
|
77
|
+
let isStatusMap = true;
|
|
78
|
+
for (const status in value) if (status !== "default" && isNaN(+status) || !isSchemaValue(value[status])) {
|
|
79
|
+
isStatusMap = false;
|
|
80
|
+
break;
|
|
81
|
+
}
|
|
82
|
+
if (isStatusMap) continue;
|
|
83
|
+
}
|
|
84
|
+
throw new Error(`[Elysia] ${where}: "${key}" is not a schema — use t.Object({ ... })`);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Every key a single route must answer to, in registration order.
|
|
89
|
+
*
|
|
90
|
+
* `registerLoose` is the caller's call, not this helper's: HTTP gates it on
|
|
91
|
+
* `canRegisterLoose` because its lookup retries the trailing slash, while WS
|
|
92
|
+
* has no such retry and must own both directions outright
|
|
93
|
+
*/
|
|
94
|
+
function expandPaths(path, needsEncode, registerLoose, explicit) {
|
|
95
|
+
const variants = [path];
|
|
96
|
+
if (needsEncode) {
|
|
97
|
+
const encoded = encodeURI(path);
|
|
98
|
+
if (encoded !== path) variants.push(encoded);
|
|
99
|
+
}
|
|
100
|
+
if (!registerLoose) return variants;
|
|
101
|
+
const paths = [];
|
|
102
|
+
for (let v = 0; v < variants.length; v++) {
|
|
103
|
+
const p = variants[v];
|
|
104
|
+
paths.push(p);
|
|
105
|
+
const loose = require_utils.getLoosePath(p);
|
|
106
|
+
if (loose !== p && !explicit?.has(loose)) paths.push(loose);
|
|
107
|
+
}
|
|
108
|
+
return paths;
|
|
109
|
+
}
|
|
22
110
|
var Elysia = class Elysia {
|
|
23
|
-
#hasPlugin;
|
|
24
|
-
#hasGlobal;
|
|
25
|
-
#ready;
|
|
26
|
-
#pending = 0;
|
|
27
|
-
#error;
|
|
28
|
-
#hash;
|
|
29
|
-
#childrenHash;
|
|
30
|
-
#scopeParent;
|
|
31
|
-
#pluginMacros;
|
|
32
|
-
#macroBaseline;
|
|
33
|
-
#declaredRoutes;
|
|
34
|
-
#routeSources;
|
|
35
111
|
get history() {
|
|
36
|
-
|
|
37
|
-
if (
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
112
|
+
const generation = this["~generation"];
|
|
113
|
+
if (this.#isCacheable && this.cachedGeneration === generation && this.cachedEpoch === mutationEpoch && this.cachedHistory !== void 0) return this.cachedHistory;
|
|
114
|
+
if (this.declaredRoutes === void 0 && this["~routeTable"]?.length) this.#materializeDeclaredRoutes();
|
|
115
|
+
if (!this.declaredRoutes?.length) return emptyHistory;
|
|
116
|
+
const history = new Array(this.declaredRoutes.length);
|
|
117
|
+
for (let sequence = 0; sequence < this.declaredRoutes.length; sequence++) {
|
|
118
|
+
const route = this.declaredRoutes[sequence];
|
|
119
|
+
const source = this.routeSources?.[sequence];
|
|
42
120
|
history[sequence] = Object.freeze({
|
|
43
121
|
sequence,
|
|
44
122
|
method: route[0],
|
|
@@ -46,12 +124,17 @@ var Elysia = class Elysia {
|
|
|
46
124
|
...source === void 0 ? {} : { source }
|
|
47
125
|
});
|
|
48
126
|
}
|
|
49
|
-
|
|
127
|
+
Object.freeze(history);
|
|
128
|
+
if (this.#isCacheable) {
|
|
129
|
+
this.#cacheRoutes(generation);
|
|
130
|
+
this.cachedHistory = history;
|
|
131
|
+
}
|
|
132
|
+
return history;
|
|
50
133
|
}
|
|
51
134
|
get ["~routes"]() {
|
|
52
|
-
if (this
|
|
53
|
-
if (!this
|
|
54
|
-
const routes = this
|
|
135
|
+
if (this.declaredRoutes === void 0 && this["~routeTable"]?.length) this.#materializeDeclaredRoutes();
|
|
136
|
+
if (!this.declaredRoutes?.length) return [];
|
|
137
|
+
const routes = this.declaredRoutes;
|
|
55
138
|
if (!this["~ext"]?.macro && !this["~scopeChildren"]) return routes;
|
|
56
139
|
return routes.map((r) => {
|
|
57
140
|
const localHook = r[4];
|
|
@@ -74,17 +157,16 @@ var Elysia = class Elysia {
|
|
|
74
157
|
this.#registerRoute(route);
|
|
75
158
|
return this;
|
|
76
159
|
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
#jitRoute;
|
|
81
|
-
#jitStatic;
|
|
82
|
-
#jitAliases;
|
|
160
|
+
get ["~programId"]() {
|
|
161
|
+
return this;
|
|
162
|
+
}
|
|
83
163
|
constructor(config) {
|
|
164
|
+
this._pending = 0;
|
|
165
|
+
this.routerBuilt = false;
|
|
84
166
|
/**
|
|
85
167
|
* ! Don't tune
|
|
86
168
|
*
|
|
87
|
-
* Interesting JSC internal: These `= undefined`
|
|
169
|
+
* Interesting JSC internal: These `= undefined` shouldn't be removed
|
|
88
170
|
*
|
|
89
171
|
* Inline slots live inside the object cell, so JSC must pick their
|
|
90
172
|
* count at allocation before any initializer runs
|
|
@@ -102,7 +184,8 @@ var Elysia = class Elysia {
|
|
|
102
184
|
* Don't omitted field either for monomorphic access
|
|
103
185
|
*
|
|
104
186
|
* @see test/memory/instance-footprint.test.ts
|
|
105
|
-
* Est.
|
|
187
|
+
* Est. overflow 37 -> 21 = butterfly 64 -> 32 slots = 738B -> 450B;
|
|
188
|
+
* reusing the app as its program identity brings the current cell to ~386B.
|
|
106
189
|
**/
|
|
107
190
|
this["~config"] = config;
|
|
108
191
|
this["~ext"] = void 0;
|
|
@@ -122,18 +205,24 @@ var Elysia = class Elysia {
|
|
|
122
205
|
this["~introspect"] = void 0;
|
|
123
206
|
this["~scopeChild"] = void 0;
|
|
124
207
|
this["~scopeChildren"] = void 0;
|
|
125
|
-
this["~programId"] = require_compile_aot.createProgramId();
|
|
126
208
|
if (config) {
|
|
127
209
|
const { prefix, name, seed, adapter } = config;
|
|
128
210
|
this["~Prefix"] = prefix ? prefix.charCodeAt(0) === 47 ? prefix : `/${prefix}` : void 0;
|
|
129
|
-
if (name) this
|
|
211
|
+
if (name) this.hash = require_utils.fnv1a(seed ? `${name}_${typeof seed === "object" ? JSON.stringify(seed, require_utils.serializeMacroSeed) : seed}` : name);
|
|
130
212
|
if (adapter?.setup) this.#useFn(adapter.setup);
|
|
131
213
|
} else this["~Prefix"] = void 0;
|
|
132
214
|
}
|
|
215
|
+
/**
|
|
216
|
+
* Every registered route with its merged hooks.
|
|
217
|
+
* Development shares a frozen cache. Production rebuilds the list so its
|
|
218
|
+
* metadata can be released after startup.
|
|
219
|
+
*/
|
|
133
220
|
get routes() {
|
|
134
|
-
|
|
135
|
-
if (
|
|
136
|
-
|
|
221
|
+
const generation = this["~generation"];
|
|
222
|
+
if (this.#isCacheable && this.cachedGeneration === generation && this.cachedEpoch === mutationEpoch && this.cachedRoutes !== void 0) return this.cachedRoutes;
|
|
223
|
+
if (this.declaredRoutes === void 0 && this["~routeTable"]?.length) this.#materializeDeclaredRoutes();
|
|
224
|
+
if (!this.declaredRoutes?.length) return [];
|
|
225
|
+
const routes = this["~routes"].map(([method, path, handler, instance, hook, appHook, inheritedChain, macroScope]) => {
|
|
137
226
|
const merged = require_compile_handler_index.composeRouteHook(instance, hook, appHook, inheritedChain, this, macroScope);
|
|
138
227
|
if (merged?.schemas?.length) for (const entry of merged.schemas) {
|
|
139
228
|
if (!entry?.response) continue;
|
|
@@ -147,20 +236,36 @@ var Elysia = class Elysia {
|
|
|
147
236
|
hooks: merged
|
|
148
237
|
};
|
|
149
238
|
});
|
|
239
|
+
if (this.#isCacheable && !require_universal_is_production.isProduction()) {
|
|
240
|
+
Object.freeze(routes);
|
|
241
|
+
this.#cacheRoutes(generation);
|
|
242
|
+
this.cachedRoutes = routes;
|
|
243
|
+
}
|
|
244
|
+
return routes;
|
|
150
245
|
}
|
|
151
246
|
decorate(typeOrNameOrDecorators, nameOrDecorators, value) {
|
|
152
|
-
|
|
153
|
-
|
|
247
|
+
return this.#setField("decorator", arguments.length, typeOrNameOrDecorators, nameOrDecorators, value);
|
|
248
|
+
}
|
|
249
|
+
#setField(field, length, typeOrName, nameOrValue, value) {
|
|
250
|
+
let as = "append";
|
|
251
|
+
let name = "";
|
|
252
|
+
switch (length) {
|
|
253
|
+
case 1:
|
|
254
|
+
value = typeOrName;
|
|
255
|
+
break;
|
|
154
256
|
case 2:
|
|
155
|
-
if (
|
|
156
|
-
|
|
157
|
-
|
|
257
|
+
if (typeOrName === "append" || typeOrName === "override") as = typeOrName;
|
|
258
|
+
else name = typeOrName;
|
|
259
|
+
value = nameOrValue;
|
|
260
|
+
break;
|
|
261
|
+
case 3:
|
|
262
|
+
as = typeOrName;
|
|
263
|
+
name = nameOrValue;
|
|
264
|
+
break;
|
|
265
|
+
default: return this;
|
|
158
266
|
}
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
#setField(field, as, name, value) {
|
|
162
|
-
if (this["~generation"] !== void 0) this.#assertMutable(field === "store" ? "state" : "decorate");
|
|
163
|
-
const ext = this.#ext;
|
|
267
|
+
this.#assertMutable(field === "store" ? "state" : "decorate");
|
|
268
|
+
const ext = this.ext;
|
|
164
269
|
const fresh = !ext[field];
|
|
165
270
|
const target = ext[field] ??= require_utils.nullObject();
|
|
166
271
|
switch (typeof value) {
|
|
@@ -169,69 +274,71 @@ var Elysia = class Elysia {
|
|
|
169
274
|
if (!name && require_utils.isEmpty(value)) return this;
|
|
170
275
|
if (name) {
|
|
171
276
|
const existing = target[name];
|
|
172
|
-
if (
|
|
277
|
+
if (existing && typeof existing === "object" && !Array.isArray(existing) && !Array.isArray(value)) target[name] = require_utils.mergeDeep(target[name], value, void 0, as === "override");
|
|
173
278
|
else target[name] = value;
|
|
279
|
+
require_utils.markSingletons(target[name]);
|
|
174
280
|
return this;
|
|
175
281
|
}
|
|
176
282
|
if (fresh) Object.assign(target, value);
|
|
177
283
|
else ext[field] = require_utils.mergeDeep(target, value, void 0, as === "override");
|
|
284
|
+
markStoredSingletons(ext[field], value);
|
|
178
285
|
return this;
|
|
179
286
|
case "function":
|
|
180
287
|
if (name) {
|
|
181
|
-
if (as === "override" || !(name in target))
|
|
182
|
-
|
|
288
|
+
if (as === "override" || !(name in target)) {
|
|
289
|
+
target[name] = value;
|
|
290
|
+
require_utils.markSingletons(value);
|
|
291
|
+
}
|
|
292
|
+
} else {
|
|
293
|
+
ext[field] = value(target);
|
|
294
|
+
markStoredSingletons(ext[field], ext[field]);
|
|
295
|
+
}
|
|
183
296
|
return this;
|
|
184
297
|
default:
|
|
185
298
|
if (as === "override" || !(name in target)) target[name] = value;
|
|
186
299
|
return this;
|
|
187
300
|
}
|
|
188
301
|
}
|
|
189
|
-
#decorate(as, name, value) {
|
|
190
|
-
return this.#setField("decorator", as, name, value);
|
|
191
|
-
}
|
|
192
302
|
state(typeOrNameOrStore, nameOrStore, value) {
|
|
193
|
-
|
|
194
|
-
case 1: return this.#state("append", "", typeOrNameOrStore);
|
|
195
|
-
case 2:
|
|
196
|
-
if (typeOrNameOrStore === "append" || typeOrNameOrStore === "override") return this.#state(typeOrNameOrStore, "", nameOrStore);
|
|
197
|
-
return this.#state("append", typeOrNameOrStore, nameOrStore);
|
|
198
|
-
case 3: return this.#state(typeOrNameOrStore, nameOrStore, value);
|
|
199
|
-
}
|
|
200
|
-
return this;
|
|
201
|
-
}
|
|
202
|
-
#state(as, name, value) {
|
|
203
|
-
return this.#setField("store", as, name, value);
|
|
303
|
+
return this.#setField("store", arguments.length, typeOrNameOrStore, nameOrStore, value);
|
|
204
304
|
}
|
|
205
305
|
headers(headers) {
|
|
206
306
|
this.#assertMutable("headers");
|
|
207
|
-
const ext = this
|
|
208
|
-
|
|
209
|
-
else ext.headers = Object.assign(require_utils.nullObject(), headers);
|
|
307
|
+
const ext = this.ext;
|
|
308
|
+
ext.headers = Object.assign(ext.headers ?? require_utils.nullObject(), headers);
|
|
210
309
|
return this;
|
|
211
310
|
}
|
|
212
311
|
#on(type, fn, scope = this["~config"]?.as) {
|
|
213
|
-
|
|
312
|
+
this.#assertMutable(type);
|
|
313
|
+
assertScope(scope);
|
|
214
314
|
const added = require_utils.nullObject();
|
|
215
315
|
added[type] = fn;
|
|
216
316
|
if (type === "trace") this["~hasTrace"] = true;
|
|
317
|
+
this.#link(added, scope, this);
|
|
318
|
+
this.#tagOrigin(fn);
|
|
319
|
+
return this;
|
|
320
|
+
}
|
|
321
|
+
#link(added, scope, owner, mayRef = true, propagated) {
|
|
217
322
|
const parent = this["~hookChain"];
|
|
218
|
-
|
|
323
|
+
const refs = parent !== void 0 && parent.refs || mayRef && Elysia.#hookHasString(added);
|
|
324
|
+
this["~hookChain"] = propagated ? {
|
|
325
|
+
added,
|
|
326
|
+
parent,
|
|
327
|
+
refs,
|
|
328
|
+
scope,
|
|
329
|
+
propagated,
|
|
330
|
+
owner
|
|
331
|
+
} : {
|
|
219
332
|
added,
|
|
220
333
|
parent,
|
|
221
|
-
refs
|
|
334
|
+
refs,
|
|
222
335
|
scope,
|
|
223
|
-
owner
|
|
336
|
+
owner
|
|
224
337
|
};
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
if (this
|
|
228
|
-
|
|
229
|
-
if (typeof f === "function" && !require_utils.fnOrigin.has(f)) require_utils.fnOrigin.set(f, this.#hash);
|
|
230
|
-
};
|
|
231
|
-
if (Array.isArray(fn)) for (const f of fn) tag(f);
|
|
232
|
-
else tag(fn);
|
|
233
|
-
}
|
|
234
|
-
return this;
|
|
338
|
+
}
|
|
339
|
+
#tagOrigin(value) {
|
|
340
|
+
if (this.hash === void 0) return;
|
|
341
|
+
for (const fn of Array.isArray(value) ? value : [value]) if (typeof fn === "function" && !require_utils.fnOrigin.has(fn)) require_utils.fnOrigin.set(fn, this.hash);
|
|
235
342
|
}
|
|
236
343
|
#onBranch(type, scopeOrFn, fn) {
|
|
237
344
|
return fn ? this.#on(type, fn, scopeOrFn) : this.#on(type, scopeOrFn);
|
|
@@ -248,7 +355,7 @@ var Elysia = class Elysia {
|
|
|
248
355
|
}
|
|
249
356
|
parser(name, fn) {
|
|
250
357
|
this.#assertMutable("parser");
|
|
251
|
-
const ext = this
|
|
358
|
+
const ext = this.ext;
|
|
252
359
|
const parsers = ext.parser ??= require_utils.nullObject();
|
|
253
360
|
parsers[name] = fn;
|
|
254
361
|
return this;
|
|
@@ -269,9 +376,7 @@ var Elysia = class Elysia {
|
|
|
269
376
|
*/
|
|
270
377
|
setup(handler) {
|
|
271
378
|
this.#assertMutable("setup");
|
|
272
|
-
|
|
273
|
-
if (Array.isArray(handler)) arr.push(...handler);
|
|
274
|
-
else arr.push(handler);
|
|
379
|
+
(this.ext.setup ??= []).push(...[].concat(handler));
|
|
275
380
|
return this;
|
|
276
381
|
}
|
|
277
382
|
transform(scopeOrFn, fn) {
|
|
@@ -281,26 +386,18 @@ var Elysia = class Elysia {
|
|
|
281
386
|
return this.#onBranch("beforeHandle", scopeOrFn, fn);
|
|
282
387
|
}
|
|
283
388
|
derive(scopeOrFn, fn) {
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
return
|
|
389
|
+
return this.#derive(scopeOrFn, fn);
|
|
390
|
+
}
|
|
391
|
+
#derive(scopeOrFn, fn, map) {
|
|
392
|
+
this.#onBranch("beforeHandle", scopeOrFn, fn);
|
|
393
|
+
const d = fn ?? scopeOrFn;
|
|
394
|
+
const entries = this["~hookChain"].added["~deriveEntries"] ??= [];
|
|
395
|
+
if (Array.isArray(d)) for (const f of d) entries.push(map ? map(f) : f);
|
|
396
|
+
else entries.push(map ? map(d) : d);
|
|
397
|
+
return this;
|
|
293
398
|
}
|
|
294
399
|
mapDerive(scopeOrFn, fn) {
|
|
295
|
-
|
|
296
|
-
const node = this["~hookChain"];
|
|
297
|
-
if (node?.added) {
|
|
298
|
-
const d = fn ?? scopeOrFn;
|
|
299
|
-
const entries = node.added["~deriveEntries"] ??= [];
|
|
300
|
-
if (Array.isArray(d)) for (const f of d) entries.push(require_utils.mapDeriveEntry(f));
|
|
301
|
-
else entries.push(require_utils.mapDeriveEntry(d));
|
|
302
|
-
}
|
|
303
|
-
return result;
|
|
400
|
+
return this.#derive(scopeOrFn, fn, require_utils.mapDeriveEntry);
|
|
304
401
|
}
|
|
305
402
|
afterHandle(scopeOrFn, fn) {
|
|
306
403
|
return this.#onBranch("afterHandle", scopeOrFn, fn);
|
|
@@ -315,26 +412,19 @@ var Elysia = class Elysia {
|
|
|
315
412
|
this.#assertMutable("error");
|
|
316
413
|
switch (arguments.length) {
|
|
317
414
|
case 1:
|
|
318
|
-
if (scopeOrFnOrError && typeof scopeOrFnOrError === "object")
|
|
319
|
-
for (const [code, ErrorClass] of Object.entries(scopeOrFnOrError)) if (typeof ErrorClass === "function") (this.#ext.error ??= /* @__PURE__ */ new Map()).set(ErrorClass, code);
|
|
320
|
-
return this;
|
|
321
|
-
}
|
|
415
|
+
if (scopeOrFnOrError && typeof scopeOrFnOrError === "object") return this;
|
|
322
416
|
return this.#onBranch("error", scopeOrFnOrError);
|
|
323
417
|
case 2:
|
|
324
|
-
if (typeof scopeOrFnOrError === "function" &&
|
|
325
|
-
const run = typeof fnOrError === "function" ? fnOrError : () => fnOrError;
|
|
326
|
-
(this.#ext.error ??= /* @__PURE__ */ new Map()).set(scopeOrFnOrError, scopeOrFnOrError.name);
|
|
327
|
-
return this.#onBranch("error", require_utils.createErrorEventHandler(run, scopeOrFnOrError));
|
|
328
|
-
}
|
|
418
|
+
if (typeof scopeOrFnOrError === "function" && scopeOrFnOrError.prototype instanceof Object) return this.#errorClass(scopeOrFnOrError, fnOrError);
|
|
329
419
|
return this.#onBranch("error", scopeOrFnOrError, fnOrError);
|
|
330
|
-
case 3:
|
|
331
|
-
const run = typeof fn === "function" ? fn : () => fn;
|
|
332
|
-
(this.#ext.error ??= /* @__PURE__ */ new Map()).set(fnOrError, fnOrError.name);
|
|
333
|
-
return this.#onBranch("error", scopeOrFnOrError, require_utils.createErrorEventHandler(run, fnOrError));
|
|
334
|
-
}
|
|
420
|
+
case 3: return this.#errorClass(fnOrError, fn, scopeOrFnOrError);
|
|
335
421
|
}
|
|
336
422
|
return this;
|
|
337
423
|
}
|
|
424
|
+
#errorClass(ErrorClass, fn, scope) {
|
|
425
|
+
const run = typeof fn === "function" ? fn : () => fn;
|
|
426
|
+
return this.#on("error", require_utils.createErrorEventHandler(run, ErrorClass), scope);
|
|
427
|
+
}
|
|
338
428
|
trace(scopeOrFn, fn) {
|
|
339
429
|
return this.#onBranch("trace", scopeOrFn, fn);
|
|
340
430
|
}
|
|
@@ -353,21 +443,13 @@ var Elysia = class Elysia {
|
|
|
353
443
|
if (node.scope !== "global") {
|
|
354
444
|
node.scope = scope;
|
|
355
445
|
node.propagated = false;
|
|
356
|
-
for (const key in node.added) {
|
|
357
|
-
if (!require_utils.eventProperties.has(key)) continue;
|
|
358
|
-
const v = node.added[key];
|
|
359
|
-
const fns = Array.isArray(v) ? v : [v];
|
|
360
|
-
for (const fn of fns) {
|
|
361
|
-
if (typeof fn !== "function") continue;
|
|
362
|
-
if (scope === "plugin") this.#hasPlugin = true;
|
|
363
|
-
else this.#hasGlobal = true;
|
|
364
|
-
}
|
|
365
|
-
}
|
|
366
446
|
}
|
|
367
447
|
node = node.parent;
|
|
368
448
|
}
|
|
369
449
|
}
|
|
370
450
|
guard() {
|
|
451
|
+
const maybeHook = typeof arguments[0] === "string" ? arguments[1] : arguments[0];
|
|
452
|
+
if (maybeHook && typeof maybeHook === "object" && "as" in maybeHook && maybeHook.as !== void 0) throw new Error(`[elysia] guard({ as: '${maybeHook.as}' }) was removed in 2.0. Pass the scope as the first argument instead: guard('${maybeHook.as === "scoped" ? "plugin" : maybeHook.as}', { ... }). To combine a guard schema with a route's own schema for the same slot, add schema: 'merge'.`);
|
|
371
453
|
if (arguments.length === 1) return this.#guard("local", arguments[0]);
|
|
372
454
|
if (arguments.length === 2) {
|
|
373
455
|
if (typeof arguments[1] === "function") return this.group("", arguments[0], arguments[1]);
|
|
@@ -376,21 +458,12 @@ var Elysia = class Elysia {
|
|
|
376
458
|
return this;
|
|
377
459
|
}
|
|
378
460
|
#guard(scope, hook) {
|
|
461
|
+
assertScope(scope);
|
|
462
|
+
if (hook) assertSchemaShape(hook, ".guard()");
|
|
379
463
|
hook = require_schema_snapshot.snapshotHookSchemas(hook);
|
|
380
464
|
require_utils.hookToGuard(hook);
|
|
381
|
-
const
|
|
382
|
-
|
|
383
|
-
if (this.#hash !== void 0 && !require_utils.fnOrigin.has(fn)) require_utils.fnOrigin.set(fn, this.#hash);
|
|
384
|
-
};
|
|
385
|
-
for (const key in hook) {
|
|
386
|
-
if (!require_utils.eventProperties.has(key)) continue;
|
|
387
|
-
const raw = hook[key];
|
|
388
|
-
if (raw === null) continue;
|
|
389
|
-
if (Array.isArray(raw)) for (const fn of raw) trackFn(fn);
|
|
390
|
-
else trackFn(raw);
|
|
391
|
-
}
|
|
392
|
-
if (hook.derive) if (Array.isArray(hook.derive)) for (const fn of hook.derive) trackFn(fn);
|
|
393
|
-
else trackFn(hook.derive);
|
|
465
|
+
for (const key in hook) if (require_utils.eventProperties.has(key)) this.#tagOrigin(hook[key]);
|
|
466
|
+
this.#tagOrigin(hook.derive);
|
|
394
467
|
this.#pushHook(hook, scope);
|
|
395
468
|
return this;
|
|
396
469
|
}
|
|
@@ -409,7 +482,7 @@ var Elysia = class Elysia {
|
|
|
409
482
|
prefix
|
|
410
483
|
} : void 0);
|
|
411
484
|
child["~scopeChild"] = true;
|
|
412
|
-
child
|
|
485
|
+
child.scopeParent = this;
|
|
413
486
|
(this["~scopeChildren"] ??= []).push(child);
|
|
414
487
|
const src = this["~ext"];
|
|
415
488
|
if (src) {
|
|
@@ -432,7 +505,7 @@ var Elysia = class Elysia {
|
|
|
432
505
|
this.#use(child);
|
|
433
506
|
return this;
|
|
434
507
|
}
|
|
435
|
-
get
|
|
508
|
+
get ext() {
|
|
436
509
|
return this["~ext"] ??= require_utils.nullObject();
|
|
437
510
|
}
|
|
438
511
|
["~resolvedCapability"](kind) {
|
|
@@ -451,9 +524,9 @@ var Elysia = class Elysia {
|
|
|
451
524
|
return provider;
|
|
452
525
|
}
|
|
453
526
|
#ensureMacroTable() {
|
|
454
|
-
const ext = this
|
|
527
|
+
const ext = this.ext;
|
|
455
528
|
if (ext.macro) return ext.macro;
|
|
456
|
-
const parent = this["~scopeChild"] ? this
|
|
529
|
+
const parent = this["~scopeChild"] ? this.scopeParent : void 0;
|
|
457
530
|
ext.macro = parent ? Object.create(parent.#ensureMacroTable()) : require_utils.nullObject();
|
|
458
531
|
return ext.macro;
|
|
459
532
|
}
|
|
@@ -461,41 +534,30 @@ var Elysia = class Elysia {
|
|
|
461
534
|
this.#assertMutable("guard");
|
|
462
535
|
let hook = _hook;
|
|
463
536
|
if (hook.derive) {
|
|
464
|
-
const
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
promoted[key] = hook[key];
|
|
468
|
-
}
|
|
469
|
-
const extras = [];
|
|
470
|
-
if (hook.derive) if (Array.isArray(hook.derive)) extras.push(...hook.derive);
|
|
471
|
-
else extras.push(hook.derive);
|
|
537
|
+
const { derive, ...rest } = hook;
|
|
538
|
+
const extras = [].concat(derive);
|
|
539
|
+
hook = Object.assign(require_utils.nullObject(), rest);
|
|
472
540
|
if (extras.length) {
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
else promoted.beforeHandle = extras;
|
|
476
|
-
(promoted["~deriveEntries"] ??= []).push(...extras);
|
|
541
|
+
hook.beforeHandle = extras.concat(hook.beforeHandle || []);
|
|
542
|
+
(hook["~deriveEntries"] ??= []).push(...extras);
|
|
477
543
|
}
|
|
478
|
-
hook = promoted;
|
|
479
544
|
}
|
|
480
545
|
if (hook.trace) this["~hasTrace"] = true;
|
|
481
|
-
|
|
482
|
-
this["~hookChain"] = {
|
|
483
|
-
added: hook,
|
|
484
|
-
parent,
|
|
485
|
-
refs: parent !== void 0 && parent.refs || Elysia.#hookHasString(hook),
|
|
486
|
-
scope,
|
|
487
|
-
owner: this
|
|
488
|
-
};
|
|
546
|
+
this.#link(hook, scope, this);
|
|
489
547
|
return this;
|
|
490
548
|
}
|
|
491
|
-
macro(macro) {
|
|
549
|
+
macro(macro, definition) {
|
|
492
550
|
this.#assertMutable("macro");
|
|
493
551
|
if (typeof macro === "function") throw new Error("use `.macro({ name: fn })` instead of `.macro(fn)`");
|
|
552
|
+
if (definition != null || typeof macro === "string") throw new Error("[Elysia] .macro(name, definition) was removed in 2.0 — use .macro({ [name]: definition })");
|
|
494
553
|
const m = this.#ensureMacroTable();
|
|
495
|
-
const baseline = this
|
|
554
|
+
const baseline = this.macroBaseline;
|
|
496
555
|
for (const key in macro) {
|
|
497
|
-
if (typeof macro[key] === "object")
|
|
498
|
-
|
|
556
|
+
if (typeof macro[key] === "object") {
|
|
557
|
+
if (macro[key]) assertSchemaShape(macro[key], `.macro(${key})`);
|
|
558
|
+
macro[key] = require_utils.hookToGuard(macro[key]);
|
|
559
|
+
}
|
|
560
|
+
if (this.hash !== void 0 && !require_utils.macroOrigin.has(macro[key])) require_utils.macroOrigin.set(macro[key], this.hash);
|
|
499
561
|
if (baseline?.has(key) && key in m && m[key] !== macro[key]) throw new Error(`[Elysia] Macro "${key}" can be only define once`);
|
|
500
562
|
}
|
|
501
563
|
Object.assign(m, macro);
|
|
@@ -518,7 +580,7 @@ var Elysia = class Elysia {
|
|
|
518
580
|
const seedSource = hook.seed ?? value;
|
|
519
581
|
const seedType = typeof seedSource;
|
|
520
582
|
let seedKey;
|
|
521
|
-
if (seedSource === null ||
|
|
583
|
+
if (seedSource === null || seedType !== "object") seedKey = key + "\0" + seedType + "\0" + String(seedSource);
|
|
522
584
|
else try {
|
|
523
585
|
seedKey = key + "\0object\0" + JSON.stringify(seedSource, require_utils.serializeMacroSeed);
|
|
524
586
|
} catch {
|
|
@@ -533,7 +595,7 @@ var Elysia = class Elysia {
|
|
|
533
595
|
}
|
|
534
596
|
for (const k in hook) {
|
|
535
597
|
const v = hook[k];
|
|
536
|
-
if (k === "seed") continue;
|
|
598
|
+
if (k === "seed" || k === "meta" || k === "$type") continue;
|
|
537
599
|
if (k === "introspect") {
|
|
538
600
|
v?.(input);
|
|
539
601
|
delete input[key];
|
|
@@ -582,11 +644,9 @@ var Elysia = class Elysia {
|
|
|
582
644
|
insertions.set(k, at + added.length);
|
|
583
645
|
} else if (k in input) {
|
|
584
646
|
if (Array.isArray(input[k])) {
|
|
585
|
-
|
|
586
|
-
for (const item of v) if (!input[k].some((e) => e === item)) input[k].unshift(item);
|
|
587
|
-
} else if (!input[k].some((item) => item === v)) input[k].unshift(v);
|
|
647
|
+
for (const item of Array.isArray(v) ? v : [v]) if (!input[k].includes(item)) input[k].unshift(item);
|
|
588
648
|
} else if (input[k] !== v) input[k] = [v, input[k]];
|
|
589
|
-
} else input[k] =
|
|
649
|
+
} else input[k] = Array.isArray(v) ? v.slice() : v;
|
|
590
650
|
delete input[key];
|
|
591
651
|
}
|
|
592
652
|
}
|
|
@@ -594,7 +654,7 @@ var Elysia = class Elysia {
|
|
|
594
654
|
}
|
|
595
655
|
use(app) {
|
|
596
656
|
if (!app) return this;
|
|
597
|
-
|
|
657
|
+
this.#assertMutable("use");
|
|
598
658
|
if (typeof app === "function") return this.#useFn(app);
|
|
599
659
|
if (typeof app.then === "function") return this.#useAsync(app);
|
|
600
660
|
if (Array.isArray(app)) {
|
|
@@ -608,21 +668,37 @@ var Elysia = class Elysia {
|
|
|
608
668
|
return this;
|
|
609
669
|
}
|
|
610
670
|
#useFn(app) {
|
|
611
|
-
const prevBaseline = this
|
|
671
|
+
const prevBaseline = this.macroBaseline;
|
|
612
672
|
const baseline = /* @__PURE__ */ new Set();
|
|
613
673
|
const existingMacro = this["~ext"]?.macro;
|
|
614
674
|
if (existingMacro) for (const k in existingMacro) baseline.add(k);
|
|
615
|
-
this
|
|
675
|
+
this.macroBaseline = baseline;
|
|
676
|
+
let wantSnapshot = false;
|
|
677
|
+
let settled = false;
|
|
678
|
+
let beforeMacro;
|
|
679
|
+
queueMicrotask(() => {
|
|
680
|
+
if (wantSnapshot && !settled) {
|
|
681
|
+
beforeMacro = new Map(Object.entries(this["~ext"]?.macro ?? require_utils.nullObject()));
|
|
682
|
+
(this.macroSnapshots ??= /* @__PURE__ */ new Set()).add(beforeMacro);
|
|
683
|
+
}
|
|
684
|
+
});
|
|
616
685
|
const result = app(this);
|
|
617
|
-
this
|
|
686
|
+
this.macroBaseline = prevBaseline;
|
|
618
687
|
if (result && typeof result.then === "function") {
|
|
619
|
-
|
|
620
|
-
return this.#useAsync(result.then((value) => {
|
|
688
|
+
wantSnapshot = true;
|
|
689
|
+
return this.#useAsync(Promise.resolve(result).then((value) => {
|
|
690
|
+
settled = true;
|
|
691
|
+
if (!beforeMacro) return value;
|
|
692
|
+
this.macroSnapshots?.delete(beforeMacro);
|
|
621
693
|
const after = this["~ext"]?.macro;
|
|
622
694
|
if (after) {
|
|
623
695
|
for (const [k, def] of Object.entries(after)) if (beforeMacro.get(k) !== def) throw new Error(`Macro ${k} can only run in sync plugin`);
|
|
624
696
|
}
|
|
625
697
|
return value;
|
|
698
|
+
}, (err) => {
|
|
699
|
+
settled = true;
|
|
700
|
+
if (beforeMacro) this.macroSnapshots?.delete(beforeMacro);
|
|
701
|
+
throw err;
|
|
626
702
|
}));
|
|
627
703
|
}
|
|
628
704
|
return this;
|
|
@@ -633,17 +709,17 @@ var Elysia = class Elysia {
|
|
|
633
709
|
if (app["~introspect"] || config?.introspect) this["~introspect"] = true;
|
|
634
710
|
const name = config?.name;
|
|
635
711
|
if (name) {
|
|
636
|
-
const hash = app
|
|
637
|
-
if (this
|
|
638
|
-
this
|
|
639
|
-
this
|
|
712
|
+
const hash = app.hash;
|
|
713
|
+
if (this.childrenHash?.has(hash)) return;
|
|
714
|
+
this.childrenHash ??= /* @__PURE__ */ new Set();
|
|
715
|
+
this.childrenHash.add(hash);
|
|
640
716
|
(addedByThisCall ??= /* @__PURE__ */ new Set()).add(hash);
|
|
641
717
|
}
|
|
642
|
-
if (app
|
|
718
|
+
if (app.childrenHash) addedByThisCall = this.#absorbChildrenHash(app, addedByThisCall);
|
|
643
719
|
if (app["~ext"]) this.#assertMacroUnique(app, addedByThisCall);
|
|
644
720
|
if (app["~hasTrace"]) this["~hasTrace"] = true;
|
|
645
|
-
if (app
|
|
646
|
-
if (app
|
|
721
|
+
if (app.declaredRoutes === void 0 && app["~routeTable"]?.length) app.#materializeDeclaredRoutes();
|
|
722
|
+
if (app.declaredRoutes?.length) {
|
|
647
723
|
if (app["~hasWS"]) this["~hasWS"] = true;
|
|
648
724
|
this.#emitChildRoutes(app, this["~hookChain"], name);
|
|
649
725
|
}
|
|
@@ -653,17 +729,17 @@ var Elysia = class Elysia {
|
|
|
653
729
|
}
|
|
654
730
|
const hookChain = app["~hookChain"];
|
|
655
731
|
if (app["~ext"]) this.#absorbExt(app);
|
|
656
|
-
if (
|
|
732
|
+
if (hookChain) this.#propagateHooks(app, hookChain, addedByThisCall);
|
|
657
733
|
}
|
|
658
734
|
#absorbChildrenHash(app, addedByThisCall) {
|
|
659
|
-
const incoming = app
|
|
660
|
-
if (this
|
|
661
|
-
if (this
|
|
662
|
-
this
|
|
735
|
+
const incoming = app.childrenHash;
|
|
736
|
+
if (this.childrenHash) for (const h of incoming) {
|
|
737
|
+
if (this.childrenHash.has(h)) continue;
|
|
738
|
+
this.childrenHash.add(h);
|
|
663
739
|
(addedByThisCall ??= /* @__PURE__ */ new Set()).add(h);
|
|
664
740
|
}
|
|
665
741
|
else {
|
|
666
|
-
this
|
|
742
|
+
this.childrenHash = new Set(incoming);
|
|
667
743
|
addedByThisCall = new Set(incoming);
|
|
668
744
|
}
|
|
669
745
|
return addedByThisCall;
|
|
@@ -682,7 +758,7 @@ var Elysia = class Elysia {
|
|
|
682
758
|
if (existing === incoming) continue;
|
|
683
759
|
const origin = require_utils.macroOrigin.get(existing);
|
|
684
760
|
if (origin !== void 0 && origin === require_utils.macroOrigin.get(incoming)) continue;
|
|
685
|
-
if (addedByThisCall) for (const h of addedByThisCall) this
|
|
761
|
+
if (addedByThisCall) for (const h of addedByThisCall) this.childrenHash.delete(h);
|
|
686
762
|
throw new Error(`[Elysia] Macro "${macroName}" can be only define once`);
|
|
687
763
|
}
|
|
688
764
|
}
|
|
@@ -695,80 +771,54 @@ var Elysia = class Elysia {
|
|
|
695
771
|
* Keep the cold blocks in their own frames.
|
|
696
772
|
*/
|
|
697
773
|
#absorbExt(app) {
|
|
698
|
-
const { decorator, store, headers, models, parser, macro,
|
|
774
|
+
const { decorator, store, headers, models, parser, macro, hoc, setup, cleanup, capability } = app["~ext"];
|
|
699
775
|
const ext = this["~ext"] ??= require_utils.nullObject();
|
|
700
|
-
if (decorator)
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
776
|
+
if (decorator) {
|
|
777
|
+
if (ext.decorator) require_utils.mergeDeep(ext.decorator, decorator, void 0, true, false, void 0, { map: void 0 });
|
|
778
|
+
else ext.decorator = require_utils.clonePlainDecorators(decorator);
|
|
779
|
+
markStoredSingletons(ext.decorator, decorator);
|
|
780
|
+
}
|
|
781
|
+
if (store) {
|
|
782
|
+
if (ext.store) require_utils.mergeDeep(ext.store, store);
|
|
783
|
+
else ext.store = Object.assign(require_utils.nullObject(), store);
|
|
784
|
+
markStoredSingletons(ext.store, store);
|
|
785
|
+
}
|
|
786
|
+
if (headers) ext.headers = Object.assign(ext.headers ?? require_utils.nullObject(), headers);
|
|
787
|
+
if (models) ext.models = Object.assign(ext.models ?? require_utils.nullObject(), models);
|
|
788
|
+
if (parser) ext.parser = Object.assign(ext.parser ?? require_utils.nullObject(), parser);
|
|
710
789
|
if (macro) if (app["~scopeChild"]) {
|
|
711
|
-
const pluginMacros = app
|
|
790
|
+
const pluginMacros = app.pluginMacros;
|
|
712
791
|
let changed = false;
|
|
713
792
|
if (pluginMacros?.size) {
|
|
714
793
|
const target = this.#ensureMacroTable();
|
|
715
794
|
for (const [name, def] of pluginMacros) if (!(name in target)) {
|
|
716
795
|
target[name] = def;
|
|
717
796
|
changed = true;
|
|
718
|
-
if (this["~scopeChild"]) (this
|
|
797
|
+
if (this["~scopeChild"]) (this.pluginMacros ??= /* @__PURE__ */ new Map()).set(name, def);
|
|
719
798
|
}
|
|
720
799
|
}
|
|
721
800
|
if (changed) require_utils.invalidateMacroEpoch();
|
|
722
801
|
} else {
|
|
723
802
|
Object.assign(this.#ensureMacroTable(), macro);
|
|
724
803
|
if (this["~scopeChild"]) {
|
|
725
|
-
const pluginMacros = this
|
|
804
|
+
const pluginMacros = this.pluginMacros ??= /* @__PURE__ */ new Map();
|
|
726
805
|
for (const name in macro) pluginMacros.set(name, macro[name]);
|
|
727
806
|
}
|
|
728
807
|
require_utils.invalidateMacroEpoch();
|
|
729
808
|
}
|
|
730
|
-
if (
|
|
731
|
-
|
|
732
|
-
if (
|
|
733
|
-
const seen = new Set(ext.hoc);
|
|
734
|
-
for (const fn of hoc) if (!seen.has(fn)) {
|
|
735
|
-
seen.add(fn);
|
|
736
|
-
ext.hoc.push(fn);
|
|
737
|
-
}
|
|
738
|
-
} else ext.hoc = hoc.slice();
|
|
739
|
-
if (setup) if (ext.setup) {
|
|
740
|
-
const seen = new Set(ext.setup);
|
|
741
|
-
for (const fn of setup) if (!seen.has(fn)) {
|
|
742
|
-
seen.add(fn);
|
|
743
|
-
ext.setup.push(fn);
|
|
744
|
-
}
|
|
745
|
-
} else ext.setup = setup.slice();
|
|
746
|
-
if (cleanup) if (ext.cleanup) {
|
|
747
|
-
const seen = new Set(ext.cleanup);
|
|
748
|
-
for (const fn of cleanup) if (!seen.has(fn)) {
|
|
749
|
-
seen.add(fn);
|
|
750
|
-
ext.cleanup.push(fn);
|
|
751
|
-
}
|
|
752
|
-
} else ext.cleanup = cleanup.slice();
|
|
809
|
+
if (hoc) ext.hoc = mergeExtCallbacks(ext.hoc, hoc);
|
|
810
|
+
if (setup) ext.setup = mergeExtCallbacks(ext.setup, setup);
|
|
811
|
+
if (cleanup) ext.cleanup = mergeExtCallbacks(ext.cleanup, cleanup);
|
|
753
812
|
if (capability) {
|
|
754
813
|
const target = ext.capability ??= require_utils.nullObject();
|
|
755
|
-
if (capability.trace) {
|
|
756
|
-
const incoming = capability.trace.provider;
|
|
757
|
-
if (!target.trace) target.trace = { provider: incoming };
|
|
758
|
-
}
|
|
814
|
+
if (capability.trace) target.trace ??= { provider: capability.trace.provider };
|
|
759
815
|
if (capability.ws) {
|
|
760
|
-
const incoming = capability.ws.provider;
|
|
761
|
-
const existing = target.ws;
|
|
762
816
|
const incomingOptions = capability.ws.options;
|
|
763
|
-
|
|
764
|
-
provider:
|
|
765
|
-
options:
|
|
766
|
-
depth: entry.depth + 1,
|
|
767
|
-
value: entry.value,
|
|
768
|
-
origin: entry.origin
|
|
769
|
-
})) : void 0
|
|
817
|
+
const existing = target.ws ??= {
|
|
818
|
+
provider: capability.ws.provider,
|
|
819
|
+
options: void 0
|
|
770
820
|
};
|
|
771
|
-
|
|
821
|
+
if (incomingOptions?.length) {
|
|
772
822
|
const base = existing.options ?? [];
|
|
773
823
|
const seen = new Set(base.map((e) => e.origin));
|
|
774
824
|
let next;
|
|
@@ -798,7 +848,6 @@ var Elysia = class Elysia {
|
|
|
798
848
|
let globalEvents;
|
|
799
849
|
let pluginMayRef = false;
|
|
800
850
|
let globalMayRef = false;
|
|
801
|
-
if (app.#hasGlobal) this.#hasGlobal = true;
|
|
802
851
|
const nodes = useNodesBuffer;
|
|
803
852
|
nodes.length = 0;
|
|
804
853
|
let current = hookChain;
|
|
@@ -826,10 +875,7 @@ var Elysia = class Elysia {
|
|
|
826
875
|
const target = isGlobal ? globalEvents ??= require_utils.nullObject() : pluginEvents ??= require_utils.nullObject();
|
|
827
876
|
if (isGlobal) globalMayRef = true;
|
|
828
877
|
else pluginMayRef = true;
|
|
829
|
-
for (const s of schemas)
|
|
830
|
-
(target.schemas ??= []).push(s);
|
|
831
|
-
if (isGlobal) this.#hasGlobal = true;
|
|
832
|
-
}
|
|
878
|
+
for (const s of schemas) (target.schemas ??= []).push(s);
|
|
833
879
|
continue;
|
|
834
880
|
}
|
|
835
881
|
if (key === "schema") continue;
|
|
@@ -839,13 +885,12 @@ var Elysia = class Elysia {
|
|
|
839
885
|
const count = many ? raw.length : 1;
|
|
840
886
|
for (let f = 0; f < count; f++) {
|
|
841
887
|
const fn = many ? raw[f] : raw;
|
|
842
|
-
const childrenHash = this
|
|
888
|
+
const childrenHash = this.childrenHash;
|
|
843
889
|
if (childrenHash !== void 0) {
|
|
844
890
|
const origin = require_utils.fnOrigin.get(fn);
|
|
845
891
|
if (origin !== void 0 && childrenHash.has(origin) && !addedByThisCall?.has(origin)) continue;
|
|
846
892
|
}
|
|
847
893
|
require_utils.pushField(isGlobal ? globalEvents ??= require_utils.nullObject() : pluginEvents ??= require_utils.nullObject(), key, fn);
|
|
848
|
-
if (isGlobal) this.#hasGlobal = true;
|
|
849
894
|
}
|
|
850
895
|
continue;
|
|
851
896
|
}
|
|
@@ -864,40 +909,46 @@ var Elysia = class Elysia {
|
|
|
864
909
|
}
|
|
865
910
|
}
|
|
866
911
|
nodes.length = 0;
|
|
867
|
-
if (globalEvents)
|
|
868
|
-
|
|
869
|
-
this["~hookChain"] = {
|
|
870
|
-
added: globalEvents,
|
|
871
|
-
parent,
|
|
872
|
-
refs: parent !== void 0 && parent.refs || globalMayRef && Elysia.#hookHasString(globalEvents),
|
|
873
|
-
scope: "global",
|
|
874
|
-
propagated: true,
|
|
875
|
-
owner: app
|
|
876
|
-
};
|
|
877
|
-
}
|
|
878
|
-
if (pluginEvents) {
|
|
879
|
-
const parent = this["~hookChain"];
|
|
880
|
-
this["~hookChain"] = {
|
|
881
|
-
added: pluginEvents,
|
|
882
|
-
parent,
|
|
883
|
-
refs: parent !== void 0 && parent.refs || pluginMayRef && Elysia.#hookHasString(pluginEvents),
|
|
884
|
-
scope: "plugin",
|
|
885
|
-
propagated: true,
|
|
886
|
-
owner: app
|
|
887
|
-
};
|
|
888
|
-
}
|
|
912
|
+
if (globalEvents) this.#link(globalEvents, "global", app, globalMayRef, true);
|
|
913
|
+
if (pluginEvents) this.#link(pluginEvents, "plugin", app, pluginMayRef, true);
|
|
889
914
|
}
|
|
890
915
|
#emitChildRoutes(app, preChain, name) {
|
|
891
|
-
const declared = app
|
|
892
|
-
if (!declared?.length) return;
|
|
916
|
+
const declared = app.declaredRoutes;
|
|
893
917
|
const limit = declared.length;
|
|
918
|
+
const tail = app["~hookChain"];
|
|
919
|
+
let recent;
|
|
920
|
+
let hasLocal = false;
|
|
894
921
|
let lastChildChain;
|
|
895
922
|
let lastCombined;
|
|
923
|
+
let lastTailChild = null;
|
|
924
|
+
let lastTailCombined;
|
|
896
925
|
for (let i = 0; i < limit; i++) {
|
|
897
926
|
const route = declared[i];
|
|
898
927
|
const childChain = route[6];
|
|
928
|
+
const absorbed = tail !== void 0 && route[3] !== app;
|
|
929
|
+
if (absorbed && recent === void 0) {
|
|
930
|
+
recent = /* @__PURE__ */ new Set();
|
|
931
|
+
for (let node = tail; node && "added" in node; node = node.parent) {
|
|
932
|
+
recent.add(node);
|
|
933
|
+
if (require_utils.isLocalScope(node.scope)) {
|
|
934
|
+
hasLocal = true;
|
|
935
|
+
break;
|
|
936
|
+
}
|
|
937
|
+
}
|
|
938
|
+
}
|
|
899
939
|
let inheritedChain;
|
|
900
|
-
if (
|
|
940
|
+
if (absorbed && hasLocal && !recent.has(require_utils.rootSnapshot(childChain))) {
|
|
941
|
+
if (childChain !== lastTailChild) {
|
|
942
|
+
lastTailChild = childChain;
|
|
943
|
+
lastTailCombined = {
|
|
944
|
+
combine: childChain,
|
|
945
|
+
over: preChain,
|
|
946
|
+
tail,
|
|
947
|
+
refs: !!(childChain?.refs || preChain?.refs || tail.refs)
|
|
948
|
+
};
|
|
949
|
+
}
|
|
950
|
+
inheritedChain = lastTailCombined;
|
|
951
|
+
} else if (childChain === void 0) inheritedChain = preChain;
|
|
901
952
|
else if (preChain === void 0) inheritedChain = childChain;
|
|
902
953
|
else if (childChain === lastChildChain) inheritedChain = lastCombined;
|
|
903
954
|
else {
|
|
@@ -926,55 +977,91 @@ var Elysia = class Elysia {
|
|
|
926
977
|
], source);
|
|
927
978
|
}
|
|
928
979
|
get modules() {
|
|
929
|
-
const ready = this
|
|
980
|
+
const ready = this.ready;
|
|
930
981
|
if (!ready) {
|
|
931
|
-
if (this
|
|
982
|
+
if (this._error !== void 0) return Promise.reject(this._error.error);
|
|
932
983
|
return Promise.resolve();
|
|
933
984
|
}
|
|
934
985
|
return ready.then(() => {
|
|
935
|
-
if (this
|
|
936
|
-
if (this
|
|
986
|
+
if (this._error !== void 0) throw this._error.error;
|
|
987
|
+
if (this.ready && this.ready !== ready) return this.modules;
|
|
937
988
|
});
|
|
938
989
|
}
|
|
939
990
|
get pending() {
|
|
940
|
-
return this
|
|
991
|
+
return this._pending > 0;
|
|
941
992
|
}
|
|
942
993
|
#useAsync(promise) {
|
|
943
|
-
if (!this
|
|
944
|
-
this
|
|
945
|
-
const next = (this
|
|
994
|
+
if (!this.ready) this._error = void 0;
|
|
995
|
+
this._pending++;
|
|
996
|
+
const next = (this.ready ?? Promise.resolve()).then(() => promise).then((value) => {
|
|
946
997
|
const plugin = value && typeof value === "object" && "default" in value && value.default ? value.default : value;
|
|
998
|
+
const snapshots = this.macroSnapshots;
|
|
999
|
+
let before;
|
|
1000
|
+
if (snapshots?.size) {
|
|
1001
|
+
const macro = this["~ext"]?.macro;
|
|
1002
|
+
before = macro ? new Map(Object.entries(macro)) : /* @__PURE__ */ new Map();
|
|
1003
|
+
}
|
|
947
1004
|
if (plugin) try {
|
|
948
1005
|
this.use(plugin);
|
|
949
1006
|
} catch (err) {
|
|
950
|
-
this
|
|
1007
|
+
this._error ??= { error: err };
|
|
951
1008
|
console.error(err);
|
|
952
1009
|
}
|
|
1010
|
+
if (before) {
|
|
1011
|
+
const after = this["~ext"]?.macro;
|
|
1012
|
+
if (after) {
|
|
1013
|
+
for (const [k, def] of Object.entries(after)) if (before.get(k) !== def) {
|
|
1014
|
+
for (const snap of snapshots) if (snap.has(k) === before.has(k) && snap.get(k) === before.get(k)) snap.set(k, def);
|
|
1015
|
+
}
|
|
1016
|
+
}
|
|
1017
|
+
}
|
|
953
1018
|
}).finally(() => {
|
|
954
|
-
this
|
|
1019
|
+
this._pending--;
|
|
955
1020
|
}).then(() => {}, (err) => {
|
|
956
|
-
this
|
|
1021
|
+
this._error ??= { error: err };
|
|
957
1022
|
console.error(err);
|
|
958
|
-
}).finally(() =>
|
|
959
|
-
|
|
1023
|
+
}).finally(() => {
|
|
1024
|
+
if (this._pending > 0) return;
|
|
1025
|
+
if (this.ready !== next) return;
|
|
1026
|
+
const previousCompiled = this.compiled;
|
|
1027
|
+
const previousJitColdRemaining = this.jitColdRemaining;
|
|
1028
|
+
this.ready = void 0;
|
|
1029
|
+
this.compiled = void 0;
|
|
1030
|
+
this.fetchFn = void 0;
|
|
1031
|
+
this.routerBuilt = false;
|
|
1032
|
+
require_context.clearContextCache(this);
|
|
1033
|
+
try {
|
|
1034
|
+
this.#buildRouter(false);
|
|
1035
|
+
} catch (error) {
|
|
1036
|
+
this.compiled = previousCompiled;
|
|
1037
|
+
this.jitColdRemaining = previousJitColdRemaining;
|
|
1038
|
+
this._error ??= { error };
|
|
1039
|
+
}
|
|
1040
|
+
});
|
|
1041
|
+
this.ready = next;
|
|
960
1042
|
return this;
|
|
961
1043
|
}
|
|
962
|
-
#tryDrain(sentinel) {
|
|
963
|
-
if (this.#pending > 0) return;
|
|
964
|
-
if (this.#ready !== sentinel) return;
|
|
965
|
-
this.#ready = void 0;
|
|
966
|
-
this.#fetchFn = void 0;
|
|
967
|
-
this.#routerBuilt = false;
|
|
968
|
-
this.#buildRouter(false);
|
|
969
|
-
}
|
|
970
1044
|
#add(method, path, hookOrFn, fn, hasHook = fn !== void 0) {
|
|
971
1045
|
if (this["~Prefix"]) path = require_utils.joinPath(this["~Prefix"], path);
|
|
972
1046
|
else if (path && path.charCodeAt(0) !== 47) path = "/" + path;
|
|
1047
|
+
if (typeof hookOrFn === "function" && require_utils.isPlainObject(fn) && !hasHookKeys(hookOrFn)) {
|
|
1048
|
+
let isHook = hasHookKeys(fn);
|
|
1049
|
+
const macro = this["~ext"]?.macro;
|
|
1050
|
+
if (!isHook && macro) {
|
|
1051
|
+
for (const key in fn) if (key in macro) {
|
|
1052
|
+
isHook = true;
|
|
1053
|
+
break;
|
|
1054
|
+
}
|
|
1055
|
+
}
|
|
1056
|
+
if (isHook) throw new Error(`[Elysia] .${method === "*" ? "all" : method.toLowerCase()}('${path}', handler, hook) is the 1.x order; Elysia 2 takes (path, hook, handler) — see the 2.0 migration guide`);
|
|
1057
|
+
}
|
|
1058
|
+
if (hasHook && hookOrFn) assertSchemaShape(hookOrFn, `${method} ${path}`);
|
|
973
1059
|
const handler = hasHook ? fn : hookOrFn;
|
|
974
1060
|
const hook = hasHook ? require_schema_snapshot.snapshotHookSchemas(hookOrFn) : void 0;
|
|
975
1061
|
const appHook = this["~hookChain"];
|
|
976
|
-
|
|
977
|
-
|
|
1062
|
+
const verb = this["~generation"] === void 0 ? "method" : method === "*" ? "all" : method.toLowerCase();
|
|
1063
|
+
this.#assertMutable(verb in this ? verb : "method");
|
|
1064
|
+
(this.declaredRoutes ?? this.#materializeDeclaredRoutes()).push(appHook ? [
|
|
978
1065
|
method,
|
|
979
1066
|
path,
|
|
980
1067
|
handler,
|
|
@@ -993,76 +1080,61 @@ var Elysia = class Elysia {
|
|
|
993
1080
|
handler,
|
|
994
1081
|
this
|
|
995
1082
|
]);
|
|
996
|
-
if (this
|
|
997
|
-
this.#compiled = void 0;
|
|
998
|
-
this.#jitColdRemaining = void 0;
|
|
999
|
-
this.#jitTable = void 0;
|
|
1000
|
-
this.#jitRoute = void 0;
|
|
1001
|
-
this.#jitStatic = void 0;
|
|
1002
|
-
this.#jitAliases = void 0;
|
|
1003
|
-
this.#fetchFn = void 0;
|
|
1004
|
-
this.#routerBuilt = false;
|
|
1005
|
-
}
|
|
1083
|
+
if (this.routerBuilt || this.compiled !== void 0) this.#invalidate();
|
|
1006
1084
|
return this;
|
|
1007
1085
|
}
|
|
1008
1086
|
#assertMutable(api) {
|
|
1087
|
+
mutationEpoch++;
|
|
1009
1088
|
if (this["~generation"] === void 0) return;
|
|
1010
|
-
throw new Error(`[Elysia] .${api}() called after the app was sealed`);
|
|
1089
|
+
throw new Error(`[Elysia] .${api}() called after the app was sealed by its first request, listen or compile`);
|
|
1090
|
+
}
|
|
1091
|
+
get #isCacheable() {
|
|
1092
|
+
return this["~generation"] !== void 0 && this.routerBuilt && !require_compile_aot.Capture.isCapturing();
|
|
1093
|
+
}
|
|
1094
|
+
#cacheRoutes(generation) {
|
|
1095
|
+
if (this.cachedGeneration === generation && this.cachedEpoch === mutationEpoch) return;
|
|
1096
|
+
this.cachedGeneration = generation;
|
|
1097
|
+
this.cachedEpoch = mutationEpoch;
|
|
1098
|
+
this.cachedRoutes = void 0;
|
|
1099
|
+
this.cachedHistory = void 0;
|
|
1011
1100
|
}
|
|
1012
1101
|
#materializeDeclaredRoutes() {
|
|
1013
|
-
if (this
|
|
1102
|
+
if (this.declaredRoutes !== void 0) return this.declaredRoutes;
|
|
1014
1103
|
const table = this["~routeTable"];
|
|
1015
|
-
if (!table) return this
|
|
1104
|
+
if (!table) return this.declaredRoutes = [];
|
|
1016
1105
|
const routes = new Array(table.length);
|
|
1017
1106
|
for (let i = 0; i < table.length; i++) routes[i] = require_route_table.routeRow(table, i);
|
|
1018
|
-
return this
|
|
1107
|
+
return this.declaredRoutes = routes;
|
|
1019
1108
|
}
|
|
1020
1109
|
#registerRoute(route, source) {
|
|
1021
|
-
|
|
1022
|
-
const routes = this
|
|
1110
|
+
this.#assertMutable("route");
|
|
1111
|
+
const routes = this.declaredRoutes ?? this.#materializeDeclaredRoutes();
|
|
1023
1112
|
const sequence = routes.length;
|
|
1024
1113
|
routes.push(route);
|
|
1025
|
-
if (source) (this
|
|
1026
|
-
if (this
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1114
|
+
if (source) (this.routeSources ??= [])[sequence] = source;
|
|
1115
|
+
if (this.routerBuilt || this.compiled !== void 0) this.#invalidate();
|
|
1116
|
+
}
|
|
1117
|
+
#invalidate() {
|
|
1118
|
+
this.compiled = void 0;
|
|
1119
|
+
this.jitColdRemaining = void 0;
|
|
1120
|
+
this.jitTable = void 0;
|
|
1121
|
+
this.jitRoute = void 0;
|
|
1122
|
+
this.jitAliases = void 0;
|
|
1123
|
+
this.fetchFn = void 0;
|
|
1124
|
+
this.routerBuilt = false;
|
|
1036
1125
|
}
|
|
1037
1126
|
model(name, model) {
|
|
1038
1127
|
this.#assertMutable("model");
|
|
1039
|
-
const models = this
|
|
1128
|
+
const models = this.ext.models ??= require_utils.nullObject();
|
|
1040
1129
|
switch (typeof name) {
|
|
1041
1130
|
case "object":
|
|
1042
|
-
const
|
|
1043
|
-
if (entries.length) for (let [key, value] of entries) {
|
|
1044
|
-
if (key in models) continue;
|
|
1045
|
-
if ("~standard" in value) models[key] = value;
|
|
1046
|
-
else {
|
|
1047
|
-
value = require_schema_snapshot.snapshotSchema(value);
|
|
1048
|
-
value.$id ??= key;
|
|
1049
|
-
models[key] = value;
|
|
1050
|
-
}
|
|
1051
|
-
}
|
|
1131
|
+
for (const [key, value] of Object.entries(name)) if (!(key in models)) models[key] = toModel(key, value);
|
|
1052
1132
|
return this;
|
|
1053
1133
|
case "function": {
|
|
1054
|
-
const remapped = name(models
|
|
1134
|
+
const remapped = name(models);
|
|
1055
1135
|
const next = require_utils.nullObject();
|
|
1056
|
-
for (const key in remapped)
|
|
1057
|
-
|
|
1058
|
-
if ("~standard" in value) next[key] = value;
|
|
1059
|
-
else {
|
|
1060
|
-
value = require_schema_snapshot.snapshotSchema(value);
|
|
1061
|
-
value.$id ??= key;
|
|
1062
|
-
next[key] = value;
|
|
1063
|
-
}
|
|
1064
|
-
}
|
|
1065
|
-
this.#ext.models = next;
|
|
1136
|
+
for (const key in remapped) next[key] = toModel(key, remapped[key]);
|
|
1137
|
+
this.ext.models = next;
|
|
1066
1138
|
return this;
|
|
1067
1139
|
}
|
|
1068
1140
|
case "string":
|
|
@@ -1097,6 +1169,9 @@ var Elysia = class Elysia {
|
|
|
1097
1169
|
options(path, hookOrFn, fn) {
|
|
1098
1170
|
return this.#add("OPTIONS", path, hookOrFn, fn);
|
|
1099
1171
|
}
|
|
1172
|
+
query(path, hookOrFn, fn) {
|
|
1173
|
+
return this.#add("QUERY", path, hookOrFn, fn);
|
|
1174
|
+
}
|
|
1100
1175
|
head(path, hookOrFn, fn) {
|
|
1101
1176
|
return this.#add("HEAD", path, hookOrFn, fn);
|
|
1102
1177
|
}
|
|
@@ -1121,22 +1196,18 @@ var Elysia = class Elysia {
|
|
|
1121
1196
|
this.#add("WS", path, opts, void 0, true);
|
|
1122
1197
|
return this;
|
|
1123
1198
|
}
|
|
1124
|
-
mount(path,
|
|
1199
|
+
mount(path, handler) {
|
|
1125
1200
|
const options = {
|
|
1126
|
-
...config,
|
|
1127
1201
|
parse: "none",
|
|
1128
|
-
detail: {
|
|
1129
|
-
...config?.detail,
|
|
1130
|
-
hide: true
|
|
1131
|
-
}
|
|
1202
|
+
detail: { hide: true }
|
|
1132
1203
|
};
|
|
1133
1204
|
if (typeof path === "function" || path === "" || path === "/") {
|
|
1134
|
-
const run = typeof path === "function" ? path : typeof
|
|
1205
|
+
const run = typeof path === "function" ? path : typeof handler === "function" ? handler : null;
|
|
1135
1206
|
if (!run) throw new Error("Invalid handler");
|
|
1136
1207
|
this.all("/*", options, Elysia.#mountHandler(run, 2));
|
|
1137
1208
|
return this;
|
|
1138
1209
|
}
|
|
1139
|
-
const handle = typeof
|
|
1210
|
+
const handle = typeof handler === "function" ? handler : null;
|
|
1140
1211
|
if (!handle) throw new Error("Invalid handler");
|
|
1141
1212
|
const endsStar = path.endsWith("*") ? 1 : 0;
|
|
1142
1213
|
const wildcardSuffix = path.endsWith("/") ? "*" : "/*";
|
|
@@ -1172,75 +1243,102 @@ var Elysia = class Elysia {
|
|
|
1172
1243
|
compile() {
|
|
1173
1244
|
this["~config"] ??= require_utils.nullObject();
|
|
1174
1245
|
this["~config"].precompile = true;
|
|
1175
|
-
this.#
|
|
1176
|
-
this.#compiled = void 0;
|
|
1177
|
-
this.#jitColdRemaining = void 0;
|
|
1178
|
-
this.#jitTable = void 0;
|
|
1179
|
-
this.#jitRoute = void 0;
|
|
1180
|
-
this.#jitStatic = void 0;
|
|
1181
|
-
this.#jitAliases = void 0;
|
|
1182
|
-
this.#fetchFn = void 0;
|
|
1246
|
+
this.#invalidate();
|
|
1183
1247
|
this.fetch;
|
|
1184
1248
|
return this;
|
|
1185
1249
|
}
|
|
1186
|
-
handler(index, immediate
|
|
1187
|
-
if (this
|
|
1188
|
-
const
|
|
1189
|
-
|
|
1190
|
-
|
|
1250
|
+
handler(index, immediate, route, aliases, table) {
|
|
1251
|
+
if (this.compiled?.[index]) return this.compiled[index];
|
|
1252
|
+
const indexedTable = table ?? (this.routerBuilt ? this["~routeTable"] : void 0);
|
|
1253
|
+
const compiled = this.compiled ??= new Array(indexedTable?.length ?? this["~routes"].length);
|
|
1254
|
+
if (immediate ?? this["~config"]?.precompile) {
|
|
1255
|
+
const row = route ?? (indexedTable ? require_route_table.routeRow(indexedTable, index) : this["~routes"][index]);
|
|
1256
|
+
const exactDuplicate = ((indexedTable?.flags[index] ?? 0) & require_route_table.RouteFlag.ExactDuplicate) !== 0;
|
|
1191
1257
|
let handler;
|
|
1192
1258
|
try {
|
|
1193
|
-
handler = require_compile_handler_index.compileHandler(row, this,
|
|
1259
|
+
handler = require_compile_handler_index.compileHandler(row, this, exactDuplicate && require_compile_aot.Compiled.hasProgram(this["~programId"]));
|
|
1194
1260
|
} catch (error) {
|
|
1195
1261
|
throw new Error(`[Elysia] Failed to compile route ${row[0]} ${row[1]}: ${error?.message ?? error}`, { cause: error });
|
|
1196
1262
|
}
|
|
1197
1263
|
compiled[index] = handler;
|
|
1198
|
-
this.#
|
|
1264
|
+
if (indexedTable) this.#satisfyJit(indexedTable, index);
|
|
1199
1265
|
return handler;
|
|
1200
1266
|
}
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
if (
|
|
1205
|
-
if (route !== void 0) (this.#jitRoute ??= [])[index] = route;
|
|
1206
|
-
if (precomputedStatic !== void 0) (this.#jitStatic ??= [])[index] = precomputedStatic;
|
|
1207
|
-
if (aliases !== void 0) (this.#jitAliases ??= [])[index] = aliases;
|
|
1267
|
+
const jitRoute = route ?? (indexedTable ? void 0 : this["~routes"][index]);
|
|
1268
|
+
if (indexedTable !== void 0) this.jitTable = indexedTable;
|
|
1269
|
+
if (jitRoute !== void 0) (this.jitRoute ??= [])[index] = jitRoute;
|
|
1270
|
+
if (aliases !== void 0) (this.jitAliases ??= [])[index] = aliases;
|
|
1208
1271
|
return (context) => this.#jitDispatch(index, context);
|
|
1209
1272
|
}
|
|
1273
|
+
#staticAliases(table, index) {
|
|
1274
|
+
const flags = table.flags[index];
|
|
1275
|
+
if ((flags & (require_route_table.RouteFlag.WS | require_route_table.RouteFlag.Dynamic)) !== 0) return;
|
|
1276
|
+
const path = table.path[index];
|
|
1277
|
+
const method = table.method[index];
|
|
1278
|
+
const needsEncode = (flags & require_route_table.RouteFlag.Encode) !== 0;
|
|
1279
|
+
const registerLoose = this["~config"]?.strictPath !== true && canRegisterLoose(path, false);
|
|
1280
|
+
if (!needsEncode && !registerLoose) return;
|
|
1281
|
+
let explicit;
|
|
1282
|
+
if (registerLoose) {
|
|
1283
|
+
explicit = /* @__PURE__ */ new Set();
|
|
1284
|
+
for (let i = 0; i < table.length; i++) {
|
|
1285
|
+
if (table.method[i] !== method) continue;
|
|
1286
|
+
const declared = table.path[i];
|
|
1287
|
+
explicit.add(declared);
|
|
1288
|
+
if ((table.flags[i] & require_route_table.RouteFlag.Encode) !== 0) explicit.add(encodeURI(declared));
|
|
1289
|
+
}
|
|
1290
|
+
}
|
|
1291
|
+
return {
|
|
1292
|
+
method,
|
|
1293
|
+
paths: expandPaths(path, needsEncode, registerLoose, explicit)
|
|
1294
|
+
};
|
|
1295
|
+
}
|
|
1296
|
+
#releaseJit() {
|
|
1297
|
+
require_compile_aot.Compiled.release(this["~programId"]);
|
|
1298
|
+
this.jitColdRemaining = void 0;
|
|
1299
|
+
this.jitRoute = void 0;
|
|
1300
|
+
this.jitAliases = void 0;
|
|
1301
|
+
this.jitTable = void 0;
|
|
1302
|
+
}
|
|
1303
|
+
#satisfyJit(table, index) {
|
|
1304
|
+
if ((table.flags[index] & require_route_table.RouteFlag.ExactDuplicate) !== 0) return false;
|
|
1305
|
+
if (this.jitColdRemaining === void 0) {
|
|
1306
|
+
if (this["~generation"] === void 0 && this["~config"]?.precompile !== true && require_universal_is_production.isProduction() && !require_compile_aot.Capture.isAotBuildEnv()) table.flags[index] |= require_route_table.RouteFlag.JITSatisfied;
|
|
1307
|
+
return false;
|
|
1308
|
+
}
|
|
1309
|
+
if ((table.flags[index] & require_route_table.RouteFlag.JITCold) === 0) return false;
|
|
1310
|
+
table.flags[index] &= ~require_route_table.RouteFlag.JITCold;
|
|
1311
|
+
if (--this.jitColdRemaining > 0) return false;
|
|
1312
|
+
this.#releaseJit();
|
|
1313
|
+
return true;
|
|
1314
|
+
}
|
|
1210
1315
|
#jitDispatch(index, context) {
|
|
1211
|
-
if (this
|
|
1212
|
-
const
|
|
1316
|
+
if (this.compiled[index]) return this.compiled[index](context);
|
|
1317
|
+
const route = this.jitRoute?.[index];
|
|
1318
|
+
const table = this.jitTable ?? this["~routeTable"];
|
|
1319
|
+
const materialized = route ?? require_route_table.routeRow(table, index);
|
|
1320
|
+
const exactDuplicate = ((table?.flags[index] ?? 0) & require_route_table.RouteFlag.ExactDuplicate) !== 0;
|
|
1213
1321
|
let handler;
|
|
1214
1322
|
try {
|
|
1215
|
-
handler = require_compile_handler_index.compileHandler(materialized, this, this
|
|
1323
|
+
handler = require_compile_handler_index.compileHandler(materialized, this, exactDuplicate && require_compile_aot.Compiled.hasProgram(this["~programId"]));
|
|
1216
1324
|
} catch (error) {
|
|
1217
1325
|
const routeError = new Error(`[Elysia] Failed to compile route ${materialized[0]} ${materialized[1]}: ${error?.message ?? error}`, { cause: error });
|
|
1218
1326
|
const finalize = this["~finalizeError"];
|
|
1219
1327
|
if (finalize) return finalize(context, routeError);
|
|
1220
1328
|
throw routeError;
|
|
1221
1329
|
}
|
|
1222
|
-
this
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1330
|
+
this.compiled[index] = handler;
|
|
1331
|
+
if (!exactDuplicate) {
|
|
1332
|
+
const aliases = this.jitAliases?.[index] ?? (table ? this.#staticAliases(table, index) : void 0);
|
|
1333
|
+
if (aliases) {
|
|
1334
|
+
this.#initMap();
|
|
1335
|
+
const map = this["~map"][aliases.method] ??= require_utils.nullObject();
|
|
1336
|
+
for (let p = 0; p < aliases.paths.length; p++) map[aliases.paths[p]] = handler;
|
|
1337
|
+
} else this.#saveHandler(materialized[0], materialized[1], handler);
|
|
1228
1338
|
}
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
this
|
|
1232
|
-
const map = this["~map"][aliases.method] ??= require_utils.nullObject();
|
|
1233
|
-
for (let p = 0; p < aliases.paths.length; p++) map[aliases.paths[p]] = handler;
|
|
1234
|
-
} else this.#saveHandler(materialized[0], materialized[1], handler);
|
|
1235
|
-
if (releasedNow) {
|
|
1236
|
-
this.#jitRoute = void 0;
|
|
1237
|
-
this.#jitStatic = void 0;
|
|
1238
|
-
this.#jitAliases = void 0;
|
|
1239
|
-
this.#jitTable = void 0;
|
|
1240
|
-
} else {
|
|
1241
|
-
if (this.#jitRoute) this.#jitRoute[index] = void 0;
|
|
1242
|
-
if (this.#jitStatic) this.#jitStatic[index] = void 0;
|
|
1243
|
-
if (this.#jitAliases) this.#jitAliases[index] = void 0;
|
|
1339
|
+
if (!(table ? this.#satisfyJit(table, index) : false)) {
|
|
1340
|
+
if (this.jitRoute) this.jitRoute[index] = void 0;
|
|
1341
|
+
if (this.jitAliases) this.jitAliases[index] = void 0;
|
|
1244
1342
|
}
|
|
1245
1343
|
return handler(context);
|
|
1246
1344
|
}
|
|
@@ -1257,7 +1355,7 @@ var Elysia = class Elysia {
|
|
|
1257
1355
|
if (typeof response === "string") return true;
|
|
1258
1356
|
if (response && typeof response === "object") {
|
|
1259
1357
|
const record = response;
|
|
1260
|
-
if (!(
|
|
1358
|
+
if (!isSingleSchema(record)) {
|
|
1261
1359
|
for (const status in record) if (typeof record[status] === "string") return true;
|
|
1262
1360
|
}
|
|
1263
1361
|
}
|
|
@@ -1271,16 +1369,41 @@ var Elysia = class Elysia {
|
|
|
1271
1369
|
}
|
|
1272
1370
|
return false;
|
|
1273
1371
|
}
|
|
1274
|
-
#
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
if (
|
|
1279
|
-
if (Elysia.#
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1372
|
+
static #slotHasTypeBox(value, models, record) {
|
|
1373
|
+
if (typeof value === "string") value = models?.[value];
|
|
1374
|
+
if (!value || typeof value !== "object") return false;
|
|
1375
|
+
if ("~kind" in value || "~elyAcl" in value) return true;
|
|
1376
|
+
if (!record || "~standard" in value) return false;
|
|
1377
|
+
for (const status in value) if (Elysia.#slotHasTypeBox(value[status], models)) return true;
|
|
1378
|
+
return false;
|
|
1379
|
+
}
|
|
1380
|
+
static #hookHasTypeBox(h, models) {
|
|
1381
|
+
if (!h || typeof h !== "object") return false;
|
|
1382
|
+
for (const key in h) {
|
|
1383
|
+
if (key === "schemas") {
|
|
1384
|
+
const schemas = h[key];
|
|
1385
|
+
if (Array.isArray(schemas)) {
|
|
1386
|
+
for (let s = 0; s < schemas.length; s++) if (Elysia.#hookHasTypeBox(schemas[s], models)) return true;
|
|
1387
|
+
}
|
|
1388
|
+
continue;
|
|
1389
|
+
}
|
|
1390
|
+
if (require_utils.schemaProperties.has(key) && Elysia.#slotHasTypeBox(h[key], models, key === "response")) return true;
|
|
1391
|
+
}
|
|
1392
|
+
return false;
|
|
1393
|
+
}
|
|
1394
|
+
static #chainHasTypeBox(node, models, seen, resolve) {
|
|
1395
|
+
while (node) {
|
|
1396
|
+
if (seen.has(node)) return false;
|
|
1397
|
+
seen.add(node);
|
|
1398
|
+
if ("added" in node) {
|
|
1399
|
+
if (Elysia.#hookHasTypeBox(resolve ? resolve(node) : node.added, models)) return true;
|
|
1400
|
+
node = node.parent;
|
|
1401
|
+
} else {
|
|
1402
|
+
if (Elysia.#chainHasTypeBox(node.combine, models, seen, resolve) || Elysia.#chainHasTypeBox(node.tail, models, seen, resolve)) return true;
|
|
1403
|
+
node = node.over;
|
|
1404
|
+
}
|
|
1405
|
+
}
|
|
1406
|
+
return false;
|
|
1284
1407
|
}
|
|
1285
1408
|
#assertRouteModelRefs(route, method) {
|
|
1286
1409
|
const models = this["~ext"]?.models;
|
|
@@ -1294,7 +1417,7 @@ var Elysia = class Elysia {
|
|
|
1294
1417
|
if (!models || !(v in models)) throw new Error(`[Elysia] Unknown model reference "${v}" for ${key} on route ${method} ${path}.`);
|
|
1295
1418
|
} else if (key === "response" && v && typeof v === "object") {
|
|
1296
1419
|
const record = v;
|
|
1297
|
-
if (
|
|
1420
|
+
if (isSingleSchema(record)) continue;
|
|
1298
1421
|
for (const status in record) {
|
|
1299
1422
|
const r = record[status];
|
|
1300
1423
|
if (typeof r === "string" && (!models || !(r in models))) throw new Error(`[Elysia] Unknown model reference "${r}" for response ${status} on route ${method} ${path}.`);
|
|
@@ -1307,30 +1430,27 @@ var Elysia = class Elysia {
|
|
|
1307
1430
|
const schemas = hook?.schemas;
|
|
1308
1431
|
if (Array.isArray(schemas)) for (let s = 0; s < schemas.length; s++) checkSlots(schemas[s]);
|
|
1309
1432
|
}
|
|
1310
|
-
#routerBuilt = false;
|
|
1311
1433
|
#buildRouter(seal = false) {
|
|
1312
|
-
if (this
|
|
1434
|
+
if (this.routerBuilt) {
|
|
1313
1435
|
if (seal && this["~generation"] === void 0) this.#publishGeneration();
|
|
1314
1436
|
return;
|
|
1315
1437
|
}
|
|
1316
1438
|
const compilerSession = require_compile_aot.beginCompilerSession(this);
|
|
1317
1439
|
const previousMap = this["~map"];
|
|
1318
1440
|
const previousRouter = this["~router"];
|
|
1319
|
-
const previousCompiled = this
|
|
1320
|
-
const previousJitTable = this
|
|
1321
|
-
const previousJitRoute = this
|
|
1322
|
-
const
|
|
1323
|
-
const previousJitAliases = this.#jitAliases;
|
|
1441
|
+
const previousCompiled = this.compiled;
|
|
1442
|
+
const previousJitTable = this.jitTable;
|
|
1443
|
+
const previousJitRoute = this.jitRoute;
|
|
1444
|
+
const previousJitAliases = this.jitAliases;
|
|
1324
1445
|
const previousHasDynamicWS = this["~hasDynamicWS"];
|
|
1325
1446
|
const previousGeneration = this["~generation"];
|
|
1326
1447
|
this["~map"] = void 0;
|
|
1327
1448
|
this["~router"] = void 0;
|
|
1328
|
-
this
|
|
1329
|
-
this
|
|
1330
|
-
this
|
|
1331
|
-
this
|
|
1332
|
-
this
|
|
1333
|
-
this.#jitAliases = void 0;
|
|
1449
|
+
this.compiled = previousCompiled?.slice();
|
|
1450
|
+
this.jitColdRemaining = void 0;
|
|
1451
|
+
this.jitTable = void 0;
|
|
1452
|
+
this.jitRoute = void 0;
|
|
1453
|
+
this.jitAliases = void 0;
|
|
1334
1454
|
this["~hasDynamicWS"] = void 0;
|
|
1335
1455
|
this["~generation"] = void 0;
|
|
1336
1456
|
let buildSucceeded = false;
|
|
@@ -1346,18 +1466,17 @@ var Elysia = class Elysia {
|
|
|
1346
1466
|
Object.assign(previousRouter, nextRouter);
|
|
1347
1467
|
this["~router"] = previousRouter;
|
|
1348
1468
|
}
|
|
1349
|
-
this
|
|
1469
|
+
this.routerBuilt = true;
|
|
1350
1470
|
if (seal) this.#publishGeneration();
|
|
1351
1471
|
buildSucceeded = true;
|
|
1352
1472
|
} catch (error) {
|
|
1353
1473
|
this["~map"] = previousMap;
|
|
1354
1474
|
this["~router"] = previousRouter;
|
|
1355
|
-
this
|
|
1356
|
-
this
|
|
1357
|
-
this
|
|
1358
|
-
this
|
|
1359
|
-
this
|
|
1360
|
-
this.#jitAliases = previousJitAliases;
|
|
1475
|
+
this.compiled = previousCompiled;
|
|
1476
|
+
this.jitColdRemaining = void 0;
|
|
1477
|
+
this.jitTable = previousJitTable;
|
|
1478
|
+
this.jitRoute = previousJitRoute;
|
|
1479
|
+
this.jitAliases = previousJitAliases;
|
|
1361
1480
|
this["~hasDynamicWS"] = previousHasDynamicWS;
|
|
1362
1481
|
this["~generation"] = previousGeneration;
|
|
1363
1482
|
throw error;
|
|
@@ -1378,26 +1497,31 @@ var Elysia = class Elysia {
|
|
|
1378
1497
|
"~wsConfig": this["~wsConfig"]
|
|
1379
1498
|
};
|
|
1380
1499
|
if (require_universal_is_production.isProduction() && !require_compile_aot.Capture.isAotBuildEnv()) {
|
|
1381
|
-
if (this["~config"]?.precompile)
|
|
1500
|
+
if (this["~config"]?.precompile) this.#releaseJit();
|
|
1382
1501
|
else {
|
|
1383
1502
|
const table = this["~routeTable"];
|
|
1384
|
-
const routeCount = table
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
for (let i = 0; i < routeCount; i++)
|
|
1388
|
-
|
|
1389
|
-
|
|
1503
|
+
const routeCount = table.length;
|
|
1504
|
+
const compiled = this.compiled;
|
|
1505
|
+
let cold = 0;
|
|
1506
|
+
for (let i = 0; i < routeCount; i++) {
|
|
1507
|
+
const satisfied = (table.flags[i] & require_route_table.RouteFlag.JITSatisfied) !== 0;
|
|
1508
|
+
table.flags[i] &= ~(require_route_table.RouteFlag.JITCold | require_route_table.RouteFlag.JITSatisfied);
|
|
1509
|
+
const flags = table.flags[i];
|
|
1510
|
+
if (satisfied || (flags & (require_route_table.RouteFlag.WS | require_route_table.RouteFlag.ExactDuplicate)) !== 0 || compiled?.[i] !== void 0) continue;
|
|
1511
|
+
table.flags[i] |= require_route_table.RouteFlag.JITCold;
|
|
1512
|
+
cold++;
|
|
1513
|
+
}
|
|
1514
|
+
if (cold === 0) this.#releaseJit();
|
|
1515
|
+
else this.jitColdRemaining = cold;
|
|
1390
1516
|
}
|
|
1391
|
-
|
|
1392
|
-
|
|
1517
|
+
require_compile_handler_index.clearHandlerAnalysisCaches(this);
|
|
1518
|
+
require_utils.clearFlattenChainMemo(this);
|
|
1519
|
+
if (!this["~ext"]?.macro && !this["~scopeChildren"]) this.declaredRoutes = void 0;
|
|
1393
1520
|
}
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
this["~generation"] = void 0;
|
|
1399
|
-
this.#buildRouter(true);
|
|
1400
|
-
return this;
|
|
1521
|
+
const ext = this["~ext"];
|
|
1522
|
+
if (ext?.hoc) extCallbackIndexes.delete(ext.hoc);
|
|
1523
|
+
if (ext?.setup) extCallbackIndexes.delete(ext.setup);
|
|
1524
|
+
if (ext?.cleanup) extCallbackIndexes.delete(ext.cleanup);
|
|
1401
1525
|
}
|
|
1402
1526
|
#buildRouterUnsafe() {
|
|
1403
1527
|
const precompile = this["~config"]?.precompile;
|
|
@@ -1413,21 +1537,52 @@ var Elysia = class Elysia {
|
|
|
1413
1537
|
const length = table.length;
|
|
1414
1538
|
const appChain = this["~hookChain"];
|
|
1415
1539
|
if (this["~ext"]?.macro || this["~scopeChildren"] || appChain !== void 0 && appChain.refs) for (let i = 0; i < length; i++) this.#assertRouteModelRefs(require_route_table.routeRow(table, i), method[i]);
|
|
1416
|
-
else for (let i = 0; i < length; i++)
|
|
1417
|
-
|
|
1540
|
+
else for (let i = 0; i < length; i++) {
|
|
1541
|
+
const macroScope = table.macroScope?.get(i);
|
|
1542
|
+
const owner = table.owner[i];
|
|
1543
|
+
const candidate = macroScope ?? owner ?? this;
|
|
1544
|
+
if ((candidate === this ? this : require_compile_handler_index.localMacroRoot(candidate, this))["~ext"]?.macro || Elysia.#hookHasString(table.localHook[i]) || table.appHook[i]?.refs || table.inheritedChain[i]?.refs) this.#assertRouteModelRefs(require_route_table.routeRow(table, i), method[i]);
|
|
1545
|
+
}
|
|
1546
|
+
let hasTypeBoxSchema = false;
|
|
1547
|
+
if (length) {
|
|
1548
|
+
const models = this["~ext"]?.models;
|
|
1549
|
+
const resolve = require_compile_handler_index.chainResolver(this);
|
|
1550
|
+
const rootChain = this["~hookChain"];
|
|
1551
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1552
|
+
const { localHook, appHook, inheritedChain, owner } = table;
|
|
1553
|
+
for (let i = 0; i < table.length; i++) if (Elysia.#hookHasTypeBox(localHook[i], models) || Elysia.#chainHasTypeBox(appHook[i], models, seen, resolve) || Elysia.#chainHasTypeBox(inheritedChain[i], models, seen, resolve) || owner[i] !== this && Elysia.#chainHasTypeBox(rootChain, models, seen, resolve)) {
|
|
1554
|
+
hasTypeBoxSchema = true;
|
|
1555
|
+
break;
|
|
1556
|
+
}
|
|
1557
|
+
}
|
|
1558
|
+
if (hasTypeBoxSchema) try {
|
|
1559
|
+
require_type_bridge.warmTypebox();
|
|
1560
|
+
} catch {}
|
|
1561
|
+
let markDuplicates = false;
|
|
1562
|
+
if (length) {
|
|
1563
|
+
const programId = this["~programId"];
|
|
1564
|
+
if (!require_compile_aot.Compiled.claim(programId, this["~aotFingerprint"] = require_compile_aot.createAotFingerprint())) require_compile_aot.Compiled.assertUncontested(programId);
|
|
1565
|
+
markDuplicates = require_compile_aot.Compiled.hasProgram(programId) || precompile !== true && require_universal_is_production.isProduction() && !require_compile_aot.Capture.isAotBuildEnv();
|
|
1566
|
+
}
|
|
1418
1567
|
const isLoose = this["~config"]?.strictPath !== true;
|
|
1568
|
+
const collectExplicit = isLoose && table.hasLoose;
|
|
1419
1569
|
let explicitPaths;
|
|
1420
|
-
if (
|
|
1421
|
-
|
|
1570
|
+
if (markDuplicates || collectExplicit) {
|
|
1571
|
+
const seen = /* @__PURE__ */ new Map();
|
|
1572
|
+
if (collectExplicit) explicitPaths = seen;
|
|
1422
1573
|
for (let i = 0; i < length; i++) {
|
|
1423
1574
|
const m = method[i];
|
|
1424
1575
|
const p = path[i];
|
|
1425
|
-
let
|
|
1426
|
-
if (!
|
|
1427
|
-
|
|
1428
|
-
|
|
1576
|
+
let paths = seen.get(m);
|
|
1577
|
+
if (!paths) seen.set(m, paths = /* @__PURE__ */ new Map());
|
|
1578
|
+
if (markDuplicates && (flags[i] & require_route_table.RouteFlag.WS) === 0) {
|
|
1579
|
+
const displaced = paths.get(p);
|
|
1580
|
+
if (displaced !== void 0 && displaced >= 0) flags[displaced] |= require_route_table.RouteFlag.ExactDuplicate;
|
|
1581
|
+
paths.set(p, i);
|
|
1582
|
+
} else paths.set(p, -1);
|
|
1583
|
+
if (collectExplicit && (flags[i] & require_route_table.RouteFlag.Encode) !== 0) {
|
|
1429
1584
|
const encoded = encodeURI(p);
|
|
1430
|
-
if (encoded !== p) set
|
|
1585
|
+
if (encoded !== p && !paths.has(encoded)) paths.set(encoded, -1);
|
|
1431
1586
|
}
|
|
1432
1587
|
}
|
|
1433
1588
|
}
|
|
@@ -1440,54 +1595,40 @@ var Elysia = class Elysia {
|
|
|
1440
1595
|
const handler = ws[0];
|
|
1441
1596
|
const options = ws[1];
|
|
1442
1597
|
if (wsConfig === void 0 && wsCap.options) wsConfig = wsCap.options;
|
|
1598
|
+
const wsNeedsEncode = (routeFlags & require_route_table.RouteFlag.Encode) !== 0;
|
|
1443
1599
|
if ((routeFlags & require_route_table.RouteFlag.Dynamic) !== 0) {
|
|
1444
|
-
|
|
1600
|
+
const wsRouter = this["~router"] ??= new memoirist.default({ loosePath: isLoose });
|
|
1601
|
+
const wsPaths = expandPaths(routePath, wsNeedsEncode, false, void 0);
|
|
1602
|
+
for (let v = 0; v < wsPaths.length; v++) wsRouter.add("WS", wsPaths[v], handler);
|
|
1445
1603
|
this["~hasDynamicWS"] = true;
|
|
1446
1604
|
} else {
|
|
1447
|
-
this.#initMap();
|
|
1448
1605
|
const wsMap = this["~map"]["WS"] ??= require_utils.nullObject();
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
const loose = require_utils.getLoosePath(routePath);
|
|
1452
|
-
if (loose !== routePath && !explicitPaths?.get("WS")?.has(loose)) wsMap[loose] = handler;
|
|
1453
|
-
}
|
|
1606
|
+
const wsPaths = expandPaths(routePath, wsNeedsEncode, isLoose, isLoose ? explicitPaths?.get("WS") : void 0);
|
|
1607
|
+
for (let v = 0; v < wsPaths.length; v++) wsMap[wsPaths[v]] = handler;
|
|
1454
1608
|
}
|
|
1455
1609
|
if (options && require_utils.isNotEmpty(options)) {
|
|
1456
1610
|
wsConfig ??= require_utils.nullObject();
|
|
1457
|
-
wsCap.provider.accumulateOptions(wsConfig, options
|
|
1611
|
+
wsCap.provider.accumulateOptions(wsConfig, options);
|
|
1458
1612
|
}
|
|
1459
1613
|
continue;
|
|
1460
1614
|
}
|
|
1461
1615
|
const isDynamic = (routeFlags & require_route_table.RouteFlag.Dynamic) !== 0;
|
|
1462
1616
|
const needsEncode = (routeFlags & require_route_table.RouteFlag.Encode) !== 0;
|
|
1463
1617
|
const registerLoose = isLoose && canRegisterLoose(routePath, isDynamic);
|
|
1464
|
-
const explicitMain = registerLoose ? explicitPaths?.get(routeMethod) : void 0;
|
|
1465
1618
|
if (!isDynamic && !needsEncode && !registerLoose) {
|
|
1466
1619
|
const map = methods[routeMethod] ??= require_utils.nullObject();
|
|
1467
|
-
map[routePath] = this.handler(i, precompile, void 0, void 0,
|
|
1620
|
+
map[routePath] = this.handler(i, precompile, void 0, void 0, table);
|
|
1468
1621
|
continue;
|
|
1469
1622
|
}
|
|
1470
|
-
const
|
|
1471
|
-
if (needsEncode) {
|
|
1472
|
-
const encoded = encodeURI(routePath);
|
|
1473
|
-
if (encoded !== routePath) variants.push(encoded);
|
|
1474
|
-
}
|
|
1475
|
-
const paths = [];
|
|
1476
|
-
for (let v = 0; v < variants.length; v++) {
|
|
1477
|
-
const p = variants[v];
|
|
1478
|
-
paths.push(p);
|
|
1479
|
-
if (registerLoose) {
|
|
1480
|
-
const loose = require_utils.getLoosePath(p);
|
|
1481
|
-
if (loose !== p && !explicitMain?.has(loose)) paths.push(loose);
|
|
1482
|
-
}
|
|
1483
|
-
}
|
|
1623
|
+
const paths = expandPaths(routePath, needsEncode, registerLoose, registerLoose ? explicitPaths?.get(routeMethod) : void 0);
|
|
1484
1624
|
if (isDynamic) {
|
|
1625
|
+
if (require_utils.isHTMLBundle(table.handler[i])) continue;
|
|
1485
1626
|
const router = this["~router"] ??= new memoirist.default({ loosePath: isLoose });
|
|
1486
|
-
const handler = this.handler(i, precompile, void 0, void 0,
|
|
1627
|
+
const handler = this.handler(i, precompile, void 0, void 0, table);
|
|
1487
1628
|
for (let p = 0; p < paths.length; p++) router.add(routeMethod, paths[p], handler);
|
|
1488
1629
|
} else {
|
|
1489
1630
|
const map = methods[routeMethod] ??= require_utils.nullObject();
|
|
1490
|
-
const handler = this.handler(i, precompile, void 0,
|
|
1631
|
+
const handler = this.handler(i, precompile, void 0, {
|
|
1491
1632
|
method: routeMethod,
|
|
1492
1633
|
paths
|
|
1493
1634
|
}, table);
|
|
@@ -1496,19 +1637,28 @@ var Elysia = class Elysia {
|
|
|
1496
1637
|
}
|
|
1497
1638
|
this["~wsConfig"] = wsConfig;
|
|
1498
1639
|
}
|
|
1499
|
-
#fetchFn;
|
|
1500
1640
|
get fetch() {
|
|
1501
|
-
if (this
|
|
1502
|
-
|
|
1503
|
-
|
|
1641
|
+
if (this.fetchFn) return this.fetchFn;
|
|
1642
|
+
if (this.ready) return (request, ...rest) => {
|
|
1643
|
+
const run = () => this.fetch(request, ...rest);
|
|
1644
|
+
return this.ready ? this.modules.then(run, run) : run();
|
|
1645
|
+
};
|
|
1646
|
+
return this.#dispatch();
|
|
1647
|
+
}
|
|
1648
|
+
#dispatch() {
|
|
1649
|
+
this.#buildRouter(!this._pending);
|
|
1650
|
+
if (this.ready) return require_handler_fetch.applyHoc(this, require_handler_fetch.createFetchHandler(this));
|
|
1651
|
+
return this.fetchFn ??= require_handler_fetch.applyHoc(this, require_handler_fetch.createFetchHandler(this));
|
|
1504
1652
|
}
|
|
1505
|
-
#handle;
|
|
1506
1653
|
get handle() {
|
|
1507
|
-
return this
|
|
1654
|
+
return this._handle ??= async (requestOrUrl, options) => (this.fetchFn ?? this.#dispatch())(typeof requestOrUrl === "string" ? new Request(requestOrUrl.charCodeAt(0) === 47 ? `http://e.ly${requestOrUrl}` : requestOrUrl, options) : requestOrUrl);
|
|
1508
1655
|
}
|
|
1509
1656
|
listen(options, callback) {
|
|
1510
1657
|
const listen = (this["~config"]?.adapter ?? (require_universal_constants.isBun ? require_adapter_bun_index.BunAdapter : void 0))?.listen;
|
|
1511
|
-
if (!listen)
|
|
1658
|
+
if (!listen) {
|
|
1659
|
+
const deno = typeof Deno !== "undefined";
|
|
1660
|
+
throw new Error(`[Elysia] listen() requires an adapter on ${deno ? "Deno" : typeof process === "undefined" ? "this runtime" : "Node.js"} — https://elysiajs.com/integrations/${deno ? "deno" : "node"}`);
|
|
1661
|
+
}
|
|
1512
1662
|
if (!require_compile_aot.Capture.isAotBuildEnv()) listen(this, options, callback);
|
|
1513
1663
|
return this;
|
|
1514
1664
|
}
|
|
@@ -1529,8 +1679,8 @@ var Elysia = class Elysia {
|
|
|
1529
1679
|
*/
|
|
1530
1680
|
wrap(callback) {
|
|
1531
1681
|
this.#assertMutable("wrap");
|
|
1532
|
-
if (this
|
|
1533
|
-
const ext = this
|
|
1682
|
+
if (this.fetchFn && !this._pending) console.warn("[Elysia] .wrap() was called after the fetch handler was built");
|
|
1683
|
+
const ext = this.ext;
|
|
1534
1684
|
(ext.hoc ??= []).push(callback);
|
|
1535
1685
|
return this;
|
|
1536
1686
|
}
|
|
@@ -1548,31 +1698,49 @@ var Elysia = class Elysia {
|
|
|
1548
1698
|
* ```
|
|
1549
1699
|
*/
|
|
1550
1700
|
cleanup(handler) {
|
|
1701
|
+
if (this["~ext"]?.cleanupEpoch?.(handler)) return this;
|
|
1551
1702
|
this.#assertMutable("cleanup");
|
|
1552
|
-
|
|
1553
|
-
if (Array.isArray(handler)) arr.push(...handler);
|
|
1554
|
-
else arr.push(handler);
|
|
1703
|
+
(this.ext.cleanup ??= []).push(...[].concat(handler));
|
|
1555
1704
|
return this;
|
|
1556
1705
|
}
|
|
1557
1706
|
/**
|
|
1558
|
-
* Stop the underlying server (if any),
|
|
1559
|
-
* it has stopped. Mirrors `Server.stop()`.
|
|
1707
|
+
* Stop the underlying server (if any), then run every `cleanup` handler
|
|
1560
1708
|
*
|
|
1561
|
-
*
|
|
1562
|
-
*
|
|
1563
|
-
*
|
|
1709
|
+
* Awaiting `stop()` from inside a `setup`, `cleanup` or WebSocket lifecycle
|
|
1710
|
+
* callback is only supported while that callback is still synchronous
|
|
1711
|
+
*
|
|
1712
|
+
* @param closeActiveConnections Pass `true` to terminate active
|
|
1713
|
+
* transports. Omit (or pass `false`) to drain safely.
|
|
1564
1714
|
*/
|
|
1565
1715
|
stop(closeActiveConnections) {
|
|
1716
|
+
const stop = this["~ext"]?.stop;
|
|
1717
|
+
if (stop) return stop(closeActiveConnections);
|
|
1566
1718
|
const server = this.server;
|
|
1567
1719
|
if (!server) return;
|
|
1568
|
-
|
|
1569
|
-
|
|
1720
|
+
let result;
|
|
1721
|
+
const errors = [];
|
|
1722
|
+
try {
|
|
1723
|
+
result = server.stop?.(closeActiveConnections);
|
|
1724
|
+
} catch (error) {
|
|
1725
|
+
errors.push(error);
|
|
1726
|
+
} finally {
|
|
1727
|
+
this.server = void 0;
|
|
1728
|
+
}
|
|
1570
1729
|
const handlers = this["~ext"]?.cleanup;
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1730
|
+
if (!errors.length && !handlers?.length) return result && typeof result.then === "function" ? result : void 0;
|
|
1731
|
+
return (async () => {
|
|
1732
|
+
try {
|
|
1733
|
+
await result;
|
|
1734
|
+
} catch (error) {
|
|
1735
|
+
errors.push(error);
|
|
1736
|
+
}
|
|
1737
|
+
if (handlers) for (let i = 0; i < handlers.length; i++) try {
|
|
1738
|
+
await handlers[i](this);
|
|
1739
|
+
} catch (error) {
|
|
1740
|
+
errors.push(error);
|
|
1741
|
+
}
|
|
1742
|
+
require_utils.throwLifecycleErrors(errors);
|
|
1743
|
+
})();
|
|
1576
1744
|
}
|
|
1577
1745
|
};
|
|
1578
1746
|
|