Skip to content

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 authored and Rylan Hawkins committed Aug 16, 2016
1 parent acbf9a0 commit e90f54d
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 55 deletions.
30 changes: 19 additions & 11 deletions src/QueryManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -325,12 +325,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,
}),
loading: queryStoreValue.loading,
};
Expand Down Expand Up @@ -558,15 +560,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 || []),
});

return {
Expand Down Expand Up @@ -674,12 +678,14 @@ export class QueryManager {
initialResult: Object,
} {
const { missingSelectionSets, result } = diffSelectionSetAgainstStore({
context: {
store: this.store.getState()[this.reduxRootKey].data,
fragmentMap,
},
selectionSet: queryDef.selectionSet,
store: this.store.getState()[this.reduxRootKey].data,
throwOnMissingField: false,
rootId,
variables,
fragmentMap,
});

const initialResult = result;
Expand Down Expand Up @@ -761,12 +767,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,
},
rootId: querySS.id,
selectionSet: querySS.selectionSet,
variables,
returnPartialData: returnPartialData || noFetch,
fragmentMap,
});
// 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 @@ -52,6 +52,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 @@ -64,7 +71,7 @@ export function diffQueryAgainstStore({
const queryDef = getQueryDefinition(query);

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

return diffSelectionSetAgainstStore({
store,
context: { store, fragmentMap: {} },
rootId,
selectionSet: fragmentDef.selectionSet,
throwOnMissingField: false,
Expand Down Expand Up @@ -126,28 +133,22 @@ export function handleFragmentErrors(fragmentErrors: { [typename: string]: Error
* @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 Down Expand Up @@ -177,12 +178,11 @@ export function diffSelectionSetAgainstStore({

if (isField(selection)) {
const diffResult = diffFieldAgainstStore({
context,
field: selection,
throwOnMissingField,
variables,
rootId,
store,
fragmentMap,
included,
});
fieldIsMissing = diffResult.isMissing;
Expand All @@ -204,12 +204,11 @@ export function diffSelectionSetAgainstStore({
if (included) {
try {
const diffResult = diffSelectionSetAgainstStore({
context,
selectionSet: selection.selectionSet,
throwOnMissingField,
variables,
rootId,
store,
fragmentMap,
});
fieldIsMissing = diffResult.isMissing;
fieldResult = diffResult.result;
Expand All @@ -232,7 +231,7 @@ export function diffSelectionSetAgainstStore({
}
}
} 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 @@ -243,12 +242,11 @@ export function diffSelectionSetAgainstStore({
if (included) {
try {
const diffResult = diffSelectionSetAgainstStore({
context,
selectionSet: fragment.selectionSet,
throwOnMissingField,
variables,
rootId,
store,
fragmentMap,
});
fieldIsMissing = diffResult.isMissing;
fieldResult = diffResult.result;
Expand Down Expand Up @@ -311,23 +309,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 @@ -382,12 +378,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 @@ -409,12 +404,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
18 changes: 9 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 Down Expand Up @@ -37,12 +38,14 @@ export function readQueryFromStore({
const queryDef = getQueryDefinition(query);

return readSelectionSetFromStore({
store,
context: {
store,
fragmentMap: fragmentMap || {},
},
rootId: 'ROOT_QUERY',
selectionSet: queryDef.selectionSet,
variables,
returnPartialData,
fragmentMap,
});
}

Expand All @@ -62,7 +65,7 @@ export function readFragmentFromStore({
const fragmentDef = getFragmentDefinition(fragment);

return readSelectionSetFromStore({
store,
context: { store, fragmentMap: {} },
rootId,
selectionSet: fragmentDef.selectionSet,
variables,
Expand All @@ -71,29 +74,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
31 changes: 22 additions & 9 deletions test/diffAgainstStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,10 @@ describe('diffing queries against the store', () => {
}`;
assert.throws(() => {
diffSelectionSetAgainstStore({
store,
context: {
store,
fragmentMap: {},
},
rootId: 'ROOT_QUERY',
selectionSet: getQueryDefinition(unionQuery).selectionSet,
variables: null,
Expand Down Expand Up @@ -353,7 +356,10 @@ describe('diffing queries against the store', () => {
}`;
assert.doesNotThrow(() => {
diffSelectionSetAgainstStore({
store,
context: {
store,
fragmentMap: {},
},
rootId: 'ROOT_QUERY',
selectionSet: getQueryDefinition(unionQuery).selectionSet,
variables: null,
Expand Down Expand Up @@ -395,12 +401,14 @@ describe('diffing queries against the store', () => {
}`;
assert.doesNotThrow(() => {
diffSelectionSetAgainstStore({
store,
context: {
store,
fragmentMap: createFragmentMap(getFragmentDefinitions(unionQuery)),
},
rootId: 'ROOT_QUERY',
selectionSet: getQueryDefinition(unionQuery).selectionSet,
variables: null,
throwOnMissingField: true,
fragmentMap: createFragmentMap(getFragmentDefinitions(unionQuery)),
});
});
});
Expand Down Expand Up @@ -439,12 +447,14 @@ describe('diffing queries against the store', () => {
}`;
assert.throw(() => {
diffSelectionSetAgainstStore({
store,
context: {
store,
fragmentMap: createFragmentMap(getFragmentDefinitions(unionQuery)),
},
rootId: 'ROOT_QUERY',
selectionSet: getQueryDefinition(unionQuery).selectionSet,
variables: null,
throwOnMissingField: true,
fragmentMap: createFragmentMap(getFragmentDefinitions(unionQuery)),
});
});
});
Expand Down Expand Up @@ -484,7 +494,10 @@ describe('diffing queries against the store', () => {

assert.throw(() => {
diffSelectionSetAgainstStore({
store,
context: {
store,
fragmentMap: {},
},
rootId: 'ROOT_QUERY',
selectionSet: getQueryDefinition(unionQuery).selectionSet,
variables: null,
Expand Down Expand Up @@ -527,7 +540,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 @@ -541,7 +554,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 e90f54d

Please sign in to comment.