mirror of
https://github.com/stablyai/orca.git
synced 2026-09-28 16:02:45 +00:00
Fix WSL preflight context snapshot stability (#2749)
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import type { AppState } from '@/store/types'
|
||||
import {
|
||||
getLocalPreflightContext,
|
||||
getWslDistroFromPath,
|
||||
localPreflightContextKey
|
||||
} from './local-preflight-context'
|
||||
|
||||
function makeState(args: { repoPath?: string | null; worktreePath?: string | null }): AppState {
|
||||
const repoId = 'repo-1'
|
||||
const worktreeId = `${repoId}::worktree-1`
|
||||
return {
|
||||
activeRepoId: repoId,
|
||||
activeWorktreeId: args.worktreePath === undefined ? null : worktreeId,
|
||||
repos:
|
||||
args.repoPath === undefined
|
||||
? []
|
||||
: [
|
||||
{
|
||||
id: repoId,
|
||||
path: args.repoPath
|
||||
}
|
||||
],
|
||||
worktreesByRepo:
|
||||
args.worktreePath === undefined
|
||||
? {}
|
||||
: {
|
||||
[repoId]: [
|
||||
{
|
||||
id: worktreeId,
|
||||
repoId,
|
||||
path: args.worktreePath
|
||||
}
|
||||
]
|
||||
}
|
||||
} as AppState
|
||||
}
|
||||
|
||||
describe('local preflight context', () => {
|
||||
it('extracts WSL distro names from supported UNC forms', () => {
|
||||
expect(getWslDistroFromPath(String.raw`\\wsl.localhost\Ubuntu\home\alice\repo`)).toBe('Ubuntu')
|
||||
expect(getWslDistroFromPath(String.raw`\\wsl$\Debian\home\alice\repo`)).toBe('Debian')
|
||||
expect(getWslDistroFromPath('/Users/alice/repo')).toBeNull()
|
||||
})
|
||||
|
||||
it('returns a stable snapshot for repeated WSL selector reads', () => {
|
||||
const state = makeState({
|
||||
worktreePath: String.raw`\\wsl.localhost\Ubuntu\home\alice\repo`
|
||||
})
|
||||
|
||||
const first = getLocalPreflightContext(state)
|
||||
const second = getLocalPreflightContext(state)
|
||||
|
||||
expect(first).toBe(second)
|
||||
expect(first).toEqual({ wslDistro: 'Ubuntu' })
|
||||
expect(localPreflightContextKey(first)).toBe('wsl:Ubuntu')
|
||||
})
|
||||
|
||||
it('reuses the same WSL snapshot across equivalent active repo and worktree paths', () => {
|
||||
const fromRepo = getLocalPreflightContext(
|
||||
makeState({
|
||||
repoPath: String.raw`\\wsl.localhost\Ubuntu\home\alice\repo`
|
||||
})
|
||||
)
|
||||
const fromWorktree = getLocalPreflightContext(
|
||||
makeState({
|
||||
repoPath: '/Users/alice/repo',
|
||||
worktreePath: String.raw`\\wsl.localhost\Ubuntu\home\alice\repo`
|
||||
})
|
||||
)
|
||||
const fromOtherDistro = getLocalPreflightContext(
|
||||
makeState({
|
||||
worktreePath: String.raw`\\wsl.localhost\Debian\home\alice\repo`
|
||||
})
|
||||
)
|
||||
|
||||
expect(fromRepo).toBe(fromWorktree)
|
||||
expect(fromOtherDistro).not.toBe(fromRepo)
|
||||
expect(fromOtherDistro).toEqual({ wslDistro: 'Debian' })
|
||||
})
|
||||
|
||||
it('uses the stable host context for non-WSL paths', () => {
|
||||
const state = makeState({ repoPath: '/Users/alice/repo' })
|
||||
|
||||
expect(getLocalPreflightContext(state)).toBeUndefined()
|
||||
expect(getLocalPreflightContext(state)).toBeUndefined()
|
||||
expect(localPreflightContextKey(getLocalPreflightContext(state))).toBe('host')
|
||||
})
|
||||
})
|
||||
@@ -3,10 +3,25 @@ import { parseWslUncPath } from '../../../shared/wsl-paths'
|
||||
|
||||
export type LocalPreflightContext = { wslDistro?: string | null } | undefined
|
||||
|
||||
const wslPreflightContextsByDistro = new Map<string, NonNullable<LocalPreflightContext>>()
|
||||
|
||||
export function getWslDistroFromPath(path?: string | null): string | null {
|
||||
return path ? (parseWslUncPath(path)?.distro ?? null) : null
|
||||
}
|
||||
|
||||
function getWslPreflightContext(wslDistro: string): NonNullable<LocalPreflightContext> {
|
||||
const cached = wslPreflightContextsByDistro.get(wslDistro)
|
||||
if (cached) {
|
||||
return cached
|
||||
}
|
||||
|
||||
// Why: React/Zustand selectors must return a cached snapshot. A fresh object
|
||||
// here triggers a useSyncExternalStore loop when Settings observes WSL repos.
|
||||
const context = Object.freeze({ wslDistro })
|
||||
wslPreflightContextsByDistro.set(wslDistro, context)
|
||||
return context
|
||||
}
|
||||
|
||||
export function getLocalPreflightContext(state: AppState): LocalPreflightContext {
|
||||
const activeWorktree = state.activeWorktreeId
|
||||
? Object.values(state.worktreesByRepo ?? {})
|
||||
@@ -16,7 +31,7 @@ export function getLocalPreflightContext(state: AppState): LocalPreflightContext
|
||||
const activePath =
|
||||
activeWorktree?.path ?? (state.repos ?? []).find((repo) => repo.id === state.activeRepoId)?.path
|
||||
const wslDistro = getWslDistroFromPath(activePath)
|
||||
return wslDistro ? { wslDistro } : undefined
|
||||
return wslDistro ? getWslPreflightContext(wslDistro) : undefined
|
||||
}
|
||||
|
||||
export function localPreflightContextKey(context: LocalPreflightContext): string {
|
||||
|
||||
Reference in New Issue
Block a user