wsjtx-lib 1.0.3 → 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.
Files changed (48) hide show
  1. package/dist/chunk-IOOVX2IY.js +39 -0
  2. package/dist/chunk-JMWITWT7.js +74 -0
  3. package/dist/chunk-WYLCLDX4.js +483 -0
  4. package/dist/index.cjs +554 -0
  5. package/dist/index.cjs.map +1 -0
  6. package/dist/index.d.cts +192 -0
  7. package/dist/index.d.ts +192 -0
  8. package/dist/index.js +484 -0
  9. package/dist/index.js.map +1 -0
  10. package/dist/src/index.cjs +554 -0
  11. package/dist/src/index.d.cts +192 -0
  12. package/dist/src/index.d.ts +7 -5
  13. package/dist/src/index.d.ts.map +1 -1
  14. package/dist/src/index.js +24 -24
  15. package/dist/src/index.js.map +1 -1
  16. package/dist/src/types.cjs +64 -0
  17. package/dist/src/types.d.cts +252 -0
  18. package/dist/test/wsjtx.basic.test.cjs +759 -0
  19. package/dist/test/wsjtx.basic.test.d.cts +2 -0
  20. package/dist/test/wsjtx.basic.test.js +12 -14
  21. package/dist/test/wsjtx.basic.test.js.map +1 -1
  22. package/dist/test/wsjtx.test.cjs +4004 -0
  23. package/dist/test/wsjtx.test.d.cts +2 -0
  24. package/dist/test/wsjtx.test.js +12 -14
  25. package/dist/test/wsjtx.test.js.map +1 -1
  26. package/dist/types.cjs +64 -0
  27. package/dist/types.cjs.map +1 -0
  28. package/dist/types.d.cts +252 -0
  29. package/dist/types.d.ts +252 -0
  30. package/dist/types.js +8 -0
  31. package/dist/types.js.map +1 -0
  32. package/package.json +1 -1
  33. package/prebuilds/darwin-arm64/build-info.json +2 -2
  34. package/prebuilds/darwin-arm64/libfftw3f.3.dylib +0 -0
  35. package/prebuilds/darwin-arm64/libfftw3f_threads.3.dylib +0 -0
  36. package/prebuilds/darwin-arm64/libgfortran.5.dylib +0 -0
  37. package/prebuilds/darwin-arm64/wsjtx_lib_nodejs.node +0 -0
  38. package/prebuilds/linux-arm64/build-info.json +2 -2
  39. package/prebuilds/linux-arm64/wsjtx_lib_nodejs.node +0 -0
  40. package/prebuilds/linux-x64/build-info.json +2 -2
  41. package/prebuilds/linux-x64/wsjtx_lib_nodejs.node +0 -0
  42. package/prebuilds/package-info.json +2 -2
  43. package/prebuilds/win32-x64/build-info.json +3 -3
  44. package/prebuilds/win32-x64/libgcc_s_seh-1.dll +0 -0
  45. package/prebuilds/win32-x64/libgfortran-5.dll +0 -0
  46. package/prebuilds/win32-x64/libstdc++-6.dll +0 -0
  47. package/prebuilds/win32-x64/libwinpthread-1.dll +0 -0
  48. package/prebuilds/win32-x64/wsjtx_lib_nodejs.node +0 -0
package/dist/index.cjs ADDED
@@ -0,0 +1,554 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ WSJTXError: () => WSJTXError,
34
+ WSJTXLib: () => WSJTXLib,
35
+ WSJTXMode: () => WSJTXMode
36
+ });
37
+ module.exports = __toCommonJS(index_exports);
38
+
39
+ // src/types.ts
40
+ var WSJTXMode = /* @__PURE__ */ ((WSJTXMode2) => {
41
+ WSJTXMode2[WSJTXMode2["FT8"] = 0] = "FT8";
42
+ WSJTXMode2[WSJTXMode2["FT4"] = 1] = "FT4";
43
+ WSJTXMode2[WSJTXMode2["JT4"] = 2] = "JT4";
44
+ WSJTXMode2[WSJTXMode2["JT65"] = 3] = "JT65";
45
+ WSJTXMode2[WSJTXMode2["JT9"] = 4] = "JT9";
46
+ WSJTXMode2[WSJTXMode2["FST4"] = 5] = "FST4";
47
+ WSJTXMode2[WSJTXMode2["Q65"] = 6] = "Q65";
48
+ WSJTXMode2[WSJTXMode2["FST4W"] = 7] = "FST4W";
49
+ WSJTXMode2[WSJTXMode2["WSPR"] = 8] = "WSPR";
50
+ return WSJTXMode2;
51
+ })(WSJTXMode || {});
52
+ var WSJTXError = class extends Error {
53
+ constructor(message, code) {
54
+ super(message);
55
+ this.code = code;
56
+ this.name = "WSJTXError";
57
+ }
58
+ };
59
+
60
+ // src/index.ts
61
+ var import_node_module = require("module");
62
+ var import_node_url = require("url");
63
+ var import_node_path = __toESM(require("path"), 1);
64
+ var import_node_fs = __toESM(require("fs"), 1);
65
+ var import_meta = {};
66
+ function getModuleContext() {
67
+ try {
68
+ if (typeof import_meta !== "undefined" && import_meta.url) {
69
+ return {
70
+ require: (0, import_node_module.createRequire)(import_meta.url),
71
+ __filename: (0, import_node_url.fileURLToPath)(import_meta.url),
72
+ __dirname: import_node_path.default.dirname((0, import_node_url.fileURLToPath)(import_meta.url))
73
+ };
74
+ }
75
+ } catch {
76
+ }
77
+ return {
78
+ require: typeof require2 !== "undefined" ? require2 : (0, import_node_module.createRequire)("file://"),
79
+ __filename: typeof __filename !== "undefined" ? __filename : "",
80
+ __dirname: typeof __dirname !== "undefined" ? __dirname : ""
81
+ };
82
+ }
83
+ var moduleContext = getModuleContext();
84
+ var { require: require2, __filename, __dirname } = moduleContext;
85
+ function findNativeModule() {
86
+ const platform = process.platform;
87
+ const arch = process.arch;
88
+ const isPkgEnvironment = !!process.pkg || __dirname.includes("/snapshot/") || __dirname.includes("\\snapshot\\");
89
+ if (isPkgEnvironment) {
90
+ console.log("Detected pkg packaged environment");
91
+ const execDir = import_node_path.default.dirname(process.execPath);
92
+ const pkgPaths = [
93
+ // 1. 与可执行文件同目录(最常见的打包方式)
94
+ import_node_path.default.join(execDir, "wsjtx_lib_nodejs.node"),
95
+ import_node_path.default.join(execDir, `wsjtx_lib_nodejs-${platform}-${arch}.node`),
96
+ // 2. prebuilds 子目录(保持结构的打包方式)
97
+ import_node_path.default.join(execDir, "prebuilds", `${platform}-${arch}`, "wsjtx_lib_nodejs.node"),
98
+ // 3. 相对于可执行文件的其他可能位置
99
+ import_node_path.default.join(execDir, "..", "prebuilds", `${platform}-${arch}`, "wsjtx_lib_nodejs.node"),
100
+ import_node_path.default.join(execDir, "lib", "wsjtx_lib_nodejs.node"),
101
+ import_node_path.default.join(execDir, "native", "wsjtx_lib_nodejs.node")
102
+ ];
103
+ console.log("PKG environment - searching for native module:");
104
+ pkgPaths.forEach((p) => console.log(` - ${p}`));
105
+ for (const modulePath of pkgPaths) {
106
+ if (import_node_fs.default.existsSync(modulePath)) {
107
+ console.log(`Found native module at: ${modulePath}`);
108
+ return modulePath;
109
+ }
110
+ }
111
+ const pathList2 = pkgPaths.map((p) => ` - ${p}`).join("\n");
112
+ throw new Error(
113
+ `Native module not found in pkg packaged environment for ${platform}-${arch}.
114
+ Searched in:
115
+ ${pathList2}
116
+
117
+ Solutions:
118
+ 1. Ensure the native module is included in your pkg configuration
119
+ 2. Copy wsjtx_lib_nodejs.node to the same directory as your executable
120
+ 3. Check if the native module was properly bundled during packaging`
121
+ );
122
+ }
123
+ const moduleRoot = import_node_path.default.resolve(__dirname, "..");
124
+ const possiblePaths = [
125
+ // 1. Prebuilt binaries (npm packages) - highest priority
126
+ import_node_path.default.join(moduleRoot, "prebuilds", `${platform}-${arch}`, "wsjtx_lib_nodejs.node"),
127
+ // 2. GitHub Actions legacy format (for backward compatibility)
128
+ import_node_path.default.join(moduleRoot, "prebuilds", `${platform}-latest-${arch}`, "wsjtx_lib_nodejs.node"),
129
+ import_node_path.default.join(moduleRoot, "prebuilds", `ubuntu-latest-${arch}`, "wsjtx_lib_nodejs.node"),
130
+ // Linux
131
+ import_node_path.default.join(moduleRoot, "prebuilds", `macos-latest-${arch}`, "wsjtx_lib_nodejs.node"),
132
+ // macOS
133
+ import_node_path.default.join(moduleRoot, "prebuilds", `windows-latest-${arch}`, "wsjtx_lib_nodejs.node"),
134
+ // Windows
135
+ // 3. Local development builds - third priority
136
+ import_node_path.default.join(moduleRoot, "build", "wsjtx_lib_nodejs.node"),
137
+ import_node_path.default.join(moduleRoot, "build", "Release", "wsjtx_lib_nodejs.node")
138
+ ];
139
+ console.log("Normal environment - searching for native module:");
140
+ possiblePaths.forEach((p) => console.log(` - ${p}`));
141
+ for (const modulePath of possiblePaths) {
142
+ if (import_node_fs.default.existsSync(modulePath)) {
143
+ console.log(`Found native module at: ${modulePath}`);
144
+ return modulePath;
145
+ }
146
+ }
147
+ const pathList = possiblePaths.map((p) => ` - ${p}`).join("\n");
148
+ throw new Error(
149
+ `Native module not found for ${platform}-${arch}.
150
+ Searched in:
151
+ ${pathList}
152
+
153
+ Solutions:
154
+ 1. If you installed via npm, this may be a missing prebuilt binary
155
+ 2. For development, run "npm run build" to compile the native module
156
+ 3. Check if your platform/architecture is supported`
157
+ );
158
+ }
159
+ var nativeModulePath = findNativeModule();
160
+ var { WSJTXLib: NativeWSJTXLib } = require2(nativeModulePath);
161
+ var WSJTXLib = class _WSJTXLib {
162
+ native;
163
+ config;
164
+ /**
165
+ * Create a new WSJTX library instance
166
+ *
167
+ * @param config Optional configuration options
168
+ * @throws {WSJTXError} If the native library fails to initialize
169
+ */
170
+ constructor(config = {}) {
171
+ this.config = {
172
+ maxThreads: 4,
173
+ debug: false,
174
+ ...config
175
+ };
176
+ try {
177
+ this.native = new NativeWSJTXLib();
178
+ } catch (error) {
179
+ throw new WSJTXError(
180
+ `Failed to initialize WSJTX library: ${error instanceof Error ? error.message : String(error)}`,
181
+ "INIT_ERROR"
182
+ );
183
+ }
184
+ }
185
+ /**
186
+ * Decode digital radio signals from audio data
187
+ *
188
+ * This method processes audio samples and attempts to decode digital
189
+ * messages using the specified protocol mode. The operation is performed
190
+ * asynchronously to avoid blocking the Node.js event loop.
191
+ *
192
+ * @param mode The digital mode to use for decoding
193
+ * @param audioData Audio samples (Float32Array or Int16Array)
194
+ * @param frequency Center frequency in Hz
195
+ * @param threads Number of threads to use (1-16, default: 4)
196
+ * @returns Promise that resolves when decoding is complete
197
+ *
198
+ * @throws {WSJTXError} If parameters are invalid or decoding fails
199
+ *
200
+ * @example
201
+ * ```typescript
202
+ * const audioData = new Float32Array(48000 * 13); // 13 seconds
203
+ * await lib.decode(WSJTXMode.FT8, audioData, 1500);
204
+ * const messages = lib.pullMessages();
205
+ * ```
206
+ */
207
+ async decode(mode, audioData, frequency, threads = this.config.maxThreads || 4) {
208
+ this.validateMode(mode);
209
+ this.validateFrequency(frequency);
210
+ this.validateThreads(threads);
211
+ this.validateAudioData(audioData);
212
+ if (!this.isDecodingSupported(mode)) {
213
+ throw new WSJTXError(`Decoding not supported for mode: ${WSJTXMode[mode]}`, "UNSUPPORTED_MODE");
214
+ }
215
+ return new Promise((resolve, reject) => {
216
+ const callback = (error, result) => {
217
+ if (error) {
218
+ reject(new WSJTXError(error.message, "DECODE_ERROR"));
219
+ } else {
220
+ resolve({ success: result });
221
+ }
222
+ };
223
+ try {
224
+ this.native.decode(mode, audioData, frequency, threads, callback);
225
+ } catch (error) {
226
+ reject(new WSJTXError(
227
+ `Decode operation failed: ${error instanceof Error ? error.message : String(error)}`,
228
+ "DECODE_ERROR"
229
+ ));
230
+ }
231
+ });
232
+ }
233
+ /**
234
+ * Encode a message into audio waveform for transmission
235
+ *
236
+ * Generates the audio waveform that represents the specified message
237
+ * using the given digital mode. The resulting audio can be fed to
238
+ * a radio transmitter or audio interface.
239
+ *
240
+ * @param mode The digital mode to use for encoding
241
+ * @param message The message text to encode (mode-specific format)
242
+ * @param frequency Center frequency in Hz
243
+ * @param threads Number of threads to use (1-16, default: 4)
244
+ * @returns Promise that resolves with encoded audio data and actual message sent
245
+ *
246
+ * @throws {WSJTXError} If parameters are invalid or encoding fails
247
+ *
248
+ * @example
249
+ * ```typescript
250
+ * const result = await lib.encode(WSJTXMode.FT8, 'CQ DX K1ABC FN20', 1500);
251
+ * console.log('Generated audio samples:', result.audioData.length);
252
+ * console.log('Actual message sent:', result.messageSent);
253
+ * ```
254
+ */
255
+ async encode(mode, message, frequency, threads = this.config.maxThreads || 4) {
256
+ this.validateMode(mode);
257
+ this.validateMessage(message);
258
+ this.validateFrequency(frequency);
259
+ this.validateThreads(threads);
260
+ if (!this.isEncodingSupported(mode)) {
261
+ throw new WSJTXError(`Encoding not supported for mode: ${WSJTXMode[mode]}`, "UNSUPPORTED_MODE");
262
+ }
263
+ return new Promise((resolve, reject) => {
264
+ const callback = (error, result) => {
265
+ if (error) {
266
+ reject(new WSJTXError(error.message, "ENCODE_ERROR"));
267
+ } else {
268
+ resolve(result);
269
+ }
270
+ };
271
+ try {
272
+ this.native.encode(mode, message, frequency, threads, callback);
273
+ } catch (error) {
274
+ reject(new WSJTXError(
275
+ `Encode operation failed: ${error instanceof Error ? error.message : String(error)}`,
276
+ "ENCODE_ERROR"
277
+ ));
278
+ }
279
+ });
280
+ }
281
+ /**
282
+ * Decode WSPR signals from IQ data
283
+ *
284
+ * WSPR (Weak Signal Propagation Reporter) is a specialized protocol
285
+ * for studying radio propagation. This method takes IQ (complex)
286
+ * samples and attempts to decode WSPR transmissions.
287
+ *
288
+ * @param iqData Interleaved I,Q samples as Float32Array
289
+ * @param options Decoder options (frequency, callsign, etc.)
290
+ * @returns Promise that resolves with array of decoded WSPR results
291
+ *
292
+ * @throws {WSJTXError} If parameters are invalid or decoding fails
293
+ *
294
+ * @example
295
+ * ```typescript
296
+ * const iqData = new Float32Array(2 * 12000 * 111); // 2 minutes of IQ data
297
+ * const options = {
298
+ * dialFrequency: 14095600, // 20m WSPR frequency
299
+ * callsign: 'K1ABC',
300
+ * locator: 'FN20'
301
+ * };
302
+ * const results = await lib.decodeWSPR(iqData, options);
303
+ * ```
304
+ */
305
+ async decodeWSPR(iqData, options = {}) {
306
+ this.validateIQData(iqData);
307
+ const defaultOptions = {
308
+ dialFrequency: 14095600,
309
+ // 20m WSPR frequency
310
+ callsign: "",
311
+ locator: "",
312
+ quickMode: false,
313
+ useHashTable: true,
314
+ passes: 2,
315
+ subtraction: true,
316
+ ...options
317
+ };
318
+ return new Promise((resolve, reject) => {
319
+ const callback = (error, results) => {
320
+ if (error) {
321
+ reject(new WSJTXError(error.message, "WSPR_DECODE_ERROR"));
322
+ } else {
323
+ resolve(results);
324
+ }
325
+ };
326
+ try {
327
+ this.native.decodeWSPR(iqData, defaultOptions, callback);
328
+ } catch (error) {
329
+ reject(new WSJTXError(
330
+ `WSPR decode failed: ${error instanceof Error ? error.message : String(error)}`,
331
+ "WSPR_DECODE_ERROR"
332
+ ));
333
+ }
334
+ });
335
+ }
336
+ /**
337
+ * Retrieve decoded messages from the internal queue
338
+ *
339
+ * Messages are added to an internal queue as they are decoded.
340
+ * This method retrieves and removes all pending messages from the queue.
341
+ *
342
+ * @returns Array of decoded messages
343
+ *
344
+ * @example
345
+ * ```typescript
346
+ * const messages = lib.pullMessages();
347
+ * messages.forEach(msg => {
348
+ * console.log(`${msg.text} (SNR: ${msg.snr} dB, ΔT: ${msg.deltaTime}s)`);
349
+ * });
350
+ * ```
351
+ */
352
+ pullMessages() {
353
+ try {
354
+ return this.native.pullMessages();
355
+ } catch (error) {
356
+ throw new WSJTXError(
357
+ `Failed to pull messages: ${error instanceof Error ? error.message : String(error)}`,
358
+ "PULL_ERROR"
359
+ );
360
+ }
361
+ }
362
+ /**
363
+ * Check if encoding is supported for a specific mode
364
+ *
365
+ * @param mode The mode to check
366
+ * @returns True if encoding is supported
367
+ */
368
+ isEncodingSupported(mode) {
369
+ return this.native.isEncodingSupported(mode);
370
+ }
371
+ /**
372
+ * Check if decoding is supported for a specific mode
373
+ *
374
+ * @param mode The mode to check
375
+ * @returns True if decoding is supported
376
+ */
377
+ isDecodingSupported(mode) {
378
+ return this.native.isDecodingSupported(mode);
379
+ }
380
+ /**
381
+ * Get the required sample rate for a specific mode
382
+ *
383
+ * @param mode The mode to query
384
+ * @returns Sample rate in Hz
385
+ */
386
+ getSampleRate(mode) {
387
+ return this.native.getSampleRate(mode);
388
+ }
389
+ /**
390
+ * Get the transmission duration for a specific mode
391
+ *
392
+ * @param mode The mode to query
393
+ * @returns Duration in seconds
394
+ */
395
+ getTransmissionDuration(mode) {
396
+ return this.native.getTransmissionDuration(mode);
397
+ }
398
+ /**
399
+ * Get capabilities for all supported modes
400
+ *
401
+ * @returns Array of mode capability information
402
+ */
403
+ getAllModeCapabilities() {
404
+ const modes = Object.values(WSJTXMode).filter((v) => typeof v === "number");
405
+ return modes.map((mode) => ({
406
+ mode,
407
+ encodingSupported: this.isEncodingSupported(mode),
408
+ decodingSupported: this.isDecodingSupported(mode),
409
+ sampleRate: this.getSampleRate(mode),
410
+ duration: this.getTransmissionDuration(mode)
411
+ }));
412
+ }
413
+ /**
414
+ * Convert audio format between Float32Array and Int16Array
415
+ *
416
+ * @param audioData Input audio data
417
+ * @param targetFormat Target format ('float32' or 'int16')
418
+ * @returns Converted audio data
419
+ */
420
+ static convertAudioFormat(audioData, targetFormat) {
421
+ if (targetFormat !== "float32" && targetFormat !== "int16") {
422
+ throw new Error(`Invalid target format: ${targetFormat}. Must be 'float32' or 'int16'`);
423
+ }
424
+ if (targetFormat === "float32") {
425
+ if (audioData instanceof Float32Array) {
426
+ return audioData;
427
+ }
428
+ const result = new Float32Array(audioData.length);
429
+ for (let i = 0; i < audioData.length; i++) {
430
+ result[i] = audioData[i] / 32768;
431
+ }
432
+ return result;
433
+ } else {
434
+ if (audioData instanceof Int16Array) {
435
+ return audioData;
436
+ }
437
+ const result = new Int16Array(audioData.length);
438
+ for (let i = 0; i < audioData.length; i++) {
439
+ result[i] = Math.max(-32768, Math.min(32767, Math.round(audioData[i] * 32768)));
440
+ }
441
+ return result;
442
+ }
443
+ }
444
+ /**
445
+ * Static convenience helper for async audio format conversion.
446
+ */
447
+ static async convertAudioFormatAsync(audioData, targetFormat) {
448
+ const lib = new _WSJTXLib();
449
+ return lib.convertAudioFormatAsync(audioData, targetFormat);
450
+ }
451
+ /**
452
+ * Asynchronously convert audio data format without blocking the event loop
453
+ *
454
+ * Uses native thread pool to offload conversion.
455
+ */
456
+ async convertAudioFormatAsync(audioData, targetFormat) {
457
+ if (targetFormat !== "float32" && targetFormat !== "int16") {
458
+ throw new Error(`Invalid target format: ${targetFormat}. Must be 'float32' or 'int16'`);
459
+ }
460
+ this.validateAudioData(audioData);
461
+ return new Promise((resolve, reject) => {
462
+ const callback = (error, result) => {
463
+ if (error) {
464
+ reject(new WSJTXError(error.message ?? String(error), "CONVERT_ERROR"));
465
+ } else {
466
+ resolve(result);
467
+ }
468
+ };
469
+ try {
470
+ this.native.convertAudioAsync(audioData, targetFormat, callback);
471
+ } catch (error) {
472
+ reject(new WSJTXError(
473
+ `Convert operation failed: ${error instanceof Error ? error.message : String(error)}`,
474
+ "CONVERT_ERROR"
475
+ ));
476
+ }
477
+ });
478
+ }
479
+ // Validation methods
480
+ validateMode(mode) {
481
+ if (!Object.values(WSJTXMode).includes(mode)) {
482
+ throw new WSJTXError(`Invalid mode: ${mode}`, "INVALID_MODE");
483
+ }
484
+ }
485
+ validateFrequency(frequency) {
486
+ if (!Number.isInteger(frequency) || frequency < 0 || frequency > 3e7) {
487
+ throw new WSJTXError(
488
+ `Invalid frequency: ${frequency}. Must be between 0 and 30,000,000 Hz`,
489
+ "INVALID_FREQUENCY"
490
+ );
491
+ }
492
+ }
493
+ validateThreads(threads) {
494
+ if (!Number.isInteger(threads) || threads < 1 || threads > 16) {
495
+ throw new WSJTXError(
496
+ `Invalid thread count: ${threads}. Must be between 1 and 16`,
497
+ "INVALID_THREADS"
498
+ );
499
+ }
500
+ }
501
+ validateMessage(message) {
502
+ if (typeof message !== "string" || message.length === 0 || message.length > 22) {
503
+ throw new WSJTXError(
504
+ `Invalid message: "${message}". Must be 1-22 characters long`,
505
+ "INVALID_MESSAGE"
506
+ );
507
+ }
508
+ }
509
+ validateAudioData(audioData) {
510
+ if (!(audioData instanceof Float32Array) && !(audioData instanceof Int16Array)) {
511
+ throw new WSJTXError(
512
+ "Invalid audio data: must be Float32Array or Int16Array",
513
+ "INVALID_AUDIO_DATA"
514
+ );
515
+ }
516
+ if (audioData.length === 0) {
517
+ throw new WSJTXError("Audio data cannot be empty", "INVALID_AUDIO_DATA");
518
+ }
519
+ }
520
+ validateIQData(iqData) {
521
+ if (!(iqData instanceof Float32Array)) {
522
+ throw new WSJTXError(
523
+ "Invalid IQ data: must be Float32Array with interleaved I,Q samples",
524
+ "INVALID_IQ_DATA"
525
+ );
526
+ }
527
+ if (iqData.length === 0 || iqData.length % 2 !== 0) {
528
+ throw new WSJTXError(
529
+ "IQ data length must be even (interleaved I,Q samples)",
530
+ "INVALID_IQ_DATA"
531
+ );
532
+ }
533
+ }
534
+ };
535
+ // Annotate the CommonJS export names for ESM import in node:
536
+ 0 && (module.exports = {
537
+ WSJTXError,
538
+ WSJTXLib,
539
+ WSJTXMode
540
+ });
541
+ /**
542
+ * WSJTX Digital Radio Protocol Library for Node.js
543
+ *
544
+ * This library provides encoding and decoding capabilities for various
545
+ * digital amateur radio protocols including FT8, FT4, WSPR, and others.
546
+ *
547
+ * The library is a Node.js C++ extension that wraps the wsjtx_lib C library,
548
+ * providing high-performance digital signal processing capabilities with
549
+ * multi-platform support (Windows, macOS, Linux).
550
+ *
551
+ * @version 1.0.0
552
+ * @author WSJTX Development Team
553
+ * @license GPL-3.0
554
+ */
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/types.ts"],"sourcesContent":["/**\n * WSJTX Digital Radio Protocol Library for Node.js\n * \n * High-level TypeScript wrapper around the native C++ WSJTX library bindings.\n * Provides async/await support, input validation, and convenient utilities\n * for working with digital amateur radio protocols.\n * \n * @example\n * ```typescript\n * import { WSJTXLib, WSJTXMode } from 'wsjtx-lib';\n * \n * const lib = new WSJTXLib();\n * \n * // Decode FT8 audio data\n * const audioData = new Float32Array(48000 * 13); // 13 seconds at 48kHz\n * const result = await lib.decode(WSJTXMode.FT8, audioData, 1500);\n * \n * // Get decoded messages\n * const messages = lib.pullMessages();\n * console.log('Decoded messages:', messages);\n * ```\n */\n\nimport {\n WSJTXMode,\n DecodeResult,\n EncodeResult,\n WSPRResult,\n WSPRDecodeOptions,\n WSJTXMessage,\n AudioData,\n IQData,\n WSJTXError,\n WSJTXConfig,\n VersionInfo,\n ModeCapabilities,\n DecodeCallback,\n EncodeCallback,\n WSPRDecodeCallback\n} from './types.js';\n\nimport { createRequire } from 'node:module';\nimport { fileURLToPath } from 'node:url';\nimport path from 'node:path';\nimport fs from 'node:fs';\n\n// Create require function and directory paths\n// Use conditional logic to support both ES modules and CommonJS\ninterface ModuleContext {\n require: NodeRequire;\n __filename: string;\n __dirname: string;\n}\n\nfunction getModuleContext(): ModuleContext {\n try {\n // ES module environment\n if (typeof import.meta !== 'undefined' && import.meta.url) {\n return {\n require: createRequire(import.meta.url),\n __filename: fileURLToPath(import.meta.url),\n __dirname: path.dirname(fileURLToPath(import.meta.url))\n };\n }\n } catch {\n // Fallback for build-time transformation\n }\n \n // CommonJS environment fallback\n // These will be replaced during build transformation\n return {\n require: ((typeof require !== 'undefined') ? require : createRequire('file://')) as NodeRequire,\n __filename: (typeof __filename !== 'undefined') ? __filename : '',\n __dirname: (typeof __dirname !== 'undefined') ? __dirname : ''\n };\n}\n\nconst moduleContext: ModuleContext = getModuleContext();\nconst { require, __filename, __dirname } = moduleContext;\n\n// Determine the correct path to the native module\n// Priority order:\n// 1. pkg packaged environment (highest priority when in pkg)\n// 2. Prebuilt binaries (for npm published packages) \n// 3. Local build output (for development)\nfunction findNativeModule(): string {\n const platform = process.platform;\n const arch = process.arch;\n \n // 检测是否在 pkg 打包环境中\n const isPkgEnvironment = !!(process as any).pkg || __dirname.includes('/snapshot/') || __dirname.includes('\\\\snapshot\\\\');\n \n if (isPkgEnvironment) {\n console.log('Detected pkg packaged environment');\n \n // 在 pkg 环境中,原生模块通常位于可执行文件目录\n const execDir = path.dirname(process.execPath);\n \n const pkgPaths = [\n // 1. 与可执行文件同目录(最常见的打包方式)\n path.join(execDir, 'wsjtx_lib_nodejs.node'),\n path.join(execDir, `wsjtx_lib_nodejs-${platform}-${arch}.node`),\n \n // 2. prebuilds 子目录(保持结构的打包方式)\n path.join(execDir, 'prebuilds', `${platform}-${arch}`, 'wsjtx_lib_nodejs.node'),\n \n // 3. 相对于可执行文件的其他可能位置\n path.join(execDir, '..', 'prebuilds', `${platform}-${arch}`, 'wsjtx_lib_nodejs.node'),\n path.join(execDir, 'lib', 'wsjtx_lib_nodejs.node'),\n path.join(execDir, 'native', 'wsjtx_lib_nodejs.node'),\n ];\n \n console.log('PKG environment - searching for native module:');\n pkgPaths.forEach(p => console.log(` - ${p}`));\n \n for (const modulePath of pkgPaths) {\n if (fs.existsSync(modulePath)) {\n console.log(`Found native module at: ${modulePath}`);\n return modulePath;\n }\n }\n \n // 如果在 pkg 环境中找不到模块,抛出专门的错误信息\n const pathList = pkgPaths.map(p => ` - ${p}`).join('\\n');\n throw new Error(\n `Native module not found in pkg packaged environment for ${platform}-${arch}.\\n` +\n `Searched in:\\n${pathList}\\n\\n` +\n 'Solutions:\\n' +\n '1. Ensure the native module is included in your pkg configuration\\n' +\n '2. Copy wsjtx_lib_nodejs.node to the same directory as your executable\\n' +\n '3. Check if the native module was properly bundled during packaging'\n );\n }\n \n // 获取当前模块的根目录\n // __dirname 为 dist 目录,需要回退一级到项目根目录\n const moduleRoot = path.resolve(__dirname, '..');\n \n const possiblePaths = [\n // 1. Prebuilt binaries (npm packages) - highest priority\n path.join(moduleRoot, 'prebuilds', `${platform}-${arch}`, 'wsjtx_lib_nodejs.node'),\n \n // 2. GitHub Actions legacy format (for backward compatibility)\n path.join(moduleRoot, 'prebuilds', `${platform}-latest-${arch}`, 'wsjtx_lib_nodejs.node'),\n path.join(moduleRoot, 'prebuilds', `ubuntu-latest-${arch}`, 'wsjtx_lib_nodejs.node'), // Linux\n path.join(moduleRoot, 'prebuilds', `macos-latest-${arch}`, 'wsjtx_lib_nodejs.node'), // macOS \n path.join(moduleRoot, 'prebuilds', `windows-latest-${arch}`, 'wsjtx_lib_nodejs.node'), // Windows\n \n // 3. Local development builds - third priority\n path.join(moduleRoot, 'build', 'wsjtx_lib_nodejs.node'),\n path.join(moduleRoot, 'build', 'Release', 'wsjtx_lib_nodejs.node'),\n ];\n\n // 添加调试信息\n console.log('Normal environment - searching for native module:');\n possiblePaths.forEach(p => console.log(` - ${p}`));\n\n for (const modulePath of possiblePaths) {\n if (fs.existsSync(modulePath)) {\n console.log(`Found native module at: ${modulePath}`);\n return modulePath;\n }\n }\n\n // If no module found, throw a helpful error with all attempted paths\n const pathList = possiblePaths.map(p => ` - ${p}`).join('\\n');\n throw new Error(\n `Native module not found for ${platform}-${arch}.\\n` +\n `Searched in:\\n${pathList}\\n\\n` +\n 'Solutions:\\n' +\n '1. If you installed via npm, this may be a missing prebuilt binary\\n' +\n '2. For development, run \"npm run build\" to compile the native module\\n' +\n '3. Check if your platform/architecture is supported'\n );\n}\n\nconst nativeModulePath = findNativeModule();\n\n// Import the native module (will be built by cmake-js)\n// @ts-ignore - Native module types are defined separately\nconst { WSJTXLib: NativeWSJTXLib } = require(nativeModulePath);\n\n/**\n * Main WSJTX library class providing digital radio protocol processing\n * \n * This class wraps the native C++ implementation and provides a convenient\n * TypeScript/JavaScript interface with proper error handling, validation,\n * and async/await support.\n */\nexport class WSJTXLib {\n private native: any;\n private config: WSJTXConfig;\n\n /**\n * Create a new WSJTX library instance\n * \n * @param config Optional configuration options\n * @throws {WSJTXError} If the native library fails to initialize\n */\n constructor(config: WSJTXConfig = {}) {\n this.config = {\n maxThreads: 4,\n debug: false,\n ...config\n };\n\n try {\n this.native = new NativeWSJTXLib();\n } catch (error) {\n throw new WSJTXError(\n `Failed to initialize WSJTX library: ${error instanceof Error ? error.message : String(error)}`,\n 'INIT_ERROR'\n );\n }\n }\n\n /**\n * Decode digital radio signals from audio data\n * \n * This method processes audio samples and attempts to decode digital\n * messages using the specified protocol mode. The operation is performed\n * asynchronously to avoid blocking the Node.js event loop.\n * \n * @param mode The digital mode to use for decoding\n * @param audioData Audio samples (Float32Array or Int16Array)\n * @param frequency Center frequency in Hz\n * @param threads Number of threads to use (1-16, default: 4)\n * @returns Promise that resolves when decoding is complete\n * \n * @throws {WSJTXError} If parameters are invalid or decoding fails\n * \n * @example\n * ```typescript\n * const audioData = new Float32Array(48000 * 13); // 13 seconds\n * await lib.decode(WSJTXMode.FT8, audioData, 1500);\n * const messages = lib.pullMessages();\n * ```\n */\n async decode(\n mode: WSJTXMode,\n audioData: AudioData,\n frequency: number,\n threads: number = this.config.maxThreads || 4\n ): Promise<DecodeResult> {\n this.validateMode(mode);\n this.validateFrequency(frequency);\n this.validateThreads(threads);\n this.validateAudioData(audioData);\n\n if (!this.isDecodingSupported(mode)) {\n throw new WSJTXError(`Decoding not supported for mode: ${WSJTXMode[mode]}`, 'UNSUPPORTED_MODE');\n }\n\n return new Promise((resolve, reject) => {\n const callback: DecodeCallback = (error, result) => {\n if (error) {\n reject(new WSJTXError(error.message, 'DECODE_ERROR'));\n } else {\n // Convert boolean result to DecodeResult object\n resolve({ success: result as boolean });\n }\n };\n\n try {\n this.native.decode(mode, audioData, frequency, threads, callback);\n } catch (error) {\n reject(new WSJTXError(\n `Decode operation failed: ${error instanceof Error ? error.message : String(error)}`,\n 'DECODE_ERROR'\n ));\n }\n });\n }\n\n /**\n * Encode a message into audio waveform for transmission\n * \n * Generates the audio waveform that represents the specified message\n * using the given digital mode. The resulting audio can be fed to\n * a radio transmitter or audio interface.\n * \n * @param mode The digital mode to use for encoding\n * @param message The message text to encode (mode-specific format)\n * @param frequency Center frequency in Hz\n * @param threads Number of threads to use (1-16, default: 4)\n * @returns Promise that resolves with encoded audio data and actual message sent\n * \n * @throws {WSJTXError} If parameters are invalid or encoding fails\n * \n * @example\n * ```typescript\n * const result = await lib.encode(WSJTXMode.FT8, 'CQ DX K1ABC FN20', 1500);\n * console.log('Generated audio samples:', result.audioData.length);\n * console.log('Actual message sent:', result.messageSent);\n * ```\n */\n async encode(\n mode: WSJTXMode,\n message: string,\n frequency: number,\n threads: number = this.config.maxThreads || 4\n ): Promise<EncodeResult> {\n this.validateMode(mode);\n this.validateMessage(message);\n this.validateFrequency(frequency);\n this.validateThreads(threads);\n\n if (!this.isEncodingSupported(mode)) {\n throw new WSJTXError(`Encoding not supported for mode: ${WSJTXMode[mode]}`, 'UNSUPPORTED_MODE');\n }\n\n return new Promise((resolve, reject) => {\n const callback: EncodeCallback = (error, result) => {\n if (error) {\n reject(new WSJTXError(error.message, 'ENCODE_ERROR'));\n } else {\n resolve(result);\n }\n };\n\n try {\n this.native.encode(mode, message, frequency, threads, callback);\n } catch (error) {\n reject(new WSJTXError(\n `Encode operation failed: ${error instanceof Error ? error.message : String(error)}`,\n 'ENCODE_ERROR'\n ));\n }\n });\n }\n\n /**\n * Decode WSPR signals from IQ data\n * \n * WSPR (Weak Signal Propagation Reporter) is a specialized protocol\n * for studying radio propagation. This method takes IQ (complex)\n * samples and attempts to decode WSPR transmissions.\n * \n * @param iqData Interleaved I,Q samples as Float32Array\n * @param options Decoder options (frequency, callsign, etc.)\n * @returns Promise that resolves with array of decoded WSPR results\n * \n * @throws {WSJTXError} If parameters are invalid or decoding fails\n * \n * @example\n * ```typescript\n * const iqData = new Float32Array(2 * 12000 * 111); // 2 minutes of IQ data\n * const options = {\n * dialFrequency: 14095600, // 20m WSPR frequency\n * callsign: 'K1ABC',\n * locator: 'FN20'\n * };\n * const results = await lib.decodeWSPR(iqData, options);\n * ```\n */\n async decodeWSPR(\n iqData: IQData,\n options: WSPRDecodeOptions = {}\n ): Promise<WSPRResult[]> {\n this.validateIQData(iqData);\n\n const defaultOptions: Required<WSPRDecodeOptions> = {\n dialFrequency: 14095600, // 20m WSPR frequency\n callsign: '',\n locator: '',\n quickMode: false,\n useHashTable: true,\n passes: 2,\n subtraction: true,\n ...options\n };\n\n return new Promise((resolve, reject) => {\n const callback: WSPRDecodeCallback = (error, results) => {\n if (error) {\n reject(new WSJTXError(error.message, 'WSPR_DECODE_ERROR'));\n } else {\n resolve(results);\n }\n };\n\n try {\n this.native.decodeWSPR(iqData, defaultOptions, callback);\n } catch (error) {\n reject(new WSJTXError(\n `WSPR decode failed: ${error instanceof Error ? error.message : String(error)}`,\n 'WSPR_DECODE_ERROR'\n ));\n }\n });\n }\n\n /**\n * Retrieve decoded messages from the internal queue\n * \n * Messages are added to an internal queue as they are decoded.\n * This method retrieves and removes all pending messages from the queue.\n * \n * @returns Array of decoded messages\n * \n * @example\n * ```typescript\n * const messages = lib.pullMessages();\n * messages.forEach(msg => {\n * console.log(`${msg.text} (SNR: ${msg.snr} dB, ΔT: ${msg.deltaTime}s)`);\n * });\n * ```\n */\n pullMessages(): WSJTXMessage[] {\n try {\n return this.native.pullMessages();\n } catch (error) {\n throw new WSJTXError(\n `Failed to pull messages: ${error instanceof Error ? error.message : String(error)}`,\n 'PULL_ERROR'\n );\n }\n }\n\n /**\n * Check if encoding is supported for a specific mode\n * \n * @param mode The mode to check\n * @returns True if encoding is supported\n */\n isEncodingSupported(mode: WSJTXMode): boolean {\n return this.native.isEncodingSupported(mode);\n }\n\n /**\n * Check if decoding is supported for a specific mode\n * \n * @param mode The mode to check\n * @returns True if decoding is supported\n */\n isDecodingSupported(mode: WSJTXMode): boolean {\n return this.native.isDecodingSupported(mode);\n }\n\n /**\n * Get the required sample rate for a specific mode\n * \n * @param mode The mode to query\n * @returns Sample rate in Hz\n */\n getSampleRate(mode: WSJTXMode): number {\n return this.native.getSampleRate(mode);\n }\n\n /**\n * Get the transmission duration for a specific mode\n * \n * @param mode The mode to query\n * @returns Duration in seconds\n */\n getTransmissionDuration(mode: WSJTXMode): number {\n return this.native.getTransmissionDuration(mode);\n }\n\n /**\n * Get capabilities for all supported modes\n * \n * @returns Array of mode capability information\n */\n getAllModeCapabilities(): ModeCapabilities[] {\n const modes = Object.values(WSJTXMode).filter(v => typeof v === 'number') as WSJTXMode[];\n \n return modes.map(mode => ({\n mode,\n encodingSupported: this.isEncodingSupported(mode),\n decodingSupported: this.isDecodingSupported(mode),\n sampleRate: this.getSampleRate(mode),\n duration: this.getTransmissionDuration(mode)\n }));\n }\n\n /**\n * Convert audio format between Float32Array and Int16Array\n * \n * @param audioData Input audio data\n * @param targetFormat Target format ('float32' or 'int16')\n * @returns Converted audio data\n */\n static convertAudioFormat(\n audioData: AudioData,\n targetFormat: 'float32' | 'int16'\n ): AudioData {\n if (targetFormat !== 'float32' && targetFormat !== 'int16') {\n throw new Error(`Invalid target format: ${targetFormat}. Must be 'float32' or 'int16'`);\n }\n\n if (targetFormat === 'float32') {\n if (audioData instanceof Float32Array) {\n return audioData;\n }\n // Convert Int16Array to Float32Array\n const result = new Float32Array(audioData.length);\n for (let i = 0; i < audioData.length; i++) {\n result[i] = audioData[i] / 32768.0;\n }\n return result;\n } else {\n if (audioData instanceof Int16Array) {\n return audioData;\n }\n // Convert Float32Array to Int16Array\n const result = new Int16Array(audioData.length);\n for (let i = 0; i < audioData.length; i++) {\n result[i] = Math.max(-32768, Math.min(32767, Math.round(audioData[i] * 32768)));\n }\n return result;\n }\n }\n\n // Validation methods\n private validateMode(mode: WSJTXMode): void {\n if (!Object.values(WSJTXMode).includes(mode)) {\n throw new WSJTXError(`Invalid mode: ${mode}`, 'INVALID_MODE');\n }\n }\n\n private validateFrequency(frequency: number): void {\n if (!Number.isInteger(frequency) || frequency < 0 || frequency > 30000000) {\n throw new WSJTXError(\n `Invalid frequency: ${frequency}. Must be between 0 and 30,000,000 Hz`,\n 'INVALID_FREQUENCY'\n );\n }\n }\n\n private validateThreads(threads: number): void {\n if (!Number.isInteger(threads) || threads < 1 || threads > 16) {\n throw new WSJTXError(\n `Invalid thread count: ${threads}. Must be between 1 and 16`,\n 'INVALID_THREADS'\n );\n }\n }\n\n private validateMessage(message: string): void {\n if (typeof message !== 'string' || message.length === 0 || message.length > 22) {\n throw new WSJTXError(\n `Invalid message: \"${message}\". Must be 1-22 characters long`,\n 'INVALID_MESSAGE'\n );\n }\n }\n\n private validateAudioData(audioData: AudioData): void {\n if (!(audioData instanceof Float32Array) && !(audioData instanceof Int16Array)) {\n throw new WSJTXError(\n 'Invalid audio data: must be Float32Array or Int16Array',\n 'INVALID_AUDIO_DATA'\n );\n }\n if (audioData.length === 0) {\n throw new WSJTXError('Audio data cannot be empty', 'INVALID_AUDIO_DATA');\n }\n }\n\n private validateIQData(iqData: IQData): void {\n if (!(iqData instanceof Float32Array)) {\n throw new WSJTXError(\n 'Invalid IQ data: must be Float32Array with interleaved I,Q samples',\n 'INVALID_IQ_DATA'\n );\n }\n if (iqData.length === 0 || iqData.length % 2 !== 0) {\n throw new WSJTXError(\n 'IQ data length must be even (interleaved I,Q samples)',\n 'INVALID_IQ_DATA'\n );\n }\n }\n}\n\n// Re-export types for convenience\nexport {\n WSJTXMode,\n WSJTXError,\n};\n\nexport type {\n DecodeResult,\n EncodeResult,\n WSPRResult,\n WSPRDecodeOptions,\n WSJTXMessage,\n AudioData,\n IQData,\n WSJTXConfig,\n VersionInfo,\n ModeCapabilities\n};\n","/**\n * WSJTX Digital Radio Protocol Library for Node.js\n * \n * This library provides encoding and decoding capabilities for various\n * digital amateur radio protocols including FT8, FT4, WSPR, and others.\n * \n * The library is a Node.js C++ extension that wraps the wsjtx_lib C library,\n * providing high-performance digital signal processing capabilities with\n * multi-platform support (Windows, macOS, Linux).\n * \n * @version 1.0.0\n * @author WSJTX Development Team\n * @license GPL-3.0\n */\n\n/**\n * Supported WSJTX digital radio modes\n * \n * Each mode has different characteristics in terms of symbol rate,\n * bandwidth, transmission duration, and sensitivity.\n */\nexport enum WSJTXMode {\n /** \n * FT8 - 8-FSK modulation, 15-second transmissions\n * - Sample rate: 48 kHz\n * - Duration: 12.64 seconds\n * - Bandwidth: ~50 Hz\n * - Sensitivity: -24 dB\n */\n FT8 = 0,\n\n /** \n * FT4 - 4-FSK modulation, 6-second transmissions\n * - Sample rate: 48 kHz \n * - Duration: 6.0 seconds\n * - Bandwidth: ~80 Hz\n * - Sensitivity: -17 dB\n */\n FT4 = 1,\n\n /** \n * JT4 - Weak signal mode for microwave EME\n * - Sample rate: 11.025 kHz\n * - Duration: 47.1 seconds\n * - Multiple bandwidth options\n */\n JT4 = 2,\n\n /** \n * JT65 - Popular EME and HF weak signal mode\n * - Sample rate: 11.025 kHz\n * - Duration: 46.8 seconds\n * - Bandwidth: ~180 Hz\n */\n JT65 = 3,\n\n /** \n * JT9 - Low data rate, narrow bandwidth mode\n * - Sample rate: 12 kHz\n * - Duration: 49.0 seconds\n * - Bandwidth: ~16 Hz\n */\n JT9 = 4,\n\n /** \n * FST4 - Flexible format for 15-900 second transmissions\n * - Sample rate: 12 kHz\n * - Variable duration (15s, 30s, 60s, 120s, 300s, 900s)\n * - Ultra-weak signal capability\n */\n FST4 = 5,\n\n /** \n * Q65 - Optimized for EME on VHF and higher\n * - Sample rate: 12 kHz\n * - Duration: 60 seconds\n * - Multiple bandwidth options\n */\n Q65 = 6,\n\n /** \n * FST4W - Weak signal beacons\n * - Sample rate: 12 kHz\n * - Duration: 120 seconds\n * - Optimized for propagation studies\n */\n FST4W = 7,\n\n /** \n * WSPR - Weak Signal Propagation Reporter\n * - Sample rate: 12 kHz\n * - Duration: 110.6 seconds\n * - 4-FSK modulation, very weak signal capability\n */\n WSPR = 8\n}\n\n/**\n * Audio data formats supported by the library\n * Can be either 32-bit floating point or 16-bit signed integer samples\n */\nexport type AudioData = Float32Array | Int16Array;\n\n/**\n * IQ (In-phase/Quadrature) data for WSPR decoding\n * Interleaved I,Q samples as 32-bit floating point values\n */\nexport type IQData = Float32Array;\n\n/**\n * Time information for decoded messages\n */\nexport interface WSJTXTime {\n /** Hour (0-23) */\n hour: number;\n /** Minute (0-59) */\n minute: number;\n /** Second (0-59) */\n second: number;\n}\n\n/**\n * A decoded WSJTX message containing timing and signal information\n */\nexport interface WSJTXMessage {\n /** The decoded message text */\n text: string;\n /** Signal-to-noise ratio in dB */\n snr: number;\n /** Time offset from start of transmission period in seconds */\n deltaTime: number;\n /** Frequency offset from dial frequency in Hz */\n deltaFrequency: number;\n /** Unix timestamp when the message was decoded */\n timestamp: number;\n /** Sync quality metric (mode-dependent) */\n sync: number;\n}\n\n/**\n * Result from a decode operation\n */\nexport interface DecodeResult {\n /** Whether the decode operation completed successfully */\n success: boolean;\n /** Optional error message if decode failed */\n error?: string;\n}\n\n/**\n * Result from an encode operation\n */\nexport interface EncodeResult {\n /** Generated audio waveform data */\n audioData: Float32Array;\n /** The actual message that was encoded (may differ from input) */\n messageSent: string;\n}\n\n/**\n * Single WSPR decode result\n */\nexport interface WSPRResult {\n /** Frequency of the decoded signal in Hz */\n frequency: number;\n /** Sync quality metric */\n sync: number;\n /** Signal-to-noise ratio in dB */\n snr: number;\n /** Time offset in seconds */\n deltaTime: number;\n /** Frequency drift in Hz/minute */\n drift: number;\n /** Jitter metric */\n jitter: number;\n /** Decoded message text */\n message: string;\n /** Decoded callsign */\n callsign: string;\n /** Decoded grid locator */\n locator: string;\n /** Decoded power in dBm */\n power: string;\n /** Number of decode cycles */\n cycles: number;\n}\n\n/**\n * Options for WSPR decoding\n */\nexport interface WSPRDecodeOptions {\n /** Dial frequency in Hz (default: 14095600 for 20m WSPR) */\n dialFrequency?: number;\n /** Receiving station callsign for better decoding */\n callsign?: string;\n /** Receiving station grid locator */\n locator?: string;\n /** Enable quick decode mode (faster but less sensitive) */\n quickMode?: boolean;\n /** Use hash table for callsign/locator lookup */\n useHashTable?: boolean;\n /** Number of decoding passes (1-3, default: 2) */\n passes?: number;\n /** Enable signal subtraction for better weak signal decoding */\n subtraction?: boolean;\n}\n\n/**\n * Error thrown by WSJTX library operations\n */\nexport class WSJTXError extends Error {\n constructor(message: string, public code?: string) {\n super(message);\n this.name = 'WSJTXError';\n }\n}\n\n/**\n * Configuration options for the WSJTX library\n */\nexport interface WSJTXConfig {\n /** Maximum number of threads to use for processing (1-16) */\n maxThreads?: number;\n /** Enable debug logging */\n debug?: boolean;\n}\n\n/**\n * Library version information\n */\nexport interface VersionInfo {\n /** WSJTXLib wrapper version */\n wrapperVersion: string;\n /** Underlying wsjtx_lib version */\n libraryVersion: string;\n /** Node.js version used to build */\n nodeVersion: string;\n /** Build timestamp */\n buildDate: string;\n}\n\n/**\n * Mode capabilities information\n */\nexport interface ModeCapabilities {\n /** Mode identifier */\n mode: WSJTXMode;\n /** Whether encoding is supported */\n encodingSupported: boolean;\n /** Whether decoding is supported */\n decodingSupported: boolean;\n /** Required sample rate in Hz */\n sampleRate: number;\n /** Transmission duration in seconds */\n duration: number;\n /** Typical bandwidth in Hz */\n bandwidth?: number;\n /** Typical sensitivity in dB */\n sensitivity?: number;\n}\n\n/**\n * Callback function for decode operations\n * The native module returns a boolean indicating completion status\n */\nexport type DecodeCallback = (error: Error | null, result: boolean) => void;\n\n/**\n * Callback function type for asynchronous encode operations\n */\nexport type EncodeCallback = (error: Error | null, result: EncodeResult) => void;\n\n/**\n * Callback function type for asynchronous WSPR decode operations\n */\nexport type WSPRDecodeCallback = (error: Error | null, results: WSPRResult[]) => void;\n "],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACqBO,IAAK,YAAL,kBAAKA,eAAL;AAQH,EAAAA,sBAAA,SAAM,KAAN;AASA,EAAAA,sBAAA,SAAM,KAAN;AAQA,EAAAA,sBAAA,SAAM,KAAN;AAQA,EAAAA,sBAAA,UAAO,KAAP;AAQA,EAAAA,sBAAA,SAAM,KAAN;AAQA,EAAAA,sBAAA,UAAO,KAAP;AAQA,EAAAA,sBAAA,SAAM,KAAN;AAQA,EAAAA,sBAAA,WAAQ,KAAR;AAQA,EAAAA,sBAAA,UAAO,KAAP;AAzEQ,SAAAA;AAAA,GAAA;AA6LL,IAAM,aAAN,cAAyB,MAAM;AAAA,EAClC,YAAY,SAAwB,MAAe;AAC/C,UAAM,OAAO;AADmB;AAEhC,SAAK,OAAO;AAAA,EAChB;AACJ;;;AD9KA,yBAA8B;AAC9B,sBAA8B;AAC9B,uBAAiB;AACjB,qBAAe;AA5Cf;AAsDA,SAAS,mBAAkC;AACzC,MAAI;AAEF,QAAI,OAAO,gBAAgB,eAAe,YAAY,KAAK;AACzD,aAAO;AAAA,QACL,aAAS,kCAAc,YAAY,GAAG;AAAA,QACtC,gBAAY,+BAAc,YAAY,GAAG;AAAA,QACzC,WAAW,iBAAAC,QAAK,YAAQ,+BAAc,YAAY,GAAG,CAAC;AAAA,MACxD;AAAA,IACF;AAAA,EACF,QAAQ;AAAA,EAER;AAIA,SAAO;AAAA,IACL,SAAW,OAAOC,aAAY,cAAeA,eAAU,kCAAc,SAAS;AAAA,IAC9E,YAAa,OAAO,eAAe,cAAe,aAAa;AAAA,IAC/D,WAAY,OAAO,cAAc,cAAe,YAAY;AAAA,EAC9D;AACF;AAEA,IAAM,gBAA+B,iBAAiB;AACtD,IAAM,EAAE,SAAAA,UAAS,YAAY,UAAU,IAAI;AAO3C,SAAS,mBAA2B;AAClC,QAAM,WAAW,QAAQ;AACzB,QAAM,OAAO,QAAQ;AAGrB,QAAM,mBAAmB,CAAC,CAAE,QAAgB,OAAO,UAAU,SAAS,YAAY,KAAK,UAAU,SAAS,cAAc;AAExH,MAAI,kBAAkB;AACpB,YAAQ,IAAI,mCAAmC;AAG/C,UAAM,UAAU,iBAAAD,QAAK,QAAQ,QAAQ,QAAQ;AAE7C,UAAM,WAAW;AAAA;AAAA,MAEf,iBAAAA,QAAK,KAAK,SAAS,uBAAuB;AAAA,MAC1C,iBAAAA,QAAK,KAAK,SAAS,oBAAoB,QAAQ,IAAI,IAAI,OAAO;AAAA;AAAA,MAG9D,iBAAAA,QAAK,KAAK,SAAS,aAAa,GAAG,QAAQ,IAAI,IAAI,IAAI,uBAAuB;AAAA;AAAA,MAG9E,iBAAAA,QAAK,KAAK,SAAS,MAAM,aAAa,GAAG,QAAQ,IAAI,IAAI,IAAI,uBAAuB;AAAA,MACpF,iBAAAA,QAAK,KAAK,SAAS,OAAO,uBAAuB;AAAA,MACjD,iBAAAA,QAAK,KAAK,SAAS,UAAU,uBAAuB;AAAA,IACtD;AAEA,YAAQ,IAAI,gDAAgD;AAC5D,aAAS,QAAQ,OAAK,QAAQ,IAAI,OAAO,CAAC,EAAE,CAAC;AAE7C,eAAW,cAAc,UAAU;AACjC,UAAI,eAAAE,QAAG,WAAW,UAAU,GAAG;AAC7B,gBAAQ,IAAI,2BAA2B,UAAU,EAAE;AACnD,eAAO;AAAA,MACT;AAAA,IACF;AAGA,UAAMC,YAAW,SAAS,IAAI,OAAK,OAAO,CAAC,EAAE,EAAE,KAAK,IAAI;AACxD,UAAM,IAAI;AAAA,MACR,2DAA2D,QAAQ,IAAI,IAAI;AAAA;AAAA,EAC1DA,SAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAK3B;AAAA,EACF;AAIA,QAAM,aAAa,iBAAAH,QAAK,QAAQ,WAAW,IAAI;AAE/C,QAAM,gBAAgB;AAAA;AAAA,IAEpB,iBAAAA,QAAK,KAAK,YAAY,aAAa,GAAG,QAAQ,IAAI,IAAI,IAAI,uBAAuB;AAAA;AAAA,IAGjF,iBAAAA,QAAK,KAAK,YAAY,aAAa,GAAG,QAAQ,WAAW,IAAI,IAAI,uBAAuB;AAAA,IACxF,iBAAAA,QAAK,KAAK,YAAY,aAAa,iBAAiB,IAAI,IAAI,uBAAuB;AAAA;AAAA,IACnF,iBAAAA,QAAK,KAAK,YAAY,aAAa,gBAAgB,IAAI,IAAI,uBAAuB;AAAA;AAAA,IAClF,iBAAAA,QAAK,KAAK,YAAY,aAAa,kBAAkB,IAAI,IAAI,uBAAuB;AAAA;AAAA;AAAA,IAGpF,iBAAAA,QAAK,KAAK,YAAY,SAAS,uBAAuB;AAAA,IACtD,iBAAAA,QAAK,KAAK,YAAY,SAAS,WAAW,uBAAuB;AAAA,EACnE;AAGA,UAAQ,IAAI,mDAAmD;AAC/D,gBAAc,QAAQ,OAAK,QAAQ,IAAI,OAAO,CAAC,EAAE,CAAC;AAElD,aAAW,cAAc,eAAe;AACtC,QAAI,eAAAE,QAAG,WAAW,UAAU,GAAG;AAC7B,cAAQ,IAAI,2BAA2B,UAAU,EAAE;AACnD,aAAO;AAAA,IACT;AAAA,EACF;AAGA,QAAM,WAAW,cAAc,IAAI,OAAK,OAAO,CAAC,EAAE,EAAE,KAAK,IAAI;AAC7D,QAAM,IAAI;AAAA,IACR,+BAA+B,QAAQ,IAAI,IAAI;AAAA;AAAA,EAC9B,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAK3B;AACF;AAEA,IAAM,mBAAmB,iBAAiB;AAI1C,IAAM,EAAE,UAAU,eAAe,IAAID,SAAQ,gBAAgB;AAStD,IAAM,WAAN,MAAe;AAAA,EACZ;AAAA,EACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQR,YAAY,SAAsB,CAAC,GAAG;AACpC,SAAK,SAAS;AAAA,MACZ,YAAY;AAAA,MACZ,OAAO;AAAA,MACP,GAAG;AAAA,IACL;AAEA,QAAI;AACF,WAAK,SAAS,IAAI,eAAe;AAAA,IACnC,SAAS,OAAO;AACd,YAAM,IAAI;AAAA,QACR,uCAAuC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,QAC7F;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAwBA,MAAM,OACJ,MACA,WACA,WACA,UAAkB,KAAK,OAAO,cAAc,GACrB;AACvB,SAAK,aAAa,IAAI;AACtB,SAAK,kBAAkB,SAAS;AAChC,SAAK,gBAAgB,OAAO;AAC5B,SAAK,kBAAkB,SAAS;AAEhC,QAAI,CAAC,KAAK,oBAAoB,IAAI,GAAG;AACnC,YAAM,IAAI,WAAW,oCAAoC,UAAU,IAAI,CAAC,IAAI,kBAAkB;AAAA,IAChG;AAEA,WAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,YAAM,WAA2B,CAAC,OAAO,WAAW;AAClD,YAAI,OAAO;AACT,iBAAO,IAAI,WAAW,MAAM,SAAS,cAAc,CAAC;AAAA,QACtD,OAAO;AAEL,kBAAQ,EAAE,SAAS,OAAkB,CAAC;AAAA,QACxC;AAAA,MACF;AAEA,UAAI;AACF,aAAK,OAAO,OAAO,MAAM,WAAW,WAAW,SAAS,QAAQ;AAAA,MAClE,SAAS,OAAO;AACd,eAAO,IAAI;AAAA,UACT,4BAA4B,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,UAClF;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAwBA,MAAM,OACJ,MACA,SACA,WACA,UAAkB,KAAK,OAAO,cAAc,GACrB;AACvB,SAAK,aAAa,IAAI;AACtB,SAAK,gBAAgB,OAAO;AAC5B,SAAK,kBAAkB,SAAS;AAChC,SAAK,gBAAgB,OAAO;AAE5B,QAAI,CAAC,KAAK,oBAAoB,IAAI,GAAG;AACnC,YAAM,IAAI,WAAW,oCAAoC,UAAU,IAAI,CAAC,IAAI,kBAAkB;AAAA,IAChG;AAEA,WAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,YAAM,WAA2B,CAAC,OAAO,WAAW;AAClD,YAAI,OAAO;AACT,iBAAO,IAAI,WAAW,MAAM,SAAS,cAAc,CAAC;AAAA,QACtD,OAAO;AACL,kBAAQ,MAAM;AAAA,QAChB;AAAA,MACF;AAEA,UAAI;AACF,aAAK,OAAO,OAAO,MAAM,SAAS,WAAW,SAAS,QAAQ;AAAA,MAChE,SAAS,OAAO;AACd,eAAO,IAAI;AAAA,UACT,4BAA4B,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,UAClF;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA0BA,MAAM,WACJ,QACA,UAA6B,CAAC,GACP;AACvB,SAAK,eAAe,MAAM;AAE1B,UAAM,iBAA8C;AAAA,MAClD,eAAe;AAAA;AAAA,MACf,UAAU;AAAA,MACV,SAAS;AAAA,MACT,WAAW;AAAA,MACX,cAAc;AAAA,MACd,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,GAAG;AAAA,IACL;AAEA,WAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,YAAM,WAA+B,CAAC,OAAO,YAAY;AACvD,YAAI,OAAO;AACT,iBAAO,IAAI,WAAW,MAAM,SAAS,mBAAmB,CAAC;AAAA,QAC3D,OAAO;AACL,kBAAQ,OAAO;AAAA,QACjB;AAAA,MACF;AAEA,UAAI;AACF,aAAK,OAAO,WAAW,QAAQ,gBAAgB,QAAQ;AAAA,MACzD,SAAS,OAAO;AACd,eAAO,IAAI;AAAA,UACT,uBAAuB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,UAC7E;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkBA,eAA+B;AAC7B,QAAI;AACF,aAAO,KAAK,OAAO,aAAa;AAAA,IAClC,SAAS,OAAO;AACd,YAAM,IAAI;AAAA,QACR,4BAA4B,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,QAClF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,oBAAoB,MAA0B;AAC5C,WAAO,KAAK,OAAO,oBAAoB,IAAI;AAAA,EAC7C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,oBAAoB,MAA0B;AAC5C,WAAO,KAAK,OAAO,oBAAoB,IAAI;AAAA,EAC7C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,cAAc,MAAyB;AACrC,WAAO,KAAK,OAAO,cAAc,IAAI;AAAA,EACvC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,wBAAwB,MAAyB;AAC/C,WAAO,KAAK,OAAO,wBAAwB,IAAI;AAAA,EACjD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,yBAA6C;AAC3C,UAAM,QAAQ,OAAO,OAAO,SAAS,EAAE,OAAO,OAAK,OAAO,MAAM,QAAQ;AAExE,WAAO,MAAM,IAAI,WAAS;AAAA,MACxB;AAAA,MACA,mBAAmB,KAAK,oBAAoB,IAAI;AAAA,MAChD,mBAAmB,KAAK,oBAAoB,IAAI;AAAA,MAChD,YAAY,KAAK,cAAc,IAAI;AAAA,MACnC,UAAU,KAAK,wBAAwB,IAAI;AAAA,IAC7C,EAAE;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,OAAO,mBACL,WACA,cACW;AACX,QAAI,iBAAiB,aAAa,iBAAiB,SAAS;AAC1D,YAAM,IAAI,MAAM,0BAA0B,YAAY,gCAAgC;AAAA,IACxF;AAEA,QAAI,iBAAiB,WAAW;AAC9B,UAAI,qBAAqB,cAAc;AACrC,eAAO;AAAA,MACT;AAEA,YAAM,SAAS,IAAI,aAAa,UAAU,MAAM;AAChD,eAAS,IAAI,GAAG,IAAI,UAAU,QAAQ,KAAK;AACzC,eAAO,CAAC,IAAI,UAAU,CAAC,IAAI;AAAA,MAC7B;AACA,aAAO;AAAA,IACT,OAAO;AACL,UAAI,qBAAqB,YAAY;AACnC,eAAO;AAAA,MACT;AAEA,YAAM,SAAS,IAAI,WAAW,UAAU,MAAM;AAC9C,eAAS,IAAI,GAAG,IAAI,UAAU,QAAQ,KAAK;AACzC,eAAO,CAAC,IAAI,KAAK,IAAI,QAAQ,KAAK,IAAI,OAAO,KAAK,MAAM,UAAU,CAAC,IAAI,KAAK,CAAC,CAAC;AAAA,MAChF;AACA,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA,EAGQ,aAAa,MAAuB;AAC1C,QAAI,CAAC,OAAO,OAAO,SAAS,EAAE,SAAS,IAAI,GAAG;AAC5C,YAAM,IAAI,WAAW,iBAAiB,IAAI,IAAI,cAAc;AAAA,IAC9D;AAAA,EACF;AAAA,EAEQ,kBAAkB,WAAyB;AACjD,QAAI,CAAC,OAAO,UAAU,SAAS,KAAK,YAAY,KAAK,YAAY,KAAU;AACzE,YAAM,IAAI;AAAA,QACR,sBAAsB,SAAS;AAAA,QAC/B;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,gBAAgB,SAAuB;AAC7C,QAAI,CAAC,OAAO,UAAU,OAAO,KAAK,UAAU,KAAK,UAAU,IAAI;AAC7D,YAAM,IAAI;AAAA,QACR,yBAAyB,OAAO;AAAA,QAChC;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,gBAAgB,SAAuB;AAC7C,QAAI,OAAO,YAAY,YAAY,QAAQ,WAAW,KAAK,QAAQ,SAAS,IAAI;AAC9E,YAAM,IAAI;AAAA,QACR,qBAAqB,OAAO;AAAA,QAC5B;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,kBAAkB,WAA4B;AACpD,QAAI,EAAE,qBAAqB,iBAAiB,EAAE,qBAAqB,aAAa;AAC9E,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,MACF;AAAA,IACF;AACA,QAAI,UAAU,WAAW,GAAG;AAC1B,YAAM,IAAI,WAAW,8BAA8B,oBAAoB;AAAA,IACzE;AAAA,EACF;AAAA,EAEQ,eAAe,QAAsB;AAC3C,QAAI,EAAE,kBAAkB,eAAe;AACrC,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,MACF;AAAA,IACF;AACA,QAAI,OAAO,WAAW,KAAK,OAAO,SAAS,MAAM,GAAG;AAClD,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;","names":["WSJTXMode","path","require","fs","pathList"]}