You're Invited:Meet the Socket Team at RSAC and BSidesSF 2026, March 23–26.RSVP
Socket
Book a DemoSign in
Socket

@vltpkg/graph-run

Package Overview
Dependencies
Maintainers
6
Versions
11
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@vltpkg/graph-run - npm Package Compare versions

Comparing version
1.0.0-rc.18
to
1.0.0-rc.22
+21
-17
package.json
{
"name": "@vltpkg/graph-run",
"description": "Run operations on a graph, maximizing parallelism",
"version": "1.0.0-rc.18",
"version": "1.0.0-rc.22",
"repository": {

@@ -10,3 +10,6 @@ "type": "git",

},
"author": "vlt technology inc. <support@vlt.sh> (http://vlt.sh)",
"author": {
"name": "vlt technology inc.",
"email": "support@vlt.sh"
},
"dependencies": {},

@@ -25,4 +28,15 @@ "devDependencies": {

"engines": {
"node": ">=22.9.0"
"node": ">=22.22.0"
},
"scripts": {
"format": "prettier --write . --log-level warn --ignore-path ../../.prettierignore --cache",
"format:check": "prettier --check . --ignore-path ../../.prettierignore --cache",
"lint": "eslint . --fix",
"lint:check": "eslint .",
"prepack": "tsc -p tsconfig.publish.json && ../../scripts/update-dist-exports.ts",
"snap": "tap",
"test": "tap",
"posttest": "tsc --noEmit",
"typecheck": "tsc --noEmit"
},
"tap": {

@@ -32,3 +46,3 @@ "extends": "../../tap-config.yaml"

"prettier": "../../.prettierrc.js",
"module": "./dist/index.js",
"module": "./src/index.ts",
"type": "module",

@@ -39,3 +53,3 @@ "exports": {

"import": {
"default": "./dist/index.js"
"default": "./src/index.ts"
}

@@ -46,13 +60,3 @@ }

"dist"
],
"scripts": {
"format": "prettier --write . --log-level warn --ignore-path ../../.prettierignore --cache",
"format:check": "prettier --check . --ignore-path ../../.prettierignore --cache",
"lint": "eslint . --fix",
"lint:check": "eslint .",
"snap": "tap",
"test": "tap",
"posttest": "tsc --noEmit",
"typecheck": "tsc --noEmit"
}
}
]
}
/**
* Codes indicating the type of error that was encountered.
* These are found on the `Error.cause.code` field.
*
* They are:
*
* - `'GRAPHRUN_TRAVERSAL'` The command run on a given node has failed, either
* by throwing an error, or by returning a rejected promise.
* - `'GRAPHRUN_NO_NODES'` An empty list of initial nodes was provided to the
* graph run operation. At least one starting node must be present in the
* list.
* - `'GRAPHRUN_CYCLE_WITHOUT_PATH'` - A cycle in the graph was detected, but
* the path *to* the node where the cycle was detected could not be
* determined. This is impossible, and cannot ever happen.
*/
export type ErrorCode = 'GRAPHRUN_NO_NODES' | 'GRAPHRUN_CYCLE_WITHOUT_PATH' | 'GRAPHRUN_TRAVERSAL';
export type ErrorCause<Node> = {
code: ErrorCode;
} & ({
code: 'GRAPHRUN_NO_NODES';
found: unknown;
wanted: string;
} | {
code: 'GRAPHRUN_CYCLE_WITHOUT_PATH';
} | {
code: 'GRAPHRUN_TRAVERSAL';
cause: Error;
node: Node;
path: Node[];
});
export declare const isGraphRunError: <Node>(er: unknown) => er is Error & {
cause: ErrorCause<Node>;
};
/**
* Options that define the graph and how to traverse it
*/
export interface RunnerOptions<Node, Result = void> {
/** Array of one or more entry nodes. */
graph: [node: Node, ...rest: Node[]];
/** get the dependencies of a given node */
getDeps: (node: Node) => Node[] | Promise<Node[]>;
/** action to take on each node */
visit: (node: Node, signal: AbortSignal, path: Node[], depResults: DepResults<Node, Result>) => Result | Promise<Result>;
/**
* Called when a cycle is encountered.
* Throw in this method to enforce a DAG graph.
* If left undefined, then cycles are silently ignored and skipped.
*
* `node` parameter is the dependency that is being skipped.
*
* `cycle` is the route from the dependent back to itself via
* the parent.
*
* `path` is the path to the dependent who wanted this dep to be
* loaded.
*/
onCycle?: (node: Node, cycle: Node[], path: Node[]) => void | Promise<void>;
/**
* Set to `false` to continue operations even if errors occur.
* If set to false, then an AggregateError will be raised on failure
* containing all failures (even if only one). If true, then a normal
* Error will be raised on failure.
* @default true
*/
failFast?: boolean;
/** a signal that will trigger the graph traversal to end prematurely */
signal?: AbortSignal;
}
export type DepResults<Node, Result> = Map<Node, Result | undefined>;
/**
* Options that can define a synchronous graph traversal.
*
* Note that if the visit() method is async, then the *promises themselves*
* will be used as the `Result` type, which is likely not what you want!
*/
export interface RunnerOptionsSync<Node, Result = void> extends RunnerOptions<Node, Result> {
/** Get a set of dependency nodes synchronously */
getDeps: (node: Node) => Node[];
/** Visit a node synchronously */
visit: (node: Node, signal: AbortSignal, path: Node[], depResults: DepResults<Node, Result>) => Result;
/** Handle cycles synchronously */
onCycle?: (node: Node, cycle: Node[], path: Node[]) => void;
}
/** A map of nodes to their PromiseSettledResult value */
export type SettledMap<Node, Result = void> = Map<Node, PromiseSettledResult<Result>>;
/** Any function or class. Used for Error.captureStackTrace */
export type Callable = Function | ((...a: unknown[]) => unknown) | (new (...a: unknown[]) => unknown);
/** Base class of Runner and RunnerSync */
export declare abstract class RunnerBase<
/** The type of thing to be found in this graph */
Node,
/** Type returned by the visit() method */
Result = void, Sync extends boolean = false, O extends Sync extends true ? RunnerOptionsSync<Node, Result> : RunnerOptions<Node, Result> = Sync extends true ? RunnerOptionsSync<Node, Result> : RunnerOptions<Node, Result>> {
/** The map of traversal results */
readonly results: Map<Node, Result>;
/** The map of PromiseSettledResult objects */
readonly settled: SettledMap<Node, Result>;
/** Set of dependents (direct & transitive) on each node */
readonly dependents: Map<Node, Set<Node>>;
/** Set of direct dependents on each node */
readonly directDependents: Map<Node, Set<Node>>;
/** Options provided to constructor */
readonly options: O;
/**
* AbortController used internally to abort the process.
*
* This is internal only, and triggering it at the wrong time may cause
* undefined and unsupported behavior. Do not use!
*
* Instead, if you want to be able to abort the walk at any time, provide
* your own AbortSignal in the opions.
* @internal
*/
readonly abortController: AbortController;
/** True if we are in failFast mode */
readonly failFast: boolean;
/** Rejections and Errors encountered in the traversal */
readonly errors: unknown[];
/**
* Function defining the callsite where the traversal was initiated,
* used for Error.captureStackTrace.
*/
readonly from: Callable;
constructor(options: O, from?: Callable);
/** Initiate the graph traversal, resolving/returning when complete */
abstract run(): Sync extends true ? void : Promise<void>;
/** Get the dependencies of a given node */
abstract getDeps(n: Node): Sync extends true ? Node[] : Promise<Node[]>;
/** Visit a node. Calls `options.visit()` */
abstract visit(n: Node, path: Node[], depResults: DepResults<Node, Result>): Sync extends true ? Result : Promise<Result>;
/**
* Calls the `options.onCycle()` method when a cycle is detected.
*/
abstract onCycle(n: Node, cycle: Node[], path: Node[]): Sync extends true ? void : void | Promise<void>;
/**
* For a Node `n` that depends directly or transitively on Node `d`, find the
* shortest known dependency path from `n` to `d`. This is done by walking
* backwards breadth-first up the dependency relations from `d` until `n` is
* found.
*
* If no known path can be found, then `undefined` is returned. Otherwise,
* a path array is returned that starts with `n` and ends with `d`.
*
* Note that self-referential links are never considered, since they're
* by definition cyclical.
*/
route(n: Node, d: Node): undefined | [n: Node, ...path: Node[]];
/**
* If the dependency from `n -> d` at the specified path would
* cause a cycle, then call the onCycle method and return true.
* Oherwise, assign the appropriate entries in the dependency
* tracking sets, and return false.
* @internal
*/
cycleCheck(n: Node, path: Node[], d: Node): boolean;
/**
* Method that handles errors raised by visits.
* @internal
*/
handleError(er: unknown, n: Node, path: Node[]): void;
/**
* Method that handles successful visit results
* @internal
*/
handleValue(value: Result, n: Node): void;
}
/** Asynchronous graph runner */
export declare class Runner<Node, Result> extends RunnerBase<Node, Result, false, RunnerOptions<Node, Result>> {
#private;
/** Map of nodes currently awaiting completion */
readonly running: Map<Node, Promise<void>>;
/** Track which node's promise is waiting for which other nodes */
readonly promiseWaiting: Map<Node, Set<Node>>;
getDeps(n: Node): Promise<Node[]>;
visit(n: Node, path: Node[], depResults: DepResults<Node, Result>): Promise<Result>;
onCycle(n: Node, cycle: Node[], path: Node[]): Promise<void>;
run(): Promise<void>;
}
/** Synchronous graph runner */
export declare class RunnerSync<Node, Result> extends RunnerBase<Node, Result, true, RunnerOptionsSync<Node, Result>> {
#private;
getDeps(n: Node): Node[];
visit(n: Node, path: Node[], depResults: DepResults<Node, Result>): Result;
onCycle(n: Node, cycle: Node[], path: Node[]): void;
run(): Map<Node, Result>;
}
/**
* Asynchronous graph traversal method
*
* If `failFast:false` is set in the options, then an AggregateError
* will be raised if there were any failures. Otherwise, a normal Error
* is raised on failure.
*/
export declare const graphRun: <Node, Result>(options: RunnerOptions<Node, Result>) => Promise<Map<Node, Result>>;
/**
* Synchronous graph traversal method
*
* If `failFast:false` is set in the options, then an AggregateError
* will be thrown if there were any failures. Otherwise, a normal Error
* is thrown on failure.
*/
export declare const graphRunSync: <Node, Result>(options: RunnerOptionsSync<Node, Result>) => Map<Node, Result>;
/**
* Asynchronous graph traversal, capturing all error/result
* statuses.
*/
export declare const allSettled: <Node, Result>(options: RunnerOptions<Node, Result>) => Promise<SettledMap<Node, Result>>;
/**
* Synchronous graph traversal, capturing all error/result
* statuses.
*/
export declare const allSettledSync: <Node, Result>(options: RunnerOptionsSync<Node, Result>) => SettledMap<Node, Result>;
/**
* Asynchronous graph traversal, returning the first successful visit.
* If all visits fail, then an AggregateError is raised with all errors
* encountered.
*/
export declare const any: <Node, Result>(options: RunnerOptions<Node, Result>) => Promise<Result>;
/**
* Synchronous graph traversal, returning the first successful visit.
* If all visits fail, then an AggregateError is thrown with all errors
* encountered.
*/
export declare const anySync: <Node, Result>(options: RunnerOptionsSync<Node, Result>) => Result;
/**
* Asynchronous graph traversal, resolving or rejecting when the first visit
* resolves or rejects.
*/
export declare const race: <Node, Result>(options: RunnerOptions<Node, Result>) => Promise<Result>;
/**
* Synchronous graph traversal, returning or throwing when the first visit
* is completed.
*/
export declare const raceSync: <Node, Result>(options: RunnerOptionsSync<Node, Result>) => Result;
//# sourceMappingURL=index.d.ts.map
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
import { setMaxListeners } from 'node:events';
export const isGraphRunError = (er) => !!er &&
typeof er === 'object' &&
'cause' in er &&
!!er.cause &&
typeof er.cause === 'object' &&
'code' in er.cause &&
((er.cause.code === 'GRAPHRUN_NO_NODES' &&
'found' in er.cause &&
'wanted' in er.cause &&
typeof er.cause.wanted === 'string') ||
(er.cause.code === 'GRAPHRUN_TRAVERSAL' &&
'path' in er.cause &&
Array.isArray(er.cause.path) &&
'node' in er.cause &&
'cause' in er.cause) ||
er.cause.code === 'GRAPHRUN_CYCLE_WITHOUT_PATH');
/** Base class of Runner and RunnerSync */
export class RunnerBase {
/** The map of traversal results */
results = new Map();
/** The map of PromiseSettledResult objects */
settled = new Map();
/** Set of dependents (direct & transitive) on each node */
dependents = new Map();
/** Set of direct dependents on each node */
directDependents = new Map();
/** Options provided to constructor */
options;
/**
* AbortController used internally to abort the process.
*
* This is internal only, and triggering it at the wrong time may cause
* undefined and unsupported behavior. Do not use!
*
* Instead, if you want to be able to abort the walk at any time, provide
* your own AbortSignal in the opions.
* @internal
*/
abortController;
/** True if we are in failFast mode */
failFast;
/** Rejections and Errors encountered in the traversal */
errors = [];
/**
* Function defining the callsite where the traversal was initiated,
* used for Error.captureStackTrace.
*/
from;
constructor(options, from) {
const ac = new AbortController();
this.from = from ?? this.constructor;
this.abortController = ac;
setMaxListeners(Infinity, ac.signal);
this.options = options;
if (!options.graph.length) {
const er = new Error('no nodes provided to graph traversal', {
cause: {
code: 'GRAPHRUN_NO_NODES',
found: options.graph,
wanted: '[first: Node, ...rest: Node[]]',
},
});
Error.captureStackTrace(er, from);
throw er;
}
this.failFast = options.failFast !== false;
const { signal } = options;
if (signal !== undefined) {
signal.addEventListener('abort', reason => ac.abort(reason), {
once: true,
signal: ac.signal,
});
}
}
/**
* For a Node `n` that depends directly or transitively on Node `d`, find the
* shortest known dependency path from `n` to `d`. This is done by walking
* backwards breadth-first up the dependency relations from `d` until `n` is
* found.
*
* If no known path can be found, then `undefined` is returned. Otherwise,
* a path array is returned that starts with `n` and ends with `d`.
*
* Note that self-referential links are never considered, since they're
* by definition cyclical.
*/
route(n, d) {
const dependents = this.dependents.get(d);
if (!dependents?.has(n))
return undefined;
const directDependents = this.directDependents.get(d);
/* c8 ignore next */
if (!directDependents)
return undefined;
if (directDependents.has(n)) {
return [n, d];
}
const queue = [
...directDependents,
].map(dd => [dd, d]);
let step = undefined;
while (undefined !== (step = queue.shift())) {
/* c8 ignore next */
if (!dependents.has(step[0]))
continue;
if (step[0] === n) {
return step;
}
const ddd = this.directDependents.get(step[0]);
if (ddd) {
for (const d of ddd) {
queue.push([d, ...step]);
}
}
}
}
/**
* If the dependency from `n -> d` at the specified path would
* cause a cycle, then call the onCycle method and return true.
* Oherwise, assign the appropriate entries in the dependency
* tracking sets, and return false.
* @internal
*/
cycleCheck(n, path, d) {
/* c8 ignore next */
const dependents = this.dependents.get(n) ?? new Set();
this.dependents.set(n, dependents);
const isCycle = dependents.has(d);
if (isCycle) {
const cycle = this.route(d, n);
/* c8 ignore start - impossible */
if (!cycle) {
throw new Error('cycle detected, but cycle route not found', {
cause: { code: 'GRAPHRUN_CYCLE_WITHOUT_PATH' },
});
}
/* c8 ignore stop */
cycle.unshift(n);
void this.onCycle(d, cycle, path);
return true;
}
const depDD = this.directDependents.get(d) ?? new Set();
this.directDependents.set(d, depDD);
depDD.add(n);
const depDependents = this.dependents.get(d) ?? new Set();
this.dependents.set(d, depDependents);
for (const n of dependents) {
depDependents.add(n);
}
depDependents.add(n);
return false;
}
/**
* Method that handles errors raised by visits.
* @internal
*/
handleError(er, n, path) {
this.errors.push(er);
this.settled.set(n, {
status: 'rejected',
reason: er,
});
if (this.failFast) {
this.abortController.abort(er);
const e = new Error('failed graph traversal', {
cause: {
code: 'GRAPHRUN_TRAVERSAL',
node: n,
path,
cause: er,
},
});
Error.captureStackTrace(e, this.from);
throw e;
}
}
/**
* Method that handles successful visit results
* @internal
*/
handleValue(value, n) {
this.results.set(n, value);
this.settled.set(n, {
status: 'fulfilled',
value,
});
}
}
/** Asynchronous graph runner */
export class Runner extends RunnerBase {
/** Map of nodes currently awaiting completion */
running = new Map();
/** Track which node's promise is waiting for which other nodes */
promiseWaiting = new Map();
async getDeps(n) {
/* c8 ignore next */
if (this.abortController.signal.aborted)
return [];
const deps = await this.options.getDeps(n);
for (const d of deps) {
const dependents = this.dependents.get(d) ?? new Set();
this.dependents.set(d, dependents);
dependents.add(n);
const depDD = this.directDependents.get(d) ?? new Set();
this.directDependents.set(d, depDD);
depDD.add(n);
}
return deps;
}
async visit(n, path, depResults) {
const { signal } = this.abortController;
return this.options.visit(n, signal, path, depResults);
}
async onCycle(n, cycle, path) {
/* c8 ignore next */
if (this.abortController.signal.aborted)
return;
await this.options.onCycle?.(n, cycle, path);
}
/**
* Check if node `target` is waiting (directly or transitively) for node `n`.
* If so, making `n` wait for `target` would create a deadlock.
*/
#isWaitingFor(target, n, visited = new Set()) {
if (visited.has(target))
return false;
visited.add(target);
const waiting = this.promiseWaiting.get(target);
if (!waiting)
return false;
if (waiting.has(n))
return true;
for (const w of waiting) {
if (this.#isWaitingFor(w, n, visited))
return true;
}
return false;
}
async #walk(n, path) {
const r = this.running.get(n);
/* c8 ignore next */
if (r)
return r;
/* c8 ignore start */
if (this.settled.get(n))
return;
/* c8 ignore stop */
const p = this.#step(n, path).then(() => {
this.running.delete(n);
this.promiseWaiting.delete(n);
},
/* c8 ignore start - handled deeper in the chain */
(er) => {
this.running.delete(n);
this.promiseWaiting.delete(n);
throw er;
});
this.running.set(n, p);
return p;
}
async #step(n, path) {
const dependents = this.dependents.get(n) ?? new Set();
this.dependents.set(n, dependents);
const deps = await this.getDeps(n);
const awaiting = [];
const depPath = [...path, n];
// Initialize waiting set for this node
const waitingOn = new Set();
this.promiseWaiting.set(n, waitingOn);
for (const d of deps) {
/* c8 ignore next */
if (this.abortController.signal.aborted)
return;
// self-link, skip
if (d === n)
continue;
if (this.cycleCheck(n, depPath, d))
continue;
/* c8 ignore next */
if (this.settled.get(d))
continue;
const runningPromise = this.running.get(d);
if (runningPromise) {
// Check if d is already waiting for n (promise-level cycle)
if (this.#isWaitingFor(d, n)) {
// Treat as cycle to prevent deadlock
void this.onCycle(d, [n, d], depPath);
continue;
}
}
// Record that n is waiting for d
waitingOn.add(d);
awaiting.push(runningPromise ?? this.#walk(d, depPath));
}
/* c8 ignore next */
if (this.abortController.signal.aborted)
return;
await Promise.all(awaiting);
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (this.abortController.signal.aborted)
return;
const depRes = new Map(deps.map(d => [d, this.results.get(d)]));
try {
this.handleValue(await this.visit(n, path, depRes), n);
}
catch (er) {
this.handleError(er, n, path);
}
}
async run() {
const promises = [];
for (const n of this.options.graph) {
promises.push(this.#walk(n, []));
}
await Promise.all(promises);
}
}
/** Synchronous graph runner */
export class RunnerSync extends RunnerBase {
getDeps(n) {
if (this.abortController.signal.aborted)
return [];
return this.options.getDeps(n);
}
visit(n, path, depResults) {
const { signal } = this.abortController;
return this.options.visit(n, signal, path, depResults);
}
onCycle(n, cycle, path) {
/* c8 ignore next */
if (this.abortController.signal.aborted)
return;
this.options.onCycle?.(n, cycle, path);
}
#walk(n, path) {
/* c8 ignore start */
if (this.settled.get(n))
return;
/* c8 ignore stop */
this.#step(n, path);
}
#step(n, path) {
const dependents = this.dependents.get(n) ?? new Set();
this.dependents.set(n, dependents);
const deps = this.getDeps(n);
const depPath = [...path, n];
for (const d of deps) {
if (this.abortController.signal.aborted)
return;
/* c8 ignore next */
if (d === n)
continue;
if (this.cycleCheck(n, depPath, d))
continue;
if (!this.settled.get(d))
this.#walk(d, depPath);
}
if (this.abortController.signal.aborted)
return;
const depRes = new Map(deps.map(d => [d, this.results.get(d)]));
try {
this.handleValue(this.visit(n, path, depRes), n);
}
catch (er) {
this.handleError(er, n, path);
}
}
run() {
for (const n of this.options.graph) {
this.#walk(n, []);
}
return this.results;
}
}
/**
* Asynchronous graph traversal method
*
* If `failFast:false` is set in the options, then an AggregateError
* will be raised if there were any failures. Otherwise, a normal Error
* is raised on failure.
*/
export const graphRun = async (options) => {
const runner = new Runner(options, graphRun);
await runner.run();
if (runner.errors.length) {
const e = new AggregateError(runner.errors, 'failed graph traversal');
Error.captureStackTrace(e, graphRun);
throw e;
}
return runner.results;
};
/**
* Synchronous graph traversal method
*
* If `failFast:false` is set in the options, then an AggregateError
* will be thrown if there were any failures. Otherwise, a normal Error
* is thrown on failure.
*/
export const graphRunSync = (options) => {
const runner = new RunnerSync(options, graphRunSync);
runner.run();
if (runner.errors.length) {
const e = new AggregateError(runner.errors, 'failed graph traversal');
Error.captureStackTrace(e, graphRunSync);
throw e;
}
return runner.results;
};
/**
* Asynchronous graph traversal, capturing all error/result
* statuses.
*/
export const allSettled = async (options) => {
const runner = new Runner({ ...options, failFast: false }, allSettled);
await runner.run();
return runner.settled;
};
/**
* Synchronous graph traversal, capturing all error/result
* statuses.
*/
export const allSettledSync = (options) => {
const runner = new RunnerSync({ ...options, failFast: false }, allSettledSync);
runner.run();
return runner.settled;
};
/**
* Asynchronous graph traversal, returning the first successful visit.
* If all visits fail, then an AggregateError is raised with all errors
* encountered.
*/
export const any = async (options) => {
const ac = new AbortController();
let result;
let found = false;
const runner = new Runner({
...options,
failFast: false,
signal: ac.signal,
visit: async (node, signal, path, depResults) => {
try {
result = await options.visit(node, signal, path, depResults);
found = true;
ac.abort('found');
}
catch { }
return result;
},
}, any);
await runner.run();
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (!found) {
const e = new AggregateError(runner.errors, 'failed graph traversal');
Error.captureStackTrace(e, any);
throw e;
}
return result;
};
/**
* Synchronous graph traversal, returning the first successful visit.
* If all visits fail, then an AggregateError is thrown with all errors
* encountered.
*/
export const anySync = (options) => {
const ac = new AbortController();
let result;
let found = false;
const runner = new RunnerSync({
...options,
failFast: false,
signal: ac.signal,
visit: (node, signal, path, depResults) => {
try {
result = options.visit(node, signal, path, depResults);
found = true;
ac.abort('found');
}
catch { }
return result;
},
}, anySync);
runner.run();
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (!found) {
const e = new AggregateError(runner.errors, 'failed graph traversal');
Error.captureStackTrace(e, anySync);
throw e;
}
return result;
};
/**
* Asynchronous graph traversal, resolving or rejecting when the first visit
* resolves or rejects.
*/
export const race = async (options) => {
const ac = new AbortController();
let result;
const runner = new Runner({
...options,
failFast: true,
signal: ac.signal,
visit: async (node, signal, path, depResults) => {
try {
result = await options.visit(node, signal, path, depResults);
ac.abort('found');
/* c8 ignore next */
}
catch { }
return result;
},
}, race);
await runner.run();
return result;
};
/**
* Synchronous graph traversal, returning or throwing when the first visit
* is completed.
*/
export const raceSync = (options) => {
const ac = new AbortController();
let result;
const runner = new RunnerSync({
...options,
failFast: true,
signal: ac.signal,
visit: (node, signal, path, depResults) => {
try {
result = options.visit(node, signal, path, depResults);
ac.abort('found');
/* c8 ignore next */
}
catch { }
return result;
},
}, race);
runner.run();
return result;
};
//# sourceMappingURL=index.js.map
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { setMaxListeners } from 'node:events'\n\n/**\n * Codes indicating the type of error that was encountered.\n * These are found on the `Error.cause.code` field.\n *\n * They are:\n *\n * - `'GRAPHRUN_TRAVERSAL'` The command run on a given node has failed, either\n * by throwing an error, or by returning a rejected promise.\n * - `'GRAPHRUN_NO_NODES'` An empty list of initial nodes was provided to the\n * graph run operation. At least one starting node must be present in the\n * list.\n * - `'GRAPHRUN_CYCLE_WITHOUT_PATH'` - A cycle in the graph was detected, but\n * the path *to* the node where the cycle was detected could not be\n * determined. This is impossible, and cannot ever happen.\n */\nexport type ErrorCode =\n | 'GRAPHRUN_NO_NODES'\n | 'GRAPHRUN_CYCLE_WITHOUT_PATH'\n | 'GRAPHRUN_TRAVERSAL'\n\nexport type ErrorCause<Node> = {\n code: ErrorCode\n} & (\n | {\n code: 'GRAPHRUN_NO_NODES'\n found: unknown\n wanted: string\n }\n | { code: 'GRAPHRUN_CYCLE_WITHOUT_PATH' }\n | {\n code: 'GRAPHRUN_TRAVERSAL'\n cause: Error\n node: Node\n path: Node[]\n }\n)\n\nexport const isGraphRunError = <Node>(\n er: unknown,\n): er is Error & { cause: ErrorCause<Node> } =>\n !!er &&\n typeof er === 'object' &&\n 'cause' in er &&\n !!er.cause &&\n typeof er.cause === 'object' &&\n 'code' in er.cause &&\n ((er.cause.code === 'GRAPHRUN_NO_NODES' &&\n 'found' in er.cause &&\n 'wanted' in er.cause &&\n typeof er.cause.wanted === 'string') ||\n (er.cause.code === 'GRAPHRUN_TRAVERSAL' &&\n 'path' in er.cause &&\n Array.isArray(er.cause.path) &&\n 'node' in er.cause &&\n 'cause' in er.cause) ||\n er.cause.code === 'GRAPHRUN_CYCLE_WITHOUT_PATH')\n\n/**\n * Options that define the graph and how to traverse it\n */\nexport interface RunnerOptions<Node, Result = void> {\n /** Array of one or more entry nodes. */\n graph: [node: Node, ...rest: Node[]]\n\n /** get the dependencies of a given node */\n getDeps: (node: Node) => Node[] | Promise<Node[]>\n\n /** action to take on each node */\n visit: (\n node: Node,\n signal: AbortSignal,\n path: Node[],\n depResults: DepResults<Node, Result>,\n ) => Result | Promise<Result>\n\n /**\n * Called when a cycle is encountered.\n * Throw in this method to enforce a DAG graph.\n * If left undefined, then cycles are silently ignored and skipped.\n *\n * `node` parameter is the dependency that is being skipped.\n *\n * `cycle` is the route from the dependent back to itself via\n * the parent.\n *\n * `path` is the path to the dependent who wanted this dep to be\n * loaded.\n */\n onCycle?: (\n node: Node,\n cycle: Node[],\n path: Node[],\n ) => void | Promise<void>\n\n /**\n * Set to `false` to continue operations even if errors occur.\n * If set to false, then an AggregateError will be raised on failure\n * containing all failures (even if only one). If true, then a normal\n * Error will be raised on failure.\n * @default true\n */\n failFast?: boolean\n\n /** a signal that will trigger the graph traversal to end prematurely */\n signal?: AbortSignal\n}\n\nexport type DepResults<Node, Result> = Map<Node, Result | undefined>\n\n/**\n * Options that can define a synchronous graph traversal.\n *\n * Note that if the visit() method is async, then the *promises themselves*\n * will be used as the `Result` type, which is likely not what you want!\n */\nexport interface RunnerOptionsSync<\n Node,\n Result = void,\n> extends RunnerOptions<Node, Result> {\n /** Get a set of dependency nodes synchronously */\n getDeps: (node: Node) => Node[]\n\n /** Visit a node synchronously */\n visit: (\n node: Node,\n signal: AbortSignal,\n path: Node[],\n depResults: DepResults<Node, Result>,\n ) => Result\n\n /** Handle cycles synchronously */\n onCycle?: (node: Node, cycle: Node[], path: Node[]) => void\n}\n\n/** A map of nodes to their PromiseSettledResult value */\nexport type SettledMap<Node, Result = void> = Map<\n Node,\n PromiseSettledResult<Result>\n>\n\n/** Any function or class. Used for Error.captureStackTrace */\nexport type Callable =\n // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n | Function\n | ((...a: unknown[]) => unknown)\n | (new (...a: unknown[]) => unknown)\n\n/** Base class of Runner and RunnerSync */\nexport abstract class RunnerBase<\n /** The type of thing to be found in this graph */\n Node,\n /** Type returned by the visit() method */\n Result = void,\n Sync extends boolean = false,\n O extends Sync extends true ? RunnerOptionsSync<Node, Result>\n : RunnerOptions<Node, Result> = Sync extends true ?\n RunnerOptionsSync<Node, Result>\n : RunnerOptions<Node, Result>,\n> {\n /** The map of traversal results */\n readonly results = new Map<Node, Result>()\n\n /** The map of PromiseSettledResult objects */\n readonly settled: SettledMap<Node, Result> = new Map()\n\n /** Set of dependents (direct & transitive) on each node */\n readonly dependents = new Map<Node, Set<Node>>()\n\n /** Set of direct dependents on each node */\n readonly directDependents = new Map<Node, Set<Node>>()\n\n /** Options provided to constructor */\n readonly options: O\n\n /**\n * AbortController used internally to abort the process.\n *\n * This is internal only, and triggering it at the wrong time may cause\n * undefined and unsupported behavior. Do not use!\n *\n * Instead, if you want to be able to abort the walk at any time, provide\n * your own AbortSignal in the opions.\n * @internal\n */\n readonly abortController: AbortController\n\n /** True if we are in failFast mode */\n readonly failFast: boolean\n\n /** Rejections and Errors encountered in the traversal */\n readonly errors: unknown[] = []\n\n /**\n * Function defining the callsite where the traversal was initiated,\n * used for Error.captureStackTrace.\n */\n readonly from: Callable\n\n constructor(options: O, from?: Callable) {\n const ac = new AbortController()\n this.from = from ?? this.constructor\n this.abortController = ac\n setMaxListeners(Infinity, ac.signal)\n this.options = options\n if (!options.graph.length) {\n const er = new Error('no nodes provided to graph traversal', {\n cause: {\n code: 'GRAPHRUN_NO_NODES',\n found: options.graph,\n wanted: '[first: Node, ...rest: Node[]]',\n },\n })\n Error.captureStackTrace(er, from)\n throw er\n }\n this.failFast = options.failFast !== false\n const { signal } = options\n if (signal !== undefined) {\n signal.addEventListener('abort', reason => ac.abort(reason), {\n once: true,\n signal: ac.signal,\n })\n }\n }\n\n /** Initiate the graph traversal, resolving/returning when complete */\n abstract run(): Sync extends true ? void : Promise<void>\n\n /** Get the dependencies of a given node */\n abstract getDeps(\n n: Node,\n ): Sync extends true ? Node[] : Promise<Node[]>\n\n /** Visit a node. Calls `options.visit()` */\n abstract visit(\n n: Node,\n path: Node[],\n depResults: DepResults<Node, Result>,\n ): Sync extends true ? Result : Promise<Result>\n\n /**\n * Calls the `options.onCycle()` method when a cycle is detected.\n */\n abstract onCycle(\n n: Node,\n cycle: Node[],\n path: Node[],\n ): Sync extends true ? void : void | Promise<void>\n\n /**\n * For a Node `n` that depends directly or transitively on Node `d`, find the\n * shortest known dependency path from `n` to `d`. This is done by walking\n * backwards breadth-first up the dependency relations from `d` until `n` is\n * found.\n *\n * If no known path can be found, then `undefined` is returned. Otherwise,\n * a path array is returned that starts with `n` and ends with `d`.\n *\n * Note that self-referential links are never considered, since they're\n * by definition cyclical.\n */\n route(n: Node, d: Node): undefined | [n: Node, ...path: Node[]] {\n const dependents = this.dependents.get(d)\n if (!dependents?.has(n)) return undefined\n const directDependents = this.directDependents.get(d)\n /* c8 ignore next */\n if (!directDependents) return undefined\n if (directDependents.has(n)) {\n return [n, d]\n }\n const queue: [n: Node, ...r: Node[]][] = [\n ...directDependents,\n ].map(dd => [dd, d])\n let step: undefined | [n: Node, ...r: Node[]] = undefined\n while (undefined !== (step = queue.shift())) {\n /* c8 ignore next */\n if (!dependents.has(step[0])) continue\n if (step[0] === n) {\n return step\n }\n const ddd = this.directDependents.get(step[0])\n if (ddd) {\n for (const d of ddd) {\n queue.push([d, ...step])\n }\n }\n }\n }\n\n /**\n * If the dependency from `n -> d` at the specified path would\n * cause a cycle, then call the onCycle method and return true.\n * Oherwise, assign the appropriate entries in the dependency\n * tracking sets, and return false.\n * @internal\n */\n cycleCheck(n: Node, path: Node[], d: Node) {\n /* c8 ignore next */\n const dependents = this.dependents.get(n) ?? new Set()\n this.dependents.set(n, dependents)\n const isCycle = dependents.has(d)\n if (isCycle) {\n const cycle = this.route(d, n)\n /* c8 ignore start - impossible */\n if (!cycle) {\n throw new Error('cycle detected, but cycle route not found', {\n cause: { code: 'GRAPHRUN_CYCLE_WITHOUT_PATH' },\n })\n }\n /* c8 ignore stop */\n cycle.unshift(n)\n void this.onCycle(d, cycle, path)\n return true\n }\n\n const depDD = this.directDependents.get(d) ?? new Set()\n this.directDependents.set(d, depDD)\n depDD.add(n)\n\n const depDependents = this.dependents.get(d) ?? new Set()\n this.dependents.set(d, depDependents)\n for (const n of dependents) {\n depDependents.add(n)\n }\n depDependents.add(n)\n return false\n }\n\n /**\n * Method that handles errors raised by visits.\n * @internal\n */\n handleError(er: unknown, n: Node, path: Node[]) {\n this.errors.push(er)\n this.settled.set(n, {\n status: 'rejected',\n reason: er,\n })\n if (this.failFast) {\n this.abortController.abort(er)\n const e = new Error('failed graph traversal', {\n cause: {\n code: 'GRAPHRUN_TRAVERSAL',\n node: n,\n path,\n cause: er as Error,\n },\n })\n Error.captureStackTrace(e, this.from)\n throw e\n }\n }\n\n /**\n * Method that handles successful visit results\n * @internal\n */\n handleValue(value: Result, n: Node) {\n this.results.set(n, value)\n this.settled.set(n, {\n status: 'fulfilled',\n value,\n })\n }\n}\n\n/** Asynchronous graph runner */\nexport class Runner<Node, Result> extends RunnerBase<\n Node,\n Result,\n false,\n RunnerOptions<Node, Result>\n> {\n /** Map of nodes currently awaiting completion */\n readonly running = new Map<Node, Promise<void>>()\n\n /** Track which node's promise is waiting for which other nodes */\n readonly promiseWaiting = new Map<Node, Set<Node>>()\n\n async getDeps(n: Node) {\n /* c8 ignore next */\n if (this.abortController.signal.aborted) return []\n const deps = await this.options.getDeps(n)\n for (const d of deps) {\n const dependents = this.dependents.get(d) ?? new Set()\n this.dependents.set(d, dependents)\n dependents.add(n)\n const depDD = this.directDependents.get(d) ?? new Set()\n this.directDependents.set(d, depDD)\n depDD.add(n)\n }\n return deps\n }\n\n async visit(\n n: Node,\n path: Node[],\n depResults: DepResults<Node, Result>,\n ) {\n const { signal } = this.abortController\n return this.options.visit(n, signal, path, depResults)\n }\n\n async onCycle(n: Node, cycle: Node[], path: Node[]) {\n /* c8 ignore next */\n if (this.abortController.signal.aborted) return\n await this.options.onCycle?.(n, cycle, path)\n }\n\n /**\n * Check if node `target` is waiting (directly or transitively) for node `n`.\n * If so, making `n` wait for `target` would create a deadlock.\n */\n #isWaitingFor(\n target: Node,\n n: Node,\n visited = new Set<Node>(),\n ): boolean {\n if (visited.has(target)) return false\n visited.add(target)\n const waiting = this.promiseWaiting.get(target)\n if (!waiting) return false\n if (waiting.has(n)) return true\n for (const w of waiting) {\n if (this.#isWaitingFor(w, n, visited)) return true\n }\n return false\n }\n\n async #walk(n: Node, path: Node[]) {\n const r = this.running.get(n)\n /* c8 ignore next */\n if (r) return r\n /* c8 ignore start */\n if (this.settled.get(n)) return\n /* c8 ignore stop */\n const p = this.#step(n, path).then(\n () => {\n this.running.delete(n)\n this.promiseWaiting.delete(n)\n },\n /* c8 ignore start - handled deeper in the chain */\n (er: unknown) => {\n this.running.delete(n)\n this.promiseWaiting.delete(n)\n throw er\n },\n /* c8 ignore stop */\n )\n this.running.set(n, p)\n return p\n }\n\n async #step(n: Node, path: Node[]) {\n const dependents = this.dependents.get(n) ?? new Set()\n this.dependents.set(n, dependents)\n\n const deps = await this.getDeps(n)\n const awaiting: Promise<void>[] = []\n const depPath = [...path, n]\n\n // Initialize waiting set for this node\n const waitingOn = new Set<Node>()\n this.promiseWaiting.set(n, waitingOn)\n\n for (const d of deps) {\n /* c8 ignore next */\n if (this.abortController.signal.aborted) return\n // self-link, skip\n if (d === n) continue\n if (this.cycleCheck(n, depPath, d)) continue\n /* c8 ignore next */\n if (this.settled.get(d)) continue\n\n const runningPromise = this.running.get(d)\n if (runningPromise) {\n // Check if d is already waiting for n (promise-level cycle)\n if (this.#isWaitingFor(d, n)) {\n // Treat as cycle to prevent deadlock\n void this.onCycle(d, [n, d], depPath)\n continue\n }\n }\n\n // Record that n is waiting for d\n waitingOn.add(d)\n awaiting.push(runningPromise ?? this.#walk(d, depPath))\n }\n\n /* c8 ignore next */\n if (this.abortController.signal.aborted) return\n await Promise.all(awaiting)\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (this.abortController.signal.aborted) return\n const depRes = new Map<Node, Result | undefined>(\n deps.map(d => [d, this.results.get(d)]),\n )\n try {\n this.handleValue(await this.visit(n, path, depRes), n)\n } catch (er) {\n this.handleError(er, n, path)\n }\n }\n\n async run(): Promise<void> {\n const promises: Promise<void>[] = []\n for (const n of this.options.graph) {\n promises.push(this.#walk(n, []))\n }\n await Promise.all(promises)\n }\n}\n\n/** Synchronous graph runner */\nexport class RunnerSync<Node, Result> extends RunnerBase<\n Node,\n Result,\n true,\n RunnerOptionsSync<Node, Result>\n> {\n getDeps(n: Node) {\n if (this.abortController.signal.aborted) return []\n return this.options.getDeps(n)\n }\n\n visit(n: Node, path: Node[], depResults: DepResults<Node, Result>) {\n const { signal } = this.abortController\n return this.options.visit(n, signal, path, depResults)\n }\n\n onCycle(n: Node, cycle: Node[], path: Node[]) {\n /* c8 ignore next */\n if (this.abortController.signal.aborted) return\n this.options.onCycle?.(n, cycle, path)\n }\n\n #walk(n: Node, path: Node[]) {\n /* c8 ignore start */\n if (this.settled.get(n)) return\n /* c8 ignore stop */\n this.#step(n, path)\n }\n\n #step(n: Node, path: Node[]) {\n const dependents = this.dependents.get(n) ?? new Set()\n this.dependents.set(n, dependents)\n\n const deps = this.getDeps(n)\n const depPath = [...path, n]\n for (const d of deps) {\n if (this.abortController.signal.aborted) return\n /* c8 ignore next */\n if (d === n) continue\n if (this.cycleCheck(n, depPath, d)) continue\n if (!this.settled.get(d)) this.#walk(d, depPath)\n }\n\n if (this.abortController.signal.aborted) return\n const depRes = new Map<Node, Result | undefined>(\n deps.map(d => [d, this.results.get(d)]),\n )\n try {\n this.handleValue(this.visit(n, path, depRes), n)\n } catch (er) {\n this.handleError(er, n, path)\n }\n }\n\n run(): Map<Node, Result> {\n for (const n of this.options.graph) {\n this.#walk(n, [])\n }\n return this.results\n }\n}\n\n/**\n * Asynchronous graph traversal method\n *\n * If `failFast:false` is set in the options, then an AggregateError\n * will be raised if there were any failures. Otherwise, a normal Error\n * is raised on failure.\n */\nexport const graphRun = async <Node, Result>(\n options: RunnerOptions<Node, Result>,\n): Promise<Map<Node, Result>> => {\n const runner = new Runner(options, graphRun)\n await runner.run()\n if (runner.errors.length) {\n const e = new AggregateError(\n runner.errors,\n 'failed graph traversal',\n )\n Error.captureStackTrace(e, graphRun)\n throw e\n }\n return runner.results\n}\n\n/**\n * Synchronous graph traversal method\n *\n * If `failFast:false` is set in the options, then an AggregateError\n * will be thrown if there were any failures. Otherwise, a normal Error\n * is thrown on failure.\n */\nexport const graphRunSync = <Node, Result>(\n options: RunnerOptionsSync<Node, Result>,\n): Map<Node, Result> => {\n const runner = new RunnerSync(options, graphRunSync)\n runner.run()\n if (runner.errors.length) {\n const e = new AggregateError(\n runner.errors,\n 'failed graph traversal',\n )\n Error.captureStackTrace(e, graphRunSync)\n throw e\n }\n return runner.results\n}\n\n/**\n * Asynchronous graph traversal, capturing all error/result\n * statuses.\n */\nexport const allSettled = async <Node, Result>(\n options: RunnerOptions<Node, Result>,\n): Promise<SettledMap<Node, Result>> => {\n const runner = new Runner(\n { ...options, failFast: false },\n allSettled,\n )\n await runner.run()\n return runner.settled\n}\n\n/**\n * Synchronous graph traversal, capturing all error/result\n * statuses.\n */\nexport const allSettledSync = <Node, Result>(\n options: RunnerOptionsSync<Node, Result>,\n): SettledMap<Node, Result> => {\n const runner = new RunnerSync(\n { ...options, failFast: false },\n allSettledSync,\n )\n runner.run()\n return runner.settled\n}\n\n/**\n * Asynchronous graph traversal, returning the first successful visit.\n * If all visits fail, then an AggregateError is raised with all errors\n * encountered.\n */\nexport const any = async <Node, Result>(\n options: RunnerOptions<Node, Result>,\n): Promise<Result> => {\n const ac = new AbortController()\n let result!: Result\n let found = false\n const runner = new Runner<Node, Result>(\n {\n ...options,\n failFast: false,\n signal: ac.signal,\n visit: async (node, signal, path, depResults) => {\n try {\n result = await options.visit(node, signal, path, depResults)\n found = true\n ac.abort('found')\n } catch {}\n return result\n },\n },\n any,\n )\n await runner.run()\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (!found) {\n const e = new AggregateError(\n runner.errors,\n 'failed graph traversal',\n )\n Error.captureStackTrace(e, any)\n throw e\n }\n return result\n}\n\n/**\n * Synchronous graph traversal, returning the first successful visit.\n * If all visits fail, then an AggregateError is thrown with all errors\n * encountered.\n */\nexport const anySync = <Node, Result>(\n options: RunnerOptionsSync<Node, Result>,\n): Result => {\n const ac = new AbortController()\n let result!: Result\n let found = false\n const runner = new RunnerSync<Node, Result>(\n {\n ...options,\n failFast: false,\n signal: ac.signal,\n visit: (node, signal, path, depResults) => {\n try {\n result = options.visit(node, signal, path, depResults)\n found = true\n ac.abort('found')\n } catch {}\n return result\n },\n },\n anySync,\n )\n runner.run()\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (!found) {\n const e = new AggregateError(\n runner.errors,\n 'failed graph traversal',\n )\n Error.captureStackTrace(e, anySync)\n throw e\n }\n return result\n}\n\n/**\n * Asynchronous graph traversal, resolving or rejecting when the first visit\n * resolves or rejects.\n */\nexport const race = async <Node, Result>(\n options: RunnerOptions<Node, Result>,\n): Promise<Result> => {\n const ac = new AbortController()\n let result!: Result\n const runner = new Runner<Node, Result>(\n {\n ...options,\n failFast: true,\n signal: ac.signal,\n visit: async (node, signal, path, depResults) => {\n try {\n result = await options.visit(node, signal, path, depResults)\n ac.abort('found')\n /* c8 ignore next */\n } catch {}\n return result\n },\n },\n race,\n )\n await runner.run()\n return result\n}\n\n/**\n * Synchronous graph traversal, returning or throwing when the first visit\n * is completed.\n */\nexport const raceSync = <Node, Result>(\n options: RunnerOptionsSync<Node, Result>,\n): Result => {\n const ac = new AbortController()\n let result!: Result\n const runner = new RunnerSync<Node, Result>(\n {\n ...options,\n failFast: true,\n signal: ac.signal,\n visit: (node, signal, path, depResults) => {\n try {\n result = options.visit(node, signal, path, depResults)\n ac.abort('found')\n /* c8 ignore next */\n } catch {}\n return result\n },\n },\n race,\n )\n runner.run()\n return result\n}\n"]}