Add reusable DataCache class, unify frontend cache patterns

- Create DataCache class with fetch deduplication, invalidation, subscribers
- Instantiate 10 cache instances in state.js (streams, templates, sources, etc.)
- Replace inline fetch+parse+set patterns with cache.fetch() calls across modules
- Eliminate dual _scenesCache/_presetsCache sync via shared scenePresetsCache
- Remove 9 now-unused setter functions from state.js
- Clean up unused setter imports from audio-sources, value-sources, displays

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-28 19:35:20 +03:00
parent ff4e7f8adb
commit a34edf9650
11 changed files with 220 additions and 176 deletions

View File

@@ -11,14 +11,11 @@ import { CardSection } from '../core/card-sections.js';
import {
ICON_SCENE, ICON_CAPTURE, ICON_START, ICON_EDIT, ICON_REFRESH, ICON_TARGET,
} from '../core/icons.js';
import { scenePresetsCache } from '../core/state.js';
let _presetsCache = [];
let _editingId = null;
let _allTargets = []; // fetched on capture open
/** Update the internal presets cache (called from automations tab after fetching). */
export function updatePresetsCache(presets) { _presetsCache = presets; }
class ScenePresetEditorModal extends Modal {
constructor() { super('scene-preset-editor-modal'); }
snapshotValues() {
@@ -74,15 +71,7 @@ export function createSceneCard(preset) {
// ===== Dashboard section (compact cards) =====
export async function loadScenePresets() {
try {
const resp = await fetchWithAuth('/scene-presets');
if (!resp.ok) return [];
const data = await resp.json();
_presetsCache = data.presets || [];
return _presetsCache;
} catch {
return [];
}
return scenePresetsCache.fetch();
}
export function renderScenePresetsSection(presets) {
@@ -153,7 +142,7 @@ export async function openScenePresetCapture() {
// ===== Edit metadata =====
export async function editScenePreset(presetId) {
const preset = _presetsCache.find(p => p.id === presetId);
const preset = scenePresetsCache.data.find(p => p.id === presetId);
if (!preset) return;
_editingId = presetId;
@@ -295,7 +284,7 @@ export async function activateScenePreset(presetId) {
// ===== Recapture =====
export async function recaptureScenePreset(presetId) {
const preset = _presetsCache.find(p => p.id === presetId);
const preset = scenePresetsCache.data.find(p => p.id === presetId);
const name = preset ? preset.name : presetId;
const confirmed = await showConfirm(t('scenes.recapture_confirm', { name }));
if (!confirmed) return;
@@ -319,7 +308,7 @@ export async function recaptureScenePreset(presetId) {
// ===== Delete =====
export async function deleteScenePreset(presetId) {
const preset = _presetsCache.find(p => p.id === presetId);
const preset = scenePresetsCache.data.find(p => p.id === presetId);
const name = preset ? preset.name : presetId;
const confirmed = await showConfirm(t('scenes.delete_confirm', { name }));
if (!confirmed) return;