46 lines
981 B
TypeScript
46 lines
981 B
TypeScript
|
|
import {Signal, signal} from "@preact/signals-core";
|
||
|
|
|
||
|
|
export type Entity = {
|
||
|
|
id: string;
|
||
|
|
};
|
||
|
|
|
||
|
|
export type EntityAccessor<T extends Entity> = {
|
||
|
|
id: string;
|
||
|
|
value: T;
|
||
|
|
}
|
||
|
|
|
||
|
|
export function createEntityCollection<T extends Entity>() {
|
||
|
|
const collection = signal({} as Record<string, Signal<T>>);
|
||
|
|
const remove = (...ids: string[]) => {
|
||
|
|
collection.value = Object.fromEntries(
|
||
|
|
Object.entries(collection.value).filter(([id]) => !ids.includes(id)),
|
||
|
|
);
|
||
|
|
};
|
||
|
|
|
||
|
|
const add = (...entities: T[]) => {
|
||
|
|
collection.value = {
|
||
|
|
...collection.value,
|
||
|
|
...Object.fromEntries(entities.map((entity) => [entity.id, signal(entity)])),
|
||
|
|
};
|
||
|
|
};
|
||
|
|
|
||
|
|
const get = (id: string) => {
|
||
|
|
return {
|
||
|
|
id,
|
||
|
|
get value(){
|
||
|
|
return collection.value[id]?.value;
|
||
|
|
},
|
||
|
|
set value(value: T){
|
||
|
|
const signal = collection.value[id];
|
||
|
|
if(signal)signal.value = value;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return {
|
||
|
|
collection,
|
||
|
|
remove,
|
||
|
|
add,
|
||
|
|
get
|
||
|
|
}
|
||
|
|
}
|