A decentralized music tracking and discovery platform built on AT Protocol 🎵

implement getArtistAlbums xrpc method

+53 -11
+53 -11
rockskyapi/rocksky-auth/src/xrpc/app/rocksky/artist/getArtistAlbums.ts
··· 1 1 import { Context } from "context"; 2 - import { pipe } from "effect"; 2 + import { Effect, pipe } from "effect"; 3 3 import { Server } from "lexicon"; 4 + import { AlbumViewBasic } from "lexicon/types/app/rocksky/album/defs"; 5 + import { QueryParams } from "lexicon/types/app/rocksky/artist/getArtistAlbums"; 6 + import { deepCamelCaseKeys } from "lib"; 4 7 5 8 export default function (server: Server, ctx: Context) { 6 - const getArtistAlbums = (params) => pipe(params, retrieve, presentation); 9 + const getArtistAlbums = (params) => 10 + pipe( 11 + { params, ctx }, 12 + retrieve, 13 + Effect.flatMap(presentation), 14 + Effect.retry({ times: 3 }), 15 + Effect.timeout("10 seconds"), 16 + Effect.catchAll((err) => { 17 + console.error(err); 18 + return Effect.succeed({ albums: [] }); 19 + }) 20 + ); 7 21 server.app.rocksky.artist.getArtistAlbums({ 8 22 handler: async ({ params }) => { 9 - const result = getArtistAlbums(params); 23 + const result = await Effect.runPromise(getArtistAlbums(params)); 10 24 return { 11 25 encoding: "application/json", 12 26 body: result, ··· 15 29 }); 16 30 } 17 31 18 - const retrieve = () => { 19 - // Logic to retrieve albums for the artist 20 - return []; 32 + const retrieve = ({ 33 + params, 34 + ctx, 35 + }: { 36 + params: QueryParams; 37 + ctx: Context; 38 + }): Effect.Effect<{ data: Album[] }, Error> => { 39 + return Effect.tryPromise({ 40 + try: () => 41 + ctx.analytics.post("library.getArtistAlbums", { 42 + pagination: { 43 + artist_id: params.uri, 44 + }, 45 + }), 46 + catch: (error) => new Error(`Failed to retrieve artist's albums: ${error}`), 47 + }); 21 48 }; 22 49 23 - const presentation = () => { 24 - // Logic to format the albums for presentation 25 - return { 26 - albums: [], 27 - }; 50 + const presentation = ({ 51 + data, 52 + }: { 53 + data: Album[]; 54 + }): Effect.Effect<{ albums: AlbumViewBasic[] }, never> => { 55 + return Effect.sync(() => ({ albums: deepCamelCaseKeys(data) })); 56 + }; 57 + 58 + type Album = { 59 + id: string; 60 + uri: string; 61 + title: string; 62 + artist: string; 63 + artist_uri: string; 64 + year: number; 65 + album_art: string; 66 + release_date: string; 67 + sha256: string; 68 + play_count: number; 69 + unique_listeners: number; 28 70 };