From b20eda536fec82297f14cdd14680ca70c157a760 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 23 Jan 2026 22:39:49 +0000 Subject: [PATCH] fix: prevent duplicate log entries and check relay OK response - 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 --- src/actions/publish-spell.test.ts | 4 +++- src/services/event-log.ts | 16 ++++++++++++++++ src/services/publish-service.ts | 20 ++++++++++++++++---- 3 files changed, 35 insertions(+), 5 deletions(-) diff --git a/src/actions/publish-spell.test.ts b/src/actions/publish-spell.test.ts index 078f3ce..33fa4b3 100644 --- a/src/actions/publish-spell.test.ts +++ b/src/actions/publish-spell.test.ts @@ -17,7 +17,9 @@ vi.mock("@/services/accounts", () => ({ vi.mock("@/services/relay-pool", () => ({ default: { - publish: vi.fn(), + publish: vi + .fn() + .mockResolvedValue([{ from: "wss://test.relay/", ok: true }]), }, })); diff --git a/src/services/event-log.ts b/src/services/event-log.ts index 212c55f..360ee2a 100644 --- a/src/services/event-log.ts +++ b/src/services/event-log.ts @@ -282,6 +282,22 @@ class EventLogService { * Handle a publish event from PublishService */ private handlePublishEvent(event: PublishEvent): void { + // Check if we already have an entry for this publish (avoid duplicates) + const existingEntryId = this.publishIdToEntryId.get(event.id); + if (existingEntryId) { + // Update existing entry instead of creating a new one + const entryIndex = this.entries.findIndex( + (e) => e.id === existingEntryId && e.type === "PUBLISH", + ); + if (entryIndex !== -1) { + const entry = this.entries[entryIndex] as PublishLogEntry; + entry.relayStatus = new Map(event.results); + entry.status = this.calculatePublishStatus(event.results); + this.entriesSubject.next([...this.entries]); + } + return; + } + const entryId = this.generateId(); // Create initial publish entry diff --git a/src/services/publish-service.ts b/src/services/publish-service.ts index ca7b21b..30b7316 100644 --- a/src/services/publish-service.ts +++ b/src/services/publish-service.ts @@ -281,10 +281,22 @@ class PublishService { publishEvent.results.set(relay, { status: "publishing" }); try { - await pool.publish([relay], event); - publishEvent.results.set(relay, { status: "success" }); - this.emitStatus(publishId, relay, "success"); - return { relay, success: true as const }; + // pool.publish returns array of { from: string, ok: boolean, message?: string } + const responses = await pool.publish([relay], event); + const response = responses[0]; + + // Check if relay accepted the event + if (response && response.ok) { + publishEvent.results.set(relay, { status: "success" }); + this.emitStatus(publishId, relay, "success"); + return { relay, success: true as const }; + } else { + // Relay rejected the event + const error = response?.message || "Relay rejected event"; + publishEvent.results.set(relay, { status: "error", error }); + this.emitStatus(publishId, relay, "error", error); + return { relay, success: false as const, error }; + } } catch (err) { const error = err instanceof Error ? err.message : "Unknown error"; publishEvent.results.set(relay, { status: "error", error });