@atproto/bsky 0.1.1 → 0.1.3

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 +36 -0
  2. package/dist/api/app/bsky/actor/getSuggestions.d.ts.map +1 -1
  3. package/dist/api/app/bsky/actor/getSuggestions.js +9 -3
  4. package/dist/api/app/bsky/actor/getSuggestions.js.map +1 -1
  5. package/dist/api/app/bsky/feed/getFeed.d.ts.map +1 -1
  6. package/dist/api/app/bsky/feed/getFeed.js +44 -15
  7. package/dist/api/app/bsky/feed/getFeed.js.map +1 -1
  8. package/dist/api/app/bsky/graph/getSuggestedFollowsByActor.d.ts.map +1 -1
  9. package/dist/api/app/bsky/graph/getSuggestedFollowsByActor.js +7 -3
  10. package/dist/api/app/bsky/graph/getSuggestedFollowsByActor.js.map +1 -1
  11. package/dist/api/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.d.ts.map +1 -1
  12. package/dist/api/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.js +13 -4
  13. package/dist/api/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.js.map +1 -1
  14. package/dist/api/app/bsky/unspecced/getSuggestedFeeds.d.ts.map +1 -1
  15. package/dist/api/app/bsky/unspecced/getSuggestedFeeds.js +12 -4
  16. package/dist/api/app/bsky/unspecced/getSuggestedFeeds.js.map +1 -1
  17. package/dist/api/app/bsky/unspecced/getSuggestedOnboardingUsers.d.ts.map +1 -1
  18. package/dist/api/app/bsky/unspecced/getSuggestedOnboardingUsers.js +10 -3
  19. package/dist/api/app/bsky/unspecced/getSuggestedOnboardingUsers.js.map +1 -1
  20. package/dist/api/app/bsky/unspecced/getSuggestedStarterPacks.d.ts.map +1 -1
  21. package/dist/api/app/bsky/unspecced/getSuggestedStarterPacks.js +13 -4
  22. package/dist/api/app/bsky/unspecced/getSuggestedStarterPacks.js.map +1 -1
  23. package/dist/api/app/bsky/unspecced/getSuggestedUsers.js +18 -0
  24. package/dist/api/app/bsky/unspecced/getSuggestedUsers.js.map +1 -1
  25. package/dist/api/app/bsky/unspecced/getSuggestedUsersForDiscover.js +17 -0
  26. package/dist/api/app/bsky/unspecced/getSuggestedUsersForDiscover.js.map +1 -1
  27. package/dist/api/app/bsky/unspecced/getSuggestedUsersForExplore.js +18 -0
  28. package/dist/api/app/bsky/unspecced/getSuggestedUsersForExplore.js.map +1 -1
  29. package/dist/api/app/bsky/unspecced/getSuggestedUsersForSeeMore.js +18 -0
  30. package/dist/api/app/bsky/unspecced/getSuggestedUsersForSeeMore.js.map +1 -1
  31. package/dist/config.d.ts +8 -0
  32. package/dist/config.d.ts.map +1 -1
  33. package/dist/config.js +22 -0
  34. package/dist/config.js.map +1 -1
  35. package/dist/data-plane/server/routes/atmosphere.d.ts +5 -0
  36. package/dist/data-plane/server/routes/atmosphere.d.ts.map +1 -0
  37. package/dist/data-plane/server/routes/atmosphere.js +24 -0
  38. package/dist/data-plane/server/routes/atmosphere.js.map +1 -0
  39. package/dist/data-plane/server/routes/index.js +2 -2
  40. package/dist/data-plane/server/routes/index.js.map +1 -1
  41. package/dist/feature-gates/gates.d.ts +10 -0
  42. package/dist/feature-gates/gates.d.ts.map +1 -1
  43. package/dist/feature-gates/gates.js +10 -0
  44. package/dist/feature-gates/gates.js.map +1 -1
  45. package/dist/feature-gates/index.js +2 -2
  46. package/dist/feature-gates/index.js.map +1 -1
  47. package/dist/hydration/external.d.ts +65 -2
  48. package/dist/hydration/external.d.ts.map +1 -1
  49. package/dist/hydration/external.js +220 -29
  50. package/dist/hydration/external.js.map +1 -1
  51. package/dist/hydration/hydrator.d.ts.map +1 -1
  52. package/dist/hydration/hydrator.js +7 -7
  53. package/dist/hydration/hydrator.js.map +1 -1
  54. package/dist/index.d.ts.map +1 -1
  55. package/dist/index.js +3 -0
  56. package/dist/index.js.map +1 -1
  57. package/dist/lexicons/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.defs.d.ts +2 -0
  58. package/dist/lexicons/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.defs.d.ts.map +1 -1
  59. package/dist/lexicons/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.defs.js +1 -0
  60. package/dist/lexicons/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.defs.js.map +1 -1
  61. package/dist/lexicons/app/bsky/unspecced/getOnboardingSuggestedStarterPacksSkeleton.defs.d.ts +2 -0
  62. package/dist/lexicons/app/bsky/unspecced/getOnboardingSuggestedStarterPacksSkeleton.defs.d.ts.map +1 -1
  63. package/dist/lexicons/app/bsky/unspecced/getOnboardingSuggestedStarterPacksSkeleton.defs.js +1 -0
  64. package/dist/lexicons/app/bsky/unspecced/getOnboardingSuggestedStarterPacksSkeleton.defs.js.map +1 -1
  65. package/dist/lexicons/app/bsky/unspecced/getSuggestedFeeds.defs.d.ts +2 -0
  66. package/dist/lexicons/app/bsky/unspecced/getSuggestedFeeds.defs.d.ts.map +1 -1
  67. package/dist/lexicons/app/bsky/unspecced/getSuggestedFeeds.defs.js +1 -0
  68. package/dist/lexicons/app/bsky/unspecced/getSuggestedFeeds.defs.js.map +1 -1
  69. package/dist/lexicons/app/bsky/unspecced/getSuggestedFeedsSkeleton.defs.d.ts +2 -0
  70. package/dist/lexicons/app/bsky/unspecced/getSuggestedFeedsSkeleton.defs.d.ts.map +1 -1
  71. package/dist/lexicons/app/bsky/unspecced/getSuggestedFeedsSkeleton.defs.js +1 -0
  72. package/dist/lexicons/app/bsky/unspecced/getSuggestedFeedsSkeleton.defs.js.map +1 -1
  73. package/dist/lexicons/app/bsky/unspecced/getSuggestedStarterPacks.defs.d.ts +2 -0
  74. package/dist/lexicons/app/bsky/unspecced/getSuggestedStarterPacks.defs.d.ts.map +1 -1
  75. package/dist/lexicons/app/bsky/unspecced/getSuggestedStarterPacks.defs.js +1 -0
  76. package/dist/lexicons/app/bsky/unspecced/getSuggestedStarterPacks.defs.js.map +1 -1
  77. package/dist/lexicons/app/bsky/unspecced/getSuggestedStarterPacksSkeleton.defs.d.ts +2 -0
  78. package/dist/lexicons/app/bsky/unspecced/getSuggestedStarterPacksSkeleton.defs.d.ts.map +1 -1
  79. package/dist/lexicons/app/bsky/unspecced/getSuggestedStarterPacksSkeleton.defs.js +1 -0
  80. package/dist/lexicons/app/bsky/unspecced/getSuggestedStarterPacksSkeleton.defs.js.map +1 -1
  81. package/dist/proto/bsky_connect.d.ts +57 -21
  82. package/dist/proto/bsky_connect.d.ts.map +1 -1
  83. package/dist/proto/bsky_connect.js +57 -21
  84. package/dist/proto/bsky_connect.js.map +1 -1
  85. package/dist/proto/bsky_pb.d.ts +361 -72
  86. package/dist/proto/bsky_pb.d.ts.map +1 -1
  87. package/dist/proto/bsky_pb.js +529 -70
  88. package/dist/proto/bsky_pb.js.map +1 -1
  89. package/dist/util/standard-site.d.ts +0 -12
  90. package/dist/util/standard-site.d.ts.map +1 -1
  91. package/dist/util/standard-site.js +0 -14
  92. package/dist/util/standard-site.js.map +1 -1
  93. package/package.json +6 -6
  94. package/dist/data-plane/server/routes/site-standard.d.ts +0 -6
  95. package/dist/data-plane/server/routes/site-standard.d.ts.map +0 -1
  96. package/dist/data-plane/server/routes/site-standard.js +0 -9
  97. package/dist/data-plane/server/routes/site-standard.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"getSuggestedFeeds.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/unspecced/getSuggestedFeeds.ts"],"names":[],"mappings":"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","sourcesContent":["import { mapDefined, noUndefinedVals } from '@atproto/common'\nimport type { AtUriString, Client } from '@atproto/lex'\nimport { MethodNotImplementedError, type Server } from '@atproto/xrpc-server'\nimport type { AppContext } from '../../../../context.js'\nimport type { HydrateCtx, Hydrator } 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 { getAtprotoPassthroughHeaders } from '../../../../util/headers.js'\nimport type { Views } from '../../../../views/index.js'\n\nexport default function (server: Server, ctx: AppContext) {\n const getFeeds = createPipeline(skeleton, hydration, noRules, presentation)\n server.add(app.bsky.unspecced.getSuggestedFeeds, {\n auth: ctx.authVerifier.standardOptional,\n handler: async ({ auth, params, req, signal }) => {\n const viewer = auth.credentials.iss\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({ labelers, viewer })\n const headers = noUndefinedVals({\n 'accept-language': req.headers['accept-language'],\n ...getAtprotoPassthroughHeaders(req),\n })\n const result = await getFeeds(\n {\n ...params,\n hydrateCtx,\n headers,\n signal,\n },\n ctx,\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\n if (!ctx.topicsClient) {\n // Use 501 instead of 500 as these are not considered retry-able by clients\n throw new MethodNotImplementedError('Topics agent not available')\n }\n\n return ctx.topicsClient.call(\n app.bsky.unspecced.getSuggestedFeedsSkeleton,\n {\n limit: params.limit,\n viewer: params.hydrateCtx.viewer ?? undefined,\n },\n {\n headers: params.headers,\n signal: params.signal,\n },\n )\n}\n\nconst hydration = async (\n input: HydrationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, params, skeleton } = input\n return await ctx.hydrator.hydrateFeedGens(skeleton.feeds, params.hydrateCtx)\n}\n\nconst presentation = (\n input: PresentationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, skeleton, hydration } = input\n\n return {\n feeds: mapDefined(skeleton.feeds, (uri) =>\n ctx.views.feedGenerator(uri, hydration),\n ),\n }\n}\n\ntype Context = {\n hydrator: Hydrator\n views: Views\n topicsClient: Client | undefined\n}\n\ntype Params = app.bsky.unspecced.getSuggestedFeeds.$Params & {\n hydrateCtx: HydrateCtx\n headers: Record<string, string>\n signal: AbortSignal\n}\n\ntype SkeletonState = {\n feeds: AtUriString[]\n}\n"]}
1
+ {"version":3,"file":"getSuggestedFeeds.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/unspecced/getSuggestedFeeds.ts"],"names":[],"mappings":"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","sourcesContent":["import { mapDefined, noUndefinedVals } from '@atproto/common'\nimport type { AtUriString, Client } from '@atproto/lex'\nimport { MethodNotImplementedError, type Server } from '@atproto/xrpc-server'\nimport type { AppContext } from '../../../../context.js'\nimport type { HydrateCtx, Hydrator } 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 { getAtprotoPassthroughHeaders } from '../../../../util/headers.js'\nimport type { Views } from '../../../../views/index.js'\n\nexport default function (server: Server, ctx: AppContext) {\n const getFeeds = createPipeline(skeleton, hydration, noRules, presentation)\n server.add(app.bsky.unspecced.getSuggestedFeeds, {\n auth: ctx.authVerifier.standardOptional,\n handler: async ({ auth, params, req, signal }) => {\n const viewer = auth.credentials.iss\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({\n labelers,\n viewer,\n features: ctx.featureGatesClient.scope(\n ctx.featureGatesClient.parseUserContextFromHandler({ viewer, req }),\n ),\n })\n const headers = noUndefinedVals({\n 'accept-language': req.headers['accept-language'],\n ...getAtprotoPassthroughHeaders(req),\n })\n const result = await getFeeds(\n {\n ...params,\n hydrateCtx,\n headers,\n signal,\n },\n ctx,\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\n const useIris = params.hydrateCtx.features.checkGate(\n params.hydrateCtx.features.Gate.SuggestedFeedsV2Enable,\n )\n const client = useIris ? ctx.irisClient : ctx.topicsClient\n\n if (!client) {\n // Use 501 instead of 500 as these are not considered retry-able by clients\n const agent = useIris ? 'Iris' : 'Topics'\n throw new MethodNotImplementedError(`${agent} agent not available`)\n }\n\n return client.call(\n app.bsky.unspecced.getSuggestedFeedsSkeleton,\n {\n limit: params.limit,\n viewer: params.hydrateCtx.viewer ?? undefined,\n },\n {\n headers: params.headers,\n signal: params.signal,\n },\n )\n}\n\nconst hydration = async (\n input: HydrationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, params, skeleton } = input\n return await ctx.hydrator.hydrateFeedGens(skeleton.feeds, params.hydrateCtx)\n}\n\nconst presentation = (\n input: PresentationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, skeleton, hydration } = input\n\n return {\n feeds: mapDefined(skeleton.feeds, (uri) =>\n ctx.views.feedGenerator(uri, hydration),\n ),\n recIdStr: skeleton.recIdStr,\n }\n}\n\ntype Context = {\n hydrator: Hydrator\n views: Views\n topicsClient: Client | undefined\n irisClient: Client | undefined\n}\n\ntype Params = app.bsky.unspecced.getSuggestedFeeds.$Params & {\n hydrateCtx: HydrateCtx\n headers: Record<string, string>\n signal: AbortSignal\n}\n\ntype SkeletonState = {\n feeds: AtUriString[]\n recIdStr?: string\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"getSuggestedOnboardingUsers.d.ts","sourceRoot":"","sources":["../../../../../src/api/app/bsky/unspecced/getSuggestedOnboardingUsers.ts"],"names":[],"mappings":"AAEA,OAAO,EAA6B,KAAK,MAAM,EAAE,MAAM,sBAAsB,CAAA;AAC7E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAiBxD,MAAM,CAAC,OAAO,WAAW,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,QAmCvD"}
1
+ {"version":3,"file":"getSuggestedOnboardingUsers.d.ts","sourceRoot":"","sources":["../../../../../src/api/app/bsky/unspecced/getSuggestedOnboardingUsers.ts"],"names":[],"mappings":"AAEA,OAAO,EAA6B,KAAK,MAAM,EAAE,MAAM,sBAAsB,CAAA;AAC7E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAiBxD,MAAM,CAAC,OAAO,WAAW,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,QAyCvD"}
@@ -14,6 +14,10 @@ export default function (server, ctx) {
14
14
  const hydrateCtx = await ctx.hydrator.createContext({
15
15
  labelers,
16
16
  viewer,
17
+ features: ctx.featureGatesClient.scope(ctx.featureGatesClient.parseUserContextFromHandler({
18
+ viewer,
19
+ req,
20
+ })),
17
21
  });
18
22
  const headers = noUndefinedVals({
19
23
  'accept-language': req.headers['accept-language'],
@@ -34,10 +38,13 @@ export default function (server, ctx) {
34
38
  }
35
39
  const skeleton = async (input) => {
36
40
  const { params, ctx } = input;
37
- if (!ctx.suggestionsClient) {
38
- throw new MethodNotImplementedError('Suggestions agent not available');
41
+ const useIris = params.hydrateCtx.features.checkGate(params.hydrateCtx.features.Gate.SuggestedUsersIrisEnable);
42
+ const client = useIris ? ctx.irisClient : ctx.suggestionsClient;
43
+ if (!client) {
44
+ const agent = useIris ? 'Iris' : 'Suggestions';
45
+ throw new MethodNotImplementedError(`${agent} agent not available`);
39
46
  }
40
- return ctx.suggestionsClient.call(app.bsky.unspecced.getOnboardingSuggestedUsersSkeleton, {
47
+ return client.call(app.bsky.unspecced.getOnboardingSuggestedUsersSkeleton, {
41
48
  limit: params.limit,
42
49
  viewer: params.hydrateCtx.viewer ?? undefined,
43
50
  category: params.category,
@@ -1 +1 @@
1
- {"version":3,"file":"getSuggestedOnboardingUsers.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/unspecced/getSuggestedOnboardingUsers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAEzE,OAAO,EAAE,yBAAyB,EAAe,MAAM,sBAAsB,CAAA;AAE7E,OAAO,EAGL,eAAe,GAChB,MAAM,mCAAmC,CAAA;AAC1C,OAAO,EAAE,GAAG,EAAE,MAAM,+BAA+B,CAAA;AACnD,OAAO,EAKL,cAAc,GACf,MAAM,yBAAyB,CAAA;AAChC,OAAO,EAAE,4BAA4B,EAAE,MAAM,6BAA6B,CAAA;AAG1E,MAAM,CAAC,OAAO,WAAW,MAAc,EAAE,GAAe;IACtD,MAAM,2BAA2B,GAAG,cAAc,CAChD,QAAQ,EACR,SAAS,EACT,iBAAiB,EACjB,YAAY,CACb,CAAA;IACD,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,2BAA2B,EAAE;QACzD,IAAI,EAAE,GAAG,CAAC,YAAY,CAAC,gBAAgB;QACvC,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE;YAC/C,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;YACF,MAAM,OAAO,GAAG,eAAe,CAAC;gBAC9B,iBAAiB,EAAE,GAAG,CAAC,OAAO,CAAC,iBAAiB,CAAC;gBACjD,GAAG,4BAA4B,CAAC,GAAG,CAAC;aACrC,CAAC,CAAA;YACF,MAAM,MAAM,GAAG,MAAM,2BAA2B,CAC9C;gBACE,GAAG,MAAM;gBACT,UAAU;gBACV,OAAO;gBACP,MAAM;aACP,EACD,GAAG,CACJ,CAAA;YACD,OAAO;gBACL,QAAQ,EAAE,kBAAkB;gBAC5B,IAAI,EAAE,MAAM;aACb,CAAA;QACH,CAAC;KACF,CAAC,CAAA;AACJ,CAAC;AAED,MAAM,QAAQ,GAAG,KAAK,EAAE,KAAuC,EAAE,EAAE;IACjE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,CAAA;IAC7B,IAAI,CAAC,GAAG,CAAC,iBAAiB,EAAE,CAAC;QAC3B,MAAM,IAAI,yBAAyB,CAAC,iCAAiC,CAAC,CAAA;IACxE,CAAC;IAED,OAAO,GAAG,CAAC,iBAAiB,CAAC,IAAI,CAC/B,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,mCAAmC,EACtD;QACE,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,MAAM,EAAE,MAAM,CAAC,UAAU,CAAC,MAAM,IAAI,SAAS;QAC7C,QAAQ,EAAE,MAAM,CAAC,QAAQ;KAC1B,EACD;QACE,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,MAAM,EAAE,MAAM,CAAC,MAAM;KACtB,CACF,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,IAAI,GAAG,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAA;IACtC,MAAM,KAAK,GAAgC,IAAI,GAAG,EAAE,CAAA;IACpD,MAAM,MAAM,GAAG,MAAM,CAAC,UAAU,CAAC,MAAM,CAAA;IACvC,IAAI,MAAM,EAAE,CAAC;QACX,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;IACzB,CAAC;IACD,MAAM,CAAC,aAAa,EAAE,mBAAmB,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QAC7D,GAAG,CAAC,QAAQ,CAAC,eAAe,CAAC,IAAI,EAAE,MAAM,CAAC,UAAU,CAAC;QACrD,GAAG,CAAC,QAAQ,CAAC,0BAA0B,CAAC,KAAK,EAAE,MAAM,CAAC,UAAU,CAAC;KAClE,CAAC,CAAA;IAEF,OAAO,eAAe,CAAC,aAAa,EAAE,EAAE,mBAAmB,EAAE,CAAC,CAAA;AAChE,CAAC,CAAA;AAED,MAAM,iBAAiB,GAAG,CACxB,KAAmD,EACnD,EAAE;IACF,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,KAAK,CAAA;IAClD,MAAM,MAAM,GAAG,MAAM,CAAC,UAAU,CAAC,MAAM,CAAA;IACvC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,QAAQ,CAAA;IACjB,CAAC;IACD,MAAM,MAAM,GAAG,SAAS,CAAC,mBAAmB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IACzD,OAAO;QACL,GAAG,QAAQ;QACX,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE;YACjC,MAAM,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,aAAa,CAAC,GAAG,EAAE,SAAS,CAAC,CAAA;YACtD,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,SAAS,CAAA;QAChD,CAAC,CAAC;KACH,CAAA;AACH,CAAC,CAAA;AAED,MAAM,YAAY,GAAG,CACnB,KAA0D,EAC1D,EAAE;IACF,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,KAAK,CAAA;IAC1C,OAAO;QACL,KAAK,EAAE,QAAQ,CAAC,KAAK;QACrB,QAAQ,EAAE,QAAQ,CAAC,QAAQ;QAC3B,MAAM,EAAE,UAAU,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,GAAG,EAAE,EAAE,CACxC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,SAAS,CAAC,CAClC;KACF,CAAA;AACH,CAAC,CAAA","sourcesContent":["import { dedupeStrs, mapDefined, noUndefinedVals } from '@atproto/common'\nimport type { Client, DidString } from '@atproto/lex'\nimport { MethodNotImplementedError, type Server } from '@atproto/xrpc-server'\nimport type { AppContext } from '../../../../context.js'\nimport {\n type HydrateCtx,\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 { getAtprotoPassthroughHeaders } from '../../../../util/headers.js'\nimport type { Views } from '../../../../views/index.js'\n\nexport default function (server: Server, ctx: AppContext) {\n const getSuggestedOnboardingUsers = createPipeline(\n skeleton,\n hydration,\n noBlocksOrFollows,\n presentation,\n )\n server.add(app.bsky.unspecced.getSuggestedOnboardingUsers, {\n auth: ctx.authVerifier.standardOptional,\n handler: async ({ auth, params, req, signal }) => {\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 const headers = noUndefinedVals({\n 'accept-language': req.headers['accept-language'],\n ...getAtprotoPassthroughHeaders(req),\n })\n const result = await getSuggestedOnboardingUsers(\n {\n ...params,\n hydrateCtx,\n headers,\n signal,\n },\n ctx,\n )\n return {\n encoding: 'application/json',\n body: result,\n }\n },\n })\n}\n\nconst skeleton = async (input: SkeletonFnInput<Context, Params>) => {\n const { params, ctx } = input\n if (!ctx.suggestionsClient) {\n throw new MethodNotImplementedError('Suggestions agent not available')\n }\n\n return ctx.suggestionsClient.call(\n app.bsky.unspecced.getOnboardingSuggestedUsersSkeleton,\n {\n limit: params.limit,\n viewer: params.hydrateCtx.viewer ?? undefined,\n category: params.category,\n },\n {\n headers: params.headers,\n signal: params.signal,\n },\n )\n}\n\nconst hydration = async (\n input: HydrationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, params, skeleton } = input\n const dids = dedupeStrs(skeleton.dids)\n const pairs: Map<DidString, DidString[]> = new Map()\n const viewer = params.hydrateCtx.viewer\n if (viewer) {\n pairs.set(viewer, dids)\n }\n const [profilesState, bidirectionalBlocks] = await Promise.all([\n ctx.hydrator.hydrateProfiles(dids, params.hydrateCtx),\n ctx.hydrator.hydrateBidirectionalBlocks(pairs, params.hydrateCtx),\n ])\n\n return mergeManyStates(profilesState, { bidirectionalBlocks })\n}\n\nconst noBlocksOrFollows = (\n input: RulesFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, skeleton, params, hydration } = input\n const viewer = params.hydrateCtx.viewer\n if (!viewer) {\n return skeleton\n }\n const blocks = hydration.bidirectionalBlocks?.get(viewer)\n return {\n ...skeleton,\n dids: skeleton.dids.filter((did) => {\n const viewer = ctx.views.profileViewer(did, hydration)\n return !blocks?.get(did) && !viewer?.following\n }),\n }\n}\n\nconst presentation = (\n input: PresentationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, skeleton, hydration } = input\n return {\n recId: skeleton.recId,\n recIdStr: skeleton.recIdStr,\n actors: mapDefined(skeleton.dids, (did) =>\n ctx.views.profile(did, hydration),\n ),\n }\n}\n\ntype Context = {\n hydrator: Hydrator\n views: Views\n topicsClient: Client | undefined\n suggestionsClient: Client | undefined\n}\n\ntype Params = app.bsky.unspecced.getSuggestedOnboardingUsers.$Params & {\n hydrateCtx: HydrateCtx & { viewer: string | null }\n headers: Record<string, string>\n signal: AbortSignal\n category?: string\n}\n\ntype SkeletonState = {\n dids: DidString[]\n recId?: string\n recIdStr?: string\n}\n"]}
1
+ {"version":3,"file":"getSuggestedOnboardingUsers.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/unspecced/getSuggestedOnboardingUsers.ts"],"names":[],"mappings":"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","sourcesContent":["import { dedupeStrs, mapDefined, noUndefinedVals } from '@atproto/common'\nimport type { Client, DidString } from '@atproto/lex'\nimport { MethodNotImplementedError, type Server } from '@atproto/xrpc-server'\nimport type { AppContext } from '../../../../context.js'\nimport {\n type HydrateCtx,\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 { getAtprotoPassthroughHeaders } from '../../../../util/headers.js'\nimport type { Views } from '../../../../views/index.js'\n\nexport default function (server: Server, ctx: AppContext) {\n const getSuggestedOnboardingUsers = createPipeline(\n skeleton,\n hydration,\n noBlocksOrFollows,\n presentation,\n )\n server.add(app.bsky.unspecced.getSuggestedOnboardingUsers, {\n auth: ctx.authVerifier.standardOptional,\n handler: async ({ auth, params, req, signal }) => {\n const viewer = auth.credentials.iss\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({\n labelers,\n viewer,\n features: ctx.featureGatesClient.scope(\n ctx.featureGatesClient.parseUserContextFromHandler({\n viewer,\n req,\n }),\n ),\n })\n const headers = noUndefinedVals({\n 'accept-language': req.headers['accept-language'],\n ...getAtprotoPassthroughHeaders(req),\n })\n const result = await getSuggestedOnboardingUsers(\n {\n ...params,\n hydrateCtx,\n headers,\n signal,\n },\n ctx,\n )\n return {\n encoding: 'application/json',\n body: result,\n }\n },\n })\n}\n\nconst skeleton = async (input: SkeletonFnInput<Context, Params>) => {\n const { params, ctx } = input\n const useIris = params.hydrateCtx.features.checkGate(\n params.hydrateCtx.features.Gate.SuggestedUsersIrisEnable,\n )\n const client = useIris ? ctx.irisClient : ctx.suggestionsClient\n if (!client) {\n const agent = useIris ? 'Iris' : 'Suggestions'\n throw new MethodNotImplementedError(`${agent} agent not available`)\n }\n\n return client.call(\n app.bsky.unspecced.getOnboardingSuggestedUsersSkeleton,\n {\n limit: params.limit,\n viewer: params.hydrateCtx.viewer ?? undefined,\n category: params.category,\n },\n {\n headers: params.headers,\n signal: params.signal,\n },\n )\n}\n\nconst hydration = async (\n input: HydrationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, params, skeleton } = input\n const dids = dedupeStrs(skeleton.dids)\n const pairs: Map<DidString, DidString[]> = new Map()\n const viewer = params.hydrateCtx.viewer\n if (viewer) {\n pairs.set(viewer, dids)\n }\n const [profilesState, bidirectionalBlocks] = await Promise.all([\n ctx.hydrator.hydrateProfiles(dids, params.hydrateCtx),\n ctx.hydrator.hydrateBidirectionalBlocks(pairs, params.hydrateCtx),\n ])\n\n return mergeManyStates(profilesState, { bidirectionalBlocks })\n}\n\nconst noBlocksOrFollows = (\n input: RulesFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, skeleton, params, hydration } = input\n const viewer = params.hydrateCtx.viewer\n if (!viewer) {\n return skeleton\n }\n const blocks = hydration.bidirectionalBlocks?.get(viewer)\n return {\n ...skeleton,\n dids: skeleton.dids.filter((did) => {\n const viewer = ctx.views.profileViewer(did, hydration)\n return !blocks?.get(did) && !viewer?.following\n }),\n }\n}\n\nconst presentation = (\n input: PresentationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, skeleton, hydration } = input\n return {\n recId: skeleton.recId,\n recIdStr: skeleton.recIdStr,\n actors: mapDefined(skeleton.dids, (did) =>\n ctx.views.profile(did, hydration),\n ),\n }\n}\n\ntype Context = {\n hydrator: Hydrator\n views: Views\n topicsClient: Client | undefined\n suggestionsClient: Client | undefined\n irisClient: Client | undefined\n}\n\ntype Params = app.bsky.unspecced.getSuggestedOnboardingUsers.$Params & {\n hydrateCtx: HydrateCtx & { viewer: string | null }\n headers: Record<string, string>\n signal: AbortSignal\n category?: string\n}\n\ntype SkeletonState = {\n dids: DidString[]\n recId?: string\n recIdStr?: string\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"getSuggestedStarterPacks.d.ts","sourceRoot":"","sources":["../../../../../src/api/app/bsky/unspecced/getSuggestedStarterPacks.ts"],"names":[],"mappings":"AAGA,OAAO,EAA6B,KAAK,MAAM,EAAE,MAAM,sBAAsB,CAAA;AAC7E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAiBxD,MAAM,CAAC,OAAO,WAAW,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,QAgCvD"}
1
+ {"version":3,"file":"getSuggestedStarterPacks.d.ts","sourceRoot":"","sources":["../../../../../src/api/app/bsky/unspecced/getSuggestedStarterPacks.ts"],"names":[],"mappings":"AAGA,OAAO,EAA6B,KAAK,MAAM,EAAE,MAAM,sBAAsB,CAAA;AAC7E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAiBxD,MAAM,CAAC,OAAO,WAAW,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,QAsCvD"}
@@ -12,7 +12,11 @@ export default function (server, ctx) {
12
12
  handler: async ({ auth, params, req, signal }) => {
13
13
  const viewer = auth.credentials.iss;
14
14
  const labelers = ctx.reqLabelers(req);
15
- const hydrateCtx = await ctx.hydrator.createContext({ labelers, viewer });
15
+ const hydrateCtx = await ctx.hydrator.createContext({
16
+ labelers,
17
+ viewer,
18
+ features: ctx.featureGatesClient.scope(ctx.featureGatesClient.parseUserContextFromHandler({ viewer, req })),
19
+ });
16
20
  const headers = noUndefinedVals({
17
21
  'accept-language': req.headers['accept-language'],
18
22
  ...getAtprotoPassthroughHeaders(req),
@@ -32,11 +36,14 @@ export default function (server, ctx) {
32
36
  }
33
37
  const skeleton = async (input) => {
34
38
  const { params, ctx } = input;
35
- if (!ctx.topicsClient) {
39
+ const useIris = params.hydrateCtx.features.checkGate(params.hydrateCtx.features.Gate.SuggestedStarterPacksV2Enable);
40
+ const client = useIris ? ctx.irisClient : ctx.topicsClient;
41
+ if (!client) {
36
42
  // Use 501 instead of 500 as these are not considered retry-able by clients
37
- throw new MethodNotImplementedError('Topics agent not available');
43
+ const agent = useIris ? 'Iris' : 'Topics';
44
+ throw new MethodNotImplementedError(`${agent} agent not available`);
38
45
  }
39
- const skeleton = await ctx.topicsClient.call(app.bsky.unspecced.getSuggestedStarterPacksSkeleton, {
46
+ const skeleton = await client.call(app.bsky.unspecced.getSuggestedStarterPacksSkeleton, {
40
47
  limit: params.limit,
41
48
  viewer: params.hydrateCtx.viewer ?? undefined,
42
49
  }, {
@@ -68,6 +75,7 @@ const noBlocks = (input) => {
68
75
  }
69
76
  const blocks = hydration.bidirectionalBlocks?.get(viewer);
70
77
  const filteredSkeleton = {
78
+ ...skeleton,
71
79
  starterPacks: skeleton.starterPacks.filter((uri) => {
72
80
  try {
73
81
  return !blocks?.get(new AtUri(uri).did);
@@ -83,6 +91,7 @@ const presentation = (input) => {
83
91
  const { ctx, skeleton, hydration } = input;
84
92
  return {
85
93
  starterPacks: mapDefined(skeleton.starterPacks, (uri) => ctx.views.starterPack(uri, hydration)),
94
+ recIdStr: skeleton.recIdStr,
86
95
  };
87
96
  };
88
97
  function getUniqueDidsFromStarterPacks(starterPacks) {
@@ -1 +1 @@
1
- {"version":3,"file":"getSuggestedStarterPacks.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/unspecced/getSuggestedStarterPacks.ts"],"names":[],"mappings":"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","sourcesContent":["import { mapDefined, noUndefinedVals } from '@atproto/common'\nimport type { Client } from '@atproto/lex'\nimport { AtUri, type AtUriString, type DidString } from '@atproto/syntax'\nimport { MethodNotImplementedError, type Server } from '@atproto/xrpc-server'\nimport type { AppContext } from '../../../../context.js'\nimport {\n type HydrateCtx,\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 { getAtprotoPassthroughHeaders } from '../../../../util/headers.js'\nimport type { Views } from '../../../../views/index.js'\n\nexport default function (server: Server, ctx: AppContext) {\n const getSuggestedStarterPacks = createPipeline(\n skeleton,\n hydration,\n noBlocks,\n presentation,\n )\n server.add(app.bsky.unspecced.getSuggestedStarterPacks, {\n auth: ctx.authVerifier.standardOptional,\n handler: async ({ auth, params, req, signal }) => {\n const viewer = auth.credentials.iss\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({ labelers, viewer })\n const headers = noUndefinedVals({\n 'accept-language': req.headers['accept-language'],\n ...getAtprotoPassthroughHeaders(req),\n })\n const result = await getSuggestedStarterPacks(\n {\n ...params,\n hydrateCtx,\n headers,\n signal,\n },\n ctx,\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\n if (!ctx.topicsClient) {\n // Use 501 instead of 500 as these are not considered retry-able by clients\n throw new MethodNotImplementedError('Topics agent not available')\n }\n\n const skeleton = await ctx.topicsClient.call(\n app.bsky.unspecced.getSuggestedStarterPacksSkeleton,\n {\n limit: params.limit,\n viewer: params.hydrateCtx.viewer ?? undefined,\n },\n {\n headers: params.headers,\n signal: params.signal,\n },\n )\n\n // @TODO Make sure upstream always provides this\n skeleton.starterPacks ??= []\n\n return skeleton\n}\n\nconst hydration = async (\n input: HydrationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, params, skeleton } = input\n\n const pairs: Map<DidString, DidString[]> = new Map()\n const viewer = params.hydrateCtx.viewer\n if (viewer) {\n pairs.set(viewer, getUniqueDidsFromStarterPacks(skeleton.starterPacks))\n }\n const [starterPacksState, bidirectionalBlocks] = await Promise.all([\n ctx.hydrator.hydrateStarterPacks(skeleton.starterPacks, params.hydrateCtx),\n ctx.hydrator.hydrateBidirectionalBlocks(pairs, params.hydrateCtx),\n ])\n\n return mergeManyStates(starterPacksState, { bidirectionalBlocks })\n}\n\nconst noBlocks = (input: RulesFnInput<Context, Params, SkeletonState>) => {\n const { skeleton, params, hydration } = input\n const viewer = params.hydrateCtx.viewer\n if (!viewer) {\n return skeleton\n }\n\n const blocks = hydration.bidirectionalBlocks?.get(viewer)\n const filteredSkeleton: SkeletonState = {\n starterPacks: skeleton.starterPacks.filter((uri) => {\n try {\n return !blocks?.get(new AtUri(uri).did)\n } catch {\n return false\n }\n }),\n }\n\n return filteredSkeleton\n}\n\nconst presentation = (\n input: PresentationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, skeleton, hydration } = input\n\n return {\n starterPacks: mapDefined(skeleton.starterPacks, (uri) =>\n ctx.views.starterPack(uri, hydration),\n ),\n }\n}\n\ntype Context = {\n hydrator: Hydrator\n views: Views\n topicsClient: Client | undefined\n}\n\ntype Params = app.bsky.unspecced.getSuggestedStarterPacks.$Params & {\n hydrateCtx: HydrateCtx & { viewer: string | null }\n headers: Record<string, string>\n signal: AbortSignal\n}\n\ntype SkeletonState = {\n starterPacks: AtUriString[]\n}\n\nfunction getUniqueDidsFromStarterPacks(\n starterPacks?: AtUriString[],\n): DidString[] {\n if (!starterPacks) return []\n\n const dids = new Set<DidString>()\n\n for (const uri of starterPacks) {\n try {\n dids.add(new AtUri(uri).did)\n } catch {\n continue\n }\n }\n\n return Array.from(dids)\n}\n"]}
1
+ {"version":3,"file":"getSuggestedStarterPacks.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/unspecced/getSuggestedStarterPacks.ts"],"names":[],"mappings":"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","sourcesContent":["import { mapDefined, noUndefinedVals } from '@atproto/common'\nimport type { Client } from '@atproto/lex'\nimport { AtUri, type AtUriString, type DidString } from '@atproto/syntax'\nimport { MethodNotImplementedError, type Server } from '@atproto/xrpc-server'\nimport type { AppContext } from '../../../../context.js'\nimport {\n type HydrateCtx,\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 { getAtprotoPassthroughHeaders } from '../../../../util/headers.js'\nimport type { Views } from '../../../../views/index.js'\n\nexport default function (server: Server, ctx: AppContext) {\n const getSuggestedStarterPacks = createPipeline(\n skeleton,\n hydration,\n noBlocks,\n presentation,\n )\n server.add(app.bsky.unspecced.getSuggestedStarterPacks, {\n auth: ctx.authVerifier.standardOptional,\n handler: async ({ auth, params, req, signal }) => {\n const viewer = auth.credentials.iss\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({\n labelers,\n viewer,\n features: ctx.featureGatesClient.scope(\n ctx.featureGatesClient.parseUserContextFromHandler({ viewer, req }),\n ),\n })\n const headers = noUndefinedVals({\n 'accept-language': req.headers['accept-language'],\n ...getAtprotoPassthroughHeaders(req),\n })\n const result = await getSuggestedStarterPacks(\n {\n ...params,\n hydrateCtx,\n headers,\n signal,\n },\n ctx,\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\n const useIris = params.hydrateCtx.features.checkGate(\n params.hydrateCtx.features.Gate.SuggestedStarterPacksV2Enable,\n )\n const client = useIris ? ctx.irisClient : ctx.topicsClient\n\n if (!client) {\n // Use 501 instead of 500 as these are not considered retry-able by clients\n const agent = useIris ? 'Iris' : 'Topics'\n throw new MethodNotImplementedError(`${agent} agent not available`)\n }\n\n const skeleton = await client.call(\n app.bsky.unspecced.getSuggestedStarterPacksSkeleton,\n {\n limit: params.limit,\n viewer: params.hydrateCtx.viewer ?? undefined,\n },\n {\n headers: params.headers,\n signal: params.signal,\n },\n )\n\n // @TODO Make sure upstream always provides this\n skeleton.starterPacks ??= []\n\n return skeleton\n}\n\nconst hydration = async (\n input: HydrationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, params, skeleton } = input\n\n const pairs: Map<DidString, DidString[]> = new Map()\n const viewer = params.hydrateCtx.viewer\n if (viewer) {\n pairs.set(viewer, getUniqueDidsFromStarterPacks(skeleton.starterPacks))\n }\n const [starterPacksState, bidirectionalBlocks] = await Promise.all([\n ctx.hydrator.hydrateStarterPacks(skeleton.starterPacks, params.hydrateCtx),\n ctx.hydrator.hydrateBidirectionalBlocks(pairs, params.hydrateCtx),\n ])\n\n return mergeManyStates(starterPacksState, { bidirectionalBlocks })\n}\n\nconst noBlocks = (input: RulesFnInput<Context, Params, SkeletonState>) => {\n const { skeleton, params, hydration } = input\n const viewer = params.hydrateCtx.viewer\n if (!viewer) {\n return skeleton\n }\n\n const blocks = hydration.bidirectionalBlocks?.get(viewer)\n const filteredSkeleton: SkeletonState = {\n ...skeleton,\n starterPacks: skeleton.starterPacks.filter((uri) => {\n try {\n return !blocks?.get(new AtUri(uri).did)\n } catch {\n return false\n }\n }),\n }\n\n return filteredSkeleton\n}\n\nconst presentation = (\n input: PresentationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, skeleton, hydration } = input\n\n return {\n starterPacks: mapDefined(skeleton.starterPacks, (uri) =>\n ctx.views.starterPack(uri, hydration),\n ),\n recIdStr: skeleton.recIdStr,\n }\n}\n\ntype Context = {\n hydrator: Hydrator\n views: Views\n topicsClient: Client | undefined\n irisClient: Client | undefined\n}\n\ntype Params = app.bsky.unspecced.getSuggestedStarterPacks.$Params & {\n hydrateCtx: HydrateCtx & { viewer: string | null }\n headers: Record<string, string>\n signal: AbortSignal\n}\n\ntype SkeletonState = {\n starterPacks: AtUriString[]\n recIdStr?: string\n}\n\nfunction getUniqueDidsFromStarterPacks(\n starterPacks?: AtUriString[],\n): DidString[] {\n if (!starterPacks) return []\n\n const dids = new Set<DidString>()\n\n for (const uri of starterPacks) {\n try {\n dids.add(new AtUri(uri).did)\n } catch {\n continue\n }\n }\n\n return Array.from(dids)\n}\n"]}
@@ -66,7 +66,25 @@ const skeletonFromTopics = async (input) => {
66
66
  signal: params.signal,
67
67
  });
68
68
  };
69
+ const skeletonFromIris = async (input) => {
70
+ const { params, ctx } = input;
71
+ if (!ctx.irisClient) {
72
+ throw new MethodNotImplementedError('Iris agent not available');
73
+ }
74
+ return ctx.irisClient.call(app.bsky.unspecced.getSuggestedUsersSkeleton, {
75
+ limit: params.limit,
76
+ category: params.category,
77
+ viewer: params.hydrateCtx.viewer ?? undefined,
78
+ }, {
79
+ headers: params.headers,
80
+ signal: params.signal,
81
+ });
82
+ };
69
83
  const skeleton = async (input) => {
84
+ const useIris = input.params.hydrateCtx.features.checkGate(input.params.hydrateCtx.features.Gate.SuggestedUsersIrisEnable);
85
+ if (useIris) {
86
+ return skeletonFromIris(input);
87
+ }
70
88
  const useDiscover = input.params.hydrateCtx.features.checkGate(input.params.hydrateCtx.features.Gate.SuggestedUsersDiscoverEnable);
71
89
  const skeletonFn = useDiscover ? skeletonFromDiscover : skeletonFromTopics;
72
90
  return skeletonFn(input);
@@ -1 +1 @@
1
- {"version":3,"file":"getSuggestedUsers.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/unspecced/getSuggestedUsers.ts"],"names":[],"mappings":"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","sourcesContent":["import { dedupeStrs, mapDefined, noUndefinedVals } from '@atproto/common'\nimport type { Client, DidString } from '@atproto/lex'\nimport { MethodNotImplementedError, type Server } from '@atproto/xrpc-server'\nimport type { AppContext } from '../../../../context.js'\nimport {\n type HydrateCtx,\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 { getAtprotoPassthroughHeaders } from '../../../../util/headers.js'\nimport type { Views } from '../../../../views/index.js'\n\nexport default function (server: Server, ctx: AppContext) {\n const getSuggestedUsers = createPipeline(\n skeleton,\n hydration,\n noBlocksOrFollows,\n presentation,\n )\n server.add(app.bsky.unspecced.getSuggestedUsers, {\n auth: ctx.authVerifier.standardOptional,\n handler: async ({ auth, params, req, signal }) => {\n const viewer = auth.credentials.iss\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({\n labelers,\n viewer,\n features: ctx.featureGatesClient.scope(\n ctx.featureGatesClient.parseUserContextFromHandler({\n viewer,\n req,\n }),\n ),\n })\n const headers = noUndefinedVals({\n 'accept-language': req.headers['accept-language'],\n ...getAtprotoPassthroughHeaders(req),\n })\n const result = await getSuggestedUsers(\n {\n ...params,\n hydrateCtx,\n headers,\n signal,\n },\n ctx,\n )\n return {\n encoding: 'application/json',\n body: result,\n }\n },\n })\n}\n\n// TODO: rename to `skeleton` once we can fully migrate to Discover\nconst skeletonFromDiscover = async (\n input: SkeletonFnInput<Context, Params>,\n): Promise<SkeletonState> => {\n const { params, ctx } = input\n if (!ctx.suggestionsClient) {\n throw new MethodNotImplementedError('Suggestions agent not available')\n }\n\n return ctx.suggestionsClient.call(\n app.bsky.unspecced.getSuggestedUsersSkeleton,\n {\n limit: params.limit,\n category: params.category,\n viewer: params.hydrateCtx.viewer ?? undefined,\n },\n {\n headers: params.headers,\n signal: params.signal,\n },\n )\n}\n\nconst skeletonFromTopics = async (\n input: SkeletonFnInput<Context, Params>,\n): Promise<SkeletonState> => {\n const { params, ctx } = input\n\n if (!ctx.topicsClient) {\n // Use 501 instead of 500 as these are not considered retry-able by clients\n throw new MethodNotImplementedError('Topics agent not available')\n }\n\n return ctx.topicsClient.call(\n app.bsky.unspecced.getSuggestedUsersSkeleton,\n {\n limit: params.limit,\n category: params.category,\n viewer: params.hydrateCtx.viewer ?? undefined,\n },\n {\n headers: params.headers,\n signal: params.signal,\n },\n )\n}\n\nconst skeleton = async (input: SkeletonFnInput<Context, Params>) => {\n const useDiscover = input.params.hydrateCtx.features.checkGate(\n input.params.hydrateCtx.features.Gate.SuggestedUsersDiscoverEnable,\n )\n const skeletonFn = useDiscover ? skeletonFromDiscover : skeletonFromTopics\n return skeletonFn(input)\n}\n\nconst hydration = async (\n input: HydrationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, params, skeleton } = input\n const dids = dedupeStrs(skeleton.dids)\n const pairs: Map<DidString, DidString[]> = new Map()\n const viewer = params.hydrateCtx.viewer\n if (viewer) {\n pairs.set(viewer, dids)\n }\n const [profilesState, bidirectionalBlocks] = await Promise.all([\n ctx.hydrator.hydrateProfiles(dids, params.hydrateCtx),\n ctx.hydrator.hydrateBidirectionalBlocks(pairs, params.hydrateCtx),\n ])\n\n return mergeManyStates(profilesState, { bidirectionalBlocks })\n}\n\nconst noBlocksOrFollows = (\n input: RulesFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, skeleton, params, hydration } = input\n const viewer = params.hydrateCtx.viewer\n if (!viewer) {\n return skeleton\n }\n const blocks = hydration.bidirectionalBlocks?.get(viewer)\n return {\n ...skeleton,\n dids: skeleton.dids.filter((did) => {\n const viewer = ctx.views.profileViewer(did, hydration)\n return !blocks?.get(did) && !viewer?.following\n }),\n }\n}\n\nconst presentation = (\n input: PresentationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, skeleton, hydration } = input\n return {\n recId: skeleton.recId,\n recIdStr: skeleton.recIdStr,\n actors: mapDefined(skeleton.dids, (did) =>\n ctx.views.profile(did, hydration),\n ),\n }\n}\n\ntype Context = {\n hydrator: Hydrator\n views: Views\n topicsClient: Client | undefined\n suggestionsClient: Client | undefined\n}\n\ntype Params = app.bsky.unspecced.getSuggestedUsers.$Params & {\n hydrateCtx: HydrateCtx & { viewer: string | null }\n headers: Record<string, string>\n signal: AbortSignal\n category?: string\n}\n\ntype SkeletonState = {\n dids: DidString[]\n recId?: string\n recIdStr?: string\n}\n"]}
1
+ {"version":3,"file":"getSuggestedUsers.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/unspecced/getSuggestedUsers.ts"],"names":[],"mappings":"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","sourcesContent":["import { dedupeStrs, mapDefined, noUndefinedVals } from '@atproto/common'\nimport type { Client, DidString } from '@atproto/lex'\nimport { MethodNotImplementedError, type Server } from '@atproto/xrpc-server'\nimport type { AppContext } from '../../../../context.js'\nimport {\n type HydrateCtx,\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 { getAtprotoPassthroughHeaders } from '../../../../util/headers.js'\nimport type { Views } from '../../../../views/index.js'\n\nexport default function (server: Server, ctx: AppContext) {\n const getSuggestedUsers = createPipeline(\n skeleton,\n hydration,\n noBlocksOrFollows,\n presentation,\n )\n server.add(app.bsky.unspecced.getSuggestedUsers, {\n auth: ctx.authVerifier.standardOptional,\n handler: async ({ auth, params, req, signal }) => {\n const viewer = auth.credentials.iss\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({\n labelers,\n viewer,\n features: ctx.featureGatesClient.scope(\n ctx.featureGatesClient.parseUserContextFromHandler({\n viewer,\n req,\n }),\n ),\n })\n const headers = noUndefinedVals({\n 'accept-language': req.headers['accept-language'],\n ...getAtprotoPassthroughHeaders(req),\n })\n const result = await getSuggestedUsers(\n {\n ...params,\n hydrateCtx,\n headers,\n signal,\n },\n ctx,\n )\n return {\n encoding: 'application/json',\n body: result,\n }\n },\n })\n}\n\n// TODO: rename to `skeleton` once we can fully migrate to Discover\nconst skeletonFromDiscover = async (\n input: SkeletonFnInput<Context, Params>,\n): Promise<SkeletonState> => {\n const { params, ctx } = input\n if (!ctx.suggestionsClient) {\n throw new MethodNotImplementedError('Suggestions agent not available')\n }\n\n return ctx.suggestionsClient.call(\n app.bsky.unspecced.getSuggestedUsersSkeleton,\n {\n limit: params.limit,\n category: params.category,\n viewer: params.hydrateCtx.viewer ?? undefined,\n },\n {\n headers: params.headers,\n signal: params.signal,\n },\n )\n}\n\nconst skeletonFromTopics = async (\n input: SkeletonFnInput<Context, Params>,\n): Promise<SkeletonState> => {\n const { params, ctx } = input\n\n if (!ctx.topicsClient) {\n // Use 501 instead of 500 as these are not considered retry-able by clients\n throw new MethodNotImplementedError('Topics agent not available')\n }\n\n return ctx.topicsClient.call(\n app.bsky.unspecced.getSuggestedUsersSkeleton,\n {\n limit: params.limit,\n category: params.category,\n viewer: params.hydrateCtx.viewer ?? undefined,\n },\n {\n headers: params.headers,\n signal: params.signal,\n },\n )\n}\n\nconst skeletonFromIris = async (\n input: SkeletonFnInput<Context, Params>,\n): Promise<SkeletonState> => {\n const { params, ctx } = input\n if (!ctx.irisClient) {\n throw new MethodNotImplementedError('Iris agent not available')\n }\n\n return ctx.irisClient.call(\n app.bsky.unspecced.getSuggestedUsersSkeleton,\n {\n limit: params.limit,\n category: params.category,\n viewer: params.hydrateCtx.viewer ?? undefined,\n },\n {\n headers: params.headers,\n signal: params.signal,\n },\n )\n}\n\nconst skeleton = async (input: SkeletonFnInput<Context, Params>) => {\n const useIris = input.params.hydrateCtx.features.checkGate(\n input.params.hydrateCtx.features.Gate.SuggestedUsersIrisEnable,\n )\n if (useIris) {\n return skeletonFromIris(input)\n }\n const useDiscover = input.params.hydrateCtx.features.checkGate(\n input.params.hydrateCtx.features.Gate.SuggestedUsersDiscoverEnable,\n )\n const skeletonFn = useDiscover ? skeletonFromDiscover : skeletonFromTopics\n return skeletonFn(input)\n}\n\nconst hydration = async (\n input: HydrationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, params, skeleton } = input\n const dids = dedupeStrs(skeleton.dids)\n const pairs: Map<DidString, DidString[]> = new Map()\n const viewer = params.hydrateCtx.viewer\n if (viewer) {\n pairs.set(viewer, dids)\n }\n const [profilesState, bidirectionalBlocks] = await Promise.all([\n ctx.hydrator.hydrateProfiles(dids, params.hydrateCtx),\n ctx.hydrator.hydrateBidirectionalBlocks(pairs, params.hydrateCtx),\n ])\n\n return mergeManyStates(profilesState, { bidirectionalBlocks })\n}\n\nconst noBlocksOrFollows = (\n input: RulesFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, skeleton, params, hydration } = input\n const viewer = params.hydrateCtx.viewer\n if (!viewer) {\n return skeleton\n }\n const blocks = hydration.bidirectionalBlocks?.get(viewer)\n return {\n ...skeleton,\n dids: skeleton.dids.filter((did) => {\n const viewer = ctx.views.profileViewer(did, hydration)\n return !blocks?.get(did) && !viewer?.following\n }),\n }\n}\n\nconst presentation = (\n input: PresentationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, skeleton, hydration } = input\n return {\n recId: skeleton.recId,\n recIdStr: skeleton.recIdStr,\n actors: mapDefined(skeleton.dids, (did) =>\n ctx.views.profile(did, hydration),\n ),\n }\n}\n\ntype Context = {\n hydrator: Hydrator\n views: Views\n topicsClient: Client | undefined\n suggestionsClient: Client | undefined\n irisClient: Client | undefined\n}\n\ntype Params = app.bsky.unspecced.getSuggestedUsers.$Params & {\n hydrateCtx: HydrateCtx & { viewer: string | null }\n headers: Record<string, string>\n signal: AbortSignal\n category?: string\n}\n\ntype SkeletonState = {\n dids: DidString[]\n recId?: string\n recIdStr?: string\n}\n"]}
@@ -61,7 +61,24 @@ const skeletonFromGetSuggestedUsersForDiscoverSkeleton = async (input) => {
61
61
  signal: params.signal,
62
62
  });
63
63
  };
64
+ const skeletonFromIris = async (input) => {
65
+ const { params, ctx } = input;
66
+ if (!ctx.irisClient) {
67
+ throw new MethodNotImplementedError('Iris agent not available');
68
+ }
69
+ return ctx.irisClient.call(app.bsky.unspecced.getSuggestedUsersForDiscoverSkeleton, {
70
+ limit: params.limit,
71
+ viewer: params.hydrateCtx.viewer ?? undefined,
72
+ }, {
73
+ headers: params.headers,
74
+ signal: params.signal,
75
+ });
76
+ };
64
77
  const skeleton = async (input) => {
78
+ const useIris = input.params.hydrateCtx.features.checkGate(input.params.hydrateCtx.features.Gate.SuggestedUsersIrisEnable);
79
+ if (useIris) {
80
+ return skeletonFromIris(input);
81
+ }
65
82
  const useDiscover = input.params.hydrateCtx.features.checkGate(input.params.hydrateCtx.features.Gate.SuggestedUsersForDiscoverEnable);
66
83
  const skeletonFn = useDiscover
67
84
  ? skeletonFromGetSuggestedUsersForDiscoverSkeleton
@@ -1 +1 @@
1
- {"version":3,"file":"getSuggestedUsersForDiscover.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/unspecced/getSuggestedUsersForDiscover.ts"],"names":[],"mappings":"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","sourcesContent":["import { dedupeStrs, mapDefined, noUndefinedVals } from '@atproto/common'\nimport type { Client, DidString } from '@atproto/lex'\nimport { MethodNotImplementedError, type Server } from '@atproto/xrpc-server'\nimport type { AppContext } from '../../../../context.js'\nimport {\n type HydrateCtx,\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 { Views } from '../../../../views/index.js'\n\nexport default function (server: Server, ctx: AppContext) {\n const getSuggestedUsersForDiscover = createPipeline(\n skeleton,\n hydration,\n noBlocksOrFollows,\n presentation,\n )\n server.add(app.bsky.unspecced.getSuggestedUsersForDiscover, {\n auth: ctx.authVerifier.standardOptional,\n handler: async ({ auth, params, req, signal }) => {\n const viewer = auth.credentials.iss\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({\n labelers,\n viewer,\n features: ctx.featureGatesClient.scope(\n ctx.featureGatesClient.parseUserContextFromHandler({\n viewer,\n req,\n }),\n ),\n })\n const headers = noUndefinedVals({\n 'accept-language': req.headers['accept-language'],\n })\n const result = await getSuggestedUsersForDiscover(\n {\n ...params,\n hydrateCtx,\n headers,\n signal,\n },\n ctx,\n )\n return {\n encoding: 'application/json',\n body: result,\n }\n },\n })\n}\n\nconst skeletonFromGetSuggestedUsersSkeleton = async (\n input: SkeletonFnInput<Context, Params>,\n): Promise<SkeletonState> => {\n const { params, ctx } = input\n if (!ctx.suggestionsClient) {\n throw new MethodNotImplementedError('Suggestions agent not available')\n }\n\n return ctx.suggestionsClient.call(\n app.bsky.unspecced.getSuggestedUsersSkeleton,\n {\n limit: params.limit,\n viewer: params.hydrateCtx.viewer ?? undefined,\n },\n {\n headers: params.headers,\n signal: params.signal,\n },\n )\n}\n\n// TODO: rename to `skeleton` once we can fully migrate to the new endpoint\nconst skeletonFromGetSuggestedUsersForDiscoverSkeleton = async (\n input: SkeletonFnInput<Context, Params>,\n): Promise<SkeletonState> => {\n const { params, ctx } = input\n\n if (!ctx.suggestionsClient) {\n throw new MethodNotImplementedError('Suggestions agent not available')\n }\n\n return ctx.suggestionsClient.call(\n app.bsky.unspecced.getSuggestedUsersForDiscoverSkeleton,\n {\n limit: params.limit,\n viewer: params.hydrateCtx.viewer ?? undefined,\n },\n {\n headers: params.headers,\n signal: params.signal,\n },\n )\n}\n\nconst skeleton = async (input: SkeletonFnInput<Context, Params>) => {\n const useDiscover = input.params.hydrateCtx.features.checkGate(\n input.params.hydrateCtx.features.Gate.SuggestedUsersForDiscoverEnable,\n )\n const skeletonFn = useDiscover\n ? skeletonFromGetSuggestedUsersForDiscoverSkeleton\n : skeletonFromGetSuggestedUsersSkeleton\n return skeletonFn(input)\n}\n\nconst hydration = async (\n input: HydrationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, params, skeleton } = input\n const dids = dedupeStrs(skeleton.dids)\n const pairs: Map<DidString, DidString[]> = new Map()\n const viewer = params.hydrateCtx.viewer\n if (viewer) {\n pairs.set(viewer, dids)\n }\n const [profilesState, bidirectionalBlocks] = await Promise.all([\n ctx.hydrator.hydrateProfiles(dids, params.hydrateCtx),\n ctx.hydrator.hydrateBidirectionalBlocks(pairs, params.hydrateCtx),\n ])\n\n return mergeManyStates(profilesState, { bidirectionalBlocks })\n}\n\nconst noBlocksOrFollows = (\n input: RulesFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, skeleton, params, hydration } = input\n const viewer = params.hydrateCtx.viewer\n if (!viewer) {\n return skeleton\n }\n const blocks = hydration.bidirectionalBlocks?.get(viewer)\n return {\n ...skeleton,\n dids: skeleton.dids.filter((did) => {\n const viewer = ctx.views.profileViewer(did, hydration)\n return !blocks?.get(did) && !viewer?.following\n }),\n }\n}\n\nconst presentation = (\n input: PresentationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, skeleton, hydration } = input\n return {\n recIdStr: skeleton.recIdStr,\n actors: mapDefined(skeleton.dids, (did) =>\n ctx.views.profile(did, hydration),\n ),\n }\n}\n\ntype Context = {\n hydrator: Hydrator\n views: Views\n suggestionsClient: Client | undefined\n}\n\ntype Params = app.bsky.unspecced.getSuggestedUsersForDiscover.$Params & {\n hydrateCtx: HydrateCtx & { viewer: string | null }\n headers: Record<string, string>\n signal: AbortSignal\n}\n\ntype SkeletonState = {\n dids: DidString[]\n recIdStr?: string\n}\n"]}
1
+ {"version":3,"file":"getSuggestedUsersForDiscover.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/unspecced/getSuggestedUsersForDiscover.ts"],"names":[],"mappings":"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","sourcesContent":["import { dedupeStrs, mapDefined, noUndefinedVals } from '@atproto/common'\nimport type { Client, DidString } from '@atproto/lex'\nimport { MethodNotImplementedError, type Server } from '@atproto/xrpc-server'\nimport type { AppContext } from '../../../../context.js'\nimport {\n type HydrateCtx,\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 { Views } from '../../../../views/index.js'\n\nexport default function (server: Server, ctx: AppContext) {\n const getSuggestedUsersForDiscover = createPipeline(\n skeleton,\n hydration,\n noBlocksOrFollows,\n presentation,\n )\n server.add(app.bsky.unspecced.getSuggestedUsersForDiscover, {\n auth: ctx.authVerifier.standardOptional,\n handler: async ({ auth, params, req, signal }) => {\n const viewer = auth.credentials.iss\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({\n labelers,\n viewer,\n features: ctx.featureGatesClient.scope(\n ctx.featureGatesClient.parseUserContextFromHandler({\n viewer,\n req,\n }),\n ),\n })\n const headers = noUndefinedVals({\n 'accept-language': req.headers['accept-language'],\n })\n const result = await getSuggestedUsersForDiscover(\n {\n ...params,\n hydrateCtx,\n headers,\n signal,\n },\n ctx,\n )\n return {\n encoding: 'application/json',\n body: result,\n }\n },\n })\n}\n\nconst skeletonFromGetSuggestedUsersSkeleton = async (\n input: SkeletonFnInput<Context, Params>,\n): Promise<SkeletonState> => {\n const { params, ctx } = input\n if (!ctx.suggestionsClient) {\n throw new MethodNotImplementedError('Suggestions agent not available')\n }\n\n return ctx.suggestionsClient.call(\n app.bsky.unspecced.getSuggestedUsersSkeleton,\n {\n limit: params.limit,\n viewer: params.hydrateCtx.viewer ?? undefined,\n },\n {\n headers: params.headers,\n signal: params.signal,\n },\n )\n}\n\n// TODO: rename to `skeleton` once we can fully migrate to the new endpoint\nconst skeletonFromGetSuggestedUsersForDiscoverSkeleton = async (\n input: SkeletonFnInput<Context, Params>,\n): Promise<SkeletonState> => {\n const { params, ctx } = input\n\n if (!ctx.suggestionsClient) {\n throw new MethodNotImplementedError('Suggestions agent not available')\n }\n\n return ctx.suggestionsClient.call(\n app.bsky.unspecced.getSuggestedUsersForDiscoverSkeleton,\n {\n limit: params.limit,\n viewer: params.hydrateCtx.viewer ?? undefined,\n },\n {\n headers: params.headers,\n signal: params.signal,\n },\n )\n}\n\nconst skeletonFromIris = async (\n input: SkeletonFnInput<Context, Params>,\n): Promise<SkeletonState> => {\n const { params, ctx } = input\n\n if (!ctx.irisClient) {\n throw new MethodNotImplementedError('Iris agent not available')\n }\n\n return ctx.irisClient.call(\n app.bsky.unspecced.getSuggestedUsersForDiscoverSkeleton,\n {\n limit: params.limit,\n viewer: params.hydrateCtx.viewer ?? undefined,\n },\n {\n headers: params.headers,\n signal: params.signal,\n },\n )\n}\n\nconst skeleton = async (input: SkeletonFnInput<Context, Params>) => {\n const useIris = input.params.hydrateCtx.features.checkGate(\n input.params.hydrateCtx.features.Gate.SuggestedUsersIrisEnable,\n )\n if (useIris) {\n return skeletonFromIris(input)\n }\n const useDiscover = input.params.hydrateCtx.features.checkGate(\n input.params.hydrateCtx.features.Gate.SuggestedUsersForDiscoverEnable,\n )\n const skeletonFn = useDiscover\n ? skeletonFromGetSuggestedUsersForDiscoverSkeleton\n : skeletonFromGetSuggestedUsersSkeleton\n return skeletonFn(input)\n}\n\nconst hydration = async (\n input: HydrationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, params, skeleton } = input\n const dids = dedupeStrs(skeleton.dids)\n const pairs: Map<DidString, DidString[]> = new Map()\n const viewer = params.hydrateCtx.viewer\n if (viewer) {\n pairs.set(viewer, dids)\n }\n const [profilesState, bidirectionalBlocks] = await Promise.all([\n ctx.hydrator.hydrateProfiles(dids, params.hydrateCtx),\n ctx.hydrator.hydrateBidirectionalBlocks(pairs, params.hydrateCtx),\n ])\n\n return mergeManyStates(profilesState, { bidirectionalBlocks })\n}\n\nconst noBlocksOrFollows = (\n input: RulesFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, skeleton, params, hydration } = input\n const viewer = params.hydrateCtx.viewer\n if (!viewer) {\n return skeleton\n }\n const blocks = hydration.bidirectionalBlocks?.get(viewer)\n return {\n ...skeleton,\n dids: skeleton.dids.filter((did) => {\n const viewer = ctx.views.profileViewer(did, hydration)\n return !blocks?.get(did) && !viewer?.following\n }),\n }\n}\n\nconst presentation = (\n input: PresentationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, skeleton, hydration } = input\n return {\n recIdStr: skeleton.recIdStr,\n actors: mapDefined(skeleton.dids, (did) =>\n ctx.views.profile(did, hydration),\n ),\n }\n}\n\ntype Context = {\n hydrator: Hydrator\n views: Views\n suggestionsClient: Client | undefined\n irisClient: Client | undefined\n}\n\ntype Params = app.bsky.unspecced.getSuggestedUsersForDiscover.$Params & {\n hydrateCtx: HydrateCtx & { viewer: string | null }\n headers: Record<string, string>\n signal: AbortSignal\n}\n\ntype SkeletonState = {\n dids: DidString[]\n recIdStr?: string\n}\n"]}
@@ -63,7 +63,25 @@ const skeletonFromGetSuggestedUsersForExploreSkeleton = async (input) => {
63
63
  signal: params.signal,
64
64
  });
65
65
  };
66
+ const skeletonFromIris = async (input) => {
67
+ const { params, ctx } = input;
68
+ if (!ctx.irisClient) {
69
+ throw new MethodNotImplementedError('Iris agent not available');
70
+ }
71
+ return ctx.irisClient.call(app.bsky.unspecced.getSuggestedUsersForExploreSkeleton, {
72
+ limit: params.limit,
73
+ category: params.category,
74
+ viewer: params.hydrateCtx.viewer ?? undefined,
75
+ }, {
76
+ headers: params.headers,
77
+ signal: params.signal,
78
+ });
79
+ };
66
80
  const skeleton = async (input) => {
81
+ const useIris = input.params.hydrateCtx.features.checkGate(input.params.hydrateCtx.features.Gate.SuggestedUsersIrisEnable);
82
+ if (useIris) {
83
+ return skeletonFromIris(input);
84
+ }
67
85
  const useExplore = input.params.hydrateCtx.features.checkGate(input.params.hydrateCtx.features.Gate.SuggestedUsersForExploreEnable);
68
86
  const skeletonFn = useExplore
69
87
  ? skeletonFromGetSuggestedUsersForExploreSkeleton
@@ -1 +1 @@
1
- {"version":3,"file":"getSuggestedUsersForExplore.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/unspecced/getSuggestedUsersForExplore.ts"],"names":[],"mappings":"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","sourcesContent":["import { dedupeStrs, mapDefined, noUndefinedVals } from '@atproto/common'\nimport type { Client, DidString } from '@atproto/lex'\nimport { MethodNotImplementedError, type Server } from '@atproto/xrpc-server'\nimport type { AppContext } from '../../../../context.js'\nimport {\n type HydrateCtx,\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 { Views } from '../../../../views/index.js'\n\nexport default function (server: Server, ctx: AppContext) {\n const getSuggestedUsersForExplore = createPipeline(\n skeleton,\n hydration,\n noBlocksOrFollows,\n presentation,\n )\n server.add(app.bsky.unspecced.getSuggestedUsersForExplore, {\n auth: ctx.authVerifier.standardOptional,\n handler: async ({ auth, params, req, signal }) => {\n const viewer = auth.credentials.iss\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({\n labelers,\n viewer,\n features: ctx.featureGatesClient.scope(\n ctx.featureGatesClient.parseUserContextFromHandler({\n viewer,\n req,\n }),\n ),\n })\n const headers = noUndefinedVals({\n 'accept-language': req.headers['accept-language'],\n })\n const result = await getSuggestedUsersForExplore(\n {\n ...params,\n hydrateCtx,\n headers,\n signal,\n },\n ctx,\n )\n return {\n encoding: 'application/json',\n body: result,\n }\n },\n })\n}\n\nconst skeletonFromGetSuggestedUsersSkeleton = async (\n input: SkeletonFnInput<Context, Params>,\n): Promise<SkeletonState> => {\n const { params, ctx } = input\n if (!ctx.suggestionsClient) {\n throw new MethodNotImplementedError('Suggestions agent not available')\n }\n\n return ctx.suggestionsClient.call(\n app.bsky.unspecced.getSuggestedUsersSkeleton,\n {\n limit: params.limit,\n category: params.category,\n viewer: params.hydrateCtx.viewer ?? undefined,\n },\n {\n headers: params.headers,\n signal: params.signal,\n },\n )\n}\n\n// TODO: rename to `skeleton` once we can fully migrate to the new endpoint\nconst skeletonFromGetSuggestedUsersForExploreSkeleton = async (\n input: SkeletonFnInput<Context, Params>,\n): Promise<SkeletonState> => {\n const { params, ctx } = input\n\n if (!ctx.suggestionsClient) {\n throw new MethodNotImplementedError('Suggestions agent not available')\n }\n\n return ctx.suggestionsClient.call(\n app.bsky.unspecced.getSuggestedUsersForExploreSkeleton,\n {\n limit: params.limit,\n category: params.category,\n viewer: params.hydrateCtx.viewer ?? undefined,\n },\n {\n headers: params.headers,\n signal: params.signal,\n },\n )\n}\n\nconst skeleton = async (input: SkeletonFnInput<Context, Params>) => {\n const useExplore = input.params.hydrateCtx.features.checkGate(\n input.params.hydrateCtx.features.Gate.SuggestedUsersForExploreEnable,\n )\n const skeletonFn = useExplore\n ? skeletonFromGetSuggestedUsersForExploreSkeleton\n : skeletonFromGetSuggestedUsersSkeleton\n return skeletonFn(input)\n}\n\nconst hydration = async (\n input: HydrationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, params, skeleton } = input\n const dids = dedupeStrs(skeleton.dids)\n const pairs: Map<DidString, DidString[]> = new Map()\n const viewer = params.hydrateCtx.viewer\n if (viewer) {\n pairs.set(viewer, dids)\n }\n const [profilesState, bidirectionalBlocks] = await Promise.all([\n ctx.hydrator.hydrateProfiles(dids, params.hydrateCtx),\n ctx.hydrator.hydrateBidirectionalBlocks(pairs, params.hydrateCtx),\n ])\n\n return mergeManyStates(profilesState, { bidirectionalBlocks })\n}\n\nconst noBlocksOrFollows = (\n input: RulesFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, skeleton, params, hydration } = input\n const viewer = params.hydrateCtx.viewer\n if (!viewer) {\n return skeleton\n }\n const blocks = hydration.bidirectionalBlocks?.get(viewer)\n return {\n ...skeleton,\n dids: skeleton.dids.filter((did) => {\n const viewer = ctx.views.profileViewer(did, hydration)\n return !blocks?.get(did) && !viewer?.following\n }),\n }\n}\n\nconst presentation = (\n input: PresentationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, skeleton, hydration } = input\n return {\n recIdStr: skeleton.recIdStr,\n actors: mapDefined(skeleton.dids, (did) =>\n ctx.views.profile(did, hydration),\n ),\n }\n}\n\ntype Context = {\n hydrator: Hydrator\n views: Views\n suggestionsClient: Client | undefined\n}\n\ntype Params = app.bsky.unspecced.getSuggestedUsersForExplore.$Params & {\n hydrateCtx: HydrateCtx & { viewer: string | null }\n headers: Record<string, string>\n signal: AbortSignal\n category?: string\n}\n\ntype SkeletonState = {\n dids: DidString[]\n recIdStr?: string\n}\n"]}
1
+ {"version":3,"file":"getSuggestedUsersForExplore.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/unspecced/getSuggestedUsersForExplore.ts"],"names":[],"mappings":"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","sourcesContent":["import { dedupeStrs, mapDefined, noUndefinedVals } from '@atproto/common'\nimport type { Client, DidString } from '@atproto/lex'\nimport { MethodNotImplementedError, type Server } from '@atproto/xrpc-server'\nimport type { AppContext } from '../../../../context.js'\nimport {\n type HydrateCtx,\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 { Views } from '../../../../views/index.js'\n\nexport default function (server: Server, ctx: AppContext) {\n const getSuggestedUsersForExplore = createPipeline(\n skeleton,\n hydration,\n noBlocksOrFollows,\n presentation,\n )\n server.add(app.bsky.unspecced.getSuggestedUsersForExplore, {\n auth: ctx.authVerifier.standardOptional,\n handler: async ({ auth, params, req, signal }) => {\n const viewer = auth.credentials.iss\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({\n labelers,\n viewer,\n features: ctx.featureGatesClient.scope(\n ctx.featureGatesClient.parseUserContextFromHandler({\n viewer,\n req,\n }),\n ),\n })\n const headers = noUndefinedVals({\n 'accept-language': req.headers['accept-language'],\n })\n const result = await getSuggestedUsersForExplore(\n {\n ...params,\n hydrateCtx,\n headers,\n signal,\n },\n ctx,\n )\n return {\n encoding: 'application/json',\n body: result,\n }\n },\n })\n}\n\nconst skeletonFromGetSuggestedUsersSkeleton = async (\n input: SkeletonFnInput<Context, Params>,\n): Promise<SkeletonState> => {\n const { params, ctx } = input\n if (!ctx.suggestionsClient) {\n throw new MethodNotImplementedError('Suggestions agent not available')\n }\n\n return ctx.suggestionsClient.call(\n app.bsky.unspecced.getSuggestedUsersSkeleton,\n {\n limit: params.limit,\n category: params.category,\n viewer: params.hydrateCtx.viewer ?? undefined,\n },\n {\n headers: params.headers,\n signal: params.signal,\n },\n )\n}\n\n// TODO: rename to `skeleton` once we can fully migrate to the new endpoint\nconst skeletonFromGetSuggestedUsersForExploreSkeleton = async (\n input: SkeletonFnInput<Context, Params>,\n): Promise<SkeletonState> => {\n const { params, ctx } = input\n\n if (!ctx.suggestionsClient) {\n throw new MethodNotImplementedError('Suggestions agent not available')\n }\n\n return ctx.suggestionsClient.call(\n app.bsky.unspecced.getSuggestedUsersForExploreSkeleton,\n {\n limit: params.limit,\n category: params.category,\n viewer: params.hydrateCtx.viewer ?? undefined,\n },\n {\n headers: params.headers,\n signal: params.signal,\n },\n )\n}\n\nconst skeletonFromIris = async (\n input: SkeletonFnInput<Context, Params>,\n): Promise<SkeletonState> => {\n const { params, ctx } = input\n\n if (!ctx.irisClient) {\n throw new MethodNotImplementedError('Iris agent not available')\n }\n\n return ctx.irisClient.call(\n app.bsky.unspecced.getSuggestedUsersForExploreSkeleton,\n {\n limit: params.limit,\n category: params.category,\n viewer: params.hydrateCtx.viewer ?? undefined,\n },\n {\n headers: params.headers,\n signal: params.signal,\n },\n )\n}\n\nconst skeleton = async (input: SkeletonFnInput<Context, Params>) => {\n const useIris = input.params.hydrateCtx.features.checkGate(\n input.params.hydrateCtx.features.Gate.SuggestedUsersIrisEnable,\n )\n if (useIris) {\n return skeletonFromIris(input)\n }\n const useExplore = input.params.hydrateCtx.features.checkGate(\n input.params.hydrateCtx.features.Gate.SuggestedUsersForExploreEnable,\n )\n const skeletonFn = useExplore\n ? skeletonFromGetSuggestedUsersForExploreSkeleton\n : skeletonFromGetSuggestedUsersSkeleton\n return skeletonFn(input)\n}\n\nconst hydration = async (\n input: HydrationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, params, skeleton } = input\n const dids = dedupeStrs(skeleton.dids)\n const pairs: Map<DidString, DidString[]> = new Map()\n const viewer = params.hydrateCtx.viewer\n if (viewer) {\n pairs.set(viewer, dids)\n }\n const [profilesState, bidirectionalBlocks] = await Promise.all([\n ctx.hydrator.hydrateProfiles(dids, params.hydrateCtx),\n ctx.hydrator.hydrateBidirectionalBlocks(pairs, params.hydrateCtx),\n ])\n\n return mergeManyStates(profilesState, { bidirectionalBlocks })\n}\n\nconst noBlocksOrFollows = (\n input: RulesFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, skeleton, params, hydration } = input\n const viewer = params.hydrateCtx.viewer\n if (!viewer) {\n return skeleton\n }\n const blocks = hydration.bidirectionalBlocks?.get(viewer)\n return {\n ...skeleton,\n dids: skeleton.dids.filter((did) => {\n const viewer = ctx.views.profileViewer(did, hydration)\n return !blocks?.get(did) && !viewer?.following\n }),\n }\n}\n\nconst presentation = (\n input: PresentationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, skeleton, hydration } = input\n return {\n recIdStr: skeleton.recIdStr,\n actors: mapDefined(skeleton.dids, (did) =>\n ctx.views.profile(did, hydration),\n ),\n }\n}\n\ntype Context = {\n hydrator: Hydrator\n views: Views\n suggestionsClient: Client | undefined\n irisClient: Client | undefined\n}\n\ntype Params = app.bsky.unspecced.getSuggestedUsersForExplore.$Params & {\n hydrateCtx: HydrateCtx & { viewer: string | null }\n headers: Record<string, string>\n signal: AbortSignal\n category?: string\n}\n\ntype SkeletonState = {\n dids: DidString[]\n recIdStr?: string\n}\n"]}
@@ -63,7 +63,25 @@ const skeletonFromGetSuggestedUsersForSeeMoreSkeleton = async (input) => {
63
63
  signal: params.signal,
64
64
  });
65
65
  };
66
+ const skeletonFromIris = async (input) => {
67
+ const { params, ctx } = input;
68
+ if (!ctx.irisClient) {
69
+ throw new MethodNotImplementedError('Iris agent not available');
70
+ }
71
+ return ctx.irisClient.call(app.bsky.unspecced.getSuggestedUsersForSeeMoreSkeleton, {
72
+ limit: params.limit,
73
+ category: params.category,
74
+ viewer: params.hydrateCtx.viewer ?? undefined,
75
+ }, {
76
+ headers: params.headers,
77
+ signal: params.signal,
78
+ });
79
+ };
66
80
  const skeleton = async (input) => {
81
+ const useIris = input.params.hydrateCtx.features.checkGate(input.params.hydrateCtx.features.Gate.SuggestedUsersIrisEnable);
82
+ if (useIris) {
83
+ return skeletonFromIris(input);
84
+ }
67
85
  const useSeeMore = input.params.hydrateCtx.features.checkGate(input.params.hydrateCtx.features.Gate.SuggestedUsersForSeeMoreEnable);
68
86
  const skeletonFn = useSeeMore
69
87
  ? skeletonFromGetSuggestedUsersForSeeMoreSkeleton
@@ -1 +1 @@
1
- {"version":3,"file":"getSuggestedUsersForSeeMore.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/unspecced/getSuggestedUsersForSeeMore.ts"],"names":[],"mappings":"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","sourcesContent":["import { dedupeStrs, mapDefined, noUndefinedVals } from '@atproto/common'\nimport type { Client, DidString } from '@atproto/lex'\nimport { MethodNotImplementedError, type Server } from '@atproto/xrpc-server'\nimport type { AppContext } from '../../../../context.js'\nimport {\n type HydrateCtx,\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 { Views } from '../../../../views/index.js'\n\nexport default function (server: Server, ctx: AppContext) {\n const getSuggestedUsersForSeeMore = createPipeline(\n skeleton,\n hydration,\n noBlocksOrFollows,\n presentation,\n )\n server.add(app.bsky.unspecced.getSuggestedUsersForSeeMore, {\n auth: ctx.authVerifier.standardOptional,\n handler: async ({ auth, params, req, signal }) => {\n const viewer = auth.credentials.iss\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({\n labelers,\n viewer,\n features: ctx.featureGatesClient.scope(\n ctx.featureGatesClient.parseUserContextFromHandler({\n viewer,\n req,\n }),\n ),\n })\n const headers = noUndefinedVals({\n 'accept-language': req.headers['accept-language'],\n })\n const result = await getSuggestedUsersForSeeMore(\n {\n ...params,\n hydrateCtx,\n headers,\n signal,\n },\n ctx,\n )\n return {\n encoding: 'application/json',\n body: result,\n }\n },\n })\n}\n\nconst skeletonFromGetSuggestedUsersSkeleton = async (\n input: SkeletonFnInput<Context, Params>,\n): Promise<SkeletonState> => {\n const { params, ctx } = input\n if (!ctx.suggestionsClient) {\n throw new MethodNotImplementedError('Suggestions agent not available')\n }\n\n return ctx.suggestionsClient.call(\n app.bsky.unspecced.getSuggestedUsersSkeleton,\n {\n limit: params.limit,\n category: params.category,\n viewer: params.hydrateCtx.viewer ?? undefined,\n },\n {\n headers: params.headers,\n signal: params.signal,\n },\n )\n}\n\n// TODO: rename to `skeleton` once we can fully migrate to the new endpoint\nconst skeletonFromGetSuggestedUsersForSeeMoreSkeleton = async (\n input: SkeletonFnInput<Context, Params>,\n): Promise<SkeletonState> => {\n const { params, ctx } = input\n\n if (!ctx.suggestionsClient) {\n throw new MethodNotImplementedError('Suggestions agent not available')\n }\n\n return ctx.suggestionsClient.call(\n app.bsky.unspecced.getSuggestedUsersForSeeMoreSkeleton,\n {\n limit: params.limit,\n category: params.category,\n viewer: params.hydrateCtx.viewer ?? undefined,\n },\n {\n headers: params.headers,\n signal: params.signal,\n },\n )\n}\n\nconst skeleton = async (input: SkeletonFnInput<Context, Params>) => {\n const useSeeMore = input.params.hydrateCtx.features.checkGate(\n input.params.hydrateCtx.features.Gate.SuggestedUsersForSeeMoreEnable,\n )\n const skeletonFn = useSeeMore\n ? skeletonFromGetSuggestedUsersForSeeMoreSkeleton\n : skeletonFromGetSuggestedUsersSkeleton\n return skeletonFn(input)\n}\n\nconst hydration = async (\n input: HydrationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, params, skeleton } = input\n const dids = dedupeStrs(skeleton.dids)\n const pairs: Map<DidString, DidString[]> = new Map()\n const viewer = params.hydrateCtx.viewer\n if (viewer) {\n pairs.set(viewer, dids)\n }\n const [profilesState, bidirectionalBlocks] = await Promise.all([\n ctx.hydrator.hydrateProfiles(dids, params.hydrateCtx),\n ctx.hydrator.hydrateBidirectionalBlocks(pairs, params.hydrateCtx),\n ])\n\n return mergeManyStates(profilesState, { bidirectionalBlocks })\n}\n\nconst noBlocksOrFollows = (\n input: RulesFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, skeleton, params, hydration } = input\n const viewer = params.hydrateCtx.viewer\n if (!viewer) {\n return skeleton\n }\n const blocks = hydration.bidirectionalBlocks?.get(viewer)\n return {\n ...skeleton,\n dids: skeleton.dids.filter((did) => {\n const viewer = ctx.views.profileViewer(did, hydration)\n return !blocks?.get(did) && !viewer?.following\n }),\n }\n}\n\nconst presentation = (\n input: PresentationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, skeleton, hydration } = input\n return {\n recIdStr: skeleton.recIdStr,\n actors: mapDefined(skeleton.dids, (did) =>\n ctx.views.profile(did, hydration),\n ),\n }\n}\n\ntype Context = {\n hydrator: Hydrator\n views: Views\n suggestionsClient: Client | undefined\n}\n\ntype Params = app.bsky.unspecced.getSuggestedUsersForSeeMore.$Params & {\n hydrateCtx: HydrateCtx & { viewer: string | null }\n headers: Record<string, string>\n signal: AbortSignal\n category?: string\n}\n\ntype SkeletonState = {\n dids: DidString[]\n recIdStr?: string\n}\n"]}
1
+ {"version":3,"file":"getSuggestedUsersForSeeMore.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/unspecced/getSuggestedUsersForSeeMore.ts"],"names":[],"mappings":"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","sourcesContent":["import { dedupeStrs, mapDefined, noUndefinedVals } from '@atproto/common'\nimport type { Client, DidString } from '@atproto/lex'\nimport { MethodNotImplementedError, type Server } from '@atproto/xrpc-server'\nimport type { AppContext } from '../../../../context.js'\nimport {\n type HydrateCtx,\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 { Views } from '../../../../views/index.js'\n\nexport default function (server: Server, ctx: AppContext) {\n const getSuggestedUsersForSeeMore = createPipeline(\n skeleton,\n hydration,\n noBlocksOrFollows,\n presentation,\n )\n server.add(app.bsky.unspecced.getSuggestedUsersForSeeMore, {\n auth: ctx.authVerifier.standardOptional,\n handler: async ({ auth, params, req, signal }) => {\n const viewer = auth.credentials.iss\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({\n labelers,\n viewer,\n features: ctx.featureGatesClient.scope(\n ctx.featureGatesClient.parseUserContextFromHandler({\n viewer,\n req,\n }),\n ),\n })\n const headers = noUndefinedVals({\n 'accept-language': req.headers['accept-language'],\n })\n const result = await getSuggestedUsersForSeeMore(\n {\n ...params,\n hydrateCtx,\n headers,\n signal,\n },\n ctx,\n )\n return {\n encoding: 'application/json',\n body: result,\n }\n },\n })\n}\n\nconst skeletonFromGetSuggestedUsersSkeleton = async (\n input: SkeletonFnInput<Context, Params>,\n): Promise<SkeletonState> => {\n const { params, ctx } = input\n if (!ctx.suggestionsClient) {\n throw new MethodNotImplementedError('Suggestions agent not available')\n }\n\n return ctx.suggestionsClient.call(\n app.bsky.unspecced.getSuggestedUsersSkeleton,\n {\n limit: params.limit,\n category: params.category,\n viewer: params.hydrateCtx.viewer ?? undefined,\n },\n {\n headers: params.headers,\n signal: params.signal,\n },\n )\n}\n\n// TODO: rename to `skeleton` once we can fully migrate to the new endpoint\nconst skeletonFromGetSuggestedUsersForSeeMoreSkeleton = async (\n input: SkeletonFnInput<Context, Params>,\n): Promise<SkeletonState> => {\n const { params, ctx } = input\n\n if (!ctx.suggestionsClient) {\n throw new MethodNotImplementedError('Suggestions agent not available')\n }\n\n return ctx.suggestionsClient.call(\n app.bsky.unspecced.getSuggestedUsersForSeeMoreSkeleton,\n {\n limit: params.limit,\n category: params.category,\n viewer: params.hydrateCtx.viewer ?? undefined,\n },\n {\n headers: params.headers,\n signal: params.signal,\n },\n )\n}\n\nconst skeletonFromIris = async (\n input: SkeletonFnInput<Context, Params>,\n): Promise<SkeletonState> => {\n const { params, ctx } = input\n\n if (!ctx.irisClient) {\n throw new MethodNotImplementedError('Iris agent not available')\n }\n\n return ctx.irisClient.call(\n app.bsky.unspecced.getSuggestedUsersForSeeMoreSkeleton,\n {\n limit: params.limit,\n category: params.category,\n viewer: params.hydrateCtx.viewer ?? undefined,\n },\n {\n headers: params.headers,\n signal: params.signal,\n },\n )\n}\n\nconst skeleton = async (input: SkeletonFnInput<Context, Params>) => {\n const useIris = input.params.hydrateCtx.features.checkGate(\n input.params.hydrateCtx.features.Gate.SuggestedUsersIrisEnable,\n )\n if (useIris) {\n return skeletonFromIris(input)\n }\n const useSeeMore = input.params.hydrateCtx.features.checkGate(\n input.params.hydrateCtx.features.Gate.SuggestedUsersForSeeMoreEnable,\n )\n const skeletonFn = useSeeMore\n ? skeletonFromGetSuggestedUsersForSeeMoreSkeleton\n : skeletonFromGetSuggestedUsersSkeleton\n return skeletonFn(input)\n}\n\nconst hydration = async (\n input: HydrationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, params, skeleton } = input\n const dids = dedupeStrs(skeleton.dids)\n const pairs: Map<DidString, DidString[]> = new Map()\n const viewer = params.hydrateCtx.viewer\n if (viewer) {\n pairs.set(viewer, dids)\n }\n const [profilesState, bidirectionalBlocks] = await Promise.all([\n ctx.hydrator.hydrateProfiles(dids, params.hydrateCtx),\n ctx.hydrator.hydrateBidirectionalBlocks(pairs, params.hydrateCtx),\n ])\n\n return mergeManyStates(profilesState, { bidirectionalBlocks })\n}\n\nconst noBlocksOrFollows = (\n input: RulesFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, skeleton, params, hydration } = input\n const viewer = params.hydrateCtx.viewer\n if (!viewer) {\n return skeleton\n }\n const blocks = hydration.bidirectionalBlocks?.get(viewer)\n return {\n ...skeleton,\n dids: skeleton.dids.filter((did) => {\n const viewer = ctx.views.profileViewer(did, hydration)\n return !blocks?.get(did) && !viewer?.following\n }),\n }\n}\n\nconst presentation = (\n input: PresentationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, skeleton, hydration } = input\n return {\n recIdStr: skeleton.recIdStr,\n actors: mapDefined(skeleton.dids, (did) =>\n ctx.views.profile(did, hydration),\n ),\n }\n}\n\ntype Context = {\n hydrator: Hydrator\n views: Views\n suggestionsClient: Client | undefined\n irisClient: Client | undefined\n}\n\ntype Params = app.bsky.unspecced.getSuggestedUsersForSeeMore.$Params & {\n hydrateCtx: HydrateCtx & { viewer: string | null }\n headers: Record<string, string>\n signal: AbortSignal\n category?: string\n}\n\ntype SkeletonState = {\n dids: DidString[]\n recIdStr?: string\n}\n"]}
package/dist/config.d.ts CHANGED
@@ -63,7 +63,11 @@ export interface ServerConfigValues {
63
63
  topicsApiKey?: string;
64
64
  irisUrl?: string;
65
65
  irisServiceDid?: DidString;
66
+ seemoreServiceDid?: DidString;
67
+ irisStagingServiceDid?: DidString;
66
68
  trendingFeedDid?: DidString;
69
+ bskyFeedgenDids: Set<string>;
70
+ irisApiKey?: string;
67
71
  irisFeedUris?: Set<string>;
68
72
  irisStagingUrl?: string;
69
73
  irisStagingFeedUris?: Set<string>;
@@ -148,7 +152,11 @@ export declare class ServerConfig {
148
152
  get topicsApiKey(): string | undefined;
149
153
  get irisUrl(): string | undefined;
150
154
  get irisServiceDid(): `did:${string}:${string}` | undefined;
155
+ get seemoreServiceDid(): `did:${string}:${string}` | undefined;
156
+ get irisStagingServiceDid(): `did:${string}:${string}` | undefined;
151
157
  get trendingFeedDid(): `did:${string}:${string}` | undefined;
158
+ get bskyFeedgenDids(): Set<string>;
159
+ get irisApiKey(): string | undefined;
152
160
  get irisFeedUris(): Set<string> | undefined;
153
161
  get irisStagingUrl(): string | undefined;
154
162
  get irisStagingFeedUris(): Set<string> | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}