[READ ONLY MIRROR] Spark Social AppView Server
github.com/sprksocial/server
atproto
deno
hono
lexicon
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 { StoryDocument } from "../../db/models.ts";
7import { RecordProcessor } from "../processor.ts";
8
9const schema = so.sprk.story.post.main;
10type StoryRecord = so.sprk.story.post.Main;
11type IndexedStory = StoryDocument;
12
13const insertFn = async (
14 db: Database,
15 uri: AtUri,
16 cid: Cid,
17 obj: StoryRecord,
18 timestamp: string,
19): Promise<IndexedStory | null> => {
20 const story = {
21 uri: uri.toString(),
22 cid: cid.toString(),
23 authorDid: uri.host,
24 media: obj.media,
25 sound: obj.sound,
26 embeds: obj.embeds || [],
27 labels: obj.labels || null,
28 createdAt: normalizeDatetimeAlways(obj.createdAt),
29 indexedAt: timestamp,
30 };
31
32 // Use findOneAndUpdate with upsert to handle potential duplicate key errors
33 const insertedStory = await db.models.Story.findOneAndUpdate(
34 { uri: story.uri },
35 story,
36 { upsert: true, returnDocument: "after" },
37 );
38 return insertedStory;
39};
40
41const findDuplicate = (): AtUri | null => {
42 return null;
43};
44
45const notifsForInsert = () => {
46 return [];
47};
48
49const deleteFn = async (
50 db: Database,
51 uri: AtUri,
52): Promise<IndexedStory | null> => {
53 return await db.models.Story.findOneAndDelete({
54 uri: uri.toString(),
55 });
56};
57
58const notifsForDelete = () => {
59 return { notifs: [], toDelete: [] };
60};
61
62export type PluginType = RecordProcessor<typeof schema, IndexedStory>;
63
64export const makePlugin = (
65 db: Database,
66 background: BackgroundQueue,
67): PluginType => {
68 return new RecordProcessor(db, background, {
69 schema,
70 insertFn,
71 findDuplicate,
72 deleteFn,
73 notifsForInsert,
74 notifsForDelete,
75 });
76};
77
78export default makePlugin;