Data cache and collections
Refresh cached profiles, invalidate state and work with event collections.
This detailed API reference is maintained in English and follows the linked SDK source. Code examples with application variables need your own signer, keys, storage or UI.
SWR cache layer
import {
getProfile,
getNote,
getThread,
getFollows,
getRelayList,
fetchEngagementBatch,
configurePersistence,
createKeyedObservable,
} from "nostr-wot-sdk/data/cache";
configurePersistence({ namespace: "myapp", ttlMs: 24 * 3600_000 });
const profile = await getProfile("hex-pubkey");
// Cold-loads from localStorage if cached, refreshes in the background
// from relays as newer kind-0 events arrive.The cache exposes its own primitive — createKeyedObservable<K, V>() — used internally by every cached fetcher and by @nostr-wot/dm/cache. Useful if you're building your own SWR-style stream:
const obs = createKeyedObservable<string, MyValue>();
obs.set("key", { ... });
obs.subscribe("key", (v) => { /* re-render */ });
const slot = obs.get("key");Invalidating a keyed observable
Call store.clear() to discard its cached slots at runtime. It clears all slots before notifying subscribers for the invalidated keys with the idle, undefined state; subscriptions remain attached for subsequent updates. Empty clears are quiet. A callback can repopulate a slot during notification. Clearing does not cancel the caller's network requests: retire stale asynchronous writers before calling it. _reset() is reserved for test teardown and also removes subscribers.
Outbox model (NIP-65)
Every fetcher routes through the outbox helper by default. When you ask for an author's content, the SDK resolves their kind-10002 (NIP-65) relay list and queries the union of their declared write relays + your defaults. This is the only reliable way to find content that isn't pinned to popular aggregators.
Override globally:
setDefaultRelays(["wss://relay.damus.io", "wss://nos.lol"]);
setProfileAggregators(["wss://purplepag.es"]);Or per-call (most fetchers accept an optional relays override):
await fetchProfile(pubkey, ["wss://my-private-relay"]);Pool sharing
nostr-wot-sdk/data owns a single SimplePool instance, accessible via getPool(). If you have your own pool (e.g. for binary-frame coercion or NDK interop), wire it once at startup:
import { setPool } from "nostr-wot-sdk/data";
const pool = new SimplePool({ websocketImplementation: MyWebSocket });
setPool(pool);Other @nostr-wot/* packages reuse this same pool — DM subscriptions and WoT lookups, all share connections.
Event collections
import { dedupeEventsNewestFirst, topHashtags } from "nostr-wot-sdk/data";
const notes = dedupeEventsNewestFirst(relayResults);
const tags = topHashtags(notes, 8);dedupeEventsNewestFirst keeps the last occurrence of each event ID and sorts by descending created_at; equal timestamps retain first-ID encounter order. It accepts any event shape carrying those two fields and preserves extra fields without changing the input.
topHashtags counts a lowercase t tag once per note, ranks by frequency, and breaks ties alphabetically. Its default limit is eight. It accepts any object with a tags array. Neither helper verifies events; validate events and apply application filtering before collecting them.