/**
 * Shared singleton pattern utilities
 *
 * This module provides standardized singleton patterns that are used
 * throughout the codebase. It reduces boilerplate and ensures
 * consistent singleton management.
 */
/**
 * Storage for singleton instances
 */
const singletonStorage = new Map();
/**
 * Create a singleton getter function
 *
 * @param key - Unique key for this singleton
 * @param factory - Factory function to create the instance
 * @returns A function that returns the singleton instance
 *
 * @example
 * ```typescript
 * class MyService {
 *   constructor(config: Config) { ... }
 * }
 *
 * export const getMyService = createSingleton(
 *   'myService',
 *   (config?: Config) => new MyService(config ?? defaultConfig)
 * );
 *
 * // Usage:
 * const service = getMyService();
 * const serviceWithConfig = getMyService(customConfig); // Only used on first call
 * ```
 */
export function createSingleton(key, factory) {
    return (...args) => {
        if (!singletonStorage.has(key)) {
            singletonStorage.set(key, factory(...args));
        }
        return singletonStorage.get(key);
    };
}
/**
 * Create a singleton getter with reset capability
 *
 * @param key - Unique key for this singleton
 * @param factory - Factory function to create the instance
 * @returns Object with get and reset functions
 *
 * @example
 * ```typescript
 * const { get: getCache, reset: resetCache } = createResettableSingleton(
 *   'cache',
 *   () => new Cache()
 * );
 *
 * // Usage:
 * const cache = getCache();
 * resetCache(); // Clears the instance, next get() creates new one
 * ```
 */
export function createResettableSingleton(key, factory) {
    return {
        get: (...args) => {
            if (!singletonStorage.has(key)) {
                singletonStorage.set(key, factory(...args));
            }
            return singletonStorage.get(key);
        },
        reset: () => {
            singletonStorage.delete(key);
        },
    };
}
/**
 * Create a lazy singleton that's only created when first accessed
 *
 * @param factory - Factory function to create the instance
 * @returns Object with value getter and reset function
 *
 * @example
 * ```typescript
 * const heavyService = createLazySingleton(() => new HeavyService());
 *
 * // Service not created yet
 * // ...
 * const service = heavyService.value; // Created now
 * ```
 */
export function createLazySingleton(factory) {
    let instance;
    let created = false;
    return {
        get value() {
            if (!created) {
                instance = factory();
                created = true;
            }
            return instance;
        },
        reset() {
            instance = undefined;
            created = false;
        },
    };
}
// Note: Decorator-based @Singleton pattern removed due to TypeScript strict mode
// constraints. Use moduleSingleton() or createSingleton() instead for type-safe
// singleton patterns.
/**
 * Clear all singleton instances (useful for testing)
 */
export function clearAllSingletons() {
    singletonStorage.clear();
}
/**
 * Check if a singleton exists
 *
 * @param key - Singleton key to check
 * @returns true if singleton instance exists
 */
export function hasSingleton(key) {
    return singletonStorage.has(key);
}
/**
 * Get a singleton instance without creating it
 *
 * @param key - Singleton key
 * @returns The instance or undefined if not created
 */
export function peekSingleton(key) {
    return singletonStorage.get(key);
}
// Note: SingletonMixin removed due to TypeScript strict mode constraints with
// class extension. Use moduleSingleton() or createSingleton() instead.
/**
 * Create a module-level singleton pattern (most common use case)
 *
 * This is the simplest pattern for creating a singleton at module level.
 *
 * @param factory - Factory function to create the instance
 * @returns Singleton manager object
 *
 * @example
 * ```typescript
 * // In myService.ts
 * class MyService {
 *   constructor(private config: Config) {}
 * }
 *
 * const { getInstance, resetInstance } = moduleSingleton(
 *   () => new MyService(loadConfig())
 * );
 *
 * export { getInstance as getMyService, resetInstance as resetMyService };
 * ```
 */
export function moduleSingleton(factory) {
    let instance = null;
    return {
        getInstance() {
            if (instance === null) {
                instance = factory();
            }
            return instance;
        },
        resetInstance() {
            instance = null;
        },
        hasInstance() {
            return instance !== null;
        },
    };
}
//# sourceMappingURL=singleton.js.map