tangled
alpha
login
or
join now
t1c.dev
/
rocksky
forked from
rocksky.app/rocksky
2
fork
atom
A decentralized music tracking and discovery platform built on AT Protocol 🎵
2
fork
atom
overview
issues
pulls
pipelines
implement search xrpc method
tsiry-sandratraina.com
9 months ago
212172ff
547e0e7f
+128
-108
6 changed files
expand all
collapse all
unified
split
rockskyapi
rocksky-auth
lexicons
feed
defs.json
pkl
defs
feed
defs.pkl
schema
lexicon.pkl
src
lexicon
lexicons.ts
types
app
rocksky
feed
defs.ts
xrpc
app
rocksky
feed
search.ts
+17
-27
rockskyapi/rocksky-auth/lexicons/feed/defs.json
···
5
5
"searchResultsView": {
6
6
"type": "object",
7
7
"properties": {
8
8
-
"artists": {
8
8
+
"hits": {
9
9
"type": "array",
10
10
"items": {
11
11
-
"type": "ref",
12
12
-
"ref": "app.rocksky.artist.defs#artistViewBasic"
11
11
+
"type": "union",
12
12
+
"refs": [
13
13
+
"app.rocksky.song.defs#songViewBasic",
14
14
+
"app.rocksky.album.defs#albumViewBasic",
15
15
+
"app.rocksky.artist.defs#artistViewBasic",
16
16
+
"app.rocksky.playlist.defs#playlistViewBasic",
17
17
+
"app.rocksky.actor.defs#profileViewBasic"
18
18
+
]
13
19
}
14
20
},
15
15
-
"tracks": {
16
16
-
"type": "array",
17
17
-
"items": {
18
18
-
"type": "ref",
19
19
-
"ref": "app.rocksky.song.defs#songViewBasic"
20
20
-
}
21
21
+
"processingTimeMs": {
22
22
+
"type": "integer"
21
23
},
22
22
-
"albums": {
23
23
-
"type": "array",
24
24
-
"items": {
25
25
-
"type": "ref",
26
26
-
"ref": "app.rocksky.album.defs#albumViewBasic"
27
27
-
}
24
24
+
"limit": {
25
25
+
"type": "integer"
28
26
},
29
29
-
"users": {
30
30
-
"type": "array",
31
31
-
"items": {
32
32
-
"type": "ref",
33
33
-
"ref": "app.rocksky.actor.defs#profileViewBasic"
34
34
-
}
27
27
+
"offset": {
28
28
+
"type": "integer"
35
29
},
36
36
-
"playlists": {
37
37
-
"type": "array",
38
38
-
"items": {
39
39
-
"type": "ref",
40
40
-
"ref": "app.rocksky.playlist.defs#playlistViewBasic"
41
41
-
}
30
30
+
"estimatedTotalHits": {
31
31
+
"type": "integer"
42
32
}
43
33
}
44
34
},
+23
-34
rockskyapi/rocksky-auth/pkl/defs/feed/defs.pkl
···
3
3
lexicon = 1
4
4
id = "app.rocksky.feed.defs"
5
5
defs = new Mapping<String, ObjectType> {
6
6
-
["searchResultsView"] {
6
6
+
["searchResultsView"] = new ObjectType {
7
7
type = "object"
8
8
-
properties {
9
9
-
["artists"] = new Array {
8
8
+
properties {
9
9
+
["hits"] = new Array {
10
10
type = "array"
11
11
-
items = new Ref {
12
12
-
type = "ref"
13
13
-
ref = "app.rocksky.artist.defs#artistViewBasic"
11
11
+
items = new Union {
12
12
+
type = "union"
13
13
+
refs = List(
14
14
+
"app.rocksky.song.defs#songViewBasic",
15
15
+
"app.rocksky.album.defs#albumViewBasic",
16
16
+
"app.rocksky.artist.defs#artistViewBasic",
17
17
+
"app.rocksky.playlist.defs#playlistViewBasic",
18
18
+
"app.rocksky.actor.defs#profileViewBasic"
19
19
+
)
14
20
}
15
21
}
16
16
-
["tracks"] = new Array {
17
17
-
type = "array"
18
18
-
items = new Ref {
19
19
-
type = "ref"
20
20
-
ref = "app.rocksky.song.defs#songViewBasic"
21
21
-
}
22
22
+
["processingTimeMs"] = new IntegerType {
23
23
+
type = "integer"
22
24
}
23
23
-
["albums"] = new Array {
24
24
-
type = "array"
25
25
-
items = new Ref {
26
26
-
type = "ref"
27
27
-
ref = "app.rocksky.album.defs#albumViewBasic"
28
28
-
}
25
25
+
["limit"] = new IntegerType {
26
26
+
type = "integer"
29
27
}
30
30
-
31
31
-
["users"] = new Array {
32
32
-
type = "array"
33
33
-
items = new Ref {
34
34
-
type = "ref"
35
35
-
ref = "app.rocksky.actor.defs#profileViewBasic"
36
36
-
}
28
28
+
["offset"] = new IntegerType {
29
29
+
type = "integer"
37
30
}
38
38
-
["playlists"] = new Array {
39
39
-
type = "array"
40
40
-
items = new Ref {
41
41
-
type = "ref"
42
42
-
ref = "app.rocksky.playlist.defs#playlistViewBasic"
43
43
-
}
31
31
+
["estimatedTotalHits"] = new IntegerType {
32
32
+
type = "integer"
44
33
}
45
34
}
46
46
-
}
47
35
48
48
-
["nowPlayingView"] {
36
36
+
}
37
37
+
["nowPlayingView"] = new ObjectType {
49
38
type = "object"
50
39
properties {
51
40
["album"] = new StringType {
···
102
91
}
103
92
}
104
93
}
105
105
-
["nowPlayingsView"] {
94
94
+
["nowPlayingsView"] = new ObjectType {
106
95
type = "object"
107
96
properties {
108
97
["nowPlayings"] = new Array {
+2
-2
rockskyapi/rocksky-auth/pkl/schema/lexicon.pkl
···
25
25
26
26
class Array extends BaseType {
27
27
type: "array"
28
28
-
items: StringType | IntegerType | Blob | Ref
28
28
+
items: StringType | IntegerType | Blob | Ref | Union
29
29
}
30
30
31
31
class Params {
···
82
82
lexicon: Int = 1
83
83
id: String
84
84
description: String?
85
85
-
defs: Mapping<String, Procedure> | Mapping<String, Record> | Mapping<String, ObjectType> | Mapping<String, Query> | Null = null
85
85
+
defs: Mapping<String, Procedure> | Mapping<String, Record> | Mapping<String, ObjectType> | Mapping<String, Query> | Mapping<String, Array> | Mapping<String, ObjectType | Array> | Null = null
86
86
87
87
+17
-27
rockskyapi/rocksky-auth/src/lexicon/lexicons.ts
···
1463
1463
searchResultsView: {
1464
1464
type: 'object',
1465
1465
properties: {
1466
1466
-
artists: {
1466
1466
+
hits: {
1467
1467
type: 'array',
1468
1468
items: {
1469
1469
-
type: 'ref',
1470
1470
-
ref: 'lex:app.rocksky.artist.defs#artistViewBasic',
1469
1469
+
type: 'union',
1470
1470
+
refs: [
1471
1471
+
'lex:app.rocksky.song.defs#songViewBasic',
1472
1472
+
'lex:app.rocksky.album.defs#albumViewBasic',
1473
1473
+
'lex:app.rocksky.artist.defs#artistViewBasic',
1474
1474
+
'lex:app.rocksky.playlist.defs#playlistViewBasic',
1475
1475
+
'lex:app.rocksky.actor.defs#profileViewBasic',
1476
1476
+
],
1471
1477
},
1472
1478
},
1473
1473
-
tracks: {
1474
1474
-
type: 'array',
1475
1475
-
items: {
1476
1476
-
type: 'ref',
1477
1477
-
ref: 'lex:app.rocksky.song.defs#songViewBasic',
1478
1478
-
},
1479
1479
+
processingTimeMs: {
1480
1480
+
type: 'integer',
1479
1481
},
1480
1480
-
albums: {
1481
1481
-
type: 'array',
1482
1482
-
items: {
1483
1483
-
type: 'ref',
1484
1484
-
ref: 'lex:app.rocksky.album.defs#albumViewBasic',
1485
1485
-
},
1482
1482
+
limit: {
1483
1483
+
type: 'integer',
1486
1484
},
1487
1487
-
users: {
1488
1488
-
type: 'array',
1489
1489
-
items: {
1490
1490
-
type: 'ref',
1491
1491
-
ref: 'lex:app.rocksky.actor.defs#profileViewBasic',
1492
1492
-
},
1485
1485
+
offset: {
1486
1486
+
type: 'integer',
1493
1487
},
1494
1494
-
playlists: {
1495
1495
-
type: 'array',
1496
1496
-
items: {
1497
1497
-
type: 'ref',
1498
1498
-
ref: 'lex:app.rocksky.playlist.defs#playlistViewBasic',
1499
1499
-
},
1488
1488
+
estimatedTotalHits: {
1489
1489
+
type: 'integer',
1500
1490
},
1501
1491
},
1502
1492
},
+14
-7
rockskyapi/rocksky-auth/src/lexicon/types/app/rocksky/feed/defs.ts
···
5
5
import { lexicons } from '../../../../lexicons'
6
6
import { isObj, hasProp } from '../../../../util'
7
7
import { CID } from 'multiformats/cid'
8
8
-
import * as AppRockskyArtistDefs from '../artist/defs'
9
8
import * as AppRockskySongDefs from '../song/defs'
10
9
import * as AppRockskyAlbumDefs from '../album/defs'
11
11
-
import * as AppRockskyActorDefs from '../actor/defs'
10
10
+
import * as AppRockskyArtistDefs from '../artist/defs'
12
11
import * as AppRockskyPlaylistDefs from '../playlist/defs'
12
12
+
import * as AppRockskyActorDefs from '../actor/defs'
13
13
14
14
export interface SearchResultsView {
15
15
-
artists?: AppRockskyArtistDefs.ArtistViewBasic[]
16
16
-
tracks?: AppRockskySongDefs.SongViewBasic[]
17
17
-
albums?: AppRockskyAlbumDefs.AlbumViewBasic[]
18
18
-
users?: AppRockskyActorDefs.ProfileViewBasic[]
19
19
-
playlists?: AppRockskyPlaylistDefs.PlaylistViewBasic[]
15
15
+
hits?: (
16
16
+
| AppRockskySongDefs.SongViewBasic
17
17
+
| AppRockskyAlbumDefs.AlbumViewBasic
18
18
+
| AppRockskyArtistDefs.ArtistViewBasic
19
19
+
| AppRockskyPlaylistDefs.PlaylistViewBasic
20
20
+
| AppRockskyActorDefs.ProfileViewBasic
21
21
+
| { $type: string; [k: string]: unknown }
22
22
+
)[]
23
23
+
processingTimeMs?: number
24
24
+
limit?: number
25
25
+
offset?: number
26
26
+
estimatedTotalHits?: number
20
27
[k: string]: unknown
21
28
}
22
29
+55
-11
rockskyapi/rocksky-auth/src/xrpc/app/rocksky/feed/search.ts
···
1
1
import { Context } from "context";
2
2
-
import { pipe } from "effect";
2
2
+
import { Effect, pipe } from "effect";
3
3
import { Server } from "lexicon";
4
4
+
import { ProfileViewBasic } from "lexicon/types/app/rocksky/actor/defs";
5
5
+
import { AlbumViewBasic } from "lexicon/types/app/rocksky/album/defs";
6
6
+
import { ArtistViewBasic } from "lexicon/types/app/rocksky/artist/defs";
7
7
+
import { SearchResultsView } from "lexicon/types/app/rocksky/feed/defs";
8
8
+
import { QueryParams } from "lexicon/types/app/rocksky/feed/search";
9
9
+
import { PlaylistViewBasic } from "lexicon/types/app/rocksky/playlist/defs";
10
10
+
import { SongViewBasic } from "lexicon/types/app/rocksky/song/defs";
4
11
5
12
export default function (server: Server, ctx: Context) {
6
6
-
const search = (params) => pipe(params, retrieve, presentation);
13
13
+
const search = (params) =>
14
14
+
pipe({ params, ctx }, retrieve, Effect.flatMap(presentation));
7
15
server.app.rocksky.feed.search({
8
16
handler: async ({ params }) => {
9
9
-
const result = search(params);
17
17
+
const result = await Effect.runPromise(search(params));
10
18
return {
11
19
encoding: "application/json",
12
20
body: result,
···
15
23
});
16
24
}
17
25
18
18
-
const retrieve = () => {
19
19
-
// Logic to retrieve search results
20
20
-
return [];
26
26
+
const retrieve = ({ params, ctx }: { params: QueryParams; ctx: Context }) => {
27
27
+
return Effect.tryPromise(async () =>
28
28
+
ctx.meilisearch
29
29
+
.post<SearchResults>("multi-search", {
30
30
+
federation: {},
31
31
+
queries: [
32
32
+
{
33
33
+
indexUid: "albums",
34
34
+
q: params.query,
35
35
+
},
36
36
+
{
37
37
+
indexUid: "artists",
38
38
+
q: params.query,
39
39
+
},
40
40
+
{
41
41
+
indexUid: "tracks",
42
42
+
q: params.query,
43
43
+
},
44
44
+
{
45
45
+
indexUid: "playlists",
46
46
+
q: params.query,
47
47
+
},
48
48
+
{
49
49
+
indexUid: "users",
50
50
+
q: params.query,
51
51
+
},
52
52
+
],
53
53
+
})
54
54
+
.then((res) => res.data)
55
55
+
);
21
56
};
22
57
23
23
-
const presentation = (results) => {
24
24
-
// Logic to format the search results for presentation
25
25
-
return {
26
26
-
results: [],
27
27
-
};
58
58
+
const presentation = (
59
59
+
results: SearchResults
60
60
+
): Effect.Effect<SearchResultsView, never> => {
61
61
+
return Effect.succeed(results);
62
62
+
};
63
63
+
64
64
+
type SearchResults = {
65
65
+
hits: Array<
66
66
+
| SongViewBasic
67
67
+
| ArtistViewBasic
68
68
+
| AlbumViewBasic
69
69
+
| PlaylistViewBasic
70
70
+
| ProfileViewBasic
71
71
+
>;
28
72
};