|
|
@@ -3,61 +3,70 @@
|
|
|
export const useCreateCharacter = defineMutation(() => {
|
|
|
const queryCache = useQueryCache()
|
|
|
|
|
|
+ // noinspection JSUnusedLocalSymbols
|
|
|
const { mutate, ...mutation } = useMutation({
|
|
|
- onMutate(character) {
|
|
|
- // 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
|
|
|
- }
|
|
|
+ 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)
|
|
|
+ console.log("[useCreateCharacter] [onMutate]", newCharacter)
|
|
|
|
|
|
- // create a copy of the current character list with the new character
|
|
|
- const newCharacterList = [...oldCharacterList || [], 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)
|
|
|
+ // 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)
|
|
|
+ // 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 })
|
|
|
+ // 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 }
|
|
|
+ // pass the old and new character list, options, and the new character to the other hooks
|
|
|
+ return { oldCharacterList, newCharacterList, oldOptions, newCharacter }
|
|
|
+ }
|
|
|
},
|
|
|
|
|
|
- mutation: (character) => {
|
|
|
+ mutation: ({ character, optimisticUpdates = true }) => {
|
|
|
console.log("[useCreateCharacter] [mutation]", character)
|
|
|
|
|
|
return useEmit("character:create", character)
|
|
|
},
|
|
|
|
|
|
// on both error and success
|
|
|
- onSettled(_data, _errors, _vars, { newCharacter }) {
|
|
|
+ onSettled(_data, _errors, { optimisticUpdates }, { newCharacter }) {
|
|
|
console.log("[useCreateCharacter] [onSettled]")
|
|
|
|
|
|
- // invalidate queries to refetch the new data
|
|
|
- queryCache.invalidateQueries({ key: characterListQuery.key })
|
|
|
-
|
|
|
- // newCharacter can be undefined if the onMutate hook fails
|
|
|
- if (newCharacter) {
|
|
|
- queryCache.cancelQueries({ key: characterByIdQuery(newCharacter.id).key })
|
|
|
- queryCache.remove({ key: characterByIdQuery(newCharacter.id).key })
|
|
|
+ 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, _vars, { oldCharacterList, newCharacterList, oldOptions }) {
|
|
|
+ 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 (newCharacterList === queryCache.getQueryData(characterListQuery.key)) {
|
|
|
+ if (optimisticUpdates && newCharacterList === queryCache.getQueryData(characterListQuery.key)) {
|
|
|
console.log("[useCreateCharacter] [onError] [rollback]")
|
|
|
|
|
|
queryCache.setQueryData(characterListQuery.key, oldCharacterList)
|
|
|
@@ -68,24 +77,20 @@ export const useCreateCharacter = defineMutation(() => {
|
|
|
console.error("[useCreateCharacter] [onError]", error)
|
|
|
},
|
|
|
|
|
|
- onSuccess(character, _vars, { newCharacter }) {
|
|
|
+ onSuccess(character, { optimisticUpdates }, { oldCharacterList }) {
|
|
|
console.log("[useCreateCharacter] [onSuccess]", character)
|
|
|
|
|
|
- // update character list with the newly created character returned by the api
|
|
|
- const characterList = queryCache.getQueryData(characterListQuery.key) || []
|
|
|
-
|
|
|
- // replace the character created in onMutate() with the one from the server
|
|
|
- const characterIndex = _findIndex(characterList, { id: newCharacter.id })
|
|
|
-
|
|
|
- if (characterIndex >= 0) {
|
|
|
- const characterListCopy = characterList.toSpliced(characterIndex, 1, character)
|
|
|
- queryCache.setQueryData(characterListQuery.key, characterListCopy)
|
|
|
+ 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)
|
|
|
+ createCharacter: (character) => mutate({ character, optimisticUpdates: true }),
|
|
|
+ createCharacterFromEvent: (character) => mutate({ character, optimisticUpdates: false })
|
|
|
}
|
|
|
})
|