1// ===== main.go =====
2//go:build js && wasm
3
4// Package main wasm/tui/main.go — the store TUI in the browser, filling the
5// tab. The storefront itself is pkg/storepane: a websh session (bash-like
6// shell, in-memory filesystem, the browser applets) with the store started
7// in it by the `magnetosphere` command. Quitting the store — q or Ctrl+C —
8// drops you at the shell prompt, and the command starts it again.
9//
10// The same pane is what /desk opens in a window, so the two are one
11// storefront rather than two that have to be kept in step.
12//
13// Served by the /tui page; compiled at server startup as a WASMSRC drop-in
14// ('wasm/tui').
15package main
16
17import (
18 "log"
19 "syscall/js"
20
21 "github.com/0magnet/m2/pkg/storepane"
22)
23
24// wasmName is stamped by the server's wasm build (-X main.wasmName=…) so log
25// lines identify which binary they came from.
26var wasmName string
27
28func main() {
29 storepane.SetLogName(wasmName)
30
31 ready := make(chan struct{})
32 document := js.Global().Get("document")
33 readyState := document.Get("readyState").String()
34 if readyState == "interactive" || readyState == "complete" {
35 close(ready)
36 } else {
37 cb := js.FuncOf(func(js.Value, []js.Value) interface{} {
38 close(ready)
39 return nil
40 })
41 defer cb.Release()
42 document.Call("addEventListener", "DOMContentLoaded", cb)
43 }
44 <-ready
45
46 storepane.WaitForFont(document)
47
48 el := document.Call("getElementById", "terminal")
49 if !el.Truthy() {
50 log.Println(wasmName+":", "no #terminal element; exiting")
51 return
52 }
53 if err := storepane.New().Pane().Mount(el); err != nil {
54 log.Println(wasmName+":", "shell:", err)
55 return
56 }
57 select {}
58}
59
60