Skip to content

Commit deecf7e

Browse files
committed
Added browser / Bun / Deno example.
Added devcontainer.
1 parent 8a7d33a commit deecf7e

File tree

8 files changed

+201
-2
lines changed

8 files changed

+201
-2
lines changed

.devcontainer/devcontainer.json

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"name": "Yaegi: HTTP request from WASM",
3+
"image": "ubuntu:jammy",
4+
"features": {
5+
"ghcr.io/devcontainers/features/go:1": {},
6+
"ghcr.io/devcontainers/features/common-utils": {}
7+
}
8+
}

README.md

+13-2
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,13 @@
1-
# yaegi
2-
Make HTTP requests from inside WASM in Yaegi. Demo and devcontainer.
1+
# Make HTTP requests from inside WASM in Yaegi (Golang scripting)
2+
3+
This devcontainer is configured to provide you a latest stable version of Go toolset.
4+
5+
[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/wasm-outbound-http-examples/yaegi)
6+
7+
1. [Browser demo](https://wasm-outbound-http-examples.github.io/yaegi/).
8+
9+
2. Example in `browser-and-deno` directory allows you to build yourself a browser example (same as demo),
10+
along with Deno and Bun examples and experiment with it.
11+
For details, see its [README](browser-and-deno/README.md).
12+
13+
<sub>Created for (wannabe-awesome) [list](https://github.com/vasilev/HTTP-request-from-inside-WASM)</sub>

browser-and-deno/README.md

+85
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
# Use Yaegi to send HTTP(s) requests from inside WASM
2+
3+
## Instructions for this devcontainer
4+
5+
Tested with Go 1.21.6, Bun 1.0.22, Deno 1.39.2, Yaegi 0.15.1 .
6+
7+
### Preparation
8+
9+
1. Open this repo in devcontainer, e.g. using Github Codespaces.
10+
Type or copy/paste following commands to devcontainer's terminal.
11+
12+
### Building
13+
14+
1. `cd` into the folder of this example:
15+
16+
```sh
17+
cd browser-and-deno
18+
```
19+
20+
2. Install Yaegi as library:
21+
```sh
22+
go get github.com/traefik/yaegi
23+
```
24+
25+
3. Compile the example:
26+
27+
```sh
28+
GOOS=js GOARCH=wasm go build -o main.wasm main.go
29+
```
30+
31+
4. Copy the glue JS from Golang distribution to example's folder:
32+
33+
```sh
34+
cp "$(go env GOROOT)/misc/wasm/wasm_exec.js" .
35+
```
36+
37+
### Test with browser
38+
39+
1. Run simple HTTP server to temporarily publish project to Web:
40+
41+
```sh
42+
python3 -m http.server
43+
```
44+
45+
Codespace will show you "Open in Browser" button. Just click that button or
46+
obtain web address from "Forwarded Ports" tab.
47+
48+
2. As `index.html` and a **36M**-sized `main.wasm` are loaded into browser, refer to browser developer console
49+
to see the results.
50+
51+
### Test with Node.js
52+
53+
Impossible yet due to https://github.com/golang/go/issues/59605.
54+
55+
### Test with Bun
56+
57+
1. Install Bun:
58+
59+
```sh
60+
curl -fsSL https://bun.sh/install | bash
61+
```
62+
63+
2. Run with Bun:
64+
65+
```sh
66+
~/.bun/bin/bun bun.js
67+
```
68+
69+
### Test with Deno
70+
71+
1. Install Deno:
72+
73+
```sh
74+
curl -fsSL https://deno.land/x/install/install.sh | sh
75+
```
76+
77+
2. Run with Deno:
78+
79+
```sh
80+
~/.deno/bin/deno run --allow-read --allow-net deno.js
81+
```
82+
83+
### Finish
84+
85+
Perform your own experiments if desired.

browser-and-deno/bun.js

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
const fs = require('fs');
2+
require('./wasm_exec.js');
3+
4+
const buf = fs.readFileSync('main.wasm');
5+
const go = new Go();
6+
7+
(async function() {
8+
const inst = await WebAssembly.instantiate(buf, go.importObject);
9+
go.run(inst.instance);
10+
})()

browser-and-deno/deno.js

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import * as _ from './wasm_exec.js';
2+
const go = new window.Go();
3+
const f = await Deno.open('main.wasm');
4+
const buf = await Deno.readAll(f);
5+
const inst = await WebAssembly.instantiate(buf, go.importObject);
6+
go.run(inst.instance);

browser-and-deno/go.mod

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module main
2+
3+
go 1.21.6

browser-and-deno/index.html

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<title>HTTP request for Yaegi</title>
6+
<script type="text/javascript" src="wasm_exec.js"></script>
7+
</head>
8+
<body>
9+
<h2>HTTP Request from inside WASM using Yaegi</h2>
10+
11+
<p>This example uses <a href="https://github.com/traefik/yaegi">Yaegi</a>.</p>
12+
<p>See the output in browser developer console.</p>
13+
14+
<p>Actual code:</p>
15+
<pre>
16+
17+
package main
18+
19+
import (
20+
"fmt"; "io"; "net/http"
21+
)
22+
23+
func main() {
24+
resp, err := http.Get("https://httpbin.org/anything")
25+
if err != nil {
26+
panic(err)
27+
}
28+
defer resp.Body.Close()
29+
body, _ := io.ReadAll(resp.Body)
30+
fmt.Println(string(body))
31+
}
32+
33+
</pre>
34+
<script type="text/javascript">
35+
const go = new Go();
36+
WebAssembly.instantiateStreaming(fetch('main.wasm'), go.importObject).then((result) => {
37+
go.run(result.instance);
38+
});
39+
</script>
40+
<footer><small>Created for (wannabe-awesome) <a href="https://github.com/vasilev/HTTP-request-from-inside-WASM">list</a></small></footer>
41+
</body>
42+
</html>

browser-and-deno/main.go

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package main
2+
3+
import (
4+
"github.com/traefik/yaegi/interp"
5+
"github.com/traefik/yaegi/stdlib"
6+
)
7+
8+
func main() {
9+
interpreter := interp.New(interp.Options{})
10+
11+
interpreter.Use(stdlib.Symbols)
12+
13+
src := `
14+
package main
15+
16+
import (
17+
"fmt"; "io"; "net/http"
18+
)
19+
20+
func main() {
21+
resp, err := http.Get("https://httpbin.org/anything")
22+
if err != nil {
23+
panic(err)
24+
}
25+
defer resp.Body.Close()
26+
body, _ := io.ReadAll(resp.Body)
27+
fmt.Println(string(body))
28+
}
29+
`
30+
_, err := interpreter.Eval(src)
31+
if err != nil {
32+
panic(err)
33+
}
34+
}

0 commit comments

Comments
 (0)