@artenx/dshb 0.1.34 → 0.1.36

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.
Files changed (46) hide show
  1. package/lib/client.js +34 -3
  2. package/lib/client.js.map +1 -1
  3. package/lib/core/index.js +1 -1
  4. package/lib/core/routes.d.ts +1 -1
  5. package/lib/core/sync/coordinator.d.ts +16 -5
  6. package/lib/core/sync/coordinator.js +108 -37
  7. package/lib/core/sync/coordinator.js.map +1 -1
  8. package/lib/core/sync/host-key.d.ts +1 -1
  9. package/lib/core/sync/internal-routes.d.ts +3 -3
  10. package/lib/core/sync/internal-routes.js +1 -1
  11. package/lib/core/sync/model.d.ts +1 -1
  12. package/lib/core/sync/model.js.map +1 -1
  13. package/lib/core/sync/node-sync.d.ts +1 -1
  14. package/lib/core/sync/offline-archive.d.ts +3 -3
  15. package/lib/core/sync/offline-archive.js +1 -1
  16. package/lib/core/sync/offline-routes.js +1 -1
  17. package/lib/core/sync/peer-manager.d.ts +2 -2
  18. package/lib/core/sync/peer-manager.js +18 -5
  19. package/lib/core/sync/peer-manager.js.map +1 -1
  20. package/lib/core/sync/routes.d.ts +1 -1
  21. package/lib/core/sync/routes.js +19 -0
  22. package/lib/core/sync/routes.js.map +1 -1
  23. package/lib/core/sync/session-journal.d.ts +1 -1
  24. package/lib/core/sync/session-journal.js +16 -0
  25. package/lib/core/sync/session-journal.js.map +1 -1
  26. package/lib/core/sync/session-routes.d.ts +1 -1
  27. package/lib/core/sync/session-routes.js +1 -1
  28. package/lib/core/sync/session-sync.d.ts +1 -1
  29. package/lib/core/sync/session-sync.js +1 -1
  30. package/lib/core/sync/ssh-transport.d.ts +1 -1
  31. package/lib/core/sync/ssh-transport.js +29 -2
  32. package/lib/core/sync/ssh-transport.js.map +1 -1
  33. package/lib/core/sync/stores.d.ts +1 -1
  34. package/lib/core/sync/stores.js +1 -1
  35. package/lib/core/sync/stores.js.map +1 -1
  36. package/lib/core/workspaces.d.ts +1 -1
  37. package/lib/{host-key-C5afhAUd.d.ts → host-key-CSnpIrjq.d.ts} +2 -2
  38. package/lib/{model-BP7Gw1yk.d.ts → model-CKTBf-Pl.d.ts} +2 -2
  39. package/lib/{node-sync-3Z9QLz2n.d.ts → node-sync-C3Ym-HDu.d.ts} +3 -3
  40. package/lib/{session-journal-pgPqcWn9.d.ts → session-journal-VE_1tA2-.d.ts} +8 -2
  41. package/lib/{session-sync-CIqjuWkh.js → session-sync-DLr_BdvN.js} +15 -1
  42. package/lib/{session-sync-CIqjuWkh.js.map → session-sync-DLr_BdvN.js.map} +1 -1
  43. package/lib/{session-sync-BuOJvFxK.d.ts → session-sync-DrKShc5c.d.ts} +11 -5
  44. package/lib/{ssh-transport-C7povM0s.d.ts → ssh-transport-BxPWfu9X.d.ts} +13 -6
  45. package/lib/{stores-CKyEt0yk.d.ts → stores-puyTC075.d.ts} +2 -2
  46. package/package.json +1 -1
package/lib/client.js CHANGED
@@ -2395,6 +2395,7 @@ window.__ModuleLoader__.load({
2395
2395
  const [probingRemote, setProbingRemote] = (0, react.useState)(false);
2396
2396
  const [remoteProbe, setRemoteProbe] = (0, react.useState)(void 0);
2397
2397
  const [syncing, setSyncing] = (0, react.useState)(false);
2398
+ const [stopping, setStopping] = (0, react.useState)(false);
2398
2399
  const [notice, setNotice] = (0, react.useState)(void 0);
2399
2400
  const [hostKeyChallenge, setHostKeyChallenge] = (0, react.useState)(void 0);
2400
2401
  (0, react.useEffect)(() => {
@@ -2432,6 +2433,7 @@ window.__ModuleLoader__.load({
2432
2433
  const status = peer.progress?.lastRunStatus;
2433
2434
  if (!peer.enabled) return "已停用";
2434
2435
  if (status === "running") return "同步中";
2436
+ if (status === "stopped") return "上次已停止(未完成批次已丢弃)";
2435
2437
  if (status === "failed") return "上次失败";
2436
2438
  if (status === "succeeded") return "上次成功";
2437
2439
  return "尚未同步";
@@ -2609,6 +2611,34 @@ window.__ModuleLoader__.load({
2609
2611
  setSyncing(false);
2610
2612
  }
2611
2613
  };
2614
+ const stopSync = async () => {
2615
+ if (selectedId === "new") return;
2616
+ setStopping(true);
2617
+ try {
2618
+ const response = await fetch(`/api/dshb/sync/peers/${selectedId}/stop`, { method: "POST" });
2619
+ const data = await readJsonResponse(response, "停止同步失败");
2620
+ if (!response.ok || !data.ok) throw new Error(data.error ?? "停止同步失败");
2621
+ setPeers((current) => current.map((peer) => peer.id === selectedId ? {
2622
+ ...peer,
2623
+ progress: {
2624
+ ...peer.progress,
2625
+ lastRunStatus: data.stopped ? "running" : peer.progress?.lastRunStatus
2626
+ }
2627
+ } : peer));
2628
+ setNotice({
2629
+ kind: "ok",
2630
+ text: data.stopped ? "已请求停止:将在最近的安全边界中止,未完成的批次会被丢弃,已完成的会话保留" : "当前没有运行中的同步作业"
2631
+ });
2632
+ reload();
2633
+ } catch (error) {
2634
+ setNotice({
2635
+ kind: "error",
2636
+ text: error instanceof Error ? error.message : "停止同步失败"
2637
+ });
2638
+ } finally {
2639
+ setStopping(false);
2640
+ }
2641
+ };
2612
2642
  const restoreArchive = async (branchId) => {
2613
2643
  const archive = archives.find((entry) => entry.branchId === branchId);
2614
2644
  if (!archive || !window.confirm(`恢复会话 ${archive.originSessionId} 的归档版本?当前版本将保留在归档中。`)) return;
@@ -2633,6 +2663,7 @@ window.__ModuleLoader__.load({
2633
2663
  };
2634
2664
  const progressLabel = (peer) => {
2635
2665
  if (peer.progress?.lastRunStatus === "running") return "同步中";
2666
+ if (peer.progress?.lastRunStatus === "stopped") return "上次已停止:未完成的批次已丢弃,已完成的会话保留";
2636
2667
  if (peer.progress?.lastRunStatus === "failed") return `上次失败:${peer.progress.lastErrorMessage ?? "同步失败"}`;
2637
2668
  if (peer.progress?.lastSuccessAt) return `上次成功:${new Date(peer.progress.lastSuccessAt).toLocaleString()}`;
2638
2669
  return "尚未同步";
@@ -3256,10 +3287,10 @@ window.__ModuleLoader__.load({
3256
3287
  }),
3257
3288
  !isNew && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
3258
3289
  type: "button",
3259
- onClick: () => void runSync(),
3260
- disabled: busy || probing || syncInProgress || !selectedPeer?.enabled,
3290
+ onClick: () => void (syncInProgress ? stopSync() : runSync()),
3291
+ disabled: busy || probing || stopping || !selectedPeer?.enabled && !syncInProgress,
3261
3292
  style: secondaryBtn,
3262
- children: syncInProgress ? "同步中…" : "立即同步"
3293
+ children: stopping ? "正在停止…" : syncInProgress ? "停止同步" : "立即同步"
3263
3294
  }),
3264
3295
  !isNew && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
3265
3296
  type: "button",