PageSourceSearch

https://www.thelight.com.au/just-pray-sw.js

js thelight.com.au collected 2026-10-02 18:23:36 UTC 3,350 bytes, 89 lines download raw bytes

1const CACHE_NAME = 'just-pray-v3'
2const CAMPAIGN_PATH = '/come-pray'
3
4self.addEventListener('install', () => {
5    self.skipWaiting()
6})
7
8self.addEventListener('activate', (event) => {
9    event.waitUntil(
10        caches
11            .keys()
12            .then((keys) =>
13                Promise.all(
14                    keys
15                        .filter((key) => key.startsWith('just-pray-') && key !== CACHE_NAME)
16                        .map((key) => caches.delete(key))
17                )
18            )
19            .then(() => self.clients.claim())
20    )
21})
22
23self.addEventListener('fetch', (event) => {
24    if (event.request.method !== 'GET') return
25
26    const url = new URL(event.request.url)
27    const isCampaignPage = url.origin === self.location.origin && (url.pathname === CAMPAIGN_PATH || url.pathname === '/just-pray')
28    const isDailyContent =
29        url.origin === self.location.origin &&
30        url.pathname.startsWith('/api/just-pray/day/')
31
32    if (!isCampaignPage && !isDailyContent) return
33
34    event.respondWith(
35        fetch(event.request)
36            .then((response) => {
37                if (response.ok) {
38                    const copy = response.clone()
39                    caches.open(CACHE_NAME).then((cache) => cache.put(event.request, copy))
40                }
41                return response
42            })
43            .catch(async () => {
44                const cached = await caches.match(event.request)
45                if (cached) return cached
46
47                if (isCampaignPage) {
48                    return new Response(
49                        '<!doctype html><html lang="en"><meta name="viewport" content="width=device-width"><title>Come Pray</title><body style="font:18px system-ui;padding:40px;color:#12324a"><h1>Come Pray</h1><p>You are offline. Reconnect to open the campaign, or return to a prayer day you have opened before.</p></body></html>',
50                        { headers: { 'Content-Type': 'text/html' } }
51                    )
52                }
53
54                return new Response(JSON.stringify({ error: 'This day is not available offline yet.' }), {
55                    status: 503,
56                    headers: { 'Content-Type': 'application/json' },
57                })
58            })
59    )
60})
61
62self.addEventListener('push', (event) => {
63    const data = event.data?.json() || {}
64    event.waitUntil(
65        self.registration.showNotification(data.title || 'Come Pray', {
66            body: data.body || 'Take one minute to pray before your day begins.',
67            icon: '/thelight-logo.png',
68            badge: '/thelight-logo.png',
69            tag: data.tag || 'just-pray-reminder',
70            data: { url: data.url || CAMPAIGN_PATH },
71            renotify: false,
72        })
73    )
74})
75
76self.addEventListener('notificationclick', (event) => {
77    event.notification.close()
78    const target = new URL(event.notification.data?.url || CAMPAIGN_PATH, self.location.origin).href
79    event.waitUntil(
80        self.clients.matchAll({ type: 'window', includeUncontrolled: true }).then((clients) => {
81            const existing = clients.find((client) => client.url.startsWith(self.location.origin))
82            if (existing) {
83                existing.navigate(target)
84                return existing.focus()
85            }
86            return self.clients.openWindow(target)
87        })
88    )
89})

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.