FIX - preload App Store module

Preload and cache the App Store route module when the phone shell starts so FiveM CEF does not fetch it only after the user opens the app. Cover the shared loader contract with a focused registry test.
This commit is contained in:
smx.pusha
2026-08-14 19:50:50 +02:00
parent 0e1838fb1e
commit 048e72a4ae
3 changed files with 27 additions and 5 deletions
+4 -1
View File
@@ -47,7 +47,7 @@ import { useMarketplaceStore } from '@/stores/marketplace'
import { useAppCatalogStore } from '@/stores/app-catalog'
import { useAppStoreStore } from '@/stores/app-store'
import { useWidgetsStore } from '@/stores/widgets'
import { isPhoneAppId } from '@/config/apps'
import { isPhoneAppId, loadAppStoreComponent } from '@/config/apps'
import { useNotesStore } from '@/stores/notes'
import { useMemosStore } from '@/stores/memos'
import { useWeatherStore } from '@/stores/weather'
@@ -1223,6 +1223,9 @@ onMounted(() => {
window.addEventListener('resize', updateViewportScale)
systemColorScheme.addEventListener('change', onSystemColorSchemeChange)
phone.setSystemDarkMode(systemColorScheme.matches)
void loadAppStoreComponent().catch((error: unknown) => {
console.error('[App Store] Could not preload the phone app.', error)
})
void nuiCall('ui:ready', { protocolVersion: 1 })
clockTicker = setInterval(() => {
const now = Date.now()
+9 -1
View File
@@ -1,8 +1,16 @@
import { describe, expect, it } from 'vitest'
import { Newspaper } from 'lucide-vue-next'
import { isPhoneAppId, PHONE_APPS } from './apps'
import { isPhoneAppId, loadAppStoreComponent, PHONE_APPS } from './apps'
describe('app registry', () => {
it('reuses the App Store module loaded by the phone shell', async () => {
const firstLoad = loadAppStoreComponent()
const secondLoad = loadAppStoreComponent()
expect(secondLoad).toBe(firstLoad)
expect((await firstLoad).default).toBeTruthy()
})
it('has unique ids and routes with the reference dock order', () => {
expect(new Set(PHONE_APPS.map((app) => app.id)).size).toBe(
PHONE_APPS.length,
+14 -3
View File
@@ -86,6 +86,19 @@ import type {
PhoneAppDefinition,
} from '@/types/apps'
let appStoreComponentPromise:
| ReturnType<typeof importAppStoreComponent>
| null = null
function importAppStoreComponent() {
return import('@/views/apps/AppStoreApp.vue')
}
export function loadAppStoreComponent() {
appStoreComponentPromise ??= importAppStoreComponent()
return appStoreComponentPromise
}
export const PHONE_APPS = shallowReactive<PhoneAppDefinition[]>([
{
category: 'social',
@@ -481,9 +494,7 @@ export const PHONE_APPS = shallowReactive<PhoneAppDefinition[]>([
},
{
category: 'utilities',
component: markRaw(
defineAsyncComponent(() => import('@/views/apps/AppStoreApp.vue')),
),
component: markRaw(defineAsyncComponent(loadAppStoreComponent)),
dockOrder: null,
gridOrder: 9,
icon: markRaw(ShoppingBag),