refactor(lib): consolidate generic infra into src/lib

Move domain-agnostic, feature-free helpers out of the flat utils/ and store/
roots into src/lib/ (plan M4, §3 lib/ layer):
- lib/format/: formatBytes, formatClockTime, formatDuration, formatHumanDuration,
  relativeTime (pure format/date/byte/clock helpers)
- lib/i18n.ts: i18next bootstrap (global app infra)
- lib/util/: sanitizeHtml, platform, dedupeById, safeStorage (pure helpers +
  the zustand storage adapter)

playbackScheduleFormat stays in utils/format (runtime usePlayerStore dep =
audio-core coupling, not generic). formatClockTime keeps a type-only
@/store/authStoreTypes import (erased, no runtime inversion — accepted per the
deviceSync precedent).

Pure move via deep @/lib/* specifiers (no barrel → no mock-collapse surface).
tsc 0, lint 0/0, full suite 319 files / 2353 tests green.

Tooling note: lib_move.py regex extended to also rewrite side-effect imports
(import './i18n') and vi.importActual paths — both were silent gaps.
This commit is contained in:
Psychotoxical
2026-06-30 08:07:04 +02:00
parent 8cc022581f
commit 209dd61442
103 changed files with 119 additions and 119 deletions
@@ -10,7 +10,7 @@ import {
import type { SeekbarStyle, WindowButtonStyle } from '@/store/authStoreTypes';
import { useFontStore, FontId } from '@/store/fontStore';
import { useThemeStore } from '@/store/themeStore';
import { IS_LINUX, IS_WINDOWS } from '@/utils/platform';
import { IS_LINUX, IS_WINDOWS } from '@/lib/util/platform';
import SettingsSubSection from '@/features/settings/components/SettingsSubSection';
import { SettingsGroup } from '@/features/settings/components/SettingsGroup';
import { SettingsToggle } from '@/features/settings/components/SettingsToggle';
@@ -8,7 +8,7 @@ import { SettingsGroup } from '@/features/settings/components/SettingsGroup';
import { SettingsToggle } from '@/features/settings/components/SettingsToggle';
import { effectiveLoudnessPreAnalysisAttenuationDb } from '@/utils/audio/loudnessPreAnalysisSlider';
import { useAudioDevicesProbe } from '@/hooks/useAudioDevicesProbe';
import { IS_MACOS } from '@/utils/platform';
import { IS_MACOS } from '@/lib/util/platform';
import { AudioOutputDeviceSection } from '@/features/settings/components/audio/AudioOutputDeviceSection';
import { NormalizationBlock } from '@/features/settings/components/audio/NormalizationBlock';
import { PlaybackRateBlock } from '@/features/settings/components/audio/PlaybackRateBlock';
@@ -17,7 +17,7 @@ import { clearDiskSrcCacheForServer } from '@/cover/diskSrcCache';
import { serverListDisplayLabel } from '@/utils/server/serverDisplayName';
import { serverIndexKeyForProfile } from '@/utils/server/serverIndexKey';
import { showToast } from '@/utils/ui/toast';
import { formatBytes } from '@/utils/format/formatBytes';
import { formatBytes } from '@/lib/format/formatBytes';
import { clearImageCache, getImageCacheSize } from '@/utils/imageCache';
import { wakeLibraryCoverBackfill } from '@/utils/library/coverBackfillWake';
import {
@@ -6,7 +6,7 @@ import { Download, FolderOpen, Trash2, X } from 'lucide-react';
import { useAuthStore } from '@/store/authStore';
import { countHotCacheTracks } from '@/store/hotCacheStore';
import { useLocalPlaybackStore } from '@/store/localPlaybackStore';
import { formatBytes, snapHotCacheMb } from '@/utils/format/formatBytes';
import { formatBytes, snapHotCacheMb } from '@/lib/format/formatBytes';
import SettingsSubSection from '@/features/settings/components/SettingsSubSection';
import { SettingsGroup } from '@/features/settings/components/SettingsGroup';
import { SettingsToggle } from '@/features/settings/components/SettingsToggle';
@@ -6,10 +6,10 @@ import { save as saveDialog } from '@tauri-apps/plugin-dialog';
import { open as openUrl } from '@tauri-apps/plugin-shell';
import { AppWindow, ChevronDown, Download, ExternalLink, Globe, HardDrive, Info, Scale, Sliders, Users } from 'lucide-react';
import { version as appVersion } from '@/../package.json';
import i18n from '@/i18n';
import i18n from '@/lib/i18n';
import { useAuthStore } from '@/store/authStore';
import type { ClockFormat, LinuxWaylandTextRenderProfile, LoggingMode } from '@/store/authStoreTypes';
import { IS_LINUX } from '@/utils/platform';
import { IS_LINUX } from '@/lib/util/platform';
import { showToast } from '@/utils/ui/toast';
import { AboutPsysonicBrandHeader } from '@/components/AboutPsysonicLol';
import CustomSelect from '@/ui/CustomSelect';
@@ -6,7 +6,7 @@ import CoverLightbox from '@/components/CoverLightbox';
import { useThemeAnimationRisk } from '@/hooks/useThemeAnimationRisk';
import { AnimatedThemeBadge } from '@/features/settings/components/AnimatedThemeBadge';
import CustomSelect from '@/ui/CustomSelect';
import { formatRelativeTime } from '@/utils/format/relativeTime';
import { formatRelativeTime } from '@/lib/format/relativeTime';
import { useThemeStore } from '@/store/themeStore';
import { useInstalledThemesStore, type InstalledTheme } from '@/store/installedThemesStore';
import {