@taujs/server 0.5.5 → 0.5.7

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.
Files changed (2) hide show
  1. package/dist/index.js +99 -72
  2. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -304,7 +304,7 @@ var SSRTAG = {
304
304
  ssrHtml: "<!--ssr-html-->"
305
305
  };
306
306
  var TEMPLATE = {
307
- defaultEntryClient: "entry-client",
307
+ defaultEntryClient: "entry-client.tsx",
308
308
  defaultEntryServer: "entry-server",
309
309
  defaultHtmlTemplate: "index.html"
310
310
  };
@@ -1249,7 +1249,7 @@ import { pathToFileURL } from "url";
1249
1249
 
1250
1250
  // src/utils/Templates.ts
1251
1251
  var CSS_LANGS_RE = /\.(css|less|sass|scss|styl|stylus|pcss|postcss|sss)(?:$|\?)/;
1252
- async function collectStyle(server, entries) {
1252
+ var collectStyle = async (server, entries) => {
1253
1253
  const urls = await collectStyleUrls(server, entries);
1254
1254
  const codes = await Promise.all(
1255
1255
  urls.map(async (url) => {
@@ -1258,7 +1258,7 @@ async function collectStyle(server, entries) {
1258
1258
  })
1259
1259
  );
1260
1260
  return codes.flat().filter(Boolean).join("\n\n");
1261
- }
1261
+ };
1262
1262
  async function collectStyleUrls(server, entries) {
1263
1263
  const visited = /* @__PURE__ */ new Set();
1264
1264
  async function traverse(url) {
@@ -1273,7 +1273,7 @@ async function collectStyleUrls(server, entries) {
1273
1273
  await Promise.all(entries.map((url) => traverse(url)));
1274
1274
  return [...visited].filter((url) => url.match(CSS_LANGS_RE));
1275
1275
  }
1276
- function renderPreloadLinks(ssrManifest, basePath = "") {
1276
+ var renderPreloadLinks = (ssrManifest, basePath = "") => {
1277
1277
  const seen = /* @__PURE__ */ new Set();
1278
1278
  let links = "";
1279
1279
  for (const moduleId in ssrManifest) {
@@ -1288,8 +1288,8 @@ function renderPreloadLinks(ssrManifest, basePath = "") {
1288
1288
  }
1289
1289
  }
1290
1290
  return links;
1291
- }
1292
- function renderPreloadLink(file) {
1291
+ };
1292
+ var renderPreloadLink = (file) => {
1293
1293
  const fileType = file.match(/\.(js|css|woff2?|gif|jpe?g|png|svg)$/)?.[1];
1294
1294
  switch (fileType) {
1295
1295
  case "js":
@@ -1309,8 +1309,8 @@ function renderPreloadLink(file) {
1309
1309
  default:
1310
1310
  return "";
1311
1311
  }
1312
- }
1313
- function getCssLinks(manifest, basePath = "") {
1312
+ };
1313
+ var getCssLinks = (manifest, basePath = "") => {
1314
1314
  const seen = /* @__PURE__ */ new Set();
1315
1315
  const styles = [];
1316
1316
  for (const key in manifest) {
@@ -1325,7 +1325,7 @@ function getCssLinks(manifest, basePath = "") {
1325
1325
  }
1326
1326
  }
1327
1327
  return styles.join("\n");
1328
- }
1328
+ };
1329
1329
  var overrideCSSHMRConsoleError = () => {
1330
1330
  const originalConsoleError = console.error;
1331
1331
  console.error = function(message, ...optionalParams) {
@@ -1337,7 +1337,7 @@ var ensureNonNull = (value, errorMessage) => {
1337
1337
  if (value === void 0 || value === null) throw new Error(errorMessage);
1338
1338
  return value;
1339
1339
  };
1340
- function processTemplate(template) {
1340
+ var processTemplate = (template) => {
1341
1341
  const [headSplit, bodySplit] = template.split(SSRTAG.ssrHead);
1342
1342
  if (typeof bodySplit === "undefined") throw new Error(`Template is missing ${SSRTAG.ssrHead} marker.`);
1343
1343
  const [beforeBody, afterBody] = bodySplit.split(SSRTAG.ssrHtml);
@@ -1348,10 +1348,33 @@ function processTemplate(template) {
1348
1348
  beforeBody: beforeBody.replace(/\s*$/, ""),
1349
1349
  afterBody: afterBody.replace(/^\s*/, "")
1350
1350
  };
1351
- }
1351
+ };
1352
1352
  var rebuildTemplate = (parts, headContent, bodyContent) => {
1353
1353
  return `${parts.beforeHead}${headContent}${parts.afterHead}${parts.beforeBody}${bodyContent}${parts.afterBody}`;
1354
1354
  };
1355
+ var addNonceToInlineScripts = (html, nonce) => {
1356
+ if (!nonce) return html;
1357
+ return html.replace(/<script(?![^>]*\bnonce=)([^>]*)>/g, `<script nonce="${nonce}"$1>`);
1358
+ };
1359
+ var stripDevClientAndStyles = (template) => {
1360
+ return template.replace(/<script type="module" src="\/@vite\/client"><\/script>/g, "").replace(/<style type="text\/css">[\s\S]*?<\/style>/g, "");
1361
+ };
1362
+ var applyViteTransform = async (template, url, viteDevServer) => {
1363
+ return viteDevServer.transformIndexHtml(url, template);
1364
+ };
1365
+ var injectBootstrapModule = (template, bootstrapModule, nonce) => {
1366
+ if (!bootstrapModule) return template;
1367
+ const nonceAttr = nonce ? ` nonce="${nonce}"` : "";
1368
+ return template.replace("</body>", `<script${nonceAttr} type="module" src="${bootstrapModule}" defer></script></body>`);
1369
+ };
1370
+ var injectCssLink = (template, cssLink) => {
1371
+ if (!cssLink) return template;
1372
+ return template.replace("</head>", `${cssLink}</head>`);
1373
+ };
1374
+ var extractHeadInner = (html) => {
1375
+ const m = html.match(/<head[^>]*>([\s\S]*?)<\/head>/i);
1376
+ return (m?.[1] ?? "").trim();
1377
+ };
1355
1378
 
1356
1379
  // src/utils/AssetManager.ts
1357
1380
  var createMaps = () => ({
@@ -1833,6 +1856,53 @@ function createRequestContext(req, reply, baseLogger) {
1833
1856
  return { traceId, logger, headers };
1834
1857
  }
1835
1858
 
1859
+ // src/utils/HandleNotFound.ts
1860
+ var handleNotFound = async (req, reply, processedConfigs, maps, opts = {}) => {
1861
+ const { viteDevServer } = opts;
1862
+ const logger = opts.logger ?? createLogger({
1863
+ debug: opts.debug,
1864
+ context: { component: "handle-not-found", url: req.url, method: req.method, traceId: req.id }
1865
+ });
1866
+ try {
1867
+ if (/\.\w+$/.test(req.raw.url ?? "")) {
1868
+ logger.debug?.("ssr", { url: req.raw.url }, "Delegating asset-like request to Fastify notFound handler");
1869
+ return reply.callNotFound();
1870
+ }
1871
+ const defaultConfig = processedConfigs[0];
1872
+ if (!defaultConfig) {
1873
+ logger.error?.({ configCount: processedConfigs.length, url: req.raw.url }, "No default configuration found");
1874
+ throw AppError.internal("No default configuration found", {
1875
+ details: { configCount: processedConfigs.length, url: req.raw.url }
1876
+ });
1877
+ }
1878
+ const { clientRoot } = defaultConfig;
1879
+ const cspNonce = req.cspNonce ?? void 0;
1880
+ const template = ensureNonNull(maps.templates.get(clientRoot), `Template not found for clientRoot: ${clientRoot}`);
1881
+ const cssLink = maps.cssLinks.get(clientRoot);
1882
+ const bootstrapModule = maps.bootstrapModules.get(clientRoot);
1883
+ let processedTemplate = template.replace(SSRTAG.ssrHead, "").replace(SSRTAG.ssrHtml, "");
1884
+ if (isDevelopment && viteDevServer) {
1885
+ processedTemplate = stripDevClientAndStyles(processedTemplate);
1886
+ const url = req.url ? new URL(req.url, `http://${req.headers.host}`).pathname : "/";
1887
+ processedTemplate = await applyViteTransform(processedTemplate, url, viteDevServer);
1888
+ if (cspNonce) processedTemplate = addNonceToInlineScripts(processedTemplate, cspNonce);
1889
+ } else if (!isDevelopment && cssLink) {
1890
+ processedTemplate = injectCssLink(processedTemplate, cssLink);
1891
+ }
1892
+ processedTemplate = injectBootstrapModule(processedTemplate, bootstrapModule, cspNonce);
1893
+ logger.debug?.("ssr", { status: 200 }, "Sending not-found fallback HTML");
1894
+ const result = reply.status(200).type("text/html").send(processedTemplate);
1895
+ return result;
1896
+ } catch (err) {
1897
+ logger.error?.({ error: err, url: req.url, clientRoot: processedConfigs[0]?.clientRoot }, "handleNotFound failed");
1898
+ throw AppError.internal("handleNotFound failed", err, {
1899
+ stage: "handleNotFound",
1900
+ url: req.url,
1901
+ clientRoot: processedConfigs[0]?.clientRoot
1902
+ });
1903
+ }
1904
+ };
1905
+
1836
1906
  // src/utils/HandleRender.ts
1837
1907
  var handleRender = async (req, reply, routeMatchers, processedConfigs, serviceRegistry, maps, opts = {}) => {
1838
1908
  const { viteDevServer } = opts;
@@ -1849,8 +1919,7 @@ var handleRender = async (req, reply, routeMatchers, processedConfigs, serviceRe
1849
1919
  const rawNonce = req.cspNonce;
1850
1920
  const cspNonce = rawNonce && rawNonce.length > 0 ? rawNonce : void 0;
1851
1921
  if (!matchedRoute) {
1852
- reply.callNotFound();
1853
- return;
1922
+ return reply.callNotFound();
1854
1923
  }
1855
1924
  const { route, params } = matchedRoute;
1856
1925
  const { attr, appId } = route;
@@ -1877,11 +1946,11 @@ var handleRender = async (req, reply, routeMatchers, processedConfigs, serviceRe
1877
1946
  const manifest = maps.manifests.get(clientRoot);
1878
1947
  const preloadLink = maps.preloadLinks.get(clientRoot);
1879
1948
  const ssrManifest = maps.ssrManifests.get(clientRoot);
1949
+ let devHead = "";
1880
1950
  let renderModule;
1881
1951
  if (isDevelopment && viteDevServer) {
1882
1952
  try {
1883
- template = template.replace(/<script type="module" src="\/@vite\/client"><\/script>/g, "");
1884
- template = template.replace(/<style type="text\/css">[\s\S]*?<\/style>/g, "");
1953
+ template = stripDevClientAndStyles(template);
1885
1954
  const entryServerFile = resolveEntryFile(clientRoot, entryServer);
1886
1955
  const entryServerPath = path5.join(clientRoot, entryServerFile);
1887
1956
  const executedModule = await viteDevServer.ssrLoadModule(entryServerPath);
@@ -1889,7 +1958,16 @@ var handleRender = async (req, reply, routeMatchers, processedConfigs, serviceRe
1889
1958
  const styles = await collectStyle(viteDevServer, [entryServerPath]);
1890
1959
  const styleNonce = cspNonce ? ` nonce="${cspNonce}"` : "";
1891
1960
  template = template?.replace("</head>", `<style type="text/css"${styleNonce}>${styles}</style></head>`);
1892
- template = await viteDevServer.transformIndexHtml(url, template);
1961
+ const isStreaming = attr?.render === RENDERTYPE.streaming;
1962
+ if (isStreaming) {
1963
+ const stub = "<!doctype html><html><head></head><body></body></html>";
1964
+ const transformed = await viteDevServer.transformIndexHtml(url, stub);
1965
+ devHead = extractHeadInner(transformed);
1966
+ if (cspNonce) devHead = addNonceToInlineScripts(devHead, cspNonce);
1967
+ } else {
1968
+ template = await applyViteTransform(template, url, viteDevServer);
1969
+ if (cspNonce) template = addNonceToInlineScripts(template, cspNonce);
1970
+ }
1893
1971
  } catch (error) {
1894
1972
  throw AppError.internal("Failed to load dev assets", { cause: error, details: { clientRoot, entryServer, url } });
1895
1973
  }
@@ -2031,7 +2109,9 @@ var handleRender = async (req, reply, routeMatchers, processedConfigs, serviceRe
2031
2109
  writable,
2032
2110
  {
2033
2111
  onHead: (headContent) => {
2034
- let aggregateHeadContent = headContent;
2112
+ let aggregateHeadContent = "";
2113
+ if (devHead) aggregateHeadContent += devHead;
2114
+ aggregateHeadContent += headContent;
2035
2115
  if (ssrManifest && preloadLink) aggregateHeadContent += preloadLink;
2036
2116
  if (manifest && cssLink) aggregateHeadContent += cssLink;
2037
2117
  reply.raw.write(`${templateParts.beforeHead}${aggregateHeadContent}${templateParts.afterHead}${templateParts.beforeBody}`);
@@ -2106,60 +2186,6 @@ var handleRender = async (req, reply, routeMatchers, processedConfigs, serviceRe
2106
2186
  }
2107
2187
  };
2108
2188
 
2109
- // src/utils/HandleNotFound.ts
2110
- var handleNotFound = async (req, reply, processedConfigs, maps, opts = {}) => {
2111
- const logger = opts.logger ?? createLogger({
2112
- debug: opts.debug,
2113
- context: { component: "handle-not-found", url: req.url, method: req.method, traceId: req.id }
2114
- });
2115
- try {
2116
- if (/\.\w+$/.test(req.raw.url ?? "")) {
2117
- logger.debug?.("ssr", { url: req.raw.url }, "Delegating asset-like request to Fastify notFound handler");
2118
- return reply.callNotFound();
2119
- }
2120
- const defaultConfig = processedConfigs[0];
2121
- if (!defaultConfig) {
2122
- logger.error?.({ configCount: processedConfigs.length, url: req.raw.url }, "No default configuration found");
2123
- throw AppError.internal("No default configuration found", {
2124
- details: { configCount: processedConfigs.length, url: req.raw.url }
2125
- });
2126
- }
2127
- const { clientRoot } = defaultConfig;
2128
- const cspNonce = req.cspNonce ?? void 0;
2129
- const template = ensureNonNull(maps.templates.get(clientRoot), `Template not found for clientRoot: ${clientRoot}`);
2130
- const cssLink = maps.cssLinks.get(clientRoot);
2131
- const bootstrapModule = maps.bootstrapModules.get(clientRoot);
2132
- logger.debug?.(
2133
- "ssr",
2134
- {
2135
- clientRoot,
2136
- hasCssLink: !!cssLink,
2137
- hasBootstrapModule: !!bootstrapModule,
2138
- isDevelopment,
2139
- hasCspNonce: !!cspNonce
2140
- },
2141
- "Preparing not-found fallback HTML"
2142
- );
2143
- let processedTemplate = template.replace(SSRTAG.ssrHead, "").replace(SSRTAG.ssrHtml, "");
2144
- if (!isDevelopment && cssLink) {
2145
- processedTemplate = processedTemplate.replace("</head>", `${cssLink}</head>`);
2146
- }
2147
- if (bootstrapModule) {
2148
- const nonceAttr = cspNonce ? ` nonce="${cspNonce}"` : "";
2149
- processedTemplate = processedTemplate.replace("</body>", `<script${nonceAttr} type="module" src="${bootstrapModule}" defer></script></body>`);
2150
- }
2151
- logger.debug?.("ssr", { status: 200 }, "Sending not-found fallback HTML");
2152
- return reply.status(200).type("text/html").send(processedTemplate);
2153
- } catch (err) {
2154
- logger.error?.({ error: err, url: req.url, clientRoot: processedConfigs[0]?.clientRoot }, "handleNotFound failed");
2155
- throw AppError.internal("handleNotFound failed", err, {
2156
- stage: "handleNotFound",
2157
- url: req.url,
2158
- clientRoot: processedConfigs[0]?.clientRoot
2159
- });
2160
- }
2161
- };
2162
-
2163
2189
  // src/utils/StaticAssets.ts
2164
2190
  function normaliseStaticAssets(reg) {
2165
2191
  if (!reg) return [];
@@ -2288,7 +2314,8 @@ var SSRServer = fp3(
2288
2314
  },
2289
2315
  {
2290
2316
  debug: opts.debug,
2291
- logger
2317
+ logger,
2318
+ viteDevServer
2292
2319
  }
2293
2320
  );
2294
2321
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@taujs/server",
3
- "version": "0.5.5",
3
+ "version": "0.5.7",
4
4
  "description": "τjs [ taujs ]",
5
5
  "author": "John Smith | Aoede <taujs@aoede.uk.net> (https://www.aoede.uk.net)",
6
6
  "license": "MIT",
@@ -48,7 +48,7 @@
48
48
  "fastify": "^5.6.1",
49
49
  "fastify-plugin": "^5.1.0",
50
50
  "path-to-regexp": "^8.1.0",
51
- "vite": "^7.1.11"
51
+ "vite": "^7.3.1"
52
52
  },
53
53
  "devDependencies": {
54
54
  "@arethetypeswrong/cli": "^0.15.4",
@@ -66,7 +66,7 @@
66
66
  "peerDependencies": {
67
67
  "fastify": "^5.6.1",
68
68
  "typescript": "^5.5.4",
69
- "vite": "^7.1.11"
69
+ "vite": "^7.3.1"
70
70
  },
71
71
  "scripts": {
72
72
  "build": "tsup",