Pre-parse tags (#72)

This commit is contained in:
BlowaterNostr 2023-07-13 17:06:35 +08:00 committed by GitHub
parent 70f7dfd9c0
commit 9527e04972
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 113 additions and 62 deletions

View File

@ -33,12 +33,29 @@ export class Database_Contextual_View {
static async New(database: DexieDatabase, ctx: NostrAccountContext) {
const t = Date.now();
const cache: (PlainText_Nostr_Event | Decrypted_Nostr_Event)[] = await database.events.filter(
const cache: (NostrEvent)[] = await database.events.filter(
(e: NostrEvent) => {
return e.kind != NostrKind.CustomAppData;
},
).toArray();
const db = new Database_Contextual_View(database, cache, ctx);
const db = new Database_Contextual_View(
database,
cache.map((event) => {
const e: PlainText_Nostr_Event = {
content: event.content,
created_at: event.created_at,
id: event.id,
// @ts-ignore
kind: event.kind,
pubkey: event.pubkey,
sig: event.sig,
tags: event.tags,
parsedTags: getTags(event),
};
return e;
}),
ctx,
);
(async () => {
let tt = 0;
@ -69,7 +86,7 @@ export class Database_Contextual_View {
cache.push(e);
await db.sourceOfChange.put(e);
} else {
const e = {
const e: PlainText_Nostr_Event = {
content: event.content,
created_at: event.created_at,
id: event.id,
@ -77,6 +94,7 @@ export class Database_Contextual_View {
pubkey: event.pubkey,
sig: event.sig,
tags: event.tags,
parsedTags: getTags(event),
};
cache.push(e);
await db.sourceOfChange.put(e);
@ -91,7 +109,7 @@ export class Database_Contextual_View {
constructor(
private readonly database: DexieDatabase,
private readonly cache: (PlainText_Nostr_Event | Decrypted_Nostr_Event)[],
public readonly events: (PlainText_Nostr_Event | Decrypted_Nostr_Event)[],
private readonly ctx: NostrAccountContext,
) {}
@ -100,7 +118,7 @@ export class Database_Contextual_View {
};
public readonly filterEvents = (filter: (e: NostrEvent) => boolean) => {
return this.cache.filter(filter);
return this.events.filter(filter);
};
async addEvent(event: NostrEvent) {
@ -128,10 +146,10 @@ export class Database_Contextual_View {
this.database.events.delete(event.id);
return;
}
this.cache.push(e);
this.events.push(e);
await this.sourceOfChange.put(e);
} else {
const e = {
const e: PlainText_Nostr_Event = {
content: event.content,
created_at: event.created_at,
id: event.id,
@ -139,8 +157,9 @@ export class Database_Contextual_View {
pubkey: event.pubkey,
sig: event.sig,
tags: event.tags,
parsedTags: getTags(event),
};
this.cache.push(e);
this.events.push(e);
await this.sourceOfChange.put(e);
}
}
@ -318,6 +337,7 @@ async function transformEvent(event: Decryptable_Nostr_Event, ctx: NostrAccountC
pubkey: event.pubkey,
sig: event.sig,
tags: event.tags,
parsedTags: getTags(event),
decryptedContent: decrypted,
};
return e;

View File

@ -15,13 +15,16 @@ import {
} from "https://raw.githubusercontent.com/BlowaterNostr/nostr.ts/main/nostr.ts";
import {
computeThreads,
getTags,
groupImageEvents,
ParsedTag_Nostr_Event,
prepareNostrImageEvents,
prepareReplyEvent,
reassembleBase64ImageFromEvents,
} from "./nostr.ts";
import { LamportTime } from "./time.ts";
import { PrivateKey } from "https://raw.githubusercontent.com/BlowaterNostr/nostr.ts/main/key.ts";
import { ParseMessageContent } from "./UI/message-panel.tsx";
Deno.test("prepareNostrImageEvents", async (t) => {
const pri = PrivateKey.Generate();
@ -282,7 +285,7 @@ Deno.test("Group reply messages", async (t) => {
"text message 12, text message 5's reply",
);
const testEvent: NostrEvent[] = [
const testEvent = [
message1,
message2 as NostrEvent,
message3 as NostrEvent,
@ -295,7 +298,12 @@ Deno.test("Group reply messages", async (t) => {
message10 as NostrEvent,
message11 as NostrEvent,
message12 as NostrEvent,
];
].map((e): ParsedTag_Nostr_Event => {
return {
...e,
parsedTags: getTags(e),
};
});
const validResult = new Set<Set<NostrEvent>>([
new Set([
@ -305,7 +313,12 @@ Deno.test("Group reply messages", async (t) => {
message4 as NostrEvent,
message5 as NostrEvent,
message12 as NostrEvent,
]),
].map((e): ParsedTag_Nostr_Event => {
return {
...e,
parsedTags: getTags(e),
};
})),
new Set([
message6 as NostrEvent,
message7 as NostrEvent,
@ -313,7 +326,12 @@ Deno.test("Group reply messages", async (t) => {
message9 as NostrEvent,
message10 as NostrEvent,
message11 as NostrEvent,
]),
].map((e): ParsedTag_Nostr_Event => {
return {
...e,
parsedTags: getTags(e),
};
})),
]);
for (let i = 0; i < 10; i++) {
@ -377,17 +395,32 @@ Deno.test("Group reply messages", async (t) => {
message2,
message3,
message4,
];
].map((e): ParsedTag_Nostr_Event => {
return {
...e,
parsedTags: getTags(e),
};
});
const validResult = new Set([
new Set([
message1,
]),
].map((e): ParsedTag_Nostr_Event => {
return {
...e,
parsedTags: getTags(e),
};
})),
new Set([
message2,
message3,
message4,
]),
].map((e): ParsedTag_Nostr_Event => {
return {
...e,
parsedTags: getTags(e),
};
})),
]);
for (let i = 0; i < 10; i++) {
@ -435,16 +468,31 @@ Deno.test("Group reply messages", async (t) => {
message1,
message2,
message3,
];
].map((e): ParsedTag_Nostr_Event => {
return {
...e,
parsedTags: getTags(e),
};
});
const validResult = new Set([
new Set([
message1,
]),
].map((e): ParsedTag_Nostr_Event => {
return {
...e,
parsedTags: getTags(e),
};
})),
new Set([
message2,
message3,
]),
].map((e): ParsedTag_Nostr_Event => {
return {
...e,
parsedTags: getTags(e),
};
})),
]);
for (let i = 0; i < 10; i++) {
@ -496,7 +544,12 @@ Deno.test("Group reply messages", async (t) => {
message2,
message3,
message4,
];
].map((e): ParsedTag_Nostr_Event => {
return {
...e,
parsedTags: getTags(e),
};
});
const validResult = new Set([
new Set([
@ -504,7 +557,12 @@ Deno.test("Group reply messages", async (t) => {
message2,
message3,
message4,
]),
].map((e): ParsedTag_Nostr_Event => {
return {
...e,
parsedTags: getTags(e),
};
})),
]);
for (let i = 0; i < 10; i++) {

View File

@ -209,62 +209,34 @@ export function prepareReplyEvent(
);
}
export function compare(a: nostr.NostrEvent, b: nostr.NostrEvent) {
// const aTags = getTags(a);
// const bTags = getTags(b);
// if (aTags.image && bTags.image) {
// if (aTags.image[0] == bTags.image[0]) {
// return (Number(aTags.image[2]) - Number(bTags.image[2]));
// }
// }
// if (aTags.reply && aTags.reply[0] == b.id) {
// return 1;
// }
// if (bTags.reply && bTags.reply[0] == a.id) {
// return -1;
// }
// if (aTags.root && aTags.root[0] == b.id) {
// return 1;
// }
// if (bTags.root && bTags.root[0] == a.id) {
// return -1;
// }
// if (!aTags.reply && !aTags.root) {
// return -1;
// }
// if (!bTags.reply && !bTags.root) {
// return 1;
// }
for (const aTag of a.tags) {
if (aTag[0] == "lamport") {
for (const bTag of b.tags) {
if (bTag[0] == "lamport") {
return Number(aTag[1]) - Number(bTag[1]);
}
}
}
export function compare(a: ParsedTag_Nostr_Event, b: ParsedTag_Nostr_Event) {
if (a.parsedTags.lamport_timestamp && b.parsedTags.lamport_timestamp) {
return a.parsedTags.lamport_timestamp - b.parsedTags.lamport_timestamp;
}
return a.created_at - b.created_at;
}
export function computeThreads(events: nostr.NostrEvent[]) {
export type ParsedTag_Nostr_Event = nostr.NostrEvent & {
readonly parsedTags: Tags;
};
export function computeThreads(events: ParsedTag_Nostr_Event[]) {
events.sort(compare);
const idsMap = new Map<string, nostr.NostrEvent>();
const idsMap = new Map<string, ParsedTag_Nostr_Event>();
for (const event of events) {
if (!idsMap.has(event.id)) {
idsMap.set(event.id, event);
}
const tags = getTags(event);
const tags = event.parsedTags;
if (tags.image && tags.image[2] == "0" && !idsMap.has(tags.image[0])) {
idsMap.set(tags.image[0], event);
}
}
const relationsMap = new Map<nostr.NostrEvent, nostr.NostrEvent | string>();
const relationsMap = new Map<ParsedTag_Nostr_Event, ParsedTag_Nostr_Event | string>();
for (const event of events) {
let id = event.id;
const replyTags = getTags(event).root || getTags(event).reply || getTags(event).e;
const imageTags = getTags(event).image;
const replyTags = event.parsedTags.root || event.parsedTags.reply || event.parsedTags.e;
const imageTags = event.parsedTags.image;
if (replyTags && replyTags.length > 0) {
id = replyTags[0];
} else if (imageTags && imageTags.length > 0) {
@ -284,7 +256,7 @@ export function computeThreads(events: nostr.NostrEvent[]) {
}
}
const resMap = new Map<string, nostr.NostrEvent[]>();
const resMap = new Map<string, ParsedTag_Nostr_Event[]>();
for (const event of events) {
const relationEvent = relationsMap.get(event);
if (!relationEvent) {
@ -328,6 +300,7 @@ export type Decrypted_Nostr_Event = {
readonly kind: nostr.NostrKind.CustomAppData;
readonly created_at: number;
readonly tags: Tag[];
readonly parsedTags: Tags;
readonly content: string;
readonly decryptedContent: string;
};
@ -355,9 +328,9 @@ export type PlainText_Nostr_Event = {
| NostrKind.RECOMMED_SERVER;
readonly created_at: number;
readonly tags: Tag[];
readonly parsedTags: Tags;
readonly content: string;
};
export type CustomAppData = PinContact | UnpinContact | UserLogin;
export type PinContact = {