@ztimson/momentum
Version:
Client library for momentum
125 lines (112 loc) • 3.92 kB
JavaScript
import {Momentum} from '/momentum.mjs';
(async () => {
let analyticsId = null;
const production = self.location.origin !== 'http://localhost:5173';
const apiUrl = production ? self.location.origin : 'http://localhost:3000';
// Restore analytics ID from cache before creating Momentum
try {
const analyticsCache = await caches.open('analytics-cache');
const res = await analyticsCache.match('analytics-id');
if(res) analyticsId = (await res.json()).id;
} catch (err) {
console.warn('Failed to restore analytics ID:', err);
}
const cache = caches.open(apiUrl);
const momentum = new Momentum(apiUrl, {
analytics: analyticsId || false,
banner: false,
offline: true,
socket: true,
worker: false,
});
async function reloadClients() {
const allClients = await self.clients.matchAll({ type: 'window', includeUncontrolled: true });
for (const client of allClients) {
client.postMessage({ update: true });
}
}
async function update() {
const c = await cache;
let files = await momentum.static.all();
// files.map(meta => momentum.static.open(meta.path, false));
// for (const file of files) {
// const req = new Request(file.path, {cache: 'no-cache'});
// try {
// const res = await fetch(req);
// if (res.ok) await c.put(req, res);
// else throw new Error();
// } catch (err) {
// await c.delete(req);
// }
// }
}
self.addEventListener('install', e => e.waitUntil(update()));
self.addEventListener('periodicsync', e => e.waitUntil(update()));
self.addEventListener('activate', e => {
e.waitUntil((async () => {
await self.clients.claim();
await reloadClients();
})());
});
// self.addEventListener('fetch', (event) => {
// const req = event.request;
// // Only cache static momentum assets
// if(!req.url.startsWith(momentum.url.origin) || req.url.startsWith(momentum.url.origin + 'api') || req.method !== 'GET') return;
//
// event.respondWith((async () => {
// const c = await cache;
// if(!self.navigator.onLine) {
// const cachedResponse = await c.match(req);
// if(cachedResponse) return cachedResponse;
// return new Response('You are offline', {status: 503, statusText: 'Service Unavailable'});
// }
// try {
// const response = await fetch(req);
// if(response.ok) await c.put(req, response.clone());
// else if(response.status === 404) await c.delete(req);
// return response;
// } catch (err) {
// const cachedResponse = await c.match(req);
// if(cachedResponse) return cachedResponse;
// throw err;
// }
// })());
// });
self.addEventListener('message', async (event) => {
if (event.data?.analyticsId) {
momentum.analytics.id = event.data?.analyticsId
try {
const analyticsCache = await caches.open('analytics-cache');
await analyticsCache.put('analytics-id', new Response(JSON.stringify({id: event.data?.analyticsId})));
} catch (err) {
console.warn('Failed to save analytics ID:', err);
}
} else if (event.data?.skipWaiting) {
await self.skipWaiting();
} else if (event.data?.update) {
if (self.registration.waiting) {
self.registration.waiting.postMessage({skipWaiting: true});
} else {
await reloadClients();
}
}
});
self.addEventListener('notificationclick', (event) => {
const data = event.notification.data;
event.notification.close();
if(data && data.link) event.waitUntil(clients.openWindow(data.link));
});
self.addEventListener('push', async (event) => {
let data;
try { data = event.data?.json() ?? {}; }
catch { data = {message: event.data?.text()}; }
event.waitUntil(
self.registration.showNotification(data.title || `Momentum Alert`, {
body: data.message || '',
tag: data.title || 'general',
icon: data.icon || `${self.location.origin}/favicon.ico`,
data
})
);
});
})();