@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.
@@ -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
+ }