ucl/cmd/playwasm/jsiter.go
Leon Mika e7f904e7da
All checks were successful
Build / build (push) Successful in 2m32s
Added some changes to call and added builtins
- call now supports calling invokables by string
- call now takes as arguments a listable of positional args, and a hashable of keyword args
- added strs:split, strs:join, and strs:has-prefix
- added new lists module with lists:first
- added time:sleep
2025-05-17 13:59:44 +10:00

62 lines
1.3 KiB
Go

//go:build js && wasm
package main
import (
"context"
"errors"
"github.com/alecthomas/participle/v2"
"strings"
"syscall/js"
"ucl.lmika.dev/repl"
"ucl.lmika.dev/ucl"
"ucl.lmika.dev/ucl/builtins"
)
func invokeUCLCallback(name string, args ...any) {
if onLine := js.Global().Get("ucl").Get(name); !onLine.IsNull() {
onLine.Invoke(args...)
}
}
func initJS(ctx context.Context) {
uclObj := make(map[string]any)
replInst := repl.New(
ucl.WithModule(builtins.Log(nil)),
ucl.WithModule(builtins.Strs()),
ucl.WithModule(builtins.Time()),
ucl.WithModule(builtins.Itrs()),
ucl.WithModule(builtins.Lists()),
ucl.WithOut(ucl.LineHandler(func(line string) {
invokeUCLCallback("onOutLine", line)
})),
)
uclObj["eval"] = js.FuncOf(func(this js.Value, args []js.Value) any {
if len(args) != 2 {
return nil
}
cmdLine := args[0].String()
if strings.TrimSpace(cmdLine) == "" {
invokeUCLCallback("onNewCommand")
return nil
}
wantContinue := args[1].Bool()
if err := replInst.EvalAndDisplay(ctx, cmdLine); err != nil {
var p participle.Error
if errors.As(err, &p) && wantContinue {
invokeUCLCallback("onContinue")
return nil
}
invokeUCLCallback("onError", err.Error())
}
invokeUCLCallback("onNewCommand")
return nil
})
js.Global().Set("ucl", uclObj)
}