refactor(client): expose loopback state through connection

This commit is contained in:
imccyu
2026-08-03 18:34:00 +08:00
parent e47ad8e393
commit fc5ee9f786
16 changed files with 38 additions and 36 deletions

View File

@@ -8,7 +8,6 @@
import type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client'
import { deferRegistration } from '@deepseek-ai/dsh-client-ui-slots'
import type { ConnectionHandle } from '@deepseek-ai/dsh-client-connection/client'
import { isLoopbackHostname } from '@deepseek-ai/dsh-client-connection/loopback-hostname'
import { bindSnapshotSelector } from '@deepseek-ai/dsh-client-web-react'
// Type-only: pulls the shell's SlotMap merges (trigger/header/section/item).
import type {} from '@deepseek-ai/dsh-client-ui-settings/client'
@@ -42,10 +41,6 @@ declare module '@deepseek-ai/dsh-client-ui-slots' {
/** Dictionary namespace owned by this plugin (shell chrome + General copy). */
const NS = 'settings'
function welcomePersistence(): 'host' | 'memory' {
return typeof location === 'undefined' || isLoopbackHostname(location.hostname) ? 'host' : 'memory'
}
/**
* Required services (cordis fiber inject). The target slots are declared by
* ui-settings' apply, whose activation order relative to this one is NOT
@@ -66,7 +61,7 @@ export function apply(ctx: ClientContext): void {
// locale/change re-registration wiring.
const t = ctx.locale.bind(NS)
const connection = ctx.get('connection') as ConnectionHandle
const welcomeController = new WelcomeNoticeStore(connection.api, welcomePersistence())
const welcomeController = new WelcomeNoticeStore(connection.api, connection.isLoopback ? 'host' : 'memory')
const useWelcomeSnapshot = bindSnapshotSelector(welcomeController.store)
const welcomeInjected = (): WelcomeNoticeInjected => ({
controller: welcomeController,

View File

@@ -1,6 +1,6 @@
/** Ownerless-copy registrations: the four seats, the dictionaries, thunked labels, and HMR recovery. */
import { Context } from 'cordis'
import { afterEach, describe, expect, it, vi } from 'vitest'
import { describe, expect, it, vi } from 'vitest'
import { resolveSlotLabel } from '@deepseek-ai/dsh-client-ui-slots'
import { SlotsService } from '@deepseek-ai/dsh-client-runtime/client'
import { LocaleService } from '@deepseek-ai/dsh-client-locale/client'
@@ -16,8 +16,6 @@ import { WELCOME_NOTICE_SETTINGS_NAMESPACE } from '../src/onboarding-copy.ts'
// the shipped Chinese copy, so they state the browser they assume.
usePinnedBrowserLanguages('zh-CN')
afterEach(() => { vi.unstubAllGlobals() })
/** The five seats this plugin fills (slot name → expected component). */
const SEATS = [
['settings.trigger', TriggerContent],
@@ -27,7 +25,7 @@ const SEATS = [
['settings.onboarding', WelcomeNotice],
] as const
async function bench() {
async function bench(isLoopback = true) {
const ctx = new Context()
await ctx.plugin(SlotsService).await()
const locale = new LocaleService(ctx)
@@ -49,7 +47,7 @@ async function bench() {
},
},
}))
ctx.provide('connection', { api: { settings: { describe: settingsDescribe } } } as never)
ctx.provide('connection', { api: { settings: { describe: settingsDescribe } }, isLoopback } as never)
return { ctx, slots: ctx.get('slots') as SlotsService, locale, settingsDescribe }
}
@@ -162,8 +160,7 @@ describe('ui-settings-general apply', () => {
})
it('keeps remote welcome acknowledgement process-local', async () => {
vi.stubGlobal('location', { hostname: '192.0.2.20' })
const b = await bench()
const b = await bench(false)
declare(b.slots)
await b.ctx.plugin({ inject: [...inject], apply }).await()
const entry = b.slots.entries('settings.onboarding')[0]!