diff --git a/src/core/index.ts b/src/core/index.ts index ad92698..752c952 100644 --- a/src/core/index.ts +++ b/src/core/index.ts @@ -61,3 +61,10 @@ export { isValidTimestamp, } from './guards'; +// Metrics +export { + type PerformanceMetric, + type MetricsCollector, + InMemoryMetricsCollector, +} from './metrics'; + diff --git a/src/core/metrics.ts b/src/core/metrics.ts new file mode 100644 index 0000000..5d991f8 --- /dev/null +++ b/src/core/metrics.ts @@ -0,0 +1,59 @@ +/** + * Core Metrics + * + * Performance metrics contract and lightweight collector. + * Platform-agnostic, no dependencies. + * + * @author Matthew Raymer + * @version 1.0.0 + */ + +/** + * Performance metric entry + */ +export interface PerformanceMetric { + /** Operation name (e.g., 'schedule.create', 'recovery.coldStart') */ + operation: string; + /** Duration in milliseconds */ + duration: number; + /** Timestamp when metric was recorded (milliseconds since epoch) */ + timestamp: number; + /** Whether operation succeeded */ + success: boolean; + /** Optional metadata */ + metadata?: Record; +} + +/** + * Metrics collector interface + */ +export interface MetricsCollector { + record(metric: PerformanceMetric): void; + getMetrics(): PerformanceMetric[]; + clear(): void; +} + +/** + * Lightweight in-memory metrics collector + * No dependencies, platform-agnostic + */ +export class InMemoryMetricsCollector implements MetricsCollector { + private metrics: PerformanceMetric[] = []; + private maxMetrics = 100; + + record(metric: PerformanceMetric): void { + this.metrics.push(metric); + if (this.metrics.length > this.maxMetrics) { + this.metrics = this.metrics.slice(-this.maxMetrics); + } + } + + getMetrics(): PerformanceMetric[] { + return [...this.metrics]; + } + + clear(): void { + this.metrics = []; + } +} + diff --git a/src/web.ts b/src/web.ts index 3acfe11..87369a4 100644 --- a/src/web.ts +++ b/src/web.ts @@ -332,14 +332,17 @@ export class DailyNotificationWeb implements DailyNotificationPlugin { } async createSchedule(_schedule: CreateScheduleInput): Promise { + // Web stub: no timing needed (throws immediately) this.throwNotSupported(); } async updateSchedule(_id: string, _updates: unknown): Promise { + // Web stub: no timing needed (throws immediately) this.throwNotSupported(); } async deleteSchedule(_id: string): Promise { + // Web stub: no timing needed (throws immediately) this.throwNotSupported(); }