@michengai/dsh-archive-manager 1.0.11 → 1.0.13
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 +15 -0
- package/CHANGELOG.zh-CN.md +15 -0
- package/README.md +2 -2
- package/README.zh-CN.md +2 -2
- package/assets/branding/banner.txt +1 -1
- package/cordis.patch.yml +6 -14
- package/lib/client.js +57 -57
- package/lib/host-install.js +41 -0
- package/lib/index.js +28 -7
- package/lib/plugin-updater.js +34 -1
- package/lib/projcache.js +101 -5
- package/lib/workspace.js +136 -24
- package/locale/en.json +6 -0
- package/locale/zh.json +6 -0
- package/package.json +6 -3
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { bindArchiveManagerRemote, installArchiveWorkspace, tolerateStaleFileUploadResolver } from "./workspace.js";
|
|
2
|
+
import { installArchiveProjectionCache, installArchiveProjectionCacheGuards } from "./projcache.js";
|
|
3
|
+
const inject = ["workspaceRegistry", "sessionProjectionCache", "typert"];
|
|
4
|
+
async function apply(ctx) {
|
|
5
|
+
tolerateStaleFileUploadResolver(ctx);
|
|
6
|
+
const registry = ctx.workspaceRegistry;
|
|
7
|
+
const cache = ctx.sessionProjectionCache;
|
|
8
|
+
const uninstallWorkspace = installArchiveWorkspace(registry);
|
|
9
|
+
let uninstallCache = async () => {
|
|
10
|
+
};
|
|
11
|
+
let unbindRemote = () => {
|
|
12
|
+
};
|
|
13
|
+
const dispose = async () => {
|
|
14
|
+
try {
|
|
15
|
+
unbindRemote();
|
|
16
|
+
} finally {
|
|
17
|
+
try {
|
|
18
|
+
await uninstallCache();
|
|
19
|
+
} finally {
|
|
20
|
+
uninstallWorkspace();
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
try {
|
|
25
|
+
try {
|
|
26
|
+
uninstallCache = await installArchiveProjectionCache(cache);
|
|
27
|
+
} catch (error) {
|
|
28
|
+
ctx.logger?.warn?.(`archive-manager: projection cache overlay skipped: ${String(error)}`);
|
|
29
|
+
uninstallCache = installArchiveProjectionCacheGuards(cache);
|
|
30
|
+
}
|
|
31
|
+
unbindRemote = bindArchiveManagerRemote(ctx);
|
|
32
|
+
} catch (error) {
|
|
33
|
+
await dispose();
|
|
34
|
+
throw error;
|
|
35
|
+
}
|
|
36
|
+
return dispose;
|
|
37
|
+
}
|
|
38
|
+
export {
|
|
39
|
+
apply,
|
|
40
|
+
inject
|
|
41
|
+
};
|
package/lib/index.js
CHANGED
|
@@ -1,11 +1,32 @@
|
|
|
1
1
|
import { registerPluginUpdater } from "./plugin-updater.js";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
2
|
+
import { apply as installHost, inject as hostInject } from "./host-install.js";
|
|
3
|
+
const inject = ["webServer", ...hostInject];
|
|
4
|
+
async function apply(ctx) {
|
|
5
|
+
let disposeUpdater = () => {
|
|
6
|
+
};
|
|
7
|
+
try {
|
|
8
|
+
disposeUpdater = registerPluginUpdater(ctx, {
|
|
9
|
+
endpoint: "/api/michengai/dsh-archive-manager/update",
|
|
10
|
+
packageName: "@michengai/dsh-archive-manager",
|
|
11
|
+
manifestUrl: new URL("../package.json", import.meta.url)
|
|
12
|
+
});
|
|
13
|
+
} catch (error) {
|
|
14
|
+
ctx.logger?.warn?.(`archive-manager: update route skipped: ${String(error)}`);
|
|
15
|
+
}
|
|
16
|
+
let disposeHost;
|
|
17
|
+
try {
|
|
18
|
+
disposeHost = await installHost(ctx);
|
|
19
|
+
} catch (error) {
|
|
20
|
+
disposeUpdater();
|
|
21
|
+
throw error;
|
|
22
|
+
}
|
|
23
|
+
return async () => {
|
|
24
|
+
try {
|
|
25
|
+
disposeUpdater();
|
|
26
|
+
} finally {
|
|
27
|
+
await disposeHost();
|
|
28
|
+
}
|
|
29
|
+
};
|
|
9
30
|
}
|
|
10
31
|
export {
|
|
11
32
|
apply,
|
package/lib/plugin-updater.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { symbols } from "@deepseek-ai/cordis";
|
|
1
2
|
import { record } from "./contracts.js";
|
|
2
3
|
import { spawn } from "node:child_process";
|
|
3
4
|
import { existsSync, readFileSync } from "node:fs";
|
|
@@ -194,10 +195,34 @@ function publicError(error) {
|
|
|
194
195
|
const message = error instanceof Error ? error.message : "\u66F4\u65B0\u6682\u4E0D\u53EF\u7528\u3002";
|
|
195
196
|
return /[A-Za-z]:[\\/]|\/(?:home|root|Users|var|tmp)\//.test(message) ? "\u66F4\u65B0\u5931\u8D25\uFF0C\u8BF7\u67E5\u770B\u670D\u52A1\u7AEF\u65E5\u5FD7\u3002" : message;
|
|
196
197
|
}
|
|
198
|
+
const updateRoutes = Symbol.for("dsh-archive-manager.update-routes");
|
|
199
|
+
function updateRouteBag(server) {
|
|
200
|
+
const owner = server;
|
|
201
|
+
return owner[updateRoutes] ?? (owner[updateRoutes] = /* @__PURE__ */ new Map());
|
|
202
|
+
}
|
|
203
|
+
function rawService(service) {
|
|
204
|
+
const original = Reflect.get(service, symbols.original);
|
|
205
|
+
return original !== null && typeof original === "object" ? original : service;
|
|
206
|
+
}
|
|
207
|
+
function releaseUpdateRoute(server, path) {
|
|
208
|
+
const raw = rawService(server);
|
|
209
|
+
const bag = updateRouteBag(raw);
|
|
210
|
+
const owned = bag.get(path);
|
|
211
|
+
if (owned !== void 0) {
|
|
212
|
+
bag.delete(path);
|
|
213
|
+
owned();
|
|
214
|
+
}
|
|
215
|
+
for (const key of ["exact", "prefixes"]) {
|
|
216
|
+
const table = Reflect.get(raw, key);
|
|
217
|
+
if (table instanceof Map && table.has(path)) table.delete(path);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
197
220
|
function registerPluginUpdater(ctx, options) {
|
|
198
221
|
const host = ctx;
|
|
199
222
|
let installing = false;
|
|
200
|
-
|
|
223
|
+
const server = rawService(host.webServer);
|
|
224
|
+
releaseUpdateRoute(server, options.endpoint);
|
|
225
|
+
const dispose = host.webServer.register({
|
|
201
226
|
kind: "exact",
|
|
202
227
|
path: options.endpoint,
|
|
203
228
|
handler: async (request, response) => {
|
|
@@ -249,6 +274,14 @@ function registerPluginUpdater(ctx, options) {
|
|
|
249
274
|
}
|
|
250
275
|
}
|
|
251
276
|
});
|
|
277
|
+
const wrapped = () => {
|
|
278
|
+
const bag = updateRouteBag(server);
|
|
279
|
+
if (bag.get(options.endpoint) !== wrapped) return;
|
|
280
|
+
bag.delete(options.endpoint);
|
|
281
|
+
dispose();
|
|
282
|
+
};
|
|
283
|
+
updateRouteBag(server).set(options.endpoint, wrapped);
|
|
284
|
+
return wrapped;
|
|
252
285
|
}
|
|
253
286
|
export {
|
|
254
287
|
PLUGIN_UPDATE_HEADER,
|
package/lib/projcache.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const CacheBase = SessionProjectionCache;
|
|
2
2
|
import { createHash } from "node:crypto";
|
|
3
|
-
import { Service } from "@deepseek-ai/cordis";
|
|
3
|
+
import { Service, symbols } from "@deepseek-ai/cordis";
|
|
4
4
|
import {
|
|
5
5
|
SessionProjectionCache,
|
|
6
6
|
checkpointIdentity,
|
|
@@ -169,16 +169,16 @@ async function importMissingRecords(ctx, target, records, label) {
|
|
|
169
169
|
}
|
|
170
170
|
return imported;
|
|
171
171
|
}
|
|
172
|
-
async function importPreviousProjectionCache(ctx, target) {
|
|
172
|
+
async function importPreviousProjectionCache(ctx, target, currentTable) {
|
|
173
|
+
const sameSpec = projectionCacheDomainSpec.version === legacyProjectionCacheDomainSpec.version && projectionCacheDomainSpec.layout === legacyProjectionCacheDomainSpec.layout;
|
|
173
174
|
const legacySafeV2 = await readLegacySafeRecords(ctx, legacySafeV2ProjectionCacheDomainSpec, "archive-manager v2");
|
|
174
175
|
const legacySafe = await readLegacySafeRecords(ctx, legacySafeProjectionCacheDomainSpec, "archive-manager v1");
|
|
175
|
-
const legacy = await readSourceRecords(ctx, legacyProjectionCacheDomainSpec, "legacy v3");
|
|
176
|
-
const sameSpec = projectionCacheDomainSpec.version === legacyProjectionCacheDomainSpec.version && projectionCacheDomainSpec.layout === legacyProjectionCacheDomainSpec.layout;
|
|
176
|
+
const legacy = sameSpec && currentTable !== void 0 ? { opened: true, records: [...currentTable.entries()] } : await readSourceRecords(ctx, legacyProjectionCacheDomainSpec, "legacy v3");
|
|
177
177
|
let imported = 0;
|
|
178
178
|
if (legacySafeV2.opened) imported += await importMissingRecords(ctx, target, legacySafeV2.records, "archive-manager v2");
|
|
179
179
|
if (legacySafe.opened) imported += await importMissingRecords(ctx, target, legacySafe.records, "archive-manager v1");
|
|
180
180
|
if (!sameSpec) {
|
|
181
|
-
const current = await readSourceRecords(ctx, projectionCacheDomainSpec, "current");
|
|
181
|
+
const current = currentTable !== void 0 ? { opened: true, records: [...currentTable.entries()] } : await readSourceRecords(ctx, projectionCacheDomainSpec, "current");
|
|
182
182
|
if (current.opened) imported += await importMissingRecords(ctx, target, current.records, "current");
|
|
183
183
|
}
|
|
184
184
|
if (legacy.opened) imported += await importMissingRecords(ctx, target, legacy.records, "legacy v3");
|
|
@@ -269,11 +269,107 @@ var ArchiveProjectionCache = class extends CacheBase {
|
|
|
269
269
|
if (idx !== -1) this.deletedSessionOrder.splice(idx, 1);
|
|
270
270
|
}
|
|
271
271
|
};
|
|
272
|
+
const projectionGuards = /* @__PURE__ */ new WeakMap();
|
|
273
|
+
function installArchiveProjectionCacheGuards(cache, table) {
|
|
274
|
+
const target = Reflect.get(cache, symbols.original) ?? cache;
|
|
275
|
+
const existing = projectionGuards.get(target);
|
|
276
|
+
if (existing) return existing;
|
|
277
|
+
const fields = {
|
|
278
|
+
table: table ?? target.table,
|
|
279
|
+
deletedSessionIds: /* @__PURE__ */ new Set(),
|
|
280
|
+
deletedSessionOrder: [],
|
|
281
|
+
deletedSessionTombstoneLimit: 4096,
|
|
282
|
+
writeTail: Promise.resolve()
|
|
283
|
+
};
|
|
284
|
+
const receiver = Object.create(target, Object.fromEntries(Object.entries(fields).map(([name, value]) => [name, { value, writable: true, configurable: true }])));
|
|
285
|
+
const restoredMethods = [];
|
|
286
|
+
let active = true;
|
|
287
|
+
const restore = () => {
|
|
288
|
+
active = false;
|
|
289
|
+
for (const item of [...restoredMethods].reverse()) {
|
|
290
|
+
if (item.descriptor) Object.defineProperty(target, item.name, item.descriptor);
|
|
291
|
+
else delete target[item.name];
|
|
292
|
+
}
|
|
293
|
+
};
|
|
294
|
+
try {
|
|
295
|
+
for (const name of Object.getOwnPropertyNames(ArchiveProjectionCache.prototype)) {
|
|
296
|
+
if (name === "constructor") continue;
|
|
297
|
+
const method = Reflect.get(ArchiveProjectionCache.prototype, name);
|
|
298
|
+
if (typeof method !== "function") continue;
|
|
299
|
+
Object.defineProperty(receiver, name, { value: method, writable: true, configurable: true });
|
|
300
|
+
const previous = target[name];
|
|
301
|
+
restoredMethods.push({ name, descriptor: Object.getOwnPropertyDescriptor(target, name) });
|
|
302
|
+
target[name] = (...args) => {
|
|
303
|
+
if (!active) {
|
|
304
|
+
if (typeof previous === "function") return Reflect.apply(previous, target, args);
|
|
305
|
+
throw new Error("archive-manager: projection cache guards are stopped");
|
|
306
|
+
}
|
|
307
|
+
const result = Reflect.apply(method, receiver, args);
|
|
308
|
+
if (name === "delete") receiver.writeTail = Promise.allSettled([receiver.writeTail, result]).then(() => void 0);
|
|
309
|
+
return result;
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
} catch (error) {
|
|
313
|
+
restore();
|
|
314
|
+
throw error;
|
|
315
|
+
}
|
|
316
|
+
let disposal;
|
|
317
|
+
const uninstall = () => {
|
|
318
|
+
if (disposal) return disposal;
|
|
319
|
+
const drain = receiver.writeTail;
|
|
320
|
+
restore();
|
|
321
|
+
projectionGuards.delete(target);
|
|
322
|
+
return disposal = drain;
|
|
323
|
+
};
|
|
324
|
+
projectionGuards.set(target, uninstall);
|
|
325
|
+
return uninstall;
|
|
326
|
+
}
|
|
327
|
+
const projectionOverlay = Symbol.for("dsh-archive-manager.projcache-overlay");
|
|
328
|
+
async function installArchiveProjectionCache(cache) {
|
|
329
|
+
const target = cache;
|
|
330
|
+
if (target[projectionOverlay] === true) return async () => {
|
|
331
|
+
};
|
|
332
|
+
const domain = await target.ctx.storageDomain.open(safeProjectionCacheDomainSpec);
|
|
333
|
+
let installed = false;
|
|
334
|
+
const previousTable = target.table;
|
|
335
|
+
let uninstallGuards;
|
|
336
|
+
try {
|
|
337
|
+
const table = new SafeSessionTable(domain.table("sessions"));
|
|
338
|
+
await importPreviousProjectionCache(target.ctx, table, previousTable);
|
|
339
|
+
uninstallGuards = installArchiveProjectionCacheGuards(cache, table);
|
|
340
|
+
target.table = table;
|
|
341
|
+
target[projectionOverlay] = true;
|
|
342
|
+
installed = true;
|
|
343
|
+
let disposal;
|
|
344
|
+
return () => disposal ??= (async () => {
|
|
345
|
+
if (target[projectionOverlay] !== true) return;
|
|
346
|
+
const drain = uninstallGuards();
|
|
347
|
+
target.table = previousTable;
|
|
348
|
+
delete target[projectionOverlay];
|
|
349
|
+
await drain;
|
|
350
|
+
await domain.close();
|
|
351
|
+
})();
|
|
352
|
+
} catch (error) {
|
|
353
|
+
if (!installed) {
|
|
354
|
+
const drain = uninstallGuards?.();
|
|
355
|
+
target.table = previousTable;
|
|
356
|
+
delete target[projectionOverlay];
|
|
357
|
+
try {
|
|
358
|
+
await drain;
|
|
359
|
+
} finally {
|
|
360
|
+
await domain.close();
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
throw error;
|
|
364
|
+
}
|
|
365
|
+
}
|
|
272
366
|
export {
|
|
273
367
|
ArchiveProjectionCache,
|
|
274
368
|
SafeSessionTable,
|
|
275
369
|
ArchiveProjectionCache as default,
|
|
276
370
|
importPreviousProjectionCache,
|
|
371
|
+
installArchiveProjectionCache,
|
|
372
|
+
installArchiveProjectionCacheGuards,
|
|
277
373
|
legacyProjectionCacheDomainSpec,
|
|
278
374
|
legacySafeProjectionCacheDomainSpec,
|
|
279
375
|
legacySafeV2ProjectionCacheDomainSpec,
|
package/lib/workspace.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { symbols } from "@deepseek-ai/cordis";
|
|
1
2
|
import { record, errorMessage, errorCode } from "./contracts.js";
|
|
2
3
|
import * as SessionRuntime from "@deepseek-ai/dsh-session";
|
|
3
4
|
import { childCatalogFact, prepareAutomationRepair } from "./session-repair.js";
|
|
@@ -51,6 +52,20 @@ function strictCodec(typeSymbol, schema) {
|
|
|
51
52
|
schema
|
|
52
53
|
};
|
|
53
54
|
}
|
|
55
|
+
const ARCHIVE_REMOTE_METHODS = [
|
|
56
|
+
"unarchiveSession",
|
|
57
|
+
"deleteSession",
|
|
58
|
+
"deleteArchivedSessions",
|
|
59
|
+
"archivedSessionMetadata",
|
|
60
|
+
"favoriteSessions",
|
|
61
|
+
"setSessionFavorite",
|
|
62
|
+
"searchArchivedContent",
|
|
63
|
+
"searchSessionContent",
|
|
64
|
+
"previewArchivedSession",
|
|
65
|
+
"sessionDetails",
|
|
66
|
+
"diagnoseSession",
|
|
67
|
+
"repairSession"
|
|
68
|
+
];
|
|
54
69
|
function markRemoteMethod(instance, method) {
|
|
55
70
|
const context = {
|
|
56
71
|
private: false,
|
|
@@ -244,6 +259,24 @@ function registerHostRemote(ctx) {
|
|
|
244
259
|
typertCtx.typert.register(ARCHIVE_MANAGER_TYPERT);
|
|
245
260
|
});
|
|
246
261
|
}
|
|
262
|
+
function bindArchiveManagerRemote(ctx) {
|
|
263
|
+
const typert = ctx.get("typert");
|
|
264
|
+
if (typert === void 0 || typeof typert.register !== "function") {
|
|
265
|
+
throw new Error("archive-manager: typert is unavailable");
|
|
266
|
+
}
|
|
267
|
+
try {
|
|
268
|
+
const dispose = typert.register(ARCHIVE_MANAGER_TYPERT);
|
|
269
|
+
return typeof dispose === "function" ? () => {
|
|
270
|
+
dispose();
|
|
271
|
+
} : () => {
|
|
272
|
+
};
|
|
273
|
+
} catch (error) {
|
|
274
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
275
|
+
if (!message.includes("already registered")) throw error;
|
|
276
|
+
return () => {
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
}
|
|
247
280
|
async function hostRepairFormat(format, children = []) {
|
|
248
281
|
if (!format || !Number.isInteger(format.currentVersion) || format.currentVersion < 3) throw new Error("\u5F53\u524D\u5BBF\u4E3B\u4E0D\u652F\u6301\u6B64\u4FEE\u590D\uFF0C\u8BF7\u5347\u7EA7 DSH \u540E\u91CD\u8BD5");
|
|
249
282
|
if (typeof format.createRestore === "function") return format;
|
|
@@ -311,30 +344,9 @@ var ArchiveWorkspaceRegistry = class extends WorkspaceRegistry {
|
|
|
311
344
|
constructor(ctx) {
|
|
312
345
|
super(ctx);
|
|
313
346
|
tolerateStaleFileUploadResolver(ctx);
|
|
314
|
-
|
|
315
|
-
this.host.sessionPath = (id) => {
|
|
316
|
-
const path = indexedPath(id);
|
|
317
|
-
if (path !== void 0) return path;
|
|
318
|
-
if (this.invalidSessionPaths.has(id)) return void 0;
|
|
319
|
-
try {
|
|
320
|
-
return this.archivedWorkspacePath(id);
|
|
321
|
-
} catch {
|
|
322
|
-
return void 0;
|
|
323
|
-
}
|
|
324
|
-
};
|
|
347
|
+
protectArchivedSessionPath(this);
|
|
325
348
|
this.typertRemote = bindTypertRemote(this, this.name);
|
|
326
|
-
markRemoteMethod(this,
|
|
327
|
-
markRemoteMethod(this, "deleteSession");
|
|
328
|
-
markRemoteMethod(this, "deleteArchivedSessions");
|
|
329
|
-
markRemoteMethod(this, "archivedSessionMetadata");
|
|
330
|
-
markRemoteMethod(this, "favoriteSessions");
|
|
331
|
-
markRemoteMethod(this, "setSessionFavorite");
|
|
332
|
-
markRemoteMethod(this, "searchArchivedContent");
|
|
333
|
-
markRemoteMethod(this, "searchSessionContent");
|
|
334
|
-
markRemoteMethod(this, "previewArchivedSession");
|
|
335
|
-
markRemoteMethod(this, "sessionDetails");
|
|
336
|
-
markRemoteMethod(this, "diagnoseSession");
|
|
337
|
-
markRemoteMethod(this, "repairSession");
|
|
349
|
+
for (const method of ARCHIVE_REMOTE_METHODS) markRemoteMethod(this, method);
|
|
338
350
|
registerHostRemote(this.ctx);
|
|
339
351
|
}
|
|
340
352
|
/** 只读取归档日志;已有实时实例读取快照,不调用 prepare、enter 或恢复接口。 */
|
|
@@ -1204,7 +1216,107 @@ var ArchiveWorkspaceRegistry = class extends WorkspaceRegistry {
|
|
|
1204
1216
|
}
|
|
1205
1217
|
}
|
|
1206
1218
|
};
|
|
1219
|
+
const workspaceOverlay = Symbol.for("dsh-archive-manager.workspace-overlay");
|
|
1220
|
+
function protectArchivedSessionPath(registry) {
|
|
1221
|
+
const indexedPath = registry.host.sessionPath;
|
|
1222
|
+
registry.host.sessionPath = (id) => {
|
|
1223
|
+
const path = indexedPath(id);
|
|
1224
|
+
if (path !== void 0) return path;
|
|
1225
|
+
if (registry.invalidSessionPaths.has(id)) return void 0;
|
|
1226
|
+
try {
|
|
1227
|
+
return registry.archivedWorkspacePath(id);
|
|
1228
|
+
} catch {
|
|
1229
|
+
return void 0;
|
|
1230
|
+
}
|
|
1231
|
+
};
|
|
1232
|
+
return () => {
|
|
1233
|
+
registry.host.sessionPath = indexedPath;
|
|
1234
|
+
};
|
|
1235
|
+
}
|
|
1236
|
+
const remoteMethodDescriptor = "@deepseek-ai/dsh-typert-protocol/remote-methods";
|
|
1237
|
+
function markOverlayMethods(registry, methods) {
|
|
1238
|
+
const raw = Reflect.get(registry, symbols.original) ?? registry;
|
|
1239
|
+
const prototype = Object.getPrototypeOf(raw);
|
|
1240
|
+
if (prototype === null) return () => {
|
|
1241
|
+
};
|
|
1242
|
+
const before = Object.getOwnPropertyDescriptor(prototype, remoteMethodDescriptor);
|
|
1243
|
+
const marked = /* @__PURE__ */ new Set();
|
|
1244
|
+
for (const marker of Reflect.get(before?.value ?? {}, "methods") ?? []) {
|
|
1245
|
+
if (typeof marker.method === "string") marked.add(marker.method);
|
|
1246
|
+
}
|
|
1247
|
+
for (const method of methods) {
|
|
1248
|
+
if (marked.has(method)) continue;
|
|
1249
|
+
markRemoteMethod(raw, method);
|
|
1250
|
+
}
|
|
1251
|
+
return () => {
|
|
1252
|
+
if (before === void 0) delete prototype[remoteMethodDescriptor];
|
|
1253
|
+
else Object.defineProperty(prototype, remoteMethodDescriptor, before);
|
|
1254
|
+
};
|
|
1255
|
+
}
|
|
1256
|
+
function bindOverlayRemote(registry) {
|
|
1257
|
+
const raw = Reflect.get(registry, symbols.original) ?? registry;
|
|
1258
|
+
if (Reflect.get(raw, "typertRemote") !== void 0) return () => {
|
|
1259
|
+
};
|
|
1260
|
+
const name = Reflect.get(raw, "name");
|
|
1261
|
+
const serviceKey = typeof name === "string" ? name : "workspaceRegistry";
|
|
1262
|
+
Reflect.set(raw, "typertRemote", bindTypertRemote(raw, serviceKey));
|
|
1263
|
+
return () => {
|
|
1264
|
+
Reflect.deleteProperty(raw, "typertRemote");
|
|
1265
|
+
};
|
|
1266
|
+
}
|
|
1267
|
+
function installArchiveWorkspace(registry) {
|
|
1268
|
+
const overlay = registry;
|
|
1269
|
+
if (overlay[workspaceOverlay] === true) return () => {
|
|
1270
|
+
};
|
|
1271
|
+
if (registry instanceof ArchiveWorkspaceRegistry) return () => {
|
|
1272
|
+
};
|
|
1273
|
+
const target = overlay;
|
|
1274
|
+
const fields = {
|
|
1275
|
+
deletedSessionIds: /* @__PURE__ */ new Set(),
|
|
1276
|
+
deletedSessionOrder: [],
|
|
1277
|
+
deletedSessionTombstoneLimit: 4096,
|
|
1278
|
+
deletedIdentities: /* @__PURE__ */ new Map(),
|
|
1279
|
+
archivedSessionPathIndex: /* @__PURE__ */ new Map(),
|
|
1280
|
+
archivedSessionPathIndexKey: void 0
|
|
1281
|
+
};
|
|
1282
|
+
const addedFields = [];
|
|
1283
|
+
for (const [key, value] of Object.entries(fields)) {
|
|
1284
|
+
if (!Object.hasOwn(target, key)) {
|
|
1285
|
+
target[key] = value;
|
|
1286
|
+
addedFields.push(key);
|
|
1287
|
+
}
|
|
1288
|
+
}
|
|
1289
|
+
const restorePath = protectArchivedSessionPath(overlay);
|
|
1290
|
+
const restoreRemote = bindOverlayRemote(registry);
|
|
1291
|
+
const restoredMethods = [];
|
|
1292
|
+
const copiedMethods = [];
|
|
1293
|
+
for (const name of Object.getOwnPropertyNames(ArchiveWorkspaceRegistry.prototype)) {
|
|
1294
|
+
if (name === "constructor") continue;
|
|
1295
|
+
const method = Reflect.get(ArchiveWorkspaceRegistry.prototype, name);
|
|
1296
|
+
if (typeof method !== "function") continue;
|
|
1297
|
+
restoredMethods.push({ name, hadOwn: Object.hasOwn(target, name), previous: target[name] });
|
|
1298
|
+
target[name] = method;
|
|
1299
|
+
copiedMethods.push(name);
|
|
1300
|
+
}
|
|
1301
|
+
const restoreMarkers = markOverlayMethods(registry, ARCHIVE_REMOTE_METHODS.filter((method) => copiedMethods.includes(method)));
|
|
1302
|
+
target[workspaceOverlay] = true;
|
|
1303
|
+
return () => {
|
|
1304
|
+
if (target[workspaceOverlay] !== true) return;
|
|
1305
|
+
restorePath();
|
|
1306
|
+
restoreMarkers();
|
|
1307
|
+
restoreRemote();
|
|
1308
|
+
for (const item of restoredMethods.reverse()) {
|
|
1309
|
+
if (item.hadOwn) target[item.name] = item.previous;
|
|
1310
|
+
else delete target[item.name];
|
|
1311
|
+
}
|
|
1312
|
+
for (const key of addedFields) delete target[key];
|
|
1313
|
+
delete target[workspaceOverlay];
|
|
1314
|
+
};
|
|
1315
|
+
}
|
|
1207
1316
|
export {
|
|
1208
1317
|
ArchiveWorkspaceRegistry,
|
|
1209
|
-
|
|
1318
|
+
bindArchiveManagerRemote,
|
|
1319
|
+
ArchiveWorkspaceRegistry as default,
|
|
1320
|
+
installArchiveWorkspace,
|
|
1321
|
+
tolerateStaleFileUploadResolver
|
|
1210
1322
|
};
|
package/locale/en.json
ADDED
package/locale/zh.json
ADDED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@michengai/dsh-archive-manager",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "1.0.13",
|
|
4
|
+
"description": "归档、恢复、收藏和永久删除会话,并诊断损坏的会话日志。 · Archive, restore, favorite, and permanently delete sessions, and diagnose damaged session logs.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"packageManager": "pnpm@11.22.0",
|
|
7
7
|
"engines": {
|
|
@@ -12,12 +12,15 @@
|
|
|
12
12
|
".": "./lib/index.js",
|
|
13
13
|
"./workspace": "./lib/workspace.js",
|
|
14
14
|
"./projcache": "./lib/projcache.js",
|
|
15
|
+
"./host": "./lib/host-install.js",
|
|
15
16
|
"./client": "./lib/client.js",
|
|
16
|
-
"./package.json": "./package.json"
|
|
17
|
+
"./package.json": "./package.json",
|
|
18
|
+
"./locale/*.json": "./locale/*.json"
|
|
17
19
|
},
|
|
18
20
|
"files": [
|
|
19
21
|
"lib",
|
|
20
22
|
"assets",
|
|
23
|
+
"locale",
|
|
21
24
|
"cordis.patch.yml",
|
|
22
25
|
"README.md",
|
|
23
26
|
"README.zh-CN.md",
|