diff --git a/CLAUDE.md b/CLAUDE.md index 3a668ec..c02ed43 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -114,11 +114,12 @@ const text = getHighlightText(event); **Available Helpers** (split between packages in applesauce v5): *From `applesauce-core/helpers` (protocol-level):* -- **Tags**: `getTagValue(event, name)` - get single tag value (searches hidden tags first) +- **Tags**: `getTagValue(event, name)` - get single tag value (returns first match) - **Profile**: `getProfileContent(event)`, `getDisplayName(metadata, fallback)` -- **Pointers**: `parseCoordinate(aTag)`, `getEventPointerFromETag`, `getAddressPointerFromATag`, `getProfilePointerFromPTag` +- **Pointers**: `parseReplaceableAddress(address)` (from `applesauce-core/helpers/pointers`), `getEventPointerFromETag`, `getAddressPointerFromATag`, `getProfilePointerFromPTag` - **Filters**: `isFilterEqual(a, b)`, `matchFilter(filter, event)`, `mergeFilters(...filters)` - **Relays**: `getSeenRelays`, `mergeRelaySets`, `getInboxes`, `getOutboxes` +- **Caching**: `getOrComputeCachedValue(event, symbol, compute)` - cache computed values on event objects - **URL**: `normalizeURL` *From `applesauce-common/helpers` (social/NIP-specific):* @@ -131,12 +132,16 @@ const text = getHighlightText(event); - **Lists**: `getRelaysFromList` **Custom Grimoire Helpers** (not in applesauce): -- `getTagValues(event, name)` - plural version to get array of tag values (src/lib/nostr-utils.ts) +- `getTagValues(event, name)` - get ALL values for a tag name as array (applesauce only has singular `getTagValue`) - `resolveFilterAliases(filter, pubkey, contacts)` - resolves `$me`/`$contacts` aliases (src/lib/nostr-utils.ts) - `getDisplayName(pubkey, metadata)` - enhanced version with pubkey fallback (src/lib/nostr-utils.ts) - NIP-34 git helpers (src/lib/nip34-helpers.ts) - uses `getOrComputeCachedValue` for repository, issue, patch metadata - NIP-C0 code snippet helpers (src/lib/nip-c0-helpers.ts) - wraps `getTagValue` for code metadata +**Important**: `getTagValue` vs `getTagValues`: +- `getTagValue(event, "t")` → returns first "t" tag value (string or undefined) - FROM APPLESAUCE +- `getTagValues(event, "t")` → returns ALL "t" tag values (string[]) - GRIMOIRE CUSTOM (src/lib/nostr-utils.ts) + **When to use `useMemo`**: - ✅ Complex transformations not using applesauce helpers (sorting, filtering, mapping) - ✅ Creating objects/arrays for dependency tracking (options, configurations) @@ -149,19 +154,25 @@ const text = getHighlightText(event); When creating helper functions that compute derived values from Nostr events, **always use `getOrComputeCachedValue`** from applesauce-core to cache results on the event object: ```typescript -import { getOrComputeCachedValue } from "applesauce-core/helpers"; +import { getOrComputeCachedValue, getTagValue } from "applesauce-core/helpers"; +import type { NostrEvent } from "nostr-tools"; -// Define a unique symbol for caching +// Define a unique symbol for caching at module scope const MyComputedValueSymbol = Symbol("myComputedValue"); export function getMyComputedValue(event: NostrEvent): string[] { return getOrComputeCachedValue(event, MyComputedValueSymbol, () => { // Expensive computation that iterates over tags, parses content, etc. return event.tags - .filter((t) => t[0] === "myTag") + .filter((t) => t[0] === "myTag" && t[1]) .map((t) => t[1]); }); } + +// For simple single-value extraction, just use getTagValue (no caching wrapper needed) +export function getMyTitle(event: NostrEvent): string | undefined { + return getTagValue(event, "title"); +} ``` **Why this matters**: @@ -174,8 +185,9 @@ export function getMyComputedValue(event: NostrEvent): string[] { **Best practices for helper libraries**: 1. Use `getOrComputeCachedValue` for any function that iterates tags, parses content, or does regex matching 2. Define symbols at module scope (not inside functions) for proper caching -3. Simple `getTagValue()` calls don't need additional caching (already cached by applesauce) -4. Group related helpers in NIP-specific files (e.g., `nip34-helpers.ts`, `nip88-helpers.ts`) +3. Simple `getTagValue()` calls don't need additional caching - just call directly +4. For getting ALL values of a tag, use the custom `getTagValues` from `src/lib/nostr-utils.ts` +5. Group related helpers in NIP-specific files (e.g., `nip34-helpers.ts`, `nip88-helpers.ts`) ## Major Hooks