@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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neurodevs/node-lsl",
3
- "version": "18.0.0",
3
+ "version": "19.0.0",
4
4
  "description": "Lab Streaming Layer (LSL) bindings for Node",
5
5
  "type": "module",
6
6
  "keywords": [
@@ -14,7 +14,7 @@
14
14
  "brain-computer interface"
15
15
  ],
16
16
  "license": "MIT",
17
- "author": "Eric Yates <hello@ericthecurious.com>",
17
+ "author": "Eric Yates <hello@ericyates.me>",
18
18
  "homepage": "https://github.com/neurodevs/node-lsl",
19
19
  "repository": {
20
20
  "type": "git",
@@ -25,10 +25,9 @@
25
25
  },
26
26
  "main": "build/index.js",
27
27
  "scripts": {
28
- "build.ci": "yarn run build.tsc && yarn run build.resolve-paths && yarn run lint",
29
- "build.dev": "yarn run build.tsc --sourceMap ; yarn run resolve-paths.lint",
28
+ "build.ci": "yarn run build.tsc && yarn run lint",
29
+ "build.dev": "yarn run build.tsc --sourceMap ; yarn run fix.lint ; prettier --write . --log-level warn",
30
30
  "build.copy-files": "mkdir -p build && rsync -avzq --exclude='*.ts' ./src/ ./build/",
31
- "build.resolve-paths": "resolve-path-aliases --target build --patterns '**/*.js,**/*.d.ts'",
32
31
  "build.tsc": "yarn run build.copy-files && tsc",
33
32
  "clean": "yarn run clean.build",
34
33
  "clean.all": "yarn run clean.dependencies && yarn run clean.build",
@@ -36,75 +35,38 @@
36
35
  "clean.dependencies": "rm -rf node_modules/ package-lock.json yarn.lock",
37
36
  "fix.lint": "eslint --fix --cache '**/*.ts'",
38
37
  "lint": "eslint --cache '**/*.ts'",
39
- "lint.tsc": "tsc -p . --noEmit",
40
- "post.watch.build": "yarn run build.copy-files && yarn run build.resolve-paths",
41
38
  "rebuild": "yarn run clean.all && yarn install && yarn run build.dev",
42
39
  "update.dependencies": "yarn run clean.dependencies && yarn",
43
- "resolve-paths.lint": "yarn run build.resolve-paths ; yarn run lint",
44
40
  "test": "NODE_OPTIONS=--experimental-vm-modules jest",
45
- "watch.build.dev": "tsc-watch --sourceMap --onCompilationComplete 'yarn run post.watch.build'",
46
- "watch.lint": "concurrently 'yarn lint' \"chokidar 'src/**/*' -c 'yarn lint.tsc'\"",
47
- "watch.rebuild": "yarn run clean.all && yarn install && yarn run watch.build.dev",
48
- "watch.tsc": "tsc -w",
49
- "test.rs": "node build/test.js"
41
+ "watch.build.dev": "tsc-watch --sourceMap --onCompilationComplete 'yarn run build.copy-files'"
50
42
  },
51
43
  "dependencies": {
52
- "@neurodevs/generate-id": "^1.1.2",
53
- "@neurodevs/ndx-native": "^0.2.0",
44
+ "@neurodevs/generate-id": "^1.1.3",
45
+ "@neurodevs/ndx-native": "^7.1.4",
54
46
  "ffi-rs": "^1.3.1",
55
- "node-gyp": "^12.1.0",
56
- "ref-array-napi": "^1.2.2",
57
- "ref-napi": "^3.0.3",
58
47
  "ws": "^8.18.3"
59
48
  },
60
49
  "devDependencies": {
61
- "@neurodevs/node-tdd": "0.2.5",
62
- "@regressionproof/cli": "^0.8.0",
63
- "@regressionproof/jest-reporter": "^0.8.0",
64
- "@types/ffi-napi": "^4.0.10",
65
- "@types/node": "^25.0.2",
50
+ "@neurodevs/eslint-config-ndx": "^1.0.2",
51
+ "@neurodevs/node-tdd": "^3.0.1",
52
+ "@neurodevs/prettier-config-ndx": "^1.0.2",
66
53
  "@types/ws": "^8.18.1",
67
- "chokidar-cli": "^3.0.0",
68
- "concurrently": "^9.2.1",
69
- "eslint": "8.57.0",
70
- "eslint-config-spruce": "^11.2.26",
71
- "jest": "^30.2.0",
72
- "jest-circus": "^30.2.0",
73
- "prettier": "^3.7.4",
74
- "ts-node": "^10.9.2",
75
- "tsc-watch": "^7.2.0",
54
+ "prettier": "^3.9.4",
76
55
  "typescript": "^5.9.3"
77
56
  },
57
+ "resolutions": {
58
+ "glob": "^13.0.0"
59
+ },
78
60
  "jest": {
79
- "testRunner": "jest-circus/runner",
80
- "maxWorkers": 4,
81
- "testTimeout": 120000,
82
61
  "testEnvironment": "node",
83
- "extensionsToTreatAsEsm": [
84
- ".ts"
85
- ],
86
- "transform": {},
87
- "testPathIgnorePatterns": [
88
- "<rootDir>/tmp/",
89
- "<rootDir>/src/",
90
- "<rootDir>/node_modules/",
91
- "<rootDir>/build/__tests__/testDirsAndFiles/"
92
- ],
62
+ "testRunner": "jest-circus/runner",
93
63
  "testMatch": [
94
- "**/__tests__/**/*.test.js?(x)"
64
+ "<rootDir>/build/__tests__/**/*.test.js?(x)"
95
65
  ],
96
- "moduleNameMapper": {
97
- "^#spruce/(.*)$": "<rootDir>/build/.spruce/$1"
98
- },
66
+ "testTimeout": 5000,
67
+ "maxWorkers": 4,
99
68
  "reporters": [
100
- "default",
101
- "@regressionproof/jest-reporter"
102
- ]
103
- },
104
- "skill": {
105
- "namespace": "node-lsl",
106
- "upgradeIgnoreList": [
107
- "@sprucelabs/spruce-test-fixtures"
69
+ "default"
108
70
  ]
109
71
  }
110
72
  }
@@ -0,0 +1,3 @@
1
+ import prettierConfigNdx from '@neurodevs/prettier-config-ndx'
2
+
3
+ export default prettierConfigNdx
@@ -1,15 +1,15 @@
1
- import { FakeLiblsl, InfoHandle, LiblslAdapter } from '@neurodevs/ndx-native'
2
- import AbstractModuleTest from '@neurodevs/node-tdd'
1
+ import { randomInt } from 'node:crypto'
2
+
3
3
  import WebSocket, { Server } from 'ws'
4
+ import {
5
+ FakeLiblsl,
6
+ FakeLibndx,
7
+ InfoHandle,
8
+ LiblslAdapter,
9
+ LibndxAdapter,
10
+ } from '@neurodevs/ndx-native'
11
+ import AbstractModuleTest from '@neurodevs/node-tdd'
4
12
 
5
- import LslEventMarkerEmitter from '../impl/LslEventMarkerEmitter.js'
6
- import LslStreamInfo from '../impl/LslStreamInfo.js'
7
- import LslStreamInlet, {
8
- OnDataCallback,
9
- StreamInletOptions,
10
- } from '../impl/LslStreamInlet.js'
11
- import LslStreamOutlet from '../impl/LslStreamOutlet.js'
12
- import LslWebSocketBridge from '../impl/LslWebSocketBridge.js'
13
13
  import SpyEventMarkerEmitter from '../testDoubles/EventMarkerEmitter/SpyEventMarkerEmitter.js'
14
14
  import FakeStreamInfo from '../testDoubles/StreamInfo/FakeStreamInfo.js'
15
15
  import SpyStreamInfo from '../testDoubles/StreamInfo/SpyStreamInfo.js'
@@ -19,12 +19,45 @@ import FakeStreamOutlet from '../testDoubles/StreamOutlet/FakeStreamOutlet.js'
19
19
  import SpyLslWebSocketBridge from '../testDoubles/WebSocketBridge/SpyLslWebSocketBridge.js'
20
20
  import FakeWebSocket from '../testDoubles/WebSockets/FakeWebSocket.js'
21
21
  import FakeWebSocketServer from '../testDoubles/WebSockets/FakeWebSocketServer.js'
22
+ import LslWebSocketBridge from '../impl/LslWebSocketBridge.js'
23
+ import BleDeviceController from '../impl/controllers/BleDeviceController.js'
24
+ import LslEventMarkerEmitter from '../impl/LslEventMarkerEmitter.js'
25
+ import LslStreamInfo from '../impl/LslStreamInfo.js'
26
+ import LslStreamInlet, {
27
+ OnDataCallback,
28
+ StreamInletOptions,
29
+ } from '../impl/LslStreamInlet.js'
30
+ import LslStreamOutlet from '../impl/LslStreamOutlet.js'
22
31
 
23
32
  export default class AbstractPackageTest extends AbstractModuleTest {
24
33
  protected static fakeLiblsl: FakeLiblsl
34
+ protected static fakeLibndx: FakeLibndx
35
+
36
+ protected static readonly fakeStreamInfo = new FakeStreamInfo()
37
+
38
+ protected static readonly name_ = this.generateId()
39
+ protected static readonly type = this.generateId()
40
+ protected static readonly sourceId = this.generateId()
41
+ protected static readonly units = this.generateId()
42
+
43
+ protected static readonly channelNames = [
44
+ this.generateId(),
45
+ this.generateId(),
46
+ this.generateId(),
47
+ ]
48
+
49
+ protected static readonly channelCount = this.channelNames.length
50
+
51
+ protected static readonly chunkSize = randomInt(2, 100)
52
+ protected static readonly sampleRateHz = Math.floor(Math.random() * 100)
53
+ protected static readonly maxBufferedMs = Math.floor(Math.random() * 1000)
25
54
 
26
55
  protected static async beforeEach() {
27
56
  await super.beforeEach()
57
+
58
+ this.setImmediateTimeouts()
59
+
60
+ this.setFakeLibndx()
28
61
  }
29
62
 
30
63
  protected static setFakeLiblsl() {
@@ -35,6 +68,49 @@ export default class AbstractPackageTest extends AbstractModuleTest {
35
68
  FakeLiblsl.fakeInfoHandles = [{} as InfoHandle]
36
69
  }
37
70
 
71
+ protected static callsToSetTimeout: number[] = []
72
+
73
+ protected static setImmediateTimeouts() {
74
+ this.callsToSetTimeout = []
75
+
76
+ BleDeviceController.setTimeout = ((
77
+ callback: (...args: unknown[]) => void,
78
+ delayMs?: number,
79
+ ...args: unknown[]
80
+ ) => {
81
+ this.callsToSetTimeout.push(delayMs ?? 0)
82
+ return setTimeout(callback, 0, ...args)
83
+ }) as unknown as typeof setTimeout
84
+
85
+ LslStreamOutlet.setTimeout = ((
86
+ callback: (...args: unknown[]) => void,
87
+ delayMs?: number,
88
+ ...args: unknown[]
89
+ ) => {
90
+ this.callsToSetTimeout.push(delayMs ?? 0)
91
+ return setTimeout(callback, 0, ...args)
92
+ }) as unknown as typeof setTimeout
93
+
94
+ LslStreamInlet.setTimeout = ((
95
+ callback: (...args: unknown[]) => void,
96
+ delayMs?: number,
97
+ ...args: unknown[]
98
+ ) => {
99
+ this.callsToSetTimeout.push(delayMs ?? 0)
100
+ return setTimeout(callback, 0, ...args)
101
+ }) as unknown as typeof setTimeout
102
+ }
103
+
104
+ protected static setFakeLibndx() {
105
+ this.fakeLibndx = new FakeLibndx()
106
+ LibndxAdapter.setInstance(this.fakeLibndx)
107
+
108
+ FakeLibndx.resetTestDouble()
109
+ FakeLibndx.fakeResult = { status: 200 }
110
+
111
+ BleDeviceController.ndx = this.fakeLibndx
112
+ }
113
+
38
114
  protected static setSpyStreamInfo() {
39
115
  LslStreamInfo.Class = SpyStreamInfo
40
116
  SpyStreamInfo.resetTestDouble()
@@ -77,25 +153,6 @@ export default class AbstractPackageTest extends AbstractModuleTest {
77
153
  FakeWebSocketServer.resetTestDouble()
78
154
  }
79
155
 
80
- protected static readonly fakeStreamInfo = new FakeStreamInfo()
81
-
82
- protected static readonly name_ = this.generateId()
83
- protected static readonly type = this.generateId()
84
- protected static readonly sourceId = this.generateId()
85
- protected static readonly units = this.generateId()
86
-
87
- protected static readonly channelNames = [
88
- this.generateId(),
89
- this.generateId(),
90
- this.generateId(),
91
- ]
92
-
93
- protected static readonly channelCount = this.channelNames.length
94
-
95
- protected static readonly chunkSize = 2
96
- protected static readonly sampleRateHz = Math.floor(Math.random() * 100)
97
- protected static readonly maxBufferedMs = Math.floor(Math.random() * 1000)
98
-
99
156
  protected static async LslStreamInlet(
100
157
  options: Partial<StreamInletOptions>,
101
158
  onData: OnDataCallback