@neurodevs/ndx-native 0.1.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 (65) 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 -28
  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 +11 -13
  23. package/build/impl/LiblslAdapter.js +115 -123
  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/Liblsl/FakeLiblsl.d.ts +3 -3
  38. package/build/testDoubles/Liblsl/FakeLiblsl.js +3 -3
  39. package/build/testDoubles/Liblsl/FakeLiblsl.js.map +1 -1
  40. package/build/testDoubles/Libndx/FakeLibndx.d.ts +22 -0
  41. package/build/testDoubles/Libndx/FakeLibndx.js +58 -0
  42. package/build/testDoubles/Libndx/FakeLibndx.js.map +1 -0
  43. package/build/types.d.ts +2 -0
  44. package/build/types.js +2 -0
  45. package/build/types.js.map +1 -0
  46. package/eslint.config.js +3 -0
  47. package/package.json +15 -31
  48. package/prettier.config.js +3 -0
  49. package/src/.spruce/settings.json +7 -7
  50. package/src/__tests__/AbstractPackageTest.ts +2 -0
  51. package/src/__tests__/impl/LabrecorderAdapter.test.ts +27 -11
  52. package/src/__tests__/impl/LiblslAdapter.test.ts +19 -28
  53. package/src/__tests__/impl/LibndxAdapter.test.ts +279 -0
  54. package/src/__tests__/impl/LibxdfAdapter.test.ts +5 -6
  55. package/src/impl/LiblslAdapter.ts +125 -135
  56. package/src/impl/LibndxAdapter.ts +204 -0
  57. package/src/impl/LibxdfAdapter.ts +13 -15
  58. package/src/index.ts +11 -3
  59. package/src/lib/{handleError.ts → handleLslError.ts} +1 -1
  60. package/src/testDoubles/Liblsl/FakeLiblsl.ts +3 -3
  61. package/src/testDoubles/Libndx/FakeLibndx.ts +74 -0
  62. package/src/types.ts +7 -0
  63. package/tsconfig.json +24 -27
  64. package/build/lib/handleError.js.map +0 -1
  65. package/eslint.config.mjs +0 -3
@@ -0,0 +1,204 @@
1
+ import { DataType, define, open } from 'ffi-rs'
2
+
3
+ export default class LibndxAdapter implements Libndx {
4
+ public static Class?: LibndxConstructor
5
+ public static ffiRsOpen = open
6
+ public static ffiRsDefine = define
7
+
8
+ private static instance?: Libndx
9
+
10
+ private libndxPath: string
11
+ private bindings!: LibndxBindings
12
+
13
+ protected constructor(options?: LibndxAdapterOptions) {
14
+ const { libndxPath = '' } = options ?? {}
15
+
16
+ this.libndxPath = libndxPath
17
+
18
+ this.tryToLoadBindings()
19
+ }
20
+
21
+ public static getInstance(options?: LibndxAdapterOptions) {
22
+ if (!this.instance) {
23
+ this.setInstance(new this(options))
24
+ }
25
+ return this.instance!
26
+ }
27
+
28
+ public static setInstance(instance: Libndx) {
29
+ this.instance = instance
30
+ }
31
+
32
+ public static resetInstance() {
33
+ delete this.instance
34
+ }
35
+
36
+ private tryToLoadBindings() {
37
+ try {
38
+ this.openLibndx()
39
+ this.defineBindings()
40
+ } catch (err: unknown) {
41
+ this.throwFailedToLoadLibndx(err as Error)
42
+ }
43
+ }
44
+
45
+ private openLibndx() {
46
+ this.ffiRsOpen({
47
+ library: 'ndx',
48
+ path: this.libndxPath,
49
+ })
50
+ }
51
+
52
+ private defineBindings() {
53
+ this.bindings = this.ffiRsDefine({
54
+ create_ble_backend: {
55
+ library: 'ndx',
56
+ retType: DataType.String,
57
+ paramsType: [DataType.String],
58
+ },
59
+ start_ble_backend: {
60
+ library: 'ndx',
61
+ retType: DataType.String,
62
+ paramsType: [DataType.String],
63
+ },
64
+ stop_ble_backend: {
65
+ library: 'ndx',
66
+ retType: DataType.String,
67
+ paramsType: [DataType.String],
68
+ },
69
+ destroy_ble_backend: {
70
+ library: 'ndx',
71
+ retType: DataType.String,
72
+ paramsType: [DataType.String],
73
+ },
74
+ create_ftdi_backend: {
75
+ library: 'ndx',
76
+ retType: DataType.String,
77
+ paramsType: [DataType.String],
78
+ },
79
+ start_ftdi_backend: {
80
+ library: 'ndx',
81
+ retType: DataType.String,
82
+ paramsType: [DataType.String],
83
+ },
84
+ stop_ftdi_backend: {
85
+ library: 'ndx',
86
+ retType: DataType.String,
87
+ paramsType: [DataType.String],
88
+ },
89
+ destroy_ftdi_backend: {
90
+ library: 'ndx',
91
+ retType: DataType.String,
92
+ paramsType: [DataType.String],
93
+ },
94
+ }) as LibndxBindings
95
+ }
96
+
97
+ private throwFailedToLoadLibndx(err: Error) {
98
+ throw new Error(
99
+ `
100
+ \n -----------------------------------
101
+ \n Failed to load libndx! Tried to load from:
102
+ \n ${this.libndxPath}
103
+ \n Instructions to save your day (on MacOS):
104
+ \n 1. git clone https://github.com/neurodevs/libndx.git
105
+ \n 2. cd libndx && cmake -S . -B build && cmake --build build
106
+ \n 3. sudo cp build/libndx.dylib /opt/local/lib/
107
+ \n 4. Try whatever you were doing again!
108
+ \n Modify step 3 for your OS if you are not on MacOS.
109
+ \n If you're still unsure, ask an LLM with this error and your OS.
110
+ \n You could also post an issue on the repo:
111
+ \n https://github.com/neurodevs/ndx-native/issues
112
+ \n Good luck!
113
+ \n @ericthecurious
114
+ \n -----------------------------------
115
+ \n Original error: ${err.message}
116
+ \n
117
+ `.replace(/\s+/g, '')
118
+ )
119
+ }
120
+
121
+ public createBleBackend(options: BleBackendOptions) {
122
+ const { deviceUuid } = options
123
+ return this.bindings.create_ble_backend([deviceUuid])
124
+ }
125
+
126
+ public startBleBackend(options: BleBackendOptions) {
127
+ const { deviceUuid } = options
128
+ return this.bindings.start_ble_backend([deviceUuid])
129
+ }
130
+
131
+ public stopBleBackend(options: BleBackendOptions) {
132
+ const { deviceUuid } = options
133
+ return this.bindings.stop_ble_backend([deviceUuid])
134
+ }
135
+
136
+ public destroyBleBackend(options: BleBackendOptions) {
137
+ const { deviceUuid } = options
138
+ return this.bindings.destroy_ble_backend([deviceUuid])
139
+ }
140
+
141
+ public createFtdiBackend(options: FtdiBackendOptions) {
142
+ const { serialNumber } = options
143
+ return this.bindings.create_ftdi_backend([serialNumber])
144
+ }
145
+
146
+ public startFtdiBackend(options: FtdiBackendOptions) {
147
+ const { serialNumber } = options
148
+ return this.bindings.start_ftdi_backend([serialNumber])
149
+ }
150
+
151
+ public stopFtdiBackend(options: FtdiBackendOptions) {
152
+ const { serialNumber } = options
153
+ return this.bindings.stop_ftdi_backend([serialNumber])
154
+ }
155
+
156
+ public destroyFtdiBackend(options: FtdiBackendOptions) {
157
+ const { serialNumber } = options
158
+ return this.bindings.destroy_ftdi_backend([serialNumber])
159
+ }
160
+
161
+ private get ffiRsOpen() {
162
+ return LibndxAdapter.ffiRsOpen
163
+ }
164
+
165
+ private get ffiRsDefine() {
166
+ return LibndxAdapter.ffiRsDefine
167
+ }
168
+ }
169
+
170
+ export interface Libndx {
171
+ createBleBackend(options: BleBackendOptions): string
172
+ startBleBackend(options: BleBackendOptions): string
173
+ stopBleBackend(options: BleBackendOptions): string
174
+ destroyBleBackend(options: BleBackendOptions): string
175
+ createFtdiBackend(options: FtdiBackendOptions): string
176
+ startFtdiBackend(options: FtdiBackendOptions): string
177
+ stopFtdiBackend(options: FtdiBackendOptions): string
178
+ destroyFtdiBackend(options: FtdiBackendOptions): string
179
+ }
180
+
181
+ export type LibndxConstructor = new (options?: LibndxAdapterOptions) => Libndx
182
+
183
+ export interface LibndxAdapterOptions {
184
+ libndxPath?: string
185
+ }
186
+
187
+ export interface BleBackendOptions {
188
+ deviceUuid: string
189
+ }
190
+
191
+ export interface FtdiBackendOptions {
192
+ serialNumber: string
193
+ }
194
+
195
+ export interface LibndxBindings {
196
+ create_ble_backend(args: [string]): string
197
+ start_ble_backend(args: [string]): string
198
+ stop_ble_backend(args: [string]): string
199
+ destroy_ble_backend(args: [string]): string
200
+ create_ftdi_backend(args: [string]): string
201
+ start_ftdi_backend(args: [string]): string
202
+ stop_ftdi_backend(args: [string]): string
203
+ destroy_ftdi_backend(args: [string]): string
204
+ }
@@ -3,7 +3,7 @@ import {
3
3
  MangledNameExtractor,
4
4
  MangledNameMap,
5
5
  } from '@neurodevs/node-mangled-names'
6
- import { DataType, define, FieldType, FuncObj, open } from 'ffi-rs'
6
+ import { DataType, define, open } from 'ffi-rs'
7
7
 
8
8
  export default class LibxdfAdapter implements Libxdf {
9
9
  public static Class?: LibxdfConstructor
@@ -37,19 +37,15 @@ export default class LibxdfAdapter implements Libxdf {
37
37
 
38
38
  private tryToLoadBindings() {
39
39
  try {
40
- this.bindings = this.loadBindings()
40
+ this.openLibxdf()
41
+ this.bindings = this.defineBindings()
41
42
  } catch (err: unknown) {
42
43
  this.throwFailedToLoadLiblsl(err)
43
44
  }
44
45
  }
45
46
 
46
- private loadBindings() {
47
- this.openLibxdf()
48
- return this.defineBindings()
49
- }
50
-
51
47
  private openLibxdf() {
52
- LibxdfAdapter.ffiRsOpen({
48
+ this.ffiRsOpen({
53
49
  library: 'xdf',
54
50
  path: this.libxdfPath,
55
51
  })
@@ -68,7 +64,7 @@ export default class LibxdfAdapter implements Libxdf {
68
64
  return acc
69
65
  }, {})
70
66
 
71
- return LibxdfAdapter.ffiRsDefine(funcs)
67
+ return this.ffiRsDefine(funcs)
72
68
  }
73
69
 
74
70
  private throwFailedToLoadLiblsl(err: unknown) {
@@ -126,6 +122,14 @@ export default class LibxdfAdapter implements Libxdf {
126
122
  return LibxdfAdapter.loadXdfName
127
123
  }
128
124
 
125
+ private get ffiRsOpen() {
126
+ return LibxdfAdapter.ffiRsOpen
127
+ }
128
+
129
+ private get ffiRsDefine() {
130
+ return LibxdfAdapter.ffiRsDefine
131
+ }
132
+
129
133
  private static generateFailedMessage(libxdfPath: string) {
130
134
  return `
131
135
  \n -----------------------------------
@@ -171,12 +175,6 @@ export type LibxdfBindings = Record<string, (path: string[]) => string>
171
175
 
172
176
  export type LibxdfStatusCode = 0 | Exclude<number, 0>
173
177
 
174
- export type FfiRsDefineOptions = FuncObj<
175
- FieldType,
176
- boolean | undefined,
177
- boolean | undefined
178
- >
179
-
180
178
  export interface XdfFile {
181
179
  path: string
182
180
  streams: XdfStream[]
package/src/index.ts CHANGED
@@ -14,6 +14,14 @@ export * from './impl/LiblslAdapter.js'
14
14
  export { default as FakeLiblsl } from './testDoubles/Liblsl/FakeLiblsl.js'
15
15
  export * from './testDoubles/Liblsl/FakeLiblsl.js'
16
16
 
17
+ // Libndx
18
+
19
+ export { default as LibndxAdapter } from './impl/LibndxAdapter.js'
20
+ export * from './impl/LibndxAdapter.js'
21
+
22
+ export { default as FakeLibndx } from './testDoubles/Libndx/FakeLibndx.js'
23
+ export * from './testDoubles/Libndx/FakeLibndx.js'
24
+
17
25
  // Libxdf
18
26
 
19
27
  export { default as LibxdfAdapter } from './impl/LibxdfAdapter.js'
@@ -25,10 +33,10 @@ export * from './testDoubles/Libxdf/FakeLibxdf.js'
25
33
  export { default as SpyLibxdf } from './testDoubles/Libxdf/SpyLibxdf.js'
26
34
  export * from './testDoubles/Libxdf/SpyLibxdf.js'
27
35
 
28
- // handleError
36
+ // handleLslError
29
37
 
30
- export { default as handleError } from './lib/handleError.js'
31
- export * from './lib/handleError.js'
38
+ export { default as handleLslError } from './lib/handleLslError.js'
39
+ export * from './lib/handleLslError.js'
32
40
 
33
41
  // consts
34
42
 
@@ -1,4 +1,4 @@
1
- export default function handleError(errorCode: number) {
1
+ export default function handleLslError(errorCode: number) {
2
2
  switch (errorCode) {
3
3
  case 0:
4
4
  return
@@ -102,7 +102,7 @@ export default class FakeLiblsl implements Liblsl {
102
102
  this.lastDestroyStreamInfoOptions = options
103
103
  }
104
104
 
105
- public async resolveByProp(options: ResolveByPropOptions) {
105
+ public resolveByProp(options: ResolveByPropOptions) {
106
106
  this.lastResolveByPropOptions = options
107
107
  return FakeLiblsl.fakeInfoHandles
108
108
  }
@@ -137,11 +137,11 @@ export default class FakeLiblsl implements Liblsl {
137
137
  return {} as InletHandle
138
138
  }
139
139
 
140
- public async openStream(options: OpenStreamOptions) {
140
+ public openStream(options: OpenStreamOptions) {
141
141
  this.lastOpenStreamOptions = options
142
142
  }
143
143
 
144
- public async closeStream(options: CloseStreamOptions) {
144
+ public closeStream(options: CloseStreamOptions) {
145
145
  this.lastCloseStreamOptions = options
146
146
  }
147
147
 
@@ -0,0 +1,74 @@
1
+ import {
2
+ BleBackendOptions,
3
+ FtdiBackendOptions,
4
+ Libndx,
5
+ LibndxAdapterOptions,
6
+ } from '../../impl/LibndxAdapter.js'
7
+
8
+ export default class FakeLibndx implements Libndx {
9
+ public static callsToConstructor: (LibndxAdapterOptions | undefined)[] = []
10
+ public static callsToCreateBleBackend: BleBackendOptions[] = []
11
+ public static callsToStartBleBackend: BleBackendOptions[] = []
12
+ public static callsToStopBleBacked: BleBackendOptions[] = []
13
+ public static callsToDestroyBleBackend: BleBackendOptions[] = []
14
+ public static callsToCreateFtdiBackend: FtdiBackendOptions[] = []
15
+ public static callsToStartFtdiBackend: FtdiBackendOptions[] = []
16
+ public static callsToStopFtdiBackend: FtdiBackendOptions[] = []
17
+ public static callsToDestroyFtdiBackend: FtdiBackendOptions[] = []
18
+
19
+ public constructor(options?: LibndxAdapterOptions) {
20
+ FakeLibndx.callsToConstructor.push(options)
21
+ }
22
+
23
+ public createBleBackend(options: BleBackendOptions) {
24
+ FakeLibndx.callsToCreateBleBackend.push(options)
25
+ return ''
26
+ }
27
+
28
+ public startBleBackend(options: BleBackendOptions) {
29
+ FakeLibndx.callsToStartBleBackend.push(options)
30
+ return ''
31
+ }
32
+
33
+ public stopBleBackend(options: BleBackendOptions) {
34
+ FakeLibndx.callsToStopBleBacked.push(options)
35
+ return ''
36
+ }
37
+
38
+ public destroyBleBackend(options: BleBackendOptions) {
39
+ FakeLibndx.callsToDestroyBleBackend.push(options)
40
+ return ''
41
+ }
42
+
43
+ public createFtdiBackend(options: FtdiBackendOptions) {
44
+ FakeLibndx.callsToCreateFtdiBackend.push(options)
45
+ return ''
46
+ }
47
+
48
+ public startFtdiBackend(options: FtdiBackendOptions) {
49
+ FakeLibndx.callsToStartFtdiBackend.push(options)
50
+ return ''
51
+ }
52
+
53
+ public stopFtdiBackend(options: FtdiBackendOptions) {
54
+ FakeLibndx.callsToStopFtdiBackend.push(options)
55
+ return ''
56
+ }
57
+
58
+ public destroyFtdiBackend(options: FtdiBackendOptions) {
59
+ FakeLibndx.callsToDestroyFtdiBackend.push(options)
60
+ return ''
61
+ }
62
+
63
+ public static resetTestDouble() {
64
+ FakeLibndx.callsToConstructor = []
65
+ FakeLibndx.callsToCreateBleBackend = []
66
+ FakeLibndx.callsToStartBleBackend = []
67
+ FakeLibndx.callsToStopBleBacked = []
68
+ FakeLibndx.callsToDestroyBleBackend = []
69
+ FakeLibndx.callsToCreateFtdiBackend = []
70
+ FakeLibndx.callsToStartFtdiBackend = []
71
+ FakeLibndx.callsToStopFtdiBackend = []
72
+ FakeLibndx.callsToDestroyFtdiBackend = []
73
+ }
74
+ }
package/src/types.ts ADDED
@@ -0,0 +1,7 @@
1
+ import { FuncObj, FieldType } from 'ffi-rs'
2
+
3
+ export type FfiRsDefineOptions = FuncObj<
4
+ FieldType,
5
+ boolean | undefined,
6
+ boolean | undefined
7
+ >
package/tsconfig.json CHANGED
@@ -1,28 +1,25 @@
1
1
  {
2
- "compilerOptions": {
3
- "module": "nodenext",
4
- "moduleResolution": "nodenext",
5
- "target": "ES2022",
6
- "lib": ["ES2022"],
7
- "types": ["node"],
8
- "baseUrl": "src",
9
- "outDir": "build",
10
- "sourceMap": false,
11
- "strict": true,
12
- "noImplicitAny": true,
13
- "noImplicitReturns": true,
14
- "noUnusedLocals": true,
15
- "forceConsistentCasingInFileNames": true,
16
- "declaration": true,
17
- "skipLibCheck": true,
18
- "esModuleInterop": true,
19
- "moduleDetection": "force",
20
- "allowJs": true,
21
- "resolveJsonModule": true,
22
- "experimentalDecorators": true
23
- },
24
- "include": [
25
- "src/*.ts",
26
- "src/**/*.ts"
27
- ]
28
- }
2
+ "compilerOptions": {
3
+ "module": "nodenext",
4
+ "moduleResolution": "nodenext",
5
+ "target": "ES2022",
6
+ "lib": ["ES2022"],
7
+ "types": ["node"],
8
+ "baseUrl": "src",
9
+ "outDir": "build",
10
+ "sourceMap": false,
11
+ "strict": true,
12
+ "noImplicitAny": true,
13
+ "noImplicitReturns": true,
14
+ "noUnusedLocals": true,
15
+ "forceConsistentCasingInFileNames": true,
16
+ "declaration": true,
17
+ "skipLibCheck": true,
18
+ "esModuleInterop": true,
19
+ "moduleDetection": "force",
20
+ "allowJs": true,
21
+ "resolveJsonModule": true,
22
+ "experimentalDecorators": true
23
+ },
24
+ "include": ["src/*.ts", "src/**/*.ts"]
25
+ }
@@ -1 +0,0 @@
1
- {"version":3,"file":"handleError.js","sourceRoot":"","sources":["../../src/lib/handleError.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,OAAO,UAAU,WAAW,CAAC,SAAiB;IACjD,QAAQ,SAAS,EAAE,CAAC;QAChB,KAAK,CAAC;YACF,OAAM;QACV,KAAK,CAAC,CAAC;YACH,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAA;QACpE,KAAK,CAAC,CAAC;YACH,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAA;QACvD,KAAK,CAAC,CAAC;YACH,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAA;QACnE,KAAK,CAAC,CAAC;YACH,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAA;QAC7D;YACI,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAA;IAChE,CAAC;AACL,CAAC;AAED,MAAM,CAAN,IAAY,YAMX;AAND,WAAY,YAAY;IACpB,2CAAM,CAAA;IACN,sDAAY,CAAA;IACZ,gDAAS,CAAA;IACT,8DAAgB,CAAA;IAChB,kEAAkB,CAAA;AACtB,CAAC,EANW,YAAY,KAAZ,YAAY,QAMvB"}
package/eslint.config.mjs DELETED
@@ -1,3 +0,0 @@
1
- import eslintConfigSpruce from 'eslint-config-spruce'
2
-
3
- export default eslintConfigSpruce