@nifrajs/web 2.4.0 → 2.6.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.
Files changed (48) hide show
  1. package/dist/build.d.ts.map +1 -1
  2. package/dist/build.js +18 -9
  3. package/dist/build.js.map +1 -1
  4. package/dist/fonts-google.d.ts.map +1 -1
  5. package/dist/fonts-google.js +84 -16
  6. package/dist/fonts-google.js.map +1 -1
  7. package/dist/index.d.ts +27 -0
  8. package/dist/index.d.ts.map +1 -1
  9. package/dist/index.js +101 -58
  10. package/dist/index.js.map +1 -1
  11. package/dist/internal/js-string.d.ts +9 -0
  12. package/dist/internal/js-string.d.ts.map +1 -0
  13. package/dist/internal/js-string.js +18 -0
  14. package/dist/internal/js-string.js.map +1 -0
  15. package/dist/internal/server-boundary.d.ts.map +1 -1
  16. package/dist/internal/server-boundary.js +41 -7
  17. package/dist/internal/server-boundary.js.map +1 -1
  18. package/dist/manifest.d.ts.map +1 -1
  19. package/dist/manifest.js +4 -1
  20. package/dist/manifest.js.map +1 -1
  21. package/dist/plugins/svg.d.ts +9 -0
  22. package/dist/plugins/svg.d.ts.map +1 -1
  23. package/dist/plugins/svg.js +39 -5
  24. package/dist/plugins/svg.js.map +1 -1
  25. package/dist/prerender.d.ts.map +1 -1
  26. package/dist/prerender.js +10 -2
  27. package/dist/prerender.js.map +1 -1
  28. package/dist/router.d.ts.map +1 -1
  29. package/dist/router.js +13 -2
  30. package/dist/router.js.map +1 -1
  31. package/dist/service-worker.d.ts.map +1 -1
  32. package/dist/service-worker.js +2 -1
  33. package/dist/service-worker.js.map +1 -1
  34. package/dist/vite.d.ts.map +1 -1
  35. package/dist/vite.js +58 -1
  36. package/dist/vite.js.map +1 -1
  37. package/package.json +3 -2
  38. package/src/build.ts +17 -9
  39. package/src/fonts-google.ts +73 -15
  40. package/src/index.ts +135 -67
  41. package/src/internal/js-string.ts +19 -0
  42. package/src/internal/server-boundary.ts +40 -7
  43. package/src/manifest.ts +4 -1
  44. package/src/plugins/svg.ts +37 -5
  45. package/src/prerender.ts +10 -2
  46. package/src/router.ts +13 -2
  47. package/src/service-worker.ts +3 -1
  48. package/src/vite.ts +59 -1
package/dist/vite.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"vite.js","sourceRoot":"","sources":["../src/vite.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"vite.js","sourceRoot":"","sources":["../src/vite.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nifrajs/web",
3
- "version": "2.4.0",
3
+ "version": "2.6.0",
4
4
  "description": "Framework-agnostic SSR core for nifra - the render seam + HTML document orchestration.",
5
5
  "keywords": [
6
6
  "bun",
@@ -171,7 +171,7 @@
171
171
  "access": "public"
172
172
  },
173
173
  "dependencies": {
174
- "@nifrajs/core": "2.4.0"
174
+ "@nifrajs/core": "2.6.0"
175
175
  },
176
176
  "peerDependencies": {
177
177
  "sass": "^1.0.0",
@@ -189,6 +189,7 @@
189
189
  "@nifrajs/client": "workspace:*",
190
190
  "@nifrajs/schema": "workspace:*",
191
191
  "@nifrajs/test-utils": "workspace:*",
192
+ "@nifrajs/web-react": "workspace:*",
192
193
  "sass": "^1.77.0",
193
194
  "vite": "^8.0.0"
194
195
  },
package/src/build.ts CHANGED
@@ -787,7 +787,9 @@ export interface ManifestDrift {
787
787
  // The route-relative specifiers the generated manifest imports. Both shapes `generateServerManifest`
788
788
  // emits are matched: eager `import * as m0 from "./routes/x.tsx"` and lazy `() => import("./routes/x")`.
789
789
  // Captures the path inside the quotes; the caller strips the routes-dir prefix to compare with discovery.
790
- const MANIFEST_IMPORT = /(?:import\s+\*\s+as\s+\w+\s+from|import)\s*\(?\s*["']([^"']+)["']\)?/g
790
+ // `\s*(?:\(\s*)?` rather than `\s*\(?\s*`: two adjacent unbounded whitespace runs with an optional
791
+ // token between them are ambiguous, and that ambiguity backtracks quadratically on a long space run.
792
+ const MANIFEST_IMPORT = /(?:import\s+\*\s+as\s+\w+\s+from|import)\s*(?:\(\s*)?["']([^"']+)["']\)?/g
791
793
  // The baked client-entry line: `export const clientEntry = "…"`.
792
794
  const MANIFEST_CLIENT_ENTRY = /export\s+const\s+clientEntry\s*=\s*["']([^"']+)["']/
793
795
 
@@ -814,12 +816,18 @@ export function parseManifestClientEntry(source: string): string | undefined {
814
816
  }
815
817
 
816
818
  // The baked asset lines `generateServerManifest` emits: `export const styles = […]` then
817
- // `export const routeStyles = {…}`, each a JSON literal followed by the next `export const`. The capture
818
- // is `[\s\S]*?` (multi-line, non-greedy up to the following `export const`) NOT `.+` - a committed
819
- // manifest carries no format-ignore pragma, so a formatter can wrap a long `routeStyles` map across lines;
820
- // a single-line regex would then miss it and silently DROP every baked stylesheet on re-sync.
821
- const MANIFEST_STYLES = /export const styles = ([\s\S]*?)\nexport const /
822
- const MANIFEST_ROUTE_STYLES = /export const routeStyles = ([\s\S]*?)\nexport const /
819
+ // `export const routeStyles = {…}`, each a JSON literal running to the next `export const`. Extracted
820
+ // with `indexOf` slicing rather than a lazy `[\s\S]*?` regex: the slice is multi-line by nature (a
821
+ // formatter can wrap a long `routeStyles` map, and missing it would silently DROP every baked
822
+ // stylesheet on re-sync), and a lazy scan re-walks the file per unterminated opener - quadratic.
823
+ function bakedManifestLiteral(source: string, name: string): string | undefined {
824
+ const opener = `export const ${name} = `
825
+ const start = source.indexOf(opener)
826
+ if (start === -1) return undefined
827
+ const from = start + opener.length
828
+ const end = source.indexOf("\nexport const ", from)
829
+ return end === -1 ? undefined : source.slice(from, end)
830
+ }
823
831
 
824
832
  /** Parse a baked JSON literal captured from a committed manifest, tolerating a formatter's TRAILING COMMAS
825
833
  * (biome/prettier add one when wrapping a multi-line array/object; strict `JSON.parse` would reject it).
@@ -830,7 +838,7 @@ function parseManifestLiteral(raw: string): unknown {
830
838
 
831
839
  /** The baked top-level `styles` array in a committed server-manifest (empty if absent/unparseable). Pure. */
832
840
  export function parseManifestStyles(source: string): string[] {
833
- const raw = MANIFEST_STYLES.exec(source)?.[1]
841
+ const raw = bakedManifestLiteral(source, "styles")
834
842
  if (raw === undefined) return []
835
843
  try {
836
844
  const value = parseManifestLiteral(raw)
@@ -842,7 +850,7 @@ export function parseManifestStyles(source: string): string[] {
842
850
 
843
851
  /** The baked per-route `routeStyles` map in a committed server-manifest (empty if absent/unparseable). Pure. */
844
852
  export function parseManifestRouteStyles(source: string): Record<string, string[]> {
845
- const raw = MANIFEST_ROUTE_STYLES.exec(source)?.[1]
853
+ const raw = bakedManifestLiteral(source, "routeStyles")
846
854
  if (raw === undefined) return {}
847
855
  try {
848
856
  const value = parseManifestLiteral(raw)
@@ -212,30 +212,87 @@ export function googleFontsCssUrl(options: GoogleFontOptions): string {
212
212
  return `${CSS2_ENDPOINT}?${params.join("&")}`
213
213
  }
214
214
 
215
- const FACE_RE = /(?:\/\*([^*]*)\*\/\s*)?@font-face\s*\{([^}]*)\}/g
216
- const SRC_RE = /url\(\s*(['"]?)([^'")]+)\1\s*\)(?:\s*format\(\s*(['"]?)([^'")]+)\3\s*\))?/g
215
+ // The stylesheet is REMOTE input (Google's CDN, but still an upstream), so the whole parse is
216
+ // forward index scans - no unanchored regex runs on it, and no shape can backtrack polynomially on
217
+ // an adversarial response.
218
+
219
+ /** The `/* subset *​/` label immediately preceding a `@font-face` block (only whitespace between),
220
+ * scanned by index in the gap since the previous block. */
221
+ function subsetLabelBefore(css: string, faceStart: number, prevEnd: number): string | undefined {
222
+ const between = css.slice(prevEnd, faceStart)
223
+ const open = between.lastIndexOf("/*")
224
+ if (open === -1) return undefined
225
+ const close = between.indexOf("*/", open + 2)
226
+ if (close === -1 || between.slice(close + 2).trim() !== "") return undefined
227
+ return between.slice(open + 2, close)
228
+ }
217
229
 
230
+ /** The value of `prop: value;` inside a declaration body, by case-insensitive index scan. */
218
231
  function declOf(body: string, prop: string): string | undefined {
219
- const m = body.match(new RegExp(`${prop}\\s*:\\s*([^;]+);`, "i"))
220
- return m?.[1]?.trim()
232
+ const lower = body.toLowerCase()
233
+ const needle = prop.toLowerCase()
234
+ for (let at = lower.indexOf(needle); at !== -1; at = lower.indexOf(needle, at + 1)) {
235
+ let i = at + needle.length
236
+ while (i < body.length && (body[i] === " " || body[i] === "\t" || body[i] === "\n")) i++
237
+ if (body[i] !== ":") continue
238
+ i++
239
+ const end = body.indexOf(";", i)
240
+ if (end === -1) continue // unterminated declaration - same as the semicolon-requiring regex
241
+ return body.slice(i, end).trim()
242
+ }
243
+ return undefined
244
+ }
245
+
246
+ /** Strip one level of matching quotes. */
247
+ function unquote(value: string): string {
248
+ const first = value[0]
249
+ return (first === '"' || first === "'") && value.endsWith(first) && value.length > 1
250
+ ? value.slice(1, -1)
251
+ : value
252
+ }
253
+
254
+ /** Every `url(…)` (with optional trailing `format(…)`) in a declaration body, by index scan. */
255
+ function parseSrc(body: string): { url: string; format?: string }[] {
256
+ const src: { url: string; format?: string }[] = []
257
+ for (let at = body.indexOf("url("); at !== -1; at = body.indexOf("url(", at + 1)) {
258
+ const close = body.indexOf(")", at + 4)
259
+ if (close === -1) break
260
+ const url = unquote(body.slice(at + 4, close).trim())
261
+ if (url === "") continue
262
+ let cursor = close + 1
263
+ while (cursor < body.length && (body[cursor] === " " || body[cursor] === "\t")) cursor++
264
+ let format: string | undefined
265
+ if (body.startsWith("format(", cursor)) {
266
+ const formatClose = body.indexOf(")", cursor + 7)
267
+ if (formatClose !== -1) format = unquote(body.slice(cursor + 7, formatClose).trim())
268
+ }
269
+ src.push(format === undefined || format === "" ? { url } : { url, format })
270
+ }
271
+ return src
221
272
  }
222
273
 
223
274
  /** Parse Google's stylesheet into structured faces, capturing the `/* subset *​/` label that precedes
224
275
  * each `@font-face`. Pure - exported so callers can run their own download/write pipeline. */
225
276
  export function parseGoogleFontCss(css: string): ParsedFontFace[] {
226
277
  const faces: ParsedFontFace[] = []
227
- for (const match of css.matchAll(FACE_RE)) {
228
- const subset = (match[1] ?? "").trim() || "default"
229
- const body = match[2] ?? ""
278
+ let prevEnd = 0
279
+ // The next-`{` position is memoized: without it, a crafted response of N at-rules ahead of one
280
+ // late brace re-scans for that brace N times - the quadratic shape this parser exists to avoid.
281
+ let openMemo = -1
282
+ for (let at = css.indexOf("@font-face"); at !== -1; at = css.indexOf("@font-face", at + 1)) {
283
+ if (openMemo < at + 10) openMemo = css.indexOf("{", at + 10)
284
+ const open = openMemo
285
+ if (open === -1) break
286
+ if (css.slice(at + 10, open).trim() !== "") continue // not this at-rule's block
287
+ const closeBrace = css.indexOf("}", open + 1)
288
+ if (closeBrace === -1) break
289
+ const subset = (subsetLabelBefore(css, at, prevEnd) ?? "").trim() || "default"
290
+ prevEnd = closeBrace + 1
291
+ const body = css.slice(open + 1, closeBrace)
230
292
  const familyRaw = declOf(body, "font-family")
231
293
  if (familyRaw === undefined) continue
232
- const family = familyRaw.replace(/^['"]|['"]$/g, "")
233
- const src: { url: string; format?: string }[] = []
234
- for (const s of body.matchAll(SRC_RE)) {
235
- const url = s[2]
236
- if (url === undefined) continue
237
- src.push(s[4] === undefined ? { url } : { url, format: s[4] })
238
- }
294
+ const family = unquote(familyRaw)
295
+ const src = parseSrc(body)
239
296
  if (src.length === 0) continue
240
297
  const unicodeRange = declOf(body, "unicode-range")
241
298
  faces.push({
@@ -316,7 +373,8 @@ export async function loadGoogleFont(
316
373
  const family = validateFamily(options.family)
317
374
  const fetchImpl = io.fetch ?? fetch
318
375
  const writeFile = io.writeFile ?? defaultWriteFile
319
- const publicPath = (io.publicPath ?? "/fonts").replace(/\/+$/, "")
376
+ let publicPath = io.publicPath ?? "/fonts"
377
+ while (publicPath.endsWith("/")) publicPath = publicPath.slice(0, -1)
320
378
  const maxBytes = io.maxBytesPerFile ?? DEFAULT_MAX_FONT_BYTES
321
379
  const wantedSubsets = options.subsets?.map(validateSubset)
322
380
 
package/src/index.ts CHANGED
@@ -25,6 +25,7 @@ import {
25
25
  } from "./deferred.ts"
26
26
  import { isDraftEnabled } from "./draft.ts"
27
27
  import { trustedHeadAttributes } from "./internal/head-attributes.ts"
28
+ import { jsStringLiteral } from "./internal/js-string.ts"
28
29
  import { EXECUTABLE_SCRIPT_TYPES, INERT_SCRIPT_TYPES } from "./internal/script-types.ts"
29
30
  import { ISR_REVALIDATE_HEADER } from "./isr.ts"
30
31
  import { generateLlmsTxt } from "./llms-txt.ts"
@@ -478,6 +479,34 @@ export interface RenderPageOptions {
478
479
  readonly islandScripts?: readonly string[]
479
480
  /** CSP nonce applied to every framework-owned executable script in this document. */
480
481
  readonly nonce?: string
482
+ /**
483
+ * Advanced: a per-route slot the renderer fills with the request-invariant document pieces (shell
484
+ * prefix/suffix, tail statics) on the first render and reuses afterwards, skipping their re-assembly.
485
+ *
486
+ * Only pass a cache when every shell-shaping input is IDENTICAL across the requests sharing it:
487
+ * same `head` content (a static meta chain - never a `meta(data)` function), `title`, `styles`,
488
+ * `preload`, `islandScripts`, `clientEntry`, `rootId`, `hydrate`, and `prerenderedPaths`. Per-request
489
+ * values (`data`, `params`, `search`, `actionData`, `layoutData`, deferred state) are always assembled
490
+ * fresh and safe. A per-request `nonce` disables the cache automatically. `createWebApp` wires this
491
+ * per route, gated on the route + layout metas being static.
492
+ */
493
+ readonly assemblyCache?: RenderAssemblyCache
494
+ }
495
+
496
+ /** The mutable per-route slot {@link RenderPageOptions.assemblyCache} fills. Opaque - create as `{}`. */
497
+ export interface RenderAssemblyCache {
498
+ /** Shell up to (not including) the deferred-runtime insertion point. */
499
+ shellPre?: string
500
+ /** Shell from after the deferred-runtime insertion point through the open `#root` container. */
501
+ shellPost?: string
502
+ /** Tail opener: the inline script open tag + the route-id global (before the action global). */
503
+ tailPre?: string
504
+ /** Tail mid: the prerendered-paths global (between the action and layout-data globals). */
505
+ tailMid?: string
506
+ /** Tail data prefix: the `window.<data global>=` assignment head. */
507
+ tailData?: string
508
+ /** Tail from after the serialized data through `</html>`. */
509
+ tailPost?: string
481
510
  }
482
511
 
483
512
  /**
@@ -554,7 +583,12 @@ export function renderPageResult(options: RenderPageInput): MaybePromise<Rendere
554
583
  actionData === undefined
555
584
  ? undefined
556
585
  : prepareDeferred(actionData, deferred.length + layoutDeferred.length)
557
- const allDeferred = [...deferred, ...layoutDeferred, ...(actionSplit ? actionSplit.deferred : [])]
586
+ // On the common page-only path (no layout loader, no action) reuse `deferred` directly instead of
587
+ // allocating a fresh spread array every request.
588
+ const allDeferred =
589
+ layoutDeferred.length === 0 && actionSplit === undefined
590
+ ? deferred
591
+ : [...deferred, ...layoutDeferred, ...(actionSplit ? actionSplit.deferred : [])]
558
592
  // Omitted entirely when no layout has a loader - a page-only app emits exactly what it did before.
559
593
  const layoutTail =
560
594
  options.layoutData === undefined
@@ -568,71 +602,83 @@ export function renderPageResult(options: RenderPageInput): MaybePromise<Rendere
568
602
  : `window.${ACTION_GLOBAL}=${serializeData(actionSplit.forClient)};`
569
603
  const deferredRuntime =
570
604
  allDeferred.length > 0 ? `<script${nonceAttr}>${DEFERRED_RUNTIME}</script>` : ""
571
- // Matched-route chunk preloads, concatenated directly (skip the `filter().map()`
572
- // intermediate arrays - and the whole loop - on the common no-extra-preload render). De-duped
573
- // against the entry, which is preloaded separately below.
574
- let preloadLinks = ""
575
- if (preload.length > 0) {
605
+ // The regex only injects the CSP nonce into the (constant) hydration head; with no nonce it's a
606
+ // no-op that still scans the whole script every request. Skip it on the common no-nonce path.
607
+ // The request-invariant document pieces. With a caller-supplied per-route cache (and no per-request
608
+ // nonce, which would bake into them) they're built once and reused; the per-request seams - the
609
+ // deferred runtime in the shell, the action/layout-data globals and the serialized loader data in
610
+ // the tail - are always assembled fresh. Byte-identical to building the whole document inline.
611
+ const slot: RenderAssemblyCache =
612
+ nonce === undefined && options.assemblyCache !== undefined ? options.assemblyCache : {}
613
+ if (slot.shellPre === undefined) {
614
+ // Matched-route chunk preloads, concatenated directly. De-duped against the entry, which is
615
+ // preloaded separately below.
616
+ let preloadLinks = ""
576
617
  for (const url of preload) {
577
618
  if (url !== clientEntry)
578
619
  preloadLinks += `<link rel="modulepreload" href="${escapeAttr(url)}">`
579
620
  }
621
+ // The matched route's stylesheets - `<link rel="stylesheet">` in `<head>` so CSS arrives with the
622
+ // first paint (no FOUC). Render-blocking by design, and emitted regardless of `hydrate` (a static
623
+ // or `_error` page still wants its styles). In dev (Vite) CSS is injected client-side instead.
624
+ let styleLinks = ""
625
+ for (const url of styles) styleLinks += `<link rel="stylesheet" href="${escapeAttr(url)}">`
626
+ // Island bundles are referenced only by a `<script type="module">` at the END of `<body>`, so the
627
+ // browser doesn't discover them until the whole page is parsed. `modulepreload` them in `<head>`
628
+ // so the fetch starts immediately, in parallel with parsing - regardless of `hydrate`.
629
+ let islandPreloads = ""
630
+ for (const src of islandScripts)
631
+ islandPreloads += `<link rel="modulepreload" href="${escapeAttr(src)}">`
632
+ // Runs in the first-paint→hydration window to swallow a JS-only form's broken native submit. Only
633
+ // on a hydrating page (a static/_error page has no client handlers, so no footgun).
634
+ const hydrationGuard = hydrate ? `<script${nonceAttr}>${PRE_HYDRATION_GUARD}</script>` : ""
635
+ // `<html>` attributes. `lang` defaults to `"en"`; `dir` is omitted entirely when unset, which IS
636
+ // HTML's `ltr` default. Both attribute-escaped. `client.ts`'s `applyHead` mirrors this exact
637
+ // defaulting on soft-nav, so a hard load and a client navigation produce the same `<html>`.
638
+ const htmlAttrs = ` lang="${escapeAttr(head?.lang ?? "en")}"${head?.dir === undefined ? "" : ` dir="${escapeAttr(head.dir)}"`}`
639
+ // Marks the container for the client entry when the id is not the one the entry falls back to.
640
+ const rootMarker = rootId === "root" ? "" : ` ${ROOT_ATTRIBUTE}`
641
+ const rawHydrationHead = adapter.hydrationHead(nonce)
642
+ const hydrationHead =
643
+ nonce === undefined
644
+ ? rawHydrationHead
645
+ : rawHydrationHead.replace(/<script(?![^>]*\bnonce=)(?=[\s>])/g, `<script${nonceAttr}`)
646
+ // Shell up to the deferred-runtime seam: on a hydrating page that seam sits after the entry +
647
+ // route-chunk preloads; a non-hydrating page has no runtime insertion at all.
648
+ const entryPreloads = hydrate
649
+ ? `<link rel="modulepreload" href="${escapeAttr(clientEntry ?? "")}">${preloadLinks}`
650
+ : ""
651
+ slot.shellPre = `<!doctype html><html${htmlAttrs}><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1">${hydrationGuard}<title>${escapeHtml(head?.title ?? title)}</title>${headTags(head)}${styleLinks}${entryPreloads}`
652
+ slot.shellPost = `${islandPreloads}${hydrationHead}</head><body><div id="${escapeAttr(rootId)}"${rootMarker}>`
653
+ // Island bundles load regardless of `hydrate` - a static page (hydrate:false) ships no framework
654
+ // client but can still mount no-framework islands (`@nifrajs/web/islands`).
655
+ let islandTags = ""
656
+ for (const src of islandScripts)
657
+ islandTags += `<script type="module" src="${escapeAttr(src)}"${nonceAttr}></script>`
658
+ if (hydrate) {
659
+ slot.tailPre = `<script${nonceAttr}>${route}`
660
+ slot.tailMid = prerendered
661
+ slot.tailData = `window.${DATA_GLOBAL}=`
662
+ slot.tailPost = `</script><script type="module" src="${escapeAttr(clientEntry ?? "")}"${nonceAttr}></script>${islandTags}</body></html>`
663
+ } else {
664
+ slot.tailPre = ""
665
+ slot.tailMid = ""
666
+ slot.tailData = ""
667
+ slot.tailPost = `${islandTags}</body></html>`
668
+ }
580
669
  }
581
- // The matched route's stylesheets - `<link rel="stylesheet">` in `<head>` so CSS arrives with the
582
- // first paint (no FOUC). Render-blocking by design, and emitted regardless of `hydrate` (a static or
583
- // `_error` page still wants its styles). In dev (Vite) CSS is injected client-side instead, so
584
- // `styles` is empty there.
585
- let styleLinks = ""
586
- for (const url of styles) styleLinks += `<link rel="stylesheet" href="${escapeAttr(url)}">`
587
- // Island bundles are referenced only by a `<script type="module">` at the END of `<body>` (below), so
588
- // the browser doesn't discover them until the whole page is parsed. `modulepreload` them in `<head>`
589
- // so the fetch starts immediately, in parallel with parsing - regardless of `hydrate` (an island page
590
- // is typically hydrate:false). Without this, a heavy island bundle on a cold first load leaves its
591
- // server-rendered placeholder visible until that late, un-prefetched fetch lands ("stuck loading").
592
- let islandPreloads = ""
593
- for (const src of islandScripts)
594
- islandPreloads += `<link rel="modulepreload" href="${escapeAttr(src)}">`
595
- // Shell - flushed before the app finishes rendering: `<head>` (title, meta, hydration head) + the
596
- // open container. `modulepreload` of the client entry - plus the matched route's own chunks
597
- // (`preloadLinks`) - lets the JS download while the body streams. One template literal (no
598
- // intermediate array + `join`) - byte-identical to the prior output.
599
- // A non-hydrated page (e.g. an `_error` boundary) omits the client-entry preload, route-chunk
600
- // preloads, and deferred runtime - there's no client takeover to feed.
601
- const hydrationLinks = hydrate
602
- ? `<link rel="modulepreload" href="${escapeAttr(clientEntry ?? "")}">${preloadLinks}${deferredRuntime}`
603
- : ""
604
- // Runs in the first-paint→hydration window to swallow a JS-only form's broken native submit. Only on a
605
- // hydrating page (a static/_error page has no client handlers, so no footgun).
606
- const hydrationGuard = hydrate ? `<script${nonceAttr}>${PRE_HYDRATION_GUARD}</script>` : ""
607
- // `<html>` attributes. `lang` defaults to `"en"` (so an app that never sets it is byte-identical to
608
- // before); `dir` is omitted entirely when unset, which IS HTML's `ltr` default - emitting it
609
- // unconditionally would change every existing app's output for no gain. Both attribute-escaped.
610
- // `client.ts`'s `applyHead` mirrors this exact defaulting on soft-nav, so a hard load and a client
611
- // navigation to the same URL produce the same `<html>` (no drift on a multilingual site).
612
- const htmlAttrs = ` lang="${escapeAttr(head?.lang ?? "en")}"${head?.dir === undefined ? "" : ` dir="${escapeAttr(head.dir)}"`}`
613
- // Marks the container for the client entry when the id is not the one the entry falls back to. A
614
- // static attribute name with no value, so `rootId` never reaches the markup twice and there is
615
- // nothing here to escape. Omitted on the default so existing output is unchanged.
616
- const rootMarker = rootId === "root" ? "" : ` ${ROOT_ATTRIBUTE}`
617
- const hydrationHead = adapter
618
- .hydrationHead(nonce)
619
- .replace(/<script(?![^>]*\bnonce=)(?=[\s>])/g, `<script${nonceAttr}`)
620
- const shellHtml = `<!doctype html><html${htmlAttrs}><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1">${hydrationGuard}<title>${escapeHtml(head?.title ?? title)}</title>${headTags(head)}${styleLinks}${hydrationLinks}${islandPreloads}${hydrationHead}</head><body><div id="${escapeAttr(rootId)}"${rootMarker}>`
670
+ // The deferred runtime rides only on a hydrating page (a static page has no client takeover), and
671
+ // only when something actually deferred - matching the pre-cache emission exactly.
672
+ const runtimeSeam = hydrate && allDeferred.length > 0 ? deferredRuntime : ""
673
+ const shellHtml = `${slot.shellPre}${runtimeSeam}${slot.shellPost}`
621
674
  // Closes the hydration container; deferred resolve scripts go AFTER it (outside `#root`) so they
622
675
  // aren't part of the adapter's hydrated tree (an inline script inside it breaks hydration).
623
676
  const closeRootHtml = "</div>"
624
677
  // Tail - the loader-data globals + the client module. Module scripts defer (run after parse), so
625
678
  // the data global + every streamed deferred resolution are set before the entry hydrates.
626
- // Island bundles load regardless of `hydrate` - a static page (hydrate:false) ships no framework
627
- // client but can still mount no-framework islands (`@nifrajs/web/islands`).
628
- let islandTags = ""
629
- for (const src of islandScripts)
630
- islandTags += `<script type="module" src="${escapeAttr(src)}"${nonceAttr}></script>`
631
- const tailHtml = `${
632
- hydrate
633
- ? `<script${nonceAttr}>${route}${action}${prerendered}${layoutTail}window.${DATA_GLOBAL}=${serializeData(forClient)}</script><script type="module" src="${escapeAttr(clientEntry ?? "")}"${nonceAttr}></script>`
634
- : ""
635
- }${islandTags}</body></html>`
679
+ const tailHtml = hydrate
680
+ ? `${slot.tailPre}${action}${slot.tailMid}${layoutTail}${slot.tailData}${serializeData(forClient)}${slot.tailPost}`
681
+ : (slot.tailPost as string)
636
682
  const headers: Record<string, string> = { "content-type": "text/html; charset=utf-8" }
637
683
  // Caller-supplied headers (a terminal status page's `cache-control`, say). Applied before the
638
684
  // framework's own below, so `content-type` and the ISR channel stay authoritative - a caller must
@@ -1987,6 +2033,30 @@ export function createWebApp<Env = unknown>(
1987
2033
  // A dynamic route whose `getStaticPaths` declared `fallback: "404"` - only its prerendered paths
1988
2034
  // exist; anything else 404s (computed once per route, not per request).
1989
2035
  const is404Fallback = options.staticFallbacks?.[route.pattern] === "404"
2036
+ // Per-route document-assembly cache (see RenderAssemblyCache): filled on the first GET render and
2037
+ // reused while the route + layout MODULE IDENTITIES are unchanged. Attached only when every meta
2038
+ // in the chain is static - a `meta(data)` function makes the head per-request, so those routes
2039
+ // always assemble fresh. A module reload (dev HMR) yields new module objects, dropping the slot.
2040
+ let assemblySlot: RenderAssemblyCache | undefined
2041
+ let assemblySlotMod: unknown
2042
+ let assemblySlotLayouts: LoadedLayoutModules | undefined
2043
+ const assemblyCacheFor = (
2044
+ mod: RouteModule,
2045
+ lms: LoadedLayoutModules,
2046
+ ): { assemblyCache: RenderAssemblyCache } | Record<string, never> => {
2047
+ if (typeof mod.meta === "function") return {}
2048
+ for (const m of lms) if (typeof m.meta === "function") return {}
2049
+ const layoutsUnchanged =
2050
+ assemblySlotLayouts !== undefined &&
2051
+ assemblySlotLayouts.length === lms.length &&
2052
+ assemblySlotLayouts.every((m, i) => m === lms[i])
2053
+ if (assemblySlotMod !== mod || !layoutsUnchanged) {
2054
+ assemblySlot = {}
2055
+ assemblySlotMod = mod
2056
+ assemblySlotLayouts = lms
2057
+ }
2058
+ return { assemblyCache: assemblySlot as RenderAssemblyCache }
2059
+ }
1990
2060
  app.register("GET", route.pattern, undefined, async (c: RouteContext) => {
1991
2061
  // Enforce `fallback: "404"` before any work: an unlisted path under this route doesn't exist.
1992
2062
  // Covers hard navigation directly; a client soft-nav's data fetch gets the 404, throws, and the
@@ -2095,15 +2165,12 @@ export function createWebApp<Env = unknown>(
2095
2165
  headers: { "content-type": "application/x-ndjson; charset=utf-8" },
2096
2166
  })
2097
2167
  }
2098
- const { chain, head } = resolveChainAndHead(
2099
- layoutModules ?? (await loadLayoutModules(route)),
2100
- mod,
2101
- {
2102
- data,
2103
- params: c.params,
2104
- origin: originOf(c.req),
2105
- },
2106
- )
2168
+ const chainLayoutModules = layoutModules ?? (await loadLayoutModules(route))
2169
+ const { chain, head } = resolveChainAndHead(chainLayoutModules, mod, {
2170
+ data,
2171
+ params: c.params,
2172
+ origin: originOf(c.req),
2173
+ })
2107
2174
  const hydrateRoute = mod.hydrate !== false
2108
2175
  try {
2109
2176
  // `await` so a shell-render throw (renderToStream rejects before any byte) is caught here and
@@ -2130,6 +2197,7 @@ export function createWebApp<Env = unknown>(
2130
2197
  ...(mod.revalidate !== undefined ? { revalidate: mod.revalidate } : {}),
2131
2198
  ...(mod.islandScripts !== undefined ? { islandScripts: mod.islandScripts } : {}),
2132
2199
  ...titleOption,
2200
+ ...assemblyCacheFor(mod, chainLayoutModules),
2133
2201
  })
2134
2202
  } catch (err) {
2135
2203
  // Same precedence as the loader catch above - a `meta()` may signal too.
@@ -2309,7 +2377,7 @@ export function generateClientEntry(
2309
2377
  const errorRouteIds: string[] = []
2310
2378
  // Lazy loader returns the raw modules (for both the component chain + the page's `meta` export).
2311
2379
  const lazyLoader = (files: readonly string[]): string => {
2312
- const imports = files.map((f) => `import(${JSON.stringify(resolve(f))})`).join(", ")
2380
+ const imports = files.map((f) => `import(${jsStringLiteral(resolve(f))})`).join(", ")
2313
2381
  return `() => Promise.all([${imports}])`
2314
2382
  }
2315
2383
  for (const route of manifest.routes) {
@@ -2577,7 +2645,7 @@ export function generateServerManifest(
2577
2645
  // code-splitting bundler, loaded on first request). The map keys are the route-relative paths
2578
2646
  // `buildManifest` expects; the importer it builds calls the per-file loader.
2579
2647
  const loaders = files.map(
2580
- (file) => ` ${JSON.stringify(file)}: () => import(${JSON.stringify(resolve(file))}),`,
2648
+ (file) => ` ${jsStringLiteral(file)}: () => import(${jsStringLiteral(resolve(file))}),`,
2581
2649
  )
2582
2650
  return `${[
2583
2651
  ...header,
@@ -0,0 +1,19 @@
1
+ /**
2
+ * A JS string literal for embedding a runtime value in GENERATED source. `JSON.stringify` alone is
3
+ * not a code sanitizer: its output can still contain `<` (so a value holding `</script>` breaks out
4
+ * of an inline-script embedding of the generated code) and the U+2028/U+2029 line separators (legal
5
+ * inside JSON strings, line terminators to pre-ES2019 parsers). Escape all three so the emitted
6
+ * literal is inert in every context the generated source can land in.
7
+ */
8
+
9
+ // Built with fromCharCode so this file stays pure ASCII - a literal U+2028/U+2029 in source is
10
+ // invisible in review and one save-with-normalization away from silently vanishing.
11
+ const LINE_SEPARATOR = String.fromCharCode(0x2028)
12
+ const PARAGRAPH_SEPARATOR = String.fromCharCode(0x2029)
13
+
14
+ export function jsStringLiteral(value: string): string {
15
+ return JSON.stringify(value)
16
+ .replaceAll("<", "\\u003C")
17
+ .replaceAll(LINE_SEPARATOR, "\\u2028")
18
+ .replaceAll(PARAGRAPH_SEPARATOR, "\\u2029")
19
+ }
@@ -41,6 +41,8 @@ export const SERVER_FN_MODULE = /\.fn(\.[cm]?[jt]sx?)?$/
41
41
  */
42
42
  export const SERVER_ONLY_REPLACEMENT = "module.exports = new Proxy({}, { get: () => undefined })"
43
43
 
44
+ import { jsStringLiteral } from "./js-string.ts"
45
+
44
46
  const EXPORTED_DECLARATION =
45
47
  /\bexport\s+(?:declare\s+)?(?:async\s+)?(?:const|let|var|function|class|enum)\s+([A-Za-z_$][\w$]*)/g
46
48
  const EXPORTED_LIST = /\bexport\s*\{([^}]*)\}(?:\s*from\s*["'][^"']+["'])?/g
@@ -57,9 +59,15 @@ export function viteServerOnlyReplacement(source: string): string {
57
59
  for (const match of source.matchAll(EXPORTED_DECLARATION)) names.add(match[1] as string)
58
60
  for (const match of source.matchAll(EXPORTED_LIST)) {
59
61
  for (const raw of (match[1] ?? "").split(",")) {
60
- const item = raw.trim().replace(/^type\s+/, "")
62
+ // Collapse runs of whitespace first (linear), so the ` as ` split below needs no `\s+as\s+`
63
+ // regex - adjacent unbounded quantifiers around a literal backtrack quadratically on crafted
64
+ // all-whitespace input.
65
+ const item = raw
66
+ .trim()
67
+ .replace(/\s+/g, " ")
68
+ .replace(/^type /, "")
61
69
  if (item === "") continue
62
- const parts = item.split(/\s+as\s+/)
70
+ const parts = item.split(" as ")
63
71
  const exported = (parts[1] ?? parts[0] ?? "").trim()
64
72
  if (exported === "default") hasDefault = true
65
73
  else if (/^[A-Za-z_$][\w$]*$/.test(exported)) names.add(exported)
@@ -97,8 +105,33 @@ export function viteServerOnlyReplacement(source: string): string {
97
105
  const DECLARATION = /^[\t ]*export\s+const\s+([A-Za-z_$][\w$]*)\s*=\s*serverFn\s*\(/gm
98
106
  /** Any mention of `serverFn(` as a call, used to prove nothing was missed. */
99
107
  const ANY_CALL = /\bserverFn\s*\(/g
100
- /** Line comments and block comments, stripped before scanning so prose cannot register as code. */
101
- const COMMENTS = /\/\*[\s\S]*?\*\/|(^|[^:])\/\/.*$/gm
108
+ /** Strip line and block comments by forward index scan, so prose cannot register as code. Not a
109
+ * regex: every regex shape for comment stripping either backtracks polynomially on adversarial
110
+ * source or is opaque enough that reviewers cannot tell. A `//` preceded by `:` is kept (URL in a
111
+ * string - the same heuristic the previous implementation used); an unterminated block comment
112
+ * swallows the rest of the source, matching a real parser. */
113
+ function stripComments(source: string): string {
114
+ const parts: string[] = []
115
+ let keepFrom = 0
116
+ let i = 0
117
+ while (i < source.length) {
118
+ if (source.startsWith("/*", i)) {
119
+ const close = source.indexOf("*/", i + 2)
120
+ parts.push(source.slice(keepFrom, i))
121
+ i = close === -1 ? source.length : close + 2
122
+ keepFrom = i
123
+ } else if (source.startsWith("//", i) && source[i - 1] !== ":") {
124
+ const newline = source.indexOf("\n", i + 2)
125
+ parts.push(source.slice(keepFrom, i))
126
+ i = newline === -1 ? source.length : newline // keep the newline itself
127
+ keepFrom = i
128
+ } else {
129
+ i++
130
+ }
131
+ }
132
+ parts.push(source.slice(keepFrom))
133
+ return parts.join("")
134
+ }
102
135
 
103
136
  /**
104
137
  * The namespace a `*.fn.ts` module is mounted under: its filename without the `.fn` suffix.
@@ -115,7 +148,7 @@ export function serverFnNamespace(filePath: string): string {
115
148
 
116
149
  /** The server functions a module declares, in source order. */
117
150
  export function scanServerFnExports(source: string): string[] {
118
- const code = source.replaceAll(COMMENTS, "$1")
151
+ const code = stripComments(source)
119
152
  const names = [...code.matchAll(DECLARATION)].map((m) => m[1] as string)
120
153
  const calls = [...code.matchAll(ANY_CALL)].length
121
154
  if (calls > names.length) {
@@ -140,10 +173,10 @@ export function scanServerFnExports(source: string): string[] {
140
173
  export function generateServerFnStub(source: string, namespace: string): string {
141
174
  const names = scanServerFnExports(source)
142
175
  const calls = names
143
- .map((name) => `export const ${name} = (input) => __nifraCall(${JSON.stringify(name)}, input)`)
176
+ .map((name) => `export const ${name} = (input) => __nifraCall(${jsStringLiteral(name)}, input)`)
144
177
  .join("\n")
145
178
  return `// Generated by @nifrajs/web: the server half of this module never reaches the browser.
146
- const __nifraBase = ${JSON.stringify(`/_nifra/fn/${namespace}`)}
179
+ const __nifraBase = ${jsStringLiteral(`/_nifra/fn/${namespace}`)}
147
180
 
148
181
  async function __nifraCall(name, input) {
149
182
  const response = await fetch(\`\${__nifraBase}/\${name}\`, {