@neurodevs/node-lsl 20.0.0 → 22.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -6
- package/build/__tests__/AbstractPackageTest.d.ts +2 -1
- package/build/__tests__/AbstractPackageTest.js +9 -7
- package/build/__tests__/AbstractPackageTest.js.map +1 -1
- package/build/__tests__/impl/{BleDeviceController.test.d.ts → BleGattController.test.d.ts} +3 -3
- package/build/__tests__/impl/{BleDeviceController.test.js → BleGattController.test.js} +65 -65
- package/build/__tests__/impl/BleGattController.test.js.map +1 -0
- package/build/__tests__/impl/BleObserverController.test.d.ts +12 -0
- package/build/__tests__/impl/BleObserverController.test.js +62 -0
- package/build/__tests__/impl/BleObserverController.test.js.map +1 -0
- package/build/__tests__/impl/{LslEventMarkerEmitter.test.d.ts → LslEventMarkerOutlet.test.d.ts} +3 -3
- package/build/__tests__/impl/{LslEventMarkerEmitter.test.js → LslEventMarkerOutlet.test.js} +35 -36
- package/build/__tests__/impl/LslEventMarkerOutlet.test.js.map +1 -0
- package/build/__tests__/impl/LslJsonOutlet.test.d.ts +14 -0
- package/build/__tests__/impl/LslJsonOutlet.test.js +118 -0
- package/build/__tests__/impl/LslJsonOutlet.test.js.map +1 -0
- package/build/__tests__/impl/LslStreamInfo.test.js +0 -1
- package/build/__tests__/impl/LslStreamInfo.test.js.map +1 -1
- package/build/__tests__/impl/LslStreamInlet.test.js +0 -1
- package/build/__tests__/impl/LslStreamInlet.test.js.map +1 -1
- package/build/__tests__/impl/LslStreamOutlet.test.js +0 -1
- package/build/__tests__/impl/LslStreamOutlet.test.js.map +1 -1
- package/build/__tests__/impl/LslWebSocketBridge.test.js +0 -1
- package/build/__tests__/impl/LslWebSocketBridge.test.js.map +1 -1
- package/build/__tests__/impl/UsbDeviceController.test.js.map +1 -1
- package/build/impl/{LslEventMarkerEmitter.d.ts → LslEventMarkerOutlet.d.ts} +6 -6
- package/build/impl/{LslEventMarkerEmitter.js → LslEventMarkerOutlet.js} +2 -2
- package/build/impl/LslEventMarkerOutlet.js.map +1 -0
- package/build/impl/LslJsonOutlet.d.ts +33 -0
- package/build/impl/LslJsonOutlet.js +44 -0
- package/build/impl/LslJsonOutlet.js.map +1 -0
- package/build/impl/LslStreamOutlet.d.ts +3 -4
- package/build/impl/controllers/{BleDeviceController.d.ts → BleGattController.d.ts} +10 -10
- package/build/impl/controllers/{BleDeviceController.js → BleGattController.js} +18 -18
- package/build/impl/controllers/BleGattController.js.map +1 -0
- package/build/impl/controllers/BleObserverController.d.ts +20 -0
- package/build/impl/controllers/BleObserverController.js +37 -0
- package/build/impl/controllers/BleObserverController.js.map +1 -0
- package/build/impl/controllers/UsbDeviceController.d.ts +9 -9
- package/build/impl/controllers/UsbDeviceController.js +7 -7
- package/build/impl/controllers/UsbDeviceController.js.map +1 -1
- package/build/index.d.ts +24 -16
- package/build/index.js +29 -19
- package/build/index.js.map +1 -1
- package/build/scripts/runEventMarkerOutlet.js +12 -0
- package/build/scripts/runEventMarkerOutlet.js.map +1 -0
- package/build/scripts/runMuse.js +2 -2
- package/build/scripts/runMuse.js.map +1 -1
- package/build/testDoubles/{BleController/FakeBleController.d.ts → BleGatt/FakeBleGatt.d.ts} +6 -6
- package/build/testDoubles/{BleController/FakeBleController.js → BleGatt/FakeBleGatt.js} +8 -8
- package/build/testDoubles/BleGatt/FakeBleGatt.js.map +1 -0
- package/build/testDoubles/{BleController/SpyBleController.d.ts → BleGatt/SpyBleGatt.d.ts} +4 -4
- package/build/testDoubles/{BleController/SpyBleController.js → BleGatt/SpyBleGatt.js} +3 -3
- package/build/testDoubles/BleGatt/SpyBleGatt.js.map +1 -0
- package/build/testDoubles/BleObserver/FakeBleObserver.d.ts +10 -0
- package/build/testDoubles/BleObserver/FakeBleObserver.js +20 -0
- package/build/testDoubles/BleObserver/FakeBleObserver.js.map +1 -0
- package/build/testDoubles/{LslEmitter/FakeLslEmitter.d.ts → EventMarkerOutlet/FakeEventMarkerOutlet.d.ts} +2 -2
- package/build/testDoubles/{LslEmitter/FakeLslEmitter.js → EventMarkerOutlet/FakeEventMarkerOutlet.js} +7 -7
- package/build/testDoubles/EventMarkerOutlet/FakeEventMarkerOutlet.js.map +1 -0
- package/build/testDoubles/{LslEmitter/SpyLslEmitter.d.ts → EventMarkerOutlet/SpyEventMarkerOutlet.d.ts} +3 -3
- package/build/testDoubles/EventMarkerOutlet/SpyEventMarkerOutlet.js +23 -0
- package/build/testDoubles/EventMarkerOutlet/SpyEventMarkerOutlet.js.map +1 -0
- package/build/testDoubles/{LslEmitter/ThrowingLslEmitter.d.ts → EventMarkerOutlet/ThrowingEventMarkerOutlet.d.ts} +2 -2
- package/build/testDoubles/{LslEmitter/ThrowingLslEmitter.js → EventMarkerOutlet/ThrowingEventMarkerOutlet.js} +2 -2
- package/build/testDoubles/EventMarkerOutlet/ThrowingEventMarkerOutlet.js.map +1 -0
- package/build/testDoubles/JsonOutlet/FakeJsonOutlet.d.ts +10 -0
- package/build/testDoubles/JsonOutlet/FakeJsonOutlet.js +20 -0
- package/build/testDoubles/JsonOutlet/FakeJsonOutlet.js.map +1 -0
- package/build/testDoubles/UsbDevice/FakeUsbDevice.d.ts +12 -0
- package/build/testDoubles/UsbDevice/FakeUsbDevice.js +25 -0
- package/build/testDoubles/UsbDevice/FakeUsbDevice.js.map +1 -0
- package/package.json +3 -3
- package/src/__tests__/AbstractPackageTest.ts +9 -7
- package/src/__tests__/impl/{BleDeviceController.test.ts → BleGattController.test.ts} +43 -43
- package/src/__tests__/impl/BleObserverController.test.ts +72 -0
- package/src/__tests__/impl/{LslEventMarkerEmitter.test.ts → LslEventMarkerOutlet.test.ts} +20 -19
- package/src/__tests__/impl/LslJsonOutlet.test.ts +135 -0
- package/src/__tests__/impl/LslStreamInfo.test.ts +0 -1
- package/src/__tests__/impl/LslStreamInlet.test.ts +0 -1
- package/src/__tests__/impl/LslStreamOutlet.test.ts +0 -1
- package/src/__tests__/impl/LslWebSocketBridge.test.ts +0 -1
- package/src/__tests__/impl/UsbDeviceController.test.ts +2 -2
- package/src/impl/{LslEventMarkerEmitter.ts → LslEventMarkerOutlet.ts} +8 -6
- package/src/impl/LslJsonOutlet.ts +87 -0
- package/src/impl/LslStreamOutlet.ts +7 -5
- package/src/impl/controllers/{BleDeviceController.ts → BleGattController.ts} +23 -28
- package/src/impl/controllers/BleObserverController.ts +62 -0
- package/src/impl/controllers/UsbDeviceController.ts +14 -16
- package/src/index.ts +40 -24
- package/src/scripts/{runLslEmitter.ts → runEventMarkerOutlet.ts} +5 -5
- package/src/scripts/runMuse.ts +2 -2
- package/src/testDoubles/{BleController/FakeBleController.ts → BleGatt/FakeBleGatt.ts} +14 -14
- package/src/testDoubles/{BleController/SpyBleController.ts → BleGatt/SpyBleGatt.ts} +5 -5
- package/src/testDoubles/BleObserver/FakeBleObserver.ts +28 -0
- package/src/testDoubles/{LslEmitter/FakeLslEmitter.ts → EventMarkerOutlet/FakeEventMarkerOutlet.ts} +8 -8
- package/src/testDoubles/{LslEmitter/SpyLslEmitter.ts → EventMarkerOutlet/SpyEventMarkerOutlet.ts} +7 -7
- package/src/testDoubles/{LslEmitter/ThrowingLslEmitter.ts → EventMarkerOutlet/ThrowingEventMarkerOutlet.ts} +3 -3
- package/src/testDoubles/JsonOutlet/FakeJsonOutlet.ts +25 -0
- package/src/testDoubles/UsbDevice/FakeUsbDevice.ts +34 -0
- package/build/__tests__/impl/BleDeviceController.test.js.map +0 -1
- package/build/__tests__/impl/LslEventMarkerEmitter.test.js.map +0 -1
- package/build/impl/LslEventMarkerEmitter.js.map +0 -1
- package/build/impl/controllers/BleDeviceController.js.map +0 -1
- package/build/scripts/runLslEmitter.js +0 -12
- package/build/scripts/runLslEmitter.js.map +0 -1
- package/build/testDoubles/BleController/FakeBleController.js.map +0 -1
- package/build/testDoubles/BleController/SpyBleController.js.map +0 -1
- package/build/testDoubles/LslEmitter/FakeLslEmitter.js.map +0 -1
- package/build/testDoubles/LslEmitter/SpyLslEmitter.js +0 -23
- package/build/testDoubles/LslEmitter/SpyLslEmitter.js.map +0 -1
- package/build/testDoubles/LslEmitter/ThrowingLslEmitter.js.map +0 -1
- package/build/testDoubles/UsbController/FakeUsbController.d.ts +0 -12
- package/build/testDoubles/UsbController/FakeUsbController.js +0 -25
- package/build/testDoubles/UsbController/FakeUsbController.js.map +0 -1
- package/src/testDoubles/UsbController/FakeUsbController.ts +0 -34
- /package/build/scripts/{runLslEmitter.d.ts → runEventMarkerOutlet.d.ts} +0 -0
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import LslStreamOutlet, { LslOutlet } from './LslStreamOutlet.js'
|
|
2
|
+
|
|
3
|
+
export default class LslJsonOutlet implements JsonOutlet {
|
|
4
|
+
public static Class?: JsonOutletConstructor
|
|
5
|
+
public static backupIdCounter = 0
|
|
6
|
+
|
|
7
|
+
private outlet: LslOutlet
|
|
8
|
+
private maxBytesPerSample?: number
|
|
9
|
+
|
|
10
|
+
protected constructor(outlet: LslOutlet, maxBytesPerSample?: number) {
|
|
11
|
+
this.outlet = outlet
|
|
12
|
+
this.maxBytesPerSample = maxBytesPerSample
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
public static async Create(options?: JsonOutletOptions) {
|
|
16
|
+
const outlet = await this.LslStreamOutlet(options)
|
|
17
|
+
return new (this.Class ?? this)(outlet, options?.maxBytesPerSample)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
public pushJson(data: Json) {
|
|
21
|
+
const json = JSON.stringify(data)
|
|
22
|
+
this.throwIfPayloadTooLarge(json)
|
|
23
|
+
this.outlet.pushSample([json])
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
private throwIfPayloadTooLarge(json: string) {
|
|
27
|
+
const totalBytes = Buffer.byteLength(json)
|
|
28
|
+
|
|
29
|
+
if (this.maxBytesPerSample && totalBytes > this.maxBytesPerSample) {
|
|
30
|
+
throw new Error(
|
|
31
|
+
`Payload of ${totalBytes} bytes exceeds maxBytesPerSample of ${this.maxBytesPerSample}!`
|
|
32
|
+
)
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
public destroy() {
|
|
37
|
+
this.outlet.destroy()
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
private static LslStreamOutlet(options?: JsonOutletOptions) {
|
|
41
|
+
this.backupIdCounter++
|
|
42
|
+
|
|
43
|
+
const { channelName, maxBytesPerSample: _, ...rest } = options ?? {}
|
|
44
|
+
|
|
45
|
+
return LslStreamOutlet.Create({
|
|
46
|
+
name: `JSON (json-${this.backupIdCounter})`,
|
|
47
|
+
type: 'JSON',
|
|
48
|
+
sourceId: `json-${this.backupIdCounter}`,
|
|
49
|
+
channelNames: [channelName ?? 'JSON'],
|
|
50
|
+
channelFormat: 'string',
|
|
51
|
+
sampleRateHz: 0,
|
|
52
|
+
chunkSize: 1,
|
|
53
|
+
...rest,
|
|
54
|
+
})
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export interface JsonOutlet {
|
|
59
|
+
pushJson(data: Json): void
|
|
60
|
+
destroy(): void
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export type Json = Record<string, unknown>
|
|
64
|
+
|
|
65
|
+
export type JsonOutletConstructor = new (
|
|
66
|
+
outlet: LslOutlet,
|
|
67
|
+
maxBytesPerSample?: number
|
|
68
|
+
) => JsonOutlet
|
|
69
|
+
|
|
70
|
+
export interface JsonOutletOptions {
|
|
71
|
+
name?: string
|
|
72
|
+
type?: string
|
|
73
|
+
sourceId?: string
|
|
74
|
+
channelName?: string
|
|
75
|
+
sampleRateHz?: number
|
|
76
|
+
chunkSize?: number
|
|
77
|
+
maxBufferedMs?: number
|
|
78
|
+
maxBytesPerSample?: number
|
|
79
|
+
manufacturer?: string
|
|
80
|
+
units?: string
|
|
81
|
+
waitAfterConstructionMs?: number
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export type JsonOutletConstructorOptions = Omit<
|
|
85
|
+
JsonOutletOptions,
|
|
86
|
+
'waitAfterConstructionMs'
|
|
87
|
+
>
|
|
@@ -180,11 +180,7 @@ export interface LslOutlet {
|
|
|
180
180
|
|
|
181
181
|
export type LslOutletConstructor = new (options: LslOutletOptions) => LslOutlet
|
|
182
182
|
|
|
183
|
-
export interface LslOutletOptions
|
|
184
|
-
waitAfterConstructionMs?: number
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
export interface LslOutletConstructorOptions {
|
|
183
|
+
export interface LslOutletOptions {
|
|
188
184
|
name: string
|
|
189
185
|
type: string
|
|
190
186
|
sourceId: string
|
|
@@ -195,4 +191,10 @@ export interface LslOutletConstructorOptions {
|
|
|
195
191
|
maxBufferedMs?: number
|
|
196
192
|
manufacturer?: string
|
|
197
193
|
units?: string
|
|
194
|
+
waitAfterConstructionMs?: number
|
|
198
195
|
}
|
|
196
|
+
|
|
197
|
+
export type LslOutletConstructorOptions = Omit<
|
|
198
|
+
LslOutletOptions,
|
|
199
|
+
'waitAfterConstructionMs'
|
|
200
|
+
>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { LibndxAdapter, Libndx, NativePeripheral } from '@neurodevs/ndx-native'
|
|
2
2
|
|
|
3
|
-
export default class
|
|
4
|
-
public static Class?:
|
|
3
|
+
export default class BleGattController implements BleGatt {
|
|
4
|
+
public static Class?: BleGattConstructor
|
|
5
5
|
public static setTimeout = setTimeout
|
|
6
6
|
public static waitAfterMs = 1000
|
|
7
7
|
|
|
@@ -28,7 +28,7 @@ export default class BleDeviceController implements BleController {
|
|
|
28
28
|
private deviceName?: string
|
|
29
29
|
private onConnected?: (peripheral: NativePeripheral) => void
|
|
30
30
|
|
|
31
|
-
protected constructor(options:
|
|
31
|
+
protected constructor(options: BleGattOptions) {
|
|
32
32
|
const {
|
|
33
33
|
deviceUuid,
|
|
34
34
|
deviceNamePrefix,
|
|
@@ -44,7 +44,7 @@ export default class BleDeviceController implements BleController {
|
|
|
44
44
|
this.rssiIntervalMs = rssiIntervalMs
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
public static Create(options:
|
|
47
|
+
public static Create(options: BleGattOptions) {
|
|
48
48
|
return new (this.Class ?? this)(options)
|
|
49
49
|
}
|
|
50
50
|
|
|
@@ -53,13 +53,13 @@ export default class BleDeviceController implements BleController {
|
|
|
53
53
|
await this.discoverUuid()
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
this.
|
|
57
|
-
this.
|
|
56
|
+
this.createBleGattBackend()
|
|
57
|
+
this.startBleGattBackend()
|
|
58
58
|
|
|
59
59
|
await this.waitForOnConnected()
|
|
60
60
|
await this.waitToDiscoverServices()
|
|
61
61
|
|
|
62
|
-
this.
|
|
62
|
+
this.startBleGattRssiPolling()
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
private async discoverUuid() {
|
|
@@ -81,15 +81,15 @@ export default class BleDeviceController implements BleController {
|
|
|
81
81
|
if (this.deviceUuid) {
|
|
82
82
|
resolve()
|
|
83
83
|
} else {
|
|
84
|
-
|
|
84
|
+
BleGattController.setTimeout(checkDiscovered, 100)
|
|
85
85
|
}
|
|
86
86
|
}
|
|
87
87
|
checkDiscovered()
|
|
88
88
|
})
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
-
private
|
|
92
|
-
const { status, error } = this.ndx.
|
|
91
|
+
private createBleGattBackend() {
|
|
92
|
+
const { status, error } = this.ndx.createBleGattBackend({
|
|
93
93
|
deviceUuid: this.uuid,
|
|
94
94
|
})
|
|
95
95
|
|
|
@@ -102,9 +102,9 @@ export default class BleDeviceController implements BleController {
|
|
|
102
102
|
}
|
|
103
103
|
}
|
|
104
104
|
|
|
105
|
-
private
|
|
105
|
+
private startBleGattRssiPolling() {
|
|
106
106
|
if (this.rssiIntervalMs) {
|
|
107
|
-
this.ndx.
|
|
107
|
+
this.ndx.startBleGattRssiPolling({
|
|
108
108
|
deviceUuid: this.uuid,
|
|
109
109
|
intervalMs: this.rssiIntervalMs,
|
|
110
110
|
onRssi: (rssi: number) => {
|
|
@@ -114,8 +114,8 @@ export default class BleDeviceController implements BleController {
|
|
|
114
114
|
}
|
|
115
115
|
}
|
|
116
116
|
|
|
117
|
-
private
|
|
118
|
-
const { status, error } = this.ndx.
|
|
117
|
+
private startBleGattBackend() {
|
|
118
|
+
const { status, error } = this.ndx.startBleGattBackend({
|
|
119
119
|
deviceUuid: this.uuid,
|
|
120
120
|
onConnected: (peripheral: NativePeripheral) => {
|
|
121
121
|
const { name } = peripheral
|
|
@@ -136,7 +136,7 @@ export default class BleDeviceController implements BleController {
|
|
|
136
136
|
if (this.connected) {
|
|
137
137
|
resolve()
|
|
138
138
|
} else {
|
|
139
|
-
|
|
139
|
+
BleGattController.setTimeout(checkConnected, 100)
|
|
140
140
|
}
|
|
141
141
|
}
|
|
142
142
|
checkConnected()
|
|
@@ -145,10 +145,7 @@ export default class BleDeviceController implements BleController {
|
|
|
145
145
|
|
|
146
146
|
private async waitToDiscoverServices() {
|
|
147
147
|
await new Promise<void>((resolve) =>
|
|
148
|
-
|
|
149
|
-
resolve,
|
|
150
|
-
BleDeviceController.waitAfterMs
|
|
151
|
-
)
|
|
148
|
+
BleGattController.setTimeout(resolve, BleGattController.waitAfterMs)
|
|
152
149
|
)
|
|
153
150
|
}
|
|
154
151
|
|
|
@@ -156,7 +153,7 @@ export default class BleDeviceController implements BleController {
|
|
|
156
153
|
charUuid: CharacteristicUuid,
|
|
157
154
|
value: string
|
|
158
155
|
) {
|
|
159
|
-
const { status, error } = this.ndx.
|
|
156
|
+
const { status, error } = this.ndx.writeBleGattChar({
|
|
160
157
|
deviceUuid: this.uuid,
|
|
161
158
|
charUuid,
|
|
162
159
|
value,
|
|
@@ -168,7 +165,7 @@ export default class BleDeviceController implements BleController {
|
|
|
168
165
|
public async subscribeCharacteristics(
|
|
169
166
|
charCallbacks: CharacteristicCallbacks
|
|
170
167
|
) {
|
|
171
|
-
const { status, error } = this.ndx.
|
|
168
|
+
const { status, error } = this.ndx.registerBleGattCharCallbacks({
|
|
172
169
|
deviceUuid: this.uuid,
|
|
173
170
|
charCallbacks,
|
|
174
171
|
})
|
|
@@ -179,7 +176,7 @@ export default class BleDeviceController implements BleController {
|
|
|
179
176
|
}
|
|
180
177
|
|
|
181
178
|
public async disconnect() {
|
|
182
|
-
const { status, error } = this.ndx.
|
|
179
|
+
const { status, error } = this.ndx.stopBleGattBackend({
|
|
183
180
|
deviceUuid: this.uuid,
|
|
184
181
|
})
|
|
185
182
|
|
|
@@ -196,11 +193,11 @@ export default class BleDeviceController implements BleController {
|
|
|
196
193
|
}
|
|
197
194
|
|
|
198
195
|
private get ndx() {
|
|
199
|
-
return
|
|
196
|
+
return BleGattController.ndx
|
|
200
197
|
}
|
|
201
198
|
}
|
|
202
199
|
|
|
203
|
-
export interface
|
|
200
|
+
export interface BleGatt {
|
|
204
201
|
uuid: string
|
|
205
202
|
name: string
|
|
206
203
|
|
|
@@ -218,7 +215,7 @@ export interface BleController {
|
|
|
218
215
|
disconnect(): Promise<void>
|
|
219
216
|
}
|
|
220
217
|
|
|
221
|
-
export type
|
|
218
|
+
export type BleGattOptions = {
|
|
222
219
|
charCallbacks: CharacteristicCallbacks
|
|
223
220
|
onConnected?: (peripheral: NativePeripheral) => void
|
|
224
221
|
rssiIntervalMs?: number
|
|
@@ -227,9 +224,7 @@ export type BleControllerOptions = {
|
|
|
227
224
|
| { deviceUuid?: string; deviceNamePrefix: string }
|
|
228
225
|
)
|
|
229
226
|
|
|
230
|
-
export type
|
|
231
|
-
options: BleControllerOptions
|
|
232
|
-
) => BleController
|
|
227
|
+
export type BleGattConstructor = new (options: BleGattOptions) => BleGatt
|
|
233
228
|
|
|
234
229
|
export type CharacteristicCallbacks = {
|
|
235
230
|
charUuid: string
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { LibndxAdapter } from '@neurodevs/ndx-native'
|
|
2
|
+
|
|
3
|
+
export default class BleObserverController implements BleObserver {
|
|
4
|
+
public static Class?: BleObserverConstructor
|
|
5
|
+
|
|
6
|
+
private readonly deviceUuid: string
|
|
7
|
+
private readonly ndx = LibndxAdapter.getInstance()
|
|
8
|
+
|
|
9
|
+
protected constructor(options: BleObserverOptions) {
|
|
10
|
+
const { deviceUuid } = options
|
|
11
|
+
|
|
12
|
+
this.deviceUuid = deviceUuid ?? ''
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
public static Create(options: BleObserverOptions) {
|
|
16
|
+
return new (this.Class ?? this)(options)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
public async startObserving() {
|
|
20
|
+
this.createBleObserverBackend()
|
|
21
|
+
this.startBleObserverBackend()
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
private createBleObserverBackend() {
|
|
25
|
+
this.ndx.createBleObserverBackend({
|
|
26
|
+
deviceUuid: this.deviceUuid,
|
|
27
|
+
})
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
private startBleObserverBackend() {
|
|
31
|
+
this.ndx.startBleObserverBackend({
|
|
32
|
+
deviceUuid: this.deviceUuid,
|
|
33
|
+
onAdvertisement: (
|
|
34
|
+
_data: Buffer,
|
|
35
|
+
_length: number,
|
|
36
|
+
_timestampSec: number
|
|
37
|
+
) => {},
|
|
38
|
+
})
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
public async stopObserving() {
|
|
42
|
+
this.stopBleObserverBackend()
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
private stopBleObserverBackend() {
|
|
46
|
+
this.ndx.stopBleObserverBackend({
|
|
47
|
+
deviceUuid: this.deviceUuid,
|
|
48
|
+
})
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
export interface BleObserver {
|
|
52
|
+
startObserving(): Promise<void>
|
|
53
|
+
stopObserving(): Promise<void>
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export type BleObserverConstructor = new (
|
|
57
|
+
options: BleObserverOptions
|
|
58
|
+
) => BleObserver
|
|
59
|
+
|
|
60
|
+
export type BleObserverOptions = {
|
|
61
|
+
deviceUuid: string
|
|
62
|
+
}
|
|
@@ -1,65 +1,63 @@
|
|
|
1
1
|
import { LibndxAdapter } from '@neurodevs/ndx-native'
|
|
2
2
|
|
|
3
|
-
export default class UsbDeviceController implements
|
|
4
|
-
public static Class?:
|
|
3
|
+
export default class UsbDeviceController implements UsbDevice {
|
|
4
|
+
public static Class?: UsbDeviceConstructor
|
|
5
5
|
|
|
6
6
|
private onData: (data: Buffer, length: number, timestampSec: number) => void
|
|
7
7
|
private serialNumber: string
|
|
8
8
|
|
|
9
9
|
private ndx = LibndxAdapter.getInstance()
|
|
10
10
|
|
|
11
|
-
protected constructor(options:
|
|
11
|
+
protected constructor(options: UsbDeviceOptions) {
|
|
12
12
|
const { onData, serialNumber } = options ?? {}
|
|
13
13
|
|
|
14
14
|
this.onData = onData
|
|
15
15
|
this.serialNumber = serialNumber ?? ''
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
public static Create(options:
|
|
18
|
+
public static Create(options: UsbDeviceOptions) {
|
|
19
19
|
return new (this.Class ?? this)(options)
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
public async connect() {
|
|
23
|
-
this.ndx.createUsbBackend(this.
|
|
24
|
-
this.ndx.startUsbBackend(this.
|
|
23
|
+
this.ndx.createUsbBackend(this.usbDeviceOptions)
|
|
24
|
+
this.ndx.startUsbBackend(this.startUsbDeviceOptions)
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
private get
|
|
27
|
+
private get usbDeviceOptions() {
|
|
28
28
|
return {
|
|
29
29
|
serialNumber: this.serialNumber,
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
private get
|
|
33
|
+
private get startUsbDeviceOptions() {
|
|
34
34
|
return {
|
|
35
|
-
...this.
|
|
35
|
+
...this.usbDeviceOptions,
|
|
36
36
|
onData: this.onData,
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
public async writeUsb(value: string) {
|
|
41
41
|
this.ndx.writeUsbBackend({
|
|
42
|
-
...this.
|
|
42
|
+
...this.usbDeviceOptions,
|
|
43
43
|
value,
|
|
44
44
|
})
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
public async disconnect() {
|
|
48
|
-
this.ndx.stopUsbBackend(this.
|
|
48
|
+
this.ndx.stopUsbBackend(this.usbDeviceOptions)
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
export interface
|
|
52
|
+
export interface UsbDevice {
|
|
53
53
|
connect(): Promise<void>
|
|
54
54
|
writeUsb(value: string): Promise<void>
|
|
55
55
|
disconnect(): Promise<void>
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
export interface
|
|
58
|
+
export interface UsbDeviceOptions {
|
|
59
59
|
onData: (data: Buffer, length: number, timestampSec: number) => void
|
|
60
60
|
serialNumber?: string
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
-
export type
|
|
64
|
-
options?: UsbControllerOptions
|
|
65
|
-
) => UsbController
|
|
63
|
+
export type UsbDeviceConstructor = new (options?: UsbDeviceOptions) => UsbDevice
|
package/src/index.ts
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
// BleObserver
|
|
2
|
+
|
|
3
|
+
export { default as BleObserverController } from './impl/controllers/BleObserverController.js'
|
|
4
|
+
export * from './impl/controllers/BleObserverController.js'
|
|
5
|
+
|
|
6
|
+
export { default as FakeBleObserver } from './testDoubles/BleObserver/FakeBleObserver.js'
|
|
7
|
+
export * from './testDoubles/BleObserver/FakeBleObserver.js'
|
|
8
|
+
|
|
1
9
|
// ClockRegressor
|
|
2
10
|
|
|
3
11
|
export { default as WindowedClockRegressor } from './impl/clocks/WindowedClockRegressor.js'
|
|
@@ -6,16 +14,38 @@ export * from './impl/clocks/WindowedClockRegressor.js'
|
|
|
6
14
|
export { default as FakeClockRegressor } from './testDoubles/ClockRegressor/FakeClockRegressor.js'
|
|
7
15
|
export * from './testDoubles/ClockRegressor/FakeClockRegressor.js'
|
|
8
16
|
|
|
9
|
-
//
|
|
17
|
+
// BleGatt
|
|
18
|
+
|
|
19
|
+
export { default as BleGattController } from './impl/controllers/BleGattController.js'
|
|
20
|
+
export * from './impl/controllers/BleGattController.js'
|
|
21
|
+
|
|
22
|
+
export { default as SpyBleGatt } from './testDoubles/BleGatt/SpyBleGatt.js'
|
|
23
|
+
export * from './testDoubles/BleGatt/SpyBleGatt.js'
|
|
24
|
+
|
|
25
|
+
export { default as FakeBleGatt } from './testDoubles/BleGatt/FakeBleGatt.js'
|
|
26
|
+
export * from './testDoubles/BleGatt/FakeBleGatt.js'
|
|
27
|
+
|
|
28
|
+
// EventMarkerOutlet
|
|
29
|
+
|
|
30
|
+
export { default as LslEventMarkerOutlet } from './impl/LslEventMarkerOutlet.js'
|
|
31
|
+
export * from './impl/LslEventMarkerOutlet.js'
|
|
10
32
|
|
|
11
|
-
export { default as
|
|
12
|
-
export * from './
|
|
33
|
+
export { default as SpyEventMarkerOutlet } from './testDoubles/EventMarkerOutlet/SpyEventMarkerOutlet.js'
|
|
34
|
+
export * from './testDoubles/EventMarkerOutlet/SpyEventMarkerOutlet.js'
|
|
13
35
|
|
|
14
|
-
export { default as
|
|
15
|
-
export * from './testDoubles/
|
|
36
|
+
export { default as FakeEventMarkerOutlet } from './testDoubles/EventMarkerOutlet/FakeEventMarkerOutlet.js'
|
|
37
|
+
export * from './testDoubles/EventMarkerOutlet/FakeEventMarkerOutlet.js'
|
|
16
38
|
|
|
17
|
-
export { default as
|
|
18
|
-
export * from './testDoubles/
|
|
39
|
+
export { default as ThrowingEventMarkerOutlet } from './testDoubles/EventMarkerOutlet/ThrowingEventMarkerOutlet.js'
|
|
40
|
+
export * from './testDoubles/EventMarkerOutlet/ThrowingEventMarkerOutlet.js'
|
|
41
|
+
|
|
42
|
+
// JsonOutlet
|
|
43
|
+
|
|
44
|
+
export { default as LslJsonOutlet } from './impl/LslJsonOutlet.js'
|
|
45
|
+
export * from './impl/LslJsonOutlet.js'
|
|
46
|
+
|
|
47
|
+
export { default as FakeJsonOutlet } from './testDoubles/JsonOutlet/FakeJsonOutlet.js'
|
|
48
|
+
export * from './testDoubles/JsonOutlet/FakeJsonOutlet.js'
|
|
19
49
|
|
|
20
50
|
// LslWsBridge
|
|
21
51
|
|
|
@@ -28,20 +58,6 @@ export * from './testDoubles/LslWsBridge/SpyLslWsBridge.js'
|
|
|
28
58
|
export { default as FakeLslWsBridge } from './testDoubles/LslWsBridge/FakeLslWsBridge.js'
|
|
29
59
|
export * from './testDoubles/LslWsBridge/FakeLslWsBridge.js'
|
|
30
60
|
|
|
31
|
-
// LslEmitter
|
|
32
|
-
|
|
33
|
-
export { default as LslEventMarkerEmitter } from './impl/LslEventMarkerEmitter.js'
|
|
34
|
-
export * from './impl/LslEventMarkerEmitter.js'
|
|
35
|
-
|
|
36
|
-
export { default as SpyLslEmitter } from './testDoubles/LslEmitter/SpyLslEmitter.js'
|
|
37
|
-
export * from './testDoubles/LslEmitter/SpyLslEmitter.js'
|
|
38
|
-
|
|
39
|
-
export { default as FakeLslEmitter } from './testDoubles/LslEmitter/FakeLslEmitter.js'
|
|
40
|
-
export * from './testDoubles/LslEmitter/FakeLslEmitter.js'
|
|
41
|
-
|
|
42
|
-
export { default as ThrowingLslEmitter } from './testDoubles/LslEmitter/ThrowingLslEmitter.js'
|
|
43
|
-
export * from './testDoubles/LslEmitter/ThrowingLslEmitter.js'
|
|
44
|
-
|
|
45
61
|
// LslInfo
|
|
46
62
|
|
|
47
63
|
export { default as LslStreamInfo } from './impl/LslStreamInfo.js'
|
|
@@ -74,13 +90,13 @@ export * from './testDoubles/LslOutlet/FakeLslOutlet.js'
|
|
|
74
90
|
|
|
75
91
|
export { default as generateRandomOutletOptions } from './testDoubles/generateRandomOutletOptions.js'
|
|
76
92
|
|
|
77
|
-
//
|
|
93
|
+
// UsbDevice
|
|
78
94
|
|
|
79
95
|
export { default as UsbDeviceController } from './impl/controllers/UsbDeviceController.js'
|
|
80
96
|
export * from './impl/controllers/UsbDeviceController.js'
|
|
81
97
|
|
|
82
|
-
export { default as
|
|
83
|
-
export * from './testDoubles/
|
|
98
|
+
export { default as FakeUsbDevice } from './testDoubles/UsbDevice/FakeUsbDevice.js'
|
|
99
|
+
export * from './testDoubles/UsbDevice/FakeUsbDevice.js'
|
|
84
100
|
|
|
85
101
|
// WebSockets
|
|
86
102
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import
|
|
1
|
+
import LslEventMarkerOutlet from '../impl/LslEventMarkerOutlet.js'
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const outlet = await LslEventMarkerOutlet.Create()
|
|
4
4
|
|
|
5
5
|
const markers = [
|
|
6
6
|
{ name: 'phase-1-begin', waitAfterMs: 100 },
|
|
@@ -8,9 +8,9 @@ const markers = [
|
|
|
8
8
|
{ name: 'never-reached-marker', waitAfterMs: 100 },
|
|
9
9
|
]
|
|
10
10
|
|
|
11
|
-
void
|
|
11
|
+
void outlet.emitMany(markers)
|
|
12
12
|
|
|
13
13
|
await new Promise((resolve) => setTimeout(resolve, 250))
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
outlet.interrupt()
|
|
16
|
+
outlet.destroy()
|
package/src/scripts/runMuse.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import koffi from 'koffi'
|
|
2
2
|
|
|
3
|
-
import
|
|
3
|
+
import BleGattController from '../impl/controllers/BleGattController.js'
|
|
4
4
|
|
|
5
5
|
const MUSE_CHARACTERISTIC_UUIDS: Record<string, string> = {
|
|
6
6
|
CONTROL: '273E0001-4C4D-454D-96BE-F03BAC821358',
|
|
@@ -32,7 +32,7 @@ const charCallbacks = Object.entries(MUSE_CHARACTERISTIC_UUIDS).map(
|
|
|
32
32
|
}
|
|
33
33
|
)
|
|
34
34
|
|
|
35
|
-
const muse =
|
|
35
|
+
const muse = BleGattController.Create({
|
|
36
36
|
deviceUuid: 'CA6A61B7-B7A8-AF24-3C9E-04A6A5012554',
|
|
37
37
|
charCallbacks,
|
|
38
38
|
rssiIntervalMs: 1000,
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import generateId from '@neurodevs/generate-id'
|
|
2
2
|
import {
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
BleGatt,
|
|
4
|
+
BleGattOptions,
|
|
5
5
|
CharacteristicCallbacks,
|
|
6
|
-
} from '../../impl/controllers/
|
|
6
|
+
} from '../../impl/controllers/BleGattController.js'
|
|
7
7
|
|
|
8
|
-
export default class
|
|
9
|
-
public static callsToConstructor: (
|
|
8
|
+
export default class FakeBleGatt implements BleGatt {
|
|
9
|
+
public static callsToConstructor: (BleGattOptions | undefined)[] = []
|
|
10
10
|
|
|
11
11
|
public static numCallsToConnect = 0
|
|
12
12
|
|
|
@@ -26,24 +26,24 @@ export default class FakeBleController implements BleController {
|
|
|
26
26
|
private _uuid: string
|
|
27
27
|
private _name: string
|
|
28
28
|
|
|
29
|
-
public constructor(options?:
|
|
29
|
+
public constructor(options?: BleGattOptions) {
|
|
30
30
|
const { deviceUuid } = options ?? {}
|
|
31
31
|
|
|
32
32
|
this._uuid = deviceUuid ?? generateId()
|
|
33
|
-
this._name =
|
|
33
|
+
this._name = FakeBleGatt.fakeName
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
FakeBleGatt.callsToConstructor.push(options)
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
public async connect() {
|
|
39
|
-
|
|
39
|
+
FakeBleGatt.numCallsToConnect++
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
public async writeCharacteristic(
|
|
43
43
|
characteristicUuid: string,
|
|
44
44
|
value: string
|
|
45
45
|
) {
|
|
46
|
-
|
|
46
|
+
FakeBleGatt.callsToWriteCharacteristic.push({
|
|
47
47
|
characteristicUuid,
|
|
48
48
|
value,
|
|
49
49
|
})
|
|
@@ -52,11 +52,11 @@ export default class FakeBleController implements BleController {
|
|
|
52
52
|
public async subscribeCharacteristics(
|
|
53
53
|
charCallbacks: CharacteristicCallbacks
|
|
54
54
|
) {
|
|
55
|
-
|
|
55
|
+
FakeBleGatt.callsToSubscribeCharacteristics.push(charCallbacks)
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
public async disconnect() {
|
|
59
|
-
|
|
59
|
+
FakeBleGatt.numCallsToDisconnect++
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
public get uuid() {
|
|
@@ -76,6 +76,6 @@ export default class FakeBleController implements BleController {
|
|
|
76
76
|
}
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
-
export interface
|
|
80
|
-
options:
|
|
79
|
+
export interface CallToBleGattConstructor {
|
|
80
|
+
options: BleGattOptions
|
|
81
81
|
}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
} from '../../impl/controllers/
|
|
1
|
+
import BleGattController, {
|
|
2
|
+
BleGattOptions,
|
|
3
|
+
} from '../../impl/controllers/BleGattController.js'
|
|
4
4
|
|
|
5
|
-
export default class
|
|
5
|
+
export default class SpyBleGatt extends BleGattController {
|
|
6
6
|
public infoLogs: string[] = []
|
|
7
7
|
public warnLogs: string[] = []
|
|
8
8
|
public errorLogs: string[] = []
|
|
9
9
|
|
|
10
|
-
public constructor(options:
|
|
10
|
+
public constructor(options: BleGattOptions) {
|
|
11
11
|
super(options)
|
|
12
12
|
}
|
|
13
13
|
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BleObserver,
|
|
3
|
+
BleObserverOptions,
|
|
4
|
+
} from '../../impl/controllers/BleObserverController.js'
|
|
5
|
+
|
|
6
|
+
export default class FakeBleObserver implements BleObserver {
|
|
7
|
+
public static callsToConstructor: BleObserverOptions[] = []
|
|
8
|
+
public static numCallsToStartObserving = 0
|
|
9
|
+
public static numCallsToStopObserving = 0
|
|
10
|
+
|
|
11
|
+
public constructor(options: BleObserverOptions) {
|
|
12
|
+
FakeBleObserver.callsToConstructor.push(options)
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
public async startObserving() {
|
|
16
|
+
FakeBleObserver.numCallsToStartObserving++
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
public async stopObserving() {
|
|
20
|
+
FakeBleObserver.numCallsToStopObserving++
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
public static resetTestDouble() {
|
|
24
|
+
FakeBleObserver.callsToConstructor = []
|
|
25
|
+
FakeBleObserver.numCallsToStartObserving = 0
|
|
26
|
+
FakeBleObserver.numCallsToStopObserving = 0
|
|
27
|
+
}
|
|
28
|
+
}
|