feat(web): add player rune store with basic actions
Core state (queue, index, state, position, duration, volume, shuffle, repeat, error) plus actions: playQueue, togglePlay, linear skipNext, skipPrev 3-second rule, seekTo, setVolume (localStorage-persisted), registerAudioEl, reportTimeUpdate, reportDuration. Shuffle/repeat logic and audio-event reporting land in follow-up commits. Also install an in-memory Storage polyfill in vitest.setup.ts: Node 25 exposes a partial localStorage global that lacks getItem/setItem/clear (requires --localstorage-file with a path), and jsdom defers to the Node global when present, leaving tests unable to exercise storage.
This commit is contained in:
@@ -1 +1,23 @@
|
||||
import '@testing-library/jest-dom/vitest';
|
||||
|
||||
// Node 25 ships a partial localStorage global that lacks getItem/setItem/clear
|
||||
// unless launched with --localstorage-file. jsdom sees Node's global and skips
|
||||
// installing its own. Replace with an in-memory Storage-compatible polyfill so
|
||||
// tests (and browser-only code under test) see a working localStorage.
|
||||
class MemoryStorage implements Storage {
|
||||
private store = new Map<string, string>();
|
||||
get length() { return this.store.size; }
|
||||
clear(): void { this.store.clear(); }
|
||||
getItem(key: string): string | null { return this.store.get(key) ?? null; }
|
||||
key(i: number): string | null { return Array.from(this.store.keys())[i] ?? null; }
|
||||
removeItem(key: string): void { this.store.delete(key); }
|
||||
setItem(key: string, value: string): void { this.store.set(key, String(value)); }
|
||||
}
|
||||
const memLocal = new MemoryStorage();
|
||||
const memSession = new MemoryStorage();
|
||||
Object.defineProperty(globalThis, 'localStorage', { configurable: true, value: memLocal });
|
||||
Object.defineProperty(globalThis, 'sessionStorage', { configurable: true, value: memSession });
|
||||
if (typeof window !== 'undefined') {
|
||||
Object.defineProperty(window, 'localStorage', { configurable: true, value: memLocal });
|
||||
Object.defineProperty(window, 'sessionStorage', { configurable: true, value: memSession });
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user