refactor(webclient): rename proxy handler to __go_jshttp and simplify service worker

- Renamed the JavaScript-exposed HTTP handler from _portal_proxy to __go_jshttp for better alignment with Go's WASM conventions. - Replaced println with structured logging using log.Info().Msg for improved logging consistency. - Simplified the runtime check to only target TinyGo compiler. - Refactored service-worker.js to streamline caching, event handling, and WASM instantiation, removing redundant code and improving efficiency.

lemon-mint committed Oct 31, 2025 at 13:05 UTC 4e9fb7a3f30794d5349e4e13e602ff7c41fca656
2 files changed +52 -82
cmd/webclient/main_js.go
+4 -4
@@ -86,8 +86,8 @@ func main() {
86 }
87 defer rdClient.Close()
88
89 - // Expose HTTP handler to JavaScript as _portal_proxy
90 - js.Global().Set("_portal_proxy", js.FuncOf(func(this js.Value, args []js.Value) interface{} {
89 + // Expose HTTP handler to JavaScript as __go_jshttp
90 + js.Global().Set("__go_jshttp", js.FuncOf(func(this js.Value, args []js.Value) interface{} {
91 if len(args) < 1 {
92 return js.Global().Get("Promise").Call("reject",
93 js.Global().Get("Error").New("required parameter JSRequest missing"))
@@ -97,9 +97,9 @@ func main() {
97 return httpjs.ServeHTTPAsyncWithStreaming(&Proxy{}, jsReq)
98 }))
99
100 - println("Portal proxy handler registered as _portal_proxy")
100 + log.Info().Msg("Portal proxy handler registered as __go_jshttp")
101
102 - if runtime.Compiler == "tinygo" || runtime.GOARCH != "wasm" {
102 + if runtime.Compiler == "tinygo" {
103 return
104 }
105 // Wait
cmd/webclient/service-worker.js
+48 -78
@@ -1,89 +1,59 @@
1 // const wasm_exec_URL = "https://cdn.jsdelivr.net/gh/golang/go@go1.25.3/misc/wasm/wasm_exec.js";
2 const wasm_exec_URL = "/wasm_exec.js";
3 -importScripts(wasm_exec_URL);
4 -
5 -let _portal_proxy;
3 const wasm_URL = "/main.wasm";
7 -const CACHE_NAME = "WASM_Cache_v1";
4 +importScripts(wasm_exec_URL);
5
6 async function runWASM() {
10 - const go = new Go();
11 - const cache = await caches.open(CACHE_NAME);
12 - let wasm_file;
13 -
14 - const cache_wasm = await cache.match(wasm_URL);
15 -
16 - if (cache_wasm) {
17 - console.log("Service Worker: Loading WASM from cache...");
18 - wasm_file = await cache_wasm.arrayBuffer();
19 - } else {
20 - console.warn("Service Worker: WASM not in cache. Fetching from network...");
21 - const resp = await fetch(wasm_URL);
22 - wasm_file = await resp.arrayBuffer();
23 - await cache.put(wasm_URL, new Response(wasm_file.slice(0)));
24 - }
25 -
26 - console.log("Service Worker: Instantiating WebAssembly...");
27 - const { instance } = await WebAssembly.instantiate(wasm_file, go.importObject);
28 -
29 - // go.run() executes Go's main() and returns
30 - // when _portal_proxy callback is registered
31 - go.run(instance);
32 - console.log("Service Worker: Go WASM execution complete. _portal_proxy is ready.");
7 + const go = new Go();
8 + const cache = await caches.open("WASM_Cache_v1");
9 + let wasm_file;
10 + const cache_wasm = await cache.match(wasm_URL);
11 + if (cache_wasm) {
12 + wasm_file = await cache_wasm.arrayBuffer();
13 + } else {
14 + wasm_file = await (await fetch(wasm_URL)).arrayBuffer();
15 + }
16 + const instance = await WebAssembly.instantiate(wasm_file, go.importObject);
17 + go.run(instance.instance);
18 }
19
35 -self.addEventListener('install', (event) => {
36 - console.log('Service Worker: Installing...');
37 -
38 - event.waitUntil(
39 - (async () => {
40 - const cache = await caches.open(CACHE_NAME);
41 - console.log('Service Worker: Caching essential assets...');
42 - await cache.addAll([
43 - wasm_URL,
44 - wasm_exec_URL,
45 - ]);
46 - await self.skipWaiting();
47 - })()
48 - );
20 +self.addEventListener('install', (e) => {
21 + self.skipWaiting();
22 + async function LoadCache() {
23 + const cache = await caches.open("WASM_Cache_v1");
24 + await cache.addAll([
25 + wasm_URL,
26 + wasm_exec_URL,
27 + ]);
28 + }
29 + e.waitUntil(LoadCache());
30 });
31
51 -// --- 2. Activate event listener ---
52 -self.addEventListener('activate', (event) => {
53 - console.log('Service Worker: Activated.');
54 -
55 - event.waitUntil(
56 - (async () => {
57 - await self.clients.claim();
58 - // Preload WASM to prepare for next fetch requests
59 - console.log('Service Worker: Starting Go WASM preloading...');
60 - await runWASM();
61 - console.log('Service Worker: Go WASM preloading complete.');
62 - })()
63 - );
64 -});
65 -
66 -runWASM();
67 -
68 -async function proxy_handler(event) {
69 - console.log('Service Worker: Fetch event:', event.request);
70 - if (typeof _portal_proxy != 'undefined') {
71 - event.respondWith((async () => {
72 - try {
73 - const resp = await _portal_proxy(event.request);
74 - return resp;
75 - } catch {
76 - _portal_proxy = undefined;
32 +self.addEventListener('activate', (e) => {
33 + async function Activate() {
34 await runWASM();
78 - const resp = await _portal_proxy(event.request);
79 - return resp;
80 - }
81 - })());
82 - return;
83 - }
84 -
85 - console.log('Service Worker: _portal_proxy is not defined. Fetch event ignored.');
86 - event.respondWith(new Response('Service Worker: Failed to process request, please refresh the page.', { status: 500 }));
87 -}
35 + }
36 + e.waitUntil(Activate());
37 +});
38
89 -self.addEventListener('fetch', proxy_handler);
39 +self.addEventListener('fetch', (e) => {
40 + console.log(e.request);
41 + if (typeof __go_jshttp != 'undefined') {
42 + e.respondWith((async () => {
43 + try {
44 + const resp = await __go_jshttp(e.request);
45 + return resp;
46 + } catch {
47 + __go_jshttp = undefined;
48 + runWASM();
49 + const resp = await __go_jshttp(e.request);
50 + return resp;
51 + }
52 + })());
53 + return;
54 + }
55 +
56 + console.log("__go_jshttp not found");
57 + runWASM();
58 + e.respondWith(fetch(e.request));
59 +});
\ No newline at end of file