@neurodevs/node-lsl 18.0.0 → 19.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.
Files changed (124) hide show
  1. package/.vscode/launch.json +54 -58
  2. package/.vscode/settings.json +61 -66
  3. package/.vscode/tasks.json +98 -129
  4. package/README.md +14 -12
  5. package/build/__tests__/AbstractPackageTest.d.ts +16 -12
  6. package/build/__tests__/AbstractPackageTest.js +48 -20
  7. package/build/__tests__/AbstractPackageTest.js.map +1 -1
  8. package/build/__tests__/impl/BleDeviceController.test.d.ts +59 -0
  9. package/build/__tests__/impl/BleDeviceController.test.js +364 -0
  10. package/build/__tests__/impl/BleDeviceController.test.js.map +1 -0
  11. package/build/__tests__/impl/LslEventMarkerEmitter.test.js +1 -1
  12. package/build/__tests__/impl/LslEventMarkerEmitter.test.js.map +1 -1
  13. package/build/__tests__/impl/LslStreamInlet.test.js +2 -2
  14. package/build/__tests__/impl/LslStreamInlet.test.js.map +1 -1
  15. package/build/__tests__/impl/LslStreamOutlet.test.js +11 -13
  16. package/build/__tests__/impl/LslStreamOutlet.test.js.map +1 -1
  17. package/build/__tests__/impl/LslWebSocketBridge.test.js +3 -3
  18. package/build/__tests__/impl/LslWebSocketBridge.test.js.map +1 -1
  19. package/build/__tests__/impl/UsbDeviceController.test.d.ts +17 -0
  20. package/build/__tests__/impl/UsbDeviceController.test.js +81 -0
  21. package/build/__tests__/impl/UsbDeviceController.test.js.map +1 -0
  22. package/build/__tests__/impl/WindowedClockRegressor.test.d.ts +19 -0
  23. package/build/__tests__/impl/WindowedClockRegressor.test.js +172 -0
  24. package/build/__tests__/impl/WindowedClockRegressor.test.js.map +1 -0
  25. package/build/impl/LslStreamInlet.d.ts +1 -0
  26. package/build/impl/LslStreamInlet.js +2 -1
  27. package/build/impl/LslStreamInlet.js.map +1 -1
  28. package/build/impl/LslStreamOutlet.d.ts +3 -2
  29. package/build/impl/LslStreamOutlet.js +4 -3
  30. package/build/impl/LslStreamOutlet.js.map +1 -1
  31. package/build/impl/LslWebSocketBridge.js +2 -2
  32. package/build/impl/LslWebSocketBridge.js.map +1 -1
  33. package/build/impl/WindowedClockRegressor.d.ts +24 -0
  34. package/build/impl/WindowedClockRegressor.js +73 -0
  35. package/build/impl/WindowedClockRegressor.js.map +1 -0
  36. package/build/impl/controllers/BleDeviceController.d.ts +60 -0
  37. package/build/impl/controllers/BleDeviceController.js +153 -0
  38. package/build/impl/controllers/BleDeviceController.js.map +1 -0
  39. package/build/impl/controllers/UsbDeviceController.d.ts +23 -0
  40. package/build/impl/controllers/UsbDeviceController.js +40 -0
  41. package/build/impl/controllers/UsbDeviceController.js.map +1 -0
  42. package/build/impl/workers/inlet/StreamInletWorker.d.ts +4 -4
  43. package/build/impl/workers/inlet/StreamInletWorker.js +12 -12
  44. package/build/impl/workers/inlet/StreamInletWorker.js.map +1 -1
  45. package/build/impl/workers/outlet/LslStreamOutlet.worker.d.ts +3 -3
  46. package/build/impl/workers/outlet/LslStreamOutlet.worker.js +7 -7
  47. package/build/impl/workers/outlet/LslStreamOutlet.worker.js.map +1 -1
  48. package/build/index.d.ts +14 -4
  49. package/build/index.js +17 -5
  50. package/build/index.js.map +1 -1
  51. package/build/scripts/discoverMuse.d.ts +1 -0
  52. package/build/scripts/discoverMuse.js +40 -0
  53. package/build/scripts/discoverMuse.js.map +1 -0
  54. package/build/scripts/runMuse.d.ts +1 -0
  55. package/build/scripts/runMuse.js +40 -0
  56. package/build/scripts/runMuse.js.map +1 -0
  57. package/build/scripts/runUsb.d.ts +1 -0
  58. package/build/scripts/runUsb.js +14 -0
  59. package/build/scripts/runUsb.js.map +1 -0
  60. package/build/testDoubles/BleController/FakeBleController.d.ts +26 -0
  61. package/build/testDoubles/BleController/FakeBleController.js +47 -0
  62. package/build/testDoubles/BleController/FakeBleController.js.map +1 -0
  63. package/build/testDoubles/BleController/SpyBleController.d.ts +14 -0
  64. package/build/testDoubles/BleController/SpyBleController.js +48 -0
  65. package/build/testDoubles/BleController/SpyBleController.js.map +1 -0
  66. package/build/testDoubles/ClockRegressor/FakeClockRegressor.d.ts +17 -0
  67. package/build/testDoubles/ClockRegressor/FakeClockRegressor.js +23 -0
  68. package/build/testDoubles/ClockRegressor/FakeClockRegressor.js.map +1 -0
  69. package/build/testDoubles/StreamOutlet/FakeStreamOutlet.d.ts +2 -2
  70. package/build/testDoubles/StreamOutlet/FakeStreamOutlet.js +5 -2
  71. package/build/testDoubles/StreamOutlet/FakeStreamOutlet.js.map +1 -1
  72. package/build/testDoubles/UsbController/FakeUsbController.d.ts +12 -0
  73. package/build/testDoubles/UsbController/FakeUsbController.js +25 -0
  74. package/build/testDoubles/UsbController/FakeUsbController.js.map +1 -0
  75. package/build/testDoubles/WebSocketBridge/FakeWebSocketBridge.js.map +1 -1
  76. package/build/testDoubles/generateRandomOutletOptions.js +1 -1
  77. package/build/testDoubles/generateRandomOutletOptions.js.map +1 -1
  78. package/eslint.config.js +3 -0
  79. package/package.json +19 -57
  80. package/prettier.config.js +3 -0
  81. package/src/__tests__/AbstractPackageTest.ts +86 -29
  82. package/src/__tests__/impl/BleDeviceController.test.ts +535 -0
  83. package/src/__tests__/impl/LslEventMarkerEmitter.test.ts +2 -1
  84. package/src/__tests__/impl/LslStreamInlet.test.ts +2 -2
  85. package/src/__tests__/impl/LslStreamOutlet.test.ts +15 -14
  86. package/src/__tests__/impl/LslWebSocketBridge.test.ts +4 -3
  87. package/src/__tests__/impl/UsbDeviceController.test.ts +109 -0
  88. package/src/__tests__/impl/WindowedClockRegressor.test.ts +262 -0
  89. package/src/impl/LslStreamInlet.ts +4 -1
  90. package/src/impl/LslStreamOutlet.ts +5 -4
  91. package/src/impl/LslWebSocketBridge.ts +2 -2
  92. package/src/impl/WindowedClockRegressor.ts +136 -0
  93. package/src/impl/controllers/BleDeviceController.ts +240 -0
  94. package/src/impl/controllers/UsbDeviceController.ts +65 -0
  95. package/src/impl/workers/inlet/StreamInletWorker.ts +12 -12
  96. package/src/impl/workers/outlet/LslStreamOutlet.worker.ts +8 -8
  97. package/src/index.ts +24 -5
  98. package/src/scripts/discoverMuse.ts +50 -0
  99. package/src/scripts/runMuse.ts +50 -0
  100. package/src/scripts/runUsb.ts +20 -0
  101. package/src/testDoubles/BleController/FakeBleController.ts +81 -0
  102. package/src/testDoubles/BleController/SpyBleController.ts +61 -0
  103. package/src/testDoubles/ClockRegressor/FakeClockRegressor.ts +46 -0
  104. package/src/testDoubles/StreamOutlet/FakeStreamOutlet.ts +6 -3
  105. package/src/testDoubles/UsbController/FakeUsbController.ts +34 -0
  106. package/src/testDoubles/WebSocketBridge/FakeWebSocketBridge.ts +1 -2
  107. package/src/testDoubles/generateRandomOutletOptions.ts +2 -1
  108. package/tsconfig.json +23 -27
  109. package/.regressionproof.json +0 -7
  110. package/build/.spruce/settings.json +0 -15
  111. package/build/__tests__/impl/LslBackpressureMonitor.test.d.ts +0 -7
  112. package/build/__tests__/impl/LslBackpressureMonitor.test.js +0 -26
  113. package/build/__tests__/impl/LslBackpressureMonitor.test.js.map +0 -1
  114. package/build/impl/LslBackpressureMonitor.d.ts +0 -8
  115. package/build/impl/LslBackpressureMonitor.js +0 -8
  116. package/build/impl/LslBackpressureMonitor.js.map +0 -1
  117. package/build/testDoubles/BackpressureMonitor/FakeBackpressureMonitor.d.ts +0 -6
  118. package/build/testDoubles/BackpressureMonitor/FakeBackpressureMonitor.js +0 -10
  119. package/build/testDoubles/BackpressureMonitor/FakeBackpressureMonitor.js.map +0 -1
  120. package/eslint.config.mjs +0 -3
  121. package/src/.spruce/settings.json +0 -15
  122. package/src/__tests__/impl/LslBackpressureMonitor.test.ts +0 -25
  123. package/src/impl/LslBackpressureMonitor.ts +0 -13
  124. package/src/testDoubles/BackpressureMonitor/FakeBackpressureMonitor.ts +0 -13
@@ -0,0 +1,535 @@
1
+ import { randomInt } from 'node:crypto'
2
+
3
+ import { test, assert } from '@neurodevs/node-tdd'
4
+ import { FakeLibndx, NativePeripheral } from '@neurodevs/ndx-native'
5
+
6
+ import SpyBleController from '../../testDoubles/BleController/SpyBleController.js'
7
+ import AbstractPackageTest from '../AbstractPackageTest.js'
8
+ import BleDeviceController, {
9
+ BleControllerOptions,
10
+ } from '../../impl/controllers/BleDeviceController.js'
11
+
12
+ export default class BleDeviceControllerTest extends AbstractPackageTest {
13
+ private static instance: SpyBleController
14
+
15
+ private static readonly uuid = this.generateId()
16
+ private static readonly namePrefix = this.generateId()
17
+ private static readonly discoveredUuid = this.generateId()
18
+ private static readonly charUuid = this.generateId()
19
+ private static readonly charValueToWrite = this.generateId()
20
+ private static readonly rssiIntervalMs = randomInt(1, 5)
21
+ private static readonly fakeError = this.generateId()
22
+ private static readonly fake400Error = `400 error: ${this.fakeError}`
23
+ private static readonly fake500Error = `500 error: ${this.fakeError}`
24
+
25
+ private static readonly charCallbacks = [
26
+ {
27
+ charUuid: this.generateId(),
28
+ charName: this.generateId(),
29
+ onData: async () => {},
30
+ },
31
+ {
32
+ charUuid: this.generateId(),
33
+ charName: this.generateId(),
34
+ onData: async () => {},
35
+ },
36
+ ]
37
+
38
+ private static readonly extraCharCallbacks = [
39
+ {
40
+ charUuid: this.generateId(),
41
+ charName: this.generateId(),
42
+ onData: async () => {},
43
+ },
44
+ ]
45
+
46
+ private static onConnected = (_peripheral: NativePeripheral) => {
47
+ this.wasConnected = true
48
+ }
49
+
50
+ private static wasConnected: boolean
51
+
52
+ private static nativePeripheral: NativePeripheral = {
53
+ uuid: this.generateId(),
54
+ name: this.generateId(),
55
+ }
56
+
57
+ protected static async beforeAll() {
58
+ assert.isEqual(
59
+ BleDeviceController.waitAfterMs,
60
+ 1000,
61
+ 'Set incorrect waitAfterMs!'
62
+ )
63
+ }
64
+
65
+ protected static async beforeEach() {
66
+ await super.beforeEach()
67
+
68
+ BleDeviceController.waitAfterMs = 0
69
+ BleDeviceController.Class = SpyBleController
70
+
71
+ this.wasConnected = false
72
+
73
+ this.instance = await this.BleController()
74
+ }
75
+
76
+ @test()
77
+ protected static async createsInstance() {
78
+ assert.isTruthy(this.instance, 'Failed to create instance!')
79
+ }
80
+
81
+ @test()
82
+ protected static async connectCallsLibndxCreateBleBackend() {
83
+ await this.connect()
84
+
85
+ assert.isEqualDeep(
86
+ FakeLibndx.callsToCreateBleBackend[0],
87
+ {
88
+ deviceUuid: this.uuid,
89
+ },
90
+ 'Did not call createBleBackend!'
91
+ )
92
+ }
93
+
94
+ @test()
95
+ protected static async discoversUuidWhenDeviceUuidNotProvided() {
96
+ const instance = await this.BleControllerWithPrefix()
97
+
98
+ await this.connectWithDiscovery(instance)
99
+
100
+ const call = FakeLibndx.callsToDiscoverBleUuid[0]
101
+
102
+ assert.isEqual(
103
+ call?.namePrefix,
104
+ this.namePrefix,
105
+ 'Did not call discoverBleUuid with deviceNamePrefix!'
106
+ )
107
+
108
+ assert.isFunction(
109
+ call?.onDiscovered,
110
+ 'Did not pass an onDiscovered callback to discoverBleUuid!'
111
+ )
112
+ }
113
+
114
+ @test()
115
+ protected static async doesNotDiscoverUuidWhenDeviceUuidProvided() {
116
+ await this.connect()
117
+
118
+ assert.isEqual(
119
+ FakeLibndx.callsToDiscoverBleUuid.length,
120
+ 0,
121
+ 'Should not call discoverBleUuid when deviceUuid is provided!'
122
+ )
123
+ }
124
+
125
+ @test()
126
+ protected static async usesDiscoveredUuidToCreateBleBackend() {
127
+ const instance = await this.BleControllerWithPrefix()
128
+
129
+ await this.connectWithDiscovery(instance)
130
+
131
+ assert.isEqualDeep(
132
+ FakeLibndx.callsToCreateBleBackend[0],
133
+ {
134
+ deviceUuid: this.discoveredUuid,
135
+ },
136
+ 'Did not create BLE backend with the discovered uuid!'
137
+ )
138
+ }
139
+
140
+ @test()
141
+ protected static async usesDiscoveredUuidToStartBleBackend() {
142
+ const instance = await this.BleControllerWithPrefix()
143
+
144
+ await this.connectWithDiscovery(instance)
145
+
146
+ assert.isEqual(
147
+ FakeLibndx.callsToStartBleBackend[0]?.deviceUuid,
148
+ this.discoveredUuid,
149
+ 'Did not start BLE backend with the discovered uuid!'
150
+ )
151
+ }
152
+
153
+ @test()
154
+ protected static async exposesDiscoveredUuid() {
155
+ const instance = await this.BleControllerWithPrefix()
156
+
157
+ await this.connectWithDiscovery(instance)
158
+
159
+ assert.isEqual(
160
+ instance.uuid,
161
+ this.discoveredUuid,
162
+ 'Did not expose the discovered uuid!'
163
+ )
164
+ }
165
+
166
+ @test()
167
+ protected static async createBleBackendThrowsOn400() {
168
+ this.setFake400Error()
169
+
170
+ await assert.doesThrowAsync(
171
+ async () => await this.instance.connect(),
172
+ this.fake400Error,
173
+ 'Did not throw error!'
174
+ )
175
+ }
176
+
177
+ @test()
178
+ protected static async createBleBackendThrowsOn500() {
179
+ this.setFake500Error()
180
+
181
+ await assert.doesThrowAsync(
182
+ async () => await this.instance.connect(),
183
+ this.fake500Error,
184
+ 'Did not throw error!'
185
+ )
186
+ }
187
+
188
+ @test()
189
+ protected static async connectCallsLibndxStartBleBackend() {
190
+ await this.connect()
191
+
192
+ const call = FakeLibndx.callsToStartBleBackend[0]
193
+
194
+ assert.isEqual(
195
+ call.deviceUuid,
196
+ this.uuid,
197
+ 'Did not call startBleBackend with correct deviceUuid!'
198
+ )
199
+
200
+ assert.isEqual(
201
+ call.charCallbacks.length,
202
+ 2,
203
+ 'Did not call startBleBackend with charCallbacks!'
204
+ )
205
+
206
+ let i = 0
207
+ for (const charCallback of call.charCallbacks) {
208
+ assert.isEqual(
209
+ charCallback.charUuid,
210
+ this.charCallbacks[i].charUuid,
211
+ 'Incorrect charUuid!'
212
+ )
213
+
214
+ assert.isEqual(
215
+ charCallback.charName,
216
+ this.charCallbacks[i].charName,
217
+ 'Incorrect charName!'
218
+ )
219
+
220
+ assert.isFunction(
221
+ charCallback.onData,
222
+ 'Callback is not a function!'
223
+ )
224
+ i++
225
+ }
226
+ }
227
+
228
+ @test()
229
+ protected static async startBleBackendThrowsOn400() {
230
+ //@ts-ignore
231
+ this.instance.createBleBackend = () => {}
232
+
233
+ this.setFake400Error()
234
+
235
+ await assert.doesThrowAsync(
236
+ async () => await this.instance.connect(),
237
+ this.fake400Error,
238
+ 'Did not throw error!'
239
+ )
240
+ }
241
+
242
+ @test()
243
+ protected static async startBleBackendThrowsOn500() {
244
+ //@ts-ignore
245
+ this.instance.createBleBackend = () => {}
246
+
247
+ this.setFake500Error()
248
+
249
+ await assert.doesThrowAsync(
250
+ async () => await this.instance.connect(),
251
+ this.fake500Error,
252
+ 'Did not throw error!'
253
+ )
254
+ }
255
+
256
+ @test()
257
+ protected static async connectWaitsForOnConnectedEvent() {
258
+ await this.connect()
259
+
260
+ assert.isTruthy(
261
+ this.wasConnected,
262
+ 'Did not wait for onConnected event!'
263
+ )
264
+ }
265
+
266
+ @test()
267
+ protected static async waitsAfterOnConnectedToDiscoverServices() {
268
+ const waitAfterMs = 20
269
+ BleDeviceController.waitAfterMs = waitAfterMs
270
+
271
+ await this.connect()
272
+
273
+ assert.isTruthy(
274
+ this.callsToSetTimeout.includes(waitAfterMs),
275
+ 'Did not wait after on connected!'
276
+ )
277
+ }
278
+
279
+ @test()
280
+ protected static async writeCharacteristicCallsLibndxBinding() {
281
+ await this.writeCharacteristic()
282
+
283
+ assert.isEqualDeep(
284
+ FakeLibndx.callsToWriteBleCharacteristic[0],
285
+ {
286
+ deviceUuid: this.uuid,
287
+ charUuid: this.charUuid,
288
+ value: this.charValueToWrite,
289
+ },
290
+ 'Did not call writeBleCharacteristic as expected!'
291
+ )
292
+ }
293
+
294
+ @test()
295
+ protected static async writeCharacteristicThrowsOn400() {
296
+ this.setFake400Error()
297
+
298
+ await assert.doesThrowAsync(
299
+ async () => await this.writeCharacteristic(),
300
+ this.fake400Error,
301
+ 'Did not throw error!'
302
+ )
303
+ }
304
+
305
+ @test()
306
+ protected static async writeCharacteristicThrowsOn500() {
307
+ this.setFake500Error()
308
+
309
+ await assert.doesThrowAsync(
310
+ async () => await this.writeCharacteristic(),
311
+ this.fake500Error,
312
+ 'Did not throw error!'
313
+ )
314
+ }
315
+
316
+ @test()
317
+ protected static async subscribeCharacteristicsCallsLibndxBinding() {
318
+ await this.subscribeCharacteristics()
319
+
320
+ assert.isEqualDeep(
321
+ FakeLibndx.callsToAddBleCharCallbacks[0],
322
+ {
323
+ deviceUuid: this.uuid,
324
+ charCallbacks: this.extraCharCallbacks,
325
+ },
326
+ 'Did not call addBleCharCallbacks as expected!'
327
+ )
328
+ }
329
+
330
+ @test()
331
+ protected static async subscribeCharacteristicsMergesIntoCharCallbacks() {
332
+ await this.subscribeCharacteristics()
333
+
334
+ assert.isEqualDeep(
335
+ this.instance.getCharacteristicCallbacks(),
336
+ [...this.charCallbacks, ...this.extraCharCallbacks],
337
+ 'Did not merge the newly subscribed callbacks into charCallbacks!'
338
+ )
339
+ }
340
+
341
+ @test()
342
+ protected static async subscribeCharacteristicsThrowsOn400() {
343
+ this.setFake400Error()
344
+
345
+ await assert.doesThrowAsync(
346
+ async () => await this.subscribeCharacteristics(),
347
+ this.fake400Error,
348
+ 'Did not throw error!'
349
+ )
350
+ }
351
+
352
+ @test()
353
+ protected static async callsSetBleRssiInterval() {
354
+ await this.connect()
355
+
356
+ const { deviceUuid, intervalMs } =
357
+ FakeLibndx.callsToSetBleRssiInterval[0]
358
+
359
+ assert.isEqualDeep(
360
+ { deviceUuid, intervalMs },
361
+ {
362
+ deviceUuid: this.uuid,
363
+ intervalMs: this.rssiIntervalMs,
364
+ },
365
+ 'Did not call setBleRssiInterval as expected!'
366
+ )
367
+ }
368
+
369
+ @test()
370
+ protected static async disconnectCallsLibndxStopBleBackend() {
371
+ await this.disconnect()
372
+
373
+ assert.isEqualDeep(
374
+ FakeLibndx.callsToStopBleBackend[0],
375
+ {
376
+ deviceUuid: this.uuid,
377
+ },
378
+ 'Did not call stopBleBackend!'
379
+ )
380
+ }
381
+
382
+ @test()
383
+ protected static async disconnectThrowsOn400() {
384
+ this.setFake400Error()
385
+
386
+ await assert.doesThrowAsync(
387
+ async () => await this.disconnect(),
388
+ this.fake400Error,
389
+ 'Did not throw error!'
390
+ )
391
+ }
392
+
393
+ @test()
394
+ protected static async disconnectThrowsOn500() {
395
+ this.setFake500Error()
396
+
397
+ await assert.doesThrowAsync(
398
+ async () => await this.disconnect(),
399
+ this.fake500Error,
400
+ 'Did not throw error!'
401
+ )
402
+ }
403
+
404
+ @test()
405
+ protected static async disconnectResetsConnectedFlag() {
406
+ await this.connect()
407
+ await this.disconnect()
408
+
409
+ assert.isFalse(
410
+ this.instance.getConnected(),
411
+ 'Did not reset connected flag on disconnect!'
412
+ )
413
+ }
414
+
415
+ @test()
416
+ protected static async exposesPeriperalName() {
417
+ await this.connect()
418
+
419
+ assert.isEqual(
420
+ this.instance.name,
421
+ this.nativePeripheral.name,
422
+ 'Did not set peripheral name!'
423
+ )
424
+ }
425
+
426
+ @test()
427
+ protected static async returnsNAIfNameNotAvailable() {
428
+ assert.isEqual(
429
+ this.instance.name,
430
+ 'N/A',
431
+ 'Did not set default name to N/A!'
432
+ )
433
+ }
434
+
435
+ @test()
436
+ protected static async throwsWithUnknownErrorIfNoError() {
437
+ this.setFake500ErrorWithoutError()
438
+
439
+ await assert.doesThrowAsync(
440
+ async () => await this.connect(),
441
+ 'Unknown error',
442
+ 'Did not throw error!'
443
+ )
444
+ }
445
+
446
+ private static async connect() {
447
+ const promise = this.instance.connect()
448
+
449
+ const startCall = FakeLibndx.callsToStartBleBackend[0]
450
+ startCall?.onConnected(this.nativePeripheral)
451
+
452
+ await promise
453
+ }
454
+
455
+ private static async connectWithDiscovery(instance: SpyBleController) {
456
+ const promise = instance.connect()
457
+
458
+ FakeLibndx.callsToDiscoverBleUuid[0]?.onDiscovered(this.discoveredUuid)
459
+
460
+ await this.waitForCall(() => FakeLibndx.callsToStartBleBackend[0])
461
+
462
+ FakeLibndx.callsToStartBleBackend[0]?.onConnected(this.nativePeripheral)
463
+
464
+ await promise
465
+ }
466
+
467
+ private static async waitForCall<T>(getCall: () => T) {
468
+ await new Promise<void>((resolve) => {
469
+ const check = () => {
470
+ if (getCall()) {
471
+ resolve()
472
+ } else {
473
+ setTimeout(check, 0)
474
+ }
475
+ }
476
+ check()
477
+ })
478
+ }
479
+
480
+ private static async writeCharacteristic() {
481
+ await this.instance.writeCharacteristic(
482
+ this.charUuid,
483
+ this.charValueToWrite
484
+ )
485
+ }
486
+
487
+ private static async subscribeCharacteristics() {
488
+ await this.instance.subscribeCharacteristics(this.extraCharCallbacks)
489
+ }
490
+
491
+ private static async disconnect() {
492
+ await this.instance.disconnect()
493
+ }
494
+
495
+ private static setFake400Error() {
496
+ FakeLibndx.fakeResult = {
497
+ status: 400,
498
+ error: this.fakeError,
499
+ }
500
+ }
501
+
502
+ private static setFake500Error() {
503
+ FakeLibndx.fakeResult = {
504
+ status: 500,
505
+ error: this.fakeError,
506
+ }
507
+ }
508
+
509
+ private static setFake500ErrorWithoutError() {
510
+ FakeLibndx.fakeResult = {
511
+ status: 500,
512
+ }
513
+ }
514
+
515
+ private static async BleController(
516
+ options?: Partial<BleControllerOptions>
517
+ ) {
518
+ return (await BleDeviceController.Create({
519
+ deviceUuid: this.uuid,
520
+ charCallbacks: this.charCallbacks,
521
+ onConnected: this.onConnected,
522
+ rssiIntervalMs: this.rssiIntervalMs,
523
+ ...options,
524
+ })) as SpyBleController
525
+ }
526
+
527
+ private static async BleControllerWithPrefix() {
528
+ return (await BleDeviceController.Create({
529
+ deviceNamePrefix: this.namePrefix,
530
+ charCallbacks: this.charCallbacks,
531
+ onConnected: this.onConnected,
532
+ rssiIntervalMs: this.rssiIntervalMs,
533
+ } as unknown as BleControllerOptions)) as SpyBleController
534
+ }
535
+ }
@@ -1,4 +1,5 @@
1
- import { randomInt } from 'crypto'
1
+ import { randomInt } from 'node:crypto'
2
+
2
3
  import { assert, test } from '@neurodevs/node-tdd'
3
4
 
4
5
  import LslEventMarkerEmitter, {
@@ -386,7 +386,7 @@ export default class LslStreamInletTest extends AbstractPackageTest {
386
386
  protected static async pushSampleHandlesErrorCode() {
387
387
  let passedErrorCode: number | undefined
388
388
 
389
- StreamInletWorker.handleError = (errorCode: number) => {
389
+ StreamInletWorker.handleLslError = (errorCode: number) => {
390
390
  passedErrorCode = errorCode
391
391
  }
392
392
 
@@ -400,7 +400,7 @@ export default class LslStreamInletTest extends AbstractPackageTest {
400
400
  assert.isEqualDeep(
401
401
  passedErrorCode,
402
402
  FakeLiblsl.fakeErrorCode,
403
- 'Did not pass the expected error code to handleError!'
403
+ 'Did not pass the expected error code to handleLslError!'
404
404
  )
405
405
  }
406
406
 
@@ -7,7 +7,7 @@ import LslStreamOutlet, {
7
7
  StreamOutletOptions,
8
8
  } from '../../impl/LslStreamOutlet.js'
9
9
  import {
10
- setOutletHandleError,
10
+ setOutletHandleLslError,
11
11
  setOutletLiblslAdapter,
12
12
  } from '../../impl/workers/outlet/LslStreamOutlet.worker.js'
13
13
  import {
@@ -128,7 +128,7 @@ export default class LslStreamOutletTest extends AbstractPackageTest {
128
128
  maxBufferedMs: this.randomOutletOptions.maxBufferedMs,
129
129
  })
130
130
  assert.isNumber(
131
- this.fakeLiblsl.lastPushSampleFloatTimestampOptions?.timestamp
131
+ this.fakeLiblsl.lastPushSampleFloatTimestampOptions?.timestampSec
132
132
  )
133
133
  }
134
134
 
@@ -148,7 +148,7 @@ export default class LslStreamOutletTest extends AbstractPackageTest {
148
148
  sample
149
149
  )
150
150
  assert.isNumber(
151
- this.fakeLiblsl.lastPushSampleStringTimestampOptions?.timestamp
151
+ this.fakeLiblsl.lastPushSampleStringTimestampOptions?.timestampSec
152
152
  )
153
153
  }
154
154
 
@@ -159,13 +159,13 @@ export default class LslStreamOutletTest extends AbstractPackageTest {
159
159
 
160
160
  outlet.pushSample(sample)
161
161
  const t1 =
162
- this.fakeLiblsl.lastPushSampleStringTimestampOptions?.timestamp
162
+ this.fakeLiblsl.lastPushSampleStringTimestampOptions?.timestampSec
163
163
 
164
164
  await this.wait(10)
165
165
 
166
166
  outlet.pushSample(sample)
167
167
  const t2 =
168
- this.fakeLiblsl.lastPushSampleStringTimestampOptions?.timestamp
168
+ this.fakeLiblsl.lastPushSampleStringTimestampOptions?.timestampSec
169
169
 
170
170
  assert.isNotEqual(t1, t2)
171
171
  assert.isEqual(this.fakeLiblsl.localClockHitCount, 2)
@@ -227,13 +227,13 @@ export default class LslStreamOutletTest extends AbstractPackageTest {
227
227
  @test()
228
228
  protected static async pushSampleAcceptsOptionalPreciseTimestamp() {
229
229
  const outlet = await this.FloatOutlet()
230
- const fakeTimestamp = Math.random() * 1000
230
+ const timestampSec = Math.random() * 10000
231
231
 
232
- outlet.pushSample([1.0], fakeTimestamp)
232
+ outlet.pushSample([1.0], timestampSec)
233
233
 
234
234
  assert.isEqual(
235
- this.fakeLiblsl.lastPushSampleFloatTimestampOptions?.timestamp,
236
- fakeTimestamp
235
+ this.fakeLiblsl.lastPushSampleFloatTimestampOptions?.timestampSec,
236
+ timestampSec
237
237
  )
238
238
  }
239
239
 
@@ -241,7 +241,7 @@ export default class LslStreamOutletTest extends AbstractPackageTest {
241
241
  protected static async pushSampleHandlesErrorCode() {
242
242
  let passedErrorCode: number | undefined
243
243
 
244
- setOutletHandleError((errorCode: number) => {
244
+ setOutletHandleLslError((errorCode: number) => {
245
245
  passedErrorCode = errorCode
246
246
  })
247
247
 
@@ -265,11 +265,12 @@ export default class LslStreamOutletTest extends AbstractPackageTest {
265
265
 
266
266
  @test()
267
267
  protected static async waitsForTenMsAfterConstructionBeforeReturning() {
268
- const startMs = Date.now()
269
- await this.LslStreamOutlet({ waitAfterConstructionMs: 10 })
270
- const endMs = Date.now()
268
+ await this.LslStreamOutlet()
271
269
 
272
- assert.isAbove(endMs - startMs, 8)
270
+ assert.isTruthy(
271
+ this.callsToSetTimeout.includes(10),
272
+ 'Did not wait for 10ms after construction!'
273
+ )
273
274
  }
274
275
 
275
276
  @test()
@@ -1,4 +1,5 @@
1
- import { randomInt } from 'crypto'
1
+ import { randomInt } from 'node:crypto'
2
+
2
3
  import { test, assert } from '@neurodevs/node-tdd'
3
4
 
4
5
  import { StreamInletOptions } from '../../impl/LslStreamInlet.js'
@@ -152,7 +153,7 @@ export default class LslWebSocketBridgeTest extends AbstractPackageTest {
152
153
 
153
154
  await assert.doesThrowAsync(async () => {
154
155
  await this.activate()
155
- }, `\n\n Cannot activate bridge after destroying it! \n\n Please create and activate a new instance. \n`)
156
+ }, `\n\nCannot activate bridge after destroying it! \n\nPlease create and activate a new instance. \n`)
156
157
  }
157
158
 
158
159
  @test()
@@ -161,7 +162,7 @@ export default class LslWebSocketBridgeTest extends AbstractPackageTest {
161
162
 
162
163
  assert.doesThrow(() => {
163
164
  this.deactivate()
164
- }, `\n\n Cannot deactivate bridge after destroying it! \n\n Please create and activate a new instance. \n`)
165
+ }, `\n\nCannot deactivate bridge after destroying it! \n\nPlease create and activate a new instance. \n`)
165
166
  }
166
167
 
167
168
  @test()