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  }