Skip to content

Commit

Permalink
refactor to use lodash.isEqual instead of custom isEqual
Browse files Browse the repository at this point in the history
  • Loading branch information
capaj committed Jun 1, 2019
1 parent 451482f commit c472591
Show file tree
Hide file tree
Showing 12 changed files with 149 additions and 249 deletions.
4 changes: 4 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"trailingComma": "all",
"singleQuote": true
}
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,10 @@
],
"lint-staged": {
"*.ts*": [
"prettier --ignore-path \"./config/prettierignore\" --trailing-comma all --single-quote --write"
"prettier --ignore-path \"./config/prettierignore\" --write"
],
"*.js*": [
"prettier --ignore-path \"./config/prettierignore\" --trailing-comma all --single-quote --write"
"prettier --ignore-path \"./config/prettierignore\" --write"
]
},
"pre-commit": "lint-staged",
Expand Down
9 changes: 7 additions & 2 deletions packages/apollo-cache-inmemory/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions packages/apollo-cache-inmemory/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
"dependencies": {
"apollo-cache": "file:../apollo-cache",
"apollo-utilities": "file:../apollo-utilities",
"lodash.isequal": "^4.5.0",
"optimism": "^0.9.0",
"ts-invariant": "^0.4.0",
"tslib": "^1.9.3"
Expand Down
201 changes: 111 additions & 90 deletions packages/apollo-cache-inmemory/src/readFromStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import {
getQueryDefinition,
getStoreKeyName,
IdValue,
isEqual,
isField,
isIdValue,
isInlineFragment,
Expand All @@ -24,7 +23,7 @@ import {
StoreValue,
toIdValue,
} from 'apollo-utilities';

import isEqual from 'lodash.isequal';
import { Cache } from 'apollo-cache';

import {
Expand Down Expand Up @@ -103,7 +102,7 @@ type ExecSubSelectedArrayOptions = {
export interface StoreReaderConfig {
cacheKeyRoot?: KeyTrie<object>;
freezeResults?: boolean;
};
}

export class StoreReader {
private freezeResults: boolean;
Expand All @@ -120,65 +119,74 @@ export class StoreReader {

this.freezeResults = freezeResults;

this.executeStoreQuery = wrap((options: ExecStoreQueryOptions) => {
return executeStoreQuery.call(this, options);
}, {
makeCacheKey({
query,
rootValue,
contextValue,
variableValues,
fragmentMatcher,
}: ExecStoreQueryOptions) {
// The result of executeStoreQuery can be safely cached only if the
// underlying store is capable of tracking dependencies and invalidating
// the cache when relevant data have changed.
if (contextValue.store instanceof DepTrackingCache) {
return cacheKeyRoot.lookup(
contextValue.store,
query,
fragmentMatcher,
JSON.stringify(variableValues),
rootValue.id,
);
}
}
});
this.executeStoreQuery = wrap(
(options: ExecStoreQueryOptions) => {
return executeStoreQuery.call(this, options);
},
{
makeCacheKey({
query,
rootValue,
contextValue,
variableValues,
fragmentMatcher,
}: ExecStoreQueryOptions) {
// The result of executeStoreQuery can be safely cached only if the
// underlying store is capable of tracking dependencies and invalidating
// the cache when relevant data have changed.
if (contextValue.store instanceof DepTrackingCache) {
return cacheKeyRoot.lookup(
contextValue.store,
query,
fragmentMatcher,
JSON.stringify(variableValues),
rootValue.id,
);
}
},
},
);

this.executeSelectionSet = wrap((options: ExecSelectionSetOptions) => {
return executeSelectionSet.call(this, options);
}, {
makeCacheKey({
selectionSet,
rootValue,
execContext,
}: ExecSelectionSetOptions) {
if (execContext.contextValue.store instanceof DepTrackingCache) {
return cacheKeyRoot.lookup(
execContext.contextValue.store,
selectionSet,
execContext.fragmentMatcher,
JSON.stringify(execContext.variableValues),
rootValue.id,
);
}
}
});
this.executeSelectionSet = wrap(
(options: ExecSelectionSetOptions) => {
return executeSelectionSet.call(this, options);
},
{
makeCacheKey({
selectionSet,
rootValue,
execContext,
}: ExecSelectionSetOptions) {
if (execContext.contextValue.store instanceof DepTrackingCache) {
return cacheKeyRoot.lookup(
execContext.contextValue.store,
selectionSet,
execContext.fragmentMatcher,
JSON.stringify(execContext.variableValues),
rootValue.id,
);
}
},
},
);

this.executeSubSelectedArray = wrap((options: ExecSubSelectedArrayOptions) => {
return executeSubSelectedArray.call(this, options);
}, {
makeCacheKey({ field, array, execContext }) {
if (execContext.contextValue.store instanceof DepTrackingCache) {
return cacheKeyRoot.lookup(
execContext.contextValue.store,
field,
array,
JSON.stringify(execContext.variableValues),
);
}
}
});
this.executeSubSelectedArray = wrap(
(options: ExecSubSelectedArrayOptions) => {
return executeSubSelectedArray.call(this, options);
},
{
makeCacheKey({ field, array, execContext }) {
if (execContext.contextValue.store instanceof DepTrackingCache) {
return cacheKeyRoot.lookup(
execContext.contextValue.store,
field,
array,
JSON.stringify(execContext.variableValues),
);
}
},
},
);
}

/**
Expand All @@ -196,9 +204,7 @@ export class StoreReader {
* If nothing in the store changed since that previous result then values from the previous result
* will be returned to preserve referential equality.
*/
public readQueryFromStore<QueryType>(
options: ReadQueryOptions,
): QueryType {
public readQueryFromStore<QueryType>(options: ReadQueryOptions): QueryType {
const optsPatch = { returnPartialData: false };

return this.diffQueryAgainstStore<QueryType>({
Expand Down Expand Up @@ -253,7 +259,7 @@ export class StoreReader {
const hasMissingFields =
execResult.missing && execResult.missing.length > 0;

if (hasMissingFields && ! returnPartialData) {
if (hasMissingFields && !returnPartialData) {
execResult.missing.forEach(info => {
if (info.tolerable) return;
throw new InvariantError(
Expand Down Expand Up @@ -327,7 +333,11 @@ export class StoreReader {
rootValue,
execContext,
}: ExecSelectionSetOptions): ExecResult {
const { fragmentMap, contextValue, variableValues: variables } = execContext;
const {
fragmentMap,
contextValue,
variableValues: variables,
} = execContext;
const finalResult: ExecResult = { result: null };

const objectsToMerge: { [key: string]: any }[] = [];
Expand Down Expand Up @@ -363,7 +373,6 @@ export class StoreReader {
[resultKeyNameFromField(selection)]: fieldResult,
});
}

} else {
let fragment: InlineFragmentNode | FragmentDefinitionNode;

Expand All @@ -374,13 +383,19 @@ export class StoreReader {
fragment = fragmentMap[selection.name.value];

if (!fragment) {
throw new InvariantError(`No fragment named ${selection.name.value}`);
throw new InvariantError(
`No fragment named ${selection.name.value}`,
);
}
}

const typeCondition = fragment.typeCondition.name.value;

const match = execContext.fragmentMatcher(rootValue, typeCondition, contextValue);
const match = execContext.fragmentMatcher(
rootValue,
typeCondition,
contextValue,
);
if (match) {
let fragmentExecResult = this.executeSelectionSet({
selectionSet: fragment.selectionSet,
Expand Down Expand Up @@ -515,20 +530,24 @@ export class StoreReader {

// This is a nested array, recurse
if (Array.isArray(item)) {
return handleMissing(this.executeSubSelectedArray({
field,
array: item,
execContext,
}));
return handleMissing(
this.executeSubSelectedArray({
field,
array: item,
execContext,
}),
);
}

// This is an object, run the selection set on it
if (field.selectionSet) {
return handleMissing(this.executeSelectionSet({
selectionSet: field.selectionSet,
rootValue: item,
execContext,
}));
return handleMissing(
this.executeSelectionSet({
selectionSet: field.selectionSet,
rootValue: item,
execContext,
}),
);
}

assertSelectionSetForIdValue(field, item);
Expand All @@ -544,15 +563,12 @@ export class StoreReader {
}
}

function assertSelectionSetForIdValue(
field: FieldNode,
value: any,
) {
function assertSelectionSetForIdValue(field: FieldNode, value: any) {
if (!field.selectionSet && isIdValue(value)) {
throw new InvariantError(
`Missing selection set for object of type ${
value.typename
} returned for query field ${field.name.value}`
} returned for query field ${field.name.value}`,
);
}
}
Expand All @@ -562,10 +578,13 @@ function defaultFragmentMatcher() {
}

export function assertIdValue(idValue: IdValue) {
invariant(isIdValue(idValue), `\
invariant(
isIdValue(idValue),
`\
Encountered a sub-selection on the query, but the store doesn't have \
an object reference. This should never happen during normal use unless you have custom code \
that is directly manipulating the store; please file an issue.`);
that is directly manipulating the store; please file an issue.`,
);
}

function readStoreResolver(
Expand Down Expand Up @@ -617,11 +636,13 @@ function readStoreResolver(
if (typeof fieldValue === 'undefined') {
return {
result: fieldValue,
missing: [{
object,
fieldName: storeKeyName,
tolerable: false,
}],
missing: [
{
object,
fieldName: storeKeyName,
tolerable: false,
},
],
};
}

Expand Down
17 changes: 9 additions & 8 deletions packages/apollo-cache-inmemory/src/writeToStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,8 @@ import {
storeKeyNameFromField,
StoreValue,
toIdValue,
isEqual,
} from 'apollo-utilities';

import isEqual from 'lodash.isequal';
import { invariant } from 'ts-invariant';

import { ObjectCache } from './objectCache';
Expand Down Expand Up @@ -366,19 +365,21 @@ export class StoreWriter {
!generated || escapedId.generated || typenameChanged,
`Store error: the application attempted to write an object with no provided id but the store already contains an id of ${
escapedId.id
} for this object. The selectionSet that was trying to be written is:\n${
JSON.stringify(field)
}`,
} for this object. The selectionSet that was trying to be written is:\n${JSON.stringify(
field,
)}`,
);

// checks if we "lost" the typename
invariant(
!hadTypename || hasTypename,
`Store error: the application attempted to write an object with no provided typename but the store already contains an object with typename of ${
escapedId.typename
} for the object of id ${escapedId.id}. The selectionSet that was trying to be written is:\n${
JSON.stringify(field)
}`,
} for the object of id ${
escapedId.id
}. The selectionSet that was trying to be written is:\n${JSON.stringify(
field,
)}`,
);

if (escapedId.generated) {
Expand Down
Loading

0 comments on commit c472591

Please sign in to comment.