@envive-ai/react-widgets-v3 0.3.63 → 0.3.64
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/dist/debug/MessageContent.cjs +1 -1
- package/dist/debug/MessageContent.js +1 -1
- package/dist/debug/chatEmbed.cjs +1 -1
- package/dist/debug/chatEmbed.js +1 -1
- package/dist/debug/reportIssue.cjs +1 -1
- package/dist/debug/reportIssue.js +1 -1
- package/dist/hocs/withBaseWidget/withBaseWidget.cjs +28 -2
- package/dist/hocs/withBaseWidget/withBaseWidget.d.cts +2 -2
- package/dist/hocs/withBaseWidget/withBaseWidget.d.ts +2 -2
- package/dist/hocs/withBaseWidget/withBaseWidget.js +28 -2
- package/dist/packages/widgets/dist/SearchResults/SearchResultsWidget.d.ts +2 -2
- package/dist/packages/widgets/dist/SearchZeroState/SearchZeroStateWidget.d.ts +2 -2
- package/dist/packages/widgets/dist/SuggestionBar/SuggestionBar.d.ts +2 -2
- package/dist/widgets/ChatPreviewComparisonWidget/ChatPreviewComparisonWidget.cjs +2 -2
- package/dist/widgets/ChatPreviewComparisonWidget/ChatPreviewComparisonWidget.d.cts +3 -3
- package/dist/widgets/ChatPreviewComparisonWidget/ChatPreviewComparisonWidget.d.ts +3 -3
- package/dist/widgets/ChatPreviewComparisonWidget/ChatPreviewComparisonWidget.js +2 -2
- package/dist/widgets/ChatPreviewLoadingWidget/ChatPreviewLoadingWidget.cjs +2 -2
- package/dist/widgets/ChatPreviewLoadingWidget/ChatPreviewLoadingWidget.d.cts +3 -3
- package/dist/widgets/ChatPreviewLoadingWidget/ChatPreviewLoadingWidget.d.ts +3 -3
- package/dist/widgets/ChatPreviewLoadingWidget/ChatPreviewLoadingWidget.js +2 -2
- package/dist/widgets/ChatPreviewWidget/ChatPreviewWidget.cjs +2 -2
- package/dist/widgets/ChatPreviewWidget/ChatPreviewWidget.d.cts +3 -3
- package/dist/widgets/ChatPreviewWidget/ChatPreviewWidget.d.ts +3 -3
- package/dist/widgets/ChatPreviewWidget/ChatPreviewWidget.js +2 -2
- package/dist/widgets/FloatingChatWidget/FloatingChatWidget.cjs +2 -2
- package/dist/widgets/FloatingChatWidget/FloatingChatWidget.d.cts +2 -2
- package/dist/widgets/FloatingChatWidget/FloatingChatWidget.js +2 -2
- package/dist/widgets/FloatingChatWidget/hooks/useAutoPopup.cjs +2 -2
- package/dist/widgets/FloatingChatWidget/hooks/useAutoPopup.js +2 -2
- package/dist/widgets/FloatingChatWidget/hooks/useFloatingButtonVisibility.cjs +1 -1
- package/dist/widgets/FloatingChatWidget/hooks/useFloatingButtonVisibility.js +1 -1
- package/dist/widgets/FullPageSalesAgentWidget/FullPageSalesAgentWidget.cjs +2 -2
- package/dist/widgets/FullPageSalesAgentWidget/FullPageSalesAgentWidget.d.cts +2 -2
- package/dist/widgets/FullPageSalesAgentWidget/FullPageSalesAgentWidget.d.ts +2 -2
- package/dist/widgets/FullPageSalesAgentWidget/FullPageSalesAgentWidget.js +2 -2
- package/dist/widgets/ProductCardWidget/ProductCardWidget.cjs +2 -2
- package/dist/widgets/ProductCardWidget/ProductCardWidget.d.cts +2 -2
- package/dist/widgets/ProductCardWidget/ProductCardWidget.d.ts +2 -2
- package/dist/widgets/ProductCardWidget/ProductCardWidget.js +2 -2
- package/dist/widgets/PromptButtonCarouselWithImageWidget/PromptButtonCarouselWithImageWidget.cjs +2 -2
- package/dist/widgets/PromptButtonCarouselWithImageWidget/PromptButtonCarouselWithImageWidget.d.cts +3 -3
- package/dist/widgets/PromptButtonCarouselWithImageWidget/PromptButtonCarouselWithImageWidget.d.ts +3 -3
- package/dist/widgets/PromptButtonCarouselWithImageWidget/PromptButtonCarouselWithImageWidget.js +2 -2
- package/dist/widgets/PromptCarouselWidget/PromptCarouselWidget.cjs +1 -1
- package/dist/widgets/PromptCarouselWidget/PromptCarouselWidget.d.cts +2 -2
- package/dist/widgets/PromptCarouselWidget/PromptCarouselWidget.d.ts +2 -2
- package/dist/widgets/PromptCarouselWidget/PromptCarouselWidget.js +1 -1
- package/dist/widgets/SocialProofFlowWidget/SocialProofFlowWidget.d.cts +2 -2
- package/dist/widgets/SocialProofFlowWidget/SocialProofFlowWidget.d.ts +2 -2
- package/dist/widgets/SocialProofWidget/SocialProofWidget.cjs +2 -2
- package/dist/widgets/SocialProofWidget/SocialProofWidget.d.cts +3 -3
- package/dist/widgets/SocialProofWidget/SocialProofWidget.d.ts +3 -3
- package/dist/widgets/SocialProofWidget/SocialProofWidget.js +2 -2
- package/dist/widgets/TitledPromptCarouselWidget/TitledPromptCarouselWidget.cjs +1 -1
- package/dist/widgets/TitledPromptCarouselWidget/TitledPromptCarouselWidget.d.cts +2 -2
- package/dist/widgets/TitledPromptCarouselWidget/TitledPromptCarouselWidget.d.ts +2 -2
- package/dist/widgets/TitledPromptCarouselWidget/TitledPromptCarouselWidget.js +1 -1
- package/dist/widgets/TypingAnimationFlowWidget/TypingAnimationFlowWidget.d.cts +2 -2
- package/dist/widgets/TypingAnimationFlowWidget/TypingAnimationFlowWidget.d.ts +2 -2
- package/dist/widgets/TypingAnimationWidget/TypingAnimationWidget.cjs +2 -2
- package/dist/widgets/TypingAnimationWidget/TypingAnimationWidget.d.cts +3 -3
- package/dist/widgets/TypingAnimationWidget/TypingAnimationWidget.d.ts +3 -3
- package/dist/widgets/TypingAnimationWidget/TypingAnimationWidget.js +2 -2
- package/dist/widgets/dist/SearchResults/SearchResultsWidget.d.cts +2 -2
- package/dist/widgets/dist/SearchZeroState/SearchZeroStateWidget.d.cts +2 -2
- package/dist/widgets/dist/SuggestionBar/SuggestionBar.d.cts +2 -2
- package/dist/widgets/utils/functions.cjs +1 -1
- package/dist/widgets/utils/functions.js +1 -1
- package/package.json +1 -1
- package/src/hocs/withBaseWidget/__tests__/withBaseWidget.test.tsx +15 -0
- package/src/hocs/withBaseWidget/withBaseWidget.tsx +47 -3
- package/src/widgets/ProductCardWidget/__tests__/ProductCardWidget.test.tsx +6 -0
|
@@ -79,6 +79,15 @@ vi.mock('@envive-ai/react-hooks/hooks/TrackComponentVisibleEvent', () => ({
|
|
|
79
79
|
useTrackComponentVisibleEvent: (...args: unknown[]) => mockUseTrackComponentVisibleEvent(...args),
|
|
80
80
|
}));
|
|
81
81
|
|
|
82
|
+
vi.mock('@envive-ai/react-hooks/contexts/featureFlagServiceContext', () => ({
|
|
83
|
+
useFeatureFlagService: () => ({ featureFlagService: undefined }),
|
|
84
|
+
}));
|
|
85
|
+
|
|
86
|
+
// Diagnostics pulls its own amplitude context internally; stub it here like the other sub-hooks.
|
|
87
|
+
vi.mock('@envive-ai/react-hooks/hooks/WidgetLoadDiagnostics', () => ({
|
|
88
|
+
useWidgetLoadDiagnostics: vi.fn(),
|
|
89
|
+
}));
|
|
90
|
+
|
|
82
91
|
// Test widget component
|
|
83
92
|
interface TestWidgetProps extends BaseWidgetProps {
|
|
84
93
|
testId?: string;
|
|
@@ -153,6 +162,7 @@ describe('withBaseWidget', () => {
|
|
|
153
162
|
{
|
|
154
163
|
widget_config_id: 'test-config-1',
|
|
155
164
|
widget_type: WidgetTypeV3.PromptCarouselV3,
|
|
165
|
+
load_id: expect.any(String),
|
|
156
166
|
},
|
|
157
167
|
'0px',
|
|
158
168
|
true,
|
|
@@ -173,6 +183,7 @@ describe('withBaseWidget', () => {
|
|
|
173
183
|
{
|
|
174
184
|
widget_config_id: 'test-config-2',
|
|
175
185
|
widget_type: WidgetTypeV3.ChatPreviewV3,
|
|
186
|
+
load_id: expect.any(String),
|
|
176
187
|
},
|
|
177
188
|
'100px',
|
|
178
189
|
true,
|
|
@@ -198,6 +209,7 @@ describe('withBaseWidget', () => {
|
|
|
198
209
|
{
|
|
199
210
|
widget_config_id: 'test-config-4',
|
|
200
211
|
widget_type: WidgetTypeV3.SocialProofV3,
|
|
212
|
+
load_id: expect.any(String),
|
|
201
213
|
custom_prop: 'custom_value',
|
|
202
214
|
another_prop: 123,
|
|
203
215
|
},
|
|
@@ -647,6 +659,7 @@ describe('withBaseWidget', () => {
|
|
|
647
659
|
{
|
|
648
660
|
widget_config_id: 'test-config-integration',
|
|
649
661
|
widget_type: WidgetTypeV3.PromptCarouselV3,
|
|
662
|
+
load_id: expect.any(String),
|
|
650
663
|
test_integration: true,
|
|
651
664
|
},
|
|
652
665
|
'0px',
|
|
@@ -722,6 +735,7 @@ describe('withBaseWidget', () => {
|
|
|
722
735
|
{
|
|
723
736
|
widget_config_id: 'widget-1',
|
|
724
737
|
widget_type: WidgetTypeV3.PromptCarouselV3,
|
|
738
|
+
load_id: expect.any(String),
|
|
725
739
|
},
|
|
726
740
|
'0px',
|
|
727
741
|
true,
|
|
@@ -731,6 +745,7 @@ describe('withBaseWidget', () => {
|
|
|
731
745
|
{
|
|
732
746
|
widget_config_id: 'widget-2',
|
|
733
747
|
widget_type: WidgetTypeV3.ChatPreviewV3,
|
|
748
|
+
load_id: expect.any(String),
|
|
734
749
|
},
|
|
735
750
|
'0px',
|
|
736
751
|
true,
|
|
@@ -8,6 +8,9 @@ import { usePage } from '@envive-ai/react-hooks/contexts/pageContext';
|
|
|
8
8
|
import { useWidgetConfig } from '@envive-ai/react-hooks/contexts/widgetConfigContext';
|
|
9
9
|
import { OrgUIConfigV3, WidgetConfigV3 } from '@envive-ai/react-hooks/contexts/typesV3';
|
|
10
10
|
import { useUiConfig } from '@envive-ai/react-hooks/contexts/uiConfigContext';
|
|
11
|
+
import { FeatureGates } from '@envive-ai/react-hooks/application/models';
|
|
12
|
+
import { useFeatureFlagService } from '@envive-ai/react-hooks/contexts/featureFlagServiceContext';
|
|
13
|
+
import { useWidgetLoadDiagnostics } from '@envive-ai/react-hooks/hooks/WidgetLoadDiagnostics';
|
|
11
14
|
import { BaseWidgetProps, WithBaseWidgetOptions } from './types';
|
|
12
15
|
|
|
13
16
|
const logger = new Logger('withBaseWidget');
|
|
@@ -51,12 +54,28 @@ export function withBaseWidget<P extends BaseWidgetProps>(
|
|
|
51
54
|
const [uiConfigSettled, setUiConfigSettled] = useState(false);
|
|
52
55
|
const ownRequestsSettled = hardcopySettled && widgetConfigSettled && uiConfigSettled;
|
|
53
56
|
|
|
57
|
+
// --- Widget load diagnostics (see useWidgetLoadDiagnostics) ---
|
|
58
|
+
// load_id correlates this widget's mount / rendered / outcome / stall events for one load.
|
|
59
|
+
const loadId = useRef(
|
|
60
|
+
`${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`,
|
|
61
|
+
).current;
|
|
62
|
+
const { featureFlagService } = useFeatureFlagService();
|
|
63
|
+
// Diagnostics are ON by default; the gate is a kill switch (default false → enabled) so we
|
|
64
|
+
// can gather a cross-merchant baseline. Flip it true (globally or per-org) via Statsig to stop.
|
|
65
|
+
const diagnosticsEnabled = !featureFlagService?.isFeatureGateEnabled(
|
|
66
|
+
FeatureGates.IsWidgetDiagnosticsDisabled,
|
|
67
|
+
);
|
|
68
|
+
// Reason this widget's own hardcopy request rejected (distinct from a served static fallback).
|
|
69
|
+
const hardcopyErrorRef = useRef<string | undefined>(undefined);
|
|
70
|
+
|
|
54
71
|
const visibilityEventProps = {
|
|
55
72
|
widget_config_id: widgetConfigId,
|
|
56
73
|
widget_type: widgetType,
|
|
74
|
+
// Threaded onto [Envive] Widget Rendered so it can be joined to the diagnostics events.
|
|
75
|
+
load_id: loadId,
|
|
57
76
|
...options?.visibilityEventProps,
|
|
58
77
|
};
|
|
59
|
-
const { isVisible } = useTrackComponentVisibleEvent(
|
|
78
|
+
const { isVisible, visibilitySource } = useTrackComponentVisibleEvent(
|
|
60
79
|
widgetRef,
|
|
61
80
|
visibilityEventProps,
|
|
62
81
|
options?.rootMargin || '0px',
|
|
@@ -125,8 +144,14 @@ export function withBaseWidget<P extends BaseWidgetProps>(
|
|
|
125
144
|
hardcopyFetchedRef.current = true;
|
|
126
145
|
getHardcopy({ widgetType, userEvent })
|
|
127
146
|
.then(setHardcopyContent)
|
|
128
|
-
.catch(
|
|
129
|
-
// Silently handle errors - widget will render without hardcopy content
|
|
147
|
+
.catch(error => {
|
|
148
|
+
// Silently handle errors - widget will render without hardcopy content. Record the
|
|
149
|
+
// reason for the load-outcome diagnostic (the served static-fallback path resolves
|
|
150
|
+
// rather than rejects, so reaching here means no content at all).
|
|
151
|
+
hardcopyErrorRef.current =
|
|
152
|
+
error instanceof Error && error.message.includes('timed out')
|
|
153
|
+
? 'hardcopy_timeout'
|
|
154
|
+
: 'hardcopy_error';
|
|
130
155
|
})
|
|
131
156
|
.finally(() => {
|
|
132
157
|
setHardcopySettled(true);
|
|
@@ -162,6 +187,25 @@ export function withBaseWidget<P extends BaseWidgetProps>(
|
|
|
162
187
|
});
|
|
163
188
|
}, [startLoading, widgetConfigId, widgetType, getWidgetConfig]);
|
|
164
189
|
|
|
190
|
+
const pendingRequests = [
|
|
191
|
+
hardcopySettled ? null : 'hardcopy',
|
|
192
|
+
widgetConfigSettled ? null : 'widgetConfig',
|
|
193
|
+
uiConfigSettled ? null : 'uiConfig',
|
|
194
|
+
].filter((name): name is string => name !== null);
|
|
195
|
+
|
|
196
|
+
useWidgetLoadDiagnostics({
|
|
197
|
+
enabled: diagnosticsEnabled,
|
|
198
|
+
loadId,
|
|
199
|
+
widgetType,
|
|
200
|
+
widgetConfigId,
|
|
201
|
+
startLoading,
|
|
202
|
+
ownRequestsSettled,
|
|
203
|
+
hardcopyContent,
|
|
204
|
+
visibilitySource,
|
|
205
|
+
pendingRequests,
|
|
206
|
+
hardcopyErrorReason: hardcopyErrorRef.current,
|
|
207
|
+
});
|
|
208
|
+
|
|
165
209
|
return (
|
|
166
210
|
<span ref={widgetRef}>
|
|
167
211
|
<Widget
|
|
@@ -60,6 +60,11 @@ vi.mock('@envive-ai/react-hooks/contexts/featureFlagServiceContext', () => ({
|
|
|
60
60
|
useFeatureFlagService: () => ({ featureFlagService: undefined }),
|
|
61
61
|
}));
|
|
62
62
|
|
|
63
|
+
// Diagnostics pulls its own amplitude context internally; stub it like the other sub-hooks.
|
|
64
|
+
vi.mock('@envive-ai/react-hooks/hooks/WidgetLoadDiagnostics', () => ({
|
|
65
|
+
useWidgetLoadDiagnostics: vi.fn(),
|
|
66
|
+
}));
|
|
67
|
+
|
|
63
68
|
vi.mock('@envive-ai/react-hooks/contexts/hardcopyContext', () => ({
|
|
64
69
|
useHardcopy: () => ({
|
|
65
70
|
getHardcopy: mockGetHardcopy,
|
|
@@ -131,6 +136,7 @@ describe('ProductCardWidget analytics', () => {
|
|
|
131
136
|
{
|
|
132
137
|
widget_config_id: 'test-config-1',
|
|
133
138
|
widget_type: WidgetTypeV3.ProductCardV3,
|
|
139
|
+
load_id: expect.any(String),
|
|
134
140
|
},
|
|
135
141
|
'0px',
|
|
136
142
|
true,
|