| 123456789101112131415161718192021222324252627282930313233343536373839404142 |
- export namespace Rpc {
- type Definition = {
- [method: string]: (input: any) => any
- }
- export function listen(rpc: Definition) {
- onmessage = async (evt) => {
- const parsed = JSON.parse(evt.data)
- if (parsed.type === "rpc.request") {
- const result = await rpc[parsed.method](parsed.input)
- postMessage(JSON.stringify({ type: "rpc.result", result, id: parsed.id }))
- }
- }
- }
- export function client<T extends Definition>(target: {
- postMessage: (data: string) => void | null
- onmessage: ((this: Worker, ev: MessageEvent<any>) => any) | null
- }) {
- const pending = new Map<number, (result: any) => void>()
- let id = 0
- target.onmessage = async (evt) => {
- const parsed = JSON.parse(evt.data)
- if (parsed.type === "rpc.result") {
- const resolve = pending.get(parsed.id)
- if (resolve) {
- resolve(parsed.result)
- pending.delete(parsed.id)
- }
- }
- }
- return {
- call<Method extends keyof T>(method: Method, input: Parameters<T[Method]>[0]): Promise<ReturnType<T[Method]>> {
- const requestId = id++
- return new Promise((resolve) => {
- pending.set(requestId, resolve)
- target.postMessage(JSON.stringify({ type: "rpc.request", method, input, id: requestId }))
- })
- },
- }
- }
- }
|