Skip to content

Commit

Permalink
Avoid using prototype objects as keys in QueryKeyMaker Maps.
Browse files Browse the repository at this point in the history
Fixes apollographql/react-apollo#2442.

This temporarily mitigates the prototype chain bug that will be
permanently fixed by this React Native PR that I submitted yesterday:
facebook/react-native#21492

I would like to find a way to bundle a different Map polyfill in React
Native apps, without increasing bundle sizes for non-RN apps, but that has
proven tricky so far. For future reference, this seems to be the way to do
it (thanks to @peggyrayzis for the tip):
https://facebook.github.io/react-native/docs/platform-specific-code#platform-specific-extensions

Until a new version of React Native is released with these changes
included, the simplest way to fix the problem is simply to avoid storing
any prototype objects in a Map, so that's what I've done in this commit.

We are already wrapping Object.freeze and friends in src/fixPolyfills.ts,
which should make it possible to use frozen objects as Map keys (the other
bug that I addressed in the React Native PR linked above).
  • Loading branch information
benjamn committed Oct 5, 2018
1 parent 07f3f47 commit cddcc47
Showing 1 changed file with 3 additions and 2 deletions.
5 changes: 3 additions & 2 deletions packages/apollo-cache-inmemory/src/queryKeyMaker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { DocumentNode, SelectionSetNode, FragmentSpreadNode, FragmentDefinitionN
import { QueryDocumentKeys } from "graphql/language/visitor";

const CIRCULAR = Object.create(null);
const objToStr = Object.prototype.toString;

export class QueryKeyMaker {
private perQueryKeyMakers = new Map<DocumentNode, PerQueryKeyMaker>();
Expand Down Expand Up @@ -99,7 +100,7 @@ class PerQueryKeyMaker {
private lookupArray(array: any[]): object {
const elements = array.map(this.lookupAny, this);
return this.cacheKeyRoot.lookup(
Array.prototype,
objToStr.call(array),
this.cacheKeyRoot.lookupArray(elements),
);
}
Expand All @@ -108,7 +109,7 @@ class PerQueryKeyMaker {
const keys = safeSortedKeys(object);
const values = keys.map(key => this.lookupAny(object[key]));
return this.cacheKeyRoot.lookup(
Object.getPrototypeOf(object),
objToStr.call(object),
this.cacheKeyRoot.lookupArray(keys),
this.cacheKeyRoot.lookupArray(values),
);
Expand Down

0 comments on commit cddcc47

Please sign in to comment.