@neurodevs/node-lsl 12.0.5 → 13.0.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/README.md +2 -5
- package/build/__tests__/AbstractPackageTest.d.ts +9 -3
- package/build/__tests__/AbstractPackageTest.js +37 -3
- package/build/__tests__/AbstractPackageTest.js.map +1 -1
- package/build/__tests__/impl/LiblslAdapter.test.d.ts +6 -0
- package/build/__tests__/impl/LiblslAdapter.test.js +133 -12
- package/build/__tests__/impl/LiblslAdapter.test.js.map +1 -1
- package/build/__tests__/impl/LslEventMarkerOutlet.test.js +5 -5
- package/build/__tests__/impl/LslEventMarkerOutlet.test.js.map +1 -1
- package/build/__tests__/impl/LslStreamInfo.test.js +3 -3
- package/build/__tests__/impl/LslStreamInfo.test.js.map +1 -1
- package/build/__tests__/impl/LslStreamInlet.test.d.ts +30 -2
- package/build/__tests__/impl/LslStreamInlet.test.js +181 -18
- package/build/__tests__/impl/LslStreamInlet.test.js.map +1 -1
- package/build/__tests__/impl/LslStreamOutlet.test.d.ts +16 -7
- package/build/__tests__/impl/LslStreamOutlet.test.js +84 -23
- package/build/__tests__/impl/LslStreamOutlet.test.js.map +1 -1
- package/build/__tests__/impl/LslWebSocketBridge.test.d.ts +15 -0
- package/build/__tests__/impl/LslWebSocketBridge.test.js +112 -2
- package/build/__tests__/impl/LslWebSocketBridge.test.js.map +1 -1
- package/build/assertions.d.ts +3 -3
- package/build/assertions.js +6 -6
- package/build/assertions.js.map +1 -1
- package/build/handleError.d.ts +8 -0
- package/build/handleError.js +25 -0
- package/build/handleError.js.map +1 -0
- package/build/impl/LiblslAdapter.d.ts +128 -13
- package/build/impl/LiblslAdapter.js +149 -71
- package/build/impl/LiblslAdapter.js.map +1 -1
- package/build/impl/LslEventMarkerOutlet.d.ts +4 -1
- package/build/impl/LslEventMarkerOutlet.js +3 -3
- package/build/impl/LslEventMarkerOutlet.js.map +1 -1
- package/build/impl/LslStreamInfo.d.ts +3 -3
- package/build/impl/LslStreamInfo.js +5 -5
- package/build/impl/LslStreamInfo.js.map +1 -1
- package/build/impl/LslStreamInlet.d.ts +52 -14
- package/build/impl/LslStreamInlet.js +157 -20
- package/build/impl/LslStreamInlet.js.map +1 -1
- package/build/impl/LslStreamOutlet.d.ts +13 -13
- package/build/impl/LslStreamOutlet.js +22 -21
- package/build/impl/LslStreamOutlet.js.map +1 -1
- package/build/impl/LslWebSocketBridge.d.ts +35 -3
- package/build/impl/LslWebSocketBridge.js +66 -3
- package/build/impl/LslWebSocketBridge.js.map +1 -1
- package/build/index.d.ts +0 -1
- package/build/index.js +0 -1
- package/build/index.js.map +1 -1
- package/build/scripts/runLslStreamOutlet.js +2 -3
- package/build/scripts/runLslStreamOutlet.js.map +1 -1
- package/build/scripts/runOutletToInlet.d.ts +1 -0
- package/build/scripts/runOutletToInlet.js +45 -0
- package/build/scripts/runOutletToInlet.js.map +1 -0
- package/build/testDoubles/EventMarkerOutlet/FakeEventMarkerOutlet.d.ts +1 -2
- package/build/testDoubles/EventMarkerOutlet/FakeEventMarkerOutlet.js.map +1 -1
- package/build/testDoubles/EventMarkerOutlet/MockEventMarkerOutlet.d.ts +2 -2
- package/build/testDoubles/EventMarkerOutlet/MockEventMarkerOutlet.js.map +1 -1
- package/build/testDoubles/EventMarkerOutlet/ThrowingEventMarkerOutlet.d.ts +1 -2
- package/build/testDoubles/EventMarkerOutlet/ThrowingEventMarkerOutlet.js.map +1 -1
- package/build/testDoubles/Liblsl/FakeLiblsl.d.ts +15 -3
- package/build/testDoubles/Liblsl/FakeLiblsl.js +42 -0
- package/build/testDoubles/Liblsl/FakeLiblsl.js.map +1 -1
- package/build/testDoubles/StreamInfo/FakeStreamInfo.d.ts +1 -1
- package/build/testDoubles/StreamInfo/SpyStreamInfo.d.ts +1 -1
- package/build/testDoubles/StreamInlet/FakeStreamInlet.d.ts +12 -3
- package/build/testDoubles/StreamInlet/FakeStreamInlet.js +25 -5
- package/build/testDoubles/StreamInlet/FakeStreamInlet.js.map +1 -1
- package/build/testDoubles/StreamInlet/SpyStreamInlet.d.ts +3 -3
- package/build/testDoubles/StreamInlet/SpyStreamInlet.js +2 -2
- package/build/testDoubles/StreamInlet/SpyStreamInlet.js.map +1 -1
- package/build/testDoubles/StreamOutlet/FakeStreamOutlet.d.ts +4 -4
- package/build/testDoubles/StreamOutlet/FakeStreamOutlet.js +6 -6
- package/build/testDoubles/StreamOutlet/FakeStreamOutlet.js.map +1 -1
- package/build/testDoubles/StreamTransportBridge/FakeStreamTransportBridge.d.ts +6 -0
- package/build/testDoubles/StreamTransportBridge/FakeStreamTransportBridge.js +15 -0
- package/build/testDoubles/StreamTransportBridge/FakeStreamTransportBridge.js.map +1 -1
- package/build/testDoubles/StreamTransportBridge/SpyLslWebSocketBridge.d.ts +4 -0
- package/build/testDoubles/StreamTransportBridge/SpyLslWebSocketBridge.js +7 -0
- package/build/testDoubles/StreamTransportBridge/SpyLslWebSocketBridge.js.map +1 -0
- package/build/testDoubles/WebSockets/FakeWebSocket.d.ts +10 -0
- package/build/testDoubles/WebSockets/FakeWebSocket.js +14 -0
- package/build/testDoubles/WebSockets/FakeWebSocket.js.map +1 -0
- package/build/testDoubles/WebSockets/FakeWebSocketServer.d.ts +13 -0
- package/build/testDoubles/WebSockets/FakeWebSocketServer.js +22 -0
- package/build/testDoubles/WebSockets/FakeWebSocketServer.js.map +1 -0
- package/build/testDoubles/generateRandomOutletOptions.js +3 -3
- package/build/testDoubles/generateRandomOutletOptions.js.map +1 -1
- package/package.json +5 -3
- package/src/__tests__/AbstractPackageTest.ts +52 -4
- package/src/__tests__/impl/LiblslAdapter.test.ts +181 -16
- package/src/__tests__/impl/LslEventMarkerOutlet.test.ts +5 -5
- package/src/__tests__/impl/LslStreamInfo.test.ts +3 -3
- package/src/__tests__/impl/LslStreamInlet.test.ts +253 -20
- package/src/__tests__/impl/LslStreamOutlet.test.ts +111 -24
- package/src/__tests__/impl/LslWebSocketBridge.test.ts +163 -5
- package/src/assertions.ts +7 -7
- package/src/handleError.ts +24 -0
- package/src/impl/LiblslAdapter.ts +322 -97
- package/src/impl/LslEventMarkerOutlet.ts +8 -4
- package/src/impl/LslStreamInfo.ts +9 -9
- package/src/impl/LslStreamInlet.ts +233 -25
- package/src/impl/LslStreamOutlet.ts +43 -33
- package/src/impl/LslWebSocketBridge.ts +115 -5
- package/src/index.ts +0 -2
- package/src/scripts/runLslStreamOutlet.ts +2 -3
- package/src/scripts/runOutletToInlet.ts +53 -0
- package/src/testDoubles/EventMarkerOutlet/FakeEventMarkerOutlet.ts +4 -2
- package/src/testDoubles/EventMarkerOutlet/MockEventMarkerOutlet.ts +5 -2
- package/src/testDoubles/EventMarkerOutlet/ThrowingEventMarkerOutlet.ts +4 -2
- package/src/testDoubles/Liblsl/FakeLiblsl.ts +61 -1
- package/src/testDoubles/StreamInfo/FakeStreamInfo.ts +1 -1
- package/src/testDoubles/StreamInlet/FakeStreamInlet.ts +36 -5
- package/src/testDoubles/StreamInlet/SpyStreamInlet.ts +7 -2
- package/src/testDoubles/StreamOutlet/FakeStreamOutlet.ts +7 -7
- package/src/testDoubles/StreamTransportBridge/FakeStreamTransportBridge.ts +18 -0
- package/src/testDoubles/StreamTransportBridge/SpyLslWebSocketBridge.ts +9 -0
- package/src/testDoubles/WebSockets/FakeWebSocket.ts +17 -0
- package/src/testDoubles/WebSockets/FakeWebSocketServer.ts +32 -0
- package/src/testDoubles/generateRandomOutletOptions.ts +3 -3
- package/build/types.d.ts +0 -95
- package/build/types.js +0 -2
- package/build/types.js.map +0 -1
- package/src/types.ts +0 -111
|
@@ -4,23 +4,133 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
4
4
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
|
+
import { randomInt } from 'crypto';
|
|
7
8
|
import { test, assert } from '@neurodevs/node-tdd';
|
|
8
9
|
import LslWebSocketBridge from '../../impl/LslWebSocketBridge.js';
|
|
10
|
+
import FakeStreamInlet from '../../testDoubles/StreamInlet/FakeStreamInlet.js';
|
|
11
|
+
import FakeWebSocket from '../../testDoubles/WebSockets/FakeWebSocket.js';
|
|
12
|
+
import FakeWebSocketServer from '../../testDoubles/WebSockets/FakeWebSocketServer.js';
|
|
9
13
|
import AbstractPackageTest from '../AbstractPackageTest.js';
|
|
10
14
|
export default class LslWebSocketBridgeTest extends AbstractPackageTest {
|
|
11
15
|
static instance;
|
|
12
16
|
static async beforeEach() {
|
|
13
17
|
await super.beforeEach();
|
|
18
|
+
this.setFakeStreamInlet();
|
|
19
|
+
this.setFakeWebSocketServer();
|
|
20
|
+
this.setSpyLslWebSocketBridge();
|
|
14
21
|
this.instance = this.LslWebSocketBridge();
|
|
15
22
|
}
|
|
16
23
|
static async createsInstance() {
|
|
17
24
|
assert.isTruthy(this.instance, 'Failed to create instance!');
|
|
18
25
|
}
|
|
19
|
-
static
|
|
20
|
-
|
|
26
|
+
static async createsLslStreamInlet() {
|
|
27
|
+
const { channelNames, channelFormat, sampleRateHz, chunkSize } = FakeStreamInlet.callsToConstructor[0]?.options ?? {};
|
|
28
|
+
assert.isEqualDeep({
|
|
29
|
+
channelNames,
|
|
30
|
+
channelFormat,
|
|
31
|
+
sampleRateHz,
|
|
32
|
+
chunkSize,
|
|
33
|
+
}, this.baseOptions);
|
|
34
|
+
}
|
|
35
|
+
static async activateCallsStartPullingOnInlet() {
|
|
36
|
+
this.activate();
|
|
37
|
+
assert.isEqual(FakeStreamInlet.numCallsToStartPulling, 1, 'Did not call startPulling on inlet!');
|
|
38
|
+
}
|
|
39
|
+
static async deactivateCallsStopPullingOnInlet() {
|
|
40
|
+
this.activate();
|
|
41
|
+
this.deactivate();
|
|
42
|
+
assert.isEqual(FakeStreamInlet.numCallsToStopPulling, 1, 'Did not call stopPulling on inlet!');
|
|
43
|
+
}
|
|
44
|
+
static async destroyCallsDestroyOnInlet() {
|
|
45
|
+
this.destroy();
|
|
46
|
+
assert.isEqual(FakeStreamInlet.numCallsToDestroy, 1, 'Did not call destroy on inlet!');
|
|
47
|
+
}
|
|
48
|
+
static async createsWebSocketServer() {
|
|
49
|
+
assert.isEqualDeep(FakeWebSocketServer.callsToConstructor[0], { port: this.wssPort }, 'Did not create WebSocketServer!');
|
|
50
|
+
}
|
|
51
|
+
static async activateSendsDataToWebSocketClients() {
|
|
52
|
+
this.activate();
|
|
53
|
+
const { samples, timestamps } = this.simulateOnDataCallback();
|
|
54
|
+
for (const client of FakeWebSocketServer.clients) {
|
|
55
|
+
const callToClient = FakeWebSocket.callsToSend.filter((c) => c.id === client.id)[0];
|
|
56
|
+
assert.isEqualDeep(callToClient?.data, JSON.stringify({
|
|
57
|
+
samples,
|
|
58
|
+
timestamps,
|
|
59
|
+
}), 'Did not send data to client!');
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
static async doesNotSendToClientsThatAreNotReady() {
|
|
63
|
+
for (const client of FakeWebSocketServer.clients) {
|
|
64
|
+
client.readyState = WebSocket.CONNECTING;
|
|
65
|
+
}
|
|
66
|
+
this.activate();
|
|
67
|
+
this.simulateOnDataCallback();
|
|
68
|
+
assert.isEqual(FakeWebSocket.callsToSend.length, 0, 'Sent data to clients that are not ready!');
|
|
69
|
+
}
|
|
70
|
+
static async destroyClosesWebSocketServer() {
|
|
71
|
+
this.destroy();
|
|
72
|
+
assert.isEqual(FakeWebSocketServer.numCallsToClose, 1, 'Did not call close on WebSocketServer!');
|
|
73
|
+
}
|
|
74
|
+
static async throwsIfActivateIsCalledAfterDestroy() {
|
|
75
|
+
this.destroy();
|
|
76
|
+
assert.doesThrow(() => {
|
|
77
|
+
this.activate();
|
|
78
|
+
}, `\n\n Cannot re-activate bridge after destroying it! \n\n Please create and activate a new instance. \n`);
|
|
79
|
+
}
|
|
80
|
+
static activate() {
|
|
81
|
+
this.instance.activate();
|
|
82
|
+
}
|
|
83
|
+
static deactivate() {
|
|
84
|
+
this.instance.deactivate();
|
|
85
|
+
}
|
|
86
|
+
static destroy() {
|
|
87
|
+
this.instance.destroy();
|
|
88
|
+
}
|
|
89
|
+
static simulateOnDataCallback() {
|
|
90
|
+
const samples = new Float32Array([1, 2, 3, 4, 5, 6]);
|
|
91
|
+
const timestamps = new Float64Array([7, 8]);
|
|
92
|
+
FakeStreamInlet.callsToConstructor[0]?.onData(samples, timestamps);
|
|
93
|
+
return { samples, timestamps };
|
|
94
|
+
}
|
|
95
|
+
static wssPort = 8080;
|
|
96
|
+
static baseOptions = {
|
|
97
|
+
channelNames: this.channelNames,
|
|
98
|
+
channelFormat: 'float32',
|
|
99
|
+
sampleRateHz: 100 * Math.random(),
|
|
100
|
+
chunkSize: randomInt(1, 100),
|
|
101
|
+
};
|
|
102
|
+
static LslWebSocketBridge(options) {
|
|
103
|
+
return LslWebSocketBridge.Create({ ...this.baseOptions, ...options });
|
|
21
104
|
}
|
|
22
105
|
}
|
|
23
106
|
__decorate([
|
|
24
107
|
test()
|
|
25
108
|
], LslWebSocketBridgeTest, "createsInstance", null);
|
|
109
|
+
__decorate([
|
|
110
|
+
test()
|
|
111
|
+
], LslWebSocketBridgeTest, "createsLslStreamInlet", null);
|
|
112
|
+
__decorate([
|
|
113
|
+
test()
|
|
114
|
+
], LslWebSocketBridgeTest, "activateCallsStartPullingOnInlet", null);
|
|
115
|
+
__decorate([
|
|
116
|
+
test()
|
|
117
|
+
], LslWebSocketBridgeTest, "deactivateCallsStopPullingOnInlet", null);
|
|
118
|
+
__decorate([
|
|
119
|
+
test()
|
|
120
|
+
], LslWebSocketBridgeTest, "destroyCallsDestroyOnInlet", null);
|
|
121
|
+
__decorate([
|
|
122
|
+
test()
|
|
123
|
+
], LslWebSocketBridgeTest, "createsWebSocketServer", null);
|
|
124
|
+
__decorate([
|
|
125
|
+
test()
|
|
126
|
+
], LslWebSocketBridgeTest, "activateSendsDataToWebSocketClients", null);
|
|
127
|
+
__decorate([
|
|
128
|
+
test()
|
|
129
|
+
], LslWebSocketBridgeTest, "doesNotSendToClientsThatAreNotReady", null);
|
|
130
|
+
__decorate([
|
|
131
|
+
test()
|
|
132
|
+
], LslWebSocketBridgeTest, "destroyClosesWebSocketServer", null);
|
|
133
|
+
__decorate([
|
|
134
|
+
test()
|
|
135
|
+
], LslWebSocketBridgeTest, "throwsIfActivateIsCalledAfterDestroy", null);
|
|
26
136
|
//# sourceMappingURL=LslWebSocketBridge.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LslWebSocketBridge.test.js","sourceRoot":"","sources":["../../../src/__tests__/impl/LslWebSocketBridge.test.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAElD,OAAO,kBAEN,MAAM,kCAAkC,CAAA;AACzC,OAAO,mBAAmB,MAAM,2BAA2B,CAAA;AAE3D,MAAM,CAAC,OAAO,OAAO,sBAAuB,SAAQ,mBAAmB;IAC3D,MAAM,CAAC,QAAQ,CAAuB;IAEpC,MAAM,CAAC,KAAK,CAAC,UAAU;QAC7B,MAAM,KAAK,CAAC,UAAU,EAAE,CAAA;QAExB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,kBAAkB,
|
|
1
|
+
{"version":3,"file":"LslWebSocketBridge.test.js","sourceRoot":"","sources":["../../../src/__tests__/impl/LslWebSocketBridge.test.ts"],"names":[],"mappings":"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"}
|
package/build/assertions.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { ChannelFormat } from '
|
|
1
|
+
import { ChannelFormat } from 'impl/LiblslAdapter.js';
|
|
2
2
|
export declare function assertValidChunkSize(chunkSize: number): void;
|
|
3
|
-
export declare function
|
|
3
|
+
export declare function assertValidMaxBufferedMs(maxBufferedMs: number): void;
|
|
4
4
|
export declare function assertValidChannelFormat(channelFormat: ChannelFormat): void;
|
|
5
|
-
export declare function
|
|
5
|
+
export declare function assertValidSampleRateHz(sampleRateHz: number): void;
|
|
6
6
|
export declare function assertValidChannelCount(channelCount: number): void;
|
package/build/assertions.js
CHANGED
|
@@ -5,9 +5,9 @@ export function assertValidChunkSize(chunkSize) {
|
|
|
5
5
|
throw new Error(`Invalid chunk size! Must be a positive integer or zero, not: ${chunkSize}.`);
|
|
6
6
|
}
|
|
7
7
|
}
|
|
8
|
-
export function
|
|
9
|
-
if (!isPositiveIntegerOrZero(
|
|
10
|
-
throw new Error(`Invalid max buffered! Must be a positive integer or zero, not: ${
|
|
8
|
+
export function assertValidMaxBufferedMs(maxBufferedMs) {
|
|
9
|
+
if (!isPositiveIntegerOrZero(maxBufferedMs)) {
|
|
10
|
+
throw new Error(`Invalid max buffered! Must be a positive integer or zero, not: ${maxBufferedMs}.`);
|
|
11
11
|
}
|
|
12
12
|
}
|
|
13
13
|
export function assertValidChannelFormat(channelFormat) {
|
|
@@ -15,9 +15,9 @@ export function assertValidChannelFormat(channelFormat) {
|
|
|
15
15
|
throw new Error(`Invalid channel format! Must be one of: ${CHANNEL_FORMATS.join(', ')}, not ${channelFormat}.`);
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
|
-
export function
|
|
19
|
-
if (!isGreaterThanOrEqualToZero(
|
|
20
|
-
throw new Error(`Invalid sample rate! Must be a positive number or zero, not: ${
|
|
18
|
+
export function assertValidSampleRateHz(sampleRateHz) {
|
|
19
|
+
if (!isGreaterThanOrEqualToZero(sampleRateHz)) {
|
|
20
|
+
throw new Error(`Invalid sample rate! Must be a positive number or zero, not: ${sampleRateHz}.`);
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
23
|
export function assertValidChannelCount(channelCount) {
|
package/build/assertions.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"assertions.js","sourceRoot":"","sources":["../src/assertions.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"assertions.js","sourceRoot":"","sources":["../src/assertions.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAC7C,OAAO,EACH,0BAA0B,EAC1B,iBAAiB,EACjB,uBAAuB,EACvB,eAAe,GAClB,MAAM,kBAAkB,CAAA;AAEzB,MAAM,UAAU,oBAAoB,CAAC,SAAiB;IAClD,IAAI,CAAC,uBAAuB,CAAC,SAAS,CAAC,EAAE,CAAC;QACtC,MAAM,IAAI,KAAK,CACX,gEAAgE,SAAS,GAAG,CAC/E,CAAA;IACL,CAAC;AACL,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,aAAqB;IAC1D,IAAI,CAAC,uBAAuB,CAAC,aAAa,CAAC,EAAE,CAAC;QAC1C,MAAM,IAAI,KAAK,CACX,kEAAkE,aAAa,GAAG,CACrF,CAAA;IACL,CAAC;AACL,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,aAA4B;IACjE,IAAI,CAAC,eAAe,CAAC,aAAa,EAAE,eAAe,CAAC,EAAE,CAAC;QACnD,MAAM,IAAI,KAAK,CACX,2CAA2C,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,aAAa,GAAG,CACjG,CAAA;IACL,CAAC;AACL,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,YAAoB;IACxD,IAAI,CAAC,0BAA0B,CAAC,YAAY,CAAC,EAAE,CAAC;QAC5C,MAAM,IAAI,KAAK,CACX,gEAAgE,YAAY,GAAG,CAClF,CAAA;IACL,CAAC;AACL,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,YAAoB;IACxD,IAAI,CAAC,iBAAiB,CAAC,YAAY,CAAC,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CACX,2DAA2D,YAAY,GAAG,CAC7E,CAAA;IACL,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export default function handleError(errorCode) {
|
|
2
|
+
switch (errorCode) {
|
|
3
|
+
case 0:
|
|
4
|
+
return;
|
|
5
|
+
case -1:
|
|
6
|
+
throw new Error(`The liblsl operation failed due to a timeout!`);
|
|
7
|
+
case -2:
|
|
8
|
+
throw new Error(`The liblsl stream has been lost!`);
|
|
9
|
+
case -3:
|
|
10
|
+
throw new Error(`A liblsl argument was incorrectly specified!`);
|
|
11
|
+
case -4:
|
|
12
|
+
throw new Error(`An internal liblsl error has occurred!`);
|
|
13
|
+
default:
|
|
14
|
+
throw new Error(`An unknown liblsl error has occurred!`);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
export var LslErrorCode;
|
|
18
|
+
(function (LslErrorCode) {
|
|
19
|
+
LslErrorCode[LslErrorCode["Ok"] = 0] = "Ok";
|
|
20
|
+
LslErrorCode[LslErrorCode["Timeout"] = -1] = "Timeout";
|
|
21
|
+
LslErrorCode[LslErrorCode["Lost"] = -2] = "Lost";
|
|
22
|
+
LslErrorCode[LslErrorCode["BadArgument"] = -3] = "BadArgument";
|
|
23
|
+
LslErrorCode[LslErrorCode["InternalError"] = -4] = "InternalError";
|
|
24
|
+
})(LslErrorCode || (LslErrorCode = {}));
|
|
25
|
+
//# sourceMappingURL=handleError.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handleError.js","sourceRoot":"","sources":["../src/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"}
|
|
@@ -1,27 +1,142 @@
|
|
|
1
|
-
import { define, open } from 'ffi-rs';
|
|
2
|
-
import {
|
|
1
|
+
import { define, JsExternal, load, open } from 'ffi-rs';
|
|
2
|
+
import { CHANNEL_FORMATS } from '../consts.js';
|
|
3
|
+
import { LslErrorCode } from '../handleError.js';
|
|
3
4
|
export default class LiblslAdapter implements Liblsl {
|
|
4
|
-
static
|
|
5
|
-
static
|
|
5
|
+
static open: typeof open;
|
|
6
|
+
static define: typeof define;
|
|
7
|
+
static load: typeof load;
|
|
6
8
|
private static instance?;
|
|
7
|
-
|
|
9
|
+
liblslPath: string;
|
|
8
10
|
private bindings;
|
|
11
|
+
private readonly defaultMacOsPath;
|
|
9
12
|
protected constructor();
|
|
10
13
|
private tryToLoadBindings;
|
|
11
|
-
private
|
|
14
|
+
private throwFailedToLoadLiblsl;
|
|
12
15
|
static getInstance(): Liblsl;
|
|
13
16
|
static setInstance(instance: Liblsl): void;
|
|
14
17
|
static resetInstance(): void;
|
|
15
18
|
private loadBindings;
|
|
16
|
-
|
|
19
|
+
private openLiblsl;
|
|
20
|
+
private defineLiblslBindings;
|
|
21
|
+
createStreamInfo(options: CreateStreamInfoOptions): BoundStreamInfo;
|
|
17
22
|
appendChannelsToStreamInfo(options: AppendChannelsToStreamInfoOptions): void;
|
|
18
|
-
createOutlet(options: CreateOutletOptions):
|
|
19
|
-
pushSampleFloatTimestamp(options: PushSampleFloatTimestampOptions):
|
|
20
|
-
pushSampleStringTimestamp(options: PushSampleStringTimestampOptions):
|
|
23
|
+
createOutlet(options: CreateOutletOptions): BoundOutlet;
|
|
24
|
+
pushSampleFloatTimestamp(options: PushSampleFloatTimestampOptions): LslErrorCode;
|
|
25
|
+
pushSampleStringTimestamp(options: PushSampleStringTimestampOptions): LslErrorCode;
|
|
21
26
|
destroyOutlet(options: DestroyOutletOptions): void;
|
|
22
|
-
createInlet(options: CreateInletOptions):
|
|
27
|
+
createInlet(options: CreateInletOptions): BoundInlet;
|
|
28
|
+
pullSample(options: PullSampleOptions): number;
|
|
29
|
+
pullChunk(options: PullChunkOptions): number;
|
|
23
30
|
flushInlet(options: FlushInletOptions): void;
|
|
24
|
-
destroyInlet(
|
|
31
|
+
destroyInlet(options: DestroyInletOptions): void;
|
|
25
32
|
localClock(): number;
|
|
26
|
-
private
|
|
33
|
+
private get open();
|
|
34
|
+
private get define();
|
|
35
|
+
private get load();
|
|
36
|
+
private get liblslFuncs();
|
|
37
|
+
}
|
|
38
|
+
export interface Liblsl {
|
|
39
|
+
liblslPath: string;
|
|
40
|
+
createStreamInfo(options: CreateStreamInfoOptions): BoundStreamInfo;
|
|
41
|
+
appendChannelsToStreamInfo(options: AppendChannelsToStreamInfoOptions): void;
|
|
42
|
+
createOutlet(options: CreateOutletOptions): BoundOutlet;
|
|
43
|
+
pushSampleFloatTimestamp(options: PushSampleFloatTimestampOptions): LslErrorCode;
|
|
44
|
+
pushSampleStringTimestamp(options: PushSampleStringTimestampOptions): LslErrorCode;
|
|
45
|
+
destroyOutlet(options: DestroyOutletOptions): void;
|
|
46
|
+
createInlet(options: CreateInletOptions): BoundInlet;
|
|
47
|
+
pullSample(options: PullSampleOptions): number;
|
|
48
|
+
pullChunk(options: PullChunkOptions): number;
|
|
49
|
+
flushInlet(options: FlushInletOptions): void;
|
|
50
|
+
destroyInlet(options: DestroyInletOptions): void;
|
|
51
|
+
localClock(): number;
|
|
52
|
+
}
|
|
53
|
+
export interface CreateStreamInfoOptions {
|
|
54
|
+
name: string;
|
|
55
|
+
type: string;
|
|
56
|
+
channelCount: number;
|
|
57
|
+
sampleRateHz: number;
|
|
58
|
+
channelFormat: number;
|
|
59
|
+
sourceId: string;
|
|
60
|
+
manufacturer?: string;
|
|
61
|
+
units?: string;
|
|
62
|
+
}
|
|
63
|
+
export interface AppendChannelsToStreamInfoOptions {
|
|
64
|
+
info: BoundStreamInfo;
|
|
65
|
+
channels: LslChannel[];
|
|
66
|
+
}
|
|
67
|
+
export interface CreateOutletOptions {
|
|
68
|
+
info: BoundStreamInfo;
|
|
69
|
+
chunkSize: number;
|
|
70
|
+
maxBufferedMs: number;
|
|
71
|
+
}
|
|
72
|
+
export interface PushSampleFloatTimestampOptions {
|
|
73
|
+
outlet: BoundOutlet;
|
|
74
|
+
sample: number[];
|
|
75
|
+
timestamp: number;
|
|
76
|
+
}
|
|
77
|
+
export interface PushSampleStringTimestampOptions {
|
|
78
|
+
outlet: BoundOutlet;
|
|
79
|
+
sample: string[];
|
|
80
|
+
timestamp: number;
|
|
81
|
+
}
|
|
82
|
+
export interface DestroyOutletOptions {
|
|
83
|
+
outlet: BoundOutlet;
|
|
84
|
+
}
|
|
85
|
+
export interface CreateInletOptions {
|
|
86
|
+
info: BoundStreamInfo;
|
|
87
|
+
chunkSize: number;
|
|
88
|
+
maxBufferedMs: number;
|
|
89
|
+
}
|
|
90
|
+
export interface PullSampleOptions {
|
|
91
|
+
inlet: BoundInlet;
|
|
92
|
+
dataBufferPtr: JsExternal;
|
|
93
|
+
dataBufferElements: number;
|
|
94
|
+
timeout: number;
|
|
95
|
+
errcodePtr: JsExternal;
|
|
96
|
+
}
|
|
97
|
+
export interface PullChunkOptions {
|
|
98
|
+
inlet: BoundInlet;
|
|
99
|
+
dataBufferPtr: JsExternal;
|
|
100
|
+
timestampBufferPtr: JsExternal;
|
|
101
|
+
dataBufferElements: number;
|
|
102
|
+
timestampBufferElements: number;
|
|
103
|
+
timeout: number;
|
|
104
|
+
errcodePtr: JsExternal;
|
|
105
|
+
}
|
|
106
|
+
export interface FlushInletOptions {
|
|
107
|
+
inlet: BoundInlet;
|
|
108
|
+
}
|
|
109
|
+
export interface DestroyInletOptions {
|
|
110
|
+
inlet: BoundInlet;
|
|
111
|
+
}
|
|
112
|
+
export interface LiblslBindings {
|
|
113
|
+
lsl_create_streaminfo(args: [string, string, number, number, number, string]): BoundStreamInfo;
|
|
114
|
+
lsl_create_outlet(args: [BoundStreamInfo, number, number]): BoundOutlet;
|
|
115
|
+
lsl_push_sample_ft(args: [BoundOutlet, LslSample, number]): LslErrorCode;
|
|
116
|
+
lsl_push_sample_strt(args: [BoundOutlet, LslSample, number]): LslErrorCode;
|
|
117
|
+
lsl_destroy_outlet(args: [BoundOutlet]): void;
|
|
118
|
+
lsl_create_inlet(args: any): BoundInlet;
|
|
119
|
+
lsl_flush_inlet(args: [BoundInlet]): void;
|
|
120
|
+
lsl_destroy_inlet(args: any): void;
|
|
121
|
+
lsl_local_clock(args: []): number;
|
|
122
|
+
lsl_get_desc(args: [BoundStreamInfo]): BoundDescription;
|
|
123
|
+
lsl_append_child(args: [BoundDescription, string]): BoundChild;
|
|
124
|
+
lsl_append_child_value(args: [BoundChild, string, string]): void;
|
|
125
|
+
}
|
|
126
|
+
export type ChannelFormat = (typeof CHANNEL_FORMATS)[number];
|
|
127
|
+
export interface LslChannel {
|
|
128
|
+
label: string;
|
|
129
|
+
units: string;
|
|
130
|
+
type: string;
|
|
131
|
+
}
|
|
132
|
+
export type LslSample = (number | string | undefined)[];
|
|
133
|
+
export interface BoundStreamInfo {
|
|
134
|
+
}
|
|
135
|
+
export interface BoundOutlet {
|
|
136
|
+
}
|
|
137
|
+
export interface BoundInlet {
|
|
138
|
+
}
|
|
139
|
+
export interface BoundDescription {
|
|
140
|
+
}
|
|
141
|
+
export interface BoundChild {
|
|
27
142
|
}
|
|
@@ -1,24 +1,26 @@
|
|
|
1
|
-
import { DataType, define, open } from 'ffi-rs';
|
|
1
|
+
import { DataType, define, load, open, unwrapPointer } from 'ffi-rs';
|
|
2
2
|
export default class LiblslAdapter {
|
|
3
|
-
static
|
|
4
|
-
static
|
|
3
|
+
static open = open;
|
|
4
|
+
static define = define;
|
|
5
|
+
static load = load;
|
|
5
6
|
static instance;
|
|
6
|
-
|
|
7
|
+
liblslPath;
|
|
7
8
|
bindings;
|
|
9
|
+
defaultMacOsPath = `/opt/homebrew/Cellar/lsl/1.16.2/lib/liblsl.1.16.2.dylib`;
|
|
8
10
|
constructor() {
|
|
9
|
-
this.
|
|
11
|
+
this.liblslPath = process.env.LIBLSL_PATH ?? this.defaultMacOsPath;
|
|
10
12
|
this.tryToLoadBindings();
|
|
11
13
|
}
|
|
12
14
|
tryToLoadBindings() {
|
|
13
15
|
try {
|
|
14
|
-
this.
|
|
16
|
+
this.loadBindings();
|
|
15
17
|
}
|
|
16
18
|
catch (error) {
|
|
17
|
-
|
|
19
|
+
this.throwFailedToLoadLiblsl(error);
|
|
18
20
|
}
|
|
19
21
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
+
throwFailedToLoadLiblsl(error) {
|
|
23
|
+
throw new Error(`Loading the liblsl dylib failed! I tried to load it from ${this.liblslPath}.\n\n${error.message}\n\n`);
|
|
22
24
|
}
|
|
23
25
|
static getInstance() {
|
|
24
26
|
if (!this.instance) {
|
|
@@ -32,12 +34,143 @@ export default class LiblslAdapter {
|
|
|
32
34
|
static resetInstance() {
|
|
33
35
|
delete this.instance;
|
|
34
36
|
}
|
|
35
|
-
loadBindings(
|
|
36
|
-
|
|
37
|
+
loadBindings() {
|
|
38
|
+
this.openLiblsl();
|
|
39
|
+
this.bindings = this.defineLiblslBindings();
|
|
40
|
+
}
|
|
41
|
+
openLiblsl() {
|
|
42
|
+
this.open({
|
|
37
43
|
library: 'lsl',
|
|
38
|
-
path: liblslPath,
|
|
44
|
+
path: this.liblslPath,
|
|
39
45
|
});
|
|
40
|
-
|
|
46
|
+
}
|
|
47
|
+
defineLiblslBindings() {
|
|
48
|
+
return this.define(this.liblslFuncs);
|
|
49
|
+
}
|
|
50
|
+
createStreamInfo(options) {
|
|
51
|
+
const { name, type, channelCount, sampleRateHz, channelFormat, sourceId, } = options;
|
|
52
|
+
return this.bindings.lsl_create_streaminfo([
|
|
53
|
+
name,
|
|
54
|
+
type,
|
|
55
|
+
channelCount,
|
|
56
|
+
sampleRateHz,
|
|
57
|
+
channelFormat,
|
|
58
|
+
sourceId,
|
|
59
|
+
]);
|
|
60
|
+
}
|
|
61
|
+
appendChannelsToStreamInfo(options) {
|
|
62
|
+
const { info, channels } = options;
|
|
63
|
+
const description = this.bindings.lsl_get_desc([info]);
|
|
64
|
+
const parent = this.bindings.lsl_append_child([description, 'channels']);
|
|
65
|
+
for (const channel of channels) {
|
|
66
|
+
const child = this.bindings.lsl_append_child([parent, 'channel']);
|
|
67
|
+
this.bindings.lsl_append_child_value([
|
|
68
|
+
child,
|
|
69
|
+
'label',
|
|
70
|
+
channel.label,
|
|
71
|
+
]);
|
|
72
|
+
this.bindings.lsl_append_child_value([child, 'unit', channel.units]);
|
|
73
|
+
this.bindings.lsl_append_child_value([child, 'type', channel.type]);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
createOutlet(options) {
|
|
77
|
+
const { info, chunkSize, maxBufferedMs } = options;
|
|
78
|
+
return this.bindings.lsl_create_outlet([
|
|
79
|
+
info,
|
|
80
|
+
chunkSize,
|
|
81
|
+
maxBufferedMs / 1000,
|
|
82
|
+
]);
|
|
83
|
+
}
|
|
84
|
+
pushSampleFloatTimestamp(options) {
|
|
85
|
+
const { outlet, sample, timestamp } = options;
|
|
86
|
+
return this.bindings.lsl_push_sample_ft([outlet, sample, timestamp]);
|
|
87
|
+
}
|
|
88
|
+
pushSampleStringTimestamp(options) {
|
|
89
|
+
const { outlet, sample, timestamp } = options;
|
|
90
|
+
return this.bindings.lsl_push_sample_strt([outlet, sample, timestamp]);
|
|
91
|
+
}
|
|
92
|
+
destroyOutlet(options) {
|
|
93
|
+
const { outlet } = options;
|
|
94
|
+
this.bindings.lsl_destroy_outlet([outlet]);
|
|
95
|
+
}
|
|
96
|
+
createInlet(options) {
|
|
97
|
+
const { info, chunkSize, maxBufferedMs } = options;
|
|
98
|
+
return this.bindings.lsl_create_inlet([
|
|
99
|
+
info,
|
|
100
|
+
chunkSize,
|
|
101
|
+
maxBufferedMs / 1000,
|
|
102
|
+
]);
|
|
103
|
+
}
|
|
104
|
+
pullSample(options) {
|
|
105
|
+
const { inlet, dataBufferPtr, dataBufferElements, timeout, errcodePtr, } = options;
|
|
106
|
+
return this.load({
|
|
107
|
+
library: 'lsl',
|
|
108
|
+
funcName: 'lsl_pull_sample_f',
|
|
109
|
+
retType: DataType.Double,
|
|
110
|
+
paramsType: [
|
|
111
|
+
DataType.External,
|
|
112
|
+
DataType.External,
|
|
113
|
+
DataType.I32,
|
|
114
|
+
DataType.Double,
|
|
115
|
+
DataType.External,
|
|
116
|
+
],
|
|
117
|
+
paramsValue: [
|
|
118
|
+
inlet,
|
|
119
|
+
dataBufferPtr,
|
|
120
|
+
dataBufferElements,
|
|
121
|
+
timeout,
|
|
122
|
+
errcodePtr,
|
|
123
|
+
],
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
pullChunk(options) {
|
|
127
|
+
const { inlet, dataBufferPtr, timestampBufferPtr, dataBufferElements, timestampBufferElements, timeout, errcodePtr, } = options;
|
|
128
|
+
return this.load({
|
|
129
|
+
library: 'lsl',
|
|
130
|
+
funcName: 'lsl_pull_chunk_f',
|
|
131
|
+
retType: DataType.Double,
|
|
132
|
+
paramsType: [
|
|
133
|
+
DataType.External,
|
|
134
|
+
DataType.External,
|
|
135
|
+
DataType.External,
|
|
136
|
+
DataType.I32,
|
|
137
|
+
DataType.I32,
|
|
138
|
+
DataType.Double,
|
|
139
|
+
DataType.External,
|
|
140
|
+
],
|
|
141
|
+
paramsValue: [
|
|
142
|
+
inlet,
|
|
143
|
+
unwrapPointer([dataBufferPtr])[0],
|
|
144
|
+
unwrapPointer([timestampBufferPtr])[0],
|
|
145
|
+
dataBufferElements,
|
|
146
|
+
timestampBufferElements,
|
|
147
|
+
timeout,
|
|
148
|
+
unwrapPointer([errcodePtr])[0],
|
|
149
|
+
],
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
flushInlet(options) {
|
|
153
|
+
const { inlet } = options;
|
|
154
|
+
this.bindings.lsl_flush_inlet([inlet]);
|
|
155
|
+
}
|
|
156
|
+
destroyInlet(options) {
|
|
157
|
+
const { inlet } = options;
|
|
158
|
+
this.bindings.lsl_destroy_inlet([inlet]);
|
|
159
|
+
}
|
|
160
|
+
localClock() {
|
|
161
|
+
return this.bindings.lsl_local_clock([]);
|
|
162
|
+
}
|
|
163
|
+
get open() {
|
|
164
|
+
return LiblslAdapter.open;
|
|
165
|
+
}
|
|
166
|
+
get define() {
|
|
167
|
+
return LiblslAdapter.define;
|
|
168
|
+
}
|
|
169
|
+
get load() {
|
|
170
|
+
return LiblslAdapter.load;
|
|
171
|
+
}
|
|
172
|
+
get liblslFuncs() {
|
|
173
|
+
return {
|
|
41
174
|
lsl_create_streaminfo: {
|
|
42
175
|
library: 'lsl',
|
|
43
176
|
retType: DataType.External,
|
|
@@ -57,7 +190,7 @@ export default class LiblslAdapter {
|
|
|
57
190
|
},
|
|
58
191
|
lsl_push_sample_ft: {
|
|
59
192
|
library: 'lsl',
|
|
60
|
-
retType: DataType.
|
|
193
|
+
retType: DataType.I32,
|
|
61
194
|
paramsType: [
|
|
62
195
|
DataType.External,
|
|
63
196
|
DataType.FloatArray,
|
|
@@ -66,7 +199,7 @@ export default class LiblslAdapter {
|
|
|
66
199
|
},
|
|
67
200
|
lsl_push_sample_strt: {
|
|
68
201
|
library: 'lsl',
|
|
69
|
-
retType: DataType.
|
|
202
|
+
retType: DataType.I32,
|
|
70
203
|
paramsType: [
|
|
71
204
|
DataType.External,
|
|
72
205
|
DataType.StringArray,
|
|
@@ -117,62 +250,7 @@ export default class LiblslAdapter {
|
|
|
117
250
|
retType: DataType.Double,
|
|
118
251
|
paramsType: [],
|
|
119
252
|
},
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
createStreamInfo(options) {
|
|
123
|
-
const { name, type, channelCount, sampleRate, channelFormat, sourceId, } = options;
|
|
124
|
-
return this.bindings.lsl_create_streaminfo([
|
|
125
|
-
name,
|
|
126
|
-
type,
|
|
127
|
-
channelCount,
|
|
128
|
-
sampleRate,
|
|
129
|
-
channelFormat,
|
|
130
|
-
sourceId,
|
|
131
|
-
]);
|
|
132
|
-
}
|
|
133
|
-
appendChannelsToStreamInfo(options) {
|
|
134
|
-
const { info, channels } = options;
|
|
135
|
-
const description = this.bindings.lsl_get_desc([info]);
|
|
136
|
-
const parent = this.bindings.lsl_append_child([description, 'channels']);
|
|
137
|
-
for (const channel of channels) {
|
|
138
|
-
const child = this.bindings.lsl_append_child([parent, 'channel']);
|
|
139
|
-
this.bindings.lsl_append_child_value([
|
|
140
|
-
child,
|
|
141
|
-
'label',
|
|
142
|
-
channel.label,
|
|
143
|
-
]);
|
|
144
|
-
this.bindings.lsl_append_child_value([child, 'unit', channel.unit]);
|
|
145
|
-
this.bindings.lsl_append_child_value([child, 'type', channel.type]);
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
createOutlet(options) {
|
|
149
|
-
const { info, chunkSize, maxBuffered } = options;
|
|
150
|
-
return this.bindings.lsl_create_outlet([info, chunkSize, maxBuffered]);
|
|
151
|
-
}
|
|
152
|
-
pushSampleFloatTimestamp(options) {
|
|
153
|
-
const { outlet, sample, timestamp } = options;
|
|
154
|
-
this.bindings.lsl_push_sample_ft([outlet, sample, timestamp]);
|
|
155
|
-
}
|
|
156
|
-
pushSampleStringTimestamp(options) {
|
|
157
|
-
const { outlet, sample, timestamp } = options;
|
|
158
|
-
this.bindings.lsl_push_sample_strt([outlet, sample, timestamp]);
|
|
159
|
-
}
|
|
160
|
-
destroyOutlet(options) {
|
|
161
|
-
const { outlet } = options;
|
|
162
|
-
this.bindings.lsl_destroy_outlet([outlet]);
|
|
163
|
-
}
|
|
164
|
-
createInlet(options) {
|
|
165
|
-
const { info, chunkSize, maxBuffered } = options;
|
|
166
|
-
return this.bindings.lsl_create_inlet([info, chunkSize, maxBuffered]);
|
|
167
|
-
}
|
|
168
|
-
flushInlet(options) {
|
|
169
|
-
const { inlet } = options;
|
|
170
|
-
this.bindings.lsl_flush_inlet([inlet]);
|
|
171
|
-
}
|
|
172
|
-
destroyInlet(_options) { }
|
|
173
|
-
localClock() {
|
|
174
|
-
return this.bindings.lsl_local_clock([]);
|
|
253
|
+
};
|
|
175
254
|
}
|
|
176
|
-
defaultMacOsPath = '/opt/homebrew/Cellar/lsl/1.16.2/lib/liblsl.1.16.2.dylib';
|
|
177
255
|
}
|
|
178
256
|
//# sourceMappingURL=LiblslAdapter.js.map
|