feat: make bundled native runtime the default

This commit is contained in:
reaper
2026-08-28 01:00:50 -05:00
parent 7d36546266
commit a5e942f1f9
6 changed files with 65 additions and 10 deletions
@@ -16,14 +16,39 @@ const wordpress: AuroraModuleManifest = {
aurora: { core: '2.0.0-alpha.24', moduleApi: '1.0.0' }
}
function renderModal(modules: AuroraModuleManifest[]): { queryClient: QueryClient } {
function renderModal(
modules: AuroraModuleManifest[],
nativeAvailable = false
): { queryClient: QueryClient } {
vi.stubGlobal('api', {
modules: { listRegistry: vi.fn().mockResolvedValue(modules) },
runtime: {
status: vi.fn().mockResolvedValue({
selectedEngine: nativeAvailable ? 'native' : 'container',
container: { available: false, provider: null },
native: {
available: nativeAvailable,
platform: 'win32',
arch: 'x64',
runtimeVersion: nativeAvailable ? '0.1.0' : undefined,
components: nativeAvailable
? [{ id: 'php', version: '8.5.9', executable: 'php.exe', sha256: 'a'.repeat(64) }]
: []
}
})
},
create: { pickDirectory: vi.fn(), project: vi.fn() },
terminal: { onData: vi.fn().mockReturnValue(() => {}), onExit: vi.fn().mockReturnValue(() => {}) }
terminal: {
onData: vi.fn().mockReturnValue(() => {}),
onExit: vi.fn().mockReturnValue(() => {})
}
})
const queryClient = new QueryClient({ defaultOptions: { queries: { retry: false } } })
render(<QueryClientProvider client={queryClient}><CreateProjectModal onClose={vi.fn()} /></QueryClientProvider>)
render(
<QueryClientProvider client={queryClient}>
<CreateProjectModal onClose={vi.fn()} />
</QueryClientProvider>
)
return { queryClient }
}
@@ -41,4 +66,11 @@ describe('external application choices', () => {
await waitFor(() => expect(screen.queryByText('WordPress')).not.toBeInTheDocument())
expect(screen.getByText('No application modules installed')).toBeInTheDocument()
})
it('defaults to Aurora Native when the bundled runtime is ready', async () => {
renderModal([wordpress], true)
const native = await screen.findByRole('button', { name: /Aurora Native/i })
await waitFor(() => expect(native.className).toContain('border-cyan-400'))
expect(screen.getByLabelText('PHP')).toHaveValue('8.5')
})
})
@@ -1,4 +1,4 @@
import { useRef, useState } from 'react'
import { useEffect, useRef, useState } from 'react'
import { clsx } from 'clsx'
import {
ArrowLeft,
@@ -56,6 +56,7 @@ export function CreateProjectModal({ onClose }: { onClose: () => void }): React.
const createProject = useCreateProject()
const selectProject = useAppStore((s) => s.selectProject)
const setupRef = useRef<TypeSetupHandle>(null)
const runtimeChoiceMade = useRef(false)
const { data: moduleRegistry = [] } = useModuleRegistry()
const { data: runtimeStatus } = useRuntimeStatus()
const applicationModules = moduleRegistry.filter((module) => module.category === 'application')
@@ -68,8 +69,27 @@ export function CreateProjectModal({ onClose }: { onClose: () => void }): React.
const canContinue = directory !== null && nameValid && selectedModule !== undefined
const canSubmit = canContinue && setupValid && !isSubmitting
useEffect(() => {
if (!runtimeStatus || runtimeChoiceMade.current) return
runtimeChoiceMade.current = true
if (!runtimeStatus.native.available) return
setRuntimeEngine('native')
const nativePhp = runtimeStatus.native.components.find(
(component) => component.id === 'php'
)?.version
if (nativePhp) setPhpVersion(nativePhp.split('.').slice(0, 2).join('.'))
setWebServer('nginx')
setDatabase('mariadb')
setDatabaseVersion('11.8')
setAdminer(true)
setRedis(false)
setMailpit(false)
setXdebug(false)
}, [runtimeStatus])
function selectRuntimeEngine(engine: 'container' | 'native'): void {
if (engine === 'native' && !runtimeStatus?.native.available) return
runtimeChoiceMade.current = true
setRuntimeEngine(engine)
if (engine === 'native') {
const nativePhp = runtimeStatus?.native.components.find(
@@ -376,8 +396,11 @@ export function CreateProjectModal({ onClose }: { onClose: () => void }): React.
</div>
<div className="grid gap-3 sm:grid-cols-2">
<div>
<label className={labelClass}>PHP</label>
<label htmlFor="project-php-version" className={labelClass}>
PHP
</label>
<select
id="project-php-version"
className={fieldClass}
value={phpVersion}
onChange={(e) => setPhpVersion(e.target.value)}