replaceable-events #1
2 changed files with 38 additions and 9 deletions
45
index.ts
45
index.ts
|
@ -174,9 +174,11 @@ function addEventToDb(
|
|||
if (existingEvent) throw new EventAlreadyExistsException();
|
||||
try {
|
||||
db.run("BEGIN TRANSACTION");
|
||||
|
||||
if (isReplaceableEvent(decryptedEvent.kind)) {
|
||||
sql`
|
||||
DELETE FROM events
|
||||
UPDATE events
|
||||
SET replaced = 1
|
||||
WHERE kind = ${decryptedEvent.kind}
|
||||
AND pubkey = ${decryptedEvent.pubkey}
|
||||
AND created_at < ${decryptedEvent.created_at}
|
||||
|
@ -187,7 +189,8 @@ function addEventToDb(
|
|||
const dTag = decryptedEvent.tags.find((tag) => tag[0] === "d")?.[1];
|
||||
if (dTag) {
|
||||
sql`
|
||||
DELETE FROM events
|
||||
UPDATE events
|
||||
SET replaced = 1
|
||||
WHERE kind = ${decryptedEvent.kind}
|
||||
AND pubkey = ${decryptedEvent.pubkey}
|
||||
AND created_at < ${decryptedEvent.created_at}
|
||||
|
@ -386,7 +389,7 @@ function handleRequest(connection: UserConnection, request: NostrClientREQ) {
|
|||
}`,
|
||||
);
|
||||
|
||||
let query = sqlPartial`SELECT * FROM events`;
|
||||
let query = sqlPartial`SELECT * FROM events WHERE replaced = 0`;
|
||||
|
||||
const filtersAreNotEmpty = filters.some((filter) => {
|
||||
return Object.values(filter).some((value) => {
|
||||
|
@ -395,7 +398,7 @@ function handleRequest(connection: UserConnection, request: NostrClientREQ) {
|
|||
});
|
||||
|
||||
if (filtersAreNotEmpty) {
|
||||
query = mixQuery(query, sqlPartial`WHERE`);
|
||||
query = mixQuery(query, sqlPartial`AND`);
|
||||
|
||||
for (let i = 0; i < filters.length; i++) {
|
||||
// filters act as OR, filter groups act as AND
|
||||
|
@ -548,12 +551,36 @@ function handleRequest(connection: UserConnection, request: NostrClientREQ) {
|
|||
const rawTags = sql`SELECT * FROM event_tags_view WHERE event_id = ${
|
||||
events[i].id
|
||||
}`(connection.db);
|
||||
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 tagsByIndex = new Map<number, {
|
||||
name: string;
|
||||
values: Map<number, string>;
|
||||
}>();
|
||||
|
||||
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);
|
||||
}
|
||||
const tagsArray = Object.values(tags);
|
||||
|
||||
tagData.values.set(tag.tag_value_position, tag.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 event = {
|
||||
id: events[i].id,
|
||||
|
|
2
migrations/3-replaceableEvents.sql
Normal file
2
migrations/3-replaceableEvents.sql
Normal file
|
@ -0,0 +1,2 @@
|
|||
ALTER TABLE events
|
||||
ADD COLUMN replaced INTEGER NOT NULL DEFAULT 0;
|
Loading…
Add table
Reference in a new issue