diff --git a/src/components/app/AppBootstrap.tsx b/src/components/app/AppBootstrap.tsx
index 5474945..feb6c51 100644
--- a/src/components/app/AppBootstrap.tsx
+++ b/src/components/app/AppBootstrap.tsx
@@ -1,37 +1,11 @@
-import { useEffect, useState } from 'react'
import { BrowserRouter } from 'react-router-dom'
import AppLayout from '@/components/app/AppLayout'
import LoadingScreen from '@/components/app/LoadingScreen'
-import { useComponentTreeLoader } from '@/hooks/use-component-tree-loader'
-import { useSeedData } from '@/hooks/data/use-seed-data'
-import { preloadCriticalComponents } from '@/lib/component-registry'
+import { useAppBootstrap } from '@/hooks/use-app-bootstrap'
export default function AppBootstrap() {
- const { loadSeedData } = useSeedData()
- const { loadComponentTrees } = useComponentTreeLoader()
- const [appReady, setAppReady] = useState(false)
-
- useEffect(() => {
- const timer = setTimeout(() => {
- setAppReady(true)
- }, 100)
-
- loadSeedData()
- .then(() => loadComponentTrees())
- .catch(err => {
- console.error('[APP_ROUTER] ❌ Seed data loading failed:', err)
- })
- .finally(() => {
- clearTimeout(timer)
- setAppReady(true)
- preloadCriticalComponents()
- })
-
- return () => {
- clearTimeout(timer)
- }
- }, [loadSeedData, loadComponentTrees])
+ const { appReady } = useAppBootstrap({ loadComponentTrees: true })
if (!appReady) {
return
diff --git a/src/components/app/AppRouterBootstrap.tsx b/src/components/app/AppRouterBootstrap.tsx
index 83cb1f7..c2d8b2f 100644
--- a/src/components/app/AppRouterBootstrap.tsx
+++ b/src/components/app/AppRouterBootstrap.tsx
@@ -1,34 +1,11 @@
-import { useEffect, useState } from 'react'
import { BrowserRouter } from 'react-router-dom'
import AppRouterLayout from '@/components/app/AppRouterLayout'
import LoadingScreen from '@/components/app/LoadingScreen'
-import { useSeedData } from '@/hooks/data/use-seed-data'
-import { preloadCriticalComponents } from '@/lib/component-registry'
+import { useAppBootstrap } from '@/hooks/use-app-bootstrap'
export default function AppRouterBootstrap() {
- const { loadSeedData } = useSeedData()
- const [appReady, setAppReady] = useState(false)
-
- useEffect(() => {
- const timer = setTimeout(() => {
- setAppReady(true)
- }, 100)
-
- loadSeedData()
- .catch(err => {
- console.error('[APP_ROUTER] ❌ Seed data loading failed:', err)
- })
- .finally(() => {
- clearTimeout(timer)
- setAppReady(true)
- preloadCriticalComponents()
- })
-
- return () => {
- clearTimeout(timer)
- }
- }, [loadSeedData])
+ const { appReady } = useAppBootstrap()
if (!appReady) {
return
diff --git a/src/hooks/use-app-bootstrap.ts b/src/hooks/use-app-bootstrap.ts
new file mode 100644
index 0000000..c70fc35
--- /dev/null
+++ b/src/hooks/use-app-bootstrap.ts
@@ -0,0 +1,51 @@
+import { useEffect, useState } from 'react'
+
+import { useSeedData } from '@/hooks/data/use-seed-data'
+import { useComponentTreeLoader } from '@/hooks/use-component-tree-loader'
+import { preloadCriticalComponents } from '@/lib/component-registry'
+
+type AppBootstrapOptions = {
+ loadComponentTrees?: boolean
+}
+
+export function useAppBootstrap({ loadComponentTrees = false }: AppBootstrapOptions = {}) {
+ const { loadSeedData } = useSeedData()
+ const { loadComponentTrees: loadTrees } = useComponentTreeLoader({ autoLoad: false })
+ const [appReady, setAppReady] = useState(false)
+
+ useEffect(() => {
+ let isMounted = true
+ const timer = setTimeout(() => {
+ if (isMounted) {
+ setAppReady(true)
+ }
+ }, 100)
+
+ const runBootstrap = async () => {
+ try {
+ await loadSeedData()
+ if (loadComponentTrees) {
+ await loadTrees()
+ }
+ } catch (err) {
+ console.error('[APP_BOOTSTRAP] ❌ Bootstrap loading failed:', err)
+ } finally {
+ if (!isMounted) {
+ return
+ }
+ clearTimeout(timer)
+ setAppReady(true)
+ preloadCriticalComponents()
+ }
+ }
+
+ runBootstrap()
+
+ return () => {
+ isMounted = false
+ clearTimeout(timer)
+ }
+ }, [loadSeedData, loadTrees, loadComponentTrees])
+
+ return { appReady }
+}
diff --git a/src/hooks/use-component-tree-loader.ts b/src/hooks/use-component-tree-loader.ts
index 5f2bb3d..123f4b8 100644
--- a/src/hooks/use-component-tree-loader.ts
+++ b/src/hooks/use-component-tree-loader.ts
@@ -1,10 +1,14 @@
///
-import { useCallback, useState, useEffect } from 'react'
+import { useCallback, useEffect, useState } from 'react'
import { ComponentTree } from '@/types/project'
import componentTreesData from '@/config/component-trees'
-export function useComponentTreeLoader() {
+type ComponentTreeLoaderOptions = {
+ autoLoad?: boolean
+}
+
+export function useComponentTreeLoader({ autoLoad = true }: ComponentTreeLoaderOptions = {}) {
const [isLoaded, setIsLoaded] = useState(false)
const [isLoading, setIsLoading] = useState(false)
const [error, setError] = useState(null)
@@ -105,8 +109,10 @@ export function useComponentTreeLoader() {
}, [])
useEffect(() => {
- loadComponentTrees()
- }, [])
+ if (autoLoad) {
+ loadComponentTrees()
+ }
+ }, [autoLoad, loadComponentTrees])
return {
isLoaded,