@@ -14523,8 +14523,10 @@ Object.defineProperty(exports, "__esModule", {
14523
14523
value: true
14524
14524
});
14525
14525
exports.default = autoBind;
14526
+ // do not bind these, they should not be directly invoked or passed as callbacks by the user
14526
14527
var reactInternals = new Set(['constructor', 'render', 'componentWillMount', 'componentDidMount', 'componentWillReceiveProps', 'shouldComponentUpdate', 'componentWillUpdate', 'componentDidUpdate', 'componentWillUnmount']);
14527
14528
14529
+ // bind the methods from proto to the passed context object and assign them to the context
14528
14530
function autoBind(context, proto, isReact) {
14529
14531
var _iteratorNormalCompletion = true;
14530
14532
var _didIteratorError = false;
@@ -27058,7 +27060,7 @@ var _get = function get(object, property, receiver) { if (object === null) objec
27058
27060
27059
27061
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
27060
27062
27061
- exports.default = easyCompHOC ;
27063
+ exports.default = easyComp ;
27062
27064
27063
27065
var _react = __webpack_require__(25);
27064
27066
@@ -27076,91 +27078,129 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen
27076
27078
27077
27079
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
27078
27080
27079
- var OBSERVED_RENDER = Symbol('observed render');
27080
- var IS_DIRECT_RENDER = Symbol('is direct render');
27081
- var RENDER_RESULT = Symbol('render result');
27081
+ var REACTIVE_RENDER = Symbol('reactive render');
27082
27082
27083
- function easyCompHOC(WrappedComp ) {
27084
- if (typeof WrappedComp !== 'function') {
27085
- throw new TypeError('easyComp expects a component class or function as argument.');
27083
+ function easyComp(Comp ) {
27084
+ if (typeof Comp !== 'function') {
27085
+ throw new TypeError('easyComp expects a component as argument.');
27086
27086
}
27087
27087
27088
- if ((!WrappedComp.prototype || !WrappedComp.prototype.render) && !WrappedComp.isReactClass && !_react.Component.isPrototypeOf(WrappedComp)) {
27089
- var renderer = WrappedComp;
27090
- WrappedComp = function (_Component) {
27091
- _inherits(WrappedComp, _Component);
27088
+ // wrap stateless components in a class
27089
+ if (isStatelessComp(Comp)) {
27090
+ Comp = statelessToStatefulComp(Comp);
27091
+ } else if (hasComponentShouldUpdate(Comp)) {
27092
+ // shouldComponentUpdate is optimized by easyState, overwriting it would add zero or less value
27093
+ throw new Error('easyState optimizes shouldComponentUpdate, do not implement it.');
27094
+ }
27095
+
27096
+ return toReactiveComp(Comp);
27097
+ }
27098
+
27099
+ function isStatelessComp(Comp) {
27100
+ return !(Comp.prototype && Comp.prototype.render) && !_react.Component.isPrototypeOf(Comp);
27101
+ }
27102
+
27103
+ function statelessToStatefulComp(StatelessComp) {
27104
+ var _class, _temp;
27105
+
27106
+ return _temp = _class = function (_Component) {
27107
+ _inherits(StatefulComp, _Component);
27108
+
27109
+ function StatefulComp() {
27110
+ _classCallCheck(this, StatefulComp);
27111
+
27112
+ return _possibleConstructorReturn(this, (StatefulComp.__proto__ || Object.getPrototypeOf(StatefulComp)).apply(this, arguments));
27113
+ }
27114
+
27115
+ _createClass(StatefulComp, [{
27116
+ key: 'render',
27117
+
27092
27118
27093
- function WrappedComp() {
27094
- _classCallCheck(this, WrappedComp);
27119
+ // call the original function component inside the render method
27095
27120
27096
- return _possibleConstructorReturn(this, (WrappedComp.__proto__ || Object.getPrototypeOf(WrappedComp)).apply(this, arguments));
27121
+ // proxy react specific static variables to the stateful component
27122
+ // from the stateless component
27123
+ value: function render() {
27124
+ return StatelessComp.call(this, this.props, this.context);
27097
27125
}
27126
+ }]);
27098
27127
27099
- _createClass(WrappedComp, [{
27100
- key: 'render',
27101
- value: function render() {
27102
- return renderer.call(this, this.props, this.context);
27103
- }
27104
- }]);
27128
+ return StatefulComp;
27129
+ }(_react.Component), _class.displayName = StatelessComp.displayName || StatelessComp.name, _class.contextTypes = StatelessComp.contextTypes, _class.propTypes = StatelessComp.propTypes, _class.defaultProps = StatelessComp.defaultProps, _temp;
27130
+ }
27105
27131
27106
- return WrappedComp;
27107
- }(_react.Component);
27108
- WrappedComp.displayName = renderer.displayName || renderer.name;
27109
- WrappedComp.contextTypes = renderer.contextTypes;
27110
- WrappedComp.propTypes = renderer.propTypes;
27111
- WrappedComp.defaultProps = renderer.defaultProps;
27112
- }
27132
+ function hasComponentShouldUpdate(Comp) {
27133
+ return typeof Comp.prototype.shouldComponentUpdate === 'function';
27134
+ }
27113
27135
27114
- if (typeof WrappedComp.prototype.shouldComponentUpdate === 'function') {
27115
- throw new Error('Do not implement shouldComponentUpdate, easyState already optimizes it for you!');
27116
- }
27136
+ function toReactiveComp(Comp) {
27137
+ var _class2, _temp2;
27117
27138
27118
- return function (_WrappedComp) {
27119
- _inherits(EasyCompWrapper, _WrappedComp);
27139
+ // return a HOC which overwrites render, shouldComponentUpdate and componentWillUnmount
27140
+ // it decides when to run the new reactive methods and when to proxy to the original methods
27141
+ return _temp2 = _class2 = function (_Comp) {
27142
+ _inherits(EasyHOC, _Comp);
27120
27143
27121
- function EasyCompWrapper(props) {
27122
- _classCallCheck(this, EasyCompWrapper);
27144
+ // proxy react specific static variables to the HOC from the component
27145
+ function EasyHOC(props) {
27146
+ _classCallCheck(this, EasyHOC);
27123
27147
27124
- var _this2 = _possibleConstructorReturn(this, (EasyCompWrapper.__proto__ || Object.getPrototypeOf(EasyCompWrapper)).call(this, props));
27148
+ // auto bind non react specific original methods to the component instance
27149
+ var _this2 = _possibleConstructorReturn(this, (EasyHOC.__proto__ || Object.getPrototypeOf(EasyHOC)).call(this, props));
27125
27150
27126
- (0, _autoBind2.default)(_this2, WrappedComp.prototype, true);
27151
+ (0, _autoBind2.default)(_this2, Comp.prototype, true);
27152
+
27153
+ // turn the state into an observable object, which triggers rendering on mutations
27127
27154
_this2.state = (0, _observerUtil.observable)(_this2.state);
27128
27155
return _this2;
27129
27156
}
27130
27157
27131
- _createClass(EasyCompWrapper , [{
27158
+ _createClass(EasyHOC , [{
27132
27159
key: 'render',
27133
27160
value: function render() {
27134
27161
var _this3 = this;
27135
27162
27136
- if (!this[OBSERVED_RENDER]) {
27137
- this[OBSERVED_RENDER] = function () {
27138
- if (_this3[IS_DIRECT_RENDER]) {
27139
- _this3[RENDER_RESULT] = _get(EasyCompWrapper.prototype.__proto__ || Object.getPrototypeOf(EasyCompWrapper.prototype), 'render', _this3).call(_this3);
27163
+ // if it is the first direct render from react call there is no reactive render yet
27164
+ if (!this[REACTIVE_RENDER]) {
27165
+ var result = void 0;
27166
+ // create a reactive render, which is automatically called by easyState on relevant state and store mutations
27167
+ // the passed function is executed right away synchronously once by easyState
27168
+ this[REACTIVE_RENDER] = (0, _observerUtil.observe)(function () {
27169
+ // if it is the first (synchronous) execution, call the original component's render
27170
+ // this is necessary because forceUpdate can not be called synchronously inside render functions
27171
+ if (!_this3[REACTIVE_RENDER]) {
27172
+ result = _get(EasyHOC.prototype.__proto__ || Object.getPrototypeOf(EasyHOC.prototype), 'render', _this3).call(_this3);
27140
27173
} else {
27141
- _get(EasyCompWrapper.prototype.__proto__ || Object.getPrototypeOf(EasyCompWrapper.prototype), 'forceUpdate', _this3).call(_this3);
27174
+ // if it is a later reactive, asynchronous execution - triggered by easyState - forceUpdate the original component
27175
+ // this is necessary, because calling render would require the result to be returned
27176
+ // which is not possible from this asynchronous context
27177
+ _get(EasyHOC.prototype.__proto__ || Object.getPrototypeOf(EasyHOC.prototype), 'forceUpdate', _this3).call(_this3);
27142
27178
}
27143
- };
27179
+ });
27180
+ // return the result from super.render() inside the reactive render on the first render execution
27181
+ return result;
27182
+ } else {
27183
+ // return the original component's render result on direct calls from react
27184
+ return _get(EasyHOC.prototype.__proto__ || Object.getPrototypeOf(EasyHOC.prototype), 'render', this).call(this);
27144
27185
}
27186
+ }
27145
27187
27146
- this[IS_DIRECT_RENDER] = true;
27147
- this[OBSERVED_RENDER] = (0, _observerUtil.observe)(this[OBSERVED_RENDER]);
27148
- this[IS_DIRECT_RENDER] = false;
27188
+ // react should trigger updates on prop changes, while easyState handles state changes
27149
27189
27150
- return this[RENDER_RESULT];
27151
- }
27152
27190
}, {
27153
27191
key: 'shouldComponentUpdate',
27154
- value: function shouldComponentUpdate(nextProps, nextState ) {
27192
+ value: function shouldComponentUpdate(nextProps) {
27155
27193
var props = this.props;
27156
27194
27157
27195
var keys = Object.keys(props);
27158
27196
var nextKeys = Object.keys(nextProps);
27159
27197
27198
+ // component should update if the number of its props changed
27160
27199
if (keys.length !== nextKeys.length) {
27161
27200
return true;
27162
27201
}
27163
27202
27203
+ // component should update if any of its props changed value
27164
27204
var _iteratorNormalCompletion = true;
27165
27205
var _didIteratorError = false;
27166
27206
var _iteratorError = undefined;
@@ -27173,6 +27213,8 @@ function easyCompHOC(WrappedComp) {
27173
27213
return true;
27174
27214
}
27175
27215
}
27216
+
27217
+ // do not let react update the comp otherwise, leave state triggered updates to easyState
27176
27218
} catch (err) {
27177
27219
_didIteratorError = true;
27178
27220
_iteratorError = err;
@@ -27193,15 +27235,19 @@ function easyCompHOC(WrappedComp) {
27193
27235
}, {
27194
27236
key: 'componentWillUnmount',
27195
27237
value: function componentWillUnmount() {
27196
- if (_get(EasyCompWrapper.prototype.__proto__ || Object.getPrototypeOf(EasyCompWrapper.prototype), 'componentWillUnmount', this)) {
27197
- return _get(EasyCompWrapper.prototype.__proto__ || Object.getPrototypeOf(EasyCompWrapper.prototype), 'componentWillUnmount', this).call(this);
27238
+ // clean up memory used by easyState
27239
+ (0, _observerUtil.unobserve)(this[REACTIVE_RENDER]);
27240
+
27241
+ // also call user defined componentWillUnmount to allow the user
27242
+ // to clean up additional memory
27243
+ if (_get(EasyHOC.prototype.__proto__ || Object.getPrototypeOf(EasyHOC.prototype), 'componentWillUnmount', this)) {
27244
+ _get(EasyHOC.prototype.__proto__ || Object.getPrototypeOf(EasyHOC.prototype), 'componentWillUnmount', this).call(this);
27198
27245
}
27199
- (0, _observerUtil.unobserve)(this[OBSERVED_RENDER]);
27200
27246
}
27201
27247
}]);
27202
27248
27203
- return EasyCompWrapper ;
27204
- }(WrappedComp) ;
27249
+ return EasyHOC ;
27250
+ }(Comp), _class2.displayName = Comp.displayName || Comp.name, _class2.contextTypes = Comp.contextTypes, _class2.propTypes = Comp.propTypes, _class2.defaultProps = Comp.defaultProps, _temp2 ;
27205
27251
}
27206
27252
27207
27253
/***/ }),
@@ -27407,9 +27453,11 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
27407
27453
27408
27454
function easyStore(store) {
27409
27455
if ((typeof store === 'undefined' ? 'undefined' : _typeof(store)) !== 'object' || store === null) {
27410
- throw new TypeError('easyStore expects an object as argument. ');
27456
+ throw new TypeError('easyStore expects an object as argument');
27411
27457
}
27412
27458
27459
+ // create an observable object from the passed store
27460
+ // and bind all of its methods to the created observable
27413
27461
var observableStore = (0, _observerUtil.observable)(store);
27414
27462
(0, _autoBind2.default)(observableStore, store, false);
27415
27463
return observableStore;
0 commit comments