Files
frontend-svelte/src/shared/lib/helpers/createEntityStore/createEntityStore.svelte.ts
2026-02-01 11:52:58 +03:00

83 lines
1.9 KiB
TypeScript

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) {
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();
}
}
/**
* Creates a new EntityStore instance with the given initial entities.
* @param initialEntities The initial entities to populate the store with.
* @returns - A new EntityStore instance.
*/
export function createEntityStore<T extends Entity>(initialEntities: T[] = []) {
return new EntityStore<T>(initialEntities);
}