@taujs/server 0.5.4 → 0.5.6

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 +77 -103
  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
  };
@@ -1352,6 +1352,14 @@ function processTemplate(template) {
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
+ function extractHeadInner(html) {
1360
+ const m = html.match(/<head[^>]*>([\s\S]*?)<\/head>/i);
1361
+ return (m?.[1] ?? "").trim();
1362
+ }
1355
1363
 
1356
1364
  // src/utils/AssetManager.ts
1357
1365
  var createMaps = () => ({
@@ -1833,6 +1841,57 @@ function createRequestContext(req, reply, baseLogger) {
1833
1841
  return { traceId, logger, headers };
1834
1842
  }
1835
1843
 
1844
+ // src/utils/HandleNotFound.ts
1845
+ var handleNotFound = async (req, reply, processedConfigs, maps, opts = {}) => {
1846
+ const { viteDevServer } = opts;
1847
+ const logger = opts.logger ?? createLogger({
1848
+ debug: opts.debug,
1849
+ context: { component: "handle-not-found", url: req.url, method: req.method, traceId: req.id }
1850
+ });
1851
+ try {
1852
+ if (/\.\w+$/.test(req.raw.url ?? "")) {
1853
+ logger.debug?.("ssr", { url: req.raw.url }, "Delegating asset-like request to Fastify notFound handler");
1854
+ return reply.callNotFound();
1855
+ }
1856
+ const defaultConfig = processedConfigs[0];
1857
+ if (!defaultConfig) {
1858
+ logger.error?.({ configCount: processedConfigs.length, url: req.raw.url }, "No default configuration found");
1859
+ throw AppError.internal("No default configuration found", {
1860
+ details: { configCount: processedConfigs.length, url: req.raw.url }
1861
+ });
1862
+ }
1863
+ const { clientRoot } = defaultConfig;
1864
+ const cspNonce = req.cspNonce ?? void 0;
1865
+ const template = ensureNonNull(maps.templates.get(clientRoot), `Template not found for clientRoot: ${clientRoot}`);
1866
+ const cssLink = maps.cssLinks.get(clientRoot);
1867
+ const bootstrapModule = maps.bootstrapModules.get(clientRoot);
1868
+ let processedTemplate = template.replace(SSRTAG.ssrHead, "").replace(SSRTAG.ssrHtml, "");
1869
+ if (isDevelopment && viteDevServer) {
1870
+ processedTemplate = processedTemplate.replace(/<script type="module" src="\/@vite\/client"><\/script>/g, "");
1871
+ processedTemplate = processedTemplate.replace(/<style type="text\/css">[\s\S]*?<\/style>/g, "");
1872
+ const url = req.url ? new URL(req.url, `http://${req.headers.host}`).pathname : "/";
1873
+ processedTemplate = await viteDevServer.transformIndexHtml(url, processedTemplate);
1874
+ if (cspNonce) processedTemplate = processedTemplate.replace(/<script(?![^>]*\bnonce=)([^>]*)>/g, `<script nonce="${cspNonce}"$1>`);
1875
+ } else if (!isDevelopment && cssLink) {
1876
+ processedTemplate = processedTemplate.replace("</head>", `${cssLink}</head>`);
1877
+ }
1878
+ if (bootstrapModule) {
1879
+ const nonceAttr = cspNonce ? ` nonce="${cspNonce}"` : "";
1880
+ processedTemplate = processedTemplate.replace("</body>", `<script${nonceAttr} type="module" src="${bootstrapModule}" defer></script></body>`);
1881
+ }
1882
+ logger.debug?.("ssr", { status: 200 }, "Sending not-found fallback HTML");
1883
+ const result = reply.status(200).type("text/html").send(processedTemplate);
1884
+ return result;
1885
+ } catch (err) {
1886
+ logger.error?.({ error: err, url: req.url, clientRoot: processedConfigs[0]?.clientRoot }, "handleNotFound failed");
1887
+ throw AppError.internal("handleNotFound failed", err, {
1888
+ stage: "handleNotFound",
1889
+ url: req.url,
1890
+ clientRoot: processedConfigs[0]?.clientRoot
1891
+ });
1892
+ }
1893
+ };
1894
+
1836
1895
  // src/utils/HandleRender.ts
1837
1896
  var handleRender = async (req, reply, routeMatchers, processedConfigs, serviceRegistry, maps, opts = {}) => {
1838
1897
  const { viteDevServer } = opts;
@@ -1849,8 +1908,7 @@ var handleRender = async (req, reply, routeMatchers, processedConfigs, serviceRe
1849
1908
  const rawNonce = req.cspNonce;
1850
1909
  const cspNonce = rawNonce && rawNonce.length > 0 ? rawNonce : void 0;
1851
1910
  if (!matchedRoute) {
1852
- reply.callNotFound();
1853
- return;
1911
+ return reply.callNotFound();
1854
1912
  }
1855
1913
  const { route, params } = matchedRoute;
1856
1914
  const { attr, appId } = route;
@@ -1877,6 +1935,7 @@ var handleRender = async (req, reply, routeMatchers, processedConfigs, serviceRe
1877
1935
  const manifest = maps.manifests.get(clientRoot);
1878
1936
  const preloadLink = maps.preloadLinks.get(clientRoot);
1879
1937
  const ssrManifest = maps.ssrManifests.get(clientRoot);
1938
+ let devHead = "";
1880
1939
  let renderModule;
1881
1940
  if (isDevelopment && viteDevServer) {
1882
1941
  try {
@@ -1889,7 +1948,16 @@ var handleRender = async (req, reply, routeMatchers, processedConfigs, serviceRe
1889
1948
  const styles = await collectStyle(viteDevServer, [entryServerPath]);
1890
1949
  const styleNonce = cspNonce ? ` nonce="${cspNonce}"` : "";
1891
1950
  template = template?.replace("</head>", `<style type="text/css"${styleNonce}>${styles}</style></head>`);
1892
- template = await viteDevServer.transformIndexHtml(url, template);
1951
+ const isStreaming = attr?.render === RENDERTYPE.streaming;
1952
+ if (isStreaming) {
1953
+ const stub = "<!doctype html><html><head></head><body></body></html>";
1954
+ const transformed = await viteDevServer.transformIndexHtml(url, stub);
1955
+ devHead = extractHeadInner(transformed);
1956
+ if (cspNonce) devHead = devHead.replace(/<script(?![^>]*\bnonce=)([^>]*)>/g, `<script nonce="${cspNonce}"$1>`);
1957
+ } else {
1958
+ template = await viteDevServer.transformIndexHtml(url, template);
1959
+ if (cspNonce) template = addNonceToInlineScripts(template, cspNonce);
1960
+ }
1893
1961
  } catch (error) {
1894
1962
  throw AppError.internal("Failed to load dev assets", { cause: error, details: { clientRoot, entryServer, url } });
1895
1963
  }
@@ -2031,7 +2099,9 @@ var handleRender = async (req, reply, routeMatchers, processedConfigs, serviceRe
2031
2099
  writable,
2032
2100
  {
2033
2101
  onHead: (headContent) => {
2034
- let aggregateHeadContent = headContent;
2102
+ let aggregateHeadContent = "";
2103
+ if (devHead) aggregateHeadContent += devHead;
2104
+ aggregateHeadContent += headContent;
2035
2105
  if (ssrManifest && preloadLink) aggregateHeadContent += preloadLink;
2036
2106
  if (manifest && cssLink) aggregateHeadContent += cssLink;
2037
2107
  reply.raw.write(`${templateParts.beforeHead}${aggregateHeadContent}${templateParts.afterHead}${templateParts.beforeBody}`);
@@ -2106,86 +2176,6 @@ var handleRender = async (req, reply, routeMatchers, processedConfigs, serviceRe
2106
2176
  }
2107
2177
  };
2108
2178
 
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
- // src/core/routes/ResolveRouteData.ts
2164
- async function resolveRouteDataCore(url, opts) {
2165
- const match2 = matchRoute(url, opts.routeMatchers);
2166
- if (!match2) {
2167
- throw AppError.notFound("route_not_found", { details: { url } });
2168
- }
2169
- const { route, params } = match2;
2170
- if (!route.attr?.data) {
2171
- throw AppError.notFound("no_data_handler", {
2172
- details: { url, path: route.path, appId: route.appId }
2173
- });
2174
- }
2175
- const ctx = opts.getCtx();
2176
- return fetchInitialData(route.attr, params, opts.serviceRegistry, ctx);
2177
- }
2178
-
2179
- // src/utils/ResolveRouteData.ts
2180
- async function resolveRouteData(url, opts) {
2181
- const { req, reply, routeMatchers, serviceRegistry, logger } = opts;
2182
- return resolveRouteDataCore(url, {
2183
- routeMatchers,
2184
- serviceRegistry,
2185
- getCtx: () => createRequestContext(req, reply, logger)
2186
- });
2187
- }
2188
-
2189
2179
  // src/utils/StaticAssets.ts
2190
2180
  function normaliseStaticAssets(reg) {
2191
2181
  if (!reg) return [];
@@ -2295,23 +2285,6 @@ var SSRServer = fp3(
2295
2285
  viteDevServer = await setupDevServer(app, clientRoot, alias, opts.debug, opts.devNet, plugins);
2296
2286
  }
2297
2287
  app.addHook("onRequest", createAuthHook(routeMatchers, logger));
2298
- app.get("/__taujs/route", async (req, reply) => {
2299
- const query = req.query;
2300
- const url = typeof query.url === "string" ? query.url : "";
2301
- if (!url) {
2302
- throw AppError.badRequest("url query param required", {
2303
- details: { query }
2304
- });
2305
- }
2306
- const data = await resolveRouteData(url, {
2307
- req,
2308
- reply,
2309
- routeMatchers,
2310
- serviceRegistry,
2311
- logger
2312
- });
2313
- return reply.status(200).send({ data });
2314
- });
2315
2288
  app.get("/*", async (req, reply) => {
2316
2289
  await handleRender(req, reply, routeMatchers, processedConfigs, serviceRegistry, maps, {
2317
2290
  debug: opts.debug,
@@ -2331,7 +2304,8 @@ var SSRServer = fp3(
2331
2304
  },
2332
2305
  {
2333
2306
  debug: opts.debug,
2334
- logger
2307
+ logger,
2308
+ viteDevServer
2335
2309
  }
2336
2310
  );
2337
2311
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@taujs/server",
3
- "version": "0.5.4",
3
+ "version": "0.5.6",
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",