Release Healer Man 0.1.29
This commit is contained in:
1 parent
8c9809d3e0
commit
544c1bee91
120 files changed
+4363
-1036
No files matched your search
@@ -1,10 +1,51 @@
|
||||
const CONTENT_CACHE_NAME = "healer-man-content-v1";
|
||||
const OBJECT_HEADER = "x-healer-man-content-object";
|
||||
const ENCODING_HEADER = "x-healer-man-content-encoding";
|
||||
let bundledManifest;
|
||||
|
||||
function mimeType(path) {
|
||||
const extension = path.split(".").pop();
|
||||
return ({ glb: "model/gltf-binary", json: "application/json", js: "text/javascript", wasm: "application/wasm",
|
||||
ktx2: "image/ktx2", png: "image/png", webp: "image/webp", avif: "image/avif", svg: "image/svg+xml",
|
||||
mp3: "audio/mpeg", ogg: "audio/ogg", wav: "audio/wav", webm: "video/webm" })[extension] ?? "application/octet-stream";
|
||||
}
|
||||
|
||||
async function decodedResponse(response, path, encoding) {
|
||||
if (encoding !== "gzip") return response;
|
||||
const headers = new Headers(response.headers);
|
||||
headers.set("content-type", mimeType(path));
|
||||
headers.delete("content-length");
|
||||
headers.delete("content-encoding");
|
||||
headers.delete(ENCODING_HEADER);
|
||||
return new Response(response.body.pipeThrough(new DecompressionStream("gzip")), { status: 200, headers });
|
||||
}
|
||||
|
||||
async function bundledAsset(path) {
|
||||
if (!bundledManifest) {
|
||||
bundledManifest = fetch("/content/bootstrap-manifest.json", { cache: "no-cache" })
|
||||
.then((response) => response.ok ? response.json() : null)
|
||||
.catch(() => null);
|
||||
}
|
||||
const manifest = await bundledManifest;
|
||||
if (!manifest) { bundledManifest = null; return null; }
|
||||
const entry = manifest.files?.[path];
|
||||
if (!entry) return null;
|
||||
const object = entry.download ?? entry;
|
||||
// Older bootstrap catalogs served their original logical paths directly.
|
||||
if (!object.url.startsWith("/content/bundled/")) return fetch(path);
|
||||
const response = await fetch(object.url);
|
||||
if (!response.ok) return response;
|
||||
if (entry.download) return decodedResponse(response, path, entry.download.encoding);
|
||||
return new Response(response.body, { headers: { "content-type": mimeType(path) } });
|
||||
}
|
||||
const MANAGED_ASSET_PREFIXES = [
|
||||
"/assets/characters/",
|
||||
"/assets/creatures/",
|
||||
"/assets/equipment/",
|
||||
"/assets/game/",
|
||||
"/assets/ui/",
|
||||
"/basis/",
|
||||
"/data/",
|
||||
];
|
||||
const BUNDLED_ASSET_PREFIXES = [
|
||||
"/assets/ui/",
|
||||
@@ -36,6 +77,10 @@ self.addEventListener("install", (event) => {
|
||||
event.waitUntil(self.skipWaiting());
|
||||
});
|
||||
|
||||
self.addEventListener("message", (event) => {
|
||||
if (event.data?.type === "refresh-content-bootstrap") bundledManifest = null;
|
||||
});
|
||||
|
||||
self.addEventListener("activate", (event) => {
|
||||
event.waitUntil((async () => {
|
||||
const names = await caches.keys();
|
||||
@@ -56,7 +101,16 @@ self.addEventListener("fetch", (event) => {
|
||||
event.respondWith((async () => {
|
||||
const cache = await caches.open(CONTENT_CACHE_NAME);
|
||||
const cached = await cache.match(request, { ignoreSearch: true });
|
||||
if (cached) return cached;
|
||||
if (cached) {
|
||||
const objectPath = cached.headers.get(OBJECT_HEADER);
|
||||
if (!objectPath) return cached;
|
||||
if (objectPath.startsWith("/content/cache-objects/")) {
|
||||
const object = await cache.match(new URL(objectPath, self.location.origin).toString());
|
||||
if (object) return decodedResponse(object, url.pathname, object.headers.get(ENCODING_HEADER));
|
||||
}
|
||||
}
|
||||
const bundled = await bundledAsset(url.pathname);
|
||||
if (bundled) return bundled;
|
||||
if (BUNDLED_ASSET_PATHS.has(url.pathname)
|
||||
|| BUNDLED_ASSET_PREFIXES.some((prefix) => url.pathname.startsWith(prefix))) {
|
||||
return fetch(request);
|
||||
|
||||
Reference in new issue
Block a user