@neurodevs/node-lsl 11.4.1 → 12.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 (175) hide show
  1. package/.vscode/tasks.json +19 -1
  2. package/README.md +44 -34
  3. package/build/.spruce/settings.json +1 -3
  4. package/build/__tests__/{AbstractLslTest.d.ts → AbstractPackageTest.d.ts} +6 -4
  5. package/build/__tests__/AbstractPackageTest.js +58 -0
  6. package/build/__tests__/AbstractPackageTest.js.map +1 -0
  7. package/build/__tests__/{modules → impl}/LiblslAdapter.test.d.ts +5 -8
  8. package/build/__tests__/{modules → impl}/LiblslAdapter.test.js +37 -86
  9. package/build/__tests__/impl/LiblslAdapter.test.js.map +1 -0
  10. package/build/__tests__/{modules/EventMarkerOutlet.test.d.ts → impl/LslEventMarkerOutlet.test.d.ts} +5 -4
  11. package/build/__tests__/{modules/EventMarkerOutlet.test.js → impl/LslEventMarkerOutlet.test.js} +32 -25
  12. package/build/__tests__/impl/LslEventMarkerOutlet.test.js.map +1 -0
  13. package/build/__tests__/{modules → impl}/LslStreamInfo.test.d.ts +3 -4
  14. package/build/__tests__/{modules → impl}/LslStreamInfo.test.js +17 -27
  15. package/build/__tests__/impl/LslStreamInfo.test.js.map +1 -0
  16. package/build/__tests__/impl/LslStreamInlet.test.d.ts +10 -0
  17. package/build/__tests__/{modules → impl}/LslStreamInlet.test.js +9 -26
  18. package/build/__tests__/impl/LslStreamInlet.test.js.map +1 -0
  19. package/build/__tests__/{modules → impl}/LslStreamOutlet.test.d.ts +9 -7
  20. package/build/__tests__/{modules → impl}/LslStreamOutlet.test.js +40 -57
  21. package/build/__tests__/impl/LslStreamOutlet.test.js.map +1 -0
  22. package/build/__tests__/impl/LslWebSocketBridge.test.d.ts +7 -0
  23. package/build/__tests__/impl/LslWebSocketBridge.test.js +63 -0
  24. package/build/__tests__/impl/LslWebSocketBridge.test.js.map +1 -0
  25. package/build/assertions.d.ts +1 -1
  26. package/build/assertions.js +10 -31
  27. package/build/assertions.js.map +1 -1
  28. package/build/{modules → impl}/LiblslAdapter.d.ts +3 -1
  29. package/build/{modules → impl}/LiblslAdapter.js +15 -44
  30. package/build/impl/LiblslAdapter.js.map +1 -0
  31. package/build/impl/LslEventMarkerOutlet.d.ts +23 -0
  32. package/build/{modules/EventMarkerOutlet.js → impl/LslEventMarkerOutlet.js} +6 -6
  33. package/build/impl/LslEventMarkerOutlet.js.map +1 -0
  34. package/build/{modules → impl}/LslStreamInfo.js +4 -6
  35. package/build/impl/LslStreamInfo.js.map +1 -0
  36. package/build/{modules → impl}/LslStreamInlet.d.ts +8 -8
  37. package/build/{modules → impl}/LslStreamInlet.js +6 -14
  38. package/build/impl/LslStreamInlet.js.map +1 -0
  39. package/build/{modules → impl}/LslStreamOutlet.d.ts +8 -8
  40. package/build/{modules → impl}/LslStreamOutlet.js +2 -15
  41. package/build/impl/LslStreamOutlet.js.map +1 -0
  42. package/build/impl/LslWebSocketBridge.d.ts +8 -0
  43. package/build/impl/LslWebSocketBridge.js +10 -0
  44. package/build/impl/LslWebSocketBridge.js.map +1 -0
  45. package/build/index.d.ts +26 -22
  46. package/build/index.js +41 -34
  47. package/build/index.js.map +1 -1
  48. package/build/scripts/runLslEventMarkerOutlet.d.ts +1 -0
  49. package/build/scripts/runLslEventMarkerOutlet.js +23 -0
  50. package/build/scripts/runLslEventMarkerOutlet.js.map +1 -0
  51. package/build/scripts/runLslStreamOutlet.d.ts +1 -0
  52. package/build/scripts/runLslStreamOutlet.js +25 -0
  53. package/build/scripts/runLslStreamOutlet.js.map +1 -0
  54. package/build/testDoubles/{MarkerOutlet/FakeMarkerOutlet.d.ts → EventMarkerOutlet/FakeEventMarkerOutlet.d.ts} +2 -2
  55. package/build/testDoubles/EventMarkerOutlet/FakeEventMarkerOutlet.js +29 -0
  56. package/build/testDoubles/EventMarkerOutlet/FakeEventMarkerOutlet.js.map +1 -0
  57. package/build/testDoubles/{MarkerOutlet/MockMarkerOutlet.d.ts → EventMarkerOutlet/MockEventMarkerOutlet.d.ts} +2 -2
  58. package/build/testDoubles/{MarkerOutlet/MockMarkerOutlet.js → EventMarkerOutlet/MockEventMarkerOutlet.js} +3 -3
  59. package/build/testDoubles/EventMarkerOutlet/MockEventMarkerOutlet.js.map +1 -0
  60. package/build/testDoubles/EventMarkerOutlet/SpyEventMarkerOutlet.d.ts +9 -0
  61. package/build/testDoubles/{MarkerOutlet/SpyMarkerOutlet.js → EventMarkerOutlet/SpyEventMarkerOutlet.js} +8 -8
  62. package/build/testDoubles/EventMarkerOutlet/SpyEventMarkerOutlet.js.map +1 -0
  63. package/build/testDoubles/{MarkerOutlet/ThrowingMarkerOutlet.d.ts → EventMarkerOutlet/ThrowingEventMarkerOutlet.d.ts} +2 -2
  64. package/build/testDoubles/{MarkerOutlet/ThrowingMarkerOutlet.js → EventMarkerOutlet/ThrowingEventMarkerOutlet.js} +3 -3
  65. package/build/testDoubles/EventMarkerOutlet/ThrowingEventMarkerOutlet.js.map +1 -0
  66. package/build/testDoubles/StreamInfo/FakeStreamInfo.d.ts +1 -1
  67. package/build/testDoubles/StreamInfo/SpyStreamInfo.d.ts +1 -1
  68. package/build/testDoubles/StreamInfo/SpyStreamInfo.js +1 -1
  69. package/build/testDoubles/StreamInfo/SpyStreamInfo.js.map +1 -1
  70. package/build/testDoubles/StreamInlet/FakeStreamInlet.d.ts +10 -0
  71. package/build/testDoubles/StreamInlet/FakeStreamInlet.js +16 -0
  72. package/build/testDoubles/StreamInlet/FakeStreamInlet.js.map +1 -0
  73. package/build/testDoubles/StreamInlet/SpyStreamInlet.d.ts +7 -0
  74. package/build/testDoubles/{LslInlet/SpyLslInlet.js → StreamInlet/SpyStreamInlet.js} +5 -5
  75. package/build/testDoubles/StreamInlet/SpyStreamInlet.js.map +1 -0
  76. package/build/testDoubles/{LslOutlet/FakeLslOutlet.d.ts → StreamOutlet/FakeStreamOutlet.d.ts} +9 -10
  77. package/build/testDoubles/StreamOutlet/FakeStreamOutlet.js +62 -0
  78. package/build/testDoubles/StreamOutlet/FakeStreamOutlet.js.map +1 -0
  79. package/build/testDoubles/StreamTransportBridge/FakeStreamTransportBridge.d.ts +6 -0
  80. package/build/testDoubles/StreamTransportBridge/FakeStreamTransportBridge.js +13 -0
  81. package/build/testDoubles/StreamTransportBridge/FakeStreamTransportBridge.js.map +1 -0
  82. package/build/testDoubles/generateRandomOutletOptions.d.ts +2 -2
  83. package/build/testDoubles/generateRandomOutletOptions.js +10 -7
  84. package/build/testDoubles/generateRandomOutletOptions.js.map +1 -1
  85. package/build/types.d.ts +3 -3
  86. package/package.json +26 -18
  87. package/src/.spruce/settings.json +1 -3
  88. package/src/__tests__/{AbstractLslTest.ts → AbstractPackageTest.ts} +23 -17
  89. package/src/__tests__/{modules → impl}/LiblslAdapter.test.ts +36 -76
  90. package/src/__tests__/{modules/EventMarkerOutlet.test.ts → impl/LslEventMarkerOutlet.test.ts} +38 -27
  91. package/src/__tests__/{modules → impl}/LslStreamInfo.test.ts +7 -17
  92. package/src/__tests__/{modules → impl}/LslStreamInlet.test.ts +13 -30
  93. package/src/__tests__/{modules → impl}/LslStreamOutlet.test.ts +71 -63
  94. package/src/__tests__/impl/LslWebSocketBridge.test.ts +23 -0
  95. package/src/assertions.ts +19 -30
  96. package/src/{modules → impl}/LiblslAdapter.ts +18 -44
  97. package/src/{modules/EventMarkerOutlet.ts → impl/LslEventMarkerOutlet.ts} +16 -11
  98. package/src/{modules → impl}/LslStreamInfo.ts +1 -3
  99. package/src/{modules → impl}/LslStreamInlet.ts +14 -22
  100. package/src/{modules → impl}/LslStreamOutlet.ts +12 -26
  101. package/src/impl/LslWebSocketBridge.ts +13 -0
  102. package/src/index.ts +37 -29
  103. package/src/scripts/runLslEventMarkerOutlet.ts +23 -0
  104. package/src/scripts/runLslStreamOutlet.ts +22 -0
  105. package/src/testDoubles/{MarkerOutlet/FakeMarkerOutlet.ts → EventMarkerOutlet/FakeEventMarkerOutlet.ts} +6 -6
  106. package/src/testDoubles/{MarkerOutlet/MockMarkerOutlet.ts → EventMarkerOutlet/MockEventMarkerOutlet.ts} +2 -2
  107. package/src/testDoubles/EventMarkerOutlet/SpyEventMarkerOutlet.ts +24 -0
  108. package/src/testDoubles/{MarkerOutlet/ThrowingMarkerOutlet.ts → EventMarkerOutlet/ThrowingEventMarkerOutlet.ts} +2 -2
  109. package/src/testDoubles/StreamInfo/FakeStreamInfo.ts +1 -1
  110. package/src/testDoubles/StreamInfo/SpyStreamInfo.ts +1 -1
  111. package/src/testDoubles/StreamInlet/FakeStreamInlet.ts +20 -0
  112. package/src/testDoubles/StreamInlet/SpyStreamInlet.ts +16 -0
  113. package/src/testDoubles/{LslOutlet/FakeLslOutlet.ts → StreamOutlet/FakeStreamOutlet.ts} +17 -18
  114. package/src/testDoubles/StreamTransportBridge/FakeStreamTransportBridge.ts +15 -0
  115. package/src/testDoubles/generateRandomOutletOptions.ts +3 -3
  116. package/src/types.ts +3 -3
  117. package/build/.spruce/errors/errors.types.d.ts +0 -21
  118. package/build/.spruce/errors/errors.types.js +0 -3
  119. package/build/.spruce/errors/errors.types.js.map +0 -1
  120. package/build/.spruce/errors/nodeLsl/failedToLoadLiblsl.schema.d.ts +0 -3
  121. package/build/.spruce/errors/nodeLsl/failedToLoadLiblsl.schema.js +0 -19
  122. package/build/.spruce/errors/nodeLsl/failedToLoadLiblsl.schema.js.map +0 -1
  123. package/build/.spruce/errors/options.types.d.ts +0 -7
  124. package/build/.spruce/errors/options.types.js +0 -3
  125. package/build/.spruce/errors/options.types.js.map +0 -1
  126. package/build/.spruce/schemas/fields/fieldClassMap.d.ts +0 -2
  127. package/build/.spruce/schemas/fields/fieldClassMap.js +0 -5
  128. package/build/.spruce/schemas/fields/fieldClassMap.js.map +0 -1
  129. package/build/.spruce/schemas/fields/fields.types.d.ts +0 -1
  130. package/build/.spruce/schemas/fields/fields.types.js +0 -3
  131. package/build/.spruce/schemas/fields/fields.types.js.map +0 -1
  132. package/build/__tests__/AbstractLslTest.js +0 -86
  133. package/build/__tests__/AbstractLslTest.js.map +0 -1
  134. package/build/__tests__/modules/EventMarkerOutlet.test.js.map +0 -1
  135. package/build/__tests__/modules/LiblslAdapter.test.js.map +0 -1
  136. package/build/__tests__/modules/LslStreamInfo.test.js.map +0 -1
  137. package/build/__tests__/modules/LslStreamInlet.test.d.ts +0 -11
  138. package/build/__tests__/modules/LslStreamInlet.test.js.map +0 -1
  139. package/build/__tests__/modules/LslStreamOutlet.test.js.map +0 -1
  140. package/build/errors/SpruceError.d.ts +0 -6
  141. package/build/errors/SpruceError.js +0 -26
  142. package/build/errors/SpruceError.js.map +0 -1
  143. package/build/errors/failedToLoadLiblsl.builder.d.ts +0 -11
  144. package/build/errors/failedToLoadLiblsl.builder.js +0 -14
  145. package/build/errors/failedToLoadLiblsl.builder.js.map +0 -1
  146. package/build/modules/EventMarkerOutlet.d.ts +0 -23
  147. package/build/modules/EventMarkerOutlet.js.map +0 -1
  148. package/build/modules/LiblslAdapter.js.map +0 -1
  149. package/build/modules/LslStreamInfo.js.map +0 -1
  150. package/build/modules/LslStreamInlet.js.map +0 -1
  151. package/build/modules/LslStreamOutlet.js.map +0 -1
  152. package/build/testDoubles/LslInlet/FakeLslInlet.d.ts +0 -11
  153. package/build/testDoubles/LslInlet/FakeLslInlet.js +0 -16
  154. package/build/testDoubles/LslInlet/FakeLslInlet.js.map +0 -1
  155. package/build/testDoubles/LslInlet/SpyLslInlet.d.ts +0 -7
  156. package/build/testDoubles/LslInlet/SpyLslInlet.js.map +0 -1
  157. package/build/testDoubles/LslOutlet/FakeLslOutlet.js +0 -59
  158. package/build/testDoubles/LslOutlet/FakeLslOutlet.js.map +0 -1
  159. package/build/testDoubles/MarkerOutlet/FakeMarkerOutlet.js +0 -29
  160. package/build/testDoubles/MarkerOutlet/FakeMarkerOutlet.js.map +0 -1
  161. package/build/testDoubles/MarkerOutlet/MockMarkerOutlet.js.map +0 -1
  162. package/build/testDoubles/MarkerOutlet/SpyMarkerOutlet.d.ts +0 -9
  163. package/build/testDoubles/MarkerOutlet/SpyMarkerOutlet.js.map +0 -1
  164. package/build/testDoubles/MarkerOutlet/ThrowingMarkerOutlet.js.map +0 -1
  165. package/src/.spruce/errors/errors.types.ts +0 -37
  166. package/src/.spruce/errors/nodeLsl/failedToLoadLiblsl.schema.ts +0 -22
  167. package/src/.spruce/errors/options.types.ts +0 -10
  168. package/src/.spruce/schemas/fields/fieldClassMap.ts +0 -6
  169. package/src/.spruce/schemas/fields/fields.types.ts +0 -1
  170. package/src/errors/SpruceError.ts +0 -23
  171. package/src/errors/failedToLoadLiblsl.builder.ts +0 -12
  172. package/src/testDoubles/LslInlet/FakeLslInlet.ts +0 -22
  173. package/src/testDoubles/LslInlet/SpyLslInlet.ts +0 -16
  174. package/src/testDoubles/MarkerOutlet/SpyMarkerOutlet.ts +0 -24
  175. /package/build/{modules → impl}/LslStreamInfo.d.ts +0 -0
@@ -1,41 +1,24 @@
1
- import { test, assert, errorAssert } from '@sprucelabs/test-utils'
2
- import LslStreamInlet, { LslInletOptions } from '../../modules/LslStreamInlet'
3
- import { SpyLslInlet } from '../../testDoubles/LslInlet/SpyLslInlet'
1
+ import { test, assert } from '@sprucelabs/test-utils'
2
+ import LslStreamInlet, { StreamInletOptions } from '../../impl/LslStreamInlet'
4
3
  import FakeStreamInfo from '../../testDoubles/StreamInfo/FakeStreamInfo'
5
- import AbstractLslTest from '../AbstractLslTest'
4
+ import { SpyStreamInlet } from '../../testDoubles/StreamInlet/SpyStreamInlet'
5
+ import AbstractPackageTest from '../AbstractPackageTest'
6
6
 
7
- export default class LslStreamInletTest extends AbstractLslTest {
8
- private static instance: SpyLslInlet
7
+ export default class LslStreamInletTest extends AbstractPackageTest {
8
+ private static instance: SpyStreamInlet
9
9
 
10
10
  protected static async beforeEach() {
11
11
  await super.beforeEach()
12
12
 
13
- this.setSpyLslInlet()
13
+ this.setSpyStreamInlet()
14
14
  this.setFakeStreamInfo()
15
15
 
16
16
  this.instance = this.LslStreamInlet()
17
17
  }
18
18
 
19
19
  @test()
20
- protected static async canCreateLslStreamInlet() {
21
- assert.isTruthy(this.instance, 'Instance should be created!')
22
- }
23
-
24
- @test()
25
- protected static async throwsWithMissingRequiredOptions() {
26
- const err = assert.doesThrow(
27
- // @ts-ignore
28
- () => LslStreamInlet.Create()
29
- )
30
- errorAssert.assertError(err, 'MISSING_PARAMETERS', {
31
- parameters: [
32
- 'channelNames',
33
- 'channelFormat',
34
- 'sampleRate',
35
- 'chunkSize',
36
- 'maxBuffered',
37
- ],
38
- })
20
+ protected static async createsInstance() {
21
+ assert.isTruthy(this.instance, 'Failed to create instance!')
39
22
  }
40
23
 
41
24
  @test()
@@ -66,7 +49,7 @@ export default class LslStreamInletTest extends AbstractLslTest {
66
49
  }
67
50
 
68
51
  @test()
69
- protected static async callsBindingsToCreateLslInlet() {
52
+ protected static async callsBindingsToCreateStreamInlet() {
70
53
  const fakeInfo = this.instance.getStreamInfo()
71
54
 
72
55
  assert.isTruthy(fakeInfo, 'Should have created stream info!')
@@ -82,7 +65,7 @@ export default class LslStreamInletTest extends AbstractLslTest {
82
65
  )
83
66
  }
84
67
 
85
- private static LslStreamInlet(options?: Partial<LslInletOptions>) {
68
+ private static LslStreamInlet(options?: Partial<StreamInletOptions>) {
86
69
  const defaultOptions = {
87
70
  channelNames: this.channelNames,
88
71
  channelFormat: 'float32',
@@ -93,7 +76,7 @@ export default class LslStreamInletTest extends AbstractLslTest {
93
76
  chunkSize: this.chunkSize,
94
77
  maxBuffered: this.maxBuffered,
95
78
  ...options,
96
- } as LslInletOptions
97
- return LslStreamInlet.Create(defaultOptions) as SpyLslInlet
79
+ } as StreamInletOptions
80
+ return LslStreamInlet.Create(defaultOptions) as SpyStreamInlet
98
81
  }
99
82
  }
@@ -1,8 +1,10 @@
1
- import { test, assert, errorAssert, generateId } from '@sprucelabs/test-utils'
2
- import { StreamInfo } from '../../modules/LslStreamInfo'
1
+ import { test, assert } from '@sprucelabs/test-utils'
2
+ import generateId from '@neurodevs/generate-id'
3
+ import { CHANNEL_FORMATS } from '../../consts'
4
+ import { StreamInfo } from '../../impl/LslStreamInfo'
3
5
  import LslStreamOutlet, {
4
- LslOutletOptions,
5
- } from '../../modules/LslStreamOutlet'
6
+ StreamOutletOptions,
7
+ } from '../../impl/LslStreamOutlet'
6
8
  import {
7
9
  TEST_SUPPORTED_CHANNEL_FORMATS,
8
10
  TEST_UNSUPPORTED_CHANNEL_FORMATS,
@@ -11,11 +13,11 @@ import {
11
13
 
12
14
  import generateRandomOutletOptions from '../../testDoubles/generateRandomOutletOptions'
13
15
  import FakeStreamInfo from '../../testDoubles/StreamInfo/FakeStreamInfo'
14
- import { LslSample } from '../../types'
15
- import AbstractLslTest from '../AbstractLslTest'
16
+ import { ChannelFormat, LslSample } from '../../types'
17
+ import AbstractPackageTest from '../AbstractPackageTest'
16
18
 
17
- export default class LslStreamOutletTest extends AbstractLslTest {
18
- private static randomOutletOptions: LslOutletOptions
19
+ export default class LslStreamOutletTest extends AbstractPackageTest {
20
+ private static randomOutletOptions: StreamOutletOptions
19
21
 
20
22
  protected static async beforeEach() {
21
23
  await super.beforeEach()
@@ -29,30 +31,8 @@ export default class LslStreamOutletTest extends AbstractLslTest {
29
31
  }
30
32
 
31
33
  @test()
32
- protected static async throwsWithMissingRequiredParams() {
33
- const err = await assert.doesThrowAsync(
34
- //@ts-ignore
35
- async () => await LslStreamOutlet.Create()
36
- )
37
- errorAssert.assertError(err, 'MISSING_PARAMETERS', {
38
- parameters: [
39
- 'name',
40
- 'type',
41
- 'sourceId',
42
- 'channelNames',
43
- 'channelFormat',
44
- 'sampleRate',
45
- 'chunkSize',
46
- 'maxBuffered',
47
- 'manufacturer',
48
- 'unit',
49
- ],
50
- })
51
- }
52
-
53
- @test()
54
- protected static async throwsWithInvalidChannelNames() {
55
- await this.assertThrowsInvalidChannelNames(0)
34
+ protected static async throwsWithEmptyChannelNames() {
35
+ await this.assertThrowsWithEmptyChannelNames()
56
36
  }
57
37
 
58
38
  @test()
@@ -68,24 +48,30 @@ export default class LslStreamOutletTest extends AbstractLslTest {
68
48
 
69
49
  @test()
70
50
  protected static async throwsWithInvalidChannelFormat() {
71
- await this.assertDoesThrowInvalidParameters(
72
- //@ts-ignore
73
- { channelFormat: generateId() },
74
- ['channelFormat']
51
+ await this.assertThrowsInvalidChannelFormat(
52
+ 'invalid-format' as ChannelFormat
75
53
  )
76
54
  }
77
55
 
78
56
  @test()
79
- protected static async throwsWithInvalidChunkSize() {
57
+ protected static async allowsZeroChunkSize() {
80
58
  await this.LslStreamOutlet({ chunkSize: 0 })
59
+ }
60
+
61
+ @test()
62
+ protected static async throwsWithInvalidChunkSize() {
81
63
  await this.assertThrowsInvalidChunkSize(-1)
82
64
  await this.assertThrowsInvalidChunkSize(-1.5)
83
65
  await this.assertThrowsInvalidChunkSize(1.5)
84
66
  }
85
67
 
86
68
  @test()
87
- protected static async throwsWithInvalidMaxBuffered() {
69
+ protected static async allowsZeroMaxBuffered() {
88
70
  await this.LslStreamOutlet({ maxBuffered: 0 })
71
+ }
72
+
73
+ @test()
74
+ protected static async throwsWithInvalidMaxBuffered() {
89
75
  await this.assertThrowsInvalidMaxBuffered(-1)
90
76
  await this.assertThrowsInvalidMaxBuffered(-1.5)
91
77
  await this.assertThrowsInvalidMaxBuffered(1.5)
@@ -226,41 +212,61 @@ export default class LslStreamOutletTest extends AbstractLslTest {
226
212
  assert.isAbove(endMs - startMs, 10)
227
213
  }
228
214
 
229
- private static async assertThrowsInvalidMaxBuffered(maxBuffered: number) {
230
- await this.assertDoesThrowInvalidParameters({ maxBuffered }, [
231
- 'maxBuffered',
232
- ])
233
- }
234
-
235
- private static async assertThrowsInvalidChunkSize(chunkSize: number) {
236
- await this.assertDoesThrowInvalidParameters({ chunkSize }, [
237
- 'chunkSize',
238
- ])
215
+ private static async assertThrowsWithEmptyChannelNames() {
216
+ await this.createAndAssertThrows(
217
+ 'channelNames',
218
+ [],
219
+ `Invalid channel count! Must be a positive integer, not: 0.`
220
+ )
239
221
  }
240
222
 
241
223
  private static async assertThrowsInvalidSampleRate(sampleRate: number) {
242
- await this.assertDoesThrowInvalidParameters({ sampleRate }, [
224
+ await this.createAndAssertThrows(
243
225
  'sampleRate',
244
- ])
226
+ sampleRate,
227
+ `Invalid sample rate! Must be a positive number or zero, not: ${sampleRate}`
228
+ )
229
+ }
230
+
231
+ private static async assertThrowsInvalidChannelFormat(
232
+ channelFormat: ChannelFormat
233
+ ) {
234
+ await this.createAndAssertThrows(
235
+ 'channelFormat',
236
+ channelFormat,
237
+ `Invalid channel format! Must be one of: ${CHANNEL_FORMATS.join(', ')}, not ${channelFormat}.`
238
+ )
245
239
  }
246
240
 
247
- private static async assertThrowsInvalidChannelNames(count: number) {
248
- await this.assertDoesThrowInvalidParameters(
249
- { channelNames: new Array(count).fill(generateId()) },
250
- ['channelNames']
241
+ private static async assertThrowsInvalidMaxBuffered(maxBuffered: number) {
242
+ await this.createAndAssertThrows(
243
+ 'maxBuffered',
244
+ maxBuffered,
245
+ `Invalid max buffered! Must be a positive integer or zero, not: ${maxBuffered}`
251
246
  )
252
247
  }
253
248
 
254
- private static async assertDoesThrowInvalidParameters(
255
- options: Partial<LslOutletOptions>,
256
- parameters: string[]
249
+ private static async assertThrowsInvalidChunkSize(chunkSize: number) {
250
+ await this.createAndAssertThrows(
251
+ 'chunkSize',
252
+ chunkSize,
253
+ `Invalid chunk size! Must be a positive integer or zero, not: ${chunkSize}`
254
+ )
255
+ }
256
+
257
+ private static async createAndAssertThrows(
258
+ option: keyof StreamOutletOptions,
259
+ value: number | string[] | ChannelFormat,
260
+ expectedMessage: string
257
261
  ) {
258
262
  const err = await assert.doesThrowAsync(
259
- async () => await this.LslStreamOutlet(options)
263
+ async () => await this.LslStreamOutlet({ [option]: value })
264
+ )
265
+
266
+ assert.isTrue(
267
+ err.message.includes(expectedMessage),
268
+ 'Did not receive the expected error!'
260
269
  )
261
- errorAssert.assertError(err, 'INVALID_PARAMETERS', {
262
- parameters,
263
- })
264
270
  }
265
271
 
266
272
  private static async StringOutlet() {
@@ -271,7 +277,9 @@ export default class LslStreamOutletTest extends AbstractLslTest {
271
277
  return await this.LslStreamOutlet({ channelFormat: 'float32' })
272
278
  }
273
279
 
274
- private static async LslStreamOutlet(options?: Partial<LslOutletOptions>) {
280
+ private static async LslStreamOutlet(
281
+ options?: Partial<StreamOutletOptions>
282
+ ) {
275
283
  return await LslStreamOutlet.Create({
276
284
  ...this.randomOutletOptions,
277
285
  ...options,
@@ -280,7 +288,7 @@ export default class LslStreamOutletTest extends AbstractLslTest {
280
288
  }
281
289
 
282
290
  class CheckingOutlet extends LslStreamOutlet {
283
- public constructor(info: StreamInfo, options: LslOutletOptions) {
291
+ public constructor(info: StreamInfo, options: StreamOutletOptions) {
284
292
  super(info, options)
285
293
  }
286
294
  }
@@ -0,0 +1,23 @@
1
+ import AbstractSpruceTest, { test, assert } from '@sprucelabs/test-utils'
2
+ import LslWebSocketBridge, {
3
+ StreamTransportBridge,
4
+ } from '../../impl/LslWebSocketBridge'
5
+
6
+ export default class LslWebSocketBridgeTest extends AbstractSpruceTest {
7
+ private static instance: StreamTransportBridge
8
+
9
+ protected static async beforeEach() {
10
+ await super.beforeEach()
11
+
12
+ this.instance = this.LslWebSocketBridge()
13
+ }
14
+
15
+ @test()
16
+ protected static async createsInstance() {
17
+ assert.isTruthy(this.instance, 'Failed to create instance!')
18
+ }
19
+
20
+ private static LslWebSocketBridge() {
21
+ return LslWebSocketBridge.Create()
22
+ }
23
+ }
package/src/assertions.ts CHANGED
@@ -1,4 +1,3 @@
1
- import { SchemaError } from '@sprucelabs/schema'
2
1
  import { CHANNEL_FORMATS } from './consts'
3
2
  import { ChannelFormat } from './types'
4
3
  import {
@@ -8,52 +7,42 @@ import {
8
7
  isStringInArray,
9
8
  } from './validations'
10
9
 
11
- export function assertValidMaxBuffered(maxBuffered: number) {
12
- if (!isPositiveIntegerOrZero(maxBuffered)) {
13
- throw new SchemaError({
14
- code: 'INVALID_PARAMETERS',
15
- parameters: ['maxBuffered'],
16
- friendlyMessage: 'Max buffered must be a positive integer or zero.',
17
- })
10
+ export function assertValidChunkSize(chunkSize: number) {
11
+ if (!isPositiveIntegerOrZero(chunkSize)) {
12
+ throw new Error(
13
+ `Invalid chunk size! Must be a positive integer or zero, not: ${chunkSize}.`
14
+ )
18
15
  }
19
16
  }
20
17
 
21
- export function assertValidChunkSize(chunkSize: number) {
22
- if (!isPositiveIntegerOrZero(chunkSize)) {
23
- throw new SchemaError({
24
- code: 'INVALID_PARAMETERS',
25
- parameters: ['chunkSize'],
26
- friendlyMessage: 'Chunk size must be a positive integer or zero.',
27
- })
18
+ export function assertValidMaxBuffered(maxBuffered: number) {
19
+ if (!isPositiveIntegerOrZero(maxBuffered)) {
20
+ throw new Error(
21
+ `Invalid max buffered! Must be a positive integer or zero, not: ${maxBuffered}.`
22
+ )
28
23
  }
29
24
  }
30
25
 
31
26
  export function assertValidChannelFormat(channelFormat: ChannelFormat) {
32
27
  if (!isStringInArray(channelFormat, CHANNEL_FORMATS)) {
33
- throw new SchemaError({
34
- code: 'INVALID_PARAMETERS',
35
- parameters: ['channelFormat'],
36
- friendlyMessage: `Invalid `,
37
- })
28
+ throw new Error(
29
+ `Invalid channel format! Must be one of: ${CHANNEL_FORMATS.join(', ')}, not ${channelFormat}.`
30
+ )
38
31
  }
39
32
  }
40
33
 
41
34
  export function assertValidSampleRate(sampleRate: number) {
42
35
  if (!isGreaterThanOrEqualToZero(sampleRate)) {
43
- throw new SchemaError({
44
- code: 'INVALID_PARAMETERS',
45
- parameters: ['sampleRate'],
46
- friendlyMessage: 'Sample rate must be a positive number or zero.',
47
- })
36
+ throw new Error(
37
+ `Invalid sample rate! Must be a positive number or zero, not: ${sampleRate}.`
38
+ )
48
39
  }
49
40
  }
50
41
 
51
42
  export function assertValidChannelCount(channelCount: number) {
52
43
  if (!isPositiveInteger(channelCount)) {
53
- throw new SchemaError({
54
- code: 'INVALID_PARAMETERS',
55
- parameters: ['channelNames'],
56
- friendlyMessage: 'channelNames must have 1 or more labels.',
57
- })
44
+ throw new Error(
45
+ `Invalid channel count! Must be a positive integer, not: ${channelCount}.`
46
+ )
58
47
  }
59
48
  }
@@ -1,6 +1,4 @@
1
- import { assertOptions } from '@sprucelabs/schema'
2
1
  import { DataType, define, open } from 'ffi-rs'
3
- import SpruceError from '../errors/SpruceError'
4
2
  import {
5
3
  Liblsl,
6
4
  LiblslBindings,
@@ -15,29 +13,30 @@ import {
15
13
  } from '../types'
16
14
 
17
15
  export default class LiblslAdapter implements Liblsl {
18
- private static instance?: Liblsl
19
16
  public static ffiRsOpen = open
20
17
  public static ffiRsDefine = define
18
+ private static instance?: Liblsl
21
19
 
20
+ private path: string
22
21
  private bindings!: LiblslBindings
23
22
 
24
23
  protected constructor() {
25
- const path = process.env.LIBLSL_PATH! ?? this.defaultMacOsPath
26
- this.tryToLoadBindings(path)
24
+ this.path = process.env.LIBLSL_PATH! ?? this.defaultMacOsPath
25
+ this.tryToLoadBindings()
27
26
  }
28
27
 
29
- private tryToLoadBindings(path: string) {
28
+ private tryToLoadBindings() {
30
29
  try {
31
- this.bindings = this.loadBindings(path)
30
+ this.bindings = this.loadBindings(this.path)
32
31
  } catch (error) {
33
- throw new SpruceError({
34
- code: 'FAILED_TO_LOAD_LIBLSL',
35
- liblslPath: path,
36
- originalError: error as any,
37
- })
32
+ throw new Error(this.generateFailedMessage(error as Error))
38
33
  }
39
34
  }
40
35
 
36
+ private generateFailedMessage(error: Error) {
37
+ return `Loading the liblsl dylib failed! I tried to load it from ${this.path}.\n\n${error.message}\n\n`
38
+ }
39
+
41
40
  public static getInstance() {
42
41
  if (!this.instance) {
43
42
  this.setInstance(new this())
@@ -145,14 +144,7 @@ export default class LiblslAdapter implements Liblsl {
145
144
  sampleRate,
146
145
  channelFormat,
147
146
  sourceId,
148
- } = assertOptions(options, [
149
- 'name',
150
- 'type',
151
- 'channelCount',
152
- 'sampleRate',
153
- 'channelFormat',
154
- 'sourceId',
155
- ])
147
+ } = options
156
148
 
157
149
  return this.bindings.lsl_create_streaminfo([
158
150
  name,
@@ -167,7 +159,7 @@ export default class LiblslAdapter implements Liblsl {
167
159
  public appendChannelsToStreamInfo(
168
160
  options: AppendChannelsToStreamInfoOptions
169
161
  ) {
170
- const { info, channels } = assertOptions(options, ['info', 'channels'])
162
+ const { info, channels } = options
171
163
 
172
164
  const description = this.bindings.lsl_get_desc([info])
173
165
  const parent = this.bindings.lsl_append_child([description, 'channels'])
@@ -185,47 +177,29 @@ export default class LiblslAdapter implements Liblsl {
185
177
  }
186
178
 
187
179
  public createOutlet(options: CreateOutletOptions) {
188
- const { info, chunkSize, maxBuffered } = assertOptions(options, [
189
- 'info',
190
- 'chunkSize',
191
- 'maxBuffered',
192
- ])
193
-
180
+ const { info, chunkSize, maxBuffered } = options
194
181
  return this.bindings.lsl_create_outlet([info, chunkSize, maxBuffered])
195
182
  }
196
183
 
197
184
  public pushSampleFloatTimestamp(options: PushSampleFloatTimestampOptions) {
198
- const { outlet, sample, timestamp } = assertOptions(options, [
199
- 'outlet',
200
- 'sample',
201
- 'timestamp',
202
- ])
185
+ const { outlet, sample, timestamp } = options
203
186
  this.bindings.lsl_push_sample_ft([outlet, sample, timestamp])
204
187
  }
205
188
 
206
189
  public pushSampleStringTimestamp(
207
190
  options: PushSampleStringTimestampOptions
208
191
  ) {
209
- const { outlet, sample, timestamp } = assertOptions(options, [
210
- 'outlet',
211
- 'sample',
212
- 'timestamp',
213
- ])
192
+ const { outlet, sample, timestamp } = options
214
193
  this.bindings.lsl_push_sample_strt([outlet, sample, timestamp])
215
194
  }
216
195
 
217
196
  public destroyOutlet(options: DestroyOutletOptions) {
218
- const { outlet } = assertOptions(options, ['outlet'])
197
+ const { outlet } = options
219
198
  this.bindings.lsl_destroy_outlet([outlet])
220
199
  }
221
200
 
222
201
  public createInlet(options: CreateInletOptions) {
223
- const { info, chunkSize, maxBuffered } = assertOptions(options, [
224
- 'info',
225
- 'chunkSize',
226
- 'maxBuffered',
227
- ])
228
-
202
+ const { info, chunkSize, maxBuffered } = options
229
203
  return this.bindings.lsl_create_inlet([info, chunkSize, maxBuffered])
230
204
  }
231
205
 
@@ -1,19 +1,22 @@
1
1
  import { DurationMarker } from '../types'
2
- import LslStreamOutlet, { LslOutletOptions, LslOutlet } from './LslStreamOutlet'
2
+ import LslStreamOutlet, {
3
+ StreamOutletOptions,
4
+ StreamOutlet,
5
+ } from './LslStreamOutlet'
3
6
 
4
- export default class EventMarkerOutlet implements MarkerOutlet {
5
- public static Class?: MarkerOutletConstructor
7
+ export default class LslEventMarkerOutlet implements EventMarkerOutlet {
8
+ public static Class?: EventMarkerOutletConstructor
6
9
 
7
- protected lslOutlet: LslOutlet
10
+ protected streamOutlet: StreamOutlet
8
11
  private isPlaying = false
9
12
  private waitResolve?: () => void
10
13
  private timeout?: any
11
14
 
12
- protected constructor(lslOutlet: LslOutlet) {
13
- this.lslOutlet = lslOutlet
15
+ protected constructor(outlet: StreamOutlet) {
16
+ this.streamOutlet = outlet
14
17
  }
15
18
 
16
- public static async Create(options?: Partial<LslOutletOptions>) {
19
+ public static async Create(options?: Partial<StreamOutletOptions>) {
17
20
  const defaultOptions = {
18
21
  name: 'Event markers',
19
22
  type: 'Markers',
@@ -25,7 +28,7 @@ export default class EventMarkerOutlet implements MarkerOutlet {
25
28
  unit: 'N/A',
26
29
  chunkSize: 0,
27
30
  maxBuffered: 0,
28
- } as LslOutletOptions
31
+ } as StreamOutletOptions
29
32
 
30
33
  const outlet = await LslStreamOutlet.Create({
31
34
  ...defaultOptions,
@@ -55,7 +58,7 @@ export default class EventMarkerOutlet implements MarkerOutlet {
55
58
  }
56
59
 
57
60
  private pushMarkerToOutlet(markerName: string) {
58
- this.lslOutlet.pushSample([markerName])
61
+ this.streamOutlet.pushSample([markerName])
59
62
  }
60
63
 
61
64
  protected async wait(durationMs: number) {
@@ -74,10 +77,12 @@ export default class EventMarkerOutlet implements MarkerOutlet {
74
77
  }
75
78
  }
76
79
 
77
- export interface MarkerOutlet {
80
+ export interface EventMarkerOutlet {
78
81
  pushMarker(markerName: string): void
79
82
  pushMarkers(markers: DurationMarker[]): Promise<void>
80
83
  stop(): void
81
84
  }
82
85
 
83
- export type MarkerOutletConstructor = new (lslOutlet: LslOutlet) => MarkerOutlet
86
+ export type EventMarkerOutletConstructor = new (
87
+ outlet: StreamOutlet
88
+ ) => EventMarkerOutlet
@@ -1,5 +1,4 @@
1
- import { assertOptions } from '@sprucelabs/schema'
2
- import { generateId } from '@sprucelabs/test-utils'
1
+ import generateId from '@neurodevs/generate-id'
3
2
  import { CHANNEL_FORMATS_MAP } from '../consts'
4
3
  import { BoundStreamInfo, ChannelFormat } from '../types'
5
4
  import LiblslAdapter from './LiblslAdapter'
@@ -40,7 +39,6 @@ export default class LslStreamInfo implements StreamInfo {
40
39
  }
41
40
 
42
41
  public static Create(options: StreamInfoOptions) {
43
- assertOptions(options, ['channelNames', 'channelFormat', 'sampleRate'])
44
42
  return new (this.Class ?? this)(options)
45
43
  }
46
44
 
@@ -1,18 +1,17 @@
1
- import { assertOptions } from '@sprucelabs/schema'
2
- import { generateId } from '@sprucelabs/test-utils'
1
+ import generateId from '@neurodevs/generate-id'
3
2
  import { ChannelFormat } from '../types'
4
3
  import LiblslAdapter from './LiblslAdapter'
5
4
  import LslStreamInfo, { StreamInfo, StreamInfoOptions } from './LslStreamInfo'
6
5
 
7
- export default class LslStreamInlet implements LslInlet {
8
- public static Class?: LslInletConstructor
6
+ export default class LslStreamInlet implements StreamInlet {
7
+ public static Class?: StreamInletConstructor
9
8
 
10
9
  protected name: string
11
10
  protected info: StreamInfo
12
11
  private chunkSize: number
13
12
  private maxBuffered: number
14
13
 
15
- protected constructor(info: StreamInfo, options: LslInletOptions) {
14
+ protected constructor(info: StreamInfo, options: StreamInletOptions) {
16
15
  const {
17
16
  name = this.defaultName,
18
17
  chunkSize,
@@ -24,24 +23,17 @@ export default class LslStreamInlet implements LslInlet {
24
23
  this.maxBuffered = maxBuffered
25
24
  this.name = name
26
25
 
27
- this.createLslInlet()
26
+ this.createStreamInlet()
28
27
  }
29
28
 
30
- public static Create(options: LslInletOptions) {
31
- assertOptions(options, [
32
- 'channelNames',
33
- 'channelFormat',
34
- 'sampleRate',
35
- 'chunkSize',
36
- 'maxBuffered',
37
- ])
29
+ public static Create(options: StreamInletOptions) {
38
30
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
39
- const { maxBuffered, chunkSize, ...streamInfoOptions } = options
40
- const info = this.LslStreamInfo(streamInfoOptions)
31
+ const { maxBuffered, chunkSize, ...infoOptions } = options
32
+ const info = this.LslStreamInfo(infoOptions)
41
33
  return new (this.Class ?? this)(info, options)
42
34
  }
43
35
 
44
- private createLslInlet() {
36
+ private createStreamInlet() {
45
37
  this.lsl.createInlet({
46
38
  info: this.boundStreamInfo,
47
39
  chunkSize: this.chunkSize,
@@ -64,14 +56,14 @@ export default class LslStreamInlet implements LslInlet {
64
56
  }
65
57
  }
66
58
 
67
- export interface LslInlet {}
59
+ export interface StreamInlet {}
68
60
 
69
- export type LslInletConstructor = new (
61
+ export type StreamInletConstructor = new (
70
62
  info: StreamInfo,
71
- options: LslInletOptions
72
- ) => LslInlet
63
+ options: StreamInletOptions
64
+ ) => StreamInlet
73
65
 
74
- export interface LslInletOptions {
66
+ export interface StreamInletOptions {
75
67
  sampleRate: number
76
68
  channelNames: string[]
77
69
  channelFormat: ChannelFormat