Skip to content
This repository has been archived by the owner on Sep 19, 2024. It is now read-only.

Commit

Permalink
Pass a context object around with store data
Browse files Browse the repository at this point in the history
This makes it quite a bit easier to pass additional configuration to the data/* functions
  • Loading branch information
nevir committed Jul 25, 2016
1 parent f33998b commit 5a7d289
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 48 deletions.
30 changes: 19 additions & 11 deletions src/QueryManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -296,12 +296,14 @@ export class QueryManager {
try {
const resultFromStore = {
data: readSelectionSetFromStore({
store: this.getDataWithOptimisticResults(),
context: {
store: this.getDataWithOptimisticResults(),
fragmentMap: queryStoreValue.fragmentMap,
},
rootId: queryStoreValue.query.id,
selectionSet: queryStoreValue.query.selectionSet,
variables: queryStoreValue.variables,
returnPartialData: options.returnPartialData || options.noFetch,
fragmentMap: queryStoreValue.fragmentMap,
}),
};

Expand Down Expand Up @@ -535,15 +537,17 @@ export class QueryManager {
}

const previousResult = readSelectionSetFromStore({
// In case of an optimistic change, apply reducer on top of the
// results including previous optimistic updates. Otherwise, apply it
// on top of the real data only.
store: isOptimistic ? this.getDataWithOptimisticResults() : this.getApolloState().data,
context: {
// In case of an optimistic change, apply reducer on top of the
// results including previous optimistic updates. Otherwise, apply it
// on top of the real data only.
store: isOptimistic ? this.getDataWithOptimisticResults() : this.getApolloState().data,
fragmentMap: createFragmentMap(fragments || []),
},
rootId: 'ROOT_QUERY',
selectionSet: queryDefinition.selectionSet,
variables: queryOptions.variables,
returnPartialData: queryOptions.returnPartialData || queryOptions.noFetch,
fragmentMap: createFragmentMap(fragments || []),
});

resultBehaviors.push({
Expand Down Expand Up @@ -608,12 +612,14 @@ export class QueryManager {
// query, use the query diff algorithm to get as much of a result as we can, and identify
// what data is missing from the store
const { missingSelectionSets, result } = diffSelectionSetAgainstStore({
context: {
store: this.store.getState()[this.reduxRootKey].data,
fragmentMap: queryFragmentMap,
},
selectionSet: querySS.selectionSet,
store: this.store.getState()[this.reduxRootKey].data,
throwOnMissingField: false,
rootId: querySS.id,
variables,
fragmentMap: queryFragmentMap,
});

initialResult = result;
Expand Down Expand Up @@ -708,12 +714,14 @@ export class QueryManager {
// this will throw an error if there are missing fields in
// the results if returnPartialData is false.
resultFromStore = readSelectionSetFromStore({
store: this.getApolloState().data,
context: {
store: this.getApolloState().data,
fragmentMap: queryFragmentMap,
},
rootId: querySS.id,
selectionSet: querySS.selectionSet,
variables,
returnPartialData: returnPartialData || noFetch,
fragmentMap: queryFragmentMap,
});
// ensure multiple errors don't get thrown
/* tslint:disable */
Expand Down
46 changes: 20 additions & 26 deletions src/data/diffAgainstStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,13 @@ export interface DiffResult {
missingSelectionSets?: SelectionSetWithRoot[];
}

// Contexual state and configuration that is used throught a request from the
// store.
export interface StoreContext {
store: NormalizedCache;
fragmentMap: FragmentMap;
}

export function diffQueryAgainstStore({
store,
query,
Expand All @@ -55,7 +62,7 @@ export function diffQueryAgainstStore({
const queryDef = getQueryDefinition(query);

return diffSelectionSetAgainstStore({
store,
context: { store, fragmentMap: {} },
rootId: 'ROOT_QUERY',
selectionSet: queryDef.selectionSet,
throwOnMissingField: false,
Expand All @@ -77,7 +84,7 @@ export function diffFragmentAgainstStore({
const fragmentDef = getFragmentDefinition(fragment);

return diffSelectionSetAgainstStore({
store,
context: { store, fragmentMap: {} },
rootId,
selectionSet: fragmentDef.selectionSet,
throwOnMissingField: false,
Expand All @@ -97,28 +104,22 @@ export function diffFragmentAgainstStore({
* @return {result: Object, missingSelectionSets: [SelectionSet]}
*/
export function diffSelectionSetAgainstStore({
context,
selectionSet,
store,
rootId,
throwOnMissingField = false,
variables,
fragmentMap,
}: {
context: StoreContext,
selectionSet: SelectionSet,
store: NormalizedCache,
rootId: string,
throwOnMissingField: boolean,
variables: Object,
fragmentMap?: FragmentMap,
}): DiffResult {
if (selectionSet.kind !== 'SelectionSet') {
throw new Error('Must be a selection set.');
}

if (!fragmentMap) {
fragmentMap = {};
}

const result = {};
const missingFields: Selection[] = [];

Expand All @@ -139,12 +140,11 @@ export function diffSelectionSetAgainstStore({
result: fieldResult,
isMissing: fieldIsMissing,
} = diffFieldAgainstStore({
context,
field: selection,
throwOnMissingField,
variables,
rootId,
store,
fragmentMap,
included: includeField,
});

Expand All @@ -163,12 +163,11 @@ export function diffSelectionSetAgainstStore({
result: fieldResult,
isMissing: fieldIsMissing,
} = diffSelectionSetAgainstStore({
context,
selectionSet: selection.selectionSet,
throwOnMissingField,
variables,
rootId,
store,
fragmentMap,
});

if (fieldIsMissing) {
Expand All @@ -177,7 +176,7 @@ export function diffSelectionSetAgainstStore({
assign(result, fieldResult);
}
} else {
const fragment = fragmentMap[selection.name.value];
const fragment = context.fragmentMap[selection.name.value];
if (!fragment) {
throw new Error(`No fragment named ${selection.name.value}`);
}
Expand All @@ -186,12 +185,11 @@ export function diffSelectionSetAgainstStore({
result: fieldResult,
isMissing: fieldIsMissing,
} = diffSelectionSetAgainstStore({
context,
selectionSet: fragment.selectionSet,
throwOnMissingField,
variables,
rootId,
store,
fragmentMap,
});

if (fieldIsMissing) {
Expand Down Expand Up @@ -236,23 +234,21 @@ export function diffSelectionSetAgainstStore({
}

function diffFieldAgainstStore({
context,
field,
throwOnMissingField,
variables,
rootId,
store,
fragmentMap,
included = true,
}: {
context: StoreContext,
field: Field,
throwOnMissingField: boolean,
variables: Object,
rootId: string,
store: NormalizedCache,
fragmentMap?: FragmentMap,
included?: Boolean,
}): FieldDiffResult {
const storeObj = store[rootId] || {};
const storeObj = context.store[rootId] || {};
const storeFieldKey = storeKeyNameFromField(field, variables);

if (! has(storeObj, storeFieldKey)) {
Expand Down Expand Up @@ -302,12 +298,11 @@ Perhaps you want to use the \`returnPartialData\` option?`);
}

const itemDiffResult = diffSelectionSetAgainstStore({
store,
context,
throwOnMissingField,
rootId: id,
selectionSet: field.selectionSet,
variables,
fragmentMap,
});

if (itemDiffResult.isMissing) {
Expand All @@ -329,12 +324,11 @@ Perhaps you want to use the \`returnPartialData\` option?`);
if (isIdValue(storeValue)) {
const unescapedId = storeValue.id;
return diffSelectionSetAgainstStore({
store,
context,
throwOnMissingField,
rootId: unescapedId,
selectionSet: field.selectionSet,
variables,
fragmentMap,
});
}

Expand Down
15 changes: 6 additions & 9 deletions src/data/readFromStore.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {
diffSelectionSetAgainstStore,
StoreContext,
} from './diffAgainstStore';

import {
Expand All @@ -10,7 +11,6 @@ import {
import {
getQueryDefinition,
getFragmentDefinition,
FragmentMap,
} from '../queries/getFromAST';

import {
Expand All @@ -35,7 +35,7 @@ export function readQueryFromStore({
const queryDef = getQueryDefinition(query);

return readSelectionSetFromStore({
store,
context: { store, fragmentMap: {} },
rootId: 'ROOT_QUERY',
selectionSet: queryDef.selectionSet,
variables,
Expand All @@ -59,7 +59,7 @@ export function readFragmentFromStore({
const fragmentDef = getFragmentDefinition(fragment);

return readSelectionSetFromStore({
store,
context: { store, fragmentMap: {} },
rootId,
selectionSet: fragmentDef.selectionSet,
variables,
Expand All @@ -68,29 +68,26 @@ export function readFragmentFromStore({
}

export function readSelectionSetFromStore({
store,
context,
rootId,
selectionSet,
variables,
returnPartialData = false,
fragmentMap,
}: {
store: NormalizedCache,
context: StoreContext,
rootId: string,
selectionSet: SelectionSet,
variables: Object,
returnPartialData?: boolean,
fragmentMap?: FragmentMap,
}): Object {
const {
result,
} = diffSelectionSetAgainstStore({
context,
selectionSet,
rootId,
store,
throwOnMissingField: !returnPartialData,
variables,
fragmentMap,
});

return result;
Expand Down
4 changes: 2 additions & 2 deletions test/diffAgainstStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ describe('diffing queries against the store', () => {
`;

const { result } = diffSelectionSetAgainstStore({
store,
context: { store, fragmentMap: {} },
rootId: 'ROOT_QUERY',
selectionSet: getQueryDefinition(queryWithMissingField).selectionSet,
variables: null,
Expand All @@ -333,7 +333,7 @@ describe('diffing queries against the store', () => {
});
assert.throws(function() {
diffSelectionSetAgainstStore({
store,
context: { store, fragmentMap: {} },
rootId: 'ROOT_QUERY',
selectionSet: getQueryDefinition(queryWithMissingField).selectionSet,
variables: null,
Expand Down

0 comments on commit 5a7d289

Please sign in to comment.