The Basics
Two-part pattern
Define a trigger source (how to subscribe) and a trigger target (what to call). Pikku connects them and handles lifecycle.
// 1. Define the trigger source — how to subscribe
const redisSubscribe = pikkuTriggerFunc<
{ channels: string[] },
{ channel: string; message: any }
>(async ({ redis }, { channels }, { trigger }) => {
const subscriber = redis.duplicate()
subscriber.on('message', (channel, message) => {
// Fire the trigger with typed data
trigger.invoke({ channel, message: JSON.parse(message) })
})
await subscriber.subscribe(...channels)
// Return a teardown function for cleanup
return async () => {
await subscriber.unsubscribe()
await subscriber.quit()
}
})
// 2. Wire source to target
wireTrigger({
name: 'order-events',
func: onOrderEvent, // Target: your Pikku function
})
wireTriggerSource({
name: 'order-events',
func: redisSubscribe, // Source: the subscription
input: { channels: ['orders:created', 'orders:updated'] },
})
Source → Target
Source subscribes to external events, target is your business logic — fully decoupled
Typed payloads
The trigger source defines input (config) and output (event data) — both type-checked
Automatic teardown
Return a cleanup function — Pikku calls it on shutdown for graceful disconnection
Event Sources
Subscribe to anything
The trigger source is just a function. If it has a subscribe/callback pattern, you can wire it.
Redis Pub/Sub
Subscribe to Redis channels. Fire triggers on every message.
PostgreSQL LISTEN/NOTIFY
React to row changes via pg_notify. Trigger on INSERT, UPDATE, DELETE.
Polling
setInterval-based polling. Check an API or database on a timer.
Anything with a callback
File watchers, webhooks, MQTT, AMQP — if it has a subscribe pattern, it works.
Lifecycle
Setup, fire, teardown
Pikku manages the full trigger lifecycle — from subscription setup to graceful shutdown.
Setup
TriggerService starts. Each source function runs, subscribes to its event source.
Fire
External event occurs. trigger.invoke(data) dispatches to the target function via RPC.
Teardown
triggerService.stop() calls each source's cleanup function. Connections closed gracefully.
Targets can be functions or workflows. A trigger can invoke an RPC function directly, or start a workflow — both are supported via the same wiring.
Start wiring triggers in 5 minutes
One command to scaffold a project with trigger wiring already configured.
MIT Licensed · Redis, PostgreSQL, polling & more