Skip to content

feat(client): native (Node/CJS) targets + public write_audio sender#269

Open
ryanontheinside wants to merge 1 commit into
refactor/client-sdk-configfrom
feat/client-sdk-native-targets
Open

feat(client): native (Node/CJS) targets + public write_audio sender#269
ryanontheinside wants to merge 1 commit into
refactor/client-sdk-configfrom
feat/client-sdk-native-targets

Conversation

@ryanontheinside

Copy link
Copy Markdown
Collaborator

What

Enabling work in @demon/client so the native hosts (the Max for Live bridge now; the VST next) can adopt the SDK as the single wire-contract source of truth, killing the hand-reimplemented protocol copies.

  • sendWriteAudio — public sender for the write_audio command (the input primitive behind every M4L feed mode and the VST live splice). Field set (at_s/mix/repeat/source_epoch/refresh_timbre) derived from the registry in protocol.py; dropIfBusy is the client-side backpressure gate.
  • audio_written / audio_write_failed — dispatch these registered events instead of letting them fall through to the generic json event; completes the write_audio ack surface.
  • get sliceEpoch() — expose the source-generation counter consumers need to tag local buffers and pin write_audio sends.
  • WebSocketConstructor option — inject a WebSocket impl (the bridge passes ws); the OPEN ready-state constant is resolved from it so the senders never read a global WebSocket (Node-for-Max has none reliably).
  • node.ts + CJS build target — a single self-contained dist/demon-client.node.cjs (fzstd inlined, no browser-audio code) for require()-based hosts. Browser dist/demon-client.js regenerated.

Scope / dependency

Verification

Additive surface. Web app tsc --noEmit passes; SDK boundary guard + wire-contract drift guard pass (18/18). The new senders/events/WS-injection are exercised end-to-end by the bridge's mock-server suite in the dependent PR (25/25).

Enabling work for the M4L bridge and VST adopting @demon/client as the
single wire-contract source of truth (follow-up to PR #267, reviewed
separately so #267 stays scoped).

- sendWriteAudio: public sender for the write_audio command (the input
  primitive behind every M4L feed mode + the VST live splice). Field set
  (at_s/mix/repeat/source_epoch/refresh_timbre) derived from the registry
  in protocol.py; dropIfBusy is the client-side backpressure gate.
- audio_written / audio_write_failed: dispatch these registered events
  (they were falling through to the generic json event), completing the
  write_audio ack surface.
- sliceEpoch getter: expose the source-generation counter consumers need
  to tag local buffers and pin write_audio sends.
- WebSocketConstructor option: inject a WebSocket impl (the bridge passes
  `ws`); resolve the OPEN ready-state constant from it so the senders
  never read a global WebSocket (Node-for-Max has none reliably).
- node.ts + CJS build target: a single self-contained dist/
  demon-client.node.cjs (fzstd inlined, no browser-audio code) for
  require()-based hosts.

Browser bundle (dist/demon-client.js) regenerated. Additive surface;
web app tsc and the SDK boundary/wire-contract guards pass.
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