@neurodevs/node-lsl 2.0.1 → 3.1.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.
package/src/LslOutlet.ts CHANGED
@@ -1,16 +1,17 @@
1
1
  import { SchemaError, assertOptions } from '@sprucelabs/schema'
2
- import LiblslImpl, { LslBindingsStreamInfo, LslSample } from './Liblsl'
2
+ import LiblslImpl, { BoundOutlet, BoundStreamInfo, LslSample } from './Liblsl'
3
3
 
4
4
  export default class LslOutletImpl implements LslOutlet {
5
5
  private outletOptions: LslOutletOptions
6
6
  public static Class?: new (options: LslOutletOptions) => LslOutlet
7
- private streamInfo: LslBindingsStreamInfo
7
+ private streamInfo: BoundStreamInfo
8
+ private outlet: BoundOutlet
8
9
 
9
10
  protected constructor(options: LslOutletOptions) {
10
11
  const { sampleRate, channelFormat } = assertOptions(options, [
11
12
  'name',
12
13
  'type',
13
- 'channelLabels',
14
+ 'channelNames',
14
15
  'sampleRate',
15
16
  'channelFormat',
16
17
  'sourceId',
@@ -22,10 +23,12 @@ export default class LslOutletImpl implements LslOutlet {
22
23
 
23
24
  this.outletOptions = options
24
25
 
25
- const { chunkSize, maxBuffered, channelLabels, ...streamInfoOptions } = this
26
+ const { chunkSize, maxBuffered, channelNames, ...streamInfoOptions } = this
26
27
  .outletOptions as any
27
28
 
28
- this.assertValidChannelCount(channelLabels.length)
29
+ const channelCount = channelNames.length
30
+
31
+ this.assertValidChannelCount(channelCount)
29
32
  this.assertValidSampleRate(sampleRate)
30
33
  this.assertValidChannelFormat(channelFormat)
31
34
  this.assertValidChunkSize(chunkSize)
@@ -36,24 +39,38 @@ export default class LslOutletImpl implements LslOutlet {
36
39
 
37
40
  this.streamInfo = this.lsl.createStreamInfo({
38
41
  ...streamInfoOptions,
39
- channelCount: channelLabels.length,
40
- channelFormat: CHANNEL_FORMATS.indexOf(this.outletOptions.channelFormat),
42
+ channelCount,
43
+ channelFormat: this.lookupChannelFormat(channelFormat),
41
44
  })
42
45
 
43
- this.lsl.appendChannelsToStreamInfo(
44
- this.streamInfo,
45
- channelLabels.map((label: string) => ({
46
+ this.lsl.appendChannelsToStreamInfo({
47
+ info: this.streamInfo,
48
+ channels: channelNames.map((label: string) => ({
46
49
  label,
47
50
  unit: this.outletOptions.unit,
48
51
  type: this.outletOptions.type,
49
- }))
50
- )
52
+ })),
53
+ })
54
+
55
+ this.outlet = this.lsl.createOutlet({
56
+ info: this.streamInfo,
57
+ chunkSize: this.outletOptions.chunkSize,
58
+ maxBuffered: this.outletOptions.maxBuffered,
59
+ })
51
60
  }
52
61
 
53
62
  public static Outlet(options: LslOutletOptions) {
54
63
  return new (this.Class ?? this)(options)
55
64
  }
56
65
 
66
+ public pushSample(sample: LslSample) {
67
+ this.lsl.pushSample({ outlet: this.outlet, sample })
68
+ }
69
+
70
+ private lookupChannelFormat(channelFormat: ChannelFormat): number {
71
+ return CHANNEL_FORMATS.indexOf(channelFormat)
72
+ }
73
+
57
74
  private assertValidMaxBufferred(maxBuffered: number) {
58
75
  if (!this.isPositiveIntegerOrZero(maxBuffered)) {
59
76
  throw new SchemaError({
@@ -100,8 +117,8 @@ export default class LslOutletImpl implements LslOutlet {
100
117
  if (!this.isPositiveInteger(channelCount)) {
101
118
  throw new SchemaError({
102
119
  code: 'INVALID_PARAMETERS',
103
- parameters: ['channelLabels'],
104
- friendlyMessage: 'channelLabels must have 1 or more labels.',
120
+ parameters: ['channelNames'],
121
+ friendlyMessage: 'channelNames must have 1 or more labels.',
105
122
  })
106
123
  }
107
124
  }
@@ -121,17 +138,6 @@ export default class LslOutletImpl implements LslOutlet {
121
138
  private get lsl() {
122
139
  return LiblslImpl.getInstance()
123
140
  }
124
-
125
- public pushSample(sample: LslSample) {
126
- this.lsl.pushSample(
127
- this.lsl.createOutlet({
128
- info: this.streamInfo,
129
- chunkSize: this.outletOptions.chunkSize,
130
- maxBuffered: this.outletOptions.maxBuffered,
131
- }),
132
- sample
133
- )
134
- }
135
141
  }
136
142
 
137
143
  const CHANNEL_FORMATS = [
@@ -146,10 +152,15 @@ const CHANNEL_FORMATS = [
146
152
  ] as const
147
153
 
148
154
  export type ChannelFormat = (typeof CHANNEL_FORMATS)[number]
155
+
156
+ export interface LslOutlet {
157
+ pushSample(sample: LslSample): void
158
+ }
159
+
149
160
  export interface LslOutletOptions {
150
161
  name: string
151
162
  type: string
152
- channelLabels: string[]
163
+ channelNames: string[]
153
164
  sampleRate: number
154
165
  channelFormat: ChannelFormat
155
166
  sourceId: string
@@ -158,7 +169,3 @@ export interface LslOutletOptions {
158
169
  chunkSize: number
159
170
  maxBuffered: number
160
171
  }
161
-
162
- export interface LslOutlet {
163
- pushSample(sample: LslSample): void
164
- }
@@ -9,10 +9,11 @@ import LiblslImpl, {
9
9
  CreateOutletOptions,
10
10
  CreateStreamInfoOptions,
11
11
  Liblsl,
12
- LslBindingsOutlet,
13
- LslBindingsStreamInfo,
14
- LslChannel,
12
+ BoundOutlet,
13
+ BoundStreamInfo,
15
14
  LslSample,
15
+ AppendChannelsToStreamInfoOptions,
16
+ PushSampleOptions,
16
17
  } from '../../Liblsl'
17
18
  import LslOutlet, { ChannelFormat, LslOutletOptions } from '../../LslOutlet'
18
19
 
@@ -28,7 +29,7 @@ export const CHANNEL_FORMATS = [
28
29
  ] as const
29
30
 
30
31
  export default class LslOutletTest extends AbstractSpruceTest {
31
- private static spyLsl: SpyLiblsl
32
+ private static spyLiblsl: SpyLiblsl
32
33
  private static randomOutletOptions: LslOutletOptions
33
34
  private static channelIdx: number
34
35
 
@@ -39,7 +40,7 @@ export default class LslOutletTest extends AbstractSpruceTest {
39
40
  this.randomOutletOptions = {
40
41
  name: generateId(),
41
42
  type: generateId(),
42
- channelLabels: new Array(randomInt(1, 10)).fill(generateId()),
43
+ channelNames: new Array(randomInt(1, 10)).fill(generateId()),
43
44
  sampleRate: Math.random() * 10,
44
45
  channelFormat: CHANNEL_FORMATS[this.channelIdx],
45
46
  sourceId: generateId(),
@@ -49,19 +50,19 @@ export default class LslOutletTest extends AbstractSpruceTest {
49
50
  maxBuffered: randomInt(0, 10),
50
51
  }
51
52
 
52
- this.spyLsl = new SpyLiblsl()
53
- LiblslImpl.setInstance(this.spyLsl)
53
+ this.spyLiblsl = new SpyLiblsl()
54
+ LiblslImpl.setInstance(this.spyLiblsl)
54
55
  }
55
56
 
56
57
  @test()
57
- protected static async throwsWhenMissingRequiredParameters() {
58
+ protected static async throwsWhenMissingRequiredParams() {
58
59
  //@ts-ignore
59
60
  const err = assert.doesThrow(() => new LslOutlet())
60
61
  errorAssert.assertError(err, 'MISSING_PARAMETERS', {
61
62
  parameters: [
62
63
  'name',
63
64
  'type',
64
- 'channelLabels',
65
+ 'channelNames',
65
66
  'sampleRate',
66
67
  'channelFormat',
67
68
  'sourceId',
@@ -74,13 +75,8 @@ export default class LslOutletTest extends AbstractSpruceTest {
74
75
  }
75
76
 
76
77
  @test()
77
- protected static async canCreateWithRequiredParams() {
78
- this.Outlet()
79
- }
80
-
81
- @test()
82
- protected static async throwsWithInvalidChannelCount() {
83
- this.assertThrowsInvalidChannelLabels(0)
78
+ protected static async throwsWithInvalidChannelNames() {
79
+ this.assertThrowsInvalidChannelNames(0)
84
80
  }
85
81
 
86
82
  @test()
@@ -99,15 +95,7 @@ export default class LslOutletTest extends AbstractSpruceTest {
99
95
  }
100
96
 
101
97
  @test()
102
- protected static async supportsAllKnownChannelFormats() {
103
- const valid = CHANNEL_FORMATS
104
- for (const format of valid) {
105
- this.Outlet({ channelFormat: format as ChannelFormat })
106
- }
107
- }
108
-
109
- @test()
110
- protected static async throwWithInvalidChunkSize() {
98
+ protected static async throwsWithInvalidChunkSize() {
111
99
  this.Outlet({ chunkSize: 0 })
112
100
  this.assertThrowsInvalidChunkSize(-1)
113
101
  this.assertThrowsInvalidChunkSize(-1.5)
@@ -122,56 +110,67 @@ export default class LslOutletTest extends AbstractSpruceTest {
122
110
  this.assertThrowsInvalidMaxBuffered(1.5)
123
111
  }
124
112
 
125
- @test('pushing sample sends to lsl 1', [1])
126
- @test('pushing sample sends to lsl 2', [1, 2])
127
- protected static async pushingSampleSendsToLsl(sample: LslSample) {
113
+ @test()
114
+ protected static async supportsAllKnownChannelFormats() {
115
+ const valid = CHANNEL_FORMATS
116
+ for (const format of valid) {
117
+ this.Outlet({ channelFormat: format as ChannelFormat })
118
+ }
119
+ }
120
+
121
+ @test('pushing [1, 2] sample sends to LSL', [1, 2])
122
+ @test('pushing [1] sample sends to LSL', [1])
123
+ protected static async canPushSampleToLsl(sample: LslSample) {
128
124
  this.pushSample(sample)
129
- assert.isEqual(this.spyLsl.lastPushedOutlet, this.spyLsl.outlet)
130
- assert.isEqualDeep(this.spyLsl.lastPushedSample, sample)
131
- assert.isEqualDeep(this.spyLsl.lastOutletOptions, {
132
- info: this.spyLsl.streamInfo,
125
+ assert.isEqual(
126
+ this.spyLiblsl.lastPushSampleOptions?.outlet,
127
+ this.spyLiblsl.outlet
128
+ )
129
+ assert.isEqualDeep(this.spyLiblsl.lastPushSampleOptions?.sample, sample)
130
+ assert.isEqualDeep(this.spyLiblsl.lastCreateOutletOptions, {
131
+ info: this.spyLiblsl.streamInfo,
133
132
  chunkSize: this.randomOutletOptions.chunkSize,
134
133
  maxBuffered: this.randomOutletOptions.maxBuffered,
135
134
  })
136
135
  }
137
136
 
138
137
  @test()
139
- protected static async constructionPassesCorrectOptionsToCreateStreamInfo() {
138
+ protected static async constructionCreatesStreamInfo() {
140
139
  this.Outlet()
141
140
 
142
141
  const { ...options } = this.randomOutletOptions as any
143
142
 
144
- options.channelCount = options.channelLabels.length
143
+ options.channelCount = options.channelNames.length
145
144
 
146
145
  delete options.manufacturer
147
146
  delete options.unit
148
147
  delete options.chunkSize
149
148
  delete options.maxBuffered
150
- delete options.channelLabels
149
+ delete options.channelNames
151
150
 
152
- assert.isEqualDeep(this.spyLsl.lastStreamInfoOptions, {
151
+ assert.isEqualDeep(this.spyLiblsl.lastCreateStreamInfoOptions, {
153
152
  ...options,
154
153
  channelFormat: this.channelIdx,
155
154
  })
156
155
  }
157
156
 
158
157
  @test()
159
- protected static async canOverrideClasInstantiatedInFactory() {
158
+ protected static async canOverrideClassInstantiatedInFactory() {
160
159
  LslOutlet.Class = CheckingOutlet
161
160
  const instance = this.Outlet()
162
161
  assert.isInstanceOf(instance, CheckingOutlet)
163
162
  }
164
163
 
165
- @test('can add one label', [generateId()])
166
- @test('can add two labels', [generateId(), generateId()])
164
+ @test('can add one label to channels', [generateId()])
165
+ @test('can add two labels to channels', [generateId(), generateId()])
167
166
  protected static async appendsChannelsBasedOnCount(labels: string[]) {
168
167
  const type = generateId()
169
168
  const unit = generateId()
170
169
 
171
- this.Outlet({ channelLabels: labels, type, unit })
170
+ this.Outlet({ channelNames: labels, type, unit })
172
171
 
173
- assert.isEqualDeep(this.spyLsl.lastAppendChannelsToStreamInfo, {
174
- info: this.spyLsl.streamInfo,
172
+ assert.isEqualDeep(this.spyLiblsl.lastAppendChannelsToStreamInfoOptions, {
173
+ info: this.spyLiblsl.streamInfo,
175
174
  channels: labels.map((label) => ({
176
175
  label,
177
176
  type,
@@ -180,6 +179,16 @@ export default class LslOutletTest extends AbstractSpruceTest {
180
179
  })
181
180
  }
182
181
 
182
+ @test()
183
+ protected static async pushSampleShouldNotCreateMultipleOutlets() {
184
+ const outlet = this.Outlet()
185
+ outlet.pushSample([1])
186
+ outlet.pushSample([2])
187
+ outlet.pushSample([3])
188
+
189
+ assert.isEqual(this.spyLiblsl.createStreamInfoHitCount, 1)
190
+ }
191
+
183
192
  private static pushSample(sample: LslSample) {
184
193
  const outlet = this.Outlet()
185
194
  outlet.pushSample(sample)
@@ -197,10 +206,10 @@ export default class LslOutletTest extends AbstractSpruceTest {
197
206
  this.assertDoesThrowInvalidParameters({ sampleRate }, ['sampleRate'])
198
207
  }
199
208
 
200
- private static assertThrowsInvalidChannelLabels(count: number) {
209
+ private static assertThrowsInvalidChannelNames(count: number) {
201
210
  this.assertDoesThrowInvalidParameters(
202
- { channelLabels: new Array(count).fill(generateId()) },
203
- ['channelLabels']
211
+ { channelNames: new Array(count).fill(generateId()) },
212
+ ['channelNames']
204
213
  )
205
214
  }
206
215
 
@@ -223,40 +232,34 @@ export default class LslOutletTest extends AbstractSpruceTest {
223
232
  }
224
233
 
225
234
  class SpyLiblsl implements Liblsl {
226
- public lastPushedOutlet?: LslBindingsOutlet
227
- public lastPushedSample?: LslSample
228
- public lastOutletOptions?: CreateOutletOptions
229
- public lastStreamInfoOptions?: CreateStreamInfoOptions
230
- public outlet: LslBindingsOutlet = {} as LslBindingsOutlet
231
- public streamInfo: LslBindingsStreamInfo = {} as LslBindingsStreamInfo
232
- public lastAppendChannelsToStreamInfo?: {
233
- info: LslBindingsStreamInfo
234
- channels: LslChannel[]
235
- }
236
-
237
- public createStreamInfo(
238
- options: CreateStreamInfoOptions
239
- ): LslBindingsStreamInfo {
240
- this.lastStreamInfoOptions = options
235
+ public lastCreateStreamInfoOptions?: CreateStreamInfoOptions
236
+ public lastAppendChannelsToStreamInfoOptions?: AppendChannelsToStreamInfoOptions
237
+ public lastCreateOutletOptions?: CreateOutletOptions
238
+ public lastPushSampleOptions?: PushSampleOptions
239
+
240
+ public outlet: BoundOutlet = {} as BoundOutlet
241
+ public streamInfo: BoundStreamInfo = {} as BoundStreamInfo
242
+ public createStreamInfoHitCount = 0
243
+
244
+ public createStreamInfo(options: CreateStreamInfoOptions): BoundStreamInfo {
245
+ this.createStreamInfoHitCount++
246
+ this.lastCreateStreamInfoOptions = options
241
247
  return this.streamInfo
242
248
  }
249
+
243
250
  public appendChannelsToStreamInfo(
244
- info: LslBindingsStreamInfo,
245
- channels: LslChannel[]
251
+ options: AppendChannelsToStreamInfoOptions
246
252
  ): void {
247
- this.lastAppendChannelsToStreamInfo = {
248
- info,
249
- channels,
250
- }
253
+ this.lastAppendChannelsToStreamInfoOptions = options
251
254
  }
252
255
 
253
- public createOutlet(options: CreateOutletOptions): LslBindingsOutlet {
254
- this.lastOutletOptions = options
256
+ public createOutlet(options: CreateOutletOptions): BoundOutlet {
257
+ this.lastCreateOutletOptions = options
255
258
  return this.outlet
256
259
  }
257
- public pushSample(outlet: LslBindingsOutlet, sample: LslSample): void {
258
- this.lastPushedOutlet = outlet
259
- this.lastPushedSample = sample
260
+
261
+ public pushSample(options: PushSampleOptions): void {
262
+ this.lastPushSampleOptions = options
260
263
  }
261
264
  }
262
265
 
@@ -8,16 +8,17 @@ import AbstractSpruceTest, {
8
8
  import ArrayType from 'ref-array-napi'
9
9
  import ref from 'ref-napi'
10
10
  import LiblslImpl, {
11
- CreateStreamInfoOptions,
12
- LiblslBindings,
13
11
  Liblsl,
14
- LslSample,
12
+ LiblslBindings,
13
+ CreateStreamInfoOptions,
14
+ AppendChannelsToStreamInfoOptions,
15
15
  CreateOutletOptions,
16
- LslBindingsOutlet,
17
- LslBindingsStreamInfo,
16
+ PushSampleOptions,
18
17
  LslChannel,
19
- LslBindingsDesc,
20
- LslBindingsChild,
18
+ BoundOutlet,
19
+ BoundStreamInfo,
20
+ BoundDesc,
21
+ BoundChild,
21
22
  } from '../../Liblsl'
22
23
 
23
24
  export default class LiblslTest extends AbstractSpruceTest {
@@ -25,10 +26,10 @@ export default class LiblslTest extends AbstractSpruceTest {
25
26
  private static libraryPath?: string
26
27
  private static libraryOptions?: Record<string, any>
27
28
  private static fakeBindings: LiblslBindings
28
- private static fakeStreamInfo: LslBindingsStreamInfo
29
- private static fakeOutlet: LslBindingsOutlet
30
- private static fakeDesc: LslBindingsDesc
31
- private static fakeChildNamedChannels: LslBindingsChild
29
+ private static fakeStreamInfo: BoundStreamInfo
30
+ private static fakeOutlet: BoundOutlet
31
+ private static fakeDesc: BoundDesc
32
+ private static fakeChildNamedChannels: BoundChild
32
33
  private static createStreamInfoParams?: any[]
33
34
  private static appendChildParams: any[] = []
34
35
  private static createOutletParams?: any[]
@@ -36,8 +37,8 @@ export default class LiblslTest extends AbstractSpruceTest {
36
37
  private static appendChildValueParams: any[]
37
38
  private static localClock: number
38
39
  private static shouldThrowWhenCreatingBindings: boolean
39
- private static getDescriptionParams?: [LslBindingsStreamInfo]
40
- private static fakeChildNamedChannel: LslBindingsChild
40
+ private static getDescriptionParams?: [BoundStreamInfo]
41
+ private static fakeChildNamedChannel: BoundChild
41
42
  private static appendChildHitCount: number
42
43
 
43
44
  protected static async beforeEach(): Promise<void> {
@@ -79,7 +80,7 @@ export default class LiblslTest extends AbstractSpruceTest {
79
80
  return 0
80
81
  },
81
82
  lsl_local_clock: () => this.localClock,
82
- lsl_get_desc: (info: LslBindingsStreamInfo) => {
83
+ lsl_get_desc: (info: BoundStreamInfo) => {
83
84
  this.getDescriptionParams = [info]
84
85
  return this.fakeDesc
85
86
  },
@@ -108,12 +109,12 @@ export default class LiblslTest extends AbstractSpruceTest {
108
109
  },
109
110
  }
110
111
 
111
- LiblslImpl.reset()
112
+ LiblslImpl.resetInstance()
112
113
  this.lsl = LiblslImpl.getInstance()
113
114
  }
114
115
 
115
116
  @test()
116
- protected static async throwsIfNoEnvSet() {
117
+ protected static async throwsWithMissingEnv() {
117
118
  delete process.env.LIBLSL_PATH
118
119
  const err = assert.doesThrow(() => new LiblslImpl())
119
120
  errorAssert.assertError(err, 'MISSING_PARAMETERS', {
@@ -122,7 +123,7 @@ export default class LiblslTest extends AbstractSpruceTest {
122
123
  }
123
124
 
124
125
  @test()
125
- protected static async throwsHelpfulErrorWhenBindingsFailToLoad() {
126
+ protected static async throwsWhenBindingsFailToLoad() {
126
127
  this.shouldThrowWhenCreatingBindings = true
127
128
  const err = assert.doesThrow(() => new LiblslImpl())
128
129
  errorAssert.assertError(err, 'FAILED_TO_LOAD_LIBLSL', {
@@ -130,6 +131,49 @@ export default class LiblslTest extends AbstractSpruceTest {
130
131
  })
131
132
  }
132
133
 
134
+ @test()
135
+ protected static throwsWhenCreateStreamInfoIsMissingRequiredParams() {
136
+ //@ts-ignore
137
+ const err = assert.doesThrow(() => this.lsl.createStreamInfo())
138
+ errorAssert.assertError(err, 'MISSING_PARAMETERS', {
139
+ parameters: [
140
+ 'name',
141
+ 'type',
142
+ 'channelCount',
143
+ 'sampleRate',
144
+ 'channelFormat',
145
+ 'sourceId',
146
+ ],
147
+ })
148
+ }
149
+
150
+ @test()
151
+ protected static async throwsWhenAppendChannelsIsMissingRequiredParams() {
152
+ //@ts-ignore
153
+ const err = assert.doesThrow(() => this.lsl.appendChannelsToStreamInfo({}))
154
+ errorAssert.assertError(err, 'MISSING_PARAMETERS', {
155
+ parameters: ['info', 'channels'],
156
+ })
157
+ }
158
+
159
+ @test()
160
+ protected static async throwsWhenCreateOutletIsMissingRequiredParams() {
161
+ //@ts-ignore
162
+ const err = assert.doesThrow(() => this.lsl.createOutlet({}))
163
+ errorAssert.assertError(err, 'MISSING_PARAMETERS', {
164
+ parameters: ['info', 'chunkSize', 'maxBuffered'],
165
+ })
166
+ }
167
+
168
+ @test()
169
+ protected static async throwsWhenPushSampleIsMissingRequiredParams() {
170
+ //@ts-ignore
171
+ const err = assert.doesThrow(() => this.lsl.pushSample())
172
+ errorAssert.assertError(err, 'MISSING_PARAMETERS', {
173
+ parameters: ['outlet', 'sample'],
174
+ })
175
+ }
176
+
133
177
  @test()
134
178
  protected static async worksAsASingleton() {
135
179
  const liblsl = LiblslImpl.getInstance()
@@ -172,23 +216,7 @@ export default class LiblslTest extends AbstractSpruceTest {
172
216
  }
173
217
 
174
218
  @test()
175
- protected static createStreamInfoThrowsWithMissingRequiredParams() {
176
- //@ts-ignore
177
- const err = assert.doesThrow(() => this.lsl.createStreamInfo())
178
- errorAssert.assertError(err, 'MISSING_PARAMETERS', {
179
- parameters: [
180
- 'name',
181
- 'type',
182
- 'channelCount',
183
- 'sampleRate',
184
- 'channelFormat',
185
- 'sourceId',
186
- ],
187
- })
188
- }
189
-
190
- @test()
191
- protected static async canGetStreamInfoWithRequiredParams() {
219
+ protected static async canCreateStreamInfoWithRequiredParams() {
192
220
  const options = this.generateRandomCreateStreamInfoOptions()
193
221
  const actual = this.lsl.createStreamInfo(options)
194
222
 
@@ -196,15 +224,6 @@ export default class LiblslTest extends AbstractSpruceTest {
196
224
  assert.isEqualDeep(this.createStreamInfoParams, Object.values(options))
197
225
  }
198
226
 
199
- @test()
200
- protected static async createOutletThrowsWhenMissingRequiredParams() {
201
- //@ts-ignore
202
- const err = assert.doesThrow(() => this.lsl.createOutlet({}))
203
- errorAssert.assertError(err, 'MISSING_PARAMETERS', {
204
- parameters: ['info', 'chunkSize', 'maxBuffered'],
205
- })
206
- }
207
-
208
227
  @test()
209
228
  protected static async canCreateOutletWithRequiredParams() {
210
229
  const info = this.createRandomStreamInfo()
@@ -219,37 +238,27 @@ export default class LiblslTest extends AbstractSpruceTest {
219
238
  }
220
239
 
221
240
  @test()
222
- protected static async pushSampleThrowsWhenMissingRequiredParams() {
223
- //@ts-ignore
224
- const err = assert.doesThrow(() => this.lsl.pushSample())
225
- errorAssert.assertError(err, 'MISSING_PARAMETERS', {
226
- parameters: ['outlet', 'sample'],
227
- })
228
- }
229
-
230
- @test()
231
- protected static async pushSampleCallsBindings() {
241
+ protected static async canPushSampleWithRequiredParams() {
232
242
  const expected = [1, 2, 3]
233
- this.lsl.pushSample(this.fakeOutlet, expected)
243
+ const options = {
244
+ outlet: this.fakeOutlet,
245
+ sample: expected,
246
+ }
247
+ this.lsl.pushSample(options)
234
248
  assert.isEqual(this.pushSampleParams?.[0], this.fakeOutlet)
235
249
  assert.isEqual(this.pushSampleParams?.[1], expected)
236
250
  assert.isEqual(this.pushSampleParams?.[2], this.localClock)
237
251
  }
238
252
 
239
- @test()
240
- protected static async appendChannelsThrowsWithMissingParams() {
241
- //@ts-ignore
242
- const err = assert.doesThrow(() => this.lsl.appendChannelsToStreamInfo())
243
- errorAssert.assertError(err, 'MISSING_PARAMETERS', {
244
- parameters: ['info', 'channels'],
245
- })
246
- }
247
-
248
253
  @test()
249
254
  protected static async addingSingleChannelGetsDescription() {
250
255
  const info = this.createRandomStreamInfo()
251
256
  const channel: LslChannel = this.generateRandomChannelValues()
252
- this.lsl.appendChannelsToStreamInfo(info, [channel])
257
+
258
+ this.lsl.appendChannelsToStreamInfo({
259
+ info,
260
+ channels: [channel],
261
+ })
253
262
  assert.isEqual(this.getDescriptionParams?.[0], info)
254
263
 
255
264
  assert.isEqual(this.appendChildParams?.[0][0], this.fakeDesc)
@@ -280,7 +289,10 @@ export default class LiblslTest extends AbstractSpruceTest {
280
289
  const channel1 = this.generateRandomChannelValues()
281
290
  const channel2 = this.generateRandomChannelValues()
282
291
 
283
- this.lsl.appendChannelsToStreamInfo(info, [channel1, channel2])
292
+ this.lsl.appendChannelsToStreamInfo({
293
+ info,
294
+ channels: [channel1, channel2],
295
+ })
284
296
 
285
297
  assert.isEqual(this.appendChildParams?.[2][0], this.fakeChildNamedChannels)
286
298
  assert.isEqual(this.appendChildParams?.[2][1], 'channel')
@@ -290,6 +302,12 @@ export default class LiblslTest extends AbstractSpruceTest {
290
302
  assert.isEqual(this.appendChildValueParams[5][2], channel2.type)
291
303
  }
292
304
 
305
+ private static createRandomStreamInfo() {
306
+ return this.lsl.createStreamInfo(
307
+ this.generateRandomCreateStreamInfoOptions()
308
+ )
309
+ }
310
+
293
311
  private static generateRandomChannelValues(): LslChannel {
294
312
  return {
295
313
  label: generateId(),
@@ -298,38 +316,32 @@ export default class LiblslTest extends AbstractSpruceTest {
298
316
  }
299
317
  }
300
318
 
301
- private static createRandomStreamInfo() {
302
- return this.lsl.createStreamInfo(
303
- this.generateRandomCreateStreamInfoOptions()
304
- )
305
- }
306
-
307
319
  private static generateRandomCreateStreamInfoOptions() {
308
320
  return {
309
321
  name: generateId(),
310
322
  type: generateId(),
311
- channelCount: randomInt(10),
312
- sampleRate: randomInt(10),
313
- channelFormat: randomInt(10),
323
+ channelCount: randomInt(1, 10),
324
+ sampleRate: randomInt(100),
325
+ channelFormat: randomInt(7),
314
326
  sourceId: generateId(),
315
327
  }
316
328
  }
317
329
  }
318
330
 
319
331
  class FakeLiblsl implements Liblsl {
332
+ public createStreamInfo(_options: CreateStreamInfoOptions): BoundStreamInfo {
333
+ return {} as BoundStreamInfo
334
+ }
335
+
320
336
  public appendChannelsToStreamInfo(
321
- _info: LslBindingsStreamInfo,
322
- _channels: LslChannel[]
337
+ _options: AppendChannelsToStreamInfoOptions
323
338
  ): void {}
324
- public createOutlet(_options: CreateOutletOptions): LslBindingsOutlet {
325
- return {} as LslBindingsOutlet
326
- }
327
- public createStreamInfo(
328
- _options: CreateStreamInfoOptions
329
- ): LslBindingsStreamInfo {
330
- return {} as LslBindingsStreamInfo
339
+
340
+ public createOutlet(_options: CreateOutletOptions): BoundOutlet {
341
+ return {} as BoundOutlet
331
342
  }
332
- public pushSample(_sample: LslSample): void {}
343
+
344
+ public pushSample(_options: PushSampleOptions): void {}
333
345
  }
334
346
 
335
347
  const streamInfo = ref.refType(ref.types.void)