topology-runner
Version:
Run a topology consisting of a directed acyclic graph
128 lines (102 loc) • 2.75 kB
text/typescript
import EventEmitter from 'eventemitter3'
type UpdateState = (state: any) => void
export type Initialized = Record<string, any>
export interface BaseInput {
data: any[]
node: string
context?: any
}
// Work
export interface WorkInput extends BaseInput {
updateState: UpdateState
state?: any
signal: AbortSignal
}
export type WorkOutput = Promise<any>
export type RunFn = (arg: WorkInput) => WorkOutput
export interface WorkNodeDef {
run: RunFn
deps: string[]
type?: 'work'
}
// Branching
export interface BranchingInput extends BaseInput {
branch: (node: string, reason?: string) => BranchingOutput
none: (reason?: string) => BranchingOutput
}
export interface BranchingOutput {
node: string | symbol
reason?: string
}
export interface BranchingNodeDef {
run: (arg: BranchingInput) => BranchingOutput
deps: string[]
type: 'branching'
}
// Suspension
export type SuspensionInput = WorkInput
export type SuspensionOutput = Promise<void>
export interface SuspensionNodeDef {
run?: (arg: SuspensionInput) => SuspensionOutput
deps: string[]
type: 'suspension'
}
export type NodeType = 'work' | 'branching' | 'suspension'
export type Input = BranchingInput | SuspensionInput | WorkInput
export type Output = BranchingOutput | SuspensionOutput | WorkOutput
export type NodeDef = BranchingNodeDef | SuspensionNodeDef | WorkNodeDef
export type DAG = Record<string, { deps: string[], type: NodeType }>
export type Spec = Record<string, NodeDef>
export interface Options {
includeNodes?: string[]
excludeNodes?: string[]
data?: any // Fed into starting nodes (i.e., nodes with no dependencies)
context?: any // Fed to all nodes
}
export type Response = {
start(): Promise<void>
stop(): void
emitter: EventEmitter<Events, any>
getSnapshot(): Snapshot
}
export type Status =
| 'pending'
| 'running'
| 'completed'
| 'suspended'
| 'errored'
export type NodeStatus = Status | 'skipped'
export interface NodeData {
type: NodeType,
deps: string[]
status: NodeStatus
started?: Date
finished?: Date
input?: any[]
output?: any
state?: any
error?: any
selected?: string
reason?: string
}
export type SnapshotData = Record<string, NodeData>
export interface Snapshot {
status: Status
started: Date
finished?: Date
data: SnapshotData
}
export type ObjectOfPromises = Record<string | number, Promise<any>>
export type Events = 'data' | 'error' | 'done'
export type RunTopology = (spec: Spec, options?: Options) => Response
export type RunTopologyInternal = (
spec: Spec,
dag: DAG,
snapshot: Snapshot,
context: any
) => Response
export type ResumeTopology = (
spec: Spec,
snapshot?: Snapshot,
options?: Pick<Options, 'context'>
) => Response