Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pass a context object around with store data #377

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 12 additions & 6 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,
});

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