Skip to content

Conversation

@jbhanu-thoughtspot
Copy link
Contributor

No description provided.

@jbhanu-thoughtspot jbhanu-thoughtspot requested a review from a team as a code owner October 23, 2025 23:26
@mnk-blr
Copy link
Collaborator

mnk-blr commented Oct 23, 2025

Snyk checks have passed. No issues have been found so far.

Status Scanner Critical High Medium Low Total (0)
Licenses 0 0 0 0 0 issues
Open Source Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@gemini-code-assist
Copy link

Summary of Changes

Hello @jbhanu-thoughtspot, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request refines the embed destruction process by introducing more control over how embedded components are cleaned up. It allows developers to configure whether the system should wait for a cleanup event to complete before removing the embed's DOM element, providing a more robust and asynchronous cleanup mechanism. This ensures that all necessary internal resources can be properly released, improving the stability and lifecycle management of embedded applications.

Highlights

  • Configurable Cleanup on Destroy: Introduced new configuration options, waitForCleanupOnDestroy and cleanupTimeout, to control the behavior of embed destruction.
  • Enhanced Destroy Method: The destroy() method in TsEmbed now conditionally triggers a HostEvent.DestroyEmbed and can optionally wait for a specified timeout before removing the DOM element, allowing for asynchronous cleanup.
  • New Host Event: Added HostEvent.DestroyEmbed to signal when an embed is being destroyed, enabling internal cleanup processes.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a cleanup mechanism on embed destruction. I've found a critical issue in the timeout implementation for the cleanup, which acts as a delay instead and can lead to resource leaks. I've also identified a couple of medium-severity issues: a discrepancy in the default timeout value between the implementation and documentation, and an inconsistent naming for the new DestroyEmbed host event. I've provided suggestions to address these points.

Comment on lines 1335 to 1412
} else {
const cleanupTimeout = getEmbedConfig().cleanupTimeout;
setTimeout(() => {
this.trigger(HostEvent.DestroyEmbed).then(() => {
this.insertedDomEl?.parentNode?.removeChild(this.insertedDomEl);
}).catch((e) => {
logger.log('Error destroying TS Embed', e);
});
}, cleanupTimeout);
}

Choose a reason for hiding this comment

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

critical

The current implementation for handling waitForCleanupOnDestroy has a couple of issues:

  1. setTimeout is used to introduce a delay before triggering the cleanup, rather than acting as a timeout for the cleanup operation. The name cleanupTimeout suggests it should be a timeout.
  2. The DOM element this.insertedDomEl is only removed if the this.trigger(HostEvent.DestroyEmbed) promise resolves successfully. If it rejects or never resolves, the DOM element will leak.

I suggest refactoring this to use Promise.race to correctly implement the timeout and ensure the DOM element is always removed using .finally().

            } else {
                const timeout = getEmbedConfig().cleanupTimeout;
                const cleanupWithTimeout = Promise.race([
                    this.trigger(HostEvent.DestroyEmbed),
                    new Promise(resolve => setTimeout(() => {
                        logger.warn(`Cleanup on destroy timed out after ${timeout}ms.`);
                        resolve(undefined);
                    }, timeout)),
                ]);

                cleanupWithTimeout
                    .catch((e) => {
                        logger.log('Error during destroy cleanup', e);
                    })
                    .finally(() => {
                        this.insertedDomEl?.parentNode?.removeChild(this.insertedDomEl);
                    });
            }

authType: AuthType.None,
logLevel: LogLevel.ERROR,
waitForCleanupOnDestroy: false,
cleanupTimeout: 5000,

Choose a reason for hiding this comment

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

medium

The default value for cleanupTimeout is set to 5000 here, but the JSDoc for this property in src/types.ts on line 705 specifies a default of 10000. To ensure consistency between the code and documentation, please update the default value here to match the documentation.

Suggested change
cleanupTimeout: 5000,
cleanupTimeout: 10000,

* ```
* @version SDK: 1.41.0 | ThoughtSpot: 10.12.0.cl
*/
DestroyEmbed = 'EmbedDestroyed',

Choose a reason for hiding this comment

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

medium

The string value for HostEvent.DestroyEmbed is 'EmbedDestroyed'. This is a bit confusing as it sounds like an event coming from the embed, but HostEvents are sent to the embed. For consistency with other HostEvent members like AskSpotter = 'AskSpotter', consider changing the value to 'DestroyEmbed'.

Suggested change
DestroyEmbed = 'EmbedDestroyed',
DestroyEmbed = 'DestroyEmbed',

@pkg-pr-new
Copy link

pkg-pr-new bot commented Oct 23, 2025

Open in StackBlitz

npm i https://pkg.pr.new/thoughtspot/visual-embed-sdk/@thoughtspot/visual-embed-sdk@338

commit: 2700f43

@sonar-prod-ts
Copy link

sonar-prod-ts bot commented Oct 27, 2025

SonarQube Quality Gate

Quality Gate passed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 0 Code Smells

No Coverage information No Coverage information
0.0% 0.0% Duplication

@jbhanu-thoughtspot jbhanu-thoughtspot merged commit 6649d3a into main Oct 27, 2025
9 checks passed
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.

4 participants