Add synchronized server-backed playlists
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 9
- Forks
- 0
- Avg merge
- 12h 12m
- Merged PRs (30d)
- 24
Description
Goal
Add server-backed playlists synchronized through the Subsonic-compatible API, with account-scoped local caching and offline browsing.
Favorites are explicitly out of scope.
Initial scope
- List accessible playlists and show playlist metadata and ordered tracks.
- Create, rename, and delete editable playlists.
- Add/remove track occurrences and reorder tracks, preserving duplicates.
- Play a playlist or add its tracks to the playback queue.
- Cache playlist summaries and previously loaded playlist contents for offline browsing; only downloaded tracks are playable offline. Fetch details on opening a playlist. Distinguish contents not fetched from an empty playlist; fetching all playlist contents for comprehensive offline availability is outside the initial scope.
- Require connectivity for edits in the initial version. Durable offline editing is a follow-up, not an implied guarantee.
- Refresh on startup, manual refresh, and playlist opening as appropriate. Surface loading, save failures, and stale data without discarding cached content.
Server API and capabilities
Use the portable Subsonic baseline:
getPlaylists: list accessible playlists.getPlaylist: read metadata and ordered entries.createPlaylist: create a playlist, or replace an existing sequence usingplaylistIdand repeatedsongIdparameters.updatePlaylist: rename/change metadata, append withsongIdToAdd, remove occurrences withsongIndexToRemove.deletePlaylist: delete a playlist.
There is no portable move operation; reorder by replacing the full sequence. Accessible/public playlists are not necessarily editable. Respect ownership and server permissions, handle unsupported actions, and verify behavior against Navidrome and supported Subsonic/OpenSubsonic implementations. Public visibility is separate from anonymous share links.
Smart-playlist rule editing, provider-specific collaboration, and share-link management are out of scope. Server-generated playlists may be readable without editable membership; do not assume all exposed playlists support writes.
Architecture
src/subsonic-client.ts: endpoint methods and response validation, including repeated parameters.src/network.svelte.ts: normalized playlist operations and connection-scoped capabilities; keep protocol mapping here.src/schema.ts: playlist metadata and ordered entry types. Entries represent occurrences rather than using track IDs as unique row identities.src/cache.svelte.ts: use the current memory-firstCheckpointStorefor an independent account-scoped playlist document, separate from library and queue data. Include it inload(),flush(),dirty, and aggregated errors; do not introduce persist-before-publish semantics.- New playlist engine: independent refresh, serialized server-confirmed online editing, reconciliation, and errors. Show pending mutations, then publish confirmed results into the memory-first cache; avoid optimistic rollback/outbox machinery in v1.
src/session.svelte.ts: restoration, capability attachment/detachment, cancellation, and refresh coordination.- UI: playlist index/detail, management actions, add-to-playlist actions, reorder controls, and save/error states.
Extend the existing on-demand CoverEngine to resolve playlist artwork; do not persist artwork candidate indexes.
Cache playlist summaries separately from loaded details within the playlist domain. Preserve ordered track IDs and lightweight entry descriptions when library lookup fails. Do not feed playlist entries through whole-library normalization, which currently expects matching albums.
Playlist refresh is independent of the paginated search3 library traversal: the getIndexes library timestamp cannot establish playlist freshness.
Playing a playlist copies its sequence into the queue; later playlist edits must not unexpectedly change active playback. Preserve missing/unavailable track IDs rather than uploading a filtered sequence. Playlist sync must remain separate from downloading audio.
Synchronization safety
Subsonic does not provide a portable change stream, atomic conditional revision check, or idempotency keys for playlist creation/appends.
- Serialize writes per playlist and protect local edits from stale responses.
- Re-fetch/reconcile before writes where appropriate. Before destructive sequence replacement, detect changed remote contents and ask the user to reload or explicitly overwrite. Full merge/save-as-copy recovery can follow. A read-before-write check cannot eliminate all server races.
- Separate server mutation success from local durability: an OPFS checkpoint failure after server success is a cache failure, not a reason to repeat creation/appending.
- After an uncertain timeout, reconcile before retrying creation or append operations to avoid duplicates.
- Abort obsolete work on disconnect/account switch and prevent late responses from updating another account cache.
- Keep playlist failures independent from library refresh and playback.
Follow-up: durable offline editing
If offline edits are added, persist local mutations and a durable outbox together, retain a last-synchronized baseline, and support pending/error/conflict states, restart-safe retries, deletion records, and local-to-server ID mapping for new playlists.
Do not reuse the playback queue upload policy unchanged: its pending uploads are connection-scoped and lose eligibility on disconnect.
Acceptance criteria
- CRUD and track ordering synchronize with the server and are visible in another compatible client after refresh.
- Duplicate occurrences can be independently removed and reordered.
- Read-only/unsupported actions fail gracefully without losing cached data.
- Cached summaries and previously loaded playlist contents restore after a successful checkpoint and remain browsable offline. Unloaded contents are explicitly distinguished from empty playlists; offline editing is clearly unavailable in the initial version.
- Playing/enqueuing a playlist preserves existing playback semantics.
- Unavailable tracks are not silently deleted from playlists.
- Tests cover protocol mapping, persistence failures, stale responses, account isolation, cancellation, conflicting edits, and uncertain write outcomes.
- Verify playlist behavior against Navidrome and document any provider limitations.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reading the playlist-related responsibilities in src/subsonic-client.ts, src/network.svelte.ts, src/schema.ts, src/cache.svelte.ts, and src/session.svelte.ts, then trace the existing CheckpointStore and CoverEngine. Use the acceptance criteria to define coverage for protocol mapping, persistence failures, stale responses, account isolation, cancellation, conflicting edits, and uncertain writes. Done means CRUD, ordering, caching, offline browsing, playback, and graceful unsupported actions work across compatible servers without losing unavailable tracks.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- api, full-stack
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 35/100