// [DEF:environmentContext:Store] // @TIER: STANDARD // @PURPOSE: Global selected environment context for navigation and safety cues. // @LAYER: UI-State import { derived, get, writable } from "svelte/store"; import { browser } from "$app/environment"; import { api } from "$lib/api.js"; const INITIAL_STATE = { environments: [], selectedEnvId: "", isLoading: false, isLoaded: false, error: null, }; const SELECTED_ENV_KEY = "selected_env_id"; const contextStore = writable(INITIAL_STATE); function getStoredSelectedEnvId() { if (!browser) return ""; return localStorage.getItem(SELECTED_ENV_KEY) || ""; } function persistSelectedEnvId(envId) { if (!browser) return; if (!envId) { localStorage.removeItem(SELECTED_ENV_KEY); return; } localStorage.setItem(SELECTED_ENV_KEY, envId); } function hasAuthToken() { if (!browser) return false; return Boolean(localStorage.getItem("auth_token")); } function resolveSelectedEnvId(environments, preferredEnvId) { if (!Array.isArray(environments) || environments.length === 0) return ""; if (preferredEnvId && environments.some((env) => env.id === preferredEnvId)) { return preferredEnvId; } const stored = getStoredSelectedEnvId(); if (stored && environments.some((env) => env.id === stored)) { return stored; } return environments[0].id; } function applySelectedEnvId(selectedEnvId) { contextStore.update((state) => { const exists = state.environments.some((env) => env.id === selectedEnvId); const nextSelectedEnvId = exists ? selectedEnvId : ""; persistSelectedEnvId(nextSelectedEnvId); return { ...state, selectedEnvId: nextSelectedEnvId }; }); } async function refreshEnvironmentContext(preferredEnvId = "") { if (!hasAuthToken()) { contextStore.update((state) => ({ ...state, isLoading: false, isLoaded: false, error: null, })); return; } contextStore.update((state) => ({ ...state, isLoading: true, error: null })); try { const environments = await api.getEnvironmentsList(); const current = get(contextStore).selectedEnvId; const selectedEnvId = resolveSelectedEnvId( environments, preferredEnvId || current, ); persistSelectedEnvId(selectedEnvId); contextStore.update((state) => ({ ...state, environments, selectedEnvId, isLoading: false, isLoaded: true, error: null, })); } catch (error) { if (error?.status === 401) { contextStore.update((state) => ({ ...state, isLoading: false, isLoaded: false, error: null, })); return; } console.error( "[environmentContext][Coherence:Failed] Failed to refresh environments", error, ); contextStore.update((state) => ({ ...state, environments: [], selectedEnvId: "", isLoading: false, isLoaded: true, error: error?.message || "Failed to load environments", })); } } async function initializeEnvironmentContext() { const state = get(contextStore); if (state.isLoading || state.isLoaded) return; await refreshEnvironmentContext(); } export const environmentContextStore = { subscribe: contextStore.subscribe, }; export function setSelectedEnvironment(envId) { applySelectedEnvId(envId); } export { refreshEnvironmentContext, initializeEnvironmentContext }; export const selectedEnvironmentStore = derived( environmentContextStore, ($context) => $context.environments.find((env) => env.id === $context.selectedEnvId) || null, ); export const isProductionContextStore = derived( selectedEnvironmentStore, ($selectedEnvironment) => Boolean($selectedEnvironment?.is_production), ); // [/DEF:environmentContext:Store]