@envive-ai/react-hooks 0.3.39 → 0.3.41

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 (151) hide show
  1. package/dist/application/commerce-api.cjs +3 -2
  2. package/dist/application/commerce-api.js +3 -2
  3. package/dist/application/models/api/orgConfigResults.d.cts +13 -2
  4. package/dist/application/models/api/orgConfigResults.d.ts +13 -2
  5. package/dist/application/models/featureGates.cjs +2 -1
  6. package/dist/application/models/featureGates.d.cts +2 -1
  7. package/dist/application/models/featureGates.d.ts +2 -1
  8. package/dist/application/models/featureGates.js +2 -1
  9. package/dist/application/models/graphql/queries/getWidgetConfigQuery.cjs +23 -0
  10. package/dist/application/models/graphql/queries/getWidgetConfigQuery.js +22 -0
  11. package/dist/application/models/index.d.cts +2 -2
  12. package/dist/application/models/index.d.ts +2 -2
  13. package/dist/application/utils/elementObserver.d.ts +2 -2
  14. package/dist/application/utils/index.cjs +0 -2
  15. package/dist/application/utils/index.d.cts +1 -2
  16. package/dist/application/utils/index.d.ts +1 -2
  17. package/dist/application/utils/index.js +1 -2
  18. package/dist/atoms/app/index.d.cts +1 -1
  19. package/dist/atoms/app/index.d.ts +7 -7
  20. package/dist/atoms/chat/chatState.d.ts +19 -19
  21. package/dist/atoms/chat/form.d.cts +2 -2
  22. package/dist/atoms/chat/form.d.ts +2 -2
  23. package/dist/atoms/chat/index.cjs +1 -1
  24. package/dist/atoms/chat/index.d.cts +2 -2
  25. package/dist/atoms/chat/index.d.ts +3 -3
  26. package/dist/atoms/chat/index.js +1 -1
  27. package/dist/atoms/chat/lastMessage.d.cts +2 -2
  28. package/dist/atoms/chat/lastMessage.d.ts +2 -2
  29. package/dist/atoms/chat/messageQueue.d.cts +6 -6
  30. package/dist/atoms/chat/messageQueue.d.ts +6 -6
  31. package/dist/atoms/chat/performanceMetrics.d.cts +6 -6
  32. package/dist/atoms/chat/performanceMetrics.d.ts +6 -6
  33. package/dist/atoms/chat/renderedWidgetRefs.d.cts +2 -2
  34. package/dist/atoms/chat/renderedWidgetRefs.d.ts +2 -2
  35. package/dist/atoms/chat/replies.d.ts +3 -3
  36. package/dist/atoms/chat/suggestions.d.cts +2 -2
  37. package/dist/atoms/chat/suggestions.d.ts +2 -2
  38. package/dist/atoms/envive/enviveConfig.d.cts +12 -12
  39. package/dist/atoms/envive/enviveConfig.d.ts +13 -13
  40. package/dist/atoms/envive/resolvedBaseConfigVersion.cjs +9 -0
  41. package/dist/atoms/envive/resolvedBaseConfigVersion.js +8 -0
  42. package/dist/atoms/globalSearch/globalSearch.d.cts +5 -5
  43. package/dist/atoms/globalSearch/globalSearch.d.ts +5 -5
  44. package/dist/atoms/org/customerService.d.cts +6 -6
  45. package/dist/atoms/org/customerService.d.ts +6 -6
  46. package/dist/atoms/org/graphqlConfig.d.cts +4 -4
  47. package/dist/atoms/org/graphqlConfig.d.ts +4 -4
  48. package/dist/atoms/org/index.cjs +1 -1
  49. package/dist/atoms/org/index.js +1 -1
  50. package/dist/atoms/org/newOrgConfigAtom.d.cts +2 -2
  51. package/dist/atoms/org/newOrgConfigAtom.d.ts +2 -2
  52. package/dist/atoms/org/orgAnalyticsConfig.d.cts +4 -4
  53. package/dist/atoms/org/orgAnalyticsConfig.d.ts +4 -4
  54. package/dist/atoms/search/chatSearch.cjs +1 -1
  55. package/dist/atoms/search/chatSearch.d.ts +17 -17
  56. package/dist/atoms/search/chatSearch.js +1 -1
  57. package/dist/atoms/search/searchAPI.cjs +1 -1
  58. package/dist/atoms/search/searchAPI.d.ts +13 -13
  59. package/dist/atoms/search/searchAPI.js +1 -1
  60. package/dist/atoms/search/types.d.cts +1 -1
  61. package/dist/atoms/search/types.d.ts +1 -1
  62. package/dist/atoms/search/utils.d.ts +1 -1
  63. package/dist/atoms/widget/chatPreviewLoading.d.cts +2 -2
  64. package/dist/atoms/widget/chatPreviewLoading.d.ts +2 -2
  65. package/dist/contexts/enviveContext/enviveContext.cjs +11 -3
  66. package/dist/contexts/enviveContext/enviveContext.js +11 -3
  67. package/dist/contexts/enviveContext/types.d.cts +1 -1
  68. package/dist/contexts/enviveContext/types.d.ts +1 -1
  69. package/dist/contexts/graphqlContext/graphqlContext.cjs +1 -1
  70. package/dist/contexts/graphqlContext/graphqlContext.d.cts +3 -1
  71. package/dist/contexts/graphqlContext/graphqlContext.d.ts +3 -1
  72. package/dist/contexts/graphqlContext/graphqlContext.js +1 -1
  73. package/dist/contexts/pageContext/types.d.ts +1 -1
  74. package/dist/contexts/salesAgentContext/chatAPI.cjs +2 -2
  75. package/dist/contexts/salesAgentContext/chatAPI.js +2 -2
  76. package/dist/contexts/salesAgentContext/salesAgentService.cjs +10 -4
  77. package/dist/contexts/salesAgentContext/salesAgentService.js +10 -4
  78. package/dist/contexts/searchContext/searchContext.cjs +1 -1
  79. package/dist/contexts/searchContext/searchContext.js +1 -1
  80. package/dist/contexts/systemSettingsContext/systemSettingsContext.d.cts +2 -2
  81. package/dist/contexts/systemSettingsContext/systemSettingsContext.d.ts +2 -2
  82. package/dist/contexts/types.d.cts +1 -1
  83. package/dist/contexts/types.d.ts +1 -1
  84. package/dist/contexts/typesV3.d.cts +1 -1
  85. package/dist/contexts/typesV3.d.ts +1 -1
  86. package/dist/hooks/ChatToggle/useChatToggle.cjs +1 -1
  87. package/dist/hooks/ChatToggle/useChatToggle.js +1 -1
  88. package/dist/hooks/FocusTrap/index.cjs +3 -0
  89. package/dist/hooks/FocusTrap/index.d.cts +2 -0
  90. package/dist/hooks/FocusTrap/index.d.ts +2 -0
  91. package/dist/hooks/FocusTrap/index.js +3 -0
  92. package/dist/hooks/FocusTrap/useFocusTrap.cjs +105 -0
  93. package/dist/hooks/FocusTrap/useFocusTrap.d.cts +20 -0
  94. package/dist/hooks/FocusTrap/useFocusTrap.d.ts +20 -0
  95. package/dist/hooks/FocusTrap/useFocusTrap.js +104 -0
  96. package/dist/hooks/GrabAndScroll/useGrabAndScroll.d.cts +2 -2
  97. package/dist/hooks/GrabAndScroll/useGrabAndScroll.d.ts +2 -2
  98. package/dist/hooks/Search/useSearch.cjs +3 -3
  99. package/dist/hooks/Search/useSearch.js +3 -3
  100. package/dist/hooks/SystemSettingsContext/useSystemSettingsContext.d.ts +2 -2
  101. package/dist/hooks/utils.d.cts +1 -1
  102. package/dist/hooks/utils.d.ts +1 -1
  103. package/dist/services/amplitudeService/amplitudeService.cjs +17 -2
  104. package/dist/services/amplitudeService/amplitudeService.d.cts +3 -1
  105. package/dist/services/amplitudeService/amplitudeService.d.ts +3 -1
  106. package/dist/services/amplitudeService/amplitudeService.js +17 -2
  107. package/dist/services/enviveConfigService/enviveConfigService.cjs +9 -3
  108. package/dist/services/enviveConfigService/enviveConfigService.d.cts +3 -2
  109. package/dist/services/enviveConfigService/enviveConfigService.d.ts +3 -2
  110. package/dist/services/enviveConfigService/enviveConfigService.js +10 -4
  111. package/dist/services/enviveConfigService/fetchGraphQLConfig.cjs +78 -39
  112. package/dist/services/enviveConfigService/fetchGraphQLConfig.js +78 -40
  113. package/dist/services/ga4ProjectionService/ga4ProjectionService.cjs +3 -3
  114. package/dist/services/ga4ProjectionService/ga4ProjectionService.js +3 -3
  115. package/dist/services/hardcopyService/hardcopyService.cjs +4 -2
  116. package/dist/services/hardcopyService/hardcopyService.js +4 -2
  117. package/dist/types/config-versions.cjs +3 -1
  118. package/dist/types/config-versions.js +3 -2
  119. package/dist/types/customerService.cjs +2 -1
  120. package/dist/types/customerService.d.cts +2 -1
  121. package/dist/types/customerService.d.ts +2 -1
  122. package/dist/types/customerService.js +2 -1
  123. package/package.json +5 -1
  124. package/src/application/commerce-api.ts +5 -1
  125. package/src/application/models/api/orgConfigResults.ts +27 -0
  126. package/src/application/models/featureGates.ts +5 -0
  127. package/src/application/models/graphql/queries/getWidgetConfigQuery.ts +34 -0
  128. package/src/application/utils/__tests__/elementObserver.test.ts +200 -0
  129. package/src/application/utils/index.ts +0 -1
  130. package/src/atoms/envive/resolvedBaseConfigVersion.ts +11 -0
  131. package/src/contexts/enviveContext/enviveContext.tsx +20 -0
  132. package/src/contexts/graphqlContext/graphqlContext.tsx +5 -0
  133. package/src/contexts/salesAgentContext/salesAgentService.ts +4 -1
  134. package/src/hooks/FocusTrap/__tests__/useFocusTrap.test.tsx +236 -0
  135. package/src/hooks/FocusTrap/index.ts +1 -0
  136. package/src/hooks/FocusTrap/useFocusTrap.ts +125 -0
  137. package/src/services/amplitudeService/__tests__/amplitudeService.test.ts +95 -0
  138. package/src/services/amplitudeService/amplitudeService.ts +31 -1
  139. package/src/services/enviveConfigService/__tests__/fetchGraphQLConfig.test.ts +107 -1
  140. package/src/services/enviveConfigService/enviveConfigService.ts +35 -7
  141. package/src/services/enviveConfigService/fetchGraphQLConfig.ts +119 -57
  142. package/src/services/ga4ProjectionService/ga4ProjectionService.ts +2 -2
  143. package/src/services/hardcopyService/__tests__/hardcopyService.test.ts +35 -1
  144. package/src/services/hardcopyService/hardcopyService.ts +6 -1
  145. package/src/types/config-versions.ts +8 -0
  146. package/src/types/customerService.ts +1 -0
  147. package/dist/application/utils/merchantUtils.cjs +0 -18
  148. package/dist/application/utils/merchantUtils.d.cts +0 -5
  149. package/dist/application/utils/merchantUtils.d.ts +0 -5
  150. package/dist/application/utils/merchantUtils.js +0 -17
  151. package/src/application/utils/merchantUtils.ts +0 -16
@@ -14,10 +14,11 @@ let CustomerServiceType = /* @__PURE__ */ function(CustomerServiceType$1) {
14
14
  CustomerServiceType$1["helpscout"] = "helpscout";
15
15
  CustomerServiceType$1["talkdesk"] = "talkdesk";
16
16
  CustomerServiceType$1["eightByEight"] = "8x8";
17
+ CustomerServiceType$1["freshchat"] = "freshchat";
17
18
  CustomerServiceType$1["unsupported"] = "unsupported";
18
19
  return CustomerServiceType$1;
19
20
  }({});
20
21
 
21
22
  //#endregion
22
23
  exports.CustomerServiceType = CustomerServiceType;
23
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3VzdG9tZXJTZXJ2aWNlLmNqcyIsIm5hbWVzIjpbXSwic291cmNlcyI6WyIuLi8uLi9zcmMvdHlwZXMvY3VzdG9tZXJTZXJ2aWNlLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEN1c3RvbWVyU2VydmljZVByb3ZpZGVyIH0gZnJvbSAnQHNwaWZmeS1haS9jb21tZXJjZS1hcGktY2xpZW50JztcblxuZXhwb3J0IGVudW0gQ3VzdG9tZXJTZXJ2aWNlVHlwZSB7XG4gIHNob3BpZnkgPSAnc2hvcGlmeScsXG4gIGdvcmdpYXMgPSAnZ29yZ2lhcycsXG4gIGt1c3RvbWVyID0gJ2t1c3RvbWVyJyxcbiAgZ3Jvb3ZlID0gJ2dyb292ZScsXG4gIHRpZGlvID0gJ3RpZGlvJyxcbiAgem93aWUgPSAnem93aWUnLFxuICByZWRvID0gJ3JlZG8nLFxuICBnbGFkbHkgPSAnZ2xhZGx5JyxcbiAgcmljaHBhbmVsID0gJ3JpY2hwYW5lbCcsXG4gIHplbmRlc2sgPSAnemVuZGVzaycsXG4gIGhlbHBzY291dCA9ICdoZWxwc2NvdXQnLFxuICB0YWxrZGVzayA9ICd0YWxrZGVzaycsXG4gIGVpZ2h0QnlFaWdodCA9ICc4eDgnLFxuICB1bnN1cHBvcnRlZCA9ICd1bnN1cHBvcnRlZCcsXG59XG5leHBvcnQgZW51bSBDdXN0b21lclNlcnZpY2VJbnRlZ3JhdGlvbk1vZGUge1xuICBub25lID0gJ25vbmUnLFxuICBzaW1wbGUgPSAnc2ltcGxlJyxcbiAgZnVsbCA9ICdmdWxsJyxcbn1cblxuZXhwb3J0IGludGVyZmFjZSBDdXN0b21lclNlcnZpY2VJbnRlZ3JhdGlvbiB7XG4gIHByb3ZpZGVyOiBDdXN0b21lclNlcnZpY2VQcm92aWRlcjtcbiAgc3VwcG9ydGVkSW50ZWdyYXRpb25Nb2RlczogQ3VzdG9tZXJTZXJ2aWNlSW50ZWdyYXRpb25Nb2RlW107XG4gIGFsbG93RmlsZVVwbG9hZD86IGJvb2xlYW47XG4gIG1heGZpbGVVcGxvYWRTaXplPzogbnVtYmVyO1xuICAvLyBUT0RPOiBSZW1vdmUgdGhpcyBtZXRob2Qgd2hlbiBtaWdyYXRpbmcgb3RoZXIgcHJvdmlkZXJzIHRvIHRoZSBuZXcgdW5pZmllZCBDWCBidXR0b24uXG4gIG9uU3dpdGNoVG9BZ2VudDogKCkgPT4gdm9pZDtcbiAgaXNFbmFibGVkOiAoKSA9PiBib29sZWFuO1xuICBpc0J1c2luZXNzSG91cnM6IChhcGlLZXk/OiBzdHJpbmcsIGFwaUVuZHBvaW50Pzogc3RyaW5nKSA9PiBQcm9taXNlPGJvb2xlYW4+O1xufVxuIl0sIm1hcHBpbmdzIjoiOztBQUVBLElBQVksc0VBQUw7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIn0=
24
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3VzdG9tZXJTZXJ2aWNlLmNqcyIsIm5hbWVzIjpbXSwic291cmNlcyI6WyIuLi8uLi9zcmMvdHlwZXMvY3VzdG9tZXJTZXJ2aWNlLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEN1c3RvbWVyU2VydmljZVByb3ZpZGVyIH0gZnJvbSAnQHNwaWZmeS1haS9jb21tZXJjZS1hcGktY2xpZW50JztcblxuZXhwb3J0IGVudW0gQ3VzdG9tZXJTZXJ2aWNlVHlwZSB7XG4gIHNob3BpZnkgPSAnc2hvcGlmeScsXG4gIGdvcmdpYXMgPSAnZ29yZ2lhcycsXG4gIGt1c3RvbWVyID0gJ2t1c3RvbWVyJyxcbiAgZ3Jvb3ZlID0gJ2dyb292ZScsXG4gIHRpZGlvID0gJ3RpZGlvJyxcbiAgem93aWUgPSAnem93aWUnLFxuICByZWRvID0gJ3JlZG8nLFxuICBnbGFkbHkgPSAnZ2xhZGx5JyxcbiAgcmljaHBhbmVsID0gJ3JpY2hwYW5lbCcsXG4gIHplbmRlc2sgPSAnemVuZGVzaycsXG4gIGhlbHBzY291dCA9ICdoZWxwc2NvdXQnLFxuICB0YWxrZGVzayA9ICd0YWxrZGVzaycsXG4gIGVpZ2h0QnlFaWdodCA9ICc4eDgnLFxuICBmcmVzaGNoYXQgPSAnZnJlc2hjaGF0JyxcbiAgdW5zdXBwb3J0ZWQgPSAndW5zdXBwb3J0ZWQnLFxufVxuZXhwb3J0IGVudW0gQ3VzdG9tZXJTZXJ2aWNlSW50ZWdyYXRpb25Nb2RlIHtcbiAgbm9uZSA9ICdub25lJyxcbiAgc2ltcGxlID0gJ3NpbXBsZScsXG4gIGZ1bGwgPSAnZnVsbCcsXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ3VzdG9tZXJTZXJ2aWNlSW50ZWdyYXRpb24ge1xuICBwcm92aWRlcjogQ3VzdG9tZXJTZXJ2aWNlUHJvdmlkZXI7XG4gIHN1cHBvcnRlZEludGVncmF0aW9uTW9kZXM6IEN1c3RvbWVyU2VydmljZUludGVncmF0aW9uTW9kZVtdO1xuICBhbGxvd0ZpbGVVcGxvYWQ/OiBib29sZWFuO1xuICBtYXhmaWxlVXBsb2FkU2l6ZT86IG51bWJlcjtcbiAgLy8gVE9ETzogUmVtb3ZlIHRoaXMgbWV0aG9kIHdoZW4gbWlncmF0aW5nIG90aGVyIHByb3ZpZGVycyB0byB0aGUgbmV3IHVuaWZpZWQgQ1ggYnV0dG9uLlxuICBvblN3aXRjaFRvQWdlbnQ6ICgpID0+IHZvaWQ7XG4gIGlzRW5hYmxlZDogKCkgPT4gYm9vbGVhbjtcbiAgaXNCdXNpbmVzc0hvdXJzOiAoYXBpS2V5Pzogc3RyaW5nLCBhcGlFbmRwb2ludD86IHN0cmluZykgPT4gUHJvbWlzZTxib29sZWFuPjtcbn1cbiJdLCJtYXBwaW5ncyI6Ijs7QUFFQSxJQUFZLHNFQUFMO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIn0=
@@ -15,6 +15,7 @@ declare enum CustomerServiceType {
15
15
  helpscout = "helpscout",
16
16
  talkdesk = "talkdesk",
17
17
  eightByEight = "8x8",
18
+ freshchat = "freshchat",
18
19
  unsupported = "unsupported",
19
20
  }
20
21
  declare enum CustomerServiceIntegrationMode {
@@ -24,4 +25,4 @@ declare enum CustomerServiceIntegrationMode {
24
25
  }
25
26
  //#endregion
26
27
  export { CustomerServiceIntegrationMode, CustomerServiceType };
27
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3VzdG9tZXJTZXJ2aWNlLmQuY3RzIiwibmFtZXMiOltdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy90eXBlcy9jdXN0b21lclNlcnZpY2UuZC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDdXN0b21lclNlcnZpY2VQcm92aWRlciB9IGZyb20gJ0BzcGlmZnktYWkvY29tbWVyY2UtYXBpLWNsaWVudCc7XG5leHBvcnQgZGVjbGFyZSBlbnVtIEN1c3RvbWVyU2VydmljZVR5cGUge1xuICAgIHNob3BpZnkgPSBcInNob3BpZnlcIixcbiAgICBnb3JnaWFzID0gXCJnb3JnaWFzXCIsXG4gICAga3VzdG9tZXIgPSBcImt1c3RvbWVyXCIsXG4gICAgZ3Jvb3ZlID0gXCJncm9vdmVcIixcbiAgICB0aWRpbyA9IFwidGlkaW9cIixcbiAgICB6b3dpZSA9IFwiem93aWVcIixcbiAgICByZWRvID0gXCJyZWRvXCIsXG4gICAgZ2xhZGx5ID0gXCJnbGFkbHlcIixcbiAgICByaWNocGFuZWwgPSBcInJpY2hwYW5lbFwiLFxuICAgIHplbmRlc2sgPSBcInplbmRlc2tcIixcbiAgICBoZWxwc2NvdXQgPSBcImhlbHBzY291dFwiLFxuICAgIHRhbGtkZXNrID0gXCJ0YWxrZGVza1wiLFxuICAgIGVpZ2h0QnlFaWdodCA9IFwiOHg4XCIsXG4gICAgdW5zdXBwb3J0ZWQgPSBcInVuc3VwcG9ydGVkXCJcbn1cbmV4cG9ydCBkZWNsYXJlIGVudW0gQ3VzdG9tZXJTZXJ2aWNlSW50ZWdyYXRpb25Nb2RlIHtcbiAgICBub25lID0gXCJub25lXCIsXG4gICAgc2ltcGxlID0gXCJzaW1wbGVcIixcbiAgICBmdWxsID0gXCJmdWxsXCJcbn1cbmV4cG9ydCBpbnRlcmZhY2UgQ3VzdG9tZXJTZXJ2aWNlSW50ZWdyYXRpb24ge1xuICAgIHByb3ZpZGVyOiBDdXN0b21lclNlcnZpY2VQcm92aWRlcjtcbiAgICBzdXBwb3J0ZWRJbnRlZ3JhdGlvbk1vZGVzOiBDdXN0b21lclNlcnZpY2VJbnRlZ3JhdGlvbk1vZGVbXTtcbiAgICBhbGxvd0ZpbGVVcGxvYWQ/OiBib29sZWFuO1xuICAgIG1heGZpbGVVcGxvYWRTaXplPzogbnVtYmVyO1xuICAgIG9uU3dpdGNoVG9BZ2VudDogKCkgPT4gdm9pZDtcbiAgICBpc0VuYWJsZWQ6ICgpID0+IGJvb2xlYW47XG4gICAgaXNCdXNpbmVzc0hvdXJzOiAoYXBpS2V5Pzogc3RyaW5nLCBhcGlFbmRwb2ludD86IHN0cmluZykgPT4gUHJvbWlzZTxib29sZWFuPjtcbn1cbiJdLCJtYXBwaW5ncyI6Ijs7O0FBQ0EsSUFBVyxzQkFBc0IsQ0FBQyxJQUFJO0FBQ3RDLElBQVcsaUNBQVksQ0FBQSxJQUFBIn0=
28
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3VzdG9tZXJTZXJ2aWNlLmQuY3RzIiwibmFtZXMiOltdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy90eXBlcy9jdXN0b21lclNlcnZpY2UuZC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDdXN0b21lclNlcnZpY2VQcm92aWRlciB9IGZyb20gJ0BzcGlmZnktYWkvY29tbWVyY2UtYXBpLWNsaWVudCc7XG5leHBvcnQgZGVjbGFyZSBlbnVtIEN1c3RvbWVyU2VydmljZVR5cGUge1xuICAgIHNob3BpZnkgPSBcInNob3BpZnlcIixcbiAgICBnb3JnaWFzID0gXCJnb3JnaWFzXCIsXG4gICAga3VzdG9tZXIgPSBcImt1c3RvbWVyXCIsXG4gICAgZ3Jvb3ZlID0gXCJncm9vdmVcIixcbiAgICB0aWRpbyA9IFwidGlkaW9cIixcbiAgICB6b3dpZSA9IFwiem93aWVcIixcbiAgICByZWRvID0gXCJyZWRvXCIsXG4gICAgZ2xhZGx5ID0gXCJnbGFkbHlcIixcbiAgICByaWNocGFuZWwgPSBcInJpY2hwYW5lbFwiLFxuICAgIHplbmRlc2sgPSBcInplbmRlc2tcIixcbiAgICBoZWxwc2NvdXQgPSBcImhlbHBzY291dFwiLFxuICAgIHRhbGtkZXNrID0gXCJ0YWxrZGVza1wiLFxuICAgIGVpZ2h0QnlFaWdodCA9IFwiOHg4XCIsXG4gICAgZnJlc2hjaGF0ID0gXCJmcmVzaGNoYXRcIixcbiAgICB1bnN1cHBvcnRlZCA9IFwidW5zdXBwb3J0ZWRcIlxufVxuZXhwb3J0IGRlY2xhcmUgZW51bSBDdXN0b21lclNlcnZpY2VJbnRlZ3JhdGlvbk1vZGUge1xuICAgIG5vbmUgPSBcIm5vbmVcIixcbiAgICBzaW1wbGUgPSBcInNpbXBsZVwiLFxuICAgIGZ1bGwgPSBcImZ1bGxcIlxufVxuZXhwb3J0IGludGVyZmFjZSBDdXN0b21lclNlcnZpY2VJbnRlZ3JhdGlvbiB7XG4gICAgcHJvdmlkZXI6IEN1c3RvbWVyU2VydmljZVByb3ZpZGVyO1xuICAgIHN1cHBvcnRlZEludGVncmF0aW9uTW9kZXM6IEN1c3RvbWVyU2VydmljZUludGVncmF0aW9uTW9kZVtdO1xuICAgIGFsbG93RmlsZVVwbG9hZD86IGJvb2xlYW47XG4gICAgbWF4ZmlsZVVwbG9hZFNpemU/OiBudW1iZXI7XG4gICAgb25Td2l0Y2hUb0FnZW50OiAoKSA9PiB2b2lkO1xuICAgIGlzRW5hYmxlZDogKCkgPT4gYm9vbGVhbjtcbiAgICBpc0J1c2luZXNzSG91cnM6IChhcGlLZXk/OiBzdHJpbmcsIGFwaUVuZHBvaW50Pzogc3RyaW5nKSA9PiBQcm9taXNlPGJvb2xlYW4+O1xufVxuIl0sIm1hcHBpbmdzIjoiOzs7QUFDQSxJQUFXLHNCQUFzQixDQUFDLElBQUk7QUFDdEMsSUFBVyxpQ0FBWSxDQUFBLElBQUEifQ==
@@ -15,6 +15,7 @@ declare enum CustomerServiceType {
15
15
  helpscout = "helpscout",
16
16
  talkdesk = "talkdesk",
17
17
  eightByEight = "8x8",
18
+ freshchat = "freshchat",
18
19
  unsupported = "unsupported",
19
20
  }
20
21
  declare enum CustomerServiceIntegrationMode {
@@ -24,4 +25,4 @@ declare enum CustomerServiceIntegrationMode {
24
25
  }
25
26
  //#endregion
26
27
  export { CustomerServiceIntegrationMode, CustomerServiceType };
27
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3VzdG9tZXJTZXJ2aWNlLmQudHMiLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vLi4vc3JjL3R5cGVzL2N1c3RvbWVyU2VydmljZS5kLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEN1c3RvbWVyU2VydmljZVByb3ZpZGVyIH0gZnJvbSAnQHNwaWZmeS1haS9jb21tZXJjZS1hcGktY2xpZW50JztcbmV4cG9ydCBkZWNsYXJlIGVudW0gQ3VzdG9tZXJTZXJ2aWNlVHlwZSB7XG4gICAgc2hvcGlmeSA9IFwic2hvcGlmeVwiLFxuICAgIGdvcmdpYXMgPSBcImdvcmdpYXNcIixcbiAgICBrdXN0b21lciA9IFwia3VzdG9tZXJcIixcbiAgICBncm9vdmUgPSBcImdyb292ZVwiLFxuICAgIHRpZGlvID0gXCJ0aWRpb1wiLFxuICAgIHpvd2llID0gXCJ6b3dpZVwiLFxuICAgIHJlZG8gPSBcInJlZG9cIixcbiAgICBnbGFkbHkgPSBcImdsYWRseVwiLFxuICAgIHJpY2hwYW5lbCA9IFwicmljaHBhbmVsXCIsXG4gICAgemVuZGVzayA9IFwiemVuZGVza1wiLFxuICAgIGhlbHBzY291dCA9IFwiaGVscHNjb3V0XCIsXG4gICAgdGFsa2Rlc2sgPSBcInRhbGtkZXNrXCIsXG4gICAgZWlnaHRCeUVpZ2h0ID0gXCI4eDhcIixcbiAgICB1bnN1cHBvcnRlZCA9IFwidW5zdXBwb3J0ZWRcIlxufVxuZXhwb3J0IGRlY2xhcmUgZW51bSBDdXN0b21lclNlcnZpY2VJbnRlZ3JhdGlvbk1vZGUge1xuICAgIG5vbmUgPSBcIm5vbmVcIixcbiAgICBzaW1wbGUgPSBcInNpbXBsZVwiLFxuICAgIGZ1bGwgPSBcImZ1bGxcIlxufVxuZXhwb3J0IGludGVyZmFjZSBDdXN0b21lclNlcnZpY2VJbnRlZ3JhdGlvbiB7XG4gICAgcHJvdmlkZXI6IEN1c3RvbWVyU2VydmljZVByb3ZpZGVyO1xuICAgIHN1cHBvcnRlZEludGVncmF0aW9uTW9kZXM6IEN1c3RvbWVyU2VydmljZUludGVncmF0aW9uTW9kZVtdO1xuICAgIGFsbG93RmlsZVVwbG9hZD86IGJvb2xlYW47XG4gICAgbWF4ZmlsZVVwbG9hZFNpemU/OiBudW1iZXI7XG4gICAgb25Td2l0Y2hUb0FnZW50OiAoKSA9PiB2b2lkO1xuICAgIGlzRW5hYmxlZDogKCkgPT4gYm9vbGVhbjtcbiAgICBpc0J1c2luZXNzSG91cnM6IChhcGlLZXk/OiBzdHJpbmcsIGFwaUVuZHBvaW50Pzogc3RyaW5nKSA9PiBQcm9taXNlPGJvb2xlYW4+O1xufVxuIl0sIm1hcHBpbmdzIjoiOzs7QUFDQSxJQUFXLHNCQUFzQixDQUFDLElBQUk7QUFDdEMsSUFBVyxpQ0FBWSxDQUFBLElBQUEifQ==
28
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3VzdG9tZXJTZXJ2aWNlLmQudHMiLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vLi4vc3JjL3R5cGVzL2N1c3RvbWVyU2VydmljZS5kLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEN1c3RvbWVyU2VydmljZVByb3ZpZGVyIH0gZnJvbSAnQHNwaWZmeS1haS9jb21tZXJjZS1hcGktY2xpZW50JztcbmV4cG9ydCBkZWNsYXJlIGVudW0gQ3VzdG9tZXJTZXJ2aWNlVHlwZSB7XG4gICAgc2hvcGlmeSA9IFwic2hvcGlmeVwiLFxuICAgIGdvcmdpYXMgPSBcImdvcmdpYXNcIixcbiAgICBrdXN0b21lciA9IFwia3VzdG9tZXJcIixcbiAgICBncm9vdmUgPSBcImdyb292ZVwiLFxuICAgIHRpZGlvID0gXCJ0aWRpb1wiLFxuICAgIHpvd2llID0gXCJ6b3dpZVwiLFxuICAgIHJlZG8gPSBcInJlZG9cIixcbiAgICBnbGFkbHkgPSBcImdsYWRseVwiLFxuICAgIHJpY2hwYW5lbCA9IFwicmljaHBhbmVsXCIsXG4gICAgemVuZGVzayA9IFwiemVuZGVza1wiLFxuICAgIGhlbHBzY291dCA9IFwiaGVscHNjb3V0XCIsXG4gICAgdGFsa2Rlc2sgPSBcInRhbGtkZXNrXCIsXG4gICAgZWlnaHRCeUVpZ2h0ID0gXCI4eDhcIixcbiAgICBmcmVzaGNoYXQgPSBcImZyZXNoY2hhdFwiLFxuICAgIHVuc3VwcG9ydGVkID0gXCJ1bnN1cHBvcnRlZFwiXG59XG5leHBvcnQgZGVjbGFyZSBlbnVtIEN1c3RvbWVyU2VydmljZUludGVncmF0aW9uTW9kZSB7XG4gICAgbm9uZSA9IFwibm9uZVwiLFxuICAgIHNpbXBsZSA9IFwic2ltcGxlXCIsXG4gICAgZnVsbCA9IFwiZnVsbFwiXG59XG5leHBvcnQgaW50ZXJmYWNlIEN1c3RvbWVyU2VydmljZUludGVncmF0aW9uIHtcbiAgICBwcm92aWRlcjogQ3VzdG9tZXJTZXJ2aWNlUHJvdmlkZXI7XG4gICAgc3VwcG9ydGVkSW50ZWdyYXRpb25Nb2RlczogQ3VzdG9tZXJTZXJ2aWNlSW50ZWdyYXRpb25Nb2RlW107XG4gICAgYWxsb3dGaWxlVXBsb2FkPzogYm9vbGVhbjtcbiAgICBtYXhmaWxlVXBsb2FkU2l6ZT86IG51bWJlcjtcbiAgICBvblN3aXRjaFRvQWdlbnQ6ICgpID0+IHZvaWQ7XG4gICAgaXNFbmFibGVkOiAoKSA9PiBib29sZWFuO1xuICAgIGlzQnVzaW5lc3NIb3VyczogKGFwaUtleT86IHN0cmluZywgYXBpRW5kcG9pbnQ/OiBzdHJpbmcpID0+IFByb21pc2U8Ym9vbGVhbj47XG59XG4iXSwibWFwcGluZ3MiOiI7OztBQUNBLElBQVcsc0JBQXNCLENBQUMsSUFBSTtBQUN0QyxJQUFXLGlDQUFZLENBQUEsSUFBQSJ9
@@ -13,10 +13,11 @@ let CustomerServiceType = /* @__PURE__ */ function(CustomerServiceType$1) {
13
13
  CustomerServiceType$1["helpscout"] = "helpscout";
14
14
  CustomerServiceType$1["talkdesk"] = "talkdesk";
15
15
  CustomerServiceType$1["eightByEight"] = "8x8";
16
+ CustomerServiceType$1["freshchat"] = "freshchat";
16
17
  CustomerServiceType$1["unsupported"] = "unsupported";
17
18
  return CustomerServiceType$1;
18
19
  }({});
19
20
 
20
21
  //#endregion
21
22
  export { CustomerServiceType };
22
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3VzdG9tZXJTZXJ2aWNlLmpzIiwibmFtZXMiOltdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy90eXBlcy9jdXN0b21lclNlcnZpY2UudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ3VzdG9tZXJTZXJ2aWNlUHJvdmlkZXIgfSBmcm9tICdAc3BpZmZ5LWFpL2NvbW1lcmNlLWFwaS1jbGllbnQnO1xuXG5leHBvcnQgZW51bSBDdXN0b21lclNlcnZpY2VUeXBlIHtcbiAgc2hvcGlmeSA9ICdzaG9waWZ5JyxcbiAgZ29yZ2lhcyA9ICdnb3JnaWFzJyxcbiAga3VzdG9tZXIgPSAna3VzdG9tZXInLFxuICBncm9vdmUgPSAnZ3Jvb3ZlJyxcbiAgdGlkaW8gPSAndGlkaW8nLFxuICB6b3dpZSA9ICd6b3dpZScsXG4gIHJlZG8gPSAncmVkbycsXG4gIGdsYWRseSA9ICdnbGFkbHknLFxuICByaWNocGFuZWwgPSAncmljaHBhbmVsJyxcbiAgemVuZGVzayA9ICd6ZW5kZXNrJyxcbiAgaGVscHNjb3V0ID0gJ2hlbHBzY291dCcsXG4gIHRhbGtkZXNrID0gJ3RhbGtkZXNrJyxcbiAgZWlnaHRCeUVpZ2h0ID0gJzh4OCcsXG4gIHVuc3VwcG9ydGVkID0gJ3Vuc3VwcG9ydGVkJyxcbn1cbmV4cG9ydCBlbnVtIEN1c3RvbWVyU2VydmljZUludGVncmF0aW9uTW9kZSB7XG4gIG5vbmUgPSAnbm9uZScsXG4gIHNpbXBsZSA9ICdzaW1wbGUnLFxuICBmdWxsID0gJ2Z1bGwnLFxufVxuXG5leHBvcnQgaW50ZXJmYWNlIEN1c3RvbWVyU2VydmljZUludGVncmF0aW9uIHtcbiAgcHJvdmlkZXI6IEN1c3RvbWVyU2VydmljZVByb3ZpZGVyO1xuICBzdXBwb3J0ZWRJbnRlZ3JhdGlvbk1vZGVzOiBDdXN0b21lclNlcnZpY2VJbnRlZ3JhdGlvbk1vZGVbXTtcbiAgYWxsb3dGaWxlVXBsb2FkPzogYm9vbGVhbjtcbiAgbWF4ZmlsZVVwbG9hZFNpemU/OiBudW1iZXI7XG4gIC8vIFRPRE86IFJlbW92ZSB0aGlzIG1ldGhvZCB3aGVuIG1pZ3JhdGluZyBvdGhlciBwcm92aWRlcnMgdG8gdGhlIG5ldyB1bmlmaWVkIENYIGJ1dHRvbi5cbiAgb25Td2l0Y2hUb0FnZW50OiAoKSA9PiB2b2lkO1xuICBpc0VuYWJsZWQ6ICgpID0+IGJvb2xlYW47XG4gIGlzQnVzaW5lc3NIb3VyczogKGFwaUtleT86IHN0cmluZywgYXBpRW5kcG9pbnQ/OiBzdHJpbmcpID0+IFByb21pc2U8Ym9vbGVhbj47XG59XG4iXSwibWFwcGluZ3MiOiI7QUFFQSxJQUFZLHNFQUFMO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSJ9
23
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3VzdG9tZXJTZXJ2aWNlLmpzIiwibmFtZXMiOltdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy90eXBlcy9jdXN0b21lclNlcnZpY2UudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ3VzdG9tZXJTZXJ2aWNlUHJvdmlkZXIgfSBmcm9tICdAc3BpZmZ5LWFpL2NvbW1lcmNlLWFwaS1jbGllbnQnO1xuXG5leHBvcnQgZW51bSBDdXN0b21lclNlcnZpY2VUeXBlIHtcbiAgc2hvcGlmeSA9ICdzaG9waWZ5JyxcbiAgZ29yZ2lhcyA9ICdnb3JnaWFzJyxcbiAga3VzdG9tZXIgPSAna3VzdG9tZXInLFxuICBncm9vdmUgPSAnZ3Jvb3ZlJyxcbiAgdGlkaW8gPSAndGlkaW8nLFxuICB6b3dpZSA9ICd6b3dpZScsXG4gIHJlZG8gPSAncmVkbycsXG4gIGdsYWRseSA9ICdnbGFkbHknLFxuICByaWNocGFuZWwgPSAncmljaHBhbmVsJyxcbiAgemVuZGVzayA9ICd6ZW5kZXNrJyxcbiAgaGVscHNjb3V0ID0gJ2hlbHBzY291dCcsXG4gIHRhbGtkZXNrID0gJ3RhbGtkZXNrJyxcbiAgZWlnaHRCeUVpZ2h0ID0gJzh4OCcsXG4gIGZyZXNoY2hhdCA9ICdmcmVzaGNoYXQnLFxuICB1bnN1cHBvcnRlZCA9ICd1bnN1cHBvcnRlZCcsXG59XG5leHBvcnQgZW51bSBDdXN0b21lclNlcnZpY2VJbnRlZ3JhdGlvbk1vZGUge1xuICBub25lID0gJ25vbmUnLFxuICBzaW1wbGUgPSAnc2ltcGxlJyxcbiAgZnVsbCA9ICdmdWxsJyxcbn1cblxuZXhwb3J0IGludGVyZmFjZSBDdXN0b21lclNlcnZpY2VJbnRlZ3JhdGlvbiB7XG4gIHByb3ZpZGVyOiBDdXN0b21lclNlcnZpY2VQcm92aWRlcjtcbiAgc3VwcG9ydGVkSW50ZWdyYXRpb25Nb2RlczogQ3VzdG9tZXJTZXJ2aWNlSW50ZWdyYXRpb25Nb2RlW107XG4gIGFsbG93RmlsZVVwbG9hZD86IGJvb2xlYW47XG4gIG1heGZpbGVVcGxvYWRTaXplPzogbnVtYmVyO1xuICAvLyBUT0RPOiBSZW1vdmUgdGhpcyBtZXRob2Qgd2hlbiBtaWdyYXRpbmcgb3RoZXIgcHJvdmlkZXJzIHRvIHRoZSBuZXcgdW5pZmllZCBDWCBidXR0b24uXG4gIG9uU3dpdGNoVG9BZ2VudDogKCkgPT4gdm9pZDtcbiAgaXNFbmFibGVkOiAoKSA9PiBib29sZWFuO1xuICBpc0J1c2luZXNzSG91cnM6IChhcGlLZXk/OiBzdHJpbmcsIGFwaUVuZHBvaW50Pzogc3RyaW5nKSA9PiBQcm9taXNlPGJvb2xlYW4+O1xufVxuIl0sIm1hcHBpbmdzIjoiO0FBRUEsSUFBWSxzRUFBTDtBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSJ9
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@envive-ai/react-hooks",
3
- "version": "0.3.39",
3
+ "version": "0.3.41",
4
4
  "description": "React hooks for connecting to Envive AI services.",
5
5
  "keywords": [
6
6
  "react",
@@ -306,6 +306,10 @@
306
306
  "import": "./dist/hooks/ElementObserver/index.js",
307
307
  "require": "./dist/hooks/ElementObserver/index.cjs"
308
308
  },
309
+ "./hooks/FocusTrap": {
310
+ "import": "./dist/hooks/FocusTrap/index.js",
311
+ "require": "./dist/hooks/FocusTrap/index.cjs"
312
+ },
309
313
  "./hooks/GrabAndScroll": {
310
314
  "import": "./dist/hooks/GrabAndScroll/index.js",
311
315
  "require": "./dist/hooks/GrabAndScroll/index.cjs"
@@ -45,6 +45,7 @@ import { coreSupportedEventRequestToApiRequest } from 'src/application/utils/sup
45
45
  import { chatIdAtom, userIdAtom } from 'src/atoms/app'; // Import userIdAtom and chatIdAtom
46
46
  import { SupportedEvent } from 'src/atoms/app/variant';
47
47
  import { getAtomStore } from 'src/atoms/atomStore/atomStore';
48
+ import { resolvedBaseConfigVersionAtom } from 'src/atoms/envive/resolvedBaseConfigVersion';
48
49
  import {
49
50
  baseUrlAtom,
50
51
  contextSourceAtom,
@@ -166,7 +167,10 @@ class CommerceApiClient {
166
167
  };
167
168
 
168
169
  const overrideConfigVersion =
169
- getQueryParam('spiffy_config_version') || getQueryParam('envive_config_version') || undefined;
170
+ getQueryParam('spiffy_config_version') ||
171
+ getQueryParam('envive_config_version') ||
172
+ getAtomStore().get(resolvedBaseConfigVersionAtom) ||
173
+ undefined;
170
174
 
171
175
  const featureGates = featureFlagService?.featureFlagService?.getFeatureFlags() || {};
172
176
  const urlResolvingRequest = {
@@ -3,6 +3,10 @@ import { OrganizationConfig } from 'src/application/models/api/organizationConfi
3
3
  import { ColorMapping } from 'src/application/models/colorsConfig';
4
4
  import { FrontendConfig } from 'src/application/models/frontendConfig';
5
5
 
6
+ // Statsig experiment-layer namespace. Used by amplitudeService when emitting
7
+ // `experiment.{ns}.*` event properties.
8
+ export type ExperimentNamespace = 'ml' | 'merchant';
9
+
6
10
  export interface OrgConfigExperiment {
7
11
  group?: string;
8
12
  groupName?: string;
@@ -18,6 +22,29 @@ export interface OrgConfigFeatureGate {
18
22
  value?: boolean;
19
23
  }
20
24
 
25
+ // Statsig layer assignment as returned by /v1/org/config. Field names match
26
+ // the wire (snake_case); pymono drops the layer's `value` payload before
27
+ // serialization, so it isn't on this type.
28
+ export interface OrgConfigExperimentAssignment {
29
+ layer_name?: string;
30
+ namespace?: ExperimentNamespace;
31
+ allocated_experiment_name?: string | null;
32
+ group_name?: string | null;
33
+ }
34
+
35
+ // Metadata describing which version pymono picked for the user and why.
36
+ // Sourced from getWidgetConfig.resolution (GraphQL field names are camelCase
37
+ // per Ariadne's snake→camel auto-conversion). The client threads
38
+ // `baseVersion` into downstream inference requests so they're scoped to the
39
+ // same version that produced the widgets the user is seeing.
40
+ // `baseVersionSource === "deployed"` is the sentinel for "no merchant_layer
41
+ // pin, no override" — callers should treat that as "no override" and not
42
+ // pass `baseVersion` ("deployed") through as an explicit version pin.
43
+ export interface ExperimentConfigResolutionMetadata {
44
+ baseVersion?: string;
45
+ baseVersionSource?: string;
46
+ }
47
+
21
48
  export interface Organization {
22
49
  id: string;
23
50
  displayName: string;
@@ -28,4 +28,9 @@ export enum FeatureGates {
28
28
  IsAiSuggestionsVariantAEnabled = 'is_ai_suggestions_variant_a_enabled',
29
29
  IsAiSuggestionsVariantBEnabled = 'is_ai_suggestions_variant_b_enabled',
30
30
  IsVoiceInputEnabled = 'is_voice_input_enabled',
31
+ // Statsig experiments / unified getWidgetConfig endpoint migration. When
32
+ // true, EnviveConfigService calls getWidgetConfig (experiment-aware)
33
+ // instead of the legacy getProductsConfigByVersion / getColorsAndFrontend
34
+ // path.
35
+ UseUnifiedConfig = 'use_unified_config',
31
36
  }
@@ -0,0 +1,34 @@
1
+ // Statsig-experiment-aware unified config endpoint. Used when the
2
+ // `use_unified_config` feature gate is on. Selects productsConfig plus
3
+ // the resolution metadata pymono used to pick the version — the client
4
+ // threads `resolution.base_version` into downstream inference requests
5
+ // so they're scoped to the same version that produced the widgets the
6
+ // user is rendering. Gates and experiment assignments still come from
7
+ // REST /v1/org/config so AmplitudeService can read them synchronously
8
+ // before this query resolves. Once the migration completes this query
9
+ // will replace getColorsAndFrontendQuery entirely.
10
+ //
11
+ // userId is required by the schema (String!) and feeds Statsig layer
12
+ // resolution server-side.
13
+ //
14
+ // version is optional; when omitted (no `spiffy_config_version` /
15
+ // `envive_config_version` URL param) the resolver uses Statsig bucketing.
16
+ // When set, it bypasses Statsig and pins to that exact version — same
17
+ // debug/rollback affordance the legacy getColorsAndFrontendQuery offered.
18
+ export const getWidgetConfigQuery = () => `
19
+ query($userId: String!, $version: String) {
20
+ me {
21
+ getWidgetConfig(userId: $userId, version: $version) {
22
+ productsConfig {
23
+ frontend { values }
24
+ colors { values }
25
+ v_three_config { values }
26
+ }
27
+ resolution {
28
+ baseVersion
29
+ baseVersionSource
30
+ }
31
+ }
32
+ }
33
+ }
34
+ `;
@@ -0,0 +1,200 @@
1
+ import { ElementObserver } from '../elementObserver';
2
+ import { SelectorFactory } from '../nodeSelector';
3
+
4
+ function makeSelector(id: string) {
5
+ return SelectorFactory.id(id);
6
+ }
7
+
8
+ function appendDiv(id: string): HTMLDivElement {
9
+ const el = document.createElement('div');
10
+ el.id = id;
11
+ document.body.appendChild(el);
12
+ return el;
13
+ }
14
+
15
+ describe('ElementObserver', () => {
16
+ beforeEach(() => {
17
+ document.body.innerHTML = '';
18
+ });
19
+
20
+ describe('init / watch', () => {
21
+ it('calls onAdd with the element when it is already in the DOM at init time', () => {
22
+ appendDiv('target');
23
+ const observer = new ElementObserver(makeSelector('target'));
24
+ const onAdd = vi.fn();
25
+ observer.registerOnAdd(onAdd);
26
+
27
+ observer.init();
28
+
29
+ expect(onAdd).toHaveBeenCalledTimes(1);
30
+ expect(onAdd.mock.calls[0][0]).toBe(document.getElementById('target'));
31
+ });
32
+
33
+ it('does not call onAdd when the element is absent at init time', () => {
34
+ const observer = new ElementObserver(makeSelector('missing'));
35
+ const onAdd = vi.fn();
36
+ observer.registerOnAdd(onAdd);
37
+
38
+ observer.init();
39
+
40
+ expect(onAdd).not.toHaveBeenCalled();
41
+ });
42
+
43
+ it('getNode returns the watched element after init', () => {
44
+ appendDiv('target');
45
+ const observer = new ElementObserver(makeSelector('target'));
46
+ observer.init();
47
+
48
+ expect(observer.getNode()?.id).toBe('target');
49
+ });
50
+
51
+ it('getNode returns null before init', () => {
52
+ appendDiv('target');
53
+ const observer = new ElementObserver(makeSelector('target'));
54
+
55
+ expect(observer.getNode()).toBeNull();
56
+ });
57
+
58
+ it('calling watch twice on the same node does not fire onAdd a second time', () => {
59
+ const el = appendDiv('target');
60
+ const observer = new ElementObserver(makeSelector('target'));
61
+ const onAdd = vi.fn();
62
+ observer.registerOnAdd(onAdd);
63
+
64
+ observer.watch(el);
65
+ observer.watch(el);
66
+
67
+ expect(onAdd).toHaveBeenCalledTimes(1);
68
+ });
69
+ });
70
+
71
+ describe('destroy', () => {
72
+ it('calls onRemove with the element when destroyed', () => {
73
+ const el = appendDiv('target');
74
+ const observer = new ElementObserver(makeSelector('target'));
75
+ const onRemove = vi.fn();
76
+ observer.registerOnRemove(onRemove);
77
+ observer.watch(el);
78
+
79
+ observer.destroy();
80
+
81
+ expect(onRemove).toHaveBeenCalledTimes(1);
82
+ expect(onRemove.mock.calls[0][0]).toBe(el);
83
+ });
84
+
85
+ it('calls the reset function when destroyed', () => {
86
+ const el = appendDiv('target');
87
+ const observer = new ElementObserver(makeSelector('target'));
88
+ const onReset = vi.fn();
89
+ observer.registerOnReset(onReset);
90
+ observer.watch(el);
91
+
92
+ observer.destroy();
93
+
94
+ expect(onReset).toHaveBeenCalledTimes(1);
95
+ });
96
+
97
+ it('sets getNode to null after destroy', () => {
98
+ const el = appendDiv('target');
99
+ const observer = new ElementObserver(makeSelector('target'));
100
+ observer.watch(el);
101
+
102
+ observer.destroy();
103
+
104
+ expect(observer.getNode()).toBeNull();
105
+ });
106
+
107
+ it('calling destroy on an uninitialised observer does not throw', () => {
108
+ const observer = new ElementObserver(makeSelector('missing'));
109
+ expect(() => observer.destroy()).not.toThrow();
110
+ });
111
+ });
112
+
113
+ describe('show / hide', () => {
114
+ it('hides the node by setting display:none', () => {
115
+ const el = appendDiv('target');
116
+ const observer = new ElementObserver(makeSelector('target'));
117
+ observer.watch(el);
118
+
119
+ observer.hide();
120
+
121
+ expect(el.style.display).toBe('none');
122
+ });
123
+
124
+ it('restores display after a hide/show cycle', () => {
125
+ const el = appendDiv('target');
126
+ el.style.display = 'flex';
127
+ const observer = new ElementObserver(makeSelector('target'));
128
+ observer.watch(el);
129
+
130
+ observer.hide();
131
+ observer.show();
132
+
133
+ expect(el.style.display).toBe('flex');
134
+ });
135
+
136
+ it('show/hide are no-ops when node is null', () => {
137
+ const observer = new ElementObserver(makeSelector('missing'));
138
+ expect(() => {
139
+ observer.hide();
140
+ observer.show();
141
+ }).not.toThrow();
142
+ });
143
+ });
144
+
145
+ describe('event registration', () => {
146
+ it('registerEvent adds an event listener to the node', () => {
147
+ const el = appendDiv('target');
148
+ const observer = new ElementObserver(makeSelector('target'));
149
+ observer.watch(el);
150
+
151
+ const handler = vi.fn();
152
+ observer.registerEvent('click', handler);
153
+ el.dispatchEvent(new MouseEvent('click'));
154
+
155
+ expect(handler).toHaveBeenCalledTimes(1);
156
+ });
157
+
158
+ it('registerEvent replaces the previous listener for the same event type', () => {
159
+ const el = appendDiv('target');
160
+ const observer = new ElementObserver(makeSelector('target'));
161
+ observer.watch(el);
162
+
163
+ const first = vi.fn();
164
+ const second = vi.fn();
165
+ observer.registerEvent('click', first);
166
+ observer.registerEvent('click', second);
167
+
168
+ el.dispatchEvent(new MouseEvent('click'));
169
+
170
+ expect(first).not.toHaveBeenCalled();
171
+ expect(second).toHaveBeenCalledTimes(1);
172
+ });
173
+
174
+ it('event listeners are removed after destroy', () => {
175
+ const el = appendDiv('target');
176
+ const observer = new ElementObserver(makeSelector('target'));
177
+ observer.watch(el);
178
+
179
+ const handler = vi.fn();
180
+ observer.registerEvent('click', handler);
181
+ observer.destroy();
182
+
183
+ el.dispatchEvent(new MouseEvent('click'));
184
+
185
+ expect(handler).not.toHaveBeenCalled();
186
+ });
187
+ });
188
+
189
+ describe('fire', () => {
190
+ it('is a no-op (does not throw) when node is null', () => {
191
+ // fire() guards on this.node before constructing a MouseEvent,
192
+ // so an uninitialised observer must not throw.
193
+ const observer = new ElementObserver(makeSelector('missing'));
194
+ expect(() => observer.fire('click')).not.toThrow();
195
+ });
196
+ // Note: testing fire() on a live node is not possible in jsdom because
197
+ // jsdom rejects { view: window } in the MouseEvent constructor. The
198
+ // actual dispatch is covered by the E2E suite in a real browser.
199
+ });
200
+ });
@@ -6,7 +6,6 @@ export * from './divideArray';
6
6
  export * from './domObserver';
7
7
  export * from './elementObserver';
8
8
  export * from './imageFilter';
9
- export * from './merchantUtils';
10
9
  export * from './messageFromFormSubmittedEvent';
11
10
  export * from './messageFromQueryEvent';
12
11
  export * from './messageFromResponse';
@@ -0,0 +1,11 @@
1
+ import { atom } from 'jotai';
2
+
3
+ // The `base_version` pymono resolved for the current user on the unified
4
+ // path (sourced from getWidgetConfig.resolution, not REST). Read by
5
+ // commerce-api, salesAgentService, and hardcopyService as a fallback after
6
+ // the `spiffy_config_version` / `envive_config_version` URL params, so
7
+ // inference requests are scoped to the same version that produced the
8
+ // widgets the user is rendering. Undefined until the unified-path fetch
9
+ // completes, on the legacy path, and when the resolution sentinel
10
+ // `base_version_source === "deployed"` indicates no real pin to forward.
11
+ export const resolvedBaseConfigVersionAtom = atom<string | undefined>(undefined);
@@ -1,7 +1,9 @@
1
1
  import { ReactNode, useCallback, useEffect, useMemo, useRef, useState } from 'react';
2
+ import { useSetAtom } from 'jotai';
2
3
 
3
4
  import { AmplitudeService } from 'src/services/amplitudeService/amplitudeService';
4
5
  import { EnviveServiceConfig, IEnviveConfigService } from 'src/services/enviveConfigService';
6
+ import { resolvedBaseConfigVersionAtom } from 'src/atoms/envive/resolvedBaseConfigVersion';
5
7
  import { IHardcopyService } from 'src/services/hardcopyService';
6
8
  import { IUserIdentityService } from 'src/services/userIdentityService';
7
9
  import Logger from 'src/application/logging/logger';
@@ -102,6 +104,7 @@ export const EnviveProvider: React.FC<EnviveProviderProps> = ({
102
104
  }) => {
103
105
  const { extensionService } = services;
104
106
  const [enviveServiceConfig, setEnviveServiceConfig] = useState<EnviveServiceConfig | null>(null);
107
+ const setResolvedBaseConfigVersion = useSetAtom(resolvedBaseConfigVersionAtom);
105
108
  const didReportSuccessRef = useRef(false);
106
109
 
107
110
  const invokeExtensionCallback = useCallback((callback?: () => Promise<unknown> | void) => {
@@ -128,10 +131,26 @@ export const EnviveProvider: React.FC<EnviveProviderProps> = ({
128
131
  useEffect(() => {
129
132
  invokeExtensionCallback(extensionService?.onInjectionLoading);
130
133
 
134
+ // Clear any prior merchant's resolved version before the new fetch — the
135
+ // atom is module-level and survives EnviveProvider remounts (e.g. when
136
+ // Envive Hub switches merchants). Without the reset, the previous
137
+ // merchant's `baseVersion` would leak into the new merchant's inference
138
+ // requests when the new resolution falls back to the "deployed" sentinel
139
+ // and the conditional write below is skipped.
140
+ setResolvedBaseConfigVersion(undefined);
141
+
131
142
  const fetchEnviveConfig = async () => {
132
143
  try {
133
144
  const config = await services.enviveConfigService.getEnviveConfig();
134
145
  setEnviveServiceConfig(config);
146
+ // Forward only real pins to inference. baseVersionSource === "deployed"
147
+ // is the sentinel for "no merchant_layer, no override" — leaving the
148
+ // atom undefined lets inference fall through to backend's default
149
+ // version selection instead of pinning to the literal string "deployed".
150
+ const { baseVersion, baseVersionSource } = config.orgConfig?.resolution ?? {};
151
+ if (baseVersion && baseVersionSource && baseVersionSource !== 'deployed') {
152
+ setResolvedBaseConfigVersion(baseVersion);
153
+ }
135
154
  } catch (error) {
136
155
  const resolvedError =
137
156
  error instanceof Error ? error : new Error('Failed to load envive config');
@@ -146,6 +165,7 @@ export const EnviveProvider: React.FC<EnviveProviderProps> = ({
146
165
  extensionService,
147
166
  invokeExtensionCallback,
148
167
  invokeExtensionErrorCallback,
168
+ setResolvedBaseConfigVersion,
149
169
  ]);
150
170
 
151
171
  useEffect(() => {
@@ -4,6 +4,7 @@ import { baseUrlAtom, orgLevelApiKeyAtom } from 'src/atoms/envive/enviveConfig';
4
4
  import { ColorMapping } from 'src/application/models/colorsConfig';
5
5
  import { FrontendConfig } from 'src/application/models/frontendConfig';
6
6
  import { CamelCasedPropertiesDeep } from 'src/application/models';
7
+ import { ExperimentConfigResolutionMetadata } from 'src/application/models/api/orgConfigResults';
7
8
  import { FrontendConfigV3 } from 'src/application/models/frontendConfigV3';
8
9
  import { ColorMappingV3 } from 'src/application/models/colorsConfigV3';
9
10
  import { OrgPageConfig } from '../types';
@@ -17,6 +18,10 @@ export type GraphQlConfigValues = {
17
18
  colorsConfig?: ColorsConfigResponse | ColorsConfigV3Response;
18
19
  frontendConfig?: CamelCasedPropertiesDeep<FrontendConfig | FrontendConfigV3>;
19
20
  orgPageConfig?: OrgPageConfig;
21
+ // Populated only by the unified-path fetcher (getWidgetConfig.resolution).
22
+ // Legacy getColorsAndFrontendQuery does not return it. Read by EnviveProvider
23
+ // to thread baseVersion into inference requests as override_config_version.
24
+ resolution?: ExperimentConfigResolutionMetadata;
20
25
  };
21
26
 
22
27
  interface GraphQLContextValue {
@@ -15,6 +15,7 @@ import {
15
15
  import { messageFromResponse } from 'src/application/utils';
16
16
  import { appDetailsAtom } from 'src/atoms/app';
17
17
  import { analyticsContextAtom } from 'src/atoms/app/variant';
18
+ import { resolvedBaseConfigVersionAtom } from 'src/atoms/envive/resolvedBaseConfigVersion';
18
19
  import {
19
20
  messagesAtom,
20
21
  pendingResponseAtom,
@@ -247,6 +248,7 @@ export const useSalesAgentService: () => SalesAgentService = () => {
247
248
 
248
249
  const featureFlagService = useFeatureFlagService();
249
250
  const context = useAtomValue(appDetailsAtom);
251
+ const resolvedBaseConfigVersion = useAtomValue(resolvedBaseConfigVersionAtom);
250
252
 
251
253
  const createResponsePayload = useCallback(
252
254
  ({
@@ -261,6 +263,7 @@ export const useSalesAgentService: () => SalesAgentService = () => {
261
263
  const overrideConfigVersion =
262
264
  getQueryParam('spiffy_config_version') ||
263
265
  getQueryParam('envive_config_version') ||
266
+ resolvedBaseConfigVersion ||
264
267
  undefined;
265
268
  const overrideModelDatetime = getQueryParam('override_model_datetime') || undefined;
266
269
  return {
@@ -273,7 +276,7 @@ export const useSalesAgentService: () => SalesAgentService = () => {
273
276
  overrideModelDatetime,
274
277
  };
275
278
  },
276
- [context, featureFlagService?.featureFlagService],
279
+ [context, featureFlagService?.featureFlagService, resolvedBaseConfigVersion],
277
280
  );
278
281
 
279
282
  const getStreamingResponses = useCallback(