TriggerCtx
The single argument every trigger handler receives. It bundles the matching event, a conditions snapshot, the actions proxy, the check DSL, runtime metadata and an AbortSignal. The shape is fully derived from the trigger’s TriggerSchema — destructure the fields you need.
Import
Section titled “Import”import type { TriggerCtx } from '@triggery/core';
Definition
Section titled “Definition”type TriggerCtx<S extends TriggerSchema, R extends ConditionKey<S> = never> = {
readonly event: EventOf<S>;
readonly conditions: ConditionsCtx<ConditionMap<S>, R>;
readonly actions: ActionsCtx<ActionMap<S>>;
readonly check: CheckCtx<ConditionMap<S>>;
readonly meta: MetaCtx;
readonly signal: AbortSignal;
};S is the trigger’s schema; R is the union of required condition keys (required: [...] in the config).
Fields
Section titled “Fields”event — EventOf<S>
Section titled “event — EventOf<S>”Discriminated union over S['events']. Each variant has { readonly name: K; readonly payload: EventMap<S>[K] }. Narrow with event.name.
type EventOf<S> = { name: 'open'; payload: { id: string } }
| { name: 'close'; payload: { id: string; reason: 'ok' | 'cancel' } };conditions — ConditionsCtx<ConditionMap<S>, R>
Section titled “conditions — ConditionsCtx<ConditionMap<S>, R>”Snapshot of all conditions, captured once at fire time. Keys listed in required appear as non-optional; others are T | undefined.
V1 limitation: required does not narrow in the type system — conditions.user stays User | undefined even when required: ['user']. Use check.is/all/any or an early if (!conditions.user) return; guard.
actions — ActionsCtx<ActionMap<S>>
Section titled “actions — ActionsCtx<ActionMap<S>>”Map of { [name]?: (payload) => void } plus three chainable timers:
| Method | Returns | Description |
|---|---|---|
actions.<name>?.(payload) | void | Invoke an action if it’s registered. Optional chain because no reactor may be mounted. |
actions.debounce(ms) | same shape | Wait until ms of silence before firing. |
actions.throttle(ms) | same shape | At most one fire per ms window. |
actions.defer(ms) | same shape | Wait ms before firing — no coalescing. |
check — CheckCtx<ConditionMap<S>>
Section titled “check — CheckCtx<ConditionMap<S>>”The predicate DSL. See createCheck. is, all, and any all NonNullable-narrow the value inside the predicate.
meta — MetaCtx
Section titled “meta — MetaCtx”Runtime metadata about the current run:
| Field | Type | Description |
|---|---|---|
runId | string | Unique per-run id. |
triggerId | string | The trigger that’s running. |
scheduledAt | number | performance.now() when the run was enqueued. |
cascadeDepth | number | 0 for top-level fires; n for the n-th cascade child. |
parentRunId? | string | Set when the run is part of a cascade. |
parentTriggerId? | string | Same — id of the upstream trigger. |
signal — AbortSignal
Section titled “signal — AbortSignal”Aborts when the runtime cancels the current run — e.g. a take-latest concurrency strategy supersedes it, the trigger is disabled or disposed, or the runtime itself is torn down. Pass it into fetch(url, { signal }), addEventListener('…', fn, { signal }), or check signal.aborted after any async wait.
Examples
Section titled “Examples”Destructure what you need
Section titled “Destructure what you need”import { createTrigger function createTrigger<S extends TriggerSchema>(config: CreateTriggerConfig<S>, runtime?: Runtime): Trigger<S>Create a trigger and register it in a runtime (the default runtime if none is passed). } from '@triggery/core';
createTrigger createTrigger<{
events: {
ping: void;
};
conditions: {
user: {
id: string;
} | null;
};
actions: {
log: string;
};
}>(config: CreateTriggerConfig<{
events: {
ping: void;
};
conditions: {
user: {
id: string;
} | null;
};
actions: {
log: string;
};
}>, runtime?: Runtime): Trigger<{
events: {
ping: void;
};
conditions: {
user: {
id: string;
} | null;
};
actions: {
log: string;
};
}>
Create a trigger and register it in a runtime (the default runtime if none is passed). <{
events events: {
ping: void;
}
: { ping ping: void : void };
conditions conditions: {
user: {
id: string;
} | null;
}
: { user user: {
id: string;
} | null
: { id id: string : string } | null };
actions actions: {
log: string;
}
: { log log: string : string };
}>({
id id: string : 'demo',
events events: readonly "ping"[] : ['ping'],
required required?: readonly "user"[] | undefinedRequired condition keys. The trigger will not run unless all of them are registered. : ['user'],
handler handler: TriggerHandler<{
events: {
ping: void;
};
conditions: {
user: {
id: string;
} | null;
};
actions: {
log: string;
};
}, never>
({ event event: {
readonly name: "ping";
readonly payload: void;
}
, conditions conditions: ConditionsCtx<{
user: {
id: string;
} | null;
}, never>
, actions actions: ActionsCtx<{
log: string;
}>
, check check: CheckCtx<{
user: {
id: string;
} | null;
}>
, meta meta: MetaCtx , signal signal: AbortSignal }) {
if (signal signal: AbortSignal .aborted AbortSignal.aborted: booleanThe **`aborted`** read-only property returns a value that indicates whether the asynchronous operations the signal is communicating with are aborted (`true`) or not (`false`).
[MDN Reference](https://developer.mozilla.org/docs/Web/API/AbortSignal/aborted) ) return;
if (!check check: CheckCtx<{
user: {
id: string;
} | null;
}>
.is is<"user">(key: "user", predicate: (value: {
id: string;
}) => boolean): boolean
('user', u u: {
id: string;
}
=> u u: {
id: string;
}
.id id: string .length String.length: numberReturns the length of a String object. > 0)) return;
actions actions: ActionsCtx<{
log: string;
}>
.log log?: ((payload: string) => void) | undefined ?.(`[run ${meta meta: MetaCtx .runId runId: string }] ${event event: {
readonly name: "ping";
readonly payload: void;
}
.name name: "ping" }`);
},
});event.name narrowing
Section titled “event.name narrowing”import { createTrigger function createTrigger<S extends TriggerSchema>(config: CreateTriggerConfig<S>, runtime?: Runtime): Trigger<S>Create a trigger and register it in a runtime (the default runtime if none is passed). } from '@triggery/core';
createTrigger createTrigger<{
events: {
open: {
id: string;
};
close: {
id: string;
reason: "ok" | "cancel";
};
};
}>(config: CreateTriggerConfig<{
events: {
open: {
id: string;
};
close: {
id: string;
reason: "ok" | "cancel";
};
};
}>, runtime?: Runtime): Trigger<{
events: {
open: {
id: string;
};
close: {
id: string;
reason: "ok" | "cancel";
};
};
}>
Create a trigger and register it in a runtime (the default runtime if none is passed). <{
events events: {
open: {
id: string;
};
close: {
id: string;
reason: "ok" | "cancel";
};
}
: { open open: {
id: string;
}
: { id id: string : string }; close close: {
id: string;
reason: "ok" | "cancel";
}
: { id id: string : string; reason reason: "ok" | "cancel" : 'ok' | 'cancel' } };
}>({
id id: string : 'modal',
events events: readonly ("open" | "close")[] : ['open', 'close'],
handler handler: TriggerHandler<{
events: {
open: {
id: string;
};
close: {
id: string;
reason: "ok" | "cancel";
};
};
}, never>
({ event event: EventOf<{
events: {
open: {
id: string;
};
close: {
id: string;
reason: "ok" | "cancel";
};
};
}>
}) {
if (event event: EventOf<{
events: {
open: {
id: string;
};
close: {
id: string;
reason: "ok" | "cancel";
};
};
}>
.name name: "open" | "close" === 'open') {
console var console: Console .log Console.log(...data: any[]): voidThe **`console.log()`** static method outputs a message to the console.
[MDN Reference](https://developer.mozilla.org/docs/Web/API/console/log_static) ('opening', event event: {
readonly name: "open";
readonly payload: {
id: string;
};
}
.payload payload: {
id: string;
}
.id id: string );
} else {
console var console: Console .log Console.log(...data: any[]): voidThe **`console.log()`** static method outputs a message to the console.
[MDN Reference](https://developer.mozilla.org/docs/Web/API/console/log_static) ('closing', event event: {
readonly name: "close";
readonly payload: {
id: string;
reason: "ok" | "cancel";
};
}
.payload payload: {
id: string;
reason: "ok" | "cancel";
}
.reason reason: "ok" | "cancel" );
}
},
});Abort-aware async work
Section titled “Abort-aware async work”import { createTrigger function createTrigger<S extends TriggerSchema>(config: CreateTriggerConfig<S>, runtime?: Runtime): Trigger<S>Create a trigger and register it in a runtime (the default runtime if none is passed). } from '@triggery/core';
createTrigger createTrigger<{
events: {
fetch: string;
};
actions: {
setData: unknown;
};
}>(config: CreateTriggerConfig<{
events: {
fetch: string;
};
actions: {
setData: unknown;
};
}>, runtime?: Runtime): Trigger<{
events: {
fetch: string;
};
actions: {
setData: unknown;
};
}>
Create a trigger and register it in a runtime (the default runtime if none is passed). <{
events events: {
fetch: string;
}
: { fetch fetch: string : string };
actions actions: {
setData: unknown;
}
: { setData setData: unknown : unknown };
}>({
id id: string : 'fetcher',
events events: readonly "fetch"[] : ['fetch'],
concurrency concurrency?: ConcurrencyStrategy | undefinedConcurrency strategy applied across handler runs (default: `'take-latest'`).
- `take-latest` — new run aborts the previous (`signal.aborted` becomes true).
- `take-every` — every run proceeds independently, no aborts.
- `take-first` / `exhaust` — new runs are skipped while one is still in flight.
- `queue` — new runs wait for the previous to finish (serialized).
- `sync` — like `take-every`; provided as a documentation marker. : 'take-latest',
async handler handler: TriggerHandler<{
events: {
fetch: string;
};
actions: {
setData: unknown;
};
}, never>
({ event event: {
readonly name: "fetch";
readonly payload: string;
}
, actions actions: ActionsCtx<{
setData: unknown;
}>
, signal signal: AbortSignal }) {
const res const res: Response = await fetch function fetch(input: string | URL | Request, init?: RequestInit): Promise<Response> (+1 overload)[MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/fetch) (`/api/${event event: {
readonly name: "fetch";
readonly payload: string;
}
.payload payload: string }`, { signal RequestInit.signal?: AbortSignal | null | undefinedAn AbortSignal to set request's signal. });
if (signal signal: AbortSignal .aborted AbortSignal.aborted: booleanThe **`aborted`** read-only property returns a value that indicates whether the asynchronous operations the signal is communicating with are aborted (`true`) or not (`false`).
[MDN Reference](https://developer.mozilla.org/docs/Web/API/AbortSignal/aborted) ) return;
const data const data: any = await res const res: Response .json Body.json(): Promise<any>[MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/json) ();
actions actions: ActionsCtx<{
setData: unknown;
}>
.setData setData?: ((payload: unknown) => void) | undefined ?.(data const data: any );
},
});Debounced action chain
Section titled “Debounced action chain”import { createTrigger function createTrigger<S extends TriggerSchema>(config: CreateTriggerConfig<S>, runtime?: Runtime): Trigger<S>Create a trigger and register it in a runtime (the default runtime if none is passed). } from '@triggery/core';
createTrigger createTrigger<{
events: {
keystroke: string;
};
actions: {
search: string;
};
}>(config: CreateTriggerConfig<{
events: {
keystroke: string;
};
actions: {
search: string;
};
}>, runtime?: Runtime): Trigger<{
events: {
keystroke: string;
};
actions: {
search: string;
};
}>
Create a trigger and register it in a runtime (the default runtime if none is passed). <{
events events: {
keystroke: string;
}
: { keystroke keystroke: string : string };
actions actions: {
search: string;
}
: { search search: string : string };
}>({
id id: string : 'autocomplete',
events events: readonly "keystroke"[] : ['keystroke'],
handler handler: TriggerHandler<{
events: {
keystroke: string;
};
actions: {
search: string;
};
}, never>
({ event event: {
readonly name: "keystroke";
readonly payload: string;
}
, actions actions: ActionsCtx<{
search: string;
}>
}) {
actions actions: ActionsCtx<{
search: string;
}>
.debounce function debounce(ms: number): ActionsCtx<{
search: string;
}>
(300).search search?: ((payload: string) => void) | undefined ?.(event event: {
readonly name: "keystroke";
readonly payload: string;
}
.payload payload: string );
},
});Cascade-aware logging
Section titled “Cascade-aware logging”import { createTrigger function createTrigger<S extends TriggerSchema>(config: CreateTriggerConfig<S>, runtime?: Runtime): Trigger<S>Create a trigger and register it in a runtime (the default runtime if none is passed). } from '@triggery/core';
createTrigger createTrigger<{
events: {
"order-placed": {
id: string;
};
};
}>(config: CreateTriggerConfig<{
events: {
"order-placed": {
id: string;
};
};
}>, runtime?: Runtime): Trigger<{
events: {
"order-placed": {
id: string;
};
};
}>
Create a trigger and register it in a runtime (the default runtime if none is passed). <{ events events: {
'order-placed': {
id: string;
};
}
: { 'order-placed': { id id: string : string } } }>({
id id: string : 'order',
events events: readonly "order-placed"[] : ['order-placed'],
handler handler: TriggerHandler<{
events: {
"order-placed": {
id: string;
};
};
}, never>
({ event event: {
readonly name: "order-placed";
readonly payload: {
id: string;
};
}
, meta meta: MetaCtx }) {
if (meta meta: MetaCtx .cascadeDepth cascadeDepth: number > 0) {
console var console: Console .log Console.log(...data: any[]): voidThe **`console.log()`** static method outputs a message to the console.
[MDN Reference](https://developer.mozilla.org/docs/Web/API/console/log_static) (`order ${event event: {
readonly name: "order-placed";
readonly payload: {
id: string;
};
}
.payload payload: {
id: string;
}
.id id: string } via cascade from ${meta meta: MetaCtx .parentTriggerId parentTriggerId?: string | undefined }`);
}
},
});