Fox Events Fox Events

Centralizar eventos em foxes.ts

Boas práticas: definir todos os nomes de eventos e tipos de payload em um único arquivo (ex.: foxes.ts) e importar de lá. Assim você tem uma única fonte de verdade, tipagem e refatoração mais simples.

Por que centralizar?

  • Fonte única de verdade — Nomes de eventos em um só lugar; sem typos ou strings duplicadas no app.
  • Payloads tipados — Use um EventMap para que emit e on sejam verificados pelo TypeScript.
  • Refatoração mais fácil — Renomeie ou adicione eventos em um arquivo; o TypeScript aponta cada uso.
  • Descoberta — Quem chega no projeto vê todos os eventos do app em um arquivo.

Exemplo: foxes.ts

Crie um arquivo (ex.: src/foxes.ts ou lib/foxes.ts) que define o mapa de eventos e, se quiser, exporta canais tipados ou helpers.

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

// 1. Definir o mapa de eventos: nome do evento → tipo do payload (use void quando não houver payload)
export type AppEvents = {
  "user:login": { userId: string; email?: string };
  "user:logout": void;
  "app:ready": { version: string };
  "app:command": { action: "reload" | "back" };
};

// 2. Opcional: helpers tipados para não repetir o genérico em todo lugar
export const emit = Fox.emit<AppEvents>;
export const on = Fox.on<AppEvents>;
export const once = Fox.once<AppEvents>;
export const emitAsync = Fox.emitAsync<AppEvents>;

// 3. Opcional: canais pré-criados se você preferir a API por canal em vez da estática
export const channels = {
  userLogin: Fox.channel<AppEvents["user:login"]>("user:login"),
  userLogout: Fox.channel<AppEvents["user:logout"]>("user:logout"),
  appReady: Fox.channel<AppEvents["app:ready"]>("app:ready"),
  appCommand: Fox.channel<AppEvents["app:command"]>("app:command"),
} as const;

Usando no app

Com API estática (emit/on/once):

ts
import { emit, on, once } from "@/foxes";

// Tipado: o payload deve bater com AppEvents["user:login"]
emit("user:login", { userId: "u-1" });

on("app:ready", (payload) => {
  console.log(payload.version);
});

const payload = await once("user:login");

Com canais:

ts
import { channels } from "@/foxes";

channels.userLogin.emit({ userId: "u-1" });
channels.appReady.on((payload) => console.log(payload.version));
const payload = await channels.userLogin.once();

Se você só exportar o tipo:

ts
import { Fox } from "fox-events";
import type { AppEvents } from "@/foxes";

Fox.emit<AppEvents>("user:login", { userId: "u-1" });
Fox.on<AppEvents>("app:ready", (payload) => {});

Convenções de nome

  • Use o estilo domínio:ação para manter os nomes consistentes e fáceis de buscar (ex.: user:login, app:ready, cart:item-added).
  • Mantenha o mapa de eventos em dia: adicione novos eventos primeiro em foxes.ts, depois use no resto do app.

Resumo

AbordagemUse quando
Exportar só AppEventsVocê quer um tipo central e não se importa de usar Fox.emit<AppEvents>(...) em todo lugar.
Exportar emit / on / onceVocê quer um substituto direto do Fox já com os tipos aplicados.
Exportar channelsVocê prefere a API por canal e quer canais nomeados (ex.: channels.userLogin) em um só lugar.

Concentrar tudo em foxes.ts mantém nomes e payloads consistentes e facilita a manutenção do resto do app.