Как собрать ветку Nostr и не принять цитату за родительскую запись
Заметка относится к ветке A, написана в ответ на B и цитирует Z. Если превратить все ссылки в родительские связи, дерево разговора исказится.
Разберите помеченные ссылки
Для заметки вида 1 с размеченными тегами root указывает на начало ветки, а reply — на непосредственного родителя. В примере короткие имена заменяют хеши событий. Заметка окажется под B в ветке A. Цитата Z останется ссылкой в тексте.
const tags = [["e","A","","root"],["q","Z"],["e","B","","reply"]];
const eventAt = mark => tags.find(t => t[0] === "e" && t[3] === mark)?.[1];
console.log({ thread: eventAt("root"), parent: eventAt("reply") ?? eventAt("root") });
Учтите первый ответ и задержку доставки
У ответа непосредственно на корень может быть только маркер root. Тогда корень одновременно является родителем. Если B ещё не получена, сохраните её ID как недостающую связь: перенос заметки под A исказит вложенность. Для старых заметок с непомеченными тегами нужна отдельная обработка прежнего формата.