File tree 6 files changed +167
-0
lines changed
src/entrypoints.inactive/trpc
6 files changed +167
-0
lines changed Original file line number Diff line number Diff line change
1
+ # trpc
2
+
3
+ - [ trpc-chrome] ( https://github.com/jlalmes/trpc-chrome ) : See [ trpc] ( #trpc )
4
+
5
+ 1 . Replace the ` background ` and ` popup ` entrypoints with the ones in the ` entrypoints.inactive/trpc ` folder.
6
+ 2 . Install the needed packages:
7
+
8
+ ``` shell
9
+ # trpc with react-query, see https://trpc.io/docs/v10/client/react/setup
10
+ bun i @trpc/client @trpc/server @trpc/react-query @tanstack/react-query@4
11
+ # trpc-chrome
12
+ bun i trpc-chrome
13
+ # zod
14
+ bun i zod
15
+ # mitt, event emitter, for trpc subscription
16
+ bun i mitt
17
+ ```
Original file line number Diff line number Diff line change
1
+ import { initTRPC } from '@trpc/server'
2
+ import { observable } from '@trpc/server/observable'
3
+ import mitt from 'mitt'
4
+ import { createChromeHandler } from 'trpc-chrome/adapter'
5
+ import z from 'zod'
6
+
7
+ type Events = Record < string , unknown > & {
8
+ greeting : string
9
+ updateTimestamp : number
10
+ }
11
+
12
+ const ee = mitt < Events > ( )
13
+
14
+ const t = initTRPC . create ( {
15
+ allowOutsideOfServer : true ,
16
+ isServer : false ,
17
+ } )
18
+
19
+ // Uncomment below eslint comments to temporarily turn off object sorting
20
+ // /* eslint-disable perfectionist/sort-objects */
21
+ const router = t . router ( {
22
+ greeting : t . procedure . input ( z . object ( { name : z . string ( ) } ) ) . query ( ( req ) => {
23
+ const { input } = req
24
+ ee . emit ( 'greeting' , `Greeted ${ input . name } ` )
25
+
26
+ return `Hello ${ input . name } ` as const
27
+ } ) ,
28
+ onGreeting : t . procedure . subscription ( ( ) => {
29
+ return observable ( ( emit ) => {
30
+ function onGreet ( hello : string ) {
31
+ emit . next ( hello )
32
+ }
33
+
34
+ ee . on ( 'greeting' , onGreet )
35
+
36
+ return ( ) => {
37
+ ee . off ( 'greeting' , onGreet )
38
+ }
39
+ } )
40
+ } ) ,
41
+ } )
42
+ // /* eslint-enable perfectionist/sort-objects */
43
+
44
+ export type AppRouter = typeof router
45
+
46
+ export default defineBackground ( ( ) => {
47
+ createChromeHandler ( {
48
+ createContext : undefined ,
49
+ onError : undefined ,
50
+ router,
51
+ } )
52
+ } )
Original file line number Diff line number Diff line change
1
+ import { createTRPCProxyClient } from '@trpc/client'
2
+ import { chromeLink } from 'trpc-chrome/link'
3
+
4
+ import type { AppRouter } from './background'
5
+
6
+ // Integrated - Vanilla
7
+ // More: https://wxt.dev/guide/content-script-ui.html
8
+ // If using Integrated - React, refer to the popup's trpc usage
9
+ export default defineContentScript ( {
10
+ async main ( ) {
11
+ const port = chrome . runtime . connect ( )
12
+ const trpc = createTRPCProxyClient < AppRouter > ( {
13
+ links : [ chromeLink ( { port } ) ] ,
14
+ } )
15
+
16
+ const hello = await trpc . greeting . query ( { name : 'content script' } )
17
+ // eslint-disable-next-line no-console
18
+ console . log ( hello )
19
+ } ,
20
+
21
+ matches : [ 'https://example.com/' ] ,
22
+ } )
Original file line number Diff line number Diff line change
1
+ import type { AppRouter } from '@/entrypoints/background'
2
+
3
+ import { createTRPCReact } from '@trpc/react-query'
4
+
5
+ const trpcReact = createTRPCReact < AppRouter > ( )
6
+
7
+ function App ( ) {
8
+ const { data : hello } = trpcReact . greeting . useQuery ( { name : 'tRPC' } )
9
+ trpcReact . onGreeting . useSubscription ( undefined , {
10
+ onData : ( hello ) => {
11
+ // eslint-disable-next-line no-console
12
+ console . log ( hello )
13
+ } ,
14
+ } )
15
+
16
+ if ( ! hello ) {
17
+ return null
18
+ }
19
+
20
+ return (
21
+ < div data-testid = "greeting" >
22
+ { hello }
23
+ </ div >
24
+ )
25
+ }
26
+
27
+ export default App
Original file line number Diff line number Diff line change
1
+ <!doctype html>
2
+ < html lang ="en ">
3
+ < head >
4
+ < meta charset ="UTF-8 " />
5
+ < meta name ="viewport " content ="width=device-width, initial-scale=1.0 " />
6
+ < title > Default Popup Title</ title >
7
+ < meta name ="manifest.type " content ="browser_action " />
8
+ </ head >
9
+ < body >
10
+ < div id ="root "> </ div >
11
+ < script type ="module " src ="./main.tsx "> </ script >
12
+ </ body >
13
+ </ html >
Original file line number Diff line number Diff line change
1
+ import type { AppRouter } from '@/entrypoints/background'
2
+
3
+ import '@/entrypoints/style.css'
4
+ import { QueryClient , QueryClientProvider } from '@tanstack/react-query'
5
+ import { createTRPCReact } from '@trpc/react-query'
6
+ import React , { useState } from 'react'
7
+ import ReactDOM from 'react-dom/client'
8
+ import { chromeLink } from 'trpc-chrome/link'
9
+
10
+ import App from './App.tsx'
11
+
12
+ const port = browser . runtime . connect ( ) as chrome . runtime . Port
13
+
14
+ const trpcReact = createTRPCReact < AppRouter > ( )
15
+
16
+ function Root ( ) {
17
+ const [ queryClient ] = useState ( ( ) => new QueryClient ( ) )
18
+ const [ trpcClient ] = useState ( ( ) =>
19
+ trpcReact . createClient ( {
20
+ links : [ chromeLink ( { port } ) ] ,
21
+ } ) ,
22
+ )
23
+ return (
24
+ < trpcReact . Provider client = { trpcClient } queryClient = { queryClient } >
25
+ < QueryClientProvider client = { queryClient } >
26
+ < App />
27
+ </ QueryClientProvider >
28
+ </ trpcReact . Provider >
29
+ )
30
+ }
31
+
32
+ ReactDOM . createRoot ( document . getElementById ( 'root' ) ! ) . render (
33
+ < React . StrictMode >
34
+ < Root />
35
+ </ React . StrictMode > ,
36
+ )
You can’t perform that action at this time.
0 commit comments