- Delete legacy .ts stores (auth, activity, assistantChat, datasetReview, environmentContext, health, sidebar, taskDrawer, translationRun) - Create new .svelte.ts runes-based stores using reactive primitives - Migrate i18n: /i18n → /i18n/index.svelte.js - Migrate toasts: /toasts → /toasts.svelte.js - Update all component imports across 180+ files: components, pages, routes, lib - Remove fromStore() wrappers — use store.value directly with Svelte 5 runes - Update test mocks for new import paths - Add @DEPRECATED annotation to legacy alias
98 lines
4.0 KiB
TypeScript
98 lines
4.0 KiB
TypeScript
// #region StoresModule [C:3] [TYPE Module] [SEMANTICS store, state, $state, plugins, tasks]
|
|
// @BRIEF Global Svelte 5 rune-based store atoms for plugins, tasks, and UI page state.
|
|
// @LAYER UI
|
|
// @RELATION DEPENDS_ON -> [ApiModule]
|
|
// @POST All stores are initialized with sensible defaults. fetchPlugins/fetchTasks populate on call.
|
|
// @RATIONALE Migrated from Svelte 4 writable stores to Svelte 5 $state runes.
|
|
// Keeps .subscribe(), .set(), .update(), and .current for backward compat.
|
|
// Uses explicit _notify() calls instead of $effect to avoid effect_orphan in test contexts.
|
|
|
|
import { api } from './api';
|
|
import type { Plugin, Task } from '../types/models';
|
|
|
|
// ── Helper to create a rune-backed store atom ───────────────────
|
|
function createWritableAtom<T>(initial: T) {
|
|
let value = $state(initial) as T;
|
|
const subs = new Set<(v: T) => void>();
|
|
|
|
function _notify() {
|
|
const snapshot = value;
|
|
subs.forEach(fn => fn(snapshot));
|
|
}
|
|
|
|
return {
|
|
get current() { return value; },
|
|
set current(v: T) { value = v; _notify(); },
|
|
set(v: T) { value = v; _notify(); },
|
|
update(fn: (v: T) => T) { value = fn(value); _notify(); },
|
|
subscribe(fn: (v: T) => void) {
|
|
fn(value);
|
|
subs.add(fn);
|
|
return () => subs.delete(fn);
|
|
},
|
|
};
|
|
}
|
|
|
|
// ═══════════════════════════════════════════════════════════════════
|
|
// Store atoms
|
|
// ═══════════════════════════════════════════════════════════════════
|
|
|
|
// #region plugins [C:2] [TYPE Store] [SEMANTICS plugins, store]
|
|
export const plugins = createWritableAtom<Plugin[]>([]);
|
|
// #endregion plugins
|
|
|
|
// #region tasks [C:2] [TYPE Store] [SEMANTICS tasks, store]
|
|
export const tasks = createWritableAtom<Task[]>([]);
|
|
// #endregion tasks
|
|
|
|
// #region selectedPlugin [C:1] [TYPE Store]
|
|
export const selectedPlugin = createWritableAtom<Plugin | null>(null);
|
|
// #endregion selectedPlugin
|
|
|
|
// #region selectedTask [C:1] [TYPE Store]
|
|
export const selectedTask = createWritableAtom<Task | null>(null);
|
|
// #endregion selectedTask
|
|
|
|
// #region currentPage [C:1] [TYPE Store]
|
|
export const currentPage = createWritableAtom<string>('dashboard');
|
|
// #endregion currentPage
|
|
|
|
// #region taskLogs [C:1] [TYPE Store]
|
|
export const taskLogs = createWritableAtom<unknown[]>([]);
|
|
// #endregion taskLogs
|
|
|
|
// ═══════════════════════════════════════════════════════════════════
|
|
// Fetch functions
|
|
// ═══════════════════════════════════════════════════════════════════
|
|
|
|
// #region fetchPlugins [C:2] [TYPE Function] [SEMANTICS plugins, fetch]
|
|
// @BRIEF Fetches plugins from the API and updates the plugins store.
|
|
// @PRE None.
|
|
// @POST plugins store is updated with data from the API.
|
|
// @SIDE_EFFECT Makes API call; updates reactive store on success.
|
|
export async function fetchPlugins(): Promise<void> {
|
|
try {
|
|
const data = await api.getPlugins<Plugin[]>();
|
|
plugins.set(data);
|
|
} catch (error) {
|
|
console.error(`[stores.fetchPlugins] Error fetching plugins:`, error);
|
|
}
|
|
}
|
|
// #endregion fetchPlugins
|
|
|
|
// #region fetchTasks [C:2] [TYPE Function] [SEMANTICS tasks, fetch]
|
|
// @BRIEF Fetches tasks from the API and updates the tasks store.
|
|
// @PRE None.
|
|
// @POST tasks store is updated with data from the API.
|
|
// @SIDE_EFFECT Makes API call; updates reactive store on success.
|
|
export async function fetchTasks(): Promise<void> {
|
|
try {
|
|
const data = await api.getTasks<Task[]>();
|
|
tasks.set(data);
|
|
} catch (error) {
|
|
console.error(`[stores.fetchTasks] Error fetching tasks:`, error);
|
|
}
|
|
}
|
|
// #endregion fetchTasks
|
|
// #endregion StoresModule
|