@atproto/bsky 0.1.6 → 0.2.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 (283) hide show
  1. package/CHANGELOG.md +58 -0
  2. package/dist/api/app/bsky/actor/getProfile.js +1 -1
  3. package/dist/api/app/bsky/actor/getProfile.js.map +1 -1
  4. package/dist/api/app/bsky/actor/getProfiles.js +1 -1
  5. package/dist/api/app/bsky/actor/getProfiles.js.map +1 -1
  6. package/dist/api/app/bsky/actor/getSuggestions.js +2 -2
  7. package/dist/api/app/bsky/actor/getSuggestions.js.map +1 -1
  8. package/dist/api/app/bsky/embed/getEmbedExternalView.d.ts.map +1 -1
  9. package/dist/api/app/bsky/embed/getEmbedExternalView.js +132 -53
  10. package/dist/api/app/bsky/embed/getEmbedExternalView.js.map +1 -1
  11. package/dist/api/app/bsky/feed/getAuthorFeed.d.ts.map +1 -1
  12. package/dist/api/app/bsky/feed/getAuthorFeed.js +4 -2
  13. package/dist/api/app/bsky/feed/getAuthorFeed.js.map +1 -1
  14. package/dist/api/app/bsky/graph/getSuggestedFollowsByActor.js +2 -2
  15. package/dist/api/app/bsky/graph/getSuggestedFollowsByActor.js.map +1 -1
  16. package/dist/api/app/bsky/notification/constants.d.ts +4 -1
  17. package/dist/api/app/bsky/notification/constants.d.ts.map +1 -1
  18. package/dist/api/app/bsky/notification/constants.js +3 -0
  19. package/dist/api/app/bsky/notification/constants.js.map +1 -1
  20. package/dist/api/app/bsky/notification/getGroupedNotifications.js +19 -7
  21. package/dist/api/app/bsky/notification/getGroupedNotifications.js.map +1 -1
  22. package/dist/api/app/bsky/notification/grouping/spotlight.d.ts +1 -1
  23. package/dist/api/app/bsky/notification/grouping/spotlight.d.ts.map +1 -1
  24. package/dist/api/app/bsky/notification/grouping/spotlight.js +114 -80
  25. package/dist/api/app/bsky/notification/grouping/spotlight.js.map +1 -1
  26. package/dist/api/app/bsky/notification/listActivitySubscriptions.js +3 -2
  27. package/dist/api/app/bsky/notification/listActivitySubscriptions.js.map +1 -1
  28. package/dist/api/app/bsky/unspecced/getAtmosphereExploreTab.d.ts +4 -0
  29. package/dist/api/app/bsky/unspecced/getAtmosphereExploreTab.d.ts.map +1 -0
  30. package/dist/api/app/bsky/unspecced/getAtmosphereExploreTab.js +142 -0
  31. package/dist/api/app/bsky/unspecced/getAtmosphereExploreTab.js.map +1 -0
  32. package/dist/api/index.d.ts.map +1 -1
  33. package/dist/api/index.js +2 -0
  34. package/dist/api/index.js.map +1 -1
  35. package/dist/api/internal/bsky/actor/getProfiles.js +4 -1
  36. package/dist/api/internal/bsky/actor/getProfiles.js.map +1 -1
  37. package/dist/config.d.ts +4 -0
  38. package/dist/config.d.ts.map +1 -1
  39. package/dist/config.js +12 -0
  40. package/dist/config.js.map +1 -1
  41. package/dist/data-plane/server/indexing/index.d.ts +3 -1
  42. package/dist/data-plane/server/indexing/index.d.ts.map +1 -1
  43. package/dist/data-plane/server/indexing/index.js +2 -0
  44. package/dist/data-plane/server/indexing/index.js.map +1 -1
  45. package/dist/data-plane/server/indexing/plugins/profile-link.d.ts +8 -0
  46. package/dist/data-plane/server/indexing/plugins/profile-link.d.ts.map +1 -0
  47. package/dist/data-plane/server/indexing/plugins/profile-link.js +30 -0
  48. package/dist/data-plane/server/indexing/plugins/profile-link.js.map +1 -0
  49. package/dist/data-plane/server/routes/records.d.ts.map +1 -1
  50. package/dist/data-plane/server/routes/records.js +1 -0
  51. package/dist/data-plane/server/routes/records.js.map +1 -1
  52. package/dist/hydration/actor.d.ts +4 -1
  53. package/dist/hydration/actor.d.ts.map +1 -1
  54. package/dist/hydration/actor.js +11 -0
  55. package/dist/hydration/actor.js.map +1 -1
  56. package/dist/hydration/external.d.ts +74 -70
  57. package/dist/hydration/external.d.ts.map +1 -1
  58. package/dist/hydration/external.js +79 -133
  59. package/dist/hydration/external.js.map +1 -1
  60. package/dist/hydration/hydrator.d.ts +57 -14
  61. package/dist/hydration/hydrator.d.ts.map +1 -1
  62. package/dist/hydration/hydrator.js +417 -105
  63. package/dist/hydration/hydrator.js.map +1 -1
  64. package/dist/lexicons/app/bsky/actor/defs.defs.d.ts +24 -0
  65. package/dist/lexicons/app/bsky/actor/defs.defs.d.ts.map +1 -1
  66. package/dist/lexicons/app/bsky/actor/defs.defs.js +13 -0
  67. package/dist/lexicons/app/bsky/actor/defs.defs.js.map +1 -1
  68. package/dist/lexicons/app/bsky/actor/link.d.ts +3 -0
  69. package/dist/lexicons/app/bsky/actor/link.d.ts.map +1 -0
  70. package/dist/lexicons/app/bsky/actor/link.defs.d.ts +105 -0
  71. package/dist/lexicons/app/bsky/actor/link.defs.d.ts.map +1 -0
  72. package/dist/lexicons/app/bsky/actor/link.defs.js +34 -0
  73. package/dist/lexicons/app/bsky/actor/link.defs.js.map +1 -0
  74. package/dist/lexicons/app/bsky/actor/link.js +6 -0
  75. package/dist/lexicons/app/bsky/actor/link.js.map +1 -0
  76. package/dist/lexicons/app/bsky/actor/profile.defs.d.ts +14 -0
  77. package/dist/lexicons/app/bsky/actor/profile.defs.d.ts.map +1 -1
  78. package/dist/lexicons/app/bsky/actor/profile.defs.js +3 -0
  79. package/dist/lexicons/app/bsky/actor/profile.defs.js.map +1 -1
  80. package/dist/lexicons/app/bsky/actor.d.ts +1 -0
  81. package/dist/lexicons/app/bsky/actor.d.ts.map +1 -1
  82. package/dist/lexicons/app/bsky/actor.js +1 -0
  83. package/dist/lexicons/app/bsky/actor.js.map +1 -1
  84. package/dist/lexicons/app/bsky/authFullApp.defs.d.ts.map +1 -1
  85. package/dist/lexicons/app/bsky/authFullApp.defs.js +1 -0
  86. package/dist/lexicons/app/bsky/authFullApp.defs.js.map +1 -1
  87. package/dist/lexicons/app/bsky/authManageProfile.defs.d.ts.map +1 -1
  88. package/dist/lexicons/app/bsky/authManageProfile.defs.js +1 -0
  89. package/dist/lexicons/app/bsky/authManageProfile.defs.js.map +1 -1
  90. package/dist/lexicons/app/bsky/embed/external.defs.d.ts +130 -0
  91. package/dist/lexicons/app/bsky/embed/external.defs.d.ts.map +1 -1
  92. package/dist/lexicons/app/bsky/embed/external.defs.js +135 -0
  93. package/dist/lexicons/app/bsky/embed/external.defs.js.map +1 -1
  94. package/dist/lexicons/app/bsky/embed/getEmbedExternalView.defs.d.ts +15 -3
  95. package/dist/lexicons/app/bsky/embed/getEmbedExternalView.defs.d.ts.map +1 -1
  96. package/dist/lexicons/app/bsky/embed/getEmbedExternalView.defs.js +18 -3
  97. package/dist/lexicons/app/bsky/embed/getEmbedExternalView.defs.js.map +1 -1
  98. package/dist/lexicons/app/bsky/notification/getGroupedNotifications.defs.d.ts +62 -3
  99. package/dist/lexicons/app/bsky/notification/getGroupedNotifications.defs.d.ts.map +1 -1
  100. package/dist/lexicons/app/bsky/notification/getGroupedNotifications.defs.js +53 -2
  101. package/dist/lexicons/app/bsky/notification/getGroupedNotifications.defs.js.map +1 -1
  102. package/dist/lexicons/app/bsky/unspecced/getAtmosphereExploreTab.d.ts +3 -0
  103. package/dist/lexicons/app/bsky/unspecced/getAtmosphereExploreTab.d.ts.map +1 -0
  104. package/dist/lexicons/app/bsky/unspecced/getAtmosphereExploreTab.defs.d.ts +103 -0
  105. package/dist/lexicons/app/bsky/unspecced/getAtmosphereExploreTab.defs.d.ts.map +1 -0
  106. package/dist/lexicons/app/bsky/unspecced/getAtmosphereExploreTab.defs.js +95 -0
  107. package/dist/lexicons/app/bsky/unspecced/getAtmosphereExploreTab.defs.js.map +1 -0
  108. package/dist/lexicons/app/bsky/unspecced/getAtmosphereExploreTab.js +6 -0
  109. package/dist/lexicons/app/bsky/unspecced/getAtmosphereExploreTab.js.map +1 -0
  110. package/dist/lexicons/app/bsky/unspecced.d.ts +1 -0
  111. package/dist/lexicons/app/bsky/unspecced.d.ts.map +1 -1
  112. package/dist/lexicons/app/bsky/unspecced.js +1 -0
  113. package/dist/lexicons/app/bsky/unspecced.js.map +1 -1
  114. package/dist/lexicons/index.d.ts +2 -0
  115. package/dist/lexicons/index.d.ts.map +1 -1
  116. package/dist/lexicons/index.js +2 -0
  117. package/dist/lexicons/index.js.map +1 -1
  118. package/dist/lexicons/place/stream/badge/defs.d.ts +2 -0
  119. package/dist/lexicons/place/stream/badge/defs.d.ts.map +1 -0
  120. package/dist/lexicons/place/stream/badge/defs.defs.d.ts +131 -0
  121. package/dist/lexicons/place/stream/badge/defs.defs.d.ts.map +1 -0
  122. package/dist/lexicons/place/stream/badge/defs.defs.js +73 -0
  123. package/dist/lexicons/place/stream/badge/defs.defs.js.map +1 -0
  124. package/dist/lexicons/place/stream/badge/defs.js +5 -0
  125. package/dist/lexicons/place/stream/badge/defs.js.map +1 -0
  126. package/dist/lexicons/place/stream/badge.d.ts +2 -0
  127. package/dist/lexicons/place/stream/badge.d.ts.map +1 -0
  128. package/dist/lexicons/place/stream/badge.js +5 -0
  129. package/dist/lexicons/place/stream/badge.js.map +1 -0
  130. package/dist/lexicons/place/stream/chat/defs.d.ts +2 -0
  131. package/dist/lexicons/place/stream/chat/defs.d.ts.map +1 -0
  132. package/dist/lexicons/place/stream/chat/defs.defs.d.ts +44 -0
  133. package/dist/lexicons/place/stream/chat/defs.defs.d.ts.map +1 -0
  134. package/dist/lexicons/place/stream/chat/defs.defs.js +41 -0
  135. package/dist/lexicons/place/stream/chat/defs.defs.js.map +1 -0
  136. package/dist/lexicons/place/stream/chat/defs.js +5 -0
  137. package/dist/lexicons/place/stream/chat/defs.js.map +1 -0
  138. package/dist/lexicons/place/stream/chat/pinnedRecord.d.ts +3 -0
  139. package/dist/lexicons/place/stream/chat/pinnedRecord.d.ts.map +1 -0
  140. package/dist/lexicons/place/stream/chat/pinnedRecord.defs.d.ts +108 -0
  141. package/dist/lexicons/place/stream/chat/pinnedRecord.defs.d.ts.map +1 -0
  142. package/dist/lexicons/place/stream/chat/pinnedRecord.defs.js +31 -0
  143. package/dist/lexicons/place/stream/chat/pinnedRecord.defs.js.map +1 -0
  144. package/dist/lexicons/place/stream/chat/pinnedRecord.js +6 -0
  145. package/dist/lexicons/place/stream/chat/pinnedRecord.js.map +1 -0
  146. package/dist/lexicons/place/stream/chat/profile.d.ts +3 -0
  147. package/dist/lexicons/place/stream/chat/profile.d.ts.map +1 -0
  148. package/dist/lexicons/place/stream/chat/profile.defs.d.ts +143 -0
  149. package/dist/lexicons/place/stream/chat/profile.defs.d.ts.map +1 -0
  150. package/dist/lexicons/place/stream/chat/profile.defs.js +62 -0
  151. package/dist/lexicons/place/stream/chat/profile.defs.js.map +1 -0
  152. package/dist/lexicons/place/stream/chat/profile.js +6 -0
  153. package/dist/lexicons/place/stream/chat/profile.js.map +1 -0
  154. package/dist/lexicons/place/stream/chat.d.ts +4 -0
  155. package/dist/lexicons/place/stream/chat.d.ts.map +1 -0
  156. package/dist/lexicons/place/stream/chat.js +7 -0
  157. package/dist/lexicons/place/stream/chat.js.map +1 -0
  158. package/dist/lexicons/place/stream/defs.d.ts +2 -0
  159. package/dist/lexicons/place/stream/defs.d.ts.map +1 -0
  160. package/dist/lexicons/place/stream/defs.defs.d.ts +54 -0
  161. package/dist/lexicons/place/stream/defs.defs.d.ts.map +1 -0
  162. package/dist/lexicons/place/stream/defs.defs.js +40 -0
  163. package/dist/lexicons/place/stream/defs.defs.js.map +1 -0
  164. package/dist/lexicons/place/stream/defs.js +5 -0
  165. package/dist/lexicons/place/stream/defs.js.map +1 -0
  166. package/dist/lexicons/place/stream/livestream.d.ts +3 -0
  167. package/dist/lexicons/place/stream/livestream.d.ts.map +1 -0
  168. package/dist/lexicons/place/stream/livestream.defs.d.ts +312 -0
  169. package/dist/lexicons/place/stream/livestream.defs.d.ts.map +1 -0
  170. package/dist/lexicons/place/stream/livestream.defs.js +105 -0
  171. package/dist/lexicons/place/stream/livestream.defs.js.map +1 -0
  172. package/dist/lexicons/place/stream/livestream.js +6 -0
  173. package/dist/lexicons/place/stream/livestream.js.map +1 -0
  174. package/dist/lexicons/place/stream.d.ts +5 -0
  175. package/dist/lexicons/place/stream.d.ts.map +1 -0
  176. package/dist/lexicons/place/stream.js +8 -0
  177. package/dist/lexicons/place/stream.js.map +1 -0
  178. package/dist/lexicons/place.d.ts +2 -0
  179. package/dist/lexicons/place.d.ts.map +1 -0
  180. package/dist/lexicons/place.js +5 -0
  181. package/dist/lexicons/place.js.map +1 -0
  182. package/dist/lexicons/site/standard/document.defs.d.ts +127 -127
  183. package/dist/lexicons/site/standard/document.defs.d.ts.map +1 -1
  184. package/dist/lexicons/site/standard/document.defs.js +28 -28
  185. package/dist/lexicons/site/standard/document.defs.js.map +1 -1
  186. package/dist/lexicons/site/standard/graph/recommend.defs.d.ts +11 -11
  187. package/dist/lexicons/site/standard/graph/recommend.defs.d.ts.map +1 -1
  188. package/dist/lexicons/site/standard/graph/recommend.defs.js +1 -1
  189. package/dist/lexicons/site/standard/graph/recommend.defs.js.map +1 -1
  190. package/dist/lexicons/site/standard/publication.defs.d.ts +52 -52
  191. package/dist/lexicons/site/standard/publication.defs.d.ts.map +1 -1
  192. package/dist/lexicons/site/standard/publication.defs.js +6 -6
  193. package/dist/lexicons/site/standard/publication.defs.js.map +1 -1
  194. package/dist/lexicons/site/standard/theme/basic.defs.d.ts +14 -14
  195. package/dist/lexicons/site/standard/theme/basic.defs.d.ts.map +1 -1
  196. package/dist/lexicons/site/standard/theme/basic.defs.js +1 -1
  197. package/dist/lexicons/site/standard/theme/basic.defs.js.map +1 -1
  198. package/dist/lexicons/social/grain/defs.d.ts +2 -0
  199. package/dist/lexicons/social/grain/defs.d.ts.map +1 -0
  200. package/dist/lexicons/social/grain/defs.defs.d.ts +15 -0
  201. package/dist/lexicons/social/grain/defs.defs.d.ts.map +1 -0
  202. package/dist/lexicons/social/grain/defs.defs.js +14 -0
  203. package/dist/lexicons/social/grain/defs.defs.js.map +1 -0
  204. package/dist/lexicons/social/grain/defs.js +5 -0
  205. package/dist/lexicons/social/grain/defs.js.map +1 -0
  206. package/dist/lexicons/social/grain/favorite.d.ts +3 -0
  207. package/dist/lexicons/social/grain/favorite.d.ts.map +1 -0
  208. package/dist/lexicons/social/grain/favorite.defs.d.ts +72 -0
  209. package/dist/lexicons/social/grain/favorite.defs.d.ts.map +1 -0
  210. package/dist/lexicons/social/grain/favorite.defs.js +26 -0
  211. package/dist/lexicons/social/grain/favorite.defs.js.map +1 -0
  212. package/dist/lexicons/social/grain/favorite.js +6 -0
  213. package/dist/lexicons/social/grain/favorite.js.map +1 -0
  214. package/dist/lexicons/social/grain/gallery/item.d.ts +3 -0
  215. package/dist/lexicons/social/grain/gallery/item.d.ts.map +1 -0
  216. package/dist/lexicons/social/grain/gallery/item.defs.d.ts +94 -0
  217. package/dist/lexicons/social/grain/gallery/item.defs.d.ts.map +1 -0
  218. package/dist/lexicons/social/grain/gallery/item.defs.js +29 -0
  219. package/dist/lexicons/social/grain/gallery/item.defs.js.map +1 -0
  220. package/dist/lexicons/social/grain/gallery/item.js +6 -0
  221. package/dist/lexicons/social/grain/gallery/item.js.map +1 -0
  222. package/dist/lexicons/social/grain/gallery.d.ts +4 -0
  223. package/dist/lexicons/social/grain/gallery.d.ts.map +1 -0
  224. package/dist/lexicons/social/grain/gallery.defs.d.ts +98 -0
  225. package/dist/lexicons/social/grain/gallery.defs.d.ts.map +1 -0
  226. package/dist/lexicons/social/grain/gallery.defs.js +33 -0
  227. package/dist/lexicons/social/grain/gallery.defs.js.map +1 -0
  228. package/dist/lexicons/social/grain/gallery.js +7 -0
  229. package/dist/lexicons/social/grain/gallery.js.map +1 -0
  230. package/dist/lexicons/social/grain/photo.d.ts +3 -0
  231. package/dist/lexicons/social/grain/photo.d.ts.map +1 -0
  232. package/dist/lexicons/social/grain/photo.defs.d.ts +98 -0
  233. package/dist/lexicons/social/grain/photo.defs.d.ts.map +1 -0
  234. package/dist/lexicons/social/grain/photo.defs.js +31 -0
  235. package/dist/lexicons/social/grain/photo.defs.js.map +1 -0
  236. package/dist/lexicons/social/grain/photo.js +6 -0
  237. package/dist/lexicons/social/grain/photo.js.map +1 -0
  238. package/dist/lexicons/social/grain.d.ts +5 -0
  239. package/dist/lexicons/social/grain.d.ts.map +1 -0
  240. package/dist/lexicons/social/grain.js +8 -0
  241. package/dist/lexicons/social/grain.js.map +1 -0
  242. package/dist/lexicons/social.d.ts +2 -0
  243. package/dist/lexicons/social.d.ts.map +1 -0
  244. package/dist/lexicons/social.js +5 -0
  245. package/dist/lexicons/social.js.map +1 -0
  246. package/dist/proto/bsky_connect.d.ts +10 -1
  247. package/dist/proto/bsky_connect.d.ts.map +1 -1
  248. package/dist/proto/bsky_connect.js +10 -1
  249. package/dist/proto/bsky_connect.js.map +1 -1
  250. package/dist/proto/bsky_pb.d.ts +34 -0
  251. package/dist/proto/bsky_pb.d.ts.map +1 -1
  252. package/dist/proto/bsky_pb.js +60 -0
  253. package/dist/proto/bsky_pb.js.map +1 -1
  254. package/dist/telemetry/events.d.ts +30 -0
  255. package/dist/telemetry/events.d.ts.map +1 -1
  256. package/dist/telemetry/events.js +37 -0
  257. package/dist/telemetry/events.js.map +1 -1
  258. package/dist/util/external/index.d.ts +8 -0
  259. package/dist/util/external/index.d.ts.map +1 -0
  260. package/dist/util/external/index.js +50 -0
  261. package/dist/util/external/index.js.map +1 -0
  262. package/dist/util/{standard-site.d.ts → external/standard-site.d.ts} +30 -4
  263. package/dist/util/external/standard-site.d.ts.map +1 -0
  264. package/dist/util/{standard-site.js → external/standard-site.js} +73 -4
  265. package/dist/util/external/standard-site.js.map +1 -0
  266. package/dist/views/external.d.ts +8 -0
  267. package/dist/views/external.d.ts.map +1 -0
  268. package/dist/views/external.js +260 -0
  269. package/dist/views/external.js.map +1 -0
  270. package/dist/views/index.d.ts +12 -6
  271. package/dist/views/index.d.ts.map +1 -1
  272. package/dist/views/index.js +89 -42
  273. package/dist/views/index.js.map +1 -1
  274. package/dist/views/profile-link-rules.d.ts +10 -0
  275. package/dist/views/profile-link-rules.d.ts.map +1 -0
  276. package/dist/views/profile-link-rules.js +48 -0
  277. package/dist/views/profile-link-rules.js.map +1 -0
  278. package/dist/views/types.d.ts +3 -0
  279. package/dist/views/types.d.ts.map +1 -1
  280. package/dist/views/types.js.map +1 -1
  281. package/package.json +4 -4
  282. package/dist/util/standard-site.d.ts.map +0 -1
  283. package/dist/util/standard-site.js.map +0 -1
@@ -3,25 +3,15 @@ import { parseAtUriString } from '@atproto/syntax';
3
3
  import { site } from '../lexicons/index.js';
4
4
  import { hydrationLogger } from '../logger.js';
5
5
  import { RecordLookupStatus, } from '../proto/bsky_pb.js';
6
+ import { events, } from '../telemetry/events.js';
7
+ import { uriToDid } from '../util/uris.js';
6
8
  import { HydrationMap, parseDate, safeTakedownRef, } from './util.js';
7
- /**
8
- * Composes a stable map key from an `(uri, cid)` pair. A single hydration
9
- * batch can pull more than one version of the same record URI (different
10
- * posts pinning different cids), so the composite is needed for O(1)
11
- * version-exact lookups.
12
- */
13
- export function genericRecordKey(uri, cid) {
14
- return `${uri}@${cid}`;
15
- }
16
- /** Recover the URI and CID from a composite hydration key. */
17
- export function parseGenericRecordKey(key) {
18
- const at = key.lastIndexOf('@');
19
- return {
20
- uri: key.slice(0, at),
21
- cid: key.slice(at + 1),
22
- };
23
- }
24
9
  export class ExternalHydrator {
10
+ static { this.MAX_BACKLINK_PREVIEWS = 3; }
11
+ static { this.MAX_BACKLINK_GALLERY_ITEMS = 10; }
12
+ static { this.MAX_BACKLINK_FANOUT = 8; }
13
+ /** Hard cap on generic batches per traversal, counting the root as pass 1. */
14
+ static { this.MAX_EXTERNAL_HYDRATION_PASSES = 8; }
25
15
  constructor(dataplane) {
26
16
  this.dataplane = dataplane;
27
17
  }
@@ -32,8 +22,7 @@ export class ExternalHydrator {
32
22
  return map;
33
23
  const res = await this.dataplane.getRecordsByRef({ refs });
34
24
  for (let i = 0; i < refs.length; i++) {
35
- const { uri, cid } = refs[i];
36
- map.set(genericRecordKey(uri, cid), parseGenericRecord(res.results[i], includeTakedowns) ?? null);
25
+ map.set(genericRecordKey(refs[i]), parseGenericRecord(res.results[i], includeTakedowns) ?? null);
37
26
  }
38
27
  return map;
39
28
  }
@@ -124,38 +113,77 @@ export class ExternalHydrator {
124
113
  }
125
114
  return out;
126
115
  }
127
- /**
128
- * Fetch the latest `site.standard.{document,publication}` versions. The
129
- * generic record lookup does not follow references, so publications named
130
- * by the `site` field of the hydrated documents are fetched in a second
131
- * call.
132
- */
133
- async getSiteStandardRecordsByURI(uris, includeTakedowns = false) {
134
- const requested = [...new Set(uris.filter((u) => siteStandardKind(u)))];
135
- const out = emptySiteStandardRecords();
136
- if (!requested.length)
137
- return out;
138
- await this.addSiteStandardRecordsByURI(out, requested, includeTakedowns);
139
- // Publications referenced by documents but not already requested.
140
- const requestedSet = new Set(requested);
141
- const pubUris = new Set();
142
- for (const doc of out.documents.values()) {
143
- const pubUri = doc && publicationUriFromSite(doc.record.site);
144
- if (pubUri && !requestedSet.has(pubUri))
145
- pubUris.add(pubUri);
146
- }
147
- if (pubUris.size) {
148
- await this.addSiteStandardRecordsByURI(out, [...pubUris], includeTakedowns);
116
+ }
117
+ export function genericRecordKey({ uri, cid }) {
118
+ if (cid === undefined)
119
+ return uri;
120
+ if (!cid)
121
+ throw new Error(`Empty CID in record key for ${uri}`);
122
+ return `${uri}@${cid}`;
123
+ }
124
+ /**
125
+ * Recover the URI and CID from an exact record key, splitting at the last `@`.
126
+ * Throws if either part is missing. Components are trusted, not revalidated.
127
+ */
128
+ export function parseGenericRecordKey(key) {
129
+ const at = key.lastIndexOf('@');
130
+ if (at <= 0 || at === key.length - 1) {
131
+ throw new Error(`Malformed exact record key: ${key}`);
132
+ }
133
+ return {
134
+ uri: key.slice(0, at),
135
+ cid: key.slice(at + 1),
136
+ };
137
+ }
138
+ /**
139
+ * Null generic external records (in both the URI-keyed and exact-ref maps,
140
+ * keeping their keys) that are taken down by an actionable label, unless
141
+ * takedowns are included, or whose owner is explicitly unavailable. Applies to
142
+ * each record independently; counts and other records are unaffected.
143
+ */
144
+ export function actionExternalRecordTakedowns({ externalRecords, externalRecordsByRef, actors, labels, }, includeTakedowns) {
145
+ // An absent actor entry was not hydrated; only `null` means unavailable.
146
+ const isHidden = (uri) => actors?.get(uriToDid(uri)) === null ||
147
+ (!includeTakedowns && labels?.get(uri)?.isTakendown);
148
+ for (const [uri, info] of externalRecords ?? []) {
149
+ if (!info || !isHidden(uri))
150
+ continue;
151
+ externalRecords?.set(uri, null);
152
+ externalRecordsByRef?.set(genericRecordKey({ uri, cid: info.cid }), null);
153
+ }
154
+ // Every exact version is checked on its own; versions are never collapsed.
155
+ for (const [key, info] of externalRecordsByRef ?? []) {
156
+ if (info && isHidden(parseGenericRecordKey(key).uri)) {
157
+ externalRecordsByRef?.set(key, null);
149
158
  }
150
- return out;
151
159
  }
152
- async addSiteStandardRecordsByURI(out, uris, includeTakedowns) {
153
- const records = await this.getRecordsByURI(uris, includeTakedowns);
154
- for (const [uri, info] of records) {
155
- // Unavailable records have no CID to key on, so they are left out.
156
- if (!info)
157
- continue;
158
- setSiteStandardRecord(out, uri, genericRecordKey(uri, info.cid), info);
160
+ }
161
+ /**
162
+ * Run `fn` with the caller's tracker, or as the owner of a new traversal when
163
+ * there is none. Only the owner reports, once, including on failure. Owners
164
+ * that completed without scheduling a batch did no work and are not reported;
165
+ * caps and failures always are.
166
+ */
167
+ export async function trackExternalHydration(root, hydrationMetrics, fn) {
168
+ if (hydrationMetrics)
169
+ return fn(hydrationMetrics);
170
+ const owned = { recordLookups: 0, batches: 0, maxPass: 0, capped: false };
171
+ let outcome = 'failed';
172
+ try {
173
+ const state = await fn(owned);
174
+ outcome = owned.capped ? 'capped' : 'completed';
175
+ return state;
176
+ }
177
+ finally {
178
+ if (owned.batches || outcome !== 'completed') {
179
+ const { recordLookups, batches, maxPass } = owned;
180
+ events.externalHydrationTraversal({
181
+ root,
182
+ outcome,
183
+ recordLookups,
184
+ batches,
185
+ maxPass,
186
+ });
159
187
  }
160
188
  }
161
189
  }
@@ -203,14 +231,6 @@ const siteStandardKind = (uri) => {
203
231
  return undefined;
204
232
  }
205
233
  };
206
- /** The AT-URI of the publication a document's `site` field points at. */
207
- const publicationUriFromSite = (value) => {
208
- const parsed = parseAtUriString(value);
209
- return parsed.success &&
210
- parsed.value.collection === site.standard.publication.$type
211
- ? value
212
- : undefined;
213
- };
214
234
  /**
215
235
  * Generic record bodies are unvalidated, so check them against the Lexicon
216
236
  * before exposing typed fields. Parse mode is not used, to preserve the
@@ -239,14 +259,6 @@ const setSiteStandardRecord = (out, uri, key, info) => {
239
259
  * that doesn't structurally agree is rejected, so downstream callers can
240
260
  * trust the returned shape.
241
261
  *
242
- * Same observable contract as
243
- * `getSiteStandardRecordsFromHydrationMapsByDocumentUri` (the compose-path
244
- * sister) — both functions guarantee that a returned `(doc, pub)` pair
245
- * has matching site/uri, and reject orphan docs that claim a
246
- * non-hydrated publication. They differ only in how upstream availability
247
- * is asserted: this one trusts caller-supplied refs; the sister derives
248
- * everything from the dataplane response.
249
- *
250
262
  * Pairing rules:
251
263
  * - Both slots referenced: `doc.site` must equal `publication.ref.uri`,
252
264
  * else both come back `undefined`.
@@ -268,7 +280,7 @@ export const getSiteStandardRecordsFromHydrationMapsByRefs = (associatedRefs, do
268
280
  let document;
269
281
  let publication;
270
282
  for (const ref of associatedRefs) {
271
- const key = genericRecordKey(ref.uri, ref.cid);
283
+ const key = genericRecordKey(ref);
272
284
  if (!document) {
273
285
  const hit = documents?.get(key);
274
286
  if (hit)
@@ -296,8 +308,7 @@ export const getSiteStandardRecordsFromHydrationMapsByRefs = (associatedRefs, do
296
308
  }
297
309
  }
298
310
  // Doc with at-uri `site` but no publication: the post should have
299
- // pinned the publication too. Treat as misconstructed — same contract
300
- // as the compose-path lookup.
311
+ // pinned the publication too. Treat as misconstructed.
301
312
  if (document && !publication) {
302
313
  const site = document.info.record.site;
303
314
  if (site && site.startsWith('at://')) {
@@ -307,69 +318,4 @@ export const getSiteStandardRecordsFromHydrationMapsByRefs = (associatedRefs, do
307
318
  }
308
319
  return { document, publication };
309
320
  };
310
- /**
311
- * Compose-path resolution: no caller-supplied refs — the dataplane
312
- * returned the latest version of each record (including any
313
- * publications it auto-resolved from a document's `site` field). Take
314
- * the first hydrated document and pair it with the publication its
315
- * `site` field points at.
316
- *
317
- * Same observable contract as
318
- * `getSiteStandardRecordsFromHydrationMapsByRefs` (the read-path
319
- * sister) — both functions guarantee that a returned `(doc, pub)` pair
320
- * has matching site/uri, and reject orphan docs that claim a
321
- * non-hydrated publication. They differ only in how upstream
322
- * availability is asserted: this one walks whatever was returned by the
323
- * dataplane; the sister checks against caller-supplied refs.
324
- *
325
- * Pairing rules:
326
- * - Doc with at-uri `site`: must find a hydrated publication at that
327
- * URI. If none was hydrated, the doc/publication chain is incomplete
328
- * and the function returns `undefined` for both slots; the doc alone
329
- * isn't useful without its source (can't verify the pub)
330
- * - Doc with web-URL `site` (loose): no publication.
331
- * - No doc hydrated: fall through to the first hydrated publication for
332
- * the publication-only resolution flow.
333
- */
334
- export const getSiteStandardRecordsFromHydrationMapsByDocumentUri = (documents, publications) => {
335
- // First hydrated doc.
336
- let document;
337
- for (const [key, info] of documents ?? []) {
338
- if (!info)
339
- continue;
340
- document = { ref: parseGenericRecordKey(key), info };
341
- break;
342
- }
343
- let publication;
344
- if (document) {
345
- const site = document.info.record.site;
346
- if (site && site.startsWith('at://')) {
347
- // Doc declared an at-uri publication; we need it.
348
- for (const [key, info] of publications ?? []) {
349
- if (!info)
350
- continue;
351
- const ref = parseGenericRecordKey(key);
352
- if (ref.uri === site) {
353
- publication = { ref, info };
354
- break;
355
- }
356
- }
357
- if (!publication) {
358
- hydrationLogger.warn({ documentUri: document.ref.uri, documentSite: site }, 'site.standard byDocumentUri lookup failed: document.site is AT URI but no matching publication was hydrated');
359
- return { document: undefined, publication: undefined };
360
- }
361
- }
362
- // else: loose doc (web-URL site), no publication needed.
363
- }
364
- else {
365
- // Publication-only flow: no doc, take the first hydrated publication.
366
- for (const [key, info] of publications ?? []) {
367
- if (!info)
368
- continue;
369
- publication = { ref: parseGenericRecordKey(key), info };
370
- break;
371
- }
372
- }
373
- return { document, publication };
374
- };
375
321
  //# sourceMappingURL=external.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"external.js","sourceRoot":"","sources":["../../src/hydration/external.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n type AtUriString,\n type DidString,\n type InferInput,\n type NsidString,\n type RecordSchema,\n type TypedLexMap,\n isTypedLexMap,\n lexParseJsonBytes,\n} from '@atproto/lex'\nimport { parseAtUriString } from '@atproto/syntax'\nimport type { DataPlaneClient } from '../data-plane/client/index.js'\nimport { site } from '../lexicons/index.js'\nimport { hydrationLogger } from '../logger.js'\nimport {\n type RecordLookupResult,\n RecordLookupStatus,\n} from '../proto/bsky_pb.js'\nimport type {\n SiteStandardDocumentRecord,\n SiteStandardPublicationRecord,\n} from '../views/types.js'\nimport {\n HydrationMap,\n type ItemRef,\n type RecordInfo,\n parseDate,\n safeTakedownRef,\n} from './util.js'\n\n/** Generic record bodies are decoded, but not validated against a Lexicon. */\nexport type GenericRecord = RecordInfo<TypedLexMap>\nexport type GenericRecords = HydrationMap<AtUriString, GenericRecord>\n/** Keyed by `genericRecordKey(uri, cid)` to retain multiple versions of a URI. */\nexport type GenericRecordsByRef = HydrationMap<string, GenericRecord>\n\nexport type AtmosphereActivityItem = {\n uri: AtUriString\n sortedAt: Date\n}\n\nexport type AtmosphereTimeline = {\n items: AtmosphereActivityItem[]\n cursor?: string\n}\n\nexport type AtmosphereBacklinks = {\n backlinks: AtmosphereActivityItem[]\n cursor?: string\n}\n\nexport type AtmosphereBacklinkCounts = HydrationMap<\n AtUriString,\n Partial<Record<NsidString, number>>\n>\n\nexport type AtmosphereBacklinksByActor = {\n backlinks: HydrationMap<AtUriString, AtUriString[]>\n truncated: boolean\n}\n\n/**\n * Composes a stable map key from an `(uri, cid)` pair. A single hydration\n * batch can pull more than one version of the same record URI (different\n * posts pinning different cids), so the composite is needed for O(1)\n * version-exact lookups.\n */\nexport function genericRecordKey(uri: AtUriString, cid: string): string {\n return `${uri}@${cid}`\n}\n\n/** Recover the URI and CID from a composite hydration key. */\nexport function parseGenericRecordKey(key: string): {\n uri: AtUriString\n cid: string\n} {\n const at = key.lastIndexOf('@')\n return {\n uri: key.slice(0, at) as AtUriString,\n cid: key.slice(at + 1),\n }\n}\n\nexport type SiteStandardDocument = RecordInfo<SiteStandardDocumentRecord>\nexport type SiteStandardPublication = RecordInfo<SiteStandardPublicationRecord>\n\n/**\n * Keyed by `${uri}@${cid}` — see `genericRecordKey`. A single hydration\n * batch can pull more than one version of the same URI (different posts\n * pinning different cids), so the composite key is needed for O(1)\n * version-exact lookups.\n */\nexport type SiteStandardDocuments = HydrationMap<string, SiteStandardDocument>\n/**\n * Keyed by `${uri}@${cid}`. See `SiteStandardDocuments` for the rationale.\n */\nexport type SiteStandardPublications = HydrationMap<\n string,\n SiteStandardPublication\n>\nexport type SiteStandardRecords = {\n documents: SiteStandardDocuments\n publications: SiteStandardPublications\n}\n\nexport type AssociatedSiteStandardRecord<T> = {\n ref: { uri: AtUriString; cid: string }\n info: T\n}\n\nexport class ExternalHydrator {\n constructor(public dataplane: DataPlaneClient) {}\n\n /** Fetch exact record versions; unavailable records are represented by null. */\n async getRecordsByRef(\n refs: Required<ItemRef>[],\n includeTakedowns = false,\n ): Promise<GenericRecordsByRef> {\n const map: GenericRecordsByRef = new HydrationMap()\n if (!refs.length) return map\n\n const res = await this.dataplane.getRecordsByRef({ refs })\n for (let i = 0; i < refs.length; i++) {\n const { uri, cid } = refs[i]\n map.set(\n genericRecordKey(uri, cid),\n parseGenericRecord(res.results[i], includeTakedowns) ?? null,\n )\n }\n return map\n }\n\n /** Fetch the latest indexed versions without collection-specific validation. */\n async getRecordsByURI(\n uris: AtUriString[],\n includeTakedowns = false,\n ): Promise<GenericRecords> {\n const map: GenericRecords = new HydrationMap()\n if (!uris.length) return map\n\n const res = await this.dataplane.getRecordsByURI({ uris })\n for (let i = 0; i < uris.length; i++) {\n map.set(\n uris[i],\n parseGenericRecord(res.results[i], includeTakedowns) ?? null,\n )\n }\n return map\n }\n\n /** Fetch a page of activity refs for subsequent generic record hydration. */\n async getAtmosphereTimeline(\n viewerDid: DidString,\n opts: { limit?: number; cursor?: string } = {},\n ): Promise<AtmosphereTimeline> {\n const res = await this.dataplane.getAtmosphereTimeline({\n viewerDid,\n ...opts,\n })\n return {\n items: res.items.map((item) => ({\n uri: item.uri as AtUriString,\n sortedAt: parseDate(item.sortedAt) ?? new Date(0),\n })),\n cursor: res.cursor || undefined,\n }\n }\n\n /** Fetch source-record counts, optionally restricted to one collection. */\n async getAtmosphereBacklinkCounts(\n targetUris: AtUriString[],\n collection?: NsidString,\n ): Promise<AtmosphereBacklinkCounts> {\n const map: AtmosphereBacklinkCounts = new HydrationMap()\n if (!targetUris.length) return map\n\n const res = await this.dataplane.getAtmosphereBacklinkCounts({\n targetUris,\n collection,\n })\n for (const result of res.results) {\n map.set(\n result.targetUri as AtUriString,\n Object.fromEntries(\n Object.entries(result.counts).map(([nsid, count]) => [\n nsid,\n Number(count),\n ]),\n ),\n )\n }\n return map\n }\n\n /** Fetch a page of source records linking to a target. */\n async getAtmosphereBacklinks(\n targetUri: AtUriString,\n collection: NsidString,\n opts: { limit?: number; cursor?: string } = {},\n ): Promise<AtmosphereBacklinks> {\n const res = await this.dataplane.getAtmosphereBacklinks({\n targetUri,\n collection,\n ...opts,\n })\n return {\n backlinks: res.backlinks.map((backlink) => ({\n uri: backlink.uri as AtUriString,\n sortedAt: parseDate(backlink.sortedAt) ?? new Date(0),\n })),\n cursor: res.cursor || undefined,\n }\n }\n\n /** Fetch an actor's links per target, retaining the batch truncation flag. */\n async getAtmosphereBacklinksByActor(\n targetUris: AtUriString[],\n actorDid: DidString,\n collection: NsidString,\n ): Promise<AtmosphereBacklinksByActor> {\n const backlinks: AtmosphereBacklinksByActor['backlinks'] =\n new HydrationMap()\n if (!targetUris.length) return { backlinks, truncated: false }\n\n const res = await this.dataplane.getAtmosphereBacklinksByActor({\n targetUris,\n actorDid,\n collection,\n })\n for (const result of res.results) {\n backlinks.set(\n result.targetUri as AtUriString,\n result.uris as AtUriString[],\n )\n }\n return { backlinks, truncated: res.truncated }\n }\n\n /**\n * Fetch exact `site.standard.{document,publication}` versions. Does NOT\n * resolve a document's publication; callers must pin it explicitly.\n */\n async getSiteStandardRecordsByRef(\n refs: ItemRef[],\n includeTakedowns = false,\n ): Promise<SiteStandardRecords> {\n const ssRefs = refs.filter(\n (ref): ref is Required<ItemRef> =>\n !!ref.cid && siteStandardKind(ref.uri) !== undefined,\n )\n const out = emptySiteStandardRecords()\n if (!ssRefs.length) return out\n\n const records = await this.getRecordsByRef(ssRefs, includeTakedowns)\n for (const [key, info] of records) {\n setSiteStandardRecord(out, parseGenericRecordKey(key).uri, key, info)\n }\n return out\n }\n\n /**\n * Fetch the latest `site.standard.{document,publication}` versions. The\n * generic record lookup does not follow references, so publications named\n * by the `site` field of the hydrated documents are fetched in a second\n * call.\n */\n async getSiteStandardRecordsByURI(\n uris: AtUriString[],\n includeTakedowns = false,\n ): Promise<SiteStandardRecords> {\n const requested = [...new Set(uris.filter((u) => siteStandardKind(u)))]\n const out = emptySiteStandardRecords()\n if (!requested.length) return out\n\n await this.addSiteStandardRecordsByURI(out, requested, includeTakedowns)\n\n // Publications referenced by documents but not already requested.\n const requestedSet = new Set<string>(requested)\n const pubUris = new Set<AtUriString>()\n for (const doc of out.documents.values()) {\n const pubUri = doc && publicationUriFromSite(doc.record.site)\n if (pubUri && !requestedSet.has(pubUri)) pubUris.add(pubUri)\n }\n if (pubUris.size) {\n await this.addSiteStandardRecordsByURI(\n out,\n [...pubUris],\n includeTakedowns,\n )\n }\n return out\n }\n\n private async addSiteStandardRecordsByURI(\n out: SiteStandardRecords,\n uris: AtUriString[],\n includeTakedowns: boolean,\n ) {\n const records = await this.getRecordsByURI(uris, includeTakedowns)\n for (const [uri, info] of records) {\n // Unavailable records have no CID to key on, so they are left out.\n if (!info) continue\n setSiteStandardRecord(out, uri, genericRecordKey(uri, info.cid), info)\n }\n }\n}\n\nfunction parseGenericRecord(\n result: RecordLookupResult | undefined,\n includeTakedowns: boolean,\n): GenericRecord | undefined {\n if (\n result?.status !== RecordLookupStatus.FOUND &&\n !(includeTakedowns && result?.status === RecordLookupStatus.TAKEN_DOWN)\n ) {\n return undefined\n }\n const entry = result.record\n if (!entry?.cid || !entry.record.byteLength) return undefined\n if (!includeTakedowns && entry.takenDown) return undefined\n\n let record: ReturnType<typeof lexParseJsonBytes>\n try {\n record = lexParseJsonBytes(entry.record, { strict: false })\n } catch {\n return undefined\n }\n if (!isTypedLexMap(record)) return undefined\n\n return {\n record,\n cid: entry.cid,\n sortedAt: parseDate(entry.sortedAt) ?? new Date(0),\n indexedAt: parseDate(entry.indexedAt) ?? new Date(0),\n takedownRef: safeTakedownRef(entry),\n }\n}\n\nconst emptySiteStandardRecords = (): SiteStandardRecords => ({\n documents: new HydrationMap(),\n publications: new HydrationMap(),\n})\n\nconst siteStandardKind = (\n uri: string,\n): keyof SiteStandardRecords | undefined => {\n const parsed = parseAtUriString(uri)\n if (!parsed.success) return undefined\n switch (parsed.value.collection) {\n case site.standard.document.$type:\n return 'documents'\n case site.standard.publication.$type:\n return 'publications'\n default:\n return undefined\n }\n}\n\n/** The AT-URI of the publication a document's `site` field points at. */\nconst publicationUriFromSite = (value: string): AtUriString | undefined => {\n const parsed = parseAtUriString(value)\n return parsed.success &&\n parsed.value.collection === site.standard.publication.$type\n ? (value as AtUriString)\n : undefined\n}\n\n/**\n * Generic record bodies are unvalidated, so check them against the Lexicon\n * before exposing typed fields. Parse mode is not used, to preserve the\n * stored record as-is.\n */\nconst matchRecordInfo = <TSchema extends RecordSchema>(\n schema: TSchema,\n info: GenericRecord | null | undefined,\n): RecordInfo<InferInput<TSchema>> | null =>\n info && schema.$matches(info.record, { strict: false })\n ? { ...info, record: info.record }\n : null\n\n/**\n * Store a generic record in the map matching its collection. Records failing\n * Lexicon validation are stored as null.\n */\nconst setSiteStandardRecord = (\n out: SiteStandardRecords,\n uri: string,\n key: string,\n info: GenericRecord | null | undefined,\n) => {\n switch (siteStandardKind(uri)) {\n case 'documents':\n out.documents.set(key, matchRecordInfo(site.standard.document.main, info))\n break\n case 'publications':\n out.publications.set(\n key,\n matchRecordInfo(site.standard.publication.main, info),\n )\n break\n }\n}\n\n/**\n * Read-path resolution: caller pinned a set of `(uri, cid)` strongRefs in\n * the post at write time, and we honor those exact versions. Any pair\n * that doesn't structurally agree is rejected, so downstream callers can\n * trust the returned shape.\n *\n * Same observable contract as\n * `getSiteStandardRecordsFromHydrationMapsByDocumentUri` (the compose-path\n * sister) — both functions guarantee that a returned `(doc, pub)` pair\n * has matching site/uri, and reject orphan docs that claim a\n * non-hydrated publication. They differ only in how upstream availability\n * is asserted: this one trusts caller-supplied refs; the sister derives\n * everything from the dataplane response.\n *\n * Pairing rules:\n * - Both slots referenced: `doc.site` must equal `publication.ref.uri`,\n * else both come back `undefined`.\n * - Doc with at-uri `site` referenced but no matching publication ref:\n * reject the whole pairing (doc claims a publication that should have\n * been pinned, but wasn't).\n * - Loose doc (web-URL `site`) referenced: publication stays `undefined`.\n * - Only a publication referenced: document stays `undefined`.\n *\n * Each returned slot carries the matching `ref` so callers can recover\n * the owner DID for blob-cdn URL building, etc.\n */\nexport const getSiteStandardRecordsFromHydrationMapsByRefs = (\n associatedRefs: readonly { uri: AtUriString; cid: string }[] | undefined,\n documents: SiteStandardDocuments | undefined,\n publications: SiteStandardPublications | undefined,\n): {\n document: AssociatedSiteStandardRecord<SiteStandardDocument> | undefined\n publication: AssociatedSiteStandardRecord<SiteStandardPublication> | undefined\n} => {\n if (!associatedRefs?.length) {\n return { document: undefined, publication: undefined }\n }\n\n // Resolve each ref against the hydration maps, taking the first hit on\n // each side.\n let document: AssociatedSiteStandardRecord<SiteStandardDocument> | undefined\n let publication:\n AssociatedSiteStandardRecord<SiteStandardPublication> | undefined\n for (const ref of associatedRefs) {\n const key = genericRecordKey(ref.uri, ref.cid)\n if (!document) {\n const hit = documents?.get(key)\n if (hit) document = { ref, info: hit }\n }\n if (!publication) {\n const hit = publications?.get(key)\n if (hit) publication = { ref, info: hit }\n }\n if (document && publication) break\n }\n\n // Both refs resolved: enforce that the doc's `site` actually points at\n // the supplied publication. Mismatch means the post was misconstructed\n // (or tampered with), so reject the whole pairing.\n if (document && publication) {\n if (document.info.record.site !== publication.ref.uri) {\n hydrationLogger.warn(\n {\n documentUri: document.ref.uri,\n documentSite: document.info.record.site,\n publicationUri: publication.ref.uri,\n },\n 'site.standard byRefs lookup failed: doc.site does not match hydrated publication.uri',\n )\n return { document: undefined, publication: undefined }\n }\n }\n\n // Doc with at-uri `site` but no publication: the post should have\n // pinned the publication too. Treat as misconstructed — same contract\n // as the compose-path lookup.\n if (document && !publication) {\n const site = document.info.record.site\n if (site && site.startsWith('at://')) {\n hydrationLogger.warn(\n { documentUri: document.ref.uri, documentSite: site },\n 'site.standard byRefs lookup failed: document.site is AT URI but no matching publication was hydrated',\n )\n return { document: undefined, publication: undefined }\n }\n }\n\n return { document, publication }\n}\n\n/**\n * Compose-path resolution: no caller-supplied refs — the dataplane\n * returned the latest version of each record (including any\n * publications it auto-resolved from a document's `site` field). Take\n * the first hydrated document and pair it with the publication its\n * `site` field points at.\n *\n * Same observable contract as\n * `getSiteStandardRecordsFromHydrationMapsByRefs` (the read-path\n * sister) — both functions guarantee that a returned `(doc, pub)` pair\n * has matching site/uri, and reject orphan docs that claim a\n * non-hydrated publication. They differ only in how upstream\n * availability is asserted: this one walks whatever was returned by the\n * dataplane; the sister checks against caller-supplied refs.\n *\n * Pairing rules:\n * - Doc with at-uri `site`: must find a hydrated publication at that\n * URI. If none was hydrated, the doc/publication chain is incomplete\n * and the function returns `undefined` for both slots; the doc alone\n * isn't useful without its source (can't verify the pub)\n * - Doc with web-URL `site` (loose): no publication.\n * - No doc hydrated: fall through to the first hydrated publication for\n * the publication-only resolution flow.\n */\nexport const getSiteStandardRecordsFromHydrationMapsByDocumentUri = (\n documents: SiteStandardDocuments | undefined,\n publications: SiteStandardPublications | undefined,\n): {\n document: AssociatedSiteStandardRecord<SiteStandardDocument> | undefined\n publication: AssociatedSiteStandardRecord<SiteStandardPublication> | undefined\n} => {\n // First hydrated doc.\n let document: AssociatedSiteStandardRecord<SiteStandardDocument> | undefined\n for (const [key, info] of documents ?? []) {\n if (!info) continue\n document = { ref: parseGenericRecordKey(key), info }\n break\n }\n\n let publication:\n AssociatedSiteStandardRecord<SiteStandardPublication> | undefined\n if (document) {\n const site = document.info.record.site\n if (site && site.startsWith('at://')) {\n // Doc declared an at-uri publication; we need it.\n for (const [key, info] of publications ?? []) {\n if (!info) continue\n const ref = parseGenericRecordKey(key)\n if (ref.uri === site) {\n publication = { ref, info }\n break\n }\n }\n if (!publication) {\n hydrationLogger.warn(\n { documentUri: document.ref.uri, documentSite: site },\n 'site.standard byDocumentUri lookup failed: document.site is AT URI but no matching publication was hydrated',\n )\n return { document: undefined, publication: undefined }\n }\n }\n // else: loose doc (web-URL site), no publication needed.\n } else {\n // Publication-only flow: no doc, take the first hydrated publication.\n for (const [key, info] of publications ?? []) {\n if (!info) continue\n publication = { ref: parseGenericRecordKey(key), info }\n break\n }\n }\n\n return { document, publication }\n}\n"]}
1
+ {"version":3,"file":"external.js","sourceRoot":"","sources":["../../src/hydration/external.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n type AtUriString,\n type DidString,\n type InferInput,\n type NsidString,\n type RecordSchema,\n type TypedLexMap,\n isTypedLexMap,\n lexParseJsonBytes,\n} from '@atproto/lex'\nimport { parseAtUriString } from '@atproto/syntax'\nimport type { DataPlaneClient } from '../data-plane/client/index.js'\nimport { site } from '../lexicons/index.js'\nimport { hydrationLogger } from '../logger.js'\nimport {\n type RecordLookupResult,\n RecordLookupStatus,\n} from '../proto/bsky_pb.js'\nimport {\n type ExternalHydrationOutcome,\n type ExternalHydrationRoot,\n type ExternalHydrationWork,\n events,\n} from '../telemetry/events.js'\nimport { uriToDid } from '../util/uris.js'\nimport type {\n SiteStandardDocumentRecord,\n SiteStandardPublicationRecord,\n} from '../views/types.js'\nimport type { Actors } from './actor.js'\nimport type { Labels } from './label.js'\nimport {\n HydrationMap,\n type ItemRef,\n type RecordInfo,\n parseDate,\n safeTakedownRef,\n} from './util.js'\n\n/** Generic record bodies are decoded, but not validated against a Lexicon. */\nexport type ExternalRecord = RecordInfo<TypedLexMap>\nexport type ExternalRecords = HydrationMap<AtUriString, ExternalRecord>\n/** Keyed by `genericRecordKey({ uri, cid })` to retain versions of a URI. */\nexport type ExternalRecordsByRef = HydrationMap<ExactRecordKey, ExternalRecord>\nexport type ExternalRecordBacklinks = HydrationMap<AtUriString, AtUriString[]>\n\nexport type AtmosphereActivityItem = {\n uri: AtUriString\n sortedAt: Date\n}\n\nexport type AtmosphereTimeline = {\n items: AtmosphereActivityItem[]\n cursor?: string\n}\n\nexport type AtmosphereBacklinks = {\n backlinks: AtmosphereActivityItem[]\n cursor?: string\n}\n\nexport type ExternalRecordBacklinkCounts = HydrationMap<\n AtUriString,\n Partial<Record<NsidString, number>>\n>\n\nexport type AtmosphereBacklinksByActor = {\n backlinks: HydrationMap<AtUriString, AtUriString[]>\n truncated: boolean\n}\n\ndeclare const exactRecordKeySymbol: unique symbol\n\n/**\n * A version-exact `${uri}@${cid}` key, only produced by `genericRecordKey` for\n * a ref with a CID, so it can be parsed back by `parseGenericRecordKey`.\n */\nexport type ExactRecordKey = string & { [exactRecordKeySymbol]: true }\n\nexport type SiteStandardDocument = RecordInfo<SiteStandardDocumentRecord>\nexport type SiteStandardPublication = RecordInfo<SiteStandardPublicationRecord>\n\n/**\n * Keyed by `${uri}@${cid}` — see `genericRecordKey`. A single hydration\n * batch can pull more than one version of the same URI (different posts\n * pinning different cids), so the composite key is needed for O(1)\n * version-exact lookups.\n */\nexport type SiteStandardDocuments = HydrationMap<\n ExactRecordKey,\n SiteStandardDocument\n>\n/**\n * Keyed by `${uri}@${cid}`. See `SiteStandardDocuments` for the rationale.\n */\nexport type SiteStandardPublications = HydrationMap<\n ExactRecordKey,\n SiteStandardPublication\n>\nexport type SiteStandardRecords = {\n documents: SiteStandardDocuments\n publications: SiteStandardPublications\n}\n\nexport class ExternalHydrator {\n static readonly MAX_BACKLINK_PREVIEWS = 3\n static readonly MAX_BACKLINK_GALLERY_ITEMS = 10\n static readonly MAX_BACKLINK_FANOUT = 8\n /** Hard cap on generic batches per traversal, counting the root as pass 1. */\n static readonly MAX_EXTERNAL_HYDRATION_PASSES = 8\n\n constructor(public dataplane: DataPlaneClient) {}\n\n /** Fetch exact record versions; unavailable records are represented by null. */\n async getRecordsByRef(\n refs: Required<ItemRef>[],\n includeTakedowns = false,\n ): Promise<ExternalRecordsByRef> {\n const map: ExternalRecordsByRef = new HydrationMap()\n if (!refs.length) return map\n\n const res = await this.dataplane.getRecordsByRef({ refs })\n for (let i = 0; i < refs.length; i++) {\n map.set(\n genericRecordKey(refs[i]),\n parseGenericRecord(res.results[i], includeTakedowns) ?? null,\n )\n }\n return map\n }\n\n /** Fetch the latest indexed versions without collection-specific validation. */\n async getRecordsByURI(\n uris: AtUriString[],\n includeTakedowns = false,\n ): Promise<ExternalRecords> {\n const map: ExternalRecords = new HydrationMap()\n if (!uris.length) return map\n\n const res = await this.dataplane.getRecordsByURI({ uris })\n for (let i = 0; i < uris.length; i++) {\n map.set(\n uris[i],\n parseGenericRecord(res.results[i], includeTakedowns) ?? null,\n )\n }\n return map\n }\n\n /** Fetch a page of activity refs for subsequent generic record hydration. */\n async getAtmosphereTimeline(\n viewerDid: DidString,\n opts: { limit?: number; cursor?: string } = {},\n ): Promise<AtmosphereTimeline> {\n const res = await this.dataplane.getAtmosphereTimeline({\n viewerDid,\n ...opts,\n })\n return {\n items: res.items.map((item) => ({\n uri: item.uri as AtUriString,\n sortedAt: parseDate(item.sortedAt) ?? new Date(0),\n })),\n cursor: res.cursor || undefined,\n }\n }\n\n /** Fetch source-record counts, optionally restricted to one collection. */\n async getAtmosphereBacklinkCounts(\n targetUris: AtUriString[],\n collection?: NsidString,\n ): Promise<ExternalRecordBacklinkCounts> {\n const map: ExternalRecordBacklinkCounts = new HydrationMap()\n if (!targetUris.length) return map\n\n const res = await this.dataplane.getAtmosphereBacklinkCounts({\n targetUris,\n collection,\n })\n for (const result of res.results) {\n map.set(\n result.targetUri as AtUriString,\n Object.fromEntries(\n Object.entries(result.counts).map(([nsid, count]) => [\n nsid,\n Number(count),\n ]),\n ),\n )\n }\n return map\n }\n\n /** Fetch a page of source records linking to a target. */\n async getAtmosphereBacklinks(\n targetUri: AtUriString,\n collection: NsidString,\n opts: { limit?: number; cursor?: string } = {},\n ): Promise<AtmosphereBacklinks> {\n const res = await this.dataplane.getAtmosphereBacklinks({\n targetUri,\n collection,\n ...opts,\n })\n return {\n backlinks: res.backlinks.map((backlink) => ({\n uri: backlink.uri as AtUriString,\n sortedAt: parseDate(backlink.sortedAt) ?? new Date(0),\n })),\n cursor: res.cursor || undefined,\n }\n }\n\n /** Fetch an actor's links per target, retaining the batch truncation flag. */\n async getAtmosphereBacklinksByActor(\n targetUris: AtUriString[],\n actorDid: DidString,\n collection: NsidString,\n ): Promise<AtmosphereBacklinksByActor> {\n const backlinks: AtmosphereBacklinksByActor['backlinks'] =\n new HydrationMap()\n if (!targetUris.length) return { backlinks, truncated: false }\n\n const res = await this.dataplane.getAtmosphereBacklinksByActor({\n targetUris,\n actorDid,\n collection,\n })\n for (const result of res.results) {\n backlinks.set(\n result.targetUri as AtUriString,\n result.uris as AtUriString[],\n )\n }\n return { backlinks, truncated: res.truncated }\n }\n\n /**\n * Fetch exact `site.standard.{document,publication}` versions. Does NOT\n * resolve a document's publication; callers must pin it explicitly.\n */\n async getSiteStandardRecordsByRef(\n refs: ItemRef[],\n includeTakedowns = false,\n ): Promise<SiteStandardRecords> {\n const ssRefs = refs.filter(\n (ref): ref is Required<ItemRef> =>\n !!ref.cid && siteStandardKind(ref.uri) !== undefined,\n )\n const out = emptySiteStandardRecords()\n if (!ssRefs.length) return out\n\n const records = await this.getRecordsByRef(ssRefs, includeTakedowns)\n for (const [key, info] of records) {\n setSiteStandardRecord(out, parseGenericRecordKey(key).uri, key, info)\n }\n return out\n }\n}\n\n/**\n * Composes the lookup key for a ref: the bare URI for a latest-version lookup,\n * or `${uri}@${cid}` for an exact version. A single hydration batch can pull\n * several versions of one URI (different posts pinning different cids), so\n * exact maps need the composite for O(1) version-exact lookups. The two forms\n * never collide, so latest and exact lookups can share one traversal set.\n *\n * Throws on an empty CID rather than treating it as a latest lookup.\n */\nexport function genericRecordKey(ref: Required<ItemRef>): ExactRecordKey\nexport function genericRecordKey(ref: ItemRef): string\nexport function genericRecordKey({ uri, cid }: ItemRef): string {\n if (cid === undefined) return uri\n if (!cid) throw new Error(`Empty CID in record key for ${uri}`)\n return `${uri}@${cid}`\n}\n\n/**\n * Recover the URI and CID from an exact record key, splitting at the last `@`.\n * Throws if either part is missing. Components are trusted, not revalidated.\n */\nexport function parseGenericRecordKey(key: ExactRecordKey): Required<ItemRef> {\n const at = key.lastIndexOf('@')\n if (at <= 0 || at === key.length - 1) {\n throw new Error(`Malformed exact record key: ${key}`)\n }\n return {\n uri: key.slice(0, at) as AtUriString,\n cid: key.slice(at + 1),\n }\n}\n\n/**\n * Null generic external records (in both the URI-keyed and exact-ref maps,\n * keeping their keys) that are taken down by an actionable label, unless\n * takedowns are included, or whose owner is explicitly unavailable. Applies to\n * each record independently; counts and other records are unaffected.\n */\nexport function actionExternalRecordTakedowns(\n {\n externalRecords,\n externalRecordsByRef,\n actors,\n labels,\n }: {\n externalRecords?: ExternalRecords\n externalRecordsByRef?: ExternalRecordsByRef\n actors?: Actors\n labels?: Labels\n },\n includeTakedowns?: boolean,\n): void {\n // An absent actor entry was not hydrated; only `null` means unavailable.\n const isHidden = (uri: AtUriString) =>\n actors?.get(uriToDid(uri)) === null ||\n (!includeTakedowns && labels?.get(uri)?.isTakendown)\n for (const [uri, info] of externalRecords ?? []) {\n if (!info || !isHidden(uri)) continue\n externalRecords?.set(uri, null)\n externalRecordsByRef?.set(genericRecordKey({ uri, cid: info.cid }), null)\n }\n // Every exact version is checked on its own; versions are never collapsed.\n for (const [key, info] of externalRecordsByRef ?? []) {\n if (info && isHidden(parseGenericRecordKey(key).uri)) {\n externalRecordsByRef?.set(key, null)\n }\n }\n}\n\n/**\n * Generic lookup work of one external hydration traversal, shared by reference\n * through its nested passes. `capped` records hitting the pass limit.\n */\nexport type ExternalHydrationTracker = ExternalHydrationWork & {\n capped: boolean\n}\n\n/**\n * Run `fn` with the caller's tracker, or as the owner of a new traversal when\n * there is none. Only the owner reports, once, including on failure. Owners\n * that completed without scheduling a batch did no work and are not reported;\n * caps and failures always are.\n */\nexport async function trackExternalHydration<T>(\n root: ExternalHydrationRoot,\n hydrationMetrics: ExternalHydrationTracker | undefined,\n fn: (hydrationMetrics: ExternalHydrationTracker) => Promise<T>,\n): Promise<T> {\n if (hydrationMetrics) return fn(hydrationMetrics)\n const owned = { recordLookups: 0, batches: 0, maxPass: 0, capped: false }\n let outcome: ExternalHydrationOutcome = 'failed'\n try {\n const state = await fn(owned)\n outcome = owned.capped ? 'capped' : 'completed'\n return state\n } finally {\n if (owned.batches || outcome !== 'completed') {\n const { recordLookups, batches, maxPass } = owned\n events.externalHydrationTraversal({\n root,\n outcome,\n recordLookups,\n batches,\n maxPass,\n })\n }\n }\n}\n\nfunction parseGenericRecord(\n result: RecordLookupResult | undefined,\n includeTakedowns: boolean,\n): ExternalRecord | undefined {\n if (\n result?.status !== RecordLookupStatus.FOUND &&\n !(includeTakedowns && result?.status === RecordLookupStatus.TAKEN_DOWN)\n ) {\n return undefined\n }\n const entry = result.record\n if (!entry?.cid || !entry.record.byteLength) return undefined\n if (!includeTakedowns && entry.takenDown) return undefined\n\n let record: ReturnType<typeof lexParseJsonBytes>\n try {\n record = lexParseJsonBytes(entry.record, { strict: false })\n } catch {\n return undefined\n }\n if (!isTypedLexMap(record)) return undefined\n\n return {\n record,\n cid: entry.cid,\n sortedAt: parseDate(entry.sortedAt) ?? new Date(0),\n indexedAt: parseDate(entry.indexedAt) ?? new Date(0),\n takedownRef: safeTakedownRef(entry),\n }\n}\n\nconst emptySiteStandardRecords = (): SiteStandardRecords => ({\n documents: new HydrationMap(),\n publications: new HydrationMap(),\n})\n\nconst siteStandardKind = (\n uri: string,\n): keyof SiteStandardRecords | undefined => {\n const parsed = parseAtUriString(uri)\n if (!parsed.success) return undefined\n switch (parsed.value.collection) {\n case site.standard.document.$type:\n return 'documents'\n case site.standard.publication.$type:\n return 'publications'\n default:\n return undefined\n }\n}\n\n/**\n * Generic record bodies are unvalidated, so check them against the Lexicon\n * before exposing typed fields. Parse mode is not used, to preserve the\n * stored record as-is.\n */\nconst matchRecordInfo = <TSchema extends RecordSchema>(\n schema: TSchema,\n info: ExternalRecord | null | undefined,\n): RecordInfo<InferInput<TSchema>> | null =>\n info && schema.$matches(info.record, { strict: false })\n ? { ...info, record: info.record }\n : null\n\n/**\n * Store a generic record in the map matching its collection. Records failing\n * Lexicon validation are stored as null.\n */\nconst setSiteStandardRecord = (\n out: SiteStandardRecords,\n uri: string,\n key: ExactRecordKey,\n info: ExternalRecord | null | undefined,\n) => {\n switch (siteStandardKind(uri)) {\n case 'documents':\n out.documents.set(key, matchRecordInfo(site.standard.document.main, info))\n break\n case 'publications':\n out.publications.set(\n key,\n matchRecordInfo(site.standard.publication.main, info),\n )\n break\n }\n}\n\nexport type AssociatedSiteStandardRecord<T> = {\n ref: { uri: AtUriString; cid: string }\n info: T\n}\n\n/**\n * Read-path resolution: caller pinned a set of `(uri, cid)` strongRefs in\n * the post at write time, and we honor those exact versions. Any pair\n * that doesn't structurally agree is rejected, so downstream callers can\n * trust the returned shape.\n *\n * Pairing rules:\n * - Both slots referenced: `doc.site` must equal `publication.ref.uri`,\n * else both come back `undefined`.\n * - Doc with at-uri `site` referenced but no matching publication ref:\n * reject the whole pairing (doc claims a publication that should have\n * been pinned, but wasn't).\n * - Loose doc (web-URL `site`) referenced: publication stays `undefined`.\n * - Only a publication referenced: document stays `undefined`.\n *\n * Each returned slot carries the matching `ref` so callers can recover\n * the owner DID for blob-cdn URL building, etc.\n */\nexport const getSiteStandardRecordsFromHydrationMapsByRefs = (\n associatedRefs: readonly { uri: AtUriString; cid: string }[] | undefined,\n documents: SiteStandardDocuments | undefined,\n publications: SiteStandardPublications | undefined,\n): {\n document: AssociatedSiteStandardRecord<SiteStandardDocument> | undefined\n publication: AssociatedSiteStandardRecord<SiteStandardPublication> | undefined\n} => {\n if (!associatedRefs?.length) {\n return { document: undefined, publication: undefined }\n }\n\n // Resolve each ref against the hydration maps, taking the first hit on\n // each side.\n let document: AssociatedSiteStandardRecord<SiteStandardDocument> | undefined\n let publication:\n AssociatedSiteStandardRecord<SiteStandardPublication> | undefined\n for (const ref of associatedRefs) {\n const key = genericRecordKey(ref)\n if (!document) {\n const hit = documents?.get(key)\n if (hit) document = { ref, info: hit }\n }\n if (!publication) {\n const hit = publications?.get(key)\n if (hit) publication = { ref, info: hit }\n }\n if (document && publication) break\n }\n\n // Both refs resolved: enforce that the doc's `site` actually points at\n // the supplied publication. Mismatch means the post was misconstructed\n // (or tampered with), so reject the whole pairing.\n if (document && publication) {\n if (document.info.record.site !== publication.ref.uri) {\n hydrationLogger.warn(\n {\n documentUri: document.ref.uri,\n documentSite: document.info.record.site,\n publicationUri: publication.ref.uri,\n },\n 'site.standard byRefs lookup failed: doc.site does not match hydrated publication.uri',\n )\n return { document: undefined, publication: undefined }\n }\n }\n\n // Doc with at-uri `site` but no publication: the post should have\n // pinned the publication too. Treat as misconstructed.\n if (document && !publication) {\n const site = document.info.record.site\n if (site && site.startsWith('at://')) {\n hydrationLogger.warn(\n { documentUri: document.ref.uri, documentSite: site },\n 'site.standard byRefs lookup failed: document.site is AT URI but no matching publication was hydrated',\n )\n return { document: undefined, publication: undefined }\n }\n }\n\n return { document, publication }\n}\n"]}
@@ -5,8 +5,8 @@ import type { FeatureGatesClient, ScopedFeatureGatesClient } from '../feature-ga
5
5
  import { app } from '../lexicons/index.js';
6
6
  import type { BookmarkInfo, Notification } from '../proto/bsky_pb.js';
7
7
  import type { ParsedLabelers } from '../util.js';
8
- import { type ActivitySubscriptionStates, ActorHydrator, type Actors, type KnownFollowersStates, type KnownLikersStates, type ProfileAggs, type ProfileViewerStates } from './actor.js';
9
- import { ExternalHydrator, type SiteStandardDocuments, type SiteStandardPublications } from './external.js';
8
+ import { type ActivitySubscriptionStates, ActorHydrator, type Actors, type KnownFollowersStates, type KnownLikersStates, type ProfileAggs, type ProfileLinks, type ProfileViewerStates } from './actor.js';
9
+ import { type ExternalHydrationTracker, ExternalHydrator, type ExternalRecordBacklinkCounts, type ExternalRecordBacklinks, type ExternalRecords, type ExternalRecordsByRef, type SiteStandardDocuments, type SiteStandardPublications } from './external.js';
10
10
  import { type FeedGenAggs, type FeedGenViewerStates, type FeedGens, FeedHydrator, type FeedItem, type GetPostsHydrationOptions, type Likes, type Post, type PostAggs, type PostViewerStates, type Postgates, type Posts, type Reposts, type ThreadContexts, type Threadgates } from './feed.js';
11
11
  import { type Follows, GraphHydrator, type ListAggs, type ListItems, type ListMembershipStates, type ListViewerStates, type Lists, type StarterPackAggs, type StarterPacks, type Verifications } from './graph.js';
12
12
  import { LabelHydrator, type LabelerAggs, type LabelerViewerStates, type Labelers, Labels } from './label.js';
@@ -68,6 +68,7 @@ export type HydrationState = {
68
68
  feedgenAggs?: FeedGenAggs;
69
69
  starterPacks?: StarterPacks;
70
70
  starterPackAggs?: StarterPackAggs;
71
+ profileLinks?: ProfileLinks;
71
72
  labelers?: Labelers;
72
73
  labelerViewers?: LabelerViewerStates;
73
74
  labelerAggs?: LabelerAggs;
@@ -77,6 +78,11 @@ export type HydrationState = {
77
78
  bidirectionalBlocks?: BidirectionalBlocks;
78
79
  verifications?: Verifications;
79
80
  bookmarks?: Bookmarks;
81
+ externalRecords?: ExternalRecords;
82
+ externalRecordsByRef?: ExternalRecordsByRef;
83
+ /** Available backlink source URIs per target, potentially from a partial page. */
84
+ externalRecordBacklinks?: ExternalRecordBacklinks;
85
+ externalRecordBacklinkCounts?: ExternalRecordBacklinkCounts;
80
86
  siteStandardDocuments?: SiteStandardDocuments;
81
87
  siteStandardPublications?: SiteStandardPublications;
82
88
  };
@@ -95,6 +101,10 @@ type HydrateFeedItemsOptions = {
95
101
  */
96
102
  knownLikers?: boolean;
97
103
  };
104
+ export type HydrateProfilesOptions = {
105
+ knownFollowersDids?: DidString[];
106
+ activitySubscriptions?: boolean;
107
+ };
98
108
  export type PostBlock = {
99
109
  embed: boolean;
100
110
  parent: boolean;
@@ -134,11 +144,11 @@ export declare class Hydrator {
134
144
  config: HydratorConfig;
135
145
  constructor(dataplane: DataPlaneClient, serviceLabelers: readonly DidString[] | undefined, config: HydratorConfig);
136
146
  hydrateProfileViewers(dids: DidString[], ctx: HydrateCtx): Promise<HydrationState>;
137
- hydrateProfiles(dids: DidString[], ctx: HydrateCtx): Promise<HydrationState>;
138
- hydrateProfilesBasic(dids: DidString[], ctx: HydrateCtx): Promise<HydrationState>;
139
- hydrateProfilesDetailed(dids: DidString[], ctx: HydrateCtx, opts?: {
140
- knownFollowersDids?: DidString[];
141
- }): Promise<HydrationState>;
147
+ hydrateProfiles(dids: DidString[], ctx: HydrateCtx, opts?: HydrateProfilesOptions): Promise<HydrationState>;
148
+ hydrateProfilesBasic(dids: DidString[], ctx: HydrateCtx, opts?: HydrateProfilesOptions): Promise<HydrationState>;
149
+ hydrateProfilesDetailed(dids: DidString[], ctx: HydrateCtx, opts?: HydrateProfilesOptions): Promise<HydrationState>;
150
+ private hydrateProfilesWorker;
151
+ private hydrateProfileState;
142
152
  hydrateLists(uris: AtUriString[], ctx: HydrateCtx): Promise<HydrationState>;
143
153
  hydrateListsBasic(uris: AtUriString[], ctx: HydrateCtx, opts?: {
144
154
  skipAuthors: boolean;
@@ -151,12 +161,38 @@ export declare class Hydrator {
151
161
  private hydratePostBlocks;
152
162
  hydrateFeedItems(items: FeedItem[], ctx: HydrateCtx, options?: HydrateFeedItemsOptions): Promise<HydrationState>;
153
163
  /**
154
- * Hydrate the state needed to build an `app.bsky.embed.external#view` for
155
- * a set of `site.standard.*` AT-URIs at compose-time. Filters input URIs to
156
- * SS collections, fetches latest indexed versions plus labels, and gates
157
- * taken-down records.
164
+ * Hydrate the latest versions of external records, plus labels, profiles, and
165
+ * their view dependencies. `hydrationPass` is the 1-based number of this
166
+ * generic batch within the traversal (the root batch is pass 1); nested
167
+ * batches continue the count. Nested passes share the caller's
168
+ * `hydrationMetrics` tracker; without one, this call owns the traversal and
169
+ * reports its totals.
158
170
  */
159
- hydrateEmbedExternalViewFromUris(uris: AtUriString[], ctx: HydrateCtx): Promise<HydrationState>;
171
+ hydrateEmbedExternalViewFromUris(uris: AtUriString[], ctx: HydrateCtx, seenRecordKeys?: Set<string>, hydrationPass?: number, hydrationMetrics?: ExternalHydrationTracker): Promise<HydrationState>;
172
+ /**
173
+ * Like `hydrateEmbedExternalViewFromUris`, but for exact record versions
174
+ * pinned by strong refs. Roots land only in `externalRecordsByRef`; their
175
+ * URI dependencies are hydrated as latest versions by the URI path.
176
+ */
177
+ hydrateEmbedExternalViewFromRefs(refs: Required<ItemRef>[], ctx: HydrateCtx, seenRecordKeys?: Set<string>, hydrationPass?: number, hydrationMetrics?: ExternalHydrationTracker): Promise<HydrationState>;
178
+ private hydrateEmbedExternalView;
179
+ /**
180
+ * Discover view dependencies by URI collection and hydrate new URIs in a batch.
181
+ * Returns additional state. Each input is inspected in the map matching its
182
+ * identity: `(uri, cid)` refs in `externalRecordsByRef`, bare URIs in
183
+ * `externalRecords`. Every pinned version is inspected, since versions of
184
+ * one URI can reference different dependencies.
185
+ *
186
+ * `seenRecordKeys` prevents repeated lookups and cycles across nested passes,
187
+ * but not a chain of distinct URIs; `MAX_EXTERNAL_HYDRATION_PASSES` bounds
188
+ * that, as a guard against future association rules or unexpected expansion.
189
+ * `hydrationPass` is the number of the generic batch that produced `state`
190
+ * (1-based, default 1 for prehydrated state, which is treated as the root
191
+ * batch); the next nested batch is `hydrationPass + 1`. `hydrationMetrics`
192
+ * is shared as in `hydrateEmbedExternalViewFromUris`.
193
+ */
194
+ hydrateExternalViewDependencies(state: HydrationState, refs: ItemRef[], ctx: HydrateCtx, seenRecordKeys?: Set<string>, hydrationPass?: number, hydrationMetrics?: ExternalHydrationTracker): Promise<HydrationState>;
195
+ private discoverExternalViewDependencies;
160
196
  hydrateThreadPosts(refs: ItemRef[], ctx: HydrateCtx, options?: Pick<HydratePostsOptions, 'knownLikers'>): Promise<HydrationState>;
161
197
  private hydrateKnownLikers;
162
198
  hydrateFeedGens(uris: AtUriString[], // @TODO any way to get refs here?
@@ -166,13 +202,15 @@ export declare class Hydrator {
166
202
  hydrateLikes(authorDid: DidString, uris: AtUriString[], ctx: HydrateCtx): Promise<HydrationState>;
167
203
  hydrateReposts(uris: AtUriString[], ctx: HydrateCtx): Promise<HydrationState>;
168
204
  hydrateNotifications(notifs: Notification[], ctx: HydrateCtx): Promise<HydrationState>;
169
- hydrateGroupedNotifications(notifs: RawNotification[], ctx: HydrateCtx): Promise<HydrationState>;
205
+ hydrateGroupedNotifications(notifs: RawNotification[], ctx: HydrateCtx, opts?: {
206
+ knownFollowersDids?: DidString[];
207
+ }): Promise<HydrationState>;
170
208
  hydrateBookmarks(bookmarkInfos: BookmarkInfo[], ctx: HydrateCtx): Promise<HydrationState>;
171
209
  hydrateFollows(uris: AtUriString[], ctx: HydrateCtx): Promise<HydrationState>;
172
210
  hydrateBidirectionalBlocks(didMap: Map<DidString, DidString[]>, // DID -> DID[]
173
211
  ctx: HydrateCtx): Promise<BidirectionalBlocks>;
174
212
  hydrateLabelers(dids: DidString[], ctx: HydrateCtx): Promise<HydrationState>;
175
- getRecord(uri: AtUriString, includeTakedowns?: boolean): Promise<import("./graph.js").Block | import("./actor.js").ChatDeclaration | import("./feed.js").FeedGen | import("./graph.js").Follow | import("./actor.js").GermDeclaration | import("./label.js").Labeler | import("./feed.js").Like | import("./graph.js").List | import("./graph.js").ListItem | import("./actor.js").NotificationDeclaration | import("./feed.js").Postgate | RecordInfo<app.bsky.actor.profile.Main> | import("./feed.js").Repost | import("./graph.js").StarterPack | import("./actor.js").Status | import("./feed.js").Threadgate | Post | undefined>;
213
+ getRecord(uri: AtUriString, includeTakedowns?: boolean): Promise<import("./graph.js").Block | import("./actor.js").ChatDeclaration | import("./feed.js").FeedGen | import("./graph.js").Follow | import("./actor.js").GermDeclaration | import("./label.js").Labeler | import("./feed.js").Like | import("./graph.js").List | import("./graph.js").ListItem | import("./actor.js").NotificationDeclaration | import("./feed.js").Postgate | import("./actor.js").ProfileLink | RecordInfo<app.bsky.actor.profile.Main> | import("./feed.js").Repost | import("./graph.js").StarterPack | import("./actor.js").Status | import("./feed.js").Threadgate | Post | undefined>;
176
214
  createContext<V extends Omit<HydrateCtxVals, 'features'> & {
177
215
  features?: ScopedFeatureGatesClient;
178
216
  }>(vals: V): Promise<HydrateCtx & {
@@ -180,6 +218,11 @@ export declare class Hydrator {
180
218
  }>;
181
219
  resolveUri(uriStr: AtUriString): Promise<AtUriString>;
182
220
  }
221
+ /**
222
+ * The link records a profile points to, in order. Only the first
223
+ * MAX_PROFILE_LINKS are shown, and only links in the profile's own repo count.
224
+ */
225
+ export declare const profileLinkUris: (dids: DidString[], actors: Actors | undefined) => AtUriString[];
183
226
  export declare const mergeStates: (stateA: HydrationState, stateB: HydrationState) => HydrationState;
184
227
  export declare const mergeManyStates: (...states: HydrationState[]) => HydrationState;
185
228
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"hydrator.d.ts","sourceRoot":"","sources":["../../src/hydration/hydrator.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"hydrator.d.ts","sourceRoot":"","sources":["../../src/hydration/hydrator.ts"],"names":[],"mappings":"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"}