Files
paseo/packages/app/src/contexts/session-workspace-upserts.ts
T
Mohamed BoudraandGitHub 03dcda7c41 Archive any workspace from the app (#2003)
* feat(app): expose archive for every workspace

Workspace actions now archive one workspace by id. The daemon remains responsible for backing-specific cleanup, including removing a managed worktree only after its final workspace is archived.

* refactor(app): clarify archive descriptor name

* fix(app): preserve workspace archive safety

* fix(app): allow archive without upstream

* refactor(app): remove stale archive callback

* test(app): cover workspace archive ownership
2026-07-11 18:22:31 +02:00

78 lines
2.2 KiB
TypeScript

import type { WorkspaceDescriptor } from "@/stores/session-store";
import { normalizeWorkspaceOpaqueId } from "@/utils/workspace-identity";
interface PendingWorkspaceArchive {
workspaceId: string;
}
const pendingWorkspaceArchivesByServer = new Map<string, Map<string, PendingWorkspaceArchive>>();
function pendingArchiveKey(input: { serverId: string; workspaceId: string }): string {
return `${input.serverId.trim()}::${input.workspaceId.trim()}`;
}
export function markWorkspaceArchivePending(input: {
serverId: string;
workspaceId: string;
}): void {
const serverId = input.serverId.trim();
const workspaceId = normalizeWorkspaceOpaqueId(input.workspaceId);
if (!serverId || !workspaceId) {
return;
}
const archives = pendingWorkspaceArchivesByServer.get(serverId) ?? new Map();
archives.set(pendingArchiveKey({ serverId, workspaceId }), {
workspaceId,
});
pendingWorkspaceArchivesByServer.set(serverId, archives);
}
export function clearWorkspaceArchivePending(input: {
serverId: string;
workspaceId: string;
}): void {
const serverId = input.serverId.trim();
const workspaceId = normalizeWorkspaceOpaqueId(input.workspaceId);
if (!serverId || !workspaceId) {
return;
}
const archives = pendingWorkspaceArchivesByServer.get(serverId);
if (!archives) {
return;
}
archives.delete(pendingArchiveKey({ serverId, workspaceId }));
if (archives.size === 0) {
pendingWorkspaceArchivesByServer.delete(serverId);
}
}
export function isWorkspaceArchivePending(input: {
serverId: string;
workspaceId?: string | null;
}): boolean {
const serverId = input.serverId.trim();
if (!serverId) {
return false;
}
const archives = pendingWorkspaceArchivesByServer.get(serverId);
if (!archives) {
return false;
}
const workspaceId = normalizeWorkspaceOpaqueId(input.workspaceId);
return Boolean(workspaceId && archives.has(pendingArchiveKey({ serverId, workspaceId })));
}
export function shouldSuppressWorkspaceForLocalArchive(input: {
serverId: string;
workspace: WorkspaceDescriptor;
}): boolean {
return isWorkspaceArchivePending({
serverId: input.serverId,
workspaceId: input.workspace.id,
});
}