@stacksjs/stx 0.2.168 → 0.2.170
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 +624 -624
- package/dist/compression.d.ts +23 -0
- package/dist/compression.js +68 -0
- package/dist/dev-server/serve-file.js +226 -223
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/production-server.js +105 -102
- package/dist/serve.js +2 -1
- package/package.json +5 -5
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/** Whether this content type is worth compressing. */
|
|
2
|
+
export declare function isCompressible(contentType: string | null): boolean;
|
|
3
|
+
/**
|
|
4
|
+
* The best encoding both sides support, or `null` for none.
|
|
5
|
+
*
|
|
6
|
+
* Deliberately ignores the q-values in `Accept-Encoding`. Honouring them means
|
|
7
|
+
* parsing a header that is, in practice, one of about four fixed strings every
|
|
8
|
+
* real browser sends, all of which accept both encodings; the only clients
|
|
9
|
+
* that weight them are testing tools.
|
|
10
|
+
*/
|
|
11
|
+
export declare function negotiateEncoding(acceptEncoding: string | null): 'br' | 'gzip' | null;
|
|
12
|
+
/**
|
|
13
|
+
* Return `response` compressed, or unchanged when it should not be.
|
|
14
|
+
*
|
|
15
|
+
* Never throws and never drops a body: a failed compress logs nothing and
|
|
16
|
+
* returns the original, because shipping bytes uncompressed is a slower
|
|
17
|
+
* success and a broken compress step is an outage.
|
|
18
|
+
*/
|
|
19
|
+
export declare function compressResponse(request: Request, response: Response, options?: CompressionOptions): Promise<Response>;
|
|
20
|
+
export declare interface CompressionOptions {
|
|
21
|
+
threshold?: number
|
|
22
|
+
quality?: number
|
|
23
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import zlib from "node:zlib";
|
|
2
|
+
const COMPRESSIBLE = [
|
|
3
|
+
"text/",
|
|
4
|
+
"application/json",
|
|
5
|
+
"application/javascript",
|
|
6
|
+
"application/xml",
|
|
7
|
+
"application/xhtml+xml",
|
|
8
|
+
"application/rss+xml",
|
|
9
|
+
"application/atom+xml",
|
|
10
|
+
"application/manifest+json",
|
|
11
|
+
"image/svg+xml"
|
|
12
|
+
], NEVER_BUFFER = [
|
|
13
|
+
"text/event-stream",
|
|
14
|
+
"multipart/x-mixed-replace"
|
|
15
|
+
], MIN_BYTES = 1024;
|
|
16
|
+
export function isCompressible(contentType) {
|
|
17
|
+
if (!contentType)
|
|
18
|
+
return !1;
|
|
19
|
+
const type = contentType.toLowerCase();
|
|
20
|
+
if (NEVER_BUFFER.some((prefix) => type.startsWith(prefix)))
|
|
21
|
+
return !1;
|
|
22
|
+
return COMPRESSIBLE.some((prefix) => type.startsWith(prefix));
|
|
23
|
+
}
|
|
24
|
+
export function negotiateEncoding(acceptEncoding) {
|
|
25
|
+
if (!acceptEncoding)
|
|
26
|
+
return null;
|
|
27
|
+
const accepted = acceptEncoding.toLowerCase();
|
|
28
|
+
if (accepted.includes("br"))
|
|
29
|
+
return "br";
|
|
30
|
+
if (accepted.includes("gzip"))
|
|
31
|
+
return "gzip";
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
export async function compressResponse(request, response, options = {}) {
|
|
35
|
+
if (response.headers.get("content-encoding"))
|
|
36
|
+
return response;
|
|
37
|
+
if (response.status === 204 || response.status === 304 || !response.body)
|
|
38
|
+
return response;
|
|
39
|
+
if (!isCompressible(response.headers.get("content-type")))
|
|
40
|
+
return response;
|
|
41
|
+
const encoding = negotiateEncoding(request.headers.get("accept-encoding"));
|
|
42
|
+
if (!encoding)
|
|
43
|
+
return response;
|
|
44
|
+
try {
|
|
45
|
+
const body = Buffer.from(await response.clone().arrayBuffer());
|
|
46
|
+
if (body.length < (options.threshold ?? MIN_BYTES))
|
|
47
|
+
return response;
|
|
48
|
+
const compressed = encoding === "br" ? zlib.brotliCompressSync(body, {
|
|
49
|
+
params: {
|
|
50
|
+
[zlib.constants.BROTLI_PARAM_QUALITY]: options.quality ?? 5,
|
|
51
|
+
[zlib.constants.BROTLI_PARAM_SIZE_HINT]: body.length
|
|
52
|
+
}
|
|
53
|
+
}) : zlib.gzipSync(body);
|
|
54
|
+
if (compressed.length >= body.length)
|
|
55
|
+
return response;
|
|
56
|
+
const headers = new Headers(response.headers);
|
|
57
|
+
headers.set("Content-Encoding", encoding);
|
|
58
|
+
headers.set("Content-Length", String(compressed.length));
|
|
59
|
+
headers.append("Vary", "Accept-Encoding");
|
|
60
|
+
return new Response(compressed, {
|
|
61
|
+
status: response.status,
|
|
62
|
+
statusText: response.statusText,
|
|
63
|
+
headers
|
|
64
|
+
});
|
|
65
|
+
} catch {
|
|
66
|
+
return response;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -24,6 +24,7 @@ import {
|
|
|
24
24
|
setupKeyboardShortcuts
|
|
25
25
|
} from "./index.js";
|
|
26
26
|
import { serveMarkdownFile } from "./serve-markdown.js";
|
|
27
|
+
import { compressResponse } from "../compression.js";
|
|
27
28
|
export async function serveStxFile(filePath, options = {}) {
|
|
28
29
|
const port = options.port || 3000, watch = options.watch !== !1, hotReload = options.hotReload !== !1 && watch;
|
|
29
30
|
let hmrServer = null, actualHmrPort = options.hmrPort || port + 1;
|
|
@@ -135,241 +136,243 @@ export async function serveStxFile(filePath, options = {}) {
|
|
|
135
136
|
const server = serve({
|
|
136
137
|
port: actualPort,
|
|
137
138
|
async fetch(request) {
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
if (url.pathname === "/")
|
|
155
|
-
return (async () => {
|
|
156
|
-
let content = await injectCrosswindCSS(htmlContent || "");
|
|
157
|
-
if (hotReload)
|
|
158
|
-
content = injectHotReload(content, actualHmrPort);
|
|
159
|
-
if (options.native) {
|
|
160
|
-
const nativeSidebarInjection = "<style>[data-stx-sidebar],.stx-sidebar{display:none!important}</style><script>window.__craftNativeSidebar=true;document.documentElement.classList.add('has-native-sidebar')</script>";
|
|
161
|
-
if (content.includes("<head>"))
|
|
162
|
-
content = content.replace("<head>", `<head>${nativeSidebarInjection}`);
|
|
163
|
-
else if (content.includes("<html"))
|
|
164
|
-
content = content.replace(/(<html[^>]*>)/, `$1<head>${nativeSidebarInjection}</head>`);
|
|
165
|
-
else
|
|
166
|
-
content = `<head>${nativeSidebarInjection}</head>` + content;
|
|
167
|
-
}
|
|
168
|
-
if (options.titlebarHidden) {
|
|
169
|
-
const tbInjection = "<style>html.stx-titlebar-hidden .stx-traffic-lights-dot{visibility:hidden}</style><script>document.documentElement.classList.add('stx-titlebar-hidden')</script>";
|
|
170
|
-
if (content.includes("<head>"))
|
|
171
|
-
content = content.replace("<head>", `<head>${tbInjection}`);
|
|
172
|
-
else if (content.includes("<html"))
|
|
173
|
-
content = content.replace(/(<html[^>]*>)/, `$1<head>${tbInjection}</head>`);
|
|
174
|
-
else
|
|
175
|
-
content = `<head>${tbInjection}</head>${content}`;
|
|
176
|
-
}
|
|
177
|
-
return content;
|
|
178
|
-
})().then((content) => new Response(content, {
|
|
179
|
-
headers: {
|
|
180
|
-
"Content-Type": "text/html",
|
|
181
|
-
"Cache-Control": "no-store, no-cache, must-revalidate",
|
|
182
|
-
Pragma: "no-cache",
|
|
183
|
-
Expires: "0"
|
|
139
|
+
return compressResponse(request, await (async () => {
|
|
140
|
+
const url = new URL(request.url);
|
|
141
|
+
if (customRouter)
|
|
142
|
+
try {
|
|
143
|
+
const routerResponse = await customRouter.handleRequest(request);
|
|
144
|
+
if (routerResponse.status !== 404)
|
|
145
|
+
return routerResponse;
|
|
146
|
+
} catch {}
|
|
147
|
+
if (apiRoutes[url.pathname])
|
|
148
|
+
try {
|
|
149
|
+
return await apiRoutes[url.pathname](request);
|
|
150
|
+
} catch (err) {
|
|
151
|
+
return new Response(JSON.stringify({ error: err.message }), {
|
|
152
|
+
status: 500,
|
|
153
|
+
headers: { "Content-Type": "application/json" }
|
|
154
|
+
});
|
|
184
155
|
}
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
156
|
+
if (url.pathname === "/")
|
|
157
|
+
return (async () => {
|
|
158
|
+
let content = await injectCrosswindCSS(htmlContent || "");
|
|
159
|
+
if (hotReload)
|
|
160
|
+
content = injectHotReload(content, actualHmrPort);
|
|
161
|
+
if (options.native) {
|
|
162
|
+
const nativeSidebarInjection = "<style>[data-stx-sidebar],.stx-sidebar{display:none!important}</style><script>window.__craftNativeSidebar=true;document.documentElement.classList.add('has-native-sidebar')</script>";
|
|
163
|
+
if (content.includes("<head>"))
|
|
164
|
+
content = content.replace("<head>", `<head>${nativeSidebarInjection}`);
|
|
165
|
+
else if (content.includes("<html"))
|
|
166
|
+
content = content.replace(/(<html[^>]*>)/, `$1<head>${nativeSidebarInjection}</head>`);
|
|
167
|
+
else
|
|
168
|
+
content = `<head>${nativeSidebarInjection}</head>` + content;
|
|
198
169
|
}
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
break;
|
|
211
|
-
case ".json":
|
|
212
|
-
contentType = "application/json";
|
|
213
|
-
break;
|
|
214
|
-
case ".png":
|
|
215
|
-
contentType = "image/png";
|
|
216
|
-
break;
|
|
217
|
-
case ".jpg":
|
|
218
|
-
case ".jpeg":
|
|
219
|
-
contentType = "image/jpeg";
|
|
220
|
-
break;
|
|
221
|
-
case ".gif":
|
|
222
|
-
contentType = "image/gif";
|
|
223
|
-
break;
|
|
224
|
-
case ".woff":
|
|
225
|
-
contentType = "font/woff";
|
|
226
|
-
break;
|
|
227
|
-
case ".woff2":
|
|
228
|
-
contentType = "font/woff2";
|
|
229
|
-
break;
|
|
230
|
-
case ".ttf":
|
|
231
|
-
contentType = "font/ttf";
|
|
232
|
-
break;
|
|
233
|
-
case ".otf":
|
|
234
|
-
contentType = "font/otf";
|
|
235
|
-
break;
|
|
236
|
-
case ".eot":
|
|
237
|
-
contentType = "application/vnd.ms-fontobject";
|
|
238
|
-
break;
|
|
239
|
-
}
|
|
240
|
-
return new Response(file, {
|
|
241
|
-
headers: { "Content-Type": contentType }
|
|
242
|
-
});
|
|
243
|
-
}
|
|
244
|
-
const sourceDir = path.dirname(absolutePath), sourcePath = path.join(sourceDir, url.pathname);
|
|
245
|
-
if (fs.existsSync(sourcePath) && fs.statSync(sourcePath).isFile()) {
|
|
246
|
-
const file = Bun.file(sourcePath), ext = path.extname(sourcePath).toLowerCase();
|
|
247
|
-
let contentType = "text/plain";
|
|
248
|
-
if (ext === ".ts" || ext === ".tsx") {
|
|
249
|
-
const transpiler = new Bun.Transpiler({ loader: ext === ".tsx" ? "tsx" : "ts" }), code = await file.text(), js = transpiler.transformSync(code);
|
|
250
|
-
return new Response(js, {
|
|
170
|
+
if (options.titlebarHidden) {
|
|
171
|
+
const tbInjection = "<style>html.stx-titlebar-hidden .stx-traffic-lights-dot{visibility:hidden}</style><script>document.documentElement.classList.add('stx-titlebar-hidden')</script>";
|
|
172
|
+
if (content.includes("<head>"))
|
|
173
|
+
content = content.replace("<head>", `<head>${tbInjection}`);
|
|
174
|
+
else if (content.includes("<html"))
|
|
175
|
+
content = content.replace(/(<html[^>]*>)/, `$1<head>${tbInjection}</head>`);
|
|
176
|
+
else
|
|
177
|
+
content = `<head>${tbInjection}</head>${content}`;
|
|
178
|
+
}
|
|
179
|
+
return content;
|
|
180
|
+
})().then((content) => new Response(content, {
|
|
251
181
|
headers: {
|
|
252
|
-
"Content-Type": "
|
|
182
|
+
"Content-Type": "text/html",
|
|
253
183
|
"Cache-Control": "no-store, no-cache, must-revalidate",
|
|
254
184
|
Pragma: "no-cache",
|
|
255
185
|
Expires: "0"
|
|
256
186
|
}
|
|
187
|
+
}));
|
|
188
|
+
const requestedPath = path.join(outputDir, url.pathname);
|
|
189
|
+
if (fs.existsSync(requestedPath) && fs.statSync(requestedPath).isFile()) {
|
|
190
|
+
const file = Bun.file(requestedPath), ext = path.extname(requestedPath).toLowerCase();
|
|
191
|
+
let contentType = "text/plain";
|
|
192
|
+
if (ext === ".ts" || ext === ".tsx") {
|
|
193
|
+
const transpiler = new Bun.Transpiler({ loader: ext === ".tsx" ? "tsx" : "ts" }), code = await file.text(), js = transpiler.transformSync(code);
|
|
194
|
+
return new Response(js, {
|
|
195
|
+
headers: {
|
|
196
|
+
"Content-Type": "application/javascript",
|
|
197
|
+
"Cache-Control": "no-store, no-cache, must-revalidate",
|
|
198
|
+
Pragma: "no-cache",
|
|
199
|
+
Expires: "0"
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
switch (ext) {
|
|
204
|
+
case ".html":
|
|
205
|
+
contentType = "text/html";
|
|
206
|
+
break;
|
|
207
|
+
case ".css":
|
|
208
|
+
contentType = "text/css";
|
|
209
|
+
break;
|
|
210
|
+
case ".js":
|
|
211
|
+
contentType = "text/javascript";
|
|
212
|
+
break;
|
|
213
|
+
case ".json":
|
|
214
|
+
contentType = "application/json";
|
|
215
|
+
break;
|
|
216
|
+
case ".png":
|
|
217
|
+
contentType = "image/png";
|
|
218
|
+
break;
|
|
219
|
+
case ".jpg":
|
|
220
|
+
case ".jpeg":
|
|
221
|
+
contentType = "image/jpeg";
|
|
222
|
+
break;
|
|
223
|
+
case ".gif":
|
|
224
|
+
contentType = "image/gif";
|
|
225
|
+
break;
|
|
226
|
+
case ".woff":
|
|
227
|
+
contentType = "font/woff";
|
|
228
|
+
break;
|
|
229
|
+
case ".woff2":
|
|
230
|
+
contentType = "font/woff2";
|
|
231
|
+
break;
|
|
232
|
+
case ".ttf":
|
|
233
|
+
contentType = "font/ttf";
|
|
234
|
+
break;
|
|
235
|
+
case ".otf":
|
|
236
|
+
contentType = "font/otf";
|
|
237
|
+
break;
|
|
238
|
+
case ".eot":
|
|
239
|
+
contentType = "application/vnd.ms-fontobject";
|
|
240
|
+
break;
|
|
241
|
+
}
|
|
242
|
+
return new Response(file, {
|
|
243
|
+
headers: { "Content-Type": contentType }
|
|
257
244
|
});
|
|
258
245
|
}
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
}
|
|
246
|
+
const sourceDir = path.dirname(absolutePath), sourcePath = path.join(sourceDir, url.pathname);
|
|
247
|
+
if (fs.existsSync(sourcePath) && fs.statSync(sourcePath).isFile()) {
|
|
248
|
+
const file = Bun.file(sourcePath), ext = path.extname(sourcePath).toLowerCase();
|
|
249
|
+
let contentType = "text/plain";
|
|
250
|
+
if (ext === ".ts" || ext === ".tsx") {
|
|
251
|
+
const transpiler = new Bun.Transpiler({ loader: ext === ".tsx" ? "tsx" : "ts" }), code = await file.text(), js = transpiler.transformSync(code);
|
|
252
|
+
return new Response(js, {
|
|
253
|
+
headers: {
|
|
254
|
+
"Content-Type": "application/javascript",
|
|
255
|
+
"Cache-Control": "no-store, no-cache, must-revalidate",
|
|
256
|
+
Pragma: "no-cache",
|
|
257
|
+
Expires: "0"
|
|
258
|
+
}
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
switch (ext) {
|
|
262
|
+
case ".html":
|
|
263
|
+
contentType = "text/html";
|
|
264
|
+
break;
|
|
265
|
+
case ".css":
|
|
266
|
+
contentType = "text/css";
|
|
267
|
+
break;
|
|
268
|
+
case ".js":
|
|
269
|
+
contentType = "text/javascript";
|
|
270
|
+
break;
|
|
271
|
+
case ".json":
|
|
272
|
+
contentType = "application/json";
|
|
273
|
+
break;
|
|
274
|
+
case ".png":
|
|
275
|
+
contentType = "image/png";
|
|
276
|
+
break;
|
|
277
|
+
case ".jpg":
|
|
278
|
+
case ".jpeg":
|
|
279
|
+
contentType = "image/jpeg";
|
|
280
|
+
break;
|
|
281
|
+
case ".gif":
|
|
282
|
+
contentType = "image/gif";
|
|
283
|
+
break;
|
|
284
|
+
case ".svg":
|
|
285
|
+
contentType = "image/svg+xml";
|
|
286
|
+
break;
|
|
287
|
+
case ".ico":
|
|
288
|
+
contentType = "image/x-icon";
|
|
289
|
+
break;
|
|
290
|
+
case ".woff":
|
|
291
|
+
contentType = "font/woff";
|
|
292
|
+
break;
|
|
293
|
+
case ".woff2":
|
|
294
|
+
contentType = "font/woff2";
|
|
295
|
+
break;
|
|
296
|
+
case ".ttf":
|
|
297
|
+
contentType = "font/ttf";
|
|
298
|
+
break;
|
|
299
|
+
case ".otf":
|
|
300
|
+
contentType = "font/otf";
|
|
301
|
+
break;
|
|
302
|
+
case ".eot":
|
|
303
|
+
contentType = "application/vnd.ms-fontobject";
|
|
304
|
+
break;
|
|
305
|
+
}
|
|
306
|
+
return new Response(file, {
|
|
307
|
+
headers: { "Content-Type": contentType }
|
|
321
308
|
});
|
|
322
309
|
}
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
310
|
+
const publicPath = path.join(process.cwd(), "public", url.pathname);
|
|
311
|
+
if (fs.existsSync(publicPath) && fs.statSync(publicPath).isFile()) {
|
|
312
|
+
const file = Bun.file(publicPath), ext = path.extname(publicPath).toLowerCase();
|
|
313
|
+
let contentType = "application/octet-stream";
|
|
314
|
+
if (ext === ".ts" || ext === ".tsx") {
|
|
315
|
+
const transpiler = new Bun.Transpiler({ loader: ext === ".tsx" ? "tsx" : "ts" }), code = await file.text(), js = transpiler.transformSync(code);
|
|
316
|
+
return new Response(js, {
|
|
317
|
+
headers: {
|
|
318
|
+
"Content-Type": "application/javascript",
|
|
319
|
+
"Cache-Control": "no-store, no-cache, must-revalidate",
|
|
320
|
+
Pragma: "no-cache",
|
|
321
|
+
Expires: "0"
|
|
322
|
+
}
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
switch (ext) {
|
|
326
|
+
case ".html":
|
|
327
|
+
contentType = "text/html";
|
|
328
|
+
break;
|
|
329
|
+
case ".css":
|
|
330
|
+
contentType = "text/css";
|
|
331
|
+
break;
|
|
332
|
+
case ".js":
|
|
333
|
+
contentType = "text/javascript";
|
|
334
|
+
break;
|
|
335
|
+
case ".json":
|
|
336
|
+
contentType = "application/json";
|
|
337
|
+
break;
|
|
338
|
+
case ".png":
|
|
339
|
+
contentType = "image/png";
|
|
340
|
+
break;
|
|
341
|
+
case ".jpg":
|
|
342
|
+
case ".jpeg":
|
|
343
|
+
contentType = "image/jpeg";
|
|
344
|
+
break;
|
|
345
|
+
case ".gif":
|
|
346
|
+
contentType = "image/gif";
|
|
347
|
+
break;
|
|
348
|
+
case ".svg":
|
|
349
|
+
contentType = "image/svg+xml";
|
|
350
|
+
break;
|
|
351
|
+
case ".ico":
|
|
352
|
+
contentType = "image/x-icon";
|
|
353
|
+
break;
|
|
354
|
+
case ".woff":
|
|
355
|
+
contentType = "font/woff";
|
|
356
|
+
break;
|
|
357
|
+
case ".woff2":
|
|
358
|
+
contentType = "font/woff2";
|
|
359
|
+
break;
|
|
360
|
+
case ".ttf":
|
|
361
|
+
contentType = "font/ttf";
|
|
362
|
+
break;
|
|
363
|
+
case ".otf":
|
|
364
|
+
contentType = "font/otf";
|
|
365
|
+
break;
|
|
366
|
+
case ".eot":
|
|
367
|
+
contentType = "application/vnd.ms-fontobject";
|
|
368
|
+
break;
|
|
369
|
+
}
|
|
370
|
+
return new Response(file, {
|
|
371
|
+
headers: { "Content-Type": contentType }
|
|
372
|
+
});
|
|
367
373
|
}
|
|
368
|
-
return new Response(
|
|
369
|
-
|
|
370
|
-
});
|
|
371
|
-
}
|
|
372
|
-
return new Response("Not Found", { status: 404 });
|
|
374
|
+
return new Response("Not Found", { status: 404 });
|
|
375
|
+
})());
|
|
373
376
|
},
|
|
374
377
|
error(error) {
|
|
375
378
|
return new Response(`<pre>${error}
|
package/dist/index.d.ts
CHANGED
|
@@ -129,6 +129,7 @@ export * from './custom-directives';
|
|
|
129
129
|
// database moved to stx/database
|
|
130
130
|
export * from './defer';
|
|
131
131
|
export * from './deploy/index';
|
|
132
|
+
export * from './compression';
|
|
132
133
|
export * from './dev-server';
|
|
133
134
|
export * from './document-shell';
|
|
134
135
|
export * from './fragment-container';
|
package/dist/index.js
CHANGED
|
@@ -55,6 +55,7 @@ export * from "./csp.js";
|
|
|
55
55
|
export * from "./custom-directives.js";
|
|
56
56
|
export * from "./defer.js";
|
|
57
57
|
export * from "./deploy/index.js";
|
|
58
|
+
export * from "./compression.js";
|
|
58
59
|
export * from "./dev-server.js";
|
|
59
60
|
export * from "./document-shell.js";
|
|
60
61
|
export * from "./fragment-container.js";
|