This commit is contained in:
Ben Floyd 2025-11-10 12:41:52 -07:00
parent c62087036a
commit 51b37d4c47
7 changed files with 106 additions and 29 deletions

View file

@ -1,11 +1,27 @@
// Mock implementation of Obsidian API for Jest tests
// This provides minimal implementations of the classes and types used in tests
export interface MockPlugins {
plugins: Record<string, unknown>;
}
export interface MockCommands {
commands: Record<string, unknown>;
}
export interface MockVault {
[key: string]: unknown;
}
export interface MockWorkspace {
[key: string]: unknown;
}
export class App {
plugins: any;
commands: any;
vault: any;
workspace: any;
plugins: MockPlugins;
commands: MockCommands;
vault: MockVault;
workspace: MockWorkspace;
constructor() {
this.plugins = {
@ -19,9 +35,13 @@ export class App {
}
}
export interface MockSettings {
[key: string]: unknown;
}
export class Plugin {
app: App;
settings: any;
settings: MockSettings;
constructor(app: App) {
this.app = app;
@ -51,9 +71,18 @@ export class TFolder {
}
}
export interface MockView {
getViewType: () => string;
[key: string]: unknown;
}
export interface MockViewState {
[key: string]: unknown;
}
export class WorkspaceLeaf {
view: any;
viewState: any;
view: MockView;
viewState: MockViewState;
constructor() {
this.view = {
@ -62,7 +91,7 @@ export class WorkspaceLeaf {
this.viewState = {};
}
async setViewState(state: any): Promise<void> {
async setViewState(state: MockViewState): Promise<void> {
this.viewState = state;
}

View file

@ -4,11 +4,12 @@
import { eventBus, EVENTS } from './event-bus';
import { centralizedLogger } from './centralized-logger';
import { ErrorData } from './types';
export interface ErrorContext {
service: string;
method: string;
data?: any;
data?: ErrorData;
timestamp: number;
}
@ -74,7 +75,7 @@ export class ErrorHandler {
this.handleError(error, {
service,
method,
data: args,
data: { args },
timestamp: Date.now()
});
throw error;
@ -86,7 +87,7 @@ export class ErrorHandler {
this.handleError(error as Error, {
service,
method,
data: args,
data: { args },
timestamp: Date.now()
});
throw error;
@ -107,7 +108,7 @@ export class ErrorHandler {
this.handleError(error, {
service,
method,
data: args,
data: { args },
timestamp: Date.now()
});
throw error;
@ -138,7 +139,7 @@ export class ErrorHandler {
export const errorHandler = ErrorHandler.getInstance();
// Utility function for easy error handling
export function handleError(error: Error, service: string, method: string, data?: any): void {
export function handleError(error: Error, service: string, method: string, data?: ErrorData): void {
errorHandler.handleError(error, {
service,
method,

View file

@ -4,10 +4,11 @@
*/
import { centralizedLogger } from './centralized-logger';
import { EventData } from './types';
export interface EventBusEvent {
type: string;
data?: any;
data?: EventData;
timestamp: number;
source: string;
}
@ -44,7 +45,7 @@ export class EventBus {
/**
* Emit an event
*/
emit(eventType: string, data?: any, source: string = 'unknown'): void {
emit(eventType: string, data?: EventData, source: string = 'unknown'): void {
const event: EventBusEvent = {
type: eventType,
data,

View file

@ -2,11 +2,17 @@
* Performance Monitoring System
*/
import { ErrorData } from './types';
export interface PerformanceMetadata {
[key: string]: unknown;
}
export interface PerformanceMetric {
name: string;
duration: number;
timestamp: number;
metadata?: any;
metadata?: PerformanceMetadata;
}
export class PerformanceMonitor {
@ -41,7 +47,7 @@ export class PerformanceMonitor {
/**
* Record a performance metric
*/
recordMetric(name: string, duration: number, metadata?: any): void {
recordMetric(name: string, duration: number, metadata?: PerformanceMetadata): void {
if (!this.isEnabled) return;
this.metrics.push({
@ -63,7 +69,7 @@ export class PerformanceMonitor {
measure<T extends (...args: any[]) => any>(
fn: T,
name: string,
metadata?: any
metadata?: PerformanceMetadata
): T {
return ((...args: any[]) => {
const endTiming = this.startTiming(name);
@ -92,7 +98,7 @@ export class PerformanceMonitor {
measureAsync<T extends (...args: any[]) => Promise<any>>(
fn: T,
name: string,
metadata?: any
metadata?: PerformanceMetadata
): T {
return ((...args: any[]) => {
const endTiming = this.startTiming(name);
@ -177,7 +183,7 @@ export const performanceMonitor = PerformanceMonitor.getInstance();
export function measurePerformance<T extends (...args: any[]) => any>(
fn: T,
name: string,
metadata?: any
metadata?: PerformanceMetadata
): T {
return performanceMonitor.measure(fn, name, metadata);
}
@ -185,7 +191,7 @@ export function measurePerformance<T extends (...args: any[]) => any>(
export function measureAsyncPerformance<T extends (...args: any[]) => Promise<any>>(
fn: T,
name: string,
metadata?: any
metadata?: PerformanceMetadata
): T {
return performanceMonitor.measureAsync(fn, name, metadata);
}

View file

@ -35,3 +35,41 @@ export interface StreamsSettings {
debugLoggingEnabled: boolean; // Whether debug logging is enabled by default
barStyle: 'default' | 'modern'; // Style variant for the streams bar
}
// Event Data Types for type-safe event payloads
export type EventData =
// Stream events
| { stream: Stream } // STREAM_ADDED, STREAM_UPDATED
| { streamId: string } // STREAM_REMOVED
| { streamId: string; previousStreamId?: string } // ACTIVE_STREAM_CHANGED
| { streamId: string; disabled: boolean } // STREAM_UPDATED (disabled state)
// Settings events
| StreamsSettings // SETTINGS_CHANGED
// UI events
| { component: string } // CALENDAR_COMPONENT_UPDATED, RIBBON_ICONS_UPDATED
// File events
| { filePath: string } // FILE_OPENED, FILE_CREATED
// Plugin events
| { plugin: any } // PLUGIN_LOADED, PLUGIN_UNLOADED (using any for Obsidian plugin type)
// Error events
| { error: Error; service: string; method: string; data?: ErrorData } // ERROR_OCCURRED
// Date events
| { date: Date; monthView?: Date } // date-changed
// View events
| any; // Fallback for custom view events
// Error Data Types for type-safe error context
export interface ErrorData {
[key: string]: unknown;
}
// Log Types for type-safe logging
export type LogMessage = string | number | boolean | null | undefined;
export type LogParams = (LogMessage | object | Error)[];

View file

@ -204,9 +204,9 @@ export class CalendarNavigationService extends SettingsAwareSliceService impleme
public updateAllStreamsBarComponents = measurePerformance((): void => {
if (this.isInitializing) return;
this.refreshStreamsBarComponentsForNewViews();
}, 'calendar-navigation', 'updateAllStreamsBarComponents');
}, 'calendar-navigation', { operation: 'updateAllStreamsBarComponents' });
public refreshAllStreamsBarComponents(): void {
this.refreshStreamsBarComponentsForNewViews();

View file

@ -1,3 +1,5 @@
import { LogMessage, LogParams } from '../../shared/types';
export enum LogLevel {
ERROR = 0,
WARN = 1,
@ -66,28 +68,28 @@ export class Logger {
}
debug(message?: any, ...optionalParams: any[]): void {
debug(message?: LogMessage, ...optionalParams: LogParams): void {
if (!this.enabled || this.level > LogLevel.DEBUG) {
return;
}
console.debug(this.prefix + message, ...optionalParams);
}
info(message?: any, ...optionalParams: any[]): void {
info(message?: LogMessage, ...optionalParams: LogParams): void {
if (!this.enabled || this.level > LogLevel.INFO) {
return;
}
console.log(this.prefix + message, ...optionalParams);
}
warn(message?: any, ...optionalParams: any[]): void {
warn(message?: LogMessage, ...optionalParams: LogParams): void {
if (!this.enabled || this.level > LogLevel.WARN) {
return;
}
console.warn(this.prefix + message, ...optionalParams);
}
error(message?: any, ...optionalParams: any[]): void {
error(message?: LogMessage, ...optionalParams: LogParams): void {
if (!this.enabled || this.level > LogLevel.ERROR) {
return;
}
@ -95,7 +97,7 @@ export class Logger {
}
trace(message?: any, ...optionalParams: any[]): void {
trace(message?: LogMessage, ...optionalParams: LogParams): void {
if (this.enabled) {
console.trace(this.prefix + message, ...optionalParams);
}
@ -113,7 +115,7 @@ export class Logger {
}
}
table(tabularData: any, properties?: string[]): void {
table(tabularData: unknown, properties?: string[]): void {
if (this.enabled) {
console.table(tabularData, properties);
}