@neurodevs/node-lsl 0.0.1

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 (60) hide show
  1. package/.eslintignore +3 -0
  2. package/.eslintrc.js +3 -0
  3. package/.nvmrc +1 -0
  4. package/.vscode/launch.json +58 -0
  5. package/.vscode/settings.json +70 -0
  6. package/.vscode/tasks.json +112 -0
  7. package/LICENSE +21 -0
  8. package/README.md +2 -0
  9. package/build/.spruce/errors/errors.types.d.ts +21 -0
  10. package/build/.spruce/errors/errors.types.js +5 -0
  11. package/build/.spruce/errors/errors.types.js.map +1 -0
  12. package/build/.spruce/errors/nodeLsl/failedToLoadLiblsl.schema.d.ts +3 -0
  13. package/build/.spruce/errors/nodeLsl/failedToLoadLiblsl.schema.js +19 -0
  14. package/build/.spruce/errors/nodeLsl/failedToLoadLiblsl.schema.js.map +1 -0
  15. package/build/.spruce/errors/options.types.d.ts +7 -0
  16. package/build/.spruce/errors/options.types.js +3 -0
  17. package/build/.spruce/errors/options.types.js.map +1 -0
  18. package/build/.spruce/schemas/fields/fieldClassMap.d.ts +2 -0
  19. package/build/.spruce/schemas/fields/fieldClassMap.js +5 -0
  20. package/build/.spruce/schemas/fields/fieldClassMap.js.map +1 -0
  21. package/build/.spruce/schemas/fields/fields.types.d.ts +1 -0
  22. package/build/.spruce/schemas/fields/fields.types.js +3 -0
  23. package/build/.spruce/schemas/fields/fields.types.js.map +1 -0
  24. package/build/.spruce/settings.json +13 -0
  25. package/build/Liblsl.d.ts +47 -0
  26. package/build/Liblsl.js +81 -0
  27. package/build/Liblsl.js.map +1 -0
  28. package/build/LslOutlet.d.ts +30 -0
  29. package/build/LslOutlet.js +122 -0
  30. package/build/LslOutlet.js.map +1 -0
  31. package/build/__tests__/behavioral/LslOutlet.test.d.ts +26 -0
  32. package/build/__tests__/behavioral/LslOutlet.test.js +232 -0
  33. package/build/__tests__/behavioral/LslOutlet.test.js.map +1 -0
  34. package/build/__tests__/implementation/Liblsl.test.d.ts +28 -0
  35. package/build/__tests__/implementation/Liblsl.test.js +236 -0
  36. package/build/__tests__/implementation/Liblsl.test.js.map +1 -0
  37. package/build/errors/SpruceError.d.ts +6 -0
  38. package/build/errors/SpruceError.js +26 -0
  39. package/build/errors/SpruceError.js.map +1 -0
  40. package/build/errors/failedToLoadLiblsl.builder.d.ts +11 -0
  41. package/build/errors/failedToLoadLiblsl.builder.js +14 -0
  42. package/build/errors/failedToLoadLiblsl.builder.js.map +1 -0
  43. package/build/index.d.ts +4 -0
  44. package/build/index.js +27 -0
  45. package/build/index.js.map +1 -0
  46. package/package.json +80 -0
  47. package/src/.spruce/errors/errors.types.ts +40 -0
  48. package/src/.spruce/errors/nodeLsl/failedToLoadLiblsl.schema.ts +22 -0
  49. package/src/.spruce/errors/options.types.ts +10 -0
  50. package/src/.spruce/schemas/fields/fieldClassMap.ts +6 -0
  51. package/src/.spruce/schemas/fields/fields.types.ts +1 -0
  52. package/src/.spruce/settings.json +13 -0
  53. package/src/Liblsl.ts +151 -0
  54. package/src/LslOutlet.ts +143 -0
  55. package/src/__tests__/behavioral/LslOutlet.test.ts +217 -0
  56. package/src/__tests__/implementation/Liblsl.test.ts +231 -0
  57. package/src/errors/SpruceError.ts +23 -0
  58. package/src/errors/failedToLoadLiblsl.builder.ts +12 -0
  59. package/src/index.ts +5 -0
  60. package/tsconfig.json +40 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Liblsl.test.js","sourceRoot":"","sources":["../../../src/__tests__/implementation/Liblsl.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import BaseSpruceError from '@sprucelabs/error';
2
+ import ErrorOptions from "./../.spruce/errors/options.types";
3
+ export default class SpruceError extends BaseSpruceError<ErrorOptions> {
4
+ /** an easy to understand version of the errors */
5
+ friendlyMessage(): string;
6
+ }
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const error_1 = __importDefault(require("@sprucelabs/error"));
7
+ class SpruceError extends error_1.default {
8
+ /** an easy to understand version of the errors */
9
+ friendlyMessage() {
10
+ const { options } = this;
11
+ let message;
12
+ switch (options === null || options === void 0 ? void 0 : options.code) {
13
+ case 'FAILED_TO_LOAD_LIBLSL':
14
+ message = `Well shoot! Loading the liblsl dylib failed. I tried to load it from ${options.liblslPath}.`;
15
+ break;
16
+ default:
17
+ message = super.friendlyMessage();
18
+ }
19
+ const fullMessage = options.friendlyMessage
20
+ ? options.friendlyMessage
21
+ : message;
22
+ return fullMessage;
23
+ }
24
+ }
25
+ exports.default = SpruceError;
26
+ //# sourceMappingURL=SpruceError.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SpruceError.js","sourceRoot":"","sources":["../../src/errors/SpruceError.ts"],"names":[],"mappings":";;;;;AAAA,8DAA+C;AAG/C,MAAqB,WAAY,SAAQ,eAA6B;IACrE,kDAAkD;IAC3C,eAAe;QACrB,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAA;QACxB,IAAI,OAAO,CAAA;QACX,QAAQ,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,IAAI,EAAE;YACtB,KAAK,uBAAuB;gBAC3B,OAAO,GAAG,wEAAwE,OAAO,CAAC,UAAU,GAAG,CAAA;gBACvG,MAAK;YACN;gBACC,OAAO,GAAG,KAAK,CAAC,eAAe,EAAE,CAAA;SAClC;QAED,MAAM,WAAW,GAAG,OAAO,CAAC,eAAe;YAC1C,CAAC,CAAC,OAAO,CAAC,eAAe;YACzB,CAAC,CAAC,OAAO,CAAA;QAEV,OAAO,WAAW,CAAA;IACnB,CAAC;CACD;AAnBD,8BAmBC"}
@@ -0,0 +1,11 @@
1
+ declare const _default: {
2
+ id: string;
3
+ name: string;
4
+ fields: {
5
+ liblslPath: {
6
+ type: "text";
7
+ isRequired: true;
8
+ };
9
+ };
10
+ };
11
+ export default _default;
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const schema_1 = require("@sprucelabs/schema");
4
+ exports.default = (0, schema_1.buildErrorSchema)({
5
+ id: 'failedToLoadLiblsl',
6
+ name: 'FAILED_TO_LOAD_LIBLSL',
7
+ fields: {
8
+ liblslPath: {
9
+ type: 'text',
10
+ isRequired: true,
11
+ },
12
+ },
13
+ });
14
+ //# sourceMappingURL=failedToLoadLiblsl.builder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"failedToLoadLiblsl.builder.js","sourceRoot":"","sources":["../../src/errors/failedToLoadLiblsl.builder.ts"],"names":[],"mappings":";;AAAA,+CAAqD;AAErD,kBAAe,IAAA,yBAAgB,EAAC;IAC/B,EAAE,EAAE,oBAAoB;IACxB,IAAI,EAAE,uBAAuB;IAC7B,MAAM,EAAE;QACP,UAAU,EAAE;YACX,IAAI,EAAE,MAAM;YACZ,UAAU,EAAE,IAAI;SAChB;KACD;CACD,CAAC,CAAA"}
@@ -0,0 +1,4 @@
1
+ export { default as LiblslImpl } from './Liblsl';
2
+ export * from './Liblsl';
3
+ export { default as LiblslOutlet } from './LslOutlet';
4
+ export * from './LslOutlet';
package/build/index.js ADDED
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ var __importDefault = (this && this.__importDefault) || function (mod) {
17
+ return (mod && mod.__esModule) ? mod : { "default": mod };
18
+ };
19
+ Object.defineProperty(exports, "__esModule", { value: true });
20
+ exports.LiblslOutlet = exports.LiblslImpl = void 0;
21
+ var Liblsl_1 = require("./Liblsl");
22
+ Object.defineProperty(exports, "LiblslImpl", { enumerable: true, get: function () { return __importDefault(Liblsl_1).default; } });
23
+ __exportStar(require("./Liblsl"), exports);
24
+ var LslOutlet_1 = require("./LslOutlet");
25
+ Object.defineProperty(exports, "LiblslOutlet", { enumerable: true, get: function () { return __importDefault(LslOutlet_1).default; } });
26
+ __exportStar(require("./LslOutlet"), exports);
27
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA,mCAAgD;AAAvC,qHAAA,OAAO,OAAc;AAC9B,2CAAwB;AAExB,yCAAqD;AAA5C,0HAAA,OAAO,OAAgB;AAChC,8CAA2B"}
package/package.json ADDED
@@ -0,0 +1,80 @@
1
+ {
2
+ "name": "@neurodevs/node-lsl",
3
+ "version": "0.0.1",
4
+ "main": "build/index.js",
5
+ "repository": "https://github.com/neurodevs/node-lsl.git",
6
+ "scripts": {
7
+ "build.ci": "yarn build.tsc && yarn build.resolve-paths && yarn lint",
8
+ "build.dev": "yarn build.tsc --sourceMap ; yarn resolve-paths.lint",
9
+ "build.copy-files": "mkdir -p build && rsync -avzq --exclude='*.ts' ./src/ ./build/",
10
+ "build.resolve-paths": "resolve-path-aliases --target build --patterns '**/*.js,**/*.d.ts'",
11
+ "build.tsc": "yarn build.copy-files && tsc",
12
+ "clean": "yarn clean.build",
13
+ "clean.all": "yarn clean.dependencies && yarn clean.build",
14
+ "clean.build": "rm -rf build/",
15
+ "clean.dependencies": "rm -rf node_modules/ package-lock.json yarn.lock",
16
+ "fix.lint": "eslint --fix --cache '**/*.ts'",
17
+ "lint": "eslint --cache '**/*.ts'",
18
+ "lint.tsc": "tsc -p . --noEmit",
19
+ "post.watch.build": "yarn build.copy-files && yarn build.resolve-paths",
20
+ "rebuild": "yarn clean.all && yarn && yarn build.dev",
21
+ "update.dependencies": "yarn clean.dependencies && yarn",
22
+ "resolve-paths.lint": "yarn build.resolve-paths ; yarn lint",
23
+ "test": "jest",
24
+ "watch.build.dev": "tsc-watch --sourceMap --onCompilationComplete 'yarn post.watch.build'",
25
+ "watch.lint": "concurrently 'yarn lint' \"chokidar 'src/**/*' -c 'yarn lint.tsc'\"",
26
+ "watch.rebuild": "yarn clean.all && yarn && yarn watch.build.dev",
27
+ "watch.tsc": "tsc -w"
28
+ },
29
+ "devDependencies": {
30
+ "@sprucelabs/jest-json-reporter": "^7.0.120",
31
+ "@sprucelabs/resolve-path-aliases": "^1.1.261",
32
+ "@sprucelabs/spruce-test-fixtures": "^60.1.41",
33
+ "@sprucelabs/test": "^8.0.28",
34
+ "@sprucelabs/test-utils": "^4.0.72",
35
+ "@types/ffi-napi": "^4.0.10",
36
+ "@types/node": "^20.9.0",
37
+ "chokidar-cli": "^3.0.0",
38
+ "concurrently": "^8.2.2",
39
+ "eslint": "^8.53.0",
40
+ "eslint-config-spruce": "^10.13.6",
41
+ "jest": "^29.7.0",
42
+ "jest-circus": "^29.7.0",
43
+ "prettier": "^3.1.0",
44
+ "ts-node": "^10.9.1",
45
+ "tsc-watch": "^6.0.4",
46
+ "typescript": "^5.2.2"
47
+ },
48
+ "description": "Lab Streaming Layer (LSL) bindings for Node",
49
+ "skill": {
50
+ "namespace": "node-lsl"
51
+ },
52
+ "jest": {
53
+ "testRunner": "jest-circus/runner",
54
+ "maxWorkers": 4,
55
+ "testTimeout": 120000,
56
+ "testEnvironment": "node",
57
+ "testPathIgnorePatterns": [
58
+ "<rootDir>/tmp/",
59
+ "<rootDir>/src/",
60
+ "<rootDir>/node_modules/",
61
+ "<rootDir>/build/__tests__/testDirsAndFiles/"
62
+ ],
63
+ "testMatch": [
64
+ "**/__tests__/**/*.test.js?(x)"
65
+ ],
66
+ "moduleNameMapper": {
67
+ "^#spruce/(.*)$": "<rootDir>/build/.spruce/$1"
68
+ }
69
+ },
70
+ "dependencies": {
71
+ "@sprucelabs/error": "^5.1.45",
72
+ "@sprucelabs/schema": "^29.0.84",
73
+ "@sprucelabs/spruce-core-schemas": "^39.0.125",
74
+ "@sprucelabs/spruce-skill-utils": "^30.1.21",
75
+ "ffi-napi": "^4.0.3",
76
+ "node-gyp": "^10.0.1",
77
+ "ref-array-napi": "^1.2.2",
78
+ "ref-napi": "^3.0.3"
79
+ }
80
+ }
@@ -0,0 +1,40 @@
1
+ /* eslint-disable @typescript-eslint/no-namespace */
2
+ /* eslint-disable no-redeclare */
3
+
4
+ import { default as SchemaEntity } from '@sprucelabs/schema'
5
+ import * as SpruceSchema from '@sprucelabs/schema'
6
+
7
+
8
+
9
+
10
+
11
+ export declare namespace SpruceErrors.NodeLsl {
12
+
13
+
14
+ export interface FailedToLoadLiblsl {
15
+
16
+
17
+ 'liblslPath': string
18
+ }
19
+
20
+ export interface FailedToLoadLiblslSchema extends SpruceSchema.Schema {
21
+ id: 'failedToLoadLiblsl',
22
+ namespace: 'NodeLsl',
23
+ name: 'FAILED_TO_LOAD_LIBLSL',
24
+ fields: {
25
+ /** . */
26
+ 'liblslPath': {
27
+ type: 'text',
28
+ isRequired: true,
29
+ options: undefined
30
+ },
31
+ }
32
+ }
33
+
34
+ export type FailedToLoadLiblslEntity = SchemaEntity<SpruceErrors.NodeLsl.FailedToLoadLiblslSchema>
35
+
36
+ }
37
+
38
+
39
+
40
+
@@ -0,0 +1,22 @@
1
+ import { SchemaRegistry } from '@sprucelabs/schema'
2
+ import { SpruceErrors } from '../errors.types'
3
+
4
+
5
+
6
+ const failedToLoadLiblslSchema: SpruceErrors.NodeLsl.FailedToLoadLiblslSchema = {
7
+ id: 'failedToLoadLiblsl',
8
+ namespace: 'NodeLsl',
9
+ name: 'FAILED_TO_LOAD_LIBLSL',
10
+ fields: {
11
+ /** . */
12
+ 'liblslPath': {
13
+ type: 'text',
14
+ isRequired: true,
15
+ options: undefined
16
+ },
17
+ }
18
+ }
19
+
20
+ SchemaRegistry.getInstance().trackSchema(failedToLoadLiblslSchema)
21
+
22
+ export default failedToLoadLiblslSchema
@@ -0,0 +1,10 @@
1
+ import { SpruceErrors } from "#spruce/errors/errors.types"
2
+ import { ErrorOptions as ISpruceErrorOptions} from "@sprucelabs/error"
3
+
4
+ export interface FailedToLoadLiblslErrorOptions extends SpruceErrors.NodeLsl.FailedToLoadLiblsl, ISpruceErrorOptions {
5
+ code: 'FAILED_TO_LOAD_LIBLSL'
6
+ }
7
+
8
+ type ErrorOptions = | FailedToLoadLiblslErrorOptions
9
+
10
+ export default ErrorOptions
@@ -0,0 +1,6 @@
1
+ import { fieldClassMap } from '@sprucelabs/schema'
2
+
3
+
4
+
5
+
6
+ export default fieldClassMap
@@ -0,0 +1 @@
1
+ export { FieldDefinitions, FieldDefinitionMap, FieldValueTypeGeneratorMap, FieldMap } from '@sprucelabs/schema'
@@ -0,0 +1,13 @@
1
+ {
2
+ "scriptUpdater": {
3
+ "skipped": []
4
+ },
5
+ "skipped": [
6
+ "skill"
7
+ ],
8
+ "installed": [
9
+ "test",
10
+ "schema",
11
+ "error"
12
+ ]
13
+ }
package/src/Liblsl.ts ADDED
@@ -0,0 +1,151 @@
1
+ import { assertOptions } from '@sprucelabs/schema'
2
+ import ffi from 'ffi-napi'
3
+ import ArrayType from 'ref-array-napi'
4
+ import ref from 'ref-napi'
5
+ import SpruceError from './errors/SpruceError'
6
+
7
+ export default class LiblslImpl implements Liblsl {
8
+ private static instance?: Liblsl
9
+ public static ffi = ffi
10
+ private bindings: LiblslBindings
11
+
12
+ public static getInstance() {
13
+ if (!this.instance) {
14
+ this.instance = new this()
15
+ }
16
+ return this.instance!
17
+ }
18
+
19
+ public static reset() {
20
+ delete this.instance
21
+ }
22
+
23
+ public static setInstance(instance: Liblsl) {
24
+ this.instance = instance
25
+ }
26
+
27
+ public constructor() {
28
+ const path = process.env.LIBLSL_PATH!
29
+
30
+ if (!path) {
31
+ assertOptions(process, ['env.LIBLSL_PATH'])
32
+ }
33
+ try {
34
+ this.bindings = this.loadBindings(path)
35
+ } catch (err) {
36
+ console.error(err)
37
+ throw new SpruceError({
38
+ code: 'FAILED_TO_LOAD_LIBLSL',
39
+ liblslPath: path,
40
+ })
41
+ }
42
+ }
43
+
44
+ private loadBindings(path: string) {
45
+ return LiblslImpl.ffi.Library(path!, {
46
+ lsl_create_streaminfo: [
47
+ streamInfo,
48
+ ['string', 'string', 'int', 'double', 'int', 'string'],
49
+ ],
50
+ lsl_create_outlet: [outletType, [streamInfo, 'int', 'int']],
51
+ lsl_local_clock: ['double', []],
52
+ lsl_push_sample_ft: ['void', [outletType, FloatArray, 'double']],
53
+ }) as unknown as LiblslBindings
54
+ }
55
+
56
+ public pushSample(outlet: LslBindingsOutlet, sample: LslSample): void {
57
+ assertOptions({ outlet, sample }, ['outlet', 'sample'])
58
+ const clock = this.bindings.lsl_local_clock()
59
+ this.bindings.lsl_push_sample_ft(outlet, sample, clock)
60
+ }
61
+
62
+ public createOutlet(options: CreateOutletOptions) {
63
+ const { info, chunkSize, maxBuffered } = assertOptions(options, [
64
+ 'info',
65
+ 'chunkSize',
66
+ 'maxBuffered',
67
+ ])
68
+
69
+ return this.bindings.lsl_create_outlet(info, chunkSize, maxBuffered)
70
+ }
71
+
72
+ public createStreamInfo(options: CreateStreamInfoOptions): StreamInfo {
73
+ const { name, type, channelCount, sampleRate, channelFormat, sourceId } =
74
+ assertOptions(options, [
75
+ 'name',
76
+ 'type',
77
+ 'channelCount',
78
+ 'sampleRate',
79
+ 'channelFormat',
80
+ 'sourceId',
81
+ ])
82
+
83
+ return this.bindings.lsl_create_streaminfo(
84
+ name,
85
+ type,
86
+ channelCount,
87
+ sampleRate,
88
+ channelFormat,
89
+ sourceId
90
+ )
91
+ }
92
+ }
93
+
94
+ export interface Liblsl {
95
+ createStreamInfo(options: CreateStreamInfoOptions): LslBindingsStreamInfo
96
+ createOutlet(options: CreateOutletOptions): LslBindingsOutlet
97
+ pushSample(outlet: LslBindingsOutlet, sample: LslSample): void
98
+ }
99
+
100
+ export type LslSample = (number | string | undefined)[]
101
+
102
+ export interface StreamInfo {}
103
+
104
+ export interface CreateStreamInfoOptions {
105
+ name: string
106
+ type: string
107
+ channelCount: number
108
+ sampleRate: number
109
+ channelFormat: number
110
+ sourceId: string
111
+ manufacturer?: string
112
+ unit?: string
113
+ }
114
+
115
+ export interface LiblslBindings {
116
+ lsl_create_streaminfo(
117
+ name: string,
118
+ type: string,
119
+ channelCount: number,
120
+ sampleRate: number,
121
+ channelFormat: number,
122
+ sourceId: string
123
+ ): LslBindingsStreamInfo
124
+
125
+ lsl_create_outlet(
126
+ info: LslBindingsStreamInfo,
127
+ chunkSize: number,
128
+ maxBuffered: number
129
+ ): LslBindingsOutlet
130
+
131
+ lsl_push_sample_ft(
132
+ outlet: LslBindingsOutlet,
133
+ sample: LslSample,
134
+ timestamp: number
135
+ ): void
136
+
137
+ lsl_local_clock(): number
138
+ }
139
+
140
+ const streamInfo = ref.refType(ref.types.void)
141
+ const outletType = ref.refType(ref.types.void)
142
+ const FloatArray = ArrayType(ref.types.float)
143
+
144
+ export interface CreateOutletOptions {
145
+ info: StreamInfo
146
+ chunkSize: number
147
+ maxBuffered: number
148
+ }
149
+
150
+ export interface LslBindingsStreamInfo {}
151
+ export interface LslBindingsOutlet {}
@@ -0,0 +1,143 @@
1
+ import { SchemaError, assertOptions } from '@sprucelabs/schema'
2
+ import LiblslImpl, { LslSample } from './Liblsl'
3
+
4
+ export default class LslOutlet {
5
+ private outletOptions: LslOutletOptions
6
+ public constructor(options: LslOutletOptions) {
7
+ const { channelCount, sampleRate, channelFormat, chunkSize, maxBuffered } =
8
+ assertOptions(options, [
9
+ 'name',
10
+ 'type',
11
+ 'channelCount',
12
+ 'sampleRate',
13
+ 'channelFormat',
14
+ 'sourceId',
15
+ 'manufacturer',
16
+ 'unit',
17
+ 'chunkSize',
18
+ 'maxBuffered',
19
+ ])
20
+
21
+ this.assertValidChannelCount(channelCount)
22
+ this.assertValidSampleRate(sampleRate)
23
+ this.assertValidChannelFormat(channelFormat)
24
+ this.assertValidChunkSize(chunkSize)
25
+ this.assertValidMaxBufferred(maxBuffered)
26
+
27
+ this.outletOptions = options
28
+ }
29
+
30
+ private assertValidMaxBufferred(maxBuffered: number) {
31
+ if (!this.isPositiveIntegerOrZero(maxBuffered)) {
32
+ throw new SchemaError({
33
+ code: 'INVALID_PARAMETERS',
34
+ parameters: ['maxBuffered'],
35
+ friendlyMessage: 'Max buffered must be a positive integer or zero.',
36
+ })
37
+ }
38
+ }
39
+
40
+ private assertValidChunkSize(chunkSize: number) {
41
+ if (!this.isPositiveIntegerOrZero(chunkSize)) {
42
+ throw new SchemaError({
43
+ code: 'INVALID_PARAMETERS',
44
+ parameters: ['chunkSize'],
45
+ friendlyMessage: 'Chunk size must be a positive integer or zero.',
46
+ })
47
+ }
48
+ }
49
+
50
+ private assertValidChannelFormat(channelFormat: ChannelFormat) {
51
+ const validFormats = CHANNEL_FORMATS
52
+
53
+ if (validFormats.indexOf(channelFormat) === -1) {
54
+ throw new SchemaError({
55
+ code: 'INVALID_PARAMETERS',
56
+ parameters: ['channelFormat'],
57
+ friendlyMessage: 'Channel format must be a valid format.',
58
+ })
59
+ }
60
+ }
61
+
62
+ private assertValidSampleRate(sampleRate: number) {
63
+ if (!this.isPositiveNumber(sampleRate)) {
64
+ throw new SchemaError({
65
+ code: 'INVALID_PARAMETERS',
66
+ parameters: ['sampleRate'],
67
+ friendlyMessage: 'Sample rate must be a positive number.',
68
+ })
69
+ }
70
+ }
71
+
72
+ private assertValidChannelCount(channelCount: number) {
73
+ if (!this.isPositiveInteger(channelCount)) {
74
+ throw new SchemaError({
75
+ code: 'INVALID_PARAMETERS',
76
+ parameters: ['channelCount'],
77
+ friendlyMessage: 'Channel count must be a positive integer.',
78
+ })
79
+ }
80
+ }
81
+
82
+ private isPositiveNumber(value: number) {
83
+ return value > 0
84
+ }
85
+
86
+ private isPositiveIntegerOrZero(value: number) {
87
+ return Number.isInteger(value) && value >= 0
88
+ }
89
+
90
+ private isPositiveInteger(value: number) {
91
+ return Number.isInteger(value) && value > 0
92
+ }
93
+
94
+ private get lsl() {
95
+ return LiblslImpl.getInstance()
96
+ }
97
+
98
+ public pushSample(sample: LslSample) {
99
+ const { chunkSize, maxBuffered, ...streamInfoOptions } = this
100
+ .outletOptions as any
101
+
102
+ delete streamInfoOptions.manufacturer
103
+ delete streamInfoOptions.unit
104
+
105
+ const info = this.lsl.createStreamInfo({
106
+ ...streamInfoOptions,
107
+ channelFormat: CHANNEL_FORMATS.indexOf(this.outletOptions.channelFormat),
108
+ })
109
+ this.lsl.pushSample(
110
+ this.lsl.createOutlet({
111
+ info,
112
+ chunkSize,
113
+ maxBuffered,
114
+ }),
115
+ sample
116
+ )
117
+ }
118
+ }
119
+
120
+ const CHANNEL_FORMATS = [
121
+ 'undefined',
122
+ 'float32',
123
+ 'double64',
124
+ 'string',
125
+ 'int32',
126
+ 'int16',
127
+ 'int8',
128
+ 'int64',
129
+ ] as const
130
+
131
+ export type ChannelFormat = (typeof CHANNEL_FORMATS)[number]
132
+ export interface LslOutletOptions {
133
+ name: string
134
+ type: string
135
+ channelCount: number
136
+ sampleRate: number
137
+ channelFormat: ChannelFormat
138
+ sourceId: string
139
+ manufacturer: string
140
+ unit: string
141
+ chunkSize: number
142
+ maxBuffered: number
143
+ }