All files App.tsx

79.41% Statements 27/34
55.55% Branches 10/18
77.77% Functions 7/9
84.37% Lines 27/32

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71                                                67x   67x 67x   134x 134x 134x 134x 134x 67x 67x     134x               67x 66x 66x     66x                                      
/**
 * @see frontend/docs/UX/layer-contracts/L1-data-layer.md §9.2
 *   (Cache-persistointi — PersistQueryClientProvider ja onSuccess)
 * @see frontend/docs/UX/layer-contracts/L1-data-layer.md §3.4
 *   (Muistinhallinta — startCacheEviction käynnistys)
 *
 * Sovelluksen juurikomponentti. PersistQueryClientProvider hydraa
 * IndexedDB-cachen ennen renderöintiä ja käynnistää retain-eviction-
 * silmukan onSuccess-callbackissa. Kokoonpano noudattaa §9.2:n
 * mukaista startup-sekvenssiä: IndexedDB → pendingDeleteMap → eviction.
 *
 * Liittyy periaatteisiin: 8
 */
 
import { RouterProvider } from 'react-router-dom'
import { PersistQueryClientProvider } from '@tanstack/react-query-persist-client'
import { ReactQueryDevtools } from '@tanstack/react-query-devtools'
import { useEffect, useRef } from 'react'
 
import { queryClient } from '@/lib/query-client'
import { persister } from '@/lib/queryPersister'
import { startCacheEviction } from '@/lib/queryCacheEviction'
import {
  getPendingDeleteEntriesFromOutbox,
  startOutboxReplay,
} from '@/lib/mutationOutbox'
import { populatePendingDeletes, removePendingDelete } from '@/layers/L1'
import { router } from '@/router'
import { Toaster } from '@/shared/components/Toaster'
 
const enableDevtools = import.meta.env.DEV
 
export default function App() {
  const stopReplayRef = useRef<(() => void) | null>(null)
  const stopEvictionRef = useRef<(() => void) | null>(null)
 
  useEffect(() => {
    return () => {
      stopReplayRef.current?.()
      stopEvictionRef.current?.()
    }
  }, [])
 
  return (
    <PersistQueryClientProvider
      client={queryClient}
      persistOptions={{
        persister,
        maxAge: 8 * 60 * 60 * 1000,
        buster: (import.meta as unknown as Record<string, unknown>).env
          ? (import.meta as { env: Record<string, string> }).env
              .VITE_APP_VERSION ?? 'dev'
          : 'dev',
      }}
      onSuccess={async () => {
        const entries = await getPendingDeleteEntriesFromOutbox()
        populatePendingDeletes(entries)
        stopReplayRef.current = startOutboxReplay(queryClient, (entityPath, id) => {
          removePendingDelete(entityPath, id)
        })
        stopEvictionRef.current = startCacheEviction(queryClient)
      }}
    >
      <RouterProvider router={router} />
      <Toaster />
      {enableDevtools && (
        <ReactQueryDevtools buttonPosition="bottom-right" />
      )}
    </PersistQueryClientProvider>
  )
}