UNPKG

trpc-browser

Version:

tRPC adapters and links for everywhere in the browser

110 lines 5.52 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createChromeHandler = void 0; const server_1 = require("@trpc/server"); const observable_1 = require("@trpc/server/observable"); const shared_1 = require("@trpc/server/shared"); const trpcMessage_1 = require("../shared/trpcMessage"); const errors_1 = require("./errors"); const createChromeHandler = (opts) => { const { router, createContext, onError, chrome = global.chrome } = opts; if (!chrome) { console.warn("Skipping chrome handler creation: 'opts.chrome' not defined"); return; } chrome.runtime.onConnect.addListener((port) => { // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment const { transformer } = router._def._config; const subscriptions = new Map(); const listeners = []; const cleanup = () => listeners.forEach((unsub) => unsub()); port.onDisconnect.addListener(cleanup); listeners.push(() => port.onDisconnect.removeListener(cleanup)); const onMessage = async (message) => { var _a; if (!port || !(0, trpcMessage_1.isTRPCRequestWithId)(message)) return; const { trpc } = message; const sendResponse = (response) => { port.postMessage({ trpc: Object.assign({ id: trpc.id, jsonrpc: trpc.jsonrpc }, response), }); }; if (trpc.method === 'subscription.stop') { (_a = subscriptions.get(trpc.id)) === null || _a === void 0 ? void 0 : _a.unsubscribe(); subscriptions.delete(trpc.id); return sendResponse({ result: { type: 'stopped' } }); } const { method, params, id } = trpc; const ctx = await (createContext === null || createContext === void 0 ? void 0 : createContext({ req: port, res: undefined })); const handleError = (cause) => { const error = (0, errors_1.getErrorFromUnknown)(cause); onError === null || onError === void 0 ? void 0 : onError({ error, type: method, path: params.path, input: params.input, ctx, req: port, }); sendResponse({ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment error: (0, shared_1.getErrorShape)({ config: router._def._config, error, type: method, path: params.path, input: params.input, ctx, }), }); }; try { // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call const input = transformer.input.deserialize(trpc.params.input); const caller = router.createCaller(ctx); const procedureFn = trpc.params.path .split('.') // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-return, @typescript-eslint/no-explicit-any .reduce((acc, segment) => acc[segment], caller); // eslint-disable-next-line @typescript-eslint/no-unsafe-argument const result = await procedureFn(input); if (trpc.method !== 'subscription') { return sendResponse({ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call result: { type: 'data', data: transformer.output.serialize(result) }, }); } if (!(0, observable_1.isObservable)(result)) { throw new server_1.TRPCError({ message: `Subscription ${params.path} did not return an observable`, code: 'INTERNAL_SERVER_ERROR', }); } const subscription = result.subscribe({ next: (data) => { const serializedData = transformer.output.serialize(data); sendResponse({ result: { type: 'data', data: serializedData } }); }, error: handleError, complete: () => sendResponse({ result: { type: 'stopped' } }), }); if (subscriptions.has(id)) { subscription.unsubscribe(); sendResponse({ result: { type: 'stopped' } }); throw new server_1.TRPCError({ message: `Duplicate id ${id}`, code: 'BAD_REQUEST' }); } listeners.push(() => subscription.unsubscribe()); subscriptions.set(id, subscription); sendResponse({ result: { type: 'started' } }); } catch (cause) { handleError(cause); } }; port.onMessage.addListener(onMessage); listeners.push(() => port.onMessage.removeListener(onMessage)); }); }; exports.createChromeHandler = createChromeHandler; //# sourceMappingURL=chrome.js.map