Documentation
¶
Overview ¶
Package quicken renders web pages as a fast shell plus deferred regions.
A page paints its shell and lightweight skeletons immediately, then fills each region with its real content as that content becomes ready. The default transport streams over one HTTP response and stays readable with JavaScript disabled. A ClientFetch transport fetches each region after load, and a LiveChannel transport keeps a region live over a WebSocket (falling back to HTTP long-poll), pushing fine-grained patches as its server-held state changes.
A page's shell can be authored as a Go function over a Frame (the func-registry style), as an HTML marker document parsed by FromMarkup, or as an html/template rendered with the funcs from Helpers and then passed to FromMarkup. All three styles produce the same Page, so a transport serves them identically regardless of how the shell was written.
Two limitations apply to the LiveChannel transport in this release. The built-in session store keeps every session in memory and never evicts one, so each page load adds a session that lives for the process lifetime; supply a bounded SessionStore for production use. The WebSocket upgrade performs no same-origin (Origin header) check, so an application that needs cross-site request protection should validate the Origin itself. Driving a live region still requires the unguessable per-session resume token embedded in the page.
Index ¶
- Constants
- Variables
- func Escape(s string) string
- func Helpers() template.FuncMap
- func Mount(mux *http.ServeMux)
- func RenderMarkup(t *template.Template, data any) (string, error)
- func ScriptHandler() http.Handler
- func Serve(mux *http.ServeMux, path string, p *Page, t Transport)
- type ClientFetch
- type Frame
- type LiveChannel
- type LiveRegion
- type LiveSession
- type Page
- type Params
- type Payload
- type Region
- type RenderContext
- type RouteProvider
- type SessionStore
- type Shell
- type State
- type StreamHTML
- type Transport
- type Tree
Constants ¶
const ScriptPath = "/_quicken/quicken.js"
ScriptPath is where the shim is served and referenced from the shell head.
Variables ¶
var ( Text = cadence.Text Slots = cadence.Slots RegionFunc = cadence.RegionFunc )
Functions ¶
func Escape ¶
Escape returns s with HTML metacharacters escaped, for interpolating untrusted data into a dynamic Tree slot. Tree emits slot content raw (regions own their markup), so wrap any user-derived value with Escape.
func Helpers ¶ added in v0.4.0
Helpers returns template funcs for authoring a quicken page as an html/template: lazy and live emit a region marker for the given id, and quickenHead emits the shim marker. Render the template with RenderMarkup and pass the result to FromMarkup. lazy and live panic on an invalid id, which is always a programming error.
func RenderMarkup ¶ added in v0.4.0
RenderMarkup executes a template into a string, ready for FromMarkup.
func ScriptHandler ¶
ScriptHandler serves the embedded swap shim as JavaScript.
Types ¶
type ClientFetch ¶
type ClientFetch struct{}
ClientFetch delivers the shell with skeletons immediately and lets the client fetch each region from its own endpoint after load. The initial response contains no region content, so it is small and fast; regions fill in via the shim's fetch path and can be prefetched on intent. Use Serve so the per-region endpoints (Routes) are mounted alongside the page.
func (ClientFetch) Deliver ¶
func (ClientFetch) Deliver(w http.ResponseWriter, r *http.Request, p *Page) error
Deliver implements Transport. It writes the shell with skeletons plus a JSON manifest telling the client which regions to fetch and from where. It does not render any region.
func (ClientFetch) Routes ¶
func (ClientFetch) Routes(p *Page) map[string]http.Handler
Routes implements RouteProvider: one endpoint per region that renders just that region, plus a 404 guard at the region prefix. The exact per-region routes are more specific than the guard, so known ids resolve and unknown ids return Not Found rather than falling through to a catch-all page handler.
type Frame ¶
type Frame struct {
// contains filtered or unexported fields
}
Frame is handed to a Shell so it can place region skeletons and the shim.
type LiveChannel ¶
type LiveChannel struct {
Store SessionStore
// contains filtered or unexported fields
}
LiveChannel is the live transport: a WebSocket carries the first render and every subsequent fine-grained patch. A zero value uses a process-wide in-memory session store; set Store to supply your own.
pollTimeout controls how long the long-poll GET endpoint blocks waiting for the next queued message before responding 204. Zero means a default (see defaultPollTimeout in longpoll.go).
func (LiveChannel) Deliver ¶
func (lc LiveChannel) Deliver(w http.ResponseWriter, r *http.Request, p *Page) error
Deliver renders the shell with skeletons and a live manifest, mints a session, and mounts every live region so its state is ready when the socket connects. It does not stream any region's live HTML: the client renders "first" messages received over the socket, and the skeleton already in the document is the JS-off floor.
type LiveRegion ¶
type LiveRegion = cadence.LiveRegion
The region model and content substrate live in cadence, the foundation module. quicken re-exports them under its own names so its transports, pages, and authoring adapters (and their tests) keep working unchanged while depending on the shared foundation.
type LiveSession ¶
type LiveSession struct {
// contains filtered or unexported fields
}
LiveSession holds one connection's per-region state, keyed by region id.
type Page ¶
type Page struct {
// contains filtered or unexported fields
}
Page is a lazy page: a shell plus its registered regions.
func FromMarkup ¶ added in v0.4.0
FromMarkup builds a Page from an HTML document carrying quicken markers: <!--quicken head--> for the client shim, and <!--quicken lazy id--> or <!--quicken live id--> for a region's slot. Register the regions with Add and AddLive; the slot each marker produces follows the registration. It panics on malformed markup or a duplicate region or head marker, which is always a programming error.
The markup is expected to be author-controlled or trusted: a compile-time constant or the output of a trusted template, analogous to html/template.Must. An application assembling markup from dynamic or untrusted input should validate it first or recover from the panic.
func (*Page) Add ¶
Add registers a region. Regions render in the order added. Adding a region whose id is a duplicate or is not of the form [A-Za-z0-9_-]+ panics, which is always a programming error.
func (*Page) AddLive ¶
func (p *Page) AddLive(r LiveRegion) *Page
AddLive registers a live region. Live regions render in the order added. A duplicate id (in either the deferred or live set) or an id not of the form [A-Za-z0-9_-]+ panics, which is always a programming error.
type Params ¶
The region model and content substrate live in cadence, the foundation module. quicken re-exports them under its own names so its transports, pages, and authoring adapters (and their tests) keep working unchanged while depending on the shared foundation.
type Payload ¶
The region model and content substrate live in cadence, the foundation module. quicken re-exports them under its own names so its transports, pages, and authoring adapters (and their tests) keep working unchanged while depending on the shared foundation.
type Region ¶
The region model and content substrate live in cadence, the foundation module. quicken re-exports them under its own names so its transports, pages, and authoring adapters (and their tests) keep working unchanged while depending on the shared foundation.
type RenderContext ¶
type RenderContext = cadence.RenderContext
The region model and content substrate live in cadence, the foundation module. quicken re-exports them under its own names so its transports, pages, and authoring adapters (and their tests) keep working unchanged while depending on the shared foundation.
type RouteProvider ¶
RouteProvider is an optional Transport capability: extra routes a transport needs mounted alongside the page, such as the per-region fetch endpoints of ClientFetch. Serve mounts these automatically.
type SessionStore ¶
type SessionStore interface {
Get(token string) (*LiveSession, bool)
Put(token string, s *LiveSession)
Delete(token string)
}
SessionStore maps a resume token to a LiveSession. The in-memory implementation is the only one built for v1; the interface lets a shared store replace it later without touching the core.
func NewMemoryStore ¶
func NewMemoryStore() SessionStore
NewMemoryStore returns an in-process SessionStore.
type Shell ¶
Shell renders the full HTML document for a page. It places each region's skeleton with f.Slot(id) and includes the shim with f.Head(). It returns a complete document; the transport streams region fills in just before the closing body tag.
type State ¶
The region model and content substrate live in cadence, the foundation module. quicken re-exports them under its own names so its transports, pages, and authoring adapters (and their tests) keep working unchanged while depending on the shared foundation.
type StreamHTML ¶
type StreamHTML struct{}
StreamHTML flushes the shell with skeletons immediately, renders regions concurrently, and streams each region's real HTML as a fill block with an inline swap script as it becomes ready. With scripting disabled the fill blocks stay visible after the body content, so the page is still fully readable; the shim only relocates them into their slots.
func (StreamHTML) Deliver ¶
func (StreamHTML) Deliver(w http.ResponseWriter, r *http.Request, p *Page) error
Deliver implements Transport.