@atproto/bsky 0.0.243 → 0.0.244

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 (272) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/dist/api/app/bsky/actor/searchActorsTypeahead.js +5 -3
  3. package/dist/api/app/bsky/actor/searchActorsTypeahead.js.map +1 -1
  4. package/dist/api/app/bsky/notification/putPreferencesV2.js +4 -1
  5. package/dist/api/app/bsky/notification/putPreferencesV2.js.map +1 -1
  6. package/dist/api/app/bsky/notification/util.d.ts +1 -0
  7. package/dist/api/app/bsky/notification/util.d.ts.map +1 -1
  8. package/dist/api/app/bsky/notification/util.js +7 -7
  9. package/dist/api/app/bsky/notification/util.js.map +1 -1
  10. package/dist/api/blob-dispatcher.d.ts.map +1 -1
  11. package/dist/api/blob-dispatcher.js +9 -8
  12. package/dist/api/blob-dispatcher.js.map +1 -1
  13. package/dist/api/blob-resolver.d.ts +1 -1
  14. package/dist/api/blob-resolver.d.ts.map +1 -1
  15. package/dist/api/blob-resolver.js +0 -1
  16. package/dist/api/blob-resolver.js.map +1 -1
  17. package/dist/data-plane/bsync/index.d.ts +2 -0
  18. package/dist/data-plane/bsync/index.d.ts.map +1 -1
  19. package/dist/data-plane/bsync/index.js +7 -10
  20. package/dist/data-plane/bsync/index.js.map +1 -1
  21. package/dist/data-plane/server/background.d.ts +12 -8
  22. package/dist/data-plane/server/background.d.ts.map +1 -1
  23. package/dist/data-plane/server/background.js +32 -14
  24. package/dist/data-plane/server/background.js.map +1 -1
  25. package/dist/data-plane/server/index.d.ts +2 -0
  26. package/dist/data-plane/server/index.d.ts.map +1 -1
  27. package/dist/data-plane/server/index.js +7 -10
  28. package/dist/data-plane/server/index.js.map +1 -1
  29. package/dist/data-plane/server/indexing/index.d.ts +2 -2
  30. package/dist/data-plane/server/indexing/index.d.ts.map +1 -1
  31. package/dist/data-plane/server/indexing/index.js.map +1 -1
  32. package/dist/data-plane/server/indexing/plugins/block.d.ts +1 -1
  33. package/dist/data-plane/server/indexing/plugins/block.d.ts.map +1 -1
  34. package/dist/data-plane/server/indexing/plugins/block.js.map +1 -1
  35. package/dist/data-plane/server/indexing/plugins/chat-declaration.d.ts +1 -1
  36. package/dist/data-plane/server/indexing/plugins/chat-declaration.d.ts.map +1 -1
  37. package/dist/data-plane/server/indexing/plugins/chat-declaration.js.map +1 -1
  38. package/dist/data-plane/server/indexing/plugins/feed-generator.d.ts +1 -1
  39. package/dist/data-plane/server/indexing/plugins/feed-generator.d.ts.map +1 -1
  40. package/dist/data-plane/server/indexing/plugins/feed-generator.js.map +1 -1
  41. package/dist/data-plane/server/indexing/plugins/follow.d.ts +1 -1
  42. package/dist/data-plane/server/indexing/plugins/follow.d.ts.map +1 -1
  43. package/dist/data-plane/server/indexing/plugins/follow.js.map +1 -1
  44. package/dist/data-plane/server/indexing/plugins/germ-declaration.d.ts +1 -1
  45. package/dist/data-plane/server/indexing/plugins/germ-declaration.d.ts.map +1 -1
  46. package/dist/data-plane/server/indexing/plugins/germ-declaration.js.map +1 -1
  47. package/dist/data-plane/server/indexing/plugins/labeler.d.ts +1 -1
  48. package/dist/data-plane/server/indexing/plugins/labeler.d.ts.map +1 -1
  49. package/dist/data-plane/server/indexing/plugins/labeler.js.map +1 -1
  50. package/dist/data-plane/server/indexing/plugins/like.d.ts +1 -1
  51. package/dist/data-plane/server/indexing/plugins/like.d.ts.map +1 -1
  52. package/dist/data-plane/server/indexing/plugins/like.js.map +1 -1
  53. package/dist/data-plane/server/indexing/plugins/list-block.d.ts +1 -1
  54. package/dist/data-plane/server/indexing/plugins/list-block.d.ts.map +1 -1
  55. package/dist/data-plane/server/indexing/plugins/list-block.js.map +1 -1
  56. package/dist/data-plane/server/indexing/plugins/list-item.d.ts +1 -1
  57. package/dist/data-plane/server/indexing/plugins/list-item.d.ts.map +1 -1
  58. package/dist/data-plane/server/indexing/plugins/list-item.js.map +1 -1
  59. package/dist/data-plane/server/indexing/plugins/list.d.ts +1 -1
  60. package/dist/data-plane/server/indexing/plugins/list.d.ts.map +1 -1
  61. package/dist/data-plane/server/indexing/plugins/list.js.map +1 -1
  62. package/dist/data-plane/server/indexing/plugins/notif-declaration.d.ts +1 -1
  63. package/dist/data-plane/server/indexing/plugins/notif-declaration.d.ts.map +1 -1
  64. package/dist/data-plane/server/indexing/plugins/notif-declaration.js.map +1 -1
  65. package/dist/data-plane/server/indexing/plugins/post-gate.d.ts +1 -1
  66. package/dist/data-plane/server/indexing/plugins/post-gate.d.ts.map +1 -1
  67. package/dist/data-plane/server/indexing/plugins/post-gate.js.map +1 -1
  68. package/dist/data-plane/server/indexing/plugins/post.d.ts +1 -1
  69. package/dist/data-plane/server/indexing/plugins/post.d.ts.map +1 -1
  70. package/dist/data-plane/server/indexing/plugins/post.js.map +1 -1
  71. package/dist/data-plane/server/indexing/plugins/profile.d.ts +1 -1
  72. package/dist/data-plane/server/indexing/plugins/profile.d.ts.map +1 -1
  73. package/dist/data-plane/server/indexing/plugins/profile.js.map +1 -1
  74. package/dist/data-plane/server/indexing/plugins/repost.d.ts +1 -1
  75. package/dist/data-plane/server/indexing/plugins/repost.d.ts.map +1 -1
  76. package/dist/data-plane/server/indexing/plugins/repost.js.map +1 -1
  77. package/dist/data-plane/server/indexing/plugins/starter-pack.d.ts +1 -1
  78. package/dist/data-plane/server/indexing/plugins/starter-pack.d.ts.map +1 -1
  79. package/dist/data-plane/server/indexing/plugins/starter-pack.js.map +1 -1
  80. package/dist/data-plane/server/indexing/plugins/status.d.ts +1 -1
  81. package/dist/data-plane/server/indexing/plugins/status.d.ts.map +1 -1
  82. package/dist/data-plane/server/indexing/plugins/status.js.map +1 -1
  83. package/dist/data-plane/server/indexing/plugins/thread-gate.d.ts +1 -1
  84. package/dist/data-plane/server/indexing/plugins/thread-gate.d.ts.map +1 -1
  85. package/dist/data-plane/server/indexing/plugins/thread-gate.js.map +1 -1
  86. package/dist/data-plane/server/indexing/plugins/verification.d.ts +1 -1
  87. package/dist/data-plane/server/indexing/plugins/verification.d.ts.map +1 -1
  88. package/dist/data-plane/server/indexing/plugins/verification.js.map +1 -1
  89. package/dist/data-plane/server/indexing/processor.d.ts +1 -1
  90. package/dist/data-plane/server/indexing/processor.d.ts.map +1 -1
  91. package/dist/data-plane/server/indexing/processor.js.map +1 -1
  92. package/dist/data-plane/server/routes/notifs.d.ts.map +1 -1
  93. package/dist/data-plane/server/routes/notifs.js +1 -8
  94. package/dist/data-plane/server/routes/notifs.js.map +1 -1
  95. package/dist/data-plane/server/routes/search.js +2 -2
  96. package/dist/data-plane/server/routes/search.js.map +1 -1
  97. package/dist/data-plane/server/subscription.d.ts +13 -12
  98. package/dist/data-plane/server/subscription.d.ts.map +1 -1
  99. package/dist/data-plane/server/subscription.js +59 -26
  100. package/dist/data-plane/server/subscription.js.map +1 -1
  101. package/dist/feature-gates/index.d.ts +2 -1
  102. package/dist/feature-gates/index.d.ts.map +1 -1
  103. package/dist/feature-gates/index.js +9 -6
  104. package/dist/feature-gates/index.js.map +1 -1
  105. package/dist/feature-gates/metrics.d.ts +3 -3
  106. package/dist/feature-gates/metrics.d.ts.map +1 -1
  107. package/dist/feature-gates/metrics.js +8 -8
  108. package/dist/feature-gates/metrics.js.map +1 -1
  109. package/dist/index.d.ts +1 -0
  110. package/dist/index.d.ts.map +1 -1
  111. package/dist/index.js +16 -7
  112. package/dist/index.js.map +1 -1
  113. package/dist/lexicons/app/bsky/notification/defs.defs.d.ts +5 -0
  114. package/dist/lexicons/app/bsky/notification/defs.defs.d.ts.map +1 -1
  115. package/dist/lexicons/app/bsky/notification/defs.defs.js +1 -0
  116. package/dist/lexicons/app/bsky/notification/defs.defs.js.map +1 -1
  117. package/dist/lexicons/chat/bsky/notification/defs.d.ts +2 -0
  118. package/dist/lexicons/chat/bsky/notification/defs.d.ts.map +1 -0
  119. package/dist/lexicons/chat/bsky/notification/defs.defs.d.ts +20 -0
  120. package/dist/lexicons/chat/bsky/notification/defs.defs.d.ts.map +1 -0
  121. package/dist/lexicons/chat/bsky/notification/defs.defs.js +19 -0
  122. package/dist/lexicons/chat/bsky/notification/defs.defs.js.map +1 -0
  123. package/dist/lexicons/chat/bsky/notification/defs.js +5 -0
  124. package/dist/lexicons/chat/bsky/notification/defs.js.map +1 -0
  125. package/dist/lexicons/chat/bsky/notification/getPreferences.d.ts +3 -0
  126. package/dist/lexicons/chat/bsky/notification/getPreferences.d.ts.map +1 -0
  127. package/dist/lexicons/chat/bsky/notification/getPreferences.defs.d.ts +18 -0
  128. package/dist/lexicons/chat/bsky/notification/getPreferences.defs.d.ts.map +1 -0
  129. package/dist/lexicons/chat/bsky/notification/getPreferences.defs.js +16 -0
  130. package/dist/lexicons/chat/bsky/notification/getPreferences.defs.js.map +1 -0
  131. package/dist/lexicons/chat/bsky/notification/getPreferences.js +6 -0
  132. package/dist/lexicons/chat/bsky/notification/getPreferences.js.map +1 -0
  133. package/dist/lexicons/chat/bsky/notification/putPreferences.d.ts +3 -0
  134. package/dist/lexicons/chat/bsky/notification/putPreferences.d.ts.map +1 -0
  135. package/dist/lexicons/chat/bsky/notification/putPreferences.defs.d.ts +27 -0
  136. package/dist/lexicons/chat/bsky/notification/putPreferences.defs.d.ts.map +1 -0
  137. package/dist/lexicons/chat/bsky/notification/putPreferences.defs.js +22 -0
  138. package/dist/lexicons/chat/bsky/notification/putPreferences.defs.js.map +1 -0
  139. package/dist/lexicons/chat/bsky/notification/putPreferences.js +6 -0
  140. package/dist/lexicons/chat/bsky/notification/putPreferences.js.map +1 -0
  141. package/dist/lexicons/chat/bsky/notification.d.ts +4 -0
  142. package/dist/lexicons/chat/bsky/notification.d.ts.map +1 -0
  143. package/dist/lexicons/chat/bsky/notification.js +7 -0
  144. package/dist/lexicons/chat/bsky/notification.js.map +1 -0
  145. package/dist/lexicons/chat/bsky.d.ts +1 -0
  146. package/dist/lexicons/chat/bsky.d.ts.map +1 -1
  147. package/dist/lexicons/chat/bsky.js +1 -0
  148. package/dist/lexicons/chat/bsky.js.map +1 -1
  149. package/dist/lexicons/tools/ozone/report/defs.defs.d.ts +4 -0
  150. package/dist/lexicons/tools/ozone/report/defs.defs.d.ts.map +1 -1
  151. package/dist/lexicons/tools/ozone/report/defs.defs.js +2 -0
  152. package/dist/lexicons/tools/ozone/report/defs.defs.js.map +1 -1
  153. package/dist/lexicons/tools/ozone/report/queryActivities.d.ts +3 -0
  154. package/dist/lexicons/tools/ozone/report/queryActivities.d.ts.map +1 -0
  155. package/dist/lexicons/tools/ozone/report/queryActivities.defs.d.ts +42 -0
  156. package/dist/lexicons/tools/ozone/report/queryActivities.defs.d.ts.map +1 -0
  157. package/dist/lexicons/tools/ozone/report/queryActivities.defs.js +31 -0
  158. package/dist/lexicons/tools/ozone/report/queryActivities.defs.js.map +1 -0
  159. package/dist/lexicons/tools/ozone/report/queryActivities.js +6 -0
  160. package/dist/lexicons/tools/ozone/report/queryActivities.js.map +1 -0
  161. package/dist/lexicons/tools/ozone/report.d.ts +1 -0
  162. package/dist/lexicons/tools/ozone/report.d.ts.map +1 -1
  163. package/dist/lexicons/tools/ozone/report.js +1 -0
  164. package/dist/lexicons/tools/ozone/report.js.map +1 -1
  165. package/dist/proto/bsky_pb.d.ts +47 -53
  166. package/dist/proto/bsky_pb.d.ts.map +1 -1
  167. package/dist/proto/bsky_pb.js +62 -71
  168. package/dist/proto/bsky_pb.js.map +1 -1
  169. package/package.json +10 -10
  170. package/proto/bsky.proto +19 -17
  171. package/src/api/app/bsky/actor/searchActorsTypeahead.ts +5 -3
  172. package/src/api/app/bsky/notification/putPreferencesV2.ts +4 -1
  173. package/src/api/app/bsky/notification/util.ts +7 -11
  174. package/src/api/blob-dispatcher.ts +12 -8
  175. package/src/api/blob-resolver.ts +0 -1
  176. package/src/data-plane/bsync/index.ts +12 -10
  177. package/src/data-plane/server/background.ts +49 -18
  178. package/src/data-plane/server/index.ts +12 -10
  179. package/src/data-plane/server/indexing/index.ts +1 -1
  180. package/src/data-plane/server/indexing/plugins/block.ts +4 -1
  181. package/src/data-plane/server/indexing/plugins/chat-declaration.ts +4 -1
  182. package/src/data-plane/server/indexing/plugins/feed-generator.ts +4 -1
  183. package/src/data-plane/server/indexing/plugins/follow.ts +4 -1
  184. package/src/data-plane/server/indexing/plugins/germ-declaration.ts +4 -1
  185. package/src/data-plane/server/indexing/plugins/labeler.ts +4 -1
  186. package/src/data-plane/server/indexing/plugins/like.ts +4 -1
  187. package/src/data-plane/server/indexing/plugins/list-block.ts +4 -1
  188. package/src/data-plane/server/indexing/plugins/list-item.ts +4 -1
  189. package/src/data-plane/server/indexing/plugins/list.ts +4 -1
  190. package/src/data-plane/server/indexing/plugins/notif-declaration.ts +4 -1
  191. package/src/data-plane/server/indexing/plugins/post-gate.ts +4 -1
  192. package/src/data-plane/server/indexing/plugins/post.ts +4 -1
  193. package/src/data-plane/server/indexing/plugins/profile.ts +4 -1
  194. package/src/data-plane/server/indexing/plugins/repost.ts +4 -1
  195. package/src/data-plane/server/indexing/plugins/starter-pack.ts +4 -1
  196. package/src/data-plane/server/indexing/plugins/status.ts +4 -1
  197. package/src/data-plane/server/indexing/plugins/thread-gate.ts +4 -1
  198. package/src/data-plane/server/indexing/plugins/verification.ts +4 -1
  199. package/src/data-plane/server/indexing/processor.ts +1 -1
  200. package/src/data-plane/server/routes/notifs.ts +0 -14
  201. package/src/data-plane/server/routes/search.ts +2 -2
  202. package/src/data-plane/server/subscription.ts +74 -31
  203. package/src/feature-gates/index.ts +10 -6
  204. package/src/feature-gates/metrics.test.ts +12 -12
  205. package/src/feature-gates/metrics.ts +8 -8
  206. package/src/index.ts +16 -9
  207. package/tests/_util.ts +8 -25
  208. package/tests/admin/admin-auth.test.ts +2 -2
  209. package/tests/admin/moderation.test.ts +1 -1
  210. package/tests/auth.test.ts +4 -6
  211. package/tests/blob-resolver.test.ts +4 -5
  212. package/tests/data-plane/db.test.ts +1 -1
  213. package/tests/data-plane/duplicate-records.test.ts +1 -1
  214. package/tests/data-plane/handle-invalidation.test.ts +2 -2
  215. package/tests/data-plane/indexing.test.ts +24 -21
  216. package/tests/data-plane/subscription.test.ts +1 -1
  217. package/tests/data-plane/thread-mutes.test.ts +2 -2
  218. package/tests/entryway-auth.test.ts +4 -5
  219. package/tests/feed-generation.test.ts +5 -5
  220. package/tests/image/server.test.ts +1 -1
  221. package/tests/label-hydration.test.ts +3 -5
  222. package/tests/postgates.test.ts +3 -6
  223. package/tests/query-labels.test.ts +3 -5
  224. package/tests/redis-cache.test.ts +1 -3
  225. package/tests/server.test.ts +11 -16
  226. package/tests/sitemap.test.ts +3 -4
  227. package/tests/stash.test.ts +12 -8
  228. package/tests/utils.test.ts +3 -13
  229. package/tests/views/account-deactivation.test.ts +3 -5
  230. package/tests/views/actor-likes.test.ts +3 -5
  231. package/tests/views/actor-search.test.ts +6 -7
  232. package/tests/views/age-assurance-v2.test.ts +9 -6
  233. package/tests/views/age-assurance.test.ts +30 -36
  234. package/tests/views/author-feed.test.ts +4 -6
  235. package/tests/views/block-lists.test.ts +3 -5
  236. package/tests/views/blocks.test.ts +3 -5
  237. package/tests/views/bookmarks.test.ts +4 -4
  238. package/tests/views/drafts.test.ts +7 -14
  239. package/tests/views/feed-hidden-replies.test.ts +3 -6
  240. package/tests/views/feed-view-post.test.ts +3 -6
  241. package/tests/views/follows.test.ts +4 -6
  242. package/tests/views/get-config.test.ts +4 -7
  243. package/tests/views/get-suggested-onboarding-users.test.ts +11 -9
  244. package/tests/views/get-suggested-starter-packs.test.ts +11 -9
  245. package/tests/views/get-trends.test.ts +15 -9
  246. package/tests/views/internal-actor.test.ts +3 -6
  247. package/tests/views/known-followers.test.ts +3 -6
  248. package/tests/views/labeler-service.test.ts +3 -5
  249. package/tests/views/labels-needs-review.test.ts +3 -6
  250. package/tests/views/labels-takedown.test.ts +3 -4
  251. package/tests/views/likes.test.ts +4 -6
  252. package/tests/views/list-feed.test.ts +3 -5
  253. package/tests/views/lists.test.ts +3 -5
  254. package/tests/views/mute-lists.test.ts +3 -5
  255. package/tests/views/mutes.test.ts +4 -5
  256. package/tests/views/notifications.test.ts +12 -11
  257. package/tests/views/post-search.test.ts +3 -24
  258. package/tests/views/posts-debug.test.ts +11 -6
  259. package/tests/views/posts.test.ts +3 -4
  260. package/tests/views/profile-debug.test.ts +11 -5
  261. package/tests/views/profile.test.ts +11 -5
  262. package/tests/views/quotes.test.ts +4 -6
  263. package/tests/views/reposts.test.ts +4 -6
  264. package/tests/views/starter-packs.test.ts +3 -6
  265. package/tests/views/suggestions.test.ts +9 -13
  266. package/tests/views/thread-v2.test.ts +3 -5
  267. package/tests/views/thread.test.ts +3 -7
  268. package/tests/views/threadgating.test.ts +3 -5
  269. package/tests/views/timeline.test.ts +4 -5
  270. package/tests/views/verification.test.ts +4 -6
  271. package/tsconfig.build.tsbuildinfo +1 -1
  272. package/vitest.config.ts +1 -0
@@ -1,5 +1,5 @@
1
1
  import { sql } from 'kysely'
2
- import { afterAll, beforeAll, describe, expect, it } from 'vitest'
2
+ import { afterAll, beforeAll, beforeEach, describe, expect, it } from 'vitest'
3
3
  import {
4
4
  AppBskyActorProfile,
5
5
  AppBskyFeedLike,
@@ -16,6 +16,7 @@ import { repoPrepare } from '@atproto/pds'
16
16
  import { WriteOpAction } from '@atproto/repo'
17
17
  import { AtUri } from '@atproto/syntax'
18
18
  import { Database } from '../../src/data-plane/server/db/index.js'
19
+ import { IndexingService } from '../../src/data-plane/server/indexing/index.js'
19
20
  import { forSnapshot } from '../_util.js'
20
21
 
21
22
  describe('indexing', () => {
@@ -34,18 +35,19 @@ describe('indexing', () => {
34
35
  sc = network.getSeedClient()
35
36
  db = network.bsky.db
36
37
  await usersSeed(sc)
37
- // Data in tests is not processed from subscription
38
38
  await network.processAll()
39
- await network.bsky.sub.destroy()
40
- }, 20_000) // @NOTE seeding can take a while
41
39
 
42
- afterAll(async () => {
43
- await network.close()
40
+ // Data in tests is not processed from subscription, instead we call
41
+ // indexing service methods directly.
42
+ await network.bsky.sub.stop()
44
43
  })
45
44
 
45
+ beforeEach(async () => network.processAll())
46
+ afterAll(async () => network?.close())
47
+
46
48
  it('indexes posts.', async () => {
47
49
  const createdAt = new Date().toISOString()
48
- const createRecord = await prepareCreate({
50
+ const createRecord = await prepareCreate<AppBskyFeedPost.Record>({
49
51
  did: sc.dids.alice,
50
52
  collection: ids.AppBskyFeedPost,
51
53
  record: {
@@ -63,10 +65,10 @@ describe('indexing', () => {
63
65
  },
64
66
  ],
65
67
  createdAt,
66
- } satisfies AppBskyFeedPost.Record,
68
+ },
67
69
  })
68
70
  const [uri] = createRecord
69
- const updateRecord = await prepareUpdate({
71
+ const updateRecord = await prepareUpdate<AppBskyFeedPost.Record>({
70
72
  did: sc.dids.alice,
71
73
  collection: ids.AppBskyFeedPost,
72
74
  rkey: uri.rkey,
@@ -85,7 +87,7 @@ describe('indexing', () => {
85
87
  },
86
88
  ],
87
89
  createdAt,
88
- } satisfies AppBskyFeedPost.Record,
90
+ },
89
91
  })
90
92
  const deleteRecord = prepareDelete({
91
93
  did: sc.dids.alice,
@@ -434,8 +436,7 @@ describe('indexing', () => {
434
436
  await network.bsky.sub.restart()
435
437
  await basicSeed(sc, false)
436
438
  await network.processAll()
437
- await network.bsky.sub.destroy()
438
- await network.bsky.sub.background.processAll()
439
+ await network.bsky.sub.stop()
439
440
  })
440
441
 
441
442
  it('preserves indexes when no record changes.', async () => {
@@ -782,13 +783,13 @@ describe('indexing', () => {
782
783
  }
783
784
  })
784
785
 
785
- async function prepareCreate(opts: {
786
+ async function prepareCreate<TRecord>(opts: {
786
787
  did: string
787
788
  collection: string
788
789
  rkey?: string
789
- record: unknown
790
+ record: TRecord
790
791
  timestamp?: string
791
- }): Promise<[AtUri, Cid, unknown, WriteOpAction.Create, string]> {
792
+ }): Promise<[AtUri, Cid, TRecord, WriteOpAction.Create, string]> {
792
793
  const rkey = opts.rkey ?? TID.nextStr()
793
794
  return [
794
795
  AtUri.make(opts.did, opts.collection, rkey),
@@ -796,23 +797,23 @@ async function prepareCreate(opts: {
796
797
  opts.record,
797
798
  WriteOpAction.Create,
798
799
  opts.timestamp ?? new Date().toISOString(),
799
- ]
800
+ ] satisfies Parameters<IndexingService['indexRecord']>
800
801
  }
801
802
 
802
- async function prepareUpdate(opts: {
803
+ async function prepareUpdate<TRecord>(opts: {
803
804
  did: string
804
805
  collection: string
805
806
  rkey: string
806
- record: unknown
807
+ record: TRecord
807
808
  timestamp?: string
808
- }): Promise<[AtUri, Cid, unknown, WriteOpAction.Update, string]> {
809
+ }): Promise<[AtUri, Cid, TRecord, WriteOpAction.Update, string]> {
809
810
  return [
810
811
  AtUri.make(opts.did, opts.collection, opts.rkey),
811
812
  await cidForCbor(opts.record),
812
813
  opts.record,
813
814
  WriteOpAction.Update,
814
815
  opts.timestamp ?? new Date().toISOString(),
815
- ]
816
+ ] satisfies Parameters<IndexingService['indexRecord']>
816
817
  }
817
818
 
818
819
  function prepareDelete(opts: {
@@ -820,5 +821,7 @@ function prepareDelete(opts: {
820
821
  collection: string
821
822
  rkey: string
822
823
  }): [AtUri] {
823
- return [AtUri.make(opts.did, opts.collection, opts.rkey)]
824
+ return [
825
+ AtUri.make(opts.did, opts.collection, opts.rkey),
826
+ ] satisfies Parameters<IndexingService['deleteRecord']>
824
827
  }
@@ -23,7 +23,7 @@ describe('sync', () => {
23
23
  })
24
24
 
25
25
  afterAll(async () => {
26
- await network.close()
26
+ await network?.close()
27
27
  })
28
28
 
29
29
  it('indexes permit history being replayed.', async () => {
@@ -25,10 +25,10 @@ describe('thread mutes', () => {
25
25
  rootPost = (await sc.post(alice, 'root post')).ref
26
26
  replyPost = (await sc.reply(alice, rootPost, rootPost, 'first reply')).ref
27
27
  await network.processAll()
28
- }, 20_000) // @NOTE seeding can take a while
28
+ })
29
29
 
30
30
  afterAll(async () => {
31
- await network.close()
31
+ await network?.close()
32
32
  })
33
33
 
34
34
  it('mutes threads', async () => {
@@ -3,7 +3,7 @@ import * as nodeCrypto from 'node:crypto'
3
3
  import * as jose from 'jose'
4
4
  import KeyEncoderModule from 'key-encoder'
5
5
  import * as ui8 from 'uint8arrays'
6
- import { afterAll, beforeAll, describe, expect, it } from 'vitest'
6
+ import { afterAll, beforeAll, beforeEach, describe, expect, it } from 'vitest'
7
7
  import { AtUri, AtpAgent } from '@atproto/api'
8
8
  import { MINUTE } from '@atproto/common'
9
9
  import * as crypto from '@atproto/crypto'
@@ -51,13 +51,12 @@ describe('entryway auth', () => {
51
51
  agent = network.bsky.getAgent()
52
52
  sc = network.getSeedClient()
53
53
  await basicSeed(sc)
54
- await network.processAll()
54
+
55
55
  alice = sc.dids.alice
56
56
  })
57
57
 
58
- afterAll(async () => {
59
- await network.close()
60
- })
58
+ beforeEach(async () => network.processAll())
59
+ afterAll(async () => network?.close())
61
60
 
62
61
  it('works', async () => {
63
62
  const signer = new jose.SignJWT({ scope: 'com.atproto.access' })
@@ -1,5 +1,5 @@
1
1
  import assert from 'node:assert'
2
- import { afterAll, beforeAll, describe, expect, it } from 'vitest'
2
+ import { afterAll, beforeAll, beforeEach, describe, expect, it } from 'vitest'
3
3
  import {
4
4
  AppBskyFeedDefs,
5
5
  AppBskyFeedGetActorFeeds,
@@ -46,6 +46,7 @@ describe('feed generation', () => {
46
46
  network = await TestNetwork.create({
47
47
  dbPostgresSchema: 'bsky_feed_generation',
48
48
  })
49
+
49
50
  agent = network.bsky.getAgent()
50
51
  pdsAgent = network.pds.getAgent()
51
52
  sc = network.getSeedClient()
@@ -103,10 +104,9 @@ describe('feed generation', () => {
103
104
  .execute()
104
105
  })
105
106
 
106
- afterAll(async () => {
107
- await gen.close()
108
- await network.close()
109
- })
107
+ beforeEach(async () => network.processAll())
108
+ afterAll(async () => network?.close())
109
+ afterAll(async () => gen?.close())
110
110
 
111
111
  it('feed gen records can be created.', async () => {
112
112
  const all = await pdsAgent.api.app.bsky.feed.generator.create(
@@ -23,7 +23,7 @@ describe('image processing server', () => {
23
23
  })
24
24
 
25
25
  afterAll(async () => {
26
- await network.close()
26
+ await network?.close()
27
27
  })
28
28
 
29
29
  it('processes image from blob resolver.', async () => {
@@ -1,5 +1,5 @@
1
1
  import assert from 'node:assert'
2
- import { afterAll, beforeAll, describe, expect, it } from 'vitest'
2
+ import { afterAll, beforeAll, beforeEach, describe, expect, it } from 'vitest'
3
3
  import { AtpAgent } from '@atproto/api'
4
4
  import { MINUTE } from '@atproto/common'
5
5
  import { SeedClient, TestNetwork, basicSeed } from '@atproto/dev-env'
@@ -49,12 +49,10 @@ describe('label hydration', () => {
49
49
  val: 'not-expired',
50
50
  exp: new Date(Date.now() + MINUTE).toISOString(),
51
51
  })
52
- await network.processAll()
53
52
  })
54
53
 
55
- afterAll(async () => {
56
- await network.close()
57
- })
54
+ beforeEach(async () => network.processAll())
55
+ afterAll(async () => network?.close())
58
56
 
59
57
  it('hydrates labels based on a supplied labeler header', async () => {
60
58
  AtpAgent.configure({ appLabelers: [alice] })
@@ -1,4 +1,4 @@
1
- import { afterAll, beforeAll, describe, expect, it } from 'vitest'
1
+ import { afterAll, beforeAll, beforeEach, describe, expect, it } from 'vitest'
2
2
  import { AppBskyEmbedRecord, AtpAgent, ids } from '@atproto/api'
3
3
  import { SeedClient, TestNetwork } from '@atproto/dev-env'
4
4
  import { Users, postgatesSeed } from './seed/postgates.js'
@@ -20,13 +20,10 @@ describe('postgates', () => {
20
20
 
21
21
  const result = await postgatesSeed(sc)
22
22
  users = result.users
23
-
24
- await network.processAll()
25
23
  })
26
24
 
27
- afterAll(async () => {
28
- await network.close()
29
- })
25
+ beforeEach(async () => network.processAll())
26
+ afterAll(async () => network?.close())
30
27
 
31
28
  describe(`quotee <-> quoter`, () => {
32
29
  it(`quotee detaches own post from quoter`, async () => {
@@ -1,4 +1,4 @@
1
- import { afterAll, beforeAll, describe, expect, it } from 'vitest'
1
+ import { afterAll, beforeAll, beforeEach, describe, expect, it } from 'vitest'
2
2
  import { AtpAgent } from '@atproto/api'
3
3
  import { SeedClient, TestNetwork, basicSeed } from '@atproto/dev-env'
4
4
 
@@ -31,12 +31,10 @@ describe('label hydration', () => {
31
31
  cid: '',
32
32
  val: 'misleading',
33
33
  })
34
- await network.processAll()
35
34
  })
36
35
 
37
- afterAll(async () => {
38
- await network.close()
39
- })
36
+ beforeEach(async () => network.processAll())
37
+ afterAll(async () => network?.close())
40
38
 
41
39
  it('returns labels based for a subject', async () => {
42
40
  const { data } = await pdsAgent.api.com.atproto.label.queryLabels(
@@ -10,9 +10,7 @@ describe('redis cache', () => {
10
10
  redis = new Redis({ host: process.env.REDIS_HOST || '' })
11
11
  })
12
12
 
13
- afterAll(async () => {
14
- await redis.destroy()
15
- })
13
+ afterAll(async () => redis.destroy())
16
14
 
17
15
  it('caches according to namespace', async () => {
18
16
  const ns1 = redis.withNamespace('ns1')
@@ -3,7 +3,7 @@ import { AddressInfo } from 'node:net'
3
3
  import { finished } from 'node:stream/promises'
4
4
  import express from 'express'
5
5
  import { request } from 'undici'
6
- import { afterAll, beforeAll, describe, expect, it } from 'vitest'
6
+ import { afterAll, beforeAll, beforeEach, describe, expect, it } from 'vitest'
7
7
  import { TestNetwork, basicSeed } from '@atproto/dev-env'
8
8
  import { handler as errorHandler } from '../src/error.js'
9
9
  import { startServer } from './_util.js'
@@ -18,13 +18,11 @@ describe('server', () => {
18
18
  })
19
19
  const sc = network.getSeedClient()
20
20
  await basicSeed(sc)
21
- await network.processAll()
22
21
  alice = sc.dids.alice
23
22
  })
24
23
 
25
- afterAll(async () => {
26
- await network.close()
27
- })
24
+ beforeEach(async () => network.processAll())
25
+ afterAll(async () => network?.close())
28
26
 
29
27
  it('preserves 404s.', async () => {
30
28
  const response = await fetch(`${network.bsky.url}/unknown`)
@@ -37,17 +35,14 @@ describe('server', () => {
37
35
  throw new Error('Oops!')
38
36
  })
39
37
  app.use(errorHandler)
40
- const { origin, stop } = await startServer(app)
41
- try {
42
- const response = await fetch(new URL(`/oops`, origin))
43
- expect(response.status).toEqual(500)
44
- await expect(response.json()).resolves.toEqual({
45
- error: 'InternalServerError',
46
- message: 'Internal Server Error',
47
- })
48
- } finally {
49
- await stop()
50
- }
38
+ await using server = await startServer(app)
39
+
40
+ const response = await fetch(`http://localhost:${server.port}/oops`)
41
+ expect(response.status).toEqual(500)
42
+ await expect(response.json()).resolves.toEqual({
43
+ error: 'InternalServerError',
44
+ message: 'Internal Server Error',
45
+ })
51
46
  })
52
47
 
53
48
  it('healthcheck succeeds when database is available.', async () => {
@@ -1,4 +1,4 @@
1
- import { afterAll, beforeAll, describe, expect, it } from 'vitest'
1
+ import { afterAll, beforeAll, beforeEach, describe, expect, it } from 'vitest'
2
2
  import { TestNetwork } from '@atproto/dev-env'
3
3
 
4
4
  describe('sitemap', () => {
@@ -10,9 +10,8 @@ describe('sitemap', () => {
10
10
  })
11
11
  })
12
12
 
13
- afterAll(async () => {
14
- await network.close()
15
- })
13
+ beforeEach(async () => network.processAll())
14
+ afterAll(async () => network?.close())
16
15
 
17
16
  it('returns sitemap index', async () => {
18
17
  const response = await fetch(
@@ -1,4 +1,12 @@
1
- import { afterAll, afterEach, beforeAll, describe, expect, it } from 'vitest'
1
+ import {
2
+ afterAll,
3
+ afterEach,
4
+ beforeAll,
5
+ beforeEach,
6
+ describe,
7
+ expect,
8
+ it,
9
+ } from 'vitest'
2
10
  import { TestNetwork } from '@atproto/dev-env'
3
11
  import { lexStringify } from '@atproto/lex'
4
12
  import { StashClient } from '../dist/stash.js'
@@ -35,13 +43,9 @@ describe('private data', () => {
35
43
  stashClient = network.bsky.ctx.stashClient
36
44
  })
37
45
 
38
- afterEach(async () => {
39
- await clearPrivateData(db)
40
- })
41
-
42
- afterAll(async () => {
43
- await network.close()
44
- })
46
+ beforeEach(async () => network.processAll())
47
+ afterEach(async () => clearPrivateData(network.bsky.db))
48
+ afterAll(async () => network?.close())
45
49
 
46
50
  describe('create', () => {
47
51
  it('creates entry', async () => {
@@ -1,16 +1,8 @@
1
1
  import { describe, expect, it } from 'vitest'
2
- import {
3
- PostSearchQuery,
4
- parsePostSearchQuery,
5
- } from '../src/data-plane/server/util.js'
2
+ import { parsePostSearchQuery } from '../src/data-plane/server/util.js'
6
3
 
7
4
  describe('parsePostSearchQuery', () => {
8
- type TestCase = {
9
- input: string
10
- output: PostSearchQuery
11
- }
12
-
13
- const tests: TestCase[] = [
5
+ it.each([
14
6
  {
15
7
  input: `bluesky `,
16
8
  output: { q: `bluesky`, author: undefined },
@@ -38,9 +30,7 @@ describe('parsePostSearchQuery', () => {
38
30
  author: `did:test:123`,
39
31
  },
40
32
  },
41
- ]
42
-
43
- it.each(tests)(`'$input' -> '$output'`, ({ input, output }) => {
33
+ ])(`'$input' -> '$output'`, ({ input, output }) => {
44
34
  expect(parsePostSearchQuery(input)).toEqual(output)
45
35
  })
46
36
  })
@@ -1,4 +1,4 @@
1
- import { afterAll, beforeAll, describe, expect, it } from 'vitest'
1
+ import { afterAll, beforeAll, beforeEach, describe, expect, it } from 'vitest'
2
2
  import { AtpAgent, ids } from '@atproto/api'
3
3
  import { SeedClient, TestNetwork, basicSeed } from '@atproto/dev-env'
4
4
 
@@ -22,12 +22,10 @@ describe('bsky account deactivation', () => {
22
22
  {},
23
23
  { encoding: 'application/json', headers: sc.getHeaders(alice) },
24
24
  )
25
- await network.processAll()
26
25
  })
27
26
 
28
- afterAll(async () => {
29
- await network.close()
30
- })
27
+ beforeEach(async () => network.processAll())
28
+ afterAll(async () => network?.close())
31
29
 
32
30
  it('does not return deactivated profiles', async () => {
33
31
  const attempt = agent.api.app.bsky.actor.getProfile({
@@ -1,4 +1,4 @@
1
- import { afterAll, beforeAll, describe, expect, it } from 'vitest'
1
+ import { afterAll, beforeAll, beforeEach, describe, expect, it } from 'vitest'
2
2
  import { AtUri, AtpAgent, ids } from '@atproto/api'
3
3
  import { SeedClient, TestNetwork, basicSeed } from '@atproto/dev-env'
4
4
 
@@ -21,15 +21,13 @@ describe('bsky actor likes feed views', () => {
21
21
  pdsAgent = network.pds.getAgent()
22
22
  sc = network.getSeedClient()
23
23
  await basicSeed(sc)
24
- await network.processAll()
25
24
  alice = sc.dids.alice
26
25
  bob = sc.dids.bob
27
26
  carol = sc.dids.carol
28
27
  })
29
28
 
30
- afterAll(async () => {
31
- await network.close()
32
- })
29
+ beforeEach(async () => network.processAll())
30
+ afterAll(async () => network?.close())
33
31
 
34
32
  it('returns posts liked by actor', async () => {
35
33
  const {
@@ -1,4 +1,4 @@
1
- import { afterAll, beforeAll, describe, expect, it } from 'vitest'
1
+ import { afterAll, beforeAll, beforeEach, describe, expect, it } from 'vitest'
2
2
  import { AppBskyActorSearchActors, AtpAgent, ids } from '@atproto/api'
3
3
  import { wait } from '@atproto/common'
4
4
  import { SeedClient, TestNetwork, usersBulkSeed } from '@atproto/dev-env'
@@ -21,7 +21,8 @@ describe.skip('pds actor search views', () => {
21
21
  sc = network.getSeedClient()
22
22
 
23
23
  await wait(50) // allow pending sub to be established
24
- await network.bsky.sub.destroy()
24
+ await network.processAll()
25
+ await network.bsky.sub.stop()
25
26
  await usersBulkSeed(sc)
26
27
 
27
28
  // Skip did/handle resolution for expediency
@@ -41,7 +42,6 @@ describe.skip('pds actor search views', () => {
41
42
 
42
43
  // Process remaining profiles
43
44
  await network.bsky.sub.restart()
44
- await network.processAll(50000)
45
45
  headers = await network.serviceHeaders(
46
46
  Object.values(sc.dids)[0],
47
47
  ids.AppBskyActorSearchActors,
@@ -50,12 +50,11 @@ describe.skip('pds actor search views', () => {
50
50
  Object.values(sc.dids)[0],
51
51
  ids.AppBskyActorSearchActorsTypeahead,
52
52
  )
53
- }, 20_000) // @NOTE seeding can take a while
54
-
55
- afterAll(async () => {
56
- await network.close()
57
53
  })
58
54
 
55
+ beforeEach(async () => network.processAll(50_000), 50_100)
56
+ afterAll(async () => network?.close())
57
+
59
58
  it('typeahead gives relevant results', async () => {
60
59
  const result = await agent.api.app.bsky.actor.searchActorsTypeahead(
61
60
  { term: 'car' },
@@ -3,6 +3,8 @@ import { once } from 'node:events'
3
3
  import { Server, createServer } from 'node:http'
4
4
  import { AddressInfo } from 'node:net'
5
5
  import express, { Application, json } from 'express'
6
+ // eslint-disable-next-line import/default
7
+ import httpTerminator from 'http-terminator'
6
8
  import {
7
9
  afterAll,
8
10
  afterEach,
@@ -172,10 +174,8 @@ describe('age assurance v2 views', () => {
172
174
  await clearActorAgeAssurance(db)
173
175
  })
174
176
 
175
- afterAll(async () => {
176
- await network.close()
177
- await kws.stop()
178
- })
177
+ afterAll(async () => network?.close())
178
+ afterAll(async () => kws?.stop())
179
179
 
180
180
  const getState = async (params: AppBskyAgeassuranceGetState.QueryParams) => {
181
181
  const { data } = await agent.app.bsky.ageassurance.getState(params, {
@@ -667,6 +667,7 @@ class MockKwsServer {
667
667
 
668
668
  private app: Application
669
669
  private server: Server
670
+ private terminator: httpTerminator.HttpTerminator
670
671
  private bskyUrlBase = ''
671
672
 
672
673
  constructor({
@@ -693,6 +694,9 @@ class MockKwsServer {
693
694
  })
694
695
 
695
696
  this.server = createServer(this.app)
697
+ this.terminator = httpTerminator.createHttpTerminator({
698
+ server: this.server,
699
+ })
696
700
  }
697
701
 
698
702
  async listen(port?: number) {
@@ -701,8 +705,7 @@ class MockKwsServer {
701
705
  }
702
706
 
703
707
  async stop() {
704
- this.server.close()
705
- await once(this.server, 'close')
708
+ await this.terminator.terminate()
706
709
  }
707
710
 
708
711
  setBskyBaseUrl(url: string) {