dsh-recall-plugin 2.3.16 → 2.3.19
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/CHANGELOG.md +24 -0
- package/lib/client.js +100 -2
- package/lib/routes-core.js +2 -1
- package/lib/snapshots.js +44 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,30 @@
|
|
|
2
2
|
|
|
3
3
|
本文件格式遵循 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.1.0/),版本号遵循语义化版本。
|
|
4
4
|
|
|
5
|
+
## [2.3.19] - 2026-09-12
|
|
6
|
+
|
|
7
|
+
### 修复
|
|
8
|
+
|
|
9
|
+
> 本次为 2.3.17 起改动的首次 npm 发布:2.3.17 / 2.3.18 未单独发版,其全部改动随本版本一并上线。
|
|
10
|
+
|
|
11
|
+
- **2.3.17 的「排队消息」自动清理在真机上从未生效**(本机 `~/.dsh/sessions` 会话日志解压实证:两次撤回的残留排队项分别在 fork 后 92 秒与 9 秒才出现移除事件——均为手动删除,自动清理的重试窗口内子会话日志无任何队列事件)。两个静默失败面,各修一半:
|
|
12
|
+
- **Client 侧重试窗口太短**:队列快照走 control 帧,`fork` 解析后还要等 `open`/staging 完成才到达——实测可晚于数秒,原 10×200ms(2 秒)窗口全部落空后静默放弃,残留卡片一直挂着。修复:扩为 30 秒长轮询(250ms 间隔,命中即停);窗口耗尽仍无匹配时不再静默——`console.warn` 留排查痕迹,toast 提示「撤回前的一条排队消息未被自动清理,可点击该卡片右上角的删除按钮手动移除」(toast 按文本节流,同一文案 10 分钟至多一次)。
|
|
13
|
+
- **Host 侧解析只认 live 内存事件**:`resolveStaleQueueRpcIds` 此前在 `sessions.get()` 拿不到对象或其 `events` 字段缺失(版本漂移)时恒返回空数组,Client 收到空集合就什么都不做;而切点解析 `resolveCutSeq` 有磁盘降级链兜底、切点永远正常,恰好掩盖了这个缺失。修复:补齐与 `resolveCutSeq` 同款的两跳降级(`sessionQuery.readSession` → `observeSession`,后者覆盖 seeded 父会话——撤回链的父会话本身可能就是上一次撤回 fork 出的子会话;租约 `Symbol.dispose` 释放),两跳都失败才返回空数组。
|
|
14
|
+
- 顺带核验了匹配键契约:宿主队列帧构造(`queueItemsFromInbox` / `promptRpcId`)对所有 `user` 来源行透传 `source.rpcId`,seed 重放行同样携带,`placement: 'queued'` 与 `{ kind: 'remove' }` 动作均与官方 QueueDock 行为一致,无需扩展。
|
|
15
|
+
|
|
16
|
+
## [2.3.18] - 2026-09-12
|
|
17
|
+
|
|
18
|
+
### 修复
|
|
19
|
+
|
|
20
|
+
- **用户消息里的文件块被渲染成原始 JSON**:插件覆盖了整个用户节点渲染(`conversation.chat.node` keyed 渲染器),此前只对 text/image 两类块做呈现——图片走官方 `renderMessageImages`、文本走气泡,其余块一律落进 JSON 兜底 `<pre>`。于是带文档/表格附件(`type: 'file'`)的消息(含撤回后重绘的那些)整块显示成 `{"type":"file","attachment":{…}}` 原文,而官方渲染是文件卡片。修复:新增 `fileCardInfo` 纯函数(文件名 / 扩展名徽标——大写截断 4 字符、无扩展名回退 `FILE` / 体积文本 `6.7KB` 官方风)与 `.dsh-recall-filecard*` 样式,file 块渲染成与官方 `UserStyleBubble` 同形的卡片(品牌色徽标 + 文件名单行省略 + 「MD 6.7KB」元信息),按「附件在上、文本在下」的官方布局排布,并从 JSON 兜底中剔除。新增 4 例单测。
|
|
21
|
+
- **被撤回消息里的文件附件回填静默缺失**:官方 `session.attachment`(`readAttachment`)只服务图片——Host 侧按 `referencedImage` 找引用、`readImage` 取字节,file 块直接判 `ATTACHMENT_NOT_REFERENCED`;插件读不到字节就填不回输入框,此前静默跳过。修复:撤回成功后若被撤回消息含 file 块,toast 明示「文件附件无法自动回填(官方接口只支持图片回读),请重新选择文件」,不再让用户以为回填是完整的(文本与图片回填照旧)。
|
|
22
|
+
|
|
23
|
+
## [2.3.17] - 2026-09-12
|
|
24
|
+
|
|
25
|
+
### 修复
|
|
26
|
+
|
|
27
|
+
- **撤回后输入框上方凭空多出一条「排队消息」**:官方 `sessions.fork({ atSeq })` 的切点不是「切点事件本身」,而是从该 `turn/end` 推进到**下一个 `turn/start` 之前**的整段事件——排队投递的用户消息,其 inbox 入队事件(`agent/inbox/spliced`,`target: 'next-turn'`)必然落在「上一个 `turn/end`」与「领取它的那个 `turn/start`」之间,正好被复制进子会话 seed;子会话重建 inbox 后,QueueDock 就把这条本该随撤回消失的消息显示成排队消息,与回填到输入框的内容重复(本机 `~/.dsh/sessions` 会话日志解压实证:父会话 seq 93 `turn/end` → 94 入队 → 95 `turn/start` → 96 领取后移除 → 100 `user/message` 落日志,子会话 seed 恰止于 94)。修复分两半:Host 侧新增 `scanStaleQueueRpcIds` 扫切点窗口内的 inbox 入队项、取出 `source.kind === 'user'` 项的 `rpcId`(prompt 提交身份),经 execute 响应新增的 `staleQueueRpcIds` 下发;Client 侧 fork 出子会话并 open 后 `purgeStaleQueueItems` 读 `sessions.binding(childId).session.getSnapshot().queue`,按 `placement === 'queued'` + rpcId 命中逐项调官方 `updateQueue(itemId, { kind: 'remove' })`(即 QueueDock 的「删除排队消息」)。用 rpcId 而非内容比对——撤回后新发的消息带自己的 rpcId,不会被误删。queue 快照走控制流、fork 后可能晚一两拍才到,故做 10×200ms 有界重试;拿不到 live 事件(冷会话)或服务面缺失时静默放弃(残留项仍可在 QueueDock 手动删除),不影响回填与撤回主流程。新增 `tests/unit/snapshots-queue-residue.test.js`(6 例)与 `pickStaleQueueItemIds` 3 例,`routes-stale` 补 stub 与透传断言,compat-audit 新增 I35。
|
|
28
|
+
|
|
5
29
|
## [2.3.16] - 2026-09-11
|
|
6
30
|
|
|
7
31
|
### 变更
|
package/lib/client.js
CHANGED
|
@@ -10,6 +10,14 @@ var CSS = [
|
|
|
10
10
|
".dsh-recall-stack{flex-direction:column;align-items:flex-end;gap:8px;min-width:0;max-width:min(525px,82%);display:flex}",
|
|
11
11
|
".dsh-recall-bubble{background:var(--dsw-specific-bubble);max-width:100%;color:var(--dsw-alias-label-primary);border-radius:22px;padding:10px 16px;font-size:16px;line-height:1.5;white-space:pre-wrap;word-break:break-word}",
|
|
12
12
|
".dsh-recall-json{margin:0;max-width:100%;font-size:12px;line-height:1.5;color:var(--dsw-alias-label-tertiary);white-space:pre-wrap;word-break:break-word;border:1px solid var(--dsw-alias-border-l1);border-radius:10px;padding:8px 10px;background:var(--dsw-alias-markdown-code-block)}",
|
|
13
|
+
// 文件卡片(消息里的 file 块,非图片附件):复刻官方 UserStyleBubble 的附件卡
|
|
14
|
+
// ——品牌色扩展名徽标 + 文件名(单行省略)+ 「MD 6.7KB」元信息行;令牌沿用
|
|
15
|
+
// 卡片体系(layer-3 底 + 发丝描边),与图片附件的「附件在上」布局并列。
|
|
16
|
+
".dsh-recall-filecard{display:flex;align-items:center;gap:10px;max-width:100%;box-sizing:border-box;background:var(--dsw-alias-bg-layer-3);border:.5px solid var(--dsw-alias-border-l4);border-radius:12px;padding:8px 12px}",
|
|
17
|
+
".dsh-recall-filecard-icon{flex:none;width:34px;height:34px;border-radius:8px;background:var(--dsw-alias-brand-primary);color:var(--dsw-alias-label-primary-foreground);font-size:11px;font-weight:600;line-height:1;letter-spacing:.02em;display:flex;align-items:center;justify-content:center}",
|
|
18
|
+
".dsh-recall-filecard-body{display:flex;flex-direction:column;gap:2px;min-width:0}",
|
|
19
|
+
".dsh-recall-filecard-name{color:var(--dsw-alias-label-primary);font-size:14px;line-height:1.4;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}",
|
|
20
|
+
".dsh-recall-filecard-meta{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:1.4}",
|
|
13
21
|
".dsh-recall-actions{align-items:center;gap:10px;height:28px;display:flex}",
|
|
14
22
|
".dsh-recall-time{color:var(--dsw-alias-label-tertiary);white-space:nowrap;padding-right:12px;font-size:14px;line-height:1.5}",
|
|
15
23
|
".dsh-recall-action{width:28px;height:28px;color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:none;border-radius:28px;justify-content:center;align-items:center;padding:6px;display:inline-flex}",
|
|
@@ -398,6 +406,41 @@ function defaultAttachmentName(mediaType, index) {
|
|
|
398
406
|
const sub = (slash >= 0 ? text.slice(slash + 1) : text).replace(/[^a-z0-9.+-]/gi, "");
|
|
399
407
|
return "attachment-" + String(index + 1) + "." + (sub || "bin");
|
|
400
408
|
}
|
|
409
|
+
function fileExtOf(name) {
|
|
410
|
+
const dot = name.lastIndexOf(".");
|
|
411
|
+
const raw = dot > 0 && dot < name.length - 1 ? name.slice(dot + 1) : "";
|
|
412
|
+
const ext = raw.replace(/[^a-z0-9]/gi, "").toUpperCase();
|
|
413
|
+
return ext ? ext.slice(0, 4) : "FILE";
|
|
414
|
+
}
|
|
415
|
+
function fileCardSizeText(bytes) {
|
|
416
|
+
const n = typeof bytes === "number" && Number.isFinite(bytes) && bytes >= 0 ? bytes : NaN;
|
|
417
|
+
if (Number.isNaN(n)) return "";
|
|
418
|
+
if (n < 1024) return String(Math.round(n)) + "B";
|
|
419
|
+
if (n < 1048576) return (n / 1024).toFixed(1) + "KB";
|
|
420
|
+
if (n < 1073741824) return (n / 1048576).toFixed(1) + "MB";
|
|
421
|
+
return (n / 1073741824).toFixed(1) + "GB";
|
|
422
|
+
}
|
|
423
|
+
function fileCardInfo(block) {
|
|
424
|
+
if (!block || block.type !== "file") return null;
|
|
425
|
+
const ref = block.attachment;
|
|
426
|
+
const name = ref && typeof ref === "object" && typeof ref.name === "string" && ref.name !== "" ? ref.name : "\u672A\u547D\u540D\u6587\u4EF6";
|
|
427
|
+
return { name, ext: fileExtOf(name), size: fileCardSizeText(ref && typeof ref === "object" ? ref.bytes : void 0) };
|
|
428
|
+
}
|
|
429
|
+
function pickStaleQueueItemIds(queue, rpcIds) {
|
|
430
|
+
if (!Array.isArray(queue) || !Array.isArray(rpcIds)) return [];
|
|
431
|
+
const wanted = new Set(rpcIds.filter((id) => typeof id === "string" && id !== ""));
|
|
432
|
+
if (wanted.size === 0) return [];
|
|
433
|
+
const out = [];
|
|
434
|
+
for (const row of queue) {
|
|
435
|
+
const item = row;
|
|
436
|
+
if (!item || item.placement !== "queued") continue;
|
|
437
|
+
const id = item.id;
|
|
438
|
+
if (typeof id !== "string" || id === "") continue;
|
|
439
|
+
if (typeof item.rpcId !== "string" || !wanted.has(item.rpcId)) continue;
|
|
440
|
+
out.push(id);
|
|
441
|
+
}
|
|
442
|
+
return out;
|
|
443
|
+
}
|
|
401
444
|
var KIND_INFO = {
|
|
402
445
|
modified: { label: "\u4FEE\u6539", cls: "modified" },
|
|
403
446
|
restored: { label: "\u6062\u590D", cls: "restored" },
|
|
@@ -608,6 +651,41 @@ function buildRecallNode(React, util, ctx, sessionsSvc, workspacesSvc) {
|
|
|
608
651
|
return out;
|
|
609
652
|
})();
|
|
610
653
|
}
|
|
654
|
+
function purgeStaleQueueItems(targetSessionId, rpcIds) {
|
|
655
|
+
if (!Array.isArray(rpcIds) || rpcIds.length === 0) return;
|
|
656
|
+
const deadline = Date.now() + 3e4;
|
|
657
|
+
let stopped = false;
|
|
658
|
+
const attempt = () => {
|
|
659
|
+
if (stopped) return;
|
|
660
|
+
let fired = false;
|
|
661
|
+
try {
|
|
662
|
+
const binding = sessionsSvc && typeof sessionsSvc.binding === "function" ? sessionsSvc.binding(targetSessionId) : null;
|
|
663
|
+
const face = binding && binding.session;
|
|
664
|
+
if (face && typeof face.getSnapshot === "function" && typeof face.updateQueue === "function") {
|
|
665
|
+
const snapshot = face.getSnapshot();
|
|
666
|
+
const ids = pickStaleQueueItemIds(snapshot ? snapshot.queue : null, rpcIds);
|
|
667
|
+
if (ids.length > 0) {
|
|
668
|
+
fired = true;
|
|
669
|
+
for (const itemId of ids) face.updateQueue(itemId, { kind: "remove" }).catch(() => {
|
|
670
|
+
});
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
} catch (error) {
|
|
674
|
+
}
|
|
675
|
+
if (fired) {
|
|
676
|
+
stopped = true;
|
|
677
|
+
return;
|
|
678
|
+
}
|
|
679
|
+
if (Date.now() >= deadline) {
|
|
680
|
+
stopped = true;
|
|
681
|
+
console.warn("[dsh-recall-plugin] \u6B8B\u7559\u6392\u961F\u6D88\u606F\u81EA\u52A8\u6E05\u7406\u672A\u751F\u6548\uFF0830s \u5185\u961F\u5217\u5FEB\u7167\u672A\u51FA\u73B0\u5339\u914D\u9879\uFF09\uFF1A", rpcIds);
|
|
682
|
+
showThrottledToast("\u64A4\u56DE\u524D\u7684\u4E00\u6761\u6392\u961F\u6D88\u606F\u672A\u88AB\u81EA\u52A8\u6E05\u7406\uFF0C\u53EF\u70B9\u51FB\u8BE5\u5361\u7247\u53F3\u4E0A\u89D2\u7684\u5220\u9664\u6309\u94AE\u624B\u52A8\u79FB\u9664");
|
|
683
|
+
return;
|
|
684
|
+
}
|
|
685
|
+
setTimeout(attempt, 250);
|
|
686
|
+
};
|
|
687
|
+
attempt();
|
|
688
|
+
}
|
|
611
689
|
function UserRecallNode(props) {
|
|
612
690
|
const node = props && props.node;
|
|
613
691
|
const renderMessageImages = props && props.renderMessageImages;
|
|
@@ -617,7 +695,8 @@ function buildRecallNode(React, util, ctx, sessionsSvc, workspacesSvc) {
|
|
|
617
695
|
const blocks = Array.isArray(data.content) ? data.content : [];
|
|
618
696
|
const text = blocks.filter((b) => b && b.type === "text" && typeof b.text === "string").map((b) => b.text).join("");
|
|
619
697
|
const imageBlocks = blocks.filter((b) => b && b.type === "image" && b.attachment).map((b) => ({ attachment: b.attachment }));
|
|
620
|
-
const
|
|
698
|
+
const fileBlocks = blocks.filter((b) => b && b.type === "file");
|
|
699
|
+
const rest = blocks.filter((b) => !b || !(b.type === "text" && typeof b.text === "string") && !(b.type === "image" && b.attachment) && b.type !== "file");
|
|
621
700
|
const attachmentRefs = attachmentRefsFromBlocks(blocks);
|
|
622
701
|
const [copied, setCopied] = React.useState(false);
|
|
623
702
|
const [hasSnapshot, setHasSnapshot] = React.useState(false);
|
|
@@ -741,6 +820,7 @@ function buildRecallNode(React, util, ctx, sessionsSvc, workspacesSvc) {
|
|
|
741
820
|
if (typeof sessionsSvc.open === "function") sessionsSvc.open(childId);
|
|
742
821
|
chatReverted = true;
|
|
743
822
|
fillTarget = childId;
|
|
823
|
+
purgeStaleQueueItems(childId, res.staleQueueRpcIds);
|
|
744
824
|
api("lineage-record", { childId, parentId: sessionId }).catch(() => {
|
|
745
825
|
});
|
|
746
826
|
if (pluginConfig.archiveOriginal && workspacesSvc && typeof workspacesSvc.archiveSession === "function") {
|
|
@@ -754,7 +834,10 @@ function buildRecallNode(React, util, ctx, sessionsSvc, workspacesSvc) {
|
|
|
754
834
|
chatError = String(error);
|
|
755
835
|
}
|
|
756
836
|
}
|
|
757
|
-
if (pluginConfig.refillDraft)
|
|
837
|
+
if (pluginConfig.refillDraft) {
|
|
838
|
+
fillDraft(fillTarget, text, attachmentFiles);
|
|
839
|
+
if (fileBlocks.length > 0) showThrottledToast("\u88AB\u64A4\u56DE\u6D88\u606F\u91CC\u7684\u6587\u4EF6\u9644\u4EF6\u65E0\u6CD5\u81EA\u52A8\u56DE\u586B\uFF08\u5B98\u65B9\u63A5\u53E3\u53EA\u652F\u6301\u56FE\u7247\u56DE\u8BFB\uFF09\uFF0C\u8BF7\u91CD\u65B0\u9009\u62E9\u6587\u4EF6");
|
|
840
|
+
}
|
|
758
841
|
setHasSnapshot(false);
|
|
759
842
|
setRecall({ stage: "done", count: typeof res.count === "number" ? res.count : changes.length, chatReverted, chatError });
|
|
760
843
|
}).catch((error) => {
|
|
@@ -771,6 +854,21 @@ function buildRecallNode(React, util, ctx, sessionsSvc, workspacesSvc) {
|
|
|
771
854
|
render({ images: imageBlocks, align: "end" })
|
|
772
855
|
));
|
|
773
856
|
}
|
|
857
|
+
for (let i = 0; i < fileBlocks.length; i++) {
|
|
858
|
+
const info = fileCardInfo(fileBlocks[i]);
|
|
859
|
+
if (!info) continue;
|
|
860
|
+
bubbleChildren.push(React.createElement(
|
|
861
|
+
"div",
|
|
862
|
+
{ className: "dsh-recall-filecard", key: "file-" + i },
|
|
863
|
+
React.createElement("span", { className: "dsh-recall-filecard-icon" }, info.ext),
|
|
864
|
+
React.createElement(
|
|
865
|
+
"span",
|
|
866
|
+
{ className: "dsh-recall-filecard-body" },
|
|
867
|
+
React.createElement("span", { className: "dsh-recall-filecard-name", title: info.name }, info.name),
|
|
868
|
+
React.createElement("span", { className: "dsh-recall-filecard-meta" }, info.size ? info.ext + " " + info.size : info.ext)
|
|
869
|
+
)
|
|
870
|
+
));
|
|
871
|
+
}
|
|
774
872
|
if (text !== "") bubbleChildren.push(React.createElement("div", { className: "dsh-recall-bubble", key: "text" }, text));
|
|
775
873
|
for (let i = 0; i < rest.length; i++) {
|
|
776
874
|
bubbleChildren.push(React.createElement("pre", { className: "dsh-recall-json", key: "rest-" + i }, JSON.stringify(rest[i], null, 2)));
|
package/lib/routes-core.js
CHANGED
|
@@ -79,7 +79,8 @@ function createRoutesCore(deps) {
|
|
|
79
79
|
});
|
|
80
80
|
if (!result.ok) return result;
|
|
81
81
|
const cutSeq = await snaps.resolveCutSeq(sessionId, id);
|
|
82
|
-
|
|
82
|
+
const staleQueueRpcIds = await snaps.resolveStaleQueueRpcIds(sessionId, cutSeq);
|
|
83
|
+
return { ok: true, count: result.count, cutSeq, staleQueueRpcIds };
|
|
83
84
|
},
|
|
84
85
|
// 设置页排障:最近错误(Host 侧 console.error 的页面可见副本)。
|
|
85
86
|
// M1-D3/D5:条目自带 count/kind(recordError 富集)——count 在服务端
|
package/lib/snapshots.js
CHANGED
|
@@ -71,6 +71,24 @@ function scanCutSeqDetail(events, messageId) {
|
|
|
71
71
|
function scanCutSeq(events, messageId) {
|
|
72
72
|
return scanCutSeqDetail(events, messageId).cut;
|
|
73
73
|
}
|
|
74
|
+
function scanStaleQueueRpcIds(events, cutSeq) {
|
|
75
|
+
if (!Array.isArray(events)) return [];
|
|
76
|
+
if (typeof cutSeq !== "number" || !Number.isFinite(cutSeq)) return [];
|
|
77
|
+
const out = [];
|
|
78
|
+
for (const e of events) {
|
|
79
|
+
if (!e || typeof e.seq !== "number" || e.seq <= cutSeq) continue;
|
|
80
|
+
if (e.type === "turn/start") break;
|
|
81
|
+
if (e.type !== "agent/inbox/spliced") continue;
|
|
82
|
+
const inserted = e.data && Array.isArray(e.data.inserted) ? e.data.inserted : [];
|
|
83
|
+
for (const item of inserted) {
|
|
84
|
+
const source = item && item.source;
|
|
85
|
+
if (!source || source.kind !== "user") continue;
|
|
86
|
+
const rpcId = source.rpcId;
|
|
87
|
+
if (typeof rpcId === "string" && rpcId !== "" && out.indexOf(rpcId) < 0) out.push(rpcId);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return out;
|
|
91
|
+
}
|
|
74
92
|
function disposeLease(lease) {
|
|
75
93
|
const disposeSymbol = Symbol.dispose;
|
|
76
94
|
if (!disposeSymbol || lease === null || typeof lease !== "object") return;
|
|
@@ -409,7 +427,30 @@ function createSnapshots(ctx, rt, config) {
|
|
|
409
427
|
state.cutSeqCache.set(cacheKey, result);
|
|
410
428
|
return result;
|
|
411
429
|
}
|
|
412
|
-
|
|
430
|
+
async function resolveStaleQueueRpcIds(sessionId, cutSeq) {
|
|
431
|
+
if (!sessionId || typeof cutSeq !== "number" || !Number.isFinite(cutSeq)) return [];
|
|
432
|
+
const live = sessions.get(sessionId);
|
|
433
|
+
if (live && Array.isArray(live.events)) return scanStaleQueueRpcIds(live.events, cutSeq);
|
|
434
|
+
const query = ctx.get("sessionQuery");
|
|
435
|
+
if (!query) return [];
|
|
436
|
+
try {
|
|
437
|
+
const log = await query.readSession(sessionId);
|
|
438
|
+
if (log && Array.isArray(log.events)) return scanStaleQueueRpcIds(log.events, cutSeq);
|
|
439
|
+
} catch (error) {
|
|
440
|
+
}
|
|
441
|
+
if (typeof query.observeSession !== "function") return [];
|
|
442
|
+
try {
|
|
443
|
+
const lease = await query.observeSession(sessionId);
|
|
444
|
+
try {
|
|
445
|
+
return lease && Array.isArray(lease.events) ? scanStaleQueueRpcIds(lease.events, cutSeq) : [];
|
|
446
|
+
} finally {
|
|
447
|
+
disposeLease(lease);
|
|
448
|
+
}
|
|
449
|
+
} catch (error) {
|
|
450
|
+
return [];
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
return { saveIndex, loadIndex, readExclude, writeExclude, rebuildOrphans, captureSnapshot, diffFor, rollbackFor, resolveCutSeq, resolveStaleQueueRpcIds, feedbackFor, loadLineage, recordLineage };
|
|
413
454
|
}
|
|
414
455
|
export {
|
|
415
456
|
createSnapshots,
|
|
@@ -421,5 +462,6 @@ export {
|
|
|
421
462
|
parseTreeId,
|
|
422
463
|
rescueRollback,
|
|
423
464
|
scanCutSeq,
|
|
424
|
-
scanCutSeqDetail
|
|
465
|
+
scanCutSeqDetail,
|
|
466
|
+
scanStaleQueueRpcIds
|
|
425
467
|
};
|
package/package.json
CHANGED