The visualizer's PCM cache decoded the entire episode into RAM (22050 Hz mono s16 ~160 MB/hr of audio) and held it until stop() — a 3-hour episode pinned ~500 MB and long-form content hit 2.5 GB. The 4x decode also pulled the whole remote file even when only minutes were listened to. - audio-pcm-cache: sliding window around the playback position — the decode head caps at maxAheadSec (600s) ahead of the cursor, segments older than keepBehindSec (300s) are pruned, and the tail refills as playback advances. Steady state ~40 MB regardless of episode length; a backward seek past the window restarts a segment there (the existing seek-hole mechanism, no new failure mode). - feed: cap the full-parse episode cache at 1000 episodes/feed so archive-heavy subscriptions can't pin their entire history in RAM; the visible list stays bounded by the user's cache preference and fetch-more keeps working within the ceiling. - tests: pin the new head-cap and prune contracts (8/8 in audio-pcm-cache.test.ts; full suite 193 pass). Also includes the in-flight cleanup/refactor pass (cover-art resolve helper, page and comment tightening, ESLint config removal).
45 lines
1.1 KiB
TypeScript
45 lines
1.1 KiB
TypeScript
/**
|
|
* Theme observer utility for detecting and responding to theme changes.
|
|
*
|
|
* This module provides utilities for:
|
|
* - Listening to SIGUSR2 signals for theme reload
|
|
* - Emitting theme change events via the event bus
|
|
* - Tracking theme change state
|
|
*/
|
|
|
|
import { emit } from "./event-bus"
|
|
|
|
function emitThemeReload(): void {
|
|
emit("theme.reload", {})
|
|
}
|
|
|
|
export function emitThemeChanged(theme: string, mode: "dark" | "light"): void {
|
|
emit("theme.changed", { theme, mode })
|
|
}
|
|
|
|
export function emitThemeModeChanged(mode: "dark" | "light"): void {
|
|
emit("theme.mode.changed", { mode })
|
|
}
|
|
|
|
/**
|
|
* Setup SIGUSR2 signal handler for theme reload.
|
|
* This allows external tools to trigger a theme refresh by sending SIGUSR2 to the process.
|
|
*
|
|
* Usage: `kill -USR2 <pid>` to trigger a theme reload
|
|
*
|
|
* @param onReload - Callback to execute when SIGUSR2 is received
|
|
* @returns Cleanup function to remove the handler
|
|
*/
|
|
export function setupThemeSignalHandler(onReload: () => void): () => void {
|
|
const handler = () => {
|
|
emitThemeReload()
|
|
onReload()
|
|
}
|
|
|
|
process.on("SIGUSR2", handler)
|
|
|
|
return () => {
|
|
process.off("SIGUSR2", handler)
|
|
}
|
|
}
|