Service worker:
- Strip version suffix from CACHE_PAGES and CACHE_IMAGES so cached pages
and recipe thumbs survive SW updates. Each deploy used to wipe both,
forcing a re-sync before the user could open the app offline. Build
and static caches stay version-suffixed (entries are hash-fingerprinted).
- Install precaches the offline shells: /, /rezepte, /recipes, both
offline-shell pages, /glaube, /faith, /fitness — best-effort with
Promise.allSettled so a single 5xx can't fail SW install.
- Bulk thumbnail precache now skips URLs already in CACHE_IMAGES.
Recipe thumb URLs embed a content hash, so a cache hit guarantees
identical bytes; subsequent syncs after small recipe edits no longer
redownload every image.
- Activate cleanup deletes only stale versioned build/static entries
and obsolete versioned pages/images caches.
Universal load migration:
- [recipeLang]/+layout.server.ts removed; logic in universal +layout.ts.
Session fetched from /auth/session, nulled when offline.
- [recipeLang]/+page.server.ts and season/[month]/+page.server.ts
removed; merged into universal +page.ts. Drops the __data.json
round-trip entirely for these routes — IndexedDB fallback now runs
even when the SW page cache is empty (fresh install, hash mismatch,
etc.) instead of getting blocked by a 503 from the data handler.
Other:
- /static/rezepte/thumb URLs in sync.ts and the SW thumb fallback now
use the absolute https://bocken.org origin. Dev/preview servers don't
host /static/rezepte and were 404ing on themselves; production keys
resolve to the same string so existing caches stay valid.
- Root +layout.svelte invalidateAll() now bails when !navigator.onLine.
Resume-while-offline used to refetch every load() and surface the
error page instead of the still-viewable cached content.
Bump 1.64.2 -> 1.65.2.
Replace season: number[] (months 1-12) on Recipe with seasonRanges, a
list of date ranges where each endpoint is either a fixed MM-DD or a
movable liturgical anchor (Easter, Ash Wednesday, Palm Sunday,
Pentecost, Advent I) plus a day offset. The old month list couldn't
express liturgical seasons whose boundaries shift each year (Advent,
Lent, Easter Octave, Christmas Octave) nor sub-month windows.
The shared evaluator resolves anchors against [Y-1, Y, Y+1] so spans
that wrap the calendar year boundary (e.g. christmas + 0 to
christmas + 7) match correctly on both sides. SeasonSelect was
rewritten as a controlled bind:ranges editor with a
fixed/liturgical kind toggle, anchor + offset inputs, per-row
resolved-this-year preview, and preset chips.
Run the one-time migration before deploying:
pnpm exec vite-node scripts/migrate-season-to-ranges.ts
It coalesces contiguous month runs into single fixed ranges and
merges Dec/Jan wrap into one wrapping range; the new code does not
read the legacy season field, so order matters.
`navigator.serviceWorker.ready` resolves only when a SW is registered
and active. In `vite dev` no SW exists, so awaiting `ready` hangs the
sync forever. Gate on `navigator.serviceWorker.controller` first to
short-circuit cleanly when nothing controls the page.
Bump 1.57.7 -> 1.57.8.
Cache fitness page shells and data routes in the service worker so
pages load offline. Queue finished workouts in IndexedDB when the
POST fails and auto-flush them on reconnect. Show an offline banner
on the completion screen so the user knows their workout will sync.
The glob in sync.ts targeted a nonexistent /src/routes/glaube/ directory
instead of the actual [faithLang=faithLang] parameterized route. This meant
zero prayer pages were ever precached for offline use.
- Fix glob to match [faithLang=faithLang] and expand param segments to
both language variants (glaube/faith, gebete/prayers, rosenkranz/rosary)
- Extract validPrayerSlugs to shared module for build-time route enumeration
- Add faith to service worker cacheable route regex
Add type annotations, JSDoc types, null checks, and proper generics
to eliminate all svelte-check errors. Key changes include:
- Type $state(null) variables to avoid 'never' inference
- Add JSDoc typedefs for plain <script> components
- Fix mongoose model typing with Model<any> to avoid union complexity
- Add App.Error/App.PageState interfaces in app.d.ts
- Fix tuple types to array types in types.ts
- Type catch block errors and API handler params
- Add null safety for DOM queries and optional chaining
- Add standard line-clamp property alongside -webkit- prefix
Move components from flat src/lib/components/ into recipes/, faith/, and
cospend/ subdirectories. Replace ~144 relative imports across API routes
and lib files with $models, $utils, $types, and $lib aliases. Add $types
alias to svelte.config.js. Remove unused EditRecipe.svelte.
- Service worker reports image caching progress back to main thread
- Sync progress shows current phase (recipes, pages, data, images)
- Display progress bar for image downloads in sync tooltip
- Use mediapath for thumbnail URLs (with hash for cache busting)
- Serve cached thumbnails as fallback for full/placeholder when offline
- Add offline support for category, tag, icon list pages
- Add offline support for favorites page (stores locally for offline)
- Add offline support for season list page
- Cache root page and glaube pages for offline access
- Dynamically discover glaube routes at build time using Vite glob
- Add db functions for getAllCategories, getAllTags, getAllIcons
- Pre-cache __data.json for all category, tag, icon, season subroutes
- Update service worker to cache glaube and root page responses
- Add service worker with caching for build assets, static files, images, and pages
- Add IndexedDB storage for recipes (brief and full data)
- Add offline-db API endpoint for bulk recipe download
- Add offline sync button component in header
- Add offline-shell page for direct navigation fallback
- Pre-cache __data.json for client-side navigation
- Add +page.ts universal load functions with IndexedDB fallback
- Add PWA manifest and icons for installability
- Update recipe page to handle missing data gracefully