reroute-js 0.8.0 → 0.9.0
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/cli/bin.d.ts +1 -1
- package/cli/bin.js +110 -20
- package/cli/bin.js.map +5 -5
- package/cli/index.d.ts +1 -1
- package/cli/index.js +2 -2
- package/cli/index.js.map +1 -1
- package/cli/src/cli.d.ts +1 -1
- package/cli/src/commands/analyze.d.ts +1 -1
- package/cli/src/commands/boot.d.ts +1 -1
- package/cli/src/commands/build.d.ts +1 -1
- package/cli/src/commands/dev.d.ts +1 -1
- package/cli/src/commands/gen.d.ts +1 -1
- package/cli/src/commands/init.d.ts +1 -1
- package/cli/src/commands/start.d.ts +1 -1
- package/cli/src/libs/command.d.ts +1 -1
- package/cli/src/libs/index.d.ts +1 -1
- package/cli/src/libs/log.d.ts +1 -1
- package/cli/src/libs/markdown-processor.d.ts +1 -1
- package/cli/src/libs/markdown.d.ts +1 -1
- package/cli/src/libs/production.d.ts +1 -1
- package/cli/src/libs/tailwind.d.ts +1 -1
- package/cli/src/libs/version.d.ts +1 -1
- package/core/index.d.ts +1 -1
- package/core/index.js +106 -16
- package/core/index.js.map +7 -7
- package/core/src/bundler/hash.d.ts +1 -1
- package/core/src/bundler/index.d.ts +1 -1
- package/core/src/bundler/transpile.d.ts +2 -1
- package/core/src/bundler/transpile.d.ts.map +1 -1
- package/core/src/content/discovery.d.ts +1 -1
- package/core/src/content/index.d.ts +1 -1
- package/core/src/content/metadata.d.ts +1 -1
- package/core/src/content/registry.d.ts +1 -1
- package/core/src/index.d.ts +1 -1
- package/core/src/ssr/data.d.ts +1 -1
- package/core/src/ssr/index.d.ts +1 -1
- package/core/src/ssr/modules.d.ts +1 -1
- package/core/src/ssr/render.d.ts +1 -1
- package/core/src/ssr/render.d.ts.map +1 -1
- package/core/src/ssr/seed.d.ts +1 -1
- package/core/src/template/html.d.ts +1 -1
- package/core/src/template/index.d.ts +1 -1
- package/core/src/types.d.ts +9 -1
- package/core/src/types.d.ts.map +1 -1
- package/core/src/utils/cache.d.ts +1 -1
- package/core/src/utils/compression.d.ts +2 -1
- package/core/src/utils/compression.d.ts.map +1 -1
- package/core/src/utils/index.d.ts +1 -1
- package/core/src/utils/mime.d.ts +1 -1
- package/core/src/utils/path.d.ts +1 -1
- package/elysia/index.d.ts +1 -1
- package/elysia/index.js +225 -26
- package/elysia/index.js.map +8 -8
- package/elysia/src/index.d.ts +1 -1
- package/elysia/src/libs/http.d.ts +1 -1
- package/elysia/src/libs/image.d.ts +1 -1
- package/elysia/src/plugin.d.ts +1 -1
- package/elysia/src/routes/artifacts.d.ts +1 -1
- package/elysia/src/routes/content.d.ts +1 -1
- package/elysia/src/routes/dev.d.ts +1 -1
- package/elysia/src/routes/image.d.ts +1 -1
- package/elysia/src/routes/ssr.d.ts +2 -2
- package/elysia/src/routes/ssr.d.ts.map +1 -1
- package/elysia/src/routes/static.d.ts +1 -1
- package/elysia/src/routes/static.d.ts.map +1 -1
- package/elysia/src/types.d.ts +1 -1
- package/package.json +1 -1
- package/react/index.d.ts +1 -1
- package/react/index.js +2 -2
- package/react/index.js.map +1 -1
- package/react/src/components/ClientOnly.d.ts +1 -1
- package/react/src/components/ContentRoute.d.ts +1 -1
- package/react/src/components/Image.d.ts +1 -1
- package/react/src/components/Link.d.ts +1 -1
- package/react/src/components/Markdown.d.ts +1 -1
- package/react/src/components/Outlet.d.ts +1 -1
- package/react/src/components/index.d.ts +1 -1
- package/react/src/hooks/index.d.ts +1 -1
- package/react/src/hooks/useContent.d.ts +1 -1
- package/react/src/hooks/useData.d.ts +1 -1
- package/react/src/hooks/useNavigate.d.ts +1 -1
- package/react/src/hooks/useParams.d.ts +1 -1
- package/react/src/hooks/useRouter.d.ts +1 -1
- package/react/src/hooks/useSearchParams.d.ts +1 -1
- package/react/src/index.d.ts +1 -1
- package/react/src/providers/ContentProvider.d.ts +1 -1
- package/react/src/providers/RerouteProvider.d.ts +1 -1
- package/react/src/providers/RouterProvider.d.ts +1 -1
- package/react/src/providers/index.d.ts +1 -1
- package/react/src/types/any.d.ts +1 -1
- package/react/src/types/index.d.ts +1 -1
- package/react/src/types/router.d.ts +1 -1
- package/react/src/utils/content.d.ts +1 -1
- package/react/src/utils/head.d.ts +1 -1
- package/react/src/utils/index.d.ts +1 -1
package/core/src/utils/mime.d.ts
CHANGED
package/core/src/utils/path.d.ts
CHANGED
package/elysia/index.d.ts
CHANGED
package/elysia/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* reroute-js v0.
|
|
2
|
+
* reroute-js v0.9.0
|
|
3
3
|
*
|
|
4
4
|
* @license MIT
|
|
5
5
|
* @copyright 2025 stewones <hi@stewan.io>
|
|
@@ -169,6 +169,7 @@ async function buildTailwindIfConfigured(cwd) {
|
|
|
169
169
|
}
|
|
170
170
|
}
|
|
171
171
|
// packages/core/src/bundler/transpile.ts
|
|
172
|
+
var entryUrlToStaticDeps = new Map;
|
|
172
173
|
function isWatchMode() {
|
|
173
174
|
try {
|
|
174
175
|
return Array.isArray(process.execArgv) && process.execArgv.includes("--watch") || Array.isArray(process.argv) && process.argv.includes("--watch");
|
|
@@ -199,11 +200,19 @@ async function transpileFile(filePath, originalPath, options, bundleCache) {
|
|
|
199
200
|
target: "browser",
|
|
200
201
|
format: "esm",
|
|
201
202
|
minify: options.minify,
|
|
202
|
-
splitting:
|
|
203
|
+
splitting: true,
|
|
203
204
|
sourcemap: sm,
|
|
205
|
+
jsx: {
|
|
206
|
+
runtime: "automatic",
|
|
207
|
+
importSource: "react",
|
|
208
|
+
development: !options.minify
|
|
209
|
+
},
|
|
204
210
|
define: {
|
|
205
|
-
"process.env.NODE_ENV": options.minify ? '"production"' : '"development"'
|
|
206
|
-
|
|
211
|
+
"process.env.NODE_ENV": options.minify ? '"production"' : '"development"',
|
|
212
|
+
__DEV__: options.minify ? "false" : "true",
|
|
213
|
+
"import.meta.env.MODE": options.minify ? '"production"' : '"development"'
|
|
214
|
+
},
|
|
215
|
+
...options.minify ? { drop: ["console", "debugger"] } : {}
|
|
207
216
|
});
|
|
208
217
|
}
|
|
209
218
|
let result;
|
|
@@ -219,8 +228,19 @@ async function transpileFile(filePath, originalPath, options, bundleCache) {
|
|
|
219
228
|
console.error(log2);
|
|
220
229
|
throw new Error(`Failed to transpile ${filePath}`);
|
|
221
230
|
}
|
|
222
|
-
const
|
|
223
|
-
|
|
231
|
+
const outputs = await Promise.all(result.outputs.map(async (o) => ({
|
|
232
|
+
path: o.path,
|
|
233
|
+
text: await o.text()
|
|
234
|
+
})));
|
|
235
|
+
const entryBase = basename(originalPath, extname(originalPath));
|
|
236
|
+
let entry = outputs.find((o) => o.path.endsWith(`${entryBase}.js`));
|
|
237
|
+
if (!entry) {
|
|
238
|
+
entry = outputs.filter((o) => o.path.endsWith(".js")).sort((a, b) => b.text.length - a.text.length)[0];
|
|
239
|
+
}
|
|
240
|
+
if (!entry) {
|
|
241
|
+
throw new Error(`[reroute] No JS output generated for ${originalPath}`);
|
|
242
|
+
}
|
|
243
|
+
const code = entry.text;
|
|
224
244
|
let sourceMap;
|
|
225
245
|
if (options.sourcemap && result.outputs.length > 1) {
|
|
226
246
|
const mapOutput = result.outputs.find((o) => o.path.endsWith(".map"));
|
|
@@ -229,10 +249,38 @@ async function transpileFile(filePath, originalPath, options, bundleCache) {
|
|
|
229
249
|
}
|
|
230
250
|
}
|
|
231
251
|
const contentHash = await generateContentHash(code);
|
|
252
|
+
const chunks = outputs.filter((o) => o !== entry && o.path.endsWith(".js")).map((o) => ({
|
|
253
|
+
fileName: basename(o.path),
|
|
254
|
+
code: o.text,
|
|
255
|
+
hash: "",
|
|
256
|
+
isEntry: false,
|
|
257
|
+
imports: []
|
|
258
|
+
}));
|
|
259
|
+
for (const c of chunks) {
|
|
260
|
+
c.hash = await generateContentHash(c.code);
|
|
261
|
+
try {
|
|
262
|
+
const bn = c.fileName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
263
|
+
const re = new RegExp(`["'\`]((?:\\./)?${bn})["'\`]`, "g");
|
|
264
|
+
const matches = [...code.matchAll(re)];
|
|
265
|
+
if (matches.length) {
|
|
266
|
+
c.isEntry = false;
|
|
267
|
+
}
|
|
268
|
+
} catch {}
|
|
269
|
+
}
|
|
270
|
+
const staticDepNames = [];
|
|
271
|
+
try {
|
|
272
|
+
for (const c of chunks) {
|
|
273
|
+
const bn = c.fileName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
274
|
+
const re = new RegExp(`["'\`]((?:\\./)?${bn})["'\`]`, "g");
|
|
275
|
+
if (re.test(code))
|
|
276
|
+
staticDepNames.push(c.fileName);
|
|
277
|
+
}
|
|
278
|
+
} catch {}
|
|
232
279
|
const bundleInfo = {
|
|
233
280
|
hash: contentHash,
|
|
234
281
|
code,
|
|
235
|
-
sourceMap
|
|
282
|
+
sourceMap,
|
|
283
|
+
chunks
|
|
236
284
|
};
|
|
237
285
|
bundleCache.set(cacheKey, bundleInfo);
|
|
238
286
|
const sizeKB = (code.length / 1024).toFixed(2);
|
|
@@ -251,7 +299,13 @@ async function getBundleUrlsFor(modules, clientDir, prefix, options, bundleCache
|
|
|
251
299
|
try {
|
|
252
300
|
const bundleInfo = await transpileFile(fullPath, rel, options, bundleCache);
|
|
253
301
|
const base = basename(rel, extname(rel));
|
|
254
|
-
|
|
302
|
+
const entryUrl = `${prefix}/${base}.${bundleInfo.hash}.js`;
|
|
303
|
+
urls.push(entryUrl);
|
|
304
|
+
try {
|
|
305
|
+
const depNames = Array.isArray(bundleInfo.chunks) ? bundleInfo.chunks.map((c) => c.fileName).filter((name) => new RegExp(`["'\`]((?:\\./)?${name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")})["'\`]`, "g").test(bundleInfo.code)) : [];
|
|
306
|
+
const depUrls = depNames.map((n) => `${prefix}/${n}`.replace(/\/+/g, "/"));
|
|
307
|
+
entryUrlToStaticDeps.set(entryUrl, depUrls);
|
|
308
|
+
} catch {}
|
|
255
309
|
} catch (error) {
|
|
256
310
|
console.error(`[reroute] Error getting bundle URL for ${rel}:`, error);
|
|
257
311
|
urls.push(`${prefix}/${rel}`);
|
|
@@ -259,6 +313,9 @@ async function getBundleUrlsFor(modules, clientDir, prefix, options, bundleCache
|
|
|
259
313
|
}
|
|
260
314
|
return urls;
|
|
261
315
|
}
|
|
316
|
+
function getStaticDepsForUrl(entryUrl) {
|
|
317
|
+
return entryUrlToStaticDeps.get(entryUrl) || [];
|
|
318
|
+
}
|
|
262
319
|
// packages/core/src/content/discovery.ts
|
|
263
320
|
import { readdir, stat as stat2 } from "node:fs/promises";
|
|
264
321
|
|
|
@@ -714,6 +771,21 @@ async function renderSSRDocument(options) {
|
|
|
714
771
|
const scripts = [bundleUrl];
|
|
715
772
|
let hydrationScript = "";
|
|
716
773
|
let extraHead = "";
|
|
774
|
+
try {
|
|
775
|
+
if (typeof bundleUrl === "string" && bundleUrl.endsWith(".js")) {
|
|
776
|
+
extraHead += `
|
|
777
|
+
<link rel="modulepreload" href="${bundleUrl}" />`;
|
|
778
|
+
}
|
|
779
|
+
} catch {}
|
|
780
|
+
try {
|
|
781
|
+
const staticDeps = getStaticDepsForUrl(bundleUrl);
|
|
782
|
+
if (Array.isArray(staticDeps) && staticDeps.length) {
|
|
783
|
+
for (const dep of staticDeps) {
|
|
784
|
+
extraHead += `
|
|
785
|
+
<link rel="modulepreload" href="${dep}" />`;
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
} catch {}
|
|
717
789
|
let statusOverride;
|
|
718
790
|
try {
|
|
719
791
|
globalThis.__REROUTE_SSR_ACCESSED__ = {};
|
|
@@ -1076,6 +1148,9 @@ class LRUCache {
|
|
|
1076
1148
|
return this.cache.size;
|
|
1077
1149
|
}
|
|
1078
1150
|
}
|
|
1151
|
+
// packages/core/src/utils/compression.ts
|
|
1152
|
+
import { brotliCompressSync } from "node:zlib";
|
|
1153
|
+
|
|
1079
1154
|
// packages/core/src/utils/mime.ts
|
|
1080
1155
|
function getMimeType(filePath) {
|
|
1081
1156
|
const ext = filePath.split(".").pop()?.toLowerCase();
|
|
@@ -1108,18 +1183,31 @@ function isCompressible(contentType) {
|
|
|
1108
1183
|
function acceptsGzip(acceptEncoding) {
|
|
1109
1184
|
return Boolean(acceptEncoding && /gzip/i.test(acceptEncoding));
|
|
1110
1185
|
}
|
|
1186
|
+
function acceptsBrotli(acceptEncoding) {
|
|
1187
|
+
return Boolean(acceptEncoding && /\bbr\b/i.test(acceptEncoding));
|
|
1188
|
+
}
|
|
1111
1189
|
function toBytes(input) {
|
|
1112
1190
|
return typeof input === "string" ? new TextEncoder().encode(input) : input;
|
|
1113
1191
|
}
|
|
1114
1192
|
function gzipIfAccepted(body, contentType, acceptEncoding) {
|
|
1115
1193
|
const extraHeaders = {};
|
|
1116
|
-
if (
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1194
|
+
if (isCompressible(contentType)) {
|
|
1195
|
+
if (acceptsBrotli(acceptEncoding)) {
|
|
1196
|
+
try {
|
|
1197
|
+
const compressed = brotliCompressSync(toBytes(body));
|
|
1198
|
+
extraHeaders["Content-Encoding"] = "br";
|
|
1199
|
+
extraHeaders.Vary = "Accept-Encoding";
|
|
1200
|
+
return { body: compressed, extraHeaders };
|
|
1201
|
+
} catch {}
|
|
1202
|
+
}
|
|
1203
|
+
if (acceptsGzip(acceptEncoding)) {
|
|
1204
|
+
try {
|
|
1205
|
+
const compressed = Bun.gzipSync(toBytes(body));
|
|
1206
|
+
extraHeaders["Content-Encoding"] = "gzip";
|
|
1207
|
+
extraHeaders.Vary = "Accept-Encoding";
|
|
1208
|
+
return { body: compressed, extraHeaders };
|
|
1209
|
+
} catch {}
|
|
1210
|
+
}
|
|
1123
1211
|
}
|
|
1124
1212
|
return { body, extraHeaders };
|
|
1125
1213
|
}
|
|
@@ -1628,6 +1716,9 @@ function registerSSRRoutes(app, options) {
|
|
|
1628
1716
|
dataCache,
|
|
1629
1717
|
shouldIgnorePathname
|
|
1630
1718
|
} = options;
|
|
1719
|
+
const SSR_HTML_TTL_MS = isWatchMode2 ? 0 : 5 * 60 * 1000;
|
|
1720
|
+
const htmlCache = new LRUCache(200);
|
|
1721
|
+
const makeKey = (pathname, acceptEncoding) => `${pathname}::${acceptEncoding || "identity"}`;
|
|
1631
1722
|
for (const collection of collections) {
|
|
1632
1723
|
app.get(`/${collection}/*`, async ({ request, headers }) => {
|
|
1633
1724
|
const method = request.method || "GET";
|
|
@@ -1637,8 +1728,34 @@ function registerSSRRoutes(app, options) {
|
|
|
1637
1728
|
if (!/text\/html/i.test(String(accept)))
|
|
1638
1729
|
throw new NotFoundError4;
|
|
1639
1730
|
try {
|
|
1640
|
-
const
|
|
1731
|
+
const url = new URL(request.url);
|
|
1732
|
+
const pathname = url.pathname;
|
|
1733
|
+
const acceptEncoding = headers["accept-encoding"] || "";
|
|
1734
|
+
if (SSR_HTML_TTL_MS > 0) {
|
|
1735
|
+
try {
|
|
1736
|
+
const ck = makeKey(pathname, acceptEncoding);
|
|
1737
|
+
const cached = htmlCache.get(ck);
|
|
1738
|
+
if (cached && cached.exp > Date.now()) {
|
|
1739
|
+
return new Response(cached.body, {
|
|
1740
|
+
status: cached.status,
|
|
1741
|
+
headers: cached.headers
|
|
1742
|
+
});
|
|
1743
|
+
}
|
|
1744
|
+
} catch {}
|
|
1745
|
+
}
|
|
1641
1746
|
const bundleUrl = await getBundleUrl();
|
|
1747
|
+
try {
|
|
1748
|
+
const deps = getStaticDepsForUrl(bundleUrl);
|
|
1749
|
+
const all = [bundleUrl, ...deps];
|
|
1750
|
+
if (all.length) {
|
|
1751
|
+
const linkValue = all.map((u) => `<${u}>; rel=modulepreload; as=script`).join(", ");
|
|
1752
|
+
try {
|
|
1753
|
+
const hints = new Headers({ Link: linkValue });
|
|
1754
|
+
request?.sendEarlyHints?.(hints);
|
|
1755
|
+
} catch {}
|
|
1756
|
+
headers.link = headers.link ? `${headers.link}, ${linkValue}` : linkValue;
|
|
1757
|
+
}
|
|
1758
|
+
} catch {}
|
|
1642
1759
|
const result = await renderSSRDocument({
|
|
1643
1760
|
pathname,
|
|
1644
1761
|
rootComponent,
|
|
@@ -1651,16 +1768,29 @@ function registerSSRRoutes(app, options) {
|
|
|
1651
1768
|
appId,
|
|
1652
1769
|
minify
|
|
1653
1770
|
});
|
|
1654
|
-
const acceptEncoding = headers["accept-encoding"] || "";
|
|
1655
1771
|
const { body, extraHeaders } = gzipIfAccepted(result.html, "text/html; charset=utf-8", acceptEncoding);
|
|
1656
|
-
|
|
1772
|
+
const resHeaders = {
|
|
1773
|
+
"content-type": "text/html; charset=utf-8",
|
|
1774
|
+
"cache-control": isWatchMode2 ? "no-cache" : `${directive}, max-age=${maxAge}`,
|
|
1775
|
+
...headers.link ? { link: headers.link } : {},
|
|
1776
|
+
...extraHeaders
|
|
1777
|
+
};
|
|
1778
|
+
const response = new Response(body, {
|
|
1657
1779
|
status: result.status,
|
|
1658
|
-
headers:
|
|
1659
|
-
"content-type": "text/html; charset=utf-8",
|
|
1660
|
-
"cache-control": isWatchMode2 ? "no-cache" : `${directive}, max-age=${maxAge}`,
|
|
1661
|
-
...extraHeaders
|
|
1662
|
-
}
|
|
1780
|
+
headers: resHeaders
|
|
1663
1781
|
});
|
|
1782
|
+
if (SSR_HTML_TTL_MS > 0 && result.status === 200) {
|
|
1783
|
+
try {
|
|
1784
|
+
const ck = makeKey(pathname, acceptEncoding);
|
|
1785
|
+
htmlCache.set(ck, {
|
|
1786
|
+
status: result.status,
|
|
1787
|
+
headers: resHeaders,
|
|
1788
|
+
body,
|
|
1789
|
+
exp: Date.now() + SSR_HTML_TTL_MS
|
|
1790
|
+
});
|
|
1791
|
+
} catch {}
|
|
1792
|
+
}
|
|
1793
|
+
return response;
|
|
1664
1794
|
} catch (e) {
|
|
1665
1795
|
console.error(`[reroute] SSR ${collection} render error:`, e);
|
|
1666
1796
|
throw new NotFoundError4;
|
|
@@ -1703,7 +1833,31 @@ function registerSSRRoutes(app, options) {
|
|
|
1703
1833
|
if (isWatchMode2) {
|
|
1704
1834
|
await generateContentRegistry(cwd);
|
|
1705
1835
|
}
|
|
1836
|
+
const acceptEncoding = request.headers.get("accept-encoding") || "";
|
|
1837
|
+
if (SSR_HTML_TTL_MS > 0) {
|
|
1838
|
+
try {
|
|
1839
|
+
const ck = makeKey(pathname, acceptEncoding);
|
|
1840
|
+
const cached = htmlCache.get(ck);
|
|
1841
|
+
if (cached && cached.exp > Date.now()) {
|
|
1842
|
+
set.status = cached.status;
|
|
1843
|
+
Object.assign(set.headers, cached.headers);
|
|
1844
|
+
return new Response(cached.body);
|
|
1845
|
+
}
|
|
1846
|
+
} catch {}
|
|
1847
|
+
}
|
|
1706
1848
|
const bundleUrl = await getBundleUrl();
|
|
1849
|
+
try {
|
|
1850
|
+
const deps = getStaticDepsForUrl(bundleUrl);
|
|
1851
|
+
const all = [bundleUrl, ...deps];
|
|
1852
|
+
if (all.length) {
|
|
1853
|
+
const linkValue = all.map((u) => `<${u}>; rel=modulepreload; as=script`).join(", ");
|
|
1854
|
+
try {
|
|
1855
|
+
const hints = new Headers({ Link: linkValue });
|
|
1856
|
+
request?.sendEarlyHints?.(hints);
|
|
1857
|
+
} catch {}
|
|
1858
|
+
set.headers.link = set.headers.link ? `${set.headers.link}, ${linkValue}` : linkValue;
|
|
1859
|
+
}
|
|
1860
|
+
} catch {}
|
|
1707
1861
|
const result = await renderSSRDocument({
|
|
1708
1862
|
pathname,
|
|
1709
1863
|
rootComponent,
|
|
@@ -1716,7 +1870,6 @@ function registerSSRRoutes(app, options) {
|
|
|
1716
1870
|
appId,
|
|
1717
1871
|
minify
|
|
1718
1872
|
});
|
|
1719
|
-
const acceptEncoding = request.headers.get("accept-encoding") || "";
|
|
1720
1873
|
const { body, extraHeaders } = gzipIfAccepted(result.html, "text/html; charset=utf-8", acceptEncoding);
|
|
1721
1874
|
set.status = result.status;
|
|
1722
1875
|
set.headers["content-type"] = "text/html; charset=utf-8";
|
|
@@ -1727,7 +1880,19 @@ function registerSSRRoutes(app, options) {
|
|
|
1727
1880
|
if (extraHeaders.Vary) {
|
|
1728
1881
|
set.headers.vary = extraHeaders.Vary;
|
|
1729
1882
|
}
|
|
1730
|
-
|
|
1883
|
+
const response = new Response(body);
|
|
1884
|
+
if (SSR_HTML_TTL_MS > 0 && result.status === 200) {
|
|
1885
|
+
try {
|
|
1886
|
+
const ck = makeKey(pathname, acceptEncoding);
|
|
1887
|
+
htmlCache.set(ck, {
|
|
1888
|
+
status: result.status,
|
|
1889
|
+
headers: Object.fromEntries(Object.entries(set.headers).map(([k, v]) => [k, String(v)])),
|
|
1890
|
+
body,
|
|
1891
|
+
exp: Date.now() + SSR_HTML_TTL_MS
|
|
1892
|
+
});
|
|
1893
|
+
} catch {}
|
|
1894
|
+
}
|
|
1895
|
+
return response;
|
|
1731
1896
|
} catch {}
|
|
1732
1897
|
}
|
|
1733
1898
|
}
|
|
@@ -1777,6 +1942,32 @@ function registerStaticRoutes(app, options) {
|
|
|
1777
1942
|
if (bundleInfo.hash === hash2) {
|
|
1778
1943
|
const contentType = "application/javascript; charset=utf-8";
|
|
1779
1944
|
const { body, extraHeaders } = gzipIfAccepted(bundleInfo.code, contentType, acceptEncoding);
|
|
1945
|
+
try {
|
|
1946
|
+
if (Array.isArray(bundleInfo.chunks) && bundleInfo.chunks.length) {
|
|
1947
|
+
for (const chunk of bundleInfo.chunks) {
|
|
1948
|
+
const chunkPath = `${prefix}/${chunk.fileName}`.replace(/\/+/g, "/");
|
|
1949
|
+
const identityResp = new Response(chunk.code, {
|
|
1950
|
+
headers: {
|
|
1951
|
+
"Content-Type": contentType,
|
|
1952
|
+
"Cache-Control": `${directive}, max-age=${365 * 24 * 60 * 60}, immutable`,
|
|
1953
|
+
...staticHeaders
|
|
1954
|
+
}
|
|
1955
|
+
});
|
|
1956
|
+
fileCache.set(chunkPath, identityResp);
|
|
1957
|
+
const enc = headers["accept-encoding"] || "";
|
|
1958
|
+
const comp = gzipIfAccepted(chunk.code, contentType, enc);
|
|
1959
|
+
const compressedResp = new Response(comp.body, {
|
|
1960
|
+
headers: {
|
|
1961
|
+
"Content-Type": contentType,
|
|
1962
|
+
"Cache-Control": `${directive}, max-age=${365 * 24 * 60 * 60}, immutable`,
|
|
1963
|
+
...comp.extraHeaders,
|
|
1964
|
+
...staticHeaders
|
|
1965
|
+
}
|
|
1966
|
+
});
|
|
1967
|
+
fileCache.set(`${chunkPath}:${enc}`, compressedResp);
|
|
1968
|
+
}
|
|
1969
|
+
}
|
|
1970
|
+
} catch {}
|
|
1780
1971
|
const response = new Response(body, {
|
|
1781
1972
|
headers: {
|
|
1782
1973
|
"Content-Type": contentType,
|
|
@@ -1824,6 +2015,14 @@ function registerStaticRoutes(app, options) {
|
|
|
1824
2015
|
}
|
|
1825
2016
|
}
|
|
1826
2017
|
}
|
|
2018
|
+
if (requestPath.endsWith(".js")) {
|
|
2019
|
+
const acceptEncoding = headers["accept-encoding"] || "";
|
|
2020
|
+
const pathWithEnc = `${prefix}/${requestPath}`.replace(/\/+/g, "/");
|
|
2021
|
+
const cachedVariant = fileCache.get(`${pathWithEnc}:${acceptEncoding}`) || fileCache.get(pathWithEnc);
|
|
2022
|
+
if (cachedVariant) {
|
|
2023
|
+
return cachedVariant.clone();
|
|
2024
|
+
}
|
|
2025
|
+
}
|
|
1827
2026
|
if (requestPath.endsWith(".tsx") || requestPath.endsWith(".ts")) {
|
|
1828
2027
|
try {
|
|
1829
2028
|
const m = requestPath.match(/^routes\/([^/]+)\/content\/([^/]+)\.(tsx|ts)$/);
|
|
@@ -2107,4 +2306,4 @@ export {
|
|
|
2107
2306
|
reroute
|
|
2108
2307
|
};
|
|
2109
2308
|
|
|
2110
|
-
//# debugId=
|
|
2309
|
+
//# debugId=76563F260B520FB764756E2164756E21
|