Files
2eInk/src/lib/stores/pipeline.svelte.ts
patrick d02c8d281a feat: add pipeline store
- Global pipeline configuration
- Built-in and user presets
- localStorage persistence
- Preset CRUD operations

Co-Authored-By: Claude <noreply@anthropic.com>
2026-05-13 18:12:21 -04:00

157 lines
3.6 KiB
TypeScript

import {
type PipelineConfig,
type PipelinePreset,
DEFAULT_PIPELINE_CONFIG,
BUILT_IN_PRESETS,
clonePipelineConfig
} from '$lib/types';
const STORAGE_KEY = '2eink-pipeline-presets';
function createPipelineStore() {
let globalConfig = $state<PipelineConfig>(clonePipelineConfig(DEFAULT_PIPELINE_CONFIG));
let selectedPresetId = $state<string | null>('default');
let userPresets = $state<PipelinePreset[]>([]);
const allPresets = $derived<PipelinePreset[]>([...BUILT_IN_PRESETS, ...userPresets]);
const selectedPreset = $derived<PipelinePreset | null>(
allPresets.find((p) => p.id === selectedPresetId) ?? null
);
const isModified = $derived<boolean>(() => {
if (!selectedPreset) return true;
return JSON.stringify(globalConfig) !== JSON.stringify(selectedPreset.config);
});
function loadPresets(): void {
if (typeof window === 'undefined') return;
try {
const stored = localStorage.getItem(STORAGE_KEY);
if (stored) {
userPresets = JSON.parse(stored);
}
} catch {
console.warn('Failed to load pipeline presets');
}
}
function savePresets(): void {
if (typeof window === 'undefined') return;
try {
localStorage.setItem(STORAGE_KEY, JSON.stringify(userPresets));
} catch {
console.warn('Failed to save pipeline presets');
}
}
function selectPreset(presetId: string): void {
const preset = allPresets.find((p) => p.id === presetId);
if (preset) {
globalConfig = clonePipelineConfig(preset.config);
selectedPresetId = presetId;
}
}
function updateConfig(updates: Partial<PipelineConfig>): void {
globalConfig = { ...globalConfig, ...updates };
}
function updateStep<K extends keyof PipelineConfig>(
step: K,
updates: Partial<PipelineConfig[K]>
): void {
globalConfig = {
...globalConfig,
[step]: { ...globalConfig[step], ...updates }
};
}
function saveAsPreset(name: string): PipelinePreset {
const id = `user-${Date.now()}`;
const preset: PipelinePreset = {
id,
name,
config: clonePipelineConfig(globalConfig),
isBuiltIn: false
};
userPresets = [...userPresets, preset];
selectedPresetId = id;
savePresets();
return preset;
}
function updatePreset(presetId: string): void {
const index = userPresets.findIndex((p) => p.id === presetId);
if (index === -1) return;
userPresets = userPresets.map((p) =>
p.id === presetId ? { ...p, config: clonePipelineConfig(globalConfig) } : p
);
savePresets();
}
function deletePreset(presetId: string): void {
const preset = userPresets.find((p) => p.id === presetId);
if (!preset || preset.isBuiltIn) return;
userPresets = userPresets.filter((p) => p.id !== presetId);
if (selectedPresetId === presetId) {
selectPreset('default');
}
savePresets();
}
function renamePreset(presetId: string, newName: string): void {
userPresets = userPresets.map((p) => (p.id === presetId ? { ...p, name: newName } : p));
savePresets();
}
function resetToDefault(): void {
selectPreset('default');
}
function getEffectiveConfig(imageOverride: PipelineConfig | null): PipelineConfig {
return imageOverride ?? globalConfig;
}
if (typeof window !== 'undefined') {
loadPresets();
}
return {
get globalConfig() {
return globalConfig;
},
get selectedPresetId() {
return selectedPresetId;
},
get selectedPreset() {
return selectedPreset;
},
get allPresets() {
return allPresets;
},
get userPresets() {
return userPresets;
},
get isModified() {
return isModified;
},
selectPreset,
updateConfig,
updateStep,
saveAsPreset,
updatePreset,
deletePreset,
renamePreset,
resetToDefault,
getEffectiveConfig,
loadPresets
};
}
export const pipelineStore = createPipelineStore();