tangle_indexer


git clone https://radroots.dev/git/tangle_indexer.git
Log | Files | Refs | Submodules | LICENSE

index.ts (3598B)


      1 import { _env } from "$lib/utils/_env";
      2 import { type FetchJsonResult, type HttpFetch, fetch_json } from "@radroots/apps-lib";
      3 import type { PageLoadProfileData } from "@radroots/apps-lib-market";
      4 import type {
      5     RadrootsCommentEventMetadata,
      6     RadrootsListingEventMetadata,
      7     RadrootsProfileEventMetadata
      8 } from "@radroots/events-bindings";
      9 import type { RadrootsEventsIndexedManifest as radroots_events_indexed_manifest } from "@radroots/events-indexed-bindings";
     10 import { nostr_npub_encode } from "@radroots/nostr";
     11 
     12 type ProfileRoutesKind = "author" | "npub" | "nip05";
     13 
     14 type CommentsByRoot = Record<string, RadrootsCommentEventMetadata[]>;
     15 
     16 export type PageLoadProfileDataWithComments = PageLoadProfileData & {
     17     events: PageLoadProfileData["events"] & {
     18         listing_comments: CommentsByRoot;
     19     };
     20 };
     21 
     22 const { RADROOTS_MARKET_INDEXES_URL: idx_url } = _env;
     23 
     24 async function fetch_listings(
     25     fetch_fn: HttpFetch,
     26     kind: ProfileRoutesKind,
     27     key: string
     28 ): Promise<FetchJsonResult<RadrootsListingEventMetadata[]>> {
     29     const manifest_res = await fetch_json<radroots_events_indexed_manifest>(
     30         fetch_fn,
     31         `${idx_url}/events/30402/${kind}/${encodeURIComponent(key)}/manifest.json`
     32     );
     33 
     34     if (!manifest_res.ok) return manifest_res;
     35 
     36     if (!manifest_res.data.shards.length) return { ok: true, data: [] };
     37 
     38     const shard = manifest_res.data.shards[0];
     39     const shard_url = `${idx_url}/events/30402/${kind}/${encodeURIComponent(
     40         key
     41     )}/${shard.file}?v=${shard.sha256}`;
     42     const events_res = await fetch_json<RadrootsListingEventMetadata[]>(fetch_fn, shard_url);
     43     if (!events_res.ok) return events_res;
     44     return { ok: true, data: events_res.data };
     45 }
     46 
     47 async function fetch_comments_for_roots(
     48     fetch_fn: HttpFetch,
     49     rootIds: readonly string[]
     50 ): Promise<CommentsByRoot> {
     51     const unique = Array.from(new Set(rootIds.map((id) => id.toLowerCase())));
     52 
     53     const entries: [string, RadrootsCommentEventMetadata[]][] = await Promise.all(
     54         unique.map(async (id): Promise<[string, RadrootsCommentEventMetadata[]]> => {
     55             const url = `${idx_url}/events/1111/root/${encodeURIComponent(
     56                 id
     57             )}/metadata.json`;
     58             const metas_res = await fetch_json<RadrootsCommentEventMetadata[]>(
     59                 fetch_fn,
     60                 url
     61             );
     62             return [id, metas_res.ok ? metas_res.data : []];
     63         })
     64     );
     65 
     66     const out: CommentsByRoot = {};
     67     for (const [id, metas] of entries) {
     68         out[id] = metas;
     69     }
     70 
     71     return out;
     72 }
     73 
     74 export async function load_profile_indexed(
     75     fetch_fn: HttpFetch,
     76     kind: ProfileRoutesKind,
     77     key: string
     78 ): Promise<FetchJsonResult<PageLoadProfileDataWithComments>> {
     79     const profile_res = await fetch_json<RadrootsProfileEventMetadata>(
     80         fetch_fn,
     81         `${idx_url}/events/0/${kind}/${encodeURIComponent(key)}/metadata.json`
     82     );
     83     if (!profile_res.ok) return profile_res;
     84 
     85     const listings_res = await fetch_listings(fetch_fn, kind, key);
     86     if (!listings_res.ok) return listings_res;
     87 
     88     const listing_ids = listings_res.data.map((m) => m.id.toLowerCase());
     89     const listing_comments = await fetch_comments_for_roots(fetch_fn, listing_ids);
     90 
     91     const public_key = profile_res.data.author;
     92     const npub = nostr_npub_encode(public_key);
     93 
     94     return {
     95         ok: true,
     96         data: {
     97             public_key,
     98             npub,
     99             events: {
    100                 profile: profile_res.data,
    101                 listings: listings_res.data,
    102                 listing_comments
    103             }
    104         }
    105     };
    106 }