@gitlon/version 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client.cjs +1 -1
- package/dist/client.cjs.map +1 -1
- package/dist/client.js +1 -1
- package/dist/client.js.map +1 -1
- package/package.json +1 -1
package/dist/client.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e=`_`,t=`gitlon-version-cache-iframe`,n=`gitlon-version-loading`,r=5e3,i=5;function a(e){document.getElementById(n)?.remove();let t=document.createElement(`div`),r=document.createElement(`div`),i=document.createElement(`div`),a=Date.now()+e*1e3;t.id=n,t.style.cssText=`position:fixed;inset:0;z-index:2147483647;display:flex;flex-direction:column;align-items:center;justify-content:center;background:rgba(0,0,0,.65);color:#fff;font:14px/1.5 sans-serif;`,r.style.cssText=`width:36px;height:36px;margin-bottom:16px;border:3px solid rgba(255,255,255,.35);border-top-color:#fff;border-radius:50%;animation:gitlon-version-loading .8s linear infinite;`,i.textContent=`请稍等,正在检测更新...(${Math.ceil(e)}秒)`;let o=document.createElement(`style`);o.textContent=`@keyframes gitlon-version-loading{to{transform:rotate(360deg)}}`,t.append(o,r,i),document.documentElement.appendChild(t);let s=window.setInterval(()=>{let e=Math.max(0,Math.ceil((a-Date.now())/1e3));i.textContent=`请稍等,正在检测更新...(${e}秒)`},1e3);return()=>{window.clearInterval(s),t.remove()}}function o(t){let n=new URL(t,window.location.href),r=n.hash;return n.hash=``,n.searchParams.set(e,`${Date.now()}-${Math.random().toString(36).slice(2)}`),n.hash=r,n.href}function s(e){let t=new URL(e);return t.pathname.endsWith(`/`)||(t.pathname+=`/`),t.pathname+=`index.html`,t.href}function c(e){return new Promise(n=>{document.getElementById(t)?.remove();let i=document.createElement(`iframe`),a=!1,o=()=>{a||(a=!0,window.clearTimeout(s),n())},s=window.setTimeout(o,r);i.hidden=!0,i.id=t,i.addEventListener(`load`,o,{once:!0}),i.addEventListener(`error`,o,{once:!0}),i.src=e,document.documentElement.appendChild(i)})}async function l(e){let t=new URL(e,window.location.href).href;console.info(`[@gitlon/version] Clear cache for ${t}`),c(o(t)),await Promise.allSettled([fetch(o(t),{cache:`no-store`}).then(e=>e.arrayBuffer()),fetch(t,{cache:`reload`}).then(e=>e.arrayBuffer())])}async function u(e={}){let t=window.location.origin+window.location.pathname,n=e.urls??[t,s(t)],r=e.time,o=typeof r==`number`&&Number.isFinite(r)&&r>0?r:i,c=new URL(e.redirectUrl??n[0]??t,window.location.href).href,u=a(o),d=0;try{await Promise.race([(async()=>{for(let e of n)try{await l(e)}catch{}})(),new Promise(e=>{d=window.setTimeout(e,o*1e3)})])}finally{window.clearTimeout(d),u();try{
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e=`_`,t=`gitlon-version-cache-iframe`,n=`gitlon-version-loading`,r=5e3,i=5;function a(e){document.getElementById(n)?.remove();let t=document.createElement(`div`),r=document.createElement(`div`),i=document.createElement(`div`),a=Date.now()+e*1e3;t.id=n,t.style.cssText=`position:fixed;inset:0;z-index:2147483647;display:flex;flex-direction:column;align-items:center;justify-content:center;background:rgba(0,0,0,.65);color:#fff;font:14px/1.5 sans-serif;`,r.style.cssText=`width:36px;height:36px;margin-bottom:16px;border:3px solid rgba(255,255,255,.35);border-top-color:#fff;border-radius:50%;animation:gitlon-version-loading .8s linear infinite;`,i.textContent=`请稍等,正在检测更新...(${Math.ceil(e)}秒)`;let o=document.createElement(`style`);o.textContent=`@keyframes gitlon-version-loading{to{transform:rotate(360deg)}}`,t.append(o,r,i),document.documentElement.appendChild(t);let s=window.setInterval(()=>{let e=Math.max(0,Math.ceil((a-Date.now())/1e3));i.textContent=`请稍等,正在检测更新...(${e}秒)`},1e3);return()=>{window.clearInterval(s),t.remove()}}function o(t){let n=new URL(t,window.location.href),r=n.hash;return n.hash=``,n.searchParams.set(e,`${Date.now()}-${Math.random().toString(36).slice(2)}`),n.hash=r,n.href}function s(e){let t=new URL(e);return t.pathname.endsWith(`/`)||(t.pathname+=`/`),t.pathname+=`index.html`,t.href}function c(e){return new Promise(n=>{document.getElementById(t)?.remove();let i=document.createElement(`iframe`),a=!1,o=()=>{a||(a=!0,window.clearTimeout(s),n())},s=window.setTimeout(o,r);i.hidden=!0,i.id=t,i.addEventListener(`load`,o,{once:!0}),i.addEventListener(`error`,o,{once:!0}),i.src=e,document.documentElement.appendChild(i)})}async function l(e){let t=new URL(e,window.location.href).href;console.info(`[@gitlon/version] Clear cache for ${t}`),c(o(t)),await Promise.allSettled([fetch(o(t),{cache:`no-store`}).then(e=>e.arrayBuffer()),fetch(t,{cache:`reload`}).then(e=>e.arrayBuffer())])}async function u(e={}){let t=window.location.origin+window.location.pathname,n=e.urls??[t,s(t)],r=e.time,o=typeof r==`number`&&Number.isFinite(r)&&r>0?r:i,c=new URL(e.redirectUrl??n[0]??t,window.location.href).href,u=a(o),d=0;try{await Promise.race([(async()=>{for(let e of n)try{await l(e)}catch{}})(),new Promise(e=>{d=window.setTimeout(e,o*1e3)})])}finally{window.clearTimeout(d),u();try{e.onBeforeRedirect?.()}catch{}window.location.replace(c)}}exports.clearUrlCache=u;
|
|
2
2
|
//# sourceMappingURL=client.cjs.map
|
package/dist/client.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.cjs","names":[],"sources":["../src/client.ts"],"sourcesContent":["const CACHE_BUST_PARAM = '_'\nconst IFRAME_ID = 'gitlon-version-cache-iframe'\nconst LOADING_ID = 'gitlon-version-loading'\nconst IFRAME_TIMEOUT = 5_000\nconst DEFAULT_REFRESH_TIME = 5\n\nexport interface ClearUrlCacheOptions {\n urls?: string[]\n redirectUrl?: string\n time?: number\n onBeforeRedirect?: () => void | Promise<void>\n}\n\nfunction showLoading(time: number): () => void {\n document.getElementById(LOADING_ID)?.remove()\n\n const loading = document.createElement('div')\n const spinner = document.createElement('div')\n const text = document.createElement('div')\n const deadline = Date.now() + time * 1_000\n\n loading.id = LOADING_ID\n loading.style.cssText =\n 'position:fixed;inset:0;z-index:2147483647;display:flex;flex-direction:column;align-items:center;justify-content:center;background:rgba(0,0,0,.65);color:#fff;font:14px/1.5 sans-serif;'\n spinner.style.cssText =\n 'width:36px;height:36px;margin-bottom:16px;border:3px solid rgba(255,255,255,.35);border-top-color:#fff;border-radius:50%;animation:gitlon-version-loading .8s linear infinite;'\n text.textContent = `请稍等,正在检测更新...(${Math.ceil(time)}秒)`\n\n const style = document.createElement('style')\n style.textContent = '@keyframes gitlon-version-loading{to{transform:rotate(360deg)}}'\n loading.append(style, spinner, text)\n document.documentElement.appendChild(loading)\n\n const countdown = window.setInterval(() => {\n const seconds = Math.max(0, Math.ceil((deadline - Date.now()) / 1_000))\n text.textContent = `请稍等,正在检测更新...(${seconds}秒)`\n }, 1_000)\n\n return () => {\n window.clearInterval(countdown)\n loading.remove()\n }\n}\n\nfunction cacheBustedUrl(url: string): string {\n const target = new URL(url, window.location.href)\n const hash = target.hash\n\n target.hash = ''\n target.searchParams.set(\n CACHE_BUST_PARAM,\n `${Date.now()}-${Math.random().toString(36).slice(2)}`,\n )\n target.hash = hash\n\n return target.href\n}\n\nfunction indexUrl(url: string): string {\n const target = new URL(url)\n if (!target.pathname.endsWith('/')) target.pathname += '/'\n target.pathname += 'index.html'\n return target.href\n}\n\nfunction loadIframe(url: string): Promise<void> {\n return new Promise((resolve) => {\n document.getElementById(IFRAME_ID)?.remove()\n\n const iframe = document.createElement('iframe')\n let completed = false\n\n const complete = () => {\n if (completed) return\n completed = true\n window.clearTimeout(timeout)\n resolve()\n }\n\n const timeout = window.setTimeout(complete, IFRAME_TIMEOUT)\n iframe.hidden = true\n iframe.id = IFRAME_ID\n iframe.addEventListener('load', complete, { once: true })\n iframe.addEventListener('error', complete, { once: true })\n iframe.src = url\n document.documentElement.appendChild(iframe)\n })\n}\n\nasync function refreshUrlCache(url: string): Promise<void> {\n const target = new URL(url, window.location.href).href\n console.info(`[@gitlon/version] Clear cache for ${target}`)\n\n loadIframe(cacheBustedUrl(target))\n await Promise.allSettled([\n fetch(cacheBustedUrl(target), { cache: 'no-store' }).then((response) =>\n response.arrayBuffer(),\n ),\n fetch(target, { cache: 'reload' }).then((response) => response.arrayBuffer()),\n ])\n\n}\n\nexport async function clearUrlCache(options: ClearUrlCacheOptions = {}): Promise<void> {\n const defaultUrl = window.location.origin + window.location.pathname\n const urls = options.urls ?? [defaultUrl, indexUrl(defaultUrl)]\n const configuredTime = options.time\n const time =\n typeof configuredTime === 'number' &&\n Number.isFinite(configuredTime) &&\n configuredTime > 0\n ? configuredTime\n : DEFAULT_REFRESH_TIME\n const redirectUrl = new URL(\n options.redirectUrl ?? urls[0] ?? defaultUrl,\n window.location.href,\n ).href\n const hideLoading = showLoading(time)\n let refreshTimeout = 0\n\n try {\n await Promise.race([\n (async () => {\n for (const url of urls) {\n try {\n await refreshUrlCache(url)\n } catch {\n // 单个 URL 失败不阻断后续 URL。\n }\n }\n })(),\n new Promise<void>((resolve) => {\n refreshTimeout = window.setTimeout(resolve, time * 1_000)\n }),\n ])\n } finally {\n window.clearTimeout(refreshTimeout)\n hideLoading()\n try {\n
|
|
1
|
+
{"version":3,"file":"client.cjs","names":[],"sources":["../src/client.ts"],"sourcesContent":["const CACHE_BUST_PARAM = '_'\nconst IFRAME_ID = 'gitlon-version-cache-iframe'\nconst LOADING_ID = 'gitlon-version-loading'\nconst IFRAME_TIMEOUT = 5_000\nconst DEFAULT_REFRESH_TIME = 5\n\nexport interface ClearUrlCacheOptions {\n urls?: string[]\n redirectUrl?: string\n time?: number\n onBeforeRedirect?: () => void | Promise<void>\n}\n\nfunction showLoading(time: number): () => void {\n document.getElementById(LOADING_ID)?.remove()\n\n const loading = document.createElement('div')\n const spinner = document.createElement('div')\n const text = document.createElement('div')\n const deadline = Date.now() + time * 1_000\n\n loading.id = LOADING_ID\n loading.style.cssText =\n 'position:fixed;inset:0;z-index:2147483647;display:flex;flex-direction:column;align-items:center;justify-content:center;background:rgba(0,0,0,.65);color:#fff;font:14px/1.5 sans-serif;'\n spinner.style.cssText =\n 'width:36px;height:36px;margin-bottom:16px;border:3px solid rgba(255,255,255,.35);border-top-color:#fff;border-radius:50%;animation:gitlon-version-loading .8s linear infinite;'\n text.textContent = `请稍等,正在检测更新...(${Math.ceil(time)}秒)`\n\n const style = document.createElement('style')\n style.textContent = '@keyframes gitlon-version-loading{to{transform:rotate(360deg)}}'\n loading.append(style, spinner, text)\n document.documentElement.appendChild(loading)\n\n const countdown = window.setInterval(() => {\n const seconds = Math.max(0, Math.ceil((deadline - Date.now()) / 1_000))\n text.textContent = `请稍等,正在检测更新...(${seconds}秒)`\n }, 1_000)\n\n return () => {\n window.clearInterval(countdown)\n loading.remove()\n }\n}\n\nfunction cacheBustedUrl(url: string): string {\n const target = new URL(url, window.location.href)\n const hash = target.hash\n\n target.hash = ''\n target.searchParams.set(\n CACHE_BUST_PARAM,\n `${Date.now()}-${Math.random().toString(36).slice(2)}`,\n )\n target.hash = hash\n\n return target.href\n}\n\nfunction indexUrl(url: string): string {\n const target = new URL(url)\n if (!target.pathname.endsWith('/')) target.pathname += '/'\n target.pathname += 'index.html'\n return target.href\n}\n\nfunction loadIframe(url: string): Promise<void> {\n return new Promise((resolve) => {\n document.getElementById(IFRAME_ID)?.remove()\n\n const iframe = document.createElement('iframe')\n let completed = false\n\n const complete = () => {\n if (completed) return\n completed = true\n window.clearTimeout(timeout)\n resolve()\n }\n\n const timeout = window.setTimeout(complete, IFRAME_TIMEOUT)\n iframe.hidden = true\n iframe.id = IFRAME_ID\n iframe.addEventListener('load', complete, { once: true })\n iframe.addEventListener('error', complete, { once: true })\n iframe.src = url\n document.documentElement.appendChild(iframe)\n })\n}\n\nasync function refreshUrlCache(url: string): Promise<void> {\n const target = new URL(url, window.location.href).href\n console.info(`[@gitlon/version] Clear cache for ${target}`)\n\n loadIframe(cacheBustedUrl(target))\n await Promise.allSettled([\n fetch(cacheBustedUrl(target), { cache: 'no-store' }).then((response) =>\n response.arrayBuffer(),\n ),\n fetch(target, { cache: 'reload' }).then((response) => response.arrayBuffer()),\n ])\n\n}\n\nexport async function clearUrlCache(options: ClearUrlCacheOptions = {}): Promise<void> {\n const defaultUrl = window.location.origin + window.location.pathname\n const urls = options.urls ?? [defaultUrl, indexUrl(defaultUrl)]\n const configuredTime = options.time\n const time =\n typeof configuredTime === 'number' &&\n Number.isFinite(configuredTime) &&\n configuredTime > 0\n ? configuredTime\n : DEFAULT_REFRESH_TIME\n const redirectUrl = new URL(\n options.redirectUrl ?? urls[0] ?? defaultUrl,\n window.location.href,\n ).href\n const hideLoading = showLoading(time)\n let refreshTimeout = 0\n\n try {\n await Promise.race([\n (async () => {\n for (const url of urls) {\n try {\n await refreshUrlCache(url)\n } catch {\n // 单个 URL 失败不阻断后续 URL。\n }\n }\n })(),\n new Promise<void>((resolve) => {\n refreshTimeout = window.setTimeout(resolve, time * 1_000)\n }),\n ])\n } finally {\n window.clearTimeout(refreshTimeout)\n hideLoading()\n try {\n options.onBeforeRedirect?.()\n } catch {\n // 回调失败不阻断跳转。\n }\n window.location.replace(redirectUrl)\n }\n}\n"],"mappings":"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"}
|
package/dist/client.js
CHANGED
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","names":[],"sources":["../src/client.ts"],"sourcesContent":["const CACHE_BUST_PARAM = '_'\nconst IFRAME_ID = 'gitlon-version-cache-iframe'\nconst LOADING_ID = 'gitlon-version-loading'\nconst IFRAME_TIMEOUT = 5_000\nconst DEFAULT_REFRESH_TIME = 5\n\nexport interface ClearUrlCacheOptions {\n urls?: string[]\n redirectUrl?: string\n time?: number\n onBeforeRedirect?: () => void | Promise<void>\n}\n\nfunction showLoading(time: number): () => void {\n document.getElementById(LOADING_ID)?.remove()\n\n const loading = document.createElement('div')\n const spinner = document.createElement('div')\n const text = document.createElement('div')\n const deadline = Date.now() + time * 1_000\n\n loading.id = LOADING_ID\n loading.style.cssText =\n 'position:fixed;inset:0;z-index:2147483647;display:flex;flex-direction:column;align-items:center;justify-content:center;background:rgba(0,0,0,.65);color:#fff;font:14px/1.5 sans-serif;'\n spinner.style.cssText =\n 'width:36px;height:36px;margin-bottom:16px;border:3px solid rgba(255,255,255,.35);border-top-color:#fff;border-radius:50%;animation:gitlon-version-loading .8s linear infinite;'\n text.textContent = `请稍等,正在检测更新...(${Math.ceil(time)}秒)`\n\n const style = document.createElement('style')\n style.textContent = '@keyframes gitlon-version-loading{to{transform:rotate(360deg)}}'\n loading.append(style, spinner, text)\n document.documentElement.appendChild(loading)\n\n const countdown = window.setInterval(() => {\n const seconds = Math.max(0, Math.ceil((deadline - Date.now()) / 1_000))\n text.textContent = `请稍等,正在检测更新...(${seconds}秒)`\n }, 1_000)\n\n return () => {\n window.clearInterval(countdown)\n loading.remove()\n }\n}\n\nfunction cacheBustedUrl(url: string): string {\n const target = new URL(url, window.location.href)\n const hash = target.hash\n\n target.hash = ''\n target.searchParams.set(\n CACHE_BUST_PARAM,\n `${Date.now()}-${Math.random().toString(36).slice(2)}`,\n )\n target.hash = hash\n\n return target.href\n}\n\nfunction indexUrl(url: string): string {\n const target = new URL(url)\n if (!target.pathname.endsWith('/')) target.pathname += '/'\n target.pathname += 'index.html'\n return target.href\n}\n\nfunction loadIframe(url: string): Promise<void> {\n return new Promise((resolve) => {\n document.getElementById(IFRAME_ID)?.remove()\n\n const iframe = document.createElement('iframe')\n let completed = false\n\n const complete = () => {\n if (completed) return\n completed = true\n window.clearTimeout(timeout)\n resolve()\n }\n\n const timeout = window.setTimeout(complete, IFRAME_TIMEOUT)\n iframe.hidden = true\n iframe.id = IFRAME_ID\n iframe.addEventListener('load', complete, { once: true })\n iframe.addEventListener('error', complete, { once: true })\n iframe.src = url\n document.documentElement.appendChild(iframe)\n })\n}\n\nasync function refreshUrlCache(url: string): Promise<void> {\n const target = new URL(url, window.location.href).href\n console.info(`[@gitlon/version] Clear cache for ${target}`)\n\n loadIframe(cacheBustedUrl(target))\n await Promise.allSettled([\n fetch(cacheBustedUrl(target), { cache: 'no-store' }).then((response) =>\n response.arrayBuffer(),\n ),\n fetch(target, { cache: 'reload' }).then((response) => response.arrayBuffer()),\n ])\n\n}\n\nexport async function clearUrlCache(options: ClearUrlCacheOptions = {}): Promise<void> {\n const defaultUrl = window.location.origin + window.location.pathname\n const urls = options.urls ?? [defaultUrl, indexUrl(defaultUrl)]\n const configuredTime = options.time\n const time =\n typeof configuredTime === 'number' &&\n Number.isFinite(configuredTime) &&\n configuredTime > 0\n ? configuredTime\n : DEFAULT_REFRESH_TIME\n const redirectUrl = new URL(\n options.redirectUrl ?? urls[0] ?? defaultUrl,\n window.location.href,\n ).href\n const hideLoading = showLoading(time)\n let refreshTimeout = 0\n\n try {\n await Promise.race([\n (async () => {\n for (const url of urls) {\n try {\n await refreshUrlCache(url)\n } catch {\n // 单个 URL 失败不阻断后续 URL。\n }\n }\n })(),\n new Promise<void>((resolve) => {\n refreshTimeout = window.setTimeout(resolve, time * 1_000)\n }),\n ])\n } finally {\n window.clearTimeout(refreshTimeout)\n hideLoading()\n try {\n
|
|
1
|
+
{"version":3,"file":"client.js","names":[],"sources":["../src/client.ts"],"sourcesContent":["const CACHE_BUST_PARAM = '_'\nconst IFRAME_ID = 'gitlon-version-cache-iframe'\nconst LOADING_ID = 'gitlon-version-loading'\nconst IFRAME_TIMEOUT = 5_000\nconst DEFAULT_REFRESH_TIME = 5\n\nexport interface ClearUrlCacheOptions {\n urls?: string[]\n redirectUrl?: string\n time?: number\n onBeforeRedirect?: () => void | Promise<void>\n}\n\nfunction showLoading(time: number): () => void {\n document.getElementById(LOADING_ID)?.remove()\n\n const loading = document.createElement('div')\n const spinner = document.createElement('div')\n const text = document.createElement('div')\n const deadline = Date.now() + time * 1_000\n\n loading.id = LOADING_ID\n loading.style.cssText =\n 'position:fixed;inset:0;z-index:2147483647;display:flex;flex-direction:column;align-items:center;justify-content:center;background:rgba(0,0,0,.65);color:#fff;font:14px/1.5 sans-serif;'\n spinner.style.cssText =\n 'width:36px;height:36px;margin-bottom:16px;border:3px solid rgba(255,255,255,.35);border-top-color:#fff;border-radius:50%;animation:gitlon-version-loading .8s linear infinite;'\n text.textContent = `请稍等,正在检测更新...(${Math.ceil(time)}秒)`\n\n const style = document.createElement('style')\n style.textContent = '@keyframes gitlon-version-loading{to{transform:rotate(360deg)}}'\n loading.append(style, spinner, text)\n document.documentElement.appendChild(loading)\n\n const countdown = window.setInterval(() => {\n const seconds = Math.max(0, Math.ceil((deadline - Date.now()) / 1_000))\n text.textContent = `请稍等,正在检测更新...(${seconds}秒)`\n }, 1_000)\n\n return () => {\n window.clearInterval(countdown)\n loading.remove()\n }\n}\n\nfunction cacheBustedUrl(url: string): string {\n const target = new URL(url, window.location.href)\n const hash = target.hash\n\n target.hash = ''\n target.searchParams.set(\n CACHE_BUST_PARAM,\n `${Date.now()}-${Math.random().toString(36).slice(2)}`,\n )\n target.hash = hash\n\n return target.href\n}\n\nfunction indexUrl(url: string): string {\n const target = new URL(url)\n if (!target.pathname.endsWith('/')) target.pathname += '/'\n target.pathname += 'index.html'\n return target.href\n}\n\nfunction loadIframe(url: string): Promise<void> {\n return new Promise((resolve) => {\n document.getElementById(IFRAME_ID)?.remove()\n\n const iframe = document.createElement('iframe')\n let completed = false\n\n const complete = () => {\n if (completed) return\n completed = true\n window.clearTimeout(timeout)\n resolve()\n }\n\n const timeout = window.setTimeout(complete, IFRAME_TIMEOUT)\n iframe.hidden = true\n iframe.id = IFRAME_ID\n iframe.addEventListener('load', complete, { once: true })\n iframe.addEventListener('error', complete, { once: true })\n iframe.src = url\n document.documentElement.appendChild(iframe)\n })\n}\n\nasync function refreshUrlCache(url: string): Promise<void> {\n const target = new URL(url, window.location.href).href\n console.info(`[@gitlon/version] Clear cache for ${target}`)\n\n loadIframe(cacheBustedUrl(target))\n await Promise.allSettled([\n fetch(cacheBustedUrl(target), { cache: 'no-store' }).then((response) =>\n response.arrayBuffer(),\n ),\n fetch(target, { cache: 'reload' }).then((response) => response.arrayBuffer()),\n ])\n\n}\n\nexport async function clearUrlCache(options: ClearUrlCacheOptions = {}): Promise<void> {\n const defaultUrl = window.location.origin + window.location.pathname\n const urls = options.urls ?? [defaultUrl, indexUrl(defaultUrl)]\n const configuredTime = options.time\n const time =\n typeof configuredTime === 'number' &&\n Number.isFinite(configuredTime) &&\n configuredTime > 0\n ? configuredTime\n : DEFAULT_REFRESH_TIME\n const redirectUrl = new URL(\n options.redirectUrl ?? urls[0] ?? defaultUrl,\n window.location.href,\n ).href\n const hideLoading = showLoading(time)\n let refreshTimeout = 0\n\n try {\n await Promise.race([\n (async () => {\n for (const url of urls) {\n try {\n await refreshUrlCache(url)\n } catch {\n // 单个 URL 失败不阻断后续 URL。\n }\n }\n })(),\n new Promise<void>((resolve) => {\n refreshTimeout = window.setTimeout(resolve, time * 1_000)\n }),\n ])\n } finally {\n window.clearTimeout(refreshTimeout)\n hideLoading()\n try {\n options.onBeforeRedirect?.()\n } catch {\n // 回调失败不阻断跳转。\n }\n window.location.replace(redirectUrl)\n }\n}\n"],"mappings":"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"}
|