hadars 0.3.0 → 0.3.2

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.
@@ -89,6 +89,18 @@ export const makePrecontentHtmlGetter = (htmlFilePromise: Promise<string>) => {
89
89
  let preHead: string | null = null;
90
90
  let postHead: string | null = null;
91
91
  let postContent: string | null = null;
92
+
93
+ // Parse the template as soon as the file read completes — during the
94
+ // process's idle time before the first request arrives. This way the
95
+ // first real request finds preHead !== null and takes the sync path.
96
+ const primed = htmlFilePromise.then(html => {
97
+ const headEnd = html.indexOf(HEAD_MARKER);
98
+ const contentStart = html.indexOf(BODY_MARKER);
99
+ preHead = html.slice(0, headEnd);
100
+ postHead = html.slice(headEnd + HEAD_MARKER.length, contentStart);
101
+ postContent = html.slice(contentStart + BODY_MARKER.length);
102
+ });
103
+
92
104
  // Returns synchronously once the template has been loaded and parsed
93
105
  // (every request after the first). Callers can check `instanceof Promise`
94
106
  // to take a zero-await hot path.
@@ -97,14 +109,7 @@ export const makePrecontentHtmlGetter = (htmlFilePromise: Promise<string>) => {
97
109
  // Hot path — sync return, no Promise allocation.
98
110
  return [preHead + headHtml + postHead!, postContent!];
99
111
  }
100
- return htmlFilePromise.then(html => {
101
- const headEnd = html.indexOf(HEAD_MARKER);
102
- const contentStart = html.indexOf(BODY_MARKER);
103
- preHead = html.slice(0, headEnd);
104
- postHead = html.slice(headEnd + HEAD_MARKER.length, contentStart);
105
- postContent = html.slice(contentStart + BODY_MARKER.length);
106
- return [preHead + headHtml + postHead, postContent];
107
- });
112
+ return primed.then(() => [preHead! + headHtml + postHead!, postContent!]);
108
113
  };
109
114
  };
110
115
 
@@ -142,8 +147,28 @@ async function transformStream(
142
147
  return out;
143
148
  }
144
149
 
145
- export const gzipCompress = (d: Uint8Array) => transformStream(d, new (globalThis as any).CompressionStream('gzip'));
146
- export const gzipDecompress = (d: Uint8Array) => transformStream(d, new (globalThis as any).DecompressionStream('gzip'));
150
+ // Use the Web Streams CompressionStream when available (Bun, Deno, Node 18).
151
+ // Fall back to node:zlib on older Node versions.
152
+ async function zlibGzip(d: Uint8Array): Promise<Uint8Array> {
153
+ const zlib = await import('node:zlib');
154
+ const { promisify } = await import('node:util');
155
+ return promisify(zlib.gzip)(d) as Promise<Uint8Array>;
156
+ }
157
+ async function zlibGunzip(d: Uint8Array): Promise<Uint8Array> {
158
+ const zlib = await import('node:zlib');
159
+ const { promisify } = await import('node:util');
160
+ return promisify(zlib.gunzip)(d) as Promise<Uint8Array>;
161
+ }
162
+
163
+ export const gzipCompress = (d: Uint8Array): Promise<Uint8Array> =>
164
+ (globalThis as any).CompressionStream
165
+ ? transformStream(d, new (globalThis as any).CompressionStream('gzip'))
166
+ : zlibGzip(d);
167
+
168
+ export const gzipDecompress = (d: Uint8Array): Promise<Uint8Array> =>
169
+ (globalThis as any).DecompressionStream
170
+ ? transformStream(d, new (globalThis as any).DecompressionStream('gzip'))
171
+ : zlibGunzip(d);
147
172
 
148
173
  export async function buildCacheEntry(res: Response, ttl: number | undefined): Promise<CacheEntry> {
149
174
  const buf = await res.arrayBuffer();