@thoughtspot/visual-embed-sdk 1.52.2-beta.1 → 1.52.2-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/cjs/package.json +1 -1
  2. package/cjs/src/embed/liveboard.d.ts +12 -15
  3. package/cjs/src/embed/liveboard.d.ts.map +1 -1
  4. package/cjs/src/embed/liveboard.js +18 -2
  5. package/cjs/src/embed/liveboard.js.map +1 -1
  6. package/cjs/src/embed/liveboard.spec.js +25 -0
  7. package/cjs/src/embed/liveboard.spec.js.map +1 -1
  8. package/cjs/src/embed/ts-embed.spec.d.ts.map +1 -1
  9. package/cjs/src/embed/ts-embed.spec.js +10 -15
  10. package/cjs/src/embed/ts-embed.spec.js.map +1 -1
  11. package/dist/{index-Bt56pC82.js → index-CnHREfvN.js} +1 -1
  12. package/dist/src/embed/liveboard.d.ts +12 -15
  13. package/dist/src/embed/liveboard.d.ts.map +1 -1
  14. package/dist/src/embed/ts-embed.spec.d.ts.map +1 -1
  15. package/dist/tsembed-react.es.js +21 -5
  16. package/dist/tsembed-react.js +20 -4
  17. package/dist/tsembed.es.js +21 -5
  18. package/dist/tsembed.js +20 -4
  19. package/dist/visual-embed-sdk-react-full.d.ts +12 -0
  20. package/dist/visual-embed-sdk-react.d.ts +12 -0
  21. package/dist/visual-embed-sdk.d.ts +12 -15
  22. package/lib/package.json +1 -1
  23. package/lib/src/embed/liveboard.d.ts +12 -15
  24. package/lib/src/embed/liveboard.d.ts.map +1 -1
  25. package/lib/src/embed/liveboard.js +18 -2
  26. package/lib/src/embed/liveboard.js.map +1 -1
  27. package/lib/src/embed/liveboard.spec.js +25 -0
  28. package/lib/src/embed/liveboard.spec.js.map +1 -1
  29. package/lib/src/embed/ts-embed.spec.d.ts.map +1 -1
  30. package/lib/src/embed/ts-embed.spec.js +10 -15
  31. package/lib/src/embed/ts-embed.spec.js.map +1 -1
  32. package/lib/src/visual-embed-sdk.d.ts +12 -15
  33. package/package.json +1 -1
  34. package/src/embed/liveboard.spec.ts +30 -0
  35. package/src/embed/liveboard.ts +22 -3
  36. package/src/embed/ts-embed.spec.ts +11 -18
@@ -15672,21 +15672,6 @@ export interface LiveboardViewConfig extends BaseViewConfig, FullHeightViewConfi
15672
15672
  */
15673
15673
  updatedSpotterExperience?: boolean;
15674
15674
  }
15675
- /**
15676
- * Embed a ThoughtSpot Liveboard or visualization. When rendered it already
15677
- * waits for the authentication to complete, so you need not wait for
15678
- * `AuthStatus.SUCCESS`.
15679
- * @group Embed components
15680
- * @example
15681
- * ```js
15682
- * import { .. } from '@thoughtspot/visual-embed-sdk';
15683
- * init({ ... });
15684
- * const embed = new LiveboardEmbed("#container", {
15685
- * liveboardId: <your-id-here>,
15686
- * // .. other params here.
15687
- * })
15688
- * ```
15689
- */
15690
15675
  export class LiveboardEmbed extends V1Embed {
15691
15676
  protected viewConfig: LiveboardViewConfig;
15692
15677
  private readonly fullHeightController?;
@@ -15718,6 +15703,18 @@ export class LiveboardEmbed extends V1Embed {
15718
15703
  personalizedViewId: string;
15719
15704
  };
15720
15705
  protected beforePrerenderVisible(): void;
15706
+ /**
15707
+ * Whether `previous` was showing what this instance is about to show.
15708
+ *
15709
+ * Undefined-valued keys are dropped before comparing. `navigateToLiveboard`
15710
+ * assigns `vizId`, `activeTabId` and `personalizedViewId` unconditionally,
15711
+ * so an instance that has been shown once carries those keys as `undefined`
15712
+ * while a freshly constructed one does not have them at all. `isEqual`
15713
+ * counts own keys, so without this the comparison can never be true after
15714
+ * the first show — which is the whole case this exists for.
15715
+ *
15716
+ * Callbacks compare as equal: React passes a fresh closure per render.
15717
+ */
15721
15718
  private isSameEmbedConfig;
15722
15719
  private isShowingLiveboardRoute;
15723
15720
  protected handleRenderForPrerender(): Promise<TsEmbed>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thoughtspot/visual-embed-sdk",
3
- "version": "1.52.2-beta.1",
3
+ "version": "1.52.2-beta.2",
4
4
  "description": "ThoughtSpot Embed SDK",
5
5
  "module": "lib/src/index.js",
6
6
  "main": "dist/tsembed.js",
@@ -2777,6 +2777,36 @@ describe('Liveboard/viz embed tests', () => {
2777
2777
  expect(navigateToLiveboardSpy).toHaveBeenCalled();
2778
2778
  });
2779
2779
 
2780
+ test('should not route via home when the previous instance has been shown once', async () => {
2781
+ // navigateToLiveboard assigns vizId/activeTabId/personalizedViewId
2782
+ // unconditionally, so a shown instance carries them as undefined
2783
+ // while a fresh one lacks the keys entirely. Comparing raw objects
2784
+ // counts own keys, so it never matches again.
2785
+ const viewConfig = { liveboardId, ...defaultViewConfig };
2786
+ const previous = new LiveboardEmbed(getRootEl(), { ...viewConfig } as any);
2787
+ (previous as any).viewConfig.vizId = undefined;
2788
+ (previous as any).viewConfig.activeTabId = undefined;
2789
+ (previous as any).viewConfig.personalizedViewId = undefined;
2790
+
2791
+ const liveboardEmbed = new LiveboardEmbed(getRootEl(), { ...viewConfig } as any);
2792
+
2793
+ jest.spyOn(liveboardEmbed as any, 'getPreRenderObj').mockReturnValue(previous);
2794
+ const triggerSpy = jest
2795
+ .spyOn(liveboardEmbed, 'trigger')
2796
+ .mockImplementation(() => Promise.resolve(undefined as any));
2797
+ jest
2798
+ .spyOn(liveboardEmbed, 'navigateToLiveboard')
2799
+ .mockImplementation(() => Promise.resolve(undefined));
2800
+
2801
+ liveboardEmbed.isEmbedContainerLoaded = false;
2802
+ liveboardEmbed['beforePrerenderVisible']();
2803
+ liveboardEmbed.isEmbedContainerLoaded = true;
2804
+ liveboardEmbed['executeEmbedContainerReadyCallbacks']();
2805
+ await waitForPreRenderNavigate();
2806
+
2807
+ expect(triggerSpy).not.toHaveBeenCalledWith(HostEvent.Navigate, 'home');
2808
+ });
2809
+
2780
2810
  test('should route via home when a new instance shows the same route with other filters', async () => {
2781
2811
  const viewConfig = {
2782
2812
  liveboardId,
@@ -563,6 +563,14 @@ export interface LiveboardViewConfig
563
563
  * })
564
564
  * ```
565
565
  */
566
+ /**
567
+ * A shallow copy without the keys whose value is `undefined`, so a key that was
568
+ * assigned `undefined` compares equal to one that was never set.
569
+ */
570
+ const definedEntries = (config: Record<string, any> = {}): Record<string, any> => Object.fromEntries(
571
+ Object.entries(config).filter(([, value]) => value !== undefined),
572
+ );
573
+
566
574
  export class LiveboardEmbed extends V1Embed {
567
575
  protected viewConfig: LiveboardViewConfig;
568
576
 
@@ -995,13 +1003,24 @@ export class LiveboardEmbed extends V1Embed {
995
1003
  });
996
1004
  }
997
1005
 
998
- // Callbacks are compared as equal: React passes a fresh closure per render.
1006
+ /**
1007
+ * Whether `previous` was showing what this instance is about to show.
1008
+ *
1009
+ * Undefined-valued keys are dropped before comparing. `navigateToLiveboard`
1010
+ * assigns `vizId`, `activeTabId` and `personalizedViewId` unconditionally,
1011
+ * so an instance that has been shown once carries those keys as `undefined`
1012
+ * while a freshly constructed one does not have them at all. `isEqual`
1013
+ * counts own keys, so without this the comparison can never be true after
1014
+ * the first show — which is the whole case this exists for.
1015
+ *
1016
+ * Callbacks compare as equal: React passes a fresh closure per render.
1017
+ */
999
1018
  private isSameEmbedConfig(previous?: LiveboardEmbed): boolean {
1000
1019
  if (!previous) return false;
1001
1020
  if (previous === this) return true;
1002
1021
  return isEqualWith(
1003
- previous.viewConfig,
1004
- this.viewConfig,
1022
+ definedEntries(previous.viewConfig),
1023
+ definedEntries(this.viewConfig),
1005
1024
  (a, b) => (typeof a === 'function' && typeof b === 'function' ? true : undefined),
1006
1025
  );
1007
1026
  }
@@ -71,10 +71,6 @@ import * as processData from '../utils/processData';
71
71
  jest.mock('../utils/processTrigger');
72
72
 
73
73
  const mockProcessTrigger = processTrigger as jest.Mock;
74
-
75
- const flushAnimationFrame = () => new Promise<void>((resolve) => {
76
- requestAnimationFrame(() => resolve());
77
- });
78
74
  const mockHandleInterceptEvent = jest.spyOn(apiIntercept, 'handleInterceptEvent');
79
75
  const defaultViewConfig = {
80
76
  frameParams: {
@@ -2624,9 +2620,6 @@ describe('Unit test case for ts embed', () => {
2624
2620
  contentRect: { height: 297, width: 987 },
2625
2621
  },
2626
2622
  ]);
2627
- // Syncs are coalesced to one per frame.
2628
- await flushAnimationFrame();
2629
-
2630
2623
  expect(preRenderWrapper.style.height).toEqual(`${297}px`);
2631
2624
  expect(preRenderWrapper.style.width).toEqual(`${987}px`);
2632
2625
 
@@ -2887,28 +2880,28 @@ describe('Unit test case for ts embed', () => {
2887
2880
  return placeholder;
2888
2881
  };
2889
2882
 
2890
- it('should stop tracking once the frame is hidden', async () => {
2891
- const { scroller, readPlaceholderTop } = mountInNestedScroller();
2883
+ it('should stop observing the placeholder once the frame is hidden', async () => {
2884
+ const { scroller } = mountInNestedScroller();
2892
2885
 
2893
2886
  const libEmbed = new LiveboardEmbed('#tsEmbedDiv', {
2894
- preRenderId: 'scroll-stops-on-hide',
2887
+ preRenderId: 'observer-stops-on-hide',
2895
2888
  liveboardId: 'myLiveboardId',
2896
2889
  });
2897
2890
  libEmbed.preRender();
2898
2891
  await waitFor(() => !!getIFrameEl());
2899
2892
  await libEmbed.showPreRender();
2900
2893
 
2901
- stubPlaceholderRect(libEmbed, readPlaceholderTop);
2902
- libEmbed.hidePreRender();
2894
+ // Size is the only thing the browser will not handle for us, so
2895
+ // the observer is the one live resource a hide has to release.
2896
+ const observer = (libEmbed as any).resizeObserver;
2897
+ expect(observer).toBeDefined();
2898
+ const disconnectSpy = jest.spyOn(observer, 'disconnect');
2903
2899
 
2904
- const syncSpy = jest.spyOn(libEmbed, 'syncPreRenderStyle');
2905
- scroller.scrollTop = 250;
2906
- scroller.dispatchEvent(new Event('scroll'));
2907
- await flushAnimationFrame();
2900
+ libEmbed.hidePreRender();
2908
2901
 
2909
- expect(syncSpy).not.toHaveBeenCalled();
2902
+ expect(disconnectSpy).toHaveBeenCalled();
2910
2903
 
2911
- syncSpy.mockRestore();
2904
+ disconnectSpy.mockRestore();
2912
2905
  libEmbed.destroy();
2913
2906
  scroller.remove();
2914
2907
  });