@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 CHANGED
@@ -2047,7 +2047,7 @@ function getPrefix() {
2047
2047
  }
2048
2048
  var prefix = getPrefix();
2049
2049
  // package.json
2050
- var version = "0.0.25";
2050
+ var version = "0.0.27";
2051
2051
 
2052
2052
  // src/cli/middleware.ts
2053
2053
  import fs2 from "fs/promises";
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 = response.body.pipeThrough(new CompressionStream(encoding === "gzip" ? "gzip" : "deflate"));
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
  */
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@stacksjs/bun-router",
3
3
  "type": "module",
4
- "version": "0.0.25",
4
+ "version": "0.0.27",
5
5
  "description": "A fast, type-safe router for Bun.",
6
6
  "author": "Chris Breuer <chris@stacksjs.org>",
7
7
  "license": "MIT",