'use client'; import { useContext, useMemo } from 'react'; import { ContainerContext } from '../providers/ContainerProvider'; /** * Primary injection hook - gets a service by token * * @example * const leagueService = useInject(LEAGUE_SERVICE_TOKEN); */ export function useInject(token: T): T extends { type: infer U } ? U : unknown { const container = useContext(ContainerContext); if (!container) { throw new Error('useInject must be used within ContainerProvider'); } return useMemo(() => { try { return container.get(token) as T extends { type: infer U } ? U : unknown; } catch (error) { console.error(`Failed to resolve token ${token.toString()}:`, error); throw error; } }, [container, token]); } /** * Hook to get multiple services at once * * @example * const [leagueService, driverService] = useInjectMany([ * LEAGUE_SERVICE_TOKEN, * DRIVER_SERVICE_TOKEN * ]); */ export function useInjectMany(tokens: symbol[]): T { const container = useContext(ContainerContext); if (!container) { throw new Error('useInjectMany must be used within ContainerProvider'); } return useMemo(() => { return tokens.map(token => container.get(token)) as T; }, [container, tokens]); } /** * Hook to get all services of a given type (tag-based resolution) * * @example * const allServices = useInjectAll('Service'); */ export function useInjectAll(serviceIdentifier: string | symbol): T[] { const container = useContext(ContainerContext); if (!container) { throw new Error('useInjectAll must be used within ContainerProvider'); } return useMemo(() => { return container.getAll(serviceIdentifier); }, [container, serviceIdentifier]); } /** * Hook for optional service injection (returns null if not found) * * @example * const optionalService = useInjectOptional(MAYBE_SERVICE_TOKEN); */ export function useInjectOptional(token: symbol): T | null { const container = useContext(ContainerContext); if (!container) { return null; } return useMemo(() => { try { return container.get(token); } catch { return null; } }, [container, token]); }