@neurodevs/ndx-native 0.2.0 → 0.3.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 (61) hide show
  1. package/.regressionproof.json +7 -0
  2. package/.vscode/launch.json +52 -57
  3. package/.vscode/settings.json +62 -66
  4. package/.vscode/tasks.json +123 -129
  5. package/README.md +1 -0
  6. package/build/.spruce/settings.json +7 -7
  7. package/build/__tests__/AbstractPackageTest.d.ts +1 -0
  8. package/build/__tests__/AbstractPackageTest.js +1 -0
  9. package/build/__tests__/AbstractPackageTest.js.map +1 -1
  10. package/build/__tests__/impl/LabrecorderAdapter.test.d.ts +1 -1
  11. package/build/__tests__/impl/LabrecorderAdapter.test.js +9 -9
  12. package/build/__tests__/impl/LabrecorderAdapter.test.js.map +1 -1
  13. package/build/__tests__/impl/LiblslAdapter.test.d.ts +3 -4
  14. package/build/__tests__/impl/LiblslAdapter.test.js +18 -26
  15. package/build/__tests__/impl/LiblslAdapter.test.js.map +1 -1
  16. package/build/__tests__/impl/LibndxAdapter.test.d.ts +35 -0
  17. package/build/__tests__/impl/LibndxAdapter.test.js +258 -0
  18. package/build/__tests__/impl/LibndxAdapter.test.js.map +1 -0
  19. package/build/__tests__/impl/LibxdfAdapter.test.d.ts +1 -2
  20. package/build/__tests__/impl/LibxdfAdapter.test.js +5 -6
  21. package/build/__tests__/impl/LibxdfAdapter.test.js.map +1 -1
  22. package/build/impl/LiblslAdapter.d.ts +7 -9
  23. package/build/impl/LiblslAdapter.js +111 -117
  24. package/build/impl/LiblslAdapter.js.map +1 -1
  25. package/build/impl/LibndxAdapter.d.ts +57 -0
  26. package/build/impl/LibndxAdapter.js +145 -0
  27. package/build/impl/LibndxAdapter.js.map +1 -0
  28. package/build/impl/LibxdfAdapter.d.ts +3 -3
  29. package/build/impl/LibxdfAdapter.js +10 -7
  30. package/build/impl/LibxdfAdapter.js.map +1 -1
  31. package/build/index.d.ts +6 -2
  32. package/build/index.js +8 -3
  33. package/build/index.js.map +1 -1
  34. package/build/lib/{handleError.d.ts → handleLslError.d.ts} +1 -1
  35. package/build/lib/{handleError.js → handleLslError.js} +2 -2
  36. package/build/lib/handleLslError.js.map +1 -0
  37. package/build/testDoubles/Libndx/FakeLibndx.d.ts +22 -0
  38. package/build/testDoubles/Libndx/FakeLibndx.js +58 -0
  39. package/build/testDoubles/Libndx/FakeLibndx.js.map +1 -0
  40. package/build/types.d.ts +2 -0
  41. package/build/types.js +2 -0
  42. package/build/types.js.map +1 -0
  43. package/eslint.config.js +3 -0
  44. package/package.json +15 -31
  45. package/prettier.config.js +3 -0
  46. package/src/.spruce/settings.json +7 -7
  47. package/src/__tests__/AbstractPackageTest.ts +2 -0
  48. package/src/__tests__/impl/LabrecorderAdapter.test.ts +27 -11
  49. package/src/__tests__/impl/LiblslAdapter.test.ts +19 -26
  50. package/src/__tests__/impl/LibndxAdapter.test.ts +279 -0
  51. package/src/__tests__/impl/LibxdfAdapter.test.ts +5 -6
  52. package/src/impl/LiblslAdapter.ts +119 -127
  53. package/src/impl/LibndxAdapter.ts +204 -0
  54. package/src/impl/LibxdfAdapter.ts +13 -15
  55. package/src/index.ts +11 -3
  56. package/src/lib/{handleError.ts → handleLslError.ts} +1 -1
  57. package/src/testDoubles/Libndx/FakeLibndx.ts +74 -0
  58. package/src/types.ts +7 -0
  59. package/tsconfig.json +24 -27
  60. package/build/lib/handleError.js.map +0 -1
  61. package/eslint.config.mjs +0 -3
@@ -0,0 +1,279 @@
1
+ import { test, assert } from '@neurodevs/node-tdd'
2
+
3
+ import LibndxAdapter, {
4
+ Libndx,
5
+ LibndxBindings,
6
+ } from '../../impl/LibndxAdapter.js'
7
+ import AbstractPackageTest from '../AbstractPackageTest.js'
8
+ import { DataType, define, OpenParams } from 'ffi-rs'
9
+ import { FfiRsDefineOptions } from '../../types.js'
10
+ import FakeLibndx from '../../testDoubles/Libndx/FakeLibndx.js'
11
+
12
+ export default class LibndxAdapterTest extends AbstractPackageTest {
13
+ public static ffiRsDefine = define
14
+
15
+ private static instance: Libndx
16
+ private static libndxPath = this.generateId()
17
+ private static shouldThrowWhenLoadingBindings: boolean
18
+ private static fakeBindings: LibndxBindings
19
+
20
+ private static ffiRsOpenOptions?: OpenParams
21
+ private static ffiRsDefineOptions?: FfiRsDefineOptions
22
+
23
+ private static readonly bleDeviceUuid = this.generateId()
24
+ private static readonly ftdiSerialNumber = this.generateId()
25
+
26
+ protected static async beforeEach() {
27
+ await super.beforeEach()
28
+
29
+ this.shouldThrowWhenLoadingBindings = false
30
+ this.fakeBindings = this.FakeBindings()
31
+ this.clearAndFakeFfi()
32
+
33
+ this.resetInstance()
34
+ this.instance = this.LibndxAdapter()
35
+ }
36
+
37
+ @test()
38
+ protected static async createsInstance() {
39
+ assert.isTruthy(this.instance, 'Failed to create instance!')
40
+ }
41
+
42
+ @test()
43
+ protected static async throwsWhenBindingsFailToLoad() {
44
+ this.resetInstance()
45
+ this.shouldThrowWhenLoadingBindings = true
46
+
47
+ const err = assert.doesThrow(() => this.LibndxAdapter())
48
+ const actual = (err.message ?? err.stack).replace(/\s+/g, '')
49
+
50
+ assert.isEqual(
51
+ actual,
52
+ this.failedToLoadError,
53
+ 'Did not receive the expected error!'
54
+ )
55
+ }
56
+
57
+ @test()
58
+ protected static async callsFfiRsOpenWithRequiredOptions() {
59
+ assert.isEqualDeep(this.ffiRsOpenOptions, {
60
+ library: 'ndx',
61
+ path: this.libndxPath,
62
+ })
63
+ }
64
+
65
+ @test()
66
+ protected static async callsFfiRsDefineWithRequiredOptions() {
67
+ assert.isEqualDeep(
68
+ this.ffiRsDefineOptions,
69
+ {
70
+ create_ble_backend: {
71
+ library: 'ndx',
72
+ retType: DataType.String,
73
+ paramsType: [DataType.String],
74
+ },
75
+ start_ble_backend: {
76
+ library: 'ndx',
77
+ retType: DataType.String,
78
+ paramsType: [DataType.String],
79
+ },
80
+ stop_ble_backend: {
81
+ library: 'ndx',
82
+ retType: DataType.String,
83
+ paramsType: [DataType.String],
84
+ },
85
+ destroy_ble_backend: {
86
+ library: 'ndx',
87
+ retType: DataType.String,
88
+ paramsType: [DataType.String],
89
+ },
90
+ create_ftdi_backend: {
91
+ library: 'ndx',
92
+ retType: DataType.String,
93
+ paramsType: [DataType.String],
94
+ },
95
+ start_ftdi_backend: {
96
+ library: 'ndx',
97
+ retType: DataType.String,
98
+ paramsType: [DataType.String],
99
+ },
100
+ stop_ftdi_backend: {
101
+ library: 'ndx',
102
+ retType: DataType.String,
103
+ paramsType: [DataType.String],
104
+ },
105
+ destroy_ftdi_backend: {
106
+ library: 'ndx',
107
+ retType: DataType.String,
108
+ paramsType: [DataType.String],
109
+ },
110
+ },
111
+ 'Did not pass valid options to ffiRsDefine!'
112
+ )
113
+ }
114
+
115
+ @test()
116
+ protected static async getInstanceReturnsASingleton() {
117
+ assert.isEqual(LibndxAdapter.getInstance(), LibndxAdapter.getInstance())
118
+ }
119
+
120
+ @test()
121
+ protected static canSetInstance() {
122
+ const fake = new FakeLibndx()
123
+ LibndxAdapter.setInstance(fake)
124
+ assert.isEqual(LibndxAdapter.getInstance(), fake)
125
+ }
126
+
127
+ @test()
128
+ protected static async createBleBackendCallsBindingAndReturnsJsonString() {
129
+ const raw = this.instance.createBleBackend({
130
+ deviceUuid: this.bleDeviceUuid,
131
+ })
132
+ const json = JSON.parse(raw)
133
+
134
+ assert.isTruthy(json, 'createBleBackend did not return a JSON string!')
135
+ }
136
+
137
+ @test()
138
+ protected static async startBleBackendCallsBindingAndReturnsJsonString() {
139
+ const raw = this.instance.startBleBackend({
140
+ deviceUuid: this.bleDeviceUuid,
141
+ })
142
+ const json = JSON.parse(raw)
143
+
144
+ assert.isTruthy(json, 'startBleBackend did not return a JSON string!')
145
+ }
146
+
147
+ @test()
148
+ protected static async stopBleBackendCallsBindingAndReturnsJsonString() {
149
+ const raw = this.instance.stopBleBackend({
150
+ deviceUuid: this.bleDeviceUuid,
151
+ })
152
+ const json = JSON.parse(raw)
153
+
154
+ assert.isTruthy(json, 'stopBleBackend did not return a JSON string!')
155
+ }
156
+
157
+ @test()
158
+ protected static async destroyBleBackendCallsBindingAndReturnsJsonString() {
159
+ const raw = this.instance.destroyBleBackend({
160
+ deviceUuid: this.bleDeviceUuid,
161
+ })
162
+ const json = JSON.parse(raw)
163
+
164
+ assert.isTruthy(json, 'destroyBleBackend did not return a JSON string!')
165
+ }
166
+
167
+ @test()
168
+ protected static async createFtdiBackendCallsBindingAndReturnsJsonString() {
169
+ const raw = this.instance.createFtdiBackend({
170
+ serialNumber: this.ftdiSerialNumber,
171
+ })
172
+ const json = JSON.parse(raw)
173
+
174
+ assert.isTruthy(json, 'createFtdiBackend did not return a JSON string!')
175
+ }
176
+
177
+ @test()
178
+ protected static async startFtdiBackendCallsBindingAndReturnsJsonString() {
179
+ const raw = this.instance.startFtdiBackend({
180
+ serialNumber: this.ftdiSerialNumber,
181
+ })
182
+ const json = JSON.parse(raw)
183
+
184
+ assert.isTruthy(json, 'startFtdiBackend did not return a JSON string!')
185
+ }
186
+
187
+ @test()
188
+ protected static async stopFtdiBackendCallsBindingAndReturnsJsonString() {
189
+ const raw = this.instance.stopFtdiBackend({
190
+ serialNumber: this.ftdiSerialNumber,
191
+ })
192
+ const json = JSON.parse(raw)
193
+
194
+ assert.isTruthy(json, 'stopFtdiBackend did not return a JSON string!')
195
+ }
196
+
197
+ @test()
198
+ protected static async destroyFtdiBackendCallsBindingAndReturnsJsonString() {
199
+ const raw = this.instance.destroyFtdiBackend({
200
+ serialNumber: this.ftdiSerialNumber,
201
+ })
202
+ const json = JSON.parse(raw)
203
+
204
+ assert.isTruthy(
205
+ json,
206
+ 'destroyFtdiBackend did not return a JSON string!'
207
+ )
208
+ }
209
+
210
+ private static clearAndFakeFfi() {
211
+ delete this.ffiRsOpenOptions
212
+ delete this.ffiRsDefineOptions
213
+ this.fakeFfiRsOpen()
214
+ this.fakeFfiRsDefine()
215
+ }
216
+
217
+ private static fakeFfiRsOpen() {
218
+ LibndxAdapter.ffiRsOpen = (options) => {
219
+ this.ffiRsOpenOptions = options
220
+ }
221
+ }
222
+
223
+ private static fakeFfiRsDefine() {
224
+ LibndxAdapter.ffiRsDefine = ((options) => {
225
+ this.ffiRsDefineOptions = options
226
+
227
+ if (this.shouldThrowWhenLoadingBindings) {
228
+ throw new Error(this.fakeErrorMessage)
229
+ }
230
+
231
+ return this.fakeBindings as any
232
+ }) as typeof define
233
+ }
234
+
235
+ private static get failedToLoadError() {
236
+ return `
237
+ \n -----------------------------------
238
+ \n Failed to load libndx! Tried to load from:
239
+ \n ${this.libndxPath}
240
+ \n Instructions to save your day (on MacOS):
241
+ \n 1. git clone https://github.com/neurodevs/libndx.git
242
+ \n 2. cd libndx && cmake -S . -B build && cmake --build build
243
+ \n 3. sudo cp build/libndx.dylib /opt/local/lib/
244
+ \n 4. Try whatever you were doing again!
245
+ \n Modify step 3 for your OS if you are not on MacOS.
246
+ \n If you're still unsure, ask an LLM with this error and your OS.
247
+ \n You could also post an issue on the repo:
248
+ \n https://github.com/neurodevs/ndx-native/issues
249
+ \n Good luck!
250
+ \n @ericthecurious
251
+ \n -----------------------------------
252
+ \n Original error: ${this.fakeErrorMessage}
253
+ \n
254
+ `.replace(/\s+/g, '')
255
+ }
256
+
257
+ private static FakeBindings(): LibndxBindings {
258
+ return {
259
+ create_ble_backend: () => JSON.stringify({}),
260
+ start_ble_backend: () => JSON.stringify({}),
261
+ stop_ble_backend: () => JSON.stringify({}),
262
+ destroy_ble_backend: () => JSON.stringify({}),
263
+ create_ftdi_backend: () => JSON.stringify({}),
264
+ start_ftdi_backend: () => JSON.stringify({}),
265
+ stop_ftdi_backend: () => JSON.stringify({}),
266
+ destroy_ftdi_backend: () => JSON.stringify({}),
267
+ }
268
+ }
269
+
270
+ private static resetInstance() {
271
+ LibndxAdapter.resetInstance()
272
+ }
273
+
274
+ private static LibndxAdapter() {
275
+ return LibndxAdapter.getInstance({
276
+ libndxPath: this.libndxPath,
277
+ })
278
+ }
279
+ }
@@ -7,10 +7,10 @@ import { test, assert } from '@neurodevs/node-tdd'
7
7
  import { DataType, OpenParams } from 'ffi-rs'
8
8
 
9
9
  import LibxdfAdapter, {
10
- FfiRsDefineOptions,
11
10
  LibxdfBindings,
12
11
  XdfFile,
13
12
  } from '../../impl/LibxdfAdapter.js'
13
+ import { FfiRsDefineOptions } from 'types.js'
14
14
  import SpyLibxdf from '../../testDoubles/Libxdf/SpyLibxdf.js'
15
15
  import AbstractPackageTest from '../AbstractPackageTest.js'
16
16
 
@@ -44,8 +44,8 @@ export default class LibxdfTest extends AbstractPackageTest {
44
44
  }
45
45
 
46
46
  @test()
47
- protected static canCreateInstance() {
48
- assert.isTruthy(this.instance, 'Should create an instance!')
47
+ protected static createsInstance() {
48
+ assert.isTruthy(this.instance, 'Failed to create instance!')
49
49
  }
50
50
 
51
51
  @test()
@@ -90,7 +90,7 @@ export default class LibxdfTest extends AbstractPackageTest {
90
90
  paramsType: [DataType.String],
91
91
  },
92
92
  },
93
- 'Please pass valid options to ffiRsDefine!'
93
+ 'Did not pass valid options to ffiRsDefine!'
94
94
  )
95
95
  }
96
96
 
@@ -101,7 +101,7 @@ export default class LibxdfTest extends AbstractPackageTest {
101
101
  assert.isEqualDeep(
102
102
  this.loadXdfCalls[0],
103
103
  [this.path],
104
- 'Should have called load_xdf_to_json(path)!'
104
+ 'Did not call load_xdf_to_json(path)!'
105
105
  )
106
106
  }
107
107
 
@@ -241,7 +241,6 @@ export default class LibxdfTest extends AbstractPackageTest {
241
241
  private static readonly fakeNominalSampleRate = 0
242
242
  private static readonly fakeEventName = generateId()
243
243
  private static readonly fakeEventTimestamp = 0
244
- private static readonly fakeErrorMessage = 'Fake error message!'
245
244
 
246
245
  private static fakeSerializedXdf = `{"streams": [{"stream_id": ${this.fakeStreamId}, "time_series": [], "time_stamps": [], "stream_info": {"channel_count": ${this.fakeChannelCount}, "channel_format": "${this.fakeChannelFormat}", "nominal_srate": ${this.fakeNominalSampleRate}, "stream_name": "${this.fakeStreamName}", "stream_type": "${this.fakeStreamType}"}}], "events": [{"stream_id": ${this.fakeStreamId}, "event_name": "${this.fakeEventName}", "event_timestamp": ${this.fakeEventTimestamp}}]}`
247
246
 
@@ -9,7 +9,7 @@ import {
9
9
  } from 'ffi-rs'
10
10
 
11
11
  import { CHANNEL_FORMATS } from '../consts.js'
12
- import { LslErrorCode } from '../lib/handleError.js'
12
+ import { LslErrorCode } from '../lib/handleLslError.js'
13
13
 
14
14
  export default class LiblslAdapter implements Liblsl {
15
15
  public static open = open
@@ -29,20 +29,6 @@ export default class LiblslAdapter implements Liblsl {
29
29
  this.tryToLoadBindings()
30
30
  }
31
31
 
32
- private tryToLoadBindings() {
33
- try {
34
- this.loadBindings()
35
- } catch (error) {
36
- this.throwFailedToLoadLiblsl(error as Error)
37
- }
38
- }
39
-
40
- private throwFailedToLoadLiblsl(error: Error) {
41
- throw new Error(
42
- `Loading the liblsl dylib failed! I tried to load it from ${this.liblslPath}.\n\n${error.message}\n\n`
43
- )
44
- }
45
-
46
32
  public static getInstance() {
47
33
  if (!this.instance) {
48
34
  this.setInstance(new this())
@@ -58,9 +44,13 @@ export default class LiblslAdapter implements Liblsl {
58
44
  delete this.instance
59
45
  }
60
46
 
61
- private loadBindings() {
62
- this.openLiblsl()
63
- this.bindings = this.defineLiblslBindings()
47
+ private tryToLoadBindings() {
48
+ try {
49
+ this.openLiblsl()
50
+ this.defineBindings()
51
+ } catch (error) {
52
+ this.throwFailedToLoadLiblsl(error as Error)
53
+ }
64
54
  }
65
55
 
66
56
  private openLiblsl() {
@@ -70,8 +60,113 @@ export default class LiblslAdapter implements Liblsl {
70
60
  })
71
61
  }
72
62
 
73
- private defineLiblslBindings() {
74
- return this.define(this.liblslFuncs) as LiblslBindings
63
+ private defineBindings() {
64
+ this.bindings = this.define({
65
+ lsl_local_clock: {
66
+ library: 'lsl',
67
+ retType: DataType.Double,
68
+ paramsType: [],
69
+ },
70
+ lsl_create_streaminfo: {
71
+ library: 'lsl',
72
+ retType: DataType.External,
73
+ paramsType: [
74
+ DataType.String,
75
+ DataType.String,
76
+ DataType.I32,
77
+ DataType.Double,
78
+ DataType.I32,
79
+ DataType.String,
80
+ ],
81
+ },
82
+ lsl_destroy_streaminfo: {
83
+ library: 'lsl',
84
+ retType: DataType.Void,
85
+ paramsType: [DataType.External],
86
+ },
87
+ lsl_create_outlet: {
88
+ library: 'lsl',
89
+ retType: DataType.External,
90
+ paramsType: [DataType.External, DataType.I32, DataType.I32],
91
+ },
92
+ lsl_push_sample_ft: {
93
+ library: 'lsl',
94
+ retType: DataType.I32,
95
+ paramsType: [
96
+ DataType.External,
97
+ DataType.FloatArray,
98
+ DataType.Double,
99
+ ],
100
+ },
101
+ lsl_push_sample_strt: {
102
+ library: 'lsl',
103
+ retType: DataType.I32,
104
+ paramsType: [
105
+ DataType.External,
106
+ DataType.StringArray,
107
+ DataType.Double,
108
+ ],
109
+ },
110
+ lsl_destroy_outlet: {
111
+ library: 'lsl',
112
+ retType: DataType.Void,
113
+ paramsType: [DataType.External],
114
+ },
115
+ lsl_create_inlet: {
116
+ library: 'lsl',
117
+ retType: DataType.External,
118
+ paramsType: [
119
+ DataType.External,
120
+ DataType.I32,
121
+ DataType.I32,
122
+ DataType.I32,
123
+ ],
124
+ },
125
+ lsl_inlet_flush: {
126
+ library: 'lsl',
127
+ retType: DataType.I32,
128
+ paramsType: [DataType.External],
129
+ },
130
+ lsl_destroy_inlet: {
131
+ library: 'lsl',
132
+ retType: DataType.Void,
133
+ paramsType: [DataType.External],
134
+ },
135
+ lsl_get_desc: {
136
+ library: 'lsl',
137
+ retType: DataType.External,
138
+ paramsType: [DataType.External],
139
+ },
140
+ lsl_get_channel_count: {
141
+ library: 'lsl',
142
+ retType: DataType.I32,
143
+ paramsType: [DataType.External],
144
+ },
145
+ lsl_append_child: {
146
+ library: 'lsl',
147
+ retType: DataType.External,
148
+ paramsType: [DataType.External, DataType.String],
149
+ },
150
+ lsl_append_child_value: {
151
+ library: 'lsl',
152
+ retType: DataType.External,
153
+ paramsType: [
154
+ DataType.External,
155
+ DataType.String,
156
+ DataType.String,
157
+ ],
158
+ },
159
+ }) as LiblslBindings
160
+ }
161
+
162
+ private throwFailedToLoadLiblsl(error: Error) {
163
+ throw new Error(
164
+ `Loading the liblsl dylib failed! I tried to load it from ${this.liblslPath}.\n\n${error.message}\n\n`
165
+ )
166
+ }
167
+
168
+ public localClock() {
169
+ return this.bindings.lsl_local_clock([])
75
170
  }
76
171
 
77
172
  public createStreamInfo(options: CreateStreamInfoOptions) {
@@ -332,10 +427,6 @@ export default class LiblslAdapter implements Liblsl {
332
427
  this.bindings.lsl_destroy_inlet([inletHandle])
333
428
  }
334
429
 
335
- public localClock() {
336
- return this.bindings.lsl_local_clock([])
337
- }
338
-
339
430
  private get open() {
340
431
  return LiblslAdapter.open
341
432
  }
@@ -351,110 +442,13 @@ export default class LiblslAdapter implements Liblsl {
351
442
  private get alloc() {
352
443
  return LiblslAdapter.alloc
353
444
  }
354
-
355
- private get liblslFuncs() {
356
- return {
357
- lsl_create_streaminfo: {
358
- library: 'lsl',
359
- retType: DataType.External,
360
- paramsType: [
361
- DataType.String,
362
- DataType.String,
363
- DataType.I32,
364
- DataType.Double,
365
- DataType.I32,
366
- DataType.String,
367
- ],
368
- },
369
- lsl_destroy_streaminfo: {
370
- library: 'lsl',
371
- retType: DataType.Void,
372
- paramsType: [DataType.External],
373
- },
374
- lsl_create_outlet: {
375
- library: 'lsl',
376
- retType: DataType.External,
377
- paramsType: [DataType.External, DataType.I32, DataType.I32],
378
- },
379
- lsl_push_sample_ft: {
380
- library: 'lsl',
381
- retType: DataType.I32,
382
- paramsType: [
383
- DataType.External,
384
- DataType.FloatArray,
385
- DataType.Double,
386
- ],
387
- },
388
- lsl_push_sample_strt: {
389
- library: 'lsl',
390
- retType: DataType.I32,
391
- paramsType: [
392
- DataType.External,
393
- DataType.StringArray,
394
- DataType.Double,
395
- ],
396
- },
397
- lsl_destroy_outlet: {
398
- library: 'lsl',
399
- retType: DataType.Void,
400
- paramsType: [DataType.External],
401
- },
402
- lsl_create_inlet: {
403
- library: 'lsl',
404
- retType: DataType.External,
405
- paramsType: [
406
- DataType.External,
407
- DataType.I32,
408
- DataType.I32,
409
- DataType.I32,
410
- ],
411
- },
412
- lsl_inlet_flush: {
413
- library: 'lsl',
414
- retType: DataType.I32,
415
- paramsType: [DataType.External],
416
- },
417
- lsl_destroy_inlet: {
418
- library: 'lsl',
419
- retType: DataType.Void,
420
- paramsType: [DataType.External],
421
- },
422
- lsl_get_desc: {
423
- library: 'lsl',
424
- retType: DataType.External,
425
- paramsType: [DataType.External],
426
- },
427
- lsl_get_channel_count: {
428
- library: 'lsl',
429
- retType: DataType.I32,
430
- paramsType: [DataType.External],
431
- },
432
- lsl_append_child: {
433
- library: 'lsl',
434
- retType: DataType.External,
435
- paramsType: [DataType.External, DataType.String],
436
- },
437
- lsl_append_child_value: {
438
- library: 'lsl',
439
- retType: DataType.External,
440
- paramsType: [
441
- DataType.External,
442
- DataType.String,
443
- DataType.String,
444
- ],
445
- },
446
- lsl_local_clock: {
447
- library: 'lsl',
448
- retType: DataType.Double,
449
- paramsType: [],
450
- },
451
- }
452
- }
453
445
  }
454
446
 
455
447
  export interface Liblsl {
456
448
  liblslPath: string
457
449
 
450
+ localClock(): number
451
+
458
452
  createStreamInfo(options: CreateStreamInfoOptions): InfoHandle
459
453
  destroyStreamInfo(options: DestroyStreamInfoOptions): void
460
454
  appendChannelsToStreamInfo(options: AppendChannelsToStreamInfoOptions): void
@@ -481,8 +475,6 @@ export interface Liblsl {
481
475
  pullChunk(options: PullChunkOptions): number
482
476
  flushInlet(options: FlushInletOptions): void
483
477
  destroyInlet(options: DestroyInletOptions): void
484
-
485
- localClock(): number
486
478
  }
487
479
 
488
480
  export interface CreateStreamInfoOptions {
@@ -575,6 +567,8 @@ export interface DestroyInletOptions {
575
567
  }
576
568
 
577
569
  export interface LiblslBindings {
570
+ lsl_local_clock(args: []): number
571
+
578
572
  lsl_create_streaminfo(
579
573
  args: [string, string, number, number, number, string]
580
574
  ): InfoHandle
@@ -593,8 +587,6 @@ export interface LiblslBindings {
593
587
  lsl_create_inlet(args: any): InletHandle
594
588
  lsl_inlet_flush(args: [InletHandle]): void
595
589
  lsl_destroy_inlet(args: any): void
596
-
597
- lsl_local_clock(args: []): number
598
590
  }
599
591
 
600
592
  export type ChannelFormat = (typeof CHANNEL_FORMATS)[number]