fix(desktop): Vault settings tab dials its scoped profile foreground

requestGatewayForProfile always dialed with the 'background' spawn priority,
so the Vault tab under the Settings 'Applies to' selector kept the #111651
infinite-spinner path on a cold profile even after the REST side moved to
scopedDialPriority. Let requestGatewayForProfile take a spawnPriority option
and pass 'foreground' from the Vault panel; ambient callers are unchanged.

Part of #111651
This commit is contained in:
teknium1
2026-09-15 14:48:30 -07:00
committed by Teknium
parent d3ba5b307a
commit 5eb0ed4531
4 changed files with 39 additions and 7 deletions

View File

@@ -5,16 +5,20 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import { stubResizeObserver } from '@/test/jsdom'
const { requestGateway } = vi.hoisted(() => ({
requestGateway: vi.fn()
const { requestGateway, requestGatewayForProfile } = vi.hoisted(() => ({
requestGateway: vi.fn(),
requestGatewayForProfile: vi.fn()
}))
// The panel routes every RPC through the owner profile's socket (never the ambient gateway);
// the mock receives (method, params) after the profile argument.
vi.mock('@/store/gateway', async importActual => ({
...(await importActual<Record<string, unknown>>()),
requestGatewayForProfile: (_profile: string, method: string, params?: Record<string, unknown>) =>
requestGateway(method, params ?? {})
requestGatewayForProfile: (...args: [string, string, Record<string, unknown>?, ...unknown[]]) => {
requestGatewayForProfile(...args)
return requestGateway(args[1], args[2] ?? {})
}
}))
import { queryClient } from '@/lib/query-client'
@@ -45,6 +49,7 @@ const LOGIN_ITEM = {
beforeEach(() => {
requestGateway.mockReset()
requestGatewayForProfile.mockReset()
queryClient.clear()
$gatewayState.set('open')
})
@@ -61,6 +66,16 @@ describe('VaultSettings', () => {
await waitFor(() => expect(screen.getByText('Nothing saved yet')).toBeTruthy())
expect(requestGateway).toHaveBeenCalledWith('vault.list', {})
// The scoped Settings dial must be foreground so a cold profile spawn is not
// queued behind background work (#111651).
expect(requestGatewayForProfile).toHaveBeenCalledWith(
expect.any(String),
'vault.list',
{},
undefined,
undefined,
{ spawnPriority: 'foreground' }
)
})
it('lists items with label, kind badge, identifier, and origin — never passwords', async () => {

View File

@@ -165,7 +165,7 @@ export function VaultSettings() {
const requestGateway = useCallback(
<T,>(method: string, params: Record<string, unknown> = {}) =>
requestGatewayForProfile<T>(scopeProfile, method, params),
requestGatewayForProfile<T>(scopeProfile, method, params, undefined, undefined, { spawnPriority: 'foreground' }),
[scopeProfile]
)

View File

@@ -111,6 +111,19 @@ describe('requestGatewayForProfile', () => {
expect($gateway.get()).toBe(primary)
})
it('dials the profile with foreground priority when a Settings-scoped caller asks for it (#111651)', async () => {
setPrimaryGateway(makePrimary() as never, 'default')
const getConnection = vi.fn(async (profile: null | string) =>
profile ? { port: 5151, profile, token: 'secondary-token' } : { port: 4242, token: 'primary-token' }
)
installDesktop(getConnection)
await ensureGatewayForProfile('default')
await requestGatewayForProfile('worker', 'vault.list', {}, undefined, undefined, { spawnPriority: 'foreground' })
expect(getConnection).toHaveBeenCalledWith('worker', { priority: 'foreground' })
})
it('uses the primary socket and adds profile scope for a shared global remote route', async () => {
const primary = makePrimary()
setPrimaryGateway(primary as never, 'default')

View File

@@ -991,9 +991,13 @@ export async function requestGatewayForProfile<T>(
method: string,
params: Record<string, unknown> = {},
timeoutMs?: number,
signal?: AbortSignal
signal?: AbortSignal,
{ spawnPriority = 'background' }: { spawnPriority?: SpawnPriority } = {}
): Promise<T> {
const route = await gatewayForProfile(profile, true)
// A user-initiated Settings-scoped RPC (the Vault tab's "Applies to" pick)
// dials `foreground` so a cold profile spawn is not queued behind background
// work (#111651); ambient callers keep the background default.
const route = await gatewayForProfile(profile, true, spawnPriority)
try {
if (!route.gateway) {