@atproto/pds 0.5.11 → 0.5.14

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 (322) hide show
  1. package/CHANGELOG.md +46 -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/package.json +42 -38
  10. package/build.templates.cjs +0 -22
  11. package/example.env +0 -42
  12. package/jest.config.cjs +0 -27
  13. package/src/account-manager/account-manager.ts +0 -916
  14. package/src/account-manager/db/index.ts +0 -21
  15. package/src/account-manager/db/migrations/001-init.ts +0 -115
  16. package/src/account-manager/db/migrations/002-account-deactivation.ts +0 -17
  17. package/src/account-manager/db/migrations/003-privileged-app-passwords.ts +0 -12
  18. package/src/account-manager/db/migrations/004-oauth.ts +0 -122
  19. package/src/account-manager/db/migrations/005-oauth-account-management.ts +0 -136
  20. package/src/account-manager/db/migrations/006-oauth-permission-sets.ts +0 -20
  21. package/src/account-manager/db/migrations/007-lexicon-failures-index.ts +0 -14
  22. package/src/account-manager/db/migrations/index.ts +0 -17
  23. package/src/account-manager/db/schema/account-device.ts +0 -14
  24. package/src/account-manager/db/schema/account.ts +0 -16
  25. package/src/account-manager/db/schema/actor.ts +0 -17
  26. package/src/account-manager/db/schema/app-password.ts +0 -13
  27. package/src/account-manager/db/schema/authorization-request.ts +0 -30
  28. package/src/account-manager/db/schema/authorized-client.ts +0 -23
  29. package/src/account-manager/db/schema/device.ts +0 -18
  30. package/src/account-manager/db/schema/email-token.ts +0 -19
  31. package/src/account-manager/db/schema/index.ts +0 -43
  32. package/src/account-manager/db/schema/invite-code.ts +0 -24
  33. package/src/account-manager/db/schema/lexicon.ts +0 -15
  34. package/src/account-manager/db/schema/refresh-token.ts +0 -11
  35. package/src/account-manager/db/schema/repo-root.ts +0 -12
  36. package/src/account-manager/db/schema/token.ts +0 -38
  37. package/src/account-manager/db/schema/used-refresh-token.ts +0 -13
  38. package/src/account-manager/helpers/account-device.ts +0 -63
  39. package/src/account-manager/helpers/account.ts +0 -355
  40. package/src/account-manager/helpers/auth.ts +0 -222
  41. package/src/account-manager/helpers/authorization-request.ts +0 -90
  42. package/src/account-manager/helpers/authorized-client.ts +0 -75
  43. package/src/account-manager/helpers/device.ts +0 -47
  44. package/src/account-manager/helpers/email-token.ts +0 -87
  45. package/src/account-manager/helpers/invite.ts +0 -263
  46. package/src/account-manager/helpers/lexicon.ts +0 -67
  47. package/src/account-manager/helpers/password.ts +0 -136
  48. package/src/account-manager/helpers/repo.ts +0 -24
  49. package/src/account-manager/helpers/scrypt.ts +0 -53
  50. package/src/account-manager/helpers/token.ts +0 -158
  51. package/src/account-manager/helpers/used-refresh-token.ts +0 -30
  52. package/src/account-manager/oauth-store.ts +0 -880
  53. package/src/account-manager/scope-reference-getter.ts +0 -106
  54. package/src/actor-store/actor-store-reader.ts +0 -45
  55. package/src/actor-store/actor-store-resources.ts +0 -8
  56. package/src/actor-store/actor-store-transactor.ts +0 -31
  57. package/src/actor-store/actor-store-writer.ts +0 -17
  58. package/src/actor-store/actor-store.ts +0 -210
  59. package/src/actor-store/blob/reader.ts +0 -160
  60. package/src/actor-store/blob/transactor.ts +0 -383
  61. package/src/actor-store/db/index.ts +0 -20
  62. package/src/actor-store/db/migrations/001-init.ts +0 -105
  63. package/src/actor-store/db/migrations/index.ts +0 -5
  64. package/src/actor-store/db/schema/account-pref.ts +0 -11
  65. package/src/actor-store/db/schema/backlink.ts +0 -9
  66. package/src/actor-store/db/schema/blob.ts +0 -14
  67. package/src/actor-store/db/schema/index.ts +0 -23
  68. package/src/actor-store/db/schema/record-blob.ts +0 -8
  69. package/src/actor-store/db/schema/record.ts +0 -14
  70. package/src/actor-store/db/schema/repo-block.ts +0 -10
  71. package/src/actor-store/db/schema/repo-root.ts +0 -10
  72. package/src/actor-store/migrate.ts +0 -39
  73. package/src/actor-store/preference/reader.ts +0 -48
  74. package/src/actor-store/preference/transactor.ts +0 -55
  75. package/src/actor-store/preference/util.ts +0 -39
  76. package/src/actor-store/record/reader.ts +0 -374
  77. package/src/actor-store/record/transactor.ts +0 -111
  78. package/src/actor-store/repo/reader.ts +0 -31
  79. package/src/actor-store/repo/sql-repo-reader.ts +0 -150
  80. package/src/actor-store/repo/sql-repo-transactor.ts +0 -105
  81. package/src/actor-store/repo/transactor.ts +0 -227
  82. package/src/api/app/bsky/actor/getPreferences.ts +0 -57
  83. package/src/api/app/bsky/actor/getProfile.ts +0 -41
  84. package/src/api/app/bsky/actor/getProfiles.ts +0 -51
  85. package/src/api/app/bsky/actor/index.ts +0 -13
  86. package/src/api/app/bsky/actor/putPreferences.ts +0 -62
  87. package/src/api/app/bsky/feed/getActorLikes.ts +0 -63
  88. package/src/api/app/bsky/feed/getAuthorFeed.ts +0 -84
  89. package/src/api/app/bsky/feed/getFeed.ts +0 -47
  90. package/src/api/app/bsky/feed/getPostThread.ts +0 -251
  91. package/src/api/app/bsky/feed/getTimeline.ts +0 -50
  92. package/src/api/app/bsky/feed/index.ts +0 -15
  93. package/src/api/app/bsky/index.ts +0 -11
  94. package/src/api/app/bsky/notification/index.ts +0 -7
  95. package/src/api/app/bsky/notification/registerPush.ts +0 -71
  96. package/src/api/app/bsky/util/resolver.ts +0 -20
  97. package/src/api/com/atproto/admin/deleteAccount.ts +0 -22
  98. package/src/api/com/atproto/admin/disableAccountInvites.ts +0 -18
  99. package/src/api/com/atproto/admin/disableInviteCodes.ts +0 -21
  100. package/src/api/com/atproto/admin/enableAccountInvites.ts +0 -18
  101. package/src/api/com/atproto/admin/getAccountInfo.ts +0 -32
  102. package/src/api/com/atproto/admin/getAccountInfos.ts +0 -34
  103. package/src/api/com/atproto/admin/getInviteCodes.ts +0 -126
  104. package/src/api/com/atproto/admin/getSubjectStatus.ts +0 -76
  105. package/src/api/com/atproto/admin/index.ts +0 -31
  106. package/src/api/com/atproto/admin/sendEmail.ts +0 -47
  107. package/src/api/com/atproto/admin/updateAccountEmail.ts +0 -32
  108. package/src/api/com/atproto/admin/updateAccountHandle.ts +0 -47
  109. package/src/api/com/atproto/admin/updateAccountPassword.ts +0 -34
  110. package/src/api/com/atproto/admin/updateSubjectStatus.ts +0 -68
  111. package/src/api/com/atproto/admin/util.ts +0 -66
  112. package/src/api/com/atproto/identity/getRecommendedDidCredentials.ts +0 -50
  113. package/src/api/com/atproto/identity/index.ts +0 -17
  114. package/src/api/com/atproto/identity/requestPlcOperationSignature.ts +0 -59
  115. package/src/api/com/atproto/identity/resolveHandle.ts +0 -50
  116. package/src/api/com/atproto/identity/signPlcOperation.ts +0 -85
  117. package/src/api/com/atproto/identity/submitPlcOperation.ts +0 -65
  118. package/src/api/com/atproto/identity/updateHandle.ts +0 -66
  119. package/src/api/com/atproto/index.ts +0 -19
  120. package/src/api/com/atproto/moderation/createReport.ts +0 -41
  121. package/src/api/com/atproto/moderation/index.ts +0 -7
  122. package/src/api/com/atproto/repo/applyWrites.ts +0 -226
  123. package/src/api/com/atproto/repo/createRecord.ts +0 -143
  124. package/src/api/com/atproto/repo/deleteRecord.ts +0 -122
  125. package/src/api/com/atproto/repo/describeRepo.ts +0 -43
  126. package/src/api/com/atproto/repo/getRecord.ts +0 -40
  127. package/src/api/com/atproto/repo/importRepo.ts +0 -101
  128. package/src/api/com/atproto/repo/index.ts +0 -25
  129. package/src/api/com/atproto/repo/listMissingBlobs.ts +0 -29
  130. package/src/api/com/atproto/repo/listRecords.ts +0 -36
  131. package/src/api/com/atproto/repo/putRecord.ts +0 -211
  132. package/src/api/com/atproto/repo/uploadBlob.ts +0 -60
  133. package/src/api/com/atproto/server/activateAccount.ts +0 -37
  134. package/src/api/com/atproto/server/checkAccountStatus.ts +0 -51
  135. package/src/api/com/atproto/server/confirmEmail.ts +0 -39
  136. package/src/api/com/atproto/server/createAccount.ts +0 -327
  137. package/src/api/com/atproto/server/createAppPassword.ts +0 -53
  138. package/src/api/com/atproto/server/createInviteCode.ts +0 -38
  139. package/src/api/com/atproto/server/createInviteCodes.ts +0 -42
  140. package/src/api/com/atproto/server/createSession.ts +0 -97
  141. package/src/api/com/atproto/server/deactivateAccount.ts +0 -41
  142. package/src/api/com/atproto/server/deleteAccount.ts +0 -85
  143. package/src/api/com/atproto/server/deleteSession.ts +0 -23
  144. package/src/api/com/atproto/server/describeServer.ts +0 -29
  145. package/src/api/com/atproto/server/getAccountInviteCodes.ts +0 -142
  146. package/src/api/com/atproto/server/getServiceAuth.ts +0 -111
  147. package/src/api/com/atproto/server/getSession.ts +0 -80
  148. package/src/api/com/atproto/server/index.ts +0 -55
  149. package/src/api/com/atproto/server/listAppPasswords.ts +0 -45
  150. package/src/api/com/atproto/server/refreshSession.ts +0 -72
  151. package/src/api/com/atproto/server/requestAccountDelete.ts +0 -66
  152. package/src/api/com/atproto/server/requestEmailConfirmation.ts +0 -68
  153. package/src/api/com/atproto/server/requestEmailUpdate.ts +0 -86
  154. package/src/api/com/atproto/server/requestPasswordReset.ts +0 -52
  155. package/src/api/com/atproto/server/reserveSigningKey.ts +0 -15
  156. package/src/api/com/atproto/server/resetPassword.ts +0 -50
  157. package/src/api/com/atproto/server/revokeAppPassword.ts +0 -42
  158. package/src/api/com/atproto/server/updateEmail.ts +0 -52
  159. package/src/api/com/atproto/server/util.ts +0 -136
  160. package/src/api/com/atproto/sync/deprecated/getCheckout.ts +0 -27
  161. package/src/api/com/atproto/sync/deprecated/getHead.ts +0 -33
  162. package/src/api/com/atproto/sync/getBlob.ts +0 -61
  163. package/src/api/com/atproto/sync/getBlocks.ts +0 -37
  164. package/src/api/com/atproto/sync/getLatestCommit.ts +0 -33
  165. package/src/api/com/atproto/sync/getRecord.ts +0 -49
  166. package/src/api/com/atproto/sync/getRepo.ts +0 -75
  167. package/src/api/com/atproto/sync/getRepoStatus.ts +0 -34
  168. package/src/api/com/atproto/sync/index.ts +0 -27
  169. package/src/api/com/atproto/sync/listBlobs.ts +0 -33
  170. package/src/api/com/atproto/sync/listRepos.ts +0 -74
  171. package/src/api/com/atproto/sync/subscribeRepos.ts +0 -73
  172. package/src/api/com/atproto/sync/util.ts +0 -37
  173. package/src/api/com/atproto/temp/checkSignupQueue.ts +0 -34
  174. package/src/api/com/atproto/temp/index.ts +0 -7
  175. package/src/api/index.ts +0 -10
  176. package/src/api/proxy.ts +0 -44
  177. package/src/app-view.ts +0 -24
  178. package/src/auth-output.ts +0 -52
  179. package/src/auth-routes.ts +0 -64
  180. package/src/auth-scope.ts +0 -40
  181. package/src/auth-verifier.ts +0 -668
  182. package/src/background.ts +0 -65
  183. package/src/basic-routes.ts +0 -52
  184. package/src/bsky-app-view.ts +0 -33
  185. package/src/config/config.ts +0 -553
  186. package/src/config/env.ts +0 -167
  187. package/src/config/index.ts +0 -3
  188. package/src/config/secrets.ts +0 -54
  189. package/src/context.ts +0 -523
  190. package/src/crawlers.ts +0 -46
  191. package/src/db/cast.ts +0 -52
  192. package/src/db/db.ts +0 -140
  193. package/src/db/index.ts +0 -4
  194. package/src/db/migrator.ts +0 -40
  195. package/src/db/pagination.ts +0 -132
  196. package/src/db/tables/moderation.ts +0 -80
  197. package/src/db/util.ts +0 -108
  198. package/src/did-cache/db/index.ts +0 -21
  199. package/src/did-cache/db/migrations.ts +0 -17
  200. package/src/did-cache/db/schema.ts +0 -9
  201. package/src/did-cache/index.ts +0 -131
  202. package/src/disk-blobstore.ts +0 -172
  203. package/src/error.ts +0 -19
  204. package/src/handle/explicit-slurs.ts +0 -22
  205. package/src/handle/index.ts +0 -49
  206. package/src/handle/reserved.ts +0 -1059
  207. package/src/image/image-url-builder.ts +0 -16
  208. package/src/index.ts +0 -189
  209. package/src/lexicons.ts +0 -4
  210. package/src/logger.ts +0 -35
  211. package/src/mailer/index.ts +0 -111
  212. package/src/mailer/moderation.ts +0 -33
  213. package/src/mailer/templates/confirm-email.d.ts +0 -4
  214. package/src/mailer/templates/confirm-email.hbs +0 -158
  215. package/src/mailer/templates/delete-account.d.ts +0 -4
  216. package/src/mailer/templates/delete-account.hbs +0 -156
  217. package/src/mailer/templates/plc-operation.d.ts +0 -4
  218. package/src/mailer/templates/plc-operation.hbs +0 -153
  219. package/src/mailer/templates/reset-password.d.ts +0 -4
  220. package/src/mailer/templates/reset-password.hbs +0 -154
  221. package/src/mailer/templates/update-email.d.ts +0 -4
  222. package/src/mailer/templates/update-email.hbs +0 -153
  223. package/src/mailer/templates.ts +0 -17
  224. package/src/pipethrough.ts +0 -716
  225. package/src/rate-limits.ts +0 -59
  226. package/src/read-after-write/index.ts +0 -3
  227. package/src/read-after-write/types.ts +0 -35
  228. package/src/read-after-write/util.ts +0 -101
  229. package/src/read-after-write/viewer.ts +0 -290
  230. package/src/redis.ts +0 -25
  231. package/src/repo/index.ts +0 -2
  232. package/src/repo/prepare.ts +0 -266
  233. package/src/repo/types.ts +0 -65
  234. package/src/scripts/README.md +0 -40
  235. package/src/scripts/index.ts +0 -20
  236. package/src/scripts/publish-identity.ts +0 -60
  237. package/src/scripts/rebuild-repo.ts +0 -119
  238. package/src/scripts/rotate-keys.ts +0 -146
  239. package/src/scripts/sequencer-recovery/index.ts +0 -23
  240. package/src/scripts/sequencer-recovery/recoverer.ts +0 -297
  241. package/src/scripts/sequencer-recovery/recovery-db.ts +0 -65
  242. package/src/scripts/sequencer-recovery/repair-repos.ts +0 -49
  243. package/src/scripts/sequencer-recovery/user-queues.ts +0 -44
  244. package/src/scripts/util.ts +0 -7
  245. package/src/sequencer/db/index.ts +0 -21
  246. package/src/sequencer/db/migrations/001-init.ts +0 -35
  247. package/src/sequencer/db/migrations/index.ts +0 -5
  248. package/src/sequencer/db/schema.ts +0 -19
  249. package/src/sequencer/events.ts +0 -199
  250. package/src/sequencer/index.ts +0 -3
  251. package/src/sequencer/outbox.ts +0 -123
  252. package/src/sequencer/sequencer.ts +0 -290
  253. package/src/util/compression.ts +0 -16
  254. package/src/util/debug.ts +0 -10
  255. package/src/util/http.ts +0 -31
  256. package/src/util/types.ts +0 -7
  257. package/src/well-known.ts +0 -30
  258. package/test.env +0 -2
  259. package/tests/__snapshots__/takedown-appeal.test.ts.snap +0 -43
  260. package/tests/_oauth_client_assets_middleware.ts +0 -23
  261. package/tests/_puppeteer.ts +0 -147
  262. package/tests/_types.d.ts +0 -16
  263. package/tests/_util.ts +0 -191
  264. package/tests/account-deactivation.test.ts +0 -204
  265. package/tests/account-deletion.test.ts +0 -300
  266. package/tests/account-manager.test.ts +0 -462
  267. package/tests/account-migration.test.ts +0 -221
  268. package/tests/account-status.test.ts +0 -206
  269. package/tests/account.test.ts +0 -595
  270. package/tests/app-passwords.test.ts +0 -262
  271. package/tests/auth.test.ts +0 -405
  272. package/tests/blob-deletes.test.ts +0 -204
  273. package/tests/create-post.test.ts +0 -79
  274. package/tests/crud.test.ts +0 -1595
  275. package/tests/db.test.ts +0 -170
  276. package/tests/email-confirmation.test.ts +0 -227
  277. package/tests/entryway-mock.ts +0 -323
  278. package/tests/entryway.test.ts +0 -145
  279. package/tests/file-uploads.test.ts +0 -301
  280. package/tests/get-service-auth.test.ts +0 -81
  281. package/tests/handle-validation.test.ts +0 -56
  282. package/tests/handles.test.ts +0 -274
  283. package/tests/invite-codes.test.ts +0 -367
  284. package/tests/invites-admin.test.ts +0 -252
  285. package/tests/moderation.test.ts +0 -280
  286. package/tests/moderator-auth.test.ts +0 -177
  287. package/tests/oauth.test.ts +0 -334
  288. package/tests/plc-operations.test.ts +0 -239
  289. package/tests/preferences.test.ts +0 -352
  290. package/tests/proxied/__snapshots__/admin.test.ts.snap +0 -516
  291. package/tests/proxied/__snapshots__/feedgen.test.ts.snap +0 -215
  292. package/tests/proxied/__snapshots__/views.test.ts.snap +0 -4456
  293. package/tests/proxied/admin.test.ts +0 -340
  294. package/tests/proxied/feedgen.test.ts +0 -66
  295. package/tests/proxied/notif.test.ts +0 -85
  296. package/tests/proxied/procedures.test.ts +0 -175
  297. package/tests/proxied/proxy-catchall.test.ts +0 -256
  298. package/tests/proxied/proxy-header.test.ts +0 -239
  299. package/tests/proxied/proxy-oauth-aud.test.ts +0 -182
  300. package/tests/proxied/read-after-write.test.ts +0 -382
  301. package/tests/proxied/views.test.ts +0 -608
  302. package/tests/races.test.ts +0 -89
  303. package/tests/rate-limits.test.ts +0 -70
  304. package/tests/recovery.test.ts +0 -180
  305. package/tests/seeds/basic.ts +0 -165
  306. package/tests/seeds/follows.ts +0 -57
  307. package/tests/seeds/likes.ts +0 -14
  308. package/tests/seeds/reposts.ts +0 -18
  309. package/tests/seeds/thread.ts +0 -40
  310. package/tests/seeds/users-bulk.ts +0 -246
  311. package/tests/seeds/users.ts +0 -67
  312. package/tests/sequencer.test.ts +0 -251
  313. package/tests/server.test.ts +0 -151
  314. package/tests/sync/invertible-ops.test.ts +0 -99
  315. package/tests/sync/list.test.ts +0 -43
  316. package/tests/sync/subscribe-repos.test.ts +0 -672
  317. package/tests/sync/sync.test.ts +0 -316
  318. package/tests/takedown-appeal.test.ts +0 -166
  319. package/tsconfig.build.json +0 -9
  320. package/tsconfig.build.tsbuildinfo +0 -1
  321. package/tsconfig.json +0 -7
  322. 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
- >