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
This temporarily mitigates the prototype chain bug that will be fixed with
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 e2f1bc8
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 e2f1bc8

Please sign in to comment.