@openviking/react 0.1.2 → 0.1.3
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/dist/1~0.js +506 -0
- package/dist/2~0.js +122 -0
- package/dist/{g~0.js → 30~0.js} +292 -167
- package/dist/client/index.d.ts +2 -1
- package/dist/client/paths.d.ts +64 -0
- package/dist/client/response.d.ts +31 -0
- package/dist/client/sse.d.ts +39 -0
- package/dist/client/stream.d.ts +26 -0
- package/dist/client/types.d.ts +104 -0
- package/dist/client.js +1 -239
- package/dist/components/agent-connect/style.css +2 -2
- package/dist/components/file-browser-entries/file-browser-entries-icons.d.ts +18 -0
- package/dist/components/file-browser-entries/file-browser-entries.d.ts +14 -0
- package/dist/components/file-browser-entries/index.d.ts +1 -0
- package/dist/components/file-browser-entries/style.css +155 -0
- package/dist/components/file-browser-entries/style.js +0 -0
- package/dist/components/file-browser-entries/types.d.ts +45 -0
- package/dist/components/file-browser-entries.js +1 -0
- package/dist/components/file-preview/file-preview-directory.d.ts +32 -0
- package/dist/components/file-preview/file-preview-header.d.ts +21 -3
- package/dist/components/file-preview/file-preview-panels.d.ts +41 -0
- package/dist/components/file-preview/file-preview-state.d.ts +10 -3
- package/dist/components/file-preview/file-preview.d.ts +2 -1
- package/dist/components/file-preview/level-selection.d.ts +25 -0
- package/dist/components/file-preview/style.css +76 -3
- package/dist/components/file-preview/types.d.ts +100 -1
- package/dist/components/file-preview/use-directory-level.d.ts +30 -0
- package/dist/components/file-preview/use-file-preview-actions-context.d.ts +6 -2
- package/dist/components/file-preview/use-file-preview-actions.d.ts +1 -1
- package/dist/components/file-preview.js +1 -1
- package/dist/components/file-tree/file-tree-info-tooltip.d.ts +7 -7
- package/dist/components/file-tree/file-tree-row-context.d.ts +0 -5
- package/dist/components/file-tree/file-tree-row-shared.d.ts +9 -2
- package/dist/components/file-tree/file-tree-tooltip-surface.d.ts +8 -8
- package/dist/components/file-tree/style.css +71 -34
- package/dist/components/file-tree/types.d.ts +20 -0
- package/dist/components/scope-switcher/style.css +2 -2
- package/dist/components/style.css +312 -47
- package/dist/components/tui/style.css +2 -2
- package/dist/components/viking-bot/style.css +2 -2
- package/dist/file-preview-viewer~0.js +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/l~0.js +1464 -25
- package/dist/modules/console/style.css +2 -2
- package/dist/modules/file-browser/file-browser-detail-icons.d.ts +10 -0
- package/dist/modules/file-browser/file-browser-detail.d.ts +33 -0
- package/dist/modules/file-browser/file-browser-empty.d.ts +3 -0
- package/dist/modules/file-browser/file-browser-failure.d.ts +22 -0
- package/dist/modules/file-browser/file-browser-icons.d.ts +18 -0
- package/dist/modules/file-browser/file-browser-labels.d.ts +28 -0
- package/dist/modules/file-browser/file-browser-layout.d.ts +27 -0
- package/dist/modules/file-browser/file-browser-toolbar.d.ts +18 -0
- package/dist/modules/file-browser/file-browser-tree-pane.d.ts +30 -0
- package/dist/modules/file-browser/file-browser.d.ts +14 -5
- package/dist/modules/file-browser/find-result.d.ts +24 -0
- package/dist/modules/file-browser/fs-directories.d.ts +33 -0
- package/dist/modules/file-browser/fs-file-kind.d.ts +19 -0
- package/dist/modules/file-browser/fs-icon.d.ts +17 -0
- package/dist/modules/file-browser/fs-model.d.ts +106 -0
- package/dist/modules/file-browser/fs-page.d.ts +16 -0
- package/dist/modules/file-browser/fs-path.d.ts +16 -0
- package/dist/modules/file-browser/fs-read-directory.d.ts +20 -0
- package/dist/modules/file-browser/fs-scope.d.ts +22 -0
- package/dist/modules/file-browser/fs-stat.d.ts +25 -0
- package/dist/modules/file-browser/index.d.ts +3 -1
- package/dist/modules/file-browser/style.css +4927 -35
- package/dist/modules/file-browser/tree-info-copy.d.ts +15 -0
- package/dist/modules/file-browser/tree-info-copy.zh-CN.d.ts +15 -0
- package/dist/modules/file-browser/types.d.ts +189 -44
- package/dist/modules/file-browser/use-container-width.d.ts +17 -0
- package/dist/modules/file-browser/use-file-browser.d.ts +49 -0
- package/dist/modules/file-browser/use-fs-preview.d.ts +51 -0
- package/dist/modules/file-browser/use-fs-search.d.ts +35 -0
- package/dist/modules/file-browser/use-fs-tree.d.ts +43 -0
- package/dist/modules/file-browser/use-request-scope.d.ts +39 -0
- package/dist/modules/file-browser.js +1 -1
- package/dist/modules/scope-cascade/style.css +2 -2
- package/dist/modules/style.css +4933 -41
- package/dist/n~0.js +178 -74
- package/dist/o~0.js +103 -0
- package/dist/shared/components/divider/divider.d.ts +18 -0
- package/dist/shared/components/divider/index.d.ts +1 -0
- package/dist/shared/components/divider/types.d.ts +35 -0
- package/dist/shared/components/overlay/types.d.ts +7 -0
- package/dist/shared/components/{tooltip/use-tooltip-position.d.ts → overlay/use-overlay-position.d.ts} +6 -6
- package/dist/shared/components/popover/index.d.ts +1 -0
- package/dist/shared/components/popover/popover.d.ts +23 -0
- package/dist/shared/components/popover/types.d.ts +50 -0
- package/dist/shared/components/resizable/clamp.d.ts +13 -0
- package/dist/shared/components/resizable/index.d.ts +2 -0
- package/dist/shared/components/resizable/resizable-handle.d.ts +25 -0
- package/dist/shared/components/resizable/types.d.ts +48 -0
- package/dist/shared/components/tooltip/types.d.ts +5 -5
- package/dist/style.css +5345 -188
- package/package.json +6 -1
- package/dist/components/file-tree/file-tree-tooltip.d.ts +0 -17
- package/dist/modules/file-browser/file-browser-toolbar-button.d.ts +0 -10
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenViking 原生接口的路径。集中在这里,接口改名时只改一处;调用方不要自己
|
|
3
|
+
* 拼字符串。路径不含服务地址与网关前缀,拼接由 Client 完成。
|
|
4
|
+
*
|
|
5
|
+
* 用 `as const` 而不是 `enum`:字符串 enum 在 `isolatedModules` 下不会内联,
|
|
6
|
+
* 生成的对象还会被当成副作用;作为公开导出时它是 ambient const enum,消费者
|
|
7
|
+
* 一旦开启 `isolatedModules` 或 `verbatimModuleSyntax` 就无法使用。
|
|
8
|
+
*
|
|
9
|
+
* Paths of the native OpenViking API. Keeping them here means a rename is one
|
|
10
|
+
* edit, and callers never build strings themselves. A path carries no service
|
|
11
|
+
* address or gateway prefix; the Client joins those.
|
|
12
|
+
*
|
|
13
|
+
* `as const` rather than `enum`: a string enum is not inlined under
|
|
14
|
+
* `isolatedModules`, its emitted object counts as a side effect, and as a public
|
|
15
|
+
* export it is an ambient const enum that consumers with `isolatedModules` or
|
|
16
|
+
* `verbatimModuleSyntax` cannot use.
|
|
17
|
+
*/
|
|
18
|
+
export declare const OV_PATHS: {
|
|
19
|
+
/** 列出目录内容。List directory contents. */
|
|
20
|
+
readonly fsLs: '/api/v1/fs/ls';
|
|
21
|
+
/** 读取条目状态。Read an entry's status. */
|
|
22
|
+
readonly fsStat: '/api/v1/fs/stat';
|
|
23
|
+
/** 读取目录树。Read a directory tree. */
|
|
24
|
+
readonly fsTree: '/api/v1/fs/tree';
|
|
25
|
+
/** 新建目录。Create a directory. */
|
|
26
|
+
readonly fsMkdir: '/api/v1/fs/mkdir';
|
|
27
|
+
/** 移动或重命名。Move or rename. */
|
|
28
|
+
readonly fsMv: '/api/v1/fs/mv';
|
|
29
|
+
/** 读取文件正文。Read file content. */
|
|
30
|
+
readonly contentRead: '/api/v1/content/read';
|
|
31
|
+
/** 读取目录的 L0 摘要。Read a directory's L0 abstract. */
|
|
32
|
+
readonly contentAbstract: '/api/v1/content/abstract';
|
|
33
|
+
/** 读取目录的 L1 概览。Read a directory's L1 overview. */
|
|
34
|
+
readonly contentOverview: '/api/v1/content/overview';
|
|
35
|
+
/** 下载文件原始字节。Download a file's raw bytes. */
|
|
36
|
+
readonly contentDownload: '/api/v1/content/download';
|
|
37
|
+
/** 写入文件正文。Write file content. */
|
|
38
|
+
readonly contentWrite: '/api/v1/content/write';
|
|
39
|
+
/** 按模式匹配文件。Match files by pattern. */
|
|
40
|
+
readonly searchGlob: '/api/v1/search/glob';
|
|
41
|
+
/** 语义检索。Semantic search. */
|
|
42
|
+
readonly searchFind: '/api/v1/search/find';
|
|
43
|
+
/** 按正则检索正文。Search content by regular expression. */
|
|
44
|
+
readonly searchGrep: '/api/v1/search/grep';
|
|
45
|
+
/** 会话列表与新建。Session list and creation. */
|
|
46
|
+
readonly sessions: '/api/v1/sessions';
|
|
47
|
+
/** 非流式对话。Non-streaming chat. */
|
|
48
|
+
readonly botChat: '/bot/v1/chat';
|
|
49
|
+
/** 流式对话。Streaming chat. */
|
|
50
|
+
readonly botChatStream: '/bot/v1/chat/stream';
|
|
51
|
+
};
|
|
52
|
+
/** 一个静态路径的取值类型。Value type of one static path. */
|
|
53
|
+
export type OvPath = (typeof OV_PATHS)[keyof typeof OV_PATHS];
|
|
54
|
+
/**
|
|
55
|
+
* 带路径参数的接口。参数会被 URL 编码:会话 id 里出现 `/` 时不能当成路径分隔。
|
|
56
|
+
* Endpoints with a path parameter. The value is URL-encoded, so a session id
|
|
57
|
+
* containing `/` is not read as a path separator.
|
|
58
|
+
*/
|
|
59
|
+
export declare const OV_PATH_BUILDERS: {
|
|
60
|
+
/** 单个会话。One session. */
|
|
61
|
+
readonly session: (sessionId: string) => string;
|
|
62
|
+
/** 会话的消息。Messages of one session. */
|
|
63
|
+
readonly sessionMessages: (sessionId: string) => string;
|
|
64
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { OvClientError } from './errors.js';
|
|
2
|
+
import type { OvErrorEnvelope, OvSuccessEnvelope } from './types.js';
|
|
3
|
+
/** 任意对象判定。Record check. */
|
|
4
|
+
export declare function isRecord(value: unknown): value is Record<string, unknown>;
|
|
5
|
+
/** 把响应体读成原生外壳;不是对象时按空外壳处理。 */
|
|
6
|
+
export declare function readEnvelope(value: unknown): OvErrorEnvelope & OvSuccessEnvelope;
|
|
7
|
+
/** 解析 JSON 文本;不是 JSON 时返回 `undefined`,不抛错。 */
|
|
8
|
+
export declare function parseJson(raw: string): unknown;
|
|
9
|
+
/** 请求被调用方主动取消时保留 `AbortError` 语义,便于调用方区分。 */
|
|
10
|
+
export declare function isAbortError(error: unknown): boolean;
|
|
11
|
+
/**
|
|
12
|
+
* 把传输层的拒绝归一成 {@link OvClientError}。调用方主动取消时保留原始错误,
|
|
13
|
+
* 以便按 `AbortError` 判断;其余网络失败带上原始错误作为 cause。
|
|
14
|
+
*
|
|
15
|
+
* Normalises a transport rejection into {@link OvClientError}. A caller-requested
|
|
16
|
+
* abort keeps the original error so it can be recognised as an `AbortError`;
|
|
17
|
+
* every other network failure carries the original error as its cause.
|
|
18
|
+
*/
|
|
19
|
+
export declare function normalizeTransportError(error: unknown, signal?: AbortSignal): never;
|
|
20
|
+
/** 读取文本响应体。读取失败属于传输失败(含取消),必须上报。 */
|
|
21
|
+
export declare function readText(response: Response, signal?: AbortSignal): Promise<string>;
|
|
22
|
+
/** 读取二进制响应体。读取失败同样属于传输失败。 */
|
|
23
|
+
export declare function readBlob(response: Response, signal?: AbortSignal): Promise<Blob>;
|
|
24
|
+
/** 由原生错误外壳构造失败,保留错误码、状态与请求标识。 */
|
|
25
|
+
export declare function toClientError(response: Response, body: unknown, fallbackCode?: string): OvClientError;
|
|
26
|
+
/**
|
|
27
|
+
* 原生接口在 HTTP 200 里用 `status: 'error'` 表达业务失败;命中时抛错。
|
|
28
|
+
* The native API reports business failures as `status: 'error'` inside HTTP 200;
|
|
29
|
+
* throw when that happens.
|
|
30
|
+
*/
|
|
31
|
+
export declare function throwIfErrorEnvelope(response: Response, body: unknown): void;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { OvStreamEvent } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* 把事件流字节解成事件。
|
|
4
|
+
*
|
|
5
|
+
* 分帧按规范逐字符进行:`\r`、`\n` 与 `\r\n` 都是行终止符,行终止符之后紧跟的
|
|
6
|
+
* `\n` 属于同一个 CRLF,跳过即可。一个空行结束事件块,块内按行取字段。
|
|
7
|
+
*
|
|
8
|
+
* 关键在于 `\r` 必须**立即**结束当前行,不能留在缓冲区等下一个 chunk:服务端
|
|
9
|
+
* 用纯 CR 换行时,`data: one\r\r` 本身就已经是完整事件,等更多字节会让一个已经
|
|
10
|
+
* 到达的事件永远发不出去(流保持打开时就是挂死)。
|
|
11
|
+
*
|
|
12
|
+
* 早先的实现在块之间找「两个终止符」的连续片段,那样必须等第二个 `\r` 之后确认
|
|
13
|
+
* 没有跟 `\n` 才能分帧,因此才会出现上述挂起。
|
|
14
|
+
*
|
|
15
|
+
* 流结束时残留的一行与块仍会派发——规范要求丢弃,但服务端漏掉末尾空行时那样会
|
|
16
|
+
* 静默吞掉最后一个事件,代价更大;残缺的 JSON 由调用方解析失败后忽略。
|
|
17
|
+
*
|
|
18
|
+
* Decodes event-stream bytes into events.
|
|
19
|
+
*
|
|
20
|
+
* Framing follows the specification character by character: `\r`, `\n` and `\r\n`
|
|
21
|
+
* all terminate a line, and a `\n` immediately after a `\r` belongs to the same
|
|
22
|
+
* CRLF, so it is skipped. A blank line ends an event block, and fields are read
|
|
23
|
+
* line by line inside it.
|
|
24
|
+
*
|
|
25
|
+
* The point is that `\r` must end the current line **immediately** rather than
|
|
26
|
+
* being held until the next chunk: with CR-only line endings, `data: one\r\r` is
|
|
27
|
+
* already a complete event, and waiting for more bytes means an event that has
|
|
28
|
+
* arrived never dispatches — which hangs while the stream stays open.
|
|
29
|
+
*
|
|
30
|
+
* An earlier implementation searched for a run of two terminators between blocks,
|
|
31
|
+
* which required seeing past the second `\r` to know no `\n` followed, and that is
|
|
32
|
+
* exactly what caused the stall.
|
|
33
|
+
*
|
|
34
|
+
* A trailing line and block are still dispatched on end — the specification says to
|
|
35
|
+
* drop them, but a server that omits the final blank line would then lose its last
|
|
36
|
+
* event silently, which costs more; truncated JSON fails to parse and is ignored by
|
|
37
|
+
* the caller.
|
|
38
|
+
*/
|
|
39
|
+
export declare function decodeEventStream(body: ReadableStream<Uint8Array>): ReadableStream<OvStreamEvent>;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { OvClientOptions, OvRequestOptions, OvResolvedOptions, OvStream, OvStreamSpec } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* `stream()` 需要的两件外部能力:发一次请求,以及解析本次请求生效的配置。
|
|
4
|
+
* 抽成参数而不是复制实现,是为了让流式逻辑单独成文件、守住单文件行数上限。
|
|
5
|
+
*
|
|
6
|
+
* The two capabilities `stream()` needs: send one request, and resolve the
|
|
7
|
+
* configuration in effect for it. They are passed in rather than duplicated so the
|
|
8
|
+
* streaming logic can live in its own file and stay within the per-file line limit.
|
|
9
|
+
*/
|
|
10
|
+
export interface StreamDeps {
|
|
11
|
+
send: (spec: OvStreamSpec, headers?: Record<string, string>, signal?: AbortSignal, resolved?: OvResolvedOptions) => Promise<{
|
|
12
|
+
response: Response;
|
|
13
|
+
effective: OvResolvedOptions;
|
|
14
|
+
}>;
|
|
15
|
+
resolveFor: (defaults: OvClientOptions, override: OvRequestOptions | undefined) => Promise<OvResolvedOptions>;
|
|
16
|
+
defaults: OvClientOptions;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* 建立一条事件流:自己的控制器与调用方取消联动,建立阶段的失败按普通请求上报,
|
|
20
|
+
* 迭代结束(正常结束、提前 `break` 或出错)都释放底层流。
|
|
21
|
+
*
|
|
22
|
+
* Opens an event stream: its own controller is linked to caller cancellation, setup
|
|
23
|
+
* failures are reported like an ordinary request, and every way iteration ends —
|
|
24
|
+
* completion, an early `break` or an error — releases the underlying stream.
|
|
25
|
+
*/
|
|
26
|
+
export declare function openStream(spec: OvStreamSpec, { send, resolveFor, defaults }: StreamDeps): Promise<OvStream>;
|
package/dist/client/types.d.ts
CHANGED
|
@@ -111,6 +111,15 @@ export interface OvRequestSpec {
|
|
|
111
111
|
path: string;
|
|
112
112
|
query?: Readonly<Record<string, OvQueryValue>>;
|
|
113
113
|
body?: unknown;
|
|
114
|
+
/**
|
|
115
|
+
* 响应体的读取方式。省略时为 `json`:解析原生外壳并返回 `result`。需要原始
|
|
116
|
+
* 字节时传 `blob`,此时 `TResult` 应声明为 `Blob`。
|
|
117
|
+
*
|
|
118
|
+
* How the response body is read. Omitted means `json`: the native envelope is
|
|
119
|
+
* parsed and its `result` returned. Pass `blob` for raw bytes, declaring
|
|
120
|
+
* `TResult` as `Blob`.
|
|
121
|
+
*/
|
|
122
|
+
responseType?: OvResponseType;
|
|
114
123
|
/**
|
|
115
124
|
* 本次请求的身份、作用域与服务地址覆盖,例如切换到另一个库或另一个网关。
|
|
116
125
|
* Identity, scope and service-address override for this request, for example
|
|
@@ -118,6 +127,24 @@ export interface OvRequestSpec {
|
|
|
118
127
|
*/
|
|
119
128
|
options?: OvRequestOptions;
|
|
120
129
|
}
|
|
130
|
+
/**
|
|
131
|
+
* 响应体的读取方式:`json` 解析外壳后返回 `result`,`blob` 返回原始字节。
|
|
132
|
+
* How the response body is read: `json` parses the envelope and returns
|
|
133
|
+
* `result`, `blob` returns the raw bytes.
|
|
134
|
+
*/
|
|
135
|
+
export type OvResponseType = 'json' | 'blob';
|
|
136
|
+
/**
|
|
137
|
+
* 一次 JSON 请求的外壳与 `result`。列表接口把 `has_more` 放在 `result` 之外,
|
|
138
|
+
* 需要分页时用 {@link OvClient.requestEnvelope} 才能读到它。
|
|
139
|
+
* The envelope and `result` of one JSON request. A listing puts `has_more`
|
|
140
|
+
* outside `result`, so paging reads it through {@link OvClient.requestEnvelope}.
|
|
141
|
+
*/
|
|
142
|
+
export interface OvResponseEnvelope<TResult = unknown> {
|
|
143
|
+
/** 原生响应的 `result`。The native response's `result`. */
|
|
144
|
+
result: TResult;
|
|
145
|
+
/** 是否还有下一页;接口不返回该字段时为 `false`。 */
|
|
146
|
+
hasMore: boolean;
|
|
147
|
+
}
|
|
121
148
|
/** 查询参数可接受的值;`undefined` 与 `null` 表示不发送。 */
|
|
122
149
|
export type OvQueryValue = string | number | boolean | null | undefined | readonly (string | number | boolean)[];
|
|
123
150
|
/**
|
|
@@ -139,6 +166,65 @@ export interface OvErrorEnvelope {
|
|
|
139
166
|
details?: unknown;
|
|
140
167
|
};
|
|
141
168
|
}
|
|
169
|
+
/**
|
|
170
|
+
* 一个 SSE 事件。字段按 SSE 规范解析,`data` 保持原文——OpenViking 把事件类型
|
|
171
|
+
* 与事件 id 放在 `data` 的 JSON 里,不占 SSE 的 `event` / `id` 字段,调用方需要
|
|
172
|
+
* 自己解析 `data` 才能读到它们。
|
|
173
|
+
*
|
|
174
|
+
* One SSE event. Fields follow the SSE specification and `data` stays raw:
|
|
175
|
+
* OpenViking puts the event type and event id inside the `data` JSON rather than
|
|
176
|
+
* in the SSE `event` / `id` fields, so a caller parses `data` to read them.
|
|
177
|
+
*/
|
|
178
|
+
export interface OvStreamEvent {
|
|
179
|
+
/**
|
|
180
|
+
* `data:` 字段,多行按换行拼接,原样保留不做 JSON 解析。
|
|
181
|
+
* The `data:` field, with multiple lines joined by newlines and kept verbatim.
|
|
182
|
+
*/
|
|
183
|
+
data: string;
|
|
184
|
+
/**
|
|
185
|
+
* `event:` 字段,服务端未发送时省略。
|
|
186
|
+
* The `event:` field, omitted when the server sends none.
|
|
187
|
+
*/
|
|
188
|
+
event?: string;
|
|
189
|
+
/**
|
|
190
|
+
* `id:` 字段,服务端未发送时省略。
|
|
191
|
+
* The `id:` field, omitted when the server sends none.
|
|
192
|
+
*/
|
|
193
|
+
id?: string;
|
|
194
|
+
/**
|
|
195
|
+
* `retry:` 字段,单位毫秒,服务端未发送时省略。
|
|
196
|
+
* The `retry:` field in milliseconds, omitted when the server sends none.
|
|
197
|
+
*/
|
|
198
|
+
retry?: number;
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* 一次流式请求。除 `headers` 外与 {@link OvRequestSpec} 相同。
|
|
202
|
+
* A streaming request. It matches {@link OvRequestSpec} apart from `headers`.
|
|
203
|
+
*/
|
|
204
|
+
export interface OvStreamSpec extends Omit<OvRequestSpec, 'responseType'> {
|
|
205
|
+
/**
|
|
206
|
+
* 追加的请求头。身份字段仍由 Client 组装并在同名时胜出,调用方无法误改凭证。
|
|
207
|
+
* `accept: text/event-stream` 默认发送,可在此覆盖。
|
|
208
|
+
*
|
|
209
|
+
* Extra request headers. Identity headers are still assembled by the Client
|
|
210
|
+
* and win on a name clash, so a caller cannot accidentally replace a
|
|
211
|
+
* credential. `accept: text/event-stream` is sent by default and may be
|
|
212
|
+
* overridden here.
|
|
213
|
+
*/
|
|
214
|
+
headers?: Readonly<Record<string, string>>;
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* 已建立的流。异步迭代得到事件,`abort` 中止请求后迭代器以 `AbortError` 拒绝。
|
|
218
|
+
* 响应体边读边消费,因此只能迭代一次。
|
|
219
|
+
*
|
|
220
|
+
* An open stream. Iterating yields events; `abort` stops the request and the
|
|
221
|
+
* iterator then rejects with an `AbortError`. The body is consumed as it is
|
|
222
|
+
* read, so it can be iterated only once.
|
|
223
|
+
*/
|
|
224
|
+
export interface OvStream extends AsyncIterable<OvStreamEvent> {
|
|
225
|
+
/** 中止请求并释放连接。Aborts the request and releases the connection. */
|
|
226
|
+
abort: () => void;
|
|
227
|
+
}
|
|
142
228
|
/**
|
|
143
229
|
* 框架无关的请求能力。库自带基于 `fetch` 的实现,宿主也可以自行实现以复用
|
|
144
230
|
* 已有请求层;模块只依赖本接口。
|
|
@@ -152,6 +238,24 @@ export interface OvClient {
|
|
|
152
238
|
* Sends one request and returns the native response's `result`.
|
|
153
239
|
*/
|
|
154
240
|
request<TResult>(spec: OvRequestSpec): Promise<TResult>;
|
|
241
|
+
/**
|
|
242
|
+
* 与 `request` 相同,但同时返回 `result` 之外的分页标记。列表接口用它判断
|
|
243
|
+
* 是否还有下一页;`responseType: 'blob'` 不适用。
|
|
244
|
+
*
|
|
245
|
+
* Same as `request`, but also returns the pagination flag that sits outside
|
|
246
|
+
* `result`. A listing uses it to decide whether a next page exists; not
|
|
247
|
+
* applicable to `responseType: 'blob'`.
|
|
248
|
+
*/
|
|
249
|
+
requestEnvelope<TResult>(spec: OvRequestSpec): Promise<OvResponseEnvelope<TResult>>;
|
|
250
|
+
/**
|
|
251
|
+
* 建立一条 SSE 流。响应到达后即返回,事件随后逐个产出;HTTP 失败、非事件流
|
|
252
|
+
* 响应与外壳里的 `status: 'error'` 都在返回前抛出。
|
|
253
|
+
*
|
|
254
|
+
* Opens an SSE stream. It resolves once the response arrives and yields events
|
|
255
|
+
* afterwards; an HTTP failure, a non-event-stream response and a
|
|
256
|
+
* `status: 'error'` envelope all throw before it resolves.
|
|
257
|
+
*/
|
|
258
|
+
stream(spec: OvStreamSpec): Promise<OvStream>;
|
|
155
259
|
/**
|
|
156
260
|
* 当前生效的服务地址,用于缓存键与订阅隔离。
|
|
157
261
|
* The effective service address, used to isolate caches and subscriptions.
|
package/dist/client.js
CHANGED
|
@@ -1,239 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import { createContext, useContext as external_react_useContext, useMemo } from "react";
|
|
3
|
-
class OvClientError extends Error {
|
|
4
|
-
code;
|
|
5
|
-
statusCode;
|
|
6
|
-
details;
|
|
7
|
-
requestId;
|
|
8
|
-
responseBody;
|
|
9
|
-
constructor(options){
|
|
10
|
-
super(options.message, void 0 === options.cause ? void 0 : {
|
|
11
|
-
cause: options.cause
|
|
12
|
-
});
|
|
13
|
-
this.name = 'OvClientError';
|
|
14
|
-
this.code = options.code;
|
|
15
|
-
this.statusCode = options.statusCode;
|
|
16
|
-
this.details = options.details;
|
|
17
|
-
this.requestId = options.requestId;
|
|
18
|
-
this.responseBody = options.responseBody;
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
function isOvClientError(value) {
|
|
22
|
-
return value instanceof OvClientError;
|
|
23
|
-
}
|
|
24
|
-
const IDENTITY_HEADERS = {
|
|
25
|
-
apiKey: 'X-API-Key',
|
|
26
|
-
accountId: 'X-OpenViking-Account',
|
|
27
|
-
userId: 'X-OpenViking-User',
|
|
28
|
-
resourceId: 'V-Resource-Id'
|
|
29
|
-
};
|
|
30
|
-
async function evaluate(value) {
|
|
31
|
-
if (void 0 === value) return;
|
|
32
|
-
return 'function' == typeof value ? await value() : value;
|
|
33
|
-
}
|
|
34
|
-
async function resolveIdentityLayer(options) {
|
|
35
|
-
const layer = {};
|
|
36
|
-
for (const field of Object.keys(IDENTITY_HEADERS)){
|
|
37
|
-
const value = await evaluate(options?.[field]);
|
|
38
|
-
if (void 0 !== value) layer[field] = value;
|
|
39
|
-
}
|
|
40
|
-
return layer;
|
|
41
|
-
}
|
|
42
|
-
function mergeIdentityLayers(far, near) {
|
|
43
|
-
return {
|
|
44
|
-
...far,
|
|
45
|
-
...near
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
function toHeaders(layer) {
|
|
49
|
-
const out = {};
|
|
50
|
-
for (const field of Object.keys(IDENTITY_HEADERS)){
|
|
51
|
-
const value = layer[field]?.trim();
|
|
52
|
-
if (value) out[IDENTITY_HEADERS[field].toLowerCase()] = value;
|
|
53
|
-
}
|
|
54
|
-
return out;
|
|
55
|
-
}
|
|
56
|
-
function resolveClientOptions(options, identity) {
|
|
57
|
-
return {
|
|
58
|
-
baseURL: options.baseURL ?? '',
|
|
59
|
-
credentials: options.credentials ?? 'same-origin',
|
|
60
|
-
headers: toHeaders(identity),
|
|
61
|
-
signal: options.signal
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
function resolveRequestOptions(local, parent, mergedLayer) {
|
|
65
|
-
const headers = {
|
|
66
|
-
...parent.headers
|
|
67
|
-
};
|
|
68
|
-
for (const field of Object.keys(IDENTITY_HEADERS)){
|
|
69
|
-
const value = mergedLayer[field];
|
|
70
|
-
if (void 0 === value) continue;
|
|
71
|
-
const name = IDENTITY_HEADERS[field].toLowerCase();
|
|
72
|
-
if (value.trim()) headers[name] = value;
|
|
73
|
-
else delete headers[name];
|
|
74
|
-
}
|
|
75
|
-
return {
|
|
76
|
-
baseURL: local?.baseURL ?? parent.baseURL,
|
|
77
|
-
credentials: parent.credentials,
|
|
78
|
-
headers,
|
|
79
|
-
signal: local?.signal ?? parent.signal
|
|
80
|
-
};
|
|
81
|
-
}
|
|
82
|
-
function joinUrl(baseURL, path) {
|
|
83
|
-
const prefix = baseURL.replace(/\/+$/, '');
|
|
84
|
-
return `${prefix}${path.startsWith('/') ? path : `/${path}`}`;
|
|
85
|
-
}
|
|
86
|
-
function buildQuery(query) {
|
|
87
|
-
if (!query) return '';
|
|
88
|
-
const params = new URLSearchParams();
|
|
89
|
-
for (const [key, value] of Object.entries(query))if (null != value) {
|
|
90
|
-
if (Array.isArray(value)) {
|
|
91
|
-
for (const item of value)params.append(key, String(item));
|
|
92
|
-
continue;
|
|
93
|
-
}
|
|
94
|
-
params.set(key, String(value));
|
|
95
|
-
}
|
|
96
|
-
const text = params.toString();
|
|
97
|
-
return text ? `?${text}` : '';
|
|
98
|
-
}
|
|
99
|
-
function mergeProviderConfig(inherited, local) {
|
|
100
|
-
const declared = {};
|
|
101
|
-
if (void 0 !== local.apiKey) declared.apiKey = local.apiKey;
|
|
102
|
-
if (void 0 !== local.accountId) declared.accountId = local.accountId;
|
|
103
|
-
if (void 0 !== local.userId) declared.userId = local.userId;
|
|
104
|
-
if (void 0 !== local.resourceId) declared.resourceId = local.resourceId;
|
|
105
|
-
return {
|
|
106
|
-
baseURL: local.baseURL ?? inherited?.baseURL,
|
|
107
|
-
credentials: local.credentials ?? inherited?.credentials,
|
|
108
|
-
signal: local.signal ?? inherited?.signal,
|
|
109
|
-
fetch: local.fetch ?? inherited?.fetch,
|
|
110
|
-
identity: {
|
|
111
|
-
...inherited?.identity,
|
|
112
|
-
...declared
|
|
113
|
-
}
|
|
114
|
-
};
|
|
115
|
-
}
|
|
116
|
-
function isRecord(value) {
|
|
117
|
-
return 'object' == typeof value && null !== value && !Array.isArray(value);
|
|
118
|
-
}
|
|
119
|
-
function readEnvelope(value) {
|
|
120
|
-
return isRecord(value) ? value : {};
|
|
121
|
-
}
|
|
122
|
-
function isAbortError(error) {
|
|
123
|
-
return isRecord(error) && ('AbortError' === error.name || 'ABORT_ERR' === error.code);
|
|
124
|
-
}
|
|
125
|
-
function normalizeTransportError(error, signal) {
|
|
126
|
-
if (isAbortError(error) || signal?.aborted) throw error;
|
|
127
|
-
throw new OvClientError({
|
|
128
|
-
code: 'NETWORK_ERROR',
|
|
129
|
-
message: error instanceof Error ? error.message : 'Network request failed',
|
|
130
|
-
cause: error
|
|
131
|
-
});
|
|
132
|
-
}
|
|
133
|
-
function createOvClient(options = {}) {
|
|
134
|
-
const fetchImpl = options.fetch ?? globalThis.fetch;
|
|
135
|
-
if (!fetchImpl) throw new Error('createOvClient needs a fetch implementation. Pass `fetch` on platforms without a global one.');
|
|
136
|
-
const defaults = options;
|
|
137
|
-
const client = {
|
|
138
|
-
get baseURL () {
|
|
139
|
-
return defaults.baseURL ?? '';
|
|
140
|
-
},
|
|
141
|
-
async request (spec) {
|
|
142
|
-
const baseLayer = await resolveIdentityLayer(defaults);
|
|
143
|
-
const localLayer = await resolveIdentityLayer(spec.options);
|
|
144
|
-
const parent = resolveClientOptions(defaults, baseLayer);
|
|
145
|
-
const effective = resolveRequestOptions(spec.options, parent, mergeIdentityLayers(baseLayer, localLayer));
|
|
146
|
-
const url = joinUrl(effective.baseURL, spec.path) + buildQuery(spec.query);
|
|
147
|
-
const hasBody = void 0 !== spec.body;
|
|
148
|
-
const headers = hasBody ? {
|
|
149
|
-
'content-type': 'application/json',
|
|
150
|
-
...effective.headers
|
|
151
|
-
} : effective.headers;
|
|
152
|
-
let response;
|
|
153
|
-
try {
|
|
154
|
-
response = await fetchImpl(url, {
|
|
155
|
-
method: spec.method,
|
|
156
|
-
headers,
|
|
157
|
-
body: hasBody ? JSON.stringify(spec.body) : void 0,
|
|
158
|
-
credentials: effective.credentials,
|
|
159
|
-
signal: effective.signal
|
|
160
|
-
});
|
|
161
|
-
} catch (error) {
|
|
162
|
-
normalizeTransportError(error, effective.signal);
|
|
163
|
-
}
|
|
164
|
-
let raw;
|
|
165
|
-
try {
|
|
166
|
-
raw = await response.text();
|
|
167
|
-
} catch (error) {
|
|
168
|
-
normalizeTransportError(error, effective.signal);
|
|
169
|
-
}
|
|
170
|
-
let body;
|
|
171
|
-
if (raw.trim()) try {
|
|
172
|
-
body = JSON.parse(raw);
|
|
173
|
-
} catch {
|
|
174
|
-
body = raw;
|
|
175
|
-
}
|
|
176
|
-
const envelope = readEnvelope(body);
|
|
177
|
-
const requestId = response.headers.get('x-request-id') ?? void 0;
|
|
178
|
-
if (!response.ok) throw new OvClientError({
|
|
179
|
-
code: envelope.error?.code ?? `HTTP_${response.status}`,
|
|
180
|
-
message: envelope.error?.message ?? response.statusText,
|
|
181
|
-
statusCode: response.status,
|
|
182
|
-
details: envelope.error?.details,
|
|
183
|
-
requestId,
|
|
184
|
-
responseBody: body
|
|
185
|
-
});
|
|
186
|
-
if ('error' === envelope.status) throw new OvClientError({
|
|
187
|
-
code: envelope.error?.code ?? 'UNKNOWN',
|
|
188
|
-
message: envelope.error?.message ?? 'Request failed',
|
|
189
|
-
statusCode: response.status,
|
|
190
|
-
details: envelope.error?.details,
|
|
191
|
-
requestId,
|
|
192
|
-
responseBody: body
|
|
193
|
-
});
|
|
194
|
-
return 'result' in envelope ? envelope.result : body;
|
|
195
|
-
}
|
|
196
|
-
};
|
|
197
|
-
return client;
|
|
198
|
-
}
|
|
199
|
-
const OvClientContext = /*#__PURE__*/ createContext(null);
|
|
200
|
-
function OpenVikingProvider({ baseURL, apiKey, accountId, userId, resourceId, credentials, signal, fetch, children }) {
|
|
201
|
-
const parent = external_react_useContext(OvClientContext);
|
|
202
|
-
const value = useMemo(()=>{
|
|
203
|
-
const base = mergeProviderConfig(parent?.base, {
|
|
204
|
-
baseURL,
|
|
205
|
-
apiKey,
|
|
206
|
-
accountId,
|
|
207
|
-
userId,
|
|
208
|
-
resourceId,
|
|
209
|
-
credentials,
|
|
210
|
-
signal,
|
|
211
|
-
fetch
|
|
212
|
-
});
|
|
213
|
-
return {
|
|
214
|
-
base,
|
|
215
|
-
client: createOvClient({
|
|
216
|
-
...base.identity,
|
|
217
|
-
baseURL: base.baseURL,
|
|
218
|
-
credentials: base.credentials,
|
|
219
|
-
signal: base.signal,
|
|
220
|
-
fetch: base.fetch
|
|
221
|
-
})
|
|
222
|
-
};
|
|
223
|
-
}, [
|
|
224
|
-
parent,
|
|
225
|
-
baseURL,
|
|
226
|
-
apiKey,
|
|
227
|
-
accountId,
|
|
228
|
-
userId,
|
|
229
|
-
resourceId,
|
|
230
|
-
credentials,
|
|
231
|
-
signal,
|
|
232
|
-
fetch
|
|
233
|
-
]);
|
|
234
|
-
return /*#__PURE__*/ jsx(OvClientContext.Provider, {
|
|
235
|
-
value: value,
|
|
236
|
-
children: children
|
|
237
|
-
});
|
|
238
|
-
}
|
|
239
|
-
export { OpenVikingProvider, OvClientError, createOvClient, isOvClientError };
|
|
1
|
+
export { OV_PATHS, OV_PATH_BUILDERS, OpenVikingProvider, OvClientError, createOvClient, isOvClientError } from "./1~0.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
.ov-agent-connect, .ov-file-browser, .ov-file-preview, .ov-file-tree, .ov-module-placeholder, .ov-scope-switcher, .ov-tooltip, .ov-tui, .ov-viking-bot, .ov-viking-bot__interaction {
|
|
1
|
+
.ov-agent-connect, .ov-divider, .ov-file-browser, .ov-file-browser-entries, .ov-file-preview, .ov-file-tree, .ov-module-placeholder, .ov-popover, .ov-scope-switcher, .ov-tooltip, .ov-tui, .ov-viking-bot, .ov-viking-bot__interaction {
|
|
2
2
|
--ov-ui-primary-default: #5252ff;
|
|
3
3
|
--ov-ui-primary-hover-default: #7075ff;
|
|
4
4
|
--ov-ui-primary-active-default: #3833d2;
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
--ov-ui-tooltip-text-default: #fff;
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
.dark .ov-agent-connect, .dark .ov-file-browser, .dark .ov-file-preview, .dark .ov-file-tree, .dark .ov-module-placeholder, .dark .ov-scope-switcher, .dark .ov-tooltip, .dark .ov-tui, .dark .ov-viking-bot, .dark .ov-viking-bot__interaction {
|
|
33
|
+
.dark .ov-agent-connect, .dark .ov-divider, .dark .ov-file-browser, .dark .ov-file-browser-entries, .dark .ov-file-preview, .dark .ov-file-tree, .dark .ov-module-placeholder, .dark .ov-popover, .dark .ov-scope-switcher, .dark .ov-tooltip, .dark .ov-tui, .dark .ov-viking-bot, .dark .ov-viking-bot__interaction {
|
|
34
34
|
--ov-ui-primary-default: #5f5fff;
|
|
35
35
|
--ov-ui-primary-hover-default: #7075ff;
|
|
36
36
|
--ov-ui-primary-active-default: #4242ba;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 入口条的两个图标。
|
|
3
|
+
*
|
|
4
|
+
* 路径取自控制台 `assets/context-console/` 下的 `connect-agent.svg` 与
|
|
5
|
+
* `upload.svg`,只把 `vector-effect="non-scaling-stroke"` 去掉——本包的图标按
|
|
6
|
+
* viewBox 原尺寸渲染,不需要它。描边宽度 1.4 与圆头圆角保持原值。
|
|
7
|
+
*
|
|
8
|
+
* The two icons of the entry row.
|
|
9
|
+
*
|
|
10
|
+
* The paths come from `connect-agent.svg` and `upload.svg` under the console's
|
|
11
|
+
* `assets/context-console/`; only `vector-effect="non-scaling-stroke"` is dropped,
|
|
12
|
+
* because this package renders icons at their viewBox size and does not need it.
|
|
13
|
+
* The 1.4 stroke width and the round caps and joins are kept as-is.
|
|
14
|
+
*/
|
|
15
|
+
/** 连接 Agent 图标,14 × 14 的插头。Connect-agent icon: a 14 × 14 plug. */
|
|
16
|
+
export declare function ConnectAgentIcon(): import("react").JSX.Element;
|
|
17
|
+
/** 导入资源图标,12 × 12 的方框向上箭头。Import-resources icon: a 12 × 12 box with an up arrow. */
|
|
18
|
+
export declare function ImportResourcesIcon(): import("react").JSX.Element;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { FileBrowserEntriesProps } from './types.js';
|
|
2
|
+
export type { FileBrowserEntriesLabels, FileBrowserEntriesProps, } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* 文件浏览入口条:连接 Agent 与导入资源。
|
|
5
|
+
*
|
|
6
|
+
* 两项都省略回调时不渲染任何东西,入口条因此整块消失——宿主既没接连接也没接
|
|
7
|
+
* 导入时,留一条空白底色只会让人以为还有内容没加载出来。
|
|
8
|
+
*
|
|
9
|
+
* The file browser entry row: connect an agent, import resources.
|
|
10
|
+
*
|
|
11
|
+
* With both callbacks omitted nothing renders and the row disappears entirely —
|
|
12
|
+
* leaving an empty tinted strip would suggest something failed to load.
|
|
13
|
+
*/
|
|
14
|
+
export declare function FileBrowserEntries({ onConnectAgent, onImportResources, labels, className, ...rest }: FileBrowserEntriesProps): import("react").JSX.Element | null;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './file-browser-entries.js';
|