webapp/docs/nostr-patterns
Padreug 2febf0926d docs(nostr-patterns): point monotonic created_at at the shared helper
The "strictly-monotonic created_at per coord" section named useRSVP.ts as
canonical, but that file no longer exists. monotonicCreatedAt() in
src/lib/nostr/timestamp.ts is now the single implementation — make the
doc reference it and show both the per-coord-Map and single-field
tracking shapes. Keeps doc and code aligned per the docs discipline.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 12:03:58 +00:00
..
profiles.md docs(nostr): add reusable Nostr patterns reference 2026-05-05 20:24:26 +02:00
publishing.md refactor(events): rename activities module to events + wire VITE_APP_NAME for per-deployment branding (#94) 2026-06-09 18:18:26 +00:00
reactions-and-deletions.md docs(nostr): add reusable Nostr patterns reference 2026-05-05 20:24:26 +02:00
README.md refactor(events): rename activities module to events + wire VITE_APP_NAME for per-deployment branding (#94) 2026-06-09 18:18:26 +00:00
replaceable-events.md docs(nostr-patterns): point monotonic created_at at the shared helper 2026-06-18 12:03:58 +00:00
services-and-di.md docs(nostr): add reusable Nostr patterns reference 2026-05-05 20:24:26 +02:00
subscriptions.md refactor(events): rename activities module to events + wire VITE_APP_NAME for per-deployment branding (#94) 2026-06-09 18:18:26 +00:00

Nostr patterns

Living reference for reusable Nostr patterns that show up across modules (events, forum, market, chat, tasks, base, nostr-feed).

Read before writing any new Nostr code in this repo. Update whenever you introduce, refine, or correct a pattern. Each section has a "Canonical implementation" line — that's the file the pattern was harvested from. If a caller deviates, document why or align with the canonical version.

The single biggest reason this directory exists: Nostr's edge cases (relay dedup, replaceable events, reactivity-of-nested-Map, EOSE timing) are subtle enough that re-deriving them per module produces different bugs each time. Consolidating the resolution prevents that.

Index

Patterns specific to a single NIP that doesn't repeat across modules (currently: NIP-59 gift-wrapped market orders) are not listed here yet — only the cross-cutting patterns. When a second consumer adopts an NIP-specific pattern, promote it.

Conventions

  • Canonical implementation is a single file path with line numbers. If a pattern lives in multiple modules, list one canonical and the rest as "alternates" with a short note on what differs.
  • Why sections explain the failure mode the pattern prevents — not just what it does. If the why is obvious from the code, omit it.
  • Cross-link by file when patterns compose (e.g. replaceable events almost always pair with the pending-coord debounce).
  • Don't duplicate code into the docs. Reference file:line and quote at most the 5-line core. Drift between code and docs is the failure mode.

Updating

When you implement a new pattern (or fix a subtle bug in an existing one):

  1. Add or amend the relevant topic file — leave a brief "added 2026-MM-DD, from " note if it helps trace provenance.
  2. If it's a brand-new topic, add a section to this README's index and create a new topic file.
  3. If the pattern obsoletes an alternate implementation listed here, either align that implementation or note explicitly why it diverges.

Improving

We periodically deep-dive into well-known open-source Nostr apps (Coracle, Snort, Damus, NoStrudel, Habla, Highlighter, Flotilla, Zap.cooking) to mine patterns we haven't reinvented yet. Tracked as a recurring issue on Forgejo (aiolabs/webapp). Findings land here.