Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/query-optional-mode.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@effect-app/vue": minor
---

Add `mode: "optional"` overload for queries. When `mode: "optional"` is set, the `arg` must be a `WatchSource<Option<I>>`. The query is disabled (`enabled: false`) when the option is `None`, and enabled with the unwrapped value when `Some`.
56 changes: 47 additions & 9 deletions packages/vue/src/query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,16 @@ export const makeQuery = <R>(getRuntime: () => Context.Context<R>) => {
<I, A, E, Request extends Req, Name extends string>(
q: RequestHandlerWithInput<I, A, E, R, Request, Name>
): {
<TData = A>(
arg: WatchSource<Option.Option<I>>,
options: Omit<CustomUndefinedInitialQueryOptions<A, E, TData>, "enabled"> & { mode: "optional" }
): readonly [
ComputedRef<AsyncResult.AsyncResult<TData, E>>,
ComputedRef<TData | undefined>,
(options?: RefetchOptions) => Effect.Effect<QueryObserverResult<TData, CauseException<E>>>,
UseQueryDefinedReturnType<TData, CauseException<E>>
]

<TData = A>(
arg: I | WatchSource<I> | undefined,
options?: CustomUndefinedInitialQueryOptions<A, E, TData>
Expand Down Expand Up @@ -183,23 +193,42 @@ export const makeQuery = <R>(getRuntime: () => Context.Context<R>) => {
q: RequestHandlerWithInput<I, A, E, R, Request, Name>
) =>
<TData = A>(
arg: I | WatchSource<I> | undefined,
arg: I | WatchSource<I> | undefined | WatchSource<Option.Option<I>>,
// todo QueryKey type would be [string, ...string[]], but with I it would be [string, ...string[], I]
options?: any
// TODO
) => {
// we wrap into CauseException because we want to keep the full cause of the failure.
const runPromise = makeRunPromise(getRuntime())
const arr = arg
const req: { value: I } | undefined = !arg
? undefined
: typeof arr === "function"
? ({

let req: { value: I } | undefined
let callerOptions: any = options

if (options?.mode === "optional") {
const getOption: () => Option.Option<I> = typeof arr === "function"
? arr as () => Option.Option<I>
: () => (arr as { value: Option.Option<I> }).value
req = {
get value() {
return (arr as any)()
// getOrUndefined returns undefined when None, but queryFn is only called when enabled (Some)
return Option.getOrUndefined(getOption()) as I
}
})
: ref(arg) as any
}
const { mode: _mode, enabled: _enabled, ...rest } = options ?? {}
callerOptions = { ...rest, enabled: computed(() => Option.isSome(getOption())) }
} else {
req = !arg
? undefined
: typeof arr === "function"
? ({
get value() {
return (arr as any)()
}
})
: ref(arg) as any
}

const queryKey = makeQueryKey(q)
const projectionHash = (q as { queryKeyProjectionHash?: string }).queryKeyProjectionHash

Expand All @@ -215,7 +244,7 @@ export const makeQuery = <R>(getRuntime: () => Context.Context<R>) => {

const r = useTanstackQuery<A, CauseException<E>, TData>({
...defaultOptions,
...options,
...callerOptions,
retry: (retryCount, error) => {
if (error instanceof CauseException) {
if (!isHttpClientError(error.cause) && !S.is(ServiceUnavailableError)(error.cause)) {
Expand Down Expand Up @@ -274,6 +303,15 @@ export const makeQuery = <R>(getRuntime: () => Context.Context<R>) => {
<I, E, A, Request extends Req, Name extends string>(
self: RequestHandlerWithInput<I, A, E, R, Request, Name>
): {
<TData = A>(
arg: WatchSource<Option.Option<I>>,
options: Omit<CustomUndefinedInitialQueryOptions<A, CauseException<E>, TData>, "enabled"> & { mode: "optional" }
): readonly [
ComputedRef<AsyncResult.AsyncResult<TData, E>>,
ComputedRef<TData | undefined>,
(options?: RefetchOptions) => Effect.Effect<QueryObserverResult<TData, CauseException<E>>>,
UseQueryReturnType<any, any>
]
<TData = A>(
arg: I | WatchSource<I>,
options: CustomDefinedInitialQueryOptions<A, CauseException<E>, TData>
Expand Down
Loading