@uniweb/build 0.36.0 → 0.37.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uniweb/build",
3
- "version": "0.36.0",
3
+ "version": "0.37.1",
4
4
  "description": "Build tooling for the Uniweb Component Web Platform",
5
5
  "type": "module",
6
6
  "exports": {
@@ -59,15 +59,15 @@
59
59
  "js-yaml": "^4.1.0",
60
60
  "sharp": "^0.35.3",
61
61
  "yaml": "^2.5.0",
62
- "@uniweb/semantic-parser": "^1.4.0",
63
62
  "@uniweb/content-writer": "^0.3.4",
64
- "@uniweb/theming": "^0.1.15",
65
63
  "@uniweb/content-reader": "^1.2.4",
64
+ "@uniweb/semantic-parser": "^1.4.0",
65
+ "@uniweb/projections": "^0.5.7",
66
66
  "@uniweb/schemas": "^0.2.13",
67
- "@uniweb/projections": "^0.5.7"
67
+ "@uniweb/theming": "^0.1.15"
68
68
  },
69
69
  "optionalDependencies": {
70
- "@uniweb/runtime": "^0.14.0"
70
+ "@uniweb/runtime": "^0.14.2"
71
71
  },
72
72
  "peerDependencies": {
73
73
  "vite": "^5.0.0 || ^6.0.0 || ^7.0.0",
package/src/prerender.js CHANGED
@@ -567,8 +567,7 @@ export async function prerenderSite(siteDir, options = {}) {
567
567
  initPrerender,
568
568
  hydrateDataStore,
569
569
  prefetchIcons,
570
- renderPage,
571
- injectPageContent,
570
+ createPageRenderer,
572
571
  generate404Html,
573
572
  } = await import('@uniweb/runtime/ssr')
574
573
 
@@ -702,6 +701,10 @@ export async function prerenderSite(siteDir, options = {}) {
702
701
  // Initialize the Uniweb runtime using the shared SSR module
703
702
  const uniweb = initPrerender(siteContent, foundation, loadedExtensions, { onProgress })
704
703
 
704
+ // One renderer for this run: the Website is already built and the shell is
705
+ // fixed, so it is created once and asked per page.
706
+ const renderer = createPageRenderer({ website: uniweb.activeWebsite, shell: htmlShell })
707
+
705
708
  // Build-specific: pre-populate DataStore so EntityStore can resolve data during prerender.
706
709
  // hydrateDataStore handles cache-key derivation + value-shape wrapping
707
710
  // — same helper used by the browser SPA boot and by the Cloudflare
@@ -765,28 +768,37 @@ export async function prerenderSite(siteDir, options = {}) {
765
768
 
766
769
  onProgress(`Rendering ${outputRoute}...`)
767
770
 
768
- const result = renderPage(page, website)
769
-
770
- if (result.error) {
771
- if (result.error.type === 'hooks' || result.error.type === 'null-component') {
771
+ // `renderer.render` IS the sequence this loop used to spell out —
772
+ // renderPage → classify → injectPageContent. It was moved into
773
+ // `@uniweb/runtime/ssr` because an SSR isolate assembles the same three steps
774
+ // per request, and two hand-written copies of one sequence is how the two
775
+ // lanes drift. This lane passes the Page it already holds; the isolate passes
776
+ // a route. See `runtime/src/page-renderer.js` for what it leaves to the host.
777
+ const result = renderer.render(page)
778
+
779
+ if (result.outcome === 'failed') {
780
+ const { type, message } = result.error
781
+ if (type === 'hooks' || type === 'null-component') {
772
782
  console.warn(
773
- ` Skipped SSG for ${outputRoute} — ${result.error.message}. ` +
783
+ ` Skipped SSG for ${outputRoute} — ${message}. ` +
774
784
  `The page will render correctly client-side.`
775
785
  )
776
786
  } else {
777
- console.warn(` Warning: Failed to render ${outputRoute}: ${result.error.message}`)
787
+ console.warn(` Warning: Failed to render ${outputRoute}: ${message}`)
778
788
  }
789
+ continue
790
+ }
779
791
 
780
- if (process.env.UNIWEB_DEBUG) {
781
- // renderPage swallows the stack, but the classification message is informative
782
- }
792
+ // `notFound` cannot happen here — this loop iterates pages it already has,
793
+ // so `render` never resolves. Handled anyway: silently writing nothing for a
794
+ // page the loop selected would be the same shape of empty-success bug that
795
+ // `renderPage`'s content-not-loaded guard exists to catch.
796
+ if (result.outcome === 'notFound') {
797
+ console.warn(` Warning: ${outputRoute} resolved to no page; skipped`)
783
798
  continue
784
799
  }
785
800
 
786
- // Shared injection: #root, title, meta, section override CSS
787
- let html = injectPageContent(htmlShell, result.renderedContent, page, {
788
- sectionOverrideCSS: result.sectionOverrideCSS,
789
- })
801
+ let html = result.html
790
802
 
791
803
  // Build-specific: theme CSS, __SITE_CONTENT__, icon cache.
792
804
  // scopeRoutes mirrors the runtime data cascade (page → page.parent → site)
@@ -429,12 +429,10 @@ export function parseFetchConfig(fetch) {
429
429
  // ⭐ **`as` is the BINDING KEY** — the `content.data.<key>` a component
430
430
  // reads — defaulting to the query name. It was called `schema` until
431
431
  // 2026-09-02, which collided with the MODEL REF of the same name on a
432
- // `queries` declaration. `fetch.schema` is still accepted as INPUT, so
433
- // content authored before the rename keeps working; it is never emitted.
434
- // `fetch.schema` here is an AUTHOR's older spelling in a content file —
435
- // the same boundary normalization as the source-shape branch below, not
436
- // the internal alias (removed 2026-09-02). One name travels inside.
437
- as: fetch.as || fetch.schema || fetch.query,
432
+ // `queries` declaration. **The old spelling is NOT read here, by
433
+ // ruling (2026-09-03): one name, no alias.** A fetch authored as
434
+ // `schema: posts` binds to nothing and is re-authored, not translated.
435
+ as: fetch.as || fetch.query,
438
436
  prerender: fetch.prerender ?? true,
439
437
  merge: fetch.merge ?? false,
440
438
  transform: fetch.transform,
@@ -455,7 +453,6 @@ export function parseFetchConfig(fetch) {
455
453
  path,
456
454
  url,
457
455
  as,
458
- schema,
459
456
  prerender = url ? false : true,
460
457
  merge = false,
461
458
  transform,
@@ -477,12 +474,10 @@ export function parseFetchConfig(fetch) {
477
474
  return {
478
475
  path,
479
476
  url,
480
- // **The one place `schema` is still read, and it is a BOUNDARY
481
- // normalization not the internal alias.** An author may have written
482
- // `fetch: { schema: person }` before the 2026-09-02 rename; that is content
483
- // on someone's disk, not a field our own packages pass to each other.
484
- // Translating it here means one name — `as` — everywhere inside.
485
- as: as ?? schema ?? inferSchemaFromPath(path || url),
477
+ // `schema` is NOT read here by ruling (2026-09-03), the retired
478
+ // spelling has no alias anywhere, authored content included. A fetch that
479
+ // still says `schema:` gets the inferred key and is re-authored to `as:`.
480
+ as: as ?? inferSchemaFromPath(path || url),
486
481
  prerender,
487
482
  merge,
488
483
  transform,