Skip to content

Commit

Permalink
Merge pull request #4012 from ooflorent/fix/cache-ie11
Browse files Browse the repository at this point in the history
Work around spec non-compliance of Map#set and Set#add in IE11.
  • Loading branch information
benjamn committed Oct 24, 2018
2 parents 18dfe93 + f74e82d commit 7fa0d85
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 9 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
{
"name": "apollo-cache-inmemory",
"path": "./packages/apollo-cache-inmemory/lib/bundle.min.js",
"maxSize": "6.75 kB"
"maxSize": "7 kB"
},
{
"name": "apollo-client",
Expand Down
27 changes: 23 additions & 4 deletions packages/apollo-cache-inmemory/src/fixPolyfills.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,25 @@
const frozen = {};
const frozenTestMap = new Map();
// Make sure Map.prototype.set returns the Map instance, per spec.
// https://github.com/apollographql/apollo-client/issues/4024
const testMap = new Map();
if (testMap.set(1, 2) !== testMap) {
const { set } = testMap;
Map.prototype.set = function (...args) {
set.apply(this, args);
return this;
};
}

// Make sure Set.prototype.add returns the Set instance, per spec.
const testSet = new Set();
if (testSet.add(3) !== testSet) {
const { add } = testSet;
Set.prototype.add = function (...args) {
add.apply(this, args);
return this;
};
}

const frozen = {};
if (typeof Object.freeze === 'function') {
Object.freeze(frozen);
}
Expand All @@ -12,13 +31,13 @@ try {
// objects before they become non-extensible:
// https://github.com/facebook/react-native/blob/98a6f19d7c/Libraries/vendor/core/Map.js#L44-L50
// https://github.com/apollographql/react-apollo/issues/2442#issuecomment-426489517
frozenTestMap.set(frozen, frozen).delete(frozen);
testMap.set(frozen, frozen).delete(frozen);
} catch {
const wrap = (method: <T>(obj: T) => T): typeof method => {
return method && (obj => {
try {
// If .set succeeds, also call .delete to avoid leaking memory.
frozenTestMap.set(obj, obj).delete(obj);
testMap.set(obj, obj).delete(obj);
} finally {
// If .set or .delete fails, the exception will be silently swallowed
// by this return-from-finally statement:
Expand Down
14 changes: 10 additions & 4 deletions packages/apollo-cache-inmemory/src/optimism.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
declare function require(id: string): any;

export type OptimisticWrapperFunction<
T = (...args: any[]) => any,
T = (...args: any[]) => any
> = T & {
// The .dirty(...) method of an optimistic function takes exactly the same
// parameter types as the original function.
Expand All @@ -14,7 +14,9 @@ export type OptimisticWrapOptions = {
makeCacheKey?(...args: any[]): any;
};

const { wrap }: {
const {
wrap,
}: {
wrap<T>(
originalFunction: T,
options?: OptimisticWrapOptions,
Expand All @@ -40,7 +42,11 @@ export class CacheKeyNode<KeyType = object> {
}

getOrCreate(value: any): CacheKeyNode<KeyType> {
const map = this.children || (this.children = new Map);
return map.get(value) || map.set(value, new CacheKeyNode<KeyType>()).get(value);
const map = this.children || (this.children = new Map());
let node = map.get(value);
if (!node) {
map.set(value, node = new CacheKeyNode<KeyType>());
}
return node;
}
}

0 comments on commit 7fa0d85

Please sign in to comment.