@cossistant/react 0.0.1

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 (372) hide show
  1. package/_virtual/rolldown_runtime.js +13 -0
  2. package/conversation.d.ts +312 -0
  3. package/conversation.d.ts.map +1 -0
  4. package/hooks/index.d.ts +23 -0
  5. package/hooks/index.js +24 -0
  6. package/hooks/private/store/use-conversations-store.d.ts +13 -0
  7. package/hooks/private/store/use-conversations-store.d.ts.map +1 -0
  8. package/hooks/private/store/use-conversations-store.js +34 -0
  9. package/hooks/private/store/use-conversations-store.js.map +1 -0
  10. package/hooks/private/store/use-store-selector.d.ts +10 -0
  11. package/hooks/private/store/use-store-selector.d.ts.map +1 -0
  12. package/hooks/private/store/use-store-selector.js +17 -0
  13. package/hooks/private/store/use-store-selector.js.map +1 -0
  14. package/hooks/private/store/use-website-store.d.ts +18 -0
  15. package/hooks/private/store/use-website-store.d.ts.map +1 -0
  16. package/hooks/private/store/use-website-store.js +39 -0
  17. package/hooks/private/store/use-website-store.js.map +1 -0
  18. package/hooks/private/use-client-query.d.ts +25 -0
  19. package/hooks/private/use-client-query.d.ts.map +1 -0
  20. package/hooks/private/use-client-query.js +122 -0
  21. package/hooks/private/use-client-query.js.map +1 -0
  22. package/hooks/private/use-default-messages.d.ts +18 -0
  23. package/hooks/private/use-default-messages.d.ts.map +1 -0
  24. package/hooks/private/use-default-messages.js +45 -0
  25. package/hooks/private/use-default-messages.js.map +1 -0
  26. package/hooks/private/use-grouped-messages.d.ts +54 -0
  27. package/hooks/private/use-grouped-messages.d.ts.map +1 -0
  28. package/hooks/private/use-grouped-messages.js +157 -0
  29. package/hooks/private/use-grouped-messages.js.map +1 -0
  30. package/hooks/private/use-multimodal-input.d.ts +40 -0
  31. package/hooks/private/use-multimodal-input.d.ts.map +1 -0
  32. package/hooks/private/use-multimodal-input.js +129 -0
  33. package/hooks/private/use-multimodal-input.js.map +1 -0
  34. package/hooks/private/use-rest-client.d.ts +17 -0
  35. package/hooks/private/use-rest-client.d.ts.map +1 -0
  36. package/hooks/private/use-rest-client.js +41 -0
  37. package/hooks/private/use-rest-client.js.map +1 -0
  38. package/hooks/private/use-visitor-typing-reporter.d.ts +19 -0
  39. package/hooks/private/use-visitor-typing-reporter.d.ts.map +1 -0
  40. package/hooks/private/use-visitor-typing-reporter.js +140 -0
  41. package/hooks/private/use-visitor-typing-reporter.js.map +1 -0
  42. package/hooks/use-composer-refocus.d.ts +20 -0
  43. package/hooks/use-composer-refocus.d.ts.map +1 -0
  44. package/hooks/use-composer-refocus.js +32 -0
  45. package/hooks/use-composer-refocus.js.map +1 -0
  46. package/hooks/use-conversation-auto-seen.d.ts +54 -0
  47. package/hooks/use-conversation-auto-seen.d.ts.map +1 -0
  48. package/hooks/use-conversation-auto-seen.js +106 -0
  49. package/hooks/use-conversation-auto-seen.js.map +1 -0
  50. package/hooks/use-conversation-history-page.d.ts +86 -0
  51. package/hooks/use-conversation-history-page.d.ts.map +1 -0
  52. package/hooks/use-conversation-history-page.js +97 -0
  53. package/hooks/use-conversation-history-page.js.map +1 -0
  54. package/hooks/use-conversation-lifecycle.d.ts +80 -0
  55. package/hooks/use-conversation-lifecycle.d.ts.map +1 -0
  56. package/hooks/use-conversation-lifecycle.js +54 -0
  57. package/hooks/use-conversation-lifecycle.js.map +1 -0
  58. package/hooks/use-conversation-page.d.ts +82 -0
  59. package/hooks/use-conversation-page.d.ts.map +1 -0
  60. package/hooks/use-conversation-page.js +138 -0
  61. package/hooks/use-conversation-page.js.map +1 -0
  62. package/hooks/use-conversation-seen.d.ts +17 -0
  63. package/hooks/use-conversation-seen.d.ts.map +1 -0
  64. package/hooks/use-conversation-seen.js +58 -0
  65. package/hooks/use-conversation-seen.js.map +1 -0
  66. package/hooks/use-conversation-timeline-items.d.ts +21 -0
  67. package/hooks/use-conversation-timeline-items.d.ts.map +1 -0
  68. package/hooks/use-conversation-timeline-items.js +87 -0
  69. package/hooks/use-conversation-timeline-items.js.map +1 -0
  70. package/hooks/use-conversation-typing.d.ts +13 -0
  71. package/hooks/use-conversation-typing.d.ts.map +1 -0
  72. package/hooks/use-conversation-typing.js +34 -0
  73. package/hooks/use-conversation-typing.js.map +1 -0
  74. package/hooks/use-conversation.d.ts +18 -0
  75. package/hooks/use-conversation.d.ts.map +1 -0
  76. package/hooks/use-conversation.js +44 -0
  77. package/hooks/use-conversation.js.map +1 -0
  78. package/hooks/use-conversations.d.ts +20 -0
  79. package/hooks/use-conversations.d.ts.map +1 -0
  80. package/hooks/use-conversations.js +68 -0
  81. package/hooks/use-conversations.js.map +1 -0
  82. package/hooks/use-create-conversation.d.ts +30 -0
  83. package/hooks/use-create-conversation.d.ts.map +1 -0
  84. package/hooks/use-create-conversation.js +67 -0
  85. package/hooks/use-create-conversation.js.map +1 -0
  86. package/hooks/use-home-page.d.ts +82 -0
  87. package/hooks/use-home-page.d.ts.map +1 -0
  88. package/hooks/use-home-page.js +89 -0
  89. package/hooks/use-home-page.js.map +1 -0
  90. package/hooks/use-message-composer.d.ts +88 -0
  91. package/hooks/use-message-composer.d.ts.map +1 -0
  92. package/hooks/use-message-composer.js +94 -0
  93. package/hooks/use-message-composer.js.map +1 -0
  94. package/hooks/use-realtime-support.d.ts +25 -0
  95. package/hooks/use-realtime-support.d.ts.map +1 -0
  96. package/hooks/use-realtime-support.js +29 -0
  97. package/hooks/use-realtime-support.js.map +1 -0
  98. package/hooks/use-send-message.d.ts +34 -0
  99. package/hooks/use-send-message.d.ts.map +1 -0
  100. package/hooks/use-send-message.js +118 -0
  101. package/hooks/use-send-message.js.map +1 -0
  102. package/hooks/use-visitor.d.ts +28 -0
  103. package/hooks/use-visitor.d.ts.map +1 -0
  104. package/hooks/use-visitor.js +59 -0
  105. package/hooks/use-visitor.js.map +1 -0
  106. package/hooks/use-window-visibility-focus.d.ts +9 -0
  107. package/hooks/use-window-visibility-focus.d.ts.map +1 -0
  108. package/hooks/use-window-visibility-focus.js +53 -0
  109. package/hooks/use-window-visibility-focus.js.map +1 -0
  110. package/identify-visitor.d.ts +18 -0
  111. package/identify-visitor.d.ts.map +1 -0
  112. package/identify-visitor.js +26 -0
  113. package/identify-visitor.js.map +1 -0
  114. package/index.d.ts +38 -0
  115. package/index.js +38 -0
  116. package/package.json +121 -0
  117. package/primitives/avatar/avatar.d.ts +31 -0
  118. package/primitives/avatar/avatar.d.ts.map +1 -0
  119. package/primitives/avatar/avatar.js +49 -0
  120. package/primitives/avatar/avatar.js.map +1 -0
  121. package/primitives/avatar/fallback.d.ts +24 -0
  122. package/primitives/avatar/fallback.d.ts.map +1 -0
  123. package/primitives/avatar/fallback.js +57 -0
  124. package/primitives/avatar/fallback.js.map +1 -0
  125. package/primitives/avatar/image.d.ts +27 -0
  126. package/primitives/avatar/image.d.ts.map +1 -0
  127. package/primitives/avatar/image.js +58 -0
  128. package/primitives/avatar/image.js.map +1 -0
  129. package/primitives/avatar/index.d.ts +4 -0
  130. package/primitives/avatar/index.js +5 -0
  131. package/primitives/avatar/index.parts.d.ts +4 -0
  132. package/primitives/avatar/index.parts.js +5 -0
  133. package/primitives/bubble.d.ts +28 -0
  134. package/primitives/bubble.d.ts.map +1 -0
  135. package/primitives/bubble.js +43 -0
  136. package/primitives/bubble.js.map +1 -0
  137. package/primitives/button.d.ts +19 -0
  138. package/primitives/button.d.ts.map +1 -0
  139. package/primitives/button.js +27 -0
  140. package/primitives/button.js.map +1 -0
  141. package/primitives/conversation-timeline.d.ts +86 -0
  142. package/primitives/conversation-timeline.d.ts.map +1 -0
  143. package/primitives/conversation-timeline.js +119 -0
  144. package/primitives/conversation-timeline.js.map +1 -0
  145. package/primitives/index.d.ts +20 -0
  146. package/primitives/index.d.ts.map +1 -0
  147. package/primitives/index.js +45 -0
  148. package/primitives/index.js.map +1 -0
  149. package/primitives/index.parts.d.ts +13 -0
  150. package/primitives/index.parts.js +14 -0
  151. package/primitives/multimodal-input.d.ts +53 -0
  152. package/primitives/multimodal-input.d.ts.map +1 -0
  153. package/primitives/multimodal-input.js +106 -0
  154. package/primitives/multimodal-input.js.map +1 -0
  155. package/primitives/timeline-item-group.d.ts +166 -0
  156. package/primitives/timeline-item-group.d.ts.map +1 -0
  157. package/primitives/timeline-item-group.js +204 -0
  158. package/primitives/timeline-item-group.js.map +1 -0
  159. package/primitives/timeline-item.d.ts +75 -0
  160. package/primitives/timeline-item.d.ts.map +1 -0
  161. package/primitives/timeline-item.js +145 -0
  162. package/primitives/timeline-item.js.map +1 -0
  163. package/primitives/window.d.ts +31 -0
  164. package/primitives/window.d.ts.map +1 -0
  165. package/primitives/window.js +58 -0
  166. package/primitives/window.js.map +1 -0
  167. package/provider.d.ts +95 -0
  168. package/provider.d.ts.map +1 -0
  169. package/provider.js +124 -0
  170. package/provider.js.map +1 -0
  171. package/realtime/event-filter.d.ts +8 -0
  172. package/realtime/event-filter.d.ts.map +1 -0
  173. package/realtime/event-filter.js +21 -0
  174. package/realtime/event-filter.js.map +1 -0
  175. package/realtime/index.d.ts +6 -0
  176. package/realtime/index.js +7 -0
  177. package/realtime/provider.d.ts +57 -0
  178. package/realtime/provider.d.ts.map +1 -0
  179. package/realtime/provider.js +351 -0
  180. package/realtime/provider.js.map +1 -0
  181. package/realtime/seen-store.d.ts +23 -0
  182. package/realtime/seen-store.d.ts.map +1 -0
  183. package/realtime/seen-store.js +34 -0
  184. package/realtime/seen-store.js.map +1 -0
  185. package/realtime/support-provider.d.ts +17 -0
  186. package/realtime/support-provider.d.ts.map +1 -0
  187. package/realtime/support-provider.js +54 -0
  188. package/realtime/support-provider.js.map +1 -0
  189. package/realtime/typing-store.d.ts +30 -0
  190. package/realtime/typing-store.d.ts.map +1 -0
  191. package/realtime/typing-store.js +34 -0
  192. package/realtime/typing-store.js.map +1 -0
  193. package/realtime/use-realtime.d.ts +29 -0
  194. package/realtime/use-realtime.d.ts.map +1 -0
  195. package/realtime/use-realtime.js +47 -0
  196. package/realtime/use-realtime.js.map +1 -0
  197. package/realtime-events.d.ts +344 -0
  198. package/realtime-events.d.ts.map +1 -0
  199. package/schemas.d.ts +90 -0
  200. package/schemas.d.ts.map +1 -0
  201. package/support/components/avatar-stack.d.ts +45 -0
  202. package/support/components/avatar-stack.d.ts.map +1 -0
  203. package/support/components/avatar-stack.js +72 -0
  204. package/support/components/avatar-stack.js.map +1 -0
  205. package/support/components/avatar.d.ts +15 -0
  206. package/support/components/avatar.d.ts.map +1 -0
  207. package/support/components/avatar.js +23 -0
  208. package/support/components/avatar.js.map +1 -0
  209. package/support/components/bubble.d.ts +10 -0
  210. package/support/components/bubble.d.ts.map +1 -0
  211. package/support/components/bubble.js +95 -0
  212. package/support/components/bubble.js.map +1 -0
  213. package/support/components/button.d.ts +20 -0
  214. package/support/components/button.d.ts.map +1 -0
  215. package/support/components/button.js +41 -0
  216. package/support/components/button.js.map +1 -0
  217. package/support/components/container.d.ts +14 -0
  218. package/support/components/container.d.ts.map +1 -0
  219. package/support/components/container.js +115 -0
  220. package/support/components/container.js.map +1 -0
  221. package/support/components/conversation-button-link.d.ts +34 -0
  222. package/support/components/conversation-button-link.d.ts.map +1 -0
  223. package/support/components/conversation-button-link.js +195 -0
  224. package/support/components/conversation-button-link.js.map +1 -0
  225. package/support/components/conversation-event.d.ts +14 -0
  226. package/support/components/conversation-event.d.ts.map +1 -0
  227. package/support/components/conversation-event.js +76 -0
  228. package/support/components/conversation-event.js.map +1 -0
  229. package/support/components/conversation-timeline.d.ts +17 -0
  230. package/support/components/conversation-timeline.d.ts.map +1 -0
  231. package/support/components/conversation-timeline.js +95 -0
  232. package/support/components/conversation-timeline.js.map +1 -0
  233. package/support/components/cossistant-branding.d.ts +12 -0
  234. package/support/components/cossistant-branding.d.ts.map +1 -0
  235. package/support/components/cossistant-branding.js +22 -0
  236. package/support/components/cossistant-branding.js.map +1 -0
  237. package/support/components/header.d.ts +11 -0
  238. package/support/components/header.d.ts.map +1 -0
  239. package/support/components/header.js +43 -0
  240. package/support/components/header.js.map +1 -0
  241. package/support/components/icons.d.ts +21 -0
  242. package/support/components/icons.d.ts.map +1 -0
  243. package/support/components/icons.js +131 -0
  244. package/support/components/icons.js.map +1 -0
  245. package/support/components/index.d.ts +11 -0
  246. package/support/components/index.js +12 -0
  247. package/support/components/multimodal-input.d.ts +28 -0
  248. package/support/components/multimodal-input.d.ts.map +1 -0
  249. package/support/components/multimodal-input.js +138 -0
  250. package/support/components/multimodal-input.js.map +1 -0
  251. package/support/components/navigation-tab.d.ts +7 -0
  252. package/support/components/navigation-tab.d.ts.map +1 -0
  253. package/support/components/navigation-tab.js +40 -0
  254. package/support/components/navigation-tab.js.map +1 -0
  255. package/support/components/support-content.d.ts +22 -0
  256. package/support/components/support-content.d.ts.map +1 -0
  257. package/support/components/support-content.js +50 -0
  258. package/support/components/support-content.js.map +1 -0
  259. package/support/components/text-effect.d.ts +49 -0
  260. package/support/components/text-effect.d.ts.map +1 -0
  261. package/support/components/text-effect.js +221 -0
  262. package/support/components/text-effect.js.map +1 -0
  263. package/support/components/timeline-message-group.d.ts +16 -0
  264. package/support/components/timeline-message-group.d.ts.map +1 -0
  265. package/support/components/timeline-message-group.js +117 -0
  266. package/support/components/timeline-message-group.js.map +1 -0
  267. package/support/components/timeline-message-item.d.ts +17 -0
  268. package/support/components/timeline-message-item.d.ts.map +1 -0
  269. package/support/components/timeline-message-item.js +42 -0
  270. package/support/components/timeline-message-item.js.map +1 -0
  271. package/support/components/typing-indicator.d.ts +26 -0
  272. package/support/components/typing-indicator.d.ts.map +1 -0
  273. package/support/components/typing-indicator.js +37 -0
  274. package/support/components/typing-indicator.js.map +1 -0
  275. package/support/components/watermark.d.ts +8 -0
  276. package/support/components/watermark.d.ts.map +1 -0
  277. package/support/components/watermark.js +34 -0
  278. package/support/components/watermark.js.map +1 -0
  279. package/support/context/config.d.ts +32 -0
  280. package/support/context/config.d.ts.map +1 -0
  281. package/support/context/config.js +27 -0
  282. package/support/context/config.js.map +1 -0
  283. package/support/context/websocket.d.ts +22 -0
  284. package/support/context/websocket.d.ts.map +1 -0
  285. package/support/context/websocket.js +113 -0
  286. package/support/context/websocket.js.map +1 -0
  287. package/support/index.d.ts +39 -0
  288. package/support/index.d.ts.map +1 -0
  289. package/support/index.js +43 -0
  290. package/support/index.js.map +1 -0
  291. package/support/pages/articles.d.ts +7 -0
  292. package/support/pages/articles.d.ts.map +1 -0
  293. package/support/pages/articles.js +39 -0
  294. package/support/pages/articles.js.map +1 -0
  295. package/support/pages/conversation-history.d.ts +18 -0
  296. package/support/pages/conversation-history.d.ts.map +1 -0
  297. package/support/pages/conversation-history.js +120 -0
  298. package/support/pages/conversation-history.js.map +1 -0
  299. package/support/pages/conversation.d.ts +32 -0
  300. package/support/pages/conversation.d.ts.map +1 -0
  301. package/support/pages/conversation.js +92 -0
  302. package/support/pages/conversation.js.map +1 -0
  303. package/support/pages/home.d.ts +20 -0
  304. package/support/pages/home.d.ts.map +1 -0
  305. package/support/pages/home.js +184 -0
  306. package/support/pages/home.js.map +1 -0
  307. package/support/router.d.ts +14 -0
  308. package/support/router.d.ts.map +1 -0
  309. package/support/router.js +31 -0
  310. package/support/router.js.map +1 -0
  311. package/support/store/index.d.ts +2 -0
  312. package/support/store/index.js +3 -0
  313. package/support/store/support-store.d.ts +42 -0
  314. package/support/store/support-store.d.ts.map +1 -0
  315. package/support/store/support-store.js +66 -0
  316. package/support/store/support-store.js.map +1 -0
  317. package/support/support-CMoDLQoC.css +408 -0
  318. package/support/support-CMoDLQoC.css.map +1 -0
  319. package/support/support.js +1 -0
  320. package/support/text/index.d.ts +35 -0
  321. package/support/text/index.d.ts.map +1 -0
  322. package/support/text/index.js +71 -0
  323. package/support/text/index.js.map +1 -0
  324. package/support/text/locales/en.d.ts +7 -0
  325. package/support/text/locales/en.d.ts.map +1 -0
  326. package/support/text/locales/en.js +65 -0
  327. package/support/text/locales/en.js.map +1 -0
  328. package/support/text/locales/es.d.ts +7 -0
  329. package/support/text/locales/es.d.ts.map +1 -0
  330. package/support/text/locales/es.js +64 -0
  331. package/support/text/locales/es.js.map +1 -0
  332. package/support/text/locales/fr.d.ts +7 -0
  333. package/support/text/locales/fr.d.ts.map +1 -0
  334. package/support/text/locales/fr.js +64 -0
  335. package/support/text/locales/fr.js.map +1 -0
  336. package/support/text/locales/keys.d.ts +216 -0
  337. package/support/text/locales/keys.d.ts.map +1 -0
  338. package/support/text/locales/keys.js +54 -0
  339. package/support/text/locales/keys.js.map +1 -0
  340. package/support/text/runtime.d.ts +17 -0
  341. package/support/text/runtime.d.ts.map +1 -0
  342. package/support/text/runtime.js +156 -0
  343. package/support/text/runtime.js.map +1 -0
  344. package/support/utils/index.d.ts +7 -0
  345. package/support/utils/index.d.ts.map +1 -0
  346. package/support/utils/index.js +11 -0
  347. package/support/utils/index.js.map +1 -0
  348. package/support/utils/time.d.ts +5 -0
  349. package/support/utils/time.d.ts.map +1 -0
  350. package/support/utils/time.js +28 -0
  351. package/support/utils/time.js.map +1 -0
  352. package/support-config.d.ts +20 -0
  353. package/support-config.d.ts.map +1 -0
  354. package/support-config.js +25 -0
  355. package/support-config.js.map +1 -0
  356. package/support.css +2 -0
  357. package/timeline-item.d.ts +133 -0
  358. package/timeline-item.d.ts.map +1 -0
  359. package/utils/id.d.ts +6 -0
  360. package/utils/id.d.ts.map +1 -0
  361. package/utils/id.js +13 -0
  362. package/utils/id.js.map +1 -0
  363. package/utils/index.d.ts +3 -0
  364. package/utils/index.js +4 -0
  365. package/utils/text.d.ts +5 -0
  366. package/utils/text.d.ts.map +1 -0
  367. package/utils/text.js +9 -0
  368. package/utils/text.js.map +1 -0
  369. package/utils/use-render-element.d.ts +22 -0
  370. package/utils/use-render-element.d.ts.map +1 -0
  371. package/utils/use-render-element.js +35 -0
  372. package/utils/use-render-element.js.map +1 -0
@@ -0,0 +1,88 @@
1
+ import { TimelineItem } from "../timeline-item.js";
2
+ import { UseMultimodalInputOptions } from "./private/use-multimodal-input.js";
3
+ import { CossistantClient } from "@cossistant/core";
4
+
5
+ //#region src/hooks/use-message-composer.d.ts
6
+ type UseMessageComposerOptions = {
7
+ /**
8
+ * The Cossistant client instance.
9
+ */
10
+ client: CossistantClient;
11
+ /**
12
+ * Current conversation ID. Can be null if no real conversation exists yet.
13
+ * Pass null when showing default timeline items before user sends first message.
14
+ */
15
+ conversationId: string | null;
16
+ /**
17
+ * Default timeline items to include when creating a new conversation.
18
+ */
19
+ defaultTimelineItems?: TimelineItem[];
20
+ /**
21
+ * Visitor ID to associate with messages.
22
+ */
23
+ visitorId?: string;
24
+ /**
25
+ * Callback when a message is successfully sent.
26
+ * @param conversationId - The conversation ID (may be newly created)
27
+ * @param messageId - The sent message ID
28
+ */
29
+ onMessageSent?: (conversationId: string, messageId: string) => void;
30
+ /**
31
+ * Callback when message sending fails.
32
+ */
33
+ onError?: (error: Error) => void;
34
+ /**
35
+ * File upload options (max size, allowed types, etc.)
36
+ */
37
+ fileOptions?: Pick<UseMultimodalInputOptions, "maxFileSize" | "maxFiles" | "allowedFileTypes">;
38
+ };
39
+ type UseMessageComposerReturn = {
40
+ message: string;
41
+ files: File[];
42
+ error: Error | null;
43
+ isSubmitting: boolean;
44
+ canSubmit: boolean;
45
+ setMessage: (message: string) => void;
46
+ addFiles: (files: File[]) => void;
47
+ removeFile: (index: number) => void;
48
+ clearFiles: () => void;
49
+ submit: () => void;
50
+ reset: () => void;
51
+ };
52
+ /**
53
+ * Combines message input, typing indicators, and message sending into
54
+ * a single, cohesive hook for building message composers.
55
+ *
56
+ * This hook:
57
+ * - Manages text input and file attachments via useMultimodalInput
58
+ * - Sends typing indicators while user is composing
59
+ * - Handles message submission with proper error handling
60
+ * - Automatically resets input after successful send
61
+ * - Works with both pending and real conversations
62
+ *
63
+ * @example
64
+ * ```tsx
65
+ * const composer = useMessageComposer({
66
+ * client,
67
+ * conversationId: realConversationId, // null if pending
68
+ * defaultMessages,
69
+ * visitorId: visitor?.id,
70
+ * onMessageSent: (convId) => {
71
+ * // Update conversation ID if it was created
72
+ * },
73
+ * });
74
+ *
75
+ * return (
76
+ * <MessageInput
77
+ * value={composer.message}
78
+ * onChange={composer.setMessage}
79
+ * onSubmit={composer.submit}
80
+ * disabled={composer.isSubmitting}
81
+ * />
82
+ * );
83
+ * ```
84
+ */
85
+ declare function useMessageComposer(options: UseMessageComposerOptions): UseMessageComposerReturn;
86
+ //#endregion
87
+ export { UseMessageComposerOptions, UseMessageComposerReturn, useMessageComposer };
88
+ //# sourceMappingURL=use-message-composer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-message-composer.d.ts","names":[],"sources":["../../src/hooks/use-message-composer.ts"],"sourcesContent":[],"mappings":";;;;;KAUY,yBAAA;;AAAZ;;QAIS,EAAA,gBAAA;;;;;EAiCU,cAAA,EAAA,MAAA,GAAA,IAAA;EAMP;;;sBAIJ,CAAA,EAhCgB,YAgChB,EAAA;;;AAgDR;EAAkC,SAAA,CAAA,EAAA,MAAA;;;;;;;;;;oBA/Df;;;;gBAKJ,KACb;;KAKU,wBAAA;;SAGJ;SACA;;;;oBAQW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAwCH,kBAAA,UACN,4BACP"}
@@ -0,0 +1,94 @@
1
+ import { useMultimodalInput } from "./private/use-multimodal-input.js";
2
+ import { useVisitorTypingReporter } from "./private/use-visitor-typing-reporter.js";
3
+ import { useSendMessage } from "./use-send-message.js";
4
+ import { useCallback, useEffect } from "react";
5
+
6
+ //#region src/hooks/use-message-composer.ts
7
+ /**
8
+ * Combines message input, typing indicators, and message sending into
9
+ * a single, cohesive hook for building message composers.
10
+ *
11
+ * This hook:
12
+ * - Manages text input and file attachments via useMultimodalInput
13
+ * - Sends typing indicators while user is composing
14
+ * - Handles message submission with proper error handling
15
+ * - Automatically resets input after successful send
16
+ * - Works with both pending and real conversations
17
+ *
18
+ * @example
19
+ * ```tsx
20
+ * const composer = useMessageComposer({
21
+ * client,
22
+ * conversationId: realConversationId, // null if pending
23
+ * defaultMessages,
24
+ * visitorId: visitor?.id,
25
+ * onMessageSent: (convId) => {
26
+ * // Update conversation ID if it was created
27
+ * },
28
+ * });
29
+ *
30
+ * return (
31
+ * <MessageInput
32
+ * value={composer.message}
33
+ * onChange={composer.setMessage}
34
+ * onSubmit={composer.submit}
35
+ * disabled={composer.isSubmitting}
36
+ * />
37
+ * );
38
+ * ```
39
+ */
40
+ function useMessageComposer(options) {
41
+ const { client, conversationId, defaultTimelineItems = [], visitorId, onMessageSent, onError, fileOptions } = options;
42
+ const sendMessage = useSendMessage({ client });
43
+ const { handleInputChange: reportTyping, handleSubmit: stopTyping, stop: forceStopTyping } = useVisitorTypingReporter({
44
+ client,
45
+ conversationId
46
+ });
47
+ const multimodalInput = useMultimodalInput({
48
+ onSubmit: async ({ message: messageText, files }) => {
49
+ stopTyping();
50
+ sendMessage.mutate({
51
+ conversationId,
52
+ message: messageText,
53
+ files,
54
+ defaultTimelineItems,
55
+ visitorId,
56
+ onSuccess: (resultConversationId, messageId) => {
57
+ onMessageSent?.(resultConversationId, messageId);
58
+ },
59
+ onError: (err) => {
60
+ onError?.(err);
61
+ }
62
+ });
63
+ },
64
+ onError,
65
+ ...fileOptions
66
+ });
67
+ useEffect(() => () => {
68
+ forceStopTyping();
69
+ }, [forceStopTyping]);
70
+ const setMessage = useCallback((value) => {
71
+ multimodalInput.setMessage(value);
72
+ reportTyping(value);
73
+ }, [multimodalInput, reportTyping]);
74
+ const isSubmitting = multimodalInput.isSubmitting || sendMessage.isPending;
75
+ const error = multimodalInput.error || sendMessage.error;
76
+ const canSubmit = multimodalInput.canSubmit && !sendMessage.isPending;
77
+ return {
78
+ message: multimodalInput.message,
79
+ files: multimodalInput.files,
80
+ error,
81
+ isSubmitting,
82
+ canSubmit,
83
+ setMessage,
84
+ addFiles: multimodalInput.addFiles,
85
+ removeFile: multimodalInput.removeFile,
86
+ clearFiles: multimodalInput.clearFiles,
87
+ submit: multimodalInput.submit,
88
+ reset: multimodalInput.reset
89
+ };
90
+ }
91
+
92
+ //#endregion
93
+ export { useMessageComposer };
94
+ //# sourceMappingURL=use-message-composer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-message-composer.js","names":[],"sources":["../../src/hooks/use-message-composer.ts"],"sourcesContent":["import type { CossistantClient } from \"@cossistant/core\";\nimport type { TimelineItem } from \"@cossistant/types/api/timeline-item\";\nimport { useCallback, useEffect } from \"react\";\nimport {\n\ttype UseMultimodalInputOptions,\n\tuseMultimodalInput,\n} from \"./private/use-multimodal-input\";\nimport { useVisitorTypingReporter } from \"./private/use-visitor-typing-reporter\";\nimport { useSendMessage } from \"./use-send-message\";\n\nexport type UseMessageComposerOptions = {\n\t/**\n\t * The Cossistant client instance.\n\t */\n\tclient: CossistantClient;\n\n\t/**\n\t * Current conversation ID. Can be null if no real conversation exists yet.\n\t * Pass null when showing default timeline items before user sends first message.\n\t */\n\tconversationId: string | null;\n\n\t/**\n\t * Default timeline items to include when creating a new conversation.\n\t */\n\tdefaultTimelineItems?: TimelineItem[];\n\n\t/**\n\t * Visitor ID to associate with messages.\n\t */\n\tvisitorId?: string;\n\n\t/**\n\t * Callback when a message is successfully sent.\n\t * @param conversationId - The conversation ID (may be newly created)\n\t * @param messageId - The sent message ID\n\t */\n\tonMessageSent?: (conversationId: string, messageId: string) => void;\n\n\t/**\n\t * Callback when message sending fails.\n\t */\n\tonError?: (error: Error) => void;\n\n\t/**\n\t * File upload options (max size, allowed types, etc.)\n\t */\n\tfileOptions?: Pick<\n\t\tUseMultimodalInputOptions,\n\t\t\"maxFileSize\" | \"maxFiles\" | \"allowedFileTypes\"\n\t>;\n};\n\nexport type UseMessageComposerReturn = {\n\t// Input state\n\tmessage: string;\n\tfiles: File[];\n\terror: Error | null;\n\n\t// Status\n\tisSubmitting: boolean;\n\tcanSubmit: boolean;\n\n\t// Actions\n\tsetMessage: (message: string) => void;\n\taddFiles: (files: File[]) => void;\n\tremoveFile: (index: number) => void;\n\tclearFiles: () => void;\n\tsubmit: () => void;\n\treset: () => void;\n};\n\n/**\n * Combines message input, typing indicators, and message sending into\n * a single, cohesive hook for building message composers.\n *\n * This hook:\n * - Manages text input and file attachments via useMultimodalInput\n * - Sends typing indicators while user is composing\n * - Handles message submission with proper error handling\n * - Automatically resets input after successful send\n * - Works with both pending and real conversations\n *\n * @example\n * ```tsx\n * const composer = useMessageComposer({\n * client,\n * conversationId: realConversationId, // null if pending\n * defaultMessages,\n * visitorId: visitor?.id,\n * onMessageSent: (convId) => {\n * // Update conversation ID if it was created\n * },\n * });\n *\n * return (\n * <MessageInput\n * value={composer.message}\n * onChange={composer.setMessage}\n * onSubmit={composer.submit}\n * disabled={composer.isSubmitting}\n * />\n * );\n * ```\n */\nexport function useMessageComposer(\n\toptions: UseMessageComposerOptions\n): UseMessageComposerReturn {\n\tconst {\n\t\tclient,\n\t\tconversationId,\n\t\tdefaultTimelineItems = [],\n\t\tvisitorId,\n\t\tonMessageSent,\n\t\tonError,\n\t\tfileOptions,\n\t} = options;\n\n\tconst sendMessage = useSendMessage({ client });\n\n\tconst {\n\t\thandleInputChange: reportTyping,\n\t\thandleSubmit: stopTyping,\n\t\tstop: forceStopTyping,\n\t} = useVisitorTypingReporter({\n\t\tclient,\n\t\tconversationId,\n\t});\n\n\tconst multimodalInput = useMultimodalInput({\n\t\tonSubmit: async ({ message: messageText, files }) => {\n\t\t\t// Stop typing indicator\n\t\t\tstopTyping();\n\n\t\t\t// Send the message\n\t\t\tsendMessage.mutate({\n\t\t\t\tconversationId,\n\t\t\t\tmessage: messageText,\n\t\t\t\tfiles,\n\t\t\t\tdefaultTimelineItems,\n\t\t\t\tvisitorId,\n\t\t\t\tonSuccess: (resultConversationId, messageId) => {\n\t\t\t\t\tonMessageSent?.(resultConversationId, messageId);\n\t\t\t\t},\n\t\t\t\tonError: (err) => {\n\t\t\t\t\tonError?.(err);\n\t\t\t\t},\n\t\t\t});\n\t\t},\n\t\tonError,\n\t\t...fileOptions,\n\t});\n\n\t// Clean up typing indicator on unmount\n\tuseEffect(\n\t\t() => () => {\n\t\t\tforceStopTyping();\n\t\t},\n\t\t[forceStopTyping]\n\t);\n\n\t// Wrap setMessage to also report typing\n\tconst setMessage = useCallback(\n\t\t(value: string) => {\n\t\t\tmultimodalInput.setMessage(value);\n\t\t\treportTyping(value);\n\t\t},\n\t\t[multimodalInput, reportTyping]\n\t);\n\n\t// Combine submission states\n\tconst isSubmitting = multimodalInput.isSubmitting || sendMessage.isPending;\n\tconst error = multimodalInput.error || sendMessage.error;\n\tconst canSubmit = multimodalInput.canSubmit && !sendMessage.isPending;\n\n\treturn {\n\t\tmessage: multimodalInput.message,\n\t\tfiles: multimodalInput.files,\n\t\terror,\n\t\tisSubmitting,\n\t\tcanSubmit,\n\t\tsetMessage,\n\t\taddFiles: multimodalInput.addFiles,\n\t\tremoveFile: multimodalInput.removeFile,\n\t\tclearFiles: multimodalInput.clearFiles,\n\t\tsubmit: multimodalInput.submit,\n\t\treset: multimodalInput.reset,\n\t};\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyGA,SAAgB,mBACf,SAC2B;CAC3B,MAAM,EACL,QACA,gBACA,uBAAuB,EAAE,EACzB,WACA,eACA,SACA,gBACG;CAEJ,MAAM,cAAc,eAAe,EAAE,QAAQ,CAAC;CAE9C,MAAM,EACL,mBAAmB,cACnB,cAAc,YACd,MAAM,oBACH,yBAAyB;EAC5B;EACA;EACA,CAAC;CAEF,MAAM,kBAAkB,mBAAmB;EAC1C,UAAU,OAAO,EAAE,SAAS,aAAa,YAAY;AAEpD,eAAY;AAGZ,eAAY,OAAO;IAClB;IACA,SAAS;IACT;IACA;IACA;IACA,YAAY,sBAAsB,cAAc;AAC/C,qBAAgB,sBAAsB,UAAU;;IAEjD,UAAU,QAAQ;AACjB,eAAU,IAAI;;IAEf,CAAC;;EAEH;EACA,GAAG;EACH,CAAC;AAGF,uBACa;AACX,mBAAiB;IAElB,CAAC,gBAAgB,CACjB;CAGD,MAAM,aAAa,aACjB,UAAkB;AAClB,kBAAgB,WAAW,MAAM;AACjC,eAAa,MAAM;IAEpB,CAAC,iBAAiB,aAAa,CAC/B;CAGD,MAAM,eAAe,gBAAgB,gBAAgB,YAAY;CACjE,MAAM,QAAQ,gBAAgB,SAAS,YAAY;CACnD,MAAM,YAAY,gBAAgB,aAAa,CAAC,YAAY;AAE5D,QAAO;EACN,SAAS,gBAAgB;EACzB,OAAO,gBAAgB;EACvB;EACA;EACA;EACA;EACA,UAAU,gBAAgB;EAC1B,YAAY,gBAAgB;EAC5B,YAAY,gBAAgB;EAC5B,QAAQ,gBAAgB;EACxB,OAAO,gBAAgB;EACvB"}
@@ -0,0 +1,25 @@
1
+ import { AnyRealtimeEvent } from "../realtime-events.js";
2
+
3
+ //#region src/hooks/use-realtime-support.d.ts
4
+ type UseRealtimeSupportOptions = {
5
+ onEvent?: (event: AnyRealtimeEvent) => void;
6
+ };
7
+ type UseRealtimeSupportResult = {
8
+ isConnected: boolean;
9
+ isConnecting: boolean;
10
+ error: Error | null;
11
+ send: (event: AnyRealtimeEvent) => void;
12
+ lastEvent: AnyRealtimeEvent | null;
13
+ /** @deprecated Use `lastEvent` instead. */
14
+ lastMessage: AnyRealtimeEvent | null;
15
+ subscribe: (handler: (event: AnyRealtimeEvent) => void) => () => void;
16
+ };
17
+ /**
18
+ * Subscribes to websocket updates pushed by the provider-level
19
+ * `WebSocketProvider`. Delegates low-level connection state while optionally
20
+ * invoking the consumer supplied `onEvent` handler for every realtime event.
21
+ */
22
+ declare function useRealtimeSupport(options?: UseRealtimeSupportOptions): UseRealtimeSupportResult;
23
+ //#endregion
24
+ export { UseRealtimeSupportOptions, UseRealtimeSupportResult, useRealtimeSupport };
25
+ //# sourceMappingURL=use-realtime-support.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-realtime-support.d.ts","names":[],"sources":["../../src/hooks/use-realtime-support.ts"],"sourcesContent":[],"mappings":";;;KAIY,yBAAA;oBACO;AADnB,CAAA;AAIY,KAAA,wBAAA,GAAwB;EAAA,WAAA,EAAA,OAAA;cAG5B,EAAA,OAAA;OACO,EADP,KACO,GAAA,IAAA;MACH,EAAA,CAAA,KAAA,EADG,gBACH,EAAA,GAAA,IAAA;WAEE,EAFF,gBAEE,GAAA,IAAA;;EACgC,WAAA,EADhC,gBACgC,GAAA,IAAA;EAQ9B,SAAA,EAAA,CAAA,OAAA,EAAkB,CAAA,KAAA,EARJ,gBAQI,EAAA,GAAA,IAAA,EAAA,GAAA,GAAA,GAAA,IAAA;CAAA;;;;;;iBAAlB,kBAAA,WACN,4BACP"}
@@ -0,0 +1,29 @@
1
+ import { useWebSocket } from "../support/context/websocket.js";
2
+ import { useEffect } from "react";
3
+
4
+ //#region src/hooks/use-realtime-support.ts
5
+ /**
6
+ * Subscribes to websocket updates pushed by the provider-level
7
+ * `WebSocketProvider`. Delegates low-level connection state while optionally
8
+ * invoking the consumer supplied `onEvent` handler for every realtime event.
9
+ */
10
+ function useRealtimeSupport(options = {}) {
11
+ const { onEvent } = options;
12
+ const { isConnected, isConnecting, error, send, subscribe, lastEvent } = useWebSocket();
13
+ useEffect(() => {
14
+ if (onEvent) return subscribe(onEvent);
15
+ }, [onEvent, subscribe]);
16
+ return {
17
+ isConnected,
18
+ isConnecting,
19
+ error,
20
+ send,
21
+ subscribe,
22
+ lastEvent,
23
+ lastMessage: lastEvent
24
+ };
25
+ }
26
+
27
+ //#endregion
28
+ export { useRealtimeSupport };
29
+ //# sourceMappingURL=use-realtime-support.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-realtime-support.js","names":[],"sources":["../../src/hooks/use-realtime-support.ts"],"sourcesContent":["import type { AnyRealtimeEvent } from \"@cossistant/types/realtime-events\";\nimport { useEffect } from \"react\";\nimport { useWebSocket } from \"../support/context/websocket\";\n\nexport type UseRealtimeSupportOptions = {\n\tonEvent?: (event: AnyRealtimeEvent) => void;\n};\n\nexport type UseRealtimeSupportResult = {\n\tisConnected: boolean;\n\tisConnecting: boolean;\n\terror: Error | null;\n\tsend: (event: AnyRealtimeEvent) => void;\n\tlastEvent: AnyRealtimeEvent | null;\n\t/** @deprecated Use `lastEvent` instead. */\n\tlastMessage: AnyRealtimeEvent | null;\n\tsubscribe: (handler: (event: AnyRealtimeEvent) => void) => () => void;\n};\n\n/**\n * Subscribes to websocket updates pushed by the provider-level\n * `WebSocketProvider`. Delegates low-level connection state while optionally\n * invoking the consumer supplied `onEvent` handler for every realtime event.\n */\nexport function useRealtimeSupport(\n\toptions: UseRealtimeSupportOptions = {}\n): UseRealtimeSupportResult {\n\tconst { onEvent } = options;\n\tconst { isConnected, isConnecting, error, send, subscribe, lastEvent } =\n\t\tuseWebSocket();\n\n\t// Subscribe to WebSocket events\n\tuseEffect(() => {\n\t\tif (onEvent) {\n\t\t\tconst unsubscribe = subscribe(onEvent);\n\n\t\t\treturn unsubscribe;\n\t\t}\n\t}, [onEvent, subscribe]);\n\n\treturn {\n\t\tisConnected,\n\t\tisConnecting,\n\t\terror,\n\t\tsend,\n\t\tsubscribe,\n\t\tlastEvent,\n\t\tlastMessage: lastEvent,\n\t};\n}\n"],"mappings":";;;;;;;;;AAwBA,SAAgB,mBACf,UAAqC,EAAE,EACZ;CAC3B,MAAM,EAAE,YAAY;CACpB,MAAM,EAAE,aAAa,cAAc,OAAO,MAAM,WAAW,cAC1D,cAAc;AAGf,iBAAgB;AACf,MAAI,QAGH,QAFoB,UAAU,QAAQ;IAIrC,CAAC,SAAS,UAAU,CAAC;AAExB,QAAO;EACN;EACA;EACA;EACA;EACA;EACA;EACA,aAAa;EACb"}
@@ -0,0 +1,34 @@
1
+ import { TimelineItem } from "../timeline-item.js";
2
+ import { CreateConversationResponseBody } from "../conversation.js";
3
+ import { CossistantClient } from "@cossistant/core";
4
+
5
+ //#region src/hooks/use-send-message.d.ts
6
+ type SendMessageOptions = {
7
+ conversationId?: string | null;
8
+ message: string;
9
+ files?: File[];
10
+ defaultTimelineItems?: TimelineItem[];
11
+ visitorId?: string;
12
+ onSuccess?: (conversationId: string, messageId: string) => void;
13
+ onError?: (error: Error) => void;
14
+ };
15
+ type SendMessageResult = {
16
+ conversationId: string;
17
+ messageId: string;
18
+ conversation?: CreateConversationResponseBody["conversation"];
19
+ initialTimelineItems?: CreateConversationResponseBody["initialTimelineItems"];
20
+ };
21
+ type UseSendMessageResult = {
22
+ mutate: (options: SendMessageOptions) => void;
23
+ mutateAsync: (options: SendMessageOptions) => Promise<SendMessageResult | null>;
24
+ isPending: boolean;
25
+ error: Error | null;
26
+ reset: () => void;
27
+ };
28
+ type UseSendMessageOptions = {
29
+ client?: CossistantClient;
30
+ };
31
+ declare function useSendMessage(options?: UseSendMessageOptions): UseSendMessageResult;
32
+ //#endregion
33
+ export { SendMessageOptions, SendMessageResult, UseSendMessageOptions, UseSendMessageResult, useSendMessage };
34
+ //# sourceMappingURL=use-send-message.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-send-message.d.ts","names":[],"sources":["../../src/hooks/use-send-message.ts"],"sourcesContent":[],"mappings":";;;;;KAQY,kBAAA;;EAAA,OAAA,EAAA,MAAA;EAAkB,KAAA,CAAA,EAGrB,IAHqB,EAAA;sBAGrB,CAAA,EACe,YADf,EAAA;WACe,CAAA,EAAA,MAAA;WAGL,CAAA,EAAA,CAAA,cAAA,EAAA,MAAA,EAAA,SAAA,EAAA,MAAA,EAAA,GAAA,IAAA;EAAK,OAAA,CAAA,EAAA,CAAA,KAAA,EAAL,KAAK,EAAA,GAAA,IAAA;AAGxB,CAAA;AAA6B,KAAjB,iBAAA,GAAiB;gBAGb,EAAA,MAAA;WACQ,EAAA,MAAA;EAA8B,YAAA,CAAA,EADtC,8BACsC,CAAA,cAAA,CAAA;EAG1C,oBAAA,CAAA,EAHY,8BAGQ,CAAA,sBAAA,CAAA;CAAA;AACb,KADP,oBAAA,GACO;QAER,EAAA,CAAA,OAAA,EAFQ,kBAER,EAAA,GAAA,IAAA;aACG,EAAA,CAAA,OAAA,EADH,kBACG,EAAA,GAAR,OAAQ,CAAA,iBAAA,GAAA,IAAA,CAAA;WAAR,EAAA,OAAA;OAEE,EAAA,KAAA,GAAA,IAAA;EAAK,KAAA,EAAA,GAAA,GAAA,IAAA;AAIb,CAAA;AAuCgB,KAvCJ,qBAAA,GAuCkB;EAAA,MAAA,CAAA,EAtCpB,gBAsCoB;;AAE3B,iBAFa,cAAA,CAEb,OAAA,CAAA,EADO,qBACP,CAAA,EAAA,oBAAA"}
@@ -0,0 +1,118 @@
1
+ import { useSupport } from "../provider.js";
2
+ import { useCallback, useState } from "react";
3
+ import { generateMessageId } from "@cossistant/core";
4
+
5
+ //#region src/hooks/use-send-message.ts
6
+ function toError(error) {
7
+ if (error instanceof Error) return error;
8
+ if (typeof error === "string") return new Error(error);
9
+ return /* @__PURE__ */ new Error("Unknown error");
10
+ }
11
+ function buildTimelineItemPayload(body, conversationId, visitorId) {
12
+ const nowIso = (/* @__PURE__ */ new Date()).toISOString();
13
+ return {
14
+ id: generateMessageId(),
15
+ conversationId,
16
+ organizationId: "",
17
+ type: "message",
18
+ text: body,
19
+ parts: [{
20
+ type: "text",
21
+ text: body
22
+ }],
23
+ visibility: "public",
24
+ userId: null,
25
+ aiAgentId: null,
26
+ visitorId: visitorId ?? null,
27
+ createdAt: nowIso,
28
+ deletedAt: null
29
+ };
30
+ }
31
+ function useSendMessage(options = {}) {
32
+ const { client: contextClient } = useSupport();
33
+ const client = options.client ?? contextClient;
34
+ const [isPending, setIsPending] = useState(false);
35
+ const [error, setError] = useState(null);
36
+ const mutateAsync = useCallback(async (payload) => {
37
+ const { conversationId: providedConversationId, message, defaultTimelineItems = [], visitorId, onSuccess, onError } = payload;
38
+ if (!message.trim()) {
39
+ const emptyMessageError = /* @__PURE__ */ new Error("Message cannot be empty");
40
+ setError(emptyMessageError);
41
+ onError?.(emptyMessageError);
42
+ return null;
43
+ }
44
+ setIsPending(true);
45
+ setError(null);
46
+ try {
47
+ let conversationId = providedConversationId ?? void 0;
48
+ let preparedDefaultTimelineItems = defaultTimelineItems;
49
+ let initialConversation;
50
+ if (!conversationId) {
51
+ const initiated = client.initiateConversation({
52
+ defaultTimelineItems,
53
+ visitorId: visitorId ?? void 0
54
+ });
55
+ conversationId = initiated.conversationId;
56
+ preparedDefaultTimelineItems = initiated.defaultTimelineItems;
57
+ initialConversation = initiated.conversation;
58
+ }
59
+ const timelineItemPayload = buildTimelineItemPayload(message, conversationId, visitorId ?? null);
60
+ const response = await client.sendMessage({
61
+ conversationId,
62
+ item: {
63
+ id: timelineItemPayload.id,
64
+ text: timelineItemPayload.text ?? "",
65
+ type: timelineItemPayload.type,
66
+ visibility: timelineItemPayload.visibility,
67
+ userId: timelineItemPayload.userId,
68
+ aiAgentId: timelineItemPayload.aiAgentId,
69
+ visitorId: timelineItemPayload.visitorId,
70
+ createdAt: timelineItemPayload.createdAt,
71
+ parts: timelineItemPayload.parts
72
+ },
73
+ createIfPending: true
74
+ });
75
+ const messageId = response.item.id;
76
+ if (!messageId) throw new Error("SendMessage response missing item.id");
77
+ const result = {
78
+ conversationId,
79
+ messageId
80
+ };
81
+ if ("conversation" in response && response.conversation) {
82
+ result.conversation = response.conversation;
83
+ result.initialTimelineItems = response.initialTimelineItems;
84
+ } else if (initialConversation) {
85
+ result.conversation = initialConversation;
86
+ result.initialTimelineItems = preparedDefaultTimelineItems;
87
+ }
88
+ setIsPending(false);
89
+ setError(null);
90
+ onSuccess?.(result.conversationId, result.messageId);
91
+ return result;
92
+ } catch (raw) {
93
+ const normalised = toError(raw);
94
+ setIsPending(false);
95
+ setError(normalised);
96
+ onError?.(normalised);
97
+ throw normalised;
98
+ }
99
+ }, [client]);
100
+ const mutate = useCallback((opts) => {
101
+ mutateAsync(opts).catch(() => {});
102
+ }, [mutateAsync]);
103
+ const reset = useCallback(() => {
104
+ setError(null);
105
+ setIsPending(false);
106
+ }, []);
107
+ return {
108
+ mutate,
109
+ mutateAsync,
110
+ isPending,
111
+ error,
112
+ reset
113
+ };
114
+ }
115
+
116
+ //#endregion
117
+ export { useSendMessage };
118
+ //# sourceMappingURL=use-send-message.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-send-message.js","names":["initialConversation:\n\t\t\t\t\t| CreateConversationResponseBody[\"conversation\"]\n\t\t\t\t\t| undefined","result: SendMessageResult"],"sources":["../../src/hooks/use-send-message.ts"],"sourcesContent":["import type { CossistantClient } from \"@cossistant/core\";\nimport { generateMessageId } from \"@cossistant/core\";\nimport type { CreateConversationResponseBody } from \"@cossistant/types/api/conversation\";\nimport type { TimelineItem } from \"@cossistant/types/api/timeline-item\";\nimport { useCallback, useState } from \"react\";\n\nimport { useSupport } from \"../provider\";\n\nexport type SendMessageOptions = {\n\tconversationId?: string | null;\n\tmessage: string;\n\tfiles?: File[];\n\tdefaultTimelineItems?: TimelineItem[];\n\tvisitorId?: string;\n\tonSuccess?: (conversationId: string, messageId: string) => void;\n\tonError?: (error: Error) => void;\n};\n\nexport type SendMessageResult = {\n\tconversationId: string;\n\tmessageId: string;\n\tconversation?: CreateConversationResponseBody[\"conversation\"];\n\tinitialTimelineItems?: CreateConversationResponseBody[\"initialTimelineItems\"];\n};\n\nexport type UseSendMessageResult = {\n\tmutate: (options: SendMessageOptions) => void;\n\tmutateAsync: (\n\t\toptions: SendMessageOptions\n\t) => Promise<SendMessageResult | null>;\n\tisPending: boolean;\n\terror: Error | null;\n\treset: () => void;\n};\n\nexport type UseSendMessageOptions = {\n\tclient?: CossistantClient;\n};\n\nfunction toError(error: unknown): Error {\n\tif (error instanceof Error) {\n\t\treturn error;\n\t}\n\n\tif (typeof error === \"string\") {\n\t\treturn new Error(error);\n\t}\n\n\treturn new Error(\"Unknown error\");\n}\n\nfunction buildTimelineItemPayload(\n\tbody: string,\n\tconversationId: string,\n\tvisitorId?: string | null\n): TimelineItem {\n\tconst nowIso = new Date().toISOString();\n\n\treturn {\n\t\tid: generateMessageId(),\n\t\tconversationId,\n\t\torganizationId: \"\", // Will be set by backend\n\t\ttype: \"message\" as const,\n\t\ttext: body,\n\t\tparts: [{ type: \"text\" as const, text: body }],\n\t\tvisibility: \"public\" as const,\n\t\tuserId: null,\n\t\taiAgentId: null,\n\t\tvisitorId: visitorId ?? null,\n\t\tcreatedAt: nowIso,\n\t\tdeletedAt: null,\n\t} satisfies TimelineItem;\n}\n\nexport function useSendMessage(\n\toptions: UseSendMessageOptions = {}\n): UseSendMessageResult {\n\tconst { client: contextClient } = useSupport();\n\tconst client = options.client ?? contextClient;\n\n\tconst [isPending, setIsPending] = useState(false);\n\tconst [error, setError] = useState<Error | null>(null);\n\n\tconst mutateAsync = useCallback(\n\t\tasync (payload: SendMessageOptions): Promise<SendMessageResult | null> => {\n\t\t\tconst {\n\t\t\t\tconversationId: providedConversationId,\n\t\t\t\tmessage,\n\t\t\t\tdefaultTimelineItems = [],\n\t\t\t\tvisitorId,\n\t\t\t\tonSuccess,\n\t\t\t\tonError,\n\t\t\t} = payload;\n\n\t\t\tif (!message.trim()) {\n\t\t\t\tconst emptyMessageError = new Error(\"Message cannot be empty\");\n\t\t\t\tsetError(emptyMessageError);\n\t\t\t\tonError?.(emptyMessageError);\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tsetIsPending(true);\n\t\t\tsetError(null);\n\n\t\t\ttry {\n\t\t\t\tlet conversationId = providedConversationId ?? undefined;\n\t\t\t\tlet preparedDefaultTimelineItems = defaultTimelineItems;\n\t\t\t\tlet initialConversation:\n\t\t\t\t\t| CreateConversationResponseBody[\"conversation\"]\n\t\t\t\t\t| undefined;\n\n\t\t\t\tif (!conversationId) {\n\t\t\t\t\tconst initiated = client.initiateConversation({\n\t\t\t\t\t\tdefaultTimelineItems,\n\t\t\t\t\t\tvisitorId: visitorId ?? undefined,\n\t\t\t\t\t});\n\t\t\t\t\tconversationId = initiated.conversationId;\n\t\t\t\t\tpreparedDefaultTimelineItems = initiated.defaultTimelineItems;\n\t\t\t\t\tinitialConversation = initiated.conversation;\n\t\t\t\t}\n\n\t\t\t\tconst timelineItemPayload = buildTimelineItemPayload(\n\t\t\t\t\tmessage,\n\t\t\t\t\tconversationId,\n\t\t\t\t\tvisitorId ?? null\n\t\t\t\t);\n\n\t\t\t\tconst response = await client.sendMessage({\n\t\t\t\t\tconversationId,\n\t\t\t\t\titem: {\n\t\t\t\t\t\tid: timelineItemPayload.id,\n\t\t\t\t\t\ttext: timelineItemPayload.text ?? \"\",\n\t\t\t\t\t\ttype: timelineItemPayload.type,\n\t\t\t\t\t\tvisibility: timelineItemPayload.visibility,\n\t\t\t\t\t\tuserId: timelineItemPayload.userId,\n\t\t\t\t\t\taiAgentId: timelineItemPayload.aiAgentId,\n\t\t\t\t\t\tvisitorId: timelineItemPayload.visitorId,\n\t\t\t\t\t\tcreatedAt: timelineItemPayload.createdAt,\n\t\t\t\t\t\tparts: timelineItemPayload.parts,\n\t\t\t\t\t},\n\t\t\t\t\tcreateIfPending: true,\n\t\t\t\t});\n\n\t\t\t\tconst messageId = response.item.id;\n\n\t\t\t\tif (!messageId) {\n\t\t\t\t\tthrow new Error(\"SendMessage response missing item.id\");\n\t\t\t\t}\n\n\t\t\t\tconst result: SendMessageResult = {\n\t\t\t\t\tconversationId,\n\t\t\t\t\tmessageId,\n\t\t\t\t};\n\n\t\t\t\tif (\"conversation\" in response && response.conversation) {\n\t\t\t\t\tresult.conversation = response.conversation;\n\t\t\t\t\tresult.initialTimelineItems = response.initialTimelineItems;\n\t\t\t\t} else if (initialConversation) {\n\t\t\t\t\tresult.conversation = initialConversation;\n\t\t\t\t\tresult.initialTimelineItems = preparedDefaultTimelineItems;\n\t\t\t\t}\n\n\t\t\t\tsetIsPending(false);\n\t\t\t\tsetError(null);\n\t\t\t\tonSuccess?.(result.conversationId, result.messageId);\n\t\t\t\treturn result;\n\t\t\t} catch (raw) {\n\t\t\t\tconst normalised = toError(raw);\n\t\t\t\tsetIsPending(false);\n\t\t\t\tsetError(normalised);\n\t\t\t\tonError?.(normalised);\n\t\t\t\tthrow normalised;\n\t\t\t}\n\t\t},\n\t\t[client]\n\t);\n\n\tconst mutate = useCallback(\n\t\t(opts: SendMessageOptions) => {\n\t\t\tvoid mutateAsync(opts).catch(() => {\n\t\t\t\t// Swallow errors to mimic react-query behaviour for mutate\n\t\t\t});\n\t\t},\n\t\t[mutateAsync]\n\t);\n\n\tconst reset = useCallback(() => {\n\t\tsetError(null);\n\t\tsetIsPending(false);\n\t}, []);\n\n\treturn {\n\t\tmutate,\n\t\tmutateAsync,\n\t\tisPending,\n\t\terror,\n\t\treset,\n\t};\n}\n"],"mappings":";;;;;AAuCA,SAAS,QAAQ,OAAuB;AACvC,KAAI,iBAAiB,MACpB,QAAO;AAGR,KAAI,OAAO,UAAU,SACpB,QAAO,IAAI,MAAM,MAAM;AAGxB,wBAAO,IAAI,MAAM,gBAAgB;;AAGlC,SAAS,yBACR,MACA,gBACA,WACe;CACf,MAAM,0BAAS,IAAI,MAAM,EAAC,aAAa;AAEvC,QAAO;EACN,IAAI,mBAAmB;EACvB;EACA,gBAAgB;EAChB,MAAM;EACN,MAAM;EACN,OAAO,CAAC;GAAE,MAAM;GAAiB,MAAM;GAAM,CAAC;EAC9C,YAAY;EACZ,QAAQ;EACR,WAAW;EACX,WAAW,aAAa;EACxB,WAAW;EACX,WAAW;EACX;;AAGF,SAAgB,eACf,UAAiC,EAAE,EACZ;CACvB,MAAM,EAAE,QAAQ,kBAAkB,YAAY;CAC9C,MAAM,SAAS,QAAQ,UAAU;CAEjC,MAAM,CAAC,WAAW,gBAAgB,SAAS,MAAM;CACjD,MAAM,CAAC,OAAO,YAAY,SAAuB,KAAK;CAEtD,MAAM,cAAc,YACnB,OAAO,YAAmE;EACzE,MAAM,EACL,gBAAgB,wBAChB,SACA,uBAAuB,EAAE,EACzB,WACA,WACA,YACG;AAEJ,MAAI,CAAC,QAAQ,MAAM,EAAE;GACpB,MAAM,oCAAoB,IAAI,MAAM,0BAA0B;AAC9D,YAAS,kBAAkB;AAC3B,aAAU,kBAAkB;AAC5B,UAAO;;AAGR,eAAa,KAAK;AAClB,WAAS,KAAK;AAEd,MAAI;GACH,IAAI,iBAAiB,0BAA0B;GAC/C,IAAI,+BAA+B;GACnC,IAAIA;AAIJ,OAAI,CAAC,gBAAgB;IACpB,MAAM,YAAY,OAAO,qBAAqB;KAC7C;KACA,WAAW,aAAa;KACxB,CAAC;AACF,qBAAiB,UAAU;AAC3B,mCAA+B,UAAU;AACzC,0BAAsB,UAAU;;GAGjC,MAAM,sBAAsB,yBAC3B,SACA,gBACA,aAAa,KACb;GAED,MAAM,WAAW,MAAM,OAAO,YAAY;IACzC;IACA,MAAM;KACL,IAAI,oBAAoB;KACxB,MAAM,oBAAoB,QAAQ;KAClC,MAAM,oBAAoB;KAC1B,YAAY,oBAAoB;KAChC,QAAQ,oBAAoB;KAC5B,WAAW,oBAAoB;KAC/B,WAAW,oBAAoB;KAC/B,WAAW,oBAAoB;KAC/B,OAAO,oBAAoB;KAC3B;IACD,iBAAiB;IACjB,CAAC;GAEF,MAAM,YAAY,SAAS,KAAK;AAEhC,OAAI,CAAC,UACJ,OAAM,IAAI,MAAM,uCAAuC;GAGxD,MAAMC,SAA4B;IACjC;IACA;IACA;AAED,OAAI,kBAAkB,YAAY,SAAS,cAAc;AACxD,WAAO,eAAe,SAAS;AAC/B,WAAO,uBAAuB,SAAS;cAC7B,qBAAqB;AAC/B,WAAO,eAAe;AACtB,WAAO,uBAAuB;;AAG/B,gBAAa,MAAM;AACnB,YAAS,KAAK;AACd,eAAY,OAAO,gBAAgB,OAAO,UAAU;AACpD,UAAO;WACC,KAAK;GACb,MAAM,aAAa,QAAQ,IAAI;AAC/B,gBAAa,MAAM;AACnB,YAAS,WAAW;AACpB,aAAU,WAAW;AACrB,SAAM;;IAGR,CAAC,OAAO,CACR;CAED,MAAM,SAAS,aACb,SAA6B;AAC7B,EAAK,YAAY,KAAK,CAAC,YAAY,GAEjC;IAEH,CAAC,YAAY,CACb;CAED,MAAM,QAAQ,kBAAkB;AAC/B,WAAS,KAAK;AACd,eAAa,MAAM;IACjB,EAAE,CAAC;AAEN,QAAO;EACN;EACA;EACA;EACA;EACA;EACA"}
@@ -0,0 +1,28 @@
1
+ import { PublicVisitor, VisitorMetadata, VisitorResponse } from "@cossistant/types";
2
+
3
+ //#region src/hooks/use-visitor.d.ts
4
+ type UseVisitorReturn = {
5
+ visitor: PublicVisitor | null;
6
+ setVisitorMetadata: (metadata: VisitorMetadata) => Promise<VisitorResponse | null>;
7
+ identify: (params: {
8
+ externalId?: string;
9
+ email?: string;
10
+ name?: string;
11
+ image?: string;
12
+ metadata?: Record<string, unknown>;
13
+ }) => Promise<{
14
+ contactId: string;
15
+ visitorId: string;
16
+ } | null>;
17
+ };
18
+ /**
19
+ * Exposes the current visitor plus helpers to identify and update metadata.
20
+ *
21
+ * Note: Metadata is stored on contacts, not visitors. When you call
22
+ * setVisitorMetadata, it will update the contact metadata if the visitor
23
+ * has been identified. If not, you must call identify() first.
24
+ */
25
+ declare function useVisitor(): UseVisitorReturn;
26
+ //#endregion
27
+ export { UseVisitorReturn, useVisitor };
28
+ //# sourceMappingURL=use-visitor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-visitor.d.ts","names":[],"sources":["../../src/hooks/use-visitor.ts"],"sourcesContent":[],"mappings":";;;KAQY,gBAAA;WACF;EADE,kBAAA,EAAgB,CAAA,QAAA,EAGhB,eAHgB,EAAA,GAItB,OAJsB,CAId,eAJc,GAAA,IAAA,CAAA;EAAA,QAAA,EAAA,CAAA,MAAA,EAAA;IAClB,UAAA,CAAA,EAAA,MAAA;IAEE,KAAA,CAAA,EAAA,MAAA;IACE,IAAA,CAAA,EAAA,MAAA;IAAR,KAAA,CAAA,EAAA,MAAA;IAMO,QAAA,CAAA,EAAA,MAAA,CAAA,MAAA,EAAA,OAAA,CAAA;KACN,GAAA,OAAA,CAAA;IAAO,SAAA,EAAA,MAAA;IAsBE,SAAU,EAAA,MAAA;;;;;;;;;;iBAAV,UAAA,CAAA,GAAc"}
@@ -0,0 +1,59 @@
1
+ import { useSupport } from "../provider.js";
2
+ import { useCallback } from "react";
3
+
4
+ //#region src/hooks/use-visitor.ts
5
+ function safeWarn(message) {
6
+ if (typeof console !== "undefined" && typeof console.warn === "function") console.warn(message);
7
+ }
8
+ function safeError(message, error) {
9
+ if (typeof console !== "undefined" && typeof console.error === "function") console.error(message, error);
10
+ }
11
+ /**
12
+ * Exposes the current visitor plus helpers to identify and update metadata.
13
+ *
14
+ * Note: Metadata is stored on contacts, not visitors. When you call
15
+ * setVisitorMetadata, it will update the contact metadata if the visitor
16
+ * has been identified. If not, you must call identify() first.
17
+ */
18
+ function useVisitor() {
19
+ const { website, client } = useSupport();
20
+ const visitor = website?.visitor || null;
21
+ const visitorId = visitor?.id ?? null;
22
+ const setVisitorMetadata = useCallback(async (metadata) => {
23
+ if (!visitorId) {
24
+ safeWarn("No visitor is associated with this session; metadata update skipped");
25
+ return null;
26
+ }
27
+ try {
28
+ return await client.updateVisitorMetadata(metadata);
29
+ } catch (error) {
30
+ safeError("Failed to update visitor metadata", error);
31
+ return null;
32
+ }
33
+ }, [client, visitorId]);
34
+ const identify = useCallback(async (params) => {
35
+ if (!visitorId) {
36
+ safeWarn("No visitor is associated with this session; identify skipped");
37
+ return null;
38
+ }
39
+ try {
40
+ const result = await client.identify(params);
41
+ return {
42
+ contactId: result.contact.id,
43
+ visitorId: result.visitorId
44
+ };
45
+ } catch (error) {
46
+ safeError("Failed to identify visitor", error);
47
+ return null;
48
+ }
49
+ }, [client, visitorId]);
50
+ return {
51
+ visitor,
52
+ setVisitorMetadata,
53
+ identify
54
+ };
55
+ }
56
+
57
+ //#endregion
58
+ export { useVisitor };
59
+ //# sourceMappingURL=use-visitor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-visitor.js","names":[],"sources":["../../src/hooks/use-visitor.ts"],"sourcesContent":["import type {\n\tPublicVisitor,\n\tVisitorMetadata,\n\tVisitorResponse,\n} from \"@cossistant/types\";\nimport { useCallback } from \"react\";\nimport { useSupport } from \"../provider\";\n\nexport type UseVisitorReturn = {\n\tvisitor: PublicVisitor | null;\n\tsetVisitorMetadata: (\n\t\tmetadata: VisitorMetadata\n\t) => Promise<VisitorResponse | null>;\n\tidentify: (params: {\n\t\texternalId?: string;\n\t\temail?: string;\n\t\tname?: string;\n\t\timage?: string;\n\t\tmetadata?: Record<string, unknown>;\n\t}) => Promise<{ contactId: string; visitorId: string } | null>;\n};\n\nfunction safeWarn(message: string): void {\n\tif (typeof console !== \"undefined\" && typeof console.warn === \"function\") {\n\t\tconsole.warn(message);\n\t}\n}\n\nfunction safeError(message: string, error: unknown): void {\n\tif (typeof console !== \"undefined\" && typeof console.error === \"function\") {\n\t\tconsole.error(message, error);\n\t}\n}\n\n/**\n * Exposes the current visitor plus helpers to identify and update metadata.\n *\n * Note: Metadata is stored on contacts, not visitors. When you call\n * setVisitorMetadata, it will update the contact metadata if the visitor\n * has been identified. If not, you must call identify() first.\n */\nexport function useVisitor(): UseVisitorReturn {\n\tconst { website, client } = useSupport();\n\tconst visitor = website?.visitor || null;\n\tconst visitorId = visitor?.id ?? null;\n\n\tconst setVisitorMetadata = useCallback<\n\t\t(metadata: VisitorMetadata) => Promise<VisitorResponse | null>\n\t>(\n\t\tasync (metadata) => {\n\t\t\tif (!visitorId) {\n\t\t\t\tsafeWarn(\n\t\t\t\t\t\"No visitor is associated with this session; metadata update skipped\"\n\t\t\t\t);\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\treturn await client.updateVisitorMetadata(metadata);\n\t\t\t} catch (error) {\n\t\t\t\tsafeError(\"Failed to update visitor metadata\", error);\n\t\t\t\treturn null;\n\t\t\t}\n\t\t},\n\t\t[client, visitorId]\n\t);\n\n\tconst identify = useCallback<\n\t\t(params: {\n\t\t\texternalId?: string;\n\t\t\temail?: string;\n\t\t\tname?: string;\n\t\t\timage?: string;\n\t\t\tmetadata?: Record<string, unknown>;\n\t\t}) => Promise<{ contactId: string; visitorId: string } | null>\n\t>(\n\t\tasync (params) => {\n\t\t\tif (!visitorId) {\n\t\t\t\tsafeWarn(\n\t\t\t\t\t\"No visitor is associated with this session; identify skipped\"\n\t\t\t\t);\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tconst result = await client.identify(params);\n\n\t\t\t\treturn {\n\t\t\t\t\tcontactId: result.contact.id,\n\t\t\t\t\tvisitorId: result.visitorId,\n\t\t\t\t};\n\t\t\t} catch (error) {\n\t\t\t\tsafeError(\"Failed to identify visitor\", error);\n\t\t\t\treturn null;\n\t\t\t}\n\t\t},\n\t\t[client, visitorId]\n\t);\n\n\treturn {\n\t\tvisitor,\n\t\tsetVisitorMetadata,\n\t\tidentify,\n\t};\n}\n"],"mappings":";;;;AAsBA,SAAS,SAAS,SAAuB;AACxC,KAAI,OAAO,YAAY,eAAe,OAAO,QAAQ,SAAS,WAC7D,SAAQ,KAAK,QAAQ;;AAIvB,SAAS,UAAU,SAAiB,OAAsB;AACzD,KAAI,OAAO,YAAY,eAAe,OAAO,QAAQ,UAAU,WAC9D,SAAQ,MAAM,SAAS,MAAM;;;;;;;;;AAW/B,SAAgB,aAA+B;CAC9C,MAAM,EAAE,SAAS,WAAW,YAAY;CACxC,MAAM,UAAU,SAAS,WAAW;CACpC,MAAM,YAAY,SAAS,MAAM;CAEjC,MAAM,qBAAqB,YAG1B,OAAO,aAAa;AACnB,MAAI,CAAC,WAAW;AACf,YACC,sEACA;AACD,UAAO;;AAGR,MAAI;AACH,UAAO,MAAM,OAAO,sBAAsB,SAAS;WAC3C,OAAO;AACf,aAAU,qCAAqC,MAAM;AACrD,UAAO;;IAGT,CAAC,QAAQ,UAAU,CACnB;CAED,MAAM,WAAW,YAShB,OAAO,WAAW;AACjB,MAAI,CAAC,WAAW;AACf,YACC,+DACA;AACD,UAAO;;AAGR,MAAI;GACH,MAAM,SAAS,MAAM,OAAO,SAAS,OAAO;AAE5C,UAAO;IACN,WAAW,OAAO,QAAQ;IAC1B,WAAW,OAAO;IAClB;WACO,OAAO;AACf,aAAU,8BAA8B,MAAM;AAC9C,UAAO;;IAGT,CAAC,QAAQ,UAAU,CACnB;AAED,QAAO;EACN;EACA;EACA;EACA"}
@@ -0,0 +1,9 @@
1
+ //#region src/hooks/use-window-visibility-focus.d.ts
2
+ type WindowVisibilityFocusState = {
3
+ isPageVisible: boolean;
4
+ hasWindowFocus: boolean;
5
+ };
6
+ declare function useWindowVisibilityFocus(): WindowVisibilityFocusState;
7
+ //#endregion
8
+ export { WindowVisibilityFocusState, useWindowVisibilityFocus };
9
+ //# sourceMappingURL=use-window-visibility-focus.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-window-visibility-focus.d.ts","names":[],"sources":["../../src/hooks/use-window-visibility-focus.ts"],"sourcesContent":[],"mappings":";KAEY,0BAAA;EAAA,aAAA,EAAA,OAAA;EAkBI,cAAA,EAAA,OAAA;;iBAAA,wBAAA,CAAA,GAA4B"}
@@ -0,0 +1,53 @@
1
+ import { useEffect, useState } from "react";
2
+
3
+ //#region src/hooks/use-window-visibility-focus.ts
4
+ const getVisibilityFocusState = () => {
5
+ if (typeof document === "undefined") return {
6
+ isPageVisible: true,
7
+ hasWindowFocus: true
8
+ };
9
+ const isPageVisible = !document.hidden;
10
+ const hasWindowFocus = isPageVisible && (typeof document.hasFocus === "function" ? document.hasFocus() : true);
11
+ return {
12
+ isPageVisible,
13
+ hasWindowFocus
14
+ };
15
+ };
16
+ function useWindowVisibilityFocus() {
17
+ const [state, setState] = useState(() => getVisibilityFocusState());
18
+ useEffect(() => {
19
+ if (typeof document === "undefined") return;
20
+ const handleVisibilityChange = () => {
21
+ setState(getVisibilityFocusState());
22
+ };
23
+ document.addEventListener("visibilitychange", handleVisibilityChange);
24
+ handleVisibilityChange();
25
+ return () => {
26
+ document.removeEventListener("visibilitychange", handleVisibilityChange);
27
+ };
28
+ }, []);
29
+ useEffect(() => {
30
+ if (typeof window === "undefined") return;
31
+ const syncVisibilityFocus = () => {
32
+ setState(getVisibilityFocusState());
33
+ };
34
+ const handleFocus = () => {
35
+ syncVisibilityFocus();
36
+ };
37
+ const handleBlur = () => {
38
+ syncVisibilityFocus();
39
+ };
40
+ window.addEventListener("focus", handleFocus);
41
+ window.addEventListener("blur", handleBlur);
42
+ syncVisibilityFocus();
43
+ return () => {
44
+ window.removeEventListener("focus", handleFocus);
45
+ window.removeEventListener("blur", handleBlur);
46
+ };
47
+ }, []);
48
+ return state;
49
+ }
50
+
51
+ //#endregion
52
+ export { useWindowVisibilityFocus };
53
+ //# sourceMappingURL=use-window-visibility-focus.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-window-visibility-focus.js","names":[],"sources":["../../src/hooks/use-window-visibility-focus.ts"],"sourcesContent":["import { useEffect, useState } from \"react\";\n\nexport type WindowVisibilityFocusState = {\n isPageVisible: boolean;\n hasWindowFocus: boolean;\n};\n\nconst getVisibilityFocusState = (): WindowVisibilityFocusState => {\n if (typeof document === \"undefined\") {\n return { isPageVisible: true, hasWindowFocus: true };\n }\n\n const isPageVisible = !document.hidden;\n const hasWindowFocus =\n isPageVisible &&\n (typeof document.hasFocus === \"function\" ? document.hasFocus() : true);\n\n return { isPageVisible, hasWindowFocus };\n};\n\nexport function useWindowVisibilityFocus(): WindowVisibilityFocusState {\n const [state, setState] = useState<WindowVisibilityFocusState>(\n () => getVisibilityFocusState()\n );\n\n useEffect(() => {\n if (typeof document === \"undefined\") {\n return;\n }\n\n const handleVisibilityChange = () => {\n setState(getVisibilityFocusState());\n };\n\n document.addEventListener(\"visibilitychange\", handleVisibilityChange);\n handleVisibilityChange();\n return () => {\n document.removeEventListener(\n \"visibilitychange\",\n handleVisibilityChange\n );\n };\n }, []);\n\n useEffect(() => {\n if (typeof window === \"undefined\") {\n return;\n }\n\n const syncVisibilityFocus = () => {\n setState(getVisibilityFocusState());\n };\n\n const handleFocus = () => {\n syncVisibilityFocus();\n };\n const handleBlur = () => {\n syncVisibilityFocus();\n };\n\n window.addEventListener(\"focus\", handleFocus);\n window.addEventListener(\"blur\", handleBlur);\n\n syncVisibilityFocus();\n\n return () => {\n window.removeEventListener(\"focus\", handleFocus);\n window.removeEventListener(\"blur\", handleBlur);\n };\n }, []);\n\n return state;\n}\n"],"mappings":";;;AAOA,MAAM,gCAA4D;AAC1D,KAAI,OAAO,aAAa,YAChB,QAAO;EAAE,eAAe;EAAM,gBAAgB;EAAM;CAG5D,MAAM,gBAAgB,CAAC,SAAS;CAChC,MAAM,iBACE,kBACC,OAAO,SAAS,aAAa,aAAa,SAAS,UAAU,GAAG;AAEzE,QAAO;EAAE;EAAe;EAAgB;;AAGhD,SAAgB,2BAAuD;CAC/D,MAAM,CAAC,OAAO,YAAY,eACZ,yBAAyB,CACtC;AAED,iBAAgB;AACR,MAAI,OAAO,aAAa,YAChB;EAGR,MAAM,+BAA+B;AAC7B,YAAS,yBAAyB,CAAC;;AAG3C,WAAS,iBAAiB,oBAAoB,uBAAuB;AACrE,0BAAwB;AACxB,eAAa;AACL,YAAS,oBACD,oBACA,uBACP;;IAEd,EAAE,CAAC;AAEN,iBAAgB;AACR,MAAI,OAAO,WAAW,YACd;EAGR,MAAM,4BAA4B;AAC1B,YAAS,yBAAyB,CAAC;;EAG3C,MAAM,oBAAoB;AAClB,wBAAqB;;EAE7B,MAAM,mBAAmB;AACjB,wBAAqB;;AAG7B,SAAO,iBAAiB,SAAS,YAAY;AAC7C,SAAO,iBAAiB,QAAQ,WAAW;AAE3C,uBAAqB;AAErB,eAAa;AACL,UAAO,oBAAoB,SAAS,YAAY;AAChD,UAAO,oBAAoB,QAAQ,WAAW;;IAE3D,EAAE,CAAC;AAEN,QAAO"}
@@ -0,0 +1,18 @@
1
+ //#region src/identify-visitor.d.ts
2
+ type IdentifySupportVisitorProps = {
3
+ externalId?: string;
4
+ email?: string;
5
+ };
6
+ /**
7
+ * Component exposed by Cossistant allowing you to identify a visitor whenever rendered with either an `externalId` or `email`.
8
+ */
9
+ declare const IdentifySupportVisitor: {
10
+ ({
11
+ externalId,
12
+ email
13
+ }: IdentifySupportVisitorProps): null;
14
+ displayName: string;
15
+ };
16
+ //#endregion
17
+ export { IdentifySupportVisitor, IdentifySupportVisitorProps };
18
+ //# sourceMappingURL=identify-visitor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identify-visitor.d.ts","names":[],"sources":["../src/identify-visitor.tsx"],"sourcesContent":[],"mappings":";KAIY,2BAAA;EAAA,UAAA,CAAA,EAAA,MAAA;EAQC,KAAA,CAAA,EAAA,MAAA;CAcZ;;;;AAX6B,cAHjB,sBAGiB,EAAA;;;;KAA3B"}