UNPKG

dash-renderer

Version:

render dash components in react

183 lines (179 loc) 7.82 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _ramda = require("ramda"); var _react = _interopRequireDefault(require("react")); var _propTypes = _interopRequireDefault(require("prop-types")); var _reactRedux = require("react-redux"); var _api = _interopRequireDefault(require("../../actions/api")); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; } function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } } function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; } class Reloader extends _react.default.Component { constructor(props) { super(props); if (props.config.hot_reload) { var _props$config$hot_rel = props.config.hot_reload, interval = _props$config$hot_rel.interval, max_retry = _props$config$hot_rel.max_retry; this.state = { interval, disabled: false, intervalId: null, packages: null, max_retry }; } else { this.state = { disabled: true }; } this._retry = 0; this._head = document.querySelector('head'); this.clearInterval = this.clearInterval.bind(this); } clearInterval() { window.clearInterval(this.state.intervalId); this.setState({ intervalId: null }); } static getDerivedStateFromProps(props) { /* * Save the non-loading requests in the state in order to compare * current hashes with previous hashes. * Note that if there wasn't a "loading" state for the requests, * then we could simply compare `props` with `prevProps` in * `componentDidUpdate`. */ if (!(0, _ramda.isEmpty)(props.reloadRequest) && props.reloadRequest.status !== 'loading') { return { reloadRequest: props.reloadRequest }; } return null; } componentDidUpdate(prevProps, prevState) { var reloadRequest = this.state.reloadRequest; var dispatch = this.props.dispatch; // In the beginning, reloadRequest won't be defined if (!reloadRequest) { return; } /* * When reloadRequest is first defined, prevState won't be defined * for one render loop. * The first reloadRequest defines the initial/baseline hash - * it doesn't require a reload */ if (!(0, _ramda.has)('reloadRequest', prevState)) { return; } if (reloadRequest.status === 200 && (0, _ramda.path)(['content', 'reloadHash'], reloadRequest) !== (0, _ramda.path)(['reloadRequest', 'content', 'reloadHash'], prevState)) { // Check for CSS (!content.hard) or new package assets if (reloadRequest.content.hard || !(0, _ramda.equals)(reloadRequest.content.packages.length, (0, _ramda.pathOr)([], ['reloadRequest', 'content', 'packages'], prevState).length) || !(0, _ramda.equals)((0, _ramda.sort)((0, _ramda.comparator)(_ramda.lt), reloadRequest.content.packages), (0, _ramda.sort)((0, _ramda.comparator)(_ramda.lt), (0, _ramda.pathOr)([], ['reloadRequest', 'content', 'packages'], prevState)))) { // Look if it was a css file. var was_css = false; // eslint-disable-next-line prefer-const var _iterator = _createForOfIteratorHelper(reloadRequest.content.files), _step; try { for (_iterator.s(); !(_step = _iterator.n()).done;) { var a = _step.value; if (a.is_css) { was_css = true; var nodesToDisable = []; // Search for the old file by xpath. var it = document.evaluate("//link[contains(@href, \"".concat(a.url, "\")]"), this._head); var node = it.iterateNext(); while (node) { nodesToDisable.push(node); node = it.iterateNext(); } (0, _ramda.forEach)(n => n.setAttribute('disabled', 'disabled'), nodesToDisable); if (a.modified > 0) { var link = document.createElement('link'); link.href = "".concat(a.url, "?m=").concat(a.modified); link.type = 'text/css'; link.rel = 'stylesheet'; this._head.appendChild(link); // Else the file was deleted. } } else { // If there's another kind of file here do a hard reload. was_css = false; break; } } } catch (err) { _iterator.e(err); } finally { _iterator.f(); } if (!was_css) { // Assets file have changed // or a component lib has been added/removed - // Must do a hard reload window.location.reload(); } } else { // Backend code changed - can do a soft reload in place dispatch({ type: 'RELOAD' }); } } else if (this.state.intervalId !== null && reloadRequest.status === 500) { if (this._retry > this.state.max_retry) { this.clearInterval(); // Integrate with dev tools ui?! window.alert("Hot reloading is disabled after failing ".concat(this._retry, " times. ") + 'Please check your application for errors, then refresh the page.'); } this._retry++; } } componentDidMount() { var _this$props = this.props, dispatch = _this$props.dispatch, reloadRequest = _this$props.reloadRequest; var _this$state = this.state, disabled = _this$state.disabled, interval = _this$state.interval; if (!disabled && !this.state.intervalId) { var intervalId = window.setInterval(() => { // Prevent requests from piling up - reloading can take // many seconds (10-30) and the interval is 3s by default if (reloadRequest.status !== 'loading') { dispatch((0, _api.default)('_reload-hash', 'GET', 'reloadRequest')); } }, interval); this.setState({ intervalId }); } } componentWillUnmount() { if (!this.state.disabled && this.state.intervalId) { this.clearInterval(); } } render() { return null; } } Reloader.defaultProps = {}; Reloader.propTypes = { id: _propTypes.default.string, config: _propTypes.default.object, reloadRequest: _propTypes.default.object, dispatch: _propTypes.default.func, interval: _propTypes.default.number }; var _default = exports.default = (0, _reactRedux.connect)(state => ({ config: state.config, reloadRequest: state.reloadRequest }), dispatch => ({ dispatch }))(Reloader);