This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

core / web / src / lib / api / enrich.ts
2.5 kB 69 lines
1import type { BobbinContext, XrpcRequestInit } from "./client"; 2import type { Nsid } from "@atcute/lexicons/syntax"; 3import { INVALID_HANDLE, type MiniDoc } from "./identity"; 4import { jsonPost } from "./_request"; 5 6// payload types, also the keys payloads land under in the data sidecar 7export const TYPE_COUNT = "sh.tangled.query.enrichResponse#count"; 8export const TYPE_DISTINCT_AUTHORS = "sh.tangled.query.enrichResponse#distinctAuthors"; 9export const TYPE_VIEWER = "sh.tangled.query.enrichResponse#viewer"; 10export const TYPE_MINIDOC = "com.bad-example.identity.miniDoc"; 11 12export type RecordPath = string & {}; 13export type EnvelopePath = ".repo" | ".collection" | ".rkey" | "."; 14export type LinkSource = `${Nsid}:${RecordPath | EnvelopePath}`; 15 16export interface LinkDescriptor { 17 source: LinkSource; 18 type: string; 19 targets?: RecordPath[]; 20} 21 22// data[ref][source][type] = payload, payload shape depends on the type 23export type Sidecar = Record<string, Record<string, Record<string, unknown>>>; 24 25export interface Enriched<O> { 26 output: O; 27 data: Sidecar; 28} 29 30export interface EnrichRequest { 31 xrpc: string; 32 params?: Record<string, unknown>; 33 enrich: LinkDescriptor[]; 34 viewer?: string; 35} 36 37export const enrich = <O>( 38 ctx: BobbinContext, 39 req: EnrichRequest, 40 init?: XrpcRequestInit 41): Promise<Enriched<O>> => jsonPost<Enriched<O>>(ctx, "sh.tangled.query.enrichResponse", req, init); 42 43export const countOf = (data: Sidecar, ref: string | undefined, source: LinkSource): number => 44 (ref !== undefined && (data[ref]?.[source]?.[TYPE_COUNT] as number | undefined)) || 0; 45 46export const distinctAuthorsOf = ( 47 data: Sidecar, 48 ref: string | undefined, 49 source: LinkSource 50): number => 51 (ref !== undefined && (data[ref]?.[source]?.[TYPE_DISTINCT_AUTHORS] as number | undefined)) || 0; 52 53// undefined means no viewer or inapplicable descriptor, null means no matching record 54export const viewerUriOf = ( 55 data: Sidecar, 56 ref: string | undefined, 57 source: LinkSource 58): string | null | undefined => 59 ref !== undefined ? (data[ref]?.[source]?.[TYPE_VIEWER] as string | null | undefined) : undefined; 60 61export const miniDocOf = ( 62 data: Sidecar, 63 did: string | undefined, 64 source: LinkSource 65): MiniDoc | undefined => 66 did !== undefined ? (data[did]?.[source]?.[TYPE_MINIDOC] as MiniDoc | undefined) : undefined; 67 68export const handleOf = (data: Sidecar, did: string | undefined, source: LinkSource): string => 69 miniDocOf(data, did, source)?.handle ?? INVALID_HANDLE;