UNPKG

3.6 kBJavaScriptView Raw
1'use strict';
2
3function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
4
5var React = require('react');
6var React__default = _interopDefault(React);
7
8function _defineProperty(obj, key, value) {
9 if (key in obj) {
10 Object.defineProperty(obj, key, {
11 value: value,
12 enumerable: true,
13 configurable: true,
14 writable: true
15 });
16 } else {
17 obj[key] = value;
18 }
19
20 return obj;
21}
22
23function _inheritsLoose(subClass, superClass) {
24 subClass.prototype = Object.create(superClass.prototype);
25 subClass.prototype.constructor = subClass;
26 subClass.__proto__ = superClass;
27}
28
29var canUseDOM = !!(typeof window !== 'undefined' && window.document && window.document.createElement);
30function withSideEffect(reducePropsToState, handleStateChangeOnClient, mapStateOnServer) {
31 if (typeof reducePropsToState !== 'function') {
32 throw new Error('Expected reducePropsToState to be a function.');
33 }
34
35 if (typeof handleStateChangeOnClient !== 'function') {
36 throw new Error('Expected handleStateChangeOnClient to be a function.');
37 }
38
39 if (typeof mapStateOnServer !== 'undefined' && typeof mapStateOnServer !== 'function') {
40 throw new Error('Expected mapStateOnServer to either be undefined or a function.');
41 }
42
43 function getDisplayName(WrappedComponent) {
44 return WrappedComponent.displayName || WrappedComponent.name || 'Component';
45 }
46
47 return function wrap(WrappedComponent) {
48 if (typeof WrappedComponent !== 'function') {
49 throw new Error('Expected WrappedComponent to be a React component.');
50 }
51
52 var mountedInstances = [];
53 var state;
54
55 function emitChange() {
56 state = reducePropsToState(mountedInstances.map(function (instance) {
57 return instance.props;
58 }));
59
60 if (SideEffect.canUseDOM) {
61 handleStateChangeOnClient(state);
62 } else if (mapStateOnServer) {
63 state = mapStateOnServer(state);
64 }
65 }
66
67 var SideEffect =
68 /*#__PURE__*/
69 function (_PureComponent) {
70 _inheritsLoose(SideEffect, _PureComponent);
71
72 function SideEffect() {
73 return _PureComponent.apply(this, arguments) || this;
74 }
75
76 // Try to use displayName of wrapped component
77 // Expose canUseDOM so tests can monkeypatch it
78 SideEffect.peek = function peek() {
79 return state;
80 };
81
82 SideEffect.rewind = function rewind() {
83 if (SideEffect.canUseDOM) {
84 throw new Error('You may only call rewind() on the server. Call peek() to read the current state.');
85 }
86
87 var recordedState = state;
88 state = undefined;
89 mountedInstances = [];
90 return recordedState;
91 };
92
93 var _proto = SideEffect.prototype;
94
95 _proto.UNSAFE_componentWillMount = function UNSAFE_componentWillMount() {
96 mountedInstances.push(this);
97 emitChange();
98 };
99
100 _proto.componentDidUpdate = function componentDidUpdate() {
101 emitChange();
102 };
103
104 _proto.componentWillUnmount = function componentWillUnmount() {
105 var index = mountedInstances.indexOf(this);
106 mountedInstances.splice(index, 1);
107 emitChange();
108 };
109
110 _proto.render = function render() {
111 return React__default.createElement(WrappedComponent, this.props);
112 };
113
114 return SideEffect;
115 }(React.PureComponent);
116
117 _defineProperty(SideEffect, "displayName", "SideEffect(" + getDisplayName(WrappedComponent) + ")");
118
119 _defineProperty(SideEffect, "canUseDOM", canUseDOM);
120
121 return SideEffect;
122 };
123}
124
125module.exports = withSideEffect;