mirror of
https://github.com/rommapp/romm.git
synced 2026-06-27 22:35:57 +00:00
Merge branch 'master' into claude/server-side-rom-patching-EaQck
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { mount } from "@vue/test-utils";
|
||||
import { createPinia, setActivePinia } from "pinia";
|
||||
import { beforeEach, describe, expect, it } from "vitest";
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { defineComponent } from "vue";
|
||||
import storeGalleryRoms from "@/v2/stores/galleryRoms";
|
||||
import { getCoverRatio, setCoverRatio, useGalleryCoverRatios } from "./index";
|
||||
@@ -58,6 +58,30 @@ describe("useGalleryCoverRatios", () => {
|
||||
onCardRatio({ romId: 301, ratio: 0.9 }); // delta 0.2 ≥ 0.01 → updates
|
||||
expect(ratioAt(0)).toBeCloseTo(0.9);
|
||||
});
|
||||
|
||||
// Regression: GameCover writes the shared `ratioByKey` store (setCoverRatio)
|
||||
// synchronously BEFORE emitting `@ratio`. Deduping the re-pack against that
|
||||
// same store made the first report look like "no change", so the flow-packer
|
||||
// never reflowed off its default ratio and wide covers overflowed the row.
|
||||
it("schedules a re-pack when the shared store was pre-seeded by the cover", () => {
|
||||
vi.useFakeTimers();
|
||||
try {
|
||||
storeGalleryRoms().romIdIndex = [501];
|
||||
const { ratioVersion, onCardRatio } = withComposable(() =>
|
||||
useGalleryCoverRatios(),
|
||||
);
|
||||
|
||||
// Cover paints first: seed the shared map, then emit the same ratio.
|
||||
setCoverRatio({ romId: 501 }, 1.0);
|
||||
const before = ratioVersion.value;
|
||||
onCardRatio({ romId: 501, ratio: 1.0 });
|
||||
|
||||
vi.advanceTimersByTime(400);
|
||||
expect(ratioVersion.value).toBe(before + 1);
|
||||
} finally {
|
||||
vi.useRealTimers();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("getCoverRatio / setCoverRatio (shared store)", () => {
|
||||
|
||||
@@ -79,6 +79,8 @@ export function useGalleryCoverRatios() {
|
||||
const ratioVersion = ref(0);
|
||||
const maxRatio = ref(0);
|
||||
let bumpTimer: ReturnType<typeof setTimeout> | null = null;
|
||||
// Ratios already folded into the packed layout.
|
||||
const packedRatio = new Map<number, number>();
|
||||
|
||||
/** Record a cover's measured ratio (GameCard's `@ratio` handler). Reads
|
||||
* /writes the map directly by numeric rom id — no key object / string. */
|
||||
@@ -86,8 +88,9 @@ export function useGalleryCoverRatios() {
|
||||
// Track the max on every report (even cached re-paints with an
|
||||
// unchanged ratio) so it rebuilds correctly after a context reset.
|
||||
if (payload.ratio > maxRatio.value) maxRatio.value = payload.ratio;
|
||||
const prev = ratioByKey.get(payload.romId);
|
||||
const prev = packedRatio.get(payload.romId);
|
||||
if (prev != null && Math.abs(prev - payload.ratio) < RATIO_EPSILON) return;
|
||||
packedRatio.set(payload.romId, payload.ratio);
|
||||
ratioByKey.set(payload.romId, payload.ratio);
|
||||
if (bumpTimer) return;
|
||||
bumpTimer = setTimeout(() => {
|
||||
|
||||
@@ -118,6 +118,12 @@ export default defineConfig(({ mode }) => {
|
||||
extensions: [".js", ".json", ".jsx", ".mjs", ".ts", ".tsx", ".vue"],
|
||||
},
|
||||
server: {
|
||||
watch: {
|
||||
// Never crawl the served library resources: this path is a symlink
|
||||
// into the user's library (covers, screenshots) and can hold hundreds
|
||||
// of thousands of files, which OOMs the dev server's file watcher.
|
||||
ignored: ["**/assets/romm/resources/**", "**/assets/romm/resources"],
|
||||
},
|
||||
proxy: {
|
||||
"/api": {
|
||||
target: `http://127.0.0.1:${backendPort}`,
|
||||
|
||||
Reference in New Issue
Block a user