@envive-ai/react-hooks 0.3.15 → 0.3.17

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 (77) hide show
  1. package/dist/application/models/guards/api/isApiQueryTypedEventAttributes.cjs +2 -2
  2. package/dist/application/models/guards/api/isApiQueryTypedEventAttributes.js +2 -2
  3. package/dist/application/models/index.d.cts +1 -1
  4. package/dist/application/models/index.d.ts +1 -1
  5. package/dist/application/models/variantInfo/variantInfo.cjs +1 -1
  6. package/dist/application/models/variantInfo/variantInfo.d.cts +2 -2
  7. package/dist/application/models/variantInfo/variantInfo.d.ts +2 -2
  8. package/dist/application/models/variantInfo/variantInfo.js +1 -1
  9. package/dist/atoms/app/index.d.cts +7 -7
  10. package/dist/atoms/app/index.d.ts +1 -1
  11. package/dist/atoms/app/variant.cjs +5 -1
  12. package/dist/atoms/app/variant.d.cts +7 -7
  13. package/dist/atoms/app/variant.d.ts +1 -1
  14. package/dist/atoms/app/variant.js +5 -1
  15. package/dist/atoms/chat/chatState.d.cts +17 -17
  16. package/dist/atoms/chat/chatState.d.ts +18 -18
  17. package/dist/atoms/chat/form.d.cts +3 -3
  18. package/dist/atoms/chat/form.d.ts +2 -2
  19. package/dist/atoms/chat/index.d.cts +3 -3
  20. package/dist/atoms/chat/index.d.ts +2 -2
  21. package/dist/atoms/chat/lastMessage.d.cts +2 -2
  22. package/dist/atoms/chat/lastMessage.d.ts +2 -2
  23. package/dist/atoms/chat/messageQueue.d.cts +6 -6
  24. package/dist/atoms/chat/messageQueue.d.ts +6 -6
  25. package/dist/atoms/chat/performanceMetrics.d.cts +7 -7
  26. package/dist/atoms/chat/performanceMetrics.d.ts +6 -6
  27. package/dist/atoms/chat/renderedWidgetRefs.d.cts +2 -2
  28. package/dist/atoms/chat/renderedWidgetRefs.d.ts +2 -2
  29. package/dist/atoms/chat/replies.d.cts +1 -1
  30. package/dist/atoms/chat/replies.d.ts +2 -2
  31. package/dist/atoms/chat/suggestions.d.cts +3 -3
  32. package/dist/atoms/chat/suggestions.d.ts +2 -2
  33. package/dist/atoms/envive/enviveConfig.d.ts +13 -13
  34. package/dist/atoms/globalSearch/globalSearch.d.cts +5 -5
  35. package/dist/atoms/globalSearch/globalSearch.d.ts +5 -5
  36. package/dist/atoms/org/customerService.d.cts +6 -6
  37. package/dist/atoms/org/customerService.d.ts +6 -6
  38. package/dist/atoms/org/graphqlConfig.d.cts +4 -4
  39. package/dist/atoms/org/graphqlConfig.d.ts +4 -4
  40. package/dist/atoms/org/newOrgConfigAtom.d.cts +2 -2
  41. package/dist/atoms/org/newOrgConfigAtom.d.ts +2 -2
  42. package/dist/atoms/org/orgAnalyticsConfig.d.cts +5 -5
  43. package/dist/atoms/org/orgAnalyticsConfig.d.ts +5 -5
  44. package/dist/atoms/search/chatSearch.d.cts +17 -17
  45. package/dist/atoms/search/chatSearch.d.ts +17 -17
  46. package/dist/atoms/search/searchAPI.d.cts +13 -13
  47. package/dist/atoms/search/searchAPI.d.ts +13 -13
  48. package/dist/atoms/widget/chatPreviewLoading.d.cts +2 -2
  49. package/dist/atoms/widget/chatPreviewLoading.d.ts +2 -2
  50. package/dist/contexts/graphqlContext/mockV3Config.cjs +2 -3
  51. package/dist/contexts/graphqlContext/mockV3Config.js +2 -3
  52. package/dist/contexts/salesAgentContext/salesAgentContext.cjs +17 -4
  53. package/dist/contexts/salesAgentContext/salesAgentContext.js +18 -5
  54. package/dist/contexts/salesAgentContext/salesAgentService.cjs +8 -3
  55. package/dist/contexts/salesAgentContext/salesAgentService.js +8 -3
  56. package/dist/contexts/systemSettingsContext/systemSettingsContext.d.ts +2 -2
  57. package/dist/contexts/types.d.cts +1 -1
  58. package/dist/contexts/types.d.ts +1 -1
  59. package/dist/contexts/typesV3.cjs +1 -1
  60. package/dist/contexts/typesV3.d.cts +1 -10
  61. package/dist/contexts/typesV3.d.ts +1 -10
  62. package/dist/contexts/typesV3.js +1 -1
  63. package/dist/hooks/GrabAndScroll/useGrabAndScroll.d.cts +2 -2
  64. package/dist/hooks/GrabAndScroll/useGrabAndScroll.d.ts +2 -2
  65. package/dist/hooks/utils.d.cts +1 -1
  66. package/dist/hooks/utils.d.ts +1 -1
  67. package/dist/services/ga4ProjectionService/ga4EventSchema.cjs +2 -1
  68. package/dist/services/ga4ProjectionService/ga4EventSchema.js +2 -1
  69. package/package.json +3 -3
  70. package/src/application/models/guards/api/isApiQueryTypedEventAttributes.ts +1 -6
  71. package/src/application/models/variantInfo/variantInfo.ts +1 -1
  72. package/src/atoms/app/variant.ts +8 -2
  73. package/src/contexts/graphqlContext/mockV3Config.ts +0 -3
  74. package/src/contexts/salesAgentContext/salesAgentContext.tsx +25 -10
  75. package/src/contexts/salesAgentContext/salesAgentService.ts +22 -14
  76. package/src/contexts/typesV3.ts +0 -10
  77. package/src/services/ga4ProjectionService/ga4EventSchema.ts +1 -0
@@ -5,6 +5,7 @@ import {
5
5
  } from '@spiffy-ai/commerce-api-client';
6
6
  import { atom } from 'jotai';
7
7
  import { atomWithStorage } from 'jotai/utils';
8
+ import Logger from 'src/application/logging/logger';
8
9
  import {
9
10
  PDPVariantInfo,
10
11
  PLPVariantInfo,
@@ -15,7 +16,6 @@ import {
15
16
  } from 'src/application/models';
16
17
  import { sessionStorageUtil } from 'src/atoms/atomStore';
17
18
  import type { PageVariantInfo } from 'src/contexts/pageContext/types';
18
- import Logger from 'src/application/logging/logger';
19
19
  import { ShowFloatingButtonOptions } from 'src/contexts/types';
20
20
 
21
21
  export interface SupportedEvent extends Pick<
@@ -168,7 +168,7 @@ const internalProductUrlAtom = atom<string>();
168
168
  const internalPlpIdAtom = atom<string>();
169
169
  const internalUrlAtom = atom<string>();
170
170
  const internalPageVisitCategoryAtom = atom<PageVisitCategory>();
171
- const internalVariantAtom = atom<'pdp' | 'plp' | 'search' | 'page_visit'>('pdp');
171
+ const internalVariantAtom = atom<'pdp' | 'plp' | 'search' | 'page_visit' | 'full_page'>('pdp');
172
172
  const internalFloatingButtonOverrideAtom = atom<ShowFloatingButtonOptions>();
173
173
 
174
174
  export const variantIdAtom = atom(get => get(internalVariantIdAtom));
@@ -251,6 +251,12 @@ const getPageVisitContext = (pageVisitCategory: PageVisitCategory | undefined) =
251
251
  page_id: window.location.href,
252
252
  };
253
253
  }
254
+ if (pageVisitCategory === PageVisitCategory.FullPage) {
255
+ return {
256
+ page_type: 'full_page',
257
+ page_id: window.location.href,
258
+ };
259
+ }
254
260
  return {
255
261
  page_type: 'other',
256
262
  page_id: window.location.href,
@@ -133,9 +133,6 @@ export const mockV3FrontendConfig: FrontendConfigV3 = {
133
133
  welcomeMessageText:
134
134
  'Your personal shopper trained on the collective knowledge of thousands of real experts!',
135
135
  chatFooterTextFieldPlaceholderText: 'Ask me anything...',
136
- partialViewConfig: {
137
- disabled: true,
138
- },
139
136
  },
140
137
  customerServiceIntegration: {
141
138
  provider: CustomerServiceType.unsupported,
@@ -1,6 +1,6 @@
1
1
  import { UserEventCategory } from '@spiffy-ai/commerce-api-client';
2
2
  import { useAtom, useAtomValue, useSetAtom } from 'jotai';
3
- import { ReactNode, createContext, useCallback, useEffect, useMemo, useRef } from 'react';
3
+ import { ReactNode, createContext, useCallback, useEffect, useMemo, useRef, useState } from 'react';
4
4
  import Logger from 'src/application/logging/logger';
5
5
  import { NextMessageRequest, Suggestion, UserEvent } from 'src/application/models';
6
6
  import { Message, MessageRole, MessageType } from 'src/application/models/message';
@@ -61,6 +61,7 @@ export const SalesAgentProvider: React.FC<SalesAgentProviderProps> = ({
61
61
  const userEvents = useAtomValue(userEventQueueAtom);
62
62
  const userQueueEventCount = useAtomValue(userQueueEventCountAtom);
63
63
  const markUserEventsProcessed = useSetAtom(processUserEventAtom);
64
+ const [isHydrated, setIsHydrated] = useState(false);
64
65
  const [isInitialized, setIsInitialized] = useAtom(initializedAtom);
65
66
  const settingsContext = useSystemSettingsContext();
66
67
  const setMessages = useSetAtom(messagesAtom);
@@ -112,6 +113,10 @@ export const SalesAgentProvider: React.FC<SalesAgentProviderProps> = ({
112
113
  if (previewMode) {
113
114
  return;
114
115
  }
116
+ // Wait for the messages to be hydrated before sending messages to the backend
117
+ if (!isHydrated) {
118
+ return;
119
+ }
115
120
 
116
121
  if (userQueueEventCount > 0 && !isSendingRef.current) {
117
122
  isSendingRef.current = true;
@@ -178,6 +183,7 @@ export const SalesAgentProvider: React.FC<SalesAgentProviderProps> = ({
178
183
  );
179
184
  }
180
185
  }, [
186
+ isHydrated,
181
187
  createResponsePayload,
182
188
  getSuggestions,
183
189
  isInitialized,
@@ -190,16 +196,25 @@ export const SalesAgentProvider: React.FC<SalesAgentProviderProps> = ({
190
196
  ]);
191
197
 
192
198
  useEffect(() => {
193
- // Skip hydration in preview mode
194
- if (previewMode) {
195
- return;
196
- }
199
+ const startHydration = async () => {
200
+ // Skip hydration in preview mode
201
+ if (previewMode) {
202
+ return;
203
+ }
197
204
 
198
- if (isInitialized) {
199
- // Rehydrate any messages from the backend
200
- hydrateMessages();
201
- }
202
- }, [isInitialized, hydrateMessages, previewMode]);
205
+ if (!isHydrated) {
206
+ // Rehydrate any messages from the backend
207
+ try {
208
+ await hydrateMessages();
209
+ } catch (error) {
210
+ Logger.logError('[envive-ai] error hydrating messages', error);
211
+ } finally {
212
+ setIsHydrated(true);
213
+ }
214
+ }
215
+ };
216
+ startHydration();
217
+ }, [isInitialized, hydrateMessages, previewMode, isHydrated]);
203
218
 
204
219
  return <SalesAgentContext.Provider value={undefined}>{children}</SalesAgentContext.Provider>;
205
220
  };
@@ -1,8 +1,7 @@
1
+ import { UserEventCategory } from '@spiffy-ai/commerce-api-client';
1
2
  import { useAtomValue, useSetAtom } from 'jotai';
2
3
  import { useCallback } from 'react';
3
- import { v4 as uuid } from 'uuid';
4
4
  import CommerceApiClient from 'src/application/commerce-api';
5
- import { appDetailsAtom } from 'src/atoms/app';
6
5
  import Logger from 'src/application/logging/logger';
7
6
  import {
8
7
  GenerationParams,
@@ -13,7 +12,9 @@ import {
13
12
  Response,
14
13
  UserEvent,
15
14
  } from 'src/application/models';
16
- import { messageFromResponse } from 'src/application/utils';
15
+ import { messageFromQueryEvent, messageFromResponse } from 'src/application/utils';
16
+ import { appDetailsAtom } from 'src/atoms/app';
17
+ import { analyticsContextAtom } from 'src/atoms/app/variant';
17
18
  import {
18
19
  messagesAtom,
19
20
  pendingResponseAtom,
@@ -21,15 +22,14 @@ import {
21
22
  responseStreamingAtom,
22
23
  suggestionsAtom,
23
24
  } from 'src/atoms/chat/chatState';
24
- import { useMessageInterceptor } from 'src/interceptors/useMessageInterceptor';
25
25
  import { useAmplitude } from 'src/contexts/amplitudeContext';
26
+ import { useFeatureFlagService } from 'src/contexts/featureFlagServiceContext';
27
+ import { useMessageInterceptor } from 'src/interceptors/useMessageInterceptor';
26
28
  import {
27
29
  EnviveMetricsEventName,
28
30
  SpiffyMetricsEventName,
29
31
  } from 'src/services/amplitudeService/amplitudeService';
30
- import { useFeatureFlagService } from 'src/contexts/featureFlagServiceContext';
31
- import { UserEventCategory } from '@spiffy-ai/commerce-api-client';
32
- import { analyticsContextAtom } from 'src/atoms/app/variant';
32
+ import { v4 as uuid } from 'uuid';
33
33
 
34
34
  import { StatusCodeError } from './statusCodeError';
35
35
 
@@ -177,10 +177,11 @@ const processStreamingResponse = async (
177
177
  messageInterceptor: { intercept: (response?: Response) => boolean | undefined },
178
178
  setMessages: (updater: (prev: Message[][]) => Message[][]) => void,
179
179
  setResponseStreaming: (responseStreaming: boolean) => void,
180
- ): Promise<Record<string, number>> => {
180
+ ): Promise<Record<string, number | string[]>> => {
181
181
  let lastMessage: Message | undefined;
182
182
  setResponseStreaming(true);
183
- const responseAnalytics: Record<string, number> = {};
183
+ const responseAnalytics: Record<string, number | string[]> = {};
184
+ const productIds = [];
184
185
 
185
186
  for await (const response of stream) {
186
187
  try {
@@ -197,12 +198,19 @@ const processStreamingResponse = async (
197
198
  throw new Error('Failed to transform API response to client message');
198
199
  }
199
200
  if (message.type === MessageType.Product) {
200
- responseAnalytics['chat.product_cards_returned'] =
201
- (responseAnalytics['chat.product_cards_returned'] || 0) + 1;
201
+ const cardsCounter = (responseAnalytics['chat.product_cards_returned'] as number) || 0;
202
+ responseAnalytics['chat.product_cards_returned'] = cardsCounter + 1;
203
+
204
+ const productIds = responseAnalytics['chat.product_ids_returned'] as string[];
205
+ if (!productIds) {
206
+ responseAnalytics['chat.product_ids_returned'] = [message.metadata.id];
207
+ } else {
208
+ productIds.push(message.metadata.id);
209
+ }
202
210
  }
203
211
  if (message.type === MessageType.Review) {
204
- responseAnalytics['chat.review_cards_returned'] =
205
- (responseAnalytics['chat.review_cards_returned'] || 0) + 1;
212
+ const cardsCounter = (responseAnalytics['chat.review_cards_returned'] as number) || 0;
213
+ responseAnalytics['chat.review_cards_returned'] = cardsCounter + 1;
206
214
  }
207
215
 
208
216
  // No support for ChatSearch messages at the current time.
@@ -363,7 +371,7 @@ export const useSalesAgentService: () => SalesAgentService = () => {
363
371
 
364
372
  const hydrateMessages = useCallback(async () => {
365
373
  const { orgId, chatId, userId } = context;
366
- const { messages: existingMessages, userEvents } = await CommerceApiClient.getResponses(
374
+ const { messages: existingMessages } = await CommerceApiClient.getResponses(
367
375
  orgId,
368
376
  chatId,
369
377
  userId,
@@ -201,15 +201,6 @@ export interface AutoPopupConfig {
201
201
  triggers: AutoPopupTrigger[];
202
202
  }
203
203
 
204
- type PartialViewConfig = {
205
- /**
206
- * When true, only full-screen mode is supported (no partial/draggable middle state).
207
- * Useful when partial view causes usability issues on mobile.
208
- * Default: false (undefined and false = partial view enabled).
209
- */
210
- disabled?: boolean;
211
- };
212
-
213
204
  type FloatingChatConfig = {
214
205
  headerBackgroundColor?: string;
215
206
  headerMode: Mode;
@@ -223,7 +214,6 @@ type FloatingChatConfig = {
223
214
  welcomeMessageText: string;
224
215
  chatFooterTextFieldPlaceholderText: string;
225
216
  autoPopupConfig?: AutoPopupConfig;
226
- partialViewConfig?: PartialViewConfig;
227
217
  };
228
218
 
229
219
  type CustomerServiceIntegration = {
@@ -101,6 +101,7 @@ export const GA4_EVENT_SCHEMA: Record<EnviveMetricsEventName, GA4EventSchemaEntr
101
101
  'chat.user_typed',
102
102
  'chat.response_time_ms',
103
103
  'chat.product_cards_returned',
104
+ 'chat.product_ids_returned',
104
105
  'chat.review_cards_returned',
105
106
  ],
106
107
  },