diff --git a/publish/src/core/outbox.ts b/publish/src/core/outbox.ts new file mode 100644 index 0000000..de05222 --- /dev/null +++ b/publish/src/core/outbox.ts @@ -0,0 +1,37 @@ +import { Relay } from 'applesauce-relay' +import { firstValueFrom, timeout } from 'rxjs' +import type { SignedEvent } from './relays.ts' + +export interface Outbox { + read: string[] + write: string[] +} + +export function parseOutbox(ev: { tags: string[][] }): Outbox { + const read: string[] = [] + const write: string[] = [] + for (const t of ev.tags) { + if (t[0] !== 'r' || !t[1]) continue + const marker = t[2] + if (marker === 'read') read.push(t[1]) + else if (marker === 'write') write.push(t[1]) + else { + read.push(t[1]) + write.push(t[1]) + } + } + return { read, write } +} + +export async function loadOutbox( + bootstrapRelay: string, + authorPubkeyHex: string, +): Promise { + const relay = new Relay(bootstrapRelay) + const ev = await firstValueFrom( + relay + .request({ kinds: [10002], authors: [authorPubkeyHex], limit: 1 }) + .pipe(timeout({ first: 10_000 })), + ) as SignedEvent + return parseOutbox(ev) +} diff --git a/publish/tests/outbox_test.ts b/publish/tests/outbox_test.ts new file mode 100644 index 0000000..bc9ab9c --- /dev/null +++ b/publish/tests/outbox_test.ts @@ -0,0 +1,42 @@ +import { assertEquals } from '@std/assert' +import { parseOutbox } from '../src/core/outbox.ts' + +Deno.test('parseOutbox: r-tags ohne marker → beide', () => { + const ev = { + kind: 10002, + tags: [ + ['r', 'wss://damus'], + ['r', 'wss://nos'], + ], + } + assertEquals(parseOutbox(ev), { + read: ['wss://damus', 'wss://nos'], + write: ['wss://damus', 'wss://nos'], + }) +}) + +Deno.test('parseOutbox: marker read ignoriert schreib-nutzung', () => { + const ev = { + kind: 10002, + tags: [ + ['r', 'wss://r-only', 'read'], + ['r', 'wss://w-only', 'write'], + ['r', 'wss://both'], + ], + } + assertEquals(parseOutbox(ev), { + read: ['wss://r-only', 'wss://both'], + write: ['wss://w-only', 'wss://both'], + }) +}) + +Deno.test('parseOutbox: ignoriert andere tag-namen', () => { + const ev = { + kind: 10002, + tags: [ + ['r', 'wss://x'], + ['p', 'someone'], + ], + } + assertEquals(parseOutbox(ev), { read: ['wss://x'], write: ['wss://x'] }) +})