mirror of
https://github.com/wassname/talk.git
synced 2026-07-01 02:50:26 +08:00
58 lines
1.7 KiB
JavaScript
58 lines
1.7 KiB
JavaScript
import * as React from 'react';
|
|
import {graphql} from 'react-apollo';
|
|
import {getQueryOptions, resolveFragments} from 'coral-framework/services/graphqlRegistry';
|
|
import {getDefinitionName, separateDataAndRoot, getResponseErrors} from '../utils';
|
|
|
|
const withSkipOnErrors = (reducer) => (prev, action, ...rest) => {
|
|
if (action.type === 'APOLLO_MUTATION_RESULT' && getResponseErrors(action.result)) {
|
|
return prev;
|
|
}
|
|
return reducer(prev, action, ...rest);
|
|
};
|
|
|
|
/**
|
|
* Exports a HOC with the same signature as `graphql`, that will
|
|
* apply query options registered in the graphRegistry.
|
|
*/
|
|
export default (document, config = {}) => (WrappedComponent) => {
|
|
config = {
|
|
...config,
|
|
options: config.options || {},
|
|
props: config.props || (({data}) => separateDataAndRoot(data)),
|
|
};
|
|
|
|
const wrappedOptions = (data) => {
|
|
const base = (typeof config.options === 'function') ? config.options(data) : config.options;
|
|
const name = getDefinitionName(document);
|
|
const configs = getQueryOptions(name);
|
|
const reducerCallbacks =
|
|
[base.reducer || ((i) => i)]
|
|
.concat(...configs.map((cfg) => cfg.reducer))
|
|
.filter((i) => i);
|
|
|
|
const reducer = withSkipOnErrors(
|
|
reducerCallbacks.reduce(
|
|
(a, b) => (prev, ...rest) =>
|
|
b(a(prev, ...rest), ...rest),
|
|
));
|
|
|
|
return {
|
|
...base,
|
|
reducer,
|
|
};
|
|
};
|
|
|
|
let memoized = null;
|
|
const getWrapped = () => {
|
|
if (!memoized) {
|
|
memoized = graphql(resolveFragments(document), {...config, options: wrappedOptions})(WrappedComponent);
|
|
}
|
|
return memoized;
|
|
};
|
|
|
|
return (props) => {
|
|
const Wrapped = getWrapped();
|
|
return <Wrapped {...props} />;
|
|
};
|
|
};
|