Type Reference¶
All types exported from @peleke.s/cadence, organized by module.
Core Types¶
BaseSignal¶
The base shape for all signals.
interface BaseSignal<T extends string = string, P = unknown> {
type: T; // Signal type identifier
ts: number; // Unix timestamp (ms)
id: string; // Unique signal ID
source?: string; // Origin identifier
payload: P; // Signal-specific data
}
DefineSignals¶
Type helper that creates a discriminated union from a signal map.
type DefineSignals<M extends Record<string, unknown>> = {
[K in keyof M]: BaseSignal<K & string, M[K]>;
}[keyof M];
Usage:
type MySignals = DefineSignals<{
"file.changed": { path: string };
"cron.fired": { jobId: string };
}>;
// Equivalent to:
// BaseSignal<"file.changed", { path: string }> | BaseSignal<"cron.fired", { jobId: string }>
SignalPayload¶
Extract the payload type for a specific signal type.
type SignalPayload<S extends BaseSignal, T extends S["type"]> =
Extract<S, { type: T }>["payload"];
SignalHandler¶
Handler for a specific signal type.
type SignalHandler<S extends BaseSignal, T extends S["type"] = S["type"]> =
(signal: Extract<S, { type: T }>) => void | Promise<void>;
AnySignalHandler¶
Handler for any signal.
type AnySignalHandler<S extends BaseSignal> = (signal: S) => void | Promise<void>;
Middleware¶
Middleware function. Receives signal and next().
type Middleware<S extends BaseSignal> = (
signal: S,
next: () => Promise<void>,
) => Promise<void>;
BusStats¶
Bus statistics for observability.
interface BusStats {
emitted: number; // Total signals emitted
handled: number; // Total handler invocations
errors: number; // Total handler errors caught
handlers: number; // Registered type-specific handlers
anyHandlers: number; // Registered any-handlers
middleware: number; // Registered middleware
}
SignalBus¶
SignalBus¶
interface SignalBus<S extends BaseSignal = BaseSignal> {
emit(signal: S): Promise<void>;
on<T extends S["type"]>(type: T, handler: SignalHandler<S, T>): () => void;
onAny(handler: AnySignalHandler<S>): () => void;
use(middleware: Middleware<S>): void;
clear(): void;
stats(): BusStats;
replay(): Promise<number>;
}
SignalBusOptions¶
interface SignalBusOptions<S extends BaseSignal = BaseSignal> {
transport?: Transport<S>;
store?: SignalStore<S>;
executor?: HandlerExecutor<S>;
onError?: (signal: S, handlerName: string, error: unknown) => void;
}
Transport¶
Transport¶
interface Transport<S extends BaseSignal = BaseSignal> {
emit(signal: S): Promise<void>;
subscribe(handler: AnySignalHandler<S>): () => void;
}
Store¶
SignalStore¶
interface SignalStore<S extends BaseSignal = BaseSignal> {
save(signal: S): Promise<void>;
markAcked(signalId: string): Promise<void>;
getUnacked(): Promise<S[]>;
}
Executor¶
HandlerExecutor¶
interface HandlerExecutor<S extends BaseSignal = BaseSignal> {
execute(handler: AnySignalHandler<S>, signal: S): Promise<void>;
stats(): { queued: number; processing: number };
}
Source¶
Source¶
interface Source<S extends BaseSignal = BaseSignal> {
name: string;
start(emit: (signal: S) => Promise<void>): Promise<void>;
stop(): Promise<void>;
}
FileEvent¶
interface FileEvent {
type: "add" | "change" | "unlink";
path: string;
ts: number;
}
FileEventType¶
type FileEventType = "add" | "change" | "unlink";
FileWatcherOptions¶
interface FileWatcherOptions<S extends BaseSignal> {
paths: string | string[];
events?: FileEventType[];
toSignal: (event: FileEvent) => S | null;
chokidar?: {
ignored?: string | RegExp | ((path: string) => boolean);
usePolling?: boolean;
interval?: number;
ignoreInitial?: boolean;
awaitWriteFinish?: boolean | { stabilityThreshold?: number; pollInterval?: number };
};
}
CronJob¶
interface CronJob {
id: string;
name: string;
expr: string;
tz?: string;
enabled?: boolean;
}
CronSourceOptions¶
interface CronSourceOptions<S extends BaseSignal> {
jobs: CronJob[];
toSignal: (job: CronJob, firedAt: number) => S;
onFire?: (job: CronJob) => void;
onError?: (job: CronJob, error: Error) => void;
}
Clock¶
Tick¶
interface Tick {
ts: number;
seq: number;
reason: "interval" | "bridge" | "manual" | "catchup";
drift?: number;
}
TickHandler¶
type TickHandler = (tick: Tick) => void | Promise<void>;
BackpressurePolicy¶
type BackpressurePolicy = "block" | "drop" | "adaptive";
TickStats¶
interface TickStats {
tickCount: number;
droppedTicks: number;
errors: number;
avgHandlerMs: number;
avgDriftMs: number;
lastTickAt: number;
maxHandlerMs: number;
}
Clock¶
interface Clock {
start(handler: TickHandler): void;
stop(): void;
now(): number;
stats(): TickStats;
readonly running: boolean;
readonly seq: number;
}
IntervalClockOptions¶
interface IntervalClockOptions {
intervalMs: number;
backpressure?: BackpressurePolicy;
maxCatchUpTicks?: number;
onDriftWarning?: (driftMs: number) => void;
onError?: (error: unknown) => void;
}
TestClock¶
interface TestClock extends Clock {
tick(count?: number): Promise<void>;
advanceBy(ms: number): Promise<void>;
flush(): Promise<void>;
reset(): void;
readonly pendingTicks: number;
}
BridgeClock¶
interface BridgeClock extends Clock {
push(reason?: string): void;
}
ClockSourceOptions¶
interface ClockSourceOptions<S extends BaseSignal> {
clock: Clock;
toSignal: (tick: Tick) => S;
name?: string;
}