Skip to content

tapdeck 0.2.0 — in-house native Sonos engine, rename, and dependency diet#6

Merged
codybrom merged 8 commits into
mainfrom
inhouse-sonos-api
May 30, 2026
Merged

tapdeck 0.2.0 — in-house native Sonos engine, rename, and dependency diet#6
codybrom merged 8 commits into
mainfrom
inhouse-sonos-api

Conversation

@codybrom

@codybrom codybrom commented May 30, 2026

Copy link
Copy Markdown
Owner

Replaces the unmaintained sonos-http-api dependency with a small, zero-dependency native Sonos engine built into the project, and rebrands the (now-detached) fork as tapdeck 0.2.0. The app talks to Sonos directly over the LAN (UPnP/SOAP) — no API server, no port 5005, no cloud, no credentials.

Headline wins

  • npm audit: 9 → 0 — deleting sonos-http-api removes the entire EOL request/request-promise/lodash 3.x/aws-sdk chain.
  • Zero runtime deps for Sonos control (just dgram + native fetch + hand-rolled XML). Runtime deps are now only nfc-pcsc + nfccard-tool.
  • devDeps down to jest + prettier — Babel, husky, jest-fetch-mock, and assorted overrides/plugins all gone.

New engine — lib/sonos/

  • discovery.js SSDP discovery · system.js topology → group-coordinator resolution (handles stereo-pair Invisible members) + Spotify service lookup + favorites/playlists · player.js transport/rendering SOAP · services/spotify.js URI/DIDL + now-playing · soap.js/xml.js envelope + parsing.

Behavior

  • Spotify for spotify: tags; favorites/playlists/transport/command: work for any service already set up in the Sonos app; room: switches rooms.
  • Apple/Amazon/TuneIn/BBC tags log a clear 'unsupported' message (use a favorite).
  • Pre-play resets are best-effort (a radio source that rejects crossfade no longer aborts the tap).
  • New: a music card scanned into a near-muted speaker (volume < 5) raises it to min_volume (default 10) so a tap never plays silently.

Project / tooling

  • Renamed to tapdeck, version 0.2.0, README rewritten; repo renamed to codybrom/tapdeck.
  • Node 24 enforced via engines + .npmrc engine-strict (replaced the hacky preinstall guard).
  • Tests run as native ESM (jest --experimental-vm-modules, unstable_mockModule) — no Babel. Removing an unused nfc-pcsc import means the full suite runs without the native module.

Verification

  • 43/43 tests locally, on the Pi, and in CI on Node 24; npm audit 0.
  • Against the live system: discovery, coordinator resolution, volume floor (2 → 10), and playFavorite (Spotify) → PLAYING all confirmed.
  • Deployed + reboot-tested: PM2 resurrects tapdeck, reader re-attaches, engine rediscovers Sonos.

codybrom added 3 commits May 30, 2026 17:09
Port the proven subset of sonos-http-api/sonos-discovery into the project as a
zero-dependency, native (dgram + fetch + hand-rolled XML) engine under lib/sonos/,
and call it directly from process_sonos_command.js (no HTTP server, no port 5005).

- lib/sonos/{xml,soap,discovery,player,system,index}.js + services/spotify.js
- SSDP discovery, GetZoneGroupState topology -> group-coordinator resolution
  (handles stereo-pair Invisible members), SOAP transport, Spotify now-playing,
  favorites/playlists, command passthrough
- Spotify-only for music services; favorites/playlists/transport work for any
  service already configured in the Sonos app
- Drop deps: sonos-http-api, node-fetch, concurrently (+ their overrides);
  keep nan override for the nfc-pcsc native build
- Migrate tests from fetch-mock to engine-mock; add xml/soap/spotify/system
  unit tests with fixtures captured from the live system

Removes the entire EOL request/lodash/aws-sdk chain -> npm audit now 0 vulns.
@codybrom codybrom self-assigned this May 30, 2026
codybrom added 5 commits May 30, 2026 17:25
- name -> tapdeck, version -> 0.2.0, refreshed description + README
- remove nan override (pcsclite's own ^2.14.0 already resolves to nan 2.27,
  which builds on Node 24 — override was redundant)
- remove unused babel-plugin-transform-amd-to-commonjs devDependency
…uard

- remove husky devDep, prepare hook, .husky/ (IDE handles autoformat);
  simplify format script to 'prettier --write .'
- replace the hacky preinstall node-version check with engines>=24 +
  .npmrc engine-strict=true (now viable since sonos-http-api/request,
  which declared npm ^2.0.0, is gone)
- remove @babel/core, @babel/preset-env, babel-jest + babel.config.json
- jest.config: transform:{} (no transpile; native ESM via package type:module)
- test script: NODE_OPTIONS=--experimental-vm-modules jest
- migrate mocking to jest.unstable_mockModule + dynamic import in the two
  engine/command tests and sonos_nfc test
- sonos_nfc.test: drop unused nfc-pcsc import (suite no longer needs the
  native module) and inline the nfccard-tool mock; remove __mocks__/
- devDeps now just jest + prettier
When a music card (spotify/favorite/playlist) is scanned and the speaker is
basically muted (volume < 5), raise it to min_volume (configurable, default
10) so the tap never plays silently. command:/room: are unaffected.
@codybrom codybrom changed the title Replace sonos-http-api with an in-house native Sonos engine tapdeck 0.2.0 — in-house native Sonos engine, rename, and dependency diet May 30, 2026
@codybrom codybrom merged commit b0871b4 into main May 30, 2026
1 check passed
@codybrom codybrom deleted the inhouse-sonos-api branch May 30, 2026 22:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant