@navios/react-query 0.1.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/README.md +370 -0
- package/dist/index.d.mts +346 -0
- package/dist/index.d.ts +346 -0
- package/dist/index.js +345 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +325 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +43 -0
- package/src/__tests__/client-type-check.spec.mts +61 -0
- package/src/__tests__/declare-client.spec.mts +187 -0
- package/src/__tests__/make-mutation.spec.mts +140 -0
- package/src/__tests__/makeDataTag.spec.mts +70 -0
- package/src/__tests__/makeInfiniteQueryOptions.spec.mts +45 -0
- package/src/__tests__/makeQueryOptions.spec.mts +43 -0
- package/src/declare-client.mts +215 -0
- package/src/index.mts +8 -0
- package/src/make-infinite-query-options.mts +115 -0
- package/src/make-mutation.mts +121 -0
- package/src/make-query-options.mts +113 -0
- package/src/types/client-instance.mts +502 -0
- package/src/types/index.mts +6 -0
- package/src/types/mutation-args.mts +10 -0
- package/src/types/mutation-helpers.mts +13 -0
- package/src/types/query-args.mts +8 -0
- package/src/types/query-helpers.mts +34 -0
- package/src/types/query-url-params-args.mts +6 -0
- package/src/types.mts +118 -0
- package/src/utils/mutation-key.creator.mts +61 -0
- package/src/utils/query-key-creator.mts +125 -0
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
AbstractEndpoint,
|
|
3
|
+
AnyEndpointConfig,
|
|
4
|
+
UrlHasParams,
|
|
5
|
+
UrlParams,
|
|
6
|
+
} from '@navios/common'
|
|
7
|
+
import type { UseMutationResult } from '@tanstack/react-query'
|
|
8
|
+
import type { z } from 'zod'
|
|
9
|
+
|
|
10
|
+
import {
|
|
11
|
+
useIsMutating,
|
|
12
|
+
useMutation,
|
|
13
|
+
useQueryClient,
|
|
14
|
+
} from '@tanstack/react-query'
|
|
15
|
+
|
|
16
|
+
import type { BaseMutationArgs, BaseMutationParams } from './types.mjs'
|
|
17
|
+
|
|
18
|
+
import { mutationKeyCreator } from './index.mjs'
|
|
19
|
+
|
|
20
|
+
export function makeMutation<
|
|
21
|
+
Config extends AnyEndpointConfig,
|
|
22
|
+
TData = unknown,
|
|
23
|
+
TVariables extends BaseMutationArgs<Config> = BaseMutationArgs<Config>,
|
|
24
|
+
TResponse = z.output<Config['responseSchema']>,
|
|
25
|
+
TContext = unknown,
|
|
26
|
+
UseKey extends boolean = false,
|
|
27
|
+
>(
|
|
28
|
+
endpoint: AbstractEndpoint<Config>,
|
|
29
|
+
options: BaseMutationParams<
|
|
30
|
+
Config,
|
|
31
|
+
TData,
|
|
32
|
+
TVariables,
|
|
33
|
+
TResponse,
|
|
34
|
+
TContext,
|
|
35
|
+
UseKey
|
|
36
|
+
>,
|
|
37
|
+
) {
|
|
38
|
+
const config = endpoint.config
|
|
39
|
+
|
|
40
|
+
const mutationKey = mutationKeyCreator(config, options)
|
|
41
|
+
const result = (
|
|
42
|
+
keyParams: UseKey extends true
|
|
43
|
+
? UrlHasParams<Config['url']> extends true
|
|
44
|
+
? UrlParams<Config['url']>
|
|
45
|
+
: never
|
|
46
|
+
: never,
|
|
47
|
+
): UseMutationResult<TData, Error, BaseMutationArgs<Config>> => {
|
|
48
|
+
const queryClient = useQueryClient()
|
|
49
|
+
const {
|
|
50
|
+
useKey,
|
|
51
|
+
useContext,
|
|
52
|
+
onError,
|
|
53
|
+
onSuccess,
|
|
54
|
+
keyPrefix,
|
|
55
|
+
keySuffix,
|
|
56
|
+
processResponse,
|
|
57
|
+
...rest
|
|
58
|
+
} = options
|
|
59
|
+
|
|
60
|
+
const context = useContext?.() as TContext
|
|
61
|
+
|
|
62
|
+
// @ts-expect-error The types match
|
|
63
|
+
return useMutation(
|
|
64
|
+
{
|
|
65
|
+
...rest,
|
|
66
|
+
mutationKey: useKey
|
|
67
|
+
? mutationKey({
|
|
68
|
+
urlParams: keyParams,
|
|
69
|
+
})
|
|
70
|
+
: undefined,
|
|
71
|
+
scope: useKey
|
|
72
|
+
? {
|
|
73
|
+
id: JSON.stringify(
|
|
74
|
+
mutationKey({
|
|
75
|
+
urlParams: keyParams,
|
|
76
|
+
}),
|
|
77
|
+
),
|
|
78
|
+
}
|
|
79
|
+
: undefined,
|
|
80
|
+
async mutationFn(params: TVariables) {
|
|
81
|
+
const response = await endpoint(params)
|
|
82
|
+
|
|
83
|
+
return processResponse(response) as TData
|
|
84
|
+
},
|
|
85
|
+
onSuccess: onSuccess
|
|
86
|
+
? (data: TData, variables: TVariables) => {
|
|
87
|
+
return onSuccess?.(queryClient, data, variables, context)
|
|
88
|
+
}
|
|
89
|
+
: undefined,
|
|
90
|
+
onError: onError
|
|
91
|
+
? (err: Error, variables: TVariables) => {
|
|
92
|
+
return onError?.(queryClient, err, variables, context)
|
|
93
|
+
}
|
|
94
|
+
: undefined,
|
|
95
|
+
},
|
|
96
|
+
queryClient,
|
|
97
|
+
)
|
|
98
|
+
}
|
|
99
|
+
result.useIsMutating = (
|
|
100
|
+
keyParams: UseKey extends true
|
|
101
|
+
? UrlHasParams<Config['url']> extends true
|
|
102
|
+
? UrlParams<Config['url']>
|
|
103
|
+
: never
|
|
104
|
+
: never,
|
|
105
|
+
): boolean => {
|
|
106
|
+
if (!options.useKey) {
|
|
107
|
+
throw new Error(
|
|
108
|
+
'useIsMutating can only be used when useKey is set to true',
|
|
109
|
+
)
|
|
110
|
+
}
|
|
111
|
+
const isMutating = useIsMutating({
|
|
112
|
+
mutationKey: mutationKey({
|
|
113
|
+
urlParams: keyParams,
|
|
114
|
+
}),
|
|
115
|
+
})
|
|
116
|
+
return isMutating > 0
|
|
117
|
+
}
|
|
118
|
+
result.mutationKey = mutationKey
|
|
119
|
+
|
|
120
|
+
return result
|
|
121
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import type { AbstractEndpoint, AnyEndpointConfig } from '@navios/common'
|
|
2
|
+
import type {
|
|
3
|
+
DataTag,
|
|
4
|
+
QueryClient,
|
|
5
|
+
UseQueryOptions,
|
|
6
|
+
UseSuspenseQueryOptions,
|
|
7
|
+
} from '@tanstack/react-query'
|
|
8
|
+
|
|
9
|
+
import {
|
|
10
|
+
queryOptions,
|
|
11
|
+
useInfiniteQuery,
|
|
12
|
+
useSuspenseInfiniteQuery,
|
|
13
|
+
} from '@tanstack/react-query'
|
|
14
|
+
|
|
15
|
+
import type { BaseQueryArgs, BaseQueryParams } from './types.mjs'
|
|
16
|
+
import type { ClientQueryArgs } from './types/index.mjs'
|
|
17
|
+
|
|
18
|
+
import { queryKeyCreator } from './utils/query-key-creator.mjs'
|
|
19
|
+
|
|
20
|
+
type Split<S extends string, D extends string> = string extends S
|
|
21
|
+
? string[]
|
|
22
|
+
: S extends ''
|
|
23
|
+
? []
|
|
24
|
+
: S extends `${infer T}${D}${infer U}`
|
|
25
|
+
? [T, ...Split<U, D>]
|
|
26
|
+
: [S]
|
|
27
|
+
|
|
28
|
+
export function makeQueryOptions<
|
|
29
|
+
Config extends AnyEndpointConfig,
|
|
30
|
+
Options extends BaseQueryParams<Config>,
|
|
31
|
+
BaseQuery extends Omit<
|
|
32
|
+
UseQueryOptions<ReturnType<Options['processResponse']>, Error, any>,
|
|
33
|
+
| 'queryKey'
|
|
34
|
+
| 'queryFn'
|
|
35
|
+
| 'getNextPageParam'
|
|
36
|
+
| 'initialPageParam'
|
|
37
|
+
| 'enabled'
|
|
38
|
+
| 'throwOnError'
|
|
39
|
+
| 'placeholderData'
|
|
40
|
+
>,
|
|
41
|
+
>(
|
|
42
|
+
endpoint: AbstractEndpoint<Config>,
|
|
43
|
+
options: Options,
|
|
44
|
+
baseQuery: BaseQuery = {} as BaseQuery,
|
|
45
|
+
) {
|
|
46
|
+
const config = endpoint.config
|
|
47
|
+
// Let's hack the url to be a string for now
|
|
48
|
+
const queryKey = queryKeyCreator(config, options, false)
|
|
49
|
+
const processResponse = options.processResponse
|
|
50
|
+
|
|
51
|
+
const result = (
|
|
52
|
+
params: BaseQueryArgs<Config>,
|
|
53
|
+
): Options['processResponse'] extends (...args: any[]) => infer Result
|
|
54
|
+
? UseSuspenseQueryOptions<
|
|
55
|
+
Result,
|
|
56
|
+
Error,
|
|
57
|
+
BaseQuery['select'] extends (...args: any[]) => infer T ? T : Result,
|
|
58
|
+
DataTag<Split<Config['url'], '/'>, Result, Error>
|
|
59
|
+
>
|
|
60
|
+
: never => {
|
|
61
|
+
// @ts-expect-error TS2322 We know that the processResponse is defined
|
|
62
|
+
return queryOptions({
|
|
63
|
+
queryKey: queryKey.dataTag(params),
|
|
64
|
+
queryFn: async ({ signal }) => {
|
|
65
|
+
let result
|
|
66
|
+
try {
|
|
67
|
+
result = await endpoint({
|
|
68
|
+
signal,
|
|
69
|
+
...params,
|
|
70
|
+
})
|
|
71
|
+
} catch (err) {
|
|
72
|
+
if (options.onFail) {
|
|
73
|
+
options.onFail(err)
|
|
74
|
+
}
|
|
75
|
+
throw err
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return processResponse(result)
|
|
79
|
+
},
|
|
80
|
+
...baseQuery,
|
|
81
|
+
})
|
|
82
|
+
}
|
|
83
|
+
result.queryKey = queryKey
|
|
84
|
+
result.use = (params: ClientQueryArgs) => {
|
|
85
|
+
// @ts-expect-error We add additional function to the result
|
|
86
|
+
return useInfiniteQuery(result(params))
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
result.useSuspense = (params: ClientQueryArgs) => {
|
|
90
|
+
// @ts-expect-error We add additional function to the result
|
|
91
|
+
return useSuspenseInfiniteQuery(result(params))
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
result.invalidate = (queryClient: QueryClient, params: ClientQueryArgs) => {
|
|
95
|
+
return queryClient.invalidateQueries({
|
|
96
|
+
// @ts-expect-error We add additional function to the result
|
|
97
|
+
queryKey: result.queryKey.dataTag(params),
|
|
98
|
+
})
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
result.invalidateAll = (
|
|
102
|
+
queryClient: QueryClient,
|
|
103
|
+
params: ClientQueryArgs,
|
|
104
|
+
) => {
|
|
105
|
+
return queryClient.invalidateQueries({
|
|
106
|
+
// @ts-expect-error We add additional function to the result
|
|
107
|
+
queryKey: result.queryKey.filterKey(params),
|
|
108
|
+
exact: false,
|
|
109
|
+
})
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return result
|
|
113
|
+
}
|