mirror of
https://github.com/stablyai/orca.git
synced 2026-09-22 16:02:32 +00:00
* Split speech session lifecycle * Split terminal output scheduler pipeline * Split mobile browser pane modules * Prune resolved max-lines suppressions * Split pane tree equalization logic * Extract mobile troubleshoot screen styles * Split external automation manager * Split main window service attachments * Split hosted review creation checks * Split automation dispatch event handling * Split settings navigation metadata * Split daemon initialization lifecycle * Split GitLab item dialog * Split relay dispatcher layers * Split mobile host screen * Retarget mobile view settings source test * Split runtime file client layers * Split ports panel layers * Split runtime environments pane layers * Split local PTY provider responsibilities * Split CDP bridge responsibilities * Split relay Git handler responsibilities * Track moved relay Git fetch audit * Split Linear item drawer responsibilities * Split telemetry event schema responsibilities * Split resource usage status responsibilities * Split remote terminal multiplexer responsibilities * Split Git worktree responsibilities * Split Codex hook service responsibilities * Keep mirrored hook trust type private * Split web runtime session responsibilities * Split GitHub project view read path * Fix F3-speech for #17123 * Fix F1-cycle for #17131 * Fix F4-navtest for #17157 * Fix F2-allowlist for #17161
150 lines
5.1 KiB
TypeScript
150 lines
5.1 KiB
TypeScript
import type { GitHubProjectOwnerType } from '../../../shared/github/project-types'
|
|
import { githubProjectHost } from '../../../shared/github/project-identity'
|
|
|
|
export const PROJECT_VIEW_OWNER_CACHE_MAX_ENTRIES = 512
|
|
|
|
// ─── Module-scope caches (reset on HMR — intentional) ──────────────────
|
|
|
|
// Why: owners are user-controlled over a long session; bound cache entries to avoid unbounded retention while keeping the hot-owner fast path.
|
|
function rememberProjectViewCacheEntry<K, V>(
|
|
cache: Map<K, V>,
|
|
key: K,
|
|
value: V,
|
|
maxEntries = PROJECT_VIEW_OWNER_CACHE_MAX_ENTRIES
|
|
): void {
|
|
if (cache.has(key)) {
|
|
cache.delete(key)
|
|
}
|
|
cache.set(key, value)
|
|
while (cache.size > maxEntries) {
|
|
const oldest = cache.keys().next()
|
|
if (oldest.done) {
|
|
break
|
|
}
|
|
cache.delete(oldest.value)
|
|
}
|
|
}
|
|
|
|
function getProjectViewCacheEntry<K, V>(cache: Map<K, V>, key: K): V | undefined {
|
|
if (!cache.has(key)) {
|
|
return undefined
|
|
}
|
|
const value = cache.get(key) as V
|
|
rememberProjectViewCacheEntry(cache, key, value)
|
|
return value
|
|
}
|
|
|
|
// Why: plain module locals so HMR code swaps re-run capability probes instead of carrying a stale "unsupported" flag.
|
|
const ownerTypeCache = new Map<string, GitHubProjectOwnerType | null>()
|
|
// Why: keyed per owner (not a process-global flag) so one owner's capability gap doesn't poison others that DO support Issue.parent (bug-scan finding 2).
|
|
const parentFieldRetriedByOwner = new Map<string, true>()
|
|
const parentFieldWarningLoggedByOwner = new Map<string, true>()
|
|
// Why: in-flight promise per owner so concurrent fetchAllItems callers share one probe instead of each racing a duplicate first-page probe.
|
|
export const parentFieldProbeInFlight = new Map<string, Promise<void>>()
|
|
|
|
// Why: GHES owners are a separate namespace and capability surface from
|
|
// github.com owners with the same login — scope cache keys by host so one
|
|
// host's probe result can't leak into another. Normalize github.com so
|
|
// host-less callers share the same probe state as explicitly pinned calls.
|
|
export function ownerScopeKey(
|
|
owner: string,
|
|
ownerType: GitHubProjectOwnerType,
|
|
host?: string
|
|
): string {
|
|
const base = `${owner}\u0000${ownerType}`
|
|
return `${base}\u0000${githubProjectHost(host)}`
|
|
}
|
|
|
|
function ownerTypeCacheKey(owner: string, host?: string): string {
|
|
return `${owner}\u0000${githubProjectHost(host)}`
|
|
}
|
|
|
|
export function rememberOwnerType(
|
|
owner: string,
|
|
ownerType: GitHubProjectOwnerType | null,
|
|
host?: string
|
|
): void {
|
|
rememberProjectViewCacheEntry(ownerTypeCache, ownerTypeCacheKey(owner, host), ownerType)
|
|
}
|
|
|
|
export function getCachedOwnerType(
|
|
owner: string,
|
|
host?: string
|
|
): GitHubProjectOwnerType | null | undefined {
|
|
return getProjectViewCacheEntry(ownerTypeCache, ownerTypeCacheKey(owner, host))
|
|
}
|
|
|
|
export function markParentFieldRetried(scopeKey: string): void {
|
|
rememberProjectViewCacheEntry(parentFieldRetriedByOwner, scopeKey, true)
|
|
}
|
|
|
|
export function hasParentFieldRetried(scopeKey: string): boolean {
|
|
return getProjectViewCacheEntry(parentFieldRetriedByOwner, scopeKey) === true
|
|
}
|
|
|
|
export function markParentFieldWarningLogged(scopeKey: string): void {
|
|
rememberProjectViewCacheEntry(parentFieldWarningLoggedByOwner, scopeKey, true)
|
|
}
|
|
|
|
export function hasParentFieldWarningLogged(scopeKey: string): boolean {
|
|
return getProjectViewCacheEntry(parentFieldWarningLoggedByOwner, scopeKey) === true
|
|
}
|
|
|
|
export function _resetProjectViewCachesForTests(): void {
|
|
ownerTypeCache.clear()
|
|
parentFieldRetriedByOwner.clear()
|
|
parentFieldWarningLoggedByOwner.clear()
|
|
parentFieldProbeInFlight.clear()
|
|
}
|
|
|
|
export function _getProjectViewCacheSizesForTests(): {
|
|
ownerTypes: number
|
|
parentFieldRetries: number
|
|
parentFieldWarnings: number
|
|
parentFieldProbes: number
|
|
} {
|
|
return {
|
|
ownerTypes: ownerTypeCache.size,
|
|
parentFieldRetries: parentFieldRetriedByOwner.size,
|
|
parentFieldWarnings: parentFieldWarningLoggedByOwner.size,
|
|
parentFieldProbes: parentFieldProbeInFlight.size
|
|
}
|
|
}
|
|
|
|
/** @internal - exposed for cache-bound tests only. */
|
|
export function _rememberProjectViewOwnerTypeForTests(
|
|
owner: string,
|
|
ownerType: GitHubProjectOwnerType | null,
|
|
host?: string
|
|
): void {
|
|
rememberOwnerType(owner, ownerType, host)
|
|
}
|
|
|
|
/** @internal - exposed for cache-bound tests only. */
|
|
export function _getProjectViewOwnerTypeForTests(
|
|
owner: string,
|
|
host?: string
|
|
): GitHubProjectOwnerType | null | undefined {
|
|
return getCachedOwnerType(owner, host)
|
|
}
|
|
|
|
/** @internal - exposed for cache-bound tests only. */
|
|
export function _markProjectViewParentFieldRetriedForTests(scopeKey: string): void {
|
|
markParentFieldRetried(scopeKey)
|
|
}
|
|
|
|
/** @internal - exposed for cache-bound tests only. */
|
|
export function _hasProjectViewParentFieldRetriedForTests(scopeKey: string): boolean {
|
|
return hasParentFieldRetried(scopeKey)
|
|
}
|
|
|
|
/** @internal - exposed for cache-bound tests only. */
|
|
export function _markProjectViewParentFieldWarningLoggedForTests(scopeKey: string): void {
|
|
markParentFieldWarningLogged(scopeKey)
|
|
}
|
|
|
|
/** @internal - exposed for cache-bound tests only. */
|
|
export function _hasProjectViewParentFieldWarningLoggedForTests(scopeKey: string): boolean {
|
|
return hasParentFieldWarningLogged(scopeKey)
|
|
}
|