MetadataCache -> CachedMetadata, addCachedMetadataToFuzzySearch
continuous-integration/drone/push Build is failing Details

This commit is contained in:
Martti Malmi 2024-01-08 16:12:05 +02:00
parent 88924941a5
commit c80eb25d29
20 changed files with 92 additions and 71 deletions

View File

@ -1,4 +1,4 @@
import { MetadataCache } from "@snort/system"; import { CachedMetadata } from "@snort/system";
import { FormattedMessage } from "react-intl"; import { FormattedMessage } from "react-intl";
import { Link } from "react-router-dom"; import { Link } from "react-router-dom";
@ -10,7 +10,7 @@ export class BackupKeyTask extends BaseUITask {
id = "backup-key"; id = "backup-key";
noBaseStyle = true; noBaseStyle = true;
check(_: MetadataCache, session: LoginSession): boolean { check(_: CachedMetadata, session: LoginSession): boolean {
return !this.state.muted && session.type == "private_key"; return !this.state.muted && session.type == "private_key";
} }

View File

@ -1,4 +1,4 @@
import { MetadataCache } from "@snort/system"; import { CachedMetadata } from "@snort/system";
import { FormattedMessage } from "react-intl"; import { FormattedMessage } from "react-intl";
import { Link } from "react-router-dom"; import { Link } from "react-router-dom";
@ -7,7 +7,7 @@ import { BaseUITask } from "@/Components/Tasks/index";
export class Nip5Task extends BaseUITask { export class Nip5Task extends BaseUITask {
id = "buy-nip5"; id = "buy-nip5";
check(user: MetadataCache): boolean { check(user: CachedMetadata): boolean {
return !this.state.muted && !user.nip05; return !this.state.muted && !user.nip05;
} }

View File

@ -1,4 +1,4 @@
import { MetadataCache } from "@snort/system"; import { CachedMetadata } from "@snort/system";
import { FormattedMessage } from "react-intl"; import { FormattedMessage } from "react-intl";
import { BaseUITask } from "@/Components/Tasks/index"; import { BaseUITask } from "@/Components/Tasks/index";
@ -9,7 +9,7 @@ import { getCurrentSubscription } from "@/Utils/Subscription";
export class RenewSubTask extends BaseUITask { export class RenewSubTask extends BaseUITask {
id = "renew-sub"; id = "renew-sub";
check(user: MetadataCache, session: LoginSession): boolean { check(user: CachedMetadata, session: LoginSession): boolean {
const sub = getCurrentSubscription(session.subscriptions); const sub = getCurrentSubscription(session.subscriptions);
return !sub && session.subscriptions.length > 0; return !sub && session.subscriptions.length > 0;
} }

View File

@ -1,4 +1,4 @@
import { MetadataCache } from "@snort/system"; import { CachedMetadata } from "@snort/system";
import { LoginSession } from "@/Utils/Login"; import { LoginSession } from "@/Utils/Login";
@ -8,7 +8,7 @@ export interface UITask {
/** /**
* Run checks to determine if this Task should be triggered for this user * Run checks to determine if this Task should be triggered for this user
*/ */
check(user: MetadataCache, session: LoginSession): boolean; check(user: CachedMetadata, session: LoginSession): boolean;
mute(): void; mute(): void;
load(cb: () => void): void; load(cb: () => void): void;
render(): JSX.Element; render(): JSX.Element;
@ -26,7 +26,7 @@ export abstract class BaseUITask implements UITask {
abstract id: string; abstract id: string;
noBaseStyle = false; noBaseStyle = false;
abstract check(user: MetadataCache, session: LoginSession): boolean; abstract check(user: CachedMetadata, session: LoginSession): boolean;
abstract render(): JSX.Element; abstract render(): JSX.Element;
constructor() { constructor() {

View File

@ -1,7 +1,7 @@
import "@webscopeio/react-textarea-autocomplete/style.css"; import "@webscopeio/react-textarea-autocomplete/style.css";
import "./Textarea.css"; import "./Textarea.css";
import { MetadataCache, NostrPrefix } from "@snort/system"; import { CachedMetadata, NostrPrefix } from "@snort/system";
import ReactTextareaAutocomplete from "@webscopeio/react-textarea-autocomplete"; import ReactTextareaAutocomplete from "@webscopeio/react-textarea-autocomplete";
import { useIntl } from "react-intl"; import { useIntl } from "react-intl";
import TextareaAutosize from "react-textarea-autosize"; import TextareaAutosize from "react-textarea-autosize";
@ -28,7 +28,7 @@ const EmojiItem = ({ entity: { name, char } }: { entity: EmojiItemProps }) => {
); );
}; };
const UserItem = (metadata: MetadataCache) => { const UserItem = (metadata: CachedMetadata) => {
const { pubkey, display_name, nip05, ...rest } = metadata; const { pubkey, display_name, nip05, ...rest } = metadata;
return ( return (
<div key={pubkey} className="user-item"> <div key={pubkey} className="user-item">
@ -84,7 +84,7 @@ const Textarea = (props: TextareaProps) => {
"@": { "@": {
afterWhitespace: true, afterWhitespace: true,
dataProvider: userDataProvider, dataProvider: userDataProvider,
component: (props: { entity: MetadataCache }) => <UserItem {...props.entity} />, component: (props: { entity: CachedMetadata }) => <UserItem {...props.entity} />,
output: (item: { pubkey: string }) => `@${hexToBech32(NostrPrefix.PublicKey, item.pubkey)}`, output: (item: { pubkey: string }) => `@${hexToBech32(NostrPrefix.PublicKey, item.pubkey)}`,
}, },
}} }}

View File

@ -1,4 +1,4 @@
import { MetadataCache, NostrLink, NostrPrefix, UserMetadata } from "@snort/system"; import { CachedMetadata, NostrLink, NostrPrefix, UserMetadata } from "@snort/system";
import { SnortContext } from "@snort/system-react"; import { SnortContext } from "@snort/system-react";
import { ReactNode, useContext } from "react"; import { ReactNode, useContext } from "react";
import { Link, LinkProps } from "react-router-dom"; import { Link, LinkProps } from "react-router-dom";
@ -13,7 +13,7 @@ export function ProfileLink({
...others ...others
}: { }: {
pubkey: string; pubkey: string;
user?: UserMetadata | MetadataCache; user?: UserMetadata | CachedMetadata;
explicitLink?: string; explicitLink?: string;
children?: ReactNode; children?: ReactNode;
} & Omit<LinkProps, "to">) { } & Omit<LinkProps, "to">) {

View File

@ -1,10 +1,10 @@
import "./UserWebsiteLink.css"; import "./UserWebsiteLink.css";
import { MetadataCache, UserMetadata } from "@snort/system"; import { CachedMetadata, UserMetadata } from "@snort/system";
import Icon from "@/Components/Icons/Icon"; import Icon from "@/Components/Icons/Icon";
export function UserWebsiteLink({ user }: { user?: MetadataCache | UserMetadata }) { export function UserWebsiteLink({ user }: { user?: CachedMetadata | UserMetadata }) {
const website_url = const website_url =
user?.website && !user.website.startsWith("http") ? "https://" + user.website : user?.website || ""; user?.website && !user.website.startsWith("http") ? "https://" + user.website : user?.website || "";

View File

@ -1,4 +1,5 @@
import Fuse from "fuse.js"; import Fuse from "fuse.js";
import {CachedMetadata} from "@snort/system";
export type FuzzySearchResult = { export type FuzzySearchResult = {
pubkey: string; pubkey: string;
@ -19,23 +20,43 @@ export const addEventToFuzzySearch = ev => {
if (ev.kind !== 0) { if (ev.kind !== 0) {
return; return;
} }
const existing = profileTimestamps.get(ev.pubkey); requestAnimationFrame(() => {
if (existing) { const existing = profileTimestamps.get(ev.pubkey);
if (existing > ev.created_at) { if (existing) {
return; if (existing > ev.created_at) {
return;
}
fuzzySearch.remove(doc => doc.pubkey === ev.pubkey);
} }
fuzzySearch.remove(doc => doc.pubkey === ev.pubkey); profileTimestamps.set(ev.pubkey, ev.created_at);
} try {
profileTimestamps.set(ev.pubkey, ev.created_at); const data = JSON.parse(ev.content);
try { if (ev.pubkey && (data.name || data.display_name || data.nip05)) {
const data = JSON.parse(ev.content); data.pubkey = ev.pubkey;
if (ev.pubkey && (data.name || data.display_name || data.nip05)) { fuzzySearch.add(data);
data.pubkey = ev.pubkey; }
fuzzySearch.add(data); } catch (e) {
console.error(e);
} }
} catch (e) { });
console.error(e);
}
}; };
export const addCachedMetadataToFuzzySearch = (profile: CachedMetadata) => {
// TODO add profiles from Cache
requestAnimationFrame(() => {
const existing = profileTimestamps.get(profile.pubkey);
if (existing) {
if (existing > profile.created) {
return;
}
fuzzySearch.remove(doc => doc.pubkey === profile.pubkey);
}
profileTimestamps.set(profile.pubkey, profile.created);
if (profile.pubkey && (profile.name || profile.display_name || profile.nip05)) {
fuzzySearch.add(profile);
console.log('added profile to fuzzy search', profile);
}
});
}
export default fuzzySearch; export default fuzzySearch;

View File

@ -1,4 +1,4 @@
import { MetadataCache } from "@snort/system"; import { CachedMetadata } from "@snort/system";
import { ChatParticipant } from "@/chat"; import { ChatParticipant } from "@/chat";
import NoteToSelf from "@/Components/User/NoteToSelf"; import NoteToSelf from "@/Components/User/NoteToSelf";
@ -10,5 +10,5 @@ export function ChatParticipantProfile({ participant }: { participant: ChatParti
if (participant.id === publicKey) { if (participant.id === publicKey) {
return <NoteToSelf className="grow" />; return <NoteToSelf className="grow" />;
} }
return <ProfileImage pubkey={participant.id} className="grow" profile={participant.profile as MetadataCache} />; return <ProfileImage pubkey={participant.id} className="grow" profile={participant.profile as CachedMetadata} />;
} }

View File

@ -1,4 +1,4 @@
import { MetadataCache, socialGraphInstance, STR, UID } from "@snort/system"; import { CachedMetadata, socialGraphInstance, STR, UID } from "@snort/system";
import { SnortContext } from "@snort/system-react"; import { SnortContext } from "@snort/system-react";
import { useContext, useEffect, useState } from "react"; import { useContext, useEffect, useState } from "react";
import { NodeObject } from "react-force-graph-3d"; import { NodeObject } from "react-force-graph-3d";
@ -12,7 +12,7 @@ import { defaultAvatar } from "../Utils";
interface GraphNode { interface GraphNode {
id: UID; id: UID;
profile?: MetadataCache; profile?: CachedMetadata;
distance: number; distance: number;
val: number; val: number;
inboundCount: number; inboundCount: number;

View File

@ -4,7 +4,7 @@ import { fetchNip05Pubkey, LNURL } from "@snort/shared";
import { import {
encodeTLVEntries, encodeTLVEntries,
EventKind, EventKind,
MetadataCache, CachedMetadata,
NostrPrefix, NostrPrefix,
TLVEntryType, TLVEntryType,
tryParseNostrLink, tryParseNostrLink,
@ -59,13 +59,13 @@ import { ZapTarget } from "@/Utils/Zapper";
interface ProfilePageProps { interface ProfilePageProps {
id?: string; id?: string;
state?: MetadataCache; state?: CachedMetadata;
} }
export default function ProfilePage({ id: propId, state }: ProfilePageProps) { export default function ProfilePage({ id: propId, state }: ProfilePageProps) {
const params = useParams(); const params = useParams();
const location = useLocation(); const location = useLocation();
const profileState = (location.state as MetadataCache | undefined) || state; const profileState = (location.state as CachedMetadata | undefined) || state;
const navigate = useNavigate(); const navigate = useNavigate();
const [id, setId] = useState<string | undefined>(profileState?.pubkey); const [id, setId] = useState<string | undefined>(profileState?.pubkey);
const [relays, setRelays] = useState<Array<string>>(); const [relays, setRelays] = useState<Array<string>>();

View File

@ -1,6 +1,6 @@
import { base64 } from "@scure/base"; import { base64 } from "@scure/base";
import { removeUndefined, unwrap } from "@snort/shared"; import { removeUndefined, unwrap } from "@snort/shared";
import { EventKind, EventPublisher, MetadataCache, TaggedNostrEvent } from "@snort/system"; import { EventKind, EventPublisher, CachedMetadata, TaggedNostrEvent } from "@snort/system";
import { UserCache } from "@/Cache"; import { UserCache } from "@/Cache";
import SnortApi from "@/External/SnortApi"; import SnortApi from "@/External/SnortApi";
@ -38,7 +38,7 @@ export async function makeNotification(ev: TaggedNostrEvent): Promise<Notificati
return null; return null;
} }
function replaceTagsWithUser(ev: TaggedNostrEvent, users: MetadataCache[]) { function replaceTagsWithUser(ev: TaggedNostrEvent, users: CachedMetadata[]) {
return ev.content return ev.content
.split(MentionRegex) .split(MentionRegex)
.map(match => { .map(match => {

View File

@ -9,7 +9,7 @@ import {
encodeTLV, encodeTLV,
EventKind, EventKind,
HexKey, HexKey,
MetadataCache, CachedMetadata,
NostrEvent, NostrEvent,
NostrLink, NostrLink,
NostrPrefix, NostrPrefix,
@ -214,8 +214,8 @@ export function getLatestByPubkey(events: TaggedNostrEvent[]): Map<HexKey, Tagge
return deduped; return deduped;
} }
export function getLatestProfileByPubkey(profiles: MetadataCache[]): Map<HexKey, MetadataCache> { export function getLatestProfileByPubkey(profiles: CachedMetadata[]): Map<HexKey, CachedMetadata> {
const deduped = profiles.reduce((results: Map<HexKey, MetadataCache>, ev) => { const deduped = profiles.reduce((results: Map<HexKey, CachedMetadata>, ev) => {
if (!results.has(ev.pubkey)) { if (!results.has(ev.pubkey)) {
const latest = getNewestProfile(profiles.filter(a => a.pubkey === ev.pubkey)); const latest = getNewestProfile(profiles.filter(a => a.pubkey === ev.pubkey));
if (latest) { if (latest) {
@ -223,7 +223,7 @@ export function getLatestProfileByPubkey(profiles: MetadataCache[]): Map<HexKey,
} }
} }
return results; return results;
}, new Map<HexKey, MetadataCache>()); }, new Map<HexKey, CachedMetadata>());
return deduped; return deduped;
} }
@ -255,7 +255,7 @@ export function getNewest(rawNotes: readonly TaggedNostrEvent[]) {
} }
} }
export function getNewestProfile(rawNotes: MetadataCache[]) { export function getNewestProfile(rawNotes: CachedMetadata[]) {
const notes = [...rawNotes]; const notes = [...rawNotes];
notes.sort((a, b) => b.created - a.created); notes.sort((a, b) => b.created - a.created);
if (notes.length > 0) { if (notes.length > 0) {
@ -279,7 +279,7 @@ export function tagFilterOfTextRepost(note: TaggedNostrEvent, id?: u256): (tag:
tag[0] === "e" && tag[3] === "mention" && note.content === `#[${i}]` && (id ? tag[1] === id : true); tag[0] === "e" && tag[3] === "mention" && note.content === `#[${i}]` && (id ? tag[1] === id : true);
} }
export function groupByPubkey(acc: Record<HexKey, MetadataCache>, user: MetadataCache) { export function groupByPubkey(acc: Record<HexKey, CachedMetadata>, user: CachedMetadata) {
return { ...acc, [user.pubkey]: user }; return { ...acc, [user.pubkey]: user };
} }

View File

@ -2,7 +2,7 @@ import { removeUndefined, throwIfOffline } from "@snort/shared";
import { mapEventToProfile, NostrEvent, NostrSystem, ProfileLoaderService, socialGraphInstance } from "@snort/system"; import { mapEventToProfile, NostrEvent, NostrSystem, ProfileLoaderService, socialGraphInstance } from "@snort/system";
import { RelayMetrics, SystemDb, UserCache, UserRelays } from "@/Cache"; import { RelayMetrics, SystemDb, UserCache, UserRelays } from "@/Cache";
import { addEventToFuzzySearch } from "@/Db/FuzzySearch"; import { addEventToFuzzySearch, addProfileToFuzzySearch } from "@/Db/FuzzySearch";
import { LoginStore } from "@/Utils/Login"; import { LoginStore } from "@/Utils/Login";
import { hasWasm, WasmOptimizer } from "@/Utils/wasm"; import { hasWasm, WasmOptimizer } from "@/Utils/wasm";

View File

@ -1,13 +1,13 @@
import { useContext, useSyncExternalStore } from "react"; import { useContext, useSyncExternalStore } from "react";
import { HexKey, MetadataCache } from "@snort/system"; import { HexKey, CachedMetadata } from "@snort/system";
import { SnortContext } from "./context"; import { SnortContext } from "./context";
/** /**
* Gets a profile from cache or requests it from the relays * Gets a profile from cache or requests it from the relays
*/ */
export function useUserProfile(pubKey?: HexKey): MetadataCache | undefined { export function useUserProfile(pubKey?: HexKey): CachedMetadata | undefined {
const system = useContext(SnortContext); const system = useContext(SnortContext);
return useSyncExternalStore<MetadataCache | undefined>( return useSyncExternalStore<CachedMetadata | undefined>(
h => { h => {
if (pubKey) { if (pubKey) {
system.ProfileLoader.TrackKeys(pubKey); system.ProfileLoader.TrackKeys(pubKey);

View File

@ -1,4 +1,4 @@
import { NostrEvent, MetadataCache, RelayMetrics, UsersRelays } from "@snort/system"; import { NostrEvent, CachedMetadata, RelayMetrics, UsersRelays } from "@snort/system";
import Dexie, { Table } from "dexie"; import Dexie, { Table } from "dexie";
const NAME = "snort-system"; const NAME = "snort-system";
@ -13,7 +13,7 @@ const STORES = {
export class SnortSystemDb extends Dexie { export class SnortSystemDb extends Dexie {
ready = false; ready = false;
users!: Table<MetadataCache>; users!: Table<CachedMetadata>;
relayMetrics!: Table<RelayMetrics>; relayMetrics!: Table<RelayMetrics>;
userRelays!: Table<UsersRelays>; userRelays!: Table<UsersRelays>;
events!: Table<NostrEvent>; events!: Table<NostrEvent>;

View File

@ -1,7 +1,7 @@
import { FullRelaySettings, HexKey, NostrEvent, UserMetadata } from ".."; import { FullRelaySettings, HexKey, NostrEvent, UserMetadata } from "..";
import { hexToBech32, unixNowMs, DexieTableLike } from "@snort/shared"; import { hexToBech32, unixNowMs, DexieTableLike } from "@snort/shared";
export interface MetadataCache extends UserMetadata { export interface CachedMetadata extends UserMetadata {
/** /**
* When the object was saved in cache * When the object was saved in cache
*/ */
@ -58,7 +58,7 @@ export function mapEventToProfile(ev: NostrEvent) {
npub: hexToBech32("npub", ev.pubkey), npub: hexToBech32("npub", ev.pubkey),
created: ev.created_at, created: ev.created_at,
loaded: unixNowMs(), loaded: unixNowMs(),
} as MetadataCache; } as CachedMetadata;
// sanitize non-string/number // sanitize non-string/number
for (const [k, v] of Object.entries(ret)) { for (const [k, v] of Object.entries(ret)) {
@ -73,7 +73,7 @@ export function mapEventToProfile(ev: NostrEvent) {
} }
export interface SnortSystemDb { export interface SnortSystemDb {
users: DexieTableLike<MetadataCache>; users: DexieTableLike<CachedMetadata>;
relayMetrics: DexieTableLike<RelayMetrics>; relayMetrics: DexieTableLike<RelayMetrics>;
userRelays: DexieTableLike<UsersRelays>; userRelays: DexieTableLike<UsersRelays>;
events: DexieTableLike<NostrEvent>; events: DexieTableLike<NostrEvent>;

View File

@ -1,17 +1,17 @@
import { MetadataCache } from "."; import { CachedMetadata } from ".";
import { fetchNip05Pubkey, FeedCache, LNURL, DexieTableLike } from "@snort/shared"; import { fetchNip05Pubkey, FeedCache, LNURL, DexieTableLike } from "@snort/shared";
export class UserProfileCache extends FeedCache<MetadataCache> { export class UserProfileCache extends FeedCache<CachedMetadata> {
#zapperQueue: Array<{ pubkey: string; lnurl: string }> = []; #zapperQueue: Array<{ pubkey: string; lnurl: string }> = [];
#nip5Queue: Array<{ pubkey: string; nip05: string }> = []; #nip5Queue: Array<{ pubkey: string; nip05: string }> = [];
constructor(table?: DexieTableLike<MetadataCache>) { constructor(table?: DexieTableLike<CachedMetadata>) {
super("UserCache", table); super("UserCache", table);
this.#processZapperQueue(); this.#processZapperQueue();
this.#processNip5Queue(); this.#processNip5Queue();
} }
key(of: MetadataCache): string { key(of: CachedMetadata): string {
return of.pubkey; return of.pubkey;
} }
@ -23,7 +23,7 @@ export class UserProfileCache extends FeedCache<MetadataCache> {
} }
} }
async search(q: string): Promise<Array<MetadataCache>> { async search(q: string): Promise<Array<CachedMetadata>> {
if (this.table) { if (this.table) {
// on-disk cache will always have more data // on-disk cache will always have more data
return ( return (
@ -41,7 +41,7 @@ export class UserProfileCache extends FeedCache<MetadataCache> {
} else { } else {
return [...this.cache.values()] return [...this.cache.values()]
.filter(user => { .filter(user => {
const profile = user as MetadataCache; const profile = user as CachedMetadata;
return ( return (
profile.name?.includes(q) || profile.name?.includes(q) ||
profile.npub?.includes(q) || profile.npub?.includes(q) ||
@ -58,7 +58,7 @@ export class UserProfileCache extends FeedCache<MetadataCache> {
* @param m Profile metadata * @param m Profile metadata
* @returns * @returns
*/ */
override async update(m: MetadataCache) { override async update(m: CachedMetadata) {
const updateType = await super.update(m); const updateType = await super.update(m);
if (updateType !== "refresh") { if (updateType !== "refresh") {
const lnurl = m.lud16 ?? m.lud06; const lnurl = m.lud16 ?? m.lud06;
@ -78,7 +78,7 @@ export class UserProfileCache extends FeedCache<MetadataCache> {
return updateType; return updateType;
} }
takeSnapshot(): MetadataCache[] { takeSnapshot(): CachedMetadata[] {
return [...this.cache.values()]; return [...this.cache.values()];
} }

View File

@ -9,7 +9,7 @@ import { NoteStore } from "./note-collection";
import { BuiltRawReqFilter, RequestBuilder } from "./request-builder"; import { BuiltRawReqFilter, RequestBuilder } from "./request-builder";
import { RelayMetricHandler } from "./relay-metric-handler"; import { RelayMetricHandler } from "./relay-metric-handler";
import { import {
MetadataCache, CachedMetadata,
ProfileLoaderService, ProfileLoaderService,
RelayMetrics, RelayMetrics,
SystemInterface, SystemInterface,
@ -38,7 +38,7 @@ export interface NostrSystemEvents {
export interface NostrsystemProps { export interface NostrsystemProps {
relayCache?: FeedCache<UsersRelays>; relayCache?: FeedCache<UsersRelays>;
profileCache?: FeedCache<MetadataCache>; profileCache?: FeedCache<CachedMetadata>;
relayMetrics?: FeedCache<RelayMetrics>; relayMetrics?: FeedCache<RelayMetrics>;
eventsCache?: FeedCache<NostrEvent>; eventsCache?: FeedCache<NostrEvent>;
optimizer?: Optimizer; optimizer?: Optimizer;
@ -62,7 +62,7 @@ export class NostrSystem extends EventEmitter<NostrSystemEvents> implements Syst
/** /**
* Storage class for user profiles * Storage class for user profiles
*/ */
#profileCache: FeedCache<MetadataCache>; #profileCache: FeedCache<CachedMetadata>;
/** /**
* Storage class for relay metrics (connects/disconnects) * Storage class for relay metrics (connects/disconnects)

View File

@ -1,16 +1,16 @@
import { unixNowMs } from "@snort/shared"; import { unixNowMs } from "@snort/shared";
import { EventKind, TaggedNostrEvent, RequestBuilder } from "."; import { EventKind, TaggedNostrEvent, RequestBuilder } from ".";
import { ProfileCacheExpire } from "./const"; import { ProfileCacheExpire } from "./const";
import { mapEventToProfile, MetadataCache } from "./cache"; import { mapEventToProfile, CachedMetadata } from "./cache";
import { v4 as uuid } from "uuid"; import { v4 as uuid } from "uuid";
import { BackgroundLoader } from "./background-loader"; import { BackgroundLoader } from "./background-loader";
export class ProfileLoaderService extends BackgroundLoader<MetadataCache> { export class ProfileLoaderService extends BackgroundLoader<CachedMetadata> {
override name(): string { override name(): string {
return "ProfileLoaderService"; return "ProfileLoaderService";
} }
override onEvent(e: Readonly<TaggedNostrEvent>): MetadataCache | undefined { override onEvent(e: Readonly<TaggedNostrEvent>): CachedMetadata | undefined {
return mapEventToProfile(e); return mapEventToProfile(e);
} }
@ -30,11 +30,11 @@ export class ProfileLoaderService extends BackgroundLoader<MetadataCache> {
return sub; return sub;
} }
protected override makePlaceholder(key: string): MetadataCache | undefined { protected override makePlaceholder(key: string): CachedMetadata | undefined {
return { return {
pubkey: key, pubkey: key,
loaded: unixNowMs() - ProfileCacheExpire + 30_000, loaded: unixNowMs() - ProfileCacheExpire + 30_000,
created: 0, created: 0,
} as MetadataCache; } as CachedMetadata;
} }
} }