A calm place to write long-form, and publish it to the open social web. skypress.blog/
0

Configure Feed

Select the types of activity you want to include in your feed.

at trunk 47 lines 2.7 kB View raw View rendered
1# 0016 — Read routes delegate orchestration to the read-context module 2 3- **Status:** Accepted 4- **Date:** 2026-06-10 5- **Scope:** the public read path (`src/pages/[author]/**`, `src/lib/reader/read-context.ts`) 6 7## Context 8 9Every read route (author index, publication home, article, RSS) hand-assembled the same 10resolution spine in its frontmatter: strip the `@` from the URL param, resolve 11handle → DID → PDS (Decision 0007), match a publication by slug, join documents by 12`value.site === publication.uri` (Decision 0010), and map each miss to an error scene. 13That was ~230 near-duplicate lines across four files, and the join key, the 100-document 14fetch bound, and the blob-ref → logo-URL construction were caller knowledge repeated 153–4×. Because the orchestration lived in `.astro` frontmatter, it could only be "tested" 16by regex pins against the page source (see rule 8 in AGENTS.md for why container 17rendering is out). 18 19## Decision 20 21One deep module, `src/lib/reader/read-context.ts`, owns the spine behind three entry 22points — `resolveAuthorContext`, `resolvePublicationContext`, `resolveArticleContext`23each returning `{ ok: true, context }` or `{ ok: false, error: ErrorSceneCopy }`. 24 25- **Pages keep only presentation.** A new read surface (AMP, embeds, …) must call the 26 read-context interface, not re-assemble `resolveAuthor` + slug-match + site-join. 27- The module returns publications with `logoUrl` prebuilt, so callers never touch 28 `BlobRefJson` internals. 29- The per-route independent fetches (profile, publication list, documents/record) run 30 in parallel inside the module; the old pages ran them serially. 31- The article render pipeline (`resolveBlobImageUrls → renderBlocks → 32 sanitizeArticleHtml`) deliberately stays in the article page / feed builder — sealing 33 it behind its own interface is a separate, orthogonal deepening. *(Since done: 34 Decision 0018 sealed it behind `src/lib/reader/render-article.ts`.)* 35- The shallow wrappers this obsoleted (`listReaderPublications`, 36 `resolveReaderPublication`) were deleted; `listAllReaderPublications` remains the one 37 reader-side publication fetch. 38 39## Consequences 40 41- The orchestration is behaviourally unit-tested in `read-context.test.ts` (mocking only 42 the network seam: `identity.ts` + `records.ts`); the colocated `_*.meta.test.ts` source 43 pins shrank to template-wiring guards. 44- On not-found paths the module may fetch slightly more than the old serial code did 45 (the parallel fetches start before the publication match is known) — accepted for the 46 happy-path latency win. 47- RSS 404 bodies are now a uniform `Not found` instead of echoing the handle.