UNPKG

5.04 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, '__esModule', { value: true });
4
5function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
6
7var react = require('react');
8var PropTypes = _interopDefault(require('prop-types'));
9
10var isShallowEqual = function isShallowEqual (a, b) {
11 if (a === b) { return true }
12 for (var i in a) { if (!(i in b)) { return false } }
13 for (var i in b) { if (a[i] !== b[i]) { return false } }
14 return true
15};
16
17var isObjectNotNull = function (a, b) {
18 return (
19 typeof a === 'object' && typeof b === 'object' && a !== null && b !== null
20 )
21};
22
23var State = (function (Component$$1) {
24 function State (props, context) {
25 Component$$1.call(this, props, context);
26 this.broadcast = context.__statty__.broadcast;
27 this.inspect = context.__statty__.inspect;
28 this.state = props.state
29 ? props.state
30 : props.select(this.broadcast.getState());
31 this.update = this.update.bind(this);
32 this.setStateIfNeeded = this.setStateIfNeeded.bind(this);
33 }
34
35 if ( Component$$1 ) State.__proto__ = Component$$1;
36 State.prototype = Object.create( Component$$1 && Component$$1.prototype );
37 State.prototype.constructor = State;
38
39 State.prototype.update = function update (updaterFn) {
40 if (this.props.state) {
41 this.setState(updaterFn);
42 } else {
43 var oldState = this.broadcast.getState();
44 var nextState = updaterFn(oldState);
45 this.inspect && this.inspect(oldState, nextState, updaterFn);
46 this.broadcast.setState(nextState);
47 }
48 };
49
50 State.prototype.setStateIfNeeded = function setStateIfNeeded (nextState) {
51 var oldSelectdedState = this.state;
52 var newSelectedState = this.props.select(nextState);
53 if (
54 !isObjectNotNull(oldSelectdedState, newSelectedState) ||
55 !isShallowEqual(oldSelectdedState, newSelectedState)
56 ) {
57 this.setState(newSelectedState);
58 }
59 };
60
61 State.prototype.componentDidMount = function componentDidMount () {
62 if (!this.props.state) {
63 this.subscriptionId = this.broadcast.subscribe(this.setStateIfNeeded);
64 // To handle the case where a child component may have triggered a state change in
65 // its cWM/cDM, we have to re-run the selector and maybe re-render.
66 this.setStateIfNeeded(this.broadcast.getState());
67 }
68 };
69
70 State.prototype.componentWillUnmount = function componentWillUnmount () {
71 this.subscriptionId && this.broadcast.unsubscribe(this.subscriptionId);
72 };
73
74 State.prototype.render = function render () {
75 return (
76 this.props.render(
77 this.props.select(
78 this.props.state ? this.state : this.broadcast.getState()
79 ),
80 this.update
81 ) || null
82 )
83 };
84
85 return State;
86}(react.Component));
87
88State.defaultProps = {
89 select: function (s) { return s; },
90 render: function () { return null; }
91};
92
93State.contextTypes = {
94 __statty__: PropTypes.object.isRequired
95};
96
97State.propTypes = {
98 state: PropTypes.object,
99 render: PropTypes.func,
100 select: PropTypes.func
101};
102
103function createBroadcast (initialState) {
104 var listeners = {};
105 var id = 1;
106 var _state = initialState;
107
108 function getState () {
109 return _state
110 }
111
112 function setState (state) {
113 _state = state;
114 var keys = Object.keys(listeners);
115 var i = 0;
116 var len = keys.length;
117 for (; i < len; i++) {
118 // if a listener gets unsubscribed during setState we just skip it
119 if (listeners[keys[i]]) { listeners[keys[i]](state); }
120 }
121 }
122
123 // subscribe to changes and return the subscriptionId
124 function subscribe (listener) {
125 if (typeof listener !== 'function') {
126 throw new Error('listener must be a function.')
127 }
128 var currentId = id;
129 listeners[currentId] = listener;
130 id += 1;
131 return currentId
132 }
133
134 // remove subscription by removing the listener function
135 function unsubscribe (id) {
136 listeners[id] = undefined;
137 }
138
139 return { getState: getState, setState: setState, subscribe: subscribe, unsubscribe: unsubscribe }
140}
141
142var Provider = (function (Component$$1) {
143 function Provider (props, context) {
144 Component$$1.call(this, props, context);
145 this.broadcast = createBroadcast(props.state);
146 }
147
148 if ( Component$$1 ) Provider.__proto__ = Component$$1;
149 Provider.prototype = Object.create( Component$$1 && Component$$1.prototype );
150 Provider.prototype.constructor = Provider;
151
152 Provider.prototype.getChildContext = function getChildContext () {
153 return {
154 __statty__: {
155 broadcast: this.broadcast,
156 inspect: this.props.inspect
157 }
158 }
159 };
160
161 Provider.prototype.render = function render () {
162 var children = this.props.children;
163 return Array.isArray(children) ? children[0] : children
164 };
165
166 return Provider;
167}(react.Component));
168
169Provider.childContextTypes = {
170 __statty__: PropTypes.object
171};
172
173Provider.propTypes = {
174 inspect: PropTypes.func,
175 state: PropTypes.object.isRequired,
176 children: PropTypes.node.isRequired
177};
178
179exports.Provider = Provider;
180exports.State = State;