feat: the Library — tiered content rendering #85

Merged
manlycucumber merged 3 commits from feat/library-tiered-rendering into develop 2026-07-07 00:23:04 +00:00
manlycucumber commented 2026-07-07 00:08:31 +00:00 (Migrated from github.com)

The foundation of v0.3.0, the Library — Bosco's flagship. Every published topic now renders at three reading tiers, both as prerendered /library routes and inside the desktop Library window. First of five engine PRs; architecture is vetted (an 8-agent design workshop) and written up in docs/architecture/library.md.

What's here

One set of views, two hosts. Presentation-only components in src/lib/library/ (ArticleView, CategoryView, LibraryHome, TopicCard, TierSwitch, StandaloneChrome) that know nothing about routing or windows, mounted by:

  • Prerendered routes/library/, /library/[category]/, /library/[category]/[topic]/ (one static HTML file per published topic; dynamic entries() from the gated topics[]). The canonical, offline, deep-linkable, no-JS face, wrapped in retro StandaloneChrome with an "Open in Bosco" link.
  • The desktop windowLibraryBody replaces the placeholder room, browsing the same views via a small LibraryBrowser store.

In-window links never navigate. Internal links are real <a href> (so deep links / middle-click / no-JS work), but one base-path-aware delegated click intercept turns an unmodified left-click into a store move — so opening a topic keeps every other window's position and z-order (Window.svelte keeps windows mounted; a goto would tear the desktop down). Focus moves to the new view's heading.

Tiers — the eager default makes prerender work. An {#await loader()} in a template SSRs its pending branch → empty HTML. Instead the content plugin emits virtual:bosco/content-eager, a static import of each published topic's default tier, rendered synchronously → real prose in the prerendered HTML. Consequences: one Pagefind record per topic by construction (data-pagefind-body placed for PR3); the gate still keeps pending bodies out of production (no import.meta.glob(eager)); load() stays serializable (returns identity, not the component). The other two tiers load lazily on tier switch. New additive default_tier frontmatter, clamped to the nearest declared tier.

Verification (all green)

  • pnpm build (adapter-static strict) · guard:external · guard:content · guard:colour · guard:offline — the offline smoke now also asserts the prerendered topic HTML contains default-tier prose (catches an all-lazy regression).
  • svelte-check 0/0 · lint clean · 49 unit tests (adds pickDefaultTier + eager-module coverage).
  • e2e: in-window browse doesn't navigate and other windows survive; the deep link renders standalone; axe is clean on the in-window article and the standalone page.
  • Drive-by: fixes a pre-existing failing assertion in offline.spec (the Bosco heading lives in the first-run-hidden Home window; verified failing on pristine develop).

Not in this PR

Cross-links / See-also / Surprise-me / glossary (PR2) · Pagefind search (PR3) · category-landing & Archives visual design (PR4) · AI content-pipeline tooling (PR5) · the 3-topic proof + 18-topic launch set (owner-paced content).

The foundation of **v0.3.0, the Library** — Bosco's flagship. Every published topic now renders at three reading tiers, both as prerendered `/library` routes and inside the desktop Library window. First of five engine PRs; architecture is vetted (an 8-agent design workshop) and written up in [`docs/architecture/library.md`](docs/architecture/library.md). ## What's here **One set of views, two hosts.** Presentation-only components in `src/lib/library/` (`ArticleView`, `CategoryView`, `LibraryHome`, `TopicCard`, `TierSwitch`, `StandaloneChrome`) that know nothing about routing or windows, mounted by: - **Prerendered routes** — `/library/`, `/library/[category]/`, `/library/[category]/[topic]/` (one static HTML file per published topic; dynamic `entries()` from the gated `topics[]`). The canonical, offline, deep-linkable, no-JS face, wrapped in retro `StandaloneChrome` with an "Open in Bosco" link. - **The desktop window** — `LibraryBody` replaces the placeholder room, browsing the same views via a small `LibraryBrowser` store. **In-window links never navigate.** Internal links are real `<a href>` (so deep links / middle-click / no-JS work), but one **base-path-aware delegated click intercept** turns an unmodified left-click into a store move — so opening a topic keeps every other window's position and z-order (`Window.svelte` keeps windows mounted; a `goto` would tear the desktop down). Focus moves to the new view's heading. **Tiers — the eager default makes prerender work.** An `{#await loader()}` in a template SSRs its *pending* branch → empty HTML. Instead the content plugin emits **`virtual:bosco/content-eager`**, a *static* import of each **published** topic's default tier, rendered synchronously → real prose in the prerendered HTML. Consequences: one Pagefind record per topic by construction (`data-pagefind-body` placed for PR3); the gate still keeps `pending` bodies out of production (no `import.meta.glob(eager)`); `load()` stays serializable (returns identity, not the component). The other two tiers load lazily on tier switch. New additive `default_tier` frontmatter, clamped to the nearest declared tier. ## Verification (all green) - `pnpm build` (adapter-static strict) · `guard:external` · `guard:content` · `guard:colour` · `guard:offline` — the offline smoke now also asserts the prerendered topic HTML **contains default-tier prose** (catches an all-lazy regression). - `svelte-check` 0/0 · `lint` clean · **49 unit tests** (adds `pickDefaultTier` + eager-module coverage). - **e2e**: in-window browse doesn't navigate and other windows survive; the deep link renders standalone; axe is clean on the in-window article **and** the standalone page. - Drive-by: fixes a **pre-existing** failing assertion in `offline.spec` (the `Bosco` heading lives in the first-run-hidden Home window; verified failing on pristine `develop`). ## Not in this PR Cross-links / See-also / Surprise-me / glossary (PR2) · Pagefind search (PR3) · category-landing & Archives visual design (PR4) · AI content-pipeline tooling (PR5) · the 3-topic proof + 18-topic launch set (owner-paced content).
Sign in to join this conversation.
No reviewers
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Bosco/bosco!85
No description provided.