Fox Events Fox Events

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 } });