Skip to content

feat(sdk): add kinesis over Bluetooth transport#134

Draft
andrewjaykeller wants to merge 1 commit intomasterfrom
feat/kinesis-over-bluetooth
Draft

feat(sdk): add kinesis over Bluetooth transport#134
andrewjaykeller wants to merge 1 commit intomasterfrom
feat/kinesis-over-bluetooth

Conversation

@andrewjaykeller
Copy link
Copy Markdown
Contributor

Summary

Route neurosity.kinesis(label) through the BLE transport whenever the active
streaming mode is Bluetooth, so offline / LAN-only clients get the same
classification stream as cloud-connected clients. The change mirrors the
dual-transport pattern used by focus, calm, and accelerometer — no
refactoring of the transport-switching helper was needed.

Design choice

  • BluetoothClient gains a shared _kinesis$ multicast on the
    kinesis BLE characteristic and a public kinesis(label?) method that
    applies cloud-equivalent label filtering client-side.
  • Neurosity.kinesis() now calls _withStreamingModeObservable({ wifi, bluetooth }) instead of hard-coding the cloud path. When activeMode is
    BLUETOOTH, the stream comes straight off the BLE characteristic with no
    cloud roundtrip.
  • Filtering is done client-side (matching how the cloud path accepts a single
    label), which keeps the firmware payload simple: { metric, label, probability, timestamp } per classification event.
  • No transport-layer refactors; no new public configuration surface.

Unknowns / needs firmware + IPK verification

The client routing is in place, but @neurosity/ipk@2.13.0 does not yet
ship a kinesis entry in BLUETOOTH_CHARACTERISTICS. Until the firmware
exposes the characteristic and the IPK registers its UUID:

  • WebBluetoothTransport.characteristicsByName["kinesis"] will be undefined
    at runtime, so the subscription stays idle (no events). This is the same
    graceful-no-op behaviour every other feature had before its firmware shipped.
  • No SDK changes are required once the IPK upgrade lands — the subscription
    will start emitting automatically.

Follow-ups (not in this PR):

  • Firmware: implement the kinesis BLE characteristic (notify) that
    emits the same JSON events the cloud emits.
  • @neurosity/ipk: add a kinesis UUID to BLUETOOTH_CHARACTERISTICS.
  • Once both land, bump @neurosity/ipk in this repo to pick up the UUID.

Test plan

  • npm run build — succeeds
  • npm test — 18 suites / 138 tests passing (6 pre-existing skips)
  • npm run lint — no new warnings introduced
  • npm audit — no new vulnerabilities introduced (pre-existing
    follow-redirects + protobufjs advisories already on master)
  • Unit test covers BluetoothClient.kinesis() subscribing to the
    kinesis characteristic, filtering by label, and emitting all events
    when no label is provided
  • Unit test covers Neurosity.kinesis() selecting the BLE branch when
    activeMode === BLUETOOTH and propagating label filtering

Manual verification (requires firmware + IPK follow-ups above)

  • Connect a Crown over BLE with streaming mode
    BLUETOOTH_WITH_WIFI_FALLBACK, call neurosity.kinesis("leftHandPinch"),
    confirm events flow without WiFi.
  • Disconnect WiFi mid-stream, confirm the observable keeps emitting via
    BLE.

🤖 Generated with Claude Code

@netlify
Copy link
Copy Markdown

netlify Bot commented Apr 24, 2026

Deploy Preview for neurosity-sdk-js ready!

Name Link
🔨 Latest commit 8c20f8e
🔍 Latest deploy log https://app.netlify.com/projects/neurosity-sdk-js/deploys/69ebb0ec6fadee0008c542ea
😎 Deploy Preview https://deploy-preview-134--neurosity-sdk-js.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

Routes `neurosity.kinesis(label)` through the BLE transport whenever the
active streaming mode is Bluetooth, giving offline / LAN-only clients
feature parity with the cloud path.

- `BluetoothClient` now multicasts the `kinesis` characteristic and
  exposes `kinesis(label?)` with cloud-equivalent label filtering.
- `Neurosity.kinesis()` uses `_withStreamingModeObservable` so the BLE
  branch is taken when active, mirroring `focus`/`calm`/`accelerometer`.
- Adds unit coverage for the BLE path at both layers
  (`BluetoothClient.kinesis` + `Neurosity.kinesis`).

Note: `@neurosity/ipk@2.13.0` does not yet define a `kinesis` entry in
`BLUETOOTH_CHARACTERISTICS`, so the BLE payload will remain inert at
runtime until the firmware and IPK ship the characteristic UUID. The
SDK-side routing is ready and will start emitting as soon as the IPK
upgrade lands — no further SDK changes required.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@andrewjaykeller andrewjaykeller force-pushed the feat/kinesis-over-bluetooth branch from c34237b to 8c20f8e Compare April 24, 2026 18:05
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