UNPKG

@tacky/store

Version:

State management framework based on react

170 lines (134 loc) 5.63 kB
import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck"; import _createClass from "@babel/runtime/helpers/esm/createClass"; import _inherits from "@babel/runtime/helpers/esm/inherits"; import _possibleConstructorReturn from "@babel/runtime/helpers/esm/possibleConstructorReturn"; import _getPrototypeOf from "@babel/runtime/helpers/esm/getPrototypeOf"; function _createSuper(Derived) { return function () { var Super = _getPrototypeOf(Derived), result; if (_isNativeReflectConstruct()) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } import * as React from 'react'; import ErrorBoundary from './ErrorBoundary'; import { store } from '../core/store'; import { depCollector } from '../core/collector'; /** * Returns a high order component with auto refresh feature. */ export function reactive(arg) { var decorator = function decorator(Target) { // const displayName: string = Target.displayName || Target.name || '<TACKY_COMPONENT>'; var _this; // Function component with do not have this context var ObservableTarget = function ObservableTarget(props) { depCollector.start(_this); var fn = Target; // target component don't use react.memo var result = fn(props); depCollector.end(); return result; }; if (typeof Target === 'function' && (!Target.prototype || !Target.prototype.render) && !Target.prototype.isReactClass && !React.Component.isPrototypeOf(Target)) { var Wrapper = /*#__PURE__*/function (_React$PureComponent) { _inherits(Wrapper, _React$PureComponent); var _super = _createSuper(Wrapper); function Wrapper() { _classCallCheck(this, Wrapper); return _super.apply(this, arguments); } _createClass(Wrapper, [{ key: "componentDidMount", value: function componentDidMount() { var _this2 = this; this.unsubscribeHandler = store.subscribe(function () { _this2.forceUpdate(); }, _this); } }, { key: "componentWillUnmount", value: function componentWillUnmount() { if (this.unsubscribeHandler !== void 0) { this.unsubscribeHandler(); } } }, { key: "render", value: function render() { return React.createElement(ErrorBoundary, null, React.createElement(ObservableTarget, Object.assign({}, this.props))); } }]); return Wrapper; }(React.PureComponent); var _baseRender = Wrapper.prototype.render; Wrapper.prototype.render = function () { _this = this; return _baseRender.call(this); }; copyStaticProperties(Target, Wrapper); return Wrapper; } // class component var target = Target.prototype || Target; var baseRender = target.render; var callback; function refreshChildComponentView() { var _this3 = this; return function () { return React.Component.prototype.forceUpdate.call(_this3); }; } target.render = function () { _this = this; callback = refreshChildComponentView.call(this); depCollector.start(this); var result = baseRender.call(this); depCollector.end(); return result; }; var ObservableTargetComponent = /*#__PURE__*/function (_React$PureComponent2) { _inherits(ObservableTargetComponent, _React$PureComponent2); var _super2 = _createSuper(ObservableTargetComponent); function ObservableTargetComponent() { _classCallCheck(this, ObservableTargetComponent); return _super2.apply(this, arguments); } _createClass(ObservableTargetComponent, [{ key: "componentDidMount", value: function componentDidMount() { this.unsubscribeHandler = store.subscribe(function () { callback(); }, _this); } }, { key: "componentWillUnmount", value: function componentWillUnmount() { if (this.unsubscribeHandler !== void 0) { this.unsubscribeHandler(); } } }, { key: "render", value: function render() { return React.createElement(ErrorBoundary, null, React.createElement(Target, Object.assign({}, this.props))); } }]); return ObservableTargetComponent; }(React.PureComponent); copyStaticProperties(Target, ObservableTargetComponent); return ObservableTargetComponent; }; if (arg === void 0) { // @reactive() return decorator; } // @reactive return decorator.call(null, arg); } // based on https://github.com/mridgway/hoist-non-react-statics/blob/master/src/index.js var hoistBlackList = { $$typeof: true, render: true, compare: true, type: true }; function copyStaticProperties(base, target) { var keys = Object.keys(base); for (var index = 0; index < keys.length; index++) { var key = keys[index]; if (hoistBlackList[key] === void 0) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(base, key)); } } }