@neurodevs/node-lsl 17.1.1 → 18.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.
Files changed (178) hide show
  1. package/.claude/settings.local.json +10 -0
  2. package/.regressionproof.json +7 -0
  3. package/.vscode/launch.json +3 -2
  4. package/README.md +9 -35
  5. package/build/.spruce/settings.json +5 -1
  6. package/build/__tests__/AbstractPackageTest.d.ts +4 -4
  7. package/build/__tests__/AbstractPackageTest.js +9 -11
  8. package/build/__tests__/AbstractPackageTest.js.map +1 -1
  9. package/build/__tests__/impl/LslBackpressureMonitor.test.d.ts +7 -0
  10. package/build/__tests__/impl/LslBackpressureMonitor.test.js +26 -0
  11. package/build/__tests__/impl/LslBackpressureMonitor.test.js.map +1 -0
  12. package/build/__tests__/impl/LslEventMarkerEmitter.test.d.ts +34 -0
  13. package/build/__tests__/impl/LslEventMarkerEmitter.test.js +243 -0
  14. package/build/__tests__/impl/LslEventMarkerEmitter.test.js.map +1 -0
  15. package/build/__tests__/impl/LslStreamInfo.test.d.ts +0 -3
  16. package/build/__tests__/impl/LslStreamInfo.test.js +2 -27
  17. package/build/__tests__/impl/LslStreamInfo.test.js.map +1 -1
  18. package/build/__tests__/impl/LslStreamInlet.test.d.ts +20 -8
  19. package/build/__tests__/impl/LslStreamInlet.test.js +224 -69
  20. package/build/__tests__/impl/LslStreamInlet.test.js.map +1 -1
  21. package/build/__tests__/impl/LslStreamOutlet.test.d.ts +3 -7
  22. package/build/__tests__/impl/LslStreamOutlet.test.js +36 -46
  23. package/build/__tests__/impl/LslStreamOutlet.test.js.map +1 -1
  24. package/build/__tests__/impl/LslWebSocketBridge.test.js +16 -17
  25. package/build/__tests__/impl/LslWebSocketBridge.test.js.map +1 -1
  26. package/build/assertions.d.ts +1 -1
  27. package/build/assertions.js.map +1 -1
  28. package/build/impl/LslBackpressureMonitor.d.ts +8 -0
  29. package/build/impl/LslBackpressureMonitor.js +8 -0
  30. package/build/impl/LslBackpressureMonitor.js.map +1 -0
  31. package/build/impl/LslEventMarkerEmitter.d.ts +35 -0
  32. package/build/impl/LslEventMarkerEmitter.js +86 -0
  33. package/build/impl/LslEventMarkerEmitter.js.map +1 -0
  34. package/build/impl/LslStreamInfo.d.ts +4 -8
  35. package/build/impl/LslStreamInfo.js +8 -21
  36. package/build/impl/LslStreamInfo.js.map +1 -1
  37. package/build/impl/LslStreamInlet.d.ts +31 -50
  38. package/build/impl/LslStreamInlet.js +79 -149
  39. package/build/impl/LslStreamInlet.js.map +1 -1
  40. package/build/impl/LslStreamOutlet.d.ts +15 -18
  41. package/build/impl/LslStreamOutlet.js +39 -47
  42. package/build/impl/LslStreamOutlet.js.map +1 -1
  43. package/build/impl/LslWebSocketBridge.d.ts +4 -5
  44. package/build/impl/LslWebSocketBridge.js +8 -8
  45. package/build/impl/LslWebSocketBridge.js.map +1 -1
  46. package/build/impl/workers/inlet/LslStreamInlet.worker.d.ts +22 -0
  47. package/build/impl/workers/inlet/LslStreamInlet.worker.js +42 -0
  48. package/build/impl/workers/inlet/LslStreamInlet.worker.js.map +1 -0
  49. package/build/impl/workers/inlet/StreamInletWorker.d.ts +73 -0
  50. package/build/impl/workers/inlet/StreamInletWorker.js +253 -0
  51. package/build/impl/workers/inlet/StreamInletWorker.js.map +1 -0
  52. package/build/impl/workers/outlet/LslStreamOutlet.worker.d.ts +32 -0
  53. package/build/impl/workers/outlet/LslStreamOutlet.worker.js +82 -0
  54. package/build/impl/workers/outlet/LslStreamOutlet.worker.js.map +1 -0
  55. package/build/index.d.ts +12 -14
  56. package/build/index.js +14 -16
  57. package/build/index.js.map +1 -1
  58. package/build/scripts/finalizeHandles.d.ts +2 -0
  59. package/build/scripts/finalizeHandles.js +48 -0
  60. package/build/scripts/finalizeHandles.js.map +1 -0
  61. package/build/scripts/runLslEventMarkerEmitter.js +11 -0
  62. package/build/scripts/runLslEventMarkerEmitter.js.map +1 -0
  63. package/build/scripts/runOutletToInlet.js +7 -6
  64. package/build/scripts/runOutletToInlet.js.map +1 -1
  65. package/build/scripts/testDestroyOutlet.d.ts +1 -0
  66. package/build/scripts/testDestroyOutlet.js +4 -0
  67. package/build/scripts/testDestroyOutlet.js.map +1 -0
  68. package/build/testDoubles/BackpressureMonitor/FakeBackpressureMonitor.d.ts +6 -0
  69. package/build/testDoubles/BackpressureMonitor/FakeBackpressureMonitor.js +10 -0
  70. package/build/testDoubles/BackpressureMonitor/FakeBackpressureMonitor.js.map +1 -0
  71. package/build/testDoubles/EventMarkerEmitter/FakeEventMarkerEmitter.d.ts +17 -0
  72. package/build/testDoubles/EventMarkerEmitter/FakeEventMarkerEmitter.js +30 -0
  73. package/build/testDoubles/EventMarkerEmitter/FakeEventMarkerEmitter.js.map +1 -0
  74. package/build/testDoubles/EventMarkerEmitter/SpyEventMarkerEmitter.d.ts +10 -0
  75. package/build/testDoubles/EventMarkerEmitter/SpyEventMarkerEmitter.js +23 -0
  76. package/build/testDoubles/EventMarkerEmitter/SpyEventMarkerEmitter.js.map +1 -0
  77. package/build/testDoubles/EventMarkerEmitter/ThrowingEventMarkerEmitter.d.ts +9 -0
  78. package/build/testDoubles/EventMarkerEmitter/ThrowingEventMarkerEmitter.js +19 -0
  79. package/build/testDoubles/EventMarkerEmitter/ThrowingEventMarkerEmitter.js.map +1 -0
  80. package/build/testDoubles/StreamInfo/FakeStreamInfo.d.ts +3 -3
  81. package/build/testDoubles/StreamInfo/FakeStreamInfo.js +3 -3
  82. package/build/testDoubles/StreamInfo/FakeStreamInfo.js.map +1 -1
  83. package/build/testDoubles/StreamInlet/FakeStreamInlet.d.ts +8 -10
  84. package/build/testDoubles/StreamInlet/FakeStreamInlet.js +6 -7
  85. package/build/testDoubles/StreamInlet/FakeStreamInlet.js.map +1 -1
  86. package/build/testDoubles/StreamInlet/SpyStreamInlet.d.ts +2 -5
  87. package/build/testDoubles/StreamInlet/SpyStreamInlet.js +2 -8
  88. package/build/testDoubles/StreamInlet/SpyStreamInlet.js.map +1 -1
  89. package/build/testDoubles/StreamOutlet/FakeStreamOutlet.d.ts +7 -9
  90. package/build/testDoubles/StreamOutlet/FakeStreamOutlet.js +5 -8
  91. package/build/testDoubles/StreamOutlet/FakeStreamOutlet.js.map +1 -1
  92. package/build/testDoubles/WebSocketBridge/FakeWebSocketBridge.d.ts +1 -1
  93. package/build/testDoubles/WebSocketBridge/FakeWebSocketBridge.js +1 -1
  94. package/build/testDoubles/WebSocketBridge/FakeWebSocketBridge.js.map +1 -1
  95. package/build/testDoubles/WorkerThreads/FakeWorker.d.ts +27 -0
  96. package/build/testDoubles/WorkerThreads/FakeWorker.js +67 -0
  97. package/build/testDoubles/WorkerThreads/FakeWorker.js.map +1 -0
  98. package/build/validations.js +0 -2
  99. package/build/validations.js.map +1 -1
  100. package/package.json +23 -7
  101. package/src/.spruce/settings.json +5 -1
  102. package/src/__tests__/AbstractPackageTest.ts +12 -14
  103. package/src/__tests__/impl/LslBackpressureMonitor.test.ts +25 -0
  104. package/src/__tests__/impl/LslEventMarkerEmitter.test.ts +322 -0
  105. package/src/__tests__/impl/LslStreamInfo.test.ts +3 -40
  106. package/src/__tests__/impl/LslStreamInlet.test.ts +344 -97
  107. package/src/__tests__/impl/LslStreamOutlet.test.ts +61 -69
  108. package/src/__tests__/impl/LslWebSocketBridge.test.ts +18 -18
  109. package/src/assertions.ts +2 -1
  110. package/src/impl/LslBackpressureMonitor.ts +13 -0
  111. package/src/impl/LslEventMarkerEmitter.ts +133 -0
  112. package/src/impl/LslStreamInfo.ts +17 -29
  113. package/src/impl/LslStreamInlet.ts +102 -215
  114. package/src/impl/LslStreamOutlet.ts +54 -78
  115. package/src/impl/LslWebSocketBridge.ts +12 -12
  116. package/src/impl/workers/inlet/LslStreamInlet.worker.ts +74 -0
  117. package/src/impl/workers/inlet/StreamInletWorker.ts +348 -0
  118. package/src/impl/workers/outlet/LslStreamOutlet.worker.ts +144 -0
  119. package/src/index.ts +14 -17
  120. package/src/scripts/finalizeHandles.ts +63 -0
  121. package/src/scripts/runLslEventMarkerEmitter.ts +15 -0
  122. package/src/scripts/runOutletToInlet.ts +10 -8
  123. package/src/scripts/testDestroyOutlet.ts +5 -0
  124. package/src/testDoubles/BackpressureMonitor/FakeBackpressureMonitor.ts +13 -0
  125. package/src/testDoubles/EventMarkerEmitter/FakeEventMarkerEmitter.ts +46 -0
  126. package/src/testDoubles/EventMarkerEmitter/SpyEventMarkerEmitter.ts +31 -0
  127. package/src/testDoubles/EventMarkerEmitter/ThrowingEventMarkerEmitter.ts +29 -0
  128. package/src/testDoubles/StreamInfo/FakeStreamInfo.ts +4 -4
  129. package/src/testDoubles/StreamInlet/FakeStreamInlet.ts +11 -17
  130. package/src/testDoubles/StreamInlet/SpyStreamInlet.ts +3 -16
  131. package/src/testDoubles/StreamOutlet/FakeStreamOutlet.ts +12 -15
  132. package/src/testDoubles/WebSocketBridge/FakeWebSocketBridge.ts +1 -1
  133. package/src/testDoubles/WorkerThreads/FakeWorker.ts +99 -0
  134. package/src/validations.ts +0 -2
  135. package/build/__tests__/impl/LiblslAdapter.test.d.ts +0 -79
  136. package/build/__tests__/impl/LiblslAdapter.test.js +0 -688
  137. package/build/__tests__/impl/LiblslAdapter.test.js.map +0 -1
  138. package/build/__tests__/impl/LslEventMarkerOutlet.test.d.ts +0 -21
  139. package/build/__tests__/impl/LslEventMarkerOutlet.test.js +0 -160
  140. package/build/__tests__/impl/LslEventMarkerOutlet.test.js.map +0 -1
  141. package/build/handleError.d.ts +0 -8
  142. package/build/handleError.js +0 -25
  143. package/build/handleError.js.map +0 -1
  144. package/build/impl/LiblslAdapter.d.ts +0 -154
  145. package/build/impl/LiblslAdapter.js +0 -317
  146. package/build/impl/LiblslAdapter.js.map +0 -1
  147. package/build/impl/LslEventMarkerOutlet.d.ts +0 -28
  148. package/build/impl/LslEventMarkerOutlet.js +0 -63
  149. package/build/impl/LslEventMarkerOutlet.js.map +0 -1
  150. package/build/scripts/runLslEventMarkerOutlet.js +0 -18
  151. package/build/scripts/runLslEventMarkerOutlet.js.map +0 -1
  152. package/build/testDoubles/EventMarkerOutlet/FakeEventMarkerOutlet.d.ts +0 -13
  153. package/build/testDoubles/EventMarkerOutlet/FakeEventMarkerOutlet.js +0 -26
  154. package/build/testDoubles/EventMarkerOutlet/FakeEventMarkerOutlet.js.map +0 -1
  155. package/build/testDoubles/EventMarkerOutlet/MockEventMarkerOutlet.d.ts +0 -17
  156. package/build/testDoubles/EventMarkerOutlet/MockEventMarkerOutlet.js +0 -46
  157. package/build/testDoubles/EventMarkerOutlet/MockEventMarkerOutlet.js.map +0 -1
  158. package/build/testDoubles/EventMarkerOutlet/SpyEventMarkerOutlet.d.ts +0 -9
  159. package/build/testDoubles/EventMarkerOutlet/SpyEventMarkerOutlet.js +0 -19
  160. package/build/testDoubles/EventMarkerOutlet/SpyEventMarkerOutlet.js.map +0 -1
  161. package/build/testDoubles/EventMarkerOutlet/ThrowingEventMarkerOutlet.d.ts +0 -9
  162. package/build/testDoubles/EventMarkerOutlet/ThrowingEventMarkerOutlet.js +0 -19
  163. package/build/testDoubles/EventMarkerOutlet/ThrowingEventMarkerOutlet.js.map +0 -1
  164. package/build/testDoubles/Liblsl/FakeLiblsl.d.ts +0 -50
  165. package/build/testDoubles/Liblsl/FakeLiblsl.js +0 -126
  166. package/build/testDoubles/Liblsl/FakeLiblsl.js.map +0 -1
  167. package/src/__tests__/impl/LiblslAdapter.test.ts +0 -817
  168. package/src/__tests__/impl/LslEventMarkerOutlet.test.ts +0 -195
  169. package/src/handleError.ts +0 -24
  170. package/src/impl/LiblslAdapter.ts +0 -543
  171. package/src/impl/LslEventMarkerOutlet.ts +0 -97
  172. package/src/scripts/runLslEventMarkerOutlet.ts +0 -23
  173. package/src/testDoubles/EventMarkerOutlet/FakeEventMarkerOutlet.ts +0 -36
  174. package/src/testDoubles/EventMarkerOutlet/MockEventMarkerOutlet.ts +0 -75
  175. package/src/testDoubles/EventMarkerOutlet/SpyEventMarkerOutlet.ts +0 -24
  176. package/src/testDoubles/EventMarkerOutlet/ThrowingEventMarkerOutlet.ts +0 -28
  177. package/src/testDoubles/Liblsl/FakeLiblsl.ts +0 -182
  178. /package/build/scripts/{runLslEventMarkerOutlet.d.ts → runLslEventMarkerEmitter.d.ts} +0 -0
@@ -1,69 +1,50 @@
1
- import { BoundInlet } from './LiblslAdapter.js';
2
- import { StreamInfo } from './LslStreamInfo.js';
1
+ import { Worker } from 'node:worker_threads';
3
2
  export default class LslStreamInlet implements StreamInlet {
4
3
  static Class?: StreamInletConstructor;
5
- isRunning: boolean;
6
- protected info: StreamInfo;
7
- private channelCount;
4
+ static Worker: typeof Worker;
5
+ static waitAfterOpenStreamMs: number;
6
+ private sourceId;
8
7
  private chunkSize;
9
8
  private maxBufferedMs;
10
- private timeoutMs;
9
+ private pullTimeoutMs;
10
+ private openStreamTimeoutMs;
11
+ private waitAfterOpenStreamMs;
12
+ private waitBetweenPullsMs;
13
+ private flushInletOnStop;
11
14
  private onData;
12
- protected inlet: BoundInlet;
13
- private pullDataMethod;
14
- private dataBuffer;
15
- private wrappedDataBufferPtr;
16
- private dataBufferPtr;
17
- private timestampBuffer;
18
- private wrappedTimestampBufferPtr;
19
- private timestampBufferPtr;
20
- private errorCodeBuffer;
21
- private wrappedErrorCodeBufferPtr;
22
- private errorCodeBufferPtr;
15
+ private worker;
16
+ private workerReady;
23
17
  private readonly sixMinutesInMs;
24
- private lsl;
25
- protected constructor(info: StreamInfo, options: StreamInletConstructorOptions, onData: OnDataCallback);
18
+ private readonly aboutOneYearInMs;
19
+ isRunning: boolean;
20
+ protected constructor(options: StreamInletOptions, onData: OnDataCallback);
26
21
  static Create(options: StreamInletOptions, onData: OnDataCallback): Promise<StreamInlet>;
27
- private setPullDataMethod;
28
- private createBoundInlet;
29
- startPulling(): void;
30
- private createWriteableBuffers;
31
- private createDataBuffer;
32
- private readonly bytesPerFloat;
33
- private createTimestampBuffer;
34
- private readonly bytesPerDouble;
35
- private createErrorCodeBuffer;
36
- private readonly bytesPerInt;
37
- private createPointersToBuffers;
38
- private createDataBufferPtr;
39
- private createTimestampBufferPtr;
40
- private createErrorCodeBufferPtr;
41
- private pullOnLoop;
42
- private pullSample;
43
- private callPullSampleBinding;
44
- private createFloatArrayFromDataBuffer;
45
- private pullChunk;
46
- private callPullChunkBinding;
47
- private createDoubleArrayFromTimestampBuffer;
48
- private handleErrorCodeIfPresent;
22
+ private createWorkerThread;
23
+ startPulling(): Promise<void>;
24
+ private postCreate;
25
+ private postStartPulling;
49
26
  stopPulling(): void;
50
- flushQueue(): void;
27
+ flushInlet(): void;
51
28
  destroy(): void;
52
- private destroyBoundInlet;
29
+ private get defaultWaitMs();
30
+ private get Worker();
53
31
  }
54
32
  export interface StreamInlet {
55
- startPulling(): void;
33
+ startPulling(): Promise<void>;
56
34
  stopPulling(): void;
57
- flushQueue(): void;
35
+ flushInlet(): void;
58
36
  destroy(): void;
59
37
  readonly isRunning: boolean;
60
38
  }
61
- export type StreamInletConstructor = new (info: StreamInfo, options: StreamInletConstructorOptions, onData: OnDataCallback) => StreamInlet;
39
+ export type StreamInletConstructor = new (options: StreamInletOptions, onData: OnDataCallback) => StreamInlet;
62
40
  export interface StreamInletOptions {
63
- info: StreamInfo;
41
+ sourceId: string;
64
42
  chunkSize: number;
65
43
  maxBufferedMs?: number;
66
- timeoutMs?: number;
44
+ openStreamTimeoutMs?: number;
45
+ waitAfterOpenStreamMs?: number;
46
+ pullTimeoutMs?: number;
47
+ waitBetweenPullsMs?: number;
48
+ flushInletOnStop?: boolean;
67
49
  }
68
- export type StreamInletConstructorOptions = Omit<StreamInletOptions, 'info'>;
69
- export type OnDataCallback = (samples: Float32Array, timestamps: Float64Array) => void;
50
+ export type OnDataCallback = (samples: number[], timestamps: number[]) => void;
@@ -1,181 +1,111 @@
1
- import { createPointer, DataType, unwrapPointer } from 'ffi-rs';
2
- import handleError from '../handleError.js';
3
- import LiblslAdapter from './LiblslAdapter.js';
1
+ import { Worker } from 'node:worker_threads';
4
2
  export default class LslStreamInlet {
5
3
  static Class;
6
- isRunning = false;
7
- info;
8
- channelCount;
4
+ static Worker = Worker;
5
+ static waitAfterOpenStreamMs = 100;
6
+ sourceId;
9
7
  chunkSize;
10
8
  maxBufferedMs;
11
- timeoutMs;
9
+ pullTimeoutMs;
10
+ openStreamTimeoutMs;
11
+ waitAfterOpenStreamMs;
12
+ waitBetweenPullsMs;
13
+ flushInletOnStop;
12
14
  onData;
13
- inlet;
14
- pullDataMethod;
15
- dataBuffer;
16
- wrappedDataBufferPtr;
17
- dataBufferPtr;
18
- timestampBuffer;
19
- wrappedTimestampBufferPtr;
20
- timestampBufferPtr;
21
- errorCodeBuffer;
22
- wrappedErrorCodeBufferPtr;
23
- errorCodeBufferPtr;
15
+ worker;
16
+ workerReady = false;
24
17
  sixMinutesInMs = 360 * 1000;
25
- lsl = LiblslAdapter.getInstance();
26
- constructor(info, options, onData) {
27
- const { chunkSize, maxBufferedMs, timeoutMs } = options ?? {};
28
- this.info = info;
29
- this.channelCount = this.info.channelCount;
18
+ aboutOneYearInMs = 32000000 * 1000;
19
+ isRunning = false;
20
+ constructor(options, onData) {
21
+ const { sourceId, chunkSize, maxBufferedMs, pullTimeoutMs, openStreamTimeoutMs, waitAfterOpenStreamMs, waitBetweenPullsMs, flushInletOnStop, } = options ?? {};
22
+ this.sourceId = sourceId;
30
23
  this.chunkSize = chunkSize;
31
24
  this.maxBufferedMs = maxBufferedMs ?? this.sixMinutesInMs;
32
- this.timeoutMs = timeoutMs ?? 0;
25
+ this.pullTimeoutMs = pullTimeoutMs ?? 0;
26
+ this.openStreamTimeoutMs = openStreamTimeoutMs ?? this.aboutOneYearInMs;
27
+ this.waitAfterOpenStreamMs = waitAfterOpenStreamMs ?? this.defaultWaitMs;
28
+ this.waitBetweenPullsMs = waitBetweenPullsMs ?? 1;
29
+ this.flushInletOnStop = flushInletOnStop ?? true;
33
30
  this.onData = onData;
34
- this.setPullDataMethod();
35
- this.createBoundInlet();
31
+ this.createWorkerThread();
36
32
  }
37
33
  static async Create(options, onData) {
38
- const { info } = options;
39
- return new (this.Class ?? this)(info, options, onData);
40
- }
41
- setPullDataMethod() {
42
- if (this.chunkSize === 1) {
43
- this.pullDataMethod = this.pullSample;
44
- }
45
- else {
46
- this.pullDataMethod = this.pullChunk;
47
- }
48
- }
49
- createBoundInlet() {
50
- this.inlet = this.lsl.createInlet({
51
- info: this.info.boundInfo,
52
- maxBufferedMs: this.maxBufferedMs,
53
- });
54
- }
55
- startPulling() {
56
- this.isRunning = true;
57
- this.createWriteableBuffers();
58
- this.createPointersToBuffers();
59
- void this.pullOnLoop();
60
- }
61
- createWriteableBuffers() {
62
- this.createDataBuffer();
63
- this.createTimestampBuffer();
64
- this.createErrorCodeBuffer();
65
- }
66
- createDataBuffer() {
67
- this.dataBuffer = Buffer.alloc(this.bytesPerFloat * this.chunkSize * this.channelCount);
68
- }
69
- bytesPerFloat = 4;
70
- createTimestampBuffer() {
71
- this.timestampBuffer = Buffer.alloc(this.bytesPerDouble * this.chunkSize);
72
- }
73
- bytesPerDouble = 8;
74
- createErrorCodeBuffer() {
75
- this.errorCodeBuffer = Buffer.alloc(this.bytesPerInt);
76
- }
77
- bytesPerInt = 4;
78
- createPointersToBuffers() {
79
- this.createDataBufferPtr();
80
- this.createTimestampBufferPtr();
81
- this.createErrorCodeBufferPtr();
82
- }
83
- createDataBufferPtr() {
84
- this.wrappedDataBufferPtr = createPointer({
85
- paramsType: [DataType.U8Array],
86
- paramsValue: [this.dataBuffer],
87
- });
88
- this.dataBufferPtr = unwrapPointer(this.wrappedDataBufferPtr)[0];
89
- }
90
- createTimestampBufferPtr() {
91
- this.wrappedTimestampBufferPtr = createPointer({
92
- paramsType: [DataType.U8Array],
93
- paramsValue: [this.timestampBuffer],
94
- });
95
- this.timestampBufferPtr = unwrapPointer(this.wrappedTimestampBufferPtr)[0];
96
- }
97
- createErrorCodeBufferPtr() {
98
- this.wrappedErrorCodeBufferPtr = createPointer({
99
- paramsType: [DataType.U8Array],
100
- paramsValue: [this.errorCodeBuffer],
34
+ return new (this.Class ?? this)(options, onData);
35
+ }
36
+ createWorkerThread() {
37
+ this.worker = new this.Worker(new URL('./workers/inlet/LslStreamInlet.worker.js', import.meta.url));
38
+ this.worker.on('message', (msg) => {
39
+ const { type } = msg;
40
+ switch (type) {
41
+ case 'ready': {
42
+ this.workerReady = true;
43
+ break;
44
+ }
45
+ case 'data': {
46
+ const { payload } = msg;
47
+ const { samples, timestamps } = payload;
48
+ this.onData(samples, timestamps);
49
+ break;
50
+ }
51
+ case 'error': {
52
+ const { error } = msg;
53
+ throw new Error(error);
54
+ }
55
+ default:
56
+ throw new Error(`Unknown message type: ${type}`);
57
+ }
101
58
  });
102
- this.errorCodeBufferPtr = unwrapPointer(this.wrappedErrorCodeBufferPtr)[0];
103
59
  }
104
- async pullOnLoop() {
105
- if (this.isRunning) {
106
- const { samples, timestamps } = this.pullDataMethod();
107
- this.handleErrorCodeIfPresent();
108
- if (samples && timestamps) {
109
- this.onData(samples, timestamps);
60
+ async startPulling() {
61
+ if (!this.isRunning) {
62
+ this.isRunning = true;
63
+ this.postCreate();
64
+ while (!this.workerReady) {
65
+ await new Promise((resolve) => setTimeout(resolve, 10));
110
66
  }
111
- setImmediate(() => {
112
- void this.pullOnLoop();
113
- });
114
- }
115
- }
116
- pullSample() {
117
- const timestamp = this.callPullSampleBinding();
118
- if (timestamp > 0) {
119
- return {
120
- samples: this.createFloatArrayFromDataBuffer(),
121
- timestamps: new Float64Array([timestamp]),
122
- };
67
+ this.postStartPulling();
123
68
  }
124
- return { samples: undefined, timestamps: undefined };
125
- }
126
- callPullSampleBinding() {
127
- return this.lsl.pullSample({
128
- inlet: this.inlet,
129
- dataBufferPtr: this.dataBufferPtr,
130
- dataBufferElements: this.channelCount,
131
- timeout: this.timeoutMs / 1000,
132
- errcodePtr: this.errorCodeBufferPtr,
133
- });
134
- }
135
- createFloatArrayFromDataBuffer() {
136
- return new Float32Array(this.dataBuffer.buffer, this.dataBuffer.byteOffset, this.chunkSize * this.channelCount);
137
- }
138
- pullChunk() {
139
- const firstTimestamp = this.callPullChunkBinding();
140
- if (firstTimestamp > 0) {
141
- return {
142
- samples: this.createFloatArrayFromDataBuffer(),
143
- timestamps: this.createDoubleArrayFromTimestampBuffer(),
144
- };
69
+ else {
70
+ console.warn('Skipping startPulling: inlet is already running!');
145
71
  }
146
- return { samples: undefined, timestamps: undefined };
147
72
  }
148
- callPullChunkBinding() {
149
- return this.lsl.pullChunk({
150
- inlet: this.inlet,
151
- dataBufferPtr: this.dataBufferPtr,
152
- dataBufferElements: this.chunkSize * this.channelCount,
153
- timestampBufferPtr: this.timestampBufferPtr,
154
- timestampBufferElements: this.chunkSize,
155
- timeout: this.timeoutMs / 1000,
156
- errcodePtr: this.errorCodeBufferPtr,
73
+ postCreate() {
74
+ this.worker.postMessage({
75
+ type: 'createInlet',
76
+ payload: {
77
+ sourceId: this.sourceId,
78
+ chunkSize: this.chunkSize,
79
+ maxBufferedMs: this.maxBufferedMs,
80
+ openStreamTimeoutMs: this.openStreamTimeoutMs,
81
+ waitAfterOpenStreamMs: this.waitAfterOpenStreamMs,
82
+ pullTimeoutMs: this.pullTimeoutMs,
83
+ waitBetweenPullsMs: this.waitBetweenPullsMs,
84
+ flushInletOnStop: this.flushInletOnStop,
85
+ },
157
86
  });
158
87
  }
159
- createDoubleArrayFromTimestampBuffer() {
160
- return new Float64Array(this.timestampBuffer.buffer, this.timestampBuffer.byteOffset, this.chunkSize);
161
- }
162
- handleErrorCodeIfPresent() {
163
- handleError(this.errorCodeBuffer.readInt32LE());
88
+ postStartPulling() {
89
+ this.worker.postMessage({ type: 'startPulling' });
164
90
  }
165
91
  stopPulling() {
166
92
  this.isRunning = false;
93
+ this.worker.postMessage({ type: 'stopPulling' });
167
94
  }
168
- flushQueue() {
169
- this.lsl.flushInlet({ inlet: this.inlet });
95
+ flushInlet() {
96
+ this.worker.postMessage({ type: 'flushInlet' });
170
97
  }
171
98
  destroy() {
172
99
  if (this.isRunning) {
173
100
  this.stopPulling();
174
101
  }
175
- this.destroyBoundInlet();
102
+ this.worker.postMessage({ type: 'destroyInlet' });
103
+ }
104
+ get defaultWaitMs() {
105
+ return LslStreamInlet.waitAfterOpenStreamMs;
176
106
  }
177
- destroyBoundInlet() {
178
- this.lsl.destroyInlet({ inlet: this.inlet });
107
+ get Worker() {
108
+ return LslStreamInlet.Worker;
179
109
  }
180
110
  }
181
111
  //# sourceMappingURL=LslStreamInlet.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"LslStreamInlet.js","sourceRoot":"","sources":["../../src/impl/LslStreamInlet.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"LslStreamInlet.js","sourceRoot":"","sources":["../../src/impl/LslStreamInlet.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,8 @@
1
- import { ChannelFormat, LslSample } from './LiblslAdapter.js';
2
- import { StreamInfo } from './LslStreamInfo.js';
1
+ import { Worker } from 'node:worker_threads';
2
+ import { ChannelFormat, LslSample } from '@neurodevs/ndx-native';
3
3
  export default class LslStreamOutlet implements StreamOutlet {
4
4
  static Class?: StreamOutletConstructor;
5
- readonly info: StreamInfo;
5
+ static Worker: typeof Worker;
6
6
  readonly name: string;
7
7
  readonly type: string;
8
8
  readonly sourceId: string;
@@ -14,30 +14,25 @@ export default class LslStreamOutlet implements StreamOutlet {
14
14
  readonly maxBufferedMs: number;
15
15
  readonly manufacturer: string;
16
16
  readonly units: string;
17
- private boundOutlet;
18
- private pushSampleMethod;
19
- private lsl;
20
- protected constructor(info: StreamInfo, options: StreamOutletOptions);
17
+ private worker;
18
+ protected constructor(options: StreamOutletOptions);
21
19
  static Create(options: StreamOutletOptions): Promise<StreamOutlet>;
22
20
  private validateOptions;
23
21
  private validateChannelFormat;
24
22
  private get isChannelFormatSupported();
25
23
  private throwUnsupportedChannelFormat;
24
+ private createWorkerThread;
26
25
  private createStreamOutlet;
27
- private setPushSampleMethod;
28
26
  private get pushMethod();
29
27
  private readonly methodMap;
30
- pushSample(sample: LslSample): void;
28
+ pushSample(sample: LslSample, timestamp?: number): void;
31
29
  destroy(): void;
32
- private destroyBoundInfo;
33
- private destroyBoundOutlet;
34
- private static waitToAllowSetup;
35
- private static LslStreamInfo;
30
+ private get Worker();
31
+ private static waitForSetup;
36
32
  }
37
33
  export interface StreamOutlet {
38
- pushSample(sample: LslSample): void;
34
+ pushSample(sample: LslSample, timestamp?: number): void;
39
35
  destroy(): void;
40
- readonly info: StreamInfo;
41
36
  readonly name: string;
42
37
  readonly type: string;
43
38
  readonly sourceId: string;
@@ -50,8 +45,11 @@ export interface StreamOutlet {
50
45
  readonly maxBufferedMs: number;
51
46
  readonly manufacturer: string;
52
47
  }
53
- export type StreamOutletConstructor = new (info: StreamInfo, options: StreamOutletOptions) => StreamOutlet;
54
- export interface StreamOutletOptions {
48
+ export type StreamOutletConstructor = new (options: StreamOutletOptions) => StreamOutlet;
49
+ export interface StreamOutletOptions extends StreamOutletConstructorOptions {
50
+ waitAfterConstructionMs?: number;
51
+ }
52
+ export interface StreamOutletConstructorOptions {
55
53
  name: string;
56
54
  type: string;
57
55
  sourceId: string;
@@ -62,5 +60,4 @@ export interface StreamOutletOptions {
62
60
  maxBufferedMs?: number;
63
61
  manufacturer?: string;
64
62
  units?: string;
65
- waitAfterConstructionMs?: number;
66
63
  }
@@ -1,10 +1,8 @@
1
+ import { Worker } from 'node:worker_threads';
1
2
  import { assertValidChannelCount, assertValidChannelFormat, assertValidChunkSize, assertValidMaxBufferedMs, assertValidSampleRateHz, } from '../assertions.js';
2
- import handleError from '../handleError.js';
3
- import LiblslAdapter from './LiblslAdapter.js';
4
- import LslStreamInfo from './LslStreamInfo.js';
5
3
  export default class LslStreamOutlet {
6
4
  static Class;
7
- info;
5
+ static Worker = Worker;
8
6
  name;
9
7
  type;
10
8
  sourceId;
@@ -16,12 +14,9 @@ export default class LslStreamOutlet {
16
14
  maxBufferedMs = 360 * 1000;
17
15
  manufacturer = 'N/A';
18
16
  units = 'N/A';
19
- boundOutlet;
20
- pushSampleMethod;
21
- lsl = LiblslAdapter.getInstance();
22
- constructor(info, options) {
17
+ worker;
18
+ constructor(options) {
23
19
  const { name, type, sourceId, channelNames, channelFormat, sampleRateHz, chunkSize, maxBufferedMs, manufacturer, units, } = options;
24
- this.info = info;
25
20
  this.name = name;
26
21
  this.type = type;
27
22
  this.sourceId = sourceId;
@@ -34,14 +29,13 @@ export default class LslStreamOutlet {
34
29
  this.manufacturer = manufacturer ?? this.manufacturer;
35
30
  this.units = units ?? this.units;
36
31
  this.validateOptions();
32
+ this.createWorkerThread();
37
33
  this.createStreamOutlet();
38
- this.setPushSampleMethod();
39
34
  }
40
35
  static async Create(options) {
41
36
  const { waitAfterConstructionMs = 10 } = options ?? {};
42
- const info = this.LslStreamInfo(options);
43
- const instance = new (this.Class ?? this)(info, options);
44
- await this.waitToAllowSetup(waitAfterConstructionMs);
37
+ const instance = new (this.Class ?? this)(options);
38
+ await this.waitForSetup(waitAfterConstructionMs);
45
39
  return instance;
46
40
  }
47
41
  validateOptions() {
@@ -63,16 +57,28 @@ export default class LslStreamOutlet {
63
57
  throwUnsupportedChannelFormat() {
64
58
  throw new Error(`This method currently does not support the ${this.channelFormat} type! Please implement it.`);
65
59
  }
60
+ createWorkerThread() {
61
+ this.worker = new this.Worker(new URL('./workers/outlet/LslStreamOutlet.worker.js', import.meta.url));
62
+ }
66
63
  createStreamOutlet() {
67
- this.boundOutlet = this.lsl.createOutlet({
68
- info: this.info.boundInfo,
69
- chunkSize: this.chunkSize,
70
- maxBufferedMs: this.maxBufferedMs,
64
+ this.worker.postMessage({
65
+ type: 'createOutlet',
66
+ payload: {
67
+ infoOptions: {
68
+ name: this.name,
69
+ type: this.type,
70
+ sourceId: this.sourceId,
71
+ channelNames: this.channelNames,
72
+ channelFormat: this.channelFormat,
73
+ sampleRateHz: this.sampleRateHz,
74
+ units: this.units,
75
+ },
76
+ chunkSize: this.chunkSize,
77
+ maxBufferedMs: this.maxBufferedMs,
78
+ pushMethod: this.pushMethod,
79
+ },
71
80
  });
72
81
  }
73
- setPushSampleMethod() {
74
- this.pushSampleMethod = this.lsl[this.pushMethod].bind(this.lsl);
75
- }
76
82
  get pushMethod() {
77
83
  return this.methodMap[this.channelFormat];
78
84
  }
@@ -80,39 +86,25 @@ export default class LslStreamOutlet {
80
86
  float32: 'pushSampleFloatTimestamp',
81
87
  string: 'pushSampleStringTimestamp',
82
88
  };
83
- pushSample(sample) {
84
- const timestamp = this.lsl.localClock();
85
- const err = this.pushSampleMethod({
86
- outlet: this.boundOutlet,
87
- sample,
88
- timestamp,
89
+ pushSample(sample, timestamp) {
90
+ this.worker.postMessage({
91
+ type: 'pushSample',
92
+ payload: {
93
+ sample,
94
+ timestamp,
95
+ },
89
96
  });
90
- handleError(err);
91
97
  }
92
98
  destroy() {
93
- this.destroyBoundInfo();
94
- this.destroyBoundOutlet();
95
- }
96
- destroyBoundInfo() {
97
- this.lsl.destroyStreamInfo({ info: this.info.boundInfo });
99
+ this.worker.postMessage({
100
+ type: 'destroyOutlet',
101
+ });
98
102
  }
99
- destroyBoundOutlet() {
100
- this.lsl.destroyOutlet({ outlet: this.boundOutlet });
103
+ get Worker() {
104
+ return LslStreamOutlet.Worker;
101
105
  }
102
- static async waitToAllowSetup(waitAfterConstructionMs) {
106
+ static async waitForSetup(waitAfterConstructionMs) {
103
107
  await new Promise((resolve) => setTimeout(resolve, waitAfterConstructionMs));
104
108
  }
105
- static LslStreamInfo(options) {
106
- const { channelNames, channelFormat, sampleRateHz, name, type, sourceId, units, } = options;
107
- return LslStreamInfo.Create({
108
- name,
109
- type,
110
- sourceId,
111
- channelNames,
112
- channelFormat,
113
- sampleRateHz,
114
- units,
115
- });
116
- }
117
109
  }
118
110
  //# sourceMappingURL=LslStreamOutlet.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"LslStreamOutlet.js","sourceRoot":"","sources":["../../src/impl/LslStreamOutlet.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"LslStreamOutlet.js","sourceRoot":"","sources":["../../src/impl/LslStreamOutlet.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAI5C,OAAO,EACH,uBAAuB,EACvB,wBAAwB,EACxB,oBAAoB,EACpB,wBAAwB,EACxB,uBAAuB,GAC1B,MAAM,kBAAkB,CAAA;AAEzB,MAAM,CAAC,OAAO,OAAO,eAAe;IACzB,MAAM,CAAC,KAAK,CAA0B;IACtC,MAAM,CAAC,MAAM,GAAG,MAAM,CAAA;IAEb,IAAI,CAAQ;IACZ,IAAI,CAAQ;IACZ,QAAQ,CAAQ;IAChB,YAAY,CAAU;IACtB,aAAa,CAAe;IAC5B,YAAY,CAAQ;IACpB,YAAY,CAAQ;IACpB,SAAS,CAAQ;IACjB,aAAa,GAAG,GAAG,GAAG,IAAI,CAAA;IAC1B,YAAY,GAAW,KAAK,CAAA;IAC5B,KAAK,GAAW,KAAK,CAAA;IAE7B,MAAM,CAAS;IAEvB,YAAsB,OAA4B;QAC9C,MAAM,EACF,IAAI,EACJ,IAAI,EACJ,QAAQ,EACR,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,SAAS,EACT,aAAa,EACb,YAAY,EACZ,KAAK,GACR,GAAG,OAAO,CAAA;QAEX,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;QAChB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;QAChB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAA;QACxB,IAAI,CAAC,YAAY,GAAG,YAAY,CAAA;QAChC,IAAI,CAAC,aAAa,GAAG,aAAa,CAAA;QAClC,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC,MAAM,CAAA;QACvC,IAAI,CAAC,YAAY,GAAG,YAAY,CAAA;QAChC,IAAI,CAAC,SAAS,GAAG,SAAS,CAAA;QAC1B,IAAI,CAAC,aAAa,GAAG,aAAa,IAAI,IAAI,CAAC,aAAa,CAAA;QACxD,IAAI,CAAC,YAAY,GAAG,YAAY,IAAI,IAAI,CAAC,YAAY,CAAA;QACrD,IAAI,CAAC,KAAK,GAAG,KAAK,IAAI,IAAI,CAAC,KAAK,CAAA;QAEhC,IAAI,CAAC,eAAe,EAAE,CAAA;QACtB,IAAI,CAAC,kBAAkB,EAAE,CAAA;QACzB,IAAI,CAAC,kBAAkB,EAAE,CAAA;IAC7B,CAAC;IAEM,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,OAA4B;QACnD,MAAM,EAAE,uBAAuB,GAAG,EAAE,EAAE,GAAG,OAAO,IAAI,EAAE,CAAA;QAEtD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC,OAAO,CAAC,CAAA;QAClD,MAAM,IAAI,CAAC,YAAY,CAAC,uBAAuB,CAAC,CAAA;QAEhD,OAAO,QAAQ,CAAA;IACnB,CAAC;IAEO,eAAe;QACnB,uBAAuB,CAAC,IAAI,CAAC,YAAY,CAAC,CAAA;QAC1C,uBAAuB,CAAC,IAAI,CAAC,YAAY,CAAC,CAAA;QAC1C,wBAAwB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAA;QAC5C,oBAAoB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;QACpC,wBAAwB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAA;QAC5C,IAAI,CAAC,qBAAqB,EAAE,CAAA;IAChC,CAAC;IAEO,qBAAqB;QACzB,IAAI,CAAC,IAAI,CAAC,wBAAwB,EAAE,CAAC;YACjC,IAAI,CAAC,6BAA6B,EAAE,CAAA;QACxC,CAAC;IACL,CAAC;IAED,IAAY,wBAAwB;QAChC,OAAO,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,SAAS,CAAA;IAC/C,CAAC;IAEO,6BAA6B;QACjC,MAAM,IAAI,KAAK,CACX,8CAA8C,IAAI,CAAC,aAAa,6BAA6B,CAChG,CAAA;IACL,CAAC;IAEO,kBAAkB;QACtB,IAAI,CAAC,MAAM,GAAG,IAAI,IAAI,CAAC,MAAM,CACzB,IAAI,GAAG,CACH,4CAA4C,EAC5C,MAAM,CAAC,IAAI,CAAC,GAAG,CAClB,CACJ,CAAA;IACL,CAAC;IAEO,kBAAkB;QACtB,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC;YACpB,IAAI,EAAE,cAAc;YACpB,OAAO,EAAE;gBACL,WAAW,EAAE;oBACT,IAAI,EAAE,IAAI,CAAC,IAAI;oBACf,IAAI,EAAE,IAAI,CAAC,IAAI;oBACf,QAAQ,EAAE,IAAI,CAAC,QAAQ;oBACvB,YAAY,EAAE,IAAI,CAAC,YAAY;oBAC/B,aAAa,EAAE,IAAI,CAAC,aAAa;oBACjC,YAAY,EAAE,IAAI,CAAC,YAAY;oBAC/B,KAAK,EAAE,IAAI,CAAC,KAAK;iBACpB;gBACD,SAAS,EAAE,IAAI,CAAC,SAAS;gBACzB,aAAa,EAAE,IAAI,CAAC,aAAa;gBACjC,UAAU,EAAE,IAAI,CAAC,UAAU;aAC9B;SACJ,CAAC,CAAA;IACN,CAAC;IAED,IAAY,UAAU;QAClB,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,aAAa,CAAC,CAAA;IAC7C,CAAC;IAEgB,SAAS,GAAiC;QACvD,OAAO,EAAE,0BAA0B;QACnC,MAAM,EAAE,2BAA2B;KACtC,CAAA;IAEM,UAAU,CAAC,MAAiB,EAAE,SAAkB;QACnD,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC;YACpB,IAAI,EAAE,YAAY;YAClB,OAAO,EAAE;gBACL,MAAM;gBACN,SAAS;aACZ;SACJ,CAAC,CAAA;IACN,CAAC;IAEM,OAAO;QACV,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC;YACpB,IAAI,EAAE,eAAe;SACxB,CAAC,CAAA;IACN,CAAC;IAED,IAAY,MAAM;QACd,OAAO,eAAe,CAAC,MAAM,CAAA;IACjC,CAAC;IAEO,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,uBAA+B;QAC7D,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAC1B,UAAU,CAAC,OAAO,EAAE,uBAAuB,CAAC,CAC/C,CAAA;IACL,CAAC"}