@vuepress/plugin-pwa 2.0.0-rc.124 → 2.0.0-rc.125

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.
Files changed (48) hide show
  1. package/{lib/client/components/PwaFoundPopup.d.ts → dist/PwaFoundPopup-DWmIsyXx.d.ts} +3 -6
  2. package/dist/PwaInstall-Ee3il2nW.js +2 -0
  3. package/dist/PwaInstall-Ee3il2nW.js.map +1 -0
  4. package/{lib/client/components/PwaInstall.d.ts → dist/PwaInstall-w3x5rHx6.d.ts} +3 -5
  5. package/dist/PwaReadyPopup-6AypjW2B.js +2 -0
  6. package/dist/PwaReadyPopup-6AypjW2B.js.map +1 -0
  7. package/{lib/client/components/PwaReadyPopup.d.ts → dist/PwaReadyPopup-CDLxW7kc.d.ts} +3 -6
  8. package/dist/client/components/PwaFoundPopup.d.ts +2 -0
  9. package/dist/client/components/PwaFoundPopup.js +2 -0
  10. package/{lib → dist}/client/components/PwaFoundPopup.js.map +1 -1
  11. package/dist/client/components/PwaInstall.d.ts +2 -0
  12. package/dist/client/components/PwaInstall.js +1 -0
  13. package/dist/client/components/PwaReadyPopup.d.ts +2 -0
  14. package/dist/client/components/PwaReadyPopup.js +1 -0
  15. package/dist/client/composables/index.js +1 -0
  16. package/{lib → dist}/client/index.d.ts +4 -4
  17. package/dist/client/index.js +2 -0
  18. package/{lib → dist}/client/index.js.map +1 -1
  19. package/dist/composables-Bdxx2hts.js +2 -0
  20. package/dist/composables-Bdxx2hts.js.map +1 -0
  21. package/{lib/locales-BlsUewPq.d.ts → dist/locales-Bj0jQ5BO.d.ts} +1 -1
  22. package/{lib → dist}/node/index.d.ts +1 -1
  23. package/{lib/types-CGDCqUfb.d.ts → dist/types-D2911FOa.d.ts} +2 -2
  24. package/package.json +10 -10
  25. package/lib/PwaInstallModal-DH0cwyM5.js +0 -2
  26. package/lib/PwaInstallModal-DH0cwyM5.js.map +0 -1
  27. package/lib/client/components/PwaFoundPopup.js +0 -2
  28. package/lib/client/components/PwaInstall.js +0 -2
  29. package/lib/client/components/PwaInstall.js.map +0 -1
  30. package/lib/client/components/PwaReadyPopup.js +0 -2
  31. package/lib/client/components/PwaReadyPopup.js.map +0 -1
  32. package/lib/client/composables/index.js +0 -1
  33. package/lib/client/index.js +0 -2
  34. package/lib/setupViewPoint-DS4c13mS.js +0 -2
  35. package/lib/setupViewPoint-DS4c13mS.js.map +0 -1
  36. package/lib/skipWaiting-wM8NHpWa.js +0 -2
  37. package/lib/skipWaiting-wM8NHpWa.js.map +0 -1
  38. /package/{lib → dist}/client/composables/index.d.ts +0 -0
  39. /package/{lib → dist}/client/styles/modal.css +0 -0
  40. /package/{lib → dist}/client/styles/modal.css.map +0 -0
  41. /package/{lib → dist}/client/styles/popup.css +0 -0
  42. /package/{lib → dist}/client/styles/popup.css.map +0 -0
  43. /package/{lib → dist}/client/styles/vars.css +0 -0
  44. /package/{lib → dist}/client/styles/vars.css.map +0 -0
  45. /package/{lib → dist}/icons-RRw4DIWa.js +0 -0
  46. /package/{lib → dist}/icons-RRw4DIWa.js.map +0 -0
  47. /package/{lib → dist}/node/index.js +0 -0
  48. /package/{lib → dist}/node/index.js.map +0 -0
@@ -1,10 +1,7 @@
1
- import { t as PwaPluginLocaleConfig } from "../../types-CGDCqUfb.js";
1
+ import { t as PwaPluginLocaleConfig } from "./types-D2911FOa.js";
2
2
  import { Slot } from "@vuepress/helper/client";
3
3
  import * as vue from "vue";
4
4
  import { PropType, SlotsType, VNode } from "vue";
5
- import "@vuepress/helper/transition/fade-in-scale-up.css";
6
- import "../styles/popup.css";
7
-
8
5
  //#region src/client/components/PwaFoundPopup.d.ts
9
6
  declare const PwaFoundPopup: vue.DefineComponent<vue.ExtractPropTypes<{
10
7
  /** locale data */locales: {
@@ -23,5 +20,5 @@ declare const PwaFoundPopup: vue.DefineComponent<vue.ExtractPropTypes<{
23
20
  }>;
24
21
  }>, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
25
22
  //#endregion
26
- export { PwaFoundPopup };
27
- //# sourceMappingURL=PwaFoundPopup.d.ts.map
23
+ export { PwaFoundPopup as t };
24
+ //# sourceMappingURL=PwaFoundPopup-DWmIsyXx.d.ts.map
@@ -0,0 +1,2 @@
1
+ import{n as e,r as t,t as n}from"./icons-RRw4DIWa.js";import{useLocale as r}from"@vuepress/helper/client";import{useEventListener as i,useToggle as a}from"@vueuse/core";import{computed as o,defineComponent as s,h as c,onMounted as l,ref as u,shallowRef as d}from"vue";import{withBase as f}from"vuepress/client";import"./client/styles/modal.css";const p=()=>{let e=document.querySelector(`.screenshot`);e&&e.scrollBy({left:-e.clientWidth,top:0,behavior:`smooth`})},m=()=>{let e=document.querySelector(`.screenshot`);e&&e.scrollBy({left:e.clientWidth,top:0,behavior:`smooth`})},h=s({name:`PwaInstallModal`,props:{locales:{type:Object,required:!0},useHint:Boolean},emits:[`canInstall`,`hint`,`close`],setup(a,{emit:o}){let s=r(a.locales),u=d({}),h=d(),g=async()=>{let e=localStorage.getItem(`manifest`);if(e)u.value=JSON.parse(e);else try{let e=await(await fetch(f(`manifest.webmanifest`))).json();u.value=e,localStorage.setItem(`manifest`,JSON.stringify(e))}catch{console.error(`[PWA]: Error getting manifest, check that you have a valid web manifest or network connection`)}},_=async()=>{h.value&&(h.value.prompt(),document.dispatchEvent(new CustomEvent(`show`)),(await h.value.userChoice).outcome===`accepted`?(console.info(`PWA has been installed`),o(`close`,!1),o(`canInstall`,!1)):(console.info(`You choose to not install PWA`),o(`close`,!1),o(`canInstall`,!1)))},v=()=>{console.info(`You accepted the install hint`),o(`hint`)};return l(()=>{window.hasOwnProperty(`BeforeInstallPromptEvent`)&&(i(window,`beforeinstallprompt`,e=>{h.value=e,o(`canInstall`,!0),e.preventDefault()}),i(`keyup`,e=>{e.key===`Escape`&&o(`close`,!1)},{passive:!0}),g())}),()=>c(`div`,{id:`install-modal-wrapper`},[c(`div`,{class:`background`,onClick:()=>{o(`close`,!1)}}),c(`div`,{class:`install-modal`},[c(`div`,{class:`header`},[c(`button`,{type:`button`,class:`close-button`,"aria-label":s.value.close,onClick:()=>{o(`close`,!1)}},c(t)),c(`div`,{class:`logo`},[u.value.icons?c(`img`,{src:u.value.icons[0]?.src,alt:`App Logo`}):null,c(`div`,{class:`title`},[c(`h1`,u.value.short_name||u.value.name),c(`p`,{class:`desc`},s.value.explain)])])]),c(`div`,{class:`content`},[c(`div`,{class:`highlight`},[u.value.features?c(`div`,{class:`feature-wrapper`},[c(`h3`,s.value.feature),c(`ul`,u.value.features.map(e=>c(`li`,e)))]):null,u.value.screenshots?c(`div`,{class:`screenshot-wrapper`},[c(`button`,{type:`button`,"aria-label":s.value.prevImage,onClick:p},c(n)),c(`section`,{class:`screenshot`},[u.value.screenshots.map(e=>c(`div`,c(`img`,{src:e.src,alt:`App Screenshot`})))]),c(`button`,{type:`button`,"aria-label":s.value.nextImage,onClick:m},c(e))]):null]),c(`div`,{class:`description`},[c(`h3`,s.value.desc),c(`p`,u.value.description)])]),a.useHint?c(`div`,{class:`ios-text`,onClick:v},[c(`p`,s.value.iOSInstall),c(`button`,{type:`button`,class:`success`},`Got it!`)]):c(`div`,{class:`button-wrapper`},[c(`button`,{type:`button`,class:`install-button`,onClick:_},[s.value.install,c(`span`,u.value.short_name)]),c(`button`,{type:`button`,class:`cancel-button`,onClick:()=>{o(`close`,!1)}},s.value.cancel)])])])}}),g=s({name:`PwaInstall`,props:{locales:{type:Object,required:!0}},setup(e){let t=r(e.locales),[n,i]=a(),s=u(!1),d=u(!1),f=u(!1),p=u(!1),m=u(!1),g=o(()=>f.value&&p.value&&!m.value),_=o(()=>d.value&&s.value||g.value),v=()=>navigator.standalone?navigator.standalone:matchMedia(`(display-mode: standalone)`).matches,y=()=>{i(!1),m.value=!0,localStorage.setItem(`iOS-pwa-hint`,`hinted`)};return l(()=>{if(v()){let{userAgent:e}=navigator;f.value=e.includes(`iPhone`)||e.includes(`iPad`)||!!(e.includes(`Macintosh`)&&navigator.maxTouchPoints&&navigator.maxTouchPoints>2),p.value=navigator.userAgent.includes(`Safari`)&&!e.includes(`Chrome`),m.value=!!localStorage.getItem(`iOS-pwa-hint`)}`getInstalledRelatedApps`in navigator&&navigator.getInstalledRelatedApps().then(e=>{d.value=e.length>0})}),()=>c(`div`,{id:`pwa-install`},[_.value?c(`button`,{type:`button`,class:`modal-button`,onClick:()=>{i(!0)}},t.value.install):null,c(h,{style:{display:n.value?`block`:`none`},locales:e.locales,useHint:g.value,onCanInstall:e=>{s.value=e},onHint:()=>{y()},onClose:()=>i(!1)})])}});export{g as t};
2
+ //# sourceMappingURL=PwaInstall-Ee3il2nW.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PwaInstall-Ee3il2nW.js","names":[],"sources":["../src/client/components/PwaInstallModal.ts","../src/client/components/PwaInstall.ts"],"sourcesContent":["/* eslint-disable no-console */\nimport { useLocale } from '@vuepress/helper/client'\nimport { useEventListener } from '@vueuse/core'\nimport type { PropType, VNode } from 'vue'\nimport { defineComponent, h, onMounted, shallowRef } from 'vue'\nimport { withBase } from 'vuepress/client'\nimport type { AppManifest } from '../../shared/index.js'\nimport type { PwaPluginLocaleConfig } from '../types.js'\nimport { ArrowLeftIcon, ArrowRightIcon, CloseIcon } from './icons.js'\n\ninterface InstallPromptEvent extends Event {\n readonly platforms: string\n prompt: () => void\n readonly userChoice: Promise<{ outcome: 'accepted' | 'dismissed' }>\n}\n\nconst scrollToLeft = (): void => {\n const screenshotsDiv = document.querySelector('.screenshot')\n\n if (screenshotsDiv) {\n screenshotsDiv.scrollBy({\n left: -screenshotsDiv.clientWidth,\n top: 0,\n behavior: 'smooth',\n })\n }\n}\n\nconst scrollToRight = (): void => {\n const screenshotsDiv = document.querySelector('.screenshot')\n\n if (screenshotsDiv) {\n screenshotsDiv.scrollBy({\n left: screenshotsDiv.clientWidth,\n top: 0,\n behavior: 'smooth',\n })\n }\n}\n\nexport const PwaInstallModal = defineComponent({\n name: 'PwaInstallModal',\n\n props: {\n /** locale data */\n locales: {\n type: Object as PropType<PwaPluginLocaleConfig>,\n required: true,\n },\n\n /**\n * Whether use hint message instead of showing a button\n *\n * 是否使用提示\n */\n useHint: Boolean,\n },\n\n emits: ['canInstall', 'hint', 'close'],\n\n setup(props, { emit }) {\n const locale = useLocale(props.locales)\n\n const manifest = shallowRef<AppManifest>({})\n const deferredPrompt = shallowRef<InstallPromptEvent>()\n\n const getManifest = async (): Promise<void> => {\n const manifestContent = localStorage.getItem('manifest')\n\n if (manifestContent) {\n manifest.value = JSON.parse(manifestContent) as AppManifest\n } else {\n try {\n const response = await fetch(withBase('manifest.webmanifest'))\n const data = (await response.json()) as AppManifest\n\n manifest.value = data\n localStorage.setItem('manifest', JSON.stringify(data))\n } catch {\n console.error(\n '[PWA]: Error getting manifest, check that you have a valid web manifest or network connection',\n )\n }\n }\n }\n\n const install = async (): Promise<void> => {\n if (deferredPrompt.value) {\n deferredPrompt.value.prompt()\n\n document.dispatchEvent(new CustomEvent('show'))\n\n const choiceResult = await deferredPrompt.value.userChoice\n\n if (choiceResult.outcome === 'accepted') {\n console.info('PWA has been installed')\n\n emit('close', false)\n emit('canInstall', false)\n } else {\n console.info('You choose to not install PWA')\n\n emit('close', false)\n emit('canInstall', false)\n }\n }\n }\n\n const hint = (): void => {\n console.info('You accepted the install hint')\n emit('hint')\n }\n\n onMounted(() => {\n // eslint-disable-next-line no-prototype-builtins\n if (window.hasOwnProperty('BeforeInstallPromptEvent')) {\n useEventListener(window, 'beforeinstallprompt', (event) => {\n deferredPrompt.value = event as InstallPromptEvent\n\n emit('canInstall', true)\n event.preventDefault()\n })\n\n useEventListener(\n 'keyup',\n (event): void => {\n if (event.key === 'Escape') emit('close', false)\n },\n { passive: true },\n )\n\n void getManifest()\n }\n })\n\n return (): VNode =>\n h('div', { id: 'install-modal-wrapper' }, [\n h('div', {\n class: 'background',\n onClick: () => {\n emit('close', false)\n },\n }),\n\n h('div', { class: 'install-modal' }, [\n h('div', { class: 'header' }, [\n // close button\n h(\n 'button',\n {\n 'type': 'button',\n 'class': 'close-button',\n 'aria-label': locale.value.close,\n 'onClick': () => {\n emit('close', false)\n },\n },\n h(CloseIcon),\n ),\n\n h('div', { class: 'logo' }, [\n manifest.value.icons\n ? h('img', {\n src: manifest.value.icons[0]?.src,\n alt: 'App Logo',\n })\n : null,\n h('div', { class: 'title' }, [\n h('h1', manifest.value.short_name || manifest.value.name),\n h('p', { class: 'desc' }, locale.value.explain),\n ]),\n ]),\n ]),\n\n h('div', { class: 'content' }, [\n h('div', { class: 'highlight' }, [\n manifest.value.features\n ? h('div', { class: 'feature-wrapper' }, [\n h('h3', locale.value.feature),\n h(\n 'ul',\n manifest.value.features.map((feature) =>\n h('li', feature),\n ),\n ),\n ])\n : null,\n\n manifest.value.screenshots\n ? h('div', { class: 'screenshot-wrapper' }, [\n h(\n 'button',\n {\n 'type': 'button',\n 'aria-label': locale.value.prevImage,\n 'onClick': scrollToLeft,\n },\n h(ArrowLeftIcon),\n ),\n h('section', { class: 'screenshot' }, [\n manifest.value.screenshots.map((screenshot) =>\n h(\n 'div',\n h('img', {\n src: screenshot.src,\n alt: 'App Screenshot',\n }),\n ),\n ),\n ]),\n h(\n 'button',\n {\n 'type': 'button',\n 'aria-label': locale.value.nextImage,\n 'onClick': scrollToRight,\n },\n h(ArrowRightIcon),\n ),\n ])\n : null,\n ]),\n\n h('div', { class: 'description' }, [\n h('h3', locale.value.desc),\n h('p', manifest.value.description),\n ]),\n ]),\n\n props.useHint\n ? h('div', { class: 'ios-text', onClick: hint }, [\n h('p', locale.value.iOSInstall),\n h('button', { type: 'button', class: 'success' }, 'Got it!'),\n ])\n : h('div', { class: 'button-wrapper' }, [\n h(\n 'button',\n { type: 'button', class: 'install-button', onClick: install },\n [locale.value.install, h('span', manifest.value.short_name)],\n ),\n h(\n 'button',\n {\n type: 'button',\n class: 'cancel-button',\n onClick: () => {\n emit('close', false)\n },\n },\n locale.value.cancel,\n ),\n ]),\n ]),\n ])\n },\n})\n","import { useLocale } from '@vuepress/helper/client'\nimport { useToggle } from '@vueuse/core'\nimport type { PropType, VNode } from 'vue'\nimport { computed, defineComponent, h, onMounted, ref } from 'vue'\nimport type { ManifestExternalApplicationResource } from '../../shared/index.js'\nimport type { PwaPluginLocaleConfig } from '../types.js'\nimport { PwaInstallModal } from './PwaInstallModal.js'\n\nimport '../styles/modal.css'\n\ninterface ModernNavigator extends Navigator {\n // Nonstandard Api\n getInstalledRelatedApps: () => Promise<ManifestExternalApplicationResource[]>\n}\n\ninterface SafariNavigator extends Navigator {\n // Available on Apple’s iOS Safari only.\n standalone: boolean\n}\n\nexport const PwaInstall = defineComponent({\n name: 'PwaInstall',\n\n props: {\n /** locale data */\n locales: {\n type: Object as PropType<PwaPluginLocaleConfig>,\n required: true,\n },\n },\n\n setup(props) {\n const locale = useLocale(props.locales)\n const [isOpen, toggleIsOpen] = useToggle()\n\n const canInstall = ref(false)\n const hasRelatedApps = ref(false)\n const isIOS = ref(false)\n const isSafari = ref(false)\n const hinted = ref(false)\n\n const useHint = computed(\n () => isIOS.value && isSafari.value && !hinted.value,\n )\n\n const showInstall = computed(\n () => (hasRelatedApps.value && canInstall.value) || useHint.value,\n )\n\n const getInstallStatus = (): boolean => {\n if ((navigator as SafariNavigator).standalone)\n return (navigator as SafariNavigator).standalone\n\n return matchMedia('(display-mode: standalone)').matches\n }\n\n const hint = (): void => {\n toggleIsOpen(false)\n hinted.value = true\n // do not notify again\n localStorage.setItem('iOS-pwa-hint', 'hinted')\n }\n\n onMounted(() => {\n if (getInstallStatus()) {\n const { userAgent } = navigator\n\n // handle iOS specifically\n isIOS.value =\n // regular iPhone\n userAgent.includes('iPhone') ||\n // regular iPad\n userAgent.includes('iPad') ||\n // iPad pro\n Boolean(\n userAgent.includes('Macintosh') &&\n navigator.maxTouchPoints &&\n navigator.maxTouchPoints > 2,\n )\n\n isSafari.value =\n navigator.userAgent.includes('Safari') &&\n !userAgent.includes('Chrome')\n\n hinted.value = Boolean(localStorage.getItem('iOS-pwa-hint'))\n }\n\n if ('getInstalledRelatedApps' in (navigator as ModernNavigator)) {\n void (navigator as ModernNavigator)\n .getInstalledRelatedApps()\n .then((result) => {\n hasRelatedApps.value = result.length > 0\n })\n }\n })\n\n return (): VNode =>\n h('div', { id: 'pwa-install' }, [\n showInstall.value\n ? h(\n 'button',\n {\n type: 'button',\n class: 'modal-button',\n onClick: () => {\n toggleIsOpen(true)\n },\n },\n locale.value.install,\n )\n : null,\n h(PwaInstallModal, {\n style: {\n display: isOpen.value ? 'block' : 'none',\n },\n locales: props.locales,\n useHint: useHint.value,\n onCanInstall: (value: boolean) => {\n canInstall.value = value\n },\n onHint: () => {\n hint()\n },\n onClose: () => toggleIsOpen(false),\n }),\n ])\n },\n})\n"],"mappings":"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"}
@@ -1,8 +1,6 @@
1
- import { t as PwaPluginLocaleConfig } from "../../types-CGDCqUfb.js";
1
+ import { t as PwaPluginLocaleConfig } from "./types-D2911FOa.js";
2
2
  import * as vue from "vue";
3
3
  import { PropType, VNode } from "vue";
4
- import "../styles/modal.css";
5
-
6
4
  //#region src/client/components/PwaInstall.d.ts
7
5
  declare const PwaInstall: vue.DefineComponent<vue.ExtractPropTypes<{
8
6
  /** locale data */locales: {
@@ -16,5 +14,5 @@ declare const PwaInstall: vue.DefineComponent<vue.ExtractPropTypes<{
16
14
  };
17
15
  }>> & Readonly<{}>, {}, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
18
16
  //#endregion
19
- export { PwaInstall };
20
- //# sourceMappingURL=PwaInstall.d.ts.map
17
+ export { PwaInstall as t };
18
+ //# sourceMappingURL=PwaInstall-w3x5rHx6.d.ts.map
@@ -0,0 +1,2 @@
1
+ import{i as e}from"./icons-RRw4DIWa.js";import{a as t}from"./composables-Bdxx2hts.js";import{useLocale as n}from"@vuepress/helper/client";import{Transition as r,computed as i,defineComponent as a,h as o,onMounted as s,shallowRef as c}from"vue";import"@vuepress/helper/transition/fade-in-scale-up.css";import"./client/styles/popup.css";const l=e=>{let t=e.waiting;if(!t)return;let n=new MessageChannel;t.postMessage({type:`SKIP_WAITING`},[n.port2])},u=a({name:`PwaReadyPopup`,props:{locales:{type:Object,required:!0}},slots:Object,setup(a,{slots:u}){let d=n(a.locales),f=c(),p=i(()=>!!f.value),m=()=>{f.value&&=(l(f.value),void 0)};return s(()=>{t().on(`updated`,e=>{f.value=e})}),()=>o(r,{name:`fade-in-scale-up`},()=>u.default?.({isReady:p.value,reload:m})??(p.value?o(`button`,{type:`button`,class:`sw-update-popup`,tabindex:0,onClick:()=>{m()}},[d.value.update,o(`span`,{class:`icon-wrapper`},o(e))]):null))}});export{l as n,u as t};
2
+ //# sourceMappingURL=PwaReadyPopup-6AypjW2B.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PwaReadyPopup-6AypjW2B.js","names":[],"sources":["../src/client/utils/skipWaiting.ts","../src/client/components/PwaReadyPopup.ts"],"sourcesContent":["/**\n * Call `skipWaiting()` inside current waiting worker\n *\n * 在当前等待中的 Service Worker 中调用 `skipWaiting()`\n *\n * @param registration - The registration of the service worker you want activate / 想要激活的 Service Worker 的注册\n */\nexport const skipWaiting = (registration: ServiceWorkerRegistration): void => {\n // Get the waiting worker\n const worker = registration.waiting\n\n // If there is no waiting worker, return directly\n if (!worker) return\n\n // Post SKIP_WAITING message to the waiting worker\n const channel = new MessageChannel()\n\n worker.postMessage({ type: 'SKIP_WAITING' }, [channel.port2])\n}\n","import type { Slot } from '@vuepress/helper/client'\nimport { useLocale } from '@vuepress/helper/client'\nimport type { PropType, SlotsType, VNode } from 'vue'\nimport {\n Transition,\n computed,\n defineComponent,\n h,\n onMounted,\n shallowRef,\n} from 'vue'\nimport { usePwaEvent } from '../composables/index.js'\nimport type { PwaPluginLocaleConfig } from '../types.js'\nimport { skipWaiting } from '../utils/index.js'\nimport { UpdateIcon } from './icons.js'\n\nimport '@vuepress/helper/transition/fade-in-scale-up.css'\nimport '../styles/popup.css'\n\nexport const PwaReadyPopup = defineComponent({\n name: 'PwaReadyPopup',\n\n props: {\n /** locale data */\n locales: {\n type: Object as PropType<PwaPluginLocaleConfig>,\n required: true,\n },\n },\n\n slots: Object as SlotsType<{\n default?: Slot<{ isReady: boolean; reload: () => void }>\n }>,\n\n setup(props, { slots }) {\n const locale = useLocale(props.locales)\n const registration = shallowRef<ServiceWorkerRegistration>()\n\n const isReady = computed(() => Boolean(registration.value))\n\n const reload = (): void => {\n if (registration.value) {\n skipWaiting(registration.value)\n registration.value = undefined\n }\n }\n\n onMounted(() => {\n const event = usePwaEvent()\n\n event.on('updated', (reg) => {\n registration.value = reg\n })\n })\n\n return (): VNode =>\n h(\n Transition,\n { name: 'fade-in-scale-up' },\n () =>\n slots.default?.({\n isReady: isReady.value,\n reload,\n }) ??\n (isReady.value\n ? h(\n 'button',\n {\n type: 'button',\n class: 'sw-update-popup',\n tabindex: 0,\n onClick: () => {\n reload()\n },\n },\n [\n locale.value.update,\n h('span', { class: 'icon-wrapper' }, h(UpdateIcon)),\n ],\n )\n : null),\n )\n },\n})\n"],"mappings":"+UAOA,MAAa,EAAe,GAAkD,CAE5E,IAAM,EAAS,EAAa,QAG5B,GAAI,CAAC,EAAQ,OAGb,IAAM,EAAU,IAAI,eAEpB,EAAO,YAAY,CAAE,KAAM,eAAgB,CAAE,CAAC,EAAQ,MAAM,CAAC,ECElD,EAAgB,EAAgB,CAC3C,KAAM,gBAEN,MAAO,CAEL,QAAS,CACP,KAAM,OACN,SAAU,GACX,CACF,CAED,MAAO,OAIP,MAAM,EAAO,CAAE,SAAS,CACtB,IAAM,EAAS,EAAU,EAAM,QAAQ,CACjC,EAAe,GAAuC,CAEtD,EAAU,MAAe,EAAQ,EAAa,MAAO,CAErD,MAAqB,CACzB,AAEE,EAAa,SADb,EAAY,EAAa,MAAM,CACV,IAAA,KAYzB,OARA,MAAgB,CACA,GAAa,CAErB,GAAG,UAAY,GAAQ,CAC3B,EAAa,MAAQ,GACrB,EACF,KAGA,EACE,EACA,CAAE,KAAM,mBAAoB,KAE1B,EAAM,UAAU,CACd,QAAS,EAAQ,MACjB,SACD,CAAC,GACD,EAAQ,MACL,EACE,SACA,CACE,KAAM,SACN,MAAO,kBACP,SAAU,EACV,YAAe,CACb,GAAQ,EAEX,CACD,CACE,EAAO,MAAM,OACb,EAAE,OAAQ,CAAE,MAAO,eAAgB,CAAE,EAAE,EAAW,CAAC,CACpD,CACF,CACD,MACP,EAEN,CAAC"}
@@ -1,10 +1,7 @@
1
- import { t as PwaPluginLocaleConfig } from "../../types-CGDCqUfb.js";
1
+ import { t as PwaPluginLocaleConfig } from "./types-D2911FOa.js";
2
2
  import { Slot } from "@vuepress/helper/client";
3
3
  import * as vue from "vue";
4
4
  import { PropType, SlotsType, VNode } from "vue";
5
- import "@vuepress/helper/transition/fade-in-scale-up.css";
6
- import "../styles/popup.css";
7
-
8
5
  //#region src/client/components/PwaReadyPopup.d.ts
9
6
  declare const PwaReadyPopup: vue.DefineComponent<vue.ExtractPropTypes<{
10
7
  /** locale data */locales: {
@@ -23,5 +20,5 @@ declare const PwaReadyPopup: vue.DefineComponent<vue.ExtractPropTypes<{
23
20
  }>;
24
21
  }>, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
25
22
  //#endregion
26
- export { PwaReadyPopup };
27
- //# sourceMappingURL=PwaReadyPopup.d.ts.map
23
+ export { PwaReadyPopup as t };
24
+ //# sourceMappingURL=PwaReadyPopup-CDLxW7kc.d.ts.map
@@ -0,0 +1,2 @@
1
+ import { t as PwaFoundPopup } from "../../PwaFoundPopup-DWmIsyXx.js";
2
+ export { PwaFoundPopup };
@@ -0,0 +1,2 @@
1
+ import{i as e}from"../../icons-RRw4DIWa.js";import{a as t}from"../../composables-Bdxx2hts.js";import{useLocale as n}from"@vuepress/helper/client";import{Transition as r,defineComponent as i,h as a,onMounted as o,ref as s}from"vue";import"@vuepress/helper/transition/fade-in-scale-up.css";import"../styles/popup.css";const c=i({name:`PwaFoundPopup`,props:{locales:{type:Object,required:!0}},slots:Object,setup(i,{slots:c}){let l=n(i.locales),u=s(!1),d=()=>{u.value&&=(window.location.reload(!0),!1)};return o(()=>{let e=t();e.on(`updatefound`,()=>{navigator.serviceWorker.getRegistration().then(e=>{e?.active&&(u.value=!0)})}),e.on(`updated`,()=>{u.value=!1})}),()=>a(r,{name:`fade-in-scale-up`},()=>c.default?.({found:u.value,refresh:d})??(u.value?a(`button`,{type:`button`,class:`sw-hint-popup`,tabindex:0,onClick:()=>{d()}},[l.value.hint,a(`span`,{class:`icon-wrapper`},a(e))]):null))}});export{c as PwaFoundPopup};
2
+ //# sourceMappingURL=PwaFoundPopup.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"PwaFoundPopup.js","names":[],"sources":["../../../src/client/components/PwaFoundPopup.ts"],"sourcesContent":["import type { Slot } from '@vuepress/helper/client'\nimport { useLocale } from '@vuepress/helper/client'\nimport type { PropType, SlotsType, VNode } from 'vue'\nimport { Transition, defineComponent, h, onMounted, ref } from 'vue'\nimport { usePwaEvent } from '../composables/index.js'\nimport type { PwaPluginLocaleConfig } from '../types.js'\nimport { UpdateIcon } from './icons.js'\n\nimport '@vuepress/helper/transition/fade-in-scale-up.css'\nimport '../styles/popup.css'\n\nexport const PwaFoundPopup = defineComponent({\n name: 'PwaFoundPopup',\n\n props: {\n /** locale data */\n locales: {\n type: Object as PropType<PwaPluginLocaleConfig>,\n required: true,\n },\n },\n\n slots: Object as SlotsType<{\n default?: Slot<{ found: boolean; refresh: () => void }>\n }>,\n\n setup(props, { slots }) {\n const locale = useLocale(props.locales)\n const found = ref(false)\n\n const refresh = (): void => {\n if (found.value) {\n // force refresh\n // @ts-expect-error: A non-standard API\n window.location.reload(true)\n found.value = false\n }\n }\n\n onMounted(() => {\n const event = usePwaEvent()\n\n event.on('updatefound', () => {\n void navigator.serviceWorker.getRegistration().then((registration) => {\n // Check whether a valid service worker is active\n if (registration?.active) found.value = true\n })\n })\n\n event.on('updated', () => {\n found.value = false\n })\n })\n\n return (): VNode =>\n h(\n Transition,\n { name: 'fade-in-scale-up' },\n () =>\n slots.default?.({\n found: found.value,\n refresh,\n }) ??\n (found.value\n ? h(\n 'button',\n {\n type: 'button',\n class: 'sw-hint-popup',\n tabindex: 0,\n onClick: () => {\n refresh()\n },\n },\n [\n locale.value.hint,\n h('span', { class: 'icon-wrapper' }, h(UpdateIcon)),\n ],\n )\n : null),\n )\n },\n})\n"],"mappings":"+TAWA,MAAa,EAAgB,EAAgB,CAC3C,KAAM,gBAEN,MAAO,CAEL,QAAS,CACP,KAAM,OACN,SAAU,GACX,CACF,CAED,MAAO,OAIP,MAAM,EAAO,CAAE,SAAS,CACtB,IAAM,EAAS,EAAU,EAAM,QAAQ,CACjC,EAAQ,EAAI,GAAM,CAElB,MAAsB,CAC1B,AAIE,EAAM,SADN,OAAO,SAAS,OAAO,GAAK,CACd,KAmBlB,OAfA,MAAgB,CACd,IAAM,EAAQ,GAAa,CAE3B,EAAM,GAAG,kBAAqB,CACvB,UAAU,cAAc,iBAAiB,CAAC,KAAM,GAAiB,CAEhE,GAAc,SAAQ,EAAM,MAAQ,KACxC,EACF,CAEF,EAAM,GAAG,cAAiB,CACxB,EAAM,MAAQ,IACd,EACF,KAGA,EACE,EACA,CAAE,KAAM,mBAAoB,KAE1B,EAAM,UAAU,CACd,MAAO,EAAM,MACb,UACD,CAAC,GACD,EAAM,MACH,EACE,SACA,CACE,KAAM,SACN,MAAO,gBACP,SAAU,EACV,YAAe,CACb,GAAS,EAEZ,CACD,CACE,EAAO,MAAM,KACb,EAAE,OAAQ,CAAE,MAAO,eAAgB,CAAE,EAAE,EAAW,CAAC,CACpD,CACF,CACD,MACP,EAEN,CAAC"}
1
+ {"version":3,"file":"PwaFoundPopup.js","names":[],"sources":["../../../src/client/components/PwaFoundPopup.ts"],"sourcesContent":["import type { Slot } from '@vuepress/helper/client'\nimport { useLocale } from '@vuepress/helper/client'\nimport type { PropType, SlotsType, VNode } from 'vue'\nimport { Transition, defineComponent, h, onMounted, ref } from 'vue'\nimport { usePwaEvent } from '../composables/index.js'\nimport type { PwaPluginLocaleConfig } from '../types.js'\nimport { UpdateIcon } from './icons.js'\n\nimport '@vuepress/helper/transition/fade-in-scale-up.css'\nimport '../styles/popup.css'\n\nexport const PwaFoundPopup = defineComponent({\n name: 'PwaFoundPopup',\n\n props: {\n /** locale data */\n locales: {\n type: Object as PropType<PwaPluginLocaleConfig>,\n required: true,\n },\n },\n\n slots: Object as SlotsType<{\n default?: Slot<{ found: boolean; refresh: () => void }>\n }>,\n\n setup(props, { slots }) {\n const locale = useLocale(props.locales)\n const found = ref(false)\n\n const refresh = (): void => {\n if (found.value) {\n // force refresh\n // @ts-expect-error: A non-standard API\n window.location.reload(true)\n found.value = false\n }\n }\n\n onMounted(() => {\n const event = usePwaEvent()\n\n event.on('updatefound', () => {\n void navigator.serviceWorker.getRegistration().then((registration) => {\n // Check whether a valid service worker is active\n if (registration?.active) found.value = true\n })\n })\n\n event.on('updated', () => {\n found.value = false\n })\n })\n\n return (): VNode =>\n h(\n Transition,\n { name: 'fade-in-scale-up' },\n () =>\n slots.default?.({\n found: found.value,\n refresh,\n }) ??\n (found.value\n ? h(\n 'button',\n {\n type: 'button',\n class: 'sw-hint-popup',\n tabindex: 0,\n onClick: () => {\n refresh()\n },\n },\n [\n locale.value.hint,\n h('span', { class: 'icon-wrapper' }, h(UpdateIcon)),\n ],\n )\n : null),\n )\n },\n})\n"],"mappings":"4TAWA,MAAa,EAAgB,EAAgB,CAC3C,KAAM,gBAEN,MAAO,CAEL,QAAS,CACP,KAAM,OACN,SAAU,GACX,CACF,CAED,MAAO,OAIP,MAAM,EAAO,CAAE,SAAS,CACtB,IAAM,EAAS,EAAU,EAAM,QAAQ,CACjC,EAAQ,EAAI,GAAM,CAElB,MAAsB,CAC1B,AAIE,EAAM,SADN,OAAO,SAAS,OAAO,GAAK,CACd,KAmBlB,OAfA,MAAgB,CACd,IAAM,EAAQ,GAAa,CAE3B,EAAM,GAAG,kBAAqB,CACvB,UAAU,cAAc,iBAAiB,CAAC,KAAM,GAAiB,CAEhE,GAAc,SAAQ,EAAM,MAAQ,KACxC,EACF,CAEF,EAAM,GAAG,cAAiB,CACxB,EAAM,MAAQ,IACd,EACF,KAGA,EACE,EACA,CAAE,KAAM,mBAAoB,KAE1B,EAAM,UAAU,CACd,MAAO,EAAM,MACb,UACD,CAAC,GACD,EAAM,MACH,EACE,SACA,CACE,KAAM,SACN,MAAO,gBACP,SAAU,EACV,YAAe,CACb,GAAS,EAEZ,CACD,CACE,EAAO,MAAM,KACb,EAAE,OAAQ,CAAE,MAAO,eAAgB,CAAE,EAAE,EAAW,CAAC,CACpD,CACF,CACD,MACP,EAEN,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { t as PwaInstall } from "../../PwaInstall-w3x5rHx6.js";
2
+ export { PwaInstall };
@@ -0,0 +1 @@
1
+ import{t as e}from"../../PwaInstall-Ee3il2nW.js";export{e as PwaInstall};
@@ -0,0 +1,2 @@
1
+ import { t as PwaReadyPopup } from "../../PwaReadyPopup-CDLxW7kc.js";
2
+ export { PwaReadyPopup };
@@ -0,0 +1 @@
1
+ import{t as e}from"../../PwaReadyPopup-6AypjW2B.js";export{e as PwaReadyPopup};
@@ -0,0 +1 @@
1
+ import{a as e,i as t,n,r,t as i}from"../../composables-Bdxx2hts.js";export{t as pwaEventSymbol,n as setupPwa,i as setupViewPoint,e as usePwaEvent,r as useRegisterSW};
@@ -1,7 +1,7 @@
1
- import { t as PwaPluginLocaleConfig } from "../types-CGDCqUfb.js";
2
- import { PwaFoundPopup } from "./components/PwaFoundPopup.js";
3
- import { PwaInstall } from "./components/PwaInstall.js";
4
- import { PwaReadyPopup } from "./components/PwaReadyPopup.js";
1
+ import { t as PwaPluginLocaleConfig } from "../types-D2911FOa.js";
2
+ import { t as PwaFoundPopup } from "../PwaFoundPopup-DWmIsyXx.js";
3
+ import { t as PwaInstall } from "../PwaInstall-w3x5rHx6.js";
4
+ import { t as PwaReadyPopup } from "../PwaReadyPopup-CDLxW7kc.js";
5
5
  import { PwaEvent, pwaEventSymbol, setupPwa, setupViewPoint, usePwaEvent, useRegisterSW } from "./composables/index.js";
6
6
  import { Hooks } from "register-service-worker";
7
7
 
@@ -0,0 +1,2 @@
1
+ import{t as e}from"../PwaInstall-Ee3il2nW.js";import{a as t,i as n,n as r,o as i,r as a,s as o,t as s}from"../composables-Bdxx2hts.js";import{n as c,t as l}from"../PwaReadyPopup-6AypjW2B.js";import{PwaFoundPopup as u}from"./components/PwaFoundPopup.js";const d=async()=>{try{let e=await navigator.serviceWorker.getRegistration();if(e){let t=await e.unregister();return t&&console.log(`[PWA] Current service worker unregistered`),t}}catch(e){console.error(`[PWA] Unregister current service worker failed with error:`,e)}return!1};export{u as PwaFoundPopup,e as PwaInstall,l as PwaReadyPopup,o as forceUpdate,n as pwaEventSymbol,i as registerSW,r as setupPwa,s as setupViewPoint,c as skipWaiting,d as unregisterSW,t as usePwaEvent,a as useRegisterSW};
2
+ //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/client/utils/unregisterSW.ts"],"sourcesContent":["/* eslint-disable no-console */\n/**\n * Call `unregister()` inside current active worker\n *\n * 在当前激活的 Service Worker 中调用 `unregister()`\n *\n * @returns `true` if unregister success, `false` if unregister failed / `true` 表示注销成功,`false` 表示注销失败\n */\nexport const unregisterSW = async (): Promise<boolean> => {\n try {\n const registration = await navigator.serviceWorker.getRegistration()\n if (registration) {\n const found = await registration.unregister()\n if (found) console.log('[PWA] Current service worker unregistered')\n return found\n }\n } catch (err: unknown) {\n console.error(\n '[PWA] Unregister current service worker failed with error:',\n err,\n )\n }\n return false\n}\n"],"mappings":"+TAQA,MAAa,EAAe,SAA8B,CACxD,GAAI,CACF,IAAM,EAAe,MAAM,UAAU,cAAc,iBAAiB,CACpE,GAAI,EAAc,CAChB,IAAM,EAAQ,MAAM,EAAa,YAAY,CAE7C,OADI,GAAO,QAAQ,IAAI,4CAA4C,CAC5D,SAEF,EAAc,CACrB,QAAQ,MACN,6DACA,EACD,CAEH,MAAO"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/client/utils/unregisterSW.ts"],"sourcesContent":["/* eslint-disable no-console */\n/**\n * Call `unregister()` inside current active worker\n *\n * 在当前激活的 Service Worker 中调用 `unregister()`\n *\n * @returns `true` if unregister success, `false` if unregister failed / `true` 表示注销成功,`false` 表示注销失败\n */\nexport const unregisterSW = async (): Promise<boolean> => {\n try {\n const registration = await navigator.serviceWorker.getRegistration()\n if (registration) {\n const found = await registration.unregister()\n if (found) console.log('[PWA] Current service worker unregistered')\n return found\n }\n } catch (err: unknown) {\n console.error(\n '[PWA] Unregister current service worker failed with error:',\n err,\n )\n }\n return false\n}\n"],"mappings":"6PAQA,MAAa,EAAe,SAA8B,CACxD,GAAI,CACF,IAAM,EAAe,MAAM,UAAU,cAAc,iBAAiB,CACpE,GAAI,EAAc,CAChB,IAAM,EAAQ,MAAM,EAAa,YAAY,CAE7C,OADI,GAAO,QAAQ,IAAI,4CAA4C,CAC5D,SAEF,EAAc,CACrB,QAAQ,MACN,6DACA,EACD,CAEH,MAAO"}
@@ -0,0 +1,2 @@
1
+ import{inject as e,onMounted as t,provide as n}from"vue";import{withBase as r}from"vuepress/client";import i from"mitt";const a=()=>{navigator.serviceWorker.getRegistration().then(e=>{e?.active&&e.addEventListener(`updatefound`,()=>{window.location.reload(!0)})})},o=async(e,t={},n=!0)=>{let{register:r}=await import(`register-service-worker`);r(e,{ready(e){n&&console.info(`[Service Worker]: active`),t.ready?.(e)},registered(e){n&&console.log(`[Service Worker]: registered`),t.registered?.(e)},cached(e){n&&console.log(`[Service Worker]: cached`),t.cached?.(e)},updatefound(e){n&&console.log(`[Service Worker]: update found`),t.updatefound?.(e)},updated(e){n&&console.log(`[Service Worker]: updated`),t.updated?.(e)},offline(){n&&console.log(`[Service Worker]: offline`),t.offline?.()},error(e){n&&console.error(`[Service Worker]:`,e),t.error?.(e)}})},s=Symbol(__VUEPRESS_DEV__?`PwaEvent`:``),c=()=>{let t=e(s);if(!t)throw Error(`usePwaEvent() is called without provider.`);return t},l=async(e,t)=>{await o(r(e),{ready(e){t.emit(`ready`,e)},registered(e){t.emit(`registered`,e)},cached(e){t.emit(`cached`,e)},updatefound(e){t.emit(`updatefound`,e)},updated(e){let n=`service-worker-version`,r=Number(localStorage.getItem(n)||0);localStorage.setItem(n,(r+1).toString()),localStorage.removeItem(`manifest`),t.emit(`updated`,e)},offline(){t.emit(`offline`)},error(e){t.emit(`error`,e)}})},u=(e,r=!1)=>{if(__VUEPRESS_SSR__)return;let o=i();n(s,o),t(async()=>{if(__VUEPRESS_DEV__||!(`serviceWorker`in navigator))return;let t=!1;navigator.serviceWorker.controller&&navigator.serviceWorker.addEventListener(`controllerchange`,()=>{t||(t=!0,window.location.reload())}),r&&a(),await l(e,o)})},d=()=>{t(()=>{if(window.matchMedia(`(display-mode: standalone)`).matches){let e=document.head.querySelector(`meta[name="viewport"]`);if(e){e.setAttribute(`content`,`width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover`);return}let t=document.createElement(`meta`);t.name=`viewport`,t.content=`width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover`,document.head.append(t)}})};export{c as a,s as i,u as n,o,l as r,a as s,d as t};
2
+ //# sourceMappingURL=composables-Bdxx2hts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"composables-Bdxx2hts.js","names":[],"sources":["../src/client/utils/forceUpdate.ts","../src/client/utils/registerSW.ts","../src/client/composables/usePwaEvent.ts","../src/client/composables/useRegisterSW.ts","../src/client/composables/setupPwa.ts","../src/client/composables/setupViewPoint.ts"],"sourcesContent":["/**\n * Force update page content\n *\n * 强制更新页面内容\n */\nexport const forceUpdate = (): void => {\n void navigator.serviceWorker.getRegistration().then((registration) => {\n // Check whether a valid service worker is active\n if (registration?.active) {\n registration.addEventListener('updatefound', () => {\n // force refresh\n // @ts-expect-error: A non-standard API\n window.location.reload(true)\n })\n }\n })\n}\n","/* eslint-disable no-console */\nimport type { Hooks } from 'register-service-worker'\n\n/**\n * Register serviceWorker under `serviceWorkerPath`\n *\n * 在 `serviceWorkerPath` 下注册 Service Worker\n *\n * @param serviceWorkerPath - Service Worker path / Service Worker 路径\n * @param hooks - Service worker hooks / Service Worker 钩子\n * @param showStatus - Whether to show status in console / 是否在控制台显示状态\n */\nexport const registerSW = async (\n serviceWorkerPath: string,\n hooks: Hooks = {},\n showStatus = true,\n): Promise<void> => {\n const { register } = await import(\n /* webpackChunkName: \"register-service-worker\" */ 'register-service-worker'\n )\n\n // Register service worker\n register(serviceWorkerPath, {\n ready(registration) {\n if (showStatus) console.info('[Service Worker]: active')\n hooks.ready?.(registration)\n },\n\n registered(registration) {\n if (showStatus) console.log('[Service Worker]: registered')\n hooks.registered?.(registration)\n },\n\n cached(registration) {\n if (showStatus) console.log('[Service Worker]: cached')\n hooks.cached?.(registration)\n },\n\n updatefound(registration) {\n if (showStatus) console.log('[Service Worker]: update found')\n hooks.updatefound?.(registration)\n },\n\n updated(registration) {\n if (showStatus) console.log('[Service Worker]: updated')\n hooks.updated?.(registration)\n },\n\n offline() {\n if (showStatus) console.log('[Service Worker]: offline')\n hooks.offline?.()\n },\n\n error(err) {\n if (showStatus) console.error('[Service Worker]:', err)\n hooks.error?.(err)\n },\n })\n}\n","import type { Emitter } from 'mitt'\nimport type { InjectionKey } from 'vue'\nimport { inject } from 'vue'\n\ndeclare const __VUEPRESS_DEV__: boolean\n\nexport type PwaEvent = Emitter<{\n ready: ServiceWorkerRegistration\n registered: ServiceWorkerRegistration\n cached: ServiceWorkerRegistration\n updatefound: ServiceWorkerRegistration\n updated: ServiceWorkerRegistration\n offline: void\n error: Error\n}>\n\nexport const pwaEventSymbol: InjectionKey<PwaEvent> = Symbol(\n __VUEPRESS_DEV__ ? 'PwaEvent' : '',\n)\n\n/**\n * Use PWA event emitter\n *\n * 使用 PWA 事件发射器\n *\n * @returns PWA event emitter / PWA 事件发射器\n */\nexport const usePwaEvent = (): PwaEvent => {\n const pwaEvent = inject(pwaEventSymbol)\n\n if (!pwaEvent) throw new Error('usePwaEvent() is called without provider.')\n\n return pwaEvent\n}\n","import { withBase } from 'vuepress/client'\nimport { registerSW } from '../utils/index.js'\nimport type { PwaEvent } from './usePwaEvent.js'\n\n/**\n * Register service worker with event emitter\n *\n * 使用事件发射器注册 Service Worker\n *\n * @param serviceWorkerPath - Service Worker path / Service Worker 路径\n * @param event - PWA event emitter / PWA 事件发射器\n */\nexport const useRegisterSW = async (\n serviceWorkerPath: string,\n event: PwaEvent,\n): Promise<void> => {\n await registerSW(withBase(serviceWorkerPath), {\n ready(registration) {\n event.emit('ready', registration)\n },\n\n registered(registration) {\n event.emit('registered', registration)\n },\n\n cached(registration) {\n event.emit('cached', registration)\n },\n\n updatefound(registration) {\n event.emit('updatefound', registration)\n },\n\n updated(registration) {\n const key = 'service-worker-version'\n const version = Number(localStorage.getItem(key) || 0)\n\n localStorage.setItem(key, (version + 1).toString())\n localStorage.removeItem('manifest')\n\n event.emit('updated', registration)\n },\n\n offline() {\n event.emit('offline')\n },\n\n error(err) {\n event.emit('error', err)\n },\n })\n}\n","import mitt from 'mitt'\nimport { onMounted, provide } from 'vue'\nimport { forceUpdate } from '../utils/index.js'\nimport { pwaEventSymbol } from './usePwaEvent.js'\nimport { useRegisterSW } from './useRegisterSW.js'\nimport type { PwaEvent } from './index.js'\n\n/**\n * Setup PWA functionality\n *\n * 设置 PWA 功能\n *\n * @param serviceWorkerPath - Service Worker path / Service Worker 路径\n * @param shouldForceUpdate - Whether to force update / 是否强制更新\n */\nexport const setupPwa = (\n serviceWorkerPath: string,\n shouldForceUpdate = false,\n): void => {\n if (__VUEPRESS_SSR__) return\n\n // Create event emitter and provide it\n const event: PwaEvent = mitt()\n\n provide(pwaEventSymbol, event)\n\n onMounted(async () => {\n if (__VUEPRESS_DEV__ || !('serviceWorker' in navigator)) return\n\n let refreshing = false\n\n // Only listen controllerchange event when a serviceWorker is active\n if (navigator.serviceWorker.controller) {\n navigator.serviceWorker.addEventListener('controllerchange', () => {\n if (refreshing) return\n\n refreshing = true\n window.location.reload()\n })\n }\n\n if (shouldForceUpdate) forceUpdate()\n\n await useRegisterSW(serviceWorkerPath, event)\n })\n}\n","import { onMounted } from 'vue'\n\n/**\n * Setup viewport for PWA standalone mode\n *\n * 为 PWA 独立模式设置视口\n */\nexport const setupViewPoint = (): void => {\n onMounted(() => {\n const isStandAlone = window.matchMedia('(display-mode: standalone)').matches\n\n if (isStandAlone) {\n const head = document.head.querySelector('meta[name=\"viewport\"]')\n\n if (head) {\n head.setAttribute(\n 'content',\n 'width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover',\n )\n return\n }\n\n const viewportMeta = document.createElement('meta')\n\n viewportMeta.name = 'viewport'\n viewportMeta.content =\n 'width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover'\n\n document.head.append(viewportMeta)\n }\n })\n}\n"],"mappings":"wHAKA,MAAa,MAA0B,CAChC,UAAU,cAAc,iBAAiB,CAAC,KAAM,GAAiB,CAEhE,GAAc,QAChB,EAAa,iBAAiB,kBAAqB,CAGjD,OAAO,SAAS,OAAO,GAAK,EAC5B,EAEJ,ECHS,EAAa,MACxB,EACA,EAAe,EAAE,CACjB,EAAa,KACK,CAClB,GAAM,CAAE,YAAa,MAAM,OACyB,2BAIpD,EAAS,EAAmB,CAC1B,MAAM,EAAc,CACd,GAAY,QAAQ,KAAK,2BAA2B,CACxD,EAAM,QAAQ,EAAa,EAG7B,WAAW,EAAc,CACnB,GAAY,QAAQ,IAAI,+BAA+B,CAC3D,EAAM,aAAa,EAAa,EAGlC,OAAO,EAAc,CACf,GAAY,QAAQ,IAAI,2BAA2B,CACvD,EAAM,SAAS,EAAa,EAG9B,YAAY,EAAc,CACpB,GAAY,QAAQ,IAAI,iCAAiC,CAC7D,EAAM,cAAc,EAAa,EAGnC,QAAQ,EAAc,CAChB,GAAY,QAAQ,IAAI,4BAA4B,CACxD,EAAM,UAAU,EAAa,EAG/B,SAAU,CACJ,GAAY,QAAQ,IAAI,4BAA4B,CACxD,EAAM,WAAW,EAGnB,MAAM,EAAK,CACL,GAAY,QAAQ,MAAM,oBAAqB,EAAI,CACvD,EAAM,QAAQ,EAAI,EAErB,CAAC,ECzCS,EAAyC,OACpD,iBAAmB,WAAa,GACjC,CASY,MAA8B,CACzC,IAAM,EAAW,EAAO,EAAe,CAEvC,GAAI,CAAC,EAAU,MAAU,MAAM,4CAA4C,CAE3E,OAAO,GCpBI,EAAgB,MAC3B,EACA,IACkB,CAClB,MAAM,EAAW,EAAS,EAAkB,CAAE,CAC5C,MAAM,EAAc,CAClB,EAAM,KAAK,QAAS,EAAa,EAGnC,WAAW,EAAc,CACvB,EAAM,KAAK,aAAc,EAAa,EAGxC,OAAO,EAAc,CACnB,EAAM,KAAK,SAAU,EAAa,EAGpC,YAAY,EAAc,CACxB,EAAM,KAAK,cAAe,EAAa,EAGzC,QAAQ,EAAc,CACpB,IAAM,EAAM,yBACN,EAAU,OAAO,aAAa,QAAQ,EAAI,EAAI,EAAE,CAEtD,aAAa,QAAQ,GAAM,EAAU,GAAG,UAAU,CAAC,CACnD,aAAa,WAAW,WAAW,CAEnC,EAAM,KAAK,UAAW,EAAa,EAGrC,SAAU,CACR,EAAM,KAAK,UAAU,EAGvB,MAAM,EAAK,CACT,EAAM,KAAK,QAAS,EAAI,EAE3B,CAAC,ECnCS,GACX,EACA,EAAoB,KACX,CACT,GAAI,iBAAkB,OAGtB,IAAM,EAAkB,GAAM,CAE9B,EAAQ,EAAgB,EAAM,CAE9B,EAAU,SAAY,CACpB,GAAI,kBAAoB,EAAE,kBAAmB,WAAY,OAEzD,IAAI,EAAa,GAGb,UAAU,cAAc,YAC1B,UAAU,cAAc,iBAAiB,uBAA0B,CAC7D,IAEJ,EAAa,GACb,OAAO,SAAS,QAAQ,GACxB,CAGA,GAAmB,GAAa,CAEpC,MAAM,EAAc,EAAmB,EAAM,EAC7C,ECrCS,MAA6B,CACxC,MAAgB,CAGd,GAFqB,OAAO,WAAW,6BAA6B,CAAC,QAEnD,CAChB,IAAM,EAAO,SAAS,KAAK,cAAc,wBAAwB,CAEjE,GAAI,EAAM,CACR,EAAK,aACH,UACA,iGACD,CACD,OAGF,IAAM,EAAe,SAAS,cAAc,OAAO,CAEnD,EAAa,KAAO,WACpB,EAAa,QACX,iGAEF,SAAS,KAAK,OAAO,EAAa,GAEpC"}
@@ -69,4 +69,4 @@ interface PwaPluginLocaleData {
69
69
  }
70
70
  //#endregion
71
71
  export { PwaPluginLocaleData as t };
72
- //# sourceMappingURL=locales-BlsUewPq.d.ts.map
72
+ //# sourceMappingURL=locales-Bj0jQ5BO.d.ts.map
@@ -1,4 +1,4 @@
1
- import { t as PwaPluginLocaleData } from "../locales-BlsUewPq.js";
1
+ import { t as PwaPluginLocaleData } from "../locales-Bj0jQ5BO.js";
2
2
  import { DefaultLocaleInfo } from "@vuepress/helper";
3
3
  import { GenerateSWOptions } from "workbox-build";
4
4
  import { LocaleConfig } from "vuepress/shared";
@@ -1,8 +1,8 @@
1
- import { t as PwaPluginLocaleData } from "./locales-BlsUewPq.js";
1
+ import { t as PwaPluginLocaleData } from "./locales-Bj0jQ5BO.js";
2
2
  import { ExactLocaleConfig } from "@vuepress/helper/client";
3
3
 
4
4
  //#region src/client/types.d.ts
5
5
  type PwaPluginLocaleConfig = ExactLocaleConfig<PwaPluginLocaleData>;
6
6
  //#endregion
7
7
  export { PwaPluginLocaleConfig as t };
8
- //# sourceMappingURL=types-CGDCqUfb.d.ts.map
8
+ //# sourceMappingURL=types-D2911FOa.d.ts.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vuepress/plugin-pwa",
3
- "version": "2.0.0-rc.124",
3
+ "version": "2.0.0-rc.125",
4
4
  "description": "VuePress plugin - progressive web application",
5
5
  "keywords": [
6
6
  "plugin",
@@ -24,29 +24,29 @@
24
24
  "directory": "plugins/pwa/plugin-pwa"
25
25
  },
26
26
  "files": [
27
- "lib"
27
+ "dist"
28
28
  ],
29
29
  "type": "module",
30
30
  "sideEffects": [
31
- "./lib/client/styles/**/*.css"
31
+ "./dist/client/styles/**/*.css"
32
32
  ],
33
33
  "exports": {
34
34
  ".": {
35
- "types": "./lib/node/index.d.ts",
36
- "default": "./lib/node/index.js"
35
+ "types": "./dist/node/index.d.ts",
36
+ "default": "./dist/node/index.js"
37
37
  },
38
38
  "./client": {
39
- "types": "./lib/client/index.d.ts",
40
- "default": "./lib/client/index.js"
39
+ "types": "./dist/client/index.d.ts",
40
+ "default": "./dist/client/index.js"
41
41
  },
42
- "./styles/*.css": "./lib/client/styles/*.css",
42
+ "./styles/*.css": "./dist/client/styles/*.css",
43
43
  "./package.json": "./package.json"
44
44
  },
45
45
  "publishConfig": {
46
46
  "access": "public"
47
47
  },
48
48
  "dependencies": {
49
- "@vuepress/helper": "2.0.0-rc.124",
49
+ "@vuepress/helper": "2.0.0-rc.125",
50
50
  "@vueuse/core": "^14.2.1",
51
51
  "mitt": "^3.0.1",
52
52
  "register-service-worker": "^1.7.2",
@@ -56,5 +56,5 @@
56
56
  "peerDependencies": {
57
57
  "vuepress": "2.0.0-rc.26"
58
58
  },
59
- "gitHead": "f17e7479b1ef3c06814b6107df9188ba351702da"
59
+ "gitHead": "58e660bb7138f1883e5440a08903d09cdbabcdc8"
60
60
  }
@@ -1,2 +0,0 @@
1
- import{n as e,r as t,t as n}from"./icons-RRw4DIWa.js";import{useLocale as r}from"@vuepress/helper/client";import{useEventListener as i}from"@vueuse/core";import{defineComponent as a,h as o,onMounted as s,shallowRef as c}from"vue";import{withBase as l}from"vuepress/client";const u=()=>{let e=document.querySelector(`.screenshot`);e&&e.scrollBy({left:-e.clientWidth,top:0,behavior:`smooth`})},d=()=>{let e=document.querySelector(`.screenshot`);e&&e.scrollBy({left:e.clientWidth,top:0,behavior:`smooth`})},f=a({name:`PwaInstallModal`,props:{locales:{type:Object,required:!0},useHint:Boolean},emits:[`canInstall`,`hint`,`close`],setup(a,{emit:f}){let p=r(a.locales),m=c({}),h=c(),g=async()=>{let e=localStorage.getItem(`manifest`);if(e)m.value=JSON.parse(e);else try{let e=await(await fetch(l(`manifest.webmanifest`))).json();m.value=e,localStorage.setItem(`manifest`,JSON.stringify(e))}catch{console.error(`[PWA]: Error getting manifest, check that you have a valid web manifest or network connection`)}},_=async()=>{h.value&&(h.value.prompt(),document.dispatchEvent(new CustomEvent(`show`)),(await h.value.userChoice).outcome===`accepted`?(console.info(`PWA has been installed`),f(`close`,!1),f(`canInstall`,!1)):(console.info(`You choose to not install PWA`),f(`close`,!1),f(`canInstall`,!1)))},v=()=>{console.info(`You accepted the install hint`),f(`hint`)};return s(()=>{window.hasOwnProperty(`BeforeInstallPromptEvent`)&&(i(window,`beforeinstallprompt`,e=>{h.value=e,f(`canInstall`,!0),e.preventDefault()}),i(`keyup`,e=>{e.key===`Escape`&&f(`close`,!1)},{passive:!0}),g())}),()=>o(`div`,{id:`install-modal-wrapper`},[o(`div`,{class:`background`,onClick:()=>{f(`close`,!1)}}),o(`div`,{class:`install-modal`},[o(`div`,{class:`header`},[o(`button`,{type:`button`,class:`close-button`,"aria-label":p.value.close,onClick:()=>{f(`close`,!1)}},o(t)),o(`div`,{class:`logo`},[m.value.icons?o(`img`,{src:m.value.icons[0]?.src,alt:`App Logo`}):null,o(`div`,{class:`title`},[o(`h1`,m.value.short_name||m.value.name),o(`p`,{class:`desc`},p.value.explain)])])]),o(`div`,{class:`content`},[o(`div`,{class:`highlight`},[m.value.features?o(`div`,{class:`feature-wrapper`},[o(`h3`,p.value.feature),o(`ul`,m.value.features.map(e=>o(`li`,e)))]):null,m.value.screenshots?o(`div`,{class:`screenshot-wrapper`},[o(`button`,{type:`button`,"aria-label":p.value.prevImage,onClick:u},o(n)),o(`section`,{class:`screenshot`},[m.value.screenshots.map(e=>o(`div`,o(`img`,{src:e.src,alt:`App Screenshot`})))]),o(`button`,{type:`button`,"aria-label":p.value.nextImage,onClick:d},o(e))]):null]),o(`div`,{class:`description`},[o(`h3`,p.value.desc),o(`p`,m.value.description)])]),a.useHint?o(`div`,{class:`ios-text`,onClick:v},[o(`p`,p.value.iOSInstall),o(`button`,{type:`button`,class:`success`},`Got it!`)]):o(`div`,{class:`button-wrapper`},[o(`button`,{type:`button`,class:`install-button`,onClick:_},[p.value.install,o(`span`,m.value.short_name)]),o(`button`,{type:`button`,class:`cancel-button`,onClick:()=>{f(`close`,!1)}},p.value.cancel)])])])}});export{f as t};
2
- //# sourceMappingURL=PwaInstallModal-DH0cwyM5.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"PwaInstallModal-DH0cwyM5.js","names":[],"sources":["../src/client/components/PwaInstallModal.ts"],"sourcesContent":["/* eslint-disable no-console */\nimport { useLocale } from '@vuepress/helper/client'\nimport { useEventListener } from '@vueuse/core'\nimport type { PropType, VNode } from 'vue'\nimport { defineComponent, h, onMounted, shallowRef } from 'vue'\nimport { withBase } from 'vuepress/client'\nimport type { AppManifest } from '../../shared/index.js'\nimport type { PwaPluginLocaleConfig } from '../types.js'\nimport { ArrowLeftIcon, ArrowRightIcon, CloseIcon } from './icons.js'\n\ninterface InstallPromptEvent extends Event {\n readonly platforms: string\n prompt: () => void\n readonly userChoice: Promise<{ outcome: 'accepted' | 'dismissed' }>\n}\n\nconst scrollToLeft = (): void => {\n const screenshotsDiv = document.querySelector('.screenshot')\n\n if (screenshotsDiv) {\n screenshotsDiv.scrollBy({\n left: -screenshotsDiv.clientWidth,\n top: 0,\n behavior: 'smooth',\n })\n }\n}\n\nconst scrollToRight = (): void => {\n const screenshotsDiv = document.querySelector('.screenshot')\n\n if (screenshotsDiv) {\n screenshotsDiv.scrollBy({\n left: screenshotsDiv.clientWidth,\n top: 0,\n behavior: 'smooth',\n })\n }\n}\n\nexport const PwaInstallModal = defineComponent({\n name: 'PwaInstallModal',\n\n props: {\n /** locale data */\n locales: {\n type: Object as PropType<PwaPluginLocaleConfig>,\n required: true,\n },\n\n /**\n * Whether use hint message instead of showing a button\n *\n * 是否使用提示\n */\n useHint: Boolean,\n },\n\n emits: ['canInstall', 'hint', 'close'],\n\n setup(props, { emit }) {\n const locale = useLocale(props.locales)\n\n const manifest = shallowRef<AppManifest>({})\n const deferredPrompt = shallowRef<InstallPromptEvent>()\n\n const getManifest = async (): Promise<void> => {\n const manifestContent = localStorage.getItem('manifest')\n\n if (manifestContent) {\n manifest.value = JSON.parse(manifestContent) as AppManifest\n } else {\n try {\n const response = await fetch(withBase('manifest.webmanifest'))\n const data = (await response.json()) as AppManifest\n\n manifest.value = data\n localStorage.setItem('manifest', JSON.stringify(data))\n } catch {\n console.error(\n '[PWA]: Error getting manifest, check that you have a valid web manifest or network connection',\n )\n }\n }\n }\n\n const install = async (): Promise<void> => {\n if (deferredPrompt.value) {\n deferredPrompt.value.prompt()\n\n document.dispatchEvent(new CustomEvent('show'))\n\n const choiceResult = await deferredPrompt.value.userChoice\n\n if (choiceResult.outcome === 'accepted') {\n console.info('PWA has been installed')\n\n emit('close', false)\n emit('canInstall', false)\n } else {\n console.info('You choose to not install PWA')\n\n emit('close', false)\n emit('canInstall', false)\n }\n }\n }\n\n const hint = (): void => {\n console.info('You accepted the install hint')\n emit('hint')\n }\n\n onMounted(() => {\n // eslint-disable-next-line no-prototype-builtins\n if (window.hasOwnProperty('BeforeInstallPromptEvent')) {\n useEventListener(window, 'beforeinstallprompt', (event) => {\n deferredPrompt.value = event as InstallPromptEvent\n\n emit('canInstall', true)\n event.preventDefault()\n })\n\n useEventListener(\n 'keyup',\n (event): void => {\n if (event.key === 'Escape') emit('close', false)\n },\n { passive: true },\n )\n\n void getManifest()\n }\n })\n\n return (): VNode =>\n h('div', { id: 'install-modal-wrapper' }, [\n h('div', {\n class: 'background',\n onClick: () => {\n emit('close', false)\n },\n }),\n\n h('div', { class: 'install-modal' }, [\n h('div', { class: 'header' }, [\n // close button\n h(\n 'button',\n {\n 'type': 'button',\n 'class': 'close-button',\n 'aria-label': locale.value.close,\n 'onClick': () => {\n emit('close', false)\n },\n },\n h(CloseIcon),\n ),\n\n h('div', { class: 'logo' }, [\n manifest.value.icons\n ? h('img', {\n src: manifest.value.icons[0]?.src,\n alt: 'App Logo',\n })\n : null,\n h('div', { class: 'title' }, [\n h('h1', manifest.value.short_name || manifest.value.name),\n h('p', { class: 'desc' }, locale.value.explain),\n ]),\n ]),\n ]),\n\n h('div', { class: 'content' }, [\n h('div', { class: 'highlight' }, [\n manifest.value.features\n ? h('div', { class: 'feature-wrapper' }, [\n h('h3', locale.value.feature),\n h(\n 'ul',\n manifest.value.features.map((feature) =>\n h('li', feature),\n ),\n ),\n ])\n : null,\n\n manifest.value.screenshots\n ? h('div', { class: 'screenshot-wrapper' }, [\n h(\n 'button',\n {\n 'type': 'button',\n 'aria-label': locale.value.prevImage,\n 'onClick': scrollToLeft,\n },\n h(ArrowLeftIcon),\n ),\n h('section', { class: 'screenshot' }, [\n manifest.value.screenshots.map((screenshot) =>\n h(\n 'div',\n h('img', {\n src: screenshot.src,\n alt: 'App Screenshot',\n }),\n ),\n ),\n ]),\n h(\n 'button',\n {\n 'type': 'button',\n 'aria-label': locale.value.nextImage,\n 'onClick': scrollToRight,\n },\n h(ArrowRightIcon),\n ),\n ])\n : null,\n ]),\n\n h('div', { class: 'description' }, [\n h('h3', locale.value.desc),\n h('p', manifest.value.description),\n ]),\n ]),\n\n props.useHint\n ? h('div', { class: 'ios-text', onClick: hint }, [\n h('p', locale.value.iOSInstall),\n h('button', { type: 'button', class: 'success' }, 'Got it!'),\n ])\n : h('div', { class: 'button-wrapper' }, [\n h(\n 'button',\n { type: 'button', class: 'install-button', onClick: install },\n [locale.value.install, h('span', manifest.value.short_name)],\n ),\n h(\n 'button',\n {\n type: 'button',\n class: 'cancel-button',\n onClick: () => {\n emit('close', false)\n },\n },\n locale.value.cancel,\n ),\n ]),\n ]),\n ])\n },\n})\n"],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- import{i as e}from"../../icons-RRw4DIWa.js";import{a as t}from"../../setupViewPoint-DS4c13mS.js";import{useLocale as n}from"@vuepress/helper/client";import{Transition as r,defineComponent as i,h as a,onMounted as o,ref as s}from"vue";import"@vuepress/helper/transition/fade-in-scale-up.css";import"../styles/popup.css";const c=i({name:`PwaFoundPopup`,props:{locales:{type:Object,required:!0}},slots:Object,setup(i,{slots:c}){let l=n(i.locales),u=s(!1),d=()=>{u.value&&=(window.location.reload(!0),!1)};return o(()=>{let e=t();e.on(`updatefound`,()=>{navigator.serviceWorker.getRegistration().then(e=>{e?.active&&(u.value=!0)})}),e.on(`updated`,()=>{u.value=!1})}),()=>a(r,{name:`fade-in-scale-up`},()=>c.default?.({found:u.value,refresh:d})??(u.value?a(`button`,{type:`button`,class:`sw-hint-popup`,tabindex:0,onClick:()=>{d()}},[l.value.hint,a(`span`,{class:`icon-wrapper`},a(e))]):null))}});export{c as PwaFoundPopup};
2
- //# sourceMappingURL=PwaFoundPopup.js.map
@@ -1,2 +0,0 @@
1
- import{t as e}from"../../PwaInstallModal-DH0cwyM5.js";import{useLocale as t}from"@vuepress/helper/client";import{useToggle as n}from"@vueuse/core";import{computed as r,defineComponent as i,h as a,onMounted as o,ref as s}from"vue";import"../styles/modal.css";const c=i({name:`PwaInstall`,props:{locales:{type:Object,required:!0}},setup(i){let c=t(i.locales),[l,u]=n(),d=s(!1),f=s(!1),p=s(!1),m=s(!1),h=s(!1),g=r(()=>p.value&&m.value&&!h.value),_=r(()=>f.value&&d.value||g.value),v=()=>navigator.standalone?navigator.standalone:matchMedia(`(display-mode: standalone)`).matches,y=()=>{u(!1),h.value=!0,localStorage.setItem(`iOS-pwa-hint`,`hinted`)};return o(()=>{if(v()){let{userAgent:e}=navigator;p.value=e.includes(`iPhone`)||e.includes(`iPad`)||!!(e.includes(`Macintosh`)&&navigator.maxTouchPoints&&navigator.maxTouchPoints>2),m.value=navigator.userAgent.includes(`Safari`)&&!e.includes(`Chrome`),h.value=!!localStorage.getItem(`iOS-pwa-hint`)}`getInstalledRelatedApps`in navigator&&navigator.getInstalledRelatedApps().then(e=>{f.value=e.length>0})}),()=>a(`div`,{id:`pwa-install`},[_.value?a(`button`,{type:`button`,class:`modal-button`,onClick:()=>{u(!0)}},c.value.install):null,a(e,{style:{display:l.value?`block`:`none`},locales:i.locales,useHint:g.value,onCanInstall:e=>{d.value=e},onHint:()=>{y()},onClose:()=>u(!1)})])}});export{c as PwaInstall};
2
- //# sourceMappingURL=PwaInstall.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"PwaInstall.js","names":[],"sources":["../../../src/client/components/PwaInstall.ts"],"sourcesContent":["import { useLocale } from '@vuepress/helper/client'\nimport { useToggle } from '@vueuse/core'\nimport type { PropType, VNode } from 'vue'\nimport { computed, defineComponent, h, onMounted, ref } from 'vue'\nimport type { ManifestExternalApplicationResource } from '../../shared/index.js'\nimport type { PwaPluginLocaleConfig } from '../types.js'\nimport { PwaInstallModal } from './PwaInstallModal.js'\n\nimport '../styles/modal.css'\n\ninterface ModernNavigator extends Navigator {\n // Nonstandard Api\n getInstalledRelatedApps: () => Promise<ManifestExternalApplicationResource[]>\n}\n\ninterface SafariNavigator extends Navigator {\n // Available on Apple’s iOS Safari only.\n standalone: boolean\n}\n\nexport const PwaInstall = defineComponent({\n name: 'PwaInstall',\n\n props: {\n /** locale data */\n locales: {\n type: Object as PropType<PwaPluginLocaleConfig>,\n required: true,\n },\n },\n\n setup(props) {\n const locale = useLocale(props.locales)\n const [isOpen, toggleIsOpen] = useToggle()\n\n const canInstall = ref(false)\n const hasRelatedApps = ref(false)\n const isIOS = ref(false)\n const isSafari = ref(false)\n const hinted = ref(false)\n\n const useHint = computed(\n () => isIOS.value && isSafari.value && !hinted.value,\n )\n\n const showInstall = computed(\n () => (hasRelatedApps.value && canInstall.value) || useHint.value,\n )\n\n const getInstallStatus = (): boolean => {\n if ((navigator as SafariNavigator).standalone)\n return (navigator as SafariNavigator).standalone\n\n return matchMedia('(display-mode: standalone)').matches\n }\n\n const hint = (): void => {\n toggleIsOpen(false)\n hinted.value = true\n // do not notify again\n localStorage.setItem('iOS-pwa-hint', 'hinted')\n }\n\n onMounted(() => {\n if (getInstallStatus()) {\n const { userAgent } = navigator\n\n // handle iOS specifically\n isIOS.value =\n // regular iPhone\n userAgent.includes('iPhone') ||\n // regular iPad\n userAgent.includes('iPad') ||\n // iPad pro\n Boolean(\n userAgent.includes('Macintosh') &&\n navigator.maxTouchPoints &&\n navigator.maxTouchPoints > 2,\n )\n\n isSafari.value =\n navigator.userAgent.includes('Safari') &&\n !userAgent.includes('Chrome')\n\n hinted.value = Boolean(localStorage.getItem('iOS-pwa-hint'))\n }\n\n if ('getInstalledRelatedApps' in (navigator as ModernNavigator)) {\n void (navigator as ModernNavigator)\n .getInstalledRelatedApps()\n .then((result) => {\n hasRelatedApps.value = result.length > 0\n })\n }\n })\n\n return (): VNode =>\n h('div', { id: 'pwa-install' }, [\n showInstall.value\n ? h(\n 'button',\n {\n type: 'button',\n class: 'modal-button',\n onClick: () => {\n toggleIsOpen(true)\n },\n },\n locale.value.install,\n )\n : null,\n h(PwaInstallModal, {\n style: {\n display: isOpen.value ? 'block' : 'none',\n },\n locales: props.locales,\n useHint: useHint.value,\n onCanInstall: (value: boolean) => {\n canInstall.value = value\n },\n onHint: () => {\n hint()\n },\n onClose: () => toggleIsOpen(false),\n }),\n ])\n },\n})\n"],"mappings":"kQAoBA,MAAa,EAAa,EAAgB,CACxC,KAAM,aAEN,MAAO,CAEL,QAAS,CACP,KAAM,OACN,SAAU,GACX,CACF,CAED,MAAM,EAAO,CACX,IAAM,EAAS,EAAU,EAAM,QAAQ,CACjC,CAAC,EAAQ,GAAgB,GAAW,CAEpC,EAAa,EAAI,GAAM,CACvB,EAAiB,EAAI,GAAM,CAC3B,EAAQ,EAAI,GAAM,CAClB,EAAW,EAAI,GAAM,CACrB,EAAS,EAAI,GAAM,CAEnB,EAAU,MACR,EAAM,OAAS,EAAS,OAAS,CAAC,EAAO,MAChD,CAEK,EAAc,MACX,EAAe,OAAS,EAAW,OAAU,EAAQ,MAC7D,CAEK,MACC,UAA8B,WACzB,UAA8B,WAEjC,WAAW,6BAA6B,CAAC,QAG5C,MAAmB,CACvB,EAAa,GAAM,CACnB,EAAO,MAAQ,GAEf,aAAa,QAAQ,eAAgB,SAAS,EAoChD,OAjCA,MAAgB,CACd,GAAI,GAAkB,CAAE,CACtB,GAAM,CAAE,aAAc,UAGtB,EAAM,MAEJ,EAAU,SAAS,SAAS,EAE5B,EAAU,SAAS,OAAO,EAE1B,GACE,EAAU,SAAS,YAAY,EAC/B,UAAU,gBACV,UAAU,eAAiB,GAG/B,EAAS,MACP,UAAU,UAAU,SAAS,SAAS,EACtC,CAAC,EAAU,SAAS,SAAS,CAE/B,EAAO,MAAQ,EAAQ,aAAa,QAAQ,eAAe,CAGzD,4BAA8B,WAC1B,UACH,yBAAyB,CACzB,KAAM,GAAW,CAChB,EAAe,MAAQ,EAAO,OAAS,GACvC,EAEN,KAGA,EAAE,MAAO,CAAE,GAAI,cAAe,CAAE,CAC9B,EAAY,MACR,EACE,SACA,CACE,KAAM,SACN,MAAO,eACP,YAAe,CACb,EAAa,GAAK,EAErB,CACD,EAAO,MAAM,QACd,CACD,KACJ,EAAE,EAAiB,CACjB,MAAO,CACL,QAAS,EAAO,MAAQ,QAAU,OACnC,CACD,QAAS,EAAM,QACf,QAAS,EAAQ,MACjB,aAAe,GAAmB,CAChC,EAAW,MAAQ,GAErB,WAAc,CACZ,GAAM,EAER,YAAe,EAAa,GAAM,CACnC,CAAC,CACH,CAAC,EAEP,CAAC"}
@@ -1,2 +0,0 @@
1
- import{i as e}from"../../icons-RRw4DIWa.js";import{a as t}from"../../setupViewPoint-DS4c13mS.js";import{t as n}from"../../skipWaiting-wM8NHpWa.js";import{useLocale as r}from"@vuepress/helper/client";import{Transition as i,computed as a,defineComponent as o,h as s,onMounted as c,shallowRef as l}from"vue";import"@vuepress/helper/transition/fade-in-scale-up.css";import"../styles/popup.css";const u=o({name:`PwaReadyPopup`,props:{locales:{type:Object,required:!0}},slots:Object,setup(o,{slots:u}){let d=r(o.locales),f=l(),p=a(()=>!!f.value),m=()=>{f.value&&=(n(f.value),void 0)};return c(()=>{t().on(`updated`,e=>{f.value=e})}),()=>s(i,{name:`fade-in-scale-up`},()=>u.default?.({isReady:p.value,reload:m})??(p.value?s(`button`,{type:`button`,class:`sw-update-popup`,tabindex:0,onClick:()=>{m()}},[d.value.update,s(`span`,{class:`icon-wrapper`},s(e))]):null))}});export{u as PwaReadyPopup};
2
- //# sourceMappingURL=PwaReadyPopup.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"PwaReadyPopup.js","names":[],"sources":["../../../src/client/components/PwaReadyPopup.ts"],"sourcesContent":["import type { Slot } from '@vuepress/helper/client'\nimport { useLocale } from '@vuepress/helper/client'\nimport type { PropType, SlotsType, VNode } from 'vue'\nimport {\n Transition,\n computed,\n defineComponent,\n h,\n onMounted,\n shallowRef,\n} from 'vue'\nimport { usePwaEvent } from '../composables/index.js'\nimport type { PwaPluginLocaleConfig } from '../types.js'\nimport { skipWaiting } from '../utils/index.js'\nimport { UpdateIcon } from './icons.js'\n\nimport '@vuepress/helper/transition/fade-in-scale-up.css'\nimport '../styles/popup.css'\n\nexport const PwaReadyPopup = defineComponent({\n name: 'PwaReadyPopup',\n\n props: {\n /** locale data */\n locales: {\n type: Object as PropType<PwaPluginLocaleConfig>,\n required: true,\n },\n },\n\n slots: Object as SlotsType<{\n default?: Slot<{ isReady: boolean; reload: () => void }>\n }>,\n\n setup(props, { slots }) {\n const locale = useLocale(props.locales)\n const registration = shallowRef<ServiceWorkerRegistration>()\n\n const isReady = computed(() => Boolean(registration.value))\n\n const reload = (): void => {\n if (registration.value) {\n skipWaiting(registration.value)\n registration.value = undefined\n }\n }\n\n onMounted(() => {\n const event = usePwaEvent()\n\n event.on('updated', (reg) => {\n registration.value = reg\n })\n })\n\n return (): VNode =>\n h(\n Transition,\n { name: 'fade-in-scale-up' },\n () =>\n slots.default?.({\n isReady: isReady.value,\n reload,\n }) ??\n (isReady.value\n ? h(\n 'button',\n {\n type: 'button',\n class: 'sw-update-popup',\n tabindex: 0,\n onClick: () => {\n reload()\n },\n },\n [\n locale.value.update,\n h('span', { class: 'icon-wrapper' }, h(UpdateIcon)),\n ],\n )\n : null),\n )\n },\n})\n"],"mappings":"sYAmBA,MAAa,EAAgB,EAAgB,CAC3C,KAAM,gBAEN,MAAO,CAEL,QAAS,CACP,KAAM,OACN,SAAU,GACX,CACF,CAED,MAAO,OAIP,MAAM,EAAO,CAAE,SAAS,CACtB,IAAM,EAAS,EAAU,EAAM,QAAQ,CACjC,EAAe,GAAuC,CAEtD,EAAU,MAAe,EAAQ,EAAa,MAAO,CAErD,MAAqB,CACzB,AAEE,EAAa,SADb,EAAY,EAAa,MAAM,CACV,IAAA,KAYzB,OARA,MAAgB,CACA,GAAa,CAErB,GAAG,UAAY,GAAQ,CAC3B,EAAa,MAAQ,GACrB,EACF,KAGA,EACE,EACA,CAAE,KAAM,mBAAoB,KAE1B,EAAM,UAAU,CACd,QAAS,EAAQ,MACjB,SACD,CAAC,GACD,EAAQ,MACL,EACE,SACA,CACE,KAAM,SACN,MAAO,kBACP,SAAU,EACV,YAAe,CACb,GAAQ,EAEX,CACD,CACE,EAAO,MAAM,OACb,EAAE,OAAQ,CAAE,MAAO,eAAgB,CAAE,EAAE,EAAW,CAAC,CACpD,CACF,CACD,MACP,EAEN,CAAC"}
@@ -1 +0,0 @@
1
- import{a as e,i as t,n,r,t as i}from"../../setupViewPoint-DS4c13mS.js";export{t as pwaEventSymbol,n as setupPwa,i as setupViewPoint,e as usePwaEvent,r as useRegisterSW};
@@ -1,2 +0,0 @@
1
- import{PwaInstall as e}from"./components/PwaInstall.js";import{a as t,i as n,n as r,o as i,r as a,s as o,t as s}from"../setupViewPoint-DS4c13mS.js";import{t as c}from"../skipWaiting-wM8NHpWa.js";import{PwaFoundPopup as l}from"./components/PwaFoundPopup.js";import{PwaReadyPopup as u}from"./components/PwaReadyPopup.js";const d=async()=>{try{let e=await navigator.serviceWorker.getRegistration();if(e){let t=await e.unregister();return t&&console.log(`[PWA] Current service worker unregistered`),t}}catch(e){console.error(`[PWA] Unregister current service worker failed with error:`,e)}return!1};export{l as PwaFoundPopup,e as PwaInstall,u as PwaReadyPopup,o as forceUpdate,n as pwaEventSymbol,i as registerSW,r as setupPwa,s as setupViewPoint,c as skipWaiting,d as unregisterSW,t as usePwaEvent,a as useRegisterSW};
2
- //# sourceMappingURL=index.js.map
@@ -1,2 +0,0 @@
1
- import{inject as e,onMounted as t,provide as n}from"vue";import{withBase as r}from"vuepress/client";import i from"mitt";const a=()=>{navigator.serviceWorker.getRegistration().then(e=>{e?.active&&e.addEventListener(`updatefound`,()=>{window.location.reload(!0)})})},o=async(e,t={},n=!0)=>{let{register:r}=await import(`register-service-worker`);r(e,{ready(e){n&&console.info(`[Service Worker]: active`),t.ready?.(e)},registered(e){n&&console.log(`[Service Worker]: registered`),t.registered?.(e)},cached(e){n&&console.log(`[Service Worker]: cached`),t.cached?.(e)},updatefound(e){n&&console.log(`[Service Worker]: update found`),t.updatefound?.(e)},updated(e){n&&console.log(`[Service Worker]: updated`),t.updated?.(e)},offline(){n&&console.log(`[Service Worker]: offline`),t.offline?.()},error(e){n&&console.error(`[Service Worker]:`,e),t.error?.(e)}})},s=Symbol(__VUEPRESS_DEV__?`PwaEvent`:``),c=()=>{let t=e(s);if(!t)throw Error(`usePwaEvent() is called without provider.`);return t},l=async(e,t)=>o(r(e),{ready(e){t.emit(`ready`,e)},registered(e){t.emit(`registered`,e)},cached(e){t.emit(`cached`,e)},updatefound(e){t.emit(`updatefound`,e)},updated(e){let n=`service-worker-version`,r=Number(localStorage.getItem(n)||0);localStorage.setItem(n,(r+1).toString()),localStorage.removeItem(`manifest`),t.emit(`updated`,e)},offline(){t.emit(`offline`)},error(e){t.emit(`error`,e)}}),u=(e,r=!1)=>{if(__VUEPRESS_SSR__)return;let o=i();n(s,o),t(async()=>{if(__VUEPRESS_DEV__||!(`serviceWorker`in navigator))return;let t=!1;navigator.serviceWorker.controller&&navigator.serviceWorker.addEventListener(`controllerchange`,()=>{t||(t=!0,window.location.reload())}),r&&a(),await l(e,o)})},d=()=>{t(()=>{if(window.matchMedia(`(display-mode: standalone)`).matches){let e=document.head.querySelector(`meta[name="viewport"]`);if(e){e.setAttribute(`content`,`width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover`);return}let t=document.createElement(`meta`);t.name=`viewport`,t.content=`width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover`,document.head.append(t)}})};export{c as a,s as i,u as n,o,l as r,a as s,d as t};
2
- //# sourceMappingURL=setupViewPoint-DS4c13mS.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"setupViewPoint-DS4c13mS.js","names":[],"sources":["../src/client/utils/forceUpdate.ts","../src/client/utils/registerSW.ts","../src/client/composables/usePwaEvent.ts","../src/client/composables/useRegisterSW.ts","../src/client/composables/setupPwa.ts","../src/client/composables/setupViewPoint.ts"],"sourcesContent":["/**\n * Force update page content\n *\n * 强制更新页面内容\n */\nexport const forceUpdate = (): void => {\n void navigator.serviceWorker.getRegistration().then((registration) => {\n // Check whether a valid service worker is active\n if (registration?.active) {\n registration.addEventListener('updatefound', () => {\n // force refresh\n // @ts-expect-error: A non-standard API\n window.location.reload(true)\n })\n }\n })\n}\n","/* eslint-disable no-console */\nimport type { Hooks } from 'register-service-worker'\n\n/**\n * Register serviceWorker under `serviceWorkerPath`\n *\n * 在 `serviceWorkerPath` 下注册 Service Worker\n *\n * @param serviceWorkerPath - Service Worker path / Service Worker 路径\n * @param hooks - Service worker hooks / Service Worker 钩子\n * @param showStatus - Whether to show status in console / 是否在控制台显示状态\n */\nexport const registerSW = async (\n serviceWorkerPath: string,\n hooks: Hooks = {},\n showStatus = true,\n): Promise<void> => {\n const { register } = await import(\n /* webpackChunkName: \"register-service-worker\" */ 'register-service-worker'\n )\n\n // Register service worker\n register(serviceWorkerPath, {\n ready(registration) {\n if (showStatus) console.info('[Service Worker]: active')\n hooks.ready?.(registration)\n },\n\n registered(registration) {\n if (showStatus) console.log('[Service Worker]: registered')\n hooks.registered?.(registration)\n },\n\n cached(registration) {\n if (showStatus) console.log('[Service Worker]: cached')\n hooks.cached?.(registration)\n },\n\n updatefound(registration) {\n if (showStatus) console.log('[Service Worker]: update found')\n hooks.updatefound?.(registration)\n },\n\n updated(registration) {\n if (showStatus) console.log('[Service Worker]: updated')\n hooks.updated?.(registration)\n },\n\n offline() {\n if (showStatus) console.log('[Service Worker]: offline')\n hooks.offline?.()\n },\n\n error(err) {\n if (showStatus) console.error('[Service Worker]:', err)\n hooks.error?.(err)\n },\n })\n}\n","import type { Emitter } from 'mitt'\nimport type { InjectionKey } from 'vue'\nimport { inject } from 'vue'\n\ndeclare const __VUEPRESS_DEV__: boolean\n\nexport type PwaEvent = Emitter<{\n ready: ServiceWorkerRegistration\n registered: ServiceWorkerRegistration\n cached: ServiceWorkerRegistration\n updatefound: ServiceWorkerRegistration\n updated: ServiceWorkerRegistration\n offline: void\n error: Error\n}>\n\nexport const pwaEventSymbol: InjectionKey<PwaEvent> = Symbol(\n __VUEPRESS_DEV__ ? 'PwaEvent' : '',\n)\n\n/**\n * Use PWA event emitter\n *\n * 使用 PWA 事件发射器\n *\n * @returns PWA event emitter / PWA 事件发射器\n */\nexport const usePwaEvent = (): PwaEvent => {\n const pwaEvent = inject(pwaEventSymbol)\n\n if (!pwaEvent) throw new Error('usePwaEvent() is called without provider.')\n\n return pwaEvent\n}\n","import { withBase } from 'vuepress/client'\nimport { registerSW } from '../utils/index.js'\nimport type { PwaEvent } from './usePwaEvent.js'\n\n/**\n * Register service worker with event emitter\n *\n * 使用事件发射器注册 Service Worker\n *\n * @param serviceWorkerPath - Service Worker path / Service Worker 路径\n * @param event - PWA event emitter / PWA 事件发射器\n */\nexport const useRegisterSW = async (\n serviceWorkerPath: string,\n event: PwaEvent,\n): Promise<void> =>\n registerSW(withBase(serviceWorkerPath), {\n ready(registration) {\n event.emit('ready', registration)\n },\n\n registered(registration) {\n event.emit('registered', registration)\n },\n\n cached(registration) {\n event.emit('cached', registration)\n },\n\n updatefound(registration) {\n event.emit('updatefound', registration)\n },\n\n updated(registration) {\n const key = 'service-worker-version'\n const version = Number(localStorage.getItem(key) || 0)\n\n localStorage.setItem(key, (version + 1).toString())\n localStorage.removeItem('manifest')\n\n event.emit('updated', registration)\n },\n\n offline() {\n event.emit('offline')\n },\n\n error(err) {\n event.emit('error', err)\n },\n })\n","import mitt from 'mitt'\nimport { onMounted, provide } from 'vue'\nimport { forceUpdate } from '../utils/index.js'\nimport { pwaEventSymbol } from './usePwaEvent.js'\nimport { useRegisterSW } from './useRegisterSW.js'\nimport type { PwaEvent } from './index.js'\n\n/**\n * Setup PWA functionality\n *\n * 设置 PWA 功能\n *\n * @param serviceWorkerPath - Service Worker path / Service Worker 路径\n * @param shouldForceUpdate - Whether to force update / 是否强制更新\n */\nexport const setupPwa = (\n serviceWorkerPath: string,\n shouldForceUpdate = false,\n): void => {\n if (__VUEPRESS_SSR__) return\n\n // Create event emitter and provide it\n const event: PwaEvent = mitt()\n\n provide(pwaEventSymbol, event)\n\n onMounted(async () => {\n if (__VUEPRESS_DEV__ || !('serviceWorker' in navigator)) return\n\n let refreshing = false\n\n // Only listen controllerchange event when a serviceWorker is active\n if (navigator.serviceWorker.controller) {\n navigator.serviceWorker.addEventListener('controllerchange', () => {\n if (refreshing) return\n\n refreshing = true\n window.location.reload()\n })\n }\n\n if (shouldForceUpdate) forceUpdate()\n\n await useRegisterSW(serviceWorkerPath, event)\n })\n}\n","import { onMounted } from 'vue'\n\n/**\n * Setup viewport for PWA standalone mode\n *\n * 为 PWA 独立模式设置视口\n */\nexport const setupViewPoint = (): void => {\n onMounted(() => {\n const isStandAlone = window.matchMedia('(display-mode: standalone)').matches\n\n if (isStandAlone) {\n const head = document.head.querySelector('meta[name=\"viewport\"]')\n\n if (head) {\n head.setAttribute(\n 'content',\n 'width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover',\n )\n return\n }\n\n const viewportMeta = document.createElement('meta')\n\n viewportMeta.name = 'viewport'\n viewportMeta.content =\n 'width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover'\n\n document.head.append(viewportMeta)\n }\n })\n}\n"],"mappings":"wHAKA,MAAa,MAA0B,CAChC,UAAU,cAAc,iBAAiB,CAAC,KAAM,GAAiB,CAEhE,GAAc,QAChB,EAAa,iBAAiB,kBAAqB,CAGjD,OAAO,SAAS,OAAO,GAAK,EAC5B,EAEJ,ECHS,EAAa,MACxB,EACA,EAAe,EAAE,CACjB,EAAa,KACK,CAClB,GAAM,CAAE,YAAa,MAAM,OACyB,2BAIpD,EAAS,EAAmB,CAC1B,MAAM,EAAc,CACd,GAAY,QAAQ,KAAK,2BAA2B,CACxD,EAAM,QAAQ,EAAa,EAG7B,WAAW,EAAc,CACnB,GAAY,QAAQ,IAAI,+BAA+B,CAC3D,EAAM,aAAa,EAAa,EAGlC,OAAO,EAAc,CACf,GAAY,QAAQ,IAAI,2BAA2B,CACvD,EAAM,SAAS,EAAa,EAG9B,YAAY,EAAc,CACpB,GAAY,QAAQ,IAAI,iCAAiC,CAC7D,EAAM,cAAc,EAAa,EAGnC,QAAQ,EAAc,CAChB,GAAY,QAAQ,IAAI,4BAA4B,CACxD,EAAM,UAAU,EAAa,EAG/B,SAAU,CACJ,GAAY,QAAQ,IAAI,4BAA4B,CACxD,EAAM,WAAW,EAGnB,MAAM,EAAK,CACL,GAAY,QAAQ,MAAM,oBAAqB,EAAI,CACvD,EAAM,QAAQ,EAAI,EAErB,CAAC,ECzCS,EAAyC,OACpD,iBAAmB,WAAa,GACjC,CASY,MAA8B,CACzC,IAAM,EAAW,EAAO,EAAe,CAEvC,GAAI,CAAC,EAAU,MAAU,MAAM,4CAA4C,CAE3E,OAAO,GCpBI,EAAgB,MAC3B,EACA,IAEA,EAAW,EAAS,EAAkB,CAAE,CACtC,MAAM,EAAc,CAClB,EAAM,KAAK,QAAS,EAAa,EAGnC,WAAW,EAAc,CACvB,EAAM,KAAK,aAAc,EAAa,EAGxC,OAAO,EAAc,CACnB,EAAM,KAAK,SAAU,EAAa,EAGpC,YAAY,EAAc,CACxB,EAAM,KAAK,cAAe,EAAa,EAGzC,QAAQ,EAAc,CACpB,IAAM,EAAM,yBACN,EAAU,OAAO,aAAa,QAAQ,EAAI,EAAI,EAAE,CAEtD,aAAa,QAAQ,GAAM,EAAU,GAAG,UAAU,CAAC,CACnD,aAAa,WAAW,WAAW,CAEnC,EAAM,KAAK,UAAW,EAAa,EAGrC,SAAU,CACR,EAAM,KAAK,UAAU,EAGvB,MAAM,EAAK,CACT,EAAM,KAAK,QAAS,EAAI,EAE3B,CAAC,CCnCS,GACX,EACA,EAAoB,KACX,CACT,GAAI,iBAAkB,OAGtB,IAAM,EAAkB,GAAM,CAE9B,EAAQ,EAAgB,EAAM,CAE9B,EAAU,SAAY,CACpB,GAAI,kBAAoB,EAAE,kBAAmB,WAAY,OAEzD,IAAI,EAAa,GAGb,UAAU,cAAc,YAC1B,UAAU,cAAc,iBAAiB,uBAA0B,CAC7D,IAEJ,EAAa,GACb,OAAO,SAAS,QAAQ,GACxB,CAGA,GAAmB,GAAa,CAEpC,MAAM,EAAc,EAAmB,EAAM,EAC7C,ECrCS,MAA6B,CACxC,MAAgB,CAGd,GAFqB,OAAO,WAAW,6BAA6B,CAAC,QAEnD,CAChB,IAAM,EAAO,SAAS,KAAK,cAAc,wBAAwB,CAEjE,GAAI,EAAM,CACR,EAAK,aACH,UACA,iGACD,CACD,OAGF,IAAM,EAAe,SAAS,cAAc,OAAO,CAEnD,EAAa,KAAO,WACpB,EAAa,QACX,iGAEF,SAAS,KAAK,OAAO,EAAa,GAEpC"}
@@ -1,2 +0,0 @@
1
- const e=e=>{let t=e.waiting;if(!t)return;let n=new MessageChannel;t.postMessage({type:`SKIP_WAITING`},[n.port2])};export{e as t};
2
- //# sourceMappingURL=skipWaiting-wM8NHpWa.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"skipWaiting-wM8NHpWa.js","names":[],"sources":["../src/client/utils/skipWaiting.ts"],"sourcesContent":["/**\n * Call `skipWaiting()` inside current waiting worker\n *\n * 在当前等待中的 Service Worker 中调用 `skipWaiting()`\n *\n * @param registration - The registration of the service worker you want activate / 想要激活的 Service Worker 的注册\n */\nexport const skipWaiting = (registration: ServiceWorkerRegistration): void => {\n // Get the waiting worker\n const worker = registration.waiting\n\n // If there is no waiting worker, return directly\n if (!worker) return\n\n // Post SKIP_WAITING message to the waiting worker\n const channel = new MessageChannel()\n\n worker.postMessage({ type: 'SKIP_WAITING' }, [channel.port2])\n}\n"],"mappings":"AAOA,MAAa,EAAe,GAAkD,CAE5E,IAAM,EAAS,EAAa,QAG5B,GAAI,CAAC,EAAQ,OAGb,IAAM,EAAU,IAAI,eAEpB,EAAO,YAAY,CAAE,KAAM,eAAgB,CAAE,CAAC,EAAQ,MAAM,CAAC"}
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes