diff --git a/visual-embed/host-event-parameterized/README.md b/visual-embed/host-event-parameterized/README.md index 77c6d78..9eb7b9e 100644 --- a/visual-embed/host-event-parameterized/README.md +++ b/visual-embed/host-event-parameterized/README.md @@ -46,6 +46,8 @@ const App = () => { }; ``` +> **Triggering host events at load time?** These examples are button-driven, so no readiness handling is needed. For triggers fired automatically at load, use the `subscribedEvent` readiness pattern (requires `useHostEventsV2: true`) — see [update-filters-and-params](../update-filters-and-params/README.md). + ## Documentation - [Host Event Parameterization](https://developers.thoughtspot.com/docs/events-app-integration#hostEventParameterization) diff --git a/visual-embed/liveboard/package-lock.json b/visual-embed/liveboard/package-lock.json index d6a6044..73b3dd4 100644 --- a/visual-embed/liveboard/package-lock.json +++ b/visual-embed/liveboard/package-lock.json @@ -8,7 +8,7 @@ "name": "liveboard", "version": "0.0.0", "dependencies": { - "@thoughtspot/visual-embed-sdk": "*", + "@thoughtspot/visual-embed-sdk": "^1.50.1", "react": "^19.0.0", "react-dom": "^19.0.0", "react-router": "^7.5.2" @@ -21,139 +21,6 @@ "vite": "^6.3.5" } }, - "node_modules/@algolia/cache-browser-local-storage": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.24.0.tgz", - "integrity": "sha512-t63W9BnoXVrGy9iYHBgObNXqYXM3tYXCjDSHeNwnsc324r4o5UiVKUiAB4THQ5z9U5hTj6qUvwg/Ez43ZD85ww==", - "dependencies": { - "@algolia/cache-common": "4.24.0" - } - }, - "node_modules/@algolia/cache-common": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/cache-common/-/cache-common-4.24.0.tgz", - "integrity": "sha512-emi+v+DmVLpMGhp0V9q9h5CdkURsNmFC+cOS6uK9ndeJm9J4TiqSvPYVu+THUP8P/S08rxf5x2P+p3CfID0Y4g==" - }, - "node_modules/@algolia/cache-in-memory": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/cache-in-memory/-/cache-in-memory-4.24.0.tgz", - "integrity": "sha512-gDrt2so19jW26jY3/MkFg5mEypFIPbPoXsQGQWAi6TrCPsNOSEYepBMPlucqWigsmEy/prp5ug2jy/N3PVG/8w==", - "dependencies": { - "@algolia/cache-common": "4.24.0" - } - }, - "node_modules/@algolia/client-account": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/client-account/-/client-account-4.24.0.tgz", - "integrity": "sha512-adcvyJ3KjPZFDybxlqnf+5KgxJtBjwTPTeyG2aOyoJvx0Y8dUQAEOEVOJ/GBxX0WWNbmaSrhDURMhc+QeevDsA==", - "dependencies": { - "@algolia/client-common": "4.24.0", - "@algolia/client-search": "4.24.0", - "@algolia/transporter": "4.24.0" - } - }, - "node_modules/@algolia/client-analytics": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-4.24.0.tgz", - "integrity": "sha512-y8jOZt1OjwWU4N2qr8G4AxXAzaa8DBvyHTWlHzX/7Me1LX8OayfgHexqrsL4vSBcoMmVw2XnVW9MhL+Y2ZDJXg==", - "dependencies": { - "@algolia/client-common": "4.24.0", - "@algolia/client-search": "4.24.0", - "@algolia/requester-common": "4.24.0", - "@algolia/transporter": "4.24.0" - } - }, - "node_modules/@algolia/client-common": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.24.0.tgz", - "integrity": "sha512-bc2ROsNL6w6rqpl5jj/UywlIYC21TwSSoFHKl01lYirGMW+9Eek6r02Tocg4gZ8HAw3iBvu6XQiM3BEbmEMoiA==", - "dependencies": { - "@algolia/requester-common": "4.24.0", - "@algolia/transporter": "4.24.0" - } - }, - "node_modules/@algolia/client-personalization": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-4.24.0.tgz", - "integrity": "sha512-l5FRFm/yngztweU0HdUzz1rC4yoWCFo3IF+dVIVTfEPg906eZg5BOd1k0K6rZx5JzyyoP4LdmOikfkfGsKVE9w==", - "dependencies": { - "@algolia/client-common": "4.24.0", - "@algolia/requester-common": "4.24.0", - "@algolia/transporter": "4.24.0" - } - }, - "node_modules/@algolia/client-search": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.24.0.tgz", - "integrity": "sha512-uRW6EpNapmLAD0mW47OXqTP8eiIx5F6qN9/x/7HHO6owL3N1IXqydGwW5nhDFBrV+ldouro2W1VX3XlcUXEFCA==", - "dependencies": { - "@algolia/client-common": "4.24.0", - "@algolia/requester-common": "4.24.0", - "@algolia/transporter": "4.24.0" - } - }, - "node_modules/@algolia/logger-common": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/logger-common/-/logger-common-4.24.0.tgz", - "integrity": "sha512-LLUNjkahj9KtKYrQhFKCzMx0BY3RnNP4FEtO+sBybCjJ73E8jNdaKJ/Dd8A/VA4imVHP5tADZ8pn5B8Ga/wTMA==" - }, - "node_modules/@algolia/logger-console": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/logger-console/-/logger-console-4.24.0.tgz", - "integrity": "sha512-X4C8IoHgHfiUROfoRCV+lzSy+LHMgkoEEU1BbKcsfnV0i0S20zyy0NLww9dwVHUWNfPPxdMU+/wKmLGYf96yTg==", - "dependencies": { - "@algolia/logger-common": "4.24.0" - } - }, - "node_modules/@algolia/recommend": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/recommend/-/recommend-4.24.0.tgz", - "integrity": "sha512-P9kcgerfVBpfYHDfVZDvvdJv0lEoCvzNlOy2nykyt5bK8TyieYyiD0lguIJdRZZYGre03WIAFf14pgE+V+IBlw==", - "dependencies": { - "@algolia/cache-browser-local-storage": "4.24.0", - "@algolia/cache-common": "4.24.0", - "@algolia/cache-in-memory": "4.24.0", - "@algolia/client-common": "4.24.0", - "@algolia/client-search": "4.24.0", - "@algolia/logger-common": "4.24.0", - "@algolia/logger-console": "4.24.0", - "@algolia/requester-browser-xhr": "4.24.0", - "@algolia/requester-common": "4.24.0", - "@algolia/requester-node-http": "4.24.0", - "@algolia/transporter": "4.24.0" - } - }, - "node_modules/@algolia/requester-browser-xhr": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.24.0.tgz", - "integrity": "sha512-Z2NxZMb6+nVXSjF13YpjYTdvV3032YTBSGm2vnYvYPA6mMxzM3v5rsCiSspndn9rzIW4Qp1lPHBvuoKJV6jnAA==", - "dependencies": { - "@algolia/requester-common": "4.24.0" - } - }, - "node_modules/@algolia/requester-common": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-common/-/requester-common-4.24.0.tgz", - "integrity": "sha512-k3CXJ2OVnvgE3HMwcojpvY6d9kgKMPRxs/kVohrwF5WMr2fnqojnycZkxPoEg+bXm8fi5BBfFmOqgYztRtHsQA==" - }, - "node_modules/@algolia/requester-node-http": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-4.24.0.tgz", - "integrity": "sha512-JF18yTjNOVYvU/L3UosRcvbPMGT9B+/GQWNWnenIImglzNVGpyzChkXLnrSf6uxwVNO6ESGu6oN8MqcGQcjQJw==", - "dependencies": { - "@algolia/requester-common": "4.24.0" - } - }, - "node_modules/@algolia/transporter": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/transporter/-/transporter-4.24.0.tgz", - "integrity": "sha512-86nI7w6NzWxd1Zp9q3413dRshDqAzSbsQjhcDhPIatEFiZrL1/TjnHL8S7jVKFePlIMzDsZWXAXwXzcok9c5oA==", - "dependencies": { - "@algolia/cache-common": "4.24.0", - "@algolia/logger-common": "4.24.0", - "@algolia/requester-common": "4.24.0" - } - }, "node_modules/@ampproject/remapping": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", @@ -377,14 +244,6 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/runtime": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.1.tgz", - "integrity": "sha512-J5AIf3vPj3UwXaAzb5j1xM4WAQDX3EMgemF8rjCP3SoW09LfRKAXQKt6CoVYl230P6iWdRcBbnLDDdnqWxZSCA==", - "dependencies": { - "regenerator-runtime": "^0.13.4" - } - }, "node_modules/@babel/template": { "version": "7.26.8", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.26.8.tgz", @@ -1201,20 +1060,19 @@ ] }, "node_modules/@thoughtspot/visual-embed-sdk": { - "version": "1.36.0", - "resolved": "https://registry.npmjs.org/@thoughtspot/visual-embed-sdk/-/visual-embed-sdk-1.36.0.tgz", - "integrity": "sha512-RdXjGBGkDRAtqZGSxhpDHtPaWzElFoSwaSddNlQ6Z5u1BVrYPsJD+Aw6DxMbcQwN8XWg6LVtT46M1SI/OgzuWQ==", + "version": "1.50.1", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/@thoughtspot/visual-embed-sdk/-/visual-embed-sdk-1.50.1.tgz", + "integrity": "sha512-T7Kndd/oiNDaQ9iJf5/p9jNS85Cz0NPahZnxSV16sZw9p3UGMgyS0BG6iUfcUIW7VUDE4zfkcieaGP9z6vgvRw==", + "license": "ThoughtSpot Development Tools End User License Agreement", "dependencies": { - "algoliasearch": "^4.10.5", "classnames": "^2.3.1", "eventemitter3": "^4.0.7", - "gatsby-plugin-vercel": "^1.0.3", - "lodash": "^4.17.21", + "lodash": "^4.18.1", "mixpanel-browser": "2.47.0", - "ts-deepmerge": "^6.0.2", + "ts-deepmerge": "^8.0.0", "tslib": "^2.5.3", "use-deep-compare-effect": "^1.8.1", - "yaml": "^2.5.1" + "yaml": "^2.9.0" }, "peerDependencies": { "react": "> 16.8.0", @@ -1312,28 +1170,6 @@ "vite": "^4.2.0 || ^5.0.0 || ^6.0.0" } }, - "node_modules/algoliasearch": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-4.24.0.tgz", - "integrity": "sha512-bf0QV/9jVejssFBmz2HQLxUadxk574t4iwjCKp5E7NBzwKkrDEhKPISIIjAU/p6K5qDx3qoeh4+26zWN1jmw3g==", - "dependencies": { - "@algolia/cache-browser-local-storage": "4.24.0", - "@algolia/cache-common": "4.24.0", - "@algolia/cache-in-memory": "4.24.0", - "@algolia/client-account": "4.24.0", - "@algolia/client-analytics": "4.24.0", - "@algolia/client-common": "4.24.0", - "@algolia/client-personalization": "4.24.0", - "@algolia/client-search": "4.24.0", - "@algolia/logger-common": "4.24.0", - "@algolia/logger-console": "4.24.0", - "@algolia/recommend": "4.24.0", - "@algolia/requester-browser-xhr": "4.24.0", - "@algolia/requester-common": "4.24.0", - "@algolia/requester-node-http": "4.24.0", - "@algolia/transporter": "4.24.0" - } - }, "node_modules/browserslist": { "version": "4.24.4", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz", @@ -1531,15 +1367,6 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "node_modules/gatsby-plugin-vercel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/gatsby-plugin-vercel/-/gatsby-plugin-vercel-1.0.4.tgz", - "integrity": "sha512-sqDAeBGOj68/FhgPh556n6TM2oCeD/dKafhaXKS1KQHtx+ro51CZ1FpqMcYDtPqm9MUnT43HkQnIGw2z6CRyPQ==", - "dependencies": { - "@babel/runtime": "7.12.1", - "web-vitals": "0.2.4" - } - }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -1589,9 +1416,10 @@ } }, "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + "version": "4.18.1", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/lodash/-/lodash-4.18.1.tgz", + "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", + "license": "MIT" }, "node_modules/lru-cache": { "version": "5.1.1", @@ -1737,11 +1565,6 @@ } } }, - "node_modules/regenerator-runtime": { - "version": "0.13.11", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" - }, "node_modules/rollup": { "version": "4.47.1", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.47.1.tgz", @@ -1829,9 +1652,10 @@ } }, "node_modules/ts-deepmerge": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ts-deepmerge/-/ts-deepmerge-6.2.1.tgz", - "integrity": "sha512-8CYSLazCyj0DJDpPIxOFzJG46r93uh6EynYjuey+bxcLltBeqZL7DMfaE5ZPzZNFlav7wx+2TDa/mBl8gkTYzw==", + "version": "8.0.0", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/ts-deepmerge/-/ts-deepmerge-8.0.0.tgz", + "integrity": "sha512-133O+10nJmVI8w5xeVZPEv5PIrv7iaUae07wv1aH8XJH95Ur6YIhWAPhPyP1YPlbPS9fCVcNIZTu7m8urRVF0A==", + "license": "ISC", "engines": { "node": ">=14.13.1" } @@ -1996,11 +1820,6 @@ } } }, - "node_modules/web-vitals": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-0.2.4.tgz", - "integrity": "sha512-6BjspCO9VriYy12z356nL6JBS0GYeEcA457YyRzD+dD6XYCQ75NKhcOHUMHentOE7OcVCIXXDvOm0jKFfQG2Gg==" - }, "node_modules/yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", @@ -2008,14 +1827,18 @@ "dev": true }, "node_modules/yaml": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.7.0.tgz", - "integrity": "sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==", + "version": "2.9.0", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/yaml/-/yaml-2.9.0.tgz", + "integrity": "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==", + "license": "ISC", "bin": { "yaml": "bin.mjs" }, "engines": { - "node": ">= 14" + "node": ">= 14.6" + }, + "funding": { + "url": "https://github.com/sponsors/eemeli" } } } diff --git a/visual-embed/liveboard/package.json b/visual-embed/liveboard/package.json index f6a3790..e8e6dbe 100644 --- a/visual-embed/liveboard/package.json +++ b/visual-embed/liveboard/package.json @@ -10,7 +10,7 @@ "preview": "vite preview" }, "dependencies": { - "@thoughtspot/visual-embed-sdk": "latest", + "@thoughtspot/visual-embed-sdk": "^1.50.1", "react": "^19.0.0", "react-dom": "^19.0.0", "react-router": "^7.5.2" diff --git a/visual-embed/liveboard/src/pages/EmbedWithReactWithOptions.tsx b/visual-embed/liveboard/src/pages/EmbedWithReactWithOptions.tsx index 24e748b..596579a 100644 --- a/visual-embed/liveboard/src/pages/EmbedWithReactWithOptions.tsx +++ b/visual-embed/liveboard/src/pages/EmbedWithReactWithOptions.tsx @@ -1,3 +1,4 @@ +import { useEffect } from "react"; import Header from "../components/Header"; import { EmbedEvent, HostEvent, LiveboardEmbed, RuntimeFilterOp, useEmbedRef } from "@thoughtspot/visual-embed-sdk/react"; @@ -5,7 +6,7 @@ function EmbedWithReactWithOptions() { const ref = useEmbedRef(); //apply runtime filters - + const runtimeFilters = [ { columnName: "state", @@ -13,18 +14,30 @@ function EmbedWithReactWithOptions() { values: ["michigan"], }, ]; - + const onLoad = () => { console.log(EmbedEvent.Load, {}); }; - - //Register an event handler to trigger the SetVisibleVizs event when the Liveboard is rendered - const onLiveboardRendered = () => { - ref.current.trigger(HostEvent.SetVisibleVizs, [ - "3f84d633-e325-44b2-be25-c6650e5a49cf", - "28b73b4a-1341-4535-ab71-f76b6fe7bf92", - ]); - }; + + // Standard pattern for triggering a host event at load time: listen for the + // " Subscribed" ready signal via subscribedEvent() — it fires the moment + // the embedded app has registered its handler, so the trigger cannot be dropped. + // Requires useHostEventsV2 on the embed (SDK 1.45.2+ / ThoughtSpot 26.3.0.cl+). + useEffect(() => { + const embed = ref.current; + if (!embed) return; + const subscribed = embed.subscribedEvent(HostEvent.SetVisibleVizs) as EmbedEvent; + const onReady = () => { + embed.trigger(HostEvent.SetVisibleVizs, [ + "3f84d633-e325-44b2-be25-c6650e5a49cf", + "28b73b4a-1341-4535-ab71-f76b6fe7bf92", + ]); + }; + embed.on(subscribed, onReady); + return () => { + embed.off(subscribed, onReady); + }; + }, []); return ( <> @@ -38,11 +51,11 @@ function EmbedWithReactWithOptions() { liveboardId={import.meta.env.VITE_LIVEBOARD_ID} runtimeFilters={runtimeFilters} onLoad={onLoad} - onLiveboardRendered={onLiveboardRendered} + useHostEventsV2 fullHeight={true} /> ) } -export default EmbedWithReactWithOptions; \ No newline at end of file +export default EmbedWithReactWithOptions; diff --git a/visual-embed/update-filters-and-params/README.md b/visual-embed/update-filters-and-params/README.md index cbf9b27..418ad55 100644 --- a/visual-embed/update-filters-and-params/README.md +++ b/visual-embed/update-filters-and-params/README.md @@ -1,6 +1,6 @@ @@ -28,10 +30,11 @@ Working patterns and a decision guide for applying **filters and parameters** to | Filters change after load (button, external UI) | **`HostEvent.UpdateRuntimeFilters`** — array of `{ columnName, operator, values }` | SDK 1.9.0 / TS 8.1.0.cl | | Updating values of a filter that already exists on the Liveboard | **`HostEvent.UpdateFilters`** — `{ filters: [{ column, oper, values }] }` | SDK 1.23.0 / TS 9.4.0.cl | | Parameter values change after load | **`HostEvent.UpdateParameters`** — array of `{ name, value, isVisibleToUser? }` | SDK 1.29.0 / TS 10.1.0.cl | -| You need the exact moment a host event is safe to trigger | **`embed.subscribedEvent(HostEvent.X)`** listener — **only fires when `useHostEventsV2: true` is set in the embed view config** | SDK 1.45.2+ / TS 26.3.0.cl+ | +| Triggering **any** host event at load time — the standard, recommended pattern | **`embed.subscribedEvent(HostEvent.X)`** listener — fires the exact moment the event is safe to trigger. **Only fires when `useHostEventsV2: true` is set in the embed view config** | SDK 1.45.2+ / TS 26.3.0.cl+ | Good to know: +- **The `subscribedEvent` readiness pattern works on every embed type** — it is defined on the shared embed base class, so `LiveboardEmbed`, `SearchEmbed`, `SearchBarEmbed`, `AppEmbed`, and `SpotterEmbed` all support it. Prefer it over ad-hoc `Load`/`Data`/`LiveboardRendered` timing for any load-time trigger. - **`UpdateRuntimeFilters` resets the embedded object to its original state** before applying the new conditions — user changes such as drill-downs are cleared. - If multiple columns share a name, disambiguate with the `WORKSHEET_NAME::COLUMN_NAME` format in `UpdateFilters` (e.g. `"(Sample) Retail - Apparel::city"`). - **Common pitfall:** wiring the `Subscribed` readiness listener **without** enabling `useHostEventsV2` — the listener silently never fires. On clusters older than 26.3.0.cl, trigger from `EmbedEvent.Load`/`EmbedEvent.Data` instead, guarded so it runs once. @@ -83,8 +86,11 @@ const App = () => { ]); }; - // READINESS — fires the moment the embedded app has registered its handler for - // the host event, so triggering is guaranteed safe. + // READINESS — the standard pattern for triggering ANY host event at load time, + // on ANY embed type (LiveboardEmbed, SearchEmbed, AppEmbed, SpotterEmbed — the + // method is on the shared embed base class). Fires the moment the embedded app + // has registered its handler, so the trigger cannot be dropped. Same pattern for + // UpdateParameters, UpdateRuntimeFilters, or any other host event. // REQUIRES useHostEventsV2: true on the embed (see props below) — without the // flag this " Subscribed" signal NEVER fires. useEffect(() => { diff --git a/visual-embed/update-filters-and-params/src/App.tsx b/visual-embed/update-filters-and-params/src/App.tsx index c128172..f4d0736 100644 --- a/visual-embed/update-filters-and-params/src/App.tsx +++ b/visual-embed/update-filters-and-params/src/App.tsx @@ -73,7 +73,10 @@ function App() { } }; - // READINESS — trigger UpdateFilters the moment the embedded app is ready for it. + // READINESS — the standard pattern for triggering ANY host event at load time, + // on ANY embed type (LiveboardEmbed, SearchEmbed, AppEmbed, SpotterEmbed — the + // method is on the shared embed base class). Same pattern for UpdateParameters, + // UpdateRuntimeFilters, or any other host event. // The " Subscribed" signal ONLY fires when useHostEventsV2 is enabled on // the embed (see the prop below); without the flag this listener never runs. useEffect(() => { diff --git a/visual-embed/visualization/package-lock.json b/visual-embed/visualization/package-lock.json index d3fef10..3c2e39c 100644 --- a/visual-embed/visualization/package-lock.json +++ b/visual-embed/visualization/package-lock.json @@ -8,7 +8,7 @@ "name": "visualization", "version": "0.0.0", "dependencies": { - "@thoughtspot/visual-embed-sdk": "*", + "@thoughtspot/visual-embed-sdk": "^1.50.1", "react": "^19.0.0", "react-dom": "^19.0.0", "react-router": "^7.5.2" @@ -21,139 +21,6 @@ "vite": "^6.3.5" } }, - "node_modules/@algolia/cache-browser-local-storage": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.24.0.tgz", - "integrity": "sha512-t63W9BnoXVrGy9iYHBgObNXqYXM3tYXCjDSHeNwnsc324r4o5UiVKUiAB4THQ5z9U5hTj6qUvwg/Ez43ZD85ww==", - "dependencies": { - "@algolia/cache-common": "4.24.0" - } - }, - "node_modules/@algolia/cache-common": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/cache-common/-/cache-common-4.24.0.tgz", - "integrity": "sha512-emi+v+DmVLpMGhp0V9q9h5CdkURsNmFC+cOS6uK9ndeJm9J4TiqSvPYVu+THUP8P/S08rxf5x2P+p3CfID0Y4g==" - }, - "node_modules/@algolia/cache-in-memory": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/cache-in-memory/-/cache-in-memory-4.24.0.tgz", - "integrity": "sha512-gDrt2so19jW26jY3/MkFg5mEypFIPbPoXsQGQWAi6TrCPsNOSEYepBMPlucqWigsmEy/prp5ug2jy/N3PVG/8w==", - "dependencies": { - "@algolia/cache-common": "4.24.0" - } - }, - "node_modules/@algolia/client-account": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/client-account/-/client-account-4.24.0.tgz", - "integrity": "sha512-adcvyJ3KjPZFDybxlqnf+5KgxJtBjwTPTeyG2aOyoJvx0Y8dUQAEOEVOJ/GBxX0WWNbmaSrhDURMhc+QeevDsA==", - "dependencies": { - "@algolia/client-common": "4.24.0", - "@algolia/client-search": "4.24.0", - "@algolia/transporter": "4.24.0" - } - }, - "node_modules/@algolia/client-analytics": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-4.24.0.tgz", - "integrity": "sha512-y8jOZt1OjwWU4N2qr8G4AxXAzaa8DBvyHTWlHzX/7Me1LX8OayfgHexqrsL4vSBcoMmVw2XnVW9MhL+Y2ZDJXg==", - "dependencies": { - "@algolia/client-common": "4.24.0", - "@algolia/client-search": "4.24.0", - "@algolia/requester-common": "4.24.0", - "@algolia/transporter": "4.24.0" - } - }, - "node_modules/@algolia/client-common": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.24.0.tgz", - "integrity": "sha512-bc2ROsNL6w6rqpl5jj/UywlIYC21TwSSoFHKl01lYirGMW+9Eek6r02Tocg4gZ8HAw3iBvu6XQiM3BEbmEMoiA==", - "dependencies": { - "@algolia/requester-common": "4.24.0", - "@algolia/transporter": "4.24.0" - } - }, - "node_modules/@algolia/client-personalization": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-4.24.0.tgz", - "integrity": "sha512-l5FRFm/yngztweU0HdUzz1rC4yoWCFo3IF+dVIVTfEPg906eZg5BOd1k0K6rZx5JzyyoP4LdmOikfkfGsKVE9w==", - "dependencies": { - "@algolia/client-common": "4.24.0", - "@algolia/requester-common": "4.24.0", - "@algolia/transporter": "4.24.0" - } - }, - "node_modules/@algolia/client-search": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.24.0.tgz", - "integrity": "sha512-uRW6EpNapmLAD0mW47OXqTP8eiIx5F6qN9/x/7HHO6owL3N1IXqydGwW5nhDFBrV+ldouro2W1VX3XlcUXEFCA==", - "dependencies": { - "@algolia/client-common": "4.24.0", - "@algolia/requester-common": "4.24.0", - "@algolia/transporter": "4.24.0" - } - }, - "node_modules/@algolia/logger-common": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/logger-common/-/logger-common-4.24.0.tgz", - "integrity": "sha512-LLUNjkahj9KtKYrQhFKCzMx0BY3RnNP4FEtO+sBybCjJ73E8jNdaKJ/Dd8A/VA4imVHP5tADZ8pn5B8Ga/wTMA==" - }, - "node_modules/@algolia/logger-console": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/logger-console/-/logger-console-4.24.0.tgz", - "integrity": "sha512-X4C8IoHgHfiUROfoRCV+lzSy+LHMgkoEEU1BbKcsfnV0i0S20zyy0NLww9dwVHUWNfPPxdMU+/wKmLGYf96yTg==", - "dependencies": { - "@algolia/logger-common": "4.24.0" - } - }, - "node_modules/@algolia/recommend": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/recommend/-/recommend-4.24.0.tgz", - "integrity": "sha512-P9kcgerfVBpfYHDfVZDvvdJv0lEoCvzNlOy2nykyt5bK8TyieYyiD0lguIJdRZZYGre03WIAFf14pgE+V+IBlw==", - "dependencies": { - "@algolia/cache-browser-local-storage": "4.24.0", - "@algolia/cache-common": "4.24.0", - "@algolia/cache-in-memory": "4.24.0", - "@algolia/client-common": "4.24.0", - "@algolia/client-search": "4.24.0", - "@algolia/logger-common": "4.24.0", - "@algolia/logger-console": "4.24.0", - "@algolia/requester-browser-xhr": "4.24.0", - "@algolia/requester-common": "4.24.0", - "@algolia/requester-node-http": "4.24.0", - "@algolia/transporter": "4.24.0" - } - }, - "node_modules/@algolia/requester-browser-xhr": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.24.0.tgz", - "integrity": "sha512-Z2NxZMb6+nVXSjF13YpjYTdvV3032YTBSGm2vnYvYPA6mMxzM3v5rsCiSspndn9rzIW4Qp1lPHBvuoKJV6jnAA==", - "dependencies": { - "@algolia/requester-common": "4.24.0" - } - }, - "node_modules/@algolia/requester-common": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-common/-/requester-common-4.24.0.tgz", - "integrity": "sha512-k3CXJ2OVnvgE3HMwcojpvY6d9kgKMPRxs/kVohrwF5WMr2fnqojnycZkxPoEg+bXm8fi5BBfFmOqgYztRtHsQA==" - }, - "node_modules/@algolia/requester-node-http": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-4.24.0.tgz", - "integrity": "sha512-JF18yTjNOVYvU/L3UosRcvbPMGT9B+/GQWNWnenIImglzNVGpyzChkXLnrSf6uxwVNO6ESGu6oN8MqcGQcjQJw==", - "dependencies": { - "@algolia/requester-common": "4.24.0" - } - }, - "node_modules/@algolia/transporter": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/transporter/-/transporter-4.24.0.tgz", - "integrity": "sha512-86nI7w6NzWxd1Zp9q3413dRshDqAzSbsQjhcDhPIatEFiZrL1/TjnHL8S7jVKFePlIMzDsZWXAXwXzcok9c5oA==", - "dependencies": { - "@algolia/cache-common": "4.24.0", - "@algolia/logger-common": "4.24.0", - "@algolia/requester-common": "4.24.0" - } - }, "node_modules/@ampproject/remapping": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", @@ -377,14 +244,6 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/runtime": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.1.tgz", - "integrity": "sha512-J5AIf3vPj3UwXaAzb5j1xM4WAQDX3EMgemF8rjCP3SoW09LfRKAXQKt6CoVYl230P6iWdRcBbnLDDdnqWxZSCA==", - "dependencies": { - "regenerator-runtime": "^0.13.4" - } - }, "node_modules/@babel/template": { "version": "7.26.8", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.26.8.tgz", @@ -1201,20 +1060,19 @@ ] }, "node_modules/@thoughtspot/visual-embed-sdk": { - "version": "1.36.1", - "resolved": "https://registry.npmjs.org/@thoughtspot/visual-embed-sdk/-/visual-embed-sdk-1.36.1.tgz", - "integrity": "sha512-g/DlHRNUycxvE6zetWqH0GhvnMK5mCDlI3Ry4FTK+zOJLIUFjN1gbp5R3qITuq842lGyOvOA3N6ZAoyQOu6vqw==", + "version": "1.50.1", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/@thoughtspot/visual-embed-sdk/-/visual-embed-sdk-1.50.1.tgz", + "integrity": "sha512-T7Kndd/oiNDaQ9iJf5/p9jNS85Cz0NPahZnxSV16sZw9p3UGMgyS0BG6iUfcUIW7VUDE4zfkcieaGP9z6vgvRw==", + "license": "ThoughtSpot Development Tools End User License Agreement", "dependencies": { - "algoliasearch": "^4.10.5", "classnames": "^2.3.1", "eventemitter3": "^4.0.7", - "gatsby-plugin-vercel": "^1.0.3", - "lodash": "^4.17.21", + "lodash": "^4.18.1", "mixpanel-browser": "2.47.0", - "ts-deepmerge": "^6.0.2", + "ts-deepmerge": "^8.0.0", "tslib": "^2.5.3", "use-deep-compare-effect": "^1.8.1", - "yaml": "^2.5.1" + "yaml": "^2.9.0" }, "peerDependencies": { "react": "> 16.8.0", @@ -1312,28 +1170,6 @@ "vite": "^4.2.0 || ^5.0.0 || ^6.0.0" } }, - "node_modules/algoliasearch": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-4.24.0.tgz", - "integrity": "sha512-bf0QV/9jVejssFBmz2HQLxUadxk574t4iwjCKp5E7NBzwKkrDEhKPISIIjAU/p6K5qDx3qoeh4+26zWN1jmw3g==", - "dependencies": { - "@algolia/cache-browser-local-storage": "4.24.0", - "@algolia/cache-common": "4.24.0", - "@algolia/cache-in-memory": "4.24.0", - "@algolia/client-account": "4.24.0", - "@algolia/client-analytics": "4.24.0", - "@algolia/client-common": "4.24.0", - "@algolia/client-personalization": "4.24.0", - "@algolia/client-search": "4.24.0", - "@algolia/logger-common": "4.24.0", - "@algolia/logger-console": "4.24.0", - "@algolia/recommend": "4.24.0", - "@algolia/requester-browser-xhr": "4.24.0", - "@algolia/requester-common": "4.24.0", - "@algolia/requester-node-http": "4.24.0", - "@algolia/transporter": "4.24.0" - } - }, "node_modules/browserslist": { "version": "4.24.4", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz", @@ -1531,15 +1367,6 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "node_modules/gatsby-plugin-vercel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/gatsby-plugin-vercel/-/gatsby-plugin-vercel-1.0.4.tgz", - "integrity": "sha512-sqDAeBGOj68/FhgPh556n6TM2oCeD/dKafhaXKS1KQHtx+ro51CZ1FpqMcYDtPqm9MUnT43HkQnIGw2z6CRyPQ==", - "dependencies": { - "@babel/runtime": "7.12.1", - "web-vitals": "0.2.4" - } - }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -1589,9 +1416,10 @@ } }, "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + "version": "4.18.1", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/lodash/-/lodash-4.18.1.tgz", + "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", + "license": "MIT" }, "node_modules/lru-cache": { "version": "5.1.1", @@ -1737,11 +1565,6 @@ } } }, - "node_modules/regenerator-runtime": { - "version": "0.13.11", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" - }, "node_modules/rollup": { "version": "4.47.1", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.47.1.tgz", @@ -1829,9 +1652,10 @@ } }, "node_modules/ts-deepmerge": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ts-deepmerge/-/ts-deepmerge-6.2.1.tgz", - "integrity": "sha512-8CYSLazCyj0DJDpPIxOFzJG46r93uh6EynYjuey+bxcLltBeqZL7DMfaE5ZPzZNFlav7wx+2TDa/mBl8gkTYzw==", + "version": "8.0.0", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/ts-deepmerge/-/ts-deepmerge-8.0.0.tgz", + "integrity": "sha512-133O+10nJmVI8w5xeVZPEv5PIrv7iaUae07wv1aH8XJH95Ur6YIhWAPhPyP1YPlbPS9fCVcNIZTu7m8urRVF0A==", + "license": "ISC", "engines": { "node": ">=14.13.1" } @@ -1996,11 +1820,6 @@ } } }, - "node_modules/web-vitals": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-0.2.4.tgz", - "integrity": "sha512-6BjspCO9VriYy12z356nL6JBS0GYeEcA457YyRzD+dD6XYCQ75NKhcOHUMHentOE7OcVCIXXDvOm0jKFfQG2Gg==" - }, "node_modules/yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", @@ -2008,14 +1827,18 @@ "dev": true }, "node_modules/yaml": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.7.0.tgz", - "integrity": "sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==", + "version": "2.9.0", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/yaml/-/yaml-2.9.0.tgz", + "integrity": "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==", + "license": "ISC", "bin": { "yaml": "bin.mjs" }, "engines": { - "node": ">= 14" + "node": ">= 14.6" + }, + "funding": { + "url": "https://github.com/sponsors/eemeli" } } } diff --git a/visual-embed/visualization/package.json b/visual-embed/visualization/package.json index c99431a..06a118c 100644 --- a/visual-embed/visualization/package.json +++ b/visual-embed/visualization/package.json @@ -10,7 +10,7 @@ "preview": "vite preview" }, "dependencies": { - "@thoughtspot/visual-embed-sdk": "latest", + "@thoughtspot/visual-embed-sdk": "^1.50.1", "react": "^19.0.0", "react-dom": "^19.0.0", "react-router": "^7.5.2" diff --git a/visual-embed/visualization/src/pages/EmbedViaReact.tsx b/visual-embed/visualization/src/pages/EmbedViaReact.tsx index a9f30a8..4e1590c 100644 --- a/visual-embed/visualization/src/pages/EmbedViaReact.tsx +++ b/visual-embed/visualization/src/pages/EmbedViaReact.tsx @@ -1,3 +1,4 @@ +import { useEffect } from "react"; import Header from "../components/Header"; import { EmbedEvent, HostEvent, LiveboardEmbed, RuntimeFilterOp, useEmbedRef } from "@thoughtspot/visual-embed-sdk/react"; @@ -18,11 +19,24 @@ function EmbedViaReact() { console.log(EmbedEvent.Load, {}); }; - const onLiveboardRendered = () => { - ref.current.trigger(HostEvent.Delete, { - vizId: import.meta.env.VITE_LIVEBOARD_VIZ_ID - }); - }; + // Standard pattern for triggering a host event at load time: listen for the + // " Subscribed" ready signal via subscribedEvent() — it fires the moment + // the embedded app has registered its handler, so the trigger cannot be dropped. + // Requires useHostEventsV2 on the embed (SDK 1.45.2+ / ThoughtSpot 26.3.0.cl+). + useEffect(() => { + const embed = ref.current; + if (!embed) return; + const subscribed = embed.subscribedEvent(HostEvent.Delete) as EmbedEvent; + const onReady = () => { + embed.trigger(HostEvent.Delete, { + vizId: import.meta.env.VITE_LIVEBOARD_VIZ_ID + }); + }; + embed.on(subscribed, onReady); + return () => { + embed.off(subscribed, onReady); + }; + }, []); return ( <> @@ -37,11 +51,11 @@ function EmbedViaReact() { runtimeFilters={runtimeFilters} liveboardId={import.meta.env.VITE_LIVEBOARD_ID} vizId={import.meta.env.VITE_LIVEBOARD_VIZ_ID} - onLiveboardRendered={onLiveboardRendered} + useHostEventsV2 onLoad={onLoad} /> ) } -export default EmbedViaReact; \ No newline at end of file +export default EmbedViaReact;