import Dexie, { EntityTable } from "dexie" import urlB64ToUint8Array from "../b64ToUInt8" import pushPublicKey from "../pushPublicKey" interface SubscriptionRecord { id: number subscriptionId: number } export default function start(self: ServiceWorkerGlobalScope) { self.addEventListener("install", (event) => { event.waitUntil(self.skipWaiting()) }) self.addEventListener("activate", (event) => { event.waitUntil(self.clients.claim()) }) // self.addEventListener("push", function (event: PushEvent) { // console.log("[Service Worker] Push Received.") // console.log(`[Service Worker] Push had this data: "${event.data?.text()}"`) // const title = "Push Codelab" // const options = { // body: "Yay it works.", // icon: "images/icon.png", // badge: "images/badge.png", // } // event.waitUntil(self.registration.showNotification(title, options)) // }) // self.addEventListener("notificationclick", function (event) { // console.log("[Service Worker] Notification click Received.") // event.notification.close() // event.waitUntil( // self.clients.openWindow("https://developers.google.com/web/") // ) // }) self.addEventListener("message", function (event) { const waitEvent = event as ExtendableEvent if ("type" in event.data && event.data.type === "subscribed") { waitEvent.waitUntil(submitSubscription(event.data.subscription)) } }) self.addEventListener("pushsubscriptionchange", function (event) { const waitEvent = event as ExtendableEvent waitEvent.waitUntil( (async () => { const applicationServerKey = urlB64ToUint8Array(pushPublicKey) const newSubscription = await self.registration.pushManager.subscribe({ userVisibleOnly: true, applicationServerKey: applicationServerKey, }) await submitSubscription(newSubscription.toJSON()) })() ) }) } async function submitSubscription(subscription: PushSubscriptionJSON) { const db = database() const existingSubscriptionId = await db.subscriptions.get(1) await (existingSubscriptionId === undefined ? postSubscription(subscription, db) : putSubscription(subscription, existingSubscriptionId.subscriptionId)) } async function postSubscription( subscription: PushSubscriptionJSON, db: ReturnType ) { const response = await fetch(`${process.env.BASE_URL}/api/subscription/`, { method: "POST", body: JSON.stringify(subscription), headers: { "Content-Type": "application/json", }, }) db.subscriptions.put({ id: 1, subscriptionId: (await response.json()).subscriptionId, }) } function putSubscription(subscription: PushSubscriptionJSON, id: number) { return fetch(`${process.env.BASE_URL}/api/subscription/${id}`, { method: "PUT", body: JSON.stringify(subscription), headers: { "Content-Type": "application/json", }, }) } function database() { const db = new Dexie("tack-up-now", { indexedDB }) as Dexie & { subscriptions: EntityTable } db.version(1).stores({ subscriptions: "id++, subscriptionId&" }) return db }