mirror of
https://github.com/stablyai/orca.git
synced 2026-09-29 08:03:20 +00:00
perf(store): keep the repo list's identity through workspace hydration
buildRuntimeSessionPlaceholders opened with `repos.slice()`, so every workspace session hydration handed the store a brand-new `repos` array — including the common case where the session referenced no unknown runtime workspace and the contents were identical. `repos` is selected whole at 46 sites, so each hydration rerendered all of them for no data change. The appends below already build a new array rather than mutating, and the sibling `nextWorktreesByRepo` in the same function was already copy-on-write; this just gives `repos` the same treatment. No consumer of the returned array mutates it in place.
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import type { Repo } from '../../../../shared/repo-types'
|
||||
import type { Worktree } from '../../../../shared/worktree/types'
|
||||
import { DEFAULT_REPO_BADGE_COLOR } from '../../../../shared/constants'
|
||||
import { buildRuntimeSessionPlaceholders } from './workspace-terminal-placeholders'
|
||||
|
||||
const repo: Repo = {
|
||||
id: 'repo-1',
|
||||
path: '/repos/one',
|
||||
displayName: 'one',
|
||||
badgeColor: DEFAULT_REPO_BADGE_COLOR,
|
||||
addedAt: 0,
|
||||
connectionId: null,
|
||||
executionHostId: 'local'
|
||||
}
|
||||
|
||||
const worktree: Worktree = {
|
||||
id: 'repo-1::/repos/one',
|
||||
repoId: 'repo-1',
|
||||
hostId: 'local',
|
||||
displayName: 'main',
|
||||
comment: '',
|
||||
linkedIssue: null,
|
||||
linkedPR: null,
|
||||
linkedLinearIssue: null,
|
||||
linkedGitLabMR: null,
|
||||
linkedGitLabIssue: null,
|
||||
isArchived: false,
|
||||
isUnread: false,
|
||||
isPinned: false,
|
||||
sortOrder: 0,
|
||||
lastActivityAt: 0,
|
||||
path: '/repos/one',
|
||||
head: '',
|
||||
branch: '',
|
||||
isBare: false,
|
||||
isMainWorktree: true
|
||||
}
|
||||
|
||||
describe('buildRuntimeSessionPlaceholders', () => {
|
||||
it('returns the original repos array when no placeholder repo is needed', () => {
|
||||
const repos = [repo]
|
||||
const worktreesByRepo = { 'repo-1': [worktree] }
|
||||
|
||||
const result = buildRuntimeSessionPlaceholders({
|
||||
repos,
|
||||
runtimeHostIdByWorkspaceSessionKey: {},
|
||||
worktreesByRepo
|
||||
})
|
||||
|
||||
// Hydration writes these straight to the store; a fresh array would rerender
|
||||
// every component selecting the whole repo list for no data change.
|
||||
expect(result.repos).toBe(repos)
|
||||
expect(result.worktreesByRepo).toBe(worktreesByRepo)
|
||||
})
|
||||
|
||||
it('keeps the original repos array when the session only references known repos', () => {
|
||||
const repos = [repo]
|
||||
|
||||
const result = buildRuntimeSessionPlaceholders({
|
||||
repos,
|
||||
runtimeHostIdByWorkspaceSessionKey: { 'repo-1::/repos/one': 'runtime:host-1' },
|
||||
worktreesByRepo: { 'repo-1': [worktree] }
|
||||
})
|
||||
|
||||
expect(result.repos).toBe(repos)
|
||||
})
|
||||
|
||||
it('still appends a placeholder repo for an unknown runtime workspace', () => {
|
||||
const repos = [repo]
|
||||
|
||||
const result = buildRuntimeSessionPlaceholders({
|
||||
repos,
|
||||
runtimeHostIdByWorkspaceSessionKey: { 'repo-2::/repos/two': 'runtime:host-1' },
|
||||
worktreesByRepo: { 'repo-1': [worktree] }
|
||||
})
|
||||
|
||||
expect(result.repos).not.toBe(repos)
|
||||
expect(result.repos.map((entry) => entry.id)).toEqual(['repo-1', 'repo-2'])
|
||||
// The caller's array must not be mutated in place.
|
||||
expect(repos).toHaveLength(1)
|
||||
})
|
||||
})
|
||||
@@ -20,10 +20,15 @@ export function buildRuntimeSessionPlaceholders({
|
||||
runtimeHostIdByWorkspaceSessionKey: Record<string, ExecutionHostId>
|
||||
worktreesByRepo: Record<string, Worktree[]>
|
||||
}): {
|
||||
repos: Repo[]
|
||||
repos: readonly Repo[]
|
||||
worktreesByRepo: Record<string, Worktree[]>
|
||||
} {
|
||||
let nextRepos = repos.slice()
|
||||
// Why not `repos.slice()`: hydration writes this array straight back to the store, and
|
||||
// sessions that add no placeholder repo are the common case. Copying unconditionally
|
||||
// gave `repos` a new identity on every workspace hydration, rerendering every component
|
||||
// that selects the whole array. Appends below already build a new array, as
|
||||
// nextWorktreesByRepo does for its own copy-on-write.
|
||||
let nextRepos: readonly Repo[] = repos
|
||||
let nextWorktreesByRepo = worktreesByRepo
|
||||
for (const workspaceSessionKey of Object.keys(runtimeHostIdByWorkspaceSessionKey)) {
|
||||
const hostId = runtimeHostIdByWorkspaceSessionKey[workspaceSessionKey]
|
||||
|
||||
Reference in New Issue
Block a user