Fox Events Fox Events

Começando

Instale o Fox Events, crie um canal tipado e comece a emitir e escutar em poucas linhas.

Instalação

bash
npm install fox-events
bash
yarn add fox-events

Exemplo rápido

Crie um canal com um tipo de payload e use emit, on e once como precisar:

ts
import { Fox } from "fox-events";

const userLogin = Fox.channel<{ userId: string }>("user:login");

userLogin.on((payload) => {
  console.log("Login:", payload.userId);
});

userLogin.emit({ userId: "u-1" });
const first = await userLogin.once();
console.log("First login:", first.userId);

Para o modelo mental (quem publica, quem escuta, canal, on vs once, timeout), veja Publishers e listeners.

API por instância (canal)

Use Fox.channel<T>(name) quando quiser um canal duradouro com payloads tipados. Você tem emit, emitAsync, on, once e trail.

ts
const channel = Fox.channel<{ userId: string }>("user:login");

channel.emit({ userId: "u-1" });
await channel.emitAsync({ userId: "u-2" });

const off = channel.on((payload) => {
  console.log(payload.userId);
});
off();

const payload = await channel.once();
const payloadComTimeout = await channel.once({ timeout: 5000 });

const history = channel.trail();
console.log(history.published, history.received, history.unsubscribed);
channel.clearTrail();

Para opções do trail (maxHistory), tipos e toText(), veja Trail (Histórico).

Sync e async

  • emit(name, payload) — Dispara na hora e retorna void. Os listeners rodam de forma síncrona; quem chamou não espera. Use quando não precisar esperar middleware ou persistência (ex.: eventos de UI, navegação).
  • emitAsync(name, payload) — Retorna uma Promise que resolve depois que todo o middleware (e qualquer persistência) rodar. Use quando o evento passar por middleware (ex.: storage, Bridge) e você precisar esperar o processamento antes de seguir (ex.: “salvar e depois redirecionar”).
ts
// Fire-and-forget: só UI ou em memória
channel.emit("user:login", { userId: "u-1" });

// Esperar persistência / middleware (ex.: IndexedDB, Bridge para RN)
await channel.emitAsync("user:login", { userId: "u-1" });
// Agora pode navegar ou ler do storage

Sem middleware, emit e emitAsync são equivalentes para os listeners; a diferença é que emitAsync retorna uma Promise que você pode aguardar. Com middleware (ex.: storage), emitAsync espera o middleware terminar.

API estática

Quando não precisar de uma instância de canal, use Fox.emit, Fox.on e Fox.once com o nome do evento:

ts
Fox.emit("app:ready", { version: "1.0" });
await Fox.emitAsync("app:ready", { version: "1.0" });

const off = Fox.on("app:ready", (payload) => {});
off();

const payload = await Fox.once("app:ready");
const payloadComTimeout = await Fox.once("app:ready", { timeout: 3000 });

EventTarget customizado

Você pode injetar seu próprio EventTarget (por exemplo para testes ou escopos):

ts
const customTarget = new EventTarget();
const channel = Fox.channel("user:action", {
  deps: { eventTarget: customTarget },
});