@michengai/dsh-archive-manager 0.1.4 → 0.1.6
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/lib/client.js +3 -3
- package/lib/workspace.js +85 -2
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -2455,8 +2455,8 @@ window.__ModuleLoader__.load({
|
|
|
2455
2455
|
}
|
|
2456
2456
|
//#endregion
|
|
2457
2457
|
//#region dsh-archive-manager: settings section
|
|
2458
|
-
const ARCHIVE_SETTINGS_CSS = ".dsham_settings{box-sizing:border-box;width:min(100%,
|
|
2459
|
-
const ARCHIVE_SETTINGS_LAYOUT_OVERRIDE = ".dsham_settings{margin:
|
|
2458
|
+
const ARCHIVE_SETTINGS_CSS = ".dsham_settings{box-sizing:border-box;width:min(100%,760px);margin:0 auto;padding:0 0 32px;color:var(--dsw-alias-label-primary)}.dsham_settingsHeader{display:flex;align-items:flex-start;justify-content:space-between;gap:16px;margin-bottom:12px}.dsham_settings h2{margin:0;font-size:20px;font-weight:650;letter-spacing:-.2px;line-height:28px}.dsham_settingsIntro{margin:4px 0 0;max-width:42em;color:var(--dsw-alias-label-tertiary);font-size:13px;line-height:1.5}.dsham_settingsDanger{display:inline-flex;align-items:center;gap:6px;min-height:32px;padding:0 12px;color:var(--dsw-alias-state-error-primary);background:transparent;border:1px solid var(--dsw-alias-state-error-primary);border-radius:8px;cursor:pointer;font:inherit;font-size:13px;font-weight:500}.dsham_settingsDanger:hover{background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 20%,transparent)}.dsham_settingsToolbar{display:flex;gap:8px;margin-bottom:16px}.dsham_settingsSearch{display:flex;align-items:center;gap:8px;min-width:0;flex:1;height:32px;padding:0 12px;color:var(--dsw-alias-label-tertiary);background:var(--dsw-alias-bg-layer-3,var(--dsw-alias-button-elevated-fill));border:1px solid var(--dsw-alias-border-l2);border-radius:8px}.dsham_settingsSearch:focus-within{border-color:var(--dsw-alias-label-tertiary)}.dsham_settingsSearch input{width:100%;min-width:0;padding:0;color:var(--dsw-alias-label-primary);background:transparent;border:0;outline:0;font:inherit;font-size:12px}.dsham_settingsSearch input::placeholder{color:var(--dsw-alias-label-tertiary)}.dsham_settingsFilter{min-width:132px;height:32px;padding:0 28px 0 11px;color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-3,var(--dsw-alias-button-elevated-fill));border:1px solid var(--dsw-alias-border-l2);border-radius:8px;cursor:pointer;font:inherit;font-size:13px}.dsham_settingsGroup{margin:0 0 20px}.dsham_settingsGroupHeading{display:flex;align-items:center;justify-content:space-between;gap:12px;margin:0 0 14px}.dsham_settingsGroupTitle{display:flex;align-items:center;gap:8px;min-width:0;margin:0;color:var(--dsw-alias-label-primary);font-size:13px;font-weight:600}.dsham_settingsGroupTitle svg{flex:none;color:var(--dsw-alias-label-secondary)}.dsham_settingsCount{flex:none;color:var(--dsw-alias-label-tertiary);font-size:12px}.dsham_settingsList{overflow:hidden;border:1px solid var(--dsw-alias-border-l2);border-radius:12px;background:var(--dsw-alias-bg-layer-2,var(--dsw-alias-button-elevated-fill))}.dsham_settingsRow{display:flex;align-items:center;gap:12px;min-height:60px;padding:10px 16px;border-bottom:1px solid var(--dsw-alias-border-l2)}.dsham_settingsRow:last-child{border-bottom:0}.dsham_settingsContent{min-width:0;flex:1}.dsham_settingsTitle{overflow:hidden;color:var(--dsw-alias-label-primary);font-size:13px;font-weight:600;line-height:18px;text-overflow:ellipsis;white-space:nowrap}.dsham_settingsMeta{margin-top:2px;color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:16px}.dsham_settingsActions{display:flex;align-items:center;gap:8px}.dsham_settingsAction{min-height:32px;padding:0 12px;color:var(--dsw-alias-label-primary);background:transparent;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;cursor:pointer;font:inherit;font-size:13px;font-weight:500}.dsham_settingsAction:hover{filter:brightness(1.12)}.dsham_settingsDelete{display:flex;align-items:center;justify-content:center;width:28px;height:28px;color:var(--dsw-alias-label-tertiary);background:transparent;border:0;border-radius:8px;cursor:pointer}.dsham_settingsDelete:hover{color:var(--dsw-alias-state-error-primary);background:var(--dsw-alias-interactive-bg-hover)}.dsham_settingsEmpty{padding:28px 8px;color:var(--dsw-alias-label-secondary);text-align:center}.dsham_settingsError{margin-top:10px;color:var(--dsw-alias-state-error-primary);font-size:12px}@media(max-width:720px){.dsham_settings{width:100%;margin:28px auto 48px;padding:0 16px}.dsham_settingsHeader{margin-bottom:28px}.dsham_settingsToolbar{flex-wrap:wrap;margin-bottom:28px}.dsham_settingsSearch{flex-basis:100%}.dsham_settingsFilter{flex:1;min-width:0}.dsham_settingsGroup{margin-bottom:32px}.dsham_settingsRow{padding:10px 12px}.dsham_settingsActions{gap:4px}}";
|
|
2459
|
+
const ARCHIVE_SETTINGS_LAYOUT_OVERRIDE = ".dsham_settings{margin:0 auto!important}@media(max-width:720px){.dsham_settings{margin:0 auto!important}}";
|
|
2460
2460
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify("dsh-archive-manager/ArchiveSettings.layout.css") + "]") === null) {
|
|
2461
2461
|
const tag = document.createElement("style");
|
|
2462
2462
|
tag.dataset.plugin = "@michengai/dsh-archive-manager";
|
|
@@ -2524,7 +2524,7 @@ window.__ModuleLoader__.load({
|
|
|
2524
2524
|
return (0, react_jsx_runtime.jsxs)("section", {
|
|
2525
2525
|
className: "dsham_settings",
|
|
2526
2526
|
"aria-label": t("archives.title"),
|
|
2527
|
-
children: [(0, react_jsx_runtime.jsx)("style", { children: ARCHIVE_SETTINGS_CSS }), (0, react_jsx_runtime.jsxs)("header", { className: "dsham_settingsHeader", children: [(0, react_jsx_runtime.jsx)("h2", { children: t("archives.title") }), (0, react_jsx_runtime.jsxs)("button", { type: "button", className: "dsham_settingsDanger", disabled: busy || archivedSessionIds.length === 0, onClick: () => setDeleteTarget({ all: true }), children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconTrashOutline16, {}), t("archives.deleteAll")] })] }), (0, react_jsx_runtime.jsxs)("div", { className: "dsham_settingsToolbar", children: [(0, react_jsx_runtime.jsxs)("label", { className: "dsham_settingsSearch", children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconSearchOutline16, {}), (0, react_jsx_runtime.jsx)("input", { type: "search", value: query, onChange: (event) => setQuery(event.target.value), placeholder: t("archives.searchPlaceholder"), "aria-label": t("archives.searchPlaceholder") })] }), (0, react_jsx_runtime.jsx)("select", { className: "dsham_settingsFilter", value: project, onChange: (event) => setProject(event.target.value), "aria-label": t("archives.projectFilter"), children: [(0, react_jsx_runtime.jsx)("option", { value: "all", children: t("archives.allProjects") }), groups.map((group) => (0, react_jsx_runtime.jsx)("option", { value: group.title, children: group.title }, group.title))] })] }), groups.length === 0 ? (0, react_jsx_runtime.jsx)("div", { className: "dsham_settingsEmpty", children: t("archives.empty") }) : filteredGroups.length === 0 ? (0, react_jsx_runtime.jsx)("div", { className: "dsham_settingsEmpty", children: t("archives.emptyFiltered") }) : filteredGroups.map((group) => (0, react_jsx_runtime.jsxs)("section", {
|
|
2527
|
+
children: [(0, react_jsx_runtime.jsx)("style", { children: ARCHIVE_SETTINGS_CSS }), (0, react_jsx_runtime.jsxs)("header", { className: "dsham_settingsHeader", children: [(0, react_jsx_runtime.jsxs)("div", { children: [(0, react_jsx_runtime.jsx)("h2", { children: t("archives.title") }), (0, react_jsx_runtime.jsx)("p", { className: "dsham_settingsIntro", children: t("archives.description") })] }), (0, react_jsx_runtime.jsxs)("button", { type: "button", className: "dsham_settingsDanger", disabled: busy || archivedSessionIds.length === 0, onClick: () => setDeleteTarget({ all: true }), children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconTrashOutline16, {}), t("archives.deleteAll")] })] }), (0, react_jsx_runtime.jsxs)("div", { className: "dsham_settingsToolbar", children: [(0, react_jsx_runtime.jsxs)("label", { className: "dsham_settingsSearch", children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconSearchOutline16, {}), (0, react_jsx_runtime.jsx)("input", { type: "search", value: query, onChange: (event) => setQuery(event.target.value), placeholder: t("archives.searchPlaceholder"), "aria-label": t("archives.searchPlaceholder") })] }), (0, react_jsx_runtime.jsx)("select", { className: "dsham_settingsFilter", value: project, onChange: (event) => setProject(event.target.value), "aria-label": t("archives.projectFilter"), children: [(0, react_jsx_runtime.jsx)("option", { value: "all", children: t("archives.allProjects") }), groups.map((group) => (0, react_jsx_runtime.jsx)("option", { value: group.title, children: group.title }, group.title))] })] }), groups.length === 0 ? (0, react_jsx_runtime.jsx)("div", { className: "dsham_settingsEmpty", children: t("archives.empty") }) : filteredGroups.length === 0 ? (0, react_jsx_runtime.jsx)("div", { className: "dsham_settingsEmpty", children: t("archives.emptyFiltered") }) : filteredGroups.map((group) => (0, react_jsx_runtime.jsxs)("section", {
|
|
2528
2528
|
className: "dsham_settingsGroup",
|
|
2529
2529
|
children: [(0, react_jsx_runtime.jsxs)("div", { className: "dsham_settingsGroupHeading", children: [(0, react_jsx_runtime.jsxs)("h3", { className: "dsham_settingsGroupTitle", children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconFolderOpenOutline16, {}), group.title] }), (0, react_jsx_runtime.jsx)("span", { className: "dsham_settingsCount", children: t("archives.sessionCount", { n: group.sessions.length }) })] }), (0, react_jsx_runtime.jsx)("div", {
|
|
2530
2530
|
className: "dsham_settingsList",
|
package/lib/workspace.js
CHANGED
|
@@ -17,7 +17,7 @@ import { sessionDir } from "@deepseek-ai/dsh-spill-local";
|
|
|
17
17
|
*
|
|
18
18
|
* 所有可失败的持久化清理都先于不可逆的物理删除。此前任一步失败时,
|
|
19
19
|
* 转录仍保留,可重试删除;物理删除失败时记录残留路径供人工排查。
|
|
20
|
-
* `unarchiveSession` 与 `deleteSession` 通过 Typert Remote
|
|
20
|
+
* `unarchiveSession` 与 `deleteSession` 通过 Typert Remote 暴露给浏览器,并注册到 typert.local,避免生产环境只靠 SRC 扫描时 404。
|
|
21
21
|
*/
|
|
22
22
|
function markRemoteMethod(instance, method) {
|
|
23
23
|
// Simulate the TS decorator pipeline `@Remote(method)` for one method:
|
|
@@ -33,17 +33,100 @@ function markRemoteMethod(instance, method) {
|
|
|
33
33
|
};
|
|
34
34
|
Remote(method)(void 0, context);
|
|
35
35
|
}
|
|
36
|
+
const sessionIdSchema = {
|
|
37
|
+
parse(value) {
|
|
38
|
+
if (typeof value !== "string" || value.length === 0) throw new TypeError(`sessionId must be a non-empty string, got ${String(value)}`);
|
|
39
|
+
return value;
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
const archivedSetSchema = {
|
|
43
|
+
parse(value) {
|
|
44
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) throw new TypeError("result must be an object");
|
|
45
|
+
const ids = value.archivedSessionIds;
|
|
46
|
+
if (!Array.isArray(ids) || ids.some((id) => typeof id !== "string")) throw new TypeError("archivedSessionIds must be a string array");
|
|
47
|
+
return value;
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
const deletedSchema = {
|
|
51
|
+
parse(value) {
|
|
52
|
+
if (typeof value !== "object" || value === null || Array.isArray(value) || value.deleted !== true) throw new TypeError("deleted must be true");
|
|
53
|
+
return value;
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* Host 严格描述符。网关优先读 typert.local,避免 SRC 扫描缓存
|
|
58
|
+
* 或协议包双份导致 /api/workspaceRegistry/deleteSession 在生产环境 404。
|
|
59
|
+
*/
|
|
60
|
+
const ARCHIVE_MANAGER_INVOCATIONS = [
|
|
61
|
+
{
|
|
62
|
+
id: "@michengai/dsh-archive-manager#workspaceRegistry/unarchiveSession",
|
|
63
|
+
service: "workspaceRegistry",
|
|
64
|
+
namespace: "workspaceRegistry",
|
|
65
|
+
method: "unarchiveSession",
|
|
66
|
+
invocation: { kind: "direct" },
|
|
67
|
+
parameters: [{
|
|
68
|
+
name: "sessionId",
|
|
69
|
+
wire: "sessionId",
|
|
70
|
+
source: "json",
|
|
71
|
+
codec: { mode: "strict", typeSymbol: "@deepseek-ai/dsh-session/types#SessionId", schema: sessionIdSchema }
|
|
72
|
+
}],
|
|
73
|
+
result: {
|
|
74
|
+
mode: "strict",
|
|
75
|
+
typeSymbol: "@michengai/dsh-archive-manager/types#ArchivedSessionIds",
|
|
76
|
+
schema: archivedSetSchema
|
|
77
|
+
},
|
|
78
|
+
sourceLocation: { file: "@michengai/dsh-archive-manager/lib/workspace.js", line: 1, column: 1 }
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
id: "@michengai/dsh-archive-manager#workspaceRegistry/deleteSession",
|
|
82
|
+
service: "workspaceRegistry",
|
|
83
|
+
namespace: "workspaceRegistry",
|
|
84
|
+
method: "deleteSession",
|
|
85
|
+
invocation: { kind: "direct" },
|
|
86
|
+
parameters: [{
|
|
87
|
+
name: "sessionId",
|
|
88
|
+
wire: "sessionId",
|
|
89
|
+
source: "json",
|
|
90
|
+
codec: { mode: "strict", typeSymbol: "@deepseek-ai/dsh-session/types#SessionId", schema: sessionIdSchema }
|
|
91
|
+
}],
|
|
92
|
+
result: {
|
|
93
|
+
mode: "strict",
|
|
94
|
+
typeSymbol: "@michengai/dsh-archive-manager/types#Deleted",
|
|
95
|
+
schema: deletedSchema
|
|
96
|
+
},
|
|
97
|
+
sourceLocation: { file: "@michengai/dsh-archive-manager/lib/workspace.js", line: 1, column: 1 }
|
|
98
|
+
}
|
|
99
|
+
];
|
|
100
|
+
const ARCHIVE_MANAGER_TYPERT = {
|
|
101
|
+
package: "@michengai/dsh-archive-manager",
|
|
102
|
+
face: "host",
|
|
103
|
+
schemas: [],
|
|
104
|
+
model: { services: [], events: [], objects: [] },
|
|
105
|
+
invocations: ARCHIVE_MANAGER_INVOCATIONS
|
|
106
|
+
};
|
|
107
|
+
function registerHostRemote(ctx) {
|
|
108
|
+
const existing = ctx.get("typert");
|
|
109
|
+
if (existing !== undefined) {
|
|
110
|
+
existing.register(ARCHIVE_MANAGER_TYPERT);
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
ctx.inject(["typert"], (typertCtx) => {
|
|
114
|
+
typertCtx.typert.register(ARCHIVE_MANAGER_TYPERT);
|
|
115
|
+
});
|
|
116
|
+
}
|
|
36
117
|
var ArchiveWorkspaceRegistry = class extends WorkspaceRegistry {
|
|
37
118
|
static inject = [
|
|
38
119
|
"storageDomain",
|
|
39
120
|
"sessionPersistence",
|
|
40
|
-
"sessionProjectionCache"
|
|
121
|
+
"sessionProjectionCache",
|
|
122
|
+
"typert"
|
|
41
123
|
];
|
|
42
124
|
constructor(ctx) {
|
|
43
125
|
super(ctx);
|
|
44
126
|
this.typertRemote = bindTypertRemote(this, this.name);
|
|
45
127
|
markRemoteMethod(this, "unarchiveSession");
|
|
46
128
|
markRemoteMethod(this, "deleteSession");
|
|
129
|
+
registerHostRemote(this.ctx);
|
|
47
130
|
}
|
|
48
131
|
/**
|
|
49
132
|
* Move one session out of the registry-global archive set, restoring its
|