Composing flows
Flows can call other flows. A flow can run a child flow as a step and use its result, or hand the whole journey off to another flow once its own work is done. This lets you break a large process into smaller flows and reuse them across your project.
To whoever runs it, a composed flow behaves as a single flow. The steps from the child flows are merged into one list, ordered oldest first, and the run keeps a single URL and trace.
Running a child flow
Use ctx.flows.run to run a child flow inline and get its typed result back. The child flow runs to completion before the parent continues, so you can branch on its result with plain TypeScript.
Declare the child flow in your schema like any other flow:
flow DispatchOrder {
inputs {
orderId ID
}
@permission(roles: [Operator])
}Then import it into the parent's function and run it:
import { ProcessOrder, DispatchOrder } from "@teamkeel/sdk";
export default ProcessOrder({}, async (ctx, inputs) => {
const result = await ctx.flows.run(DispatchOrder, {
name: "dispatch-1",
inputs: { orderId: inputs.orderId },
});
return ctx.complete({ data: { dispatched: result.orderId } });
});The name gives the child run a unique name within the parent, in the same way step names are unique within a flow. The child's inputs and its result are fully typed from the schema, so result carries the shape the child returned through its own ctx.complete.
Handing off to a successor
Use ctx.flows.handoff to complete the current flow and pass the journey to a successor flow. The successor keeps the same URL and trace as the flow that handed off, so the whole thing reads as one continuous run.
import { ReviewOrder, NextStage } from "@teamkeel/sdk";
export default ReviewOrder({}, async (ctx, inputs) => {
// ... this flow's work ...
return ctx.flows.handoff(NextStage, { inputs: { stage: "next" } });
});Unlike ctx.flows.run, a handoff does not return to the caller. The current flow finishes and the successor takes over.
The merged single-flow view
A composed flow presents as one flow to whoever runs it. The steps of the parent and its children are combined into a single list, ordered oldest first, under one run with one URL and one trace. You do not need to stitch the child runs together yourself.
Limits in this version
Some limits apply in this first version of composed flows:
- Composition depth is capped at 8.
- A single journey can run at most 1000 child flows.
- A child flow runs with the parent's permissions and does not re-check its own
runpermission. Set permissions on the entry flow accordingly. - Handing off from a child flow is not supported yet. Return a result to the parent with
ctx.completeinstead, and let the parent decide what to do next.
For more on writing flows, see Writing flows and the function steps guide.