Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
dholms committed Dec 7, 2023
1 parent eef3a81 commit 92d9060
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 20 deletions.
57 changes: 52 additions & 5 deletions packages/bsky/src/hydration/actor.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { DataPlaneClient } from '../data-plane/client'
import { Record as ProfileRecord } from '../lexicon/types/app/bsky/actor/profile'
import { HydrationMap } from './util'
import { HydrationMap, parseRecord } from './util'

export type Profile = {
did: string
Expand All @@ -13,8 +13,9 @@ export type Profiles = HydrationMap<Profile>
export type ProfileViewerState = {
muted?: boolean
mutedByList?: string
blockedBy?: boolean
blockedBy?: string
blocking?: string
blockedByList?: string
blockingByList?: string
following?: string
followedBy?: string
Expand All @@ -34,17 +35,63 @@ export class ActorHydrator {
constructor(public dataplane: DataPlaneClient) {}

async getProfiles(dids: string[]): Promise<Profiles> {
throw new Error('unimplemented')
const [handles, profiles] = await Promise.all([
this.dataplane.getHandles({ dids }),
this.dataplane.getProfiles({ dids }),
])
return dids.reduce((acc, did, i) => {
const handle = handles[i] ?? null
const record = parseRecord<Profile>(profiles.records[i])
return acc.set(did, {
did,
handle,
record,
})
}, new HydrationMap<Profile>())
}

async getProfileViewerStates(
dids: string[],
viewer: string,
): Promise<ProfileViewerStates> {
throw new Error('unimplemented')
const res = await this.dataplane.getRelationships({
actorDid: viewer,
targetDids: dids,
})
return dids.reduce((acc, did, i) => {
const rels = res.relationships[i]
return acc.set(did, {
muted: rels.muted,
mutedByList: rels.mutedByList.length > 0 ? rels.mutedByList : undefined,
blockedBy: rels.blockedBy.length > 0 ? rels.blockedBy : undefined,
blocking: rels.blocking.length > 0 ? rels.blocking : undefined,
blockedByList:
rels.blockedByList.length > 0 ? rels.blockedByList : undefined,
blockingByList:
rels.blockingByList.length > 0 ? rels.blockingByList : undefined,
following: rels.following.length > 0 ? rels.following : undefined,
followedBy: rels.followedBy.length > 0 ? rels.followedBy : undefined,
})
}, new HydrationMap<ProfileViewerState>())
}

async getProfileAggregates(dids: string[]): Promise<ProfileAggs> {
throw new Error('unimplemented')
const aggs = await Promise.all(dids.map((did) => this.getAggsForDid(did)))
return dids.reduce((acc, did, i) => {
return acc.set(did, aggs[i])
}, new HydrationMap<ProfileAgg>())
}

private async getAggsForDid(actorDid: string) {
const [followers, follows, posts] = await Promise.all([
this.dataplane.getFollowersCount({ actorDid }),
this.dataplane.getFollowsCount({ actorDid }),
{ count: 0 }, // @TODO need getPostsCount function
])
return {
followers: followers.count,
follows: follows.count,
posts: posts.count,
}
}
}
24 changes: 10 additions & 14 deletions packages/bsky/src/hydration/graph.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import * as ui8 from 'uint8arrays'
import { Record as ListRecord } from '../lexicon/types/app/bsky/graph/list'
import { DataPlaneClient } from '../data-plane/client'
import { jsonToLex } from '@atproto/lexicon'
import { HydrationMap } from './util'
import { HydrationMap, parseRecord } from './util'

export type List = ListRecord
export type Lists = HydrationMap<List>
Expand Down Expand Up @@ -33,17 +31,15 @@ export class Blocks {
export class GraphHydrator {
constructor(public dataplane: DataPlaneClient) {}

async getListRecords(uris: string[]): Promise<Lists> {
async getLists(uris: string[]): Promise<Lists> {
const res = await this.dataplane.getLists({ uris })
return uris.reduce((acc, uri, i) => {
const list = res.records[i]
const parsed = JSON.parse(ui8.toString(list, 'utf8'))
const record = parsed ? (jsonToLex(parsed) as ListRecord) : null
const record = parseRecord<List>(res.records[i])
return acc.set(uri, record)
}, new Map() as Lists)
}, new HydrationMap() as Lists)
}

async getListsViewerState(
async getListViewerStates(
uris: string[],
viewer: string,
): Promise<ListViewerStates> {
Expand All @@ -60,11 +56,7 @@ export class GraphHydrator {
viewerListBlockUri: mutesAndBlocks[i].listBlockUri,
viewerInList: listMemberships.listitemUris[i],
})
}, new Map() as ListViewerStates)
}

async getBidirectionalBlocks(pairs: RelationshipPair[]): Promise<Blocks> {
throw new Error('unimplemented')
}, new HydrationMap() as ListViewerStates)
}

private async getMutesAndBlocks(uri: string, viewer: string) {
Expand All @@ -83,4 +75,8 @@ export class GraphHydrator {
listBlockUri: listBlockUri.listblockUri,
}
}

async getBidirectionalBlocks(pairs: RelationshipPair[]): Promise<Blocks> {
throw new Error('unimplemented')
}
}
14 changes: 13 additions & 1 deletion packages/bsky/src/hydration/util.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
import { jsonToLex } from '@atproto/lexicon'
import * as ui8 from 'uint8arrays'

export class HydrationMap<T> extends Map<string, T | null> {
merge(map: HydrationMap<T>): HydrationMap<T> {
throw new Error('unimplemented')
map.forEach((val, key) => {
this.set(key, val)
})
return this
}
}

export const parseRecord = <T>(bytes: Uint8Array): T | null => {
if (bytes.byteLength === 0) return null
const parsed = JSON.parse(ui8.toString(bytes, 'utf8'))
return parsed ? (jsonToLex(parsed) as T) : null
}

0 comments on commit 92d9060

Please sign in to comment.