| 133 | }); |
| 134 | |
| 135 | const updateThread = ( |
| 136 | byThreadKey: Record<string, ThreadRightPanelState>, |
| 137 | threadKey: string, |
| 138 | updater: (current: ThreadRightPanelState) => ThreadRightPanelState, |
| 139 | ): Record<string, ThreadRightPanelState> => { |
| 140 | const current = byThreadKey[threadKey] ?? EMPTY_THREAD_STATE; |
| 141 | const next = updater(current); |
| 142 | if (!next.isOpen && next.activeSurfaceId === null && next.surfaces.length === 0) { |
| 143 | if (!(threadKey in byThreadKey)) return byThreadKey; |
| 144 | const { [threadKey]: _removed, ...rest } = byThreadKey; |
| 145 | return rest; |
| 146 | } |
| 147 | if (next === current) return byThreadKey; |
| 148 | return { ...byThreadKey, [threadKey]: next }; |
| 149 | }; |
| 150 | |
| 151 | function normalizeRevealLine(line: number | undefined): number | null { |
| 152 | if (line === undefined || !Number.isFinite(line)) return null; |