PWA
This commit is contained in:
parent
5de8d4a791
commit
394e60ee95
10 changed files with 146 additions and 9 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -1,4 +1,3 @@
|
||||||
/node_modules/
|
/node_modules/
|
||||||
/public/build/
|
/public/build/
|
||||||
|
/public/service-worker.js
|
||||||
.DS_Store
|
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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
26
public/manifest.json
Normal 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
BIN
public/maskable_icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 505 B |
20
pwa.rollup.config.mjs
Normal file
20
pwa.rollup.config.mjs
Normal 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,
|
||||||
|
},
|
||||||
|
};
|
|
@ -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
65
src/pwa/service-worker.ts
Normal 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
7
src/pwa/tsconfig.json
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"target": "es2021",
|
||||||
|
"include": ["service-worker.ts"],
|
||||||
|
"compilerOptions": {
|
||||||
|
"lib": ["WebWorker"]
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Reference in a new issue