[READ ONLY MIRROR] Spark Social AppView Server
github.com/sprksocial/server
atproto
deno
hono
lexicon
1import { keyBy } from "@atp/common";
2import { Database } from "../db/index.ts";
3import { getRecords } from "./records.ts";
4
5export class Actors {
6 private db: Database;
7
8 constructor(db: Database) {
9 this.db = db;
10 }
11
12 async getActors(dids: string[]) {
13 const profileUris = dids.map(
14 (did) => `at://${did}/so.sprk.actor.profile/self`,
15 );
16
17 const [
18 handlesRes,
19 profiles,
20 ] = await Promise.all([
21 this.db.models.Actor.find({
22 did: { $in: dids },
23 }),
24 getRecords(this.db, profileUris),
25 ]);
26
27 const byDid = keyBy(handlesRes, "did");
28 const actors = dids.map((did, i) => {
29 const row = byDid.get(did);
30
31 return {
32 exists: !!row,
33 handle: row?.handle ?? undefined,
34 profile: profiles.records[i],
35 takenDown: !!row?.takedownRef,
36 takedownRef: row?.takedownRef || undefined,
37 tombstonedAt: undefined, // in current implementation, tombstoned actors are deleted
38 upstreamStatus: row?.upstreamStatus ?? "",
39 createdAt: profiles.records[i].createdAt, // @NOTE profile creation date not trusted in production
40 tags: [],
41 profileTags: [],
42 };
43 });
44
45 return { actors };
46 }
47
48 async getDidsByHandles(handles: string[]) {
49 if (handles.length === 0) {
50 return { dids: [] };
51 }
52
53 const res = await this.db.models.Actor.find({
54 handle: { $in: handles },
55 }).select("did handle");
56
57 const byHandle = keyBy(res, "handle");
58 const dids = handles.map((handle) => byHandle.get(handle)?.did ?? "");
59 return { dids };
60 }
61
62 async updateActorUpstreamStatus(actorDid: string, upstreamStatus: string) {
63 await this.db.models.Actor.updateOne(
64 { did: actorDid },
65 { $set: { upstreamStatus } },
66 );
67
68 return { success: true };
69 }
70}