@builder.io/qwik
Version:
An Open-Source sub-framework designed with a focus on server-side-rendering, lazy-loading, and styling/animation.
5 lines (4 loc) • 15.9 kB
JavaScript
const QWIK_PREFETCH = "(()=>{const t=Number.MAX_SAFE_INTEGER>>>1;function n(n,i){const[o,s]=c(i),a=n.t.find((t=>o===t.i));if(a)return n.o(\"intercepting\",i.pathname),e(n,a,[s],t).then((()=>function(t,n){const e=t.u.find((t=>t.l.pathname===n.pathname));return e?e.$.then((t=>t.clone())):(t.o(\"CACHE HIT\",n.pathname),t.h(n))}(n,i)))}async function e(n,e,o,c){const a=new Map;o.forEach((t=>s(e,a,t,c))),await Promise.all(Array.from(a.entries()).map((([i,o])=>async function(n,e,i){let o=n.u.find((t=>t.l.pathname===e.pathname));const s=i>=t?\"direct\":\"prefetch\";if(o){const t=o.p?\"fetching\":\"waiting\";o.m<i?(n.o(\"queue update priority\",t,e.pathname),o.m=i):n.o(\"already in queue\",s,t,e.pathname)}else await n.h(e)||(n.o(\"enqueue\",s,e.pathname),o={m:i,l:e,v:null,$:null,p:!1},o.$=new Promise((t=>o.v=t)),n.u.push(o));return o}(n,new URL(e.i+i,n.l.origin),o)))),i(n)}function i(n){n.u.sort(o);let e=0;for(const o of n.u)if(o.p)e++;else if(n.C()&&(e<n.T||o.m>=t)){o.p=!0,e++;const s=o.m>=t?\"FETCH (CACHE MISS)\":\"FETCH\";n.o(s,o.l.pathname),n.H(o.l).then((async t=>{o.v(t),200===t.status&&(n.o(\"CACHED\",o.l.pathname),await n.R(o.l,t.clone()))})).finally((()=>{n.o(\"FETCH DONE\",o.l.pathname),n.u.splice(n.u.indexOf(o),1),i(n)}))}}function o(t,n){return n.m-t.m}function s(t,n,e,i,o=!0){if(!n.has(e)){if(n.set(e,i),!t.U){let n,e;t.U=new Map;for(let i=0;i<t.L.length;i++){const o=t.L[i];if(\"string\"==typeof o)n={S:[],A:[]},e=!0,t.U.set(o,n);else if(-1===o)e=!1;else{const i=t.L[o];e?n.S.push(i):n.A.push(i)}}}const c=t.U.get(e);if(!c)return n;for(const e of c.S)s(t,n,e,i);if(o){i--;for(const e of c.A)s(t,n,e,i,!1)}}return n}function c(t){const n=new URL(t).pathname,e=n.lastIndexOf(\"/\");return[n.substring(0,e+1),n.substring(e+1)]}const a=(...t)=>{console.log(\"⚙️ Prefetch SW:\",...t)};async function r(t,n,e,i){const o=t.t.findIndex((t=>t.i===n));if(-1!==o&&t.t.splice(o,1),t.o(\"adding base:\",n),t.t.push({i:n,L:e,U:void 0}),i){const i=new Set(e.filter((t=>\"string\"==typeof t))),o=await t.C();if(o)for(const e of await o.keys()){const[s,a]=c(new URL(e.url)),r=[];s!==n||i.has(a)||(t.o(\"deleting\",e.url),r.push(o.delete(e))),await Promise.all(r)}}}function u(t,n,i){let o=t.t.find((t=>t.L.includes(i[0].replace(\"./\",\"\"))));o||(o=t.t.find((t=>n===t.i))),o?e(t,o,i,0):console.error(`Base path not found: ${n}, ignoring prefetch.`)}function f(t){if(!t.N&&t.B.length){const e=t.B.shift();t.N=(async(t,e)=>{const i=e[0];t.o(\"received message:\",i,e[1],e.slice(2)),\"graph\"===i?await r(t,e[1],e.slice(2),!0):\"graph-url\"===i?await async function(t,e,i){await r(t,e,[],!1);const o=await n(t,new URL(e+i,t.l.origin));if(o&&200===o.status){const n=await o.json();n.push(i),await r(t,e,n,!0)}}(t,e[1],e[2]):\"prefetch\"===i?await u(t,e[1],e.slice(2)):\"prefetch-all\"===i?await function(t,n){const e=t.t.find((t=>n===t.i));e?u(t,n,e.L.filter((t=>\"string\"==typeof t))):console.error(`Base path not found: ${n}, ignoring prefetch.`)}(t,e[1]):\"ping\"===i?a(\"ping\"):\"verbose\"===i?(t.o=a)(\"mode: verbose\"):console.error(\"UNKNOWN MESSAGE:\",e)})(t,e).then((()=>{t.N=null,f(t)}))}}class l{constructor(t,n,e=4,i=null,o=null,s=[],c=[],a=[]){this.H=t,this.l=n,this.T=e,this.F=i,this.N=o,this.u=s,this.t=c,this.B=a}C(){return this.F}async R(t,n){const e=await this.C();return null==e?void 0:e.put(t,n)}async h(t){const n=await this.C();return null==n?void 0:n.match(t)}o(){}}(t=>{const e=(i=t.fetch.bind(t),o=new URL(t.location.href),new l(i,o));var i,o;e.C=()=>e.F?e.F:(clearTimeout(void 0),setTimeout((()=>{e.F=null}),5e3),t.caches.open(\"QwikBundles\")),t.addEventListener(\"fetch\",(t=>{const i=t.request;if(\"GET\"===i.method){const o=n(e,new URL(i.url));o&&t.respondWith(o)}})),t.addEventListener(\"message\",(t=>{e.B.push(t.data),f(e)})),t.addEventListener(\"install\",(()=>{t.skipWaiting()})),t.addEventListener(\"activate\",(n=>{e.C=()=>e.F?e.F:(clearTimeout(void 0),setTimeout((()=>{e.F=null}),5e3),t.caches.open(\"QwikBundles\")),n.waitUntil(t.clients.claim())}))})(globalThis)})();";
const QWIK_PREFETCH_DEBUG = "(() => {\n const DIRECT_PRIORITY = Number.MAX_SAFE_INTEGER >>> 1;\n function directFetch(swState, url) {\n const [basePath, filename] = parseBaseFilename(url);\n const base = swState.$bases$.find((base2 => basePath === base2.$path$));\n if (base) {\n swState.$log$(\"intercepting\", url.pathname);\n return enqueueFileAndDependencies(swState, base, [ filename ], DIRECT_PRIORITY).then((() => function(swState, url) {\n const currentRequestTask = swState.$queue$.find((task => task.$url$.pathname === url.pathname));\n if (currentRequestTask) {\n return currentRequestTask.$response$.then((response => response.clone()));\n }\n swState.$log$(\"CACHE HIT\", url.pathname);\n return swState.$match$(url);\n }(swState, url)));\n }\n }\n async function enqueueFileAndDependencies(swState, base, filenames, priority) {\n const fetchMap = new Map;\n filenames.forEach((filename => addDependencies(base, fetchMap, filename, priority)));\n await Promise.all(Array.from(fetchMap.entries()).map((([filename, prio]) => async function(swState, url, priority) {\n let task = swState.$queue$.find((task2 => task2.$url$.pathname === url.pathname));\n const mode = priority >= DIRECT_PRIORITY ? \"direct\" : \"prefetch\";\n if (task) {\n const state = task.$isFetching$ ? \"fetching\" : \"waiting\";\n if (task.$priority$ < priority) {\n swState.$log$(\"queue update priority\", state, url.pathname);\n task.$priority$ = priority;\n } else {\n swState.$log$(\"already in queue\", mode, state, url.pathname);\n }\n } else {\n if (!await swState.$match$(url)) {\n swState.$log$(\"enqueue\", mode, url.pathname);\n task = {\n $priority$: priority,\n $url$: url,\n $resolveResponse$: null,\n $response$: null,\n $isFetching$: !1\n };\n task.$response$ = new Promise((resolve => task.$resolveResponse$ = resolve));\n swState.$queue$.push(task);\n }\n }\n return task;\n }(swState, new URL(base.$path$ + filename, swState.$url$.origin), prio))));\n taskTick(swState);\n }\n function taskTick(swState) {\n swState.$queue$.sort(byFetchOrder);\n let outstandingRequests = 0;\n for (const task of swState.$queue$) {\n if (task.$isFetching$) {\n outstandingRequests++;\n } else if (swState.$getCache$() && (outstandingRequests < swState.$maxPrefetchRequests$ || task.$priority$ >= DIRECT_PRIORITY)) {\n task.$isFetching$ = !0;\n outstandingRequests++;\n const action = task.$priority$ >= DIRECT_PRIORITY ? \"FETCH (CACHE MISS)\" : \"FETCH\";\n swState.$log$(action, task.$url$.pathname);\n swState.$fetch$(task.$url$).then((async response => {\n task.$resolveResponse$(response);\n if (200 === response.status) {\n swState.$log$(\"CACHED\", task.$url$.pathname);\n await swState.$put$(task.$url$, response.clone());\n }\n })).finally((() => {\n swState.$log$(\"FETCH DONE\", task.$url$.pathname);\n swState.$queue$.splice(swState.$queue$.indexOf(task), 1);\n taskTick(swState);\n }));\n }\n }\n }\n function byFetchOrder(a, b) {\n return b.$priority$ - a.$priority$;\n }\n function addDependencies(base, fetchMap, filename, priority, addIndirect = !0) {\n if (!fetchMap.has(filename)) {\n fetchMap.set(filename, priority);\n if (!base.$processed$) {\n base.$processed$ = new Map;\n let current, isDirect;\n for (let i = 0; i < base.$graph$.length; i++) {\n const item = base.$graph$[i];\n if (\"string\" == typeof item) {\n current = {\n $direct$: [],\n $indirect$: []\n };\n isDirect = !0;\n base.$processed$.set(item, current);\n } else if (-1 === item) {\n isDirect = !1;\n } else {\n const depName = base.$graph$[item];\n isDirect ? current.$direct$.push(depName) : current.$indirect$.push(depName);\n }\n }\n }\n const deps = base.$processed$.get(filename);\n if (!deps) {\n return fetchMap;\n }\n for (const dependentFilename of deps.$direct$) {\n addDependencies(base, fetchMap, dependentFilename, priority);\n }\n if (addIndirect) {\n priority--;\n for (const dependentFilename of deps.$indirect$) {\n addDependencies(base, fetchMap, dependentFilename, priority, !1);\n }\n }\n }\n return fetchMap;\n }\n function parseBaseFilename(url) {\n const pathname = new URL(url).pathname;\n const slashIndex = pathname.lastIndexOf(\"/\");\n return [ pathname.substring(0, slashIndex + 1), pathname.substring(slashIndex + 1) ];\n }\n const log = (...args) => {\n console.log(\"⚙️ Prefetch SW:\", ...args);\n };\n const processMessage = async (state, msg) => {\n const type = msg[0];\n state.$log$(\"received message:\", type, msg[1], msg.slice(2));\n \"graph\" === type ? await processBundleGraph(state, msg[1], msg.slice(2), !0) : \"graph-url\" === type ? await async function(swState, base, graphPath) {\n await processBundleGraph(swState, base, [], !1);\n const response = await directFetch(swState, new URL(base + graphPath, swState.$url$.origin));\n if (response && 200 === response.status) {\n const graph = await response.json();\n graph.push(graphPath);\n await processBundleGraph(swState, base, graph, !0);\n }\n }(state, msg[1], msg[2]) : \"prefetch\" === type ? await processPrefetch(state, msg[1], msg.slice(2)) : \"prefetch-all\" === type ? await function(swState, basePath) {\n const base = swState.$bases$.find((base2 => basePath === base2.$path$));\n base ? processPrefetch(swState, basePath, base.$graph$.filter((item => \"string\" == typeof item))) : console.error(`Base path not found: ${basePath}, ignoring prefetch.`);\n }(state, msg[1]) : \"ping\" === type ? log(\"ping\") : \"verbose\" === type ? (state.$log$ = log)(\"mode: verbose\") : console.error(\"UNKNOWN MESSAGE:\", msg);\n };\n async function processBundleGraph(swState, base, graph, cleanup) {\n const existingBaseIndex = swState.$bases$.findIndex((b => b.$path$ === base));\n -1 !== existingBaseIndex && swState.$bases$.splice(existingBaseIndex, 1);\n swState.$log$(\"adding base:\", base);\n swState.$bases$.push({\n $path$: base,\n $graph$: graph,\n $processed$: void 0\n });\n if (cleanup) {\n const bundles = new Set(graph.filter((item => \"string\" == typeof item)));\n const cache = await swState.$getCache$();\n if (cache) {\n for (const request of await cache.keys()) {\n const [cacheBase, filename] = parseBaseFilename(new URL(request.url));\n const promises = [];\n if (cacheBase === base && !bundles.has(filename)) {\n swState.$log$(\"deleting\", request.url);\n promises.push(cache.delete(request));\n }\n await Promise.all(promises);\n }\n }\n }\n }\n function processPrefetch(swState, basePath, bundles) {\n let base = swState.$bases$.find((base2 => base2.$graph$.includes(bundles[0].replace(\"./\", \"\"))));\n base || (base = swState.$bases$.find((base2 => basePath === base2.$path$)));\n base ? enqueueFileAndDependencies(swState, base, bundles, 0) : console.error(`Base path not found: ${basePath}, ignoring prefetch.`);\n }\n function drainMsgQueue(swState) {\n if (!swState.$msgQueuePromise$ && swState.$msgQueue$.length) {\n const top = swState.$msgQueue$.shift();\n swState.$msgQueuePromise$ = processMessage(swState, top).then((() => {\n swState.$msgQueuePromise$ = null;\n drainMsgQueue(swState);\n }));\n }\n }\n class SWStateImpl {\n constructor($fetch$, $url$, $maxPrefetchRequests$ = 4, $cache$ = null, $msgQueuePromise$ = null, $queue$ = [], $bases$ = [], $msgQueue$ = []) {\n this.$fetch$ = $fetch$;\n this.$url$ = $url$;\n this.$maxPrefetchRequests$ = $maxPrefetchRequests$;\n this.$cache$ = $cache$;\n this.$msgQueuePromise$ = $msgQueuePromise$;\n this.$queue$ = $queue$;\n this.$bases$ = $bases$;\n this.$msgQueue$ = $msgQueue$;\n }\n $getCache$() {\n return this.$cache$;\n }\n async $put$(request, response) {\n const cache = await this.$getCache$();\n return null == cache ? void 0 : cache.put(request, response);\n }\n async $match$(request) {\n const cache = await this.$getCache$();\n return null == cache ? void 0 : cache.match(request);\n }\n $log$() {}\n }\n (swScope => {\n const swState = ((fetch, url) => new SWStateImpl(fetch, url))(swScope.fetch.bind(swScope), new URL(swScope.location.href));\n swState.$getCache$ = () => {\n if (swState.$cache$) {\n return swState.$cache$;\n }\n clearTimeout(undefined);\n setTimeout((() => {\n swState.$cache$ = null;\n }), 5e3);\n return swScope.caches.open(\"QwikBundles\");\n };\n swScope.addEventListener(\"fetch\", (ev => {\n const request = ev.request;\n if (\"GET\" === request.method) {\n const response = directFetch(swState, new URL(request.url));\n response && ev.respondWith(response);\n }\n }));\n swScope.addEventListener(\"message\", (ev => {\n swState.$msgQueue$.push(ev.data);\n drainMsgQueue(swState);\n }));\n swScope.addEventListener(\"install\", (() => {\n swScope.skipWaiting();\n }));\n swScope.addEventListener(\"activate\", (event => {\n swState.$getCache$ = () => {\n if (swState.$cache$) {\n return swState.$cache$;\n }\n clearTimeout(undefined);\n setTimeout((() => {\n swState.$cache$ = null;\n }), 5e3);\n return swScope.caches.open(\"QwikBundles\");\n };\n event.waitUntil(swScope.clients.claim());\n }));\n })(globalThis);\n})();";
exports.QWIK_PREFETCH = QWIK_PREFETCH;
exports.QWIK_PREFETCH_DEBUG = QWIK_PREFETCH_DEBUG;