commits
Use artist genres instead of album genres. Parse Spotify album
release_date based on release_date_precision ('day' or 'year') to
compute releaseDate and year and pass them from retrieve to
presentation.
Join spotifyAccounts to spotifyTokens by userId (was using the wrong app
id), and add guard clauses that warn and return undefined when no tokens
or when token/app data are missing to avoid runtime errors.
Replace CURRENT_TIMESTAMP defaults with (unixepoch()) across schemas and
migration metadata. Enhance matchTrack to also match by albumArtist and
log the database query result.
Update client search endpoint and adapt to the new response shape (using
hits and _federation.indexUid). Remap result fields and fix
links/display names. Add matchTrack helper and use logger in scrobble.
Enhance CLI help styling and messages.
Register a 'meta' console sink and a logger for 'logtape' and 'meta'
categories with lowestLevel set to warning.
Create a lock file in the OS temp dir (rocksky-<did>.lock) to prevent
concurrent syncs; exit if lock exists and remove the lock after the run.
Change subscribeToJetstream to accept the user, filter by user.did, and
include commit cid. Dispatch create events to new onNewCollection
handlers which call
createArtists/createAlbums/createSongs/createScrobbles.
Add genres and artist_genres tables and create unique indexes on join
tables (album_tracks, artist_albums, artist_tracks, loved_tracks,
user_albums/user_artists/user_tracks). Update migration SQL, snapshot
and journal metadata, add PAGE_SIZE and imports in CLI sync, and tweak
agent logging.
Introduce Rocksky sync flow and Agent support. Replace sha256 columns
with cid across schemas, add scrobbles and auth_sessions tables, and add
an unstorage SQLite driver and DID cache. Add env parsing, ID
resolution/extraction utilities, update context, and adjust deps and
migration metadata
Introduce a JetStreamClient implementation and a new sync command
(apps/cli/src/cmd/sync.ts), add structured logging via @logtape/logtape,
and wire a logger into the CLI context. Remove the old @atcute/jetstream
dependency and add @logtape/logtape. Simplify scrobble CLI to a stub and
adjust schema imports to .js. Fix the now-playing query to select the
latest scrobble per user using DISTINCT ON.
Turn off React Query's structural sharing for now-playings so new arrays
are treated as changes. Also pass values directly to setQueryData for
now-playings and scrobblesChart instead of updater functions.
Make the client update now-playings by assigning a fresh array and
disable redundant invalidations. Adjust the websocket message shape so
the fields arrive at the top level for the client to consume.
Add publish_user that sends user JSON over NATS and call it after
committing user-related transactions. Thread an async_nats::Client
through save_scrobble and the websocket handler. Change save_user to
return the user's xata_id and remove the per-publish NATS connection
spawn in favor of a shared client created in the subscriber.
Add an outer try/catch around MusicBrainz hydrate requests, log
failures, and only assign mbId/artists when the lookup succeeds to avoid
throwing on lookup errors
Wrap /hydrate request in try/catch and set mbTrack to null on failure
Fetch all-time top track and fall back to it when the 7-day query is
empty. Wait for both queries to finish before rendering and use the
first available track for title, artist and album art.
Wire startDate/endDate through lexicons, PKL defs, TypeScript types, and
xrpc handlers to allow date-range filtering for actor albums, artists,
and songs.
Fix lexicon index mappings: swap artist getArtist/getArtistAlbums
entries, add feed.getFeed method, and reorder imports. Minor formatting
tweaks (scrobble likes filter, PKL whitespace).
Bind optional start_date/end_date as Option<&str> so None becomes SQL
NULL and use CAST(? AS TIMESTAMP) to filter ranges. Return
MAX(s.created_at) as created_at (last played) and fix
play_count/unique_listeners column indexes. Use i64 pagination values
and duckdb::params! for parameter binding; place LIMIT before OFFSET in
queries.
Introduce start_user_thread helper to spawn per-user threads with
automatic retries, exponential backoff, and NATS publish after max
retries for external restart. Replace direct thread spawns with the
helper. Improve progress tracker by adding an inner recovery loop,
fixing cache update logic, and handling Redis errors gracefully.
Call extractPdsFromDid(repo) to obtain the PDS base URL and pass it to
AtpAgent instead of using the hardcoded https://bsky.social. Compute the
repo once from trackWithUri.uri and reuse it for getRecord.
Import and and not from drizzle-orm and require lovedTracks.uri to be
non-null so only valid loved tracks are returned
Show @handle next to display name, remove underline styling, and call
scrollToTop when opening profiles (imported helper). ReplyModal no
longer closes the modal on profile link click.
Add null checks and early returns in Handle to avoid using an undefined
profile.did. Add profile.data?.did to effect deps and use "" fallbacks
when checking Set membership. Fix useActorCompatibilityQuery type
(undefined) and remove unused LabelMedium import. Use empty-string
fallback when calling useFollowersInfiniteQuery.
Implement compatibility API client and add Compatibility type and
Profile type. Add useActorCompatibilityQuery hook and a new
Compatibility component included in the profile Overview. Also add
Authorization header for the compatibility request, update API client
typings, and apply small UI and null-safety fixes (Stats label markup,
profile follow handling, and follower query typing).
Create a lock file in the OS temp dir (rocksky-<did>.lock) to prevent
concurrent syncs; exit if lock exists and remove the lock after the run.
Change subscribeToJetstream to accept the user, filter by user.did, and
include commit cid. Dispatch create events to new onNewCollection
handlers which call
createArtists/createAlbums/createSongs/createScrobbles.
Introduce a JetStreamClient implementation and a new sync command
(apps/cli/src/cmd/sync.ts), add structured logging via @logtape/logtape,
and wire a logger into the CLI context. Remove the old @atcute/jetstream
dependency and add @logtape/logtape. Simplify scrobble CLI to a stub and
adjust schema imports to .js. Fix the now-playing query to select the
latest scrobble per user using DISTINCT ON.
Add publish_user that sends user JSON over NATS and call it after
committing user-related transactions. Thread an async_nats::Client
through save_scrobble and the websocket handler. Change save_user to
return the user's xata_id and remove the per-publish NATS connection
spawn in favor of a shared client created in the subscriber.
Wire startDate/endDate through lexicons, PKL defs, TypeScript types, and
xrpc handlers to allow date-range filtering for actor albums, artists,
and songs.
Fix lexicon index mappings: swap artist getArtist/getArtistAlbums
entries, add feed.getFeed method, and reorder imports. Minor formatting
tweaks (scrobble likes filter, PKL whitespace).
Bind optional start_date/end_date as Option<&str> so None becomes SQL
NULL and use CAST(? AS TIMESTAMP) to filter ranges. Return
MAX(s.created_at) as created_at (last played) and fix
play_count/unique_listeners column indexes. Use i64 pagination values
and duckdb::params! for parameter binding; place LIMIT before OFFSET in
queries.
Introduce start_user_thread helper to spawn per-user threads with
automatic retries, exponential backoff, and NATS publish after max
retries for external restart. Replace direct thread spawns with the
helper. Improve progress tracker by adding an inner recovery loop,
fixing cache update logic, and handling Redis errors gracefully.
Add null checks and early returns in Handle to avoid using an undefined
profile.did. Add profile.data?.did to effect deps and use "" fallbacks
when checking Set membership. Fix useActorCompatibilityQuery type
(undefined) and remove unused LabelMedium import. Use empty-string
fallback when calling useFollowersInfiniteQuery.
Implement compatibility API client and add Compatibility type and
Profile type. Add useActorCompatibilityQuery hook and a new
Compatibility component included in the profile Overview. Also add
Authorization header for the compatibility request, update API client
typings, and apply small UI and null-safety fixes (Stats label markup,
profile follow handling, and follower query typing).