UNPKG

@tdb/web

Version:

Common condiguration for serving a web-site and testing web-based UI components.

181 lines (142 loc) 5.12 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime-corejs2/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _promise = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/promise")); var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/createClass")); var _EventEmitter = _interopRequireDefault(require("./EventEmitter")); /* global window, document */ var webpackModule = module; var PageLoader = /*#__PURE__*/ function () { function PageLoader(buildId, assetPrefix) { (0, _classCallCheck2.default)(this, PageLoader); this.buildId = buildId; this.assetPrefix = assetPrefix; this.pageCache = {}; this.pageLoadedHandlers = {}; this.pageRegisterEvents = new _EventEmitter.default(); this.loadingRoutes = {}; } (0, _createClass2.default)(PageLoader, [{ key: "normalizeRoute", value: function normalizeRoute(route) { if (route[0] !== '/') { throw new Error("Route name should start with a \"/\", got \"".concat(route, "\"")); } route = route.replace(/\/index$/, '/'); if (route === '/') return route; return route.replace(/\/$/, ''); } }, { key: "loadPage", value: function loadPage(route) { var _this = this; route = this.normalizeRoute(route); return new _promise.default(function (resolve, reject) { var fire = function fire(_ref) { var error = _ref.error, page = _ref.page; _this.pageRegisterEvents.off(route, fire); delete _this.loadingRoutes[route]; if (error) { reject(error); } else { resolve(page); } }; // If there's a cached version of the page, let's use it. var cachedPage = _this.pageCache[route]; if (cachedPage) { var error = cachedPage.error, page = cachedPage.page; error ? reject(error) : resolve(page); return; } // Register a listener to get the page _this.pageRegisterEvents.on(route, fire); // If the page is loading via SSR, we need to wait for it // rather downloading it again. if (document.getElementById("__NEXT_PAGE__".concat(route))) { return; } // Load the script if not asked to load yet. if (!_this.loadingRoutes[route]) { _this.loadScript(route); _this.loadingRoutes[route] = true; } }); } }, { key: "loadScript", value: function loadScript(route) { var _this2 = this; route = this.normalizeRoute(route); var scriptRoute = route === '/' ? '/index.js' : "".concat(route, ".js"); var script = document.createElement('script'); var url = "".concat(this.assetPrefix, "/_next/static/").concat(encodeURIComponent(this.buildId), "/pages").concat(scriptRoute); script.src = url; script.onerror = function () { var error = new Error("Error when loading route: ".concat(route)); error.code = 'PAGE_LOAD_ERROR'; _this2.pageRegisterEvents.emit(route, { error: error }); }; document.body.appendChild(script); } // This method if called by the route code. }, { key: "registerPage", value: function registerPage(route, regFn) { var _this3 = this; var register = function register() { try { var _regFn = regFn(), error = _regFn.error, page = _regFn.page; _this3.pageCache[route] = { error: error, page: page }; _this3.pageRegisterEvents.emit(route, { error: error, page: page }); } catch (error) { _this3.pageCache[route] = { error: error }; _this3.pageRegisterEvents.emit(route, { error: error }); } }; // Wait for webpack to become idle if it's not. // More info: https://github.com/zeit/next.js/pull/1511 if (webpackModule && webpackModule.hot && webpackModule.hot.status() !== 'idle') { console.log("Waiting for webpack to become \"idle\" to initialize the page: \"".concat(route, "\"")); var check = function check(status) { if (status === 'idle') { webpackModule.hot.removeStatusHandler(check); register(); } }; webpackModule.hot.status(check); } else { register(); } } }, { key: "clearCache", value: function clearCache(route) { route = this.normalizeRoute(route); delete this.pageCache[route]; delete this.loadingRoutes[route]; var script = document.getElementById("__NEXT_PAGE__".concat(route)); if (script) { script.parentNode.removeChild(script); } } }]); return PageLoader; }(); exports.default = PageLoader;