@effect-app/vue 1.25.2 → 1.26.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 +11 -0
- package/_cjs/makeClient2.cjs +265 -0
- package/_cjs/makeClient2.cjs.map +1 -0
- package/_cjs/mutate2.cjs +112 -0
- package/_cjs/mutate2.cjs.map +1 -0
- package/_cjs/query2.cjs +127 -0
- package/_cjs/query2.cjs.map +1 -0
- package/dist/makeClient2.d.ts +134 -0
- package/dist/makeClient2.d.ts.map +1 -0
- package/dist/makeClient2.js +240 -0
- package/dist/mutate2.d.ts +45 -0
- package/dist/mutate2.d.ts.map +1 -0
- package/dist/mutate2.js +86 -0
- package/dist/query2.d.ts +24 -0
- package/dist/query2.d.ts.map +1 -0
- package/dist/query2.js +119 -0
- package/package.json +33 -3
- package/src/makeClient2.ts +524 -0
- package/src/mutate2.ts +191 -0
- package/src/query2.ts +231 -0
package/src/query2.ts
ADDED
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
|
3
|
+
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
|
4
|
+
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
|
5
|
+
import { isHttpRequestError, isHttpResponseError } from "@effect-app/core/http/http-client"
|
|
6
|
+
import * as Result from "@effect-rx/rx/Result"
|
|
7
|
+
import type {
|
|
8
|
+
QueryKey,
|
|
9
|
+
QueryObserverOptions,
|
|
10
|
+
QueryObserverResult,
|
|
11
|
+
RefetchOptions,
|
|
12
|
+
UseQueryReturnType
|
|
13
|
+
} from "@tanstack/vue-query"
|
|
14
|
+
import { useQuery } from "@tanstack/vue-query"
|
|
15
|
+
import { Cause, Effect, Option, Runtime, S } from "effect-app"
|
|
16
|
+
import { ServiceUnavailableError } from "effect-app/client"
|
|
17
|
+
import { computed, ref } from "vue"
|
|
18
|
+
import type { ComputedRef, Ref, WatchSource } from "vue"
|
|
19
|
+
import { makeQueryKey, reportRuntimeError } from "./internal.js"
|
|
20
|
+
|
|
21
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
|
22
|
+
export interface QueryObserverOptionsCustom<
|
|
23
|
+
TQueryFnData = unknown,
|
|
24
|
+
TError = Error,
|
|
25
|
+
TData = TQueryFnData,
|
|
26
|
+
TQueryData = TQueryFnData,
|
|
27
|
+
TQueryKey extends QueryKey = QueryKey,
|
|
28
|
+
TPageParam = never
|
|
29
|
+
> extends
|
|
30
|
+
Omit<QueryObserverOptions<TQueryFnData, TError, TData, TQueryData, TQueryKey, TPageParam>, "queryKey" | "queryFn">
|
|
31
|
+
{}
|
|
32
|
+
|
|
33
|
+
export interface KnownFiberFailure<E> extends Runtime.FiberFailure {
|
|
34
|
+
readonly [Runtime.FiberFailureCauseId]: Cause.Cause<E>
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export const makeQuery2 = <R>(runtime: Ref<Runtime.Runtime<R>>) => {
|
|
38
|
+
// TODO: options
|
|
39
|
+
// declare function useQuery<TQueryFnData = unknown, TError = DefaultError, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey>(options: UndefinedInitialQueryOptions<TQueryFnData, TError, TData, TQueryKey>, queryClient?: QueryClient): UseQueryReturnType<TData, TError>;
|
|
40
|
+
// declare function useQuery<TQueryFnData = unknown, TError = DefaultError, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey>(options: DefinedInitialQueryOptions<TQueryFnData, TError, TData, TQueryKey>, queryClient?: QueryClient): UseQueryDefinedReturnType<TData, TError>;
|
|
41
|
+
// declare function useQuery<TQueryFnData = unknown, TError = DefaultError, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey>(options: UseQueryOptions<TQueryFnData, TError, TData, TQueryFnData, TQueryKey>, queryClient?: QueryClient): UseQueryReturnType<TData, TError>;
|
|
42
|
+
const useSafeQuery_ = <I, A, E>(
|
|
43
|
+
q:
|
|
44
|
+
| {
|
|
45
|
+
readonly handler: (
|
|
46
|
+
req: I
|
|
47
|
+
) => Effect<
|
|
48
|
+
A,
|
|
49
|
+
E,
|
|
50
|
+
R
|
|
51
|
+
>
|
|
52
|
+
mapPath: (req: I) => string
|
|
53
|
+
name: string
|
|
54
|
+
}
|
|
55
|
+
| {
|
|
56
|
+
readonly handler: Effect<
|
|
57
|
+
A,
|
|
58
|
+
E,
|
|
59
|
+
R
|
|
60
|
+
>
|
|
61
|
+
mapPath: string
|
|
62
|
+
name: string
|
|
63
|
+
},
|
|
64
|
+
arg?: I | WatchSource<I>,
|
|
65
|
+
options: QueryObserverOptionsCustom<unknown, KnownFiberFailure<E>, A> = {} // TODO
|
|
66
|
+
) => {
|
|
67
|
+
const runPromise = Runtime.runPromise(runtime.value)
|
|
68
|
+
const arr = arg
|
|
69
|
+
const req: { value: I } = !arg
|
|
70
|
+
? undefined
|
|
71
|
+
: typeof arr === "function"
|
|
72
|
+
? ({
|
|
73
|
+
get value() {
|
|
74
|
+
return (arr as any)()
|
|
75
|
+
}
|
|
76
|
+
} as any)
|
|
77
|
+
: ref(arg)
|
|
78
|
+
const queryKey = makeQueryKey(q.name)
|
|
79
|
+
const handler = q.handler
|
|
80
|
+
const r = useQuery<unknown, KnownFiberFailure<E>, A>(
|
|
81
|
+
Effect.isEffect(handler)
|
|
82
|
+
? {
|
|
83
|
+
...options,
|
|
84
|
+
retry: (retryCount, error) => {
|
|
85
|
+
if (Runtime.isFiberFailure(error)) {
|
|
86
|
+
const cause = error[Runtime.FiberFailureCauseId]
|
|
87
|
+
const sq = Cause.squash(cause)
|
|
88
|
+
if (!isHttpRequestError(sq) && !isHttpResponseError(sq) && !S.is(ServiceUnavailableError)(sq)) {
|
|
89
|
+
return false
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return retryCount < 5
|
|
94
|
+
},
|
|
95
|
+
queryKey,
|
|
96
|
+
queryFn: ({ signal }) =>
|
|
97
|
+
runPromise(
|
|
98
|
+
handler
|
|
99
|
+
.pipe(
|
|
100
|
+
Effect.tapDefect(reportRuntimeError),
|
|
101
|
+
Effect.withSpan(`query ${q.name}`, { captureStackTrace: false })
|
|
102
|
+
),
|
|
103
|
+
{ signal }
|
|
104
|
+
)
|
|
105
|
+
}
|
|
106
|
+
: {
|
|
107
|
+
...options,
|
|
108
|
+
retry: (retryCount, error) => {
|
|
109
|
+
if (Runtime.isFiberFailure(error)) {
|
|
110
|
+
const cause = error[Runtime.FiberFailureCauseId]
|
|
111
|
+
const sq = Cause.squash(cause)
|
|
112
|
+
if (!isHttpRequestError(sq) && !isHttpResponseError(sq) && !S.is(ServiceUnavailableError)(sq)) {
|
|
113
|
+
return false
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return retryCount < 5
|
|
118
|
+
},
|
|
119
|
+
queryKey: [...queryKey, req],
|
|
120
|
+
queryFn: ({ signal }) =>
|
|
121
|
+
runPromise(
|
|
122
|
+
handler(req.value)
|
|
123
|
+
.pipe(
|
|
124
|
+
Effect.tapDefect(reportRuntimeError),
|
|
125
|
+
Effect.withSpan(`query ${q.name}`, { captureStackTrace: false })
|
|
126
|
+
),
|
|
127
|
+
{ signal }
|
|
128
|
+
)
|
|
129
|
+
}
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
const result = computed(() =>
|
|
133
|
+
swrToQuery({
|
|
134
|
+
error: r.error.value ?? undefined,
|
|
135
|
+
data: r.data.value,
|
|
136
|
+
isValidating: r.isFetching.value
|
|
137
|
+
})
|
|
138
|
+
)
|
|
139
|
+
const latestSuccess = computed(() => Option.getOrUndefined(Result.value(result.value)))
|
|
140
|
+
return [
|
|
141
|
+
result,
|
|
142
|
+
latestSuccess,
|
|
143
|
+
// one thing to keep in mind is that span will be disconnected as Context does not pass from outside.
|
|
144
|
+
(options?: RefetchOptions) => Effect.promise(() => r.refetch(options)),
|
|
145
|
+
r
|
|
146
|
+
] as const
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function swrToQuery<E, A>(r: {
|
|
150
|
+
error: KnownFiberFailure<E> | undefined
|
|
151
|
+
data: A | undefined
|
|
152
|
+
isValidating: boolean
|
|
153
|
+
}): Result.Result<A, E> {
|
|
154
|
+
if (r.error) {
|
|
155
|
+
return Result.failureWithPrevious(
|
|
156
|
+
r.error[Runtime.FiberFailureCauseId],
|
|
157
|
+
r.data === undefined ? Option.none() : Option.some(Result.success(r.data)),
|
|
158
|
+
r.isValidating
|
|
159
|
+
)
|
|
160
|
+
}
|
|
161
|
+
if (r.data !== undefined) {
|
|
162
|
+
return Result.success<A, E>(r.data, r.isValidating)
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
return Result.initial(r.isValidating)
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
function useSafeQuery<E, A>(
|
|
169
|
+
self: {
|
|
170
|
+
handler: Effect<A, E, R>
|
|
171
|
+
mapPath: string
|
|
172
|
+
name: string
|
|
173
|
+
},
|
|
174
|
+
options?: QueryObserverOptionsCustom // TODO
|
|
175
|
+
): readonly [
|
|
176
|
+
ComputedRef<Result.Result<A, E>>,
|
|
177
|
+
ComputedRef<A | undefined>,
|
|
178
|
+
(options?: RefetchOptions) => Effect<QueryObserverResult<A, KnownFiberFailure<E>>>,
|
|
179
|
+
UseQueryReturnType<any, any>
|
|
180
|
+
]
|
|
181
|
+
function useSafeQuery<Arg, E, A>(
|
|
182
|
+
self: {
|
|
183
|
+
handler: (arg: Arg) => Effect<A, E, R>
|
|
184
|
+
mapPath: (arg: Arg) => string
|
|
185
|
+
name: string
|
|
186
|
+
},
|
|
187
|
+
arg: Arg | WatchSource<Arg>,
|
|
188
|
+
options?: QueryObserverOptionsCustom // TODO
|
|
189
|
+
): readonly [
|
|
190
|
+
ComputedRef<Result.Result<A, E>>,
|
|
191
|
+
ComputedRef<A | undefined>,
|
|
192
|
+
(options?: RefetchOptions) => Effect<QueryObserverResult<A, KnownFiberFailure<E>>>,
|
|
193
|
+
UseQueryReturnType<any, any>
|
|
194
|
+
]
|
|
195
|
+
function useSafeQuery(
|
|
196
|
+
self: any,
|
|
197
|
+
/*
|
|
198
|
+
q:
|
|
199
|
+
| {
|
|
200
|
+
handler: (
|
|
201
|
+
req: I
|
|
202
|
+
) => Effect<
|
|
203
|
+
A,
|
|
204
|
+
E,
|
|
205
|
+
R
|
|
206
|
+
>
|
|
207
|
+
mapPath: (req: I) => string
|
|
208
|
+
name: string
|
|
209
|
+
}
|
|
210
|
+
| {
|
|
211
|
+
handler: Effect<
|
|
212
|
+
A,
|
|
213
|
+
E,
|
|
214
|
+
R
|
|
215
|
+
>
|
|
216
|
+
mapPath: string
|
|
217
|
+
name: string
|
|
218
|
+
},
|
|
219
|
+
*/
|
|
220
|
+
argOrOptions?: any,
|
|
221
|
+
options?: any
|
|
222
|
+
) {
|
|
223
|
+
return Effect.isEffect(self.handler)
|
|
224
|
+
? useSafeQuery_(self, undefined, argOrOptions)
|
|
225
|
+
: useSafeQuery_(self, argOrOptions, options)
|
|
226
|
+
}
|
|
227
|
+
return useSafeQuery
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
|
231
|
+
export interface MakeQuery2<R> extends ReturnType<typeof makeQuery2<R>> {}
|