dsh-home-ilife 0.3.84 → 0.3.85

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/client.js CHANGED
@@ -39,8 +39,21 @@ window.__ModuleLoader__.load({
39
39
  * 维护者裁定**整条删除、删后不另找地方说**——理由:三家高级项全是只读行、不参与保存、根本没有"留空",
40
40
  * 而"留空会怎样"这条口径本就逐行住在每条的 `hint` 里(见本件 `ConfigItem.hint` 的契约)。 */
41
41
  const ADVANCED_GROUP_TITLE = "高级";
42
- /** 请求超时毫秒:与宿主侧 SPAWN_TIMEOUT_MS 同级,界面永不无限转圈。 */
43
- const READ_TIMEOUT_MS = 2e4;
42
+ /** 面板读整面(config.get)的请求超时毫秒:界面永不无限转圈。
43
+ *
44
+ * 只作用于**面板首帧读整面**这一条路;宿主侧 `skill-cli/contract.ts` 的 SPAWN_TIMEOUT_MS(20s)
45
+ * 是 CLI spawn 进程自身的上限,两者不是同一个数、也不再「同级」——别拿这条去推断宿主侧时限。
46
+ *
47
+ * #1302:20s → 6s。机器级抖动下单次 CLI spawn 实测会到 10.3s/10.4s,20s 让一次慢例先空等 20s
48
+ * 才进重试;6s 落在验收带 5–8s 内(正常读回 <1s,不会误伤)。各插件包里另外那几条单次读时限
49
+ * (体检、版本、取数)是别的读路,按票面「本次不做」保持原值。 */
50
+ const READ_TIMEOUT_MS = 6e3;
51
+ /** 保存/重置(config.save/config.reset)的请求超时毫秒:#1302 只收**读整面**这一条路,写路保持 20s。
52
+ *
53
+ * 为什么不能跟着读一起收:写路不重试、不进预算(见上面 CONFIG_READ_RETRY_MS),而宿主侧 spawn 一个
54
+ * CLI 进程最多给 20s(`skill-cli/contract.ts` 的 SPAWN_TIMEOUT_MS);慢例 spawn 实测到 10.3s,
55
+ * 若写路也 6s,界面会先判失败而宿主可能已经写成功——把一次成功的保存说成失败。 */
56
+ const WRITE_TIMEOUT_MS = 2e4;
44
57
  /** 快路径首帧有界重试表(#1142,照 #982 更新目标表同值:瞬时未就绪不再整面失败)。
45
58
  *
46
59
  * 有界、调用方负责卸载清理(见 `config-panel.ts` 的取数),不是无界轮询;仅读整面用,保存/重置永不自动重试。 */
@@ -207,8 +220,11 @@ window.__ModuleLoader__.load({
207
220
  }, ms);
208
221
  });
209
222
  }
210
- /** 一次配置电话(走调用方给的那条通道,靠端点名分发;永不抛,失败落字,文案自带通道与下一步)。 */
211
- async function configRpcOnce(call, channel, method, payload) {
223
+ /** 一次配置电话(走调用方给的那条通道,靠端点名分发;永不抛,失败落字,文案自带通道与下一步)。
224
+ *
225
+ * `timeoutMs` 由调用方按读路/写路给(#1302:读整面 6s 收口,保存/重置保持 20s);
226
+ * 超时文案里的秒数也从它算,别在这里写死常量。 */
227
+ async function configRpcOnce(call, channel, method, payload, timeoutMs = READ_TIMEOUT_MS) {
212
228
  if (typeof call !== "function") return {
213
229
  ok: false,
214
230
  message: `宿主连接缺席:connection.rpc.call 不可用(通道 ${channel}),稍后重试`
@@ -217,7 +233,7 @@ window.__ModuleLoader__.load({
217
233
  const raw = await withDeadline(call("/api", channel.replace(/^\//, ""), {
218
234
  method,
219
235
  payload
220
- }, AbortSignal.timeout(READ_TIMEOUT_MS)), READ_TIMEOUT_MS);
236
+ }, AbortSignal.timeout(timeoutMs)), timeoutMs);
221
237
  if (!isRpcResult(raw)) return {
222
238
  ok: false,
223
239
  message: `回执信封异常(通道 ${channel}),点重试重新读取`
@@ -233,7 +249,7 @@ window.__ModuleLoader__.load({
233
249
  } catch (e) {
234
250
  if (e instanceof Error && (e.name === "AbortError" || e.name === "TimeoutError")) return {
235
251
  ok: false,
236
- message: `配置请求超时(${Math.round(READ_TIMEOUT_MS / 1e3)}s,通道 ${channel}):宿主未回,点重试重新读取`
252
+ message: `配置请求超时(${Math.round(timeoutMs / 1e3)}s,通道 ${channel}):宿主未回,点重试重新读取`
237
253
  };
238
254
  return {
239
255
  ok: false,
@@ -246,10 +262,13 @@ window.__ModuleLoader__.load({
246
262
  const delays = retry?.delays ?? [];
247
263
  const sleepFn = retry?.sleep ?? retrySleep;
248
264
  const alive = retry?.isAlive ?? (() => true);
265
+ const now = retry?.now ?? Date.now;
266
+ const deadline = now() + (retry?.budgetMs ?? 15e3);
249
267
  let last = await configRpcOnce(call, channel, RPC_ENDPOINT_CONFIG_GET, {});
250
268
  for (let i = 0; i < delays.length && !last.ok; i += 1) {
251
269
  if (!alive()) return last;
252
270
  const wait = delays[i] ?? 0;
271
+ if (now() + wait + 6e3 > deadline) break;
253
272
  if (wait > 0) await sleepFn(wait);
254
273
  if (!alive()) return last;
255
274
  last = await configRpcOnce(call, channel, RPC_ENDPOINT_CONFIG_GET, {});
@@ -258,11 +277,11 @@ window.__ModuleLoader__.load({
258
277
  }
259
278
  /** 保存一份取值(回执只有 `{path, values}`,**不是**整面:写完要重新读一份整面;永不自动重试)。 */
260
279
  function saveConfigSurface(call, channel, values) {
261
- return configRpcOnce(call, channel, RPC_ENDPOINT_CONFIG_SAVE, { values });
280
+ return configRpcOnce(call, channel, RPC_ENDPOINT_CONFIG_SAVE, { values }, WRITE_TIMEOUT_MS);
262
281
  }
263
282
  /** 重置为默认(技能侧先落一份备份;回执同样不是整面,写完要重新读一份整面;永不自动重试)。 */
264
283
  function resetConfigSurface(call, channel) {
265
- return configRpcOnce(call, channel, RPC_ENDPOINT_CONFIG_RESET, {});
284
+ return configRpcOnce(call, channel, RPC_ENDPOINT_CONFIG_RESET, {}, WRITE_TIMEOUT_MS);
266
285
  }
267
286
  //#endregion
268
287
  //#region ../plugin-manager/src/directory-browser-contract.ts