@tokens-studio/graph-engine
Version:
An execution engine to handle Token Studios generators and resolvers
287 lines • 8.96 kB
TypeScript
import { GraphSchema } from '../schemas/index.js';
import { Edge } from '../programmatic/edge.js';
import { ILogger } from './interfaces.js';
import { Input } from '../programmatic/input.js';
import { Node } from '../programmatic/node.js';
import { Output } from '../programmatic/output.js';
import type { ExternalLoader, NodeRun, NodeStart } from '../types.js';
import type { NodeFactory, SerializedGraph } from './types.js';
export type CapabilityFactory = {
name: string;
register: (graph: Graph) => any;
version?: string;
};
export type InputDefinition = {
value: any;
type?: GraphSchema;
};
export type GraphExecuteOptions = {
/**
* Throws an error if the input/output nodes are not found
*/
strict?: boolean;
inputs?: Record<string, InputDefinition>;
/**
* Whether to track and emit stats as part of the execution
*/
stats?: boolean;
/**
* Whether to provide a journal of the execution
*/
journal?: boolean;
};
export type EdgeOpts = {
id: string;
source: string;
target: string;
sourceHandle: string;
targetHandle: string;
/**
* Any additional data to be stored on the edge
*/
annotations?: Record<string, any>;
/**
* Whether to automatically update the graph when the state changes or to wait for an explicit call to update
*/
noPropagate?: boolean;
};
export type FinalizerType = 'serialize' | 'output';
export type FinalizerLookup = {
serialize: SerializedGraph;
output: any;
};
export type SubscriptionLookup = {
nodeAdded: Node;
nodeRemoved: string;
edgeAdded: Edge;
edgeRemoved: string;
nodeUpdated: Node;
edgeUpdated: Edge;
start: object;
stop: object;
pause: object;
resume: object;
edgeIndexUpdated: Edge;
valueSent: Edge[];
nodeExecuted: NodeRun;
nodeStarted: NodeStart;
};
export type ListenerType<T> = [T] extends [(...args: infer U) => any] ? U : [T] extends [void] ? [] : [T];
export type SubscriptionExecutor<T extends keyof SubscriptionLookup> = (data: SubscriptionLookup[T]) => void;
export type SerializerType<T extends keyof FinalizerLookup> = FinalizerLookup[T];
export type FinalizerExecutor<Type extends keyof FinalizerLookup> = (value: SerializerType<Type>) => SerializerType<Type>;
export type PlayState = 'playing' | 'paused' | 'stopped';
export interface IGraph {
/**
* Whether to automatically update the graph when the state changes or to wait for an explicit call to update
*/
autoUpdate?: boolean;
annotations?: Record<string, any>;
}
export interface IUpdateOpts {
/**
* If true, no memoization will be performed
*/
noMemo?: boolean;
/**
* If true, the update will not be propagated to the successor nodes
*/
noRecursive?: boolean;
/**
* If true, we won't compare the input values to see if the node needs to be updated
*/
noCompare?: boolean;
}
export interface StatRecord {
start: number;
end: number;
error?: Error;
}
export interface BatchExecution {
start: number;
end: number;
stats?: Record<string, StatRecord>;
order: string[];
output?: {
[key: string]: {
value: any;
type: GraphSchema;
};
};
}
/**
* This is our internal graph representation that we use to perform transformations on
*/
export declare class Graph {
private finalizers;
private listeners;
annotations: Record<string, any>;
nodes: Record<string, Node>;
edges: Record<string, Edge>;
capabilities: Record<string, any>;
logger: ILogger;
messageQueue: {
eventName: string;
data: any;
origin: Node;
}[];
externalLoader?: ExternalLoader;
/**
* Outgoing edges from a node as an array of edgeIds
* First key is the source node
* Values are the edgeIds
*/
successorNodes: Record<string, string[]>;
constructor(input?: IGraph);
/**
* Meant to be used internally by nodes to load resources
* @param uri
* @param node
* @param data
* @returns
*/
loadResource(uri: string, node: Node, data?: any): Promise<any>;
/**
* Connects two nodes together. If the target is variadic, it will automatically add the index to the edge data if not provided
* @param source
* @param sourceHandle
* @param target
* @param targetHandle
* @param variadicIndex
* @returns
*/
connect(source: Node, sourceHandle: Output, target: Node, targetHandle: Input, variadicIndex?: number): Edge;
/**
* Checks to see if there exists any connection for an input
* @param source
* @param port
* @returns
*/
hasConnectedInput(source: Node, input: Input): boolean;
/**
* Clears the graph
*/
clear(): void;
addNode(node: Node): void;
/**
* Removes a node from the graph and disconnects all the edges.
* @param nodeId
* @returns true if the node was removed, false if the node was not found
*/
removeNode(nodeId: string): boolean;
removeEdge(edgeId: string): void;
/**
* Retrieves a flat list of all the nodes ids in the graph
* @returns
*/
getNodeIds(): string[];
/**
* Will forcefully update a node in the graph. This will also update all the edges that are connected to the node recursively
* @throws[Error] if the node is not found
* @param nodeID
*/
update(nodeID: string, opts?: IUpdateOpts): Promise<void>;
/**
* Serialize the graph for transport
* @returns
*/
serialize(): SerializedGraph;
/**
* Extracts the nodes types from a serialized graph
* @param graph
*/
static extractTypes(graph: SerializedGraph): string[];
checkCapabilitites(annotations: Record<string, any>): void;
/**
* Creates a graph from a serialized graph. Note that the types of the nodes must be present in the lookup.
* @param input
* @param lookup
*/
deserialize(serialized: SerializedGraph, lookup: Record<string, NodeFactory>): Promise<Graph>;
registerCapability(factory: CapabilityFactory): void;
clone(): Graph;
private forEachNode;
/**
* Starts the graph in network mode
* TODO Complete
*/
start: () => void;
/**
* Stops the graph in network mode
*/
stop: () => void;
pause: () => void;
resume: () => void;
/**
* Triggers a message on the graph
* TODO Complete
* @param eventName
* @param data
* @param origin
*/
trigger: (eventName: string, data: any, origin: Node) => void;
/**
* Executes the graph as a single batch. This will execute all the nodes in the graph and return the output of the output node
* @param opts
* @throws {BatchRunError}
* @returns
*/
execute(opts?: GraphExecuteOptions): Promise<BatchExecution>;
/**
* Returns the ids of the node that are immediate successors of the given node. O(m) the amount of edges
* @param nodeId
* @returns
*/
successors(nodeId: any): Node[];
/**
* Returns the ids of the node that are immediate predecessors of the given node O(m) the amount of edges
* @param nodeId
* @returns
*/
predecessors(nodeId: string): Node[];
/**
* Triggers a ripple effect on the graph starting from the given edge
* @returns
*/
ripple(output: Output): void;
/**
* Triggers the execution of the node and updates the successor nodes
* @param nodeId
* @param oneShot
* @returns
*/
propagate(nodeId: string, oneShot?: boolean): Promise<void>;
/**
* Creates an edge connection between two nodes
* @param source
* @param target
* @param data
*/
createEdge(opts: EdgeOpts): Edge;
/**
* Return all edges that point into the nodes inputs.
* O(m) the amount of edges
*/
inEdges(nodeId: string, sourceHandle?: string): Edge[];
/**
* Return all edges that are pointed out by node v.
* O(m) the amount of edges
*/
outEdges(nodeId: string, targetHandle?: string): Edge[];
/**
* Looks up a node by its id
* @param nodeId
* @returns
*/
getNode(nodeId: string): Node | undefined;
/**
* Looks up an edge by its id
* @param edgeId
* @returns
*/
getEdge(edgeId: string): Edge | undefined;
emit<P extends keyof SubscriptionLookup = keyof SubscriptionLookup>(type: P, data: SubscriptionLookup[P]): void;
on<P extends keyof SubscriptionLookup = keyof SubscriptionLookup>(type: P, listener: (...args: ListenerType<SubscriptionLookup[P]>) => void): () => void;
onFinalize<T extends keyof FinalizerLookup = keyof FinalizerLookup>(type: T, listener: (...args: ListenerType<FinalizerLookup[T]>) => FinalizerLookup[T]): () => void;
}
//# sourceMappingURL=graph.d.ts.map