UNPKG

@vitejs/plugin-rsc

Version:
91 lines (89 loc) 2.35 kB
import { decode, encode } from "turbo-stream"; //#region src/utils/rpc.ts const decodePlugins = [(type, ...rest) => { switch (type) { case "Request": { const [method, url, headers, body] = rest; return { value: new Request(url, { body, headers, method, duplex: body ? "half" : void 0 }) }; } case "Response": { const [status, statusText, headers, body] = rest; return { value: new Response(body, { headers, status, statusText }) }; } } return false; }]; const encodePlugins = [(obj) => { if (obj instanceof Request) return [ "Request", obj.method, obj.url, Array.from(obj.headers), obj.body ]; if (obj instanceof Response) return [ "Response", obj.status, obj.statusText, Array.from(obj.headers), obj.body ]; return false; }]; function createRpcServer(handlers) { return async (request) => { if (!request.body) throw new Error(`loadModuleDevProxy error: missing request body`); const reqPayload = await decode(request.body.pipeThrough(new TextDecoderStream()), { plugins: decodePlugins }); const handler = handlers[reqPayload.method]; if (!handler) throw new Error(`loadModuleDevProxy error: unknown method ${reqPayload.method}`); const resPayload = { ok: true, data: void 0 }; try { resPayload.data = await handler(...reqPayload.args); } catch (e) { resPayload.ok = false; resPayload.data = e; } return new Response(encode(resPayload, { plugins: encodePlugins, redactErrors: false })); }; } function createRpcClient(options) { async function callRpc(method, args) { const body = encode({ method, args }, { plugins: encodePlugins, redactErrors: false }).pipeThrough(new TextEncoderStream()); const res = await fetch(options.endpoint, { method: "POST", body, duplex: "half" }); if (!res.ok || !res.body) throw new Error(`loadModuleDevProxy error: ${res.status} ${res.statusText}`); const resPayload = await decode(res.body.pipeThrough(new TextDecoderStream()), { plugins: decodePlugins }); if (!resPayload.ok) throw resPayload.data; return resPayload.data; } return new Proxy({}, { get(_target, p, _receiver) { if (typeof p !== "string" || p === "then") return; return (...args) => callRpc(p, args); } }); } //#endregion export { createRpcServer as n, createRpcClient as t };