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
emiteonsejam 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
| Abordagem | Use quando |
|---|---|
Exportar só AppEvents | Você quer um tipo central e não se importa de usar Fox.emit<AppEvents>(...) em todo lugar. |
Exportar emit / on / once | Você quer um substituto direto do Fox já com os tipos aplicados. |
Exportar channels | Você 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.