- Multiple named notes with sidebar (persisted in localStorage + D1) - Dark mode toggle, persisted - Markdown preview toggle (Ctrl+M) with styled rendering - Drawing: eraser tool, undo/redo (40-step stack) - Auto-save indicator, word/char count status bar - Export note as .txt download - Keyboard shortcuts: Ctrl+S save, Ctrl+D draw, Ctrl+M markdown, Ctrl+Shift+N new note - D1 backend (noted-db) with Pages Functions API for cross-device sync - Share note: generates read-only link at /share/:token - Updated service worker to v2, skip API routes Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
28 lines
930 B
JavaScript
28 lines
930 B
JavaScript
const CACHE = 'noted-v2';
|
|
const ASSETS = ['./', './index.html', './manifest.json', './fry.png'];
|
|
|
|
self.addEventListener('install', e => {
|
|
e.waitUntil(caches.open(CACHE).then(c => c.addAll(ASSETS)));
|
|
self.skipWaiting();
|
|
});
|
|
|
|
self.addEventListener('activate', e => {
|
|
e.waitUntil(caches.keys().then(keys =>
|
|
Promise.all(keys.filter(k => k !== CACHE).map(k => caches.delete(k)))
|
|
));
|
|
self.clients.claim();
|
|
});
|
|
|
|
self.addEventListener('fetch', e => {
|
|
if (e.request.url.includes('/api/')) return;
|
|
e.respondWith(
|
|
caches.match(e.request).then(cached => cached || fetch(e.request).then(res => {
|
|
if (res.ok && e.request.method === 'GET') {
|
|
caches.open(CACHE).then(c => c.put(e.request, res.clone()));
|
|
}
|
|
return res;
|
|
}).catch(() => {
|
|
if (e.request.mode === 'navigate') return caches.match('./index.html');
|
|
}))
|
|
);
|
|
});
|