mirror of
https://github.com/BlowaterNostr/blowater.git
synced 2024-10-18 15:43:20 +00:00
Pre-parse tags (#72)
This commit is contained in:
parent
70f7dfd9c0
commit
9527e04972
36
database.ts
36
database.ts
@ -33,12 +33,29 @@ export class Database_Contextual_View {
|
|||||||
|
|
||||||
static async New(database: DexieDatabase, ctx: NostrAccountContext) {
|
static async New(database: DexieDatabase, ctx: NostrAccountContext) {
|
||||||
const t = Date.now();
|
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) => {
|
(e: NostrEvent) => {
|
||||||
return e.kind != NostrKind.CustomAppData;
|
return e.kind != NostrKind.CustomAppData;
|
||||||
},
|
},
|
||||||
).toArray();
|
).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 () => {
|
(async () => {
|
||||||
let tt = 0;
|
let tt = 0;
|
||||||
@ -69,7 +86,7 @@ export class Database_Contextual_View {
|
|||||||
cache.push(e);
|
cache.push(e);
|
||||||
await db.sourceOfChange.put(e);
|
await db.sourceOfChange.put(e);
|
||||||
} else {
|
} else {
|
||||||
const e = {
|
const e: PlainText_Nostr_Event = {
|
||||||
content: event.content,
|
content: event.content,
|
||||||
created_at: event.created_at,
|
created_at: event.created_at,
|
||||||
id: event.id,
|
id: event.id,
|
||||||
@ -77,6 +94,7 @@ export class Database_Contextual_View {
|
|||||||
pubkey: event.pubkey,
|
pubkey: event.pubkey,
|
||||||
sig: event.sig,
|
sig: event.sig,
|
||||||
tags: event.tags,
|
tags: event.tags,
|
||||||
|
parsedTags: getTags(event),
|
||||||
};
|
};
|
||||||
cache.push(e);
|
cache.push(e);
|
||||||
await db.sourceOfChange.put(e);
|
await db.sourceOfChange.put(e);
|
||||||
@ -91,7 +109,7 @@ export class Database_Contextual_View {
|
|||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private readonly database: DexieDatabase,
|
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,
|
private readonly ctx: NostrAccountContext,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
@ -100,7 +118,7 @@ export class Database_Contextual_View {
|
|||||||
};
|
};
|
||||||
|
|
||||||
public readonly filterEvents = (filter: (e: NostrEvent) => boolean) => {
|
public readonly filterEvents = (filter: (e: NostrEvent) => boolean) => {
|
||||||
return this.cache.filter(filter);
|
return this.events.filter(filter);
|
||||||
};
|
};
|
||||||
|
|
||||||
async addEvent(event: NostrEvent) {
|
async addEvent(event: NostrEvent) {
|
||||||
@ -128,10 +146,10 @@ export class Database_Contextual_View {
|
|||||||
this.database.events.delete(event.id);
|
this.database.events.delete(event.id);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.cache.push(e);
|
this.events.push(e);
|
||||||
await this.sourceOfChange.put(e);
|
await this.sourceOfChange.put(e);
|
||||||
} else {
|
} else {
|
||||||
const e = {
|
const e: PlainText_Nostr_Event = {
|
||||||
content: event.content,
|
content: event.content,
|
||||||
created_at: event.created_at,
|
created_at: event.created_at,
|
||||||
id: event.id,
|
id: event.id,
|
||||||
@ -139,8 +157,9 @@ export class Database_Contextual_View {
|
|||||||
pubkey: event.pubkey,
|
pubkey: event.pubkey,
|
||||||
sig: event.sig,
|
sig: event.sig,
|
||||||
tags: event.tags,
|
tags: event.tags,
|
||||||
|
parsedTags: getTags(event),
|
||||||
};
|
};
|
||||||
this.cache.push(e);
|
this.events.push(e);
|
||||||
await this.sourceOfChange.put(e);
|
await this.sourceOfChange.put(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -318,6 +337,7 @@ async function transformEvent(event: Decryptable_Nostr_Event, ctx: NostrAccountC
|
|||||||
pubkey: event.pubkey,
|
pubkey: event.pubkey,
|
||||||
sig: event.sig,
|
sig: event.sig,
|
||||||
tags: event.tags,
|
tags: event.tags,
|
||||||
|
parsedTags: getTags(event),
|
||||||
decryptedContent: decrypted,
|
decryptedContent: decrypted,
|
||||||
};
|
};
|
||||||
return e;
|
return e;
|
||||||
|
@ -15,13 +15,16 @@ import {
|
|||||||
} from "https://raw.githubusercontent.com/BlowaterNostr/nostr.ts/main/nostr.ts";
|
} from "https://raw.githubusercontent.com/BlowaterNostr/nostr.ts/main/nostr.ts";
|
||||||
import {
|
import {
|
||||||
computeThreads,
|
computeThreads,
|
||||||
|
getTags,
|
||||||
groupImageEvents,
|
groupImageEvents,
|
||||||
|
ParsedTag_Nostr_Event,
|
||||||
prepareNostrImageEvents,
|
prepareNostrImageEvents,
|
||||||
prepareReplyEvent,
|
prepareReplyEvent,
|
||||||
reassembleBase64ImageFromEvents,
|
reassembleBase64ImageFromEvents,
|
||||||
} from "./nostr.ts";
|
} from "./nostr.ts";
|
||||||
import { LamportTime } from "./time.ts";
|
import { LamportTime } from "./time.ts";
|
||||||
import { PrivateKey } from "https://raw.githubusercontent.com/BlowaterNostr/nostr.ts/main/key.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) => {
|
Deno.test("prepareNostrImageEvents", async (t) => {
|
||||||
const pri = PrivateKey.Generate();
|
const pri = PrivateKey.Generate();
|
||||||
@ -282,7 +285,7 @@ Deno.test("Group reply messages", async (t) => {
|
|||||||
"text message 12, text message 5's reply",
|
"text message 12, text message 5's reply",
|
||||||
);
|
);
|
||||||
|
|
||||||
const testEvent: NostrEvent[] = [
|
const testEvent = [
|
||||||
message1,
|
message1,
|
||||||
message2 as NostrEvent,
|
message2 as NostrEvent,
|
||||||
message3 as NostrEvent,
|
message3 as NostrEvent,
|
||||||
@ -295,7 +298,12 @@ Deno.test("Group reply messages", async (t) => {
|
|||||||
message10 as NostrEvent,
|
message10 as NostrEvent,
|
||||||
message11 as NostrEvent,
|
message11 as NostrEvent,
|
||||||
message12 as NostrEvent,
|
message12 as NostrEvent,
|
||||||
];
|
].map((e): ParsedTag_Nostr_Event => {
|
||||||
|
return {
|
||||||
|
...e,
|
||||||
|
parsedTags: getTags(e),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
const validResult = new Set<Set<NostrEvent>>([
|
const validResult = new Set<Set<NostrEvent>>([
|
||||||
new Set([
|
new Set([
|
||||||
@ -305,7 +313,12 @@ Deno.test("Group reply messages", async (t) => {
|
|||||||
message4 as NostrEvent,
|
message4 as NostrEvent,
|
||||||
message5 as NostrEvent,
|
message5 as NostrEvent,
|
||||||
message12 as NostrEvent,
|
message12 as NostrEvent,
|
||||||
]),
|
].map((e): ParsedTag_Nostr_Event => {
|
||||||
|
return {
|
||||||
|
...e,
|
||||||
|
parsedTags: getTags(e),
|
||||||
|
};
|
||||||
|
})),
|
||||||
new Set([
|
new Set([
|
||||||
message6 as NostrEvent,
|
message6 as NostrEvent,
|
||||||
message7 as NostrEvent,
|
message7 as NostrEvent,
|
||||||
@ -313,7 +326,12 @@ Deno.test("Group reply messages", async (t) => {
|
|||||||
message9 as NostrEvent,
|
message9 as NostrEvent,
|
||||||
message10 as NostrEvent,
|
message10 as NostrEvent,
|
||||||
message11 as NostrEvent,
|
message11 as NostrEvent,
|
||||||
]),
|
].map((e): ParsedTag_Nostr_Event => {
|
||||||
|
return {
|
||||||
|
...e,
|
||||||
|
parsedTags: getTags(e),
|
||||||
|
};
|
||||||
|
})),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
for (let i = 0; i < 10; i++) {
|
for (let i = 0; i < 10; i++) {
|
||||||
@ -377,17 +395,32 @@ Deno.test("Group reply messages", async (t) => {
|
|||||||
message2,
|
message2,
|
||||||
message3,
|
message3,
|
||||||
message4,
|
message4,
|
||||||
];
|
].map((e): ParsedTag_Nostr_Event => {
|
||||||
|
return {
|
||||||
|
...e,
|
||||||
|
parsedTags: getTags(e),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
const validResult = new Set([
|
const validResult = new Set([
|
||||||
new Set([
|
new Set([
|
||||||
message1,
|
message1,
|
||||||
]),
|
].map((e): ParsedTag_Nostr_Event => {
|
||||||
|
return {
|
||||||
|
...e,
|
||||||
|
parsedTags: getTags(e),
|
||||||
|
};
|
||||||
|
})),
|
||||||
new Set([
|
new Set([
|
||||||
message2,
|
message2,
|
||||||
message3,
|
message3,
|
||||||
message4,
|
message4,
|
||||||
]),
|
].map((e): ParsedTag_Nostr_Event => {
|
||||||
|
return {
|
||||||
|
...e,
|
||||||
|
parsedTags: getTags(e),
|
||||||
|
};
|
||||||
|
})),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
for (let i = 0; i < 10; i++) {
|
for (let i = 0; i < 10; i++) {
|
||||||
@ -435,16 +468,31 @@ Deno.test("Group reply messages", async (t) => {
|
|||||||
message1,
|
message1,
|
||||||
message2,
|
message2,
|
||||||
message3,
|
message3,
|
||||||
];
|
].map((e): ParsedTag_Nostr_Event => {
|
||||||
|
return {
|
||||||
|
...e,
|
||||||
|
parsedTags: getTags(e),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
const validResult = new Set([
|
const validResult = new Set([
|
||||||
new Set([
|
new Set([
|
||||||
message1,
|
message1,
|
||||||
]),
|
].map((e): ParsedTag_Nostr_Event => {
|
||||||
|
return {
|
||||||
|
...e,
|
||||||
|
parsedTags: getTags(e),
|
||||||
|
};
|
||||||
|
})),
|
||||||
new Set([
|
new Set([
|
||||||
message2,
|
message2,
|
||||||
message3,
|
message3,
|
||||||
]),
|
].map((e): ParsedTag_Nostr_Event => {
|
||||||
|
return {
|
||||||
|
...e,
|
||||||
|
parsedTags: getTags(e),
|
||||||
|
};
|
||||||
|
})),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
for (let i = 0; i < 10; i++) {
|
for (let i = 0; i < 10; i++) {
|
||||||
@ -496,7 +544,12 @@ Deno.test("Group reply messages", async (t) => {
|
|||||||
message2,
|
message2,
|
||||||
message3,
|
message3,
|
||||||
message4,
|
message4,
|
||||||
];
|
].map((e): ParsedTag_Nostr_Event => {
|
||||||
|
return {
|
||||||
|
...e,
|
||||||
|
parsedTags: getTags(e),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
const validResult = new Set([
|
const validResult = new Set([
|
||||||
new Set([
|
new Set([
|
||||||
@ -504,7 +557,12 @@ Deno.test("Group reply messages", async (t) => {
|
|||||||
message2,
|
message2,
|
||||||
message3,
|
message3,
|
||||||
message4,
|
message4,
|
||||||
]),
|
].map((e): ParsedTag_Nostr_Event => {
|
||||||
|
return {
|
||||||
|
...e,
|
||||||
|
parsedTags: getTags(e),
|
||||||
|
};
|
||||||
|
})),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
for (let i = 0; i < 10; i++) {
|
for (let i = 0; i < 10; i++) {
|
||||||
|
57
nostr.ts
57
nostr.ts
@ -209,62 +209,34 @@ export function prepareReplyEvent(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function compare(a: nostr.NostrEvent, b: nostr.NostrEvent) {
|
export function compare(a: ParsedTag_Nostr_Event, b: ParsedTag_Nostr_Event) {
|
||||||
// const aTags = getTags(a);
|
if (a.parsedTags.lamport_timestamp && b.parsedTags.lamport_timestamp) {
|
||||||
// const bTags = getTags(b);
|
return a.parsedTags.lamport_timestamp - b.parsedTags.lamport_timestamp;
|
||||||
// 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]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return a.created_at - b.created_at;
|
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);
|
events.sort(compare);
|
||||||
const idsMap = new Map<string, nostr.NostrEvent>();
|
const idsMap = new Map<string, ParsedTag_Nostr_Event>();
|
||||||
for (const event of events) {
|
for (const event of events) {
|
||||||
if (!idsMap.has(event.id)) {
|
if (!idsMap.has(event.id)) {
|
||||||
idsMap.set(event.id, event);
|
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])) {
|
if (tags.image && tags.image[2] == "0" && !idsMap.has(tags.image[0])) {
|
||||||
idsMap.set(tags.image[0], event);
|
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) {
|
for (const event of events) {
|
||||||
let id = event.id;
|
let id = event.id;
|
||||||
const replyTags = getTags(event).root || getTags(event).reply || getTags(event).e;
|
const replyTags = event.parsedTags.root || event.parsedTags.reply || event.parsedTags.e;
|
||||||
const imageTags = getTags(event).image;
|
const imageTags = event.parsedTags.image;
|
||||||
if (replyTags && replyTags.length > 0) {
|
if (replyTags && replyTags.length > 0) {
|
||||||
id = replyTags[0];
|
id = replyTags[0];
|
||||||
} else if (imageTags && imageTags.length > 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) {
|
for (const event of events) {
|
||||||
const relationEvent = relationsMap.get(event);
|
const relationEvent = relationsMap.get(event);
|
||||||
if (!relationEvent) {
|
if (!relationEvent) {
|
||||||
@ -328,6 +300,7 @@ export type Decrypted_Nostr_Event = {
|
|||||||
readonly kind: nostr.NostrKind.CustomAppData;
|
readonly kind: nostr.NostrKind.CustomAppData;
|
||||||
readonly created_at: number;
|
readonly created_at: number;
|
||||||
readonly tags: Tag[];
|
readonly tags: Tag[];
|
||||||
|
readonly parsedTags: Tags;
|
||||||
readonly content: string;
|
readonly content: string;
|
||||||
readonly decryptedContent: string;
|
readonly decryptedContent: string;
|
||||||
};
|
};
|
||||||
@ -355,9 +328,9 @@ export type PlainText_Nostr_Event = {
|
|||||||
| NostrKind.RECOMMED_SERVER;
|
| NostrKind.RECOMMED_SERVER;
|
||||||
readonly created_at: number;
|
readonly created_at: number;
|
||||||
readonly tags: Tag[];
|
readonly tags: Tag[];
|
||||||
|
readonly parsedTags: Tags;
|
||||||
readonly content: string;
|
readonly content: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type CustomAppData = PinContact | UnpinContact | UserLogin;
|
export type CustomAppData = PinContact | UnpinContact | UserLogin;
|
||||||
|
|
||||||
export type PinContact = {
|
export type PinContact = {
|
||||||
|
Loading…
Reference in New Issue
Block a user