diff --git a/snapshot/src/core/dedup.ts b/snapshot/src/core/dedup.ts new file mode 100644 index 0000000..8c19983 --- /dev/null +++ b/snapshot/src/core/dedup.ts @@ -0,0 +1,14 @@ +import type { SignedEvent } from './types.ts' + +export function dedupByDtag(events: SignedEvent[]): SignedEvent[] { + const byDtag = new Map() + for (const ev of events) { + const d = ev.tags.find((t) => t[0] === 'd')?.[1] + if (!d) continue + const existing = byDtag.get(d) + if (!existing || ev.created_at > existing.created_at) { + byDtag.set(d, ev) + } + } + return [...byDtag.values()] +} diff --git a/snapshot/src/core/types.ts b/snapshot/src/core/types.ts new file mode 100644 index 0000000..7f338c7 --- /dev/null +++ b/snapshot/src/core/types.ts @@ -0,0 +1,9 @@ +export interface SignedEvent { + id: string + pubkey: string + created_at: number + kind: number + tags: string[][] + content: string + sig: string +} diff --git a/snapshot/tests/dedup.test.ts b/snapshot/tests/dedup.test.ts new file mode 100644 index 0000000..726cc4d --- /dev/null +++ b/snapshot/tests/dedup.test.ts @@ -0,0 +1,29 @@ +import { assertEquals } from '@std/assert' +import { dedupByDtag } from '../src/core/dedup.ts' +import type { SignedEvent } from '../src/core/types.ts' + +function ev(d: string, created_at: number, id: string): SignedEvent { + return { + id, pubkey: 'p', created_at, kind: 30023, sig: 's', content: '', + tags: [['d', d]], + } +} + +Deno.test('dedupByDtag behaelt das neueste event pro d-tag', () => { + const out = dedupByDtag([ + ev('a', 100, 'a-old'), + ev('a', 200, 'a-new'), + ev('b', 50, 'b-only'), + ]) + const ids = out.map((e) => e.id).sort() + assertEquals(ids, ['a-new', 'b-only']) +}) + +Deno.test('dedupByDtag laesst events ohne d-tag weg', () => { + const out = dedupByDtag([ + { id: 'x', pubkey: 'p', created_at: 1, kind: 30023, sig: 's', content: '', tags: [] }, + ev('a', 1, 'a'), + ]) + assertEquals(out.length, 1) + assertEquals(out[0].id, 'a') +})