225 lines
5.7 KiB
TypeScript
225 lines
5.7 KiB
TypeScript
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/")
|
|
// )
|
|
// })
|
|
|
|
async function sendMessage(message: any) {
|
|
const clients = await self.clients.matchAll()
|
|
|
|
await Promise.all(
|
|
clients.map(async (client) => client.postMessage(message))
|
|
)
|
|
}
|
|
|
|
self.addEventListener("message", function (event) {
|
|
const waitEvent = event as ExtendableEvent
|
|
waitEvent.waitUntil(
|
|
(async () => {
|
|
await sendMessage({
|
|
message: "Got message",
|
|
data: event.data,
|
|
})
|
|
|
|
if (
|
|
"type" in event.data &&
|
|
event.data.type === "subscribed" &&
|
|
"subscription" in event.data
|
|
) {
|
|
try {
|
|
await event.waitUntil(
|
|
submitSubscription(
|
|
self.registration,
|
|
event.data.subscription as PushSubscription
|
|
)
|
|
)
|
|
} catch (e) {
|
|
await sendMessage({
|
|
message: "Got error processing subscription",
|
|
error: (e as Error).toString(),
|
|
})
|
|
}
|
|
}
|
|
|
|
await sendMessage({
|
|
message: "Processed subscription",
|
|
})
|
|
})()
|
|
)
|
|
})
|
|
|
|
self.addEventListener("pushsubscriptionchange", function (event) {
|
|
const waitEvent = event as ExtendableEvent
|
|
|
|
waitEvent.waitUntil(
|
|
(async () => {
|
|
const existingSubscription =
|
|
await self.registration.pushManager.getSubscription()
|
|
const newSubscription = await submitSubscription(
|
|
self.registration,
|
|
existingSubscription
|
|
)
|
|
|
|
await sendMessage({ type: "sent subscription", newSubscription })
|
|
})()
|
|
)
|
|
})
|
|
|
|
async function submitSubscription(
|
|
registration: ServiceWorkerRegistration,
|
|
subscription: PushSubscription | null
|
|
) {
|
|
const db = database()
|
|
|
|
await sendMessage({
|
|
message: `Is subscription null? ${subscription === null}`,
|
|
})
|
|
|
|
if (subscription === null) return
|
|
|
|
const existingSubscriptionId = await db.subscriptions.get(1)
|
|
|
|
await sendMessage({
|
|
message: `Existing subscription ID ${existingSubscriptionId}`,
|
|
})
|
|
|
|
await sendMessage({
|
|
message: `pushPublicKey ${pushPublicKey}`,
|
|
})
|
|
|
|
let applicationServerKey
|
|
try {
|
|
applicationServerKey = urlB64ToUint8Array(pushPublicKey)
|
|
} catch (error) {
|
|
await sendMessage({
|
|
message: `B64 error ${(error as Error).toString()}`,
|
|
})
|
|
}
|
|
|
|
await sendMessage({
|
|
message: `Converted public key`,
|
|
})
|
|
const newSubscription = await registration.pushManager.subscribe({
|
|
userVisibleOnly: true,
|
|
applicationServerKey: applicationServerKey,
|
|
})
|
|
|
|
await sendMessage({
|
|
message: `subscribed via pushManager`,
|
|
})
|
|
|
|
const stupid =
|
|
existingSubscriptionId === undefined
|
|
? postSubscription(newSubscription.toJSON(), db)
|
|
: putSubscription(
|
|
newSubscription.toJSON(),
|
|
existingSubscriptionId.subscriptionId
|
|
)
|
|
await stupid
|
|
|
|
return newSubscription
|
|
}
|
|
|
|
async function postSubscription(
|
|
subscription: PushSubscriptionJSON,
|
|
db: ReturnType<typeof database>
|
|
) {
|
|
await sendMessage({
|
|
message: "Log something you piece of garbage",
|
|
})
|
|
|
|
try {
|
|
await sendMessage({
|
|
message: `URL ${process.env.BASE_URL}/api/subscription/`,
|
|
})
|
|
|
|
await sendMessage({
|
|
message: `Submitting subscription ${subscription}`,
|
|
})
|
|
|
|
await sendMessage({
|
|
message: `JSON formatted: ${JSON.stringify(subscription)}`,
|
|
})
|
|
|
|
const response = await fetch(
|
|
`${process.env.BASE_URL}/api/subscription/`,
|
|
{
|
|
method: "POST",
|
|
body: JSON.stringify(subscription),
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
},
|
|
}
|
|
)
|
|
|
|
await sendMessage({
|
|
message: `Response status ${response.status}`,
|
|
})
|
|
db.subscriptions.put({
|
|
id: 1,
|
|
subscriptionId: (await response.json()).subscriptionId,
|
|
})
|
|
} catch (error) {
|
|
await sendMessage({
|
|
message: `ERRRROR ${(error as Error).toString()}}`,
|
|
})
|
|
}
|
|
}
|
|
|
|
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<SubscriptionRecord, "id">
|
|
}
|
|
|
|
db.version(1).stores({ subscriptions: "id++, subscriptionId&" })
|
|
|
|
return db
|
|
}
|