This commit is contained in:
Tobias Berger 2021-10-05 12:53:14 +02:00
parent 5de8d4a791
commit 394e60ee95
10 changed files with 146 additions and 9 deletions

3
.gitignore vendored
View file

@ -1,4 +1,3 @@
/node_modules/ /node_modules/
/public/build/ /public/build/
/public/service-worker.js
.DS_Store

View file

@ -6,8 +6,11 @@
"homepage": "https://shark.tobot.dev/", "homepage": "https://shark.tobot.dev/",
"scripts": { "scripts": {
"postinstall": "yarn simple-git-hooks", "postinstall": "yarn simple-git-hooks",
"build": "rollup -c rollup.config.mjs", "build": "yarn build:game && yarn build:pwa",
"dev": "yarn build -w", "build:game": "rollup -c rollup.config.mjs",
"build:pwa": "rollup -c pwa.rollup.config.mjs",
"dev": "yarn build:game -w",
"dev:pwa": "yarn build:pwa -w",
"start": "sirv public --no-clear", "start": "sirv public --no-clear",
"preview": "yarn build && yarn start", "preview": "yarn build && yarn start",
"check": "svelte-check --tsconfig ./tsconfig.json", "check": "svelte-check --tsconfig ./tsconfig.json",

View file

@ -36,6 +36,7 @@
<link rel="image_src" href="https://rewrite.shark.tobot.dev/sharkgame.png" /> <link rel="image_src" href="https://rewrite.shark.tobot.dev/sharkgame.png" />
<link rel="apple-touch-icon" href="https://rewrite.shark.tobot.dev/sharkgame.png" /> <link rel="apple-touch-icon" href="https://rewrite.shark.tobot.dev/sharkgame.png" />
<link rel="manifest" href="/manifest.json" />
<link rel="alternate" type="application/json+oembed" href="/oEmbed.json" /> <link rel="alternate" type="application/json+oembed" href="/oEmbed.json" />
<!-- This loads the actual game --> <!-- This loads the actual game -->
@ -81,5 +82,21 @@
'-'` </pre '-'` </pre
> >
</noscript> </noscript>
<script>
if ("serviceWorker" in navigator) {
window.addEventListener("load", () => {
navigator.serviceWorker
.register("service-worker.js")
.then((registration) => {
console.debug("Registered ServiceWorker");
})
.catch((err) => {
console.error("ServiceWorker registration failed", err);
});
});
} else {
console.warn("ServiceWorker not supported.");
}
</script>
</body> </body>
</html> </html>

26
public/manifest.json Normal file
View file

@ -0,0 +1,26 @@
{
"name": "Shark Game",
"short_name": "Sharg",
"icons": [
{
"src": "favicon.png",
"sizes": "16x16",
"type": "image/png"
},
{
"src": "sharkgame.png",
"sizes": "200x200",
"type": "image/png"
},
{
"purpose": "maskable",
"src": "maskable_icon.png",
"sizes": "32x32",
"type": "image/png"
}
],
"start_url": "/index.html",
"display": "standalone",
"background_color": "#536892",
"theme_color": "#2e4372"
}

BIN
public/maskable_icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 505 B

20
pwa.rollup.config.mjs Normal file
View file

@ -0,0 +1,20 @@
import typescript from "@rollup/plugin-typescript";
import { terser } from "rollup-plugin-terser";
const production = !process.env.ROLLUP_WATCH;
export default {
input: "src/pwa/service-worker.ts",
output: {
file: "public/service-worker.js",
preferConst: true,
strict: true,
},
plugins: [
typescript({ sourceMap: false, include: "**/service-worker.ts", lib: ["WebWorker"] }),
production && terser({ output: { comments: false } }),
],
watch: {
clearScreen: false,
},
};

View file

@ -42,6 +42,7 @@ export default {
externalLiveBindings: false, externalLiveBindings: false,
preferConst: true, preferConst: true,
strict: true, strict: true,
compact: production,
}, },
plugins: [ plugins: [
// Svelte adds "stdin" to the sourceMap // Svelte adds "stdin" to the sourceMap
@ -79,6 +80,7 @@ export default {
typescript({ typescript({
sourceMap: true, sourceMap: true,
inlineSources: true, inlineSources: true,
exclude: ["node_modules/*", "public/*", "**/service-worker.ts"],
}), }),
// In dev mode, call `yarn start` once // In dev mode, call `yarn start` once

65
src/pwa/service-worker.ts Normal file
View file

@ -0,0 +1,65 @@
const CACHE_NAME = "sharg-static-cache";
const CACHE_VERSION = "v0.0.1";
const STATIC_CACHE_NAME = CACHE_NAME + "-" + CACHE_VERSION;
const FILES_TO_CACHE = ["/", "/index.html", "/build/bundle.js", "/build/bundle.css", "/favicon.png"];
const globalScope = self as WorkerGlobalScope as ServiceWorkerGlobalScope;
globalScope.addEventListener("install", (event) => {
console.debug("[ServiceWorker] Install");
event.waitUntil(
caches.open(STATIC_CACHE_NAME).then((cache) => {
console.debug("[ServiceWorker] Pre-caching offline page");
return cache.addAll(FILES_TO_CACHE);
})
);
});
globalScope.addEventListener("activate", (evt) => {
console.log("[ServiceWorker] Activate");
// Remove previous cached data from disk.
evt.waitUntil(
caches.keys().then((keyList) => {
return Promise.all(
keyList.map((key) => {
if (key.startsWith(CACHE_NAME) && key !== STATIC_CACHE_NAME) {
console.log("[ServiceWorker] Removing old cache", key);
return caches.delete(key);
}
})
);
})
);
globalScope.clients.claim();
});
globalScope.addEventListener("fetch", (event) => {
console.debug("[ServiceWorker] Fetch", event.request.url);
function getFromFetch(cache: Cache) {
console.debug("getFromFetch");
return fetch(event.request).then((response) => {
cache.put(event.request.url, response.clone());
return response;
});
}
async function getFromCache() {
const cache = await caches.open(STATIC_CACHE_NAME);
const cached = await cache.match(event.request);
if (cached !== undefined) {
return cached;
}
try {
return await getFromFetch(cache);
} catch (e) {
console.error(e);
return Response.error();
}
}
event.respondWith(getFromCache());
});

7
src/pwa/tsconfig.json Normal file
View file

@ -0,0 +1,7 @@
{
"target": "es2021",
"include": ["service-worker.ts"],
"compilerOptions": {
"lib": ["WebWorker"]
}
}

View file

@ -1,12 +1,10 @@
{ {
"extends": "@tsconfig/svelte/tsconfig.json", "extends": "@tsconfig/svelte/tsconfig.json",
"target": "es2021", "target": "es2021",
"include": ["src/**/*"], "include": ["src/**/*"],
"exclude": ["node_modules/*", "__sapper__/*", "public/*"], "exclude": ["src/service-worker.ts"],
"compilerOptions": { "compilerOptions": {
"strict": true "strict": true,
"isolatedModules": false
} }
} }