forked from apollographql/apollo-client
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathresultReducers.ts
81 lines (69 loc) · 1.96 KB
/
resultReducers.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
import {
DocumentNode,
} from 'graphql';
import {
diffQueryAgainstStore,
} from './readFromStore';
import {
writeResultToStore,
} from './writeToStore';
import {
NormalizedCache,
} from './storeUtils';
import {
ApolloReducer,
ApolloReducerConfig,
} from '../store';
import {
ApolloAction,
} from '../actions';
import {
OperationResultReducer,
} from './mutationResults';
/**
* This function takes a result reducer and all other necessary information to obtain a proper
* redux store reducer.
* note: we're just passing the config to access dataIdFromObject, which writeToStore needs.
*/
export function createStoreReducer(
resultReducer: OperationResultReducer,
document: DocumentNode,
variables: Object,
config: ApolloReducerConfig,
): ApolloReducer {
return (store: NormalizedCache, action: ApolloAction) => {
const { result, isMissing } = diffQueryAgainstStore({
store,
query: document,
variables,
returnPartialData: true,
fragmentMatcherFunction: config.fragmentMatcher,
config,
});
if (isMissing) {
// If there is data missing, the query most likely isn't done loading yet. If there's an actual problem
// with the query's data, the error would surface on that query, so we don't need to throw here.
// It would be very hard for people to deal with missing data in reducers, so we opt not to invoke them.
return store;
}
let nextResult;
try {
nextResult = resultReducer(result, action, variables); // action should include operation name
} catch (err) {
console.warn('Unhandled error in result reducer', err);
throw err;
}
if (result !== nextResult) {
return writeResultToStore({
dataId: 'ROOT_QUERY',
result: nextResult,
store,
document,
variables,
dataIdFromObject: config.dataIdFromObject,
fragmentMatcherFunction: config.fragmentMatcher,
});
}
return store;
};
}