ssr

package
v1.2.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 10, 2026 License: MIT Imports: 18 Imported by: 0

Documentation

Overview

Package ssr renders Svelte pages on the server by running the app's server bundle in embedded QuickJS VMs. It is pure Go: no cgo and no Node.

Index

Constants

View Source
const DefaultMaxWorkers = 4

DefaultMaxWorkers caps the default number of VMs. The VMs share the C runtime's allocator, which takes a global lock on every JavaScript function call, so throughput peaks around four concurrent renders and falls with more (see docs/benchmarks.md).

Variables

View Source
var ErrNoEmails = errors.New("ssr: the app has no email templates (src/emails)")

ErrNoEmails is returned when the app has no src/emails.

View Source
var ErrTimeout = errors.New("ssr: render timed out")

ErrTimeout is returned when a render exceeds the pool's timeout.

Functions

This section is empty.

Types

type Cache added in v1.2.0

type Cache struct {
	// contains filtered or unexported fields
}

Cache remembers renders by payload and URL. A render is a pure function of both: the browser hydrates from the same payload and must produce the same HTML, so a component whose output depends on anything else (the clock, randomness) would not hydrate cleanly either. Pages that look the same for many visitors, such as anonymous pages, then render once.

Concurrent renders of the same page are coalesced into one.

func NewCache added in v1.2.0

func NewCache(next Renderer, maxBytes int) *Cache

NewCache wraps next with a cache of at most maxBytes of HTML.

func (*Cache) Next added in v1.2.0

func (c *Cache) Next() Renderer

Next returns the renderer the cache wraps.

func (*Cache) Render added in v1.2.0

func (c *Cache) Render(ctx context.Context, payload []byte, href string) (Result, error)

Render returns a cached render, or renders and caches it.

func (*Cache) Stats added in v1.2.0

func (c *Cache) Stats() (hits, misses uint64, bytes int)

Stats reports cache hits, misses, and the bytes cached.

type Dev

type Dev struct {
	URL    string // the Vite dev server, e.g. http://127.0.0.1:5174
	Client *http.Client
}

Dev renders through the Vite dev server, so server rendering uses the same up-to-date modules as hot module replacement.

func (*Dev) Email added in v1.2.0

func (d *Dev) Email(ctx context.Context, name string, props []byte) (EmailResult, []byte, error)

Email implements EmailRenderer.

func (*Dev) Render

func (d *Dev) Render(ctx context.Context, payload []byte, href string) (Result, error)

Render implements Renderer.

type EmailRenderer added in v1.2.0

type EmailRenderer interface {
	Email(ctx context.Context, name string, props []byte) (EmailResult, []byte, error)
}

EmailRenderer renders the app's email templates (src/emails). An empty name returns the template names with their preview props, as JSON.

type EmailResult added in v1.2.0

type EmailResult struct {
	Subject string `json:"subject"`
	HTML    string `json:"html"`
	Error   string `json:"error,omitempty"`
}

EmailResult is a rendered email template.

type Options

type Options struct {
	// Workers is the number of VMs, and so the number of concurrent
	// renders. The default is GOMAXPROCS, at most DefaultMaxWorkers.
	Workers int
	// Timeout bounds a single render. The default is 5 seconds.
	Timeout time.Duration
	// MemoryLimit caps each VM's heap, in bytes. The default is 256 MiB.
	MemoryLimit uintptr
	// Logger receives console output from server-side code.
	Logger *slog.Logger
	// Funcs are Go functions the bundle can call while rendering, by name;
	// ctx is the render's context.
	Funcs map[string]func(ctx context.Context, args []any) (any, error)
	// MaxRenders retires a VM after this many renders and replaces it with
	// a fresh one, built in the background. It bounds memory that libraries
	// keep across renders. The default is 10,000; a negative value never
	// retires VMs.
	MaxRenders int
}

Options configure a Pool.

type Pool

type Pool struct {
	// contains filtered or unexported fields
}

Pool renders with a fixed number of reusable VMs. VMs are created on demand; a VM that times out or fails is discarded and replaced.

func NewPool

func NewPool(bundle string, opts Options) (*Pool, error)

NewPool compiles bundle, which must define globalThis.__tern_render, and returns a pool ready to render. It creates one VM up front so a broken bundle fails at startup rather than on the first request.

func (*Pool) Close

func (p *Pool) Close() error

Close releases the pool's VMs. Renders in progress finish first.

func (*Pool) Email added in v1.2.0

func (p *Pool) Email(ctx context.Context, name string, props []byte) (EmailResult, []byte, error)

Email renders an email template with props (JSON).

func (*Pool) Render

func (p *Pool) Render(ctx context.Context, payload []byte, href string) (Result, error)

Render renders payload, waiting for a free VM if all are busy.

type Renderer

type Renderer interface {
	Render(ctx context.Context, payload []byte, href string) (Result, error)
}

Renderer renders a page payload. href is the page's absolute URL.

type Result

type Result struct {
	Head string `json:"head"`
	Body string `json:"body"`
	// Skip reports that the payload is not something the server renders.
	Skip bool `json:"skip"`
}

Result is a rendered page.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL