Перейти к содержимому
GitHubXDiscord

createTrigger

Стабильный · с 0.1.0

Единственный конструктор в Triggery. Возвращает Trigger<Schema>, зарегистрированный в указанном рантайме (или в рантайме по умолчанию, если параметр опущен). Большинство приложений создают один триггер на сценарий — один файл на триггер.

import { createTrigger } from '@triggery/core';
function createTrigger<S extends TriggerSchema>(
  config: CreateTriggerConfig<S>,
  runtime?: Runtime,
): Trigger<S>;

Дженерик S — это схема: три опциональные карты для событий, условий и действий. В обычном использовании он никогда не выводится, всегда передавай его явно.

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
};

Для void-payload используй void (события) или undefined (действия). Имена могут быть любой валидной строкой; по соглашению — kebab-case-глаголы для событий, camelCase для условий и действий.

ПараметрТипОбязательныйПо умолчаниюОписание
idstring (литерал)даУникальный ключ в реестре рантайма. Должен быть строковым литералом — см. no-dynamic-id.
eventsreadonly EventKey<S>[]даИмена событий из S['events'], на которые реагирует триггер.
requiredreadonly ConditionKey<S>[]нет[]Условия, которые должны быть зарегистрированы, чтобы обработчик запустился.
schedule'microtask' | 'sync'нет'microtask'Когда диспатчить подходящие события.
concurrencyConcurrencyStrategyнет'take-latest'Как взаимодействуют асинхронные запуски обработчика.
scopestringнет''Ограничивает триггер поддеревом <TriggerScope id="…">.
handlerTriggerHandler<S>даФункция, вызываемая, когда событие совпало и условия required удовлетворены.

Объект Trigger<S> — стабильную идентичность, которую можно передавать в хуки React / Solid / Vue.

МетодОписание
trigger.idТа же строка, которую ты передал.
trigger.enable()Заново включить отключённый триггер.
trigger.disable()Пропускать будущие события (записывает 'disabled' в инспектор).
trigger.isEnabled()Boolean.
trigger.inspect()Последний TriggerInspectSnapshot либо undefined.
trigger.dispose()Снять регистрацию в рантайме. Редко — используется в тестах.
trigger.namedHooks()Бросает исключение при прямом вызове в @triggery/core — используй createNamedHooks из биндинга.
import { createTriggerfunction 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).
@example```ts const messageTrigger = createTrigger<{ events: { 'new-message': { author: string; text: string } }; conditions: { user: { id: string }; settings: { sound: boolean } }; actions: { showToast: { title: string }; playSound: void }; }>({ id: 'message-received', events: ['new-message'], required: ['user', 'settings'], handler({ event, conditions, actions, check }) { if (!conditions.user || !conditions.settings) return; // V1: manual narrowing if (check.is('settings', (s) => s.sound)) actions.playSound?.(); actions.showToast?.({ title: event.payload.author }); }, }); ```
} from '@triggery/core';
const ping
const ping: Trigger<{
    events: {
        tick: number;
    };
}>
= createTrigger
createTrigger<{
    events: {
        tick: number;
    };
}>(config: CreateTriggerConfig<{
    events: {
        tick: number;
    };
}>, runtime?: Runtime): Trigger<{
    events: {
        tick: number;
    };
}>
Create a trigger and register it in a runtime (the default runtime if none is passed).
@example```ts const messageTrigger = createTrigger<{ events: { 'new-message': { author: string; text: string } }; conditions: { user: { id: string }; settings: { sound: boolean } }; actions: { showToast: { title: string }; playSound: void }; }>({ id: 'message-received', events: ['new-message'], required: ['user', 'settings'], handler({ event, conditions, actions, check }) { if (!conditions.user || !conditions.settings) return; // V1: manual narrowing if (check.is('settings', (s) => s.sound)) actions.playSound?.(); actions.showToast?.({ title: event.payload.author }); }, }); ```
<{
events
events: {
    tick: number;
}
: { ticktick: number: number };
}>({ idid: string: 'demo:ping', eventsevents: readonly "tick"[]: ['tick'], handler
handler: TriggerHandler<{
    events: {
        tick: number;
    };
}, never>
({ event
event: {
    readonly name: "tick";
    readonly payload: number;
}
}) {
consolevar console: Console.logConsole.log(...data: any[]): void
The **`console.log()`** static method outputs a message to the console. [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/log_static)
('tick', event
event: {
    readonly name: "tick";
    readonly payload: number;
}
.payloadpayload: number);
}, });
import { createTriggerfunction 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).
@example```ts const messageTrigger = createTrigger<{ events: { 'new-message': { author: string; text: string } }; conditions: { user: { id: string }; settings: { sound: boolean } }; actions: { showToast: { title: string }; playSound: void }; }>({ id: 'message-received', events: ['new-message'], required: ['user', 'settings'], handler({ event, conditions, actions, check }) { if (!conditions.user || !conditions.settings) return; // V1: manual narrowing if (check.is('settings', (s) => s.sound)) actions.playSound?.(); actions.showToast?.({ title: event.payload.author }); }, }); ```
} from '@triggery/core';
type Settings
type Settings = {
    sound: boolean;
    notifications: boolean;
}
= { soundsound: boolean: boolean; notificationsnotifications: boolean: boolean };
type Message
type Message = {
    author: string;
    text: string;
    channelId: string;
}
= { authorauthor: string: string; texttext: string: string; channelIdchannelId: string: string };
const messageTrigger
const messageTrigger: Trigger<{
    events: {
        "new-message": Message;
    };
    conditions: {
        settings: Settings;
        activeChannelId: string | null;
    };
    actions: {
        showToast: {
            title: string;
            body: string;
        };
        playSound: "beep";
    };
}>
= createTrigger
createTrigger<{
    events: {
        "new-message": Message;
    };
    conditions: {
        settings: Settings;
        activeChannelId: string | null;
    };
    actions: {
        showToast: {
            title: string;
            body: string;
        };
        playSound: "beep";
    };
}>(config: CreateTriggerConfig<{
    events: {
        "new-message": Message;
    };
    conditions: {
        settings: Settings;
        activeChannelId: string | null;
    };
    actions: {
        showToast: {
            title: string;
            body: string;
        };
        playSound: "beep";
    };
}>, runtime?: Runtime): Trigger<{
    events: {
        "new-message": Message;
    };
    conditions: {
        settings: Settings;
        activeChannelId: string | null;
    };
    actions: {
        showToast: {
            title: string;
            body: string;
        };
        playSound: "beep";
    };
}>
Create a trigger and register it in a runtime (the default runtime if none is passed).
@example```ts const messageTrigger = createTrigger<{ events: { 'new-message': { author: string; text: string } }; conditions: { user: { id: string }; settings: { sound: boolean } }; actions: { showToast: { title: string }; playSound: void }; }>({ id: 'message-received', events: ['new-message'], required: ['user', 'settings'], handler({ event, conditions, actions, check }) { if (!conditions.user || !conditions.settings) return; // V1: manual narrowing if (check.is('settings', (s) => s.sound)) actions.playSound?.(); actions.showToast?.({ title: event.payload.author }); }, }); ```
<{
events
events: {
    'new-message': Message;
}
: { 'new-message': Message
type Message = {
    author: string;
    text: string;
    channelId: string;
}
};
conditions
conditions: {
    settings: Settings;
    activeChannelId: string | null;
}
: { settingssettings: Settings: Settings
type Settings = {
    sound: boolean;
    notifications: boolean;
}
; activeChannelIdactiveChannelId: string | null: string | null };
actions
actions: {
    showToast: {
        title: string;
        body: string;
    };
    playSound: "beep";
}
: { showToast
showToast: {
    title: string;
    body: string;
}
: { titletitle: string: string; bodybody: string: string }; playSoundplaySound: "beep": 'beep' };
}>({ idid: string: 'message-received', eventsevents: readonly "new-message"[]: ['new-message'], requiredrequired?: readonly ("settings" | "activeChannelId")[] | undefined
Required condition keys. The trigger will not run unless all of them are registered.
: ['settings'],
handler
handler: TriggerHandler<{
    events: {
        "new-message": Message;
    };
    conditions: {
        settings: Settings;
        activeChannelId: string | null;
    };
    actions: {
        showToast: {
            title: string;
            body: string;
        };
        playSound: "beep";
    };
}, never>
({ event
event: {
    readonly name: "new-message";
    readonly payload: Message;
}
, conditions
conditions: ConditionsCtx<{
    settings: Settings;
    activeChannelId: string | null;
}, never>
, actions
actions: ActionsCtx<{
    showToast: {
        title: string;
        body: string;
    };
    playSound: "beep";
}>
, check
check: CheckCtx<{
    settings: Settings;
    activeChannelId: string | null;
}>
}) {
if (event
event: {
    readonly name: "new-message";
    readonly payload: Message;
}
.payloadpayload: Message.channelIdchannelId: string === conditions
conditions: ConditionsCtx<{
    settings: Settings;
    activeChannelId: string | null;
}, never>
.activeChannelIdactiveChannelId?: string | null | undefined) return;
if (!check
check: CheckCtx<{
    settings: Settings;
    activeChannelId: string | null;
}>
.isis<"settings">(key: "settings", predicate: (value: Settings) => boolean): boolean('settings', ss: Settings => ss: Settings.notificationsnotifications: boolean)) return;
actions
actions: ActionsCtx<{
    showToast: {
        title: string;
        body: string;
    };
    playSound: "beep";
}>
.debounce
function debounce(ms: number): ActionsCtx<{
    showToast: {
        title: string;
        body: string;
    };
    playSound: "beep";
}>
(800).playSoundplaySound?: ((payload: "beep") => void) | undefined?.('beep');
actions
actions: ActionsCtx<{
    showToast: {
        title: string;
        body: string;
    };
    playSound: "beep";
}>
.showToast
showToast?: ((payload: {
    title: string;
    body: string;
}) => void) | undefined
?.({
titletitle: string: event
event: {
    readonly name: "new-message";
    readonly payload: Message;
}
.payloadpayload: Message.authorauthor: string,
bodybody: string: event
event: {
    readonly name: "new-message";
    readonly payload: Message;
}
.payloadpayload: Message.texttext: string,
}); }, });
import { createTriggerfunction 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).
@example```ts const messageTrigger = createTrigger<{ events: { 'new-message': { author: string; text: string } }; conditions: { user: { id: string }; settings: { sound: boolean } }; actions: { showToast: { title: string }; playSound: void }; }>({ id: 'message-received', events: ['new-message'], required: ['user', 'settings'], handler({ event, conditions, actions, check }) { if (!conditions.user || !conditions.settings) return; // V1: manual narrowing if (check.is('settings', (s) => s.sound)) actions.playSound?.(); actions.showToast?.({ title: event.payload.author }); }, }); ```
} from '@triggery/core';
const fetchTrigger
const fetchTrigger: Trigger<{
    events: {
        "fetch-user": string;
    };
    actions: {
        setUser: {
            id: string;
            name: string;
        };
    };
}>
= createTrigger
createTrigger<{
    events: {
        "fetch-user": string;
    };
    actions: {
        setUser: {
            id: string;
            name: string;
        };
    };
}>(config: CreateTriggerConfig<{
    events: {
        "fetch-user": string;
    };
    actions: {
        setUser: {
            id: string;
            name: string;
        };
    };
}>, runtime?: Runtime): Trigger<{
    events: {
        "fetch-user": string;
    };
    actions: {
        setUser: {
            id: string;
            name: string;
        };
    };
}>
Create a trigger and register it in a runtime (the default runtime if none is passed).
@example```ts const messageTrigger = createTrigger<{ events: { 'new-message': { author: string; text: string } }; conditions: { user: { id: string }; settings: { sound: boolean } }; actions: { showToast: { title: string }; playSound: void }; }>({ id: 'message-received', events: ['new-message'], required: ['user', 'settings'], handler({ event, conditions, actions, check }) { if (!conditions.user || !conditions.settings) return; // V1: manual narrowing if (check.is('settings', (s) => s.sound)) actions.playSound?.(); actions.showToast?.({ title: event.payload.author }); }, }); ```
<{
events
events: {
    'fetch-user': string;
}
: { 'fetch-user': string };
actions
actions: {
    setUser: {
        id: string;
        name: string;
    };
}
: { setUser
setUser: {
    id: string;
    name: string;
}
: { idid: string: string; namename: string: string } };
}>({ idid: string: 'fetch-user', eventsevents: readonly "fetch-user"[]: ['fetch-user'], concurrencyconcurrency?: ConcurrencyStrategy | undefined
Concurrency 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-user": string;
    };
    actions: {
        setUser: {
            id: string;
            name: string;
        };
    };
}, never>
({ event
event: {
    readonly name: "fetch-user";
    readonly payload: string;
}
, actions
actions: ActionsCtx<{
    setUser: {
        id: string;
        name: string;
    };
}>
, signalsignal: AbortSignal }) {
const resconst res: Response = await fetchfunction fetch(input: string | URL | Request, init?: RequestInit): Promise<Response> (+1 overload)
[MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/fetch)
(`/api/users/${event
event: {
    readonly name: "fetch-user";
    readonly payload: string;
}
.payloadpayload: string}`, { signalRequestInit.signal?: AbortSignal | null | undefined
An AbortSignal to set request's signal.
});
if (signalsignal: AbortSignal.abortedAbortSignal.aborted: boolean
The **`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;
actions
actions: ActionsCtx<{
    setUser: {
        id: string;
        name: string;
    };
}>
.setUser
setUser?: ((payload: {
    id: string;
    name: string;
}) => void) | undefined
?.(await resconst res: Response.jsonBody.json(): Promise<any>
[MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/json)
());
}, });
import { createRuntimefunction createRuntime(options?: RuntimeOptions): Runtime, createTriggerfunction 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).
@example```ts const messageTrigger = createTrigger<{ events: { 'new-message': { author: string; text: string } }; conditions: { user: { id: string }; settings: { sound: boolean } }; actions: { showToast: { title: string }; playSound: void }; }>({ id: 'message-received', events: ['new-message'], required: ['user', 'settings'], handler({ event, conditions, actions, check }) { if (!conditions.user || !conditions.settings) return; // V1: manual narrowing if (check.is('settings', (s) => s.sound)) actions.playSound?.(); actions.showToast?.({ title: event.payload.author }); }, }); ```
} from '@triggery/core';
const runtimeconst runtime: Runtime = createRuntimefunction createRuntime(options?: RuntimeOptions): Runtime({ inspectorinspector?: InspectorOption | undefined
Enable / disable the per-run inspector. See {@link InspectorOption } .
: { devdev?: boolean | undefined: true, prodprod?: boolean | undefined: false } });
const trigger
const trigger: Trigger<{
    events: {
        hi: void;
    };
}>
= createTrigger
createTrigger<{
    events: {
        hi: void;
    };
}>(config: CreateTriggerConfig<{
    events: {
        hi: void;
    };
}>, runtime?: Runtime): Trigger<{
    events: {
        hi: void;
    };
}>
Create a trigger and register it in a runtime (the default runtime if none is passed).
@example```ts const messageTrigger = createTrigger<{ events: { 'new-message': { author: string; text: string } }; conditions: { user: { id: string }; settings: { sound: boolean } }; actions: { showToast: { title: string }; playSound: void }; }>({ id: 'message-received', events: ['new-message'], required: ['user', 'settings'], handler({ event, conditions, actions, check }) { if (!conditions.user || !conditions.settings) return; // V1: manual narrowing if (check.is('settings', (s) => s.sound)) actions.playSound?.(); actions.showToast?.({ title: event.payload.author }); }, }); ```
<{ events
events: {
    hi: void;
}
: { hihi: void: void } }>(
{ idid: string: 'demo:hi', eventsevents: readonly "hi"[]: ['hi'], handler
handler: TriggerHandler<{
    events: {
        hi: void;
    };
}, never>
() {
consolevar console: Console.logConsole.log(...data: any[]): void
The **`console.log()`** static method outputs a message to the console. [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/log_static)
('hi');
}, }, runtimeconst runtime: Runtime, );