mirror of
https://github.com/stablyai/orca.git
synced 2026-10-22 00:03:47 +00:00
fix(browser): latch overlay retention after commit
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
// @vitest-environment happy-dom
|
||||
import { cleanup, render } from '@testing-library/react'
|
||||
import { Suspense } from 'react'
|
||||
import { renderToStaticMarkup } from 'react-dom/server'
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import type { BrowserTab as BrowserTabState, Tab, TabGroup } from '../../../../shared/types'
|
||||
@@ -94,6 +95,33 @@ describe('BrowserPaneOverlayLayer', () => {
|
||||
expect(view.container.querySelectorAll('[data-browser-overlay-tab-id]')).toHaveLength(2)
|
||||
})
|
||||
|
||||
it('does not retain browser slots from an eligible render that never commits', () => {
|
||||
const pending = new Promise<never>(() => {})
|
||||
const BlockCommit = ({ blocked }: { blocked: boolean }): null => {
|
||||
if (blocked) {
|
||||
throw pending
|
||||
}
|
||||
return null
|
||||
}
|
||||
const renderBoundary = (mountEligible: boolean, blocked: boolean) => (
|
||||
<Suspense fallback={<span data-suspended />}>
|
||||
<RetainedBrowserPaneOverlayLayer
|
||||
worktreeId="wt-1"
|
||||
isWorktreeActive={mountEligible}
|
||||
mountEligible={mountEligible}
|
||||
/>
|
||||
<BlockCommit blocked={blocked} />
|
||||
</Suspense>
|
||||
)
|
||||
const view = render(renderBoundary(false, false))
|
||||
|
||||
view.rerender(renderBoundary(true, true))
|
||||
expect(view.container.querySelector('[data-suspended]')).not.toBeNull()
|
||||
|
||||
view.rerender(renderBoundary(false, false))
|
||||
expect(view.container.querySelectorAll('[data-browser-overlay-tab-id]')).toHaveLength(0)
|
||||
})
|
||||
|
||||
it('keeps inactive browser panes mounted for a visible worktree', () => {
|
||||
const markup = renderOverlay({ isWorktreeActive: true })
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { memo, useCallback, useMemo, useRef } from 'react'
|
||||
import { memo, useCallback, useLayoutEffect, useMemo, useState } from 'react'
|
||||
import { registerBrowserOverlaySlotViewport } from './browser-page-viewport'
|
||||
import { useShallow } from 'zustand/react/shallow'
|
||||
import { useAppStore } from '../../store'
|
||||
@@ -203,11 +203,14 @@ export const RetainedBrowserPaneOverlayLayer = memo(function RetainedBrowserPane
|
||||
isWorktreeActive: boolean
|
||||
mountEligible: boolean
|
||||
}): React.JSX.Element | null {
|
||||
const hasMountedRef = useRef(mountEligible)
|
||||
if (mountEligible) {
|
||||
hasMountedRef.current = true
|
||||
}
|
||||
if (!hasMountedRef.current) {
|
||||
const [hasCommittedMount, setHasCommittedMount] = useState(false)
|
||||
// Why: commit the latch with the persistent slot DOM so discarded renders cannot retain a guest host.
|
||||
useLayoutEffect(() => {
|
||||
if (mountEligible && !hasCommittedMount) {
|
||||
setHasCommittedMount(true)
|
||||
}
|
||||
}, [hasCommittedMount, mountEligible])
|
||||
if (!mountEligible && !hasCommittedMount) {
|
||||
return null
|
||||
}
|
||||
return <BrowserPaneOverlayLayer worktreeId={worktreeId} isWorktreeActive={isWorktreeActive} />
|
||||
|
||||
Reference in New Issue
Block a user