import type { BobbinContext, XrpcRequestInit } from "./client"; import type { Nsid } from "@atcute/lexicons/syntax"; import { jsonPost } from "./_request"; export type RecordPath = string & {}; export type EnvelopePath = ".repo" | ".collection" | ".rkey" | "."; export type LinkSource = `${Nsid}:${RecordPath | EnvelopePath}`; export interface LinkDescriptor { source: LinkSource; type: "count" | "distinctAuthors" | "viewer"; } // ref is did or at-uri, source echoes the descriptor string, viewer holds the caller's own record uri if requested, null if none exists export interface StatsLeaf { count?: number; distinctAuthors?: number; viewer?: string | null; } export type Stats = Record>; export interface Enriched { output: O; stats: Stats; } export interface EnrichRequest { xrpc: string; params?: Record; enrich: LinkDescriptor[]; sources?: string[]; viewer?: string; } export const enrich = ( ctx: BobbinContext, req: EnrichRequest, init?: XrpcRequestInit ): Promise> => jsonPost>(ctx, "sh.tangled.query.enrichResponse", req, init); export const countOf = (stats: Stats, ref: string | undefined, source: LinkSource): number => (ref !== undefined && stats[ref]?.[source]?.count) || 0; // undefined means no viewer or inapplicable descriptor, null means no matching record export const viewerUriOf = ( stats: Stats, ref: string | undefined, source: LinkSource ): string | null | undefined => (ref !== undefined ? stats[ref]?.[source]?.viewer : undefined);