@hobiri/website-runtime
v0.1.1
Published
Shared website-runtime composition for Hobiri applications (bootstrap, rendering, 404 middleware, sitemap responses).
Readme
@hobiri/website-runtime
Shared website-runtime composition for Hobiri applications: Comity Kernel bootstrap, Preact page rendering, 404 middleware, and sitemap responses.
Install
pnpm add @hobiri/website-runtimePeer dependencies (@comity/*, hono, preact) must be provided by the
consumer; see Dependencies.
Application route tables, views, layouts, content, themes, forms, and business logic stay in each consumer. The package owns only call-site composition that must evolve together across websites.
API
createWebsiteApp({ routes, middlewares? })— compose Kernel + HTTP, Hono, and router modules; resolve the Hono application.renderPage(view, { status? }?)— render a Preact view to an HTTP response (default 200; render failures log viaconsole.errorand return 500).createNotFoundMiddleware(render404)— delegate 404 rendering to an application-owned callback; null results or thrown errors preserve the original response.sitemapResponse(urls, { status? }?)— adapt a URL inventory to a sitemap XML response (default 200).
Dependencies
Peer dependencies (@comity/primitives, @comity/http, @comity/http-hono,
hono, preact) keep a single runtime identity for error classes involved in
request handling. The remaining Comity packages are direct dependencies used
only inside the package. Consumers keep their own direct Comity dependencies.
Non-goals
Content models, layouts, themes, forms, business logic, build tooling, framework lifecycle, metapackage re-exports, HappyBen API support.
Consumer contract
Each consumer owns its route table, middleware list, views, layouts, content, and deployment configuration, and composes them explicitly:
import { createWebsiteApp } from "@hobiri/website-runtime";
import middlewares from "./server/middleware/index.js";
import routes from "./server/routes/index.js";
const app = await createWebsiteApp({ routes, middlewares });
export default app;Rules:
- Route tables and middleware lists stay application-owned; the package copies the route array and never retains caller data.
- Views and 404 pages stay application-owned;
renderPageandcreateNotFoundMiddlewareonly adapt them to HTTP responses. - Sitemap URL inventories stay application-owned;
sitemapResponseonly adapts them to an XML response. - Consumers upgrade independently by bumping the pinned version; releases are never synchronized across applications.
- Consumers keep their own direct Comity dependencies; the package never re-exports Comity types.
Rendering constraints
Rendering goes through Comity's pipeline (streaming first, static fallback)
with deterministic head-tag ordering. The package, the consumer, and Comity
must resolve a single Preact and preact-render-to-string instance: the
consumer's view closures and the package's renderer share hook context, so
mixing live-source and registry-distributed Comity copies breaks server
rendering. Keep all Comity packages on the same published release line
(@comity/seo and @comity/media remain at 0.9.0; the rest at 0.9.1).
Verifying a new consumer
- Compose the application as above and request every route.
- Assert statuses, content types, and representative markup per route.
- Assert the sitemap is valid XML with the owned inventory.
- Assert unknown paths return the custom 404 (never 500).
- Repeat requests to rule out state leakage.
- Run typecheck, tests, and both client and worker builds.
- Where workerd tooling exists, execute the built worker and repeat the same assertions against it.
License
MIT — see LICENSE.
