Flow Signal integration
Exact signatures for static Signal waits and existing local Flow signal delivery.
Public named exports on this page come from @use-crux/core/flow. Helper names
shown inside the flow() overload describe compiler inference and are not
additional named exports.
Static and local declarations
type FlowSignalSpec<TPayload = unknown> =
| ZodType<TPayload>
| NoPayloadSignal;
type FlowSignalDeclaration = FlowSignalSpec | StaticSignalSource;
type FlowSignalMap = Readonly<
Record<string, FlowSignalDeclaration>
>;
interface FlowDefinitionOptions<
TSignals extends FlowSignalMap = FlowSignalMap,
> {
readonly signals: TSignals;
}FlowSignalSpec declares an existing local Flow signal addressed by name and
flowId. StaticSignalSource declares a Signal definition or filtered view
that the Flow may pass to waitFor(source). One map may contain both.
type DeclaredFlowSignalSource<TSignals extends FlowSignalMap> = Extract<
TSignals[keyof TSignals],
StaticSignalSource
>;
type FlowSignalPayload<TSpec> =
TSpec extends ZodType<infer TPayload>
? TPayload
: TSpec extends NoPayloadSignal
? void
: never;DeclaredFlowSignalSource restricts a static wait to source types represented
in that Flow's map. FlowSignalPayload infers only local signal payloads.
flow(name, options, handler)
function flow<
const TSignals extends FlowSignalMap,
THandler extends InferredFlowHandler<TSignals>,
>(
name: string,
options: FlowDefinitionOptions<TSignals>,
handler: THandler,
): FlowHandle<HandlerOutput<THandler>, HandlerInput<THandler>, TSignals>;InferredFlowHandler, HandlerOutput, and HandlerInput represent the
factory's inference internals; callers provide an ordinary handler. Definition
is inert. Activating a Flow with any static Signal source performs durable
capability preflight before allocating work or invoking the handler.
FlowScope.waitFor(source, options?)
interface FlowWaitForSignalOptions {
readonly timeout?: string;
}
waitFor<const TSource extends DeclaredFlowSignalSource<TSignals>>(
source: TSource,
options?: FlowWaitForSignalOptions,
): Promise<SignalOccurrenceFor<TSource>>;Registers the Flow suspension and required durable Signal delivery atomically.
The Promise resolves during Flow execution with the complete occurrence after
a matching delivery wins. timeout uses existing Flow duration syntax such as
"30m" or "24h"; omission waits without a deadline.
This overload is structurally separate from the existing event overload:
waitFor<TPayload = JsonValue>(
event: string | FlowWaitForEvent<TPayload>,
options?: FlowWaitForOptions,
): Promise<TPayload>;Local Flow signals
interface NoPayloadSignal {
readonly _tag: "crux.flow.no_payload";
}
function noPayload(): NoPayloadSignal;
interface FlowSignalOptions {
readonly resume: boolean;
}noPayload() creates the reusable marker for a local signal-map entry.
FlowSignalOptions.resume controls whether local delivery nudges the configured
Runtime immediately; false records it for a later explicit resume.
For a local schema entry, FlowHandle.signal has this inferred shape:
signal<TName extends keyof TSignals & string>(
flowId: string,
signalName: TSignals[TName] extends FlowSignalSpec ? TName : never,
...args: [FlowSignalPayload<TSignals[TName]>] extends [void]
? [options?: FlowSignalOptions]
: [
payload: FlowSignalPayload<TSignals[TName]>,
options?: FlowSignalOptions,
]
): Promise<void>;For noPayload() the payload argument is omitted. Static Signal entries are
excluded from FlowHandle.signal; publish them through Signal.publish().
InvalidSignalPayloadError
class InvalidSignalPayloadError extends Error {
readonly signalName: string;
constructor(signalName: string, detail: string);
}Thrown when a local Flow signal payload fails its declared Zod schema or sends
data to a noPayload() entry. It does not represent Signal publication schema
failure; that uses SignalValidationError.
Filters and helper types
Exact signatures for Signal match data, predicates, filtered views, and static-source occurrence inference.
Providers and transports
Exact public API for Signal providers, webhook, polling, managed stream, SSE, and WebSocket transports, managed bindings, accept/normalize lifecycle, statistics, and projections.