You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			317 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			JavaScript
		
	
			
		
		
	
	
			317 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			JavaScript
		
	
| "use strict";
 | |
| Object.defineProperty(exports, "__esModule", {
 | |
|     value: true
 | |
| });
 | |
| 0 && (module.exports = {
 | |
|     markAssetError: null,
 | |
|     isAssetError: null,
 | |
|     getClientBuildManifest: null,
 | |
|     createRouteLoader: null
 | |
| });
 | |
| function _export(target, all) {
 | |
|     for(var name in all)Object.defineProperty(target, name, {
 | |
|         enumerable: true,
 | |
|         get: all[name]
 | |
|     });
 | |
| }
 | |
| _export(exports, {
 | |
|     markAssetError: function() {
 | |
|         return markAssetError;
 | |
|     },
 | |
|     isAssetError: function() {
 | |
|         return isAssetError;
 | |
|     },
 | |
|     getClientBuildManifest: function() {
 | |
|         return getClientBuildManifest;
 | |
|     },
 | |
|     createRouteLoader: function() {
 | |
|         return createRouteLoader;
 | |
|     }
 | |
| });
 | |
| const _interop_require_default = require("@swc/helpers/_/_interop_require_default");
 | |
| const _getassetpathfromroute = /*#__PURE__*/ _interop_require_default._(require("../shared/lib/router/utils/get-asset-path-from-route"));
 | |
| const _trustedtypes = require("./trusted-types");
 | |
| const _requestidlecallback = require("./request-idle-callback");
 | |
| const _deploymentid = require("../build/deployment-id");
 | |
| // 3.8s was arbitrarily chosen as it's what https://web.dev/interactive
 | |
| // considers as "Good" time-to-interactive. We must assume something went
 | |
| // wrong beyond this point, and then fall-back to a full page transition to
 | |
| // show the user something of value.
 | |
| const MS_MAX_IDLE_DELAY = 3800;
 | |
| function withFuture(key, map, generator) {
 | |
|     let entry = map.get(key);
 | |
|     if (entry) {
 | |
|         if ("future" in entry) {
 | |
|             return entry.future;
 | |
|         }
 | |
|         return Promise.resolve(entry);
 | |
|     }
 | |
|     let resolver;
 | |
|     const prom = new Promise((resolve)=>{
 | |
|         resolver = resolve;
 | |
|     });
 | |
|     map.set(key, entry = {
 | |
|         resolve: resolver,
 | |
|         future: prom
 | |
|     });
 | |
|     return generator ? generator()// eslint-disable-next-line no-sequences
 | |
|     .then((value)=>(resolver(value), value)).catch((err)=>{
 | |
|         map.delete(key);
 | |
|         throw err;
 | |
|     }) : prom;
 | |
| }
 | |
| const ASSET_LOAD_ERROR = Symbol("ASSET_LOAD_ERROR");
 | |
| function markAssetError(err) {
 | |
|     return Object.defineProperty(err, ASSET_LOAD_ERROR, {});
 | |
| }
 | |
| function isAssetError(err) {
 | |
|     return err && ASSET_LOAD_ERROR in err;
 | |
| }
 | |
| function hasPrefetch(link) {
 | |
|     try {
 | |
|         link = document.createElement("link");
 | |
|         return(// detect IE11 since it supports prefetch but isn't detected
 | |
|         // with relList.support
 | |
|         !!window.MSInputMethodContext && !!document.documentMode || link.relList.supports("prefetch"));
 | |
|     } catch (e) {
 | |
|         return false;
 | |
|     }
 | |
| }
 | |
| const canPrefetch = hasPrefetch();
 | |
| const getAssetQueryString = ()=>{
 | |
|     return (0, _deploymentid.getDeploymentIdQueryOrEmptyString)();
 | |
| };
 | |
| function prefetchViaDom(href, as, link) {
 | |
|     return new Promise((resolve, reject)=>{
 | |
|         const selector = '\n      link[rel="prefetch"][href^="' + href + '"],\n      link[rel="preload"][href^="' + href + '"],\n      script[src^="' + href + '"]';
 | |
|         if (document.querySelector(selector)) {
 | |
|             return resolve();
 | |
|         }
 | |
|         link = document.createElement("link");
 | |
|         // The order of property assignment here is intentional:
 | |
|         if (as) link.as = as;
 | |
|         link.rel = "prefetch";
 | |
|         link.crossOrigin = process.env.__NEXT_CROSS_ORIGIN;
 | |
|         link.onload = resolve;
 | |
|         link.onerror = ()=>reject(markAssetError(new Error("Failed to prefetch: " + href)));
 | |
|         // `href` should always be last:
 | |
|         link.href = href;
 | |
|         document.head.appendChild(link);
 | |
|     });
 | |
| }
 | |
| function appendScript(src, script) {
 | |
|     return new Promise((resolve, reject)=>{
 | |
|         script = document.createElement("script");
 | |
|         // The order of property assignment here is intentional.
 | |
|         // 1. Setup success/failure hooks in case the browser synchronously
 | |
|         //    executes when `src` is set.
 | |
|         script.onload = resolve;
 | |
|         script.onerror = ()=>reject(markAssetError(new Error("Failed to load script: " + src)));
 | |
|         // 2. Configure the cross-origin attribute before setting `src` in case the
 | |
|         //    browser begins to fetch.
 | |
|         script.crossOrigin = process.env.__NEXT_CROSS_ORIGIN;
 | |
|         // 3. Finally, set the source and inject into the DOM in case the child
 | |
|         //    must be appended for fetching to start.
 | |
|         script.src = src;
 | |
|         document.body.appendChild(script);
 | |
|     });
 | |
| }
 | |
| // We wait for pages to be built in dev before we start the route transition
 | |
| // timeout to prevent an un-necessary hard navigation in development.
 | |
| let devBuildPromise;
 | |
| // Resolve a promise that times out after given amount of milliseconds.
 | |
| function resolvePromiseWithTimeout(p, ms, err) {
 | |
|     return new Promise((resolve, reject)=>{
 | |
|         let cancelled = false;
 | |
|         p.then((r)=>{
 | |
|             // Resolved, cancel the timeout
 | |
|             cancelled = true;
 | |
|             resolve(r);
 | |
|         }).catch(reject);
 | |
|         // We wrap these checks separately for better dead-code elimination in
 | |
|         // production bundles.
 | |
|         if (process.env.NODE_ENV === "development") {
 | |
|             (devBuildPromise || Promise.resolve()).then(()=>{
 | |
|                 (0, _requestidlecallback.requestIdleCallback)(()=>setTimeout(()=>{
 | |
|                         if (!cancelled) {
 | |
|                             reject(err);
 | |
|                         }
 | |
|                     }, ms));
 | |
|             });
 | |
|         }
 | |
|         if (process.env.NODE_ENV !== "development") {
 | |
|             (0, _requestidlecallback.requestIdleCallback)(()=>setTimeout(()=>{
 | |
|                     if (!cancelled) {
 | |
|                         reject(err);
 | |
|                     }
 | |
|                 }, ms));
 | |
|         }
 | |
|     });
 | |
| }
 | |
| function getClientBuildManifest() {
 | |
|     if (self.__BUILD_MANIFEST) {
 | |
|         return Promise.resolve(self.__BUILD_MANIFEST);
 | |
|     }
 | |
|     const onBuildManifest = new Promise((resolve)=>{
 | |
|         // Mandatory because this is not concurrent safe:
 | |
|         const cb = self.__BUILD_MANIFEST_CB;
 | |
|         self.__BUILD_MANIFEST_CB = ()=>{
 | |
|             resolve(self.__BUILD_MANIFEST);
 | |
|             cb && cb();
 | |
|         };
 | |
|     });
 | |
|     return resolvePromiseWithTimeout(onBuildManifest, MS_MAX_IDLE_DELAY, markAssetError(new Error("Failed to load client build manifest")));
 | |
| }
 | |
| function getFilesForRoute(assetPrefix, route) {
 | |
|     if (process.env.NODE_ENV === "development") {
 | |
|         const scriptUrl = assetPrefix + "/_next/static/chunks/pages" + encodeURI((0, _getassetpathfromroute.default)(route, ".js")) + getAssetQueryString();
 | |
|         return Promise.resolve({
 | |
|             scripts: [
 | |
|                 (0, _trustedtypes.__unsafeCreateTrustedScriptURL)(scriptUrl)
 | |
|             ],
 | |
|             // Styles are handled by `style-loader` in development:
 | |
|             css: []
 | |
|         });
 | |
|     }
 | |
|     return getClientBuildManifest().then((manifest)=>{
 | |
|         if (!(route in manifest)) {
 | |
|             throw markAssetError(new Error("Failed to lookup route: " + route));
 | |
|         }
 | |
|         const allFiles = manifest[route].map((entry)=>assetPrefix + "/_next/" + encodeURI(entry));
 | |
|         return {
 | |
|             scripts: allFiles.filter((v)=>v.endsWith(".js")).map((v)=>(0, _trustedtypes.__unsafeCreateTrustedScriptURL)(v) + getAssetQueryString()),
 | |
|             css: allFiles.filter((v)=>v.endsWith(".css")).map((v)=>v + getAssetQueryString())
 | |
|         };
 | |
|     });
 | |
| }
 | |
| function createRouteLoader(assetPrefix) {
 | |
|     const entrypoints = new Map();
 | |
|     const loadedScripts = new Map();
 | |
|     const styleSheets = new Map();
 | |
|     const routes = new Map();
 | |
|     function maybeExecuteScript(src) {
 | |
|         // With HMR we might need to "reload" scripts when they are
 | |
|         // disposed and readded. Executing scripts twice has no functional
 | |
|         // differences
 | |
|         if (process.env.NODE_ENV !== "development") {
 | |
|             let prom = loadedScripts.get(src.toString());
 | |
|             if (prom) {
 | |
|                 return prom;
 | |
|             }
 | |
|             // Skip executing script if it's already in the DOM:
 | |
|             if (document.querySelector('script[src^="' + src + '"]')) {
 | |
|                 return Promise.resolve();
 | |
|             }
 | |
|             loadedScripts.set(src.toString(), prom = appendScript(src));
 | |
|             return prom;
 | |
|         } else {
 | |
|             return appendScript(src);
 | |
|         }
 | |
|     }
 | |
|     function fetchStyleSheet(href) {
 | |
|         let prom = styleSheets.get(href);
 | |
|         if (prom) {
 | |
|             return prom;
 | |
|         }
 | |
|         styleSheets.set(href, prom = fetch(href).then((res)=>{
 | |
|             if (!res.ok) {
 | |
|                 throw new Error("Failed to load stylesheet: " + href);
 | |
|             }
 | |
|             return res.text().then((text)=>({
 | |
|                     href: href,
 | |
|                     content: text
 | |
|                 }));
 | |
|         }).catch((err)=>{
 | |
|             throw markAssetError(err);
 | |
|         }));
 | |
|         return prom;
 | |
|     }
 | |
|     return {
 | |
|         whenEntrypoint (route) {
 | |
|             return withFuture(route, entrypoints);
 | |
|         },
 | |
|         onEntrypoint (route, execute) {
 | |
|             (execute ? Promise.resolve().then(()=>execute()).then((exports1)=>({
 | |
|                     component: exports1 && exports1.default || exports1,
 | |
|                     exports: exports1
 | |
|                 }), (err)=>({
 | |
|                     error: err
 | |
|                 })) : Promise.resolve(undefined)).then((input)=>{
 | |
|                 const old = entrypoints.get(route);
 | |
|                 if (old && "resolve" in old) {
 | |
|                     if (input) {
 | |
|                         entrypoints.set(route, input);
 | |
|                         old.resolve(input);
 | |
|                     }
 | |
|                 } else {
 | |
|                     if (input) {
 | |
|                         entrypoints.set(route, input);
 | |
|                     } else {
 | |
|                         entrypoints.delete(route);
 | |
|                     }
 | |
|                     // when this entrypoint has been resolved before
 | |
|                     // the route is outdated and we want to invalidate
 | |
|                     // this cache entry
 | |
|                     routes.delete(route);
 | |
|                 }
 | |
|             });
 | |
|         },
 | |
|         loadRoute (route, prefetch) {
 | |
|             return withFuture(route, routes, ()=>{
 | |
|                 let devBuildPromiseResolve;
 | |
|                 if (process.env.NODE_ENV === "development") {
 | |
|                     devBuildPromise = new Promise((resolve)=>{
 | |
|                         devBuildPromiseResolve = resolve;
 | |
|                     });
 | |
|                 }
 | |
|                 return resolvePromiseWithTimeout(getFilesForRoute(assetPrefix, route).then((param)=>{
 | |
|                     let { scripts, css } = param;
 | |
|                     return Promise.all([
 | |
|                         entrypoints.has(route) ? [] : Promise.all(scripts.map(maybeExecuteScript)),
 | |
|                         Promise.all(css.map(fetchStyleSheet))
 | |
|                     ]);
 | |
|                 }).then((res)=>{
 | |
|                     return this.whenEntrypoint(route).then((entrypoint)=>({
 | |
|                             entrypoint,
 | |
|                             styles: res[1]
 | |
|                         }));
 | |
|                 }), MS_MAX_IDLE_DELAY, markAssetError(new Error("Route did not complete loading: " + route))).then((param)=>{
 | |
|                     let { entrypoint, styles } = param;
 | |
|                     const res = Object.assign({
 | |
|                         styles: styles
 | |
|                     }, entrypoint);
 | |
|                     return "error" in entrypoint ? entrypoint : res;
 | |
|                 }).catch((err)=>{
 | |
|                     if (prefetch) {
 | |
|                         // we don't want to cache errors during prefetch
 | |
|                         throw err;
 | |
|                     }
 | |
|                     return {
 | |
|                         error: err
 | |
|                     };
 | |
|                 }).finally(()=>devBuildPromiseResolve == null ? void 0 : devBuildPromiseResolve());
 | |
|             });
 | |
|         },
 | |
|         prefetch (route) {
 | |
|             // https://github.com/GoogleChromeLabs/quicklink/blob/453a661fa1fa940e2d2e044452398e38c67a98fb/src/index.mjs#L115-L118
 | |
|             // License: Apache 2.0
 | |
|             let cn;
 | |
|             if (cn = navigator.connection) {
 | |
|                 // Don't prefetch if using 2G or if Save-Data is enabled.
 | |
|                 if (cn.saveData || /2g/.test(cn.effectiveType)) return Promise.resolve();
 | |
|             }
 | |
|             return getFilesForRoute(assetPrefix, route).then((output)=>Promise.all(canPrefetch ? output.scripts.map((script)=>prefetchViaDom(script.toString(), "script")) : [])).then(()=>{
 | |
|                 (0, _requestidlecallback.requestIdleCallback)(()=>this.loadRoute(route, true).catch(()=>{}));
 | |
|             }).catch(// swallow prefetch errors
 | |
|             ()=>{});
 | |
|         }
 | |
|     };
 | |
| }
 | |
| 
 | |
| if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
 | |
|   Object.defineProperty(exports.default, '__esModule', { value: true });
 | |
|   Object.assign(exports.default, exports);
 | |
|   module.exports = exports.default;
 | |
| }
 | |
| 
 | |
| //# sourceMappingURL=route-loader.js.map
 |