@navios/react-query 0.7.1 → 1.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.
- package/CHANGELOG.md +171 -1
- package/README.md +152 -4
- package/coverage/base.css +224 -0
- package/coverage/block-navigation.js +87 -0
- package/coverage/client/declare-client.mts.html +1264 -0
- package/coverage/client/index.html +116 -0
- package/coverage/clover.xml +160 -0
- package/coverage/coverage-final.json +8 -0
- package/coverage/favicon.png +0 -0
- package/coverage/index.html +146 -0
- package/coverage/mutation/index.html +131 -0
- package/coverage/mutation/key-creator.mts.html +277 -0
- package/coverage/mutation/make-hook.mts.html +952 -0
- package/coverage/prettify.css +1 -0
- package/coverage/prettify.js +2 -0
- package/coverage/query/index.html +161 -0
- package/coverage/query/key-creator.mts.html +415 -0
- package/coverage/query/make-infinite-options.mts.html +601 -0
- package/coverage/query/make-options.mts.html +838 -0
- package/coverage/query/prefetch.mts.html +1063 -0
- package/coverage/sort-arrow-sprite.png +0 -0
- package/coverage/sorter.js +210 -0
- package/dist/src/__tests__/errorSchema.spec.d.mts +2 -0
- package/dist/src/__tests__/errorSchema.spec.d.mts.map +1 -0
- package/dist/src/__tests__/prefetch.spec.d.mts +2 -0
- package/dist/src/__tests__/prefetch.spec.d.mts.map +1 -0
- package/dist/src/client/__type-tests__/from-endpoint.spec-d.d.mts +2 -0
- package/dist/src/client/__type-tests__/from-endpoint.spec-d.d.mts.map +1 -0
- package/dist/src/client/__type-tests__/infinite-query.spec-d.d.mts +2 -0
- package/dist/src/client/__type-tests__/infinite-query.spec-d.d.mts.map +1 -0
- package/dist/src/client/__type-tests__/multipart-mutation.spec-d.d.mts +2 -0
- package/dist/src/client/__type-tests__/multipart-mutation.spec-d.d.mts.map +1 -0
- package/dist/src/client/__type-tests__/mutation.spec-d.d.mts +2 -0
- package/dist/src/client/__type-tests__/mutation.spec-d.d.mts.map +1 -0
- package/dist/src/client/__type-tests__/query.spec-d.d.mts +2 -0
- package/dist/src/client/__type-tests__/query.spec-d.d.mts.map +1 -0
- package/dist/src/client/declare-client.d.mts +15 -8
- package/dist/src/client/declare-client.d.mts.map +1 -1
- package/dist/src/client/types/from-endpoint.d.mts +130 -0
- package/dist/src/client/types/from-endpoint.d.mts.map +1 -0
- package/dist/src/client/types/helpers.d.mts +74 -0
- package/dist/src/client/types/helpers.d.mts.map +1 -0
- package/dist/src/client/types/index.d.mts +21 -0
- package/dist/src/client/types/index.d.mts.map +1 -0
- package/dist/src/client/types/infinite-query.d.mts +61 -0
- package/dist/src/client/types/infinite-query.d.mts.map +1 -0
- package/dist/src/client/types/multipart-mutation.d.mts +98 -0
- package/dist/src/client/types/multipart-mutation.d.mts.map +1 -0
- package/dist/src/client/types/mutation.d.mts +75 -0
- package/dist/src/client/types/mutation.d.mts.map +1 -0
- package/dist/src/client/types/query.d.mts +65 -0
- package/dist/src/client/types/query.d.mts.map +1 -0
- package/dist/src/client/types.d.mts +1 -608
- package/dist/src/client/types.d.mts.map +1 -1
- package/dist/src/common/types.d.mts +40 -3
- package/dist/src/common/types.d.mts.map +1 -1
- package/dist/src/mutation/index.d.mts +1 -0
- package/dist/src/mutation/index.d.mts.map +1 -1
- package/dist/src/mutation/make-hook.d.mts +42 -16
- package/dist/src/mutation/make-hook.d.mts.map +1 -1
- package/dist/src/mutation/optimistic.d.mts +172 -0
- package/dist/src/mutation/optimistic.d.mts.map +1 -0
- package/dist/src/mutation/types.d.mts +41 -20
- package/dist/src/mutation/types.d.mts.map +1 -1
- package/dist/src/query/index.d.mts +1 -0
- package/dist/src/query/index.d.mts.map +1 -1
- package/dist/src/query/key-creator.d.mts.map +1 -1
- package/dist/src/query/make-infinite-options.d.mts +3 -2
- package/dist/src/query/make-infinite-options.d.mts.map +1 -1
- package/dist/src/query/make-options.d.mts +42 -12
- package/dist/src/query/make-options.d.mts.map +1 -1
- package/dist/src/query/prefetch.d.mts +245 -0
- package/dist/src/query/prefetch.d.mts.map +1 -0
- package/dist/src/query/types.d.mts +25 -18
- package/dist/src/query/types.d.mts.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/lib/index.cjs +451 -28
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.cts +1019 -600
- package/lib/index.d.cts.map +1 -1
- package/lib/index.d.mts +1016 -597
- package/lib/index.d.mts.map +1 -1
- package/lib/index.mjs +447 -29
- package/lib/index.mjs.map +1 -1
- package/package.json +3 -3
- package/src/__tests__/declare-client.spec.mts +229 -2
- package/src/__tests__/errorSchema.spec.mts +391 -0
- package/src/__tests__/make-mutation.spec.mts +6 -5
- package/src/__tests__/makeDataTag.spec.mts +2 -1
- package/src/__tests__/makeQueryOptions.spec.mts +2 -1
- package/src/__tests__/prefetch.spec.mts +310 -0
- package/src/client/__type-tests__/from-endpoint.spec-d.mts +550 -0
- package/src/client/__type-tests__/infinite-query.spec-d.mts +648 -0
- package/src/client/__type-tests__/multipart-mutation.spec-d.mts +725 -0
- package/src/client/__type-tests__/mutation.spec-d.mts +757 -0
- package/src/client/__type-tests__/query.spec-d.mts +701 -0
- package/src/client/declare-client.mts +59 -34
- package/src/client/types/from-endpoint.mts +344 -0
- package/src/client/types/helpers.mts +140 -0
- package/src/client/types/index.mts +26 -0
- package/src/client/types/infinite-query.mts +133 -0
- package/src/client/types/multipart-mutation.mts +264 -0
- package/src/client/types/mutation.mts +176 -0
- package/src/client/types/query.mts +132 -0
- package/src/client/types.mts +1 -1935
- package/src/common/types.mts +67 -3
- package/src/mutation/index.mts +1 -0
- package/src/mutation/make-hook.mts +171 -63
- package/src/mutation/optimistic.mts +300 -0
- package/src/mutation/types.mts +87 -30
- package/src/query/index.mts +1 -0
- package/src/query/key-creator.mts +24 -13
- package/src/query/make-infinite-options.mts +53 -10
- package/src/query/make-options.mts +184 -43
- package/src/query/prefetch.mts +326 -0
- package/src/query/types.mts +56 -17
- package/src/client/__type-tests__/client-instance.spec-d.mts +0 -852
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,176 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## [0.
|
|
3
|
+
## [1.0.0] - 2026-01-08
|
|
4
|
+
|
|
5
|
+
### Highlights
|
|
6
|
+
|
|
7
|
+
This is the first stable release of `@navios/react-query`. It includes major improvements to type safety, new helpers for common patterns like optimistic updates and SSR prefetching, and full support for discriminated union error handling.
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
|
|
11
|
+
- **Optimistic Update Helpers Marked Experimental**: `createOptimisticUpdate` and `createMultiOptimisticUpdate` are now marked as `@experimental`. These APIs may change in future versions - use manual optimistic update patterns for production code until these helpers stabilize.
|
|
12
|
+
|
|
13
|
+
## [1.0.0-alpha.1] - 2026-01-07
|
|
14
|
+
|
|
15
|
+
### Highlights
|
|
16
|
+
|
|
17
|
+
This was a pre-release version of `@navios/react-query`.
|
|
18
|
+
|
|
19
|
+
### Breaking Changes
|
|
20
|
+
|
|
21
|
+
- **Type file reorganization** - Client types have been split into modular files for better maintainability:
|
|
22
|
+
- `client/types.mts` → Split into `client/types/query.mts`, `client/types/mutation.mts`, `client/types/infinite-query.mts`, `client/types/multipart-mutation.mts`, `client/types/from-endpoint.mts`, and `client/types/helpers.mts`
|
|
23
|
+
- If you were importing internal types directly, update your imports to use the new paths or the re-exported types from the main entry point.
|
|
24
|
+
|
|
25
|
+
### Added
|
|
26
|
+
|
|
27
|
+
#### Error Schema Support (Discriminated Union Mode)
|
|
28
|
+
|
|
29
|
+
Full support for `errorSchema` in queries and mutations when using `useDiscriminatorResponse: true` mode. API error responses are now returned as data (not thrown) and can be discriminated by status code:
|
|
30
|
+
|
|
31
|
+
```typescript
|
|
32
|
+
const api = builder({ useDiscriminatorResponse: true })
|
|
33
|
+
|
|
34
|
+
const getUser = client.query({
|
|
35
|
+
method: 'GET',
|
|
36
|
+
url: '/users/$userId',
|
|
37
|
+
responseSchema: userSchema,
|
|
38
|
+
errorSchema: {
|
|
39
|
+
400: z.object({ error: z.string(), code: z.number() }),
|
|
40
|
+
404: z.object({ notFound: z.literal(true) }),
|
|
41
|
+
},
|
|
42
|
+
processResponse: (data) => {
|
|
43
|
+
// data is typed as: User | { error: string, code: number } | { notFound: true }
|
|
44
|
+
if ('error' in data) {
|
|
45
|
+
return { ok: false, error: data.error }
|
|
46
|
+
}
|
|
47
|
+
if ('notFound' in data) {
|
|
48
|
+
return { ok: false, error: 'User not found' }
|
|
49
|
+
}
|
|
50
|
+
return { ok: true, user: data }
|
|
51
|
+
},
|
|
52
|
+
})
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
#### SSR/RSC Prefetch Helpers
|
|
56
|
+
|
|
57
|
+
New `createPrefetchHelper` and `createPrefetchHelpers` utilities for server-side rendering and React Server Components:
|
|
58
|
+
|
|
59
|
+
```typescript
|
|
60
|
+
import { createPrefetchHelper, prefetchAll } from '@navios/react-query'
|
|
61
|
+
import { dehydrate, HydrationBoundary, QueryClient } from '@tanstack/react-query'
|
|
62
|
+
|
|
63
|
+
// Create prefetch helper from query
|
|
64
|
+
const userPrefetch = createPrefetchHelper(getUser)
|
|
65
|
+
|
|
66
|
+
// Server Component
|
|
67
|
+
async function UserPage({ userId }: { userId: string }) {
|
|
68
|
+
const queryClient = new QueryClient()
|
|
69
|
+
|
|
70
|
+
await userPrefetch.prefetch(queryClient, { urlParams: { userId } })
|
|
71
|
+
|
|
72
|
+
return (
|
|
73
|
+
<HydrationBoundary state={dehydrate(queryClient)}>
|
|
74
|
+
<UserProfile userId={userId} />
|
|
75
|
+
</HydrationBoundary>
|
|
76
|
+
)
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
**Prefetch helper methods:**
|
|
81
|
+
|
|
82
|
+
- `prefetch(queryClient, params)` - Prefetch data on the server
|
|
83
|
+
- `ensureData(queryClient, params)` - Ensure data exists, returns the data
|
|
84
|
+
- `getQueryOptions(params)` - Get raw query options for customization
|
|
85
|
+
- `prefetchMany(queryClient, paramsList)` - Prefetch multiple queries in parallel
|
|
86
|
+
|
|
87
|
+
**Batch prefetching:**
|
|
88
|
+
|
|
89
|
+
```typescript
|
|
90
|
+
// Create multiple prefetch helpers at once
|
|
91
|
+
const prefetchers = createPrefetchHelpers({
|
|
92
|
+
user: getUser,
|
|
93
|
+
posts: getUserPosts,
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
// Or use prefetchAll for different queries
|
|
97
|
+
await prefetchAll(queryClient, [
|
|
98
|
+
{ helper: userPrefetch, params: { urlParams: { userId } } },
|
|
99
|
+
{
|
|
100
|
+
helper: postsPrefetch,
|
|
101
|
+
params: { urlParams: { userId }, params: { limit: 10 } },
|
|
102
|
+
},
|
|
103
|
+
])
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
#### Optimistic Update Helpers
|
|
107
|
+
|
|
108
|
+
New `createOptimisticUpdate` and `createMultiOptimisticUpdate` utilities for type-safe optimistic updates:
|
|
109
|
+
|
|
110
|
+
```typescript
|
|
111
|
+
import {
|
|
112
|
+
createMultiOptimisticUpdate,
|
|
113
|
+
createOptimisticUpdate,
|
|
114
|
+
} from '@navios/react-query'
|
|
115
|
+
|
|
116
|
+
const updateUser = client.mutation({
|
|
117
|
+
method: 'PATCH',
|
|
118
|
+
url: '/users/$userId',
|
|
119
|
+
requestSchema: updateUserSchema,
|
|
120
|
+
responseSchema: userSchema,
|
|
121
|
+
processResponse: (data) => data,
|
|
122
|
+
useContext: () => ({ queryClient: useQueryClient() }),
|
|
123
|
+
...createOptimisticUpdate({
|
|
124
|
+
queryKey: ['users', userId],
|
|
125
|
+
updateFn: (oldData, variables) => ({
|
|
126
|
+
...oldData,
|
|
127
|
+
...variables.data,
|
|
128
|
+
}),
|
|
129
|
+
rollbackOnError: true, // default
|
|
130
|
+
invalidateOnSettled: true, // default
|
|
131
|
+
}),
|
|
132
|
+
})
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
**Multi-query optimistic updates:**
|
|
136
|
+
|
|
137
|
+
```typescript
|
|
138
|
+
const updateUser = client.mutation({
|
|
139
|
+
// ...
|
|
140
|
+
...createMultiOptimisticUpdate([
|
|
141
|
+
{
|
|
142
|
+
queryKey: ['users', userId],
|
|
143
|
+
updateFn: (oldData, variables) => ({ ...oldData, ...variables.data }),
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
queryKey: ['users'],
|
|
147
|
+
updateFn: (oldList, variables) =>
|
|
148
|
+
(oldList ?? []).map((u) =>
|
|
149
|
+
u.id === userId ? { ...u, ...variables.data } : u,
|
|
150
|
+
),
|
|
151
|
+
},
|
|
152
|
+
]),
|
|
153
|
+
})
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
#### New Type Exports
|
|
157
|
+
|
|
158
|
+
- `ComputeBaseResult<UseDiscriminator, Response, ErrorSchema>` - Compute result type based on discriminator mode
|
|
159
|
+
- `PrefetchHelper<TParams, TData, TError>` - Type for prefetch helper instances
|
|
160
|
+
- `QueryOptionsCreator<TParams, TData, TError>` - Type for query options creator functions
|
|
161
|
+
- `OptimisticUpdateConfig<TData, TVariables, TQueryData>` - Configuration for optimistic updates
|
|
162
|
+
- `OptimisticUpdateCallbacks<TData, TVariables, TQueryData>` - Return type from `createOptimisticUpdate`
|
|
163
|
+
|
|
164
|
+
### Changed
|
|
165
|
+
|
|
166
|
+
- **Improved type inference** - Better type inference for `processResponse` callbacks, especially when using `errorSchema`
|
|
167
|
+
- **Modular type definitions** - Client types are now organized into separate files by concern:
|
|
168
|
+
- `types/query.mts` - Query-related types
|
|
169
|
+
- `types/mutation.mts` - Mutation-related types
|
|
170
|
+
- `types/infinite-query.mts` - Infinite query types
|
|
171
|
+
- `types/multipart-mutation.mts` - Multipart mutation types
|
|
172
|
+
- `types/from-endpoint.mts` - Types for `*FromEndpoint` methods
|
|
173
|
+
- `types/helpers.mts` - Helper types like `EndpointHelper`, `StreamHelper`, `ComputeBaseResult`
|
|
4
174
|
|
|
5
175
|
### Fixed
|
|
6
176
|
|
package/README.md
CHANGED
|
@@ -9,7 +9,9 @@ Type-safe React Query integration for Navios API client with Zod schema validati
|
|
|
9
9
|
- **React Query Integration** - Seamless integration with TanStack Query v5
|
|
10
10
|
- **Declarative API** - Define endpoints once, use everywhere
|
|
11
11
|
- **URL Parameters** - Built-in support for parameterized URLs (`/users/$userId`)
|
|
12
|
-
- **Optimistic Updates** - First-class
|
|
12
|
+
- **Optimistic Updates** - First-class helpers via `createOptimisticUpdate`
|
|
13
|
+
- **SSR/RSC Support** - Built-in prefetch helpers for server-side rendering
|
|
14
|
+
- **Error Schema Support** - Type-safe error handling with discriminated unions
|
|
13
15
|
- **Stream Support** - Handle file downloads and blob responses
|
|
14
16
|
|
|
15
17
|
## Installation
|
|
@@ -514,6 +516,148 @@ function AvatarUpload({ userId }: { userId: string }) {
|
|
|
514
516
|
}
|
|
515
517
|
```
|
|
516
518
|
|
|
519
|
+
## SSR/RSC Prefetch Helpers
|
|
520
|
+
|
|
521
|
+
For server-side rendering and React Server Components, use the prefetch helpers:
|
|
522
|
+
|
|
523
|
+
```typescript
|
|
524
|
+
import { createPrefetchHelper, prefetchAll } from '@navios/react-query'
|
|
525
|
+
import { dehydrate, HydrationBoundary, QueryClient } from '@tanstack/react-query'
|
|
526
|
+
|
|
527
|
+
// Create prefetch helper from your query
|
|
528
|
+
const userPrefetch = createPrefetchHelper(getUser)
|
|
529
|
+
|
|
530
|
+
// Server Component
|
|
531
|
+
async function UserPage({ userId }: { userId: string }) {
|
|
532
|
+
const queryClient = new QueryClient()
|
|
533
|
+
|
|
534
|
+
await userPrefetch.prefetch(queryClient, { urlParams: { userId } })
|
|
535
|
+
|
|
536
|
+
return (
|
|
537
|
+
<HydrationBoundary state={dehydrate(queryClient)}>
|
|
538
|
+
<UserProfile userId={userId} />
|
|
539
|
+
</HydrationBoundary>
|
|
540
|
+
)
|
|
541
|
+
}
|
|
542
|
+
```
|
|
543
|
+
|
|
544
|
+
### Batch Prefetching
|
|
545
|
+
|
|
546
|
+
```typescript
|
|
547
|
+
// Create multiple helpers at once
|
|
548
|
+
const prefetchers = createPrefetchHelpers({
|
|
549
|
+
user: getUser,
|
|
550
|
+
posts: getUserPosts,
|
|
551
|
+
})
|
|
552
|
+
|
|
553
|
+
// Or prefetch different queries in parallel
|
|
554
|
+
await prefetchAll(queryClient, [
|
|
555
|
+
{ helper: userPrefetch, params: { urlParams: { userId } } },
|
|
556
|
+
{ helper: postsPrefetch, params: { urlParams: { userId }, params: { limit: 10 } } },
|
|
557
|
+
])
|
|
558
|
+
```
|
|
559
|
+
|
|
560
|
+
### Helper Methods
|
|
561
|
+
|
|
562
|
+
- `prefetch(queryClient, params)` - Prefetch data on the server
|
|
563
|
+
- `ensureData(queryClient, params)` - Ensure data exists, returns the data
|
|
564
|
+
- `getQueryOptions(params)` - Get raw query options for customization
|
|
565
|
+
- `prefetchMany(queryClient, paramsList)` - Prefetch multiple queries in parallel
|
|
566
|
+
|
|
567
|
+
## Optimistic Update Helpers
|
|
568
|
+
|
|
569
|
+
Simplify optimistic updates with the `createOptimisticUpdate` helper:
|
|
570
|
+
|
|
571
|
+
```typescript
|
|
572
|
+
import { createOptimisticUpdate } from '@navios/react-query'
|
|
573
|
+
|
|
574
|
+
const updateUser = client.mutation({
|
|
575
|
+
method: 'PATCH',
|
|
576
|
+
url: '/users/$userId',
|
|
577
|
+
requestSchema: updateUserSchema,
|
|
578
|
+
responseSchema: userSchema,
|
|
579
|
+
processResponse: (data) => data,
|
|
580
|
+
useContext: () => ({ queryClient: useQueryClient() }),
|
|
581
|
+
...createOptimisticUpdate({
|
|
582
|
+
queryKey: ['users', userId],
|
|
583
|
+
updateFn: (oldData, variables) => ({
|
|
584
|
+
...oldData,
|
|
585
|
+
...variables.data,
|
|
586
|
+
}),
|
|
587
|
+
rollbackOnError: true, // default
|
|
588
|
+
invalidateOnSettled: true, // default
|
|
589
|
+
}),
|
|
590
|
+
})
|
|
591
|
+
```
|
|
592
|
+
|
|
593
|
+
### Multi-Query Optimistic Updates
|
|
594
|
+
|
|
595
|
+
When a mutation affects multiple cached queries:
|
|
596
|
+
|
|
597
|
+
```typescript
|
|
598
|
+
import { createMultiOptimisticUpdate } from '@navios/react-query'
|
|
599
|
+
|
|
600
|
+
const updateUser = client.mutation({
|
|
601
|
+
// ...config
|
|
602
|
+
...createMultiOptimisticUpdate([
|
|
603
|
+
{
|
|
604
|
+
queryKey: ['users', userId],
|
|
605
|
+
updateFn: (oldData, variables) => ({ ...oldData, ...variables.data }),
|
|
606
|
+
},
|
|
607
|
+
{
|
|
608
|
+
queryKey: ['users'],
|
|
609
|
+
updateFn: (oldList, variables) =>
|
|
610
|
+
(oldList ?? []).map((u) =>
|
|
611
|
+
u.id === userId ? { ...u, ...variables.data } : u
|
|
612
|
+
),
|
|
613
|
+
},
|
|
614
|
+
]),
|
|
615
|
+
})
|
|
616
|
+
```
|
|
617
|
+
|
|
618
|
+
## Error Schema Support
|
|
619
|
+
|
|
620
|
+
When using `useDiscriminatorResponse: true` mode, API errors are returned as data instead of being thrown. This enables type-safe error discrimination:
|
|
621
|
+
|
|
622
|
+
```typescript
|
|
623
|
+
const api = builder({ useDiscriminatorResponse: true })
|
|
624
|
+
|
|
625
|
+
const getUser = client.query({
|
|
626
|
+
method: 'GET',
|
|
627
|
+
url: '/users/$userId',
|
|
628
|
+
responseSchema: userSchema,
|
|
629
|
+
errorSchema: {
|
|
630
|
+
400: z.object({ error: z.string(), code: z.number() }),
|
|
631
|
+
404: z.object({ notFound: z.literal(true) }),
|
|
632
|
+
500: z.object({ serverError: z.string() }),
|
|
633
|
+
},
|
|
634
|
+
processResponse: (data) => {
|
|
635
|
+
// data is typed as: User | { error: string, code: number } | { notFound: true } | { serverError: string }
|
|
636
|
+
if ('error' in data) {
|
|
637
|
+
return { ok: false as const, error: data.error }
|
|
638
|
+
}
|
|
639
|
+
if ('notFound' in data) {
|
|
640
|
+
return { ok: false as const, error: 'User not found' }
|
|
641
|
+
}
|
|
642
|
+
if ('serverError' in data) {
|
|
643
|
+
return { ok: false as const, error: data.serverError }
|
|
644
|
+
}
|
|
645
|
+
return { ok: true as const, user: data }
|
|
646
|
+
},
|
|
647
|
+
})
|
|
648
|
+
|
|
649
|
+
// In your component
|
|
650
|
+
function UserProfile({ userId }: { userId: string }) {
|
|
651
|
+
const result = getUser.useSuspense({ urlParams: { userId } })
|
|
652
|
+
|
|
653
|
+
if (!result.ok) {
|
|
654
|
+
return <ErrorMessage error={result.error} />
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
return <div>{result.user.name}</div>
|
|
658
|
+
}
|
|
659
|
+
```
|
|
660
|
+
|
|
517
661
|
## API Reference
|
|
518
662
|
|
|
519
663
|
### `declareClient(options)`
|
|
@@ -594,11 +738,15 @@ The context passed to mutation callbacks includes:
|
|
|
594
738
|
- `meta` - Mutation metadata
|
|
595
739
|
- `onMutateResult` - Return value from `onMutate` (in `onSuccess`, `onError`, `onSettled`)
|
|
596
740
|
|
|
597
|
-
## Migration
|
|
741
|
+
## Migration to 1.0.0
|
|
742
|
+
|
|
743
|
+
See [CHANGELOG.md](./CHANGELOG.md) for full migration guide.
|
|
744
|
+
|
|
745
|
+
### From 0.7.x
|
|
598
746
|
|
|
599
|
-
|
|
747
|
+
- **Type file reorganization** - If importing internal types, update paths to use `client/types/*.mts`
|
|
600
748
|
|
|
601
|
-
|
|
749
|
+
### From 0.5.x to 0.6.x
|
|
602
750
|
|
|
603
751
|
- Mutation callbacks now receive `(data, variables, context)` instead of `(queryClient, data, variables)`
|
|
604
752
|
- Use `useContext` hook to provide `queryClient` and other dependencies
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
body, html {
|
|
2
|
+
margin:0; padding: 0;
|
|
3
|
+
height: 100%;
|
|
4
|
+
}
|
|
5
|
+
body {
|
|
6
|
+
font-family: Helvetica Neue, Helvetica, Arial;
|
|
7
|
+
font-size: 14px;
|
|
8
|
+
color:#333;
|
|
9
|
+
}
|
|
10
|
+
.small { font-size: 12px; }
|
|
11
|
+
*, *:after, *:before {
|
|
12
|
+
-webkit-box-sizing:border-box;
|
|
13
|
+
-moz-box-sizing:border-box;
|
|
14
|
+
box-sizing:border-box;
|
|
15
|
+
}
|
|
16
|
+
h1 { font-size: 20px; margin: 0;}
|
|
17
|
+
h2 { font-size: 14px; }
|
|
18
|
+
pre {
|
|
19
|
+
font: 12px/1.4 Consolas, "Liberation Mono", Menlo, Courier, monospace;
|
|
20
|
+
margin: 0;
|
|
21
|
+
padding: 0;
|
|
22
|
+
-moz-tab-size: 2;
|
|
23
|
+
-o-tab-size: 2;
|
|
24
|
+
tab-size: 2;
|
|
25
|
+
}
|
|
26
|
+
a { color:#0074D9; text-decoration:none; }
|
|
27
|
+
a:hover { text-decoration:underline; }
|
|
28
|
+
.strong { font-weight: bold; }
|
|
29
|
+
.space-top1 { padding: 10px 0 0 0; }
|
|
30
|
+
.pad2y { padding: 20px 0; }
|
|
31
|
+
.pad1y { padding: 10px 0; }
|
|
32
|
+
.pad2x { padding: 0 20px; }
|
|
33
|
+
.pad2 { padding: 20px; }
|
|
34
|
+
.pad1 { padding: 10px; }
|
|
35
|
+
.space-left2 { padding-left:55px; }
|
|
36
|
+
.space-right2 { padding-right:20px; }
|
|
37
|
+
.center { text-align:center; }
|
|
38
|
+
.clearfix { display:block; }
|
|
39
|
+
.clearfix:after {
|
|
40
|
+
content:'';
|
|
41
|
+
display:block;
|
|
42
|
+
height:0;
|
|
43
|
+
clear:both;
|
|
44
|
+
visibility:hidden;
|
|
45
|
+
}
|
|
46
|
+
.fl { float: left; }
|
|
47
|
+
@media only screen and (max-width:640px) {
|
|
48
|
+
.col3 { width:100%; max-width:100%; }
|
|
49
|
+
.hide-mobile { display:none!important; }
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.quiet {
|
|
53
|
+
color: #7f7f7f;
|
|
54
|
+
color: rgba(0,0,0,0.5);
|
|
55
|
+
}
|
|
56
|
+
.quiet a { opacity: 0.7; }
|
|
57
|
+
|
|
58
|
+
.fraction {
|
|
59
|
+
font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace;
|
|
60
|
+
font-size: 10px;
|
|
61
|
+
color: #555;
|
|
62
|
+
background: #E8E8E8;
|
|
63
|
+
padding: 4px 5px;
|
|
64
|
+
border-radius: 3px;
|
|
65
|
+
vertical-align: middle;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
div.path a:link, div.path a:visited { color: #333; }
|
|
69
|
+
table.coverage {
|
|
70
|
+
border-collapse: collapse;
|
|
71
|
+
margin: 10px 0 0 0;
|
|
72
|
+
padding: 0;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
table.coverage td {
|
|
76
|
+
margin: 0;
|
|
77
|
+
padding: 0;
|
|
78
|
+
vertical-align: top;
|
|
79
|
+
}
|
|
80
|
+
table.coverage td.line-count {
|
|
81
|
+
text-align: right;
|
|
82
|
+
padding: 0 5px 0 20px;
|
|
83
|
+
}
|
|
84
|
+
table.coverage td.line-coverage {
|
|
85
|
+
text-align: right;
|
|
86
|
+
padding-right: 10px;
|
|
87
|
+
min-width:20px;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
table.coverage td span.cline-any {
|
|
91
|
+
display: inline-block;
|
|
92
|
+
padding: 0 5px;
|
|
93
|
+
width: 100%;
|
|
94
|
+
}
|
|
95
|
+
.missing-if-branch {
|
|
96
|
+
display: inline-block;
|
|
97
|
+
margin-right: 5px;
|
|
98
|
+
border-radius: 3px;
|
|
99
|
+
position: relative;
|
|
100
|
+
padding: 0 4px;
|
|
101
|
+
background: #333;
|
|
102
|
+
color: yellow;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
.skip-if-branch {
|
|
106
|
+
display: none;
|
|
107
|
+
margin-right: 10px;
|
|
108
|
+
position: relative;
|
|
109
|
+
padding: 0 4px;
|
|
110
|
+
background: #ccc;
|
|
111
|
+
color: white;
|
|
112
|
+
}
|
|
113
|
+
.missing-if-branch .typ, .skip-if-branch .typ {
|
|
114
|
+
color: inherit !important;
|
|
115
|
+
}
|
|
116
|
+
.coverage-summary {
|
|
117
|
+
border-collapse: collapse;
|
|
118
|
+
width: 100%;
|
|
119
|
+
}
|
|
120
|
+
.coverage-summary tr { border-bottom: 1px solid #bbb; }
|
|
121
|
+
.keyline-all { border: 1px solid #ddd; }
|
|
122
|
+
.coverage-summary td, .coverage-summary th { padding: 10px; }
|
|
123
|
+
.coverage-summary tbody { border: 1px solid #bbb; }
|
|
124
|
+
.coverage-summary td { border-right: 1px solid #bbb; }
|
|
125
|
+
.coverage-summary td:last-child { border-right: none; }
|
|
126
|
+
.coverage-summary th {
|
|
127
|
+
text-align: left;
|
|
128
|
+
font-weight: normal;
|
|
129
|
+
white-space: nowrap;
|
|
130
|
+
}
|
|
131
|
+
.coverage-summary th.file { border-right: none !important; }
|
|
132
|
+
.coverage-summary th.pct { }
|
|
133
|
+
.coverage-summary th.pic,
|
|
134
|
+
.coverage-summary th.abs,
|
|
135
|
+
.coverage-summary td.pct,
|
|
136
|
+
.coverage-summary td.abs { text-align: right; }
|
|
137
|
+
.coverage-summary td.file { white-space: nowrap; }
|
|
138
|
+
.coverage-summary td.pic { min-width: 120px !important; }
|
|
139
|
+
.coverage-summary tfoot td { }
|
|
140
|
+
|
|
141
|
+
.coverage-summary .sorter {
|
|
142
|
+
height: 10px;
|
|
143
|
+
width: 7px;
|
|
144
|
+
display: inline-block;
|
|
145
|
+
margin-left: 0.5em;
|
|
146
|
+
background: url(sort-arrow-sprite.png) no-repeat scroll 0 0 transparent;
|
|
147
|
+
}
|
|
148
|
+
.coverage-summary .sorted .sorter {
|
|
149
|
+
background-position: 0 -20px;
|
|
150
|
+
}
|
|
151
|
+
.coverage-summary .sorted-desc .sorter {
|
|
152
|
+
background-position: 0 -10px;
|
|
153
|
+
}
|
|
154
|
+
.status-line { height: 10px; }
|
|
155
|
+
/* yellow */
|
|
156
|
+
.cbranch-no { background: yellow !important; color: #111; }
|
|
157
|
+
/* dark red */
|
|
158
|
+
.red.solid, .status-line.low, .low .cover-fill { background:#C21F39 }
|
|
159
|
+
.low .chart { border:1px solid #C21F39 }
|
|
160
|
+
.highlighted,
|
|
161
|
+
.highlighted .cstat-no, .highlighted .fstat-no, .highlighted .cbranch-no{
|
|
162
|
+
background: #C21F39 !important;
|
|
163
|
+
}
|
|
164
|
+
/* medium red */
|
|
165
|
+
.cstat-no, .fstat-no, .cbranch-no, .cbranch-no { background:#F6C6CE }
|
|
166
|
+
/* light red */
|
|
167
|
+
.low, .cline-no { background:#FCE1E5 }
|
|
168
|
+
/* light green */
|
|
169
|
+
.high, .cline-yes { background:rgb(230,245,208) }
|
|
170
|
+
/* medium green */
|
|
171
|
+
.cstat-yes { background:rgb(161,215,106) }
|
|
172
|
+
/* dark green */
|
|
173
|
+
.status-line.high, .high .cover-fill { background:rgb(77,146,33) }
|
|
174
|
+
.high .chart { border:1px solid rgb(77,146,33) }
|
|
175
|
+
/* dark yellow (gold) */
|
|
176
|
+
.status-line.medium, .medium .cover-fill { background: #f9cd0b; }
|
|
177
|
+
.medium .chart { border:1px solid #f9cd0b; }
|
|
178
|
+
/* light yellow */
|
|
179
|
+
.medium { background: #fff4c2; }
|
|
180
|
+
|
|
181
|
+
.cstat-skip { background: #ddd; color: #111; }
|
|
182
|
+
.fstat-skip { background: #ddd; color: #111 !important; }
|
|
183
|
+
.cbranch-skip { background: #ddd !important; color: #111; }
|
|
184
|
+
|
|
185
|
+
span.cline-neutral { background: #eaeaea; }
|
|
186
|
+
|
|
187
|
+
.coverage-summary td.empty {
|
|
188
|
+
opacity: .5;
|
|
189
|
+
padding-top: 4px;
|
|
190
|
+
padding-bottom: 4px;
|
|
191
|
+
line-height: 1;
|
|
192
|
+
color: #888;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
.cover-fill, .cover-empty {
|
|
196
|
+
display:inline-block;
|
|
197
|
+
height: 12px;
|
|
198
|
+
}
|
|
199
|
+
.chart {
|
|
200
|
+
line-height: 0;
|
|
201
|
+
}
|
|
202
|
+
.cover-empty {
|
|
203
|
+
background: white;
|
|
204
|
+
}
|
|
205
|
+
.cover-full {
|
|
206
|
+
border-right: none !important;
|
|
207
|
+
}
|
|
208
|
+
pre.prettyprint {
|
|
209
|
+
border: none !important;
|
|
210
|
+
padding: 0 !important;
|
|
211
|
+
margin: 0 !important;
|
|
212
|
+
}
|
|
213
|
+
.com { color: #999 !important; }
|
|
214
|
+
.ignore-none { color: #999; font-weight: normal; }
|
|
215
|
+
|
|
216
|
+
.wrapper {
|
|
217
|
+
min-height: 100%;
|
|
218
|
+
height: auto !important;
|
|
219
|
+
height: 100%;
|
|
220
|
+
margin: 0 auto -48px;
|
|
221
|
+
}
|
|
222
|
+
.footer, .push {
|
|
223
|
+
height: 48px;
|
|
224
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
2
|
+
var jumpToCode = (function init() {
|
|
3
|
+
// Classes of code we would like to highlight in the file view
|
|
4
|
+
var missingCoverageClasses = ['.cbranch-no', '.cstat-no', '.fstat-no'];
|
|
5
|
+
|
|
6
|
+
// Elements to highlight in the file listing view
|
|
7
|
+
var fileListingElements = ['td.pct.low'];
|
|
8
|
+
|
|
9
|
+
// We don't want to select elements that are direct descendants of another match
|
|
10
|
+
var notSelector = ':not(' + missingCoverageClasses.join('):not(') + ') > '; // becomes `:not(a):not(b) > `
|
|
11
|
+
|
|
12
|
+
// Selector that finds elements on the page to which we can jump
|
|
13
|
+
var selector =
|
|
14
|
+
fileListingElements.join(', ') +
|
|
15
|
+
', ' +
|
|
16
|
+
notSelector +
|
|
17
|
+
missingCoverageClasses.join(', ' + notSelector); // becomes `:not(a):not(b) > a, :not(a):not(b) > b`
|
|
18
|
+
|
|
19
|
+
// The NodeList of matching elements
|
|
20
|
+
var missingCoverageElements = document.querySelectorAll(selector);
|
|
21
|
+
|
|
22
|
+
var currentIndex;
|
|
23
|
+
|
|
24
|
+
function toggleClass(index) {
|
|
25
|
+
missingCoverageElements
|
|
26
|
+
.item(currentIndex)
|
|
27
|
+
.classList.remove('highlighted');
|
|
28
|
+
missingCoverageElements.item(index).classList.add('highlighted');
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function makeCurrent(index) {
|
|
32
|
+
toggleClass(index);
|
|
33
|
+
currentIndex = index;
|
|
34
|
+
missingCoverageElements.item(index).scrollIntoView({
|
|
35
|
+
behavior: 'smooth',
|
|
36
|
+
block: 'center',
|
|
37
|
+
inline: 'center'
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function goToPrevious() {
|
|
42
|
+
var nextIndex = 0;
|
|
43
|
+
if (typeof currentIndex !== 'number' || currentIndex === 0) {
|
|
44
|
+
nextIndex = missingCoverageElements.length - 1;
|
|
45
|
+
} else if (missingCoverageElements.length > 1) {
|
|
46
|
+
nextIndex = currentIndex - 1;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
makeCurrent(nextIndex);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function goToNext() {
|
|
53
|
+
var nextIndex = 0;
|
|
54
|
+
|
|
55
|
+
if (
|
|
56
|
+
typeof currentIndex === 'number' &&
|
|
57
|
+
currentIndex < missingCoverageElements.length - 1
|
|
58
|
+
) {
|
|
59
|
+
nextIndex = currentIndex + 1;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
makeCurrent(nextIndex);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return function jump(event) {
|
|
66
|
+
if (
|
|
67
|
+
document.getElementById('fileSearch') === document.activeElement &&
|
|
68
|
+
document.activeElement != null
|
|
69
|
+
) {
|
|
70
|
+
// if we're currently focused on the search input, we don't want to navigate
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
switch (event.which) {
|
|
75
|
+
case 78: // n
|
|
76
|
+
case 74: // j
|
|
77
|
+
goToNext();
|
|
78
|
+
break;
|
|
79
|
+
case 66: // b
|
|
80
|
+
case 75: // k
|
|
81
|
+
case 80: // p
|
|
82
|
+
goToPrevious();
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
})();
|
|
87
|
+
window.addEventListener('keydown', jumpToCode);
|