@neurodevs/node-lsl 23.1.0 → 23.1.2

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.
Files changed (38) hide show
  1. package/build/__tests__/AbstractPackageTest.js +0 -1
  2. package/build/__tests__/AbstractPackageTest.js.map +1 -1
  3. package/build/__tests__/impl/BleGattController.test.d.ts +4 -0
  4. package/build/__tests__/impl/BleGattController.test.js +27 -5
  5. package/build/__tests__/impl/BleGattController.test.js.map +1 -1
  6. package/build/__tests__/impl/LslStreamInlet.test.d.ts +4 -5
  7. package/build/__tests__/impl/LslStreamInlet.test.js +37 -58
  8. package/build/__tests__/impl/LslStreamInlet.test.js.map +1 -1
  9. package/build/impl/LslStreamInfo.d.ts +3 -3
  10. package/build/impl/LslStreamInfo.js.map +1 -1
  11. package/build/impl/LslStreamInlet.d.ts +9 -39
  12. package/build/impl/LslStreamInlet.js +23 -151
  13. package/build/impl/LslStreamInlet.js.map +1 -1
  14. package/build/impl/LslStreamOutlet.d.ts +3 -3
  15. package/build/impl/LslStreamOutlet.js.map +1 -1
  16. package/build/impl/clocks/WindowedClockRegressor.d.ts +2 -2
  17. package/build/impl/clocks/WindowedClockRegressor.js.map +1 -1
  18. package/build/impl/controllers/BleGattController.d.ts +21 -12
  19. package/build/impl/controllers/BleGattController.js +22 -30
  20. package/build/impl/controllers/BleGattController.js.map +1 -1
  21. package/build/testDoubles/BleGatt/FakeBleGatt.d.ts +3 -2
  22. package/build/testDoubles/BleGatt/FakeBleGatt.js +6 -4
  23. package/build/testDoubles/BleGatt/FakeBleGatt.js.map +1 -1
  24. package/build/testDoubles/BleGatt/SpyBleGatt.d.ts +1 -1
  25. package/build/testDoubles/BleGatt/SpyBleGatt.js +2 -2
  26. package/build/testDoubles/BleGatt/SpyBleGatt.js.map +1 -1
  27. package/build/testDoubles/LslOutlet/FakeLslOutlet.d.ts +1 -1
  28. package/package.json +3 -4
  29. package/src/__tests__/AbstractPackageTest.ts +0 -2
  30. package/src/__tests__/impl/BleGattController.test.ts +48 -6
  31. package/src/__tests__/impl/LslStreamInlet.test.ts +45 -86
  32. package/src/impl/LslStreamInfo.ts +3 -3
  33. package/src/impl/LslStreamInlet.ts +38 -218
  34. package/src/impl/LslStreamOutlet.ts +3 -3
  35. package/src/impl/clocks/WindowedClockRegressor.ts +1 -1
  36. package/src/impl/controllers/BleGattController.ts +35 -37
  37. package/src/testDoubles/BleGatt/FakeBleGatt.ts +9 -6
  38. package/src/testDoubles/BleGatt/SpyBleGatt.ts +2 -2
@@ -1,24 +1,9 @@
1
- import {
2
- handleLslError,
3
- InfoHandle,
4
- InletHandle,
5
- LiblslAdapter,
6
- } from '@neurodevs/ndx-native'
7
- import {
8
- JsExternal,
9
- unwrapPointer,
10
- createPointer,
11
- DataType,
12
- freePointer,
13
- PointerType,
14
- } from 'ffi-rs'
1
+ import { InfoHandle, InletHandle, LiblslAdapter } from '@neurodevs/ndx-native'
15
2
 
16
3
  export default class LslStreamInlet implements LslInlet {
17
4
  public static Class?: LslInletConstructor
18
5
  public static waitAfterOpenStreamMs = 100
19
6
  public static lsl = LiblslAdapter.getInstance()
20
- public static handleLslError = handleLslError
21
- public static freePointer = freePointer
22
7
 
23
8
  public isRunning = false
24
9
 
@@ -32,37 +17,12 @@ export default class LslStreamInlet implements LslInlet {
32
17
  private onData: OnDataCallback
33
18
 
34
19
  private infoHandle!: InfoHandle
35
- private inletHandle!: InletHandle
36
- private channelCount!: number
37
-
38
- private pullMethod!: () => {
39
- samples: number[] | undefined
40
- timestamps: number[] | undefined
41
- }
42
-
43
- private sampleBuffer!: Buffer<ArrayBuffer>
44
- private sampleBufferRef!: JsExternal[]
45
- private sampleBufferPtr!: JsExternal
46
-
47
- private timestampBuffer!: Buffer<ArrayBuffer>
48
- private timestampBufferRef!: JsExternal[]
49
- private timestampBufferPtr!: JsExternal
50
-
51
- private pullErrorBuffer!: Buffer<ArrayBuffer>
52
- private pullErrorBufferRef!: JsExternal[]
53
- private pullErrorBufferPtr!: JsExternal
54
-
55
- private openStreamErrorBuffer!: Buffer<ArrayBuffer>
56
- private openStreamErrorBufferRef!: JsExternal[]
57
- private openStreamErrorBufferPtr!: JsExternal
20
+ private inletHandle?: InletHandle
21
+ private pullMethod: () => PulledData | undefined
58
22
 
59
23
  private readonly sixMinutesInMs = 360 * 1000
60
24
  private readonly aboutOneYearInMs = 32000000 * 1000
61
25
 
62
- private readonly bytesPerFloat = 4
63
- private readonly bytesPerDouble = 8
64
- private readonly bytesPerI32 = 4
65
-
66
26
  protected constructor(options: LslInletOptions, onData: OnDataCallback) {
67
27
  const {
68
28
  sourceId,
@@ -82,6 +42,10 @@ export default class LslStreamInlet implements LslInlet {
82
42
  this.waitBetweenPullsMs = waitBetweenPullsMs ?? 1
83
43
  this.flushInletOnStop = flushInletOnStop ?? true
84
44
  this.onData = onData
45
+
46
+ this.pullMethod = (
47
+ chunkSize === 1 ? this.pullSample : this.pullChunk
48
+ ).bind(this)
85
49
  }
86
50
 
87
51
  public static async Create(
@@ -106,10 +70,6 @@ export default class LslStreamInlet implements LslInlet {
106
70
  private async createInlet() {
107
71
  this.infoHandle = this.resolveInfoHandle()
108
72
  this.inletHandle = this.doCreateInlet()
109
- this.channelCount = this.getChannelCount()
110
-
111
- this.allocateWritableBuffers()
112
- this.setPullMethod()
113
73
 
114
74
  this.openStream()
115
75
  }
@@ -146,144 +106,14 @@ export default class LslStreamInlet implements LslInlet {
146
106
  return this.lsl.createInlet({
147
107
  infoHandle: this.infoHandle,
148
108
  maxBufferedMs: this.maxBufferedMs,
109
+ chunkSize: this.chunkSize,
149
110
  })
150
111
  }
151
112
 
152
- private getChannelCount() {
153
- return this.lsl.getChannelCount({ infoHandle: this.infoHandle })
154
- }
155
-
156
- private allocateWritableBuffers() {
157
- this.allocateDataBuffer()
158
- this.allocateTimestampBuffer()
159
- this.allocatePullErrorBuffer()
160
- this.allocateOpenStreamErrorBuffer()
161
- }
162
-
163
- private allocateDataBuffer() {
164
- this.sampleBuffer = Buffer.alloc(
165
- this.channelCount * this.chunkSize * this.bytesPerFloat
166
- )
167
-
168
- this.sampleBufferRef = createPointer({
169
- paramsType: [DataType.U8Array],
170
- paramsValue: [this.sampleBuffer],
171
- })
172
-
173
- this.sampleBufferPtr = unwrapPointer(this.sampleBufferRef)[0]
174
- }
175
-
176
- private allocateTimestampBuffer() {
177
- this.timestampBuffer = Buffer.alloc(
178
- this.chunkSize * this.bytesPerDouble
179
- )
180
-
181
- this.timestampBufferRef = createPointer({
182
- paramsType: [DataType.U8Array],
183
- paramsValue: [this.timestampBuffer],
184
- })
185
-
186
- this.timestampBufferPtr = unwrapPointer(this.timestampBufferRef)[0]
187
- }
188
-
189
- private allocatePullErrorBuffer() {
190
- this.pullErrorBuffer = Buffer.alloc(this.bytesPerI32)
191
-
192
- this.pullErrorBufferRef = createPointer({
193
- paramsType: [DataType.U8Array],
194
- paramsValue: [this.pullErrorBuffer],
195
- })
196
-
197
- this.pullErrorBufferPtr = unwrapPointer(this.pullErrorBufferRef)[0]
198
- }
199
-
200
- private allocateOpenStreamErrorBuffer() {
201
- this.openStreamErrorBuffer = Buffer.alloc(this.bytesPerI32)
202
-
203
- this.openStreamErrorBufferRef = createPointer({
204
- paramsType: [DataType.U8Array],
205
- paramsValue: [this.openStreamErrorBuffer],
206
- })
207
-
208
- this.openStreamErrorBufferPtr = unwrapPointer(
209
- this.openStreamErrorBufferRef
210
- )[0]
211
- }
212
-
213
- private setPullMethod() {
214
- this.pullMethod =
215
- this.chunkSize === 1 ? this.pullSample : this.pullChunk
216
- }
217
-
218
- private pullSample = () => {
219
- const timestampSec = this.doPullsample()
220
-
221
- if (timestampSec > 0) {
222
- return {
223
- samples: this.readSamplesFromBuffer(),
224
- timestamps: [timestampSec],
225
- }
226
- }
227
- return { samples: undefined, timestamps: undefined }
228
- }
229
-
230
- private doPullsample() {
231
- return this.lsl.pullSample({
232
- inletHandle: this.inletHandle,
233
- sampleBufferPtr: this.sampleBufferPtr,
234
- sampleBufferElements: this.channelCount,
235
- timeoutMs: this.pullTimeoutMs,
236
- errorCodePtr: this.pullErrorBufferPtr,
237
- })
238
- }
239
-
240
- private readSamplesFromBuffer() {
241
- const floats = new Float32Array(
242
- this.sampleBuffer.buffer,
243
- this.sampleBuffer.byteOffset,
244
- this.chunkSize * this.channelCount
245
- )
246
- return Array.from(floats)
247
- }
248
-
249
- private pullChunk = () => {
250
- const firstTimestampSec = this.doPullChunk()
251
-
252
- if (firstTimestampSec > 0) {
253
- return {
254
- samples: this.readSamplesFromBuffer(),
255
- timestamps: this.readTimestampsFromBuffer(),
256
- }
257
- }
258
- return { samples: undefined, timestamps: undefined }
259
- }
260
-
261
- private doPullChunk() {
262
- return this.lsl.pullChunk({
263
- inletHandle: this.inletHandle,
264
- sampleBufferPtr: this.sampleBufferPtr,
265
- sampleBufferElements: this.chunkSize * this.channelCount,
266
- timestampBufferPtr: this.timestampBufferPtr,
267
- timestampBufferElements: this.chunkSize,
268
- timeoutMs: this.pullTimeoutMs,
269
- errorCodePtr: this.pullErrorBufferPtr,
270
- })
271
- }
272
-
273
- private readTimestampsFromBuffer() {
274
- const doubles = new Float64Array(
275
- this.timestampBuffer.buffer,
276
- this.timestampBuffer.byteOffset,
277
- this.chunkSize
278
- )
279
- return Array.from(doubles)
280
- }
281
-
282
113
  private openStream() {
283
114
  this.lsl.openStream({
284
- inletHandle: this.inletHandle,
115
+ inletHandle: this.inletHandle!,
285
116
  timeoutMs: this.openStreamTimeoutMs,
286
- errorCodePtr: this.openStreamErrorBufferPtr,
287
117
  })
288
118
  }
289
119
 
@@ -295,17 +125,26 @@ export default class LslStreamInlet implements LslInlet {
295
125
  }
296
126
 
297
127
  private async pullDataOnce() {
298
- const { samples, timestamps } = this.pullMethod()
299
- this.handleLslErrorIfPresent()
128
+ const pulled = this.pullMethod()
300
129
 
301
- if (samples && timestamps) {
302
- this.onData(samples, timestamps)
130
+ if (pulled) {
131
+ this.onData(pulled.samples, pulled.timestamps)
303
132
  }
304
133
  }
305
134
 
306
- private handleLslErrorIfPresent() {
307
- const errorCode = this.pullErrorBuffer.readInt32LE()
308
- this.handleLslError(errorCode)
135
+ private pullSample() {
136
+ return this.lsl.pullSample(this.pullOptions)
137
+ }
138
+
139
+ private pullChunk() {
140
+ return this.lsl.pullChunk(this.pullOptions)
141
+ }
142
+
143
+ private get pullOptions() {
144
+ return {
145
+ inletHandle: this.inletHandle!,
146
+ timeoutMs: this.pullTimeoutMs,
147
+ }
309
148
  }
310
149
 
311
150
  private async waitBetweenPulls() {
@@ -313,7 +152,7 @@ export default class LslStreamInlet implements LslInlet {
313
152
  }
314
153
 
315
154
  public flushInlet() {
316
- this.lsl.flushInlet({ inletHandle: this.inletHandle })
155
+ this.lsl.flushInlet({ inletHandle: this.inletHandle! })
317
156
  }
318
157
 
319
158
  public stopPulling() {
@@ -326,7 +165,7 @@ export default class LslStreamInlet implements LslInlet {
326
165
  }
327
166
 
328
167
  private closeStream() {
329
- this.lsl.closeStream({ inletHandle: this.inletHandle })
168
+ this.lsl.closeStream({ inletHandle: this.inletHandle! })
330
169
  }
331
170
 
332
171
  public destroy() {
@@ -334,43 +173,19 @@ export default class LslStreamInlet implements LslInlet {
334
173
  this.stopPulling()
335
174
  }
336
175
 
337
- this.doDestroyInlet()
338
- this.freeNativePointers()
339
- }
340
-
341
- private doDestroyInlet() {
342
- this.lsl.destroyInlet({ inletHandle: this.inletHandle })
176
+ this.destroyInletIfCreated()
343
177
  }
344
178
 
345
- private freeNativePointers() {
346
- this.freePointer({
347
- paramsType: [
348
- DataType.U8Array,
349
- DataType.U8Array,
350
- DataType.U8Array,
351
- DataType.U8Array,
352
- ],
353
- paramsValue: [
354
- this.openStreamErrorBufferPtr,
355
- this.sampleBufferPtr,
356
- this.timestampBufferPtr,
357
- this.pullErrorBufferPtr,
358
- ],
359
- pointerType: PointerType.CPointer,
360
- })
179
+ private destroyInletIfCreated() {
180
+ if (this.inletHandle) {
181
+ this.lsl.destroyInlet({ inletHandle: this.inletHandle })
182
+ delete this.inletHandle
183
+ }
361
184
  }
362
185
 
363
186
  private get lsl() {
364
187
  return LslStreamInlet.lsl
365
188
  }
366
-
367
- private get handleLslError() {
368
- return LslStreamInlet.handleLslError
369
- }
370
-
371
- private get freePointer() {
372
- return LslStreamInlet.freePointer
373
- }
374
189
  }
375
190
 
376
191
  export interface LslInlet {
@@ -396,4 +211,9 @@ export interface LslInletOptions {
396
211
  flushInletOnStop?: boolean
397
212
  }
398
213
 
214
+ export interface PulledData {
215
+ samples: number[]
216
+ timestamps: number[]
217
+ }
218
+
399
219
  export type OnDataCallback = (samples: number[], timestamps: number[]) => void
@@ -25,7 +25,7 @@ export default class LslStreamOutlet implements LslOutlet {
25
25
  public readonly name: string
26
26
  public readonly type: string
27
27
  public readonly sourceId: string
28
- public readonly channelNames: string[]
28
+ public readonly channelNames: readonly string[]
29
29
  public readonly channelFormat: ChannelFormat
30
30
  public readonly channelCount: number
31
31
  public readonly sampleRateHz: number
@@ -168,7 +168,7 @@ export interface LslOutlet {
168
168
  readonly name: string
169
169
  readonly type: string
170
170
  readonly sourceId: string
171
- readonly channelNames: string[]
171
+ readonly channelNames: readonly string[]
172
172
  readonly channelCount: number
173
173
  readonly channelFormat: ChannelFormat
174
174
  readonly sampleRateHz: number
@@ -184,7 +184,7 @@ export interface LslOutletOptions {
184
184
  name: string
185
185
  type: string
186
186
  sourceId: string
187
- channelNames: string[]
187
+ channelNames: readonly string[]
188
188
  channelFormat: ChannelFormat
189
189
  sampleRateHz: number
190
190
  chunkSize: number
@@ -41,7 +41,7 @@ export default class WindowedClockRegressor implements ClockRegressor {
41
41
 
42
42
  const anchor = this.anchorTimeFor(deviceTime)
43
43
 
44
- const timestamps = Array(chunkSize).fill(0)
44
+ const timestamps: number[] = Array(chunkSize).fill(0)
45
45
 
46
46
  for (let i = 0; i <= chunkSize - 1; i++) {
47
47
  const stepsFromLast = chunkSize - 1 - i
@@ -1,33 +1,20 @@
1
- import { LibndxAdapter, Libndx, NativePeripheral } from '@neurodevs/ndx-native'
1
+ import { LibndxAdapter, NativePeripheral } from '@neurodevs/ndx-native'
2
2
 
3
3
  export default class BleGattController implements BleGatt {
4
4
  public static Class?: BleGattConstructor
5
5
  public static setTimeout = setTimeout
6
6
  public static waitAfterMs = 1000
7
7
 
8
- private static _ndx?: Libndx
9
-
10
- public static get ndx() {
11
- if (!this._ndx) {
12
- this._ndx = LibndxAdapter.getInstance()
13
- }
14
- return this._ndx
15
- }
16
-
17
- public static set ndx(value: Libndx) {
18
- this._ndx = value
19
- }
20
-
21
8
  protected charCallbacks: CharacteristicCallbacks
22
9
  protected rssiIntervalMs?: number
23
- protected connected = false
10
+ protected state: BleGattState = { status: 'disconnected' }
24
11
  protected log = console
25
12
 
26
- private deviceUuid?: string
27
13
  private deviceNamePrefix?: string
28
- private deviceName?: string
29
14
  private onConnected?: (peripheral: NativePeripheral) => void
30
15
 
16
+ private readonly ndx = LibndxAdapter.getInstance()
17
+
31
18
  protected constructor(options: BleGattOptions) {
32
19
  const {
33
20
  deviceUuid,
@@ -37,7 +24,7 @@ export default class BleGattController implements BleGatt {
37
24
  rssiIntervalMs,
38
25
  } = options
39
26
 
40
- this.deviceUuid = deviceUuid
27
+ this.state = { status: 'disconnected', uuid: deviceUuid }
41
28
  this.deviceNamePrefix = deviceNamePrefix
42
29
  this.charCallbacks = charCallbacks
43
30
  this.onConnected = onConnected
@@ -49,10 +36,12 @@ export default class BleGattController implements BleGatt {
49
36
  }
50
37
 
51
38
  public async connect() {
52
- if (!this.deviceUuid) {
39
+ if (!this.state.uuid) {
53
40
  await this.discoverUuid()
54
41
  }
55
42
 
43
+ this.state = { status: 'connecting', uuid: this.uuid }
44
+
56
45
  this.createBleGattBackend()
57
46
  this.startBleGattBackend()
58
47
 
@@ -66,7 +55,7 @@ export default class BleGattController implements BleGatt {
66
55
  const { status, error } = this.ndx.discoverBleUuid({
67
56
  namePrefix: this.deviceNamePrefix as string,
68
57
  onDiscovered: (uuid: string) => {
69
- this.deviceUuid = uuid
58
+ this.state = { status: 'disconnected', uuid }
70
59
  },
71
60
  })
72
61
 
@@ -78,7 +67,7 @@ export default class BleGattController implements BleGatt {
78
67
  private async waitForDiscoveredUuid() {
79
68
  await new Promise<void>((resolve) => {
80
69
  const checkDiscovered = () => {
81
- if (this.deviceUuid) {
70
+ if (this.uuid) {
82
71
  resolve()
83
72
  } else {
84
73
  BleGattController.setTimeout(checkDiscovered, 100)
@@ -119,12 +108,11 @@ export default class BleGattController implements BleGatt {
119
108
  deviceUuid: this.uuid,
120
109
  onConnected: (peripheral: NativePeripheral) => {
121
110
  const { name } = peripheral
122
- this.deviceName = name
123
- this.connected = true
111
+ this.state = { status: 'connected', uuid: this.uuid, name }
124
112
  this.log.info(`Connected to device ${this.uuid}!`)
125
113
  this.onConnected?.(peripheral)
126
114
  },
127
- charCallbacks: this.charCallbacks,
115
+ charCallbacks: [...this.charCallbacks],
128
116
  })
129
117
 
130
118
  this.throwIfError(status, error)
@@ -133,7 +121,7 @@ export default class BleGattController implements BleGatt {
133
121
  private async waitForOnConnected() {
134
122
  await new Promise<void>((resolve) => {
135
123
  const checkConnected = () => {
136
- if (this.connected) {
124
+ if (this.state.status === 'connected') {
137
125
  resolve()
138
126
  } else {
139
127
  BleGattController.setTimeout(checkConnected, 100)
@@ -154,7 +142,7 @@ export default class BleGattController implements BleGatt {
154
142
  value: string
155
143
  ) {
156
144
  const { status, error } = this.ndx.writeBleGattChar({
157
- deviceUuid: this.uuid,
145
+ deviceUuid: this.requireUuid(),
158
146
  charUuid,
159
147
  value,
160
148
  })
@@ -166,8 +154,8 @@ export default class BleGattController implements BleGatt {
166
154
  charCallbacks: CharacteristicCallbacks
167
155
  ) {
168
156
  const { status, error } = this.ndx.registerBleGattCharCallbacks({
169
- deviceUuid: this.uuid,
170
- charCallbacks,
157
+ deviceUuid: this.requireUuid(),
158
+ charCallbacks: [...charCallbacks],
171
159
  })
172
160
 
173
161
  this.throwIfError(status, error)
@@ -177,29 +165,34 @@ export default class BleGattController implements BleGatt {
177
165
 
178
166
  public async disconnect() {
179
167
  const { status, error } = this.ndx.stopBleGattBackend({
180
- deviceUuid: this.uuid,
168
+ deviceUuid: this.requireUuid(),
181
169
  })
182
170
 
183
171
  this.throwIfError(status, error)
184
- this.connected = false
172
+ this.state = { status: 'disconnected', uuid: this.state.uuid }
185
173
  }
186
174
 
187
175
  public get uuid() {
188
- return this.deviceUuid ?? ''
176
+ return this.state.uuid ?? ''
189
177
  }
190
178
 
191
179
  public get name() {
192
- return this.deviceName ?? 'N/A'
180
+ return this.state.name ?? 'N/A'
193
181
  }
194
182
 
195
- private get ndx() {
196
- return BleGattController.ndx
183
+ private requireUuid() {
184
+ if (!this.uuid) {
185
+ throw new Error(
186
+ 'Device uuid is not resolved yet! Must either pass as option to Create or call connect() first.'
187
+ )
188
+ }
189
+ return this.uuid
197
190
  }
198
191
  }
199
192
 
200
193
  export interface BleGatt {
201
- uuid: string
202
- name: string
194
+ readonly uuid: string
195
+ readonly name: string
203
196
 
204
197
  connect(): Promise<void>
205
198
 
@@ -226,7 +219,12 @@ export type BleGattOptions = {
226
219
 
227
220
  export type BleGattConstructor = new (options: BleGattOptions) => BleGatt
228
221
 
229
- export type CharacteristicCallbacks = {
222
+ export type BleGattState =
223
+ | { status: 'disconnected'; uuid?: string; name?: string }
224
+ | { status: 'connecting'; uuid: string; name?: string }
225
+ | { status: 'connected'; uuid: string; name: string }
226
+
227
+ export type CharacteristicCallbacks = readonly {
230
228
  charUuid: string
231
229
  charName?: string
232
230
  onData: (data: Buffer, length: number, timestampSec: number) => void
@@ -22,21 +22,24 @@ export default class FakeBleGatt implements BleGatt {
22
22
 
23
23
  public static fakeCharacteristics: Record<string, unknown> = {}
24
24
  public static fakeName = `fake-${generateId()}`
25
+ public static fakeDiscoveredUuid = `fake-uuid-${generateId()}`
25
26
 
26
- private _uuid: string
27
- private _name: string
27
+ private _uuid?: string
28
+ private _name?: string
28
29
 
29
30
  public constructor(options?: BleGattOptions) {
30
31
  const { deviceUuid } = options ?? {}
31
32
 
32
- this._uuid = deviceUuid ?? generateId()
33
- this._name = FakeBleGatt.fakeName
33
+ this._uuid = deviceUuid
34
34
 
35
35
  FakeBleGatt.callsToConstructor.push(options)
36
36
  }
37
37
 
38
38
  public async connect() {
39
39
  FakeBleGatt.numCallsToConnect++
40
+
41
+ this._uuid = this._uuid ?? FakeBleGatt.fakeDiscoveredUuid
42
+ this._name = FakeBleGatt.fakeName
40
43
  }
41
44
 
42
45
  public async writeCharacteristic(
@@ -60,11 +63,11 @@ export default class FakeBleGatt implements BleGatt {
60
63
  }
61
64
 
62
65
  public get uuid() {
63
- return this._uuid
66
+ return this._uuid ?? ''
64
67
  }
65
68
 
66
69
  public get name() {
67
- return this._name
70
+ return this._name ?? 'N/A'
68
71
  }
69
72
 
70
73
  public static resetTestDouble() {
@@ -19,8 +19,8 @@ export default class SpyBleGatt extends BleGattController {
19
19
  return this.rssiIntervalMs
20
20
  }
21
21
 
22
- public getConnected() {
23
- return this.connected
22
+ public getState() {
23
+ return this.state
24
24
  }
25
25
 
26
26
  public setLogInfoSpy() {