@neurodevs/node-lsl 11.4.0 → 11.4.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 (81) hide show
  1. package/README.md +40 -29
  2. package/build/.spruce/settings.json +1 -3
  3. package/build/__tests__/AbstractLslTest.d.ts +1 -0
  4. package/build/__tests__/AbstractLslTest.js +1 -0
  5. package/build/__tests__/AbstractLslTest.js.map +1 -1
  6. package/build/__tests__/modules/LiblslAdapter.test.d.ts +1 -5
  7. package/build/__tests__/modules/LiblslAdapter.test.js +5 -61
  8. package/build/__tests__/modules/LiblslAdapter.test.js.map +1 -1
  9. package/build/__tests__/modules/LslStreamInfo.test.d.ts +0 -1
  10. package/build/__tests__/modules/LslStreamInfo.test.js +0 -11
  11. package/build/__tests__/modules/LslStreamInfo.test.js.map +1 -1
  12. package/build/__tests__/modules/LslStreamInlet.test.d.ts +0 -1
  13. package/build/__tests__/modules/LslStreamInlet.test.js +0 -17
  14. package/build/__tests__/modules/LslStreamInlet.test.js.map +1 -1
  15. package/build/__tests__/modules/LslStreamOutlet.test.d.ts +7 -5
  16. package/build/__tests__/modules/LslStreamOutlet.test.js +34 -52
  17. package/build/__tests__/modules/LslStreamOutlet.test.js.map +1 -1
  18. package/build/assertions.d.ts +1 -1
  19. package/build/assertions.js +10 -31
  20. package/build/assertions.js.map +1 -1
  21. package/build/modules/LiblslAdapter.d.ts +3 -1
  22. package/build/modules/LiblslAdapter.js +15 -44
  23. package/build/modules/LiblslAdapter.js.map +1 -1
  24. package/build/modules/LslStreamInfo.js +0 -2
  25. package/build/modules/LslStreamInfo.js.map +1 -1
  26. package/build/modules/LslStreamInlet.js +2 -10
  27. package/build/modules/LslStreamInlet.js.map +1 -1
  28. package/build/modules/LslStreamOutlet.js +0 -13
  29. package/build/modules/LslStreamOutlet.js.map +1 -1
  30. package/build/scripts/demoMarkerOutlet.d.ts +1 -0
  31. package/build/scripts/demoMarkerOutlet.js +23 -0
  32. package/build/scripts/demoMarkerOutlet.js.map +1 -0
  33. package/build/scripts/demoStreamOutlet.d.ts +1 -0
  34. package/build/scripts/demoStreamOutlet.js +25 -0
  35. package/build/scripts/demoStreamOutlet.js.map +1 -0
  36. package/build/testDoubles/LslOutlet/FakeLslOutlet.d.ts +4 -4
  37. package/build/testDoubles/LslOutlet/FakeLslOutlet.js +12 -10
  38. package/build/testDoubles/LslOutlet/FakeLslOutlet.js.map +1 -1
  39. package/package.json +8 -12
  40. package/src/.spruce/settings.json +1 -3
  41. package/src/__tests__/AbstractLslTest.ts +1 -0
  42. package/src/__tests__/modules/LiblslAdapter.test.ts +12 -58
  43. package/src/__tests__/modules/LslStreamInfo.test.ts +1 -12
  44. package/src/__tests__/modules/LslStreamInlet.test.ts +1 -18
  45. package/src/__tests__/modules/LslStreamOutlet.test.ts +56 -55
  46. package/src/assertions.ts +19 -30
  47. package/src/modules/LiblslAdapter.ts +18 -44
  48. package/src/modules/LslStreamInfo.ts +0 -2
  49. package/src/modules/LslStreamInlet.ts +2 -10
  50. package/src/modules/LslStreamOutlet.ts +0 -14
  51. package/src/scripts/demoMarkerOutlet.ts +23 -0
  52. package/src/scripts/demoStreamOutlet.ts +22 -0
  53. package/src/testDoubles/LslOutlet/FakeLslOutlet.ts +16 -14
  54. package/build/.spruce/errors/errors.types.d.ts +0 -21
  55. package/build/.spruce/errors/errors.types.js +0 -3
  56. package/build/.spruce/errors/errors.types.js.map +0 -1
  57. package/build/.spruce/errors/nodeLsl/failedToLoadLiblsl.schema.d.ts +0 -3
  58. package/build/.spruce/errors/nodeLsl/failedToLoadLiblsl.schema.js +0 -19
  59. package/build/.spruce/errors/nodeLsl/failedToLoadLiblsl.schema.js.map +0 -1
  60. package/build/.spruce/errors/options.types.d.ts +0 -7
  61. package/build/.spruce/errors/options.types.js +0 -3
  62. package/build/.spruce/errors/options.types.js.map +0 -1
  63. package/build/.spruce/schemas/fields/fieldClassMap.d.ts +0 -2
  64. package/build/.spruce/schemas/fields/fieldClassMap.js +0 -5
  65. package/build/.spruce/schemas/fields/fieldClassMap.js.map +0 -1
  66. package/build/.spruce/schemas/fields/fields.types.d.ts +0 -1
  67. package/build/.spruce/schemas/fields/fields.types.js +0 -3
  68. package/build/.spruce/schemas/fields/fields.types.js.map +0 -1
  69. package/build/errors/SpruceError.d.ts +0 -6
  70. package/build/errors/SpruceError.js +0 -26
  71. package/build/errors/SpruceError.js.map +0 -1
  72. package/build/errors/failedToLoadLiblsl.builder.d.ts +0 -11
  73. package/build/errors/failedToLoadLiblsl.builder.js +0 -14
  74. package/build/errors/failedToLoadLiblsl.builder.js.map +0 -1
  75. package/src/.spruce/errors/errors.types.ts +0 -37
  76. package/src/.spruce/errors/nodeLsl/failedToLoadLiblsl.schema.ts +0 -22
  77. package/src/.spruce/errors/options.types.ts +0 -10
  78. package/src/.spruce/schemas/fields/fieldClassMap.ts +0 -6
  79. package/src/.spruce/schemas/fields/fields.types.ts +0 -1
  80. package/src/errors/SpruceError.ts +0 -23
  81. package/src/errors/failedToLoadLiblsl.builder.ts +0 -12
@@ -1,5 +1,5 @@
1
1
  import { randomInt } from 'crypto'
2
- import { test, assert, errorAssert, generateId } from '@sprucelabs/test-utils'
2
+ import { test, assert, generateId } from '@sprucelabs/test-utils'
3
3
  import { DataType, OpenParams } from 'ffi-rs'
4
4
  import LiblslAdapter from '../../modules/LiblslAdapter'
5
5
  import FakeLiblsl from '../../testDoubles/Liblsl/FakeLiblsl'
@@ -94,9 +94,13 @@ export default class LiblslAdapterTest extends AbstractLslTest {
94
94
  LiblslAdapter.resetInstance()
95
95
 
96
96
  const err = assert.doesThrow(() => LiblslAdapter.getInstance())
97
- errorAssert.assertError(err, 'FAILED_TO_LOAD_LIBLSL', {
98
- liblslPath: process.env.LIBLSL_PATH,
99
- })
97
+
98
+ debugger
99
+
100
+ assert.isTrue(
101
+ err.message.includes(this.generateFailedMessage()),
102
+ 'Did not receive the expected error!'
103
+ )
100
104
  }
101
105
 
102
106
  @test()
@@ -107,60 +111,6 @@ export default class LiblslAdapterTest extends AbstractLslTest {
107
111
  })
108
112
  }
109
113
 
110
- @test()
111
- protected static throwsWhenCreateStreamInfoIsMissingRequiredParams() {
112
- //@ts-ignore
113
- const err = assert.doesThrow(() => this.lsl.createStreamInfo())
114
- errorAssert.assertError(err, 'MISSING_PARAMETERS', {
115
- parameters: [
116
- 'name',
117
- 'type',
118
- 'channelCount',
119
- 'sampleRate',
120
- 'channelFormat',
121
- 'sourceId',
122
- ],
123
- })
124
- }
125
-
126
- @test()
127
- protected static async throwsWhenAppendChannelsIsMissingRequiredParams() {
128
- const err = assert.doesThrow(() =>
129
- //@ts-ignore
130
- this.lsl.appendChannelsToStreamInfo({})
131
- )
132
- errorAssert.assertError(err, 'MISSING_PARAMETERS', {
133
- parameters: ['info', 'channels'],
134
- })
135
- }
136
-
137
- @test()
138
- protected static async throwsWhenCreateOutletIsMissingRequiredParams() {
139
- //@ts-ignore
140
- const err = assert.doesThrow(() => this.lsl.createOutlet({}))
141
- errorAssert.assertError(err, 'MISSING_PARAMETERS', {
142
- parameters: ['info', 'chunkSize', 'maxBuffered'],
143
- })
144
- }
145
-
146
- @test()
147
- protected static async throwsWhenPushSampleFloatTimestampIsMissingRequiredParams() {
148
- //@ts-ignore
149
- const err = assert.doesThrow(() => this.lsl.pushSampleFloatTimestamp())
150
- errorAssert.assertError(err, 'MISSING_PARAMETERS', {
151
- parameters: ['outlet', 'sample', 'timestamp'],
152
- })
153
- }
154
-
155
- @test()
156
- protected static async throwsWhenPushSampleStringTimestampIsMissingRequiredParams() {
157
- //@ts-ignore
158
- const err = assert.doesThrow(() => this.lsl.pushSampleFloatTimestamp())
159
- errorAssert.assertError(err, 'MISSING_PARAMETERS', {
160
- parameters: ['outlet', 'sample', 'timestamp'],
161
- })
162
- }
163
-
164
114
  @test()
165
115
  protected static async worksAsASingleton() {
166
116
  const liblsl = LiblslAdapter.getInstance()
@@ -461,6 +411,10 @@ export default class LiblslAdapterTest extends AbstractLslTest {
461
411
  }
462
412
  }
463
413
 
414
+ private static generateFailedMessage() {
415
+ return `Loading the liblsl dylib failed! I tried to load it from ${process.env.LIBLSL_PATH}.`
416
+ }
417
+
464
418
  private static FakeBindings() {
465
419
  return {
466
420
  lsl_create_streaminfo: (params: any[]) => {
@@ -1,4 +1,4 @@
1
- import { test, assert, generateId, errorAssert } from '@sprucelabs/test-utils'
1
+ import { test, assert, generateId } from '@sprucelabs/test-utils'
2
2
  import { CHANNEL_FORMATS } from '../../consts'
3
3
  import LslStreamInfo, { StreamInfoOptions } from '../../modules/LslStreamInfo'
4
4
  import SpyStreamInfo from '../../testDoubles/StreamInfo/SpyStreamInfo'
@@ -20,17 +20,6 @@ export default class LslStreamInfoTest extends AbstractLslTest {
20
20
  assert.isTruthy(this.instance, 'Instance should be created!')
21
21
  }
22
22
 
23
- @test()
24
- protected static async throwsWithMissingRequiredOptions() {
25
- const err = assert.doesThrow(
26
- // @ts-ignore
27
- () => LslStreamInfo.Create()
28
- )
29
- errorAssert.assertError(err, 'MISSING_PARAMETERS', {
30
- parameters: ['channelNames', 'channelFormat', 'sampleRate'],
31
- })
32
- }
33
-
34
23
  @test()
35
24
  protected static async generatesUniqueNameIfNotProvided() {
36
25
  const instance1 = this.LslStreamInfo({ name: undefined })
@@ -1,4 +1,4 @@
1
- import { test, assert, errorAssert } from '@sprucelabs/test-utils'
1
+ import { test, assert } from '@sprucelabs/test-utils'
2
2
  import LslStreamInlet, { LslInletOptions } from '../../modules/LslStreamInlet'
3
3
  import { SpyLslInlet } from '../../testDoubles/LslInlet/SpyLslInlet'
4
4
  import FakeStreamInfo from '../../testDoubles/StreamInfo/FakeStreamInfo'
@@ -21,23 +21,6 @@ export default class LslStreamInletTest extends AbstractLslTest {
21
21
  assert.isTruthy(this.instance, 'Instance should be created!')
22
22
  }
23
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
- })
39
- }
40
-
41
24
  @test()
42
25
  protected static async createsStreamInfoWithExpectedOptions() {
43
26
  assert.isEqualDeep(
@@ -1,4 +1,5 @@
1
- import { test, assert, errorAssert, generateId } from '@sprucelabs/test-utils'
1
+ import { test, assert, generateId } from '@sprucelabs/test-utils'
2
+ import { CHANNEL_FORMATS } from '../../consts'
2
3
  import { StreamInfo } from '../../modules/LslStreamInfo'
3
4
  import LslStreamOutlet, {
4
5
  LslOutletOptions,
@@ -11,7 +12,7 @@ import {
11
12
 
12
13
  import generateRandomOutletOptions from '../../testDoubles/generateRandomOutletOptions'
13
14
  import FakeStreamInfo from '../../testDoubles/StreamInfo/FakeStreamInfo'
14
- import { LslSample } from '../../types'
15
+ import { ChannelFormat, LslSample } from '../../types'
15
16
  import AbstractLslTest from '../AbstractLslTest'
16
17
 
17
18
  export default class LslStreamOutletTest extends AbstractLslTest {
@@ -29,30 +30,8 @@ export default class LslStreamOutletTest extends AbstractLslTest {
29
30
  }
30
31
 
31
32
  @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)
33
+ protected static async throwsWithEmptyChannelNames() {
34
+ await this.assertThrowsWithEmptyChannelNames()
56
35
  }
57
36
 
58
37
  @test()
@@ -68,24 +47,30 @@ export default class LslStreamOutletTest extends AbstractLslTest {
68
47
 
69
48
  @test()
70
49
  protected static async throwsWithInvalidChannelFormat() {
71
- await this.assertDoesThrowInvalidParameters(
72
- //@ts-ignore
73
- { channelFormat: generateId() },
74
- ['channelFormat']
50
+ await this.assertThrowsInvalidChannelFormat(
51
+ 'invalid-format' as ChannelFormat
75
52
  )
76
53
  }
77
54
 
78
55
  @test()
79
- protected static async throwsWithInvalidChunkSize() {
56
+ protected static async allowsZeroChunkSize() {
80
57
  await this.LslStreamOutlet({ chunkSize: 0 })
58
+ }
59
+
60
+ @test()
61
+ protected static async throwsWithInvalidChunkSize() {
81
62
  await this.assertThrowsInvalidChunkSize(-1)
82
63
  await this.assertThrowsInvalidChunkSize(-1.5)
83
64
  await this.assertThrowsInvalidChunkSize(1.5)
84
65
  }
85
66
 
86
67
  @test()
87
- protected static async throwsWithInvalidMaxBuffered() {
68
+ protected static async allowsZeroMaxBuffered() {
88
69
  await this.LslStreamOutlet({ maxBuffered: 0 })
70
+ }
71
+
72
+ @test()
73
+ protected static async throwsWithInvalidMaxBuffered() {
89
74
  await this.assertThrowsInvalidMaxBuffered(-1)
90
75
  await this.assertThrowsInvalidMaxBuffered(-1.5)
91
76
  await this.assertThrowsInvalidMaxBuffered(1.5)
@@ -226,41 +211,57 @@ export default class LslStreamOutletTest extends AbstractLslTest {
226
211
  assert.isAbove(endMs - startMs, 10)
227
212
  }
228
213
 
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
- ])
214
+ private static async assertThrowsWithEmptyChannelNames() {
215
+ await this.createAndAssertThrows(
216
+ 'channelNames',
217
+ [],
218
+ `Invalid channel count! Must be a positive integer, not: 0.`
219
+ )
239
220
  }
240
221
 
241
222
  private static async assertThrowsInvalidSampleRate(sampleRate: number) {
242
- await this.assertDoesThrowInvalidParameters({ sampleRate }, [
223
+ await this.createAndAssertThrows(
243
224
  'sampleRate',
244
- ])
225
+ sampleRate,
226
+ `Invalid sample rate! Must be a positive number or zero, not: ${sampleRate}`
227
+ )
228
+ }
229
+
230
+ private static async assertThrowsInvalidChannelFormat(
231
+ channelFormat: ChannelFormat
232
+ ) {
233
+ await this.createAndAssertThrows(
234
+ 'channelFormat',
235
+ channelFormat,
236
+ `Invalid channel format! Must be one of: ${CHANNEL_FORMATS.join(', ')}, not ${channelFormat}.`
237
+ )
245
238
  }
246
239
 
247
- private static async assertThrowsInvalidChannelNames(count: number) {
248
- await this.assertDoesThrowInvalidParameters(
249
- { channelNames: new Array(count).fill(generateId()) },
250
- ['channelNames']
240
+ private static async assertThrowsInvalidMaxBuffered(maxBuffered: number) {
241
+ await this.createAndAssertThrows(
242
+ 'maxBuffered',
243
+ maxBuffered,
244
+ `Invalid max buffered! Must be a positive integer or zero, not: ${maxBuffered}`
251
245
  )
252
246
  }
253
247
 
254
- private static async assertDoesThrowInvalidParameters(
255
- options: Partial<LslOutletOptions>,
256
- parameters: string[]
248
+ private static async assertThrowsInvalidChunkSize(chunkSize: number) {
249
+ await this.createAndAssertThrows(
250
+ 'chunkSize',
251
+ chunkSize,
252
+ `Invalid chunk size! Must be a positive integer or zero, not: ${chunkSize}`
253
+ )
254
+ }
255
+
256
+ private static async createAndAssertThrows(
257
+ option: keyof LslOutletOptions,
258
+ value: number | string[] | ChannelFormat,
259
+ expectedMessage: string
257
260
  ) {
258
261
  const err = await assert.doesThrowAsync(
259
- async () => await this.LslStreamOutlet(options)
262
+ async () => await this.LslStreamOutlet({ [option]: value })
260
263
  )
261
- errorAssert.assertError(err, 'INVALID_PARAMETERS', {
262
- parameters,
263
- })
264
+ assert.isTrue(err.message.includes(expectedMessage))
264
265
  }
265
266
 
266
267
  private static async StringOutlet() {
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,4 +1,3 @@
1
- import { assertOptions } from '@sprucelabs/schema'
2
1
  import { generateId } from '@sprucelabs/test-utils'
3
2
  import { CHANNEL_FORMATS_MAP } from '../consts'
4
3
  import { BoundStreamInfo, ChannelFormat } from '../types'
@@ -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,4 +1,3 @@
1
- import { assertOptions } from '@sprucelabs/schema'
2
1
  import { generateId } from '@sprucelabs/test-utils'
3
2
  import { ChannelFormat } from '../types'
4
3
  import LiblslAdapter from './LiblslAdapter'
@@ -28,16 +27,9 @@ export default class LslStreamInlet implements LslInlet {
28
27
  }
29
28
 
30
29
  public static Create(options: LslInletOptions) {
31
- assertOptions(options, [
32
- 'channelNames',
33
- 'channelFormat',
34
- 'sampleRate',
35
- 'chunkSize',
36
- 'maxBuffered',
37
- ])
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
 
@@ -1,4 +1,3 @@
1
- import { assertOptions } from '@sprucelabs/schema'
2
1
  import {
3
2
  assertValidChannelCount,
4
3
  assertValidChannelFormat,
@@ -28,19 +27,6 @@ export default class LslStreamOutlet implements LslOutlet {
28
27
  }
29
28
 
30
29
  public static async Create(options: LslOutletOptions) {
31
- assertOptions(options, [
32
- 'name',
33
- 'type',
34
- 'sourceId',
35
- 'channelNames',
36
- 'channelFormat',
37
- 'sampleRate',
38
- 'chunkSize',
39
- 'maxBuffered',
40
- 'manufacturer',
41
- 'unit',
42
- ])
43
-
44
30
  const { waitAfterConstructionMs = 10 } = options ?? {}
45
31
 
46
32
  const streamInfoOptions = {
@@ -0,0 +1,23 @@
1
+ import EventMarkerOutlet from '../modules/EventMarkerOutlet'
2
+
3
+ async function main() {
4
+ const outlet = await EventMarkerOutlet.Create()
5
+
6
+ const markers = [
7
+ { name: 'phase-1-begin', durationMs: 100 },
8
+ { name: 'phase-1-end', durationMs: 10 },
9
+ ]
10
+
11
+ // Hangs until complete
12
+ await outlet.pushMarkers(markers)
13
+
14
+ // Void promise, does not hang
15
+ void outlet.pushMarkers(markers)
16
+
17
+ // Interrupts the above pushMarkers process
18
+ outlet.stop()
19
+ }
20
+
21
+ main().catch((error) => {
22
+ console.error('Error in main:', error)
23
+ })
@@ -0,0 +1,22 @@
1
+ import LslStreamOutlet from '../modules/LslStreamOutlet'
2
+
3
+ async function main() {
4
+ const instance = await LslStreamOutlet.Create({
5
+ name: 'Muse S (2nd gen)',
6
+ type: 'EEG',
7
+ channelNames: ['TP9', 'AF7', 'AF8', 'TP10', 'AUX'],
8
+ sampleRate: 256,
9
+ channelFormat: 'float32',
10
+ sourceId: 'muse-s-eeg',
11
+ manufacturer: 'Interaxon Inc.',
12
+ unit: 'microvolt',
13
+ chunkSize: 12,
14
+ maxBuffered: 360,
15
+ })
16
+
17
+ instance.pushSample([1, 2, 3, 4, 5])
18
+ }
19
+
20
+ main().catch((error) => {
21
+ console.error('Error in main:', error)
22
+ })