crater

package module
v1.9.0 Latest Latest
Warning

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

Go to latest
Published: Aug 6, 2023 License: GPL-2.0 Imports: 17 Imported by: 0

README

Crater

A simple and easy to use webassembly library which allows you to more easily write frontend code inside of Golang.

Best to be compiled with TinyGo, this can save you a lot of size on the resulting binary.

Example file:

import (
	"fmt"
	"time"

	"github.com/Nigel2392/crater"
	"github.com/Nigel2392/crater/craterhttp"
	"github.com/Nigel2392/crater/decoder"
	"github.com/Nigel2392/crater/loader"
	"github.com/Nigel2392/crater/logger"
	"github.com/Nigel2392/crater/messenger"
	"github.com/Nigel2392/jsext/v2"
	"github.com/Nigel2392/jsext/v2/console"
	"github.com/Nigel2392/jsext/v2/websocket"
)

var app, _ = jsext.GetElementById("app")

// Main webassembly entry point
func main() {
	var loader, err = loader.NewLoader(
		loader.ID("loader"),                  // set the loader element's id to "loader"
		loader.ClassList([]string{"loader"}), // add the loader class to the loader element
		loader.QuerySelector("body"),         // the element where the attributes will be added to (Can be added also with loader.Element())
		loader.Element(jsext.Body),           // the element where the attributes will be added to (Can be added also with loader.QuerySelector())
	)
	if err != nil {
		console.Error(err)
		return
	}

	// Initialize a logger to use.
	var log = logger.StdLogger
	log.Loglevel(logger.Debug)

	// Initialize a new application
	crater.New(&crater.Config{
		RootElement:     app,
		Loader:          loader,
		Logger:          log,
		Flags:           crater.F_CHANGE_PAGE_EACH_CLICK | crater.F_LOG_EACH_MESSAGE,
		Messenger:       messenger.New(messenger.Styling{}),
		NotFoundHandler: NotFound,
	})

	// Open a websocket and handle the connection.
	crater.OpenSock("ws://127.0.0.1:8080/ws", &crater.SockOpts{
		OnOpen: func(w *websocket.WebSocket, event websocket.MessageEvent) {
			crater.LogInfo("Websocket opened")
			fmt.Println(event.Data().String())
			w.SendBytes([]byte("Hello World!"))
		},
		OnMessage: func(w *websocket.WebSocket, event websocket.MessageEvent) {
			crater.LogInfo("Received message")
			fmt.Println(event.Data().String())
		},
	})

	// Handle the root path.
	crater.Handle("/", crater.ToPageFunc(func(p *crater.Page) {
		p.Heading(1, "Hello World!")
	}))

	// Handle the hello path.
	crater.Handle("/hello/<<name>>", crater.ToPageFunc(func(p *crater.Page) {
		p.Heading(1, "Hello "+p.Variables.Get("name"))

		go func() {
			time.Sleep(time.Second * 5)
			crater.ErrorMessage(2*time.Second, "This", "is", "an", "error", "message", "number", i)
			crater.WarningMessage(2*time.Second, "This", "is", "a", "warning", "message", "number", i)
			crater.InfoMessage(2*time.Second, "This", "is", "an", "info", "message", "number", i)
			crater.SuccessMessage(2*time.Second, "This", "is", "a", "success", "message", "number", i, crater.OnClickFunc(func() {
				crater.HandlePath("/")
			}))
		}()
	}))

	// Easily handle a request to a server.
	crater.HandleEndpoint("/test", craterhttp.NewRequestFunc("GET", "https://jsonplaceholder.typicode.com/todos/1", nil), crater.ToPageFunc(func(p *crater.Page) {
		var respM = make(map[string]interface{})
		var err = p.DecodeResponse(decoder.JSONDecoder, &respM)
		if err != nil {
			console.Error(err.Error())
			return
		}
		crater.LogInfof("Received response: %s", respM)
		p.InnerHTML(fmt.Sprintf("%s", respM))
	}))

	// Run the application.
	err = crater.Run()
	if err != nil {
		console.Error(err.Error())
		return
	}
}


Documentation

Index

Constants

View Source
const (
	// SignalRun is sent when the application starts.
	SignalRun = "crater.Run"

	// SignalExit is sent when the application exits.
	//
	// The value sent is the error.
	SignalExit = "crater.Exit"

	// SignalPageChange is sent when a page is changed.
	SignalPageChange = "crater.PageChange"

	// SignalPageRendered is sent when a page is rendered.
	//
	// The value sent is the page.
	SignalPageRendered = "crater.PageRendered"

	// SignalSockConnected is sent when a websocket is connected.
	//
	// The value sent is the websocket.
	SignalSockConnected = "crater.SockConnected"

	// SignalClientResponse is sent when the client receives a response.
	//
	// The value sent is the client.
	SignalClientResponse = "crater.ClientResponse"

	// SignalHandlerAdded is sent when a handler is added.
	//
	// The value sent is the handler.
	SignalHandlerAdded = "crater.HandlerAdded"
)

If the value returned is unspecified, it is safe to assume the value to be nil.

Variables

This section is empty.

Functions

func After added in v1.6.2

func After(task tasker.Task) error

Execute a task after the duration has passed, or immediately if the duration is 0. If the task name is provided, the task will be reset to the new duration. If the task name is not provided, the task will be executed once after the duration has passed.

func Canvas

func Canvas() *jse.Element

Retrieve the application's root element.

func Client added in v1.8.2

func Client() *craterhttp.Client

Client returns the application's http client.

func Dequeue added in v1.6.2

func Dequeue(task string) error

Dequeue a task by name. If there is an error, it will be of types: - ErrNoNameSpecified - ErrNotFound

func Enqueue added in v1.6.2

func Enqueue(task tasker.Task) error

Enqueue a task periodically by name. If there is an error, it will be of type: - ErrNoNameSpecified

func ErrorMessage

func ErrorMessage(d time.Duration, s ...any)

An error message to be shown to the user.

This function will spin up a goroutine to log the message.

func Exit

func Exit(err error)

Exit the application with an error.

func GetGlobal added in v1.7.9

func GetGlobal[T any](key string) (ret T, ok bool)

Get global data for the application.

This function will look in the javascript global scope for the data if it is not found in the application's data.

This means it must supported by jsext.ToGo()

If T implements jsext.Unmarshaller, it will be used to unmarshal the javascript value.

func GlobalExists added in v1.8.4

func GlobalExists(name string) bool

Check if a global value or function exists.

func GlobalJS added in v1.8.3

func GlobalJS() js.Value

func GlobalJSName added in v1.7.7

func GlobalJSName(name string)

func HandleEndpoint

func HandleEndpoint(path string, r craterhttp.RequestFunc, h PageFunc)

Handle a path with a page function.

The page passed to this function will have acess to page.DecodeResponse and page.Response fields.

The page function will be called when the path is visited.

func HandlePath

func HandlePath(path string)

Change page to the given path.

func HideLoader

func HideLoader()

Hide the application's loader.

func InfoMessage

func InfoMessage(d time.Duration, s ...any)

An info message to be shown to the user.

This function will spin up a goroutine to log the message.

func LogDebug

func LogDebug(s ...any)

Log a debug message.

func LogDebugf

func LogDebugf(format string, v ...interface{})

Log a debug message in Sprintf format.

This function will spin up a goroutine to log the message.

func LogError

func LogError(s ...any)

Log an error.

func LogErrorf

func LogErrorf(format string, v ...interface{})

Log an error in Sprintf format.

This function will spin up a goroutine to log the message.

func LogInfo

func LogInfo(s ...any)

Log an info message.

func LogInfof

func LogInfof(format string, v ...interface{})

Log an info message in Sprintf format.

This function will spin up a goroutine to log the message.

func Mux

func Mux() *mux.Mux

Retrieve the application's path multiplexer.

func New

func New(c *Config)

Initialize a new application

The config parameter is optional, if nil, the default config will be used

func OpenSock

func OpenSock(url string, options *SockOpts)

Open a websocket for the application.

func Redirect added in v1.8.3

func Redirect(path string)

Redirect is a wrapper around HandlePath.

func RegisterHook added in v1.8.4

func RegisterHook(name string, hook func(any) error)

RegisterHook registers a hook with the application.

func Run

func Run() error

Run the application.

This function will block until the application exits.

func SendHook added in v1.8.4

func SendHook(name string, v any) error

Send a signal through the application's hook system.

func SetGlobal added in v1.7.9

func SetGlobal(key string, value interface{}, setGLobal bool)

Set global data for the application, and javascript global scope If specified, but this means it must supported by jsext.ValueOf()

func SetGlobalFunc added in v1.7.9

func SetGlobalFunc(name string, f func(args ...interface{}) Marshaller) (js.Func, error)

Add a global function to the application.

This function will be available to all pages, and in the global javascript scope.

Arguments (if any) are limited to the types supported by jsext.ToGo()

func SetLogLevel

func SetLogLevel(level logger.LogLevel)

Set the application's log level.

func SetTemplate

func SetTemplate(name string, f func(args ...interface{}) Marshaller)

SetTemplate sets the application's template.

func ShowLoader

func ShowLoader()

Show the application's loader.

func Socket added in v1.4.3

func Socket() *websocket.WebSocket

Socket returns the application's websocket.

func SuccessMessage

func SuccessMessage(d time.Duration, s ...any)

A success message to be shown to the user.

This function will spin up a goroutine to log the message.

func WarningMessage

func WarningMessage(d time.Duration, s ...any)

A warning message to be shown to the user.

This function will spin up a goroutine to log the message.

func WithEmbed

func WithEmbed(f func(pageCtx context.Context, page *jse.Element) *jse.Element)

WithEmbed sets the application's embed function.

This can be used to embed the page element, useful for navbars, footers etc.

func WithFlags

func WithFlags(flags CraterFlags)

WithFlags sets the application's flags.

func WithLoader

func WithLoader(l Loader)

WithLoader sets the application's loader.

func WithLogger

func WithLogger(l Logger)

WithLogger sets the application's logger.

func WithMessenger

func WithMessenger(m Messenger)

WithMessenger sets the application's messenger.

func WithNotFoundHandler

func WithNotFoundHandler(h PageFunc)

WithNotFoundHandler sets the application's not found handler.

func WithOnResponseError

func WithOnResponseError(f func(error))

WithOnResponseError sets the application's OnResponseError function.

func WithoutTemplate

func WithoutTemplate(name string)

WithoutTemplate removes a template from the application.

Types

type Config

type Config struct {
	// The function which will be called when a page is not found
	NotFoundHandler PageFunc `jsc:"-"`

	// The function which will be called when an error occurs in HandleEndpoint()
	OnResponseError func(error) `jsc:"-"`

	// The application's loader.
	Loader Loader `jsc:"-"`

	// The application's logger.
	Logger Logger `jsc:"-"`

	// The application's messenger.
	//
	// This will display messages to the user.
	Messenger Messenger `jsc:"-"`

	// The root element of the application.
	//
	// This will be passed to the Page struct, and will be used to render the page.
	RootElement jsext.Element `jsc:"-"`

	// Optional flags to change the behavior of the application.
	Flags CraterFlags `jsc:"-"`

	// The initial page URL.
	InitialPageURL string `jsc:"-"`

	// HttpClientTimeout is the timeout for the http client.
	HttpClientTimeout time.Duration `jsc:"-"`

	// Allows you to embed the canvas written to inside of another canvas.
	//
	// Useful for navbars, footers etc.
	//
	// The page should be embedded into the element returned by this function.
	EmbedFunc func(ctx context.Context, page *jse.Element) *jse.Element `jsc:"-"`

	// Templates which can be set, these can be used globally in the application.
	//
	// The arguments passed to the function are the arguments passed to the template.
	Templates map[string]func(args ...interface{}) Marshaller `jsc:"-"`
}

type CraterFlags

type CraterFlags uint32
const (
	// Change the page on each click of a link
	//
	// If not set, the page will only change when the URL changes.
	F_CHANGE_PAGE_EACH_CLICK CraterFlags = 1 << iota

	// Log each message sent with crater.InfoMessage(), crater.ErrorMessage() etc.
	F_LOG_EACH_MESSAGE

	// Close all websocket connections after switching pages
	//
	// If not set, websocket connections will be kept open
	// and must be closed manually, or they will be reused for the handler it was set on.
	F_CLOSE_SOCKS_EACH_PAGE

	// Append the canvas to the application's element instead of replacing it
	F_APPEND_CANVAS
)

func (CraterFlags) Has

func (f CraterFlags) Has(flag CraterFlags) bool

Check if the flag is set

type Decoder

type Decoder decoder.Decoder

The decoder interface for decoding responses with Response.DecodeResponse

type FullPage added in v1.4.7

type FullPage interface {
	PageFunc
	Preloader
	Initter
	Templater
	SockConfigurator
}

type Initter added in v1.4.3

type Initter interface {
	Init()
}

type Loader

type Loader interface {
	Show()
	Hide()
}

A loader which will display when a page is loading

type Logger

type Logger logger.Logger

A logger which will be used to log messages

type Marshaller added in v1.4.1

type Marshaller interface {
	MarshalJS() js.Value
}

func ExecGlobalFunc added in v1.7.7

func ExecGlobalFunc(name string, args ...interface{}) Marshaller

Call a global function.

This function will panic if the function does not exist.

Arguments (if any) are limited to the types supported by jsext.ValueOf() if it is bound to js.Global alone, otherwise it is limited to the types supported by jsext.ToGo()

func WithTemplate

func WithTemplate(name string, args ...interface{}) Marshaller

WithTemplate adds a template to the application.

This function will panic if the template does not exist.

The arguments passed to this function will be passed to the template function.

type Messenger

type Messenger messenger.Messenger

A messenger which will display messages to the user

type NullMarshaller added in v1.7.3

type NullMarshaller struct{}

func (NullMarshaller) MarshalJS added in v1.7.3

func (NullMarshaller) MarshalJS() js.Value

type OnClickFunc

type OnClickFunc messenger.OnClickFunc

func (OnClickFunc) OnClick

func (f OnClickFunc) OnClick()

type Page

type Page struct {
	// The root element of the page
	//
	// This is the element which will act as a canvas for the page
	Canvas *jse.Element `jsc:"root"`

	// The response received from the server
	*craterhttp.Response `jsc:"-"`

	// The variables received from the server
	Variables mux.Variables `jsc:"variables"`

	// The context of the page
	//
	// This will be reset for each page render.
	Context context.Context `jsc:"-"`

	// A function which can be arbitrarily set, and will be called after the page is rendered.
	AfterRender func(p *Page) `jsc:"-"`

	// State is an object where we can more easily keep track of and store state.
	//
	// This is useful for keeping track of things like whether or not a page is loading.
	State *state.State `jsc:"-"`

	// Sock is a websocket connection to the server for the current page.
	Sock *websocket.WebSocket `jsc:"-"`
}

Page represents a page in the application.

func (*Page) AppendChild added in v1.4.3

func (p *Page) AppendChild(e ...*jse.Element)

func (*Page) Clear

func (p *Page) Clear()

func (*Page) Walk added in v1.3.8

func (p *Page) Walk(nodetypes []dom.NodeType, fn func(e dom.Node))

type PageFunc

type PageFunc interface {
	Serve(p *Page)
}

func ToPageFunc added in v1.4.1

func ToPageFunc(f func(p *Page)) PageFunc

Create a new page function from a which will be called when the page is rendered.

type Preloader added in v1.4.1

type Preloader interface {
	Preload(p *Page)
}

type Route

type Route interface {
	Handle(path string, h PageFunc) Route
}

func Handle

func Handle(path string, h PageFunc) Route

Handle a path with a page function.

The page function will be called when the path is visited.

This function returns a route that can be used to add children.

type SockConfigurator added in v1.4.3

type SockConfigurator interface {
	SockOptions() (url string, opts SockOpts)
}

type SockOpts

type SockOpts struct {
	Protocols []string
	OnOpen    func(*websocket.WebSocket, websocket.MessageEvent)
	OnMessage func(*websocket.WebSocket, websocket.MessageEvent)
	OnClose   func(*websocket.WebSocket, jsext.Event)
	OnError   func(*websocket.WebSocket, jsext.Event)
}

func (*SockOpts) Apply added in v1.4.3

func (o *SockOpts) Apply(sock *websocket.WebSocket)

func (*SockOpts) OpenSock added in v1.4.3

func (o *SockOpts) OpenSock(url string) *websocket.WebSocket

type Templater added in v1.4.3

type Templater interface {
	Templates() map[string]func(args ...interface{}) Marshaller
}

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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