You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Under certain conditions (all of which are a bit confusing) a different key is generated (by keyDocument()) given the same DocumentNode.
This is noticeable in a next-urql app when we see unexpected cache misses during either final server-side render (Error: ReactDOMServer does not yet support Suspense.) or client-side rehydration (since cached data isn't found, React warns about unexpected dom nodes, and data is fetched over network again).
touch pages/index.tsx, or make a trivial change to it's contents like <h1> to <h2>
Wait for recompile & then refresh the browser
Observe error rendering server-side: Error: ReactDOMServer does not yet support Suspense.
Refresh browser (or allow it to automatically refresh) until a page loads without the above error
Observe console warning & network request to graphql server
Analysis
To debug I built packages/core with hash() modified to console.log it's input (unique graphql query string) & output (hash number).
I found that, for my single query, either of two different query strings would be hashed: "query MyQuery { ... }" (bare) or "# MyQuery\nquery MyQuery { ... }" (prefixed), resulting in a different hash number.
I see a problem that stringifyDocument() is not idempotent. When first called with a DocumentNode that has no .loc property, it adds the .loc property and returns only the bare query string. The next time it's called with the exact same DocumentNode object, since the .loc property is now present, the result will be prefixed with operation name if available.
TBH It was pretty confusing, because the code looks ok at first glance - you would think stringifyDocument() wouldn't be called twice with the same object anyway, due to short-circuiting in keyDocument() when that object has a .__key property defined.
But I looked closer and noticed that this .__key property is only added to the document objects that are being kept in the docs Map. Document objects that never get added to the docs Map (because another identical document object was "keyed" first) never have their .__key property defined, and are therefore stringified & hashed on each call to keyDocument().
The text was updated successfully, but these errors were encountered:
Under certain conditions (all of which are a bit confusing) a different key is generated (by
keyDocument()
) given the same DocumentNode.This is noticeable in a next-urql app when we see unexpected cache misses during either final server-side render (
Error: ReactDOMServer does not yet support Suspense.
) or client-side rehydration (since cached data isn't found, React warns about unexpected dom nodes, and data is fetched over network again).versions are the latest as of writing this:
Uses next-urql's default exchanges
Steps to reproduce
yarn next dev
touch pages/index.tsx
, or make a trivial change to it's contents like<h1>
to<h2>
Error: ReactDOMServer does not yet support Suspense.
Analysis
To debug I built
packages/core
withhash()
modified toconsole.log
it's input (unique graphql query string) & output (hash number).I found that, for my single query, either of two different query strings would be hashed:
"query MyQuery { ... }"
(bare) or"# MyQuery\nquery MyQuery { ... }"
(prefixed), resulting in a different hash number.See in
stringifyDocument()
where the query string gets prefixed.I see a problem that
stringifyDocument()
is not idempotent. When first called with a DocumentNode that has no.loc
property, it adds the.loc
property and returns only the bare query string. The next time it's called with the exact same DocumentNode object, since the.loc
property is now present, the result will be prefixed with operation name if available.TBH It was pretty confusing, because the code looks ok at first glance - you would think
stringifyDocument()
wouldn't be called twice with the same object anyway, due to short-circuiting inkeyDocument()
when that object has a.__key
property defined.But I looked closer and noticed that this
.__key
property is only added to the document objects that are being kept in thedocs
Map. Document objects that never get added to thedocs
Map (because another identical document object was "keyed" first) never have their.__key
property defined, and are therefore stringified & hashed on each call tokeyDocument()
.The text was updated successfully, but these errors were encountered: