@atproto/bsky 0.0.279 → 0.0.281

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 (97) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/dist/api/app/bsky/bookmark/getBookmarks.js +1 -1
  3. package/dist/api/app/bsky/bookmark/getBookmarks.js.map +1 -1
  4. package/dist/api/app/bsky/contact/getMatches.js +1 -1
  5. package/dist/api/app/bsky/contact/getMatches.js.map +1 -1
  6. package/dist/api/app/bsky/graph/getBlocks.js +1 -1
  7. package/dist/api/app/bsky/graph/getBlocks.js.map +1 -1
  8. package/dist/api/app/bsky/graph/getFollowers.js +1 -1
  9. package/dist/api/app/bsky/graph/getFollowers.js.map +1 -1
  10. package/dist/api/app/bsky/graph/getFollows.js +1 -1
  11. package/dist/api/app/bsky/graph/getFollows.js.map +1 -1
  12. package/dist/api/app/bsky/graph/getKnownFollowers.d.ts.map +1 -1
  13. package/dist/api/app/bsky/graph/getKnownFollowers.js +12 -7
  14. package/dist/api/app/bsky/graph/getKnownFollowers.js.map +1 -1
  15. package/dist/api/app/bsky/graph/getList.js +1 -1
  16. package/dist/api/app/bsky/graph/getList.js.map +1 -1
  17. package/dist/api/app/bsky/graph/getListBlocks.js +1 -1
  18. package/dist/api/app/bsky/graph/getListBlocks.js.map +1 -1
  19. package/dist/api/app/bsky/graph/getListMutes.js +1 -1
  20. package/dist/api/app/bsky/graph/getListMutes.js.map +1 -1
  21. package/dist/api/app/bsky/graph/getMutes.js +1 -1
  22. package/dist/api/app/bsky/graph/getMutes.js.map +1 -1
  23. package/dist/api/app/bsky/graph/getStarterPacksWithMembership.js +1 -1
  24. package/dist/api/app/bsky/graph/getStarterPacksWithMembership.js.map +1 -1
  25. package/dist/api/app/bsky/notification/getPreferences.d.ts +1 -1
  26. package/dist/api/app/bsky/notification/getPreferences.d.ts.map +1 -1
  27. package/dist/api/app/bsky/notification/getPreferences.js +2 -18
  28. package/dist/api/app/bsky/notification/getPreferences.js.map +1 -1
  29. package/dist/api/app/bsky/notification/listActivitySubscriptions.js +1 -1
  30. package/dist/api/app/bsky/notification/listActivitySubscriptions.js.map +1 -1
  31. package/dist/api/app/bsky/notification/listNotifications.d.ts.map +1 -1
  32. package/dist/api/app/bsky/notification/listNotifications.js +3 -18
  33. package/dist/api/app/bsky/notification/listNotifications.js.map +1 -1
  34. package/dist/api/app/bsky/notification/putPreferences.d.ts.map +1 -1
  35. package/dist/api/app/bsky/notification/putPreferences.js +14 -2
  36. package/dist/api/app/bsky/notification/putPreferences.js.map +1 -1
  37. package/dist/api/app/bsky/notification/putPreferencesV2.d.ts +1 -1
  38. package/dist/api/app/bsky/notification/putPreferencesV2.d.ts.map +1 -1
  39. package/dist/api/app/bsky/notification/putPreferencesV2.js +3 -15
  40. package/dist/api/app/bsky/notification/putPreferencesV2.js.map +1 -1
  41. package/dist/api/app/bsky/notification/util.d.ts +5 -0
  42. package/dist/api/app/bsky/notification/util.d.ts.map +1 -1
  43. package/dist/api/app/bsky/notification/util.js +39 -0
  44. package/dist/api/app/bsky/notification/util.js.map +1 -1
  45. package/dist/api/util.js +2 -2
  46. package/dist/api/util.js.map +1 -1
  47. package/dist/data-plane/server/bsync-subscription.d.ts +0 -3
  48. package/dist/data-plane/server/bsync-subscription.d.ts.map +1 -1
  49. package/dist/data-plane/server/bsync-subscription.js +1 -27
  50. package/dist/data-plane/server/bsync-subscription.js.map +1 -1
  51. package/dist/data-plane/server/db/migrations/20260918T214110000Z-remove-priority-notifs.d.ts +4 -0
  52. package/dist/data-plane/server/db/migrations/20260918T214110000Z-remove-priority-notifs.d.ts.map +1 -0
  53. package/dist/data-plane/server/db/migrations/20260918T214110000Z-remove-priority-notifs.js +13 -0
  54. package/dist/data-plane/server/db/migrations/20260918T214110000Z-remove-priority-notifs.js.map +1 -0
  55. package/dist/data-plane/server/db/migrations/index.d.ts +1 -0
  56. package/dist/data-plane/server/db/migrations/index.d.ts.map +1 -1
  57. package/dist/data-plane/server/db/migrations/index.js +1 -0
  58. package/dist/data-plane/server/db/migrations/index.js.map +1 -1
  59. package/dist/data-plane/server/db/tables/actor-state.d.ts +0 -1
  60. package/dist/data-plane/server/db/tables/actor-state.d.ts.map +1 -1
  61. package/dist/data-plane/server/db/tables/actor-state.js.map +1 -1
  62. package/dist/data-plane/server/index.d.ts +2 -2
  63. package/dist/data-plane/server/index.d.ts.map +1 -1
  64. package/dist/data-plane/server/index.js +2 -2
  65. package/dist/data-plane/server/index.js.map +1 -1
  66. package/dist/data-plane/server/routes/follows.d.ts.map +1 -1
  67. package/dist/data-plane/server/routes/follows.js +57 -22
  68. package/dist/data-plane/server/routes/follows.js.map +1 -1
  69. package/dist/data-plane/server/routes/notifs.d.ts.map +1 -1
  70. package/dist/data-plane/server/routes/notifs.js +2 -12
  71. package/dist/data-plane/server/routes/notifs.js.map +1 -1
  72. package/dist/data-plane/server/routes/profile.js +0 -3
  73. package/dist/data-plane/server/routes/profile.js.map +1 -1
  74. package/dist/hydration/actor.d.ts +0 -1
  75. package/dist/hydration/actor.d.ts.map +1 -1
  76. package/dist/hydration/actor.js +8 -10
  77. package/dist/hydration/actor.js.map +1 -1
  78. package/dist/index.d.ts.map +1 -1
  79. package/dist/index.js +1 -0
  80. package/dist/index.js.map +1 -1
  81. package/dist/proto/bsky_connect.d.ts +10 -1
  82. package/dist/proto/bsky_connect.d.ts.map +1 -1
  83. package/dist/proto/bsky_connect.js +10 -1
  84. package/dist/proto/bsky_connect.js.map +1 -1
  85. package/dist/proto/bsky_pb.d.ts +79 -12
  86. package/dist/proto/bsky_pb.d.ts.map +1 -1
  87. package/dist/proto/bsky_pb.js +125 -15
  88. package/dist/proto/bsky_pb.js.map +1 -1
  89. package/dist/proto/bsync_connect.d.ts +1 -10
  90. package/dist/proto/bsync_connect.d.ts.map +1 -1
  91. package/dist/proto/bsync_connect.js +1 -10
  92. package/dist/proto/bsync_connect.js.map +1 -1
  93. package/dist/proto/bsync_pb.d.ts +0 -38
  94. package/dist/proto/bsync_pb.d.ts.map +1 -1
  95. package/dist/proto/bsync_pb.js +0 -57
  96. package/dist/proto/bsync_pb.js.map +1 -1
  97. package/package.json +11 -12
package/CHANGELOG.md CHANGED
@@ -1,5 +1,45 @@
1
1
  # @atproto/bsky
2
2
 
3
+ ## 0.0.281
4
+
5
+ ### Patch Changes
6
+
7
+ - [#5531](https://github.com/bluesky-social/atproto/pull/5531) [`f210723`](https://github.com/bluesky-social/atproto/commit/f21072353415b4362c90f1dd013f014d6cdadca5) Thanks [@rafaeleyng](https://github.com/rafaeleyng)! - Deprecate the legacy notification priority fields.
8
+
9
+ - [#5529](https://github.com/bluesky-social/atproto/pull/5529) [`421111e`](https://github.com/bluesky-social/atproto/commit/421111e98031d2f8780cc37887d66c5f6659cda8) Thanks [@rafaeleyng](https://github.com/rafaeleyng)! - Map legacy priority notification preferences onto granular preferences and remove the old priority state.
10
+
11
+ - [#5522](https://github.com/bluesky-social/atproto/pull/5522) [`d442d03`](https://github.com/bluesky-social/atproto/commit/d442d037d33d68061df6b44d4269b5ee7309c66f) Thanks [@rafaeleyng](https://github.com/rafaeleyng)! - Fix known-followers sampling rollout evaluation to use the viewer DID.
12
+
13
+ - [#5518](https://github.com/bluesky-social/atproto/pull/5518) [`e801c39`](https://github.com/bluesky-social/atproto/commit/e801c39fea8903c6381fd72abd65add426ddcf93) Thanks [@rafaeleyng](https://github.com/rafaeleyng)! - Migrate known-follower enumeration and sampling to rankedfollows behind feature flags.
14
+
15
+ - [#5521](https://github.com/bluesky-social/atproto/pull/5521) [`1eafad7`](https://github.com/bluesky-social/atproto/commit/1eafad71c4f5f8ffc2b6c35ad9f704994d1cd3c4) Thanks [@rafaeleyng](https://github.com/rafaeleyng)! - Fix getKnownFollowers cursor coercion
16
+
17
+ - [#5530](https://github.com/bluesky-social/atproto/pull/5530) [`f86aaa6`](https://github.com/bluesky-social/atproto/commit/f86aaa615b4372c1634011337e42247690d77c5a) Thanks [@rafaeleyng](https://github.com/rafaeleyng)! - Remove the obsolete AddNotifOperation RPC.
18
+
19
+ - [#5523](https://github.com/bluesky-social/atproto/pull/5523) [`d3ceb6b`](https://github.com/bluesky-social/atproto/commit/d3ceb6bbcad0f1a5c9b8daa2c81a4b4259c96e1d) Thanks [@rafaeleyng](https://github.com/rafaeleyng)! - Use sampled known followers for all profile hydration.
20
+
21
+ - [#5538](https://github.com/bluesky-social/atproto/pull/5538) [`9c76c34`](https://github.com/bluesky-social/atproto/commit/9c76c3422ed0c5369871633d2c4ed67a2f61ae33) Thanks [@rafaeleyng](https://github.com/rafaeleyng)! - Deprecate the unsupported `seenAt` notification parameter.
22
+ - Updated dependencies [[`f210723`](https://github.com/bluesky-social/atproto/commit/f21072353415b4362c90f1dd013f014d6cdadca5), [`2480187`](https://github.com/bluesky-social/atproto/commit/2480187c9554ff161227480dd6c0bcaf5e7e3921), [`9c76c34`](https://github.com/bluesky-social/atproto/commit/9c76c3422ed0c5369871633d2c4ed67a2f61ae33), [`30f8149`](https://github.com/bluesky-social/atproto/commit/30f8149e629f9afc3fe41cf66bd8482954d7c052)]:
23
+ - @atproto/api@0.21.0
24
+ - @atproto/xrpc-server@0.13.2
25
+ - @atproto/identity@0.5.14
26
+ - @atproto-labs/xrpc-utils@0.1.23
27
+ - @atproto/sync@0.4.11
28
+ - @atproto/lex@0.3.12
29
+
30
+ ## 0.0.280
31
+
32
+ ### Patch Changes
33
+
34
+ - [#5504](https://github.com/bluesky-social/atproto/pull/5504) [`1ff43e6`](https://github.com/bluesky-social/atproto/commit/1ff43e6e592b1c3ac44e9cd5585370063035a90d) Thanks [@devinivy](https://github.com/devinivy)! - Honor `BSKY_DISABLE_SSRF_PROTECTION` when the AppView resolves identities. The
35
+ mock dataplane server used by dev-env takes a `fetch` option for the same
36
+ purpose.
37
+ - Updated dependencies [[`1ff43e6`](https://github.com/bluesky-social/atproto/commit/1ff43e6e592b1c3ac44e9cd5585370063035a90d), [`f88aa58`](https://github.com/bluesky-social/atproto/commit/f88aa5842df9aba9f208a6073272b43ef9bd089d)]:
38
+ - @atproto/identity@0.5.13
39
+ - @atproto-labs/fetch-node@0.4.0
40
+ - @atproto/sync@0.4.10
41
+ - @atproto/lex@0.3.11
42
+
3
43
  ## 0.0.279
4
44
 
5
45
  ### Patch Changes
@@ -39,7 +39,7 @@ const skeleton = async (input) => {
39
39
  return {
40
40
  actorDid,
41
41
  bookmarkInfos: bookmarks,
42
- cursor: cursor || undefined,
42
+ cursor,
43
43
  };
44
44
  };
45
45
  const hydration = async (input) => {
@@ -1 +1 @@
1
- {"version":3,"file":"getBookmarks.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/bookmark/getBookmarks.ts"],"names":[],"mappings":"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","sourcesContent":["import { mapDefined } from '@atproto/common'\nimport type { Server } from '@atproto/xrpc-server'\nimport type { AppContext } from '../../../../context.js'\nimport type {\n HydrateCtxWithViewer,\n Hydrator,\n} from '../../../../hydration/hydrator.js'\nimport { app } from '../../../../lexicons/index.js'\nimport {\n type HydrationFnInput,\n type PresentationFnInput,\n type SkeletonFnInput,\n createPipeline,\n noRules,\n} from '../../../../pipeline.js'\nimport type { BookmarkInfo } from '../../../../proto/bsky_pb.js'\nimport type { Views } from '../../../../views/index.js'\nimport { fillPage, resHeaders } from '../../../util.js'\n\nexport default function (server: Server, ctx: AppContext) {\n const getBookmarks = createPipeline(\n skeleton,\n hydration,\n noRules, // Blocks are included and handled on views. Mutes are included.\n presentation,\n )\n server.add(app.bsky.bookmark.getBookmarks, {\n auth: ctx.authVerifier.standard,\n handler: async ({ params, auth, req }) => {\n const viewer = auth.credentials.iss\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({\n labelers,\n viewer,\n })\n\n const result = await fillPage({\n cursor: params.cursor,\n limit: params.limit,\n fetch: ({ cursor, limit }) =>\n getBookmarks({ ...params, cursor, limit, hydrateCtx }, ctx),\n items: (r) => r.bookmarks,\n })\n\n return {\n encoding: 'application/json',\n body: result,\n headers: resHeaders({ labelers: hydrateCtx.labelers }),\n }\n },\n })\n}\n\nconst skeleton = async (\n input: SkeletonFnInput<Context, Params>,\n): Promise<SkeletonState> => {\n const { params, ctx } = input\n const actorDid = params.hydrateCtx.viewer\n const { bookmarks, cursor } = await ctx.hydrator.dataplane.getActorBookmarks({\n actorDid: params.hydrateCtx.viewer,\n limit: params.limit,\n cursor: params.cursor,\n })\n return {\n actorDid,\n bookmarkInfos: bookmarks,\n cursor: cursor || undefined,\n }\n}\n\nconst hydration = async (\n input: HydrationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, params, skeleton } = input\n const { bookmarkInfos } = skeleton\n return ctx.hydrator.hydrateBookmarks(bookmarkInfos, params.hydrateCtx)\n}\n\nconst presentation = (\n input: PresentationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, hydration, skeleton } = input\n const { bookmarkInfos, cursor } = skeleton\n const bookmarkViews = mapDefined(bookmarkInfos, (bookmarkInfo) =>\n ctx.views.bookmark(bookmarkInfo.key, hydration),\n )\n return { bookmarks: bookmarkViews, cursor }\n}\n\ntype Context = {\n hydrator: Hydrator\n views: Views\n}\n\ntype Params = app.bsky.bookmark.getBookmarks.$Params & {\n hydrateCtx: HydrateCtxWithViewer\n}\n\ntype SkeletonState = {\n actorDid: string\n bookmarkInfos: BookmarkInfo[]\n cursor?: string\n}\n"]}
1
+ {"version":3,"file":"getBookmarks.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/bookmark/getBookmarks.ts"],"names":[],"mappings":"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","sourcesContent":["import { mapDefined } from '@atproto/common'\nimport type { Server } from '@atproto/xrpc-server'\nimport type { AppContext } from '../../../../context.js'\nimport type {\n HydrateCtxWithViewer,\n Hydrator,\n} from '../../../../hydration/hydrator.js'\nimport { app } from '../../../../lexicons/index.js'\nimport {\n type HydrationFnInput,\n type PresentationFnInput,\n type SkeletonFnInput,\n createPipeline,\n noRules,\n} from '../../../../pipeline.js'\nimport type { BookmarkInfo } from '../../../../proto/bsky_pb.js'\nimport type { Views } from '../../../../views/index.js'\nimport { fillPage, resHeaders } from '../../../util.js'\n\nexport default function (server: Server, ctx: AppContext) {\n const getBookmarks = createPipeline(\n skeleton,\n hydration,\n noRules, // Blocks are included and handled on views. Mutes are included.\n presentation,\n )\n server.add(app.bsky.bookmark.getBookmarks, {\n auth: ctx.authVerifier.standard,\n handler: async ({ params, auth, req }) => {\n const viewer = auth.credentials.iss\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({\n labelers,\n viewer,\n })\n\n const result = await fillPage({\n cursor: params.cursor,\n limit: params.limit,\n fetch: ({ cursor, limit }) =>\n getBookmarks({ ...params, cursor, limit, hydrateCtx }, ctx),\n items: (r) => r.bookmarks,\n })\n\n return {\n encoding: 'application/json',\n body: result,\n headers: resHeaders({ labelers: hydrateCtx.labelers }),\n }\n },\n })\n}\n\nconst skeleton = async (\n input: SkeletonFnInput<Context, Params>,\n): Promise<SkeletonState> => {\n const { params, ctx } = input\n const actorDid = params.hydrateCtx.viewer\n const { bookmarks, cursor } = await ctx.hydrator.dataplane.getActorBookmarks({\n actorDid: params.hydrateCtx.viewer,\n limit: params.limit,\n cursor: params.cursor,\n })\n return {\n actorDid,\n bookmarkInfos: bookmarks,\n cursor,\n }\n}\n\nconst hydration = async (\n input: HydrationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, params, skeleton } = input\n const { bookmarkInfos } = skeleton\n return ctx.hydrator.hydrateBookmarks(bookmarkInfos, params.hydrateCtx)\n}\n\nconst presentation = (\n input: PresentationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, hydration, skeleton } = input\n const { bookmarkInfos, cursor } = skeleton\n const bookmarkViews = mapDefined(bookmarkInfos, (bookmarkInfo) =>\n ctx.views.bookmark(bookmarkInfo.key, hydration),\n )\n return { bookmarks: bookmarkViews, cursor }\n}\n\ntype Context = {\n hydrator: Hydrator\n views: Views\n}\n\ntype Params = app.bsky.bookmark.getBookmarks.$Params & {\n hydrateCtx: HydrateCtxWithViewer\n}\n\ntype SkeletonState = {\n actorDid: string\n bookmarkInfos: BookmarkInfo[]\n cursor?: string\n}\n"]}
@@ -39,7 +39,7 @@ const skeleton = async (input) => {
39
39
  return {
40
40
  actor,
41
41
  subjects: subjects,
42
- cursor: cursor || undefined,
42
+ cursor,
43
43
  };
44
44
  };
45
45
  const hydration = async (input) => {
@@ -1 +1 @@
1
- {"version":3,"file":"getMatches.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/contact/getMatches.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAS5C,OAAO,EAAE,GAAG,EAAE,MAAM,+BAA+B,CAAA;AACnD,OAAO,EAGL,cAAc,GACf,MAAM,yBAAyB,CAAA;AAGhC,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAC3C,OAAO,EAAE,iCAAiC,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAEhF,MAAM,CAAC,OAAO,WAAW,MAAc,EAAE,GAAe;IACtD,MAAM,UAAU,GAAG,cAAc,CAAC,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAA;IAE9E,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE;QACtC,IAAI,EAAE,GAAG,CAAC,YAAY,CAAC,QAAQ;QAC/B,OAAO,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE;YACvC,iCAAiC,CAAC,GAAG,CAAC,CAAA;YAEtC,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAA;YACnC,MAAM,QAAQ,GAAG,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,CAAA;YACrC,MAAM,UAAU,GAAG,MAAM,GAAG,CAAC,QAAQ,CAAC,aAAa,CAAC;gBAClD,QAAQ;gBACR,MAAM;aACP,CAAC,CAAA;YAEF,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC;gBAC5B,MAAM,EAAE,MAAM,CAAC,MAAM;gBACrB,KAAK,EAAE,MAAM,CAAC,KAAK;gBACnB,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE,CAC3B,UAAU,CAAC,EAAE,GAAG,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE,GAAG,CAAC;gBAC3D,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO;aACxB,CAAC,CAAA;YAEF,OAAO;gBACL,QAAQ,EAAE,kBAAkB;gBAC5B,IAAI,EAAE,MAAM;aACb,CAAA;QACH,CAAC;KACF,CAAC,CAAA;AACJ,CAAC;AAED,MAAM,QAAQ,GAAG,KAAK,EACpB,KAAuC,EACf,EAAE;IAC1B,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,CAAA;IAC7B,MAAM,KAAK,GAAG,MAAM,CAAC,UAAU,CAAC,MAAM,CAAA;IACtC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,iBAAiB,CAClD,GAAG,CAAC,aAAa,CAAC,UAAU,CAAC;QAC3B,KAAK,EAAE,MAAM,CAAC,UAAU,CAAC,MAAM;QAC/B,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,MAAM,EAAE,MAAM,CAAC,MAAM;KACtB,CAAC,CACH,CAAA;IACD,OAAO;QACL,KAAK;QACL,QAAQ,EAAE,QAAuB;QACjC,MAAM,EAAE,MAAM,IAAI,SAAS;KAC5B,CAAA;AACH,CAAC,CAAA;AAED,MAAM,SAAS,GAAG,KAAK,EACrB,KAAuD,EACvD,EAAE;IACF,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAA;IACvC,MAAM,EAAE,QAAQ,EAAE,GAAG,QAAQ,CAAA;IAC7B,OAAO,GAAG,CAAC,QAAQ,CAAC,eAAe,CAAC,QAAQ,EAAE,MAAM,CAAC,UAAU,CAAC,CAAA;AAClE,CAAC,CAAA;AAED,MAAM,QAAQ,GAAG,CAAC,MAIjB,EAAE,EAAE;IACH,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,MAAM,CAAA;IAC3C,QAAQ,CAAC,QAAQ,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE;QACvD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,iBAAiB,CAAC,OAAO,EAAE,SAAS,CAAC,CAAA;IACzD,CAAC,CAAC,CAAA;IACF,OAAO,QAAQ,CAAA;AACjB,CAAC,CAAA;AAED,MAAM,YAAY,GAAG,CAAC,KAKrB,EAAE,EAAE;IACH,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,KAAK,CAAA;IAC1C,MAAM,OAAO,GAAG,UAAU,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,EAAE,CACpD,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,SAAS,CAAC,CAClC,CAAA;IACD,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAA;AAC7C,CAAC,CAAA","sourcesContent":["import { mapDefined } from '@atproto/common'\nimport type { DidString } from '@atproto/lex'\nimport type { Server } from '@atproto/xrpc-server'\nimport type { AppContext } from '../../../../context.js'\nimport type {\n HydrateCtxWithViewer,\n HydrationState,\n Hydrator,\n} from '../../../../hydration/hydrator.js'\nimport { app } from '../../../../lexicons/index.js'\nimport {\n type HydrationFnInput,\n type SkeletonFnInput,\n createPipeline,\n} from '../../../../pipeline.js'\nimport type { RolodexClient } from '../../../../rolodex.js'\nimport type { Views } from '../../../../views/index.js'\nimport { fillPage } from '../../../util.js'\nimport { assertRolodexOrThrowUnimplemented, callRolodexClient } from './util.js'\n\nexport default function (server: Server, ctx: AppContext) {\n const getMatches = createPipeline(skeleton, hydration, noBlocks, presentation)\n\n server.add(app.bsky.contact.getMatches, {\n auth: ctx.authVerifier.standard,\n handler: async ({ params, auth, req }) => {\n assertRolodexOrThrowUnimplemented(ctx)\n\n const viewer = auth.credentials.iss\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({\n labelers,\n viewer,\n })\n\n const result = await fillPage({\n cursor: params.cursor,\n limit: params.limit,\n fetch: ({ cursor, limit }) =>\n getMatches({ ...params, cursor, limit, hydrateCtx }, ctx),\n items: (r) => r.matches,\n })\n\n return {\n encoding: 'application/json',\n body: result,\n }\n },\n })\n}\n\nconst skeleton = async (\n input: SkeletonFnInput<Context, Params>,\n): Promise<SkeletonState> => {\n const { params, ctx } = input\n const actor = params.hydrateCtx.viewer\n const { cursor, subjects } = await callRolodexClient(\n ctx.rolodexClient.getMatches({\n actor: params.hydrateCtx.viewer,\n limit: params.limit,\n cursor: params.cursor,\n }),\n )\n return {\n actor,\n subjects: subjects as DidString[],\n cursor: cursor || undefined,\n }\n}\n\nconst hydration = async (\n input: HydrationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, params, skeleton } = input\n const { subjects } = skeleton\n return ctx.hydrator.hydrateProfiles(subjects, params.hydrateCtx)\n}\n\nconst noBlocks = (inputs: {\n ctx: Context\n skeleton: SkeletonState\n hydration: HydrationState\n}) => {\n const { ctx, skeleton, hydration } = inputs\n skeleton.subjects = skeleton.subjects.filter((subject) => {\n return !ctx.views.viewerBlockExists(subject, hydration)\n })\n return skeleton\n}\n\nconst presentation = (input: {\n ctx: Context\n params: Params\n skeleton: SkeletonState\n hydration: HydrationState\n}) => {\n const { ctx, skeleton, hydration } = input\n const matches = mapDefined(skeleton.subjects, (did) =>\n ctx.views.profile(did, hydration),\n )\n return { matches, cursor: skeleton.cursor }\n}\n\ntype Context = {\n hydrator: Hydrator\n rolodexClient: RolodexClient\n views: Views\n}\n\ntype Params = app.bsky.contact.getMatches.$Params & {\n hydrateCtx: HydrateCtxWithViewer\n}\n\ntype SkeletonState = {\n actor: string\n subjects: DidString[]\n cursor?: string\n}\n"]}
1
+ {"version":3,"file":"getMatches.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/contact/getMatches.ts"],"names":[],"mappings":"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","sourcesContent":["import { mapDefined } from '@atproto/common'\nimport type { DidString } from '@atproto/lex'\nimport type { Server } from '@atproto/xrpc-server'\nimport type { AppContext } from '../../../../context.js'\nimport type {\n HydrateCtxWithViewer,\n HydrationState,\n Hydrator,\n} from '../../../../hydration/hydrator.js'\nimport { app } from '../../../../lexicons/index.js'\nimport {\n type HydrationFnInput,\n type SkeletonFnInput,\n createPipeline,\n} from '../../../../pipeline.js'\nimport type { RolodexClient } from '../../../../rolodex.js'\nimport type { Views } from '../../../../views/index.js'\nimport { fillPage } from '../../../util.js'\nimport { assertRolodexOrThrowUnimplemented, callRolodexClient } from './util.js'\n\nexport default function (server: Server, ctx: AppContext) {\n const getMatches = createPipeline(skeleton, hydration, noBlocks, presentation)\n\n server.add(app.bsky.contact.getMatches, {\n auth: ctx.authVerifier.standard,\n handler: async ({ params, auth, req }) => {\n assertRolodexOrThrowUnimplemented(ctx)\n\n const viewer = auth.credentials.iss\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({\n labelers,\n viewer,\n })\n\n const result = await fillPage({\n cursor: params.cursor,\n limit: params.limit,\n fetch: ({ cursor, limit }) =>\n getMatches({ ...params, cursor, limit, hydrateCtx }, ctx),\n items: (r) => r.matches,\n })\n\n return {\n encoding: 'application/json',\n body: result,\n }\n },\n })\n}\n\nconst skeleton = async (\n input: SkeletonFnInput<Context, Params>,\n): Promise<SkeletonState> => {\n const { params, ctx } = input\n const actor = params.hydrateCtx.viewer\n const { cursor, subjects } = await callRolodexClient(\n ctx.rolodexClient.getMatches({\n actor: params.hydrateCtx.viewer,\n limit: params.limit,\n cursor: params.cursor,\n }),\n )\n return {\n actor,\n subjects: subjects as DidString[],\n cursor,\n }\n}\n\nconst hydration = async (\n input: HydrationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, params, skeleton } = input\n const { subjects } = skeleton\n return ctx.hydrator.hydrateProfiles(subjects, params.hydrateCtx)\n}\n\nconst noBlocks = (inputs: {\n ctx: Context\n skeleton: SkeletonState\n hydration: HydrationState\n}) => {\n const { ctx, skeleton, hydration } = inputs\n skeleton.subjects = skeleton.subjects.filter((subject) => {\n return !ctx.views.viewerBlockExists(subject, hydration)\n })\n return skeleton\n}\n\nconst presentation = (input: {\n ctx: Context\n params: Params\n skeleton: SkeletonState\n hydration: HydrationState\n}) => {\n const { ctx, skeleton, hydration } = input\n const matches = mapDefined(skeleton.subjects, (did) =>\n ctx.views.profile(did, hydration),\n )\n return { matches, cursor: skeleton.cursor }\n}\n\ntype Context = {\n hydrator: Hydrator\n rolodexClient: RolodexClient\n views: Views\n}\n\ntype Params = app.bsky.contact.getMatches.$Params & {\n hydrateCtx: HydrateCtxWithViewer\n}\n\ntype SkeletonState = {\n actor: string\n subjects: DidString[]\n cursor?: string\n}\n"]}
@@ -38,7 +38,7 @@ const skeleton = async (input) => {
38
38
  const blockedDids = mapDefined(blockUris, (uri) => blocks.get(uri)?.record.subject);
39
39
  return {
40
40
  blockedDids,
41
- cursor: cursor || undefined,
41
+ cursor,
42
42
  };
43
43
  };
44
44
  const hydration = async (input) => {
@@ -1 +1 @@
1
- {"version":3,"file":"getBlocks.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/graph/getBlocks.ts"],"names":[],"mappings":"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","sourcesContent":["import { mapDefined } from '@atproto/common'\nimport type { AtUriString, DidString } from '@atproto/syntax'\nimport type { Server } from '@atproto/xrpc-server'\nimport type { AppContext } from '../../../../context.js'\nimport type {\n HydrateCtxWithViewer,\n Hydrator,\n} from '../../../../hydration/hydrator.js'\nimport { app } from '../../../../lexicons/index.js'\nimport {\n type HydrationFnInput,\n type PresentationFnInput,\n type SkeletonFnInput,\n createPipeline,\n noRules,\n} from '../../../../pipeline.js'\nimport type { Views } from '../../../../views/index.js'\nimport { clearlyBadCursor, fillPage, resHeaders } from '../../../util.js'\n\nexport default function (server: Server, ctx: AppContext) {\n const getBlocks = createPipeline(skeleton, hydration, noRules, presentation)\n server.add(app.bsky.graph.getBlocks, {\n auth: ctx.authVerifier.standard,\n handler: async ({ params, auth, req }) => {\n const viewer = auth.credentials.iss\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({ labelers, viewer })\n const result = await fillPage({\n cursor: params.cursor,\n limit: params.limit,\n fetch: ({ cursor, limit }) =>\n getBlocks({ ...params, cursor, limit, hydrateCtx }, ctx),\n items: (r) => r.blocks,\n })\n return {\n encoding: 'application/json',\n body: result,\n headers: resHeaders({ labelers: hydrateCtx.labelers }),\n }\n },\n })\n}\n\nconst skeleton = async (\n input: SkeletonFnInput<Context, Params>,\n): Promise<SkeletonState> => {\n const { params, ctx } = input\n if (clearlyBadCursor(params.cursor)) {\n return { blockedDids: [] }\n }\n const { blockUris, cursor } = (await ctx.hydrator.dataplane.getBlocks({\n actorDid: params.hydrateCtx.viewer,\n cursor: params.cursor,\n limit: params.limit,\n })) as {\n blockUris: AtUriString[]\n cursor?: string\n }\n const blocks = await ctx.hydrator.graph.getBlocks(blockUris)\n const blockedDids = mapDefined(\n blockUris,\n (uri) => blocks.get(uri)?.record.subject,\n )\n return {\n blockedDids,\n cursor: cursor || undefined,\n }\n}\n\nconst hydration = async (\n input: HydrationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, params, skeleton } = input\n return ctx.hydrator.hydrateProfiles(skeleton.blockedDids, params.hydrateCtx)\n}\n\nconst presentation = (\n input: PresentationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, hydration, skeleton } = input\n const { blockedDids, cursor } = skeleton\n const blocks = mapDefined(blockedDids, (did) => {\n return ctx.views.profile(did, hydration)\n })\n return { blocks, cursor }\n}\n\ntype Context = {\n hydrator: Hydrator\n views: Views\n}\n\ntype Params = app.bsky.graph.getBlocks.$Params & {\n hydrateCtx: HydrateCtxWithViewer\n}\n\ntype SkeletonState = {\n blockedDids: DidString[]\n cursor?: string\n}\n"]}
1
+ {"version":3,"file":"getBlocks.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/graph/getBlocks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAQ5C,OAAO,EAAE,GAAG,EAAE,MAAM,+BAA+B,CAAA;AACnD,OAAO,EAIL,cAAc,EACd,OAAO,GACR,MAAM,yBAAyB,CAAA;AAEhC,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAEzE,MAAM,CAAC,OAAO,WAAW,MAAc,EAAE,GAAe;IACtD,MAAM,SAAS,GAAG,cAAc,CAAC,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,YAAY,CAAC,CAAA;IAC5E,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE;QACnC,IAAI,EAAE,GAAG,CAAC,YAAY,CAAC,QAAQ;QAC/B,OAAO,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE;YACvC,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAA;YACnC,MAAM,QAAQ,GAAG,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,CAAA;YACrC,MAAM,UAAU,GAAG,MAAM,GAAG,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAA;YACzE,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC;gBAC5B,MAAM,EAAE,MAAM,CAAC,MAAM;gBACrB,KAAK,EAAE,MAAM,CAAC,KAAK;gBACnB,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE,CAC3B,SAAS,CAAC,EAAE,GAAG,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE,GAAG,CAAC;gBAC1D,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM;aACvB,CAAC,CAAA;YACF,OAAO;gBACL,QAAQ,EAAE,kBAAkB;gBAC5B,IAAI,EAAE,MAAM;gBACZ,OAAO,EAAE,UAAU,CAAC,EAAE,QAAQ,EAAE,UAAU,CAAC,QAAQ,EAAE,CAAC;aACvD,CAAA;QACH,CAAC;KACF,CAAC,CAAA;AACJ,CAAC;AAED,MAAM,QAAQ,GAAG,KAAK,EACpB,KAAuC,EACf,EAAE;IAC1B,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,CAAA;IAC7B,IAAI,gBAAgB,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;QACpC,OAAO,EAAE,WAAW,EAAE,EAAE,EAAE,CAAA;IAC5B,CAAC;IACD,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC,SAAS,CAAC;QACpE,QAAQ,EAAE,MAAM,CAAC,UAAU,CAAC,MAAM;QAClC,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,KAAK,EAAE,MAAM,CAAC,KAAK;KACpB,CAAC,CAGD,CAAA;IACD,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,SAAS,CAAC,SAAS,CAAC,CAAA;IAC5D,MAAM,WAAW,GAAG,UAAU,CAC5B,SAAS,EACT,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,OAAO,CACzC,CAAA;IACD,OAAO;QACL,WAAW;QACX,MAAM;KACP,CAAA;AACH,CAAC,CAAA;AAED,MAAM,SAAS,GAAG,KAAK,EACrB,KAAuD,EACvD,EAAE;IACF,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAA;IACvC,OAAO,GAAG,CAAC,QAAQ,CAAC,eAAe,CAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC,UAAU,CAAC,CAAA;AAC9E,CAAC,CAAA;AAED,MAAM,YAAY,GAAG,CACnB,KAA0D,EAC1D,EAAE;IACF,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAA;IAC1C,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,QAAQ,CAAA;IACxC,MAAM,MAAM,GAAG,UAAU,CAAC,WAAW,EAAE,CAAC,GAAG,EAAE,EAAE;QAC7C,OAAO,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,SAAS,CAAC,CAAA;IAC1C,CAAC,CAAC,CAAA;IACF,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,CAAA;AAC3B,CAAC,CAAA","sourcesContent":["import { mapDefined } from '@atproto/common'\nimport type { AtUriString, DidString } from '@atproto/syntax'\nimport type { Server } from '@atproto/xrpc-server'\nimport type { AppContext } from '../../../../context.js'\nimport type {\n HydrateCtxWithViewer,\n Hydrator,\n} from '../../../../hydration/hydrator.js'\nimport { app } from '../../../../lexicons/index.js'\nimport {\n type HydrationFnInput,\n type PresentationFnInput,\n type SkeletonFnInput,\n createPipeline,\n noRules,\n} from '../../../../pipeline.js'\nimport type { Views } from '../../../../views/index.js'\nimport { clearlyBadCursor, fillPage, resHeaders } from '../../../util.js'\n\nexport default function (server: Server, ctx: AppContext) {\n const getBlocks = createPipeline(skeleton, hydration, noRules, presentation)\n server.add(app.bsky.graph.getBlocks, {\n auth: ctx.authVerifier.standard,\n handler: async ({ params, auth, req }) => {\n const viewer = auth.credentials.iss\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({ labelers, viewer })\n const result = await fillPage({\n cursor: params.cursor,\n limit: params.limit,\n fetch: ({ cursor, limit }) =>\n getBlocks({ ...params, cursor, limit, hydrateCtx }, ctx),\n items: (r) => r.blocks,\n })\n return {\n encoding: 'application/json',\n body: result,\n headers: resHeaders({ labelers: hydrateCtx.labelers }),\n }\n },\n })\n}\n\nconst skeleton = async (\n input: SkeletonFnInput<Context, Params>,\n): Promise<SkeletonState> => {\n const { params, ctx } = input\n if (clearlyBadCursor(params.cursor)) {\n return { blockedDids: [] }\n }\n const { blockUris, cursor } = (await ctx.hydrator.dataplane.getBlocks({\n actorDid: params.hydrateCtx.viewer,\n cursor: params.cursor,\n limit: params.limit,\n })) as {\n blockUris: AtUriString[]\n cursor?: string\n }\n const blocks = await ctx.hydrator.graph.getBlocks(blockUris)\n const blockedDids = mapDefined(\n blockUris,\n (uri) => blocks.get(uri)?.record.subject,\n )\n return {\n blockedDids,\n cursor,\n }\n}\n\nconst hydration = async (\n input: HydrationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, params, skeleton } = input\n return ctx.hydrator.hydrateProfiles(skeleton.blockedDids, params.hydrateCtx)\n}\n\nconst presentation = (\n input: PresentationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, hydration, skeleton } = input\n const { blockedDids, cursor } = skeleton\n const blocks = mapDefined(blockedDids, (did) => {\n return ctx.views.profile(did, hydration)\n })\n return { blocks, cursor }\n}\n\ntype Context = {\n hydrator: Hydrator\n views: Views\n}\n\ntype Params = app.bsky.graph.getBlocks.$Params & {\n hydrateCtx: HydrateCtxWithViewer\n}\n\ntype SkeletonState = {\n blockedDids: DidString[]\n cursor?: string\n}\n"]}
@@ -55,7 +55,7 @@ const skeleton = async (input) => {
55
55
  return {
56
56
  subjectDid,
57
57
  followUris: followers.map((f) => f.uri),
58
- cursor: cursor || undefined,
58
+ cursor,
59
59
  };
60
60
  };
61
61
  const hydration = async (input) => {
@@ -1 +1 @@
1
- {"version":3,"file":"getFollowers.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/graph/getFollowers.ts"],"names":[],"mappings":"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","sourcesContent":["import { mapDefined } from '@atproto/common'\nimport type { AtUriString, DidString } from '@atproto/syntax'\nimport { InvalidRequestError, type Server } from '@atproto/xrpc-server'\nimport type { AppContext } from '../../../../context.js'\nimport {\n type HydrateCtx,\n type Hydrator,\n mergeStates,\n} from '../../../../hydration/hydrator.js'\nimport { app } from '../../../../lexicons/index.js'\nimport {\n type HydrationFnInput,\n type PresentationFnInput,\n type RulesFnInput,\n type SkeletonFnInput,\n createPipeline,\n} from '../../../../pipeline.js'\nimport { uriToDid as didFromUri } from '../../../../util/uris.js'\nimport type { Views } from '../../../../views/index.js'\nimport { clearlyBadCursor, fillPage, resHeaders } from '../../../util.js'\n\nexport default function (server: Server, ctx: AppContext) {\n const getFollowers = createPipeline(\n skeleton,\n hydration,\n noBlocks,\n presentation,\n )\n server.add(app.bsky.graph.getFollowers, {\n auth: ctx.authVerifier.optionalStandardOrRole,\n handler: async ({ params, auth, req }) => {\n const { viewer, includeTakedowns, skipViewerBlocks } =\n ctx.authVerifier.parseCreds(auth)\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({\n labelers,\n viewer,\n includeTakedowns,\n skipViewerBlocks,\n })\n\n const result = await fillPage({\n cursor: params.cursor,\n limit: params.limit,\n fetch: ({ cursor, limit }) =>\n getFollowers(\n {\n ...params,\n cursor,\n limit,\n hydrateCtx,\n },\n ctx,\n ),\n items: (r) => r.followers,\n })\n\n return {\n encoding: 'application/json',\n body: result,\n headers: resHeaders({ labelers: hydrateCtx.labelers }),\n }\n },\n })\n}\n\nconst skeleton = async (\n input: SkeletonFnInput<Context, Params>,\n): Promise<SkeletonState> => {\n const { params, ctx } = input\n const [subjectDid] = await ctx.hydrator.actor.getDidsDefined([params.actor])\n if (!subjectDid) {\n throw new InvalidRequestError(`Actor not found: ${params.actor}`)\n }\n if (clearlyBadCursor(params.cursor)) {\n return { subjectDid, followUris: [] }\n }\n const { followers, cursor } = await ctx.hydrator.graph.getActorFollowers({\n did: subjectDid,\n cursor: params.cursor,\n limit: params.limit,\n sort: params.sort,\n })\n return {\n subjectDid,\n followUris: followers.map((f) => f.uri as AtUriString),\n cursor: cursor || undefined,\n }\n}\n\nconst hydration = async (\n input: HydrationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, params, skeleton } = input\n const { followUris, subjectDid } = skeleton\n const followState = await ctx.hydrator.hydrateFollows(\n followUris,\n params.hydrateCtx,\n )\n const dids = [subjectDid]\n if (followState.follows) {\n for (const [uri, follow] of followState.follows) {\n if (follow) {\n dids.push(didFromUri(uri))\n }\n }\n }\n const profileState = await ctx.hydrator.hydrateProfiles(\n dids,\n params.hydrateCtx,\n )\n return mergeStates(followState, profileState)\n}\n\nconst noBlocks = (input: RulesFnInput<Context, Params, SkeletonState>) => {\n const { skeleton, params, hydration, ctx } = input\n const viewer = params.hydrateCtx.viewer\n skeleton.followUris = skeleton.followUris.filter((followUri) => {\n const followerDid = didFromUri(followUri)\n return (\n !hydration.followBlocks?.get(followUri) &&\n (!viewer || !ctx.views.viewerBlockExists(followerDid, hydration))\n )\n })\n return skeleton\n}\n\nconst presentation = (\n input: PresentationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, hydration, skeleton, params } = input\n const { subjectDid, followUris, cursor } = skeleton\n const isNoHosted = (did: DidString) =>\n ctx.views.actorIsNoHosted(did, hydration)\n\n const subject = ctx.views.profile(subjectDid, hydration)\n if (\n !subject ||\n (!params.hydrateCtx.includeTakedowns && isNoHosted(subjectDid))\n ) {\n throw new InvalidRequestError(`Actor not found: ${params.actor}`)\n }\n\n const followers = mapDefined(followUris, (followUri) => {\n const followerDid = didFromUri(followUri)\n if (!params.hydrateCtx.includeTakedowns && isNoHosted(followerDid)) {\n return\n }\n return ctx.views.profile(didFromUri(followUri), hydration)\n })\n\n return { followers, subject, cursor }\n}\n\ntype Context = {\n hydrator: Hydrator\n views: Views\n}\n\ntype Params = app.bsky.graph.getFollowers.$Params & {\n hydrateCtx: HydrateCtx\n}\n\ntype SkeletonState = {\n subjectDid: DidString\n followUris: AtUriString[]\n cursor?: string\n}\n"]}
1
+ {"version":3,"file":"getFollowers.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/graph/getFollowers.ts"],"names":[],"mappings":"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","sourcesContent":["import { mapDefined } from '@atproto/common'\nimport type { AtUriString, DidString } from '@atproto/syntax'\nimport { InvalidRequestError, type Server } from '@atproto/xrpc-server'\nimport type { AppContext } from '../../../../context.js'\nimport {\n type HydrateCtx,\n type Hydrator,\n mergeStates,\n} from '../../../../hydration/hydrator.js'\nimport { app } from '../../../../lexicons/index.js'\nimport {\n type HydrationFnInput,\n type PresentationFnInput,\n type RulesFnInput,\n type SkeletonFnInput,\n createPipeline,\n} from '../../../../pipeline.js'\nimport { uriToDid as didFromUri } from '../../../../util/uris.js'\nimport type { Views } from '../../../../views/index.js'\nimport { clearlyBadCursor, fillPage, resHeaders } from '../../../util.js'\n\nexport default function (server: Server, ctx: AppContext) {\n const getFollowers = createPipeline(\n skeleton,\n hydration,\n noBlocks,\n presentation,\n )\n server.add(app.bsky.graph.getFollowers, {\n auth: ctx.authVerifier.optionalStandardOrRole,\n handler: async ({ params, auth, req }) => {\n const { viewer, includeTakedowns, skipViewerBlocks } =\n ctx.authVerifier.parseCreds(auth)\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({\n labelers,\n viewer,\n includeTakedowns,\n skipViewerBlocks,\n })\n\n const result = await fillPage({\n cursor: params.cursor,\n limit: params.limit,\n fetch: ({ cursor, limit }) =>\n getFollowers(\n {\n ...params,\n cursor,\n limit,\n hydrateCtx,\n },\n ctx,\n ),\n items: (r) => r.followers,\n })\n\n return {\n encoding: 'application/json',\n body: result,\n headers: resHeaders({ labelers: hydrateCtx.labelers }),\n }\n },\n })\n}\n\nconst skeleton = async (\n input: SkeletonFnInput<Context, Params>,\n): Promise<SkeletonState> => {\n const { params, ctx } = input\n const [subjectDid] = await ctx.hydrator.actor.getDidsDefined([params.actor])\n if (!subjectDid) {\n throw new InvalidRequestError(`Actor not found: ${params.actor}`)\n }\n if (clearlyBadCursor(params.cursor)) {\n return { subjectDid, followUris: [] }\n }\n const { followers, cursor } = await ctx.hydrator.graph.getActorFollowers({\n did: subjectDid,\n cursor: params.cursor,\n limit: params.limit,\n sort: params.sort,\n })\n return {\n subjectDid,\n followUris: followers.map((f) => f.uri as AtUriString),\n cursor,\n }\n}\n\nconst hydration = async (\n input: HydrationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, params, skeleton } = input\n const { followUris, subjectDid } = skeleton\n const followState = await ctx.hydrator.hydrateFollows(\n followUris,\n params.hydrateCtx,\n )\n const dids = [subjectDid]\n if (followState.follows) {\n for (const [uri, follow] of followState.follows) {\n if (follow) {\n dids.push(didFromUri(uri))\n }\n }\n }\n const profileState = await ctx.hydrator.hydrateProfiles(\n dids,\n params.hydrateCtx,\n )\n return mergeStates(followState, profileState)\n}\n\nconst noBlocks = (input: RulesFnInput<Context, Params, SkeletonState>) => {\n const { skeleton, params, hydration, ctx } = input\n const viewer = params.hydrateCtx.viewer\n skeleton.followUris = skeleton.followUris.filter((followUri) => {\n const followerDid = didFromUri(followUri)\n return (\n !hydration.followBlocks?.get(followUri) &&\n (!viewer || !ctx.views.viewerBlockExists(followerDid, hydration))\n )\n })\n return skeleton\n}\n\nconst presentation = (\n input: PresentationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, hydration, skeleton, params } = input\n const { subjectDid, followUris, cursor } = skeleton\n const isNoHosted = (did: DidString) =>\n ctx.views.actorIsNoHosted(did, hydration)\n\n const subject = ctx.views.profile(subjectDid, hydration)\n if (\n !subject ||\n (!params.hydrateCtx.includeTakedowns && isNoHosted(subjectDid))\n ) {\n throw new InvalidRequestError(`Actor not found: ${params.actor}`)\n }\n\n const followers = mapDefined(followUris, (followUri) => {\n const followerDid = didFromUri(followUri)\n if (!params.hydrateCtx.includeTakedowns && isNoHosted(followerDid)) {\n return\n }\n return ctx.views.profile(didFromUri(followUri), hydration)\n })\n\n return { followers, subject, cursor }\n}\n\ntype Context = {\n hydrator: Hydrator\n views: Views\n}\n\ntype Params = app.bsky.graph.getFollowers.$Params & {\n hydrateCtx: HydrateCtx\n}\n\ntype SkeletonState = {\n subjectDid: DidString\n followUris: AtUriString[]\n cursor?: string\n}\n"]}
@@ -50,7 +50,7 @@ const skeleton = async (input) => {
50
50
  return {
51
51
  subjectDid,
52
52
  followUris: follows.map((f) => f.uri),
53
- cursor: cursor || undefined,
53
+ cursor,
54
54
  };
55
55
  };
56
56
  const hydration = async (input) => {
@@ -1 +1 @@
1
- {"version":3,"file":"getFollows.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/graph/getFollows.ts"],"names":[],"mappings":"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","sourcesContent":["import { mapDefined } from '@atproto/common'\nimport type { AtUriString, DidString } from '@atproto/lex'\nimport { InvalidRequestError, type Server } from '@atproto/xrpc-server'\nimport type { AppContext } from '../../../../context.js'\nimport {\n type HydrateCtx,\n type Hydrator,\n mergeStates,\n} from '../../../../hydration/hydrator.js'\nimport { app } from '../../../../lexicons/index.js'\nimport {\n type HydrationFnInput,\n type PresentationFnInput,\n type RulesFnInput,\n type SkeletonFnInput,\n createPipeline,\n} from '../../../../pipeline.js'\nimport type { Views } from '../../../../views/index.js'\nimport { clearlyBadCursor, fillPage, resHeaders } from '../../../util.js'\n\nexport default function (server: Server, ctx: AppContext) {\n const getFollows = createPipeline(skeleton, hydration, noBlocks, presentation)\n server.add(app.bsky.graph.getFollows, {\n auth: ctx.authVerifier.optionalStandardOrRole,\n handler: async ({ params, auth, req }) => {\n const { viewer, includeTakedowns, skipViewerBlocks } =\n ctx.authVerifier.parseCreds(auth)\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({\n labelers,\n viewer,\n includeTakedowns,\n skipViewerBlocks,\n })\n\n // @TODO ensure canViewTakedowns gets threaded through and applied properly\n const result = await fillPage({\n cursor: params.cursor,\n limit: params.limit,\n fetch: ({ cursor, limit }) =>\n getFollows({ ...params, cursor, limit, hydrateCtx }, ctx),\n items: (r) => r.follows,\n })\n\n return {\n encoding: 'application/json',\n body: result,\n headers: resHeaders({ labelers: hydrateCtx.labelers }),\n }\n },\n })\n}\n\nconst skeleton = async (\n input: SkeletonFnInput<Context, Params>,\n): Promise<SkeletonState> => {\n const { params, ctx } = input\n const [subjectDid] = await ctx.hydrator.actor.getDidsDefined([params.actor])\n if (!subjectDid) {\n throw new InvalidRequestError(`Actor not found: ${params.actor}`)\n }\n if (clearlyBadCursor(params.cursor)) {\n return { subjectDid, followUris: [] }\n }\n const { follows, cursor } = await ctx.hydrator.graph.getActorFollows({\n did: subjectDid,\n cursor: params.cursor,\n limit: params.limit,\n sort: params.sort,\n })\n return {\n subjectDid,\n followUris: follows.map((f) => f.uri as AtUriString),\n cursor: cursor || undefined,\n }\n}\n\nconst hydration = async (\n input: HydrationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, params, skeleton } = input\n const { followUris, subjectDid } = skeleton\n const followState = await ctx.hydrator.hydrateFollows(\n followUris,\n params.hydrateCtx,\n )\n const dids = [subjectDid]\n if (followState.follows) {\n for (const follow of followState.follows.values()) {\n if (follow) {\n dids.push(follow.record.subject)\n }\n }\n }\n const profileState = await ctx.hydrator.hydrateProfiles(\n dids,\n params.hydrateCtx,\n )\n return mergeStates(followState, profileState)\n}\n\nconst noBlocks = (input: RulesFnInput<Context, Params, SkeletonState>) => {\n const { skeleton, params, hydration, ctx } = input\n const viewer = params.hydrateCtx.viewer\n skeleton.followUris = skeleton.followUris.filter((followUri) => {\n const follow = hydration.follows?.get(followUri)\n if (!follow) return false\n return (\n !hydration.followBlocks?.get(followUri) &&\n (!viewer ||\n !ctx.views.viewerBlockExists(follow.record.subject, hydration))\n )\n })\n return skeleton\n}\n\nconst presentation = (\n input: PresentationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, hydration, skeleton, params } = input\n const { subjectDid, followUris, cursor } = skeleton\n const isNoHosted = (did: DidString) =>\n ctx.views.actorIsNoHosted(did, hydration)\n\n const subject = ctx.views.profile(subjectDid, hydration)\n if (\n !subject ||\n (!params.hydrateCtx.includeTakedowns && isNoHosted(subjectDid))\n ) {\n throw new InvalidRequestError(`Actor not found: ${params.actor}`)\n }\n\n const follows = mapDefined(followUris, (followUri) => {\n const followDid = hydration.follows?.get(followUri)?.record.subject\n if (!followDid) return\n if (!params.hydrateCtx.includeTakedowns && isNoHosted(followDid)) {\n return\n }\n return ctx.views.profile(followDid, hydration)\n })\n\n return { follows, subject, cursor }\n}\n\ntype Context = {\n hydrator: Hydrator\n views: Views\n}\n\ntype Params = app.bsky.graph.getFollowers.$Params & {\n hydrateCtx: HydrateCtx\n}\n\ntype SkeletonState = {\n subjectDid: DidString\n followUris: AtUriString[]\n cursor?: string\n}\n"]}
1
+ {"version":3,"file":"getFollows.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/graph/getFollows.ts"],"names":[],"mappings":"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","sourcesContent":["import { mapDefined } from '@atproto/common'\nimport type { AtUriString, DidString } from '@atproto/lex'\nimport { InvalidRequestError, type Server } from '@atproto/xrpc-server'\nimport type { AppContext } from '../../../../context.js'\nimport {\n type HydrateCtx,\n type Hydrator,\n mergeStates,\n} from '../../../../hydration/hydrator.js'\nimport { app } from '../../../../lexicons/index.js'\nimport {\n type HydrationFnInput,\n type PresentationFnInput,\n type RulesFnInput,\n type SkeletonFnInput,\n createPipeline,\n} from '../../../../pipeline.js'\nimport type { Views } from '../../../../views/index.js'\nimport { clearlyBadCursor, fillPage, resHeaders } from '../../../util.js'\n\nexport default function (server: Server, ctx: AppContext) {\n const getFollows = createPipeline(skeleton, hydration, noBlocks, presentation)\n server.add(app.bsky.graph.getFollows, {\n auth: ctx.authVerifier.optionalStandardOrRole,\n handler: async ({ params, auth, req }) => {\n const { viewer, includeTakedowns, skipViewerBlocks } =\n ctx.authVerifier.parseCreds(auth)\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({\n labelers,\n viewer,\n includeTakedowns,\n skipViewerBlocks,\n })\n\n // @TODO ensure canViewTakedowns gets threaded through and applied properly\n const result = await fillPage({\n cursor: params.cursor,\n limit: params.limit,\n fetch: ({ cursor, limit }) =>\n getFollows({ ...params, cursor, limit, hydrateCtx }, ctx),\n items: (r) => r.follows,\n })\n\n return {\n encoding: 'application/json',\n body: result,\n headers: resHeaders({ labelers: hydrateCtx.labelers }),\n }\n },\n })\n}\n\nconst skeleton = async (\n input: SkeletonFnInput<Context, Params>,\n): Promise<SkeletonState> => {\n const { params, ctx } = input\n const [subjectDid] = await ctx.hydrator.actor.getDidsDefined([params.actor])\n if (!subjectDid) {\n throw new InvalidRequestError(`Actor not found: ${params.actor}`)\n }\n if (clearlyBadCursor(params.cursor)) {\n return { subjectDid, followUris: [] }\n }\n const { follows, cursor } = await ctx.hydrator.graph.getActorFollows({\n did: subjectDid,\n cursor: params.cursor,\n limit: params.limit,\n sort: params.sort,\n })\n return {\n subjectDid,\n followUris: follows.map((f) => f.uri as AtUriString),\n cursor,\n }\n}\n\nconst hydration = async (\n input: HydrationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, params, skeleton } = input\n const { followUris, subjectDid } = skeleton\n const followState = await ctx.hydrator.hydrateFollows(\n followUris,\n params.hydrateCtx,\n )\n const dids = [subjectDid]\n if (followState.follows) {\n for (const follow of followState.follows.values()) {\n if (follow) {\n dids.push(follow.record.subject)\n }\n }\n }\n const profileState = await ctx.hydrator.hydrateProfiles(\n dids,\n params.hydrateCtx,\n )\n return mergeStates(followState, profileState)\n}\n\nconst noBlocks = (input: RulesFnInput<Context, Params, SkeletonState>) => {\n const { skeleton, params, hydration, ctx } = input\n const viewer = params.hydrateCtx.viewer\n skeleton.followUris = skeleton.followUris.filter((followUri) => {\n const follow = hydration.follows?.get(followUri)\n if (!follow) return false\n return (\n !hydration.followBlocks?.get(followUri) &&\n (!viewer ||\n !ctx.views.viewerBlockExists(follow.record.subject, hydration))\n )\n })\n return skeleton\n}\n\nconst presentation = (\n input: PresentationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, hydration, skeleton, params } = input\n const { subjectDid, followUris, cursor } = skeleton\n const isNoHosted = (did: DidString) =>\n ctx.views.actorIsNoHosted(did, hydration)\n\n const subject = ctx.views.profile(subjectDid, hydration)\n if (\n !subject ||\n (!params.hydrateCtx.includeTakedowns && isNoHosted(subjectDid))\n ) {\n throw new InvalidRequestError(`Actor not found: ${params.actor}`)\n }\n\n const follows = mapDefined(followUris, (followUri) => {\n const followDid = hydration.follows?.get(followUri)?.record.subject\n if (!followDid) return\n if (!params.hydrateCtx.includeTakedowns && isNoHosted(followDid)) {\n return\n }\n return ctx.views.profile(followDid, hydration)\n })\n\n return { follows, subject, cursor }\n}\n\ntype Context = {\n hydrator: Hydrator\n views: Views\n}\n\ntype Params = app.bsky.graph.getFollowers.$Params & {\n hydrateCtx: HydrateCtx\n}\n\ntype SkeletonState = {\n subjectDid: DidString\n followUris: AtUriString[]\n cursor?: string\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"getKnownFollowers.d.ts","sourceRoot":"","sources":["../../../../../src/api/app/bsky/graph/getKnownFollowers.ts"],"names":[],"mappings":"AAEA,OAAO,EAAuB,KAAK,MAAM,EAAE,MAAM,sBAAsB,CAAA;AACvE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAgBxD,MAAM,CAAC,OAAO,WAAW,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,QA0BvD"}
1
+ {"version":3,"file":"getKnownFollowers.d.ts","sourceRoot":"","sources":["../../../../../src/api/app/bsky/graph/getKnownFollowers.ts"],"names":[],"mappings":"AAEA,OAAO,EAAuB,KAAK,MAAM,EAAE,MAAM,sBAAsB,CAAA;AACvE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAgBxD,MAAM,CAAC,OAAO,WAAW,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,QAgCvD"}
@@ -2,7 +2,7 @@ import { mapDefined } from '@atproto/common';
2
2
  import { InvalidRequestError } from '@atproto/xrpc-server';
3
3
  import { app } from '../../../../lexicons/index.js';
4
4
  import { createPipeline, } from '../../../../pipeline.js';
5
- import { clearlyBadCursor, resHeaders } from '../../../util.js';
5
+ import { clearlyBadCursor, fillPage, resHeaders } from '../../../util.js';
6
6
  export default function (server, ctx) {
7
7
  const getKnownFollowers = createPipeline(skeleton, hydration, noBlocks, presentation);
8
8
  server.add(app.bsky.graph.getKnownFollowers, {
@@ -14,7 +14,12 @@ export default function (server, ctx) {
14
14
  labelers,
15
15
  viewer,
16
16
  });
17
- const result = await getKnownFollowers({ ...params, hydrateCtx }, ctx);
17
+ const result = await fillPage({
18
+ cursor: params.cursor,
19
+ limit: params.limit,
20
+ fetch: ({ cursor, limit }) => getKnownFollowers({ ...params, cursor, limit, hydrateCtx }, ctx),
21
+ items: (r) => r.followers,
22
+ });
18
23
  return {
19
24
  encoding: 'application/json',
20
25
  body: result,
@@ -35,15 +40,15 @@ const skeleton = async (input) => {
35
40
  const res = await ctx.hydrator.dataplane.getFollowsFollowing({
36
41
  actorDid: params.hydrateCtx.viewer,
37
42
  targetDids: [subjectDid],
43
+ limit: params.limit,
44
+ cursor: params.cursor,
38
45
  });
39
46
  const result = res.results.at(0);
40
- const knownFollowers = result
41
- ? result.dids.slice(0, params.limit)
42
- : [];
47
+ const knownFollowers = result ? result.dids : [];
43
48
  return {
44
49
  subjectDid,
45
50
  knownFollowers,
46
- cursor: undefined,
51
+ cursor: result?.cursor,
47
52
  };
48
53
  };
49
54
  const hydration = async (input) => {
@@ -66,6 +71,6 @@ const presentation = (input) => {
66
71
  return ctx.views.profile(did, hydration);
67
72
  });
68
73
  const subject = ctx.views.profile(skeleton.subjectDid, hydration);
69
- return { subject, followers, cursor: undefined };
74
+ return { subject, followers, cursor: skeleton.cursor };
70
75
  };
71
76
  //# sourceMappingURL=getKnownFollowers.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"getKnownFollowers.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/graph/getKnownFollowers.ts"],"names":[],"mappings":"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","sourcesContent":["import { mapDefined } from '@atproto/common'\nimport type { DidString } from '@atproto/lex'\nimport { InvalidRequestError, type Server } from '@atproto/xrpc-server'\nimport type { AppContext } from '../../../../context.js'\nimport type {\n HydrateCtxWithViewer,\n Hydrator,\n} from '../../../../hydration/hydrator.js'\nimport { app } from '../../../../lexicons/index.js'\nimport {\n type HydrationFnInput,\n type PresentationFnInput,\n type RulesFnInput,\n type SkeletonFnInput,\n createPipeline,\n} from '../../../../pipeline.js'\nimport type { Views } from '../../../../views/index.js'\nimport { clearlyBadCursor, resHeaders } from '../../../util.js'\n\nexport default function (server: Server, ctx: AppContext) {\n const getKnownFollowers = createPipeline(\n skeleton,\n hydration,\n noBlocks,\n presentation,\n )\n server.add(app.bsky.graph.getKnownFollowers, {\n auth: ctx.authVerifier.standard,\n handler: async ({ params, auth, req }) => {\n const viewer = auth.credentials.iss\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({\n labelers,\n viewer,\n })\n\n const result = await getKnownFollowers({ ...params, hydrateCtx }, ctx)\n\n return {\n encoding: 'application/json',\n body: result,\n headers: resHeaders({ labelers: hydrateCtx.labelers }),\n }\n },\n })\n}\n\nconst skeleton = async (\n input: SkeletonFnInput<Context, Params>,\n): Promise<SkeletonState> => {\n const { params, ctx } = input\n const [subjectDid] = await ctx.hydrator.actor.getDidsDefined([params.actor])\n if (!subjectDid) {\n throw new InvalidRequestError(`Actor not found: ${params.actor}`)\n }\n if (clearlyBadCursor(params.cursor)) {\n return { subjectDid, knownFollowers: [], cursor: undefined }\n }\n\n const res = await ctx.hydrator.dataplane.getFollowsFollowing({\n actorDid: params.hydrateCtx.viewer,\n targetDids: [subjectDid],\n })\n const result = res.results.at(0)\n const knownFollowers = result\n ? (result.dids.slice(0, params.limit) as DidString[])\n : []\n\n return {\n subjectDid,\n knownFollowers,\n cursor: undefined,\n }\n}\n\nconst hydration = async (\n input: HydrationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, params, skeleton } = input\n const { knownFollowers } = skeleton\n const profilesState = await ctx.hydrator.hydrateProfiles(\n knownFollowers.concat(skeleton.subjectDid),\n params.hydrateCtx,\n )\n return profilesState\n}\n\nconst noBlocks = (input: RulesFnInput<Context, Params, SkeletonState>) => {\n const { skeleton, hydration, ctx } = input\n skeleton.knownFollowers = skeleton.knownFollowers.filter((did) => {\n return !ctx.views.viewerBlockExists(did, hydration)\n })\n return skeleton\n}\n\nconst presentation = (\n input: PresentationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, hydration, skeleton } = input\n const { knownFollowers } = skeleton\n\n const followers = mapDefined(knownFollowers, (did) => {\n return ctx.views.profile(did, hydration)\n })\n const subject = ctx.views.profile(skeleton.subjectDid, hydration)!\n\n return { subject, followers, cursor: undefined }\n}\n\ntype Context = {\n hydrator: Hydrator\n views: Views\n}\n\ntype Params = app.bsky.graph.getKnownFollowers.$Params & {\n hydrateCtx: HydrateCtxWithViewer\n}\n\ntype SkeletonState = {\n subjectDid: DidString\n knownFollowers: DidString[]\n cursor?: string\n}\n"]}
1
+ {"version":3,"file":"getKnownFollowers.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/graph/getKnownFollowers.ts"],"names":[],"mappings":"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","sourcesContent":["import { mapDefined } from '@atproto/common'\nimport type { DidString } from '@atproto/lex'\nimport { InvalidRequestError, type Server } from '@atproto/xrpc-server'\nimport type { AppContext } from '../../../../context.js'\nimport type {\n HydrateCtxWithViewer,\n Hydrator,\n} from '../../../../hydration/hydrator.js'\nimport { app } from '../../../../lexicons/index.js'\nimport {\n type HydrationFnInput,\n type PresentationFnInput,\n type RulesFnInput,\n type SkeletonFnInput,\n createPipeline,\n} from '../../../../pipeline.js'\nimport type { Views } from '../../../../views/index.js'\nimport { clearlyBadCursor, fillPage, resHeaders } from '../../../util.js'\n\nexport default function (server: Server, ctx: AppContext) {\n const getKnownFollowers = createPipeline(\n skeleton,\n hydration,\n noBlocks,\n presentation,\n )\n server.add(app.bsky.graph.getKnownFollowers, {\n auth: ctx.authVerifier.standard,\n handler: async ({ params, auth, req }) => {\n const viewer = auth.credentials.iss\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({\n labelers,\n viewer,\n })\n\n const result = await fillPage({\n cursor: params.cursor,\n limit: params.limit,\n fetch: ({ cursor, limit }) =>\n getKnownFollowers({ ...params, cursor, limit, hydrateCtx }, ctx),\n items: (r) => r.followers,\n })\n\n return {\n encoding: 'application/json',\n body: result,\n headers: resHeaders({ labelers: hydrateCtx.labelers }),\n }\n },\n })\n}\n\nconst skeleton = async (\n input: SkeletonFnInput<Context, Params>,\n): Promise<SkeletonState> => {\n const { params, ctx } = input\n const [subjectDid] = await ctx.hydrator.actor.getDidsDefined([params.actor])\n if (!subjectDid) {\n throw new InvalidRequestError(`Actor not found: ${params.actor}`)\n }\n if (clearlyBadCursor(params.cursor)) {\n return { subjectDid, knownFollowers: [], cursor: undefined }\n }\n\n const res = await ctx.hydrator.dataplane.getFollowsFollowing({\n actorDid: params.hydrateCtx.viewer,\n targetDids: [subjectDid],\n limit: params.limit,\n cursor: params.cursor,\n })\n const result = res.results.at(0)\n const knownFollowers = result ? (result.dids as DidString[]) : []\n\n return {\n subjectDid,\n knownFollowers,\n cursor: result?.cursor,\n }\n}\n\nconst hydration = async (\n input: HydrationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, params, skeleton } = input\n const { knownFollowers } = skeleton\n const profilesState = await ctx.hydrator.hydrateProfiles(\n knownFollowers.concat(skeleton.subjectDid),\n params.hydrateCtx,\n )\n return profilesState\n}\n\nconst noBlocks = (input: RulesFnInput<Context, Params, SkeletonState>) => {\n const { skeleton, hydration, ctx } = input\n skeleton.knownFollowers = skeleton.knownFollowers.filter((did) => {\n return !ctx.views.viewerBlockExists(did, hydration)\n })\n return skeleton\n}\n\nconst presentation = (\n input: PresentationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, hydration, skeleton } = input\n const { knownFollowers } = skeleton\n\n const followers = mapDefined(knownFollowers, (did) => {\n return ctx.views.profile(did, hydration)\n })\n const subject = ctx.views.profile(skeleton.subjectDid, hydration)!\n\n return { subject, followers, cursor: skeleton.cursor }\n}\n\ntype Context = {\n hydrator: Hydrator\n views: Views\n}\n\ntype Params = app.bsky.graph.getKnownFollowers.$Params & {\n hydrateCtx: HydrateCtxWithViewer\n}\n\ntype SkeletonState = {\n subjectDid: DidString\n knownFollowers: DidString[]\n cursor?: string\n}\n"]}
@@ -46,7 +46,7 @@ const skeleton = async (input) => {
46
46
  return {
47
47
  listUri: params.list,
48
48
  listitems,
49
- cursor: cursor || undefined,
49
+ cursor,
50
50
  };
51
51
  };
52
52
  const hydration = async (input) => {
@@ -1 +1 @@
1
- {"version":3,"file":"getList.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/graph/getList.ts"],"names":[],"mappings":"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","sourcesContent":["import { mapDefined } from '@atproto/common'\nimport type { AtUriString, DidString } from '@atproto/lex'\nimport { InvalidRequestError, type Server } from '@atproto/xrpc-server'\nimport type { AppContext } from '../../../../context.js'\nimport {\n type HydrateCtx,\n type HydrationState,\n type Hydrator,\n mergeManyStates,\n} from '../../../../hydration/hydrator.js'\nimport { app } from '../../../../lexicons/index.js'\nimport {\n type HydrationFnInput,\n type PresentationFnInput,\n type RulesFnInput,\n type SkeletonFnInput,\n createPipeline,\n} from '../../../../pipeline.js'\nimport type { ListItemInfo } from '../../../../proto/bsky_pb.js'\nimport { uriToDid as didFromUri } from '../../../../util/uris.js'\nimport type { Views } from '../../../../views/index.js'\nimport { clearlyBadCursor, fillPage, resHeaders } from '../../../util.js'\n\nexport default function (server: Server, ctx: AppContext) {\n const getList = createPipeline(skeleton, hydration, noBlocks, presentation)\n server.add(app.bsky.graph.getList, {\n auth: ctx.authVerifier.standardOptional,\n handler: async ({ params, auth, req }) => {\n const { viewer, includeTakedowns, skipViewerBlocks } =\n ctx.authVerifier.parseCreds(auth)\n\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({\n labelers,\n viewer,\n includeTakedowns,\n skipViewerBlocks,\n })\n const result = await fillPage({\n cursor: params.cursor,\n limit: params.limit,\n fetch: ({ cursor, limit }) =>\n getList({ ...params, cursor, limit, hydrateCtx }, ctx),\n items: (r) => r.items,\n })\n return {\n encoding: 'application/json',\n body: result,\n headers: resHeaders({ labelers: hydrateCtx.labelers }),\n }\n },\n })\n}\n\nconst skeleton = async (\n input: SkeletonFnInput<Context, Params>,\n): Promise<SkeletonState> => {\n const { ctx, params } = input\n if (clearlyBadCursor(params.cursor)) {\n return { listUri: params.list, listitems: [] }\n }\n const { listitems, cursor } = await ctx.hydrator.dataplane.getListMembers({\n listUri: params.list,\n limit: params.limit,\n cursor: params.cursor,\n viewerDid: params.hydrateCtx.viewer ?? undefined,\n })\n return {\n listUri: params.list,\n listitems,\n cursor: cursor || undefined,\n }\n}\n\nconst hydration = async (\n input: HydrationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, params, skeleton } = input\n const { listUri, listitems } = skeleton\n const [listState, profileState] = await Promise.all([\n ctx.hydrator.hydrateLists([listUri], params.hydrateCtx),\n ctx.hydrator.hydrateProfiles(\n listitems.map(({ did }) => did as DidString),\n params.hydrateCtx,\n ),\n ])\n const bidirectionalBlocks = await maybeGetBlocksForReferenceAndCurateList({\n ctx,\n params,\n skeleton,\n listState,\n })\n return mergeManyStates(listState, profileState, { bidirectionalBlocks })\n}\n\nconst noBlocks = (input: RulesFnInput<Context, Params, SkeletonState>) => {\n const { skeleton, hydration } = input\n const creator = didFromUri(skeleton.listUri)\n const blocks = hydration.bidirectionalBlocks?.get(creator)\n skeleton.listitems = skeleton.listitems.filter(({ did }) => {\n return !blocks?.get(did as DidString)\n })\n return skeleton\n}\n\nconst presentation = (\n input: PresentationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, skeleton, hydration } = input\n const { listUri, listitems, cursor } = skeleton\n const list = ctx.views.list(listUri, hydration)\n if (!list) {\n throw new InvalidRequestError('List not found')\n }\n const showOptOuts =\n hydration.ctx?.viewer === didFromUri(listUri) &&\n list.purpose === app.bsky.graph.defs.Referencelist\n const items = mapDefined(listitems, ({ uri, did, subjectOptedOut }) =>\n ctx.views.listItemView(\n uri as AtUriString,\n did as DidString,\n hydration,\n showOptOuts && subjectOptedOut,\n ),\n )\n return { list, items, cursor }\n}\n\nconst maybeGetBlocksForReferenceAndCurateList = async (input: {\n ctx: Context\n listState: HydrationState\n skeleton: SkeletonState\n params: Params\n}) => {\n const { ctx, params, listState, skeleton } = input\n const { listitems } = skeleton\n const { list } = params\n const listRecord = listState.lists?.get(list)\n const creator = didFromUri(list)\n if (\n params.hydrateCtx.viewer === creator ||\n listRecord?.record.purpose === 'app.bsky.graph.defs#modlist'\n ) {\n return\n }\n const pairs: Map<DidString, DidString[]> = new Map()\n pairs.set(\n creator,\n listitems.map(({ did }) => did as DidString),\n )\n return await ctx.hydrator.hydrateBidirectionalBlocks(pairs, params.hydrateCtx)\n}\n\ntype Context = {\n hydrator: Hydrator\n views: Views\n}\n\ntype Params = app.bsky.graph.getList.$Params & {\n hydrateCtx: HydrateCtx\n}\n\ntype SkeletonState = {\n listUri: AtUriString\n listitems: ListItemInfo[]\n cursor?: string\n}\n"]}
1
+ {"version":3,"file":"getList.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/graph/getList.ts"],"names":[],"mappings":"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","sourcesContent":["import { mapDefined } from '@atproto/common'\nimport type { AtUriString, DidString } from '@atproto/lex'\nimport { InvalidRequestError, type Server } from '@atproto/xrpc-server'\nimport type { AppContext } from '../../../../context.js'\nimport {\n type HydrateCtx,\n type HydrationState,\n type Hydrator,\n mergeManyStates,\n} from '../../../../hydration/hydrator.js'\nimport { app } from '../../../../lexicons/index.js'\nimport {\n type HydrationFnInput,\n type PresentationFnInput,\n type RulesFnInput,\n type SkeletonFnInput,\n createPipeline,\n} from '../../../../pipeline.js'\nimport type { ListItemInfo } from '../../../../proto/bsky_pb.js'\nimport { uriToDid as didFromUri } from '../../../../util/uris.js'\nimport type { Views } from '../../../../views/index.js'\nimport { clearlyBadCursor, fillPage, resHeaders } from '../../../util.js'\n\nexport default function (server: Server, ctx: AppContext) {\n const getList = createPipeline(skeleton, hydration, noBlocks, presentation)\n server.add(app.bsky.graph.getList, {\n auth: ctx.authVerifier.standardOptional,\n handler: async ({ params, auth, req }) => {\n const { viewer, includeTakedowns, skipViewerBlocks } =\n ctx.authVerifier.parseCreds(auth)\n\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({\n labelers,\n viewer,\n includeTakedowns,\n skipViewerBlocks,\n })\n const result = await fillPage({\n cursor: params.cursor,\n limit: params.limit,\n fetch: ({ cursor, limit }) =>\n getList({ ...params, cursor, limit, hydrateCtx }, ctx),\n items: (r) => r.items,\n })\n return {\n encoding: 'application/json',\n body: result,\n headers: resHeaders({ labelers: hydrateCtx.labelers }),\n }\n },\n })\n}\n\nconst skeleton = async (\n input: SkeletonFnInput<Context, Params>,\n): Promise<SkeletonState> => {\n const { ctx, params } = input\n if (clearlyBadCursor(params.cursor)) {\n return { listUri: params.list, listitems: [] }\n }\n const { listitems, cursor } = await ctx.hydrator.dataplane.getListMembers({\n listUri: params.list,\n limit: params.limit,\n cursor: params.cursor,\n viewerDid: params.hydrateCtx.viewer ?? undefined,\n })\n return {\n listUri: params.list,\n listitems,\n cursor,\n }\n}\n\nconst hydration = async (\n input: HydrationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, params, skeleton } = input\n const { listUri, listitems } = skeleton\n const [listState, profileState] = await Promise.all([\n ctx.hydrator.hydrateLists([listUri], params.hydrateCtx),\n ctx.hydrator.hydrateProfiles(\n listitems.map(({ did }) => did as DidString),\n params.hydrateCtx,\n ),\n ])\n const bidirectionalBlocks = await maybeGetBlocksForReferenceAndCurateList({\n ctx,\n params,\n skeleton,\n listState,\n })\n return mergeManyStates(listState, profileState, { bidirectionalBlocks })\n}\n\nconst noBlocks = (input: RulesFnInput<Context, Params, SkeletonState>) => {\n const { skeleton, hydration } = input\n const creator = didFromUri(skeleton.listUri)\n const blocks = hydration.bidirectionalBlocks?.get(creator)\n skeleton.listitems = skeleton.listitems.filter(({ did }) => {\n return !blocks?.get(did as DidString)\n })\n return skeleton\n}\n\nconst presentation = (\n input: PresentationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, skeleton, hydration } = input\n const { listUri, listitems, cursor } = skeleton\n const list = ctx.views.list(listUri, hydration)\n if (!list) {\n throw new InvalidRequestError('List not found')\n }\n const showOptOuts =\n hydration.ctx?.viewer === didFromUri(listUri) &&\n list.purpose === app.bsky.graph.defs.Referencelist\n const items = mapDefined(listitems, ({ uri, did, subjectOptedOut }) =>\n ctx.views.listItemView(\n uri as AtUriString,\n did as DidString,\n hydration,\n showOptOuts && subjectOptedOut,\n ),\n )\n return { list, items, cursor }\n}\n\nconst maybeGetBlocksForReferenceAndCurateList = async (input: {\n ctx: Context\n listState: HydrationState\n skeleton: SkeletonState\n params: Params\n}) => {\n const { ctx, params, listState, skeleton } = input\n const { listitems } = skeleton\n const { list } = params\n const listRecord = listState.lists?.get(list)\n const creator = didFromUri(list)\n if (\n params.hydrateCtx.viewer === creator ||\n listRecord?.record.purpose === 'app.bsky.graph.defs#modlist'\n ) {\n return\n }\n const pairs: Map<DidString, DidString[]> = new Map()\n pairs.set(\n creator,\n listitems.map(({ did }) => did as DidString),\n )\n return await ctx.hydrator.hydrateBidirectionalBlocks(pairs, params.hydrateCtx)\n}\n\ntype Context = {\n hydrator: Hydrator\n views: Views\n}\n\ntype Params = app.bsky.graph.getList.$Params & {\n hydrateCtx: HydrateCtx\n}\n\ntype SkeletonState = {\n listUri: AtUriString\n listitems: ListItemInfo[]\n cursor?: string\n}\n"]}
@@ -34,7 +34,7 @@ const skeleton = async (input) => {
34
34
  cursor: params.cursor,
35
35
  limit: params.limit,
36
36
  });
37
- return { listUris: listUris, cursor: cursor || undefined };
37
+ return { listUris: listUris, cursor };
38
38
  };
39
39
  const hydration = async (input) => {
40
40
  const { ctx, params, skeleton } = input;
@@ -1 +1 @@
1
- {"version":3,"file":"getListBlocks.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/graph/getListBlocks.ts"],"names":[],"mappings":"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","sourcesContent":["import { mapDefined } from '@atproto/common'\nimport type { AtUriString } from '@atproto/lex'\nimport type { Server } from '@atproto/xrpc-server'\nimport type { AppContext } from '../../../../context.js'\nimport type {\n HydrateCtxWithViewer,\n Hydrator,\n} from '../../../../hydration/hydrator.js'\nimport { app } from '../../../../lexicons/index.js'\nimport {\n type HydrationFnInput,\n type PresentationFnInput,\n type SkeletonFnInput,\n createPipeline,\n noRules,\n} from '../../../../pipeline.js'\nimport type { Views } from '../../../../views/index.js'\nimport { clearlyBadCursor, fillPage, resHeaders } from '../../../util.js'\n\nexport default function (server: Server, ctx: AppContext) {\n const getListBlocks = createPipeline(\n skeleton,\n hydration,\n noRules,\n presentation,\n )\n server.add(app.bsky.graph.getListBlocks, {\n auth: ctx.authVerifier.standard,\n handler: async ({ params, auth, req }) => {\n const viewer = auth.credentials.iss\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({ labelers, viewer })\n const result = await fillPage({\n cursor: params.cursor,\n limit: params.limit,\n fetch: ({ cursor, limit }) =>\n getListBlocks({ ...params, cursor, limit, hydrateCtx }, ctx),\n items: (r) => r.lists,\n })\n return {\n encoding: 'application/json',\n body: result,\n headers: resHeaders({ labelers: hydrateCtx.labelers }),\n }\n },\n })\n}\n\nconst skeleton = async (\n input: SkeletonFnInput<Context, Params>,\n): Promise<SkeletonState> => {\n const { ctx, params } = input\n if (clearlyBadCursor(params.cursor)) {\n return { listUris: [] }\n }\n const { listUris, cursor } =\n await ctx.hydrator.dataplane.getBlocklistSubscriptions({\n actorDid: params.hydrateCtx.viewer,\n cursor: params.cursor,\n limit: params.limit,\n })\n return { listUris: listUris as AtUriString[], cursor: cursor || undefined }\n}\n\nconst hydration = async (\n input: HydrationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, params, skeleton } = input\n return await ctx.hydrator.hydrateLists(skeleton.listUris, params.hydrateCtx)\n}\n\nconst presentation = (\n input: PresentationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, skeleton, hydration } = input\n const { listUris, cursor } = skeleton\n const lists = mapDefined(listUris, (uri) => ctx.views.list(uri, hydration))\n return { lists, cursor }\n}\n\ntype Context = {\n hydrator: Hydrator\n views: Views\n}\n\ntype Params = app.bsky.graph.getListBlocks.$Params & {\n hydrateCtx: HydrateCtxWithViewer\n}\n\ntype SkeletonState = {\n listUris: AtUriString[]\n cursor?: string\n}\n"]}
1
+ {"version":3,"file":"getListBlocks.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/graph/getListBlocks.ts"],"names":[],"mappings":"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","sourcesContent":["import { mapDefined } from '@atproto/common'\nimport type { AtUriString } from '@atproto/lex'\nimport type { Server } from '@atproto/xrpc-server'\nimport type { AppContext } from '../../../../context.js'\nimport type {\n HydrateCtxWithViewer,\n Hydrator,\n} from '../../../../hydration/hydrator.js'\nimport { app } from '../../../../lexicons/index.js'\nimport {\n type HydrationFnInput,\n type PresentationFnInput,\n type SkeletonFnInput,\n createPipeline,\n noRules,\n} from '../../../../pipeline.js'\nimport type { Views } from '../../../../views/index.js'\nimport { clearlyBadCursor, fillPage, resHeaders } from '../../../util.js'\n\nexport default function (server: Server, ctx: AppContext) {\n const getListBlocks = createPipeline(\n skeleton,\n hydration,\n noRules,\n presentation,\n )\n server.add(app.bsky.graph.getListBlocks, {\n auth: ctx.authVerifier.standard,\n handler: async ({ params, auth, req }) => {\n const viewer = auth.credentials.iss\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({ labelers, viewer })\n const result = await fillPage({\n cursor: params.cursor,\n limit: params.limit,\n fetch: ({ cursor, limit }) =>\n getListBlocks({ ...params, cursor, limit, hydrateCtx }, ctx),\n items: (r) => r.lists,\n })\n return {\n encoding: 'application/json',\n body: result,\n headers: resHeaders({ labelers: hydrateCtx.labelers }),\n }\n },\n })\n}\n\nconst skeleton = async (\n input: SkeletonFnInput<Context, Params>,\n): Promise<SkeletonState> => {\n const { ctx, params } = input\n if (clearlyBadCursor(params.cursor)) {\n return { listUris: [] }\n }\n const { listUris, cursor } =\n await ctx.hydrator.dataplane.getBlocklistSubscriptions({\n actorDid: params.hydrateCtx.viewer,\n cursor: params.cursor,\n limit: params.limit,\n })\n return { listUris: listUris as AtUriString[], cursor }\n}\n\nconst hydration = async (\n input: HydrationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, params, skeleton } = input\n return await ctx.hydrator.hydrateLists(skeleton.listUris, params.hydrateCtx)\n}\n\nconst presentation = (\n input: PresentationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, skeleton, hydration } = input\n const { listUris, cursor } = skeleton\n const lists = mapDefined(listUris, (uri) => ctx.views.list(uri, hydration))\n return { lists, cursor }\n}\n\ntype Context = {\n hydrator: Hydrator\n views: Views\n}\n\ntype Params = app.bsky.graph.getListBlocks.$Params & {\n hydrateCtx: HydrateCtxWithViewer\n}\n\ntype SkeletonState = {\n listUris: AtUriString[]\n cursor?: string\n}\n"]}
@@ -34,7 +34,7 @@ const skeleton = async (input) => {
34
34
  cursor: params.cursor,
35
35
  limit: params.limit,
36
36
  });
37
- return { listUris: listUris, cursor: cursor || undefined };
37
+ return { listUris: listUris, cursor };
38
38
  };
39
39
  const hydration = async (input) => {
40
40
  const { ctx, params, skeleton } = input;
@@ -1 +1 @@
1
- {"version":3,"file":"getListMutes.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/graph/getListMutes.ts"],"names":[],"mappings":"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","sourcesContent":["import { mapDefined } from '@atproto/common'\nimport type { AtUriString } from '@atproto/lex'\nimport type { Server } from '@atproto/xrpc-server'\nimport type { AppContext } from '../../../../context.js'\nimport type {\n HydrateCtxWithViewer,\n Hydrator,\n} from '../../../../hydration/hydrator.js'\nimport { app } from '../../../../lexicons/index.js'\nimport {\n type HydrationFnInput,\n type PresentationFnInput,\n type SkeletonFnInput,\n createPipeline,\n noRules,\n} from '../../../../pipeline.js'\nimport type { Views } from '../../../../views/index.js'\nimport { clearlyBadCursor, fillPage, resHeaders } from '../../../util.js'\n\nexport default function (server: Server, ctx: AppContext) {\n const getListMutes = createPipeline(\n skeleton,\n hydration,\n noRules,\n presentation,\n )\n server.add(app.bsky.graph.getListMutes, {\n auth: ctx.authVerifier.standard,\n handler: async ({ params, auth, req }) => {\n const viewer = auth.credentials.iss\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({ labelers, viewer })\n const result = await fillPage({\n cursor: params.cursor,\n limit: params.limit,\n fetch: ({ cursor, limit }) =>\n getListMutes({ ...params, cursor, limit, hydrateCtx }, ctx),\n items: (r) => r.lists,\n })\n return {\n encoding: 'application/json',\n body: result,\n headers: resHeaders({ labelers: hydrateCtx.labelers }),\n }\n },\n })\n}\n\nconst skeleton = async (\n input: SkeletonFnInput<Context, Params>,\n): Promise<SkeletonState> => {\n const { ctx, params } = input\n if (clearlyBadCursor(params.cursor)) {\n return { listUris: [] }\n }\n const { listUris, cursor } =\n await ctx.hydrator.dataplane.getMutelistSubscriptions({\n actorDid: params.hydrateCtx.viewer,\n cursor: params.cursor,\n limit: params.limit,\n })\n return { listUris: listUris as AtUriString[], cursor: cursor || undefined }\n}\n\nconst hydration = async (\n input: HydrationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, params, skeleton } = input\n return await ctx.hydrator.hydrateLists(skeleton.listUris, params.hydrateCtx)\n}\n\nconst presentation = (\n input: PresentationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, skeleton, hydration } = input\n const { listUris, cursor } = skeleton\n const lists = mapDefined(listUris, (uri) => ctx.views.list(uri, hydration))\n return { lists, cursor }\n}\n\ntype Context = {\n hydrator: Hydrator\n views: Views\n}\n\ntype Params = app.bsky.graph.getListBlocks.$Params & {\n hydrateCtx: HydrateCtxWithViewer\n}\n\ntype SkeletonState = {\n listUris: AtUriString[]\n cursor?: string\n}\n"]}
1
+ {"version":3,"file":"getListMutes.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/graph/getListMutes.ts"],"names":[],"mappings":"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","sourcesContent":["import { mapDefined } from '@atproto/common'\nimport type { AtUriString } from '@atproto/lex'\nimport type { Server } from '@atproto/xrpc-server'\nimport type { AppContext } from '../../../../context.js'\nimport type {\n HydrateCtxWithViewer,\n Hydrator,\n} from '../../../../hydration/hydrator.js'\nimport { app } from '../../../../lexicons/index.js'\nimport {\n type HydrationFnInput,\n type PresentationFnInput,\n type SkeletonFnInput,\n createPipeline,\n noRules,\n} from '../../../../pipeline.js'\nimport type { Views } from '../../../../views/index.js'\nimport { clearlyBadCursor, fillPage, resHeaders } from '../../../util.js'\n\nexport default function (server: Server, ctx: AppContext) {\n const getListMutes = createPipeline(\n skeleton,\n hydration,\n noRules,\n presentation,\n )\n server.add(app.bsky.graph.getListMutes, {\n auth: ctx.authVerifier.standard,\n handler: async ({ params, auth, req }) => {\n const viewer = auth.credentials.iss\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({ labelers, viewer })\n const result = await fillPage({\n cursor: params.cursor,\n limit: params.limit,\n fetch: ({ cursor, limit }) =>\n getListMutes({ ...params, cursor, limit, hydrateCtx }, ctx),\n items: (r) => r.lists,\n })\n return {\n encoding: 'application/json',\n body: result,\n headers: resHeaders({ labelers: hydrateCtx.labelers }),\n }\n },\n })\n}\n\nconst skeleton = async (\n input: SkeletonFnInput<Context, Params>,\n): Promise<SkeletonState> => {\n const { ctx, params } = input\n if (clearlyBadCursor(params.cursor)) {\n return { listUris: [] }\n }\n const { listUris, cursor } =\n await ctx.hydrator.dataplane.getMutelistSubscriptions({\n actorDid: params.hydrateCtx.viewer,\n cursor: params.cursor,\n limit: params.limit,\n })\n return { listUris: listUris as AtUriString[], cursor }\n}\n\nconst hydration = async (\n input: HydrationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, params, skeleton } = input\n return await ctx.hydrator.hydrateLists(skeleton.listUris, params.hydrateCtx)\n}\n\nconst presentation = (\n input: PresentationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, skeleton, hydration } = input\n const { listUris, cursor } = skeleton\n const lists = mapDefined(listUris, (uri) => ctx.views.list(uri, hydration))\n return { lists, cursor }\n}\n\ntype Context = {\n hydrator: Hydrator\n views: Views\n}\n\ntype Params = app.bsky.graph.getListBlocks.$Params & {\n hydrateCtx: HydrateCtxWithViewer\n}\n\ntype SkeletonState = {\n listUris: AtUriString[]\n cursor?: string\n}\n"]}
@@ -43,7 +43,7 @@ const skeleton = async (input) => {
43
43
  : res.dids;
44
44
  return {
45
45
  mutedDids: mutedDids,
46
- cursor: res.cursor || undefined,
46
+ cursor: res.cursor,
47
47
  };
48
48
  };
49
49
  const hydration = async (input) => {
@@ -1 +1 @@
1
- {"version":3,"file":"getMutes.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/graph/getMutes.ts"],"names":[],"mappings":"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","sourcesContent":["import { mapDefined } from '@atproto/common'\nimport type { DidString } from '@atproto/lex'\nimport type { Server } from '@atproto/xrpc-server'\nimport type { AppContext } from '../../../../context.js'\nimport type {\n HydrateCtxWithViewer,\n Hydrator,\n} from '../../../../hydration/hydrator.js'\nimport { app } from '../../../../lexicons/index.js'\nimport {\n type HydrationFnInput,\n type PresentationFnInput,\n type SkeletonFnInput,\n createPipeline,\n noRules,\n} from '../../../../pipeline.js'\nimport type { Views } from '../../../../views/index.js'\nimport { clearlyBadCursor, fillPage, resHeaders } from '../../../util.js'\n\nexport default function (server: Server, ctx: AppContext) {\n const getMutes = createPipeline(skeleton, hydration, noRules, presentation)\n server.add(app.bsky.graph.getMutes, {\n auth: ctx.authVerifier.standard,\n handler: async ({ params, auth, req }) => {\n const viewer = auth.credentials.iss\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({ labelers, viewer })\n const result = await fillPage({\n cursor: params.cursor,\n limit: params.limit,\n fetch: ({ cursor, limit }) =>\n getMutes({ ...params, cursor, limit, hydrateCtx }, ctx),\n items: (r) => r.mutes,\n })\n return {\n encoding: 'application/json',\n body: result,\n headers: resHeaders({ labelers: hydrateCtx.labelers }),\n }\n },\n })\n}\n\nconst skeleton = async (\n input: SkeletonFnInput<Context, Params>,\n): Promise<SkeletonState> => {\n const { params, ctx } = input\n if (clearlyBadCursor(params.cursor)) {\n return { mutedDids: [] }\n }\n const res = await ctx.hydrator.dataplane.getMutes({\n actorDid: params.hydrateCtx.viewer,\n cursor: params.cursor,\n limit: params.limit,\n })\n\n // only fully muted accounts are enumerated: scoped mutes (only reposts /\n // only quoteposts) are filtered out.\n const mutedDids = res.mutes.length\n ? res.mutes\n .filter((mute) => !mute.onlyReposts && !mute.onlyQuoteposts)\n .map((mute) => mute.did)\n : res.dids\n return {\n mutedDids: mutedDids as DidString[],\n cursor: res.cursor || undefined,\n }\n}\n\nconst hydration = async (\n input: HydrationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, params, skeleton } = input\n const { mutedDids } = skeleton\n return ctx.hydrator.hydrateProfiles(mutedDids, params.hydrateCtx)\n}\n\nconst presentation = (\n input: PresentationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, hydration, skeleton } = input\n const { mutedDids, cursor } = skeleton\n const mutes = mapDefined(mutedDids, (did) => {\n return ctx.views.profile(did, hydration)\n })\n return { mutes, cursor }\n}\n\ntype Context = {\n hydrator: Hydrator\n views: Views\n}\n\ntype Params = app.bsky.graph.getMutes.$Params & {\n hydrateCtx: HydrateCtxWithViewer\n}\n\ntype SkeletonState = {\n mutedDids: DidString[]\n cursor?: string\n}\n"]}
1
+ {"version":3,"file":"getMutes.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/graph/getMutes.ts"],"names":[],"mappings":"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","sourcesContent":["import { mapDefined } from '@atproto/common'\nimport type { DidString } from '@atproto/lex'\nimport type { Server } from '@atproto/xrpc-server'\nimport type { AppContext } from '../../../../context.js'\nimport type {\n HydrateCtxWithViewer,\n Hydrator,\n} from '../../../../hydration/hydrator.js'\nimport { app } from '../../../../lexicons/index.js'\nimport {\n type HydrationFnInput,\n type PresentationFnInput,\n type SkeletonFnInput,\n createPipeline,\n noRules,\n} from '../../../../pipeline.js'\nimport type { Views } from '../../../../views/index.js'\nimport { clearlyBadCursor, fillPage, resHeaders } from '../../../util.js'\n\nexport default function (server: Server, ctx: AppContext) {\n const getMutes = createPipeline(skeleton, hydration, noRules, presentation)\n server.add(app.bsky.graph.getMutes, {\n auth: ctx.authVerifier.standard,\n handler: async ({ params, auth, req }) => {\n const viewer = auth.credentials.iss\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({ labelers, viewer })\n const result = await fillPage({\n cursor: params.cursor,\n limit: params.limit,\n fetch: ({ cursor, limit }) =>\n getMutes({ ...params, cursor, limit, hydrateCtx }, ctx),\n items: (r) => r.mutes,\n })\n return {\n encoding: 'application/json',\n body: result,\n headers: resHeaders({ labelers: hydrateCtx.labelers }),\n }\n },\n })\n}\n\nconst skeleton = async (\n input: SkeletonFnInput<Context, Params>,\n): Promise<SkeletonState> => {\n const { params, ctx } = input\n if (clearlyBadCursor(params.cursor)) {\n return { mutedDids: [] }\n }\n const res = await ctx.hydrator.dataplane.getMutes({\n actorDid: params.hydrateCtx.viewer,\n cursor: params.cursor,\n limit: params.limit,\n })\n\n // only fully muted accounts are enumerated: scoped mutes (only reposts /\n // only quoteposts) are filtered out.\n const mutedDids = res.mutes.length\n ? res.mutes\n .filter((mute) => !mute.onlyReposts && !mute.onlyQuoteposts)\n .map((mute) => mute.did)\n : res.dids\n return {\n mutedDids: mutedDids as DidString[],\n cursor: res.cursor,\n }\n}\n\nconst hydration = async (\n input: HydrationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, params, skeleton } = input\n const { mutedDids } = skeleton\n return ctx.hydrator.hydrateProfiles(mutedDids, params.hydrateCtx)\n}\n\nconst presentation = (\n input: PresentationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, hydration, skeleton } = input\n const { mutedDids, cursor } = skeleton\n const mutes = mapDefined(mutedDids, (did) => {\n return ctx.views.profile(did, hydration)\n })\n return { mutes, cursor }\n}\n\ntype Context = {\n hydrator: Hydrator\n views: Views\n}\n\ntype Params = app.bsky.graph.getMutes.$Params & {\n hydrateCtx: HydrateCtxWithViewer\n}\n\ntype SkeletonState = {\n mutedDids: DidString[]\n cursor?: string\n}\n"]}
@@ -45,7 +45,7 @@ const skeleton = async (input) => {
45
45
  return {
46
46
  actorDid,
47
47
  starterPackUris: starterPackUris,
48
- cursor: cursor || undefined,
48
+ cursor,
49
49
  };
50
50
  };
51
51
  const hydration = async (input) => {