mirror of
https://github.com/stablyai/orca.git
synced 2026-09-22 00:02:31 +00:00
perf(renderer): cache startup action selector (#17458)
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { createStore } from 'zustand/vanilla'
|
||||
import {
|
||||
resetStartupActionsSelectorCacheForTest,
|
||||
selectStartupActions,
|
||||
type StartupActions
|
||||
} from './startup-actions-selector'
|
||||
|
||||
type StartupTestState = StartupActions & { publication: number }
|
||||
|
||||
function makeActions(): StartupActions {
|
||||
return {
|
||||
fetchReposForAllHosts: vi.fn(),
|
||||
awaitLocalRepoCatalogSettlement: vi.fn(),
|
||||
fetchProjectGroupsForAllHosts: vi.fn(),
|
||||
fetchFolderWorkspacesForAllHosts: vi.fn(),
|
||||
fetchAllWorktrees: vi.fn(),
|
||||
fetchWorktrees: vi.fn(),
|
||||
fetchWorktreeLineage: vi.fn(),
|
||||
fetchOrcaProfiles: vi.fn(),
|
||||
fetchSettings: vi.fn(),
|
||||
awaitOwnerWorktreeVisibilityDefaultsHydration: vi.fn(),
|
||||
fetchKeybindings: vi.fn(),
|
||||
initGitHubCache: vi.fn(),
|
||||
hydrateWorkspaceSession: vi.fn(),
|
||||
hydrateTabsSession: vi.fn(),
|
||||
hydrateEditorSession: vi.fn(),
|
||||
hydrateBrowserSession: vi.fn(),
|
||||
fetchBrowserSessionProfiles: vi.fn(),
|
||||
reconnectPersistedTerminals: vi.fn(),
|
||||
setTerminalStartupRestorationReady: vi.fn(),
|
||||
setDeferredSshReconnectTargets: vi.fn(),
|
||||
setSshConnectionState: vi.fn(),
|
||||
hydratePersistedUI: vi.fn(),
|
||||
setHydrationSucceeded: vi.fn(),
|
||||
pruneLastVisitedTimestamps: vi.fn(),
|
||||
seedActiveWorktreeLastVisitedIfMissing: vi.fn()
|
||||
} as StartupActions
|
||||
}
|
||||
|
||||
describe('startup action selector', () => {
|
||||
beforeEach(() => {
|
||||
resetStartupActionsSelectorCacheForTest()
|
||||
})
|
||||
|
||||
it('reuses one action bundle across 1,000 repeated reads', () => {
|
||||
const actions = makeActions()
|
||||
const first = selectStartupActions(actions)
|
||||
|
||||
for (let read = 0; read < 1_000; read += 1) {
|
||||
expect(selectStartupActions(actions)).toBe(first)
|
||||
}
|
||||
})
|
||||
|
||||
it('rebuilds the bundle when one action reference changes', () => {
|
||||
const actions = makeActions()
|
||||
const first = selectStartupActions(actions)
|
||||
const replacement = { ...actions, fetchSettings: vi.fn() } as StartupActions
|
||||
|
||||
const next = selectStartupActions(replacement)
|
||||
expect(next).not.toBe(first)
|
||||
|
||||
for (let read = 0; read < 1_000; read += 1) {
|
||||
expect(selectStartupActions(replacement)).toBe(next)
|
||||
}
|
||||
})
|
||||
|
||||
it('keeps the selected projection stable across 1,000 unrelated publications', () => {
|
||||
const actions = makeActions()
|
||||
const store = createStore<StartupTestState>(() => ({ ...actions, publication: 0 }))
|
||||
let publicationCount = 0
|
||||
let projectionChangeCount = 0
|
||||
let previousProjection = selectStartupActions(store.getState())
|
||||
const unsubscribe = store.subscribe((state) => {
|
||||
publicationCount += 1
|
||||
const projection = selectStartupActions(state)
|
||||
if (projection !== previousProjection) {
|
||||
projectionChangeCount += 1
|
||||
}
|
||||
previousProjection = projection
|
||||
})
|
||||
|
||||
for (let publication = 1; publication <= 1_000; publication += 1) {
|
||||
store.setState({ publication })
|
||||
}
|
||||
|
||||
expect(publicationCount).toBe(1_000)
|
||||
expect(projectionChangeCount).toBe(0)
|
||||
unsubscribe()
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,105 @@
|
||||
import type { AppState } from '../store/types'
|
||||
|
||||
export type StartupActions = Pick<
|
||||
AppState,
|
||||
| 'fetchReposForAllHosts'
|
||||
| 'awaitLocalRepoCatalogSettlement'
|
||||
| 'fetchProjectGroupsForAllHosts'
|
||||
| 'fetchFolderWorkspacesForAllHosts'
|
||||
| 'fetchAllWorktrees'
|
||||
| 'fetchWorktrees'
|
||||
| 'fetchWorktreeLineage'
|
||||
| 'fetchOrcaProfiles'
|
||||
| 'fetchSettings'
|
||||
| 'awaitOwnerWorktreeVisibilityDefaultsHydration'
|
||||
| 'fetchKeybindings'
|
||||
| 'initGitHubCache'
|
||||
| 'hydrateWorkspaceSession'
|
||||
| 'hydrateTabsSession'
|
||||
| 'hydrateEditorSession'
|
||||
| 'hydrateBrowserSession'
|
||||
| 'fetchBrowserSessionProfiles'
|
||||
| 'reconnectPersistedTerminals'
|
||||
| 'setTerminalStartupRestorationReady'
|
||||
| 'setDeferredSshReconnectTargets'
|
||||
| 'setSshConnectionState'
|
||||
| 'hydratePersistedUI'
|
||||
| 'setHydrationSucceeded'
|
||||
| 'pruneLastVisitedTimestamps'
|
||||
| 'seedActiveWorktreeLastVisitedIfMissing'
|
||||
>
|
||||
|
||||
let cachedStartupActions: StartupActions | null = null
|
||||
|
||||
/** Keeps the always-mounted startup subscription stable across unrelated store writes. */
|
||||
export function selectStartupActions(state: StartupActions): StartupActions {
|
||||
if (
|
||||
cachedStartupActions &&
|
||||
cachedStartupActions.fetchReposForAllHosts === state.fetchReposForAllHosts &&
|
||||
cachedStartupActions.awaitLocalRepoCatalogSettlement ===
|
||||
state.awaitLocalRepoCatalogSettlement &&
|
||||
cachedStartupActions.fetchProjectGroupsForAllHosts === state.fetchProjectGroupsForAllHosts &&
|
||||
cachedStartupActions.fetchFolderWorkspacesForAllHosts ===
|
||||
state.fetchFolderWorkspacesForAllHosts &&
|
||||
cachedStartupActions.fetchAllWorktrees === state.fetchAllWorktrees &&
|
||||
cachedStartupActions.fetchWorktrees === state.fetchWorktrees &&
|
||||
cachedStartupActions.fetchWorktreeLineage === state.fetchWorktreeLineage &&
|
||||
cachedStartupActions.fetchOrcaProfiles === state.fetchOrcaProfiles &&
|
||||
cachedStartupActions.fetchSettings === state.fetchSettings &&
|
||||
cachedStartupActions.awaitOwnerWorktreeVisibilityDefaultsHydration ===
|
||||
state.awaitOwnerWorktreeVisibilityDefaultsHydration &&
|
||||
cachedStartupActions.fetchKeybindings === state.fetchKeybindings &&
|
||||
cachedStartupActions.initGitHubCache === state.initGitHubCache &&
|
||||
cachedStartupActions.hydrateWorkspaceSession === state.hydrateWorkspaceSession &&
|
||||
cachedStartupActions.hydrateTabsSession === state.hydrateTabsSession &&
|
||||
cachedStartupActions.hydrateEditorSession === state.hydrateEditorSession &&
|
||||
cachedStartupActions.hydrateBrowserSession === state.hydrateBrowserSession &&
|
||||
cachedStartupActions.fetchBrowserSessionProfiles === state.fetchBrowserSessionProfiles &&
|
||||
cachedStartupActions.reconnectPersistedTerminals === state.reconnectPersistedTerminals &&
|
||||
cachedStartupActions.setTerminalStartupRestorationReady ===
|
||||
state.setTerminalStartupRestorationReady &&
|
||||
cachedStartupActions.setDeferredSshReconnectTargets === state.setDeferredSshReconnectTargets &&
|
||||
cachedStartupActions.setSshConnectionState === state.setSshConnectionState &&
|
||||
cachedStartupActions.hydratePersistedUI === state.hydratePersistedUI &&
|
||||
cachedStartupActions.setHydrationSucceeded === state.setHydrationSucceeded &&
|
||||
cachedStartupActions.pruneLastVisitedTimestamps === state.pruneLastVisitedTimestamps &&
|
||||
cachedStartupActions.seedActiveWorktreeLastVisitedIfMissing ===
|
||||
state.seedActiveWorktreeLastVisitedIfMissing
|
||||
) {
|
||||
return cachedStartupActions
|
||||
}
|
||||
|
||||
cachedStartupActions = {
|
||||
fetchReposForAllHosts: state.fetchReposForAllHosts,
|
||||
awaitLocalRepoCatalogSettlement: state.awaitLocalRepoCatalogSettlement,
|
||||
fetchProjectGroupsForAllHosts: state.fetchProjectGroupsForAllHosts,
|
||||
fetchFolderWorkspacesForAllHosts: state.fetchFolderWorkspacesForAllHosts,
|
||||
fetchAllWorktrees: state.fetchAllWorktrees,
|
||||
fetchWorktrees: state.fetchWorktrees,
|
||||
fetchWorktreeLineage: state.fetchWorktreeLineage,
|
||||
fetchOrcaProfiles: state.fetchOrcaProfiles,
|
||||
fetchSettings: state.fetchSettings,
|
||||
awaitOwnerWorktreeVisibilityDefaultsHydration:
|
||||
state.awaitOwnerWorktreeVisibilityDefaultsHydration,
|
||||
fetchKeybindings: state.fetchKeybindings,
|
||||
initGitHubCache: state.initGitHubCache,
|
||||
hydrateWorkspaceSession: state.hydrateWorkspaceSession,
|
||||
hydrateTabsSession: state.hydrateTabsSession,
|
||||
hydrateEditorSession: state.hydrateEditorSession,
|
||||
hydrateBrowserSession: state.hydrateBrowserSession,
|
||||
fetchBrowserSessionProfiles: state.fetchBrowserSessionProfiles,
|
||||
reconnectPersistedTerminals: state.reconnectPersistedTerminals,
|
||||
setTerminalStartupRestorationReady: state.setTerminalStartupRestorationReady,
|
||||
setDeferredSshReconnectTargets: state.setDeferredSshReconnectTargets,
|
||||
setSshConnectionState: state.setSshConnectionState,
|
||||
hydratePersistedUI: state.hydratePersistedUI,
|
||||
setHydrationSucceeded: state.setHydrationSucceeded,
|
||||
pruneLastVisitedTimestamps: state.pruneLastVisitedTimestamps,
|
||||
seedActiveWorktreeLastVisitedIfMissing: state.seedActiveWorktreeLastVisitedIfMissing
|
||||
}
|
||||
return cachedStartupActions
|
||||
}
|
||||
|
||||
export function resetStartupActionsSelectorCacheForTest(): void {
|
||||
cachedStartupActions = null
|
||||
}
|
||||
@@ -1,39 +1,9 @@
|
||||
// The renderer boot chain's store subscription, kept apart from the chain itself
|
||||
// so one useShallow equality check covers every startup action.
|
||||
// so unrelated store publications reuse one action projection.
|
||||
|
||||
import { useShallow } from 'zustand/react/shallow'
|
||||
import { useAppStore } from '../store'
|
||||
import { selectStartupActions } from './startup-actions-selector'
|
||||
|
||||
export function useStartupActions() {
|
||||
// Why: consolidate action refs into one useShallow subscription so React runs one equality check per store mutation instead of one per action.
|
||||
return useAppStore(
|
||||
useShallow((s) => ({
|
||||
fetchReposForAllHosts: s.fetchReposForAllHosts,
|
||||
awaitLocalRepoCatalogSettlement: s.awaitLocalRepoCatalogSettlement,
|
||||
fetchProjectGroupsForAllHosts: s.fetchProjectGroupsForAllHosts,
|
||||
fetchFolderWorkspacesForAllHosts: s.fetchFolderWorkspacesForAllHosts,
|
||||
fetchAllWorktrees: s.fetchAllWorktrees,
|
||||
fetchWorktrees: s.fetchWorktrees,
|
||||
fetchWorktreeLineage: s.fetchWorktreeLineage,
|
||||
fetchOrcaProfiles: s.fetchOrcaProfiles,
|
||||
fetchSettings: s.fetchSettings,
|
||||
awaitOwnerWorktreeVisibilityDefaultsHydration:
|
||||
s.awaitOwnerWorktreeVisibilityDefaultsHydration,
|
||||
fetchKeybindings: s.fetchKeybindings,
|
||||
initGitHubCache: s.initGitHubCache,
|
||||
hydrateWorkspaceSession: s.hydrateWorkspaceSession,
|
||||
hydrateTabsSession: s.hydrateTabsSession,
|
||||
hydrateEditorSession: s.hydrateEditorSession,
|
||||
hydrateBrowserSession: s.hydrateBrowserSession,
|
||||
fetchBrowserSessionProfiles: s.fetchBrowserSessionProfiles,
|
||||
reconnectPersistedTerminals: s.reconnectPersistedTerminals,
|
||||
setTerminalStartupRestorationReady: s.setTerminalStartupRestorationReady,
|
||||
setDeferredSshReconnectTargets: s.setDeferredSshReconnectTargets,
|
||||
setSshConnectionState: s.setSshConnectionState,
|
||||
hydratePersistedUI: s.hydratePersistedUI,
|
||||
setHydrationSucceeded: s.setHydrationSucceeded,
|
||||
pruneLastVisitedTimestamps: s.pruneLastVisitedTimestamps,
|
||||
seedActiveWorktreeLastVisitedIfMissing: s.seedActiveWorktreeLastVisitedIfMissing
|
||||
}))
|
||||
)
|
||||
return useAppStore(selectStartupActions)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user