@sailboat-computer/data-storage
Version:
Shared data storage library for sailboat computer v3
199 lines • 6.83 kB
JavaScript
;
/**
* 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