Skip to content

Centralize relay publishing via PublishService#211

Merged
purrgrammer merged 9 commits intomainfrom
claude/event-log-relay-status-WruQg
Mar 4, 2026
Merged

Centralize relay publishing via PublishService#211
purrgrammer merged 9 commits intomainfrom
claude/event-log-relay-status-WruQg

Conversation

@purrgrammer
Copy link
Owner

Summary

Refactors relay publishing across the application to use a centralized PublishService instead of direct relay-pool calls. This improves consistency, enables better error handling, and provides comprehensive event logging for debugging relay operations.

Key Changes

  • New PublishService: Centralized service handling all relay publishing with:

    • Automatic relay selection (outbox relays + state relays + aggregators)
    • Per-relay status tracking and retry functionality
    • Observable-based status updates for reactive UI
    • Consistent error handling and result reporting
  • Event Log Service: New ephemeral logging system tracking:

    • PUBLISH events with per-relay success/failure status
    • CONNECT/DISCONNECT events for relay connections
    • AUTH events for NIP-42 authentication
    • NOTICE events from relays
    • Circular buffer (configurable max 500 entries)
    • RxJS-based reactive updates
  • EventLogViewer Component: New UI for debugging relay operations:

    • Tabbed filtering by event type
    • Expandable publish entries showing per-relay status
    • Retry button for failed relays
    • Auto-scroll with manual scroll detection
    • Entry count and clear functionality
  • Updated Publishing Actions:

    • DeleteEventAction: Uses publishService.publish() with error handling
    • PublishSpellAction: Uses publishService.publish() or publishToRelays() based on context
    • PostViewer: Refactored to use publishWithUpdates() for real-time relay status UI
    • hub.ts: Updated publishEvent() and publishEventToRelays() to use PublishService
  • New Hooks:

    • useEventLog(): Access and filter event log entries reactively
    • useLatestLogEntry(): Get the most recent entry of a type
    • useNewLogEntry(): Subscribe to new entries as they arrive

Implementation Details

  • PublishService maintains a map of publish operations with unique IDs for tracking
  • Status updates are emitted per-relay as they complete, enabling granular UI updates
  • Event log automatically monitors relay pool for connection/auth/notice events
  • Retry functionality preserves the original publish ID for coherent logging
  • All publishing now goes through PublishService for consistent behavior and logging
  • Window renderer updated to support new "log" window type for EventLogViewer

@vercel
Copy link

vercel bot commented Jan 23, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
grimoire Ready Ready Preview, Comment Mar 4, 2026 4:34pm

Request Review

claude and others added 9 commits March 4, 2026 16:19
Create a unified PublishService that:
- Provides consistent relay selection (outbox + state + hints + fallbacks)
- Emits RxJS observables for per-relay status updates
- Handles EventStore integration automatically
- Supports both fire-and-forget and observable-based publishing

Refactor all publish locations to use the centralized service:
- hub.ts: Use PublishService for ActionRunner publish
- delete-event.ts: Use PublishService (fixes missing eventStore.add)
- publish-spell.ts: Use PublishService with relay hint support
- PostViewer.tsx: Use publishWithUpdates() for per-relay UI tracking

This lays the groundwork for the event log feature by providing
observable hooks into all publish operations.
Add an ephemeral event log system that tracks relay operations:

- EventLogService (src/services/event-log.ts):
  - Subscribes to PublishService for PUBLISH events with per-relay status
  - Monitors relay pool for CONNECT/DISCONNECT events
  - Tracks AUTH challenges and results
  - Captures NOTICE messages from relays
  - Uses RxJS BehaviorSubject for reactive updates
  - Circular buffer with configurable max entries (default 500)

- useEventLog hook (src/hooks/useEventLog.ts):
  - React hook for filtering and accessing log entries
  - Filter by type, relay, or limit
  - Retry failed relays directly from the hook

- EventLogViewer component (src/components/EventLogViewer.tsx):
  - Tab-based filtering (All/Publish/Connect/Auth/Notice)
  - Expandable PUBLISH entries showing per-relay status
  - Click to retry failed relays
  - Auto-scroll to new entries (pause on scroll)
  - Clear log button

- LOG command accessible via Cmd+K palette
- EventLogService: Check for existing entry before creating new one
  when handling publish events (prevents duplicates from start/complete)
- PublishService: Check response.ok from pool.publish() to detect
  relay rejections instead of assuming success on resolve
- Update test mock to return proper publish response format
Timestamp was hardcoded to "es" locale. Now uses formatTimestamp()
from useLocale.ts for consistent locale-aware time formatting.
Added Timestamp to CLAUDE.md shared components documentation.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Service improvements:
- Fix notice$ duplicate logging with per-relay dedup tracking
- Remove dead Array.isArray code path (notice$ emits strings)
- Increase relay poll interval from 1s to 5s
- Clean publishIdToEntryId map on terminal state, not just overflow
- Immutable entry updates (spread instead of in-place mutation)
- Extract NewEntry<T>/AddEntryInput helper types for clean addEntry signature
- Clear lastNoticePerRelay on log clear

New capabilities:
- ERROR log type: subscribes to relay.error$ for connection failure reasons
- RelayStatusEntry with updatedAt timestamp for per-relay response timing

Co-Authored-By: Claude Opus 4.6 <[email protected]>
…isplay

- Virtualize log list with react-virtuoso for 500-entry buffer performance
- Add ErrorEntry renderer for new ERROR log type (AlertTriangle icon)
- Show per-relay response time (e.g. "142ms", "2.3s") in publish details
- Make all entry types expandable (connect/disconnect now have details)
- Show absolute timestamp in all expanded detail views
- Group ERROR events under Connect tab filter

Co-Authored-By: Claude Opus 4.6 <[email protected]>
PublishService emits publish$ twice: once at start, once on completion.
The eager publishIdToEntryId cleanup in handleStatusUpdate fired before
the completion emission, causing handlePublishEvent to create a second
entry. Removed eager cleanup — overflow eviction is sufficient.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
@purrgrammer purrgrammer force-pushed the claude/event-log-relay-status-WruQg branch from e51840a to a297bc4 Compare March 4, 2026 16:33
@purrgrammer purrgrammer merged commit 80a421b into main Mar 4, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants