vugu: github.com/vugu/vugu Index | Examples | Files | Directories

package vugu

import "github.com/vugu/vugu"

Package vugu provides core functionality including vugu->go codegen and in-browser DOM syncing running in WebAssembly. See http://www.vugu.org/

Since Vugu projects can have both client-side (running in WebAssembly) as well as server-side functionality many of the items in this package are available in both environments. Some however are either only available or only generally useful in one environment.

Common functionality includes the ComponentType interface, and ComponentInst struct corresponding to an instantiated componnet. VGNode and related structs are used to represent a virtual Document Object Model. It is based on golang.org/x/net/html but with additional fields needed for Vugu. Data hashing is performed by ComputeHash() and can be customized by implementing the DataHasher interface.

Client-side code uses JSEnv to maintain a render loop and regenerate virtual DOM and efficiently synchronize it with the browser as needed. DOMEvent is a wrapper around events from the browser and EventEnv is used to synchronize data access when writing event handler code that spawns goroutines. Where appropriate, server-side stubs are available so components can be compiled for both client (WebAssembly) and server (server-side rendering and testing).

Server-side code can use ParserGo and ParserGoPkg to parse .vugu files and code generate a corresponding .go file. StaticHTMLEnv can be used to generate static HTML, similar to the output of JSEnv but can be run on the server. Supported features are approximately the same minus event handling, unapplicable to static output.

Index

Examples

Package Files

component.go data-hasher.go doc.go env-js-stub.go env-static-html.go env.go events-component.go events-dom.go events-dom_dummy.go parser-go-pkg.go parser-go.go parser.go vgnode.go

Constants

const (
    ErrorNode    = VGNodeType(html.ErrorNode)
    TextNode     = VGNodeType(html.TextNode)
    DocumentNode = VGNodeType(html.DocumentNode)
    ElementNode  = VGNodeType(html.ElementNode)
    CommentNode  = VGNodeType(html.CommentNode)
    DoctypeNode  = VGNodeType(html.DoctypeNode)
)

Available VGNodeTypes.

Variables

var DOMEventStub = &DOMEvent{}

DOMEventStub is used as a value to mean "replace this with the actual event that came in". In .vugu files, "event" points to this.

func ComputeHash Uses

func ComputeHash(i interface{}) uint64

ComputeHash performs data hashing. It walks your data structure and hashes the information as it goes. It uses xxhash internally and returns a uint64. It is intended to be both fast and have good hash distribution to avoid collision-related bugs. Maps are sorted by key and then both keys and values are hashed. Nil values are skipped. Behavior is undefined for circular references via interface or pointer. Will call DataHash() method if present (see DataHasher) on a type. Otherwise will walk the data and find primitive values and hash them byte for byte. No guarantee is made about the exact hash algorithm used or how type information is or is not hashed - only that the same data structure should consistently hash to the same value and changing any value in the data tree should change the hash.

Code:

type D struct {
    A string
}
data1 := &D{A: "test1"}
data2 := &D{A: "test2"}

fmt.Println(ComputeHash(data1) == ComputeHash(data1))
fmt.Println(ComputeHash(data1) == ComputeHash(data2))

Output:

true
false

func RegisterComponentType Uses

func RegisterComponentType(tagName string, ct ComponentType)

RegisterComponentType can be called during init to register a component and make it available by default to the rest of the application. A program may retrieved these by calling RegisteredComponentTypes() or it may choose to form its own set. RegisterComponentType() just makes it available in case that's useful. It is good practice for components to register themselves in an init function.

type ComponentInst Uses

type ComponentInst struct {
    Type ComponentType // type of component
    Data interface{}   // data as returned by NewData
}

ComponentInst corresponds to a ComponentType that has been instantiated.

func New Uses

func New(ct ComponentType, props Props) (*ComponentInst, error)

New instantiates a component based on its ComponentType and a set of Props. It essentially just calls NewData and returns a ComponentInst.

type ComponentType Uses

type ComponentType interface {
    BuildVDOM(data interface{}) (vdom *VGNode, css *VGNode, reterr error) // based on the given data, build the VGNode tree
    NewData(props Props) (interface{}, error)                             // initial data when component is instanciated
}

ComponentType is implemented by any type that wants to be a component. The BuildVDOM method is called to generate the virtual DOM for a component; and this method is usually code generated (by ParserGo) from a .vugu file. NewData provides for specific behavior when a component is initialized.

type ComponentTypeMap Uses

type ComponentTypeMap map[string]ComponentType

ComponentTypeMap is a map of the component tag name to a ComponentType.

func RegisteredComponentTypes Uses

func RegisteredComponentTypes() ComponentTypeMap

RegisteredComponentTypes returns a copy of the map of registered component types.

type DOMEvent Uses

type DOMEvent struct {
}

DOMEvent is an event originated in the browser. It wraps the JS event that comes in. It is meant to be used in WebAssembly but some methods exist here so code can compile server-side as well (although DOMEvents should not ever be generated server-side).

func (*DOMEvent) EventEnv Uses

func (e *DOMEvent) EventEnv() EventEnv

EventEnv returns the EventEnv for the current environment and allows locking and unlocking around modifications. See EventEnv struct. Non-wasm implementation returns nil.

func (*DOMEvent) JSEvent Uses

func (e *DOMEvent) JSEvent() interface{}

JSEvent this returns a js.Value in wasm that corresponds to the event object. Non-wasm implementation returns nil.

func (*DOMEvent) JSEventThis Uses

func (e *DOMEvent) JSEventThis() interface{}

JSEventThis returns a js.Value in wasm that corresponds to the "this" variable from the event callback. It is the DOM element the event was attached to. Non-wasm implementation returns nil.

func (*DOMEvent) PreventDefault Uses

func (e *DOMEvent) PreventDefault()

PreventDefault calls preventDefault() on the JS event object. Non-wasm implementation is nop.

func (*DOMEvent) RequestRender Uses

func (e *DOMEvent) RequestRender()

RequestRender tells the environment it should be re-rendered as soon as possible (as soon as it can obtain a read lock). Non-wasm implementation is nop.

type DOMEventHandler Uses

type DOMEventHandler struct {
    ReceiverAndMethodHash uint64        // hash value corresponding to the method and receiver, so we get a unique value for each combination of method and receiver
    Method                reflect.Value // method to be called, with receiver baked into it if needed (see reflect/Value.MethodByName)
    Args                  []interface{} // arguments to be passed in when calling (special case for eventStub)
}

DOMEventHandler is created in BuildVDOM to represent a method call that is performed to handle an event.

type DataHasher Uses

type DataHasher interface {
    DataHash() uint64
}

DataHasher can be implemented by types to override the hashing behavior. ComputeHash() will call DataHash() on an instance of a type if the method is present. Useful for providing fast and stable hashing for structures that are large but only require a small amount data to be examined to determine if changed, or are already hashed internally, etc.

type Env Uses

type Env interface {
    RegisterComponentType(tagName string, ct ComponentType)
    Render() error
}

Env specifies the common methods for environment implementations. See JSEnv and StaticHtmlEnv for implementations.

type EventEnv Uses

type EventEnv interface {
    Lock()         // acquire write lock
    UnlockOnly()   // release write lock
    UnlockRender() // release write lock and request re-render

    RLock()   // acquire read lock
    RUnlock() // release read lock
}

EventEnv provides locking mechanism to for rendering environment to events so data access and rendering can be synchronized and avoid race conditions.

type JSEnv Uses

type JSEnv struct {
    MountParent string    // query selector
    DebugWriter io.Writer // write debug information about render details to this Writer if not nil
}

JSEnv is responsible for rendering (efficiently synchronizing) HTML in the browser in a WebAssembly application. Browser calls are performed using syscall/js. Various internal hashing and other optimizations are performed to attempt to make rendering as effience as possible. If used outside of a wasm program all methods will panic.

func NewJSEnv Uses

func NewJSEnv(mountParent string, rootInst *ComponentInst, components ComponentTypeMap) *JSEnv

NewJSEnv returns a new instance with the specified mountParent (CSS selector of where in the HTML the ouptut will go), the root component instance, and any other component types available.

func (*JSEnv) EventWait Uses

func (e *JSEnv) EventWait() bool

EventWait blocks until an event occurs and re-rendering is needed. Returns true unless the browser has gone away and the program should exit.

func (*JSEnv) RegisterComponentType Uses

func (e *JSEnv) RegisterComponentType(tagName string, ct ComponentType)

RegisterComponentType assigns a component type to a tag name.

func (*JSEnv) Render Uses

func (e *JSEnv) Render() error

Render is where the magic happens and your root component instance has its virtual DOM rendered and synchronized to the browser DOM. Render attempts to perform as few operations as possible and uses hashing to avoid unnecessary work. Component instances of children of the root component (referenced with HTML tags that have the components tag name), are managed as rendering occurs. Child components are created according to a hash of their properties and are recreated if their position in the DOM changes OR if their properties (HTML attributes on the referencing tag) change. Render is normally called in a loop with EventWait() being used to block until re-rendering is needed.

type ParserGo Uses

type ParserGo struct {
    PackageName   string // name of package to use at top of files
    ComponentType string // just the struct name, no "*"
    DataType      string // just the struct name, no "*"
    OutDir        string // output dir
    OutFile       string // output file name with ".go" suffix
}

ParserGo is a template parser that emits Go source code that will construct the appropriately wired VGNodes.

func (*ParserGo) Parse Uses

func (p *ParserGo) Parse(r io.Reader) error

Parse will parse a .vugu file and write out a Go source code file to OutFile.

type ParserGoPkg Uses

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

ParserGoPkg knows how to perform source file generation in relation to a package folder. Whereas ParserGo handles converting a single template, ParserGoPkg is a higher level interface and provides the functionality of the vugugen command line tool. It will scan a package folder for .vugu files and convert them to .go, with the appropriate defaults and logic.

func NewParserGoPkg Uses

func NewParserGoPkg(pkgPath string, opts *ParserGoPkgOpts) *ParserGoPkg

NewParserGoPkg returns a new ParserGoPkg with the specified options or default if nil. The pkgPath is required and must be an absolute path.

func (*ParserGoPkg) Run Uses

func (p *ParserGoPkg) Run() error

Run does the work and generates the appropriate .go files from .vugu files. It will also create a go.mod file if not present and not SkipGoMod. Same for main.go and SkipMainGo (will also skip if package already has file with package name something other than main). Per-file code generation is performed by ParserGo.

type ParserGoPkgOpts Uses

type ParserGoPkgOpts struct {
    SkipRegisterComponentTypes bool // indicates func init() { vugu.RegisterComponentType(...) } code should not be emitted in each file
    SkipGoMod                  bool // do not try and create go.mod if it doesn't exist
    SkipMainGo                 bool // do not try and create main_wasm.go if it doesn't exist in a main package
}

ParserGoPkgOpts is the options for ParserGoPkg.

type Props Uses

type Props map[string]interface{}

Props is a map that corresponds to property names and values. The name can correspond to an HTML attribute, or a property being passed in during component instantiation, depending on the context.

func (Props) Clone Uses

func (p Props) Clone() Props

Clone makes a copy of the Props map, distinct from the original.

func (Props) Merge Uses

func (p Props) Merge(p2 Props) Props

Merge will copy everything from p2 into p and return p for ease of use. Does not copy p.

func (Props) OrderedKeys Uses

func (p Props) OrderedKeys() []string

OrderedKeys returns the keys sorted alphabetically.

type StaticHTMLEnv Uses

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

StaticHTMLEnv is an environment that renders to static HTML. Can be used to implement "server side rendering" as well as during testing.

func NewStaticHTMLEnv Uses

func NewStaticHTMLEnv(out io.Writer, rootInst *ComponentInst, components ComponentTypeMap) *StaticHTMLEnv

NewStaticHTMLEnv returns a new instance of StaticHTMLEnv initialized properly. The out and rootInst are required, components may be nil.

func (*StaticHTMLEnv) RegisterComponentType Uses

func (e *StaticHTMLEnv) RegisterComponentType(tagName string, ct ComponentType)

RegisterComponentType sets a component type with its tag name.

func (*StaticHTMLEnv) Render Uses

func (e *StaticHTMLEnv) Render() error

Render performs redering to static HTML. The logic used is similar to JSEnv.Render however it will discard DOM events and is less careful about managing component lifecycle: components are simply created when needed and discarded after.

type VGAtom Uses

type VGAtom uint32

VGAtom is an integer corresponding to golang.org/x/net/html/atom.Atom. Note that this may be removed for simplicity and to remove the dependency on the package above. Suggest you don't use it.

type VGAttribute Uses

type VGAttribute struct {
    Namespace, Key, Val string
}

VGAttribute is the attribute on an HTML tag.

type VGNode Uses

type VGNode struct {
    Parent, FirstChild, LastChild, PrevSibling, NextSibling *VGNode

    Type      VGNodeType
    DataAtom  VGAtom
    Data      string
    Namespace string
    Attr      []VGAttribute

    Props Props // dynamic attributes, used as input for components or converted to attributes for regular HTML elements

    InnerHTML string // indicates that children should be ignored and this raw HTML is the children of this tag

    DOMEventHandlers map[string]DOMEventHandler // describes invocations when DOM events happen
    // contains filtered or unexported fields
}

VGNode represents a node from our virtual DOM with the dynamic parts wired up into functions.

func (*VGNode) AppendChild Uses

func (n *VGNode) AppendChild(c *VGNode)

AppendChild adds a node c as a child of n.

It will panic if c already has a parent or siblings.

func (*VGNode) InsertBefore Uses

func (n *VGNode) InsertBefore(newChild, oldChild *VGNode)

InsertBefore inserts newChild as a child of n, immediately before oldChild in the sequence of n's children. oldChild may be nil, in which case newChild is appended to the end of n's children.

It will panic if newChild already has a parent or siblings.

func (*VGNode) RemoveChild Uses

func (n *VGNode) RemoveChild(c *VGNode)

RemoveChild removes a node c that is a child of n. Afterwards, c will have no parent and no siblings.

It will panic if c's parent is not n.

func (*VGNode) SetDOMEventHandler Uses

func (n *VGNode) SetDOMEventHandler(name string, h DOMEventHandler)

SetDOMEventHandler will assign a named event to DOMEventHandlers (will allocate the map if nil). Used during VDOM construction and during render to determine browser events to hook up.

func (*VGNode) Walk Uses

func (vgn *VGNode) Walk(f func(*VGNode) error) error

Walk will walk the tree under a VGNode using the specified callback function. If the function provided returns a non-nil error then walking will be stopped and this error will be returned. Only FirstChild and NextSibling are used while walking and so with well-formed documents should not loop. (But loops created manually by modifying FirstChild or NextSibling pointers could cause this function to recurse indefinitely.) Note that f may modify nodes as it visits them with predictable results as long as it does not modify elements higher on the tree (up, toward the parent); it is safe to modify self and children.

type VGNodeType Uses

type VGNodeType uint32

VGNodeType is one of the valid node types (error, text, docuemnt, element, comment, doctype). Note that only text, element and comment are currently used.

Directories

PathSynopsis
cmd/vugufmt
cmd/vugugenvugugen is a command line tool to convert .vugu files into Go source code.
distutilPackage distutil has some useful functions for building your Vugu application's distribution
internal/htmlxPackage htmlx is a fork of https://github.com/golang/net/html.
internal/htmlx/atomPackage atom provides integer codes (also known as atoms) for a fixed set of frequently occurring HTML strings: tag names and attribute keys such as "p" and "id".
internal/htmlx/charsetPackage charset provides common text encodings for HTML documents.
simplehttpPackage simplehttp provides an http.Handler that makes it easy to serve Vugu applications.
vugufmtPackage vugufmt provides gofmt-like functionality for vugu files.

Package vugu imports 23 packages (graph) and is imported by 2 packages. Updated 2019-07-21. Refresh now. Tools for package owners.