@envive-ai/react-hooks 0.2.6 → 0.2.7-arthur-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 (377) hide show
  1. package/dist/{NewOrgConfig-BfrGpiGk.js → NewOrgConfig-BVByiYPp.js} +2 -2
  2. package/dist/{NewOrgConfig-BxSuoP9C.cjs → NewOrgConfig-CInGtTV6.cjs} +2 -2
  3. package/dist/{SystemSettingsContext-Bkoiobdv.cjs → SystemSettingsContext-150LTxIk.cjs} +2 -2
  4. package/dist/{SystemSettingsContext-B8X_Dvw2.js → SystemSettingsContext-ei5B0dxO.js} +2 -2
  5. package/dist/{TrackComponentVisibleEvent-DMuX-byo.cjs → TrackComponentVisibleEvent-C7-nnBks.cjs} +2 -2
  6. package/dist/{TrackComponentVisibleEvent-DwfGqNTx.js → TrackComponentVisibleEvent-CuwSLbug.js} +2 -2
  7. package/dist/amplitudeContext-BBQ1ATA3.js +265 -0
  8. package/dist/amplitudeContext-BItT9HmT.js +1 -0
  9. package/dist/amplitudeContext-C-0-DDk3.cjs +287 -0
  10. package/dist/{amplitudeContext-B73xamNe.d.cts → amplitudeContext-CCVyp5RU.d.cts} +1 -1
  11. package/dist/amplitudeContext-DPtyVv3Q.cjs +0 -0
  12. package/dist/{amplitudeContext-CiO9T9c-.d.ts → amplitudeContext-DcRur97Z.d.ts} +1 -1
  13. package/dist/{api-bHEYmSiT.js → api-BWSsazAG.js} +3 -3
  14. package/dist/{api-BvygKEiX.cjs → api-DeW6rHj3.cjs} +3 -3
  15. package/dist/{app-Aqkm_SlS.js → app-C_Y-57U5.js} +3 -4
  16. package/dist/{app-BQw_-JGl.cjs → app-XEFPotoH.cjs} +3 -4
  17. package/dist/application/models/graphql/index.cjs +4 -3
  18. package/dist/application/models/graphql/index.d.cts +2 -2
  19. package/dist/application/models/graphql/index.d.ts +2 -2
  20. package/dist/application/models/graphql/index.js +3 -3
  21. package/dist/application/models/guards/api/index.cjs +3 -3
  22. package/dist/application/models/guards/api/index.d.cts +2 -1
  23. package/dist/application/models/guards/api/index.d.ts +2 -1
  24. package/dist/application/models/guards/api/index.js +3 -3
  25. package/dist/application/models/guards/utils.cjs +1 -1
  26. package/dist/application/models/guards/utils.d.cts +1 -1
  27. package/dist/application/models/guards/utils.d.ts +1 -1
  28. package/dist/application/models/guards/utils.js +1 -1
  29. package/dist/application/models/index.cjs +9 -9
  30. package/dist/application/models/index.d.cts +11 -10
  31. package/dist/application/models/index.d.ts +11 -10
  32. package/dist/application/models/index.js +8 -8
  33. package/dist/application/models/variantInfo/index.d.cts +1 -1
  34. package/dist/application/models/variantInfo/index.d.ts +1 -1
  35. package/dist/application/utils/index.cjs +17 -17
  36. package/dist/application/utils/index.d.cts +16 -15
  37. package/dist/application/utils/index.d.ts +16 -15
  38. package/dist/application/utils/index.js +17 -17
  39. package/dist/{atomStore-CmZbgQHc.cjs → atomStore-8ppNkJ_n.cjs} +1 -1
  40. package/dist/{atomStore-DEcDhiLp.js → atomStore-BLYJ2ZoQ.js} +1 -1
  41. package/dist/atoms/app/index.cjs +12 -12
  42. package/dist/atoms/app/index.d.cts +19 -18
  43. package/dist/atoms/app/index.d.ts +14 -13
  44. package/dist/atoms/app/index.js +12 -12
  45. package/dist/atoms/atomStore/index.cjs +1 -1
  46. package/dist/atoms/atomStore/index.js +1 -1
  47. package/dist/atoms/chat/index.cjs +18 -18
  48. package/dist/atoms/chat/index.d.cts +39 -38
  49. package/dist/atoms/chat/index.d.ts +13 -12
  50. package/dist/atoms/chat/index.js +18 -18
  51. package/dist/atoms/globalSearch/index.d.cts +5 -5
  52. package/dist/atoms/org/index.cjs +1 -1
  53. package/dist/atoms/org/index.d.cts +30 -29
  54. package/dist/atoms/org/index.d.ts +30 -29
  55. package/dist/atoms/org/index.js +1 -1
  56. package/dist/atoms/search/index.cjs +20 -20
  57. package/dist/atoms/search/index.d.cts +13 -12
  58. package/dist/atoms/search/index.d.ts +13 -12
  59. package/dist/atoms/search/index.js +20 -20
  60. package/dist/atoms/search/types.d.cts +4 -2
  61. package/dist/atoms/search/types.d.ts +4 -2
  62. package/dist/{cdnContext-Cd0Kvt6g.cjs → cdnContext-Bzqk0s2M.cjs} +2 -2
  63. package/dist/{cdnContext-D8pHA9gh.js → cdnContext-CTC-zBtx.js} +2 -2
  64. package/dist/{chat-U1IgKNij.js → chat-Bzay7QnI.js} +9 -9
  65. package/dist/{chat-DwNALtox.cjs → chat-Ckd1b_z_.cjs} +14 -8
  66. package/dist/{chat-EJbfGWRr.js → chat-ClvJ9xEj.js} +1 -1
  67. package/dist/{chat-CJ9D8n7g.cjs → chat-DCGriB7h.cjs} +1 -1
  68. package/dist/{chatElementDisplayLocation-DWmfNX_u.d.cts → chatElementDisplayLocation-B7vr33eG.d.cts} +1 -1
  69. package/dist/{chatElementDisplayLocation-DbmdwAff.d.ts → chatElementDisplayLocation-D4XF0UfI.d.ts} +1 -1
  70. package/dist/{chatSearch-DtE2cUQw.cjs → chatSearch-Bev4ZI8Z.cjs} +4 -4
  71. package/dist/{chatSearch-Bb2SMr9X.js → chatSearch-DNaGtQyx.js} +4 -4
  72. package/dist/{chatState-BXBN-12W.js → chatState-CcCvgmSM.js} +3 -3
  73. package/dist/{chatState-B3Dyrd9M.cjs → chatState-OkYPVghN.cjs} +3 -3
  74. package/dist/{commerce-api-DXbnMNT8.js → commerce-api-ml5fkEuk.js} +9 -8
  75. package/dist/{commerce-api-Dx02FCQ7.cjs → commerce-api-sQtLuwTh.cjs} +9 -8
  76. package/dist/{common-CuwWqIJ1.cjs → common-DQPvV_S_.cjs} +1 -1
  77. package/dist/{common-Df2bwzd2.js → common-c_4eX0qn.js} +1 -1
  78. package/dist/{components-QGCWJ26c.js → components-CDpaMUjK.js} +1 -1
  79. package/dist/{components-BCfFLf9X.cjs → components-DKwVHIjq.cjs} +1 -1
  80. package/dist/config/index.cjs +4 -4
  81. package/dist/config/index.d.cts +4 -4
  82. package/dist/config/index.d.ts +4 -4
  83. package/dist/config/index.js +4 -4
  84. package/dist/config/locators/components/chat/index.cjs +1 -1
  85. package/dist/config/locators/components/chat/index.d.cts +1 -1
  86. package/dist/config/locators/components/chat/index.d.ts +1 -1
  87. package/dist/config/locators/components/chat/index.js +1 -1
  88. package/dist/config/locators/components/common/index.cjs +1 -1
  89. package/dist/config/locators/components/common/index.d.cts +1 -1
  90. package/dist/config/locators/components/common/index.d.ts +1 -1
  91. package/dist/config/locators/components/common/index.js +1 -1
  92. package/dist/config/locators/components/index.cjs +1 -1
  93. package/dist/config/locators/components/index.d.cts +1 -1
  94. package/dist/config/locators/components/index.d.ts +1 -1
  95. package/dist/config/locators/components/index.js +1 -1
  96. package/dist/config/locators/index.cjs +4 -4
  97. package/dist/config/locators/index.d.cts +4 -4
  98. package/dist/config/locators/index.d.ts +4 -4
  99. package/dist/config/locators/index.js +4 -4
  100. package/dist/contexts/amplitudeContext/index.cjs +17 -16
  101. package/dist/contexts/amplitudeContext/index.d.cts +1 -1
  102. package/dist/contexts/amplitudeContext/index.d.ts +1 -1
  103. package/dist/contexts/amplitudeContext/index.js +17 -16
  104. package/dist/contexts/cdnContext/index.cjs +4 -4
  105. package/dist/contexts/cdnContext/index.js +4 -4
  106. package/dist/contexts/chatContext/index.cjs +25 -25
  107. package/dist/contexts/chatContext/index.d.cts +2 -2
  108. package/dist/contexts/chatContext/index.d.ts +2 -2
  109. package/dist/contexts/chatContext/index.js +25 -25
  110. package/dist/contexts/enviveConfigContext/index.cjs +4 -4
  111. package/dist/contexts/enviveConfigContext/index.d.cts +3 -3
  112. package/dist/contexts/enviveConfigContext/index.d.ts +3 -3
  113. package/dist/contexts/enviveConfigContext/index.js +4 -4
  114. package/dist/contexts/enviveCssContext/index.cjs +15 -15
  115. package/dist/contexts/enviveCssContext/index.js +15 -15
  116. package/dist/contexts/featureFlagContext/index.cjs +6 -6
  117. package/dist/contexts/featureFlagContext/index.d.cts +3 -3
  118. package/dist/contexts/featureFlagContext/index.d.ts +3 -3
  119. package/dist/contexts/featureFlagContext/index.js +6 -6
  120. package/dist/contexts/featureFlagServiceContext/index.cjs +3 -3
  121. package/dist/contexts/featureFlagServiceContext/index.d.cts +4 -4
  122. package/dist/contexts/featureFlagServiceContext/index.d.ts +4 -4
  123. package/dist/contexts/featureFlagServiceContext/index.js +3 -3
  124. package/dist/contexts/graphqlContext/index.cjs +11 -11
  125. package/dist/contexts/graphqlContext/index.d.cts +13 -12
  126. package/dist/contexts/graphqlContext/index.d.ts +13 -12
  127. package/dist/contexts/graphqlContext/index.js +11 -11
  128. package/dist/contexts/localStorageContext/index.cjs +2 -2
  129. package/dist/contexts/localStorageContext/index.js +2 -2
  130. package/dist/contexts/newOrgConfigContext/index.cjs +14 -14
  131. package/dist/contexts/newOrgConfigContext/index.d.cts +14 -13
  132. package/dist/contexts/newOrgConfigContext/index.d.ts +14 -13
  133. package/dist/contexts/newOrgConfigContext/index.js +14 -14
  134. package/dist/contexts/searchContext/index.cjs +18 -18
  135. package/dist/contexts/searchContext/index.d.cts +1 -1
  136. package/dist/contexts/searchContext/index.d.ts +1 -1
  137. package/dist/contexts/searchContext/index.js +18 -18
  138. package/dist/contexts/sessionStorageContext/index.cjs +2 -2
  139. package/dist/contexts/sessionStorageContext/index.js +2 -2
  140. package/dist/contexts/shopifyUrlContext/index.cjs +2 -2
  141. package/dist/contexts/shopifyUrlContext/index.d.cts +3 -3
  142. package/dist/contexts/shopifyUrlContext/index.d.ts +3 -3
  143. package/dist/contexts/shopifyUrlContext/index.js +2 -2
  144. package/dist/contexts/systemSettingsContext/index.cjs +4 -4
  145. package/dist/contexts/systemSettingsContext/index.d.cts +16 -15
  146. package/dist/contexts/systemSettingsContext/index.d.ts +16 -15
  147. package/dist/contexts/systemSettingsContext/index.js +4 -4
  148. package/dist/contexts/types.cjs +1 -1
  149. package/dist/contexts/types.d.cts +3 -3
  150. package/dist/contexts/types.d.ts +3 -3
  151. package/dist/contexts/types.js +1 -1
  152. package/dist/contexts/userIdentityContext/index.cjs +20 -20
  153. package/dist/contexts/userIdentityContext/index.d.cts +1 -1
  154. package/dist/contexts/userIdentityContext/index.d.ts +1 -1
  155. package/dist/contexts/userIdentityContext/index.js +20 -20
  156. package/dist/{enviveConfig-BlIkxiAF.js → enviveConfig-DV8F12B9.js} +3 -3
  157. package/dist/{enviveConfig-B42OJ8bK.cjs → enviveConfig-DZHdtLsQ.cjs} +3 -3
  158. package/dist/{enviveConfigContext-1_EivtCa.js → enviveConfigContext-BS7aNop5.js} +3 -3
  159. package/dist/{enviveConfigContext-Y1ahEAMe.cjs → enviveConfigContext-CTcHUIFP.cjs} +3 -3
  160. package/dist/{featureFlagServiceContext-D3Ge8GH5.cjs → featureFlagServiceContext-CJyYItqu.cjs} +3 -3
  161. package/dist/{featureFlagServiceContext-C5U0bshi.d.ts → featureFlagServiceContext-CpxlOkI9.d.ts} +2 -2
  162. package/dist/{featureFlagServiceContext-CAPrb4e_.js → featureFlagServiceContext-FBM6DdMJ.js} +3 -3
  163. package/dist/{featureFlagServiceContext-CiKWV306.d.cts → featureFlagServiceContext-p5UBwPM3.d.cts} +2 -2
  164. package/dist/{featureGates-D4Me_IZH.js → featureGates-KEwAL8p_.js} +1 -1
  165. package/dist/{featureGates-Bt_Y3kZ7.cjs → featureGates-qU_ulhpC.cjs} +1 -1
  166. package/dist/{frontendConfig-BiD1-j48.d.ts → frontendConfig-Cawh5iqv.d.ts} +6 -3
  167. package/dist/{frontendConfig-tVg0hsWZ.d.cts → frontendConfig-iZipB5FG.d.cts} +6 -3
  168. package/dist/graphql-CkxgqsXP.js +48 -0
  169. package/dist/graphql-i3dtpVTl.cjs +71 -0
  170. package/dist/{graphqlContext-Bf3E-V2T.d.cts → graphqlContext-BeyKU1Dr.d.cts} +2 -2
  171. package/dist/{graphqlContext-CpwAvnro.cjs → graphqlContext-CVbYIftg.cjs} +6 -6
  172. package/dist/{graphqlContext-CDeKzb46.d.ts → graphqlContext-DgkS-UX1.d.ts} +4 -4
  173. package/dist/{graphqlContext-dyWNSWNv.js → graphqlContext-DouNZbYo.js} +5 -5
  174. package/dist/hooks/AmplitudeOperations/index.cjs +18 -18
  175. package/dist/hooks/AmplitudeOperations/index.d.cts +1 -1
  176. package/dist/hooks/AmplitudeOperations/index.d.ts +1 -1
  177. package/dist/hooks/AmplitudeOperations/index.js +18 -18
  178. package/dist/hooks/AppDetails/index.cjs +15 -15
  179. package/dist/hooks/AppDetails/index.d.cts +12 -11
  180. package/dist/hooks/AppDetails/index.d.ts +12 -11
  181. package/dist/hooks/AppDetails/index.js +15 -15
  182. package/dist/hooks/CdnOperations/index.cjs +4 -4
  183. package/dist/hooks/CdnOperations/index.js +4 -4
  184. package/dist/hooks/ChatToggle/index.cjs +18 -18
  185. package/dist/hooks/ChatToggle/index.d.cts +1 -1
  186. package/dist/hooks/ChatToggle/index.d.ts +1 -1
  187. package/dist/hooks/ChatToggle/index.js +18 -18
  188. package/dist/hooks/ChatToggleAnalytics/index.cjs +19 -19
  189. package/dist/hooks/ChatToggleAnalytics/index.d.cts +1 -1
  190. package/dist/hooks/ChatToggleAnalytics/index.d.ts +1 -1
  191. package/dist/hooks/ChatToggleAnalytics/index.js +19 -19
  192. package/dist/hooks/CustomerSupportHandoff/index.cjs +1 -1
  193. package/dist/hooks/CustomerSupportHandoff/index.js +1 -1
  194. package/dist/hooks/Debounce/index.cjs +20 -2
  195. package/dist/hooks/Debounce/index.js +18 -2
  196. package/dist/hooks/ElementObserver/index.d.cts +1 -1
  197. package/dist/hooks/ElementObserver/index.d.ts +1 -1
  198. package/dist/hooks/GrabAndScroll/index.d.ts +2 -2
  199. package/dist/hooks/GraphQLConfig/index.cjs +12 -12
  200. package/dist/hooks/GraphQLConfig/index.d.cts +13 -12
  201. package/dist/hooks/GraphQLConfig/index.d.ts +13 -12
  202. package/dist/hooks/GraphQLConfig/index.js +12 -12
  203. package/dist/hooks/IdentifyUser/index.cjs +20 -20
  204. package/dist/hooks/IdentifyUser/index.js +20 -20
  205. package/dist/hooks/ImageResolver/index.cjs +10 -10
  206. package/dist/hooks/ImageResolver/index.js +10 -10
  207. package/dist/hooks/LocalStorageOperations/index.cjs +2 -2
  208. package/dist/hooks/LocalStorageOperations/index.js +2 -2
  209. package/dist/hooks/MessageFilter/index.cjs +8 -8
  210. package/dist/hooks/MessageFilter/index.d.cts +12 -11
  211. package/dist/hooks/MessageFilter/index.d.ts +12 -11
  212. package/dist/hooks/MessageFilter/index.js +8 -8
  213. package/dist/hooks/NewOrgConfig/index.cjs +15 -15
  214. package/dist/hooks/NewOrgConfig/index.d.cts +14 -13
  215. package/dist/hooks/NewOrgConfig/index.d.ts +14 -13
  216. package/dist/hooks/NewOrgConfig/index.js +15 -15
  217. package/dist/hooks/Search/index.cjs +323 -152
  218. package/dist/hooks/Search/index.d.cts +21 -17
  219. package/dist/hooks/Search/index.d.ts +21 -17
  220. package/dist/hooks/Search/index.js +323 -153
  221. package/dist/hooks/SearchOperations/index.cjs +18 -18
  222. package/dist/hooks/SearchOperations/index.d.cts +1 -1
  223. package/dist/hooks/SearchOperations/index.d.ts +1 -1
  224. package/dist/hooks/SearchOperations/index.js +18 -18
  225. package/dist/hooks/SessionStorageOperations/index.cjs +2 -2
  226. package/dist/hooks/SessionStorageOperations/index.js +2 -2
  227. package/dist/hooks/ShopifyUrlOperations/index.cjs +2 -2
  228. package/dist/hooks/ShopifyUrlOperations/index.d.cts +5 -5
  229. package/dist/hooks/ShopifyUrlOperations/index.d.ts +5 -5
  230. package/dist/hooks/ShopifyUrlOperations/index.js +2 -2
  231. package/dist/hooks/SystemSettingsContext/index.cjs +5 -5
  232. package/dist/hooks/SystemSettingsContext/index.d.cts +12 -11
  233. package/dist/hooks/SystemSettingsContext/index.d.ts +14 -13
  234. package/dist/hooks/SystemSettingsContext/index.js +5 -5
  235. package/dist/hooks/TrackComponentVisibleEvent/index.cjs +17 -17
  236. package/dist/hooks/TrackComponentVisibleEvent/index.d.cts +2 -2
  237. package/dist/hooks/TrackComponentVisibleEvent/index.d.ts +2 -2
  238. package/dist/hooks/TrackComponentVisibleEvent/index.js +17 -17
  239. package/dist/hooks/UpdateAnalyticsProps/index.cjs +16 -16
  240. package/dist/hooks/UpdateAnalyticsProps/index.js +16 -16
  241. package/dist/hooks/utils.d.cts +12 -11
  242. package/dist/hooks/utils.d.ts +12 -11
  243. package/dist/{index-B6xpW8RG.d.ts → index--9_c4tze.d.ts} +1 -1
  244. package/dist/index-BEpDGqnz.d.cts +41 -0
  245. package/dist/{index-D31m6bPU.d.ts → index-BKvFVPUX.d.ts} +1 -1
  246. package/dist/{index-VwfWqyR_.d.ts → index-BNHIIgYk.d.ts} +1 -1
  247. package/dist/index-BUDrAxnl.d.ts +673 -0
  248. package/dist/{index-DzbkQtaK.d.cts → index-CCboEuTO.d.cts} +1 -1
  249. package/dist/{index-wFHfdr6p.d.ts → index-CMJM-3zV.d.ts} +5 -5
  250. package/dist/{index-FQjyuD3D.d.cts → index-COXkY78t.d.cts} +1 -1
  251. package/dist/{index--uHjE7L8.d.ts → index-D7htGSQC.d.ts} +1 -1
  252. package/dist/index-DM_5fh8c.d.ts +101 -0
  253. package/dist/index-DU7uw0ba.d.cts +101 -0
  254. package/dist/{index-Da1s8h5C.d.cts → index-DZtnHhlr.d.cts} +1 -1
  255. package/dist/{index-Bq39XSmY.d.cts → index-DpJzjjpi.d.cts} +34 -34
  256. package/dist/{index-DSRs6N6J.d.ts → index-Dtw-hJdt.d.ts} +1 -1
  257. package/dist/index-Dy3TTIOm.d.cts +673 -0
  258. package/dist/index-ErVcwUnR.d.ts +41 -0
  259. package/dist/{index-Cyq5HiC0.d.cts → index-OkKEOL6H.d.cts} +1 -1
  260. package/dist/{index-9NE86em3.d.cts → index-hAqp0oYb.d.cts} +1 -1
  261. package/dist/interceptors/index.d.cts +13 -12
  262. package/dist/interceptors/index.d.ts +13 -12
  263. package/dist/interceptors/types.d.cts +12 -11
  264. package/dist/interceptors/types.d.ts +12 -11
  265. package/dist/{localStorageContext-DAOJ4be4.js → localStorageContext-CqcSvg2H.js} +2 -2
  266. package/dist/{localStorageContext-C5giszHn.cjs → localStorageContext-DiLfSsqL.cjs} +2 -2
  267. package/dist/{locators-C2fWd-74.js → locators-BMQGmGLq.js} +1 -1
  268. package/dist/{locators-Cx3q6Z_h.cjs → locators-DxYdak1F.cjs} +1 -1
  269. package/dist/{logger-0D_8Ip2L.cjs → logger-TBIl4uIH.cjs} +1 -1
  270. package/dist/{logger-Co0IA3k5.js → logger-W3lqg-4b.js} +1 -1
  271. package/dist/models-CWOgrLCm.js +1284 -0
  272. package/dist/models-DqdLOi2I.cjs +1519 -0
  273. package/dist/{newOrgConfigContext-BMvcqPzD.cjs → newOrgConfigContext-BIDz4ZuO.cjs} +4 -4
  274. package/dist/{newOrgConfigContext-DOdUxlOE.d.cts → newOrgConfigContext-CJI3tsVV.d.cts} +2 -2
  275. package/dist/{newOrgConfigContext-BVyJExeW.d.ts → newOrgConfigContext-CKn7B2rj.d.ts} +2 -2
  276. package/dist/{newOrgConfigContext-6mlrvr1w.js → newOrgConfigContext-u_9UPNcX.js} +4 -4
  277. package/dist/{nodeSelector-DYhDUi7v.d.ts → nodeSelector-B5NfnUHv.d.ts} +1 -1
  278. package/dist/{nodeSelector-B3bPtEjX.d.cts → nodeSelector-vKB44CDB.d.cts} +1 -1
  279. package/dist/{orgAnalyticsConfig-Bm23fw4s.cjs → orgAnalyticsConfig-CGEQtAFs.cjs} +1 -1
  280. package/dist/{orgAnalyticsConfig-CpBmga08.js → orgAnalyticsConfig-i4jozLBB.js} +1 -1
  281. package/dist/responseGenerics-D9bS-Dd6.d.ts +148 -0
  282. package/dist/{index-Cx9e-fRi.d.ts → responseGenerics-DWLV09cQ.d.cts} +4 -40
  283. package/dist/{search-y-ioX5Mz.d.cts → search-6RrxBXD6.d.cts} +1 -1
  284. package/dist/{search-D-UfTjB7.cjs → search-CTVX9gC6.cjs} +2 -2
  285. package/dist/{search-B1OtJe8Z.d.ts → search-DrJiCT7d.d.ts} +1 -1
  286. package/dist/{search-yawhMv22.js → search-NgNrXNS9.js} +2 -2
  287. package/dist/{search-filter-types-BxaNSLs_.d.cts → search-filter-types-BItKtezf.d.cts} +1 -1
  288. package/dist/{search-filter-types-OI9zH3E_.d.ts → search-filter-types-CGFhksO3.d.ts} +1 -1
  289. package/dist/{searchContext-CFuwIIW-.cjs → searchContext-CnDXkawZ.cjs} +6 -6
  290. package/dist/{searchContext-CiqOqTJL.js → searchContext-DtRmshTA.js} +6 -6
  291. package/dist/{sessionStorageContext-BmCW091C.cjs → sessionStorageContext-1Ks_d4Z0.cjs} +2 -2
  292. package/dist/{sessionStorageContext-CNxkqJi1.js → sessionStorageContext-CDcl7NVl.js} +2 -2
  293. package/dist/{shopifyUrlContext-aZMwCfbJ.cjs → shopifyUrlContext-CxjV3qvH.cjs} +2 -2
  294. package/dist/{shopifyUrlContext-BXbI0PIG.js → shopifyUrlContext-D2btP_lY.js} +2 -2
  295. package/dist/{spiffyWidgets-CvEJIuJx.d.ts → spiffyWidgets-CR6F7FRE.d.ts} +1 -1
  296. package/dist/{spiffyWidgets-BuS00VaQ.d.cts → spiffyWidgets-eNbU1gMc.d.cts} +1 -1
  297. package/dist/{systemSettingsContext-SozpUezn.cjs → systemSettingsContext-BejoGzzB.cjs} +2 -2
  298. package/dist/{systemSettingsContext-kz6yyiFF.js → systemSettingsContext-C4dtZ0uZ.js} +2 -2
  299. package/dist/{test-types-DRhqHXw-.d.ts → test-types-BEml_bm3.d.ts} +1 -1
  300. package/dist/{test-types-ThQiO_cc.d.cts → test-types-Dsu8RJZu.d.cts} +1 -1
  301. package/dist/types/index.d.cts +2 -2
  302. package/dist/types/index.d.ts +2 -2
  303. package/dist/{types-r0Z6CwyF.d.ts → types-4LQ7LUCk.d.ts} +2 -2
  304. package/dist/types-BegmH0S1.d.ts +60 -0
  305. package/dist/types-BuvXXGxE.cjs +1 -1
  306. package/dist/types-CtUb63bt.js +76 -0
  307. package/dist/{types-zQGBI-Yo.d.cts → types-DFsSqmWx.d.cts} +2 -2
  308. package/dist/types-DWorwfS-.d.cts +60 -0
  309. package/dist/types-DXnG1tV0.js +1 -1
  310. package/dist/types-UUvB6h05.cjs +106 -0
  311. package/dist/types.d.cts +3 -3
  312. package/dist/types.d.ts +3 -3
  313. package/dist/{unsupportedProductExceptions-B4f9aLjr.cjs → unsupportedProductExceptions-B0yx2bHK.cjs} +1 -1
  314. package/dist/{unsupportedProductExceptions-DlmraJm8.js → unsupportedProductExceptions-Cs66ngs3.js} +1 -1
  315. package/dist/{urlsParser-DhcEZLc_.cjs → urlsParser-COzMdJaX.cjs} +1 -1
  316. package/dist/{urlsParser-DLCzibqU.js → urlsParser-DxjoLj98.js} +1 -1
  317. package/dist/{useAmplitudeOperations-D0nvIYlt.cjs → useAmplitudeOperations-BJXD9v2u.cjs} +2 -2
  318. package/dist/{useAmplitudeOperations-Dhks3PgF.js → useAmplitudeOperations-Dym0Ker8.js} +2 -2
  319. package/dist/{useAppDetails-qyaQIbWE.js → useAppDetails-Dmh16bWE.js} +4 -4
  320. package/dist/{useAppDetails-B9sGmpJ3.cjs → useAppDetails-DsAZ1xQn.cjs} +4 -4
  321. package/dist/{useGraphQLConfig-CgKEfVYc.cjs → useGraphQLConfig-B3DlwmGg.cjs} +2 -2
  322. package/dist/{useGraphQLConfig-BccQUaeW.js → useGraphQLConfig-DSRaDTdT.js} +2 -2
  323. package/dist/{userIdentityContext-BKLedN4R.d.ts → userIdentityContext-C6kApbuk.d.ts} +1 -1
  324. package/dist/userIdentityContext-DF3atBFE.js +119 -0
  325. package/dist/userIdentityContext-DpQTduhF.cjs +136 -0
  326. package/dist/{userIdentityContext-D2oFVFzo.d.cts → userIdentityContext-kU1PIo8K.d.cts} +1 -1
  327. package/dist/{utils-DFPt3FSw.js → utils-B7KTAEmV.js} +4 -4
  328. package/dist/{utils-BhyZiDrE.d.ts → utils-BRkGP1eb.d.ts} +1 -1
  329. package/dist/{utils-B7PAzB_M.d.cts → utils-CBD4g2Nc.d.cts} +4 -4
  330. package/dist/{utils-C6imnLBo.cjs → utils-CDw74BCO.cjs} +1 -1
  331. package/dist/{utils-Cazq8Q3q.cjs → utils-CcC2jZRi.cjs} +4 -4
  332. package/dist/{utils-B3x_9JTY.d.cts → utils-DCrwX6FT.d.cts} +1 -1
  333. package/dist/{utils-C4ci_t0-.js → utils-DIvMgPe8.js} +1 -1
  334. package/dist/{utils-B1v0iXs3.d.ts → utils-QKFAbPT6.d.ts} +4 -4
  335. package/package.json +7 -2
  336. package/src/application/commerce-api.ts +2 -0
  337. package/src/application/models/graphql/index.ts +1 -0
  338. package/src/atoms/app/index.ts +1 -1
  339. package/src/atoms/search/productRetrievalAPI.ts +70 -0
  340. package/src/atoms/search/productRetrievalAdapter.ts +25 -0
  341. package/src/atoms/search/types.ts +13 -0
  342. package/src/contexts/amplitudeContext/__tests__/amplitudeContext.test.tsx +525 -0
  343. package/src/contexts/amplitudeContext/amplitudeContext.tsx +5 -2
  344. package/src/contexts/graphqlContext/__tests__/graphqlContext.test.tsx +790 -0
  345. package/src/contexts/localStorageContext/__tests__/localStorageContext.test.tsx +775 -0
  346. package/src/contexts/newOrgConfigContext/__tests__/newOrgConfigContext.test.tsx +495 -0
  347. package/src/contexts/searchContext/__tests__/searchContext.test.tsx +806 -0
  348. package/src/contexts/systemSettingsContext/__tests__/systemSettingsContext.test.tsx +506 -0
  349. package/src/contexts/types.ts +3 -0
  350. package/src/contexts/userIdentityContext/userIdentityContext.tsx +7 -5
  351. package/src/hooks/Search/useRecommendedProducts.ts +48 -0
  352. package/src/hooks/Search/useSearch.tsx +89 -182
  353. package/src/hooks/Search/useSearchInput.ts +263 -0
  354. package/src/types/FilterAttribute.ts +35 -0
  355. package/dist/amplitudeContext-DOqL2Vn8.js +0 -264
  356. package/dist/amplitudeContext-ZTQMvVTV.cjs +0 -286
  357. package/dist/graphql-OkhsP4ir.js +0 -36
  358. package/dist/graphql-l4dQrsA6.cjs +0 -53
  359. package/dist/index-Bmub8e38.d.cts +0 -98
  360. package/dist/index-CG3P8xE1.d.cts +0 -676
  361. package/dist/index-CiWEYzXl.d.cts +0 -184
  362. package/dist/index-D2VaMPA3.d.ts +0 -98
  363. package/dist/index-fUsw_Mea.d.ts +0 -676
  364. package/dist/models-CkJ-wg9Q.cjs +0 -1537
  365. package/dist/models-UHOY0ak5.js +0 -1296
  366. package/dist/types-BwNrLPSZ.cjs +0 -106
  367. package/dist/types-CKMMb_gX.d.cts +0 -51
  368. package/dist/types-D3uOF0Oy.js +0 -76
  369. package/dist/types-DZPuBnHe.d.ts +0 -51
  370. package/dist/useDebounce-BZDtUAQ8.cjs +0 -26
  371. package/dist/useDebounce-ueblXZI-.js +0 -19
  372. package/dist/userIdentityContext-Cb6lLv6t.cjs +0 -132
  373. package/dist/userIdentityContext-O_DHHPTN.js +0 -115
  374. /package/dist/{AmplitudeOperations-ChZWcSsc.js → AmplitudeOperations-C-ieCm9m.js} +0 -0
  375. /package/dist/{AmplitudeOperations-JggIc1zD.cjs → AmplitudeOperations-p7APchq9.cjs} +0 -0
  376. /package/dist/{index-RcVcRKH7.d.cts → index-A0HvA68Y.d.cts} +0 -0
  377. /package/dist/{index-mHc9_XC3.d.ts → index-DNVvRcKu.d.ts} +0 -0
@@ -0,0 +1,775 @@
1
+ import React from "react";
2
+ import { render, screen, waitFor, act } from "@testing-library/react";
3
+ import {
4
+ LocalStorageProvider,
5
+ useLocalStorage,
6
+ LocalStorageKeys,
7
+ } from "../localStorageContext";
8
+ import Logger from "src/application/logging/logger";
9
+ import { LocalStorageEventListener } from "src/application/models/localStorageEventListener";
10
+
11
+ // Mock the Logger to avoid console output in tests
12
+ vi.spyOn(Logger, "logDebug").mockImplementation(() => {});
13
+ vi.spyOn(Logger, "logWarn").mockImplementation(() => {});
14
+ vi.spyOn(Logger, "logError").mockImplementation(() => {});
15
+
16
+ // Component that uses the useLocalStorage hook
17
+ const MockLocalStorageComponent: React.FC = () => {
18
+ const {
19
+ setItem,
20
+ getItem,
21
+ setSpiffyOnFeatureFlag,
22
+ getSpiffyOnFeatureFlag,
23
+ isAvailable,
24
+ attachListener,
25
+ detachListener,
26
+ } = useLocalStorage();
27
+
28
+ const [testValue, setTestValue] = React.useState<string | null>(null);
29
+ const [spiffyOnValue, setSpiffyOnValue] = React.useState<string | null>(null);
30
+ const [eventReceived, setEventReceived] = React.useState(false);
31
+
32
+ React.useEffect(() => {
33
+ // Test getItem
34
+ const value = getItem("test-key");
35
+ setTestValue(value);
36
+
37
+ // Test getSpiffyOnFeatureFlag
38
+ const spiffyOn = getSpiffyOnFeatureFlag();
39
+ setSpiffyOnValue(spiffyOn);
40
+
41
+ // Test attachListener
42
+ const listener: LocalStorageEventListener = {
43
+ storageKey: "test-listener-key",
44
+ listener: () => {
45
+ setEventReceived(true);
46
+ },
47
+ };
48
+ attachListener(listener);
49
+
50
+ return () => {
51
+ detachListener(listener);
52
+ };
53
+ }, [getItem, getSpiffyOnFeatureFlag, attachListener, detachListener]);
54
+
55
+ return (
56
+ <div data-testid="local-storage-component">
57
+ <div data-testid="is-available">{isAvailable.toString()}</div>
58
+ <div data-testid="test-value">{testValue || "null"}</div>
59
+ <div data-testid="spiffy-on-value">{spiffyOnValue || "null"}</div>
60
+ <div data-testid="event-received">{eventReceived.toString()}</div>
61
+ <button
62
+ data-testid="set-item-btn"
63
+ onClick={() => {
64
+ setItem("test-key", "test-value");
65
+ setTestValue(getItem("test-key"));
66
+ }}
67
+ >
68
+ Set Item
69
+ </button>
70
+ <button
71
+ data-testid="set-spiffy-on-true-btn"
72
+ onClick={() => {
73
+ setSpiffyOnFeatureFlag(true);
74
+ setSpiffyOnValue(getSpiffyOnFeatureFlag());
75
+ }}
76
+ >
77
+ Set Spiffy On True
78
+ </button>
79
+ <button
80
+ data-testid="set-spiffy-on-false-btn"
81
+ onClick={() => {
82
+ setSpiffyOnFeatureFlag(false);
83
+ setSpiffyOnValue(getSpiffyOnFeatureFlag());
84
+ }}
85
+ >
86
+ Set Spiffy On False
87
+ </button>
88
+ <button
89
+ data-testid="trigger-event-btn"
90
+ onClick={() => {
91
+ setItem("test-listener-key", "event-value");
92
+ }}
93
+ >
94
+ Trigger Event
95
+ </button>
96
+ </div>
97
+ );
98
+ };
99
+
100
+ describe("LocalStorageProvider", () => {
101
+ beforeEach(() => {
102
+ vi.clearAllMocks();
103
+ // Clear localStorage before each test
104
+ if (typeof localStorage !== "undefined") {
105
+ localStorage.clear();
106
+ }
107
+ });
108
+
109
+ describe("useLocalStorage Hook Integration", () => {
110
+ it("should provide localStorage context through useLocalStorage hook", async () => {
111
+ render(
112
+ <LocalStorageProvider>
113
+ <MockLocalStorageComponent />
114
+ </LocalStorageProvider>
115
+ );
116
+
117
+ await waitFor(() => {
118
+ expect(screen.getByTestId("is-available")).toHaveTextContent("true");
119
+ });
120
+
121
+ // Verify all context methods are accessible
122
+ expect(screen.getByTestId("local-storage-component")).toBeInTheDocument();
123
+ });
124
+
125
+ it("should throw error when used outside of LocalStorageProvider", () => {
126
+ const consoleSpy = vi
127
+ .spyOn(console, "error")
128
+ .mockImplementation(() => {});
129
+
130
+ const TestComponent: React.FC = () => {
131
+ try {
132
+ useLocalStorage();
133
+ return <div data-testid="no-error">No Error</div>;
134
+ } catch (error: any) {
135
+ return <div data-testid="error">{error.message}</div>;
136
+ }
137
+ };
138
+
139
+ render(<TestComponent />);
140
+
141
+ expect(screen.getByTestId("error")).toHaveTextContent(
142
+ "useLocalStorage must be used within a LocalStorageProvider"
143
+ );
144
+
145
+ consoleSpy.mockRestore();
146
+ });
147
+ });
148
+
149
+ describe("isAvailable State", () => {
150
+ it("should be true when localStorage is available", async () => {
151
+ render(
152
+ <LocalStorageProvider>
153
+ <MockLocalStorageComponent />
154
+ </LocalStorageProvider>
155
+ );
156
+
157
+ await waitFor(() => {
158
+ expect(screen.getByTestId("is-available")).toHaveTextContent("true");
159
+ });
160
+ });
161
+
162
+ it("should be false when localStorage is not available", async () => {
163
+ const originalLocalStorage = window.localStorage;
164
+ Object.defineProperty(window, "localStorage", {
165
+ value: undefined,
166
+ writable: true,
167
+ configurable: true,
168
+ });
169
+
170
+ render(
171
+ <LocalStorageProvider>
172
+ <MockLocalStorageComponent />
173
+ </LocalStorageProvider>
174
+ );
175
+
176
+ await waitFor(() => {
177
+ expect(screen.getByTestId("is-available")).toHaveTextContent("false");
178
+ });
179
+
180
+ // Restore localStorage
181
+ Object.defineProperty(window, "localStorage", {
182
+ value: originalLocalStorage,
183
+ writable: true,
184
+ configurable: true,
185
+ });
186
+ });
187
+
188
+ it("should log error when localStorage is not available", async () => {
189
+ const logErrorSpy = vi.spyOn(Logger, "logError");
190
+ const originalLocalStorage = window.localStorage;
191
+ Object.defineProperty(window, "localStorage", {
192
+ value: undefined,
193
+ writable: true,
194
+ configurable: true,
195
+ });
196
+
197
+ render(
198
+ <LocalStorageProvider>
199
+ <div>Test</div>
200
+ </LocalStorageProvider>
201
+ );
202
+
203
+ await waitFor(() => {
204
+ expect(logErrorSpy).toHaveBeenCalledWith(
205
+ "localStorage is not available",
206
+ undefined
207
+ );
208
+ });
209
+
210
+ // Restore localStorage
211
+ Object.defineProperty(window, "localStorage", {
212
+ value: originalLocalStorage,
213
+ writable: true,
214
+ configurable: true,
215
+ });
216
+ });
217
+ });
218
+
219
+ describe("setItem and getItem", () => {
220
+ it("should set and get items from localStorage", async () => {
221
+ render(
222
+ <LocalStorageProvider>
223
+ <MockLocalStorageComponent />
224
+ </LocalStorageProvider>
225
+ );
226
+
227
+ await waitFor(() => {
228
+ expect(screen.getByTestId("is-available")).toHaveTextContent("true");
229
+ });
230
+
231
+ await act(async () => {
232
+ screen.getByTestId("set-item-btn").click();
233
+ });
234
+
235
+ await waitFor(() => {
236
+ expect(screen.getByTestId("test-value")).toHaveTextContent("test-value");
237
+ });
238
+
239
+ // Verify it's actually in localStorage
240
+ expect(localStorage.getItem("test-key")).toBe("test-value");
241
+ });
242
+
243
+ it("should return null when item doesn't exist", async () => {
244
+ render(
245
+ <LocalStorageProvider>
246
+ <MockLocalStorageComponent />
247
+ </LocalStorageProvider>
248
+ );
249
+
250
+ await waitFor(() => {
251
+ expect(screen.getByTestId("test-value")).toHaveTextContent("null");
252
+ });
253
+ });
254
+
255
+ it("should dispatch storage event when setItem is called", async () => {
256
+ const eventHandler = vi.fn();
257
+ window.addEventListener("storage", eventHandler);
258
+
259
+ render(
260
+ <LocalStorageProvider>
261
+ <MockLocalStorageComponent />
262
+ </LocalStorageProvider>
263
+ );
264
+
265
+ await waitFor(() => {
266
+ expect(screen.getByTestId("is-available")).toHaveTextContent("true");
267
+ });
268
+
269
+ await act(async () => {
270
+ screen.getByTestId("set-item-btn").click();
271
+ });
272
+
273
+ await waitFor(() => {
274
+ expect(eventHandler).toHaveBeenCalled();
275
+ const event = eventHandler.mock.calls[0][0] as StorageEvent;
276
+ expect(event.key).toBe("test-key");
277
+ expect(event.newValue).toBe("test-value");
278
+ });
279
+
280
+ window.removeEventListener("storage", eventHandler);
281
+ });
282
+
283
+ it("should not set item when localStorage is not available", async () => {
284
+ const originalLocalStorage = window.localStorage;
285
+ const mockLocalStorage = {
286
+ setItem: vi.fn(),
287
+ getItem: vi.fn(),
288
+ removeItem: vi.fn(),
289
+ clear: vi.fn(),
290
+ key: vi.fn(),
291
+ length: 0,
292
+ };
293
+
294
+ Object.defineProperty(window, "localStorage", {
295
+ value: undefined,
296
+ writable: true,
297
+ configurable: true,
298
+ });
299
+
300
+ const TestComponent: React.FC = () => {
301
+ const { setItem } = useLocalStorage();
302
+ React.useEffect(() => {
303
+ setItem("test-key", "test-value");
304
+ }, [setItem]);
305
+ return <div>Test</div>;
306
+ };
307
+
308
+ render(
309
+ <LocalStorageProvider>
310
+ <TestComponent />
311
+ </LocalStorageProvider>
312
+ );
313
+
314
+ await waitFor(() => {
315
+ // setItem should not throw, just return early
316
+ expect(mockLocalStorage.setItem).not.toHaveBeenCalled();
317
+ });
318
+
319
+ // Restore localStorage
320
+ Object.defineProperty(window, "localStorage", {
321
+ value: originalLocalStorage,
322
+ writable: true,
323
+ configurable: true,
324
+ });
325
+ });
326
+
327
+ it("should not get item when localStorage is not available", async () => {
328
+ const originalLocalStorage = window.localStorage;
329
+ Object.defineProperty(window, "localStorage", {
330
+ value: undefined,
331
+ writable: true,
332
+ configurable: true,
333
+ });
334
+
335
+ const TestComponent: React.FC = () => {
336
+ const { getItem } = useLocalStorage();
337
+ const value = getItem("test-key");
338
+ return <div data-testid="value">{value || "null"}</div>;
339
+ };
340
+
341
+ render(
342
+ <LocalStorageProvider>
343
+ <TestComponent />
344
+ </LocalStorageProvider>
345
+ );
346
+
347
+ await waitFor(() => {
348
+ expect(screen.getByTestId("value")).toHaveTextContent("null");
349
+ });
350
+
351
+ // Restore localStorage
352
+ Object.defineProperty(window, "localStorage", {
353
+ value: originalLocalStorage,
354
+ writable: true,
355
+ configurable: true,
356
+ });
357
+ });
358
+ });
359
+
360
+ describe("setSpiffyOnFeatureFlag and getSpiffyOnFeatureFlag", () => {
361
+ it("should set SpiffyOn feature flag to true", async () => {
362
+ render(
363
+ <LocalStorageProvider>
364
+ <MockLocalStorageComponent />
365
+ </LocalStorageProvider>
366
+ );
367
+
368
+ await waitFor(() => {
369
+ expect(screen.getByTestId("is-available")).toHaveTextContent("true");
370
+ });
371
+
372
+ await act(async () => {
373
+ screen.getByTestId("set-spiffy-on-true-btn").click();
374
+ });
375
+
376
+ await waitFor(() => {
377
+ expect(screen.getByTestId("spiffy-on-value")).toHaveTextContent("true");
378
+ });
379
+
380
+ // Verify it's actually in localStorage
381
+ expect(localStorage.getItem(LocalStorageKeys.SpiffyOnOverride)).toBe(
382
+ "true"
383
+ );
384
+ });
385
+
386
+ it("should set SpiffyOn feature flag to false", async () => {
387
+ render(
388
+ <LocalStorageProvider>
389
+ <MockLocalStorageComponent />
390
+ </LocalStorageProvider>
391
+ );
392
+
393
+ await waitFor(() => {
394
+ expect(screen.getByTestId("is-available")).toHaveTextContent("true");
395
+ });
396
+
397
+ await act(async () => {
398
+ screen.getByTestId("set-spiffy-on-false-btn").click();
399
+ });
400
+
401
+ await waitFor(() => {
402
+ expect(screen.getByTestId("spiffy-on-value")).toHaveTextContent("false");
403
+ });
404
+
405
+ // Verify it's actually in localStorage
406
+ expect(localStorage.getItem(LocalStorageKeys.SpiffyOnOverride)).toBe(
407
+ "false"
408
+ );
409
+ });
410
+
411
+ it("should not set feature flag when value is null", async () => {
412
+ const TestComponent: React.FC = () => {
413
+ const { setSpiffyOnFeatureFlag, getSpiffyOnFeatureFlag } =
414
+ useLocalStorage();
415
+ React.useEffect(() => {
416
+ setSpiffyOnFeatureFlag(null);
417
+ const value = getSpiffyOnFeatureFlag();
418
+ (window as any).spiffyOnValue = value;
419
+ }, [setSpiffyOnFeatureFlag, getSpiffyOnFeatureFlag]);
420
+ return <div>Test</div>;
421
+ };
422
+
423
+ render(
424
+ <LocalStorageProvider>
425
+ <TestComponent />
426
+ </LocalStorageProvider>
427
+ );
428
+
429
+ await waitFor(() => {
430
+ // When null is passed, it should not set anything
431
+ expect((window as any).spiffyOnValue).toBeNull();
432
+ });
433
+ });
434
+
435
+ it("should return null when feature flag is not set", async () => {
436
+ render(
437
+ <LocalStorageProvider>
438
+ <MockLocalStorageComponent />
439
+ </LocalStorageProvider>
440
+ );
441
+
442
+ await waitFor(() => {
443
+ expect(screen.getByTestId("spiffy-on-value")).toHaveTextContent("null");
444
+ });
445
+ });
446
+
447
+ it("should not set feature flag when localStorage is not available", async () => {
448
+ const originalLocalStorage = window.localStorage;
449
+ Object.defineProperty(window, "localStorage", {
450
+ value: undefined,
451
+ writable: true,
452
+ configurable: true,
453
+ });
454
+
455
+ const TestComponent: React.FC = () => {
456
+ const { setSpiffyOnFeatureFlag, isAvailable } = useLocalStorage();
457
+ React.useEffect(() => {
458
+ setSpiffyOnFeatureFlag(true);
459
+ }, [setSpiffyOnFeatureFlag]);
460
+ return <div data-testid="is-available">{isAvailable.toString()}</div>;
461
+ };
462
+
463
+ render(
464
+ <LocalStorageProvider>
465
+ <TestComponent />
466
+ </LocalStorageProvider>
467
+ );
468
+
469
+ await waitFor(() => {
470
+ // Should not throw, just return early
471
+ expect(screen.getByTestId("is-available")).toHaveTextContent("false");
472
+ });
473
+
474
+ // Restore localStorage
475
+ Object.defineProperty(window, "localStorage", {
476
+ value: originalLocalStorage,
477
+ writable: true,
478
+ configurable: true,
479
+ });
480
+ });
481
+ });
482
+
483
+ describe("attachListener and detachListener", () => {
484
+ it("should attach and trigger storage event listener", async () => {
485
+ render(
486
+ <LocalStorageProvider>
487
+ <MockLocalStorageComponent />
488
+ </LocalStorageProvider>
489
+ );
490
+
491
+ await waitFor(() => {
492
+ expect(screen.getByTestId("is-available")).toHaveTextContent("true");
493
+ });
494
+
495
+ // Wait a bit to ensure listener is attached
496
+ await new Promise((resolve) => setTimeout(resolve, 50));
497
+
498
+ await act(async () => {
499
+ screen.getByTestId("trigger-event-btn").click();
500
+ });
501
+
502
+ await waitFor(() => {
503
+ expect(screen.getByTestId("event-received")).toHaveTextContent("true");
504
+ }, { timeout: 2000 });
505
+ });
506
+
507
+ it("should only trigger listener for matching storage key", async () => {
508
+ const listener1 = vi.fn();
509
+ const listener2 = vi.fn();
510
+
511
+ const TestComponent: React.FC = () => {
512
+ const { attachListener, setItem, detachListener } = useLocalStorage();
513
+ const [ready, setReady] = React.useState(false);
514
+
515
+ React.useEffect(() => {
516
+ const listenerObj1: LocalStorageEventListener = {
517
+ storageKey: "key1",
518
+ listener: listener1,
519
+ };
520
+ const listenerObj2: LocalStorageEventListener = {
521
+ storageKey: "key2",
522
+ listener: listener2,
523
+ };
524
+ attachListener(listenerObj1);
525
+ attachListener(listenerObj2);
526
+ setReady(true);
527
+
528
+ return () => {
529
+ detachListener(listenerObj1);
530
+ detachListener(listenerObj2);
531
+ };
532
+ }, [attachListener, detachListener]);
533
+
534
+ React.useEffect(() => {
535
+ if (ready) {
536
+ // Set item for key1 after listeners are attached
537
+ setTimeout(() => {
538
+ setItem("key1", "value1");
539
+ }, 50);
540
+ }
541
+ }, [ready, setItem]);
542
+
543
+ return <div data-testid="ready">{ready.toString()}</div>;
544
+ };
545
+
546
+ render(
547
+ <LocalStorageProvider>
548
+ <TestComponent />
549
+ </LocalStorageProvider>
550
+ );
551
+
552
+ await waitFor(() => {
553
+ expect(screen.getByTestId("ready")).toHaveTextContent("true");
554
+ });
555
+
556
+ await waitFor(() => {
557
+ expect(listener1).toHaveBeenCalled();
558
+ expect(listener2).not.toHaveBeenCalled();
559
+ }, { timeout: 2000 });
560
+ });
561
+
562
+ it("should log debug message when storage event is received", async () => {
563
+ const logDebugSpy = vi.spyOn(Logger, "logDebug");
564
+
565
+ const TestComponent: React.FC = () => {
566
+ const { attachListener, setItem, detachListener } = useLocalStorage();
567
+ const [ready, setReady] = React.useState(false);
568
+
569
+ React.useEffect(() => {
570
+ const listener: LocalStorageEventListener = {
571
+ storageKey: "test-key",
572
+ listener: () => {},
573
+ };
574
+ attachListener(listener);
575
+ setReady(true);
576
+
577
+ return () => {
578
+ detachListener(listener);
579
+ };
580
+ }, [attachListener, detachListener]);
581
+
582
+ React.useEffect(() => {
583
+ if (ready) {
584
+ // Set item after listener is attached
585
+ setTimeout(() => {
586
+ setItem("test-key", "test-value");
587
+ }, 50);
588
+ }
589
+ }, [ready, setItem]);
590
+
591
+ return <div data-testid="ready">{ready.toString()}</div>;
592
+ };
593
+
594
+ render(
595
+ <LocalStorageProvider>
596
+ <TestComponent />
597
+ </LocalStorageProvider>
598
+ );
599
+
600
+ await waitFor(() => {
601
+ expect(screen.getByTestId("ready")).toHaveTextContent("true");
602
+ });
603
+
604
+ await waitFor(() => {
605
+ expect(logDebugSpy).toHaveBeenCalledWith(
606
+ "[spiffy-ai] Storage event key=test-key, value=",
607
+ "test-value"
608
+ );
609
+ }, { timeout: 2000 });
610
+ });
611
+
612
+ it("should attach and detach listeners without errors", async () => {
613
+ const listener = vi.fn();
614
+
615
+ const TestComponent: React.FC = () => {
616
+ const { attachListener, detachListener } = useLocalStorage();
617
+ const [attached, setAttached] = React.useState(false);
618
+
619
+ React.useEffect(() => {
620
+ const listenerObj: LocalStorageEventListener = {
621
+ storageKey: "test-key",
622
+ listener,
623
+ };
624
+ attachListener(listenerObj);
625
+ setAttached(true);
626
+
627
+ return () => {
628
+ detachListener(listenerObj);
629
+ };
630
+ }, [attachListener, detachListener]);
631
+
632
+ return <div data-testid="attached">{attached.toString()}</div>;
633
+ };
634
+
635
+ render(
636
+ <LocalStorageProvider>
637
+ <TestComponent />
638
+ </LocalStorageProvider>
639
+ );
640
+
641
+ await waitFor(() => {
642
+ expect(screen.getByTestId("attached")).toHaveTextContent("true");
643
+ });
644
+
645
+ // Verify methods can be called without errors
646
+ expect(screen.getByTestId("attached")).toBeInTheDocument();
647
+ });
648
+
649
+ it("should not attach listener when localStorage is not available", async () => {
650
+ const originalLocalStorage = window.localStorage;
651
+ const addEventListenerSpy = vi.spyOn(window, "addEventListener");
652
+
653
+ Object.defineProperty(window, "localStorage", {
654
+ value: undefined,
655
+ writable: true,
656
+ configurable: true,
657
+ });
658
+
659
+ const TestComponent: React.FC = () => {
660
+ const { attachListener } = useLocalStorage();
661
+ React.useEffect(() => {
662
+ attachListener({
663
+ storageKey: "test-key",
664
+ listener: () => {},
665
+ });
666
+ }, [attachListener]);
667
+ return <div>Test</div>;
668
+ };
669
+
670
+ render(
671
+ <LocalStorageProvider>
672
+ <TestComponent />
673
+ </LocalStorageProvider>
674
+ );
675
+
676
+ await waitFor(() => {
677
+ // addEventListener should not be called for storage events
678
+ const storageCalls = addEventListenerSpy.mock.calls.filter(
679
+ (call: any) => call[0] === "storage"
680
+ );
681
+ expect(storageCalls.length).toBe(0);
682
+ });
683
+
684
+ addEventListenerSpy.mockRestore();
685
+
686
+ // Restore localStorage
687
+ Object.defineProperty(window, "localStorage", {
688
+ value: originalLocalStorage,
689
+ writable: true,
690
+ configurable: true,
691
+ });
692
+ });
693
+
694
+ it("should allow attaching and detaching multiple listeners", async () => {
695
+ const listener1 = vi.fn();
696
+ const listener2 = vi.fn();
697
+
698
+ const TestComponent: React.FC = () => {
699
+ const { attachListener, detachListener } = useLocalStorage();
700
+ const [ready, setReady] = React.useState(false);
701
+
702
+ React.useEffect(() => {
703
+ const listenerObj1: LocalStorageEventListener = {
704
+ storageKey: "key1",
705
+ listener: listener1,
706
+ };
707
+ const listenerObj2: LocalStorageEventListener = {
708
+ storageKey: "key2",
709
+ listener: listener2,
710
+ };
711
+
712
+ attachListener(listenerObj1);
713
+ attachListener(listenerObj2);
714
+ // Detach one listener
715
+ detachListener(listenerObj1);
716
+ setReady(true);
717
+
718
+ return () => {
719
+ detachListener(listenerObj1);
720
+ detachListener(listenerObj2);
721
+ };
722
+ }, [attachListener, detachListener]);
723
+
724
+ return <div data-testid="ready">{ready.toString()}</div>;
725
+ };
726
+
727
+ render(
728
+ <LocalStorageProvider>
729
+ <TestComponent />
730
+ </LocalStorageProvider>
731
+ );
732
+
733
+ await waitFor(() => {
734
+ expect(screen.getByTestId("ready")).toHaveTextContent("true");
735
+ });
736
+
737
+ // Verify methods can be called without errors
738
+ expect(screen.getByTestId("ready")).toBeInTheDocument();
739
+ });
740
+ });
741
+
742
+ describe("Context Value Memoization", () => {
743
+ it("should maintain stable context value references", async () => {
744
+ let contextValue1: any;
745
+ let contextValue2: any;
746
+
747
+ const Component1: React.FC = () => {
748
+ const context = useLocalStorage();
749
+ contextValue1 = context;
750
+ return <div>Component1</div>;
751
+ };
752
+
753
+ const Component2: React.FC = () => {
754
+ const context = useLocalStorage();
755
+ contextValue2 = context;
756
+ return <div>Component2</div>;
757
+ };
758
+
759
+ render(
760
+ <LocalStorageProvider>
761
+ <Component1 />
762
+ <Component2 />
763
+ </LocalStorageProvider>
764
+ );
765
+
766
+ await waitFor(() => {
767
+ expect(contextValue1).toBeDefined();
768
+ expect(contextValue2).toBeDefined();
769
+ // Both components should receive the same context instance
770
+ expect(contextValue1).toBe(contextValue2);
771
+ });
772
+ });
773
+ });
774
+ });
775
+