2023-07-11 09:49:58 +00:00
|
|
|
import { Database_Contextual_View } from "../database.ts";
|
2023-10-06 00:05:35 +00:00
|
|
|
import { NostrAccountContext, NostrKind } from "../lib/nostr-ts/nostr.ts";
|
2023-07-16 15:04:23 +00:00
|
|
|
import { Parsed_Event, Profile_Nostr_Event } from "../nostr.ts";
|
2023-09-06 21:04:25 +00:00
|
|
|
import { prepareNormalNostrEvent } from "../lib/nostr-ts/event.ts";
|
2023-10-01 20:59:07 +00:00
|
|
|
import { semaphore } from "https://raw.githubusercontent.com/BlowaterNostr/csp/master/csp.ts";
|
2023-10-15 22:39:21 +00:00
|
|
|
import { ProfileAdder } from "./gm.ts";
|
2023-11-03 13:09:13 +00:00
|
|
|
import { ConnectionPool } from "../lib/nostr-ts/relay-pool.ts";
|
2023-08-28 20:34:41 +00:00
|
|
|
|
2023-10-15 22:39:21 +00:00
|
|
|
export class ProfileSyncer implements ProfileAdder {
|
2023-08-28 20:34:41 +00:00
|
|
|
readonly userSet = new Set<string>();
|
2023-10-01 20:59:07 +00:00
|
|
|
private readonly lock = semaphore(1);
|
2023-08-28 20:34:41 +00:00
|
|
|
|
2023-06-30 14:05:57 +00:00
|
|
|
constructor(
|
2023-08-28 20:34:41 +00:00
|
|
|
private readonly database: Database_Contextual_View,
|
|
|
|
private readonly pool: ConnectionPool,
|
2023-09-27 19:49:23 +00:00
|
|
|
) {
|
|
|
|
}
|
2023-08-28 20:34:41 +00:00
|
|
|
|
|
|
|
async add(...users: string[]) {
|
2023-08-29 22:46:42 +00:00
|
|
|
const size = this.userSet.size;
|
|
|
|
for (const user of users) {
|
|
|
|
this.userSet.add(user);
|
|
|
|
}
|
|
|
|
if (this.userSet.size == size) {
|
|
|
|
return;
|
|
|
|
}
|
2023-10-01 20:59:07 +00:00
|
|
|
const resp = await this.lock(async () => {
|
|
|
|
await this.pool.closeSub(ProfileSyncer.name);
|
|
|
|
const resp = await this.pool.newSub(ProfileSyncer.name, {
|
|
|
|
authors: Array.from(this.userSet),
|
|
|
|
kinds: [NostrKind.META_DATA],
|
|
|
|
});
|
|
|
|
return resp;
|
2023-09-27 19:49:23 +00:00
|
|
|
});
|
2023-08-29 22:46:42 +00:00
|
|
|
if (resp instanceof Error) {
|
2023-10-01 20:59:07 +00:00
|
|
|
console.log(resp);
|
2023-08-29 22:46:42 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
for await (let { res: nostrMessage, url: relayUrl } of resp.chan) {
|
|
|
|
if (nostrMessage.type === "EVENT" && nostrMessage.event.content) {
|
2023-11-16 09:18:30 +00:00
|
|
|
this.database.addEvent(nostrMessage.event, relayUrl);
|
2023-08-29 22:46:42 +00:00
|
|
|
}
|
2023-06-30 14:05:57 +00:00
|
|
|
}
|
2023-08-28 20:34:41 +00:00
|
|
|
}
|
2023-06-30 14:05:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
export async function saveProfile(
|
|
|
|
profile: ProfileData,
|
|
|
|
sender: NostrAccountContext,
|
|
|
|
pool: ConnectionPool,
|
|
|
|
) {
|
|
|
|
const event = await prepareNormalNostrEvent(
|
|
|
|
sender,
|
2023-10-26 08:42:04 +00:00
|
|
|
{ kind: NostrKind.META_DATA, content: JSON.stringify(profile) },
|
2023-06-30 14:05:57 +00:00
|
|
|
);
|
|
|
|
pool.sendEvent(event);
|
|
|
|
}
|
|
|
|
|
|
|
|
// aka user profile
|
|
|
|
export interface ProfileData {
|
|
|
|
name?: string;
|
|
|
|
picture?: string;
|
|
|
|
about?: string;
|
|
|
|
website?: string;
|
|
|
|
banner?: string;
|
|
|
|
[key: string]: string | undefined;
|
|
|
|
}
|
|
|
|
|
2023-07-14 10:59:25 +00:00
|
|
|
export function ProfileFromNostrEvent(
|
2023-07-15 05:58:03 +00:00
|
|
|
event: Parsed_Event<NostrKind.META_DATA>,
|
2023-07-14 14:13:15 +00:00
|
|
|
) {
|
2023-10-07 10:59:06 +00:00
|
|
|
const profileData = parseJSON<ProfileData>(event.content);
|
2023-07-14 14:13:15 +00:00
|
|
|
if (profileData instanceof Error) {
|
|
|
|
return profileData;
|
2023-07-07 08:31:06 +00:00
|
|
|
}
|
2023-07-14 14:13:15 +00:00
|
|
|
const e: Profile_Nostr_Event = {
|
2023-06-30 14:05:57 +00:00
|
|
|
kind: event.kind,
|
|
|
|
id: event.id,
|
|
|
|
sig: event.sig,
|
|
|
|
created_at: event.created_at,
|
|
|
|
pubkey: event.pubkey,
|
|
|
|
tags: event.tags,
|
2023-07-14 10:59:25 +00:00
|
|
|
content: event.content,
|
|
|
|
parsedTags: event.parsedTags,
|
|
|
|
profile: profileData,
|
2023-07-15 05:58:03 +00:00
|
|
|
publicKey: event.publicKey,
|
2023-06-30 14:05:57 +00:00
|
|
|
};
|
2023-07-14 14:13:15 +00:00
|
|
|
return e;
|
|
|
|
}
|
|
|
|
|
2023-10-07 10:59:06 +00:00
|
|
|
export function parseJSON<T>(content: string): T | Error {
|
2023-07-14 14:13:15 +00:00
|
|
|
try {
|
2023-10-07 10:59:06 +00:00
|
|
|
return JSON.parse(content) as T;
|
2023-07-14 14:13:15 +00:00
|
|
|
} catch (e) {
|
|
|
|
return e as Error;
|
|
|
|
}
|
2023-06-30 14:05:57 +00:00
|
|
|
}
|