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
		
	
| 
											9 months ago
										 | "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
 |