diff --git a/src/static/presets.js b/src/static/presets.js index bbc1308..23f24f4 100644 --- a/src/static/presets.js +++ b/src/static/presets.js @@ -637,20 +637,55 @@ document.addEventListener('DOMContentLoaded', () => { return payload; }; + const normalizePatternMap = (raw) => { + if (!raw) return {}; + if (typeof raw === 'object' && !Array.isArray(raw)) { + // Support wrapped payloads like { patterns: {...} }. + if (raw.patterns && typeof raw.patterns === 'object' && !Array.isArray(raw.patterns)) { + return raw.patterns; + } + return raw; + } + if (Array.isArray(raw)) { + // Support list payloads like [{name: "blink", ...}, ...]. + return raw.reduce((acc, item, idx) => { + if (item && typeof item === 'object') { + const name = item.name || item.id || String(idx); + acc[String(name)] = item; + } + return acc; + }, {}); + } + return {}; + }; + const loadPatterns = async () => { if (!presetPatternInput) { return; } try { // Load pattern definitions from pattern.json - const response = await fetch('/patterns/definitions', { + let patternsPayload = null; + let response = await fetch('/patterns/definitions', { headers: { Accept: 'application/json' }, }); - if (!response.ok) { - return; + if (response.ok) { + patternsPayload = await response.json(); } - const patterns = await response.json(); - cachedPatterns = patterns || {}; + + let normalized = normalizePatternMap(patternsPayload); + if (!Object.keys(normalized).length) { + // Fallback when definitions route is unavailable or returns an empty map. + response = await fetch('/patterns', { + headers: { Accept: 'application/json' }, + }); + if (!response.ok) { + return; + } + patternsPayload = await response.json(); + normalized = normalizePatternMap(patternsPayload); + } + cachedPatterns = normalized; const entries = Object.keys(cachedPatterns); const desiredPattern = presetPatternInput.value; presetPatternInput.innerHTML = '';