From 245739178479d3845e10af9c265b10fbd9c4a864 Mon Sep 17 00:00:00 2001 From: dholms Date: Thu, 1 Feb 2024 18:07:06 -0600 Subject: [PATCH 1/5] dont apply missing mod lists --- packages/bsky/src/hydration/hydrator.ts | 31 +++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/packages/bsky/src/hydration/hydrator.ts b/packages/bsky/src/hydration/hydrator.ts index f6b70f7173a..c967908934e 100644 --- a/packages/bsky/src/hydration/hydrator.ts +++ b/packages/bsky/src/hydration/hydrator.ts @@ -104,6 +104,10 @@ export class Hydrator { listUris.push(...listUrisFromProfileViewer(item)) }) const listState = await this.hydrateListsBasic(listUris, viewer) + // if a list no longer exists or is not a mod list, then remove from viewer state + profileViewers?.forEach((item) => { + removeNonModListsFromProfileViewer(item, listState) + }) return mergeStates(listState, { actors, labels, @@ -563,9 +567,36 @@ const listUrisFromProfileViewer = (item: ProfileViewerState | null) => { if (item?.blockingByList) { listUris.push(item.blockingByList) } + if (item?.blockedByList) { + listUris.push(item.blockedByList) + } return listUris } +const removeNonModListsFromProfileViewer = ( + item: ProfileViewerState | null, + state: HydrationState, +) => { + if (!isModList(item?.mutedByList, state)) { + delete item?.mutedByList + } + if (!isModList(item?.blockingByList, state)) { + delete item?.blockingByList + } + if (!isModList(item?.blockedByList, state)) { + delete item?.blockedByList + } +} + +const isModList = ( + listUri: string | undefined, + state: HydrationState, +): boolean => { + if (!listUri) return false + const list = state.lists?.get(listUri) + return list?.record.purpose === 'app.bsky.graph.defs#modlist' +} + const labelSubjectsForDid = (dids: string[]) => { return [ ...dids, From add0cc86e657ffdecdd85366d32be6f7e760f429 Mon Sep 17 00:00:00 2001 From: dholms Date: Thu, 1 Feb 2024 18:10:59 -0600 Subject: [PATCH 2/5] update mock dataplane --- packages/bsky/src/data-plane/server/routes/relationships.ts | 6 ------ 1 file changed, 6 deletions(-) diff --git a/packages/bsky/src/data-plane/server/routes/relationships.ts b/packages/bsky/src/data-plane/server/routes/relationships.ts index c877c1112f3..d6029e169e8 100644 --- a/packages/bsky/src/data-plane/server/routes/relationships.ts +++ b/packages/bsky/src/data-plane/server/routes/relationships.ts @@ -26,8 +26,6 @@ export default (db: Database): Partial> => ({ db.db .selectFrom('list_item') .innerJoin('list_mute', 'list_mute.listUri', 'list_item.listUri') - .innerJoin('list', 'list.uri', 'list_item.listUri') - .where('list.purpose', '=', 'app.bsky.graph.defs#modlist') .where('list_mute.mutedByDid', '=', actorDid) .whereRef('list_item.subjectDid', '=', ref('actor.did')) .select('list_item.listUri') @@ -47,8 +45,6 @@ export default (db: Database): Partial> => ({ db.db .selectFrom('list_item') .innerJoin('list_block', 'list_block.subjectUri', 'list_item.listUri') - .innerJoin('list', 'list.uri', 'list_item.listUri') - .where('list.purpose', '=', 'app.bsky.graph.defs#modlist') .where('list_block.creator', '=', actorDid) .whereRef('list_item.subjectDid', '=', ref('actor.did')) .select('list_item.listUri') @@ -56,8 +52,6 @@ export default (db: Database): Partial> => ({ db.db .selectFrom('list_item') .innerJoin('list_block', 'list_block.subjectUri', 'list_item.listUri') - .innerJoin('list', 'list.uri', 'list_item.listUri') - .where('list.purpose', '=', 'app.bsky.graph.defs#modlist') .where('list_item.subjectDid', '=', actorDid) .whereRef('list_block.creator', '=', ref('actor.did')) .select('list_item.listUri') From ad9233ef888b867bc2f0c14a8ee445590b38b557 Mon Sep 17 00:00:00 2001 From: Daniel Holmgren Date: Fri, 2 Feb 2024 11:37:52 -0600 Subject: [PATCH 3/5] Update packages/bsky/src/hydration/hydrator.ts Co-authored-by: devin ivy --- packages/bsky/src/hydration/hydrator.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/bsky/src/hydration/hydrator.ts b/packages/bsky/src/hydration/hydrator.ts index c967908934e..8b063781754 100644 --- a/packages/bsky/src/hydration/hydrator.ts +++ b/packages/bsky/src/hydration/hydrator.ts @@ -567,6 +567,7 @@ const listUrisFromProfileViewer = (item: ProfileViewerState | null) => { if (item?.blockingByList) { listUris.push(item.blockingByList) } + // blocked-by list does not appear in views, but will be used to evaluate the existence of a block between users. if (item?.blockedByList) { listUris.push(item.blockedByList) } From 9cdc882601d1ed1e05e71af65719bd97807cec6d Mon Sep 17 00:00:00 2001 From: dholms Date: Fri, 2 Feb 2024 14:27:33 -0600 Subject: [PATCH 4/5] refactor & document a bit better --- packages/bsky/src/hydration/actor.ts | 5 +++- packages/bsky/src/hydration/hydrator.ts | 37 ++++++++++++++++++------- 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/packages/bsky/src/hydration/actor.ts b/packages/bsky/src/hydration/actor.ts index f340221067d..de032468c22 100644 --- a/packages/bsky/src/hydration/actor.ts +++ b/packages/bsky/src/hydration/actor.ts @@ -106,7 +106,10 @@ export class ActorHydrator { }, new HydrationMap()) } - async getProfileViewerStates( + // "naive" because this method does not verify the existence of the list itself + // a later check in the main hydrator will remove list uris that have been deleted or + // repurposed to "curate lists" + async getProfileViewerStatesNaive( dids: string[], viewer: string, ): Promise { diff --git a/packages/bsky/src/hydration/hydrator.ts b/packages/bsky/src/hydration/hydrator.ts index 8b063781754..d7ead860336 100644 --- a/packages/bsky/src/hydration/hydrator.ts +++ b/packages/bsky/src/hydration/hydrator.ts @@ -87,18 +87,17 @@ export class Hydrator { } // app.bsky.actor.defs#profileView - // - profile + // - profile viewer // - list basic - async hydrateProfiles( + // Note: builds on the naive profile viewer hydrator and removes references to lists that have been deleted + async hydrateProfileViewers( dids: string[], - viewer: string | null, - includeTakedowns = false, + viewer: string, ): Promise { - const [actors, labels, profileViewers] = await Promise.all([ - this.actor.getActors(dids, includeTakedowns), - this.label.getLabelsForSubjects(labelSubjectsForDid(dids)), - viewer ? this.actor.getProfileViewerStates(dids, viewer) : undefined, - ]) + const profileViewers = await this.actor.getProfileViewerStatesNaive( + dids, + viewer, + ) const listUris: string[] = [] profileViewers?.forEach((item) => { listUris.push(...listUrisFromProfileViewer(item)) @@ -109,9 +108,27 @@ export class Hydrator { removeNonModListsFromProfileViewer(item, listState) }) return mergeStates(listState, { + profileViewers, + viewer, + }) + } + + // app.bsky.actor.defs#profileView + // - profile + // - list basic + async hydrateProfiles( + dids: string[], + viewer: string | null, + includeTakedowns = false, + ): Promise { + const [actors, labels, profileViewersState] = await Promise.all([ + this.actor.getActors(dids, includeTakedowns), + this.label.getLabelsForSubjects(labelSubjectsForDid(dids)), + viewer ? this.hydrateProfileViewers(dids, viewer) : undefined, + ]) + return mergeStates(profileViewersState ?? {}, { actors, labels, - profileViewers, viewer, }) } From b86ba6e6ac97bebfb127f554ec5dc4e462eea041 Mon Sep 17 00:00:00 2001 From: dholms Date: Fri, 2 Feb 2024 14:29:06 -0600 Subject: [PATCH 5/5] fix up other routes --- packages/bsky/src/api/app/bsky/feed/getAuthorFeed.ts | 5 +---- packages/bsky/src/api/app/bsky/graph/getRelationships.ts | 5 ++++- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/bsky/src/api/app/bsky/feed/getAuthorFeed.ts b/packages/bsky/src/api/app/bsky/feed/getAuthorFeed.ts index 2fa6114d8be..1f11a9f9b8d 100644 --- a/packages/bsky/src/api/app/bsky/feed/getAuthorFeed.ts +++ b/packages/bsky/src/api/app/bsky/feed/getAuthorFeed.ts @@ -95,10 +95,7 @@ const hydration = async (inputs: { const [feedPostState, profileViewerState = {}] = await Promise.all([ ctx.hydrator.hydrateFeedItems(skeleton.items, params.viewer), params.viewer - ? ctx.hydrator.actor.getProfileViewerStates( - [skeleton.actor.did], - params.viewer, - ) + ? ctx.hydrator.hydrateProfileViewers([skeleton.actor.did], params.viewer) : undefined, ]) return mergeStates(feedPostState, profileViewerState) diff --git a/packages/bsky/src/api/app/bsky/graph/getRelationships.ts b/packages/bsky/src/api/app/bsky/graph/getRelationships.ts index d0fc43d53ab..47aaa6cd083 100644 --- a/packages/bsky/src/api/app/bsky/graph/getRelationships.ts +++ b/packages/bsky/src/api/app/bsky/graph/getRelationships.ts @@ -14,7 +14,10 @@ export default function (server: Server, ctx: AppContext) { }, } } - const res = await ctx.hydrator.actor.getProfileViewerStates(others, actor) + const res = await ctx.hydrator.actor.getProfileViewerStatesNaive( + others, + actor, + ) const relationships = others.map((did) => { const subject = res.get(did) return subject