// lib/stores/products.ts
import { writable, derived } from 'svelte/store';
interface Product {
id: string;
name: string;
price: number;
category: string;
inStock: boolean;
}
interface Filters {
search: string;
category: string | null;
maxPrice: number;
inStockOnly: boolean;
}
function createProductStore() {
const products = writable<Map<string, Product>>(new Map());
const filters = writable<Filters>({
search: '',
category: null,
maxPrice: Infinity,
inStockOnly: false
});
const sort = writable<'name' | 'price'>('name');
const page = writable(1);
const pageSize = writable(20);
const filtered = derived([products, filters, sort], ([$prods, $filters, $sort]) => {
let items = Array.from($prods.values()).filter(p => {
const matchesSearch = p.name.toLowerCase().includes($filters.search.toLowerCase());
const matchesCategory = !$filters.category || p.category === $filters.category;
const matchesPrice = p.price <= $filters.maxPrice;
const matchesStock = !$filters.inStockOnly || p.inStock;
return matchesSearch && matchesCategory && matchesPrice && matchesStock;
});
items.sort((a, b) => {
if ($sort === 'price') return a.price - b.price;
return a.name.localeCompare(b.name);
});
return items;
});
const totalPages = derived([filtered, pageSize], ([$filtered, $pageSize]) =>
Math.ceil($filtered.length / $pageSize)
);
const paginatedProducts = derived([filtered, page, pageSize], ([$filtered, $page, $pageSize]) => {
const start = ($page - 1) * $pageSize;
return $filtered.slice(start, start + $pageSize);
});
return {
products: { subscribe: products.subscribe },
filters: { subscribe: filters.subscribe },
filtered: { subscribe: filtered.subscribe },
paginatedProducts: { subscribe: paginatedProducts.subscribe },
totalPages: { subscribe: totalPages.subscribe },
setFilter: (key: keyof Filters, value: any) => {
filters.update(f => ({ ...f, [key]: value }));
page.set(1);
},
setProducts: (prods: Product[]) => {
const map = new Map(prods.map(p => [p.id, p]));
products.set(map);
},
addProduct: (product: Product) => {
products.update(m => new Map(m).set(product.id, product));
}
};
}
export const productStore = createProductStore();