Skip to content

Commit

Permalink
feat: added filter status
Browse files Browse the repository at this point in the history
  • Loading branch information
mbret committed Dec 3, 2023
1 parent ee33303 commit 1b0fe5a
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 29 deletions.
19 changes: 13 additions & 6 deletions src/lib/queries/client/mutations/MutationClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -227,11 +227,9 @@ export class MutationClient {
mutation.stateSubject.pipe(map(() => mutation))
)

const mutationsOnStateUpdate$ = combineLatest(mutationsOnStateUpdate)

return mutationsOnStateUpdate.length === 0
? of([])
: mutationsOnStateUpdate$
: combineLatest(mutationsOnStateUpdate)
}),
map(reduceByNumber),
distinctUntilChanged()
Expand Down Expand Up @@ -262,9 +260,18 @@ export class MutationClient {
.map((mutation) => finalSelect(mutation))

const value$ = this.mutationsSubject.pipe(
map((mutations) =>
mutations.filter(predicate).map((mutation) => finalSelect(mutation))
),
switchMap((mutations) => {
const mutationsOnStateUpdate = mutations.map((mutation) =>
mutation.stateSubject.pipe(
filter(() => predicate(mutation)),
map(() => finalSelect(mutation))
)
)

return mutationsOnStateUpdate.length === 0
? of([])
: combineLatest(mutationsOnStateUpdate)
}),
distinctUntilChanged(shallowEqual)
)

Expand Down
22 changes: 15 additions & 7 deletions src/lib/queries/client/mutations/filters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,23 @@ import { type MutationFilters } from "./types"

export const createPredicateForFilters = <TData>({
mutationKey,
status,
predicate
}: MutationFilters<TData> = {}) => {
const defaultPredicate: MutationFilters<TData>["predicate"] = ({
options
}) =>
mutationKey
? // @todo optimize
serializeKey(options.mutationKey) === serializeKey(mutationKey)
: true
const defaultPredicate: MutationFilters<TData>["predicate"] = (mutation) => {
if (
mutationKey !== undefined &&
// @todo optimize
serializeKey(mutation.options.mutationKey) !== serializeKey(mutationKey)
) {
return false
}

if (status && mutation.stateSubject.getValue().status !== status)
return false

return true
}
const finalPredicate = predicate ?? defaultPredicate

return finalPredicate
Expand Down
19 changes: 9 additions & 10 deletions src/lib/queries/react/mutations/useIsMutating.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,18 @@ import { skip } from "rxjs"
import { type MutationFilters } from "../../client/mutations/types"
import { useLiveRef } from "../../../utils/useLiveRef"
import { type QueryClient } from "../../client/createClient"
import { createPredicateForFilters } from "../../client/mutations/filters"

export const useIsMutating = <TData>(
{ mutationKey, predicate }: MutationFilters<TData> = {},
filters: MutationFilters<TData> = {},
queryClient?: QueryClient
) => {
const defaultQueryClient = useQueryClient({ unsafe: !!queryClient })
const finalQueryClient = queryClient?.client ?? defaultQueryClient
const { mutationKey } = filters
const mutationKeyRef = useLiveRef(mutationKey)
const serializedKey = mutationKey ? serializeKey(mutationKey) : undefined
const predicateRef = useLiveRef(predicate)
const filtersRef = useLiveRef(filters)

const runningMutations$ = useMemo(() => {
const { lastValue, value$ } =
Expand All @@ -24,14 +26,11 @@ export const useIsMutating = <TData>(
/**
* We have to delay function call so that we don't need a stable predicate function
*/
predicate: (mutation) =>
!predicateRef.current
? mutationKeyRef.current
? // @todo optimize
serializeKey(mutationKeyRef.current) ===
serializeKey(mutation.options.mutationKey)
: true
: predicateRef.current(mutation)
predicate: (mutation) => {
return filtersRef.current?.predicate
? filtersRef.current.predicate(mutation)
: createPredicateForFilters(filtersRef.current)(mutation)
}
})

return {
Expand Down
26 changes: 20 additions & 6 deletions src/lib/queries/react/mutations/useMutationState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,30 +8,44 @@ import {
import { useLiveRef } from "../../../utils/useLiveRef"
import { type Mutation } from "../../client/mutations/Mutation"
import { skip } from "rxjs"
import { serializeKey } from "../../client/keys/serializeKey"
import { createPredicateForFilters } from "../../client/mutations/filters"

export interface MutationStateOptions<TResult> {
filters?: MutationFilters<TResult>
export interface MutationStateOptions<TResult, TData> {
filters?: MutationFilters<TData>
select?: (mutation: Mutation<any>) => TResult
}

export const useMutationState = <TResult = MutationState>({
export const useMutationState = <TData, TResult = MutationState>({
filters,
select
}: MutationStateOptions<TResult> = {}): TResult[] => {
}: MutationStateOptions<TResult, TData> = {}): TResult[] => {
const queryClient = useQueryClient()
const { mutationKey, status } = filters ?? {}
const filtersRef = useLiveRef(filters)
const serializedKey = mutationKey ? serializeKey(mutationKey) : undefined
const selectRef = useLiveRef(select)

const { value$, lastValue } = useMemo(() => {
const { lastValue, value$ } = queryClient.mutationClient.mutationState({
const { lastValue, value$ } = queryClient.mutationClient.mutationState<
TData,
TResult
>({
filters: {
predicate: (mutation) => {
return filtersRef.current?.predicate
? filtersRef.current.predicate(mutation)
: createPredicateForFilters(filtersRef.current)(mutation)
}
},
select: (mutation) =>
selectRef.current
? selectRef.current(mutation)
: (mutation.stateSubject.getValue() as TResult)
})

return { lastValue, value$: value$.pipe(skip(1)) }
}, [queryClient])
}, [queryClient, serializedKey, status])

return useObserve(value$) ?? lastValue
}

0 comments on commit 1b0fe5a

Please sign in to comment.