@andrewthehan/adage
v0.0.10
Published
Async Directed Acyclic Graph Execution
Downloads
41
Readme
adage
Async Directed Acyclic Graph Execution
Small utility to run async processors according to declared dependencies.
Installation
$ npm i @andrewthehan/adageUsage
import {
addDependencies,
checkIsExecutable,
createDependencyGraph,
type DependencyGraph,
execute,
type Processor,
safeExecute,
} from "@andrewthehan/adage";
const processors = new Map<string, Processor<number>>();
processors.set("pollMouseInput", async (delta: number) => { ... });
processors.set("pollKeyboardInput", async (delta: number) => { ... });
processors.set("update", async (delta: number) => { ... });
processors.set("render", async (delta: number) => { ... });
processors.set("logWorldState", async (delta: number) => { ... });
const deps: DependencyGraph<string> = createDependencyGraph<string>();
addDependencies(
deps,
["pollKeyboardInput", "pollMouseInput"],
"update",
["render", "logWorldState"],
);
// pollKeyboardInput ──┐ ┌──> render
// ├──> update ──┤
// pollMouseInput ──┘ └──> logWorldState
// check this after configuration changes
checkIsExecutable(processors, deps);
// execute the processors with dependencies taken into account
await execute(processors, deps, 50);
// alternatively use: await safeExecute(processors, deps, 50);Note that the same object is passed through so mutations are propagated.
type Damage = {
amount: 100;
};
const processors = new Map<string, Processor<Damage>>();
processors.set("shield", async (damage: Damage) => {
damage.amount -= 10;
});
processors.set("armor", async (damage: Damage) => {
damage.amount *= 0.9;
});
processors.set("apply", async (damage: Damage) => {
console.log(`Apply ${damage.amount} damage!`);
});
const deps: DependencyGraph<string> = createDependencyGraph<string>();
addDependencies(deps, "shield", "armor", "apply");
// shield ──> armor ──> apply
checkIsExecutable(processors, deps);
await execute(processors, deps, { amount: 100 });
// prints: Apply 81 damage!