@liquid-brains/brainlight 1.0.4

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/.done ADDED
File without changes
package/index.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #! /usr/bin/env ts-node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
package/index.d.ts.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/index.js ADDED
@@ -0,0 +1,247 @@
1
+ #! /usr/bin/env node
2
+ import * as Vielight from './lib/neuropro/index.js';
3
+ import * as fs from 'fs';
4
+ function AssertNever(x) {
5
+ throw (new Error(`Unexpected value: ${x}`));
6
+ }
7
+ function nonEmptyString(value) {
8
+ if (value === undefined || value === null) {
9
+ throw (new Error('Expected non-empty string'));
10
+ }
11
+ if (typeof value !== 'string' || value.trim() === '') {
12
+ throw (new Error('Expected non-empty string'));
13
+ }
14
+ return (value);
15
+ }
16
+ function nonEmptyNumber(value, defaultValue) {
17
+ if (value === undefined || value === null) {
18
+ if (defaultValue !== undefined) {
19
+ return (defaultValue);
20
+ }
21
+ throw (new Error('Expected non-empty number'));
22
+ }
23
+ if (typeof value !== 'number' || isNaN(value)) {
24
+ if (defaultValue !== undefined) {
25
+ return (defaultValue);
26
+ }
27
+ throw (new Error('Expected non-empty number'));
28
+ }
29
+ return (value);
30
+ }
31
+ function parseIntSafe(value) {
32
+ const parsed = parseInt(nonEmptyString(value), 10);
33
+ if (isNaN(parsed) || !Number.isInteger(parsed)) {
34
+ throw (new Error('Expected a valid integer'));
35
+ }
36
+ return (parsed);
37
+ }
38
+ function parseArgs(args) {
39
+ if (args.length === 0) {
40
+ return ({ command: 'help' });
41
+ }
42
+ const command = args[0];
43
+ switch (command) {
44
+ case 'help':
45
+ return ({ command: command });
46
+ case 'list':
47
+ let kinds = new Set();
48
+ for (const arg of args.slice(1)) {
49
+ if (arg === '--single') {
50
+ kinds.add('single');
51
+ }
52
+ else if (arg === '--batch') {
53
+ kinds.add('batch');
54
+ }
55
+ else {
56
+ throw new Error(`Unknown argument: ${arg}`);
57
+ }
58
+ }
59
+ return ({
60
+ command: command,
61
+ kinds: kinds
62
+ });
63
+ case 'get':
64
+ case 'save':
65
+ case 'delete':
66
+ if (args.length < 2 || !args[1]) {
67
+ throw new Error('Missing filename for get command');
68
+ }
69
+ return ({ command: command, filename: args[1] });
70
+ case 'run':
71
+ if (args.length < 2) {
72
+ throw new Error('Missing filenames for run command');
73
+ }
74
+ return ({ command: 'run', filenames: args.slice(1) });
75
+ case 'runRandom':
76
+ let preview = false;
77
+ const runRandomArgs = {};
78
+ let i = 1;
79
+ while (i < args.length) {
80
+ const arg = args[i];
81
+ if (arg === '--basename') {
82
+ i++;
83
+ runRandomArgs.basename = nonEmptyString(args[i]);
84
+ }
85
+ else if (arg === '--duration') {
86
+ i++;
87
+ runRandomArgs.duration = parseIntSafe(args[i]);
88
+ }
89
+ else if (arg === '--freq') {
90
+ i++;
91
+ const freqParts = nonEmptyString(args[i]).split('/');
92
+ if (freqParts.length === 1) {
93
+ const frequencyRange = nonEmptyString(freqParts[0]).split('...');
94
+ if (frequencyRange.length < 1 || frequencyRange.length > 2) {
95
+ throw (new Error('Invalid format for --freq argument'));
96
+ }
97
+ runRandomArgs.freqMin = parseIntSafe(frequencyRange[0]);
98
+ if (frequencyRange[1] !== undefined) {
99
+ runRandomArgs.freqMax = parseIntSafe(frequencyRange[1]);
100
+ }
101
+ }
102
+ else if (freqParts.length === 2) {
103
+ const [freqMinStr, freqMaxStr] = freqParts;
104
+ const frequencyRange = nonEmptyString(freqMinStr).split('...');
105
+ const couplingRange = nonEmptyString(freqMaxStr).split('...');
106
+ if (frequencyRange.length < 1 || frequencyRange.length > 2 || couplingRange.length < 1 || couplingRange.length > 2) {
107
+ throw (new Error('Invalid format for --freq argument'));
108
+ }
109
+ runRandomArgs.freqMin = parseIntSafe(frequencyRange[0]);
110
+ if (frequencyRange[1] !== undefined) {
111
+ runRandomArgs.freqMax = parseIntSafe(frequencyRange[1]);
112
+ }
113
+ runRandomArgs.couplingMin = parseIntSafe(couplingRange[0]);
114
+ if (couplingRange[1] !== undefined) {
115
+ runRandomArgs.couplingMax = parseIntSafe(couplingRange[1]);
116
+ }
117
+ }
118
+ else {
119
+ throw new Error('Invalid format for --freq argument');
120
+ }
121
+ }
122
+ else if (arg === '--power') {
123
+ i++;
124
+ const powerParts = nonEmptyString(args[i]).split('...');
125
+ if (powerParts.length === 1 || powerParts.length === 2) {
126
+ runRandomArgs.powerMin = parseIntSafe(powerParts[0]);
127
+ runRandomArgs.powerMax = parseIntSafe(powerParts[1] ?? String(runRandomArgs.powerMin));
128
+ }
129
+ else {
130
+ throw new Error('Invalid format for --power argument');
131
+ }
132
+ }
133
+ else if (arg === '--coupling-on-distribution') {
134
+ i++;
135
+ runRandomArgs.couplingRandomDistribution = parseIntSafe(args[i]);
136
+ }
137
+ else if (arg === '--preview') {
138
+ preview = true;
139
+ }
140
+ else {
141
+ throw new Error(`Unknown argument: ${arg}`);
142
+ }
143
+ i++;
144
+ }
145
+ if (!runRandomArgs.duration || !runRandomArgs.freqMin || !runRandomArgs.powerMin) {
146
+ throw (new Error('Missing required arguments for runRandom command'));
147
+ }
148
+ return ({
149
+ command: 'runRandom',
150
+ preview: preview,
151
+ ...runRandomArgs
152
+ });
153
+ default:
154
+ if (1 + 1 === 2) {
155
+ return ({ command: 'help' });
156
+ }
157
+ AssertNever(command);
158
+ }
159
+ }
160
+ async function listFiles(device, kinds) {
161
+ let limitKinds = undefined;
162
+ if (kinds.size > 0) {
163
+ if (kinds.has('single')) {
164
+ limitKinds ??= [];
165
+ limitKinds.push('vnp0');
166
+ limitKinds.push('vnp2');
167
+ }
168
+ if (kinds.has('batch')) {
169
+ limitKinds ??= [];
170
+ limitKinds.push('vnp3');
171
+ }
172
+ }
173
+ const files = await device.listFiles(limitKinds);
174
+ console.log('Files:');
175
+ for (const file of files) {
176
+ console.log(`- ${file}`);
177
+ }
178
+ }
179
+ async function getFile(device, filename) {
180
+ const data = await device.getFile(filename);
181
+ fs.writeFileSync(filename, JSON.stringify(data, null, 8), 'utf-8');
182
+ }
183
+ async function saveFile(device, filename) {
184
+ const data = JSON.parse(fs.readFileSync(filename, 'utf-8'));
185
+ await device.saveFile(filename, data);
186
+ }
187
+ async function deleteFile(device, filename) {
188
+ await device.deleteFile(filename);
189
+ }
190
+ async function runFiles(device, filenames) {
191
+ for (const filename of filenames) {
192
+ await device.runFile(filename);
193
+ }
194
+ }
195
+ async function runRandom(device, args) {
196
+ await device.runRandom(args);
197
+ }
198
+ async function previewRandom(args) {
199
+ const data = Vielight.VielightDevice.generateRandomParams('preview', args);
200
+ console.log(JSON.stringify(data, undefined, 8));
201
+ }
202
+ async function main(inputArgs) {
203
+ const device = new Vielight.VielightDevice({ ip: '192.168.0.58', logger: console });
204
+ const args = parseArgs(inputArgs);
205
+ switch (args.command) {
206
+ case 'list':
207
+ await listFiles(device, args.kinds);
208
+ break;
209
+ case 'get':
210
+ await getFile(device, args.filename);
211
+ break;
212
+ case 'save':
213
+ await saveFile(device, args.filename);
214
+ break;
215
+ case 'delete':
216
+ await deleteFile(device, args.filename);
217
+ break;
218
+ case 'run':
219
+ await runFiles(device, args.filenames);
220
+ break;
221
+ case 'runRandom':
222
+ if (args.preview) {
223
+ await previewRandom(args);
224
+ }
225
+ else {
226
+ await runRandom(device, args);
227
+ }
228
+ break;
229
+ case 'help':
230
+ default:
231
+ console.log('Usage:');
232
+ console.log(' list [--single] [--batch] List all files on the device');
233
+ console.log(' get <filename> Get a file from the device');
234
+ console.log(' save <filename> Save a file to the device');
235
+ console.log(' delete <filename> Delete a file from the device');
236
+ console.log(' run <filenames...> Run a sequence of files on the device');
237
+ console.log(' runRandom [--basename <string>] --duration <minutes> --freq <freqMin[...freqMax]>[/<couplingMin[...couplingMax]>] [--coupling-on-distribution <0...100>] --power <min[...max]> Run a random sequence of files on the device');
238
+ break;
239
+ }
240
+ }
241
+ main(process.argv.slice(2)).then(function () {
242
+ process.exit(0);
243
+ }, function (error) {
244
+ console.error(error);
245
+ process.exit(1);
246
+ });
247
+ //# sourceMappingURL=index.js.map
package/index.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,136 @@
1
+ #! /usr/bin/env ts-node
2
+ export type VielightRandomParams = {
3
+ basename?: string;
4
+ duration: number;
5
+ freqMin: number;
6
+ freqMax?: number;
7
+ couplingMin?: number;
8
+ couplingMax?: number;
9
+ couplingRandomDistribution?: number;
10
+ powerMin: number;
11
+ powerMax?: number;
12
+ };
13
+ export type VielightRunOptions = {
14
+ signal?: AbortSignal;
15
+ waitForCompletion?: boolean;
16
+ };
17
+ export type VielightDeviceEventPayloads = {
18
+ 'run-random-start': {
19
+ fileCount: number;
20
+ };
21
+ 'run-random-upload-start-file': {
22
+ fileName: string;
23
+ fileIndex: number;
24
+ fileCount: number;
25
+ };
26
+ 'run-randomupload-finish-file': {
27
+ fileName: string;
28
+ fileIndex: number;
29
+ fileCount: number;
30
+ };
31
+ 'run-random-run-start-file': {
32
+ fileName: string;
33
+ fileIndex: number;
34
+ fileCount: number;
35
+ };
36
+ 'run-random-run-finish-file': {
37
+ fileName: string;
38
+ fileIndex: number;
39
+ fileCount: number;
40
+ };
41
+ };
42
+ export type VielightDeviceEventListeners = {
43
+ [EventName in keyof VielightDeviceEventPayloads]: (event: VielightDeviceEventPayloads[EventName]) => void;
44
+ };
45
+ export type VielightDeviceEventName = keyof VielightDeviceEventListeners;
46
+ type VielightDeviceArgs = {
47
+ ip: string;
48
+ /** default: no logger */
49
+ logger?: Pick<typeof console, 'log' | 'error'>;
50
+ /** default: fetch. If provided, this function will be used to make HTTP requests to the device. */
51
+ fetch?: (input: URL) => Promise<{
52
+ ok: boolean;
53
+ status: number;
54
+ text: () => Promise<string>;
55
+ json: () => Promise<unknown>;
56
+ }>;
57
+ /** default: true. If false, the fetch function is assumed to not return any data, and the makeRequest function will not attempt to read the response body. */
58
+ fetchCanReturnData?: boolean;
59
+ };
60
+ export declare class VielightDevice {
61
+ private ip;
62
+ private logger?;
63
+ private fetch;
64
+ private fetchCanReturnData;
65
+ private eventListeners;
66
+ constructor(args: VielightDeviceArgs);
67
+ on<EventName extends VielightDeviceEventName>(eventName: EventName, listener: VielightDeviceEventListeners[EventName]): symbol;
68
+ off(listenerID: symbol): void;
69
+ private emit;
70
+ private makeRequest;
71
+ listFiles(limit?: 'vnp0' | 'vnp2' | 'vnp3' | ('vnp0' | 'vnp2' | 'vnp3')[]): Promise<string[]>;
72
+ getFile(filename: string): Promise<unknown>;
73
+ private saveFileNew;
74
+ private saveFileOverwrite;
75
+ private saveBatchFileNew;
76
+ private saveBatchFileOverwrite;
77
+ saveFile(filename: string, data: unknown, force?: boolean): Promise<true | undefined>;
78
+ private deleteSingleFile;
79
+ private deleteBatchFile;
80
+ deleteFile(filename: string): Promise<boolean>;
81
+ stop(): Promise<void>;
82
+ private throwIfStopped;
83
+ runFile(filename: string, options?: VielightRunOptions): Promise<void>;
84
+ runFileFromData(filename: string, data: unknown, options?: VielightRunOptions): Promise<void>;
85
+ static generateRandomParams(filename: string, args: VielightRandomParams): {
86
+ defaultFile: boolean;
87
+ secretFile: boolean;
88
+ usedByBatch: number;
89
+ single: boolean;
90
+ updateExisting: boolean;
91
+ saveNew: boolean;
92
+ filename: string;
93
+ notes: string;
94
+ frequency: {
95
+ active: boolean;
96
+ startFreq: null;
97
+ endFreq: null;
98
+ freqStepSize: null;
99
+ stepDuration: null;
100
+ };
101
+ power: {
102
+ active: boolean;
103
+ startPower: null;
104
+ endPower: null;
105
+ powerStepSize: null;
106
+ stepDuration: null;
107
+ };
108
+ cross: {
109
+ active: boolean;
110
+ freq: null;
111
+ couplingDelay: null;
112
+ stopCoupling: null;
113
+ } | {
114
+ active: boolean;
115
+ freq: number;
116
+ couplingDelay: number;
117
+ stopCoupling: number;
118
+ };
119
+ modules: {
120
+ module_no: number;
121
+ active: boolean;
122
+ activeRunTime: number;
123
+ delayStartTime: number;
124
+ moduleControl: {
125
+ phase: number;
126
+ dutyCycle: number;
127
+ };
128
+ freq: number;
129
+ power: number;
130
+ applyCross: boolean;
131
+ }[];
132
+ };
133
+ runRandom(args: VielightRandomParams, options?: VielightRunOptions): Promise<void>;
134
+ }
135
+ export {};
136
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/neuropro/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,525 @@
1
+ #! /usr/bin/env ts-node
2
+ function sessionStoppedError() {
3
+ return (new Error('Session stopped.'));
4
+ }
5
+ async function asleep(ms, signal) {
6
+ if (signal?.aborted) {
7
+ throw (sessionStoppedError());
8
+ }
9
+ return (new Promise(function (resolve, reject) {
10
+ const timeoutID = setTimeout(function () {
11
+ signal?.removeEventListener('abort', abort);
12
+ resolve();
13
+ }, ms);
14
+ function abort() {
15
+ clearTimeout(timeoutID);
16
+ reject(sessionStoppedError());
17
+ }
18
+ signal?.addEventListener('abort', abort, { once: true });
19
+ }));
20
+ }
21
+ function isBatchFile(filename, data) {
22
+ /*
23
+ * Determine if we should fetch a batch file (vnp3/vnp4) or a
24
+ * single file (vnp0/vnp1/vnp2)
25
+ */
26
+ let isBatch = false;
27
+ if (filename.match(/\.vnp[34]$/)) {
28
+ isBatch = true;
29
+ }
30
+ /*
31
+ * Verify that the contents match the isBatch determination if
32
+ * we have them
33
+ */
34
+ if (data !== undefined) {
35
+ if (typeof data !== 'object' || data === null) {
36
+ throw (new Error('invalid data: not an object'));
37
+ }
38
+ if (!('single' in data)) {
39
+ throw (new Error('invalid data: no "single"'));
40
+ }
41
+ if (typeof data.single !== 'boolean') {
42
+ throw (new Error('invalid data: "single" is not a boolean'));
43
+ }
44
+ if (data.single && isBatch) {
45
+ throw (new Error('invalid data: "single" is true but filename indicates batch file'));
46
+ }
47
+ }
48
+ return (isBatch);
49
+ }
50
+ export class VielightDevice {
51
+ ip;
52
+ logger;
53
+ fetch;
54
+ fetchCanReturnData;
55
+ eventListeners = new Map();
56
+ constructor(args) {
57
+ this.ip = args.ip;
58
+ this.logger = args.logger;
59
+ this.fetch = args.fetch ?? fetch;
60
+ this.fetchCanReturnData = args.fetchCanReturnData ?? true;
61
+ }
62
+ on(eventName, listener) {
63
+ const listenerID = Symbol(eventName);
64
+ let listeners = this.eventListeners.get(eventName);
65
+ if (listeners === undefined) {
66
+ listeners = new Map();
67
+ this.eventListeners.set(eventName, listeners);
68
+ }
69
+ listeners.set(listenerID, listener);
70
+ return (listenerID);
71
+ }
72
+ off(listenerID) {
73
+ for (const listeners of this.eventListeners.values()) {
74
+ if (listeners.delete(listenerID)) {
75
+ return;
76
+ }
77
+ }
78
+ }
79
+ emit(eventName, event) {
80
+ const listeners = this.eventListeners.get(eventName);
81
+ if (listeners === undefined) {
82
+ return;
83
+ }
84
+ for (const listener of listeners.values()) {
85
+ const typedListener = listener;
86
+ typedListener(event);
87
+ }
88
+ }
89
+ async makeRequest(path, options) {
90
+ const url = new URL(`http://${this.ip}/${path}`);
91
+ options = { ...options };
92
+ options.examineResult = options.examineResult ?? true;
93
+ options.jsonResult = options.jsonResult ?? true;
94
+ if (options?.query) {
95
+ for (const [key, value] of Object.entries(options.query)) {
96
+ url.searchParams.append(key, value);
97
+ }
98
+ }
99
+ this.logger?.log(`Making request to ${url.toString()}`);
100
+ const response = await this.fetch(url);
101
+ if (!response.ok) {
102
+ throw (new Error(`Request failed with status ${response.status}: ${await response.text()}`));
103
+ }
104
+ if (!options.examineResult) {
105
+ return (null);
106
+ }
107
+ if (!this.fetchCanReturnData) {
108
+ throw (new Error('Cannot examine result because fetch cannot return data'));
109
+ }
110
+ if (options.jsonResult) {
111
+ return (await response.json());
112
+ }
113
+ return (await response.text());
114
+ }
115
+ async listFiles(limit) {
116
+ let resultRaw0 = [];
117
+ let resultRaw1 = [];
118
+ let resultRaw2 = [];
119
+ function has(kind) {
120
+ if (limit === undefined) {
121
+ if (kind === 'vnp3') {
122
+ return (false);
123
+ }
124
+ return (true);
125
+ }
126
+ if (typeof limit === 'string') {
127
+ return (limit === kind);
128
+ }
129
+ if (Array.isArray(limit)) {
130
+ return (limit.includes(kind));
131
+ }
132
+ throw (new Error('Unexpected limit type'));
133
+ }
134
+ if (has('vnp0')) {
135
+ resultRaw0 = await this.makeRequest('getlistfile', { query: { msg: 'vnp0' } });
136
+ }
137
+ if (has('vnp2')) {
138
+ resultRaw1 = await this.makeRequest('getlistfile', { query: { msg: 'vnp2' } });
139
+ }
140
+ if (has('vnp3')) {
141
+ resultRaw2 = await this.makeRequest('getlistbatchfile', { query: { msg: 'get listbatchfile' } });
142
+ }
143
+ if (!Array.isArray(resultRaw0) || !Array.isArray(resultRaw1) || !Array.isArray(resultRaw2)) {
144
+ throw new Error('Unexpected response format');
145
+ }
146
+ const filter = function (item) {
147
+ if (typeof item !== 'string') {
148
+ throw new Error('Unexpected item format');
149
+ }
150
+ return (true);
151
+ };
152
+ const result0 = resultRaw0.filter(filter);
153
+ const result1 = resultRaw1.filter(filter);
154
+ const result2 = resultRaw2.filter(filter);
155
+ const result = [...result0, ...result1, ...result2];
156
+ return (result);
157
+ }
158
+ async getFile(filename) {
159
+ if (!isBatchFile(filename)) {
160
+ const data = await this.makeRequest('filedata', { query: { data: filename } });
161
+ return (data);
162
+ }
163
+ else {
164
+ const data = await this.makeRequest('batchfiledata', { query: { data: filename } });
165
+ return (data);
166
+ }
167
+ }
168
+ async saveFileNew(filename, data) {
169
+ await this.makeRequest('filename', { examineResult: false, query: { data: filename } });
170
+ await this.makeRequest('savenewfile', { examineResult: false, query: { data: JSON.stringify(data) } });
171
+ try {
172
+ const filelist = await this.listFiles('vnp0');
173
+ await this.makeRequest('updatelistfile', { examineResult: false, query: { data: JSON.stringify(filelist) } });
174
+ }
175
+ catch {
176
+ /*
177
+ * Ignore errors in case we can't list files
178
+ */
179
+ }
180
+ return (true);
181
+ }
182
+ async saveFileOverwrite(filename, data) {
183
+ await this.makeRequest('filename', { examineResult: false, query: { data: filename } });
184
+ await this.makeRequest('datafileExisting', { examineResult: false, query: { data: JSON.stringify(data) } });
185
+ return (true);
186
+ }
187
+ async saveBatchFileNew(filename, data) {
188
+ await this.makeRequest('batchfilename', { examineResult: false, query: { data: filename } });
189
+ await this.makeRequest('savenewbatchfile', { examineResult: false, query: { data: JSON.stringify(data) } });
190
+ try {
191
+ const filelist = await this.listFiles('vnp3');
192
+ await this.makeRequest('updatelistbatchfile', { examineResult: false, query: { data: JSON.stringify(filelist) } });
193
+ }
194
+ catch {
195
+ /*
196
+ * Ignore errors in case we can't list files
197
+ */
198
+ }
199
+ if (typeof data !== 'object' || data === null) {
200
+ return (true);
201
+ }
202
+ if (!('filenames' in data) || !Array.isArray(data.filenames)) {
203
+ return (true);
204
+ }
205
+ for (const filename of data.filenames) {
206
+ if (typeof filename !== 'string' || filename === '') {
207
+ continue;
208
+ }
209
+ await this.makeRequest('usedBatchFileTrue', { examineResult: false, query: { data: filename } });
210
+ }
211
+ return (true);
212
+ }
213
+ async saveBatchFileOverwrite(filename, data) {
214
+ await this.makeRequest('batchfilename', { examineResult: false, query: { data: filename } });
215
+ await this.makeRequest('batchdatafileExisting', { examineResult: false, query: { data: JSON.stringify(data) } });
216
+ /* XXX:TODO: Should we usedBatchFileFalse?data=<filename> for any files removed ? We can't always read the old value */
217
+ /* XXX:TODO: Should we usedBatchFileTrue?data=<filename> for any files added ? We can't always read the old value */
218
+ return (true);
219
+ }
220
+ async saveFile(filename, data, force = false) {
221
+ if (typeof data !== 'object' || data === null) {
222
+ throw (new Error('invalid data: not an object'));
223
+ }
224
+ if (!('filename' in data)) {
225
+ throw (new Error('invalid data: no filename'));
226
+ }
227
+ data.filename = filename.replace(/\.vnp[0-9]$/, '');
228
+ if (isBatchFile(filename, data)) {
229
+ try {
230
+ await this.saveBatchFileNew(filename, data);
231
+ }
232
+ catch {
233
+ force = true;
234
+ }
235
+ if (force) {
236
+ await this.saveBatchFileOverwrite(filename, data);
237
+ }
238
+ return;
239
+ }
240
+ try {
241
+ await this.saveFileNew(filename, data);
242
+ }
243
+ catch {
244
+ force = true;
245
+ }
246
+ if (force) {
247
+ await this.saveFileOverwrite(filename, data);
248
+ }
249
+ return (true);
250
+ }
251
+ async deleteSingleFile(filename) {
252
+ await this.makeRequest('deletefile', { examineResult: false, query: { data: filename } });
253
+ return (true);
254
+ }
255
+ async deleteBatchFile(filename) {
256
+ await this.makeRequest('deletebatchModule', { examineResult: false, query: { data: filename } });
257
+ try {
258
+ const filelist = await this.listFiles('vnp3');
259
+ await this.makeRequest('updatelistbatchfile', { examineResult: false, query: { data: JSON.stringify(filelist) } });
260
+ }
261
+ catch {
262
+ /*
263
+ * Ignore errors in case we can't list files
264
+ */
265
+ }
266
+ return (true);
267
+ }
268
+ async deleteFile(filename) {
269
+ if (isBatchFile(filename)) {
270
+ return (await this.deleteBatchFile(filename));
271
+ }
272
+ return (await this.deleteSingleFile(filename));
273
+ }
274
+ async stop() {
275
+ await this.makeRequest('stop', { examineResult: false, query: { msg: 'Stop button pressed' } });
276
+ }
277
+ throwIfStopped(signal) {
278
+ if (signal?.aborted) {
279
+ throw (sessionStoppedError());
280
+ }
281
+ }
282
+ async runFile(filename, options) {
283
+ options = { ...options };
284
+ options.waitForCompletion = options.waitForCompletion ?? true;
285
+ this.throwIfStopped(options?.signal);
286
+ try {
287
+ await this.stop();
288
+ }
289
+ catch {
290
+ /* Ignored */
291
+ }
292
+ await asleep(100, options?.signal);
293
+ this.throwIfStopped(options?.signal);
294
+ await this.makeRequest('filedatarun', { examineResult: false, query: { data: filename } });
295
+ await asleep(100, options?.signal);
296
+ this.throwIfStopped(options?.signal);
297
+ await this.makeRequest('run', { examineResult: false, query: { msg: 'Run button pressed' } });
298
+ //await this.makeRequest('runFreq', { jsonResult: false, query: { msg: 'Run button pressed' } });
299
+ if (!options.waitForCompletion) {
300
+ return;
301
+ }
302
+ let errorCount = 0;
303
+ let totalErrorCount = 0;
304
+ for (;;) {
305
+ await asleep(1000, options?.signal);
306
+ this.throwIfStopped(options?.signal);
307
+ let statusCode = 'UNK';
308
+ try {
309
+ const status = await this.makeRequest('activate', { jsonResult: false, query: { msg: 'Waiting for ending respond' } });
310
+ if (typeof status !== 'string') {
311
+ throw (new Error('Unexpected response format'));
312
+ }
313
+ statusCode = status.slice(0, 3);
314
+ errorCount = 0;
315
+ }
316
+ catch {
317
+ errorCount++;
318
+ totalErrorCount++;
319
+ }
320
+ this.throwIfStopped(options?.signal);
321
+ if (errorCount > 5 || totalErrorCount > 10) {
322
+ throw (new Error('Device not responding'));
323
+ }
324
+ if (statusCode === 'TOE') {
325
+ /* Normal running code */
326
+ }
327
+ else if (statusCode === 'SPT') {
328
+ break;
329
+ }
330
+ else {
331
+ this.logger?.log(`Unknown status code: ${statusCode}`);
332
+ }
333
+ }
334
+ }
335
+ async runFileFromData(filename, data, options) {
336
+ const stopDevice = () => {
337
+ void this.stop().catch(function () {
338
+ /* The local run still ends when the device is unreachable. */
339
+ });
340
+ };
341
+ options?.signal?.addEventListener('abort', stopDevice, { once: true });
342
+ if (options?.signal?.aborted) {
343
+ stopDevice();
344
+ }
345
+ try {
346
+ try {
347
+ await this.deleteFile(filename);
348
+ }
349
+ catch {
350
+ /* Ignored */
351
+ }
352
+ this.throwIfStopped(options?.signal);
353
+ await this.saveFile(filename, data);
354
+ await this.runFile(filename, options);
355
+ }
356
+ finally {
357
+ options?.signal?.removeEventListener('abort', stopDevice);
358
+ }
359
+ }
360
+ static generateRandomParams(filename, args) {
361
+ const randomValue = function (min, max) {
362
+ if (max === undefined) {
363
+ return (min);
364
+ }
365
+ const computedRandomValue = Math.floor(Math.random() * (max - min + 1)) + min;
366
+ return (computedRandomValue);
367
+ };
368
+ const randomChoice = function (choices, weights) {
369
+ if (weights === undefined) {
370
+ weights = new Array(choices.length).fill(1);
371
+ }
372
+ const totalWeight = weights.reduce((sum, weight) => sum + weight, 0);
373
+ const randomValue = Math.random() * totalWeight;
374
+ if (choices.length !== weights.length) {
375
+ throw (new Error('Choices and weights arrays must have the same length'));
376
+ }
377
+ let cumulativeWeight = 0;
378
+ for (let i = 0; i < choices.length; i++) {
379
+ cumulativeWeight += weights[i];
380
+ if (randomValue < cumulativeWeight) {
381
+ return (choices[i]);
382
+ }
383
+ }
384
+ return (choices[choices.length - 1]);
385
+ };
386
+ const frequency = randomValue(args.freqMin, args.freqMax);
387
+ let crossCouplingFreq = undefined;
388
+ if (args.couplingMin !== undefined) {
389
+ crossCouplingFreq = randomValue(args.couplingMin, args.couplingMax);
390
+ }
391
+ const crossCouplingInfo = (function () {
392
+ if (crossCouplingFreq === undefined) {
393
+ return ({
394
+ "active": false,
395
+ "freq": null,
396
+ "couplingDelay": null,
397
+ "stopCoupling": null
398
+ });
399
+ }
400
+ return ({
401
+ "active": true,
402
+ "freq": crossCouplingFreq,
403
+ "couplingDelay": 0,
404
+ "stopCoupling": 1
405
+ });
406
+ })();
407
+ return ({
408
+ "defaultFile": false,
409
+ "secretFile": false,
410
+ "usedByBatch": 0,
411
+ "single": true,
412
+ "updateExisting": true,
413
+ "saveNew": false,
414
+ "filename": filename.replace(/\.vnp0$/, ''),
415
+ "notes": 'Randomly generated file',
416
+ "frequency": {
417
+ "active": false,
418
+ "startFreq": null,
419
+ "endFreq": null,
420
+ "freqStepSize": null,
421
+ "stepDuration": null
422
+ },
423
+ "power": {
424
+ "active": false,
425
+ "startPower": null,
426
+ "endPower": null,
427
+ "powerStepSize": null,
428
+ "stepDuration": null
429
+ },
430
+ "cross": crossCouplingInfo,
431
+ "modules": new Array(12).fill(null).map(function (_, index) {
432
+ const applyCross = crossCouplingInfo.active;
433
+ const distributionA = args.couplingRandomDistribution ?? 50;
434
+ if (distributionA < 0 || distributionA > 100 || !Number.isSafeInteger(distributionA)) {
435
+ throw (new Error('invalid cross coupling random distribution'));
436
+ }
437
+ return ({
438
+ "module_no": index + 1,
439
+ "active": true,
440
+ "activeRunTime": 1,
441
+ "delayStartTime": 0,
442
+ "moduleControl": {
443
+ "phase": randomChoice([0, 1]),
444
+ "dutyCycle": 5
445
+ },
446
+ "freq": frequency,
447
+ "power": randomValue(args.powerMin, args.powerMax),
448
+ "applyCross": randomChoice([applyCross, false], [distributionA, 100 - distributionA])
449
+ });
450
+ })
451
+ });
452
+ }
453
+ async runRandom(args, options) {
454
+ const stopDevice = () => {
455
+ void this.stop().catch(function () {
456
+ /* The local loop still stops when the device is unreachable. */
457
+ });
458
+ };
459
+ options?.signal?.addEventListener('abort', stopDevice, { once: true });
460
+ if (options?.signal?.aborted) {
461
+ stopDevice();
462
+ }
463
+ const filenameGenerator = function (minute) {
464
+ return (`${args.basename ?? 'random'}_${minute}.vnp0`);
465
+ };
466
+ try {
467
+ this.throwIfStopped(options?.signal);
468
+ this.emit('run-random-start', { fileCount: args.duration });
469
+ for (let minute = 0; minute < args.duration; minute++) {
470
+ this.throwIfStopped(options?.signal);
471
+ const filename = filenameGenerator(minute);
472
+ const fileEvent = { fileName: filename, fileIndex: minute + 1, fileCount: args.duration };
473
+ this.emit('run-random-upload-start-file', fileEvent);
474
+ const data = VielightDevice.generateRandomParams(filename, args);
475
+ try {
476
+ await this.deleteFile(filename);
477
+ }
478
+ catch {
479
+ /* Ignore */
480
+ }
481
+ this.throwIfStopped(options?.signal);
482
+ await this.saveFile(filename, data);
483
+ this.emit('run-randomupload-finish-file', fileEvent);
484
+ }
485
+ this.logger?.log('Running...');
486
+ for (let minute = 0; minute < args.duration; minute++) {
487
+ this.throwIfStopped(options?.signal);
488
+ const filename = filenameGenerator(minute);
489
+ const fileEvent = { fileName: filename, fileIndex: minute + 1, fileCount: args.duration };
490
+ let runFinished = false;
491
+ let timeoutID;
492
+ try {
493
+ await Promise.race([
494
+ new Promise((resolve) => {
495
+ timeoutID = setTimeout(() => {
496
+ if (!runFinished) {
497
+ this.logger?.log('Timeout reached');
498
+ }
499
+ resolve();
500
+ }, 65_000);
501
+ }),
502
+ (async () => {
503
+ this.emit('run-random-run-start-file', fileEvent);
504
+ await this.runFile(filename, {
505
+ ...options,
506
+ waitForCompletion: true
507
+ });
508
+ runFinished = true;
509
+ this.emit('run-random-run-finish-file', fileEvent);
510
+ })()
511
+ ]);
512
+ }
513
+ finally {
514
+ if (timeoutID !== undefined) {
515
+ clearTimeout(timeoutID);
516
+ }
517
+ }
518
+ }
519
+ }
520
+ finally {
521
+ options?.signal?.removeEventListener('abort', stopDevice);
522
+ }
523
+ }
524
+ }
525
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/neuropro/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.test.d.ts","sourceRoot":"","sources":["../../../src/lib/neuropro/index.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,136 @@
1
+ import { strict as assert } from 'node:assert';
2
+ import test from 'node:test';
3
+ import { VielightDevice } from './index.js';
4
+ test('uses the supplied fetch to retrieve files', async function () {
5
+ const requestedURLs = [];
6
+ const device = new VielightDevice({
7
+ ip: '192.0.2.1:8080',
8
+ fetch: async function (input) {
9
+ requestedURLs.push(input);
10
+ return (new Response(JSON.stringify(['one.vnp0']), { status: 200 }));
11
+ }
12
+ });
13
+ const files = await device.listFiles('vnp0');
14
+ assert.deepEqual(files, ['one.vnp0']);
15
+ assert.equal(requestedURLs.length, 1);
16
+ assert.equal(requestedURLs[0]?.toString(), 'http://192.0.2.1:8080/getlistfile?msg=vnp0');
17
+ });
18
+ test('uses a fetch without response data for write-only requests', async function () {
19
+ const requestedURLs = [];
20
+ const device = new VielightDevice({
21
+ ip: '127.0.0.1',
22
+ fetchCanReturnData: false,
23
+ fetch: async function (input) {
24
+ requestedURLs.push(input);
25
+ return ({
26
+ ok: true,
27
+ status: 200,
28
+ text: async function () {
29
+ assert.fail('Write-only requests must not read response text.');
30
+ },
31
+ json: async function () {
32
+ assert.fail('Write-only requests must not read response JSON.');
33
+ }
34
+ });
35
+ }
36
+ });
37
+ await device.stop();
38
+ await device.deleteFile('old.vnp0');
39
+ await device.runFile('run.vnp0', { waitForCompletion: false });
40
+ assert.deepEqual(requestedURLs.map(function (url) {
41
+ return (url.toString());
42
+ }), [
43
+ 'http://127.0.0.1/stop?msg=Stop+button+pressed',
44
+ 'http://127.0.0.1/deletefile?data=old.vnp0',
45
+ 'http://127.0.0.1/stop?msg=Stop+button+pressed',
46
+ 'http://127.0.0.1/filedatarun?data=run.vnp0',
47
+ 'http://127.0.0.1/run?msg=Run+button+pressed'
48
+ ]);
49
+ });
50
+ test('rejects result-reading requests when fetch cannot return data', async function () {
51
+ const device = new VielightDevice({
52
+ ip: '127.0.0.1',
53
+ fetchCanReturnData: false,
54
+ fetch: async function () {
55
+ return ({
56
+ ok: true,
57
+ status: 200,
58
+ text: async function () {
59
+ assert.fail('Successful requests must not read response text before rejecting.');
60
+ },
61
+ json: async function () {
62
+ assert.fail('Successful requests must not read response JSON before rejecting.');
63
+ }
64
+ });
65
+ }
66
+ });
67
+ await assert.rejects(device.listFiles('vnp0'), /Cannot examine result because fetch cannot return data/);
68
+ });
69
+ test('runRandom reports upload and run events and removes listeners', async function () {
70
+ const device = new VielightDevice({
71
+ ip: '127.0.0.1',
72
+ fetch: async function (input) {
73
+ const requestURL = new URL(input);
74
+ if (requestURL.pathname === '/getlistfile') {
75
+ return (new Response('[]', { status: 200 }));
76
+ }
77
+ if (requestURL.pathname === '/activate') {
78
+ return (new Response('SPT', { status: 200 }));
79
+ }
80
+ return (new Response('', { status: 200 }));
81
+ }
82
+ });
83
+ const reportedEvents = [];
84
+ const removedListenerID = device.on('run-random-start', function () {
85
+ assert.fail('Removed listener was called.');
86
+ });
87
+ device.off(removedListenerID);
88
+ device.on('run-random-start', function (event) {
89
+ assert.equal(event.fileCount, 1);
90
+ reportedEvents.push('run-random-start');
91
+ });
92
+ device.on('run-random-upload-start-file', function (event) {
93
+ assert.equal(event.fileIndex, 1);
94
+ reportedEvents.push('run-random-upload-start-file');
95
+ });
96
+ device.on('run-randomupload-finish-file', function () {
97
+ reportedEvents.push('run-randomupload-finish-file');
98
+ });
99
+ device.on('run-random-run-start-file', function () {
100
+ reportedEvents.push('run-random-run-start-file');
101
+ });
102
+ device.on('run-random-run-finish-file', function () {
103
+ reportedEvents.push('run-random-run-finish-file');
104
+ });
105
+ await device.runRandom({ duration: 1, freqMin: 10, powerMin: 1 });
106
+ assert.deepEqual(reportedEvents, [
107
+ 'run-random-start',
108
+ 'run-random-upload-start-file',
109
+ 'run-randomupload-finish-file',
110
+ 'run-random-run-start-file',
111
+ 'run-random-run-finish-file'
112
+ ]);
113
+ });
114
+ test('runRandom stops the device and rejects when its signal is aborted', async function () {
115
+ const device = new VielightDevice({
116
+ ip: '127.0.0.1',
117
+ fetch: async function (input) {
118
+ const requestURL = new URL(input);
119
+ if (requestURL.pathname === '/getlistfile') {
120
+ return (new Response('[]', { status: 200 }));
121
+ }
122
+ if (requestURL.pathname === '/stop') {
123
+ stopRequests++;
124
+ }
125
+ return (new Response('', { status: 200 }));
126
+ }
127
+ });
128
+ const controller = new AbortController();
129
+ let stopRequests = 0;
130
+ device.on('run-random-run-start-file', function () {
131
+ controller.abort();
132
+ });
133
+ await assert.rejects(device.runRandom({ duration: 1, freqMin: 10, powerMin: 1 }, { signal: controller.signal }), /Session stopped\./);
134
+ assert.equal(stopRequests, 1);
135
+ });
136
+ //# sourceMappingURL=index.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.test.js","sourceRoot":"","sources":["../../../src/lib/neuropro/index.test.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,25 @@
1
+ {
2
+ "name": "@liquid-brains/brainlight",
3
+ "version": "1.0.4",
4
+ "repository": {
5
+ "type": "git",
6
+ "url": "git@github.com:liquid-brains/brainlight.git"
7
+ },
8
+ "description": "Library for interacting with various brain-light devices",
9
+ "license": "ISC",
10
+ "author": "Roy Keene <npm@rkeene.org>",
11
+ "type": "module",
12
+ "main": "index.js",
13
+ "scripts": {
14
+ "tsc": "tsc",
15
+ "test": "tsx --test src/lib/neuropro/index.test.ts"
16
+ },
17
+ "devDependencies": {
18
+ "@types/node": "26.6.3",
19
+ "tsx": "4.23.15",
20
+ "typescript": "7.0.2"
21
+ },
22
+ "allowScripts": {
23
+ "esbuild@0.28.2": true
24
+ }
25
+ }