// noinspection JSIgnoredPromiseFromCall export const useUpdateCharacter = defineMutation(() => { const queryCache = useQueryCache() // noinspection JSUnusedLocalSymbols const { mutate, ...mutation } = useMutation({ onMutate({ id, updates, optimisticUpdates }) { if (optimisticUpdates) { // save the current character and character list const oldCharacterList = queryCache.getQueryData(characterListQuery.key) // find the index of the mutated character const characterIndex = _findIndex(oldCharacterList, { id }) let oldOptions, oldCharacter, newCharacter, newCharacterList if (characterIndex >= 0) { // save the options and character oldOptions = queryCache.getQueryData(characterOptionsQuery.key) oldCharacter = oldCharacterList[characterIndex] // create the new character newCharacter = { ...oldCharacter, ...updates } // create a copy of the character list with the updated character newCharacterList = oldCharacterList.toSpliced(characterIndex, 1, newCharacter) // calculate new character options const newOptions = getCharacterOptions(newCharacterList) // update caches queryCache.setQueryData(characterListQuery.key, newCharacterList) queryCache.setQueryData(characterOptionsQuery.key, newOptions) // cancel (without refreshing) queries depending on the character queryCache.cancelQueries({ key: characterListQuery.key }) queryCache.cancelQueries({ key: characterByIdQuery(id).key }) } // pass the old and new character, and character lists to the other hooks return { oldCharacter, newCharacter, oldCharacterList, newCharacterList, oldOptions } } }, mutation: ({ id, updates, optimisticUpdates = true }) => useEmit("character:update", id, updates), onSettled(_data, _error, { id, optimisticUpdates }, { newCharacter }) { // invalidate the queries to refetch the new data if (!optimisticUpdates || newCharacter) { queryCache.invalidateQueries({ key: characterListQuery.key }) queryCache.invalidateQueries({ key: characterByIdQuery(id).key }) } }, onError( error, { id, optimisticUpdates }, { oldCharacter, oldCharacterList, oldOptions, newCharacterList } ) { // before applying the rollback, check if the values in the cache are the same // in case the cache was updated by another mutation or query if ( optimisticUpdates && newCharacterList === queryCache.getQueryData(characterListQuery.key) ) { queryCache.setQueryData(characterListQuery.key, oldCharacterList) queryCache.setQueryData(characterOptionsQuery.key, oldOptions) queryCache.setQueryData(characterByIdQuery(id).key, oldCharacter) } // handle the error console.error("[useUpdateCharacter] [onError]", error) }, onSuccess() {} }) return { ...mutation, updateCharacter: (id, updates) => mutate({ id, updates, optimisticUpdates: true }), updateCharacterFromEvent: (id, updates) => mutate({ id, updates, optimisticUpdates: false }) } })