Recommended Shape
For browser BLE integrations, the adapter should satisfy theBleDeviceLike
shape expected by @elata-biosciences/eeg-web-ble.
That means the device layer handles discovery, session setup, subscription, and
packet decoding, while BleTransport handles the app-facing transport surface.
Implementation Order
Implement discovery
Define the
requestDevice filters and any optional services required to find
the device cleanly in the browser picker.Prepare the session
Connect to GATT, resolve characteristics, and do any startup writes that are
required before streaming can begin.
Decode packets into EEG rows
Turn vendor packets into
number[][] where each row is one time step and
the row width matches numEegChannels.Emit stable metadata
Expose
samplingRate, eegNames, numEegChannels, and related device
metadata accurately.Minimal Adapter Skeleton
What the Adapter Must Own
| Responsibility | Adapter owns it? |
|---|---|
| Device discovery | yes |
| GATT connection and characteristic setup | yes |
| Packet decoding | yes |
| Accurate metadata | yes |
| App-facing transport lifecycle | usually through BleTransport |
| Normalized frame delivery to apps | through the shared transport contract |
Packet Decoding Rules
Keep the decoder boring and deterministic.| Rule | Why it matters |
|---|---|
| Reject malformed packets early | Prevents bad rows from reaching apps |
| Preserve channel order | Keeps downstream features and models consistent |
| Batch rows only when needed | Avoids hidden latency and timestamp confusion |
| Track packet counters when available | Helps detect drops or corruption |
| Separate EEG from aux logic cleanly | Makes debugging and testing easier |
Session Lifecycle Rules
Your adapter should make these transitions unsurprising:| Stage | Good behavior |
|---|---|
| Discover | only matching devices are shown |
| Connect | required services and characteristics resolve clearly |
| Start | stream begins once, without duplicate subscriptions |
| Stop | notifications stop cleanly |
| Release | the session can be started again later |
Reliability Notes
startStreaming() is the safest default for app consumers because it combines
connect and start. Your adapter should still make the underlying connect()
and start() steps reliable on their own.Related Docs
Next
Validate the integration
Turn the adapter into a reliable transport under real failure conditions.
Prepare the handoff
Package the integration with the docs and caveats other teams need.