[READ ONLY MIRROR] Spark Social AppView Server github.com/sprksocial/server
atproto deno hono lexicon
5
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 92 lines 2.3 kB view raw
1import { Cid } from "@atp/lex"; 2import { AtUri, normalizeDatetimeAlways } from "@atp/syntax"; 3import * as so from "../../../lex/so.ts"; 4import { BackgroundQueue } from "../../background.ts"; 5import { Database } from "../../db/index.ts"; 6import { GeneratorDocument } from "../../db/models.ts"; 7import { RecordProcessor } from "../processor.ts"; 8 9const schema = so.sprk.feed.generator.main; 10type FeedGeneratorRecord = so.sprk.feed.generator.Main; 11type IndexedFeedGenerator = GeneratorDocument; 12 13const insertFn = async ( 14 db: Database, 15 uri: AtUri, 16 cid: Cid, 17 obj: FeedGeneratorRecord, 18 timestamp: string, 19): Promise<IndexedFeedGenerator | null> => { 20 // Extract and clean avatar to ensure it matches MediaRef format 21 const avatar = obj.avatar 22 ? { 23 $type: "blob", 24 ref: (obj.avatar as unknown as Record<string, unknown>)?.ref || null, 25 } 26 : null; 27 28 const generator = { 29 uri: uri.toString(), 30 cid: cid.toString(), 31 authorDid: uri.host, 32 did: obj.did, 33 displayName: obj.displayName, 34 description: obj.description || null, 35 descriptionFacets: obj.descriptionFacets || null, 36 avatar, 37 acceptsInteractions: obj.acceptsInteractions || null, 38 labels: null, // Will be populated by label processing 39 createdAt: normalizeDatetimeAlways(obj.createdAt), 40 indexedAt: timestamp, 41 }; 42 43 const insertedGenerator = await db.models.Generator.findOneAndUpdate( 44 { uri: generator.uri }, 45 { $set: generator }, 46 { upsert: true, returnDocument: "after" }, 47 ); 48 return insertedGenerator; 49}; 50 51const findDuplicate = (): AtUri | null => { 52 return null; 53}; 54 55const notifsForInsert = () => { 56 return []; 57}; 58 59const deleteFn = async ( 60 db: Database, 61 uri: AtUri, 62): Promise<IndexedFeedGenerator | null> => { 63 const deleted = await db.models.Generator.findOneAndDelete({ 64 uri: uri.toString(), 65 }); 66 return deleted; 67}; 68 69const notifsForDelete = () => { 70 return { notifs: [], toDelete: [] }; 71}; 72 73export type PluginType = RecordProcessor< 74 typeof schema, 75 IndexedFeedGenerator 76>; 77 78export const makePlugin = ( 79 db: Database, 80 background: BackgroundQueue, 81): PluginType => { 82 return new RecordProcessor(db, background, { 83 schema, 84 insertFn, 85 findDuplicate, 86 deleteFn, 87 notifsForInsert, 88 notifsForDelete, 89 }); 90}; 91 92export default makePlugin;