release: v2.33.1 - Production build and packaging

This commit is contained in:
g1nation
2026-05-01 18:04:56 +09:00
parent c366a041c5
commit 250c998293
5 changed files with 258 additions and 44 deletions
+42 -8
View File
@@ -15,6 +15,10 @@ export interface AggregateResult {
average?: number;
}
export interface AggregateOptions {
collectValues?: boolean;
}
/**
* DataProcessor:
* 시스템의 알고리즘적 효율성과 유지보수성을 극대화하기 위한 핵심 집계 엔진.
@@ -26,8 +30,14 @@ export class DataProcessor {
* @param data 집계할 데이터 배열
* @param keyPath 집계 기준이 될 속성 경로
*/
public static aggregate(data: any[], keyPath: string): AggregateResult[] {
public static aggregate(data: any[], keyPath: string, options: AggregateOptions = {}): AggregateResult[] {
if (!data || data.length === 0) return [];
if (!Array.isArray(data)) {
throw new TypeError('DataProcessor.aggregate expects data to be an array.');
}
const pathSegments = this.parseKeyPath(keyPath);
const collectValues = options.collectValues !== false;
// 1. 성능 상충 관계 (Sweet Spot) 고려:
// 데이터가 매우 작을 때는(예: N < 10) 해시 맵 생성 오버헤드가 더 클 수 있으나,
@@ -37,7 +47,7 @@ export class DataProcessor {
for (const item of data) {
try {
const keyValue = this.getNestedValue(item, keyPath);
const keyValue = this.getNestedValue(item, pathSegments);
if (keyValue === undefined || keyValue === null) continue;
const key = String(keyValue);
@@ -53,7 +63,9 @@ export class DataProcessor {
}
entry.count++;
entry.values.push(item);
if (collectValues) {
entry.values.push(item);
}
// 수치형 데이터인 경우 평균 계산을 위한 로직 (예시)
if (typeof item.value === 'number') {
@@ -74,15 +86,37 @@ export class DataProcessor {
* 데이터 분포 민감성(Data Distribution Sensitivity)을 고려한 고도화된 집계 (Trie 기반)
* 키가 매우 길거나 계층적인 경우 메모리 및 검색 속도 최적화를 위해 사용합니다.
*/
public static aggregateByTrie(data: any[], keyPath: string): AggregateResult[] {
public static aggregateByTrie(data: any[], keyPath: string, options: AggregateOptions = {}): AggregateResult[] {
// TODO: 복잡한 키 구조를 위한 Trie 인덱싱 로직 구현 (Phase 2 확장 예정)
return this.aggregate(data, keyPath);
return this.aggregate(data, keyPath, options);
}
/**
* 중첩된 객체 속성 접근 (Safety handling)
* 중첩된 객체 속성 접근 (Safety handling).
* keyPath는 루프 밖에서 한 번만 파싱하여 대규모 데이터 처리 시 반복 split 비용을 피합니다.
*/
private static getNestedValue(obj: any, path: string): any {
return path.split('.').reduce((prev, curr) => prev && prev[curr], obj);
private static getNestedValue(obj: any, pathSegments: string[]): any {
return pathSegments.reduce((prev, curr) => {
if (prev === undefined || prev === null) return undefined;
return prev[curr];
}, obj);
}
private static parseKeyPath(keyPath: string): string[] {
if (typeof keyPath !== 'string' || keyPath.trim().length === 0) {
throw new TypeError('DataProcessor.aggregate expects keyPath to be a non-empty string.');
}
const segments = keyPath.split('.').map(segment => segment.trim());
if (segments.some(segment => segment.length === 0)) {
throw new TypeError('DataProcessor.aggregate received an invalid keyPath.');
}
const forbiddenSegments = new Set(['__proto__', 'prototype', 'constructor']);
if (segments.some(segment => forbiddenSegments.has(segment))) {
throw new TypeError('DataProcessor.aggregate received an unsafe keyPath.');
}
return segments;
}
}