Skip to content

Commit

Permalink
Pass a context object around with store data
Browse files Browse the repository at this point in the history
Prompted by #376's brittleness; this helps keep common state/configuration around when performing a query.

---

Also, as part of this, I noticed there are two seemingly unused functions: `diffQueryAgainstStore`, `diffFragmentAgainstStore`
  • Loading branch information
nevir committed Jul 14, 2016
1 parent fdc7173 commit a750b7c
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 44 deletions.
20 changes: 13 additions & 7 deletions src/QueryManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -379,12 +379,14 @@ export class QueryManager {
}
} else {
const resultFromStore = 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,
returnPartialData: options.returnPartialData,
});

if (observer.next) {
Expand Down Expand Up @@ -622,12 +624,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 @@ -727,12 +731,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 @@ -42,6 +42,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 @@ -54,7 +61,7 @@ export function diffQueryAgainstStore({
const queryDef = getQueryDefinition(query);

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

return diffSelectionSetAgainstStore({
store,
context: { store, fragmentMap: {} },
rootId,
selectionSet: fragmentDef.selectionSet,
throwOnMissingField: false,
Expand All @@ -96,28 +103,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 @@ -138,12 +139,11 @@ export function diffSelectionSetAgainstStore({
result: fieldResult,
isMissing: fieldIsMissing,
} = diffFieldAgainstStore({
context,
field: selection,
throwOnMissingField,
variables,
rootId,
store,
fragmentMap,
included: includeField,
});

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

if (fieldIsMissing) {
Expand All @@ -176,7 +175,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 @@ -185,12 +184,11 @@ export function diffSelectionSetAgainstStore({
result: fieldResult,
isMissing: fieldIsMissing,
} = diffSelectionSetAgainstStore({
context,
selectionSet: fragment.selectionSet,
throwOnMissingField,
variables,
rootId,
store,
fragmentMap,
});

if (fieldIsMissing) {
Expand Down Expand Up @@ -235,23 +233,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 @@ -293,12 +289,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 @@ -317,12 +312,11 @@ Perhaps you want to use the \`returnPartialData\` option?`);

if (isString(storeValue)) {
return diffSelectionSetAgainstStore({
store,
context,
throwOnMissingField,
rootId: storeValue,
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 a750b7c

Please sign in to comment.