elysia 2.0.0-exp.51 → 2.0.0-exp.53
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.js +2 -6
- package/dist/adapter/bun/index.mjs +2 -6
- package/dist/adapter/origin.d.ts +7 -3
- package/dist/adapter/origin.js +7 -3
- package/dist/adapter/origin.mjs +7 -3
- package/dist/adapter/utils.js +3 -3
- package/dist/adapter/utils.mjs +3 -3
- package/dist/base.d.ts +0 -10
- package/dist/base.js +50 -23
- package/dist/base.mjs +50 -23
- package/dist/compile/aot-capture.js +1 -1
- package/dist/compile/aot-capture.mjs +1 -1
- package/dist/compile/aot.d.ts +1 -1
- package/dist/compile/aot.js +4 -5
- package/dist/compile/aot.mjs +4 -5
- package/dist/compile/handler/frozen-validator.d.ts +1 -1
- package/dist/compile/handler/frozen-validator.js +1 -4
- package/dist/compile/handler/frozen-validator.mjs +1 -4
- package/dist/compile/handler/jit.js +2 -1
- package/dist/compile/handler/jit.mjs +3 -2
- package/dist/compile/handler/params.d.ts +2 -2
- package/dist/compile/handler/params.js +6 -3
- package/dist/compile/handler/params.mjs +7 -4
- package/dist/compile/handler/utils.d.ts +9 -1
- package/dist/compile/handler/utils.js +15 -0
- package/dist/compile/handler/utils.mjs +15 -1
- package/dist/context.d.ts +2 -2
- package/dist/cookie/crypto.js +6 -7
- package/dist/cookie/crypto.mjs +7 -8
- package/dist/handler/fetch.js +0 -1
- package/dist/handler/fetch.mjs +0 -1
- package/dist/package.js +1 -1
- package/dist/package.mjs +1 -1
- package/dist/plugin/aot/core.d.ts +4 -4
- package/dist/plugin/aot/core.js +1 -1
- package/dist/plugin/aot/core.mjs +1 -1
- package/dist/plugin/aot/source.d.ts +1 -1
- package/dist/plugin/aot/unplugin.d.ts +5 -9
- package/dist/plugin/aot/unplugin.js +3 -7
- package/dist/plugin/aot/unplugin.mjs +3 -7
- package/dist/schema-snapshot.js +6 -6
- package/dist/schema-snapshot.mjs +6 -6
- package/dist/sucrose.d.ts +1 -1
- package/dist/sucrose.js +14 -22
- package/dist/sucrose.mjs +15 -23
- package/dist/type/bridge.d.ts +6 -6
- package/dist/type/bridge.js +1 -2
- package/dist/type/bridge.mjs +1 -2
- package/dist/type/coerce-plan.js +2 -5
- package/dist/type/coerce-plan.mjs +3 -6
- package/dist/type/constants.d.ts +1 -1
- package/dist/type/elysia/string.js +6 -6
- package/dist/type/elysia/string.mjs +6 -6
- package/dist/type/elysia/utils.js +5 -7
- package/dist/type/elysia/utils.mjs +6 -8
- package/dist/type/validator/index.d.ts +1 -1
- package/dist/type/validator/index.js +2 -10
- package/dist/type/validator/index.mjs +2 -10
- package/dist/type/validator/validator-cache.js +5 -6
- package/dist/type/validator/validator-cache.mjs +6 -7
- package/dist/types.d.ts +1 -1
- package/dist/utils.d.ts +10 -1
- package/dist/utils.js +14 -0
- package/dist/utils.mjs +14 -1
- package/dist/ws/types.d.ts +2 -2
- package/package.json +1 -1
|
@@ -4,9 +4,9 @@ const require_constants = require('../../constants.js');
|
|
|
4
4
|
const require_utils = require('../../utils.js');
|
|
5
5
|
const require_adapter_web_standard_index = require('../web-standard/index.js');
|
|
6
6
|
const require_generation = require('../../generation.js');
|
|
7
|
+
const require_adapter_origin = require('../origin.js');
|
|
7
8
|
const require_compile_handler_index = require('../../compile/handler/index.js');
|
|
8
9
|
const require_route_table = require('../../route-table.js');
|
|
9
|
-
const require_adapter_origin = require('../origin.js');
|
|
10
10
|
|
|
11
11
|
//#region src/adapter/bun/index.ts
|
|
12
12
|
/**
|
|
@@ -15,12 +15,8 @@ const require_adapter_origin = require('../origin.js');
|
|
|
15
15
|
* always run before the next request comes in
|
|
16
16
|
* @see ../origin.ts
|
|
17
17
|
*
|
|
18
|
-
* Publish the request `Bun.serve` handed us so `createFetchHandler` can prove,
|
|
19
|
-
* before its first suspension, that it holds the untouched original and may
|
|
20
|
-
* defer materializing `request.signal`
|
|
21
|
-
*
|
|
22
18
|
* `finally` runs on the synchronous return of `fetch` (the returned promise is
|
|
23
|
-
* not awaited), so the slot is live only for the handler's synchronous prologue
|
|
19
|
+
* not awaited), so the slot is live only for the handler's synchronous prologue
|
|
24
20
|
*/
|
|
25
21
|
const withOrigin = (fetch) => (request, server) => {
|
|
26
22
|
require_adapter_origin.origin.request = request;
|
|
@@ -3,9 +3,9 @@ import { isDynamicRegex, needEncodeRegex } from "../../constants.mjs";
|
|
|
3
3
|
import { flattenChain, getLoosePath, nullObject } from "../../utils.mjs";
|
|
4
4
|
import { WebStandardAdapter } from "../web-standard/index.mjs";
|
|
5
5
|
import { frozenRootOf, resolvedWsOf } from "../../generation.mjs";
|
|
6
|
+
import { origin } from "../origin.mjs";
|
|
6
7
|
import { buildNativeStaticResponse } from "../../compile/handler/index.mjs";
|
|
7
8
|
import { routeRow } from "../../route-table.mjs";
|
|
8
|
-
import { origin } from "../origin.mjs";
|
|
9
9
|
|
|
10
10
|
//#region src/adapter/bun/index.ts
|
|
11
11
|
/**
|
|
@@ -14,12 +14,8 @@ import { origin } from "../origin.mjs";
|
|
|
14
14
|
* always run before the next request comes in
|
|
15
15
|
* @see ../origin.ts
|
|
16
16
|
*
|
|
17
|
-
* Publish the request `Bun.serve` handed us so `createFetchHandler` can prove,
|
|
18
|
-
* before its first suspension, that it holds the untouched original and may
|
|
19
|
-
* defer materializing `request.signal`
|
|
20
|
-
*
|
|
21
17
|
* `finally` runs on the synchronous return of `fetch` (the returned promise is
|
|
22
|
-
* not awaited), so the slot is live only for the handler's synchronous prologue
|
|
18
|
+
* not awaited), so the slot is live only for the handler's synchronous prologue
|
|
23
19
|
*/
|
|
24
20
|
const withOrigin = (fetch) => (request, server) => {
|
|
25
21
|
origin.request = request;
|
package/dist/adapter/origin.d.ts
CHANGED
|
@@ -11,7 +11,9 @@
|
|
|
11
11
|
* and therefore must be observed synchronously.
|
|
12
12
|
*
|
|
13
13
|
* The Bun adapter publishes the untouched original here for the *synchronous*
|
|
14
|
-
* prologue of `app.fetch` and
|
|
14
|
+
* prologue of `app.fetch` and, on the lane where `fetch` has no request hook
|
|
15
|
+
* to run, for the compiled route's own entry probe, which is still inside that
|
|
16
|
+
* same synchronous frame, then clears it in `finally`, so the window closes
|
|
15
17
|
* before the first suspension and cannot leak across concurrent requests.
|
|
16
18
|
* A `.wrap()` HOC that replaces the request or defers calling `next()` past a
|
|
17
19
|
* microtask simply misses the window, fetch handler falls back to eager check
|
|
@@ -23,14 +25,16 @@
|
|
|
23
25
|
* JavaScript only ever does ONE thing at a time. When a request comes in, the
|
|
24
26
|
* adapter writes its name on the whiteboard (`origin.request = request`),
|
|
25
27
|
* walks it down the hall (`fetch(request)` the synchronous part, where the
|
|
26
|
-
* one and only identity check happens
|
|
28
|
+
* one and only identity check happens, in `fetch`'s prologue, or at the
|
|
29
|
+
* compiled route's entry when `fetch` had no hook to run first), and erases
|
|
30
|
+
* the whiteboard `finally`
|
|
27
31
|
* all in one uninterruptible turn. The next request's turn CANNOT start
|
|
28
32
|
* until this turn is completely finished, because that is how the event loop
|
|
29
33
|
* works: run-to-completion, no preemption. So request B can never see request
|
|
30
34
|
* A's name on the board, by the time B's turn starts, the board was already
|
|
31
35
|
* erased at the end of A's turn.
|
|
32
36
|
*
|
|
33
|
-
* "But the handler is async!"
|
|
37
|
+
* "But the handler is async!" the `await`s inside it run LATER, in separate
|
|
34
38
|
* turns. That is fine, because the check already happened: the verdict was
|
|
35
39
|
* copied onto that request's own context (`'~sig'`) during the synchronous
|
|
36
40
|
* part, and the code that runs after an `await` only ever reads the context,
|
package/dist/adapter/origin.js
CHANGED
|
@@ -13,7 +13,9 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
13
13
|
* and therefore must be observed synchronously.
|
|
14
14
|
*
|
|
15
15
|
* The Bun adapter publishes the untouched original here for the *synchronous*
|
|
16
|
-
* prologue of `app.fetch` and
|
|
16
|
+
* prologue of `app.fetch` and, on the lane where `fetch` has no request hook
|
|
17
|
+
* to run, for the compiled route's own entry probe, which is still inside that
|
|
18
|
+
* same synchronous frame, then clears it in `finally`, so the window closes
|
|
17
19
|
* before the first suspension and cannot leak across concurrent requests.
|
|
18
20
|
* A `.wrap()` HOC that replaces the request or defers calling `next()` past a
|
|
19
21
|
* microtask simply misses the window, fetch handler falls back to eager check
|
|
@@ -25,14 +27,16 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
25
27
|
* JavaScript only ever does ONE thing at a time. When a request comes in, the
|
|
26
28
|
* adapter writes its name on the whiteboard (`origin.request = request`),
|
|
27
29
|
* walks it down the hall (`fetch(request)` the synchronous part, where the
|
|
28
|
-
* one and only identity check happens
|
|
30
|
+
* one and only identity check happens, in `fetch`'s prologue, or at the
|
|
31
|
+
* compiled route's entry when `fetch` had no hook to run first), and erases
|
|
32
|
+
* the whiteboard `finally`
|
|
29
33
|
* all in one uninterruptible turn. The next request's turn CANNOT start
|
|
30
34
|
* until this turn is completely finished, because that is how the event loop
|
|
31
35
|
* works: run-to-completion, no preemption. So request B can never see request
|
|
32
36
|
* A's name on the board, by the time B's turn starts, the board was already
|
|
33
37
|
* erased at the end of A's turn.
|
|
34
38
|
*
|
|
35
|
-
* "But the handler is async!"
|
|
39
|
+
* "But the handler is async!" the `await`s inside it run LATER, in separate
|
|
36
40
|
* turns. That is fine, because the check already happened: the verdict was
|
|
37
41
|
* copied onto that request's own context (`'~sig'`) during the synchronous
|
|
38
42
|
* part, and the code that runs after an `await` only ever reads the context,
|
package/dist/adapter/origin.mjs
CHANGED
|
@@ -11,7 +11,9 @@
|
|
|
11
11
|
* and therefore must be observed synchronously.
|
|
12
12
|
*
|
|
13
13
|
* The Bun adapter publishes the untouched original here for the *synchronous*
|
|
14
|
-
* prologue of `app.fetch` and
|
|
14
|
+
* prologue of `app.fetch` and, on the lane where `fetch` has no request hook
|
|
15
|
+
* to run, for the compiled route's own entry probe, which is still inside that
|
|
16
|
+
* same synchronous frame, then clears it in `finally`, so the window closes
|
|
15
17
|
* before the first suspension and cannot leak across concurrent requests.
|
|
16
18
|
* A `.wrap()` HOC that replaces the request or defers calling `next()` past a
|
|
17
19
|
* microtask simply misses the window, fetch handler falls back to eager check
|
|
@@ -23,14 +25,16 @@
|
|
|
23
25
|
* JavaScript only ever does ONE thing at a time. When a request comes in, the
|
|
24
26
|
* adapter writes its name on the whiteboard (`origin.request = request`),
|
|
25
27
|
* walks it down the hall (`fetch(request)` the synchronous part, where the
|
|
26
|
-
* one and only identity check happens
|
|
28
|
+
* one and only identity check happens, in `fetch`'s prologue, or at the
|
|
29
|
+
* compiled route's entry when `fetch` had no hook to run first), and erases
|
|
30
|
+
* the whiteboard `finally`
|
|
27
31
|
* all in one uninterruptible turn. The next request's turn CANNOT start
|
|
28
32
|
* until this turn is completely finished, because that is how the event loop
|
|
29
33
|
* works: run-to-completion, no preemption. So request B can never see request
|
|
30
34
|
* A's name on the board, by the time B's turn starts, the board was already
|
|
31
35
|
* erased at the end of A's turn.
|
|
32
36
|
*
|
|
33
|
-
* "But the handler is async!"
|
|
37
|
+
* "But the handler is async!" the `await`s inside it run LATER, in separate
|
|
34
38
|
* turns. That is fine, because the check already happened: the verdict was
|
|
35
39
|
* copied onto that request's own context (`'~sig'`) during the synchronous
|
|
36
40
|
* part, and the code that runs after an `await` only ever reads the context,
|
package/dist/adapter/utils.js
CHANGED
|
@@ -360,20 +360,20 @@ function createResponseHandler(handler) {
|
|
|
360
360
|
const explicitlyBorrowed = require_adapter_response_ownership.isBorrowedResponse(response);
|
|
361
361
|
const borrowed = !owned || explicitlyBorrowed;
|
|
362
362
|
const mustClone = owned && explicitlyBorrowed;
|
|
363
|
-
if (!borrowed && response.bodyUsed) throw new TypeError("Cannot reuse a consumed Response across requests
|
|
363
|
+
if (!borrowed && response.bodyUsed) throw new TypeError("Cannot reuse a consumed Response across requests");
|
|
364
364
|
if (set) {
|
|
365
365
|
const status = mergeStatus(response.status, set.status);
|
|
366
366
|
const statusUnchanged = status === void 0 || status === response.status;
|
|
367
367
|
if (!mustClone && statusUnchanged && !set.cookie && !require_utils.isNotEmpty(set.headers)) return response;
|
|
368
368
|
} else if (!mustClone) return response;
|
|
369
|
-
if (!borrowed && response.body?.locked) throw new TypeError("Cannot patch a Response whose body is locked
|
|
369
|
+
if (!borrowed && response.body?.locked) throw new TypeError("Cannot patch a Response whose body is locked");
|
|
370
370
|
let body = response.body;
|
|
371
371
|
if (borrowed) {
|
|
372
372
|
const bodyBefore = body;
|
|
373
373
|
const cloned = response.clone();
|
|
374
374
|
if (explicitlyBorrowed && bodyBefore && response.body !== bodyBefore && !warnedStreamBorrows.has(response)) {
|
|
375
375
|
warnedStreamBorrows.add(response);
|
|
376
|
-
console.warn("[elysia] borrow() was called on a stream-backed Response
|
|
376
|
+
console.warn("[elysia] borrow() was called on a stream-backed Response");
|
|
377
377
|
}
|
|
378
378
|
body = cloned.body && response.body ? cancelPropagatingBody(cloned.body, response.body, explicitlyBorrowed) : cloned.body;
|
|
379
379
|
}
|
package/dist/adapter/utils.mjs
CHANGED
|
@@ -359,20 +359,20 @@ function createResponseHandler(handler) {
|
|
|
359
359
|
const explicitlyBorrowed = isBorrowedResponse(response);
|
|
360
360
|
const borrowed = !owned || explicitlyBorrowed;
|
|
361
361
|
const mustClone = owned && explicitlyBorrowed;
|
|
362
|
-
if (!borrowed && response.bodyUsed) throw new TypeError("Cannot reuse a consumed Response across requests
|
|
362
|
+
if (!borrowed && response.bodyUsed) throw new TypeError("Cannot reuse a consumed Response across requests");
|
|
363
363
|
if (set) {
|
|
364
364
|
const status = mergeStatus(response.status, set.status);
|
|
365
365
|
const statusUnchanged = status === void 0 || status === response.status;
|
|
366
366
|
if (!mustClone && statusUnchanged && !set.cookie && !isNotEmpty(set.headers)) return response;
|
|
367
367
|
} else if (!mustClone) return response;
|
|
368
|
-
if (!borrowed && response.body?.locked) throw new TypeError("Cannot patch a Response whose body is locked
|
|
368
|
+
if (!borrowed && response.body?.locked) throw new TypeError("Cannot patch a Response whose body is locked");
|
|
369
369
|
let body = response.body;
|
|
370
370
|
if (borrowed) {
|
|
371
371
|
const bodyBefore = body;
|
|
372
372
|
const cloned = response.clone();
|
|
373
373
|
if (explicitlyBorrowed && bodyBefore && response.body !== bodyBefore && !warnedStreamBorrows.has(response)) {
|
|
374
374
|
warnedStreamBorrows.add(response);
|
|
375
|
-
console.warn("[elysia] borrow() was called on a stream-backed Response
|
|
375
|
+
console.warn("[elysia] borrow() was called on a stream-backed Response");
|
|
376
376
|
}
|
|
377
377
|
body = cloned.body && response.body ? cancelPropagatingBody(cloned.body, response.body, explicitlyBorrowed) : cloned.body;
|
|
378
378
|
}
|
package/dist/base.d.ts
CHANGED
|
@@ -524,16 +524,6 @@ declare class Elysia<const in out BasePath extends string = '', const in out Sco
|
|
|
524
524
|
parser: Metadata['parser'];
|
|
525
525
|
response: Metadata['response'] & MacroContext['response'] & ElysiaHandlerToResponseSchemaAmbiguous<BeforeHandle> & ElysiaHandlerToResponseSchemaAmbiguous<AfterHandle> & ElysiaHandlerToResponseSchemaAmbiguous<ErrorHandle>;
|
|
526
526
|
}, {}, Ephemeral, Volatile>) => NewElysia): Elysia<BasePath, Scope, Singleton, Definitions, Metadata, Routes & NewElysia['~Routes'], Ephemeral, Volatile>;
|
|
527
|
-
/**
|
|
528
|
-
* Single idempotent capability resolver-accessor (README rev 2.1). Reads
|
|
529
|
-
* the merged `~ext.capability` channel — never mutated during a build — and
|
|
530
|
-
* throws when a capability is used but its provider was never registered.
|
|
531
|
-
* For `trace` the resolved view IS the nearest-root provider (merge already
|
|
532
|
-
* keeps it); for `ws` it additionally resolves the depth-precedence base
|
|
533
|
-
* options. Called at the start of every router build and by `compileHandler`
|
|
534
|
-
* before it reads the frozen root, so direct-compiler paths resolve without
|
|
535
|
-
* a prior seal.
|
|
536
|
-
*/
|
|
537
527
|
['~resolvedCapability'](kind: 'trace'): TraceCapability | undefined;
|
|
538
528
|
['~resolvedCapability'](kind: 'ws'): {
|
|
539
529
|
provider: WSCapability;
|
package/dist/base.js
CHANGED
|
@@ -33,9 +33,7 @@ var Elysia = class Elysia {
|
|
|
33
33
|
#macroBaseline;
|
|
34
34
|
#declaredRoutes;
|
|
35
35
|
#routeSources;
|
|
36
|
-
#cachedHistory;
|
|
37
36
|
get history() {
|
|
38
|
-
if (this.#cachedHistory) return this.#cachedHistory;
|
|
39
37
|
if (this.#declaredRoutes === void 0 && this["~routeTable"]?.length) this.#materializeDeclaredRoutes();
|
|
40
38
|
if (!this.#declaredRoutes?.length) return emptyHistory;
|
|
41
39
|
const history = new Array(this.#declaredRoutes.length);
|
|
@@ -49,7 +47,7 @@ var Elysia = class Elysia {
|
|
|
49
47
|
...source === void 0 ? {} : { source }
|
|
50
48
|
});
|
|
51
49
|
}
|
|
52
|
-
return
|
|
50
|
+
return Object.freeze(history);
|
|
53
51
|
}
|
|
54
52
|
get ["~routes"]() {
|
|
55
53
|
if (this.#declaredRoutes === void 0 && this["~routeTable"]?.length) this.#materializeDeclaredRoutes();
|
|
@@ -83,19 +81,59 @@ var Elysia = class Elysia {
|
|
|
83
81
|
#jitRoute;
|
|
84
82
|
#jitStatic;
|
|
85
83
|
#jitAliases;
|
|
86
|
-
#cachedRoutes;
|
|
87
84
|
constructor(config) {
|
|
88
|
-
|
|
85
|
+
/**
|
|
86
|
+
* ! Don't tune
|
|
87
|
+
*
|
|
88
|
+
* Interesting JSC internal: These `= undefined` are load-bearing
|
|
89
|
+
*
|
|
90
|
+
* Inline slots live inside the object cell, so JSC must pick their
|
|
91
|
+
* count at allocation before any initializer runs
|
|
92
|
+
*
|
|
93
|
+
* Its only signal is counting `this.x =` in the ctor body;
|
|
94
|
+
* class-field initializers compile into a separate hidden function
|
|
95
|
+
* the guess never sees
|
|
96
|
+
*
|
|
97
|
+
* The cell can't grow afterwards, so once inline slots run out every
|
|
98
|
+
* later property spills into the butterfly, and capacity is by n^2
|
|
99
|
+
*
|
|
100
|
+
* Fields run first before ctor (here), so they take the inline slots
|
|
101
|
+
* these assignments reserve
|
|
102
|
+
*
|
|
103
|
+
* Don't omitted field either for monomorphic access
|
|
104
|
+
*
|
|
105
|
+
* @see test/memory/instance-footprint.test.ts
|
|
106
|
+
* Est. Overflow 37 -> 21 = butterfly 64 -> 32 slots = 738B -> 450B/instance
|
|
107
|
+
**/
|
|
89
108
|
this["~config"] = config;
|
|
90
|
-
this["~
|
|
91
|
-
|
|
92
|
-
|
|
109
|
+
this["~ext"] = void 0;
|
|
110
|
+
this["~hookChain"] = void 0;
|
|
111
|
+
this["~wsConfig"] = void 0;
|
|
112
|
+
this.server = void 0;
|
|
113
|
+
this["~router"] = void 0;
|
|
114
|
+
this["~map"] = void 0;
|
|
115
|
+
this["~routeTable"] = void 0;
|
|
116
|
+
this["~hasWS"] = void 0;
|
|
117
|
+
this["~hasDynamicWS"] = void 0;
|
|
118
|
+
this["~hasTrace"] = void 0;
|
|
119
|
+
this["~finalizeError"] = void 0;
|
|
120
|
+
this["~aotFingerprint"] = void 0;
|
|
121
|
+
this["~compilerSession"] = void 0;
|
|
122
|
+
this["~generation"] = void 0;
|
|
123
|
+
this["~introspect"] = void 0;
|
|
124
|
+
this["~scopeChild"] = void 0;
|
|
125
|
+
this["~scopeChildren"] = void 0;
|
|
126
|
+
this["~programId"] = require_compile_aot.createProgramId();
|
|
127
|
+
if (config) {
|
|
128
|
+
const { prefix, name, seed } = config;
|
|
129
|
+
this["~Prefix"] = prefix ? prefix.charCodeAt(0) === 47 ? prefix : `/${prefix}` : void 0;
|
|
130
|
+
if (name) this.#hash = require_utils.fnv1a(seed ? `${name}_${typeof seed === "object" ? JSON.stringify(seed, require_utils.serializeMacroSeed) : seed}` : name);
|
|
131
|
+
} else this["~Prefix"] = void 0;
|
|
93
132
|
}
|
|
94
133
|
get routes() {
|
|
95
|
-
if (this.#cachedRoutes) return this.#cachedRoutes;
|
|
96
134
|
if (this.#declaredRoutes === void 0 && this["~routeTable"]?.length) this.#materializeDeclaredRoutes();
|
|
97
135
|
if (!this.#declaredRoutes?.length) return [];
|
|
98
|
-
|
|
136
|
+
return this["~routes"].map(([method, path, handler, instance, hook, appHook, inheritedChain, macroScope]) => {
|
|
99
137
|
const merged = require_compile_handler_index.composeRouteHook(instance, hook, appHook, inheritedChain, this, macroScope);
|
|
100
138
|
if (merged?.schemas?.length) for (const entry of merged.schemas) {
|
|
101
139
|
if (!entry?.response) continue;
|
|
@@ -109,8 +147,6 @@ var Elysia = class Elysia {
|
|
|
109
147
|
hooks: merged
|
|
110
148
|
};
|
|
111
149
|
});
|
|
112
|
-
this.#cachedRoutes = routes;
|
|
113
|
-
return routes;
|
|
114
150
|
}
|
|
115
151
|
decorate(typeOrNameOrDecorators, nameOrDecorators, value) {
|
|
116
152
|
switch (arguments.length) {
|
|
@@ -186,7 +222,6 @@ var Elysia = class Elysia {
|
|
|
186
222
|
scope,
|
|
187
223
|
owner: this
|
|
188
224
|
};
|
|
189
|
-
this.#cachedRoutes = void 0;
|
|
190
225
|
if (scope === "plugin") this.#hasPlugin = true;
|
|
191
226
|
else if (scope === "global") this.#hasGlobal = true;
|
|
192
227
|
if (this.#hash !== void 0) {
|
|
@@ -306,7 +341,6 @@ var Elysia = class Elysia {
|
|
|
306
341
|
as(target) {
|
|
307
342
|
this.#assertMutable("as");
|
|
308
343
|
this.#as(this["~hookChain"], target === "global" ? "global" : "plugin");
|
|
309
|
-
this.#cachedRoutes = void 0;
|
|
310
344
|
return this;
|
|
311
345
|
}
|
|
312
346
|
#as(node, scope) {
|
|
@@ -452,7 +486,6 @@ var Elysia = class Elysia {
|
|
|
452
486
|
scope,
|
|
453
487
|
owner: this
|
|
454
488
|
};
|
|
455
|
-
this.#cachedRoutes = void 0;
|
|
456
489
|
return this;
|
|
457
490
|
}
|
|
458
491
|
macro(macro) {
|
|
@@ -466,7 +499,6 @@ var Elysia = class Elysia {
|
|
|
466
499
|
if (baseline?.has(key) && key in m && m[key] !== macro[key]) throw new Error(`[Elysia] Macro "${key}" can be only define once`);
|
|
467
500
|
}
|
|
468
501
|
Object.assign(m, macro);
|
|
469
|
-
this.#cachedRoutes = void 0;
|
|
470
502
|
require_utils.invalidateMacroEpoch();
|
|
471
503
|
return this;
|
|
472
504
|
}
|
|
@@ -606,7 +638,6 @@ var Elysia = class Elysia {
|
|
|
606
638
|
this.#childrenHash.add(hash);
|
|
607
639
|
(addedByThisCall ??= /* @__PURE__ */ new Set()).add(hash);
|
|
608
640
|
}
|
|
609
|
-
this.#cachedRoutes = void 0;
|
|
610
641
|
if (app.#childrenHash) addedByThisCall = this.#absorbChildrenHash(app, addedByThisCall);
|
|
611
642
|
if (app["~ext"]) this.#assertMacroUnique(app, addedByThisCall);
|
|
612
643
|
if (app["~hasTrace"]) this["~hasTrace"] = true;
|
|
@@ -961,9 +992,7 @@ var Elysia = class Elysia {
|
|
|
961
992
|
handler,
|
|
962
993
|
this
|
|
963
994
|
]);
|
|
964
|
-
if (this.#routerBuilt || this.#compiled !== void 0
|
|
965
|
-
this.#cachedHistory = void 0;
|
|
966
|
-
this.#cachedRoutes = void 0;
|
|
995
|
+
if (this.#routerBuilt || this.#compiled !== void 0) {
|
|
967
996
|
this.#compiled = void 0;
|
|
968
997
|
this.#jitColdRemaining = void 0;
|
|
969
998
|
this.#jitTable = void 0;
|
|
@@ -993,9 +1022,7 @@ var Elysia = class Elysia {
|
|
|
993
1022
|
const sequence = routes.length;
|
|
994
1023
|
routes.push(route);
|
|
995
1024
|
if (source) (this.#routeSources ??= [])[sequence] = source;
|
|
996
|
-
if (this.#routerBuilt || this.#compiled !== void 0
|
|
997
|
-
this.#cachedHistory = void 0;
|
|
998
|
-
this.#cachedRoutes = void 0;
|
|
1025
|
+
if (this.#routerBuilt || this.#compiled !== void 0) {
|
|
999
1026
|
this.#compiled = void 0;
|
|
1000
1027
|
this.#jitColdRemaining = void 0;
|
|
1001
1028
|
this.#jitTable = void 0;
|
package/dist/base.mjs
CHANGED
|
@@ -30,9 +30,7 @@ var Elysia = class Elysia {
|
|
|
30
30
|
#macroBaseline;
|
|
31
31
|
#declaredRoutes;
|
|
32
32
|
#routeSources;
|
|
33
|
-
#cachedHistory;
|
|
34
33
|
get history() {
|
|
35
|
-
if (this.#cachedHistory) return this.#cachedHistory;
|
|
36
34
|
if (this.#declaredRoutes === void 0 && this["~routeTable"]?.length) this.#materializeDeclaredRoutes();
|
|
37
35
|
if (!this.#declaredRoutes?.length) return emptyHistory;
|
|
38
36
|
const history = new Array(this.#declaredRoutes.length);
|
|
@@ -46,7 +44,7 @@ var Elysia = class Elysia {
|
|
|
46
44
|
...source === void 0 ? {} : { source }
|
|
47
45
|
});
|
|
48
46
|
}
|
|
49
|
-
return
|
|
47
|
+
return Object.freeze(history);
|
|
50
48
|
}
|
|
51
49
|
get ["~routes"]() {
|
|
52
50
|
if (this.#declaredRoutes === void 0 && this["~routeTable"]?.length) this.#materializeDeclaredRoutes();
|
|
@@ -80,19 +78,59 @@ var Elysia = class Elysia {
|
|
|
80
78
|
#jitRoute;
|
|
81
79
|
#jitStatic;
|
|
82
80
|
#jitAliases;
|
|
83
|
-
#cachedRoutes;
|
|
84
81
|
constructor(config) {
|
|
85
|
-
|
|
82
|
+
/**
|
|
83
|
+
* ! Don't tune
|
|
84
|
+
*
|
|
85
|
+
* Interesting JSC internal: These `= undefined` are load-bearing
|
|
86
|
+
*
|
|
87
|
+
* Inline slots live inside the object cell, so JSC must pick their
|
|
88
|
+
* count at allocation before any initializer runs
|
|
89
|
+
*
|
|
90
|
+
* Its only signal is counting `this.x =` in the ctor body;
|
|
91
|
+
* class-field initializers compile into a separate hidden function
|
|
92
|
+
* the guess never sees
|
|
93
|
+
*
|
|
94
|
+
* The cell can't grow afterwards, so once inline slots run out every
|
|
95
|
+
* later property spills into the butterfly, and capacity is by n^2
|
|
96
|
+
*
|
|
97
|
+
* Fields run first before ctor (here), so they take the inline slots
|
|
98
|
+
* these assignments reserve
|
|
99
|
+
*
|
|
100
|
+
* Don't omitted field either for monomorphic access
|
|
101
|
+
*
|
|
102
|
+
* @see test/memory/instance-footprint.test.ts
|
|
103
|
+
* Est. Overflow 37 -> 21 = butterfly 64 -> 32 slots = 738B -> 450B/instance
|
|
104
|
+
**/
|
|
86
105
|
this["~config"] = config;
|
|
87
|
-
this["~
|
|
88
|
-
|
|
89
|
-
|
|
106
|
+
this["~ext"] = void 0;
|
|
107
|
+
this["~hookChain"] = void 0;
|
|
108
|
+
this["~wsConfig"] = void 0;
|
|
109
|
+
this.server = void 0;
|
|
110
|
+
this["~router"] = void 0;
|
|
111
|
+
this["~map"] = void 0;
|
|
112
|
+
this["~routeTable"] = void 0;
|
|
113
|
+
this["~hasWS"] = void 0;
|
|
114
|
+
this["~hasDynamicWS"] = void 0;
|
|
115
|
+
this["~hasTrace"] = void 0;
|
|
116
|
+
this["~finalizeError"] = void 0;
|
|
117
|
+
this["~aotFingerprint"] = void 0;
|
|
118
|
+
this["~compilerSession"] = void 0;
|
|
119
|
+
this["~generation"] = void 0;
|
|
120
|
+
this["~introspect"] = void 0;
|
|
121
|
+
this["~scopeChild"] = void 0;
|
|
122
|
+
this["~scopeChildren"] = void 0;
|
|
123
|
+
this["~programId"] = createProgramId();
|
|
124
|
+
if (config) {
|
|
125
|
+
const { prefix, name, seed } = config;
|
|
126
|
+
this["~Prefix"] = prefix ? prefix.charCodeAt(0) === 47 ? prefix : `/${prefix}` : void 0;
|
|
127
|
+
if (name) this.#hash = fnv1a(seed ? `${name}_${typeof seed === "object" ? JSON.stringify(seed, serializeMacroSeed) : seed}` : name);
|
|
128
|
+
} else this["~Prefix"] = void 0;
|
|
90
129
|
}
|
|
91
130
|
get routes() {
|
|
92
|
-
if (this.#cachedRoutes) return this.#cachedRoutes;
|
|
93
131
|
if (this.#declaredRoutes === void 0 && this["~routeTable"]?.length) this.#materializeDeclaredRoutes();
|
|
94
132
|
if (!this.#declaredRoutes?.length) return [];
|
|
95
|
-
|
|
133
|
+
return this["~routes"].map(([method, path, handler, instance, hook, appHook, inheritedChain, macroScope]) => {
|
|
96
134
|
const merged = composeRouteHook(instance, hook, appHook, inheritedChain, this, macroScope);
|
|
97
135
|
if (merged?.schemas?.length) for (const entry of merged.schemas) {
|
|
98
136
|
if (!entry?.response) continue;
|
|
@@ -106,8 +144,6 @@ var Elysia = class Elysia {
|
|
|
106
144
|
hooks: merged
|
|
107
145
|
};
|
|
108
146
|
});
|
|
109
|
-
this.#cachedRoutes = routes;
|
|
110
|
-
return routes;
|
|
111
147
|
}
|
|
112
148
|
decorate(typeOrNameOrDecorators, nameOrDecorators, value) {
|
|
113
149
|
switch (arguments.length) {
|
|
@@ -183,7 +219,6 @@ var Elysia = class Elysia {
|
|
|
183
219
|
scope,
|
|
184
220
|
owner: this
|
|
185
221
|
};
|
|
186
|
-
this.#cachedRoutes = void 0;
|
|
187
222
|
if (scope === "plugin") this.#hasPlugin = true;
|
|
188
223
|
else if (scope === "global") this.#hasGlobal = true;
|
|
189
224
|
if (this.#hash !== void 0) {
|
|
@@ -303,7 +338,6 @@ var Elysia = class Elysia {
|
|
|
303
338
|
as(target) {
|
|
304
339
|
this.#assertMutable("as");
|
|
305
340
|
this.#as(this["~hookChain"], target === "global" ? "global" : "plugin");
|
|
306
|
-
this.#cachedRoutes = void 0;
|
|
307
341
|
return this;
|
|
308
342
|
}
|
|
309
343
|
#as(node, scope) {
|
|
@@ -449,7 +483,6 @@ var Elysia = class Elysia {
|
|
|
449
483
|
scope,
|
|
450
484
|
owner: this
|
|
451
485
|
};
|
|
452
|
-
this.#cachedRoutes = void 0;
|
|
453
486
|
return this;
|
|
454
487
|
}
|
|
455
488
|
macro(macro) {
|
|
@@ -463,7 +496,6 @@ var Elysia = class Elysia {
|
|
|
463
496
|
if (baseline?.has(key) && key in m && m[key] !== macro[key]) throw new Error(`[Elysia] Macro "${key}" can be only define once`);
|
|
464
497
|
}
|
|
465
498
|
Object.assign(m, macro);
|
|
466
|
-
this.#cachedRoutes = void 0;
|
|
467
499
|
invalidateMacroEpoch();
|
|
468
500
|
return this;
|
|
469
501
|
}
|
|
@@ -603,7 +635,6 @@ var Elysia = class Elysia {
|
|
|
603
635
|
this.#childrenHash.add(hash);
|
|
604
636
|
(addedByThisCall ??= /* @__PURE__ */ new Set()).add(hash);
|
|
605
637
|
}
|
|
606
|
-
this.#cachedRoutes = void 0;
|
|
607
638
|
if (app.#childrenHash) addedByThisCall = this.#absorbChildrenHash(app, addedByThisCall);
|
|
608
639
|
if (app["~ext"]) this.#assertMacroUnique(app, addedByThisCall);
|
|
609
640
|
if (app["~hasTrace"]) this["~hasTrace"] = true;
|
|
@@ -958,9 +989,7 @@ var Elysia = class Elysia {
|
|
|
958
989
|
handler,
|
|
959
990
|
this
|
|
960
991
|
]);
|
|
961
|
-
if (this.#routerBuilt || this.#compiled !== void 0
|
|
962
|
-
this.#cachedHistory = void 0;
|
|
963
|
-
this.#cachedRoutes = void 0;
|
|
992
|
+
if (this.#routerBuilt || this.#compiled !== void 0) {
|
|
964
993
|
this.#compiled = void 0;
|
|
965
994
|
this.#jitColdRemaining = void 0;
|
|
966
995
|
this.#jitTable = void 0;
|
|
@@ -990,9 +1019,7 @@ var Elysia = class Elysia {
|
|
|
990
1019
|
const sequence = routes.length;
|
|
991
1020
|
routes.push(route);
|
|
992
1021
|
if (source) (this.#routeSources ??= [])[sequence] = source;
|
|
993
|
-
if (this.#routerBuilt || this.#compiled !== void 0
|
|
994
|
-
this.#cachedHistory = void 0;
|
|
995
|
-
this.#cachedRoutes = void 0;
|
|
1022
|
+
if (this.#routerBuilt || this.#compiled !== void 0) {
|
|
996
1023
|
this.#compiled = void 0;
|
|
997
1024
|
this.#jitColdRemaining = void 0;
|
|
998
1025
|
this.#jitTable = void 0;
|
|
@@ -283,7 +283,7 @@ function captureBridgeFree(aot, slot, rawSchema) {
|
|
|
283
283
|
}
|
|
284
284
|
}
|
|
285
285
|
function beginValidatorCapture() {
|
|
286
|
-
if (require_compile_aot.captureImpl === void 0) throw require_compile_aot.aotActivationError;
|
|
286
|
+
if (require_compile_aot.captureImpl === void 0) throw require_compile_aot.aotActivationError();
|
|
287
287
|
const active = require_compile_aot.CompilerState.session;
|
|
288
288
|
if (active?.capture !== void 0) {
|
|
289
289
|
if (active.explicitCapture) throw new Error("[elysia-aot]: A capture session is already active.");
|
|
@@ -280,7 +280,7 @@ function captureBridgeFree(aot, slot, rawSchema) {
|
|
|
280
280
|
}
|
|
281
281
|
}
|
|
282
282
|
function beginValidatorCapture() {
|
|
283
|
-
if (captureImpl === void 0) throw aotActivationError;
|
|
283
|
+
if (captureImpl === void 0) throw aotActivationError();
|
|
284
284
|
const active = CompilerState.session;
|
|
285
285
|
if (active?.capture !== void 0) {
|
|
286
286
|
if (active.explicitCapture) throw new Error("[elysia-aot]: A capture session is already active.");
|
package/dist/compile/aot.d.ts
CHANGED
|
@@ -217,7 +217,7 @@ interface CapturedValidator {
|
|
|
217
217
|
bridgeFree?: boolean;
|
|
218
218
|
}
|
|
219
219
|
/** @internal shared with `aot-capture.ts` (`beginValidatorCapture`). */
|
|
220
|
-
declare const aotActivationError: Error;
|
|
220
|
+
declare const aotActivationError: () => Error;
|
|
221
221
|
interface CapturedHandler {
|
|
222
222
|
method: string;
|
|
223
223
|
path: string;
|
package/dist/compile/aot.js
CHANGED
|
@@ -36,9 +36,8 @@ function endCompilerSession(app, session, failed = false) {
|
|
|
36
36
|
}
|
|
37
37
|
const getCompilerSession = () => activeSession;
|
|
38
38
|
let reconstructImpl;
|
|
39
|
-
const reconstructActivationError = /* @__PURE__ */ new Error("Elysia AOT reconstruct module is not activated.");
|
|
40
39
|
function reconstruct() {
|
|
41
|
-
if (reconstructImpl === void 0) throw
|
|
40
|
+
if (reconstructImpl === void 0) throw new Error("Elysia AOT reconstruct module is not activated");
|
|
42
41
|
return reconstructImpl;
|
|
43
42
|
}
|
|
44
43
|
let registered;
|
|
@@ -161,7 +160,7 @@ function captureEntry({ method, path, slot }) {
|
|
|
161
160
|
return e;
|
|
162
161
|
}
|
|
163
162
|
/** @internal shared with `aot-capture.ts` (`beginValidatorCapture`). */
|
|
164
|
-
const aotActivationError = /* @__PURE__ */ new Error("Elysia AOT capture module is not activated.");
|
|
163
|
+
const aotActivationError = () => /* @__PURE__ */ new Error("Elysia AOT capture module is not activated.");
|
|
165
164
|
function captureHandler(v) {
|
|
166
165
|
if (!isValidatorCapturing()) return;
|
|
167
166
|
const session = activeSession;
|
|
@@ -176,11 +175,11 @@ const captureGet = (loc) => activeSession?.capture?.get(`${loc.method}_${loc.pat
|
|
|
176
175
|
const isAotBuildEnv = () => !!require_universal_env.env.ELYSIA_AOT_BUILD;
|
|
177
176
|
const isValidatorCapturing = () => {
|
|
178
177
|
if (activeSession?.capture !== void 0) {
|
|
179
|
-
if (captureImpl === void 0) throw aotActivationError;
|
|
178
|
+
if (captureImpl === void 0) throw aotActivationError();
|
|
180
179
|
return true;
|
|
181
180
|
}
|
|
182
181
|
if (isAotBuildEnv()) {
|
|
183
|
-
if (captureImpl === void 0) throw aotActivationError;
|
|
182
|
+
if (captureImpl === void 0) throw aotActivationError();
|
|
184
183
|
return true;
|
|
185
184
|
}
|
|
186
185
|
return false;
|
package/dist/compile/aot.mjs
CHANGED
|
@@ -35,9 +35,8 @@ function endCompilerSession(app, session, failed = false) {
|
|
|
35
35
|
}
|
|
36
36
|
const getCompilerSession = () => activeSession;
|
|
37
37
|
let reconstructImpl;
|
|
38
|
-
const reconstructActivationError = /* @__PURE__ */ new Error("Elysia AOT reconstruct module is not activated.");
|
|
39
38
|
function reconstruct() {
|
|
40
|
-
if (reconstructImpl === void 0) throw
|
|
39
|
+
if (reconstructImpl === void 0) throw new Error("Elysia AOT reconstruct module is not activated");
|
|
41
40
|
return reconstructImpl;
|
|
42
41
|
}
|
|
43
42
|
let registered;
|
|
@@ -160,7 +159,7 @@ function captureEntry({ method, path, slot }) {
|
|
|
160
159
|
return e;
|
|
161
160
|
}
|
|
162
161
|
/** @internal shared with `aot-capture.ts` (`beginValidatorCapture`). */
|
|
163
|
-
const aotActivationError = /* @__PURE__ */ new Error("Elysia AOT capture module is not activated.");
|
|
162
|
+
const aotActivationError = () => /* @__PURE__ */ new Error("Elysia AOT capture module is not activated.");
|
|
164
163
|
function captureHandler(v) {
|
|
165
164
|
if (!isValidatorCapturing()) return;
|
|
166
165
|
const session = activeSession;
|
|
@@ -175,11 +174,11 @@ const captureGet = (loc) => activeSession?.capture?.get(`${loc.method}_${loc.pat
|
|
|
175
174
|
const isAotBuildEnv = () => !!env.ELYSIA_AOT_BUILD;
|
|
176
175
|
const isValidatorCapturing = () => {
|
|
177
176
|
if (activeSession?.capture !== void 0) {
|
|
178
|
-
if (captureImpl === void 0) throw aotActivationError;
|
|
177
|
+
if (captureImpl === void 0) throw aotActivationError();
|
|
179
178
|
return true;
|
|
180
179
|
}
|
|
181
180
|
if (isAotBuildEnv()) {
|
|
182
|
-
if (captureImpl === void 0) throw aotActivationError;
|
|
181
|
+
if (captureImpl === void 0) throw aotActivationError();
|
|
183
182
|
return true;
|
|
184
183
|
}
|
|
185
184
|
return false;
|
|
@@ -4,7 +4,7 @@ import { AnyElysia } from "../../base.js";
|
|
|
4
4
|
|
|
5
5
|
//#region src/compile/handler/frozen-validator.d.ts
|
|
6
6
|
declare const isBridgeNotInitialized: (error: unknown) => boolean;
|
|
7
|
-
/** `{ check, clean?, decode? }`
|
|
7
|
+
/** `{ check, clean?, decode? }` the slot's compiled predicate + cleaner. */
|
|
8
8
|
interface SlotCheckClean {
|
|
9
9
|
check: (value: unknown) => boolean;
|
|
10
10
|
clean?: (value: unknown) => unknown;
|
|
@@ -200,10 +200,7 @@ var FrozenSlotValidator = class {
|
|
|
200
200
|
/**
|
|
201
201
|
* The JIT/frozen slot validator: the reconstruct-free `FrozenSlotValidator`
|
|
202
202
|
* base plus the codec/inner-codec branch re-added via the `buildCheckClean`
|
|
203
|
-
* override
|
|
204
|
-
* The only reorder — `this.hasCodec` is set by the base ctor before this runs,
|
|
205
|
-
* where the original set it after the `frozen.ic` side-effect — is unobservable
|
|
206
|
-
* (`reconstructInnerCodecs` neither reads nor sets `hasCodec`).
|
|
203
|
+
* override
|
|
207
204
|
*/
|
|
208
205
|
var CodecFrozenSlotValidator = class extends FrozenSlotValidator {
|
|
209
206
|
buildCheckClean(frozen, schema, raw, normalize) {
|
|
@@ -199,10 +199,7 @@ var FrozenSlotValidator = class {
|
|
|
199
199
|
/**
|
|
200
200
|
* The JIT/frozen slot validator: the reconstruct-free `FrozenSlotValidator`
|
|
201
201
|
* base plus the codec/inner-codec branch re-added via the `buildCheckClean`
|
|
202
|
-
* override
|
|
203
|
-
* The only reorder — `this.hasCodec` is set by the base ctor before this runs,
|
|
204
|
-
* where the original set it after the `frozen.ic` side-effect — is unobservable
|
|
205
|
-
* (`reconstructInnerCodecs` neither reads nor sets `hasCodec`).
|
|
202
|
+
* override
|
|
206
203
|
*/
|
|
207
204
|
var CodecFrozenSlotValidator = class extends FrozenSlotValidator {
|
|
208
205
|
buildCheckClean(frozen, schema, raw, normalize) {
|