feat(federation): prune dmAlternatives on removeInstanceSpaces

Drops the given origin from every inner (origin→localId) map; removes
the outer federatedId entry when its inner map becomes empty. Keeps the
store from accumulating stale origin references across long sessions
with connect/disconnect churn.
This commit is contained in:
Jannis Braun
2026-04-23 01:02:05 +02:00
parent 088fd40834
commit e7430f1a54
2 changed files with 51 additions and 0 deletions
@@ -113,4 +113,46 @@ describe('spaceStore.dmAlternatives', () => {
expect(byOrigin?.get('https://remote.example')).toBe('remote-new'); expect(byOrigin?.get('https://remote.example')).toBe('remote-new');
expect(byOrigin?.size).toBe(1); expect(byOrigin?.size).toBe(1);
}); });
it('removeInstanceSpaces drops the origin from every inner map', () => {
useSpaceStore.getState().populateFromReady(
'',
[],
[],
[makeDm('home-1', 'fed-aaa'), makeDm('home-2', 'fed-bbb')],
null,
0,
);
useSpaceStore.getState().populateFromReady(
'https://remote.example',
[],
[],
[makeDm('remote-1', 'fed-aaa'), makeDm('remote-2', 'fed-bbb')],
null,
0,
);
useSpaceStore.getState().removeInstanceSpaces('https://remote.example');
const alts = useSpaceStore.getState().dmAlternatives;
expect(alts.get('fed-aaa')?.has('https://remote.example')).toBe(false);
expect(alts.get('fed-aaa')?.get('')).toBe('home-1');
expect(alts.get('fed-bbb')?.has('https://remote.example')).toBe(false);
expect(alts.get('fed-bbb')?.get('')).toBe('home-2');
});
it('removeInstanceSpaces deletes federatedId entry if its inner map becomes empty', () => {
useSpaceStore.getState().populateFromReady(
'https://remote.example',
[],
[],
[makeDm('remote-only', 'fed-solo')],
null,
0,
);
useSpaceStore.getState().removeInstanceSpaces('https://remote.example');
expect(useSpaceStore.getState().dmAlternatives.has('fed-solo')).toBe(false);
});
}); });
+9
View File
@@ -870,6 +870,14 @@ export const useSpaceStore = create<SpaceState>((set, get) => ({
} }
} }
// Prune dmAlternatives: drop this origin from every inner map.
const dmAlternatives = new Map<string, Map<string, string>>();
for (const [fid, byOrigin] of state.dmAlternatives) {
const nextInner = new Map(byOrigin);
nextInner.delete(origin);
if (nextInner.size > 0) dmAlternatives.set(fid, nextInner);
}
return { return {
spaces: remainingSpaces, spaces: remainingSpaces,
channelToSpaceMap, channelToSpaceMap,
@@ -877,6 +885,7 @@ export const useSpaceStore = create<SpaceState>((set, get) => ({
channelPermissions, channelPermissions,
channelOriginMap, channelOriginMap,
spacePermissions, spacePermissions,
dmAlternatives,
currentSpaceId: remainingSpaces.find(s => s.id === state.currentSpaceId) currentSpaceId: remainingSpaces.find(s => s.id === state.currentSpaceId)
? state.currentSpaceId ? state.currentSpaceId
: null, : null,