A decentralized music tracking and discovery platform built on AT Protocol 🎵 rocksky.app
spotify atproto lastfm musicbrainz scrobbling listenbrainz
0

Configure Feed

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

feat(sdk): propagate matchSong track/disc number to all typed SDKs

Add trackNumber/discNumber to the songMatchView lexicon (pkl source +
generated JSON) so matchSong's `matches` list carries the fields Deezer
now backfills. Regenerate server lexicon types, the TypeScript and Go
SDKs, and the crates/rocksky-sdk Rust bindings; forward the fields
through the hand-written DeezerMatch type via the existing `...m` spread.

Bump every native/FFI SDK to a patch release (TS/Python/Ruby/Elixir
0.8.1, Clojure 0.8.1-SNAPSHOT, Kotlin 0.9.1, Erlang 0.5.1, Gleam 1.8.1);
rocksky-sdk already at 0.6.1, sdk/rust deprecated, Go versioned by tag.

+70 -10
+8
apps/api/lexicons/song/defs.json
··· 236 236 "description": "The duration of the matched track in milliseconds.", 237 237 "minimum": 0 238 238 }, 239 + "trackNumber": { 240 + "type": "integer", 241 + "description": "The track number of the matched track in its album." 242 + }, 243 + "discNumber": { 244 + "type": "integer", 245 + "description": "The disc number of the matched track in its album." 246 + }, 239 247 "link": { 240 248 "type": "string", 241 249 "description": "A URL to the matched track on the provider.",
+8
apps/api/pkl/defs/song/defs.pkl
··· 236 236 minimum = 0 237 237 description = "The duration of the matched track in milliseconds." 238 238 } 239 + ["trackNumber"] = new IntegerType { 240 + type = "integer" 241 + description = "The track number of the matched track in its album." 242 + } 243 + ["discNumber"] = new IntegerType { 244 + type = "integer" 245 + description = "The disc number of the matched track in its album." 246 + } 239 247 ["link"] = new StringType { 240 248 type = "string" 241 249 format = "uri"
+8
apps/api/src/lexicon/lexicons.ts
··· 7598 7598 description: "The duration of the matched track in milliseconds.", 7599 7599 minimum: 0, 7600 7600 }, 7601 + trackNumber: { 7602 + type: "integer", 7603 + description: "The track number of the matched track in its album.", 7604 + }, 7605 + discNumber: { 7606 + type: "integer", 7607 + description: "The disc number of the matched track in its album.", 7608 + }, 7601 7609 link: { 7602 7610 type: "string", 7603 7611 description: "A URL to the matched track on the provider.",
+4
apps/api/src/lexicon/types/app/rocksky/song/defs.ts
··· 133 133 isrc?: string; 134 134 /** The duration of the matched track in milliseconds. */ 135 135 durationMs?: number; 136 + /** The track number of the matched track in its album. */ 137 + trackNumber?: number; 138 + /** The disc number of the matched track in its album. */ 139 + discNumber?: number; 136 140 /** A URL to the matched track on the provider. */ 137 141 link?: string; 138 142 /** A URL to a short audio preview of the matched track. */
+2
apps/api/src/lib/deezer.ts
··· 38 38 albumArt?: string; 39 39 isrc?: string; 40 40 durationMs: number; 41 + trackNumber?: number; 42 + discNumber?: number; 41 43 link?: string; 42 44 preview?: string; 43 45 rank?: number;
+5 -1
apps/api/src/xrpc/app/rocksky/song/matchSong.ts
··· 140 140 let spotifyTrack: Track | undefined; 141 141 if (needsSpotify) { 142 142 try { 143 - spotifyTrack = await searchOnSpotify(ctx, params.title, params.artist); 143 + spotifyTrack = await searchOnSpotify( 144 + ctx, 145 + params.title, 146 + params.artist, 147 + ); 144 148 } catch (error) { 145 149 consola.warn( 146 150 "Spotify search failed, falling back to Deezer:",
+1 -1
crates/rocksky-sdk/Cargo.toml
··· 1 1 [package] 2 2 name = "rocksky-sdk" 3 - version = "0.6.0" 3 + version = "0.6.1" 4 4 description = "Official Rust SDK for Rocksky — a music scrobbling & discovery platform on the AT Protocol" 5 5 authors.workspace = true 6 6 edition.workspace = true
+18
crates/rocksky-sdk/src/app_rocksky/song.rs
··· 202 202 ///The artist of the matched track. 203 203 #[serde(skip_serializing_if = "Option::is_none")] 204 204 pub artist: Option<S>, 205 + ///The disc number of the matched track in its album. 206 + #[serde(skip_serializing_if = "Option::is_none")] 207 + pub disc_number: Option<i64>, 205 208 ///The duration of the matched track in milliseconds. 206 209 #[serde(skip_serializing_if = "Option::is_none")] 207 210 pub duration_ms: Option<i64>, ··· 229 232 ///The title of the matched track. 230 233 #[serde(skip_serializing_if = "Option::is_none")] 231 234 pub title: Option<S>, 235 + ///The track number of the matched track in its album. 236 + #[serde(skip_serializing_if = "Option::is_none")] 237 + pub track_number: Option<i64>, 232 238 #[serde(flatten, default, skip_serializing_if = "Option::is_none")] 233 239 pub extra_data: Option<BTreeMap<SmolStr, Data<S>>>, 234 240 } ··· 1893 1899 }), 1894 1900 ); 1895 1901 map.insert( 1902 + SmolStr::new_static("discNumber"), 1903 + LexObjectProperty::Integer(LexInteger { 1904 + ..Default::default() 1905 + }), 1906 + ); 1907 + map.insert( 1896 1908 SmolStr::new_static("durationMs"), 1897 1909 LexObjectProperty::Integer(LexInteger { 1898 1910 minimum: Some(0i64), ··· 1966 1978 description: Some( 1967 1979 CowStr::new_static("The title of the matched track."), 1968 1980 ), 1981 + ..Default::default() 1982 + }), 1983 + ); 1984 + map.insert( 1985 + SmolStr::new_static("trackNumber"), 1986 + LexObjectProperty::Integer(LexInteger { 1969 1987 ..Default::default() 1970 1988 }), 1971 1989 );
+1 -1
sdk/clojure/build.clj
··· 13 13 [deps-deploy.deps-deploy :as dd])) 14 14 15 15 (def lib 'app.rocksky/sdk) 16 - (def version "0.8.0-SNAPSHOT") 16 + (def version "0.8.1-SNAPSHOT") 17 17 (def class-dir "target/classes") 18 18 (def basis (delay (b/create-basis {:project "deps.edn"}))) 19 19 (def jar-file (format "target/%s-%s.jar" (name lib) version))
+1 -1
sdk/elixir/mix.exs
··· 1 1 defmodule Rocksky.MixProject do 2 2 use Mix.Project 3 3 4 - @version "0.8.0" 4 + @version "0.8.1" 5 5 @source_url "https://github.com/tsirysndr/rocksky" 6 6 7 7 def project do
+1 -1
sdk/erlang/src/rocksky_erl.app.src
··· 3 3 "Official Erlang SDK for Rocksky — a Rustler NIF over the shared Rust core " 4 4 "(rocksky-sdk): AppView reads, record writes (scrobble fan-out, like, " 5 5 "follow, shout), and the identity hashes shared across every Rocksky SDK."}, 6 - {vsn, "0.5.0"}, 6 + {vsn, "0.5.1"}, 7 7 {registered, []}, 8 8 %% crypto/inets/ssl/public_key back the first-load NIF download + checksum 9 9 %% verify in rocksky_nif. kernel/stdlib are mandatory.
+1 -1
sdk/gleam/gleam.toml
··· 1 1 name = "rocksky" 2 - version = "1.8.0" 2 + version = "1.8.1" 3 3 4 4 description = "Gleam SDK for Rocksky — native bindings to the shared Rust core: AppView reads, AT Protocol PDS writes, and identity hashes" 5 5 licences = ["MIT"]
+4
sdk/go/rocksky/gen/types.go
··· 2227 2227 ISRC string `json:"isrc,omitempty"` 2228 2228 // The duration of the matched track in milliseconds. 2229 2229 DurationMS int `json:"durationMs,omitempty"` 2230 + // The track number of the matched track in its album. 2231 + TrackNumber int `json:"trackNumber,omitempty"` 2232 + // The disc number of the matched track in its album. 2233 + DiscNumber int `json:"discNumber,omitempty"` 2230 2234 // A URL to the matched track on the provider. 2231 2235 Link string `json:"link,omitempty"` 2232 2236 // A URL to a short audio preview of the matched track.
+1 -1
sdk/kotlin/rocksky/build.gradle.kts
··· 18 18 } 19 19 20 20 group = "app.rocksky" 21 - version = "0.9.0" 21 + version = "0.9.1" 22 22 23 23 kotlin { 24 24 jvmToolchain(17)
+1 -1
sdk/python/pyproject.toml
··· 1 1 [project] 2 2 name = "rocksky" 3 - version = "0.8.0" 3 + version = "0.8.1" 4 4 description = "Python SDK for Rocksky — native bindings to the shared Rust core" 5 5 readme = "README.md" 6 6 license = { text = "MIT" }
+1 -1
sdk/ruby/lib/rocksky/version.rb
··· 1 1 # frozen_string_literal: true 2 2 3 3 module Rocksky 4 - VERSION = "0.8.0" 4 + VERSION = "0.8.1" 5 5 end
+1 -1
sdk/typescript/package.json
··· 1 1 { 2 2 "name": "@rocksky/sdk", 3 - "version": "0.8.0", 3 + "version": "0.8.1", 4 4 "description": "TypeScript SDK for Rocksky \u2014 built on atcute: AppView reads, AT Protocol PDS writes (scrobble, like, follow, shout), a local dedup index, and Jetstream real-time sync.", 5 5 "license": "MIT", 6 6 "repository": {
+4
sdk/typescript/src/generated/types.ts
··· 2273 2273 isrc?: string; 2274 2274 /** The duration of the matched track in milliseconds. */ 2275 2275 durationMs?: number; 2276 + /** The track number of the matched track in its album. */ 2277 + trackNumber?: number; 2278 + /** The disc number of the matched track in its album. */ 2279 + discNumber?: number; 2276 2280 /** A URL to the matched track on the provider. */ 2277 2281 link?: Uri; 2278 2282 /** A URL to a short audio preview of the matched track. */