// noinspection JSIgnoredPromiseFromCall export const useCreateCharacter = defineMutation(() => { const queryCache = useQueryCache() // noinspection JSUnusedLocalSymbols const { mutate, ...mutation } = useMutation({ onMutate({ character, optimisticUpdates }) { if (optimisticUpdates) { // save the current character list and options const oldCharacterList = queryCache.getQueryData(characterListQuery.key) const oldOptions = queryCache.getQueryData(characterOptionsQuery.key) // create the new character const newCharacter = { ...character, id: Number.MAX_SAFE_INTEGER } console.log("[useCreateCharacter] [onMutate]", newCharacter) // create a copy of the current character list with the new character const newCharacterList = [...oldCharacterList || [], newCharacter] // calculate new character options const newOptions = getCharacterOptions(newCharacterList) // update the caches with the new character list, options, and character queryCache.setQueryData(characterListQuery.key, newCharacterList) queryCache.setQueryData(characterOptionsQuery.key, newOptions) // cancel (without refreshing) queries depending on the character list queryCache.cancelQueries({ key: characterListQuery.key }) // pass the old and new character list, options, and the new character to the other hooks return { oldCharacterList, newCharacterList, oldOptions, newCharacter } } }, mutation: ({ character, optimisticUpdates = true }) => { console.log("[useCreateCharacter] [mutation]", character) return useEmit("character:create", character) }, // on both error and success onSettled(_data, _errors, { optimisticUpdates }, { newCharacter }) { console.log("[useCreateCharacter] [onSettled]") if (optimisticUpdates) { // invalidate queries to refetch the new data queryCache.invalidateQueries({ key: characterListQuery.key }) // newCharacter can be undefined if the onMutate hook fails if (newCharacter) { // directly cancel queries with a temp id and remove cache entry queryCache.getEntries({ key: characterByIdQuery(newCharacter.id).key, exact: true }) .map((entry) => { queryCache.cancel(entry) queryCache.remove(entry) }) } } }, onError(error, { optimisticUpdates }, { oldCharacterList, newCharacterList, oldOptions }) { // before applying the rollback, check if the value in the cache is the same // in case the cache was updated by another mutation or query if (optimisticUpdates && newCharacterList === queryCache.getQueryData(characterListQuery.key)) { console.log("[useCreateCharacter] [onError] [rollback]") queryCache.setQueryData(characterListQuery.key, oldCharacterList) queryCache.setQueryData(characterOptionsQuery.key, oldOptions) } // handle the error console.error("[useCreateCharacter] [onError]", error) }, onSuccess(character, { optimisticUpdates }, { oldCharacterList }) { console.log("[useCreateCharacter] [onSuccess]", character) if (optimisticUpdates) { // create a copy of oldCharacterList with newly returned character const characterList = [...oldCharacterList || [], character] queryCache.setQueryData(characterListQuery.key, characterList) } } }) return { ...mutation, createCharacter: (character) => mutate({ character, optimisticUpdates: true }), createCharacterFromEvent: (character) => mutate({ character, optimisticUpdates: false }) } })