di usage in website
This commit is contained in:
88
apps/website/lib/di/hooks/useInject.ts
Normal file
88
apps/website/lib/di/hooks/useInject.ts
Normal file
@@ -0,0 +1,88 @@
|
||||
'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<T extends symbol>(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);
|
||||
} catch (error) {
|
||||
console.error(`Failed to resolve token ${token.toString()}:`, error);
|
||||
throw error;
|
||||
}
|
||||
}, [container, token]) as any;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook to get multiple services at once
|
||||
*
|
||||
* @example
|
||||
* const [leagueService, driverService] = useInjectMany([
|
||||
* LEAGUE_SERVICE_TOKEN,
|
||||
* DRIVER_SERVICE_TOKEN
|
||||
* ]);
|
||||
*/
|
||||
export function useInjectMany<T extends any[]>(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>('Service');
|
||||
*/
|
||||
export function useInjectAll<T>(serviceIdentifier: string | symbol): T[] {
|
||||
const container = useContext(ContainerContext);
|
||||
|
||||
if (!container) {
|
||||
throw new Error('useInjectAll must be used within ContainerProvider');
|
||||
}
|
||||
|
||||
return useMemo(() => {
|
||||
return container.getAll<T>(serviceIdentifier);
|
||||
}, [container, serviceIdentifier]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook for optional service injection (returns null if not found)
|
||||
*
|
||||
* @example
|
||||
* const optionalService = useInjectOptional(MAYBE_SERVICE_TOKEN);
|
||||
*/
|
||||
export function useInjectOptional<T>(token: symbol): T | null {
|
||||
const container = useContext(ContainerContext);
|
||||
|
||||
if (!container) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return useMemo(() => {
|
||||
try {
|
||||
return container.get<T>(token);
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}, [container, token]);
|
||||
}
|
||||
39
apps/website/lib/di/hooks/useReactQueryWithApiError.ts
Normal file
39
apps/website/lib/di/hooks/useReactQueryWithApiError.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
import { UseQueryResult } from '@tanstack/react-query';
|
||||
import { ApiError } from '@/lib/api/base/ApiError';
|
||||
|
||||
/**
|
||||
* Converts React-Query error to ApiError for StateContainer compatibility
|
||||
* This eliminates the need to repeat error conversion logic in every hook
|
||||
*/
|
||||
export function convertToApiError(error: any): ApiError | null {
|
||||
if (!error) return null;
|
||||
|
||||
if (error instanceof ApiError) {
|
||||
return error;
|
||||
}
|
||||
|
||||
return new ApiError(
|
||||
error.message || 'An unexpected error occurred',
|
||||
'UNKNOWN_ERROR',
|
||||
{ timestamp: new Date().toISOString() },
|
||||
error instanceof Error ? error : undefined
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to enhance React-Query result with ApiError conversion
|
||||
* Returns the same structure as before but with DRY error handling
|
||||
*/
|
||||
export function enhanceQueryResult<TData, TError = any>(
|
||||
queryResult: UseQueryResult<TData, TError>
|
||||
) {
|
||||
const apiError = convertToApiError(queryResult.error);
|
||||
|
||||
return {
|
||||
...queryResult,
|
||||
error: apiError, // Directly return ApiError for StateContainer compatibility
|
||||
retry: async () => {
|
||||
await queryResult.refetch();
|
||||
},
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user