simplify petAppearance cache lookup, remove hacks

I think I got all up in my head about direct queries for this one, because of a previous implementation I had in mind, and I forgot that I could just query species and color from the cache by reference without breaking out of the API provided to the cache function!

I also learned in here that I _can_ look up things from the root by doing `readField("allSpecies", {__ref: "ROOT_QUERY"})`, which I struggled to figure out my previous time. I couldn't figure out how to read an uncached field with arguments (I couldn't quite figure out how to build a proper FieldNode, and passing the string form seemed to provide `null` to the `species` cache field reader), but it's probably doable!
This commit is contained in:
Emi Matchu 2020-09-05 16:37:17 -07:00
parent ee45ae880e
commit 88862f9ce7

View file

@ -1,7 +1,6 @@
import { ApolloClient, createHttpLink, InMemoryCache } from "@apollo/client"; import { ApolloClient, createHttpLink, InMemoryCache } from "@apollo/client";
import { setContext } from "@apollo/client/link/context"; import { setContext } from "@apollo/client/link/context";
import { createPersistedQueryLink } from "apollo-link-persisted-queries"; import { createPersistedQueryLink } from "apollo-link-persisted-queries";
import gql from "graphql-tag";
import cachedZones from "./cached-data/zones.json"; import cachedZones from "./cached-data/zones.json";
@ -48,49 +47,25 @@ const typePolicies = {
// case we can reuse the standard color appearance if we already have // case we can reuse the standard color appearance if we already have
// it! This helps for fast loading when switching between standard // it! This helps for fast loading when switching between standard
// colors. // colors.
const { speciesId, colorId } = args; const { speciesId, colorId } = args;
const speciesStandardBodyId = readField(
// HACK: I can't find a way to do bigger-picture queries like this from "standardBodyId",
// Apollo's cache field reader API. Am I missing something? I toReference({ __typename: "Species", id: speciesId })
// don't love escape-hatching to the client like this, but... );
let cachedData; const colorIsStandard = readField(
try { "isStandard",
cachedData = hackyEscapeHatchClient.readQuery({ toReference({ __typename: "Color", id: colorId })
query: gql` );
query CacheLookupForItemAppearanceReader( if (speciesStandardBodyId == null || colorIsStandard == null) {
$speciesId: ID!
$colorId: ID!
) {
species(id: $speciesId) {
standardBodyId
}
color(id: $colorId) {
isStandard
}
}
`,
variables: { speciesId, colorId },
});
} catch (e) {
// Some errors are expected while setting up the cache... not sure
// how to distinguish from Real errors. Just gonna ignore them all
// for now!
return undefined;
}
if (!cachedData) {
// This is an expected case while the page is loading. // This is an expected case while the page is loading.
return undefined; return null;
} }
const { species, color } = cachedData; if (colorIsStandard) {
if (color.isStandard) {
const itemId = readField("id"); const itemId = readField("id");
const bodyId = species.standardBodyId;
return toReference({ return toReference({
__typename: "ItemAppearance", __typename: "ItemAppearance",
id: `item-${itemId}-body-${bodyId}`, id: `item-${itemId}-body-${speciesStandardBodyId}`,
}); });
} else { } else {
return undefined; return undefined;
@ -142,17 +117,11 @@ for (const zone of cachedZones) {
* apolloClient is the global Apollo Client instance we use for GraphQL * apolloClient is the global Apollo Client instance we use for GraphQL
* queries. This is how we communicate with the server! * queries. This is how we communicate with the server!
*/ */
let hackyEscapeHatchClient = null; const buildClient = (getAuth0) =>
const buildClient = (getAuth0) => { new ApolloClient({
const client = new ApolloClient({
link: buildAuthLink(getAuth0).concat(persistedQueryLink).concat(httpLink), link: buildAuthLink(getAuth0).concat(persistedQueryLink).concat(httpLink),
cache: new InMemoryCache({ typePolicies }).restore(initialCache), cache: new InMemoryCache({ typePolicies }).restore(initialCache),
connectToDevTools: true, connectToDevTools: true,
}); });
hackyEscapeHatchClient = client;
return client;
};
export default buildClient; export default buildClient;