Documentation
¶
Index ¶
- Constants
- func AttachLive(c Stateful, inst LiveInstance)
- func CheckHandler(fn any) error
- func CheckStateful(c Stateful) error
- func EventName(attr string) string
- func Handler(f func(r *http.Request) (Node, error)) http.Handler
- func KeyText(k any) string
- func MountLive(ctx context.Context, c Stateful) error
- func SettleState(c Stateful)
- func String(ctx context.Context, n Node) (string, error)
- func TrackedState(c Stateful) (tracked, changed bool)
- func Void(tag string) bool
- func Walk(ctx context.Context, n Node, r Renderer) error
- func WithLiveHost(ctx context.Context, h LiveHost) context.Context
- func Write(w http.ResponseWriter, r *http.Request, n Node) error
- type Assign
- type Attr
- type Boundary
- type Builder
- type ComponentNode
- type Element
- type Event
- type EventHandler
- type Frame
- type Group
- type HTMLRenderer
- type Live
- type LiveHost
- type LiveInstance
- type Node
- func Child(v any) Node
- func Component(site string, key any, props Stateful) Node
- func El(tag string, attrs []Attr, children ...Node) Node
- func ErrorBoundary(fallback func(err error) Node, children ...Node) Node
- func F(fp uint64, shape string, kids ...Node) Node
- func Fragment(children ...Node) Node
- func Nodes(build func(add func(Node))) Node
- func RootAttrs(n Node, attrs ...Attr) (Node, bool)
- func Safe(html string) Node
- func Text(v any) Node
- func Try(n Node, err error) Node
- func WithChildren(c Node, children Node) Node
- type NodeFunc
- type RawHTML
- type Renderer
- type Stateful
- type Style
- type TextNode
- type Tree
- type TreeHost
- type TreeList
- type TreeRef
- type TryNode
Constants ¶
const VukaJSX = 1
VukaJSX marks the package as a JSX target implementing version 1 of Vuka's contract: a .vuka file importing ui lowers its JSX to El, Text, Child, Fragment, Nodes and Try; on… attributes to On; tags naming a Stateful type to Component; and children of components that read them from their context (templ components) go through WithChildren.
Variables ¶
This section is empty.
Functions ¶
func AttachLive ¶
func AttachLive(c Stateful, inst LiveInstance)
AttachLive binds a component to its session instance. Package live calls it.
func CheckHandler ¶
CheckHandler reports a value an on… attribute can't take: a handler is a func(), or a func taking the event's value (a string, number or bool), a form (a struct or pointer to one, or url.Values) or an Event, optionally after a context.Context, returning nothing or an error.
func CheckStateful ¶
CheckStateful reports a stateful component that embeds *Live rather than Live, which has no instance to attach.
func EventName ¶
EventName is the DOM event an on… attribute names: onClick is click, onKeyDown keydown.
func Handler ¶
Handler serves the Node f builds for each request through templ.Handler: rendered in full with the request's context, then sent as text/html. An error from f or from rendering answers 500 with only the status text.
func MountLive ¶
MountLive runs c's Mount method, if it has one: Mount(), Mount() error, Mount(context.Context) or Mount(context.Context) error.
func SettleState ¶
func SettleState(c Stateful)
SettleState marks c's Assigns unchanged, after a render.
func TrackedState ¶
TrackedState reports whether c's state is all Assigns (tracked), and whether one of them changed since SettleState. Package live calls it.
func Walk ¶
Walk sends n's tree to r. Frames, Groups, Builders and Child conversions are flattened (r never sees them); a TryNode with an error stops the walk with it; a Boundary walks its children into a recording first, and replays it into r — or, when they fail, walks Fallback(err) instead, so r never sees the failed part. Inside a Boundary an opaque Node is rendered while recording and replayed as Opaque of its HTML (a RawHTML). Children on a void element are an error. The first error from r stops the walk.
func WithLiveHost ¶
WithLiveHost is ctx carrying h.
Types ¶
type Assign ¶
type Assign[T any] struct { // contains filtered or unexported fields }
Assign is a stateful component's state value whose changes a live session tracks: Set and Update mark it changed. A component whose state fields (its unexported ones, except those tagged `vuka:"-"`) are all Assigns renders again only when one of them changed or its props did; otherwise the session keeps its last render without calling Render.
type Row struct {
ui.Live
Name string // a prop
qty ui.Assign[int] // state
}
func (r *Row) Inc() { r.qty.Update(func(n int) int { return n + 1 }) }
Render must then read nothing but props and Assigns (and fields tagged `vuka:"-"`, which must not change what it renders); in tests (or with VUKA_LIVE_VERIFY=1) the session renders skipped components anyway and fails when the result differs.
type Attr ¶
Attr is one attribute of an element. In HTML it renders the way templ renders the same attribute written as an expression:
- nil and false omit it, true writes it bare;
- class takes a string or anything templ.Classes does ([]string, map[string]bool, templ.KV, …);
- style takes a Style or anything templ's style attributes do, sanitized by templ (an unsafe property or value becomes templ's placeholder);
- href on a and link, action on form and data on object are URLs: templ.URL keeps relative URLs and http, https, mailto, tel, ftp and ftps, and turns anything else into about:invalid#TemplFailedSanitizationURL; a templ.SafeURL passes as is. Like templ, other attributes (img src, …) aren't URL-checked;
- a templ.ComponentScript writes its Call; a Node is rendered and escaped; anything else goes through fmt.Sprint and is escaped (templ.ResolveAttributeValue).
className and htmlFor name class and for. Names must be letters, digits, - _ : and . (templ only ever sees literal names; here a dynamic one could smuggle in another attribute), else Render fails.
type Boundary ¶
Boundary renders Children or, when one of them fails, Fallback(err) in place of everything they produced.
type Builder ¶
type Builder func(add func(Node))
Builder produces children as it runs: a loop, if or match block. It runs once per Render or Walk, each added child rendered as it is added.
type ComponentNode ¶
ComponentNode is a stateful component's tag, <Counter Start={5} />: Props is a fresh value carrying the attributes, never mounted itself. Site (the tag's place in the source), Key and the instance rendering it identify the instance a session keeps.
type Element ¶
Element is an element: <Tag Attrs>Children</Tag>. A void element (br, img, input, …; see Void) has no closing tag, and children on one are an error; in HTML, html is preceded by the doctype.
Text inside script follows templ's Go expressions in a script: it is JSON-encoded (templ's runtime.ScriptContentOutsideStringLiteral), so it arrives as a quoted JS string with < > & escaped. templ has no expressions inside style; here text in a style element is written as is with "</" written "<\/", so it can't end the element.
type Event ¶
type Event struct {
Target string `json:"target"`
Type string `json:"event,omitempty"`
Value string `json:"value,omitempty"`
Key string `json:"key,omitempty"`
Form url.Values `json:"form,omitempty"`
}
Event is what the browser reports of an event, and what a handler taking a ui.Event receives. Target is the handler's id; Type the DOM event; Value the target element's value (for a checkbox, "true" or "false"); Key the key of a keyboard event; Form the fields of the form a submit event comes from.
type EventHandler ¶
type EventHandler struct{ Fn any }
EventHandler is an on… attribute's expression on an element: onClick={c.Inc}. Under a live session it renders as data-vk-on-<event>="<handler id>" and the session calls Fn when the browser reports the event; without one it renders nothing. A templ.ComponentScript renders as templ renders it.
type Frame ¶
Frame is a piece of JSX as the compiler saw it: a tree's root, a block's body (one per loop iteration or branch taken), or a component tag's children. It renders exactly as its Kids would; under a live session it is also a frame of the render tree, whose markup splits into statics (what the source fixes, identical every render) and dynamics (what Go expressions produce), so a session sends the statics once and then only the dynamics that changed.
FP fingerprints what its statics are made of: its tags, attribute names and literal values, text, and where the expressions go — pieces of JSX that render the same statics share it, however they are formatted. Shape describes Kids, one item each, in the order they appear:
t text from the source
h b c a dynamic: an {expr} child, a {for}/{if}/{match} block, a component tag
E…(…) an element: a flag per attribute, s (a literal) or d (an expression),
then its children's items in parentheses
G(…) a fragment, <>…</>
Hand-written trees need no Frame: a Node that isn't one is a single dynamic of the frame around it, rendered to HTML.
type HTMLRenderer ¶
type HTMLRenderer struct {
// contains filtered or unexported fields
}
HTMLRenderer is the Renderer writing HTML: what Render does. Escaping and sanitizing are templ's (see Attr and Element).
func NewHTMLRenderer ¶
func NewHTMLRenderer(ctx context.Context, w io.Writer) *HTMLRenderer
NewHTMLRenderer is an HTMLRenderer writing to w, unbuffered; ctx renders Node attribute values.
func (*HTMLRenderer) Close ¶
func (h *HTMLRenderer) Close(e *Element) error
func (*HTMLRenderer) Open ¶
func (h *HTMLRenderer) Open(e *Element) error
func (*HTMLRenderer) Raw ¶
func (h *HTMLRenderer) Raw(html string) error
func (*HTMLRenderer) Text ¶
func (h *HTMLRenderer) Text(s string) error
type Live ¶
type Live struct {
// contains filtered or unexported fields
}
Live, embedded by value in a struct whose pointer has a Render() Node method, makes the struct a stateful component:
type Counter struct {
ui.Live
Start int // exported fields are props, set from the tag's attributes
n int // unexported fields are state
}
Rendered without a live session (ui.String, Handler, …) a stateful component mounts and renders once, as plain HTML. Under a session (package live) it is an instance that keeps its state between renders and answers the events of the elements it renders.
type LiveHost ¶
type LiveHost interface {
Component(ctx context.Context, n *ComponentNode, w io.Writer) error
Handler(ctx context.Context, fn any) string
Keyed(ctx context.Context, key any) context.Context
}
LiveHost renders stateful components and registers event handlers for a live session. Package live implements it; ctx carries it.
type LiveInstance ¶
LiveInstance is a session's side of a component instance. Package live implements it.
type Node ¶
Node is anything that renders HTML: what a JSX expression evaluates to. It is templ.Component itself, so Vuka components are templ components and templ components are Vuka children, with nothing in between.
The Nodes built here (*Element, TextNode, RawHTML, Group, Builder, TryNode, Boundary, *Frame) are also a tree any Renderer can Walk; any other Node — a templ component, a NodeFunc — is opaque: it can only render HTML. Nodes are immutable values; rendering one concurrently is safe.
func Child ¶
Child is a {expr} child: a Node as is, nil as nothing, an error as its message, a []Node or []any as each element in turn, anything else as Text.
func ErrorBoundary ¶
ErrorBoundary renders children, or — when one of them fails — fallback(err) in place of everything they wrote.
func RootAttrs ¶
RootAttrs is n with attrs added after its root element's own, when n is an element or a frame of one element; ok is false otherwise.
func WithChildren ¶
WithChildren renders c with children as its templ children (templ.WithChildren), so a templ component's { children... } renders them: <Card>{…}</Card> on a templ Card.
type NodeFunc ¶
type NodeFunc = templ.ComponentFunc
NodeFunc is a function rendering HTML: templ.ComponentFunc.
type Renderer ¶
type Renderer interface {
Open(e *Element) error // before children
Close(e *Element) error // after children (not called for void elements)
Text(s string) error
Raw(html string) error // Safe content
Opaque(ctx context.Context, n Node) error // a component that only renders HTML (templ, NodeFunc)
}
Renderer receives a node tree in document order; Walk drives it. The HTML renderer behind every Node's Render is one; package term is another.
type Stateful ¶
type Stateful interface {
Render() Node
// contains filtered or unexported methods
}
Stateful is a stateful component: a pointer to a struct embedding Live, with a Render method.
type Style ¶
Style is an inline style: style={ui.Style{"color": "red"}}, rendered by templ as "color:red;" sorted by property, each property and value sanitized.
type Tree ¶
Tree is a frame of a live render tree: the markup of a piece of JSX as statics, the strings its source fixes, around dynamics, what its expressions rendered. Its HTML is Statics[0] + Dyn[0] + Statics[1] + … + Statics[len(Dyn)]. A dynamic is a string of HTML, a nested *Tree, a *TreeList (a block's items) or a TreeRef (a stateful component instance, rendered by the session as a tree of its own).
Key identifies the statics: the frame's fingerprint in its render context. Two trees with the same Key have the same Statics, which are shared and must not be modified.
func BuildTree ¶
BuildTree renders n as a render tree. A Frame becomes a Tree split as its shape says; anything else is a frame of one dynamic. ctx should carry a live host; with verify, statics already known for a Key are rendered again and compared, and a difference is an error.
func OpaqueTree ¶
OpaqueTree is a frame with no statics of its own around dyns.
type TreeHost ¶
type TreeHost interface {
LiveHost
ComponentRef(ctx context.Context, n *ComponentNode) (id string, err error)
}
TreeHost is a LiveHost that can render a stateful component's tag as a reference to its instance. Package live implements it.
type TreeList ¶
TreeList is a {for}, {if} or {match} block's items, a frame per iteration or branch taken. Keys are the items' keys, from the key attribute of each item's first element or component tag; nil unless every item has one.
Directories
¶
| Path | Synopsis |
|---|---|
|
Package live runs stateful components for a connected browser: a Session keeps the component instances of one page, calls their event handlers and Update methods, and answers each with the HTML of the components whose output changed.
|
Package live runs stateful components for a connected browser: a Session keeps the component instances of one page, calls their event handlers and Update methods, and answers each with the HTML of the components whose output changed. |
|
internal/demo
Package demo is stateful components compiled by the Vuka compiler, for the live package's property tests and benchmarks.
|
Package demo is stateful components compiled by the Vuka compiler, for the live package's property tests and benchmarks. |
|
livetest
Package livetest is a reference client of the live protocol, in Go: it keeps what a browser runtime keeps — the page's HTML for v1, each instance's render tree for v2 — and applies the server's messages the way a runtime must, so tests can check that what a client ends up with is what the server rendered.
|
Package livetest is a reference client of the live protocol, in Go: it keeps what a browser runtime keeps — the page's HTML for v1, each instance's render tree for v2 — and applies the server's messages the way a runtime must, so tests can check that what a client ends up with is what the server rendered. |
|
Package templx bridges templ: children for templ components, and the components of .templ files a vuka.File names.
|
Package templx bridges templ: children for templ components, and the components of .templ files a vuka.File names. |
|
Package term renders a ui Node tree as terminal text: headings, paragraphs word-wrapped at a width, lists, tables, quotes, code, links, and inline bold/italic/underline as ANSI styles when Color is on.
|
Package term renders a ui Node tree as terminal text: headings, paragraphs word-wrapped at a width, lists, tables, quotes, code, links, and inline bold/italic/underline as ANSI styles when Color is on. |