Documentation ¶
Index ¶
- Constants
- Variables
- func AttrMapFromNode(node *html.Node) map[string]string
- func GenerateRandomString(n int) (string, error)
- func WiredErrorMap() map[string]string
- type BrowserEvent
- type Change
- type ChangeType
- type ChildWiredComponent
- type ComponentContext
- type ComponentLifeCycle
- type ComponentLifeTime
- type ComponentLifeTimeMessage
- type DOMEvent
- type EventSource
- type EventSourceType
- type HTTPHandlerCtx
- type HTTPMiddleware
- type LifeTimeStage
- type LiveWire
- type Log
- type LoggerBasic
- type Page
- type PageContent
- type PageEnum
- type PatchBrowser
- type PatchNodeChildren
- type PatchTreeNode
- type Random
- type Session
- type SessionStatus
- type WireSessions
- type WiredComponent
- func (w *WiredComponent) Create(life *ComponentLifeCycle) error
- func (w *WiredComponent) GetFieldFromPath(path string) *reflect.Value
- func (w *WiredComponent) InvokeMethodInPath(path string, data map[string]string, domEvent *DOMEvent) error
- func (w *WiredComponent) Kill() error
- func (w *WiredComponent) KillChildren()
- func (w *WiredComponent) Mount() error
- func (w *WiredComponent) MountChildren() error
- func (w *WiredComponent) Render() (string, error)
- func (w *WiredComponent) RenderChild(fn reflect.Value, _ ...reflect.Value) template.HTML
- func (w *WiredComponent) SetValueInPath(value string, path string) error
- func (w *WiredComponent) Update()
- func (w *WiredComponent) UpdateWithSource(source *EventSource)
- func (w *WiredComponent) WiredRender() (*patches, error)
- type WiredComponentWrapper
- func (l *WiredComponentWrapper) BeforeMount(_ *WiredComponent)
- func (l *WiredComponentWrapper) BeforeUnmount(_ *WiredComponent)
- func (l *WiredComponentWrapper) Commit()
- func (l *WiredComponentWrapper) Create(lc *WiredComponent)
- func (l *WiredComponentWrapper) Mounted(_ *WiredComponent)
- func (l *WiredComponentWrapper) TemplateHandler(_ *WiredComponent) string
- type WiredEventsChannel
- type WiredPageEvent
- type WiredRenderer
- type WiredResponse
- type WiredServer
- func (s *WiredServer) CreateHTMLHandler(f func() *WiredComponent, c PageContent) func(ctx *fiber.Ctx) error
- func (s *WiredServer) CreateHTMLHandlerWithMiddleware(f func(ctx context.Context) *WiredComponent, content PageContent, ...) func(c *fiber.Ctx) error
- func (s *WiredServer) HandleFirstRequest(lc *WiredComponent, c PageContent) (*WiredResponse, error)
- func (s *WiredServer) HandleHTMLRequest(ctx *fiber.Ctx, lc *WiredComponent, c PageContent)
- func (s *WiredServer) HandlePollRequest()
- func (s *WiredServer) HandleWSRequest(c *websocket.Conn)
- type WiredState
Constants ¶
const ( LogTrace = iota - 1 LogDebug LogInfo LogWarn LogError LogFatal LogPanic )
const ( EventWiredInput = "li" EventWiredMethod = "lm" EventWiredDom = "ld" EventWiredDisconnect = "lx" EventWiredError = "le" EventWiredConnectElement = "lce" )
const ComponentIdAttrKey = "go-wired-component-id"
const (
EventSourceInput = "input"
)
const PageComponentMounted = 2
const PageComponentUpdated = 1
Variables ¶
var ( ErrComponentNotPrepared = errors.New("Component need to be prepared") ErrComponentWithoutLog = errors.New("Component without log defined") ErrComponentNil = errors.New("Component nil") )
var ( ErrCouldNotProvideValidSelector = fmt.Errorf("could not provide a valid selector") ErrElementNotSigned = fmt.Errorf("element is not signed with go-wired-uid") )
var BasePage *template.Template
var BasePageString = `<!DOCTYPE html>
<html lang="{{ .Lang }}">
<head>
<meta charset="UTF-8" />
<title>{{ .Title }}</title>
{{ .Head }}
</head>
<body>
{{ .Body }}
</body>
<script type="application/javascript">
const GO_WIRED_CONNECTED="go-wired-connected",GO_WIRED_COMPONENT_ID="go-wired-component-id",EVENT_WIRED_DOM_COMPONENT_ID_KEY="cid",EVENT_WIRED_DOM_INSTRUCTIONS_KEY="i",EVENT_WIRED_DOM_TYPE_KEY="t",EVENT_WIRED_DOM_CONTENT_KEY="c",EVENT_WIRED_DOM_ATTR_KEY="a",EVENT_WIRED_DOM_SELECTOR_KEY="s",EVENT_WIRED_DOM_INDEX_KEY="i",handleChange={"{{ .Enum.DiffSetAttr }}":handleDiffSetAttr,"{{ .Enum.DiffRemoveAttr }}":handleDiffRemoveAttr,"{{ .Enum.DiffReplace }}":handleDiffReplace,"{{ .Enum.DiffRemove }}":handleDiffRemove,"{{ .Enum.DiffSetInnerHTML }}":handleDiffSetInnerHTML,"{{ .Enum.DiffAppend }}":handleDiffAppend,"{{ .Enum.DiffMove }}":handleDiffMove},goWired={server:createConnection(),handlers:[],once:createOnceEmitter(),getWiredComponent(a){return document.querySelector(["*[",GO_WIRED_COMPONENT_ID,"=",a,"]"].join(""))},on(a,b){const c=this.handlers.push({name:a,handler:b});return c-1},findHandler(a){return this.handlers.filter(b=>b.name===a)},emit(a,b){for(const c of this.findHandler(a))c.handler(b)},off(a){this.handlers.splice(a,1)},send(a){goWired.server.send(JSON.stringify(a))},connectChildren(a){const b=a.querySelectorAll("*["+GO_WIRED_COMPONENT_ID+"]");b.forEach(a=>{this.connectElement(a)})},connectElement(a){if(typeof a=="string"){console.warn("is string");return}if(!isElement(a)){console.warn("not element");return}const b=[],c=findWiredClicksFromElement(a);c.forEach(function(a){const c=getComponentIdFromElement(a);a.addEventListener("click",function(b){goWired.send({name:"{{ .Enum.EventWiredMethod }}",component_id:c,method_name:a.getAttribute("go-wired-click"),method_data:dataFromElementAttributes(a)})}),b.push(a)});const d=findWiredKeyDownFromElement(a);d.forEach(function(a){const e=getComponentIdFromElement(a),f=a.getAttribute("go-wired-keydown"),c=a.attributes;let d=[];for(let a=0;a<c.length;a++)(c[a].name==="go-wired-key"||c[a].name.startsWith("go-wired-key-"))&&d.push(c[a].value);a.addEventListener("keydown",function(g){const c=String(g.code);let b=!0;if(d.length!==0){b=!1;for(let a=0;a<d.length;a++)if(d[a]===c){b=!0;break}}b&&goWired.send({name:"{{ .Enum.EventWiredMethod }}",component_id:e,method_name:f,method_data:dataFromElementAttributes(a),dom_event:{keyCode:c}})}),b.push(a)});const e=findWiredInputsFromElement(a);e.forEach(function(a){const c=a.getAttribute("type"),d=getComponentIdFromElement(a);a.addEventListener("input",function(e){let b=a.value;c==="checkbox"&&(b=a.checked),goWired.send({name:"{{ .Enum.EventWiredInput }}",component_id:d,key:a.getAttribute("go-wired-input"),value:String(b)})}),b.push(a)});for(const a of b)a.setAttribute(GO_WIRED_CONNECTED,!0)},connect(a){const b=goWired.getWiredComponent(a);goWired.connectElement(b),goWired.on("{{ .Enum.EventWiredDom }}",function(b){if(a===b[EVENT_WIRED_DOM_COMPONENT_ID_KEY])for(const c of b[EVENT_WIRED_DOM_INSTRUCTIONS_KEY]){const f=c[EVENT_WIRED_DOM_TYPE_KEY],g=c[EVENT_WIRED_DOM_CONTENT_KEY],h=c[EVENT_WIRED_DOM_ATTR_KEY],d=c[EVENT_WIRED_DOM_SELECTOR_KEY],i=c[EVENT_WIRED_DOM_INDEX_KEY],e=document.querySelector(d);if(!e){console.error("Element not found",d);return}handleChange[f]({content:g,attr:h,index:i},e,a)}})}};goWired.once.on("WS_CONNECTION_OPEN",()=>{goWired.on("{{ .Enum.EventWiredConnectElement }}",a=>{const b=a[EVENT_WIRED_DOM_COMPONENT_ID_KEY];goWired.connect(b)}),goWired.on("{{ .Enum.EventWiredError }}",a=>{console.error("message",a.m),a.m==='{{ index .EnumWiredError ` + "`WiredErrorSessionNotFound`" + `}}'&&window.location.reload(!1)})}),goWired.server.onmessage=a=>{try{const b=JSON.parse(a.data);goWired.emit(b.t,b)}catch(b){console.log("Error",b),console.log("Error message",a.data)}},goWired.server.onopen=()=>{goWired.once.emit("WS_CONNECTION_OPEN")};function createConnection(){const a=[];return window.location.protocol==="https:"?a.push("wss"):a.push("ws"),a.push("://",window.location.host,"/ws"),new WebSocket(a.join(""))}function createOnceEmitter(){const a={},b=(b,c)=>(a[b]={called:c,cbs:[]},a[b]);return{on(d,e){let c=a[d];c||(c=b(d,!1)),c.cbs.push(e)},emit(c,...e){const d=a[c];if(!d){b(c,!0);return}for(const a of d.cbs)a()}}}const findWiredInputsFromElement=a=>a.querySelectorAll(["*[go-wired-input]:not([",GO_WIRED_CONNECTED,"])"].join("")),findWiredClicksFromElement=a=>a.querySelectorAll(["*[go-wired-click]:not([",GO_WIRED_CONNECTED,"])"].join("")),findWiredKeyDownFromElement=a=>a.querySelectorAll(["*[go-wired-keydown]:not([",GO_WIRED_CONNECTED,"])"].join("")),dataFromElementAttributes=c=>{const a=c.attributes;let b={};for(let c=0;c<a.length;c++)a[c].name.startsWith("go-wired-data-")&&(b[a[c].name.substring(13)]=a[c].value);return b};function getElementChild(b,c){let a=b.firstElementChild;while(c>0){if(!a){console.error("Element not found in path",b);return}if(a=a.nextSibling,a.nodeType!==Node.ELEMENT_NODE)continue;c--}return a}function isElement(a){return typeof HTMLElement=="object"?a instanceof HTMLElement:a&&typeof a=="object"&&a.nodeType===1&&typeof a.nodeName=="string"}function handleDiffSetAttr(c,b){const{attr:a}=c;a.Name==="value"&&b.value?b.value=a.Value:b.setAttribute(a.Name,a.Value)}function handleDiffRemoveAttr(a,b){const{attr:c}=a;b.removeAttribute(c.Name)}function handleDiffReplace(d,a){const{content:e}=d,b=document.createElement("div");b.innerHTML=e;const c=a.parentElement;c.replaceChild(b.firstChild,a),goWired.connectElement(c)}function handleDiffRemove(c,a){const b=a.parentElement;b.removeChild(a)}function handleDiffSetInnerHTML(c,a){let{content:b}=c;if(b===void 0&&(b=""),a.nodeType===Node.TEXT_NODE){a.textContent=b;return}a.innerHTML=b,goWired.connectElement(a)}function handleDiffAppend(c,a){const{content:d}=c,b=document.createElement("div");b.innerHTML=d;const e=b.firstChild;a.appendChild(e),goWired.connectElement(a)}function handleDiffMove(c,a){const b=a.parentNode;b.removeChild(a);const d=getElementChild(b,c.index);b.replaceChild(a,d)}const getComponentIdFromElement=a=>{const b=a.getAttribute("go-wired-component-id");return b?b:a.parentElement?getComponentIdFromElement(a.parentElement):void 0}
</script>
</html>
`
Code automatically generated. DO NOT EDIT. > go run ci/create_html_page.go
var (
WiredErrorSessionNotFound = "session_not_found"
)
Functions ¶
func AttrMapFromNode ¶
AttrMapFromNode todo
func GenerateRandomString ¶
func WiredErrorMap ¶
Types ¶
type BrowserEvent ¶
type ChangeType ¶ added in v0.0.2
type ChangeType int
const ( Append ChangeType = iota Remove SetInnerHTML SetAttr RemoveAttr Replace Move )
type ChildWiredComponent ¶
type ChildWiredComponent interface{}
type ComponentContext ¶
type ComponentContext struct {
Pairs map[string]interface{}
}
func NewComponentContext ¶
func NewComponentContext() ComponentContext
type ComponentLifeCycle ¶
type ComponentLifeCycle chan ComponentLifeTimeMessage
type ComponentLifeTime ¶
type ComponentLifeTime interface { Create(component *WiredComponent) TemplateHandler(component *WiredComponent) string Mounted(component *WiredComponent) BeforeMount(component *WiredComponent) BeforeUnmount(component *WiredComponent) }
type ComponentLifeTimeMessage ¶
type ComponentLifeTimeMessage struct { Stage LifeTimeStage Component *WiredComponent Source *EventSource }
type EventSource ¶
type EventSource struct { Type EventSourceType Value string }
type EventSourceType ¶
type EventSourceType string
type HTTPHandlerCtx ¶
HTTPHandlerCtx HTTP Handler with a page level context.
type HTTPMiddleware ¶
type HTTPMiddleware func(next HTTPHandlerCtx) HTTPHandlerCtx
HTTPMiddleware Middleware to run on HTTP requests.
type LifeTimeStage ¶
type LifeTimeStage int
const ( WillCreate LifeTimeStage = iota Created WillMount WillMountChildren ChildrenMounted Mounted Rendered Updated WillUnmount Unmounted )
type LiveWire ¶
type LiveWire struct {
Sessions WireSessions
}
func (*LiveWire) DeleteSession ¶
func (*LiveWire) GetSession ¶
type LoggerBasic ¶
func NewLoggerBasic ¶
func NewLoggerBasic() *LoggerBasic
type Page ¶
type Page struct { Events WiredEventsChannel ComponentsLifeCycle *ComponentLifeCycle // Components is a list that handle all the components from the page Components map[string]*WiredComponent // contains filtered or unexported fields }
func NewWiredPage ¶
func NewWiredPage(c *WiredComponent) *Page
func (*Page) Emit ¶
func (lp *Page) Emit(lts int, c *WiredComponent)
func (*Page) EmitWithSource ¶
func (lp *Page) EmitWithSource(lts int, c *WiredComponent, source *EventSource)
func (*Page) HandleBrowserEvent ¶
func (lp *Page) HandleBrowserEvent(m BrowserEvent) error
func (*Page) SetContent ¶
func (lp *Page) SetContent(c PageContent)
type PageContent ¶
type PageEnum ¶
type PageEnum struct { EventWiredInput string EventWiredMethod string EventWiredDom string EventWiredConnectElement string EventWiredError string NodeSetAttr ChangeType NodeRemoveAttr ChangeType NodeReplace ChangeType NodeRemove ChangeType NodeSetInnerHTML ChangeType NodeAppend ChangeType NodeMove ChangeType }
type PatchBrowser ¶
type PatchBrowser struct { ComponentID string `json:"cid,omitempty"` Type string `json:"t"` Message string `json:"m"` Changes []Change `json:"i,omitempty"` }
func NewPatchBrowser ¶
func NewPatchBrowser(componentID string) *PatchBrowser
type PatchNodeChildren ¶
type PatchNodeChildren map[int]*PatchTreeNode
type PatchTreeNode ¶
type PatchTreeNode struct { Children PatchNodeChildren `json:"c,omitempty"` Changes []Change `json:"i"` }
type Random ¶
type Random struct {
// contains filtered or unexported fields
}
func NewWiredID ¶
func NewWiredID() *Random
func (Random) GenerateSmall ¶
type Session ¶
type Session struct { WiredPage *Page OutChannel chan PatchBrowser Status SessionStatus // contains filtered or unexported fields }
func NewSession ¶
func NewSession() *Session
func (*Session) ActivatePage ¶
func (*Session) IngestMessage ¶
func (session *Session) IngestMessage(message BrowserEvent) error
func (*Session) QueueMessage ¶
func (session *Session) QueueMessage(message PatchBrowser)
func (*Session) WiredRenderComponent ¶
func (s *Session) WiredRenderComponent(c *WiredComponent, source *EventSource) error
WiredRenderComponent render the updated Component and compare with last state. It may apply with *all child components*
type SessionStatus ¶
type SessionStatus string
const ( SessionNew SessionStatus = "n" SessionOpen SessionStatus = "o" SessionClosed SessionStatus = "c" )
type WireSessions ¶
type WiredComponent ¶
type WiredComponent struct { Name string IsMounted bool IsCreated bool Exited bool Context ComponentContext // contains filtered or unexported fields }
func NewWiredComponent ¶
func NewWiredComponent(name string, component ComponentLifeTime) *WiredComponent
NewWiredComponent ...
func (*WiredComponent) Create ¶
func (w *WiredComponent) Create(life *ComponentLifeCycle) error
func (*WiredComponent) GetFieldFromPath ¶
func (w *WiredComponent) GetFieldFromPath(path string) *reflect.Value
GetFieldFromPath ...
func (*WiredComponent) InvokeMethodInPath ¶
func (w *WiredComponent) InvokeMethodInPath(path string, data map[string]string, domEvent *DOMEvent) error
InvokeMethodInPath ...
func (*WiredComponent) KillChildren ¶
func (w *WiredComponent) KillChildren()
func (*WiredComponent) Mount ¶
func (w *WiredComponent) Mount() error
Mount 2. the Component loading html
func (*WiredComponent) MountChildren ¶
func (w *WiredComponent) MountChildren() error
func (*WiredComponent) RenderChild ¶
func (*WiredComponent) SetValueInPath ¶
func (w *WiredComponent) SetValueInPath(value string, path string) error
SetValueInPath ...
func (*WiredComponent) Update ¶
func (w *WiredComponent) Update()
func (*WiredComponent) UpdateWithSource ¶
func (w *WiredComponent) UpdateWithSource(source *EventSource)
func (*WiredComponent) WiredRender ¶
func (w *WiredComponent) WiredRender() (*patches, error)
WiredRender render a new version of the Component, and detect differences from the last render and sets the "new old" version of render
type WiredComponentWrapper ¶
type WiredComponentWrapper struct { Name string Component *WiredComponent }
WiredComponentWrapper is a struct
func (*WiredComponentWrapper) BeforeMount ¶
func (l *WiredComponentWrapper) BeforeMount(_ *WiredComponent)
BeforeMount the Component loading html
func (*WiredComponentWrapper) BeforeUnmount ¶
func (l *WiredComponentWrapper) BeforeUnmount(_ *WiredComponent)
BeforeUnmount before we kill the Component
func (*WiredComponentWrapper) Commit ¶
func (l *WiredComponentWrapper) Commit()
Commit puts an boolean to the commit channel and notifies who is listening
func (*WiredComponentWrapper) Create ¶
func (l *WiredComponentWrapper) Create(lc *WiredComponent)
func (*WiredComponentWrapper) Mounted ¶
func (l *WiredComponentWrapper) Mounted(_ *WiredComponent)
BeforeMount the Component loading html
func (*WiredComponentWrapper) TemplateHandler ¶
func (l *WiredComponentWrapper) TemplateHandler(_ *WiredComponent) string
TemplateHandler ...
type WiredEventsChannel ¶
type WiredEventsChannel chan WiredPageEvent
type WiredPageEvent ¶
type WiredPageEvent struct { Type int Component *WiredComponent Source *EventSource }
type WiredRenderer ¶
type WiredRenderer struct {
// contains filtered or unexported fields
}
func (*WiredRenderer) Render ¶
func (renderer *WiredRenderer) Render(data interface{}) (string, *html.Node, error)
func (*WiredRenderer) WiredRender ¶
func (renderer *WiredRenderer) WiredRender(data interface{}) (*patches, error)
type WiredResponse ¶
type WiredServer ¶
func NewServer ¶
func NewServer() *WiredServer
func (*WiredServer) CreateHTMLHandler ¶
func (s *WiredServer) CreateHTMLHandler(f func() *WiredComponent, c PageContent) func(ctx *fiber.Ctx) error
func (*WiredServer) CreateHTMLHandlerWithMiddleware ¶
func (s *WiredServer) CreateHTMLHandlerWithMiddleware(f func(ctx context.Context) *WiredComponent, content PageContent, middlewares ...HTTPMiddleware) func(c *fiber.Ctx) error
func (*WiredServer) HandleFirstRequest ¶
func (s *WiredServer) HandleFirstRequest(lc *WiredComponent, c PageContent) (*WiredResponse, error)
func (*WiredServer) HandleHTMLRequest ¶
func (s *WiredServer) HandleHTMLRequest(ctx *fiber.Ctx, lc *WiredComponent, c PageContent)
func (*WiredServer) HandlePollRequest ¶
func (s *WiredServer) HandlePollRequest()
func (*WiredServer) HandleWSRequest ¶
func (s *WiredServer) HandleWSRequest(c *websocket.Conn)
type WiredState ¶
type WiredState struct {
// contains filtered or unexported fields
}