+45
-10
src/api/queries/profile.ts
+45
-10
src/api/queries/profile.ts
···
2
2
3
3
import type { AppBskyActorDefs } from '@atcute/bluesky';
4
4
import { ok } from '@atcute/client';
5
-
import type { ActorIdentifier } from '@atcute/lexicons';
5
+
import type { ActorIdentifier, Did } from '@atcute/lexicons';
6
+
import { isDid } from '@atcute/lexicons/syntax';
7
+
import { createBatchedFetch } from '@mary/batch-fetch';
6
8
import { createQuery } from '@mary/solid-query';
7
9
8
10
import { useAgent } from '~/lib/states/agent';
9
11
import { useSession } from '~/lib/states/session';
12
+
import { define, inject } from '~/lib/states/singleton';
10
13
11
14
import { dequal } from '../utils/dequal';
12
15
13
16
export interface ProfileQueryOptions {
17
+
batched?: boolean;
14
18
staleTime?: number;
15
19
gcTime?: number;
16
20
}
17
21
22
+
const BatchedProfileService = define('batched-profile', () => {
23
+
const { client } = useAgent();
24
+
25
+
const fetch = createBatchedFetch<Did, AppBskyActorDefs.ProfileViewDetailed>({
26
+
limit: 25,
27
+
idFromResource: (profile) => profile.did,
28
+
async fetch(queries, signal) {
29
+
const data = await ok(
30
+
client.get('app.bsky.actor.getProfiles', {
31
+
signal,
32
+
params: {
33
+
actors: queries,
34
+
},
35
+
}),
36
+
);
37
+
38
+
return data.profiles;
39
+
},
40
+
});
41
+
42
+
return { fetch };
43
+
});
44
+
18
45
export const createProfileQuery = (didOrHandle: () => ActorIdentifier, opts: ProfileQueryOptions = {}) => {
19
46
const { client } = useAgent();
20
47
const { currentAccount } = useSession();
48
+
49
+
const batched = inject(BatchedProfileService);
21
50
22
51
return createQuery((queryClient) => {
23
52
const $didOrHandle = didOrHandle();
···
26
55
queryKey: ['profile', $didOrHandle],
27
56
staleTime: opts.staleTime,
28
57
gcTime: opts.gcTime,
29
-
async queryFn(ctx): Promise<AppBskyActorDefs.ProfileViewDetailed> {
30
-
const data = await ok(
31
-
client.get('app.bsky.actor.getProfile', {
32
-
signal: ctx.signal,
33
-
params: {
34
-
actor: $didOrHandle!,
35
-
},
36
-
}),
37
-
);
58
+
async queryFn({ signal }): Promise<AppBskyActorDefs.ProfileViewDetailed> {
59
+
let data: AppBskyActorDefs.ProfileViewDetailed;
60
+
61
+
if (opts.batched && isDid($didOrHandle)) {
62
+
data = await batched.fetch($didOrHandle, signal);
63
+
} else {
64
+
data = await ok(
65
+
client.get('app.bsky.actor.getProfile', {
66
+
signal,
67
+
params: {
68
+
actor: $didOrHandle!,
69
+
},
70
+
}),
71
+
);
72
+
}
38
73
39
74
if (currentAccount !== undefined && currentAccount.did === data.did) {
40
75
// Unset `knownFollowers` as we don't need that on our own profile.