refactor(team): extract data request keys
This commit is contained in:
parent
1d2f61ad86
commit
69f7a21771
3 changed files with 106 additions and 34 deletions
|
|
@ -29,6 +29,14 @@ import {
|
|||
isTeamTaskNeedsFixActionable,
|
||||
} from '@shared/utils/teamTaskState';
|
||||
|
||||
import {
|
||||
getFullTeamDataRequestKey,
|
||||
getTeamDataRequestKey,
|
||||
getTeamDataRequestLabel,
|
||||
getThinTeamDataRequestKey,
|
||||
isTeamDataRequestKeyForTeam,
|
||||
normalizeTeamGetDataOptions,
|
||||
} from '../team/teamDataRequestKeys';
|
||||
import { selectTeamDataForName } from '../team/teamDataSelectors';
|
||||
import {
|
||||
areInboxMessageArraysEquivalent,
|
||||
|
|
@ -155,38 +163,6 @@ interface RefreshTeamDataOptions {
|
|||
withDedup?: boolean;
|
||||
}
|
||||
|
||||
type TeamDataSnapshotMode = 'full' | 'thin';
|
||||
|
||||
function normalizeTeamGetDataOptions(options?: TeamGetDataOptions): TeamGetDataOptions | undefined {
|
||||
return options?.includeMemberBranches === false ? { includeMemberBranches: false } : undefined;
|
||||
}
|
||||
|
||||
function shouldIncludeMemberBranches(options?: TeamGetDataOptions): boolean {
|
||||
return normalizeTeamGetDataOptions(options)?.includeMemberBranches !== false;
|
||||
}
|
||||
|
||||
function getTeamDataSnapshotMode(options?: TeamGetDataOptions): TeamDataSnapshotMode {
|
||||
return shouldIncludeMemberBranches(options) ? 'full' : 'thin';
|
||||
}
|
||||
|
||||
function getTeamDataRequestKey(teamName: string, options?: TeamGetDataOptions): string {
|
||||
const normalizedOptions = normalizeTeamGetDataOptions(options);
|
||||
return `${teamName}\u0000mode:${getTeamDataSnapshotMode(normalizedOptions)}`;
|
||||
}
|
||||
|
||||
function getTeamDataRequestLabel(teamName: string, options?: TeamGetDataOptions): string {
|
||||
const normalizedOptions = normalizeTeamGetDataOptions(options);
|
||||
return `team:getData(${teamName},mode=${getTeamDataSnapshotMode(normalizedOptions)})`;
|
||||
}
|
||||
|
||||
function getFullTeamDataRequestKey(teamName: string): string {
|
||||
return getTeamDataRequestKey(teamName);
|
||||
}
|
||||
|
||||
function getThinTeamDataRequestKey(teamName: string): string {
|
||||
return getTeamDataRequestKey(teamName, { includeMemberBranches: false });
|
||||
}
|
||||
|
||||
function hasFullTeamDataRequestForTeam(teamName: string): boolean {
|
||||
return inFlightTeamDataRequests.has(getFullTeamDataRequestKey(teamName));
|
||||
}
|
||||
|
|
@ -196,9 +172,8 @@ function hasThinTeamDataRequestForTeam(teamName: string): boolean {
|
|||
}
|
||||
|
||||
function clearTeamDataRequestsForTeam(teamName: string): void {
|
||||
const prefix = `${teamName}\u0000`;
|
||||
for (const key of inFlightTeamDataRequests.keys()) {
|
||||
if (key.startsWith(prefix)) {
|
||||
if (isTeamDataRequestKeyForTeam(key, teamName)) {
|
||||
inFlightTeamDataRequests.delete(key);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
39
src/renderer/store/team/teamDataRequestKeys.ts
Normal file
39
src/renderer/store/team/teamDataRequestKeys.ts
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
import type { TeamGetDataOptions } from '@shared/types';
|
||||
|
||||
export type TeamDataSnapshotMode = 'full' | 'thin';
|
||||
|
||||
export function normalizeTeamGetDataOptions(
|
||||
options?: TeamGetDataOptions
|
||||
): TeamGetDataOptions | undefined {
|
||||
return options?.includeMemberBranches === false ? { includeMemberBranches: false } : undefined;
|
||||
}
|
||||
|
||||
export function shouldIncludeMemberBranches(options?: TeamGetDataOptions): boolean {
|
||||
return normalizeTeamGetDataOptions(options)?.includeMemberBranches !== false;
|
||||
}
|
||||
|
||||
export function getTeamDataSnapshotMode(options?: TeamGetDataOptions): TeamDataSnapshotMode {
|
||||
return shouldIncludeMemberBranches(options) ? 'full' : 'thin';
|
||||
}
|
||||
|
||||
export function getTeamDataRequestKey(teamName: string, options?: TeamGetDataOptions): string {
|
||||
const normalizedOptions = normalizeTeamGetDataOptions(options);
|
||||
return `${teamName}\u0000mode:${getTeamDataSnapshotMode(normalizedOptions)}`;
|
||||
}
|
||||
|
||||
export function getTeamDataRequestLabel(teamName: string, options?: TeamGetDataOptions): string {
|
||||
const normalizedOptions = normalizeTeamGetDataOptions(options);
|
||||
return `team:getData(${teamName},mode=${getTeamDataSnapshotMode(normalizedOptions)})`;
|
||||
}
|
||||
|
||||
export function getFullTeamDataRequestKey(teamName: string): string {
|
||||
return getTeamDataRequestKey(teamName);
|
||||
}
|
||||
|
||||
export function getThinTeamDataRequestKey(teamName: string): string {
|
||||
return getTeamDataRequestKey(teamName, { includeMemberBranches: false });
|
||||
}
|
||||
|
||||
export function isTeamDataRequestKeyForTeam(requestKey: string, teamName: string): boolean {
|
||||
return requestKey.startsWith(`${teamName}\u0000`);
|
||||
}
|
||||
58
test/renderer/store/teamDataRequestKeys.test.ts
Normal file
58
test/renderer/store/teamDataRequestKeys.test.ts
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
import { describe, expect, it } from 'vitest';
|
||||
|
||||
import {
|
||||
getFullTeamDataRequestKey,
|
||||
getTeamDataRequestKey,
|
||||
getTeamDataRequestLabel,
|
||||
getTeamDataSnapshotMode,
|
||||
getThinTeamDataRequestKey,
|
||||
isTeamDataRequestKeyForTeam,
|
||||
normalizeTeamGetDataOptions,
|
||||
shouldIncludeMemberBranches,
|
||||
} from '../../../src/renderer/store/team/teamDataRequestKeys';
|
||||
|
||||
describe('teamDataRequestKeys', () => {
|
||||
it('normalizes only the thin snapshot option and treats all other inputs as full snapshots', () => {
|
||||
expect(normalizeTeamGetDataOptions()).toBeUndefined();
|
||||
expect(normalizeTeamGetDataOptions({})).toBeUndefined();
|
||||
expect(normalizeTeamGetDataOptions({ includeMemberBranches: true })).toBeUndefined();
|
||||
expect(normalizeTeamGetDataOptions({ includeMemberBranches: false })).toEqual({
|
||||
includeMemberBranches: false,
|
||||
});
|
||||
|
||||
expect(shouldIncludeMemberBranches()).toBe(true);
|
||||
expect(shouldIncludeMemberBranches({ includeMemberBranches: true })).toBe(true);
|
||||
expect(shouldIncludeMemberBranches({ includeMemberBranches: false })).toBe(false);
|
||||
});
|
||||
|
||||
it('maps normalized request options to stable full and thin snapshot modes', () => {
|
||||
expect(getTeamDataSnapshotMode()).toBe('full');
|
||||
expect(getTeamDataSnapshotMode({ includeMemberBranches: true })).toBe('full');
|
||||
expect(getTeamDataSnapshotMode({ includeMemberBranches: false })).toBe('thin');
|
||||
});
|
||||
|
||||
it('builds request keys that preserve the existing null-separated team/mode contract', () => {
|
||||
expect(getTeamDataRequestKey('my-team')).toBe('my-team\u0000mode:full');
|
||||
expect(getTeamDataRequestKey('my-team', { includeMemberBranches: true })).toBe(
|
||||
'my-team\u0000mode:full'
|
||||
);
|
||||
expect(getTeamDataRequestKey('my-team', { includeMemberBranches: false })).toBe(
|
||||
'my-team\u0000mode:thin'
|
||||
);
|
||||
expect(getFullTeamDataRequestKey('my-team')).toBe('my-team\u0000mode:full');
|
||||
expect(getThinTeamDataRequestKey('my-team')).toBe('my-team\u0000mode:thin');
|
||||
});
|
||||
|
||||
it('builds timeout/debug labels from the same normalized mode policy', () => {
|
||||
expect(getTeamDataRequestLabel('my-team')).toBe('team:getData(my-team,mode=full)');
|
||||
expect(getTeamDataRequestLabel('my-team', { includeMemberBranches: false })).toBe(
|
||||
'team:getData(my-team,mode=thin)'
|
||||
);
|
||||
});
|
||||
|
||||
it('matches request keys only for the exact team prefix boundary', () => {
|
||||
expect(isTeamDataRequestKeyForTeam('my-team\u0000mode:full', 'my-team')).toBe(true);
|
||||
expect(isTeamDataRequestKeyForTeam('my-team-extra\u0000mode:full', 'my-team')).toBe(false);
|
||||
expect(isTeamDataRequestKeyForTeam('my-team', 'my-team')).toBe(false);
|
||||
});
|
||||
});
|
||||
Loading…
Reference in a new issue