UNPKG

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