forked from lmorg/murex
-
Notifications
You must be signed in to change notification settings - Fork 0
/
main_js.go
131 lines (104 loc) · 3.41 KB
/
main_js.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
// +build js
package main
import (
"syscall/js"
"github.com/lmorg/murex/app"
_ "github.com/lmorg/murex/builtins"
"github.com/lmorg/murex/builtins/pipes/term"
"github.com/lmorg/murex/config/defaults"
"github.com/lmorg/murex/lang"
"github.com/lmorg/murex/lang/ref"
"github.com/lmorg/murex/shell"
"github.com/lmorg/murex/utils/ansi"
"github.com/lmorg/murex/utils/readline"
)
const interactive = true
func main() {
startMurex()
js.Global().Set("wasmShellExec", wasmShellExec())
js.Global().Set("wasmShellStart", wasmShellStart())
js.Global().Set("wasmKeyPress", wasmKeyPress())
wait := make(chan bool)
<-wait
}
func startMurex() {
lang.InitEnv()
// default config
defaults.Defaults(lang.ShellProcess.Config, interactive)
// compiled profile
source := defaults.DefaultMurexProfile()
ref := ref.History.AddSource("(builtin)", "source/builtin", []byte(string(source)))
execSource(defaults.DefaultMurexProfile(), ref)
// load modules and profile
//profile.Execute()
// start interactive shell
//shell.Start()
}
// wasmShellExec returns a Promise
func wasmShellExec() js.Func {
return js.FuncOf(func(this js.Value, args []js.Value) interface{} {
block := args[0].String()
// Handler for the Promise: this is a JS function
// It receives two arguments, which are JS functions themselves: resolve and reject
handler := js.FuncOf(func(this js.Value, args []js.Value) interface{} {
resolve := args[0]
reject := args[1]
// Now that we have a way to return the response to JS, spawn a goroutine
// This way, we don't block the event loop and avoid a deadlock
go func() {
fork := lang.ShellProcess.Fork(lang.F_PARENT_VARTABLE | lang.F_NEW_MODULE | lang.F_NO_STDIN)
fork.FileRef.Source.Module = app.Name
fork.Stderr = term.NewErr(ansi.IsAllowed())
var err error
lang.ShellExitNum, err = fork.Execute([]rune(block))
if err != nil {
errorConstructor := js.Global().Get("Error")
errorObject := errorConstructor.New(err.Error())
reject.Invoke(errorObject)
}
resolve.Invoke("wasmShellExec(): " + block)
}()
// The handler of a Promise doesn't return any value
return nil
})
// Create and return the Promise object
promiseConstructor := js.Global().Get("Promise")
return promiseConstructor.New(handler)
})
}
// wasmShellStart starts the interactive shell as a Promise
func wasmShellStart() js.Func {
return js.FuncOf(func(this js.Value, args []js.Value) interface{} {
handler := js.FuncOf(func(this js.Value, args []js.Value) interface{} {
resolve := args[0]
//reject := args[1]
go func() {
resolve.Invoke("Starting interactive shell....")
shell.Start()
}()
// The handler of a Promise doesn't return any value
return nil
})
// Create and return the Promise object
promiseConstructor := js.Global().Get("Promise")
return promiseConstructor.New(handler)
})
}
// wasmKeyPress starts the interactive shell as a Promise
func wasmKeyPress() js.Func {
return js.FuncOf(func(this js.Value, args []js.Value) interface{} {
stdin := args[0].String()
handler := js.FuncOf(func(this js.Value, args []js.Value) interface{} {
//resolve := args[0]
//reject := args[1]
go func() {
readline.Stdin <- stdin
}()
// The handler of a Promise doesn't return any value
return nil
})
// Create and return the Promise object
promiseConstructor := js.Global().Get("Promise")
return promiseConstructor.New(handler)
})
}