diff --git a/index.ts b/index.ts index 4186bc0..7cfb67a 100644 --- a/index.ts +++ b/index.ts @@ -7,13 +7,9 @@ import type { import { getCCNPrivateKey, getCCNPubkey, - isAddressableEvent, isArray, - isCCNReplaceableEvent, isLocalhost, - isReplaceableEvent, isValidJSON, - parseATagQuery, randomTimeUpTo2DaysInThePast, } from "./utils.ts"; import * as nostrTools from "@nostr/tools"; @@ -175,58 +171,6 @@ function addEventToDb( if (existingEvent) throw new EventAlreadyExistsException(); try { db.run("BEGIN TRANSACTION"); - - if (isReplaceableEvent(decryptedEvent.kind)) { - sql` - UPDATE events - SET replaced = 1 - WHERE kind = ${decryptedEvent.kind} - AND pubkey = ${decryptedEvent.pubkey} - AND created_at < ${decryptedEvent.created_at} - `(db); - } - - if (isAddressableEvent(decryptedEvent.kind)) { - const dTag = decryptedEvent.tags.find((tag) => tag[0] === "d")?.[1]; - if (dTag) { - sql` - UPDATE events - SET replaced = 1 - WHERE kind = ${decryptedEvent.kind} - AND pubkey = ${decryptedEvent.pubkey} - AND created_at < ${decryptedEvent.created_at} - AND id IN ( - SELECT event_id FROM event_tags - WHERE tag_name = 'd' - AND tag_id IN ( - SELECT tag_id FROM event_tags_values - WHERE value_position = 1 - AND value = ${dTag} - ) - ) - `(db); - } - } - - if (isCCNReplaceableEvent(decryptedEvent.kind)) { - const dTag = decryptedEvent.tags.find((tag) => tag[0] === "d")?.[1]; - sql` - UPDATE events - SET replaced = 1 - WHERE kind = ${decryptedEvent.kind} - AND created_at < ${decryptedEvent.created_at} - AND id IN ( - SELECT event_id FROM event_tags - WHERE tag_name = 'd' - AND tag_id IN ( - SELECT tag_id FROM event_tags_values - WHERE value_position = 1 - AND value = ${dTag} - ) - ) - `(db); - } - sql` INSERT INTO events (id, original_id, pubkey, created_at, kind, content, sig, first_seen) VALUES ( ${decryptedEvent.id}, @@ -409,7 +353,7 @@ function handleRequest(connection: UserConnection, request: NostrClientREQ) { }`, ); - let query = sqlPartial`SELECT * FROM events WHERE replaced = 0`; + let query = sqlPartial`SELECT * FROM events`; const filtersAreNotEmpty = filters.some((filter) => { return Object.values(filter).some((value) => { @@ -418,7 +362,7 @@ function handleRequest(connection: UserConnection, request: NostrClientREQ) { }); if (filtersAreNotEmpty) { - query = mixQuery(query, sqlPartial`AND`); + query = mixQuery(query, sqlPartial`WHERE`); for (let i = 0; i < filters.length; i++) { // filters act as OR, filter groups act as AND @@ -487,73 +431,22 @@ function handleRequest(connection: UserConnection, request: NostrClientREQ) { const uniqueValues = [...new Set(value)]; query = mixQuery(query, sqlPartial`(`); for (let k = 0; k < uniqueValues.length; k++) { - const tagValue = uniqueValues[k] as string; - if (tag === "a") { - const aTagInfo = parseATagQuery(tagValue); - - if (aTagInfo.dTag && aTagInfo.dTag !== "") { - if (isCCNReplaceableEvent(aTagInfo.kind)) { - // CCN replaceable event reference - query = mixQuery( - query, - sqlPartial`id IN ( - SELECT e.id - FROM events e - JOIN event_tags t ON e.id = t.event_id - JOIN event_tags_values v ON t.tag_id = v.tag_id - WHERE e.kind = ${aTagInfo.kind} - AND t.tag_name = 'd' - AND v.value_position = 1 - AND v.value = ${aTagInfo.dTag} - )`, - ); - } else { - // Addressable event reference - query = mixQuery( - query, - sqlPartial`id IN ( - SELECT e.id - FROM events e - JOIN event_tags t ON e.id = t.event_id - JOIN event_tags_values v ON t.tag_id = v.tag_id - WHERE e.kind = ${aTagInfo.kind} - AND e.pubkey = ${aTagInfo.pubkey} - AND t.tag_name = 'd' - AND v.value_position = 1 - AND v.value = ${aTagInfo.dTag} - )`, - ); - } - } else { - // Replaceable event reference - query = mixQuery( - query, - sqlPartial`id IN ( - SELECT id - FROM events - WHERE kind = ${aTagInfo.kind} - AND pubkey = ${aTagInfo.pubkey} - )`, - ); - } - } else { - // Regular tag handling (unchanged) - query = mixQuery( - query, - sqlPartial`id IN ( - SELECT t.event_id - FROM event_tags t - WHERE t.tag_name = ${tag} - AND t.tag_id IN ( - SELECT v.tag_id - FROM event_tags_values v - WHERE v.value_position = 1 - AND v.value = ${tagValue} - ) - )`, - ); - } + const value = uniqueValues[k] as string; + query = mixQuery( + query, + sqlPartial`id IN ( + SELECT t.event_id + FROM event_tags t + WHERE t.tag_name = ${tag} + AND t.tag_id IN ( + SELECT v.tag_id + FROM event_tags_values v + WHERE v.value_position = 1 + AND v.value = ${value} + ) + )`, + ); if (k < uniqueValues.length - 1) { query = mixQuery(query, sqlPartial`OR`); } @@ -588,36 +481,12 @@ function handleRequest(connection: UserConnection, request: NostrClientREQ) { const rawTags = sql`SELECT * FROM event_tags_view WHERE event_id = ${ events[i].id }`(connection.db); - const tagsByIndex = new Map; - }>(); - - for (const tag of rawTags) { - let tagData = tagsByIndex.get(tag.tag_index); - if (!tagData) { - tagData = { - name: tag.tag_name, - values: new Map(), - }; - tagsByIndex.set(tag.tag_index, tagData); - } - - tagData.values.set(tag.tag_value_position, tag.tag_value); + const tags: { [key: string]: string[] } = {}; + for (const item of rawTags) { + if (!tags[item.tag_name]) tags[item.tag_name] = [item.tag_name]; + tags[item.tag_name].push(item.tag_value); } - - const tagsArray = Array.from(tagsByIndex.entries()) - .sort(([indexA], [indexB]) => indexA - indexB) - .map(([_, tagData]) => { - const { name, values } = tagData; - - return [ - name, - ...Array.from(values.entries()) - .sort(([posA], [posB]) => posA - posB) - .map(([_, value]) => value), - ]; - }); + const tagsArray = Object.values(tags); const event = { id: events[i].id, diff --git a/migrations/3-replaceableEvents.sql b/migrations/3-replaceableEvents.sql deleted file mode 100644 index 67ba8fc..0000000 --- a/migrations/3-replaceableEvents.sql +++ /dev/null @@ -1,2 +0,0 @@ -ALTER TABLE events -ADD COLUMN replaced INTEGER NOT NULL DEFAULT 0; diff --git a/utils.ts b/utils.ts index 94e930c..1ec0095 100644 --- a/utils.ts +++ b/utils.ts @@ -67,35 +67,3 @@ export async function getCCNPrivateKey(): Promise { ); return decryptUint8Array(decodeBase64(encryptedPrivateKey), encryptionKey); } - -export function isReplaceableEvent(kind: number): boolean { - return (kind >= 10000 && kind < 20000) || kind === 0 || kind === 3; -} - -export function isAddressableEvent(kind: number): boolean { - return kind >= 30000 && kind < 40000; -} - -export function isRegularEvent(kind: number): boolean { - return (kind >= 1000 && kind < 10000) || - (kind >= 4 && kind < 45) || - kind === 1 || - kind === 2; -} - -export function isCCNReplaceableEvent(kind: number): boolean { - return (kind >= 60000 && kind < 65536); -} - -export function parseATagQuery( - aTagValue: string, -): { kind: number; pubkey: string; dTag?: string } { - const parts = aTagValue.split(":"); - if (parts.length < 2) return { kind: 0, pubkey: "" }; - - return { - kind: Number.parseInt(parts[0], 10), - pubkey: parts[1], - dTag: parts.length > 2 ? parts[2] : undefined, - }; -}