2019-12-02 16:02:30 +01:00

56 lines
1.4 KiB
JavaScript

let nextHandlerId = 1
const handlerResolvers = {}
const startWasm = async (wasm, WASMHTTP_HANDLER_ID, WASMHTTP_PATH) => {
const go = new Go()
go.env = {
WASMHTTP_HANDLER_ID,
WASMHTTP_PATH,
}
const { instance } = await WebAssembly.instantiateStreaming(fetch(wasm), go.importObject)
return go.run(instance)
}
const trimStart = (s, c) => {
let r = s
while (r.startsWith(c)) r = r.slice(c.length)
return r
}
const trimEnd = (s, c) => {
let r = s
while (r.endsWith(c)) r = r.slice(0, -c.length)
return r
}
self.wasmhttp = {
serve: ({ wasm, base } = {}) => {
try {
if (!wasm) throw TypeError('options.wasm must be defined')
const handlerId = `${nextHandlerId++}`
const handler = new Promise(resolve => handlerResolvers[handlerId] = resolve)
let path = new URL(registration.scope).pathname
if (base && base !== '') path = `${trimEnd(path, '/')}/${trimStart(base, '/')}`
startWasm(wasm, handlerId, path)
addEventListener('fetch', async e => {
if (!new URL(e.request.url).pathname.startsWith(path)) return
// FIXME try catch
e.respondWith((await handler)(e.request))
})
} catch (e) {
console.error('wasmhttp: error:', e)
throw e
}
},
registerHandler: (handlerId, handler) => {
handlerResolvers[handlerId](handler)
delete handlerResolvers[handlerId]
},
}