Storage
Persistência IndexedDB, hydrate, storage customizado.
IndexedDBStorage
ts
import { Fox } from "fox-events";
import { IndexedDBStorage } from "fox-events/storage";
const storage = new IndexedDBStorage();
const channel = Fox.channel<{ id: string }>("user:action", {
den: { storage },
});
// autoPersist é true por padrão quando storage é fornecido
channel.emit({ id: "a-1" });
storage.close();Persistência manual (sem autoPersist)
Se você definir autoPersist: false, os eventos não são salvos automaticamente. Você ainda pode passar storage e chamar hydrate() para carregar o estado anterior. Para persistir manualmente (ex.: ao sair da página ou quando quiser), obtenha o trail e grave no storage usando o mesmo formato de chave que a lib usa: ${keyPrefix}:${channel.name}:published, ${keyPrefix}:${channel.name}:received e ${keyPrefix}:${channel.name}:unsubscribed. Use o mesmo keyPrefix que você passou nas options (o padrão é "fox").
ts
import { Fox } from "fox-events";
import { IndexedDBStorage } from "fox-events/storage";
const storage = new IndexedDBStorage();
const keyPrefix = "myapp";
const channel = Fox.channel<{ id: string }>("user:action", {
den: { storage, keyPrefix, autoPersist: false },
});
channel.emit({ id: "a-1" });
// Depois: persistir manualmente (ex.: ao sair da página)
const t = channel.trail();
await storage.setItem(`${keyPrefix}:${channel.name}:published`, t.published);
await storage.setItem(`${keyPrefix}:${channel.name}:received`, t.received);
await storage.setItem(`${keyPrefix}:${channel.name}:unsubscribed`, t.unsubscribed);Hydrate na Inicialização
ts
const channel = Fox.channel<{ id: string }>("user:action", {
den: { storage, hydrateOnInit: true },
});
await channel.hydrate();Prefixo de Chaves
ts
const channel = Fox.channel("user:action", {
den: { storage, keyPrefix: "myapp" },
});Storage customizado
Você pode implementar IEventStorage com qualquer backend. Dois exemplos:
SessionStorage (em memória por aba):
ts
import type { IEventStorage } from "fox-events/storage";
const sessionStorageAdapter: IEventStorage = {
async get(key) {
const raw = sessionStorage.getItem(key);
return raw ? JSON.parse(raw) : null;
},
async setItem(key, value) {
sessionStorage.setItem(key, JSON.stringify(value));
},
async removeItem(key) {
sessionStorage.removeItem(key);
},
async clear() {
sessionStorage.clear();
},
};
Fox.channel("session-events", { den: { storage: sessionStorageAdapter } });HTTP (persistir via API):
ts
import type { IEventStorage } from "fox-events/storage";
const API_BASE = "https://api.example.com/events";
const httpStorage: IEventStorage = {
async get(key) {
const res = await fetch(`${API_BASE}/${encodeURIComponent(key)}`);
if (!res.ok) return null;
return res.json();
},
async setItem(key, value) {
await fetch(`${API_BASE}/${encodeURIComponent(key)}`, {
method: "PUT",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(value),
});
},
async removeItem(key) {
await fetch(`${API_BASE}/${encodeURIComponent(key)}`, { method: "DELETE" });
},
async clear() {
await fetch(API_BASE, { method: "DELETE" });
},
};
Fox.channel("remote-events", { den: { storage: httpStorage } });