elysia 2.0.0-beta.2 → 2.0.0-beta.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapter/bun/index.d.ts +1 -1
- package/dist/adapter/bun/index.js +320 -56
- package/dist/adapter/bun/index.mjs +321 -57
- package/dist/adapter/utils.js +51 -30
- package/dist/adapter/utils.mjs +52 -31
- package/dist/adapter/web-standard/handler.js +5 -2
- package/dist/adapter/web-standard/handler.mjs +5 -2
- package/dist/base.d.ts +18 -7
- package/dist/base.js +213 -101
- package/dist/base.mjs +215 -103
- package/dist/compile/aot-capture.js +1 -1
- package/dist/compile/aot-capture.mjs +1 -1
- package/dist/compile/aot.d.ts +5 -4
- package/dist/compile/aot.js +17 -9
- package/dist/compile/aot.mjs +18 -9
- package/dist/compile/handler/descriptor.js +1 -1
- package/dist/compile/handler/descriptor.mjs +1 -1
- package/dist/compile/handler/frozen-validator.d.ts +4 -1
- package/dist/compile/handler/frozen-validator.js +8 -3
- package/dist/compile/handler/frozen-validator.mjs +5 -3
- package/dist/compile/handler/index.d.ts +2 -2
- package/dist/compile/handler/index.js +8 -6
- package/dist/compile/handler/index.mjs +8 -6
- package/dist/compile/handler/reconstruct.d.ts +1 -1
- package/dist/compile/handler/reconstruct.js +4 -3
- package/dist/compile/handler/reconstruct.mjs +4 -3
- package/dist/compile/handler/utils.js +2 -2
- package/dist/compile/handler/utils.mjs +3 -3
- package/dist/compile/jit-probe.d.ts +2 -2
- package/dist/context.d.ts +1 -1
- package/dist/context.js +8 -5
- package/dist/context.mjs +8 -5
- package/dist/cookie/config.d.ts +1 -0
- package/dist/cookie/config.js +3 -2
- package/dist/cookie/config.mjs +3 -2
- package/dist/cookie/cookie.d.ts +1 -0
- package/dist/cookie/cookie.js +6 -5
- package/dist/cookie/cookie.mjs +6 -5
- package/dist/cookie/crypto.d.ts +8 -7
- package/dist/cookie/crypto.js +38 -31
- package/dist/cookie/crypto.mjs +38 -32
- package/dist/cookie/error.js +1 -2
- package/dist/cookie/error.mjs +1 -2
- package/dist/cookie/lib.js +5 -1
- package/dist/cookie/lib.mjs +5 -1
- 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.js +28 -14
- package/dist/cookie/utils.mjs +29 -15
- package/dist/handler/error.d.ts +23 -12
- package/dist/handler/error.js +24 -21
- package/dist/handler/error.mjs +20 -21
- package/dist/handler/fetch.js +6 -7
- package/dist/handler/fetch.mjs +7 -8
- package/dist/handler/utils.js +4 -2
- package/dist/handler/utils.mjs +5 -3
- package/dist/index.js +1 -8
- package/dist/package.js +1 -1
- package/dist/package.mjs +1 -1
- package/dist/plugin/aot/core.d.ts +33 -6
- package/dist/plugin/aot/core.js +120 -40
- package/dist/plugin/aot/core.mjs +121 -43
- package/dist/plugin/aot/esbuild.js +8 -2
- package/dist/plugin/aot/esbuild.mjs +9 -3
- package/dist/plugin/aot/hooks.d.ts +2 -1
- package/dist/plugin/aot/hooks.js +3 -3
- package/dist/plugin/aot/hooks.mjs +4 -4
- package/dist/plugin/aot/source.d.ts +4 -1
- package/dist/plugin/aot/source.js +21 -14
- package/dist/plugin/aot/source.mjs +21 -14
- package/dist/plugin/aot/worker.js +2 -2
- package/dist/plugin/aot/worker.mjs +2 -2
- 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.js +17 -22
- package/dist/schema-snapshot.mjs +17 -22
- package/dist/type/bridge-live.d.ts +1 -1
- package/dist/type/bridge-live.js +2 -2
- package/dist/type/bridge-live.mjs +2 -2
- package/dist/type/bridge.d.ts +1 -1
- package/dist/type/coerce-plan.js +3 -4
- package/dist/type/coerce-plan.mjs +1 -1
- package/dist/type/coerce.d.ts +1 -1
- package/dist/type/compat.d.ts +3 -0
- package/dist/type/compat.js +32 -14
- package/dist/type/compat.mjs +27 -8
- package/dist/type/constants.d.ts +1 -1
- package/dist/type/elysia/array-buffer.js +2 -3
- package/dist/type/elysia/array-buffer.mjs +1 -1
- package/dist/type/elysia/array-string.js +7 -4
- package/dist/type/elysia/array-string.mjs +9 -5
- package/dist/type/elysia/boolean-string.js +2 -3
- package/dist/type/elysia/boolean-string.mjs +1 -1
- package/dist/type/elysia/boolean.js +4 -3
- package/dist/type/elysia/boolean.mjs +4 -2
- package/dist/type/elysia/cookie.js +2 -1
- package/dist/type/elysia/cookie.mjs +2 -1
- package/dist/type/elysia/date.js +7 -7
- package/dist/type/elysia/date.mjs +3 -2
- package/dist/type/elysia/file-type.d.ts +9 -2
- package/dist/type/elysia/file-type.js +16 -1
- package/dist/type/elysia/file-type.mjs +16 -2
- package/dist/type/elysia/file.js +8 -4
- package/dist/type/elysia/file.mjs +8 -3
- package/dist/type/elysia/files.js +6 -4
- package/dist/type/elysia/files.mjs +5 -2
- package/dist/type/elysia/form.js +2 -3
- package/dist/type/elysia/form.mjs +3 -3
- package/dist/type/elysia/integer-string.js +4 -5
- package/dist/type/elysia/integer-string.mjs +3 -3
- package/dist/type/elysia/integer.js +4 -3
- package/dist/type/elysia/integer.mjs +4 -2
- 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.js +4 -3
- package/dist/type/elysia/number.mjs +4 -2
- package/dist/type/elysia/numeric-enum.js +2 -3
- package/dist/type/elysia/numeric-enum.mjs +1 -1
- package/dist/type/elysia/numeric.js +5 -5
- package/dist/type/elysia/numeric.mjs +3 -2
- package/dist/type/elysia/object-string.js +7 -4
- package/dist/type/elysia/object-string.mjs +9 -5
- package/dist/type/elysia/string.js +4 -3
- package/dist/type/elysia/string.mjs +4 -2
- package/dist/type/elysia/uint8-array.js +2 -3
- package/dist/type/elysia/uint8-array.mjs +1 -1
- package/dist/type/elysia/union-enum.js +2 -3
- package/dist/type/elysia/union-enum.mjs +1 -1
- package/dist/type/elysia/utils.js +2 -3
- package/dist/type/elysia/utils.mjs +1 -1
- package/dist/type/exports.js +10 -1
- package/dist/type/exports.mjs +7 -0
- package/dist/type/index.d.ts +9 -1
- package/dist/type/index.js +41 -13
- package/dist/type/index.mjs +44 -9
- package/dist/type/typebox-type-live.d.ts +9 -0
- package/dist/type/typebox-type-live.js +31 -0
- package/dist/type/typebox-type-live.mjs +16 -0
- package/dist/type/typebox-type.d.ts +24 -0
- package/dist/type/typebox-type.js +130 -0
- package/dist/type/typebox-type.mjs +66 -0
- package/dist/type/typebox-value-live.d.ts +9 -0
- package/dist/type/typebox-value-live.js +27 -0
- package/dist/type/typebox-value-live.mjs +11 -0
- package/dist/type/typebox-value.d.ts +30 -0
- package/dist/type/typebox-value.js +147 -0
- package/dist/type/typebox-value.mjs +62 -0
- package/dist/type/validator/custom-error.js +4 -5
- package/dist/type/validator/custom-error.mjs +3 -3
- package/dist/type/validator/default-precompute.js +4 -5
- package/dist/type/validator/default-precompute.mjs +1 -1
- package/dist/type/validator/index.d.ts +1 -1
- package/dist/type/validator/index.js +51 -42
- package/dist/type/validator/index.mjs +33 -23
- package/dist/type/validator/validator-cache.d.ts +1 -1
- package/dist/type/validator/validator-cache.js +27 -14
- package/dist/type/validator/validator-cache.mjs +27 -13
- package/dist/universal/constants.d.ts +2 -1
- package/dist/universal/constants.js +3 -1
- package/dist/universal/constants.mjs +2 -1
- package/dist/utils.d.ts +19 -1
- package/dist/utils.js +25 -3
- package/dist/utils.mjs +19 -3
- package/dist/validator/index.js +2 -1
- package/dist/validator/index.mjs +2 -1
- package/dist/ws/context.d.ts +8 -1
- package/dist/ws/context.js +65 -29
- package/dist/ws/context.mjs +64 -29
- package/dist/ws/route.js +176 -28
- package/dist/ws/route.mjs +179 -31
- package/package.json +5 -3
package/dist/base.mjs
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { isBun } from "./universal/constants.mjs";
|
|
2
|
-
import { clonePlainDecorators, clonePlainDeep, coalesceSchemas, createErrorEventHandler, eventProperties, fnOrigin, fnv1a, getLoosePath, guardNonPlainLeaves, hookToGuard, invalidateMacroEpoch, isEmpty, isNotEmpty, isRecordNumber, joinPath, macroOrigin, mapDeriveEntry, mergeDeep, mergeResponse, nullObject, pushField, schemaProperties, serializeMacroSeed } from "./utils.mjs";
|
|
2
|
+
import { clonePlainDecorators, clonePlainDeep, coalesceSchemas, createErrorEventHandler, eventProperties, fnOrigin, fnv1a, getLoosePath, guardNonPlainLeaves, hookToGuard, invalidateMacroEpoch, isEmpty, isNotEmpty, isRecordNumber, joinPath, macroOrigin, mapDeriveEntry, mergeDeep, mergeResponse, nullObject, pushField, schemaProperties, serializeMacroSeed, throwLifecycleErrors } from "./utils.mjs";
|
|
3
3
|
import { Ref } from "./type/bridge.mjs";
|
|
4
4
|
import { isProduction } from "./universal/is-production.mjs";
|
|
5
|
-
import { Capture, Compiled, beginCompilerSession, createAotFingerprint,
|
|
5
|
+
import { Capture, Compiled, beginCompilerSession, createAotFingerprint, endCompilerSession } from "./compile/aot.mjs";
|
|
6
6
|
import { traceCapabilityRequired, wsCapabilityRequired } from "./generation.mjs";
|
|
7
7
|
import { compileHandler, composeRouteHook, localMacroRoot, resolveLocalHook } from "./compile/handler/index.mjs";
|
|
8
8
|
import { RouteFlag, buildRouteTable, routeRow } from "./route-table.mjs";
|
|
9
9
|
import { BunAdapter } from "./adapter/bun/index.mjs";
|
|
10
|
+
import { clearContextCache } from "./context.mjs";
|
|
10
11
|
import { applyHoc, createFetchHandler } from "./handler/fetch.mjs";
|
|
11
12
|
import { clearAuthoringAnalysisCaches } from "./compile/analysis-cache.mjs";
|
|
12
13
|
import { snapshotHookSchemas, snapshotSchema } from "./schema-snapshot.mjs";
|
|
@@ -15,7 +16,47 @@ import Memoirist from "memoirist";
|
|
|
15
16
|
//#region src/base.ts
|
|
16
17
|
const useNodesBuffer = [];
|
|
17
18
|
const emptyHistory = Object.freeze([]);
|
|
19
|
+
const extCallbackIndexes = /* @__PURE__ */ new WeakMap();
|
|
20
|
+
const mergeExtCallbacks = (target, incoming) => {
|
|
21
|
+
let index = extCallbackIndexes.get(target);
|
|
22
|
+
if (!index) {
|
|
23
|
+
index = {
|
|
24
|
+
indexedLength: target.length,
|
|
25
|
+
seen: new Set(target)
|
|
26
|
+
};
|
|
27
|
+
extCallbackIndexes.set(target, index);
|
|
28
|
+
} else for (let i = index.indexedLength; i < target.length; i++) index.seen.add(target[i]);
|
|
29
|
+
for (const fn of incoming) {
|
|
30
|
+
if (index.seen.has(fn)) continue;
|
|
31
|
+
target.push(fn);
|
|
32
|
+
index.seen.add(fn);
|
|
33
|
+
}
|
|
34
|
+
index.indexedLength = target.length;
|
|
35
|
+
};
|
|
18
36
|
const canRegisterLoose = (path, isDynamic) => !isDynamic && (path.length === 0 || path.charCodeAt(path.length - 1) === 47);
|
|
37
|
+
/**
|
|
38
|
+
* Every key a single route must answer to, in registration order.
|
|
39
|
+
*
|
|
40
|
+
* `registerLoose` is the caller's call, not this helper's: HTTP gates it on
|
|
41
|
+
* `canRegisterLoose` because its lookup retries the trailing slash, while WS
|
|
42
|
+
* has no such retry and must own both directions outright
|
|
43
|
+
*/
|
|
44
|
+
const expandPaths = (path, needsEncode, registerLoose, explicit) => {
|
|
45
|
+
const variants = [path];
|
|
46
|
+
if (needsEncode) {
|
|
47
|
+
const encoded = encodeURI(path);
|
|
48
|
+
if (encoded !== path) variants.push(encoded);
|
|
49
|
+
}
|
|
50
|
+
if (!registerLoose) return variants;
|
|
51
|
+
const paths = [];
|
|
52
|
+
for (let v = 0; v < variants.length; v++) {
|
|
53
|
+
const p = variants[v];
|
|
54
|
+
paths.push(p);
|
|
55
|
+
const loose = getLoosePath(p);
|
|
56
|
+
if (loose !== p && !explicit?.has(loose)) paths.push(loose);
|
|
57
|
+
}
|
|
58
|
+
return paths;
|
|
59
|
+
};
|
|
19
60
|
var Elysia = class Elysia {
|
|
20
61
|
#hasPlugin;
|
|
21
62
|
#hasGlobal;
|
|
@@ -77,11 +118,14 @@ var Elysia = class Elysia {
|
|
|
77
118
|
#jitRoute;
|
|
78
119
|
#jitStatic;
|
|
79
120
|
#jitAliases;
|
|
121
|
+
get ["~programId"]() {
|
|
122
|
+
return this;
|
|
123
|
+
}
|
|
80
124
|
constructor(config) {
|
|
81
125
|
/**
|
|
82
126
|
* ! Don't tune
|
|
83
127
|
*
|
|
84
|
-
* Interesting JSC internal: These `= undefined`
|
|
128
|
+
* Interesting JSC internal: These `= undefined` shouldn't be removed
|
|
85
129
|
*
|
|
86
130
|
* Inline slots live inside the object cell, so JSC must pick their
|
|
87
131
|
* count at allocation before any initializer runs
|
|
@@ -99,7 +143,8 @@ var Elysia = class Elysia {
|
|
|
99
143
|
* Don't omitted field either for monomorphic access
|
|
100
144
|
*
|
|
101
145
|
* @see test/memory/instance-footprint.test.ts
|
|
102
|
-
* Est.
|
|
146
|
+
* Est. overflow 37 -> 21 = butterfly 64 -> 32 slots = 738B -> 450B;
|
|
147
|
+
* reusing the app as its program identity brings the current cell to ~386B.
|
|
103
148
|
**/
|
|
104
149
|
this["~config"] = config;
|
|
105
150
|
this["~ext"] = void 0;
|
|
@@ -119,7 +164,6 @@ var Elysia = class Elysia {
|
|
|
119
164
|
this["~introspect"] = void 0;
|
|
120
165
|
this["~scopeChild"] = void 0;
|
|
121
166
|
this["~scopeChildren"] = void 0;
|
|
122
|
-
this["~programId"] = createProgramId();
|
|
123
167
|
if (config) {
|
|
124
168
|
const { prefix, name, seed, adapter } = config;
|
|
125
169
|
this["~Prefix"] = prefix ? prefix.charCodeAt(0) === 47 ? prefix : `/${prefix}` : void 0;
|
|
@@ -726,27 +770,12 @@ var Elysia = class Elysia {
|
|
|
726
770
|
}
|
|
727
771
|
if (error) if (ext.error) for (const [code, handler] of error) ext.error.set(code, handler);
|
|
728
772
|
else ext.error = new Map(error);
|
|
729
|
-
if (hoc) if (ext.hoc)
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
} else ext.hoc = hoc.slice();
|
|
736
|
-
if (setup) if (ext.setup) {
|
|
737
|
-
const seen = new Set(ext.setup);
|
|
738
|
-
for (const fn of setup) if (!seen.has(fn)) {
|
|
739
|
-
seen.add(fn);
|
|
740
|
-
ext.setup.push(fn);
|
|
741
|
-
}
|
|
742
|
-
} else ext.setup = setup.slice();
|
|
743
|
-
if (cleanup) if (ext.cleanup) {
|
|
744
|
-
const seen = new Set(ext.cleanup);
|
|
745
|
-
for (const fn of cleanup) if (!seen.has(fn)) {
|
|
746
|
-
seen.add(fn);
|
|
747
|
-
ext.cleanup.push(fn);
|
|
748
|
-
}
|
|
749
|
-
} else ext.cleanup = cleanup.slice();
|
|
773
|
+
if (hoc) if (ext.hoc) mergeExtCallbacks(ext.hoc, hoc);
|
|
774
|
+
else ext.hoc = hoc.slice();
|
|
775
|
+
if (setup) if (ext.setup) mergeExtCallbacks(ext.setup, setup);
|
|
776
|
+
else ext.setup = setup.slice();
|
|
777
|
+
if (cleanup) if (ext.cleanup) mergeExtCallbacks(ext.cleanup, cleanup);
|
|
778
|
+
else ext.cleanup = cleanup.slice();
|
|
750
779
|
if (capability) {
|
|
751
780
|
const target = ext.capability ??= nullObject();
|
|
752
781
|
if (capability.trace) {
|
|
@@ -925,11 +954,11 @@ var Elysia = class Elysia {
|
|
|
925
954
|
get modules() {
|
|
926
955
|
const ready = this.#ready;
|
|
927
956
|
if (!ready) {
|
|
928
|
-
if (this.#error !== void 0) return Promise.reject(this.#error);
|
|
957
|
+
if (this.#error !== void 0) return Promise.reject(this.#error.error);
|
|
929
958
|
return Promise.resolve();
|
|
930
959
|
}
|
|
931
960
|
return ready.then(() => {
|
|
932
|
-
if (this.#error !== void 0) throw this.#error;
|
|
961
|
+
if (this.#error !== void 0) throw this.#error.error;
|
|
933
962
|
if (this.#ready && this.#ready !== ready) return this.modules;
|
|
934
963
|
});
|
|
935
964
|
}
|
|
@@ -944,13 +973,13 @@ var Elysia = class Elysia {
|
|
|
944
973
|
if (plugin) try {
|
|
945
974
|
this.use(plugin);
|
|
946
975
|
} catch (err) {
|
|
947
|
-
this.#error ??= err;
|
|
976
|
+
this.#error ??= { error: err };
|
|
948
977
|
console.error(err);
|
|
949
978
|
}
|
|
950
979
|
}).finally(() => {
|
|
951
980
|
this.#pending--;
|
|
952
981
|
}).then(() => {}, (err) => {
|
|
953
|
-
this.#error ??= err;
|
|
982
|
+
this.#error ??= { error: err };
|
|
954
983
|
console.error(err);
|
|
955
984
|
}).finally(() => this.#tryDrain(next));
|
|
956
985
|
this.#ready = next;
|
|
@@ -959,10 +988,20 @@ var Elysia = class Elysia {
|
|
|
959
988
|
#tryDrain(sentinel) {
|
|
960
989
|
if (this.#pending > 0) return;
|
|
961
990
|
if (this.#ready !== sentinel) return;
|
|
991
|
+
const previousCompiled = this.#compiled;
|
|
992
|
+
const previousJitColdRemaining = this.#jitColdRemaining;
|
|
962
993
|
this.#ready = void 0;
|
|
994
|
+
this.#compiled = void 0;
|
|
963
995
|
this.#fetchFn = void 0;
|
|
964
996
|
this.#routerBuilt = false;
|
|
965
|
-
this
|
|
997
|
+
clearContextCache(this);
|
|
998
|
+
try {
|
|
999
|
+
this.#buildRouter(false);
|
|
1000
|
+
} catch (error) {
|
|
1001
|
+
this.#compiled = previousCompiled;
|
|
1002
|
+
this.#jitColdRemaining = previousJitColdRemaining;
|
|
1003
|
+
this.#error ??= { error };
|
|
1004
|
+
}
|
|
966
1005
|
}
|
|
967
1006
|
#add(method, path, hookOrFn, fn, hasHook = fn !== void 0) {
|
|
968
1007
|
if (this["~Prefix"]) path = joinPath(this["~Prefix"], path);
|
|
@@ -1180,22 +1219,24 @@ var Elysia = class Elysia {
|
|
|
1180
1219
|
this.fetch;
|
|
1181
1220
|
return this;
|
|
1182
1221
|
}
|
|
1183
|
-
handler(index, immediate
|
|
1222
|
+
handler(index, immediate, route, precomputedStatic, aliases, table) {
|
|
1184
1223
|
if (this.#compiled?.[index]) return this.#compiled[index];
|
|
1185
|
-
const
|
|
1186
|
-
|
|
1187
|
-
|
|
1224
|
+
const indexedTable = table ?? (this.#routerBuilt ? this["~routeTable"] : void 0);
|
|
1225
|
+
const compiled = this.#compiled ??= new Array(indexedTable?.length ?? this["~routes"].length);
|
|
1226
|
+
if (immediate ?? this["~config"]?.precompile) {
|
|
1227
|
+
const row = route ?? (indexedTable ? routeRow(indexedTable, index) : this["~routes"][index]);
|
|
1228
|
+
const exactDuplicate = ((indexedTable?.flags[index] ?? 0) & RouteFlag.ExactDuplicate) !== 0;
|
|
1188
1229
|
let handler;
|
|
1189
1230
|
try {
|
|
1190
|
-
handler = compileHandler(row, this, precomputedStatic);
|
|
1231
|
+
handler = compileHandler(row, this, precomputedStatic, exactDuplicate && Compiled.hasProgram(this["~programId"]));
|
|
1191
1232
|
} catch (error) {
|
|
1192
1233
|
throw new Error(`[Elysia] Failed to compile route ${row[0]} ${row[1]}: ${error?.message ?? error}`, { cause: error });
|
|
1193
1234
|
}
|
|
1194
1235
|
compiled[index] = handler;
|
|
1195
|
-
this.#
|
|
1236
|
+
if (indexedTable) this.#satisfyJit(indexedTable, index);
|
|
1196
1237
|
return handler;
|
|
1197
1238
|
}
|
|
1198
|
-
return this.#jitHandler(index, route ?? (
|
|
1239
|
+
return this.#jitHandler(index, route ?? (indexedTable ? void 0 : this["~routes"][index]), precomputedStatic, aliases, indexedTable);
|
|
1199
1240
|
}
|
|
1200
1241
|
#jitHandler(index, route, precomputedStatic, aliases, table) {
|
|
1201
1242
|
if (table !== void 0) this.#jitTable = table;
|
|
@@ -1204,12 +1245,58 @@ var Elysia = class Elysia {
|
|
|
1204
1245
|
if (aliases !== void 0) (this.#jitAliases ??= [])[index] = aliases;
|
|
1205
1246
|
return (context) => this.#jitDispatch(index, context);
|
|
1206
1247
|
}
|
|
1248
|
+
#staticAliases(table, index) {
|
|
1249
|
+
const flags = table.flags[index];
|
|
1250
|
+
if ((flags & (RouteFlag.WS | RouteFlag.Dynamic)) !== 0) return;
|
|
1251
|
+
const path = table.path[index];
|
|
1252
|
+
const method = table.method[index];
|
|
1253
|
+
const needsEncode = (flags & RouteFlag.Encode) !== 0;
|
|
1254
|
+
const registerLoose = this["~config"]?.strictPath !== true && canRegisterLoose(path, false);
|
|
1255
|
+
if (!needsEncode && !registerLoose) return;
|
|
1256
|
+
let explicit;
|
|
1257
|
+
if (registerLoose) {
|
|
1258
|
+
explicit = /* @__PURE__ */ new Set();
|
|
1259
|
+
for (let i = 0; i < table.length; i++) {
|
|
1260
|
+
if (table.method[i] !== method) continue;
|
|
1261
|
+
const declared = table.path[i];
|
|
1262
|
+
explicit.add(declared);
|
|
1263
|
+
if ((table.flags[i] & RouteFlag.Encode) !== 0) explicit.add(encodeURI(declared));
|
|
1264
|
+
}
|
|
1265
|
+
}
|
|
1266
|
+
return {
|
|
1267
|
+
method,
|
|
1268
|
+
paths: expandPaths(path, needsEncode, registerLoose, explicit)
|
|
1269
|
+
};
|
|
1270
|
+
}
|
|
1271
|
+
#releaseJit() {
|
|
1272
|
+
Compiled.release(this["~programId"]);
|
|
1273
|
+
this.#jitColdRemaining = void 0;
|
|
1274
|
+
this.#jitRoute = void 0;
|
|
1275
|
+
this.#jitStatic = void 0;
|
|
1276
|
+
this.#jitAliases = void 0;
|
|
1277
|
+
this.#jitTable = void 0;
|
|
1278
|
+
}
|
|
1279
|
+
#satisfyJit(table, index) {
|
|
1280
|
+
if ((table.flags[index] & RouteFlag.ExactDuplicate) !== 0) return false;
|
|
1281
|
+
if (this.#jitColdRemaining === void 0) {
|
|
1282
|
+
if (this["~generation"] === void 0 && this["~config"]?.precompile !== true && isProduction() && !Capture.isAotBuildEnv()) table.flags[index] |= RouteFlag.JITSatisfied;
|
|
1283
|
+
return false;
|
|
1284
|
+
}
|
|
1285
|
+
if ((table.flags[index] & RouteFlag.JITCold) === 0) return false;
|
|
1286
|
+
table.flags[index] &= ~RouteFlag.JITCold;
|
|
1287
|
+
if (--this.#jitColdRemaining > 0) return false;
|
|
1288
|
+
this.#releaseJit();
|
|
1289
|
+
return true;
|
|
1290
|
+
}
|
|
1207
1291
|
#jitDispatch(index, context) {
|
|
1208
1292
|
if (this.#compiled[index]) return this.#compiled[index](context);
|
|
1209
|
-
const
|
|
1293
|
+
const route = this.#jitRoute?.[index];
|
|
1294
|
+
const table = this.#jitTable ?? this["~routeTable"];
|
|
1295
|
+
const materialized = route ?? routeRow(table, index);
|
|
1296
|
+
const exactDuplicate = ((table?.flags[index] ?? 0) & RouteFlag.ExactDuplicate) !== 0;
|
|
1210
1297
|
let handler;
|
|
1211
1298
|
try {
|
|
1212
|
-
handler = compileHandler(materialized, this, this.#jitStatic?.[index]);
|
|
1299
|
+
handler = compileHandler(materialized, this, this.#jitStatic?.[index], exactDuplicate && Compiled.hasProgram(this["~programId"]));
|
|
1213
1300
|
} catch (error) {
|
|
1214
1301
|
const routeError = new Error(`[Elysia] Failed to compile route ${materialized[0]} ${materialized[1]}: ${error?.message ?? error}`, { cause: error });
|
|
1215
1302
|
const finalize = this["~finalizeError"];
|
|
@@ -1217,24 +1304,15 @@ var Elysia = class Elysia {
|
|
|
1217
1304
|
throw routeError;
|
|
1218
1305
|
}
|
|
1219
1306
|
this.#compiled[index] = handler;
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1307
|
+
if (!exactDuplicate) {
|
|
1308
|
+
const aliases = this.#jitAliases?.[index] ?? (table ? this.#staticAliases(table, index) : void 0);
|
|
1309
|
+
if (aliases) {
|
|
1310
|
+
this.#initMap();
|
|
1311
|
+
const map = this["~map"][aliases.method] ??= nullObject();
|
|
1312
|
+
for (let p = 0; p < aliases.paths.length; p++) map[aliases.paths[p]] = handler;
|
|
1313
|
+
} else this.#saveHandler(materialized[0], materialized[1], handler);
|
|
1225
1314
|
}
|
|
1226
|
-
|
|
1227
|
-
if (aliases) {
|
|
1228
|
-
this.#initMap();
|
|
1229
|
-
const map = this["~map"][aliases.method] ??= nullObject();
|
|
1230
|
-
for (let p = 0; p < aliases.paths.length; p++) map[aliases.paths[p]] = handler;
|
|
1231
|
-
} else this.#saveHandler(materialized[0], materialized[1], handler);
|
|
1232
|
-
if (releasedNow) {
|
|
1233
|
-
this.#jitRoute = void 0;
|
|
1234
|
-
this.#jitStatic = void 0;
|
|
1235
|
-
this.#jitAliases = void 0;
|
|
1236
|
-
this.#jitTable = void 0;
|
|
1237
|
-
} else {
|
|
1315
|
+
if (!(table ? this.#satisfyJit(table, index) : false)) {
|
|
1238
1316
|
if (this.#jitRoute) this.#jitRoute[index] = void 0;
|
|
1239
1317
|
if (this.#jitStatic) this.#jitStatic[index] = void 0;
|
|
1240
1318
|
if (this.#jitAliases) this.#jitAliases[index] = void 0;
|
|
@@ -1375,19 +1453,30 @@ var Elysia = class Elysia {
|
|
|
1375
1453
|
"~wsConfig": this["~wsConfig"]
|
|
1376
1454
|
};
|
|
1377
1455
|
if (isProduction() && !Capture.isAotBuildEnv()) {
|
|
1378
|
-
if (this["~config"]?.precompile)
|
|
1456
|
+
if (this["~config"]?.precompile) this.#releaseJit();
|
|
1379
1457
|
else {
|
|
1380
1458
|
const table = this["~routeTable"];
|
|
1381
|
-
const routeCount = table
|
|
1382
|
-
let cold = routeCount;
|
|
1459
|
+
const routeCount = table.length;
|
|
1383
1460
|
const compiled = this.#compiled;
|
|
1384
|
-
|
|
1385
|
-
|
|
1461
|
+
let cold = 0;
|
|
1462
|
+
for (let i = 0; i < routeCount; i++) {
|
|
1463
|
+
const satisfied = (table.flags[i] & RouteFlag.JITSatisfied) !== 0;
|
|
1464
|
+
table.flags[i] &= ~(RouteFlag.JITCold | RouteFlag.JITSatisfied);
|
|
1465
|
+
const flags = table.flags[i];
|
|
1466
|
+
if (satisfied || (flags & (RouteFlag.WS | RouteFlag.ExactDuplicate)) !== 0 || compiled?.[i] !== void 0) continue;
|
|
1467
|
+
table.flags[i] |= RouteFlag.JITCold;
|
|
1468
|
+
cold++;
|
|
1469
|
+
}
|
|
1470
|
+
if (cold === 0) this.#releaseJit();
|
|
1386
1471
|
else this.#jitColdRemaining = cold;
|
|
1387
1472
|
}
|
|
1388
1473
|
clearAuthoringAnalysisCaches(this);
|
|
1389
1474
|
if (!this["~ext"]?.macro && !this["~scopeChildren"]) this.#declaredRoutes = void 0;
|
|
1390
1475
|
}
|
|
1476
|
+
const ext = this["~ext"];
|
|
1477
|
+
if (ext?.hoc) extCallbackIndexes.delete(ext.hoc);
|
|
1478
|
+
if (ext?.setup) extCallbackIndexes.delete(ext.setup);
|
|
1479
|
+
if (ext?.cleanup) extCallbackIndexes.delete(ext.cleanup);
|
|
1391
1480
|
}
|
|
1392
1481
|
["~newGeneration"]() {
|
|
1393
1482
|
this.#fetchFn = void 0;
|
|
@@ -1411,20 +1500,31 @@ var Elysia = class Elysia {
|
|
|
1411
1500
|
const appChain = this["~hookChain"];
|
|
1412
1501
|
if (this["~ext"]?.macro || this["~scopeChildren"] || appChain !== void 0 && appChain.refs) for (let i = 0; i < length; i++) this.#assertRouteModelRefs(routeRow(table, i), method[i]);
|
|
1413
1502
|
else for (let i = 0; i < length; i++) if (this.#routeMayHaveModelRef(table, i)) this.#assertRouteModelRefs(routeRow(table, i), method[i]);
|
|
1414
|
-
|
|
1503
|
+
let markDuplicates = false;
|
|
1504
|
+
if (length) {
|
|
1505
|
+
const programId = this["~programId"];
|
|
1506
|
+
if (!Compiled.claim(programId, this["~aotFingerprint"] = createAotFingerprint())) Compiled.assertUncontested(programId);
|
|
1507
|
+
markDuplicates = Compiled.hasProgram(programId) || precompile !== true && isProduction() && !Capture.isAotBuildEnv();
|
|
1508
|
+
}
|
|
1415
1509
|
const isLoose = this["~config"]?.strictPath !== true;
|
|
1510
|
+
const collectExplicit = isLoose && table.hasLoose;
|
|
1416
1511
|
let explicitPaths;
|
|
1417
|
-
if (
|
|
1418
|
-
|
|
1512
|
+
if (markDuplicates || collectExplicit) {
|
|
1513
|
+
const seen = /* @__PURE__ */ new Map();
|
|
1514
|
+
if (collectExplicit) explicitPaths = seen;
|
|
1419
1515
|
for (let i = 0; i < length; i++) {
|
|
1420
1516
|
const m = method[i];
|
|
1421
1517
|
const p = path[i];
|
|
1422
|
-
let
|
|
1423
|
-
if (!
|
|
1424
|
-
|
|
1425
|
-
|
|
1518
|
+
let paths = seen.get(m);
|
|
1519
|
+
if (!paths) seen.set(m, paths = /* @__PURE__ */ new Map());
|
|
1520
|
+
if (markDuplicates && (flags[i] & RouteFlag.WS) === 0) {
|
|
1521
|
+
const displaced = paths.get(p);
|
|
1522
|
+
if (displaced !== void 0 && displaced >= 0) flags[displaced] |= RouteFlag.ExactDuplicate;
|
|
1523
|
+
paths.set(p, i);
|
|
1524
|
+
} else paths.set(p, -1);
|
|
1525
|
+
if (collectExplicit && (flags[i] & RouteFlag.Encode) !== 0) {
|
|
1426
1526
|
const encoded = encodeURI(p);
|
|
1427
|
-
if (encoded !== p) set
|
|
1527
|
+
if (encoded !== p && !paths.has(encoded)) paths.set(encoded, -1);
|
|
1428
1528
|
}
|
|
1429
1529
|
}
|
|
1430
1530
|
}
|
|
@@ -1437,17 +1537,17 @@ var Elysia = class Elysia {
|
|
|
1437
1537
|
const handler = ws[0];
|
|
1438
1538
|
const options = ws[1];
|
|
1439
1539
|
if (wsConfig === void 0 && wsCap.options) wsConfig = wsCap.options;
|
|
1540
|
+
const wsNeedsEncode = (routeFlags & RouteFlag.Encode) !== 0;
|
|
1440
1541
|
if ((routeFlags & RouteFlag.Dynamic) !== 0) {
|
|
1441
|
-
|
|
1542
|
+
const wsRouter = this["~router"] ??= new Memoirist({ loosePath: isLoose });
|
|
1543
|
+
const wsPaths = expandPaths(routePath, wsNeedsEncode, false, void 0);
|
|
1544
|
+
for (let v = 0; v < wsPaths.length; v++) wsRouter.add("WS", wsPaths[v], handler);
|
|
1442
1545
|
this["~hasDynamicWS"] = true;
|
|
1443
1546
|
} else {
|
|
1444
1547
|
this.#initMap();
|
|
1445
1548
|
const wsMap = this["~map"]["WS"] ??= nullObject();
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
const loose = getLoosePath(routePath);
|
|
1449
|
-
if (loose !== routePath && !explicitPaths?.get("WS")?.has(loose)) wsMap[loose] = handler;
|
|
1450
|
-
}
|
|
1549
|
+
const wsPaths = expandPaths(routePath, wsNeedsEncode, isLoose, isLoose ? explicitPaths?.get("WS") : void 0);
|
|
1550
|
+
for (let v = 0; v < wsPaths.length; v++) wsMap[wsPaths[v]] = handler;
|
|
1451
1551
|
}
|
|
1452
1552
|
if (options && isNotEmpty(options)) {
|
|
1453
1553
|
wsConfig ??= nullObject();
|
|
@@ -1458,26 +1558,12 @@ var Elysia = class Elysia {
|
|
|
1458
1558
|
const isDynamic = (routeFlags & RouteFlag.Dynamic) !== 0;
|
|
1459
1559
|
const needsEncode = (routeFlags & RouteFlag.Encode) !== 0;
|
|
1460
1560
|
const registerLoose = isLoose && canRegisterLoose(routePath, isDynamic);
|
|
1461
|
-
const explicitMain = registerLoose ? explicitPaths?.get(routeMethod) : void 0;
|
|
1462
1561
|
if (!isDynamic && !needsEncode && !registerLoose) {
|
|
1463
1562
|
const map = methods[routeMethod] ??= nullObject();
|
|
1464
1563
|
map[routePath] = this.handler(i, precompile, void 0, void 0, void 0, table);
|
|
1465
1564
|
continue;
|
|
1466
1565
|
}
|
|
1467
|
-
const
|
|
1468
|
-
if (needsEncode) {
|
|
1469
|
-
const encoded = encodeURI(routePath);
|
|
1470
|
-
if (encoded !== routePath) variants.push(encoded);
|
|
1471
|
-
}
|
|
1472
|
-
const paths = [];
|
|
1473
|
-
for (let v = 0; v < variants.length; v++) {
|
|
1474
|
-
const p = variants[v];
|
|
1475
|
-
paths.push(p);
|
|
1476
|
-
if (registerLoose) {
|
|
1477
|
-
const loose = getLoosePath(p);
|
|
1478
|
-
if (loose !== p && !explicitMain?.has(loose)) paths.push(loose);
|
|
1479
|
-
}
|
|
1480
|
-
}
|
|
1566
|
+
const paths = expandPaths(routePath, needsEncode, registerLoose, registerLoose ? explicitPaths?.get(routeMethod) : void 0);
|
|
1481
1567
|
if (isDynamic) {
|
|
1482
1568
|
const router = this["~router"] ??= new Memoirist({ loosePath: isLoose });
|
|
1483
1569
|
const handler = this.handler(i, precompile, void 0, void 0, void 0, table);
|
|
@@ -1545,6 +1631,7 @@ var Elysia = class Elysia {
|
|
|
1545
1631
|
* ```
|
|
1546
1632
|
*/
|
|
1547
1633
|
cleanup(handler) {
|
|
1634
|
+
if (this["~ext"]?.cleanupEpoch?.(handler)) return this;
|
|
1548
1635
|
this.#assertMutable("cleanup");
|
|
1549
1636
|
const arr = this.#ext.cleanup ??= [];
|
|
1550
1637
|
if (Array.isArray(handler)) arr.push(...handler);
|
|
@@ -1552,24 +1639,49 @@ var Elysia = class Elysia {
|
|
|
1552
1639
|
return this;
|
|
1553
1640
|
}
|
|
1554
1641
|
/**
|
|
1555
|
-
* Stop the underlying server (if any),
|
|
1556
|
-
*
|
|
1642
|
+
* Stop the underlying server (if any), then run every `cleanup` handler.
|
|
1643
|
+
* Omitted and `false` are the same graceful stop: new requests are gated,
|
|
1644
|
+
* tracked WebSockets are settled and active HTTP is drained, then cleanup
|
|
1645
|
+
* runs and the epoch is released. `true` force-closes the transport
|
|
1646
|
+
* instead of draining it, and escalates a graceful stop already in flight.
|
|
1647
|
+
*
|
|
1648
|
+
* Awaiting `stop()` from inside a `setup`, `cleanup` or WebSocket lifecycle
|
|
1649
|
+
* callback is only supported while that callback is still synchronous; the
|
|
1650
|
+
* teardown is waiting on the callback, so after an `await` it can only be
|
|
1651
|
+
* issued as `void app.stop()`.
|
|
1557
1652
|
*
|
|
1558
|
-
* @param closeActiveConnections Pass `true` to terminate
|
|
1559
|
-
*
|
|
1560
|
-
* draining gracefully.
|
|
1653
|
+
* @param closeActiveConnections Pass `true` to terminate active
|
|
1654
|
+
* transports. Omit (or pass `false`) to drain safely.
|
|
1561
1655
|
*/
|
|
1562
1656
|
stop(closeActiveConnections) {
|
|
1657
|
+
const stop = this["~ext"]?.stop;
|
|
1658
|
+
if (stop) return stop(closeActiveConnections);
|
|
1563
1659
|
const server = this.server;
|
|
1564
1660
|
if (!server) return;
|
|
1565
|
-
|
|
1566
|
-
|
|
1661
|
+
let result;
|
|
1662
|
+
const errors = [];
|
|
1663
|
+
try {
|
|
1664
|
+
result = server.stop?.(closeActiveConnections);
|
|
1665
|
+
} catch (error) {
|
|
1666
|
+
errors.push(error);
|
|
1667
|
+
} finally {
|
|
1668
|
+
this.server = void 0;
|
|
1669
|
+
}
|
|
1567
1670
|
const handlers = this["~ext"]?.cleanup;
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1671
|
+
if (!errors.length && !handlers?.length) return result && typeof result.then === "function" ? result : void 0;
|
|
1672
|
+
return (async () => {
|
|
1673
|
+
try {
|
|
1674
|
+
await result;
|
|
1675
|
+
} catch (error) {
|
|
1676
|
+
errors.push(error);
|
|
1677
|
+
}
|
|
1678
|
+
if (handlers) for (let i = 0; i < handlers.length; i++) try {
|
|
1679
|
+
await handlers[i](this);
|
|
1680
|
+
} catch (error) {
|
|
1681
|
+
errors.push(error);
|
|
1682
|
+
}
|
|
1683
|
+
throwLifecycleErrors(errors);
|
|
1684
|
+
})();
|
|
1573
1685
|
}
|
|
1574
1686
|
};
|
|
1575
1687
|
|
|
@@ -13,8 +13,8 @@ const require_type_validator_frozen_check = require('../type/validator/frozen-ch
|
|
|
13
13
|
const require_type_validator_custom_error = require('../type/validator/custom-error.js');
|
|
14
14
|
const require_type_validator_exact_mirror = require('../type/validator/exact-mirror.js');
|
|
15
15
|
const require_type_validator_string_codec_aot = require('../type/validator/string-codec-aot.js');
|
|
16
|
-
let typebox_value = require("typebox/value");
|
|
17
16
|
let typebox_schema = require("typebox/schema");
|
|
17
|
+
let typebox_value = require("typebox/value");
|
|
18
18
|
|
|
19
19
|
//#region src/compile/aot-capture.ts
|
|
20
20
|
function emptyContainers(node, depth) {
|
|
@@ -11,8 +11,8 @@ import { buildFrozenCheck } from "../type/validator/frozen-check.mjs";
|
|
|
11
11
|
import { captureCustomErrors } from "../type/validator/custom-error.mjs";
|
|
12
12
|
import { getExactMirror } from "../type/validator/exact-mirror.mjs";
|
|
13
13
|
import { captureStringCodecEntries } from "../type/validator/string-codec-aot.mjs";
|
|
14
|
-
import { Default } from "typebox/value";
|
|
15
14
|
import { Build, Compile } from "typebox/schema";
|
|
15
|
+
import { Default } from "typebox/value";
|
|
16
16
|
|
|
17
17
|
//#region src/compile/aot-capture.ts
|
|
18
18
|
function emptyContainers(node, depth) {
|
package/dist/compile/aot.d.ts
CHANGED
|
@@ -8,8 +8,7 @@ interface AotFingerprint {
|
|
|
8
8
|
interface ProgramId {
|
|
9
9
|
readonly _: unique symbol;
|
|
10
10
|
}
|
|
11
|
-
declare const
|
|
12
|
-
declare function createAotFingerprint(): AotFingerprint;
|
|
11
|
+
declare const createAotFingerprint: () => AotFingerprint;
|
|
13
12
|
interface CompilerSession {
|
|
14
13
|
readonly sucroseCache: Map<number, {
|
|
15
14
|
content: string;
|
|
@@ -91,7 +90,7 @@ interface HandlerManifest {
|
|
|
91
90
|
}
|
|
92
91
|
interface CompiledSnapshot {
|
|
93
92
|
registered: CompiledProgramRegistration | undefined;
|
|
94
|
-
claimed:
|
|
93
|
+
claimed: WeakRef<ProgramId> | undefined;
|
|
95
94
|
programs: WeakMap<ProgramId, CompiledProgram>;
|
|
96
95
|
}
|
|
97
96
|
interface CompiledProgramRegistration {
|
|
@@ -131,9 +130,11 @@ declare function reconstruct(): ReconstructImpl;
|
|
|
131
130
|
declare abstract class Compiled {
|
|
132
131
|
static register(manifest: CompiledProgramRegistration): void;
|
|
133
132
|
static claim(id: ProgramId, fingerprint: AotFingerprint): boolean;
|
|
133
|
+
static assertUncontested(id: ProgramId): void;
|
|
134
134
|
static get reconstruct(): ReconstructImpl | undefined;
|
|
135
135
|
static set reconstruct(impl: ReconstructImpl | undefined);
|
|
136
136
|
static getHandler(id: ProgramId | undefined, method: string, path: string): FrozenHandler | undefined;
|
|
137
|
+
static hasProgram(id: ProgramId | undefined): boolean;
|
|
137
138
|
static getValidator(method: string, path: string, slot: ValidatorSlot, id?: ProgramId): FrozenValidator | undefined;
|
|
138
139
|
static hasValidator(method: string, path: string, slot: ValidatorSlot, id?: ProgramId): boolean;
|
|
139
140
|
static getPlanRebuilder(id?: ProgramId): ((original: unknown, plan: CoercePlan) => any) | undefined;
|
|
@@ -284,4 +285,4 @@ interface CaptureImpl {
|
|
|
284
285
|
declare let captureImpl: CaptureImpl | undefined;
|
|
285
286
|
declare function setCaptureImpl(impl: CaptureImpl | undefined): void;
|
|
286
287
|
//#endregion
|
|
287
|
-
export { AOT_ABI, AOT_MANIFEST_FORMAT, AotFingerprint, Capture, CaptureImpl, CapturedHandler, CapturedMirror, CapturedValidator, CheckBuildResult, Compiled, CompiledProgramRegistration, CompiledSnapshot, CompilerSession, CompilerState, EMPTY_EXTERNALS, FrozenBothFactory, FrozenCheckFactory, FrozenHandler, FrozenMirror, FrozenMirrorFactory, FrozenValidator, HandlerManifest, ProgramId, ReconstructImpl, StringCodecNode, ValidatorManifest, ValidatorSlot, aotActivationError, beginCompilerSession, captureImpl, createAotFingerprint,
|
|
288
|
+
export { AOT_ABI, AOT_MANIFEST_FORMAT, AotFingerprint, Capture, CaptureImpl, CapturedHandler, CapturedMirror, CapturedValidator, CheckBuildResult, Compiled, CompiledProgramRegistration, CompiledSnapshot, CompilerSession, CompilerState, EMPTY_EXTERNALS, FrozenBothFactory, FrozenCheckFactory, FrozenHandler, FrozenMirror, FrozenMirrorFactory, FrozenValidator, HandlerManifest, ProgramId, ReconstructImpl, StringCodecNode, ValidatorManifest, ValidatorSlot, aotActivationError, beginCompilerSession, captureImpl, createAotFingerprint, endCompilerSession, getCompilerSession, reconstruct, setCaptureImpl };
|
package/dist/compile/aot.js
CHANGED
|
@@ -6,11 +6,8 @@ const require_package = require('../package.js');
|
|
|
6
6
|
//#region src/compile/aot.ts
|
|
7
7
|
const AOT_MANIFEST_FORMAT = 3;
|
|
8
8
|
const AOT_ABI = `${require_package.version}:${3}`;
|
|
9
|
-
const createProgramId = () => ({});
|
|
10
9
|
const sharedAotFingerprint = Object.freeze({ abi: AOT_ABI });
|
|
11
|
-
|
|
12
|
-
return sharedAotFingerprint;
|
|
13
|
-
}
|
|
10
|
+
const createAotFingerprint = () => sharedAotFingerprint;
|
|
14
11
|
let activeSession;
|
|
15
12
|
const newCompilerSession = () => ({ sucroseCache: /* @__PURE__ */ new Map() });
|
|
16
13
|
function beginCompilerSession(app) {
|
|
@@ -41,7 +38,12 @@ function reconstruct() {
|
|
|
41
38
|
return reconstructImpl;
|
|
42
39
|
}
|
|
43
40
|
let registered;
|
|
44
|
-
|
|
41
|
+
/**
|
|
42
|
+
* App that consumed this process's manifest, held weakly: it only has to
|
|
43
|
+
* recognise a re-claim by the *same* app, and `assertUncontested` always
|
|
44
|
+
* compares against a live id, so a cleared ref answers as a strong one would
|
|
45
|
+
*/
|
|
46
|
+
let claimed;
|
|
45
47
|
let programs = /* @__PURE__ */ new WeakMap();
|
|
46
48
|
const programFor = (id) => id ? programs.get(id) : void 0;
|
|
47
49
|
const fingerprintMismatch = (manifest, actual) => {
|
|
@@ -54,14 +56,14 @@ const fingerprintMismatch = (manifest, actual) => {
|
|
|
54
56
|
var Compiled = class {
|
|
55
57
|
static register(manifest) {
|
|
56
58
|
registered = manifest;
|
|
57
|
-
claimed =
|
|
59
|
+
claimed = void 0;
|
|
58
60
|
}
|
|
59
61
|
static claim(id, fingerprint) {
|
|
60
62
|
if (!registered || claimed) return false;
|
|
61
63
|
const manifest = registered;
|
|
62
64
|
const differences = fingerprintMismatch(manifest, fingerprint);
|
|
63
65
|
if (differences.length) throw new Error(`[elysia-aot] Registered manifest fingerprint mismatch: ${differences.join("; ")}.`);
|
|
64
|
-
claimed =
|
|
66
|
+
claimed = new WeakRef(id);
|
|
65
67
|
registered = void 0;
|
|
66
68
|
programs.set(id, {
|
|
67
69
|
...manifest,
|
|
@@ -69,6 +71,10 @@ var Compiled = class {
|
|
|
69
71
|
});
|
|
70
72
|
return true;
|
|
71
73
|
}
|
|
74
|
+
static assertUncontested(id) {
|
|
75
|
+
if (claimed === void 0 || claimed.deref() === id || isAotBuildEnv()) return;
|
|
76
|
+
throw new Error("[elysia-aot] A second Elysia app built a router in this process. An AOT build seals one app per process.");
|
|
77
|
+
}
|
|
72
78
|
static get reconstruct() {
|
|
73
79
|
return reconstructImpl;
|
|
74
80
|
}
|
|
@@ -78,6 +84,9 @@ var Compiled = class {
|
|
|
78
84
|
static getHandler(id, method, path) {
|
|
79
85
|
return programFor(id)?.handlers?.[method]?.[path];
|
|
80
86
|
}
|
|
87
|
+
static hasProgram(id) {
|
|
88
|
+
return programFor(id) !== void 0;
|
|
89
|
+
}
|
|
81
90
|
static getValidator(method, path, slot, id) {
|
|
82
91
|
const program = programFor(id);
|
|
83
92
|
if (!program) return void 0;
|
|
@@ -116,7 +125,7 @@ var Compiled = class {
|
|
|
116
125
|
/** @internal test isolation */
|
|
117
126
|
static clear() {
|
|
118
127
|
registered = void 0;
|
|
119
|
-
claimed =
|
|
128
|
+
claimed = void 0;
|
|
120
129
|
programs = /* @__PURE__ */ new WeakMap();
|
|
121
130
|
}
|
|
122
131
|
};
|
|
@@ -213,7 +222,6 @@ Object.defineProperty(exports, 'captureImpl', {
|
|
|
213
222
|
}
|
|
214
223
|
});
|
|
215
224
|
exports.createAotFingerprint = createAotFingerprint;
|
|
216
|
-
exports.createProgramId = createProgramId;
|
|
217
225
|
exports.endCompilerSession = endCompilerSession;
|
|
218
226
|
exports.getCompilerSession = getCompilerSession;
|
|
219
227
|
exports.reconstruct = reconstruct;
|