github.com/tetratelabs/wazero@v1.2.1/experimental/gojs/example/stars.go (about) 1 package main 2 3 import ( 4 "context" 5 "io" 6 "log" 7 "net/http" 8 "os" 9 "path" 10 "strings" 11 "time" 12 13 "github.com/tetratelabs/wazero" 14 "github.com/tetratelabs/wazero/experimental/gojs" 15 "github.com/tetratelabs/wazero/sys" 16 ) 17 18 // main invokes Wasm compiled via `GOARCH=wasm GOOS=js`, which reports the star 19 // count of wazero. 20 // 21 // This shows how to integrate an HTTP client with wasm using gojs. 22 func main() { 23 ctx := context.Background() 24 25 // Create a new WebAssembly Runtime. 26 r := wazero.NewRuntime(ctx) 27 defer r.Close(ctx) // This closes everything this Runtime created. 28 29 // Add the host functions used by `GOARCH=wasm GOOS=js` 30 start := time.Now() 31 gojs.MustInstantiate(ctx, r) 32 33 goJsInstantiate := time.Since(start).Milliseconds() 34 log.Printf("gojs.MustInstantiate took %dms", goJsInstantiate) 35 36 // Combine the above into our baseline config, overriding defaults. 37 moduleConfig := wazero.NewModuleConfig(). 38 // By default, I/O streams are discarded, so you won't see output. 39 WithStdout(os.Stdout).WithStderr(os.Stderr) 40 41 bin, err := os.ReadFile(path.Join("stars", "main.wasm")) 42 if err != nil { 43 log.Panicln(err) 44 } 45 46 // Compile the WebAssembly module using the default configuration. 47 start = time.Now() 48 compiled, err := r.CompileModule(ctx, bin) 49 if err != nil { 50 log.Panicln(err) 51 } 52 compilationTime := time.Since(start).Milliseconds() 53 log.Printf("CompileModule took %dms", compilationTime) 54 55 // Instead of making real HTTP calls, return fake data. 56 config := gojs.NewConfig(moduleConfig).WithRoundTripper(&fakeGitHub{}) 57 58 // Execute the "run" function, which corresponds to "main" in stars/main.go. 59 start = time.Now() 60 err = gojs.Run(ctx, r, compiled, config) 61 runTime := time.Since(start).Milliseconds() 62 log.Printf("gojs.Run took %dms", runTime) 63 if exitErr, ok := err.(*sys.ExitError); ok && exitErr.ExitCode() != 0 { 64 log.Panicln(err) 65 } else if !ok { 66 log.Panicln(err) 67 } 68 } 69 70 // compile-time check to ensure fakeGitHub implements http.RoundTripper 71 var _ http.RoundTripper = &fakeGitHub{} 72 73 type fakeGitHub struct{} 74 75 func (f *fakeGitHub) RoundTrip(*http.Request) (*http.Response, error) { 76 fakeResponse := `{"stargazers_count": 9999999}` 77 return &http.Response{ 78 StatusCode: http.StatusOK, 79 Status: http.StatusText(http.StatusOK), 80 Body: io.NopCloser(strings.NewReader(fakeResponse)), 81 ContentLength: int64(len(fakeResponse)), 82 }, nil 83 }