fix(host,client): abort superseded listings on the wire; keep the native swap resolvable

Supersession (newer navigation, path editing, closing, unmount) now
aborts the in-flight listing's request instead of only discarding its
result: the browser mints an AbortController per listing, the signal
rides the workspace face (IWorkspaces.listDirectory gains an optional
signal) onto the fetch carrier, and the Host scan stops with it (817's
cancellation chain). apps/cli keeps both picker packages as dependencies
so the documented one-row cordis.yml swap to the native backend resolves
at boot.
This commit is contained in:
creatixchu
2026-07-29 06:19:18 +08:00
parent 463893947b
commit 53240f4664
9 changed files with 77 additions and 28 deletions

View File

@@ -40,9 +40,10 @@ export interface IWorkspaces {
/**
* List one directory level through the Host's `browse` capability.
* @param path - absolute directory to list; absent lists the Host home directory.
* @param signal - aborts the wire request (and the Host's scan) when the caller supersedes it.
* @returns the level's listing with breadcrumb ancestry.
*/
listDirectory(path?: string): Promise<DirectoryListing>
listDirectory(path?: string, signal?: AbortSignal): Promise<DirectoryListing>
/**
* Create one child directory through the Host's `browse` capability.
* @param path - absolute existing parent directory.

View File

@@ -195,10 +195,11 @@ export class WorkspacesService implements IWorkspaces {
/**
* List one directory level through the Host's `browse` capability.
* @param path - absolute directory to list; absent lists the Host home directory.
* @param signal - aborts the wire request (and the Host's scan) when the caller supersedes it.
* @returns the level's listing with breadcrumb ancestry.
*/
async listDirectory(path?: string): Promise<DirectoryListing> {
const response = await this.api.host.listDirectory(path === undefined ? {} : { path })
async listDirectory(path?: string, signal?: AbortSignal): Promise<DirectoryListing> {
const response = await this.api.host.listDirectory(path === undefined ? {} : { path }, signal)
if (!response.result.ok) throw new DirectoryBrowseError(response.result.error)
return response.result.value
}