@atproto/bsky 0.0.222 → 0.0.224
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.
- package/CHANGELOG.md +18 -0
- package/dist/api/app/bsky/graph/getSuggestedFollowsByActor.js +1 -1
- package/dist/api/app/bsky/graph/getSuggestedFollowsByActor.js.map +1 -1
- package/dist/api/app/bsky/unspecced/getSuggestedUsersForDiscover.d.ts +4 -0
- package/dist/api/app/bsky/unspecced/getSuggestedUsersForDiscover.d.ts.map +1 -0
- package/dist/api/app/bsky/unspecced/getSuggestedUsersForDiscover.js +107 -0
- package/dist/api/app/bsky/unspecced/getSuggestedUsersForDiscover.js.map +1 -0
- package/dist/api/app/bsky/unspecced/getSuggestedUsersForExplore.d.ts +4 -0
- package/dist/api/app/bsky/unspecced/getSuggestedUsersForExplore.d.ts.map +1 -0
- package/dist/api/app/bsky/unspecced/getSuggestedUsersForExplore.js +109 -0
- package/dist/api/app/bsky/unspecced/getSuggestedUsersForExplore.js.map +1 -0
- package/dist/api/app/bsky/unspecced/getSuggestedUsersForSeeMore.d.ts +4 -0
- package/dist/api/app/bsky/unspecced/getSuggestedUsersForSeeMore.d.ts.map +1 -0
- package/dist/api/app/bsky/unspecced/getSuggestedUsersForSeeMore.js +109 -0
- package/dist/api/app/bsky/unspecced/getSuggestedUsersForSeeMore.js.map +1 -0
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +6 -0
- package/dist/api/index.js.map +1 -1
- package/dist/feature-gates/gates.d.ts +3 -0
- package/dist/feature-gates/gates.d.ts.map +1 -1
- package/dist/feature-gates/gates.js +3 -0
- package/dist/feature-gates/gates.js.map +1 -1
- package/dist/lexicons/app/bsky/unspecced/getSuggestedUsersForDiscover.d.ts +3 -0
- package/dist/lexicons/app/bsky/unspecced/getSuggestedUsersForDiscover.d.ts.map +1 -0
- package/dist/lexicons/app/bsky/unspecced/getSuggestedUsersForDiscover.defs.d.ts +22 -0
- package/dist/lexicons/app/bsky/unspecced/getSuggestedUsersForDiscover.defs.d.ts.map +1 -0
- package/dist/lexicons/app/bsky/unspecced/getSuggestedUsersForDiscover.defs.js +53 -0
- package/dist/lexicons/app/bsky/unspecced/getSuggestedUsersForDiscover.defs.js.map +1 -0
- package/dist/lexicons/app/bsky/unspecced/getSuggestedUsersForDiscover.js +45 -0
- package/dist/lexicons/app/bsky/unspecced/getSuggestedUsersForDiscover.js.map +1 -0
- package/dist/lexicons/app/bsky/unspecced/getSuggestedUsersForDiscoverSkeleton.d.ts +3 -0
- package/dist/lexicons/app/bsky/unspecced/getSuggestedUsersForDiscoverSkeleton.d.ts.map +1 -0
- package/dist/lexicons/app/bsky/unspecced/getSuggestedUsersForDiscoverSkeleton.defs.d.ts +31 -0
- package/dist/lexicons/app/bsky/unspecced/getSuggestedUsersForDiscoverSkeleton.defs.d.ts.map +1 -0
- package/dist/lexicons/app/bsky/unspecced/getSuggestedUsersForDiscoverSkeleton.defs.js +20 -0
- package/dist/lexicons/app/bsky/unspecced/getSuggestedUsersForDiscoverSkeleton.defs.js.map +1 -0
- package/dist/lexicons/app/bsky/unspecced/getSuggestedUsersForDiscoverSkeleton.js +45 -0
- package/dist/lexicons/app/bsky/unspecced/getSuggestedUsersForDiscoverSkeleton.js.map +1 -0
- package/dist/lexicons/app/bsky/unspecced/getSuggestedUsersForExplore.d.ts +3 -0
- package/dist/lexicons/app/bsky/unspecced/getSuggestedUsersForExplore.d.ts.map +1 -0
- package/dist/lexicons/app/bsky/unspecced/getSuggestedUsersForExplore.defs.d.ts +24 -0
- package/dist/lexicons/app/bsky/unspecced/getSuggestedUsersForExplore.defs.d.ts.map +1 -0
- package/dist/lexicons/app/bsky/unspecced/getSuggestedUsersForExplore.defs.js +54 -0
- package/dist/lexicons/app/bsky/unspecced/getSuggestedUsersForExplore.defs.js.map +1 -0
- package/dist/lexicons/app/bsky/unspecced/getSuggestedUsersForExplore.js +45 -0
- package/dist/lexicons/app/bsky/unspecced/getSuggestedUsersForExplore.js.map +1 -0
- package/dist/lexicons/app/bsky/unspecced/getSuggestedUsersForExploreSkeleton.d.ts +3 -0
- package/dist/lexicons/app/bsky/unspecced/getSuggestedUsersForExploreSkeleton.d.ts.map +1 -0
- package/dist/lexicons/app/bsky/unspecced/getSuggestedUsersForExploreSkeleton.defs.d.ts +33 -0
- package/dist/lexicons/app/bsky/unspecced/getSuggestedUsersForExploreSkeleton.defs.d.ts.map +1 -0
- package/dist/lexicons/app/bsky/unspecced/getSuggestedUsersForExploreSkeleton.defs.js +21 -0
- package/dist/lexicons/app/bsky/unspecced/getSuggestedUsersForExploreSkeleton.defs.js.map +1 -0
- package/dist/lexicons/app/bsky/unspecced/getSuggestedUsersForExploreSkeleton.js +45 -0
- package/dist/lexicons/app/bsky/unspecced/getSuggestedUsersForExploreSkeleton.js.map +1 -0
- package/dist/lexicons/app/bsky/unspecced/getSuggestedUsersForSeeMore.d.ts +3 -0
- package/dist/lexicons/app/bsky/unspecced/getSuggestedUsersForSeeMore.d.ts.map +1 -0
- package/dist/lexicons/app/bsky/unspecced/getSuggestedUsersForSeeMore.defs.d.ts +24 -0
- package/dist/lexicons/app/bsky/unspecced/getSuggestedUsersForSeeMore.defs.d.ts.map +1 -0
- package/dist/lexicons/app/bsky/unspecced/getSuggestedUsersForSeeMore.defs.js +54 -0
- package/dist/lexicons/app/bsky/unspecced/getSuggestedUsersForSeeMore.defs.js.map +1 -0
- package/dist/lexicons/app/bsky/unspecced/getSuggestedUsersForSeeMore.js +45 -0
- package/dist/lexicons/app/bsky/unspecced/getSuggestedUsersForSeeMore.js.map +1 -0
- package/dist/lexicons/app/bsky/unspecced/getSuggestedUsersForSeeMoreSkeleton.d.ts +3 -0
- package/dist/lexicons/app/bsky/unspecced/getSuggestedUsersForSeeMoreSkeleton.d.ts.map +1 -0
- package/dist/lexicons/app/bsky/unspecced/getSuggestedUsersForSeeMoreSkeleton.defs.d.ts +33 -0
- package/dist/lexicons/app/bsky/unspecced/getSuggestedUsersForSeeMoreSkeleton.defs.d.ts.map +1 -0
- package/dist/lexicons/app/bsky/unspecced/getSuggestedUsersForSeeMoreSkeleton.defs.js +21 -0
- package/dist/lexicons/app/bsky/unspecced/getSuggestedUsersForSeeMoreSkeleton.defs.js.map +1 -0
- package/dist/lexicons/app/bsky/unspecced/getSuggestedUsersForSeeMoreSkeleton.js +45 -0
- package/dist/lexicons/app/bsky/unspecced/getSuggestedUsersForSeeMoreSkeleton.js.map +1 -0
- package/dist/lexicons/app/bsky/unspecced.d.ts +6 -0
- package/dist/lexicons/app/bsky/unspecced.d.ts.map +1 -1
- package/dist/lexicons/app/bsky/unspecced.js +7 -1
- package/dist/lexicons/app/bsky/unspecced.js.map +1 -1
- package/package.json +7 -7
- package/src/api/app/bsky/graph/getSuggestedFollowsByActor.ts +2 -2
- package/src/api/app/bsky/unspecced/getSuggestedUsersForDiscover.ts +175 -0
- package/src/api/app/bsky/unspecced/getSuggestedUsersForExplore.ts +178 -0
- package/src/api/app/bsky/unspecced/getSuggestedUsersForSeeMore.ts +178 -0
- package/src/api/index.ts +6 -0
- package/src/feature-gates/gates.ts +3 -0
- package/tsconfig.build.tsbuildinfo +1 -1
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { dedupeStrs, mapDefined, noUndefinedVals } from '@atproto/common'
|
|
2
|
+
import { Client, DidString } from '@atproto/lex'
|
|
3
|
+
import { MethodNotImplementedError, Server } from '@atproto/xrpc-server'
|
|
4
|
+
import { AppContext } from '../../../../context'
|
|
5
|
+
import {
|
|
6
|
+
HydrateCtx,
|
|
7
|
+
Hydrator,
|
|
8
|
+
mergeManyStates,
|
|
9
|
+
} from '../../../../hydration/hydrator'
|
|
10
|
+
import { app } from '../../../../lexicons/index.js'
|
|
11
|
+
import {
|
|
12
|
+
HydrationFnInput,
|
|
13
|
+
PresentationFnInput,
|
|
14
|
+
RulesFnInput,
|
|
15
|
+
SkeletonFnInput,
|
|
16
|
+
createPipeline,
|
|
17
|
+
} from '../../../../pipeline'
|
|
18
|
+
import { Views } from '../../../../views'
|
|
19
|
+
|
|
20
|
+
export default function (server: Server, ctx: AppContext) {
|
|
21
|
+
const getSuggestedUsersForExplore = createPipeline(
|
|
22
|
+
skeleton,
|
|
23
|
+
hydration,
|
|
24
|
+
noBlocksOrFollows,
|
|
25
|
+
presentation,
|
|
26
|
+
)
|
|
27
|
+
server.add(app.bsky.unspecced.getSuggestedUsersForExplore, {
|
|
28
|
+
auth: ctx.authVerifier.standardOptional,
|
|
29
|
+
handler: async ({ auth, params, req }) => {
|
|
30
|
+
const viewer = auth.credentials.iss
|
|
31
|
+
const labelers = ctx.reqLabelers(req)
|
|
32
|
+
const hydrateCtx = await ctx.hydrator.createContext({
|
|
33
|
+
labelers,
|
|
34
|
+
viewer,
|
|
35
|
+
features: ctx.featureGatesClient.scope(
|
|
36
|
+
ctx.featureGatesClient.parseUserContextFromHandler({
|
|
37
|
+
viewer,
|
|
38
|
+
req,
|
|
39
|
+
}),
|
|
40
|
+
),
|
|
41
|
+
})
|
|
42
|
+
const headers = noUndefinedVals({
|
|
43
|
+
'accept-language': req.headers['accept-language'],
|
|
44
|
+
})
|
|
45
|
+
const result = await getSuggestedUsersForExplore(
|
|
46
|
+
{
|
|
47
|
+
...params,
|
|
48
|
+
hydrateCtx,
|
|
49
|
+
headers,
|
|
50
|
+
},
|
|
51
|
+
ctx,
|
|
52
|
+
)
|
|
53
|
+
return {
|
|
54
|
+
encoding: 'application/json',
|
|
55
|
+
body: result,
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
})
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const skeletonFromGetSuggestedUsersSkeleton = async (
|
|
62
|
+
input: SkeletonFnInput<Context, Params>,
|
|
63
|
+
): Promise<SkeletonState> => {
|
|
64
|
+
const { params, ctx } = input
|
|
65
|
+
if (!ctx.suggestionsClient) {
|
|
66
|
+
throw new MethodNotImplementedError('Suggestions agent not available')
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return ctx.suggestionsClient.call(
|
|
70
|
+
app.bsky.unspecced.getSuggestedUsersSkeleton,
|
|
71
|
+
{
|
|
72
|
+
limit: params.limit,
|
|
73
|
+
category: params.category,
|
|
74
|
+
viewer: params.hydrateCtx.viewer ?? undefined,
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
headers: params.headers,
|
|
78
|
+
},
|
|
79
|
+
)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// TODO: rename to `skeleton` once we can fully migrate to the new endpoint
|
|
83
|
+
const skeletonFromGetSuggestedUsersForExploreSkeleton = async (
|
|
84
|
+
input: SkeletonFnInput<Context, Params>,
|
|
85
|
+
): Promise<SkeletonState> => {
|
|
86
|
+
const { params, ctx } = input
|
|
87
|
+
|
|
88
|
+
if (!ctx.suggestionsClient) {
|
|
89
|
+
throw new MethodNotImplementedError('Suggestions agent not available')
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return ctx.suggestionsClient.call(
|
|
93
|
+
app.bsky.unspecced.getSuggestedUsersForExploreSkeleton,
|
|
94
|
+
{
|
|
95
|
+
limit: params.limit,
|
|
96
|
+
category: params.category,
|
|
97
|
+
viewer: params.hydrateCtx.viewer ?? undefined,
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
headers: params.headers,
|
|
101
|
+
},
|
|
102
|
+
)
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const skeleton = async (input: SkeletonFnInput<Context, Params>) => {
|
|
106
|
+
const useExplore = input.params.hydrateCtx.features.checkGate(
|
|
107
|
+
input.params.hydrateCtx.features.Gate.SuggestedUsersForExploreEnable,
|
|
108
|
+
)
|
|
109
|
+
const skeletonFn = useExplore
|
|
110
|
+
? skeletonFromGetSuggestedUsersForExploreSkeleton
|
|
111
|
+
: skeletonFromGetSuggestedUsersSkeleton
|
|
112
|
+
return skeletonFn(input)
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const hydration = async (
|
|
116
|
+
input: HydrationFnInput<Context, Params, SkeletonState>,
|
|
117
|
+
) => {
|
|
118
|
+
const { ctx, params, skeleton } = input
|
|
119
|
+
const dids = dedupeStrs(skeleton.dids)
|
|
120
|
+
const pairs: Map<DidString, DidString[]> = new Map()
|
|
121
|
+
const viewer = params.hydrateCtx.viewer
|
|
122
|
+
if (viewer) {
|
|
123
|
+
pairs.set(viewer, dids)
|
|
124
|
+
}
|
|
125
|
+
const [profilesState, bidirectionalBlocks] = await Promise.all([
|
|
126
|
+
ctx.hydrator.hydrateProfiles(dids, params.hydrateCtx),
|
|
127
|
+
ctx.hydrator.hydrateBidirectionalBlocks(pairs, params.hydrateCtx),
|
|
128
|
+
])
|
|
129
|
+
|
|
130
|
+
return mergeManyStates(profilesState, { bidirectionalBlocks })
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const noBlocksOrFollows = (
|
|
134
|
+
input: RulesFnInput<Context, Params, SkeletonState>,
|
|
135
|
+
) => {
|
|
136
|
+
const { ctx, skeleton, params, hydration } = input
|
|
137
|
+
const viewer = params.hydrateCtx.viewer
|
|
138
|
+
if (!viewer) {
|
|
139
|
+
return skeleton
|
|
140
|
+
}
|
|
141
|
+
const blocks = hydration.bidirectionalBlocks?.get(viewer)
|
|
142
|
+
return {
|
|
143
|
+
...skeleton,
|
|
144
|
+
dids: skeleton.dids.filter((did) => {
|
|
145
|
+
const viewer = ctx.views.profileViewer(did, hydration)
|
|
146
|
+
return !blocks?.get(did) && !viewer?.following
|
|
147
|
+
}),
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
const presentation = (
|
|
152
|
+
input: PresentationFnInput<Context, Params, SkeletonState>,
|
|
153
|
+
) => {
|
|
154
|
+
const { ctx, skeleton, hydration } = input
|
|
155
|
+
return {
|
|
156
|
+
recIdStr: skeleton.recIdStr,
|
|
157
|
+
actors: mapDefined(skeleton.dids, (did) =>
|
|
158
|
+
ctx.views.profile(did, hydration),
|
|
159
|
+
),
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
type Context = {
|
|
164
|
+
hydrator: Hydrator
|
|
165
|
+
views: Views
|
|
166
|
+
suggestionsClient: Client | undefined
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
type Params = app.bsky.unspecced.getSuggestedUsersForExplore.$Params & {
|
|
170
|
+
hydrateCtx: HydrateCtx & { viewer: string | null }
|
|
171
|
+
headers: Record<string, string>
|
|
172
|
+
category?: string
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
type SkeletonState = {
|
|
176
|
+
dids: DidString[]
|
|
177
|
+
recIdStr?: string
|
|
178
|
+
}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { dedupeStrs, mapDefined, noUndefinedVals } from '@atproto/common'
|
|
2
|
+
import { Client, DidString } from '@atproto/lex'
|
|
3
|
+
import { MethodNotImplementedError, Server } from '@atproto/xrpc-server'
|
|
4
|
+
import { AppContext } from '../../../../context'
|
|
5
|
+
import {
|
|
6
|
+
HydrateCtx,
|
|
7
|
+
Hydrator,
|
|
8
|
+
mergeManyStates,
|
|
9
|
+
} from '../../../../hydration/hydrator'
|
|
10
|
+
import { app } from '../../../../lexicons/index.js'
|
|
11
|
+
import {
|
|
12
|
+
HydrationFnInput,
|
|
13
|
+
PresentationFnInput,
|
|
14
|
+
RulesFnInput,
|
|
15
|
+
SkeletonFnInput,
|
|
16
|
+
createPipeline,
|
|
17
|
+
} from '../../../../pipeline'
|
|
18
|
+
import { Views } from '../../../../views'
|
|
19
|
+
|
|
20
|
+
export default function (server: Server, ctx: AppContext) {
|
|
21
|
+
const getSuggestedUsersForSeeMore = createPipeline(
|
|
22
|
+
skeleton,
|
|
23
|
+
hydration,
|
|
24
|
+
noBlocksOrFollows,
|
|
25
|
+
presentation,
|
|
26
|
+
)
|
|
27
|
+
server.add(app.bsky.unspecced.getSuggestedUsersForSeeMore, {
|
|
28
|
+
auth: ctx.authVerifier.standardOptional,
|
|
29
|
+
handler: async ({ auth, params, req }) => {
|
|
30
|
+
const viewer = auth.credentials.iss
|
|
31
|
+
const labelers = ctx.reqLabelers(req)
|
|
32
|
+
const hydrateCtx = await ctx.hydrator.createContext({
|
|
33
|
+
labelers,
|
|
34
|
+
viewer,
|
|
35
|
+
features: ctx.featureGatesClient.scope(
|
|
36
|
+
ctx.featureGatesClient.parseUserContextFromHandler({
|
|
37
|
+
viewer,
|
|
38
|
+
req,
|
|
39
|
+
}),
|
|
40
|
+
),
|
|
41
|
+
})
|
|
42
|
+
const headers = noUndefinedVals({
|
|
43
|
+
'accept-language': req.headers['accept-language'],
|
|
44
|
+
})
|
|
45
|
+
const result = await getSuggestedUsersForSeeMore(
|
|
46
|
+
{
|
|
47
|
+
...params,
|
|
48
|
+
hydrateCtx,
|
|
49
|
+
headers,
|
|
50
|
+
},
|
|
51
|
+
ctx,
|
|
52
|
+
)
|
|
53
|
+
return {
|
|
54
|
+
encoding: 'application/json',
|
|
55
|
+
body: result,
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
})
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const skeletonFromGetSuggestedUsersSkeleton = async (
|
|
62
|
+
input: SkeletonFnInput<Context, Params>,
|
|
63
|
+
): Promise<SkeletonState> => {
|
|
64
|
+
const { params, ctx } = input
|
|
65
|
+
if (!ctx.suggestionsClient) {
|
|
66
|
+
throw new MethodNotImplementedError('Suggestions agent not available')
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return ctx.suggestionsClient.call(
|
|
70
|
+
app.bsky.unspecced.getSuggestedUsersSkeleton,
|
|
71
|
+
{
|
|
72
|
+
limit: params.limit,
|
|
73
|
+
category: params.category,
|
|
74
|
+
viewer: params.hydrateCtx.viewer ?? undefined,
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
headers: params.headers,
|
|
78
|
+
},
|
|
79
|
+
)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// TODO: rename to `skeleton` once we can fully migrate to the new endpoint
|
|
83
|
+
const skeletonFromGetSuggestedUsersForSeeMoreSkeleton = async (
|
|
84
|
+
input: SkeletonFnInput<Context, Params>,
|
|
85
|
+
): Promise<SkeletonState> => {
|
|
86
|
+
const { params, ctx } = input
|
|
87
|
+
|
|
88
|
+
if (!ctx.suggestionsClient) {
|
|
89
|
+
throw new MethodNotImplementedError('Suggestions agent not available')
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return ctx.suggestionsClient.call(
|
|
93
|
+
app.bsky.unspecced.getSuggestedUsersForSeeMoreSkeleton,
|
|
94
|
+
{
|
|
95
|
+
limit: params.limit,
|
|
96
|
+
category: params.category,
|
|
97
|
+
viewer: params.hydrateCtx.viewer ?? undefined,
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
headers: params.headers,
|
|
101
|
+
},
|
|
102
|
+
)
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const skeleton = async (input: SkeletonFnInput<Context, Params>) => {
|
|
106
|
+
const useSeeMore = input.params.hydrateCtx.features.checkGate(
|
|
107
|
+
input.params.hydrateCtx.features.Gate.SuggestedUsersForSeeMoreEnable,
|
|
108
|
+
)
|
|
109
|
+
const skeletonFn = useSeeMore
|
|
110
|
+
? skeletonFromGetSuggestedUsersForSeeMoreSkeleton
|
|
111
|
+
: skeletonFromGetSuggestedUsersSkeleton
|
|
112
|
+
return skeletonFn(input)
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const hydration = async (
|
|
116
|
+
input: HydrationFnInput<Context, Params, SkeletonState>,
|
|
117
|
+
) => {
|
|
118
|
+
const { ctx, params, skeleton } = input
|
|
119
|
+
const dids = dedupeStrs(skeleton.dids)
|
|
120
|
+
const pairs: Map<DidString, DidString[]> = new Map()
|
|
121
|
+
const viewer = params.hydrateCtx.viewer
|
|
122
|
+
if (viewer) {
|
|
123
|
+
pairs.set(viewer, dids)
|
|
124
|
+
}
|
|
125
|
+
const [profilesState, bidirectionalBlocks] = await Promise.all([
|
|
126
|
+
ctx.hydrator.hydrateProfiles(dids, params.hydrateCtx),
|
|
127
|
+
ctx.hydrator.hydrateBidirectionalBlocks(pairs, params.hydrateCtx),
|
|
128
|
+
])
|
|
129
|
+
|
|
130
|
+
return mergeManyStates(profilesState, { bidirectionalBlocks })
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const noBlocksOrFollows = (
|
|
134
|
+
input: RulesFnInput<Context, Params, SkeletonState>,
|
|
135
|
+
) => {
|
|
136
|
+
const { ctx, skeleton, params, hydration } = input
|
|
137
|
+
const viewer = params.hydrateCtx.viewer
|
|
138
|
+
if (!viewer) {
|
|
139
|
+
return skeleton
|
|
140
|
+
}
|
|
141
|
+
const blocks = hydration.bidirectionalBlocks?.get(viewer)
|
|
142
|
+
return {
|
|
143
|
+
...skeleton,
|
|
144
|
+
dids: skeleton.dids.filter((did) => {
|
|
145
|
+
const viewer = ctx.views.profileViewer(did, hydration)
|
|
146
|
+
return !blocks?.get(did) && !viewer?.following
|
|
147
|
+
}),
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
const presentation = (
|
|
152
|
+
input: PresentationFnInput<Context, Params, SkeletonState>,
|
|
153
|
+
) => {
|
|
154
|
+
const { ctx, skeleton, hydration } = input
|
|
155
|
+
return {
|
|
156
|
+
recIdStr: skeleton.recIdStr,
|
|
157
|
+
actors: mapDefined(skeleton.dids, (did) =>
|
|
158
|
+
ctx.views.profile(did, hydration),
|
|
159
|
+
),
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
type Context = {
|
|
164
|
+
hydrator: Hydrator
|
|
165
|
+
views: Views
|
|
166
|
+
suggestionsClient: Client | undefined
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
type Params = app.bsky.unspecced.getSuggestedUsersForSeeMore.$Params & {
|
|
170
|
+
hydrateCtx: HydrateCtx & { viewer: string | null }
|
|
171
|
+
headers: Record<string, string>
|
|
172
|
+
category?: string
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
type SkeletonState = {
|
|
176
|
+
dids: DidString[]
|
|
177
|
+
recIdStr?: string
|
|
178
|
+
}
|
package/src/api/index.ts
CHANGED
|
@@ -82,6 +82,9 @@ import getUnspeccedSuggestedFeeds from './app/bsky/unspecced/getSuggestedFeeds'
|
|
|
82
82
|
import getSuggestedOnboardingUsers from './app/bsky/unspecced/getSuggestedOnboardingUsers'
|
|
83
83
|
import getSuggestedStarterPacks from './app/bsky/unspecced/getSuggestedStarterPacks'
|
|
84
84
|
import getSuggestedUsers from './app/bsky/unspecced/getSuggestedUsers'
|
|
85
|
+
import getSuggestedUsersForDiscover from './app/bsky/unspecced/getSuggestedUsersForDiscover'
|
|
86
|
+
import getSuggestedUsersForExplore from './app/bsky/unspecced/getSuggestedUsersForExplore'
|
|
87
|
+
import getSuggestedUsersForSeeMore from './app/bsky/unspecced/getSuggestedUsersForSeeMore'
|
|
85
88
|
import getTaggedSuggestions from './app/bsky/unspecced/getTaggedSuggestions'
|
|
86
89
|
import getTrendingTopics from './app/bsky/unspecced/getTrendingTopics'
|
|
87
90
|
import getTrends from './app/bsky/unspecced/getTrends'
|
|
@@ -169,6 +172,9 @@ export default function (server: Server, ctx: AppContext) {
|
|
|
169
172
|
getSuggestedOnboardingUsers(server, ctx)
|
|
170
173
|
getSuggestedStarterPacks(server, ctx)
|
|
171
174
|
getSuggestedUsers(server, ctx)
|
|
175
|
+
getSuggestedUsersForDiscover(server, ctx)
|
|
176
|
+
getSuggestedUsersForExplore(server, ctx)
|
|
177
|
+
getSuggestedUsersForSeeMore(server, ctx)
|
|
172
178
|
getUnspeccedSuggestedFeeds(server, ctx)
|
|
173
179
|
getLabelerServices(server, ctx)
|
|
174
180
|
searchActors(server, ctx)
|
|
@@ -8,6 +8,9 @@ export enum Gate {
|
|
|
8
8
|
SuggestedUsersSocialProofEnable = 'suggested_users:social_proof:enable',
|
|
9
9
|
ThreadsReplyRankingExplorationEnable = 'threads:reply_ranking_exploration:enable',
|
|
10
10
|
SearchFilteringExplorationEnable = 'search:filtering_exploration:enable',
|
|
11
|
+
SuggestedUsersForExploreEnable = 'suggested_users:for_explore:enable',
|
|
12
|
+
SuggestedUsersForDiscoverEnable = 'suggested_users:for_discover:enable',
|
|
13
|
+
SuggestedUsersForSeeMoreEnable = 'suggested_users:for_see_more:enable',
|
|
11
14
|
|
|
12
15
|
// temp
|
|
13
16
|
AATest = 'aa-test-appview',
|