@dsh-workbench/core 0.3.4 → 0.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/client.js +1243 -78
- package/dist/client/client.body.js +1243 -78
- package/dist/client/index.js +1243 -78
- package/dist/host/index.js +623 -841
- package/dist/types/app/client.d.ts +201 -60
- package/dist/types/modules/panels/model/diy-context.d.ts +4 -5
- package/dist/types/modules/panels/model/diy-observers.d.ts +2 -2
- package/dist/types/modules/panels/model/diy-page.d.ts +1 -1
- package/dist/types/modules/panels/unit.d.ts +3 -4
- package/dist/types/shared/api/context-chips.d.ts +20 -0
- package/dist/types/shared/api/host/diy-components.d.ts +17 -6
- package/dist/types/shared/api/host/diy-workshop.d.ts +0 -3
- package/dist/types/shared/api/host/preset-scope.d.ts +16 -0
- package/dist/types/shared/api/host/tool-scope.d.ts +6 -2
- package/dist/types/shared/api/host/workshop-root.d.ts +7 -0
- package/dist/types/shared/components/BlockerState.d.ts +12 -0
- package/dist/types/shared/components/PanelFoot.d.ts +9 -0
- package/dist/types/shared/components/Tip.d.ts +8 -0
- package/dist/types/shared/hooks/bundle-queries.d.ts +12 -0
- package/dist/types/shared/hooks/fact-transports.d.ts +4 -0
- package/dist/types/shared/hooks/panel-state-report.d.ts +12 -0
- package/dist/types/shared/hooks/use-api-resource.d.ts +22 -0
- package/dist/types/shared/hooks/use-blocker-actions.d.ts +8 -0
- package/dist/types/shared/hooks/use-capabilities.d.ts +55 -0
- package/dist/types/shared/hooks/use-capability-gate.d.ts +16 -0
- package/dist/types/shared/hooks/use-card-summary.d.ts +7 -0
- package/dist/types/shared/hooks/use-diy-debug.d.ts +13 -0
- package/dist/types/shared/hooks/use-diy-record.d.ts +13 -0
- package/dist/types/shared/hooks/use-facts.d.ts +10 -0
- package/dist/types/shared/hooks/use-host-write.d.ts +12 -0
- package/dist/types/shared/hooks/use-long-task.d.ts +8 -0
- package/dist/types/shared/hooks/use-unit-board.d.ts +17 -0
- package/dist/types/shared/hooks/use-visible-busy.d.ts +17 -0
- package/package.json +2 -2
- package/skills/workbench-module-diy/DATASOURCE.md +2 -2
- package/skills/workbench-module-diy/FAMILY.md +5 -4
- package/skills/workbench-module-diy/KIT.md +105 -100
- package/skills/workbench-module-diy/PANEL.md +19 -11
- package/skills/workbench-module-diy/REVIEW.md +4 -4
- package/skills/workbench-module-diy/SKILL.md +5 -4
- package/skills/workbench-module-diy/TOOLING.md +2 -2
- package/skills/workbench-module-diy/TOOLS.md +1 -1
- package/skills/workbench-module-diy/WIRING.md +2 -1
- package/skills/workbench-module-diy/HOOKS.md +0 -95
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { DshHostContext, DshToolRunContext } from '@dsh-workbench/shared';
|
|
2
|
-
import { type BrowserFindResult, type BrowserReadResult } from '@dsh-workbench/shared/host';
|
|
3
2
|
import type { BundleChange } from '../../../shared/api/bundle-install';
|
|
4
3
|
import type { PanelsService } from './service';
|
|
5
4
|
export declare const OUTPUT_SCHEMA: {
|
|
@@ -85,18 +84,18 @@ export declare function asNumber(value: unknown): number | undefined;
|
|
|
85
84
|
export declare function asText(value: unknown): string;
|
|
86
85
|
export declare function plainJson<T>(value: T): T;
|
|
87
86
|
export declare function verdictOf(change: BundleChange): string;
|
|
88
|
-
export declare function renderProbe(out: BrowserReadResult): string;
|
|
89
|
-
export declare function renderFind(out: BrowserFindResult): string;
|
|
90
87
|
export declare function showOrReason(panels: PanelsService, unit: string, workspace: string | null): {
|
|
91
88
|
readonly ok: boolean;
|
|
92
89
|
readonly reason?: string;
|
|
93
90
|
};
|
|
94
|
-
export declare function workshopOf(ctx: DshHostContext, exec: DshToolRunContext): {
|
|
91
|
+
export declare function workshopOf(ctx: DshHostContext, exec: DshToolRunContext): Promise<{
|
|
95
92
|
readonly packagesDir: string;
|
|
96
93
|
readonly workspace: string | null;
|
|
97
|
-
|
|
94
|
+
readonly title: string;
|
|
95
|
+
}>;
|
|
98
96
|
export declare function modulesOf(ctx: DshHostContext, packagesDir: string): {
|
|
99
97
|
installed: string[];
|
|
100
98
|
modules: readonly import("@/shared/api/host/diy-workshop").WorkshopModule[];
|
|
101
99
|
};
|
|
100
|
+
export declare function moduleDirsOf(packagesDir: string): readonly string[];
|
|
102
101
|
export declare function panelEntriesOf(panels: PanelsService, workspace: string | null): import("./config").PanelEntry[];
|
|
@@ -7,5 +7,5 @@ export interface ObserverCleanup {
|
|
|
7
7
|
export interface CleanupLog {
|
|
8
8
|
warn?(message: string): void;
|
|
9
9
|
}
|
|
10
|
-
export declare function stopObservers(ctx: DshHostContext, session?: string): Promise<ObserverCleanup>;
|
|
11
|
-
export declare function withObserverCleanup(store: DebugStore, cleanup: () => Promise<ObserverCleanup>, logger?: CleanupLog | undefined): DebugStore;
|
|
10
|
+
export declare function stopObservers(ctx: DshHostContext, workspace: string | null | undefined, session?: string): Promise<ObserverCleanup>;
|
|
11
|
+
export declare function withObserverCleanup(store: DebugStore, cleanup: (workspace: string | null) => Promise<ObserverCleanup>, logger?: CleanupLog | undefined): DebugStore;
|
|
@@ -26,5 +26,5 @@ export declare function debugForeignPactText(held: DebugState): string;
|
|
|
26
26
|
export declare function debugOffBoardText(held: DebugState, situation?: BoardSituation): string;
|
|
27
27
|
export declare function boardProbeOf(page: WorkbenchPage): BoardProbe;
|
|
28
28
|
export declare function boardStateOf(page: WorkbenchPage, workshop: string | null): BoardState;
|
|
29
|
-
export declare function boardGateText(situation: BoardSituation, unit: string, page: WorkbenchPage): string;
|
|
29
|
+
export declare function boardGateText(situation: BoardSituation, unit: string, page: WorkbenchPage, title?: string): string;
|
|
30
30
|
export declare function pageAt(ctx: DshHostContext, exec: DshToolRunContext, raw: unknown, options?: PageOptions): Promise<PageHandle>;
|
|
@@ -20,7 +20,6 @@ export declare const DIY_PANEL_TOOL = "workbench_diy_panel";
|
|
|
20
20
|
export declare const DIY_COMPONENTS_TOOL = "workbench_diy_components";
|
|
21
21
|
export declare const DIY_RECON_TOOL = "workbench_diy_recon";
|
|
22
22
|
export declare const DIY_SPEC_TOOL = "workbench_diy_spec";
|
|
23
|
-
export declare const DIY_PROBE_TOOL = "workbench_diy_probe";
|
|
24
23
|
export declare const DIY_INSTALL_TOOL = "workbench_diy_install";
|
|
25
24
|
export declare const DIY_SHOW_TOOL = "workbench_diy_show";
|
|
26
25
|
export declare const DIY_STATE_TOOL = "workbench_diy_state";
|
|
@@ -48,11 +47,11 @@ export declare const DIY_DEBUG_START_TOOL = "workbench_diy_debug_start";
|
|
|
48
47
|
export declare const DIY_DEBUG_PAUSE_TOOL = "workbench_diy_debug_pause";
|
|
49
48
|
export declare const DIY_DEBUG_RESUME_TOOL = "workbench_diy_debug_resume";
|
|
50
49
|
export declare const DIY_DEBUG_STOP_TOOL = "workbench_diy_debug_stop";
|
|
51
|
-
export declare const ALL_TOOLS: readonly ["workbench_panels_list", "workbench_panels_show", "workbench_panels_hide", "workbench_panels_move", "workbench_panels_reset", "workbench_panels_follow", "workbench_modules_list", "workbench_modules_install", "workbench_modules_update", "workbench_modules_uninstall", "workbench_modules_install_bundle", "workbench_modules_update_dependency", "workbench_modules_update_plugin", "workbench_modules_uninstall_plugin", "workbench_modules_update_workbench", "workbench_diy_list", "workbench_diy_status", "workbench_diy_panel", "workbench_diy_components", "workbench_diy_recon", "workbench_diy_spec", "
|
|
50
|
+
export declare const ALL_TOOLS: readonly ["workbench_panels_list", "workbench_panels_show", "workbench_panels_hide", "workbench_panels_move", "workbench_panels_reset", "workbench_panels_follow", "workbench_modules_list", "workbench_modules_install", "workbench_modules_update", "workbench_modules_uninstall", "workbench_modules_install_bundle", "workbench_modules_update_dependency", "workbench_modules_update_plugin", "workbench_modules_uninstall_plugin", "workbench_modules_update_workbench", "workbench_diy_list", "workbench_diy_status", "workbench_diy_panel", "workbench_diy_components", "workbench_diy_recon", "workbench_diy_spec", "workbench_diy_install", "workbench_diy_show", "workbench_diy_state", "workbench_diy_html", "workbench_diy_find", "workbench_diy_click", "workbench_diy_hover", "workbench_diy_type", "workbench_diy_fill", "workbench_diy_keys", "workbench_diy_scroll", "workbench_diy_wait", "workbench_diy_eval", "workbench_diy_screenshot", "workbench_diy_network", "workbench_diy_dialog", "workbench_diy_logs_watch", "workbench_diy_logs_read", "workbench_diy_logs_stop", "workbench_diy_record_prepare", "workbench_diy_record_read", "workbench_diy_record_detail", "workbench_diy_record_stop", "workbench_diy_debug_start", "workbench_diy_debug_pause", "workbench_diy_debug_resume", "workbench_diy_debug_stop"];
|
|
52
51
|
export type PanelsToolName = (typeof ALL_TOOLS)[number];
|
|
53
|
-
export declare const READ_TOOLS: readonly ["workbench_panels_list", "workbench_modules_list", "workbench_diy_list", "workbench_diy_status", "workbench_diy_panel", "workbench_diy_components", "workbench_diy_recon", "workbench_diy_spec", "
|
|
52
|
+
export declare const READ_TOOLS: readonly ["workbench_panels_list", "workbench_modules_list", "workbench_diy_list", "workbench_diy_status", "workbench_diy_panel", "workbench_diy_components", "workbench_diy_recon", "workbench_diy_spec", "workbench_diy_state", "workbench_diy_html", "workbench_diy_find", "workbench_diy_click", "workbench_diy_hover", "workbench_diy_type", "workbench_diy_fill", "workbench_diy_keys", "workbench_diy_scroll", "workbench_diy_wait", "workbench_diy_eval", "workbench_diy_screenshot", "workbench_diy_network", "workbench_diy_dialog", "workbench_diy_logs_watch", "workbench_diy_logs_read", "workbench_diy_logs_stop", "workbench_diy_record_read", "workbench_diy_record_detail", "workbench_diy_record_stop"];
|
|
54
53
|
export declare const WRITE_TOOLS: readonly ["workbench_panels_show", "workbench_panels_hide", "workbench_panels_move", "workbench_panels_reset", "workbench_panels_follow", "workbench_modules_install", "workbench_modules_update", "workbench_modules_uninstall", "workbench_modules_install_bundle", "workbench_modules_update_dependency", "workbench_modules_update_plugin", "workbench_modules_uninstall_plugin", "workbench_modules_update_workbench", "workbench_diy_install", "workbench_diy_show", "workbench_diy_record_prepare", "workbench_diy_debug_start", "workbench_diy_debug_pause", "workbench_diy_debug_resume", "workbench_diy_debug_stop"];
|
|
55
|
-
export declare const DIY_TOOLS: readonly ["workbench_diy_list", "workbench_diy_status", "workbench_diy_panel", "workbench_diy_components", "workbench_diy_recon", "workbench_diy_spec", "
|
|
54
|
+
export declare const DIY_TOOLS: readonly ["workbench_diy_list", "workbench_diy_status", "workbench_diy_panel", "workbench_diy_components", "workbench_diy_recon", "workbench_diy_spec", "workbench_diy_install", "workbench_diy_show", "workbench_diy_state", "workbench_diy_html", "workbench_diy_find", "workbench_diy_click", "workbench_diy_hover", "workbench_diy_type", "workbench_diy_fill", "workbench_diy_keys", "workbench_diy_scroll", "workbench_diy_wait", "workbench_diy_eval", "workbench_diy_screenshot", "workbench_diy_network", "workbench_diy_dialog", "workbench_diy_logs_watch", "workbench_diy_logs_read", "workbench_diy_logs_stop"];
|
|
56
55
|
export declare const DIY_RECORD_TOOLS: readonly ["workbench_diy_record_prepare", "workbench_diy_record_read", "workbench_diy_record_detail", "workbench_diy_record_stop"];
|
|
57
56
|
export declare const DIY_DEBUG_TOOLS: readonly ["workbench_diy_debug_start", "workbench_diy_debug_pause", "workbench_diy_debug_resume", "workbench_diy_debug_stop"];
|
|
58
57
|
export declare const panelsUnit: UnitManifest;
|
|
@@ -1,10 +1,30 @@
|
|
|
1
1
|
import type { DshClientContext } from '@dsh-workbench/shared';
|
|
2
2
|
import { type ContextRef } from '@dsh-workbench/shared';
|
|
3
|
+
/**
|
|
4
|
+
* 对话 `@` 引用源报名用的名字:引用、lexicon 与编解码都挂在这个 source 名下。
|
|
5
|
+
*/
|
|
3
6
|
export declare const CONTEXT_SOURCE = "workbench";
|
|
7
|
+
/**
|
|
8
|
+
* `addContextChip` 的结果:`inserted` 真插进输入框了、`unavailable` 这台 dsh 缺服务或当时插不进去。
|
|
9
|
+
*/
|
|
4
10
|
export type ChipResult = 'inserted' | 'unavailable';
|
|
11
|
+
/**
|
|
12
|
+
* 装引用源要的外壳依赖:现在这个会话是哪一个 —— 拿不到 session id 就插不了。
|
|
13
|
+
*/
|
|
5
14
|
export interface ContextChipsDeps {
|
|
6
15
|
currentSessionId(): string | undefined;
|
|
7
16
|
}
|
|
17
|
+
/**
|
|
18
|
+
* 外壳启动、拿到 dsh 的 client context 之后调一次:把 `@` 引用源注册进对话输入框;
|
|
19
|
+
* dsh 没给 `inputTriggers` 时不装、也不报错。
|
|
20
|
+
*/
|
|
8
21
|
export declare function installContextChips(ctx: DshClientContext, deps: ContextChipsDeps): void;
|
|
22
|
+
/**
|
|
23
|
+
* 要往当前对话输入框插一条 `@` 引用时调用(卡片上“发到对话”那类动作):同步返回,只反映当场这一拍 ——
|
|
24
|
+
* 没插进去会自己再试几拍,后面成功了也不会回头改这个返回值。没装过 / 没会话 / 拿不到输入框都回 `unavailable`。
|
|
25
|
+
*/
|
|
9
26
|
export declare function addContextChip(ref: ContextRef, label: string): ChipResult;
|
|
27
|
+
/**
|
|
28
|
+
* 把编好的引用串码成带 `@` 的标记文本(输入框里显示与复制到剪贴板都是这一份);认不出的串原样加个 `@`。
|
|
29
|
+
*/
|
|
10
30
|
export declare function serializeChipRef(encoded: string): string;
|
|
@@ -18,8 +18,9 @@ export declare function scopeOf(raw: string): SurfaceScope;
|
|
|
18
18
|
export declare function wantsPrimitives(scope: SurfaceScope): boolean;
|
|
19
19
|
export declare function wantsKit(scope: SurfaceScope): boolean;
|
|
20
20
|
export declare function toolchainBinOf(root: string): string | null;
|
|
21
|
+
export declare function toolchainBinAmong(root: string, dirs: readonly string[]): string | null;
|
|
21
22
|
export declare function queryCommandOf(bin: string, only: 'kit' | 'primitives'): string;
|
|
22
|
-
export declare function runSurfaceQuery(shell: DshShell, bin: string, only: 'kit' | 'primitives', root: string): Promise<SurfacePayload>;
|
|
23
|
+
export declare function runSurfaceQuery(shell: DshShell, bin: string, only: 'kit' | 'primitives', root: string, fallbackBin?: string): Promise<SurfacePayload>;
|
|
23
24
|
export declare function filesOf(payload: SurfacePayload | undefined): Record<string, string>;
|
|
24
25
|
export declare function rootsOf(payload: SurfacePayload | undefined): Record<string, string>;
|
|
25
26
|
export declare function countsOf(payload: SurfacePayload | undefined): Record<string, number>;
|
|
@@ -31,19 +32,29 @@ export declare function findFileOf(name: string, query: SurfaceQuery): {
|
|
|
31
32
|
} | null;
|
|
32
33
|
export declare function excerptOf(text: string, maxLines?: number): string;
|
|
33
34
|
export declare function excerptAt(file: string, maxLines?: number): string;
|
|
35
|
+
/** 指引目录:从宿主产物往上找 `skills/workbench-module-diy`(找不到回 `null`)。 */
|
|
34
36
|
export declare function skillDirOf(from: string): string | null;
|
|
35
|
-
export declare function symbolsIn(heading: string): readonly string[];
|
|
36
|
-
export declare function docSectionOf(name: string, dir: string | null): {
|
|
37
|
-
readonly file: string;
|
|
38
|
-
readonly lines: string;
|
|
39
|
-
} | null;
|
|
40
37
|
export declare function byLocationOf(payload: SurfacePayload): readonly {
|
|
41
38
|
readonly where: string;
|
|
42
39
|
readonly names: readonly string[];
|
|
43
40
|
}[];
|
|
41
|
+
export interface SurfaceBucket {
|
|
42
|
+
readonly label: string;
|
|
43
|
+
readonly key: string;
|
|
44
|
+
readonly names: readonly string[];
|
|
45
|
+
}
|
|
46
|
+
export declare function kitBucketsOf(payload: SurfacePayload): readonly SurfaceBucket[];
|
|
47
|
+
export declare function matchesBucket(where: string, bucket: string): boolean;
|
|
48
|
+
export declare function bucketNamesOf(query: SurfaceQuery): readonly {
|
|
49
|
+
readonly face: 'kit' | 'primitives';
|
|
50
|
+
readonly keys: readonly string[];
|
|
51
|
+
}[];
|
|
52
|
+
export declare const TWO_FACE_ALL = "\u26A0\uFE0F \u4E24\u4E2A\u9762\u4E00\u8D77\u4E0D\u7ED9\u5168\u8868 \u2014\u2014 \u8981\u5168\u8868\u5C31\u6307\u540D\u4E00\u9762\uFF1Ascope=kit \u6216 scope=primitives\u3002";
|
|
53
|
+
export declare function refusesEvery(scope: SurfaceScope, all: boolean, focused: boolean): boolean;
|
|
44
54
|
export declare function renderSurfaceText(query: SurfaceQuery, options: {
|
|
45
55
|
scope: SurfaceScope;
|
|
46
56
|
all: boolean;
|
|
57
|
+
bucket?: string;
|
|
47
58
|
}): string;
|
|
48
59
|
export declare function listedNamesOf(query: SurfaceQuery): readonly string[];
|
|
49
60
|
export type FaceState = 'not-queried' | 'ok' | 'unreadable';
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { DshHostContext } from '@dsh-workbench/shared';
|
|
2
1
|
export interface WorkshopModule {
|
|
3
2
|
readonly unit: string;
|
|
4
3
|
readonly name: string;
|
|
@@ -6,11 +5,9 @@ export interface WorkshopModule {
|
|
|
6
5
|
readonly dir: string;
|
|
7
6
|
readonly installed: boolean;
|
|
8
7
|
}
|
|
9
|
-
export declare function workshopPackagesDir(ctx: DshHostContext): string | null;
|
|
10
8
|
export declare function insideWorkshop(root: string, target: string): boolean;
|
|
11
9
|
export declare function workshopModules(packagesDir: string, installed?: readonly string[]): readonly WorkshopModule[];
|
|
12
10
|
export declare function readDesignOfModule(dir: string): unknown;
|
|
13
|
-
export declare function inWorkshopSession(ctx: DshHostContext, workspace: string | null): boolean;
|
|
14
11
|
export interface WorkshopSync {
|
|
15
12
|
readonly state: 'ok' | 'syncing' | 'failed';
|
|
16
13
|
readonly version: string;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { DshHostContext } from '@dsh-workbench/shared';
|
|
2
|
+
import { type ToolScopeContext } from '@dsh-workbench/shared/host';
|
|
3
|
+
import { type ToolScope } from './tool-scope';
|
|
4
|
+
export interface SessionProjections {
|
|
5
|
+
stateOf(session: unknown, key: string): unknown;
|
|
6
|
+
onChanged(listener: (session: unknown, key: string, value: unknown, seq: unknown) => void): () => void;
|
|
7
|
+
}
|
|
8
|
+
export interface PresetScopeOptions {
|
|
9
|
+
readonly ctx: DshHostContext;
|
|
10
|
+
readonly deniedTools: (context: ToolScopeContext) => readonly string[];
|
|
11
|
+
readonly logger?: {
|
|
12
|
+
info?(message: string): void;
|
|
13
|
+
warn?(message: string): void;
|
|
14
|
+
} | undefined;
|
|
15
|
+
}
|
|
16
|
+
export declare function createPresetScope(options: PresetScopeOptions): ToolScope;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { DshPromptAssembly } from '@dsh-workbench/shared';
|
|
2
|
+
import type { ToolScopeContext } from '@dsh-workbench/shared/host';
|
|
2
3
|
export interface ScopedToolRegistry {
|
|
3
4
|
restrict(filter: {
|
|
4
5
|
readonly allow?: readonly string[];
|
|
@@ -11,13 +12,16 @@ export interface ToolScopeAgent {
|
|
|
11
12
|
get?<T = unknown>(name: string): T | undefined;
|
|
12
13
|
} | undefined;
|
|
13
14
|
readonly session?: {
|
|
15
|
+
readonly id?: string | undefined;
|
|
14
16
|
readonly header?: {
|
|
15
|
-
readonly cwd?: string;
|
|
17
|
+
readonly cwd?: string | undefined;
|
|
18
|
+
readonly agentPreset?: string | undefined;
|
|
16
19
|
} | undefined;
|
|
17
20
|
} | undefined;
|
|
18
21
|
}
|
|
19
22
|
export interface ToolScopeOptions {
|
|
20
|
-
deniedTools(
|
|
23
|
+
deniedTools(context: ToolScopeContext): readonly string[];
|
|
24
|
+
presetOf?: ((handle: ToolScopeAgent) => string | null) | undefined;
|
|
21
25
|
logger?: {
|
|
22
26
|
info?(message: string): void;
|
|
23
27
|
warn?(message: string): void;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { DshHostContext } from '@dsh-workbench/shared';
|
|
2
|
+
export interface WorkshopRoot {
|
|
3
|
+
readonly root: string;
|
|
4
|
+
readonly packagesDir: string;
|
|
5
|
+
readonly title: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function workshopRootOf(ctx: DshHostContext, workspace: string | null): Promise<WorkshopRoot | null>;
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import type { ModuleBlocker } from '@dsh-workbench/shared';
|
|
2
2
|
import type { Translate } from '@dsh-workbench/shared';
|
|
3
|
+
/**
|
|
4
|
+
* `<BlockerState>` 的 prop:一份 blocker 加几个回调。
|
|
5
|
+
*/
|
|
3
6
|
export interface BlockerStateProps {
|
|
4
7
|
readonly blocker: ModuleBlocker;
|
|
5
8
|
readonly t: Translate;
|
|
@@ -8,4 +11,13 @@ export interface BlockerStateProps {
|
|
|
8
11
|
readonly flush?: boolean;
|
|
9
12
|
readonly onOpenMarket?: () => void;
|
|
10
13
|
}
|
|
14
|
+
/**
|
|
15
|
+
* 卡片被挡住(或要给一句 notice)时渲染的那一块:按 `blocker.severity` 出块状或一行提示,动作接重试 / 跑修复 / 复制。
|
|
16
|
+
* @param props.blocker - 要显示的那份 blocker:`title` / `hint` / `detail` / `actions` / `severity`。
|
|
17
|
+
* @param props.t - 翻译函数,这一块出现的每句话都从它来。
|
|
18
|
+
* @param props.onRetry - `retry` 动作与修复成功后的重试回调。
|
|
19
|
+
* @param props.onOpenMarket - `open-market` 动作;没给就退回 `onRetry`。
|
|
20
|
+
* @param props.busy - 外层是不是在忙(默认 `false`);为真时动作一并禁用。
|
|
21
|
+
* @param props.flush - 是否贴着容器边(默认 `false`):去掉图标、收窄留白,给卡片内嵌用。
|
|
22
|
+
*/
|
|
11
23
|
export declare function BlockerState({ blocker, t, onRetry, busy, flush, onOpenMarket, }: BlockerStateProps): JSX.Element;
|
|
@@ -1,7 +1,16 @@
|
|
|
1
1
|
import type { ReactNode } from '@dsh-workbench/shared';
|
|
2
|
+
/**
|
|
3
|
+
* `<PanelFoot>` 的 prop:左边一句脚注,右边一格内容。
|
|
4
|
+
*/
|
|
2
5
|
export interface PanelFootProps {
|
|
3
6
|
readonly text?: string;
|
|
4
7
|
readonly size?: 'sm' | 'md';
|
|
5
8
|
readonly children?: ReactNode;
|
|
6
9
|
}
|
|
10
|
+
/**
|
|
11
|
+
* 面板底部那行脚注:左侧一句 `text`,右侧放 `children`,两样都不给就是一个空的页脚壳。
|
|
12
|
+
* @param props.text - 左侧那句说明文字;不传时左侧什么都不渲染。
|
|
13
|
+
* @param props.size - 文字档(默认 `'sm'`,11px 三级色;`'md'` 是 14px 二级色,给更宽的面板用)。
|
|
14
|
+
* @param props.children - 右侧那一格内容(一般是按钮或状态),可省略。
|
|
15
|
+
*/
|
|
7
16
|
export declare function PanelFoot({ text, size, children }: PanelFootProps): JSX.Element;
|
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
import { Tooltip } from '@deepseek-ai/dsh-client-ui-primitives';
|
|
2
2
|
type TooltipProps = Parameters<typeof Tooltip>[0];
|
|
3
|
+
/**
|
|
4
|
+
* dsh `Tooltip` 的外壳默认值版:说明统一按右栏习惯(`bottom` / `end` / `gap 6` / 挂 body)来,其余 prop 原样转给 `Tooltip`。
|
|
5
|
+
* @param props.side - 气泡出现在锚点哪一侧(默认 `'bottom'`)。
|
|
6
|
+
* @param props.align - 底 / 顶气泡贴锚点哪条边(默认 `'end'`)。
|
|
7
|
+
* @param props.gap - 锚点到气泡的间距(默认 `6`)。
|
|
8
|
+
* @param props.portal - 是否挂到 `document.body`,以逃出裁剪容器与层叠上下文(默认 `true`)。
|
|
9
|
+
* @param props.children - 单个锚点元素;`label` / `shortcutKeys` / `openOnClick` 等其余 prop 与 dsh 同形。
|
|
10
|
+
*/
|
|
3
11
|
export declare function Tip({ side, align, gap, portal, ...rest }: TooltipProps): JSX.Element;
|
|
4
12
|
export {};
|
|
@@ -1,7 +1,19 @@
|
|
|
1
1
|
import type { ApiResponse } from '@dsh-workbench/shared';
|
|
2
2
|
import { type BundleInspectionPayload, type BundleRegistriesPayload, type ModuleVersionsPayload } from '../api/bundle-install';
|
|
3
3
|
import { type InstalledPluginsPayload } from '../api/installed-plugins';
|
|
4
|
+
/**
|
|
5
|
+
* 读模块源注册表:装模块时能从哪些源取、当前解析到哪一个。
|
|
6
|
+
*/
|
|
4
7
|
export declare function readBundleRegistries(): Promise<ApiResponse<BundleRegistriesPayload>>;
|
|
8
|
+
/**
|
|
9
|
+
* 装之前先看清一个 spec 是什么(收了 / 拒了 / 是个插件);`registry` 省略或空就按默认源解析。
|
|
10
|
+
*/
|
|
5
11
|
export declare function readBundleInspection(spec: string, registry?: string): Promise<ApiResponse<BundleInspectionPayload>>;
|
|
12
|
+
/**
|
|
13
|
+
* 问模块有没有新版;`force: true` 绕过缓存重新问源(“更新”那条路用)。
|
|
14
|
+
*/
|
|
6
15
|
export declare function readModuleVersions(force?: boolean): Promise<ApiResponse<ModuleVersionsPayload>>;
|
|
16
|
+
/**
|
|
17
|
+
* 读已装的 opencli 插件台账;`force: true` 绕过缓存重新问一遍。
|
|
18
|
+
*/
|
|
7
19
|
export declare function readInstalledPlugins(force?: boolean): Promise<ApiResponse<InstalledPluginsPayload>>;
|
|
@@ -1,12 +1,24 @@
|
|
|
1
1
|
import type { PanelCardError, PanelCardPhase } from '@dsh-workbench/shared';
|
|
2
|
+
/**
|
|
3
|
+
* 从路由里切出单元 id(`cmdb/runs` → `cmdb`);切不出来(没有前缀)回 `null`。
|
|
4
|
+
*/
|
|
2
5
|
export declare function unitOfRoute(route: string): string | null;
|
|
6
|
+
/**
|
|
7
|
+
* 告诉上报这沓“现在的工作区是哪个”;换工作区会丢掉还没冲出去的待报读数。
|
|
8
|
+
*/
|
|
3
9
|
export declare function setPanelWorkspace(path: string | null): void;
|
|
10
|
+
/**
|
|
11
|
+
* 卡片读数落地时调它(`useApiResource` 已经接好):同一单元同一条路由只留最新一条,攒一拍再一起冲给宿主。
|
|
12
|
+
*/
|
|
4
13
|
export declare function reportPanelRead(input: {
|
|
5
14
|
readonly unit: string;
|
|
6
15
|
readonly route: string;
|
|
7
16
|
readonly phase: PanelCardPhase;
|
|
8
17
|
readonly error?: PanelCardError | undefined;
|
|
9
18
|
}): void;
|
|
19
|
+
/**
|
|
20
|
+
* 卡片崩了时调它:`unit` 与原因立刻报给宿主(不攒);还不知道工作区时不报。
|
|
21
|
+
*/
|
|
10
22
|
export declare function reportPanelCrash(input: {
|
|
11
23
|
readonly unit: string;
|
|
12
24
|
readonly reason: string;
|
|
@@ -1,16 +1,38 @@
|
|
|
1
1
|
import type { ApiError, ApiResponse, Query } from '@dsh-workbench/shared';
|
|
2
|
+
/**
|
|
3
|
+
* 一次读的状态:`idle` 没开读 · `loading` 在飞 · `ready` 有值 · `error` 失败;`value` 是 `ApiResponse<T>`、
|
|
4
|
+
* `at` 是拿到这个值的时间戳。**身份没变的重取(如点刷新)进 `loading` 时上一次的 `value` 与 `at` 会留着**
|
|
5
|
+
* —— 界面照旧有得画;身份变了、本来就没值、或读到 `error` 时才没有(那时两者都是 `undefined`)。
|
|
6
|
+
*/
|
|
2
7
|
export interface ResourceState<T> {
|
|
3
8
|
readonly phase: 'idle' | 'loading' | 'ready' | 'error';
|
|
4
9
|
readonly value?: T;
|
|
5
10
|
readonly error?: ApiError;
|
|
6
11
|
readonly at?: number;
|
|
7
12
|
}
|
|
13
|
+
/**
|
|
14
|
+
* 这次读的身份:`route` 加排好序的 `query`(排序是为了同一次读只有一个 key);给了 `override` 就用它。
|
|
15
|
+
*/
|
|
8
16
|
export declare function resourceIdentity(route: string, query: Query, override?: string | undefined): string;
|
|
17
|
+
/**
|
|
18
|
+
* 把身份与两个版本号拼成合流用的 key:同一个 key 的并发读共享同一条请求。
|
|
19
|
+
*/
|
|
9
20
|
export declare function readKeyOf(identity: string, refreshToken: number, factRev: number): string;
|
|
21
|
+
/**
|
|
22
|
+
* 非 hook 的取数本体(要自己管缓存时才直接调):同一个 `key` 只发一次,并发调用共享同一个 `task`;
|
|
23
|
+
* 用它就一定要 `release`(一般放 `finally`),最后一个 `release` 才 abort,否则那条请求永不取消。
|
|
24
|
+
*/
|
|
10
25
|
export declare function requestResource<T>(route: string, query: Query, key: string): {
|
|
11
26
|
task: Promise<ApiResponse<T>>;
|
|
12
27
|
release: () => void;
|
|
13
28
|
};
|
|
29
|
+
/**
|
|
30
|
+
* 卡片里所有的读都走它:按身份发一次 `apiGet`,同 key 合流、订阅事实通道(这条变了自动重取)、
|
|
31
|
+
* 并把读数上报面板(`workbench_diy_panel` 看的就是它);身份或版本号一变就换一条读,旧的当场取消。
|
|
32
|
+
* `options.enabled` 为 `false` 时不发请求、相位恒为 `idle`;`key` 覆盖身份、`fact` 换订阅哪条事实
|
|
33
|
+
* (默认 `factOfRoute(route)`)、`report: false` 不上报(夹具与后台探针用)。身份没变的重取会留住上一格
|
|
34
|
+
* 的 `value`,相位降到 `loading`。
|
|
35
|
+
*/
|
|
14
36
|
export declare function useApiResource<T>(route: string, query: Query, refreshToken: number, options?: {
|
|
15
37
|
enabled?: boolean;
|
|
16
38
|
key?: string;
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import type { BlockerAction } from '@dsh-workbench/shared';
|
|
2
|
+
/**
|
|
3
|
+
* blocker 那几个动作的句柄:`run(action)` 执行、`copied` 刚复制走的文本、`running` 正在跑的修复标签、`failure` 失败信息。
|
|
4
|
+
*/
|
|
2
5
|
export interface BlockerActions {
|
|
3
6
|
run(action: BlockerAction): void;
|
|
4
7
|
copied: string | null;
|
|
@@ -8,4 +11,9 @@ export interface BlockerActions {
|
|
|
8
11
|
detail?: string;
|
|
9
12
|
} | null;
|
|
10
13
|
}
|
|
14
|
+
/**
|
|
15
|
+
* `<BlockerState>` 用它把 blocker 的动作接到实处:`retry` 与修复成功后的重试走 `onRetry`、`run-fix` 走 provision
|
|
16
|
+
* 写通道、`copy` 写剪贴板、`open-url` 开新窗;`open-market` 没给 `onOpenMarket` 时退回 `onRetry`。
|
|
17
|
+
* 自己画 blocker 那一块才直接用。
|
|
18
|
+
*/
|
|
11
19
|
export declare function useBlockerActions(onRetry: () => void, onOpenMarket?: () => void): BlockerActions;
|
|
@@ -1,25 +1,80 @@
|
|
|
1
1
|
import type { CapabilityPayload } from '@dsh-workbench/shared';
|
|
2
|
+
/**
|
|
3
|
+
* 纯函数:`refreshToken` 与上一次不同,这一次就该强制重探。
|
|
4
|
+
*/
|
|
2
5
|
export declare function shouldForce(refreshToken: number, previousToken: number): boolean;
|
|
6
|
+
/**
|
|
7
|
+
* 整张能力表:单元 id → 那一格声明的能力(`design.json` 里那份)。
|
|
8
|
+
*/
|
|
3
9
|
export type CapabilityMap = Record<string, CapabilityPayload>;
|
|
10
|
+
/**
|
|
11
|
+
* 探针状态:`checkedAt` 上一次探完的时刻(没探过是 `null`)、`checking` 是不是正在探。
|
|
12
|
+
*/
|
|
4
13
|
export interface CapabilityProbeState {
|
|
5
14
|
readonly checkedAt: number | null;
|
|
6
15
|
readonly checking: boolean;
|
|
7
16
|
}
|
|
17
|
+
/**
|
|
18
|
+
* 让下一次强探静默(不点亮 `checking`)—— 装机预检那类不该惊动界面的探用。
|
|
19
|
+
*/
|
|
8
20
|
export declare function markNextProbeSilent(): void;
|
|
21
|
+
/**
|
|
22
|
+
* 探针状态的取值口,给 `useSyncExternalStore` 用;渲染里要状态请用 `useCapabilityProbe`。
|
|
23
|
+
*/
|
|
9
24
|
export declare function probeValue(): CapabilityProbeState;
|
|
25
|
+
/**
|
|
26
|
+
* 探针状态的订阅口,返回退订函数;渲染里要状态请用 `useCapabilityProbe`。
|
|
27
|
+
*/
|
|
10
28
|
export declare function subscribeProbe(listener: () => void): () => void;
|
|
29
|
+
/**
|
|
30
|
+
* 能力表那条事实的名字:写完之后 `useFactInvalidate(CAPABILITY_FACT)` 标它,读者自动重取。
|
|
31
|
+
*/
|
|
11
32
|
export declare const CAPABILITY_FACT = "capability";
|
|
33
|
+
/**
|
|
34
|
+
* 当前整张能力表的取值口(没探过是 `null`),给 `useSyncExternalStore` 用;渲染里请用 `useCapabilities`。
|
|
35
|
+
*/
|
|
12
36
|
export declare function capabilityValue(): CapabilityMap | null;
|
|
37
|
+
/**
|
|
38
|
+
* 能力表的订阅口,返回退订函数;渲染里请用 `useCapabilities`。
|
|
39
|
+
*/
|
|
13
40
|
export declare function subscribeCapabilities(listener: () => void): () => void;
|
|
41
|
+
/**
|
|
42
|
+
* 写入口:换整张表并通知订阅者(同值不通知);传 `null` 清探针状态,`rechecked: true` 时顺手记下 `checkedAt`。
|
|
43
|
+
*/
|
|
14
44
|
export declare function setCapabilities(next: CapabilityMap | null, rechecked?: boolean): void;
|
|
45
|
+
/**
|
|
46
|
+
* 一次强探开始:点亮“正在探”;已经在探就跳过。
|
|
47
|
+
*/
|
|
15
48
|
export declare function beginProbe(): void;
|
|
49
|
+
/**
|
|
50
|
+
* 一次强探收尾:熄灭“正在探”。
|
|
51
|
+
*/
|
|
16
52
|
export declare function endProbe(): void;
|
|
53
|
+
/**
|
|
54
|
+
* 把一次探测的结果发布出去:读到了就广播并回 `true`;没读到(`null`)时已有结论就留着回 `false`,
|
|
55
|
+
* 从来没有过结论才落一张空表回 `true`(“探不动”不等于“还没探”)。
|
|
56
|
+
*/
|
|
17
57
|
export declare function publishCapability(result: CapabilityMap | null, rechecked?: boolean): boolean;
|
|
58
|
+
/**
|
|
59
|
+
* 同一语义(同一个 `force`)的在飞探测搭车:并发调用共享同一个 promise;落地或失败就清掉,
|
|
60
|
+
* 下一次强探会真的再跑一遍;`force` 不同不搭车。
|
|
61
|
+
*/
|
|
18
62
|
export declare function shareCapabilityFetch(force: boolean, load: (force: boolean) => Promise<CapabilityMap | null>): Promise<CapabilityMap | null>;
|
|
63
|
+
/**
|
|
64
|
+
* 探一次能力表并发布:`force` 决定这是“重探”还是顺带读 —— 只有重探负责点亮 / 熄灭探针(`silent` 时连点亮都不做),
|
|
65
|
+
* 被更新的一次重探盖过的非强制结果会丢掉。
|
|
66
|
+
*/
|
|
19
67
|
export declare function runCapabilityRead(options: {
|
|
20
68
|
readonly force: boolean;
|
|
21
69
|
readonly silent?: boolean;
|
|
22
70
|
readonly load?: (force: boolean) => Promise<CapabilityMap | null>;
|
|
23
71
|
}): Promise<void>;
|
|
72
|
+
/**
|
|
73
|
+
* 渲染里要整张能力表时调用:所有读者共享同一份结论,没探过是 `null`。
|
|
74
|
+
* `refreshToken` 变化算一次强制重探,事实版本(`CAPABILITY_FACT`)与 `reloadToken` 变化各触发一次重读。
|
|
75
|
+
*/
|
|
24
76
|
export declare function useCapabilities(refreshToken: number, reloadToken?: number): CapabilityMap | null;
|
|
77
|
+
/**
|
|
78
|
+
* 渲染里要探针状态(`checking` / `checkedAt`)时调用,比如“最近检查”那一行。
|
|
79
|
+
*/
|
|
25
80
|
export declare function useCapabilityProbe(): CapabilityProbeState;
|
|
@@ -1,15 +1,27 @@
|
|
|
1
1
|
import type { CapabilityPayload } from '@dsh-workbench/shared';
|
|
2
2
|
import { type GateMode } from '@dsh-workbench/shared';
|
|
3
3
|
import { type CapabilityMap } from './use-capabilities';
|
|
4
|
+
/**
|
|
5
|
+
* 一格的能力门:`capability` 是这一格声明的能力(没读到是 `null`)、`gated` 放行没(为真 = 这一格能画)、
|
|
6
|
+
* `forceProbe()` 现在就去探一次。
|
|
7
|
+
*/
|
|
4
8
|
export interface CapabilityGate {
|
|
5
9
|
readonly capability: CapabilityPayload | null;
|
|
6
10
|
readonly gated: boolean;
|
|
7
11
|
forceProbe(): void;
|
|
8
12
|
}
|
|
13
|
+
/**
|
|
14
|
+
* 卡片里判断“这一格现在能不能画”时调用:`refreshToken` 变化触发一次重探。
|
|
15
|
+
* `options.mode` 换门的口径(默认 `'capability'`)、`options.fixture` 给夹具一份假能力;
|
|
16
|
+
* `gated` 按口径算 —— 读数还没到先放行(让它去读),读到明确不通过才拦;`forceProbe()` 是“现在就去探一次”。
|
|
17
|
+
*/
|
|
9
18
|
export declare function useCapabilityGate(unit: string, refreshToken: number, options?: {
|
|
10
19
|
readonly mode?: GateMode | undefined;
|
|
11
20
|
readonly fixture?: CapabilityPayload | undefined;
|
|
12
21
|
}): CapabilityGate;
|
|
22
|
+
/**
|
|
23
|
+
* 整张能力表的视图:表本体加探针的 `checkedAt` / `checking`,以及 `forceProbe()` 与 `reload()`。
|
|
24
|
+
*/
|
|
13
25
|
export interface CapabilityMapView {
|
|
14
26
|
readonly capabilities: CapabilityMap | null;
|
|
15
27
|
readonly checkedAt: number | null;
|
|
@@ -17,4 +29,8 @@ export interface CapabilityMapView {
|
|
|
17
29
|
forceProbe(): void;
|
|
18
30
|
reload(): void;
|
|
19
31
|
}
|
|
32
|
+
/**
|
|
33
|
+
* 设置页 / 体检那类“要全部单元的能力表”时调用:`reload()` 重取整张表、`forceProbe()` 立刻探一次、
|
|
34
|
+
* `checking` 是探针在跑;没探过时 `capabilities` 是 `null`。
|
|
35
|
+
*/
|
|
20
36
|
export declare function useCapabilityMap(refreshToken: number): CapabilityMapView;
|
|
@@ -1,7 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 卡片报给面板那一格的两个数:`refreshing` 还在不在忙、`at` 最近一次读到值的时间(没有是 `null`)。
|
|
3
|
+
*/
|
|
1
4
|
export interface CardSummary {
|
|
2
5
|
readonly refreshing: boolean;
|
|
3
6
|
readonly at: number | null;
|
|
4
7
|
}
|
|
8
|
+
/**
|
|
9
|
+
* 自己搭卡片、要把 `{ refreshing, at }` 在变化时交给调用点上报面板时调用;`onSummary` 要稳定引用
|
|
10
|
+
* (一般 `useCallback`),否则每次渲染都会上报一次。`useUnitBoard` 已经把这条接好。
|
|
11
|
+
*/
|
|
5
12
|
export declare function useCardSummary(onSummary: (summary: CardSummary) => void, summary: {
|
|
6
13
|
readonly refreshing: boolean;
|
|
7
14
|
readonly at: number | null | undefined;
|
|
@@ -1,8 +1,21 @@
|
|
|
1
1
|
import type { DebugState } from '@dsh-workbench/shared';
|
|
2
2
|
import type { HostWrite } from './use-host-write';
|
|
3
|
+
/**
|
|
4
|
+
* 调试约定的读路由(宿主侧那半同名)。
|
|
5
|
+
*/
|
|
3
6
|
export declare const DIY_DEBUG_ROUTE = "panels/diy-debug";
|
|
7
|
+
/**
|
|
8
|
+
* 调试约定那条事实的名字:写完调 `useFactInvalidate(DIY_DEBUG_FACT)`,读者自动重取。
|
|
9
|
+
*/
|
|
4
10
|
export declare const DIY_DEBUG_FACT = "diy-debug";
|
|
11
|
+
/**
|
|
12
|
+
* 要读“现在的调试约定是什么”时调用(左栏底部那枚状态);跟着事实变化自动重取,不上报面板;
|
|
13
|
+
* 还没读到或后端说没有约定时都是 `null`。
|
|
14
|
+
*/
|
|
5
15
|
export declare function useDiyDebugState(): DebugState | null;
|
|
16
|
+
/**
|
|
17
|
+
* 要发“开始 / 暂停 / 继续 / 结束调试”那几把动作时调用;写走 `diy-debug/act` 通道。
|
|
18
|
+
*/
|
|
6
19
|
export declare function useDiyDebugAct(): HostWrite<{
|
|
7
20
|
text?: string;
|
|
8
21
|
}>;
|
|
@@ -1,8 +1,21 @@
|
|
|
1
1
|
import type { RecordState } from '@dsh-workbench/shared';
|
|
2
2
|
import type { HostWrite } from './use-host-write';
|
|
3
|
+
/**
|
|
4
|
+
* 录制交接的读路由(宿主侧那半同名)。
|
|
5
|
+
*/
|
|
3
6
|
export declare const DIY_RECORD_ROUTE = "panels/diy-record";
|
|
7
|
+
/**
|
|
8
|
+
* 录制交接那条事实的名字:写完调 `useFactInvalidate(DIY_RECORD_FACT)`,读者自动重取。
|
|
9
|
+
*/
|
|
4
10
|
export declare const DIY_RECORD_FACT = "diy-record";
|
|
11
|
+
/**
|
|
12
|
+
* 要读“这一段录制交接进行到哪了”时调用(左栏底部那枚状态);跟着事实变化自动重取,不上报面板;
|
|
13
|
+
* 还没读到或后端说没有交接时都是 `null`。
|
|
14
|
+
*/
|
|
5
15
|
export declare function useDiyRecordState(): RecordState | null;
|
|
16
|
+
/**
|
|
17
|
+
* 要发录制交接那几把动作(准备 / 读回 / 收尾)时调用;写走 `diy-record/act` 通道。
|
|
18
|
+
*/
|
|
6
19
|
export declare function useDiyRecordAct(): HostWrite<{
|
|
7
20
|
text?: string;
|
|
8
21
|
}>;
|
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 渲染里要“这条事实的版本号”时调用:版本一变,喂给 `useApiResource` 的 key 就变、读自动重来。
|
|
3
|
+
* 卡片读数默认订的 `factOfRoute(route)` 已经接好,只有要订别的事实才显式传 `fact`。
|
|
4
|
+
*/
|
|
1
5
|
export declare function useFactRevision(fact: string): number;
|
|
6
|
+
/**
|
|
7
|
+
* 不在渲染里的地方(宿主事件、定时器里看到的旧值)要听事实变化时用它;返回值就是退订函数,用完记得退。
|
|
8
|
+
*/
|
|
2
9
|
export declare function subscribeFactRevision(fact: string, listener: () => void): () => void;
|
|
10
|
+
/**
|
|
11
|
+
* 写完之后把这条事实标脏时调用:不标,面板就停在旧值;不传 `fact` 是把所有事实一起标脏。
|
|
12
|
+
*/
|
|
3
13
|
export declare function useFactInvalidate(): (fact?: string) => void;
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
import { type WriteChannel, type WriteOutcome } from '@dsh-workbench/shared';
|
|
2
|
+
/**
|
|
3
|
+
* 一个写通道的句柄:`busy` 在发、`failed` / `detail` 上一条人话失败(没有是 `null`)、
|
|
4
|
+
* `send(body, { silent })` 回 `WriteOutcome`、`fail(message, detail?)` 本地就知道不行时自己塞一条、`clear()` 清掉。
|
|
5
|
+
*/
|
|
2
6
|
export interface HostWrite<T> {
|
|
3
7
|
readonly busy: boolean;
|
|
4
8
|
readonly failed: string | null;
|
|
@@ -9,9 +13,17 @@ export interface HostWrite<T> {
|
|
|
9
13
|
fail(message: string, detail?: string): void;
|
|
10
14
|
clear(): void;
|
|
11
15
|
}
|
|
16
|
+
/**
|
|
17
|
+
* 写通道的配置:`channel` 用哪个前缀、`resource` 挂在它的哪一格(多数通道留空)、`networkText` 网络不通时那句人话。
|
|
18
|
+
*/
|
|
12
19
|
export interface HostWriteOptions {
|
|
13
20
|
readonly channel: WriteChannel;
|
|
14
21
|
readonly resource?: string | undefined;
|
|
15
22
|
readonly networkText: string;
|
|
16
23
|
}
|
|
24
|
+
/**
|
|
25
|
+
* 组件里要写(发 POST)时调用 —— 写只走这条,别在组件里自己 `fetch`。
|
|
26
|
+
* `send` 失败自动落到 `failed` + `detail`(界面直接显示,别自己拼);`silent: true` 是不打扰:不动 `busy` / `failed`,
|
|
27
|
+
* 结果只从返回值拿。返回的 `busy` 是这一路写有没有在飞。
|
|
28
|
+
*/
|
|
17
29
|
export declare function useHostWrite<T>(options: HostWriteOptions): HostWrite<T>;
|