forked from
rocksky.app/rocksky
A decentralized music tracking and discovery platform built on AT Protocol 馃幍
1import { Context } from "../context.ts";
2import { Algorithm, feedParams } from "./types.ts";
3import schema from "../schema/mod.ts";
4import { and, arrayContains, desc, eq, lt } from "drizzle-orm";
5
6const handler = async (
7 ctx: Context,
8 params: feedParams,
9 _did?: string | null,
10) => {
11 const { limit = 50, cursor } = params;
12
13 const whereConditions = [arrayContains(schema.artists.genres, ["breakcore"])];
14
15 if (cursor) {
16 const cursorDate = new Date(parseInt(cursor, 10));
17 whereConditions.push(lt(schema.scrobbles.timestamp, cursorDate));
18 }
19
20 const scrobbles = await ctx.db
21 .select()
22 .from(schema.scrobbles)
23 .leftJoin(schema.artists, eq(schema.scrobbles.artistId, schema.artists.id))
24 .where(and(...whereConditions))
25 .orderBy(desc(schema.scrobbles.timestamp))
26 .limit(limit)
27 .execute();
28
29 const feed = scrobbles.map(({ scrobbles }) => ({ scrobble: scrobbles.uri }));
30
31 const { scrobbles: lastScrobble } =
32 scrobbles.length > 0 ? scrobbles.at(-1)! : { scrobbles: null };
33 const nextCursor = lastScrobble
34 ? lastScrobble.timestamp.getTime().toString(10)
35 : undefined;
36
37 return {
38 cursor: nextCursor,
39 feed,
40 };
41};
42
43export const publisherDid = "did:plc:vegqomyce4ssoqs7zwqvgqty";
44export const rkey = "breakcore";
45
46export const info = {
47 handler,
48 needsAuth: false,
49 publisherDid,
50 rkey,
51} as Algorithm;