Skip to content

Commit 61d2646

Browse files
committed
feat: added support of mutation returning EMPTY
1 parent 366990e commit 61d2646

File tree

1 file changed

+31
-15
lines changed

1 file changed

+31
-15
lines changed

src/lib/queries/client/mutations/mutation/executeMutation.ts

+31-15
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,11 @@ import {
99
iif,
1010
catchError,
1111
scan,
12-
shareReplay
12+
shareReplay,
13+
isEmpty,
14+
tap,
15+
share,
16+
ignoreElements
1317
} from "rxjs"
1418
import { type MutationOptions, type MutationState } from "./types"
1519
import { makeObservable } from "../../utils/makeObservable"
@@ -43,16 +47,16 @@ export const executeMutation = <
4347

4448
const mutationFn = options.mutationFn ?? defaultFn
4549

46-
const onOptionMutate$ = iif(
47-
() => isPaused,
48-
of(state.context),
49-
makeObservable(
50-
// eslint-disable-next-line @typescript-eslint/promise-function-async
51-
() => options.onMutate?.(variables) ?? undefined
52-
)
50+
const contextFromOnMutate$ = makeObservable(
51+
// eslint-disable-next-line @typescript-eslint/promise-function-async
52+
() => options.onMutate?.(variables) ?? undefined
5353
)
5454

55-
const onMutate$ = onOptionMutate$.pipe(shareReplay(1))
55+
const rawContext$ = of(state.context)
56+
57+
const context$ = iif(() => isPaused, rawContext$, contextFromOnMutate$).pipe(
58+
shareReplay(1)
59+
)
5660

5761
type QueryState = Omit<Partial<LocalState>, "data"> & {
5862
// add layer to allow undefined as mutation result
@@ -78,15 +82,27 @@ export const executeMutation = <
7882
)
7983
}
8084

81-
const queryRunner$ = onMutate$.pipe(
85+
const queryRunner$ = context$.pipe(
8286
switchMap((context) => {
8387
const fn$ =
8488
typeof mutationFn === "function"
8589
? // eslint-disable-next-line @typescript-eslint/promise-function-async
8690
makeObservable(() => mutationFn(variables))
8791
: mutationFn
8892

89-
const finalFn$ = fn$.pipe(
93+
const sharedFn$ = fn$.pipe(share())
94+
95+
const completeWithoutValue$ = sharedFn$.pipe(
96+
isEmpty(),
97+
tap((isEmppty) => {
98+
if (isEmppty) {
99+
throw new Error("Mutation completed without any emission (EMPTY)")
100+
}
101+
}),
102+
ignoreElements()
103+
)
104+
105+
const finalFn$ = merge(sharedFn$, completeWithoutValue$).pipe(
90106
map(
91107
(data): QueryState => ({
92108
result: {
@@ -152,7 +168,7 @@ export const executeMutation = <
152168
const mutation$ = merge(
153169
initState$,
154170
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
155-
onMutate$.pipe(map((context) => ({ context }) as Partial<LocalState>)),
171+
context$.pipe(map((context) => ({ context }) as Partial<LocalState>)),
156172
queryRunner$.pipe(
157173
switchMap(({ result: mutationData, error, ...restState }) => {
158174
if (!mutationData && !error)
@@ -161,7 +177,7 @@ export const executeMutation = <
161177
...restState
162178
} as Partial<LocalState>)
163179

164-
const onSuccess$ = error
180+
const success$ = error
165181
? of(null)
166182
: makeObservable(() =>
167183
options.onSuccess?.(
@@ -180,11 +196,11 @@ export const executeMutation = <
180196
)
181197
)
182198

183-
const onSettled$ = onOptionSettled$.pipe(
199+
const settled$ = onOptionSettled$.pipe(
184200
catchError((error) => (mutationData ? of(mutationData) : of(error)))
185201
)
186202

187-
const result$ = concat(onSuccess$, onSettled$).pipe(
203+
const result$ = concat(success$, settled$).pipe(
188204
toArray(),
189205
map(() =>
190206
error

0 commit comments

Comments
 (0)