Closed dkzlv closed 7 months ago
@martinmckenna Hey! It would be helpful if you could have a look at this. I'm still brewing the error handling, but it will be ready for 0.3.0 release.
I touch a bunch of things that may break your code:
batched
computed store to run less fetchers in situations where you have multiple key dependencies. So when you update 3 atom dependencies one by one, it will not result in 3 fetcher calls but 1.refetch
into revalidate
mutate
function can only run with concurrency 1. So all subsequent calls to mutate
function while it hasn't finished will result in void calls.@eta-orionis Hey there! I'm probably gonna close your PR #35 in favor of this one. Sorry about that.
But I'd love to hear your opinion on the way I implemented automatic error handling in here.
I'm gonna release this after the weekend, when I test it in a real-life project of my own.
@dkzlv awesome can't wait to try it out!
can we add better TS for the error handler. I'd like to be able to type it properly, rather than it being any
@martinmckenna
can we add better TS for the error handler. I'd like to be able to type it properly, rather than it being any
Yeah, you're absolutely right. Swapped those for unknown
instead. Since we do not know what type it would be (it can be thrown from a fetcher function whose exception can be anything, even throw "hey"
) the only 2 ways I can think of to properly type them would be to either manually cast them or use something like type assertions/guards.
@dkzlv yep agreed. i guess what i was getting at though is createMutatorStore
already takes an optional error type as the 3rd type argument. can we just pass that along to the onError
handler?
i'm on my phone but line 331 in main.ts is where i'm talking about
also looking at this diff, it is still intentional that we're going to have to check for the existence of an error, before going down our success rotue?
Something like
const { mutate } = useStore($postThing({ onError: () => showToastNotification("something went wrong") }))
const handleClick = () => {
await mutate();
const hasError = !!$postThing?.value?.error
if(!hasError) {
// success path
}
}
@martinmckenna Yeah, we briefly discussed it in #27. Specifically, I outlined the motivation in this message. I'm not sure what could be done differently here from the perspective of the library. Open to suggestions though!
If that's something you're willing to simplify, keep in mind you can always solve this in userland by writing a custom hook, something along the lines of:
const useMutation = ($store) => {
const { mutate } = useStore($store);
return useCallback(
async (...args) => {
const res = await mutate(...args);
if ($store.value?.error) throw $store.value.error;
return res;
},
[mutate]
);
};
This would allow you to treat mutate
as a typical async function that throws an error.
- nanostores > 0.10 is required
>=0.10
?
Features/fixes:
mutate
function until it resolves.onError
to a single Mutation Store instance.cacheLifetime
. Make it so thatdedupeTime
is responsible for calls of the fetcher function, whereascacheLifetime
is responsible for the… lifetime of the cache. Meaning, it will be put indata
even if it's stale, up tocacheLifetime
time.cache
variable set on the context. Fixes #15 and probably makes #19 possible.Docs:
Breaking changes:
refetchOn*
settings are all renamed torevalidateOn*