@orpc/react 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/dist/index.js +635 -0
  2. package/dist/src/general-hooks.d.ts +24 -0
  3. package/dist/src/general-hooks.d.ts.map +1 -0
  4. package/dist/src/general-utils.d.ts +41 -0
  5. package/dist/src/general-utils.d.ts.map +1 -0
  6. package/dist/src/index.d.ts +9 -0
  7. package/dist/src/index.d.ts.map +1 -0
  8. package/dist/src/orpc-path.d.ts +5 -0
  9. package/dist/src/orpc-path.d.ts.map +1 -0
  10. package/dist/src/procedure-hooks.d.ts +31 -0
  11. package/dist/src/procedure-hooks.d.ts.map +1 -0
  12. package/dist/src/procedure-utils.d.ts +35 -0
  13. package/dist/src/procedure-utils.d.ts.map +1 -0
  14. package/dist/src/react-context.d.ts +13 -0
  15. package/dist/src/react-context.d.ts.map +1 -0
  16. package/dist/src/react-hooks.d.ts +22 -0
  17. package/dist/src/react-hooks.d.ts.map +1 -0
  18. package/dist/src/react-utils.d.ts +22 -0
  19. package/dist/src/react-utils.d.ts.map +1 -0
  20. package/dist/src/react.d.ts +21 -0
  21. package/dist/src/react.d.ts.map +1 -0
  22. package/dist/src/tanstack-key.d.ts +15 -0
  23. package/dist/src/tanstack-key.d.ts.map +1 -0
  24. package/dist/src/tanstack-query.d.ts +19 -0
  25. package/dist/src/tanstack-query.d.ts.map +1 -0
  26. package/dist/src/types.d.ts +5 -0
  27. package/dist/src/types.d.ts.map +1 -0
  28. package/dist/src/use-queries/builder.d.ts +20 -0
  29. package/dist/src/use-queries/builder.d.ts.map +1 -0
  30. package/dist/src/use-queries/builders.d.ts +19 -0
  31. package/dist/src/use-queries/builders.d.ts.map +1 -0
  32. package/dist/src/use-queries/hook.d.ts +16 -0
  33. package/dist/src/use-queries/hook.d.ts.map +1 -0
  34. package/dist/tsconfig.tsbuildinfo +1 -0
  35. package/package.json +56 -0
  36. package/src/general-hooks.test-d.ts +151 -0
  37. package/src/general-hooks.test.tsx +232 -0
  38. package/src/general-hooks.ts +100 -0
  39. package/src/general-utils.test-d.ts +454 -0
  40. package/src/general-utils.test.tsx +818 -0
  41. package/src/general-utils.ts +397 -0
  42. package/src/index.ts +8 -0
  43. package/src/orpc-path.test-d.ts +13 -0
  44. package/src/orpc-path.test.ts +12 -0
  45. package/src/orpc-path.ts +24 -0
  46. package/src/procedure-hooks.test-d.ts +321 -0
  47. package/src/procedure-hooks.test.tsx +388 -0
  48. package/src/procedure-hooks.ts +271 -0
  49. package/src/procedure-utils.test-d.ts +476 -0
  50. package/src/procedure-utils.test.tsx +330 -0
  51. package/src/procedure-utils.ts +315 -0
  52. package/src/react-context.ts +43 -0
  53. package/src/react-hooks.ts +102 -0
  54. package/src/react-utils.ts +110 -0
  55. package/src/react.test-d.ts +89 -0
  56. package/src/react.test.tsx +102 -0
  57. package/src/react.tsx +80 -0
  58. package/src/tanstack-key.test-d.ts +35 -0
  59. package/src/tanstack-key.test.ts +62 -0
  60. package/src/tanstack-key.ts +64 -0
  61. package/src/tanstack-query.ts +27 -0
  62. package/src/types.ts +7 -0
  63. package/src/use-queries/builder.test-d.ts +29 -0
  64. package/src/use-queries/builder.test.ts +25 -0
  65. package/src/use-queries/builder.ts +72 -0
  66. package/src/use-queries/builders.test-d.ts +30 -0
  67. package/src/use-queries/builders.test.tsx +29 -0
  68. package/src/use-queries/builders.ts +101 -0
  69. package/src/use-queries/hook.test-d.ts +64 -0
  70. package/src/use-queries/hook.test.tsx +89 -0
  71. package/src/use-queries/hook.ts +57 -0
@@ -0,0 +1,330 @@
1
+ import { orpcClient, queryClient } from '../tests/orpc'
2
+ import { createProcedureUtils } from './procedure-utils'
3
+
4
+ beforeEach(() => {
5
+ queryClient.clear()
6
+ })
7
+
8
+ describe('fetchQuery', () => {
9
+ const utils = createProcedureUtils({
10
+ client: orpcClient.user.find,
11
+ path: ['user', 'find'],
12
+ queryClient: queryClient,
13
+ })
14
+
15
+ it('on success', async () => {
16
+ const data = await utils.fetchQuery({ id: '123455' })
17
+
18
+ expect(data.id).toEqual('123455')
19
+
20
+ expect(
21
+ queryClient.getQueriesData({
22
+ exact: true,
23
+ queryKey: [
24
+ ['user', 'find'],
25
+ { input: { id: '123455' }, type: 'query' },
26
+ ],
27
+ })[0]?.[1],
28
+ ).toBe(data)
29
+ })
30
+
31
+ it('on error', () => {
32
+ // @ts-expect-error invalid input
33
+ expect(utils.fetchQuery({ id: {} })).rejects.toThrowError(
34
+ 'Validation input failed',
35
+ )
36
+ })
37
+ })
38
+
39
+ describe('fetchInfiniteQuery', () => {
40
+ const utils = createProcedureUtils({
41
+ client: orpcClient.user.list,
42
+ path: ['user', 'list'],
43
+ queryClient: queryClient,
44
+ })
45
+
46
+ it('on success', async () => {
47
+ const data = await utils.fetchInfiniteQuery({ input: {} })
48
+
49
+ expect(data).toMatchObject({
50
+ pageParams: [undefined],
51
+ pages: [
52
+ {
53
+ nextCursor: 2,
54
+ users: [{ name: 'number-0' }, { name: 'number-1' }],
55
+ },
56
+ ],
57
+ })
58
+
59
+ expect(
60
+ queryClient.getQueriesData({
61
+ exact: true,
62
+ queryKey: [['user', 'list'], { input: {}, type: 'infinite' }],
63
+ })[0]?.[1],
64
+ ).toBe(data)
65
+ })
66
+
67
+ it('on error', () => {
68
+ expect(
69
+ // @ts-expect-error invalid input
70
+ utils.fetchInfiniteQuery({ input: { keyword: {} } }),
71
+ ).rejects.toThrowError('Validation input failed')
72
+ })
73
+ })
74
+
75
+ describe('prefetchQuery', () => {
76
+ const utils = createProcedureUtils({
77
+ client: orpcClient.user.find,
78
+ path: ['user', 'find'],
79
+ queryClient: queryClient,
80
+ })
81
+
82
+ it('on success', async () => {
83
+ const result = await utils.prefetchQuery({ id: '123455' })
84
+ expect(result).toEqual(undefined)
85
+
86
+ expect(
87
+ queryClient.getQueriesData({
88
+ exact: true,
89
+ queryKey: [
90
+ ['user', 'find'],
91
+ { input: { id: '123455' }, type: 'query' },
92
+ ],
93
+ })[0]?.[1],
94
+ ).toEqual({
95
+ id: '123455',
96
+ name: 'name-123455',
97
+ })
98
+ })
99
+
100
+ it('on error', () => {
101
+ expect(
102
+ // @ts-expect-error invalid input
103
+ utils.prefetchQuery({ id: 1244 }),
104
+ ).resolves.toEqual(undefined)
105
+ })
106
+ })
107
+
108
+ describe('prefetchInfiniteQuery', () => {
109
+ const utils = createProcedureUtils({
110
+ client: orpcClient.user.list,
111
+ path: ['user', 'list'],
112
+ queryClient: queryClient,
113
+ })
114
+
115
+ it('on success', async () => {
116
+ const result = await utils.prefetchInfiniteQuery({ input: {} })
117
+ expect(result).toEqual(undefined)
118
+
119
+ expect(
120
+ queryClient.getQueriesData({
121
+ exact: true,
122
+ queryKey: [['user', 'list'], { input: {}, type: 'infinite' }],
123
+ })[0]?.[1],
124
+ ).toMatchObject({
125
+ pageParams: [undefined],
126
+ pages: [
127
+ {
128
+ nextCursor: 2,
129
+ users: [{ name: 'number-0' }, { name: 'number-1' }],
130
+ },
131
+ ],
132
+ })
133
+ })
134
+
135
+ it('on error', () => {
136
+ expect(
137
+ // @ts-expect-error invalid input
138
+ utils.prefetchInfiniteQuery({ keyword: 1222 }, {}),
139
+ ).resolves.toEqual(undefined)
140
+ })
141
+ })
142
+
143
+ describe('ensureQueryData', () => {
144
+ const utils = createProcedureUtils({
145
+ client: orpcClient.user.find,
146
+ path: ['user', 'find'],
147
+ queryClient: queryClient,
148
+ })
149
+
150
+ it('on success', async () => {
151
+ const data = await utils.ensureQueryData({ id: '123455' })
152
+
153
+ expect(data.id).toEqual('123455')
154
+
155
+ expect(
156
+ queryClient.getQueriesData({
157
+ exact: true,
158
+ queryKey: [
159
+ ['user', 'find'],
160
+ { input: { id: '123455' }, type: 'query' },
161
+ ],
162
+ })[0]?.[1],
163
+ ).toBe(data)
164
+ })
165
+
166
+ it('on error', () => {
167
+ // @ts-expect-error invalid input
168
+ expect(utils.ensureQueryData({ id: {} })).rejects.toThrowError(
169
+ 'Validation input failed',
170
+ )
171
+ })
172
+ })
173
+
174
+ describe('ensureInfiniteQuery', () => {
175
+ const utils = createProcedureUtils({
176
+ client: orpcClient.user.list,
177
+ path: ['user', 'list'],
178
+ queryClient: queryClient,
179
+ })
180
+
181
+ it('on success', async () => {
182
+ const data = await utils.ensureInfiniteQueryData({ input: {} })
183
+
184
+ expect(data).toMatchObject({
185
+ pageParams: [undefined],
186
+ pages: [
187
+ {
188
+ nextCursor: 2,
189
+ users: [{ name: 'number-0' }, { name: 'number-1' }],
190
+ },
191
+ ],
192
+ })
193
+
194
+ expect(
195
+ queryClient.getQueriesData({
196
+ exact: true,
197
+ queryKey: [['user', 'list'], { input: {}, type: 'infinite' }],
198
+ })[0]?.[1],
199
+ ).toBe(data)
200
+ })
201
+
202
+ it('on error', () => {
203
+ expect(
204
+ // @ts-expect-error invalid input
205
+ utils.ensureInfiniteQueryData({ input: { keyword: {} } }),
206
+ ).rejects.toThrowError('Validation input failed')
207
+ })
208
+ })
209
+
210
+ describe('getQueryData', () => {
211
+ const utils = createProcedureUtils({
212
+ client: orpcClient.user.find,
213
+ path: ['user', 'find'],
214
+ queryClient: queryClient,
215
+ })
216
+
217
+ it('on success', async () => {
218
+ expect(utils.getQueryData({ id: '123455' })).toEqual(undefined)
219
+ const data = await utils.ensureQueryData({ id: '123455' })
220
+ expect(utils.getQueryData({ id: '123455' })).toBe(data)
221
+ })
222
+ })
223
+
224
+ describe('getInfiniteQueryData', () => {
225
+ const utils = createProcedureUtils({
226
+ client: orpcClient.user.list,
227
+ path: ['user', 'list'],
228
+ queryClient: queryClient,
229
+ })
230
+
231
+ it('on success', async () => {
232
+ expect(utils.getInfiniteQueryData({})).toEqual(undefined)
233
+ const data = await utils.ensureInfiniteQueryData({ input: {} })
234
+ expect(utils.getInfiniteQueryData({})).toBe(data)
235
+ })
236
+ })
237
+
238
+ describe('getQueryState', () => {
239
+ const utils = createProcedureUtils({
240
+ client: orpcClient.user.find,
241
+ path: ['user', 'find'],
242
+ queryClient: queryClient,
243
+ })
244
+
245
+ it('on success', async () => {
246
+ expect(utils.getQueryState({ id: '123455' })).toEqual(undefined)
247
+ const data = await utils.ensureQueryData({ id: '123455' })
248
+ expect(utils.getQueryState({ id: '123455' })).toMatchObject({
249
+ status: 'success',
250
+ data,
251
+ })
252
+ })
253
+ })
254
+
255
+ describe('getInfiniteQueryState', () => {
256
+ const utils = createProcedureUtils({
257
+ client: orpcClient.user.list,
258
+ path: ['user', 'list'],
259
+ queryClient: queryClient,
260
+ })
261
+
262
+ it('on success', async () => {
263
+ expect(utils.getInfiniteQueryState({})).toEqual(undefined)
264
+ const data = await utils.ensureInfiniteQueryData({ input: {} })
265
+ expect(utils.getInfiniteQueryState({})).toMatchObject({
266
+ status: 'success',
267
+ data,
268
+ })
269
+ })
270
+ })
271
+
272
+ describe('setQueryData', () => {
273
+ const utils = createProcedureUtils({
274
+ client: orpcClient.user.find,
275
+ path: ['user', 'find'],
276
+ queryClient: queryClient,
277
+ })
278
+
279
+ it('on success', async () => {
280
+ const original = await utils.ensureQueryData({ id: '1222' })
281
+
282
+ const user = {
283
+ id: '1222',
284
+ name: 'name-1222-fake-fake',
285
+ }
286
+
287
+ utils.setQueryData({ id: user.id }, (data) => {
288
+ expect(data).toBe(original)
289
+
290
+ return user
291
+ })
292
+
293
+ expect(
294
+ queryClient.getQueriesData({
295
+ exact: true,
296
+ queryKey: [['user', 'find'], { input: { id: user.id }, type: 'query' }],
297
+ })[0]?.[1],
298
+ ).toEqual(user)
299
+ })
300
+ })
301
+
302
+ describe('getInfiniteQueryData', () => {
303
+ const utils = createProcedureUtils({
304
+ client: orpcClient.user.list,
305
+ path: ['user', 'list'],
306
+ queryClient: queryClient,
307
+ })
308
+
309
+ it('on success', async () => {
310
+ const original = await utils.ensureInfiniteQueryData({ input: {} })
311
+
312
+ const data = {
313
+ pages: [],
314
+ pageParams: [],
315
+ }
316
+
317
+ utils.setInfiniteQueryData({}, (ori) => {
318
+ expect(ori).toBe(original)
319
+
320
+ return data
321
+ })
322
+
323
+ expect(
324
+ queryClient.getQueriesData({
325
+ exact: true,
326
+ queryKey: [['user', 'list'], { input: {}, type: 'infinite' }],
327
+ })[0]?.[1],
328
+ ).toEqual(data)
329
+ })
330
+ })
@@ -0,0 +1,315 @@
1
+ import type { ProcedureClient } from '@orpc/client'
2
+ import type { Schema, SchemaInput, SchemaOutput } from '@orpc/contract'
3
+ import type { PartialOnUndefinedDeep, SetOptional } from '@orpc/shared'
4
+ import type {
5
+ DefaultError,
6
+ EnsureInfiniteQueryDataOptions,
7
+ EnsureQueryDataOptions,
8
+ FetchInfiniteQueryOptions,
9
+ FetchQueryOptions,
10
+ InfiniteData,
11
+ QueryClient,
12
+ QueryKey,
13
+ QueryState,
14
+ SetDataOptions,
15
+ Updater,
16
+ } from '@tanstack/react-query'
17
+ import { getQueryKeyFromPath } from './tanstack-key'
18
+ import type { SchemaInputForInfiniteQuery } from './types'
19
+
20
+ export interface ProcedureUtils<
21
+ TInputSchema extends Schema,
22
+ TOutputSchema extends Schema,
23
+ THandlerOutput extends SchemaOutput<TOutputSchema>,
24
+ > {
25
+ fetchQuery(
26
+ input: SchemaInput<TInputSchema>,
27
+ options?: SetOptional<
28
+ FetchQueryOptions<SchemaOutput<TOutputSchema, THandlerOutput>>,
29
+ 'queryKey' | 'queryFn'
30
+ >,
31
+ ): Promise<SchemaOutput<TOutputSchema, THandlerOutput>>
32
+ fetchInfiniteQuery(
33
+ options: PartialOnUndefinedDeep<
34
+ SetOptional<
35
+ FetchInfiniteQueryOptions<
36
+ SchemaOutput<TOutputSchema, THandlerOutput>,
37
+ DefaultError,
38
+ SchemaOutput<TOutputSchema, THandlerOutput>,
39
+ QueryKey,
40
+ SchemaInput<TInputSchema>['cursor']
41
+ >,
42
+ 'queryKey' | 'queryFn'
43
+ > & {
44
+ input: SchemaInputForInfiniteQuery<TInputSchema>
45
+ }
46
+ >,
47
+ ): Promise<
48
+ InfiniteData<
49
+ SchemaOutput<TOutputSchema, THandlerOutput>,
50
+ SchemaInput<TInputSchema>['cursor']
51
+ >
52
+ >
53
+
54
+ prefetchQuery(
55
+ input: SchemaInput<TInputSchema>,
56
+ options?: SetOptional<
57
+ FetchQueryOptions<SchemaOutput<TOutputSchema, THandlerOutput>>,
58
+ 'queryKey' | 'queryFn'
59
+ >,
60
+ ): Promise<void>
61
+ prefetchInfiniteQuery(
62
+ options: PartialOnUndefinedDeep<
63
+ SetOptional<
64
+ FetchInfiniteQueryOptions<
65
+ SchemaOutput<TOutputSchema, THandlerOutput>,
66
+ DefaultError,
67
+ SchemaOutput<TOutputSchema, THandlerOutput>,
68
+ QueryKey,
69
+ SchemaInput<TInputSchema>['cursor']
70
+ >,
71
+ 'queryKey' | 'queryFn'
72
+ > & {
73
+ input: SchemaInputForInfiniteQuery<TInputSchema>
74
+ }
75
+ >,
76
+ ): Promise<void>
77
+
78
+ getQueryData(
79
+ input: SchemaInput<TInputSchema>,
80
+ ): SchemaOutput<TOutputSchema, THandlerOutput> | undefined
81
+ getInfiniteQueryData(
82
+ input: SchemaInputForInfiniteQuery<TInputSchema>,
83
+ ):
84
+ | InfiniteData<
85
+ SchemaOutput<TOutputSchema, THandlerOutput>,
86
+ SchemaInput<TInputSchema>['cursor']
87
+ >
88
+ | undefined
89
+
90
+ ensureQueryData(
91
+ input: SchemaInput<TInputSchema>,
92
+ options?: SetOptional<
93
+ EnsureQueryDataOptions<SchemaOutput<TOutputSchema, THandlerOutput>>,
94
+ 'queryFn' | 'queryKey'
95
+ >,
96
+ ): Promise<SchemaOutput<TOutputSchema, THandlerOutput>>
97
+ ensureInfiniteQueryData(
98
+ options: PartialOnUndefinedDeep<
99
+ SetOptional<
100
+ EnsureInfiniteQueryDataOptions<
101
+ SchemaOutput<TOutputSchema, THandlerOutput>,
102
+ DefaultError,
103
+ SchemaOutput<TOutputSchema, THandlerOutput>,
104
+ QueryKey,
105
+ SchemaInput<TInputSchema>['cursor']
106
+ >,
107
+ 'queryKey' | 'queryFn'
108
+ > & {
109
+ input: SchemaInputForInfiniteQuery<TInputSchema>
110
+ }
111
+ >,
112
+ ): Promise<
113
+ InfiniteData<
114
+ SchemaOutput<TOutputSchema, THandlerOutput>,
115
+ SchemaInput<TInputSchema>['cursor']
116
+ >
117
+ >
118
+
119
+ getQueryState(
120
+ input: SchemaInput<TInputSchema>,
121
+ ): QueryState<SchemaOutput<TOutputSchema, THandlerOutput>> | undefined
122
+ getInfiniteQueryState(
123
+ input: SchemaInputForInfiniteQuery<TInputSchema>,
124
+ ):
125
+ | QueryState<
126
+ InfiniteData<
127
+ SchemaOutput<TOutputSchema, THandlerOutput>,
128
+ SchemaInput<TInputSchema>['cursor']
129
+ >
130
+ >
131
+ | undefined
132
+
133
+ setQueryData(
134
+ input: SchemaInput<TInputSchema>,
135
+ updater: Updater<
136
+ SchemaOutput<TOutputSchema, THandlerOutput> | undefined,
137
+ SchemaOutput<TOutputSchema, THandlerOutput> | undefined
138
+ >,
139
+ options?: SetDataOptions,
140
+ ): SchemaOutput<TOutputSchema, THandlerOutput> | undefined
141
+ setInfiniteQueryData(
142
+ input: SchemaInputForInfiniteQuery<TInputSchema>,
143
+ updater: Updater<
144
+ | InfiniteData<
145
+ SchemaOutput<TOutputSchema, THandlerOutput>,
146
+ SchemaInput<TInputSchema>['cursor']
147
+ >
148
+ | undefined,
149
+ | InfiniteData<
150
+ SchemaOutput<TOutputSchema, THandlerOutput>,
151
+ SchemaInput<TInputSchema>['cursor']
152
+ >
153
+ | undefined
154
+ >,
155
+ options?: SetDataOptions,
156
+ ):
157
+ | InfiniteData<
158
+ SchemaOutput<TOutputSchema, THandlerOutput>,
159
+ SchemaInput<TInputSchema>['cursor']
160
+ >
161
+ | undefined
162
+ }
163
+
164
+ export interface CreateProcedureUtilsOptions<
165
+ TInputSchema extends Schema = undefined,
166
+ TOutputSchema extends Schema = undefined,
167
+ THandlerOutput extends
168
+ SchemaOutput<TOutputSchema> = SchemaOutput<TOutputSchema>,
169
+ > {
170
+ client: ProcedureClient<TInputSchema, TOutputSchema, THandlerOutput>
171
+ queryClient: QueryClient
172
+
173
+ /**
174
+ * The path of procedure on sever
175
+ */
176
+ path: string[]
177
+ }
178
+
179
+ export function createProcedureUtils<
180
+ TInputSchema extends Schema,
181
+ TOutputSchema extends Schema,
182
+ THandlerOutput extends SchemaOutput<TOutputSchema>,
183
+ >(
184
+ options: CreateProcedureUtilsOptions<
185
+ TInputSchema,
186
+ TOutputSchema,
187
+ THandlerOutput
188
+ >,
189
+ ): ProcedureUtils<TInputSchema, TOutputSchema, THandlerOutput> {
190
+ return {
191
+ fetchQuery(input, options_) {
192
+ return options.queryClient.fetchQuery({
193
+ queryKey: getQueryKeyFromPath(options.path, { input, type: 'query' }),
194
+ queryFn: () => options.client(input),
195
+ ...options_,
196
+ })
197
+ },
198
+ fetchInfiniteQuery(options_) {
199
+ const { input, ...rest } = options_
200
+ return options.queryClient.fetchInfiniteQuery({
201
+ queryKey: getQueryKeyFromPath(options.path, {
202
+ input,
203
+ type: 'infinite',
204
+ }),
205
+ queryFn: ({ pageParam }) => {
206
+ return options.client({ ...(input as any), pageParam } as any)
207
+ },
208
+ ...(rest as any),
209
+ })
210
+ },
211
+
212
+ prefetchQuery(input, options_) {
213
+ return options.queryClient.prefetchQuery({
214
+ queryKey: getQueryKeyFromPath(options.path, {
215
+ input,
216
+ type: 'query',
217
+ }),
218
+ queryFn: () => options.client(input),
219
+ ...options_,
220
+ })
221
+ },
222
+ prefetchInfiniteQuery(options_) {
223
+ const { input, ...rest } = options_
224
+ return options.queryClient.prefetchInfiniteQuery({
225
+ queryKey: getQueryKeyFromPath(options.path, {
226
+ input,
227
+ type: 'infinite',
228
+ }),
229
+ queryFn: ({ pageParam }) => {
230
+ return options.client({ ...(input as any), cursor: pageParam } as any)
231
+ },
232
+ ...(rest as any),
233
+ })
234
+ },
235
+
236
+ getQueryData(input) {
237
+ return options.queryClient.getQueryData(
238
+ getQueryKeyFromPath(options.path, {
239
+ input,
240
+ type: 'query',
241
+ }),
242
+ )
243
+ },
244
+ getInfiniteQueryData(input) {
245
+ return options.queryClient.getQueryData(
246
+ getQueryKeyFromPath(options.path, {
247
+ input,
248
+ type: 'infinite',
249
+ }),
250
+ )
251
+ },
252
+
253
+ ensureQueryData(input, options_) {
254
+ return options.queryClient.ensureQueryData({
255
+ queryKey: getQueryKeyFromPath(options.path, {
256
+ input,
257
+ type: 'query',
258
+ }),
259
+ queryFn: () => options.client(input),
260
+ ...options_,
261
+ })
262
+ },
263
+ ensureInfiniteQueryData(options_) {
264
+ const { input, ...rest } = options_
265
+ return options.queryClient.ensureInfiniteQueryData({
266
+ queryKey: getQueryKeyFromPath(options.path, {
267
+ input,
268
+ type: 'infinite',
269
+ }),
270
+ queryFn: ({ pageParam }) => {
271
+ return options.client({ ...(input as any), pageParam } as any)
272
+ },
273
+ ...(rest as any),
274
+ })
275
+ },
276
+
277
+ getQueryState(input) {
278
+ return options.queryClient.getQueryState(
279
+ getQueryKeyFromPath(options.path, {
280
+ input,
281
+ type: 'query',
282
+ }),
283
+ )
284
+ },
285
+ getInfiniteQueryState(input) {
286
+ return options.queryClient.getQueryState(
287
+ getQueryKeyFromPath(options.path, {
288
+ input,
289
+ type: 'infinite',
290
+ }),
291
+ )
292
+ },
293
+
294
+ setQueryData(input, updater, options_) {
295
+ return options.queryClient.setQueryData(
296
+ getQueryKeyFromPath(options.path, {
297
+ input,
298
+ type: 'query',
299
+ }),
300
+ updater,
301
+ options_,
302
+ )
303
+ },
304
+ setInfiniteQueryData(input, updater, options_) {
305
+ return options.queryClient.setQueryData(
306
+ getQueryKeyFromPath(options.path, {
307
+ input,
308
+ type: 'infinite',
309
+ }),
310
+ updater,
311
+ options_,
312
+ )
313
+ },
314
+ }
315
+ }
@@ -0,0 +1,43 @@
1
+ import type {
2
+ RouterClientWithContractRouter,
3
+ RouterClientWithRouter,
4
+ } from '@orpc/client'
5
+ import type { ContractRouter } from '@orpc/contract'
6
+ import type { Router } from '@orpc/server'
7
+ import type { QueryClient } from '@tanstack/react-query'
8
+ import { type Context, createContext, useContext } from 'react'
9
+
10
+ export interface ORPCContextValue<
11
+ TRouter extends ContractRouter | Router<any>,
12
+ > {
13
+ client: TRouter extends ContractRouter
14
+ ? RouterClientWithContractRouter<TRouter>
15
+ : TRouter extends Router<any>
16
+ ? RouterClientWithRouter<TRouter>
17
+ : never
18
+ queryClient: QueryClient
19
+ }
20
+
21
+ export type ORPCContext<TRouter extends ContractRouter | Router<any>> = Context<
22
+ ORPCContextValue<TRouter> | undefined
23
+ >
24
+
25
+ export function createORPCContext<
26
+ TRouter extends ContractRouter | Router<any>,
27
+ >(): ORPCContext<TRouter> {
28
+ return createContext(undefined as any)
29
+ }
30
+
31
+ export function useORPCContext<TRouter extends ContractRouter | Router<any>>(
32
+ context: ORPCContext<TRouter>,
33
+ ): ORPCContextValue<TRouter> {
34
+ const value = useContext(context)
35
+
36
+ if (!value) {
37
+ throw new Error(
38
+ 'useORPCContext must be used within a <ORPCContext.Provider>, please see the docs',
39
+ )
40
+ }
41
+
42
+ return value
43
+ }