refactor: address Copilot review on debug overlay

- Lazy-load DebugOverlay via defineAsyncComponent so its chunk (and the
  vueuse perf hooks it pulls in) stays out of the default bundle until the
  developer toggle is enabled.
- Add useDebugMode unit tests mirroring useCrtMode: default-off, persisted
  restore, write-through, and singleton sharing.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
zurdi
2026-06-20 09:21:43 +00:00
parent eb1b477013
commit 90777d5cbb
2 changed files with 62 additions and 2 deletions

View File

@@ -0,0 +1,50 @@
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { nextTick } from "vue";
const KEY = "settings.v2.debugMode";
// `enabled` is a module-level singleton created at import time, so it reads
// localStorage exactly once on load. Re-import the module fresh after seeding
// storage to exercise the default / persisted-read paths in isolation.
async function loadFresh() {
vi.resetModules();
const { useDebugMode } = await import("./index");
return useDebugMode();
}
beforeEach(() => {
localStorage.clear();
});
afterEach(() => {
localStorage.clear();
});
describe("useDebugMode", () => {
it("defaults to off when nothing is persisted", async () => {
const { enabled } = await loadFresh();
expect(enabled.value).toBe(false);
});
it("restores a previously persisted value on load", async () => {
localStorage.setItem(KEY, "true");
const { enabled } = await loadFresh();
expect(enabled.value).toBe(true);
});
it("persists changes under the 'settings.v2.debugMode' key", async () => {
const { enabled } = await loadFresh();
enabled.value = true;
await nextTick();
expect(localStorage.getItem(KEY)).toBe("true");
});
it("shares a single instance across calls within a load", async () => {
vi.resetModules();
const { useDebugMode } = await import("./index");
const a = useDebugMode();
const b = useDebugMode();
a.enabled.value = true;
expect(b.enabled.value).toBe(true);
});
});

View File

@@ -9,7 +9,13 @@
// Per-ROM action menus are not app-wide: each GameCard owns its own
// `MoreMenu` dropdown on the three-dots button. Right-click is left to
// the browser so "Open in new tab" etc. keep working.
import { onBeforeUnmount, onMounted, provide, ref } from "vue";
import {
defineAsyncComponent,
onBeforeUnmount,
onMounted,
provide,
ref,
} from "vue";
import { useRouter } from "vue-router";
import storeCollections from "@/stores/collections";
import storePlatforms from "@/stores/platforms";
@@ -17,7 +23,6 @@ import AppNav from "@/v2/components/AppShell/AppNav.vue";
import BackgroundArt from "@/v2/components/AppShell/BackgroundArt.vue";
import BottomNav from "@/v2/components/AppShell/BottomNav.vue";
import CrtOverlay from "@/v2/components/AppShell/CrtOverlay.vue";
import DebugOverlay from "@/v2/components/AppShell/DebugOverlay.vue";
import GlobalDialogs from "@/v2/components/Dialogs/GlobalDialogs.vue";
import SoundtrackMiniPlayer from "@/v2/components/Soundtrack/MiniPlayer.vue";
import { BACKGROUND_ART_KEY } from "@/v2/composables/useBackgroundArt";
@@ -46,7 +51,12 @@ const collectionsStore = storeCollections();
const platformsStore = storePlatforms();
// Developer debug overlay — opt-in via Settings → Developer (per-device).
// Lazily loaded so its chunk (and the vueuse perf hooks it pulls in) is only
// fetched once the toggle is on, keeping it out of the default bundle.
const { enabled: debugEnabled } = useDebugMode();
const DebugOverlay = defineAsyncComponent(
() => import("@/v2/components/AppShell/DebugOverlay.vue"),
);
// Shared reactive background art — views paint covers via the injected setter.
const layerA = ref<string | null>(null);