Quick Start¶
Build a file-watching signal pipeline in under 5 minutes.
Step 1: Define your signals¶
Every Cadence project starts by defining signal types. Use DefineSignals to create a type-safe union from a simple map:
import { type DefineSignals } from "@peleke.s/cadence";
type MySignals = DefineSignals<{
"file.changed": { path: string; event: "add" | "change" | "unlink" };
"task.found": { file: string; line: number; text: string };
}>;
Each key becomes a signal type, each value becomes the payload shape. TypeScript enforces this everywhere.
Step 2: Create a bus and subscribe¶
import { createSignalBus } from "@peleke.s/cadence";
const bus = createSignalBus<MySignals>();
// Type-specific handler — only receives "file.changed" signals
bus.on("file.changed", async (signal) => {
console.log(`[${signal.payload.event}] ${signal.payload.path}`);
});
// Any-handler — receives all signals
bus.onAny(async (signal) => {
console.log(`Signal: ${signal.type} at ${new Date(signal.ts).toISOString()}`);
});
Step 3: Create a source and connect it¶
Sources produce signals from external events. Connect them to the bus with start():
import { createFileWatcherSource } from "@peleke.s/cadence";
const watcher = createFileWatcherSource<MySignals>({
paths: ["./notes"],
toSignal: (event) => ({
type: "file.changed",
ts: Date.now(),
id: crypto.randomUUID(),
payload: { path: event.path, event: event.type },
}),
});
// Start watching — file changes flow through the bus to your handlers
await watcher.start((signal) => bus.emit(signal));
Complete Example¶
import {
createSignalBus,
createFileWatcherSource,
type DefineSignals,
} from "@peleke.s/cadence";
type MySignals = DefineSignals<{
"file.changed": { path: string; event: "add" | "change" | "unlink" };
}>;
const bus = createSignalBus<MySignals>();
bus.on("file.changed", async (signal) => {
console.log(`[${signal.payload.event}] ${signal.payload.path}`);
});
const watcher = createFileWatcherSource<MySignals>({
paths: ["./notes"],
toSignal: (event) => ({
type: "file.changed",
ts: Date.now(),
id: crypto.randomUUID(),
payload: { path: event.path, event: event.type },
}),
});
await watcher.start((signal) => bus.emit(signal));
// Now modify a file in ./notes and watch the console
What's Next?¶
- Core Concepts — understand the pluggable architecture
- Signal Bus Guide — middleware, replay, error handling
- Sources Guide — file watcher and cron scheduling
- Clock System Guide — interval timers, testing, and bridging