@stacksjs/bun-router 0.0.25 → 0.0.27
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/cli.js +1 -1
- package/dist/index.js +52 -1
- package/dist/response/compression.d.ts +13 -0
- package/dist/types.d.ts +12 -2
- package/package.json +1 -1
package/dist/cli.js
CHANGED
package/dist/index.js
CHANGED
|
@@ -2057,6 +2057,8 @@ function isCompressible(contentType) {
|
|
|
2057
2057
|
if (!contentType)
|
|
2058
2058
|
return false;
|
|
2059
2059
|
const type = contentType.split(";")[0]?.trim().toLowerCase() ?? "";
|
|
2060
|
+
if (type === "text/event-stream")
|
|
2061
|
+
return false;
|
|
2060
2062
|
if (type.startsWith("text/"))
|
|
2061
2063
|
return true;
|
|
2062
2064
|
return [
|
|
@@ -2114,13 +2116,61 @@ async function compressResponse(response, request2, options = {}) {
|
|
|
2114
2116
|
appendVary(response.headers, "Accept-Encoding");
|
|
2115
2117
|
return response;
|
|
2116
2118
|
}
|
|
2119
|
+
const known = Number(response.headers.get("content-length") ?? Number.NaN);
|
|
2120
|
+
const body = Number.isFinite(known) ? { stream: response.body, size: known, ended: false } : await peekBody(response.body, settings.threshold);
|
|
2121
|
+
if (body.ended && body.size < settings.threshold) {
|
|
2122
|
+
const headers2 = new Headers(response.headers);
|
|
2123
|
+
appendVary(headers2, "Accept-Encoding");
|
|
2124
|
+
return new Response(body.stream, { status: response.status, statusText: response.statusText, headers: headers2 });
|
|
2125
|
+
}
|
|
2117
2126
|
const headers = new Headers(response.headers);
|
|
2118
2127
|
headers.set("Content-Encoding", encoding);
|
|
2119
2128
|
appendVary(headers, "Accept-Encoding");
|
|
2120
2129
|
headers.delete("Content-Length");
|
|
2121
|
-
const compressed =
|
|
2130
|
+
const compressed = body.stream.pipeThrough(new CompressionStream(encoding === "gzip" ? "gzip" : "deflate"));
|
|
2122
2131
|
return new Response(compressed, { status: response.status, statusText: response.statusText, headers });
|
|
2123
2132
|
}
|
|
2133
|
+
async function peekBody(source, limit) {
|
|
2134
|
+
const reader = source.getReader();
|
|
2135
|
+
const prefix = [];
|
|
2136
|
+
let size = 0;
|
|
2137
|
+
let ended = false;
|
|
2138
|
+
while (size < limit) {
|
|
2139
|
+
const { value, done } = await reader.read();
|
|
2140
|
+
if (done) {
|
|
2141
|
+
ended = true;
|
|
2142
|
+
break;
|
|
2143
|
+
}
|
|
2144
|
+
if (value) {
|
|
2145
|
+
prefix.push(value);
|
|
2146
|
+
size += value.byteLength;
|
|
2147
|
+
}
|
|
2148
|
+
}
|
|
2149
|
+
const stream = new ReadableStream({
|
|
2150
|
+
start(controller) {
|
|
2151
|
+
for (const chunk of prefix)
|
|
2152
|
+
controller.enqueue(chunk);
|
|
2153
|
+
if (ended)
|
|
2154
|
+
controller.close();
|
|
2155
|
+
},
|
|
2156
|
+
async pull(controller) {
|
|
2157
|
+
if (ended)
|
|
2158
|
+
return;
|
|
2159
|
+
const { value, done } = await reader.read();
|
|
2160
|
+
if (done) {
|
|
2161
|
+
ended = true;
|
|
2162
|
+
controller.close();
|
|
2163
|
+
return;
|
|
2164
|
+
}
|
|
2165
|
+
if (value)
|
|
2166
|
+
controller.enqueue(value);
|
|
2167
|
+
},
|
|
2168
|
+
cancel(reason) {
|
|
2169
|
+
return reader.cancel(reason);
|
|
2170
|
+
}
|
|
2171
|
+
});
|
|
2172
|
+
return { stream, size, ended };
|
|
2173
|
+
}
|
|
2124
2174
|
function appendVary(headers, value) {
|
|
2125
2175
|
const existing = headers.get("vary");
|
|
2126
2176
|
if (!existing) {
|
|
@@ -13779,6 +13829,7 @@ export {
|
|
|
13779
13829
|
performanceDashboard,
|
|
13780
13830
|
performanceAssertions,
|
|
13781
13831
|
performanceAlerting,
|
|
13832
|
+
peekBody,
|
|
13782
13833
|
parseThrottleString,
|
|
13783
13834
|
oauth2Auth,
|
|
13784
13835
|
normalizePath,
|
|
@@ -85,5 +85,18 @@ export declare function shouldCompress(response: Response, encoding: string | nu
|
|
|
85
85
|
* unconditionally at the end of the pipeline.
|
|
86
86
|
*/
|
|
87
87
|
export declare function compressResponse(response: Response, request: Request, options?: CompressionOptions): Promise<Response>;
|
|
88
|
+
/**
|
|
89
|
+
* Read up to `limit` bytes, and hand back a stream that still has them.
|
|
90
|
+
*
|
|
91
|
+
* The prefix is re-emitted before the rest of the source, so nothing is lost
|
|
92
|
+
* and nothing is held beyond the limit. `ended` says the body finished inside
|
|
93
|
+
* the prefix, which is what makes a small answer distinguishable from the
|
|
94
|
+
* beginning of a large one.
|
|
95
|
+
*/
|
|
96
|
+
export declare function peekBody(source: ReadableStream<Uint8Array>, limit: number): Promise<{
|
|
97
|
+
stream: ReadableStream<Uint8Array>;
|
|
98
|
+
size: number;
|
|
99
|
+
ended: boolean;
|
|
100
|
+
}>;
|
|
88
101
|
/** Add to `Vary` without dropping what is already there. */
|
|
89
102
|
export declare function appendVary(headers: Headers, value: string): void;
|
package/dist/types.d.ts
CHANGED
|
@@ -1155,9 +1155,19 @@ export type RouteMethodConstraint<M extends HTTPMethod = HTTPMethod> = M;
|
|
|
1155
1155
|
*/
|
|
1156
1156
|
export type AllowedMimeType = 'image/jpeg' | 'image/png' | 'image/gif' | 'image/webp' | 'image/svg+xml' | 'application/pdf' | 'application/json' | 'text/plain' | 'text/csv' | 'application/octet-stream';
|
|
1157
1157
|
/**
|
|
1158
|
-
* Response status codes - narrow and specific
|
|
1158
|
+
* Response status codes - narrow and specific.
|
|
1159
|
+
*
|
|
1160
|
+
* Narrow to catch typos, not to pick which parts of HTTP an application is
|
|
1161
|
+
* allowed to speak. Everything below is a status a real handler returns, and a
|
|
1162
|
+
* missing one is not a nudge toward a better design: it is a type error on
|
|
1163
|
+
* correct code, with `as any` as the only way out. The set grew because an
|
|
1164
|
+
* upload endpoint could not say 413 for a body over its limit.
|
|
1165
|
+
*
|
|
1166
|
+
* Deliberately still absent: 1xx, which Bun handles; 306, which is unused; and
|
|
1167
|
+
* 3xx redirect codes other than the ones `redirect()` already accepts, so a
|
|
1168
|
+
* redirect keeps going through the helper that sets a Location header.
|
|
1159
1169
|
*/
|
|
1160
|
-
export type ResponseStatus = 200 | 201 | 202 | 204 | 301 | 302 | 304 | 400 | 401 | 403 | 404 | 405 | 409 | 422 | 429 | 500 | 502 | 503 | 504;
|
|
1170
|
+
export type ResponseStatus = 200 | 201 | 202 | 203 | 204 | 205 | 206 | 301 | 302 | 303 | 304 | 307 | 308 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 418 | 422 | 423 | 425 | 426 | 428 | 429 | 431 | 451 | 500 | 501 | 502 | 503 | 504 | 505 | 507 | 511;
|
|
1161
1171
|
/**
|
|
1162
1172
|
* Content types - narrow
|
|
1163
1173
|
*/
|