Skip to content

Conversation

@turner
Copy link
Collaborator

@turner turner commented Nov 12, 2025

No description provided.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR refactors the HICBrowser "God Object" by extracting distinct responsibilities into dedicated coordinator/manager classes following the Single Responsibility Principle. The refactoring introduces StateManager, NotificationCoordinator, InteractionHandler, DataLoader, and RenderCoordinator to separate state management, UI notifications, user interactions, data loading, and rendering concerns.

Key Changes

  • Extracted state management into StateManager class for centralized dataset and state handling
  • Created NotificationCoordinator to handle all UI component notifications
  • Introduced InteractionHandler for user interaction methods (goto, zoom, pan)
  • Added DataLoader to manage Hi-C file, track, and normalization data loading
  • Implemented RenderCoordinator to handle rendering coordination and queuing

Reviewed Changes

Copilot reviewed 36 out of 36 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
js/hicBrowser.js Refactored to delegate responsibilities to new coordinator classes while maintaining backward compatibility
js/stateManager.js New class managing active dataset, state transitions, and cross-browser synchronization
js/notificationCoordinator.js New class coordinating UI component updates when browser state changes
js/interactionHandler.js New class handling navigation, zoom, and pan operations
js/dataLoader.js New class managing data loading operations for Hi-C files, tracks, and normalizations
js/renderCoordinator.js New class coordinating rendering with queuing logic for rapid calls
js/hicState.js Added helper methods for state validation, pixel size adjustment, and update finalization
js/urlUtils.js Added session loading from File objects and file paths with URL shortcut expansion
js/session.js Added URL shortcut expansion for backward compatibility
test/testSession.js New test file for session loading functionality
vite.config.js Added plugins to suppress source map warnings for third-party dependencies
various widget files Added helper methods to encapsulate DOM manipulation

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

}

juicebox.init(document.getElementById("app-container"), config_deep_map)
juicebox.init(document.getElementById("app-container"), config)
Copy link

Copilot AI Nov 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Variable config_deep_map is changed to config, but config is not defined in this file. This will cause a ReferenceError at runtime. Either define config or revert to config_deep_map.

Copilot uses AI. Check for mistakes.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot open a new pull request to apply changes based on this feedback

} catch (error) {
this.browser.contactMapLabel.textContent = "";
this.browser.contactMapLabel.title = "";
config.name = name;
Copy link

Copilot AI Nov 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Variable name is used before it's defined. The line config.name = name references name from line 84, but this code is in the catch block after the try block where name was defined. If an error occurs before line 84, name will be undefined, causing this assignment to fail silently or set config.name to undefined.

Copilot uses AI. Check for mistakes.
Comment on lines +88 to +109
customLogger: {
warn(msg, options) {
// Filter out source map warnings for igv dependencies
const message = typeof msg === 'string' ? msg : String(msg);
if (message.includes('igv-ui.css.map') ||
message.includes('Failed to load source map') ||
(message.includes('ENOENT') && message.includes('igv'))) {
return; // Suppress these warnings
}
// Use default warning logger for other messages
console.warn(msg, options);
},
error(msg, options) {
// Filter out source map errors for igv dependencies
const message = typeof msg === 'string' ? msg : String(msg);
if (message.includes('igv-ui.css.map') ||
message.includes('Failed to load source map') ||
(message.includes('ENOENT') && message.includes('igv'))) {
return; // Suppress these errors
}
// Use default error logger for other messages
console.error(msg, options);
Copy link

Copilot AI Nov 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The custom logger's warn and error methods call console.warn(msg, options) and console.error(msg, options). However, the standard console methods don't accept an options parameter in this way. This may cause issues or unexpected behavior. Consider spreading the arguments or checking if options is defined before passing it.

Copilot uses AI. Check for mistakes.
"height": 1000,
"url": "https://www.encodeproject.org/files/ENCFF799QGA/@@download/ENCFF799QGA.hic",
"name": "in-situ agar GM12878 MboI experiment",
// "name": "in-situ agar GM12878 MboI experiment",
Copy link

Copilot AI Nov 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Property "name" is commented out but should either be removed entirely or have an explanation for why it's commented out. Leaving commented-out code reduces maintainability.

Suggested change
// "name": "in-situ agar GM12878 MboI experiment",

Copilot uses AI. Check for mistakes.
for (i = 0; i < resolutions.length; i++) {
if (this.browser.state.zoom === resolutions[i].index) break;
}
if (i !== undefined) {
Copy link

Copilot AI Nov 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This guard always evaluates to true.

Suggested change
if (i !== undefined) {
if (i < resolutions.length) {

Copilot uses AI. Check for mistakes.
* @param {boolean} eventData.dragging - Whether currently dragging
*/
notifyLocusChange(eventData) {
const { state, resolutionChanged, chrChanged, dragging } = eventData;
Copy link

Copilot AI Nov 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused variable dragging.

Suggested change
const { state, resolutionChanged, chrChanged, dragging } = eventData;
const { state, resolutionChanged, chrChanged } = eventData;

Copilot uses AI. Check for mistakes.
this.updating = false;
if (this.pending.size > 0) {
const queued = [];
for (let [k, v] of this.pending) {
Copy link

Copilot AI Nov 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused variable k.

Suggested change
for (let [k, v] of this.pending) {
for (let v of this.pending.values()) {

Copilot uses AI. Check for mistakes.

import { describe, test, expect } from 'vitest';
import { extractConfig } from "../js/urlUtils.js";
import { restoreSession } from "../js/session.js";
Copy link

Copilot AI Nov 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused import restoreSession.

Copilot uses AI. Check for mistakes.
Copy link

Copilot AI commented Nov 12, 2025

@turner I've opened a new pull request, #405, to work on those changes. Once the pull request is ready, I'll request review from you.

@turner turner closed this Nov 12, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants