export type WorkspaceKeyIdentity = { id: string; }; export type WorkspaceSearchableKey = WorkspaceKeyIdentity & { name: string; }; export function filterWorkspaceKeys( keys: T[], search: string, ) { const query = search.trim().toLowerCase(); if (!query) { return keys; } return keys.filter((item) => item.name.toLowerCase().includes(query)); } export function resolveSelectedWorkspaceKey( keys: T[], selectedKeyId: string | null, ) { if (keys.length === 0) { return null; } return keys.find((item) => item.id === selectedKeyId) ?? keys[0]; } export function resolveSelectedWorkspaceKeyId( keys: T[], selectedKeyId: string | null, ) { return resolveSelectedWorkspaceKey(keys, selectedKeyId)?.id ?? null; } export function replaceWorkspaceKeyRecord( current: T[], next: T, ) { let replaced = false; const updated = current.map((item) => { if (item.id !== next.id) { return item; } replaced = true; return { ...item, ...next, }; }); return replaced ? updated : [next, ...current]; } export function appendWorkspaceKeyRecords( current: T[], next: T[], ) { const seen = new Set(current.map((item) => item.id)); const appended = [...current]; for (const item of next) { if (seen.has(item.id)) { continue; } seen.add(item.id); appended.push(item); } return appended; }