diff --git a/crates/rocksky-sdk/README.md b/crates/rocksky-sdk/README.md index d9f141ba..abccdf5d 100644 --- a/crates/rocksky-sdk/README.md +++ b/crates/rocksky-sdk/README.md @@ -73,7 +73,7 @@ Ok(()) } | Verb | Record(s) | | -------------------------------------- | ----------------------------- | | `scrobble(draft)` → `ScrobbleResult` | fans out to **artist + album + song + scrobble** (duplicates skipped) | -| `scrobble_match(title, artist, album, mb_id, isrc)` | resolves full metadata via `match_song`, then the same fan-out (album/mb_id/isrc optional) | +| `scrobble_match(&ScrobbleMatch { .. })` | resolves full metadata via `match_song`, then the same fan-out (title/artist required; album/mb_id/isrc/timestamp optional) | | `create_song(draft)` | `app.rocksky.song` | | `create_album(draft)` | `app.rocksky.album` | | `create_artist(draft)` | `app.rocksky.artist` | diff --git a/docs/sdks/clojure.mdx b/docs/sdks/clojure.mdx index dcba8cfe..c829d7af 100644 --- a/docs/sdks/clojure.mdx +++ b/docs/sdks/clojure.mdx @@ -13,7 +13,7 @@ identity hashes — the same engine behind every Rocksky SDK. deps.edn: ```clojure -app.rocksky/sdk {:mvn/version "0.5.0-SNAPSHOT"} +app.rocksky/sdk {:mvn/version "0.6.0-SNAPSHOT"} ``` The jar is native-free; the library is fetched from the GitHub release on first @@ -62,8 +62,10 @@ e.g. `(top-tracks-interval 5 0 [:days 7])`. canonical metadata. **Writes — `rocksky.core`**: `(login ... :dedup-path "./dedup")`, then -`(scrobble agent track)` (full metadata) or `(scrobble-match agent title artist)` -(optionally `... album mb-id isrc` — match-then-write), `(like agent uri cid)`, +`(scrobble agent track)` (full metadata) or `(scrobble-match agent params)` — a +map with camelCase keys, required `:title`/`:artist`, optional `:album`, `:mbId`, +`:isrc` (match anchors) and `:timestamp` (scrobbled-at Unix seconds) — +match-then-write, `(like agent uri cid)`, `(follow agent did)`, `(shout ...)`, `(refresh-session agent)`, `(agent-close agent)`. With `:dedup-path` set, `(sync-repo agent)` (repo backfill) and `(hydrate-from-jetstream agent)` (live stream) run deduped against the diff --git a/docs/sdks/elixir.mdx b/docs/sdks/elixir.mdx index a2857f50..6f44834e 100644 --- a/docs/sdks/elixir.mdx +++ b/docs/sdks/elixir.mdx @@ -13,11 +13,11 @@ behind every Rocksky SDK. The same NIF powers the [Erlang](/sdks/erlang) and ```elixir def deps do - [{:rocksky_ex, "~> 0.5"}] + [{:rocksky_ex, "~> 0.6"}] end ``` -`rocksky_ex` 0.5.0 pulls in `rocksky_erl` 0.2.0, whose loader fetches the native +`rocksky_ex` 0.6.0 pulls in `rocksky_erl` 0.3.0, whose loader fetches the native library from the GitHub release on first use. ## Quickstart @@ -62,8 +62,12 @@ Typed date-window charts: `top_tracks_interval(5, 0, {:days, 7})` / metadata. **Writes — `Rocksky`**: `login(session, id, pw, appview \\ "", dedup_path \\ "")`, -then `scrobble` (full metadata) or `scrobble_match(agent, title, artist, album -\\ "", mb_id \\ "", isrc \\ "")` (match-then-write), `like`, `follow`, `shout`, +then `scrobble` (full metadata) or `scrobble_match(agent, input)` — `input` is a +map with camelCase string keys, required `"title"`/`"artist"`, optional +`"album"`, `"mbId"`, `"isrc"` (match anchors) and `"timestamp"` (scrobbled-at +Unix seconds), e.g. +`Rocksky.scrobble_match(agent, %{"title" => "Chaser", "artist" => "Calibro 35"})` +— then `like`, `follow`, `shout`, `refresh_session`. Pass a `dedup_path` at login to enable dedup + realtime, then `sync_repo(agent)` / `hydrate_from_jetstream(agent)`. diff --git a/docs/sdks/erlang.mdx b/docs/sdks/erlang.mdx index 710ba7b1..a5e32055 100644 --- a/docs/sdks/erlang.mdx +++ b/docs/sdks/erlang.mdx @@ -17,7 +17,7 @@ the GitHub release on first use. ```erlang %% rebar.config -{deps, [{rocksky_erl, "0.2.0"}]}. +{deps, [{rocksky_erl, "0.3.0"}]}. ``` ## Quickstart @@ -34,7 +34,8 @@ io:format("~p scrobbles~n", [maps:get(<<"scrobbles">>, Stats)]), %% Writes — log in with an app password. Agent = rocksky:agent_login(<<"session.json">>, <<"alice.bsky.social">>, <<"app-pw">>), -{ok, Out} = rocksky:agent_scrobble_match(Agent, <<"Chaser">>, <<"Calibro 35">>). +{ok, Out} = rocksky:agent_scrobble_match(Agent, + #{<<"title">> => <<"Chaser">>, <<"artist">> => <<"Calibro 35">>}). ``` Reads/writes return `{ok, Value}` | `{error, Message}` with binary-keyed maps. @@ -72,9 +73,13 @@ into full canonical metadata (album, artwork, duration, MBID, ISRC, links). then `agent_scrobble` (full metadata), `agent_like`, `agent_follow`, `agent_shout`, `agent_refresh_session`. -**Match-then-scrobble** — `rocksky:agent_scrobble_match(Agent, Title, Artist)` -(also `/4` with `Album`, `/6` with `Album`, `MbId`, `Isrc`) resolves canonical -metadata and scrobbles in one call. +**Match-then-scrobble** — `rocksky:agent_scrobble_match(Agent, Input)` where +`Input` is a map with camelCase binary keys: required `<<"title">>`/`<<"artist">>`, +optional `<<"album">>`, `<<"mbId">>`, `<<"isrc">>` (match anchors) and +`<<"timestamp">>` (scrobbled-at Unix seconds). Resolves canonical metadata and +scrobbles in one call. (A flat `/7` form — +`agent_scrobble_match(Agent, Title, Artist, Album, MbId, Isrc, Timestamp)`, empty +strings / `0` omitted — backs the Gleam SDK.) **Dedup + realtime** — pass a `DedupPath` to `agent_login/5` to enable the local dedup store, then keep it warm with `rocksky:agent_sync_repo(Agent)` and diff --git a/docs/sdks/gleam.mdx b/docs/sdks/gleam.mdx index dae4ef5e..49dab0c1 100644 --- a/docs/sdks/gleam.mdx +++ b/docs/sdks/gleam.mdx @@ -11,10 +11,10 @@ PDS writes, and the identity hashes. Targets Erlang. ## Install ```bash -gleam add rocksky # rocksky = ">= 1.5.0 and < 2.0.0" +gleam add rocksky # rocksky = ">= 1.6.0 and < 2.0.0" ``` -`rocksky` 1.5.0 depends on `rocksky_erl` 0.2.0, whose loader fetches the native +`rocksky` 1.6.0 depends on `rocksky_erl` 0.3.0, whose loader fetches the native library from the GitHub release on first use. ## Quickstart @@ -52,8 +52,12 @@ LastYears(Int) | Range(String, String)`. `match_song(title, artist)` resolves a bare title + artist into full canonical metadata. **Writes**: `login(session_path, identifier, password)`, then `scrobble` (full -metadata) or `scrobble_match(agent, title, artist, album, mb_id, isrc)` -(match-then-write), `like`, `follow`, `shout`, `refresh_session`. With a dedup path +metadata) or `scrobble_match(agent, ScrobbleMatch(title, artist, album, mb_id, +isrc, timestamp))` (match-then-write) — `title`/`artist` are `String`, the rest +`Option` (`album` override, `mb_id`/`isrc` match anchors, `timestamp` scrobbled-at +Unix seconds), e.g. +`scrobble_match(agent, ScrobbleMatch("Chaser", "Calibro 35", None, None, None, None))` — +`like`, `follow`, `shout`, `refresh_session`. With a dedup path set, `sync_repo(agent)` / `hydrate_from_jetstream(agent)` keep the dedup + realtime store warm. diff --git a/docs/sdks/go.mdx b/docs/sdks/go.mdx index 9c674dfd..eaf1164f 100644 --- a/docs/sdks/go.mdx +++ b/docs/sdks/go.mdx @@ -61,8 +61,9 @@ auth-gated queries with `NewClient("").WithToken(token)`. `TopTracks` / `TopArtists` remain all-time shorthands. **Writes — `Agent`**: `Scrobble` (fan-out from full metadata), -`ScrobbleMatch(ctx, appview, title, artist, album, mbID, isrc)` (resolves -metadata via `MatchSong`, then the same fan-out; album/mbID/isrc optional), +`ScrobbleMatch(ctx, appview, ScrobbleMatchInput{Title, Artist})` (resolves +metadata via `MatchSong`, then the same fan-out; Title/Artist required, +Album/MbID/ISRC/Timestamp optional pointers, `appview` "" = default), `CreateSong` / `CreateAlbum` / `CreateArtist`, `Like`, `Follow`, `Shout` / `ReplyShout`, `SetNowPlaying` / `ClearNowPlaying`, `Delete`, `RefreshSession`. Records are the generated `gen.*Record` types. diff --git a/docs/sdks/kotlin.mdx b/docs/sdks/kotlin.mdx index 32cb9a44..b65ca80a 100644 --- a/docs/sdks/kotlin.mdx +++ b/docs/sdks/kotlin.mdx @@ -13,7 +13,7 @@ Rocksky SDK. ```kotlin dependencies { - implementation("app.rocksky:rocksky-kotlin:0.6.0") + implementation("app.rocksky:rocksky-kotlin:0.7.0") } ``` @@ -56,8 +56,11 @@ metadata. A raw-JSON long tail (`album`, `artist`, `song`, `playlists`, calls **any** read query by NSID. **Writes — `Agent`**: `login(...)` (top-level, `appview`/`dedupPath` optional), -then `scrobble` (full metadata) or `scrobbleMatch(title, artist, album, mbId, -isrc)` (resolve via `matchSong`, then fan out), `createSong` / `createAlbum` / +then `scrobble` (full metadata) or `scrobbleMatch(ScrobbleMatchInput(title, +artist, album, mbId, isrc, timestamp))` (resolve via `matchSong`, then fan out — +`title`/`artist` required, `album`/`mbId`/`isrc` are `String?` and `timestamp` +is `Long?`, all default null; `ScrobbleMatchInput` is an `app.rocksky` +typealias), `createSong` / `createAlbum` / `createArtist`, `like` / `unlike`, `follow` / `unfollow`, `shout` / `replyShout`, `setNowPlaying` / `clearNowPlaying`, `syncRepo` (dedup backfill, returns per-collection counts as JSON), `hydrateFromJetstream` (live dedup off the diff --git a/docs/sdks/overview.mdx b/docs/sdks/overview.mdx index 1cc84fb2..1133a4ee 100644 --- a/docs/sdks/overview.mdx +++ b/docs/sdks/overview.mdx @@ -66,7 +66,9 @@ Every SDK exposes the same three things: auth-gated queries. - **Writes** — an **Agent** that logs in with an **app password**, resolves the account's PDS, and writes records: `scrobble`, `scrobble_match` - (match-then-write from a bare title + artist), `createSong` / `createAlbum` / + (match-then-write from a title/artist input object, with optional album + override, `mbId`/`isrc` match anchors, and a scrobbled-at timestamp), + `createSong` / `createAlbum` / `createArtist`, `like`, `follow`, `shout`, now-playing. - **Identity hashes** — `songHash` / `albumHash` / `artistHash` (lowercase-hex SHA-256), byte-for-byte identical across every SDK and the server. diff --git a/docs/sdks/python.mdx b/docs/sdks/python.mdx index 0ae4b7be..849fa458 100644 --- a/docs/sdks/python.mdx +++ b/docs/sdks/python.mdx @@ -12,11 +12,11 @@ hashes — the same engine behind every Rocksky SDK. ```bash uv -uv add rocksky==0.5.0 +uv add rocksky==0.6.0 ``` ```bash pip -pip install rocksky==0.5.0 +pip install rocksky==0.6.0 ``` @@ -61,8 +61,10 @@ bare title+artist to canonical metadata. A raw-JSON long tail (`album`, `artist` `av.get(nsid, params)` (a `dict[str, str]`) calls **any** read query by NSID. **Writes — `Agent`**: `login_password(...)`, then `scrobble` (full metadata) or -`scrobble_match(title, artist, album, mb_id, isrc)` (resolve via `match_song`, -then fan out), `create_song` / `create_album` / `create_artist`, `like` / +`scrobble_match(ScrobbleMatchInput(title, artist, album=None, mb_id=None, +isrc=None, timestamp=None))` (resolve via `match_song`, then fan out — `title`/ +`artist` required, `timestamp` is scrobbled-at Unix seconds; `ScrobbleMatchInput` +imports from `rocksky`), `create_song` / `create_album` / `create_artist`, `like` / `unlike`, `follow` / `unfollow`, `shout` / `reply_shout`, `set_now_playing` / `clear_now_playing`, `sync_repo` (dedup backfill, returns per-collection counts as JSON), `hydrate_from_jetstream` (live dedup off the firehose). diff --git a/docs/sdks/ruby.mdx b/docs/sdks/ruby.mdx index 653a6e36..0e5c3971 100644 --- a/docs/sdks/ruby.mdx +++ b/docs/sdks/ruby.mdx @@ -14,7 +14,7 @@ same engine behind every Rocksky SDK. gem install rocksky ``` -Or in a Gemfile: `gem "rocksky", "~> 0.5"`. +Or in a Gemfile: `gem "rocksky", "~> 0.6"`. The gem is pure-Ruby; the native library is fetched from the GitHub release on first load and cached. @@ -64,8 +64,10 @@ and `top_artists_interval(...)` — `interval:` is `:all` or `[:days, n]` / bare title + artist into full canonical metadata. **Writes — `Rocksky::Agent`**: `login(..., dedup_path:)`, then `scrobble` -(full metadata) or `scrobble_match(title, artist, album: nil, mb_id: nil, isrc: nil)` -(match-then-write), plus `like`, `follow`, `shout`, `refresh_session`, `close`. +(full metadata) or `scrobble_match(params)` — a single Hash with camelCase +string keys, required `"title"`/`"artist"`, optional `"album"`, `"mbId"`, +`"isrc"`, `"timestamp"` (match-then-write), plus `like`, `follow`, `shout`, +`refresh_session`, `close`. With `dedup_path:` set at login, `sync_repo` (repo backfill) and `hydrate_from_jetstream` (live stream) run deduped against the on-disk store. diff --git a/docs/sdks/rust.mdx b/docs/sdks/rust.mdx index b298b48b..27364249 100644 --- a/docs/sdks/rust.mdx +++ b/docs/sdks/rust.mdx @@ -14,7 +14,7 @@ index and Jetstream real-time sync. ```toml [dependencies] -rocksky-sdk = { version = "0.2", features = ["dedup", "jetstream"] } +rocksky-sdk = { version = "0.4", features = ["dedup", "jetstream"] } ``` The `dedup` and `jetstream` features are optional (they pull in RocksDB + the @@ -69,8 +69,9 @@ let month = av.top_tracks_interval(DateInterval::LastDays(30), 50, 0).await?; ``` **Writes — `RockskyAgent`**: `scrobble` (fan-out from full metadata), -`scrobble_match(title, artist, album, mb_id, isrc)` (resolves metadata via -`match_song`, then the same fan-out; album/mb_id/isrc optional), `create_song` / +`scrobble_match(&ScrobbleMatch { .. })` (resolves metadata via `match_song`, then +the same fan-out; title/artist required, album/mb_id/isrc/timestamp optional), +`create_song` / `create_album` / `create_artist`, `like` / `unlike`, `follow` / `unfollow`, `shout` / `reply_shout`, `set_now_playing` / `clear_now_playing`. App-password + loopback OAuth login. diff --git a/docs/sdks/typescript.mdx b/docs/sdks/typescript.mdx index 817799e5..b315b78b 100644 --- a/docs/sdks/typescript.mdx +++ b/docs/sdks/typescript.mdx @@ -84,8 +84,13 @@ full canonical metadata (album, artwork, duration, MBID, ISRC, links). `new RockskyClient(appview, token)` — sent as `Authorization: Bearer `. **Writes — `Agent`**: two scrobble paths — `scrobble(rec)` writes full metadata -you already have, and `scrobbleMatch(title, artist, album?, mbId?, isrc?)` -resolves full metadata via `matchSong` first, then writes. Plus `createSong` / +you already have, and `scrobbleMatch(input, appview?)` takes a +`ScrobbleMatchInput` object (`{ title, artist, album?, mbId?, isrc?, timestamp? }` +— title/artist required; `album` overrides the resolved album, `mbId`/`isrc` are +match anchors, `timestamp` is a scrobbled-at Unix-seconds time; the optional +`appview` overrides the AppView used for matching) and resolves full metadata via +`matchSong` first, then writes — e.g. +`agent.scrobbleMatch({ title: "Chaser", artist: "Calibro 35" })`. Plus `createSong` / `createAlbum` / `createArtist`, `like`, `follow`, `shout` / `replyShout`, `setNowPlaying` / `clearNowPlaying`, `delete`. diff --git a/sdk/clojure/README.md b/sdk/clojure/README.md index b5d3ce39..9efc444b 100644 --- a/sdk/clojure/README.md +++ b/sdk/clojure/README.md @@ -12,7 +12,7 @@ same engine behind every Rocksky SDK. deps.edn: ```clojure -app.rocksky/sdk {:mvn/version "0.5.0-SNAPSHOT"} +app.rocksky/sdk {:mvn/version "0.6.0-SNAPSHOT"} ``` The jar is native-free; the library is fetched from the GitHub release on first @@ -89,8 +89,9 @@ canonical metadata. `(login session-path identifier password)` → an opaque agent handle; pass `:dedup-path "./dedup"` to enable scrobble dedup + realtime hydration (see below). Then `(scrobble agent track)` (full metadata, fans out to -artist/album/song/scrobble) or `(scrobble-match agent title artist)` (optionally -`... album mb-id isrc` — matches a bare title + artist first, then writes), +artist/album/song/scrobble) or `(scrobble-match agent params)` — a map with +camelCase keys, required `:title`/`:artist`, optional `:album`, `:mbId`, `:isrc`, +`:timestamp` — matching a bare title + artist first, then writes, `(like agent uri cid)`, `(follow agent did)`, `(shout agent subject-uri subject-cid message)`, `(refresh-session agent)`, `(agent-close agent)`. diff --git a/sdk/elixir/README.md b/sdk/elixir/README.md index 454a26c2..3e61ee43 100644 --- a/sdk/elixir/README.md +++ b/sdk/elixir/README.md @@ -16,11 +16,11 @@ every Rocksky SDK. ```elixir def deps do - [{:rocksky_ex, "~> 0.5"}] + [{:rocksky_ex, "~> 0.6"}] end ``` -`rocksky_ex` 0.5.0 pulls in `rocksky_erl` 0.2.0, whose loader fetches the native library from +`rocksky_ex` 0.6.0 pulls in `rocksky_erl` 0.3.0, whose loader fetches the native library from the GitHub release on first use (checksum-verified). For monorepo dev, build it locally and point at it: `../erlang/build-core.sh` then set `ROCKSKY_ERL_PATH=../erlang`. @@ -89,9 +89,12 @@ opaque agent handle. Then `scrobble(agent, track)` (full metadata; fans out to artist/album/song/scrobble), `like(agent, uri, cid)`, `follow(agent, did)`, `shout(agent, subject_uri, subject_cid, message)`, `refresh_session(agent)`. -**Match-then-scrobble** — `scrobble_match(agent, title, artist, album \\ "", mb_id -\\ "", isrc \\ "")` resolves canonical metadata and scrobbles in one call; the -full-metadata `scrobble/2` still works when you already have it. +**Match-then-scrobble** — `scrobble_match(agent, input)` resolves canonical +metadata and scrobbles in one call. `input` is a map with camelCase string keys: +required `"title"`/`"artist"`, optional `"album"` (override), `"mbId"`/`"isrc"` +(match anchors) and `"timestamp"` (scrobbled-at Unix seconds, default now) — +e.g. `scrobble_match(agent, %{"title" => "Chaser", "artist" => "Calibro 35"})`. +The full-metadata `scrobble/2` still works when you already have it. **Dedup + realtime** — pass a `dedup_path` to `login/5` to enable the local dedup store, then keep it warm with `sync_repo(agent)` and diff --git a/sdk/erlang/README.md b/sdk/erlang/README.md index 719d76f8..eac5df1f 100644 --- a/sdk/erlang/README.md +++ b/sdk/erlang/README.md @@ -37,7 +37,7 @@ Agent = rocksky:agent_login(<<"session.json">>, <<"alice.bsky.social">>, <<"app- Reads/writes return `{ok, Value}` | `{error, Message}` with binary-keyed maps. -The Hex package is `rocksky_erl` 0.2.0. +The Hex package is `rocksky_erl` 0.3.0. ## API @@ -70,9 +70,13 @@ into full canonical metadata. then `agent_scrobble` (full metadata), `agent_like`, `agent_follow`, `agent_shout`, `agent_refresh_session`. -**Match-then-scrobble** — `rocksky:agent_scrobble_match(Agent, Title, Artist)` -(also `/4` with `Album`, `/6` with `Album`, `MbId`, `Isrc`) resolves canonical -metadata and scrobbles in one call. +**Match-then-scrobble** — `rocksky:agent_scrobble_match(Agent, Input)` where +`Input` is a map with camelCase binary keys: required `<<"title">>`/`<<"artist">>`, +optional `<<"album">>`, `<<"mbId">>`, `<<"isrc">>` (match anchors) and +`<<"timestamp">>` (scrobbled-at Unix seconds). Resolves canonical metadata and +scrobbles in one call. A flat `/7` form — +`agent_scrobble_match(Agent, Title, Artist, Album, MbId, Isrc, Timestamp)`, empty +strings / `0` omitted — backs the Gleam SDK. **Dedup + realtime** — pass a `DedupPath` to `agent_login/5` to enable the local dedup store, then keep it warm with `rocksky:agent_sync_repo(Agent)` and diff --git a/sdk/gleam/README.md b/sdk/gleam/README.md index 9a6546b2..c883f111 100644 --- a/sdk/gleam/README.md +++ b/sdk/gleam/README.md @@ -15,10 +15,10 @@ Rocksky SDK. Targets Erlang. ## Installation ```sh -gleam add rocksky # rocksky = ">= 1.5.0 and < 2.0.0" +gleam add rocksky # rocksky = ">= 1.6.0 and < 2.0.0" ``` -`rocksky` 1.5.0 depends on `rocksky_erl` 0.2.0, whose loader fetches the native +`rocksky` 1.6.0 depends on `rocksky_erl` 0.3.0, whose loader fetches the native library from the GitHub release on first use (checksum-verified). For monorepo dev, build it with `../erlang/build-core.sh` and use the local path dep in `gleam.toml`. @@ -78,7 +78,10 @@ canonical metadata. `login(session_path, identifier, password)` → an opaque `Agent`. Then `scrobble(agent, track)` (full metadata) or -`scrobble_match(agent, title, artist, album, mb_id, isrc)` (match-then-write), +`scrobble_match(agent, ScrobbleMatch(title, artist, album, mb_id, isrc, timestamp))` +(match-then-write) — `title`/`artist` are `String`, the rest `Option` (`album` +override, `mb_id`/`isrc` match anchors, `timestamp` scrobbled-at Unix seconds), +e.g. `scrobble_match(agent, ScrobbleMatch("Chaser", "Calibro 35", None, None, None, None))`, `like(agent, uri, cid)`, `follow(agent, did)`, `shout(agent, subject_uri, subject_cid, message)`, `refresh_session(agent)`. diff --git a/sdk/go/README.md b/sdk/go/README.md index f73dfe8f..aa25661f 100644 --- a/sdk/go/README.md +++ b/sdk/go/README.md @@ -62,8 +62,9 @@ Attach a bearer token for auth-gated queries with `NewClient("").WithToken(token `TopTracks` / `TopArtists` remain all-time shorthands. **Writes — `Agent`**: `Scrobble` (fan-out from full metadata), -`ScrobbleMatch(ctx, appview, title, artist, album, mbID, isrc)` (resolves -metadata via `MatchSong`, then the same fan-out; album/mbID/isrc optional), +`ScrobbleMatch(ctx, appview, ScrobbleMatchInput{Title, Artist})` (resolves +metadata via `MatchSong`, then the same fan-out; Title/Artist required, +Album/MbID/ISRC/Timestamp optional pointers, `appview` "" = default), `CreateSong`/`CreateAlbum`/`CreateArtist`, `Like`, `Follow`, `Shout`/`ReplyShout`, `SetNowPlaying`/`ClearNowPlaying`, `Delete`, `RefreshSession`. Records are the generated `gen.*Record` types. diff --git a/sdk/kotlin/README.md b/sdk/kotlin/README.md index 298c27bc..780d4f08 100644 --- a/sdk/kotlin/README.md +++ b/sdk/kotlin/README.md @@ -10,7 +10,7 @@ every Rocksky SDK. Lives in the `:rocksky` Gradle module, package `app.rocksky`. ```kotlin dependencies { - implementation("app.rocksky:rocksky-kotlin:0.6.0") + implementation("app.rocksky:rocksky-kotlin:0.7.0") } ``` @@ -79,9 +79,13 @@ returns an agent (`appview`/`dedupPath` default to none). Then: - `scrobble(ScrobbleInput)` — from full metadata, writes the scrobble; with a dedup store, skips an existing same-second scrobble of the same track. -- `scrobbleMatch(title, artist, album, mbId, isrc)` — resolves the track via - `matchSong` first, then fans out the same way (`album` / `mbId` / `isrc` - optional). +- `scrobbleMatch(ScrobbleMatchInput)` — resolves the track via `matchSong` + first, then fans out the same way. `ScrobbleMatchInput(title, artist, album, + mbId, isrc, timestamp)` — `title`/`artist` required; `album`/`mbId`/`isrc` are + `String?` (album override, match anchors) and `timestamp` is `Long?` + (scrobbled-at Unix seconds), all defaulting to null. `ScrobbleMatchInput` is + an `app.rocksky` typealias + (e.g. `agent.scrobbleMatch(ScrobbleMatchInput(title = "Chaser", artist = "Calibro 35"))`). - `createSong(SongInput)`, `createAlbum(AlbumInput)`, `createArtist(ArtistInput)` - `like(uri, cid)`, `unlike(uri)`, `follow(did)`, `unfollow(did)` - `shout(subjectUri, subjectCid, message)`, `replyShout(...)` diff --git a/sdk/python/README.md b/sdk/python/README.md index 283a4ac9..ce51d26f 100644 --- a/sdk/python/README.md +++ b/sdk/python/README.md @@ -9,7 +9,7 @@ every Rocksky SDK (Ruby, Kotlin, Clojure, Erlang/Elixir/Gleam). ## Install ```sh -pip install rocksky==0.5.0 # or: uv add rocksky==0.5.0 +pip install rocksky==0.6.0 # or: uv add rocksky==0.6.0 ``` The wheel is pure-Python; the ~14 MB native library is fetched from the GitHub @@ -87,9 +87,12 @@ returns an agent. Then: - `scrobble(ScrobbleInput)` → `ScrobbleResult` — from full metadata, writes **artist + album + song + scrobble**, skipping any that already exist (with a dedup store). -- `scrobble_match(title, artist, album, mb_id, isrc)` → `ScrobbleResult` — - resolves the track via `match_song` first, then fans out the same way - (`album` / `mb_id` / `isrc` optional). +- `scrobble_match(ScrobbleMatchInput)` → `ScrobbleResult` — resolves the track + via `match_song` first, then fans out the same way. `ScrobbleMatchInput(title, + artist, album=None, mb_id=None, isrc=None, timestamp=None)` — `title`/`artist` + required; `album` overrides the resolved album, `mb_id`/`isrc` are match + anchors, `timestamp` is the scrobbled-at Unix seconds + (e.g. `agent.scrobble_match(ScrobbleMatchInput(title="Chaser", artist="Calibro 35"))`). - `create_song(SongInput)`, `create_album(AlbumInput)`, `create_artist(ArtistInput)` - `like(uri, cid)`, `unlike(uri)`, `follow(did)`, `unfollow(did)` - `shout(subject_uri, subject_cid, message)`, `reply_shout(...)` diff --git a/sdk/ruby/README.md b/sdk/ruby/README.md index 7973c705..b437df05 100644 --- a/sdk/ruby/README.md +++ b/sdk/ruby/README.md @@ -14,7 +14,7 @@ gem install rocksky Or in a Gemfile: ```ruby -gem "rocksky", "~> 0.5" +gem "rocksky", "~> 0.6" ``` The gem is pure-Ruby; the native library is fetched from the GitHub release on @@ -92,11 +92,14 @@ below). Then `scrobble(track)` (fans out to artist/album/song/scrobble), `refresh_session`, and `close` (release the native handle). **Two scrobble paths** — `scrobble(track)` takes full metadata, while -`scrobble_match(title, artist, album: nil, mb_id: nil, isrc: nil)` matches a bare +`scrobble_match(params)` takes a single Hash with camelCase string keys — +required `"title"`/`"artist"`, optional `"album"` (override), `"mbId"`/`"isrc"` +(match anchors), `"timestamp"` (scrobbled-at Unix seconds) — matching a bare title + artist first, then writes. ```ruby -agent.scrobble_match("Chaser", "Calibro 35", album: "Jazzploitation") +agent.scrobble_match("title" => "Chaser", "artist" => "Calibro 35", + "album" => "Jazzploitation") ``` **Dedup + realtime** — with `dedup_path:` set at login, `agent.sync_repo` diff --git a/sdk/typescript/README.md b/sdk/typescript/README.md index 225073f4..fdd4c96a 100644 --- a/sdk/typescript/README.md +++ b/sdk/typescript/README.md @@ -69,8 +69,13 @@ full canonical metadata (album, artwork, duration, MBID, ISRC, links). `Authorization: Bearer `. **Writes — `Agent`**: two scrobble paths. `scrobble(rec)` writes full metadata -you already have; `scrobbleMatch(title, artist, album?, mbId?, isrc?)` resolves -full metadata via `matchSong` first, then writes. Plus +you already have; `scrobbleMatch(input, appview?)` takes a `ScrobbleMatchInput` +object (`{ title, artist, album?, mbId?, isrc?, timestamp? }` — title/artist +required; `album` overrides the resolved album, `mbId`/`isrc` are match anchors, +`timestamp` is a scrobbled-at Unix-seconds time; the optional `appview` overrides +the AppView used for matching) and resolves full metadata via `matchSong` first, +then writes — e.g. `agent.scrobbleMatch({ title: "Chaser", artist: "Calibro 35" })`. +Plus `createSong`/`createAlbum`/`createArtist`, `like`, `follow`, `shout`/`replyShout`, `setNowPlaying`/`clearNowPlaying`, `delete`. Records are the generated types from `./generated/types`.