-
-
Notifications
You must be signed in to change notification settings - Fork 80
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix SSR issues #94 & #95 & (somewhat incidentally) bug #91 #97
Conversation
Btw, I believe this PR is ready for review and merging. This fixes the essential problem of #91 & two other issues and we can add the new |
@zenflow this looks good for me and appears to work in the examples, so that's good! That being said, some things are a bit out of my wheelhouse. I'm wondering if someone else can review this as well before we merge. @elie222? @mattiasewers? as for the |
The downside of normalizing by default is making "raw" queries just a tiny bit not as nice:
I don't actually have much of a use for "raw" queries or a "raw" cache mode right now, but I think we should fully preserve it since I could see it being useful in some situations, maybe debugging, to completely circumvent all the crazy things we're doing in our models. |
Actually, I can't really imagine any uses for "fully raw" queries at all.. even for debugging because I can see the network response in chrome devtools.. and obviously even that would not have been enough to make the optimization. When someone passes |
@chrisdrackett I must agree now that there's no need for adding an option, and we can just always keep a normalized cache. I can add the I will do that soon and commit it in this PR if it hasn't already been reviewed & merged. See #97 (comment) |
Made one major fixup: bc7da9b Fixup 00a836, in deflate(), only remove props of root type objects. If we removed props of objects of types that are known but not root (as my code was doing before), then we would never get them back (in most cases, i.e. unless you've saved the instance in the store yourself) because |
00a836 is a typo. It should be 00a8366. |
@zenflow Good job! I've gone through everything and nothing seems to break tests, types or examples. @chrisdrackett This can be merged whenever you see fit |
@chrisdrackett do you think this could be merged? (I don't care when it's released) I prefer to do the normalizing __queryCache bit in a follow-up PR if that's ok. Also I think it still needs a bit of discussion first, see issue #99 which I just opened to carry on the discussion. |
Yeah, lets get it merged and I'll work on getting a release cut later this week! |
Update README in regards to the new `noSsr` query option from PR #97
I started working on fixing #94 with my proposed solution (force fetchPolicy to 'cache-first' when on server or first render on client, and render+wait repeatedly in getDataFromTree) but found that getDataFromTree was still entering an infinite loop, since
store.query()
still pushes a promise (to store.__promises) when it's a cache hit (i.e. just getting the results from the cache, synchronously).So it was necessary to rework the control-flow of the
Query
class, so that we onlystore.pushPromise()
when there is some actual async work to do, and otherwise just set the results (data
orerror
) and thepromise
(which is already settled). The current code in master follows a shared path of execution once it has data, regardless of whether it is from the cache or from a fresh response (and with no use of a param/flag to indicate which). That is also the cause #91. I separated out two execution pathsfetchResults
&useCachedResults
, and simplified the async control-flow (I have never found it helpful to pass around a promise'sresolve
&reject
handlers. There is a reason they are only meant to be called inside the promises callback, as innew Promise(callback)
). Instead of repeating the problematic code in the newuseCachedResults
path, there I put thedata
through a newstore.deflate
method (removes data properties from objects of known types) before putting it throughstore.merge
(only if query is not "raw"). This is all done in 00a8366.I didn't make the 2nd step (see #91) of removing the (above mentioned) data properties of known types from the
__queryCache
(which would be awesome) because thequery
method can be called with theraw
option, and that will need the full, inflated (un-deflate
d) data to be in the cache. To deal with that I propose a new option for theRootStore
constructor:cacheMode: "raw" | "normalized"
to indicate how you want your data cached. With 'raw' things behave exactly as they do already. With 'normalized', the data is put throughstore.deflate()
before saving to __queryCache. The data no longer needs to bedeflate
d just beforemerge
ing. If query is called withraw: true
, the data should be put through a newstore.inflate()
method before being returned, which will add the data props back to objects of known types. This way we can save many bytes in __queryCache (for SSR or serializing/deserializing for localStorage) while keeping first-class support for "raw" queries.@chrisdrackett @mattiasewers What do you think of my proposed
cacheMode: "raw" | "normalized"
option? We could default it to "raw" for now, since that is the current behavior, and in the version 1 release switch it to "normalized" since that is (I imagine) what people would want in most cases for performance.The other commits in this PR are pretty straight-forward I think.
noSsr: boolean
query option to skip fetching query on server side