All files / utils connector.js

75.76% Statements 25/33
41.67% Branches 5/12
68.75% Functions 11/16
75% Lines 21/28

Press n or j to go to the next uncovered block, b, p or k for the previous block.

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      8x 8x   8x 26x                         26x 26x   26x           162x         1370x       1114x   162x 162x   162x 952x 952x 174x 174x 174x         162x 174x 510x                        
import { bindActionCreators } from 'redux';
import shallowEqual from './shallowEqual';
 
const defaultMapState = () => ({});
const defaultMapDispatch = {};
 
const normalizeMapState = mapState => {
	Eif (typeof mapState === 'function') return mapState;
 
	if (mapState === Object(mapState)) {
		return (state, ownProps) =>
			Object.keys(mapState)
				.filter(key => typeof mapState[key] === 'function')
				.reduce((map, key) => ({ ...map, [key]: mapState[key](state, ownProps) }), {});
	}
 
	throw new Error('[revux] - mapState provided to connect is invalid');
};
 
// eslint-disable-next-line
const connector = (_mapState = defaultMapState, mapDispatch = defaultMapDispatch) => component => {
	const mapState = normalizeMapState(_mapState);
 
	return {
		name: `connect-${component.name}`,
		mixins: [component],
		inject: ['$$store'],
 
		data() {
			const merged = {
				...mapState(this.$$store.getState(), this.$props || {}),
				...bindActionCreators(mapDispatch, this.$$store.dispatch),
			};
 
			return Object.keys(merged).reduce((data, key) => ({ ...data, [key]: merged[key] }), {});
		},
 
		created() {
			const getMappedState = state => mapState(state, this.$props || {});
 
			const observeStore = (store, select, onChange) => {
				let currentState = select(store.getState());
 
				return store.subscribe(() => {
					const nextState = select(store.getState());
					if (!shallowEqual(currentState, nextState)) {
						const previousState = currentState;
						currentState = nextState;
						onChange(currentState, previousState);
					}
				});
			};
 
			this._unsubscribe = observeStore(this.$$store, getMappedState, newState => {
				Object.keys(newState).forEach(key => {
					this.$set(this, key, newState[key]);
				});
			});
		},
 
		beforeDestroy() {
			this._unsubscribe();
		},
	};
};
 
export default connector;