dspx 0.1.1-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (172) hide show
  1. package/.github/workflows/ci.yml +185 -0
  2. package/.vscode/c_cpp_properties.json +17 -0
  3. package/.vscode/settings.json +68 -0
  4. package/.vscode/tasks.json +28 -0
  5. package/DISCLAIMER.md +32 -0
  6. package/LICENSE +21 -0
  7. package/README.md +1803 -0
  8. package/ROADMAP.md +192 -0
  9. package/TECHNICAL_DEBT.md +165 -0
  10. package/binding.gyp +65 -0
  11. package/docs/ADVANCED_LOGGER_FEATURES.md +598 -0
  12. package/docs/AUTHENTICATION_SECURITY.md +396 -0
  13. package/docs/BACKEND_IMPROVEMENTS.md +399 -0
  14. package/docs/CHEBYSHEV_BIQUAD_EQ_IMPLEMENTATION.md +405 -0
  15. package/docs/FFT_IMPLEMENTATION.md +490 -0
  16. package/docs/FFT_IMPROVEMENTS_SUMMARY.md +387 -0
  17. package/docs/FFT_USER_GUIDE.md +494 -0
  18. package/docs/FILTERS_IMPLEMENTATION.md +260 -0
  19. package/docs/FILTER_API_GUIDE.md +418 -0
  20. package/docs/FIR_SIMD_OPTIMIZATION.md +175 -0
  21. package/docs/LOGGER_API_REFERENCE.md +350 -0
  22. package/docs/NOTCH_FILTER_QUICK_REF.md +121 -0
  23. package/docs/PHASE2_TESTS_AND_NOTCH_FILTER.md +341 -0
  24. package/docs/PHASES_5_7_SUMMARY.md +403 -0
  25. package/docs/PIPELINE_FILTER_INTEGRATION.md +446 -0
  26. package/docs/SIMD_OPTIMIZATIONS.md +211 -0
  27. package/docs/TEST_MIGRATION_SUMMARY.md +173 -0
  28. package/docs/TIMESERIES_IMPLEMENTATION_SUMMARY.md +322 -0
  29. package/docs/TIMESERIES_QUICK_REF.md +85 -0
  30. package/docs/advanced.md +559 -0
  31. package/docs/time-series-guide.md +617 -0
  32. package/docs/time-series-migration.md +376 -0
  33. package/jest.config.js +37 -0
  34. package/package.json +42 -0
  35. package/prebuilds/linux-x64/dsp-ts-redis.node +0 -0
  36. package/prebuilds/win32-x64/dsp-ts-redis.node +0 -0
  37. package/scripts/test.js +24 -0
  38. package/src/build/dsp-ts-redis.node +0 -0
  39. package/src/native/DspPipeline.cc +675 -0
  40. package/src/native/DspPipeline.h +44 -0
  41. package/src/native/FftBindings.cc +817 -0
  42. package/src/native/FilterBindings.cc +1001 -0
  43. package/src/native/IDspStage.h +53 -0
  44. package/src/native/adapters/InterpolatorStage.h +201 -0
  45. package/src/native/adapters/MeanAbsoluteValueStage.h +289 -0
  46. package/src/native/adapters/MovingAverageStage.h +306 -0
  47. package/src/native/adapters/RectifyStage.h +88 -0
  48. package/src/native/adapters/ResamplerStage.h +238 -0
  49. package/src/native/adapters/RmsStage.h +299 -0
  50. package/src/native/adapters/SscStage.h +121 -0
  51. package/src/native/adapters/VarianceStage.h +307 -0
  52. package/src/native/adapters/WampStage.h +114 -0
  53. package/src/native/adapters/WaveformLengthStage.h +115 -0
  54. package/src/native/adapters/ZScoreNormalizeStage.h +326 -0
  55. package/src/native/core/FftEngine.cc +441 -0
  56. package/src/native/core/FftEngine.h +224 -0
  57. package/src/native/core/FirFilter.cc +324 -0
  58. package/src/native/core/FirFilter.h +149 -0
  59. package/src/native/core/IirFilter.cc +576 -0
  60. package/src/native/core/IirFilter.h +210 -0
  61. package/src/native/core/MovingAbsoluteValueFilter.cc +17 -0
  62. package/src/native/core/MovingAbsoluteValueFilter.h +135 -0
  63. package/src/native/core/MovingAverageFilter.cc +18 -0
  64. package/src/native/core/MovingAverageFilter.h +135 -0
  65. package/src/native/core/MovingFftFilter.cc +291 -0
  66. package/src/native/core/MovingFftFilter.h +203 -0
  67. package/src/native/core/MovingVarianceFilter.cc +194 -0
  68. package/src/native/core/MovingVarianceFilter.h +114 -0
  69. package/src/native/core/MovingZScoreFilter.cc +215 -0
  70. package/src/native/core/MovingZScoreFilter.h +113 -0
  71. package/src/native/core/Policies.h +352 -0
  72. package/src/native/core/RmsFilter.cc +18 -0
  73. package/src/native/core/RmsFilter.h +131 -0
  74. package/src/native/core/SscFilter.cc +16 -0
  75. package/src/native/core/SscFilter.h +137 -0
  76. package/src/native/core/WampFilter.cc +16 -0
  77. package/src/native/core/WampFilter.h +101 -0
  78. package/src/native/core/WaveformLengthFilter.cc +17 -0
  79. package/src/native/core/WaveformLengthFilter.h +98 -0
  80. package/src/native/utils/CircularBufferArray.cc +336 -0
  81. package/src/native/utils/CircularBufferArray.h +62 -0
  82. package/src/native/utils/CircularBufferVector.cc +145 -0
  83. package/src/native/utils/CircularBufferVector.h +45 -0
  84. package/src/native/utils/NapiUtils.cc +53 -0
  85. package/src/native/utils/NapiUtils.h +21 -0
  86. package/src/native/utils/SimdOps.h +870 -0
  87. package/src/native/utils/SlidingWindowFilter.cc +239 -0
  88. package/src/native/utils/SlidingWindowFilter.h +159 -0
  89. package/src/native/utils/TimeSeriesBuffer.cc +205 -0
  90. package/src/native/utils/TimeSeriesBuffer.h +140 -0
  91. package/src/ts/CircularLogBuffer.ts +87 -0
  92. package/src/ts/DriftDetector.ts +331 -0
  93. package/src/ts/TopicRouter.ts +428 -0
  94. package/src/ts/__tests__/AdvancedDsp.test.ts +585 -0
  95. package/src/ts/__tests__/AuthAndEdgeCases.test.ts +241 -0
  96. package/src/ts/__tests__/Chaining.test.ts +387 -0
  97. package/src/ts/__tests__/ChebyshevBiquad.test.ts +229 -0
  98. package/src/ts/__tests__/CircularLogBuffer.test.ts +158 -0
  99. package/src/ts/__tests__/DriftDetector.test.ts +389 -0
  100. package/src/ts/__tests__/Fft.test.ts +484 -0
  101. package/src/ts/__tests__/ListState.test.ts +153 -0
  102. package/src/ts/__tests__/Logger.test.ts +208 -0
  103. package/src/ts/__tests__/LoggerAdvanced.test.ts +319 -0
  104. package/src/ts/__tests__/LoggerMinor.test.ts +247 -0
  105. package/src/ts/__tests__/MeanAbsoluteValue.test.ts +398 -0
  106. package/src/ts/__tests__/MovingAverage.test.ts +322 -0
  107. package/src/ts/__tests__/RMS.test.ts +315 -0
  108. package/src/ts/__tests__/Rectify.test.ts +272 -0
  109. package/src/ts/__tests__/Redis.test.ts +456 -0
  110. package/src/ts/__tests__/SlopeSignChange.test.ts +166 -0
  111. package/src/ts/__tests__/Tap.test.ts +164 -0
  112. package/src/ts/__tests__/TimeBasedExpiration.test.ts +124 -0
  113. package/src/ts/__tests__/TimeBasedRmsAndMav.test.ts +231 -0
  114. package/src/ts/__tests__/TimeBasedVarianceAndZScore.test.ts +284 -0
  115. package/src/ts/__tests__/TimeSeries.test.ts +254 -0
  116. package/src/ts/__tests__/TopicRouter.test.ts +332 -0
  117. package/src/ts/__tests__/TopicRouterAdvanced.test.ts +483 -0
  118. package/src/ts/__tests__/TopicRouterPriority.test.ts +487 -0
  119. package/src/ts/__tests__/Variance.test.ts +509 -0
  120. package/src/ts/__tests__/WaveformLength.test.ts +147 -0
  121. package/src/ts/__tests__/WillisonAmplitude.test.ts +197 -0
  122. package/src/ts/__tests__/ZScoreNormalize.test.ts +459 -0
  123. package/src/ts/advanced-dsp.ts +566 -0
  124. package/src/ts/backends.ts +1137 -0
  125. package/src/ts/bindings.ts +1225 -0
  126. package/src/ts/easter-egg.ts +42 -0
  127. package/src/ts/examples/MeanAbsoluteValue/test-state.ts +99 -0
  128. package/src/ts/examples/MeanAbsoluteValue/test-streaming.ts +269 -0
  129. package/src/ts/examples/MovingAverage/test-state.ts +85 -0
  130. package/src/ts/examples/MovingAverage/test-streaming.ts +188 -0
  131. package/src/ts/examples/RMS/test-state.ts +97 -0
  132. package/src/ts/examples/RMS/test-streaming.ts +253 -0
  133. package/src/ts/examples/Rectify/test-state.ts +107 -0
  134. package/src/ts/examples/Rectify/test-streaming.ts +242 -0
  135. package/src/ts/examples/Variance/test-state.ts +195 -0
  136. package/src/ts/examples/Variance/test-streaming.ts +260 -0
  137. package/src/ts/examples/ZScoreNormalize/test-state.ts +277 -0
  138. package/src/ts/examples/ZScoreNormalize/test-streaming.ts +306 -0
  139. package/src/ts/examples/advanced-dsp-examples.ts +397 -0
  140. package/src/ts/examples/callbacks/advanced-router-features.ts +326 -0
  141. package/src/ts/examples/callbacks/benchmark-circular-buffer.ts +109 -0
  142. package/src/ts/examples/callbacks/monitoring-example.ts +265 -0
  143. package/src/ts/examples/callbacks/pipeline-callbacks-example.ts +137 -0
  144. package/src/ts/examples/callbacks/pooled-callbacks-example.ts +274 -0
  145. package/src/ts/examples/callbacks/priority-routing-example.ts +277 -0
  146. package/src/ts/examples/callbacks/production-topic-router.ts +214 -0
  147. package/src/ts/examples/callbacks/topic-based-logging.ts +161 -0
  148. package/src/ts/examples/chaining/test-chaining-redis.ts +113 -0
  149. package/src/ts/examples/chaining/test-chaining.ts +52 -0
  150. package/src/ts/examples/emg-features-example.ts +284 -0
  151. package/src/ts/examples/fft-example.ts +309 -0
  152. package/src/ts/examples/fft-examples.ts +349 -0
  153. package/src/ts/examples/filter-examples.ts +320 -0
  154. package/src/ts/examples/list-state-example.ts +131 -0
  155. package/src/ts/examples/logger-example.ts +91 -0
  156. package/src/ts/examples/notch-filter-examples.ts +243 -0
  157. package/src/ts/examples/phase5/drift-detection-example.ts +290 -0
  158. package/src/ts/examples/phase6-7/production-observability.ts +476 -0
  159. package/src/ts/examples/phase6-7/redis-timeseries-integration.ts +446 -0
  160. package/src/ts/examples/redis/redis-example.ts +202 -0
  161. package/src/ts/examples/redis-example.ts +202 -0
  162. package/src/ts/examples/simd-benchmark.ts +126 -0
  163. package/src/ts/examples/tap-debugging.ts +230 -0
  164. package/src/ts/examples/timeseries/comparison-example.ts +290 -0
  165. package/src/ts/examples/timeseries/iot-sensor-example.ts +143 -0
  166. package/src/ts/examples/timeseries/redis-streaming-example.ts +233 -0
  167. package/src/ts/examples/waveform-length-example.ts +139 -0
  168. package/src/ts/fft.ts +722 -0
  169. package/src/ts/filters.ts +1078 -0
  170. package/src/ts/index.ts +120 -0
  171. package/src/ts/types.ts +589 -0
  172. package/tsconfig.json +15 -0
@@ -0,0 +1,120 @@
1
+ // Export the main API
2
+ export { createDspPipeline, DspProcessor } from "./bindings";
3
+ export {
4
+ TopicRouter,
5
+ TopicRouterBuilder,
6
+ createTopicRouter,
7
+ } from "./TopicRouter";
8
+ export {
9
+ createPagerDutyHandler,
10
+ createPrometheusHandler,
11
+ createLokiHandler,
12
+ createCloudWatchHandler,
13
+ createDatadogHandler,
14
+ createConsoleHandler,
15
+ createMockHandler,
16
+ Logger,
17
+ JSONFormatter,
18
+ TextFormatter,
19
+ SEVERITY_MAPPINGS,
20
+ tracingContext,
21
+ getTracingContext,
22
+ withTracingContext,
23
+ generateTraceparent,
24
+ type Formatter,
25
+ type SeverityMapping,
26
+ type HandlerWithFlush,
27
+ type LoggerMetrics,
28
+ type SamplingConfig,
29
+ type LoggerOptions,
30
+ } from "./backends";
31
+ export {
32
+ DriftDetector,
33
+ detectGaps,
34
+ validateMonotonicity,
35
+ estimateSampleRate,
36
+ } from "./DriftDetector";
37
+ export {
38
+ FftProcessor,
39
+ MovingFftProcessor,
40
+ FftUtils,
41
+ type ComplexArray,
42
+ type WindowType,
43
+ type FftMode,
44
+ } from "./fft";
45
+ export {
46
+ FirFilter,
47
+ IirFilter,
48
+ type FilterType,
49
+ type FilterMode,
50
+ type FilterOptions,
51
+ type FirFilterOptions,
52
+ type IirFilterOptions,
53
+ type ButterworthFilterOptions,
54
+ type ChebyshevFilterOptions,
55
+ type BiquadFilterOptions,
56
+ } from "./filters";
57
+ export {
58
+ calculateHjorthParameters,
59
+ calculateSpectralCentroid,
60
+ calculateSpectralRolloff,
61
+ calculateSpectralFlux,
62
+ calculateSpectralFeatures,
63
+ calculateShannonEntropy,
64
+ calculateSampleEntropy,
65
+ calculateApproximateEntropy,
66
+ HjorthTracker,
67
+ SpectralFeaturesTracker,
68
+ EntropyTracker,
69
+ } from "./advanced-dsp";
70
+ export { egg } from "./easter-egg";
71
+ export type {
72
+ DriftStatistics,
73
+ DriftDetectorOptions,
74
+ TimingMetrics,
75
+ GapDetection,
76
+ MonotonicityViolation,
77
+ SampleRateEstimate,
78
+ } from "./DriftDetector";
79
+ export type {
80
+ ProcessOptions,
81
+ MovingAverageParams,
82
+ RedisConfig,
83
+ RmsParams,
84
+ RectifyParams,
85
+ VarianceParams,
86
+ ZScoreNormalizeParams,
87
+ MeanAbsoluteValueParams,
88
+
89
+ // logging and monitoring interfaces
90
+ PipelineCallbacks,
91
+ LogLevel,
92
+ LogContext,
93
+ LogEntry,
94
+ LogTopic,
95
+ LogPriority,
96
+ SampleBatch,
97
+ TapCallback,
98
+ PipelineStateSummary,
99
+ StageSummary,
100
+
101
+ // Advanced DSP types
102
+ HjorthParameters,
103
+ HjorthParams,
104
+ SpectralFeatures,
105
+ SpectralFeaturesParams,
106
+ EntropyParams,
107
+ SampleEntropyParams,
108
+ ApproximateEntropyParams,
109
+ DecimateParams,
110
+ InterpolateParams,
111
+ ResampleParams,
112
+ } from "./types";
113
+ export type {
114
+ RouteHandler,
115
+ Route,
116
+ RouteOptions,
117
+ RouteMetrics,
118
+ PatternMatcher,
119
+ } from "./TopicRouter";
120
+ export type { BackendConfig } from "./backends";
@@ -0,0 +1,589 @@
1
+ /**
2
+ * Drift statistics for timing diagnostics
3
+ */
4
+ export interface DriftStatistics {
5
+ deltaMs: number;
6
+ expectedMs: number;
7
+ absoluteDrift: number;
8
+ relativeDrift: number;
9
+ sampleIndex: number;
10
+ currentTimestamp: number;
11
+ previousTimestamp: number;
12
+ }
13
+
14
+ /**
15
+ * Options for processing data
16
+ *
17
+ * Two modes supported:
18
+ * 1. Sample-based (legacy): Provide sampleRate, assumes fixed intervals
19
+ * 2. Time-based (new): Omit sampleRate, timestamps are explicit or auto-generated
20
+ */
21
+ export interface ProcessOptions {
22
+ /**
23
+ * Sample rate in Hz (legacy mode)
24
+ * If provided, assumes fixed time intervals between samples
25
+ * If omitted, uses explicit timestamps (time-based mode)
26
+ */
27
+ sampleRate?: number;
28
+
29
+ /**
30
+ * Number of channels in the signal (default: 1)
31
+ */
32
+ channels?: number;
33
+
34
+ /**
35
+ * Enable drift detection for timing diagnostics (default: false)
36
+ * Only works with explicit timestamps
37
+ */
38
+ enableDriftDetection?: boolean;
39
+
40
+ /**
41
+ * Drift threshold percentage (0-100, default: 10%)
42
+ * Only used when enableDriftDetection is true
43
+ */
44
+ driftThreshold?: number;
45
+
46
+ /**
47
+ * Callback when drift is detected
48
+ * Only used when enableDriftDetection is true
49
+ */
50
+ onDriftDetected?: (stats: DriftStatistics) => void;
51
+ }
52
+
53
+ /**
54
+ * Redis configuration for state persistence
55
+ */
56
+ export interface RedisConfig {
57
+ redisHost?: string;
58
+ redisPort?: number;
59
+ stateKey?: string;
60
+ }
61
+
62
+ /**
63
+ * Parameters for adding a moving average stage
64
+ *
65
+ * Two windowing modes supported:
66
+ * 1. Sample-based (legacy): windowSize in samples (requires sampleRate in process())
67
+ * 2. Time-based (new): windowDuration in milliseconds (works with any sample rate)
68
+ */
69
+ export interface MovingAverageParams {
70
+ mode: "batch" | "moving";
71
+
72
+ /**
73
+ * Window size in samples (legacy, sample-based mode)
74
+ * Required for "moving" mode when using sampleRate-based processing
75
+ */
76
+ windowSize?: number;
77
+
78
+ /**
79
+ * Window duration in milliseconds (time-based mode)
80
+ * Required for "moving" mode when using time-based processing
81
+ * Takes precedence over windowSize if both provided
82
+ */
83
+ windowDuration?: number;
84
+ }
85
+
86
+ /**
87
+ * Parameters for adding a RMS stage
88
+ *
89
+ * Two windowing modes supported:
90
+ * 1. Sample-based (legacy): windowSize in samples (requires sampleRate in process())
91
+ * 2. Time-based (new): windowDuration in milliseconds (works with any sample rate)
92
+ */
93
+ export interface RmsParams {
94
+ mode: "batch" | "moving";
95
+
96
+ /**
97
+ * Window size in samples (legacy, sample-based mode)
98
+ * Required for "moving" mode when using sampleRate-based processing
99
+ */
100
+ windowSize?: number;
101
+
102
+ /**
103
+ * Window duration in milliseconds (time-based mode)
104
+ * Required for "moving" mode when using time-based processing
105
+ * Takes precedence over windowSize if both provided
106
+ */
107
+ windowDuration?: number;
108
+ }
109
+
110
+ /**
111
+ * Parameters for adding a rectify stage
112
+ */
113
+ export interface RectifyParams {
114
+ mode?: "full" | "half"; // Default: "full"
115
+ }
116
+
117
+ /**
118
+ * Parameters for adding a variance stage
119
+ *
120
+ * Two windowing modes supported:
121
+ * 1. Sample-based (legacy): windowSize in samples (requires sampleRate in process())
122
+ * 2. Time-based (new): windowDuration in milliseconds (works with any sample rate)
123
+ */
124
+ export interface VarianceParams {
125
+ mode: "batch" | "moving";
126
+
127
+ /**
128
+ * Window size in samples (legacy, sample-based mode)
129
+ * Required for "moving" mode when using sampleRate-based processing
130
+ */
131
+ windowSize?: number;
132
+
133
+ /**
134
+ * Window duration in milliseconds (time-based mode)
135
+ * Required for "moving" mode when using time-based processing
136
+ * Takes precedence over windowSize if both provided
137
+ */
138
+ windowDuration?: number;
139
+ }
140
+
141
+ /**
142
+ * Parameters for adding a Z-Score Normalization stage
143
+ *
144
+ * Two windowing modes supported:
145
+ * 1. Sample-based (legacy): windowSize in samples (requires sampleRate in process())
146
+ * 2. Time-based (new): windowDuration in milliseconds (works with any sample rate)
147
+ */
148
+ export interface ZScoreNormalizeParams {
149
+ mode: "batch" | "moving";
150
+
151
+ /**
152
+ * Window size in samples (legacy, sample-based mode)
153
+ * Required for "moving" mode when using sampleRate-based processing
154
+ */
155
+ windowSize?: number;
156
+
157
+ /**
158
+ * Window duration in milliseconds (time-based mode)
159
+ * Required for "moving" mode when using time-based processing
160
+ * Takes precedence over windowSize if both provided
161
+ */
162
+ windowDuration?: number;
163
+
164
+ /**
165
+ * Small value to prevent division by zero when standard deviation is 0.
166
+ * @default 1e-6
167
+ */
168
+ epsilon?: number;
169
+ }
170
+
171
+ /**
172
+ * Parameters for adding a Mean Absolute Value (MAV) stage
173
+ *
174
+ * Two windowing modes supported:
175
+ * 1. Sample-based (legacy): windowSize in samples (requires sampleRate in process())
176
+ * 2. Time-based (new): windowDuration in milliseconds (works with any sample rate)
177
+ */
178
+ export interface MeanAbsoluteValueParams {
179
+ mode: "batch" | "moving";
180
+
181
+ /**
182
+ * Window size in samples (legacy, sample-based mode)
183
+ * Required for "moving" mode when using sampleRate-based processing
184
+ */
185
+ windowSize?: number;
186
+
187
+ /**
188
+ * Window duration in milliseconds (time-based mode)
189
+ * Required for "moving" mode when using time-based processing
190
+ * Takes precedence over windowSize if both provided
191
+ */
192
+ windowDuration?: number;
193
+ }
194
+
195
+ /**
196
+ * Parameters for adding a Waveform Length stage
197
+ * Computes the cumulative length of the signal path (sum of absolute differences)
198
+ */
199
+ export interface WaveformLengthParams {
200
+ /**
201
+ * Window size in samples
202
+ * Required parameter for waveform length calculation
203
+ */
204
+ windowSize: number;
205
+ }
206
+
207
+ /**
208
+ * Parameters for adding a Slope Sign Change (SSC) stage
209
+ * Counts frequency content by detecting sign changes in slope
210
+ */
211
+ export interface SlopeSignChangeParams {
212
+ /**
213
+ * Window size in samples
214
+ * Required parameter for SSC calculation
215
+ */
216
+ windowSize: number;
217
+
218
+ /**
219
+ * Threshold for noise suppression (default: 0.0)
220
+ * Only count sign changes when |slope| exceeds this threshold
221
+ */
222
+ threshold?: number;
223
+ }
224
+
225
+ /**
226
+ * Parameters for adding a Willison Amplitude (WAMP) stage
227
+ * Counts the number of times consecutive samples differ by more than a threshold
228
+ */
229
+ export interface WillisonAmplitudeParams {
230
+ /**
231
+ * Window size in samples
232
+ * Required parameter for WAMP calculation
233
+ */
234
+ windowSize: number;
235
+
236
+ /**
237
+ * Threshold for difference detection (default: 0.0)
238
+ * Only count differences exceeding this threshold
239
+ */
240
+ threshold?: number;
241
+ }
242
+
243
+ /**
244
+ * Tap callback function for inspecting samples at any point in the pipeline
245
+ * @param samples - Float32Array view of the current samples
246
+ * @param stageName - Name of the pipeline stage
247
+ */
248
+ export type TapCallback = (samples: Float32Array, stageName: string) => void;
249
+
250
+ /**
251
+ * Log levels for pipeline callbacks
252
+ * Extended levels: trace (most verbose) -> debug -> info -> warn -> error -> fatal (most critical)
253
+ */
254
+ export type LogLevel = "trace" | "debug" | "info" | "warn" | "error" | "fatal";
255
+
256
+ /**
257
+ * Log topics following Kafka-style hierarchical structure
258
+ * Examples:
259
+ * - pipeline.stage.moving-average.samples
260
+ * - pipeline.stage.rms.performance
261
+ * - pipeline.stage.rectify.error
262
+ * - pipeline.debug
263
+ * - pipeline.error
264
+ */
265
+ export type LogTopic = string;
266
+
267
+ /**
268
+ * Log priority levels (1-10)
269
+ * Lower numbers = lower priority, higher numbers = higher priority
270
+ *
271
+ * Priority Guidelines:
272
+ * - 1-3: Low priority (debug, verbose info)
273
+ * - 4-6: Normal priority (standard info, warnings)
274
+ * - 7-8: High priority (errors, important events)
275
+ * - 9-10: Critical priority (alerts, system failures)
276
+ */
277
+ export type LogPriority = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10;
278
+
279
+ /**
280
+ * Context information passed to logging callbacks
281
+ */
282
+ export interface LogContext {
283
+ stage?: string;
284
+ timestamp?: number;
285
+ [key: string]: any;
286
+ }
287
+
288
+ /**
289
+ * A single log entry with timestamp and topic
290
+ * Supports distributed tracing with optional trace/span/correlation IDs
291
+ */
292
+ export interface LogEntry {
293
+ topic?: LogTopic; // Optional: generated automatically by logging system
294
+ level: LogLevel;
295
+ message: string;
296
+ context?: LogContext;
297
+ timestamp: number;
298
+ priority?: LogPriority; // Optional: defaults to 1 (lowest priority)
299
+
300
+ // Distributed tracing fields (for Datadog, AWS X-Ray, Jaeger, etc.)
301
+ traceId?: string; // Unique identifier for the entire trace
302
+ spanId?: string; // Unique identifier for this span within the trace
303
+ correlationId?: string; // Business-level correlation (e.g., request ID)
304
+ }
305
+
306
+ /**
307
+ * Batch of samples with metadata for efficient callback processing
308
+ */
309
+ export interface SampleBatch {
310
+ stage: string;
311
+ samples: Float32Array;
312
+ startIndex: number;
313
+ count: number;
314
+ }
315
+
316
+ /**
317
+ * Pipeline callback functions for monitoring and observability
318
+ *
319
+ * PRODUCTION ARCHITECTURE PHILOSOPHY:
320
+ * - Individual callbacks (onSample, onLog): ~6-7M samples/sec raw speed
321
+ * WARNING: BLOCKS event loop with millions of synchronous calls - NOT production-safe
322
+ *
323
+ * - Pooled callbacks (onBatch, onLogBatch): ~3-5M samples/sec sustained
324
+ * RECOMMENDED: Non-blocking, batched processing - RECOMMENDED for production
325
+ *
326
+ * Trade-off: Pooled callbacks sacrifice raw speed for guaranteed non-blocking behavior.
327
+ * This aligns with industry telemetry patterns (Kafka producers, Loki agents, OTLP exporters).
328
+ */
329
+ export interface PipelineCallbacks {
330
+ /**
331
+ * Called for each sample after processing (use sparingly for performance)
332
+ * WARNING: Blocks event loop with millions of synchronous calls per second
333
+ * Raw performance: ~6-7M samples/sec, but NOT recommended for production servers
334
+ * Consider using onBatch instead for non-blocking, production-safe processing
335
+ * @param value - The processed sample value
336
+ * @param index - Sample index in the buffer
337
+ * @param stage - Name of the current stage
338
+ */
339
+ onSample?: (value: number, index: number, stage: string) => void;
340
+
341
+ /**
342
+ * Called with batches of processed samples (RECOMMENDED for production)
343
+ * Production-safe: Non-blocking, batched processing (~3-5M samples/sec sustained)
344
+ * Samples are provided as a view into the result buffer
345
+ * @param batch - Contains stage name, sample data, start index, and count
346
+ */
347
+ onBatch?: (batch: SampleBatch) => void;
348
+
349
+ /**
350
+ * Called after each stage completes processing
351
+ * @param stage - Name of the completed stage
352
+ * @param durationMs - Processing time in milliseconds
353
+ */
354
+ onStageComplete?: (stage: string, durationMs: number) => void;
355
+
356
+ /**
357
+ * Called when an error occurs in a stage
358
+ * @param stage - Name of the stage where error occurred
359
+ * @param error - The error object
360
+ */
361
+ onError?: (stage: string, error: Error) => void;
362
+
363
+ /**
364
+ * Called for each logging event during pipeline execution
365
+ * WARNING: Blocks event loop with frequent synchronous calls
366
+ * Raw performance: ~6M samples/sec, but NOT recommended for production servers
367
+ * Consider using onLogBatch for non-blocking, production-safe logging (~3M samples/sec)
368
+ * @param topic - Kafka-style hierarchical topic (e.g., "pipeline.stage.rms.error")
369
+ * @param level - Log severity level
370
+ * @param message - Log message
371
+ * @param context - Additional context information
372
+ */
373
+ onLog?: (
374
+ topic: LogTopic,
375
+ level: LogLevel,
376
+ message: string,
377
+ context?: LogContext
378
+ ) => void;
379
+
380
+ /**
381
+ * Called with batched log messages (RECOMMENDED for production)
382
+ * Production-safe: Non-blocking, batched logging with fixed-size circular buffer
383
+ * Logs are pooled and flushed at the end of each process() call
384
+ * Provides stable ~3M samples/sec throughput without blocking event loop
385
+ *
386
+ * Topic-based filtering examples:
387
+ * - Filter by pattern: logs.filter(l => l.topic.startsWith('pipeline.stage.'))
388
+ * - Subscribe to errors: logs.filter(l => l.topic.endsWith('.error'))
389
+ * - Route by topic: Route errors to alerting, metrics to monitoring
390
+ *
391
+ * @param logs - Array of log entries with topics and timestamps
392
+ */
393
+ onLogBatch?: (logs: LogEntry[]) => void;
394
+
395
+ /**
396
+ * Topic filter for selective log subscription (optional)
397
+ * If provided, only logs matching the topic pattern will be delivered
398
+ * Supports wildcards: 'pipeline.stage.*', 'pipeline.*.error'
399
+ * If omitted, all logs are delivered
400
+ */
401
+ topicFilter?: string | string[];
402
+ }
403
+
404
+ /**
405
+ * Summary information for a single pipeline stage
406
+ */
407
+ export interface StageSummary {
408
+ /** Stage index in the pipeline */
409
+ index: number;
410
+ /** Stage type (e.g., 'movingAverage', 'rms', 'rectify') */
411
+ type: string;
412
+ /** Window size for stateful filters in samples (legacy, if applicable) */
413
+ windowSize?: number;
414
+ /** Window duration for stateful filters in milliseconds (time-based, if applicable) */
415
+ windowDuration?: number;
416
+ /** Number of channels (if applicable) */
417
+ numChannels?: number;
418
+ /** Rectification mode for rectify stage (if applicable) */
419
+ mode?: "full" | "half";
420
+ /** Buffer size for stateful filters (if applicable) */
421
+ bufferSize?: number;
422
+ /** Number of channels with state (if applicable) */
423
+ channelCount?: number;
424
+ }
425
+
426
+ /**
427
+ * Pipeline state summary (lightweight view without full buffer data)
428
+ * Useful for debugging and monitoring pipeline structure
429
+ */
430
+ export interface PipelineStateSummary {
431
+ /** Total number of stages in the pipeline */
432
+ stageCount: number;
433
+ /** Timestamp when the summary was generated */
434
+ timestamp: number;
435
+ /** Array of stage summaries */
436
+ stages: StageSummary[];
437
+ }
438
+
439
+ /**
440
+ * Hjorth parameters - measures of signal complexity
441
+ */
442
+ export interface HjorthParameters {
443
+ /** Activity: Variance of the signal */
444
+ activity: number;
445
+ /** Mobility: Square root of (variance of first derivative / variance) */
446
+ mobility: number;
447
+ /** Complexity: Mobility of first derivative / Mobility of signal */
448
+ complexity: number;
449
+ }
450
+
451
+ /**
452
+ * Parameters for Hjorth parameters calculation
453
+ */
454
+ export interface HjorthParams {
455
+ mode: "batch" | "moving";
456
+ /**
457
+ * Window size in samples (required for moving mode)
458
+ */
459
+ windowSize?: number;
460
+ /**
461
+ * Window duration in milliseconds (alternative to windowSize)
462
+ */
463
+ windowDuration?: number;
464
+ }
465
+
466
+ /**
467
+ * Parameters for decimation (downsampling)
468
+ */
469
+ export interface DecimateParams {
470
+ /** Decimation factor M (output rate = input rate / M) */
471
+ factor: number;
472
+ /** Apply anti-aliasing filter before decimation (default: true) */
473
+ useAntiAliasingFilter?: boolean;
474
+ /** FIR filter order for anti-aliasing (default: auto-calculated) */
475
+ filterOrder?: number;
476
+ }
477
+
478
+ /**
479
+ * Parameters for interpolation (upsampling)
480
+ */
481
+ export interface InterpolateParams {
482
+ /** Interpolation factor L (output rate = input rate * L) */
483
+ factor: number;
484
+ /** Apply anti-imaging filter after interpolation (default: true) */
485
+ useAntiImagingFilter?: boolean;
486
+ /** FIR filter order for anti-imaging (default: auto-calculated) */
487
+ filterOrder?: number;
488
+ }
489
+
490
+ /**
491
+ * Parameters for resampling (rational rate conversion)
492
+ */
493
+ export interface ResampleParams {
494
+ /** Interpolation factor L */
495
+ upsampleFactor: number;
496
+ /** Decimation factor M (new rate = old rate * L / M) */
497
+ downsampleFactor: number;
498
+ /** Apply combined anti-aliasing/anti-imaging filter (default: true) */
499
+ useFilter?: boolean;
500
+ /** FIR filter order (default: auto-calculated) */
501
+ filterOrder?: number;
502
+ }
503
+
504
+ /**
505
+ * Spectral features extracted from FFT
506
+ */
507
+ export interface SpectralFeatures {
508
+ /** Spectral centroid: center of mass of spectrum (Hz) */
509
+ centroid: number;
510
+ /** Spectral rolloff: frequency below which X% of energy is contained (Hz) */
511
+ rolloff: number;
512
+ /** Spectral flux: change in spectrum from previous frame */
513
+ flux: number;
514
+ }
515
+
516
+ /**
517
+ * Parameters for spectral feature extraction
518
+ */
519
+ export interface SpectralFeaturesParams {
520
+ /** FFT size (should be power of 2, default: 2048) */
521
+ fftSize?: number;
522
+ /** Rolloff percentage (0-100, default: 85) */
523
+ rolloffPercentage?: number;
524
+ }
525
+
526
+ /**
527
+ * Parameters for Shannon entropy calculation
528
+ */
529
+ export interface EntropyParams {
530
+ mode: "batch" | "moving";
531
+ /**
532
+ * Window size in samples (required for moving mode)
533
+ */
534
+ windowSize?: number;
535
+ /**
536
+ * Window duration in milliseconds (alternative to windowSize)
537
+ */
538
+ windowDuration?: number;
539
+ /**
540
+ * Number of bins for histogram (default: 256)
541
+ */
542
+ numBins?: number;
543
+ }
544
+
545
+ /**
546
+ * Parameters for Sample Entropy (SampEn)
547
+ */
548
+ export interface SampleEntropyParams {
549
+ mode: "batch" | "moving";
550
+ /**
551
+ * Window size in samples (required for moving mode)
552
+ */
553
+ windowSize?: number;
554
+ /**
555
+ * Window duration in milliseconds (alternative to windowSize)
556
+ */
557
+ windowDuration?: number;
558
+ /**
559
+ * Pattern length (default: 2)
560
+ */
561
+ m?: number;
562
+ /**
563
+ * Tolerance for matching (default: 0.2 * std deviation)
564
+ */
565
+ r?: number;
566
+ }
567
+
568
+ /**
569
+ * Parameters for Approximate Entropy (ApEn)
570
+ */
571
+ export interface ApproximateEntropyParams {
572
+ mode: "batch" | "moving";
573
+ /**
574
+ * Window size in samples (required for moving mode)
575
+ */
576
+ windowSize?: number;
577
+ /**
578
+ * Window duration in milliseconds (alternative to windowSize)
579
+ */
580
+ windowDuration?: number;
581
+ /**
582
+ * Pattern length (default: 2)
583
+ */
584
+ m?: number;
585
+ /**
586
+ * Tolerance for matching (default: 0.2 * std deviation)
587
+ */
588
+ r?: number;
589
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,15 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "module": "ESNext",
5
+ "strict": true,
6
+ "esModuleInterop": true,
7
+ "skipLibCheck": true,
8
+ "forceConsistentCasingInFileNames": true,
9
+ "moduleResolution": "node",
10
+ "outDir": "./dist",
11
+ "rootDir": "./src"
12
+ },
13
+ "include": ["src/**/*"],
14
+ "exclude": ["node_modules"]
15
+ }