| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596 |
- // 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 })
- }
- })
|