elysia 2.0.0-exp.46 → 2.0.0-exp.47
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/index.d.ts +1 -1
- package/dist/adapter/index.js +1 -3
- package/dist/adapter/index.mjs +1 -3
- package/dist/adapter/response-ownership.d.ts +5 -0
- package/dist/adapter/response-ownership.js +13 -0
- package/dist/adapter/response-ownership.mjs +10 -0
- package/dist/adapter/utils.d.ts +4 -4
- package/dist/adapter/utils.js +57 -17
- package/dist/adapter/utils.mjs +58 -18
- package/dist/adapter/web-standard/handler.d.ts +3 -3
- package/dist/adapter/web-standard/handler.js +39 -43
- package/dist/adapter/web-standard/handler.mjs +39 -43
- package/dist/base.js +97 -25
- package/dist/base.mjs +97 -25
- package/dist/compile/analysis-cache.d.ts +6 -0
- package/dist/compile/analysis-cache.js +14 -0
- package/dist/compile/analysis-cache.mjs +13 -0
- package/dist/compile/aot-capture.js +4 -0
- package/dist/compile/aot-capture.mjs +4 -0
- package/dist/compile/aot.d.ts +5 -0
- package/dist/compile/aot.js +7 -0
- package/dist/compile/aot.mjs +7 -0
- package/dist/compile/handler/descriptor.d.ts +3 -3
- package/dist/compile/handler/index.d.ts +6 -3
- package/dist/compile/handler/index.js +9 -42
- package/dist/compile/handler/index.mjs +9 -42
- package/dist/compile/handler/jit.d.ts +1 -1
- package/dist/compile/handler/jit.js +22 -16
- package/dist/compile/handler/jit.mjs +23 -17
- package/dist/compile/handler/params.js +1 -0
- package/dist/compile/handler/params.mjs +2 -1
- package/dist/compile/handler/reconstruct.d.ts +1 -1
- package/dist/compile/handler/utils.js +1 -1
- package/dist/compile/handler/utils.mjs +1 -1
- package/dist/compile/jit-probe.d.ts +0 -2
- package/dist/compile/jit-probe.js +1 -3
- package/dist/compile/jit-probe.mjs +1 -3
- package/dist/cookie/crypto.d.ts +4 -1
- package/dist/cookie/crypto.js +26 -4
- package/dist/cookie/crypto.mjs +24 -5
- package/dist/cookie/utils.d.ts +10 -3
- package/dist/cookie/utils.js +30 -5
- package/dist/cookie/utils.mjs +30 -6
- package/dist/handler/fetch.js +9 -7
- package/dist/handler/fetch.mjs +9 -7
- package/dist/index.d.ts +5 -4
- package/dist/index.js +3 -0
- package/dist/index.mjs +3 -2
- package/dist/package.js +1 -1
- package/dist/package.mjs +1 -1
- package/dist/plugin/aot/core.d.ts +10 -4
- package/dist/plugin/aot/core.js +22 -26
- package/dist/plugin/aot/core.mjs +21 -25
- package/dist/plugin/aot/rspack.js +1 -2
- package/dist/plugin/aot/rspack.mjs +2 -3
- package/dist/plugin/aot/source.d.ts +3 -33
- package/dist/plugin/aot/source.js +1 -21
- package/dist/plugin/aot/source.mjs +2 -21
- package/dist/plugin/aot/treeshake.d.ts +2 -8
- package/dist/plugin/aot/treeshake.js +3 -3
- package/dist/plugin/aot/treeshake.mjs +3 -3
- package/dist/route-table.d.ts +1 -2
- package/dist/route-table.js +2 -6
- package/dist/route-table.mjs +2 -6
- package/dist/sucrose.d.ts +1 -7
- package/dist/sucrose.js +444 -231
- package/dist/sucrose.mjs +445 -229
- package/dist/type/bridge-live.d.ts +2 -2
- package/dist/type/bridge.d.ts +2 -2
- package/dist/type/constants.d.ts +1 -1
- package/dist/type/exports.d.ts +1 -1
- package/dist/type/index.d.ts +1 -1
- package/dist/type/validator/index.d.ts +2 -2
- package/dist/type/validator/validator-cache.js +7 -3
- package/dist/type/validator/validator-cache.mjs +7 -3
- package/dist/types.d.ts +0 -17
- package/dist/utils.d.ts +12 -1
- package/dist/utils.js +20 -0
- package/dist/utils.mjs +18 -1
- package/dist/validator/index.d.ts +1 -1
- package/dist/validator/route.d.ts +1 -1
- package/package.json +1 -7
- package/dist/compile/plan/emit.d.ts +0 -18
- package/dist/compile/plan/emit.js +0 -434
- package/dist/compile/plan/emit.mjs +0 -433
- package/dist/compile/plan/plan.d.ts +0 -53
- package/dist/compile/plan/plan.js +0 -96
- package/dist/compile/plan/plan.mjs +0 -94
- package/dist/experimental/resume.d.ts +0 -11
- package/dist/experimental/resume.js +0 -12
- package/dist/experimental/resume.mjs +0 -11
package/dist/adapter/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ElysiaAdapterOptions } from "./types.js";
|
|
2
2
|
|
|
3
3
|
//#region src/adapter/index.d.ts
|
|
4
|
-
declare
|
|
4
|
+
declare const createAdapter: (adapter: ElysiaAdapterOptions) => ElysiaAdapterOptions;
|
|
5
5
|
type ElysiaAdapter = ReturnType<typeof createAdapter>;
|
|
6
6
|
//#endregion
|
|
7
7
|
export { ElysiaAdapter, type ElysiaAdapterOptions, createAdapter };
|
package/dist/adapter/index.js
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
2
|
|
|
3
3
|
//#region src/adapter/index.ts
|
|
4
|
-
|
|
5
|
-
return adapter;
|
|
6
|
-
}
|
|
4
|
+
const createAdapter = (adapter) => adapter;
|
|
7
5
|
|
|
8
6
|
//#endregion
|
|
9
7
|
exports.createAdapter = createAdapter;
|
package/dist/adapter/index.mjs
CHANGED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
+
|
|
3
|
+
//#region src/adapter/response-ownership.ts
|
|
4
|
+
const borrowedResponses = /* @__PURE__ */ new WeakSet();
|
|
5
|
+
function borrow(response) {
|
|
6
|
+
borrowedResponses.add(response);
|
|
7
|
+
return response;
|
|
8
|
+
}
|
|
9
|
+
const isBorrowedResponse = (response) => borrowedResponses.has(response);
|
|
10
|
+
|
|
11
|
+
//#endregion
|
|
12
|
+
exports.borrow = borrow;
|
|
13
|
+
exports.isBorrowedResponse = isBorrowedResponse;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
//#region src/adapter/response-ownership.ts
|
|
2
|
+
const borrowedResponses = /* @__PURE__ */ new WeakSet();
|
|
3
|
+
function borrow(response) {
|
|
4
|
+
borrowedResponses.add(response);
|
|
5
|
+
return response;
|
|
6
|
+
}
|
|
7
|
+
const isBorrowedResponse = (response) => borrowedResponses.has(response);
|
|
8
|
+
|
|
9
|
+
//#endregion
|
|
10
|
+
export { borrow, isBorrowedResponse };
|
package/dist/adapter/utils.d.ts
CHANGED
|
@@ -17,16 +17,16 @@ declare function responseToSetHeaders(response: Response, set?: Context['set']):
|
|
|
17
17
|
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" | "Not Found" | "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";
|
|
18
18
|
};
|
|
19
19
|
interface CreateHandlerParameter {
|
|
20
|
-
mapResponse(response: unknown, set: Context['set'], request?: Request): Response;
|
|
21
|
-
mapCompactResponse(response: unknown, request?: Request): Response;
|
|
20
|
+
mapResponse(response: unknown, set: Context['set'], request?: Request, owned?: boolean): Response;
|
|
21
|
+
mapCompactResponse(response: unknown, request?: Request, owned?: boolean): Response;
|
|
22
22
|
}
|
|
23
23
|
declare function createStreamHandler({
|
|
24
24
|
mapResponse,
|
|
25
25
|
mapCompactResponse
|
|
26
|
-
}: CreateHandlerParameter): (generator: Generator | AsyncGenerator | ReadableStream, set?: Context["set"], request?: Request, skipFormat?: boolean) => Promise<Response>;
|
|
26
|
+
}: CreateHandlerParameter): (generator: Generator | AsyncGenerator | ReadableStream, set?: Context["set"], request?: Request, skipFormat?: boolean, owned?: boolean) => Promise<Response>;
|
|
27
27
|
declare function streamResponse(response: Response): AsyncGenerator<any, void, any>;
|
|
28
28
|
declare function handleSet(set: Context['set']): void;
|
|
29
|
-
declare function createResponseHandler(handler: CreateHandlerParameter): (response: Response, set?: Context["set"], request?: Request) => any;
|
|
29
|
+
declare function createResponseHandler(handler: CreateHandlerParameter): (response: Response, set?: Context["set"], request?: Request, owned?: boolean) => any;
|
|
30
30
|
/**
|
|
31
31
|
* Split async source into `branches` independent iterators
|
|
32
32
|
*
|
package/dist/adapter/utils.js
CHANGED
|
@@ -4,6 +4,7 @@ const require_constants = require('../constants.js');
|
|
|
4
4
|
const require_utils = require('../utils.js');
|
|
5
5
|
const require_adapter_skip_clone = require('./skip-clone.js');
|
|
6
6
|
const require_cookie_serialize = require('../cookie/serialize.js');
|
|
7
|
+
const require_adapter_response_ownership = require('./response-ownership.js');
|
|
7
8
|
const require_adapter_default_headers = require('./default-headers.js');
|
|
8
9
|
|
|
9
10
|
//#region src/adapter/utils.ts
|
|
@@ -143,29 +144,49 @@ function enqueueBinaryChunk(controller, chunk) {
|
|
|
143
144
|
return false;
|
|
144
145
|
}
|
|
145
146
|
function createStreamHandler({ mapResponse, mapCompactResponse }) {
|
|
146
|
-
return async (generator, set, request, skipFormat) => {
|
|
147
|
-
|
|
147
|
+
return async (generator, set, request, skipFormat, owned = false) => {
|
|
148
|
+
if (require_utils.isByteStream(generator)) {
|
|
149
|
+
if (generator.locked) throw new TypeError("Cannot transfer a locked or consumed byte stream");
|
|
150
|
+
if (set) {
|
|
151
|
+
handleSet(set);
|
|
152
|
+
const headers = materializeSetHeaders(set);
|
|
153
|
+
if (headers instanceof Headers) {
|
|
154
|
+
if (!headers.has("content-type")) headers.set("content-type", "application/octet-stream");
|
|
155
|
+
} else if (!headers["content-type"]) headers["content-type"] = "application/octet-stream";
|
|
156
|
+
return new Response(generator, set);
|
|
157
|
+
}
|
|
158
|
+
return new Response(generator, { headers: { "content-type": "application/octet-stream" } });
|
|
159
|
+
}
|
|
160
|
+
const typedSSE = !skipFormat && "sse" in generator && generator.sse === true;
|
|
161
|
+
let init = typedSSE ? void 0 : generator.next?.();
|
|
148
162
|
if (set) handleSet(set);
|
|
149
163
|
if (init instanceof Promise) init = await init;
|
|
150
164
|
if (init?.value instanceof ReadableStream) generator = init.value;
|
|
151
165
|
else if (init && (typeof init?.done === "undefined" || init?.done)) {
|
|
152
|
-
if (set) return mapResponse(init.value, set, request);
|
|
153
|
-
return mapCompactResponse(init.value, request);
|
|
166
|
+
if (set) return mapResponse(init.value, set, request, owned);
|
|
167
|
+
return mapCompactResponse(init.value, request, owned);
|
|
154
168
|
}
|
|
155
|
-
const isSSE = !skipFormat && (init?.value?.sse ?? generator?.sse ?? (set?.headers instanceof Headers ? set.headers.get("content-type")?.startsWith("text/event-stream") : set?.headers["content-type"]?.startsWith("text/event-stream")));
|
|
169
|
+
const isSSE = typedSSE || !skipFormat && (init?.value?.sse ?? generator?.sse ?? (set?.headers instanceof Headers ? set.headers.get("content-type")?.startsWith("text/event-stream") : set?.headers["content-type"]?.startsWith("text/event-stream")));
|
|
156
170
|
const format = isSSE ? sseFormat : identityFormat;
|
|
157
171
|
const contentType = isSSE ? "text/event-stream" : init?.value && typeof init?.value === "object" ? ArrayBuffer.isView(init.value) ? "application/octet-stream" : "application/json" : "text/plain";
|
|
158
172
|
if (set) materializeSetHeaders(set);
|
|
159
173
|
const headers = set?.headers;
|
|
160
174
|
if (headers instanceof Headers) {
|
|
161
|
-
if (!headers.has("transfer-encoding")) headers.set("transfer-encoding", "chunked");
|
|
175
|
+
if (!typedSSE && !headers.has("transfer-encoding")) headers.set("transfer-encoding", "chunked");
|
|
162
176
|
if (!headers.has("content-type")) headers.set("content-type", contentType);
|
|
163
177
|
if (!headers.has("cache-control")) headers.set("cache-control", "no-cache");
|
|
164
178
|
} else if (headers) {
|
|
165
|
-
if (!headers["transfer-encoding"]) headers["transfer-encoding"] = "chunked";
|
|
179
|
+
if (!typedSSE && !headers["transfer-encoding"]) headers["transfer-encoding"] = "chunked";
|
|
166
180
|
if (!headers["content-type"]) headers["content-type"] = contentType;
|
|
167
181
|
if (!headers["cache-control"]) headers["cache-control"] = "no-cache";
|
|
168
|
-
} else set = {
|
|
182
|
+
} else if (typedSSE) set = {
|
|
183
|
+
status: 200,
|
|
184
|
+
headers: {
|
|
185
|
+
"content-type": contentType,
|
|
186
|
+
"cache-control": "no-cache"
|
|
187
|
+
}
|
|
188
|
+
};
|
|
189
|
+
else set = {
|
|
169
190
|
status: 200,
|
|
170
191
|
headers: {
|
|
171
192
|
"content-type": contentType,
|
|
@@ -250,7 +271,7 @@ function createStreamHandler({ mapResponse, mapCompactResponse }) {
|
|
|
250
271
|
cleanupAbort();
|
|
251
272
|
safeReturn();
|
|
252
273
|
}
|
|
253
|
-
}), set);
|
|
274
|
+
}, typedSSE ? { highWaterMark: 0 } : void 0), set);
|
|
254
275
|
};
|
|
255
276
|
}
|
|
256
277
|
async function* streamResponse(response) {
|
|
@@ -310,7 +331,7 @@ function mergeStatus(responseStatus, setStatus) {
|
|
|
310
331
|
if (responseStatus === 200) return setStatus;
|
|
311
332
|
return responseStatus;
|
|
312
333
|
}
|
|
313
|
-
function cancelPropagatingBody(clonedBody, orphanedBranch) {
|
|
334
|
+
function cancelPropagatingBody(clonedBody, orphanedBranch, preserveOrphan = false) {
|
|
314
335
|
const reader = clonedBody.getReader();
|
|
315
336
|
return new ReadableStream({
|
|
316
337
|
async pull(controller) {
|
|
@@ -319,23 +340,42 @@ function cancelPropagatingBody(clonedBody, orphanedBranch) {
|
|
|
319
340
|
else controller.enqueue(value);
|
|
320
341
|
},
|
|
321
342
|
cancel(reason) {
|
|
343
|
+
if (preserveOrphan) {
|
|
344
|
+
reader.cancel(reason).catch(() => {});
|
|
345
|
+
return;
|
|
346
|
+
}
|
|
322
347
|
orphanedBranch.cancel(reason);
|
|
323
348
|
return reader.cancel(reason);
|
|
324
349
|
}
|
|
325
350
|
});
|
|
326
351
|
}
|
|
352
|
+
const warnedStreamBorrows = /* @__PURE__ */ new WeakSet();
|
|
327
353
|
function createResponseHandler(handler) {
|
|
328
354
|
const handleStream = createStreamHandler(handler);
|
|
329
|
-
return (response, set, request) => {
|
|
355
|
+
return (response, set, request, owned = false) => {
|
|
356
|
+
if (require_adapter_skip_clone.skipClone.has(response) && !response.bodyUsed) {
|
|
357
|
+
require_adapter_skip_clone.skipClone.delete(response);
|
|
358
|
+
owned = true;
|
|
359
|
+
}
|
|
360
|
+
const explicitlyBorrowed = require_adapter_response_ownership.isBorrowedResponse(response);
|
|
361
|
+
const borrowed = !owned || explicitlyBorrowed;
|
|
362
|
+
const mustClone = owned && explicitlyBorrowed;
|
|
363
|
+
if (!borrowed && response.bodyUsed) throw new TypeError("Cannot reuse a consumed Response across requests — a returned Response is request-owned; call borrow(response) to mark it reusable");
|
|
330
364
|
if (set) {
|
|
331
365
|
const status = mergeStatus(response.status, set.status);
|
|
332
|
-
|
|
333
|
-
|
|
366
|
+
const statusUnchanged = status === void 0 || status === response.status;
|
|
367
|
+
if (!mustClone && statusUnchanged && !set.cookie && !require_utils.isNotEmpty(set.headers)) return response;
|
|
368
|
+
} else if (!mustClone) return response;
|
|
369
|
+
if (!borrowed && response.body?.locked) throw new TypeError("Cannot patch a Response whose body is locked — release the reader, or call borrow(response) if it must be reused");
|
|
334
370
|
let body = response.body;
|
|
335
|
-
if (
|
|
336
|
-
|
|
371
|
+
if (borrowed) {
|
|
372
|
+
const bodyBefore = body;
|
|
337
373
|
const cloned = response.clone();
|
|
338
|
-
|
|
374
|
+
if (explicitlyBorrowed && bodyBefore && response.body !== bodyBefore && !warnedStreamBorrows.has(response)) {
|
|
375
|
+
warnedStreamBorrows.add(response);
|
|
376
|
+
console.warn("[elysia] borrow() was called on a stream-backed Response — its entire body will stay buffered in memory for as long as the borrowed object lives, and every reuse adds a tee layer. Borrow only buffered Responses (string / ArrayBuffer / Blob bodies), or construct a fresh Response per request.");
|
|
377
|
+
}
|
|
378
|
+
body = cloned.body && response.body ? cancelPropagatingBody(cloned.body, response.body, explicitlyBorrowed) : cloned.body;
|
|
339
379
|
}
|
|
340
380
|
const newResponse = new Response(body, set ? {
|
|
341
381
|
headers: mergeHeaders(response.headers, set.headers),
|
|
@@ -346,7 +386,7 @@ function createResponseHandler(handler) {
|
|
|
346
386
|
status: response.status,
|
|
347
387
|
statusText: response.statusText
|
|
348
388
|
});
|
|
349
|
-
if (!newResponse.headers.has("content-length") && newResponse.headers.get("transfer-encoding") === "chunked") return handleStream(streamResponse(newResponse), responseToSetHeaders(newResponse, set), request, true);
|
|
389
|
+
if (borrowed && !newResponse.headers.has("content-length") && newResponse.headers.get("transfer-encoding") === "chunked") return handleStream(streamResponse(newResponse), responseToSetHeaders(newResponse, set), request, true);
|
|
350
390
|
return newResponse;
|
|
351
391
|
};
|
|
352
392
|
}
|
package/dist/adapter/utils.mjs
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { hasHeaderShorthand, isBun } from "../universal/constants.mjs";
|
|
2
2
|
import { StatusMap } from "../constants.mjs";
|
|
3
|
-
import { isNotEmpty, nullObject } from "../utils.mjs";
|
|
3
|
+
import { isByteStream, isNotEmpty, nullObject } from "../utils.mjs";
|
|
4
4
|
import { skipClone } from "./skip-clone.mjs";
|
|
5
5
|
import { serializeCookie } from "../cookie/serialize.mjs";
|
|
6
|
+
import { isBorrowedResponse } from "./response-ownership.mjs";
|
|
6
7
|
import { defaultHeaders } from "./default-headers.mjs";
|
|
7
8
|
|
|
8
9
|
//#region src/adapter/utils.ts
|
|
@@ -142,29 +143,49 @@ function enqueueBinaryChunk(controller, chunk) {
|
|
|
142
143
|
return false;
|
|
143
144
|
}
|
|
144
145
|
function createStreamHandler({ mapResponse, mapCompactResponse }) {
|
|
145
|
-
return async (generator, set, request, skipFormat) => {
|
|
146
|
-
|
|
146
|
+
return async (generator, set, request, skipFormat, owned = false) => {
|
|
147
|
+
if (isByteStream(generator)) {
|
|
148
|
+
if (generator.locked) throw new TypeError("Cannot transfer a locked or consumed byte stream");
|
|
149
|
+
if (set) {
|
|
150
|
+
handleSet(set);
|
|
151
|
+
const headers = materializeSetHeaders(set);
|
|
152
|
+
if (headers instanceof Headers) {
|
|
153
|
+
if (!headers.has("content-type")) headers.set("content-type", "application/octet-stream");
|
|
154
|
+
} else if (!headers["content-type"]) headers["content-type"] = "application/octet-stream";
|
|
155
|
+
return new Response(generator, set);
|
|
156
|
+
}
|
|
157
|
+
return new Response(generator, { headers: { "content-type": "application/octet-stream" } });
|
|
158
|
+
}
|
|
159
|
+
const typedSSE = !skipFormat && "sse" in generator && generator.sse === true;
|
|
160
|
+
let init = typedSSE ? void 0 : generator.next?.();
|
|
147
161
|
if (set) handleSet(set);
|
|
148
162
|
if (init instanceof Promise) init = await init;
|
|
149
163
|
if (init?.value instanceof ReadableStream) generator = init.value;
|
|
150
164
|
else if (init && (typeof init?.done === "undefined" || init?.done)) {
|
|
151
|
-
if (set) return mapResponse(init.value, set, request);
|
|
152
|
-
return mapCompactResponse(init.value, request);
|
|
165
|
+
if (set) return mapResponse(init.value, set, request, owned);
|
|
166
|
+
return mapCompactResponse(init.value, request, owned);
|
|
153
167
|
}
|
|
154
|
-
const isSSE = !skipFormat && (init?.value?.sse ?? generator?.sse ?? (set?.headers instanceof Headers ? set.headers.get("content-type")?.startsWith("text/event-stream") : set?.headers["content-type"]?.startsWith("text/event-stream")));
|
|
168
|
+
const isSSE = typedSSE || !skipFormat && (init?.value?.sse ?? generator?.sse ?? (set?.headers instanceof Headers ? set.headers.get("content-type")?.startsWith("text/event-stream") : set?.headers["content-type"]?.startsWith("text/event-stream")));
|
|
155
169
|
const format = isSSE ? sseFormat : identityFormat;
|
|
156
170
|
const contentType = isSSE ? "text/event-stream" : init?.value && typeof init?.value === "object" ? ArrayBuffer.isView(init.value) ? "application/octet-stream" : "application/json" : "text/plain";
|
|
157
171
|
if (set) materializeSetHeaders(set);
|
|
158
172
|
const headers = set?.headers;
|
|
159
173
|
if (headers instanceof Headers) {
|
|
160
|
-
if (!headers.has("transfer-encoding")) headers.set("transfer-encoding", "chunked");
|
|
174
|
+
if (!typedSSE && !headers.has("transfer-encoding")) headers.set("transfer-encoding", "chunked");
|
|
161
175
|
if (!headers.has("content-type")) headers.set("content-type", contentType);
|
|
162
176
|
if (!headers.has("cache-control")) headers.set("cache-control", "no-cache");
|
|
163
177
|
} else if (headers) {
|
|
164
|
-
if (!headers["transfer-encoding"]) headers["transfer-encoding"] = "chunked";
|
|
178
|
+
if (!typedSSE && !headers["transfer-encoding"]) headers["transfer-encoding"] = "chunked";
|
|
165
179
|
if (!headers["content-type"]) headers["content-type"] = contentType;
|
|
166
180
|
if (!headers["cache-control"]) headers["cache-control"] = "no-cache";
|
|
167
|
-
} else set = {
|
|
181
|
+
} else if (typedSSE) set = {
|
|
182
|
+
status: 200,
|
|
183
|
+
headers: {
|
|
184
|
+
"content-type": contentType,
|
|
185
|
+
"cache-control": "no-cache"
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
else set = {
|
|
168
189
|
status: 200,
|
|
169
190
|
headers: {
|
|
170
191
|
"content-type": contentType,
|
|
@@ -249,7 +270,7 @@ function createStreamHandler({ mapResponse, mapCompactResponse }) {
|
|
|
249
270
|
cleanupAbort();
|
|
250
271
|
safeReturn();
|
|
251
272
|
}
|
|
252
|
-
}), set);
|
|
273
|
+
}, typedSSE ? { highWaterMark: 0 } : void 0), set);
|
|
253
274
|
};
|
|
254
275
|
}
|
|
255
276
|
async function* streamResponse(response) {
|
|
@@ -309,7 +330,7 @@ function mergeStatus(responseStatus, setStatus) {
|
|
|
309
330
|
if (responseStatus === 200) return setStatus;
|
|
310
331
|
return responseStatus;
|
|
311
332
|
}
|
|
312
|
-
function cancelPropagatingBody(clonedBody, orphanedBranch) {
|
|
333
|
+
function cancelPropagatingBody(clonedBody, orphanedBranch, preserveOrphan = false) {
|
|
313
334
|
const reader = clonedBody.getReader();
|
|
314
335
|
return new ReadableStream({
|
|
315
336
|
async pull(controller) {
|
|
@@ -318,23 +339,42 @@ function cancelPropagatingBody(clonedBody, orphanedBranch) {
|
|
|
318
339
|
else controller.enqueue(value);
|
|
319
340
|
},
|
|
320
341
|
cancel(reason) {
|
|
342
|
+
if (preserveOrphan) {
|
|
343
|
+
reader.cancel(reason).catch(() => {});
|
|
344
|
+
return;
|
|
345
|
+
}
|
|
321
346
|
orphanedBranch.cancel(reason);
|
|
322
347
|
return reader.cancel(reason);
|
|
323
348
|
}
|
|
324
349
|
});
|
|
325
350
|
}
|
|
351
|
+
const warnedStreamBorrows = /* @__PURE__ */ new WeakSet();
|
|
326
352
|
function createResponseHandler(handler) {
|
|
327
353
|
const handleStream = createStreamHandler(handler);
|
|
328
|
-
return (response, set, request) => {
|
|
354
|
+
return (response, set, request, owned = false) => {
|
|
355
|
+
if (skipClone.has(response) && !response.bodyUsed) {
|
|
356
|
+
skipClone.delete(response);
|
|
357
|
+
owned = true;
|
|
358
|
+
}
|
|
359
|
+
const explicitlyBorrowed = isBorrowedResponse(response);
|
|
360
|
+
const borrowed = !owned || explicitlyBorrowed;
|
|
361
|
+
const mustClone = owned && explicitlyBorrowed;
|
|
362
|
+
if (!borrowed && response.bodyUsed) throw new TypeError("Cannot reuse a consumed Response across requests — a returned Response is request-owned; call borrow(response) to mark it reusable");
|
|
329
363
|
if (set) {
|
|
330
364
|
const status = mergeStatus(response.status, set.status);
|
|
331
|
-
|
|
332
|
-
|
|
365
|
+
const statusUnchanged = status === void 0 || status === response.status;
|
|
366
|
+
if (!mustClone && statusUnchanged && !set.cookie && !isNotEmpty(set.headers)) return response;
|
|
367
|
+
} else if (!mustClone) return response;
|
|
368
|
+
if (!borrowed && response.body?.locked) throw new TypeError("Cannot patch a Response whose body is locked — release the reader, or call borrow(response) if it must be reused");
|
|
333
369
|
let body = response.body;
|
|
334
|
-
if (
|
|
335
|
-
|
|
370
|
+
if (borrowed) {
|
|
371
|
+
const bodyBefore = body;
|
|
336
372
|
const cloned = response.clone();
|
|
337
|
-
|
|
373
|
+
if (explicitlyBorrowed && bodyBefore && response.body !== bodyBefore && !warnedStreamBorrows.has(response)) {
|
|
374
|
+
warnedStreamBorrows.add(response);
|
|
375
|
+
console.warn("[elysia] borrow() was called on a stream-backed Response — its entire body will stay buffered in memory for as long as the borrowed object lives, and every reuse adds a tee layer. Borrow only buffered Responses (string / ArrayBuffer / Blob bodies), or construct a fresh Response per request.");
|
|
376
|
+
}
|
|
377
|
+
body = cloned.body && response.body ? cancelPropagatingBody(cloned.body, response.body, explicitlyBorrowed) : cloned.body;
|
|
338
378
|
}
|
|
339
379
|
const newResponse = new Response(body, set ? {
|
|
340
380
|
headers: mergeHeaders(response.headers, set.headers),
|
|
@@ -345,7 +385,7 @@ function createResponseHandler(handler) {
|
|
|
345
385
|
status: response.status,
|
|
346
386
|
statusText: response.statusText
|
|
347
387
|
});
|
|
348
|
-
if (!newResponse.headers.has("content-length") && newResponse.headers.get("transfer-encoding") === "chunked") return handleStream(streamResponse(newResponse), responseToSetHeaders(newResponse, set), request, true);
|
|
388
|
+
if (borrowed && !newResponse.headers.has("content-length") && newResponse.headers.get("transfer-encoding") === "chunked") return handleStream(streamResponse(newResponse), responseToSetHeaders(newResponse, set), request, true);
|
|
349
389
|
return newResponse;
|
|
350
390
|
};
|
|
351
391
|
}
|
|
@@ -2,10 +2,10 @@ import { MaybePromise } from "../../types.js";
|
|
|
2
2
|
import { Context } from "../../context.js";
|
|
3
3
|
|
|
4
4
|
//#region src/adapter/web-standard/handler.d.ts
|
|
5
|
-
declare function mapResponse(response: unknown, set: Context['set'], request?: Request): Response;
|
|
6
|
-
declare function mapCompactResponse(response: unknown, request?: Request): Response;
|
|
5
|
+
declare function mapResponse(response: unknown, set: Context['set'], request?: Request, owned?: boolean): Response;
|
|
6
|
+
declare function mapCompactResponse(response: unknown, request?: Request, owned?: boolean): Response;
|
|
7
7
|
declare function errorToResponse(error: Error & {
|
|
8
8
|
toResponse?(): MaybePromise<Response>;
|
|
9
|
-
}, set?: Context['set']): any;
|
|
9
|
+
}, set?: Context['set'], request?: Request, owned?: boolean): any;
|
|
10
10
|
//#endregion
|
|
11
11
|
export { errorToResponse, mapCompactResponse, mapResponse };
|
|
@@ -7,6 +7,7 @@ const require_adapter_default_headers = require('../default-headers.js');
|
|
|
7
7
|
const require_adapter_utils = require('../utils.js');
|
|
8
8
|
|
|
9
9
|
//#region src/adapter/web-standard/handler.ts
|
|
10
|
+
const textPlainInit = { headers: { "content-type": "text/plain" } };
|
|
10
11
|
function handleElysiaFile(file, set = { headers: require_utils.nullObject() }, request) {
|
|
11
12
|
const path = file.path;
|
|
12
13
|
const contentType = require_universal_file.mime[path.slice(path.lastIndexOf(".") + 1).toLowerCase()];
|
|
@@ -20,23 +21,17 @@ function handleElysiaFile(file, set = { headers: require_utils.nullObject() }, r
|
|
|
20
21
|
});
|
|
21
22
|
return require_adapter_utils.handleFile(file.value, set, request);
|
|
22
23
|
}
|
|
23
|
-
function
|
|
24
|
-
if (response === null || response === void 0) return void 0;
|
|
25
|
-
const proto = Object.getPrototypeOf(response);
|
|
26
|
-
if (proto === null) return "Object";
|
|
27
|
-
return proto.constructor?.name;
|
|
28
|
-
}
|
|
29
|
-
function mapResponseWithSet(response, set, request) {
|
|
24
|
+
function mapResponseWithSet(response, set, request, owned) {
|
|
30
25
|
require_adapter_utils.handleSet(set);
|
|
31
26
|
const headers = set.headers;
|
|
32
|
-
switch (
|
|
27
|
+
switch (response?.constructor?.name) {
|
|
33
28
|
case "String":
|
|
34
29
|
if (!require_universal_constants.isBun && !headers["content-type"]) require_adapter_utils.materializeSetHeaders(set)["content-type"] = "text/plain";
|
|
35
30
|
return new Response(response, set);
|
|
36
31
|
case "Array": return Response.json(response, set);
|
|
37
32
|
case "Object":
|
|
38
33
|
if (response["~ely-form"]) return new Response(require_utils.formToFormData(response), set);
|
|
39
|
-
if (typeof response?.next === "function") return handleStream(response, set, request);
|
|
34
|
+
if (typeof response?.next === "function") return handleStream(response, set, request, void 0, owned);
|
|
40
35
|
return Response.json(response, set);
|
|
41
36
|
case "Number":
|
|
42
37
|
case "Boolean": return new Response(response.toString(), set);
|
|
@@ -46,32 +41,33 @@ function mapResponseWithSet(response, set, request) {
|
|
|
46
41
|
case "ElysiaStatus":
|
|
47
42
|
set.status = response.code;
|
|
48
43
|
if (response.headers) Object.assign(require_adapter_utils.materializeSetHeaders(set), response.headers);
|
|
49
|
-
return mapResponseWithSet(response.response, set, request);
|
|
44
|
+
return mapResponseWithSet(response.response, set, request, owned);
|
|
50
45
|
case void 0: return response ? Response.json(response, set) : new Response(null, set);
|
|
51
|
-
case "Response": return handleResponse(response, set, request);
|
|
52
|
-
case "Error": return errorToResponse(response, set);
|
|
53
|
-
case "Promise": return response.then((x) => mapResponseWithSet(x, set, request));
|
|
54
|
-
case "Function": return mapResponseWithSet(response(), set, request);
|
|
46
|
+
case "Response": return handleResponse(response, set, request, owned);
|
|
47
|
+
case "Error": return errorToResponse(response, set, request, owned);
|
|
48
|
+
case "Promise": return response.then((x) => mapResponseWithSet(x, set, request, owned));
|
|
49
|
+
case "Function": return mapResponseWithSet(response(), set, request, owned);
|
|
55
50
|
case "FormData": return new Response(response, set);
|
|
56
|
-
default: return mapResponseFallback(response, set, request);
|
|
51
|
+
default: return mapResponseFallback(response, set, request, owned);
|
|
57
52
|
}
|
|
58
53
|
}
|
|
59
|
-
function mapResponse(response, set, request) {
|
|
54
|
+
function mapResponse(response, set, request, owned) {
|
|
60
55
|
const headers = set.headers;
|
|
61
|
-
if (set.status !== void 0 || set.cookie || headers["\0"] === headers || require_utils.isNotEmpty(headers)) return mapResponseWithSet(response, set, request);
|
|
56
|
+
if (set.status !== void 0 || set.cookie || headers["\0"] === headers || require_utils.isNotEmpty(headers)) return mapResponseWithSet(response, set, request, owned);
|
|
62
57
|
if (response instanceof require_error.ElysiaStatus) {
|
|
63
58
|
set.status = response.code;
|
|
64
59
|
if (response.headers) Object.assign(set.headers, response.headers);
|
|
65
|
-
return mapResponse(response.response, set, request);
|
|
60
|
+
return mapResponse(response.response, set, request, owned);
|
|
66
61
|
}
|
|
67
|
-
if (response instanceof Response) return response;
|
|
68
|
-
if (response instanceof Promise) return response.then((x) => mapResponse(x, set, request));
|
|
69
|
-
if (typeof response?.next === "function" || response instanceof ReadableStream) return handleStream(response, set, request);
|
|
70
|
-
return mapCompactResponse(response, request);
|
|
62
|
+
if (response instanceof Response) return owned ? handleResponse(response, void 0, request, true) : response;
|
|
63
|
+
if (response instanceof Promise) return response.then((x) => mapResponse(x, set, request, owned));
|
|
64
|
+
if (typeof response?.next === "function" || response instanceof ReadableStream) return handleStream(response, set, request, void 0, owned);
|
|
65
|
+
return mapCompactResponse(response, request, owned);
|
|
71
66
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
67
|
+
const textHeaders = require_universal_constants.isBun ? void 0 : textPlainInit;
|
|
68
|
+
function mapCompactResponse(response, request, owned) {
|
|
69
|
+
switch (response?.constructor?.name) {
|
|
70
|
+
case "String": return new Response(response, textHeaders);
|
|
75
71
|
case "Array": return Response.json(response);
|
|
76
72
|
case "Object":
|
|
77
73
|
if (response["~ely-form"]) return new Response(require_utils.formToFormData(response));
|
|
@@ -84,22 +80,22 @@ function mapCompactResponse(response, request) {
|
|
|
84
80
|
case "ElysiaStatus": return mapResponse(response.response, {
|
|
85
81
|
status: response.code,
|
|
86
82
|
headers: response.headers ? Object.assign(require_utils.nullObject(), response.headers) : require_utils.nullObject()
|
|
87
|
-
});
|
|
83
|
+
}, request, owned);
|
|
88
84
|
case void 0: return response ? Response.json(response) : new Response("");
|
|
89
|
-
case "Response": return response;
|
|
90
|
-
case "Error": return errorToResponse(response);
|
|
91
|
-
case "Promise": return response.then((x) => mapCompactResponse(x, request));
|
|
92
|
-
case "Function": return mapCompactResponse(response(), request);
|
|
85
|
+
case "Response": return owned ? handleResponse(response, void 0, request, true) : response;
|
|
86
|
+
case "Error": return errorToResponse(response, void 0, request, owned);
|
|
87
|
+
case "Promise": return response.then((x) => mapCompactResponse(x, request, owned));
|
|
88
|
+
case "Function": return mapCompactResponse(response(), request, owned);
|
|
93
89
|
case "FormData": return new Response(response);
|
|
94
|
-
default: return mapCompactResponseFallback(response, void 0, request);
|
|
90
|
+
default: return mapCompactResponseFallback(response, void 0, request, owned);
|
|
95
91
|
}
|
|
96
92
|
}
|
|
97
|
-
function errorToResponse(error, set) {
|
|
93
|
+
function errorToResponse(error, set, request, owned = false) {
|
|
98
94
|
if (error?.toResponse) {
|
|
99
95
|
const targetSet = set ?? { headers: require_utils.nullObject() };
|
|
100
96
|
const apply = (resolved) => {
|
|
101
97
|
if (resolved instanceof Response) targetSet.status = resolved.status;
|
|
102
|
-
return mapResponse(resolved, targetSet);
|
|
98
|
+
return mapResponse(resolved, targetSet, request, owned);
|
|
103
99
|
};
|
|
104
100
|
const raw = error.toResponse();
|
|
105
101
|
return typeof raw?.then === "function" ? raw.then(apply) : apply(raw);
|
|
@@ -115,31 +111,31 @@ function errorToResponse(error, set) {
|
|
|
115
111
|
});
|
|
116
112
|
}
|
|
117
113
|
function mapFallback(map) {
|
|
118
|
-
return (response, set, request) => {
|
|
119
|
-
if (response instanceof Response) return handleResponse(response, set, request);
|
|
120
|
-
if (response instanceof Promise) return response.then((x) => map(x, set, request));
|
|
121
|
-
if (response instanceof Error) return errorToResponse(response, set);
|
|
114
|
+
return (response, set, request, owned = false) => {
|
|
115
|
+
if (response instanceof Response) return handleResponse(response, set, request, owned);
|
|
116
|
+
if (response instanceof Promise) return response.then((x) => map(x, set, request, owned));
|
|
117
|
+
if (response instanceof Error) return errorToResponse(response, set, request, owned);
|
|
122
118
|
if (response instanceof require_error.ElysiaStatus) if (set) {
|
|
123
119
|
set.status = response.code;
|
|
124
120
|
if (response.headers) set.headers = {
|
|
125
121
|
...set.headers,
|
|
126
122
|
...response.headers
|
|
127
123
|
};
|
|
128
|
-
return map(response.response, set, request);
|
|
124
|
+
return map(response.response, set, request, owned);
|
|
129
125
|
} else return mapResponse(response.response, {
|
|
130
126
|
status: response.code,
|
|
131
127
|
headers: response.headers ? { ...response.headers } : {}
|
|
132
|
-
});
|
|
133
|
-
if (typeof response?.next === "function" || response instanceof ReadableStream) return handleStream(response, set, request);
|
|
134
|
-
if (typeof response?.then === "function") return response.then((x) => map(x, set, request));
|
|
128
|
+
}, request, owned);
|
|
129
|
+
if (typeof response?.next === "function" || response instanceof ReadableStream) return handleStream(response, set, request, void 0, owned);
|
|
130
|
+
if (typeof response?.then === "function") return response.then((x) => map(x, set, request, owned));
|
|
135
131
|
if (Array.isArray(response)) return Response.json(response);
|
|
136
|
-
if (typeof response?.toResponse === "function") return map(response.toResponse(), set, request);
|
|
132
|
+
if (typeof response?.toResponse === "function") return map(response.toResponse(), set, request, owned);
|
|
137
133
|
if (response?.constructor?.name === "Cookie" && response.jar) return new Response(response.value, set);
|
|
138
134
|
return new Response(response, set);
|
|
139
135
|
};
|
|
140
136
|
}
|
|
141
137
|
const mapResponseFallback = mapFallback(mapResponse);
|
|
142
|
-
const mapCompactResponseFallback = mapFallback((response, _, request) => mapCompactResponse(response, request));
|
|
138
|
+
const mapCompactResponseFallback = mapFallback((response, _, request, owned) => mapCompactResponse(response, request, owned));
|
|
143
139
|
const handleResponse = require_adapter_utils.createResponseHandler({
|
|
144
140
|
mapResponse,
|
|
145
141
|
mapCompactResponse
|