@atproto/pds 0.5.12 → 0.5.15

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 (326) hide show
  1. package/CHANGELOG.md +53 -0
  2. package/dist/api/app/bsky/notification/index.d.ts.map +1 -1
  3. package/dist/api/app/bsky/notification/index.js +2 -0
  4. package/dist/api/app/bsky/notification/index.js.map +1 -1
  5. package/dist/api/app/bsky/notification/unregisterPush.d.ts +4 -0
  6. package/dist/api/app/bsky/notification/unregisterPush.d.ts.map +1 -0
  7. package/dist/api/app/bsky/notification/unregisterPush.js +48 -0
  8. package/dist/api/app/bsky/notification/unregisterPush.js.map +1 -0
  9. package/dist/lexicons/app/bsky/actor/defs.defs.d.ts +6 -0
  10. package/dist/lexicons/app/bsky/actor/defs.defs.d.ts.map +1 -1
  11. package/dist/lexicons/app/bsky/actor/defs.defs.js +1 -0
  12. package/dist/lexicons/app/bsky/actor/defs.defs.js.map +1 -1
  13. package/package.json +42 -38
  14. package/build.templates.cjs +0 -22
  15. package/example.env +0 -42
  16. package/jest.config.cjs +0 -27
  17. package/src/account-manager/account-manager.ts +0 -916
  18. package/src/account-manager/db/index.ts +0 -21
  19. package/src/account-manager/db/migrations/001-init.ts +0 -115
  20. package/src/account-manager/db/migrations/002-account-deactivation.ts +0 -17
  21. package/src/account-manager/db/migrations/003-privileged-app-passwords.ts +0 -12
  22. package/src/account-manager/db/migrations/004-oauth.ts +0 -122
  23. package/src/account-manager/db/migrations/005-oauth-account-management.ts +0 -136
  24. package/src/account-manager/db/migrations/006-oauth-permission-sets.ts +0 -20
  25. package/src/account-manager/db/migrations/007-lexicon-failures-index.ts +0 -14
  26. package/src/account-manager/db/migrations/index.ts +0 -17
  27. package/src/account-manager/db/schema/account-device.ts +0 -14
  28. package/src/account-manager/db/schema/account.ts +0 -16
  29. package/src/account-manager/db/schema/actor.ts +0 -17
  30. package/src/account-manager/db/schema/app-password.ts +0 -13
  31. package/src/account-manager/db/schema/authorization-request.ts +0 -30
  32. package/src/account-manager/db/schema/authorized-client.ts +0 -23
  33. package/src/account-manager/db/schema/device.ts +0 -18
  34. package/src/account-manager/db/schema/email-token.ts +0 -19
  35. package/src/account-manager/db/schema/index.ts +0 -43
  36. package/src/account-manager/db/schema/invite-code.ts +0 -24
  37. package/src/account-manager/db/schema/lexicon.ts +0 -15
  38. package/src/account-manager/db/schema/refresh-token.ts +0 -11
  39. package/src/account-manager/db/schema/repo-root.ts +0 -12
  40. package/src/account-manager/db/schema/token.ts +0 -38
  41. package/src/account-manager/db/schema/used-refresh-token.ts +0 -13
  42. package/src/account-manager/helpers/account-device.ts +0 -63
  43. package/src/account-manager/helpers/account.ts +0 -355
  44. package/src/account-manager/helpers/auth.ts +0 -222
  45. package/src/account-manager/helpers/authorization-request.ts +0 -90
  46. package/src/account-manager/helpers/authorized-client.ts +0 -75
  47. package/src/account-manager/helpers/device.ts +0 -47
  48. package/src/account-manager/helpers/email-token.ts +0 -87
  49. package/src/account-manager/helpers/invite.ts +0 -263
  50. package/src/account-manager/helpers/lexicon.ts +0 -67
  51. package/src/account-manager/helpers/password.ts +0 -136
  52. package/src/account-manager/helpers/repo.ts +0 -24
  53. package/src/account-manager/helpers/scrypt.ts +0 -53
  54. package/src/account-manager/helpers/token.ts +0 -158
  55. package/src/account-manager/helpers/used-refresh-token.ts +0 -30
  56. package/src/account-manager/oauth-store.ts +0 -880
  57. package/src/account-manager/scope-reference-getter.ts +0 -106
  58. package/src/actor-store/actor-store-reader.ts +0 -45
  59. package/src/actor-store/actor-store-resources.ts +0 -8
  60. package/src/actor-store/actor-store-transactor.ts +0 -31
  61. package/src/actor-store/actor-store-writer.ts +0 -17
  62. package/src/actor-store/actor-store.ts +0 -210
  63. package/src/actor-store/blob/reader.ts +0 -160
  64. package/src/actor-store/blob/transactor.ts +0 -383
  65. package/src/actor-store/db/index.ts +0 -20
  66. package/src/actor-store/db/migrations/001-init.ts +0 -105
  67. package/src/actor-store/db/migrations/index.ts +0 -5
  68. package/src/actor-store/db/schema/account-pref.ts +0 -11
  69. package/src/actor-store/db/schema/backlink.ts +0 -9
  70. package/src/actor-store/db/schema/blob.ts +0 -14
  71. package/src/actor-store/db/schema/index.ts +0 -23
  72. package/src/actor-store/db/schema/record-blob.ts +0 -8
  73. package/src/actor-store/db/schema/record.ts +0 -14
  74. package/src/actor-store/db/schema/repo-block.ts +0 -10
  75. package/src/actor-store/db/schema/repo-root.ts +0 -10
  76. package/src/actor-store/migrate.ts +0 -39
  77. package/src/actor-store/preference/reader.ts +0 -48
  78. package/src/actor-store/preference/transactor.ts +0 -55
  79. package/src/actor-store/preference/util.ts +0 -39
  80. package/src/actor-store/record/reader.ts +0 -374
  81. package/src/actor-store/record/transactor.ts +0 -111
  82. package/src/actor-store/repo/reader.ts +0 -31
  83. package/src/actor-store/repo/sql-repo-reader.ts +0 -150
  84. package/src/actor-store/repo/sql-repo-transactor.ts +0 -105
  85. package/src/actor-store/repo/transactor.ts +0 -227
  86. package/src/api/app/bsky/actor/getPreferences.ts +0 -57
  87. package/src/api/app/bsky/actor/getProfile.ts +0 -41
  88. package/src/api/app/bsky/actor/getProfiles.ts +0 -51
  89. package/src/api/app/bsky/actor/index.ts +0 -13
  90. package/src/api/app/bsky/actor/putPreferences.ts +0 -62
  91. package/src/api/app/bsky/feed/getActorLikes.ts +0 -63
  92. package/src/api/app/bsky/feed/getAuthorFeed.ts +0 -84
  93. package/src/api/app/bsky/feed/getFeed.ts +0 -47
  94. package/src/api/app/bsky/feed/getPostThread.ts +0 -251
  95. package/src/api/app/bsky/feed/getTimeline.ts +0 -50
  96. package/src/api/app/bsky/feed/index.ts +0 -15
  97. package/src/api/app/bsky/index.ts +0 -11
  98. package/src/api/app/bsky/notification/index.ts +0 -7
  99. package/src/api/app/bsky/notification/registerPush.ts +0 -71
  100. package/src/api/app/bsky/util/resolver.ts +0 -20
  101. package/src/api/com/atproto/admin/deleteAccount.ts +0 -22
  102. package/src/api/com/atproto/admin/disableAccountInvites.ts +0 -18
  103. package/src/api/com/atproto/admin/disableInviteCodes.ts +0 -21
  104. package/src/api/com/atproto/admin/enableAccountInvites.ts +0 -18
  105. package/src/api/com/atproto/admin/getAccountInfo.ts +0 -32
  106. package/src/api/com/atproto/admin/getAccountInfos.ts +0 -34
  107. package/src/api/com/atproto/admin/getInviteCodes.ts +0 -126
  108. package/src/api/com/atproto/admin/getSubjectStatus.ts +0 -76
  109. package/src/api/com/atproto/admin/index.ts +0 -31
  110. package/src/api/com/atproto/admin/sendEmail.ts +0 -47
  111. package/src/api/com/atproto/admin/updateAccountEmail.ts +0 -32
  112. package/src/api/com/atproto/admin/updateAccountHandle.ts +0 -47
  113. package/src/api/com/atproto/admin/updateAccountPassword.ts +0 -34
  114. package/src/api/com/atproto/admin/updateSubjectStatus.ts +0 -68
  115. package/src/api/com/atproto/admin/util.ts +0 -66
  116. package/src/api/com/atproto/identity/getRecommendedDidCredentials.ts +0 -50
  117. package/src/api/com/atproto/identity/index.ts +0 -17
  118. package/src/api/com/atproto/identity/requestPlcOperationSignature.ts +0 -59
  119. package/src/api/com/atproto/identity/resolveHandle.ts +0 -50
  120. package/src/api/com/atproto/identity/signPlcOperation.ts +0 -85
  121. package/src/api/com/atproto/identity/submitPlcOperation.ts +0 -65
  122. package/src/api/com/atproto/identity/updateHandle.ts +0 -66
  123. package/src/api/com/atproto/index.ts +0 -19
  124. package/src/api/com/atproto/moderation/createReport.ts +0 -41
  125. package/src/api/com/atproto/moderation/index.ts +0 -7
  126. package/src/api/com/atproto/repo/applyWrites.ts +0 -226
  127. package/src/api/com/atproto/repo/createRecord.ts +0 -143
  128. package/src/api/com/atproto/repo/deleteRecord.ts +0 -122
  129. package/src/api/com/atproto/repo/describeRepo.ts +0 -43
  130. package/src/api/com/atproto/repo/getRecord.ts +0 -40
  131. package/src/api/com/atproto/repo/importRepo.ts +0 -101
  132. package/src/api/com/atproto/repo/index.ts +0 -25
  133. package/src/api/com/atproto/repo/listMissingBlobs.ts +0 -29
  134. package/src/api/com/atproto/repo/listRecords.ts +0 -36
  135. package/src/api/com/atproto/repo/putRecord.ts +0 -211
  136. package/src/api/com/atproto/repo/uploadBlob.ts +0 -60
  137. package/src/api/com/atproto/server/activateAccount.ts +0 -37
  138. package/src/api/com/atproto/server/checkAccountStatus.ts +0 -51
  139. package/src/api/com/atproto/server/confirmEmail.ts +0 -39
  140. package/src/api/com/atproto/server/createAccount.ts +0 -327
  141. package/src/api/com/atproto/server/createAppPassword.ts +0 -53
  142. package/src/api/com/atproto/server/createInviteCode.ts +0 -38
  143. package/src/api/com/atproto/server/createInviteCodes.ts +0 -42
  144. package/src/api/com/atproto/server/createSession.ts +0 -97
  145. package/src/api/com/atproto/server/deactivateAccount.ts +0 -41
  146. package/src/api/com/atproto/server/deleteAccount.ts +0 -85
  147. package/src/api/com/atproto/server/deleteSession.ts +0 -23
  148. package/src/api/com/atproto/server/describeServer.ts +0 -29
  149. package/src/api/com/atproto/server/getAccountInviteCodes.ts +0 -142
  150. package/src/api/com/atproto/server/getServiceAuth.ts +0 -111
  151. package/src/api/com/atproto/server/getSession.ts +0 -80
  152. package/src/api/com/atproto/server/index.ts +0 -55
  153. package/src/api/com/atproto/server/listAppPasswords.ts +0 -45
  154. package/src/api/com/atproto/server/refreshSession.ts +0 -72
  155. package/src/api/com/atproto/server/requestAccountDelete.ts +0 -66
  156. package/src/api/com/atproto/server/requestEmailConfirmation.ts +0 -68
  157. package/src/api/com/atproto/server/requestEmailUpdate.ts +0 -86
  158. package/src/api/com/atproto/server/requestPasswordReset.ts +0 -52
  159. package/src/api/com/atproto/server/reserveSigningKey.ts +0 -15
  160. package/src/api/com/atproto/server/resetPassword.ts +0 -50
  161. package/src/api/com/atproto/server/revokeAppPassword.ts +0 -42
  162. package/src/api/com/atproto/server/updateEmail.ts +0 -52
  163. package/src/api/com/atproto/server/util.ts +0 -136
  164. package/src/api/com/atproto/sync/deprecated/getCheckout.ts +0 -27
  165. package/src/api/com/atproto/sync/deprecated/getHead.ts +0 -33
  166. package/src/api/com/atproto/sync/getBlob.ts +0 -61
  167. package/src/api/com/atproto/sync/getBlocks.ts +0 -37
  168. package/src/api/com/atproto/sync/getLatestCommit.ts +0 -33
  169. package/src/api/com/atproto/sync/getRecord.ts +0 -49
  170. package/src/api/com/atproto/sync/getRepo.ts +0 -75
  171. package/src/api/com/atproto/sync/getRepoStatus.ts +0 -34
  172. package/src/api/com/atproto/sync/index.ts +0 -27
  173. package/src/api/com/atproto/sync/listBlobs.ts +0 -33
  174. package/src/api/com/atproto/sync/listRepos.ts +0 -74
  175. package/src/api/com/atproto/sync/subscribeRepos.ts +0 -73
  176. package/src/api/com/atproto/sync/util.ts +0 -37
  177. package/src/api/com/atproto/temp/checkSignupQueue.ts +0 -34
  178. package/src/api/com/atproto/temp/index.ts +0 -7
  179. package/src/api/index.ts +0 -10
  180. package/src/api/proxy.ts +0 -44
  181. package/src/app-view.ts +0 -24
  182. package/src/auth-output.ts +0 -52
  183. package/src/auth-routes.ts +0 -64
  184. package/src/auth-scope.ts +0 -40
  185. package/src/auth-verifier.ts +0 -668
  186. package/src/background.ts +0 -65
  187. package/src/basic-routes.ts +0 -52
  188. package/src/bsky-app-view.ts +0 -33
  189. package/src/config/config.ts +0 -553
  190. package/src/config/env.ts +0 -167
  191. package/src/config/index.ts +0 -3
  192. package/src/config/secrets.ts +0 -54
  193. package/src/context.ts +0 -523
  194. package/src/crawlers.ts +0 -46
  195. package/src/db/cast.ts +0 -52
  196. package/src/db/db.ts +0 -140
  197. package/src/db/index.ts +0 -4
  198. package/src/db/migrator.ts +0 -40
  199. package/src/db/pagination.ts +0 -132
  200. package/src/db/tables/moderation.ts +0 -80
  201. package/src/db/util.ts +0 -108
  202. package/src/did-cache/db/index.ts +0 -21
  203. package/src/did-cache/db/migrations.ts +0 -17
  204. package/src/did-cache/db/schema.ts +0 -9
  205. package/src/did-cache/index.ts +0 -131
  206. package/src/disk-blobstore.ts +0 -172
  207. package/src/error.ts +0 -19
  208. package/src/handle/explicit-slurs.ts +0 -22
  209. package/src/handle/index.ts +0 -49
  210. package/src/handle/reserved.ts +0 -1059
  211. package/src/image/image-url-builder.ts +0 -16
  212. package/src/index.ts +0 -189
  213. package/src/lexicons.ts +0 -4
  214. package/src/logger.ts +0 -35
  215. package/src/mailer/index.ts +0 -111
  216. package/src/mailer/moderation.ts +0 -33
  217. package/src/mailer/templates/confirm-email.d.ts +0 -4
  218. package/src/mailer/templates/confirm-email.hbs +0 -158
  219. package/src/mailer/templates/delete-account.d.ts +0 -4
  220. package/src/mailer/templates/delete-account.hbs +0 -156
  221. package/src/mailer/templates/plc-operation.d.ts +0 -4
  222. package/src/mailer/templates/plc-operation.hbs +0 -153
  223. package/src/mailer/templates/reset-password.d.ts +0 -4
  224. package/src/mailer/templates/reset-password.hbs +0 -154
  225. package/src/mailer/templates/update-email.d.ts +0 -4
  226. package/src/mailer/templates/update-email.hbs +0 -153
  227. package/src/mailer/templates.ts +0 -17
  228. package/src/pipethrough.ts +0 -716
  229. package/src/rate-limits.ts +0 -59
  230. package/src/read-after-write/index.ts +0 -3
  231. package/src/read-after-write/types.ts +0 -35
  232. package/src/read-after-write/util.ts +0 -101
  233. package/src/read-after-write/viewer.ts +0 -290
  234. package/src/redis.ts +0 -25
  235. package/src/repo/index.ts +0 -2
  236. package/src/repo/prepare.ts +0 -266
  237. package/src/repo/types.ts +0 -65
  238. package/src/scripts/README.md +0 -40
  239. package/src/scripts/index.ts +0 -20
  240. package/src/scripts/publish-identity.ts +0 -60
  241. package/src/scripts/rebuild-repo.ts +0 -119
  242. package/src/scripts/rotate-keys.ts +0 -146
  243. package/src/scripts/sequencer-recovery/index.ts +0 -23
  244. package/src/scripts/sequencer-recovery/recoverer.ts +0 -297
  245. package/src/scripts/sequencer-recovery/recovery-db.ts +0 -65
  246. package/src/scripts/sequencer-recovery/repair-repos.ts +0 -49
  247. package/src/scripts/sequencer-recovery/user-queues.ts +0 -44
  248. package/src/scripts/util.ts +0 -7
  249. package/src/sequencer/db/index.ts +0 -21
  250. package/src/sequencer/db/migrations/001-init.ts +0 -35
  251. package/src/sequencer/db/migrations/index.ts +0 -5
  252. package/src/sequencer/db/schema.ts +0 -19
  253. package/src/sequencer/events.ts +0 -199
  254. package/src/sequencer/index.ts +0 -3
  255. package/src/sequencer/outbox.ts +0 -123
  256. package/src/sequencer/sequencer.ts +0 -290
  257. package/src/util/compression.ts +0 -16
  258. package/src/util/debug.ts +0 -10
  259. package/src/util/http.ts +0 -31
  260. package/src/util/types.ts +0 -7
  261. package/src/well-known.ts +0 -30
  262. package/test.env +0 -2
  263. package/tests/__snapshots__/takedown-appeal.test.ts.snap +0 -43
  264. package/tests/_oauth_client_assets_middleware.ts +0 -23
  265. package/tests/_puppeteer.ts +0 -147
  266. package/tests/_types.d.ts +0 -16
  267. package/tests/_util.ts +0 -191
  268. package/tests/account-deactivation.test.ts +0 -204
  269. package/tests/account-deletion.test.ts +0 -300
  270. package/tests/account-manager.test.ts +0 -462
  271. package/tests/account-migration.test.ts +0 -221
  272. package/tests/account-status.test.ts +0 -206
  273. package/tests/account.test.ts +0 -595
  274. package/tests/app-passwords.test.ts +0 -262
  275. package/tests/auth.test.ts +0 -405
  276. package/tests/blob-deletes.test.ts +0 -204
  277. package/tests/create-post.test.ts +0 -79
  278. package/tests/crud.test.ts +0 -1595
  279. package/tests/db.test.ts +0 -170
  280. package/tests/email-confirmation.test.ts +0 -227
  281. package/tests/entryway-mock.ts +0 -323
  282. package/tests/entryway.test.ts +0 -145
  283. package/tests/file-uploads.test.ts +0 -301
  284. package/tests/get-service-auth.test.ts +0 -81
  285. package/tests/handle-validation.test.ts +0 -56
  286. package/tests/handles.test.ts +0 -274
  287. package/tests/invite-codes.test.ts +0 -367
  288. package/tests/invites-admin.test.ts +0 -252
  289. package/tests/moderation.test.ts +0 -280
  290. package/tests/moderator-auth.test.ts +0 -177
  291. package/tests/oauth.test.ts +0 -334
  292. package/tests/plc-operations.test.ts +0 -239
  293. package/tests/preferences.test.ts +0 -352
  294. package/tests/proxied/__snapshots__/admin.test.ts.snap +0 -516
  295. package/tests/proxied/__snapshots__/feedgen.test.ts.snap +0 -215
  296. package/tests/proxied/__snapshots__/views.test.ts.snap +0 -4456
  297. package/tests/proxied/admin.test.ts +0 -340
  298. package/tests/proxied/feedgen.test.ts +0 -66
  299. package/tests/proxied/notif.test.ts +0 -85
  300. package/tests/proxied/procedures.test.ts +0 -175
  301. package/tests/proxied/proxy-catchall.test.ts +0 -256
  302. package/tests/proxied/proxy-header.test.ts +0 -239
  303. package/tests/proxied/proxy-oauth-aud.test.ts +0 -182
  304. package/tests/proxied/read-after-write.test.ts +0 -382
  305. package/tests/proxied/views.test.ts +0 -608
  306. package/tests/races.test.ts +0 -89
  307. package/tests/rate-limits.test.ts +0 -70
  308. package/tests/recovery.test.ts +0 -180
  309. package/tests/seeds/basic.ts +0 -165
  310. package/tests/seeds/follows.ts +0 -57
  311. package/tests/seeds/likes.ts +0 -14
  312. package/tests/seeds/reposts.ts +0 -18
  313. package/tests/seeds/thread.ts +0 -40
  314. package/tests/seeds/users-bulk.ts +0 -246
  315. package/tests/seeds/users.ts +0 -67
  316. package/tests/sequencer.test.ts +0 -251
  317. package/tests/server.test.ts +0 -151
  318. package/tests/sync/invertible-ops.test.ts +0 -99
  319. package/tests/sync/list.test.ts +0 -43
  320. package/tests/sync/subscribe-repos.test.ts +0 -672
  321. package/tests/sync/sync.test.ts +0 -316
  322. package/tests/takedown-appeal.test.ts +0 -166
  323. package/tsconfig.build.json +0 -9
  324. package/tsconfig.build.tsbuildinfo +0 -1
  325. package/tsconfig.json +0 -7
  326. package/tsconfig.tests.json +0 -8
@@ -1,19 +0,0 @@
1
- import { Generated, GeneratedAlways, Insertable, Selectable } from 'kysely'
2
-
3
- export type RepoSeqEventType = 'append' | 'sync' | 'identity' | 'account'
4
-
5
- export interface RepoSeq {
6
- seq: GeneratedAlways<number>
7
- did: string
8
- eventType: RepoSeqEventType
9
- event: Uint8Array
10
- invalidated: Generated<0 | 1>
11
- sequencedAt: string
12
- }
13
-
14
- export type RepoSeqInsert = Insertable<RepoSeq>
15
- export type RepoSeqEntry = Selectable<RepoSeq>
16
-
17
- export type SequencerDbSchema = {
18
- repo_seq: RepoSeq
19
- }
@@ -1,199 +0,0 @@
1
- import assert from 'node:assert'
2
- import { z } from 'zod'
3
- import { schema } from '@atproto/common'
4
- import {
5
- DatetimeString,
6
- DidString,
7
- HandleString,
8
- isDidString,
9
- isHandleString,
10
- } from '@atproto/lex'
11
- import { encode as cborEncode } from '@atproto/lex-cbor'
12
- import { BlockMap, blocksToCarFile } from '@atproto/repo'
13
- import { AccountStatus } from '../account-manager/account-manager.js'
14
- import { CommitDataWithOps, SyncEvtData } from '../repo/index.js'
15
- import { RepoSeqInsert } from './db/index.js'
16
-
17
- export const formatSeqCommit = async (
18
- did: string,
19
- commitData: CommitDataWithOps,
20
- ): Promise<RepoSeqInsert> => {
21
- const blocksToSend = new BlockMap()
22
- blocksToSend.addMap(commitData.newBlocks)
23
- blocksToSend.addMap(commitData.relevantBlocks)
24
-
25
- const evt = {
26
- repo: did,
27
- commit: commitData.cid,
28
- rev: commitData.rev,
29
- since: commitData.since,
30
- blocks: await blocksToCarFile(commitData.cid, blocksToSend),
31
- ops: commitData.ops,
32
- prevData: commitData.prevData ?? undefined,
33
- // deprecated (but still required) fields
34
- rebase: false,
35
- tooBig: false,
36
- blobs: [],
37
- }
38
-
39
- return {
40
- did,
41
- eventType: 'append' as const,
42
- event: cborEncode(evt),
43
- sequencedAt: new Date().toISOString(),
44
- }
45
- }
46
-
47
- export const formatSeqSyncEvt = async (
48
- did: DidString,
49
- data: SyncEvtData,
50
- ): Promise<RepoSeqInsert> => {
51
- const blocks = await blocksToCarFile(data.cid, data.blocks)
52
- const evt: SyncEvt = {
53
- did,
54
- rev: data.rev,
55
- blocks,
56
- }
57
- return {
58
- did,
59
- eventType: 'sync',
60
- event: cborEncode(evt),
61
- sequencedAt: new Date().toISOString(),
62
- }
63
- }
64
-
65
- export const syncEvtDataFromCommit = (
66
- commitData: CommitDataWithOps,
67
- ): SyncEvtData => {
68
- const { blocks, missing } = commitData.relevantBlocks.getMany([
69
- commitData.cid,
70
- ])
71
- assert(
72
- !missing.length,
73
- 'commit block was not found, could not build sync event',
74
- )
75
- return {
76
- rev: commitData.rev,
77
- cid: commitData.cid,
78
- blocks,
79
- }
80
- }
81
-
82
- export const formatSeqIdentityEvt = async (
83
- did: DidString,
84
- handle?: HandleString,
85
- ): Promise<RepoSeqInsert> => {
86
- const evt: IdentityEvt = handle //
87
- ? { did, handle }
88
- : { did }
89
-
90
- return {
91
- did,
92
- eventType: 'identity',
93
- event: cborEncode(evt),
94
- sequencedAt: new Date().toISOString(),
95
- }
96
- }
97
-
98
- export const formatSeqAccountEvt = async (
99
- did: DidString,
100
- status: AccountStatus,
101
- ): Promise<RepoSeqInsert> => {
102
- const evt: AccountEvt =
103
- status === AccountStatus.Active
104
- ? { did, active: true }
105
- : { did, active: false, status }
106
-
107
- return {
108
- did,
109
- eventType: 'account',
110
- event: cborEncode(evt),
111
- sequencedAt: new Date().toISOString(),
112
- }
113
- }
114
-
115
- export const commitEvtOp = z.object({
116
- action: z.union([
117
- z.literal('create'),
118
- z.literal('update'),
119
- z.literal('delete'),
120
- ]),
121
- // @TODO should we validate that the "path" is a valid "<nsid>/<rkey>" ?
122
- path: z.string(),
123
- cid: schema.cid.nullable(),
124
- prev: schema.cid.optional(),
125
- })
126
- export type CommitEvtOp = z.infer<typeof commitEvtOp>
127
-
128
- // @TODO This runtime code is only used to generate "types". We should either
129
- // make use of it or only use types.
130
- export const commitEvt = z.object({
131
- rebase: z.boolean(),
132
- tooBig: z.boolean(),
133
- repo: z.string().refine(isDidString),
134
- commit: schema.cid,
135
- rev: z.string(),
136
- since: z.string().nullable(),
137
- blocks: schema.bytes,
138
- ops: z.array(commitEvtOp),
139
- blobs: z.array(schema.cid),
140
- prevData: schema.cid.optional(),
141
- })
142
- export type CommitEvt = z.infer<typeof commitEvt>
143
-
144
- export const syncEvt = z.object({
145
- did: z.string().refine(isDidString),
146
- blocks: schema.bytes,
147
- rev: z.string(),
148
- })
149
- export type SyncEvt = z.infer<typeof syncEvt>
150
-
151
- export const identityEvt = z.object({
152
- did: z.string().refine(isDidString),
153
- handle: z.string().refine(isHandleString).optional(),
154
- })
155
- export type IdentityEvt = z.infer<typeof identityEvt>
156
-
157
- export const accountEvt = z.object({
158
- did: z.string().refine(isDidString),
159
- active: z.boolean(),
160
- status: z
161
- .enum([
162
- AccountStatus.Takendown,
163
- AccountStatus.Suspended,
164
- AccountStatus.Deleted,
165
- AccountStatus.Deactivated,
166
- ])
167
- .optional(),
168
- })
169
- export type AccountEvt = z.infer<typeof accountEvt>
170
-
171
- type TypedCommitEvt = {
172
- type: 'commit'
173
- seq: number
174
- time: DatetimeString
175
- evt: CommitEvt
176
- }
177
- type TypedSyncEvt = {
178
- type: 'sync'
179
- seq: number
180
- time: DatetimeString
181
- evt: SyncEvt
182
- }
183
- type TypedIdentityEvt = {
184
- type: 'identity'
185
- seq: number
186
- time: DatetimeString
187
- evt: IdentityEvt
188
- }
189
- type TypedAccountEvt = {
190
- type: 'account'
191
- seq: number
192
- time: DatetimeString
193
- evt: AccountEvt
194
- }
195
- export type SeqEvt =
196
- | TypedCommitEvt
197
- | TypedSyncEvt
198
- | TypedIdentityEvt
199
- | TypedAccountEvt
@@ -1,3 +0,0 @@
1
- export * from './sequencer.js'
2
- export * from './outbox.js'
3
- export * from './events.js'
@@ -1,123 +0,0 @@
1
- import { AsyncBuffer, AsyncBufferFullError } from '@atproto/common'
2
- import { InvalidRequestError } from '@atproto/xrpc-server'
3
- import { SeqEvt, Sequencer } from './index.js'
4
-
5
- export type OutboxOpts = {
6
- maxBufferSize: number
7
- }
8
-
9
- export class Outbox {
10
- private caughtUp = false
11
- lastSeen = -1
12
-
13
- cutoverBuffer: SeqEvt[]
14
- outBuffer: AsyncBuffer<SeqEvt>
15
-
16
- constructor(
17
- public sequencer: Sequencer,
18
- opts: Partial<OutboxOpts> = {},
19
- ) {
20
- const { maxBufferSize = 500 } = opts
21
- this.cutoverBuffer = []
22
- this.outBuffer = new AsyncBuffer<SeqEvt>(maxBufferSize)
23
- }
24
-
25
- // event stream occurs in 3 phases
26
- // 1. backfill events: events that have been added to the DB since the last time a connection was open.
27
- // The outbox is not yet listening for new events from the sequencer
28
- // 2. cutover: the outbox has caught up with where the sequencer purports to be,
29
- // but the sequencer might already be halfway through sending out a round of updates.
30
- // Therefore, we start accepting the sequencer's events in a buffer, while making our own request to the
31
- // database to ensure we're caught up. We then dedupe the query & the buffer & stream the events in order
32
- // 3. streaming: we're all caught up on historic state, so the sequencer outputs events and we
33
- // immediately yield them
34
- async *events(
35
- backfillCursor?: number,
36
- signal?: AbortSignal,
37
- ): AsyncGenerator<SeqEvt> {
38
- // catch up as much as we can
39
- if (backfillCursor !== undefined) {
40
- for await (const evt of this.getBackfill(backfillCursor)) {
41
- if (signal?.aborted) return
42
- this.lastSeen = evt.seq
43
- yield evt
44
- }
45
- } else {
46
- // if not backfill, we don't need to cutover, just start streaming
47
- this.caughtUp = true
48
- }
49
-
50
- // streams updates from sequencer, but buffers them for cutover as it makes a last request
51
-
52
- const addToBuffer = (evts) => {
53
- if (this.caughtUp) {
54
- this.outBuffer.pushMany(evts)
55
- } else {
56
- this.cutoverBuffer = [...this.cutoverBuffer, ...evts]
57
- }
58
- }
59
-
60
- if (!signal?.aborted) {
61
- this.sequencer.on('events', addToBuffer)
62
- }
63
- signal?.addEventListener('abort', () =>
64
- this.sequencer.off('events', addToBuffer),
65
- )
66
-
67
- const cutover = async () => {
68
- // only need to perform cutover if we've been backfilling
69
- if (backfillCursor !== undefined) {
70
- const cutoverEvts = await this.sequencer.requestSeqRange({
71
- earliestSeq: this.lastSeen > -1 ? this.lastSeen : backfillCursor,
72
- })
73
- this.outBuffer.pushMany(cutoverEvts)
74
- // dont worry about dupes, we ensure order on yield
75
- this.outBuffer.pushMany(this.cutoverBuffer)
76
- this.caughtUp = true
77
- this.cutoverBuffer = []
78
- } else {
79
- this.caughtUp = true
80
- }
81
- }
82
- cutover()
83
-
84
- while (true) {
85
- try {
86
- for await (const evt of this.outBuffer.events()) {
87
- if (signal?.aborted) return
88
- if (evt.seq > this.lastSeen) {
89
- this.lastSeen = evt.seq
90
- yield evt
91
- }
92
- }
93
- } catch (err) {
94
- if (err instanceof AsyncBufferFullError) {
95
- throw new InvalidRequestError(
96
- 'Stream consumer too slow',
97
- 'ConsumerTooSlow',
98
- )
99
- } else {
100
- throw err
101
- }
102
- }
103
- }
104
- }
105
-
106
- // yields only historical events
107
- async *getBackfill(backfillCursor: number) {
108
- const PAGE_SIZE = 500
109
- while (true) {
110
- const evts = await this.sequencer.requestSeqRange({
111
- earliestSeq: this.lastSeen > -1 ? this.lastSeen : backfillCursor,
112
- limit: PAGE_SIZE,
113
- })
114
- for (const evt of evts) {
115
- yield evt
116
- }
117
- // if we're within half a pagesize of the sequencer, we call it good & switch to cutover
118
- const seqCursor = this.sequencer.lastSeen ?? -1
119
- if (seqCursor - this.lastSeen < PAGE_SIZE / 2) break
120
- if (evts.length < 1) break
121
- }
122
- }
123
- }
@@ -1,290 +0,0 @@
1
- import EventEmitter from 'node:events'
2
- import type TypedEmitter from 'typed-emitter'
3
- import { SECOND, wait } from '@atproto/common'
4
- import { decode as cborDecode } from '@atproto/lex-cbor'
5
- import { DatetimeString, DidString, HandleString } from '@atproto/syntax'
6
- import { AccountStatus } from '../account-manager/helpers/account.js'
7
- import { Crawlers } from '../crawlers.js'
8
- import { seqLogger as log } from '../logger.js'
9
- import { CommitDataWithOps, SyncEvtData } from '../repo/index.js'
10
- import {
11
- RepoSeqEntry,
12
- RepoSeqInsert,
13
- SequencerDb,
14
- getDb,
15
- getMigrator,
16
- } from './db/index.js'
17
- import {
18
- AccountEvt,
19
- CommitEvt,
20
- IdentityEvt,
21
- SeqEvt,
22
- SyncEvt,
23
- formatSeqAccountEvt,
24
- formatSeqCommit,
25
- formatSeqIdentityEvt,
26
- formatSeqSyncEvt,
27
- syncEvtDataFromCommit,
28
- } from './events.js'
29
-
30
- export * from './events.js'
31
-
32
- export class Sequencer extends (EventEmitter as new () => SequencerEmitter) {
33
- db: SequencerDb
34
- destroyed = false
35
- pollPromise: Promise<void> | null = null
36
- triesWithNoResults = 0
37
-
38
- constructor(
39
- public dbLocation: string,
40
- public crawlers: Crawlers,
41
- public lastSeen = 0,
42
- disableWalAutoCheckpoint = false,
43
- ) {
44
- super()
45
- // note: this does not err when surpassed, just prints a warning to stderr
46
- this.setMaxListeners(100)
47
- this.db = getDb(dbLocation, disableWalAutoCheckpoint)
48
- }
49
-
50
- async start() {
51
- await this.db.ensureWal()
52
- const migrator = getMigrator(this.db)
53
- await migrator.migrateToLatestOrThrow()
54
- const curr = await this.curr()
55
- this.lastSeen = curr ?? 0
56
- if (this.pollPromise === null) {
57
- this.pollPromise = this.pollDb()
58
- }
59
- }
60
-
61
- async destroy() {
62
- this.destroyed = true
63
- if (this.pollPromise) {
64
- await this.pollPromise
65
- }
66
- this.emit('close')
67
- }
68
-
69
- async curr(): Promise<number | null> {
70
- const got = await this.db.db
71
- .selectFrom('repo_seq')
72
- .selectAll()
73
- .orderBy('seq', 'desc')
74
- .limit(1)
75
- .executeTakeFirst()
76
- return got?.seq ?? null
77
- }
78
-
79
- async next(cursor: number): Promise<SeqRow | null> {
80
- const got = await this.db.db
81
- .selectFrom('repo_seq')
82
- .selectAll()
83
- .where('seq', '>', cursor)
84
- .limit(1)
85
- .orderBy('seq', 'asc')
86
- .executeTakeFirst()
87
- return got || null
88
- }
89
-
90
- async earliestAfterTime(time: string): Promise<SeqRow | null> {
91
- const got = await this.db.db
92
- .selectFrom('repo_seq')
93
- .selectAll()
94
- .where('sequencedAt', '>=', time)
95
- .orderBy('sequencedAt', 'asc')
96
- .limit(1)
97
- .executeTakeFirst()
98
- return got || null
99
- }
100
-
101
- async requestSeqRange(opts: {
102
- earliestSeq?: number
103
- latestSeq?: number
104
- earliestTime?: string
105
- limit?: number
106
- }): Promise<SeqEvt[]> {
107
- const { earliestSeq, latestSeq, earliestTime, limit } = opts
108
-
109
- let seqQb = this.db.db
110
- .selectFrom('repo_seq')
111
- .selectAll()
112
- .orderBy('seq', 'asc')
113
- .where('invalidated', '=', 0)
114
- if (earliestSeq !== undefined) {
115
- seqQb = seqQb.where('seq', '>', earliestSeq)
116
- }
117
- if (latestSeq !== undefined) {
118
- seqQb = seqQb.where('seq', '<=', latestSeq)
119
- }
120
- if (earliestTime !== undefined) {
121
- seqQb = seqQb.where('sequencedAt', '>=', earliestTime)
122
- }
123
- if (limit !== undefined) {
124
- seqQb = seqQb.limit(limit)
125
- }
126
-
127
- const rows = await seqQb.execute()
128
- if (rows.length < 1) {
129
- return []
130
- }
131
-
132
- return parseRepoSeqRows(rows)
133
- }
134
-
135
- private async pollDb(): Promise<void> {
136
- if (this.destroyed) return
137
- // if already polling, do not start another poll
138
- try {
139
- const evts = await this.requestSeqRange({
140
- earliestSeq: this.lastSeen,
141
- limit: 1000,
142
- })
143
- if (evts.length > 0) {
144
- this.triesWithNoResults = 0
145
- this.emit('events', evts)
146
- this.lastSeen = evts.at(-1)?.seq ?? this.lastSeen
147
- } else {
148
- await this.exponentialBackoff()
149
- }
150
- this.pollPromise = this.pollDb()
151
- } catch (err) {
152
- log.error({ err, lastSeen: this.lastSeen }, 'sequencer failed to poll db')
153
- await this.exponentialBackoff()
154
- this.pollPromise = this.pollDb()
155
- }
156
- }
157
-
158
- // when no results, exponential backoff on pulling, with a max of a second wait
159
- private async exponentialBackoff(): Promise<void> {
160
- this.triesWithNoResults++
161
- const waitTime = Math.min(Math.pow(2, this.triesWithNoResults), SECOND)
162
- await wait(waitTime)
163
- }
164
-
165
- async sequenceEvts(events: readonly RepoSeqInsert[]): Promise<number[]> {
166
- if (!events.length) return []
167
- const rows = await this.db.executeWithRetry(
168
- this.db.db.insertInto('repo_seq').values(events).returning('seq'),
169
- )
170
- this.crawlers.notifyOfUpdate()
171
- return rows.map((row) => row.seq)
172
- }
173
-
174
- public async sequenceCommit(
175
- did: DidString,
176
- commitData: CommitDataWithOps,
177
- ): Promise<void> {
178
- await this.sequenceEvts([await formatSeqCommit(did, commitData)])
179
- }
180
-
181
- public async sequenceSync(did: DidString, data: SyncEvtData): Promise<void> {
182
- await this.sequenceEvts([await formatSeqSyncEvt(did, data)])
183
- }
184
-
185
- public async sequenceIdentity(
186
- did: DidString,
187
- handle?: HandleString,
188
- ): Promise<void> {
189
- await this.sequenceEvts([await formatSeqIdentityEvt(did, handle)])
190
- }
191
-
192
- public async sequenceAccount(
193
- did: DidString,
194
- status: AccountStatus,
195
- ): Promise<void> {
196
- await this.sequenceEvts([await formatSeqAccountEvt(did, status)])
197
- }
198
-
199
- public async sequenceAccountCreation(
200
- did: DidString,
201
- handle: HandleString,
202
- commit: CommitDataWithOps,
203
- ): Promise<void> {
204
- // Atomically sequence all events
205
- await this.sequenceEvts([
206
- await formatSeqIdentityEvt(did, handle),
207
- await formatSeqAccountEvt(did, AccountStatus.Active),
208
- await formatSeqCommit(did, commit),
209
- await formatSeqSyncEvt(did, syncEvtDataFromCommit(commit)),
210
- ])
211
- }
212
-
213
- public async sequenceAccountActivation(
214
- did: DidString,
215
- handle: HandleString,
216
- status: AccountStatus,
217
- syncData: SyncEvtData,
218
- ): Promise<void> {
219
- // Atomically sequence all events
220
- await this.sequenceEvts([
221
- await formatSeqAccountEvt(did, status),
222
- await formatSeqIdentityEvt(did, handle),
223
- await formatSeqSyncEvt(did, syncData),
224
- ])
225
- }
226
-
227
- public async sequenceAccountDeletion(did: DidString) {
228
- const [seq] = await this.sequenceEvts([
229
- await formatSeqAccountEvt(did, AccountStatus.Deleted),
230
- ])
231
- await this.db.executeWithRetry(
232
- this.db.db
233
- .deleteFrom('repo_seq')
234
- .where('did', '=', did)
235
- .where('seq', '!=', seq),
236
- )
237
- }
238
- }
239
-
240
- export const parseRepoSeqRows = (rows: RepoSeqEntry[]): SeqEvt[] => {
241
- const seqEvts: SeqEvt[] = []
242
- for (const row of rows) {
243
- // should never hit this because of WHERE clause
244
- if (row.seq === null) {
245
- continue
246
- }
247
- const evt = cborDecode(row.event)
248
- if (row.eventType === 'append') {
249
- seqEvts.push({
250
- type: 'commit',
251
- seq: row.seq,
252
- time: row.sequencedAt as DatetimeString,
253
- evt: evt as CommitEvt,
254
- })
255
- } else if (row.eventType === 'sync') {
256
- seqEvts.push({
257
- type: 'sync',
258
- seq: row.seq,
259
- time: row.sequencedAt as DatetimeString,
260
- evt: evt as SyncEvt,
261
- })
262
- } else if (row.eventType === 'identity') {
263
- seqEvts.push({
264
- type: 'identity',
265
- seq: row.seq,
266
- time: row.sequencedAt as DatetimeString,
267
- evt: evt as IdentityEvt,
268
- })
269
- } else if (row.eventType === 'account') {
270
- seqEvts.push({
271
- type: 'account',
272
- seq: row.seq,
273
- time: row.sequencedAt as DatetimeString,
274
- evt: evt as AccountEvt,
275
- })
276
- }
277
- }
278
- return seqEvts
279
- }
280
-
281
- type SeqRow = RepoSeqEntry
282
-
283
- type SequencerEvents = {
284
- events: (evts: SeqEvt[]) => void
285
- close: () => void
286
- }
287
-
288
- export type SequencerEmitter = TypedEmitter.default<SequencerEvents>
289
-
290
- export default Sequencer
@@ -1,16 +0,0 @@
1
- import compression from 'compression'
2
- import express from 'express'
3
-
4
- export default function () {
5
- return compression({
6
- filter,
7
- })
8
- }
9
-
10
- function filter(_req: express.Request, res: express.Response) {
11
- const contentType = res.getHeader('Content-type')
12
- if (contentType === 'application/vnd.ipld.car') {
13
- return true
14
- }
15
- return compression.filter(_req, res)
16
- }
package/src/util/debug.ts DELETED
@@ -1,10 +0,0 @@
1
- export const debugCatch = <Func extends (...args: any[]) => any>(fn: Func) => {
2
- return async (...args: Parameters<Func>) => {
3
- try {
4
- return (await fn(...args)) as Awaited<ReturnType<Func>>
5
- } catch (err) {
6
- console.error(err)
7
- throw err
8
- }
9
- }
10
- }
package/src/util/http.ts DELETED
@@ -1,31 +0,0 @@
1
- import { ServerResponse } from 'node:http'
2
-
3
- /**
4
- * Set or appends a value to the `Vary` header in the response, only if the
5
- * value is not already present.
6
- */
7
- export function appendVary(res: ServerResponse, value: string) {
8
- if (!varyContains(res, value.toLowerCase())) {
9
- res.appendHeader('Vary', value)
10
- }
11
- }
12
-
13
- function varyContains(res: ServerResponse, searchValue: string) {
14
- const headerValue = res.getHeader('Vary')
15
- switch (typeof headerValue) {
16
- case 'string':
17
- return varyStringContains(headerValue, searchValue)
18
- case 'object':
19
- // headerValue is a string[] here
20
- return headerValue.some((h) => varyStringContains(h, searchValue))
21
- default:
22
- return false
23
- }
24
- }
25
-
26
- function varyStringContains(headerValue: string, searchValue: string): boolean {
27
- return headerValue
28
- .split(',')
29
- .map((v) => v.trim().toLowerCase())
30
- .some((v) => v === searchValue || v === `*`)
31
- }
package/src/util/types.ts DELETED
@@ -1,7 +0,0 @@
1
- export type Simplify<T> = {
2
- [K in keyof T]: T[K]
3
- } & NonNullable<unknown>
4
-
5
- export type WithRequired<T, K extends keyof T> = Simplify<
6
- Omit<T, K> & Required<Pick<T, K>>
7
- >