State single source of truth

Generated 2026-10-05 from the code by scripts/state-ssot-doc.py (D-322d T-36, CHECKLIST 4.1). Rule: each piece of client state has one owner module, and components read and change it only through that owner.

Owners

ConcernOwner moduleExportslocalStorage keysImporters
Screen-reader announcementssrc/lib/core/state/a11yState.svelte.jsa11yStatenone3
Theme and app shell (sidebar, drawer)src/lib/core/state/appState.svelte.jsAppState, appStatebeetle-theme6
Drag and dropsrc/lib/core/state/dndState.svelte.jsdndStatenone2
Library filter panelsrc/lib/core/state/filterPanelState.svelte.jsFilterPanelState, filterPanelStatenone2
Keyboard shortcutssrc/lib/core/state/shortcutState.svelte.jsshortcutStatebeetle-settings, beetle-shortcuts2
Toast notificationssrc/lib/core/state/toastState.svelte.jstoastStatenone13
UI settingssrc/lib/core/state/uiSettingsState.svelte.jsRATING_STYLES, HEART_COLORS, UiSettingsState, uiSettingsStatebeetle-ui-settings2
Library folders (sidebar)src/lib/features/library/LibraryState.svelte.jsLibraryStatenone1
Playlists (sidebar and playlist pages, v2 API)src/lib/features/playlists/PlaylistState.svelte.jsPlaylistState, setPlaylistState, getPlaylistStatenone4
Player queue and playbacksrc/lib/features/player/PlayerState.svelte.jsPlayerState, playerStatenone3

Theme

  • appState.theme owns the theme. src/lib/features/settings/themeCatalog.js validates it, and it persists under beetle-theme, which src/app.html reads before hydration to avoid a flash.
  • No second theme or UI-settings store is left: the legacy stores listed below are deleted.
  • The per-theme text-contrast fixes in the generated block at the end of src/lib/app.css (scripts/theme-contrast-audit.py) change colours only, not who owns the theme.

Direct localStorage access outside the owners

FileKeys
src/lib/features/player/EQControls.sveltebeetle-eq-settings
src/lib/ui/feedback/ToastManager.sveltebeetle-settings
src/lib/ui/layout/Sidebar.sveltebeetle-folder-sort
src/routes/settings/+page.jsbeetle-settings
src/routes/settings/+page.sveltebeetle-settings

Plan

  1. New client state goes into the owner of its concern, or into a new *State.svelte.js owner added to this table. Components do not call localStorage themselves.
  2. Each file in the direct-access table moves its keys into the owner of that concern the next time the file changes.
  3. Regenerate this page after state changes: python3 scripts/state-ssot-doc.py.

Deleted legacy stores

  • src/lib/core/state/themeState.svelte.js
  • src/lib/features/player/store.js
  • src/lib/stores/playlistStore.js
  • src/lib/stores/shortcutStore.js
  • src/lib/stores/themeStore.js