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

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 (281) hide show
  1. package/cjs/package.json +1 -1
  2. package/cjs/src/contracts/contracts.spec.js +4 -0
  3. package/cjs/src/contracts/contracts.spec.js.map +1 -1
  4. package/cjs/src/contracts/host-event-contracts.d.ts +10 -0
  5. package/cjs/src/contracts/host-event-contracts.d.ts.map +1 -1
  6. package/cjs/src/css-variables.d.ts +373 -5
  7. package/cjs/src/css-variables.d.ts.map +1 -1
  8. package/cjs/src/embed/app.d.ts +15 -0
  9. package/cjs/src/embed/app.d.ts.map +1 -1
  10. package/cjs/src/embed/app.js +6 -3
  11. package/cjs/src/embed/app.js.map +1 -1
  12. package/cjs/src/embed/app.spec.js +28 -0
  13. package/cjs/src/embed/app.spec.js.map +1 -1
  14. package/cjs/src/embed/auto-frame-renderer.d.ts.map +1 -1
  15. package/cjs/src/embed/auto-frame-renderer.js +244 -4
  16. package/cjs/src/embed/auto-frame-renderer.js.map +1 -1
  17. package/cjs/src/embed/auto-frame-renderer.spec.js +389 -0
  18. package/cjs/src/embed/auto-frame-renderer.spec.js.map +1 -1
  19. package/cjs/src/embed/bodyless-conversation.js +1 -1
  20. package/cjs/src/embed/bodyless-conversation.js.map +1 -1
  21. package/cjs/src/embed/conversation.d.ts +29 -0
  22. package/cjs/src/embed/conversation.d.ts.map +1 -1
  23. package/cjs/src/embed/conversation.js +7 -3
  24. package/cjs/src/embed/conversation.js.map +1 -1
  25. package/cjs/src/embed/conversation.spec.js +88 -0
  26. package/cjs/src/embed/conversation.spec.js.map +1 -1
  27. package/cjs/src/embed/host-events.spec.js +32 -0
  28. package/cjs/src/embed/host-events.spec.js.map +1 -1
  29. package/cjs/src/embed/liveboard-override-utils.d.ts +59 -0
  30. package/cjs/src/embed/liveboard-override-utils.d.ts.map +1 -0
  31. package/cjs/src/embed/liveboard-override-utils.js +19 -0
  32. package/cjs/src/embed/liveboard-override-utils.js.map +1 -0
  33. package/cjs/src/embed/liveboard-override-utils.spec.d.ts +2 -0
  34. package/cjs/src/embed/liveboard-override-utils.spec.d.ts.map +1 -0
  35. package/cjs/src/embed/liveboard-override-utils.spec.js +34 -0
  36. package/cjs/src/embed/liveboard-override-utils.spec.js.map +1 -0
  37. package/cjs/src/embed/liveboard.d.ts +44 -13
  38. package/cjs/src/embed/liveboard.d.ts.map +1 -1
  39. package/cjs/src/embed/liveboard.js +19 -23
  40. package/cjs/src/embed/liveboard.js.map +1 -1
  41. package/cjs/src/embed/liveboard.spec.js +122 -0
  42. package/cjs/src/embed/liveboard.spec.js.map +1 -1
  43. package/cjs/src/embed/search-bar.js +1 -1
  44. package/cjs/src/embed/search-bar.js.map +1 -1
  45. package/cjs/src/embed/search.js +1 -1
  46. package/cjs/src/embed/search.js.map +1 -1
  47. package/cjs/src/embed/search.spec.js +20 -0
  48. package/cjs/src/embed/search.spec.js.map +1 -1
  49. package/cjs/src/embed/spotter-utils.d.ts +12 -0
  50. package/cjs/src/embed/spotter-utils.d.ts.map +1 -1
  51. package/cjs/src/embed/spotter-utils.js +20 -2
  52. package/cjs/src/embed/spotter-utils.js.map +1 -1
  53. package/cjs/src/embed/spotter-utils.spec.js +19 -0
  54. package/cjs/src/embed/spotter-utils.spec.js.map +1 -1
  55. package/cjs/src/embed/spotter-viz-utils.d.ts +15 -0
  56. package/cjs/src/embed/spotter-viz-utils.d.ts.map +1 -1
  57. package/cjs/src/embed/spotter-viz-utils.js.map +1 -1
  58. package/cjs/src/embed/spotter-viz-utils.spec.js +11 -0
  59. package/cjs/src/embed/spotter-viz-utils.spec.js.map +1 -1
  60. package/cjs/src/embed/ts-embed.d.ts +18 -20
  61. package/cjs/src/embed/ts-embed.d.ts.map +1 -1
  62. package/cjs/src/embed/ts-embed.js +181 -45
  63. package/cjs/src/embed/ts-embed.js.map +1 -1
  64. package/cjs/src/embed/ts-embed.spec.d.ts.map +1 -1
  65. package/cjs/src/embed/ts-embed.spec.js +610 -0
  66. package/cjs/src/embed/ts-embed.spec.js.map +1 -1
  67. package/cjs/src/index.d.ts +5 -3
  68. package/cjs/src/index.d.ts.map +1 -1
  69. package/cjs/src/index.js +4 -2
  70. package/cjs/src/index.js.map +1 -1
  71. package/cjs/src/mixpanel-service.d.ts +1 -0
  72. package/cjs/src/mixpanel-service.d.ts.map +1 -1
  73. package/cjs/src/mixpanel-service.js +1 -0
  74. package/cjs/src/mixpanel-service.js.map +1 -1
  75. package/cjs/src/react/all-types-export.d.ts +1 -1
  76. package/cjs/src/react/all-types-export.d.ts.map +1 -1
  77. package/cjs/src/react/all-types-export.js +2 -1
  78. package/cjs/src/react/all-types-export.js.map +1 -1
  79. package/cjs/src/types.d.ts +251 -4
  80. package/cjs/src/types.d.ts.map +1 -1
  81. package/cjs/src/types.js +176 -0
  82. package/cjs/src/types.js.map +1 -1
  83. package/cjs/src/utils/graphql/answerService/answer-queries.d.ts +1 -0
  84. package/cjs/src/utils/graphql/answerService/answer-queries.d.ts.map +1 -1
  85. package/cjs/src/utils/graphql/answerService/answer-queries.js +8 -1
  86. package/cjs/src/utils/graphql/answerService/answer-queries.js.map +1 -1
  87. package/cjs/src/utils/graphql/answerService/answerService.d.ts +28 -4
  88. package/cjs/src/utils/graphql/answerService/answerService.d.ts.map +1 -1
  89. package/cjs/src/utils/graphql/answerService/answerService.js +39 -4
  90. package/cjs/src/utils/graphql/answerService/answerService.js.map +1 -1
  91. package/cjs/src/utils/graphql/answerService/answerService.spec.js +124 -0
  92. package/cjs/src/utils/graphql/answerService/answerService.spec.js.map +1 -1
  93. package/cjs/src/utils/runtimeTelemetry.d.ts +11 -0
  94. package/cjs/src/utils/runtimeTelemetry.d.ts.map +1 -0
  95. package/cjs/src/utils/runtimeTelemetry.js +34 -0
  96. package/cjs/src/utils/runtimeTelemetry.js.map +1 -0
  97. package/cjs/src/utils/runtimeTelemetry.spec.d.ts +2 -0
  98. package/cjs/src/utils/runtimeTelemetry.spec.d.ts.map +1 -0
  99. package/cjs/src/utils/runtimeTelemetry.spec.js +124 -0
  100. package/cjs/src/utils/runtimeTelemetry.spec.js.map +1 -0
  101. package/dist/{index-CnHREfvN.js → index-CrBnZBZv.js} +1 -1
  102. package/dist/src/contracts/host-event-contracts.d.ts +10 -0
  103. package/dist/src/contracts/host-event-contracts.d.ts.map +1 -1
  104. package/dist/src/css-variables.d.ts +373 -5
  105. package/dist/src/css-variables.d.ts.map +1 -1
  106. package/dist/src/embed/app.d.ts +15 -0
  107. package/dist/src/embed/app.d.ts.map +1 -1
  108. package/dist/src/embed/auto-frame-renderer.d.ts.map +1 -1
  109. package/dist/src/embed/conversation.d.ts +29 -0
  110. package/dist/src/embed/conversation.d.ts.map +1 -1
  111. package/dist/src/embed/liveboard-override-utils.d.ts +59 -0
  112. package/dist/src/embed/liveboard-override-utils.d.ts.map +1 -0
  113. package/dist/src/embed/liveboard-override-utils.spec.d.ts +2 -0
  114. package/dist/src/embed/liveboard-override-utils.spec.d.ts.map +1 -0
  115. package/dist/src/embed/liveboard.d.ts +44 -13
  116. package/dist/src/embed/liveboard.d.ts.map +1 -1
  117. package/dist/src/embed/spotter-utils.d.ts +12 -0
  118. package/dist/src/embed/spotter-utils.d.ts.map +1 -1
  119. package/dist/src/embed/spotter-viz-utils.d.ts +15 -0
  120. package/dist/src/embed/spotter-viz-utils.d.ts.map +1 -1
  121. package/dist/src/embed/ts-embed.d.ts +18 -20
  122. package/dist/src/embed/ts-embed.d.ts.map +1 -1
  123. package/dist/src/embed/ts-embed.spec.d.ts.map +1 -1
  124. package/dist/src/index.d.ts +5 -3
  125. package/dist/src/index.d.ts.map +1 -1
  126. package/dist/src/mixpanel-service.d.ts +1 -0
  127. package/dist/src/mixpanel-service.d.ts.map +1 -1
  128. package/dist/src/react/all-types-export.d.ts +1 -1
  129. package/dist/src/react/all-types-export.d.ts.map +1 -1
  130. package/dist/src/types.d.ts +251 -4
  131. package/dist/src/types.d.ts.map +1 -1
  132. package/dist/src/utils/graphql/answerService/answer-queries.d.ts +1 -0
  133. package/dist/src/utils/graphql/answerService/answer-queries.d.ts.map +1 -1
  134. package/dist/src/utils/graphql/answerService/answerService.d.ts +28 -4
  135. package/dist/src/utils/graphql/answerService/answerService.d.ts.map +1 -1
  136. package/dist/src/utils/runtimeTelemetry.d.ts +11 -0
  137. package/dist/src/utils/runtimeTelemetry.d.ts.map +1 -0
  138. package/dist/src/utils/runtimeTelemetry.spec.d.ts +2 -0
  139. package/dist/src/utils/runtimeTelemetry.spec.d.ts.map +1 -0
  140. package/dist/tsembed-react.es.js +500 -85
  141. package/dist/tsembed-react.js +499 -84
  142. package/dist/tsembed.es.js +743 -90
  143. package/dist/tsembed.js +741 -88
  144. package/dist/visual-embed-sdk-react-full.d.ts +788 -44
  145. package/dist/visual-embed-sdk-react.d.ts +783 -44
  146. package/dist/visual-embed-sdk.d.ts +815 -45
  147. package/lib/package.json +1 -1
  148. package/lib/src/contracts/contracts.spec.js +4 -0
  149. package/lib/src/contracts/contracts.spec.js.map +1 -1
  150. package/lib/src/contracts/host-event-contracts.d.ts +10 -0
  151. package/lib/src/contracts/host-event-contracts.d.ts.map +1 -1
  152. package/lib/src/css-variables.d.ts +373 -5
  153. package/lib/src/css-variables.d.ts.map +1 -1
  154. package/lib/src/embed/app.d.ts +15 -0
  155. package/lib/src/embed/app.d.ts.map +1 -1
  156. package/lib/src/embed/app.js +7 -4
  157. package/lib/src/embed/app.js.map +1 -1
  158. package/lib/src/embed/app.spec.js +28 -0
  159. package/lib/src/embed/app.spec.js.map +1 -1
  160. package/lib/src/embed/auto-frame-renderer.d.ts.map +1 -1
  161. package/lib/src/embed/auto-frame-renderer.js +244 -4
  162. package/lib/src/embed/auto-frame-renderer.js.map +1 -1
  163. package/lib/src/embed/auto-frame-renderer.spec.js +389 -0
  164. package/lib/src/embed/auto-frame-renderer.spec.js.map +1 -1
  165. package/lib/src/embed/bodyless-conversation.js +1 -1
  166. package/lib/src/embed/bodyless-conversation.js.map +1 -1
  167. package/lib/src/embed/conversation.d.ts +29 -0
  168. package/lib/src/embed/conversation.d.ts.map +1 -1
  169. package/lib/src/embed/conversation.js +8 -4
  170. package/lib/src/embed/conversation.js.map +1 -1
  171. package/lib/src/embed/conversation.spec.js +89 -1
  172. package/lib/src/embed/conversation.spec.js.map +1 -1
  173. package/lib/src/embed/host-events.spec.js +32 -0
  174. package/lib/src/embed/host-events.spec.js.map +1 -1
  175. package/lib/src/embed/liveboard-override-utils.d.ts +59 -0
  176. package/lib/src/embed/liveboard-override-utils.d.ts.map +1 -0
  177. package/lib/src/embed/liveboard-override-utils.js +15 -0
  178. package/lib/src/embed/liveboard-override-utils.js.map +1 -0
  179. package/lib/src/embed/liveboard-override-utils.spec.d.ts +2 -0
  180. package/lib/src/embed/liveboard-override-utils.spec.d.ts.map +1 -0
  181. package/lib/src/embed/liveboard-override-utils.spec.js +32 -0
  182. package/lib/src/embed/liveboard-override-utils.spec.js.map +1 -0
  183. package/lib/src/embed/liveboard.d.ts +44 -13
  184. package/lib/src/embed/liveboard.d.ts.map +1 -1
  185. package/lib/src/embed/liveboard.js +19 -23
  186. package/lib/src/embed/liveboard.js.map +1 -1
  187. package/lib/src/embed/liveboard.spec.js +122 -0
  188. package/lib/src/embed/liveboard.spec.js.map +1 -1
  189. package/lib/src/embed/search-bar.js +1 -1
  190. package/lib/src/embed/search-bar.js.map +1 -1
  191. package/lib/src/embed/search.js +1 -1
  192. package/lib/src/embed/search.js.map +1 -1
  193. package/lib/src/embed/search.spec.js +20 -0
  194. package/lib/src/embed/search.spec.js.map +1 -1
  195. package/lib/src/embed/spotter-utils.d.ts +12 -0
  196. package/lib/src/embed/spotter-utils.d.ts.map +1 -1
  197. package/lib/src/embed/spotter-utils.js +19 -1
  198. package/lib/src/embed/spotter-utils.js.map +1 -1
  199. package/lib/src/embed/spotter-utils.spec.js +19 -0
  200. package/lib/src/embed/spotter-utils.spec.js.map +1 -1
  201. package/lib/src/embed/spotter-viz-utils.d.ts +15 -0
  202. package/lib/src/embed/spotter-viz-utils.d.ts.map +1 -1
  203. package/lib/src/embed/spotter-viz-utils.js.map +1 -1
  204. package/lib/src/embed/spotter-viz-utils.spec.js +11 -0
  205. package/lib/src/embed/spotter-viz-utils.spec.js.map +1 -1
  206. package/lib/src/embed/ts-embed.d.ts +18 -20
  207. package/lib/src/embed/ts-embed.d.ts.map +1 -1
  208. package/lib/src/embed/ts-embed.js +181 -45
  209. package/lib/src/embed/ts-embed.js.map +1 -1
  210. package/lib/src/embed/ts-embed.spec.d.ts.map +1 -1
  211. package/lib/src/embed/ts-embed.spec.js +611 -1
  212. package/lib/src/embed/ts-embed.spec.js.map +1 -1
  213. package/lib/src/index.d.ts +5 -3
  214. package/lib/src/index.d.ts.map +1 -1
  215. package/lib/src/index.js +3 -2
  216. package/lib/src/index.js.map +1 -1
  217. package/lib/src/mixpanel-service.d.ts +1 -0
  218. package/lib/src/mixpanel-service.d.ts.map +1 -1
  219. package/lib/src/mixpanel-service.js +1 -0
  220. package/lib/src/mixpanel-service.js.map +1 -1
  221. package/lib/src/react/all-types-export.d.ts +1 -1
  222. package/lib/src/react/all-types-export.d.ts.map +1 -1
  223. package/lib/src/react/all-types-export.js +1 -1
  224. package/lib/src/react/all-types-export.js.map +1 -1
  225. package/lib/src/types.d.ts +251 -4
  226. package/lib/src/types.d.ts.map +1 -1
  227. package/lib/src/types.js +176 -0
  228. package/lib/src/types.js.map +1 -1
  229. package/lib/src/utils/graphql/answerService/answer-queries.d.ts +1 -0
  230. package/lib/src/utils/graphql/answerService/answer-queries.d.ts.map +1 -1
  231. package/lib/src/utils/graphql/answerService/answer-queries.js +7 -0
  232. package/lib/src/utils/graphql/answerService/answer-queries.js.map +1 -1
  233. package/lib/src/utils/graphql/answerService/answerService.d.ts +28 -4
  234. package/lib/src/utils/graphql/answerService/answerService.d.ts.map +1 -1
  235. package/lib/src/utils/graphql/answerService/answerService.js +39 -4
  236. package/lib/src/utils/graphql/answerService/answerService.js.map +1 -1
  237. package/lib/src/utils/graphql/answerService/answerService.spec.js +125 -1
  238. package/lib/src/utils/graphql/answerService/answerService.spec.js.map +1 -1
  239. package/lib/src/utils/runtimeTelemetry.d.ts +11 -0
  240. package/lib/src/utils/runtimeTelemetry.d.ts.map +1 -0
  241. package/lib/src/utils/runtimeTelemetry.js +28 -0
  242. package/lib/src/utils/runtimeTelemetry.js.map +1 -0
  243. package/lib/src/utils/runtimeTelemetry.spec.d.ts +2 -0
  244. package/lib/src/utils/runtimeTelemetry.spec.d.ts.map +1 -0
  245. package/lib/src/utils/runtimeTelemetry.spec.js +122 -0
  246. package/lib/src/utils/runtimeTelemetry.spec.js.map +1 -0
  247. package/lib/src/visual-embed-sdk.d.ts +815 -45
  248. package/package.json +1 -1
  249. package/src/contracts/contracts.spec.ts +4 -0
  250. package/src/contracts/host-event-contracts.ts +13 -0
  251. package/src/css-variables.ts +475 -26
  252. package/src/embed/app.spec.ts +32 -0
  253. package/src/embed/app.ts +29 -4
  254. package/src/embed/auto-frame-renderer.spec.ts +464 -0
  255. package/src/embed/auto-frame-renderer.ts +305 -6
  256. package/src/embed/bodyless-conversation.ts +1 -1
  257. package/src/embed/conversation.spec.ts +118 -1
  258. package/src/embed/conversation.ts +42 -3
  259. package/src/embed/host-events.spec.ts +44 -0
  260. package/src/embed/liveboard-override-utils.spec.ts +38 -0
  261. package/src/embed/liveboard-override-utils.ts +71 -0
  262. package/src/embed/liveboard.spec.ts +138 -0
  263. package/src/embed/liveboard.ts +64 -24
  264. package/src/embed/search-bar.tsx +1 -1
  265. package/src/embed/search.spec.ts +23 -0
  266. package/src/embed/search.ts +1 -1
  267. package/src/embed/spotter-utils.spec.ts +20 -0
  268. package/src/embed/spotter-utils.ts +24 -1
  269. package/src/embed/spotter-viz-utils.spec.ts +11 -0
  270. package/src/embed/spotter-viz-utils.ts +15 -0
  271. package/src/embed/ts-embed.spec.ts +767 -0
  272. package/src/embed/ts-embed.ts +186 -41
  273. package/src/index.ts +18 -1
  274. package/src/mixpanel-service.ts +1 -0
  275. package/src/react/all-types-export.ts +7 -0
  276. package/src/types.ts +254 -5
  277. package/src/utils/graphql/answerService/answer-queries.ts +8 -0
  278. package/src/utils/graphql/answerService/answerService.spec.ts +145 -1
  279. package/src/utils/graphql/answerService/answerService.ts +65 -3
  280. package/src/utils/runtimeTelemetry.spec.ts +148 -0
  281. package/src/utils/runtimeTelemetry.ts +50 -0
package/dist/tsembed.js CHANGED
@@ -1,4 +1,4 @@
1
- /* @thoughtspot/visual-embed-sdk version 1.52.2-beta.2 */
1
+ /* @thoughtspot/visual-embed-sdk version 1.53.1 */
2
2
  'use client';
3
3
  (function (global, factory) {
4
4
  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
@@ -1214,6 +1214,36 @@
1214
1214
  * ```
1215
1215
  */
1216
1216
  EmbedEvent["Edit"] = "edit";
1217
+ /**
1218
+ * Emitted when a user clicks **Edit** on a Liveboard.
1219
+ *
1220
+ * Fired alongside {@link EmbedEvent.Edit} for backward compatibility;
1221
+ * listen to this instead of `Edit` to target the Liveboard surface only.
1222
+ * @version SDK: 1.54.0 | ThoughtSpot Cloud: 26.11.0.cl
1223
+ * @example
1224
+ * ```js
1225
+ * liveboardEmbed.on(EmbedEvent.EditLiveboard, payload => {
1226
+ * console.log('Liveboard edit', payload);
1227
+ * })
1228
+ * ```
1229
+ */
1230
+ EmbedEvent["EditLiveboard"] = "editLiveboard";
1231
+ /**
1232
+ * Emitted when a user clicks **Edit** on a visualization inside a
1233
+ * Liveboard.
1234
+ *
1235
+ * Fired alongside {@link EmbedEvent.Edit} for backward compatibility;
1236
+ * listen to this instead of `Edit` to target the visualization surface
1237
+ * only.
1238
+ * @version SDK: 1.54.0 | ThoughtSpot Cloud: 26.11.0.cl
1239
+ * @example
1240
+ * ```js
1241
+ * liveboardEmbed.on(EmbedEvent.EditVisualization, payload => {
1242
+ * console.log('visualization edit', payload);
1243
+ * })
1244
+ * ```
1245
+ */
1246
+ EmbedEvent["EditVisualization"] = "editVisualization";
1217
1247
  /**
1218
1248
  * Emitted when a user clicks *Make a copy* on a Liveboard
1219
1249
  * @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl, 8.8.1.sw
@@ -3185,6 +3215,46 @@
3185
3215
  * @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl, 8.8.1.sw
3186
3216
  */
3187
3217
  HostEvent["Edit"] = "edit";
3218
+ /**
3219
+ * Trigger the **Edit** action on a Liveboard only — does not affect a
3220
+ * visualization's edit surface.
3221
+ *
3222
+ * Behaves like {@link HostEvent.Edit} restricted to the Liveboard
3223
+ * surface. Use {@link HostEvent.EditVisualization} to target a
3224
+ * visualization instead, or `HostEvent.Edit` to control whichever
3225
+ * surface applies contextually (unchanged, existing behavior).
3226
+ * @example
3227
+ * ```js
3228
+ * liveboardEmbed.trigger(HostEvent.EditLiveboard)
3229
+ * ```
3230
+ * @version SDK: 1.54.0 | ThoughtSpot Cloud: 26.11.0.cl
3231
+ */
3232
+ HostEvent["EditLiveboard"] = "editLiveboard";
3233
+ /**
3234
+ * Trigger the **Edit** action on a specific visualization inside a
3235
+ * Liveboard only — does not affect the Liveboard-level edit surface.
3236
+ * @param - Object parameter. Includes the following keys:
3237
+ * - `vizId`: **Required.** The visualization to edit.
3238
+ *
3239
+ * @example
3240
+ * ```js
3241
+ * liveboardEmbed.trigger(HostEvent.EditVisualization, {vizId:
3242
+ * '730496d6-6903-4601-937e-2c691821af3c'})
3243
+ * ```
3244
+ * @version SDK: 1.54.0 | ThoughtSpot Cloud: 26.11.0.cl
3245
+ */
3246
+ HostEvent["EditVisualization"] = "editVisualization";
3247
+ /**
3248
+ * Exits Liveboard edit mode , equivalent to clicking the
3249
+ * *Cancel* button in the Liveboard edit header. The Liveboard returns to
3250
+ * view mode and the embedded app emits the {@link EmbedEvent.Cancel} event.
3251
+ * @version SDK: 1.55.0 | ThoughtSpot Cloud: 26.12.0.cl
3252
+ * @example
3253
+ * ```js
3254
+ * liveboardEmbed.trigger(HostEvent.ExitEditMode);
3255
+ * ```
3256
+ */
3257
+ HostEvent["ExitEditMode"] = "exitEditMode";
3188
3258
  /**
3189
3259
  * Trigger the **Copy link** action on a Liveboard or visualization
3190
3260
  * Payload: {@link VizScopedRequest}.
@@ -4720,6 +4790,39 @@
4720
4790
  * @version SDK: 1.49.0 | ThoughtSpot Cloud: 26.6.0.cl
4721
4791
  */
4722
4792
  HostEvent["RefreshLiveboardBrowserCache"] = "refreshLiveboardBrowserCache";
4793
+ /**
4794
+ * Switch the embed between dark appearance and its default appearance
4795
+ * while it is open, without reloading it.
4796
+ * Payload: {@link UpdateThemeRequest}.
4797
+ *
4798
+ * Use it to keep the embed in step with a theme switch in your
4799
+ * application; the appearance the embed loads with is set by `isDarkMode`.
4800
+ * The event resolves with the applied value, such as `{ isDarkMode: true }`.
4801
+ * When dark appearance is not available in the embed, the embed does not
4802
+ * change and the event rejects with an error message instead.
4803
+ * @version SDK: 1.55.0 | ThoughtSpot Cloud: 26.12.0.cl
4804
+ * @param - `isDarkMode` - `true` for dark appearance, `false` for the
4805
+ * default appearance.
4806
+ * @example
4807
+ * ```js
4808
+ * appEmbed.trigger(HostEvent.UpdateTheme, { isDarkMode: true });
4809
+ * ```
4810
+ * @example
4811
+ * ```js
4812
+ * // Follow a theme switch in your application
4813
+ * const themeSwitch = document.querySelector('#theme-switch');
4814
+ * themeSwitch.addEventListener('change', async (event) => {
4815
+ * try {
4816
+ * await appEmbed.trigger(HostEvent.UpdateTheme, {
4817
+ * isDarkMode: event.target.checked,
4818
+ * });
4819
+ * } catch (error) {
4820
+ * console.warn(error);
4821
+ * }
4822
+ * });
4823
+ * ```
4824
+ */
4825
+ HostEvent["UpdateTheme"] = "UpdateTheme";
4723
4826
  })(exports.HostEvent || (exports.HostEvent = {}));
4724
4827
  /**
4725
4828
  * The different visual modes that the data sources panel within
@@ -4747,6 +4850,22 @@
4747
4850
  var Param;
4748
4851
  (function (Param) {
4749
4852
  Param["Tsmcp"] = "tsmcp";
4853
+ /**
4854
+ * Marker added by a host app replaying a stored conversation. Carries the
4855
+ * analytical session (conversation) identifier, from which the renderer
4856
+ * resolves the answer's current session parameters. Stripped before the
4857
+ * URL reaches the ThoughtSpot application.
4858
+ * @version SDK: 1.52.2 | ThoughtSpot Cloud: 26.9.0.cl
4859
+ */
4860
+ Param["TsmcpConversationId"] = "tsmcpConversationId";
4861
+ /**
4862
+ * Zero-based position of the answer within the conversation, counting only
4863
+ * non-thinking answer items in message order. Accompanies
4864
+ * {@link TsmcpConversationId}; defaults to 0 when absent. Stripped before
4865
+ * the URL reaches the ThoughtSpot application.
4866
+ * @version SDK: 1.52.2 | ThoughtSpot Cloud: 26.9.0.cl
4867
+ */
4868
+ Param["TsmcpAnswerIndex"] = "tsmcpAnswerIndex";
4750
4869
  Param["EmbedApp"] = "embedApp";
4751
4870
  Param["DataSources"] = "dataSources";
4752
4871
  Param["DataSourceMode"] = "dataSourceMode";
@@ -4910,6 +5029,9 @@
4910
5029
  Param["SpotterDataSources"] = "spotterDataSources";
4911
5030
  Param["OpenSpotterOnLiveboardByDefault"] = "openSpotterOnLiveboardByDefault";
4912
5031
  Param["ShowAnswerEditPanel"] = "showAnswerEditPanel";
5032
+ Param["IsDarkMode"] = "isDarkMode";
5033
+ Param["RadiantThemeEnabled"] = "radiantThemeEnabled";
5034
+ Param["SpotterExperienceVersion"] = "spotterExperienceVersion";
4913
5035
  })(Param || (Param = {}));
4914
5036
  /**
4915
5037
  * ThoughtSpot application pages include actions and menu commands
@@ -5364,12 +5486,43 @@
5364
5486
  * The *Edit* action on the Liveboard page and in the
5365
5487
  * visualization menu.
5366
5488
  * Opens a Liveboard or visualization in edit mode.
5489
+ *
5490
+ * Controls both surfaces together. To target one surface only, use
5491
+ * {@link Action.EditLiveboard} or {@link Action.EditVisualization}.
5367
5492
  * @example
5368
5493
  * ```js
5369
5494
  * disabledActions: [Action.Edit]
5370
5495
  * ```
5371
5496
  */
5372
5497
  Action["Edit"] = "edit";
5498
+ /**
5499
+ * The *Edit* action on the Liveboard page only.
5500
+ * Opens a Liveboard in edit mode.
5501
+ *
5502
+ * Does not affect the *Edit* action in the visualization menu; use
5503
+ * {@link Action.EditVisualization} for that, or {@link Action.Edit} to
5504
+ * control both surfaces together.
5505
+ * @version SDK: 1.54.0 | ThoughtSpot Cloud: 26.11.0.cl
5506
+ * @example
5507
+ * ```js
5508
+ * disabledActions: [Action.EditLiveboard]
5509
+ * ```
5510
+ */
5511
+ Action["EditLiveboard"] = "editLiveboard";
5512
+ /**
5513
+ * The *Edit* action in the visualization `...` menu only.
5514
+ * Opens a visualization in the editor.
5515
+ *
5516
+ * Does not affect the *Edit* action on the Liveboard page; use
5517
+ * {@link Action.EditLiveboard} for that, or {@link Action.Edit} to
5518
+ * control both surfaces together.
5519
+ * @version SDK: 1.54.0 | ThoughtSpot Cloud: 26.11.0.cl
5520
+ * @example
5521
+ * ```js
5522
+ * disabledActions: [Action.EditVisualization]
5523
+ * ```
5524
+ */
5525
+ Action["EditVisualization"] = "editVisualization";
5373
5526
  /**
5374
5527
  * The text edit option for Liveboard and visualization titles.
5375
5528
  * @example
@@ -7145,6 +7298,29 @@
7145
7298
  * ```
7146
7299
  */
7147
7300
  Action["CustomizeHomepage"] = "customizeHomepage";
7301
+ /**
7302
+ * Controls the visibility and disabled state of the *Cancel* button in the
7303
+ * Liveboard edit header, the button that discards the changes made in edit
7304
+ * mode and returns the Liveboard to view mode. The button is shown only
7305
+ * while the Liveboard is in edit mode.
7306
+ * @version SDK: 1.55.0 | ThoughtSpot Cloud: 26.12.0.cl
7307
+ * @example
7308
+ * ```js
7309
+ * const liveboardEmbed = new LiveboardEmbed('#tsEmbed', {
7310
+ * ... // other embed view config
7311
+ * hiddenActions: [Action.Cancel],
7312
+ * });
7313
+ * ```
7314
+ * @example
7315
+ * ```js
7316
+ * const liveboardEmbed = new LiveboardEmbed('#tsEmbed', {
7317
+ * ... // other embed view config
7318
+ * disabledActions: [Action.Cancel],
7319
+ * disabledActionReason: 'Save your changes to leave edit mode',
7320
+ * });
7321
+ * ```
7322
+ */
7323
+ Action["Cancel"] = "cancel";
7148
7324
  })(exports.Action || (exports.Action = {}));
7149
7325
  exports.PrefetchFeatures = void 0;
7150
7326
  (function (PrefetchFeatures) {
@@ -7649,7 +7825,7 @@
7649
7825
  TableContentDensity["Compact"] = "COMPACT";
7650
7826
  })(exports.TableContentDensity || (exports.TableContentDensity = {}));
7651
7827
 
7652
- var version$1="1.52.2-beta.2";var pkg = {version:version$1};
7828
+ var version$1="1.53.1";var pkg = {version:version$1};
7653
7829
 
7654
7830
  const { version } = pkg;
7655
7831
 
@@ -10316,6 +10492,13 @@ mutation RemoveColumns($session: BachSessionIdInput!, $logicalColumnIds: [GUID!]
10316
10492
  ${bachSessionId}
10317
10493
  }
10318
10494
  }
10495
+ `;
10496
+ const updateSort = `
10497
+ mutation UpdateSort($session: BachSessionIdInput!, $sortOrder: [AnswerColumnSortInput!]!) {
10498
+ Answer__updateSort(session: $session, sortOrder: $sortOrder) {
10499
+ ${bachSessionId}
10500
+ }
10501
+ }
10319
10502
  `;
10320
10503
  const getAnswer = `
10321
10504
  query GetAnswer($session: BachSessionIdInput!) {
@@ -10621,6 +10804,26 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
10621
10804
  },
10622
10805
  });
10623
10806
  }
10807
+ /**
10808
+ * Adapt the sort options into the `updateSort` payload and send it.
10809
+ * @param sortOptions Columns to sort by, each with a direction.
10810
+ * @param sourceDetail
10811
+ */
10812
+ async adaptSorting(sortOptions, sourceDetail) {
10813
+ const { answer } = await this.executeQuery(getAnswer, {});
10814
+ const guidToColumnId = getGuidToColumnIdMap(answer);
10815
+ const sortOrder = sortOptions.map((sort) => {
10816
+ const guid = getGuidsFromColumnNames(sourceDetail, [sort.columnName])
10817
+ .values().next().value;
10818
+ return {
10819
+ columnId: guidToColumnId.get(guid),
10820
+ sortType: sort.ascending ? 'ASCENDING' : 'DESCENDING',
10821
+ };
10822
+ });
10823
+ return this.executeQuery(updateSort, {
10824
+ sortOrder,
10825
+ });
10826
+ }
10624
10827
  async updateDisplayMode(displayMode = "TABLE_MODE") {
10625
10828
  return this.executeQuery(updateDisplayMode, {
10626
10829
  displayMode,
@@ -10708,18 +10911,21 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
10708
10911
  * automatically passed.
10709
10912
  * @param outputColumnNames
10710
10913
  * @param selectedPoints
10914
+ * @param sortOptions Optional columns to sort the underlying data by.
10711
10915
  * @example
10712
10916
  * ```js
10713
10917
  * embed.on(EmbedEvent.CustomAction, e => {
10714
- * const underlying = await e.answerService.getUnderlyingDataForPoint([
10715
- * 'col name 1' // The column should exist in the data source.
10716
- * ]);
10918
+ * const underlying = await e.answerService.getUnderlyingDataForPoint(
10919
+ * ['col name 1'], // The column should exist in the data source.
10920
+ * undefined,
10921
+ * [{ columnName: 'col name 1', ascending: true }],
10922
+ * );
10717
10923
  * const data = await underlying.fetchData(0, 100);
10718
10924
  * })
10719
10925
  * ```
10720
10926
  * @version SDK: 1.25.0 | ThoughtSpot: 9.10.0.cl
10721
10927
  */
10722
- async getUnderlyingDataForPoint(outputColumnNames, selectedPoints) {
10928
+ async getUnderlyingDataForPoint(outputColumnNames, selectedPoints, sortOptions) {
10723
10929
  if (!selectedPoints && !this.selectedPoints) {
10724
10930
  throw new Error('Needs to be triggered in context of a point');
10725
10931
  }
@@ -10747,6 +10953,9 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
10747
10953
  if (columnsToRemove.length) {
10748
10954
  await unaggAnswerSession.removeColumns(columnsToRemove);
10749
10955
  }
10956
+ if (sortOptions === null || sortOptions === void 0 ? void 0 : sortOptions.length) {
10957
+ await unaggAnswerSession.adaptSorting(sortOptions, sourceDetail);
10958
+ }
10750
10959
  return unaggAnswerSession;
10751
10960
  }
10752
10961
  /**
@@ -10806,6 +11015,15 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
10806
11015
  this.tmlOverride = override;
10807
11016
  }
10808
11017
  }
11018
+ /**
11019
+ * Build a map from a source column guid to the answer's viz column id, using
11020
+ * the `referencedColumns` link on each viz column.
11021
+ * @param answer
11022
+ */
11023
+ function getGuidToColumnIdMap(answer) {
11024
+ const tableViz = answer.visualizations.find((viz) => viz.columns);
11025
+ return new Map(tableViz.columns.map((col) => [col.column.referencedColumns[0].guid, col.column.id]));
11026
+ }
10809
11027
  /**
10810
11028
  *
10811
11029
  * @param sourceDetail
@@ -19820,6 +20038,7 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
19820
20038
  const MIXPANEL_EVENT = {
19821
20039
  VISUAL_SDK_RENDER_START: 'visual-sdk-render-start',
19822
20040
  VISUAL_SDK_CALLED_INIT: 'visual-sdk-called-init',
20041
+ VISUAL_SDK_INIT_ACTIONS: 'visual-sdk-init-actions',
19823
20042
  VISUAL_SDK_RENDER_COMPLETE: 'visual-sdk-render-complete',
19824
20043
  VISUAL_SDK_RENDER_FAILED: 'visual-sdk-render-failed',
19825
20044
  VISUAL_SDK_TRIGGER: 'visual-sdk-trigger',
@@ -19894,6 +20113,32 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
19894
20113
  }
19895
20114
  }
19896
20115
 
20116
+ // Membership is checked, not just the key: a bare key allowlist would upload an
20117
+ // arbitrary customer string sitting under `operator` verbatim.
20118
+ const isEnumMember = (enumObject, value) => typeof value === 'string' && Object.values(enumObject).includes(value);
20119
+ const uniqueEnumMembers = (enumObject, values) => Array.from(new Set(values.filter((v) => isEnumMember(enumObject, v))));
20120
+ const describeRuntimeFilters = (runtimeFilters) => ({
20121
+ count: runtimeFilters.length,
20122
+ operators: uniqueEnumMembers(exports.RuntimeFilterOp, runtimeFilters.map((filter) => filter === null || filter === void 0 ? void 0 : filter.operator)),
20123
+ });
20124
+ const describeRuntimeParameters = (runtimeParameters) => ({
20125
+ count: runtimeParameters.length,
20126
+ applicabilityLevels: uniqueEnumMembers(exports.ApplicabilityLevel, runtimeParameters.map((parameter) => { var _a; return (_a = parameter === null || parameter === void 0 ? void 0 : parameter.applicability) === null || _a === void 0 ? void 0 : _a.level; })),
20127
+ });
20128
+ // Column names, parameter names and operands are customer data and must never
20129
+ // reach Mixpanel; an unrecognized shape is dropped rather than forwarded.
20130
+ const summarizeRuntimeDataForTelemetry = (viewConfig) => {
20131
+ const { runtimeFilters, runtimeParameters, ...rest } = viewConfig !== null && viewConfig !== void 0 ? viewConfig : {};
20132
+ const telemetryProps = { ...rest };
20133
+ if (Array.isArray(runtimeFilters)) {
20134
+ telemetryProps.runtimeFilters = describeRuntimeFilters(runtimeFilters);
20135
+ }
20136
+ if (Array.isArray(runtimeParameters)) {
20137
+ telemetryProps.runtimeParameters = describeRuntimeParameters(runtimeParameters);
20138
+ }
20139
+ return telemetryProps;
20140
+ };
20141
+
19897
20142
  var eventemitter3 = createCommonjsModule(function (module) {
19898
20143
 
19899
20144
  var has = Object.prototype.hasOwnProperty
@@ -22212,6 +22457,97 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
22212
22457
  // truthy, so null or '' leaves the previous embed's values in place. '&' is
22213
22458
  // truthy and parses to {}.
22214
22459
  const NO_RUNTIME_PARAMS = '&';
22460
+ /**
22461
+ * Params kept on the iframe `src` when `excludeConfigFromURL` is set. The rest
22462
+ * are sent in the APP_INIT payload.
22463
+ * @internal
22464
+ */
22465
+ const BOOTSTRAP_URL_PARAMS = new Set([
22466
+ // Marks the app as embedded.
22467
+ Param.EmbedApp,
22468
+ // The host page URL, used to validate the postMessage origin.
22469
+ Param.HostAppUrl,
22470
+ // The SDK version.
22471
+ Param.Version,
22472
+ // The authentication type set in init.
22473
+ Param.AuthType,
22474
+ // Whether the app signs the user in automatically.
22475
+ Param.AutoLogin,
22476
+ // Stops the app from redirecting to its login page.
22477
+ Param.DisableLoginRedirect,
22478
+ // Forces the SAML redirect for EmbeddedSSO.
22479
+ Param.ForceSAMLAutoRedirect,
22480
+ // Set for cookieless trusted authentication.
22481
+ Param.cookieless,
22482
+ // Lets the app use the pre-fetched auth info.
22483
+ Param.preAuthCache,
22484
+ // Blocks access to the full app outside the embed.
22485
+ Param.blockNonEmbedFullAppAccess,
22486
+ // The org to load, which the auth info depends on.
22487
+ Param.OverrideOrgId,
22488
+ // The host window height when the iframe loads.
22489
+ Param.ViewPortHeight,
22490
+ // The host window width when the iframe loads.
22491
+ Param.ViewPortWidth,
22492
+ // The app's client log level.
22493
+ Param.ClientLogLevel,
22494
+ // Lets the app override the native console.
22495
+ Param.OverrideNativeConsole,
22496
+ // An extra Pendo tracking key.
22497
+ Param.PendoTrackingKey,
22498
+ // The locale for number formatting.
22499
+ Param.NumberFormatLocale,
22500
+ // The locale for date formatting.
22501
+ Param.DateFormatLocale,
22502
+ // The currency format.
22503
+ Param.CurrencyFormat,
22504
+ // The UI language.
22505
+ Param.Locale,
22506
+ // Turns on dark mode.
22507
+ Param.IsDarkMode,
22508
+ // Turns on the radiant theme that dark mode needs.
22509
+ Param.RadiantThemeEnabled,
22510
+ // Marks a SearchEmbed or SearchBarEmbed.
22511
+ Param.searchEmbed,
22512
+ // Marks a LiveboardEmbed.
22513
+ Param.livedBoardEmbed,
22514
+ // Marks a SpotterAgentEmbed.
22515
+ Param.isSpotterAgentEmbed,
22516
+ // Marks a SpotterEmbed.
22517
+ Param.SpotterEnabled,
22518
+ // Marks an AppEmbed.
22519
+ Param.IsFullAppEmbed,
22520
+ // Legacy flag for the onBeforeGetVizData API intercept.
22521
+ Param.IsOnBeforeGetVizDataInterceptEnabled,
22522
+ // Lets the host override links in the app.
22523
+ Param.LinkOverride,
22524
+ // Turns on version 2 of the link overrides.
22525
+ Param.EnableLinkOverridesV2,
22526
+ // Stops links from opening in a new tab.
22527
+ Param.DisableRedirectionLinksInNewTab,
22528
+ // Uses replaceState instead of pushState for app navigation.
22529
+ Param.OverrideHistoryState,
22530
+ // Shows search results as a table.
22531
+ Param.ForceTable,
22532
+ // The URL of the custom string IDs file.
22533
+ Param.StringIDsUrl,
22534
+ // The data sources that search opens with.
22535
+ Param.DataSources,
22536
+ // Exposes translation IDs in the app.
22537
+ Param.ExposeTranslationIDs,
22538
+ // The URL of the custom icon sprite.
22539
+ Param.IconSpriteUrl,
22540
+ // The tag that filters the metadata lists in an AppEmbed.
22541
+ Param.Tag,
22542
+ // Set when a Liveboard embed shows a single visualization (vizId).
22543
+ Param.vizEmbed,
22544
+ // Whether search opens with the last-selected data sources.
22545
+ Param.UseLastSelectedDataSource,
22546
+ // The query mode Spotter opens in.
22547
+ Param.DefaultQueryMode,
22548
+ // The initial search query. Omitted with excludeSearchTokenStringFromURL.
22549
+ Param.searchTokenString,
22550
+ ]);
22215
22551
  /**
22216
22552
  * The event id map from v2 event names to v1 event id
22217
22553
  * v1 events are the classic embed events implemented in Blink v1
@@ -22240,6 +22576,7 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
22240
22576
  this.embedNodeKey = '__tsEmbed';
22241
22577
  this.embedContainerLoadedKey = '__tsEmbedContainerLoaded';
22242
22578
  this.isAppInitialized = false;
22579
+ this.initDataParams = {};
22243
22580
  /**
22244
22581
  * Should we encode URL Query Params using base64 encoding which ThoughtSpot
22245
22582
  * will generate for embedding. This provides additional security to
@@ -22274,7 +22611,7 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
22274
22611
  */
22275
22612
  this.appInitCb = async (_, responder) => {
22276
22613
  try {
22277
- const appInitData = await this.getAppInitData();
22614
+ const appInitData = this.withInitDataParams(await this.getAppInitData());
22278
22615
  this.isAppInitialized = true;
22279
22616
  responder({
22280
22617
  type: exports.EmbedEvent.APP_INIT,
@@ -22428,9 +22765,7 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
22428
22765
  ...viewConfig,
22429
22766
  };
22430
22767
  this.registerAppInit();
22431
- uploadMixpanelEvent(MIXPANEL_EVENT.VISUAL_SDK_EMBED_CREATE, {
22432
- ...viewConfig,
22433
- });
22768
+ uploadMixpanelEvent(MIXPANEL_EVENT.VISUAL_SDK_EMBED_CREATE, summarizeRuntimeDataForTelemetry(viewConfig));
22434
22769
  const embedConfig = getEmbedConfig();
22435
22770
  if (embedConfig) {
22436
22771
  this.embedConfig = embedConfig;
@@ -22702,6 +23037,18 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
22702
23037
  async getAppInitData() {
22703
23038
  return this.getDefaultAppInitData();
22704
23039
  }
23040
+ withInitDataParams(appInitData) {
23041
+ if (isEmpty_1(this.initDataParams)) {
23042
+ return appInitData;
23043
+ }
23044
+ return {
23045
+ ...appInitData,
23046
+ embedParams: {
23047
+ ...this.initDataParams,
23048
+ ...(appInitData.embedParams || {}),
23049
+ },
23050
+ };
23051
+ }
22705
23052
  /**
22706
23053
  * Helper method to refresh/update auth token for TrustedAuthTokenCookieless auth type
22707
23054
  * @param responder - Function to send response back
@@ -22761,7 +23108,7 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
22761
23108
  * @returns queryParams
22762
23109
  */
22763
23110
  getBaseQueryParams(queryParams = {}) {
22764
- var _a, _b, _c, _d;
23111
+ var _a, _b, _c, _d, _e;
22765
23112
  let hostAppUrl = ((_a = window === null || window === void 0 ? void 0 : window.location) === null || _a === void 0 ? void 0 : _a.host) || '';
22766
23113
  // The below check is needed because TS Cloud firewall, blocks
22767
23114
  // localhost/127.0.0.1 in any url param.
@@ -22798,6 +23145,15 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
22798
23145
  if (this.embedConfig.currencyFormat) {
22799
23146
  queryParams[Param.CurrencyFormat] = this.embedConfig.currencyFormat;
22800
23147
  }
23148
+ // The view config wins over init, so an embed can opt out of a dark
23149
+ // mode set in `init`. `??` and not `||`, so that an explicit `false`
23150
+ // overrides an init-level `true`.
23151
+ const isDarkMode = (_c = this.viewConfig.isDarkMode) !== null && _c !== void 0 ? _c : this.embedConfig.isDarkMode;
23152
+ setParamIfDefined(queryParams, Param.IsDarkMode, isDarkMode, true);
23153
+ // The app's dark mode lives in its radiant theme, so turn that on too.
23154
+ if (isDarkMode) {
23155
+ queryParams[Param.RadiantThemeEnabled] = true;
23156
+ }
22801
23157
  const { disabledActions, disabledActionReason, hiddenActions, visibleActions, hiddenTabs, visibleTabs, showAlerts, additionalFlags: additionalFlagsFromView, locale, customizations, contextMenuTrigger, linkOverride, enableLinkOverridesV2, insertInToSlide, disableRedirectionLinksInNewTab, overrideOrgId, overrideHistoryState, exposeTranslationIDs, primaryAction, } = this.viewConfig;
22802
23158
  const { additionalFlags: additionalFlagsFromInit } = this.embedConfig;
22803
23159
  const additionalFlags = {
@@ -22863,7 +23219,7 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
22863
23219
  if (spriteUrl) {
22864
23220
  queryParams[Param.IconSpriteUrl] = spriteUrl.replace('https://', '');
22865
23221
  }
22866
- const stringIDsUrl = ((_c = customizations === null || customizations === void 0 ? void 0 : customizations.content) === null || _c === void 0 ? void 0 : _c.stringIDsUrl) || ((_d = embedCustomizations === null || embedCustomizations === void 0 ? void 0 : embedCustomizations.content) === null || _d === void 0 ? void 0 : _d.stringIDsUrl);
23222
+ const stringIDsUrl = ((_d = customizations === null || customizations === void 0 ? void 0 : customizations.content) === null || _d === void 0 ? void 0 : _d.stringIDsUrl) || ((_e = embedCustomizations === null || embedCustomizations === void 0 ? void 0 : embedCustomizations.content) === null || _e === void 0 ? void 0 : _e.stringIDsUrl);
22867
23223
  if (stringIDsUrl) {
22868
23224
  queryParams[Param.StringIDsUrl] = stringIDsUrl;
22869
23225
  }
@@ -22917,13 +23273,32 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
22917
23273
  return path;
22918
23274
  }
22919
23275
  getEmbedParams() {
22920
- const queryParams = this.getEmbedParamsObject();
23276
+ const queryParams = this.getUrlQueryParamsObject();
22921
23277
  return getQueryParamString(queryParams);
22922
23278
  }
22923
23279
  getEmbedParamsObject() {
22924
23280
  const params = this.getBaseQueryParams();
22925
23281
  return params;
22926
23282
  }
23283
+ getUrlQueryParamsObject() {
23284
+ const queryParams = this.getEmbedParamsObject();
23285
+ if (!this.isConfigExcludedFromUrl()) {
23286
+ this.initDataParams = {};
23287
+ return queryParams;
23288
+ }
23289
+ const urlParams = {};
23290
+ const excludedParams = {};
23291
+ Object.entries(queryParams).forEach(([key, value]) => {
23292
+ if (BOOTSTRAP_URL_PARAMS.has(key)) {
23293
+ urlParams[key] = value;
23294
+ }
23295
+ else {
23296
+ excludedParams[key] = deserializeParam(value);
23297
+ }
23298
+ });
23299
+ this.initDataParams = excludedParams;
23300
+ return urlParams;
23301
+ }
22927
23302
  getRootIframeSrc() {
22928
23303
  const query = this.getEmbedParams();
22929
23304
  return this.getEmbedBasePath(query);
@@ -23162,26 +23537,12 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
23162
23537
  return placeholder;
23163
23538
  }
23164
23539
  /**
23165
- * Resolves the configured preRenderContainer to a live element. A string
23166
- * selector is re-queried on every call so a remounted container (E.g.: React
23167
- * replacing the node) resolves to the fresh element; an element passed
23168
- * directly cannot be re-resolved.
23169
- *
23170
- * With nothing configured the frame goes into the host element's nearest
23171
- * scrolling ancestor, falling back to `document.body`.
23172
- *
23173
- * The wrapper is absolutely positioned, so it follows the page for free —
23174
- * but only while it sits inside whatever scrolls. `document.body` is right
23175
- * only when the document itself is the scroller; an app that scrolls an
23176
- * inner element instead left the frame pinned to the viewport while the page
23177
- * moved under it (SCAL-338563). Being inside the scroller also lets wheel
23178
- * events chain out of the frame into it, which they cannot do from
23179
- * `document.body`.
23180
- *
23181
- * A scrolling ancestor is layout chrome rather than route content, so it
23182
- * outlives the embed in practice; and if it does go, the host element goes
23183
- * with it and this instance is remounting anyway.
23184
- * `reconcilePreRenderContainer` re-runs this on a detached container.
23540
+ * Resolves the configured preRenderContainer, or defaults to the host's
23541
+ * nearest scrolling ancestor (document.body if none). The absolutely
23542
+ * positioned wrapper only follows the page while it sits inside what
23543
+ * scrolls, so body is right only when the document itself scrolls — an inner
23544
+ * scroller left the frame pinned to the viewport (SCAL-338563). A string
23545
+ * selector is re-queried each call so a remounted container resolves fresh.
23185
23546
  */
23186
23547
  resolvePreRenderContainerTarget() {
23187
23548
  var _a;
@@ -23623,9 +23984,16 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
23623
23984
  * @param args
23624
23985
  */
23625
23986
  async render() {
23987
+ var _a, _b, _c;
23626
23988
  uploadMixpanelEvent(MIXPANEL_EVENT.VISUAL_SDK_RENDER_CALLED, {
23627
23989
  embedComponentType: this.viewConfig.embedComponentType,
23628
23990
  });
23991
+ uploadMixpanelEvent(MIXPANEL_EVENT.VISUAL_SDK_INIT_ACTIONS, {
23992
+ embedComponentType: this.viewConfig.embedComponentType,
23993
+ hiddenActions: (_a = this.viewConfig.hiddenActions) !== null && _a !== void 0 ? _a : [],
23994
+ visibleActions: (_b = this.viewConfig.visibleActions) !== null && _b !== void 0 ? _b : [],
23995
+ disabledActions: (_c = this.viewConfig.disabledActions) !== null && _c !== void 0 ? _c : [],
23996
+ });
23629
23997
  if (!getIsInitCalled()) {
23630
23998
  logger$3.error(ERROR_MESSAGE.RENDER_CALLED_BEFORE_INIT);
23631
23999
  }
@@ -23860,6 +24228,26 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
23860
24228
  this.isRendered = true;
23861
24229
  return this.renderIFrame(prerenderFrameSrc);
23862
24230
  }
24231
+ isConfigExcludedFromUrl() {
24232
+ var _a, _b, _c;
24233
+ const flag = (_b = (_a = this.viewConfig.additionalFlags) === null || _a === void 0 ? void 0 : _a.excludeConfigFromURL) !== null && _b !== void 0 ? _b : (_c = this.embedConfig.additionalFlags) === null || _c === void 0 ? void 0 : _c.excludeConfigFromURL;
24234
+ return flag === true || flag === 'true';
24235
+ }
24236
+ async triggerUpdateEmbedParams() {
24237
+ try {
24238
+ const params = await this.getUpdateEmbedParamsObject();
24239
+ this.trigger(exports.HostEvent.UpdateEmbedParams, params);
24240
+ }
24241
+ catch (error) {
24242
+ logger$3.error(ERROR_MESSAGE.UPDATE_PARAMS_FAILED, error);
24243
+ this.handleError({
24244
+ errorType: exports.ErrorDetailsTypes.API,
24245
+ message: (error === null || error === void 0 ? void 0 : error.message) || ERROR_MESSAGE.UPDATE_PARAMS_FAILED,
24246
+ code: exports.EmbedErrorCodes.UPDATE_PARAMS_FAILED,
24247
+ error: (error === null || error === void 0 ? void 0 : error.message) || error,
24248
+ });
24249
+ }
24250
+ }
23863
24251
  beforePrerenderVisible() {
23864
24252
  // We can ignore this as its a bit expensive and the newer customers
23865
24253
  // have moved on to UpdateEmbedParams supported clusters
@@ -23870,17 +24258,7 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
23870
24258
  this.preRenderParamsApplied = new Promise((resolve) => {
23871
24259
  this.executeAfterEmbedContainerLoaded(async () => {
23872
24260
  try {
23873
- const params = await this.getUpdateEmbedParamsObject();
23874
- this.trigger(exports.HostEvent.UpdateEmbedParams, params);
23875
- }
23876
- catch (error) {
23877
- logger$3.error(ERROR_MESSAGE.UPDATE_PARAMS_FAILED, error);
23878
- this.handleError({
23879
- errorType: exports.ErrorDetailsTypes.API,
23880
- message: (error === null || error === void 0 ? void 0 : error.message) || ERROR_MESSAGE.UPDATE_PARAMS_FAILED,
23881
- code: exports.EmbedErrorCodes.UPDATE_PARAMS_FAILED,
23882
- error: (error === null || error === void 0 ? void 0 : error.message) || error,
23883
- });
24261
+ await this.triggerUpdateEmbedParams();
23884
24262
  }
23885
24263
  finally {
23886
24264
  setTimeout(resolve, UPDATE_EMBED_PARAMS_SETTLE_MS);
@@ -24014,19 +24392,21 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
24014
24392
  return;
24015
24393
  }
24016
24394
  const { zIndex } = this.getPreRenderConfig();
24395
+ // A hidden pre-render frame must add no scroll space to the host page.
24017
24396
  const preRenderHideStyles = {
24018
24397
  opacity: '0',
24019
24398
  pointerEvents: 'none',
24020
24399
  zIndex: zIndex !== undefined ? String(zIndex) : '-1000',
24021
- position: 'absolute',
24400
+ // Resolves to the viewport, so the hidden frame belongs to no
24401
+ // scroll container's overflow; syncPreRenderStyle restores absolute
24402
+ // on show.
24403
+ position: 'fixed',
24022
24404
  top: '0',
24023
24405
  left: '0',
24024
24406
  overflow: 'hidden',
24025
- // Keeps the measured size — so the next show needs no resize, which
24026
- // is the point of pre-rendering — while lifting the box out of
24027
- // the container's scrollable area. Overflow only extends
24028
- // downwards, so a hidden frame parked above the top edge adds
24029
- // none, where one left at full height shows as blank scroll space.
24407
+ // The one exception: a transformed or contained ancestor captures
24408
+ // `fixed`; parking above the top edge keeps it out of that
24409
+ // overflow.
24030
24410
  transform: PRERENDER_PARKED_TRANSFORM,
24031
24411
  };
24032
24412
  setStyleProperties(this.preRenderWrapper, preRenderHideStyles);
@@ -24196,8 +24576,11 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
24196
24576
  embedParams: { visualOverridesParams: visualOverrides },
24197
24577
  };
24198
24578
  }
24579
+ // The app reads enableSpotterInstructionAndMoreSettings from the top level
24580
+ // of embedParams, so lift it out of the sidebar config.
24581
+ const { enableSpotterInstructionAndMoreSettings, ...sidebarConfigRest } = spotterSidebarConfig || {};
24199
24582
  const resolvedSidebarConfig = {
24200
- ...spotterSidebarConfig,
24583
+ ...sidebarConfigRest,
24201
24584
  ...(resolvedEnablePastConversations !== undefined && {
24202
24585
  enablePastConversationsSidebar: resolvedEnablePastConversations,
24203
24586
  }),
@@ -24219,6 +24602,9 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
24219
24602
  embedParams: {
24220
24603
  ...(defaultAppInitData.embedParams || {}),
24221
24604
  spotterSidebarConfig: resolvedSidebarConfig,
24605
+ ...(enableSpotterInstructionAndMoreSettings !== undefined
24606
+ ? { enableSpotterInstructionAndMoreSettings }
24607
+ : {}),
24222
24608
  ...(visualOverrides !== undefined ? { visualOverridesParams: visualOverrides } : {}),
24223
24609
  },
24224
24610
  };
@@ -24259,7 +24645,19 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
24259
24645
  spotterAnalystConfig,
24260
24646
  },
24261
24647
  };
24262
- }
24648
+ }
24649
+ /**
24650
+ * The Spotter experience version to load in the embedded view.
24651
+ * @version SDK: 1.53.0 | ThoughtSpot Cloud: 26.11.0.cl
24652
+ * @group Embed components
24653
+ */
24654
+ exports.SpotterExperienceVersion = void 0;
24655
+ (function (SpotterExperienceVersion) {
24656
+ /**
24657
+ * The Spotter experience version introduced in ThoughtSpot 26.11.
24658
+ */
24659
+ SpotterExperienceVersion["SPOTTER_2026_11"] = "spotter_2026_11";
24660
+ })(exports.SpotterExperienceVersion || (exports.SpotterExperienceVersion = {}));
24263
24661
 
24264
24662
  function buildSpotterVizAppInitData(initData, viewConfig) {
24265
24663
  const { spotterViz } = viewConfig;
@@ -24456,12 +24854,12 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
24456
24854
  * embedded Liveboard or visualization.
24457
24855
  */
24458
24856
  getEmbedParams() {
24459
- const params = this.getEmbedParamsObject();
24857
+ const params = this.getUrlQueryParamsObject();
24460
24858
  return getQueryParamString(params, true);
24461
24859
  }
24462
24860
  getEmbedParamsObject() {
24463
24861
  var _a;
24464
- const { tag, hideTagFilterChips, hideObjects, liveboardV2, showPrimaryNavbar, disableProfileAndHelp, hideHamburger, hideObjectSearch, hideNotification, hideApplicationSwitcher, hideOrgSwitcher, enableSearchAssist, newConnectionsExperience, dataPanelV2 = true, updatedSpotterExperience, hideLiveboardHeader = false, showLiveboardTitle = true, showLiveboardDescription = true, showMaskedFilterChip = false, isLiveboardMasterpiecesEnabled, newChartsLibrary, hideHomepageLeftNav = false, modularHomeExperience, isLiveboardHeaderSticky = true, enableAskSage, collapseSearchBarInitially = false, enable2ColumnLayout, isLiveboardAlwaysOn12ColLayout, enableCustomColumnGroups = false, dataPanelCustomGroupsAccordionInitialState = exports.DataPanelCustomColumnGroupsAccordionState.EXPAND_ALL, collapseSearchBar = true, isLiveboardCompactHeaderEnabled, showLiveboardVerifiedBadge = true, showLiveboardReverifyBanner = true, hideIrrelevantChipsInLiveboardTabs, isEnhancedFilterInteractivityEnabled, homePageSearchBarMode, isUnifiedSearchExperienceEnabled = true, enablePendoHelp = true, discoveryExperience, coverAndFilterOptionInPDF, isLiveboardStylingAndGroupingEnabled, liveboardGutter, isPNGInScheduledEmailsEnabled = false, isLiveboardXLSXCSVDownloadEnabled, isGranularXLSXCSVSchedulesEnabled, isCentralizedLiveboardFilterUXEnabled = false, isScopedLiveboardFilteringEnabled, isLinkParametersEnabled, updatedSpotterChatPrompt, showSpotterRadiance, defaultQueryMode, enableStopAnswerGenerationEmbed, spotterChatConfig, spotterDataSources, isThisPeriodInDateFiltersEnabled, enableHomepageAnnouncement = false, isContinuousLiveboardPDFEnabled, enableLiveboardDataCache, hideAnswerEditPanel, } = this.viewConfig;
24862
+ const { tag, hideTagFilterChips, hideObjects, liveboardV2, showPrimaryNavbar, disableProfileAndHelp, hideHamburger, hideObjectSearch, hideNotification, hideApplicationSwitcher, hideOrgSwitcher, enableSearchAssist, newConnectionsExperience, dataPanelV2 = true, updatedSpotterExperience, hideLiveboardHeader = false, showLiveboardTitle = true, showLiveboardDescription = true, showMaskedFilterChip = false, isLiveboardMasterpiecesEnabled, newChartsLibrary, hideHomepageLeftNav = false, modularHomeExperience, isLiveboardHeaderSticky = true, enableAskSage, collapseSearchBarInitially = false, enable2ColumnLayout, isLiveboardAlwaysOn12ColLayout, enableCustomColumnGroups = false, dataPanelCustomGroupsAccordionInitialState = exports.DataPanelCustomColumnGroupsAccordionState.EXPAND_ALL, collapseSearchBar = true, isLiveboardCompactHeaderEnabled, showLiveboardVerifiedBadge = true, showLiveboardReverifyBanner = true, hideIrrelevantChipsInLiveboardTabs, isEnhancedFilterInteractivityEnabled, homePageSearchBarMode, isUnifiedSearchExperienceEnabled = true, enablePendoHelp = true, discoveryExperience, coverAndFilterOptionInPDF, isLiveboardStylingAndGroupingEnabled, liveboardGutter, isPNGInScheduledEmailsEnabled = false, isLiveboardXLSXCSVDownloadEnabled, isGranularXLSXCSVSchedulesEnabled, isCentralizedLiveboardFilterUXEnabled = false, isScopedLiveboardFilteringEnabled, isLinkParametersEnabled, updatedSpotterChatPrompt, showSpotterRadiance, defaultQueryMode, enableStopAnswerGenerationEmbed, spotterChatConfig, spotterDataSources, isThisPeriodInDateFiltersEnabled, enableHomepageAnnouncement = false, isContinuousLiveboardPDFEnabled, enableLiveboardDataCache, hideAnswerEditPanel, spotterExperienceVersion, } = this.viewConfig;
24465
24863
  let params = {};
24466
24864
  params[Param.PrimaryNavHidden] = !showPrimaryNavbar;
24467
24865
  params[Param.HideProfleAndHelp] = !!disableProfileAndHelp;
@@ -24516,6 +24914,9 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
24516
24914
  if (spotterDataSources && spotterDataSources.length) {
24517
24915
  params[Param.SpotterDataSources] = JSON.stringify(spotterDataSources);
24518
24916
  }
24917
+ if (spotterExperienceVersion !== undefined) {
24918
+ params[Param.SpotterExperienceVersion] = spotterExperienceVersion;
24919
+ }
24519
24920
  // Handle spotterChatConfig params
24520
24921
  if (spotterChatConfig) {
24521
24922
  const { hideToolResponseCardBranding, toolResponseCardBrandingLabel, spotterFileUploadEnabled, spotterFileUploadFileTypes, enableStarterPrompts, openSpotterOnLiveboardByDefault, } = spotterChatConfig;
@@ -24634,7 +25035,7 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
24634
25035
  }
24635
25036
  // Navigation V1/V2 and home page V1/V2 are deprecated. V3 is now the
24636
25037
  // default experience, Need to send navigationVersion=v3 and
24637
- // homepageVersion=v3 even when the no discoveryExperience /
25038
+ // homepageVersion=v3 even when the no discoveryExperience /
24638
25039
  // modularHomeExperience config is set. Without these
24639
25040
  // params, older TSA versions (< 26.7) fall back to V2 for nav and
24640
25041
  // home page, so the defaults must be sent explicitly from the SDK.
@@ -24883,6 +25284,21 @@ query GetEurekaVizSnapshots(
24883
25284
  document.head.insertAdjacentHTML('beforeend', previewStyles);
24884
25285
  };
24885
25286
 
25287
+ function buildLiveboardOverrideAppInitData(initData, viewConfig) {
25288
+ var _a;
25289
+ const { liveboardOverride } = viewConfig;
25290
+ // ThoughtSpot ignores an override with no data source entries; skip it.
25291
+ if (!((_a = liveboardOverride === null || liveboardOverride === void 0 ? void 0 : liveboardOverride.dataSourceOverride) === null || _a === void 0 ? void 0 : _a.length))
25292
+ return initData;
25293
+ return {
25294
+ ...initData,
25295
+ embedParams: {
25296
+ ...(initData.embedParams || {}),
25297
+ liveboardOverride,
25298
+ },
25299
+ };
25300
+ }
25301
+
24886
25302
  /**
24887
25303
  * Copyright (c) 2022
24888
25304
  *
@@ -24952,14 +25368,15 @@ query GetEurekaVizSnapshots(
24952
25368
  async getAppInitData() {
24953
25369
  const defaultAppInitData = await super.getAppInitData();
24954
25370
  const vizInitData = buildSpotterVizAppInitData(defaultAppInitData, this.viewConfig);
24955
- return buildStarterPromptsAppInitData(vizInitData, this.viewConfig);
25371
+ const starterPromptsInitData = buildStarterPromptsAppInitData(vizInitData, this.viewConfig);
25372
+ return buildLiveboardOverrideAppInitData(starterPromptsInitData, this.viewConfig);
24956
25373
  }
24957
25374
  /**
24958
25375
  * Construct a map of params to be passed on to the
24959
25376
  * embedded Liveboard or visualization.
24960
25377
  */
24961
25378
  getEmbedParams() {
24962
- const params = this.getEmbedParamsObject();
25379
+ const params = this.getUrlQueryParamsObject();
24963
25380
  const queryParams = getQueryParamString(params, true);
24964
25381
  return queryParams;
24965
25382
  }
@@ -24967,7 +25384,7 @@ query GetEurekaVizSnapshots(
24967
25384
  var _a;
24968
25385
  let params = {};
24969
25386
  params = this.getBaseQueryParams(params);
24970
- const { enableVizTransformations, visibleVizs, liveboardV2, vizId, hideTabPanel, activeTabId, hideLiveboardHeader, showLiveboardDescription, showLiveboardTitle, isLiveboardHeaderSticky = true, isLiveboardCompactHeaderEnabled, showLiveboardVerifiedBadge = true, showLiveboardReverifyBanner = true, hideIrrelevantChipsInLiveboardTabs, showMaskedFilterChip = false, isLiveboardMasterpiecesEnabled, newChartsLibrary, isEnhancedFilterInteractivityEnabled, enableAskSage, enable2ColumnLayout, isLiveboardAlwaysOn12ColLayout, dataPanelV2 = true, updatedSpotterExperience, enableCustomColumnGroups = false, oAuthPollingInterval, isForceRedirect, dataSourceId, coverAndFilterOptionInPDF, isLiveboardStylingAndGroupingEnabled, liveboardGutter, isPNGInScheduledEmailsEnabled = false, isLiveboardXLSXCSVDownloadEnabled, isGranularXLSXCSVSchedulesEnabled, showSpotterLimitations, isCentralizedLiveboardFilterUXEnabled = false, isScopedLiveboardFilteringEnabled, isLinkParametersEnabled, updatedSpotterChatPrompt, showSpotterRadiance, enableStopAnswerGenerationEmbed, spotterChatConfig, isThisPeriodInDateFiltersEnabled, isContinuousLiveboardPDFEnabled, enableLiveboardDataCache, } = this.viewConfig;
25387
+ const { enableVizTransformations, visibleVizs, liveboardV2, vizId, hideTabPanel, activeTabId, hideLiveboardHeader, showLiveboardDescription, showLiveboardTitle, isLiveboardHeaderSticky = true, isLiveboardCompactHeaderEnabled, showLiveboardVerifiedBadge = true, showLiveboardReverifyBanner = true, hideIrrelevantChipsInLiveboardTabs, showMaskedFilterChip = false, isLiveboardMasterpiecesEnabled, newChartsLibrary, isEnhancedFilterInteractivityEnabled, enableAskSage, enable2ColumnLayout, isLiveboardAlwaysOn12ColLayout, dataPanelV2 = true, updatedSpotterExperience, enableCustomColumnGroups = false, oAuthPollingInterval, isForceRedirect, dataSourceId, coverAndFilterOptionInPDF, isLiveboardStylingAndGroupingEnabled, liveboardGutter, isPNGInScheduledEmailsEnabled = false, isLiveboardXLSXCSVDownloadEnabled, isGranularXLSXCSVSchedulesEnabled, showSpotterLimitations, isCentralizedLiveboardFilterUXEnabled = false, isScopedLiveboardFilteringEnabled, isLinkParametersEnabled, updatedSpotterChatPrompt, showSpotterRadiance, enableStopAnswerGenerationEmbed, spotterChatConfig, isThisPeriodInDateFiltersEnabled, isContinuousLiveboardPDFEnabled, enableLiveboardDataCache, spotterExperienceVersion, } = this.viewConfig;
24971
25388
  const preventLiveboardFilterRemoval = this.viewConfig.preventLiveboardFilterRemoval
24972
25389
  || this.viewConfig.preventPinboardFilterRemoval;
24973
25390
  (_a = this.fullHeightController) === null || _a === void 0 ? void 0 : _a.addQueryParams(params);
@@ -25029,6 +25446,9 @@ query GetEurekaVizSnapshots(
25029
25446
  if (isLiveboardStylingAndGroupingEnabled !== undefined) {
25030
25447
  params[Param.IsLiveboardStylingAndGroupingEnabled] = isLiveboardStylingAndGroupingEnabled;
25031
25448
  }
25449
+ if (spotterExperienceVersion !== undefined) {
25450
+ params[Param.SpotterExperienceVersion] = spotterExperienceVersion;
25451
+ }
25032
25452
  if (liveboardGutter !== undefined) {
25033
25453
  params[Param.LiveboardGutter] = liveboardGutter;
25034
25454
  }
@@ -25201,7 +25621,7 @@ query GetEurekaVizSnapshots(
25201
25621
  // instance. React builds a new instance per mount, so an equal config
25202
25622
  // is a hide/show, not a hand-over: there is nothing stale to clear.
25203
25623
  const previous = this.getPreRenderObj();
25204
- const showing = this.isSameEmbedConfig(previous)
25624
+ const previousRoute = this.isSameEmbedConfig(previous)
25205
25625
  ? undefined
25206
25626
  : previous === null || previous === void 0 ? void 0 : previous.currentLiveboardState;
25207
25627
  this.executeAfterEmbedContainerLoaded(async () => {
@@ -25209,7 +25629,7 @@ query GetEurekaVizSnapshots(
25209
25629
  // Navigate goes out first, so the container loads with the previous
25210
25630
  // config's filters.
25211
25631
  await this.preRenderParamsApplied;
25212
- if (this.isShowingLiveboardRoute(showing)) {
25632
+ if (this.isAlreadyOnSameRoute(previousRoute)) {
25213
25633
  // Navigate to the route we are already on is a no-op, so the
25214
25634
  // liveboard keeps its state. Home unmounts the container, which
25215
25635
  // clears it.
@@ -25230,18 +25650,9 @@ query GetEurekaVizSnapshots(
25230
25650
  };
25231
25651
  });
25232
25652
  }
25233
- /**
25234
- * Whether `previous` was showing what this instance is about to show.
25235
- *
25236
- * Undefined-valued keys are dropped before comparing. `navigateToLiveboard`
25237
- * assigns `vizId`, `activeTabId` and `personalizedViewId` unconditionally,
25238
- * so an instance that has been shown once carries those keys as `undefined`
25239
- * while a freshly constructed one does not have them at all. `isEqual`
25240
- * counts own keys, so without this the comparison can never be true after
25241
- * the first show — which is the whole case this exists for.
25242
- *
25243
- * Callbacks compare as equal: React passes a fresh closure per render.
25244
- */
25653
+ // definedEntries drops undefined-valued keys: a shown instance carries
25654
+ // vizId/activeTabId/etc as undefined, so a raw isEqual never matches again.
25655
+ // Functions compare equal, since React passes a fresh closure per render.
25245
25656
  isSameEmbedConfig(previous) {
25246
25657
  if (!previous)
25247
25658
  return false;
@@ -25252,14 +25663,14 @@ query GetEurekaVizSnapshots(
25252
25663
  // The whole route, not just the liveboard id: the path is built from the
25253
25664
  // viz, tab and view too, so a same-liveboard show onto another tab is a
25254
25665
  // real navigation.
25255
- isShowingLiveboardRoute(showing) {
25256
- if (!(showing === null || showing === void 0 ? void 0 : showing.liveboardId))
25666
+ isAlreadyOnSameRoute(previousRoute) {
25667
+ if (!(previousRoute === null || previousRoute === void 0 ? void 0 : previousRoute.liveboardId))
25257
25668
  return false;
25258
25669
  const { liveboardId, vizId, activeTabId, personalizedViewId, } = this.viewConfig;
25259
- return showing.liveboardId === liveboardId
25260
- && showing.vizId === vizId
25261
- && showing.activeTabId === activeTabId
25262
- && showing.personalizedViewId === personalizedViewId;
25670
+ return previousRoute.liveboardId === liveboardId
25671
+ && previousRoute.vizId === vizId
25672
+ && previousRoute.activeTabId === activeTabId
25673
+ && previousRoute.personalizedViewId === personalizedViewId;
25263
25674
  }
25264
25675
  async handleRenderForPrerender() {
25265
25676
  if (isUndefined$1(this.viewConfig.liveboardId)) {
@@ -25511,7 +25922,7 @@ query GetEurekaVizSnapshots(
25511
25922
  }
25512
25923
  getEmbedParams() {
25513
25924
  const { runtimeParameters, runtimeFilters, excludeRuntimeParametersfromURL, excludeRuntimeFiltersfromURL, } = this.viewConfig;
25514
- const queryParams = this.getEmbedParamsObject();
25925
+ const queryParams = this.getUrlQueryParamsObject();
25515
25926
  let query = '';
25516
25927
  const queryParamsString = getQueryParamString(queryParams, true);
25517
25928
  if (queryParamsString) {
@@ -25599,7 +26010,7 @@ query GetEurekaVizSnapshots(
25599
26010
  * @param dataSources A list of data source GUIDs
25600
26011
  */
25601
26012
  getIFrameSrc() {
25602
- const queryParams = this.getEmbedParamsObject();
26013
+ const queryParams = this.getUrlQueryParamsObject();
25603
26014
  const path = 'search-bar-embed';
25604
26015
  let query = '';
25605
26016
  const queryParamsString = getQueryParamString(queryParams, true);
@@ -26033,7 +26444,7 @@ query SendMessage($params: Input_convassist_SendMessageRequest) {
26033
26444
  getIframeSrc() {
26034
26445
  const { sessionId, genNo, acSessionId, acGenNo, convId, messageId, } = this.viewConfig;
26035
26446
  const path = 'conv-assist-answer';
26036
- const queryParams = this.getEmbedParamsObject();
26447
+ const queryParams = this.getUrlQueryParamsObject();
26037
26448
  let query = '';
26038
26449
  const queryParamsString = getQueryParamString(queryParams, true);
26039
26450
  if (queryParamsString) {
@@ -26230,18 +26641,22 @@ query SendMessage($params: Input_convassist_SendMessageRequest) {
26230
26641
  }
26231
26642
  }
26232
26643
  setParamIfDefined(queryParams, Param.UpdatedSpotterExperience, updatedSpotterExperience, true);
26644
+ setParamIfDefined(queryParams, Param.SpotterExperienceVersion, this.viewConfig.spotterExperienceVersion);
26233
26645
  return queryParams;
26234
26646
  }
26235
26647
  getIframeSrc() {
26236
- const { worksheetId, searchOptions, runtimeFilters, excludeRuntimeFiltersfromURL, runtimeParameters, excludeRuntimeParametersfromURL, sharedConversationId, dataSources, } = this.viewConfig;
26648
+ const { worksheetId, searchOptions, runtimeFilters, excludeRuntimeFiltersfromURL, runtimeParameters, excludeRuntimeParametersfromURL, sharedConversationId, dataSources, spotterExperienceVersion, } = this.viewConfig;
26237
26649
  // Deep-link into the read-only shared-conversation reader view when a
26238
26650
  // shared conversation id is supplied (e.g. a recipient landing from a
26239
26651
  // host-configured CONVERSATION_URL share link); otherwise the normal
26240
26652
  // Spotter conversation surface.
26241
- const path = sharedConversationId
26653
+ let path = sharedConversationId
26242
26654
  ? `insights/conv-assist/s/${encodeURIComponent(sharedConversationId)}`
26243
26655
  : 'insights/conv-assist';
26244
- const queryParams = this.getEmbedParamsObject();
26656
+ if (spotterExperienceVersion === exports.SpotterExperienceVersion.SPOTTER_2026_11) {
26657
+ path = path.replace('insights/conv-assist', 'insights/spotter');
26658
+ }
26659
+ const queryParams = this.getUrlQueryParamsObject();
26245
26660
  let query = '';
26246
26661
  const queryParamsString = getQueryParamString(queryParams, true);
26247
26662
  if (queryParamsString) {
@@ -27031,6 +27446,20 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
27031
27446
  return { filters: [...liveboardFilterParams, ...runtimeFilterParams] };
27032
27447
  }
27033
27448
 
27449
+ /**
27450
+ * Route the ThoughtSpot application uses to render a single conversational
27451
+ * answer. Used when a replayed frame carries no route of its own.
27452
+ */
27453
+ const CONV_ASSIST_ANSWER_ROUTE = '/embed/conv-assist-answer';
27454
+ /**
27455
+ * Base path of the conversation service, proxied by the cluster's nginx as
27456
+ * the `convex` upstream. These are the same handlers the public
27457
+ * `/api/rest/2.0/ai/agent/conversations/...` endpoints proxy to, so the
27458
+ * response shapes are identical, but calling them directly skips the prism
27459
+ * hop and its error re-wrapping.
27460
+ */
27461
+ const CONVERSATION_SERVICE_PATH = '/conversation/v2';
27462
+ const DEFAULT_STALE_ANSWER_NOTICE = 'This data may have changed since the last time you had a chat.';
27034
27463
  /**
27035
27464
  * Starts an automatic renderer that watches the DOM for iframes containing
27036
27465
  * the `tsmcp=true` query parameter and replaces them with fully configured
@@ -27093,6 +27522,111 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
27093
27522
  observer.observe(document.body, { childList: true, subtree: true });
27094
27523
  return observer;
27095
27524
  }
27525
+ /**
27526
+ * Writes resolved session parameters into the route's hash query string,
27527
+ * preserving the route and any other hash params the source URL carried.
27528
+ *
27529
+ * @param sourceHash - The source URL's hash, with or without a leading `#`.
27530
+ * Falls back to the conversational-answer route when empty, so a host app
27531
+ * replaying a chat need only supply the conversation identifier.
27532
+ */
27533
+ function buildAnswerHash(sourceHash, resolved) {
27534
+ const withoutHash = (sourceHash || '').replace('#', '');
27535
+ const [route, existingQuery] = withoutHash.split('?');
27536
+ const params = new URLSearchParams(existingQuery || '');
27537
+ Object.entries(resolved).forEach(([key, value]) => params.set(key, value));
27538
+ return `${route || CONV_ASSIST_ANSWER_ROUTE}?${params.toString()}`;
27539
+ }
27540
+ /**
27541
+ * Reads {@link Param.TsmcpAnswerIndex} as a whole, non-negative array index.
27542
+ *
27543
+ * Anything else - absent, malformed, fractional, negative - falls back to the
27544
+ * first answer rather than indexing with a value that can never match.
27545
+ */
27546
+ function answerIndexFromParam(raw) {
27547
+ const parsed = Number(raw);
27548
+ return Number.isInteger(parsed) && parsed >= 0 ? parsed : 0;
27549
+ }
27550
+ /**
27551
+ * In-flight answer-id list requests, keyed by conversation-service URL.
27552
+ *
27553
+ * Replaying a stored chat mounts every one of its frames at once, and each
27554
+ * frame resolves on its own. Without this, N frames from one conversation make
27555
+ * N identical list calls. Sharing the in-flight request collapses them to one.
27556
+ *
27557
+ * Only the id list is shared, and only while its request is in flight: the
27558
+ * entry is dropped once the request settles, whether it succeeded or not. A
27559
+ * failed response is therefore never reused, and a frame mounted later always
27560
+ * reads a fresh list. The per-answer load call is never shared - it returns
27561
+ * live session state with its own expiry.
27562
+ */
27563
+ const answerIdListRequests = new Map();
27564
+ /**
27565
+ * Lists a conversation's answer ids: its non-thinking `answer` items, in
27566
+ * message order. The host app counts answers the same way, so the Nth id here
27567
+ * is the Nth stored answer.
27568
+ *
27569
+ * @param conversationUrl - The conversation's base URL on the conversation
27570
+ * service, `{host}/conversation/v2/{encoded id}`.
27571
+ * @param conversationId - The conversation identifier, used in log messages.
27572
+ * @returns The ids, or `null` when the conversation cannot be read. Never
27573
+ * rejects, so callers sharing the request need no error handling of their own.
27574
+ */
27575
+ async function fetchAnswerIds(conversationUrl, conversationId) {
27576
+ try {
27577
+ const messagesResponse = await tokenizedFetch(`${conversationUrl}/public`, {
27578
+ credentials: 'include',
27579
+ headers: { Accept: 'application/json' },
27580
+ });
27581
+ if (!messagesResponse.ok) {
27582
+ logger$3.warn(`[AutoFrameRenderer] Conversation fetch failed for ${conversationId}: ${messagesResponse.status}`);
27583
+ return null;
27584
+ }
27585
+ const messagesBody = await messagesResponse.json();
27586
+ const messages = messagesBody === null || messagesBody === void 0 ? void 0 : messagesBody.messages;
27587
+ const answerIds = [];
27588
+ for (const message of Array.isArray(messages) ? messages : []) {
27589
+ for (const item of (message === null || message === void 0 ? void 0 : message.response_items) || []) {
27590
+ if ((item === null || item === void 0 ? void 0 : item.type) === 'answer' && (item === null || item === void 0 ? void 0 : item.is_thinking) === false && (item === null || item === void 0 ? void 0 : item.answer_id)) {
27591
+ answerIds.push(item.answer_id);
27592
+ }
27593
+ }
27594
+ }
27595
+ return answerIds;
27596
+ }
27597
+ catch (e) {
27598
+ logger$3.warn(`[AutoFrameRenderer] Failed to list answers for ${conversationId}: ${e}`);
27599
+ return null;
27600
+ }
27601
+ }
27602
+ /**
27603
+ * The answer-id list for a conversation, joining a request already in flight
27604
+ * for it.
27605
+ *
27606
+ * @param conversationUrl - The conversation's base URL on the conversation
27607
+ * service. Also the key requests are shared under.
27608
+ * @param conversationId - The conversation identifier, used in log messages.
27609
+ * @param stale - A request the caller already read and found too short. It is
27610
+ * not reused; the first caller to pass it starts a new request, and the
27611
+ * others join that one.
27612
+ * @returns The shared request: the ids, or `null` when the conversation cannot
27613
+ * be read. Never rejects.
27614
+ */
27615
+ function getAnswerIds(conversationUrl, conversationId, stale) {
27616
+ const inFlight = answerIdListRequests.get(conversationUrl);
27617
+ if (inFlight && inFlight !== stale) {
27618
+ return inFlight;
27619
+ }
27620
+ const request = fetchAnswerIds(conversationUrl, conversationId);
27621
+ answerIdListRequests.set(conversationUrl, request);
27622
+ const release = () => {
27623
+ if (answerIdListRequests.get(conversationUrl) === request) {
27624
+ answerIdListRequests.delete(conversationUrl);
27625
+ }
27626
+ };
27627
+ request.then(release, release);
27628
+ return request;
27629
+ }
27096
27630
  function isTSMCPIframe(iframe) {
27097
27631
  try {
27098
27632
  const url = new URL(iframe.src);
@@ -27126,20 +27660,112 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
27126
27660
  * ThoughtSpot application.
27127
27661
  *
27128
27662
  * @param sourceSrc - The original iframe's `src` URL string.
27663
+ * @param preserveSourceUrl - When true, return the source URL unchanged.
27129
27664
  * @returns The constructed URL to use for the ThoughtSpot embed iframe.
27130
27665
  */
27131
- getMCPIframeSrc(sourceSrc) {
27132
- const queryParams = this.getEmbedParamsObject();
27666
+ getMCPIframeSrc(sourceSrc, resolved, preserveSourceUrl = false) {
27667
+ if (preserveSourceUrl) {
27668
+ return sourceSrc;
27669
+ }
27670
+ const queryParams = this.getUrlQueryParamsObject();
27133
27671
  const sourceURL = new URL(sourceSrc);
27134
27672
  const existingQueryParams = sourceURL.searchParams;
27135
27673
  const existingQueryParamsObject = Object.fromEntries(existingQueryParams);
27136
27674
  delete existingQueryParamsObject[Param.Tsmcp];
27675
+ // Replay markers address the SDK, not the ThoughtSpot application.
27676
+ delete existingQueryParamsObject[Param.TsmcpConversationId];
27677
+ delete existingQueryParamsObject[Param.TsmcpAnswerIndex];
27137
27678
  const mergedQueryParams = { ...queryParams, ...existingQueryParamsObject };
27138
27679
  const mergedQueryParamsString = getQueryParamString(mergedQueryParams, true);
27139
27680
  const queryString = mergedQueryParamsString ? `?${mergedQueryParamsString}` : '';
27140
- const frameSrc = `${this.getEmbedBasePath(queryString)}${sourceURL.hash.replace('#', '')}`;
27681
+ const hash = resolved
27682
+ ? buildAnswerHash(sourceURL.hash, resolved)
27683
+ : sourceURL.hash.replace('#', '');
27684
+ const frameSrc = `${this.getEmbedBasePath(queryString)}${hash}`;
27141
27685
  return frameSrc;
27142
27686
  }
27687
+ /**
27688
+ * Resolves the current session parameters for an answer stored only as a
27689
+ * conversation identifier plus an ordinal position.
27690
+ *
27691
+ * The answer object behind `sessionId`/`genNo` expires (roughly 8 hours),
27692
+ * so a host app replaying a stored chat cannot persist those values. It
27693
+ * persists the conversation identifier instead, and this walks the two
27694
+ * conversation-service APIs to rebuild them:
27695
+ *
27696
+ * 1. `GET {conv}/public` lists the conversation's messages; the
27697
+ * non-thinking `answer` items, in message order, give the answer ids.
27698
+ * Frames from the same conversation share one in-flight call - see
27699
+ * {@link getAnswerIds}.
27700
+ * 2. `POST {conv}/message/{id}/load/public` turns the answer id at
27701
+ * `answerIndex` into a live session identifier, generation number and
27702
+ * agent-context state.
27703
+ *
27704
+ * @returns The resolved parameters, or `null` when resolution fails - the
27705
+ * caller then falls back to whatever the source URL already carried.
27706
+ */
27707
+ async resolveAnswerSessionParams(conversationId, answerIndex) {
27708
+ const base = `${this.thoughtSpotHost}${CONVERSATION_SERVICE_PATH}/${encodeURIComponent(conversationId)}`;
27709
+ try {
27710
+ const listRequest = getAnswerIds(base, conversationId);
27711
+ let answerIds = await listRequest;
27712
+ if (answerIds && !answerIds[answerIndex]) {
27713
+ // The list only grows, so a short one may predate this answer:
27714
+ // a frame that joined a request started before it was added.
27715
+ // Read the list once more before giving up.
27716
+ answerIds = await getAnswerIds(base, conversationId, listRequest);
27717
+ }
27718
+ if (!answerIds) {
27719
+ return null;
27720
+ }
27721
+ const answerId = answerIds[answerIndex];
27722
+ if (!answerId) {
27723
+ logger$3.warn(`[AutoFrameRenderer] No answer at index ${answerIndex} in conversation ${conversationId} (found ${answerIds.length}).`);
27724
+ return null;
27725
+ }
27726
+ // The load handler is a POST upstream; the public REST endpoint
27727
+ // exposed it as a GET and supplied this body on the caller's
27728
+ // behalf.
27729
+ const detailsResponse = await tokenizedFetch(`${base}/message/${encodeURIComponent(answerId)}/load/public`, {
27730
+ credentials: 'include',
27731
+ method: 'POST',
27732
+ headers: {
27733
+ Accept: 'application/json',
27734
+ 'Content-Type': 'application/json',
27735
+ 'x-requested-by': 'ThoughtSpot',
27736
+ },
27737
+ body: JSON.stringify({ type: 'TS_ANSWER' }),
27738
+ });
27739
+ if (!detailsResponse.ok) {
27740
+ logger$3.warn(`[AutoFrameRenderer] Answer load failed for ${answerId}: ${detailsResponse.status}`);
27741
+ return null;
27742
+ }
27743
+ const detailsBody = await detailsResponse.json();
27744
+ const answer = detailsBody === null || detailsBody === void 0 ? void 0 : detailsBody.answer;
27745
+ const acState = answer === null || answer === void 0 ? void 0 : answer.ac_state;
27746
+ // All four are nullable in the load-answer response. A missing
27747
+ // generation number is as unusable as a missing session id:
27748
+ // stringifying it would put a literal "null" in the hash. Fail
27749
+ // the resolve instead and let the caller fall back.
27750
+ if (!(answer === null || answer === void 0 ? void 0 : answer.session_identifier)
27751
+ || !(acState === null || acState === void 0 ? void 0 : acState.transaction_identifier)
27752
+ || !(Number.isInteger(answer.generation_number) && answer.generation_number > 0)
27753
+ || !(Number.isInteger(acState.generation_number) && acState.generation_number > 0)) {
27754
+ logger$3.warn(`[AutoFrameRenderer] Answer load returned incomplete session state for ${answerId}.`);
27755
+ return null;
27756
+ }
27757
+ return {
27758
+ sessionId: answer.session_identifier,
27759
+ genNo: String(answer.generation_number),
27760
+ acSessionId: acState.transaction_identifier,
27761
+ acGenNo: String(acState.generation_number),
27762
+ };
27763
+ }
27764
+ catch (e) {
27765
+ logger$3.warn(`[AutoFrameRenderer] Failed to resolve stored answer: ${e}`);
27766
+ return null;
27767
+ }
27768
+ }
27143
27769
  /**
27144
27770
  * Overrides the base insertion behavior so the new embed iframe
27145
27771
  * replaces the original iframe in-place rather than being appended
@@ -27168,10 +27794,37 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
27168
27794
  if (this.shouldWaitForRenderPromise) {
27169
27795
  await this.isReadyForRenderPromise;
27170
27796
  }
27171
- const src = this.getMCPIframeSrc(iframe.src);
27797
+ // Only frames that ask for it take the replay path. A frame straight
27798
+ // from the MCP server carries its own session params and no
27799
+ // conversation id, so it renders exactly as it always has.
27800
+ const sourceParams = new URL(iframe.src).searchParams;
27801
+ const conversationId = sourceParams.get(Param.TsmcpConversationId);
27802
+ let resolved = null;
27803
+ if (conversationId) {
27804
+ resolved = await this.resolveAnswerSessionParams(conversationId, answerIndexFromParam(sourceParams.get(Param.TsmcpAnswerIndex)));
27805
+ }
27806
+ const src = this.getMCPIframeSrc(iframe.src, resolved !== null && resolved !== void 0 ? resolved : undefined, Boolean(conversationId) && !resolved);
27172
27807
  await this.renderIFrame(src);
27808
+ // Mark only answers actually re-resolved: their numbers were computed
27809
+ // now, not when the conversation happened.
27810
+ if (resolved && !this.viewConfig.suppressStaleAnswerNotice) {
27811
+ this.markAsStaleAnswer();
27812
+ }
27173
27813
  this.isRendered = true;
27174
27814
  }
27815
+ /**
27816
+ * Adds the "data may have changed" notice to the rendered frame as a
27817
+ * native tooltip, so it needs no stylesheet and cannot disturb the host
27818
+ * app's layout.
27819
+ */
27820
+ markAsStaleAnswer() {
27821
+ if (!this.iFrame) {
27822
+ return;
27823
+ }
27824
+ this.iFrame.title = this.viewConfig.staleAnswerNoticeText || DEFAULT_STALE_ANSWER_NOTICE;
27825
+ // Exposed so a host app can style or replace the native tooltip.
27826
+ this.iFrame.dataset.tsStaleAnswer = 'true';
27827
+ }
27175
27828
  }
27176
27829
 
27177
27830
  const ALIAS = Symbol.for('yaml.alias');