feature/searchbar-enhance #17
@@ -0,0 +1,80 @@
|
|||||||
|
import { SvelteMap } from 'svelte/reactivity';
|
||||||
|
|
||||||
|
export interface Entity {
|
||||||
|
id: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Svelte 5 Entity Store
|
||||||
|
* Uses SvelteMap for O(1) lookups and granular reactivity.
|
||||||
|
*/
|
||||||
|
export class EntityStore<T extends Entity> {
|
||||||
|
// SvelteMap is a reactive version of the native Map
|
||||||
|
#entities = new SvelteMap<string, T>();
|
||||||
|
|
||||||
|
constructor(initialEntities: T[] = []) {
|
||||||
|
this.setAll(initialEntities);
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Selectors (Equivalent to Selectors) ---
|
||||||
|
|
||||||
|
/** Get all entities as an array */
|
||||||
|
get all() {
|
||||||
|
return Array.from(this.#entities.values());
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Select a single entity by ID */
|
||||||
|
getById(id: string) {
|
||||||
|
return this.#entities.get(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Select multiple entities by IDs */
|
||||||
|
getByIds(ids: string[]) {
|
||||||
|
return ids.map(id => this.#entities.get(id)).filter((e): e is T => !!e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Actions (CRUD) ---
|
||||||
|
|
||||||
|
addOne(entity: T) {
|
||||||
|
this.#entities.set(entity.id, entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
addMany(entities: T[]) {
|
||||||
|
entities.forEach(e => this.addOne(e));
|
||||||
|
}
|
||||||
|
|
||||||
|
updateOne(id: string, changes: Partial<T>) {
|
||||||
|
const entity = this.#entities.get(id);
|
||||||
|
if (entity) {
|
||||||
|
// In Svelte 5, updating the object property directly is reactive
|
||||||
|
// if the object itself was made reactive, but here we replace
|
||||||
|
// the reference to ensure top-level map triggers.
|
||||||
|
this.#entities.set(id, { ...entity, ...changes });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
removeOne(id: string) {
|
||||||
|
this.#entities.delete(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
removeMany(ids: string[]) {
|
||||||
|
ids.forEach(id => this.#entities.delete(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
setAll(entities: T[]) {
|
||||||
|
this.#entities.clear();
|
||||||
|
this.addMany(entities);
|
||||||
|
}
|
||||||
|
|
||||||
|
has(id: string) {
|
||||||
|
return this.#entities.has(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
clear() {
|
||||||
|
this.#entities.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createEntityStore<T extends Entity>(initialEntities: T[] = []) {
|
||||||
|
return new EntityStore<T>(initialEntities);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user