@atproto/bsky 0.0.273 → 0.0.275

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 (255) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/dist/api/app/bsky/actor/getSuggestions.d.ts.map +1 -1
  3. package/dist/api/app/bsky/actor/getSuggestions.js +7 -2
  4. package/dist/api/app/bsky/actor/getSuggestions.js.map +1 -1
  5. package/dist/api/app/bsky/actor/searchActors.d.ts.map +1 -1
  6. package/dist/api/app/bsky/actor/searchActors.js +13 -6
  7. package/dist/api/app/bsky/actor/searchActors.js.map +1 -1
  8. package/dist/api/app/bsky/bookmark/getBookmarks.d.ts.map +1 -1
  9. package/dist/api/app/bsky/bookmark/getBookmarks.js +7 -2
  10. package/dist/api/app/bsky/bookmark/getBookmarks.js.map +1 -1
  11. package/dist/api/app/bsky/contact/getMatches.d.ts.map +1 -1
  12. package/dist/api/app/bsky/contact/getMatches.js +8 -2
  13. package/dist/api/app/bsky/contact/getMatches.js.map +1 -1
  14. package/dist/api/app/bsky/feed/getActorFeeds.d.ts.map +1 -1
  15. package/dist/api/app/bsky/feed/getActorFeeds.js +7 -2
  16. package/dist/api/app/bsky/feed/getActorFeeds.js.map +1 -1
  17. package/dist/api/app/bsky/feed/getActorLikes.d.ts.map +1 -1
  18. package/dist/api/app/bsky/feed/getActorLikes.js +7 -2
  19. package/dist/api/app/bsky/feed/getActorLikes.js.map +1 -1
  20. package/dist/api/app/bsky/feed/getAuthorFeed.d.ts.map +1 -1
  21. package/dist/api/app/bsky/feed/getAuthorFeed.js +7 -2
  22. package/dist/api/app/bsky/feed/getAuthorFeed.js.map +1 -1
  23. package/dist/api/app/bsky/feed/getFeed.d.ts +13 -0
  24. package/dist/api/app/bsky/feed/getFeed.d.ts.map +1 -1
  25. package/dist/api/app/bsky/feed/getFeed.js +41 -8
  26. package/dist/api/app/bsky/feed/getFeed.js.map +1 -1
  27. package/dist/api/app/bsky/feed/getLikes.d.ts.map +1 -1
  28. package/dist/api/app/bsky/feed/getLikes.js +7 -2
  29. package/dist/api/app/bsky/feed/getLikes.js.map +1 -1
  30. package/dist/api/app/bsky/feed/getListFeed.d.ts.map +1 -1
  31. package/dist/api/app/bsky/feed/getListFeed.js +7 -2
  32. package/dist/api/app/bsky/feed/getListFeed.js.map +1 -1
  33. package/dist/api/app/bsky/feed/getQuotes.d.ts.map +1 -1
  34. package/dist/api/app/bsky/feed/getQuotes.js +7 -2
  35. package/dist/api/app/bsky/feed/getQuotes.js.map +1 -1
  36. package/dist/api/app/bsky/feed/getRepostedBy.d.ts.map +1 -1
  37. package/dist/api/app/bsky/feed/getRepostedBy.js +7 -2
  38. package/dist/api/app/bsky/feed/getRepostedBy.js.map +1 -1
  39. package/dist/api/app/bsky/feed/getSuggestedFeeds.d.ts.map +1 -1
  40. package/dist/api/app/bsky/feed/getSuggestedFeeds.js +20 -13
  41. package/dist/api/app/bsky/feed/getSuggestedFeeds.js.map +1 -1
  42. package/dist/api/app/bsky/feed/getTimeline.d.ts.map +1 -1
  43. package/dist/api/app/bsky/feed/getTimeline.js +7 -2
  44. package/dist/api/app/bsky/feed/getTimeline.js.map +1 -1
  45. package/dist/api/app/bsky/feed/searchPosts.d.ts.map +1 -1
  46. package/dist/api/app/bsky/feed/searchPosts.js +14 -7
  47. package/dist/api/app/bsky/feed/searchPosts.js.map +1 -1
  48. package/dist/api/app/bsky/feed/searchPostsV2.d.ts.map +1 -1
  49. package/dist/api/app/bsky/feed/searchPostsV2.js +17 -9
  50. package/dist/api/app/bsky/feed/searchPostsV2.js.map +1 -1
  51. package/dist/api/app/bsky/graph/getActorStarterPacks.d.ts.map +1 -1
  52. package/dist/api/app/bsky/graph/getActorStarterPacks.js +7 -2
  53. package/dist/api/app/bsky/graph/getActorStarterPacks.js.map +1 -1
  54. package/dist/api/app/bsky/graph/getBlocks.d.ts.map +1 -1
  55. package/dist/api/app/bsky/graph/getBlocks.js +7 -2
  56. package/dist/api/app/bsky/graph/getBlocks.js.map +1 -1
  57. package/dist/api/app/bsky/graph/getFollowers.d.ts.map +1 -1
  58. package/dist/api/app/bsky/graph/getFollowers.js +10 -18
  59. package/dist/api/app/bsky/graph/getFollowers.js.map +1 -1
  60. package/dist/api/app/bsky/graph/getFollows.d.ts.map +1 -1
  61. package/dist/api/app/bsky/graph/getFollows.js +7 -2
  62. package/dist/api/app/bsky/graph/getFollows.js.map +1 -1
  63. package/dist/api/app/bsky/graph/getList.d.ts.map +1 -1
  64. package/dist/api/app/bsky/graph/getList.js +7 -2
  65. package/dist/api/app/bsky/graph/getList.js.map +1 -1
  66. package/dist/api/app/bsky/graph/getListBlocks.d.ts.map +1 -1
  67. package/dist/api/app/bsky/graph/getListBlocks.js +7 -2
  68. package/dist/api/app/bsky/graph/getListBlocks.js.map +1 -1
  69. package/dist/api/app/bsky/graph/getListMutes.d.ts.map +1 -1
  70. package/dist/api/app/bsky/graph/getListMutes.js +7 -2
  71. package/dist/api/app/bsky/graph/getListMutes.js.map +1 -1
  72. package/dist/api/app/bsky/graph/getLists.d.ts.map +1 -1
  73. package/dist/api/app/bsky/graph/getLists.js +9 -4
  74. package/dist/api/app/bsky/graph/getLists.js.map +1 -1
  75. package/dist/api/app/bsky/graph/getListsWithMembership.d.ts.map +1 -1
  76. package/dist/api/app/bsky/graph/getListsWithMembership.js +9 -4
  77. package/dist/api/app/bsky/graph/getListsWithMembership.js.map +1 -1
  78. package/dist/api/app/bsky/graph/getMutes.d.ts.map +1 -1
  79. package/dist/api/app/bsky/graph/getMutes.js +22 -30
  80. package/dist/api/app/bsky/graph/getMutes.js.map +1 -1
  81. package/dist/api/app/bsky/graph/getStarterPacksWithMembership.d.ts.map +1 -1
  82. package/dist/api/app/bsky/graph/getStarterPacksWithMembership.js +7 -2
  83. package/dist/api/app/bsky/graph/getStarterPacksWithMembership.js.map +1 -1
  84. package/dist/api/app/bsky/graph/searchStarterPacks.d.ts.map +1 -1
  85. package/dist/api/app/bsky/graph/searchStarterPacks.js +13 -6
  86. package/dist/api/app/bsky/graph/searchStarterPacks.js.map +1 -1
  87. package/dist/api/app/bsky/graph/searchStarterPacksV2.d.ts.map +1 -1
  88. package/dist/api/app/bsky/graph/searchStarterPacksV2.js +7 -2
  89. package/dist/api/app/bsky/graph/searchStarterPacksV2.js.map +1 -1
  90. package/dist/api/app/bsky/notification/listActivitySubscriptions.d.ts.map +1 -1
  91. package/dist/api/app/bsky/notification/listActivitySubscriptions.js +7 -2
  92. package/dist/api/app/bsky/notification/listActivitySubscriptions.js.map +1 -1
  93. package/dist/api/app/bsky/notification/listNotifications.d.ts.map +1 -1
  94. package/dist/api/app/bsky/notification/listNotifications.js +17 -35
  95. package/dist/api/app/bsky/notification/listNotifications.js.map +1 -1
  96. package/dist/api/app/bsky/unspecced/getPopularFeedGenerators.d.ts.map +1 -1
  97. package/dist/api/app/bsky/unspecced/getPopularFeedGenerators.js +49 -43
  98. package/dist/api/app/bsky/unspecced/getPopularFeedGenerators.js.map +1 -1
  99. package/dist/api/app/bsky/unspecced/getTrendingTopics.d.ts.map +1 -1
  100. package/dist/api/app/bsky/unspecced/getTrendingTopics.js +3 -14
  101. package/dist/api/app/bsky/unspecced/getTrendingTopics.js.map +1 -1
  102. package/dist/api/app/bsky/unspecced/getTrends.d.ts.map +1 -1
  103. package/dist/api/app/bsky/unspecced/getTrends.js +3 -14
  104. package/dist/api/app/bsky/unspecced/getTrends.js.map +1 -1
  105. package/dist/api/util.d.ts +15 -0
  106. package/dist/api/util.d.ts.map +1 -1
  107. package/dist/api/util.js +26 -0
  108. package/dist/api/util.js.map +1 -1
  109. package/dist/auth-verifier.d.ts.map +1 -1
  110. package/dist/auth-verifier.js +16 -9
  111. package/dist/auth-verifier.js.map +1 -1
  112. package/dist/config.d.ts +2 -0
  113. package/dist/config.d.ts.map +1 -1
  114. package/dist/config.js +5 -0
  115. package/dist/config.js.map +1 -1
  116. package/dist/data-plane/server/db/pagination.d.ts +8 -0
  117. package/dist/data-plane/server/db/pagination.d.ts.map +1 -1
  118. package/dist/data-plane/server/db/pagination.js +20 -2
  119. package/dist/data-plane/server/db/pagination.js.map +1 -1
  120. package/dist/data-plane/server/op-thread.d.ts +7 -0
  121. package/dist/data-plane/server/op-thread.d.ts.map +1 -0
  122. package/dist/data-plane/server/op-thread.js +71 -0
  123. package/dist/data-plane/server/op-thread.js.map +1 -0
  124. package/dist/data-plane/server/routes/activity-subscription.js +3 -3
  125. package/dist/data-plane/server/routes/activity-subscription.js.map +1 -1
  126. package/dist/data-plane/server/routes/blocks.js +6 -6
  127. package/dist/data-plane/server/routes/blocks.js.map +1 -1
  128. package/dist/data-plane/server/routes/bookmarks.js +3 -3
  129. package/dist/data-plane/server/routes/bookmarks.js.map +1 -1
  130. package/dist/data-plane/server/routes/drafts.js +3 -3
  131. package/dist/data-plane/server/routes/drafts.js.map +1 -1
  132. package/dist/data-plane/server/routes/feed-gens.js +14 -12
  133. package/dist/data-plane/server/routes/feed-gens.js.map +1 -1
  134. package/dist/data-plane/server/routes/feeds.d.ts.map +1 -1
  135. package/dist/data-plane/server/routes/feeds.js +36 -15
  136. package/dist/data-plane/server/routes/feeds.js.map +1 -1
  137. package/dist/data-plane/server/routes/follows.js +6 -6
  138. package/dist/data-plane/server/routes/follows.js.map +1 -1
  139. package/dist/data-plane/server/routes/likes.js +6 -6
  140. package/dist/data-plane/server/routes/likes.js.map +1 -1
  141. package/dist/data-plane/server/routes/lists.js +6 -6
  142. package/dist/data-plane/server/routes/lists.js.map +1 -1
  143. package/dist/data-plane/server/routes/mutes.js +7 -7
  144. package/dist/data-plane/server/routes/mutes.js.map +1 -1
  145. package/dist/data-plane/server/routes/notifs.js +3 -3
  146. package/dist/data-plane/server/routes/notifs.js.map +1 -1
  147. package/dist/data-plane/server/routes/quotes.js +3 -3
  148. package/dist/data-plane/server/routes/quotes.js.map +1 -1
  149. package/dist/data-plane/server/routes/records.d.ts +3 -1
  150. package/dist/data-plane/server/routes/records.d.ts.map +1 -1
  151. package/dist/data-plane/server/routes/records.js +41 -4
  152. package/dist/data-plane/server/routes/records.js.map +1 -1
  153. package/dist/data-plane/server/routes/reposts.js +6 -6
  154. package/dist/data-plane/server/routes/reposts.js.map +1 -1
  155. package/dist/data-plane/server/routes/search.js +9 -9
  156. package/dist/data-plane/server/routes/search.js.map +1 -1
  157. package/dist/data-plane/server/routes/starter-packs.js +3 -3
  158. package/dist/data-plane/server/routes/starter-packs.js.map +1 -1
  159. package/dist/data-plane/server/routes/threads.d.ts.map +1 -1
  160. package/dist/data-plane/server/routes/threads.js +3 -74
  161. package/dist/data-plane/server/routes/threads.js.map +1 -1
  162. package/dist/feature-gates/gates.d.ts +2 -1
  163. package/dist/feature-gates/gates.d.ts.map +1 -1
  164. package/dist/feature-gates/gates.js +2 -1
  165. package/dist/feature-gates/gates.js.map +1 -1
  166. package/dist/hydration/feed.d.ts +3 -0
  167. package/dist/hydration/feed.d.ts.map +1 -1
  168. package/dist/hydration/feed.js +12 -0
  169. package/dist/hydration/feed.js.map +1 -1
  170. package/dist/hydration/hydrator.d.ts.map +1 -1
  171. package/dist/hydration/hydrator.js +4 -2
  172. package/dist/hydration/hydrator.js.map +1 -1
  173. package/dist/image/server.d.ts +1 -1
  174. package/dist/image/server.d.ts.map +1 -1
  175. package/dist/image/server.js +40 -22
  176. package/dist/image/server.js.map +1 -1
  177. package/dist/lexicons/app/bsky/actor/contentVisibilityDeclaration.d.ts +3 -0
  178. package/dist/lexicons/app/bsky/actor/contentVisibilityDeclaration.d.ts.map +1 -0
  179. package/dist/lexicons/app/bsky/actor/contentVisibilityDeclaration.defs.d.ts +66 -0
  180. package/dist/lexicons/app/bsky/actor/contentVisibilityDeclaration.defs.d.ts.map +1 -0
  181. package/dist/lexicons/app/bsky/actor/contentVisibilityDeclaration.defs.js +26 -0
  182. package/dist/lexicons/app/bsky/actor/contentVisibilityDeclaration.defs.js.map +1 -0
  183. package/dist/lexicons/app/bsky/actor/contentVisibilityDeclaration.js +6 -0
  184. package/dist/lexicons/app/bsky/actor/contentVisibilityDeclaration.js.map +1 -0
  185. package/dist/lexicons/app/bsky/actor.d.ts +1 -0
  186. package/dist/lexicons/app/bsky/actor.d.ts.map +1 -1
  187. package/dist/lexicons/app/bsky/actor.js +1 -0
  188. package/dist/lexicons/app/bsky/actor.js.map +1 -1
  189. package/dist/lexicons/app/bsky/authCreatePosts.defs.d.ts.map +1 -1
  190. package/dist/lexicons/app/bsky/authCreatePosts.defs.js +5 -0
  191. package/dist/lexicons/app/bsky/authCreatePosts.defs.js.map +1 -1
  192. package/dist/lexicons/app/bsky/authFullApp.defs.d.ts.map +1 -1
  193. package/dist/lexicons/app/bsky/authFullApp.defs.js +5 -0
  194. package/dist/lexicons/app/bsky/authFullApp.defs.js.map +1 -1
  195. package/dist/lexicons/app/bsky/embed/video.defs.d.ts.map +1 -1
  196. package/dist/lexicons/app/bsky/embed/video.defs.js +2 -4
  197. package/dist/lexicons/app/bsky/embed/video.defs.js.map +1 -1
  198. package/dist/lexicons/app/bsky/video/abortUpload.d.ts +3 -0
  199. package/dist/lexicons/app/bsky/video/abortUpload.d.ts.map +1 -0
  200. package/dist/lexicons/app/bsky/video/abortUpload.defs.d.ts +53 -0
  201. package/dist/lexicons/app/bsky/video/abortUpload.defs.d.ts.map +1 -0
  202. package/dist/lexicons/app/bsky/video/abortUpload.defs.js +26 -0
  203. package/dist/lexicons/app/bsky/video/abortUpload.defs.js.map +1 -0
  204. package/dist/lexicons/app/bsky/video/abortUpload.js +6 -0
  205. package/dist/lexicons/app/bsky/video/abortUpload.js.map +1 -0
  206. package/dist/lexicons/app/bsky/video/defs.defs.d.ts +1 -1
  207. package/dist/lexicons/app/bsky/video/defs.defs.d.ts.map +1 -1
  208. package/dist/lexicons/app/bsky/video/defs.defs.js.map +1 -1
  209. package/dist/lexicons/app/bsky/video/finishUpload.d.ts +3 -0
  210. package/dist/lexicons/app/bsky/video/finishUpload.d.ts.map +1 -0
  211. package/dist/lexicons/app/bsky/video/finishUpload.defs.d.ts +42 -0
  212. package/dist/lexicons/app/bsky/video/finishUpload.defs.d.ts.map +1 -0
  213. package/dist/lexicons/app/bsky/video/finishUpload.defs.js +30 -0
  214. package/dist/lexicons/app/bsky/video/finishUpload.defs.js.map +1 -0
  215. package/dist/lexicons/app/bsky/video/finishUpload.js +6 -0
  216. package/dist/lexicons/app/bsky/video/finishUpload.js.map +1 -0
  217. package/dist/lexicons/app/bsky/video/getUploadStatus.d.ts +3 -0
  218. package/dist/lexicons/app/bsky/video/getUploadStatus.d.ts.map +1 -0
  219. package/dist/lexicons/app/bsky/video/getUploadStatus.defs.d.ts +73 -0
  220. package/dist/lexicons/app/bsky/video/getUploadStatus.defs.d.ts.map +1 -0
  221. package/dist/lexicons/app/bsky/video/getUploadStatus.defs.js +30 -0
  222. package/dist/lexicons/app/bsky/video/getUploadStatus.defs.js.map +1 -0
  223. package/dist/lexicons/app/bsky/video/getUploadStatus.js +6 -0
  224. package/dist/lexicons/app/bsky/video/getUploadStatus.js.map +1 -0
  225. package/dist/lexicons/app/bsky/video/startUpload.d.ts +3 -0
  226. package/dist/lexicons/app/bsky/video/startUpload.d.ts.map +1 -0
  227. package/dist/lexicons/app/bsky/video/startUpload.defs.d.ts +63 -0
  228. package/dist/lexicons/app/bsky/video/startUpload.defs.d.ts.map +1 -0
  229. package/dist/lexicons/app/bsky/video/startUpload.defs.js +36 -0
  230. package/dist/lexicons/app/bsky/video/startUpload.defs.js.map +1 -0
  231. package/dist/lexicons/app/bsky/video/startUpload.js +6 -0
  232. package/dist/lexicons/app/bsky/video/startUpload.js.map +1 -0
  233. package/dist/lexicons/app/bsky/video/uploadPart.d.ts +3 -0
  234. package/dist/lexicons/app/bsky/video/uploadPart.d.ts.map +1 -0
  235. package/dist/lexicons/app/bsky/video/uploadPart.defs.d.ts +37 -0
  236. package/dist/lexicons/app/bsky/video/uploadPart.defs.d.ts.map +1 -0
  237. package/dist/lexicons/app/bsky/video/uploadPart.defs.js +31 -0
  238. package/dist/lexicons/app/bsky/video/uploadPart.defs.js.map +1 -0
  239. package/dist/lexicons/app/bsky/video/uploadPart.js +6 -0
  240. package/dist/lexicons/app/bsky/video/uploadPart.js.map +1 -0
  241. package/dist/lexicons/app/bsky/video.d.ts +5 -0
  242. package/dist/lexicons/app/bsky/video.d.ts.map +1 -1
  243. package/dist/lexicons/app/bsky/video.js +5 -0
  244. package/dist/lexicons/app/bsky/video.js.map +1 -1
  245. package/dist/proto/bsky_pb.d.ts +39 -0
  246. package/dist/proto/bsky_pb.d.ts.map +1 -1
  247. package/dist/proto/bsky_pb.js +55 -0
  248. package/dist/proto/bsky_pb.js.map +1 -1
  249. package/dist/views/index.d.ts.map +1 -1
  250. package/dist/views/index.js +2 -0
  251. package/dist/views/index.js.map +1 -1
  252. package/dist/views/types.d.ts +4 -1
  253. package/dist/views/types.d.ts.map +1 -1
  254. package/dist/views/types.js.map +1 -1
  255. package/package.json +12 -12
@@ -1 +1 @@
1
- {"version":3,"file":"getFollows.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/graph/getFollows.ts"],"names":[],"mappings":"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","sourcesContent":["import { mapDefined } from '@atproto/common'\nimport type { AtUriString, DidString } from '@atproto/lex'\nimport { InvalidRequestError, type Server } from '@atproto/xrpc-server'\nimport type { AppContext } from '../../../../context.js'\nimport {\n type HydrateCtx,\n type Hydrator,\n mergeStates,\n} from '../../../../hydration/hydrator.js'\nimport { app } from '../../../../lexicons/index.js'\nimport {\n type HydrationFnInput,\n type PresentationFnInput,\n type RulesFnInput,\n type SkeletonFnInput,\n createPipeline,\n} from '../../../../pipeline.js'\nimport type { Views } from '../../../../views/index.js'\nimport { clearlyBadCursor, resHeaders } from '../../../util.js'\n\nexport default function (server: Server, ctx: AppContext) {\n const getFollows = createPipeline(skeleton, hydration, noBlocks, presentation)\n server.add(app.bsky.graph.getFollows, {\n auth: ctx.authVerifier.optionalStandardOrRole,\n handler: async ({ params, auth, req }) => {\n const { viewer, includeTakedowns, skipViewerBlocks } =\n ctx.authVerifier.parseCreds(auth)\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({\n labelers,\n viewer,\n includeTakedowns,\n skipViewerBlocks,\n })\n\n // @TODO ensure canViewTakedowns gets threaded through and applied properly\n const result = await getFollows({ ...params, hydrateCtx }, ctx)\n\n return {\n encoding: 'application/json',\n body: result,\n headers: resHeaders({ labelers: hydrateCtx.labelers }),\n }\n },\n })\n}\n\nconst skeleton = async (\n input: SkeletonFnInput<Context, Params>,\n): Promise<SkeletonState> => {\n const { params, ctx } = input\n const [subjectDid] = await ctx.hydrator.actor.getDidsDefined([params.actor])\n if (!subjectDid) {\n throw new InvalidRequestError(`Actor not found: ${params.actor}`)\n }\n if (clearlyBadCursor(params.cursor)) {\n return { subjectDid, followUris: [] }\n }\n const { follows, cursor } = await ctx.hydrator.graph.getActorFollows({\n did: subjectDid,\n cursor: params.cursor,\n limit: params.limit,\n sort: params.sort,\n })\n return {\n subjectDid,\n followUris: follows.map((f) => f.uri as AtUriString),\n cursor: cursor || undefined,\n }\n}\n\nconst hydration = async (\n input: HydrationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, params, skeleton } = input\n const { followUris, subjectDid } = skeleton\n const followState = await ctx.hydrator.hydrateFollows(\n followUris,\n params.hydrateCtx,\n )\n const dids = [subjectDid]\n if (followState.follows) {\n for (const follow of followState.follows.values()) {\n if (follow) {\n dids.push(follow.record.subject)\n }\n }\n }\n const profileState = await ctx.hydrator.hydrateProfiles(\n dids,\n params.hydrateCtx,\n )\n return mergeStates(followState, profileState)\n}\n\nconst noBlocks = (input: RulesFnInput<Context, Params, SkeletonState>) => {\n const { skeleton, params, hydration, ctx } = input\n const viewer = params.hydrateCtx.viewer\n skeleton.followUris = skeleton.followUris.filter((followUri) => {\n const follow = hydration.follows?.get(followUri)\n if (!follow) return false\n return (\n !hydration.followBlocks?.get(followUri) &&\n (!viewer ||\n !ctx.views.viewerBlockExists(follow.record.subject, hydration))\n )\n })\n return skeleton\n}\n\nconst presentation = (\n input: PresentationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, hydration, skeleton, params } = input\n const { subjectDid, followUris, cursor } = skeleton\n const isNoHosted = (did: DidString) =>\n ctx.views.actorIsNoHosted(did, hydration)\n\n const subject = ctx.views.profile(subjectDid, hydration)\n if (\n !subject ||\n (!params.hydrateCtx.includeTakedowns && isNoHosted(subjectDid))\n ) {\n throw new InvalidRequestError(`Actor not found: ${params.actor}`)\n }\n\n const follows = mapDefined(followUris, (followUri) => {\n const followDid = hydration.follows?.get(followUri)?.record.subject\n if (!followDid) return\n if (!params.hydrateCtx.includeTakedowns && isNoHosted(followDid)) {\n return\n }\n return ctx.views.profile(followDid, hydration)\n })\n\n return { follows, subject, cursor }\n}\n\ntype Context = {\n hydrator: Hydrator\n views: Views\n}\n\ntype Params = app.bsky.graph.getFollowers.$Params & {\n hydrateCtx: HydrateCtx\n}\n\ntype SkeletonState = {\n subjectDid: DidString\n followUris: AtUriString[]\n cursor?: string\n}\n"]}
1
+ {"version":3,"file":"getFollows.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/graph/getFollows.ts"],"names":[],"mappings":"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","sourcesContent":["import { mapDefined } from '@atproto/common'\nimport type { AtUriString, DidString } from '@atproto/lex'\nimport { InvalidRequestError, type Server } from '@atproto/xrpc-server'\nimport type { AppContext } from '../../../../context.js'\nimport {\n type HydrateCtx,\n type Hydrator,\n mergeStates,\n} from '../../../../hydration/hydrator.js'\nimport { app } from '../../../../lexicons/index.js'\nimport {\n type HydrationFnInput,\n type PresentationFnInput,\n type RulesFnInput,\n type SkeletonFnInput,\n createPipeline,\n} from '../../../../pipeline.js'\nimport type { Views } from '../../../../views/index.js'\nimport { clearlyBadCursor, fillPage, resHeaders } from '../../../util.js'\n\nexport default function (server: Server, ctx: AppContext) {\n const getFollows = createPipeline(skeleton, hydration, noBlocks, presentation)\n server.add(app.bsky.graph.getFollows, {\n auth: ctx.authVerifier.optionalStandardOrRole,\n handler: async ({ params, auth, req }) => {\n const { viewer, includeTakedowns, skipViewerBlocks } =\n ctx.authVerifier.parseCreds(auth)\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({\n labelers,\n viewer,\n includeTakedowns,\n skipViewerBlocks,\n })\n\n // @TODO ensure canViewTakedowns gets threaded through and applied properly\n const result = await fillPage({\n cursor: params.cursor,\n limit: params.limit,\n fetch: ({ cursor, limit }) =>\n getFollows({ ...params, cursor, limit, hydrateCtx }, ctx),\n items: (r) => r.follows,\n })\n\n return {\n encoding: 'application/json',\n body: result,\n headers: resHeaders({ labelers: hydrateCtx.labelers }),\n }\n },\n })\n}\n\nconst skeleton = async (\n input: SkeletonFnInput<Context, Params>,\n): Promise<SkeletonState> => {\n const { params, ctx } = input\n const [subjectDid] = await ctx.hydrator.actor.getDidsDefined([params.actor])\n if (!subjectDid) {\n throw new InvalidRequestError(`Actor not found: ${params.actor}`)\n }\n if (clearlyBadCursor(params.cursor)) {\n return { subjectDid, followUris: [] }\n }\n const { follows, cursor } = await ctx.hydrator.graph.getActorFollows({\n did: subjectDid,\n cursor: params.cursor,\n limit: params.limit,\n sort: params.sort,\n })\n return {\n subjectDid,\n followUris: follows.map((f) => f.uri as AtUriString),\n cursor: cursor || undefined,\n }\n}\n\nconst hydration = async (\n input: HydrationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, params, skeleton } = input\n const { followUris, subjectDid } = skeleton\n const followState = await ctx.hydrator.hydrateFollows(\n followUris,\n params.hydrateCtx,\n )\n const dids = [subjectDid]\n if (followState.follows) {\n for (const follow of followState.follows.values()) {\n if (follow) {\n dids.push(follow.record.subject)\n }\n }\n }\n const profileState = await ctx.hydrator.hydrateProfiles(\n dids,\n params.hydrateCtx,\n )\n return mergeStates(followState, profileState)\n}\n\nconst noBlocks = (input: RulesFnInput<Context, Params, SkeletonState>) => {\n const { skeleton, params, hydration, ctx } = input\n const viewer = params.hydrateCtx.viewer\n skeleton.followUris = skeleton.followUris.filter((followUri) => {\n const follow = hydration.follows?.get(followUri)\n if (!follow) return false\n return (\n !hydration.followBlocks?.get(followUri) &&\n (!viewer ||\n !ctx.views.viewerBlockExists(follow.record.subject, hydration))\n )\n })\n return skeleton\n}\n\nconst presentation = (\n input: PresentationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, hydration, skeleton, params } = input\n const { subjectDid, followUris, cursor } = skeleton\n const isNoHosted = (did: DidString) =>\n ctx.views.actorIsNoHosted(did, hydration)\n\n const subject = ctx.views.profile(subjectDid, hydration)\n if (\n !subject ||\n (!params.hydrateCtx.includeTakedowns && isNoHosted(subjectDid))\n ) {\n throw new InvalidRequestError(`Actor not found: ${params.actor}`)\n }\n\n const follows = mapDefined(followUris, (followUri) => {\n const followDid = hydration.follows?.get(followUri)?.record.subject\n if (!followDid) return\n if (!params.hydrateCtx.includeTakedowns && isNoHosted(followDid)) {\n return\n }\n return ctx.views.profile(followDid, hydration)\n })\n\n return { follows, subject, cursor }\n}\n\ntype Context = {\n hydrator: Hydrator\n views: Views\n}\n\ntype Params = app.bsky.graph.getFollowers.$Params & {\n hydrateCtx: HydrateCtx\n}\n\ntype SkeletonState = {\n subjectDid: DidString\n followUris: AtUriString[]\n cursor?: string\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"getList.d.ts","sourceRoot":"","sources":["../../../../../src/api/app/bsky/graph/getList.ts"],"names":[],"mappings":"AAEA,OAAO,EAAuB,KAAK,MAAM,EAAE,MAAM,sBAAsB,CAAA;AACvE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAoBxD,MAAM,CAAC,OAAO,WAAW,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,QAuBvD"}
1
+ {"version":3,"file":"getList.d.ts","sourceRoot":"","sources":["../../../../../src/api/app/bsky/graph/getList.ts"],"names":[],"mappings":"AAEA,OAAO,EAAuB,KAAK,MAAM,EAAE,MAAM,sBAAsB,CAAA;AACvE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAoBxD,MAAM,CAAC,OAAO,WAAW,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,QA6BvD"}
@@ -4,7 +4,7 @@ import { mergeManyStates, } from '../../../../hydration/hydrator.js';
4
4
  import { app } from '../../../../lexicons/index.js';
5
5
  import { createPipeline, } from '../../../../pipeline.js';
6
6
  import { uriToDid as didFromUri } from '../../../../util/uris.js';
7
- import { clearlyBadCursor, resHeaders } from '../../../util.js';
7
+ import { clearlyBadCursor, fillPage, resHeaders } from '../../../util.js';
8
8
  export default function (server, ctx) {
9
9
  const getList = createPipeline(skeleton, hydration, noBlocks, presentation);
10
10
  server.add(app.bsky.graph.getList, {
@@ -18,7 +18,12 @@ export default function (server, ctx) {
18
18
  includeTakedowns,
19
19
  skipViewerBlocks,
20
20
  });
21
- const result = await getList({ ...params, hydrateCtx }, ctx);
21
+ const result = await fillPage({
22
+ cursor: params.cursor,
23
+ limit: params.limit,
24
+ fetch: ({ cursor, limit }) => getList({ ...params, cursor, limit, hydrateCtx }, ctx),
25
+ items: (r) => r.items,
26
+ });
22
27
  return {
23
28
  encoding: 'application/json',
24
29
  body: result,
@@ -1 +1 @@
1
- {"version":3,"file":"getList.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/graph/getList.ts"],"names":[],"mappings":"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","sourcesContent":["import { mapDefined } from '@atproto/common'\nimport type { AtUriString, DidString } from '@atproto/lex'\nimport { InvalidRequestError, type Server } from '@atproto/xrpc-server'\nimport type { AppContext } from '../../../../context.js'\nimport {\n type HydrateCtx,\n type HydrationState,\n type Hydrator,\n mergeManyStates,\n} from '../../../../hydration/hydrator.js'\nimport { app } from '../../../../lexicons/index.js'\nimport {\n type HydrationFnInput,\n type PresentationFnInput,\n type RulesFnInput,\n type SkeletonFnInput,\n createPipeline,\n} from '../../../../pipeline.js'\nimport type { ListItemInfo } from '../../../../proto/bsky_pb.js'\nimport { uriToDid as didFromUri } from '../../../../util/uris.js'\nimport type { Views } from '../../../../views/index.js'\nimport { clearlyBadCursor, resHeaders } from '../../../util.js'\n\nexport default function (server: Server, ctx: AppContext) {\n const getList = createPipeline(skeleton, hydration, noBlocks, presentation)\n server.add(app.bsky.graph.getList, {\n auth: ctx.authVerifier.standardOptional,\n handler: async ({ params, auth, req }) => {\n const { viewer, includeTakedowns, skipViewerBlocks } =\n ctx.authVerifier.parseCreds(auth)\n\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({\n labelers,\n viewer,\n includeTakedowns,\n skipViewerBlocks,\n })\n const result = await getList({ ...params, hydrateCtx }, ctx)\n return {\n encoding: 'application/json',\n body: result,\n headers: resHeaders({ labelers: hydrateCtx.labelers }),\n }\n },\n })\n}\n\nconst skeleton = async (\n input: SkeletonFnInput<Context, Params>,\n): Promise<SkeletonState> => {\n const { ctx, params } = input\n if (clearlyBadCursor(params.cursor)) {\n return { listUri: params.list, listitems: [] }\n }\n const { listitems, cursor } = await ctx.hydrator.dataplane.getListMembers({\n listUri: params.list,\n limit: params.limit,\n cursor: params.cursor,\n })\n return {\n listUri: params.list,\n listitems,\n cursor: cursor || undefined,\n }\n}\n\nconst hydration = async (\n input: HydrationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, params, skeleton } = input\n const { listUri, listitems } = skeleton\n const [listState, profileState] = await Promise.all([\n ctx.hydrator.hydrateLists([listUri], params.hydrateCtx),\n ctx.hydrator.hydrateProfiles(\n listitems.map(({ did }) => did as DidString),\n params.hydrateCtx,\n ),\n ])\n const bidirectionalBlocks = await maybeGetBlocksForReferenceAndCurateList({\n ctx,\n params,\n skeleton,\n listState,\n })\n return mergeManyStates(listState, profileState, { bidirectionalBlocks })\n}\n\nconst noBlocks = (input: RulesFnInput<Context, Params, SkeletonState>) => {\n const { skeleton, hydration } = input\n const creator = didFromUri(skeleton.listUri)\n const blocks = hydration.bidirectionalBlocks?.get(creator)\n skeleton.listitems = skeleton.listitems.filter(({ did }) => {\n return !blocks?.get(did as DidString)\n })\n return skeleton\n}\n\nconst presentation = (\n input: PresentationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, skeleton, hydration } = input\n const { listUri, listitems, cursor } = skeleton\n const list = ctx.views.list(listUri, hydration)\n const items = mapDefined(listitems, ({ uri, did }) =>\n ctx.views.listItemView(uri as AtUriString, did as DidString, hydration),\n )\n if (!list) {\n throw new InvalidRequestError('List not found')\n }\n return { list, items, cursor }\n}\n\nconst maybeGetBlocksForReferenceAndCurateList = async (input: {\n ctx: Context\n listState: HydrationState\n skeleton: SkeletonState\n params: Params\n}) => {\n const { ctx, params, listState, skeleton } = input\n const { listitems } = skeleton\n const { list } = params\n const listRecord = listState.lists?.get(list)\n const creator = didFromUri(list)\n if (\n params.hydrateCtx.viewer === creator ||\n listRecord?.record.purpose === 'app.bsky.graph.defs#modlist'\n ) {\n return\n }\n const pairs: Map<DidString, DidString[]> = new Map()\n pairs.set(\n creator,\n listitems.map(({ did }) => did as DidString),\n )\n return await ctx.hydrator.hydrateBidirectionalBlocks(pairs, params.hydrateCtx)\n}\n\ntype Context = {\n hydrator: Hydrator\n views: Views\n}\n\ntype Params = app.bsky.graph.getList.$Params & {\n hydrateCtx: HydrateCtx\n}\n\ntype SkeletonState = {\n listUri: AtUriString\n listitems: ListItemInfo[]\n cursor?: string\n}\n"]}
1
+ {"version":3,"file":"getList.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/graph/getList.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAE5C,OAAO,EAAE,mBAAmB,EAAe,MAAM,sBAAsB,CAAA;AAEvE,OAAO,EAIL,eAAe,GAChB,MAAM,mCAAmC,CAAA;AAC1C,OAAO,EAAE,GAAG,EAAE,MAAM,+BAA+B,CAAA;AACnD,OAAO,EAKL,cAAc,GACf,MAAM,yBAAyB,CAAA;AAEhC,OAAO,EAAE,QAAQ,IAAI,UAAU,EAAE,MAAM,0BAA0B,CAAA;AAEjE,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAEzE,MAAM,CAAC,OAAO,WAAW,MAAc,EAAE,GAAe;IACtD,MAAM,OAAO,GAAG,cAAc,CAAC,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAA;IAC3E,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE;QACjC,IAAI,EAAE,GAAG,CAAC,YAAY,CAAC,gBAAgB;QACvC,OAAO,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE;YACvC,MAAM,EAAE,MAAM,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,GAClD,GAAG,CAAC,YAAY,CAAC,UAAU,CAAC,IAAI,CAAC,CAAA;YAEnC,MAAM,QAAQ,GAAG,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,CAAA;YACrC,MAAM,UAAU,GAAG,MAAM,GAAG,CAAC,QAAQ,CAAC,aAAa,CAAC;gBAClD,QAAQ;gBACR,MAAM;gBACN,gBAAgB;gBAChB,gBAAgB;aACjB,CAAC,CAAA;YACF,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC;gBAC5B,MAAM,EAAE,MAAM,CAAC,MAAM;gBACrB,KAAK,EAAE,MAAM,CAAC,KAAK;gBACnB,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE,CAC3B,OAAO,CAAC,EAAE,GAAG,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE,GAAG,CAAC;gBACxD,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK;aACtB,CAAC,CAAA;YACF,OAAO;gBACL,QAAQ,EAAE,kBAAkB;gBAC5B,IAAI,EAAE,MAAM;gBACZ,OAAO,EAAE,UAAU,CAAC,EAAE,QAAQ,EAAE,UAAU,CAAC,QAAQ,EAAE,CAAC;aACvD,CAAA;QACH,CAAC;KACF,CAAC,CAAA;AACJ,CAAC;AAED,MAAM,QAAQ,GAAG,KAAK,EACpB,KAAuC,EACf,EAAE;IAC1B,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,KAAK,CAAA;IAC7B,IAAI,gBAAgB,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;QACpC,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,CAAA;IAChD,CAAC;IACD,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC,cAAc,CAAC;QACxE,OAAO,EAAE,MAAM,CAAC,IAAI;QACpB,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,MAAM,EAAE,MAAM,CAAC,MAAM;KACtB,CAAC,CAAA;IACF,OAAO;QACL,OAAO,EAAE,MAAM,CAAC,IAAI;QACpB,SAAS;QACT,MAAM,EAAE,MAAM,IAAI,SAAS;KAC5B,CAAA;AACH,CAAC,CAAA;AAED,MAAM,SAAS,GAAG,KAAK,EACrB,KAAuD,EACvD,EAAE;IACF,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAA;IACvC,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,QAAQ,CAAA;IACvC,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QAClD,GAAG,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;QACvD,GAAG,CAAC,QAAQ,CAAC,eAAe,CAC1B,SAAS,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,GAAgB,CAAC,EAC5C,MAAM,CAAC,UAAU,CAClB;KACF,CAAC,CAAA;IACF,MAAM,mBAAmB,GAAG,MAAM,uCAAuC,CAAC;QACxE,GAAG;QACH,MAAM;QACN,QAAQ;QACR,SAAS;KACV,CAAC,CAAA;IACF,OAAO,eAAe,CAAC,SAAS,EAAE,YAAY,EAAE,EAAE,mBAAmB,EAAE,CAAC,CAAA;AAC1E,CAAC,CAAA;AAED,MAAM,QAAQ,GAAG,CAAC,KAAmD,EAAE,EAAE;IACvE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,KAAK,CAAA;IACrC,MAAM,OAAO,GAAG,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;IAC5C,MAAM,MAAM,GAAG,SAAS,CAAC,mBAAmB,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;IAC1D,QAAQ,CAAC,SAAS,GAAG,QAAQ,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE;QACzD,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,GAAgB,CAAC,CAAA;IACvC,CAAC,CAAC,CAAA;IACF,OAAO,QAAQ,CAAA;AACjB,CAAC,CAAA;AAED,MAAM,YAAY,GAAG,CACnB,KAA0D,EAC1D,EAAE;IACF,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,KAAK,CAAA;IAC1C,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,QAAQ,CAAA;IAC/C,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,CAAC,CAAA;IAC/C,MAAM,KAAK,GAAG,UAAU,CAAC,SAAS,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,CACnD,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC,GAAkB,EAAE,GAAgB,EAAE,SAAS,CAAC,CACxE,CAAA;IACD,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,mBAAmB,CAAC,gBAAgB,CAAC,CAAA;IACjD,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,CAAA;AAChC,CAAC,CAAA;AAED,MAAM,uCAAuC,GAAG,KAAK,EAAE,KAKtD,EAAE,EAAE;IACH,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAA;IAClD,MAAM,EAAE,SAAS,EAAE,GAAG,QAAQ,CAAA;IAC9B,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,CAAA;IACvB,MAAM,UAAU,GAAG,SAAS,CAAC,KAAK,EAAE,GAAG,CAAC,IAAI,CAAC,CAAA;IAC7C,MAAM,OAAO,GAAG,UAAU,CAAC,IAAI,CAAC,CAAA;IAChC,IACE,MAAM,CAAC,UAAU,CAAC,MAAM,KAAK,OAAO;QACpC,UAAU,EAAE,MAAM,CAAC,OAAO,KAAK,6BAA6B,EAC5D,CAAC;QACD,OAAM;IACR,CAAC;IACD,MAAM,KAAK,GAAgC,IAAI,GAAG,EAAE,CAAA;IACpD,KAAK,CAAC,GAAG,CACP,OAAO,EACP,SAAS,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,GAAgB,CAAC,CAC7C,CAAA;IACD,OAAO,MAAM,GAAG,CAAC,QAAQ,CAAC,0BAA0B,CAAC,KAAK,EAAE,MAAM,CAAC,UAAU,CAAC,CAAA;AAChF,CAAC,CAAA","sourcesContent":["import { mapDefined } from '@atproto/common'\nimport type { AtUriString, DidString } from '@atproto/lex'\nimport { InvalidRequestError, type Server } from '@atproto/xrpc-server'\nimport type { AppContext } from '../../../../context.js'\nimport {\n type HydrateCtx,\n type HydrationState,\n type Hydrator,\n mergeManyStates,\n} from '../../../../hydration/hydrator.js'\nimport { app } from '../../../../lexicons/index.js'\nimport {\n type HydrationFnInput,\n type PresentationFnInput,\n type RulesFnInput,\n type SkeletonFnInput,\n createPipeline,\n} from '../../../../pipeline.js'\nimport type { ListItemInfo } from '../../../../proto/bsky_pb.js'\nimport { uriToDid as didFromUri } from '../../../../util/uris.js'\nimport type { Views } from '../../../../views/index.js'\nimport { clearlyBadCursor, fillPage, resHeaders } from '../../../util.js'\n\nexport default function (server: Server, ctx: AppContext) {\n const getList = createPipeline(skeleton, hydration, noBlocks, presentation)\n server.add(app.bsky.graph.getList, {\n auth: ctx.authVerifier.standardOptional,\n handler: async ({ params, auth, req }) => {\n const { viewer, includeTakedowns, skipViewerBlocks } =\n ctx.authVerifier.parseCreds(auth)\n\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({\n labelers,\n viewer,\n includeTakedowns,\n skipViewerBlocks,\n })\n const result = await fillPage({\n cursor: params.cursor,\n limit: params.limit,\n fetch: ({ cursor, limit }) =>\n getList({ ...params, cursor, limit, hydrateCtx }, ctx),\n items: (r) => r.items,\n })\n return {\n encoding: 'application/json',\n body: result,\n headers: resHeaders({ labelers: hydrateCtx.labelers }),\n }\n },\n })\n}\n\nconst skeleton = async (\n input: SkeletonFnInput<Context, Params>,\n): Promise<SkeletonState> => {\n const { ctx, params } = input\n if (clearlyBadCursor(params.cursor)) {\n return { listUri: params.list, listitems: [] }\n }\n const { listitems, cursor } = await ctx.hydrator.dataplane.getListMembers({\n listUri: params.list,\n limit: params.limit,\n cursor: params.cursor,\n })\n return {\n listUri: params.list,\n listitems,\n cursor: cursor || undefined,\n }\n}\n\nconst hydration = async (\n input: HydrationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, params, skeleton } = input\n const { listUri, listitems } = skeleton\n const [listState, profileState] = await Promise.all([\n ctx.hydrator.hydrateLists([listUri], params.hydrateCtx),\n ctx.hydrator.hydrateProfiles(\n listitems.map(({ did }) => did as DidString),\n params.hydrateCtx,\n ),\n ])\n const bidirectionalBlocks = await maybeGetBlocksForReferenceAndCurateList({\n ctx,\n params,\n skeleton,\n listState,\n })\n return mergeManyStates(listState, profileState, { bidirectionalBlocks })\n}\n\nconst noBlocks = (input: RulesFnInput<Context, Params, SkeletonState>) => {\n const { skeleton, hydration } = input\n const creator = didFromUri(skeleton.listUri)\n const blocks = hydration.bidirectionalBlocks?.get(creator)\n skeleton.listitems = skeleton.listitems.filter(({ did }) => {\n return !blocks?.get(did as DidString)\n })\n return skeleton\n}\n\nconst presentation = (\n input: PresentationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, skeleton, hydration } = input\n const { listUri, listitems, cursor } = skeleton\n const list = ctx.views.list(listUri, hydration)\n const items = mapDefined(listitems, ({ uri, did }) =>\n ctx.views.listItemView(uri as AtUriString, did as DidString, hydration),\n )\n if (!list) {\n throw new InvalidRequestError('List not found')\n }\n return { list, items, cursor }\n}\n\nconst maybeGetBlocksForReferenceAndCurateList = async (input: {\n ctx: Context\n listState: HydrationState\n skeleton: SkeletonState\n params: Params\n}) => {\n const { ctx, params, listState, skeleton } = input\n const { listitems } = skeleton\n const { list } = params\n const listRecord = listState.lists?.get(list)\n const creator = didFromUri(list)\n if (\n params.hydrateCtx.viewer === creator ||\n listRecord?.record.purpose === 'app.bsky.graph.defs#modlist'\n ) {\n return\n }\n const pairs: Map<DidString, DidString[]> = new Map()\n pairs.set(\n creator,\n listitems.map(({ did }) => did as DidString),\n )\n return await ctx.hydrator.hydrateBidirectionalBlocks(pairs, params.hydrateCtx)\n}\n\ntype Context = {\n hydrator: Hydrator\n views: Views\n}\n\ntype Params = app.bsky.graph.getList.$Params & {\n hydrateCtx: HydrateCtx\n}\n\ntype SkeletonState = {\n listUri: AtUriString\n listitems: ListItemInfo[]\n cursor?: string\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"getListBlocks.d.ts","sourceRoot":"","sources":["../../../../../src/api/app/bsky/graph/getListBlocks.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAA;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAgBxD,MAAM,CAAC,OAAO,WAAW,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,QAqBvD"}
1
+ {"version":3,"file":"getListBlocks.d.ts","sourceRoot":"","sources":["../../../../../src/api/app/bsky/graph/getListBlocks.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAA;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAgBxD,MAAM,CAAC,OAAO,WAAW,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,QA2BvD"}
@@ -1,7 +1,7 @@
1
1
  import { mapDefined } from '@atproto/common';
2
2
  import { app } from '../../../../lexicons/index.js';
3
3
  import { createPipeline, noRules, } from '../../../../pipeline.js';
4
- import { clearlyBadCursor, resHeaders } from '../../../util.js';
4
+ import { clearlyBadCursor, fillPage, resHeaders } from '../../../util.js';
5
5
  export default function (server, ctx) {
6
6
  const getListBlocks = createPipeline(skeleton, hydration, noRules, presentation);
7
7
  server.add(app.bsky.graph.getListBlocks, {
@@ -10,7 +10,12 @@ export default function (server, ctx) {
10
10
  const viewer = auth.credentials.iss;
11
11
  const labelers = ctx.reqLabelers(req);
12
12
  const hydrateCtx = await ctx.hydrator.createContext({ labelers, viewer });
13
- const result = await getListBlocks({ ...params, hydrateCtx }, ctx);
13
+ const result = await fillPage({
14
+ cursor: params.cursor,
15
+ limit: params.limit,
16
+ fetch: ({ cursor, limit }) => getListBlocks({ ...params, cursor, limit, hydrateCtx }, ctx),
17
+ items: (r) => r.lists,
18
+ });
14
19
  return {
15
20
  encoding: 'application/json',
16
21
  body: result,
@@ -1 +1 @@
1
- {"version":3,"file":"getListBlocks.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/graph/getListBlocks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAQ5C,OAAO,EAAE,GAAG,EAAE,MAAM,+BAA+B,CAAA;AACnD,OAAO,EAIL,cAAc,EACd,OAAO,GACR,MAAM,yBAAyB,CAAA;AAEhC,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAE/D,MAAM,CAAC,OAAO,WAAW,MAAc,EAAE,GAAe;IACtD,MAAM,aAAa,GAAG,cAAc,CAClC,QAAQ,EACR,SAAS,EACT,OAAO,EACP,YAAY,CACb,CAAA;IACD,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,aAAa,EAAE;QACvC,IAAI,EAAE,GAAG,CAAC,YAAY,CAAC,QAAQ;QAC/B,OAAO,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE;YACvC,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAA;YACnC,MAAM,QAAQ,GAAG,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,CAAA;YACrC,MAAM,UAAU,GAAG,MAAM,GAAG,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAA;YACzE,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,EAAE,GAAG,MAAM,EAAE,UAAU,EAAE,EAAE,GAAG,CAAC,CAAA;YAClE,OAAO;gBACL,QAAQ,EAAE,kBAAkB;gBAC5B,IAAI,EAAE,MAAM;gBACZ,OAAO,EAAE,UAAU,CAAC,EAAE,QAAQ,EAAE,UAAU,CAAC,QAAQ,EAAE,CAAC;aACvD,CAAA;QACH,CAAC;KACF,CAAC,CAAA;AACJ,CAAC;AAED,MAAM,QAAQ,GAAG,KAAK,EACpB,KAAuC,EACf,EAAE;IAC1B,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,KAAK,CAAA;IAC7B,IAAI,gBAAgB,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;QACpC,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAA;IACzB,CAAC;IACD,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GACxB,MAAM,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC,yBAAyB,CAAC;QACrD,QAAQ,EAAE,MAAM,CAAC,UAAU,CAAC,MAAM;QAClC,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,KAAK,EAAE,MAAM,CAAC,KAAK;KACpB,CAAC,CAAA;IACJ,OAAO,EAAE,QAAQ,EAAE,QAAyB,EAAE,MAAM,EAAE,MAAM,IAAI,SAAS,EAAE,CAAA;AAC7E,CAAC,CAAA;AAED,MAAM,SAAS,GAAG,KAAK,EACrB,KAAuD,EACvD,EAAE;IACF,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAA;IACvC,OAAO,MAAM,GAAG,CAAC,QAAQ,CAAC,YAAY,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,UAAU,CAAC,CAAA;AAC9E,CAAC,CAAA;AAED,MAAM,YAAY,GAAG,CACnB,KAA0D,EAC1D,EAAE;IACF,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,KAAK,CAAA;IAC1C,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,QAAQ,CAAA;IACrC,MAAM,KAAK,GAAG,UAAU,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC,CAAA;IAC3E,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAA;AAC1B,CAAC,CAAA","sourcesContent":["import { mapDefined } from '@atproto/common'\nimport type { AtUriString } from '@atproto/lex'\nimport type { Server } from '@atproto/xrpc-server'\nimport type { AppContext } from '../../../../context.js'\nimport type {\n HydrateCtxWithViewer,\n Hydrator,\n} from '../../../../hydration/hydrator.js'\nimport { app } from '../../../../lexicons/index.js'\nimport {\n type HydrationFnInput,\n type PresentationFnInput,\n type SkeletonFnInput,\n createPipeline,\n noRules,\n} from '../../../../pipeline.js'\nimport type { Views } from '../../../../views/index.js'\nimport { clearlyBadCursor, resHeaders } from '../../../util.js'\n\nexport default function (server: Server, ctx: AppContext) {\n const getListBlocks = createPipeline(\n skeleton,\n hydration,\n noRules,\n presentation,\n )\n server.add(app.bsky.graph.getListBlocks, {\n auth: ctx.authVerifier.standard,\n handler: async ({ params, auth, req }) => {\n const viewer = auth.credentials.iss\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({ labelers, viewer })\n const result = await getListBlocks({ ...params, hydrateCtx }, ctx)\n return {\n encoding: 'application/json',\n body: result,\n headers: resHeaders({ labelers: hydrateCtx.labelers }),\n }\n },\n })\n}\n\nconst skeleton = async (\n input: SkeletonFnInput<Context, Params>,\n): Promise<SkeletonState> => {\n const { ctx, params } = input\n if (clearlyBadCursor(params.cursor)) {\n return { listUris: [] }\n }\n const { listUris, cursor } =\n await ctx.hydrator.dataplane.getBlocklistSubscriptions({\n actorDid: params.hydrateCtx.viewer,\n cursor: params.cursor,\n limit: params.limit,\n })\n return { listUris: listUris as AtUriString[], cursor: cursor || undefined }\n}\n\nconst hydration = async (\n input: HydrationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, params, skeleton } = input\n return await ctx.hydrator.hydrateLists(skeleton.listUris, params.hydrateCtx)\n}\n\nconst presentation = (\n input: PresentationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, skeleton, hydration } = input\n const { listUris, cursor } = skeleton\n const lists = mapDefined(listUris, (uri) => ctx.views.list(uri, hydration))\n return { lists, cursor }\n}\n\ntype Context = {\n hydrator: Hydrator\n views: Views\n}\n\ntype Params = app.bsky.graph.getListBlocks.$Params & {\n hydrateCtx: HydrateCtxWithViewer\n}\n\ntype SkeletonState = {\n listUris: AtUriString[]\n cursor?: string\n}\n"]}
1
+ {"version":3,"file":"getListBlocks.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/graph/getListBlocks.ts"],"names":[],"mappings":"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","sourcesContent":["import { mapDefined } from '@atproto/common'\nimport type { AtUriString } from '@atproto/lex'\nimport type { Server } from '@atproto/xrpc-server'\nimport type { AppContext } from '../../../../context.js'\nimport type {\n HydrateCtxWithViewer,\n Hydrator,\n} from '../../../../hydration/hydrator.js'\nimport { app } from '../../../../lexicons/index.js'\nimport {\n type HydrationFnInput,\n type PresentationFnInput,\n type SkeletonFnInput,\n createPipeline,\n noRules,\n} from '../../../../pipeline.js'\nimport type { Views } from '../../../../views/index.js'\nimport { clearlyBadCursor, fillPage, resHeaders } from '../../../util.js'\n\nexport default function (server: Server, ctx: AppContext) {\n const getListBlocks = createPipeline(\n skeleton,\n hydration,\n noRules,\n presentation,\n )\n server.add(app.bsky.graph.getListBlocks, {\n auth: ctx.authVerifier.standard,\n handler: async ({ params, auth, req }) => {\n const viewer = auth.credentials.iss\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({ labelers, viewer })\n const result = await fillPage({\n cursor: params.cursor,\n limit: params.limit,\n fetch: ({ cursor, limit }) =>\n getListBlocks({ ...params, cursor, limit, hydrateCtx }, ctx),\n items: (r) => r.lists,\n })\n return {\n encoding: 'application/json',\n body: result,\n headers: resHeaders({ labelers: hydrateCtx.labelers }),\n }\n },\n })\n}\n\nconst skeleton = async (\n input: SkeletonFnInput<Context, Params>,\n): Promise<SkeletonState> => {\n const { ctx, params } = input\n if (clearlyBadCursor(params.cursor)) {\n return { listUris: [] }\n }\n const { listUris, cursor } =\n await ctx.hydrator.dataplane.getBlocklistSubscriptions({\n actorDid: params.hydrateCtx.viewer,\n cursor: params.cursor,\n limit: params.limit,\n })\n return { listUris: listUris as AtUriString[], cursor: cursor || undefined }\n}\n\nconst hydration = async (\n input: HydrationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, params, skeleton } = input\n return await ctx.hydrator.hydrateLists(skeleton.listUris, params.hydrateCtx)\n}\n\nconst presentation = (\n input: PresentationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, skeleton, hydration } = input\n const { listUris, cursor } = skeleton\n const lists = mapDefined(listUris, (uri) => ctx.views.list(uri, hydration))\n return { lists, cursor }\n}\n\ntype Context = {\n hydrator: Hydrator\n views: Views\n}\n\ntype Params = app.bsky.graph.getListBlocks.$Params & {\n hydrateCtx: HydrateCtxWithViewer\n}\n\ntype SkeletonState = {\n listUris: AtUriString[]\n cursor?: string\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"getListMutes.d.ts","sourceRoot":"","sources":["../../../../../src/api/app/bsky/graph/getListMutes.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAA;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAgBxD,MAAM,CAAC,OAAO,WAAW,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,QAqBvD"}
1
+ {"version":3,"file":"getListMutes.d.ts","sourceRoot":"","sources":["../../../../../src/api/app/bsky/graph/getListMutes.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAA;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAgBxD,MAAM,CAAC,OAAO,WAAW,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,QA2BvD"}
@@ -1,7 +1,7 @@
1
1
  import { mapDefined } from '@atproto/common';
2
2
  import { app } from '../../../../lexicons/index.js';
3
3
  import { createPipeline, noRules, } from '../../../../pipeline.js';
4
- import { clearlyBadCursor, resHeaders } from '../../../util.js';
4
+ import { clearlyBadCursor, fillPage, resHeaders } from '../../../util.js';
5
5
  export default function (server, ctx) {
6
6
  const getListMutes = createPipeline(skeleton, hydration, noRules, presentation);
7
7
  server.add(app.bsky.graph.getListMutes, {
@@ -10,7 +10,12 @@ export default function (server, ctx) {
10
10
  const viewer = auth.credentials.iss;
11
11
  const labelers = ctx.reqLabelers(req);
12
12
  const hydrateCtx = await ctx.hydrator.createContext({ labelers, viewer });
13
- const result = await getListMutes({ ...params, hydrateCtx }, ctx);
13
+ const result = await fillPage({
14
+ cursor: params.cursor,
15
+ limit: params.limit,
16
+ fetch: ({ cursor, limit }) => getListMutes({ ...params, cursor, limit, hydrateCtx }, ctx),
17
+ items: (r) => r.lists,
18
+ });
14
19
  return {
15
20
  encoding: 'application/json',
16
21
  body: result,
@@ -1 +1 @@
1
- {"version":3,"file":"getListMutes.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/graph/getListMutes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAQ5C,OAAO,EAAE,GAAG,EAAE,MAAM,+BAA+B,CAAA;AACnD,OAAO,EAIL,cAAc,EACd,OAAO,GACR,MAAM,yBAAyB,CAAA;AAEhC,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAE/D,MAAM,CAAC,OAAO,WAAW,MAAc,EAAE,GAAe;IACtD,MAAM,YAAY,GAAG,cAAc,CACjC,QAAQ,EACR,SAAS,EACT,OAAO,EACP,YAAY,CACb,CAAA;IACD,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE;QACtC,IAAI,EAAE,GAAG,CAAC,YAAY,CAAC,QAAQ;QAC/B,OAAO,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE;YACvC,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAA;YACnC,MAAM,QAAQ,GAAG,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,CAAA;YACrC,MAAM,UAAU,GAAG,MAAM,GAAG,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAA;YACzE,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,EAAE,GAAG,MAAM,EAAE,UAAU,EAAE,EAAE,GAAG,CAAC,CAAA;YACjE,OAAO;gBACL,QAAQ,EAAE,kBAAkB;gBAC5B,IAAI,EAAE,MAAM;gBACZ,OAAO,EAAE,UAAU,CAAC,EAAE,QAAQ,EAAE,UAAU,CAAC,QAAQ,EAAE,CAAC;aACvD,CAAA;QACH,CAAC;KACF,CAAC,CAAA;AACJ,CAAC;AAED,MAAM,QAAQ,GAAG,KAAK,EACpB,KAAuC,EACf,EAAE;IAC1B,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,KAAK,CAAA;IAC7B,IAAI,gBAAgB,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;QACpC,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAA;IACzB,CAAC;IACD,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GACxB,MAAM,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC,wBAAwB,CAAC;QACpD,QAAQ,EAAE,MAAM,CAAC,UAAU,CAAC,MAAM;QAClC,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,KAAK,EAAE,MAAM,CAAC,KAAK;KACpB,CAAC,CAAA;IACJ,OAAO,EAAE,QAAQ,EAAE,QAAyB,EAAE,MAAM,EAAE,MAAM,IAAI,SAAS,EAAE,CAAA;AAC7E,CAAC,CAAA;AAED,MAAM,SAAS,GAAG,KAAK,EACrB,KAAuD,EACvD,EAAE;IACF,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAA;IACvC,OAAO,MAAM,GAAG,CAAC,QAAQ,CAAC,YAAY,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,UAAU,CAAC,CAAA;AAC9E,CAAC,CAAA;AAED,MAAM,YAAY,GAAG,CACnB,KAA0D,EAC1D,EAAE;IACF,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,KAAK,CAAA;IAC1C,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,QAAQ,CAAA;IACrC,MAAM,KAAK,GAAG,UAAU,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC,CAAA;IAC3E,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAA;AAC1B,CAAC,CAAA","sourcesContent":["import { mapDefined } from '@atproto/common'\nimport type { AtUriString } from '@atproto/lex'\nimport type { Server } from '@atproto/xrpc-server'\nimport type { AppContext } from '../../../../context.js'\nimport type {\n HydrateCtxWithViewer,\n Hydrator,\n} from '../../../../hydration/hydrator.js'\nimport { app } from '../../../../lexicons/index.js'\nimport {\n type HydrationFnInput,\n type PresentationFnInput,\n type SkeletonFnInput,\n createPipeline,\n noRules,\n} from '../../../../pipeline.js'\nimport type { Views } from '../../../../views/index.js'\nimport { clearlyBadCursor, resHeaders } from '../../../util.js'\n\nexport default function (server: Server, ctx: AppContext) {\n const getListMutes = createPipeline(\n skeleton,\n hydration,\n noRules,\n presentation,\n )\n server.add(app.bsky.graph.getListMutes, {\n auth: ctx.authVerifier.standard,\n handler: async ({ params, auth, req }) => {\n const viewer = auth.credentials.iss\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({ labelers, viewer })\n const result = await getListMutes({ ...params, hydrateCtx }, ctx)\n return {\n encoding: 'application/json',\n body: result,\n headers: resHeaders({ labelers: hydrateCtx.labelers }),\n }\n },\n })\n}\n\nconst skeleton = async (\n input: SkeletonFnInput<Context, Params>,\n): Promise<SkeletonState> => {\n const { ctx, params } = input\n if (clearlyBadCursor(params.cursor)) {\n return { listUris: [] }\n }\n const { listUris, cursor } =\n await ctx.hydrator.dataplane.getMutelistSubscriptions({\n actorDid: params.hydrateCtx.viewer,\n cursor: params.cursor,\n limit: params.limit,\n })\n return { listUris: listUris as AtUriString[], cursor: cursor || undefined }\n}\n\nconst hydration = async (\n input: HydrationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, params, skeleton } = input\n return await ctx.hydrator.hydrateLists(skeleton.listUris, params.hydrateCtx)\n}\n\nconst presentation = (\n input: PresentationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, skeleton, hydration } = input\n const { listUris, cursor } = skeleton\n const lists = mapDefined(listUris, (uri) => ctx.views.list(uri, hydration))\n return { lists, cursor }\n}\n\ntype Context = {\n hydrator: Hydrator\n views: Views\n}\n\ntype Params = app.bsky.graph.getListBlocks.$Params & {\n hydrateCtx: HydrateCtxWithViewer\n}\n\ntype SkeletonState = {\n listUris: AtUriString[]\n cursor?: string\n}\n"]}
1
+ {"version":3,"file":"getListMutes.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/graph/getListMutes.ts"],"names":[],"mappings":"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","sourcesContent":["import { mapDefined } from '@atproto/common'\nimport type { AtUriString } from '@atproto/lex'\nimport type { Server } from '@atproto/xrpc-server'\nimport type { AppContext } from '../../../../context.js'\nimport type {\n HydrateCtxWithViewer,\n Hydrator,\n} from '../../../../hydration/hydrator.js'\nimport { app } from '../../../../lexicons/index.js'\nimport {\n type HydrationFnInput,\n type PresentationFnInput,\n type SkeletonFnInput,\n createPipeline,\n noRules,\n} from '../../../../pipeline.js'\nimport type { Views } from '../../../../views/index.js'\nimport { clearlyBadCursor, fillPage, resHeaders } from '../../../util.js'\n\nexport default function (server: Server, ctx: AppContext) {\n const getListMutes = createPipeline(\n skeleton,\n hydration,\n noRules,\n presentation,\n )\n server.add(app.bsky.graph.getListMutes, {\n auth: ctx.authVerifier.standard,\n handler: async ({ params, auth, req }) => {\n const viewer = auth.credentials.iss\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({ labelers, viewer })\n const result = await fillPage({\n cursor: params.cursor,\n limit: params.limit,\n fetch: ({ cursor, limit }) =>\n getListMutes({ ...params, cursor, limit, hydrateCtx }, ctx),\n items: (r) => r.lists,\n })\n return {\n encoding: 'application/json',\n body: result,\n headers: resHeaders({ labelers: hydrateCtx.labelers }),\n }\n },\n })\n}\n\nconst skeleton = async (\n input: SkeletonFnInput<Context, Params>,\n): Promise<SkeletonState> => {\n const { ctx, params } = input\n if (clearlyBadCursor(params.cursor)) {\n return { listUris: [] }\n }\n const { listUris, cursor } =\n await ctx.hydrator.dataplane.getMutelistSubscriptions({\n actorDid: params.hydrateCtx.viewer,\n cursor: params.cursor,\n limit: params.limit,\n })\n return { listUris: listUris as AtUriString[], cursor: cursor || undefined }\n}\n\nconst hydration = async (\n input: HydrationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, params, skeleton } = input\n return await ctx.hydrator.hydrateLists(skeleton.listUris, params.hydrateCtx)\n}\n\nconst presentation = (\n input: PresentationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, skeleton, hydration } = input\n const { listUris, cursor } = skeleton\n const lists = mapDefined(listUris, (uri) => ctx.views.list(uri, hydration))\n return { lists, cursor }\n}\n\ntype Context = {\n hydrator: Hydrator\n views: Views\n}\n\ntype Params = app.bsky.graph.getListBlocks.$Params & {\n hydrateCtx: HydrateCtxWithViewer\n}\n\ntype SkeletonState = {\n listUris: AtUriString[]\n cursor?: string\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"getLists.d.ts","sourceRoot":"","sources":["../../../../../src/api/app/bsky/graph/getLists.ts"],"names":[],"mappings":"AAEA,OAAO,EAAuB,KAAK,MAAM,EAAE,MAAM,sBAAsB,CAAA;AACvE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAiBxD,MAAM,CAAC,OAAO,WAAW,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,QA4BvD"}
1
+ {"version":3,"file":"getLists.d.ts","sourceRoot":"","sources":["../../../../../src/api/app/bsky/graph/getLists.ts"],"names":[],"mappings":"AAEA,OAAO,EAAuB,KAAK,MAAM,EAAE,MAAM,sBAAsB,CAAA;AACvE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAiBxD,MAAM,CAAC,OAAO,WAAW,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,QAkCvD"}
@@ -3,7 +3,7 @@ import { InvalidRequestError } from '@atproto/xrpc-server';
3
3
  import { parseString } from '../../../../hydration/util.js';
4
4
  import { app } from '../../../../lexicons/index.js';
5
5
  import { createPipeline, } from '../../../../pipeline.js';
6
- import { clearlyBadCursor, resHeaders } from '../../../util.js';
6
+ import { clearlyBadCursor, fillPage, resHeaders } from '../../../util.js';
7
7
  const CURATELIST = app.bsky.graph.defs.curatelist.value;
8
8
  const MODLIST = app.bsky.graph.defs.modlist.value;
9
9
  export default function (server, ctx) {
@@ -19,7 +19,12 @@ export default function (server, ctx) {
19
19
  includeTakedowns,
20
20
  skipViewerBlocks,
21
21
  });
22
- const result = await getLists({ ...params, hydrateCtx }, ctx);
22
+ const result = await fillPage({
23
+ cursor: params.cursor,
24
+ limit: params.limit,
25
+ fetch: ({ cursor, limit }) => getLists({ ...params, cursor, limit, hydrateCtx }, ctx),
26
+ items: (r) => r.lists,
27
+ });
23
28
  return {
24
29
  encoding: 'application/json',
25
30
  body: result,
@@ -63,8 +68,8 @@ const filterPurposes = (input) => {
63
68
  acceptedPurposes.add(CURATELIST);
64
69
  if (purposes.includes(CURATELIST))
65
70
  acceptedPurposes.add(CURATELIST);
66
- // @NOTE: While we don't support filtering on the dataplane, this might result in empty pages.
67
- // Despite the empty pages, the pagination still can enumerate all items for the specified filters.
71
+ // Purpose filtering happens after dataplane pagination. fillPage requests
72
+ // subsequent dataplane pages to replace lists filtered out here.
68
73
  skeleton.listUris = skeleton.listUris.filter((uri) => {
69
74
  const list = hydration.lists?.get(uri);
70
75
  return acceptedPurposes.has(list?.record.purpose);
@@ -1 +1 @@
1
- {"version":3,"file":"getLists.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/graph/getLists.ts"],"names":[],"mappings":"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","sourcesContent":["import { mapDefined } from '@atproto/common'\nimport type { AtUriString } from '@atproto/syntax'\nimport { InvalidRequestError, type Server } from '@atproto/xrpc-server'\nimport type { AppContext } from '../../../../context.js'\nimport type { HydrateCtx, Hydrator } from '../../../../hydration/hydrator.js'\nimport { parseString } from '../../../../hydration/util.js'\nimport { app } from '../../../../lexicons/index.js'\nimport {\n type HydrationFnInput,\n type PresentationFnInput,\n type RulesFnInput,\n type SkeletonFnInput,\n createPipeline,\n} from '../../../../pipeline.js'\nimport type { Views } from '../../../../views/index.js'\nimport { clearlyBadCursor, resHeaders } from '../../../util.js'\n\nconst CURATELIST = app.bsky.graph.defs.curatelist.value\nconst MODLIST = app.bsky.graph.defs.modlist.value\n\nexport default function (server: Server, ctx: AppContext) {\n const getLists = createPipeline(\n skeleton,\n hydration,\n filterPurposes,\n presentation,\n )\n server.add(app.bsky.graph.getLists, {\n auth: ctx.authVerifier.optionalStandardOrRole,\n handler: async ({ params, auth, req }) => {\n const labelers = ctx.reqLabelers(req)\n const { viewer, includeTakedowns, skipViewerBlocks } =\n ctx.authVerifier.parseCreds(auth)\n const hydrateCtx = await ctx.hydrator.createContext({\n labelers,\n viewer,\n includeTakedowns,\n skipViewerBlocks,\n })\n const result = await getLists({ ...params, hydrateCtx }, ctx)\n\n return {\n encoding: 'application/json',\n body: result,\n headers: resHeaders({ labelers: hydrateCtx.labelers }),\n }\n },\n })\n}\n\nconst skeleton = async (\n input: SkeletonFnInput<Context, Params>,\n): Promise<SkeletonState> => {\n const { ctx, params } = input\n if (clearlyBadCursor(params.cursor)) {\n return { listUris: [] }\n }\n\n const [did] = await ctx.hydrator.actor.getDids([params.actor])\n if (!did) throw new InvalidRequestError('Profile not found')\n\n const { listUris, cursor } = await ctx.hydrator.dataplane.getActorLists({\n actorDid: did,\n cursor: params.cursor,\n limit: params.limit,\n })\n return {\n listUris: listUris as AtUriString[],\n cursor: parseString(cursor),\n }\n}\n\nconst hydration = async (\n input: HydrationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, params, skeleton } = input\n const { listUris } = skeleton\n return ctx.hydrator.hydrateLists(listUris, params.hydrateCtx)\n}\n\nconst filterPurposes = (\n input: RulesFnInput<Context, Params, SkeletonState>,\n) => {\n const { skeleton, hydration, params } = input\n const purposes = params.purposes || ['modlist', 'curatelist']\n\n const acceptedPurposes = new Set()\n if (purposes.includes('modlist')) acceptedPurposes.add(MODLIST)\n if (purposes.includes(MODLIST)) acceptedPurposes.add(MODLIST)\n if (purposes.includes('curatelist')) acceptedPurposes.add(CURATELIST)\n if (purposes.includes(CURATELIST)) acceptedPurposes.add(CURATELIST)\n\n // @NOTE: While we don't support filtering on the dataplane, this might result in empty pages.\n // Despite the empty pages, the pagination still can enumerate all items for the specified filters.\n skeleton.listUris = skeleton.listUris.filter((uri) => {\n const list = hydration.lists?.get(uri)\n return acceptedPurposes.has(list?.record.purpose)\n })\n return skeleton\n}\n\nconst presentation = (\n input: PresentationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, skeleton, hydration } = input\n const { listUris, cursor } = skeleton\n const lists = mapDefined(listUris, (uri) => {\n return ctx.views.list(uri, hydration)\n })\n return { lists, cursor }\n}\n\ntype Context = {\n hydrator: Hydrator\n views: Views\n}\n\ntype Params = app.bsky.graph.getLists.$Params & {\n hydrateCtx: HydrateCtx\n}\n\ntype SkeletonState = {\n listUris: AtUriString[]\n cursor?: string\n}\n"]}
1
+ {"version":3,"file":"getLists.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/graph/getLists.ts"],"names":[],"mappings":"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","sourcesContent":["import { mapDefined } from '@atproto/common'\nimport type { AtUriString } from '@atproto/syntax'\nimport { InvalidRequestError, type Server } from '@atproto/xrpc-server'\nimport type { AppContext } from '../../../../context.js'\nimport type { HydrateCtx, Hydrator } from '../../../../hydration/hydrator.js'\nimport { parseString } from '../../../../hydration/util.js'\nimport { app } from '../../../../lexicons/index.js'\nimport {\n type HydrationFnInput,\n type PresentationFnInput,\n type RulesFnInput,\n type SkeletonFnInput,\n createPipeline,\n} from '../../../../pipeline.js'\nimport type { Views } from '../../../../views/index.js'\nimport { clearlyBadCursor, fillPage, resHeaders } from '../../../util.js'\n\nconst CURATELIST = app.bsky.graph.defs.curatelist.value\nconst MODLIST = app.bsky.graph.defs.modlist.value\n\nexport default function (server: Server, ctx: AppContext) {\n const getLists = createPipeline(\n skeleton,\n hydration,\n filterPurposes,\n presentation,\n )\n server.add(app.bsky.graph.getLists, {\n auth: ctx.authVerifier.optionalStandardOrRole,\n handler: async ({ params, auth, req }) => {\n const labelers = ctx.reqLabelers(req)\n const { viewer, includeTakedowns, skipViewerBlocks } =\n ctx.authVerifier.parseCreds(auth)\n const hydrateCtx = await ctx.hydrator.createContext({\n labelers,\n viewer,\n includeTakedowns,\n skipViewerBlocks,\n })\n const result = await fillPage({\n cursor: params.cursor,\n limit: params.limit,\n fetch: ({ cursor, limit }) =>\n getLists({ ...params, cursor, limit, hydrateCtx }, ctx),\n items: (r) => r.lists,\n })\n\n return {\n encoding: 'application/json',\n body: result,\n headers: resHeaders({ labelers: hydrateCtx.labelers }),\n }\n },\n })\n}\n\nconst skeleton = async (\n input: SkeletonFnInput<Context, Params>,\n): Promise<SkeletonState> => {\n const { ctx, params } = input\n if (clearlyBadCursor(params.cursor)) {\n return { listUris: [] }\n }\n\n const [did] = await ctx.hydrator.actor.getDids([params.actor])\n if (!did) throw new InvalidRequestError('Profile not found')\n\n const { listUris, cursor } = await ctx.hydrator.dataplane.getActorLists({\n actorDid: did,\n cursor: params.cursor,\n limit: params.limit,\n })\n return {\n listUris: listUris as AtUriString[],\n cursor: parseString(cursor),\n }\n}\n\nconst hydration = async (\n input: HydrationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, params, skeleton } = input\n const { listUris } = skeleton\n return ctx.hydrator.hydrateLists(listUris, params.hydrateCtx)\n}\n\nconst filterPurposes = (\n input: RulesFnInput<Context, Params, SkeletonState>,\n) => {\n const { skeleton, hydration, params } = input\n const purposes = params.purposes || ['modlist', 'curatelist']\n\n const acceptedPurposes = new Set()\n if (purposes.includes('modlist')) acceptedPurposes.add(MODLIST)\n if (purposes.includes(MODLIST)) acceptedPurposes.add(MODLIST)\n if (purposes.includes('curatelist')) acceptedPurposes.add(CURATELIST)\n if (purposes.includes(CURATELIST)) acceptedPurposes.add(CURATELIST)\n\n // Purpose filtering happens after dataplane pagination. fillPage requests\n // subsequent dataplane pages to replace lists filtered out here.\n skeleton.listUris = skeleton.listUris.filter((uri) => {\n const list = hydration.lists?.get(uri)\n return acceptedPurposes.has(list?.record.purpose)\n })\n return skeleton\n}\n\nconst presentation = (\n input: PresentationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, skeleton, hydration } = input\n const { listUris, cursor } = skeleton\n const lists = mapDefined(listUris, (uri) => {\n return ctx.views.list(uri, hydration)\n })\n return { lists, cursor }\n}\n\ntype Context = {\n hydrator: Hydrator\n views: Views\n}\n\ntype Params = app.bsky.graph.getLists.$Params & {\n hydrateCtx: HydrateCtx\n}\n\ntype SkeletonState = {\n listUris: AtUriString[]\n cursor?: string\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"getListsWithMembership.d.ts","sourceRoot":"","sources":["../../../../../src/api/app/bsky/graph/getListsWithMembership.ts"],"names":[],"mappings":"AAEA,OAAO,EAAuB,KAAK,MAAM,EAAE,MAAM,sBAAsB,CAAA;AACvE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAoBxD,MAAM,CAAC,OAAO,WAAW,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,QA4BvD"}
1
+ {"version":3,"file":"getListsWithMembership.d.ts","sourceRoot":"","sources":["../../../../../src/api/app/bsky/graph/getListsWithMembership.ts"],"names":[],"mappings":"AAEA,OAAO,EAAuB,KAAK,MAAM,EAAE,MAAM,sBAAsB,CAAA;AACvE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAoBxD,MAAM,CAAC,OAAO,WAAW,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,QA+BvD"}
@@ -3,7 +3,7 @@ import { InvalidRequestError } from '@atproto/xrpc-server';
3
3
  import { parseString } from '../../../../hydration/util.js';
4
4
  import { app } from '../../../../lexicons/index.js';
5
5
  import { createPipeline, } from '../../../../pipeline.js';
6
- import { clearlyBadCursor, resHeaders } from '../../../util.js';
6
+ import { clearlyBadCursor, fillPage, resHeaders } from '../../../util.js';
7
7
  const CURATELIST = app.bsky.graph.defs.curatelist.value;
8
8
  const MODLIST = app.bsky.graph.defs.modlist.value;
9
9
  export default function (server, ctx) {
@@ -17,7 +17,12 @@ export default function (server, ctx) {
17
17
  labelers,
18
18
  viewer,
19
19
  });
20
- const result = await getListsWithMembership({ ...params, hydrateCtx }, ctx);
20
+ const result = await fillPage({
21
+ cursor: params.cursor,
22
+ limit: params.limit,
23
+ fetch: ({ cursor, limit }) => getListsWithMembership({ ...params, cursor, limit, hydrateCtx }, ctx),
24
+ items: (r) => r.listsWithMembership,
25
+ });
21
26
  return {
22
27
  encoding: 'application/json',
23
28
  body: result,
@@ -62,8 +67,8 @@ const filterPurposes = (input) => {
62
67
  acceptedPurposes.add(CURATELIST);
63
68
  if (purposes.includes(CURATELIST))
64
69
  acceptedPurposes.add(CURATELIST);
65
- // @NOTE: While we don't support filtering on the dataplane, this might result in empty pages.
66
- // Despite the empty pages, the pagination still can enumerate all items for the specified filters.
70
+ // Purpose filtering happens after dataplane pagination. fillPage requests
71
+ // subsequent dataplane pages to replace lists filtered out here.
67
72
  skeleton.listUris = skeleton.listUris.filter((uri) => {
68
73
  const list = hydration.lists?.get(uri);
69
74
  return acceptedPurposes.has(list?.record.purpose);
@@ -1 +1 @@
1
- {"version":3,"file":"getListsWithMembership.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/graph/getListsWithMembership.ts"],"names":[],"mappings":"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","sourcesContent":["import { mapDefined } from '@atproto/common'\nimport type { AtUriString, DidString } from '@atproto/lex'\nimport { InvalidRequestError, type Server } from '@atproto/xrpc-server'\nimport type { AppContext } from '../../../../context.js'\nimport type {\n HydrateCtxWithViewer,\n Hydrator,\n} from '../../../../hydration/hydrator.js'\nimport { parseString } from '../../../../hydration/util.js'\nimport { app } from '../../../../lexicons/index.js'\nimport {\n type HydrationFnInput,\n type PresentationFnInput,\n type RulesFnInput,\n type SkeletonFnInput,\n createPipeline,\n} from '../../../../pipeline.js'\nimport type { Views } from '../../../../views/index.js'\nimport { clearlyBadCursor, resHeaders } from '../../../util.js'\n\nconst CURATELIST = app.bsky.graph.defs.curatelist.value\nconst MODLIST = app.bsky.graph.defs.modlist.value\n\nexport default function (server: Server, ctx: AppContext) {\n const getListsWithMembership = createPipeline(\n skeleton,\n hydration,\n filterPurposes,\n presentation,\n )\n server.add(app.bsky.graph.getListsWithMembership, {\n auth: ctx.authVerifier.standard,\n handler: async ({ params, auth, req }) => {\n const viewer = auth.credentials.iss\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({\n labelers,\n viewer,\n })\n const result = await getListsWithMembership(\n { ...params, hydrateCtx },\n ctx,\n )\n\n return {\n encoding: 'application/json',\n body: result,\n headers: resHeaders({ labelers: hydrateCtx.labelers }),\n }\n },\n })\n}\n\nconst skeleton = async (\n input: SkeletonFnInput<Context, Params>,\n): Promise<SkeletonState> => {\n const { ctx, params } = input\n const [actorDid] = await ctx.hydrator.actor.getDids([params.actor])\n if (!actorDid) throw new InvalidRequestError('Profile not found')\n\n if (clearlyBadCursor(params.cursor)) {\n return { actorDid, listUris: [] }\n }\n\n const { listUris, cursor } = await ctx.hydrator.dataplane.getActorLists({\n actorDid: params.hydrateCtx.viewer,\n cursor: params.cursor,\n limit: params.limit,\n })\n return {\n actorDid,\n listUris: listUris as AtUriString[],\n cursor: parseString(cursor),\n }\n}\n\nconst hydration = async (\n input: HydrationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, params, skeleton } = input\n const { actorDid, listUris } = skeleton\n return ctx.hydrator.hydrateListsMembership(\n listUris,\n actorDid,\n params.hydrateCtx,\n )\n}\n\nconst filterPurposes = (\n input: RulesFnInput<Context, Params, SkeletonState>,\n) => {\n const { skeleton, hydration, params } = input\n const purposes = params.purposes || ['modlist', 'curatelist']\n\n const acceptedPurposes = new Set()\n if (purposes.includes('modlist')) acceptedPurposes.add(MODLIST)\n if (purposes.includes(MODLIST)) acceptedPurposes.add(MODLIST)\n if (purposes.includes('curatelist')) acceptedPurposes.add(CURATELIST)\n if (purposes.includes(CURATELIST)) acceptedPurposes.add(CURATELIST)\n\n // @NOTE: While we don't support filtering on the dataplane, this might result in empty pages.\n // Despite the empty pages, the pagination still can enumerate all items for the specified filters.\n skeleton.listUris = skeleton.listUris.filter((uri) => {\n const list = hydration.lists?.get(uri)\n return acceptedPurposes.has(list?.record.purpose)\n })\n return skeleton\n}\n\nconst presentation = (\n input: PresentationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, skeleton, hydration } = input\n const { actorDid, listUris, cursor } = skeleton\n const listsWithMembership = mapDefined(listUris, (uri) => {\n const list = ctx.views.list(uri, hydration)\n if (!list) return\n\n const listItemUri = hydration.listMemberships\n ?.get(uri)\n ?.get(actorDid)?.actorListItemUri\n\n return {\n list,\n listItem: listItemUri\n ? ctx.views.listItemView(listItemUri, actorDid, hydration)\n : undefined,\n }\n })\n return { listsWithMembership, cursor }\n}\n\ntype Context = {\n hydrator: Hydrator\n views: Views\n}\n\ntype Params = app.bsky.graph.getListsWithMembership.$Params & {\n hydrateCtx: HydrateCtxWithViewer\n}\n\ntype SkeletonState = {\n actorDid: DidString\n listUris: AtUriString[]\n cursor?: string\n}\n"]}
1
+ {"version":3,"file":"getListsWithMembership.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/graph/getListsWithMembership.ts"],"names":[],"mappings":"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","sourcesContent":["import { mapDefined } from '@atproto/common'\nimport type { AtUriString, DidString } from '@atproto/lex'\nimport { InvalidRequestError, type Server } from '@atproto/xrpc-server'\nimport type { AppContext } from '../../../../context.js'\nimport type {\n HydrateCtxWithViewer,\n Hydrator,\n} from '../../../../hydration/hydrator.js'\nimport { parseString } from '../../../../hydration/util.js'\nimport { app } from '../../../../lexicons/index.js'\nimport {\n type HydrationFnInput,\n type PresentationFnInput,\n type RulesFnInput,\n type SkeletonFnInput,\n createPipeline,\n} from '../../../../pipeline.js'\nimport type { Views } from '../../../../views/index.js'\nimport { clearlyBadCursor, fillPage, resHeaders } from '../../../util.js'\n\nconst CURATELIST = app.bsky.graph.defs.curatelist.value\nconst MODLIST = app.bsky.graph.defs.modlist.value\n\nexport default function (server: Server, ctx: AppContext) {\n const getListsWithMembership = createPipeline(\n skeleton,\n hydration,\n filterPurposes,\n presentation,\n )\n server.add(app.bsky.graph.getListsWithMembership, {\n auth: ctx.authVerifier.standard,\n handler: async ({ params, auth, req }) => {\n const viewer = auth.credentials.iss\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({\n labelers,\n viewer,\n })\n const result = await fillPage({\n cursor: params.cursor,\n limit: params.limit,\n fetch: ({ cursor, limit }) =>\n getListsWithMembership({ ...params, cursor, limit, hydrateCtx }, ctx),\n items: (r) => r.listsWithMembership,\n })\n\n return {\n encoding: 'application/json',\n body: result,\n headers: resHeaders({ labelers: hydrateCtx.labelers }),\n }\n },\n })\n}\n\nconst skeleton = async (\n input: SkeletonFnInput<Context, Params>,\n): Promise<SkeletonState> => {\n const { ctx, params } = input\n const [actorDid] = await ctx.hydrator.actor.getDids([params.actor])\n if (!actorDid) throw new InvalidRequestError('Profile not found')\n\n if (clearlyBadCursor(params.cursor)) {\n return { actorDid, listUris: [] }\n }\n\n const { listUris, cursor } = await ctx.hydrator.dataplane.getActorLists({\n actorDid: params.hydrateCtx.viewer,\n cursor: params.cursor,\n limit: params.limit,\n })\n return {\n actorDid,\n listUris: listUris as AtUriString[],\n cursor: parseString(cursor),\n }\n}\n\nconst hydration = async (\n input: HydrationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, params, skeleton } = input\n const { actorDid, listUris } = skeleton\n return ctx.hydrator.hydrateListsMembership(\n listUris,\n actorDid,\n params.hydrateCtx,\n )\n}\n\nconst filterPurposes = (\n input: RulesFnInput<Context, Params, SkeletonState>,\n) => {\n const { skeleton, hydration, params } = input\n const purposes = params.purposes || ['modlist', 'curatelist']\n\n const acceptedPurposes = new Set()\n if (purposes.includes('modlist')) acceptedPurposes.add(MODLIST)\n if (purposes.includes(MODLIST)) acceptedPurposes.add(MODLIST)\n if (purposes.includes('curatelist')) acceptedPurposes.add(CURATELIST)\n if (purposes.includes(CURATELIST)) acceptedPurposes.add(CURATELIST)\n\n // Purpose filtering happens after dataplane pagination. fillPage requests\n // subsequent dataplane pages to replace lists filtered out here.\n skeleton.listUris = skeleton.listUris.filter((uri) => {\n const list = hydration.lists?.get(uri)\n return acceptedPurposes.has(list?.record.purpose)\n })\n return skeleton\n}\n\nconst presentation = (\n input: PresentationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, skeleton, hydration } = input\n const { actorDid, listUris, cursor } = skeleton\n const listsWithMembership = mapDefined(listUris, (uri) => {\n const list = ctx.views.list(uri, hydration)\n if (!list) return\n\n const listItemUri = hydration.listMemberships\n ?.get(uri)\n ?.get(actorDid)?.actorListItemUri\n\n return {\n list,\n listItem: listItemUri\n ? ctx.views.listItemView(listItemUri, actorDid, hydration)\n : undefined,\n }\n })\n return { listsWithMembership, cursor }\n}\n\ntype Context = {\n hydrator: Hydrator\n views: Views\n}\n\ntype Params = app.bsky.graph.getListsWithMembership.$Params & {\n hydrateCtx: HydrateCtxWithViewer\n}\n\ntype SkeletonState = {\n actorDid: DidString\n listUris: AtUriString[]\n cursor?: string\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"getMutes.d.ts","sourceRoot":"","sources":["../../../../../src/api/app/bsky/graph/getMutes.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAA;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAgBxD,MAAM,CAAC,OAAO,WAAW,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,QAgBvD"}
1
+ {"version":3,"file":"getMutes.d.ts","sourceRoot":"","sources":["../../../../../src/api/app/bsky/graph/getMutes.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAA;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAgBxD,MAAM,CAAC,OAAO,WAAW,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,QAsBvD"}
@@ -1,7 +1,7 @@
1
1
  import { mapDefined } from '@atproto/common';
2
2
  import { app } from '../../../../lexicons/index.js';
3
3
  import { createPipeline, noRules, } from '../../../../pipeline.js';
4
- import { clearlyBadCursor, resHeaders } from '../../../util.js';
4
+ import { clearlyBadCursor, fillPage, resHeaders } from '../../../util.js';
5
5
  export default function (server, ctx) {
6
6
  const getMutes = createPipeline(skeleton, hydration, noRules, presentation);
7
7
  server.add(app.bsky.graph.getMutes, {
@@ -10,7 +10,12 @@ export default function (server, ctx) {
10
10
  const viewer = auth.credentials.iss;
11
11
  const labelers = ctx.reqLabelers(req);
12
12
  const hydrateCtx = await ctx.hydrator.createContext({ labelers, viewer });
13
- const result = await getMutes({ ...params, hydrateCtx }, ctx);
13
+ const result = await fillPage({
14
+ cursor: params.cursor,
15
+ limit: params.limit,
16
+ fetch: ({ cursor, limit }) => getMutes({ ...params, cursor, limit, hydrateCtx }, ctx),
17
+ items: (r) => r.mutes,
18
+ });
14
19
  return {
15
20
  encoding: 'application/json',
16
21
  body: result,
@@ -19,40 +24,27 @@ export default function (server, ctx) {
19
24
  },
20
25
  });
21
26
  }
22
- // Bounds dataplane round trips per request when filling pages. A page can
23
- // only run short when it contains scoped mutes, so this is only reached by
24
- // viewers with many consecutive scoped mutes; the client just paginates
25
- // again from the returned cursor.
26
- const MAX_PAGE_FILL_FETCHES = 10;
27
27
  const skeleton = async (input) => {
28
28
  const { params, ctx } = input;
29
29
  if (clearlyBadCursor(params.cursor)) {
30
30
  return { mutedDids: [] };
31
31
  }
32
+ const res = await ctx.hydrator.dataplane.getMutes({
33
+ actorDid: params.hydrateCtx.viewer,
34
+ cursor: params.cursor,
35
+ limit: params.limit,
36
+ });
32
37
  // only fully muted accounts are enumerated: scoped mutes (only reposts /
33
- // only quoteposts) are filtered out. Since scoped entries still consume
34
- // cursor range, keep fetching until the page holds at least `limit` full
35
- // mutes. Whole dataplane pages are appended, so the response may exceed
36
- // `limit`; this keeps the returned cursor a plain dataplane cursor.
37
- const mutedDids = [];
38
- let cursor = params.cursor;
39
- for (let i = 0; i < MAX_PAGE_FILL_FETCHES; i++) {
40
- const res = await ctx.hydrator.dataplane.getMutes({
41
- actorDid: params.hydrateCtx.viewer,
42
- cursor,
43
- limit: params.limit,
44
- });
45
- const fullMuteDids = res.mutes.length
46
- ? res.mutes
47
- .filter((mute) => !mute.onlyReposts && !mute.onlyQuoteposts)
48
- .map((mute) => mute.did)
49
- : res.dids;
50
- mutedDids.push(...fullMuteDids);
51
- cursor = res.cursor || undefined;
52
- if (!cursor || mutedDids.length >= params.limit)
53
- break;
54
- }
55
- return { mutedDids, cursor };
38
+ // only quoteposts) are filtered out.
39
+ const mutedDids = res.mutes.length
40
+ ? res.mutes
41
+ .filter((mute) => !mute.onlyReposts && !mute.onlyQuoteposts)
42
+ .map((mute) => mute.did)
43
+ : res.dids;
44
+ return {
45
+ mutedDids: mutedDids,
46
+ cursor: res.cursor || undefined,
47
+ };
56
48
  };
57
49
  const hydration = async (input) => {
58
50
  const { ctx, params, skeleton } = input;
@@ -1 +1 @@
1
- {"version":3,"file":"getMutes.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/graph/getMutes.ts"],"names":[],"mappings":"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","sourcesContent":["import { mapDefined } from '@atproto/common'\nimport type { DidString } from '@atproto/lex'\nimport type { Server } from '@atproto/xrpc-server'\nimport type { AppContext } from '../../../../context.js'\nimport type {\n HydrateCtxWithViewer,\n Hydrator,\n} from '../../../../hydration/hydrator.js'\nimport { app } from '../../../../lexicons/index.js'\nimport {\n type HydrationFnInput,\n type PresentationFnInput,\n type SkeletonFnInput,\n createPipeline,\n noRules,\n} from '../../../../pipeline.js'\nimport type { Views } from '../../../../views/index.js'\nimport { clearlyBadCursor, resHeaders } from '../../../util.js'\n\nexport default function (server: Server, ctx: AppContext) {\n const getMutes = createPipeline(skeleton, hydration, noRules, presentation)\n server.add(app.bsky.graph.getMutes, {\n auth: ctx.authVerifier.standard,\n handler: async ({ params, auth, req }) => {\n const viewer = auth.credentials.iss\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({ labelers, viewer })\n const result = await getMutes({ ...params, hydrateCtx }, ctx)\n return {\n encoding: 'application/json',\n body: result,\n headers: resHeaders({ labelers: hydrateCtx.labelers }),\n }\n },\n })\n}\n\n// Bounds dataplane round trips per request when filling pages. A page can\n// only run short when it contains scoped mutes, so this is only reached by\n// viewers with many consecutive scoped mutes; the client just paginates\n// again from the returned cursor.\nconst MAX_PAGE_FILL_FETCHES = 10\n\nconst skeleton = async (\n input: SkeletonFnInput<Context, Params>,\n): Promise<SkeletonState> => {\n const { params, ctx } = input\n if (clearlyBadCursor(params.cursor)) {\n return { mutedDids: [] }\n }\n // only fully muted accounts are enumerated: scoped mutes (only reposts /\n // only quoteposts) are filtered out. Since scoped entries still consume\n // cursor range, keep fetching until the page holds at least `limit` full\n // mutes. Whole dataplane pages are appended, so the response may exceed\n // `limit`; this keeps the returned cursor a plain dataplane cursor.\n const mutedDids: DidString[] = []\n let cursor = params.cursor\n for (let i = 0; i < MAX_PAGE_FILL_FETCHES; i++) {\n const res = await ctx.hydrator.dataplane.getMutes({\n actorDid: params.hydrateCtx.viewer,\n cursor,\n limit: params.limit,\n })\n const fullMuteDids = res.mutes.length\n ? res.mutes\n .filter((mute) => !mute.onlyReposts && !mute.onlyQuoteposts)\n .map((mute) => mute.did)\n : res.dids\n mutedDids.push(...(fullMuteDids as DidString[]))\n cursor = res.cursor || undefined\n if (!cursor || mutedDids.length >= params.limit) break\n }\n return { mutedDids, cursor }\n}\n\nconst hydration = async (\n input: HydrationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, params, skeleton } = input\n const { mutedDids } = skeleton\n return ctx.hydrator.hydrateProfiles(mutedDids, params.hydrateCtx)\n}\n\nconst presentation = (\n input: PresentationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, hydration, skeleton } = input\n const { mutedDids, cursor } = skeleton\n const mutes = mapDefined(mutedDids, (did) => {\n return ctx.views.profile(did, hydration)\n })\n return { mutes, cursor }\n}\n\ntype Context = {\n hydrator: Hydrator\n views: Views\n}\n\ntype Params = app.bsky.graph.getMutes.$Params & {\n hydrateCtx: HydrateCtxWithViewer\n}\n\ntype SkeletonState = {\n mutedDids: DidString[]\n cursor?: string\n}\n"]}
1
+ {"version":3,"file":"getMutes.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/graph/getMutes.ts"],"names":[],"mappings":"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","sourcesContent":["import { mapDefined } from '@atproto/common'\nimport type { DidString } from '@atproto/lex'\nimport type { Server } from '@atproto/xrpc-server'\nimport type { AppContext } from '../../../../context.js'\nimport type {\n HydrateCtxWithViewer,\n Hydrator,\n} from '../../../../hydration/hydrator.js'\nimport { app } from '../../../../lexicons/index.js'\nimport {\n type HydrationFnInput,\n type PresentationFnInput,\n type SkeletonFnInput,\n createPipeline,\n noRules,\n} from '../../../../pipeline.js'\nimport type { Views } from '../../../../views/index.js'\nimport { clearlyBadCursor, fillPage, resHeaders } from '../../../util.js'\n\nexport default function (server: Server, ctx: AppContext) {\n const getMutes = createPipeline(skeleton, hydration, noRules, presentation)\n server.add(app.bsky.graph.getMutes, {\n auth: ctx.authVerifier.standard,\n handler: async ({ params, auth, req }) => {\n const viewer = auth.credentials.iss\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({ labelers, viewer })\n const result = await fillPage({\n cursor: params.cursor,\n limit: params.limit,\n fetch: ({ cursor, limit }) =>\n getMutes({ ...params, cursor, limit, hydrateCtx }, ctx),\n items: (r) => r.mutes,\n })\n return {\n encoding: 'application/json',\n body: result,\n headers: resHeaders({ labelers: hydrateCtx.labelers }),\n }\n },\n })\n}\n\nconst skeleton = async (\n input: SkeletonFnInput<Context, Params>,\n): Promise<SkeletonState> => {\n const { params, ctx } = input\n if (clearlyBadCursor(params.cursor)) {\n return { mutedDids: [] }\n }\n const res = await ctx.hydrator.dataplane.getMutes({\n actorDid: params.hydrateCtx.viewer,\n cursor: params.cursor,\n limit: params.limit,\n })\n\n // only fully muted accounts are enumerated: scoped mutes (only reposts /\n // only quoteposts) are filtered out.\n const mutedDids = res.mutes.length\n ? res.mutes\n .filter((mute) => !mute.onlyReposts && !mute.onlyQuoteposts)\n .map((mute) => mute.did)\n : res.dids\n return {\n mutedDids: mutedDids as DidString[],\n cursor: res.cursor || undefined,\n }\n}\n\nconst hydration = async (\n input: HydrationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, params, skeleton } = input\n const { mutedDids } = skeleton\n return ctx.hydrator.hydrateProfiles(mutedDids, params.hydrateCtx)\n}\n\nconst presentation = (\n input: PresentationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, hydration, skeleton } = input\n const { mutedDids, cursor } = skeleton\n const mutes = mapDefined(mutedDids, (did) => {\n return ctx.views.profile(did, hydration)\n })\n return { mutes, cursor }\n}\n\ntype Context = {\n hydrator: Hydrator\n views: Views\n}\n\ntype Params = app.bsky.graph.getMutes.$Params & {\n hydrateCtx: HydrateCtxWithViewer\n}\n\ntype SkeletonState = {\n mutedDids: DidString[]\n cursor?: string\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"getStarterPacksWithMembership.d.ts","sourceRoot":"","sources":["../../../../../src/api/app/bsky/graph/getStarterPacksWithMembership.ts"],"names":[],"mappings":"AAEA,OAAO,EAAuB,KAAK,MAAM,EAAE,MAAM,sBAAsB,CAAA;AACvE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAiBxD,MAAM,CAAC,OAAO,WAAW,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,QA4BvD"}
1
+ {"version":3,"file":"getStarterPacksWithMembership.d.ts","sourceRoot":"","sources":["../../../../../src/api/app/bsky/graph/getStarterPacksWithMembership.ts"],"names":[],"mappings":"AAEA,OAAO,EAAuB,KAAK,MAAM,EAAE,MAAM,sBAAsB,CAAA;AACvE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAiBxD,MAAM,CAAC,OAAO,WAAW,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,QAkCvD"}
@@ -3,7 +3,7 @@ import { InvalidRequestError } from '@atproto/xrpc-server';
3
3
  import { mergeManyStates, } from '../../../../hydration/hydrator.js';
4
4
  import { app } from '../../../../lexicons/index.js';
5
5
  import { createPipeline, noRules, } from '../../../../pipeline.js';
6
- import { clearlyBadCursor, resHeaders } from '../../../util.js';
6
+ import { clearlyBadCursor, fillPage, resHeaders } from '../../../util.js';
7
7
  export default function (server, ctx) {
8
8
  const getStarterPacksWithMembership = createPipeline(skeleton, hydration, noRules, presentation);
9
9
  server.add(app.bsky.graph.getStarterPacksWithMembership, {
@@ -15,7 +15,12 @@ export default function (server, ctx) {
15
15
  labelers,
16
16
  viewer,
17
17
  });
18
- const result = await getStarterPacksWithMembership({ ...params, hydrateCtx }, ctx);
18
+ const result = await fillPage({
19
+ cursor: params.cursor,
20
+ limit: params.limit,
21
+ fetch: ({ cursor, limit }) => getStarterPacksWithMembership({ ...params, cursor, limit, hydrateCtx }, ctx),
22
+ items: (r) => r.starterPacksWithMembership,
23
+ });
19
24
  return {
20
25
  encoding: 'application/json',
21
26
  body: result,
@@ -1 +1 @@
1
- {"version":3,"file":"getStarterPacksWithMembership.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/graph/getStarterPacksWithMembership.ts"],"names":[],"mappings":"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","sourcesContent":["import { mapDefined } from '@atproto/common'\nimport type { AtUriString, DidString } from '@atproto/syntax'\nimport { InvalidRequestError, type Server } from '@atproto/xrpc-server'\nimport type { AppContext } from '../../../../context.js'\nimport {\n type HydrateCtxWithViewer,\n type Hydrator,\n mergeManyStates,\n} from '../../../../hydration/hydrator.js'\nimport { app } from '../../../../lexicons/index.js'\nimport {\n type HydrationFnInput,\n type PresentationFnInput,\n type SkeletonFnInput,\n createPipeline,\n noRules,\n} from '../../../../pipeline.js'\nimport type { Views } from '../../../../views/index.js'\nimport { clearlyBadCursor, resHeaders } from '../../../util.js'\n\nexport default function (server: Server, ctx: AppContext) {\n const getStarterPacksWithMembership = createPipeline(\n skeleton,\n hydration,\n noRules,\n presentation,\n )\n server.add(app.bsky.graph.getStarterPacksWithMembership, {\n auth: ctx.authVerifier.standard,\n handler: async ({ params, auth, req }) => {\n const viewer = auth.credentials.iss\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({\n labelers,\n viewer,\n })\n const result = await getStarterPacksWithMembership(\n { ...params, hydrateCtx },\n ctx,\n )\n\n return {\n encoding: 'application/json',\n body: result,\n headers: resHeaders({ labelers: hydrateCtx.labelers }),\n }\n },\n })\n}\n\nconst skeleton = async (\n input: SkeletonFnInput<Context, Params>,\n): Promise<SkeletonState> => {\n const { ctx, params } = input\n const [actorDid] = await ctx.hydrator.actor.getDids([params.actor])\n if (!actorDid) throw new InvalidRequestError('Profile not found')\n\n if (clearlyBadCursor(params.cursor)) {\n return { actorDid, starterPackUris: [] }\n }\n\n const { uris: starterPackUris, cursor } =\n await ctx.hydrator.dataplane.getActorStarterPacks({\n actorDid: params.hydrateCtx.viewer,\n cursor: params.cursor,\n limit: params.limit,\n })\n\n return {\n actorDid,\n starterPackUris: starterPackUris as AtUriString[],\n cursor: cursor || undefined,\n }\n}\n\nconst hydration = async (\n input: HydrationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, params, skeleton } = input\n const { actorDid, starterPackUris } = skeleton\n const spHydrationState = await ctx.hydrator.hydrateStarterPacks(\n starterPackUris,\n params.hydrateCtx,\n )\n const listUris = mapDefined(\n starterPackUris,\n (uri) => spHydrationState.starterPacks?.get(uri)?.record.list,\n )\n const listMembershipHydrationState =\n await ctx.hydrator.hydrateListsMembership(\n listUris,\n actorDid,\n params.hydrateCtx,\n )\n return mergeManyStates(spHydrationState, listMembershipHydrationState)\n}\n\nconst presentation = (\n input: PresentationFnInput<Context, Params, SkeletonState>,\n): app.bsky.graph.getStarterPacksWithMembership.$OutputBody => {\n const { ctx, skeleton, hydration } = input\n const { actorDid, starterPackUris, cursor } = skeleton\n\n const starterPacksWithMembership = mapDefined(starterPackUris, (spUri) => {\n const listUri = hydration.starterPacks?.get(spUri)?.record.list\n const starterPack = ctx.views.starterPack(spUri, hydration)\n if (!listUri || !starterPack) return\n\n const listItemUri = hydration.listMemberships\n ?.get(listUri)\n ?.get(actorDid)?.actorListItemUri\n\n return {\n starterPack,\n listItem: listItemUri\n ? ctx.views.listItemView(listItemUri, actorDid, hydration)\n : undefined,\n }\n })\n return { starterPacksWithMembership, cursor }\n}\n\ntype Context = {\n hydrator: Hydrator\n views: Views\n}\n\ntype Params = app.bsky.graph.getStarterPacksWithMembership.$Params & {\n hydrateCtx: HydrateCtxWithViewer\n}\n\ntype SkeletonState = {\n actorDid: DidString\n starterPackUris: AtUriString[]\n cursor?: string\n}\n"]}
1
+ {"version":3,"file":"getStarterPacksWithMembership.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/graph/getStarterPacksWithMembership.ts"],"names":[],"mappings":"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","sourcesContent":["import { mapDefined } from '@atproto/common'\nimport type { AtUriString, DidString } from '@atproto/syntax'\nimport { InvalidRequestError, type Server } from '@atproto/xrpc-server'\nimport type { AppContext } from '../../../../context.js'\nimport {\n type HydrateCtxWithViewer,\n type Hydrator,\n mergeManyStates,\n} from '../../../../hydration/hydrator.js'\nimport { app } from '../../../../lexicons/index.js'\nimport {\n type HydrationFnInput,\n type PresentationFnInput,\n type SkeletonFnInput,\n createPipeline,\n noRules,\n} from '../../../../pipeline.js'\nimport type { Views } from '../../../../views/index.js'\nimport { clearlyBadCursor, fillPage, resHeaders } from '../../../util.js'\n\nexport default function (server: Server, ctx: AppContext) {\n const getStarterPacksWithMembership = createPipeline(\n skeleton,\n hydration,\n noRules,\n presentation,\n )\n server.add(app.bsky.graph.getStarterPacksWithMembership, {\n auth: ctx.authVerifier.standard,\n handler: async ({ params, auth, req }) => {\n const viewer = auth.credentials.iss\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({\n labelers,\n viewer,\n })\n const result = await fillPage({\n cursor: params.cursor,\n limit: params.limit,\n fetch: ({ cursor, limit }) =>\n getStarterPacksWithMembership(\n { ...params, cursor, limit, hydrateCtx },\n ctx,\n ),\n items: (r) => r.starterPacksWithMembership,\n })\n\n return {\n encoding: 'application/json',\n body: result,\n headers: resHeaders({ labelers: hydrateCtx.labelers }),\n }\n },\n })\n}\n\nconst skeleton = async (\n input: SkeletonFnInput<Context, Params>,\n): Promise<SkeletonState> => {\n const { ctx, params } = input\n const [actorDid] = await ctx.hydrator.actor.getDids([params.actor])\n if (!actorDid) throw new InvalidRequestError('Profile not found')\n\n if (clearlyBadCursor(params.cursor)) {\n return { actorDid, starterPackUris: [] }\n }\n\n const { uris: starterPackUris, cursor } =\n await ctx.hydrator.dataplane.getActorStarterPacks({\n actorDid: params.hydrateCtx.viewer,\n cursor: params.cursor,\n limit: params.limit,\n })\n\n return {\n actorDid,\n starterPackUris: starterPackUris as AtUriString[],\n cursor: cursor || undefined,\n }\n}\n\nconst hydration = async (\n input: HydrationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, params, skeleton } = input\n const { actorDid, starterPackUris } = skeleton\n const spHydrationState = await ctx.hydrator.hydrateStarterPacks(\n starterPackUris,\n params.hydrateCtx,\n )\n const listUris = mapDefined(\n starterPackUris,\n (uri) => spHydrationState.starterPacks?.get(uri)?.record.list,\n )\n const listMembershipHydrationState =\n await ctx.hydrator.hydrateListsMembership(\n listUris,\n actorDid,\n params.hydrateCtx,\n )\n return mergeManyStates(spHydrationState, listMembershipHydrationState)\n}\n\nconst presentation = (\n input: PresentationFnInput<Context, Params, SkeletonState>,\n): app.bsky.graph.getStarterPacksWithMembership.$OutputBody => {\n const { ctx, skeleton, hydration } = input\n const { actorDid, starterPackUris, cursor } = skeleton\n\n const starterPacksWithMembership = mapDefined(starterPackUris, (spUri) => {\n const listUri = hydration.starterPacks?.get(spUri)?.record.list\n const starterPack = ctx.views.starterPack(spUri, hydration)\n if (!listUri || !starterPack) return\n\n const listItemUri = hydration.listMemberships\n ?.get(listUri)\n ?.get(actorDid)?.actorListItemUri\n\n return {\n starterPack,\n listItem: listItemUri\n ? ctx.views.listItemView(listItemUri, actorDid, hydration)\n : undefined,\n }\n })\n return { starterPacksWithMembership, cursor }\n}\n\ntype Context = {\n hydrator: Hydrator\n views: Views\n}\n\ntype Params = app.bsky.graph.getStarterPacksWithMembership.$Params & {\n hydrateCtx: HydrateCtxWithViewer\n}\n\ntype SkeletonState = {\n actorDid: DidString\n starterPackUris: AtUriString[]\n cursor?: string\n}\n"]}