mirror of
https://github.com/wu736139669/hapi.git
synced 2026-08-05 06:24:37 +00:00
Implement push notification system with VAPID keys, client service worker integration, and push subscription management. Includes server-side PushService for sending notifications and PushNotifier for reactive event handling, plus client-side usePushNotifications hook and service worker support.
124 lines
2.9 KiB
TypeScript
124 lines
2.9 KiB
TypeScript
/// <reference lib="webworker" />
|
|
import { precacheAndRoute } from 'workbox-precaching'
|
|
import { registerRoute } from 'workbox-routing'
|
|
import { CacheFirst, NetworkFirst } from 'workbox-strategies'
|
|
import { ExpirationPlugin } from 'workbox-expiration'
|
|
|
|
declare const self: ServiceWorkerGlobalScope & {
|
|
__WB_MANIFEST: Array<string | { url: string; revision?: string }>
|
|
}
|
|
|
|
type PushPayload = {
|
|
title: string
|
|
body?: string
|
|
icon?: string
|
|
badge?: string
|
|
tag?: string
|
|
data?: {
|
|
type?: string
|
|
sessionId?: string
|
|
url?: string
|
|
}
|
|
}
|
|
|
|
precacheAndRoute(self.__WB_MANIFEST)
|
|
|
|
registerRoute(
|
|
({ url }) => url.pathname === '/api/sessions',
|
|
new NetworkFirst({
|
|
cacheName: 'api-sessions',
|
|
networkTimeoutSeconds: 10,
|
|
plugins: [
|
|
new ExpirationPlugin({
|
|
maxEntries: 10,
|
|
maxAgeSeconds: 60 * 5
|
|
})
|
|
]
|
|
})
|
|
)
|
|
|
|
registerRoute(
|
|
({ url }) => /^\/api\/sessions\/[^/]+$/.test(url.pathname),
|
|
new NetworkFirst({
|
|
cacheName: 'api-session-detail',
|
|
networkTimeoutSeconds: 10,
|
|
plugins: [
|
|
new ExpirationPlugin({
|
|
maxEntries: 20,
|
|
maxAgeSeconds: 60 * 5
|
|
})
|
|
]
|
|
})
|
|
)
|
|
|
|
registerRoute(
|
|
({ url }) => url.pathname === '/api/machines',
|
|
new NetworkFirst({
|
|
cacheName: 'api-machines',
|
|
networkTimeoutSeconds: 10,
|
|
plugins: [
|
|
new ExpirationPlugin({
|
|
maxEntries: 5,
|
|
maxAgeSeconds: 60 * 10
|
|
})
|
|
]
|
|
})
|
|
)
|
|
|
|
registerRoute(
|
|
/^https:\/\/cdn\.socket\.io\/.*/,
|
|
new CacheFirst({
|
|
cacheName: 'cdn-socketio',
|
|
plugins: [
|
|
new ExpirationPlugin({
|
|
maxEntries: 5,
|
|
maxAgeSeconds: 60 * 60 * 24 * 30
|
|
})
|
|
]
|
|
})
|
|
)
|
|
|
|
registerRoute(
|
|
/^https:\/\/telegram\.org\/.*/,
|
|
new CacheFirst({
|
|
cacheName: 'cdn-telegram',
|
|
plugins: [
|
|
new ExpirationPlugin({
|
|
maxEntries: 5,
|
|
maxAgeSeconds: 60 * 60 * 24 * 7
|
|
})
|
|
]
|
|
})
|
|
)
|
|
|
|
self.addEventListener('push', (event) => {
|
|
const payload = event.data?.json() as PushPayload | undefined
|
|
if (!payload) {
|
|
return
|
|
}
|
|
|
|
const title = payload.title || 'HAPI'
|
|
const body = payload.body ?? ''
|
|
const icon = payload.icon ?? '/pwa-192x192.png'
|
|
const badge = payload.badge ?? '/pwa-64x64.png'
|
|
const data = payload.data
|
|
const tag = payload.tag
|
|
|
|
event.waitUntil(
|
|
self.registration.showNotification(title, {
|
|
body,
|
|
icon,
|
|
badge,
|
|
data,
|
|
tag
|
|
})
|
|
)
|
|
})
|
|
|
|
self.addEventListener('notificationclick', (event) => {
|
|
event.notification.close()
|
|
const data = event.notification.data as { url?: string } | undefined
|
|
const url = data?.url ?? '/'
|
|
event.waitUntil(self.clients.openWindow(url))
|
|
})
|