2026-04-02 13:52:15 +08:00
|
|
|
import {Signal, signal, SignalOptions} from "@preact/signals-core";
|
|
|
|
|
import {create} from 'mutative';
|
2026-04-01 13:36:16 +08:00
|
|
|
|
2026-04-02 13:52:15 +08:00
|
|
|
export class Entity<T> extends Signal<T> {
|
|
|
|
|
public constructor(public readonly id: string, t?: T, options?: SignalOptions<T>) {
|
|
|
|
|
super(t, options);
|
|
|
|
|
}
|
|
|
|
|
produce(fn: (draft: T) => void) {
|
|
|
|
|
this.value = create(this.value, fn);
|
|
|
|
|
}
|
2026-04-01 13:36:16 +08:00
|
|
|
}
|
|
|
|
|
|
2026-04-02 13:52:15 +08:00
|
|
|
export function entity<T = undefined>(id: string, t?: T, options?: SignalOptions<T>) {
|
|
|
|
|
return new Entity<T>(id, t, options);
|
2026-04-01 22:55:59 +08:00
|
|
|
}
|
|
|
|
|
|
2026-04-02 13:52:15 +08:00
|
|
|
export type EntityCollection<T> = {
|
|
|
|
|
collection: Signal<Record<string, Entity<T>>>;
|
|
|
|
|
remove(...ids: string[]): void;
|
|
|
|
|
add(...entities: (T & {id: string})[]): void;
|
|
|
|
|
get(id: string): Entity<T>;
|
2026-04-01 22:55:59 +08:00
|
|
|
}
|
|
|
|
|
|
2026-04-02 13:52:15 +08:00
|
|
|
export function createEntityCollection<T>(): EntityCollection<T> {
|
|
|
|
|
const collection = signal({} as Record<string, Entity<T>>);
|
2026-04-01 13:36:16 +08:00
|
|
|
const remove = (...ids: string[]) => {
|
|
|
|
|
collection.value = Object.fromEntries(
|
2026-04-02 13:52:15 +08:00
|
|
|
Object.entries(collection.value).filter(([id]) => !ids.includes(id)),
|
2026-04-01 13:36:16 +08:00
|
|
|
);
|
|
|
|
|
};
|
2026-04-02 13:52:15 +08:00
|
|
|
|
|
|
|
|
const add = (...entities: (T & {id: string})[]) => {
|
2026-04-01 13:36:16 +08:00
|
|
|
collection.value = {
|
|
|
|
|
...collection.value,
|
2026-04-02 13:52:15 +08:00
|
|
|
...Object.fromEntries(entities.map((e) => [e.id, entity(e.id, e)])),
|
2026-04-01 13:36:16 +08:00
|
|
|
};
|
|
|
|
|
};
|
2026-04-02 13:52:15 +08:00
|
|
|
|
|
|
|
|
const get = (id: string) => collection.value[id];
|
|
|
|
|
|
2026-04-01 13:36:16 +08:00
|
|
|
return {
|
|
|
|
|
collection,
|
|
|
|
|
remove,
|
|
|
|
|
add,
|
|
|
|
|
get
|
|
|
|
|
}
|
|
|
|
|
}
|