UNPKG

@sailboat-computer/data-storage

Version:

Shared data storage library for sailboat computer v3

199 lines 6.83 kB
"use strict"; /** * Downsampling engine implementation */ Object.defineProperty(exports, "__esModule", { value: true }); exports.createDownsamplingEngine = exports.DownsamplingEngineImpl = void 0; const errors_1 = require("../utils/errors"); /** * Downsampling engine implementation */ class DownsamplingEngineImpl { constructor() { this.rules = []; this.downsamplers = new Map(); this.initialized = false; } /** * Initialize the downsampling engine * * @param rules - Downsampling rules */ initialize(rules) { this.rules = rules; this.initialized = true; console.log('Downsampling engine initialized with', rules.length, 'rules'); } /** * Downsample data * * @param data - Data to downsample * @returns Downsampled data */ async downsample(data) { this.ensureInitialized(); if (data.length === 0) { return []; } try { // Group data by category const dataByCategory = this.groupByCategory(data); // Process each category const results = []; for (const [category, categoryData] of Object.entries(dataByCategory)) { // Find rule for category const rule = this.findRuleForCategory(category); if (!rule) { // No rule found, keep data as is results.push(...categoryData); continue; } // Get downsampler for strategy type const downsampler = this.getDownsampler(rule.strategy.type); if (!downsampler) { console.warn(`No downsampler found for strategy type ${rule.strategy.type}`); results.push(...categoryData); continue; } // Filter out critical data if conditions are specified let criticalData = []; let nonCriticalData = categoryData; if (rule.criticalDataConditions && rule.criticalDataConditions.length > 0) { [criticalData, nonCriticalData] = this.separateCriticalData(categoryData, rule.criticalDataConditions); } // Downsample non-critical data const downsampledData = await downsampler.downsample(nonCriticalData, rule.strategy); // Combine critical and downsampled data results.push(...criticalData, ...downsampledData); } return results; } catch (error) { console.error('Failed to downsample data:', error); throw new errors_1.StorageError(errors_1.StorageErrorCode.DOWNSAMPLING_FAILED, 'Failed to downsample data', { error }); } } /** * Register a downsampler * * @param downsampler - Downsampler to register */ registerDownsampler(downsampler) { this.downsamplers.set(downsampler.type, downsampler); console.log(`Registered downsampler for strategy type ${downsampler.type}`); } /** * Get a downsampler for a strategy type * * @param strategyType - Strategy type * @returns Downsampler or undefined if not found */ getDownsampler(strategyType) { return this.downsamplers.get(strategyType); } /** * Group data by category * * @param data - Data to group * @returns Data grouped by category */ groupByCategory(data) { const result = {}; for (const item of data) { const category = item.metadata.category; if (!result[category]) { result[category] = []; } result[category].push(item); } return result; } /** * Find rule for category * * @param category - Data category * @returns Downsampling rule or undefined if not found */ findRuleForCategory(category) { return this.rules.find(rule => rule.dataType === category); } /** * Separate critical data from non-critical data * * @param data - Data to separate * @param conditions - Critical data conditions * @returns Tuple of critical and non-critical data */ separateCriticalData(data, conditions) { const criticalData = []; const nonCriticalData = []; for (const item of data) { if (this.isCriticalData(item, conditions)) { criticalData.push(item); } else { nonCriticalData.push(item); } } return [criticalData, nonCriticalData]; } /** * Check if data is critical * * @param data - Data to check * @param conditions - Critical data conditions * @returns Whether data is critical */ isCriticalData(data, conditions) { // Check if any condition matches return conditions.some(condition => { const { field, operator, value } = condition; const fieldValue = data.data[field]; switch (operator) { case 'eq': return fieldValue === value; case 'neq': return fieldValue !== value; case 'gt': return fieldValue > value; case 'gte': return fieldValue >= value; case 'lt': return fieldValue < value; case 'lte': return fieldValue <= value; case 'in': return Array.isArray(value) && value.includes(fieldValue); case 'nin': return Array.isArray(value) && !value.includes(fieldValue); case 'contains': return typeof fieldValue === 'string' && fieldValue.includes(value); case 'regex': return typeof fieldValue === 'string' && new RegExp(value).test(fieldValue); default: return false; } }); } /** * Ensure downsampling engine is initialized * * @throws StorageError if not initialized */ ensureInitialized() { if (!this.initialized) { throw new errors_1.StorageError(errors_1.StorageErrorCode.SYSTEM_ERROR, 'Downsampling engine not initialized', {}); } } } exports.DownsamplingEngineImpl = DownsamplingEngineImpl; /** * Create a new downsampling engine * * @returns Downsampling engine */ function createDownsamplingEngine() { return new DownsamplingEngineImpl(); } exports.createDownsamplingEngine = createDownsamplingEngine; //# sourceMappingURL=engine.js.map