@envive-ai/react-hooks 0.3.18 → 0.3.19

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 (196) hide show
  1. package/dist/application/commerce-api.cjs +14 -13
  2. package/dist/application/commerce-api.js +14 -13
  3. package/dist/application/logging/logger.cjs +16 -10
  4. package/dist/application/logging/logger.js +16 -10
  5. package/dist/application/models/guards/api/isApiFormResponse.cjs +9 -8
  6. package/dist/application/models/guards/api/isApiFormResponse.js +9 -8
  7. package/dist/application/models/guards/api/isApiFormSubmittedResponseAttributes.cjs +6 -5
  8. package/dist/application/models/guards/api/isApiFormSubmittedResponseAttributes.js +6 -5
  9. package/dist/application/models/guards/api/isApiOrderResponseAttributes.cjs +19 -18
  10. package/dist/application/models/guards/api/isApiOrderResponseAttributes.js +19 -18
  11. package/dist/application/models/guards/api/isApiOrgConfigResults.cjs +27 -26
  12. package/dist/application/models/guards/api/isApiOrgConfigResults.js +27 -26
  13. package/dist/application/models/guards/api/isApiOrganizationConfig.cjs +23 -22
  14. package/dist/application/models/guards/api/isApiOrganizationConfig.js +23 -22
  15. package/dist/application/models/guards/api/isApiProductResponseAttributes.cjs +12 -11
  16. package/dist/application/models/guards/api/isApiProductResponseAttributes.js +12 -11
  17. package/dist/application/models/guards/api/isApiResponse.cjs +7 -6
  18. package/dist/application/models/guards/api/isApiResponse.js +7 -6
  19. package/dist/application/models/guards/graphQL/isGraphQLColorsConfig.cjs +5 -4
  20. package/dist/application/models/guards/graphQL/isGraphQLColorsConfig.js +5 -4
  21. package/dist/application/models/validators/validateGraphQLFrontendConfig.cjs +15 -14
  22. package/dist/application/models/validators/validateGraphQLFrontendConfig.js +15 -14
  23. package/dist/application/utils/analyticsUtils.cjs +4 -3
  24. package/dist/application/utils/analyticsUtils.js +4 -3
  25. package/dist/application/utils/nextMessageRequestToApiRequest.cjs +3 -1
  26. package/dist/application/utils/nextMessageRequestToApiRequest.js +3 -1
  27. package/dist/atoms/app/index.d.cts +7 -7
  28. package/dist/atoms/app/index.d.ts +7 -7
  29. package/dist/atoms/app/variant.cjs +3 -2
  30. package/dist/atoms/app/variant.js +3 -2
  31. package/dist/atoms/chat/chatState.d.cts +17 -17
  32. package/dist/atoms/chat/chatState.d.ts +17 -17
  33. package/dist/atoms/chat/form.d.cts +2 -2
  34. package/dist/atoms/chat/form.d.ts +2 -2
  35. package/dist/atoms/chat/index.d.cts +2 -2
  36. package/dist/atoms/chat/index.d.ts +2 -2
  37. package/dist/atoms/chat/lastMessage.d.cts +2 -2
  38. package/dist/atoms/chat/lastMessage.d.ts +2 -2
  39. package/dist/atoms/chat/messageQueue.d.cts +6 -6
  40. package/dist/atoms/chat/messageQueue.d.ts +6 -6
  41. package/dist/atoms/chat/performanceMetrics.cjs +3 -2
  42. package/dist/atoms/chat/performanceMetrics.d.cts +6 -6
  43. package/dist/atoms/chat/performanceMetrics.d.ts +6 -6
  44. package/dist/atoms/chat/performanceMetrics.js +3 -2
  45. package/dist/atoms/chat/renderedWidgetRefs.d.cts +2 -2
  46. package/dist/atoms/chat/renderedWidgetRefs.d.ts +2 -2
  47. package/dist/atoms/chat/replies.d.cts +2 -2
  48. package/dist/atoms/chat/replies.d.ts +3 -3
  49. package/dist/atoms/chat/suggestions.d.cts +2 -2
  50. package/dist/atoms/chat/suggestions.d.ts +2 -2
  51. package/dist/atoms/envive/enviveConfig.cjs +5 -4
  52. package/dist/atoms/envive/enviveConfig.d.cts +13 -13
  53. package/dist/atoms/envive/enviveConfig.d.ts +13 -13
  54. package/dist/atoms/envive/enviveConfig.js +5 -4
  55. package/dist/atoms/globalSearch/globalSearch.d.cts +5 -5
  56. package/dist/atoms/globalSearch/globalSearch.d.ts +5 -5
  57. package/dist/atoms/org/customerService.d.cts +6 -6
  58. package/dist/atoms/org/customerService.d.ts +6 -6
  59. package/dist/atoms/org/graphqlConfig.d.cts +4 -4
  60. package/dist/atoms/org/graphqlConfig.d.ts +4 -4
  61. package/dist/atoms/org/newOrgConfigAtom.d.cts +2 -2
  62. package/dist/atoms/org/newOrgConfigAtom.d.ts +2 -2
  63. package/dist/atoms/org/orgAnalyticsConfig.d.cts +5 -5
  64. package/dist/atoms/org/orgAnalyticsConfig.d.ts +5 -5
  65. package/dist/atoms/search/chatSearch.d.cts +17 -17
  66. package/dist/atoms/search/chatSearch.d.ts +17 -17
  67. package/dist/atoms/search/searchAPI.d.cts +13 -13
  68. package/dist/atoms/search/searchAPI.d.ts +13 -13
  69. package/dist/atoms/search/types.d.cts +1 -1
  70. package/dist/atoms/search/types.d.ts +1 -1
  71. package/dist/atoms/search/utils.d.ts +1 -1
  72. package/dist/atoms/widget/chatPreviewLoading.d.cts +2 -2
  73. package/dist/atoms/widget/chatPreviewLoading.d.ts +2 -2
  74. package/dist/contexts/amplitudeContext/amplitudeContext.cjs +4 -3
  75. package/dist/contexts/amplitudeContext/amplitudeContext.js +3 -2
  76. package/dist/contexts/enviveConfigContext/enviveConfigContext.cjs +26 -15
  77. package/dist/contexts/enviveConfigContext/enviveConfigContext.d.cts +2 -4
  78. package/dist/contexts/enviveConfigContext/enviveConfigContext.d.ts +2 -4
  79. package/dist/contexts/enviveConfigContext/enviveConfigContext.js +29 -16
  80. package/dist/contexts/enviveConfigContext/index.cjs +2 -1
  81. package/dist/contexts/enviveConfigContext/index.d.cts +2 -1
  82. package/dist/contexts/enviveConfigContext/index.d.ts +2 -1
  83. package/dist/contexts/enviveConfigContext/index.js +2 -1
  84. package/dist/contexts/enviveConfigContext/useEnviveConfig.cjs +12 -0
  85. package/dist/contexts/enviveConfigContext/useEnviveConfig.d.cts +7 -0
  86. package/dist/contexts/enviveConfigContext/useEnviveConfig.d.ts +7 -0
  87. package/dist/contexts/enviveConfigContext/useEnviveConfig.js +11 -0
  88. package/dist/contexts/enviveContext/WindowChatToggleBinder.cjs +7 -5
  89. package/dist/contexts/enviveContext/WindowChatToggleBinder.js +6 -4
  90. package/dist/contexts/enviveContext/enviveContext.cjs +34 -39
  91. package/dist/contexts/enviveContext/enviveContext.js +35 -40
  92. package/dist/contexts/featureFlagServiceContext/featureFlagServiceContext.cjs +7 -6
  93. package/dist/contexts/featureFlagServiceContext/featureFlagServiceContext.js +7 -6
  94. package/dist/contexts/graphqlContext/graphqlContext.cjs +8 -7
  95. package/dist/contexts/graphqlContext/graphqlContext.js +8 -7
  96. package/dist/contexts/hardcopyContext/hardcopyContext.cjs +9 -8
  97. package/dist/contexts/hardcopyContext/hardcopyContext.js +9 -8
  98. package/dist/contexts/localStorageContext/localStorageContext.cjs +4 -3
  99. package/dist/contexts/localStorageContext/localStorageContext.js +4 -3
  100. package/dist/contexts/pageContext/pageContext.cjs +3 -2
  101. package/dist/contexts/pageContext/pageContext.js +3 -2
  102. package/dist/contexts/salesAgentContext/chatAPI.cjs +3 -2
  103. package/dist/contexts/salesAgentContext/chatAPI.js +3 -2
  104. package/dist/contexts/salesAgentContext/salesAgentContext.cjs +4 -3
  105. package/dist/contexts/salesAgentContext/salesAgentContext.js +4 -3
  106. package/dist/contexts/salesAgentContext/salesAgentService.cjs +3 -2
  107. package/dist/contexts/salesAgentContext/salesAgentService.js +3 -2
  108. package/dist/contexts/searchContext/searchContext.cjs +8 -6
  109. package/dist/contexts/searchContext/searchContext.js +7 -5
  110. package/dist/contexts/sessionStorageContext/sessionStorageContext.cjs +3 -2
  111. package/dist/contexts/sessionStorageContext/sessionStorageContext.js +3 -2
  112. package/dist/contexts/systemSettingsContext/systemSettingsContext.d.cts +2 -2
  113. package/dist/contexts/types.d.cts +1 -1
  114. package/dist/contexts/types.d.ts +1 -1
  115. package/dist/contexts/typesV3.d.cts +1 -1
  116. package/dist/contexts/typesV3.d.ts +1 -1
  117. package/dist/contexts/uiConfigContext/index.cjs +0 -1
  118. package/dist/contexts/uiConfigContext/index.d.cts +2 -2
  119. package/dist/contexts/uiConfigContext/index.d.ts +2 -2
  120. package/dist/contexts/uiConfigContext/index.js +2 -2
  121. package/dist/contexts/uiConfigContext/uiConfigContext.cjs +13 -30
  122. package/dist/contexts/uiConfigContext/uiConfigContext.d.cts +5 -9
  123. package/dist/contexts/uiConfigContext/uiConfigContext.d.ts +5 -9
  124. package/dist/contexts/uiConfigContext/uiConfigContext.js +14 -29
  125. package/dist/contexts/userIdentityContext/userIdentityContext.cjs +7 -7
  126. package/dist/contexts/userIdentityContext/userIdentityContext.js +7 -7
  127. package/dist/contexts/widgetConfigContext/widgetConfigContext.cjs +4 -3
  128. package/dist/contexts/widgetConfigContext/widgetConfigContext.js +4 -3
  129. package/dist/hooks/CustomerSupportHandoff/useCustomerSupportHandoff.cjs +4 -3
  130. package/dist/hooks/CustomerSupportHandoff/useCustomerSupportHandoff.js +4 -3
  131. package/dist/hooks/GrabAndScroll/useGrabAndScroll.d.cts +2 -2
  132. package/dist/hooks/SystemSettingsContext/useSystemSettingsContext.d.cts +2 -2
  133. package/dist/hooks/WidgetInteraction/useWidgetInteraction.cjs +2 -2
  134. package/dist/hooks/WidgetInteraction/useWidgetInteraction.js +2 -2
  135. package/dist/hooks/WidgetInteraction/utils.cjs +2 -1
  136. package/dist/hooks/WidgetInteraction/utils.js +2 -1
  137. package/dist/hooks/utils.d.cts +1 -1
  138. package/dist/hooks/utils.d.ts +1 -1
  139. package/dist/services/amplitudeService/amplitudeService.cjs +8 -7
  140. package/dist/services/amplitudeService/amplitudeService.js +8 -7
  141. package/dist/services/ga4ProjectionService/ga4ProjectionService.cjs +3 -2
  142. package/dist/services/ga4ProjectionService/ga4ProjectionService.js +3 -2
  143. package/dist/services/userIdentityService/userIdentityService.cjs +8 -7
  144. package/dist/services/userIdentityService/userIdentityService.js +8 -7
  145. package/package.json +1 -1
  146. package/src/application/commerce-api.ts +14 -12
  147. package/src/application/logging/logger.ts +33 -8
  148. package/src/application/models/guards/api/isApiFormResponse.ts +9 -7
  149. package/src/application/models/guards/api/isApiFormSubmittedResponseAttributes.ts +6 -4
  150. package/src/application/models/guards/api/isApiOrderResponseAttributes.ts +19 -17
  151. package/src/application/models/guards/api/isApiOrgConfigResults.ts +40 -48
  152. package/src/application/models/guards/api/isApiOrganizationConfig.ts +25 -38
  153. package/src/application/models/guards/api/isApiProductResponseAttributes.ts +12 -10
  154. package/src/application/models/guards/api/isApiResponse.ts +7 -5
  155. package/src/application/models/guards/graphQL/isGraphQLColorsConfig.ts +5 -3
  156. package/src/application/models/validators/validateGraphQLFrontendConfig.ts +15 -13
  157. package/src/application/utils/analyticsUtils.ts +4 -4
  158. package/src/application/utils/nextMessageRequestToApiRequest.ts +2 -0
  159. package/src/atoms/app/variant.ts +3 -1
  160. package/src/atoms/chat/performanceMetrics.ts +3 -1
  161. package/src/atoms/envive/enviveConfig.ts +5 -3
  162. package/src/contexts/amplitudeContext/amplitudeContext.tsx +1 -1
  163. package/src/contexts/enviveConfigContext/__tests__/enviveConfigContext.test.tsx +4 -3
  164. package/src/contexts/enviveConfigContext/enviveConfigContext.tsx +50 -35
  165. package/src/contexts/enviveConfigContext/index.ts +1 -0
  166. package/src/contexts/enviveConfigContext/useEnviveConfig.ts +9 -0
  167. package/src/contexts/enviveContext/WindowChatToggleBinder.tsx +6 -4
  168. package/src/contexts/enviveContext/enviveContext.tsx +40 -45
  169. package/src/contexts/featureFlagServiceContext/featureFlagServiceContext.tsx +11 -12
  170. package/src/contexts/graphqlContext/__tests__/graphqlContext.test.tsx +4 -4
  171. package/src/contexts/graphqlContext/graphqlContext.tsx +8 -6
  172. package/src/contexts/hardcopyContext/hardcopyContext.tsx +9 -7
  173. package/src/contexts/localStorageContext/__tests__/localStorageContext.test.tsx +6 -6
  174. package/src/contexts/localStorageContext/localStorageContext.tsx +4 -2
  175. package/src/contexts/pageContext/__tests__/pageContext.test.tsx +5 -5
  176. package/src/contexts/pageContext/pageContext.tsx +3 -1
  177. package/src/contexts/salesAgentContext/chatAPI.ts +5 -5
  178. package/src/contexts/salesAgentContext/salesAgentContext.tsx +4 -2
  179. package/src/contexts/salesAgentContext/salesAgentService.ts +4 -2
  180. package/src/contexts/searchContext/__tests__/searchContext.test.tsx +15 -12
  181. package/src/contexts/searchContext/searchContext.tsx +6 -4
  182. package/src/contexts/sessionStorageContext/sessionStorageContext.tsx +3 -1
  183. package/src/contexts/uiConfigContext/__tests__/uiConfigContext.test.tsx +7 -32
  184. package/src/contexts/uiConfigContext/uiConfigContext.tsx +17 -29
  185. package/src/contexts/userIdentityContext/__tests__/userIdentityContext.test.tsx +5 -5
  186. package/src/contexts/userIdentityContext/userIdentityContext.tsx +7 -6
  187. package/src/contexts/widgetConfigContext/__tests__/widgetConfigContext.test.tsx +7 -7
  188. package/src/contexts/widgetConfigContext/widgetConfigContext.tsx +4 -2
  189. package/src/hooks/CustomerSupportHandoff/useCustomerSupportHandoff.ts +4 -2
  190. package/src/hooks/Search/__tests__/useSearch.test.tsx +14 -8
  191. package/src/hooks/WidgetInteraction/useWidgetInteraction.ts +3 -2
  192. package/src/hooks/WidgetInteraction/utils.ts +3 -1
  193. package/src/services/amplitudeService/__tests__/amplitudeService.test.ts +3 -3
  194. package/src/services/amplitudeService/amplitudeService.ts +8 -6
  195. package/src/services/ga4ProjectionService/ga4ProjectionService.ts +3 -1
  196. package/src/services/userIdentityService/userIdentityService.ts +8 -8
@@ -6,13 +6,13 @@ import { SparkleIconColor } from '@envive-ai/react-toolkit-v3/WelcomeMessage';
6
6
  import { ChatHeaderVariant } from '@envive-ai/react-toolkit-v3/ChatHeader';
7
7
  import { Theme } from '@envive-ai/react-toolkit-v3/Tokens';
8
8
  import { FloatingButtonLocation } from '@envive-ai/react-toolkit-v3/FloatingButton';
9
- import { UiConfigProvider, useUiConfig } from '../uiConfigContext';
9
+ import { useUiConfig } from '../uiConfigContext';
10
10
  import { ConfigVersionEnum, OrgUIConfigV3 } from '../../typesV3';
11
11
 
12
12
  // Mock the Logger to avoid console output in tests
13
- vi.spyOn(Logger, 'logInfo').mockImplementation(() => {});
14
- vi.spyOn(Logger, 'logWarn').mockImplementation(() => {});
15
- vi.spyOn(Logger, 'logError').mockImplementation(() => {});
13
+ vi.spyOn(Logger.prototype, 'logInfo').mockImplementation(() => {});
14
+ vi.spyOn(Logger.prototype, 'logWarn').mockImplementation(() => {});
15
+ vi.spyOn(Logger.prototype, 'logError').mockImplementation(() => {});
16
16
 
17
17
  // Mock the useNewOrgConfig hook
18
18
  vi.mock('src/hooks/NewOrgConfig', () => ({
@@ -30,7 +30,7 @@ const MockUiConfigComponent: React.FC = () => {
30
30
  setIsLoadingState(true);
31
31
  try {
32
32
  const config = await getUiConfig();
33
- setUiConfig(config);
33
+ setUiConfig(config ?? null);
34
34
  setError(null);
35
35
  } catch (err: unknown) {
36
36
  setError(err instanceof Error ? err.message : 'Unknown error');
@@ -74,7 +74,7 @@ const TestWrapper: React.FC<{
74
74
  loading: mockNewOrgConfig.loading ?? false,
75
75
  });
76
76
 
77
- return <UiConfigProvider>{children}</UiConfigProvider>;
77
+ return children;
78
78
  };
79
79
 
80
80
  describe('UiConfigProvider', () => {
@@ -129,7 +129,7 @@ describe('UiConfigProvider', () => {
129
129
  });
130
130
 
131
131
  describe('useUiConfig Hook Integration', () => {
132
- it('should provide context through useUiConfig hook', async () => {
132
+ it('should provide ui config data via useUiConfig hook', async () => {
133
133
  const mockUiConfig = createMockUiConfig();
134
134
 
135
135
  render(
@@ -151,31 +151,6 @@ describe('UiConfigProvider', () => {
151
151
 
152
152
  expect(screen.getByTestId('is-loading')).toHaveTextContent('false');
153
153
  });
154
-
155
- it('should throw error when used outside of UiConfigProvider', () => {
156
- const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
157
-
158
- const TestComponent: React.FC = () => {
159
- try {
160
- useUiConfig();
161
- return <div data-testid="no-error">No Error</div>;
162
- } catch (error: unknown) {
163
- return (
164
- <div data-testid="error">
165
- {error instanceof Error ? error.message : 'Unknown error'}
166
- </div>
167
- );
168
- }
169
- };
170
-
171
- render(<TestComponent />);
172
-
173
- expect(screen.getByTestId('error')).toHaveTextContent(
174
- 'useUiConfig must be used within a UiConfigProvider',
175
- );
176
-
177
- consoleSpy.mockRestore();
178
- });
179
154
  });
180
155
 
181
156
  describe('getUiConfig', () => {
@@ -1,44 +1,32 @@
1
- import { ReactNode, createContext, useCallback, useContext, useMemo, useState } from 'react';
2
1
  import Logger from 'src/application/logging/logger';
3
2
  import { useNewOrgConfig } from 'src/hooks/NewOrgConfig';
4
3
  import { OrgUIConfigV3 } from '../typesV3';
5
4
 
6
- interface UiConfigContextType {
7
- getUiConfig: () => Promise<OrgUIConfigV3>;
5
+ const logger = new Logger('uiConfigContext');
6
+ interface UiConfigHookResult {
7
+ getUiConfig: () => Promise<OrgUIConfigV3 | undefined>;
8
8
  isLoading: boolean;
9
9
  }
10
10
 
11
- const UiConfigContext = createContext<UiConfigContextType | undefined>(undefined);
11
+ export const useUiConfig = (): UiConfigHookResult => {
12
+ const { frontendConfig, loading } = useNewOrgConfig();
12
13
 
13
- export const UiConfigProvider: React.FC<{ children: ReactNode }> = ({ children }) => {
14
- const { frontendConfig, loading: isFrontendConfigLoading } = useNewOrgConfig();
15
- const [isLoadingUiConfig, setIsLoadingUiConfig] = useState(false);
14
+ const getUiConfig = async (): Promise<OrgUIConfigV3 | undefined> => {
15
+ logger.logDebug('uiConfigContext | retrieving ui config');
16
16
 
17
- const getUiConfig = useCallback(async (): Promise<OrgUIConfigV3> => {
18
- setIsLoadingUiConfig(true);
19
- Logger.logInfo('uiConfigContext | retrieving ui config');
20
- if (isFrontendConfigLoading) {
21
- setIsLoadingUiConfig(false);
17
+ if (loading) {
18
+ logger.logDebug('uiConfigContext | frontend config still loading');
22
19
  throw new Error('Frontend config is loading');
23
20
  }
24
21
 
25
- const response = frontendConfig?.uiConfigs as OrgUIConfigV3;
26
- Logger.logInfo('uiConfigContext | returning ui config response', response);
27
- setIsLoadingUiConfig(false);
28
- return response;
29
- }, [frontendConfig, isFrontendConfigLoading]);
30
-
31
- const isLoading = isFrontendConfigLoading || isLoadingUiConfig;
32
-
33
- const value = useMemo(() => ({ getUiConfig, isLoading }), [getUiConfig, isLoading]);
22
+ const response = frontendConfig?.uiConfigs as OrgUIConfigV3 | undefined;
23
+ logger.logDebug('uiConfigContext | returning ui config response', response);
34
24
 
35
- return <UiConfigContext.Provider value={value}>{children}</UiConfigContext.Provider>;
36
- };
25
+ return response;
26
+ };
37
27
 
38
- export const useUiConfig = () => {
39
- const context = useContext(UiConfigContext);
40
- if (!context) {
41
- throw new Error('useUiConfig must be used within a UiConfigProvider');
42
- }
43
- return context;
28
+ return {
29
+ getUiConfig,
30
+ isLoading: loading,
31
+ };
44
32
  };
@@ -8,9 +8,9 @@ import { UserIdentityService } from 'src/services/userIdentityService';
8
8
  import { UserIdentityProvider, useUserIdentity } from '../userIdentityContext';
9
9
 
10
10
  // Mock the Logger to avoid console output in tests
11
- vi.spyOn(Logger, 'logInfo').mockImplementation(() => {});
12
- vi.spyOn(Logger, 'logWarn').mockImplementation(() => {});
13
- vi.spyOn(Logger, 'logError').mockImplementation(() => {});
11
+ vi.spyOn(Logger.prototype, 'logInfo').mockImplementation(() => {});
12
+ vi.spyOn(Logger.prototype, 'logWarn').mockImplementation(() => {});
13
+ vi.spyOn(Logger.prototype, 'logError').mockImplementation(() => {});
14
14
 
15
15
  // Mock uuid to have predictable values in tests
16
16
  vi.mock('uuid', () => ({
@@ -262,7 +262,7 @@ describe('UserIdentityProvider', () => {
262
262
  });
263
263
 
264
264
  it('should log info when setting userId override', async () => {
265
- const logSpy = vi.spyOn(Logger, 'logInfo');
265
+ const logSpy = vi.spyOn(Logger.prototype, 'logInfo');
266
266
 
267
267
  const ComponentWithSet: React.FC = () => {
268
268
  const context = useUserIdentity();
@@ -283,7 +283,7 @@ describe('UserIdentityProvider', () => {
283
283
  });
284
284
 
285
285
  it('should log info when clearing userId override', async () => {
286
- const logSpy = vi.spyOn(Logger, 'logInfo');
286
+ const logSpy = vi.spyOn(Logger.prototype, 'logInfo');
287
287
 
288
288
  const ComponentWithClear: React.FC = () => {
289
289
  const context = useUserIdentity();
@@ -13,6 +13,8 @@ import { useSetAtom } from 'jotai';
13
13
  import { userIdAtom } from 'src/atoms/app';
14
14
  import { UserIdentityService } from 'src/services/userIdentityService';
15
15
 
16
+ const logger = new Logger('userIdentityContext');
17
+
16
18
  export interface UserIdentityContextType {
17
19
  getUserIdOrDefault: () => Promise<string>;
18
20
  getUserIdOverrideFromLocalStorage: () => string | undefined;
@@ -53,7 +55,7 @@ export const UserIdentityProvider: React.FC<UserIdentityProviderProps> = ({
53
55
 
54
56
  const setUserIdOverrideInLocalStorage = useCallback(
55
57
  (userId: string): string => {
56
- Logger.logInfo(`setUserIdOverrideInLocalStorage - Setting user_id=${userId}`);
58
+ logger.logInfo(`setUserIdOverrideInLocalStorage - Setting user_id=${userId}`);
57
59
  setItem(USER_ID_OVERRIDE_KEY, userId);
58
60
  // window.dispatchEvent is handled by useLocalStorage now
59
61
  return userId;
@@ -62,7 +64,7 @@ export const UserIdentityProvider: React.FC<UserIdentityProviderProps> = ({
62
64
  );
63
65
 
64
66
  const clearUserIdOverrideInLocalStorage = useCallback(() => {
65
- Logger.logInfo(`clearUserIdOverrideInLocalStorage - Clearing user_id`);
67
+ logger.logInfo(`clearUserIdOverrideInLocalStorage - Clearing user_id`);
66
68
  // LocalStorageService.getLocalStorage()?.removeItem(USER_ID_OVERRIDE_KEY);
67
69
  // window.dispatchEvent is handled by useLocalStorage now
68
70
  setItem(USER_ID_OVERRIDE_KEY, ''); // Set to empty string to clear
@@ -80,15 +82,15 @@ export const UserIdentityProvider: React.FC<UserIdentityProviderProps> = ({
80
82
 
81
83
  if (!enviveUserId) {
82
84
  throw new Error(
83
- '[spiffy-ai] EnviveAnalytics.resolveEnviveUserId() returned null/undefined - this should never happen',
85
+ 'EnviveAnalytics.resolveEnviveUserId() returned null/undefined - this should never happen',
84
86
  );
85
87
  }
86
88
 
87
89
  return enviveUserId;
88
90
  } catch (error: unknown) {
89
- Logger.logError('[spiffy-ai] CRITICAL: Failed to get user ID from EnviveAnalytics', error);
91
+ logger.logError('CRITICAL: Failed to get user ID from EnviveAnalytics', error);
90
92
  const errorMessage = error instanceof Error ? error.message : 'Unknown error';
91
- throw new Error(`[spiffy-ai] CRITICAL: User ID resolution failed: ${errorMessage}`);
93
+ throw new Error(`CRITICAL: User ID resolution failed: ${errorMessage}`);
92
94
  }
93
95
  }, [getUserIdOverrideFromLocalStorage]);
94
96
 
@@ -112,7 +114,6 @@ export const UserIdentityProvider: React.FC<UserIdentityProviderProps> = ({
112
114
  if (isReady && !localUserId) {
113
115
  const setUserIdStates = async () => {
114
116
  const newUserId = await getUserIdOrDefault();
115
- console.log('useUserIdentity useEffect - setting localUserId', newUserId);
116
117
  setLocalUserId(newUserId);
117
118
  setUserId(newUserId);
118
119
  };
@@ -7,9 +7,9 @@ import { WidgetConfigProvider, useWidgetConfig } from '../widgetConfigContext';
7
7
  import { WidgetConfigV3, WidgetTypeV3 } from '../../typesV3';
8
8
 
9
9
  // Mock the Logger to avoid console output in tests
10
- vi.spyOn(Logger, 'logInfo').mockImplementation(() => {});
11
- vi.spyOn(Logger, 'logWarn').mockImplementation(() => {});
12
- vi.spyOn(Logger, 'logError').mockImplementation(() => {});
10
+ vi.spyOn(Logger.prototype, 'logInfo').mockImplementation(() => {});
11
+ vi.spyOn(Logger.prototype, 'logWarn').mockImplementation(() => {});
12
+ vi.spyOn(Logger.prototype, 'logError').mockImplementation(() => {});
13
13
 
14
14
  // Mock the useNewOrgConfig hook
15
15
  vi.mock('src/hooks/NewOrgConfig', () => ({
@@ -394,7 +394,7 @@ describe('WidgetConfigProvider', () => {
394
394
 
395
395
  describe('Logger Integration', () => {
396
396
  it('should log info when retrieving widget config', async () => {
397
- const logInfoSpy = vi.spyOn(Logger, 'logInfo');
397
+ const logDebugSpy = vi.spyOn(Logger.prototype, 'logDebug');
398
398
  const mockWidgetConfig: WidgetConfigV3 = {
399
399
  widgetConfigId: 'test-config-id',
400
400
  type: WidgetTypeV3.PromptCarouselV3,
@@ -425,12 +425,12 @@ describe('WidgetConfigProvider', () => {
425
425
  });
426
426
 
427
427
  await waitFor(() => {
428
- expect(logInfoSpy).toHaveBeenCalledWith('widgetConfigContext | retrieving widget config', {
428
+ expect(logDebugSpy).toHaveBeenCalledWith('retrieving widget config', {
429
429
  widgetConfigId: 'test-config-id',
430
430
  widgetType: WidgetTypeV3.PromptCarouselV3,
431
431
  });
432
- expect(logInfoSpy).toHaveBeenCalledWith(
433
- 'widgetConfigContext | returning widget config response',
432
+ expect(logDebugSpy).toHaveBeenCalledWith(
433
+ 'returning widget config response',
434
434
  mockWidgetConfig,
435
435
  );
436
436
  });
@@ -3,6 +3,8 @@ import Logger from 'src/application/logging/logger';
3
3
  import { useNewOrgConfig } from 'src/hooks/NewOrgConfig';
4
4
  import { WidgetConfigV3, WidgetTypeV3 } from '../typesV3';
5
5
 
6
+ const logger = new Logger('widgetConfigContext');
7
+
6
8
  interface WidgetConfigRequest {
7
9
  widgetType: WidgetTypeV3;
8
10
  widgetConfigId: string;
@@ -22,7 +24,7 @@ export const WidgetConfigProvider: React.FC<{ children: ReactNode }> = ({ childr
22
24
  const getWidgetConfig = useCallback(
23
25
  async (request: WidgetConfigRequest): Promise<WidgetConfigV3> => {
24
26
  setIsLoadingWidgetConfig(true);
25
- Logger.logInfo('widgetConfigContext | retrieving widget config', {
27
+ logger.logDebug('retrieving widget config', {
26
28
  widgetConfigId: request.widgetConfigId,
27
29
  widgetType: request.widgetType,
28
30
  });
@@ -33,7 +35,7 @@ export const WidgetConfigProvider: React.FC<{ children: ReactNode }> = ({ childr
33
35
 
34
36
  const { widgetConfigId, widgetType } = request;
35
37
  const response = frontendConfig?.widgetConfigs?.[widgetConfigId];
36
- Logger.logInfo('widgetConfigContext | returning widget config response', response);
38
+ logger.logDebug('returning widget config response', response);
37
39
 
38
40
  if (widgetConfigId === 'fake-widget-config-id') {
39
41
  return {} as WidgetConfigV3;
@@ -1,6 +1,8 @@
1
1
  import Logger from 'src/application/logging/logger';
2
2
  import { useCallback } from 'react';
3
3
 
4
+ const logger = new Logger('useCustomerSupportHandoff');
5
+
4
6
  /**
5
7
  * Hook to call the `click` method of the merchant's customer support chat widget.
6
8
  *
@@ -17,14 +19,14 @@ export const useCustomerSupportHandoff = (onSwitchToAgent?: () => void) => {
17
19
  const kustomerElement = document.getElementById('kustomer-ui-sdk-iframe');
18
20
 
19
21
  if (kustomerElement == null || !(kustomerElement instanceof HTMLIFrameElement)) {
20
- Logger.logError('[spiffy-ai] Kustomer iFrame element not found', undefined);
22
+ logger.logError('Kustomer iFrame element not found', undefined);
21
23
  return;
22
24
  }
23
25
 
24
26
  const kustomerButton = kustomerElement.contentWindow?.document?.getElementById('rootChatIcon');
25
27
 
26
28
  if (kustomerButton == null) {
27
- Logger.logError('[spiffy-ai] Kustomer button not found', undefined);
29
+ logger.logError('Kustomer button not found', undefined);
28
30
  return;
29
31
  }
30
32
 
@@ -135,14 +135,20 @@ vi.mock('@spiffy-ai/commerce-api-client', () => ({
135
135
  }));
136
136
 
137
137
  // Mock Logger
138
- vi.mock('src/application/logging/logger', () => ({
139
- default: {
140
- logInfo: vi.fn(),
141
- logWarn: vi.fn(),
142
- logError: vi.fn(),
143
- logDebug: vi.fn(),
144
- },
145
- }));
138
+ vi.mock('src/application/logging/logger', () => {
139
+ const MockLogger = vi.fn(function MockLogger() {
140
+ return {
141
+ logInfo: vi.fn(),
142
+ logWarn: vi.fn(),
143
+ logError: vi.fn(),
144
+ logDebug: vi.fn(),
145
+ };
146
+ });
147
+
148
+ return {
149
+ default: MockLogger,
150
+ };
151
+ });
146
152
 
147
153
  // Mock search service adapter
148
154
  vi.mock('src/atoms/search/searchServiceAdapter', () => ({
@@ -6,12 +6,15 @@ import { v4 as uuid } from 'uuid';
6
6
  import { InternalWidgetInteraction, WidgetInteraction } from './types';
7
7
  import { extractPageContext } from './utils';
8
8
 
9
+ const getInteractionId = () => uuid();
10
+
9
11
  export const useWidgetInteraction = () => {
10
12
  const { trackEvent } = useAmplitude();
11
13
  const variantInfo = useAtomValue(pageVariantInfoAtom);
12
14
 
13
15
  const trackWidgetInteraction = (props: WidgetInteraction) => {
14
16
  if (props.trigger) {
17
+ // eslint-disable-next-line no-param-reassign
15
18
  props.trigger.interaction_id = props.trigger.interaction_id || getInteractionId();
16
19
  }
17
20
 
@@ -26,8 +29,6 @@ export const useWidgetInteraction = () => {
26
29
  });
27
30
  };
28
31
 
29
- const getInteractionId = () => uuid();
30
-
31
32
  return {
32
33
  trackWidgetInteraction,
33
34
  getInteractionId,
@@ -3,9 +3,9 @@ import {
3
3
  FullPageSalesAgentVariantInfo,
4
4
  HomeVariantInfo,
5
5
  OtherVariantInfo,
6
- PageVariantInfo,
7
6
  PDPPageVariantInfo,
8
7
  PLPPageVariantInfo,
8
+ PageVariantInfo,
9
9
  } from '../../contexts/pageContext/types';
10
10
  import { WidgetInteractionContext, WidgetInteractionPageType } from './types';
11
11
 
@@ -38,6 +38,8 @@ export const extractPageContext = (
38
38
  page_id: (pageVariant as FullPageSalesAgentVariantInfo).url,
39
39
  page_type: WidgetInteractionPageType.FULL_PAGE,
40
40
  };
41
+ default:
42
+ return null;
41
43
  }
42
44
 
43
45
  return null;
@@ -281,7 +281,7 @@ describe('AmplitudeService', () => {
281
281
  featureFlagService,
282
282
  });
283
283
 
284
- const logWarnSpy = vi.spyOn(Logger, 'logWarn');
284
+ const logWarnSpy = vi.spyOn(Logger.prototype, 'logWarn');
285
285
 
286
286
  await service.trackEvent({
287
287
  eventName: SpiffyMetricsEventName.ChatUserMessageInput,
@@ -304,7 +304,7 @@ describe('AmplitudeService', () => {
304
304
  throw error;
305
305
  });
306
306
 
307
- const logErrorSpy = vi.spyOn(Logger, 'logError');
307
+ const logErrorSpy = vi.spyOn(Logger.prototype, 'logError');
308
308
 
309
309
  await service.trackEvent({
310
310
  eventName: SpiffyMetricsEventName.ChatUserMessageInput,
@@ -312,7 +312,7 @@ describe('AmplitudeService', () => {
312
312
  });
313
313
 
314
314
  expect(logErrorSpy).toHaveBeenCalledWith(
315
- '[spiffy-ai] Error tracking event',
315
+ 'Error tracking event',
316
316
  error,
317
317
  expect.objectContaining({
318
318
  eventName: SpiffyMetricsEventName.ChatUserMessageInput,
@@ -17,6 +17,8 @@ import { EnviveMetricsEventName, SpiffyMetricsEventName } from './eventNames';
17
17
  // Re-export event names for convenience
18
18
  export { EnviveMetricsEventName, SpiffyMetricsEventName };
19
19
 
20
+ const logger = new Logger('amplitudeService');
21
+
20
22
  export interface TrackEventParams {
21
23
  eventName: SpiffyMetricsEventName | EnviveMetricsEventName;
22
24
  eventProps?: Record<string, unknown>;
@@ -217,7 +219,7 @@ export class AmplitudeService {
217
219
  );
218
220
 
219
221
  if (!isReady) {
220
- Logger.logDebug('AmplitudeService is not ready', {
222
+ logger.logDebug('AmplitudeService is not ready', {
221
223
  isReady,
222
224
  userId: this.config.userId,
223
225
  hasFeatureFlagService: !!this.config.featureFlagService,
@@ -351,12 +353,12 @@ export class AmplitudeService {
351
353
  eventGroups,
352
354
  alsoSendToGoogleAnalytics = false,
353
355
  }: TrackEventParams): Promise<void> {
354
- Logger.logDebug('Submitting event', eventName);
356
+ logger.logDebug('Submitting event', eventName);
355
357
  try {
356
358
  const decoratedEventName = AmplitudeService.decorateEventName(eventName);
357
359
 
358
360
  if (!this.amplitudeClient) {
359
- Logger.logWarn('amplitude client undefined', undefined, {
361
+ logger.logWarn('amplitude client undefined', undefined, {
360
362
  event_name: decoratedEventName,
361
363
  });
362
364
  return;
@@ -377,7 +379,7 @@ export class AmplitudeService {
377
379
  const hashArray = Array.from(new Uint8Array(hashBuffer));
378
380
  const currentInsertId = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
379
381
 
380
- Logger.logDebug(`amplitude tracking ${decoratedEventName}`, null, {
382
+ logger.logDebug(`amplitude tracking ${decoratedEventName}`, null, {
381
383
  event_name: decoratedEventName,
382
384
  props: mappedEventProps,
383
385
  });
@@ -404,7 +406,7 @@ export class AmplitudeService {
404
406
  };
405
407
  projectToGA4(eventName as EnviveMetricsEventName, mergedPropsForGA4);
406
408
  } else if (alsoSendToGoogleAnalytics && this.config.orgGaConfig) {
407
- Logger.logDebug('[spiffy-ai] GA tracking', decoratedEventName);
409
+ logger.logDebug('GA tracking', decoratedEventName);
408
410
  if (typeof window !== 'undefined' && window.dataLayer) {
409
411
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
410
412
  (window.dataLayer as any[]).push({
@@ -414,7 +416,7 @@ export class AmplitudeService {
414
416
  }
415
417
  }
416
418
  } catch (err) {
417
- Logger.logError('[spiffy-ai] Error tracking event', err, {
419
+ logger.logError('Error tracking event', err, {
418
420
  eventName,
419
421
  eventProps,
420
422
  });
@@ -2,6 +2,8 @@ import Logger from 'src/application/logging/logger';
2
2
  import { EnviveMetricsEventName } from '../amplitudeService/eventNames';
3
3
  import { GA4ProjectedEventConfig, GA4_EVENT_SCHEMA } from './ga4EventSchema';
4
4
 
5
+ const logger = new Logger('ga4ProjectionService');
6
+
5
7
  const filterToSchema = (
6
8
  eventProps: Record<string, unknown>,
7
9
  allowedFields: readonly string[],
@@ -130,7 +132,7 @@ export const projectToGA4 = (
130
132
  ...truncatedParams,
131
133
  });
132
134
  } catch (err) {
133
- Logger.logError('[envive-ai] Error projecting event to GA4', err, {
135
+ logger.logError('Error projecting event to GA4', err, {
134
136
  eventName,
135
137
  });
136
138
  }
@@ -4,6 +4,8 @@ import { getAtomStore } from 'src/atoms/atomStore';
4
4
  import { userIdAtom } from 'src/atoms/app';
5
5
  import { ExecutionContext } from '@envive-ai/analytics/dist/analytics/EnviveAnalytics';
6
6
 
7
+ const logger = new Logger('userIdentityService');
8
+
7
9
  type UserIdentityServiceProps = {
8
10
  apiKey: string;
9
11
  };
@@ -18,7 +20,7 @@ export class UserIdentityService {
18
20
  }
19
21
 
20
22
  getUserIdOverrideFromLocalStorage(): string | undefined {
21
- Logger.logDebug('[spiffy-ai] Getting userID from localStorage');
23
+ logger.logDebug('Getting userID from localStorage');
22
24
  return localStorage.getItem(this.USER_ID_OVERRIDE_KEY) ?? undefined;
23
25
  }
24
26
 
@@ -29,7 +31,7 @@ export class UserIdentityService {
29
31
  }
30
32
 
31
33
  try {
32
- Logger.logDebug('Getting userID via EnviveAnalytics in UserIdentityService');
34
+ logger.logDebug('Getting userID via EnviveAnalytics in UserIdentityService');
33
35
  const enviveAnalytics = new EnviveAnalytics({
34
36
  apiKey: this.apiKey,
35
37
  environmentInfo: { executionContext: ExecutionContext.EnviveReactComponentsV3 },
@@ -37,16 +39,14 @@ export class UserIdentityService {
37
39
  const enviveUserId = await enviveAnalytics.resolveEnviveUserId();
38
40
 
39
41
  if (!enviveUserId) {
40
- throw new Error(
41
- '[spiffy-ai] EnviveAnalytics.resolveEnviveUserId() returned null/undefined',
42
- );
42
+ throw new Error('EnviveAnalytics.resolveEnviveUserId() returned null/undefined');
43
43
  }
44
44
 
45
45
  return enviveUserId;
46
46
  } catch (error: unknown) {
47
- Logger.logError('[spiffy-ai] CRITICAL: Failed to get user ID:', error);
47
+ logger.logError('CRITICAL: Failed to get user ID:', error);
48
48
  const errorMessage = error instanceof Error ? error.message : 'Unknown error';
49
- throw new Error(`[spiffy-ai] CRITICAL: User ID resolution failed: ${errorMessage}`);
49
+ throw new Error(`CRITICAL: User ID resolution failed: ${errorMessage}`);
50
50
  }
51
51
  }
52
52
 
@@ -57,7 +57,7 @@ export class UserIdentityService {
57
57
  const store = atomStore || getAtomStore();
58
58
  store.set(userIdAtom, userId);
59
59
  } catch (error) {
60
- Logger.logError('[spiffy-ai] CRITICAL: Failed to initialize user ID:', error);
60
+ logger.logError('CRITICAL: Failed to initialize user ID:', error);
61
61
  throw error;
62
62
  }
63
63
  }