saasquatch / bunshi

Molecule pattern for jotai, valtio, zustand, nanostores, xstate, react and vue
https://www.bunshi.org/
MIT License
211 stars 14 forks source link

Infinite execution when using jotai-apollo atoms #69

Open lazakrisz opened 1 month ago

lazakrisz commented 1 month ago

hello πŸ‘‹ , first of amazing library thank you so much. as I was using the lib I noticed that whenever I create an atom (from jotai-apollo) within a molecule it keeps infinitely running (maybe related to dependencies?)

Couple other things that I have tried:

here is a stackblitz with the issue: https://stackblitz.com/edit/vitejs-vite-xaz7lw?file=src%2FApp.tsx if you uncomment the following part:

{/* <ScopeProvider scope={TestScope}>
        <InfiniteLoadingList />
  </ScopeProvider> */}

you should see continuous console logs from the molecule: image

if there is any way I can help please let me know (ex.: pr, tests etc...), although I'll probably require some assistance πŸ™ .

loganvolkers commented 1 month ago

Thanks for the reproduction @lazakrisz and the cases where it fails and where it doesn't. That's really helpful!

This sounds like a classic integration testing problem. jotai-apollo and bunshi may both be operating the right way, but not when paired together.

image

I don't know what may be causing this.

The biggest help you could do is to add some test cases to ScopeProvider.test.tsx. If you can make it fail, then open a draft PR with the failing tests, and I can help figure out how to make them pass.

The Void scopes can be used to create unique molecules test might be a good foundation. It uses createLifecycleUtils to make sure a molecule isn't created more times than needed, which we want to be 1 but in the case you've created is Infinite.

lazakrisz commented 1 month ago

thank you @loganvolkers , will start to investigate this! πŸ”

lazakrisz commented 1 month ago

Update as I was investigating this:

by default each async atom in jotai uses Suspense in order to suspend until the data is available. (source: https://jotai.org/docs/utilities/async) If the Suspense Boundary is wrapping the component that is suspending while the promise is pending (see here: https://github.com/saasquatch/bunshi/blob/7594a71fba744b0519ae5a9cc91e005422aaefb1/src/react/ScopeProvider.test.tsx#L570) then all is good βœ… . However if the Suspense boundary is wrapping the entire application (in my Apps case) or in case of this test (see here: https://github.com/saasquatch/bunshi/blob/7594a71fba744b0519ae5a9cc91e005422aaefb1/src/react/ScopeProvider.test.tsx#L635) then the Suspense boundary is never unmounted (see here: https://github.com/saasquatch/bunshi/blob/7594a71fba744b0519ae5a9cc91e005422aaefb1/src/react/ScopeProvider.test.tsx#L684). Furthermore I have also forked and updated the Stackblitz to showcase this same behaviour: https://stackblitz.com/edit/vitejs-vite-eqmpey?file=src%2FApp.tsx I have added the new code within the LoadableList.

I also want to mention that there are currently two solutions to this problem from an application perspective:

I believe both are valid solutions, let me know what you think @loganvolkers πŸ‘