nanostores / query

⚡️ Powerful data fetching library for Nano Stores. TS/JS. Framework agnostic.
MIT License
229 stars 10 forks source link

WIP for release/0.3.0 #36

Closed dkzlv closed 7 months ago

dkzlv commented 7 months ago

Features/fixes:

Docs:

Breaking changes:

dkzlv commented 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:

  1. nanostores > 0.10 is required. We now use the new 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.
  2. renaming refetch into revalidate
  3. introducing infinite cache by default (akin to swr)
  4. 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.
dkzlv commented 7 months ago

@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.

martinmckenna commented 7 months ago

@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

dkzlv commented 7 months ago

@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.

martinmckenna commented 7 months ago

@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

martinmckenna commented 7 months ago

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
  }
}
dkzlv commented 7 months ago

@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.

lovio commented 6 months ago
  1. nanostores > 0.10 is required

>=0.10?