@asyncflowstate/core is a framework-agnostic, TypeScript-first engine for orchestrating complex async operations, retries, and state management.
import { Flow } from "@asyncflowstate/core";
// Create and execute a flow
const flow = new Flow(async (id: string) => {
const response = await fetch(`/api/user/${id}`);
return response.json();
});
flow.subscribe((state) => console.log(state));
await flow.execute("user-123");The main class for managing async operations.
new Flow<TData, TError, TArgs>(
action: (...args: TArgs) => Promise<TData> | AsyncIterable<any> | ReadableStream<any>,
options?: FlowOptions<TData, TError, TArgs>
)status- Current lifecycle phase:'idle' | 'loading' | 'streaming' | 'success' | 'error'data- Result of the last successful execution (or accumulated stream data)error- Error object from the last failureprogress- Execution progress (0-100)state- Read-only snapshot of the full statesignals- Inter-flow communication channels (start,success,error,cancel,stream,reset,restore)
execute(...args)- Initiates the flow execution. Handles debouncing/throttling/circuit breaking.cancel()- Aborts the current executionreset()- Resets flow to idle state and clears data/errorsubscribe(listener)- Subscribes to state changessetOptions(options)- Updates options at runtimesetProgress(val)- Manually update progress during execution
Execute multiple flows sequentially.
import { FlowSequence } from "@asyncflowstate/core";
const sequence = new FlowSequence([
{ name: "Auth", flow: loginFlow },
{ name: "Fetch", flow: dataFlow, mapInput: (auth) => auth.token },
]);
await sequence.execute();Execute multiple flows in parallel.
import { FlowParallel } from "@asyncflowstate/core";
const parallel = new FlowParallel([flow1, flow2], "all");
await parallel.execute();const flow = new Flow(fetchData, {
circuitBreaker: {
failureThreshold: 5,
resetTimeout: 30000,
},
circuitBreakerKey: "api-service-v1", // Persisted to localStorage
});const upload = new Flow(uploadFile);
const process = new Flow(processFile, {
triggerOn: [upload.signals.success],
});If the action returns an AsyncIterable or ReadableStream, the flow treats it as a stream, accumulates data (if strings), and emits stream signals for each chunk.
flow.use({
onStart: (context) => console.log("Started", context),
onSuccess: (data) => console.log("Success", data),
onStream: (chunk) => console.log("Chunk", chunk),
});import type {
FlowState,
FlowStatus,
FlowOptions,
FlowEvent,
RetryOptions,
CircuitBreakerOptions,
} from "@asyncflowstate/core";