@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.
Files changed (288) hide show
  1. package/CHANGELOG.md +61 -0
  2. package/dist/api/app/bsky/actor/getProfile.d.ts.map +1 -1
  3. package/dist/api/app/bsky/actor/getProfile.js +1 -0
  4. package/dist/api/app/bsky/actor/getProfile.js.map +1 -1
  5. package/dist/api/app/bsky/actor/getProfiles.d.ts.map +1 -1
  6. package/dist/api/app/bsky/actor/getProfiles.js +1 -0
  7. package/dist/api/app/bsky/actor/getProfiles.js.map +1 -1
  8. package/dist/api/app/bsky/actor/getSuggestions.d.ts.map +1 -1
  9. package/dist/api/app/bsky/actor/getSuggestions.js +1 -0
  10. package/dist/api/app/bsky/actor/getSuggestions.js.map +1 -1
  11. package/dist/api/app/bsky/actor/searchActors.d.ts.map +1 -1
  12. package/dist/api/app/bsky/actor/searchActors.js +1 -0
  13. package/dist/api/app/bsky/actor/searchActors.js.map +1 -1
  14. package/dist/api/app/bsky/actor/searchActorsTypeahead.d.ts.map +1 -1
  15. package/dist/api/app/bsky/actor/searchActorsTypeahead.js +1 -0
  16. package/dist/api/app/bsky/actor/searchActorsTypeahead.js.map +1 -1
  17. package/dist/api/app/bsky/bookmark/getBookmarks.d.ts.map +1 -1
  18. package/dist/api/app/bsky/bookmark/getBookmarks.js +1 -0
  19. package/dist/api/app/bsky/bookmark/getBookmarks.js.map +1 -1
  20. package/dist/api/app/bsky/contact/getMatches.d.ts.map +1 -1
  21. package/dist/api/app/bsky/contact/getMatches.js +1 -0
  22. package/dist/api/app/bsky/contact/getMatches.js.map +1 -1
  23. package/dist/api/app/bsky/contact/importContacts.d.ts.map +1 -1
  24. package/dist/api/app/bsky/contact/importContacts.js +1 -0
  25. package/dist/api/app/bsky/contact/importContacts.js.map +1 -1
  26. package/dist/api/app/bsky/feed/getActorFeeds.d.ts.map +1 -1
  27. package/dist/api/app/bsky/feed/getActorFeeds.js +5 -1
  28. package/dist/api/app/bsky/feed/getActorFeeds.js.map +1 -1
  29. package/dist/api/app/bsky/feed/getActorLikes.d.ts.map +1 -1
  30. package/dist/api/app/bsky/feed/getActorLikes.js +1 -0
  31. package/dist/api/app/bsky/feed/getActorLikes.js.map +1 -1
  32. package/dist/api/app/bsky/feed/getAuthorFeed.d.ts.map +1 -1
  33. package/dist/api/app/bsky/feed/getAuthorFeed.js +1 -0
  34. package/dist/api/app/bsky/feed/getAuthorFeed.js.map +1 -1
  35. package/dist/api/app/bsky/feed/getFeed.d.ts.map +1 -1
  36. package/dist/api/app/bsky/feed/getFeed.js +1 -0
  37. package/dist/api/app/bsky/feed/getFeed.js.map +1 -1
  38. package/dist/api/app/bsky/feed/getFeedGenerator.d.ts.map +1 -1
  39. package/dist/api/app/bsky/feed/getFeedGenerator.js +5 -1
  40. package/dist/api/app/bsky/feed/getFeedGenerator.js.map +1 -1
  41. package/dist/api/app/bsky/feed/getFeedGenerators.d.ts.map +1 -1
  42. package/dist/api/app/bsky/feed/getFeedGenerators.js +5 -1
  43. package/dist/api/app/bsky/feed/getFeedGenerators.js.map +1 -1
  44. package/dist/api/app/bsky/feed/getLikes.d.ts.map +1 -1
  45. package/dist/api/app/bsky/feed/getLikes.js +1 -0
  46. package/dist/api/app/bsky/feed/getLikes.js.map +1 -1
  47. package/dist/api/app/bsky/feed/getListFeed.d.ts.map +1 -1
  48. package/dist/api/app/bsky/feed/getListFeed.js +1 -0
  49. package/dist/api/app/bsky/feed/getListFeed.js.map +1 -1
  50. package/dist/api/app/bsky/feed/getPostThread.d.ts.map +1 -1
  51. package/dist/api/app/bsky/feed/getPostThread.js +1 -0
  52. package/dist/api/app/bsky/feed/getPostThread.js.map +1 -1
  53. package/dist/api/app/bsky/feed/getPosts.d.ts.map +1 -1
  54. package/dist/api/app/bsky/feed/getPosts.js +5 -1
  55. package/dist/api/app/bsky/feed/getPosts.js.map +1 -1
  56. package/dist/api/app/bsky/feed/getQuotes.d.ts.map +1 -1
  57. package/dist/api/app/bsky/feed/getQuotes.js +1 -0
  58. package/dist/api/app/bsky/feed/getQuotes.js.map +1 -1
  59. package/dist/api/app/bsky/feed/getRepostedBy.d.ts.map +1 -1
  60. package/dist/api/app/bsky/feed/getRepostedBy.js +1 -0
  61. package/dist/api/app/bsky/feed/getRepostedBy.js.map +1 -1
  62. package/dist/api/app/bsky/feed/getSuggestedFeeds.d.ts.map +1 -1
  63. package/dist/api/app/bsky/feed/getSuggestedFeeds.js +5 -1
  64. package/dist/api/app/bsky/feed/getSuggestedFeeds.js.map +1 -1
  65. package/dist/api/app/bsky/feed/getTimeline.d.ts.map +1 -1
  66. package/dist/api/app/bsky/feed/getTimeline.js +1 -0
  67. package/dist/api/app/bsky/feed/getTimeline.js.map +1 -1
  68. package/dist/api/app/bsky/feed/searchPosts.d.ts.map +1 -1
  69. package/dist/api/app/bsky/feed/searchPosts.js +1 -0
  70. package/dist/api/app/bsky/feed/searchPosts.js.map +1 -1
  71. package/dist/api/app/bsky/feed/searchPostsV2.d.ts.map +1 -1
  72. package/dist/api/app/bsky/feed/searchPostsV2.js +1 -0
  73. package/dist/api/app/bsky/feed/searchPostsV2.js.map +1 -1
  74. package/dist/api/app/bsky/graph/getActorStarterPacks.d.ts.map +1 -1
  75. package/dist/api/app/bsky/graph/getActorStarterPacks.js +1 -0
  76. package/dist/api/app/bsky/graph/getActorStarterPacks.js.map +1 -1
  77. package/dist/api/app/bsky/graph/getBlocks.d.ts.map +1 -1
  78. package/dist/api/app/bsky/graph/getBlocks.js +5 -1
  79. package/dist/api/app/bsky/graph/getBlocks.js.map +1 -1
  80. package/dist/api/app/bsky/graph/getFollowers.d.ts.map +1 -1
  81. package/dist/api/app/bsky/graph/getFollowers.js +1 -0
  82. package/dist/api/app/bsky/graph/getFollowers.js.map +1 -1
  83. package/dist/api/app/bsky/graph/getFollows.d.ts.map +1 -1
  84. package/dist/api/app/bsky/graph/getFollows.js +1 -0
  85. package/dist/api/app/bsky/graph/getFollows.js.map +1 -1
  86. package/dist/api/app/bsky/graph/getKnownFollowers.d.ts.map +1 -1
  87. package/dist/api/app/bsky/graph/getKnownFollowers.js +1 -0
  88. package/dist/api/app/bsky/graph/getKnownFollowers.js.map +1 -1
  89. package/dist/api/app/bsky/graph/getList.d.ts.map +1 -1
  90. package/dist/api/app/bsky/graph/getList.js +1 -0
  91. package/dist/api/app/bsky/graph/getList.js.map +1 -1
  92. package/dist/api/app/bsky/graph/getListBlocks.d.ts.map +1 -1
  93. package/dist/api/app/bsky/graph/getListBlocks.js +5 -1
  94. package/dist/api/app/bsky/graph/getListBlocks.js.map +1 -1
  95. package/dist/api/app/bsky/graph/getListMutes.d.ts.map +1 -1
  96. package/dist/api/app/bsky/graph/getListMutes.js +5 -1
  97. package/dist/api/app/bsky/graph/getListMutes.js.map +1 -1
  98. package/dist/api/app/bsky/graph/getLists.d.ts.map +1 -1
  99. package/dist/api/app/bsky/graph/getLists.js +1 -0
  100. package/dist/api/app/bsky/graph/getLists.js.map +1 -1
  101. package/dist/api/app/bsky/graph/getListsWithMembership.d.ts.map +1 -1
  102. package/dist/api/app/bsky/graph/getListsWithMembership.js +1 -0
  103. package/dist/api/app/bsky/graph/getListsWithMembership.js.map +1 -1
  104. package/dist/api/app/bsky/graph/getMutes.d.ts.map +1 -1
  105. package/dist/api/app/bsky/graph/getMutes.js +5 -1
  106. package/dist/api/app/bsky/graph/getMutes.js.map +1 -1
  107. package/dist/api/app/bsky/graph/getStarterPack.d.ts.map +1 -1
  108. package/dist/api/app/bsky/graph/getStarterPack.js +1 -0
  109. package/dist/api/app/bsky/graph/getStarterPack.js.map +1 -1
  110. package/dist/api/app/bsky/graph/getStarterPacks.d.ts.map +1 -1
  111. package/dist/api/app/bsky/graph/getStarterPacks.js +1 -0
  112. package/dist/api/app/bsky/graph/getStarterPacks.js.map +1 -1
  113. package/dist/api/app/bsky/graph/getStarterPacksWithMembership.d.ts.map +1 -1
  114. package/dist/api/app/bsky/graph/getStarterPacksWithMembership.js +1 -0
  115. package/dist/api/app/bsky/graph/getStarterPacksWithMembership.js.map +1 -1
  116. package/dist/api/app/bsky/graph/getSuggestedFollowsByActor.d.ts.map +1 -1
  117. package/dist/api/app/bsky/graph/getSuggestedFollowsByActor.js +1 -0
  118. package/dist/api/app/bsky/graph/getSuggestedFollowsByActor.js.map +1 -1
  119. package/dist/api/app/bsky/graph/searchStarterPacks.d.ts.map +1 -1
  120. package/dist/api/app/bsky/graph/searchStarterPacks.js +1 -0
  121. package/dist/api/app/bsky/graph/searchStarterPacks.js.map +1 -1
  122. package/dist/api/app/bsky/graph/searchStarterPacksV2.d.ts.map +1 -1
  123. package/dist/api/app/bsky/graph/searchStarterPacksV2.js +1 -0
  124. package/dist/api/app/bsky/graph/searchStarterPacksV2.js.map +1 -1
  125. package/dist/api/app/bsky/labeler/getServices.d.ts.map +1 -1
  126. package/dist/api/app/bsky/labeler/getServices.js +1 -0
  127. package/dist/api/app/bsky/labeler/getServices.js.map +1 -1
  128. package/dist/api/app/bsky/notification/getGroupedNotifications.d.ts.map +1 -1
  129. package/dist/api/app/bsky/notification/getGroupedNotifications.js +41 -20
  130. package/dist/api/app/bsky/notification/getGroupedNotifications.js.map +1 -1
  131. package/dist/api/app/bsky/notification/grouping/algoGravity.d.ts +4 -3
  132. package/dist/api/app/bsky/notification/grouping/algoGravity.d.ts.map +1 -1
  133. package/dist/api/app/bsky/notification/grouping/algoGravity.js +53 -42
  134. package/dist/api/app/bsky/notification/grouping/algoGravity.js.map +1 -1
  135. package/dist/api/app/bsky/notification/grouping/algoLookback.d.ts +4 -3
  136. package/dist/api/app/bsky/notification/grouping/algoLookback.d.ts.map +1 -1
  137. package/dist/api/app/bsky/notification/grouping/algoLookback.js +56 -42
  138. package/dist/api/app/bsky/notification/grouping/algoLookback.js.map +1 -1
  139. package/dist/api/app/bsky/notification/grouping/grouping.d.ts +12 -2
  140. package/dist/api/app/bsky/notification/grouping/grouping.d.ts.map +1 -1
  141. package/dist/api/app/bsky/notification/grouping/grouping.js +20 -6
  142. package/dist/api/app/bsky/notification/grouping/grouping.js.map +1 -1
  143. package/dist/api/app/bsky/notification/grouping/spotlight.d.ts +2 -2
  144. package/dist/api/app/bsky/notification/grouping/spotlight.d.ts.map +1 -1
  145. package/dist/api/app/bsky/notification/grouping/spotlight.js +35 -22
  146. package/dist/api/app/bsky/notification/grouping/spotlight.js.map +1 -1
  147. package/dist/api/app/bsky/notification/listActivitySubscriptions.d.ts.map +1 -1
  148. package/dist/api/app/bsky/notification/listActivitySubscriptions.js +1 -0
  149. package/dist/api/app/bsky/notification/listActivitySubscriptions.js.map +1 -1
  150. package/dist/api/app/bsky/notification/listNotifications.d.ts.map +1 -1
  151. package/dist/api/app/bsky/notification/listNotifications.js +5 -1
  152. package/dist/api/app/bsky/notification/listNotifications.js.map +1 -1
  153. package/dist/api/app/bsky/unspecced/atmosphere-grouping.d.ts +16 -0
  154. package/dist/api/app/bsky/unspecced/atmosphere-grouping.d.ts.map +1 -0
  155. package/dist/api/app/bsky/unspecced/atmosphere-grouping.js +124 -0
  156. package/dist/api/app/bsky/unspecced/atmosphere-grouping.js.map +1 -0
  157. package/dist/api/app/bsky/unspecced/atmosphere-hydration.d.ts +32 -0
  158. package/dist/api/app/bsky/unspecced/atmosphere-hydration.d.ts.map +1 -0
  159. package/dist/api/app/bsky/unspecced/atmosphere-hydration.js +201 -0
  160. package/dist/api/app/bsky/unspecced/atmosphere-hydration.js.map +1 -0
  161. package/dist/api/app/bsky/unspecced/atmosphere-pagination.d.ts +6 -0
  162. package/dist/api/app/bsky/unspecced/atmosphere-pagination.d.ts.map +1 -0
  163. package/dist/api/app/bsky/unspecced/atmosphere-pagination.js +164 -0
  164. package/dist/api/app/bsky/unspecced/atmosphere-pagination.js.map +1 -0
  165. package/dist/api/app/bsky/unspecced/getAtmosphereExploreTab.d.ts.map +1 -1
  166. package/dist/api/app/bsky/unspecced/getAtmosphereExploreTab.js +120 -55
  167. package/dist/api/app/bsky/unspecced/getAtmosphereExploreTab.js.map +1 -1
  168. package/dist/api/app/bsky/unspecced/getAtmosphereTimeline.d.ts +4 -0
  169. package/dist/api/app/bsky/unspecced/getAtmosphereTimeline.d.ts.map +1 -0
  170. package/dist/api/app/bsky/unspecced/getAtmosphereTimeline.js +30 -0
  171. package/dist/api/app/bsky/unspecced/getAtmosphereTimeline.js.map +1 -0
  172. package/dist/api/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.d.ts.map +1 -1
  173. package/dist/api/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.js +4 -7
  174. package/dist/api/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.js.map +1 -1
  175. package/dist/api/app/bsky/unspecced/getPopularFeedGenerators.d.ts.map +1 -1
  176. package/dist/api/app/bsky/unspecced/getPopularFeedGenerators.js +1 -0
  177. package/dist/api/app/bsky/unspecced/getPopularFeedGenerators.js.map +1 -1
  178. package/dist/api/app/bsky/unspecced/getPostThreadOtherV2.d.ts.map +1 -1
  179. package/dist/api/app/bsky/unspecced/getPostThreadOtherV2.js +1 -0
  180. package/dist/api/app/bsky/unspecced/getPostThreadOtherV2.js.map +1 -1
  181. package/dist/api/app/bsky/unspecced/getPostThreadV2.d.ts.map +1 -1
  182. package/dist/api/app/bsky/unspecced/getPostThreadV2.js +1 -0
  183. package/dist/api/app/bsky/unspecced/getPostThreadV2.js.map +1 -1
  184. package/dist/api/app/bsky/unspecced/getSuggestedFeeds.d.ts.map +1 -1
  185. package/dist/api/app/bsky/unspecced/getSuggestedFeeds.js +4 -7
  186. package/dist/api/app/bsky/unspecced/getSuggestedFeeds.js.map +1 -1
  187. package/dist/api/app/bsky/unspecced/getSuggestedOnboardingUsers.d.ts.map +1 -1
  188. package/dist/api/app/bsky/unspecced/getSuggestedOnboardingUsers.js +1 -0
  189. package/dist/api/app/bsky/unspecced/getSuggestedOnboardingUsers.js.map +1 -1
  190. package/dist/api/app/bsky/unspecced/getSuggestedStarterPacks.d.ts.map +1 -1
  191. package/dist/api/app/bsky/unspecced/getSuggestedStarterPacks.js +4 -7
  192. package/dist/api/app/bsky/unspecced/getSuggestedStarterPacks.js.map +1 -1
  193. package/dist/api/app/bsky/unspecced/getSuggestedUsers.d.ts.map +1 -1
  194. package/dist/api/app/bsky/unspecced/getSuggestedUsers.js +2 -19
  195. package/dist/api/app/bsky/unspecced/getSuggestedUsers.js.map +1 -1
  196. package/dist/api/app/bsky/unspecced/getSuggestedUsersForDiscover.d.ts.map +1 -1
  197. package/dist/api/app/bsky/unspecced/getSuggestedUsersForDiscover.js +1 -0
  198. package/dist/api/app/bsky/unspecced/getSuggestedUsersForDiscover.js.map +1 -1
  199. package/dist/api/app/bsky/unspecced/getSuggestedUsersForExplore.d.ts.map +1 -1
  200. package/dist/api/app/bsky/unspecced/getSuggestedUsersForExplore.js +1 -0
  201. package/dist/api/app/bsky/unspecced/getSuggestedUsersForExplore.js.map +1 -1
  202. package/dist/api/app/bsky/unspecced/getSuggestedUsersForSeeMore.d.ts.map +1 -1
  203. package/dist/api/app/bsky/unspecced/getSuggestedUsersForSeeMore.js +1 -0
  204. package/dist/api/app/bsky/unspecced/getSuggestedUsersForSeeMore.js.map +1 -1
  205. package/dist/api/app/bsky/unspecced/getTrendingTopics.d.ts.map +1 -1
  206. package/dist/api/app/bsky/unspecced/getTrendingTopics.js +6 -2
  207. package/dist/api/app/bsky/unspecced/getTrendingTopics.js.map +1 -1
  208. package/dist/api/app/bsky/unspecced/getTrends.d.ts.map +1 -1
  209. package/dist/api/app/bsky/unspecced/getTrends.js +6 -2
  210. package/dist/api/app/bsky/unspecced/getTrends.js.map +1 -1
  211. package/dist/api/blob-resolver.d.ts.map +1 -1
  212. package/dist/api/blob-resolver.js +9 -8
  213. package/dist/api/blob-resolver.js.map +1 -1
  214. package/dist/api/index.d.ts.map +1 -1
  215. package/dist/api/index.js +2 -0
  216. package/dist/api/index.js.map +1 -1
  217. package/dist/api/internal/bsky/actor/getProfiles.d.ts.map +1 -1
  218. package/dist/api/internal/bsky/actor/getProfiles.js +1 -0
  219. package/dist/api/internal/bsky/actor/getProfiles.js.map +1 -1
  220. package/dist/config.d.ts +2 -6
  221. package/dist/config.d.ts.map +1 -1
  222. package/dist/config.js +7 -16
  223. package/dist/config.js.map +1 -1
  224. package/dist/context.d.ts +0 -2
  225. package/dist/context.d.ts.map +1 -1
  226. package/dist/context.js +0 -3
  227. package/dist/context.js.map +1 -1
  228. package/dist/feature-gates/gates.d.ts +0 -4
  229. package/dist/feature-gates/gates.d.ts.map +1 -1
  230. package/dist/feature-gates/gates.js +0 -4
  231. package/dist/feature-gates/gates.js.map +1 -1
  232. package/dist/hydration/external.d.ts +58 -45
  233. package/dist/hydration/external.d.ts.map +1 -1
  234. package/dist/hydration/external.js +134 -114
  235. package/dist/hydration/external.js.map +1 -1
  236. package/dist/hydration/hydrator.d.ts +15 -9
  237. package/dist/hydration/hydrator.d.ts.map +1 -1
  238. package/dist/hydration/hydrator.js +170 -210
  239. package/dist/hydration/hydrator.js.map +1 -1
  240. package/dist/image/server.d.ts.map +1 -1
  241. package/dist/image/server.js +12 -1
  242. package/dist/image/server.js.map +1 -1
  243. package/dist/index.d.ts.map +1 -1
  244. package/dist/index.js +4 -19
  245. package/dist/index.js.map +1 -1
  246. package/dist/lexicons/app/bsky/unspecced/getAtmosphereExploreTab.defs.d.ts +29 -0
  247. package/dist/lexicons/app/bsky/unspecced/getAtmosphereExploreTab.defs.d.ts.map +1 -1
  248. package/dist/lexicons/app/bsky/unspecced/getAtmosphereExploreTab.defs.js +2 -1
  249. package/dist/lexicons/app/bsky/unspecced/getAtmosphereExploreTab.defs.js.map +1 -1
  250. package/dist/lexicons/app/bsky/unspecced/getAtmosphereTimeline.d.ts +3 -0
  251. package/dist/lexicons/app/bsky/unspecced/getAtmosphereTimeline.d.ts.map +1 -0
  252. package/dist/lexicons/app/bsky/unspecced/getAtmosphereTimeline.defs.d.ts +85 -0
  253. package/dist/lexicons/app/bsky/unspecced/getAtmosphereTimeline.defs.d.ts.map +1 -0
  254. package/dist/lexicons/app/bsky/unspecced/getAtmosphereTimeline.defs.js +29 -0
  255. package/dist/lexicons/app/bsky/unspecced/getAtmosphereTimeline.defs.js.map +1 -0
  256. package/dist/lexicons/app/bsky/unspecced/getAtmosphereTimeline.js +6 -0
  257. package/dist/lexicons/app/bsky/unspecced/getAtmosphereTimeline.js.map +1 -0
  258. package/dist/lexicons/app/bsky/unspecced.d.ts +1 -0
  259. package/dist/lexicons/app/bsky/unspecced.d.ts.map +1 -1
  260. package/dist/lexicons/app/bsky/unspecced.js +1 -0
  261. package/dist/lexicons/app/bsky/unspecced.js.map +1 -1
  262. package/dist/lexicons/tools/ozone/moderation/emitEvent.defs.d.ts +2 -2
  263. package/dist/lexicons/tools/ozone/moderation/emitEvent.defs.js.map +1 -1
  264. package/dist/lexicons/tools/ozone/report/closeReports.defs.d.ts +1 -1
  265. package/dist/lexicons/tools/ozone/report/closeReports.defs.d.ts.map +1 -1
  266. package/dist/lexicons/tools/ozone/report/closeReports.defs.js +1 -1
  267. package/dist/lexicons/tools/ozone/report/closeReports.defs.js.map +1 -1
  268. package/dist/telemetry/events.d.ts +14 -6
  269. package/dist/telemetry/events.d.ts.map +1 -1
  270. package/dist/telemetry/events.js +40 -5
  271. package/dist/telemetry/events.js.map +1 -1
  272. package/dist/util/external/standard-site.d.ts +2 -3
  273. package/dist/util/external/standard-site.d.ts.map +1 -1
  274. package/dist/util/external/standard-site.js +2 -3
  275. package/dist/util/external/standard-site.js.map +1 -1
  276. package/dist/util/uris.d.ts +5 -2
  277. package/dist/util/uris.d.ts.map +1 -1
  278. package/dist/util/uris.js +14 -1
  279. package/dist/util/uris.js.map +1 -1
  280. package/dist/views/external.d.ts +5 -0
  281. package/dist/views/external.d.ts.map +1 -1
  282. package/dist/views/external.js +38 -11
  283. package/dist/views/external.js.map +1 -1
  284. package/dist/views/index.d.ts +2 -2
  285. package/dist/views/index.d.ts.map +1 -1
  286. package/dist/views/index.js +17 -11
  287. package/dist/views/index.js.map +1 -1
  288. package/package.json +13 -14
@@ -1,8 +1,9 @@
1
1
  import { type AtUriString, type DidString, type NsidString, type TypedLexMap } from '@atproto/lex';
2
2
  import type { DataPlaneClient } from '../data-plane/client/index.js';
3
3
  import { type ExternalHydrationRoot, type ExternalHydrationWork, type HydrationXrpcEndpoint } from '../telemetry/events.js';
4
- import type { SiteStandardDocumentRecord, SiteStandardPublicationRecord } from '../views/types.js';
4
+ import { type SiteStandardDocumentRecord, type SiteStandardPublicationRecord } from '../views/types.js';
5
5
  import type { Actors } from './actor.js';
6
+ import type { Posts } from './feed.js';
6
7
  import type { Labels } from './label.js';
7
8
  import { HydrationMap, type ItemRef, type RecordInfo } from './util.js';
8
9
  /** Generic record bodies are decoded, but not validated against a Lexicon. */
@@ -11,6 +12,8 @@ export type ExternalRecords = HydrationMap<AtUriString, ExternalRecord>;
11
12
  /** Keyed by `genericRecordKey({ uri, cid })` to retain versions of a URI. */
12
13
  export type ExternalRecordsByRef = HydrationMap<ExactRecordKey, ExternalRecord>;
13
14
  export type ExternalRecordBacklinks = HydrationMap<AtUriString, AtUriString[]>;
15
+ /** Viewer subscription outcomes per publication; null means unknown. */
16
+ export type ExternalPublicationSubscriptions = HydrationMap<AtUriString, boolean>;
14
17
  export type AtmosphereActivityItem = {
15
18
  uri: AtUriString;
16
19
  sortedAt: Date;
@@ -38,33 +41,56 @@ export type ExactRecordKey = string & {
38
41
  };
39
42
  export type SiteStandardDocument = RecordInfo<SiteStandardDocumentRecord>;
40
43
  export type SiteStandardPublication = RecordInfo<SiteStandardPublicationRecord>;
44
+ export type ExternalHydrationLevel = 'basic' | 'detailed';
41
45
  /**
42
- * Keyed by `${uri}@${cid}` — see `genericRecordKey`. A single hydration
43
- * batch can pull more than one version of the same URI (different posts
44
- * pinning different cids), so the composite key is needed for O(1)
45
- * version-exact lookups.
46
+ * Options for external hydration traversals. `hydration` picks one level for
47
+ * the whole traversal (default `'detailed'`): `'basic'` hydrates renderable
48
+ * content, moderation and aggregate backlink counts; `'detailed'` also samples
49
+ * social-preview backlinks and hydrates their records and participants.
50
+ * `publicationSubscriptions` opts an authenticated viewer into request-cached
51
+ * subscription discovery. The remaining fields are shared traversal state.
46
52
  */
47
- export type SiteStandardDocuments = HydrationMap<ExactRecordKey, SiteStandardDocument>;
53
+ export type ExternalHydrationOptions = {
54
+ hydration?: ExternalHydrationLevel;
55
+ seenRecordKeys?: Set<string>;
56
+ hydrationPass?: number;
57
+ hydrationMetrics?: ExternalHydrationTracker;
58
+ publicationSubscriptions?: ExternalPublicationSubscriptions;
59
+ };
48
60
  /**
49
- * Keyed by `${uri}@${cid}`. See `SiteStandardDocuments` for the rationale.
61
+ * Per-collection sample limits. Basic hydration skips social previews,
62
+ * but keeps gallery items. Direct publication/photo references are singular.
50
63
  */
51
- export type SiteStandardPublications = HydrationMap<ExactRecordKey, SiteStandardPublication>;
52
- export type SiteStandardRecords = {
53
- documents: SiteStandardDocuments;
54
- publications: SiteStandardPublications;
64
+ export declare const EXTERNAL_HYDRATION_LIMITS: {
65
+ readonly "site.standard.document": {
66
+ readonly recommendationPreviews: 3;
67
+ };
68
+ readonly "site.standard.publication": {
69
+ readonly subscriberPreviews: 3;
70
+ };
71
+ readonly "social.grain.gallery": {
72
+ readonly items: 10;
73
+ readonly favoritePreviews: 3;
74
+ };
55
75
  };
76
+ /** Maximum in-flight backlink sample RPCs, not a dependency-count limit. */
77
+ export declare const MAX_CONCURRENT_BACKLINK_REQUESTS = 8;
78
+ /** Maximum logical batches per traversal, counting the root as pass 1. */
79
+ export declare const MAX_EXTERNAL_HYDRATION_PASSES = 8;
56
80
  export declare class ExternalHydrator {
57
81
  dataplane: DataPlaneClient;
58
- static readonly MAX_BACKLINK_PREVIEWS = 3;
59
- static readonly MAX_BACKLINK_GALLERY_ITEMS = 10;
60
- static readonly MAX_BACKLINK_FANOUT = 8;
61
- /** Hard cap on generic batches per traversal, counting the root as pass 1. */
62
- static readonly MAX_EXTERNAL_HYDRATION_PASSES = 8;
63
82
  /**
64
83
  * Entries per generic record RPC. The dataplane rejects larger URI lookups;
65
84
  * exact-ref lookups use the same bound defensively.
66
85
  */
67
86
  static readonly MAX_RECORDS_PER_REQUEST = 100;
87
+ /**
88
+ * Target URIs per backlink-count RPC. The dataplane requires between 1 and
89
+ * 100; this is a separate limit from `MAX_RECORDS_PER_REQUEST`.
90
+ */
91
+ static readonly MAX_BACKLINK_COUNT_TARGETS_PER_REQUEST = 100;
92
+ /** Target URIs per actor-backlink RPC, bounded by the dataplane. */
93
+ static readonly MAX_BACKLINK_ACTOR_TARGETS_PER_REQUEST = 100;
68
94
  constructor(dataplane: DataPlaneClient);
69
95
  /**
70
96
  * Fetch exact record versions; unavailable records are represented by null.
@@ -83,7 +109,11 @@ export declare class ExternalHydrator {
83
109
  limit?: number;
84
110
  cursor?: string;
85
111
  }): Promise<AtmosphereTimeline>;
86
- /** Fetch source-record counts, optionally restricted to one collection. */
112
+ /**
113
+ * Fetch source-record counts, optionally restricted to one collection. Large
114
+ * inputs are fetched in sequential bounded requests; any failed request
115
+ * rejects the whole call.
116
+ */
87
117
  getAtmosphereBacklinkCounts(targetUris: AtUriString[], collection?: NsidString): Promise<ExternalRecordBacklinkCounts>;
88
118
  /** Fetch a page of source records linking to a target. */
89
119
  getAtmosphereBacklinks(targetUri: AtUriString, collection: NsidString, opts?: {
@@ -92,11 +122,6 @@ export declare class ExternalHydrator {
92
122
  }): Promise<AtmosphereBacklinks>;
93
123
  /** Fetch an actor's links per target, retaining the batch truncation flag. */
94
124
  getAtmosphereBacklinksByActor(targetUris: AtUriString[], actorDid: DidString, collection: NsidString): Promise<AtmosphereBacklinksByActor>;
95
- /**
96
- * Fetch exact `site.standard.{document,publication}` versions. Does NOT
97
- * resolve a document's publication; callers must pin it explicitly.
98
- */
99
- getSiteStandardRecordsByRef(refs: ItemRef[], includeTakedowns?: boolean): Promise<SiteStandardRecords>;
100
125
  }
101
126
  /**
102
127
  * Composes the lookup key for a ref: the bare URI for a latest-version lookup,
@@ -145,9 +170,10 @@ export type ExternalHydrationTracker = ExternalHydrationWork & {
145
170
  * there is none. Only the owner reports, once, including on failure, with the
146
171
  * context's XRPC endpoint (`'unknown'` if unset) and the traversal's wall time. A
147
172
  * returned traversal is `capped` if it hit the pass limit, else `partial` if
148
- * it recovered from a dependency failure. Owners that completed without
149
- * scheduling a batch did no work and are not reported; other outcomes always
150
- * are.
173
+ * it recovered from a dependency failure. Owners that completed report when
174
+ * they scheduled a batch or inspected roots (even prehydrated or unavailable
175
+ * ones); only genuinely empty successful calls are not reported. Other
176
+ * outcomes always are.
151
177
  */
152
178
  export declare function trackExternalHydration<T>(root: ExternalHydrationRoot, xrpcEndpoint: HydrationXrpcEndpoint | undefined, hydrationMetrics: ExternalHydrationTracker | undefined, fn: (hydrationMetrics: ExternalHydrationTracker) => Promise<T>): Promise<T>;
153
179
  export type AssociatedSiteStandardRecord<T> = {
@@ -158,29 +184,16 @@ export type AssociatedSiteStandardRecord<T> = {
158
184
  info: T;
159
185
  };
160
186
  /**
161
- * Read-path resolution: caller pinned a set of `(uri, cid)` strongRefs in
162
- * the post at write time, and we honor those exact versions. Any pair
163
- * that doesn't structurally agree is rejected, so downstream callers can
164
- * trust the returned shape.
165
- *
166
- * Pairing rules:
167
- * - Both slots referenced: `doc.site` must equal `publication.ref.uri`,
168
- * else both come back `undefined`.
169
- * - Doc with at-uri `site` referenced but no matching publication ref:
170
- * reject the whole pairing (doc claims a publication that should have
171
- * been pinned, but wasn't).
172
- * - Loose doc (web-URL `site`) referenced: publication stays `undefined`.
173
- * - Only a publication referenced: document stays `undefined`.
174
- *
175
- * Each returned slot carries the matching `ref` so callers can recover
176
- * the owner DID for blob-cdn URL building, etc.
187
+ * Select one pinned embed root. Legacy publication-first pairs may put their
188
+ * document second; no other authored refs participate in hydration.
177
189
  */
178
- export declare const getSiteStandardRecordsFromHydrationMapsByRefs: (associatedRefs: readonly {
179
- uri: AtUriString;
180
- cid: string;
181
- }[] | undefined, documents: SiteStandardDocuments | undefined, publications: SiteStandardPublications | undefined) => {
190
+ export declare function getExternalRootRef(refs: readonly Required<ItemRef>[] | undefined): Required<ItemRef> | undefined;
191
+ /** Select a pinned Standard.site root and its derived publication, if needed. */
192
+ export declare function getSiteStandardRecordsFromRefs(associatedRefs: readonly Required<ItemRef>[] | undefined, records: ExternalRecordsByRef | undefined, dependencies?: ExternalRecords): {
182
193
  document: AssociatedSiteStandardRecord<SiteStandardDocument> | undefined;
183
194
  publication: AssociatedSiteStandardRecord<SiteStandardPublication> | undefined;
184
195
  };
196
+ /** Collect one root per post across all layers, deduped by exact ref. */
197
+ export declare const externalAssociatedRefsFromPosts: (...postLayers: Posts[]) => Required<ItemRef>[];
185
198
  export {};
186
199
  //# sourceMappingURL=external.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"external.d.ts","sourceRoot":"","sources":["../../src/hydration/external.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"external.d.ts","sourceRoot":"","sources":["../../src/hydration/external.ts"],"names":[],"mappings":"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"}
@@ -1,24 +1,39 @@
1
1
  import { performance } from 'node:perf_hooks';
2
2
  import { chunkArray } from '@atproto/common';
3
- import { isTypedLexMap, lexParseJsonBytes, } from '@atproto/lex';
3
+ import { isDidString, isTypedLexMap, lexParseJsonBytes, } from '@atproto/lex';
4
4
  import { parseAtUriString } from '@atproto/syntax';
5
- import { site } from '../lexicons/index.js';
6
- import { hydrationLogger } from '../logger.js';
5
+ import { site, social } from '../lexicons/index.js';
7
6
  import { RecordLookupStatus, } from '../proto/bsky_pb.js';
8
7
  import { events, } from '../telemetry/events.js';
9
- import { uriToDid } from '../util/uris.js';
8
+ import { recordUriOf, uriToDid } from '../util/uris.js';
9
+ import { isExternalEmbedType, isRecordWithMediaType, } from '../views/types.js';
10
10
  import { HydrationMap, parseDate, safeTakedownRef, } from './util.js';
11
+ /**
12
+ * Per-collection sample limits. Basic hydration skips social previews,
13
+ * but keeps gallery items. Direct publication/photo references are singular.
14
+ */
15
+ export const EXTERNAL_HYDRATION_LIMITS = {
16
+ [site.standard.document.$type]: { recommendationPreviews: 3 },
17
+ [site.standard.publication.$type]: { subscriberPreviews: 3 },
18
+ [social.grain.gallery.$type]: { items: 10, favoritePreviews: 3 },
19
+ };
20
+ /** Maximum in-flight backlink sample RPCs, not a dependency-count limit. */
21
+ export const MAX_CONCURRENT_BACKLINK_REQUESTS = 8;
22
+ /** Maximum logical batches per traversal, counting the root as pass 1. */
23
+ export const MAX_EXTERNAL_HYDRATION_PASSES = 8;
11
24
  export class ExternalHydrator {
12
- static { this.MAX_BACKLINK_PREVIEWS = 3; }
13
- static { this.MAX_BACKLINK_GALLERY_ITEMS = 10; }
14
- static { this.MAX_BACKLINK_FANOUT = 8; }
15
- /** Hard cap on generic batches per traversal, counting the root as pass 1. */
16
- static { this.MAX_EXTERNAL_HYDRATION_PASSES = 8; }
17
25
  /**
18
26
  * Entries per generic record RPC. The dataplane rejects larger URI lookups;
19
27
  * exact-ref lookups use the same bound defensively.
20
28
  */
21
29
  static { this.MAX_RECORDS_PER_REQUEST = 100; }
30
+ /**
31
+ * Target URIs per backlink-count RPC. The dataplane requires between 1 and
32
+ * 100; this is a separate limit from `MAX_RECORDS_PER_REQUEST`.
33
+ */
34
+ static { this.MAX_BACKLINK_COUNT_TARGETS_PER_REQUEST = 100; }
35
+ /** Target URIs per actor-backlink RPC, bounded by the dataplane. */
36
+ static { this.MAX_BACKLINK_ACTOR_TARGETS_PER_REQUEST = 100; }
22
37
  constructor(dataplane) {
23
38
  this.dataplane = dataplane;
24
39
  }
@@ -68,20 +83,24 @@ export class ExternalHydrator {
68
83
  cursor: res.cursor || undefined,
69
84
  };
70
85
  }
71
- /** Fetch source-record counts, optionally restricted to one collection. */
86
+ /**
87
+ * Fetch source-record counts, optionally restricted to one collection. Large
88
+ * inputs are fetched in sequential bounded requests; any failed request
89
+ * rejects the whole call.
90
+ */
72
91
  async getAtmosphereBacklinkCounts(targetUris, collection) {
73
92
  const map = new HydrationMap();
74
- if (!targetUris.length)
75
- return map;
76
- const res = await this.dataplane.getAtmosphereBacklinkCounts({
77
- targetUris,
78
- collection,
79
- });
80
- for (const result of res.results) {
81
- map.set(result.targetUri, Object.fromEntries(Object.entries(result.counts).map(([nsid, count]) => [
82
- nsid,
83
- Number(count),
84
- ])));
93
+ for (const chunk of chunkArray(targetUris, ExternalHydrator.MAX_BACKLINK_COUNT_TARGETS_PER_REQUEST)) {
94
+ const res = await this.dataplane.getAtmosphereBacklinkCounts({
95
+ targetUris: chunk,
96
+ collection,
97
+ });
98
+ for (const result of res.results) {
99
+ map.set(result.targetUri, Object.fromEntries(Object.entries(result.counts).map(([nsid, count]) => [
100
+ nsid,
101
+ Number(count),
102
+ ])));
103
+ }
85
104
  }
86
105
  return map;
87
106
  }
@@ -115,21 +134,6 @@ export class ExternalHydrator {
115
134
  }
116
135
  return { backlinks, truncated: res.truncated };
117
136
  }
118
- /**
119
- * Fetch exact `site.standard.{document,publication}` versions. Does NOT
120
- * resolve a document's publication; callers must pin it explicitly.
121
- */
122
- async getSiteStandardRecordsByRef(refs, includeTakedowns = false) {
123
- const ssRefs = refs.filter((ref) => !!ref.cid && siteStandardKind(ref.uri) !== undefined);
124
- const out = emptySiteStandardRecords();
125
- if (!ssRefs.length)
126
- return out;
127
- const records = await this.getRecordsByRef(ssRefs, includeTakedowns);
128
- for (const [key, info] of records) {
129
- setSiteStandardRecord(out, parseGenericRecordKey(key).uri, key, info);
130
- }
131
- return out;
132
- }
133
137
  }
134
138
  export function genericRecordKey({ uri, cid }) {
135
139
  if (cid === undefined)
@@ -180,9 +184,10 @@ export function actionExternalRecordTakedowns({ externalRecords, externalRecords
180
184
  * there is none. Only the owner reports, once, including on failure, with the
181
185
  * context's XRPC endpoint (`'unknown'` if unset) and the traversal's wall time. A
182
186
  * returned traversal is `capped` if it hit the pass limit, else `partial` if
183
- * it recovered from a dependency failure. Owners that completed without
184
- * scheduling a batch did no work and are not reported; other outcomes always
185
- * are.
187
+ * it recovered from a dependency failure. Owners that completed report when
188
+ * they scheduled a batch or inspected roots (even prehydrated or unavailable
189
+ * ones); only genuinely empty successful calls are not reported. Other
190
+ * outcomes always are.
186
191
  */
187
192
  export async function trackExternalHydration(root, xrpcEndpoint, hydrationMetrics, fn) {
188
193
  if (hydrationMetrics)
@@ -207,7 +212,7 @@ export async function trackExternalHydration(root, xrpcEndpoint, hydrationMetric
207
212
  return state;
208
213
  }
209
214
  finally {
210
- if (owned.batches || outcome !== 'completed') {
215
+ if (owned.batches > 0 || owned.roots > 0 || outcome !== 'completed') {
211
216
  events.externalHydrationTraversal({
212
217
  xrpcEndpoint: xrpcEndpoint ?? 'unknown',
213
218
  root,
@@ -251,10 +256,6 @@ function parseGenericRecord(result, includeTakedowns) {
251
256
  takedownRef: safeTakedownRef(entry),
252
257
  };
253
258
  }
254
- const emptySiteStandardRecords = () => ({
255
- documents: new HydrationMap(),
256
- publications: new HydrationMap(),
257
- });
258
259
  const siteStandardKind = (uri) => {
259
260
  const parsed = parseAtUriString(uri);
260
261
  if (!parsed.success)
@@ -277,82 +278,101 @@ const matchRecordInfo = (schema, info) => info && schema.$matches(info.record, {
277
278
  ? { ...info, record: info.record }
278
279
  : null;
279
280
  /**
280
- * Store a generic record in the map matching its collection. Records failing
281
- * Lexicon validation are stored as null.
281
+ * Select one pinned embed root. Legacy publication-first pairs may put their
282
+ * document second; no other authored refs participate in hydration.
282
283
  */
283
- const setSiteStandardRecord = (out, uri, key, info) => {
284
- switch (siteStandardKind(uri)) {
285
- case 'documents':
286
- out.documents.set(key, matchRecordInfo(site.standard.document.main, info));
287
- break;
288
- case 'publications':
289
- out.publications.set(key, matchRecordInfo(site.standard.publication.main, info));
290
- break;
284
+ export function getExternalRootRef(refs) {
285
+ let root = refs?.[0];
286
+ if (!root)
287
+ return undefined;
288
+ if (siteStandardKind(root.uri) === 'publications') {
289
+ const second = refs?.[1];
290
+ if (second && siteStandardKind(second.uri) === 'documents')
291
+ root = second;
291
292
  }
292
- };
293
- /**
294
- * Read-path resolution: caller pinned a set of `(uri, cid)` strongRefs in
295
- * the post at write time, and we honor those exact versions. Any pair
296
- * that doesn't structurally agree is rejected, so downstream callers can
297
- * trust the returned shape.
298
- *
299
- * Pairing rules:
300
- * - Both slots referenced: `doc.site` must equal `publication.ref.uri`,
301
- * else both come back `undefined`.
302
- * - Doc with at-uri `site` referenced but no matching publication ref:
303
- * reject the whole pairing (doc claims a publication that should have
304
- * been pinned, but wasn't).
305
- * - Loose doc (web-URL `site`) referenced: publication stays `undefined`.
306
- * - Only a publication referenced: document stays `undefined`.
307
- *
308
- * Each returned slot carries the matching `ref` so callers can recover
309
- * the owner DID for blob-cdn URL building, etc.
310
- */
311
- export const getSiteStandardRecordsFromHydrationMapsByRefs = (associatedRefs, documents, publications) => {
312
- if (!associatedRefs?.length) {
313
- return { document: undefined, publication: undefined };
293
+ return isHydratableAssociatedRef(root) ? root : undefined;
294
+ }
295
+ /** Select a pinned Standard.site root and its derived publication, if needed. */
296
+ export function getSiteStandardRecordsFromRefs(associatedRefs, records, dependencies) {
297
+ const empty = { document: undefined, publication: undefined };
298
+ const ref = getExternalRootRef(associatedRefs);
299
+ if (!ref)
300
+ return empty;
301
+ const info = records?.get(genericRecordKey(ref));
302
+ if (siteStandardKind(ref.uri) === 'publications') {
303
+ const publication = matchRecordInfo(site.standard.publication.main, info);
304
+ return publication
305
+ ? { document: undefined, publication: { ref, info: publication } }
306
+ : empty;
314
307
  }
315
- // Resolve each ref against the hydration maps, taking the first hit on
316
- // each side.
317
- let document;
318
- let publication;
319
- for (const ref of associatedRefs) {
320
- const key = genericRecordKey(ref);
321
- if (!document) {
322
- const hit = documents?.get(key);
323
- if (hit)
324
- document = { ref, info: hit };
325
- }
326
- if (!publication) {
327
- const hit = publications?.get(key);
328
- if (hit)
329
- publication = { ref, info: hit };
330
- }
331
- if (document && publication)
332
- break;
308
+ if (siteStandardKind(ref.uri) !== 'documents')
309
+ return empty;
310
+ const document = matchRecordInfo(site.standard.document.main, info);
311
+ if (!document)
312
+ return empty;
313
+ const documentSelection = { ref, info: document };
314
+ const docSite = document.record.site;
315
+ if (!docSite.startsWith('at://')) {
316
+ return { document: documentSelection, publication: undefined };
333
317
  }
334
- // Both refs resolved: enforce that the doc's `site` actually points at
335
- // the supplied publication. Mismatch means the post was misconstructed
336
- // (or tampered with), so reject the whole pairing.
337
- if (document && publication) {
338
- if (document.info.record.site !== publication.ref.uri) {
339
- hydrationLogger.warn({
340
- documentUri: document.ref.uri,
341
- documentSite: document.info.record.site,
342
- publicationUri: publication.ref.uri,
343
- }, 'site.standard byRefs lookup failed: doc.site does not match hydrated publication.uri');
344
- return { document: undefined, publication: undefined };
345
- }
318
+ const uri = recordUriOf(docSite, site.standard.publication.$type);
319
+ if (!uri)
320
+ return empty;
321
+ const publication = matchRecordInfo(site.standard.publication.main, dependencies?.get(uri));
322
+ if (!publication)
323
+ return empty;
324
+ return {
325
+ document: documentSelection,
326
+ publication: { ref: { uri, cid: publication.cid }, info: publication },
327
+ };
328
+ }
329
+ const externalAssociatedRefs = (post) => {
330
+ const embed = post?.embed;
331
+ if (!embed)
332
+ return [];
333
+ if (isExternalEmbedType(embed)) {
334
+ return embed.external.associatedRefs ?? [];
346
335
  }
347
- // Doc with at-uri `site` but no publication: the post should have
348
- // pinned the publication too. Treat as misconstructed.
349
- if (document && !publication) {
350
- const site = document.info.record.site;
351
- if (site && site.startsWith('at://')) {
352
- hydrationLogger.warn({ documentUri: document.ref.uri, documentSite: site }, 'site.standard byRefs lookup failed: document.site is AT URI but no matching publication was hydrated');
353
- return { document: undefined, publication: undefined };
336
+ if (isRecordWithMediaType(embed) && isExternalEmbedType(embed.media)) {
337
+ return embed.media.external.associatedRefs ?? [];
338
+ }
339
+ return [];
340
+ };
341
+ /**
342
+ * An exact ref needs a nonempty CID and a complete record URI in a DID repo,
343
+ * so malformed refs are skipped instead of becoming latest lookups.
344
+ */
345
+ const isHydratableAssociatedRef = (ref) => {
346
+ if (!ref.cid)
347
+ return false;
348
+ const parsed = parseAtUriString(ref.uri);
349
+ if (!parsed.success)
350
+ return false;
351
+ const { authority, collection, rkey, query, hash } = parsed.value;
352
+ return (isDidString(authority) &&
353
+ !!collection &&
354
+ !!rkey &&
355
+ query === undefined &&
356
+ hash === undefined);
357
+ };
358
+ /** Collect one root per post across all layers, deduped by exact ref. */
359
+ export const externalAssociatedRefsFromPosts = (...postLayers) => {
360
+ const seen = new Set();
361
+ const out = [];
362
+ for (const layer of postLayers) {
363
+ for (const item of layer.values()) {
364
+ if (!item)
365
+ continue;
366
+ const ref = getExternalRootRef(externalAssociatedRefs(item.record));
367
+ if (!ref)
368
+ continue;
369
+ const key = genericRecordKey(ref);
370
+ if (seen.has(key))
371
+ continue;
372
+ seen.add(key);
373
+ out.push({ uri: ref.uri, cid: ref.cid });
354
374
  }
355
375
  }
356
- return { document, publication };
376
+ return out;
357
377
  };
358
378
  //# sourceMappingURL=external.js.map