loftur

Lifecycles

Site code lifecycle

Site code — routes, islands, server functions, GraphQL documents — lives in a single working tree per site. You edit it freely; the only gate is publish.

The loop

site_write  →  site_check  →  preview_site  →  publish_site  →  rollback_site
   edit         preflight       see it live      snapshot         undo
  • site_write transpiles each file and stores it. Type and GraphQL errors come back per write, server-side — there's no tsc or linter running as you type, so work in small increments.
  • site_check is the non-destructive preflight — "green means green." It runs the same validation publish_site will, against the live schema, without touching anything. Clean check ⇒ the publish will succeed.
  • preview_site mints a short-lived token and serves the draft tree behind an HttpOnly cookie. This renders your unpublished working tree — and unpublished content — in the real runtime. It's your feedback loop, since you can't compile-and-run locally.
  • publish_site validates every GraphQL document against the live schema, smoke-renders /, computes a footprint, and snapshots the whole tree into an immutable version, then repoints the published pointer.
  • rollback_site repoints to any previous version — byte-for-byte, instantly.

A failed publish never touches the live site. Validation happens before the pointer moves, so the worst case of a bad publish is: nothing shipped.

One draft, no branches

A site has a single working draft — there are no branches. Publish (or reset_site) before starting an unrelated change. History and undo are the version list plus site_diff and rollback_site, not git.

Preview vs published, end to end

The draft/published split runs through the whole request path, not just the code:

Draft (preview)Published
Served bypreview_site cookiedefault
Isolate iddraft:<sha> (content-addressed)site:v<N> (stable)
Content seenincludes draftspublished only
serverFn endpoint/__fn/draft/… (cookie-gated)/__fn/v<N>/…

Because the published site is a frozen snapshot loaded by version, it can never accidentally render draft code or draft content — the flag is bound to the render path, not to anything a visitor can set.