@atproto/bsky 0.3.13 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +61 -0
- package/dist/api/app/bsky/actor/getProfile.d.ts.map +1 -1
- package/dist/api/app/bsky/actor/getProfile.js +1 -0
- package/dist/api/app/bsky/actor/getProfile.js.map +1 -1
- package/dist/api/app/bsky/actor/getProfiles.d.ts.map +1 -1
- package/dist/api/app/bsky/actor/getProfiles.js +1 -0
- package/dist/api/app/bsky/actor/getProfiles.js.map +1 -1
- package/dist/api/app/bsky/actor/getSuggestions.d.ts.map +1 -1
- package/dist/api/app/bsky/actor/getSuggestions.js +1 -0
- package/dist/api/app/bsky/actor/getSuggestions.js.map +1 -1
- package/dist/api/app/bsky/actor/searchActors.d.ts.map +1 -1
- package/dist/api/app/bsky/actor/searchActors.js +1 -0
- package/dist/api/app/bsky/actor/searchActors.js.map +1 -1
- package/dist/api/app/bsky/actor/searchActorsTypeahead.d.ts.map +1 -1
- package/dist/api/app/bsky/actor/searchActorsTypeahead.js +1 -0
- package/dist/api/app/bsky/actor/searchActorsTypeahead.js.map +1 -1
- package/dist/api/app/bsky/bookmark/getBookmarks.d.ts.map +1 -1
- package/dist/api/app/bsky/bookmark/getBookmarks.js +1 -0
- package/dist/api/app/bsky/bookmark/getBookmarks.js.map +1 -1
- package/dist/api/app/bsky/contact/getMatches.d.ts.map +1 -1
- package/dist/api/app/bsky/contact/getMatches.js +1 -0
- package/dist/api/app/bsky/contact/getMatches.js.map +1 -1
- package/dist/api/app/bsky/contact/importContacts.d.ts.map +1 -1
- package/dist/api/app/bsky/contact/importContacts.js +1 -0
- package/dist/api/app/bsky/contact/importContacts.js.map +1 -1
- package/dist/api/app/bsky/feed/getActorFeeds.d.ts.map +1 -1
- package/dist/api/app/bsky/feed/getActorFeeds.js +5 -1
- package/dist/api/app/bsky/feed/getActorFeeds.js.map +1 -1
- package/dist/api/app/bsky/feed/getActorLikes.d.ts.map +1 -1
- package/dist/api/app/bsky/feed/getActorLikes.js +1 -0
- package/dist/api/app/bsky/feed/getActorLikes.js.map +1 -1
- package/dist/api/app/bsky/feed/getAuthorFeed.d.ts.map +1 -1
- package/dist/api/app/bsky/feed/getAuthorFeed.js +1 -0
- package/dist/api/app/bsky/feed/getAuthorFeed.js.map +1 -1
- package/dist/api/app/bsky/feed/getFeed.d.ts.map +1 -1
- package/dist/api/app/bsky/feed/getFeed.js +1 -0
- package/dist/api/app/bsky/feed/getFeed.js.map +1 -1
- package/dist/api/app/bsky/feed/getFeedGenerator.d.ts.map +1 -1
- package/dist/api/app/bsky/feed/getFeedGenerator.js +5 -1
- package/dist/api/app/bsky/feed/getFeedGenerator.js.map +1 -1
- package/dist/api/app/bsky/feed/getFeedGenerators.d.ts.map +1 -1
- package/dist/api/app/bsky/feed/getFeedGenerators.js +5 -1
- package/dist/api/app/bsky/feed/getFeedGenerators.js.map +1 -1
- package/dist/api/app/bsky/feed/getLikes.d.ts.map +1 -1
- package/dist/api/app/bsky/feed/getLikes.js +1 -0
- package/dist/api/app/bsky/feed/getLikes.js.map +1 -1
- package/dist/api/app/bsky/feed/getListFeed.d.ts.map +1 -1
- package/dist/api/app/bsky/feed/getListFeed.js +1 -0
- package/dist/api/app/bsky/feed/getListFeed.js.map +1 -1
- package/dist/api/app/bsky/feed/getPostThread.d.ts.map +1 -1
- package/dist/api/app/bsky/feed/getPostThread.js +1 -0
- package/dist/api/app/bsky/feed/getPostThread.js.map +1 -1
- package/dist/api/app/bsky/feed/getPosts.d.ts.map +1 -1
- package/dist/api/app/bsky/feed/getPosts.js +5 -1
- package/dist/api/app/bsky/feed/getPosts.js.map +1 -1
- package/dist/api/app/bsky/feed/getQuotes.d.ts.map +1 -1
- package/dist/api/app/bsky/feed/getQuotes.js +1 -0
- package/dist/api/app/bsky/feed/getQuotes.js.map +1 -1
- package/dist/api/app/bsky/feed/getRepostedBy.d.ts.map +1 -1
- package/dist/api/app/bsky/feed/getRepostedBy.js +1 -0
- package/dist/api/app/bsky/feed/getRepostedBy.js.map +1 -1
- package/dist/api/app/bsky/feed/getSuggestedFeeds.d.ts.map +1 -1
- package/dist/api/app/bsky/feed/getSuggestedFeeds.js +5 -1
- package/dist/api/app/bsky/feed/getSuggestedFeeds.js.map +1 -1
- package/dist/api/app/bsky/feed/getTimeline.d.ts.map +1 -1
- package/dist/api/app/bsky/feed/getTimeline.js +1 -0
- package/dist/api/app/bsky/feed/getTimeline.js.map +1 -1
- package/dist/api/app/bsky/feed/searchPosts.d.ts.map +1 -1
- package/dist/api/app/bsky/feed/searchPosts.js +1 -0
- package/dist/api/app/bsky/feed/searchPosts.js.map +1 -1
- package/dist/api/app/bsky/feed/searchPostsV2.d.ts.map +1 -1
- package/dist/api/app/bsky/feed/searchPostsV2.js +1 -0
- package/dist/api/app/bsky/feed/searchPostsV2.js.map +1 -1
- package/dist/api/app/bsky/graph/getActorStarterPacks.d.ts.map +1 -1
- package/dist/api/app/bsky/graph/getActorStarterPacks.js +1 -0
- package/dist/api/app/bsky/graph/getActorStarterPacks.js.map +1 -1
- package/dist/api/app/bsky/graph/getBlocks.d.ts.map +1 -1
- package/dist/api/app/bsky/graph/getBlocks.js +5 -1
- package/dist/api/app/bsky/graph/getBlocks.js.map +1 -1
- package/dist/api/app/bsky/graph/getFollowers.d.ts.map +1 -1
- package/dist/api/app/bsky/graph/getFollowers.js +1 -0
- package/dist/api/app/bsky/graph/getFollowers.js.map +1 -1
- package/dist/api/app/bsky/graph/getFollows.d.ts.map +1 -1
- package/dist/api/app/bsky/graph/getFollows.js +1 -0
- package/dist/api/app/bsky/graph/getFollows.js.map +1 -1
- package/dist/api/app/bsky/graph/getKnownFollowers.d.ts.map +1 -1
- package/dist/api/app/bsky/graph/getKnownFollowers.js +1 -0
- package/dist/api/app/bsky/graph/getKnownFollowers.js.map +1 -1
- package/dist/api/app/bsky/graph/getList.d.ts.map +1 -1
- package/dist/api/app/bsky/graph/getList.js +1 -0
- package/dist/api/app/bsky/graph/getList.js.map +1 -1
- package/dist/api/app/bsky/graph/getListBlocks.d.ts.map +1 -1
- package/dist/api/app/bsky/graph/getListBlocks.js +5 -1
- package/dist/api/app/bsky/graph/getListBlocks.js.map +1 -1
- package/dist/api/app/bsky/graph/getListMutes.d.ts.map +1 -1
- package/dist/api/app/bsky/graph/getListMutes.js +5 -1
- package/dist/api/app/bsky/graph/getListMutes.js.map +1 -1
- package/dist/api/app/bsky/graph/getLists.d.ts.map +1 -1
- package/dist/api/app/bsky/graph/getLists.js +1 -0
- package/dist/api/app/bsky/graph/getLists.js.map +1 -1
- package/dist/api/app/bsky/graph/getListsWithMembership.d.ts.map +1 -1
- package/dist/api/app/bsky/graph/getListsWithMembership.js +1 -0
- package/dist/api/app/bsky/graph/getListsWithMembership.js.map +1 -1
- package/dist/api/app/bsky/graph/getMutes.d.ts.map +1 -1
- package/dist/api/app/bsky/graph/getMutes.js +5 -1
- package/dist/api/app/bsky/graph/getMutes.js.map +1 -1
- package/dist/api/app/bsky/graph/getStarterPack.d.ts.map +1 -1
- package/dist/api/app/bsky/graph/getStarterPack.js +1 -0
- package/dist/api/app/bsky/graph/getStarterPack.js.map +1 -1
- package/dist/api/app/bsky/graph/getStarterPacks.d.ts.map +1 -1
- package/dist/api/app/bsky/graph/getStarterPacks.js +1 -0
- package/dist/api/app/bsky/graph/getStarterPacks.js.map +1 -1
- package/dist/api/app/bsky/graph/getStarterPacksWithMembership.d.ts.map +1 -1
- package/dist/api/app/bsky/graph/getStarterPacksWithMembership.js +1 -0
- package/dist/api/app/bsky/graph/getStarterPacksWithMembership.js.map +1 -1
- package/dist/api/app/bsky/graph/getSuggestedFollowsByActor.d.ts.map +1 -1
- package/dist/api/app/bsky/graph/getSuggestedFollowsByActor.js +1 -0
- package/dist/api/app/bsky/graph/getSuggestedFollowsByActor.js.map +1 -1
- package/dist/api/app/bsky/graph/searchStarterPacks.d.ts.map +1 -1
- package/dist/api/app/bsky/graph/searchStarterPacks.js +1 -0
- package/dist/api/app/bsky/graph/searchStarterPacks.js.map +1 -1
- package/dist/api/app/bsky/graph/searchStarterPacksV2.d.ts.map +1 -1
- package/dist/api/app/bsky/graph/searchStarterPacksV2.js +1 -0
- package/dist/api/app/bsky/graph/searchStarterPacksV2.js.map +1 -1
- package/dist/api/app/bsky/labeler/getServices.d.ts.map +1 -1
- package/dist/api/app/bsky/labeler/getServices.js +1 -0
- package/dist/api/app/bsky/labeler/getServices.js.map +1 -1
- package/dist/api/app/bsky/notification/getGroupedNotifications.d.ts.map +1 -1
- package/dist/api/app/bsky/notification/getGroupedNotifications.js +41 -20
- package/dist/api/app/bsky/notification/getGroupedNotifications.js.map +1 -1
- package/dist/api/app/bsky/notification/grouping/algoGravity.d.ts +4 -3
- package/dist/api/app/bsky/notification/grouping/algoGravity.d.ts.map +1 -1
- package/dist/api/app/bsky/notification/grouping/algoGravity.js +53 -42
- package/dist/api/app/bsky/notification/grouping/algoGravity.js.map +1 -1
- package/dist/api/app/bsky/notification/grouping/algoLookback.d.ts +4 -3
- package/dist/api/app/bsky/notification/grouping/algoLookback.d.ts.map +1 -1
- package/dist/api/app/bsky/notification/grouping/algoLookback.js +56 -42
- package/dist/api/app/bsky/notification/grouping/algoLookback.js.map +1 -1
- package/dist/api/app/bsky/notification/grouping/grouping.d.ts +12 -2
- package/dist/api/app/bsky/notification/grouping/grouping.d.ts.map +1 -1
- package/dist/api/app/bsky/notification/grouping/grouping.js +20 -6
- package/dist/api/app/bsky/notification/grouping/grouping.js.map +1 -1
- package/dist/api/app/bsky/notification/grouping/spotlight.d.ts +2 -2
- package/dist/api/app/bsky/notification/grouping/spotlight.d.ts.map +1 -1
- package/dist/api/app/bsky/notification/grouping/spotlight.js +35 -22
- package/dist/api/app/bsky/notification/grouping/spotlight.js.map +1 -1
- package/dist/api/app/bsky/notification/listActivitySubscriptions.d.ts.map +1 -1
- package/dist/api/app/bsky/notification/listActivitySubscriptions.js +1 -0
- package/dist/api/app/bsky/notification/listActivitySubscriptions.js.map +1 -1
- package/dist/api/app/bsky/notification/listNotifications.d.ts.map +1 -1
- package/dist/api/app/bsky/notification/listNotifications.js +5 -1
- package/dist/api/app/bsky/notification/listNotifications.js.map +1 -1
- package/dist/api/app/bsky/unspecced/atmosphere-grouping.d.ts +16 -0
- package/dist/api/app/bsky/unspecced/atmosphere-grouping.d.ts.map +1 -0
- package/dist/api/app/bsky/unspecced/atmosphere-grouping.js +124 -0
- package/dist/api/app/bsky/unspecced/atmosphere-grouping.js.map +1 -0
- package/dist/api/app/bsky/unspecced/atmosphere-hydration.d.ts +32 -0
- package/dist/api/app/bsky/unspecced/atmosphere-hydration.d.ts.map +1 -0
- package/dist/api/app/bsky/unspecced/atmosphere-hydration.js +201 -0
- package/dist/api/app/bsky/unspecced/atmosphere-hydration.js.map +1 -0
- package/dist/api/app/bsky/unspecced/atmosphere-pagination.d.ts +6 -0
- package/dist/api/app/bsky/unspecced/atmosphere-pagination.d.ts.map +1 -0
- package/dist/api/app/bsky/unspecced/atmosphere-pagination.js +164 -0
- package/dist/api/app/bsky/unspecced/atmosphere-pagination.js.map +1 -0
- package/dist/api/app/bsky/unspecced/getAtmosphereExploreTab.d.ts.map +1 -1
- package/dist/api/app/bsky/unspecced/getAtmosphereExploreTab.js +120 -55
- package/dist/api/app/bsky/unspecced/getAtmosphereExploreTab.js.map +1 -1
- package/dist/api/app/bsky/unspecced/getAtmosphereTimeline.d.ts +4 -0
- package/dist/api/app/bsky/unspecced/getAtmosphereTimeline.d.ts.map +1 -0
- package/dist/api/app/bsky/unspecced/getAtmosphereTimeline.js +30 -0
- package/dist/api/app/bsky/unspecced/getAtmosphereTimeline.js.map +1 -0
- package/dist/api/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.d.ts.map +1 -1
- package/dist/api/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.js +4 -7
- package/dist/api/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.js.map +1 -1
- package/dist/api/app/bsky/unspecced/getPopularFeedGenerators.d.ts.map +1 -1
- package/dist/api/app/bsky/unspecced/getPopularFeedGenerators.js +1 -0
- package/dist/api/app/bsky/unspecced/getPopularFeedGenerators.js.map +1 -1
- package/dist/api/app/bsky/unspecced/getPostThreadOtherV2.d.ts.map +1 -1
- package/dist/api/app/bsky/unspecced/getPostThreadOtherV2.js +1 -0
- package/dist/api/app/bsky/unspecced/getPostThreadOtherV2.js.map +1 -1
- package/dist/api/app/bsky/unspecced/getPostThreadV2.d.ts.map +1 -1
- package/dist/api/app/bsky/unspecced/getPostThreadV2.js +1 -0
- package/dist/api/app/bsky/unspecced/getPostThreadV2.js.map +1 -1
- package/dist/api/app/bsky/unspecced/getSuggestedFeeds.d.ts.map +1 -1
- package/dist/api/app/bsky/unspecced/getSuggestedFeeds.js +4 -7
- package/dist/api/app/bsky/unspecced/getSuggestedFeeds.js.map +1 -1
- package/dist/api/app/bsky/unspecced/getSuggestedOnboardingUsers.d.ts.map +1 -1
- package/dist/api/app/bsky/unspecced/getSuggestedOnboardingUsers.js +1 -0
- package/dist/api/app/bsky/unspecced/getSuggestedOnboardingUsers.js.map +1 -1
- package/dist/api/app/bsky/unspecced/getSuggestedStarterPacks.d.ts.map +1 -1
- package/dist/api/app/bsky/unspecced/getSuggestedStarterPacks.js +4 -7
- package/dist/api/app/bsky/unspecced/getSuggestedStarterPacks.js.map +1 -1
- package/dist/api/app/bsky/unspecced/getSuggestedUsers.d.ts.map +1 -1
- package/dist/api/app/bsky/unspecced/getSuggestedUsers.js +2 -19
- package/dist/api/app/bsky/unspecced/getSuggestedUsers.js.map +1 -1
- package/dist/api/app/bsky/unspecced/getSuggestedUsersForDiscover.d.ts.map +1 -1
- package/dist/api/app/bsky/unspecced/getSuggestedUsersForDiscover.js +1 -0
- package/dist/api/app/bsky/unspecced/getSuggestedUsersForDiscover.js.map +1 -1
- package/dist/api/app/bsky/unspecced/getSuggestedUsersForExplore.d.ts.map +1 -1
- package/dist/api/app/bsky/unspecced/getSuggestedUsersForExplore.js +1 -0
- package/dist/api/app/bsky/unspecced/getSuggestedUsersForExplore.js.map +1 -1
- package/dist/api/app/bsky/unspecced/getSuggestedUsersForSeeMore.d.ts.map +1 -1
- package/dist/api/app/bsky/unspecced/getSuggestedUsersForSeeMore.js +1 -0
- package/dist/api/app/bsky/unspecced/getSuggestedUsersForSeeMore.js.map +1 -1
- package/dist/api/app/bsky/unspecced/getTrendingTopics.d.ts.map +1 -1
- package/dist/api/app/bsky/unspecced/getTrendingTopics.js +6 -2
- package/dist/api/app/bsky/unspecced/getTrendingTopics.js.map +1 -1
- package/dist/api/app/bsky/unspecced/getTrends.d.ts.map +1 -1
- package/dist/api/app/bsky/unspecced/getTrends.js +6 -2
- package/dist/api/app/bsky/unspecced/getTrends.js.map +1 -1
- package/dist/api/blob-resolver.d.ts.map +1 -1
- package/dist/api/blob-resolver.js +9 -8
- package/dist/api/blob-resolver.js.map +1 -1
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +2 -0
- package/dist/api/index.js.map +1 -1
- package/dist/api/internal/bsky/actor/getProfiles.d.ts.map +1 -1
- package/dist/api/internal/bsky/actor/getProfiles.js +1 -0
- package/dist/api/internal/bsky/actor/getProfiles.js.map +1 -1
- package/dist/config.d.ts +2 -6
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +7 -16
- package/dist/config.js.map +1 -1
- package/dist/context.d.ts +0 -2
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +0 -3
- package/dist/context.js.map +1 -1
- package/dist/feature-gates/gates.d.ts +0 -4
- package/dist/feature-gates/gates.d.ts.map +1 -1
- package/dist/feature-gates/gates.js +0 -4
- package/dist/feature-gates/gates.js.map +1 -1
- package/dist/hydration/external.d.ts +58 -45
- package/dist/hydration/external.d.ts.map +1 -1
- package/dist/hydration/external.js +134 -114
- package/dist/hydration/external.js.map +1 -1
- package/dist/hydration/hydrator.d.ts +15 -9
- package/dist/hydration/hydrator.d.ts.map +1 -1
- package/dist/hydration/hydrator.js +170 -210
- package/dist/hydration/hydrator.js.map +1 -1
- package/dist/image/server.d.ts.map +1 -1
- package/dist/image/server.js +12 -1
- package/dist/image/server.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -19
- package/dist/index.js.map +1 -1
- package/dist/lexicons/app/bsky/unspecced/getAtmosphereExploreTab.defs.d.ts +29 -0
- package/dist/lexicons/app/bsky/unspecced/getAtmosphereExploreTab.defs.d.ts.map +1 -1
- package/dist/lexicons/app/bsky/unspecced/getAtmosphereExploreTab.defs.js +2 -1
- package/dist/lexicons/app/bsky/unspecced/getAtmosphereExploreTab.defs.js.map +1 -1
- package/dist/lexicons/app/bsky/unspecced/getAtmosphereTimeline.d.ts +3 -0
- package/dist/lexicons/app/bsky/unspecced/getAtmosphereTimeline.d.ts.map +1 -0
- package/dist/lexicons/app/bsky/unspecced/getAtmosphereTimeline.defs.d.ts +85 -0
- package/dist/lexicons/app/bsky/unspecced/getAtmosphereTimeline.defs.d.ts.map +1 -0
- package/dist/lexicons/app/bsky/unspecced/getAtmosphereTimeline.defs.js +29 -0
- package/dist/lexicons/app/bsky/unspecced/getAtmosphereTimeline.defs.js.map +1 -0
- package/dist/lexicons/app/bsky/unspecced/getAtmosphereTimeline.js +6 -0
- package/dist/lexicons/app/bsky/unspecced/getAtmosphereTimeline.js.map +1 -0
- package/dist/lexicons/app/bsky/unspecced.d.ts +1 -0
- package/dist/lexicons/app/bsky/unspecced.d.ts.map +1 -1
- package/dist/lexicons/app/bsky/unspecced.js +1 -0
- package/dist/lexicons/app/bsky/unspecced.js.map +1 -1
- package/dist/lexicons/tools/ozone/moderation/emitEvent.defs.d.ts +2 -2
- package/dist/lexicons/tools/ozone/moderation/emitEvent.defs.js.map +1 -1
- package/dist/lexicons/tools/ozone/report/closeReports.defs.d.ts +1 -1
- package/dist/lexicons/tools/ozone/report/closeReports.defs.d.ts.map +1 -1
- package/dist/lexicons/tools/ozone/report/closeReports.defs.js +1 -1
- package/dist/lexicons/tools/ozone/report/closeReports.defs.js.map +1 -1
- package/dist/telemetry/events.d.ts +14 -6
- package/dist/telemetry/events.d.ts.map +1 -1
- package/dist/telemetry/events.js +40 -5
- package/dist/telemetry/events.js.map +1 -1
- package/dist/util/external/standard-site.d.ts +2 -3
- package/dist/util/external/standard-site.d.ts.map +1 -1
- package/dist/util/external/standard-site.js +2 -3
- package/dist/util/external/standard-site.js.map +1 -1
- package/dist/util/uris.d.ts +5 -2
- package/dist/util/uris.d.ts.map +1 -1
- package/dist/util/uris.js +14 -1
- package/dist/util/uris.js.map +1 -1
- package/dist/views/external.d.ts +5 -0
- package/dist/views/external.d.ts.map +1 -1
- package/dist/views/external.js +38 -11
- package/dist/views/external.js.map +1 -1
- package/dist/views/index.d.ts +2 -2
- package/dist/views/index.d.ts.map +1 -1
- package/dist/views/index.js +17 -11
- package/dist/views/index.js.map +1 -1
- package/package.json +13 -14
|
@@ -6,12 +6,11 @@ import { NOTIFICATION_REASON } from '../api/app/bsky/notification/constants.js';
|
|
|
6
6
|
import { app, chat, com, place, site, social } from '../lexicons/index.js';
|
|
7
7
|
import { hydrationLogger } from '../logger.js';
|
|
8
8
|
import { events } from '../telemetry/events.js';
|
|
9
|
-
import {
|
|
10
|
-
import { uriToDid, uriToDid as didFromUri } from '../util/uris.js';
|
|
9
|
+
import { recordUriOf, uriToDid, uriToDid as didFromUri } from '../util/uris.js';
|
|
11
10
|
import { MAX_PROFILE_LINKS } from '../views/profile-link-rules.js';
|
|
12
|
-
import {
|
|
11
|
+
import { isListRuleType, isRecordEmbedType, isRecordWithMediaType, } from '../views/types.js';
|
|
13
12
|
import { ActorHydrator, } from './actor.js';
|
|
14
|
-
import { ExternalHydrator, actionExternalRecordTakedowns,
|
|
13
|
+
import { EXTERNAL_HYDRATION_LIMITS, ExternalHydrator, MAX_CONCURRENT_BACKLINK_REQUESTS, MAX_EXTERNAL_HYDRATION_PASSES, actionExternalRecordTakedowns, externalAssociatedRefsFromPosts, genericRecordKey, trackExternalHydration, } from './external.js';
|
|
15
14
|
import { FeedHydrator, } from './feed.js';
|
|
16
15
|
import { GraphHydrator, } from './graph.js';
|
|
17
16
|
import { LabelHydrator, Labels, } from './label.js';
|
|
@@ -424,13 +423,7 @@ export class Hydrator {
|
|
|
424
423
|
postUrisWithPostgates.add(uri);
|
|
425
424
|
}
|
|
426
425
|
}
|
|
427
|
-
const
|
|
428
|
-
const siteStandardLabelSubjects = dedupeStrs(siteStandardRefs.map((ref) => ref.uri));
|
|
429
|
-
// Site-standard record owners need profile basics so we can populate
|
|
430
|
-
// `associatedProfiles` on the external embed view. Include them in the
|
|
431
|
-
// post-author profile fetch below; any DIDs surfaced later by the
|
|
432
|
-
// dataplane are picked up by the top-up after the parallel batch.
|
|
433
|
-
const ssRefDids = siteStandardRefs.map((ref) => uriToDid(ref.uri));
|
|
426
|
+
const externalRefs = externalAssociatedRefsFromPosts(postsLayer0, postsLayer1, postsLayer2);
|
|
434
427
|
// Collect known-liker profiles and author-liker block relationships.
|
|
435
428
|
const knownLikers = await knownLikersPromise;
|
|
436
429
|
const knownLikerDids = [];
|
|
@@ -446,45 +439,34 @@ export class Hydrator {
|
|
|
446
439
|
});
|
|
447
440
|
const knownProfileDids = dedupeStrs([
|
|
448
441
|
...allPostUris.map(didFromUri),
|
|
449
|
-
...ssRefDids,
|
|
450
442
|
...knownLikerDids,
|
|
451
443
|
]);
|
|
452
|
-
const [postAggs, postViewers, labels, { postBlocks, additionalRelationshipsBidirectionalBlocks: authorsAndKnownLikersBidirectionalBlocks, }, profileState, listState, feedGenState, labelerState, starterPackState, postgates,
|
|
444
|
+
const [postAggs, postViewers, labels, { postBlocks, additionalRelationshipsBidirectionalBlocks: authorsAndKnownLikersBidirectionalBlocks, }, profileState, listState, feedGenState, labelerState, starterPackState, postgates, externalState,] = await Promise.all([
|
|
453
445
|
this.feed.getPostAggregates(allRefs, ctx.viewer),
|
|
454
446
|
ctx.viewer
|
|
455
447
|
? this.feed.getPostViewerStates(threadRefs, ctx.viewer)
|
|
456
448
|
: undefined,
|
|
457
|
-
this.label.getLabelsForSubjects(
|
|
458
|
-
this.hydratePostBlocks(posts, ctx, authorsAndKnownLikersRelationships
|
|
449
|
+
this.label.getLabelsForSubjects(allPostUris, ctx.labelers),
|
|
450
|
+
this.hydratePostBlocks(posts, ctx, authorsAndKnownLikersRelationships, {
|
|
451
|
+
skipReplyBlocks: options.skipReplyBlocks,
|
|
452
|
+
}),
|
|
459
453
|
this.hydrateProfiles(knownProfileDids, ctx),
|
|
460
454
|
this.hydrateLists([...nestedListUris, ...threadgateListUris], ctx),
|
|
461
455
|
this.hydrateFeedGens(nestedFeedGenUris, ctx),
|
|
462
456
|
this.hydrateLabelers(nestedLabelerDids, ctx),
|
|
463
457
|
this.hydrateStarterPacksBasic(nestedStarterPackUris, ctx),
|
|
464
458
|
this.feed.getPostgatesForPosts([...postUrisWithPostgates.values()]),
|
|
465
|
-
this.
|
|
459
|
+
this.hydrateEmbedExternalViewFromRefs(externalRefs, ctx, {
|
|
460
|
+
hydration: 'basic',
|
|
461
|
+
seenRecordKeys: options.externalSeenRecordKeys,
|
|
462
|
+
publicationSubscriptions: options.externalPublicationSubscriptions,
|
|
463
|
+
}),
|
|
466
464
|
]);
|
|
467
465
|
if (!ctx.includeTakedowns) {
|
|
468
466
|
actionTakedownLabels(allPostUris, posts, labels);
|
|
469
|
-
actionSiteStandardTakedownLabels(siteStandardDocuments, siteStandardPublications, labels);
|
|
470
|
-
}
|
|
471
|
-
// Defensive top-up: in the unlikely case the dataplane returned a
|
|
472
|
-
// publication owned by a DID not present in the post-author or
|
|
473
|
-
// pinned-ref sets, fetch its profile serially and fold it in.
|
|
474
|
-
const knownProfileDidsSet = new Set(knownProfileDids);
|
|
475
|
-
const extraSsDids = [];
|
|
476
|
-
for (const key of siteStandardPublications.keys()) {
|
|
477
|
-
const did = uriToDid(parseGenericRecordKey(key).uri);
|
|
478
|
-
if (!knownProfileDidsSet.has(did)) {
|
|
479
|
-
knownProfileDidsSet.add(did);
|
|
480
|
-
extraSsDids.push(did);
|
|
481
|
-
}
|
|
482
467
|
}
|
|
483
|
-
const mergedProfileState = extraSsDids.length
|
|
484
|
-
? mergeStates(profileState, await this.hydrateProfilesBasic(extraSsDids, ctx))
|
|
485
|
-
: profileState;
|
|
486
468
|
// combine all hydration state
|
|
487
|
-
return mergeManyStates(
|
|
469
|
+
return mergeManyStates(externalState, profileState, listState, feedGenState, labelerState, starterPackState, {
|
|
488
470
|
posts,
|
|
489
471
|
postAggs,
|
|
490
472
|
postViewers,
|
|
@@ -494,12 +476,10 @@ export class Hydrator {
|
|
|
494
476
|
labels,
|
|
495
477
|
threadgates,
|
|
496
478
|
postgates,
|
|
497
|
-
siteStandardDocuments,
|
|
498
|
-
siteStandardPublications,
|
|
499
479
|
ctx,
|
|
500
480
|
});
|
|
501
481
|
}
|
|
502
|
-
async hydratePostBlocks(posts, ctx, additionalRelationships = []) {
|
|
482
|
+
async hydratePostBlocks(posts, ctx, additionalRelationships = [], opts) {
|
|
503
483
|
const postBlocks = new HydrationMap();
|
|
504
484
|
const postBlocksPairs = new Map();
|
|
505
485
|
const relationships = [];
|
|
@@ -510,20 +490,21 @@ export class Hydrator {
|
|
|
510
490
|
const creator = didFromUri(uri);
|
|
511
491
|
const postBlockPairs = {};
|
|
512
492
|
postBlocksPairs.set(uri, postBlockPairs);
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
493
|
+
if (!opts?.skipReplyBlocks) {
|
|
494
|
+
const parentUri = post.reply?.parent.uri;
|
|
495
|
+
const parentDid = parentUri && didFromUri(parentUri);
|
|
496
|
+
if (parentDid && parentDid !== creator) {
|
|
497
|
+
const pair = [creator, parentDid];
|
|
498
|
+
relationships.push(pair);
|
|
499
|
+
postBlockPairs.parent = pair;
|
|
500
|
+
}
|
|
501
|
+
const rootUri = post.reply?.root.uri;
|
|
502
|
+
const rootDid = rootUri && didFromUri(rootUri);
|
|
503
|
+
if (rootDid && rootDid !== creator) {
|
|
504
|
+
const pair = [creator, rootDid];
|
|
505
|
+
relationships.push(pair);
|
|
506
|
+
postBlockPairs.root = pair;
|
|
507
|
+
}
|
|
527
508
|
}
|
|
528
509
|
// 3p block for record embeds
|
|
529
510
|
for (const embedUri of nestedRecordUris(post)) {
|
|
@@ -626,27 +607,33 @@ export class Hydrator {
|
|
|
626
607
|
* generic batch within the traversal (the root batch is pass 1); nested
|
|
627
608
|
* batches continue the count. Nested passes share the caller's
|
|
628
609
|
* `hydrationMetrics` tracker; without one, this call owns the traversal and
|
|
629
|
-
* reports its totals.
|
|
610
|
+
* reports its totals. `options.hydration` (default `'detailed'`) applies to
|
|
611
|
+
* the whole traversal and is propagated to every nested pass.
|
|
630
612
|
*/
|
|
631
|
-
async hydrateEmbedExternalViewFromUris(uris, ctx,
|
|
632
|
-
|
|
613
|
+
async hydrateEmbedExternalViewFromUris(uris, ctx, options = {}) {
|
|
614
|
+
const { hydration = 'detailed', seenRecordKeys = new Set(), hydrationPass = 1, hydrationMetrics, publicationSubscriptions, } = options;
|
|
615
|
+
return trackExternalHydration('uris', ctx.xrpcEndpoint, hydrationMetrics, (hydrationMetrics) => this.hydrateEmbedExternalView(uris.map(uriToRef), ctx, hydration, seenRecordKeys, hydrationPass, hydrationMetrics, publicationSubscriptions));
|
|
633
616
|
}
|
|
634
617
|
/**
|
|
635
618
|
* Like `hydrateEmbedExternalViewFromUris`, but for exact record versions
|
|
636
619
|
* pinned by strong refs. Roots land only in `externalRecordsByRef`; their
|
|
637
620
|
* URI dependencies are hydrated as latest versions by the URI path.
|
|
638
621
|
*/
|
|
639
|
-
async hydrateEmbedExternalViewFromRefs(refs, ctx,
|
|
640
|
-
|
|
622
|
+
async hydrateEmbedExternalViewFromRefs(refs, ctx, options = {}) {
|
|
623
|
+
const { hydration = 'detailed', seenRecordKeys = new Set(), hydrationPass = 1, hydrationMetrics, publicationSubscriptions, } = options;
|
|
624
|
+
return trackExternalHydration('refs', ctx.xrpcEndpoint, hydrationMetrics, (hydrationMetrics) => this.hydrateEmbedExternalView(refs, ctx, hydration, seenRecordKeys, hydrationPass, hydrationMetrics, publicationSubscriptions));
|
|
641
625
|
}
|
|
642
|
-
async hydrateEmbedExternalView(refs, ctx, seenRecordKeys, hydrationPass, hydrationMetrics) {
|
|
626
|
+
async hydrateEmbedExternalView(refs, ctx, hydration, seenRecordKeys, hydrationPass, hydrationMetrics, publicationSubscriptions) {
|
|
643
627
|
// Filter at the entry point so each lookup runs at most once per shared
|
|
644
628
|
// traversal, even for callers that did not prefilter their input. Null or
|
|
645
629
|
// unavailable results stay seen as completed lookups. Nothing unseen means
|
|
646
630
|
// no hydration work, and no pass is consumed.
|
|
647
631
|
const items = takeUnseenRefs(refs, seenRecordKeys);
|
|
648
|
-
if (!items.length)
|
|
649
|
-
return
|
|
632
|
+
if (!items.length) {
|
|
633
|
+
return publicationSubscriptions
|
|
634
|
+
? { ctx, externalPublicationSubscriptions: publicationSubscriptions }
|
|
635
|
+
: { ctx };
|
|
636
|
+
}
|
|
650
637
|
// Get any bare URIs to fetch
|
|
651
638
|
const byUriValues = items
|
|
652
639
|
.filter(({ cid }) => cid === undefined)
|
|
@@ -696,10 +683,17 @@ export class Hydrator {
|
|
|
696
683
|
labels,
|
|
697
684
|
externalRecords,
|
|
698
685
|
externalRecordsByRef,
|
|
686
|
+
externalPublicationSubscriptions: publicationSubscriptions,
|
|
699
687
|
});
|
|
700
688
|
actionExternalRecordTakedowns(baseState, ctx.includeTakedowns);
|
|
701
689
|
// Discover and hydrate any additional view dependencies
|
|
702
|
-
const depsState = await this.hydrateExternalViewDependencies(baseState, items, ctx,
|
|
690
|
+
const depsState = await this.hydrateExternalViewDependencies(baseState, items, ctx, {
|
|
691
|
+
hydration,
|
|
692
|
+
seenRecordKeys,
|
|
693
|
+
hydrationPass,
|
|
694
|
+
hydrationMetrics,
|
|
695
|
+
publicationSubscriptions,
|
|
696
|
+
});
|
|
703
697
|
// A supplemental latest lookup returning the same URI and CID is the same
|
|
704
698
|
// version, so it may replace an unavailable exact entry; other CIDs have
|
|
705
699
|
// other keys and never satisfy a pin.
|
|
@@ -718,15 +712,21 @@ export class Hydrator {
|
|
|
718
712
|
* `hydrationPass` is the number of the generic batch that produced `state`
|
|
719
713
|
* (1-based, default 1 for prehydrated state, which is treated as the root
|
|
720
714
|
* batch); the next nested batch is `hydrationPass + 1`. `hydrationMetrics`
|
|
721
|
-
* is shared as in `hydrateEmbedExternalViewFromUris`.
|
|
715
|
+
* is shared as in `hydrateEmbedExternalViewFromUris`. `options.hydration`
|
|
716
|
+
* (default `'detailed'`) decides, per collection, whether social-preview
|
|
717
|
+
* samples are scheduled; backlink counts and content dependencies are
|
|
718
|
+
* discovered at both levels.
|
|
722
719
|
*/
|
|
723
|
-
async hydrateExternalViewDependencies(state, refs, ctx,
|
|
724
|
-
|
|
720
|
+
async hydrateExternalViewDependencies(state, refs, ctx, options = {}) {
|
|
721
|
+
const { hydration = 'detailed', seenRecordKeys = new Set(), hydrationPass = 1, hydrationMetrics, publicationSubscriptions, } = options;
|
|
722
|
+
return trackExternalHydration('dependencies', ctx.xrpcEndpoint, hydrationMetrics, (hydrationMetrics) => this.discoverExternalViewDependencies(state, refs, ctx, hydration, seenRecordKeys, hydrationPass, hydrationMetrics, publicationSubscriptions));
|
|
725
723
|
}
|
|
726
|
-
async discoverExternalViewDependencies(state, refs, ctx, seenRecordKeys, hydrationPass, hydrationMetrics) {
|
|
727
|
-
//
|
|
724
|
+
async discoverExternalViewDependencies(state, refs, ctx, hydration, seenRecordKeys, hydrationPass, hydrationMetrics, publicationSubscriptions) {
|
|
725
|
+
// Social-preview backlink sources to sample per target, each with its own
|
|
726
|
+
// bound. A target with no samples still gets its aggregate count.
|
|
728
727
|
const targets = new Map();
|
|
729
728
|
const discoveredUris = new Set();
|
|
729
|
+
const publicationUris = new Set();
|
|
730
730
|
const rootBatch = !hydrationMetrics.rootsCounted;
|
|
731
731
|
hydrationMetrics.rootsCounted = true;
|
|
732
732
|
for (const ref of refs) {
|
|
@@ -756,7 +756,8 @@ export class Hydrator {
|
|
|
756
756
|
if (!parsed.success ||
|
|
757
757
|
!isDidString(parsed.value.authority) ||
|
|
758
758
|
!parsed.value.rkey ||
|
|
759
|
-
parsed.value.
|
|
759
|
+
parsed.value.query !== undefined ||
|
|
760
|
+
parsed.value.hash !== undefined) {
|
|
760
761
|
continue;
|
|
761
762
|
}
|
|
762
763
|
/*
|
|
@@ -765,24 +766,33 @@ export class Hydrator {
|
|
|
765
766
|
const { collection } = parsed.value;
|
|
766
767
|
if (collection === site.standard.document.$type &&
|
|
767
768
|
site.standard.document.$matches(record, { strict: false })) {
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
769
|
+
const limits = EXTERNAL_HYDRATION_LIMITS[site.standard.document.$type];
|
|
770
|
+
targets.set(uri, hydration === 'detailed'
|
|
771
|
+
? [
|
|
772
|
+
{
|
|
773
|
+
collection: site.standard.graph.recommend.$type,
|
|
774
|
+
limit: limits.recommendationPreviews,
|
|
775
|
+
},
|
|
776
|
+
]
|
|
777
|
+
: []);
|
|
774
778
|
const publicationUri = recordUriOf(record.site, site.standard.publication.$type);
|
|
775
|
-
if (publicationUri)
|
|
779
|
+
if (publicationUri) {
|
|
776
780
|
discoveredUris.add(publicationUri);
|
|
781
|
+
publicationUris.add(publicationUri);
|
|
782
|
+
}
|
|
777
783
|
}
|
|
778
784
|
else if (collection === site.standard.publication.$type &&
|
|
779
785
|
site.standard.publication.$matches(record, { strict: false })) {
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
+
publicationUris.add(uri);
|
|
787
|
+
const limits = EXTERNAL_HYDRATION_LIMITS[site.standard.publication.$type];
|
|
788
|
+
targets.set(uri, hydration === 'detailed'
|
|
789
|
+
? [
|
|
790
|
+
{
|
|
791
|
+
collection: site.standard.graph.subscription.$type,
|
|
792
|
+
limit: limits.subscriberPreviews,
|
|
793
|
+
},
|
|
794
|
+
]
|
|
795
|
+
: []);
|
|
786
796
|
}
|
|
787
797
|
else if (collection === place.stream.livestream.$type &&
|
|
788
798
|
place.stream.livestream.$matches(record, { strict: false })) {
|
|
@@ -790,16 +800,20 @@ export class Hydrator {
|
|
|
790
800
|
}
|
|
791
801
|
else if (collection === social.grain.gallery.$type &&
|
|
792
802
|
social.grain.gallery.$matches(record, { strict: false })) {
|
|
793
|
-
|
|
794
|
-
|
|
803
|
+
const limits = EXTERNAL_HYDRATION_LIMITS[social.grain.gallery.$type];
|
|
804
|
+
// Membership items are content, sampled at every level.
|
|
805
|
+
const samples = [];
|
|
806
|
+
if (hydration === 'detailed') {
|
|
807
|
+
samples.push({
|
|
795
808
|
collection: social.grain.favorite.$type,
|
|
796
|
-
limit:
|
|
797
|
-
}
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
809
|
+
limit: limits.favoritePreviews,
|
|
810
|
+
});
|
|
811
|
+
}
|
|
812
|
+
samples.push({
|
|
813
|
+
collection: social.grain.gallery.item.$type,
|
|
814
|
+
limit: limits.items,
|
|
815
|
+
});
|
|
816
|
+
targets.set(uri, samples);
|
|
803
817
|
}
|
|
804
818
|
else if (collection === social.grain.gallery.item.$type &&
|
|
805
819
|
social.grain.gallery.item.$matches(record, { strict: false })) {
|
|
@@ -808,6 +822,52 @@ export class Hydrator {
|
|
|
808
822
|
if (photoUri)
|
|
809
823
|
discoveredUris.add(photoUri);
|
|
810
824
|
}
|
|
825
|
+
else if (
|
|
826
|
+
// @NOTE Preview actions must not refetch pinned targets as latest.
|
|
827
|
+
rootBatch &&
|
|
828
|
+
collection === site.standard.graph.recommend.$type &&
|
|
829
|
+
site.standard.graph.recommend.$matches(record, { strict: false })) {
|
|
830
|
+
const documentUri = recordUriOf(record.document, site.standard.document.$type);
|
|
831
|
+
if (documentUri)
|
|
832
|
+
discoveredUris.add(documentUri);
|
|
833
|
+
}
|
|
834
|
+
else if (rootBatch &&
|
|
835
|
+
collection === site.standard.graph.subscription.$type &&
|
|
836
|
+
site.standard.graph.subscription.$matches(record, { strict: false })) {
|
|
837
|
+
const publicationUri = recordUriOf(record.publication, site.standard.publication.$type);
|
|
838
|
+
if (publicationUri)
|
|
839
|
+
discoveredUris.add(publicationUri);
|
|
840
|
+
}
|
|
841
|
+
else if (rootBatch &&
|
|
842
|
+
collection === social.grain.favorite.$type &&
|
|
843
|
+
social.grain.favorite.$matches(record, { strict: false })) {
|
|
844
|
+
const galleryUri = recordUriOf(record.subject, social.grain.gallery.$type);
|
|
845
|
+
if (galleryUri)
|
|
846
|
+
discoveredUris.add(galleryUri);
|
|
847
|
+
}
|
|
848
|
+
}
|
|
849
|
+
if (publicationSubscriptions && ctx.viewer) {
|
|
850
|
+
const publications = [...publicationUris].filter((uri) => !publicationSubscriptions.has(uri));
|
|
851
|
+
// @NOTE Reserve even unknown outcomes before awaiting, so concurrent roots
|
|
852
|
+
// sharing this request's cache never repeat a subscription lookup.
|
|
853
|
+
for (const uri of publications)
|
|
854
|
+
publicationSubscriptions.set(uri, null);
|
|
855
|
+
for (const batch of chunkArray(publications, ExternalHydrator.MAX_BACKLINK_ACTOR_TARGETS_PER_REQUEST)) {
|
|
856
|
+
try {
|
|
857
|
+
const result = await this.external.getAtmosphereBacklinksByActor(batch, ctx.viewer, site.standard.graph.subscription.$type);
|
|
858
|
+
for (const publication of batch) {
|
|
859
|
+
const subscribed = result.backlinks
|
|
860
|
+
.get(publication)
|
|
861
|
+
?.some((uri) => recordUriOf(uri, site.standard.graph.subscription.$type) &&
|
|
862
|
+
uriToDid(uri) === ctx.viewer);
|
|
863
|
+
publicationSubscriptions.set(publication, subscribed ? true : result.truncated ? null : false);
|
|
864
|
+
}
|
|
865
|
+
}
|
|
866
|
+
catch (err) {
|
|
867
|
+
hydrationMetrics.partial = true;
|
|
868
|
+
hydrationLogger.warn({ err }, 'failed to hydrate external publication subscriptions');
|
|
869
|
+
}
|
|
870
|
+
}
|
|
811
871
|
}
|
|
812
872
|
let externalRecordBacklinks;
|
|
813
873
|
let externalRecordBacklinkCounts;
|
|
@@ -826,7 +886,7 @@ export class Hydrator {
|
|
|
826
886
|
}),
|
|
827
887
|
(async () => {
|
|
828
888
|
// @NOTE Bound fan-out as well as each sample; counts are independent.
|
|
829
|
-
for (const batch of chunkArray(queries,
|
|
889
|
+
for (const batch of chunkArray(queries, MAX_CONCURRENT_BACKLINK_REQUESTS)) {
|
|
830
890
|
await Promise.all(batch.map(async ({ uri, collection, limit }) => {
|
|
831
891
|
let page;
|
|
832
892
|
try {
|
|
@@ -838,9 +898,11 @@ export class Hydrator {
|
|
|
838
898
|
return;
|
|
839
899
|
}
|
|
840
900
|
const links = page.backlinks
|
|
841
|
-
.
|
|
842
|
-
|
|
843
|
-
|
|
901
|
+
.flatMap(({ uri }) => {
|
|
902
|
+
const link = recordUriOf(uri, collection);
|
|
903
|
+
return link ? [link] : [];
|
|
904
|
+
})
|
|
905
|
+
.slice(0, limit);
|
|
844
906
|
backlinks.set(uri, dedupeStrs([...(backlinks.get(uri) ?? []), ...links]));
|
|
845
907
|
links.forEach((link) => discoveredUris.add(link));
|
|
846
908
|
}));
|
|
@@ -852,20 +914,25 @@ export class Hydrator {
|
|
|
852
914
|
}
|
|
853
915
|
const newUris = [...discoveredUris].filter((uri) => !seenRecordKeys.has(genericRecordKey({ uri })));
|
|
854
916
|
let nested = {};
|
|
855
|
-
if (newUris.length &&
|
|
856
|
-
hydrationPass >= ExternalHydrator.MAX_EXTERNAL_HYDRATION_PASSES) {
|
|
917
|
+
if (newUris.length && hydrationPass >= MAX_EXTERNAL_HYDRATION_PASSES) {
|
|
857
918
|
// Keep the partial state. Skipped URIs are not marked seen: they were
|
|
858
919
|
// never fetched.
|
|
859
920
|
hydrationMetrics.capped = true;
|
|
860
921
|
hydrationLogger.warn({
|
|
861
922
|
hydrationPass,
|
|
862
|
-
maxPasses:
|
|
923
|
+
maxPasses: MAX_EXTERNAL_HYDRATION_PASSES,
|
|
863
924
|
skipped: newUris.length,
|
|
864
925
|
}, 'external hydration pass limit reached, skipping dependencies');
|
|
865
926
|
}
|
|
866
927
|
else if (newUris.length) {
|
|
867
928
|
try {
|
|
868
|
-
nested = await this.hydrateEmbedExternalViewFromUris(newUris, ctx,
|
|
929
|
+
nested = await this.hydrateEmbedExternalViewFromUris(newUris, ctx, {
|
|
930
|
+
hydration,
|
|
931
|
+
seenRecordKeys,
|
|
932
|
+
hydrationPass: hydrationPass + 1,
|
|
933
|
+
hydrationMetrics,
|
|
934
|
+
publicationSubscriptions,
|
|
935
|
+
});
|
|
869
936
|
}
|
|
870
937
|
catch (err) {
|
|
871
938
|
// Skip the whole batch; partial child state could miss moderation.
|
|
@@ -873,7 +940,12 @@ export class Hydrator {
|
|
|
873
940
|
hydrationLogger.warn({ err, hydrationPass, skipped: newUris.length }, 'failed to hydrate external view dependencies');
|
|
874
941
|
}
|
|
875
942
|
}
|
|
876
|
-
return mergeStates({
|
|
943
|
+
return mergeStates({
|
|
944
|
+
ctx,
|
|
945
|
+
externalRecordBacklinks,
|
|
946
|
+
externalRecordBacklinkCounts,
|
|
947
|
+
externalPublicationSubscriptions: publicationSubscriptions,
|
|
948
|
+
}, nested);
|
|
877
949
|
}
|
|
878
950
|
// app.bsky.feed.defs#threadViewPost
|
|
879
951
|
// - post
|
|
@@ -1239,7 +1311,7 @@ export class Hydrator {
|
|
|
1239
1311
|
postUris.add(parentUri);
|
|
1240
1312
|
});
|
|
1241
1313
|
const [postState, feedGenState, starterPackState] = await Promise.all([
|
|
1242
|
-
this.hydratePosts([...postUris].map((uri) => ({ uri })), ctx, { posts }),
|
|
1314
|
+
this.hydratePosts([...postUris].map((uri) => ({ uri })), ctx, { posts }, { skipReplyBlocks: true }),
|
|
1243
1315
|
this.hydrateFeedGens([...feedGenUris], ctx),
|
|
1244
1316
|
this.hydrateStarterPacksBasic([...starterPackUris], ctx),
|
|
1245
1317
|
]);
|
|
@@ -1573,52 +1645,6 @@ const nestedRecordUris = (post) => {
|
|
|
1573
1645
|
}
|
|
1574
1646
|
return uris;
|
|
1575
1647
|
};
|
|
1576
|
-
/**
|
|
1577
|
-
* Returns every strongRef the post embedded as `external.associatedRefs`,
|
|
1578
|
-
* regardless of collection. Callers are responsible for filtering to NSIDs
|
|
1579
|
-
* they care about.
|
|
1580
|
-
*/
|
|
1581
|
-
const externalAssociatedRefs = (post) => {
|
|
1582
|
-
const embed = post?.embed;
|
|
1583
|
-
if (!embed)
|
|
1584
|
-
return [];
|
|
1585
|
-
if (isExternalEmbedType(embed)) {
|
|
1586
|
-
return embed.external.associatedRefs ?? [];
|
|
1587
|
-
}
|
|
1588
|
-
if (isRecordWithMediaType(embed) && isExternalEmbedType(embed.media)) {
|
|
1589
|
-
return embed.media.external.associatedRefs ?? [];
|
|
1590
|
-
}
|
|
1591
|
-
return [];
|
|
1592
|
-
};
|
|
1593
|
-
/**
|
|
1594
|
-
* Collects standard.site refs across all post layers, deduped by `uri+cid` so
|
|
1595
|
-
* the dataplane batch is minimal even if multiple posts in the layer reference
|
|
1596
|
-
* the same exact version of an SS record. The same `${uri}@${cid}` keys are
|
|
1597
|
-
* what `getSiteStandardRecordsByRef` uses on the resulting hydration maps,
|
|
1598
|
-
* which lets `lookupAssociatedSiteStandardRecords` do an O(1) version-exact
|
|
1599
|
-
* lookup at view time.
|
|
1600
|
-
*/
|
|
1601
|
-
const siteStandardRefsFromPosts = (...postLayers) => {
|
|
1602
|
-
const seen = new Set();
|
|
1603
|
-
const out = [];
|
|
1604
|
-
for (const layer of postLayers) {
|
|
1605
|
-
for (const item of layer.values()) {
|
|
1606
|
-
if (!item)
|
|
1607
|
-
continue;
|
|
1608
|
-
for (const ref of externalAssociatedRefs(item.record)) {
|
|
1609
|
-
if (!new AtUri(ref.uri).collection.startsWith(SITE_STANDARD_NSID_PREFIX)) {
|
|
1610
|
-
continue;
|
|
1611
|
-
}
|
|
1612
|
-
const key = `${ref.uri}@${ref.cid}`;
|
|
1613
|
-
if (seen.has(key))
|
|
1614
|
-
continue;
|
|
1615
|
-
seen.add(key);
|
|
1616
|
-
out.push({ uri: ref.uri, cid: ref.cid });
|
|
1617
|
-
}
|
|
1618
|
-
}
|
|
1619
|
-
}
|
|
1620
|
-
return out;
|
|
1621
|
-
};
|
|
1622
1648
|
const getListUrisFromThreadgates = (gates) => {
|
|
1623
1649
|
const uris = [];
|
|
1624
1650
|
for (const gate of gates.values()) {
|
|
@@ -1708,8 +1734,7 @@ export const mergeStates = (stateA, stateB) => {
|
|
|
1708
1734
|
externalRecordsByRef: mergeMaps(stateA.externalRecordsByRef, stateB.externalRecordsByRef),
|
|
1709
1735
|
externalRecordBacklinks: mergeMaps(stateA.externalRecordBacklinks, stateB.externalRecordBacklinks),
|
|
1710
1736
|
externalRecordBacklinkCounts: mergeMaps(stateA.externalRecordBacklinkCounts, stateB.externalRecordBacklinkCounts),
|
|
1711
|
-
|
|
1712
|
-
siteStandardPublications: mergeMaps(stateA.siteStandardPublications, stateB.siteStandardPublications),
|
|
1737
|
+
externalPublicationSubscriptions: mergeMaps(stateA.externalPublicationSubscriptions, stateB.externalPublicationSubscriptions),
|
|
1713
1738
|
};
|
|
1714
1739
|
};
|
|
1715
1740
|
export const mergeManyStates = (...states) => {
|
|
@@ -1722,71 +1747,6 @@ const actionTakedownLabels = (keys, hydrationMap, labels) => {
|
|
|
1722
1747
|
}
|
|
1723
1748
|
}
|
|
1724
1749
|
};
|
|
1725
|
-
/**
|
|
1726
|
-
* The URI when an externally authored reference is a complete DID-based
|
|
1727
|
-
* record URI in `collection`, with a record key and no fragment.
|
|
1728
|
-
*/
|
|
1729
|
-
const recordUriOf = (value, collection) => {
|
|
1730
|
-
const parsed = parseAtUriString(value);
|
|
1731
|
-
return parsed.success &&
|
|
1732
|
-
isDidString(parsed.value.authority) &&
|
|
1733
|
-
parsed.value.collection === collection &&
|
|
1734
|
-
parsed.value.rkey &&
|
|
1735
|
-
!parsed.value.hash
|
|
1736
|
-
? value
|
|
1737
|
-
: undefined;
|
|
1738
|
-
};
|
|
1739
|
-
/**
|
|
1740
|
-
* Apply takedown labels to the site.standard hydration maps. Per-record
|
|
1741
|
-
* takedowns null any entry whose subject URI is taken down; pair takedowns
|
|
1742
|
-
* propagate that null across doc/publication pairs so we never render half
|
|
1743
|
-
* of a moderated embed. Pairs are discovered via `doc.record.site`; orphan
|
|
1744
|
-
* docs and orphan publications are subject only to the per-record sweep.
|
|
1745
|
-
*/
|
|
1746
|
-
const actionSiteStandardTakedownLabels = (documents, publications, labels) => {
|
|
1747
|
-
// Pairings have to be captured before nulling — the doc record carries
|
|
1748
|
-
// the publication URI in its `site` field, and we lose it once we null.
|
|
1749
|
-
const pairings = [];
|
|
1750
|
-
if (documents.size > 0 && publications.size > 0) {
|
|
1751
|
-
const pubKeysByUri = new Map();
|
|
1752
|
-
for (const key of publications.keys()) {
|
|
1753
|
-
const { uri } = parseGenericRecordKey(key);
|
|
1754
|
-
const list = pubKeysByUri.get(uri);
|
|
1755
|
-
if (list)
|
|
1756
|
-
list.push(key);
|
|
1757
|
-
else
|
|
1758
|
-
pubKeysByUri.set(uri, [key]);
|
|
1759
|
-
}
|
|
1760
|
-
for (const [docKey, doc] of documents) {
|
|
1761
|
-
const site = doc?.record.site;
|
|
1762
|
-
if (!site || !site.startsWith('at://'))
|
|
1763
|
-
continue;
|
|
1764
|
-
for (const pubKey of pubKeysByUri.get(site) ?? []) {
|
|
1765
|
-
pairings.push({ docKey, pubKey });
|
|
1766
|
-
}
|
|
1767
|
-
}
|
|
1768
|
-
}
|
|
1769
|
-
// Per-record takedowns: null any entry whose subject URI is taken down.
|
|
1770
|
-
for (const key of documents.keys()) {
|
|
1771
|
-
const { uri } = parseGenericRecordKey(key);
|
|
1772
|
-
if (labels.get(uri)?.isTakendown)
|
|
1773
|
-
documents.set(key, null);
|
|
1774
|
-
}
|
|
1775
|
-
for (const key of publications.keys()) {
|
|
1776
|
-
const { uri } = parseGenericRecordKey(key);
|
|
1777
|
-
if (labels.get(uri)?.isTakendown)
|
|
1778
|
-
publications.set(key, null);
|
|
1779
|
-
}
|
|
1780
|
-
// Pair takedowns: if exactly one side of a pair was nulled above, mirror.
|
|
1781
|
-
for (const { docKey, pubKey } of pairings) {
|
|
1782
|
-
const doc = documents.get(docKey);
|
|
1783
|
-
const pub = publications.get(pubKey);
|
|
1784
|
-
if (doc === null && pub !== null)
|
|
1785
|
-
publications.set(pubKey, null);
|
|
1786
|
-
if (pub === null && doc !== null)
|
|
1787
|
-
documents.set(docKey, null);
|
|
1788
|
-
}
|
|
1789
|
-
};
|
|
1790
1750
|
const uriToRef = (uri) => {
|
|
1791
1751
|
return { uri };
|
|
1792
1752
|
};
|