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

@triggery/signals

Читай значение сигнала из условия Triggery, не задействуя signal-tracking на хост-компоненте. Совместимо с @preact/signals-core, alien-signals и любым структурно похожим сигналом, у которого есть peek() или .value.

npm bundle

pnpm add @triggery/core @triggery/react @triggery/signals @preact/signals-core

Peer-зависимости: react >= 18.0.0. Библиотека сигналов — на твой выбор: подходят и @preact/signals-core, и alien-signals.

ЭкспортНазначение
useSignalCondition(trigger, name, signal, selector?)Регистрирует условие на основе сигнала. Сначала пробует peek(), при отсутствии — .value.
import { signal } from '@preact/signals-core';
import { createTrigger } from '@triggery/core';
import { useSignalCondition } from '@triggery/signals';

const settings = signal({ sound: true, notifications: true });

const messageTrigger = createTrigger<{
  events: { 'new-message': { text: string } };
  conditions: { settings: { sound: boolean; notifications: boolean } };
  actions: { showToast: { body: string } };
}>({
  id: 'message-received',
  events: ['new-message'],
  required: ['settings'],
  handler({ event, conditions, actions }) {
    if (!conditions.settings.notifications) return;
    actions.showToast?.({ body: event.payload.text });
  },
});

function SettingsBridge() {
  useSignalCondition(messageTrigger, 'settings', settings);
  return null;
}

С селектором-проекцией:

useSignalCondition(messageTrigger, 'settings', profile, (p) => p.settings);

Pull-only: сигнал читается только при срабатывании триггера. Адаптер сначала пробует peek() (без dependency tracking) и откатывается к .value, если peek отсутствует. В обоих случаях подписчик на сигнал не регистрируется, поэтому хост-компонент никогда не ререндерится на обновлениях сигнала.

Если компоненту нужно ещё и рендерить сигнал — используй useSignal() из @preact/signals-react или аналог из своей библиотеки сигналов; оба пути ортогональны.

useSignalCondition<V, S, K>(
  trigger: Trigger<S>,
  name: K,
  signal: { peek?(): V; readonly value?: V },
  selector?: (value: V) => ConditionMap<S>[K],
): void