forked from phenom/healer-man
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,4 +1,5 @@
|
||||
import { readFileSync } from "node:fs";
|
||||
import { gzipSync } from "node:zlib";
|
||||
import { runInNewContext } from "node:vm";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import { ARENA_STAGES } from "../game/arenaStages";
|
||||
@@ -9,10 +10,11 @@ const workerSource = readFileSync(
|
||||
"utf8",
|
||||
);
|
||||
|
||||
function contentWorker(cached?: Response) {
|
||||
function contentWorker(cached?: Response, bundledFiles: Record<string, unknown> = {}, object?: Response) {
|
||||
const handlers = new Map<string, (event: unknown) => void>();
|
||||
const fetch = vi.fn(async () => new Response("bundled arena", { status: 200 }));
|
||||
const match = vi.fn(async () => cached);
|
||||
const fetch = vi.fn(async (url: RequestInfo | URL) => String(url) === "/content/bootstrap-manifest.json"
|
||||
? Response.json({ files: bundledFiles }) : object?.clone() ?? new Response("bundled arena", { status: 200 }));
|
||||
const match = vi.fn(async (url: RequestInfo | URL) => String(url).includes("/content/cache-objects/") ? object?.clone() : cached?.clone());
|
||||
runInNewContext(workerSource, {
|
||||
self: {
|
||||
location: { origin: "https://healer.test" },
|
||||
@@ -22,10 +24,13 @@ function contentWorker(cached?: Response) {
|
||||
fetch,
|
||||
URL,
|
||||
Response,
|
||||
Headers,
|
||||
DecompressionStream,
|
||||
});
|
||||
return {
|
||||
fetch,
|
||||
match,
|
||||
refresh: () => handlers.get("message")!({ data: { type: "refresh-content-bootstrap" } }),
|
||||
request: (path: string) => {
|
||||
let response: Promise<Response> | undefined;
|
||||
handlers.get("fetch")!({
|
||||
@@ -45,7 +50,7 @@ describe("browser content cache worker", () => {
|
||||
expect(response?.status).toBe(200);
|
||||
expect(await response?.text()).toBe("bundled arena");
|
||||
}
|
||||
expect(worker.fetch).toHaveBeenCalledTimes(stage.assets.length);
|
||||
expect(worker.fetch).toHaveBeenCalledTimes(stage.assets.length + 1);
|
||||
});
|
||||
|
||||
it("prefers installed arena updates over bundled files, ignoring the runtime query", async () => {
|
||||
@@ -61,7 +66,8 @@ describe("browser content cache worker", () => {
|
||||
const response = await worker.request("/assets/game/manastorm/optional/visual.glb");
|
||||
expect(response?.status).toBe(404);
|
||||
expect(await response?.text()).toBe("Optional content is not installed.");
|
||||
expect(worker.fetch).not.toHaveBeenCalled();
|
||||
expect(worker.fetch).toHaveBeenCalledTimes(1);
|
||||
expect(worker.fetch).toHaveBeenCalledWith("/content/bootstrap-manifest.json", { cache: "no-cache" });
|
||||
});
|
||||
|
||||
it("serves only cached same-origin asset requests from the active content cache", () => {
|
||||
@@ -70,11 +76,38 @@ describe("browser content cache worker", () => {
|
||||
expect(workerSource).toContain("url.origin !== self.location.origin");
|
||||
expect(workerSource).toContain("MANAGED_ASSET_PREFIXES.some");
|
||||
expect(workerSource).toContain('"/assets/game/"');
|
||||
expect(workerSource).toContain("if (cached) return cached");
|
||||
expect(workerSource).toContain("if (!objectPath) return cached");
|
||||
expect(workerSource).toContain("BUNDLED_ASSET_PATHS.has(url.pathname)");
|
||||
expect(workerSource).toContain("BUNDLED_ASSET_PREFIXES.some");
|
||||
expect(workerSource).not.toContain('"/assets/characters/wow335a-v1/textures/character/human/",');
|
||||
expect(workerSource).toContain('status: 404');
|
||||
expect(workerSource).not.toContain("cached ?? fetch(request)");
|
||||
});
|
||||
|
||||
it("expands bundled gzip without requiring a Manastorm install", async () => {
|
||||
const url = "/assets/game/manastorm/shared/visual.glb";
|
||||
const original = "glTF original dungeon".repeat(100);
|
||||
const worker = contentWorker(undefined, { [url]: { download: { url: "/content/bundled/object.glb.gz", encoding: "gzip" } } }, new Response(gzipSync(original)));
|
||||
const response = await worker.request(url);
|
||||
expect(await response?.text()).toBe(original);
|
||||
expect(response?.headers.get("content-type")).toBe("model/gltf-binary");
|
||||
});
|
||||
|
||||
it("resolves a tiny installed alias to one compressed shared object", async () => {
|
||||
const original = "glTF installed original".repeat(100);
|
||||
const worker = contentWorker(new Response(null, { headers: { "x-healer-man-content-object": "/content/cache-objects/shared.glb" } }), {},
|
||||
new Response(gzipSync(original), { headers: { "x-healer-man-content-encoding": "gzip" } }));
|
||||
expect(await (await worker.request("/assets/creatures/optional/model.glb"))?.text()).toBe(original);
|
||||
expect(worker.fetch).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("refreshes bootstrap mappings when a new app session starts", async () => {
|
||||
const path = "/assets/game/dungeons/new/visual.glb";
|
||||
const files: Record<string, unknown> = {};
|
||||
const worker = contentWorker(undefined, files, new Response(gzipSync("new original")));
|
||||
expect((await worker.request(path))?.status).toBe(404);
|
||||
files[path] = { download: { url: "/content/bundled/new.glb.gzip", encoding: "gzip" } };
|
||||
worker.refresh();
|
||||
expect(await (await worker.request(path))?.text()).toBe("new original");
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user