react-static
Version:
A progressive static site generator for React
175 lines (138 loc) • 16.6 kB
JavaScript
;
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
var _react = _interopRequireWildcard(require("react"));
var _2 = require("..");
var _utils = require("../utils");
var _useStaticInfo = require("../hooks/useStaticInfo");
var _useRoutePath = require("../hooks/useRoutePath");
//
/**
*
* @param {string} path
* @returns {React.ComponentType<{}> | false}
*/
function getTemplateForPath(path) {
var is404 = (0, _utils.is404Path)(path);
var Comp = _2.templatesByPath[path] || false;
if (!Comp && _2.templateErrorByPath[path]) {
is404 = true;
Comp = _2.templatesByPath[_utils.PATH_404] || false;
}
return {
is404: is404,
Comp: Comp
};
}
/**
*
*
* @param {string} path
* @returns {React.ReactNode | false}
*/
function getComponentForPath(path) {
var _getTemplateForPath = getTemplateForPath(path),
Comp = _getTemplateForPath.Comp,
is404 = _getTemplateForPath.is404;
if (is404 && !Comp) {
return false;
}
return /*#__PURE__*/_react["default"].createElement(Comp, {
is404: is404
});
}
var RoutesInner = function RoutesInner(_ref) {
var routePath = _ref.routePath,
renderFn = _ref.render;
// Let the user specify a manual routePath.
// This is useful for animations where multiple routes
// might be rendered simultaneously
var staticInfo = (0, _useStaticInfo.useStaticInfo)(); // eslint-disable-next-line
var _useState = (0, _react.useState)(0),
_useState2 = (0, _slicedToArray2["default"])(_useState, 2),
_ = _useState2[0],
setCount = _useState2[1]; // If in production, make sure the staticInfo is ingested into the
// cache
(0, _react.useState)(function () {
// useState's initializer will only fire once per component instance,
// and it will fire during the first render (unlike an effect, which
// only fires after the first render). Think of it like a constructor call.
if (process.env.REACT_STATIC_ENV === 'production' && staticInfo) {
var path = staticInfo.path,
sharedData = staticInfo.sharedData,
sharedHashesByProp = staticInfo.sharedHashesByProp,
template = staticInfo.template; // Hydrate routeInfoByPath with the embedded routeInfo
_2.routeInfoByPath[path] = staticInfo; // Hydrate sharedDataByHash with the embedded routeInfo
Object.keys(sharedHashesByProp).forEach(function (propKey) {
_2.sharedDataByHash[sharedHashesByProp[propKey]] = sharedData[propKey];
}); // In SRR and production, synchronously register the template for the
// initial path
(0, _2.registerTemplateForPath)(path, template); // For a 404 route we will register the current route as invalid
if ((0, _utils.is404Path)(path)) {
var currentPath = (0, _utils.getCurrentRoutePath)(); // As long as we didn't navigate to the 404.html page directly
if ((0, _utils.is404Path)(currentPath)) {
_2.routeErrorByPath[currentPath] = true;
_2.templateErrorByPath[currentPath] = true;
}
}
}
});
(0, _react.useEffect)(function () {
return (0, _2.onReloadTemplates)(function () {
setCount(function (old) {
return old + 1;
});
});
}); // If SSR, force the routePath to be the statically exported one
if (typeof document === 'undefined') {
routePath = staticInfo.path;
} else if (!routePath) {
// If a routePath is still not defined in the browser,
// use the window location as the default
routePath = decodeURIComponent(window.location.href);
}
routePath = (0, _useRoutePath.useRoutePath)(routePath); // Try and get the template
var _getTemplateForPath2 = getTemplateForPath(routePath),
Comp = _getTemplateForPath2.Comp,
is404 = _getTemplateForPath2.is404;
if (!Comp) {
if (is404) {
throw new Error('Neither the page template or 404 template could be found. This means something is terribly wrong. Please, file an issue!');
} // Suspend while we fetch the resource
throw Promise.all([new Promise(function (resolve) {
return setTimeout(resolve, 500);
}), (0, _2.prefetch)(routePath, {
priority: true
})]);
}
return /*#__PURE__*/_react["default"].createElement(_useRoutePath.routePathContext.Provider, {
value: routePath
}, renderFn ? renderFn({
routePath: routePath,
getComponentForPath: getComponentForPath
}) : /*#__PURE__*/_react["default"].createElement(Comp, {
is404: is404
}));
};
var Routes = function Routes(_ref2) {
var originalProps = (0, _extends2["default"])({}, _ref2);
// Once a routePath goes into the Routes component,
// useRoutePath must ALWAYS return the routePath used
// in its parent, so we pass it down as context
// Get the Routes hook
var CompWrapper = (0, _react.useMemo)(function () {
return _2.plugins.Routes(function (props) {
return /*#__PURE__*/_react["default"].createElement(RoutesInner, props);
});
}, [_2.plugins]); // Pass all props so that plugins can use it
return /*#__PURE__*/_react["default"].createElement(CompWrapper, originalProps);
};
var _default = Routes;
exports["default"] = _default;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9icm93c2VyL2NvbXBvbmVudHMvUm91dGVzLmpzIl0sIm5hbWVzIjpbImdldFRlbXBsYXRlRm9yUGF0aCIsInBhdGgiLCJpczQwNCIsIkNvbXAiLCJ0ZW1wbGF0ZXNCeVBhdGgiLCJ0ZW1wbGF0ZUVycm9yQnlQYXRoIiwiUEFUSF80MDQiLCJnZXRDb21wb25lbnRGb3JQYXRoIiwiUmVhY3QiLCJjcmVhdGVFbGVtZW50IiwiUm91dGVzSW5uZXIiLCJyb3V0ZVBhdGgiLCJyZW5kZXJGbiIsInJlbmRlciIsInN0YXRpY0luZm8iLCJfIiwic2V0Q291bnQiLCJwcm9jZXNzIiwiZW52IiwiUkVBQ1RfU1RBVElDX0VOViIsInNoYXJlZERhdGEiLCJzaGFyZWRIYXNoZXNCeVByb3AiLCJ0ZW1wbGF0ZSIsInJvdXRlSW5mb0J5UGF0aCIsIk9iamVjdCIsImtleXMiLCJmb3JFYWNoIiwicHJvcEtleSIsInNoYXJlZERhdGFCeUhhc2giLCJjdXJyZW50UGF0aCIsInJvdXRlRXJyb3JCeVBhdGgiLCJvbGQiLCJkb2N1bWVudCIsImRlY29kZVVSSUNvbXBvbmVudCIsIndpbmRvdyIsImxvY2F0aW9uIiwiaHJlZiIsIkVycm9yIiwiUHJvbWlzZSIsImFsbCIsInJlc29sdmUiLCJzZXRUaW1lb3V0IiwicHJpb3JpdHkiLCJSb3V0ZXMiLCJvcmlnaW5hbFByb3BzIiwiQ29tcFdyYXBwZXIiLCJwbHVnaW5zIiwicHJvcHMiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7OztBQUFBOztBQUVBOztBQVdBOztBQUNBOztBQUNBOztBQWRBOztBQWdCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBU0Esa0JBQVQsQ0FBNEJDLElBQTVCLEVBQWtDO0FBQ2hDLE1BQUlDLEtBQUssR0FBRyxzQkFBVUQsSUFBVixDQUFaO0FBQ0EsTUFBSUUsSUFBSSxHQUFHQyxtQkFBZ0JILElBQWhCLEtBQXlCLEtBQXBDOztBQUVBLE1BQUksQ0FBQ0UsSUFBRCxJQUFTRSx1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LGdDQUFDLFdBQUQsRUFBaUJBLEtBQWpCLENBQUo7QUFBQSxLQUFwQixDQUFOO0FBQUEsR0FEa0IsRUFFbEIsQ0FBQ0QsVUFBRCxDQUZrQixDQUFwQixDQU51QyxDQVd2Qzs7QUFDQSxzQkFBTyxnQ0FBQyxXQUFELEVBQWlCRixhQUFqQixDQUFQO0FBQ0QsQ0FiRDs7ZUFlZUQsTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBSZWFjdCwgeyB1c2VTdGF0ZSwgdXNlTWVtbywgdXNlRWZmZWN0IH0gZnJvbSAncmVhY3QnXG4vL1xuaW1wb3J0IHtcbiAgdGVtcGxhdGVzQnlQYXRoLFxuICB0ZW1wbGF0ZUVycm9yQnlQYXRoLFxuICByb3V0ZUluZm9CeVBhdGgsXG4gIHNoYXJlZERhdGFCeUhhc2gsXG4gIHJlZ2lzdGVyVGVtcGxhdGVGb3JQYXRoLFxuICBwcmVmZXRjaCxcbiAgcGx1Z2lucyxcbiAgb25SZWxvYWRUZW1wbGF0ZXMsXG4gIHJvdXRlRXJyb3JCeVBhdGgsXG59IGZyb20gJy4uJ1xuaW1wb3J0IHsgZ2V0Q3VycmVudFJvdXRlUGF0aCwgaXM0MDRQYXRoLCBQQVRIXzQwNCB9IGZyb20gJy4uL3V0aWxzJ1xuaW1wb3J0IHsgdXNlU3RhdGljSW5mbyB9IGZyb20gJy4uL2hvb2tzL3VzZVN0YXRpY0luZm8nXG5pbXBvcnQgeyByb3V0ZVBhdGhDb250ZXh0LCB1c2VSb3V0ZVBhdGggfSBmcm9tICcuLi9ob29rcy91c2VSb3V0ZVBhdGgnXG5cbi8qKlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBwYXRoXG4gKiBAcmV0dXJucyB7UmVhY3QuQ29tcG9uZW50VHlwZTx7fT4gfCBmYWxzZX1cbiAqL1xuZnVuY3Rpb24gZ2V0VGVtcGxhdGVGb3JQYXRoKHBhdGgpIHtcbiAgbGV0IGlzNDA0ID0gaXM0MDRQYXRoKHBhdGgpXG4gIGxldCBDb21wID0gdGVtcGxhdGVzQnlQYXRoW3BhdGhdIHx8IGZhbHNlXG5cbiAgaWYgKCFDb21wICYmIHRlbXBsYXRlRXJyb3JCeVBhdGhbcGF0aF0pIHtcbiAgICBpczQwNCA9IHRydWVcbiAgICBDb21wID0gdGVtcGxhdGVzQnlQYXRoW1BBVEhfNDA0XSB8fCBmYWxzZVxuICB9XG5cbiAgcmV0dXJuIHsgaXM0MDQsIENvbXAgfVxufVxuXG4vKipcbiAqXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHBhdGhcbiAqIEByZXR1cm5zIHtSZWFjdC5SZWFjdE5vZGUgfCBmYWxzZX1cbiAqL1xuZnVuY3Rpb24gZ2V0Q29tcG9uZW50Rm9yUGF0aChwYXRoKSB7XG4gIGNvbnN0IHsgQ29tcCwgaXM0MDQgfSA9IGdldFRlbXBsYXRlRm9yUGF0aChwYXRoKVxuICBpZiAoaXM0MDQgJiYgIUNvbXApIHtcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuXG4gIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KENvbXAsIHsgaXM0MDQgfSlcbn1cblxuY29uc3QgUm91dGVzSW5uZXIgPSAoeyByb3V0ZVBhdGgsIHJlbmRlcjogcmVuZGVyRm4gfSkgPT4ge1xuICAvLyBMZXQgdGhlIHVzZXIgc3BlY2lmeSBhIG1hbnVhbCByb3V0ZVBhdGguXG4gIC8vIFRoaXMgaXMgdXNlZnVsIGZvciBhbmltYXRpb25zIHdoZXJlIG11bHRpcGxlIHJvdXRlc1xuICAvLyBtaWdodCBiZSByZW5kZXJlZCBzaW11bHRhbmVvdXNseVxuXG4gIGNvbnN0IHN0YXRpY0luZm8gPSB1c2VTdGF0aWNJbmZvKClcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lXG4gIGNvbnN0IFtfLCBzZXRDb3VudF0gPSB1c2VTdGF0ZSgwKVxuXG4gIC8vIElmIGluIHByb2R1Y3Rpb24sIG1ha2Ugc3VyZSB0aGUgc3RhdGljSW5mbyBpcyBpbmdlc3RlZCBpbnRvIHRoZVxuICAvLyBjYWNoZVxuICB1c2VTdGF0ZSgoKSA9PiB7XG4gICAgLy8gdXNlU3RhdGUncyBpbml0aWFsaXplciB3aWxsIG9ubHkgZmlyZSBvbmNlIHBlciBjb21wb25lbnQgaW5zdGFuY2UsXG4gICAgLy8gYW5kIGl0IHdpbGwgZmlyZSBkdXJpbmcgdGhlIGZpcnN0IHJlbmRlciAodW5saWtlIGFuIGVmZmVjdCwgd2hpY2hcbiAgICAvLyBvbmx5IGZpcmVzIGFmdGVyIHRoZSBmaXJzdCByZW5kZXIpLiBUaGluayBvZiBpdCBsaWtlIGEgY29uc3RydWN0b3IgY2FsbC5cbiAgICBpZiAocHJvY2Vzcy5lbnYuUkVBQ1RfU1RBVElDX0VOViA9PT0gJ3Byb2R1Y3Rpb24nICYmIHN0YXRpY0luZm8pIHtcbiAgICAgIGNvbnN0IHsgcGF0aCwgc2hhcmVkRGF0YSwgc2hhcmVkSGFzaGVzQnlQcm9wLCB0ZW1wbGF0ZSB9ID0gc3RhdGljSW5mb1xuXG4gICAgICAvLyBIeWRyYXRlIHJvdXRlSW5mb0J5UGF0aCB3aXRoIHRoZSBlbWJlZGRlZCByb3V0ZUluZm9cbiAgICAgIHJvdXRlSW5mb0J5UGF0aFtwYXRoXSA9IHN0YXRpY0luZm9cblxuICAgICAgLy8gSHlkcmF0ZSBzaGFyZWREYXRhQnlIYXNoIHdpdGggdGhlIGVtYmVkZGVkIHJvdXRlSW5mb1xuICAgICAgT2JqZWN0LmtleXMoc2hhcmVkSGFzaGVzQnlQcm9wKS5mb3JFYWNoKHByb3BLZXkgPT4ge1xuICAgICAgICBzaGFyZWREYXRhQnlIYXNoW3NoYXJlZEhhc2hlc0J5UHJvcFtwcm9wS2V5XV0gPSBzaGFyZWREYXRhW3Byb3BLZXldXG4gICAgICB9KVxuXG4gICAgICAvLyBJbiBTUlIgYW5kIHByb2R1Y3Rpb24sIHN5bmNocm9ub3VzbHkgcmVnaXN0ZXIgdGhlIHRlbXBsYXRlIGZvciB0aGVcbiAgICAgIC8vIGluaXRpYWwgcGF0aFxuICAgICAgcmVnaXN0ZXJUZW1wbGF0ZUZvclBhdGgocGF0aCwgdGVtcGxhdGUpXG5cbiAgICAgIC8vIEZvciBhIDQwNCByb3V0ZSB3ZSB3aWxsIHJlZ2lzdGVyIHRoZSBjdXJyZW50IHJvdXRlIGFzIGludmFsaWRcbiAgICAgIGlmIChpczQwNFBhdGgocGF0aCkpIHtcbiAgICAgICAgY29uc3QgY3VycmVudFBhdGggPSBnZXRDdXJyZW50Um91dGVQYXRoKClcbiAgICAgICAgLy8gQXMgbG9uZyBhcyB3ZSBkaWRuJ3QgbmF2aWdhdGUgdG8gdGhlIDQwNC5odG1sIHBhZ2UgZGlyZWN0bHlcbiAgICAgICAgaWYgKGlzNDA0UGF0aChjdXJyZW50UGF0aCkpIHtcbiAgICAgICAgICByb3V0ZUVycm9yQnlQYXRoW2N1cnJlbnRQYXRoXSA9IHRydWVcbiAgICAgICAgICB0ZW1wbGF0ZUVycm9yQnlQYXRoW2N1cnJlbnRQYXRoXSA9IHRydWVcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfSlcblxuICB1c2VFZmZlY3QoKCkgPT5cbiAgICBvblJlbG9hZFRlbXBsYXRlcygoKSA9PiB7XG4gICAgICBzZXRDb3VudChvbGQgPT4gb2xkICsgMSlcbiAgICB9KVxuICApXG5cbiAgLy8gSWYgU1NSLCBmb3JjZSB0aGUgcm91dGVQYXRoIHRvIGJlIHRoZSBzdGF0aWNhbGx5IGV4cG9ydGVkIG9uZVxuICBpZiAodHlwZW9mIGRvY3VtZW50ID09PSAndW5kZWZpbmVkJykge1xuICAgIHJvdXRlUGF0aCA9IHN0YXRpY0luZm8ucGF0aFxuICB9IGVsc2UgaWYgKCFyb3V0ZVBhdGgpIHtcbiAgICAvLyBJZiBhIHJvdXRlUGF0aCBpcyBzdGlsbCBub3QgZGVmaW5lZCBpbiB0aGUgYnJvd3NlcixcbiAgICAvLyB1c2UgdGhlIHdpbmRvdyBsb2NhdGlvbiBhcyB0aGUgZGVmYXVsdFxuICAgIHJvdXRlUGF0aCA9IGRlY29kZVVSSUNvbXBvbmVudCh3aW5kb3cubG9jYXRpb24uaHJlZilcbiAgfVxuXG4gIHJvdXRlUGF0aCA9IHVzZVJvdXRlUGF0aChyb3V0ZVBhdGgpXG5cbiAgLy8gVHJ5IGFuZCBnZXQgdGhlIHRlbXBsYXRlXG4gIGNvbnN0IHsgQ29tcCwgaXM0MDQgfSA9IGdldFRlbXBsYXRlRm9yUGF0aChyb3V0ZVBhdGgpXG5cbiAgaWYgKCFDb21wKSB7XG4gICAgaWYgKGlzNDA0KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICdOZWl0aGVyIHRoZSBwYWdlIHRlbXBsYXRlIG9yIDQwNCB0ZW1wbGF0ZSBjb3VsZCBiZSBmb3VuZC4gVGhpcyBtZWFucyBzb21ldGhpbmcgaXMgdGVycmlibHkgd3JvbmcuIFBsZWFzZSwgZmlsZSBhbiBpc3N1ZSEnXG4gICAgICApXG4gICAgfVxuICAgIC8vIFN1c3BlbmQgd2hpbGUgd2UgZmV0Y2ggdGhlIHJlc291cmNlXG4gICAgdGhyb3cgUHJvbWlzZS5hbGwoW1xuICAgICAgbmV3IFByb21pc2UocmVzb2x2ZSA9PiBzZXRUaW1lb3V0KHJlc29sdmUsIDUwMCkpLFxuICAgICAgcHJlZmV0Y2gocm91dGVQYXRoLCB7IHByaW9yaXR5OiB0cnVlIH0pLFxuICAgIF0pXG4gIH1cblxuICByZXR1cm4gKFxuICAgIDxyb3V0ZVBhdGhDb250ZXh0LlByb3ZpZGVyIHZhbHVlPXtyb3V0ZVBhdGh9PlxuICAgICAge3JlbmRlckZuID8gKFxuICAgICAgICByZW5kZXJGbih7IHJvdXRlUGF0aCwgZ2V0Q29tcG9uZW50Rm9yUGF0aCB9KVxuICAgICAgKSA6IChcbiAgICAgICAgPENvbXAgaXM0MDQ9e2lzNDA0fSAvPlxuICAgICAgKX1cbiAgICA8L3JvdXRlUGF0aENvbnRleHQuUHJvdmlkZXI+XG4gIClcbn1cblxuY29uc3QgUm91dGVzID0gKHsgLi4ub3JpZ2luYWxQcm9wcyB9KSA9PiB7XG4gIC8vIE9uY2UgYSByb3V0ZVBhdGggZ29lcyBpbnRvIHRoZSBSb3V0ZXMgY29tcG9uZW50LFxuICAvLyB1c2VSb3V0ZVBhdGggbXVzdCBBTFdBWVMgcmV0dXJuIHRoZSByb3V0ZVBhdGggdXNlZFxuICAvLyBpbiBpdHMgcGFyZW50LCBzbyB3ZSBwYXNzIGl0IGRvd24gYXMgY29udGV4dFxuXG4gIC8vIEdldCB0aGUgUm91dGVzIGhvb2tcbiAgY29uc3QgQ29tcFdyYXBwZXIgPSB1c2VNZW1vKFxuICAgICgpID0+IHBsdWdpbnMuUm91dGVzKHByb3BzID0+IDxSb3V0ZXNJbm5lciB7Li4ucHJvcHN9IC8+KSxcbiAgICBbcGx1Z2luc11cbiAgKVxuXG4gIC8vIFBhc3MgYWxsIHByb3BzIHNvIHRoYXQgcGx1Z2lucyBjYW4gdXNlIGl0XG4gIHJldHVybiA8Q29tcFdyYXBwZXIgey4uLm9yaWdpbmFsUHJvcHN9IC8+XG59XG5cbmV4cG9ydCBkZWZhdWx0IFJvdXRlc1xuIl19