diff --git a/examples/with-plasmo/package.json b/examples/with-plasmo/package.json index f188e5f..a6e2e76 100644 --- a/examples/with-plasmo/package.json +++ b/examples/with-plasmo/package.json @@ -13,6 +13,7 @@ "plasmo": "^0.84.0", "react": "^18.2.0", "react-dom": "^18.2.0", + "superjson": "^2.2.1", "zod": "^3.19.1" }, "devDependencies": { diff --git a/examples/with-plasmo/src/background.ts b/examples/with-plasmo/src/background.ts index caf6de8..0c023c4 100644 --- a/examples/with-plasmo/src/background.ts +++ b/examples/with-plasmo/src/background.ts @@ -1,4 +1,6 @@ import { initTRPC } from '@trpc/server'; +import { observable } from '@trpc/server/observable'; +import SuperJSON from 'superjson'; import { z } from 'zod'; import { createChromeHandler } from '../../../adapter'; @@ -6,12 +8,21 @@ import { createChromeHandler } from '../../../adapter'; const t = initTRPC.create({ isServer: false, allowOutsideOfServer: true, + transformer: SuperJSON, }); const appRouter = t.router({ openNewTab: t.procedure.input(z.object({ url: z.string().url() })).mutation(async ({ input }) => { await chrome.tabs.create({ url: input.url, active: true }); }), + subscribeToAnything: t.procedure.subscription(() => { + return observable((emit) => { + const interval = setInterval(() => { + emit.next(new Date().toISOString()); + }, 1000); + return () => clearInterval(interval); + }); + }), }); export type AppRouter = typeof appRouter; diff --git a/examples/with-plasmo/src/contents/content.ts b/examples/with-plasmo/src/contents/content.ts index 30d931a..a569e6f 100644 --- a/examples/with-plasmo/src/contents/content.ts +++ b/examples/with-plasmo/src/contents/content.ts @@ -1,8 +1,11 @@ import { relay } from 'trpc-browser/relay'; import { autoConnect } from 'trpc-browser/shared/chrome'; -void autoConnect(chrome, (port) => { - return relay(window, port); // return so it has the cleanup function for disconnect -}).then(() => { +void autoConnect( + () => chrome.runtime.connect(), + (port) => { + return relay(window, port); // return so it has the cleanup function for disconnect + }, +).then(() => { return console.log('Content script loaded - bridge initialized'); }); diff --git a/examples/with-plasmo/src/contents/inpage.tsx b/examples/with-plasmo/src/contents/inpage.tsx index dc0345e..b79474f 100644 --- a/examples/with-plasmo/src/contents/inpage.tsx +++ b/examples/with-plasmo/src/contents/inpage.tsx @@ -1,6 +1,7 @@ import { createTRPCProxyClient } from '@trpc/client'; import type { PlasmoCSConfig } from 'plasmo'; import type { FC } from 'react'; +import SuperJSON from 'superjson'; import { windowLink } from 'trpc-browser/link'; import type { AppRouter } from '~background'; @@ -12,6 +13,7 @@ export const config: PlasmoCSConfig = { }; const windowClient = createTRPCProxyClient({ + transformer: SuperJSON, links: [/* 👉 */ windowLink({ window })], }); @@ -30,8 +32,10 @@ const ExtensionInpageUi: FC = () => { cursor: 'pointer', }} onClick={async () => { - await windowClient.openNewTab.mutate({ - url: 'https://google.com', + await windowClient.subscribeToAnything.subscribe(undefined, { + onData(data) { + console.log('data', data); + }, }); }} > diff --git a/package-lock.json b/package-lock.json index d8f729e..885da71 100644 --- a/package-lock.json +++ b/package-lock.json @@ -48,6 +48,7 @@ "plasmo": "^0.84.0", "react": "^18.2.0", "react-dom": "^18.2.0", + "superjson": "^2.2.1", "zod": "^3.19.1" }, "devDependencies": { @@ -58,6 +59,17 @@ "typescript": "^4.9.3" } }, + "examples/with-plasmo/node_modules/superjson": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/superjson/-/superjson-2.2.1.tgz", + "integrity": "sha512-8iGv75BYOa0xRJHK5vRLEjE2H/i4lulTjzpUXic3Eg8akftYjkmQDa8JARQ42rlczXyFR3IeRoeFCc7RxHsYZA==", + "dependencies": { + "copy-anything": "^3.0.2" + }, + "engines": { + "node": ">=16" + } + }, "node_modules/@ampproject/remapping": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", @@ -7625,7 +7637,6 @@ "version": "3.0.5", "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-3.0.5.tgz", "integrity": "sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==", - "dev": true, "dependencies": { "is-what": "^4.1.8" }, @@ -10257,7 +10268,6 @@ "version": "4.1.11", "resolved": "https://registry.npmjs.org/is-what/-/is-what-4.1.11.tgz", "integrity": "sha512-gr9+qDrJvdwT4+N2TAACsZQIB4Ow9j2eefqlh3m9JUV41M1LoKhcE+/j+IVni/r6U8Jnc1PwhjdjVJr+Xmtb0A==", - "dev": true, "engines": { "node": ">=12.13" }, diff --git a/src/adapter/chrome.ts b/src/adapter/chrome.ts index d7b0104..600f636 100644 --- a/src/adapter/chrome.ts +++ b/src/adapter/chrome.ts @@ -67,14 +67,16 @@ export const createChromeHandler = ( sendResponse({ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment - error: getErrorShape({ - config: router._def._config, - error, - type: method, - path: params.path, - input: params.input, - ctx, - }), + error: transformer.output.serialize( + getErrorShape({ + config: router._def._config, + error, + type: method, + path: params.path, + input: params.input, + ctx, + }), + ), }); }; @@ -105,7 +107,10 @@ export const createChromeHandler = ( } const subscription = result.subscribe({ - next: (data) => sendResponse({ result: { type: 'data', data } }), + next: (data) => { + const serializedData = transformer.output.serialize(data); + sendResponse({ result: { type: 'data', data: serializedData } }); + }, error: handleError, complete: () => sendResponse({ result: { type: 'stopped' } }), }); diff --git a/src/adapter/window.ts b/src/adapter/window.ts index 1e63f8f..b8a82db 100644 --- a/src/adapter/window.ts +++ b/src/adapter/window.ts @@ -73,14 +73,16 @@ export const createWindowHandler = ( sendResponse({ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment - error: getErrorShape({ - config: router._def._config, - error, - type: method, - path: params.path, - input: params.input, - ctx, - }), + error: transformer.output.serialize( + getErrorShape({ + config: router._def._config, + error, + type: method, + path: params.path, + input: params.input, + ctx, + }), + ), }); }; @@ -111,7 +113,11 @@ export const createWindowHandler = ( } const subscription = result.subscribe({ - next: (data) => sendResponse({ result: { type: 'data', data } }), + next: (data) => { + const serializedData = transformer.output.serialize(data); + + sendResponse({ result: { type: 'data', data: serializedData } }); + }, error: handleError, complete: () => sendResponse({ result: { type: 'stopped' } }), });