worker
import { composeWorker, withEdgeCache, withHealing } from "louise-toolkit/worker";The Worker entrypoint helpers. Every Louise site’s worker.ts has the same
shape: try a few Louise-owned routes, fall through to the framework’s SSR
handler, optionally wire queue / scheduled. composeWorker builds that
ExportedHandler; withEdgeCache and withHealing wrap the fallback and the
routes. No peers.
composeWorker(options)
Section titled “composeWorker(options)”function composeWorker<Env>(options: ComposeWorkerOptions<Env>): ExportedHandler<Env>;
interface ComposeWorkerOptions<Env> { routes?: WorkerRoute<Env>[]; // first to return a Response wins fetch: ExportedHandler<Env>["fetch"]; // SSR fallback when no route matches queue?: ExportedHandler<Env>["queue"]; scheduled?: ExportedHandler<Env>["scheduled"];}Composes an ExportedHandler from ordered WorkerRoutes over an SSR fallback.
On fetch, each route runs in order and the first Response short-circuits; if
none match, the fetch fallback handles it. A WorkerRoute returns a Response
to handle the request, or undefined to pass it to the next route.
export default composeWorker<Env>({ routes: [louiseApiRoute, ogImageRoute], fetch: ssrHandler, // for example, @astrojs/cloudflare's handle queue: (batch, env) => processBatch(batch, (m) => handle(m, env)),});withEdgeCache(handler, config)
Section titled “withEdgeCache(handler, config)”function withEdgeCache<Env>( handler: (request, env, ctx) => Response | Promise<Response>, config?: EdgeCacheConfig,): (request, env, ctx) => Promise<Response>;
interface EdgeCacheConfig { bypass?: (request: Request) => boolean; // skip cache, always run fresh cache?: () => Cache; // defaults to caches.default; injectable for tests signalHeader?: string; // defaults to cloudflare-cdn-cache-control}A cookie-aware edge cache for the SSR fallback. It caches public GETs in the
Worker-controlled Cache API (caches.default), keyed by URL, and stores a
response only when it carries a cacheable directive in the signal header.
Bypassed requests (for example, an authenticated editor) and non-GETs always run
the handler. Drop-in for composeWorker’s fetch.
Which header carries that decision is your host’s convention, not this layer’s,
so signalHeader is configurable. It defaults to
CDN_CACHE_CONTROL (cloudflare-cdn-cache-control), which is what a
Cloudflare-targeting SSR adapter emits for a cacheable response—so most sites
never set it. A host that signals some other way sets its own name and is not
obliged to adopt Cloudflare’s.
The signal header is always stripped from the response, whichever one you use, for the reason in the caution below.
export default composeWorker<Env>({ fetch: withEdgeCache(ssrHandler, { bypass: (req) => hasEditorSession(req) }),});Helpers
Section titled “Helpers”CDN_CACHE_CONTROL—the response header consumed as the “cache me” signal.isCacheableDirective(directive)—is a Cache-Control value an opt-in (public/unspecified with a positivemax-age, notno-store/no-cache/private)?
withHealing(route, options)
Section titled “withHealing(route, options)”function withHealing<Env>(route: WorkerRoute<Env>, options: HealingOptions<Env>): WorkerRoute<Env>;
interface HealingOptions<Env> { rules: Record<string, HealingRule<Env>>; // keyed by LouiseError.code fallbackRule?: HealingRule<Env>; // for codes with no explicit rule sleep?: (ms: number) => Promise<void>; // injectable for tests}Wraps a route so thrown LouiseErrors are healed by
policy instead of surfacing as a 500. A rule (selected by error.code) composes
three deterministic strategies: retry (re-run, optional exponential
backoffMs), fallback (serve a degraded/stale Response), and escalate
(hand the failure off out-of-band via ctx.waitUntil, so recovery never blocks
the response). Non-LouiseErrors, and codes with no matching rule, re-throw.
const healed = withHealing(apiRoute, { rules: { DB_ERROR: { retries: 2, backoffMs: 50, fallback: ({ request }) => serveStale(request), escalate: ({ env, ...c }) => enqueue(env.HEAL_QUEUE, describeFailure(c)), }, },});WorkerRoute, ComposeWorkerOptions, EdgeCacheConfig, HealingRule,
HealingContext, HealingOptions, FailureReport.