TriggerSchema
Stable · since 0.1.0
TriggerSchema is the single generic parameter you pass to createTrigger. It describes the complete typed surface of a trigger — every event it reacts to, every condition it can read, and every action it can call. All three keys are optional; an empty schema ({}) is valid for triggers that have no inputs and no outputs.
Import
Section titled “Import”import type { TriggerSchema } from '@triggery/core';
Definition
Section titled “Definition”type TriggerSchema = {
events?: Record<string, unknown>; // payload type per event name
conditions?: Record<string, unknown>; // value type per condition name
actions?: Record<string, unknown>; // payload type per action name
};Fields
Section titled “Fields”| Field | Type | Required | Description |
|---|---|---|---|
events | Record<string, unknown> | optional | Map of eventName → payloadType. Use void for events with no payload. |
conditions | Record<string, unknown> | optional | Map of conditionName → valueType. Values flow pull-only (runtime calls the getter at fire-time). |
actions | Record<string, unknown> | optional | Map of actionName → payloadType. Use void for parameter-less actions. |
Naming conventions
Section titled “Naming conventions”The library doesn’t enforce a casing convention — any string is a valid key. Common practice in the Triggery ecosystem:
- Events: kebab-case verbs scoped by domain —
'new-message','cta:click','session-expired'. - Conditions: camelCase nouns —
user,activeChannelId,featureFlags. - Actions: camelCase verbs —
showToast,playSound,setUser.
This pairs cleanly with the createNamedHooks helper, which converts kebab/camel keys to PascalCase hook names ('new-message' → useNewMessageEvent).
Examples
Section titled “Examples”Empty schema
Section titled “Empty schema”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<{}>(config: CreateTriggerConfig<{}>, runtime?: Runtime): Trigger<{}>Create a trigger and register it in a runtime (the default runtime if none is passed). <{}>({
id id: string : 'demo:empty',
events events: readonly string[] : [],
handler handler: TriggerHandler<{}, never> () {
// No events, conditions or actions — useful for triggers driven by side
// channels (timers, external callbacks) where the dispatch keeps a heartbeat.
},
});Events-only schema
Section titled “Events-only schema”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: {
tick: number;
tock: void;
};
}>(config: CreateTriggerConfig<{
events: {
tick: number;
tock: void;
};
}>, runtime?: Runtime): Trigger<{
events: {
tick: number;
tock: void;
};
}>
Create a trigger and register it in a runtime (the default runtime if none is passed). <{
events events: {
tick: number;
tock: void;
}
: { tick tick: number : number; tock tock: void : void };
}>({
id id: string : 'clock',
events events: readonly ("tick" | "tock")[] : ['tick', 'tock'],
handler handler: TriggerHandler<{
events: {
tick: number;
tock: void;
};
}, never>
({ event event: EventOf<{
events: {
tick: number;
tock: void;
};
}>
}) {
if (event event: EventOf<{
events: {
tick: number;
tock: void;
};
}>
.name name: "tick" | "tock" === 'tick') {
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) ('tick payload', event event: {
readonly name: "tick";
readonly payload: number;
}
.payload payload: number ); // typed number
} 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) ('tock'); // typed void
}
},
});Full schema with all three maps
Section titled “Full schema with all three maps”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';
type User type User = {
id: string;
name: string;
}
= { id id: string : string; name name: string : string };
createTrigger createTrigger<{
events: {
"new-message": {
text: string;
channelId: string;
};
};
conditions: {
user: User | null;
activeChannelId: string | null;
};
actions: {
showToast: {
title: string;
body: string;
};
playSound: "beep" | "chime";
};
}>(config: CreateTriggerConfig<{
events: {
"new-message": {
text: string;
channelId: string;
};
};
conditions: {
user: User | null;
activeChannelId: string | null;
};
actions: {
showToast: {
title: string;
body: string;
};
playSound: "beep" | "chime";
};
}>, runtime?: Runtime): Trigger<...>
Create a trigger and register it in a runtime (the default runtime if none is passed). <{
events events: {
'new-message': {
text: string;
channelId: string;
};
}
: { 'new-message': { text text: string : string; channelId channelId: string : string } };
conditions conditions: {
user: User | null;
activeChannelId: string | null;
}
: { user user: User | null : User type User = {
id: string;
name: string;
}
| null; activeChannelId activeChannelId: string | null : string | null };
actions actions: {
showToast: {
title: string;
body: string;
};
playSound: "beep" | "chime";
}
: { showToast showToast: {
title: string;
body: string;
}
: { title title: string : string; body body: string : string }; playSound playSound: "beep" | "chime" : 'beep' | 'chime' };
}>({
id id: string : 'message-received',
events events: readonly "new-message"[] : ['new-message'],
required required?: readonly ("user" | "activeChannelId")[] | undefinedRequired condition keys. The trigger will not run unless all of them are registered. : ['user'],
handler handler: TriggerHandler<{
events: {
"new-message": {
text: string;
channelId: string;
};
};
conditions: {
user: User | null;
activeChannelId: string | null;
};
actions: {
showToast: {
title: string;
body: string;
};
playSound: "beep" | "chime";
};
}, never>
({ event event: {
readonly name: "new-message";
readonly payload: {
text: string;
channelId: string;
};
}
, conditions conditions: ConditionsCtx<{
user: User | null;
activeChannelId: string | null;
}, never>
, actions actions: ActionsCtx<{
showToast: {
title: string;
body: string;
};
playSound: "beep" | "chime";
}>
, check check: CheckCtx<{
user: User | null;
activeChannelId: string | null;
}>
}) {
if (event event: {
readonly name: "new-message";
readonly payload: {
text: string;
channelId: string;
};
}
.payload payload: {
text: string;
channelId: string;
}
.channelId channelId: string === conditions conditions: ConditionsCtx<{
user: User | null;
activeChannelId: string | null;
}, never>
.activeChannelId activeChannelId?: string | null | undefined ) return;
actions actions: ActionsCtx<{
showToast: {
title: string;
body: string;
};
playSound: "beep" | "chime";
}>
.showToast showToast?: ((payload: {
title: string;
body: string;
}) => void) | undefined
?.({
title title: string : conditions conditions: ConditionsCtx<{
user: User | null;
activeChannelId: string | null;
}, never>
.user user?: User | null | undefined ?.name name: string | undefined ?? '',
body body: string : event event: {
readonly name: "new-message";
readonly payload: {
text: string;
channelId: string;
};
}
.payload payload: {
text: string;
channelId: string;
}
.text text: string ,
});
actions actions: ActionsCtx<{
showToast: {
title: string;
body: string;
};
playSound: "beep" | "chime";
}>
.playSound playSound?: ((payload: "beep" | "chime") => void) | undefined ?.('beep');
},
});Discriminated event union
Section titled “Discriminated event union”The event field in the handler context is a discriminated union over S['events']:
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" === 'close') {
// narrowed: event.payload is { id; reason } here
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) ('closed', event event: {
readonly name: "close";
readonly payload: {
id: string;
reason: "ok" | "cancel";
};
}
.payload payload: {
id: string;
reason: "ok" | "cancel";
}
.reason reason: "ok" | "cancel" );
}
},
});Related
Section titled “Related” createTrigger The constructor that consumes this schema.
TriggerCtx The handler context — built from the schema.
Trigger anatomy guide Field-by-field walkthrough.
createNamedHooks Generate PascalCase hooks from the schema.