"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

exports.__esModule = true;
exports.default = void 0;

var _loader = require("./loader");

var _findPath = require("./find-path");

var _pDefer = _interopRequireDefault(require("p-defer"));

const WAITING_FOR_HOT_UPDATE_TIMEOUT = 1000;
const COMPONENT_GRABBING_RETRY_LIMIT = 5;

class DevLoader extends _loader.BaseLoader {
  constructor(syncRequires, matchPaths) {
    const loadComponent = (chunkName, key = `components`, retry = 0) => {
      const module = this.syncRequires[key][chunkName];

      if (!module && retry < COMPONENT_GRABBING_RETRY_LIMIT) {
        return new Promise(resolve => {
          const checkAgain = () => loadComponent(chunkName, key, retry + 1);

          let waitingForHotUpdate = setTimeout(() => {
            waitingForHotUpdate = undefined;
            resolve(checkAgain());
          }, WAITING_FOR_HOT_UPDATE_TIMEOUT);
          this.waitingForHotUpdatePromise.promise.then(() => {
            if (waitingForHotUpdate) {
              clearTimeout(waitingForHotUpdate);
              resolve(checkAgain());
            }
          });
        });
      }

      return Promise.resolve(module);
    };

    super(loadComponent, matchPaths);
    this.waitingForHotUpdatePromise = (0, _pDefer.default)();
    this.syncRequires = syncRequires;
  }

  loadPage(pagePath) {
    const realPath = (0, _findPath.findPath)(pagePath);
    return super.loadPage(realPath).then(result => require(`./socketIo`).getPageData(realPath).then(() => result));
  }

  loadPageDataJson(rawPath) {
    return super.loadPageDataJson(rawPath).then(data => {
      // when we can't find a proper 404.html we fallback to dev-404-page
      // we need to make sure to mark it as not found.
      if (data.status === _loader.PageResourceStatus.Error && rawPath !== `/dev-404-page/`) {
        console.error(`404 page could not be found. Checkout https://www.gatsbyjs.org/docs/add-404-page/`);
        return this.loadPageDataJson(`/dev-404-page/`).then(result => Object.assign({}, data, result));
      }

      return data;
    });
  }

  doPrefetch(pagePath) {
    return Promise.resolve(require(`./socketIo`).getPageData(pagePath));
  }

  updateSyncRequires(syncRequires) {
    this.syncRequires = syncRequires;
    this.waitingForHotUpdatePromise.resolve();
    this.waitingForHotUpdatePromise = (0, _pDefer.default)();
  }

}

var _default = DevLoader;
exports.default = _default;