@thoughtspot/visual-embed-sdk 1.50.0 → 1.51.0-test
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.
- package/cjs/package.json +1 -1
- package/cjs/src/config.d.ts +1 -0
- package/cjs/src/config.d.ts.map +1 -1
- package/cjs/src/config.js +2 -1
- package/cjs/src/config.js.map +1 -1
- package/cjs/src/css-variables.d.ts +122 -0
- package/cjs/src/css-variables.d.ts.map +1 -1
- package/cjs/src/embed/app.d.ts +176 -24
- package/cjs/src/embed/app.d.ts.map +1 -1
- package/cjs/src/embed/app.js +86 -38
- package/cjs/src/embed/app.js.map +1 -1
- package/cjs/src/embed/app.spec.js +672 -150
- package/cjs/src/embed/app.spec.js.map +1 -1
- package/cjs/src/embed/base.d.ts +1 -1
- package/cjs/src/embed/base.js +1 -1
- package/cjs/src/embed/conversation.d.ts +401 -2
- package/cjs/src/embed/conversation.d.ts.map +1 -1
- package/cjs/src/embed/conversation.js +32 -16
- package/cjs/src/embed/conversation.js.map +1 -1
- package/cjs/src/embed/conversation.spec.js +346 -17
- package/cjs/src/embed/conversation.spec.js.map +1 -1
- package/cjs/src/embed/events.spec.js +638 -0
- package/cjs/src/embed/events.spec.js.map +1 -1
- package/cjs/src/embed/host-events.spec.js +187 -0
- package/cjs/src/embed/host-events.spec.js.map +1 -1
- package/cjs/src/embed/hostEventClient/contracts.d.ts +51 -14
- package/cjs/src/embed/hostEventClient/contracts.d.ts.map +1 -1
- package/cjs/src/embed/hostEventClient/contracts.js +11 -1
- package/cjs/src/embed/hostEventClient/contracts.js.map +1 -1
- package/cjs/src/embed/hostEventClient/host-event-client.d.ts +2 -1
- package/cjs/src/embed/hostEventClient/host-event-client.d.ts.map +1 -1
- package/cjs/src/embed/hostEventClient/host-event-client.js +9 -0
- package/cjs/src/embed/hostEventClient/host-event-client.js.map +1 -1
- package/cjs/src/embed/hostEventClient/host-event-client.spec.js +236 -0
- package/cjs/src/embed/hostEventClient/host-event-client.spec.js.map +1 -1
- package/cjs/src/embed/hostEventClient/utils.d.ts +2 -0
- package/cjs/src/embed/hostEventClient/utils.d.ts.map +1 -1
- package/cjs/src/embed/hostEventClient/utils.js +32 -2
- package/cjs/src/embed/hostEventClient/utils.js.map +1 -1
- package/cjs/src/embed/hostEventClient/utils.spec.js +178 -0
- package/cjs/src/embed/hostEventClient/utils.spec.js.map +1 -1
- package/cjs/src/embed/liveboard.d.ts +81 -13
- package/cjs/src/embed/liveboard.d.ts.map +1 -1
- package/cjs/src/embed/liveboard.js +50 -9
- package/cjs/src/embed/liveboard.js.map +1 -1
- package/cjs/src/embed/liveboard.spec.js +432 -4
- package/cjs/src/embed/liveboard.spec.js.map +1 -1
- package/cjs/src/embed/spotter-utils.d.ts +15 -1
- package/cjs/src/embed/spotter-utils.d.ts.map +1 -1
- package/cjs/src/embed/spotter-utils.js +28 -1
- package/cjs/src/embed/spotter-utils.js.map +1 -1
- package/cjs/src/embed/spotter-utils.spec.js +129 -0
- package/cjs/src/embed/spotter-utils.spec.js.map +1 -1
- package/cjs/src/embed/spotter-viz-utils.d.ts +37 -4
- package/cjs/src/embed/spotter-viz-utils.d.ts.map +1 -1
- package/cjs/src/embed/spotter-viz-utils.js.map +1 -1
- package/cjs/src/embed/spotter-viz-utils.spec.js +17 -0
- package/cjs/src/embed/spotter-viz-utils.spec.js.map +1 -1
- package/cjs/src/embed/ts-embed.d.ts +16 -8
- package/cjs/src/embed/ts-embed.d.ts.map +1 -1
- package/cjs/src/embed/ts-embed.js +96 -37
- package/cjs/src/embed/ts-embed.js.map +1 -1
- package/cjs/src/embed/ts-embed.spec.js +683 -3
- package/cjs/src/embed/ts-embed.spec.js.map +1 -1
- package/cjs/src/errors.d.ts +1 -0
- package/cjs/src/errors.d.ts.map +1 -1
- package/cjs/src/errors.js +1 -0
- package/cjs/src/errors.js.map +1 -1
- package/cjs/src/index.d.ts +3 -3
- package/cjs/src/index.d.ts.map +1 -1
- package/cjs/src/index.js +4 -2
- package/cjs/src/index.js.map +1 -1
- package/cjs/src/mixpanel-service.d.ts +4 -0
- package/cjs/src/mixpanel-service.d.ts.map +1 -1
- package/cjs/src/mixpanel-service.js +4 -0
- package/cjs/src/mixpanel-service.js.map +1 -1
- package/cjs/src/react/all-types-export.d.ts +1 -1
- package/cjs/src/react/all-types-export.d.ts.map +1 -1
- package/cjs/src/react/all-types-export.js +2 -1
- package/cjs/src/react/all-types-export.js.map +1 -1
- package/cjs/src/react/all-types-export.parity.spec.d.ts +2 -0
- package/cjs/src/react/all-types-export.parity.spec.d.ts.map +1 -0
- package/cjs/src/react/all-types-export.parity.spec.js +194 -0
- package/cjs/src/react/all-types-export.parity.spec.js.map +1 -0
- package/cjs/src/react/index.d.ts +66 -32
- package/cjs/src/react/index.d.ts.map +1 -1
- package/cjs/src/react/index.js +5 -3
- package/cjs/src/react/index.js.map +1 -1
- package/cjs/src/react/index.spec.js +101 -0
- package/cjs/src/react/index.spec.js.map +1 -1
- package/cjs/src/react/util.spec.js +251 -0
- package/cjs/src/react/util.spec.js.map +1 -1
- package/cjs/src/types.d.ts +902 -28
- package/cjs/src/types.d.ts.map +1 -1
- package/cjs/src/types.js +701 -14
- package/cjs/src/types.js.map +1 -1
- package/cjs/src/utils/processData.spec.js +93 -0
- package/cjs/src/utils/processData.spec.js.map +1 -1
- package/cjs/src/utils/processTrigger.spec.js +61 -0
- package/cjs/src/utils/processTrigger.spec.js.map +1 -1
- package/cjs/src/utils.spec.js +4 -0
- package/cjs/src/utils.spec.js.map +1 -1
- package/dist/{index-B5xoN6Cp.js → index-Bivg-mDx.js} +1 -1
- package/dist/src/config.d.ts +1 -0
- package/dist/src/config.d.ts.map +1 -1
- package/dist/src/css-variables.d.ts +122 -0
- package/dist/src/css-variables.d.ts.map +1 -1
- package/dist/src/embed/app.d.ts +176 -24
- package/dist/src/embed/app.d.ts.map +1 -1
- package/dist/src/embed/base.d.ts +1 -1
- package/dist/src/embed/conversation.d.ts +401 -2
- package/dist/src/embed/conversation.d.ts.map +1 -1
- package/dist/src/embed/hostEventClient/contracts.d.ts +51 -14
- package/dist/src/embed/hostEventClient/contracts.d.ts.map +1 -1
- package/dist/src/embed/hostEventClient/host-event-client.d.ts +2 -1
- package/dist/src/embed/hostEventClient/host-event-client.d.ts.map +1 -1
- package/dist/src/embed/hostEventClient/utils.d.ts +2 -0
- package/dist/src/embed/hostEventClient/utils.d.ts.map +1 -1
- package/dist/src/embed/liveboard.d.ts +81 -13
- package/dist/src/embed/liveboard.d.ts.map +1 -1
- package/dist/src/embed/spotter-utils.d.ts +15 -1
- package/dist/src/embed/spotter-utils.d.ts.map +1 -1
- package/dist/src/embed/spotter-viz-utils.d.ts +37 -4
- package/dist/src/embed/spotter-viz-utils.d.ts.map +1 -1
- package/dist/src/embed/ts-embed.d.ts +16 -8
- package/dist/src/embed/ts-embed.d.ts.map +1 -1
- package/dist/src/errors.d.ts +1 -0
- package/dist/src/errors.d.ts.map +1 -1
- package/dist/src/index.d.ts +3 -3
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/mixpanel-service.d.ts +4 -0
- package/dist/src/mixpanel-service.d.ts.map +1 -1
- package/dist/src/react/all-types-export.d.ts +1 -1
- package/dist/src/react/all-types-export.d.ts.map +1 -1
- package/dist/src/react/all-types-export.parity.spec.d.ts +2 -0
- package/dist/src/react/all-types-export.parity.spec.d.ts.map +1 -0
- package/dist/src/react/index.d.ts +66 -32
- package/dist/src/react/index.d.ts.map +1 -1
- package/dist/src/types.d.ts +902 -28
- package/dist/src/types.d.ts.map +1 -1
- package/dist/tsembed-react.es.js +1269 -206
- package/dist/tsembed-react.js +1268 -205
- package/dist/tsembed.es.js +1364 -304
- package/dist/tsembed.js +1362 -302
- package/dist/visual-embed-sdk-react-full.d.ts +1867 -157
- package/dist/visual-embed-sdk-react.d.ts +1872 -161
- package/dist/visual-embed-sdk.d.ts +1815 -127
- package/lib/package.json +1 -1
- package/lib/src/config.d.ts +1 -0
- package/lib/src/config.d.ts.map +1 -1
- package/lib/src/config.js +1 -0
- package/lib/src/config.js.map +1 -1
- package/lib/src/css-variables.d.ts +122 -0
- package/lib/src/css-variables.d.ts.map +1 -1
- package/lib/src/embed/app.d.ts +176 -24
- package/lib/src/embed/app.d.ts.map +1 -1
- package/lib/src/embed/app.js +87 -39
- package/lib/src/embed/app.js.map +1 -1
- package/lib/src/embed/app.spec.js +673 -151
- package/lib/src/embed/app.spec.js.map +1 -1
- package/lib/src/embed/base.d.ts +1 -1
- package/lib/src/embed/base.js +1 -1
- package/lib/src/embed/conversation.d.ts +401 -2
- package/lib/src/embed/conversation.d.ts.map +1 -1
- package/lib/src/embed/conversation.js +33 -17
- package/lib/src/embed/conversation.js.map +1 -1
- package/lib/src/embed/conversation.spec.js +347 -18
- package/lib/src/embed/conversation.spec.js.map +1 -1
- package/lib/src/embed/events.spec.js +638 -0
- package/lib/src/embed/events.spec.js.map +1 -1
- package/lib/src/embed/host-events.spec.js +188 -1
- package/lib/src/embed/host-events.spec.js.map +1 -1
- package/lib/src/embed/hostEventClient/contracts.d.ts +51 -14
- package/lib/src/embed/hostEventClient/contracts.d.ts.map +1 -1
- package/lib/src/embed/hostEventClient/contracts.js +10 -0
- package/lib/src/embed/hostEventClient/contracts.js.map +1 -1
- package/lib/src/embed/hostEventClient/host-event-client.d.ts +2 -1
- package/lib/src/embed/hostEventClient/host-event-client.d.ts.map +1 -1
- package/lib/src/embed/hostEventClient/host-event-client.js +10 -1
- package/lib/src/embed/hostEventClient/host-event-client.js.map +1 -1
- package/lib/src/embed/hostEventClient/host-event-client.spec.js +236 -0
- package/lib/src/embed/hostEventClient/host-event-client.spec.js.map +1 -1
- package/lib/src/embed/hostEventClient/utils.d.ts +2 -0
- package/lib/src/embed/hostEventClient/utils.d.ts.map +1 -1
- package/lib/src/embed/hostEventClient/utils.js +28 -1
- package/lib/src/embed/hostEventClient/utils.js.map +1 -1
- package/lib/src/embed/hostEventClient/utils.spec.js +179 -1
- package/lib/src/embed/hostEventClient/utils.spec.js.map +1 -1
- package/lib/src/embed/liveboard.d.ts +81 -13
- package/lib/src/embed/liveboard.d.ts.map +1 -1
- package/lib/src/embed/liveboard.js +50 -9
- package/lib/src/embed/liveboard.js.map +1 -1
- package/lib/src/embed/liveboard.spec.js +432 -4
- package/lib/src/embed/liveboard.spec.js.map +1 -1
- package/lib/src/embed/spotter-utils.d.ts +15 -1
- package/lib/src/embed/spotter-utils.d.ts.map +1 -1
- package/lib/src/embed/spotter-utils.js +25 -0
- package/lib/src/embed/spotter-utils.js.map +1 -1
- package/lib/src/embed/spotter-utils.spec.js +130 -1
- package/lib/src/embed/spotter-utils.spec.js.map +1 -1
- package/lib/src/embed/spotter-viz-utils.d.ts +37 -4
- package/lib/src/embed/spotter-viz-utils.d.ts.map +1 -1
- package/lib/src/embed/spotter-viz-utils.js.map +1 -1
- package/lib/src/embed/spotter-viz-utils.spec.js +17 -0
- package/lib/src/embed/spotter-viz-utils.spec.js.map +1 -1
- package/lib/src/embed/ts-embed.d.ts +16 -8
- package/lib/src/embed/ts-embed.d.ts.map +1 -1
- package/lib/src/embed/ts-embed.js +96 -37
- package/lib/src/embed/ts-embed.js.map +1 -1
- package/lib/src/embed/ts-embed.spec.js +683 -3
- package/lib/src/embed/ts-embed.spec.js.map +1 -1
- package/lib/src/errors.d.ts +1 -0
- package/lib/src/errors.d.ts.map +1 -1
- package/lib/src/errors.js +1 -0
- package/lib/src/errors.js.map +1 -1
- package/lib/src/index.d.ts +3 -3
- package/lib/src/index.d.ts.map +1 -1
- package/lib/src/index.js +3 -3
- package/lib/src/index.js.map +1 -1
- package/lib/src/mixpanel-service.d.ts +4 -0
- package/lib/src/mixpanel-service.d.ts.map +1 -1
- package/lib/src/mixpanel-service.js +4 -0
- package/lib/src/mixpanel-service.js.map +1 -1
- package/lib/src/react/all-types-export.d.ts +1 -1
- package/lib/src/react/all-types-export.d.ts.map +1 -1
- package/lib/src/react/all-types-export.js +1 -1
- package/lib/src/react/all-types-export.js.map +1 -1
- package/lib/src/react/all-types-export.parity.spec.d.ts +2 -0
- package/lib/src/react/all-types-export.parity.spec.d.ts.map +1 -0
- package/lib/src/react/all-types-export.parity.spec.js +191 -0
- package/lib/src/react/all-types-export.parity.spec.js.map +1 -0
- package/lib/src/react/index.d.ts +66 -32
- package/lib/src/react/index.d.ts.map +1 -1
- package/lib/src/react/index.js +5 -3
- package/lib/src/react/index.js.map +1 -1
- package/lib/src/react/index.spec.js +102 -1
- package/lib/src/react/index.spec.js.map +1 -1
- package/lib/src/react/util.spec.js +251 -0
- package/lib/src/react/util.spec.js.map +1 -1
- package/lib/src/types.d.ts +902 -28
- package/lib/src/types.d.ts.map +1 -1
- package/lib/src/types.js +701 -14
- package/lib/src/types.js.map +1 -1
- package/lib/src/utils/processData.spec.js +93 -0
- package/lib/src/utils/processData.spec.js.map +1 -1
- package/lib/src/utils/processTrigger.spec.js +61 -0
- package/lib/src/utils/processTrigger.spec.js.map +1 -1
- package/lib/src/utils.spec.js +4 -0
- package/lib/src/utils.spec.js.map +1 -1
- package/lib/src/visual-embed-sdk.d.ts +1815 -127
- package/package.json +1 -1
- package/src/config.ts +1 -0
- package/src/css-variables.ts +150 -0
- package/src/embed/app.spec.ts +877 -196
- package/src/embed/app.ts +276 -75
- package/src/embed/base.ts +1 -1
- package/src/embed/conversation.spec.ts +411 -21
- package/src/embed/conversation.ts +441 -18
- package/src/embed/events.spec.ts +761 -1
- package/src/embed/host-events.spec.ts +242 -0
- package/src/embed/hostEventClient/contracts.ts +57 -14
- package/src/embed/hostEventClient/host-event-client.spec.ts +372 -0
- package/src/embed/hostEventClient/host-event-client.ts +18 -2
- package/src/embed/hostEventClient/utils.spec.ts +204 -0
- package/src/embed/hostEventClient/utils.ts +37 -10
- package/src/embed/liveboard.spec.ts +565 -4
- package/src/embed/liveboard.ts +155 -28
- package/src/embed/spotter-utils.spec.ts +140 -1
- package/src/embed/spotter-utils.ts +36 -1
- package/src/embed/spotter-viz-utils.spec.ts +17 -0
- package/src/embed/spotter-viz-utils.ts +37 -4
- package/src/embed/ts-embed.spec.ts +885 -3
- package/src/embed/ts-embed.ts +111 -39
- package/src/errors.ts +1 -0
- package/src/index.ts +45 -2
- package/src/mixpanel-service.ts +4 -0
- package/src/react/all-types-export.parity.spec.ts +208 -0
- package/src/react/all-types-export.ts +22 -0
- package/src/react/index.spec.tsx +158 -0
- package/src/react/index.tsx +70 -33
- package/src/react/util.spec.tsx +255 -0
- package/src/types.ts +904 -24
- package/src/utils/processData.spec.ts +97 -0
- package/src/utils/processTrigger.spec.ts +91 -0
- package/src/utils.spec.ts +5 -0
package/src/embed/ts-embed.ts
CHANGED
|
@@ -10,6 +10,7 @@ import isEqual from 'lodash/isEqual';
|
|
|
10
10
|
import isEmpty from 'lodash/isEmpty';
|
|
11
11
|
import isObject from 'lodash/isObject';
|
|
12
12
|
import {
|
|
13
|
+
HostEventRequest,
|
|
13
14
|
TriggerPayload,
|
|
14
15
|
TriggerResponse,
|
|
15
16
|
UIPassthroughArrayResponse,
|
|
@@ -66,6 +67,8 @@ import {
|
|
|
66
67
|
MessagePayload,
|
|
67
68
|
ContextType,
|
|
68
69
|
ContextObject,
|
|
70
|
+
PreRenderConfig,
|
|
71
|
+
BaseViewConfig,
|
|
69
72
|
} from '../types';
|
|
70
73
|
import { uploadMixpanelEvent, MIXPANEL_EVENT } from '../mixpanel-service';
|
|
71
74
|
import { processEventData, processAuthFailure } from '../utils/processData';
|
|
@@ -206,7 +209,7 @@ export class TsEmbed {
|
|
|
206
209
|
|
|
207
210
|
private resizeObserver: ResizeObserver;
|
|
208
211
|
|
|
209
|
-
private preRenderContainerEl: HTMLElement
|
|
212
|
+
private preRenderContainerEl: HTMLElement = document.body;
|
|
210
213
|
|
|
211
214
|
private containerScrollListener: (() => void) | null = null;
|
|
212
215
|
|
|
@@ -771,6 +774,7 @@ export class TsEmbed {
|
|
|
771
774
|
insertInToSlide,
|
|
772
775
|
disableRedirectionLinksInNewTab,
|
|
773
776
|
overrideOrgId,
|
|
777
|
+
overrideHistoryState,
|
|
774
778
|
exposeTranslationIDs,
|
|
775
779
|
primaryAction,
|
|
776
780
|
} = this.viewConfig;
|
|
@@ -869,6 +873,9 @@ export class TsEmbed {
|
|
|
869
873
|
if (overrideOrgId !== undefined) {
|
|
870
874
|
queryParams[Param.OverrideOrgId] = overrideOrgId;
|
|
871
875
|
}
|
|
876
|
+
if (overrideHistoryState !== undefined) {
|
|
877
|
+
queryParams[Param.OverrideHistoryState] = overrideHistoryState;
|
|
878
|
+
}
|
|
872
879
|
|
|
873
880
|
if (this.isPreAuthCacheEnabled()) {
|
|
874
881
|
queryParams[Param.preAuthCache] = true;
|
|
@@ -955,11 +962,27 @@ export class TsEmbed {
|
|
|
955
962
|
return iFrame;
|
|
956
963
|
}
|
|
957
964
|
|
|
965
|
+
/**
|
|
966
|
+
* Returns a merged {@link PreRenderConfig} object where each shared key
|
|
967
|
+
* prefers `preRenderConfig.key` over the top-level `viewConfig.key` for
|
|
968
|
+
* backward compatibility.
|
|
969
|
+
*/
|
|
970
|
+
protected getPreRenderConfig(): PreRenderConfig {
|
|
971
|
+
const viewCfg = this.viewConfig as BaseViewConfig;
|
|
972
|
+
const preRenderCfg = viewCfg.preRenderConfig ?? {};
|
|
973
|
+
return {
|
|
974
|
+
...preRenderCfg,
|
|
975
|
+
preRenderId: preRenderCfg.preRenderId ?? viewCfg.preRenderId,
|
|
976
|
+
preRenderContainer: preRenderCfg.preRenderContainer ?? viewCfg.preRenderContainer,
|
|
977
|
+
doNotTrackPreRenderSize: preRenderCfg.doNotTrackPreRenderSize ?? viewCfg.doNotTrackPreRenderSize,
|
|
978
|
+
};
|
|
979
|
+
}
|
|
980
|
+
|
|
958
981
|
/**
|
|
959
982
|
* Returns true if this embed instance is configured for pre-rendering.
|
|
960
983
|
*/
|
|
961
984
|
protected isPreRenderEmbed() {
|
|
962
|
-
return !!this.
|
|
985
|
+
return !!this.getPreRenderConfig().preRenderId;
|
|
963
986
|
}
|
|
964
987
|
protected handleInsertionIntoDOM(child: string | Node): void {
|
|
965
988
|
if (this.isPreRenderEmbed()) {
|
|
@@ -1115,6 +1138,7 @@ export class TsEmbed {
|
|
|
1115
1138
|
this.setIframeElement(this.preRenderChild);
|
|
1116
1139
|
}
|
|
1117
1140
|
this.isRendered = true;
|
|
1141
|
+
this.inheritPreRenderContainer();
|
|
1118
1142
|
}
|
|
1119
1143
|
|
|
1120
1144
|
return this.isPreRenderConnected();
|
|
@@ -1172,7 +1196,7 @@ export class TsEmbed {
|
|
|
1172
1196
|
* fresh element; an element passed directly cannot be re-resolved.
|
|
1173
1197
|
*/
|
|
1174
1198
|
private resolvePreRenderContainerTarget(): HTMLElement {
|
|
1175
|
-
const containerConfig = this.
|
|
1199
|
+
const containerConfig = this.getPreRenderConfig().preRenderContainer;
|
|
1176
1200
|
let container: Element | null = null;
|
|
1177
1201
|
if (typeof containerConfig === 'string') {
|
|
1178
1202
|
try {
|
|
@@ -1189,15 +1213,40 @@ export class TsEmbed {
|
|
|
1189
1213
|
return (container as HTMLElement) ?? document.body;
|
|
1190
1214
|
}
|
|
1191
1215
|
|
|
1216
|
+
private inheritPreRenderContainer(): void {
|
|
1217
|
+
const preRenderedObject = this.getPreRenderObj<TsEmbed>();
|
|
1218
|
+
if (!preRenderedObject || preRenderedObject === (this as TsEmbed)) {
|
|
1219
|
+
return;
|
|
1220
|
+
}
|
|
1221
|
+
const ownerContainer = preRenderedObject.preRenderContainerEl ?? document.body;
|
|
1222
|
+
if (
|
|
1223
|
+
this.getPreRenderConfig().preRenderContainer
|
|
1224
|
+
&& this.resolvePreRenderContainerTarget() !== ownerContainer
|
|
1225
|
+
) {
|
|
1226
|
+
logger.warn(
|
|
1227
|
+
'preRenderContainer is applied only by the component that creates the preRender; '
|
|
1228
|
+
+ 'the one passed here is ignored. Set it on the PreRender component instead.',
|
|
1229
|
+
);
|
|
1230
|
+
}
|
|
1231
|
+
this.preRenderContainerEl = ownerContainer;
|
|
1232
|
+
this.applyPreRenderContainerPositioning();
|
|
1233
|
+
}
|
|
1234
|
+
|
|
1235
|
+
private getCustomPreRenderContainer(): HTMLElement | null {
|
|
1236
|
+
const container = this.preRenderContainerEl;
|
|
1237
|
+
return container && container !== document.body ? container : null;
|
|
1238
|
+
}
|
|
1239
|
+
|
|
1192
1240
|
/**
|
|
1193
|
-
* Makes the container a positioning context for the absolutely
|
|
1194
|
-
* wrapper, stashing the original inline `position` on the element
|
|
1195
|
-
* destroy() can restore it exactly, leaving no trace. Recording it
|
|
1196
|
-
* element rather than per-instance lets the override be reverted even
|
|
1197
|
-
* embeds share the same container.
|
|
1241
|
+
* Makes the resolved container a positioning context for the absolutely
|
|
1242
|
+
* positioned wrapper, stashing the original inline `position` on the element
|
|
1243
|
+
* (once) so destroy() can restore it exactly, leaving no trace. Recording it
|
|
1244
|
+
* on the element rather than per-instance lets the override be reverted even
|
|
1245
|
+
* when embeds share the same container.
|
|
1198
1246
|
*/
|
|
1199
|
-
private applyPreRenderContainerPositioning(
|
|
1200
|
-
|
|
1247
|
+
private applyPreRenderContainerPositioning(): void {
|
|
1248
|
+
const container = this.getCustomPreRenderContainer();
|
|
1249
|
+
if (!container) {
|
|
1201
1250
|
return;
|
|
1202
1251
|
}
|
|
1203
1252
|
const pos = window.getComputedStyle(container).position;
|
|
@@ -1243,11 +1292,11 @@ export class TsEmbed {
|
|
|
1243
1292
|
resolved.addEventListener('scroll', this.containerScrollListener);
|
|
1244
1293
|
}
|
|
1245
1294
|
}
|
|
1246
|
-
this.
|
|
1295
|
+
this.preRenderContainerEl = resolved;
|
|
1296
|
+
this.applyPreRenderContainerPositioning();
|
|
1247
1297
|
if (wrapper.parentNode !== resolved) {
|
|
1248
1298
|
resolved.appendChild(wrapper);
|
|
1249
1299
|
}
|
|
1250
|
-
this.preRenderContainerEl = resolved;
|
|
1251
1300
|
}
|
|
1252
1301
|
|
|
1253
1302
|
protected insertIntoDOMForPreRender(child: string | Node): void {
|
|
@@ -1275,7 +1324,7 @@ export class TsEmbed {
|
|
|
1275
1324
|
|
|
1276
1325
|
const targetContainer = this.resolvePreRenderContainerTarget();
|
|
1277
1326
|
this.preRenderContainerEl = targetContainer;
|
|
1278
|
-
this.applyPreRenderContainerPositioning(
|
|
1327
|
+
this.applyPreRenderContainerPositioning();
|
|
1279
1328
|
targetContainer.appendChild(preRenderWrapper);
|
|
1280
1329
|
}
|
|
1281
1330
|
|
|
@@ -1621,7 +1670,11 @@ export class TsEmbed {
|
|
|
1621
1670
|
* ```
|
|
1622
1671
|
* @version SDK: 1.45.2 | ThoughtSpot: 26.3.0.cl (for context parameter)
|
|
1623
1672
|
*/
|
|
1624
|
-
public async trigger<
|
|
1673
|
+
public async trigger<
|
|
1674
|
+
HostEventT extends HostEvent,
|
|
1675
|
+
PayloadT = HostEventRequest<HostEventT>,
|
|
1676
|
+
ContextT extends ContextType = ContextType,
|
|
1677
|
+
>(
|
|
1625
1678
|
messageType: HostEventT,
|
|
1626
1679
|
data: TriggerPayload<PayloadT, HostEventT> = {} as any,
|
|
1627
1680
|
context?: ContextT,
|
|
@@ -1706,6 +1759,9 @@ export class TsEmbed {
|
|
|
1706
1759
|
* @param args
|
|
1707
1760
|
*/
|
|
1708
1761
|
public async render(): Promise<TsEmbed> {
|
|
1762
|
+
uploadMixpanelEvent(MIXPANEL_EVENT.VISUAL_SDK_RENDER_CALLED, {
|
|
1763
|
+
embedComponentType: this.viewConfig.embedComponentType,
|
|
1764
|
+
});
|
|
1709
1765
|
if (!getIsInitCalled()) {
|
|
1710
1766
|
logger.error(ERROR_MESSAGE.RENDER_CALLED_BEFORE_INIT);
|
|
1711
1767
|
}
|
|
@@ -1786,7 +1842,11 @@ export class TsEmbed {
|
|
|
1786
1842
|
showPreRenderByDefault = false,
|
|
1787
1843
|
replaceExistingPreRender = false,
|
|
1788
1844
|
): Promise<TsEmbed> {
|
|
1789
|
-
|
|
1845
|
+
uploadMixpanelEvent(MIXPANEL_EVENT.VISUAL_SDK_PRE_RENDER, {
|
|
1846
|
+
showPreRenderByDefault,
|
|
1847
|
+
replaceExistingPreRender,
|
|
1848
|
+
});
|
|
1849
|
+
if (!this.getPreRenderConfig().preRenderId) {
|
|
1790
1850
|
logger.error(ERROR_MESSAGE.PRERENDER_ID_MISSING);
|
|
1791
1851
|
return this;
|
|
1792
1852
|
}
|
|
@@ -1845,13 +1905,13 @@ export class TsEmbed {
|
|
|
1845
1905
|
* same container — a shared container still needs the positioning context.
|
|
1846
1906
|
*/
|
|
1847
1907
|
private restorePreRenderContainerPosition(): void {
|
|
1848
|
-
const container = this.preRenderContainerEl
|
|
1908
|
+
const container = this.preRenderContainerEl;
|
|
1849
1909
|
if (!container || container === document.body) {
|
|
1850
1910
|
return;
|
|
1851
1911
|
}
|
|
1852
1912
|
// Drop our reference up front so a destroyed embed never pins a
|
|
1853
1913
|
// detached container in memory; restoration uses the local handle.
|
|
1854
|
-
this.preRenderContainerEl =
|
|
1914
|
+
this.preRenderContainerEl = document.body;
|
|
1855
1915
|
const originalPosition = container.dataset[PRERENDER_CONTAINER_ORIGINAL_POSITION_KEY];
|
|
1856
1916
|
if (originalPosition === undefined) {
|
|
1857
1917
|
// We never overrode this container's position; nothing to restore.
|
|
@@ -1877,10 +1937,7 @@ export class TsEmbed {
|
|
|
1877
1937
|
if (!this.containerScrollListener) {
|
|
1878
1938
|
return;
|
|
1879
1939
|
}
|
|
1880
|
-
const customContainer =
|
|
1881
|
-
this.preRenderContainerEl && this.preRenderContainerEl !== document.body
|
|
1882
|
-
? this.preRenderContainerEl
|
|
1883
|
-
: null;
|
|
1940
|
+
const customContainer = this.getCustomPreRenderContainer();
|
|
1884
1941
|
customContainer?.removeEventListener('scroll', this.containerScrollListener);
|
|
1885
1942
|
this.containerScrollListener = null;
|
|
1886
1943
|
}
|
|
@@ -1974,9 +2031,15 @@ export class TsEmbed {
|
|
|
1974
2031
|
* wrapper to overlay it.
|
|
1975
2032
|
*/
|
|
1976
2033
|
public async showPreRender(): Promise<TsEmbed> {
|
|
2034
|
+
uploadMixpanelEvent(MIXPANEL_EVENT.VISUAL_SDK_SHOW_PRE_RENDER, {
|
|
2035
|
+
preRenderId: this.getPreRenderConfig().preRenderId,
|
|
2036
|
+
embedComponentType: this.viewConfig.embedComponentType,
|
|
2037
|
+
});
|
|
2038
|
+
|
|
1977
2039
|
if (this.shouldWaitForRenderPromise) await this.isReadyForRenderPromise;
|
|
1978
2040
|
|
|
1979
|
-
|
|
2041
|
+
|
|
2042
|
+
if (!this.getPreRenderConfig().preRenderId) {
|
|
1980
2043
|
logger.error(ERROR_MESSAGE.PRERENDER_ID_MISSING);
|
|
1981
2044
|
return this;
|
|
1982
2045
|
}
|
|
@@ -1999,25 +2062,26 @@ export class TsEmbed {
|
|
|
1999
2062
|
}
|
|
2000
2063
|
|
|
2001
2064
|
const placeHolderId = this.getPreRenderIds().placeHolder;
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2065
|
+
// Remove any stale placeholder from a previous cycle. It is located
|
|
2066
|
+
// via a subtree-wide querySelector, so it may be nested deeper than a
|
|
2067
|
+
// direct child (E.g.: with fullHeight the host app can wrap it). Use
|
|
2068
|
+
// Element.remove() — which detaches from whatever the real parent is —
|
|
2069
|
+
// rather than hostElement.removeChild(), which throws NotFoundError
|
|
2070
|
+
// when the match is not a direct child. Mirrors the wrapper/child
|
|
2071
|
+
// cleanup in createPreRenderWrapper()/createPreRenderChild().
|
|
2072
|
+
this.hostElement.querySelector(`#${placeHolderId}`)?.remove();
|
|
2006
2073
|
|
|
2007
2074
|
this.hostElement.appendChild(this.insertedDomEl);
|
|
2008
2075
|
|
|
2009
2076
|
this.syncPreRenderStyle();
|
|
2010
2077
|
|
|
2011
|
-
const customContainer =
|
|
2012
|
-
this.preRenderContainerEl && this.preRenderContainerEl !== document.body
|
|
2013
|
-
? this.preRenderContainerEl
|
|
2014
|
-
: null;
|
|
2078
|
+
const customContainer = this.getCustomPreRenderContainer();
|
|
2015
2079
|
if (customContainer && !this.containerScrollListener) {
|
|
2016
2080
|
this.containerScrollListener = () => this.syncPreRenderStyle();
|
|
2017
2081
|
customContainer.addEventListener('scroll', this.containerScrollListener);
|
|
2018
2082
|
}
|
|
2019
2083
|
|
|
2020
|
-
if (!this.
|
|
2084
|
+
if (!this.getPreRenderConfig().doNotTrackPreRenderSize) {
|
|
2021
2085
|
const observeTarget = (this.insertedDomEl as HTMLElement) ?? this.hostElement;
|
|
2022
2086
|
this.resizeObserver = new ResizeObserver((entries) => {
|
|
2023
2087
|
entries.forEach((entry) => {
|
|
@@ -2063,15 +2127,16 @@ export class TsEmbed {
|
|
|
2063
2127
|
logger.error(ERROR_MESSAGE.SYNC_STYLE_CALLED_BEFORE_RENDER);
|
|
2064
2128
|
return;
|
|
2065
2129
|
}
|
|
2130
|
+
if (!this.getPreRenderPlaceHolderElement().isConnected) {
|
|
2131
|
+
logger.debug('syncPreRenderStyle skipped: placeholder is detached');
|
|
2132
|
+
return;
|
|
2133
|
+
}
|
|
2066
2134
|
// Self-heal if the resolved container was remounted/detached, so we
|
|
2067
2135
|
// never measure a stale node (which would collapse the wrapper).
|
|
2068
2136
|
this.reconcilePreRenderContainer();
|
|
2069
2137
|
const elBoundingClient = this.getPreRenderPlaceHolderElement().getBoundingClientRect();
|
|
2070
2138
|
|
|
2071
|
-
const containerEl =
|
|
2072
|
-
this.preRenderContainerEl && this.preRenderContainerEl !== document.body
|
|
2073
|
-
? this.preRenderContainerEl
|
|
2074
|
-
: null;
|
|
2139
|
+
const containerEl = this.getCustomPreRenderContainer();
|
|
2075
2140
|
const containerRect = containerEl?.getBoundingClientRect() ?? { x: 0, y: 0 };
|
|
2076
2141
|
const scrollX = containerEl ? containerEl.scrollLeft : window.scrollX;
|
|
2077
2142
|
const scrollY = containerEl ? containerEl.scrollTop : window.scrollY;
|
|
@@ -2090,16 +2155,22 @@ export class TsEmbed {
|
|
|
2090
2155
|
* If the component is not preRendered, it issues a warning.
|
|
2091
2156
|
*/
|
|
2092
2157
|
public hidePreRender(): void {
|
|
2158
|
+
uploadMixpanelEvent(MIXPANEL_EVENT.VISUAL_SDK_HIDE_PRE_RENDER, {
|
|
2159
|
+
preRenderId: this.getPreRenderConfig().preRenderId,
|
|
2160
|
+
embedComponentType: this.viewConfig.embedComponentType,
|
|
2161
|
+
});
|
|
2162
|
+
|
|
2093
2163
|
logger.debug('HidePreRender Called');
|
|
2094
2164
|
if (!this.isPreRenderConnected()) {
|
|
2095
2165
|
// if the embed component is not preRendered , nothing to hide
|
|
2096
2166
|
logger.warn('PreRender should be called before hiding it using hidePreRender.');
|
|
2097
2167
|
return;
|
|
2098
2168
|
}
|
|
2169
|
+
const { zIndex } = this.getPreRenderConfig();
|
|
2099
2170
|
const preRenderHideStyles = {
|
|
2100
2171
|
opacity: '0',
|
|
2101
2172
|
pointerEvents: 'none',
|
|
2102
|
-
zIndex: '-1000',
|
|
2173
|
+
zIndex: zIndex !== undefined ? String(zIndex) : '-1000',
|
|
2103
2174
|
position: 'absolute',
|
|
2104
2175
|
top: '0',
|
|
2105
2176
|
left: '0',
|
|
@@ -2129,10 +2200,11 @@ export class TsEmbed {
|
|
|
2129
2200
|
* @property {string} child - The HTML element ID for the PreRender child.
|
|
2130
2201
|
*/
|
|
2131
2202
|
public getPreRenderIds() {
|
|
2203
|
+
const preRenderId = this.getPreRenderConfig().preRenderId;
|
|
2132
2204
|
return {
|
|
2133
|
-
wrapper: `${PRERENDER_WRAPPER_ID_PREFIX}${
|
|
2134
|
-
child: `tsEmbed-pre-render-child-${
|
|
2135
|
-
placeHolder: `tsEmbed-pre-render-placeholder-${
|
|
2205
|
+
wrapper: `${PRERENDER_WRAPPER_ID_PREFIX}${preRenderId}`,
|
|
2206
|
+
child: `tsEmbed-pre-render-child-${preRenderId}`,
|
|
2207
|
+
placeHolder: `tsEmbed-pre-render-placeholder-${preRenderId}`,
|
|
2136
2208
|
};
|
|
2137
2209
|
}
|
|
2138
2210
|
|
package/src/errors.ts
CHANGED
|
@@ -31,6 +31,7 @@ export const ERROR_MESSAGE = {
|
|
|
31
31
|
INVALID_SPOTTER_DOCUMENTATION_URL: 'Invalid spotterDocumentationUrl. Please provide a valid http or https URL.',
|
|
32
32
|
UPDATEFILTERS_INVALID_PAYLOAD: 'UpdateFilters requires a valid filter or filters array. Expected: { filter: { column, oper, values } } or { filters: [{ column, oper, values }, ...] }',
|
|
33
33
|
DRILLDOWN_INVALID_PAYLOAD: 'DrillDown requires a valid points object. Expected: { points: { clickedPoint?, selectedPoints? }, autoDrillDown?, vizId? }',
|
|
34
|
+
UPDATEPARAMETERS_INVALID_PAYLOAD: 'UpdateParameters received an invalid applicability. Expected: { level: LIVEBOARD | TAB | GROUP, targetId } where targetId is required for TAB and GROUP levels',
|
|
34
35
|
};
|
|
35
36
|
|
|
36
37
|
export const CUSTOM_ACTIONS_ERROR_MESSAGE = {
|
package/src/index.ts
CHANGED
|
@@ -32,7 +32,7 @@ import { PinboardEmbed, LiveboardViewConfig, LiveboardEmbed } from './embed/live
|
|
|
32
32
|
import { SearchEmbed, SearchViewConfig } from './embed/search';
|
|
33
33
|
import { SearchBarEmbed, SearchBarViewConfig } from './embed/search-bar';
|
|
34
34
|
import { SpotterAgentEmbed, SpotterAgentEmbedViewConfig, BodylessConversation, BodylessConversationViewConfig} from './embed/bodyless-conversation';
|
|
35
|
-
import { SpotterEmbed, SpotterEmbedViewConfig, SpotterChatViewConfig, SpotterSidebarViewConfig, ConversationEmbed, ConversationViewConfig } from './embed/conversation';
|
|
35
|
+
import { SpotterEmbed, SpotterEmbedViewConfig, SpotterChatViewConfig, SpotterSidebarViewConfig, SpotterAnalystConfig, SpotterQueryMode, SpotterShareConversationConfig, StarterPromptsConfig, StarterPromptCategory, StarterPreviewDataCategory, StarterPromptQuestion, ConversationEmbed, ConversationViewConfig } from './embed/conversation';
|
|
36
36
|
import { SpotterVizConfig, SpotterVizStarterPrompt, SpotterVizLoaderTip } from './embed/spotter-viz-utils';
|
|
37
37
|
import {
|
|
38
38
|
AuthFailureType, AuthStatus, AuthEvent, AuthEventEmitter,
|
|
@@ -88,7 +88,24 @@ import { uploadMixpanelEvent, MIXPANEL_EVENT } from './mixpanel-service';
|
|
|
88
88
|
import { tokenizedFetch } from './tokenizedFetch';
|
|
89
89
|
import { getAnswerFromQuery } from './utils/graphql/nlsService/nls-answer-service';
|
|
90
90
|
import { createLiveboardWithAnswers } from './utils/liveboardService/liveboardService';
|
|
91
|
-
import {
|
|
91
|
+
import {
|
|
92
|
+
UIPassthroughEvent,
|
|
93
|
+
UIPassthroughContractBase,
|
|
94
|
+
UIPassthroughRequest,
|
|
95
|
+
UIPassthroughResponse,
|
|
96
|
+
UIPassthroughArrayResponse,
|
|
97
|
+
HostEventRequest,
|
|
98
|
+
HostEventResponse,
|
|
99
|
+
TriggerPayload,
|
|
100
|
+
TriggerResponse,
|
|
101
|
+
LiveboardTab,
|
|
102
|
+
LiveboardGroup,
|
|
103
|
+
ApplicabilityLevel,
|
|
104
|
+
Applicability,
|
|
105
|
+
FilterUpdate,
|
|
106
|
+
LiveboardFilter,
|
|
107
|
+
LiveboardParameter,
|
|
108
|
+
} from './embed/hostEventClient/contracts';
|
|
92
109
|
|
|
93
110
|
export {
|
|
94
111
|
init,
|
|
@@ -117,6 +134,13 @@ export {
|
|
|
117
134
|
SpotterEmbedViewConfig,
|
|
118
135
|
SpotterChatViewConfig,
|
|
119
136
|
SpotterSidebarViewConfig,
|
|
137
|
+
SpotterAnalystConfig,
|
|
138
|
+
SpotterQueryMode,
|
|
139
|
+
SpotterShareConversationConfig,
|
|
140
|
+
StarterPromptsConfig,
|
|
141
|
+
StarterPromptCategory,
|
|
142
|
+
StarterPreviewDataCategory,
|
|
143
|
+
StarterPromptQuestion,
|
|
120
144
|
ConversationViewConfig,
|
|
121
145
|
ConversationEmbed,
|
|
122
146
|
AuthFailureType,
|
|
@@ -168,6 +192,25 @@ export {
|
|
|
168
192
|
VizPoint,
|
|
169
193
|
CustomActionPayload,
|
|
170
194
|
UIPassthroughEvent,
|
|
195
|
+
// Host event payload / response contracts. These describe what to send with
|
|
196
|
+
// `embed.trigger(HostEvent.X, payload)` and what the returned promise
|
|
197
|
+
// resolves with. See `UIPassthroughContractBase` for the per-event
|
|
198
|
+
// request/response shapes.
|
|
199
|
+
UIPassthroughContractBase,
|
|
200
|
+
UIPassthroughRequest,
|
|
201
|
+
UIPassthroughResponse,
|
|
202
|
+
UIPassthroughArrayResponse,
|
|
203
|
+
HostEventRequest,
|
|
204
|
+
HostEventResponse,
|
|
205
|
+
TriggerPayload,
|
|
206
|
+
TriggerResponse,
|
|
207
|
+
LiveboardTab,
|
|
208
|
+
LiveboardGroup,
|
|
209
|
+
ApplicabilityLevel,
|
|
210
|
+
Applicability,
|
|
211
|
+
FilterUpdate,
|
|
212
|
+
LiveboardFilter,
|
|
213
|
+
LiveboardParameter,
|
|
171
214
|
ListPageColumns,
|
|
172
215
|
DataPanelCustomColumnGroupsAccordionState,
|
|
173
216
|
CustomActionsPosition,
|
package/src/mixpanel-service.ts
CHANGED
|
@@ -26,6 +26,10 @@ export const MIXPANEL_EVENT = {
|
|
|
26
26
|
VISUAL_SDK_IFRAME_LOAD_PERFORMANCE: 'visual-sdk-iframe-load-performance',
|
|
27
27
|
VISUAL_SDK_EMBED_CREATE: 'visual-sdk-embed-create',
|
|
28
28
|
VERCEL_INTEGRATION_COMPLETED: 'vercel-integration-completed',
|
|
29
|
+
VISUAL_SDK_RENDER_CALLED: 'visual-sdk-render-called',
|
|
30
|
+
VISUAL_SDK_PRE_RENDER: 'visual-sdk-pre-render',
|
|
31
|
+
VISUAL_SDK_SHOW_PRE_RENDER: 'visual-sdk-show-pre-render',
|
|
32
|
+
VISUAL_SDK_HIDE_PRE_RENDER: 'visual-sdk-hide-pre-render',
|
|
29
33
|
};
|
|
30
34
|
|
|
31
35
|
let isMixpanelInitialized = false;
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parity gate: every symbol exported from `src/index.ts` must also be exported
|
|
3
|
+
* from `src/react/all-types-export.ts`.
|
|
4
|
+
*
|
|
5
|
+
* `package.json` `exports` restricts consumers to two entry points — `.` and
|
|
6
|
+
* `./react` — and the React surface is a HAND-MAINTAINED duplicate export list,
|
|
7
|
+
* not a `export * from '../index'`. So a symbol added only to `src/index.ts` is
|
|
8
|
+
* invisible to every React consumer.
|
|
9
|
+
*
|
|
10
|
+
* The sibling `all-types-export.spec.ts` cannot catch this: it inspects the
|
|
11
|
+
* module at runtime, and type-only exports (interfaces, type aliases) are
|
|
12
|
+
* erased by the compiler. This spec therefore compares the two files as TEXT.
|
|
13
|
+
*/
|
|
14
|
+
import * as fs from 'fs';
|
|
15
|
+
import * as path from 'path';
|
|
16
|
+
|
|
17
|
+
const INDEX_PATH = path.join(__dirname, '..', 'index.ts');
|
|
18
|
+
const REACT_EXPORT_PATH = path.join(__dirname, 'all-types-export.ts');
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Symbols intentionally absent from the React surface.
|
|
22
|
+
* Add here only with a reason — every entry is a thing React users cannot use.
|
|
23
|
+
*/
|
|
24
|
+
const REACT_EXEMPT = new Set<string>([
|
|
25
|
+
// React has its own component wrappers for these; the raw classes are not
|
|
26
|
+
// part of the /react surface.
|
|
27
|
+
'SearchEmbed',
|
|
28
|
+
'SearchBarEmbed',
|
|
29
|
+
'LiveboardEmbed',
|
|
30
|
+
'AppEmbed',
|
|
31
|
+
'SpotterEmbed',
|
|
32
|
+
'SpotterAgentEmbed',
|
|
33
|
+
'ConversationEmbed',
|
|
34
|
+
'BodylessConversation',
|
|
35
|
+
'PreRenderedSearchEmbed',
|
|
36
|
+
'PreRenderedSearchBarEmbed',
|
|
37
|
+
'PreRenderedLiveboardEmbed',
|
|
38
|
+
'PreRenderedAppEmbed',
|
|
39
|
+
'PreRenderedConversationEmbed',
|
|
40
|
+
'PinboardEmbed',
|
|
41
|
+
'TsEmbed',
|
|
42
|
+
'V1Embed',
|
|
43
|
+
]);
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* PRE-EXISTING gaps, discovered when this spec was introduced. These are
|
|
47
|
+
* symbols React consumers cannot import today — most look like oversights
|
|
48
|
+
* rather than deliberate omissions (e.g. `ContextType`, `CustomActionPayload`,
|
|
49
|
+
* `VizPoint`, the Spotter view configs).
|
|
50
|
+
*
|
|
51
|
+
* This list may only ever SHRINK. Do not add to it — a new entry means a
|
|
52
|
+
* symbol was added to `src/index.ts` without adding it to the React surface,
|
|
53
|
+
* which is exactly what this spec exists to prevent. Removing entries (by
|
|
54
|
+
* exporting them from `all-types-export.ts`) is a welcome follow-up; it is
|
|
55
|
+
* deliberately out of scope for the change that introduced this gate.
|
|
56
|
+
*/
|
|
57
|
+
const KNOWN_REACT_GAPS = new Set<string>([
|
|
58
|
+
'AnswerService',
|
|
59
|
+
'AutoMCPFrameRendererViewConfig',
|
|
60
|
+
'BackgroundFormatType',
|
|
61
|
+
'BodylessConversationViewConfig',
|
|
62
|
+
'ConditionalFormattingComparisonType',
|
|
63
|
+
'ConditionalFormattingOperator',
|
|
64
|
+
'ContextMenuTriggerOptions',
|
|
65
|
+
'ContextType',
|
|
66
|
+
'ConversationViewConfig',
|
|
67
|
+
'CustomActionPayload',
|
|
68
|
+
'DataLabelFilterOperator',
|
|
69
|
+
'EmbedErrorCodes',
|
|
70
|
+
'EmbedErrorDetailsEvent',
|
|
71
|
+
'ErrorDetailsTypes',
|
|
72
|
+
'HomeLeftNavItem',
|
|
73
|
+
'HomePage',
|
|
74
|
+
'HomePageSearchBarMode',
|
|
75
|
+
'HomepageModule',
|
|
76
|
+
'LegendPosition',
|
|
77
|
+
'ListPage',
|
|
78
|
+
'ListPageColumns',
|
|
79
|
+
'LogLevel',
|
|
80
|
+
'MIXPANEL_EVENT',
|
|
81
|
+
'PrimaryNavbarVersion',
|
|
82
|
+
'SessionInterface',
|
|
83
|
+
'SpotterAgentEmbedViewConfig',
|
|
84
|
+
'SpotterChatViewConfig',
|
|
85
|
+
'SpotterEmbedViewConfig',
|
|
86
|
+
'SpotterQueryMode',
|
|
87
|
+
'SpotterShareConversationConfig',
|
|
88
|
+
'SpotterSidebarViewConfig',
|
|
89
|
+
'SpotterVizConfig',
|
|
90
|
+
'SpotterVizLoaderTip',
|
|
91
|
+
'SpotterVizStarterPrompt',
|
|
92
|
+
'TableContentDensity',
|
|
93
|
+
'TableTheme',
|
|
94
|
+
'UnderlyingDataPoint',
|
|
95
|
+
'VisualizationOverrides',
|
|
96
|
+
'VizPoint',
|
|
97
|
+
// Standalone helpers re-exported from src/index.ts outside the main block.
|
|
98
|
+
'createLiveboardWithAnswers',
|
|
99
|
+
'executeTML',
|
|
100
|
+
'executeTMLInput',
|
|
101
|
+
'exportTML',
|
|
102
|
+
'exportTMLInput',
|
|
103
|
+
'getAnswerFromQuery',
|
|
104
|
+
'startAutoMCPFrameRenderer',
|
|
105
|
+
'tokenizedFetch',
|
|
106
|
+
]);
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Extract identifiers from every `export { ... }` / `export type { ... }` block
|
|
110
|
+
* in a source file. Handles `a`, `a as b` (records the exported name `b`),
|
|
111
|
+
* comments and trailing commas.
|
|
112
|
+
*
|
|
113
|
+
* `export * from '...'` cannot be enumerated by name (the names live in another
|
|
114
|
+
* module), so it would silently defeat this parity gate. We refuse to run
|
|
115
|
+
* against it: if either file adopts a star re-export, this throws so the gate
|
|
116
|
+
* is extended deliberately rather than passing blind.
|
|
117
|
+
*/
|
|
118
|
+
const extractExportedNames = (source: string): Set<string> => {
|
|
119
|
+
if (/export\s*\*/.test(source)) {
|
|
120
|
+
throw new Error(
|
|
121
|
+
'Parity extractor found an `export *` re-export, which it cannot '
|
|
122
|
+
+ 'enumerate by name. Extend extractExportedNames to resolve star '
|
|
123
|
+
+ 'exports before relying on this gate.',
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
const names = new Set<string>();
|
|
127
|
+
// Matches `export { ... }` and `export type { ... }`.
|
|
128
|
+
const blockRe = /export\s*(?:type\s+)?\{([\s\S]*?)\}/g;
|
|
129
|
+
let match = blockRe.exec(source);
|
|
130
|
+
while (match !== null) {
|
|
131
|
+
match[1]
|
|
132
|
+
// strip line and block comments
|
|
133
|
+
.replace(/\/\*[\s\S]*?\*\//g, '')
|
|
134
|
+
.replace(/\/\/[^\n]*/g, '')
|
|
135
|
+
.split(',')
|
|
136
|
+
.map((entry) => entry.trim())
|
|
137
|
+
.filter(Boolean)
|
|
138
|
+
.forEach((entry) => {
|
|
139
|
+
// `foo as bar` exports the name `bar`
|
|
140
|
+
const parts = entry.split(/\s+as\s+/);
|
|
141
|
+
const exported = (parts[parts.length - 1] || '').trim();
|
|
142
|
+
if (/^[A-Za-z_$][\w$]*$/.test(exported)) {
|
|
143
|
+
names.add(exported);
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
match = blockRe.exec(source);
|
|
147
|
+
}
|
|
148
|
+
return names;
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
describe('react/all-types-export parity with index', () => {
|
|
152
|
+
it('exports every symbol that src/index.ts exports', () => {
|
|
153
|
+
const indexNames = extractExportedNames(fs.readFileSync(INDEX_PATH, 'utf8'));
|
|
154
|
+
const reactNames = extractExportedNames(fs.readFileSync(REACT_EXPORT_PATH, 'utf8'));
|
|
155
|
+
|
|
156
|
+
// Sanity: the extractor found something. Guards against a regex that
|
|
157
|
+
// silently matches nothing after a refactor.
|
|
158
|
+
expect(indexNames.size).toBeGreaterThan(50);
|
|
159
|
+
expect(reactNames.size).toBeGreaterThan(50);
|
|
160
|
+
|
|
161
|
+
const missing = [...indexNames]
|
|
162
|
+
.filter((name) => !reactNames.has(name))
|
|
163
|
+
.filter((name) => !REACT_EXEMPT.has(name))
|
|
164
|
+
.filter((name) => !KNOWN_REACT_GAPS.has(name))
|
|
165
|
+
.sort();
|
|
166
|
+
|
|
167
|
+
if (missing.length > 0) {
|
|
168
|
+
throw new Error(
|
|
169
|
+
'These symbols are exported from src/index.ts but NOT from '
|
|
170
|
+
+ 'src/react/all-types-export.ts, so React consumers cannot '
|
|
171
|
+
+ `import them:\n ${missing.join('\n ')}\n\n`
|
|
172
|
+
+ 'Add them to src/react/all-types-export.ts. Do NOT add them '
|
|
173
|
+
+ 'to KNOWN_REACT_GAPS — that list is a shrinking backlog of '
|
|
174
|
+
+ 'pre-existing gaps and must never grow.',
|
|
175
|
+
);
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
it('KNOWN_REACT_GAPS only lists symbols that are genuinely still missing', () => {
|
|
180
|
+
// Ratchet: once a gap is fixed, its entry must be deleted, so the list
|
|
181
|
+
// can only shrink.
|
|
182
|
+
const indexNames = extractExportedNames(fs.readFileSync(INDEX_PATH, 'utf8'));
|
|
183
|
+
const reactNames = extractExportedNames(fs.readFileSync(REACT_EXPORT_PATH, 'utf8'));
|
|
184
|
+
|
|
185
|
+
const stale = [...KNOWN_REACT_GAPS]
|
|
186
|
+
.filter((name) => reactNames.has(name) || !indexNames.has(name))
|
|
187
|
+
.sort();
|
|
188
|
+
|
|
189
|
+
if (stale.length > 0) {
|
|
190
|
+
throw new Error(
|
|
191
|
+
'These entries in KNOWN_REACT_GAPS are no longer gaps (they are '
|
|
192
|
+
+ 'now exported from the React surface, or no longer exported '
|
|
193
|
+
+ `from src/index.ts). Delete them from the list:\n ${stale.join('\n ')}`,
|
|
194
|
+
);
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
it('exposes the host event contract types on the React surface', () => {
|
|
199
|
+
const reactNames = extractExportedNames(fs.readFileSync(REACT_EXPORT_PATH, 'utf8'));
|
|
200
|
+
[
|
|
201
|
+
'UIPassthroughContractBase',
|
|
202
|
+
'HostEventRequest',
|
|
203
|
+
'HostEventResponse',
|
|
204
|
+
'TriggerPayload',
|
|
205
|
+
'TriggerResponse',
|
|
206
|
+
].forEach((name) => expect(reactNames.has(name)).toBe(true));
|
|
207
|
+
});
|
|
208
|
+
});
|
|
@@ -56,8 +56,30 @@ export {
|
|
|
56
56
|
RuntimeParameter,
|
|
57
57
|
resetCachedAuthToken,
|
|
58
58
|
UIPassthroughEvent,
|
|
59
|
+
// Host event payload / response contracts — kept in sync with src/index.ts
|
|
60
|
+
// (enforced by all-types-export.parity.spec.ts).
|
|
61
|
+
UIPassthroughContractBase,
|
|
62
|
+
UIPassthroughRequest,
|
|
63
|
+
UIPassthroughResponse,
|
|
64
|
+
UIPassthroughArrayResponse,
|
|
65
|
+
HostEventRequest,
|
|
66
|
+
HostEventResponse,
|
|
67
|
+
TriggerPayload,
|
|
68
|
+
TriggerResponse,
|
|
69
|
+
LiveboardTab,
|
|
70
|
+
LiveboardGroup,
|
|
71
|
+
ApplicabilityLevel,
|
|
72
|
+
Applicability,
|
|
73
|
+
FilterUpdate,
|
|
74
|
+
LiveboardFilter,
|
|
75
|
+
LiveboardParameter,
|
|
59
76
|
DataPanelCustomColumnGroupsAccordionState,
|
|
60
77
|
InterceptedApiType,
|
|
61
78
|
CustomActionsPosition,
|
|
62
79
|
CustomActionTarget,
|
|
80
|
+
SpotterAnalystConfig,
|
|
81
|
+
StarterPromptsConfig,
|
|
82
|
+
StarterPromptCategory,
|
|
83
|
+
StarterPreviewDataCategory,
|
|
84
|
+
StarterPromptQuestion,
|
|
63
85
|
} from '../index';
|