@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.
Files changed (73) hide show
  1. package/dist/debug/MessageContent.cjs +1 -1
  2. package/dist/debug/MessageContent.js +1 -1
  3. package/dist/debug/chatEmbed.cjs +1 -1
  4. package/dist/debug/chatEmbed.js +1 -1
  5. package/dist/debug/reportIssue.cjs +1 -1
  6. package/dist/debug/reportIssue.js +1 -1
  7. package/dist/hocs/withBaseWidget/withBaseWidget.cjs +28 -2
  8. package/dist/hocs/withBaseWidget/withBaseWidget.d.cts +2 -2
  9. package/dist/hocs/withBaseWidget/withBaseWidget.d.ts +2 -2
  10. package/dist/hocs/withBaseWidget/withBaseWidget.js +28 -2
  11. package/dist/packages/widgets/dist/SearchResults/SearchResultsWidget.d.ts +2 -2
  12. package/dist/packages/widgets/dist/SearchZeroState/SearchZeroStateWidget.d.ts +2 -2
  13. package/dist/packages/widgets/dist/SuggestionBar/SuggestionBar.d.ts +2 -2
  14. package/dist/widgets/ChatPreviewComparisonWidget/ChatPreviewComparisonWidget.cjs +2 -2
  15. package/dist/widgets/ChatPreviewComparisonWidget/ChatPreviewComparisonWidget.d.cts +3 -3
  16. package/dist/widgets/ChatPreviewComparisonWidget/ChatPreviewComparisonWidget.d.ts +3 -3
  17. package/dist/widgets/ChatPreviewComparisonWidget/ChatPreviewComparisonWidget.js +2 -2
  18. package/dist/widgets/ChatPreviewLoadingWidget/ChatPreviewLoadingWidget.cjs +2 -2
  19. package/dist/widgets/ChatPreviewLoadingWidget/ChatPreviewLoadingWidget.d.cts +3 -3
  20. package/dist/widgets/ChatPreviewLoadingWidget/ChatPreviewLoadingWidget.d.ts +3 -3
  21. package/dist/widgets/ChatPreviewLoadingWidget/ChatPreviewLoadingWidget.js +2 -2
  22. package/dist/widgets/ChatPreviewWidget/ChatPreviewWidget.cjs +2 -2
  23. package/dist/widgets/ChatPreviewWidget/ChatPreviewWidget.d.cts +3 -3
  24. package/dist/widgets/ChatPreviewWidget/ChatPreviewWidget.d.ts +3 -3
  25. package/dist/widgets/ChatPreviewWidget/ChatPreviewWidget.js +2 -2
  26. package/dist/widgets/FloatingChatWidget/FloatingChatWidget.cjs +2 -2
  27. package/dist/widgets/FloatingChatWidget/FloatingChatWidget.d.cts +2 -2
  28. package/dist/widgets/FloatingChatWidget/FloatingChatWidget.js +2 -2
  29. package/dist/widgets/FloatingChatWidget/hooks/useAutoPopup.cjs +2 -2
  30. package/dist/widgets/FloatingChatWidget/hooks/useAutoPopup.js +2 -2
  31. package/dist/widgets/FloatingChatWidget/hooks/useFloatingButtonVisibility.cjs +1 -1
  32. package/dist/widgets/FloatingChatWidget/hooks/useFloatingButtonVisibility.js +1 -1
  33. package/dist/widgets/FullPageSalesAgentWidget/FullPageSalesAgentWidget.cjs +2 -2
  34. package/dist/widgets/FullPageSalesAgentWidget/FullPageSalesAgentWidget.d.cts +2 -2
  35. package/dist/widgets/FullPageSalesAgentWidget/FullPageSalesAgentWidget.d.ts +2 -2
  36. package/dist/widgets/FullPageSalesAgentWidget/FullPageSalesAgentWidget.js +2 -2
  37. package/dist/widgets/ProductCardWidget/ProductCardWidget.cjs +2 -2
  38. package/dist/widgets/ProductCardWidget/ProductCardWidget.d.cts +2 -2
  39. package/dist/widgets/ProductCardWidget/ProductCardWidget.d.ts +2 -2
  40. package/dist/widgets/ProductCardWidget/ProductCardWidget.js +2 -2
  41. package/dist/widgets/PromptButtonCarouselWithImageWidget/PromptButtonCarouselWithImageWidget.cjs +2 -2
  42. package/dist/widgets/PromptButtonCarouselWithImageWidget/PromptButtonCarouselWithImageWidget.d.cts +3 -3
  43. package/dist/widgets/PromptButtonCarouselWithImageWidget/PromptButtonCarouselWithImageWidget.d.ts +3 -3
  44. package/dist/widgets/PromptButtonCarouselWithImageWidget/PromptButtonCarouselWithImageWidget.js +2 -2
  45. package/dist/widgets/PromptCarouselWidget/PromptCarouselWidget.cjs +1 -1
  46. package/dist/widgets/PromptCarouselWidget/PromptCarouselWidget.d.cts +2 -2
  47. package/dist/widgets/PromptCarouselWidget/PromptCarouselWidget.d.ts +2 -2
  48. package/dist/widgets/PromptCarouselWidget/PromptCarouselWidget.js +1 -1
  49. package/dist/widgets/SocialProofFlowWidget/SocialProofFlowWidget.d.cts +2 -2
  50. package/dist/widgets/SocialProofFlowWidget/SocialProofFlowWidget.d.ts +2 -2
  51. package/dist/widgets/SocialProofWidget/SocialProofWidget.cjs +2 -2
  52. package/dist/widgets/SocialProofWidget/SocialProofWidget.d.cts +3 -3
  53. package/dist/widgets/SocialProofWidget/SocialProofWidget.d.ts +3 -3
  54. package/dist/widgets/SocialProofWidget/SocialProofWidget.js +2 -2
  55. package/dist/widgets/TitledPromptCarouselWidget/TitledPromptCarouselWidget.cjs +1 -1
  56. package/dist/widgets/TitledPromptCarouselWidget/TitledPromptCarouselWidget.d.cts +2 -2
  57. package/dist/widgets/TitledPromptCarouselWidget/TitledPromptCarouselWidget.d.ts +2 -2
  58. package/dist/widgets/TitledPromptCarouselWidget/TitledPromptCarouselWidget.js +1 -1
  59. package/dist/widgets/TypingAnimationFlowWidget/TypingAnimationFlowWidget.d.cts +2 -2
  60. package/dist/widgets/TypingAnimationFlowWidget/TypingAnimationFlowWidget.d.ts +2 -2
  61. package/dist/widgets/TypingAnimationWidget/TypingAnimationWidget.cjs +2 -2
  62. package/dist/widgets/TypingAnimationWidget/TypingAnimationWidget.d.cts +3 -3
  63. package/dist/widgets/TypingAnimationWidget/TypingAnimationWidget.d.ts +3 -3
  64. package/dist/widgets/TypingAnimationWidget/TypingAnimationWidget.js +2 -2
  65. package/dist/widgets/dist/SearchResults/SearchResultsWidget.d.cts +2 -2
  66. package/dist/widgets/dist/SearchZeroState/SearchZeroStateWidget.d.cts +2 -2
  67. package/dist/widgets/dist/SuggestionBar/SuggestionBar.d.cts +2 -2
  68. package/dist/widgets/utils/functions.cjs +1 -1
  69. package/dist/widgets/utils/functions.js +1 -1
  70. package/package.json +1 -1
  71. package/src/hocs/withBaseWidget/__tests__/withBaseWidget.test.tsx +15 -0
  72. package/src/hocs/withBaseWidget/withBaseWidget.tsx +47 -3
  73. 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,