forked from phenom/healer-man
Release Healer Man 0.1.27
This commit is contained in:
1 parent
147c2804d4
commit
ed8b9e3719
6 files changed
+86
-6
No files matched your search
@@ -1992,3 +1992,26 @@ Vite's existing large-chunk advisory remains informational.
|
|||||||
eight-heading pixel comparisons, profiles, before/after timing JSON, and
|
eight-heading pixel comparisons, profiles, before/after timing JSON, and
|
||||||
screenshots. Measurements use the same desktop Edge/RX 9070 XT setup as the
|
screenshots. Measurements use the same desktop Edge/RX 9070 XT setup as the
|
||||||
preceding audit. These CPU improvements do not certify Thor performance.
|
preceding audit. These CPU improvements do not certify Thor performance.
|
||||||
|
|
||||||
|
# 2026-09-09 — bundled arena assets blocked by the browser content worker
|
||||||
|
|
||||||
|
- Reproduced the reported collision-matched fallback in the production build
|
||||||
|
with the content worker active. Warnorken's `visual.glb?arena-runtime=1`
|
||||||
|
returned 404 even though the file was bundled and directly served with 200.
|
||||||
|
The worker omitted `/assets/game/arenas/` from its bundled asset prefixes and
|
||||||
|
incorrectly rejected these files as uninstalled optional content.
|
||||||
|
- Added the arena prefix to the worker. Installed updates still take priority;
|
||||||
|
missing optional dungeon content still returns 404. Behavioral worker tests
|
||||||
|
failed for all eight arenas before the fix and now cover visual, collision,
|
||||||
|
and navigation requests with the runtime query parameter.
|
||||||
|
- The production build passed. Reloading the same browser session activated
|
||||||
|
the fixed worker without clearing storage or downloading content. Warnorken
|
||||||
|
rendered textured stone geometry and Nagrand rendered its authored arena
|
||||||
|
geometry; neither showed the loading/fallback banner after loading, and no
|
||||||
|
new console errors were recorded. Checks used offline practice in the Codex
|
||||||
|
browser at `http://127.0.0.1:4174/`, backed by a local test server on port 4173.
|
||||||
|
- All 22 content tests and the eight-arena asset validator passed. Screenshots,
|
||||||
|
before/after error logs, asset validation, and build output are saved under
|
||||||
|
`playtest-artifacts/2026-09-09-arena-loading/`. The existing large-bundle
|
||||||
|
advisory remains. This verifies the local browser build, not a deployment
|
||||||
|
or an Android package.
|
||||||
Generated
+2
-2
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "healer-man",
|
"name": "healer-man",
|
||||||
"version": "0.1.26",
|
"version": "0.1.27",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "healer-man",
|
"name": "healer-man",
|
||||||
"version": "0.1.26",
|
"version": "0.1.27",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@capacitor/android": "8.4.1",
|
"@capacitor/android": "8.4.1",
|
||||||
"@capacitor/core": "8.4.1",
|
"@capacitor/core": "8.4.1",
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "healer-man",
|
"name": "healer-man",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.1.26",
|
"version": "0.1.27",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite --host 0.0.0.0",
|
"dev": "vite --host 0.0.0.0",
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ const BUNDLED_ASSET_PREFIXES = [
|
|||||||
"/assets/characters/wow335a-v1/manifest.json",
|
"/assets/characters/wow335a-v1/manifest.json",
|
||||||
"/assets/characters/wow335a-v1/human/",
|
"/assets/characters/wow335a-v1/human/",
|
||||||
"/assets/creatures/wailing-caverns/",
|
"/assets/creatures/wailing-caverns/",
|
||||||
|
"/assets/game/arenas/",
|
||||||
"/assets/game/dungeons/wailing-caverns/",
|
"/assets/game/dungeons/wailing-caverns/",
|
||||||
];
|
];
|
||||||
const BUNDLED_ASSET_PATHS = new Set([
|
const BUNDLED_ASSET_PATHS = new Set([
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
{
|
{
|
||||||
"versionName": "0.1.26",
|
"versionName": "0.1.27",
|
||||||
"versionCode": 1026
|
"versionCode": 1027
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
import { readFileSync } from "node:fs";
|
import { readFileSync } from "node:fs";
|
||||||
import { describe, expect, it } from "vitest";
|
import { runInNewContext } from "node:vm";
|
||||||
|
import { describe, expect, it, vi } from "vitest";
|
||||||
|
import { ARENA_STAGES } from "../game/arenaStages";
|
||||||
import { BROWSER_CONTENT_CACHE_NAME } from "./contentManager";
|
import { BROWSER_CONTENT_CACHE_NAME } from "./contentManager";
|
||||||
|
|
||||||
const workerSource = readFileSync(
|
const workerSource = readFileSync(
|
||||||
@@ -7,7 +9,61 @@ const workerSource = readFileSync(
|
|||||||
"utf8",
|
"utf8",
|
||||||
);
|
);
|
||||||
|
|
||||||
|
function contentWorker(cached?: 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);
|
||||||
|
runInNewContext(workerSource, {
|
||||||
|
self: {
|
||||||
|
location: { origin: "https://healer.test" },
|
||||||
|
addEventListener: (type: string, handler: (event: unknown) => void) => handlers.set(type, handler),
|
||||||
|
},
|
||||||
|
caches: { open: async () => ({ match }) },
|
||||||
|
fetch,
|
||||||
|
URL,
|
||||||
|
Response,
|
||||||
|
});
|
||||||
|
return {
|
||||||
|
fetch,
|
||||||
|
match,
|
||||||
|
request: (path: string) => {
|
||||||
|
let response: Promise<Response> | undefined;
|
||||||
|
handlers.get("fetch")!({
|
||||||
|
request: new Request(new URL(path, "https://healer.test")),
|
||||||
|
respondWith: (value: Promise<Response>) => { response = value; },
|
||||||
|
});
|
||||||
|
return response;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
describe("browser content cache worker", () => {
|
describe("browser content cache worker", () => {
|
||||||
|
it.each(ARENA_STAGES)("loads bundled $name assets without an optional content install", async (stage) => {
|
||||||
|
const worker = contentWorker();
|
||||||
|
for (const asset of stage.assets) {
|
||||||
|
const response = await worker.request(`${asset.url}?arena-runtime=1`);
|
||||||
|
expect(response?.status).toBe(200);
|
||||||
|
expect(await response?.text()).toBe("bundled arena");
|
||||||
|
}
|
||||||
|
expect(worker.fetch).toHaveBeenCalledTimes(stage.assets.length);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("prefers installed arena updates over bundled files, ignoring the runtime query", async () => {
|
||||||
|
const worker = contentWorker(new Response("updated arena"));
|
||||||
|
const response = await worker.request(`${ARENA_STAGES[0].assets[0].url}?arena-runtime=1`);
|
||||||
|
expect(await response?.text()).toBe("updated arena");
|
||||||
|
expect(worker.match).toHaveBeenCalledWith(expect.any(Request), { ignoreSearch: true });
|
||||||
|
expect(worker.fetch).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("still blocks optional dungeon assets that have not been installed", async () => {
|
||||||
|
const worker = contentWorker();
|
||||||
|
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();
|
||||||
|
});
|
||||||
|
|
||||||
it("serves only cached same-origin asset requests from the active content cache", () => {
|
it("serves only cached same-origin asset requests from the active content cache", () => {
|
||||||
expect(workerSource).toContain(`const CONTENT_CACHE_NAME = "${BROWSER_CONTENT_CACHE_NAME}";`);
|
expect(workerSource).toContain(`const CONTENT_CACHE_NAME = "${BROWSER_CONTENT_CACHE_NAME}";`);
|
||||||
expect(workerSource).toContain('request.method !== "GET"');
|
expect(workerSource).toContain('request.method !== "GET"');
|
||||||
|
|||||||
Reference in new issue
Block a user