mirror of
https://github.com/tale/headplane.git
synced 2026-08-31 17:28:14 +00:00
chore: reorganize go code
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
//go:build js && wasm
|
||||
|
||||
package hp_ipn
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"syscall/js"
|
||||
|
||||
"tailscale.com/ipn"
|
||||
"tailscale.com/types/netmap"
|
||||
)
|
||||
|
||||
// Maps ipn.State values to their string representations for the frontend.
|
||||
var BackendState = map[ipn.State]string{
|
||||
ipn.NoState: "NoState",
|
||||
ipn.Stopped: "Stopped",
|
||||
ipn.Starting: "Starting",
|
||||
ipn.Running: "Running",
|
||||
ipn.InUseOtherUser: "InUseOtherUser",
|
||||
ipn.NeedsMachineAuth: "NeedsMachineAuth",
|
||||
ipn.NeedsLogin: "NeedsLogin",
|
||||
}
|
||||
|
||||
// Represents the callbacks that the TsWasmNet module can invoke to register
|
||||
// data retrieval and notifications on the frontend.
|
||||
type TsWasmNetCallbacks struct {
|
||||
// Changes in the backend state.
|
||||
NotifyState func(ipn.State)
|
||||
|
||||
// Updates to the backend's network map.
|
||||
NotifyNetMap func(*netmap.NetworkMap)
|
||||
|
||||
// If interactive login is required, this passes a login URL.
|
||||
NotifyBrowseToURL func(string)
|
||||
|
||||
// If the process panics, this function is called in go.recover.
|
||||
NotifyPanicRecover func(string)
|
||||
}
|
||||
|
||||
// Parses a JavaScript object containing the necessary callbacks for the
|
||||
// TsWasmNet module to properly interact with the frontend.
|
||||
func ParseTsWasmNetCallbacks(obj js.Value) (*TsWasmNetCallbacks, error) {
|
||||
if obj.IsUndefined() || obj.IsNull() {
|
||||
return nil, errors.New("callbacks object is undefined or null")
|
||||
}
|
||||
|
||||
state, err := validateCallback("NotifyState", obj)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid callback NotifyState: %w", err)
|
||||
}
|
||||
|
||||
// TODO: This is complicated, as the NetworkMap is a complex type.
|
||||
_, err = validateCallback("NotifyNetMap", obj)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid callback NotifyNetMap: %w", err)
|
||||
}
|
||||
|
||||
browseURL, err := validateCallback("NotifyBrowseToURL", obj)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid callback NotifyBrowseToURL: %w", err)
|
||||
}
|
||||
|
||||
panicRecover, err := validateCallback("NotifyPanicRecover", obj)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid callback NotifyPanicRecover: %w", err)
|
||||
}
|
||||
|
||||
return &TsWasmNetCallbacks{
|
||||
NotifyState: func(ipnState ipn.State) {
|
||||
state.Invoke(BackendState[ipnState])
|
||||
},
|
||||
|
||||
NotifyNetMap: func(nm *netmap.NetworkMap) {
|
||||
// TODO: This is complicated
|
||||
},
|
||||
|
||||
NotifyBrowseToURL: func(url string) {
|
||||
browseURL.Invoke(url)
|
||||
},
|
||||
|
||||
NotifyPanicRecover: func(msg string) {
|
||||
panicRecover.Invoke(msg)
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Validates the specified key is a JS function and returns it.
|
||||
func validateCallback(key string, obj js.Value) (*js.Value, error) {
|
||||
val := obj.Get(key)
|
||||
if val.IsUndefined() || val.IsNull() {
|
||||
return nil, errors.New("callback is undefined or null")
|
||||
}
|
||||
|
||||
if val.Type() != js.TypeFunction {
|
||||
return nil, errors.New("callback is not a function")
|
||||
}
|
||||
|
||||
return &val, nil
|
||||
}
|
||||
Reference in New Issue
Block a user