Skip to content

Commit

Permalink
Merge pull request #752 from MuckRock/sveltekit-service-worker
Browse files Browse the repository at this point in the history
Use a service worker to cache requests
  • Loading branch information
eyeseast authored Oct 3, 2024
2 parents d1f7243 + 2a67dcf commit b79650d
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 1 deletion.
1 change: 1 addition & 0 deletions jsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
".svelte-kit/ambient.d.ts",
"vite.config.js",
"vite.config.ts",
"src/app.d.ts",
"src/lib/**/*.js",
"src/lib/**/*.ts",
"src/lib/**/*.svelte",
Expand Down
10 changes: 10 additions & 0 deletions src/app.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,16 @@ declare global {
// interface PageState {}
// interface Platform {}
}

namespace svelteHTML {
interface HTMLAttributes<T> {
"on:vite:preloadError"?: (event: any) => any;
}

interface HTMLProps<T> {
"on:vite:preloadError"?: (event: any) => any;
}
}
}

export {};
20 changes: 19 additions & 1 deletion src/routes/+layout.svelte
Original file line number Diff line number Diff line change
@@ -1,12 +1,28 @@
<script>
<script lang="ts">
import { browser } from "$app/environment";
import { beforeNavigate } from "$app/navigation";
import { updated } from "$app/stores";
import { locale } from "svelte-i18n";
import "@/style/variables.css";
import "@/style/global.css";
import "@/style/kit.css";
$: useCyrillicCharset = browser ? ["uk", "ru"].includes($locale) : false;
// this checks if the site has been updated and triggers a full page reload
// on the next navigation to update the cache
beforeNavigate(({ willUnload, to }) => {
if ($updated && !willUnload && to?.url) {
location.href = to.url.href;
}
});
// https://vite.dev/guide/build#load-error-handling
function reload() {
window.location.reload();
}
</script>

<svelte:head>
Expand All @@ -16,4 +32,6 @@
{/if}
</svelte:head>

<svelte:window on:vite:preloadError={reload} />

<slot />
86 changes: 86 additions & 0 deletions src/service-worker.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/// <reference types="@sveltejs/kit" />
/// <reference no-default-lib="true"/>
/// <reference lib="esnext" />
/// <reference lib="webworker" />

const sw = self as unknown as ServiceWorkerGlobalScope;

import { build, files, version } from "$service-worker";

// Create a unique cache name for this deployment
const CACHE = `cache-${version}`;

const ASSETS = [
...build, // the app itself
...files, // everything in `static`
];

sw.addEventListener("install", (event) => {
// Create a new cache and add all files to it
async function addFilesToCache() {
const cache = await caches.open(CACHE);
await cache.addAll(ASSETS);
}

event.waitUntil(addFilesToCache());
});

sw.addEventListener("activate", (event) => {
// Remove previous cached data from disk
async function deleteOldCaches() {
for (const key of await caches.keys()) {
if (key !== CACHE) await caches.delete(key);
}
}

event.waitUntil(deleteOldCaches());
});

sw.addEventListener("fetch", (event) => {
// ignore POST requests etc
if (event.request.method !== "GET") return;

async function respond() {
const url = new URL(event.request.url);
const cache = await caches.open(CACHE);

// `build`/`files` can always be served from the cache
if (ASSETS.includes(url.pathname)) {
const response = await cache.match(url.pathname);

if (response) {
return response;
}
}

// for everything else, try the network first, but
// fall back to the cache if we're offline
try {
const response = await fetch(event.request);

// if we're offline, fetch can return a value that is not a Response
// instead of throwing - and we can't pass this non-Response to respondWith
if (!(response instanceof Response)) {
throw new Error("invalid response from fetch");
}

if (response.status === 200) {
cache.put(event.request, response.clone());
}

return response;
} catch (err) {
const response = await cache.match(event.request);

if (response) {
return response;
}

// if there's no cache, then just error out
// as there is nothing we can do to respond to this request
throw err;
}
}

event.respondWith(respond());
});
1 change: 1 addition & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"src/**/*.ts",
"src/**/*.svelte",
"src/**/*.js",
"src/app.d.ts",
".svelte-kit/ambient.d.ts"
],
"exclude": ["public/*"]
Expand Down

0 comments on commit b79650d

Please sign in to comment.