UNPKG

@rfkit/spectrum-analyzer

Version:

A high-performance spectrum analyzer library for RF signal processing, supporting real-time spectrum analysis, waterfall display, and multi-segment frequency scanning

1 lines 22.2 kB
var t=/*#__PURE__*/function(t){return t.Horizontal="horizontal",t.Vertical="vertical",t}({}),e=/*#__PURE__*/function(t){return t.Circle="circle",t.Rect="rect",t.Line="line",t.Stepline="stepline",t.Bar="bar",t.Area="area",t}({}),a=/*#__PURE__*/function(t){return t.PropertyChanged="propertyChanged",t.SeriesAdded="seriesAdded",t.SeriesRemoved="seriesRemoved",t.SeriesCleared="seriesCleared",t}({});let s={thickness:1,orientation:t.Horizontal,display:!0,type:e.Line,color:"#00000000",label:""};class n{seriesMap=new Map;changeCallbacks=[];subscribers=new Map;constructor(t=[]){this.initializeSeries(t)}initializeSeries(t){for(let e of t)this.addSeries(e)}addSeries(t){let e={...s,...t};this.seriesMap.set(t.name,e),this.emitEvent({type:a.SeriesAdded,name:t.name,series:e})}getSeries(t){return this.seriesMap.get(t)}getAllSeries(){return Array.from(this.seriesMap.values())}getAllConfigs(){let t={};for(let[e,a]of this.seriesMap)t[e]={...a};return t}setSeriesProperty(t,e,s){let n=this.seriesMap.get(t);if(!n||"name"===e)return!1;let i=n[e],r={...n,[e]:s};return this.seriesMap.set(t,r),this.notifyChange(t,e,s),this.emitEvent({type:a.PropertyChanged,name:t,property:e,value:s,oldValue:i,series:r}),!0}removeSeries(t){let e=this.seriesMap.get(t);if(!e)return!1;let s=this.seriesMap.delete(t);return s&&this.emitEvent({type:a.SeriesRemoved,name:t,series:e}),s}hasSeries(t){return this.seriesMap.has(t)}onChange(t){this.changeCallbacks.push(t)}offChange(t){let e=this.changeCallbacks.indexOf(t);e>-1&&this.changeCallbacks.splice(e,1)}notifyChange(t,e,a){for(let s of this.changeCallbacks)s(t,e,a)}clear(){this.seriesMap.clear(),this.emitEvent({type:a.SeriesCleared})}size(){return this.seriesMap.size}subscribe(t,e={}){if(this.subscribers.set(t,e),e.immediate)for(let e of this.seriesMap.values())this.shouldNotifySubscriber(t,{type:a.SeriesAdded,name:e.name,series:e})&&t({type:a.SeriesAdded,name:e.name,series:e});return()=>{this.subscribers.delete(t)}}unsubscribe(t){this.subscribers.delete(t)}emitEvent(t){for(let[e]of this.subscribers)this.shouldNotifySubscriber(e,t)&&e(t)}shouldNotifySubscriber(t,e){let a=this.subscribers.get(t);return!!a&&(!a.eventTypes||!!a.eventTypes.includes(e.type))&&(!a.seriesNames||!e.name||!!a.seriesNames.includes(e.name))}}let i={INITIAL_VALUE:0/0,WATERFALL_MAX_FRAMES:100,OUTPUT_POINTS:1001},r={MAX_PEAKS:2},l=null,o={UPDATE_INTERVAL:1,LEVEL_MIN:-20,LEVEL_MAX:140,LEVEL_RANGE:161},h={maxPoints:i.OUTPUT_POINTS,waterfallMaxFrames:i.WATERFALL_MAX_FRAMES,initialValue:i.INITIAL_VALUE,processing:{enableWaterfall:!1,enableMetrics:!1,enableFluorescence:!1,enablePeakStats:!1,fluorescenceUpdateInterval:o.UPDATE_INTERVAL},peakDetection:{maxPeaks:r.MAX_PEAKS},outputPoints:i.OUTPUT_POINTS,outputRange:{start:0,end:i.OUTPUT_POINTS},templateTolerance:0},c={EMPTY_SEGMENTS:"频段配置不能为空",INVALID_CONFIG:"必须且只能配置 segments 或 bandwidthConfig 其中之一",EMPTY_BANDWIDTH:"bandwidthConfig 不能为空",INVALID_SEGMENT:t=>`无效的段索引: ${t}`,INDEX_OUT_OF_BOUNDS:t=>`索引超出范围: ${t}`,INVALID_ANTENNA_FACTOR_LENGTH:t=>`天线因子数据长度必须等于实时数据长度 (${t})`,INVALID_ANTENNA_FACTOR:"天线因子数据必须是有效的正数",INVALID_SAMPLING_RANGE:"采样范围无效",INVALID_MAX_POINTS:"点数必须大于0",INVALID_LENGTH:t=>`频率占用度数据长度不匹配,期望长度为 ${t}`};class m extends Error{code;details;constructor(t,e,a){super(t),this.code=e,this.details=a,this.name="SpectrumError"}}class u extends m{constructor(t,e){super(t,"DATA_VALIDATION_ERROR",e)}}class p extends m{index;constructor(t,e,a){super(t,"INDEX_OUT_OF_BOUNDS_ERROR",{index:e,...a||{}}),this.index=e}}var d=/*#__PURE__*/function(t){return t.REPLACE="replace",t.MERGE="merge",t.CLEAR="clear",t}({});let g=()=>({data:[],rawData:[],range:{x:[0,0],y:[0,0]},sourceSize:{width:0,height:0},columnIndices:new Uint32Array(0),rowIndices:new Uint32Array(0)}),f=t=>{let e=new Float32Array(t);return e.timestamp=t.timestamp,void 0!==t.allValid&&(e.allValid=t.allValid),t.peaks&&(e.peaks={...t.peaks,peaks:t.peaks.peaks.map(t=>({...t}))}),e},w=(t,e)=>{if(!Number.isInteger(t)||t<=0)throw new u(`${e} 必须是正整数`)},D=(t,e,a)=>{let[s,n]=t;if(!Number.isFinite(s)||!Number.isFinite(n)||s>=n)throw new u(`${a} 采样范围无效`);let i=Math.max(0,Math.min(e,Math.floor(s))),r=Math.max(0,Math.min(e,Math.ceil(n)));if(i>=r)throw new u(`${a} 采样范围超出数据边界`);return[i,r]},_=(t,e,a)=>{if(0===t[0]&&t[1]===e)return[0,a];let s=Math.min(t[0],a-1),n=Math.max(s+1,Math.min(t[1],a));return[s,n]},x=(t,e,a)=>{if(0===t[0]&&t[1]===e)return[0,a];if(t[1]===e){let e=Math.min(t[1]-t[0],a);return[a-e,a]}return _(t,e,a)},I=(t,e,a,s)=>{if(0===t[0]&&t[1]===e)return[0,a];let n=Math.min(t[1]-t[0],a);if(t[1]===e)return[a-n,a];let i=Math.max(0,Math.min(t[0]-s,a-n));return[i,i+n]},A=(t,e)=>{let[a,s]=t,n=s-a,i=Math.min(n,e),r=new Uint32Array(i);if(n<=e){for(let t=0;t<i;t++)r[t]=a+t;return r}for(let t=0;t<i;t++){let e=Math.floor(t*n/i),s=Math.floor((t+1)*n/i);r[t]=a+Math.min(s-1,Math.floor((e+s)/2))}return r},y=(t,e)=>t[0]===e[0]&&t[1]===e[1],S=(t,e)=>{if(t.length!==e.length)return!1;for(let a=0;a<t.length;a++)if(t[a]!==e[a])return!1;return!0},C=(t,e,a)=>{let s=t.subarray(e[0],e[1]),n=s.length,i=Math.min(n,a);if(n<=a)return 0===e[0]&&e[1]===t.length?t:(s.timestamp=t.timestamp,s);let r=new Float32Array(i);r.timestamp=t.timestamp;for(let t=0;t<i;t++){let e=Math.floor(t*n/i),a=Math.floor((t+1)*n/i),l=0/0;for(let t=e;t<a;t++){let e=s[t];Number.isFinite(e)&&(!Number.isFinite(l)||e>l)&&(l=e)}r[t]=l}return r};class b{maxFrames;onWaterfallUpdate;sourceData=[];samplingOptions;snapshot=g();constructor(t={}){if(void 0!==t.maxFrames&&(!Number.isInteger(t.maxFrames)||t.maxFrames<=0))throw new u("maxFrames 必须是正整数");this.maxFrames=t.maxFrames,this.onWaterfallUpdate=t.onWaterfallUpdate}setData(t){if(0===t.length)return this.sourceData=[],this.samplingOptions=void 0,this.publishSnapshot(g());let e=t[0].length;if(0===e)throw new u("瀑布图帧不能为空");for(let a of t)if(a.length!==e)throw new u("瀑布图数据必须是等宽矩阵");let a=this.snapshot.sourceSize,s=[...t];void 0!==this.maxFrames&&s.length>this.maxFrames&&(s=s.slice(-this.maxFrames));let n=this.samplingOptions;n&&a.width>0&&a.height>0&&(n={...n,x:_(n.x,a.width,e),y:x(n.y,a.height,s.length)});let i=this.createSnapshot(s,n);return this.sourceData=s,this.samplingOptions=n,this.publishSnapshot(i)}appendFrame(t){if(0===t.length)throw new u("瀑布图帧不能为空");let e=this.sourceData[0]?.length;if(void 0!==e&&t.length!==e)throw new u("追加帧宽度必须与现有瀑布图一致");let a=this.sourceData.length,s=[...this.sourceData,f(t)],n=0;void 0!==this.maxFrames&&s.length>this.maxFrames&&(n=s.length-this.maxFrames,s.splice(0,n));let i=this.samplingOptions;i&&a>0&&(i={...i,y:I(i.y,a,s.length,n)});let r=this.createSnapshot(s,i);return this.sourceData=s,this.samplingOptions=i,this.publishSnapshot(r)}updateSamplingRange(t){let e=this.getSourceSize(this.sourceData);if(0===e.width||0===e.height)throw new u("设置采样范围前必须先设置瀑布图数据");w(t.outputWidth,"outputWidth"),w(t.outputHeight,"outputHeight");let a={x:D(t.x,e.width,"X"),y:D(t.y,e.height,"Y"),outputWidth:t.outputWidth,outputHeight:t.outputHeight},s=this.createSnapshot(this.sourceData,a);return this.samplingOptions=a,this.publishSnapshot(s)}getSnapshot(){return this.snapshot}createSnapshot(t,e){let a=this.getSourceSize(t);if(0===a.width||0===a.height)return g();let s=e?.x??[0,a.width],n=e?.y??[0,a.height],i=e?.outputWidth??s[1]-s[0],r=e?.outputHeight??n[1]-n[0],l=A(s,i),o=A(n,r),h=this.createReusableRows(s,l);return{data:Array.from(o,e=>{let a=t[e];return h.get(a)??C(a,s,i)}),rawData:t,range:{x:s,y:n},sourceSize:a,columnIndices:l,rowIndices:o}}createReusableRows(t,e){let a=this.snapshot;if(!y(a.range.x,t)||!S(a.columnIndices,e))return new Map;let s=new Map;for(let t=0;t<a.rowIndices.length;t++){let e=a.rawData[a.rowIndices[t]],n=a.data[t];e&&n&&s.set(e,n)}return s}getSourceSize(t){return{width:t[0]?.length??0,height:t.length}}publishSnapshot(t){return this.snapshot=t,this.onWaterfallUpdate?.(t),t}}let E={DEFAULT_CACHE_TIME:15e3,DEFAULT_GRANULARITY:10,DEFAULT_RANGE:[-20,100]},v={cacheTime:E.DEFAULT_CACHE_TIME,granularity:E.DEFAULT_GRANULARITY,range:E.DEFAULT_RANGE,maxPoints:void 0,onLevelStreamUpdate:t=>{}},N=null,M=!1,T=null;function R(){return"u">typeof process&&"object"==typeof process.versions&&!!process.versions?.node}async function F(){M||(T||(T=(async()=>{let t=await import("./src-rust/pkg/rfkit_spectrum_analyzer_wasm.js");if("function"==typeof t.default)if(R()){let e=new URL("./src-rust/pkg/rfkit_spectrum_analyzer_wasm_bg.wasm",import.meta.url);if("file:"===e.protocol){let{readFile:a}=await import("node:fs/promises"),s=await a(e);await t.default({module_or_path:s})}else await t.default()}else await t.default();N=t,M=!0})()),await T)}function k(){return M}function L(){if(!N)throw Error('WASM not initialized. Call `await initWasm()` before using WASM classes.\nExample:\n import { initWasm } from "@rfkit/spectrum-analyzer/wasm";\n await initWasm();');return N}function O(){if(!M)throw Error('WASM not initialized. Call `await initWasm()` before creating WASM instances.\nExample:\n import { initWasm, SpectrumAnalyzer } from "@rfkit/spectrum-analyzer/wasm";\n await initWasm();\n const analyzer = new SpectrumAnalyzer(config);')}class U{wasmInstance;onLevelStreamUpdate;config;constructor(t){O();let e=L();this.onLevelStreamUpdate=t.onLevelStreamUpdate;let{onLevelStreamUpdate:a,...s}=t;this.config={cacheTime:v.cacheTime,granularity:v.granularity,range:[...v.range],maxPoints:v.maxPoints,...s},this.wasmInstance=new e.WasmLevelStreamAnalyzer(this.config),this.onLevelStreamUpdate&&this.wasmInstance.set_callback(t=>{this.onLevelStreamUpdate?.(t)})}process(t,e){this.wasmInstance.process(t,e)}reset(){this.wasmInstance.reset()}setConfig(t){"onLevelStreamUpdate"in t&&(this.onLevelStreamUpdate=t.onLevelStreamUpdate,this.wasmInstance.set_callback(t=>{this.onLevelStreamUpdate?.(t)}));let e=void 0!==t.cacheTime&&this.config.cacheTime!==t.cacheTime||void 0!==t.granularity&&this.config.granularity!==t.granularity||void 0!==t.maxPoints&&this.config.maxPoints!==t.maxPoints,{onLevelStreamUpdate:a,...s}=t,n={...this.config,...s};this.config=n,this.wasmInstance.set_config(n,e,!!t.range)}getAll(){return this.wasmInstance.get_all()}}class P{wasmInstance;onSpectrumUpdate;hasSegments=!1;segments=[];callbackContext=null;templateDataRaw=new Float32Array(0);backgroundNoiseDataRaw=new Float32Array(0);thresholdDataRaw=new Float32Array(0);antennaFactorData;srcIndexCache;extraData={};antennaFactorSwitch=!1;config;constructor(t){O();let e=L();this.onSpectrumUpdate=t.onSpectrumUpdate;let{onSpectrumUpdate:a,...s}=t;this.wasmInstance=new e.WasmSpectrumAnalyzer(s),this.wasmInstance.set_callback(t=>{let e=this.convertOutput(t);e&&(e.srcIndexCache&&(this.srcIndexCache=e.srcIndexCache),this.onSpectrumUpdate?.(e))}),this.antennaFactorData=this.wasmInstance.get_antenna_factor_view(),this.srcIndexCache=this.wasmInstance.get_src_index_cache_view(),this.config=this.readConfig()}readConfig(){let t=this.wasmInstance.get_config();return{initialValue:i.INITIAL_VALUE,...t}}normalizeSeriesData(t){let e=new Float32Array(this.config.maxPoints);return e.fill(i.INITIAL_VALUE),e.set(t.subarray(0,this.config.maxPoints)),e}resampleSingleDataLikeJs(t){let{outputRange:{start:e,end:a}}=this.config,s=t.subarray(e,a),n=this.srcIndexCache.length,i=new Float32Array(n);for(let t=0;t<n;t++)i[t]=s[this.srcIndexCache[t]];return i}normalizeSegments(t){let e=0;return t.map(t=>{let{startFrequency:a,stopFrequency:s,stepFrequency:n}=t,i=Math.round(1e3*(s-a)/n)+1,r=e;return e+=i,{startFrequency:a,stopFrequency:s,stepFrequency:n,pointCount:i,startIndex:r}})}resolveGlobalIndex(t=0,e=0){if(this.segments.length>0){let a=this.segments[t];if(!a)throw new u(c.INVALID_SEGMENT(t));return a.startIndex+e}return e}validateSegmentInput(t,e){if(e<0||e+t.length>this.config.maxPoints)throw new p(c.INDEX_OUT_OF_BOUNDS(e),e)}clearLocalResetMirrors(){this.templateDataRaw=new Float32Array(0),this.backgroundNoiseDataRaw=new Float32Array(0),this.thresholdDataRaw=new Float32Array(0),this.extraData={}}convertOutput(t){let e=this.callbackContext;if(e?.type==="setExtraData"&&e.mode===d.CLEAR)return null;let a={...t};a.realData&&void 0!==a.timestamp&&(a.realData.timestamp=a.timestamp),delete a.timestamp,void 0!==a.peakStats&&a.realData&&(a.realData.peaks=a.peakStats),delete a.peakStats;let s=t=>Object.fromEntries(t.map(t=>[t,a[t]])),n=t=>{"fluorescenceData"in t||(t.fluorescenceData=void 0),"fluorescenceMaxCount"in t||(t.fluorescenceMaxCount=0)},i=!("occupancyData"in a);switch(e?.type){case"process":if(i)return s(["realData","maxData","minData","avgData","templateData","backgroundNoiseData","thresholdData","extraData","srcIndexCache","processTimes","scanProgress"]);return n(a),"templateOverData"in a||(a.templateOverData=[]),s(["realData","maxData","minData","avgData","templateData","occupancyData","backgroundNoiseData","thresholdData","fluorescenceData","fluorescenceMaxCount","extraData","srcIndexCache","waterfallData","scanProgress","processTimes","templateOverData"]);case"setAntennaFactorSwitch":case"updateSamplingRange":return n(a),s(["realData","maxData","minData","avgData","templateData","occupancyData","backgroundNoiseData","thresholdData","fluorescenceData","fluorescenceMaxCount","extraData","srcIndexCache","waterfallData"]);case"updateProcessing":case"setRealData":case"setMaxData":case"setMinData":case"setAvgData":return n(a),s(["realData","maxData","minData","avgData","templateData","occupancyData","backgroundNoiseData","thresholdData","fluorescenceData","fluorescenceMaxCount","extraData","srcIndexCache"]);case"clearMetricsData":return s(["maxData","minData","avgData","processTimes"]);case"setFluorescenceData":return s(["fluorescenceData","fluorescenceMaxCount"]);case"setTemplateData":return{templateData:this.resampleSingleDataLikeJs(this.templateDataRaw),templateOverData:a.templateOverData??[]};case"setOccupancyData":return{occupancyData:a.occupancyData??new Float32Array(0)};case"setBackgroundNoiseData":return{backgroundNoiseData:this.resampleSingleDataLikeJs(this.backgroundNoiseDataRaw)};case"setThresholdData":return{thresholdData:this.resampleSingleDataLikeJs(this.thresholdDataRaw)};case"setExtraData":return{extraData:a.extraData??{}};case"setWaterfallData":return{waterfallData:a.waterfallData??[]};case"reset":case"initializeSegments":return s(["realData","maxData","minData","avgData","templateData","backgroundNoiseData","thresholdData","extraData","srcIndexCache","processTimes","scanProgress"]);default:return a}}withCallbackContext(t,e){let a=this.callbackContext;this.callbackContext=t;try{return e()}finally{this.callbackContext=a}}process(t){let e=this.config.maxPoints;if(t.data?.length){let e=this.resolveGlobalIndex(t.segmentOffset??0,t.offset??0);if(this.segments.length>0)this.validateSegmentInput(t.data,e);else if(e<0||t.data.length===this.config.maxPoints&&e+t.data.length>this.config.maxPoints)throw new p(c.INDEX_OUT_OF_BOUNDS(e),e)}try{this.withCallbackContext({type:"process"},()=>{this.wasmInstance.process(t.data,String(t.timestamp),t.segmentOffset??0,t.offset??0,t.fluorescenceData,t.fluorescenceMaxCount)})}catch(a){let e=String(a instanceof Error?a.message:a??"");if(e.includes("Data exceeds max points")||e.includes("Index out of bounds")){let e=this.resolveGlobalIndex(t.segmentOffset??0,t.offset??0);throw new p(c.INDEX_OUT_OF_BOUNDS(e),e)}throw a instanceof Error?a:Error(e)}finally{this.hasSegments||t.data.length===e||(this.config=this.readConfig(),this.antennaFactorData=this.wasmInstance.get_antenna_factor_view(),this.srcIndexCache=this.wasmInstance.get_src_index_cache_view(),this.clearLocalResetMirrors())}}initializeSegments(t){if(!t?.length)throw new u(c.EMPTY_SEGMENTS);this.withCallbackContext({type:"initializeSegments"},()=>{this.wasmInstance.initialize_segments(t)}),this.hasSegments=!0,this.segments=this.normalizeSegments(t),this.clearLocalResetMirrors(),this.config=this.readConfig(),this.antennaFactorData=this.wasmInstance.get_antenna_factor_view(),this.srcIndexCache=this.wasmInstance.get_src_index_cache_view()}updateSamplingRange(t,e){if(t<0||t>=e)throw new u(c.INVALID_SAMPLING_RANGE);let a=this.withCallbackContext({type:"updateSamplingRange"},()=>this.wasmInstance.update_sampling_range(t,e));return this.srcIndexCache=a,this.config=this.readConfig(),a}reset(t){this.withCallbackContext({type:"reset"},()=>{this.wasmInstance.reset(t??!1)}),this.clearLocalResetMirrors(),this.antennaFactorData=this.wasmInstance.get_antenna_factor_view(),this.srcIndexCache=this.wasmInstance.get_src_index_cache_view(),this.config=this.readConfig()}setAntennaFactor(t){let e=t instanceof Float32Array?t:new Float32Array(t);e.length!==this.config.maxPoints&&console.warn(c.INVALID_ANTENNA_FACTOR_LENGTH(this.config.maxPoints));let a=!1;for(let t=0;t<e.length;t++)if(!(Number.isFinite(e[t])&&e[t]>0)){a=!0;break}a&&console.warn(c.INVALID_ANTENNA_FACTOR),this.wasmInstance.set_antenna_factor(e),this.antennaFactorData=this.wasmInstance.get_antenna_factor_view()}setAntennaFactorSwitch(t){this.withCallbackContext({type:"setAntennaFactorSwitch"},()=>{this.wasmInstance.set_antenna_factor_switch(t)}),this.antennaFactorSwitch=t}setRealData(t){this.withCallbackContext({type:"setRealData"},()=>{this.wasmInstance.set_real_data(t,String(t.timestamp))})}setMaxData(t){this.withCallbackContext({type:"setMaxData"},()=>{this.wasmInstance.set_max_data(t)})}setMinData(t){this.withCallbackContext({type:"setMinData"},()=>{this.wasmInstance.set_min_data(t)})}setAvgData(t){this.withCallbackContext({type:"setAvgData"},()=>{this.wasmInstance.set_avg_data(t)})}setWaterfallData(t){this.withCallbackContext({type:"setWaterfallData"},()=>{this.wasmInstance.set_waterfall_data(t)}),this.config=this.readConfig()}setTemplateData(t,e){if(t&&0!==t.length){let a=t instanceof Float32Array?t:new Float32Array(t);this.templateDataRaw=new Float32Array(a),this.withCallbackContext({type:"setTemplateData"},()=>{this.wasmInstance.set_template_data(a,e)})}else{this.templateDataRaw=new Float32Array(0),this.withCallbackContext({type:"setTemplateData"},()=>{this.wasmInstance.set_template_data(void 0,void 0)});return}void 0!==e&&(this.config=this.readConfig())}setOccupancyData(t){if(t&&0!==t.length){let e=t instanceof Float32Array?t:new Float32Array(t);this.withCallbackContext({type:"setOccupancyData"},()=>{this.wasmInstance.set_occupancy_data(e)})}else this.withCallbackContext({type:"setOccupancyData"},()=>{this.wasmInstance.set_occupancy_data(void 0)})}setBackgroundNoiseData(t){if(t&&0!==t.length){let e=t instanceof Float32Array?t:new Float32Array(t);this.backgroundNoiseDataRaw=new Float32Array(e),this.withCallbackContext({type:"setBackgroundNoiseData"},()=>{this.wasmInstance.set_background_noise_data(e)})}else this.backgroundNoiseDataRaw=new Float32Array(0),this.withCallbackContext({type:"setBackgroundNoiseData"},()=>{this.wasmInstance.set_background_noise_data(void 0)})}setThresholdData(t,e){if(t&&0!==t.length){let a,s,n=t instanceof Float32Array?t:new Float32Array(t),r=0;if(e){let t=this.resolveGlobalIndex(e.segmentOffset??0,e.offset??0);this.validateSegmentInput(n,t),this.thresholdDataRaw.length===this.config.maxPoints?(s=new Float32Array(this.thresholdDataRaw.subarray(t,t+n.length)),r=t):(a=this.thresholdDataRaw,this.thresholdDataRaw=new Float32Array(this.config.maxPoints),this.thresholdDataRaw.fill(i.INITIAL_VALUE),a.length>0&&this.thresholdDataRaw.set(a.subarray(0,this.config.maxPoints))),this.thresholdDataRaw.set(n,t)}else a=this.thresholdDataRaw,this.thresholdDataRaw=new Float32Array(this.config.maxPoints),this.thresholdDataRaw.fill(i.INITIAL_VALUE),this.thresholdDataRaw.set(n.subarray(0,this.config.maxPoints));try{this.withCallbackContext({type:"setThresholdData"},()=>{this.wasmInstance.set_threshold_data(n,e?e.segmentOffset??0:void 0,e?e.offset??0:void 0)})}catch(t){throw a?this.thresholdDataRaw=a:s&&this.thresholdDataRaw.set(s,r),t}}else this.thresholdDataRaw=new Float32Array(0),this.withCallbackContext({type:"setThresholdData"},()=>{this.wasmInstance.set_threshold_data(void 0,void 0,void 0)})}setExtraData(t,e=d.MERGE,a){if(e===d.CLEAR){this.extraData={},this.withCallbackContext({type:"setExtraData",mode:e},()=>{this.wasmInstance.set_extra_data(null,e,void 0,void 0)});return}if(!t){e===d.REPLACE&&(this.extraData={},this.withCallbackContext({type:"setExtraData",mode:e},()=>{this.wasmInstance.set_extra_data(null,e,void 0,void 0)}));return}let s=Object.entries(t).map(([t,e])=>[t,e?.length?new Float32Array(e):null]),n=a?this.resolveGlobalIndex(a.segmentOffset??0,a.offset??0):0;if(a)for(let[,t]of s)t&&this.validateSegmentInput(t,n);for(let[t,r]of(e===d.REPLACE&&(this.extraData={}),s)){if(!r){delete this.extraData[t];continue}if(!a){this.extraData[t]=this.normalizeSeriesData(r);continue}let e=this.extraData[t];if(e?.length!==this.config.maxPoints){let a=new Float32Array(this.config.maxPoints);a.fill(i.INITIAL_VALUE),e?.length&&a.set(e.subarray(0,this.config.maxPoints)),e=a,this.extraData[t]=e}e.set(r,n)}this.withCallbackContext({type:"setExtraData",mode:e},()=>{this.wasmInstance.set_extra_data(t,e,a?.segmentOffset,a?.offset)})}getPerformanceMetrics(){return this.wasmInstance.get_performance_metrics()}updateProcessing(t){this.withCallbackContext({type:"updateProcessing"},()=>{this.wasmInstance.update_processing(t)}),this.config=this.readConfig()}clearMetricsData(){this.withCallbackContext({type:"clearMetricsData"},()=>{this.wasmInstance.clear_metrics_data()})}getPeakStats(){let t=this.wasmInstance.get_peak_stats();if(null!=t)return t}setFluorescenceData(t,e){this.withCallbackContext({type:"setFluorescenceData"},()=>{this.wasmInstance.set_fluorescence_data(t,e)})}getAllRawData(t){return this.wasmInstance.get_all_raw_data(t)}}export{u as DataValidationError,c as ERROR_MESSAGES,p as IndexOutOfBoundsError,U as LevelStreamAnalyzer,i as SPECTRUM,n as SeriesManager,P as SpectrumAnalyzer,m as SpectrumError,b as WaterfallAnalyzer,F as initWasm,k as isWasmReady,d as ExtraDataMode,e as GraphicType,t as OrientationType,a as SeriesEventType};