feat: add spawner utility
Introduce `createSpawner` and `spawnerEffect` to manage the lifecycle of side effects based on a collection of IDs. `spawnerEffect` uses Preact signals to automatically trigger spawners when IDs are added to an iterable and cleanup functions when they are removed.
This commit is contained in:
parent
bbab3cc43b
commit
e8c995f74f
|
|
@ -71,4 +71,6 @@ export { createRNG, Mulberry32RNG } from "./utils/rng";
|
|||
export type { MiddlewareChain } from "./utils/middleware";
|
||||
export { createMiddlewareChain } from "./utils/middleware";
|
||||
|
||||
export * from "./utils/spawner";
|
||||
|
||||
export * from "@preact/signals-core";
|
||||
|
|
|
|||
|
|
@ -0,0 +1,39 @@
|
|||
import { effect } from "@preact/signals-core";
|
||||
|
||||
export type SpawnerFunction = (id: string) => () => void;
|
||||
|
||||
export function createSpawner(spawner: SpawnerFunction) {
|
||||
const entries = new Map<string, () => void>();
|
||||
|
||||
function update(set: Set<string>) {
|
||||
for (const key of set) {
|
||||
if (!entries.has(key)) {
|
||||
entries.set(key, spawner(key));
|
||||
}
|
||||
}
|
||||
|
||||
for (const [key, entry] of entries) {
|
||||
if (!set.has(key)) {
|
||||
entry();
|
||||
entries.delete(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return update;
|
||||
}
|
||||
|
||||
export function spawnerEffect(
|
||||
iterable: () => Iterable<string>,
|
||||
spawner: SpawnerFunction,
|
||||
) {
|
||||
const update = createSpawner(spawner);
|
||||
|
||||
return effect(() => {
|
||||
const set = new Set<string>();
|
||||
for (const each of iterable()) {
|
||||
set.add(each);
|
||||
}
|
||||
update(set);
|
||||
});
|
||||
}
|
||||
Loading…
Reference in New Issue