2026-01-15 18:26:53 +00:00
// CRITICAL: React must be imported first before any Zustand/react imports
2025-12-08 18:57:54 +00:00
import React from 'react' ;
import ReactDOM from 'react-dom/client' ;
2026-01-15 18:26:53 +00:00
// DEBUG: Global error handler pour capturer les erreurs d'initialisation
if ( typeof window !== 'undefined' ) {
window . addEventListener ( 'error' , ( event ) = > {
// #region agent log
if ( event . message && event . message . includes ( 'ie' ) && event . message . includes ( 'initialization' ) ) {
fetch ( 'http://127.0.0.1:7242/ingest/09c5ea5e-2380-4cc3-92aa-d26f3b3d26f6' , { method : 'POST' , headers : { 'Content-Type' : 'application/json' } , body :JSON.stringify ( { location : 'main.tsx:globalErrorHandler' , message : 'Variable ie initialization error caught' , data : { message :event.message , filename :event.filename , lineno :event.lineno , colno :event.colno , error :event.error?.stack , loadedScripts :Array.from ( document . scripts ) . map ( s = > s . src ) } , timestamp :Date.now ( ) , sessionId : 'debug-session' , runId : 'runtime' , hypothesisId : 'B' } ) } ) . catch ( ( ) = > { } ) ;
}
// #endregion
} , true ) ;
window . addEventListener ( 'unhandledrejection' , ( event ) = > {
// #region agent log
if ( event . reason && ( event . reason . message ? . includes ( 'ie' ) || event . reason . message ? . includes ( 'initialization' ) ) ) {
fetch ( 'http://127.0.0.1:7242/ingest/09c5ea5e-2380-4cc3-92aa-d26f3b3d26f6' , { method : 'POST' , headers : { 'Content-Type' : 'application/json' } , body :JSON.stringify ( { location : 'main.tsx:unhandledRejection' , message : 'Unhandled rejection with ie error' , data : { reason :event.reason?.message , stack :event.reason?.stack } , timestamp :Date.now ( ) , sessionId : 'debug-session' , runId : 'runtime' , hypothesisId : 'B' } ) } ) . catch ( ( ) = > { } ) ;
}
// #endregion
} ) ;
}
2025-12-08 18:57:54 +00:00
import { BrowserRouter } from 'react-router-dom' ;
import { QueryClient , QueryClientProvider } from '@tanstack/react-query' ;
state-utilities: update stateInvalidation to work with React Query
- Created QueryClient singleton (queryClientSingleton.ts):
- Provides global access to QueryClient for state invalidation
- Set in main.tsx after QueryClient creation
- Updated invalidateQueries() to use QueryClient directly:
- Replaced custom event system with direct QueryClient.invalidateQueries()
- Added query key mapping for all resource types
- Event system kept as fallback if QueryClient not available
- Updated invalidateStore() for Library Store:
- Removed clearItems() call (method doesn't exist, domain data migrated to React Query)
- Library Store now only contains UI state (filters)
- React Query cache invalidation handles refetching
- Query keys mapped:
- tracks: ['tracks'], ['track'], ['library']
- playlists: ['playlists'], ['playlist']
- users: ['users'], ['user'], ['auth'], ['userProfile']
- conversations: ['conversations'], ['conversation'], ['chat'], ['chatConversations']
- roles: ['roles'], ['role']
- library: ['library'], ['tracks'], ['favorites'], ['libraryItems']
- auth: ['auth'], ['user']
- Action 4.6.1.5 complete
2026-01-15 18:38:47 +00:00
// Action 4.6.1.5: Import QueryClient singleton setter
import { setQueryClient } from './utils/queryClientSingleton' ;
2026-01-15 18:26:53 +00:00
// CRITICAL FIX: Import lazy de react-hot-toast pour éviter les collisions de noms de variables après minification
import { LazyToaster } from './components/feedback/LazyToaster' ;
2025-12-08 18:57:54 +00:00
import { App } from './app/App' ;
2026-01-16 11:15:20 +00:00
import { logger } from './utils/logger' ;
2025-12-08 18:57:54 +00:00
import './index.css' ;
feat: add fusion design system foundation
- Created design-system.css with tokens from KŌDŌ, BOTANICAL, and Spectre Astral
- Added color palette (cyber neons + nature tones + space gradients)
- Implemented typography system (Orbitron, Rajdhani, Inter, Source Serif, JetBrains Mono)
- Added spacing scale, border radius, shadows, and glows
- Created keyframe animations (logo-spin, graffiti-shake, gentle-pulse, etc.)
- Added utility classes for gradients, glows, clip-paths, and hover effects
- Imported Google Fonts in index.html
- Integrated design system CSS in main.tsx
2026-01-03 22:35:02 +00:00
import './styles/design-system.css' ;
feat: add layout, navigation, and utility components
Phase 3: Layout & Navigation
- Created header.css with animated hexagonal logo
- Gradient navigation links with hover effects
- Responsive mobile menu with toggle animation
- Full mobile/tablet support
Global Effects:
- Created global-effects.css with texture overlay (graffiti wall)
- Scanline effect (gaming CRT)
- Custom scrollbar with gradient
- Focus styles and selection colors
- Page layout, container, section utilities
- Grid system (2, 3, 4 columns + auto-fit)
- Flex utilities and spacing helpers
Additional Components:
- Created Badge component (8 variants: default, cyber, neon, nature, gaming, success, warning, error)
- Created Tag component with closable option
- Created Avatar component (4 variants, 6 sizes, status indicators)
- Created AvatarGroup for stacked avatars
- All components fully typed with TypeScript
Imported all new CSS files in main.tsx
2026-01-03 23:22:06 +00:00
import './styles/global-effects.css' ;
import './styles/header.css' ;
2025-12-17 13:07:35 +00:00
// Initialize i18next before React renders
import './lib/i18n' ;
2025-12-27 00:58:49 +00:00
// FIX #20: Initialize Sentry for error tracking
import { initSentry } from './lib/sentry' ;
2025-12-25 12:37:10 +00:00
// FE-API-019: Initialize MSW for development if enabled
import { env } from './config/env' ;
2026-01-16 10:53:29 +00:00
// Action 11.2.1.4: Initialize grid overlay utility (dev only)
import { initGridOverlay } from './utils/gridOverlay' ;
2025-12-03 21:56:50 +00:00
2025-12-08 18:57:54 +00:00
// HMR Force Update: 1765126900
2025-12-03 21:56:50 +00:00
2025-12-27 00:58:49 +00:00
// FIX #20: Initialize Sentry before React renders
initSentry ( ) ;
2025-12-08 18:57:54 +00:00
const queryClient = new QueryClient ( {
defaultOptions : {
queries : {
retry : false ,
2026-01-16 13:35:42 +00:00
refetchOnWindowFocus : false , // Keep disabled (intentional - avoid unnecessary refetches)
// Edge 6.1: Handle stale data in cache - Ensure stale data refreshed appropriately
staleTime : 1 * 60 * 1000 , // Default: Consider data fresh for 1 minute (individual hooks can override)
gcTime : 5 * 60 * 1000 , // Default: Keep in cache for 5 minutes (formerly cacheTime)
refetchOnMount : true , // Refetch stale data when component mounts (ensures fresh data)
refetchOnReconnect : true , // Refetch stale data when network reconnects
2025-12-08 18:57:54 +00:00
} ,
} ,
2025-12-03 21:56:50 +00:00
} ) ;
2025-12-08 18:57:54 +00:00
state-utilities: update stateInvalidation to work with React Query
- Created QueryClient singleton (queryClientSingleton.ts):
- Provides global access to QueryClient for state invalidation
- Set in main.tsx after QueryClient creation
- Updated invalidateQueries() to use QueryClient directly:
- Replaced custom event system with direct QueryClient.invalidateQueries()
- Added query key mapping for all resource types
- Event system kept as fallback if QueryClient not available
- Updated invalidateStore() for Library Store:
- Removed clearItems() call (method doesn't exist, domain data migrated to React Query)
- Library Store now only contains UI state (filters)
- React Query cache invalidation handles refetching
- Query keys mapped:
- tracks: ['tracks'], ['track'], ['library']
- playlists: ['playlists'], ['playlist']
- users: ['users'], ['user'], ['auth'], ['userProfile']
- conversations: ['conversations'], ['conversation'], ['chat'], ['chatConversations']
- roles: ['roles'], ['role']
- library: ['library'], ['tracks'], ['favorites'], ['libraryItems']
- auth: ['auth'], ['user']
- Action 4.6.1.5 complete
2026-01-15 18:38:47 +00:00
// Action 4.6.1.5: Set QueryClient singleton for state invalidation
setQueryClient ( queryClient ) ;
2025-12-25 12:37:10 +00:00
// FE-API-019: Initialize MSW worker for development
async function enableMocking() {
if ( ! env . USE_MSW ) {
return ;
}
if ( import . meta . env . DEV ) {
const { worker } = await import ( './mocks/browser' ) ;
feat: add fusion design system foundation
- Created design-system.css with tokens from KŌDŌ, BOTANICAL, and Spectre Astral
- Added color palette (cyber neons + nature tones + space gradients)
- Implemented typography system (Orbitron, Rajdhani, Inter, Source Serif, JetBrains Mono)
- Added spacing scale, border radius, shadows, and glows
- Created keyframe animations (logo-spin, graffiti-shake, gentle-pulse, etc.)
- Added utility classes for gradients, glows, clip-paths, and hover effects
- Imported Google Fonts in index.html
- Integrated design system CSS in main.tsx
2026-01-03 22:35:02 +00:00
2025-12-25 12:37:10 +00:00
// Start the worker
await worker . start ( {
onUnhandledRequest : 'bypass' , // Don't warn about unhandled requests
serviceWorker : {
url : '/mockServiceWorker.js' ,
} ,
} ) ;
2025-12-27 00:50:39 +00:00
// FIX #18: Utiliser logger structuré
const { logger } = await import ( './utils/logger' ) ;
logger . info ( '[MSW] Mock Service Worker started' , { component : 'MSW' } ) ;
2025-12-25 12:37:10 +00:00
}
}
2026-01-15 18:26:53 +00:00
const renderApp = ( ) = > {
// #region agent log
fetch ( 'http://127.0.0.1:7242/ingest/09c5ea5e-2380-4cc3-92aa-d26f3b3d26f6' , { method : 'POST' , headers : { 'Content-Type' : 'application/json' } , body :JSON.stringify ( { location : 'main.tsx:renderApp' , message : 'Rendering app' , data : { loadedScripts :document.scripts.length } , timestamp :Date.now ( ) , sessionId : 'debug-session' , runId : 'runtime' , hypothesisId : 'C' } ) } ) . catch ( ( ) = > { } ) ;
// #endregion
2025-12-25 12:37:10 +00:00
ReactDOM . createRoot ( document . getElementById ( 'root' ) ! ) . render (
< React.StrictMode >
< QueryClientProvider client = { queryClient } >
< BrowserRouter
future = { {
v7_startTransition : true ,
v7_relativeSplatPath : true ,
} }
>
< App / >
2026-01-15 18:26:53 +00:00
< LazyToaster position = "top-right" / >
2025-12-25 12:37:10 +00:00
< / BrowserRouter >
< / QueryClientProvider >
< / React.StrictMode > ,
) ;
2026-01-15 18:26:53 +00:00
} ;
// CRITICAL FIX: Précharger react-hot-toast AVANT de rendre l'app
// pour éviter les collisions de noms de variables (ie) lors de la minification
// Le module sera chargé dans un chunk séparé, évitant les conflits
const preloadToast = import ( 'react-hot-toast' )
. then ( ( mod ) = > {
// #region agent log
fetch ( 'http://127.0.0.1:7242/ingest/09c5ea5e-2380-4cc3-92aa-d26f3b3d26f6' , { method : 'POST' , headers : { 'Content-Type' : 'application/json' } , body :JSON.stringify ( { location : 'main.tsx:preloadToast' , message : 'react-hot-toast loaded successfully' , data : { hasDefault : ! ! mod . default , hasToaster : ! ! mod . Toaster } , timestamp :Date.now ( ) , sessionId : 'debug-session' , runId : 'runtime' , hypothesisId : 'D' } ) } ) . catch ( ( ) = > { } ) ;
// #endregion
return mod ;
} )
. catch ( ( err ) = > {
// #region agent log
fetch ( 'http://127.0.0.1:7242/ingest/09c5ea5e-2380-4cc3-92aa-d26f3b3d26f6' , { method : 'POST' , headers : { 'Content-Type' : 'application/json' } , body :JSON.stringify ( { location : 'main.tsx:preloadToast' , message : 'react-hot-toast load error' , data : { error :err.message , stack :err.stack } , timestamp :Date.now ( ) , sessionId : 'debug-session' , runId : 'runtime' , hypothesisId : 'D' } ) } ) . catch ( ( ) = > { } ) ;
// #endregion
// Ignorer les erreurs de préchargement
} ) ;
// Start MSW and preload toast before rendering the app
Promise . all ( [ enableMocking ( ) , preloadToast ] )
. catch ( ( error ) = > {
2026-01-16 11:15:20 +00:00
logger . error ( '[Init] Failed to initialize; continuing' , {
error : error instanceof Error ? error.message : String ( error ) ,
stack : error instanceof Error ? error.stack : undefined ,
} ) ;
2026-01-15 18:26:53 +00:00
} )
. finally ( ( ) = > {
2026-01-16 10:53:29 +00:00
// Action 11.2.1.4: Initialize grid overlay utility (dev only)
initGridOverlay ( ) ;
2026-01-15 18:26:53 +00:00
renderApp ( ) ;
} ) ;