From ab2e138baedf7114c49c8ecca244326341659d37 Mon Sep 17 00:00:00 2001 From: VChet <17050347+VChet@users.noreply.github.com> Date: Wed, 5 Jul 2023 23:37:47 +0400 Subject: [PATCH] WIP: feat: add periodicSync service --- env.d.ts | 21 +++++++++++++++++++++ src/services/periodicSync.ts | 28 ++++++++++++++++++++++++++++ src/sw.ts | 6 ++++++ 3 files changed, 55 insertions(+) create mode 100644 src/services/periodicSync.ts diff --git a/env.d.ts b/env.d.ts index 7b6bc20..0e3f63d 100644 --- a/env.d.ts +++ b/env.d.ts @@ -8,3 +8,24 @@ interface ImportMetaEnv { interface ImportMeta { readonly env: ImportMetaEnv } + +interface SyncManager { + register: (tag: string, options?: { minInterval: number }) => Promise + unregister: (tag: string) => Promise + getTags: (() => Promise) & (() => Promise) +} + +interface ServiceWorkerRegistration { + readonly sync: SyncManager + readonly periodicSync: SyncManager +} + +interface SyncEvent extends ExtendableEvent { + readonly lastChance: boolean + readonly tag: string +} + +interface ServiceWorkerGlobalScopeEventMap { + sync: SyncEvent + periodicSync: SyncEvent +} diff --git a/src/services/periodicSync.ts b/src/services/periodicSync.ts new file mode 100644 index 0000000..8abef28 --- /dev/null +++ b/src/services/periodicSync.ts @@ -0,0 +1,28 @@ +import { ref } from "vue"; + +const MIN_INTERVAL = 24 * 60 * 60 * 1000; +const registration = ref(null); + +async function isActive(tag: string) { + if (!registration.value) registration.value = await navigator.serviceWorker.ready; + const tags: string[] = await registration.value.periodicSync.getTags(); + return tags.includes(tag); +} + +async function register(tag: string, minInterval = MIN_INTERVAL) { + if (!registration.value) registration.value = await navigator.serviceWorker.ready; + return registration.value.periodicSync.register(tag, { minInterval }); +} + +async function unregister(tag: string) { + if (!registration.value) registration.value = await navigator.serviceWorker.ready; + return registration.value.periodicSync.unregister(tag); +} + +export function usePeriodicSync(tag: string) { + return { + isActive: () => isActive(tag), + register: () => register(tag), + unregister: () => unregister(tag) + }; +} diff --git a/src/sw.ts b/src/sw.ts index 2249bfc..eeb00cd 100644 --- a/src/sw.ts +++ b/src/sw.ts @@ -1,3 +1,4 @@ +import dayjs from "dayjs"; import { cleanupOutdatedCaches, createHandlerBoundToURL, precacheAndRoute } from "workbox-precaching"; import { NavigationRoute, registerRoute } from "workbox-routing"; import { CacheFirst } from "workbox-strategies"; @@ -8,6 +9,11 @@ self.addEventListener("message", (event) => { if (event.data && event.data.type === "SKIP_WAITING") self.skipWaiting(); }); +self.addEventListener("periodicsync", (event) => { + const promiseChain = self.registration.showNotification(`${dayjs().format("dddd HH:mm:ss")} Test`); + (event as ExtendableEvent).waitUntil(promiseChain); +}); + // self.__WB_MANIFEST is default injection point precacheAndRoute(self.__WB_MANIFEST);