mirror of
https://github.com/block/buzz.git
synced 2026-10-27 04:30:52 +00:00
fix(desktop): clean up managed agents when channel is deleted (#152)
This commit is contained in:
51
desktop/src/features/channels/cleanupChannelAgents.ts
Normal file
51
desktop/src/features/channels/cleanupChannelAgents.ts
Normal file
@@ -0,0 +1,51 @@
|
||||
/**
|
||||
* Best-effort cleanup of managed agents when a channel is deleted.
|
||||
*
|
||||
* Each agent added via the "Add agents" dialog is a unique process scoped to
|
||||
* the channel. When the channel is deleted these orphaned agents should be
|
||||
* removed — but only if they are not members of any other channel.
|
||||
*/
|
||||
import {
|
||||
deleteManagedAgent,
|
||||
getChannelMembers,
|
||||
listManagedAgents,
|
||||
listRelayAgents,
|
||||
} from "@/shared/api/tauri";
|
||||
|
||||
export async function cleanupChannelAgents(channelId: string): Promise<void> {
|
||||
const [members, managedAgents, relayAgents] = await Promise.all([
|
||||
getChannelMembers(channelId),
|
||||
listManagedAgents(),
|
||||
listRelayAgents(),
|
||||
]);
|
||||
|
||||
const memberPubkeys = new Set(
|
||||
members.map((member) => member.pubkey.toLowerCase()),
|
||||
);
|
||||
|
||||
// Find managed agents that are members of this channel.
|
||||
const agentsInChannel = managedAgents.filter((agent) =>
|
||||
memberPubkeys.has(agent.pubkey.toLowerCase()),
|
||||
);
|
||||
|
||||
// Only delete agents that are NOT members of any other channel.
|
||||
const agentsToDelete = agentsInChannel.filter((agent) => {
|
||||
const relayAgent = relayAgents.find(
|
||||
(ra) => ra.pubkey.toLowerCase() === agent.pubkey.toLowerCase(),
|
||||
);
|
||||
if (!relayAgent) {
|
||||
// Not found in relay — safe to delete.
|
||||
return true;
|
||||
}
|
||||
// Only delete if this is the agent's only channel.
|
||||
const otherChannels = relayAgent.channelIds.filter(
|
||||
(id) => id !== channelId,
|
||||
);
|
||||
return otherChannels.length === 0;
|
||||
});
|
||||
|
||||
// Delete orphaned agents (best-effort — don't block channel deletion).
|
||||
await Promise.allSettled(
|
||||
agentsToDelete.map((agent) => deleteManagedAgent(agent.pubkey)),
|
||||
);
|
||||
}
|
||||
@@ -25,6 +25,7 @@ import {
|
||||
unarchiveChannel,
|
||||
updateChannel,
|
||||
} from "@/shared/api/tauri";
|
||||
import { cleanupChannelAgents } from "@/features/channels/cleanupChannelAgents";
|
||||
import type {
|
||||
AddChannelMembersInput,
|
||||
Channel,
|
||||
@@ -343,6 +344,13 @@ export function useDeleteChannelMutation(channelId: string | null) {
|
||||
throw new Error("No channel selected.");
|
||||
}
|
||||
|
||||
// Best-effort cleanup of managed agents scoped to this channel.
|
||||
try {
|
||||
await cleanupChannelAgents(channelId);
|
||||
} catch (error) {
|
||||
console.warn("Failed to clean up managed agents:", error);
|
||||
}
|
||||
|
||||
await deleteChannel(channelId);
|
||||
},
|
||||
onSuccess: () => {
|
||||
@@ -361,7 +369,11 @@ export function useDeleteChannelMutation(channelId: string | null) {
|
||||
});
|
||||
},
|
||||
onSettled: async () => {
|
||||
await queryClient.invalidateQueries({ queryKey: channelsQueryKey });
|
||||
await Promise.all([
|
||||
queryClient.invalidateQueries({ queryKey: channelsQueryKey }),
|
||||
queryClient.invalidateQueries({ queryKey: ["managed-agents"] }),
|
||||
queryClient.invalidateQueries({ queryKey: ["relay-agents"] }),
|
||||
]);
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -478,7 +490,6 @@ export function useSelectedChannel(
|
||||
}
|
||||
|
||||
// ── Canvas ────────────────────────────────────────────────────────────────────
|
||||
|
||||
export function useCanvasQuery(channelId: string | null, enabled = true) {
|
||||
return useQuery({
|
||||
queryKey: ["channel-canvas", channelId],
|
||||
|
||||
Reference in New Issue
Block a user