@@ -3,6 +3,7 @@ import { Config, AppState, DOM } from './config.js';
33import { Alert } from './alert.js' ;
44import { messenger } from './bus.js' ;
55import { projectManager } from './projectmanager.js' ;
6+ import { dbManager } from './dbmanager.js' ;
67
78/**
89 * DataProcessor Module
@@ -40,7 +41,6 @@ class DataProcessor {
4041 Config . ANOMALY_TEMPLATES = providedTemplates ;
4142 } catch ( error ) {
4243 console . error ( 'Config Loader:' , error ) ;
43- // Fallback to safe state
4444 try {
4545 Config . ANOMALY_TEMPLATES = { } ;
4646 } catch ( e ) {
@@ -69,17 +69,16 @@ class DataProcessor {
6969 files . forEach ( ( file ) => {
7070 const reader = new FileReader ( ) ;
7171
72- reader . onload = ( e ) => {
72+ reader . onload = async ( e ) => {
7373 try {
7474 let rawData ;
7575 if ( file . name . endsWith ( '.csv' ) ) {
7676 const parsedCSV = this . #parseCSV( e . target . result ) ;
77- // Normalize "Wide" CSVs (exported from app) to "Long" format
7877 rawData = this . #normalizeWideCSV( parsedCSV ) ;
7978 } else {
8079 rawData = JSON . parse ( e . target . result ) ;
8180 }
82- this . #process( rawData , file . name ) ;
81+ await this . #process( rawData , file . name ) ;
8382 } catch ( err ) {
8483 const msg = `Error parsing ${ file . name } : ${ err . message } ` ;
8584 console . error ( msg ) ;
@@ -100,8 +99,8 @@ class DataProcessor {
10099 * @param {Array } data - Array of {s, t, v} points
101100 * @param {string } fileName - Source file identifier
102101 */
103- process ( data , fileName ) {
104- const result = this . #process( data , fileName ) ;
102+ async process ( data , fileName ) {
103+ const result = await this . #process( data , fileName ) ;
105104 this . #finalizeBatchLoad( ) ;
106105 return result ;
107106 }
@@ -110,17 +109,15 @@ class DataProcessor {
110109 * Processes raw telemetry array into a structured log entry.
111110 * @private
112111 */
113- #process( data , fileName ) {
112+ async #process( data , fileName ) {
114113 try {
115114 if ( ! Array . isArray ( data ) ) throw new Error ( 'Input data must be an array' ) ;
116115
117116 let telemetryPoints = data ;
118117 let fileMetadata = { } ;
119118
120- // Check if the first element is a metadata block
121119 if ( data . length > 0 && data [ 0 ] . metadata ) {
122120 fileMetadata = data [ 0 ] . metadata ;
123- // The rest of the array is the actual telemetry data
124121 telemetryPoints = data . slice ( 1 ) ;
125122 }
126123
@@ -134,7 +131,7 @@ class DataProcessor {
134131 // Detect schema based on the first actual data point
135132 const schema = this . #detectSchema( telemetryPoints [ 0 ] ) ;
136133
137- // CHANGED: Use flatMap to handle 1-to-many expansion (e.g. Object -> Multiple Signals)
134+ // Use flatMap to handle 1-to-many expansion (e.g. Object -> Multiple Signals)
138135 const processedPoints = telemetryPoints . flatMap ( ( item ) =>
139136 this . #applyMappingAndCleaning( item , schema )
140137 ) ;
@@ -145,10 +142,33 @@ class DataProcessor {
145142 result . metadata = fileMetadata ;
146143 result . size = telemetryPoints . length ;
147144
148- AppState . files . push ( result ) ;
145+ // --- CHANGED: Check for duplicates in Library before saving ---
146+ const allLibraryFiles = await dbManager . getAllFiles ( ) ;
147+ const existingFile = allLibraryFiles . find (
148+ ( f ) => f . name === fileName && f . size === result . size
149+ ) ;
150+
151+ if ( existingFile ) {
152+ console . log (
153+ `File '${ fileName } ' already exists in library (ID: ${ existingFile . id } ). Skipping DB save.`
154+ ) ;
155+ result . dbId = existingFile . id ;
156+ } else {
157+ const dbId = await dbManager . saveTelemetry ( result ) ;
158+ result . dbId = dbId ;
159+ }
160+
161+ const isAlreadyInSession = AppState . files . some (
162+ ( f ) => f . dbId === result . dbId
163+ ) ;
164+ if ( ! isAlreadyInSession ) {
165+ AppState . files . push ( result ) ;
166+ }
149167
168+ // Register with project manager (it handles its own duplicate checks for resources)
150169 projectManager . registerFile ( {
151170 name : fileName ,
171+ dbId : result . dbId ,
152172 size : result . size ,
153173 metadata : result . metadata ,
154174 } ) ;
@@ -265,15 +285,15 @@ class DataProcessor {
265285
266286 const keys = Object . keys ( rows [ 0 ] ) ;
267287
268- // 1. If it already has the standard columns, return as is.
288+ // If it already has the standard columns, return as is.
269289 if (
270290 keys . includes ( 'SensorName' ) &&
271291 ( keys . includes ( 'Time_ms' ) || keys . includes ( 'time' ) )
272292 ) {
273293 return rows ;
274294 }
275295
276- // 2. Detect Time Column
296+ // Detect Time Column
277297 const timeKey = keys . find ( ( k ) => k . toLowerCase ( ) . includes ( 'time' ) ) ;
278298 if ( ! timeKey ) return rows ;
279299
0 commit comments