18 Commits

Author SHA1 Message Date
Nicolas Lepage
ac1cfbfe8a chore: v2.2.1 2025-02-07 11:48:06 +01:00
Nicolas Lepage
f0a7bf8f2b docs: updates EliCDavis’ contribution 2025-02-07 11:46:33 +01:00
Nicolas Lepage
d7055fb5ea [BUGFIX] Writes default header when response close and no header already written 2025-02-07 11:45:18 +01:00
Nicolas Lepage
b9921d7d43 fix: writes default header when response closed and no header written 2025-02-07 11:42:55 +01:00
Nicolas Lepage
2f3e39bf97 chore: v2.2.0 2025-02-06 11:21:25 +01:00
Nicolas Lepage
065e91545b docs: adds FAQ mentionning websockets and tinygo 2025-02-06 11:17:08 +01:00
Nicolas Lepage
9be33ecb4d docs: updates examples doc and adds an index for examples 2025-02-06 10:15:25 +01:00
Nicolas Lepage
6ddad6298b docs: adds EliCDavis as a contributor 2025-02-06 10:08:56 +01:00
Nicolas Lepage
1f38d08145 feat: Provide ability to passthrough and hit network 2025-02-06 09:58:37 +01:00
Nicolas Lepage
5dc06a3dbb docs: updates documentation for registerWasmHTTPListener 2025-02-06 09:55:58 +01:00
Nicolas Lepage
38c1814f66 refactor: change signature for passthrough function 2025-02-06 09:55:56 +01:00
Eli Davis
268c971467 Provide ability to passthrough and hit network 2025-02-05 17:48:27 -08:00
Nicolas Lepage
57a311369e doc: credit contributors 2025-01-19 11:29:03 +01:00
Nicolas Lepage
5f2b342f3a chore: v2.1.0 2025-01-19 11:16:06 +01:00
Nicolas Lepage
8e787fbf29 Merge pull request #17 from jphastings/compile-with-tinygo
TinyGo compatible packages
2025-01-19 11:03:24 +01:00
JP Hastings-Spital
ce6765e72a feat: Demonstrates TinyGo compatibility
Adds an example that demonstrates TinyGo compatibility, as well as using a server-side HTTP handler as a fallback.
2025-01-19 11:01:15 +01:00
Nico
d12a255cff implements io.Closer for readablestream.Reader 2024-12-30 00:51:31 +01:00
JP Hastings-Spital
a16a847b26 fix: TinyGo compatible packages
The net/http/httptest package isn't implemented in tinygo — this (minor) change swaps to creating the necessary http.Request struct directly (which needs an extra step or two).

This *is not* enough to get TinyGo _working_ as a compiler for this repo, but the compilation succeeds now.
2024-12-14 10:12:55 +00:00
21 changed files with 1119 additions and 27 deletions

37
.all-contributorsrc Normal file
View File

@@ -0,0 +1,37 @@
{
"projectName": "go-wasm-http-server",
"projectOwner": "nlepage",
"repoType": "github",
"repoHost": "https://github.com",
"files": [
"README.md"
],
"imageSize": 100,
"commit": false,
"commitConvention": "gitmoji",
"contributors": [
{
"login": "jphastings",
"name": "JP Hastings-Edrei",
"avatar_url": "https://avatars.githubusercontent.com/u/42999?v=4",
"profile": "https://byjp.me/",
"contributions": [
"code",
"doc",
"example"
]
},
{
"login": "EliCDavis",
"name": "Eli Davis",
"avatar_url": "https://avatars.githubusercontent.com/u/9094977?v=4",
"profile": "https://recolude.com/",
"contributions": [
"code",
"bug"
]
}
],
"contributorsPerLine": 7,
"linkToUsage": false
}

View File

@@ -186,7 +186,7 @@
same "printed page" as the copyright notice for easier same "printed page" as the copyright notice for easier
identification within third-party archives. identification within third-party archives.
Copyright 2021 Nicolas Lepage Copyright 2025 Nicolas Lepage
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.

View File

@@ -6,9 +6,6 @@
<a href="https://github.com/nlepage/go-wasm-http-server/blob/master/LICENSE" target="_blank"> <a href="https://github.com/nlepage/go-wasm-http-server/blob/master/LICENSE" target="_blank">
<img alt="License: Apache 2.0" src="https://img.shields.io/badge/License-Apache--2.0-yellow.svg" /> <img alt="License: Apache 2.0" src="https://img.shields.io/badge/License-Apache--2.0-yellow.svg" />
</a> </a>
<a href="https://twitter.com/njblepage" target="_blank">
<img alt="Twitter: njblepage" src="https://img.shields.io/twitter/follow/njblepage.svg?style=social" />
</a>
</p> </p>
> Embed your Go HTTP handlers in a ServiceWorker (using [WebAssembly](https://mdn.io/WebAssembly/)) and emulate an HTTP server! > Embed your Go HTTP handlers in a ServiceWorker (using [WebAssembly](https://mdn.io/WebAssembly/)) and emulate an HTTP server!
@@ -18,9 +15,10 @@
- [Hello example](https://nlepage.github.io/go-wasm-http-server/hello) ([sources](https://github.com/nlepage/go-wasm-http-server/tree/master/docs/hello)) - [Hello example](https://nlepage.github.io/go-wasm-http-server/hello) ([sources](https://github.com/nlepage/go-wasm-http-server/tree/master/docs/hello))
- [Hello example with state](https://nlepage.github.io/go-wasm-http-server/hello-state) ([sources](https://github.com/nlepage/go-wasm-http-server/tree/master/docs/hello-state)) - [Hello example with state](https://nlepage.github.io/go-wasm-http-server/hello-state) ([sources](https://github.com/nlepage/go-wasm-http-server/tree/master/docs/hello-state))
- [Hello example with state and keepalive](https://nlepage.github.io/go-wasm-http-server/hello-state-keepalive) ([sources](https://github.com/nlepage/go-wasm-http-server/tree/master/docs/hello-state-keepalive)) - [Hello example with state and keepalive](https://nlepage.github.io/go-wasm-http-server/hello-state-keepalive) ([sources](https://github.com/nlepage/go-wasm-http-server/tree/master/docs/hello-state-keepalive))
- [Hello example with Server Sent Events](https://nlepage.github.io/go-wasm-http-server/hello-sse/) ([sources](https://nlepage.github.io/go-wasm-http-server/hello-sse/))
- [😺 Catption generator example](https://nlepage.github.io/catption/wasm) ([sources](https://github.com/nlepage/catption/tree/wasm)) - [😺 Catption generator example](https://nlepage.github.io/catption/wasm) ([sources](https://github.com/nlepage/catption/tree/wasm))
- [Random password generator web server](https://nlepage.github.io/random-password-please/) ([sources](https://github.com/nlepage/random-password-please) forked from [jbarham/random-password-please](https://github.com/jbarham/random-password-please)) - [Random password generator web server](https://nlepage.github.io/random-password-please/) ([sources](https://github.com/nlepage/random-password-please) forked from [jbarham/random-password-please](https://github.com/jbarham/random-password-please))
- [Server fallbacks, and compiling with TinyGo](https://nlepage.github.io/go-wasm-http-server/tinygo/) (runs locally; see [sources & readme](https://github.com/nlepage/go-wasm-http-server/tree/master/docs/tinygo#readme) for how to run this example)
## How? ## How?
@@ -39,6 +37,7 @@ The slides are available [here](https://nlepage.github.io/go-wasm-http-talk/).
`go-wasm-http-server` requires you to build your Go application to WebAssembly, so you need to make sure your code is compatible: `go-wasm-http-server` requires you to build your Go application to WebAssembly, so you need to make sure your code is compatible:
- no C bindings - no C bindings
- no System dependencies such as file system or network (database server for example) - no System dependencies such as file system or network (database server for example)
- For smaller WASM blobs, your code may also benefit from being compatible with, and compiled by, [TinyGo](https://tinygo.org/docs/reference/lang-support/stdlib/). See the TinyGo specific details below.
## Usage ## Usage
@@ -87,17 +86,37 @@ You may want to use build tags as shown above (or file name suffixes) in order t
Then build your WebAssembly binary: Then build your WebAssembly binary:
```sh ```sh
# To compile with Go
GOOS=js GOARCH=wasm go build -o server.wasm . GOOS=js GOARCH=wasm go build -o server.wasm .
# To compile with TinyGo, if your code is compatible
GOOS=js GOARCH=wasm tinygo build -o server.wasm .
``` ```
### Step 2: Create ServiceWorker file ### Step 2: Create ServiceWorker file
First, check the version of Go/TinyGo you compiled your wasm with:
```sh
$ go version
go version go1.23.4 darwin/arm64
# ^------^
$ tinygo version
tinygo version 0.35.0 darwin/arm64 (using go version go1.23.4 and LLVM version 18.1.2)
# ^----^
```
Create a ServiceWorker file with the following code: Create a ServiceWorker file with the following code:
📄 `sw.js` 📄 `sw.js`
```js ```js
importScripts('https://cdn.jsdelivr.net/gh/golang/go@go1.18.4/misc/wasm/wasm_exec.js') // Note the 'go.1.23.4' below, that matches the version you just found:
importScripts('https://cdn.jsdelivr.net/gh/nlepage/go-wasm-http-server@v2.0.5/sw.js') importScripts('https://cdn.jsdelivr.net/gh/golang/go@go1.23.4/misc/wasm/wasm_exec.js')
// If you compiled with TinyGo then, similarly, use:
importScripts('https://cdn.jsdelivr.net/gh/tinygo-org/tinygo@0.35.0/targets/wasm_exec.js')
importScripts('https://cdn.jsdelivr.net/gh/nlepage/go-wasm-http-server@v2.2.1/sw.js')
registerWasmHTTPListener('path/to/server.wasm') registerWasmHTTPListener('path/to/server.wasm')
``` ```
@@ -163,15 +182,44 @@ URL string of the WebAssembly module, example: `"path/to/my-module.wasm"`.
An optional object containing: An optional object containing:
- `base` (`string`): Base path of the server, relative to the ServiceWorker's scope. - `base` (`string`): Base path of the server, relative to the ServiceWorker's scope.
- `cacheName` (`string`): Name of the [Cache](https://developer.mozilla.org/en-US/docs/Web/API/Cache) to store the WebAssembly binary.
- `args` (`string[]`): Arguments for the WebAssembly module. - `args` (`string[]`): Arguments for the WebAssembly module.
- `passthrough` (`(request: Request): boolean`): Optional callback to allow passing the request through to network.
## Author ## <abbr title="Frequently Asked Questions">FAQ</abbr> ❓
👤 **Nicolas Lepage** ### Are WebSockets supported?
* Website: https://nicolas.lepage.dev/ No, WebSockets arent and wont be supported, because Service Workers cannot intercept websocket connections.
* Twitter: [@njblepage](https://twitter.com/njblepage)
* Github: [@nlepage](https://github.com/nlepage) However [Server Sent Events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events), which is an alternative to WebSockets, are supported, you can find the code for an example [here](https://github.com/nlepage/go-wasm-http-server/tree/master/docs/hello-sse) and the demo [here](https://nlepage.github.io/go-wasm-http-server/hello-sse/).
### Is it compatible with TinyGo?
Yes, an example and some specific information is available [here](https://github.com/nlepage/go-wasm-http-server/tree/master/docs/tinygo).
## Contributors ✨
Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
<!-- prettier-ignore-start -->
<!-- markdownlint-disable -->
<table>
<tbody>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://byjp.me/"><img src="https://avatars.githubusercontent.com/u/42999?v=4?s=100" width="100px;" alt="JP Hastings-Edrei"/><br /><sub><b>JP Hastings-Edrei</b></sub></a><br /><a href="https://github.com/nlepage/go-wasm-http-server/commits?author=jphastings" title="Code">💻</a> <a href="https://github.com/nlepage/go-wasm-http-server/commits?author=jphastings" title="Documentation">📖</a> <a href="#example-jphastings" title="Examples">💡</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://recolude.com/"><img src="https://avatars.githubusercontent.com/u/9094977?v=4?s=100" width="100px;" alt="Eli Davis"/><br /><sub><b>Eli Davis</b></sub></a><br /><a href="https://github.com/nlepage/go-wasm-http-server/commits?author=EliCDavis" title="Code">💻</a> <a href="https://github.com/nlepage/go-wasm-http-server/issues?q=author%3AEliCDavis" title="Bug reports">🐛</a></td>
</tr>
</tbody>
</table>
<!-- markdownlint-restore -->
<!-- prettier-ignore-end -->
<!-- ALL-CONTRIBUTORS-LIST:END -->
This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!
## 🤝 Contributing ## 🤝 Contributing
@@ -183,7 +231,7 @@ Give a ⭐️ if this project helped you!
## 📝 License ## 📝 License
Copyright © 2021 [Nicolas Lepage](https://github.com/nlepage).<br /> Copyright © 2025 [Nicolas Lepage](https://github.com/nlepage).<br />
This project is [Apache 2.0](https://github.com/nlepage/go-wasm-http-server/blob/master/LICENSE) licensed. This project is [Apache 2.0](https://github.com/nlepage/go-wasm-http-server/blob/master/LICENSE) licensed.
*** ***

View File

@@ -1,5 +1,5 @@
importScripts('https://cdn.jsdelivr.net/gh/golang/go@go1.23.1/misc/wasm/wasm_exec.js') importScripts('https://cdn.jsdelivr.net/gh/golang/go@go1.23.1/misc/wasm/wasm_exec.js')
importScripts('https://cdn.jsdelivr.net/gh/nlepage/go-wasm-http-server@v2.0.5/sw.js') importScripts('https://cdn.jsdelivr.net/gh/nlepage/go-wasm-http-server@v2.2.1/sw.js')
const wasm = 'api.wasm' const wasm = 'api.wasm'

View File

@@ -1,5 +1,5 @@
importScripts('https://cdn.jsdelivr.net/gh/golang/go@go1.23.1/misc/wasm/wasm_exec.js') importScripts('https://cdn.jsdelivr.net/gh/golang/go@go1.23.1/misc/wasm/wasm_exec.js')
importScripts('https://cdn.jsdelivr.net/gh/nlepage/go-wasm-http-server@v2.0.5/sw.js') importScripts('https://cdn.jsdelivr.net/gh/nlepage/go-wasm-http-server@v2.2.1/sw.js')
const wasm = 'api.wasm' const wasm = 'api.wasm'

View File

@@ -1,5 +1,5 @@
importScripts('https://cdn.jsdelivr.net/gh/golang/go@go1.23.1/misc/wasm/wasm_exec.js') importScripts('https://cdn.jsdelivr.net/gh/golang/go@go1.23.1/misc/wasm/wasm_exec.js')
importScripts('https://cdn.jsdelivr.net/gh/nlepage/go-wasm-http-server@v2.0.5/sw.js') importScripts('https://cdn.jsdelivr.net/gh/nlepage/go-wasm-http-server@v2.2.1/sw.js')
const wasm = 'api.wasm' const wasm = 'api.wasm'

16
docs/index.html Normal file
View File

@@ -0,0 +1,16 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>go-wasm-http-server examples</title>
</head>
<body>
<h1>go-wasm-http-server examples</h1>
<ul>
<li><a href="hello/">Hello example</a> (<a href="https://github.com/nlepage/go-wasm-http-server/tree/master/docs/hello">Sources</a>)</li>
<li><a href="hello-state/">Hello example with state</a> (<a href="https://github.com/nlepage/go-wasm-http-server/tree/master/docs/hello-state">Sources</a>)</li>
<li><a href="hello-state-keepalive/">Hello example with state and keepalive</a> (<a href="https://github.com/nlepage/go-wasm-http-server/tree/master/docs/hello-state-keepalive">Sources</a>)</li>
<li><a href="hello-sse/">Hello example with Server Sent Events</a> (<a href="https://github.com/nlepage/go-wasm-http-server/tree/master/docs/hello-sse">Sources</a>)</li>
</ul>
<p>See <a href="https://github.com/nlepage/go-wasm-http-server?tab=readme-ov-file#readme">README</a> for more information.</p>
</body>
</html>

42
docs/tinygo/README.md Normal file
View File

@@ -0,0 +1,42 @@
# Compiling with TinyGo
This example demonstrates that go-wasm-http-server can also be compiled with [TinyGo](https://www.tinygo.org), producing significantly smaller WASM blobs, though at the expense of [at least one known bug](https://github.com/tinygo-org/tinygo/issues/1140) and a [reduced standard library](https://tinygo.org/docs/reference/lang-support/stdlib/).
This example also demonstrates how the same code can be used for both server-side execution, and client-side execution in WASM (providing support for clients that cannot interpret WASM).
## Prerequisites
You'll need a version of [TinyGo installed](https://tinygo.org/getting-started/install/). (eg. `brew install tinygo-org/tools/tinygo`)
You'll need to make sure the first line of `sw.js` here has the same tinygo version number as your TinyGo version (this was v0.35.0 at time of writing).
## Build & run
Compile the WASM blob with TinyGo (this has been done for you for this example):
```bash
GOOS=js GOARCH=wasm tinygo build -o api.wasm .
```
Run the server (with Go, not TinyGo):
```bash
$ go run .
Server starting on http://127.0.0.1:<port>
```
## Important notes
You **must** use the TinyGo `wasm_exec.js`, specific to the version of TinyGo used to compile the WASM, in your `sw.js`. For example, if using the JSDelivr CDN:
```js
importScripts('https://cdn.jsdelivr.net/gh/tinygo-org/tinygo@0.35.0/targets/wasm_exec.js')
```
Note that the `0.35.0` within the path matches the TinyGo version used:
```sh
$ tinygo version
tinygo version 0.35.0 darwin/arm64 (using go version go1.23.4 and LLVM version 18.1.2)
# ^----^
```

BIN
docs/tinygo/api.wasm Normal file

Binary file not shown.

19
docs/tinygo/handlers.go Normal file
View File

@@ -0,0 +1,19 @@
package main
import (
"encoding/json"
"net/http"
"runtime"
)
func goRuntimeHandler(res http.ResponseWriter, req *http.Request) {
res.Header().Add("Content-Type", "application/json")
if err := json.NewEncoder(res).Encode(map[string]string{
"os": runtime.GOOS,
"arch": runtime.GOARCH,
"compiler": runtime.Compiler,
"version": runtime.Version(),
}); err != nil {
panic(err)
}
}

44
docs/tinygo/index.html Normal file
View File

@@ -0,0 +1,44 @@
<!DOCTYPE html>
<html>
<head>
<title>go-wasm-http-server tinygo demo</title>
<script>
const sw = navigator.serviceWorker
function attachServiceWorker() {
sw.register('sw.js')
.then(() => {
document.getElementById('wasm-status').innerText = "⚡️ Loaded - Will execute WASM locally"
})
.catch((err) => {
document.getElementById('wasm-status').innerText = "🛑 Error loading service worker — Check console"
console.error(err)
})
}
async function makeQuery() {
const res = await fetch('api/tiny', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
}
})
document.getElementById('output').innerText = await res.text()
}
</script>
</head>
<body>
<p>This example demonstrates that go-wasm-http-server can be compiled with <a href="https://www.tinygo.org">TinyGo</em>, producing significantly smaller WASM blobs, at the expense of <a href="https://github.com/tinygo-org/tinygo/issues/1140">at least one known bug</a>, and a <a href="https://tinygo.org/docs/reference/lang-support/stdlib/">reduced standard library</a>.</p>
<dl><dt>WASM HTTP Service Worker:</dt><dd id="wasm-status">☁️ Not loaded — will call server</dd></dl>
<ol>
<li><button onclick="makeQuery()">Call API</button></li>
<li><button onclick="attachServiceWorker()">Attach the service worker</button></li>
<li><span>Call the API again (Step 1)</span></li>
</ol>
<h3>Response:</h3>
<pre id="output"></pre>
</body>
</html>

34
docs/tinygo/server.go Normal file
View File

@@ -0,0 +1,34 @@
//go:build !wasm
// +build !wasm
package main
import (
"embed"
"fmt"
"log"
"net"
"net/http"
)
//go:embed *.html *.js *.wasm
var thisDir embed.FS
func main() {
// Serve all files in this directory statically
http.Handle("/", http.FileServer(http.FS(thisDir)))
// Note that this needs to be mounted at /api/tiny, rather than just /tiny (like in wasm.go)
// because the service worker mounts the WASM server at /api (at the end of sw.js)
http.HandleFunc("/api/tiny", goRuntimeHandler)
// Pick any available port. Note that ServiceWorkers _require_ localhost for non-SSL serving (so other LAN/WAN IPs will prevent the service worker from loading)
listener, err := net.Listen("tcp", ":0")
if err != nil {
log.Fatalf("Unable to claim a port to start server on: %v", err)
}
// Share the port being used & start
fmt.Printf("Server starting on http://127.0.0.1:%d\n", listener.Addr().(*net.TCPAddr).Port)
panic(http.Serve(listener, nil))
}

14
docs/tinygo/sw.js Normal file
View File

@@ -0,0 +1,14 @@
importScripts('https://cdn.jsdelivr.net/gh/tinygo-org/tinygo@0.35.0/targets/wasm_exec.js')
importScripts('https://cdn.jsdelivr.net/gh/nlepage/go-wasm-http-server@v2.2.1/sw.js')
const wasm = 'api.wasm'
addEventListener('install', (event) => {
event.waitUntil(caches.open('examples').then((cache) => cache.add(wasm)))
})
addEventListener('activate', (event) => {
event.waitUntil(clients.claim())
})
registerWasmHTTPListener(wasm, { base: 'api' })

18
docs/tinygo/wasm.go Normal file
View File

@@ -0,0 +1,18 @@
//go:build wasm
// +build wasm
package main
import (
"net/http"
wasmhttp "github.com/nlepage/go-wasm-http-server/v2"
)
func main() {
http.HandleFunc("/tiny", goRuntimeHandler)
wasmhttp.Serve(nil)
select {}
}

3
go.sum
View File

@@ -4,3 +4,6 @@ github.com/nlepage/go-js-promise v1.0.0 h1:K7OmJ3+0BgWJ2LfXchg2sI6RDr7AW/KWR8182
github.com/nlepage/go-js-promise v1.0.0/go.mod h1:bdOP0wObXu34euibyK39K1hoBCtlgTKXGc56AGflaRo= github.com/nlepage/go-js-promise v1.0.0/go.mod h1:bdOP0wObXu34euibyK39K1hoBCtlgTKXGc56AGflaRo=
github.com/tmaxmax/go-sse v0.8.0 h1:pPpTgyyi1r7vG2o6icebnpGEh3ebcnBXqDWkb7aTofs= github.com/tmaxmax/go-sse v0.8.0 h1:pPpTgyyi1r7vG2o6icebnpGEh3ebcnBXqDWkb7aTofs=
github.com/tmaxmax/go-sse v0.8.0/go.mod h1:HLoxqxdH+7oSUItjtnpxjzJedfr/+Rrm/dNWBcTxJFM= github.com/tmaxmax/go-sse v0.8.0/go.mod h1:HLoxqxdH+7oSUItjtnpxjzJedfr/+Rrm/dNWBcTxJFM=
golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/tools v0.5.0/go.mod h1:N+Kgy78s5I24c24dU8OfWNEotWjutIs8SnJvn5IDq+k=

View File

@@ -14,7 +14,7 @@ type Reader struct {
off int off int
} }
var _ io.Reader = (*Reader)(nil) var _ io.ReadCloser = (*Reader)(nil)
func NewReader(r safejs.Value) *Reader { func NewReader(r safejs.Value) *Reader {
return &Reader{ return &Reader{
@@ -83,3 +83,14 @@ func (r *Reader) Read(p []byte) (int, error) {
return n, nil return n, nil
} }
func (r *Reader) Close() error {
p, err := r.value.Call("cancel")
if err != nil {
return err
}
_, err = promise.Await(safejs.Unsafe(p))
return err
}

787
package-lock.json generated Normal file
View File

@@ -0,0 +1,787 @@
{
"name": "go-wasm-http-server",
"version": "0.1.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "go-wasm-http-server",
"version": "0.1.0",
"license": "Apache-2.0",
"devDependencies": {
"all-contributors-cli": "^6.26.1"
}
},
"node_modules/@babel/runtime": {
"version": "7.26.0",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.0.tgz",
"integrity": "sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==",
"dev": true,
"license": "MIT",
"dependencies": {
"regenerator-runtime": "^0.14.0"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/all-contributors-cli": {
"version": "6.26.1",
"resolved": "https://registry.npmjs.org/all-contributors-cli/-/all-contributors-cli-6.26.1.tgz",
"integrity": "sha512-Ymgo3FJACRBEd1eE653FD1J/+uD0kqpUNYfr9zNC1Qby0LgbhDBzB3EF6uvkAbYpycStkk41J+0oo37Lc02yEw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.7.6",
"async": "^3.1.0",
"chalk": "^4.0.0",
"didyoumean": "^1.2.1",
"inquirer": "^7.3.3",
"json-fixer": "^1.6.8",
"lodash": "^4.11.2",
"node-fetch": "^2.6.0",
"pify": "^5.0.0",
"yargs": "^15.0.1"
},
"bin": {
"all-contributors": "dist/cli.js"
},
"engines": {
"node": ">=4"
},
"optionalDependencies": {
"prettier": "^2"
}
},
"node_modules/ansi-escapes": {
"version": "4.3.2",
"resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz",
"integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"type-fest": "^0.21.3"
},
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/ansi-regex": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dev": true,
"license": "MIT",
"dependencies": {
"color-convert": "^2.0.1"
},
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
"node_modules/async": {
"version": "3.2.6",
"resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz",
"integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==",
"dev": true,
"license": "MIT"
},
"node_modules/camelcase": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
"integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=6"
}
},
"node_modules/chalk": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"dev": true,
"license": "MIT",
"dependencies": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/chalk/chalk?sponsor=1"
}
},
"node_modules/chardet": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz",
"integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==",
"dev": true,
"license": "MIT"
},
"node_modules/cli-cursor": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
"integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==",
"dev": true,
"license": "MIT",
"dependencies": {
"restore-cursor": "^3.1.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/cli-width": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz",
"integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==",
"dev": true,
"license": "ISC",
"engines": {
"node": ">= 10"
}
},
"node_modules/cliui": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz",
"integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
"dev": true,
"license": "ISC",
"dependencies": {
"string-width": "^4.2.0",
"strip-ansi": "^6.0.0",
"wrap-ansi": "^6.2.0"
}
},
"node_modules/color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"color-name": "~1.1.4"
},
"engines": {
"node": ">=7.0.0"
}
},
"node_modules/color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true,
"license": "MIT"
},
"node_modules/decamelize": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
"integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/didyoumean": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz",
"integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==",
"dev": true,
"license": "Apache-2.0"
},
"node_modules/emoji-regex": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
"dev": true,
"license": "MIT"
},
"node_modules/escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
"integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=0.8.0"
}
},
"node_modules/external-editor": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz",
"integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==",
"dev": true,
"license": "MIT",
"dependencies": {
"chardet": "^0.7.0",
"iconv-lite": "^0.4.24",
"tmp": "^0.0.33"
},
"engines": {
"node": ">=4"
}
},
"node_modules/figures": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz",
"integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==",
"dev": true,
"license": "MIT",
"dependencies": {
"escape-string-regexp": "^1.0.5"
},
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/find-up": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
"integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
"dev": true,
"license": "MIT",
"dependencies": {
"locate-path": "^5.0.0",
"path-exists": "^4.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/get-caller-file": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
"dev": true,
"license": "ISC",
"engines": {
"node": "6.* || 8.* || >= 10.*"
}
},
"node_modules/has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/iconv-lite": {
"version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
"integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
"dev": true,
"license": "MIT",
"dependencies": {
"safer-buffer": ">= 2.1.2 < 3"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/inquirer": {
"version": "7.3.3",
"resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.3.3.tgz",
"integrity": "sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==",
"dev": true,
"license": "MIT",
"dependencies": {
"ansi-escapes": "^4.2.1",
"chalk": "^4.1.0",
"cli-cursor": "^3.1.0",
"cli-width": "^3.0.0",
"external-editor": "^3.0.3",
"figures": "^3.0.0",
"lodash": "^4.17.19",
"mute-stream": "0.0.8",
"run-async": "^2.4.0",
"rxjs": "^6.6.0",
"string-width": "^4.1.0",
"strip-ansi": "^6.0.0",
"through": "^2.3.6"
},
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/is-fullwidth-code-point": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/json-fixer": {
"version": "1.6.15",
"resolved": "https://registry.npmjs.org/json-fixer/-/json-fixer-1.6.15.tgz",
"integrity": "sha512-TuDuZ5KrgyjoCIppdPXBMqiGfota55+odM+j2cQ5rt/XKyKmqGB3Whz1F8SN8+60yYGy/Nu5lbRZ+rx8kBIvBw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.18.9",
"chalk": "^4.1.2",
"pegjs": "^0.10.0"
},
"engines": {
"node": ">=10"
}
},
"node_modules/locate-path": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
"integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
"dev": true,
"license": "MIT",
"dependencies": {
"p-locate": "^4.1.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/lodash": {
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
"dev": true,
"license": "MIT"
},
"node_modules/mimic-fn": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
"integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=6"
}
},
"node_modules/mute-stream": {
"version": "0.0.8",
"resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz",
"integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==",
"dev": true,
"license": "ISC"
},
"node_modules/node-fetch": {
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
"integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
"dev": true,
"license": "MIT",
"dependencies": {
"whatwg-url": "^5.0.0"
},
"engines": {
"node": "4.x || >=6.0.0"
},
"peerDependencies": {
"encoding": "^0.1.0"
},
"peerDependenciesMeta": {
"encoding": {
"optional": true
}
}
},
"node_modules/onetime": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
"integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
"dev": true,
"license": "MIT",
"dependencies": {
"mimic-fn": "^2.1.0"
},
"engines": {
"node": ">=6"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/os-tmpdir": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
"integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/p-limit": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
"integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
"dev": true,
"license": "MIT",
"dependencies": {
"p-try": "^2.0.0"
},
"engines": {
"node": ">=6"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/p-locate": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
"integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
"dev": true,
"license": "MIT",
"dependencies": {
"p-limit": "^2.2.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/p-try": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=6"
}
},
"node_modules/path-exists": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
"integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/pegjs": {
"version": "0.10.0",
"resolved": "https://registry.npmjs.org/pegjs/-/pegjs-0.10.0.tgz",
"integrity": "sha512-qI5+oFNEGi3L5HAxDwN2LA4Gg7irF70Zs25edhjld9QemOgp0CbvMtbFcMvFtEo1OityPrcCzkQFB8JP/hxgow==",
"dev": true,
"license": "MIT",
"bin": {
"pegjs": "bin/pegjs"
},
"engines": {
"node": ">=0.10"
}
},
"node_modules/pify": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/pify/-/pify-5.0.0.tgz",
"integrity": "sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/prettier": {
"version": "2.8.8",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz",
"integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==",
"dev": true,
"license": "MIT",
"optional": true,
"bin": {
"prettier": "bin-prettier.js"
},
"engines": {
"node": ">=10.13.0"
},
"funding": {
"url": "https://github.com/prettier/prettier?sponsor=1"
}
},
"node_modules/regenerator-runtime": {
"version": "0.14.1",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
"integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==",
"dev": true,
"license": "MIT"
},
"node_modules/require-directory": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
"integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/require-main-filename": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
"integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
"dev": true,
"license": "ISC"
},
"node_modules/restore-cursor": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz",
"integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==",
"dev": true,
"license": "MIT",
"dependencies": {
"onetime": "^5.1.0",
"signal-exit": "^3.0.2"
},
"engines": {
"node": ">=8"
}
},
"node_modules/run-async": {
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz",
"integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=0.12.0"
}
},
"node_modules/rxjs": {
"version": "6.6.7",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz",
"integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"tslib": "^1.9.0"
},
"engines": {
"npm": ">=2.0.0"
}
},
"node_modules/safer-buffer": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
"dev": true,
"license": "MIT"
},
"node_modules/set-blocking": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
"integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==",
"dev": true,
"license": "ISC"
},
"node_modules/signal-exit": {
"version": "3.0.7",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
"integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
"dev": true,
"license": "ISC"
},
"node_modules/string-width": {
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
"dev": true,
"license": "MIT",
"dependencies": {
"emoji-regex": "^8.0.0",
"is-fullwidth-code-point": "^3.0.0",
"strip-ansi": "^6.0.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/strip-ansi": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
"dev": true,
"license": "MIT",
"dependencies": {
"ansi-regex": "^5.0.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"dev": true,
"license": "MIT",
"dependencies": {
"has-flag": "^4.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/through": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
"integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==",
"dev": true,
"license": "MIT"
},
"node_modules/tmp": {
"version": "0.0.33",
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
"integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
"dev": true,
"license": "MIT",
"dependencies": {
"os-tmpdir": "~1.0.2"
},
"engines": {
"node": ">=0.6.0"
}
},
"node_modules/tr46": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
"dev": true,
"license": "MIT"
},
"node_modules/tslib": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
"dev": true,
"license": "0BSD"
},
"node_modules/type-fest": {
"version": "0.21.3",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz",
"integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==",
"dev": true,
"license": "(MIT OR CC0-1.0)",
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/webidl-conversions": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
"dev": true,
"license": "BSD-2-Clause"
},
"node_modules/whatwg-url": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
"dev": true,
"license": "MIT",
"dependencies": {
"tr46": "~0.0.3",
"webidl-conversions": "^3.0.0"
}
},
"node_modules/which-module": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz",
"integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==",
"dev": true,
"license": "ISC"
},
"node_modules/wrap-ansi": {
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
"integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
"dev": true,
"license": "MIT",
"dependencies": {
"ansi-styles": "^4.0.0",
"string-width": "^4.1.0",
"strip-ansi": "^6.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/y18n": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz",
"integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==",
"dev": true,
"license": "ISC"
},
"node_modules/yargs": {
"version": "15.4.1",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz",
"integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==",
"dev": true,
"license": "MIT",
"dependencies": {
"cliui": "^6.0.0",
"decamelize": "^1.2.0",
"find-up": "^4.1.0",
"get-caller-file": "^2.0.1",
"require-directory": "^2.1.1",
"require-main-filename": "^2.0.0",
"set-blocking": "^2.0.0",
"string-width": "^4.2.0",
"which-module": "^2.0.0",
"y18n": "^4.0.0",
"yargs-parser": "^18.1.2"
},
"engines": {
"node": ">=8"
}
},
"node_modules/yargs-parser": {
"version": "18.1.3",
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
"integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
"dev": true,
"license": "ISC",
"dependencies": {
"camelcase": "^5.0.0",
"decamelize": "^1.2.0"
},
"engines": {
"node": ">=6"
}
}
}
}

View File

@@ -5,5 +5,8 @@
"main": "index.js", "main": "index.js",
"repository": "https://github.com/nlepage/go-wasm-http-server", "repository": "https://github.com/nlepage/go-wasm-http-server",
"author": "Nicolas Lepage <19571875+nlepage@users.noreply.github.com>", "author": "Nicolas Lepage <19571875+nlepage@users.noreply.github.com>",
"license": "Apache-2.0" "license": "Apache-2.0",
"devDependencies": {
"all-contributors-cli": "^6.26.1"
}
} }

View File

@@ -3,7 +3,7 @@ package wasmhttp
import ( import (
"io" "io"
"net/http" "net/http"
"net/http/httptest" "net/url"
"syscall/js" "syscall/js"
promise "github.com/nlepage/go-js-promise" promise "github.com/nlepage/go-js-promise"
@@ -20,7 +20,11 @@ func Request(uvalue js.Value) (*http.Request, error) {
return nil, err return nil, err
} }
url, err := value.GetString("url") rawURL, err := value.GetString("url")
if err != nil {
return nil, err
}
u, err := url.Parse(rawURL)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -30,7 +34,7 @@ func Request(uvalue js.Value) (*http.Request, error) {
return nil, err return nil, err
} }
var bodyReader io.Reader var bodyReader io.ReadCloser
if !body.IsNull() { if !body.IsNull() {
// WORKAROUND: Firefox does not have request.body ReadableStream // WORKAROUND: Firefox does not have request.body ReadableStream
@@ -59,11 +63,15 @@ func Request(uvalue js.Value) (*http.Request, error) {
bodyReader = readablestream.NewReader(r) bodyReader = readablestream.NewReader(r)
} }
req := httptest.NewRequest( req := &http.Request{
method, Method: method,
url, URL: u,
bodyReader, Body: bodyReader,
) Header: make(http.Header),
Proto: "HTTP/1.1",
ProtoMajor: 1,
ProtoMinor: 1,
}
headers, err := value.Get("headers") headers, err := value.Get("headers")
if err != nil { if err != nil {

View File

@@ -123,6 +123,9 @@ func (r *response) Flush() {
// Close implements [io.Closer] // Close implements [io.Closer]
func (r *response) Close() error { func (r *response) Close() error {
if !r.wroteHeader {
r.WriteHeader(200)
}
if err := r.body.Flush(); err != nil { if err := r.body.Flush(); err != nil {
return err return err
} }

7
sw.js
View File

@@ -1,4 +1,4 @@
function registerWasmHTTPListener(wasm, { base, cacheName, args = [] } = {}) { function registerWasmHTTPListener(wasm, { base, cacheName, passthrough, args = [] } = {}) {
let path = new URL(registration.scope).pathname let path = new URL(registration.scope).pathname
if (base && base !== '') path = `${trimEnd(path, '/')}/${trimStart(base, '/')}` if (base && base !== '') path = `${trimEnd(path, '/')}/${trimStart(base, '/')}`
@@ -17,6 +17,11 @@ function registerWasmHTTPListener(wasm, { base, cacheName, args = [] } = {}) {
WebAssembly.instantiateStreaming(source, go.importObject).then(({ instance }) => go.run(instance)) WebAssembly.instantiateStreaming(source, go.importObject).then(({ instance }) => go.run(instance))
addEventListener('fetch', e => { addEventListener('fetch', e => {
if (passthrough?.(e.request)) {
e.respondWith(fetch(e.request))
return;
}
const { pathname } = new URL(e.request.url) const { pathname } = new URL(e.request.url)
if (!pathname.startsWith(path)) return if (!pathname.startsWith(path)) return