@lark-base-open/base-site-channel 0.1.1 → 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/README.md CHANGED
@@ -1,47 +1,47 @@
1
1
  # @lark-base-open/base-site-channel
2
2
 
3
- 用于宿主页面与 iframe 页面之间的双向调用。
3
+ Bidirectional communication between a host page and an iframe page.
4
4
 
5
- ## 适用场景
5
+ ## When to use it
6
6
 
7
- - 宿主页面需要嵌入一个 iframe 页面
8
- - 宿主页面需要主动调用 iframe 内提供的能力
9
- - iframe 页面也需要反向调用宿主页面提供的能力
10
- - 希望通过统一的调用方式管理双方通信
7
+ - A host page embeds an iframe page.
8
+ - The host needs to call APIs exposed by the iframe.
9
+ - The iframe also needs to call APIs exposed by the host.
10
+ - Both sides need one consistent communication model.
11
11
 
12
- ## 对外能力
12
+ ## Public capabilities
13
13
 
14
- - Host 侧创建 iframe 容器并加载目标页面
15
- - Host 侧监听页面加载状态
16
- - Host 侧注册可被 Client 调用的方法
17
- - Host 侧主动调用 Client 提供的方法
18
- - Host 侧订阅 Client 派发的事件
19
- - Host 侧主动向 Client 派发事件
20
- - Client 侧注册可被 Host 调用的方法
21
- - Client 侧主动调用 Host 提供的方法
22
- - Client 侧订阅 Host 派发的事件
23
- - Client 侧主动向 Host 派发事件
24
- - Client 侧直接使用内置批量二进制拉取能力,从 Host 内部 worker 拉取 URLList
14
+ - Create an iframe container and load its page from the Host.
15
+ - Observe the iframe load status from the Host.
16
+ - Register Host methods that the Client can call.
17
+ - Call Client methods from the Host.
18
+ - Subscribe to Client events from the Host.
19
+ - Emit events to the Client from the Host.
20
+ - Register Client methods that the Host can call.
21
+ - Call Host methods from the Client.
22
+ - Subscribe to Host events from the Client.
23
+ - Emit events to the Host from the Client.
24
+ - Use the built-in batch binary fetch API to fetch a URL list through the Host's internal worker.
25
25
 
26
- ## 导出内容
26
+ ## Exports
27
27
 
28
28
  ```ts
29
29
  import { Host, LoadStatus, client } from "@lark-base-open/base-site-channel";
30
30
  ```
31
31
 
32
- ## 快速开始
32
+ ## Quick start
33
33
 
34
- ### 1. 在 Host 页面创建通信实例
34
+ ### 1. Create a channel in the Host page
35
35
 
36
- Host 负责:
36
+ The Host is responsible for:
37
37
 
38
- - 创建 iframe
39
- - 加载 client 页面地址
40
- - 监听加载状态
41
- - 注册给 client 使用的方法
42
- - 调用 client 方法
43
- - 订阅 client 事件
44
- - 派发事件给 client
38
+ - Creating the iframe.
39
+ - Loading the Client page URL.
40
+ - Observing the load status.
41
+ - Registering methods for the Client.
42
+ - Calling Client methods.
43
+ - Subscribing to Client events.
44
+ - Emitting events to the Client.
45
45
 
46
46
  ```ts
47
47
  import { Host, LoadStatus } from "@lark-base-open/base-site-channel";
@@ -56,7 +56,7 @@ const host = new Host(
56
56
  container,
57
57
  (status, errorInfo) => {
58
58
  if (status === LoadStatus.ERROR) {
59
- console.error("页面加载失败", errorInfo);
59
+ console.error("Page failed to load", errorInfo);
60
60
  }
61
61
  },
62
62
  "demo-block",
@@ -65,7 +65,7 @@ const host = new Host(
65
65
  host.setClientUrl("https://example.com/view");
66
66
  ```
67
67
 
68
- ### 2. 在 Host 页面注册可被 Client 调用的方法
68
+ ### 2. Register Host methods callable by the Client
69
69
 
70
70
  ```ts
71
71
  host.registerApi<{ userId: string }, { name: string }>(
@@ -78,7 +78,7 @@ host.registerApi<{ userId: string }, { name: string }>(
78
78
  );
79
79
  ```
80
80
 
81
- ### 3. 在 Host 页面主动调用 Client 方法
81
+ ### 3. Call a Client method from the Host
82
82
 
83
83
  ```ts
84
84
  const result = await host.invokeApi<{ keyword: string }, { total: number }>(
@@ -89,22 +89,22 @@ const result = await host.invokeApi<{ keyword: string }, { total: number }>(
89
89
  );
90
90
  ```
91
91
 
92
- ### 4. 在 Host 页面订阅 Client 事件
92
+ ### 4. Subscribe to Client events from the Host
93
93
 
94
94
  ```ts
95
95
  const unsubscribe = host.subscribeEvent<{ count: number }>(
96
96
  "dataChange",
97
97
  (payload) => {
98
- // 监听 client 派发的事件
98
+ // Handle an event emitted by the Client.
99
99
  console.log("host receive dataChange", payload.count);
100
100
  },
101
101
  );
102
102
 
103
- // 不再需要时取消订阅
103
+ // Unsubscribe when this listener is no longer needed.
104
104
  unsubscribe();
105
105
  ```
106
106
 
107
- ### 5. 在 Host 页面主动向 Client 派发事件
107
+ ### 5. Emit an event to the Client from the Host
108
108
 
109
109
  ```ts
110
110
  await host.emitEvent("themeChange", {
@@ -112,11 +112,11 @@ await host.emitEvent("themeChange", {
112
112
  });
113
113
  ```
114
114
 
115
- ## Client 页面使用方式
115
+ ## Using the Client in an iframe page
116
116
 
117
- Client 侧直接使用库导出的单例 `client`,适合在 iframe 页面中直接接入。
117
+ The Client can use the exported `client` singleton directly in an iframe page.
118
118
 
119
- ### 1. 在 Client 页面注册可被 Host 调用的方法
119
+ ### 1. Register Client methods callable by the Host
120
120
 
121
121
  ```ts
122
122
  import { client } from "@lark-base-open/base-site-channel";
@@ -131,7 +131,7 @@ client.registerApi<{ keyword: string }, { total: number }>(
131
131
  );
132
132
  ```
133
133
 
134
- ### 2. 在 Client 页面主动调用 Host 方法
134
+ ### 2. Call a Host method from the Client
135
135
 
136
136
  ```ts
137
137
  const userInfo = await client.invokeApi<{ userId: string }, { name: string }>(
@@ -142,22 +142,22 @@ const userInfo = await client.invokeApi<{ userId: string }, { name: string }>(
142
142
  );
143
143
  ```
144
144
 
145
- ### 3. 在 Client 页面订阅 Host 事件
145
+ ### 3. Subscribe to Host events from the Client
146
146
 
147
147
  ```ts
148
148
  const unsubscribe = client.subscribeEvent<{ theme: string }>(
149
149
  "themeChange",
150
150
  (payload) => {
151
- // 监听 host 派发的事件
151
+ // Handle an event emitted by the Host.
152
152
  console.log("client receive themeChange", payload.theme);
153
153
  },
154
154
  );
155
155
 
156
- // 不再需要时取消订阅
156
+ // Unsubscribe when this listener is no longer needed.
157
157
  unsubscribe();
158
158
  ```
159
159
 
160
- ### 4. 在 Client 页面主动向 Host 派发事件
160
+ ### 4. Emit an event to the Host from the Client
161
161
 
162
162
  ```ts
163
163
  await client.emitEvent("dataChange", {
@@ -165,63 +165,63 @@ await client.emitEvent("dataChange", {
165
165
  });
166
166
  ```
167
167
 
168
- ## 推荐使用流程
168
+ ## Recommended flow
169
169
 
170
- ### Host 侧流程
170
+ ### Host flow
171
171
 
172
- 1. 准备一个用于挂载 iframe 的容器元素
173
- 2. 创建 `Host` 实例,建议传入唯一的 `instanceId`
174
- 3. 先通过 `registerApi` 暴露宿主能力
175
- 4. 再调用 `setClientUrl` 加载 iframe 页面
176
- 5. 在需要监听 client 状态变化时通过 `subscribeEvent` 订阅事件
177
- 6. 在业务需要时通过 `invokeApi` 调用 client 能力,或通过 `emitEvent` 派发事件
178
- 7. 页面卸载时调用 `destroy`
172
+ 1. Prepare a container element for the iframe.
173
+ 2. Create a `Host` instance with a unique `instanceId`.
174
+ 3. Expose Host methods with `registerApi` before loading the iframe.
175
+ 4. Load the iframe page with `setClientUrl`.
176
+ 5. Subscribe to Client state changes with `subscribeEvent` when needed.
177
+ 6. Call Client methods with `invokeApi` or emit events with `emitEvent` as needed.
178
+ 7. Call `destroy` when the page unmounts.
179
179
 
180
- ### Client 侧流程
180
+ ### Client flow
181
181
 
182
- 1. 在 iframe 页面中引入 `client`
183
- 2. 通过 `registerApi` 暴露 iframe 页面能力
184
- 3. 在需要监听 host 状态变化时通过 `subscribeEvent` 订阅事件
185
- 4. 在业务需要时通过 `invokeApi` 调用 host 能力,或通过 `emitEvent` 派发事件
182
+ 1. Import `client` in the iframe page.
183
+ 2. Expose iframe methods with `registerApi`.
184
+ 3. Subscribe to Host state changes with `subscribeEvent` when needed.
185
+ 4. Call Host methods with `invokeApi` or emit events with `emitEvent` as needed.
186
186
 
187
- ## 加载状态说明
187
+ ## Load status
188
188
 
189
- `LoadStatus` 包含以下几种状态:
189
+ `LoadStatus` has these values:
190
190
 
191
- - `pending`:初始状态
192
- - `loading`:正在加载 iframe 页面
193
- - `loaded`:页面已可正常通信
194
- - `error`:加载失败或通信不可用
191
+ - `pending`: Initial state.
192
+ - `loading`: The iframe page is loading.
193
+ - `loaded`: The page can communicate with the Host.
194
+ - `error`: Loading failed or communication is unavailable.
195
195
 
196
- 常见处理方式:
196
+ Typical handling:
197
197
 
198
- - `loading` 时展示加载中状态
199
- - `loaded` 后再执行依赖 iframe 的业务操作
200
- - `error` 时展示错误提示,并根据需要允许重试
198
+ - Show a loading state while `loading`.
199
+ - Run iframe-dependent operations only after `loaded`.
200
+ - Show an error and offer a retry when the status is `error`.
201
201
 
202
- ## 构造参数说明
202
+ ## Constructor options
203
203
 
204
204
  `new Host(containerEl, onLoadStatusChange, instanceId, allowedOrigin, extraAttributes, options)`
205
205
 
206
- - `containerEl`:iframe 挂载容器
207
- - `onLoadStatusChange`:页面状态变化回调
208
- - `instanceId`:当前通信实例标识,建议保持唯一
209
- - `allowedOrigin`:允许通信的绝对 URL 或 origin 列表;非法配置会被拒绝,不支持正则或通配符
210
- - `extraAttributes`:附加到 iframe 上的属性
211
- - `options`:Host 可选配置对象
212
- - `options.enableBinaryFetch`:是否允许 Client 调用内置二进制 fetch,默认 `false`;Site Runtime 接入必须保持关闭
206
+ - `containerEl`: Element that contains the iframe.
207
+ - `onLoadStatusChange`: Callback for page status changes.
208
+ - `instanceId`: Identifier for this channel instance; keep it unique.
209
+ - `allowedOrigin`: Allowed absolute URLs or origins. Invalid settings are rejected; regular expressions and wildcards are unsupported.
210
+ - `extraAttributes`: Additional iframe attributes.
211
+ - `options`: Optional Host settings.
212
+ - `options.enableBinaryFetch`: Whether the Client may use built-in binary fetching. Defaults to `false` and must stay disabled for Site Runtime integration.
213
213
 
214
- ## 通信日志
214
+ ## Communication logs
215
215
 
216
- Host 与 Client 的握手、`invokeApi/registerApi`、`emitEvent/subscribeEvent`、回调和销毁日志统一在 Channel API 内部记录。运行环境存在 `window.BearWebSlardarWeb` 时通过 `sendLog` 上报,统一使用 `event_name=Runtime_SiteChannel_Message`,并通过 `channel_side`、`channel_message`、`key` 等脱敏字段区分阶段;没有 Slardar 实例或实例调用失败时,降级到对应级别的 `console.info/warn/error`。
216
+ The Channel API logs Host and Client handshakes, API calls, events, callbacks, and teardown. If `window.BearWebSlardarWeb` is available, it reports through `sendLog` with `event_name=Runtime_SiteChannel_Message` and redacted fields such as `channel_side`, `channel_message`, and `key`. Otherwise it falls back to `console.info`, `console.warn`, or `console.error` at the matching level.
217
217
 
218
- Client 调用 `invokeApi` 时生成 `logId` 并记录 `api request sent`;Host 收到后记录 `api request received`,返回时记录 `api response sent` 并复用同一个 `logId`;Client 收到回调后记录 `api response received`。这些日志只记录操作阶段、方法 key、状态和错误类型等必要元数据,不记录请求参数或响应内容;标识符只记录是否存在。业务方不需要在每个 Channel 调用点重复打印通信日志。
218
+ The Client assigns a `logId` when it sends an `invokeApi` request. The Host records the same ID when receiving the request and sending the response; the Client records it when receiving the callback. Logs contain the phase, method key, status, and error type, but no request parameters or response body. Identifiers are logged only as present or absent. Callers do not need to log every Channel operation again.
219
219
 
220
- `invoke` 与 `callback` 已由上述 API 语义日志覆盖,不再额外记录 `send message to host/client` 或 `receive host/client message`;通用收发日志仅用于握手、事件等其他消息类型。
220
+ API-level logs already cover `invoke` and `callback`; generic send/receive logs are reserved for handshakes, events, and other message types.
221
221
 
222
222
  ## Site Runtime
223
223
 
224
- 本包同时提供 Site iframe 专用 Runtime 门面,业务方不需要直接操作底层 Channel:
224
+ The package also provides a Site iframe Runtime interface so business pages do not need to use the low-level Channel directly:
225
225
 
226
226
  ```ts
227
227
  import {
@@ -239,74 +239,74 @@ await logout();
239
239
  await siteRuntime.ready();
240
240
  ```
241
241
 
242
- - `./runtime`:子页面使用的 HTTP、Function、生命周期和 Chatbot stream API
243
- - `./runtime-contract`:父子页面共享的 `site.v1` key、payload、类型和稳定错误码
244
- - `requestEdit()`:通知父页面申请进入编辑态
245
- - `getCurrentUser()`:读取父页面登录用户信息,稳定包含 `name`、`avatarUrl`
246
- - `logout()`:请求父页面退出当前登录态
247
- - 上述三个方法统一通过 `site.v1.function.invoke` 调用内置 Runtime Function,不新增平级 Channel API
242
+ - `./runtime`: HTTP, Function, lifecycle, and Chatbot stream APIs for the child page.
243
+ - `./runtime-contract`: Shared `site.v1` keys, payloads, types, and stable error codes.
244
+ - `requestEdit()`: Ask the parent page to enter edit mode.
245
+ - `getCurrentUser()`: Read the signed-in user from the parent page; always includes `name` and `avatarUrl`.
246
+ - `logout()`: Ask the parent page to sign out the current user.
247
+ - These three methods use the built-in Runtime Functions through `site.v1.function.invoke`; they do not add peer Channel APIs.
248
248
 
249
- ## 常用方法说明
249
+ ## Common methods
250
250
 
251
251
  ### Host
252
252
 
253
- - `setClientUrl(url)`:设置并加载 client 页面地址
254
- - `registerApi(key, handler)`:注册给 client 使用的方法
255
- - `invokeApi(key, params)`:调用 client 方法
256
- - `subscribeEvent(key, handler)`:订阅 client 派发的事件,返回取消订阅函数
257
- - `unsubscribeEvent(key, handler?)`:取消指定事件订阅,不传 `handler` 时移除该事件全部订阅
258
- - `emitEvent(key, params)`:主动向 client 派发事件
259
- - `destroy()`:销毁实例并释放资源
253
+ - `setClientUrl(url)`: Set and load the Client page URL.
254
+ - `registerApi(key, handler)`: Register a method callable by the Client.
255
+ - `invokeApi(key, params)`: Call a Client method.
256
+ - `subscribeEvent(key, handler)`: Subscribe to Client events; returns an unsubscribe function.
257
+ - `unsubscribeEvent(key, handler?)`: Remove a subscription, or all subscriptions for the event if `handler` is omitted.
258
+ - `emitEvent(key, params)`: Emit an event to the Client.
259
+ - `destroy()`: Destroy the instance and release its resources.
260
260
 
261
261
  ### Client
262
262
 
263
- - `registerApi(key, handler)`:注册给 host 使用的方法
264
- - `invokeApi(key, params)`:调用 host 方法
265
- - `subscribeEvent(key, handler)`:订阅 host 派发的事件,返回取消订阅函数
266
- - `unsubscribeEvent(key, handler?)`:取消指定事件订阅,不传 `handler` 时移除该事件全部订阅
267
- - `emitEvent(key, params)`:主动向 host 派发事件
268
- - `fetchBinaryList(params)`:发起内置批量二进制拉取任务,返回 `{ jobId }`
269
- - `subscribeBinaryFetchProgress(handler)`:订阅内置批量二进制拉取进度
270
- - `cancelBinaryFetch(jobId)`:取消指定的二进制拉取任务
263
+ - `registerApi(key, handler)`: Register a method callable by the Host.
264
+ - `invokeApi(key, params)`: Call a Host method.
265
+ - `subscribeEvent(key, handler)`: Subscribe to Host events; returns an unsubscribe function.
266
+ - `unsubscribeEvent(key, handler?)`: Remove a subscription, or all subscriptions for the event if `handler` is omitted.
267
+ - `emitEvent(key, params)`: Emit an event to the Host.
268
+ - `fetchBinaryList(params)`: Start a batch binary fetch job and return its `{ jobId }`.
269
+ - `subscribeBinaryFetchProgress(handler)`: Subscribe to binary fetch progress.
270
+ - `cancelBinaryFetch(jobId)`: Cancel a binary fetch job.
271
271
 
272
- ## 内置批量二进制拉取能力
272
+ ## Built-in batch binary fetching
273
273
 
274
- 这套能力用于 Host <-> iframe 场景下的大文件、图片密文或附件密文传输。
274
+ Use this API to transfer large files, encrypted images, or encrypted attachments between a Host and an iframe.
275
275
 
276
- ### 为什么 iframe 里直接拉 URL 会被拦
276
+ ### Why direct iframe downloads can fail
277
277
 
278
- 在很多接入场景里:
278
+ A common integration has these constraints:
279
279
 
280
- - iframe 页面运行在外网沙箱域名
281
- - 文件下载地址位于内网域名或受限 CDN 域名
282
- - iframe 内直接执行 `fetch(url).arrayBuffer()` 时会受到浏览器 CORS 限制
280
+ - The iframe runs on an external sandbox origin.
281
+ - Download URLs point to internal domains or restricted CDN origins.
282
+ - A direct `fetch(url).arrayBuffer()` from the iframe is blocked by browser CORS.
283
283
 
284
- 即使业务已经拿到下载地址,只要浏览器判定当前 iframe 页面来源无权访问该资源,请求仍然会失败。
284
+ A download URL alone does not grant access from the iframe origin; the browser can still reject the request.
285
285
 
286
- ### 为什么把拉取动作放到 Host
286
+ ### Why the Host performs the fetch
287
287
 
288
- Host 页面通常运行在具备访问权限的环境中,可以正常访问这些内网或受限域名。因此更合理的方案是:
288
+ The Host often runs in an environment that can reach those internal or restricted origins. The flow is:
289
289
 
290
- 1. iframe 只负责描述“要拉哪些 URL”
291
- 2. Host 在内部 worker 中真正执行批量下载
292
- 3. 每个文件下载完成后立刻把完整 `ArrayBuffer` 渐进式回传给 iframe
293
- 4. iframe 拿到密文 bytes 后再自行解密、生成 `Blob` 或 `blobUrl`
290
+ 1. The iframe describes which URLs to fetch.
291
+ 2. The Host downloads them in an internal worker.
292
+ 3. After each download, the Host progressively transfers the complete `ArrayBuffer` to the iframe.
293
+ 4. The iframe decrypts the bytes and creates a `Blob` or `blobUrl` as needed.
294
294
 
295
- 业务层不需要自己额外封装 host worker,也不需要自己设计底层 `postMessage` 协议。
295
+ Business code does not need another Host worker or a custom `postMessage` protocol.
296
296
 
297
- ### 为什么回传要使用 Transferable
297
+ ### Why responses use Transferable objects
298
298
 
299
- 二进制文件可能很大,如果直接走普通结构化拷贝,主线程和 iframe 之间会产生额外复制成本。内置能力会使用:
299
+ Large binary files are expensive to copy between the main thread and an iframe. The built-in API uses:
300
300
 
301
301
  ```ts
302
302
  postMessage(message, "*", [arrayBuffer]);
303
303
  ```
304
304
 
305
- 把 `ArrayBuffer` 作为 `Transferable` 传输,避免大块二进制在通信层重复拷贝,更适合图片密文、附件密文这类场景。
305
+ The `ArrayBuffer` is transferred as a `Transferable`, avoiding another large copy for encrypted images and attachments.
306
306
 
307
- ### 对外 API
307
+ ### Public API
308
308
 
309
- Client / iframe 侧直接使用以下内置 API:
309
+ The Client or iframe calls these built-in APIs:
310
310
 
311
311
  ```ts
312
312
  type BinaryFetchItem = {
@@ -355,18 +355,18 @@ client.subscribeBinaryFetchProgress(handler: (progress: BinaryFetchProgress) =>
355
355
  client.cancelBinaryFetch(jobId: string): Promise<void>;
356
356
  ```
357
357
 
358
- 说明:
358
+ Notes:
359
359
 
360
- - 不需要业务层手动 `registerApi`
361
- - Host 会在内部自动启用专用 worker
362
- - 默认支持并发控制
363
- - 单个 job 默认并发为 `4`
364
- - 单 worker 下的全局总并发上限默认是 `6`
365
- - `credentials` 可选,默认使用 `same-origin`
366
- - 每个文件下载完成后会一次性回传完整 `ArrayBuffer`
367
- - 如果握手未完成,`fetchBinaryList` 和 `cancelBinaryFetch` 会像 `invokeApi` 一样直接 reject
360
+ - Business code does not need to call `registerApi` for this feature.
361
+ - The Host starts the dedicated worker internally.
362
+ - Concurrency is controlled by default.
363
+ - Each job defaults to `4` concurrent downloads.
364
+ - A single worker defaults to a global maximum of `6` concurrent downloads.
365
+ - `credentials` is optional and defaults to `same-origin`.
366
+ - Each completed file transfers its full `ArrayBuffer` once.
367
+ - `fetchBinaryList` and `cancelBinaryFetch` reject before the handshake completes, like `invokeApi`.
368
368
 
369
- ### 如何发起 URLList 拉取
369
+ ### Start a URL-list fetch
370
370
 
371
371
  ```ts
372
372
  import { client } from "@lark-base-open/base-site-channel";
@@ -387,7 +387,7 @@ const { jobId } = await client.fetchBinaryList({
387
387
  });
388
388
  ```
389
389
 
390
- ### 如何订阅 progress
390
+ ### Subscribe to progress
391
391
 
392
392
  ```ts
393
393
  const unsubscribe = client.subscribeBinaryFetchProgress((progress) => {
@@ -426,21 +426,21 @@ const unsubscribe = client.subscribeBinaryFetchProgress((progress) => {
426
426
  });
427
427
  ```
428
428
 
429
- ### 如何取消任务
429
+ ### Cancel a job
430
430
 
431
431
  ```ts
432
432
  await client.cancelBinaryFetch(jobId);
433
433
  unsubscribe();
434
434
  ```
435
435
 
436
- ### 完整示例
436
+ ### Complete example
437
437
 
438
- 下面的示例演示:
438
+ This example shows how to:
439
439
 
440
- - client 发起 `fetchBinaryList`
441
- - client 监听 `item-complete`
442
- - 业务层按 `itemId` 接收完整 `ArrayBuffer`
443
- - 最终在 iframe 中自行解密并生成 `blobUrl`
440
+ - Start `fetchBinaryList` from the Client.
441
+ - Receive `item-complete` progress events.
442
+ - Use `itemId` to associate each complete `ArrayBuffer` with its request.
443
+ - Decrypt the bytes and create a `blobUrl` in the iframe.
444
444
 
445
445
  ```ts
446
446
  import { client } from "@lark-base-open/base-site-channel";
@@ -503,7 +503,7 @@ function decryptFileBytes(
503
503
  return Promise.resolve(buffer);
504
504
  }
505
505
 
506
- // 业务需要时可以取消
506
+ // Cancel when the business flow no longer needs this job.
507
507
  if (shouldCancelJob(jobId)) {
508
508
  await client.cancelBinaryFetch(jobId);
509
509
  }
@@ -513,9 +513,9 @@ function shouldCancelJob(targetJobId: string) {
513
513
  }
514
514
  ```
515
515
 
516
- ### 进度消息结构
516
+ ### Progress message shape
517
517
 
518
- 内置 progress 消息包含以下几种类型:
518
+ Built-in progress messages have these types:
519
519
 
520
520
  ```ts
521
521
  type BinaryFetchProgress =
@@ -549,70 +549,70 @@ type BinaryFetchProgress =
549
549
  };
550
550
  ```
551
551
 
552
- ## Event 使用说明
552
+ ## Events
553
553
 
554
- 事件通信适合处理“状态变化通知”这类不需要返回值的场景,比如:
554
+ Use events for one-way state changes that need no return value, for example:
555
555
 
556
- - 宿主页面主题切换后通知 iframe 页面更新样式
557
- - iframe 页面数据变更后通知宿主页面刷新外层状态
558
- - 双方同步选中态、表单状态、可见性等轻量级状态
556
+ - Notify the iframe to update its style when the Host theme changes.
557
+ - Notify the Host to refresh outer-page state when iframe data changes.
558
+ - Synchronize lightweight selection, form, or visibility state.
559
559
 
560
- 与 `invokeApi` 的区别:
560
+ How they differ from `invokeApi`:
561
561
 
562
- - `invokeApi` 适合请求-响应场景,调用方需要拿到返回值
563
- - `emitEvent` 适合单向通知场景,发送后不等待业务返回值
564
- - `subscribeEvent` 用于订阅对端派发的事件
562
+ - Use `invokeApi` for request-response operations that need a result.
563
+ - Use `emitEvent` for one-way notifications; it does not await a business result.
564
+ - Use `subscribeEvent` to receive events emitted by the other side.
565
565
 
566
- ### Host 订阅 Client 事件
566
+ ### Subscribe to Client events from the Host
567
567
 
568
568
  ```ts
569
569
  const stopListenDataChange = host.subscribeEvent<{ count: number }>(
570
570
  "dataChange",
571
571
  (payload) => {
572
- // 当 iframe 页面发生数据变化时,宿主页面会收到通知
572
+ // Refresh Host state after data changes in the iframe.
573
573
  console.log("host receive dataChange", payload.count);
574
574
  },
575
575
  );
576
576
  ```
577
577
 
578
- ### Client 向 Host 派发事件
578
+ ### Emit an event to the Host from the Client
579
579
 
580
580
  ```ts
581
581
  client.emitEvent("dataChange", {
582
- // 通知 host 当前数据已变化
582
+ // Tell the Host that data changed.
583
583
  count: 1,
584
584
  });
585
585
  ```
586
586
 
587
- ### Client 订阅 Host 事件
587
+ ### Subscribe to Host events from the Client
588
588
 
589
589
  ```ts
590
590
  const stopListenThemeChange = client.subscribeEvent<{
591
591
  theme: "light" | "dark";
592
592
  }>("themeChange", (payload) => {
593
- // 监听 host 的主题变化事件
593
+ // Handle a Host theme change.
594
594
  document.body.dataset.theme = payload.theme;
595
595
  });
596
596
  ```
597
597
 
598
- ### Host 向 Client 派发事件
598
+ ### Emit an event to the Client from the Host
599
599
 
600
600
  ```ts
601
601
  client.emitEvent("themeChange", {
602
- // 通知 client 同步主题
602
+ // Ask the Client to apply the new theme.
603
603
  theme: "dark",
604
604
  });
605
605
  ```
606
606
 
607
- ### 取消订阅
607
+ ### Unsubscribe
608
608
 
609
- 推荐优先使用 `subscribeEvent` 返回的取消函数:
609
+ Prefer the cleanup function returned by `subscribeEvent`:
610
610
 
611
611
  ```ts
612
612
  const unsubscribe = client.subscribeEvent<{ visible: boolean }>(
613
613
  "visibleChange",
614
614
  (payload) => {
615
- // 处理可见性变化
615
+ // Handle a visibility change.
616
616
  console.log(payload.visible);
617
617
  },
618
618
  );
@@ -620,11 +620,11 @@ const unsubscribe = client.subscribeEvent<{ visible: boolean }>(
620
620
  unsubscribe();
621
621
  ```
622
622
 
623
- 也可以通过 `unsubscribeEvent` 主动移除:
623
+ You can also remove a listener with `unsubscribeEvent`:
624
624
 
625
625
  ```ts
626
626
  const onVisibleChange = (payload: { visible: boolean }) => {
627
- // 处理可见性变化
627
+ // Handle a visibility change.
628
628
  console.log(payload.visible);
629
629
  };
630
630
 
@@ -632,16 +632,16 @@ client.subscribeEvent("visibleChange", onVisibleChange);
632
632
  client.unsubscribeEvent("visibleChange", onVisibleChange);
633
633
  ```
634
634
 
635
- 使用建议:
635
+ Recommendations:
636
636
 
637
- - 事件 `key` 建议使用明确的业务语义名称,例如 `themeChange`、`dataChange`
638
- - 事件更适合通知类场景,不建议替代有返回值的接口调用
639
- - 建议在页面销毁、组件卸载时及时取消订阅,避免重复监听
640
- - 事件参数建议保持轻量、稳定,避免传递难以序列化的数据
637
+ - Give event `key` values clear business names, such as `themeChange` or `dataChange`.
638
+ - Use events for notifications, not as substitutes for calls that return values.
639
+ - Unsubscribe when a page or component unmounts to avoid duplicate listeners.
640
+ - Keep event payloads small and stable; avoid values that are difficult to serialize.
641
641
 
642
- ## invokeApi 报错说明
642
+ ## Errors from invokeApi
643
643
 
644
- `invokeApi` 在调用失败时会返回一个被拒绝的 Promise,错误对象格式如下:
644
+ A failed `invokeApi` call rejects its Promise with an error object shaped like this:
645
645
 
646
646
  ```ts
647
647
  type InvokeApiError = {
@@ -650,7 +650,7 @@ type InvokeApiError = {
650
650
  };
651
651
  ```
652
652
 
653
- 建议统一使用 `try/catch` 处理:
653
+ Handle failures with `try/catch`:
654
654
 
655
655
  ```ts
656
656
  try {
@@ -664,44 +664,44 @@ try {
664
664
  } catch (error) {
665
665
  const invokeError = error;
666
666
  console.error(
667
- "调用失败",
667
+ "Request failed",
668
668
  invokeError?.code,
669
669
  invokeError?.msg || invokeError?.message,
670
670
  );
671
671
  }
672
672
  ```
673
673
 
674
- 常见报错场景:
674
+ Common failure cases:
675
675
 
676
- - 业务接口报错
677
- - iframe 页面加载失败
678
- - 当前加载地址不在允许通信范围内
679
- - 页面未完成初始化,导致调用超时
680
- - 对端方法内部执行失败,并返回业务错误
676
+ - A business API fails.
677
+ - The iframe page fails to load.
678
+ - The current page URL is outside the allowed origins.
679
+ - Page initialization has not completed before the call times out.
680
+ - The remote method fails and returns a business error.
681
681
 
682
- 常见错误码:
682
+ Common error codes:
683
683
 
684
- - 业务接口错误码
685
- - `-1`:未知错误
686
- - `10001`:iframe 加载失败
687
- - `10002`:当前页面地址不允许通信
688
- - `10003`:页面初始化超时
689
- - `10004`:对端未注册该 API
690
- - `10005`:调用超时
691
- - `10006`:通道已销毁
692
- - `10007`:内置二进制下载能力未开启
693
- - `10008`:同一请求 id 被新请求顶替
694
- - `10009`:当前环境不具备建联条件(非 iframe 环境、拿不到 host origin、Host 尚未 `setClientUrl`)
684
+ - Codes returned by business APIs.
685
+ - `-1`: Unknown error.
686
+ - `10001`: Iframe load failed.
687
+ - `10002`: The current page URL is not allowed to communicate.
688
+ - `10003`: Page initialization timed out.
689
+ - `10004`: The remote API is not registered.
690
+ - `10005`: The call timed out.
691
+ - `10006`: The channel has been destroyed.
692
+ - `10007`: Built-in binary downloading is disabled.
693
+ - `10008`: Another request replaced one with the same ID.
694
+ - `10009`: The environment cannot establish a channel (for example, not an iframe, no Host origin, or `setClientUrl` has not been called).
695
695
 
696
- 处理建议:
696
+ Handling recommendations:
697
697
 
698
- - 在 `loaded` 状态后再调用 `invokeApi`
699
- - Host 侧先完成 `registerApi`,再执行 `setClientUrl`
700
- - 将业务异常转换为明确的 `code` 和 `msg` 返回,便于调用方统一处理
698
+ - Call `invokeApi` only after the status becomes `loaded`.
699
+ - On the Host, finish `registerApi` calls before `setClientUrl`.
700
+ - Convert business failures into specific `code` and `msg` values for consistent handling by callers.
701
701
 
702
- ## 完整示例
702
+ ## Complete example
703
703
 
704
- ### Host 页面
704
+ ### Host page
705
705
 
706
706
  ```ts
707
707
  import { Host, LoadStatus } from "@lark-base-open/base-site-channel";
@@ -716,7 +716,7 @@ const host = new Host(
716
716
  container,
717
717
  (status) => {
718
718
  if (status === LoadStatus.LOADED) {
719
- console.log("client 页面已就绪");
719
+ console.log("Client page is ready");
720
720
  }
721
721
  },
722
722
  "demo-block",
@@ -754,7 +754,7 @@ host.emitEvent("themeChange", {
754
754
  stopListenDataChange();
755
755
  ```
756
756
 
757
- ### Client 页面
757
+ ### Client page
758
758
 
759
759
  ```ts
760
760
  import { client } from "@lark-base-open/base-site-channel";
@@ -789,9 +789,9 @@ client.emitEvent("dataChange", {
789
789
  stopListenThemeChange();
790
790
  ```
791
791
 
792
- ## 使用建议
792
+ ## Recommendations
793
793
 
794
- - `key` 建议按业务语义命名,避免重复
795
- - `instanceId` 建议为每个 iframe 实例保持唯一
796
- - 在 Host 页面销毁、切页或重新挂载时主动调用 `destroy`
797
- - 只有在 iframe 页面已经可用时再发起业务调用
794
+ - Name each `key` by its business purpose and avoid duplicates.
795
+ - Keep `instanceId` unique for each iframe instance.
796
+ - Call `destroy` when the Host page unmounts, navigates away, or remounts.
797
+ - Start business calls only after the iframe is ready.
@@ -185,11 +185,40 @@ interface SiteChatbotStreamError {
185
185
  retryable: boolean;
186
186
  subscriptionId: string;
187
187
  }
188
- type SiteAIMessageRole = 'assistant' | 'system' | 'user';
189
- interface SiteAIStreamMessageParam {
190
- content: string;
191
- role: SiteAIMessageRole;
188
+ interface SiteAITextContentPart {
189
+ text: string;
190
+ type: 'text';
191
+ }
192
+ interface SiteAIImageContentPart {
193
+ detail?: 'high' | 'low' | 'xhigh';
194
+ type: 'image';
195
+ url: string;
196
+ }
197
+ interface SiteAIVideoContentPart {
198
+ fps?: number;
199
+ type: 'video';
200
+ url: string;
201
+ }
202
+ interface SiteAIAudioContentPart {
203
+ type: 'audio';
204
+ url: string;
205
+ }
206
+ /** PDF document input. filename is required when url is a data URL. */
207
+ interface SiteAIFileContentPart {
208
+ filename?: string;
209
+ type: 'file';
210
+ url: string;
211
+ }
212
+ type SiteAIMessageContentPart = SiteAITextContentPart | SiteAIImageContentPart | SiteAIVideoContentPart | SiteAIAudioContentPart | SiteAIFileContentPart;
213
+ interface SiteAIUserMessageParam {
214
+ content: SiteAIMessageContentPart[];
215
+ role: 'user';
216
+ }
217
+ interface SiteAITextMessageParam {
218
+ content: SiteAITextContentPart[];
219
+ role: 'assistant';
192
220
  }
221
+ type SiteAIStreamMessageParam = SiteAIUserMessageParam | SiteAITextMessageParam;
193
222
  interface SiteAIStreamDelta {
194
223
  content?: string;
195
224
  raw: unknown;
@@ -310,4 +339,4 @@ interface SiteRuntimeUserInfo {
310
339
  }
311
340
  declare const isValidSiteFunctionName: (functionName: string) => boolean;
312
341
 
313
- export { SITE_RUNTIME_PROTOCOL_VERSION, SiteAICapabilityType, SiteAIFunctionError, SiteAIFunctionResult, SiteAIFunctionStreamCloseRequest, SiteAIFunctionStreamDone, SiteAIFunctionStreamError, SiteAIFunctionStreamMessage, SiteAIFunctionStreamOpenRequest, SiteAIFunctionVariables, SiteAIImageAsset, SiteAIImageTask, SiteAIMediaTask, SiteAIMediaTaskBase, SiteAIMessageRole, SiteAIStreamDelta, SiteAIStreamMessageParam, SiteAITaskStatus, SiteAITextDelta, SiteAIVideoAsset, SiteAIVideoTask, SiteAttachmentTarget, SiteAttachmentUploadCancelRequest, SiteAttachmentUploadOptions, SiteAttachmentUploadPayload, SiteAttachmentUploadProgress, SiteAttachmentUploadRequest, SiteAttachmentUploadResult, SiteChatbotStreamCloseRequest, SiteChatbotStreamError, SiteChatbotStreamMessage, SiteChatbotStreamOpenRequest, SiteFunctionDefinition, SiteFunctionInvokeRequest, SiteHttpCancelRequest, SiteHttpMethod, SiteHttpRequest, SiteHttpRequestInit, SiteHttpRequestOptions, SiteHttpResponse, SiteHttpResponseType, SiteProjectEnv, SiteRuntimeApi, SiteRuntimeContext, SiteRuntimeError, SiteRuntimeErrorCode, SiteRuntimeEvent, SiteRuntimeFunction, SiteRuntimeLoadFailedEvent, SiteRuntimeModeChangedEvent, SiteRuntimeReadyEvent, SiteRuntimeUserInfo, isValidSiteFunctionName, readSiteAITextDelta };
342
+ export { SITE_RUNTIME_PROTOCOL_VERSION, SiteAIAudioContentPart, SiteAICapabilityType, SiteAIFileContentPart, SiteAIFunctionError, SiteAIFunctionResult, SiteAIFunctionStreamCloseRequest, SiteAIFunctionStreamDone, SiteAIFunctionStreamError, SiteAIFunctionStreamMessage, SiteAIFunctionStreamOpenRequest, SiteAIFunctionVariables, SiteAIImageAsset, SiteAIImageContentPart, SiteAIImageTask, SiteAIMediaTask, SiteAIMediaTaskBase, SiteAIMessageContentPart, SiteAIStreamDelta, SiteAIStreamMessageParam, SiteAITaskStatus, SiteAITextContentPart, SiteAITextDelta, SiteAITextMessageParam, SiteAIUserMessageParam, SiteAIVideoAsset, SiteAIVideoContentPart, SiteAIVideoTask, SiteAttachmentTarget, SiteAttachmentUploadCancelRequest, SiteAttachmentUploadOptions, SiteAttachmentUploadPayload, SiteAttachmentUploadProgress, SiteAttachmentUploadRequest, SiteAttachmentUploadResult, SiteChatbotStreamCloseRequest, SiteChatbotStreamError, SiteChatbotStreamMessage, SiteChatbotStreamOpenRequest, SiteFunctionDefinition, SiteFunctionInvokeRequest, SiteHttpCancelRequest, SiteHttpMethod, SiteHttpRequest, SiteHttpRequestInit, SiteHttpRequestOptions, SiteHttpResponse, SiteHttpResponseType, SiteProjectEnv, SiteRuntimeApi, SiteRuntimeContext, SiteRuntimeError, SiteRuntimeErrorCode, SiteRuntimeEvent, SiteRuntimeFunction, SiteRuntimeLoadFailedEvent, SiteRuntimeModeChangedEvent, SiteRuntimeReadyEvent, SiteRuntimeUserInfo, isValidSiteFunctionName, readSiteAITextDelta };
@@ -1 +1 @@
1
- var r="site.v1",s={AIFunctionStreamClose:"site.v1.ai.function.stream.close",AIFunctionStreamOpen:"site.v1.ai.function.stream.open",AttachmentUpload:"site.v1.attachment.upload",AttachmentUploadCancel:"site.v1.attachment.upload.cancel",FunctionInvoke:"site.v1.function.invoke",HttpRequest:"site.v1.http.request",HttpRequestCancel:"site.v1.http.request.cancel",RuntimeContext:"site.v1.runtime.context",StreamClose:"site.v1.chatbot.stream.close",StreamOpen:"site.v1.chatbot.stream.open"},a={AIFunctionStreamDone:"site.v1.ai.function.stream.done",AIFunctionStreamError:"site.v1.ai.function.stream.error",AIFunctionStreamMessage:"site.v1.ai.function.stream.message",AttachmentUploadProgress:"site.v1.attachment.upload.progress",LifecycleLoadFailed:"site.v1.lifecycle.load-failed",LifecycleReady:"site.v1.lifecycle.ready",ModeChanged:"site.v1.runtime.mode-changed",StreamError:"site.v1.chatbot.stream.error",StreamMessage:"site.v1.chatbot.stream.message"},o={GetCurrentUser:"function.runtime.getCurrentUser",Logout:"function.runtime.logout",RequestEdit:"function.runtime.requestEdit"},c={AttachmentUnavailable:"ATTACHMENT_UNAVAILABLE",AttachmentUploadCanceled:"ATTACHMENT_UPLOAD_CANCELED",AttachmentUploadFailed:"ATTACHMENT_UPLOAD_FAILED",AttachmentUploadStalled:"ATTACHMENT_UPLOAD_STALLED",ChannelDestroyed:"CHANNEL_DESTROYED",FunctionNotAllowed:"FUNCTION_NOT_ALLOWED",FunctionRequestFailed:"FUNCTION_REQUEST_FAILED",InvalidAIFunctionTask:"INVALID_AI_FUNCTION_TASK",HttpRequestFailed:"HTTP_REQUEST_FAILED",HttpResponseTypeUnsupported:"HTTP_RESPONSE_TYPE_UNSUPPORTED",HttpRequestCanceled:"HTTP_REQUEST_CANCELED",InvalidAttachmentTarget:"INVALID_ATTACHMENT_TARGET",InvalidFunctionName:"INVALID_FUNCTION_NAME",InvalidHttpHeader:"INVALID_HTTP_HEADER",InvalidHttpUrl:"INVALID_HTTP_URL",LogoutFailed:"LOGOUT_FAILED",ProtocolMismatch:"PROTOCOL_MISMATCH",RequestTimeout:"REQUEST_TIMEOUT",StreamDisconnected:"STREAM_DISCONNECTED",StreamHealthTimeout:"STREAM_HEALTH_TIMEOUT",StreamInterrupted:"STREAM_INTERRUPTED",StreamOpenFailed:"STREAM_OPEN_FAILED",StreamSeqGap:"STREAM_SEQ_GAP",StreamUnavailable:"STREAM_UNAVAILABLE",UnsupportedHttpBody:"UNSUPPORTED_HTTP_BODY",UserInfoUnavailable:"USER_INFO_UNAVAILABLE"},p=e=>{var t,n;return{answer:(t=e.content)!=null?t:"",reasoning:(n=e.reasoningContent)!=null?n:""}},i=/^function(?:\.[A-Za-z_][A-Za-z0-9_]*)+$/,S=e=>i.test(e);export{r as SITE_RUNTIME_PROTOCOL_VERSION,s as SiteRuntimeApi,c as SiteRuntimeErrorCode,a as SiteRuntimeEvent,o as SiteRuntimeFunction,S as isValidSiteFunctionName,p as readSiteAITextDelta};
1
+ var r="site.v1",a={AIFunctionStreamClose:"site.v1.ai.function.stream.close",AIFunctionStreamOpen:"site.v1.ai.function.stream.open",AttachmentUpload:"site.v1.attachment.upload",AttachmentUploadCancel:"site.v1.attachment.upload.cancel",FunctionInvoke:"site.v1.function.invoke",HttpRequest:"site.v1.http.request",HttpRequestCancel:"site.v1.http.request.cancel",RuntimeContext:"site.v1.runtime.context",StreamClose:"site.v1.chatbot.stream.close",StreamOpen:"site.v1.chatbot.stream.open"},s={AIFunctionStreamDone:"site.v1.ai.function.stream.done",AIFunctionStreamError:"site.v1.ai.function.stream.error",AIFunctionStreamMessage:"site.v1.ai.function.stream.message",AttachmentUploadProgress:"site.v1.attachment.upload.progress",LifecycleLoadFailed:"site.v1.lifecycle.load-failed",LifecycleReady:"site.v1.lifecycle.ready",ModeChanged:"site.v1.runtime.mode-changed",StreamError:"site.v1.chatbot.stream.error",StreamMessage:"site.v1.chatbot.stream.message"},o={GetCurrentUser:"function.runtime.getCurrentUser",Logout:"function.runtime.logout",RequestEdit:"function.runtime.requestEdit"},p={AttachmentUnavailable:"ATTACHMENT_UNAVAILABLE",AttachmentUploadCanceled:"ATTACHMENT_UPLOAD_CANCELED",AttachmentUploadFailed:"ATTACHMENT_UPLOAD_FAILED",AttachmentUploadStalled:"ATTACHMENT_UPLOAD_STALLED",ChannelDestroyed:"CHANNEL_DESTROYED",FunctionNotAllowed:"FUNCTION_NOT_ALLOWED",FunctionRequestFailed:"FUNCTION_REQUEST_FAILED",InvalidAIFunctionTask:"INVALID_AI_FUNCTION_TASK",HttpRequestFailed:"HTTP_REQUEST_FAILED",HttpResponseTypeUnsupported:"HTTP_RESPONSE_TYPE_UNSUPPORTED",HttpRequestCanceled:"HTTP_REQUEST_CANCELED",InvalidAttachmentTarget:"INVALID_ATTACHMENT_TARGET",InvalidFunctionName:"INVALID_FUNCTION_NAME",InvalidHttpHeader:"INVALID_HTTP_HEADER",InvalidHttpUrl:"INVALID_HTTP_URL",LogoutFailed:"LOGOUT_FAILED",ProtocolMismatch:"PROTOCOL_MISMATCH",RequestTimeout:"REQUEST_TIMEOUT",StreamDisconnected:"STREAM_DISCONNECTED",StreamHealthTimeout:"STREAM_HEALTH_TIMEOUT",StreamInterrupted:"STREAM_INTERRUPTED",StreamOpenFailed:"STREAM_OPEN_FAILED",StreamSeqGap:"STREAM_SEQ_GAP",StreamUnavailable:"STREAM_UNAVAILABLE",UnsupportedHttpBody:"UNSUPPORTED_HTTP_BODY",UserInfoUnavailable:"USER_INFO_UNAVAILABLE"},c=e=>{var t,n;return{answer:(t=e.content)!=null?t:"",reasoning:(n=e.reasoningContent)!=null?n:""}},i=/^function(?:\.[A-Za-z_][A-Za-z0-9_]*)+$/,S=e=>i.test(e);export{r as SITE_RUNTIME_PROTOCOL_VERSION,a as SiteRuntimeApi,p as SiteRuntimeErrorCode,s as SiteRuntimeEvent,o as SiteRuntimeFunction,S as isValidSiteFunctionName,c as readSiteAITextDelta};
package/dist/runtime.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { SiteAttachmentUploadOptions, SiteAttachmentUploadResult, SiteHttpRequestOptions, SiteRuntimeContext, SiteRuntimeUserInfo, SiteRuntimeModeChangedEvent, SiteFunctionDefinition, SiteProjectEnv, SiteAIStreamMessageParam, SiteAIFunctionVariables, SiteAIFunctionError, SiteAIStreamDelta, SiteAIMediaTask, SiteAIFunctionResult } from './runtime-contract.js';
2
- export { SITE_RUNTIME_PROTOCOL_VERSION, SiteAICapabilityType, SiteAIFunctionStreamCloseRequest, SiteAIFunctionStreamDone, SiteAIFunctionStreamError, SiteAIFunctionStreamMessage, SiteAIFunctionStreamOpenRequest, SiteAIImageAsset, SiteAIImageTask, SiteAIMediaTaskBase, SiteAIMessageRole, SiteAITaskStatus, SiteAITextDelta, SiteAIVideoAsset, SiteAIVideoTask, SiteAttachmentTarget, SiteAttachmentUploadCancelRequest, SiteAttachmentUploadPayload, SiteAttachmentUploadProgress, SiteAttachmentUploadRequest, SiteChatbotStreamCloseRequest, SiteChatbotStreamMessage, SiteChatbotStreamOpenRequest, SiteFunctionInvokeRequest, SiteHttpCancelRequest, SiteHttpMethod, SiteHttpRequest, SiteHttpRequestInit, SiteHttpResponse, SiteHttpResponseType, SiteRuntimeApi, SiteRuntimeError, SiteRuntimeErrorCode, SiteRuntimeEvent, SiteRuntimeFunction, SiteRuntimeLoadFailedEvent, SiteRuntimeReadyEvent, isValidSiteFunctionName, readSiteAITextDelta } from './runtime-contract.js';
2
+ export { SITE_RUNTIME_PROTOCOL_VERSION, SiteAIAudioContentPart, SiteAICapabilityType, SiteAIFileContentPart, SiteAIFunctionStreamCloseRequest, SiteAIFunctionStreamDone, SiteAIFunctionStreamError, SiteAIFunctionStreamMessage, SiteAIFunctionStreamOpenRequest, SiteAIImageAsset, SiteAIImageContentPart, SiteAIImageTask, SiteAIMediaTaskBase, SiteAIMessageContentPart, SiteAITaskStatus, SiteAITextContentPart, SiteAITextDelta, SiteAITextMessageParam, SiteAIUserMessageParam, SiteAIVideoAsset, SiteAIVideoContentPart, SiteAIVideoTask, SiteAttachmentTarget, SiteAttachmentUploadCancelRequest, SiteAttachmentUploadPayload, SiteAttachmentUploadProgress, SiteAttachmentUploadRequest, SiteChatbotStreamCloseRequest, SiteChatbotStreamMessage, SiteChatbotStreamOpenRequest, SiteFunctionInvokeRequest, SiteHttpCancelRequest, SiteHttpMethod, SiteHttpRequest, SiteHttpRequestInit, SiteHttpResponse, SiteHttpResponseType, SiteRuntimeApi, SiteRuntimeError, SiteRuntimeErrorCode, SiteRuntimeEvent, SiteRuntimeFunction, SiteRuntimeLoadFailedEvent, SiteRuntimeReadyEvent, isValidSiteFunctionName, readSiteAITextDelta } from './runtime-contract.js';
3
3
 
4
4
  interface RuntimeChannel {
5
5
  emitEvent: <T>(key: string, params: T) => Promise<void>;
package/dist/runtime.mjs CHANGED
@@ -1,4 +1,4 @@
1
- var ct=Object.defineProperty,dt=Object.defineProperties;var ut=Object.getOwnPropertyDescriptors;var N=Object.getOwnPropertySymbols;var ve=Object.prototype.hasOwnProperty,be=Object.prototype.propertyIsEnumerable;var Ae=(t,e,n)=>e in t?ct(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n,a=(t,e)=>{for(var n in e||(e={}))ve.call(e,n)&&Ae(t,n,e[n]);if(N)for(var n of N(e))be.call(e,n)&&Ae(t,n,e[n]);return t},f=(t,e)=>dt(t,ut(e));var Te=(t,e)=>{var n={};for(var r in t)ve.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&N)for(var r of N(t))e.indexOf(r)<0&&be.call(t,r)&&(n[r]=t[r]);return n};var p=(t,e,n)=>new Promise((r,i)=>{var o=c=>{try{d(n.next(c))}catch(m){i(m)}},s=c=>{try{d(n.throw(c))}catch(m){i(m)}},d=c=>c.done?r(c.value):Promise.resolve(c.value).then(o,s);d((n=n.apply(t,e)).next())});import{uniqueId as ee}from"lodash-es";var W="same-origin",Ce="__internal_fetchBinaryList__",Re="__internal_cancelBinaryFetch__",ke="__internal_binaryFetchProgress__";function $(t){return Number.isFinite(t)?Math.max(1,Math.floor(t)):4}function Y(t){return t==="omit"||t==="include"?t:W}var L=(i=>(i.IFRAME_LOAD_ERROR="iframeLoadError",i.NOT_ALLOWED_URL="notAllowedUrl",i.HANDSHAKE_TIME_OUT="handshakeTimeout",i.CHANNEL_UNAVAILABLE="channelUnavailable",i))(L||{});var b=class extends Error{constructor(n,r){super(r);this.code=n,this.name="ChannelCallbackError"}};function Me(t){return new b(10004,`api "${t}" is not registered`)}function Fe(t){return new b(10005,`api "${t}" timed out`)}function G(){return new b(10006,"channel has been destroyed")}function Pe(t){return new b(10008,`request "${t}" was superseded by a new one`)}var lt="unknown error";function we(t){return typeof t=="object"&&t!==null}function pt(t){if(typeof t=="string"&&t)return t;if(t instanceof b&&t.message||t instanceof Error&&t.message)return t.message;if(we(t)){let{msg:e,message:n}=t;if(typeof e=="string"&&e)return e;if(typeof n=="string"&&n)return n}return lt}function ht(t){if(t instanceof b)return t.code;if(!we(t))return-1;let{code:e}=t;return typeof e=="string"&&e||typeof e=="number"&&Number.isFinite(e)?e:-1}function A(t){return{code:ht(t),msg:pt(t)}}function _e(t){return t instanceof ArrayBuffer||ArrayBuffer.isView(t)||typeof Blob!="undefined"&&t instanceof Blob}function mt(t){return _e(t)||Object.values(t).some(e=>_e(e))}function He(t){return t&&typeof t=="object"?mt(t)?t:JSON.parse(JSON.stringify(t)):t}var ft={["iframeLoadError"]:10001,["notAllowedUrl"]:10002,["handshakeTimeout"]:10003,["channelUnavailable"]:10009};function gt(t){return typeof t=="object"&&t!==null}function St(t){if(!gt(t))return!1;let{type:e}=t;return typeof e=="string"&&Object.values(L).includes(e)}function J(t){return St(t)?{code:ft[t.type],msg:t.message||t.type}:A(t)}function X(t){let e=Promise.reject(t);return e.catch(()=>{}),e}var P=class{constructor(e,n){this._target=e,this._options=n}sendMsg(e,n){if(!this._target)throw new Error("target window is not found");this._target.postMessage(e,this._options.targetOrigin,n!=null?n:[])}listenMsg(e){this._eventHandler=n=>{n.source===this._options.sourceWindow&&this._options.allowedOrigins.includes(n.origin)&&e(n)},typeof window!="undefined"&&window.addEventListener("message",this._eventHandler)}destroy(){typeof window!="undefined"&&this._eventHandler&&window.removeEventListener("message",this._eventHandler),this._eventHandler=void 0}};var x=class{constructor(e,n,r){e==="host"?this.channelManager=new P(n,r):e==="client"&&(this.channelManager=new P(window.parent,r))}static createInstance(e,n,r){return new x(e,n,r)}sendMsg(e,n){var r;(r=this.channelManager)==null||r.sendMsg(e,n)}listenMsg(e){var n;(n=this.channelManager)==null||n.listenMsg(e)}destroy(){var e;(e=this.channelManager)==null||e.destroy()}};var O=class{constructor(){this.requests=new Map}create(e,n,r=3e4){return this.reject(e,A(Pe(e))),new Promise((i,o)=>{let s=setTimeout(()=>{var d;((d=this.requests.get(e))==null?void 0:d.timeout)===s&&(this.requests.delete(e),o(A(Fe(n))))},r);this.requests.set(e,{reject:o,resolve:i,timeout:s})})}resolve(e,n){let r=this.take(e);return r?(r.resolve(n),!0):!1}reject(e,n){let r=this.take(e);return r?(r.reject(n),!0):!1}rejectAll(e){for(let n of this.requests.keys())this.reject(n,e)}take(e){let n=this.requests.get(e);if(n)return this.requests.delete(e),clearTimeout(n.timeout),n}};var Q=t=>typeof t=="object"&&t!==null,Et=new Set(["blockId","expectedPrefixId","id","jobId","prefixId","url"]),C=t=>{let e={};for(let[n,r]of Object.entries(t))if(!(n==="inputParams"||n==="outputParams")){if(Et.has(n)){e[`${n}Present`]=!!r;continue}if(n==="error"){Object.assign(e,R(r));continue}if(n==="errorInfo"&&Q(r)){e.errorType=typeof r.type=="string"?r.type:"object";continue}(typeof r=="string"||typeof r=="number"||typeof r=="boolean")&&(e[n]=r)}return e},M=t=>{let e={idPresent:!!t.id,type:t.type},n=Q(t.payload)?t.payload:{};return typeof n.key=="string"&&(e.key=n.key),t.type==="callback"&&typeof n.code=="number"&&(e.callbackCode=n.code),t.type==="handshake"&&typeof n.proactive=="boolean"&&(e.proactive=n.proactive),e},Z=t=>t.type!=="invoke"&&t.type!=="callback",R=t=>{if(!Q(t))return{errorType:typeof t};let e={errorType:t instanceof Error?t.name:"object"};return(typeof t.code=="number"||typeof t.code=="string")&&(e.errorCode=t.code),e};var At=()=>{let t=Reflect.get(globalThis,"BearWebSlardarWeb");return typeof t=="function"?t:void 0},vt=t=>{let e={};for(let[n,r]of Object.entries(C(t)))typeof r=="string"||typeof r=="number"?e[n]=r:typeof r=="boolean"&&(e[n]=String(r));return e},Ne=(t,e,n,r)=>{console[e](`[base-site-channel][${t}]`,n,r)},U=(t,e,n,r={})=>{let i=C(r),o=At();if(!o){Ne(t,e,n,i);return}try{o("sendLog",{content:`[base-site-channel][${t}] ${n}`,extra:a({event_name:"Runtime_SiteChannel_Message",bizType:"Runtime",subType:"SiteChannel",action:"Message",channel_side:t,channel_message:n},vt(i)),level:e})}catch(s){Ne(t,e,n,f(a({},i),{slardarFallback:!0,slardarErrorType:s instanceof Error?s.name:typeof s}))}};var Ct=()=>{var n;if(typeof window=="undefined")return null;let e=((n=window.location.ancestorOrigins)==null?void 0:n[0])||document.referrer;if(!e)return null;try{return new URL(e).origin}catch(r){return null}},Rt=t=>{try{return new URL(t).origin}catch(e){return null}},te=class{constructor(e={}){this.pendingRequests=new O;this.eventMap=new Map;this.eventHandlerMap=new Map;this._msgChannel=null;this._invokeId="";this._handshakePromise=X({type:"channelUnavailable",message:"channel handshake is not initialized"});this._handshakeResolve=null;this._handshakeReject=null;this._handshakeRetryTimes=0;this._handshakeStatus=0;this._handshakeTimeout=null;this._prefixId="";this._destroyed=!1;let n=e.hostOrigin?Rt(e.hostOrigin):null;if(this.hostOrigin=n!=null?n:Ct(),e.hostOrigin&&!n&&this.logWarn("invalid hostOrigin, fallback to parent origin"),typeof window=="undefined"||window.parent===window){this.failHandshake("invalid window context",{hasWindow:typeof window!="undefined",isTopWindow:typeof window!="undefined"?window.parent===window:!0});return}if(!this.hostOrigin){this.failHandshake("host origin unavailable");return}this._msgChannel=x.createInstance("client",window.parent,{allowedOrigins:[this.hostOrigin],sourceWindow:window.parent,targetOrigin:this.hostOrigin}),this.listeningHostMsg(),this.startHandshake()}logInfo(e,n={}){U("client","info",e,a({hasPrefixId:!!this._prefixId,handshakeStatus:this._handshakeStatus},C(n)))}logWarn(e,n={}){U("client","warn",e,a({hasPrefixId:!!this._prefixId,handshakeStatus:this._handshakeStatus},C(n)))}logError(e,n={}){U("client","error",e,a({hasPrefixId:!!this._prefixId,handshakeStatus:this._handshakeStatus},C(n)))}failHandshake(e,n={}){this._handshakeStatus=2,this._handshakePromise=X({type:"channelUnavailable",message:e}),this.logError(`init failed: ${e}`,n)}sendProactiveHandshakeMsg(){var n;let e={id:ee("handshake-"),type:"handshake",payload:{proactive:!0}};this.logInfo("send proactive handshake",M(e)),(n=this._msgChannel)==null||n.sendMsg(e)}_initHandshake(){this._handshakeRetryTimes=0,clearTimeout(this._handshakeTimeout),this._handshakeStatus=0,this.logInfo("init handshake"),this._handshakePromise=new Promise((e,n)=>{this._handshakeResolve=e,this._handshakeReject=n,this._handshakeTimeout=setTimeout(()=>this.retryHandshake(n),2e3)})}startHandshake(){this._initHandshake(),this._handshakePromise.then(()=>{this._handshakeStatus=1,this.logInfo("handshake success")}).catch(e=>{this._handshakeStatus=2,this.logError("handshake failed",{error:e})}),this.sendProactiveHandshakeMsg()}retryHandshake(e){this._handshakeStatus===0&&(this._handshakeRetryTimes<5?(this.logWarn("retry handshake",{retryTimes:this._handshakeRetryTimes+1}),this.sendProactiveHandshakeMsg(),this._handshakeRetryTimes++,this._handshakeTimeout=setTimeout(()=>this.retryHandshake(e),2e3+2**this._handshakeRetryTimes)):(this.logError("handshake retry timeout",{retryTimes:this._handshakeRetryTimes}),e({type:"handshakeTimeout",message:"iframe handshake time out"})))}updateInvokeId(){this._invokeId=ee(`${this._prefixId}-invoke-`)}handleChannelMessage(e){let{data:n}=e;Z(n)&&this.logInfo("receive host message",M(n));let{type:r}=n;r==="callback"?this.handleHostCallback(n):r==="handshake"?this.handleHandshakeCallback(n):r==="invoke"?this.handleHostInvoke(n).catch(i=>{this.logError("handle host invoke error",a(a({},M(n)),R(i)))}):r==="event"&&this.handleHostEvent(n).catch(i=>{this.logError("handle host event error",a(a({},M(n)),R(i)))})}handleHostCallback(e){let{id:n,payload:r}=e,i={logId:n,key:r.key,callbackCode:r.code};if(r.code===1){if(this.pendingRequests.reject(n,r.res)){this.logWarn("api response received",i);return}}else if(this.pendingRequests.resolve(n,r.res)){this.logInfo("api response received",i);return}this.logWarn("host callback request not found",{id:n,key:r.key})}handleHostInvoke(e){return p(this,null,function*(){yield this._handshakePromise;let{id:n,payload:r}=e,{key:i,params:o,prefixId:s}=r;if(s!==this._prefixId){this.logWarn("ignore host invoke because prefixId mismatch",{id:n,key:i,prefixId:s,expectedPrefixId:this._prefixId});return}let d=this.eventMap.get(i);if(typeof d!="function"){this.logWarn("host invoke handler not found",{id:n,key:i}),this.sendMsg2Host({id:n,type:"callback",payload:{key:i,res:A(Me(i)),code:1}});return}this.logInfo("handle host invoke",{id:n,key:i});try{let c=He(yield d(o));this.sendMsg2Host({id:n,type:"callback",payload:{key:i,res:c,code:0}}),this.logInfo("host invoke success",{id:n,key:i})}catch(c){this.logError("host invoke failed",a({id:n,key:i},R(c))),this.sendMsg2Host({id:n,type:"callback",payload:{key:i,res:A(c),code:1}})}})}handleHostEvent(e){return p(this,null,function*(){yield this._handshakePromise;let{payload:n}=e,{key:r,params:i,prefixId:o}=n;if(o!==this._prefixId){this.logWarn("ignore host event because prefixId mismatch",{key:r,prefixId:o,expectedPrefixId:this._prefixId});return}let s=this.eventHandlerMap.get(r);if(!(s!=null&&s.size)){this.logWarn("host event handler not found",{key:r});return}this.logInfo("handle host event",{key:r,handlerCount:s.size}),yield Promise.allSettled(Array.from(s,d=>d(i)))})}handleHandshakeCallback(e){var o,s;let{id:n,payload:r}=e;this._prefixId=(o=r==null?void 0:r.prefixId)!=null?o:"",this.logInfo("receive handshake callback",{id:n,prefixId:this._prefixId}),(s=this._handshakeResolve)==null||s.call(this);let i={id:n,type:"handshake",payload:{proactive:!1,info:{isHandshakeSuccess:!0}}};this.sendMsg2Host(i)}listeningHostMsg(){var e;this.logInfo("start listening host messages"),(e=this._msgChannel)==null||e.listenMsg(this.handleChannelMessage.bind(this))}sendMsg2Host(e,n){var r;Z(e)&&this.logInfo("send message to host",M(e)),(r=this._msgChannel)==null||r.sendMsg(e,n)}invokeApi(e,n,r){return p(this,null,function*(){if(this._destroyed)return Promise.reject(A(G()));try{yield this._handshakePromise}catch(s){return this.logError("invoke api blocked by handshake error",a({key:e},R(s))),Promise.reject(J(s))}this._invokeId||this.updateInvokeId();let i=this._invokeId,o=this.pendingRequests.create(i,e,r==null?void 0:r.timeoutMs);return this.logInfo("api request sent",{key:e,logId:i}),this.sendMsg2Host({type:"invoke",id:i,payload:{key:e,params:n,prefixId:this._prefixId}}),this.updateInvokeId(),o})}registerApi(e,n){if(this.eventMap.has(e)){this.logWarn("register api ignored because key already exists",{key:e});return}this.eventMap.set(e,n),this.logInfo("register api",{key:e})}emitEvent(e,n){return p(this,null,function*(){try{yield this._handshakePromise}catch(r){return this.logError("emit event blocked by handshake error",a({key:e},R(r))),Promise.reject(J(r))}this.logInfo("emit event",{key:e}),this.sendMsg2Host({type:"event",id:ee(`${this._prefixId}-event-`),payload:{key:e,params:n,prefixId:this._prefixId}})})}fetchBinaryList(e){return p(this,null,function*(){var n;return this.logInfo("invoke built-in binary fetch",{status:"start",itemCount:e.items.length,concurrency:$(e.concurrency),credentials:Y(e.credentials)}),this.invokeApi(Ce,{items:e.items,concurrency:$(e.concurrency),credentials:Y((n=e.credentials)!=null?n:W)})})}subscribeBinaryFetchProgress(e){return this.subscribeEvent(ke,e)}cancelBinaryFetch(e){return p(this,null,function*(){this.logInfo("invoke built-in binary fetch cancel",{jobId:e,status:"cancel-requested"}),yield this.invokeApi(Re,{jobId:e})})}destroy(){var n,r;if(this._destroyed)return;this._destroyed=!0,this.logInfo("destroy client"),(n=this._msgChannel)==null||n.destroy(),clearTimeout(this._handshakeTimeout);let e=A(G());(r=this._handshakeReject)==null||r.call(this,{type:"handshakeTimeout",message:e.msg}),this.pendingRequests.rejectAll(e),this.eventMap.clear(),this.eventHandlerMap.clear()}subscribeEvent(e,n){var i;let r=(i=this.eventHandlerMap.get(e))!=null?i:new Set;return r.add(n),this.eventHandlerMap.set(e,r),this.logInfo("subscribe event",{key:e,handlerCount:r.size}),()=>this.unsubscribeEvent(e,n)}unsubscribeEvent(e,n){let r=this.eventHandlerMap.get(e);if(!r){this.logWarn("unsubscribe event ignored because key is not subscribed",{key:e});return}if(!n){this.eventHandlerMap.delete(e),this.logInfo("unsubscribe all event handlers",{key:e,handlerCount:0});return}r.delete(n),r.size===0&&this.eventHandlerMap.delete(e),this.logInfo("unsubscribe event",{key:e,handlerCount:r.size})}},kt=t=>new te(t),k=kt();var Oe="site.v1",g={AIFunctionStreamClose:"site.v1.ai.function.stream.close",AIFunctionStreamOpen:"site.v1.ai.function.stream.open",AttachmentUpload:"site.v1.attachment.upload",AttachmentUploadCancel:"site.v1.attachment.upload.cancel",FunctionInvoke:"site.v1.function.invoke",HttpRequest:"site.v1.http.request",HttpRequestCancel:"site.v1.http.request.cancel",RuntimeContext:"site.v1.runtime.context",StreamClose:"site.v1.chatbot.stream.close",StreamOpen:"site.v1.chatbot.stream.open"},y={AIFunctionStreamDone:"site.v1.ai.function.stream.done",AIFunctionStreamError:"site.v1.ai.function.stream.error",AIFunctionStreamMessage:"site.v1.ai.function.stream.message",AttachmentUploadProgress:"site.v1.attachment.upload.progress",LifecycleLoadFailed:"site.v1.lifecycle.load-failed",LifecycleReady:"site.v1.lifecycle.ready",ModeChanged:"site.v1.runtime.mode-changed",StreamError:"site.v1.chatbot.stream.error",StreamMessage:"site.v1.chatbot.stream.message"},D={GetCurrentUser:"function.runtime.getCurrentUser",Logout:"function.runtime.logout",RequestEdit:"function.runtime.requestEdit"},u={AttachmentUnavailable:"ATTACHMENT_UNAVAILABLE",AttachmentUploadCanceled:"ATTACHMENT_UPLOAD_CANCELED",AttachmentUploadFailed:"ATTACHMENT_UPLOAD_FAILED",AttachmentUploadStalled:"ATTACHMENT_UPLOAD_STALLED",ChannelDestroyed:"CHANNEL_DESTROYED",FunctionNotAllowed:"FUNCTION_NOT_ALLOWED",FunctionRequestFailed:"FUNCTION_REQUEST_FAILED",InvalidAIFunctionTask:"INVALID_AI_FUNCTION_TASK",HttpRequestFailed:"HTTP_REQUEST_FAILED",HttpResponseTypeUnsupported:"HTTP_RESPONSE_TYPE_UNSUPPORTED",HttpRequestCanceled:"HTTP_REQUEST_CANCELED",InvalidAttachmentTarget:"INVALID_ATTACHMENT_TARGET",InvalidFunctionName:"INVALID_FUNCTION_NAME",InvalidHttpHeader:"INVALID_HTTP_HEADER",InvalidHttpUrl:"INVALID_HTTP_URL",LogoutFailed:"LOGOUT_FAILED",ProtocolMismatch:"PROTOCOL_MISMATCH",RequestTimeout:"REQUEST_TIMEOUT",StreamDisconnected:"STREAM_DISCONNECTED",StreamHealthTimeout:"STREAM_HEALTH_TIMEOUT",StreamInterrupted:"STREAM_INTERRUPTED",StreamOpenFailed:"STREAM_OPEN_FAILED",StreamSeqGap:"STREAM_SEQ_GAP",StreamUnavailable:"STREAM_UNAVAILABLE",UnsupportedHttpBody:"UNSUPPORTED_HTTP_BODY",UserInfoUnavailable:"USER_INFO_UNAVAILABLE"},_r=t=>{var e,n;return{answer:(e=t.content)!=null?e:"",reasoning:(n=t.reasoningContent)!=null?n:""}},_t=/^function(?:\.[A-Za-z_][A-Za-z0-9_]*)+$/,Ue=t=>_t.test(t);var xt=0,De=(i,o)=>p(void 0,[i,o],function*(t,{init:e,url:n,signal:r}){if((e==null?void 0:e.responseType)!==void 0&&!["text","arrayBuffer"].includes(e.responseType))throw new I(u.HttpResponseTypeUnsupported,"\u4E0D\u652F\u6301\u7684 HTTP \u54CD\u5E94\u7C7B\u578B");let s=()=>new DOMException("The operation was aborted","AbortError");if(r!=null&&r.aborted)throw s();let d=typeof crypto!="undefined"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():`http-${Date.now()}-${++xt}`,c=()=>{},m=new Promise((h,_)=>{c=()=>{_(s()),t.invokeApi(g.HttpRequestCancel,{requestId:d}).catch(()=>{})}});r==null||r.addEventListener("abort",c,{once:!0});try{let h=yield Promise.race([t.invokeApi(g.HttpRequest,{requestId:d,url:n,init:e},{timeoutMs:(e==null?void 0:e.timeoutMs)===void 0?void 0:Math.min(e.timeoutMs,6e4)+1e3}),m]);if((e==null?void 0:e.responseType)==="arrayBuffer"&&(h.bodyType!=="arrayBuffer"||!(h.body instanceof ArrayBuffer)))throw new I(u.HttpResponseTypeUnsupported,"\u5F53\u524D\u5BBF\u4E3B\u4E0D\u652F\u6301 HTTP \u4E8C\u8FDB\u5236\u54CD\u5E94\uFF0C\u8BF7\u5347\u7EA7\u5BBF\u4E3B");return new Response([204,205,304].includes(h.status)?null:h.body,{headers:h.headers,status:h.status,statusText:h.statusText})}finally{r==null||r.removeEventListener("abort",c)}});var I=class extends Error{constructor(n,r){super(r);this.code=n;this.name="SiteRuntimeInvocationError"}},Be=t=>typeof t=="string"&&t.trim().length>0,Mt=t=>typeof File!="undefined"&&t instanceof File,qe=12e4,Ft=2*60*60*1e3,je=0,Pt=()=>typeof crypto!="undefined"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():(je+=1,`site-upload-${je}`),wt=t=>typeof t=="object"&&t!==null&&"code"in t?t.code:void 0,Ht=t=>{if(t instanceof Error&&t.message)return t.message;if(typeof t=="object"&&t!==null){if("message"in t&&typeof t.message=="string")return t.message;if("msg"in t&&typeof t.msg=="string")return t.msg}return String(t)},Nt=new Set([u.AttachmentUnavailable,u.AttachmentUploadCanceled,u.AttachmentUploadFailed,u.AttachmentUploadStalled,u.InvalidAttachmentTarget]),Lt=(t,e)=>{if(t instanceof I)return t;let n=wt(t),r=Ht(t);return String(n)===String(10004)?new I(u.AttachmentUnavailable,r):typeof n=="string"&&Nt.has(n)?new I(n,r):new I(e,r)},B=(t,e,n)=>p(void 0,null,function*(){if(!Ue(e))throw new I(u.InvalidFunctionName,"Function name \u5FC5\u987B\u4F7F\u7528 function \u5F00\u5934\u7684\u70B9\u53F7\u8DEF\u5F84");return t.invokeApi(g.FunctionInvoke,{functionName:e,params:n})}),q=class{constructor(e){this.channel=e;this.uploadAttachment=r=>p(this,null,function*(){var i=r,{onProgress:e}=i,n=Te(i,["onProgress"]);if(!Be(n==null?void 0:n.baseToken)||!Be(n==null?void 0:n.tableId)||!Mt(n==null?void 0:n.file))throw new I(u.InvalidAttachmentTarget,"\u9644\u4EF6\u4E0A\u4F20\u76EE\u6807\u5FC5\u987B\u5305\u542B baseToken\u3001tableId\uFF0C\u4E14 file \u4E3A File");let o=Pt(),s,d=()=>{},c=()=>{this.channel.invokeApi(g.AttachmentUploadCancel,{uploadId:o}).catch(()=>{})},m=new Promise((h,_)=>{let H=()=>{clearTimeout(s),s=setTimeout(()=>{c(),_(new I(u.AttachmentUploadStalled,`\u9644\u4EF6\u4E0A\u4F20\u5DF2\u505C\u6EDE\u8D85\u8FC7 ${qe/1e3}s`))},qe)};d=this.channel.subscribeEvent(y.AttachmentUploadProgress,T=>{(T==null?void 0:T.uploadId)===o&&(H(),Promise.resolve(e==null?void 0:e(T)).catch(()=>{console.error("[base-site-channel][runtime] Attachment progress callback failed")}))})});try{return yield Promise.race([this.channel.invokeApi(g.AttachmentUpload,f(a({},n),{uploadId:o}),{timeoutMs:Ft}),m])}catch(h){throw Lt(h,u.AttachmentUploadFailed)}finally{clearTimeout(s),d()}});this.invokeHttp=e=>De(this.channel,e);this.invokeApi=(e,n)=>B(this.channel,e,n);this.getRuntimeContext=()=>this.channel.invokeApi(g.RuntimeContext,void 0);this.getCurrentUser=()=>B(this.channel,D.GetCurrentUser,void 0);this.logout=()=>B(this.channel,D.Logout,void 0);this.requestEdit=()=>B(this.channel,D.RequestEdit,void 0);this.ready=()=>this.channel.emitEvent(y.LifecycleReady,{protocolVersion:Oe});this.reportLoadFailed=e=>this.channel.emitEvent(y.LifecycleLoadFailed,{code:e});this.subscribeModeChanged=e=>this.channel.subscribeEvent(y.ModeChanged,({mode:n})=>e(n))}},j=(t=k)=>new q(t),v=j(),Ot=v.invokeHttp,Ut=v.invokeApi,Dt=v.getCurrentUser,Bt=v.logout,qt=v.requestEdit,jt=v.uploadAttachment;var Kt=new Set(["open.feishu.cn","open.feishu-pre.cn","open.feishu-boe.cn"]),Ke="/open-apis",Vt="/base-site/api/openapi",zt=new Set(["DELETE","GET","PATCH","POST","PUT"]),Wt=()=>(typeof globalThis.location=="undefined"?"":globalThis.location.pathname).replace(/^\/+/,"").startsWith("preview")?[["x-project-env","preview"]]:[],$t=t=>{if(typeof Request!="undefined"&&t instanceof Request)throw new TypeError("Site Runtime fetch \u6682\u4E0D\u652F\u6301 Request \u5165\u53C2");let e=String(t);if(e.startsWith("//"))throw new TypeError("Site Runtime fetch \u4E0D\u652F\u6301 scheme-relative URL");if(e.startsWith("/"))return e;let n=new URL(e);if(Kt.has(n.hostname)&&n.pathname.startsWith(Ke))return`${Vt}${n.pathname.slice(Ke.length)}${n.search}`;throw new TypeError("Site Runtime fetch \u4EC5\u652F\u6301\u76F8\u5BF9\u4E1A\u52A1\u8DEF\u5F84")},Yt=t=>{let e=new Headers(t);Wt().forEach(([r,i])=>e.set(r,i));let n={};return e.forEach((r,i)=>{n[i]=r}),n},Gt=(t,e)=>{var r,i,o;let n=(i=(r=t==null?void 0:t.method)==null?void 0:r.toUpperCase())!=null?i:"GET";if(!zt.has(n))throw new TypeError(`Site Runtime fetch \u4E0D\u652F\u6301 ${n} \u65B9\u6CD5`);if((t==null?void 0:t.body)!==void 0&&t.body!==null&&typeof t.body!="string")throw new TypeError("Site Runtime fetch body \u4EC5\u652F\u6301\u5B57\u7B26\u4E32");if((o=t==null?void 0:t.signal)!=null&&o.aborted)throw new DOMException("The operation was aborted","AbortError");return{body:typeof(t==null?void 0:t.body)=="string"?t.body:void 0,headers:Yt(t==null?void 0:t.headers),method:n,timeoutMs:e}},K=(t=v,e)=>(n,r)=>t.invokeHttp(f(a({init:Gt(r,e)},r!=null&&r.signal?{signal:r.signal}:{}),{url:$t(n)})),Jt=K();var Ve=0,Xt=()=>typeof crypto!="undefined"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():(Ve+=1,`site-chatbot-${Ve}`),V=(t,e)=>{try{t==null||t(e)}catch(n){console.error("[base-site-channel][runtime] Chatbot callback failed")}},F=class extends Error{constructor(n,r){super(`Chatbot stream error: ${n}`);this.code=n;this.retryable=r;this.name="SiteChatbotStreamError"}},ne=class{constructor(e){this.options=e;this.init=e=>{this.destroy();let n=Xt(),r={lastSeq:0,subscriptionId:n,unsubscribeError:()=>{},unsubscribeMessage:()=>{}};r.unsubscribeMessage=this.channel.subscribeEvent(y.StreamMessage,i=>{i.subscriptionId!==n||i.seq<=r.lastSeq||(i.seq>r.lastSeq+1&&V(this.onErrorCallback,new F(u.StreamSeqGap,!0)),r.lastSeq=i.seq,V(this.onMessageCallback,i.data))}),r.unsubscribeError=this.channel.subscribeEvent(y.StreamError,i=>{i.subscriptionId===n&&V(this.onErrorCallback,new F(i.code,i.retryable))}),this.current=r,this.channel.invokeApi(g.StreamOpen,{chatbotId:this.options.chatbotId,subscriptionId:n,threadId:e}).catch(()=>{var i;((i=this.current)==null?void 0:i.subscriptionId)===n&&V(this.onErrorCallback,new F(u.StreamOpenFailed,!0))})};this.onMessage=e=>{this.onMessageCallback=e};this.onError=e=>{this.onErrorCallback=e};this.destroy=()=>{let e=this.current;e&&(e.unsubscribeMessage(),e.unsubscribeError(),this.current=void 0,this.channel.invokeApi(g.StreamClose,{subscriptionId:e.subscriptionId}).catch(()=>console.error("[base-site-channel][runtime] Chatbot stream close failed")))};var n;this.channel=(n=e.channel)!=null?n:k}};var ie="prod",ze=0,Ye=()=>typeof crypto!="undefined"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():(ze+=1,`site-ai-fn-${ze}`),E=(t,e)=>{try{t==null||t(e)}catch(n){console.error("[base-site-channel][runtime] AI function callback failed")}},l=(t,e)=>{let n=new Error(e||`AI function error: ${t}`);return n.name="SiteAIFunctionError",n.code=t,n},Ge=()=>l(u.InvalidHttpUrl,"siteToken is required to invoke site AI function"),oe=()=>typeof window!="undefined"&&window.parent!==window,se=t=>{if(typeof queueMicrotask=="function"){queueMicrotask(t);return}Promise.resolve().then(t)},ae=t=>{let e={data:[],event:"message"};for(let n of t.split(/\r?\n/))n.startsWith("event:")?e.event=n.slice(6).trim():n.startsWith("data:")&&e.data.push(n.slice(5).trimStart());return e},re=(t,e)=>{for(let n of e){let r=t[n];if(typeof r=="string")return r}},Je=t=>{let e=[t];if(t&&typeof t=="object"){let n=t;e.push(n.response,n.data)}for(let n of e){if(!n||typeof n!="object")continue;let r=re(n,["request_id","requestId","RequestID","id"]);if(r)return r}},Xe=t=>{if(!t||typeof t!="object")return{};let e=t;return{content:re(e,["content","text","answer"]),reasoningContent:re(e,["reasoning_content","reasoningContent","reasoning"])}},Qt=t=>{if(!t||typeof t!="object")return{};let e=t.choices;if(!Array.isArray(e))return{};for(let n of e){let r=n.delta,{content:i,reasoningContent:o}=Xe(r);if(i!==void 0||o!==void 0)return{content:i,reasoningContent:o}}return{}},Qe=t=>{var n;let e=[t];if(t&&typeof t=="object"){let r=t;e.push(r.response,r.data)}for(let r of e){let i=Qt(r);if(i.content!==void 0||i.reasoningContent!==void 0)return i;let o=Xe(r&&typeof r=="object"&&(n=r.delta)!=null?n:r);if(o.content!==void 0||o.reasoningContent!==void 0)return o}return{}},z=t=>{try{let e=JSON.parse(t),n=Qe(e),r=Je(e);return f(a(a(a({},n.content!==void 0?{content:n.content}:{}),n.reasoningContent!==void 0?{reasoningContent:n.reasoningContent}:{}),r?{requestId:r}:{}),{raw:e})}catch(e){return{content:t,raw:t}}},Ze=t=>{if(typeof t=="string")return z(t);let e=Qe(t),n=Je(t),r=t&&typeof t=="object"&&"raw"in t?t.raw:t;return f(a(a(a({},e.content!==void 0?{content:e.content}:{}),e.reasoningContent!==void 0?{reasoningContent:e.reasoningContent}:{}),n?{requestId:n}:{}),{raw:r})},Zt=t=>{var e,n;try{let r=JSON.parse(t),i=(e=r.Code)!=null?e:r.code,o=(n=r.Message)!=null?n:r.message,s=typeof i=="string"||typeof i=="number"?String(i):"STREAM_FAILED";return l(s||"STREAM_FAILED",typeof o=="string"&&o?o:t)}catch(r){return l("STREAM_FAILED",t)}},ce=()=>({text:""}),en=t=>/(^|\n)(data|event|id|retry):/.test(t),We=t=>{if(!t||t==="[DONE]")return!!t;try{return JSON.parse(t),!0}catch(e){return!1}},tn=t=>{if(t){if(en(t)){let n=ae(t).data.join(`
1
+ var ct=Object.defineProperty,dt=Object.defineProperties;var ut=Object.getOwnPropertyDescriptors;var N=Object.getOwnPropertySymbols;var ve=Object.prototype.hasOwnProperty,be=Object.prototype.propertyIsEnumerable;var Ae=(t,e,n)=>e in t?ct(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n,a=(t,e)=>{for(var n in e||(e={}))ve.call(e,n)&&Ae(t,n,e[n]);if(N)for(var n of N(e))be.call(e,n)&&Ae(t,n,e[n]);return t},f=(t,e)=>dt(t,ut(e));var Te=(t,e)=>{var n={};for(var r in t)ve.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&N)for(var r of N(t))e.indexOf(r)<0&&be.call(t,r)&&(n[r]=t[r]);return n};var p=(t,e,n)=>new Promise((r,i)=>{var o=c=>{try{d(n.next(c))}catch(m){i(m)}},s=c=>{try{d(n.throw(c))}catch(m){i(m)}},d=c=>c.done?r(c.value):Promise.resolve(c.value).then(o,s);d((n=n.apply(t,e)).next())});import{uniqueId as ee}from"lodash-es";var W="same-origin",Ce="__internal_fetchBinaryList__",Re="__internal_cancelBinaryFetch__",ke="__internal_binaryFetchProgress__";function $(t){return Number.isFinite(t)?Math.max(1,Math.floor(t)):4}function Y(t){return t==="omit"||t==="include"?t:W}var L=(i=>(i.IFRAME_LOAD_ERROR="iframeLoadError",i.NOT_ALLOWED_URL="notAllowedUrl",i.HANDSHAKE_TIME_OUT="handshakeTimeout",i.CHANNEL_UNAVAILABLE="channelUnavailable",i))(L||{});var b=class extends Error{constructor(n,r){super(r);this.code=n,this.name="ChannelCallbackError"}};function Me(t){return new b(10004,`api "${t}" is not registered`)}function Pe(t){return new b(10005,`api "${t}" timed out`)}function G(){return new b(10006,"channel has been destroyed")}function Fe(t){return new b(10008,`request "${t}" was superseded by a new one`)}var lt="unknown error";function we(t){return typeof t=="object"&&t!==null}function pt(t){if(typeof t=="string"&&t)return t;if(t instanceof b&&t.message||t instanceof Error&&t.message)return t.message;if(we(t)){let{msg:e,message:n}=t;if(typeof e=="string"&&e)return e;if(typeof n=="string"&&n)return n}return lt}function ht(t){if(t instanceof b)return t.code;if(!we(t))return-1;let{code:e}=t;return typeof e=="string"&&e||typeof e=="number"&&Number.isFinite(e)?e:-1}function A(t){return{code:ht(t),msg:pt(t)}}function xe(t){return t instanceof ArrayBuffer||ArrayBuffer.isView(t)||typeof Blob!="undefined"&&t instanceof Blob}function mt(t){return xe(t)||Object.values(t).some(e=>xe(e))}function He(t){return t&&typeof t=="object"?mt(t)?t:JSON.parse(JSON.stringify(t)):t}var ft={["iframeLoadError"]:10001,["notAllowedUrl"]:10002,["handshakeTimeout"]:10003,["channelUnavailable"]:10009};function gt(t){return typeof t=="object"&&t!==null}function It(t){if(!gt(t))return!1;let{type:e}=t;return typeof e=="string"&&Object.values(L).includes(e)}function J(t){return It(t)?{code:ft[t.type],msg:t.message||t.type}:A(t)}function X(t){let e=Promise.reject(t);return e.catch(()=>{}),e}var F=class{constructor(e,n){this._target=e,this._options=n}sendMsg(e,n){if(!this._target)throw new Error("target window is not found");this._target.postMessage(e,this._options.targetOrigin,n!=null?n:[])}listenMsg(e){this._eventHandler=n=>{n.source===this._options.sourceWindow&&this._options.allowedOrigins.includes(n.origin)&&e(n)},typeof window!="undefined"&&window.addEventListener("message",this._eventHandler)}destroy(){typeof window!="undefined"&&this._eventHandler&&window.removeEventListener("message",this._eventHandler),this._eventHandler=void 0}};var _=class{constructor(e,n,r){e==="host"?this.channelManager=new F(n,r):e==="client"&&(this.channelManager=new F(window.parent,r))}static createInstance(e,n,r){return new _(e,n,r)}sendMsg(e,n){var r;(r=this.channelManager)==null||r.sendMsg(e,n)}listenMsg(e){var n;(n=this.channelManager)==null||n.listenMsg(e)}destroy(){var e;(e=this.channelManager)==null||e.destroy()}};var O=class{constructor(){this.requests=new Map}create(e,n,r=3e4){return this.reject(e,A(Fe(e))),new Promise((i,o)=>{let s=setTimeout(()=>{var d;((d=this.requests.get(e))==null?void 0:d.timeout)===s&&(this.requests.delete(e),o(A(Pe(n))))},r);this.requests.set(e,{reject:o,resolve:i,timeout:s})})}resolve(e,n){let r=this.take(e);return r?(r.resolve(n),!0):!1}reject(e,n){let r=this.take(e);return r?(r.reject(n),!0):!1}rejectAll(e){for(let n of this.requests.keys())this.reject(n,e)}take(e){let n=this.requests.get(e);if(n)return this.requests.delete(e),clearTimeout(n.timeout),n}};var Q=t=>typeof t=="object"&&t!==null,Et=new Set(["blockId","expectedPrefixId","id","jobId","prefixId","url"]),C=t=>{let e={};for(let[n,r]of Object.entries(t))if(!(n==="inputParams"||n==="outputParams")){if(Et.has(n)){e[`${n}Present`]=!!r;continue}if(n==="error"){Object.assign(e,R(r));continue}if(n==="errorInfo"&&Q(r)){e.errorType=typeof r.type=="string"?r.type:"object";continue}(typeof r=="string"||typeof r=="number"||typeof r=="boolean")&&(e[n]=r)}return e},M=t=>{let e={idPresent:!!t.id,type:t.type},n=Q(t.payload)?t.payload:{};return typeof n.key=="string"&&(e.key=n.key),t.type==="callback"&&typeof n.code=="number"&&(e.callbackCode=n.code),t.type==="handshake"&&typeof n.proactive=="boolean"&&(e.proactive=n.proactive),e},Z=t=>t.type!=="invoke"&&t.type!=="callback",R=t=>{if(!Q(t))return{errorType:typeof t};let e={errorType:t instanceof Error?t.name:"object"};return(typeof t.code=="number"||typeof t.code=="string")&&(e.errorCode=t.code),e};var At=()=>{let t=Reflect.get(globalThis,"BearWebSlardarWeb");return typeof t=="function"?t:void 0},vt=t=>{let e={};for(let[n,r]of Object.entries(C(t)))typeof r=="string"||typeof r=="number"?e[n]=r:typeof r=="boolean"&&(e[n]=String(r));return e},Ne=(t,e,n,r)=>{console[e](`[base-site-channel][${t}]`,n,r)},U=(t,e,n,r={})=>{let i=C(r),o=At();if(!o){Ne(t,e,n,i);return}try{o("sendLog",{content:`[base-site-channel][${t}] ${n}`,extra:a({event_name:"Runtime_SiteChannel_Message",bizType:"Runtime",subType:"SiteChannel",action:"Message",channel_side:t,channel_message:n},vt(i)),level:e})}catch(s){Ne(t,e,n,f(a({},i),{slardarFallback:!0,slardarErrorType:s instanceof Error?s.name:typeof s}))}};var Ct=()=>{var n;if(typeof window=="undefined")return null;let e=((n=window.location.ancestorOrigins)==null?void 0:n[0])||document.referrer;if(!e)return null;try{return new URL(e).origin}catch(r){return null}},Rt=t=>{try{return new URL(t).origin}catch(e){return null}},te=class{constructor(e={}){this.pendingRequests=new O;this.eventMap=new Map;this.eventHandlerMap=new Map;this._msgChannel=null;this._invokeId="";this._handshakePromise=X({type:"channelUnavailable",message:"channel handshake is not initialized"});this._handshakeResolve=null;this._handshakeReject=null;this._handshakeRetryTimes=0;this._handshakeStatus=0;this._handshakeTimeout=null;this._prefixId="";this._destroyed=!1;let n=e.hostOrigin?Rt(e.hostOrigin):null;if(this.hostOrigin=n!=null?n:Ct(),e.hostOrigin&&!n&&this.logWarn("invalid hostOrigin, fallback to parent origin"),typeof window=="undefined"||window.parent===window){this.failHandshake("invalid window context",{hasWindow:typeof window!="undefined",isTopWindow:typeof window!="undefined"?window.parent===window:!0});return}if(!this.hostOrigin){this.failHandshake("host origin unavailable");return}this._msgChannel=_.createInstance("client",window.parent,{allowedOrigins:[this.hostOrigin],sourceWindow:window.parent,targetOrigin:this.hostOrigin}),this.listeningHostMsg(),this.startHandshake()}logInfo(e,n={}){U("client","info",e,a({hasPrefixId:!!this._prefixId,handshakeStatus:this._handshakeStatus},C(n)))}logWarn(e,n={}){U("client","warn",e,a({hasPrefixId:!!this._prefixId,handshakeStatus:this._handshakeStatus},C(n)))}logError(e,n={}){U("client","error",e,a({hasPrefixId:!!this._prefixId,handshakeStatus:this._handshakeStatus},C(n)))}failHandshake(e,n={}){this._handshakeStatus=2,this._handshakePromise=X({type:"channelUnavailable",message:e}),this.logError(`init failed: ${e}`,n)}sendProactiveHandshakeMsg(){var n;let e={id:ee("handshake-"),type:"handshake",payload:{proactive:!0}};this.logInfo("send proactive handshake",M(e)),(n=this._msgChannel)==null||n.sendMsg(e)}_initHandshake(){this._handshakeRetryTimes=0,clearTimeout(this._handshakeTimeout),this._handshakeStatus=0,this.logInfo("init handshake"),this._handshakePromise=new Promise((e,n)=>{this._handshakeResolve=e,this._handshakeReject=n,this._handshakeTimeout=setTimeout(()=>this.retryHandshake(n),2e3)})}startHandshake(){this._initHandshake(),this._handshakePromise.then(()=>{this._handshakeStatus=1,this.logInfo("handshake success")}).catch(e=>{this._handshakeStatus=2,this.logError("handshake failed",{error:e})}),this.sendProactiveHandshakeMsg()}retryHandshake(e){this._handshakeStatus===0&&(this._handshakeRetryTimes<5?(this.logWarn("retry handshake",{retryTimes:this._handshakeRetryTimes+1}),this.sendProactiveHandshakeMsg(),this._handshakeRetryTimes++,this._handshakeTimeout=setTimeout(()=>this.retryHandshake(e),2e3+2**this._handshakeRetryTimes)):(this.logError("handshake retry timeout",{retryTimes:this._handshakeRetryTimes}),e({type:"handshakeTimeout",message:"iframe handshake time out"})))}updateInvokeId(){this._invokeId=ee(`${this._prefixId}-invoke-`)}handleChannelMessage(e){let{data:n}=e;Z(n)&&this.logInfo("receive host message",M(n));let{type:r}=n;r==="callback"?this.handleHostCallback(n):r==="handshake"?this.handleHandshakeCallback(n):r==="invoke"?this.handleHostInvoke(n).catch(i=>{this.logError("handle host invoke error",a(a({},M(n)),R(i)))}):r==="event"&&this.handleHostEvent(n).catch(i=>{this.logError("handle host event error",a(a({},M(n)),R(i)))})}handleHostCallback(e){let{id:n,payload:r}=e,i={logId:n,key:r.key,callbackCode:r.code};if(r.code===1){if(this.pendingRequests.reject(n,r.res)){this.logWarn("api response received",i);return}}else if(this.pendingRequests.resolve(n,r.res)){this.logInfo("api response received",i);return}this.logWarn("host callback request not found",{id:n,key:r.key})}handleHostInvoke(e){return p(this,null,function*(){yield this._handshakePromise;let{id:n,payload:r}=e,{key:i,params:o,prefixId:s}=r;if(s!==this._prefixId){this.logWarn("ignore host invoke because prefixId mismatch",{id:n,key:i,prefixId:s,expectedPrefixId:this._prefixId});return}let d=this.eventMap.get(i);if(typeof d!="function"){this.logWarn("host invoke handler not found",{id:n,key:i}),this.sendMsg2Host({id:n,type:"callback",payload:{key:i,res:A(Me(i)),code:1}});return}this.logInfo("handle host invoke",{id:n,key:i});try{let c=He(yield d(o));this.sendMsg2Host({id:n,type:"callback",payload:{key:i,res:c,code:0}}),this.logInfo("host invoke success",{id:n,key:i})}catch(c){this.logError("host invoke failed",a({id:n,key:i},R(c))),this.sendMsg2Host({id:n,type:"callback",payload:{key:i,res:A(c),code:1}})}})}handleHostEvent(e){return p(this,null,function*(){yield this._handshakePromise;let{payload:n}=e,{key:r,params:i,prefixId:o}=n;if(o!==this._prefixId){this.logWarn("ignore host event because prefixId mismatch",{key:r,prefixId:o,expectedPrefixId:this._prefixId});return}let s=this.eventHandlerMap.get(r);if(!(s!=null&&s.size)){this.logWarn("host event handler not found",{key:r});return}this.logInfo("handle host event",{key:r,handlerCount:s.size}),yield Promise.allSettled(Array.from(s,d=>d(i)))})}handleHandshakeCallback(e){var o,s;let{id:n,payload:r}=e;this._prefixId=(o=r==null?void 0:r.prefixId)!=null?o:"",this.logInfo("receive handshake callback",{id:n,prefixId:this._prefixId}),(s=this._handshakeResolve)==null||s.call(this);let i={id:n,type:"handshake",payload:{proactive:!1,info:{isHandshakeSuccess:!0}}};this.sendMsg2Host(i)}listeningHostMsg(){var e;this.logInfo("start listening host messages"),(e=this._msgChannel)==null||e.listenMsg(this.handleChannelMessage.bind(this))}sendMsg2Host(e,n){var r;Z(e)&&this.logInfo("send message to host",M(e)),(r=this._msgChannel)==null||r.sendMsg(e,n)}invokeApi(e,n,r){return p(this,null,function*(){if(this._destroyed)return Promise.reject(A(G()));try{yield this._handshakePromise}catch(s){return this.logError("invoke api blocked by handshake error",a({key:e},R(s))),Promise.reject(J(s))}this._invokeId||this.updateInvokeId();let i=this._invokeId,o=this.pendingRequests.create(i,e,r==null?void 0:r.timeoutMs);return this.logInfo("api request sent",{key:e,logId:i}),this.sendMsg2Host({type:"invoke",id:i,payload:{key:e,params:n,prefixId:this._prefixId}}),this.updateInvokeId(),o})}registerApi(e,n){if(this.eventMap.has(e)){this.logWarn("register api ignored because key already exists",{key:e});return}this.eventMap.set(e,n),this.logInfo("register api",{key:e})}emitEvent(e,n){return p(this,null,function*(){try{yield this._handshakePromise}catch(r){return this.logError("emit event blocked by handshake error",a({key:e},R(r))),Promise.reject(J(r))}this.logInfo("emit event",{key:e}),this.sendMsg2Host({type:"event",id:ee(`${this._prefixId}-event-`),payload:{key:e,params:n,prefixId:this._prefixId}})})}fetchBinaryList(e){return p(this,null,function*(){var n;return this.logInfo("invoke built-in binary fetch",{status:"start",itemCount:e.items.length,concurrency:$(e.concurrency),credentials:Y(e.credentials)}),this.invokeApi(Ce,{items:e.items,concurrency:$(e.concurrency),credentials:Y((n=e.credentials)!=null?n:W)})})}subscribeBinaryFetchProgress(e){return this.subscribeEvent(ke,e)}cancelBinaryFetch(e){return p(this,null,function*(){this.logInfo("invoke built-in binary fetch cancel",{jobId:e,status:"cancel-requested"}),yield this.invokeApi(Re,{jobId:e})})}destroy(){var n,r;if(this._destroyed)return;this._destroyed=!0,this.logInfo("destroy client"),(n=this._msgChannel)==null||n.destroy(),clearTimeout(this._handshakeTimeout);let e=A(G());(r=this._handshakeReject)==null||r.call(this,{type:"handshakeTimeout",message:e.msg}),this.pendingRequests.rejectAll(e),this.eventMap.clear(),this.eventHandlerMap.clear()}subscribeEvent(e,n){var i;let r=(i=this.eventHandlerMap.get(e))!=null?i:new Set;return r.add(n),this.eventHandlerMap.set(e,r),this.logInfo("subscribe event",{key:e,handlerCount:r.size}),()=>this.unsubscribeEvent(e,n)}unsubscribeEvent(e,n){let r=this.eventHandlerMap.get(e);if(!r){this.logWarn("unsubscribe event ignored because key is not subscribed",{key:e});return}if(!n){this.eventHandlerMap.delete(e),this.logInfo("unsubscribe all event handlers",{key:e,handlerCount:0});return}r.delete(n),r.size===0&&this.eventHandlerMap.delete(e),this.logInfo("unsubscribe event",{key:e,handlerCount:r.size})}},kt=t=>new te(t),k=kt();var Oe="site.v1",g={AIFunctionStreamClose:"site.v1.ai.function.stream.close",AIFunctionStreamOpen:"site.v1.ai.function.stream.open",AttachmentUpload:"site.v1.attachment.upload",AttachmentUploadCancel:"site.v1.attachment.upload.cancel",FunctionInvoke:"site.v1.function.invoke",HttpRequest:"site.v1.http.request",HttpRequestCancel:"site.v1.http.request.cancel",RuntimeContext:"site.v1.runtime.context",StreamClose:"site.v1.chatbot.stream.close",StreamOpen:"site.v1.chatbot.stream.open"},y={AIFunctionStreamDone:"site.v1.ai.function.stream.done",AIFunctionStreamError:"site.v1.ai.function.stream.error",AIFunctionStreamMessage:"site.v1.ai.function.stream.message",AttachmentUploadProgress:"site.v1.attachment.upload.progress",LifecycleLoadFailed:"site.v1.lifecycle.load-failed",LifecycleReady:"site.v1.lifecycle.ready",ModeChanged:"site.v1.runtime.mode-changed",StreamError:"site.v1.chatbot.stream.error",StreamMessage:"site.v1.chatbot.stream.message"},D={GetCurrentUser:"function.runtime.getCurrentUser",Logout:"function.runtime.logout",RequestEdit:"function.runtime.requestEdit"},u={AttachmentUnavailable:"ATTACHMENT_UNAVAILABLE",AttachmentUploadCanceled:"ATTACHMENT_UPLOAD_CANCELED",AttachmentUploadFailed:"ATTACHMENT_UPLOAD_FAILED",AttachmentUploadStalled:"ATTACHMENT_UPLOAD_STALLED",ChannelDestroyed:"CHANNEL_DESTROYED",FunctionNotAllowed:"FUNCTION_NOT_ALLOWED",FunctionRequestFailed:"FUNCTION_REQUEST_FAILED",InvalidAIFunctionTask:"INVALID_AI_FUNCTION_TASK",HttpRequestFailed:"HTTP_REQUEST_FAILED",HttpResponseTypeUnsupported:"HTTP_RESPONSE_TYPE_UNSUPPORTED",HttpRequestCanceled:"HTTP_REQUEST_CANCELED",InvalidAttachmentTarget:"INVALID_ATTACHMENT_TARGET",InvalidFunctionName:"INVALID_FUNCTION_NAME",InvalidHttpHeader:"INVALID_HTTP_HEADER",InvalidHttpUrl:"INVALID_HTTP_URL",LogoutFailed:"LOGOUT_FAILED",ProtocolMismatch:"PROTOCOL_MISMATCH",RequestTimeout:"REQUEST_TIMEOUT",StreamDisconnected:"STREAM_DISCONNECTED",StreamHealthTimeout:"STREAM_HEALTH_TIMEOUT",StreamInterrupted:"STREAM_INTERRUPTED",StreamOpenFailed:"STREAM_OPEN_FAILED",StreamSeqGap:"STREAM_SEQ_GAP",StreamUnavailable:"STREAM_UNAVAILABLE",UnsupportedHttpBody:"UNSUPPORTED_HTTP_BODY",UserInfoUnavailable:"USER_INFO_UNAVAILABLE"},xr=t=>{var e,n;return{answer:(e=t.content)!=null?e:"",reasoning:(n=t.reasoningContent)!=null?n:""}},xt=/^function(?:\.[A-Za-z_][A-Za-z0-9_]*)+$/,Ue=t=>xt.test(t);var _t=0,De=(i,o)=>p(void 0,[i,o],function*(t,{init:e,url:n,signal:r}){if((e==null?void 0:e.responseType)!==void 0&&!["text","arrayBuffer"].includes(e.responseType))throw new S(u.HttpResponseTypeUnsupported,"Unsupported HTTP response type; use text or arrayBuffer");let s=()=>new DOMException("The operation was aborted","AbortError");if(r!=null&&r.aborted)throw s();let d=typeof crypto!="undefined"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():`http-${Date.now()}-${++_t}`,c=()=>{},m=new Promise((h,x)=>{c=()=>{x(s()),t.invokeApi(g.HttpRequestCancel,{requestId:d}).catch(()=>{})}});r==null||r.addEventListener("abort",c,{once:!0});try{let h=yield Promise.race([t.invokeApi(g.HttpRequest,{requestId:d,url:n,init:e},{timeoutMs:(e==null?void 0:e.timeoutMs)===void 0?void 0:Math.min(e.timeoutMs,6e4)+1e3}),m]);if((e==null?void 0:e.responseType)==="arrayBuffer"&&(h.bodyType!=="arrayBuffer"||!(h.body instanceof ArrayBuffer)))throw new S(u.HttpResponseTypeUnsupported,"The current host does not support binary HTTP responses; upgrade the host");return new Response([204,205,304].includes(h.status)?null:h.body,{headers:h.headers,status:h.status,statusText:h.statusText})}finally{r==null||r.removeEventListener("abort",c)}});var S=class extends Error{constructor(n,r){super(r);this.code=n;this.name="SiteRuntimeInvocationError"}},Be=t=>typeof t=="string"&&t.trim().length>0,Mt=t=>typeof File!="undefined"&&t instanceof File,qe=12e4,Pt=2*60*60*1e3,je=0,Ft=()=>typeof crypto!="undefined"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():(je+=1,`site-upload-${je}`),wt=t=>typeof t=="object"&&t!==null&&"code"in t?t.code:void 0,Ht=t=>{if(t instanceof Error&&t.message)return t.message;if(typeof t=="object"&&t!==null){if("message"in t&&typeof t.message=="string")return t.message;if("msg"in t&&typeof t.msg=="string")return t.msg}return String(t)},Nt=new Set([u.AttachmentUnavailable,u.AttachmentUploadCanceled,u.AttachmentUploadFailed,u.AttachmentUploadStalled,u.InvalidAttachmentTarget]),Lt=(t,e)=>{if(t instanceof S)return t;let n=wt(t),r=Ht(t);return String(n)===String(10004)?new S(u.AttachmentUnavailable,r):typeof n=="string"&&Nt.has(n)?new S(n,r):new S(e,r)},B=(t,e,n)=>p(void 0,null,function*(){if(!Ue(e))throw new S(u.InvalidFunctionName,"Function name must be a dot-separated path beginning with function (for example, function.orders.list)");return t.invokeApi(g.FunctionInvoke,{functionName:e,params:n})}),q=class{constructor(e){this.channel=e;this.uploadAttachment=r=>p(this,null,function*(){var i=r,{onProgress:e}=i,n=Te(i,["onProgress"]);if(!Be(n==null?void 0:n.baseToken)||!Be(n==null?void 0:n.tableId)||!Mt(n==null?void 0:n.file))throw new S(u.InvalidAttachmentTarget,"Attachment upload requires nonempty baseToken and tableId values and a File");let o=Ft(),s,d=()=>{},c=()=>{this.channel.invokeApi(g.AttachmentUploadCancel,{uploadId:o}).catch(()=>{})},m=new Promise((h,x)=>{let H=()=>{clearTimeout(s),s=setTimeout(()=>{c(),x(new S(u.AttachmentUploadStalled,`Attachment upload made no progress for more than ${qe/1e3} seconds`))},qe)};d=this.channel.subscribeEvent(y.AttachmentUploadProgress,T=>{(T==null?void 0:T.uploadId)===o&&(H(),Promise.resolve(e==null?void 0:e(T)).catch(()=>{console.error("[base-site-channel][runtime] Attachment progress callback failed")}))})});try{return yield Promise.race([this.channel.invokeApi(g.AttachmentUpload,f(a({},n),{uploadId:o}),{timeoutMs:Pt}),m])}catch(h){throw Lt(h,u.AttachmentUploadFailed)}finally{clearTimeout(s),d()}});this.invokeHttp=e=>De(this.channel,e);this.invokeApi=(e,n)=>B(this.channel,e,n);this.getRuntimeContext=()=>this.channel.invokeApi(g.RuntimeContext,void 0);this.getCurrentUser=()=>B(this.channel,D.GetCurrentUser,void 0);this.logout=()=>B(this.channel,D.Logout,void 0);this.requestEdit=()=>B(this.channel,D.RequestEdit,void 0);this.ready=()=>this.channel.emitEvent(y.LifecycleReady,{protocolVersion:Oe});this.reportLoadFailed=e=>this.channel.emitEvent(y.LifecycleLoadFailed,{code:e});this.subscribeModeChanged=e=>this.channel.subscribeEvent(y.ModeChanged,({mode:n})=>e(n))}},j=(t=k)=>new q(t),v=j(),Ot=v.invokeHttp,Ut=v.invokeApi,Dt=v.getCurrentUser,Bt=v.logout,qt=v.requestEdit,jt=v.uploadAttachment;var Kt=new Set(["open.feishu.cn","open.feishu-pre.cn","open.feishu-boe.cn"]),Ke="/open-apis",Vt="/base-site/api/openapi",zt=new Set(["DELETE","GET","PATCH","POST","PUT"]),Wt=()=>(typeof globalThis.location=="undefined"?"":globalThis.location.pathname).replace(/^\/+/,"").startsWith("preview")?[["x-project-env","preview"]]:[],$t=t=>{if(typeof Request!="undefined"&&t instanceof Request)throw new TypeError("Site Runtime fetch does not accept a Request object; pass a URL instead");let e=String(t);if(e.startsWith("//"))throw new TypeError("Site Runtime fetch does not accept a scheme-relative URL");if(e.startsWith("/"))return e;let n=new URL(e);if(Kt.has(n.hostname)&&n.pathname.startsWith(Ke))return`${Vt}${n.pathname.slice(Ke.length)}${n.search}`;throw new TypeError("Site Runtime fetch accepts only relative business paths or supported Feishu OpenAPI URLs")},Yt=t=>{let e=new Headers(t);Wt().forEach(([r,i])=>e.set(r,i));let n={};return e.forEach((r,i)=>{n[i]=r}),n},Gt=(t,e)=>{var r,i,o;let n=(i=(r=t==null?void 0:t.method)==null?void 0:r.toUpperCase())!=null?i:"GET";if(!zt.has(n))throw new TypeError(`Site Runtime fetch does not support the ${n} method`);if((t==null?void 0:t.body)!==void 0&&t.body!==null&&typeof t.body!="string")throw new TypeError("Site Runtime fetch requires a string request body");if((o=t==null?void 0:t.signal)!=null&&o.aborted)throw new DOMException("The operation was aborted","AbortError");return{body:typeof(t==null?void 0:t.body)=="string"?t.body:void 0,headers:Yt(t==null?void 0:t.headers),method:n,timeoutMs:e}},K=(t=v,e)=>(n,r)=>t.invokeHttp(f(a({init:Gt(r,e)},r!=null&&r.signal?{signal:r.signal}:{}),{url:$t(n)})),Jt=K();var Ve=0,Xt=()=>typeof crypto!="undefined"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():(Ve+=1,`site-chatbot-${Ve}`),V=(t,e)=>{try{t==null||t(e)}catch(n){console.error("[base-site-channel][runtime] Chatbot callback failed")}},P=class extends Error{constructor(n,r){super(`Chatbot stream error: ${n}`);this.code=n;this.retryable=r;this.name="SiteChatbotStreamError"}},ne=class{constructor(e){this.options=e;this.init=e=>{this.destroy();let n=Xt(),r={lastSeq:0,subscriptionId:n,unsubscribeError:()=>{},unsubscribeMessage:()=>{}};r.unsubscribeMessage=this.channel.subscribeEvent(y.StreamMessage,i=>{i.subscriptionId!==n||i.seq<=r.lastSeq||(i.seq>r.lastSeq+1&&V(this.onErrorCallback,new P(u.StreamSeqGap,!0)),r.lastSeq=i.seq,V(this.onMessageCallback,i.data))}),r.unsubscribeError=this.channel.subscribeEvent(y.StreamError,i=>{i.subscriptionId===n&&V(this.onErrorCallback,new P(i.code,i.retryable))}),this.current=r,this.channel.invokeApi(g.StreamOpen,{chatbotId:this.options.chatbotId,subscriptionId:n,threadId:e}).catch(()=>{var i;((i=this.current)==null?void 0:i.subscriptionId)===n&&V(this.onErrorCallback,new P(u.StreamOpenFailed,!0))})};this.onMessage=e=>{this.onMessageCallback=e};this.onError=e=>{this.onErrorCallback=e};this.destroy=()=>{let e=this.current;e&&(e.unsubscribeMessage(),e.unsubscribeError(),this.current=void 0,this.channel.invokeApi(g.StreamClose,{subscriptionId:e.subscriptionId}).catch(()=>console.error("[base-site-channel][runtime] Chatbot stream close failed")))};var n;this.channel=(n=e.channel)!=null?n:k}};var ie="prod",ze=0,Ye=()=>typeof crypto!="undefined"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():(ze+=1,`site-ai-fn-${ze}`),E=(t,e)=>{try{t==null||t(e)}catch(n){console.error("[base-site-channel][runtime] AI function callback failed")}},l=(t,e)=>{let n=new Error(e||`AI function error: ${t}`);return n.name="SiteAIFunctionError",n.code=t,n},Ge=()=>l(u.InvalidHttpUrl,"siteToken is required to invoke site AI function"),oe=()=>typeof window!="undefined"&&window.parent!==window,se=t=>{if(typeof queueMicrotask=="function"){queueMicrotask(t);return}Promise.resolve().then(t)},ae=t=>{let e={data:[],event:"message"};for(let n of t.split(/\r?\n/))n.startsWith("event:")?e.event=n.slice(6).trim():n.startsWith("data:")&&e.data.push(n.slice(5).trimStart());return e},re=(t,e)=>{for(let n of e){let r=t[n];if(typeof r=="string")return r}},Je=t=>{let e=[t];if(t&&typeof t=="object"){let n=t;e.push(n.response,n.data)}for(let n of e){if(!n||typeof n!="object")continue;let r=re(n,["request_id","requestId","RequestID","id"]);if(r)return r}},Xe=t=>{if(!t||typeof t!="object")return{};let e=t;return{content:re(e,["content","text","answer"]),reasoningContent:re(e,["reasoning_content","reasoningContent","reasoning"])}},Qt=t=>{if(!t||typeof t!="object")return{};let e=t.choices;if(!Array.isArray(e))return{};for(let n of e){let r=n.delta,{content:i,reasoningContent:o}=Xe(r);if(i!==void 0||o!==void 0)return{content:i,reasoningContent:o}}return{}},Qe=t=>{var n;let e=[t];if(t&&typeof t=="object"){let r=t;e.push(r.response,r.data)}for(let r of e){let i=Qt(r);if(i.content!==void 0||i.reasoningContent!==void 0)return i;let o=Xe(r&&typeof r=="object"&&(n=r.delta)!=null?n:r);if(o.content!==void 0||o.reasoningContent!==void 0)return o}return{}},z=t=>{try{let e=JSON.parse(t),n=Qe(e),r=Je(e);return f(a(a(a({},n.content!==void 0?{content:n.content}:{}),n.reasoningContent!==void 0?{reasoningContent:n.reasoningContent}:{}),r?{requestId:r}:{}),{raw:e})}catch(e){return{content:t,raw:t}}},Ze=t=>{if(typeof t=="string")return z(t);let e=Qe(t),n=Je(t),r=t&&typeof t=="object"&&"raw"in t?t.raw:t;return f(a(a(a({},e.content!==void 0?{content:e.content}:{}),e.reasoningContent!==void 0?{reasoningContent:e.reasoningContent}:{}),n?{requestId:n}:{}),{raw:r})},Zt=t=>{var e,n;try{let r=JSON.parse(t),i=(e=r.Code)!=null?e:r.code,o=(n=r.Message)!=null?n:r.message,s=typeof i=="string"||typeof i=="number"?String(i):"STREAM_FAILED";return l(s||"STREAM_FAILED",typeof o=="string"&&o?o:t)}catch(r){return l("STREAM_FAILED",t)}},ce=()=>({text:""}),en=t=>/(^|\n)(data|event|id|retry):/.test(t),We=t=>{if(!t||t==="[DONE]")return!!t;try{return JSON.parse(t),!0}catch(e){return!1}},tn=t=>{if(t){if(en(t)){let n=ae(t).data.join(`
2
2
  `);return We(n)?n:void 0}return We(t)?t:void 0}},de=(t,e)=>{var o;t.text+=e;let n=t.text.split(/\r?\n\r?\n/);t.text=(o=n.pop())!=null?o:"";let r=n.map(s=>ae(s).data.join(`
3
3
  `)).filter(Boolean),i=tn(t.text);return i!==void 0&&(r.push(i),t.text=""),r},nn=(t,e)=>t==="[DONE]"?(E(e.onDone,void 0),!0):(E(e.onMessage,z(t)),!1),$e=(t,e,n)=>{let r=ae(t);if(r.data.length===0)return!1;let i=r.data.join(`
4
- `);if(r.event==="error")return E(n.onError,Zt(i)),!0;for(let o of de(e,i))if(nn(o,n))return!0;return!1},et=(t,e)=>p(void 0,null,function*(){var s;if(!t.body)throw l(u.StreamUnavailable,"SSE body missing");let n=t.body.getReader(),r=new TextDecoder,i=ce(),o="";try{for(;;){let{done:d,value:c}=yield n.read();o+=r.decode(c,{stream:!d});let m=o.split(/\r?\n\r?\n/);o=(s=m.pop())!=null?s:"";for(let h of m)if($e(h,i,e))return;if(d){if(o&&$e(o,i,e))return;E(e.onError,l(u.StreamInterrupted,"SSE stream ended without [DONE]"));return}}}finally{n.releaseLock()}}),ue=()=>{var n;let t=typeof globalThis.location=="undefined"?"":globalThis.location.pathname,e=/^\/?(preview\/)?app\/([^/]+)(\/|$)/.exec(t);return e?{env:e[1]?"preview":ie,siteToken:decodeURIComponent((n=e[2])!=null?n:"")}:{}},tt=(t,e,n)=>{if(!t.startsWith("/")||t.startsWith("//"))throw l(u.InvalidHttpUrl,"AI function endpoint must be a same-origin relative path");let r=t.replace("{siteToken}",encodeURIComponent(e.siteToken)).replace(":token",encodeURIComponent(e.siteToken)).replace("{functionKey}","").replace(":function_key",""),i=new URL(r,"https://base.site");if(i.searchParams.set("env",e.env),n)for(let[o,s]of Object.entries(n))i.searchParams.set(o,s);return`${i.pathname}${i.search}`};var rn="/space/api/bitable/streaming/site/v1/:token/ai_functions/:function_key/invoke",rt="/space/api/bitable/site/v1/:token/ai_functions/:function_key/tasks",on=6e4,sn=/^([1-9][0-9]{1,4})x([1-9][0-9]{1,4})$/i,an=3686400,cn=16777216,dn=14,un=t=>{let e=t.trim().replace("\xD7","x");if(/^[234]K$/i.test(e))return!0;let n=sn.exec(e);if(!n)return!1;let r=Number(n[1]),i=Number(n[2]),o=r*i;return o>=an&&o<=cn&&r<=i*16&&i<=r*16},ln=t=>{if(!t)return;let e=typeof t.image=="string"?[t.image]:t.image;if(e&&(e.length<1||e.length>dn||e.some(n=>!n.trim())))throw l(u.InvalidAIFunctionTask,"input.image must contain 1 to 14 non-empty strings");if(t.size!==void 0&&!un(t.size))throw l(u.InvalidAIFunctionTask,"input.size must follow the Seedream 5.0 lite size limits")},fe=t=>{var n;let e=(n=t.siteToken)==null?void 0:n.trim();return a(a(a({},t.env?{env:t.env}:{}),t.requestId?{requestId:t.requestId}:{}),e?{siteToken:e}:{})},ge=t=>{var r,i,o;let e=ue(),n=((r=t.siteToken)==null?void 0:r.trim())||e.siteToken;if(!n)throw Ge();return{env:(o=(i=t.env)!=null?i:e.env)!=null?o:ie,requestId:t.requestId,siteToken:n}},Se=(t,e,n)=>tt(t.replace(":function_key",encodeURIComponent(e)),n),it=t=>f(a({},t.requestId?{"X-Request-Id":t.requestId}:{}),{Accept:"application/json","Content-Type":"application/json"}),ot=t=>{var e;return!t.channel&&!oe()?globalThis.fetch:K(j((e=t.channel)!=null?e:k),on)},pe=class{constructor(e,n){this.params=e;this.context=n;this.callbacks={};this.controller=new AbortController;this.closed=!1;this.onMessage=e=>{this.callbacks.onMessage=e};this.onError=e=>{this.callbacks.onError=e};this.onDone=e=>{this.callbacks.onDone=e};this.destroy=()=>{this.closed||(this.closed=!0,this.controller.abort())};se(()=>{this.start()})}start(){return p(this,null,function*(){var e;if(!this.closed)try{let n=yield fetch(Se(rn,this.params.functionKey,this.context),{body:JSON.stringify({messages:this.params.messages,variables:(e=this.params.variables)!=null?e:{}}),credentials:"include",headers:f(a({},this.context.requestId?{"X-Request-Id":this.context.requestId}:{}),{Accept:"text/event-stream","Content-Type":"application/json"}),method:"POST",signal:this.controller.signal});if(!n.ok)throw l("HTTP_ERROR",`${n.status} ${n.statusText}`);yield et(n,this.callbacks)}catch(n){this.closed||E(this.callbacks.onError,n instanceof Error?n:l("STREAM_FAILED"))}})}},he=class{constructor(e){this.options=e;this.closed=!1;this.onMessage=e=>{this.onMessageCallback=e};this.onError=e=>{this.onErrorCallback=e};this.onDone=e=>{this.onDoneCallback=e};this.destroy=()=>{this.closed=!0;let e=this.current;e&&(this.cleanup(),this.channel.invokeApi(g.AIFunctionStreamClose,{subscriptionId:e.subscriptionId}).catch(()=>console.error("[base-site-channel][runtime] AI function stream close failed")))};var n;this.channel=(n=e.channel)!=null?n:k,se(()=>this.init())}init(){var i;if(this.closed)return;this.cleanup();let e=Ye(),n={lastSeq:0,subscriptionId:e,unsubscribeDone:()=>{},unsubscribeError:()=>{},unsubscribeMessage:()=>{},upstream:ce()};n.unsubscribeMessage=this.channel.subscribeEvent(y.AIFunctionStreamMessage,o=>this.handleMessage(o,n)),n.unsubscribeError=this.channel.subscribeEvent(y.AIFunctionStreamError,o=>this.handleError(o,e)),n.unsubscribeDone=this.channel.subscribeEvent(y.AIFunctionStreamDone,o=>this.handleDone(o,e)),this.current=n;let r=a(a(a({functionKey:this.options.params.functionKey,messages:this.options.params.messages,subscriptionId:e,variables:(i=this.options.params.variables)!=null?i:{}},this.options.context.env?{env:this.options.context.env}:{}),this.options.context.requestId?{requestId:this.options.context.requestId}:{}),this.options.context.siteToken?{siteToken:this.options.context.siteToken}:{});this.channel.invokeApi(g.AIFunctionStreamOpen,r).catch(()=>{var o;((o=this.current)==null?void 0:o.subscriptionId)===e&&E(this.onErrorCallback,l(u.StreamOpenFailed))})}handleMessage(e,n){if(e.subscriptionId===n.subscriptionId&&!(e.seq<=n.lastSeq)){if(e.seq>n.lastSeq+1&&E(this.onErrorCallback,l(u.StreamSeqGap)),n.lastSeq=e.seq,typeof e.data!="string"){E(this.onMessageCallback,Ze(e.data));return}de(n.upstream,e.data).forEach(r=>{r!=="[DONE]"&&E(this.onMessageCallback,z(r))})}}handleError(e,n){e.subscriptionId===n&&(E(this.onErrorCallback,l(e.code,e.message)),this.cleanup())}handleDone(e,n){e.subscriptionId===n&&(E(this.onDoneCallback,void 0),this.cleanup())}cleanup(){let e=this.current;e&&(e.unsubscribeMessage(),e.unsubscribeError(),e.unsubscribeDone(),this.current=void 0)}},st=(t,e={})=>{var r;if(!((r=t.functionKey)!=null&&r.trim()))throw l(u.InvalidFunctionName,"functionKey is required");let n=a(a({},ue()),fe(e));return e.channel||oe()?new he({channel:e.channel,context:n,params:t}):new pe(t,ge(e))},pn=t=>p(void 0,null,function*(){if(!t.ok){let e=yield t.text().catch(()=>"");throw l("HTTP_ERROR",`${t.status} ${t.statusText} ${e}`)}try{return yield t.json()}catch(e){throw l(u.InvalidAIFunctionTask,"AI function task response is invalid")}}),w=t=>typeof t=="object"&&t!==null&&!Array.isArray(t),hn=t=>t==="cancelled"||t==="failed"||t==="queued"||t==="running"||t==="succeeded",S=(t,e)=>{for(let n of e){let r=t[n];if(typeof r=="string"&&r.trim())return r}},mn=(t,e)=>{for(let n of e){let r=t[n];if(typeof r=="number"&&Number.isFinite(r))return r}},fn=t=>{let e=S(t,["capabilityType","capability_type","CapabilityType"]);return e==="image"||e==="video"?e:void 0},gn=t=>{if(Array.isArray(t))return t.filter(w).map(e=>{var o;let n=S(e,["size","Size"]),r=S(e,["token","Token"]),i=S(e,["url","URL"]);return a(a(a({safetyStatus:(o=S(e,["safetyStatus","safety_status","SafetyStatus"]))!=null?o:""},n?{size:n}:{}),r?{token:r}:{}),i?{url:i}:{})})},Sn=t=>{var i,o;if(!w(t))return;let e=(o=(i=t.durationSeconds)!=null?i:t.duration_seconds)!=null?o:t.DurationSeconds,n=S(t,["token","Token"]),r=S(t,["url","URL"]);return a(a(a({},typeof e=="number"?{durationSeconds:e}:{}),n?{token:n}:{}),r?{url:r}:{})},le=t=>{var _,H,T,Ie,ye,Ee;if(!w(t))throw l(u.InvalidAIFunctionTask,"AI function task response is invalid");let e=S(t,["type","Type"]),n=S(t,["taskId","task_id","TaskID"]),r=(_=t.status)!=null?_:t.Status;if(e!=="image_task"&&e!=="video_task"||!n||!hn(r))throw l(u.InvalidAIFunctionTask,"AI function task response is invalid");let i=(H=S(t,["requestId","request_id","RequestID"]))!=null?H:"",o=mn(t,["progress","Progress"]),s=fn(t),d=S(t,["errCode","err_code","ErrCode"]),c=S(t,["errMessage","err_message","ErrMessage"]),m=gn((Ie=(T=t.imageAssets)!=null?T:t.image_assets)!=null?Ie:t.ImageAssets),h=Sn((Ee=(ye=t.videoAsset)!=null?ye:t.video_asset)!=null?Ee:t.VideoAsset);return f(a(a(a(a(a(a({},s?{capabilityType:s}:{}),d?{errCode:d}:{}),c?{errMessage:c}:{}),m?{imageAssets:m}:{}),o!==void 0?{progress:o}:{}),h?{videoAsset:h}:{}),{requestId:i,status:r,taskId:n,type:e})},In=t=>{var i,o,s,d,c,m,h;let e=(i=t.code)!=null?i:t.Code;if(typeof e=="number"&&e!==0||typeof e=="string"&&e&&e!=="0")return{code:String(e),message:(o=S(t,["msg","message","Message"]))!=null?o:"AI function task failed"};let n=(d=(s=t.BaseResp)!=null?s:t.base_resp)!=null?d:t.baseResp;if(!w(n))return;let r=(m=(c=n.StatusCode)!=null?c:n.status_code)!=null?m:n.statusCode;if(typeof r=="number"&&r!==0||typeof r=="string"&&r&&r!=="0")return{code:String(r),message:(h=S(n,["StatusMessage","status_message","statusMessage"]))!=null?h:"AI function task failed"}},yn=t=>{if(!w(t))return le(t);let e=In(t);if(e)throw l(e.code,e.message);return"data"in t&&t.data!==void 0?le(t.data):le(t)},at=t=>p(void 0,null,function*(){return yn(yield pn(t))}),me=(n,...r)=>p(void 0,[n,...r],function*(t,e={}){var s,d,c;if(!((s=t.functionKey)!=null&&s.trim()))throw l(u.InvalidFunctionName,"functionKey is required");t.capability==="image"&&ln(t.input);let i=ge(a(a({},e),fe(e))),o=yield ot(e)(Se(rt,t.functionKey,i),{body:JSON.stringify({input:(d=t.input)!=null?d:{},variables:(c=t.variables)!=null?c:{}}),credentials:"include",headers:it(i),method:"POST"});return at(o)}),En=(r,i,...o)=>p(void 0,[r,i,...o],function*(t,e,n={}){if(!(t!=null&&t.trim()))throw l(u.InvalidFunctionName,"functionKey is required");if(typeof e!="string"||!e.trim())throw l(u.InvalidAIFunctionTask,"taskId is required");let s=ge(a(a({},n),fe(n))),d=Se(rt,t,s),c=d.includes("?")?`${d.replace("?",`/${encodeURIComponent(e)}?`)}`:`${d}/${encodeURIComponent(e)}`,m=yield ot(n)(c,{credentials:"include",headers:it(s),method:"GET"});return at(m)}),nt=(t,e)=>new Promise((n,r)=>{var d;let i="",o="",s=st({functionKey:t.functionKey,messages:(d=t.messages)!=null?d:[],variables:t.variables},e);s.onMessage(c=>{typeof c.content=="string"&&(i+=c.content),!o&&typeof c.requestId=="string"&&c.requestId&&(o=c.requestId)}),s.onError(c=>{s.destroy(),r(c)}),s.onDone(()=>{s.destroy(),n({content:i,requestId:o||e.requestId||"",type:"text"})})}),An=(n,...r)=>p(void 0,[n,...r],function*(t,e={}){var i;if(!((i=t.functionKey)!=null&&i.trim()))throw l(u.InvalidFunctionName,"functionKey is required");return t.capability==="image"||t.capability==="video"?me(t,e):t.capability==="text"||t.capability==="vision"?nt(t,e):t.input&&!t.messages?me(t,e):nt(t,e)});export{Oe as SITE_RUNTIME_PROTOCOL_VERSION,ne as SiteChatbotStreamAdapter,F as SiteChatbotStreamError,g as SiteRuntimeApi,q as SiteRuntimeClient,u as SiteRuntimeErrorCode,y as SiteRuntimeEvent,D as SiteRuntimeFunction,I as SiteRuntimeInvocationError,An as callSiteAIFunction,me as createSiteAIFunctionTask,j as createSiteRuntimeClient,K as createSiteRuntimeFetch,Jt as fetch,Dt as getCurrentUser,En as getSiteAIFunctionTask,Ut as invokeApi,Ot as invokeHttp,st as invokeSiteAIFunctionStream,Ue as isValidSiteFunctionName,Bt as logout,_r as readSiteAITextDelta,qt as requestEdit,v as siteRuntime,jt as uploadAttachment};
4
+ `);if(r.event==="error")return E(n.onError,Zt(i)),!0;for(let o of de(e,i))if(nn(o,n))return!0;return!1},et=(t,e)=>p(void 0,null,function*(){var s;if(!t.body)throw l(u.StreamUnavailable,"SSE body missing");let n=t.body.getReader(),r=new TextDecoder,i=ce(),o="";try{for(;;){let{done:d,value:c}=yield n.read();o+=r.decode(c,{stream:!d});let m=o.split(/\r?\n\r?\n/);o=(s=m.pop())!=null?s:"";for(let h of m)if($e(h,i,e))return;if(d){if(o&&$e(o,i,e))return;E(e.onError,l(u.StreamInterrupted,"SSE stream ended without [DONE]"));return}}}finally{n.releaseLock()}}),ue=()=>{var n;let t=typeof globalThis.location=="undefined"?"":globalThis.location.pathname,e=/^\/?(preview\/)?app\/([^/]+)(\/|$)/.exec(t);return e?{env:e[1]?"preview":ie,siteToken:decodeURIComponent((n=e[2])!=null?n:"")}:{}},tt=(t,e,n)=>{if(!t.startsWith("/")||t.startsWith("//"))throw l(u.InvalidHttpUrl,"AI function endpoint must be a same-origin relative path");let r=t.replace("{siteToken}",encodeURIComponent(e.siteToken)).replace(":token",encodeURIComponent(e.siteToken)).replace("{functionKey}","").replace(":function_key",""),i=new URL(r,"https://base.site");if(i.searchParams.set("env",e.env),n)for(let[o,s]of Object.entries(n))i.searchParams.set(o,s);return`${i.pathname}${i.search}`};var rn="/space/api/bitable/streaming/site/v1/:token/ai_functions/:function_key/invoke",rt="/space/api/bitable/site/v1/:token/ai_functions/:function_key/tasks",on=6e4,sn=/^([1-9][0-9]{1,4})x([1-9][0-9]{1,4})$/i,an=3686400,cn=16777216,dn=14,un=t=>{let e=t.trim().replace("\xD7","x");if(/^[234]K$/i.test(e))return!0;let n=sn.exec(e);if(!n)return!1;let r=Number(n[1]),i=Number(n[2]),o=r*i;return o>=an&&o<=cn&&r<=i*16&&i<=r*16},ln=t=>{if(!t)return;let e=typeof t.image=="string"?[t.image]:t.image;if(e&&(e.length<1||e.length>dn||e.some(n=>!n.trim())))throw l(u.InvalidAIFunctionTask,"input.image must contain 1 to 14 non-empty strings");if(t.size!==void 0&&!un(t.size))throw l(u.InvalidAIFunctionTask,"input.size must follow the Seedream 5.0 lite size limits")},fe=t=>{var n;let e=(n=t.siteToken)==null?void 0:n.trim();return a(a(a({},t.env?{env:t.env}:{}),t.requestId?{requestId:t.requestId}:{}),e?{siteToken:e}:{})},ge=t=>{var r,i,o;let e=ue(),n=((r=t.siteToken)==null?void 0:r.trim())||e.siteToken;if(!n)throw Ge();return{env:(o=(i=t.env)!=null?i:e.env)!=null?o:ie,requestId:t.requestId,siteToken:n}},Ie=(t,e,n)=>tt(t.replace(":function_key",encodeURIComponent(e)),n),it=t=>f(a({},t.requestId?{"X-Request-Id":t.requestId}:{}),{Accept:"application/json","Content-Type":"application/json"}),ot=t=>{var e;return!t.channel&&!oe()?globalThis.fetch:K(j((e=t.channel)!=null?e:k),on)},pe=class{constructor(e,n){this.params=e;this.context=n;this.callbacks={};this.controller=new AbortController;this.closed=!1;this.onMessage=e=>{this.callbacks.onMessage=e};this.onError=e=>{this.callbacks.onError=e};this.onDone=e=>{this.callbacks.onDone=e};this.destroy=()=>{this.closed||(this.closed=!0,this.controller.abort())};se(()=>{this.start()})}start(){return p(this,null,function*(){var e;if(!this.closed)try{let n=yield fetch(Ie(rn,this.params.functionKey,this.context),{body:JSON.stringify({messages:this.params.messages,variables:(e=this.params.variables)!=null?e:{}}),credentials:"include",headers:f(a({},this.context.requestId?{"X-Request-Id":this.context.requestId}:{}),{Accept:"text/event-stream","Content-Type":"application/json"}),method:"POST",signal:this.controller.signal});if(!n.ok)throw l("HTTP_ERROR",`${n.status} ${n.statusText}`);yield et(n,this.callbacks)}catch(n){this.closed||E(this.callbacks.onError,n instanceof Error?n:l("STREAM_FAILED"))}})}},he=class{constructor(e){this.options=e;this.closed=!1;this.onMessage=e=>{this.onMessageCallback=e};this.onError=e=>{this.onErrorCallback=e};this.onDone=e=>{this.onDoneCallback=e};this.destroy=()=>{this.closed=!0;let e=this.current;e&&(this.cleanup(),this.channel.invokeApi(g.AIFunctionStreamClose,{subscriptionId:e.subscriptionId}).catch(()=>console.error("[base-site-channel][runtime] AI function stream close failed")))};var n;this.channel=(n=e.channel)!=null?n:k,se(()=>this.init())}init(){var i;if(this.closed)return;this.cleanup();let e=Ye(),n={lastSeq:0,subscriptionId:e,unsubscribeDone:()=>{},unsubscribeError:()=>{},unsubscribeMessage:()=>{},upstream:ce()};n.unsubscribeMessage=this.channel.subscribeEvent(y.AIFunctionStreamMessage,o=>this.handleMessage(o,n)),n.unsubscribeError=this.channel.subscribeEvent(y.AIFunctionStreamError,o=>this.handleError(o,e)),n.unsubscribeDone=this.channel.subscribeEvent(y.AIFunctionStreamDone,o=>this.handleDone(o,e)),this.current=n;let r=a(a(a({functionKey:this.options.params.functionKey,messages:this.options.params.messages,subscriptionId:e,variables:(i=this.options.params.variables)!=null?i:{}},this.options.context.env?{env:this.options.context.env}:{}),this.options.context.requestId?{requestId:this.options.context.requestId}:{}),this.options.context.siteToken?{siteToken:this.options.context.siteToken}:{});this.channel.invokeApi(g.AIFunctionStreamOpen,r).catch(()=>{var o;((o=this.current)==null?void 0:o.subscriptionId)===e&&E(this.onErrorCallback,l(u.StreamOpenFailed))})}handleMessage(e,n){if(e.subscriptionId===n.subscriptionId&&!(e.seq<=n.lastSeq)){if(e.seq>n.lastSeq+1&&E(this.onErrorCallback,l(u.StreamSeqGap)),n.lastSeq=e.seq,typeof e.data!="string"){E(this.onMessageCallback,Ze(e.data));return}de(n.upstream,e.data).forEach(r=>{r!=="[DONE]"&&E(this.onMessageCallback,z(r))})}}handleError(e,n){e.subscriptionId===n&&(E(this.onErrorCallback,l(e.code,e.message)),this.cleanup())}handleDone(e,n){e.subscriptionId===n&&(E(this.onDoneCallback,void 0),this.cleanup())}cleanup(){let e=this.current;e&&(e.unsubscribeMessage(),e.unsubscribeError(),e.unsubscribeDone(),this.current=void 0)}},st=(t,e={})=>{var r;if(!((r=t.functionKey)!=null&&r.trim()))throw l(u.InvalidFunctionName,"functionKey is required");let n=a(a({},ue()),fe(e));return e.channel||oe()?new he({channel:e.channel,context:n,params:t}):new pe(t,ge(e))},pn=t=>p(void 0,null,function*(){if(!t.ok){let e=yield t.text().catch(()=>"");throw l("HTTP_ERROR",`${t.status} ${t.statusText} ${e}`)}try{return yield t.json()}catch(e){throw l(u.InvalidAIFunctionTask,"AI function task response is invalid")}}),w=t=>typeof t=="object"&&t!==null&&!Array.isArray(t),hn=t=>t==="cancelled"||t==="failed"||t==="queued"||t==="running"||t==="succeeded",I=(t,e)=>{for(let n of e){let r=t[n];if(typeof r=="string"&&r.trim())return r}},mn=(t,e)=>{for(let n of e){let r=t[n];if(typeof r=="number"&&Number.isFinite(r))return r}},fn=t=>{let e=I(t,["capabilityType","capability_type","CapabilityType"]);return e==="image"||e==="video"?e:void 0},gn=t=>{if(Array.isArray(t))return t.filter(w).map(e=>{var o;let n=I(e,["size","Size"]),r=I(e,["token","Token"]),i=I(e,["url","URL"]);return a(a(a({safetyStatus:(o=I(e,["safetyStatus","safety_status","SafetyStatus"]))!=null?o:""},n?{size:n}:{}),r?{token:r}:{}),i?{url:i}:{})})},In=t=>{var i,o;if(!w(t))return;let e=(o=(i=t.durationSeconds)!=null?i:t.duration_seconds)!=null?o:t.DurationSeconds,n=I(t,["token","Token"]),r=I(t,["url","URL"]);return a(a(a({},typeof e=="number"?{durationSeconds:e}:{}),n?{token:n}:{}),r?{url:r}:{})},le=t=>{var x,H,T,Se,ye,Ee;if(!w(t))throw l(u.InvalidAIFunctionTask,"AI function task response is invalid");let e=I(t,["type","Type"]),n=I(t,["taskId","task_id","TaskID"]),r=(x=t.status)!=null?x:t.Status;if(e!=="image_task"&&e!=="video_task"||!n||!hn(r))throw l(u.InvalidAIFunctionTask,"AI function task response is invalid");let i=(H=I(t,["requestId","request_id","RequestID"]))!=null?H:"",o=mn(t,["progress","Progress"]),s=fn(t),d=I(t,["errCode","err_code","ErrCode"]),c=I(t,["errMessage","err_message","ErrMessage"]),m=gn((Se=(T=t.imageAssets)!=null?T:t.image_assets)!=null?Se:t.ImageAssets),h=In((Ee=(ye=t.videoAsset)!=null?ye:t.video_asset)!=null?Ee:t.VideoAsset);return f(a(a(a(a(a(a({},s?{capabilityType:s}:{}),d?{errCode:d}:{}),c?{errMessage:c}:{}),m?{imageAssets:m}:{}),o!==void 0?{progress:o}:{}),h?{videoAsset:h}:{}),{requestId:i,status:r,taskId:n,type:e})},Sn=t=>{var i,o,s,d,c,m,h;let e=(i=t.code)!=null?i:t.Code;if(typeof e=="number"&&e!==0||typeof e=="string"&&e&&e!=="0")return{code:String(e),message:(o=I(t,["msg","message","Message"]))!=null?o:"AI function task failed"};let n=(d=(s=t.BaseResp)!=null?s:t.base_resp)!=null?d:t.baseResp;if(!w(n))return;let r=(m=(c=n.StatusCode)!=null?c:n.status_code)!=null?m:n.statusCode;if(typeof r=="number"&&r!==0||typeof r=="string"&&r&&r!=="0")return{code:String(r),message:(h=I(n,["StatusMessage","status_message","statusMessage"]))!=null?h:"AI function task failed"}},yn=t=>{if(!w(t))return le(t);let e=Sn(t);if(e)throw l(e.code,e.message);return"data"in t&&t.data!==void 0?le(t.data):le(t)},at=t=>p(void 0,null,function*(){return yn(yield pn(t))}),me=(n,...r)=>p(void 0,[n,...r],function*(t,e={}){var s,d,c;if(!((s=t.functionKey)!=null&&s.trim()))throw l(u.InvalidFunctionName,"functionKey is required");t.capability==="image"&&ln(t.input);let i=ge(a(a({},e),fe(e))),o=yield ot(e)(Ie(rt,t.functionKey,i),{body:JSON.stringify({input:(d=t.input)!=null?d:{},variables:(c=t.variables)!=null?c:{}}),credentials:"include",headers:it(i),method:"POST"});return at(o)}),En=(r,i,...o)=>p(void 0,[r,i,...o],function*(t,e,n={}){if(!(t!=null&&t.trim()))throw l(u.InvalidFunctionName,"functionKey is required");if(typeof e!="string"||!e.trim())throw l(u.InvalidAIFunctionTask,"taskId is required");let s=ge(a(a({},n),fe(n))),d=Ie(rt,t,s),c=d.includes("?")?`${d.replace("?",`/${encodeURIComponent(e)}?`)}`:`${d}/${encodeURIComponent(e)}`,m=yield ot(n)(c,{credentials:"include",headers:it(s),method:"GET"});return at(m)}),nt=(t,e)=>new Promise((n,r)=>{var d;let i="",o="",s=st({functionKey:t.functionKey,messages:(d=t.messages)!=null?d:[],variables:t.variables},e);s.onMessage(c=>{typeof c.content=="string"&&(i+=c.content),!o&&typeof c.requestId=="string"&&c.requestId&&(o=c.requestId)}),s.onError(c=>{s.destroy(),r(c)}),s.onDone(()=>{s.destroy(),n({content:i,requestId:o||e.requestId||"",type:"text"})})}),An=(n,...r)=>p(void 0,[n,...r],function*(t,e={}){var i;if(!((i=t.functionKey)!=null&&i.trim()))throw l(u.InvalidFunctionName,"functionKey is required");return t.capability==="image"||t.capability==="video"?me(t,e):t.capability==="text"||t.capability==="vision"?nt(t,e):t.input&&!t.messages?me(t,e):nt(t,e)});export{Oe as SITE_RUNTIME_PROTOCOL_VERSION,ne as SiteChatbotStreamAdapter,P as SiteChatbotStreamError,g as SiteRuntimeApi,q as SiteRuntimeClient,u as SiteRuntimeErrorCode,y as SiteRuntimeEvent,D as SiteRuntimeFunction,S as SiteRuntimeInvocationError,An as callSiteAIFunction,me as createSiteAIFunctionTask,j as createSiteRuntimeClient,K as createSiteRuntimeFetch,Jt as fetch,Dt as getCurrentUser,En as getSiteAIFunctionTask,Ut as invokeApi,Ot as invokeHttp,st as invokeSiteAIFunctionStream,Ue as isValidSiteFunctionName,Bt as logout,xr as readSiteAITextDelta,qt as requestEdit,v as siteRuntime,jt as uploadAttachment};
package/package.json CHANGED
@@ -1 +1 @@
1
- {"name":"@lark-base-open/base-site-channel","version":"0.1.1","description":"","main":"dist/index.mjs","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs"},"./client":{"types":"./dist/client.d.ts","import":"./dist/client.mjs"},"./runtime":{"types":"./dist/runtime.d.ts","import":"./dist/runtime.mjs"},"./runtime-contract":{"types":"./dist/runtime-contract.d.ts","import":"./dist/runtime-contract.mjs"}},"files":["dist"],"scripts":{"test":"npm run build && node --import tsx --test test/*.test.ts && npm run test:types","test:types":"tsc --noEmit --strict --skipLibCheck --module esnext --moduleResolution bundler --target es2022 test-types/function-map.ts","build":"tsup","dev":"NODE_ENV=development tsup --watch","upload:alpha":"pnpm build && npx @bitable/pack-dev-cli upload"},"keywords":[],"author":"","devDependencies":{"@types/node":"^22.15.0","tsup":"^6.7.0","tsx":"^4.20.3","typescript":"^5.8.3"},"dependencies":{"lodash-es":"^4.17.21"}}
1
+ {"name":"@lark-base-open/base-site-channel","version":"0.1.3","description":"","main":"dist/index.mjs","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs"},"./client":{"types":"./dist/client.d.ts","import":"./dist/client.mjs"},"./runtime":{"types":"./dist/runtime.d.ts","import":"./dist/runtime.mjs"},"./runtime-contract":{"types":"./dist/runtime-contract.d.ts","import":"./dist/runtime-contract.mjs"}},"files":["dist"],"scripts":{"test":"npm run build && node --import tsx --test test/*.test.ts && npm run test:types","test:types":"tsc --noEmit --strict --skipLibCheck --module esnext --moduleResolution bundler --target es2022 test-types/function-map.ts","build":"tsup","dev":"NODE_ENV=development tsup --watch","upload:alpha":"pnpm build && npx @bitable/pack-dev-cli upload"},"keywords":[],"author":"","devDependencies":{"@types/node":"^22.15.0","tsup":"^6.7.0","tsx":"^4.20.3","typescript":"^5.8.3"},"dependencies":{"lodash-es":"^4.17.21"}}