@atproto/bsky 0.0.273 → 0.0.274

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 (249) hide show
  1. package/CHANGELOG.md +25 -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/config.d.ts +2 -0
  110. package/dist/config.d.ts.map +1 -1
  111. package/dist/config.js +5 -0
  112. package/dist/config.js.map +1 -1
  113. package/dist/data-plane/server/db/pagination.d.ts +8 -0
  114. package/dist/data-plane/server/db/pagination.d.ts.map +1 -1
  115. package/dist/data-plane/server/db/pagination.js +20 -2
  116. package/dist/data-plane/server/db/pagination.js.map +1 -1
  117. package/dist/data-plane/server/op-thread.d.ts +7 -0
  118. package/dist/data-plane/server/op-thread.d.ts.map +1 -0
  119. package/dist/data-plane/server/op-thread.js +71 -0
  120. package/dist/data-plane/server/op-thread.js.map +1 -0
  121. package/dist/data-plane/server/routes/activity-subscription.js +3 -3
  122. package/dist/data-plane/server/routes/activity-subscription.js.map +1 -1
  123. package/dist/data-plane/server/routes/blocks.js +6 -6
  124. package/dist/data-plane/server/routes/blocks.js.map +1 -1
  125. package/dist/data-plane/server/routes/bookmarks.js +3 -3
  126. package/dist/data-plane/server/routes/bookmarks.js.map +1 -1
  127. package/dist/data-plane/server/routes/drafts.js +3 -3
  128. package/dist/data-plane/server/routes/drafts.js.map +1 -1
  129. package/dist/data-plane/server/routes/feed-gens.js +14 -12
  130. package/dist/data-plane/server/routes/feed-gens.js.map +1 -1
  131. package/dist/data-plane/server/routes/feeds.d.ts.map +1 -1
  132. package/dist/data-plane/server/routes/feeds.js +36 -15
  133. package/dist/data-plane/server/routes/feeds.js.map +1 -1
  134. package/dist/data-plane/server/routes/follows.js +6 -6
  135. package/dist/data-plane/server/routes/follows.js.map +1 -1
  136. package/dist/data-plane/server/routes/likes.js +6 -6
  137. package/dist/data-plane/server/routes/likes.js.map +1 -1
  138. package/dist/data-plane/server/routes/lists.js +6 -6
  139. package/dist/data-plane/server/routes/lists.js.map +1 -1
  140. package/dist/data-plane/server/routes/mutes.js +7 -7
  141. package/dist/data-plane/server/routes/mutes.js.map +1 -1
  142. package/dist/data-plane/server/routes/notifs.js +3 -3
  143. package/dist/data-plane/server/routes/notifs.js.map +1 -1
  144. package/dist/data-plane/server/routes/quotes.js +3 -3
  145. package/dist/data-plane/server/routes/quotes.js.map +1 -1
  146. package/dist/data-plane/server/routes/records.d.ts +3 -1
  147. package/dist/data-plane/server/routes/records.d.ts.map +1 -1
  148. package/dist/data-plane/server/routes/records.js +41 -4
  149. package/dist/data-plane/server/routes/records.js.map +1 -1
  150. package/dist/data-plane/server/routes/reposts.js +6 -6
  151. package/dist/data-plane/server/routes/reposts.js.map +1 -1
  152. package/dist/data-plane/server/routes/search.js +9 -9
  153. package/dist/data-plane/server/routes/search.js.map +1 -1
  154. package/dist/data-plane/server/routes/starter-packs.js +3 -3
  155. package/dist/data-plane/server/routes/starter-packs.js.map +1 -1
  156. package/dist/data-plane/server/routes/threads.d.ts.map +1 -1
  157. package/dist/data-plane/server/routes/threads.js +3 -74
  158. package/dist/data-plane/server/routes/threads.js.map +1 -1
  159. package/dist/feature-gates/gates.d.ts +2 -1
  160. package/dist/feature-gates/gates.d.ts.map +1 -1
  161. package/dist/feature-gates/gates.js +2 -1
  162. package/dist/feature-gates/gates.js.map +1 -1
  163. package/dist/hydration/feed.d.ts +3 -0
  164. package/dist/hydration/feed.d.ts.map +1 -1
  165. package/dist/hydration/feed.js +12 -0
  166. package/dist/hydration/feed.js.map +1 -1
  167. package/dist/hydration/hydrator.d.ts.map +1 -1
  168. package/dist/hydration/hydrator.js +4 -2
  169. package/dist/hydration/hydrator.js.map +1 -1
  170. package/dist/image/server.d.ts +1 -1
  171. package/dist/image/server.d.ts.map +1 -1
  172. package/dist/image/server.js +40 -22
  173. package/dist/image/server.js.map +1 -1
  174. package/dist/lexicons/app/bsky/actor/contentVisibilityDeclaration.d.ts +3 -0
  175. package/dist/lexicons/app/bsky/actor/contentVisibilityDeclaration.d.ts.map +1 -0
  176. package/dist/lexicons/app/bsky/actor/contentVisibilityDeclaration.defs.d.ts +66 -0
  177. package/dist/lexicons/app/bsky/actor/contentVisibilityDeclaration.defs.d.ts.map +1 -0
  178. package/dist/lexicons/app/bsky/actor/contentVisibilityDeclaration.defs.js +26 -0
  179. package/dist/lexicons/app/bsky/actor/contentVisibilityDeclaration.defs.js.map +1 -0
  180. package/dist/lexicons/app/bsky/actor/contentVisibilityDeclaration.js +6 -0
  181. package/dist/lexicons/app/bsky/actor/contentVisibilityDeclaration.js.map +1 -0
  182. package/dist/lexicons/app/bsky/actor.d.ts +1 -0
  183. package/dist/lexicons/app/bsky/actor.d.ts.map +1 -1
  184. package/dist/lexicons/app/bsky/actor.js +1 -0
  185. package/dist/lexicons/app/bsky/actor.js.map +1 -1
  186. package/dist/lexicons/app/bsky/authCreatePosts.defs.d.ts.map +1 -1
  187. package/dist/lexicons/app/bsky/authCreatePosts.defs.js +5 -0
  188. package/dist/lexicons/app/bsky/authCreatePosts.defs.js.map +1 -1
  189. package/dist/lexicons/app/bsky/authFullApp.defs.d.ts.map +1 -1
  190. package/dist/lexicons/app/bsky/authFullApp.defs.js +5 -0
  191. package/dist/lexicons/app/bsky/authFullApp.defs.js.map +1 -1
  192. package/dist/lexicons/app/bsky/video/abortUpload.d.ts +3 -0
  193. package/dist/lexicons/app/bsky/video/abortUpload.d.ts.map +1 -0
  194. package/dist/lexicons/app/bsky/video/abortUpload.defs.d.ts +53 -0
  195. package/dist/lexicons/app/bsky/video/abortUpload.defs.d.ts.map +1 -0
  196. package/dist/lexicons/app/bsky/video/abortUpload.defs.js +26 -0
  197. package/dist/lexicons/app/bsky/video/abortUpload.defs.js.map +1 -0
  198. package/dist/lexicons/app/bsky/video/abortUpload.js +6 -0
  199. package/dist/lexicons/app/bsky/video/abortUpload.js.map +1 -0
  200. package/dist/lexicons/app/bsky/video/defs.defs.d.ts +1 -1
  201. package/dist/lexicons/app/bsky/video/defs.defs.d.ts.map +1 -1
  202. package/dist/lexicons/app/bsky/video/defs.defs.js.map +1 -1
  203. package/dist/lexicons/app/bsky/video/finishUpload.d.ts +3 -0
  204. package/dist/lexicons/app/bsky/video/finishUpload.d.ts.map +1 -0
  205. package/dist/lexicons/app/bsky/video/finishUpload.defs.d.ts +42 -0
  206. package/dist/lexicons/app/bsky/video/finishUpload.defs.d.ts.map +1 -0
  207. package/dist/lexicons/app/bsky/video/finishUpload.defs.js +30 -0
  208. package/dist/lexicons/app/bsky/video/finishUpload.defs.js.map +1 -0
  209. package/dist/lexicons/app/bsky/video/finishUpload.js +6 -0
  210. package/dist/lexicons/app/bsky/video/finishUpload.js.map +1 -0
  211. package/dist/lexicons/app/bsky/video/getUploadStatus.d.ts +3 -0
  212. package/dist/lexicons/app/bsky/video/getUploadStatus.d.ts.map +1 -0
  213. package/dist/lexicons/app/bsky/video/getUploadStatus.defs.d.ts +73 -0
  214. package/dist/lexicons/app/bsky/video/getUploadStatus.defs.d.ts.map +1 -0
  215. package/dist/lexicons/app/bsky/video/getUploadStatus.defs.js +30 -0
  216. package/dist/lexicons/app/bsky/video/getUploadStatus.defs.js.map +1 -0
  217. package/dist/lexicons/app/bsky/video/getUploadStatus.js +6 -0
  218. package/dist/lexicons/app/bsky/video/getUploadStatus.js.map +1 -0
  219. package/dist/lexicons/app/bsky/video/startUpload.d.ts +3 -0
  220. package/dist/lexicons/app/bsky/video/startUpload.d.ts.map +1 -0
  221. package/dist/lexicons/app/bsky/video/startUpload.defs.d.ts +63 -0
  222. package/dist/lexicons/app/bsky/video/startUpload.defs.d.ts.map +1 -0
  223. package/dist/lexicons/app/bsky/video/startUpload.defs.js +36 -0
  224. package/dist/lexicons/app/bsky/video/startUpload.defs.js.map +1 -0
  225. package/dist/lexicons/app/bsky/video/startUpload.js +6 -0
  226. package/dist/lexicons/app/bsky/video/startUpload.js.map +1 -0
  227. package/dist/lexicons/app/bsky/video/uploadPart.d.ts +3 -0
  228. package/dist/lexicons/app/bsky/video/uploadPart.d.ts.map +1 -0
  229. package/dist/lexicons/app/bsky/video/uploadPart.defs.d.ts +37 -0
  230. package/dist/lexicons/app/bsky/video/uploadPart.defs.d.ts.map +1 -0
  231. package/dist/lexicons/app/bsky/video/uploadPart.defs.js +31 -0
  232. package/dist/lexicons/app/bsky/video/uploadPart.defs.js.map +1 -0
  233. package/dist/lexicons/app/bsky/video/uploadPart.js +6 -0
  234. package/dist/lexicons/app/bsky/video/uploadPart.js.map +1 -0
  235. package/dist/lexicons/app/bsky/video.d.ts +5 -0
  236. package/dist/lexicons/app/bsky/video.d.ts.map +1 -1
  237. package/dist/lexicons/app/bsky/video.js +5 -0
  238. package/dist/lexicons/app/bsky/video.js.map +1 -1
  239. package/dist/proto/bsky_pb.d.ts +39 -0
  240. package/dist/proto/bsky_pb.d.ts.map +1 -1
  241. package/dist/proto/bsky_pb.js +55 -0
  242. package/dist/proto/bsky_pb.js.map +1 -1
  243. package/dist/views/index.d.ts.map +1 -1
  244. package/dist/views/index.js +2 -0
  245. package/dist/views/index.js.map +1 -1
  246. package/dist/views/types.d.ts +4 -1
  247. package/dist/views/types.d.ts.map +1 -1
  248. package/dist/views/types.js.map +1 -1
  249. package/package.json +10 -10
@@ -1 +1 @@
1
- {"version":3,"file":"follows.js","sourceRoot":"","sources":["../../../../src/data-plane/server/routes/follows.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ServiceImpl } from '@connectrpc/connect'\nimport { keyBy } from '@atproto/common'\nimport type { Service } from '../../../proto/bsky_connect.js'\nimport { FollowsFollowing } from '../../../proto/bsky_pb.js'\nimport type { Database } from '../db/index.js'\nimport { TimeCidKeyset, paginate } from '../db/pagination.js'\n\nexport default (db: Database): Partial<ServiceImpl<typeof Service>> => ({\n async getActorFollowsActors(req) {\n const { actorDid, targetDids } = req\n if (targetDids.length < 1) {\n return { uris: [] }\n }\n const res = await db.db\n .selectFrom('follow')\n .where('follow.creator', '=', actorDid)\n .where('follow.subjectDid', 'in', targetDids)\n .selectAll()\n .execute()\n const bySubject = keyBy(res, 'subjectDid')\n const uris = targetDids.map((did) => bySubject.get(did)?.uri ?? '')\n return {\n uris,\n }\n },\n async getFollowers(req) {\n const { actorDid, limit, cursor } = req\n const { ref } = db.db.dynamic\n let followersReq = db.db\n .selectFrom('follow')\n .where('follow.subjectDid', '=', actorDid)\n .innerJoin('actor as creator', 'creator.did', 'follow.creator')\n .selectAll('creator')\n .select([\n 'follow.uri as uri',\n 'follow.cid as cid',\n 'follow.creator as creatorDid',\n 'follow.subjectDid as subjectDid',\n 'follow.sortAt as sortAt',\n ])\n\n const keyset = new TimeCidKeyset(ref('follow.sortAt'), ref('follow.cid'))\n followersReq = paginate(followersReq, {\n limit,\n cursor,\n keyset,\n tryIndex: true,\n })\n\n const followers = await followersReq.execute()\n return {\n followers: followers.map((f) => ({\n uri: f.uri,\n actorDid: f.creatorDid,\n subjectDid: f.subjectDid,\n })),\n cursor: keyset.packFromResult(followers),\n }\n },\n async getFollows(req) {\n const { actorDid, limit, cursor } = req\n const { ref } = db.db.dynamic\n\n let followsReq = db.db\n .selectFrom('follow')\n .where('follow.creator', '=', actorDid)\n .innerJoin('actor as subject', 'subject.did', 'follow.subjectDid')\n .selectAll('subject')\n .select([\n 'follow.uri as uri',\n 'follow.cid as cid',\n 'follow.creator as creatorDid',\n 'follow.subjectDid as subjectDid',\n 'follow.sortAt as sortAt',\n ])\n\n const keyset = new TimeCidKeyset(ref('follow.sortAt'), ref('follow.cid'))\n followsReq = paginate(followsReq, {\n limit,\n cursor,\n keyset,\n tryIndex: true,\n })\n\n const follows = await followsReq.execute()\n\n return {\n follows: follows.map((f) => ({\n uri: f.uri,\n actorDid: f.creatorDid,\n subjectDid: f.subjectDid,\n })),\n cursor: keyset.packFromResult(follows),\n }\n },\n\n /**\n * Return known followers of a given actor.\n *\n * Example:\n * - Alice follows Bob\n * - Bob follows Dan\n *\n * If Alice (the viewer) looks at Dan's profile (the subject), she should see that Bob follows Dan\n */\n async getFollowsFollowing(req) {\n const { actorDid: viewerDid, targetDids: subjectDids } = req\n\n /*\n * 1. Get all the people the Alice is following\n * 2. Get all the people the Dan is followed by\n * 3. Find the intersection\n */\n\n const results: FollowsFollowing[] = []\n\n for (const subjectDid of subjectDids) {\n const followsReq = db.db\n .selectFrom('follow')\n .where('follow.creator', '=', viewerDid)\n .where(\n 'follow.subjectDid',\n 'in',\n db.db\n .selectFrom('follow')\n .where('follow.subjectDid', '=', subjectDid)\n .select(['creator']),\n )\n .select(['subjectDid'])\n const rows = await followsReq.execute()\n results.push(\n new FollowsFollowing({\n targetDid: subjectDid,\n dids: rows.map((r) => r.subjectDid),\n }),\n )\n }\n\n return { results }\n },\n})\n"]}
1
+ {"version":3,"file":"follows.js","sourceRoot":"","sources":["../../../../src/data-plane/server/routes/follows.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ServiceImpl } from '@connectrpc/connect'\nimport { keyBy } from '@atproto/common'\nimport type { Service } from '../../../proto/bsky_connect.js'\nimport { FollowsFollowing } from '../../../proto/bsky_pb.js'\nimport type { Database } from '../db/index.js'\nimport { TimeCidKeyset, paginate } from '../db/pagination.js'\n\nexport default (db: Database): Partial<ServiceImpl<typeof Service>> => ({\n async getActorFollowsActors(req) {\n const { actorDid, targetDids } = req\n if (targetDids.length < 1) {\n return { uris: [] }\n }\n const res = await db.db\n .selectFrom('follow')\n .where('follow.creator', '=', actorDid)\n .where('follow.subjectDid', 'in', targetDids)\n .selectAll()\n .execute()\n const bySubject = keyBy(res, 'subjectDid')\n const uris = targetDids.map((did) => bySubject.get(did)?.uri ?? '')\n return {\n uris,\n }\n },\n async getFollowers(req) {\n const { actorDid, limit, cursor } = req\n const { ref } = db.db.dynamic\n let followersReq = db.db\n .selectFrom('follow')\n .where('follow.subjectDid', '=', actorDid)\n .innerJoin('actor as creator', 'creator.did', 'follow.creator')\n .selectAll('creator')\n .select([\n 'follow.uri as uri',\n 'follow.cid as cid',\n 'follow.creator as creatorDid',\n 'follow.subjectDid as subjectDid',\n 'follow.sortAt as sortAt',\n ])\n\n const keyset = new TimeCidKeyset(ref('follow.sortAt'), ref('follow.cid'))\n followersReq = paginate(followersReq, {\n limit,\n cursor,\n keyset,\n tryIndex: true,\n })\n\n const page = keyset.page(await followersReq.execute(), limit)\n return {\n followers: page.items.map((f) => ({\n uri: f.uri,\n actorDid: f.creatorDid,\n subjectDid: f.subjectDid,\n })),\n cursor: page.cursor,\n }\n },\n async getFollows(req) {\n const { actorDid, limit, cursor } = req\n const { ref } = db.db.dynamic\n\n let followsReq = db.db\n .selectFrom('follow')\n .where('follow.creator', '=', actorDid)\n .innerJoin('actor as subject', 'subject.did', 'follow.subjectDid')\n .selectAll('subject')\n .select([\n 'follow.uri as uri',\n 'follow.cid as cid',\n 'follow.creator as creatorDid',\n 'follow.subjectDid as subjectDid',\n 'follow.sortAt as sortAt',\n ])\n\n const keyset = new TimeCidKeyset(ref('follow.sortAt'), ref('follow.cid'))\n followsReq = paginate(followsReq, {\n limit,\n cursor,\n keyset,\n tryIndex: true,\n })\n\n const page = keyset.page(await followsReq.execute(), limit)\n\n return {\n follows: page.items.map((f) => ({\n uri: f.uri,\n actorDid: f.creatorDid,\n subjectDid: f.subjectDid,\n })),\n cursor: page.cursor,\n }\n },\n\n /**\n * Return known followers of a given actor.\n *\n * Example:\n * - Alice follows Bob\n * - Bob follows Dan\n *\n * If Alice (the viewer) looks at Dan's profile (the subject), she should see that Bob follows Dan\n */\n async getFollowsFollowing(req) {\n const { actorDid: viewerDid, targetDids: subjectDids } = req\n\n /*\n * 1. Get all the people the Alice is following\n * 2. Get all the people the Dan is followed by\n * 3. Find the intersection\n */\n\n const results: FollowsFollowing[] = []\n\n for (const subjectDid of subjectDids) {\n const followsReq = db.db\n .selectFrom('follow')\n .where('follow.creator', '=', viewerDid)\n .where(\n 'follow.subjectDid',\n 'in',\n db.db\n .selectFrom('follow')\n .where('follow.subjectDid', '=', subjectDid)\n .select(['creator']),\n )\n .select(['subjectDid'])\n const rows = await followsReq.execute()\n results.push(\n new FollowsFollowing({\n targetDid: subjectDid,\n dids: rows.map((r) => r.subjectDid),\n }),\n )\n }\n\n return { results }\n },\n})\n"]}
@@ -19,10 +19,10 @@ export default (db) => ({
19
19
  cursor,
20
20
  keyset,
21
21
  });
22
- const likes = await builder.execute();
22
+ const page = keyset.page(await builder.execute(), limit);
23
23
  return {
24
- uris: likes.map((l) => l.uri),
25
- cursor: keyset.packFromResult(likes),
24
+ uris: page.items.map((l) => l.uri),
25
+ cursor: page.cursor,
26
26
  };
27
27
  },
28
28
  // @NOTE deprecated in favor of getLikesBySubjectSorted
@@ -59,13 +59,13 @@ export default (db) => ({
59
59
  cursor,
60
60
  keyset,
61
61
  });
62
- const likes = await builder.execute();
62
+ const page = keyset.page(await builder.execute(), limit);
63
63
  return {
64
- likes: likes.map((l) => ({
64
+ likes: page.items.map((l) => ({
65
65
  uri: l.uri,
66
66
  subject: l.subject,
67
67
  })),
68
- cursor: keyset.packFromResult(likes),
68
+ cursor: page.cursor,
69
69
  };
70
70
  },
71
71
  });
@@ -1 +1 @@
1
- {"version":3,"file":"likes.js","sourceRoot":"","sources":["../../../../src/data-plane/server/routes/likes.ts"],"names":[],"mappings":"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","sourcesContent":["import assert from 'node:assert'\nimport type { ServiceImpl } from '@connectrpc/connect'\nimport { keyBy } from '@atproto/common'\nimport type { Service } from '../../../proto/bsky_connect.js'\nimport type { Database } from '../db/index.js'\nimport { TimeCidKeyset, paginate } from '../db/pagination.js'\n\nexport default (db: Database): Partial<ServiceImpl<typeof Service>> => ({\n async getLikesBySubjectSorted(req) {\n const { subject, cursor, limit } = req\n const { ref } = db.db.dynamic\n\n if (!subject?.uri) {\n return { uris: [] }\n }\n\n // @NOTE ignoring subject.cid\n let builder = db.db\n .selectFrom('like')\n .where('like.subject', '=', subject?.uri)\n .selectAll('like')\n\n const keyset = new TimeCidKeyset(ref('like.sortAt'), ref('like.cid'))\n builder = paginate(builder, {\n limit,\n cursor,\n keyset,\n })\n\n const likes = await builder.execute()\n\n return {\n uris: likes.map((l) => l.uri),\n cursor: keyset.packFromResult(likes),\n }\n },\n\n // @NOTE deprecated in favor of getLikesBySubjectSorted\n async getLikesBySubject(req, context) {\n assert(this.getLikesBySubjectSorted)\n return this.getLikesBySubjectSorted(req, context)\n },\n\n async getLikesByActorAndSubjects(req) {\n const { actorDid, refs } = req\n if (refs.length === 0) {\n return { uris: [] }\n }\n // @NOTE ignoring ref.cid\n const res = await db.db\n .selectFrom('like')\n .where('creator', '=', actorDid)\n .where(\n 'subject',\n 'in',\n refs.map(({ uri }) => uri),\n )\n .selectAll()\n .execute()\n const bySubject = keyBy(res, 'subject')\n const uris = refs.map(({ uri }) => bySubject.get(uri)?.uri ?? '')\n return { uris }\n },\n\n async getActorLikes(req) {\n const { actorDid, limit, cursor } = req\n const { ref } = db.db.dynamic\n\n let builder = db.db\n .selectFrom('like')\n .where('like.creator', '=', actorDid)\n .selectAll()\n\n const keyset = new TimeCidKeyset(ref('like.sortAt'), ref('like.cid'))\n\n builder = paginate(builder, {\n limit,\n cursor,\n keyset,\n })\n\n const likes = await builder.execute()\n\n return {\n likes: likes.map((l) => ({\n uri: l.uri,\n subject: l.subject,\n })),\n cursor: keyset.packFromResult(likes),\n }\n },\n})\n"]}
1
+ {"version":3,"file":"likes.js","sourceRoot":"","sources":["../../../../src/data-plane/server/routes/likes.ts"],"names":[],"mappings":"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","sourcesContent":["import assert from 'node:assert'\nimport type { ServiceImpl } from '@connectrpc/connect'\nimport { keyBy } from '@atproto/common'\nimport type { Service } from '../../../proto/bsky_connect.js'\nimport type { Database } from '../db/index.js'\nimport { TimeCidKeyset, paginate } from '../db/pagination.js'\n\nexport default (db: Database): Partial<ServiceImpl<typeof Service>> => ({\n async getLikesBySubjectSorted(req) {\n const { subject, cursor, limit } = req\n const { ref } = db.db.dynamic\n\n if (!subject?.uri) {\n return { uris: [] }\n }\n\n // @NOTE ignoring subject.cid\n let builder = db.db\n .selectFrom('like')\n .where('like.subject', '=', subject?.uri)\n .selectAll('like')\n\n const keyset = new TimeCidKeyset(ref('like.sortAt'), ref('like.cid'))\n builder = paginate(builder, {\n limit,\n cursor,\n keyset,\n })\n\n const page = keyset.page(await builder.execute(), limit)\n\n return {\n uris: page.items.map((l) => l.uri),\n cursor: page.cursor,\n }\n },\n\n // @NOTE deprecated in favor of getLikesBySubjectSorted\n async getLikesBySubject(req, context) {\n assert(this.getLikesBySubjectSorted)\n return this.getLikesBySubjectSorted(req, context)\n },\n\n async getLikesByActorAndSubjects(req) {\n const { actorDid, refs } = req\n if (refs.length === 0) {\n return { uris: [] }\n }\n // @NOTE ignoring ref.cid\n const res = await db.db\n .selectFrom('like')\n .where('creator', '=', actorDid)\n .where(\n 'subject',\n 'in',\n refs.map(({ uri }) => uri),\n )\n .selectAll()\n .execute()\n const bySubject = keyBy(res, 'subject')\n const uris = refs.map(({ uri }) => bySubject.get(uri)?.uri ?? '')\n return { uris }\n },\n\n async getActorLikes(req) {\n const { actorDid, limit, cursor } = req\n const { ref } = db.db.dynamic\n\n let builder = db.db\n .selectFrom('like')\n .where('like.creator', '=', actorDid)\n .selectAll()\n\n const keyset = new TimeCidKeyset(ref('like.sortAt'), ref('like.cid'))\n\n builder = paginate(builder, {\n limit,\n cursor,\n keyset,\n })\n\n const page = keyset.page(await builder.execute(), limit)\n\n return {\n likes: page.items.map((l) => ({\n uri: l.uri,\n subject: l.subject,\n })),\n cursor: page.cursor,\n }\n },\n})\n"]}
@@ -16,10 +16,10 @@ export default (db) => ({
16
16
  keyset,
17
17
  tryIndex: true,
18
18
  });
19
- const lists = await builder.execute();
19
+ const page = keyset.page(await builder.execute(), limit);
20
20
  return {
21
- listUris: lists.map((item) => item.uri),
22
- cursor: keyset.packFromResult(lists),
21
+ listUris: page.items.map((item) => item.uri),
22
+ cursor: page.cursor,
23
23
  };
24
24
  },
25
25
  async getListMembers(req) {
@@ -36,13 +36,13 @@ export default (db) => ({
36
36
  keyset,
37
37
  tryIndex: true,
38
38
  });
39
- const listItems = await builder.execute();
39
+ const page = keyset.page(await builder.execute(), limit);
40
40
  return {
41
- listitems: listItems.map((item) => ({
41
+ listitems: page.items.map((item) => ({
42
42
  uri: item.uri,
43
43
  did: item.subjectDid,
44
44
  })),
45
- cursor: keyset.packFromResult(listItems),
45
+ cursor: page.cursor,
46
46
  };
47
47
  },
48
48
  async getListMembership(req) {
@@ -1 +1 @@
1
- {"version":3,"file":"lists.js","sourceRoot":"","sources":["../../../../src/data-plane/server/routes/lists.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ServiceImpl } from '@connectrpc/connect'\nimport { keyBy } from '@atproto/common'\nimport type { Service } from '../../../proto/bsky_connect.js'\nimport type { Database } from '../db/index.js'\nimport { TimeCidKeyset, paginate } from '../db/pagination.js'\nimport { countAll } from '../db/util.js'\n\nexport default (db: Database): Partial<ServiceImpl<typeof Service>> => ({\n async getActorLists(req) {\n const { actorDid, cursor, limit } = req\n const { ref } = db.db.dynamic\n let builder = db.db\n .selectFrom('list')\n .where('creator', '=', actorDid)\n .selectAll()\n const keyset = new TimeCidKeyset(ref('list.sortAt'), ref('list.cid'))\n builder = paginate(builder, {\n limit,\n cursor,\n keyset,\n tryIndex: true,\n })\n const lists = await builder.execute()\n return {\n listUris: lists.map((item) => item.uri),\n cursor: keyset.packFromResult(lists),\n }\n },\n\n async getListMembers(req) {\n const { listUri, cursor, limit } = req\n const { ref } = db.db.dynamic\n let builder = db.db\n .selectFrom('list_item')\n .where('listUri', '=', listUri)\n .selectAll()\n\n const keyset = new TimeCidKeyset(\n ref('list_item.sortAt'),\n ref('list_item.cid'),\n )\n\n builder = paginate(builder, {\n limit,\n cursor,\n keyset,\n tryIndex: true,\n })\n\n const listItems = await builder.execute()\n return {\n listitems: listItems.map((item) => ({\n uri: item.uri,\n did: item.subjectDid,\n })),\n cursor: keyset.packFromResult(listItems),\n }\n },\n\n async getListMembership(req) {\n const { actorDid, listUris } = req\n if (listUris.length === 0) {\n return { listitemUris: [] }\n }\n const res = await db.db\n .selectFrom('list_item')\n .where('subjectDid', '=', actorDid)\n .where('listUri', 'in', listUris)\n .selectAll()\n .execute()\n const byListUri = keyBy(res, 'listUri')\n const listitemUris = listUris.map((uri) => byListUri.get(uri)?.uri ?? '')\n return {\n listitemUris,\n }\n },\n\n async getListCount(req) {\n const res = await db.db\n .selectFrom('list_item')\n .select(countAll.as('count'))\n .where('list_item.listUri', '=', req.listUri)\n .executeTakeFirst()\n return {\n count: res?.count,\n }\n },\n})\n"]}
1
+ {"version":3,"file":"lists.js","sourceRoot":"","sources":["../../../../src/data-plane/server/routes/lists.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ServiceImpl } from '@connectrpc/connect'\nimport { keyBy } from '@atproto/common'\nimport type { Service } from '../../../proto/bsky_connect.js'\nimport type { Database } from '../db/index.js'\nimport { TimeCidKeyset, paginate } from '../db/pagination.js'\nimport { countAll } from '../db/util.js'\n\nexport default (db: Database): Partial<ServiceImpl<typeof Service>> => ({\n async getActorLists(req) {\n const { actorDid, cursor, limit } = req\n const { ref } = db.db.dynamic\n let builder = db.db\n .selectFrom('list')\n .where('creator', '=', actorDid)\n .selectAll()\n const keyset = new TimeCidKeyset(ref('list.sortAt'), ref('list.cid'))\n builder = paginate(builder, {\n limit,\n cursor,\n keyset,\n tryIndex: true,\n })\n const page = keyset.page(await builder.execute(), limit)\n return {\n listUris: page.items.map((item) => item.uri),\n cursor: page.cursor,\n }\n },\n\n async getListMembers(req) {\n const { listUri, cursor, limit } = req\n const { ref } = db.db.dynamic\n let builder = db.db\n .selectFrom('list_item')\n .where('listUri', '=', listUri)\n .selectAll()\n\n const keyset = new TimeCidKeyset(\n ref('list_item.sortAt'),\n ref('list_item.cid'),\n )\n\n builder = paginate(builder, {\n limit,\n cursor,\n keyset,\n tryIndex: true,\n })\n\n const page = keyset.page(await builder.execute(), limit)\n return {\n listitems: page.items.map((item) => ({\n uri: item.uri,\n did: item.subjectDid,\n })),\n cursor: page.cursor,\n }\n },\n\n async getListMembership(req) {\n const { actorDid, listUris } = req\n if (listUris.length === 0) {\n return { listitemUris: [] }\n }\n const res = await db.db\n .selectFrom('list_item')\n .where('subjectDid', '=', actorDid)\n .where('listUri', 'in', listUris)\n .selectAll()\n .execute()\n const byListUri = keyBy(res, 'listUri')\n const listitemUris = listUris.map((uri) => byListUri.get(uri)?.uri ?? '')\n return {\n listitemUris,\n }\n },\n\n async getListCount(req) {\n const res = await db.db\n .selectFrom('list_item')\n .select(countAll.as('count'))\n .where('list_item.listUri', '=', req.listUri)\n .executeTakeFirst()\n return {\n count: res?.count,\n }\n },\n})\n"]}
@@ -35,15 +35,15 @@ export default (db) => ({
35
35
  cursor,
36
36
  keyset,
37
37
  });
38
- const mutes = await builder.execute();
38
+ const page = keyset.page(await builder.execute(), limit);
39
39
  return {
40
- dids: mutes.map((m) => m.did),
41
- mutes: mutes.map((m) => ({
40
+ dids: page.items.map((m) => m.did),
41
+ mutes: page.items.map((m) => ({
42
42
  did: m.did,
43
43
  onlyReposts: m.onlyReposts,
44
44
  onlyQuoteposts: m.onlyQuoteposts,
45
45
  })),
46
- cursor: keyset.packFromResult(mutes),
46
+ cursor: page.cursor,
47
47
  };
48
48
  },
49
49
  async getActorMutesActorViaList(req) {
@@ -90,10 +90,10 @@ export default (db) => ({
90
90
  cursor,
91
91
  keyset,
92
92
  });
93
- const lists = await builder.execute();
93
+ const page = keyset.page(await builder.execute(), limit);
94
94
  return {
95
- listUris: lists.map((l) => l.uri),
96
- cursor: keyset.packFromResult(lists),
95
+ listUris: page.items.map((l) => l.uri),
96
+ cursor: page.cursor,
97
97
  };
98
98
  },
99
99
  async createActorMute(req) {
@@ -1 +1 @@
1
- {"version":3,"file":"mutes.js","sourceRoot":"","sources":["../../../../src/data-plane/server/routes/mutes.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAA;AAEhC,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAA;AACvC,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAA;AACvC,OAAO,EAAE,GAAG,EAAE,MAAM,4BAA4B,CAAA;AAGhD,OAAO,EACL,kBAAkB,EAClB,aAAa,EACb,QAAQ,GACT,MAAM,qBAAqB,CAAA;AAE5B,eAAe,CAAC,EAAY,EAAwC,EAAE,CAAC,CAAC;IACtE,KAAK,CAAC,kBAAkB,CAAC,GAAG;QAC1B,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,GAAG,CAAA;QACnC,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,EAAE;aACpB,UAAU,CAAC,MAAM,CAAC;aAClB,SAAS,EAAE;aACX,KAAK,CAAC,YAAY,EAAE,GAAG,EAAE,QAAQ,CAAC;aAClC,KAAK,CAAC,YAAY,EAAE,GAAG,EAAE,SAAS,CAAC;aACnC,gBAAgB,EAAE,CAAA;QACrB,OAAO;YACL,KAAK,EAAE,GAAG,IAAI,IAAI,IAAI,CAAC,GAAG,CAAC,WAAW,IAAI,CAAC,GAAG,CAAC,cAAc;YAC7D,gBAAgB,EAAE,GAAG,EAAE,WAAW,IAAI,KAAK;YAC3C,mBAAmB,EAAE,GAAG,EAAE,cAAc,IAAI,KAAK;SAClD,CAAA;IACH,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,GAAG;QAChB,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,GAAG,CAAA;QACvC,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,OAAO,CAAA;QAE7B,IAAI,OAAO,GAAG,EAAE,CAAC,EAAE;aAChB,UAAU,CAAC,MAAM,CAAC;aAClB,SAAS,CAAC,OAAO,EAAE,WAAW,EAAE,iBAAiB,CAAC;aAClD,KAAK,CAAC,iBAAiB,EAAE,GAAG,EAAE,QAAQ,CAAC;aACvC,SAAS,CAAC,OAAO,CAAC;aAClB,MAAM,CAAC,6BAA6B,CAAC;aACrC,MAAM,CAAC,iCAAiC,CAAC;aACzC,MAAM,CAAC,uCAAuC,CAAC,CAAA;QAElD,MAAM,MAAM,GAAG,IAAI,kBAAkB,CACnC,GAAG,CAAC,gBAAgB,CAAC,EACrB,GAAG,CAAC,iBAAiB,CAAC,CACvB,CAAA;QACD,OAAO,GAAG,QAAQ,CAAC,OAAO,EAAE;YAC1B,KAAK;YACL,MAAM;YACN,MAAM;SACP,CAAC,CAAA;QAEF,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,CAAA;QAErC,OAAO;YACL,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;YAC7B,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBACvB,GAAG,EAAE,CAAC,CAAC,GAAG;gBACV,WAAW,EAAE,CAAC,CAAC,WAAW;gBAC1B,cAAc,EAAE,CAAC,CAAC,cAAc;aACjC,CAAC,CAAC;YACH,MAAM,EAAE,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC;SACrC,CAAA;IACH,CAAC;IAED,KAAK,CAAC,yBAAyB,CAAC,GAAG;QACjC,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,GAAG,CAAA;QACnC,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,EAAE;aACpB,UAAU,CAAC,WAAW,CAAC;aACvB,SAAS,CAAC,WAAW,EAAE,mBAAmB,EAAE,mBAAmB,CAAC;aAChE,KAAK,CAAC,sBAAsB,EAAE,GAAG,EAAE,QAAQ,CAAC;aAC5C,KAAK,CAAC,sBAAsB,EAAE,GAAG,EAAE,SAAS,CAAC;aAC7C,MAAM,CAAC,mBAAmB,CAAC;aAC3B,KAAK,CAAC,CAAC,CAAC;aACR,gBAAgB,EAAE,CAAA;QACrB,OAAO;YACL,OAAO,EAAE,GAAG,EAAE,OAAO;SACtB,CAAA;IACH,CAAC;IAED,KAAK,CAAC,uBAAuB,CAAC,GAAG;QAC/B,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,GAAG,CAAA;QACjC,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,EAAE;aACpB,UAAU,CAAC,WAAW,CAAC;aACvB,KAAK,CAAC,YAAY,EAAE,GAAG,EAAE,QAAQ,CAAC;aAClC,KAAK,CAAC,SAAS,EAAE,GAAG,EAAE,OAAO,CAAC;aAC9B,SAAS,EAAE;aACX,KAAK,CAAC,CAAC,CAAC;aACR,gBAAgB,EAAE,CAAA;QACrB,OAAO;YACL,UAAU,EAAE,CAAC,CAAC,GAAG;SAClB,CAAA;IACH,CAAC;IAED,KAAK,CAAC,wBAAwB,CAAC,GAAG;QAChC,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,GAAG,CAAA;QACvC,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,OAAO,CAAA;QAC7B,IAAI,OAAO,GAAG,EAAE,CAAC,EAAE;aAChB,UAAU,CAAC,MAAM,CAAC;aAClB,KAAK,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CACpB,MAAM,CACJ,EAAE,CAAC,EAAE;aACF,UAAU,CAAC,WAAW,CAAC;aACvB,KAAK,CAAC,sBAAsB,EAAE,GAAG,EAAE,QAAQ,CAAC;aAC5C,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC;aACnD,SAAS,EAAE,CACf,CACF;aACA,SAAS,CAAC,MAAM,CAAC,CAAA;QAEpB,MAAM,MAAM,GAAG,IAAI,aAAa,CAAC,GAAG,CAAC,gBAAgB,CAAC,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC,CAAA;QACxE,OAAO,GAAG,QAAQ,CAAC,OAAO,EAAE;YAC1B,KAAK;YACL,MAAM;YACN,MAAM;SACP,CAAC,CAAA;QACF,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,CAAA;QAErC,OAAO;YACL,QAAQ,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;YACjC,MAAM,EAAE,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC;SACrC,CAAA;IACH,CAAC;IAED,KAAK,CAAC,eAAe,CAAC,GAAG;QACvB,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,cAAc,EAAE,GAAG,GAAG,CAAA;QACjE,MAAM,CAAC,QAAQ,KAAK,UAAU,EAAE,sBAAsB,CAAC,CAAA,CAAC,2CAA2C;QACnG,MAAM,EAAE,CAAC,EAAE;aACR,UAAU,CAAC,MAAM,CAAC;aAClB,MAAM,CAAC;YACN,UAAU;YACV,UAAU,EAAE,QAAQ;YACpB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,WAAW;YACX,cAAc;SACf,CAAC;aACD,UAAU,CAAC,CAAC,EAAE,EAAE,EAAE,CACjB,EAAE;aACC,OAAO,CAAC,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;aACrC,WAAW,CAAC,EAAE,WAAW,EAAE,cAAc,EAAE,CAAC,CAChD;aACA,OAAO,EAAE,CAAA;IACd,CAAC;IAED,KAAK,CAAC,eAAe,CAAC,GAAG;QACvB,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,GAAG,CAAA;QACpC,MAAM,CAAC,QAAQ,KAAK,UAAU,EAAE,sBAAsB,CAAC,CAAA;QACvD,MAAM,EAAE,CAAC,EAAE;aACR,UAAU,CAAC,MAAM,CAAC;aAClB,KAAK,CAAC,YAAY,EAAE,GAAG,EAAE,UAAU,CAAC;aACpC,KAAK,CAAC,YAAY,EAAE,GAAG,EAAE,QAAQ,CAAC;aAClC,OAAO,EAAE,CAAA;IACd,CAAC;IAED,KAAK,CAAC,eAAe,CAAC,GAAG;QACvB,MAAM,EAAE,QAAQ,EAAE,GAAG,GAAG,CAAA;QACxB,MAAM,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,YAAY,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC,OAAO,EAAE,CAAA;IAC7E,CAAC;IAED,KAAK,CAAC,+BAA+B,CAAC,GAAG;QACvC,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,GAAG,CAAA;QACpC,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC,EAAE,kBAAkB,CAAC,CAAA;QACjD,MAAM,EAAE,CAAC,EAAE;aACR,UAAU,CAAC,WAAW,CAAC;aACvB,MAAM,CAAC;YACN,OAAO,EAAE,UAAU;YACnB,UAAU,EAAE,QAAQ;YACpB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACpC,CAAC;aACD,UAAU,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC;aAClC,OAAO,EAAE,CAAA;IACd,CAAC;IAED,KAAK,CAAC,+BAA+B,CAAC,GAAG;QACvC,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,GAAG,CAAA;QACpC,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC,EAAE,kBAAkB,CAAC,CAAA;QACjD,MAAM,EAAE,CAAC,EAAE;aACR,UAAU,CAAC,WAAW,CAAC;aACvB,KAAK,CAAC,SAAS,EAAE,GAAG,EAAE,UAAU,CAAC;aACjC,KAAK,CAAC,YAAY,EAAE,GAAG,EAAE,QAAQ,CAAC;aAClC,OAAO,EAAE,CAAA;IACd,CAAC;IAED,KAAK,CAAC,+BAA+B,CAAC,GAAG;QACvC,MAAM,EAAE,QAAQ,EAAE,GAAG,GAAG,CAAA;QACxB,MAAM,EAAE,CAAC,EAAE;aACR,UAAU,CAAC,WAAW,CAAC;aACvB,KAAK,CAAC,YAAY,EAAE,GAAG,EAAE,QAAQ,CAAC;aAClC,OAAO,EAAE,CAAA;IACd,CAAC;IAED,KAAK,CAAC,wBAAwB,CAAC,GAAG;QAChC,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,GAAG,GAAG,CAAA;QACrC,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC7B,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,CAAA;QACtB,CAAC;QACD,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,EAAE;aACpB,UAAU,CAAC,aAAa,CAAC;aACzB,SAAS,EAAE;aACX,KAAK,CAAC,YAAY,EAAE,GAAG,EAAE,QAAQ,CAAC;aAClC,KAAK,CAAC,SAAS,EAAE,IAAI,EAAE,WAAW,CAAC;aACnC,OAAO,EAAE,CAAA;QACZ,MAAM,SAAS,GAAG,KAAK,CAAC,GAAG,EAAE,SAAS,CAAC,CAAA;QACvC,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAA;QAC5D,OAAO,EAAE,KAAK,EAAE,CAAA;IAClB,CAAC;CACF,CAAC,CAAA;AAEF,MAAM,SAAS,GAAG,CAAC,GAAW,EAAE,EAAE,CAChC,IAAI,KAAK,CAAC,GAAG,CAAC,CAAC,UAAU,KAAK,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAA","sourcesContent":["import assert from 'node:assert'\nimport type { ServiceImpl } from '@connectrpc/connect'\nimport { keyBy } from '@atproto/common'\nimport { AtUri } from '@atproto/syntax'\nimport { app } from '../../../lexicons/index.js'\nimport type { Service } from '../../../proto/bsky_connect.js'\nimport type { Database } from '../db/index.js'\nimport {\n CreatedAtDidKeyset,\n TimeCidKeyset,\n paginate,\n} from '../db/pagination.js'\n\nexport default (db: Database): Partial<ServiceImpl<typeof Service>> => ({\n async getActorMutesActor(req) {\n const { actorDid, targetDid } = req\n const res = await db.db\n .selectFrom('mute')\n .selectAll()\n .where('mutedByDid', '=', actorDid)\n .where('subjectDid', '=', targetDid)\n .executeTakeFirst()\n return {\n muted: res != null && !res.onlyReposts && !res.onlyQuoteposts,\n mutedOnlyReposts: res?.onlyReposts ?? false,\n mutedOnlyQuoteposts: res?.onlyQuoteposts ?? false,\n }\n },\n\n async getMutes(req) {\n const { actorDid, limit, cursor } = req\n const { ref } = db.db.dynamic\n\n let builder = db.db\n .selectFrom('mute')\n .innerJoin('actor', 'actor.did', 'mute.subjectDid')\n .where('mute.mutedByDid', '=', actorDid)\n .selectAll('actor')\n .select('mute.createdAt as createdAt')\n .select('mute.onlyReposts as onlyReposts')\n .select('mute.onlyQuoteposts as onlyQuoteposts')\n\n const keyset = new CreatedAtDidKeyset(\n ref('mute.createdAt'),\n ref('mute.subjectDid'),\n )\n builder = paginate(builder, {\n limit,\n cursor,\n keyset,\n })\n\n const mutes = await builder.execute()\n\n return {\n dids: mutes.map((m) => m.did),\n mutes: mutes.map((m) => ({\n did: m.did,\n onlyReposts: m.onlyReposts,\n onlyQuoteposts: m.onlyQuoteposts,\n })),\n cursor: keyset.packFromResult(mutes),\n }\n },\n\n async getActorMutesActorViaList(req) {\n const { actorDid, targetDid } = req\n const res = await db.db\n .selectFrom('list_mute')\n .innerJoin('list_item', 'list_item.listUri', 'list_mute.listUri')\n .where('list_mute.mutedByDid', '=', actorDid)\n .where('list_item.subjectDid', '=', targetDid)\n .select('list_mute.listUri')\n .limit(1)\n .executeTakeFirst()\n return {\n listUri: res?.listUri,\n }\n },\n\n async getMutelistSubscription(req) {\n const { actorDid, listUri } = req\n const res = await db.db\n .selectFrom('list_mute')\n .where('mutedByDid', '=', actorDid)\n .where('listUri', '=', listUri)\n .selectAll()\n .limit(1)\n .executeTakeFirst()\n return {\n subscribed: !!res,\n }\n },\n\n async getMutelistSubscriptions(req) {\n const { actorDid, limit, cursor } = req\n const { ref } = db.db.dynamic\n let builder = db.db\n .selectFrom('list')\n .where(({ exists }) =>\n exists(\n db.db\n .selectFrom('list_mute')\n .where('list_mute.mutedByDid', '=', actorDid)\n .whereRef('list_mute.listUri', '=', ref('list.uri'))\n .selectAll(),\n ),\n )\n .selectAll('list')\n\n const keyset = new TimeCidKeyset(ref('list.createdAt'), ref('list.cid'))\n builder = paginate(builder, {\n limit,\n cursor,\n keyset,\n })\n const lists = await builder.execute()\n\n return {\n listUris: lists.map((l) => l.uri),\n cursor: keyset.packFromResult(lists),\n }\n },\n\n async createActorMute(req) {\n const { actorDid, subjectDid, onlyReposts, onlyQuoteposts } = req\n assert(actorDid !== subjectDid, 'cannot mute yourself') // @TODO pass message through in http error\n await db.db\n .insertInto('mute')\n .values({\n subjectDid,\n mutedByDid: actorDid,\n createdAt: new Date().toISOString(),\n onlyReposts,\n onlyQuoteposts,\n })\n .onConflict((oc) =>\n oc\n .columns(['mutedByDid', 'subjectDid'])\n .doUpdateSet({ onlyReposts, onlyQuoteposts }),\n )\n .execute()\n },\n\n async deleteActorMute(req) {\n const { actorDid, subjectDid } = req\n assert(actorDid !== subjectDid, 'cannot mute yourself')\n await db.db\n .deleteFrom('mute')\n .where('subjectDid', '=', subjectDid)\n .where('mutedByDid', '=', actorDid)\n .execute()\n },\n\n async clearActorMutes(req) {\n const { actorDid } = req\n await db.db.deleteFrom('mute').where('mutedByDid', '=', actorDid).execute()\n },\n\n async createActorMutelistSubscription(req) {\n const { actorDid, subjectUri } = req\n assert(isListUri(subjectUri), 'must mute a list')\n await db.db\n .insertInto('list_mute')\n .values({\n listUri: subjectUri,\n mutedByDid: actorDid,\n createdAt: new Date().toISOString(),\n })\n .onConflict((oc) => oc.doNothing())\n .execute()\n },\n\n async deleteActorMutelistSubscription(req) {\n const { actorDid, subjectUri } = req\n assert(isListUri(subjectUri), 'must mute a list')\n await db.db\n .deleteFrom('list_mute')\n .where('listUri', '=', subjectUri)\n .where('mutedByDid', '=', actorDid)\n .execute()\n },\n\n async clearActorMutelistSubscriptions(req) {\n const { actorDid } = req\n await db.db\n .deleteFrom('list_mute')\n .where('mutedByDid', '=', actorDid)\n .execute()\n },\n\n async getThreadMutesOnSubjects(req) {\n const { actorDid, threadRoots } = req\n if (threadRoots.length === 0) {\n return { muted: [] }\n }\n const res = await db.db\n .selectFrom('thread_mute')\n .selectAll()\n .where('mutedByDid', '=', actorDid)\n .where('rootUri', 'in', threadRoots)\n .execute()\n const byRootUri = keyBy(res, 'rootUri')\n const muted = threadRoots.map((uri) => !!byRootUri.get(uri))\n return { muted }\n },\n})\n\nconst isListUri = (uri: string) =>\n new AtUri(uri).collection === app.bsky.graph.list.$type\n"]}
1
+ {"version":3,"file":"mutes.js","sourceRoot":"","sources":["../../../../src/data-plane/server/routes/mutes.ts"],"names":[],"mappings":"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","sourcesContent":["import assert from 'node:assert'\nimport type { ServiceImpl } from '@connectrpc/connect'\nimport { keyBy } from '@atproto/common'\nimport { AtUri } from '@atproto/syntax'\nimport { app } from '../../../lexicons/index.js'\nimport type { Service } from '../../../proto/bsky_connect.js'\nimport type { Database } from '../db/index.js'\nimport {\n CreatedAtDidKeyset,\n TimeCidKeyset,\n paginate,\n} from '../db/pagination.js'\n\nexport default (db: Database): Partial<ServiceImpl<typeof Service>> => ({\n async getActorMutesActor(req) {\n const { actorDid, targetDid } = req\n const res = await db.db\n .selectFrom('mute')\n .selectAll()\n .where('mutedByDid', '=', actorDid)\n .where('subjectDid', '=', targetDid)\n .executeTakeFirst()\n return {\n muted: res != null && !res.onlyReposts && !res.onlyQuoteposts,\n mutedOnlyReposts: res?.onlyReposts ?? false,\n mutedOnlyQuoteposts: res?.onlyQuoteposts ?? false,\n }\n },\n\n async getMutes(req) {\n const { actorDid, limit, cursor } = req\n const { ref } = db.db.dynamic\n\n let builder = db.db\n .selectFrom('mute')\n .innerJoin('actor', 'actor.did', 'mute.subjectDid')\n .where('mute.mutedByDid', '=', actorDid)\n .selectAll('actor')\n .select('mute.createdAt as createdAt')\n .select('mute.onlyReposts as onlyReposts')\n .select('mute.onlyQuoteposts as onlyQuoteposts')\n\n const keyset = new CreatedAtDidKeyset(\n ref('mute.createdAt'),\n ref('mute.subjectDid'),\n )\n builder = paginate(builder, {\n limit,\n cursor,\n keyset,\n })\n\n const page = keyset.page(await builder.execute(), limit)\n\n return {\n dids: page.items.map((m) => m.did),\n mutes: page.items.map((m) => ({\n did: m.did,\n onlyReposts: m.onlyReposts,\n onlyQuoteposts: m.onlyQuoteposts,\n })),\n cursor: page.cursor,\n }\n },\n\n async getActorMutesActorViaList(req) {\n const { actorDid, targetDid } = req\n const res = await db.db\n .selectFrom('list_mute')\n .innerJoin('list_item', 'list_item.listUri', 'list_mute.listUri')\n .where('list_mute.mutedByDid', '=', actorDid)\n .where('list_item.subjectDid', '=', targetDid)\n .select('list_mute.listUri')\n .limit(1)\n .executeTakeFirst()\n return {\n listUri: res?.listUri,\n }\n },\n\n async getMutelistSubscription(req) {\n const { actorDid, listUri } = req\n const res = await db.db\n .selectFrom('list_mute')\n .where('mutedByDid', '=', actorDid)\n .where('listUri', '=', listUri)\n .selectAll()\n .limit(1)\n .executeTakeFirst()\n return {\n subscribed: !!res,\n }\n },\n\n async getMutelistSubscriptions(req) {\n const { actorDid, limit, cursor } = req\n const { ref } = db.db.dynamic\n let builder = db.db\n .selectFrom('list')\n .where(({ exists }) =>\n exists(\n db.db\n .selectFrom('list_mute')\n .where('list_mute.mutedByDid', '=', actorDid)\n .whereRef('list_mute.listUri', '=', ref('list.uri'))\n .selectAll(),\n ),\n )\n .selectAll('list')\n\n const keyset = new TimeCidKeyset(ref('list.createdAt'), ref('list.cid'))\n builder = paginate(builder, {\n limit,\n cursor,\n keyset,\n })\n const page = keyset.page(await builder.execute(), limit)\n\n return {\n listUris: page.items.map((l) => l.uri),\n cursor: page.cursor,\n }\n },\n\n async createActorMute(req) {\n const { actorDid, subjectDid, onlyReposts, onlyQuoteposts } = req\n assert(actorDid !== subjectDid, 'cannot mute yourself') // @TODO pass message through in http error\n await db.db\n .insertInto('mute')\n .values({\n subjectDid,\n mutedByDid: actorDid,\n createdAt: new Date().toISOString(),\n onlyReposts,\n onlyQuoteposts,\n })\n .onConflict((oc) =>\n oc\n .columns(['mutedByDid', 'subjectDid'])\n .doUpdateSet({ onlyReposts, onlyQuoteposts }),\n )\n .execute()\n },\n\n async deleteActorMute(req) {\n const { actorDid, subjectDid } = req\n assert(actorDid !== subjectDid, 'cannot mute yourself')\n await db.db\n .deleteFrom('mute')\n .where('subjectDid', '=', subjectDid)\n .where('mutedByDid', '=', actorDid)\n .execute()\n },\n\n async clearActorMutes(req) {\n const { actorDid } = req\n await db.db.deleteFrom('mute').where('mutedByDid', '=', actorDid).execute()\n },\n\n async createActorMutelistSubscription(req) {\n const { actorDid, subjectUri } = req\n assert(isListUri(subjectUri), 'must mute a list')\n await db.db\n .insertInto('list_mute')\n .values({\n listUri: subjectUri,\n mutedByDid: actorDid,\n createdAt: new Date().toISOString(),\n })\n .onConflict((oc) => oc.doNothing())\n .execute()\n },\n\n async deleteActorMutelistSubscription(req) {\n const { actorDid, subjectUri } = req\n assert(isListUri(subjectUri), 'must mute a list')\n await db.db\n .deleteFrom('list_mute')\n .where('listUri', '=', subjectUri)\n .where('mutedByDid', '=', actorDid)\n .execute()\n },\n\n async clearActorMutelistSubscriptions(req) {\n const { actorDid } = req\n await db.db\n .deleteFrom('list_mute')\n .where('mutedByDid', '=', actorDid)\n .execute()\n },\n\n async getThreadMutesOnSubjects(req) {\n const { actorDid, threadRoots } = req\n if (threadRoots.length === 0) {\n return { muted: [] }\n }\n const res = await db.db\n .selectFrom('thread_mute')\n .selectAll()\n .where('mutedByDid', '=', actorDid)\n .where('rootUri', 'in', threadRoots)\n .execute()\n const byRootUri = keyBy(res, 'rootUri')\n const muted = threadRoots.map((uri) => !!byRootUri.get(uri))\n return { muted }\n },\n})\n\nconst isListUri = (uri: string) =>\n new AtUri(uri).collection === app.bsky.graph.list.$type\n"]}
@@ -41,8 +41,8 @@ export default (db) => ({
41
41
  cursor,
42
42
  limit,
43
43
  });
44
- const notifsRes = await builder.execute();
45
- const notifications = notifsRes.map((notif) => ({
44
+ const page = key.page(await builder.execute(), limit);
45
+ const notifications = page.items.map((notif) => ({
46
46
  recipientDid: actorDid,
47
47
  uri: notif.uri,
48
48
  reason: notif.reason,
@@ -52,7 +52,7 @@ export default (db) => ({
52
52
  }));
53
53
  return {
54
54
  notifications,
55
- cursor: key.packFromResult(notifsRes),
55
+ cursor: page.cursor,
56
56
  };
57
57
  },
58
58
  async getNotificationSeen(req) {
@@ -1 +1 @@
1
- {"version":3,"file":"notifs.js","sourceRoot":"","sources":["../../../../src/data-plane/server/routes/notifs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;AAE9C,OAAO,EAAE,GAAG,EAAE,MAAM,QAAQ,CAAA;AAC5B,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAA;AACvC,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AAGvC,OAAO,EACL,gCAAgC,EAChC,mBAAmB,EACnB,sBAAsB,EACtB,uBAAuB,GACxB,MAAM,2BAA2B,CAAA;AAClC,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAE9C,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,EAAE,QAAQ,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAA;AAE9D,eAAe,CAAC,EAAY,EAAwC,EAAE,CAAC,CAAC;IACtE,KAAK,CAAC,gBAAgB,CAAC,GAAG;QACxB,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,GAAG,CAAA;QACjD,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,OAAO,CAAA;QAC7B,MAAM,gBAAgB,GAAG,EAAE,CAAC,EAAE;aAC3B,UAAU,CAAC,QAAQ,CAAC;aACpB,MAAM,CAAC,GAAG,CAAS,GAAG,IAAI,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC;aACvC,KAAK,CAAC,SAAS,EAAE,GAAG,EAAE,QAAQ,CAAC;aAC/B,QAAQ,CAAC,YAAY,EAAE,GAAG,EAAE,GAAG,CAAC,cAAc,CAAC,CAAC;aAChD,KAAK,CAAC,CAAC,CAAC,CAAA;QAEX,IAAI,OAAO,GAAG,EAAE,CAAC,EAAE;aAChB,UAAU,CAAC,uBAAuB,CAAC;aACnC,KAAK,CAAC,WAAW,EAAE,GAAG,EAAE,QAAQ,CAAC;aACjC,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,CACZ,EAAE,CAAC,EAAE,CAAC;YACJ,EAAE,CAAC,eAAe,EAAE,IAAI,EAAE,IAAI,CAAC;YAC/B,EAAE,CAAC,MAAM,CACP,EAAE,CAAC,EAAE;iBACF,UAAU,CAAC,mBAAmB,CAAC;iBAC/B,SAAS,EAAE;iBACX,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE,GAAG,CAAC,qBAAqB,CAAC,CAAC,CAC5D;SACF,CAAC,CACH;aACA,GAAG,CAAC,QAAQ,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC;aACzE,MAAM,CAAC;YACN,2BAA2B;YAC3B,wBAAwB;YACxB,wBAAwB;YACxB,wBAAwB;YACxB,sCAAsC;YACtC,wBAAwB;SACzB,CAAC;aACD,MAAM,CAAC,gBAAgB,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAA;QAE1C,MAAM,GAAG,GAAG,IAAI,YAAY,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAA;QACjD,OAAO,GAAG,GAAG,CAAC,QAAQ,CAAC,OAAO,EAAE;YAC9B,MAAM;YACN,KAAK;SACN,CAAC,CAAA;QAEF,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,CAAA;QACzC,MAAM,aAAa,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YAC9C,YAAY,EAAE,QAAQ;YACtB,GAAG,EAAE,KAAK,CAAC,GAAG;YACd,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,aAAa,EAAE,KAAK,CAAC,aAAa,IAAI,SAAS;YAC/C,SAAS,EAAE,SAAS,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YACrD,QAAQ,EAAE,KAAK,CAAC,QAAQ,IAAI,KAAK;SAClC,CAAC,CAAC,CAAA;QACH,OAAO;YACL,aAAa;YACb,MAAM,EAAE,GAAG,CAAC,cAAc,CAAC,SAAS,CAAC;SACtC,CAAA;IACH,CAAC;IAED,KAAK,CAAC,mBAAmB,CAAC,GAAG;QAC3B,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,GAAG,CAAA;QAClC,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,EAAE;aACpB,UAAU,CAAC,aAAa,CAAC;aACzB,KAAK,CAAC,KAAK,EAAE,GAAG,EAAE,QAAQ,CAAC;aAC3B,SAAS,EAAE;aACX,gBAAgB,EAAE,CAAA;QACrB,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,OAAO,EAAE,CAAA;QACX,CAAC;QACD,MAAM,QAAQ,GACZ,QAAQ,IAAI,GAAG,CAAC,sBAAsB;YACpC,CAAC,CAAC,GAAG,CAAC,sBAAsB;YAC5B,CAAC,CAAC,GAAG,CAAC,cAAc,CAAA;QACxB,OAAO;YACL,SAAS,EAAE,SAAS,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAC;SAClD,CAAA;IACH,CAAC;IAED,KAAK,CAAC,0BAA0B,CAAC,GAAG;QAClC,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,GAAG,CAAA;QAClC,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,OAAO,CAAA;QAC7B,MAAM,WAAW,GAAG,MAAM,EAAE,CAAC,EAAE;aAC5B,UAAU,CAAC,aAAa,CAAC;aACzB,KAAK,CAAC,KAAK,EAAE,GAAG,EAAE,QAAQ,CAAC;aAC3B,SAAS,EAAE;aACX,gBAAgB,EAAE,CAAA;QACrB,MAAM,QAAQ,GACZ,QAAQ,IAAI,WAAW,EAAE,sBAAsB;YAC7C,CAAC,CAAC,WAAW,CAAC,sBAAsB;YACpC,CAAC,CAAC,WAAW,EAAE,cAAc,CAAA;QAEjC,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,EAAE;aACvB,UAAU,CAAC,cAAc,CAAC;aAC1B,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC;aAC5B,SAAS,CAAC,OAAO,EAAE,WAAW,EAAE,kBAAkB,CAAC;aACnD,QAAQ,CAAC,aAAa,EAAE,iBAAiB,EAAE,WAAW,CAAC;aACvD,SAAS,CAAC,QAAQ,EAAE,YAAY,EAAE,wBAAwB,CAAC;aAC3D,KAAK,CAAC,oBAAoB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC;aAC1C,KAAK,CAAC,oBAAoB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;YAC1C,yFAAyF;aACxF,KAAK,CAAC,kBAAkB,EAAE,GAAG,EAAE,QAAQ,CAAC;aACxC,KAAK,CAAC,qBAAqB,EAAE,GAAG,EAAE,QAAQ,IAAI,EAAE,CAAC;aACjD,GAAG,CAAC,QAAQ,EAAE,CAAC,EAAE,EAAE,EAAE,CACpB,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CACtB,MAAM,CACJ,EAAE,CAAC,EAAE;aACF,UAAU,CAAC,QAAQ,CAAC;aACpB,MAAM,CAAC,GAAG,CAAS,GAAG,IAAI,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC;aACvC,KAAK,CAAC,SAAS,EAAE,GAAG,EAAE,QAAQ,CAAC;aAC/B,QAAQ,CAAC,YAAY,EAAE,GAAG,EAAE,GAAG,CAAC,qBAAqB,CAAC,CAAC,CAC3D,CACF,CACF;aACA,gBAAgB,EAAE,CAAA;QAErB,OAAO;YACL,KAAK,EAAE,MAAM,EAAE,KAAK;SACrB,CAAA;IACH,CAAC;IAED,KAAK,CAAC,sBAAsB,CAAC,GAAG;QAC9B,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,GAAG,CAAA;QAC7C,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,OAAM;QACR,CAAC;QACD,MAAM,YAAY,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,WAAW,EAAE,CAAA;QACrD,IAAI,OAAO,GAAG,EAAE,CAAC,EAAE;aAChB,WAAW,CAAC,aAAa,CAAC;aAC1B,KAAK,CAAC,KAAK,EAAE,GAAG,EAAE,QAAQ,CAAC;aAC3B,YAAY,EAAE,CAAA;QACjB,IAAI,QAAQ,EAAE,CAAC;YACb,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,EAAE,sBAAsB,EAAE,YAAY,EAAE,CAAC,CAAA;QACjE,CAAC;aAAM,CAAC;YACN,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,EAAE,cAAc,EAAE,YAAY,EAAE,CAAC,CAAA;QACzD,CAAC;QACD,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,gBAAgB,EAAE,CAAA;QAClD,IAAI,SAAS,EAAE,CAAC;YACd,OAAM;QACR,CAAC;QACD,MAAM,EAAE,CAAC,EAAE;aACR,UAAU,CAAC,aAAa,CAAC;aACzB,MAAM,CAAC;YACN,GAAG,EAAE,QAAQ;YACb,cAAc,EAAE,YAAY;YAC5B,cAAc,EAAE,QAAQ;YACxB,sBAAsB,EAAE,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS;SAC5D,CAAC;aACD,UAAU,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC;aAClC,gBAAgB,EAAE,CAAA;IACvB,CAAC;IAED,KAAK,CAAC,0BAA0B,CAAC,GAAG;QAClC,MAAM,EAAE,IAAI,EAAE,GAAG,GAAG,CAAA;QACpB,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtB,OAAO,EAAE,WAAW,EAAE,EAAE,EAAE,CAAA;QAC5B,CAAC;QAED,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,EAAE;aACpB,UAAU,CAAC,cAAc,CAAC;aAC1B,SAAS,EAAE;aACX,KAAK,CAAC,UAAU,EAAE,IAAI,EAAE,IAAI,CAAC;aAC7B,KAAK,CACJ,WAAW,EACX,GAAG,EACH,UAAU,CAAC,kCAAkC,CAAC,KAAK,CACpD;aACA,KAAK,CAAC,KAAK,EAAE,GAAG,EAAE,MAAM,CAAC;aACzB,OAAO,EAAE,CAAA;QAEZ,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,EAAE,UAAU,CAAC,CAAA;QACpC,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;YACnC,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;YAC1B,IAAI,CAAC,GAAG,EAAE,CAAC;gBACT,OAAO,EAAE,CAAA;YACX,CAAC;YACD,MAAM,CAAC,GAAG,QAAQ,CAAyC,GAAG,CAAC,OAAO,CAAC,CAAA;YACvE,OAAO,oCAAoC,CAAC,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;QAC7D,CAAC,CAAC,CAAA;QAEF,OAAO,EAAE,WAAW,EAAE,CAAA;IACxB,CAAC;CACF,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,oCAAoC,GAAG,CAClD,CAAyC,EACzC,IAAY,EACa,EAAE;IAC3B,MAAM,iCAAiC,GAAG,CACxC,CAAkD,EAChB,EAAE,CACpC,IAAI,gCAAgC,CAAC;QACnC,OAAO,EACL,CAAC,CAAC,OAAO,KAAK,SAAS;YACrB,CAAC,CAAC,mBAAmB,CAAC,OAAO;YAC7B,CAAC,CAAC,mBAAmB,CAAC,GAAG;QAC7B,IAAI,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,IAAI,IAAI,IAAI,EAAE;QACjC,IAAI,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,IAAI,IAAI,IAAI,EAAE;KAClC,CAAC,CAAA;IAEJ,MAAM,uBAAuB,GAAG,CAC9B,CAAwC,EAChB,EAAE,CAC1B,IAAI,sBAAsB,CAAC;QACzB,IAAI,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,IAAI,IAAI,IAAI,EAAE;QACjC,IAAI,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,IAAI,IAAI,IAAI,EAAE;KAClC,CAAC,CAAA;IAEJ,OAAO,IAAI,uBAAuB,CAAC;QACjC,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;QACxB,MAAM,EAAE,iCAAiC,CAAC,CAAC,CAAC,MAAM,CAAC;QACnD,IAAI,EAAE,iCAAiC,CAAC,CAAC,CAAC,IAAI,CAAC;QAC/C,aAAa,EAAE,iCAAiC,CAAC,CAAC,CAAC,aAAa,CAAC;QACjE,OAAO,EAAE,iCAAiC,CAAC,CAAC,CAAC,OAAO,CAAC;QACrD,KAAK,EAAE,iCAAiC,CAAC,CAAC,CAAC,KAAK,CAAC;QACjD,KAAK,EAAE,iCAAiC,CAAC,CAAC,CAAC,KAAK,CAAC;QACjD,MAAM,EAAE,iCAAiC,CAAC,CAAC,CAAC,MAAM,CAAC;QACnD,eAAe,EAAE,iCAAiC,CAAC,CAAC,CAAC,eAAe,CAAC;QACrE,iBAAiB,EAAE,uBAAuB,CAAC,CAAC,CAAC,iBAAiB,CAAC;QAC/D,cAAc,EAAE,uBAAuB,CAAC,CAAC,CAAC,cAAc,CAAC;QACzD,UAAU,EAAE,uBAAuB,CAAC,CAAC,CAAC,UAAU,CAAC;QACjD,QAAQ,EAAE,uBAAuB,CAAC,CAAC,CAAC,QAAQ,CAAC;KAC9C,CAAC,CAAA;AACJ,CAAC,CAAA","sourcesContent":["import { Timestamp } from '@bufbuild/protobuf'\nimport type { ServiceImpl } from '@connectrpc/connect'\nimport { sql } from 'kysely'\nimport { keyBy } from '@atproto/common'\nimport { lexParse } from '@atproto/lex'\nimport type { app } from '../../../lexicons/index.js'\nimport type { Service } from '../../../proto/bsky_connect.js'\nimport {\n FilterableNotificationPreference,\n NotificationInclude,\n NotificationPreference,\n NotificationPreferences,\n} from '../../../proto/bsky_pb.js'\nimport { Namespaces } from '../../../stash.js'\nimport type { Database } from '../db/index.js'\nimport { IsoSortAtKey } from '../db/pagination.js'\nimport { countAll, notSoftDeletedClause } from '../db/util.js'\n\nexport default (db: Database): Partial<ServiceImpl<typeof Service>> => ({\n async getNotifications(req) {\n const { actorDid, limit, cursor, priority } = req\n const { ref } = db.db.dynamic\n const priorityFollowQb = db.db\n .selectFrom('follow')\n .select(sql<boolean>`${true}`.as('val'))\n .where('creator', '=', actorDid)\n .whereRef('subjectDid', '=', ref('notif.author'))\n .limit(1)\n\n let builder = db.db\n .selectFrom('notification as notif')\n .where('notif.did', '=', actorDid)\n .where((eb) =>\n eb.or([\n eb('reasonSubject', 'is', null),\n eb.exists(\n db.db\n .selectFrom('record as subject')\n .selectAll()\n .whereRef('subject.uri', '=', ref('notif.reasonSubject')),\n ),\n ]),\n )\n .$if(priority, (qb) => qb.where(({ exists }) => exists(priorityFollowQb)))\n .select([\n 'notif.author as authorDid',\n 'notif.recordUri as uri',\n 'notif.recordCid as cid',\n 'notif.reason as reason',\n 'notif.reasonSubject as reasonSubject',\n 'notif.sortAt as sortAt',\n ])\n .select(priorityFollowQb.as('priority'))\n\n const key = new IsoSortAtKey(ref('notif.sortAt'))\n builder = key.paginate(builder, {\n cursor,\n limit,\n })\n\n const notifsRes = await builder.execute()\n const notifications = notifsRes.map((notif) => ({\n recipientDid: actorDid,\n uri: notif.uri,\n reason: notif.reason,\n reasonSubject: notif.reasonSubject ?? undefined,\n timestamp: Timestamp.fromDate(new Date(notif.sortAt)),\n priority: notif.priority ?? false,\n }))\n return {\n notifications,\n cursor: key.packFromResult(notifsRes),\n }\n },\n\n async getNotificationSeen(req) {\n const { actorDid, priority } = req\n const res = await db.db\n .selectFrom('actor_state')\n .where('did', '=', actorDid)\n .selectAll()\n .executeTakeFirst()\n if (!res) {\n return {}\n }\n const lastSeen =\n priority && res.lastSeenPriorityNotifs\n ? res.lastSeenPriorityNotifs\n : res.lastSeenNotifs\n return {\n timestamp: Timestamp.fromDate(new Date(lastSeen)),\n }\n },\n\n async getUnreadNotificationCount(req) {\n const { actorDid, priority } = req\n const { ref } = db.db.dynamic\n const lastSeenRes = await db.db\n .selectFrom('actor_state')\n .where('did', '=', actorDid)\n .selectAll()\n .executeTakeFirst()\n const lastSeen =\n priority && lastSeenRes?.lastSeenPriorityNotifs\n ? lastSeenRes.lastSeenPriorityNotifs\n : lastSeenRes?.lastSeenNotifs\n\n const result = await db.db\n .selectFrom('notification')\n .select(countAll.as('count'))\n .innerJoin('actor', 'actor.did', 'notification.did')\n .leftJoin('actor_state', 'actor_state.did', 'actor.did')\n .innerJoin('record', 'record.uri', 'notification.recordUri')\n .where(notSoftDeletedClause(ref('record')))\n .where(notSoftDeletedClause(ref('actor')))\n // Ensure to hit notification_did_sortat_idx, handling case where lastSeenNotifs is null.\n .where('notification.did', '=', actorDid)\n .where('notification.sortAt', '>', lastSeen ?? '')\n .$if(priority, (qb) =>\n qb.where(({ exists }) =>\n exists(\n db.db\n .selectFrom('follow')\n .select(sql<boolean>`${true}`.as('val'))\n .where('creator', '=', actorDid)\n .whereRef('subjectDid', '=', ref('notification.author')),\n ),\n ),\n )\n .executeTakeFirst()\n\n return {\n count: result?.count,\n }\n },\n\n async updateNotificationSeen(req) {\n const { actorDid, timestamp, priority } = req\n if (!timestamp) {\n return\n }\n const timestampIso = timestamp.toDate().toISOString()\n let builder = db.db\n .updateTable('actor_state')\n .where('did', '=', actorDid)\n .returningAll()\n if (priority) {\n builder = builder.set({ lastSeenPriorityNotifs: timestampIso })\n } else {\n builder = builder.set({ lastSeenNotifs: timestampIso })\n }\n const updateRes = await builder.executeTakeFirst()\n if (updateRes) {\n return\n }\n await db.db\n .insertInto('actor_state')\n .values({\n did: actorDid,\n lastSeenNotifs: timestampIso,\n priorityNotifs: priority,\n lastSeenPriorityNotifs: priority ? timestampIso : undefined,\n })\n .onConflict((oc) => oc.doNothing())\n .executeTakeFirst()\n },\n\n async getNotificationPreferences(req) {\n const { dids } = req\n if (dids.length === 0) {\n return { preferences: [] }\n }\n\n const res = await db.db\n .selectFrom('private_data')\n .selectAll()\n .where('actorDid', 'in', dids)\n .where(\n 'namespace',\n '=',\n Namespaces.AppBskyNotificationDefsPreferences.$type,\n )\n .where('key', '=', 'self')\n .execute()\n\n const byDid = keyBy(res, 'actorDid')\n const preferences = dids.map((did) => {\n const row = byDid.get(did)\n if (!row) {\n return {}\n }\n const p = lexParse<app.bsky.notification.defs.Preferences>(row.payload)\n return notificationPreferencesLexToProtobuf(p, row.payload)\n })\n\n return { preferences }\n },\n})\n\nexport const notificationPreferencesLexToProtobuf = (\n p: app.bsky.notification.defs.Preferences,\n json: string,\n): NotificationPreferences => {\n const lexFilterablePreferenceToProtobuf = (\n p: app.bsky.notification.defs.FilterablePreference,\n ): FilterableNotificationPreference =>\n new FilterableNotificationPreference({\n include:\n p.include === 'follows'\n ? NotificationInclude.FOLLOWS\n : NotificationInclude.ALL,\n list: { enabled: p.list ?? true },\n push: { enabled: p.push ?? true },\n })\n\n const lexPreferenceToProtobuf = (\n p: app.bsky.notification.defs.Preference,\n ): NotificationPreference =>\n new NotificationPreference({\n list: { enabled: p.list ?? true },\n push: { enabled: p.push ?? true },\n })\n\n return new NotificationPreferences({\n entry: Buffer.from(json),\n follow: lexFilterablePreferenceToProtobuf(p.follow),\n like: lexFilterablePreferenceToProtobuf(p.like),\n likeViaRepost: lexFilterablePreferenceToProtobuf(p.likeViaRepost),\n mention: lexFilterablePreferenceToProtobuf(p.mention),\n quote: lexFilterablePreferenceToProtobuf(p.quote),\n reply: lexFilterablePreferenceToProtobuf(p.reply),\n repost: lexFilterablePreferenceToProtobuf(p.repost),\n repostViaRepost: lexFilterablePreferenceToProtobuf(p.repostViaRepost),\n starterpackJoined: lexPreferenceToProtobuf(p.starterpackJoined),\n subscribedPost: lexPreferenceToProtobuf(p.subscribedPost),\n unverified: lexPreferenceToProtobuf(p.unverified),\n verified: lexPreferenceToProtobuf(p.verified),\n })\n}\n"]}
1
+ {"version":3,"file":"notifs.js","sourceRoot":"","sources":["../../../../src/data-plane/server/routes/notifs.ts"],"names":[],"mappings":"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","sourcesContent":["import { Timestamp } from '@bufbuild/protobuf'\nimport type { ServiceImpl } from '@connectrpc/connect'\nimport { sql } from 'kysely'\nimport { keyBy } from '@atproto/common'\nimport { lexParse } from '@atproto/lex'\nimport type { app } from '../../../lexicons/index.js'\nimport type { Service } from '../../../proto/bsky_connect.js'\nimport {\n FilterableNotificationPreference,\n NotificationInclude,\n NotificationPreference,\n NotificationPreferences,\n} from '../../../proto/bsky_pb.js'\nimport { Namespaces } from '../../../stash.js'\nimport type { Database } from '../db/index.js'\nimport { IsoSortAtKey } from '../db/pagination.js'\nimport { countAll, notSoftDeletedClause } from '../db/util.js'\n\nexport default (db: Database): Partial<ServiceImpl<typeof Service>> => ({\n async getNotifications(req) {\n const { actorDid, limit, cursor, priority } = req\n const { ref } = db.db.dynamic\n const priorityFollowQb = db.db\n .selectFrom('follow')\n .select(sql<boolean>`${true}`.as('val'))\n .where('creator', '=', actorDid)\n .whereRef('subjectDid', '=', ref('notif.author'))\n .limit(1)\n\n let builder = db.db\n .selectFrom('notification as notif')\n .where('notif.did', '=', actorDid)\n .where((eb) =>\n eb.or([\n eb('reasonSubject', 'is', null),\n eb.exists(\n db.db\n .selectFrom('record as subject')\n .selectAll()\n .whereRef('subject.uri', '=', ref('notif.reasonSubject')),\n ),\n ]),\n )\n .$if(priority, (qb) => qb.where(({ exists }) => exists(priorityFollowQb)))\n .select([\n 'notif.author as authorDid',\n 'notif.recordUri as uri',\n 'notif.recordCid as cid',\n 'notif.reason as reason',\n 'notif.reasonSubject as reasonSubject',\n 'notif.sortAt as sortAt',\n ])\n .select(priorityFollowQb.as('priority'))\n\n const key = new IsoSortAtKey(ref('notif.sortAt'))\n builder = key.paginate(builder, {\n cursor,\n limit,\n })\n\n const page = key.page(await builder.execute(), limit)\n const notifications = page.items.map((notif) => ({\n recipientDid: actorDid,\n uri: notif.uri,\n reason: notif.reason,\n reasonSubject: notif.reasonSubject ?? undefined,\n timestamp: Timestamp.fromDate(new Date(notif.sortAt)),\n priority: notif.priority ?? false,\n }))\n return {\n notifications,\n cursor: page.cursor,\n }\n },\n\n async getNotificationSeen(req) {\n const { actorDid, priority } = req\n const res = await db.db\n .selectFrom('actor_state')\n .where('did', '=', actorDid)\n .selectAll()\n .executeTakeFirst()\n if (!res) {\n return {}\n }\n const lastSeen =\n priority && res.lastSeenPriorityNotifs\n ? res.lastSeenPriorityNotifs\n : res.lastSeenNotifs\n return {\n timestamp: Timestamp.fromDate(new Date(lastSeen)),\n }\n },\n\n async getUnreadNotificationCount(req) {\n const { actorDid, priority } = req\n const { ref } = db.db.dynamic\n const lastSeenRes = await db.db\n .selectFrom('actor_state')\n .where('did', '=', actorDid)\n .selectAll()\n .executeTakeFirst()\n const lastSeen =\n priority && lastSeenRes?.lastSeenPriorityNotifs\n ? lastSeenRes.lastSeenPriorityNotifs\n : lastSeenRes?.lastSeenNotifs\n\n const result = await db.db\n .selectFrom('notification')\n .select(countAll.as('count'))\n .innerJoin('actor', 'actor.did', 'notification.did')\n .leftJoin('actor_state', 'actor_state.did', 'actor.did')\n .innerJoin('record', 'record.uri', 'notification.recordUri')\n .where(notSoftDeletedClause(ref('record')))\n .where(notSoftDeletedClause(ref('actor')))\n // Ensure to hit notification_did_sortat_idx, handling case where lastSeenNotifs is null.\n .where('notification.did', '=', actorDid)\n .where('notification.sortAt', '>', lastSeen ?? '')\n .$if(priority, (qb) =>\n qb.where(({ exists }) =>\n exists(\n db.db\n .selectFrom('follow')\n .select(sql<boolean>`${true}`.as('val'))\n .where('creator', '=', actorDid)\n .whereRef('subjectDid', '=', ref('notification.author')),\n ),\n ),\n )\n .executeTakeFirst()\n\n return {\n count: result?.count,\n }\n },\n\n async updateNotificationSeen(req) {\n const { actorDid, timestamp, priority } = req\n if (!timestamp) {\n return\n }\n const timestampIso = timestamp.toDate().toISOString()\n let builder = db.db\n .updateTable('actor_state')\n .where('did', '=', actorDid)\n .returningAll()\n if (priority) {\n builder = builder.set({ lastSeenPriorityNotifs: timestampIso })\n } else {\n builder = builder.set({ lastSeenNotifs: timestampIso })\n }\n const updateRes = await builder.executeTakeFirst()\n if (updateRes) {\n return\n }\n await db.db\n .insertInto('actor_state')\n .values({\n did: actorDid,\n lastSeenNotifs: timestampIso,\n priorityNotifs: priority,\n lastSeenPriorityNotifs: priority ? timestampIso : undefined,\n })\n .onConflict((oc) => oc.doNothing())\n .executeTakeFirst()\n },\n\n async getNotificationPreferences(req) {\n const { dids } = req\n if (dids.length === 0) {\n return { preferences: [] }\n }\n\n const res = await db.db\n .selectFrom('private_data')\n .selectAll()\n .where('actorDid', 'in', dids)\n .where(\n 'namespace',\n '=',\n Namespaces.AppBskyNotificationDefsPreferences.$type,\n )\n .where('key', '=', 'self')\n .execute()\n\n const byDid = keyBy(res, 'actorDid')\n const preferences = dids.map((did) => {\n const row = byDid.get(did)\n if (!row) {\n return {}\n }\n const p = lexParse<app.bsky.notification.defs.Preferences>(row.payload)\n return notificationPreferencesLexToProtobuf(p, row.payload)\n })\n\n return { preferences }\n },\n})\n\nexport const notificationPreferencesLexToProtobuf = (\n p: app.bsky.notification.defs.Preferences,\n json: string,\n): NotificationPreferences => {\n const lexFilterablePreferenceToProtobuf = (\n p: app.bsky.notification.defs.FilterablePreference,\n ): FilterableNotificationPreference =>\n new FilterableNotificationPreference({\n include:\n p.include === 'follows'\n ? NotificationInclude.FOLLOWS\n : NotificationInclude.ALL,\n list: { enabled: p.list ?? true },\n push: { enabled: p.push ?? true },\n })\n\n const lexPreferenceToProtobuf = (\n p: app.bsky.notification.defs.Preference,\n ): NotificationPreference =>\n new NotificationPreference({\n list: { enabled: p.list ?? true },\n push: { enabled: p.push ?? true },\n })\n\n return new NotificationPreferences({\n entry: Buffer.from(json),\n follow: lexFilterablePreferenceToProtobuf(p.follow),\n like: lexFilterablePreferenceToProtobuf(p.like),\n likeViaRepost: lexFilterablePreferenceToProtobuf(p.likeViaRepost),\n mention: lexFilterablePreferenceToProtobuf(p.mention),\n quote: lexFilterablePreferenceToProtobuf(p.quote),\n reply: lexFilterablePreferenceToProtobuf(p.reply),\n repost: lexFilterablePreferenceToProtobuf(p.repost),\n repostViaRepost: lexFilterablePreferenceToProtobuf(p.repostViaRepost),\n starterpackJoined: lexPreferenceToProtobuf(p.starterpackJoined),\n subscribedPost: lexPreferenceToProtobuf(p.subscribedPost),\n unverified: lexPreferenceToProtobuf(p.unverified),\n verified: lexPreferenceToProtobuf(p.verified),\n })\n}\n"]}
@@ -15,10 +15,10 @@ export default (db) => ({
15
15
  cursor,
16
16
  keyset,
17
17
  });
18
- const quotes = await builder.execute();
18
+ const page = keyset.page(await builder.execute(), limit);
19
19
  return {
20
- uris: quotes.map((q) => q.uri),
21
- cursor: keyset.packFromResult(quotes),
20
+ uris: page.items.map((q) => q.uri),
21
+ cursor: page.cursor,
22
22
  };
23
23
  },
24
24
  });
@@ -1 +1 @@
1
- {"version":3,"file":"quotes.js","sourceRoot":"","sources":["../../../../src/data-plane/server/routes/quotes.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAA;AAE7D,eAAe,CAAC,EAAY,EAAwC,EAAE,CAAC,CAAC;IACtE,KAAK,CAAC,wBAAwB,CAAC,GAAG;QAChC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,CAAA;QACtC,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,OAAO,CAAA;QAE7B,IAAI,CAAC,OAAO,EAAE,GAAG;YAAE,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,CAAA;QAEtC,IAAI,OAAO,GAAG,EAAE,CAAC,EAAE;aAChB,UAAU,CAAC,OAAO,CAAC;aACnB,KAAK,CAAC,eAAe,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC;aACxC,MAAM,CAAC,CAAC,WAAW,EAAE,WAAW,EAAE,cAAc,CAAC,CAAC,CAAA;QAErD,MAAM,MAAM,GAAG,IAAI,aAAa,CAAC,GAAG,CAAC,cAAc,CAAC,EAAE,GAAG,CAAC,WAAW,CAAC,CAAC,CAAA;QACvE,OAAO,GAAG,QAAQ,CAAC,OAAO,EAAE;YAC1B,KAAK;YACL,MAAM;YACN,MAAM;SACP,CAAC,CAAA;QAEF,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,CAAA;QAEtC,OAAO;YACL,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;YAC9B,MAAM,EAAE,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC;SACtC,CAAA;IACH,CAAC;CACF,CAAC,CAAA","sourcesContent":["import type { ServiceImpl } from '@connectrpc/connect'\nimport type { Service } from '../../../proto/bsky_connect.js'\nimport type { Database } from '../db/index.js'\nimport { TimeCidKeyset, paginate } from '../db/pagination.js'\n\nexport default (db: Database): Partial<ServiceImpl<typeof Service>> => ({\n async getQuotesBySubjectSorted(req) {\n const { subject, cursor, limit } = req\n const { ref } = db.db.dynamic\n\n if (!subject?.uri) return { uris: [] }\n\n let builder = db.db\n .selectFrom('quote')\n .where('quote.subject', '=', subject.uri)\n .select(['quote.uri', 'quote.cid', 'quote.sortAt'])\n\n const keyset = new TimeCidKeyset(ref('quote.sortAt'), ref('quote.cid'))\n builder = paginate(builder, {\n limit,\n cursor,\n keyset,\n })\n\n const quotes = await builder.execute()\n\n return {\n uris: quotes.map((q) => q.uri),\n cursor: keyset.packFromResult(quotes),\n }\n },\n})\n"]}
1
+ {"version":3,"file":"quotes.js","sourceRoot":"","sources":["../../../../src/data-plane/server/routes/quotes.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAA;AAE7D,eAAe,CAAC,EAAY,EAAwC,EAAE,CAAC,CAAC;IACtE,KAAK,CAAC,wBAAwB,CAAC,GAAG;QAChC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,CAAA;QACtC,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,OAAO,CAAA;QAE7B,IAAI,CAAC,OAAO,EAAE,GAAG;YAAE,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,CAAA;QAEtC,IAAI,OAAO,GAAG,EAAE,CAAC,EAAE;aAChB,UAAU,CAAC,OAAO,CAAC;aACnB,KAAK,CAAC,eAAe,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC;aACxC,MAAM,CAAC,CAAC,WAAW,EAAE,WAAW,EAAE,cAAc,CAAC,CAAC,CAAA;QAErD,MAAM,MAAM,GAAG,IAAI,aAAa,CAAC,GAAG,CAAC,cAAc,CAAC,EAAE,GAAG,CAAC,WAAW,CAAC,CAAC,CAAA;QACvE,OAAO,GAAG,QAAQ,CAAC,OAAO,EAAE;YAC1B,KAAK;YACL,MAAM;YACN,MAAM;SACP,CAAC,CAAA;QAEF,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,OAAO,CAAC,OAAO,EAAE,EAAE,KAAK,CAAC,CAAA;QAExD,OAAO;YACL,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;YAClC,MAAM,EAAE,IAAI,CAAC,MAAM;SACpB,CAAA;IACH,CAAC;CACF,CAAC,CAAA","sourcesContent":["import type { ServiceImpl } from '@connectrpc/connect'\nimport type { Service } from '../../../proto/bsky_connect.js'\nimport type { Database } from '../db/index.js'\nimport { TimeCidKeyset, paginate } from '../db/pagination.js'\n\nexport default (db: Database): Partial<ServiceImpl<typeof Service>> => ({\n async getQuotesBySubjectSorted(req) {\n const { subject, cursor, limit } = req\n const { ref } = db.db.dynamic\n\n if (!subject?.uri) return { uris: [] }\n\n let builder = db.db\n .selectFrom('quote')\n .where('quote.subject', '=', subject.uri)\n .select(['quote.uri', 'quote.cid', 'quote.sortAt'])\n\n const keyset = new TimeCidKeyset(ref('quote.sortAt'), ref('quote.cid'))\n builder = paginate(builder, {\n limit,\n cursor,\n keyset,\n })\n\n const page = keyset.page(await builder.execute(), limit)\n\n return {\n uris: page.items.map((q) => q.uri),\n cursor: page.cursor,\n }\n },\n})\n"]}
@@ -1,7 +1,7 @@
1
1
  import type { ServiceImpl } from '@connectrpc/connect';
2
2
  import { l } from '@atproto/lex';
3
3
  import type { Service } from '../../../proto/bsky_connect.js';
4
- import { PostRecordMeta, Record } from '../../../proto/bsky_pb.js';
4
+ import { OpThread, PostRecordMeta, Record } from '../../../proto/bsky_pb.js';
5
5
  import type { Database } from '../db/index.js';
6
6
  export default _default;
7
7
  declare function _default(db: Database): Partial<ServiceImpl<typeof Service>>;
@@ -12,8 +12,10 @@ export declare const getRecords: (db: Database, ns?: l.Main<l.RecordSchema>) =>
12
12
  }>;
13
13
  export declare const getPostRecords: (db: Database) => (req: {
14
14
  uris: string[];
15
+ includeOpThreadMetadata?: boolean;
15
16
  }) => Promise<{
16
17
  records: Record[];
17
18
  meta: PostRecordMeta[];
19
+ opThreads: OpThread[];
18
20
  }>;
19
21
  //# sourceMappingURL=records.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"records.d.ts","sourceRoot":"","sources":["../../../../src/data-plane/server/routes/records.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AAGtD,OAAO,EAAE,CAAC,EAAE,MAAM,cAAc,CAAA;AAGhC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAA;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAA;AAClE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;;0BAE9B,EAAE,EAAE,QAAQ,GAAG,OAAO,CAAC,WAAW,CAAC,OAAO,OAAO,CAAC,CAAC;AAyBnE,eAAO,MAAM,UAAU,OAAQ,QAAQ,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,WAG/C;IAAE,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE,KAAG,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CAoCtE,CAAA;AAED,eAAO,MAAM,cAAc,OAAQ,QAAQ,WAEtB;IACjB,IAAI,EAAE,MAAM,EAAE,CAAA;CACf,KAAG,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IAAC,IAAI,EAAE,cAAc,EAAE,CAAA;CAAE,CA4B1D,CAAA"}
1
+ {"version":3,"file":"records.d.ts","sourceRoot":"","sources":["../../../../src/data-plane/server/routes/records.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AAGtD,OAAO,EAAE,CAAC,EAAE,MAAM,cAAc,CAAA;AAIhC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAA;AAC7D,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAA;AAC5E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;;0BAG9B,EAAE,EAAE,QAAQ,GAAG,OAAO,CAAC,WAAW,CAAC,OAAO,OAAO,CAAC,CAAC;AAyBnE,eAAO,MAAM,UAAU,OAAQ,QAAQ,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,WAG/C;IAAE,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE,KAAG,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CAoCtE,CAAA;AAED,eAAO,MAAM,cAAc,OAAQ,QAAQ,WAEtB;IACjB,IAAI,EAAE,MAAM,EAAE,CAAA;IACd,uBAAuB,CAAC,EAAE,OAAO,CAAA;CAClC,KAAG,OAAO,CAAC;IACV,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,IAAI,EAAE,cAAc,EAAE,CAAA;IACtB,SAAS,EAAE,QAAQ,EAAE,CAAA;CACtB,CA6BF,CAAA"}
@@ -4,7 +4,9 @@ import { keyBy } from '@atproto/common';
4
4
  import { l } from '@atproto/lex';
5
5
  import { AtUri } from '@atproto/syntax';
6
6
  import { app, chat, com } from '../../../lexicons/index.js';
7
- import { PostRecordMeta, Record } from '../../../proto/bsky_pb.js';
7
+ import { dataplaneLogger } from '../../../logger.js';
8
+ import { OpThread, PostRecordMeta, Record } from '../../../proto/bsky_pb.js';
9
+ import { resolveCanonicalOpThread } from '../op-thread.js';
8
10
  export default (db) => ({
9
11
  getBlockRecords: getRecords(db, app.bsky.graph.block),
10
12
  getFeedGeneratorRecords: getRecords(db, app.bsky.feed.generator),
@@ -68,10 +70,10 @@ export const getRecords = (db, ns) => {
68
70
  export const getPostRecords = (db) => {
69
71
  const getBaseRecords = getRecords(db, app.bsky.feed.post);
70
72
  return async (req) => {
71
- const [{ records }, details] = await Promise.all([
73
+ const [{ records }, details, opThreads] = await Promise.all([
72
74
  getBaseRecords(req),
73
75
  req.uris.length
74
- ? await db.db
76
+ ? db.db
75
77
  .selectFrom('post')
76
78
  .where('uri', 'in', req.uris)
77
79
  .select([
@@ -83,6 +85,7 @@ export const getPostRecords = (db) => {
83
85
  ])
84
86
  .execute()
85
87
  : [],
88
+ req.includeOpThreadMetadata ? getOpThreads(db, req.uris) : [],
86
89
  ]);
87
90
  const byKey = keyBy(details, 'uri');
88
91
  const meta = req.uris.map((uri) => {
@@ -93,9 +96,43 @@ export const getPostRecords = (db) => {
93
96
  hasPostGate: !!byKey.get(uri)?.hasPostGate,
94
97
  });
95
98
  });
96
- return { records, meta };
99
+ return { records, meta, opThreads };
97
100
  };
98
101
  };
102
+ const getOpThreads = async (db, uris) => {
103
+ if (!uris.length)
104
+ return [];
105
+ const requestedRoots = db.db
106
+ .selectFrom('post')
107
+ .where('uri', 'in', uris)
108
+ .select((eb) => eb.fn.coalesce('replyRoot', 'uri').as('rootUri'))
109
+ .distinct();
110
+ const rows = await db.db
111
+ .selectFrom('op_thread_reply')
112
+ .innerJoin(requestedRoots.as('requested_root'), 'requested_root.rootUri', 'op_thread_reply.rootUri')
113
+ .select([
114
+ 'op_thread_reply.rootUri',
115
+ 'op_thread_reply.uri',
116
+ 'op_thread_reply.parentUri',
117
+ 'op_thread_reply.deletedAt',
118
+ ])
119
+ .execute();
120
+ const repliesByRoot = new Map();
121
+ for (const row of rows) {
122
+ const replies = repliesByRoot.get(row.rootUri) ?? [];
123
+ replies.push(row);
124
+ repliesByRoot.set(row.rootUri, replies);
125
+ }
126
+ const opThreads = [];
127
+ for (const [rootUri, replies] of repliesByRoot) {
128
+ const opThread = resolveCanonicalOpThread(rootUri, replies);
129
+ if (!opThread)
130
+ continue;
131
+ opThreads.push(new OpThread({ rootUri, uris: opThread }));
132
+ }
133
+ dataplaneLogger.debug({ uris: uris.length, roots: repliesByRoot.size, rows: rows.length }, 'op threads resolved');
134
+ return opThreads;
135
+ };
99
136
  const compositeTime = (ts1, ts2) => {
100
137
  if (!ts1)
101
138
  return ts2;
@@ -1 +1 @@
1
- {"version":3,"file":"records.js","sourceRoot":"","sources":["../../../../src/data-plane/server/routes/records.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;AAE9C,OAAO,KAAK,GAAG,MAAM,aAAa,CAAA;AAClC,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAA;AACvC,OAAO,EAAE,CAAC,EAAE,MAAM,cAAc,CAAA;AAChC,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAA;AACvC,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,4BAA4B,CAAA;AAE3D,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAA;AAGlE,eAAe,CAAC,EAAY,EAAwC,EAAE,CAAC,CAAC;IACtE,eAAe,EAAE,UAAU,CAAC,EAAE,EAAE,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC;IACrD,uBAAuB,EAAE,UAAU,CAAC,EAAE,EAAE,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC;IAChE,gBAAgB,EAAE,UAAU,CAAC,EAAE,EAAE,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;IACvD,cAAc,EAAE,UAAU,CAAC,EAAE,EAAE,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;IAClD,mBAAmB,EAAE,UAAU,CAAC,EAAE,EAAE,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC;IAC7D,kBAAkB,EAAE,UAAU,CAAC,EAAE,EAAE,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC;IAC3D,cAAc,EAAE,UAAU,CAAC,EAAE,EAAE,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;IACnD,cAAc,EAAE,cAAc,CAAC,EAAE,CAAC;IAClC,iBAAiB,EAAE,UAAU,CAAC,EAAE,EAAE,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC;IACzD,gBAAgB,EAAE,UAAU,CAAC,EAAE,EAAE,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;IACtD,oBAAoB,EAAE,UAAU,CAAC,EAAE,EAAE,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC;IAC9D,kBAAkB,EAAE,UAAU,CAAC,EAAE,EAAE,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC;IAC1D,iBAAiB,EAAE,UAAU,CAAC,EAAE,EAAE,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC;IAC3D,8BAA8B,EAAE,UAAU,CAAC,EAAE,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC;IAC3E,iCAAiC,EAAE,UAAU,CAC3C,EAAE,EACF,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,WAAW,CAClC;IACD,yBAAyB,EAAE,UAAU,CAAC,EAAE,EAAE,GAAG,CAAC,WAAW,CAAC,WAAW,CAAC;IACtE,qBAAqB,EAAE,UAAU,CAAC,EAAE,EAAE,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC;IACjE,sBAAsB,EAAE,UAAU,CAAC,EAAE,EAAE,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC;IACnE,gBAAgB,EAAE,UAAU,CAAC,EAAE,EAAE,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;CACxD,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,EAAY,EAAE,EAA2B,EAAE,EAAE;IACtE,MAAM,UAAU,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAA;IAEvD,OAAO,KAAK,EAAE,GAAuB,EAAkC,EAAE;QACvE,MAAM,SAAS,GAAG,UAAU;YAC1B,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,CAAC,UAAU,KAAK,UAAU,CAAC;YACpE,CAAC,CAAC,GAAG,CAAC,IAAI,CAAA;QACZ,MAAM,GAAG,GAAG,SAAS,CAAC,MAAM;YAC1B,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE;iBACR,UAAU,CAAC,QAAQ,CAAC;iBACpB,SAAS,EAAE;iBACX,KAAK,CAAC,KAAK,EAAE,IAAI,EAAE,SAAS,CAAC;iBAC7B,OAAO,EAAE;YACd,CAAC,CAAC,EAAE,CAAA;QACN,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;QAC/B,MAAM,OAAO,GAAa,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;YAC7C,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;YAC1B,MAAM,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;YAClD,MAAM,YAAY,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAA;YAC9D,MAAM,SAAS,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC;gBAC9C,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,YAAY,CAAC;gBAClC,CAAC,CAAC,SAAS,CAAA;YACb,MAAM,SAAS,GAAG,GAAG,EAAE,SAAS;gBAC9B,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;gBAC9C,CAAC,CAAC,SAAS,CAAA;YACb,MAAM,WAAW,GAAG,GAAG,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;YAChD,OAAO,IAAI,MAAM,CAAC;gBAChB,MAAM,EAAE,WAAsC;gBAC9C,GAAG,EAAE,GAAG,EAAE,GAAG;gBACb,SAAS;gBACT,SAAS;gBACT,QAAQ,EAAE,aAAa,CAAC,SAAS,EAAE,SAAS,CAAC;gBAC7C,SAAS,EAAE,CAAC,CAAC,GAAG,EAAE,WAAW;gBAC7B,WAAW,EAAE,GAAG,EAAE,WAAW,IAAI,SAAS;gBAC1C,IAAI,EAAE,GAAG,EAAE,IAAI,IAAI,SAAS;aAC7B,CAAC,CAAA;QACJ,CAAC,CAAC,CAAA;QACF,OAAO,EAAE,OAAO,EAAE,CAAA;IACpB,CAAC,CAAA;AACH,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,EAAY,EAAE,EAAE;IAC7C,MAAM,cAAc,GAAG,UAAU,CAAC,EAAE,EAAE,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACzD,OAAO,KAAK,EAAE,GAEb,EAA0D,EAAE;QAC3D,MAAM,CAAC,EAAE,OAAO,EAAE,EAAE,OAAO,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;YAC/C,cAAc,CAAC,GAAG,CAAC;YACnB,GAAG,CAAC,IAAI,CAAC,MAAM;gBACb,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE;qBACR,UAAU,CAAC,MAAM,CAAC;qBAClB,KAAK,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC;qBAC5B,MAAM,CAAC;oBACN,KAAK;oBACL,oBAAoB;oBACpB,wBAAwB;oBACxB,eAAe;oBACf,aAAa;iBACd,CAAC;qBACD,OAAO,EAAE;gBACd,CAAC,CAAC,EAAE;SACP,CAAC,CAAA;QACF,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,CAAA;QACnC,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;YAChC,OAAO,IAAI,cAAc,CAAC;gBACxB,kBAAkB,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,kBAAkB;gBACxD,sBAAsB,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,sBAAsB;gBAChE,aAAa,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,aAAa;gBAC9C,WAAW,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,WAAW;aAC3C,CAAC,CAAA;QACJ,CAAC,CAAC,CAAA;QACF,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAA;IAC1B,CAAC,CAAA;AACH,CAAC,CAAA;AAED,MAAM,aAAa,GAAG,CACpB,GAA0B,EAC1B,GAA0B,EAC1B,EAAE;IACF,IAAI,CAAC,GAAG;QAAE,OAAO,GAAG,CAAA;IACpB,IAAI,CAAC,GAAG;QAAE,OAAO,GAAG,CAAA;IACpB,OAAO,GAAG,CAAC,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAA;AAChD,CAAC,CAAA","sourcesContent":["import { Timestamp } from '@bufbuild/protobuf'\nimport type { ServiceImpl } from '@connectrpc/connect'\nimport * as ui8 from 'uint8arrays'\nimport { keyBy } from '@atproto/common'\nimport { l } from '@atproto/lex'\nimport { AtUri } from '@atproto/syntax'\nimport { app, chat, com } from '../../../lexicons/index.js'\nimport type { Service } from '../../../proto/bsky_connect.js'\nimport { PostRecordMeta, Record } from '../../../proto/bsky_pb.js'\nimport type { Database } from '../db/index.js'\n\nexport default (db: Database): Partial<ServiceImpl<typeof Service>> => ({\n getBlockRecords: getRecords(db, app.bsky.graph.block),\n getFeedGeneratorRecords: getRecords(db, app.bsky.feed.generator),\n getFollowRecords: getRecords(db, app.bsky.graph.follow),\n getLikeRecords: getRecords(db, app.bsky.feed.like),\n getListBlockRecords: getRecords(db, app.bsky.graph.listblock),\n getListItemRecords: getRecords(db, app.bsky.graph.listitem),\n getListRecords: getRecords(db, app.bsky.graph.list),\n getPostRecords: getPostRecords(db),\n getProfileRecords: getRecords(db, app.bsky.actor.profile),\n getRepostRecords: getRecords(db, app.bsky.feed.repost),\n getThreadGateRecords: getRecords(db, app.bsky.feed.threadgate),\n getPostgateRecords: getRecords(db, app.bsky.feed.postgate),\n getLabelerRecords: getRecords(db, app.bsky.labeler.service),\n getActorChatDeclarationRecords: getRecords(db, chat.bsky.actor.declaration),\n getNotificationDeclarationRecords: getRecords(\n db,\n app.bsky.notification.declaration,\n ),\n getGermDeclarationRecords: getRecords(db, com.germnetwork.declaration),\n getStarterPackRecords: getRecords(db, app.bsky.graph.starterpack),\n getVerificationRecords: getRecords(db, app.bsky.graph.verification),\n getStatusRecords: getRecords(db, app.bsky.actor.status),\n})\n\nexport const getRecords = (db: Database, ns?: l.Main<l.RecordSchema>) => {\n const collection = ns ? l.getMain(ns).$type : undefined\n\n return async (req: { uris: string[] }): Promise<{ records: Record[] }> => {\n const validUris = collection\n ? req.uris.filter((uri) => new AtUri(uri).collection === collection)\n : req.uris\n const res = validUris.length\n ? await db.db\n .selectFrom('record')\n .selectAll()\n .where('uri', 'in', validUris)\n .execute()\n : []\n const byUri = keyBy(res, 'uri')\n const records: Record[] = req.uris.map((uri) => {\n const row = byUri.get(uri)\n const json = row ? row.json : JSON.stringify(null)\n const createdAtRaw = new Date(JSON.parse(json)?.['createdAt'])\n const createdAt = !isNaN(createdAtRaw.getTime())\n ? Timestamp.fromDate(createdAtRaw)\n : undefined\n const indexedAt = row?.indexedAt\n ? Timestamp.fromDate(new Date(row?.indexedAt))\n : undefined\n const recordBytes = ui8.fromString(json, 'utf8')\n return new Record({\n record: recordBytes as Uint8Array<ArrayBuffer>,\n cid: row?.cid,\n createdAt,\n indexedAt,\n sortedAt: compositeTime(createdAt, indexedAt),\n takenDown: !!row?.takedownRef,\n takedownRef: row?.takedownRef ?? undefined,\n tags: row?.tags ?? undefined,\n })\n })\n return { records }\n }\n}\n\nexport const getPostRecords = (db: Database) => {\n const getBaseRecords = getRecords(db, app.bsky.feed.post)\n return async (req: {\n uris: string[]\n }): Promise<{ records: Record[]; meta: PostRecordMeta[] }> => {\n const [{ records }, details] = await Promise.all([\n getBaseRecords(req),\n req.uris.length\n ? await db.db\n .selectFrom('post')\n .where('uri', 'in', req.uris)\n .select([\n 'uri',\n 'violatesThreadGate',\n 'violatesEmbeddingRules',\n 'hasThreadGate',\n 'hasPostGate',\n ])\n .execute()\n : [],\n ])\n const byKey = keyBy(details, 'uri')\n const meta = req.uris.map((uri) => {\n return new PostRecordMeta({\n violatesThreadGate: !!byKey.get(uri)?.violatesThreadGate,\n violatesEmbeddingRules: !!byKey.get(uri)?.violatesEmbeddingRules,\n hasThreadGate: !!byKey.get(uri)?.hasThreadGate,\n hasPostGate: !!byKey.get(uri)?.hasPostGate,\n })\n })\n return { records, meta }\n }\n}\n\nconst compositeTime = (\n ts1: Timestamp | undefined,\n ts2: Timestamp | undefined,\n) => {\n if (!ts1) return ts2\n if (!ts2) return ts1\n return ts1.toDate() < ts2.toDate() ? ts1 : ts2\n}\n"]}
1
+ {"version":3,"file":"records.js","sourceRoot":"","sources":["../../../../src/data-plane/server/routes/records.ts"],"names":[],"mappings":"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","sourcesContent":["import { Timestamp } from '@bufbuild/protobuf'\nimport type { ServiceImpl } from '@connectrpc/connect'\nimport * as ui8 from 'uint8arrays'\nimport { keyBy } from '@atproto/common'\nimport { l } from '@atproto/lex'\nimport { AtUri } from '@atproto/syntax'\nimport { app, chat, com } from '../../../lexicons/index.js'\nimport { dataplaneLogger } from '../../../logger.js'\nimport type { Service } from '../../../proto/bsky_connect.js'\nimport { OpThread, PostRecordMeta, Record } from '../../../proto/bsky_pb.js'\nimport type { Database } from '../db/index.js'\nimport { resolveCanonicalOpThread } from '../op-thread.js'\n\nexport default (db: Database): Partial<ServiceImpl<typeof Service>> => ({\n getBlockRecords: getRecords(db, app.bsky.graph.block),\n getFeedGeneratorRecords: getRecords(db, app.bsky.feed.generator),\n getFollowRecords: getRecords(db, app.bsky.graph.follow),\n getLikeRecords: getRecords(db, app.bsky.feed.like),\n getListBlockRecords: getRecords(db, app.bsky.graph.listblock),\n getListItemRecords: getRecords(db, app.bsky.graph.listitem),\n getListRecords: getRecords(db, app.bsky.graph.list),\n getPostRecords: getPostRecords(db),\n getProfileRecords: getRecords(db, app.bsky.actor.profile),\n getRepostRecords: getRecords(db, app.bsky.feed.repost),\n getThreadGateRecords: getRecords(db, app.bsky.feed.threadgate),\n getPostgateRecords: getRecords(db, app.bsky.feed.postgate),\n getLabelerRecords: getRecords(db, app.bsky.labeler.service),\n getActorChatDeclarationRecords: getRecords(db, chat.bsky.actor.declaration),\n getNotificationDeclarationRecords: getRecords(\n db,\n app.bsky.notification.declaration,\n ),\n getGermDeclarationRecords: getRecords(db, com.germnetwork.declaration),\n getStarterPackRecords: getRecords(db, app.bsky.graph.starterpack),\n getVerificationRecords: getRecords(db, app.bsky.graph.verification),\n getStatusRecords: getRecords(db, app.bsky.actor.status),\n})\n\nexport const getRecords = (db: Database, ns?: l.Main<l.RecordSchema>) => {\n const collection = ns ? l.getMain(ns).$type : undefined\n\n return async (req: { uris: string[] }): Promise<{ records: Record[] }> => {\n const validUris = collection\n ? req.uris.filter((uri) => new AtUri(uri).collection === collection)\n : req.uris\n const res = validUris.length\n ? await db.db\n .selectFrom('record')\n .selectAll()\n .where('uri', 'in', validUris)\n .execute()\n : []\n const byUri = keyBy(res, 'uri')\n const records: Record[] = req.uris.map((uri) => {\n const row = byUri.get(uri)\n const json = row ? row.json : JSON.stringify(null)\n const createdAtRaw = new Date(JSON.parse(json)?.['createdAt'])\n const createdAt = !isNaN(createdAtRaw.getTime())\n ? Timestamp.fromDate(createdAtRaw)\n : undefined\n const indexedAt = row?.indexedAt\n ? Timestamp.fromDate(new Date(row?.indexedAt))\n : undefined\n const recordBytes = ui8.fromString(json, 'utf8')\n return new Record({\n record: recordBytes as Uint8Array<ArrayBuffer>,\n cid: row?.cid,\n createdAt,\n indexedAt,\n sortedAt: compositeTime(createdAt, indexedAt),\n takenDown: !!row?.takedownRef,\n takedownRef: row?.takedownRef ?? undefined,\n tags: row?.tags ?? undefined,\n })\n })\n return { records }\n }\n}\n\nexport const getPostRecords = (db: Database) => {\n const getBaseRecords = getRecords(db, app.bsky.feed.post)\n return async (req: {\n uris: string[]\n includeOpThreadMetadata?: boolean\n }): Promise<{\n records: Record[]\n meta: PostRecordMeta[]\n opThreads: OpThread[]\n }> => {\n const [{ records }, details, opThreads] = await Promise.all([\n getBaseRecords(req),\n req.uris.length\n ? db.db\n .selectFrom('post')\n .where('uri', 'in', req.uris)\n .select([\n 'uri',\n 'violatesThreadGate',\n 'violatesEmbeddingRules',\n 'hasThreadGate',\n 'hasPostGate',\n ])\n .execute()\n : [],\n req.includeOpThreadMetadata ? getOpThreads(db, req.uris) : [],\n ])\n const byKey = keyBy(details, 'uri')\n const meta = req.uris.map((uri) => {\n return new PostRecordMeta({\n violatesThreadGate: !!byKey.get(uri)?.violatesThreadGate,\n violatesEmbeddingRules: !!byKey.get(uri)?.violatesEmbeddingRules,\n hasThreadGate: !!byKey.get(uri)?.hasThreadGate,\n hasPostGate: !!byKey.get(uri)?.hasPostGate,\n })\n })\n return { records, meta, opThreads }\n }\n}\n\nconst getOpThreads = async (\n db: Database,\n uris: string[],\n): Promise<OpThread[]> => {\n if (!uris.length) return []\n\n const requestedRoots = db.db\n .selectFrom('post')\n .where('uri', 'in', uris)\n .select((eb) => eb.fn.coalesce('replyRoot', 'uri').as('rootUri'))\n .distinct()\n\n const rows = await db.db\n .selectFrom('op_thread_reply')\n .innerJoin(\n requestedRoots.as('requested_root'),\n 'requested_root.rootUri',\n 'op_thread_reply.rootUri',\n )\n .select([\n 'op_thread_reply.rootUri',\n 'op_thread_reply.uri',\n 'op_thread_reply.parentUri',\n 'op_thread_reply.deletedAt',\n ])\n .execute()\n\n const repliesByRoot = new Map<\n string,\n { uri: string; parentUri: string; deletedAt: string | null }[]\n >()\n for (const row of rows) {\n const replies = repliesByRoot.get(row.rootUri) ?? []\n replies.push(row)\n repliesByRoot.set(row.rootUri, replies)\n }\n\n const opThreads: OpThread[] = []\n for (const [rootUri, replies] of repliesByRoot) {\n const opThread = resolveCanonicalOpThread(rootUri, replies)\n if (!opThread) continue\n\n opThreads.push(new OpThread({ rootUri, uris: opThread }))\n }\n\n dataplaneLogger.debug(\n { uris: uris.length, roots: repliesByRoot.size, rows: rows.length },\n 'op threads resolved',\n )\n\n return opThreads\n}\n\nconst compositeTime = (\n ts1: Timestamp | undefined,\n ts2: Timestamp | undefined,\n) => {\n if (!ts1) return ts2\n if (!ts2) return ts1\n return ts1.toDate() < ts2.toDate() ? ts1 : ts2\n}\n"]}
@@ -14,10 +14,10 @@ export default (db) => ({
14
14
  cursor,
15
15
  keyset,
16
16
  });
17
- const reposts = await builder.execute();
17
+ const page = keyset.page(await builder.execute(), limit);
18
18
  return {
19
- uris: reposts.map((l) => l.uri),
20
- cursor: keyset.packFromResult(reposts),
19
+ uris: page.items.map((l) => l.uri),
20
+ cursor: page.cursor,
21
21
  };
22
22
  },
23
23
  async getRepostsByActorAndSubjects(req) {
@@ -48,10 +48,10 @@ export default (db) => ({
48
48
  cursor,
49
49
  keyset,
50
50
  });
51
- const reposts = await builder.execute();
51
+ const page = keyset.page(await builder.execute(), limit);
52
52
  return {
53
- uris: reposts.map((l) => l.uri),
54
- cursor: keyset.packFromResult(reposts),
53
+ uris: page.items.map((l) => l.uri),
54
+ cursor: page.cursor,
55
55
  };
56
56
  },
57
57
  });
@@ -1 +1 @@
1
- {"version":3,"file":"reposts.js","sourceRoot":"","sources":["../../../../src/data-plane/server/routes/reposts.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ServiceImpl } from '@connectrpc/connect'\nimport { keyBy } from '@atproto/common'\nimport type { Service } from '../../../proto/bsky_connect.js'\nimport type { Database } from '../db/index.js'\nimport { TimeCidKeyset, paginate } from '../db/pagination.js'\n\nexport default (db: Database): Partial<ServiceImpl<typeof Service>> => ({\n async getRepostsBySubject(req) {\n const { subject, cursor, limit } = req\n const { ref } = db.db.dynamic\n\n let builder = db.db\n .selectFrom('repost')\n .where('repost.subject', '=', subject?.uri ?? '')\n .selectAll('repost')\n\n const keyset = new TimeCidKeyset(ref('repost.sortAt'), ref('repost.cid'))\n builder = paginate(builder, {\n limit,\n cursor,\n keyset,\n })\n\n const reposts = await builder.execute()\n\n return {\n uris: reposts.map((l) => l.uri),\n cursor: keyset.packFromResult(reposts),\n }\n },\n\n async getRepostsByActorAndSubjects(req) {\n const { actorDid, refs } = req\n if (refs.length === 0) {\n return { uris: [] }\n }\n const res = await db.db\n .selectFrom('repost')\n .where('creator', '=', actorDid)\n .where(\n 'subject',\n 'in',\n refs.map(({ uri }) => uri),\n )\n .selectAll()\n .execute()\n const bySubject = keyBy(res, 'subject')\n const uris = refs.map(({ uri }) => bySubject.get(uri)?.uri ?? '')\n return { uris }\n },\n\n async getActorReposts(req) {\n const { actorDid, limit, cursor } = req\n const { ref } = db.db.dynamic\n\n let builder = db.db\n .selectFrom('repost')\n .where('repost.creator', '=', actorDid)\n .selectAll()\n\n const keyset = new TimeCidKeyset(ref('repost.sortAt'), ref('repost.cid'))\n\n builder = paginate(builder, {\n limit,\n cursor,\n keyset,\n })\n\n const reposts = await builder.execute()\n\n return {\n uris: reposts.map((l) => l.uri),\n cursor: keyset.packFromResult(reposts),\n }\n },\n})\n"]}
1
+ {"version":3,"file":"reposts.js","sourceRoot":"","sources":["../../../../src/data-plane/server/routes/reposts.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ServiceImpl } from '@connectrpc/connect'\nimport { keyBy } from '@atproto/common'\nimport type { Service } from '../../../proto/bsky_connect.js'\nimport type { Database } from '../db/index.js'\nimport { TimeCidKeyset, paginate } from '../db/pagination.js'\n\nexport default (db: Database): Partial<ServiceImpl<typeof Service>> => ({\n async getRepostsBySubject(req) {\n const { subject, cursor, limit } = req\n const { ref } = db.db.dynamic\n\n let builder = db.db\n .selectFrom('repost')\n .where('repost.subject', '=', subject?.uri ?? '')\n .selectAll('repost')\n\n const keyset = new TimeCidKeyset(ref('repost.sortAt'), ref('repost.cid'))\n builder = paginate(builder, {\n limit,\n cursor,\n keyset,\n })\n\n const page = keyset.page(await builder.execute(), limit)\n\n return {\n uris: page.items.map((l) => l.uri),\n cursor: page.cursor,\n }\n },\n\n async getRepostsByActorAndSubjects(req) {\n const { actorDid, refs } = req\n if (refs.length === 0) {\n return { uris: [] }\n }\n const res = await db.db\n .selectFrom('repost')\n .where('creator', '=', actorDid)\n .where(\n 'subject',\n 'in',\n refs.map(({ uri }) => uri),\n )\n .selectAll()\n .execute()\n const bySubject = keyBy(res, 'subject')\n const uris = refs.map(({ uri }) => bySubject.get(uri)?.uri ?? '')\n return { uris }\n },\n\n async getActorReposts(req) {\n const { actorDid, limit, cursor } = req\n const { ref } = db.db.dynamic\n\n let builder = db.db\n .selectFrom('repost')\n .where('repost.creator', '=', actorDid)\n .selectAll()\n\n const keyset = new TimeCidKeyset(ref('repost.sortAt'), ref('repost.cid'))\n\n builder = paginate(builder, {\n limit,\n cursor,\n keyset,\n })\n\n const page = keyset.page(await builder.execute(), limit)\n\n return {\n uris: page.items.map((l) => l.uri),\n cursor: page.cursor,\n }\n },\n})\n"]}