@envive-ai/react-hooks 0.3.0 → 0.3.2

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 (264) hide show
  1. package/dist/application/commerce-api.cjs +4 -4
  2. package/dist/application/commerce-api.js +4 -4
  3. package/dist/application/models/api/response.d.cts +1 -1
  4. package/dist/application/models/api/response.d.ts +1 -1
  5. package/dist/application/models/frontendConfig.d.cts +1 -1
  6. package/dist/application/models/frontendConfig.d.ts +1 -1
  7. package/dist/application/models/guards/api/isApiFormResponse.cjs +1 -1
  8. package/dist/application/models/guards/api/isApiFormResponse.js +1 -1
  9. package/dist/application/models/guards/api/isApiFormSubmittedResponseAttributes.cjs +1 -1
  10. package/dist/application/models/guards/api/isApiFormSubmittedResponseAttributes.js +1 -1
  11. package/dist/application/models/guards/api/isApiOrderResponseAttributes.cjs +2 -2
  12. package/dist/application/models/guards/api/isApiOrderResponseAttributes.js +2 -2
  13. package/dist/application/models/guards/api/isApiProductResponseAttributes.cjs +1 -1
  14. package/dist/application/models/guards/api/isApiProductResponseAttributes.js +1 -1
  15. package/dist/application/models/guards/api/isApiResponse.cjs +1 -1
  16. package/dist/application/models/guards/api/isApiResponse.js +1 -1
  17. package/dist/application/models/guards/api/isApiSearchEventAttributes.cjs +2 -2
  18. package/dist/application/models/guards/api/isApiSearchEventAttributes.js +2 -2
  19. package/dist/application/models/message.cjs +1 -1
  20. package/dist/application/models/message.d.cts +1 -1
  21. package/dist/application/models/message.d.ts +1 -1
  22. package/dist/application/models/message.js +1 -1
  23. package/dist/application/models/validators/validateGraphQLColorsConfig.cjs +2 -1
  24. package/dist/application/models/validators/validateGraphQLColorsConfig.js +2 -1
  25. package/dist/application/models/validators/validateGraphQLFrontendConfig.cjs +1 -1
  26. package/dist/application/models/validators/validateGraphQLFrontendConfig.d.cts +1 -1
  27. package/dist/application/models/validators/validateGraphQLFrontendConfig.d.ts +1 -1
  28. package/dist/application/models/validators/validateGraphQLFrontendConfig.js +1 -1
  29. package/dist/application/utils/analyticsUtils.cjs +2 -2
  30. package/dist/application/utils/analyticsUtils.js +2 -2
  31. package/dist/application/utils/domObserver.cjs +1 -1
  32. package/dist/application/utils/domObserver.js +1 -1
  33. package/dist/application/utils/elementObserver.cjs +1 -1
  34. package/dist/application/utils/elementObserver.d.cts +2 -2
  35. package/dist/application/utils/elementObserver.js +1 -1
  36. package/dist/application/utils/mutationHelper.cjs +2 -2
  37. package/dist/application/utils/mutationHelper.js +2 -2
  38. package/dist/application/utils/nodeSelector.cjs +5 -2
  39. package/dist/application/utils/nodeSelector.js +5 -2
  40. package/dist/application/utils/stringUtils.cjs +1 -1
  41. package/dist/application/utils/stringUtils.js +1 -1
  42. package/dist/atoms/app/index.cjs +1 -1
  43. package/dist/atoms/app/index.d.cts +1 -1
  44. package/dist/atoms/app/index.js +1 -1
  45. package/dist/atoms/app/variant.cjs +1 -1
  46. package/dist/atoms/app/variant.d.cts +3 -3
  47. package/dist/atoms/app/variant.d.ts +3 -3
  48. package/dist/atoms/app/variant.js +1 -1
  49. package/dist/atoms/chat/chatState.d.cts +15 -15
  50. package/dist/atoms/chat/chatState.d.ts +15 -15
  51. package/dist/atoms/chat/form.d.cts +2 -2
  52. package/dist/atoms/chat/form.d.ts +2 -2
  53. package/dist/atoms/chat/index.cjs +1 -1
  54. package/dist/atoms/chat/index.d.cts +3 -3
  55. package/dist/atoms/chat/index.d.ts +2 -2
  56. package/dist/atoms/chat/index.js +1 -1
  57. package/dist/atoms/chat/lastMessage.d.cts +2 -2
  58. package/dist/atoms/chat/lastMessage.d.ts +2 -2
  59. package/dist/atoms/chat/messageQueue.cjs +1 -1
  60. package/dist/atoms/chat/messageQueue.js +1 -1
  61. package/dist/atoms/chat/performanceMetrics.d.cts +6 -6
  62. package/dist/atoms/chat/performanceMetrics.d.ts +6 -6
  63. package/dist/atoms/chat/renderedWidgetRefs.d.cts +2 -2
  64. package/dist/atoms/chat/renderedWidgetRefs.d.ts +2 -2
  65. package/dist/atoms/chat/replies.cjs +2 -2
  66. package/dist/atoms/chat/replies.d.cts +2 -2
  67. package/dist/atoms/chat/replies.d.ts +2 -2
  68. package/dist/atoms/chat/replies.js +2 -2
  69. package/dist/atoms/chat/suggestions.d.cts +2 -2
  70. package/dist/atoms/chat/suggestions.d.ts +2 -2
  71. package/dist/atoms/globalSearch/globalSearch.cjs +3 -1
  72. package/dist/atoms/globalSearch/globalSearch.d.cts +10 -7
  73. package/dist/atoms/globalSearch/globalSearch.d.ts +10 -7
  74. package/dist/atoms/globalSearch/globalSearch.js +3 -2
  75. package/dist/atoms/globalSearch/index.cjs +1 -0
  76. package/dist/atoms/globalSearch/index.d.cts +2 -2
  77. package/dist/atoms/globalSearch/index.d.ts +2 -2
  78. package/dist/atoms/globalSearch/index.js +2 -2
  79. package/dist/atoms/org/customerService.d.cts +7 -7
  80. package/dist/atoms/org/graphqlConfig.cjs +1 -1
  81. package/dist/atoms/org/graphqlConfig.d.cts +6 -6
  82. package/dist/atoms/org/graphqlConfig.d.ts +5 -5
  83. package/dist/atoms/org/graphqlConfig.js +1 -1
  84. package/dist/atoms/org/newOrgConfigAtom.d.cts +2 -2
  85. package/dist/atoms/org/newOrgConfigAtom.d.ts +2 -2
  86. package/dist/atoms/org/orgAnalyticsConfig.cjs +1 -1
  87. package/dist/atoms/org/orgAnalyticsConfig.d.cts +6 -6
  88. package/dist/atoms/org/orgAnalyticsConfig.d.ts +6 -6
  89. package/dist/atoms/org/orgAnalyticsConfig.js +1 -1
  90. package/dist/atoms/search/chatSearch.d.cts +17 -17
  91. package/dist/atoms/search/chatSearch.d.ts +17 -17
  92. package/dist/atoms/search/searchAPI.cjs +1 -1
  93. package/dist/atoms/search/searchAPI.d.cts +14 -14
  94. package/dist/atoms/search/searchAPI.d.ts +14 -14
  95. package/dist/atoms/search/searchAPI.js +1 -1
  96. package/dist/atoms/search/searchServiceAdapter.cjs +1 -1
  97. package/dist/atoms/search/searchServiceAdapter.js +1 -1
  98. package/dist/atoms/search/types.d.cts +1 -1
  99. package/dist/contexts/amplitudeContext/amplitudeContext.cjs +6 -6
  100. package/dist/contexts/amplitudeContext/amplitudeContext.js +6 -6
  101. package/dist/contexts/cdnContext/cdnContext.cjs +1 -1
  102. package/dist/contexts/cdnContext/cdnContext.js +1 -1
  103. package/dist/contexts/chatContext/chatContext.cjs +4 -4
  104. package/dist/contexts/chatContext/chatContext.d.cts +2 -2
  105. package/dist/contexts/chatContext/chatContext.js +4 -4
  106. package/dist/contexts/enviveConfigContext/enviveConfigContext.cjs +2 -3
  107. package/dist/contexts/enviveConfigContext/enviveConfigContext.js +2 -3
  108. package/dist/contexts/enviveContext/enviveContext.cjs +52 -0
  109. package/dist/contexts/enviveContext/enviveContext.d.cts +31 -0
  110. package/dist/contexts/enviveContext/enviveContext.d.ts +31 -0
  111. package/dist/contexts/enviveContext/enviveContext.js +51 -0
  112. package/dist/contexts/enviveContext/index.cjs +5 -0
  113. package/dist/contexts/enviveContext/index.d.cts +3 -0
  114. package/dist/contexts/enviveContext/index.d.ts +3 -0
  115. package/dist/contexts/enviveContext/index.js +4 -0
  116. package/dist/contexts/enviveContext/types.cjs +11 -0
  117. package/dist/contexts/enviveContext/types.d.cts +8 -0
  118. package/dist/contexts/enviveContext/types.d.ts +8 -0
  119. package/dist/contexts/enviveContext/types.js +10 -0
  120. package/dist/contexts/featureFlagContext/featureFlagContext.cjs +2 -2
  121. package/dist/contexts/featureFlagContext/featureFlagContext.js +2 -2
  122. package/dist/contexts/featureFlagServiceContext/featureFlagServiceContext.cjs +2 -2
  123. package/dist/contexts/featureFlagServiceContext/featureFlagServiceContext.js +2 -2
  124. package/dist/contexts/graphqlContext/graphqlContext.cjs +3 -3
  125. package/dist/contexts/graphqlContext/graphqlContext.js +3 -3
  126. package/dist/contexts/localStorageContext/localStorageContext.cjs +1 -1
  127. package/dist/contexts/localStorageContext/localStorageContext.js +1 -1
  128. package/dist/contexts/newOrgConfigContext/newOrgConfigContext.cjs +1 -1
  129. package/dist/contexts/newOrgConfigContext/newOrgConfigContext.js +1 -1
  130. package/dist/contexts/searchContext/searchContext.cjs +1 -1
  131. package/dist/contexts/searchContext/searchContext.js +1 -1
  132. package/dist/contexts/sessionStorageContext/sessionStorageContext.cjs +1 -1
  133. package/dist/contexts/sessionStorageContext/sessionStorageContext.js +1 -1
  134. package/dist/contexts/systemSettingsContext/systemSettingsContext.d.cts +2 -2
  135. package/dist/contexts/systemSettingsContext/systemSettingsContext.d.ts +2 -2
  136. package/dist/contexts/types.cjs +1 -1
  137. package/dist/contexts/types.d.cts +1 -1
  138. package/dist/contexts/types.d.ts +1 -1
  139. package/dist/contexts/types.js +1 -1
  140. package/dist/contexts/userIdentityContext/userIdentityContext.cjs +1 -1
  141. package/dist/contexts/userIdentityContext/userIdentityContext.js +1 -1
  142. package/dist/events/index.cjs +2 -4
  143. package/dist/events/index.js +2 -4
  144. package/dist/hooks/AmplitudeOperations/useAmplitudeOperations.cjs +1 -1
  145. package/dist/hooks/AmplitudeOperations/useAmplitudeOperations.js +1 -1
  146. package/dist/hooks/Debounce/useDebounce.cjs +1 -1
  147. package/dist/hooks/Debounce/useDebounce.js +1 -1
  148. package/dist/hooks/ElementObserver/useElementObserver.cjs +2 -2
  149. package/dist/hooks/ElementObserver/useElementObserver.js +2 -2
  150. package/dist/hooks/GrabAndScroll/useGrabAndScroll.d.cts +2 -2
  151. package/dist/hooks/GrabAndScroll/useGrabAndScroll.d.ts +2 -2
  152. package/dist/hooks/IdentifyUser/useIdentifyUser.cjs +1 -1
  153. package/dist/hooks/IdentifyUser/useIdentifyUser.js +1 -1
  154. package/dist/hooks/ImageResolver/useImageResolver.cjs +2 -2
  155. package/dist/hooks/ImageResolver/useImageResolver.js +2 -2
  156. package/dist/hooks/IsSmallScreen/useIsSmallScreen.cjs +1 -1
  157. package/dist/hooks/IsSmallScreen/useIsSmallScreen.js +1 -1
  158. package/dist/hooks/LocalStorageOperations/useLocalStorageOperations.cjs +11 -3
  159. package/dist/hooks/LocalStorageOperations/useLocalStorageOperations.js +11 -3
  160. package/dist/hooks/Search/useRecommendedProducts.cjs +1 -1
  161. package/dist/hooks/Search/useRecommendedProducts.js +1 -1
  162. package/dist/hooks/Search/useSearch.cjs +6 -3
  163. package/dist/hooks/Search/useSearch.d.cts +3 -1
  164. package/dist/hooks/Search/useSearch.d.ts +3 -1
  165. package/dist/hooks/Search/useSearch.js +7 -4
  166. package/dist/hooks/Search/useSearchInput.cjs +1 -1
  167. package/dist/hooks/Search/useSearchInput.js +1 -1
  168. package/dist/hooks/SearchOperations/useSearchOperations.cjs +1 -1
  169. package/dist/hooks/SearchOperations/useSearchOperations.d.cts +1 -1
  170. package/dist/hooks/SearchOperations/useSearchOperations.d.ts +1 -1
  171. package/dist/hooks/SearchOperations/useSearchOperations.js +1 -1
  172. package/dist/hooks/SessionStorageOperations/useSessionStorageOperations.cjs +1 -1
  173. package/dist/hooks/SessionStorageOperations/useSessionStorageOperations.js +1 -1
  174. package/dist/hooks/SystemSettingsContext/useSystemSettingsContext.d.cts +2 -2
  175. package/dist/hooks/SystemSettingsContext/useSystemSettingsContext.d.ts +2 -2
  176. package/dist/hooks/TrackComponentVisibleEvent/useTrackComponentVisibleEvent.cjs +1 -1
  177. package/dist/hooks/TrackComponentVisibleEvent/useTrackComponentVisibleEvent.js +1 -1
  178. package/dist/hooks/utils.cjs +3 -3
  179. package/dist/hooks/utils.d.cts +1 -1
  180. package/dist/hooks/utils.d.ts +1 -1
  181. package/dist/hooks/utils.js +3 -3
  182. package/package.json +25 -6
  183. package/src/application/commerce-api.ts +12 -10
  184. package/src/application/models/api/nextMessageRequest.ts +2 -0
  185. package/src/application/models/api/response.ts +4 -4
  186. package/src/application/models/api/search.ts +1 -2
  187. package/src/application/models/api/userEvent.ts +1 -2
  188. package/src/application/models/frontendConfig.ts +2 -2
  189. package/src/application/models/guards/api/isApiOrderResponseAttributes.ts +8 -4
  190. package/src/application/models/guards/api/isApiSearchEventAttributes.ts +1 -1
  191. package/src/application/models/index.ts +1 -0
  192. package/src/application/models/message.ts +5 -5
  193. package/src/application/models/utilityTypes/delimiterCase.ts +1 -0
  194. package/src/application/models/validators/validateGraphQLColorsConfig.ts +2 -1
  195. package/src/application/models/validators/validateGraphQLFrontendConfig.ts +1 -1
  196. package/src/application/models/variantInfo/variantInfo.ts +3 -0
  197. package/src/application/utils/analyticsUtils.ts +3 -3
  198. package/src/application/utils/domObserver.ts +1 -0
  199. package/src/application/utils/elementObserver.ts +1 -0
  200. package/src/application/utils/mutationHelper.ts +3 -1
  201. package/src/application/utils/nodeSelector.ts +7 -1
  202. package/src/application/utils/stringUtils.ts +1 -0
  203. package/src/atoms/app/index.ts +17 -6
  204. package/src/atoms/app/variant.ts +11 -13
  205. package/src/atoms/chat/__tests__/messageQueue.test.spec.ts +61 -0
  206. package/src/atoms/chat/index.ts +8 -8
  207. package/src/atoms/chat/messageQueue.ts +2 -48
  208. package/src/atoms/chat/replies.ts +3 -3
  209. package/src/atoms/org/graphqlConfig.ts +0 -1
  210. package/src/atoms/org/orgAnalyticsConfig.ts +1 -1
  211. package/src/atoms/search/searchAPI.ts +1 -1
  212. package/src/atoms/search/searchServiceAdapter.ts +1 -1
  213. package/src/contexts/amplitudeContext/__tests__/amplitudeContext.test.tsx +4 -3
  214. package/src/contexts/amplitudeContext/amplitudeContext.tsx +5 -5
  215. package/src/contexts/cdnContext/cdnContext.tsx +1 -1
  216. package/src/contexts/enviveConfigContext/__tests__/enviveConfigContext.test.tsx +2 -3
  217. package/src/contexts/enviveConfigContext/enviveConfigContext.tsx +3 -3
  218. package/src/contexts/enviveContext/enviveContext.tsx +89 -0
  219. package/src/contexts/enviveContext/index.ts +2 -0
  220. package/src/contexts/enviveContext/types.ts +4 -0
  221. package/src/contexts/featureFlagContext/featureFlagContext.tsx +1 -1
  222. package/src/contexts/featureFlagServiceContext/featureFlagServiceContext.tsx +1 -1
  223. package/src/contexts/graphqlContext/__tests__/graphqlContext.test.tsx +7 -5
  224. package/src/contexts/graphqlContext/graphqlContext.tsx +1 -5
  225. package/src/contexts/hardcopyContext/hardcopyContext.tsx +70 -0
  226. package/src/contexts/hardcopyContext/index.ts +1 -0
  227. package/src/contexts/localStorageContext/__tests__/localStorageContext.test.tsx +9 -3
  228. package/src/contexts/localStorageContext/localStorageContext.tsx +1 -1
  229. package/src/contexts/newOrgConfigContext/__tests__/newOrgConfigContext.test.tsx +2 -3
  230. package/src/contexts/newOrgConfigContext/newOrgConfigContext.tsx +1 -1
  231. package/src/contexts/pageContext/__tests__/pageContext.test.tsx +666 -0
  232. package/src/contexts/pageContext/index.ts +2 -0
  233. package/src/contexts/pageContext/mapping.ts +38 -0
  234. package/src/contexts/pageContext/pageContext.tsx +78 -0
  235. package/src/contexts/pageContext/types.ts +27 -0
  236. package/src/contexts/salesAgentContext/chatAPI.ts +75 -0
  237. package/src/contexts/salesAgentContext/index.ts +3 -0
  238. package/src/contexts/salesAgentContext/salesAgentContext.tsx +128 -0
  239. package/src/contexts/salesAgentContext/salesAgentService.ts +197 -0
  240. package/src/contexts/searchContext/__tests__/searchContext.test.tsx +14 -15
  241. package/src/contexts/searchContext/searchContext.tsx +1 -1
  242. package/src/contexts/sessionStorageContext/sessionStorageContext.tsx +1 -1
  243. package/src/contexts/systemSettingsContext/__tests__/systemSettingsContext.test.tsx +7 -6
  244. package/src/contexts/types.ts +20 -22
  245. package/src/contexts/userIdentityContext/__tests__/userIdentityContext.test.tsx +3 -8
  246. package/src/contexts/userIdentityContext/userIdentityContext.tsx +1 -1
  247. package/src/events/index.ts +5 -7
  248. package/src/hooks/AmplitudeOperations/useAmplitudeOperations.ts +1 -1
  249. package/src/hooks/Debounce/useDebounce.ts +1 -1
  250. package/src/hooks/ElementObserver/useElementObserver.ts +2 -1
  251. package/src/hooks/GraphQLConfig/useGraphQLConfig.ts +4 -2
  252. package/src/hooks/IdentifyUser/useIdentifyUser.ts +1 -1
  253. package/src/hooks/ImageResolver/useImageResolver.ts +2 -0
  254. package/src/hooks/IsSmallScreen/useIsSmallScreen.ts +1 -1
  255. package/src/hooks/LocalStorageOperations/useLocalStorageOperations.ts +20 -4
  256. package/src/hooks/Search/__tests__/useSearch.test.tsx +15 -10
  257. package/src/hooks/Search/useRecommendedProducts.ts +2 -2
  258. package/src/hooks/Search/useSearchInput.ts +1 -1
  259. package/src/hooks/SearchOperations/useSearchOperations.ts +2 -2
  260. package/src/hooks/SessionStorageOperations/useSessionStorageOperations.ts +1 -1
  261. package/src/hooks/TrackComponentVisibleEvent/useTrackComponentVisibleEvent.ts +2 -2
  262. package/src/hooks/utils.ts +3 -2
  263. package/src/contexts/chatContext/chatContext.tsx +0 -463
  264. package/src/contexts/chatContext/index.ts +0 -1
@@ -2,13 +2,11 @@ import { ContextEnvEnum, ContextSourceEnum } from '@spiffy-ai/commerce-api-clien
2
2
  import { atom } from 'jotai';
3
3
  import { atomWithStorage } from 'jotai/utils';
4
4
  import { VariantInfo } from 'src/application/models';
5
- import {
6
- UserIdentityContextType,
7
- useUserIdentity,
8
- } from 'src/contexts/userIdentityContext/userIdentityContext';
9
- import { variantInfoAtom } from 'src/atoms/app/variant';
5
+ import { UserIdentityContextType } from 'src/contexts/userIdentityContext/userIdentityContext';
10
6
  import { v4 as uuid } from 'uuid';
11
- import { contextSourceAtom } from '../envive/enviveConfig';
7
+ import { contextSourceAtom, envAtom, orgShortNameAtom } from '../envive/enviveConfig';
8
+ import { orgIdAtom } from '../org/graphqlConfig';
9
+ import { variantInfoAtom } from './variant';
12
10
 
13
11
  export interface AppDetails {
14
12
  orgId: string;
@@ -49,3 +47,16 @@ export const appSourceAtom = atom<ContextSourceEnum>(
49
47
  export const chatIdAtom = atomWithStorage<string>('v1-spiffy-chat-session-id', uuid(), undefined, {
50
48
  getOnInit: true,
51
49
  });
50
+
51
+ export const appDetailsAtom = atom(
52
+ (get): AppDetails => ({
53
+ orgId: get(orgIdAtom) ?? '',
54
+ // TODO: orgShortName should be available when this atom is created
55
+ orgShortName: get(orgShortNameAtom) ?? 'spiffy-ai',
56
+ chatId: get(chatIdAtom),
57
+ userId: get(userIdAtom),
58
+ source: get(appSourceAtom),
59
+ env: get(envAtom) as ContextEnvEnum,
60
+ variantInfo: get(variantInfoAtom),
61
+ }),
62
+ );
@@ -1,20 +1,23 @@
1
1
  import { atomWithStorage } from 'jotai/utils';
2
2
  import { atom } from 'jotai';
3
- import { SupportedEventResponse, PageVisitCategory } from '@spiffy-ai/commerce-api-client';
4
3
  import {
5
- PageVisitVariantInfo,
4
+ PageVisitCategory,
5
+ SupportedEventResponse,
6
+ UserEvent,
7
+ } from '@spiffy-ai/commerce-api-client';
8
+ import {
6
9
  PDPVariantInfo,
7
10
  PLPVariantInfo,
11
+ PageVisitVariantInfo,
8
12
  VariantInfo,
9
13
  VariantTypeEnum,
10
14
  } from 'src/application/models';
11
15
  import { sessionStorageUtil } from 'src/atoms/atomStore';
12
16
 
13
- export interface SupportedEvent
14
- extends Pick<
15
- SupportedEventResponse,
16
- 'supported' | 'ready' | 'category' | 'collections' | 'top_category'
17
- > {
17
+ export interface SupportedEvent extends Pick<
18
+ SupportedEventResponse,
19
+ 'supported' | 'ready' | 'category' | 'collections' | 'top_category'
20
+ > {
18
21
  numberOfReviews: number | undefined;
19
22
  merchant_tags?: string[];
20
23
  }
@@ -88,12 +91,7 @@ export interface UrlResolverResponse {
88
91
  variant_type: string;
89
92
  specific_details: UrlResolvingPDPConfig | UrlResolvingPLPConfig | UrlResolvingGenericConfig;
90
93
  ready: boolean;
91
- user_event?: {
92
- event_id?: string;
93
- attributes?: PDPAttributes | PLPAttributes;
94
- category?: string;
95
- created_at?: string;
96
- };
94
+ user_event?: UserEvent;
97
95
  page_variant?: BackendPageVariantConfig;
98
96
  }
99
97
 
@@ -0,0 +1,61 @@
1
+ import { UserEventCategory } from '@spiffy-ai/commerce-api-client';
2
+ import { createStore } from 'jotai';
3
+ import { UserEvent } from 'src/application/models';
4
+ import {
5
+ clearUserEventAtom,
6
+ processUserEventAtom,
7
+ queueUserEventAtom,
8
+ userEventQueueAtom,
9
+ userQueueEventCountAtom,
10
+ } from 'src/atoms/chat/messageQueue';
11
+
12
+ const userEvent1 = {
13
+ eventId: '123',
14
+ category: UserEventCategory.AppLoaded,
15
+ createdAt: 'now',
16
+ } satisfies UserEvent;
17
+ const userEvent2 = {
18
+ eventId: '456',
19
+ category: UserEventCategory.AppLoaded,
20
+ createdAt: 'now',
21
+ } satisfies UserEvent;
22
+
23
+ describe('eventQueue', () => {
24
+ it('should be able to enqueue items and show them in the queue', () => {
25
+ const store = createStore();
26
+ store.set(queueUserEventAtom, userEvent1);
27
+ expect(store.get(userEventQueueAtom)).toEqual([userEvent1]);
28
+ expect(store.get(userQueueEventCountAtom)).toBe(1);
29
+ });
30
+ it('should be able to mark eventQueue items as processed and remove them from the queue', () => {
31
+ const store = createStore();
32
+ store.set(queueUserEventAtom, userEvent1);
33
+ store.set(queueUserEventAtom, userEvent2);
34
+ expect(store.get(userEventQueueAtom)).toEqual([userEvent1, userEvent2]);
35
+ expect(store.get(userQueueEventCountAtom)).toBe(2);
36
+ store.set(processUserEventAtom, ['123']);
37
+ expect(store.get(userEventQueueAtom)).toEqual([userEvent2]);
38
+ expect(store.get(userQueueEventCountAtom)).toBe(1);
39
+ });
40
+ it('should be able to mark non-existent eventQueue items as procesed without an exception being raised', () => {
41
+ const store = createStore();
42
+ store.set(queueUserEventAtom, userEvent1);
43
+ store.set(queueUserEventAtom, userEvent2);
44
+ expect(store.get(userEventQueueAtom)).toEqual([userEvent1, userEvent2]);
45
+ expect(store.get(userQueueEventCountAtom)).toBe(2);
46
+ store.set(processUserEventAtom, ['foo']);
47
+ expect(store.get(userEventQueueAtom)).toEqual([userEvent1, userEvent2]);
48
+ expect(store.get(userQueueEventCountAtom)).toBe(2);
49
+ });
50
+ it('should be able to clear all eventQueue items', () => {
51
+ const store = createStore();
52
+ expect(store.get(userQueueEventCountAtom)).toBe(0);
53
+ store.set(queueUserEventAtom, userEvent1);
54
+ store.set(queueUserEventAtom, userEvent2);
55
+ expect(store.get(userEventQueueAtom)).toEqual([userEvent1, userEvent2]);
56
+ expect(store.get(userQueueEventCountAtom)).toBe(2);
57
+ store.set(clearUserEventAtom);
58
+ expect(store.get(userEventQueueAtom)).toEqual([]);
59
+ expect(store.get(userQueueEventCountAtom)).toBe(0);
60
+ });
61
+ });
@@ -1,17 +1,17 @@
1
1
  import { atom } from 'jotai';
2
2
  import {
3
- responseStreamingAtom,
4
- suggestionsLoadingAtom,
5
- messagesAtom,
6
- userQueryAtom,
7
- replyEventCategoryAtom,
8
- userHasRepliedAtom,
9
3
  askQuestionBtnClickedAtom,
10
- suggestionsAtom,
11
4
  chatIsOpenAtom,
12
5
  chatOnToggleAtom,
13
- userEventsAtom,
6
+ messagesAtom,
7
+ replyEventCategoryAtom,
8
+ responseStreamingAtom,
14
9
  suggestionAtom,
10
+ suggestionsAtom,
11
+ suggestionsLoadingAtom,
12
+ userEventsAtom,
13
+ userHasRepliedAtom,
14
+ userQueryAtom,
15
15
  } from './chatState';
16
16
 
17
17
  export * from './chatState';
@@ -1,10 +1,5 @@
1
1
  import { atom } from 'jotai';
2
- import { v4 as uuid } from 'uuid';
3
- import { GenerationParams, NextMessageRequest, UserEvent } from 'src/application/models';
4
- import { getAtomStore } from 'src/atoms/atomStore/atomStore';
5
- import { userIdAtom, chatIdAtom } from 'src/atoms/app';
6
- import { orgShortNameAtom, contextSourceAtom, envAtom } from 'src/atoms/envive/enviveConfig';
7
- import { orgIdAtom, featureFlagServiceAtom } from 'src/atoms/org/graphqlConfig';
2
+ import { UserEvent } from 'src/application/models';
8
3
 
9
4
  const internalUserEventQueueAtom = atom<UserEvent[]>([]);
10
5
 
@@ -43,46 +38,5 @@ export const processUserEventAtom = atom(null, (get, set, eventIds: string[]) =>
43
38
  set(internalUserEventQueueAtom, remaining);
44
39
  });
45
40
 
46
- export const userQueueEventCountAtom = atom(get => get(userEventQueueAtom).length);
47
-
48
- import { ContextSourceEnum, ContextEnvEnum } from '@spiffy-ai/commerce-api-client'; // Import necessary enums
41
+ export const userQueueEventCountAtom = atom(get => get(userEventQueueAtom).length); // Import necessary enums
49
42
  // import type { Context } from "@spiffy-ai/commerce-api-client/dist/models/Context"; // Import Context type
50
-
51
- export const createResponsePayload = ({
52
- userEvents,
53
- generationParams,
54
- }: {
55
- userEvents: UserEvent[];
56
- generationParams?: GenerationParams;
57
- }): NextMessageRequest => {
58
- const atomStore = getAtomStore();
59
- const orgShortName = atomStore.get(orgShortNameAtom);
60
- const orgId = atomStore.get(orgIdAtom);
61
- const userId = atomStore.get(userIdAtom);
62
- const chatId = atomStore.get(chatIdAtom);
63
- const source = atomStore.get(contextSourceAtom);
64
- const env = atomStore.get(envAtom);
65
-
66
- const featureFlagService = atomStore.get(featureFlagServiceAtom);
67
-
68
- const context = {
69
- userId: userId ?? '',
70
- org_id: orgId ?? '',
71
- org_short_name: orgShortName ?? '',
72
- chat_id: chatId ?? '',
73
- source: source ?? ContextSourceEnum.App,
74
- env: (env as ContextEnvEnum) ?? ContextEnvEnum.Dev,
75
- };
76
-
77
- const featureFlags = featureFlagService?.featureFlagService?.getFeatureFlags() || {};
78
-
79
- return {
80
- id: uuid(),
81
- context,
82
- userEvents,
83
- featureFlags: Object.fromEntries(
84
- Object.entries(featureFlags).filter(([, isEnabled]) => isEnabled),
85
- ), // Convert back to Record<string, boolean>
86
- generationParams,
87
- };
88
- };
@@ -1,15 +1,15 @@
1
1
  import { atom } from 'jotai';
2
2
  import { Message, MessageType } from 'src/application/models';
3
3
  import {
4
- userHasRepliedAtom,
5
4
  messagesAtom,
6
- userQueryAtom,
7
5
  replyEventCategoryAtom,
6
+ userHasRepliedAtom,
7
+ userQueryAtom,
8
8
  } from 'src/atoms/chat';
9
9
  import { UserEventCategory } from '@spiffy-ai/commerce-api-client';
10
- import { queueUserEventAtom } from './messageQueue';
11
10
  import { SpiffyMetricsEventName } from 'src/contexts/amplitudeContext/amplitudeContext';
12
11
  import { amplitudeTrackEventAtom } from 'src/atoms/amplitude/amplitudeTrackEventAtom';
12
+ import { queueUserEventAtom } from './messageQueue';
13
13
 
14
14
  type HandleReplyParams = {
15
15
  message: Message;
@@ -1,7 +1,6 @@
1
1
  import { atom } from 'jotai';
2
2
  import { ColorMapping } from 'src/application/models/colorsConfig';
3
3
  import { FrontendConfig } from 'src/application/models/frontendConfig';
4
- import { orgShortNameAtom } from '../envive/enviveConfig';
5
4
  import { FeatureFlagContextType } from 'src/contexts/featureFlagServiceContext/featureFlagServiceContext'; // Import FeatureFlagContextType from new context
6
5
 
7
6
  export const internalGraphQLColorsConfigAtom = atom<ColorMapping | undefined>(undefined);
@@ -1,7 +1,7 @@
1
1
  import { atom } from 'jotai';
2
2
  import {
3
- OrgAnalyticsConfig,
4
3
  OrgAnalyticsAmplitudeConfig,
4
+ OrgAnalyticsConfig,
5
5
  OrgAnalyticsCustomerServiceConfig,
6
6
  OrgAnalyticsGoogleAnalyticsConfig,
7
7
  } from 'src/application/models/api/orgAnalyticsConfig';
@@ -1,5 +1,5 @@
1
1
  import { atom } from 'jotai';
2
- import { SearchResult, SearchParams } from 'src/application/models/api/search';
2
+ import { SearchParams, SearchResult } from 'src/application/models/api/search';
3
3
  import { ProductSorting } from './types';
4
4
  import { ProductFilters } from './productFilters';
5
5
  import { ProductSorter } from './productSorter';
@@ -1,4 +1,4 @@
1
- import { SearchResult, SearchParams } from 'src/application/models/api/search';
1
+ import { SearchParams, SearchResult } from 'src/application/models/api/search';
2
2
 
3
3
  // This will be set by the SearchProvider when it initializes
4
4
  let searchServiceFunction: ((params: SearchParams) => Promise<SearchResult>) | null = null;
@@ -1,7 +1,6 @@
1
1
  import React from 'react';
2
- import { render, screen, waitFor, act } from '@testing-library/react';
2
+ import { act, render, screen, waitFor } from '@testing-library/react';
3
3
  import { Provider, useStore } from 'jotai';
4
- import { AmplitudeProvider, useAmplitude, SpiffyMetricsEventName } from '../amplitudeContext';
5
4
  import {
6
5
  UserIdentityProvider,
7
6
  useUserIdentity,
@@ -11,7 +10,7 @@ import { EnviveConfigProvider } from 'src/contexts/enviveConfigContext/enviveCon
11
10
  import { FeatureFlagServiceProvider } from 'src/contexts/featureFlagServiceContext/featureFlagServiceContext';
12
11
  import { userIdAtom } from 'src/atoms/app';
13
12
  import Logger from 'src/application/logging/logger';
14
- import { createInstance } from '@amplitude/analytics-browser';
13
+ import { AmplitudeProvider, SpiffyMetricsEventName, useAmplitude } from '../amplitudeContext';
15
14
 
16
15
  // Mock the Logger to avoid console output in tests
17
16
  // vi.spyOn(Logger, "logInfo").mockImplementation(() => {});
@@ -62,6 +61,7 @@ const MockAmplitudeComponent: React.FC = () => {
62
61
  <div data-testid="is-ready">{amplitude.isReady.toString()}</div>
63
62
  <button
64
63
  data-testid="track-event-button"
64
+ type="button"
65
65
  onClick={() =>
66
66
  amplitude.trackEvent({
67
67
  eventName: SpiffyMetricsEventName.ChatUserMessageInput,
@@ -373,6 +373,7 @@ describe('AmplitudeProvider with UserIdentityContext', () => {
373
373
  return (
374
374
  <button
375
375
  data-testid="track-multiple"
376
+ type="button"
376
377
  onClick={trackMultiple}
377
378
  >
378
379
  Track Multiple
@@ -1,4 +1,4 @@
1
- import React, { createContext, useContext, useCallback, useMemo, useEffect } from 'react';
1
+ import React, { createContext, useCallback, useContext, useEffect, useMemo } from 'react';
2
2
  import { useAtomValue } from 'jotai';
3
3
  import { createInstance } from '@amplitude/analytics-browser';
4
4
  import { FeatureGates } from 'src/application/models/featureGates';
@@ -8,12 +8,12 @@ import {
8
8
  amplitudeApiKeyAtom,
9
9
  contextSourceAtom,
10
10
  dataResidencyAtom,
11
+ envAtom,
11
12
  identifyingPrefixAtom,
12
13
  } from 'src/atoms/envive/enviveConfig';
13
14
  import { LocalStorageKeys, useLocalStorage } from 'src/contexts/localStorageContext';
14
15
  import { orgAnalyticsGoogleAnalyticsConfigAtom } from 'src/atoms/org/orgAnalyticsConfig';
15
16
  import { userIdAtom } from 'src/atoms/app';
16
- import { envAtom } from 'src/atoms/envive/enviveConfig';
17
17
  import Logger from 'src/application/logging/logger';
18
18
  import type {
19
19
  BrowserClient,
@@ -162,8 +162,8 @@ export const AmplitudeProvider: React.FC<{ children: React.ReactNode }> = ({ chi
162
162
  const amplitudeSessionReplayInit = useCallback((): boolean => {
163
163
  const isEnabled = Boolean(
164
164
  orgShortName === OrgShortName.UniqueVintage &&
165
- featureFlagService?.isClientSessionEnabled() &&
166
- featureFlagService?.isFeatureGateEnabled(FeatureGates.IsNewFeatureEnabled),
165
+ featureFlagService?.isClientSessionEnabled() &&
166
+ featureFlagService?.isFeatureGateEnabled(FeatureGates.IsNewFeatureEnabled),
167
167
  );
168
168
  const sampleRate = 1;
169
169
 
@@ -358,7 +358,7 @@ export const AmplitudeProvider: React.FC<{ children: React.ReactNode }> = ({ chi
358
358
  if (window.dataLayer) {
359
359
  (window.dataLayer as any[]).push({
360
360
  event: decoratedEventName,
361
- eventProps: eventProps,
361
+ eventProps,
362
362
  });
363
363
  }
364
364
  }
@@ -1,4 +1,4 @@
1
- import React, { createContext, useContext, useCallback, useMemo } from 'react';
1
+ import React, { createContext, useCallback, useContext, useMemo } from 'react';
2
2
  import { useAtomValue } from 'jotai';
3
3
  import { cdnUrlAtom } from '../../atoms/envive/enviveConfig';
4
4
 
@@ -1,10 +1,9 @@
1
1
  import React from 'react';
2
2
  import { render, screen, waitFor } from '@testing-library/react';
3
- import { Provider } from 'jotai';
4
- import { useAtomValue } from 'jotai';
5
- import { EnviveConfigProvider, useEnviveConfig } from '../enviveConfigContext';
3
+ import { Provider, useAtomValue } from 'jotai';
6
4
  import { enviveConfigAtom } from 'src/atoms/envive/enviveConfig';
7
5
  import Logger from 'src/application/logging/logger';
6
+ import { EnviveConfigProvider, useEnviveConfig } from '../enviveConfigContext';
8
7
 
9
8
  // Mock the Logger to avoid console output in tests
10
9
  vi.spyOn(Logger, 'logDebug').mockImplementation(() => {});
@@ -1,5 +1,5 @@
1
- import React, { createContext, useContext, ReactNode, useEffect } from 'react';
2
- import { useSetAtom, useAtomValue } from 'jotai';
1
+ import React, { ReactNode, createContext, useEffect } from 'react';
2
+ import { useAtomValue, useSetAtom } from 'jotai';
3
3
  import { enviveConfigAtom } from 'src/atoms/envive/enviveConfig';
4
4
  import Logger from 'src/application/logging/logger';
5
5
  import { OrgConfigFeatureGate } from 'src/application/models/api/orgConfigResults';
@@ -82,5 +82,5 @@ export const EnviveConfigProvider: React.FC<EnviveConfigProviderProps> = ({
82
82
  export const useEnviveConfig = (): EnviveConfig => {
83
83
  const config = useAtomValue(enviveConfigAtom);
84
84
 
85
- return config ? config : {};
85
+ return config || {};
86
86
  };
@@ -0,0 +1,89 @@
1
+ import { ReactNode, createContext } from 'react';
2
+
3
+ import { OrgConfigFeatureGate } from 'src/application/models/api/orgConfigResults';
4
+ import { AmplitudeProvider } from '../amplitudeContext';
5
+ import { EnviveConfigProvider } from '../enviveConfigContext';
6
+ import { EnviveCssProvider } from '../enviveCssContext';
7
+ import { FeatureFlagServiceProvider } from '../featureFlagServiceContext';
8
+ import { GraphQLProvider } from '../graphqlContext';
9
+ import { LocalStorageProvider } from '../localStorageContext';
10
+ import { NewOrgConfigProvider } from '../newOrgConfigContext';
11
+ import { UserIdentityProvider } from '../userIdentityContext';
12
+ import { EnviveAgent } from './types';
13
+ import { SearchProvider } from '../searchContext';
14
+ import { SalesAgentProvider } from '../salesAgentContext/salesAgentContext';
15
+ import { SystemSettingsContextProvider } from '../systemSettingsContext';
16
+
17
+ const EnviveContext = createContext<null>(null);
18
+
19
+ interface AgentWrapperProps {
20
+ children: ReactNode;
21
+ enabledAgents: EnviveAgent[];
22
+ }
23
+
24
+ interface EnviveProviderProps extends AgentWrapperProps {
25
+ amplitudeApiKey?: string;
26
+ dataResidency?: string;
27
+ env?: string;
28
+ baseUrl?: string;
29
+ reactAppName?: string;
30
+ cdnUrl?: string;
31
+ contextSource?: string;
32
+ orgLevelApiKey?: string;
33
+ orgShortName?: string;
34
+ identifyingPrefix: string;
35
+ featureOverrides?: Record<string, boolean>;
36
+ variantUrlOverride?: string;
37
+ variantInfoOverride?: any;
38
+ show?: boolean;
39
+ publicKey?: string;
40
+ featureGates?: OrgConfigFeatureGate[]; // New prop for feature gates
41
+ }
42
+
43
+ const SearchAgentWrapper: React.FC<AgentWrapperProps> = ({ children, enabledAgents }) => {
44
+ if (!enabledAgents.includes(EnviveAgent.SearchAgent)) {
45
+ return children;
46
+ }
47
+ return <SearchProvider>{children}</SearchProvider>;
48
+ };
49
+
50
+ const SalesAgentWrapper: React.FC<AgentWrapperProps> = ({ children, enabledAgents }) => {
51
+ if (!enabledAgents.includes(EnviveAgent.SalesAgent)) {
52
+ return children;
53
+ }
54
+ return (
55
+ <SystemSettingsContextProvider>
56
+ <SalesAgentProvider>{children}</SalesAgentProvider>
57
+ </SystemSettingsContextProvider>
58
+ );
59
+ };
60
+
61
+ export const EnviveProvider: React.FC<EnviveProviderProps> = ({
62
+ children,
63
+ enabledAgents,
64
+ ...config
65
+ }) => (
66
+ <EnviveContext.Provider value={null}>
67
+ <EnviveConfigProvider {...config}>
68
+ <GraphQLProvider>
69
+ <NewOrgConfigProvider>
70
+ <LocalStorageProvider>
71
+ <FeatureFlagServiceProvider featureGates={[]}>
72
+ <UserIdentityProvider>
73
+ <AmplitudeProvider>
74
+ <EnviveCssProvider>
75
+ <SearchAgentWrapper enabledAgents={enabledAgents}>
76
+ <SalesAgentWrapper enabledAgents={enabledAgents}>
77
+ {children}
78
+ </SalesAgentWrapper>
79
+ </SearchAgentWrapper>
80
+ </EnviveCssProvider>
81
+ </AmplitudeProvider>
82
+ </UserIdentityProvider>
83
+ </FeatureFlagServiceProvider>
84
+ </LocalStorageProvider>
85
+ </NewOrgConfigProvider>
86
+ </GraphQLProvider>
87
+ </EnviveConfigProvider>
88
+ </EnviveContext.Provider>
89
+ );
@@ -0,0 +1,2 @@
1
+ export * from './enviveContext';
2
+ export * from './types';
@@ -0,0 +1,4 @@
1
+ export enum EnviveAgent {
2
+ SalesAgent = 'sales',
3
+ SearchAgent = 'search',
4
+ }
@@ -1,4 +1,4 @@
1
- import React, { createContext, useContext, useCallback, useMemo } from 'react';
1
+ import React, { createContext, useCallback, useContext, useMemo } from 'react';
2
2
  import Logger from 'src/application/logging/logger';
3
3
  import { StatsigFeatureGate } from '@spiffy-ai/commerce-api-client';
4
4
  import { FeatureGates } from 'src/application/models/featureGates';
@@ -1,4 +1,4 @@
1
- import React, { createContext, useContext, useMemo, ReactNode } from 'react';
1
+ import React, { ReactNode, createContext, useContext, useMemo } from 'react';
2
2
  import { OrgConfigFeatureGate } from 'src/application/models/api/orgConfigResults';
3
3
  import { FeatureGates } from 'src/application/models/featureGates';
4
4
  import Logger from 'src/application/logging/logger';
@@ -1,12 +1,11 @@
1
1
  import React from 'react';
2
- import { render, screen, waitFor, act } from '@testing-library/react';
3
- import { Provider } from 'jotai';
4
- import { useAtomValue } from 'jotai';
5
- import { GraphQLProvider, useGraphQLClient } from '../graphqlContext';
2
+ import { act, render, screen, waitFor } from '@testing-library/react';
3
+ import { Provider, useAtomValue } from 'jotai';
6
4
  import { EnviveConfigProvider } from 'src/contexts/enviveConfigContext/enviveConfigContext';
7
- import { orgLevelApiKeyAtom, baseUrlAtom } from 'src/atoms/envive/enviveConfig';
5
+ import { baseUrlAtom, orgLevelApiKeyAtom } from 'src/atoms/envive/enviveConfig';
8
6
  import Logger from 'src/application/logging/logger';
9
7
  import { getMerchantOrgIdQuery } from 'src/application/models/graphql/queries/getMerchantOrgIdQuery';
8
+ import { GraphQLProvider, useGraphQLClient } from '../graphqlContext';
10
9
 
11
10
  // Mock the Logger to avoid console output in tests
12
11
  vi.spyOn(Logger, 'logDebug').mockImplementation(() => {});
@@ -25,6 +24,7 @@ const MockGraphQLComponent: React.FC = () => {
25
24
  <div data-testid="is-ready">{client.isReady.toString()}</div>
26
25
  <button
27
26
  data-testid="execute-query-btn"
27
+ type="button"
28
28
  onClick={async () => {
29
29
  try {
30
30
  const result = await client.executeQuery('query { test }');
@@ -38,6 +38,7 @@ const MockGraphQLComponent: React.FC = () => {
38
38
  </button>
39
39
  <button
40
40
  data-testid="get-org-id-btn"
41
+ type="button"
41
42
  onClick={async () => {
42
43
  try {
43
44
  const orgId = await client.getOrgId();
@@ -51,6 +52,7 @@ const MockGraphQLComponent: React.FC = () => {
51
52
  </button>
52
53
  <button
53
54
  data-testid="get-config-btn"
55
+ type="button"
54
56
  onClick={async () => {
55
57
  try {
56
58
  const config = await client.getColorsAndFrontendConfig();
@@ -1,16 +1,12 @@
1
- import React, { createContext, useContext, useCallback, useMemo, ReactNode } from 'react';
1
+ import React, { ReactNode, createContext, useCallback, useContext, useMemo } from 'react';
2
2
  import { useAtomValue } from 'jotai';
3
3
  import { baseUrlAtom, orgLevelApiKeyAtom } from 'src/atoms/envive/enviveConfig';
4
4
  import { getMerchantOrgIdQuery } from 'src/application/models/graphql/queries/getMerchantOrgIdQuery';
5
5
  import { validateGraphQLOrgId } from 'src/application/models/validators/validateGraphQLOrgId';
6
6
  import {
7
- getMerchantColorsQuery,
8
7
  GetMerchantColorsQueryData,
9
- getMerchantFrontendConfigQuery,
10
8
  GetMerchantFrontendConfigQueryData,
11
9
  } from 'src/application/models/graphql';
12
- import { validateGraphQLColorsConfig } from 'src/application/models/validators/validateGraphQLColorsConfig';
13
- import { validateGraphQLFrontendConfig } from 'src/application/models/validators/validateGraphQLFrontendConfig';
14
10
  import { ColorMapping } from 'src/application/models/colorsConfig';
15
11
  import { FrontendConfig } from 'src/application/models/frontendConfig';
16
12
  import Logger from 'src/application/logging/logger';
@@ -0,0 +1,70 @@
1
+ import { UserEvent } from '@spiffy-ai/commerce-api-client';
2
+ import { ReactNode, createContext, useCallback, useContext, useMemo } from 'react';
3
+ import Logger from 'src/application/logging/logger';
4
+ import { WidgetTypeV3 } from '../types';
5
+
6
+ interface HardcopyRequest {
7
+ widgetType: WidgetTypeV3;
8
+ userEvent: UserEvent;
9
+ }
10
+
11
+ export type HardcopyResponse = {
12
+ language: string;
13
+ values: Record<string, string | string[]>;
14
+ };
15
+
16
+ interface HardcopyContextType {
17
+ getHardcopy: (HardcopyRequest: HardcopyRequest) => Promise<HardcopyResponse>;
18
+ }
19
+
20
+ // These are just sample responses for the sake of testing.
21
+ // As we start to build the actual widgets we should determine what the actual
22
+ // values and their names should be.
23
+ const MOCK_HARDCOPY_RESPONSE: Partial<Record<WidgetTypeV3, HardcopyResponse>> = {
24
+ [WidgetTypeV3.SuggestionBarV3]: {
25
+ language: 'en',
26
+ values: {
27
+ suggestionBarButtons: ['Button 1', 'Button 2', 'Button 3'],
28
+ },
29
+ },
30
+ [WidgetTypeV3.ChatPreviewV3]: {
31
+ language: 'en',
32
+ values: {
33
+ chatPreviewTitle: 'Chat Preview Title',
34
+ typewriterTextPrefix: 'Want to know',
35
+ typewriterTexts: ['more about this product?', 'what others are saying?', 'how to use it?'],
36
+ suggestionButtons: ['Button 1', 'Button 2', 'Button 3'],
37
+ footerText: 'Ask me anything...',
38
+
39
+ chatPreviewDescription: 'Chat Preview Description',
40
+ },
41
+ },
42
+ };
43
+
44
+ const HardcopyContext = createContext<HardcopyContextType | undefined>(undefined);
45
+
46
+ export const HardcopyProvider: React.FC<{ children: ReactNode }> = ({ children }) => {
47
+ const languages = useMemo(() => navigator.languages, []);
48
+
49
+ const getHardcopy = useCallback(async (request: HardcopyRequest): Promise<HardcopyResponse> => {
50
+ Logger.logInfo('hardcopyContext | retrieving hardcopy', languages);
51
+ const response = MOCK_HARDCOPY_RESPONSE[request.widgetType];
52
+ Logger.logInfo('hardcopyContext | returning hardcopy response', response);
53
+ if (!response) {
54
+ throw new Error(`No hardcopy response found for widget type: ${request.widgetType}`);
55
+ }
56
+ return response;
57
+ }, []);
58
+
59
+ const value = useMemo(() => ({ getHardcopy }), [getHardcopy]);
60
+
61
+ return <HardcopyContext.Provider value={value}>{children}</HardcopyContext.Provider>;
62
+ };
63
+
64
+ export const useHardcopy = () => {
65
+ const context = useContext(HardcopyContext);
66
+ if (!context) {
67
+ throw new Error('useHardcopy must be used within a HardcopyProvider');
68
+ }
69
+ return context;
70
+ };
@@ -0,0 +1 @@
1
+ export * from './hardcopyContext';