elysia 2.0.0-rc.3 → 2.0.0-rc.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/utils.d.ts +8 -12
- package/dist/adapter/utils.js +88 -106
- package/dist/adapter/utils.mjs +88 -106
- package/dist/base.d.ts +2 -3
- package/dist/base.js +97 -194
- package/dist/base.mjs +95 -192
- package/dist/compile/aot-capture.js +24 -5
- package/dist/compile/aot-capture.mjs +24 -5
- package/dist/compile/aot-emit.js +6 -0
- package/dist/compile/aot-emit.mjs +6 -0
- package/dist/compile/aot.d.ts +43 -10
- package/dist/compile/aot.js +31 -25
- package/dist/compile/aot.mjs +29 -27
- package/dist/compile/handler/descriptor.d.ts +2 -0
- package/dist/compile/handler/descriptor.js +9 -3
- package/dist/compile/handler/descriptor.mjs +9 -3
- package/dist/compile/handler/frozen-validator.d.ts +1 -2
- package/dist/compile/handler/frozen-validator.js +0 -2
- package/dist/compile/handler/frozen-validator.mjs +1 -2
- package/dist/compile/handler/index.js +3 -5
- package/dist/compile/handler/index.mjs +3 -5
- package/dist/compile/handler/jit.d.ts +4 -2
- package/dist/compile/handler/jit.js +26 -18
- package/dist/compile/handler/jit.mjs +26 -19
- package/dist/compile/handler/param-resolvers.d.ts +3 -2
- package/dist/compile/handler/param-resolvers.js +2 -0
- package/dist/compile/handler/param-resolvers.mjs +3 -2
- package/dist/compile/handler/param-table.js +1 -0
- package/dist/compile/handler/param-table.mjs +2 -1
- package/dist/compile/handler/params.d.ts +1 -5
- package/dist/compile/handler/params.js +2 -3
- package/dist/compile/handler/params.mjs +2 -2
- package/dist/compile/handler/reconstruct.js +4 -4
- package/dist/compile/handler/reconstruct.mjs +3 -3
- package/dist/compile/handler/route-shape.d.ts +9 -1
- package/dist/compile/handler/route-shape.js +14 -2
- package/dist/compile/handler/route-shape.mjs +13 -4
- package/dist/compile/handler/utils.d.ts +4 -2
- package/dist/compile/handler/utils.js +19 -3
- package/dist/compile/handler/utils.mjs +19 -4
- package/dist/compile/utils.d.ts +3 -1
- package/dist/compile/utils.js +2 -0
- package/dist/compile/utils.mjs +2 -1
- package/dist/context.js +2 -0
- package/dist/context.mjs +2 -0
- package/dist/cookie/utils.js +37 -10
- package/dist/cookie/utils.mjs +37 -10
- package/dist/error.d.ts +11 -1
- package/dist/error.js +6 -1
- package/dist/error.mjs +6 -1
- package/dist/handler/error.js +4 -2
- package/dist/handler/error.mjs +4 -2
- package/dist/handler/fetch.js +91 -144
- package/dist/handler/fetch.mjs +93 -146
- package/dist/index.d.ts +2 -2
- package/dist/package.js +1 -1
- package/dist/package.mjs +1 -1
- package/dist/plugin/aot/core.d.ts +27 -15
- package/dist/plugin/aot/core.js +22 -17
- package/dist/plugin/aot/core.mjs +20 -16
- package/dist/plugin/aot/source.js +7 -1
- package/dist/plugin/aot/source.mjs +7 -1
- package/dist/plugin/trace.d.ts +1 -0
- package/dist/plugin/trace.js +3 -1
- package/dist/plugin/trace.mjs +4 -2
- package/dist/plugin/websocket.d.ts +1 -0
- package/dist/route-table.d.ts +0 -1
- package/dist/route-table.js +1 -2
- package/dist/route-table.mjs +1 -2
- package/dist/schema-snapshot.d.ts +7 -2
- package/dist/schema-snapshot.js +50 -16
- package/dist/schema-snapshot.mjs +51 -17
- package/dist/sucrose.d.ts +3 -2
- package/dist/sucrose.js +22 -6
- package/dist/sucrose.mjs +22 -6
- package/dist/trace.d.ts +31 -2
- package/dist/trace.js +84 -0
- package/dist/trace.mjs +83 -1
- package/dist/type/bridge-live.d.ts +1 -1
- package/dist/type/bridge-live.js +1 -1
- package/dist/type/bridge-live.mjs +1 -1
- package/dist/type/bridge.d.ts +1 -1
- package/dist/type/coerce.d.ts +1 -1
- package/dist/type/constants.d.ts +1 -1
- package/dist/type/typebox-value-live.d.ts +2 -2
- package/dist/type/typebox-value-live.js +2 -2
- package/dist/type/typebox-value-live.mjs +2 -2
- package/dist/type/typebox-value-ops.d.ts +2 -2
- package/dist/type/typebox-value-ops.js +2 -2
- package/dist/type/typebox-value-ops.mjs +2 -2
- package/dist/type/typebox-value-require.js +9 -8
- package/dist/type/typebox-value-require.mjs +9 -8
- package/dist/type/typebox-value.d.ts +6 -6
- package/dist/type/validator/custom-error.d.ts +18 -3
- package/dist/type/validator/custom-error.js +1 -18
- package/dist/type/validator/custom-error.mjs +2 -19
- package/dist/type/validator/frozen-check.d.ts +3 -2
- package/dist/type/validator/frozen-check.js +20 -1
- package/dist/type/validator/frozen-check.mjs +19 -1
- package/dist/type/validator/string-codec-aot.js +1 -1
- package/dist/type/validator/string-codec-aot.mjs +1 -1
- package/dist/types.d.ts +6 -8
- package/dist/utils.d.ts +3 -9
- package/dist/utils.js +20 -54
- package/dist/utils.mjs +21 -54
- package/dist/validator/index.js +2 -3
- package/dist/validator/index.mjs +1 -2
- package/dist/ws/context.d.ts +1 -1
- package/dist/ws/context.js +2 -10
- package/dist/ws/context.mjs +3 -11
- package/dist/ws/route.js +41 -28
- package/dist/ws/route.mjs +44 -31
- package/package.json +7 -1
- package/src/adapter/utils.ts +124 -138
- package/src/base.ts +165 -383
- package/src/compile/aot-capture.ts +29 -2
- package/src/compile/aot-emit.ts +6 -1
- package/src/compile/aot.ts +92 -32
- package/src/compile/handler/descriptor.ts +30 -6
- package/src/compile/handler/frozen-validator.ts +0 -4
- package/src/compile/handler/index.ts +10 -5
- package/src/compile/handler/jit.ts +67 -20
- package/src/compile/handler/param-resolvers.ts +2 -0
- package/src/compile/handler/param-table.ts +2 -0
- package/src/compile/handler/params.ts +1 -5
- package/src/compile/handler/reconstruct.ts +3 -6
- package/src/compile/handler/route-shape.ts +26 -2
- package/src/compile/handler/utils.ts +21 -5
- package/src/compile/utils.ts +4 -0
- package/src/context.ts +7 -1
- package/src/cookie/utils.ts +53 -16
- package/src/error.ts +27 -2
- package/src/handler/error.ts +11 -3
- package/src/handler/fetch.ts +209 -276
- package/src/plugin/aot/core.ts +83 -33
- package/src/plugin/aot/source.ts +17 -2
- package/src/plugin/trace.ts +9 -2
- package/src/route-table.ts +1 -2
- package/src/schema-snapshot.ts +101 -20
- package/src/sucrose.ts +44 -13
- package/src/trace.ts +185 -1
- package/src/type/typebox-value-require.ts +11 -7
- package/src/type/validator/custom-error.ts +2 -33
- package/src/type/validator/frozen-check.ts +31 -1
- package/src/types.ts +5 -8
- package/src/utils.ts +29 -83
- package/src/validator/index.ts +1 -4
- package/src/ws/context.ts +5 -13
- package/src/ws/route.ts +73 -54
package/dist/adapter/utils.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { BaseCookie } from "../cookie/types.js";
|
|
|
3
3
|
import { Context } from "../context.js";
|
|
4
4
|
import { ElysiaFile } from "../universal/file.js";
|
|
5
5
|
import { HTTPHeaders } from "../types.js";
|
|
6
|
+
|
|
6
7
|
//#region src/adapter/utils.d.ts
|
|
7
8
|
declare const hget: (h: Headers | Record<string, unknown>, k: string) => unknown;
|
|
8
9
|
declare function hput(h: Headers | Record<string, unknown>, k: string, v: unknown, soft?: 1): void;
|
|
@@ -17,7 +18,7 @@ declare function responseToSetHeaders(response: Response, set?: Context['set']):
|
|
|
17
18
|
redirect?: never;
|
|
18
19
|
} | {
|
|
19
20
|
headers: any;
|
|
20
|
-
status: number | "Continue" | "Switching Protocols" | "Processing" | "Early Hints" | "OK" | "Created" | "Accepted" | "Non-Authoritative Information" | "No Content" | "Reset Content" | "Partial Content" | "Multi-Status" | "Already Reported" | "Multiple Choices" | "Moved Permanently" | "Found" | "See Other" | "Not Modified" | "Temporary Redirect" | "Permanent Redirect" | "Bad Request" | "Unauthorized" | "Payment Required" | "Forbidden" | "
|
|
21
|
+
status: number | "Not Found" | "Continue" | "Switching Protocols" | "Processing" | "Early Hints" | "OK" | "Created" | "Accepted" | "Non-Authoritative Information" | "No Content" | "Reset Content" | "Partial Content" | "Multi-Status" | "Already Reported" | "Multiple Choices" | "Moved Permanently" | "Found" | "See Other" | "Not Modified" | "Temporary Redirect" | "Permanent Redirect" | "Bad Request" | "Unauthorized" | "Payment Required" | "Forbidden" | "Method Not Allowed" | "Not Acceptable" | "Proxy Authentication Required" | "Request Timeout" | "Conflict" | "Gone" | "Length Required" | "Precondition Failed" | "Payload Too Large" | "URI Too Long" | "Unsupported Media Type" | "Range Not Satisfiable" | "Expectation Failed" | "I'm a teapot" | "Enhance Your Calm" | "Misdirected Request" | "Unprocessable Content" | "Locked" | "Failed Dependency" | "Too Early" | "Upgrade Required" | "Precondition Required" | "Too Many Requests" | "Request Header Fields Too Large" | "Unavailable For Legal Reasons" | "Internal Server Error" | "Not Implemented" | "Bad Gateway" | "Service Unavailable" | "Gateway Timeout" | "HTTP Version Not Supported" | "Variant Also Negotiates" | "Insufficient Storage" | "Loop Detected" | "Not Extended" | "Network Authentication Required";
|
|
21
22
|
};
|
|
22
23
|
interface CreateHandlerParameter {
|
|
23
24
|
mapResponse(response: unknown, set: Context['set'], request?: Request, owned?: boolean): Response;
|
|
@@ -38,23 +39,18 @@ declare function createResponseHandler(): (response: Response, set?: Context["se
|
|
|
38
39
|
*/
|
|
39
40
|
declare function observeStream(source: ReadableStream): [ReadableStream, AsyncIterable<unknown>, AsyncIterableIterator<unknown>] | undefined;
|
|
40
41
|
/**
|
|
41
|
-
* Split async source into
|
|
42
|
+
* Split async source into a value iterator and a completion iterator
|
|
42
43
|
*
|
|
43
|
-
* A producer drains the source ahead of
|
|
44
|
+
* A producer drains the source ahead of the value consumer (response/client)
|
|
44
45
|
*
|
|
45
46
|
* To prevent long/infinite stream, the unconsumed window is capped:
|
|
46
|
-
* Consumed-by-every-branch entries are trimmed off the front
|
|
47
47
|
* Producer backpressures whenever the window hits `cap` ENTRIES or
|
|
48
48
|
* `capBytes` bytes, whichever comes first
|
|
49
49
|
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
* Branch 0 is the value consumer (response/client)
|
|
54
|
-
* When `return()` (client abort / early exit), source is stopped
|
|
55
|
-
* so the observer branches can still reach completion instead of spinning
|
|
56
|
-
* an infinite source
|
|
50
|
+
* The second iterator yields nothing: it settles once the source ends
|
|
51
|
+
* (rejects with its error) or the value iterator returns, which stops
|
|
52
|
+
* the source so an infinite one can't keep afterResponse waiting
|
|
57
53
|
*/
|
|
58
|
-
declare function tee<T>(source: AsyncIterable<T>,
|
|
54
|
+
declare function tee<T>(source: AsyncIterable<T>, cap?: number, capBytes?: number): AsyncIterableIterator<T>[];
|
|
59
55
|
//#endregion
|
|
60
56
|
export { createResponseHandler, createStreamHandler, handleFile, handleSet, hget, hput, materializeSetHeaders, normalizeContentType, observeStream, parseSetCookies, responseToSetHeaders, streamResponse, tee };
|
package/dist/adapter/utils.js
CHANGED
|
@@ -3,6 +3,7 @@ const require_universal_constants = require('../universal/constants.js');
|
|
|
3
3
|
const require_constants = require('../constants.js');
|
|
4
4
|
const require_utils = require('../utils.js');
|
|
5
5
|
const require_adapter_skip_clone = require('./skip-clone.js');
|
|
6
|
+
const require_error = require('../error.js');
|
|
6
7
|
const require_cookie_serialize = require('../cookie/serialize.js');
|
|
7
8
|
const require_adapter_response_ownership = require('./response-ownership.js');
|
|
8
9
|
const require_adapter_default_headers = require('./default-headers.js');
|
|
@@ -147,8 +148,8 @@ function createStreamHandler({ mapResponse, mapCompactResponse }) {
|
|
|
147
148
|
}
|
|
148
149
|
return new Response(generator, { headers: { "content-type": "application/octet-stream" } });
|
|
149
150
|
}
|
|
150
|
-
const
|
|
151
|
-
if (
|
|
151
|
+
const pickChunk = set?.["~chunk"];
|
|
152
|
+
if (pickChunk) set["~chunk"] = void 0;
|
|
152
153
|
const typedSSE = !skipFormat && "sse" in generator && generator.sse === true;
|
|
153
154
|
const sourceIterator = typeof generator.next === "function" ? generator : void 0;
|
|
154
155
|
let init = typedSSE ? void 0 : generator.next?.();
|
|
@@ -166,8 +167,23 @@ function createStreamHandler({ mapResponse, mapCompactResponse }) {
|
|
|
166
167
|
const yieldedStream = init?.value instanceof ReadableStream;
|
|
167
168
|
if (yieldedStream) generator = init.value;
|
|
168
169
|
else if (init && (typeof init?.done === "undefined" || init?.done)) {
|
|
169
|
-
|
|
170
|
-
|
|
170
|
+
let value = init.value;
|
|
171
|
+
if (pickChunk) {
|
|
172
|
+
if (value instanceof Promise || typeof value?.then === "function") value = await value;
|
|
173
|
+
const wrapped = value instanceof require_error.ElysiaStatus;
|
|
174
|
+
const validator = pickChunk(wrapped ? value.status : set?.status ?? 200);
|
|
175
|
+
if (validator) {
|
|
176
|
+
let body = wrapped ? value.response : value;
|
|
177
|
+
if (body instanceof Promise || typeof body?.then === "function") body = await body;
|
|
178
|
+
if (typeof body?.next === "function") {
|
|
179
|
+
if (set) set["~chunk"] = pickChunk;
|
|
180
|
+
} else if (!(body instanceof Error) && !(body instanceof Response) && !(body instanceof ReadableStream)) body = await (validator.mayReturnPromise ? validator.From(body, "response", true) : validator.EncodeFrom(body, "response"));
|
|
181
|
+
if (wrapped) value.response = body;
|
|
182
|
+
else value = body;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
if (set) return mapResponse(value, set, request, owned);
|
|
186
|
+
return mapCompactResponse(value, request, owned);
|
|
171
187
|
}
|
|
172
188
|
const isSSE = typedSSE || !skipFormat && (init?.value?.sse ?? generator?.sse ?? (set && hget(set.headers, "content-type")?.startsWith("text/event-stream")));
|
|
173
189
|
const format = isSSE ? sseFormat : identityFormat;
|
|
@@ -246,14 +262,10 @@ function createStreamHandler({ mapResponse, mapCompactResponse }) {
|
|
|
246
262
|
controller.enqueue(new Uint8Array(value.buffer, value.byteOffset, value.byteLength));
|
|
247
263
|
return;
|
|
248
264
|
}
|
|
249
|
-
if (typeof value === "object")
|
|
250
|
-
controller.enqueue(textEncoder.encode(format(JSON.stringify(value))));
|
|
251
|
-
} catch {
|
|
252
|
-
controller.enqueue(textEncoder.encode(format(value.toString())));
|
|
253
|
-
}
|
|
265
|
+
if (typeof value === "object") controller.enqueue(textEncoder.encode(format(JSON.stringify(value))));
|
|
254
266
|
else controller.enqueue(textEncoder.encode(format(value.toString())));
|
|
255
267
|
};
|
|
256
|
-
const validator = sourceStream ? void 0 :
|
|
268
|
+
const validator = sourceStream ? void 0 : pickChunk?.(set.status ?? 200);
|
|
257
269
|
const enqueueChunk = validator?.Clean || validator?.mayReturnPromise ? (controller, value) => {
|
|
258
270
|
const cleaned = cleanChunk(validator, value, typedSSE);
|
|
259
271
|
return cleaned instanceof Promise && cleaned !== value ? cleaned.then((value) => enqueueValue(controller, value)) : enqueueValue(controller, cleaned);
|
|
@@ -443,20 +455,23 @@ function observeStream(source) {
|
|
|
443
455
|
value
|
|
444
456
|
];
|
|
445
457
|
}
|
|
446
|
-
function tee(source,
|
|
458
|
+
function tee(source, cap = 64, capBytes = 1 << 22) {
|
|
447
459
|
const iterator = source[Symbol.asyncIterator]?.() ?? source[Symbol.iterator]();
|
|
448
460
|
const buffer = [];
|
|
449
461
|
const sizes = [];
|
|
450
|
-
let base = 0;
|
|
451
462
|
let windowBytes = 0;
|
|
452
463
|
let done = false;
|
|
453
464
|
let stopped = false;
|
|
454
465
|
let failed = false;
|
|
455
466
|
let sourceError;
|
|
456
467
|
let drainResume = null;
|
|
457
|
-
|
|
458
|
-
let
|
|
459
|
-
const
|
|
468
|
+
let pending = null;
|
|
469
|
+
let finish;
|
|
470
|
+
const completed = new Promise((resolve, reject) => finish = {
|
|
471
|
+
resolve,
|
|
472
|
+
reject
|
|
473
|
+
});
|
|
474
|
+
completed.catch(() => {});
|
|
460
475
|
const resumeProducer = () => {
|
|
461
476
|
if (drainResume) {
|
|
462
477
|
const resume = drainResume;
|
|
@@ -464,135 +479,102 @@ function tee(source, branches = 2, cap = 64, capBytes = 1 << 22) {
|
|
|
464
479
|
resume();
|
|
465
480
|
}
|
|
466
481
|
};
|
|
467
|
-
const
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
}
|
|
480
|
-
}
|
|
481
|
-
if (buffer.length < cap && windowBytes < capBytes) resumeProducer();
|
|
482
|
-
};
|
|
483
|
-
const closeBranch = (me) => {
|
|
484
|
-
if (cursors[me] === Infinity) return;
|
|
485
|
-
cursors[me] = Infinity;
|
|
486
|
-
active--;
|
|
487
|
-
if (me === 0 && !stopped) {
|
|
488
|
-
stopped = true;
|
|
489
|
-
done = true;
|
|
490
|
-
resumeProducer();
|
|
491
|
-
try {
|
|
492
|
-
const r = iterator.return?.();
|
|
493
|
-
if (r && typeof r.then === "function") r.catch(() => {});
|
|
494
|
-
} catch {}
|
|
495
|
-
wakeAll();
|
|
496
|
-
}
|
|
497
|
-
if (active === 0) {
|
|
498
|
-
buffer.length = 0;
|
|
499
|
-
sizes.length = 0;
|
|
500
|
-
windowBytes = 0;
|
|
501
|
-
} else trim();
|
|
502
|
-
};
|
|
503
|
-
const serve = (me, p) => {
|
|
504
|
-
const i = cursors[me];
|
|
505
|
-
if (i === Infinity) return p.resolve(doneResult);
|
|
506
|
-
if (i < base + buffer.length) {
|
|
507
|
-
const value = buffer[i - base];
|
|
508
|
-
cursors[me] = i + 1;
|
|
509
|
-
trim();
|
|
510
|
-
return p.resolve({
|
|
511
|
-
done: false,
|
|
512
|
-
value
|
|
513
|
-
});
|
|
514
|
-
}
|
|
515
|
-
if (failed) return p.reject(sourceError);
|
|
516
|
-
if (done) {
|
|
517
|
-
closeBranch(me);
|
|
518
|
-
return p.resolve(doneResult);
|
|
519
|
-
}
|
|
520
|
-
pending[me] = p;
|
|
521
|
-
};
|
|
522
|
-
const wakeAll = () => {
|
|
523
|
-
for (let b = 0; b < branches; b++) {
|
|
524
|
-
const p = pending[b];
|
|
525
|
-
if (!p) continue;
|
|
526
|
-
pending[b] = null;
|
|
527
|
-
serve(b, p);
|
|
528
|
-
}
|
|
482
|
+
const stop = (p) => {
|
|
483
|
+
pending = null;
|
|
484
|
+
p?.resolve(doneResult);
|
|
485
|
+
if (stopped) return;
|
|
486
|
+
stopped = done = true;
|
|
487
|
+
buffer.length = sizes.length = windowBytes = 0;
|
|
488
|
+
resumeProducer();
|
|
489
|
+
try {
|
|
490
|
+
const r = iterator.return?.();
|
|
491
|
+
if (r && typeof r.then === "function") r.catch(() => {});
|
|
492
|
+
} catch {}
|
|
493
|
+
finish.resolve(doneResult);
|
|
529
494
|
};
|
|
530
495
|
(async () => {
|
|
531
496
|
try {
|
|
532
497
|
while (!stopped) {
|
|
533
498
|
const result = await iterator.next();
|
|
534
499
|
if (result.done || stopped) break;
|
|
500
|
+
const p = pending;
|
|
501
|
+
if (p) {
|
|
502
|
+
pending = null;
|
|
503
|
+
p.resolve({
|
|
504
|
+
done: false,
|
|
505
|
+
value: result.value
|
|
506
|
+
});
|
|
507
|
+
continue;
|
|
508
|
+
}
|
|
535
509
|
buffer.push(result.value);
|
|
536
510
|
sizes.push(teeChunkCost(result.value));
|
|
537
511
|
windowBytes += sizes[sizes.length - 1];
|
|
538
|
-
|
|
539
|
-
if ((buffer.length >= cap || windowBytes >= capBytes) && active > 0 && !stopped) await new Promise((resolve) => {
|
|
512
|
+
if ((buffer.length >= cap || windowBytes >= capBytes) && !stopped) await new Promise((resolve) => {
|
|
540
513
|
drainResume = resolve;
|
|
541
514
|
});
|
|
542
515
|
}
|
|
543
516
|
} catch (error) {
|
|
544
|
-
failed =
|
|
517
|
+
failed = !stopped;
|
|
545
518
|
sourceError = error;
|
|
546
519
|
} finally {
|
|
547
520
|
done = true;
|
|
548
|
-
|
|
521
|
+
const p = pending;
|
|
522
|
+
pending = null;
|
|
523
|
+
if (failed) {
|
|
524
|
+
p?.reject(sourceError);
|
|
525
|
+
finish.reject(sourceError);
|
|
526
|
+
} else {
|
|
527
|
+
p?.resolve(doneResult);
|
|
528
|
+
finish.resolve(doneResult);
|
|
529
|
+
}
|
|
549
530
|
}
|
|
550
531
|
})();
|
|
551
|
-
const
|
|
532
|
+
const value = Object.assign(Object.create(null), {
|
|
552
533
|
[Symbol.asyncIterator]() {
|
|
553
534
|
return this;
|
|
554
535
|
},
|
|
555
536
|
next: () => {
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
trim();
|
|
537
|
+
if (buffer.length) {
|
|
538
|
+
const value = buffer.shift();
|
|
539
|
+
windowBytes -= sizes.shift();
|
|
540
|
+
if (buffer.length < cap && windowBytes < capBytes) resumeProducer();
|
|
561
541
|
return Promise.resolve({
|
|
562
542
|
done: false,
|
|
563
543
|
value
|
|
564
544
|
});
|
|
565
545
|
}
|
|
566
|
-
|
|
546
|
+
if (failed) return Promise.reject(sourceError);
|
|
547
|
+
if (done) return Promise.resolve(doneResult);
|
|
548
|
+
return new Promise((resolve, reject) => pending = {
|
|
567
549
|
resolve,
|
|
568
550
|
reject
|
|
569
|
-
})
|
|
551
|
+
});
|
|
570
552
|
},
|
|
571
|
-
return: (
|
|
572
|
-
|
|
573
|
-
if (p) {
|
|
574
|
-
pending[me] = null;
|
|
575
|
-
p.resolve(doneResult);
|
|
576
|
-
}
|
|
577
|
-
closeBranch(me);
|
|
553
|
+
return: (result) => {
|
|
554
|
+
stop(pending);
|
|
578
555
|
return Promise.resolve({
|
|
579
556
|
done: true,
|
|
580
|
-
value
|
|
557
|
+
value: result
|
|
581
558
|
});
|
|
582
559
|
},
|
|
583
560
|
throw: (error) => {
|
|
584
|
-
|
|
585
|
-
if (p) {
|
|
586
|
-
pending[me] = null;
|
|
587
|
-
p.resolve(doneResult);
|
|
588
|
-
}
|
|
589
|
-
closeBranch(me);
|
|
561
|
+
stop(pending);
|
|
590
562
|
return Promise.reject(error);
|
|
591
563
|
}
|
|
592
564
|
});
|
|
593
|
-
const
|
|
594
|
-
|
|
595
|
-
|
|
565
|
+
const observer = Object.assign(Object.create(null), {
|
|
566
|
+
[Symbol.asyncIterator]() {
|
|
567
|
+
return this;
|
|
568
|
+
},
|
|
569
|
+
next: () => completed,
|
|
570
|
+
return: (result) => Promise.resolve({
|
|
571
|
+
done: true,
|
|
572
|
+
value: result
|
|
573
|
+
}),
|
|
574
|
+
throw: (error) => Promise.reject(error)
|
|
575
|
+
});
|
|
576
|
+
if (source.sse === true) value.sse = true;
|
|
577
|
+
return [value, observer];
|
|
596
578
|
}
|
|
597
579
|
|
|
598
580
|
//#endregion
|
package/dist/adapter/utils.mjs
CHANGED
|
@@ -3,6 +3,7 @@ import { hasHeaderShorthand } from "../universal/constants.mjs";
|
|
|
3
3
|
import { StatusMap } from "../constants.mjs";
|
|
4
4
|
import { EmptyObject, isByteStream, isNotEmpty, sseData } from "../utils.mjs";
|
|
5
5
|
import { skipClone } from "./skip-clone.mjs";
|
|
6
|
+
import { ElysiaStatus } from "../error.mjs";
|
|
6
7
|
import { serializeCookie } from "../cookie/serialize.mjs";
|
|
7
8
|
import { isBorrowedResponse } from "./response-ownership.mjs";
|
|
8
9
|
import { defaultHeaders } from "./default-headers.mjs";
|
|
@@ -147,8 +148,8 @@ function createStreamHandler({ mapResponse, mapCompactResponse }) {
|
|
|
147
148
|
}
|
|
148
149
|
return new Response(generator, { headers: { "content-type": "application/octet-stream" } });
|
|
149
150
|
}
|
|
150
|
-
const
|
|
151
|
-
if (
|
|
151
|
+
const pickChunk = set?.["~chunk"];
|
|
152
|
+
if (pickChunk) set["~chunk"] = void 0;
|
|
152
153
|
const typedSSE = !skipFormat && "sse" in generator && generator.sse === true;
|
|
153
154
|
const sourceIterator = typeof generator.next === "function" ? generator : void 0;
|
|
154
155
|
let init = typedSSE ? void 0 : generator.next?.();
|
|
@@ -166,8 +167,23 @@ function createStreamHandler({ mapResponse, mapCompactResponse }) {
|
|
|
166
167
|
const yieldedStream = init?.value instanceof ReadableStream;
|
|
167
168
|
if (yieldedStream) generator = init.value;
|
|
168
169
|
else if (init && (typeof init?.done === "undefined" || init?.done)) {
|
|
169
|
-
|
|
170
|
-
|
|
170
|
+
let value = init.value;
|
|
171
|
+
if (pickChunk) {
|
|
172
|
+
if (value instanceof Promise || typeof value?.then === "function") value = await value;
|
|
173
|
+
const wrapped = value instanceof ElysiaStatus;
|
|
174
|
+
const validator = pickChunk(wrapped ? value.status : set?.status ?? 200);
|
|
175
|
+
if (validator) {
|
|
176
|
+
let body = wrapped ? value.response : value;
|
|
177
|
+
if (body instanceof Promise || typeof body?.then === "function") body = await body;
|
|
178
|
+
if (typeof body?.next === "function") {
|
|
179
|
+
if (set) set["~chunk"] = pickChunk;
|
|
180
|
+
} else if (!(body instanceof Error) && !(body instanceof Response) && !(body instanceof ReadableStream)) body = await (validator.mayReturnPromise ? validator.From(body, "response", true) : validator.EncodeFrom(body, "response"));
|
|
181
|
+
if (wrapped) value.response = body;
|
|
182
|
+
else value = body;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
if (set) return mapResponse(value, set, request, owned);
|
|
186
|
+
return mapCompactResponse(value, request, owned);
|
|
171
187
|
}
|
|
172
188
|
const isSSE = typedSSE || !skipFormat && (init?.value?.sse ?? generator?.sse ?? (set && hget(set.headers, "content-type")?.startsWith("text/event-stream")));
|
|
173
189
|
const format = isSSE ? sseFormat : identityFormat;
|
|
@@ -246,14 +262,10 @@ function createStreamHandler({ mapResponse, mapCompactResponse }) {
|
|
|
246
262
|
controller.enqueue(new Uint8Array(value.buffer, value.byteOffset, value.byteLength));
|
|
247
263
|
return;
|
|
248
264
|
}
|
|
249
|
-
if (typeof value === "object")
|
|
250
|
-
controller.enqueue(textEncoder.encode(format(JSON.stringify(value))));
|
|
251
|
-
} catch {
|
|
252
|
-
controller.enqueue(textEncoder.encode(format(value.toString())));
|
|
253
|
-
}
|
|
265
|
+
if (typeof value === "object") controller.enqueue(textEncoder.encode(format(JSON.stringify(value))));
|
|
254
266
|
else controller.enqueue(textEncoder.encode(format(value.toString())));
|
|
255
267
|
};
|
|
256
|
-
const validator = sourceStream ? void 0 :
|
|
268
|
+
const validator = sourceStream ? void 0 : pickChunk?.(set.status ?? 200);
|
|
257
269
|
const enqueueChunk = validator?.Clean || validator?.mayReturnPromise ? (controller, value) => {
|
|
258
270
|
const cleaned = cleanChunk(validator, value, typedSSE);
|
|
259
271
|
return cleaned instanceof Promise && cleaned !== value ? cleaned.then((value) => enqueueValue(controller, value)) : enqueueValue(controller, cleaned);
|
|
@@ -443,20 +455,23 @@ function observeStream(source) {
|
|
|
443
455
|
value
|
|
444
456
|
];
|
|
445
457
|
}
|
|
446
|
-
function tee(source,
|
|
458
|
+
function tee(source, cap = 64, capBytes = 1 << 22) {
|
|
447
459
|
const iterator = source[Symbol.asyncIterator]?.() ?? source[Symbol.iterator]();
|
|
448
460
|
const buffer = [];
|
|
449
461
|
const sizes = [];
|
|
450
|
-
let base = 0;
|
|
451
462
|
let windowBytes = 0;
|
|
452
463
|
let done = false;
|
|
453
464
|
let stopped = false;
|
|
454
465
|
let failed = false;
|
|
455
466
|
let sourceError;
|
|
456
467
|
let drainResume = null;
|
|
457
|
-
|
|
458
|
-
let
|
|
459
|
-
const
|
|
468
|
+
let pending = null;
|
|
469
|
+
let finish;
|
|
470
|
+
const completed = new Promise((resolve, reject) => finish = {
|
|
471
|
+
resolve,
|
|
472
|
+
reject
|
|
473
|
+
});
|
|
474
|
+
completed.catch(() => {});
|
|
460
475
|
const resumeProducer = () => {
|
|
461
476
|
if (drainResume) {
|
|
462
477
|
const resume = drainResume;
|
|
@@ -464,135 +479,102 @@ function tee(source, branches = 2, cap = 64, capBytes = 1 << 22) {
|
|
|
464
479
|
resume();
|
|
465
480
|
}
|
|
466
481
|
};
|
|
467
|
-
const
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
}
|
|
480
|
-
}
|
|
481
|
-
if (buffer.length < cap && windowBytes < capBytes) resumeProducer();
|
|
482
|
-
};
|
|
483
|
-
const closeBranch = (me) => {
|
|
484
|
-
if (cursors[me] === Infinity) return;
|
|
485
|
-
cursors[me] = Infinity;
|
|
486
|
-
active--;
|
|
487
|
-
if (me === 0 && !stopped) {
|
|
488
|
-
stopped = true;
|
|
489
|
-
done = true;
|
|
490
|
-
resumeProducer();
|
|
491
|
-
try {
|
|
492
|
-
const r = iterator.return?.();
|
|
493
|
-
if (r && typeof r.then === "function") r.catch(() => {});
|
|
494
|
-
} catch {}
|
|
495
|
-
wakeAll();
|
|
496
|
-
}
|
|
497
|
-
if (active === 0) {
|
|
498
|
-
buffer.length = 0;
|
|
499
|
-
sizes.length = 0;
|
|
500
|
-
windowBytes = 0;
|
|
501
|
-
} else trim();
|
|
502
|
-
};
|
|
503
|
-
const serve = (me, p) => {
|
|
504
|
-
const i = cursors[me];
|
|
505
|
-
if (i === Infinity) return p.resolve(doneResult);
|
|
506
|
-
if (i < base + buffer.length) {
|
|
507
|
-
const value = buffer[i - base];
|
|
508
|
-
cursors[me] = i + 1;
|
|
509
|
-
trim();
|
|
510
|
-
return p.resolve({
|
|
511
|
-
done: false,
|
|
512
|
-
value
|
|
513
|
-
});
|
|
514
|
-
}
|
|
515
|
-
if (failed) return p.reject(sourceError);
|
|
516
|
-
if (done) {
|
|
517
|
-
closeBranch(me);
|
|
518
|
-
return p.resolve(doneResult);
|
|
519
|
-
}
|
|
520
|
-
pending[me] = p;
|
|
521
|
-
};
|
|
522
|
-
const wakeAll = () => {
|
|
523
|
-
for (let b = 0; b < branches; b++) {
|
|
524
|
-
const p = pending[b];
|
|
525
|
-
if (!p) continue;
|
|
526
|
-
pending[b] = null;
|
|
527
|
-
serve(b, p);
|
|
528
|
-
}
|
|
482
|
+
const stop = (p) => {
|
|
483
|
+
pending = null;
|
|
484
|
+
p?.resolve(doneResult);
|
|
485
|
+
if (stopped) return;
|
|
486
|
+
stopped = done = true;
|
|
487
|
+
buffer.length = sizes.length = windowBytes = 0;
|
|
488
|
+
resumeProducer();
|
|
489
|
+
try {
|
|
490
|
+
const r = iterator.return?.();
|
|
491
|
+
if (r && typeof r.then === "function") r.catch(() => {});
|
|
492
|
+
} catch {}
|
|
493
|
+
finish.resolve(doneResult);
|
|
529
494
|
};
|
|
530
495
|
(async () => {
|
|
531
496
|
try {
|
|
532
497
|
while (!stopped) {
|
|
533
498
|
const result = await iterator.next();
|
|
534
499
|
if (result.done || stopped) break;
|
|
500
|
+
const p = pending;
|
|
501
|
+
if (p) {
|
|
502
|
+
pending = null;
|
|
503
|
+
p.resolve({
|
|
504
|
+
done: false,
|
|
505
|
+
value: result.value
|
|
506
|
+
});
|
|
507
|
+
continue;
|
|
508
|
+
}
|
|
535
509
|
buffer.push(result.value);
|
|
536
510
|
sizes.push(teeChunkCost(result.value));
|
|
537
511
|
windowBytes += sizes[sizes.length - 1];
|
|
538
|
-
|
|
539
|
-
if ((buffer.length >= cap || windowBytes >= capBytes) && active > 0 && !stopped) await new Promise((resolve) => {
|
|
512
|
+
if ((buffer.length >= cap || windowBytes >= capBytes) && !stopped) await new Promise((resolve) => {
|
|
540
513
|
drainResume = resolve;
|
|
541
514
|
});
|
|
542
515
|
}
|
|
543
516
|
} catch (error) {
|
|
544
|
-
failed =
|
|
517
|
+
failed = !stopped;
|
|
545
518
|
sourceError = error;
|
|
546
519
|
} finally {
|
|
547
520
|
done = true;
|
|
548
|
-
|
|
521
|
+
const p = pending;
|
|
522
|
+
pending = null;
|
|
523
|
+
if (failed) {
|
|
524
|
+
p?.reject(sourceError);
|
|
525
|
+
finish.reject(sourceError);
|
|
526
|
+
} else {
|
|
527
|
+
p?.resolve(doneResult);
|
|
528
|
+
finish.resolve(doneResult);
|
|
529
|
+
}
|
|
549
530
|
}
|
|
550
531
|
})();
|
|
551
|
-
const
|
|
532
|
+
const value = Object.assign(Object.create(null), {
|
|
552
533
|
[Symbol.asyncIterator]() {
|
|
553
534
|
return this;
|
|
554
535
|
},
|
|
555
536
|
next: () => {
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
trim();
|
|
537
|
+
if (buffer.length) {
|
|
538
|
+
const value = buffer.shift();
|
|
539
|
+
windowBytes -= sizes.shift();
|
|
540
|
+
if (buffer.length < cap && windowBytes < capBytes) resumeProducer();
|
|
561
541
|
return Promise.resolve({
|
|
562
542
|
done: false,
|
|
563
543
|
value
|
|
564
544
|
});
|
|
565
545
|
}
|
|
566
|
-
|
|
546
|
+
if (failed) return Promise.reject(sourceError);
|
|
547
|
+
if (done) return Promise.resolve(doneResult);
|
|
548
|
+
return new Promise((resolve, reject) => pending = {
|
|
567
549
|
resolve,
|
|
568
550
|
reject
|
|
569
|
-
})
|
|
551
|
+
});
|
|
570
552
|
},
|
|
571
|
-
return: (
|
|
572
|
-
|
|
573
|
-
if (p) {
|
|
574
|
-
pending[me] = null;
|
|
575
|
-
p.resolve(doneResult);
|
|
576
|
-
}
|
|
577
|
-
closeBranch(me);
|
|
553
|
+
return: (result) => {
|
|
554
|
+
stop(pending);
|
|
578
555
|
return Promise.resolve({
|
|
579
556
|
done: true,
|
|
580
|
-
value
|
|
557
|
+
value: result
|
|
581
558
|
});
|
|
582
559
|
},
|
|
583
560
|
throw: (error) => {
|
|
584
|
-
|
|
585
|
-
if (p) {
|
|
586
|
-
pending[me] = null;
|
|
587
|
-
p.resolve(doneResult);
|
|
588
|
-
}
|
|
589
|
-
closeBranch(me);
|
|
561
|
+
stop(pending);
|
|
590
562
|
return Promise.reject(error);
|
|
591
563
|
}
|
|
592
564
|
});
|
|
593
|
-
const
|
|
594
|
-
|
|
595
|
-
|
|
565
|
+
const observer = Object.assign(Object.create(null), {
|
|
566
|
+
[Symbol.asyncIterator]() {
|
|
567
|
+
return this;
|
|
568
|
+
},
|
|
569
|
+
next: () => completed,
|
|
570
|
+
return: (result) => Promise.resolve({
|
|
571
|
+
done: true,
|
|
572
|
+
value: result
|
|
573
|
+
}),
|
|
574
|
+
throw: (error) => Promise.reject(error)
|
|
575
|
+
});
|
|
576
|
+
if (source.sse === true) value.sse = true;
|
|
577
|
+
return [value, observer];
|
|
596
578
|
}
|
|
597
579
|
|
|
598
580
|
//#endregion
|
package/dist/base.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { Context, ErrorContext, LifecycleContext } from "./context.js";
|
|
|
5
5
|
import { TraceCapability, TraceHandler } from "./trace.js";
|
|
6
6
|
import { AnySchema } from "./type/types.js";
|
|
7
7
|
import { AotFingerprint, CompilerSession, ProgramId } from "./compile/aot.js";
|
|
8
|
-
import { AddRoute, AddWSRoute, AfterHandler, AfterResponseHandler, AnyErrorConstructor, AnyLocalHook, BodyHandler, CatchAllEntries, CatchAllHookReturn, CompiledHandler, CreateEden, DefaultEphemeral, DefaultMetadata, DefaultSingleton, DefinitionBase, DeriveResponse, ElysiaConfig, ElysiaHandlerToResponseSchemaAmbiguous, EphemeralType, ErrorDefinitionEntry, ErrorHandler, ErrorHookStatus, EventScope, ExcludeElysiaResponse, GlobalHookReturn, GracefulHandler, GuardHookSingleton, GuardLocalHook, HTTPMethod, HeadersKeyCheck, HistoryEntry, HookContextSchema, HookContextSingleton, InlineHandler, InlineHandlerNonMacro, InputSchema, InputSchemaKey, InstanceHookReturn, InternalRoute, IntersectIfObjectSchema, JoinPath, LegacyScope, LocalHook, LocalHookReturn, Macro, MacroCatchAll, MacroOptionContext, MacroToContext, MacroToProperty, MapResponse, MaybeArray, MaybePromise, MergeElysiaInstances, MergeSchema, MergeScopedSchemas, MetadataBase, ObjectMacroDefs, OptionalHandler, ParentInput, ParentResponse, PluginHookReturn, PreHandler, PreValidationTransform, Prettify, PublicRoute, ResolveUsedRouteErrors, RouteBase, ScopedHookReturn, ScopedMapDeriveReturn, SingletonBase,
|
|
8
|
+
import { AddRoute, AddWSRoute, AfterHandler, AfterResponseHandler, AnyErrorConstructor, AnyLocalHook, BodyHandler, CatchAllEntries, CatchAllHookReturn, CompiledHandler, CreateEden, DefaultEphemeral, DefaultMetadata, DefaultSingleton, DefinitionBase, DeriveResponse, ElysiaConfig, ElysiaHandlerToResponseSchemaAmbiguous, EphemeralType, ErrorDefinitionEntry, ErrorHandler, ErrorHookStatus, EventScope, ExcludeElysiaResponse, GlobalHookReturn, GracefulHandler, GuardHookSingleton, GuardLocalHook, HTTPMethod, HeadersKeyCheck, HistoryEntry, HookContextSchema, HookContextSingleton, InlineHandler, InlineHandlerNonMacro, InputSchema, InputSchemaKey, InstanceHookReturn, InternalRoute, IntersectIfObjectSchema, JoinPath, LegacyScope, LocalHook, LocalHookReturn, Macro, MacroCatchAll, MacroOptionContext, MacroToContext, MacroToProperty, MapResponse, MaybeArray, MaybePromise, MergeElysiaInstances, MergeSchema, MergeScopedSchemas, MetadataBase, ObjectMacroDefs, OptionalHandler, ParentInput, ParentResponse, PluginHookReturn, PreHandler, PreValidationTransform, Prettify, PublicRoute, ResolveUsedRouteErrors, RouteBase, ScopedHookReturn, ScopedMapDeriveReturn, SingletonBase, UnionResponseStatus, UnwrapRoute, UnwrapSchema, UsedRoutesUnder, WithErrorEntries, WithoutMacroCatch, WrapFn } from "./types.js";
|
|
9
9
|
import { RouteErrorHooks } from "./handler/utils.js";
|
|
10
10
|
import { WSCapability, WSHandlerResponse, WSLocalHook, WSMessageHandler, WSOptions, WSOptionsEntry } from "./ws/types.js";
|
|
11
11
|
import { RouteTable } from "./route-table.js";
|
|
@@ -103,7 +103,6 @@ declare class Elysia<const in out BasePath extends string = '', const in out Sco
|
|
|
103
103
|
private jitColdRemaining?;
|
|
104
104
|
private jitTable?;
|
|
105
105
|
private jitRoute?;
|
|
106
|
-
private jitAliases?;
|
|
107
106
|
'~router'?: Memoirist<CompiledHandler | number>;
|
|
108
107
|
'~map'?: {
|
|
109
108
|
[method: string]: {
|
|
@@ -1044,7 +1043,7 @@ declare class Elysia<const in out BasePath extends string = '', const in out Sco
|
|
|
1044
1043
|
/** @internal Run a route build under the cookie config of route `index` */
|
|
1045
1044
|
['~withRouteCookie']<Args extends unknown[], Result>(index: number, build: (...args: Args) => Result, ...args: Args): Result;
|
|
1046
1045
|
/** @internal */
|
|
1047
|
-
handler(index: number, immediate?: boolean, route?: InternalRoute,
|
|
1046
|
+
handler(index: number, immediate?: boolean, route?: InternalRoute, table?: RouteTable): CompiledHandler;
|
|
1048
1047
|
'~dispatch'(index: number, context: any): MaybePromise<Response>;
|
|
1049
1048
|
private fetchFn?;
|
|
1050
1049
|
get fetch(): (request: Request) => MaybePromise<Response>;
|