vuka

package module
v0.7.0 Latest Latest
Warning

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

Go to latest
Published: Oct 10, 2026 License: MIT Imports: 15 Imported by: 0

README

Vuka

Vuka

Docs: vuka-lang.github.io/vuka

Vuka is Go with Result and Option, ? error propagation, pattern matching, function and method overloading, typed attributes, decorators, and JSX components rendered by templ, with Elixir-style multi-clause functions on the way. It transpiles to plain Go and builds with the go command you already have.

func area(c Circle) float64 { return math.Pi * c.R * c.R }

@export("RectArea")
func area(r Rect) float64 { return r.W * r.H }

func (c *Counter) Add(by int)    { c.n += by }
func (c *Counter) Add(by string) { c.n += len(by) }

@cache.Memo{TTL: 5 * time.Minute}
func lookup(id int) User { … }
func lookup(arg string) Result[User] {
	id := strconv.Atoi(arg)?          // Go's (T, error) works directly
	u := find(id)?
	return Ok(u)
}

match lookup(arg) {
case Ok(u):
	fmt.Println(u.Name)
case Err(&NotFound{ID: id}):
	fmt.Println("missing user", id)
case Err(e) if errors.Is(e, strconv.ErrSyntax):
	fmt.Println("not a number:", arg)
case Err(e):
	fmt.Println("error:", e)
}
go install github.com/vuka-lang/vuka/cmd/vuka@latest
vuka new hello && cd hello && vuka run .

A Vuka project is a Go module: .vuka and .go files sit side by side in the same packages and call each other, the way Kotlin and Java share a project. Dependencies are Go's: go get a module and import it from any .vuka file.

Editors

vuka lsp is a language server for .vuka files: gopls behind a proxy that keeps the generated Go open in gopls as unsaved buffers (nothing is written to your tree) and maps every position both ways. Completion, hover, signature help, go to definition, references, rename, outline, code actions, inlay hints and formatting (vuka fmt) all work; Vuka's own errors and Go's type errors show on the .vuka lines. Overloads show under the name you wrote (area, not area__Circle). vuka.File paths (@web.Template("views/pets.templ")) are clickable.

  • VS Code: the extension in editors/vscode (npm install && npx vsce package, then install the .vsix). It offers to serve your Go files too: run as gopls (a link the extension makes, set as the Go extension's go.alternateTools.gopls), vuka is a drop-in gopls, so .go files in a package with .vuka files see their code instead of "undefined" errors. Both servers use one shared gopls daemon (gopls -remote=auto), so the work is done once.
  • Any other editor: run vuka lsp over stdio for the vuka file type (needs gopls: go install golang.org/x/tools/gopls@latest).

Built to track Go

Vuka owns only its additions. Each one is found by go/scanner and lowered to Go in place; everything else passes through untouched, to be parsed and type-checked by the standard library's go/parser and go/types. When Go adds syntax, Vuka already accepts it.

  • Install Vuka with your own toolchain (go install, or go get -tool and go tool vuka). Its parser is the stdlib of the Go that built it, so it matches yours.
  • TestStdlibPassesThrough feeds every file of $GOROOT/src through Vuka and requires byte-identical output. Run it on a new Go release to find out what, if anything, has to change.
  • The generated code is plain Go; its only runtime is the small Result/Option package. //line directives point compile errors and panics at the .vuka source, down to the column.

What works

Result and Option live in the runtime package github.com/vuka-lang/vuka (its root; nothing else in it). Vuka code writes Result[User], Ok(u), Err(e), Some(x) and None unqualified, and the transpiler adds the import wherever the package doesn't declare those names itself. Err and None take their type from where the value goes (return Err(e) in a function returning Result[User]). Result's error is Go's error, so it meets Go code halfway: vuka.Of(os.ReadFile(p)) wraps a Go call, r.Get() hands back (T, error). Your module needs the dependency: go get github.com/vuka-lang/vuka.

? ends a statement: x := f()?, x = f()?, var x = f()?, return f()? or f()?. The operand is Go's (T…, error), an error, a Result, or an Option (in a function returning an Option). On failure the function returns: zero values plus the error, Err(e), or None, whichever its results call for. The operand stays where it is, so nothing is reordered.

match is a statement of cases, tried in order:

pattern matches
_, default anything
x anything, binding it to x (a constant's name compares instead)
0, "a", Max, pkg.Const, true an equal value
^x the value of the variable x (Elixir's pin)
Ok(p), Err(p), Some(p), None a Result or Option, then p inside
T{F: p, …}, &T{…} a struct's fields; against an interface, a type test too
1, 2, 3 any of them

case p if cond: adds a guard. A match must be exhaustive (Ok and Err, Some and None, true and false, or a case that takes anything), and a case after one that matches everything is an error; both are reported before Go sees the code.

Overloading. Functions and methods may share a name when their parameter types differ. Each declaration is renamed (area__Circle, Add__int_int), and each call goes to the overload that best fits its arguments' static types: identical types beat an untyped constant's default type, which beats any other assignable value. A tie is a compile error that lists the candidates. Calls whose argument types come from other overloaded calls resolve too.

Attributes come before a top-level declaration:

@doc("…") becomes the declaration's doc comment
@deprecated("…") adds a Deprecated: paragraph
@export("Name") generates Name, a wrapper with the declaration's signature: how Go code reaches one overload
@T / @pkg.T{…} any Go type, bare or as a composite literal; the generated code type-checks it

Decorators wrap a declaration, Python-style. The simplest kind works on any function, whatever its signature:

decorator logged(c) {
	fmt.Println("calling", c.Name, c.Args)
	c.Next()                                   // run the function (or the next decorator)
	fmt.Println("returned", c.Results)
}

decorator retry(times int)(c) {             // with parameters
	for i := 0; i < times; i++ {
		if c.Next(); c.Err() == nil {
			return
		}
	}
}

@retry(3)
@logged
func charge(ctx context.Context, id int) (Receipt, error) { … }

@logged
func (s *Store) Save(u User) error { … }   // methods too

decorator name(c) { … } is shorthand for func name(c *vuka.Call), a vuka.Decorator; plain Go functions of that type work the same, in .vuka or .go files. A decorator with parameters (retry(3)) is built once per decorated function, so state it keeps (a cache, a counter) isn't shared.

*vuka.Call
c.Name, c.Receiver "main.charge"; the receiver of a method
c.Args, c.Results arguments (change them before Next) and results
c.Next() run the rest; call it again to retry, or not at all
c.Return(v…) answer without running the function (caches, mocks)
c.Err(), c.SetErr(err) the trailing error result
c.Context() the context.Context argument
vuka.Arg[T](c, i) argument i as a T
c.Attr(&x), vuka.AttrOf[T](c) a typed attribute on the same declaration
@Perm("orders.write")
@guard                                      // reads it: var p Perm; c.Attr(&p)
func save(ctx context.Context, o Order) error { … }

A type decorator receives the type: func Model(t *vuka.Type) gets t.Name, t.Reflect and t.Attr, at init. Packing a call into a *vuka.Call costs a small allocation; for hot paths, a typed decorator func(F) F (or for a type, a generic func[T]) has none and checks every type. Vuka picks the form from the decorator's type, so both mix freely, and a decorator that fits neither is a compile error on its @ line. Functions keep their name for a wrapper that builds the decorated function once; recursion goes through it; init, overloads, generic functions and type ( … ) groups can be decorated.

A declarer, func(d *vuka.Decl) (or a call returning one, such as @web.Get("/pets/{id}")), doesn't wrap calls: it runs once at init, top to bottom, with the function's name, attributes, parameter names and types, and the decorated function itself — the way to register routes, commands or jobs. A string literal passed where a decorator or attribute takes a vuka.File (@web.Template("views/pet.html")) is checked at compile time and embedded in the binary; f.Bytes() reads it, and vuka.TemplComponents(f) gives a .templ file's components with their parameter names — also for a .templ file in a subdirectory, which is a package of its own (package views).

Static fields and methods belong to a type, as in Kotlin or Java:

type User struct {
	Name string

	static Table   = "users"
	static created int            // private: lowercase, as in Go
	static const Max = 100
}

func User.New(name string) *User {
	User.created++
	return &User{Name: name}
}

u := User.New("ada")
fmt.Println(User.Table, User.Max)

They lower to plain package-level Go: User_Table, _User_created, func User_New, which is also how Go code reaches them. A static can't share a name with a field or method (in Go, User.Save already means a method).

A static on a generic type has one value per instantiation, and statics are reached through embedding. With a base type whose type parameter is named Self, Vuka fills in the embedding type, and methods taking self *Self get the whole outer value. That's enough for a Django-style model API:

// package orm
type Model[Self any] struct {
	static Objects = Manager[Self]{}
}

func (m *Model[Self]) Save(self *Self, ctx context.Context) error { … }

// your models
type User struct {
	orm.Model               // = orm.Model[User]
	Name string
}

users := User.Objects.All(ctx)   // the User manager, from orm.Model
err := u.Save(ctx)               // Save gets u itself as self

orm.Model[User] written out works the same. Self is filled in only for a type parameter of that name, so other generics never get a type argument you didn't write. A type embedding User reaches User's statics, as Go promotes fields; self there is the embedded User. Calls that pass self must not have side effects in the receiver expression (Vuka uses it twice).

Field attributes and references. A struct field takes typed attributes after it (after its tag, if any), and Type.Field — meaningless in Go — is a typed reference to the field:

type Post struct {
	ID     int64    @PK
	Title  string   `json:"title"` @Char{Max: 200}
	Author FK[User] @Rel{OnDelete: Cascade}
	Views  int      @Default(0)
}

q := vuka.And(Post.Title.Contains("go"), Post.Author.Name.Eq("ada"), Post.Views.Gt(100))
q.Match(post)                         // in memory; or translate q.Op, q.Path, q.Value
vuka.SortBy(posts, Post.Views.Desc())

Attributes are type-checked Go values, stripped from the struct and recorded at init: vuka.FieldAttrs[Post]()["Title"], vuka.FieldsOf[Post](), or Attrs in a type decorator's fields. A reference continues through struct and pointer fields, embedded structs, and types implementing vuka.Related[U] (a foreign key's Related() *U). Its type follows the field's — StringRef has Contains, OrderedRef has Gt, NullableRef has IsNil — and its predicates are vuka.Pred[Post], so an API taking them rejects a User field. Hover and go to definition on a reference land on the field.

Dependency injection comes from a type decorator, with no annotations on fields: a struct's fields are its dependencies.

@di.Component
type OrderService struct {
	db    *DB
	users *UserService
	mu    sync.Mutex `inject:"-"`   // not a dependency
}

A type decorator func(t *vuka.Type) on a struct gets t.New, a constructor taking each injected field as a parameter, func(db *DB, users *UserService) *OrderService: the shape nexus.Provide, fx.Provide and dig.Provide take, so a container wires it from parameter types, with no reflection on fields (and unexported fields work). Every field is injected except _, those tagged inject:"-", and embedded values (embedded pointers and interfaces are). A struct that declares its own static New is built with that instead; otherwise the generated constructor is its static New, handy in tests: OrderService.New(fakeDB, fakeUsers). t.Fields lists the fields with their tags, attributes and whether they're injected.

The whole nexus integration is a few lines (examples/nexus-di):

var providers []any

func Component(t *vuka.Type) { providers = append(providers, t.New) }
func Module() nexus.Option  { return nexus.Provide(providers...) }

CLI

vuka new <dir> [module path]
vuka mod tidy|why|vendor|… [args]
vuka explain [-full] file.vuka
vuka fix [-n] [fixer…]
vuka fmt [-l] [-w] [-d] [paths…]
vuka build|run|test|vet|install [go flags] [packages]
vuka gen [-check] [-o build]
vuka gen -inplace [-check] [dir | dir/...]
vuka lsp

build, run and the rest transpile the module into a temporary overlay (go build -overlay), so no generated file lands among your sources.

vuka explain file.vuka shows each line Vuka rewrites beside the Go it becomes, then the code it adds after the source (decorator wrappers, statics), each labelled with the line it comes from; -full prints the whole generated file.

vuka fmt formats .vuka files the way gofmt formats Go (-w writes them back, -l lists those that differ, -d shows the diff): the Go exactly as gofmt prints it, Vuka's syntax spaced to match, and JSX laid out Prettier-style, without changing what a page renders.

vuka fix repairs what tooling can: runtime upgrades the module's Vuka runtime when generated code needs a newer one, static-names rewrites statics spelt by their Go names (User_Table) to User.Table in .vuka files, and orphans removes files vuka gen -inplace wrote for .vuka files that are gone, and attr-of renames vuka.Attr[T](c) to vuka.AttrOf[T](c) (v0.5.0). -n reports without changing anything; name fixers to run only those. It is also where future syntax changes will get their codemods.

Components and JSX. Markup is an expression, and a component is a function returning a vuka.Node, which is templ.Component:

func PetRow(pet Pet) vuka.Node {
	return <tr><td>{pet.Name}</td><td>{pet.Age}</td></tr>
}

func Page(pets []Pet) vuka.Node {
	return <Shell title="Pets">                      // a templ component
		<table>{for _, p := range pets { <PetRow pet={p} /> }}</table>
	</Shell>
}

Attributes bind to parameters by name (or to a props struct's fields), children to a children parameter; {for}, {if} and {match} blocks hold markup. .templ files compile with the package, no templ generate, and call Vuka components back. vuka.Handler/Write/String render HTML; vuka/term renders the same tree as terminal text. A struct embedding vuka.Live is a stateful component — exported fields are props, unexported ones state, and onClick={c.Inc} an event handler — which vuka/live keeps alive for a connected page, answering each event with the components whose HTML changed. See Components and JSX.

The build module

Like Kotlin's build/, vuka build and vuka gen keep a build/ directory: a complete Go module with the same module path, where every .vuka file is replaced by its generated Go and everything else is copied (.go files, embedded assets, testdata; relative replace paths in go.mod adjusted). Inside it, plain Go tools need no Vuka at all:

vuka gen
cd build && go build ./... && go test ./... && go vet ./...

The sync is incremental (only changed files are written, deleted sources are removed), compile errors in build/ point at the .vuka lines, and a .vuka-build marker means vuka never syncs over a directory it didn't make. vuka new adds /build/ to .gitignore. vuka gen -check fails when build/ is out of date, for CI.

Roadmap

  1. Enums (sum types) with exhaustive match; lambdas, ?., ??, tuples, functional helpers (the rest of Dingo's set)
  2. Multi-clause functions with patterns and guards; arity overloading for default arguments; Elixir-style module attributes (@max 3, read as @max)
  3. @derive and generator attributes; lowering to native Go when a Go release adds an equivalent feature

Libraries

  • web — a web framework: routes, services and controllers declared with decorators, parameters bound by name, templ / html / JSX views, dependency injection, .env configuration and live components over a WebSocket. Docs: vuka-lang.github.io/vuka/web.
  • orm — a Django-style ORM: models declared with field attributes, queries written with field references, Result/Option terminals, @orm.Transaction, search, several databases and Go migrations. Docs: vuka-lang.github.io/vuka/orm.

Other modules go get your repository root, not build/. To publish a Vuka library for Go users, write the generated files beside the sources and commit them (vuka gen -inplace, and vuka gen -inplace -check in CI).

Known limits

  • Overloads are resolved within a package; calling another package's overloads goes through its @export names.
  • Generic functions can't be overloaded yet.
  • Go's own error messages show mangled names (area__int).
  • An overloaded method can't satisfy an interface method of the plain name.
  • ? ends a statement; it can't sit inside a larger expression, or in an if, for or switch header.
  • Struct patterns of generic types aren't supported yet.

Documentation

Overview

Package vuka is the runtime of Vuka programs: Result and Option.

Vuka code writes Result[User], Ok(u), Err(e), Some(x) and None unqualified; the transpiler points them here. Go code uses the package like any other.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Arg added in v0.2.0

func Arg[T any](c *Call, i int) T

Arg is argument i as a T.

func As added in v0.2.0

func As[T any](v any) T

As converts a value held in an any back to T; nil is T's zero value. It panics, naming both types, when a decorator put something else there.

func AttachLive added in v0.7.0

func AttachLive(c Stateful, inst LiveInstance)

AttachLive binds a component to its session instance. Package live calls it.

func AttrOf added in v0.5.0

func AttrOf[T any](c *Call) (T, bool)

AttrOf is the declaration's typed attribute of type T.

func EventName added in v0.7.0

func EventName(attr string) string

EventName is the DOM event an on… attribute names: onClick is click, onKeyDown keydown.

func FieldAttrs added in v0.7.0

func FieldAttrs[T any]() map[string][]any

FieldAttrs is the typed attributes of T's fields, by field name: for

type Post struct {
	Title string @Char{Max: 200}
}

FieldAttrs[Post]()["Title"] is []any{Char{Max: 200}}. It is nil for a type whose fields carry none.

func FieldAttrsOf added in v0.7.0

func FieldAttrsOf(t reflect.Type) map[string][]any

FieldAttrsOf is FieldAttrs for a reflect.Type.

func Handler added in v0.5.0

func Handler(f func(r *http.Request) (Node, error)) http.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 Instance

func Instance[F any](s *Instances, build func() F) F

Instance returns the instantiation of a generic decorated function whose type is F, building it the first time.

func MountLive added in v0.7.0

func MountLive(ctx context.Context, c Stateful) error

MountLive runs c's Mount method, if it has one: Mount(), Mount() error, Mount(context.Context) or Mount(context.Context) error.

func RegisterFields added in v0.7.0

func RegisterFields[T any](attrs map[string][]any)

RegisterFields records the typed attributes written on T's fields, by field name. Generated code calls it at init, for every struct with field attributes.

func RegisterTempl added in v0.6.0

func RegisterTempl(key string, components ...TemplComponent)

RegisterTempl records the components compiled from a .templ file. Generated code calls it.

func SortBy added in v0.7.0

func SortBy[T any](xs []T, orders ...Order[T])

SortBy sorts xs by the orders, the first deciding, the next breaking ties; the sort is stable.

func String added in v0.5.0

func String(ctx context.Context, n Node) (string, error)

String renders n as HTML into a string.

func Void added in v0.5.0

func Void(tag string) bool

Void reports whether tag is a void element: no children, no closing tag.

func Walk added in v0.5.0

func Walk(ctx context.Context, n Node, r Renderer) error

Walk sends n's tree to r. 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 added in v0.7.0

func WithLiveHost(ctx context.Context, h LiveHost) context.Context

WithLiveHost is ctx carrying h.

func Write added in v0.5.0

func Write(w http.ResponseWriter, r *http.Request, n Node) error

Write renders n with r's context and sends it as text/html (unless a Content-Type is set already). The page is rendered in full first, so a render error is returned with nothing written.

Types

type Attr added in v0.2.0

type Attr struct {
	Name  string
	Value any
}

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 added in v0.5.0

type Boundary struct {
	Fallback func(err error) Node
	Children []Node
}

Boundary renders Children or, when one of them fails, Fallback(err) in place of everything they produced.

func (Boundary) Render added in v0.5.0

func (n Boundary) Render(ctx context.Context, w io.Writer) error

type Builder added in v0.5.0

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.

func (Builder) Render added in v0.5.0

func (n Builder) Render(ctx context.Context, w io.Writer) error

type Call added in v0.2.0

type Call struct {
	Name     string
	Receiver any   // the receiver, for a method
	Args     []any // the arguments; a variadic parameter is one slice
	Results  []any // the results, once Next has run (or Return was called)
	// contains filtered or unexported fields
}

Call is one call of a decorated function, passed down its decorators.

func NewCall added in v0.2.0

func NewCall(fn *Func, chain []Decorator, recv any, args []any, invoke func(c *Call) []any) *Call

NewCall starts a call through chain, ending in invoke. Generated code calls it.

func (*Call) Attr added in v0.2.0

func (c *Call) Attr(ptr any) bool

Attr fills ptr with the declaration's typed attribute of ptr's element type, reporting whether there is one: var r Route; c.Attr(&r).

func (*Call) Context added in v0.2.0

func (c *Call) Context() context.Context

Context is the call's context.Context argument, or context.Background().

func (*Call) Err added in v0.2.0

func (c *Call) Err() error

Err is the function's error result, or nil.

func (*Call) Next added in v0.2.0

func (c *Call) Next()

Next runs the rest of the chain: the next decorator, or the function itself. It can be called more than once.

func (*Call) Return added in v0.2.0

func (c *Call) Return(results ...any)

Return sets the results without running the function; the rest of the chain is skipped unless Next is called.

func (*Call) Run added in v0.2.0

func (c *Call) Run()

Run runs the chain and checks what it left in Results. Generated code calls it.

func (*Call) SetErr added in v0.2.0

func (c *Call) SetErr(err error)

SetErr replaces the error result. Before Next, it makes the call fail with zero values and err.

type CompareRef added in v0.7.0

type CompareRef[T any, V interface{ Compare(V) int }] struct{ Ref[T, V] }

CompareRef is a reference to a field whose type orders itself, such as time.Time.

func CompareRefOf added in v0.7.0

func CompareRefOf[T any, V interface{ Compare(V) int }](index [][]int, _ func(*T)) CompareRef[T, V]

func (CompareRef[T, V]) Asc added in v0.7.0

func (r CompareRef[T, V]) Asc() Order[T]

func (CompareRef[T, V]) Desc added in v0.7.0

func (r CompareRef[T, V]) Desc() Order[T]

func (CompareRef[T, V]) Ge added in v0.7.0

func (r CompareRef[T, V]) Ge(v V) Pred[T]

Ge is the predicate field >= v, by V's Compare.

func (CompareRef[T, V]) Gt added in v0.7.0

func (r CompareRef[T, V]) Gt(v V) Pred[T]

Gt is the predicate field > v, by V's Compare.

func (CompareRef[T, V]) Le added in v0.7.0

func (r CompareRef[T, V]) Le(v V) Pred[T]

Le is the predicate field <= v, by V's Compare.

func (CompareRef[T, V]) Lt added in v0.7.0

func (r CompareRef[T, V]) Lt(v V) Pred[T]

Lt is the predicate field < v, by V's Compare.

type ComponentNode added in v0.7.0

type ComponentNode struct {
	Site  string
	Key   any
	Props Stateful
}

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.

func (*ComponentNode) Render added in v0.7.0

func (n *ComponentNode) Render(ctx context.Context, w io.Writer) error

type Decl added in v0.6.0

type Decl struct {
	Name  string // "main.ShowPet", "PetAdmin.Index"
	Pkg   string // the package's import path
	File  string // the source file's base name, and the line of the name, for messages
	Line  int
	Attrs []any // the declaration's typed attributes
	// Func is the function, wrapped by the declaration's other decorators, so
	// calling it runs them too. For a method it is the method expression:
	// func(recv, args…).
	Func     any
	Recv     reflect.Type // the receiver type, for a method
	Params   []Param      // the parameters, receiver excluded
	Results  []reflect.Type
	Variadic bool
}

Decl describes a declaration for a declarer: a decorator of type func(d *vuka.Decl), which runs once at program start rather than around each call. Declarers register things — routes, commands, jobs — from the declarations they decorate:

func Get(path string) func(*vuka.Decl) {
	return func(d *vuka.Decl) { routes[path] = d.Func }
}

func FuncDecl added in v0.6.0

func FuncDecl(d Decl, params ...string) *Decl

FuncDecl describes a function for its declarers, given its parameters' names. Generated code calls it.

func MethodDecl added in v0.6.0

func MethodDecl(d Decl, params ...string) *Decl

MethodDecl describes a method, d.Func being its method expression. Generated code calls it.

func (*Decl) Attr added in v0.6.0

func (d *Decl) Attr(ptr any) bool

Attr fills ptr with the declaration's typed attribute of ptr's element type, reporting whether there is one: var r Route; d.Attr(&r).

type Decorated

type Decorated[F any] struct {
	// contains filtered or unexported fields
}

Decorated holds a decorated function, built from its decorators on first use. Vuka generates one per decorated function or method.

func (*Decorated[F]) Get

func (d *Decorated[F]) Get(build func() F) F

Get returns the decorated function, building it the first time.

type Decorator added in v0.2.0

type Decorator func(c *Call)

Decorator wraps a call of any function: it runs code around c.Next(), may change c.Args before it, read or replace c.Results after it, call it again (retries) or not at all (caches). Written once, it decorates any function or method:

func logged(c *vuka.Call) {
	fmt.Println("calling", c.Name, c.Args)
	c.Next()
}

A decorator with parameters is a function returning one; it runs once per decorated function, so state it keeps isn't shared between functions.

type Element added in v0.5.0

type Element struct {
	Tag      string
	Attrs    []Attr
	Children []Node
}

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.

func (*Element) Render added in v0.5.0

func (n *Element) Render(ctx context.Context, w io.Writer) error

type Event added in v0.7.0

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 vuka.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 added in v0.7.0

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.

func On added in v0.7.0

func On(fn any) EventHandler

On is an on… attribute's expression.

type Field added in v0.3.0

type Field struct {
	Name     string
	Type     reflect.Type
	Tag      reflect.StructTag
	Attrs    []any // the field's typed attributes
	Injected bool  // a parameter of New: not blank, not tagged inject:"-"
}

Field is a field of a struct.

func FieldsOf added in v0.7.0

func FieldsOf[T any]() []Field

FieldsOf describes the fields of the struct T, with their tags and attributes. It is nil when T isn't a struct.

func (Field) Attr added in v0.7.0

func (f Field) Attr(ptr any) bool

Attr fills ptr with the field's typed attribute of ptr's element type, reporting whether there is one: var c Char; f.Attr(&c).

type FieldPath added in v0.7.0

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

FieldPath is where a field reference leads from its root struct: one step per field written (Post.Author.Name has two), each step an index path that passes through embedded structs. Between steps it goes through a pointer or a Related value.

func (FieldPath) Attr added in v0.7.0

func (p FieldPath) Attr(ptr any) bool

Attr fills ptr with the last field's typed attribute of ptr's element type.

func (FieldPath) Attrs added in v0.7.0

func (p FieldPath) Attrs() []any

Attrs are the typed attributes of the last field.

func (FieldPath) Fields added in v0.7.0

func (p FieldPath) Fields() []reflect.StructField

Fields are the struct fields of each step.

func (FieldPath) Index added in v0.7.0

func (p FieldPath) Index() [][]int

Index is the reflect index path of each step.

func (FieldPath) Names added in v0.7.0

func (p FieldPath) Names() []string

Names are the fields as written: ["Author", "Name"].

func (FieldPath) Root added in v0.7.0

func (p FieldPath) Root() reflect.Type

Root is the struct type the path starts from.

func (FieldPath) String added in v0.7.0

func (p FieldPath) String() string

func (FieldPath) Value added in v0.7.0

func (p FieldPath) Value(root any) (any, bool)

Value follows the path in root, a value or pointer of the root type. It reports false when a nil pointer or relation is on the way.

type File added in v0.6.0

type File string

File names a file of the program's source tree. A string literal written where a decorator or typed attribute takes a File is checked when the program is compiled (it must exist, in the package's directory or below) and embedded into the binary; the File then holds "importpath:relative/path" and Bytes returns the embedded content:

func Template(view vuka.File) func(*vuka.Decl) { … view.Bytes() … }

@Template("views/pet.html")
func showPet(id int) Pet { … }

For a .templ file, TemplComponents also gives its components. The file may be in a subdirectory that is a package of its own (views/pets.templ with `package views`): its File is then that package's ("module/views:pets.templ") and the generated code imports it.

func FileOf added in v0.6.0

func FileOf(key, data string) File

FileOf is an embedded file's File. Generated code calls it.

func (File) Bytes added in v0.6.0

func (f File) Bytes() ([]byte, error)

Bytes is the file's content: embedded, or for a File Vuka didn't embed (a conversion such as vuka.File("x.txt")) read from disk.

func (File) Path added in v0.6.0

func (f File) Path() string

Path is the file's path, relative to its package's directory.

func (File) Pkg added in v0.6.0

func (f File) Pkg() string

Pkg is the import path of the package the file belongs to; "" for a File Vuka didn't embed.

type Func added in v0.2.0

type Func struct {
	Name     string // "main.charge", "Store.Save"
	Attrs    []any  // the declaration's typed attributes
	ErrIndex int    // the trailing error result's index, or -1
	CtxIndex int    // the context.Context argument's index, or -1
	Zero     func() []any
}

Func describes a decorated function. Vuka generates one per function.

type Group added in v0.5.0

type Group []Node

Group is children with no element around them.

func (Group) Render added in v0.5.0

func (n Group) Render(ctx context.Context, w io.Writer) error

type HTMLRenderer added in v0.5.0

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 added in v0.5.0

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 added in v0.5.0

func (h *HTMLRenderer) Close(e *Element) error

func (*HTMLRenderer) Opaque added in v0.5.0

func (h *HTMLRenderer) Opaque(ctx context.Context, n Node) error

func (*HTMLRenderer) Open added in v0.5.0

func (h *HTMLRenderer) Open(e *Element) error

func (*HTMLRenderer) Raw added in v0.5.0

func (h *HTMLRenderer) Raw(html string) error

func (*HTMLRenderer) Text added in v0.5.0

func (h *HTMLRenderer) Text(s string) error

type Instances

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

Instances holds a generic decorated function's instantiations, each built from its decorators on first use.

type Live added in v0.7.0

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 {
	vuka.Live
	Start int // exported fields are props, set from the tag's attributes
	n     int // unexported fields are state
}

Rendered without a live session (vuka.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.

func (*Live) ID added in v0.7.0

func (l *Live) ID() string

ID is the instance's id in its session, the value of its root element's data-vk-id; "" when rendered without one.

func (*Live) Subscribe added in v0.7.0

func (l *Live) Subscribe(topics ...string)

Subscribe asks the session for the messages published on topics, delivered to the component's Update methods. Without a session it does nothing.

type LiveHost added in v0.7.0

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 added in v0.7.0

type LiveInstance interface {
	ID() string
	Subscribe(topics ...string)
}

LiveInstance is a session's side of a component instance. Package live implements it.

type Node added in v0.5.0

type Node = templ.Component

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) 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 added in v0.5.0

func Child(v any) Node

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 Component added in v0.7.0

func Component(site string, key any, props Stateful) Node

Component is a stateful component's tag.

func El added in v0.5.0

func El(tag string, attrs []Attr, children ...Node) Node

El is an element.

func ErrorBoundary added in v0.5.0

func ErrorBoundary(fallback func(err error) Node, children ...Node) Node

ErrorBoundary renders children, or — when one of them fails — fallback(err) in place of everything they wrote.

func Fragment added in v0.5.0

func Fragment(children ...Node) Node

Fragment renders children in order, with no element around them.

func Nodes added in v0.5.0

func Nodes(build func(add func(Node))) Node

Nodes is the children a loop, if or match block produces.

func Safe added in v0.5.0

func Safe(html string) Node

Safe is trusted HTML, written as is. Never pass it user input.

func Text added in v0.5.0

func Text(v any) Node

Text is text: v formatted like fmt.Sprint, nil as nothing.

func Try added in v0.5.0

func Try(n Node, err error) Node

Try is a (Node, error) component's result as a child.

type NodeFunc added in v0.5.0

type NodeFunc = templ.ComponentFunc

NodeFunc is a function rendering HTML: templ.ComponentFunc.

type NullableRef added in v0.7.0

type NullableRef[T, V any] struct{ Ref[T, V] }

NullableRef is a reference to a field that can be nil or None.

func NullableRefOf added in v0.7.0

func NullableRefOf[T, V any](index [][]int, _ func(*T)) NullableRef[T, V]

func (NullableRef[T, V]) IsNil added in v0.7.0

func (r NullableRef[T, V]) IsNil() Pred[T]

IsNil is the predicate that the field is nil or None (or that a nil pointer or relation is on the way).

func (NullableRef[T, V]) NotNil added in v0.7.0

func (r NullableRef[T, V]) NotNil() Pred[T]

NotNil is the predicate that the field is neither nil nor None.

type Op added in v0.7.0

type Op string

Op is what a predicate tests.

const (
	OpEq         Op = "eq"
	OpNe         Op = "ne"
	OpLt         Op = "lt"
	OpLe         Op = "le"
	OpGt         Op = "gt"
	OpGe         Op = "ge"
	OpIn         Op = "in"
	OpContains   Op = "contains"
	OpStartsWith Op = "startswith"
	OpEndsWith   Op = "endswith"
	OpIsNil      Op = "isnil"
	OpNotNil     Op = "notnil"
	OpAnd        Op = "and"
	OpOr         Op = "or"
	OpNot        Op = "not"
)

type Option

type Option[T any] struct {
	// contains filtered or unexported fields
}

Option is a value that may be absent. The zero Option is None.

func FromPtr

func FromPtr[T any](p *T) Option[T]

FromPtr is None for a nil pointer and Some(*p) otherwise.

func MapOption

func MapOption[T, U any](o Option[T], f func(T) U) Option[U]

MapOption applies f to a present value.

func None

func None[T any]() Option[T]

None is an absent value. Vuka code writes plain None; the transpiler fills in T from where the value goes.

func Some

func Some[T any](v T) Option[T]

Some is a present value.

func (Option[T]) Get

func (o Option[T]) Get() (T, bool)

Get is Go's comma-ok form: v, ok := o.Get().

func (Option[T]) IsNone

func (o Option[T]) IsNone() bool

func (Option[T]) IsSome

func (o Option[T]) IsSome() bool

func (Option[T]) String

func (o Option[T]) String() string

func (Option[T]) Unwrap

func (o Option[T]) Unwrap() T

Unwrap is the value; it panics when o is None.

func (Option[T]) UnwrapOr

func (o Option[T]) UnwrapOr(def T) T

UnwrapOr is the value, or def when o is None.

func (Option[T]) Value

func (o Option[T]) Value() T

Value is the value, or T's zero value when o is None.

type Order added in v0.7.0

type Order[T any] struct {
	Path FieldPath
	Desc bool
	// contains filtered or unexported fields
}

Order is an ordering of Ts by a field: Post.Views.Desc().

func (Order[T]) Compare added in v0.7.0

func (o Order[T]) Compare(a, b T) int

Compare orders a and b by o: negative when a comes first. A value whose field can't be reached (a nil pointer or relation on the way) comes first.

func (Order[T]) String added in v0.7.0

func (o Order[T]) String() string

type OrderedRef added in v0.7.0

type OrderedRef[T any, V cmp.Ordered] struct{ Ref[T, V] }

OrderedRef is a reference to a number field (or any cmp.Ordered type).

func OrderedRefOf added in v0.7.0

func OrderedRefOf[T any, V cmp.Ordered](index [][]int, _ func(*T)) OrderedRef[T, V]

func (OrderedRef[T, V]) Asc added in v0.7.0

func (r OrderedRef[T, V]) Asc() Order[T]

func (OrderedRef[T, V]) Desc added in v0.7.0

func (r OrderedRef[T, V]) Desc() Order[T]

func (OrderedRef[T, V]) Ge added in v0.7.0

func (r OrderedRef[T, V]) Ge(v V) Pred[T]

Ge is the predicate field >= v.

func (OrderedRef[T, V]) Gt added in v0.7.0

func (r OrderedRef[T, V]) Gt(v V) Pred[T]

Gt is the predicate field > v.

func (OrderedRef[T, V]) Le added in v0.7.0

func (r OrderedRef[T, V]) Le(v V) Pred[T]

Le is the predicate field <= v.

func (OrderedRef[T, V]) Lt added in v0.7.0

func (r OrderedRef[T, V]) Lt(v V) Pred[T]

Lt is the predicate field < v.

type Param added in v0.6.0

type Param struct {
	Name string
	Type reflect.Type
}

Param is a parameter of a declared function: its name as written ("" when unnamed) and type.

type Pred added in v0.7.0

type Pred[T any] struct {
	Op    Op
	Path  FieldPath // the field tested; zero for and, or and not
	Value any       // the operand: a V, a []V for in; nil for isnil, notnil and the combinations
	Preds []Pred[T] // the operands of and, or and not
	// contains filtered or unexported fields
}

Pred is a condition on a T, built from field references — Post.Views.Gt(100), vuka.Or(…) — and kept as data, so a query builder can translate it (Op, the field's Path and attributes, the Value) or Match can test it in memory. Being typed by T, a Pred[User] can't be passed where a Pred[Post] is wanted.

func And added in v0.7.0

func And[T any](ps ...Pred[T]) Pred[T]

And holds when every p does.

func Not added in v0.7.0

func Not[T any](p Pred[T]) Pred[T]

Not holds when p doesn't.

func Or added in v0.7.0

func Or[T any](ps ...Pred[T]) Pred[T]

Or holds when any p does.

func (Pred[T]) Match added in v0.7.0

func (p Pred[T]) Match(t T) bool

Match tests p on t. A comparison fails when a nil pointer or relation is on the way to its field; IsNil holds.

func (Pred[T]) String added in v0.7.0

func (p Pred[T]) String() string

String writes p readably: Author.Name = "ada", (Views > 100 OR Title contains "go").

type RawHTML added in v0.5.0

type RawHTML string

RawHTML is trusted HTML, written as is.

func (RawHTML) Render added in v0.5.0

func (n RawHTML) Render(ctx context.Context, w io.Writer) error

type Ref added in v0.7.0

type Ref[T, V any] struct {
	// contains filtered or unexported fields
}

Ref is a field reference: Post.Title in Vuka source, a typed handle on the Title field of Post, of type V. Through pointer, struct and Related fields it reaches further: Post.Author.Name. Its methods build predicates and orderings over T, or read the field.

Vuka picks the most capable kind for the field's type: StringRef for strings, OrderedRef for numbers, CompareRef for types with a Compare method (time.Time), NullableRef for pointers, slices, maps, interfaces and Options, and Ref for the rest.

func RefOf added in v0.7.0

func RefOf[T, V any](index [][]int, _ func(*T)) Ref[T, V]

RefOf, OrderedRefOf, StringRefOf, CompareRefOf and NullableRefOf make references; Vuka generates the calls. The function is never called: it is there so the compiler and the editor see the fields the reference names.

func (Ref[T, V]) Asc added in v0.7.0

func (r Ref[T, V]) Asc() Order[T]

Asc orders by the field, smallest first.

func (Ref[T, V]) Attr added in v0.7.0

func (r Ref[T, V]) Attr(ptr any) bool

Attr fills ptr with the field's typed attribute of ptr's element type.

func (Ref[T, V]) Attrs added in v0.7.0

func (r Ref[T, V]) Attrs() []any

Attrs are the typed attributes of the field referred to.

func (Ref[T, V]) Desc added in v0.7.0

func (r Ref[T, V]) Desc() Order[T]

Desc orders by the field, largest first.

func (Ref[T, V]) Eq added in v0.7.0

func (r Ref[T, V]) Eq(v V) Pred[T]

Eq is the predicate field == v.

func (Ref[T, V]) FieldPath added in v0.7.0

func (r Ref[T, V]) FieldPath() FieldPath

FieldPath is where the reference leads.

func (Ref[T, V]) Get added in v0.7.0

func (r Ref[T, V]) Get(t T) V

Get is the field's value in t, or V's zero value when a nil pointer or relation is on the way.

func (Ref[T, V]) In added in v0.7.0

func (r Ref[T, V]) In(vs ...V) Pred[T]

In is the predicate that the field equals one of vs.

func (Ref[T, V]) Lookup added in v0.7.0

func (r Ref[T, V]) Lookup(t T) (V, bool)

Lookup is the field's value in t; false when a nil pointer or relation is on the way.

func (Ref[T, V]) Name added in v0.7.0

func (r Ref[T, V]) Name() string

Name is the path as written, dotted: "Author.Name".

func (Ref[T, V]) Ne added in v0.7.0

func (r Ref[T, V]) Ne(v V) Pred[T]

Ne is the predicate field != v.

func (Ref[T, V]) Path added in v0.7.0

func (r Ref[T, V]) Path() []string

Path is the fields as written: ["Author", "Name"].

type Related[T any] interface{ Related() *T }

Related is implemented by a field type that refers to a T held elsewhere, such as a foreign key. A field reference continues through it into T's fields: with Author of a type implementing Related[User], Post.Author.Name is a Ref[Post, string]. Related returns nil when there is no T.

type Renderer added in v0.5.0

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 Result

type Result[T any] struct {
	// contains filtered or unexported fields
}

Result is a value or an error. It is Ok when it holds no error; the zero Result is Ok with T's zero value.

func AndThen

func AndThen[T, U any](r Result[T], f func(T) Result[U]) Result[U]

AndThen chains a step that can fail.

func Err

func Err[T any](err error) Result[T]

Err is a failed Result. err must not be nil.

func Map

func Map[T, U any](r Result[T], f func(T) U) Result[U]

Map applies f to an Ok value.

func Of

func Of[T any](v T, err error) Result[T]

Of turns Go's (T, error) into a Result: vuka.Of(os.ReadFile(name)).

func Ok

func Ok[T any](v T) Result[T]

Ok is a successful Result.

func (Result[T]) Err

func (r Result[T]) Err() error

Err is the error, or nil when r succeeded.

func (Result[T]) Get

func (r Result[T]) Get() (T, error)

Get turns r back into Go's (T, error).

func (Result[T]) IsErr

func (r Result[T]) IsErr() bool

func (Result[T]) IsOk

func (r Result[T]) IsOk() bool

func (Result[T]) String

func (r Result[T]) String() string

func (Result[T]) Unwrap

func (r Result[T]) Unwrap() T

Unwrap is the value; it panics when r failed.

func (Result[T]) UnwrapOr

func (r Result[T]) UnwrapOr(def T) T

UnwrapOr is the value, or def when r failed.

func (Result[T]) Value

func (r Result[T]) Value() T

Value is the value, or T's zero value when r failed.

type Stateful added in v0.7.0

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.

func CopyLive added in v0.7.0

func CopyLive(c Stateful) Stateful

CopyLive is a shallow copy of c.

type Static added in v0.2.0

type Static[V any] struct {
	V V
}

Static is the storage of a static field of a generic type: one per instantiation, so Model[User] and Model[Order] each have their own.

func StaticOf added in v0.2.0

func StaticOf[K, V any](s *Statics, init func() V) *Static[V]

StaticOf returns the static field of the instantiated type K, built by init on first use. Generated code calls it.

type Statics added in v0.2.0

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

Statics holds one generic static field's instantiations.

type StringRef added in v0.7.0

type StringRef[T any, V ~string] struct{ OrderedRef[T, V] }

StringRef is a reference to a string field.

func StringRefOf added in v0.7.0

func StringRefOf[T any, V ~string](index [][]int, _ func(*T)) StringRef[T, V]

func (StringRef[T, V]) Contains added in v0.7.0

func (r StringRef[T, V]) Contains(s V) Pred[T]

Contains is the predicate that the field contains s.

func (StringRef[T, V]) EndsWith added in v0.7.0

func (r StringRef[T, V]) EndsWith(s V) Pred[T]

EndsWith is the predicate that the field ends with s.

func (StringRef[T, V]) StartsWith added in v0.7.0

func (r StringRef[T, V]) StartsWith(s V) Pred[T]

StartsWith is the predicate that the field starts with s.

type Style added in v0.5.0

type Style map[string]string

Style is an inline style: style={vuka.Style{"color": "red"}}, rendered by templ as "color:red;" sorted by property, each property and value sanitized.

type TemplComponent added in v0.6.0

type TemplComponent struct {
	Name   string
	Func   any
	Params []string
}

TemplComponent is a component of a .templ file: its name, the generated function (func(params…) templ.Component) and its parameters' names.

func TemplComponents added in v0.6.0

func TemplComponents(f File) ([]TemplComponent, bool)

TemplComponents are the components of an embedded .templ file, in source order: all of them for a file of the referencing package, the exported ones for a file of a subdirectory's package.

type TextNode added in v0.5.0

type TextNode string

TextNode is text, escaped when rendered.

func (TextNode) Render added in v0.5.0

func (n TextNode) Render(ctx context.Context, w io.Writer) error

type TryNode added in v0.5.0

type TryNode struct {
	Node Node
	Err  error
}

TryNode is a (Node, error) component's result as a child: Err fails the render, else Node renders.

func (TryNode) Render added in v0.5.0

func (n TryNode) Render(ctx context.Context, w io.Writer) error

type Type added in v0.2.0

type Type struct {
	Name    string // "main.User"
	Reflect reflect.Type
	Attrs   []any   // the declaration's typed attributes
	New     any     // the constructor, for a struct; nil otherwise
	Fields  []Field // the struct's fields
}

Type describes a decorated type, for a type decorator:

func Model(t *vuka.Type) { registry[t.Name] = t.Reflect }

For a struct, New is a constructor taking each dependency field as a parameter (or the type's own static New, when it declares one), which is the shape dependency-injection containers take:

func Component(t *vuka.Type) { providers = append(providers, t.New) }

func TypeOf added in v0.2.0

func TypeOf[T any](name string, attrs ...any) *Type

TypeOf describes T for its decorators. Generated code calls it.

func TypeWith added in v0.3.0

func TypeWith[T any](name string, ctor any, attrs ...any) *Type

TypeWith describes a struct T with its constructor. Generated code calls it.

func (*Type) Attr added in v0.2.0

func (t *Type) Attr(ptr any) bool

Attr fills ptr with the type's typed attribute of ptr's element type.

Directories

Path Synopsis
cmd
vuka command
Command vuka transpiles Vuka source to Go and runs the go command over it.
Command vuka transpiles Vuka source to Go and runs the go command over it.
vukavet module
internal
format
Package format formats Vuka source: the Go in it exactly as gofmt does, and its JSX the way Prettier lays out markup, without changing what it renders.
Package format formats Vuka source: the Go in it exactly as gofmt does, and its JSX the way Prettier lays out markup, without changing what it renders.
load
Package load finds Vuka packages in a module and supplies what transpiling them needs from the go command: build-context file selection, export data for imports, and the overlay that puts generated files in front of the compiler.
Package load finds Vuka packages in a module and supplies what transpiling them needs from the go command: build-context file selection, export data for imports, and the overlay that puts generated files in front of the compiler.
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.
Package templx passes children to templ components.
Package templx passes children to templ components.
Package term renders a vuka 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 vuka 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 transpile turns Vuka source into Go.
Package transpile turns Vuka source into Go.

Jump to

Keyboard shortcuts

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