createNamedHooks
Stable · since 0.1.0
Returns a proxy of hooks specialized for one trigger. Instead of writing useEvent(messageTrigger, 'new-message') everywhere, you call useNewMessageEvent() and the type system already knows which trigger and which port. Same for useUserCondition(getter, deps?) and useShowToastAction(handler).
The proxy is lazy and cached: each hook name is parsed once, the matching delegator is built once, and subsequent renders hit the cache.
Import
Section titled “Import”import { createNamedHooks } from '@triggery/react';
Signature
Section titled “Signature”function createNamedHooks<S extends TriggerSchema>(
trigger: Trigger<S>,
): NamedHooks<S>;Parameters
Section titled “Parameters”| Param | Type | Description |
|---|---|---|
trigger | Trigger<S> | The trigger to bind the hooks to. |
Returns
Section titled “Returns”A proxy object typed as NamedHooks<S> — the union of:
| Source schema field | Generated hook | Signature |
|---|---|---|
events: { 'new-message': T } | useNewMessageEvent | () => (payload: T) => void |
conditions: { user: U } | useUserCondition | (getter: () => U, deps?: readonly unknown[]) => void |
actions: { showToast: P } | useShowToastAction | (handler: (payload: P) => void | Promise<void>) => void |
Name conversion: kebab-case and camelCase keys both round-trip through PascalCase. 'new-message' → NewMessage, 'user' → User, 'showToast' → ShowToast.
Examples
Section titled “Examples”Export the hooks alongside the trigger
Section titled “Export the hooks alongside the trigger”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';
import { createNamedHooks function createNamedHooks<S extends TriggerSchema>(trigger: Trigger<S>): NamedHooks<S>Build the named-hooks proxy for a trigger.
For a schema with `events: { 'new-message' }`, `conditions: { user }` and
`actions: { showToast }` this returns:
useNewMessageEvent -> () => fire
useUserCondition -> (getter, deps?) => void
useShowToastAction -> (handler) => void
Names are derived from string keys via `kebab-case -> PascalCase`:
- `'new-message'` -> `useNewMessageEvent`
- `'user'` -> `useUserCondition`
- `'showToast'` -> `useShowToastAction`
Use it like:
export const { useNewMessageEvent, useUserCondition, useShowToastAction } =
createNamedHooks(messageTrigger);
Implementation detail: the underlying object is a `Proxy` keyed by the hook
name. Each lookup synthesizes a hook that delegates to `useEvent` /
`useCondition` / `useAction` with the right port name. } from '@triggery/react';
type Message type Message = {
author: string;
text: string;
}
= { author author: string : string; text text: string : string };
export const messageTrigger const messageTrigger: Trigger<{
events: {
"new-message": Message;
};
conditions: {
user: {
id: string;
name: string;
} | null;
};
actions: {
showToast: {
title: string;
body: string;
};
};
}>
= createTrigger createTrigger<{
events: {
"new-message": Message;
};
conditions: {
user: {
id: string;
name: string;
} | null;
};
actions: {
showToast: {
title: string;
body: string;
};
};
}>(config: CreateTriggerConfig<{
events: {
"new-message": Message;
};
conditions: {
user: {
id: string;
name: string;
} | null;
};
actions: {
showToast: {
title: string;
body: string;
};
};
}>, runtime?: Runtime): Trigger<{
events: {
"new-message": Message;
};
conditions: {
user: {
id: string;
name: string;
} | null;
};
actions: {
showToast: {
title: string;
body: string;
};
};
}>
Create a trigger and register it in a runtime (the default runtime if none is passed). <{
events events: {
'new-message': Message;
}
: { 'new-message': Message type Message = {
author: string;
text: string;
}
};
conditions conditions: {
user: {
id: string;
name: string;
} | null;
}
: { user user: {
id: string;
name: string;
} | null
: { id id: string : string; name name: string : string } | null };
actions actions: {
showToast: {
title: string;
body: string;
};
}
: { showToast showToast: {
title: string;
body: string;
}
: { title title: string : string; body body: string : string } };
}>({
id id: string : 'chat:new-message',
events events: readonly "new-message"[] : ['new-message'],
required required?: readonly "user"[] | undefinedRequired condition keys. The trigger will not run unless all of them are registered. : ['user'],
handler handler: TriggerHandler<{
events: {
"new-message": Message;
};
conditions: {
user: {
id: string;
name: string;
} | null;
};
actions: {
showToast: {
title: string;
body: string;
};
};
}, never>
({ event event: {
readonly name: "new-message";
readonly payload: Message;
}
, conditions conditions: ConditionsCtx<{
user: {
id: string;
name: string;
} | null;
}, never>
, actions actions: ActionsCtx<{
showToast: {
title: string;
body: string;
};
}>
}) {
actions actions: ActionsCtx<{
showToast: {
title: string;
body: string;
};
}>
.showToast showToast?: ((payload: {
title: string;
body: string;
}) => void) | undefined
?.({
title title: string : conditions conditions: ConditionsCtx<{
user: {
id: string;
name: string;
} | null;
}, never>
.user user?: {
id: string;
name: string;
} | null | undefined
?.name name: string | undefined ?? '',
body body: string : event event: {
readonly name: "new-message";
readonly payload: Message;
}
.payload payload: Message .text text: string ,
});
},
});
export const {
useNewMessageEvent const useNewMessageEvent: EventHook<Message> ,
useUserCondition const useUserCondition: ConditionHook<{
id: string;
name: string;
} | null>
,
useShowToastAction const useShowToastAction: ActionHook<{
title: string;
body: string;
}>
,
} = createNamedHooks createNamedHooks<{
events: {
"new-message": Message;
};
conditions: {
user: {
id: string;
name: string;
} | null;
};
actions: {
showToast: {
title: string;
body: string;
};
};
}>(trigger: Trigger<{
events: {
"new-message": Message;
};
conditions: {
user: {
id: string;
name: string;
} | null;
};
actions: {
showToast: {
title: string;
body: string;
};
};
}>): NamedHooks<{
events: {
"new-message": Message;
};
conditions: {
user: {
id: string;
name: string;
} | null;
};
actions: {
showToast: {
title: string;
body: string;
};
};
}>
Build the named-hooks proxy for a trigger.
For a schema with `events: { 'new-message' }`, `conditions: { user }` and
`actions: { showToast }` this returns:
useNewMessageEvent -> () => fire
useUserCondition -> (getter, deps?) => void
useShowToastAction -> (handler) => void
Names are derived from string keys via `kebab-case -> PascalCase`:
- `'new-message'` -> `useNewMessageEvent`
- `'user'` -> `useUserCondition`
- `'showToast'` -> `useShowToastAction`
Use it like:
export const { useNewMessageEvent, useUserCondition, useShowToastAction } =
createNamedHooks(messageTrigger);
Implementation detail: the underlying object is a `Proxy` keyed by the hook
name. Each lookup synthesizes a hook that delegates to `useEvent` /
`useCondition` / `useAction` with the right port name. (messageTrigger const messageTrigger: Trigger<{
events: {
"new-message": Message;
};
conditions: {
user: {
id: string;
name: string;
} | null;
};
actions: {
showToast: {
title: string;
body: string;
};
};
}>
);Consume them in components
Section titled “Consume them in components”import { useEffect } from 'react';
import {
useNewMessageEvent,
useUserCondition,
useShowToastAction,
} from '../triggers/message.trigger';
function Producer({ socket }: { socket: WebSocket }) {
const fire = useNewMessageEvent();
useEffect(() => {
socket.addEventListener('message', e => fire(JSON.parse(e.data)));
}, [socket, fire]);
return null;
}
function UserProvider({ user }: { user: { id: string; name: string } | null }) {
useUserCondition(() => user, [user]);
return null;
}
function Toaster() {
useShowToastAction(({ title, body }) => console.log('toast', title, body));
return null;
}Per-event subset
Section titled “Per-event subset”You don’t have to export everything:
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';
import { createNamedHooks function createNamedHooks<S extends TriggerSchema>(trigger: Trigger<S>): NamedHooks<S>Build the named-hooks proxy for a trigger.
For a schema with `events: { 'new-message' }`, `conditions: { user }` and
`actions: { showToast }` this returns:
useNewMessageEvent -> () => fire
useUserCondition -> (getter, deps?) => void
useShowToastAction -> (handler) => void
Names are derived from string keys via `kebab-case -> PascalCase`:
- `'new-message'` -> `useNewMessageEvent`
- `'user'` -> `useUserCondition`
- `'showToast'` -> `useShowToastAction`
Use it like:
export const { useNewMessageEvent, useUserCondition, useShowToastAction } =
createNamedHooks(messageTrigger);
Implementation detail: the underlying object is a `Proxy` keyed by the hook
name. Each lookup synthesizes a hook that delegates to `useEvent` /
`useCondition` / `useAction` with the right port name. } from '@triggery/react';
const trigger const trigger: Trigger<{
events: {
ping: void;
pong: void;
};
}>
= createTrigger createTrigger<{
events: {
ping: void;
pong: void;
};
}>(config: CreateTriggerConfig<{
events: {
ping: void;
pong: void;
};
}>, runtime?: Runtime): Trigger<{
events: {
ping: void;
pong: void;
};
}>
Create a trigger and register it in a runtime (the default runtime if none is passed). <{
events events: {
ping: void;
pong: void;
}
: { ping ping: void : void; pong pong: void : void };
}>({
id id: string : 'x',
events events: readonly ("ping" | "pong")[] : ['ping', 'pong'],
handler handler: TriggerHandler<{
events: {
ping: void;
pong: void;
};
}, never>
() {},
});
// Pull only the hook you use.
export const { usePingEvent const usePingEvent: EventHook<void> } = createNamedHooks createNamedHooks<{
events: {
ping: void;
pong: void;
};
}>(trigger: Trigger<{
events: {
ping: void;
pong: void;
};
}>): NamedHooks<{
events: {
ping: void;
pong: void;
};
}>
Build the named-hooks proxy for a trigger.
For a schema with `events: { 'new-message' }`, `conditions: { user }` and
`actions: { showToast }` this returns:
useNewMessageEvent -> () => fire
useUserCondition -> (getter, deps?) => void
useShowToastAction -> (handler) => void
Names are derived from string keys via `kebab-case -> PascalCase`:
- `'new-message'` -> `useNewMessageEvent`
- `'user'` -> `useUserCondition`
- `'showToast'` -> `useShowToastAction`
Use it like:
export const { useNewMessageEvent, useUserCondition, useShowToastAction } =
createNamedHooks(messageTrigger);
Implementation detail: the underlying object is a `Proxy` keyed by the hook
name. Each lookup synthesizes a hook that delegates to `useEvent` /
`useCondition` / `useAction` with the right port name. (trigger const trigger: Trigger<{
events: {
ping: void;
pong: void;
};
}>
);Related
Section titled “Related” useEvent The underlying primitive — used by every generated event hook.
useCondition The underlying primitive for condition hooks.
useAction The underlying primitive for action hooks.
prefer-named-hook lint rule Auto-suggest named hooks once threshold is reached.