import type { BobbinContext, XrpcRequestInit } from "./client"; import type { Nsid } from "@atcute/lexicons/syntax"; import { INVALID_HANDLE, type MiniDoc } from "./identity"; import { jsonPost } from "./_request"; // payload types, also the keys payloads land under in the data sidecar export const TYPE_COUNT = "sh.tangled.query.enrichResponse#count"; export const TYPE_DISTINCT_AUTHORS = "sh.tangled.query.enrichResponse#distinctAuthors"; export const TYPE_VIEWER = "sh.tangled.query.enrichResponse#viewer"; export const TYPE_MINIDOC = "com.bad-example.identity.miniDoc"; export type RecordPath = string & {}; export type EnvelopePath = ".repo" | ".collection" | ".rkey" | "."; export type LinkSource = `${Nsid}:${RecordPath | EnvelopePath}`; export interface LinkDescriptor { source: LinkSource; type: string; targets?: RecordPath[]; } // data[ref][source][type] = payload, payload shape depends on the type export type Sidecar = Record>>; export interface Enriched { output: O; data: Sidecar; } export interface EnrichRequest { xrpc: string; params?: Record; enrich: LinkDescriptor[]; viewer?: string; } export const enrich = ( ctx: BobbinContext, req: EnrichRequest, init?: XrpcRequestInit ): Promise> => jsonPost>(ctx, "sh.tangled.query.enrichResponse", req, init); export const countOf = (data: Sidecar, ref: string | undefined, source: LinkSource): number => (ref !== undefined && (data[ref]?.[source]?.[TYPE_COUNT] as number | undefined)) || 0; export const distinctAuthorsOf = ( data: Sidecar, ref: string | undefined, source: LinkSource ): number => (ref !== undefined && (data[ref]?.[source]?.[TYPE_DISTINCT_AUTHORS] as number | undefined)) || 0; // undefined means no viewer or inapplicable descriptor, null means no matching record export const viewerUriOf = ( data: Sidecar, ref: string | undefined, source: LinkSource ): string | null | undefined => ref !== undefined ? (data[ref]?.[source]?.[TYPE_VIEWER] as string | null | undefined) : undefined; export const miniDocOf = ( data: Sidecar, did: string | undefined, source: LinkSource ): MiniDoc | undefined => did !== undefined ? (data[did]?.[source]?.[TYPE_MINIDOC] as MiniDoc | undefined) : undefined; export const handleOf = (data: Sidecar, did: string | undefined, source: LinkSource): string => miniDocOf(data, did, source)?.handle ?? INVALID_HANDLE;