Something went wrong. Try again.
csr tangled client in solid-js
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219import { ok } from '@atcute/client';import type { ResolvedActor } from '@atcute/identity-resolver';import type { Did, Nsid, ResourceUri } from '@atcute/lexicons/syntax';import type { OAuthUserAgent } from '@atcute/oauth-browser-client';import { ShTangledGraphFollow } from '@atcute/tangled';
import { getRpc } from './client';import { createAuthRpc, resolveActor, resolveActorForDisplay } from './identity';import { parseAtUri, type RecordCreationResult } from './records';import { listAllAppviewRecords } from './appview';
const FOLLOW_COLLECTION = 'sh.tangled.graph.follow' as Nsid;
export interface FollowRecord { uri: ResourceUri; cid: string; rkey: string; value: ShTangledGraphFollow.Main;}
export const listFollowRecords = async (actor: string | ResolvedActor): Promise<FollowRecord[]> => { const resolved = typeof actor === 'string' ? await resolveActor(actor) : actor; const rpc = getRpc(resolved.pds); const records: FollowRecord[] = []; let cursor: string | undefined;
do { const page = await ok( rpc.get('com.atproto.repo.listRecords', { params: { repo: resolved.did, collection: FOLLOW_COLLECTION, limit: 100, cursor, reverse: true, }, }), );
records.push( ...page.records.map((record) => ({ uri: record.uri, cid: record.cid, rkey: parseAtUri(record.uri).rkey, value: record.value as ShTangledGraphFollow.Main, })), ); cursor = page.cursor; } while (cursor);
return records;};
export const createFollow = async (agent: OAuthUserAgent, followeeDid: Did): Promise<RecordCreationResult> => { const rpc = createAuthRpc(agent); const record: ShTangledGraphFollow.Main = { $type: 'sh.tangled.graph.follow', subject: followeeDid, createdAt: new Date().toISOString(), }; const result = await ok( rpc.post('com.atproto.repo.createRecord', { input: { repo: agent.sub, collection: FOLLOW_COLLECTION, record, }, }), );
return { uri: result.uri, rkey: parseAtUri(result.uri).rkey, };};
export const deleteFollow = async (agent: OAuthUserAgent, rkey: string): Promise<void> => { const rpc = createAuthRpc(agent); await ok( rpc.post('com.atproto.repo.deleteRecord', { input: { repo: agent.sub, collection: FOLLOW_COLLECTION, rkey, }, }), );};
export interface FollowerFollowingItem { did: Did; handle: string; actor: ResolvedActor; followRecord: FollowRecord;}
export const getFollowers = async (did: Did): Promise<FollowerFollowingItem[]> => { const records = await listAllAppviewRecords<ShTangledGraphFollow.Main>('sh.tangled.graph.listFollows', did); return Promise.all( records.map(async (record) => { const parsed = parseAtUri(record.uri); const actor = await resolveActorForDisplay(parsed.did); return { did: parsed.did, handle: actor.handle, actor, followRecord: { uri: record.uri, cid: record.cid ?? '', rkey: parsed.rkey, value: record.value, }, }; }) );};
export const getFollowing = async (did: Did): Promise<FollowerFollowingItem[]> => { const records = await listAllAppviewRecords<ShTangledGraphFollow.Main>('sh.tangled.graph.listFollowsBy', did); return Promise.all( records.map(async (record) => { const targetDid = record.value.subject as Did; const actor = await resolveActorForDisplay(targetDid); const parsed = parseAtUri(record.uri); return { did: targetDid, handle: actor.handle, actor, followRecord: { uri: record.uri, cid: record.cid ?? '', rkey: parsed.rkey, value: record.value, }, }; }) );};
const VOUCH_COLLECTION = 'sh.tangled.graph.vouch';
export interface VouchRecord { uri: string; cid: string; value: { $type: 'sh.tangled.graph.vouch'; createdAt: string; kind: 'vouch' | 'denounce'; reason?: string; evidences?: string[]; };}
export const getVouchRecord = async ( viewerDid: Did, subjectDid: Did): Promise<VouchRecord | null> => { try { const resolvedViewer = await resolveActor(viewerDid); const rpc = getRpc(resolvedViewer.pds); const result = await ok( rpc.get('com.atproto.repo.getRecord', { params: { repo: resolvedViewer.did, collection: VOUCH_COLLECTION, rkey: subjectDid, }, }) ); return result as unknown as VouchRecord; } catch (e) { return null; }};
export const putVouchRecord = async ( agent: OAuthUserAgent, subjectDid: Did, kind: 'vouch' | 'denounce', reason?: string, evidences?: string[]): Promise<void> => { const rpc = createAuthRpc(agent); const record = { $type: VOUCH_COLLECTION, createdAt: new Date().toISOString(), kind, reason: reason || undefined, evidences: evidences || undefined, }; await ok( rpc.post('com.atproto.repo.putRecord', { input: { repo: agent.sub, collection: VOUCH_COLLECTION, rkey: subjectDid, record, }, }) );};
export const deleteVouchRecord = async ( agent: OAuthUserAgent, subjectDid: Did): Promise<void> => { const rpc = createAuthRpc(agent); await ok( rpc.post('com.atproto.repo.deleteRecord', { input: { repo: agent.sub, collection: VOUCH_COLLECTION, rkey: subjectDid, }, }) );};