PageSourceSearch

https://web-production-89794.up.railway.app/portal-sw.js

js web-production-89794.up.railway.app collected 2026-10-03 12:16:38 UTC 2,850 bytes, 83 lines download raw bytes

1/*
2 * Anahuac RV Park — Portal Service Worker
3 * Handles push notifications, notification clicks, and app badge updates.
4 */
5
6var CACHE_VERSION = 'portal-v14';
7
8self.addEventListener('install', () => { self.skipWaiting(); });
9self.addEventListener('activate', (event) => {
10  event.waitUntil(
11    Promise.all([
12      // Delete old portal caches only (don't touch admin's rvpark-* caches)
13      caches.keys().then(function(keys) {
14        return Promise.all(keys.filter(function(k) { return k !== CACHE_VERSION && k.startsWith('portal-'); }).map(function(k) { return caches.delete(k); }));
15      }),
16      self.clients.claim()
17    ])
18  );
19});
20
21// Never cache HTML or API — always fetch fresh
22self.addEventListener('fetch', (event) => {
23  var url = new URL(event.request.url);
24  if (url.pathname.endsWith('.html') || url.pathname.startsWith('/api/') || url.pathname === '/portal') {
25    return; // Let the browser handle normally (network only)
26  }
27  // Self-destruct kill switch
28  if (url.searchParams.has('_nuke_sw')) {
29    event.respondWith(
30      self.registration.unregister().then(function() { return caches.keys(); }).then(function(keys) { return Promise.all(keys.map(function(k) { return caches.delete(k); })); }).then(function() { return fetch(event.request); })
31    );
32    return;
33  }
34  // All other requests: default browser behavior (no custom caching)
35});
36
37// Push notification handler
38self.addEventListener('push', (event) => {
39  if (!event.data) return;
40
41  let data;
42  try { data = event.data.json(); } catch { return; }
43
44  const options = {
45    body: data.body || '',
46    icon: data.icon || '/icons/icon-192x192.png',
47    badge: '/icons/favicon-32x32.png',
48    tag: data.tag || 'general',
49    data: { url: data.url || '/portal' },
50    requireInteraction: data.priority === 'critical',
51    vibrate: data.priority === 'critical' ? [200, 100, 200, 100, 200] : [100],
52    renotify: true,
53  };
54
55  event.waitUntil(
56    self.registration.showNotification(data.title || 'Anahuac RV Park', options)
57  );
58
59  // Update badge count on the app icon
60  if (self.navigator && self.navigator.setAppBadge && data.badge_count != null) {
61    try { self.navigator.setAppBadge(data.badge_count); } catch {}
62  }
63});
64
65// Notification click handler — open or focus the portal
66self.addEventListener('notificationclick', (event) => {
67  event.notification.close();
68  const targetUrl = event.notification.data?.url || '/portal';
69
70  event.waitUntil(
71    self.clients.matchAll({ type: 'window', includeUncontrolled: true }).then((windowClients) => {
72      for (const client of windowClients) {
73        if (client.url.includes('/portal') && 'focus' in client) {
74          client.navigate(targetUrl);
75          return client.focus();
76        }
77      }
78      if (self.clients.openWindow) {
79        return self.clients.openWindow(targetUrl);
80      }
81    })
82  );
83});

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.