@cossistant/react 0.0.3 → 0.0.5

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 (320) hide show
  1. package/README.md +74 -0
  2. package/_virtual/rolldown_runtime.js +19 -0
  3. package/conversation.d.ts +26 -3
  4. package/conversation.d.ts.map +1 -1
  5. package/hooks/index.d.ts +5 -3
  6. package/hooks/index.js +7 -5
  7. package/hooks/private/store/use-conversations-store.d.ts +8 -0
  8. package/hooks/private/store/use-conversations-store.d.ts.map +1 -1
  9. package/hooks/private/store/use-conversations-store.js +8 -0
  10. package/hooks/private/store/use-conversations-store.js.map +1 -1
  11. package/hooks/private/store/use-store-selector.d.ts +4 -0
  12. package/hooks/private/store/use-store-selector.d.ts.map +1 -1
  13. package/hooks/private/store/use-store-selector.js +5 -2
  14. package/hooks/private/store/use-store-selector.js.map +1 -1
  15. package/hooks/private/store/use-website-store.d.ts +4 -0
  16. package/hooks/private/store/use-website-store.d.ts.map +1 -1
  17. package/hooks/private/store/use-website-store.js +6 -3
  18. package/hooks/private/store/use-website-store.js.map +1 -1
  19. package/hooks/private/typing.d.ts +35 -0
  20. package/hooks/private/typing.d.ts.map +1 -0
  21. package/hooks/private/typing.js +49 -0
  22. package/hooks/private/typing.js.map +1 -0
  23. package/hooks/private/use-client-query.d.ts +5 -0
  24. package/hooks/private/use-client-query.d.ts.map +1 -1
  25. package/hooks/private/use-client-query.js +5 -0
  26. package/hooks/private/use-client-query.js.map +1 -1
  27. package/hooks/private/use-grouped-messages.d.ts +10 -4
  28. package/hooks/private/use-grouped-messages.d.ts.map +1 -1
  29. package/hooks/private/use-grouped-messages.js +24 -4
  30. package/hooks/private/use-grouped-messages.js.map +1 -1
  31. package/hooks/private/use-multimodal-input.d.ts.map +1 -1
  32. package/hooks/private/use-rest-client.d.ts.map +1 -1
  33. package/hooks/private/use-visitor-typing-reporter.d.ts +6 -0
  34. package/hooks/private/use-visitor-typing-reporter.d.ts.map +1 -1
  35. package/hooks/private/use-visitor-typing-reporter.js +6 -0
  36. package/hooks/private/use-visitor-typing-reporter.js.map +1 -1
  37. package/hooks/use-composer-refocus.d.ts.map +1 -1
  38. package/hooks/use-conversation-auto-seen.d.ts +9 -0
  39. package/hooks/use-conversation-auto-seen.d.ts.map +1 -1
  40. package/hooks/use-conversation-auto-seen.js +44 -3
  41. package/hooks/use-conversation-auto-seen.js.map +1 -1
  42. package/hooks/use-conversation-history-page.d.ts.map +1 -1
  43. package/hooks/use-conversation-history-page.js +16 -18
  44. package/hooks/use-conversation-history-page.js.map +1 -1
  45. package/hooks/use-conversation-lifecycle.d.ts.map +1 -1
  46. package/hooks/use-conversation-lifecycle.js +2 -4
  47. package/hooks/use-conversation-lifecycle.js.map +1 -1
  48. package/hooks/use-conversation-page.d.ts +6 -0
  49. package/hooks/use-conversation-page.d.ts.map +1 -1
  50. package/hooks/use-conversation-page.js +41 -3
  51. package/hooks/use-conversation-page.js.map +1 -1
  52. package/hooks/use-conversation-preview.d.ts +61 -0
  53. package/hooks/use-conversation-preview.d.ts.map +1 -0
  54. package/hooks/use-conversation-preview.js +173 -0
  55. package/hooks/use-conversation-preview.js.map +1 -0
  56. package/hooks/use-conversation-seen.d.ts +4 -0
  57. package/hooks/use-conversation-seen.d.ts.map +1 -1
  58. package/hooks/use-conversation-seen.js +4 -0
  59. package/hooks/use-conversation-seen.js.map +1 -1
  60. package/hooks/use-conversation-timeline-items.d.ts +4 -0
  61. package/hooks/use-conversation-timeline-items.d.ts.map +1 -1
  62. package/hooks/use-conversation-timeline-items.js +4 -0
  63. package/hooks/use-conversation-timeline-items.js.map +1 -1
  64. package/hooks/use-conversation-timeline.d.ts +32 -0
  65. package/hooks/use-conversation-timeline.d.ts.map +1 -0
  66. package/hooks/use-conversation-timeline.js +41 -0
  67. package/hooks/use-conversation-timeline.js.map +1 -0
  68. package/hooks/use-conversation-typing.d.ts +4 -0
  69. package/hooks/use-conversation-typing.d.ts.map +1 -1
  70. package/hooks/use-conversation-typing.js +4 -0
  71. package/hooks/use-conversation-typing.js.map +1 -1
  72. package/hooks/use-conversation.d.ts +11 -0
  73. package/hooks/use-conversation.d.ts.map +1 -1
  74. package/hooks/use-conversation.js +11 -0
  75. package/hooks/use-conversation.js.map +1 -1
  76. package/hooks/use-conversations.d.ts +12 -0
  77. package/hooks/use-conversations.d.ts.map +1 -1
  78. package/hooks/use-conversations.js +12 -0
  79. package/hooks/use-conversations.js.map +1 -1
  80. package/hooks/use-create-conversation.d.ts +5 -0
  81. package/hooks/use-create-conversation.d.ts.map +1 -1
  82. package/hooks/use-create-conversation.js +12 -9
  83. package/hooks/use-create-conversation.js.map +1 -1
  84. package/hooks/use-home-page.d.ts.map +1 -1
  85. package/hooks/use-home-page.js +6 -4
  86. package/hooks/use-home-page.js.map +1 -1
  87. package/hooks/use-message-composer.d.ts.map +1 -1
  88. package/hooks/use-realtime-support.d.ts.map +1 -1
  89. package/hooks/use-send-message.d.ts +9 -0
  90. package/hooks/use-send-message.d.ts.map +1 -1
  91. package/hooks/use-send-message.js +15 -13
  92. package/hooks/use-send-message.js.map +1 -1
  93. package/hooks/use-visitor.d.ts.map +1 -1
  94. package/hooks/use-visitor.js +28 -30
  95. package/hooks/use-visitor.js.map +1 -1
  96. package/hooks/use-window-visibility-focus.d.ts +4 -0
  97. package/hooks/use-window-visibility-focus.d.ts.map +1 -1
  98. package/hooks/use-window-visibility-focus.js +5 -2
  99. package/hooks/use-window-visibility-focus.js.map +1 -1
  100. package/identify-visitor.d.ts +12 -3
  101. package/identify-visitor.d.ts.map +1 -1
  102. package/identify-visitor.js +58 -9
  103. package/identify-visitor.js.map +1 -1
  104. package/index.d.ts +10 -7
  105. package/index.js +10 -9
  106. package/package.json +14 -17
  107. package/primitives/avatar/avatar.d.ts.map +1 -1
  108. package/primitives/avatar/fallback.d.ts.map +1 -1
  109. package/primitives/avatar/fallback.js +1 -3
  110. package/primitives/avatar/fallback.js.map +1 -1
  111. package/primitives/avatar/image.d.ts.map +1 -1
  112. package/primitives/avatar/index.d.ts +1 -0
  113. package/primitives/bubble.d.ts +2 -0
  114. package/primitives/bubble.d.ts.map +1 -1
  115. package/primitives/bubble.js +8 -2
  116. package/primitives/bubble.js.map +1 -1
  117. package/primitives/button.d.ts.map +1 -1
  118. package/primitives/conversation-timeline.d.ts.map +1 -1
  119. package/primitives/conversation-timeline.js +58 -5
  120. package/primitives/conversation-timeline.js.map +1 -1
  121. package/primitives/index.d.ts +1 -0
  122. package/primitives/index.parts.d.ts +1 -0
  123. package/primitives/multimodal-input.d.ts.map +1 -1
  124. package/primitives/timeline-item-group.d.ts +7 -7
  125. package/primitives/timeline-item-group.d.ts.map +1 -1
  126. package/primitives/timeline-item-group.js.map +1 -1
  127. package/primitives/timeline-item.d.ts +1 -1
  128. package/primitives/timeline-item.d.ts.map +1 -1
  129. package/primitives/timeline-item.js +7 -1
  130. package/primitives/timeline-item.js.map +1 -1
  131. package/primitives/window.d.ts +1 -1
  132. package/primitives/window.d.ts.map +1 -1
  133. package/primitives/window.js +4 -4
  134. package/primitives/window.js.map +1 -1
  135. package/provider.d.ts +23 -43
  136. package/provider.d.ts.map +1 -1
  137. package/provider.js +152 -49
  138. package/provider.js.map +1 -1
  139. package/realtime/event-filter.d.ts +4 -0
  140. package/realtime/event-filter.d.ts.map +1 -1
  141. package/realtime/event-filter.js +4 -0
  142. package/realtime/event-filter.js.map +1 -1
  143. package/realtime/index.js +1 -1
  144. package/realtime/provider.d.ts +7 -2
  145. package/realtime/provider.d.ts.map +1 -1
  146. package/realtime/provider.js +23 -1
  147. package/realtime/provider.js.map +1 -1
  148. package/realtime/seen-store.d.ts +13 -0
  149. package/realtime/seen-store.d.ts.map +1 -1
  150. package/realtime/seen-store.js +14 -2
  151. package/realtime/seen-store.js.map +1 -1
  152. package/realtime/support-provider.d.ts +1 -2
  153. package/realtime/support-provider.d.ts.map +1 -1
  154. package/realtime/support-provider.js +19 -20
  155. package/realtime/support-provider.js.map +1 -1
  156. package/realtime/typing-store.d.ts +18 -0
  157. package/realtime/typing-store.d.ts.map +1 -1
  158. package/realtime/typing-store.js +19 -2
  159. package/realtime/typing-store.js.map +1 -1
  160. package/realtime/use-realtime.d.ts +8 -4
  161. package/realtime/use-realtime.d.ts.map +1 -1
  162. package/realtime/use-realtime.js +4 -0
  163. package/realtime/use-realtime.js.map +1 -1
  164. package/realtime-events.d.ts +17 -3
  165. package/realtime-events.d.ts.map +1 -1
  166. package/schemas.d.ts +7 -1
  167. package/schemas.d.ts.map +1 -1
  168. package/support/components/avatar-stack.d.ts +8 -4
  169. package/support/components/avatar-stack.d.ts.map +1 -1
  170. package/support/components/avatar-stack.js +4 -0
  171. package/support/components/avatar-stack.js.map +1 -1
  172. package/support/components/avatar.d.ts +11 -6
  173. package/support/components/avatar.d.ts.map +1 -1
  174. package/support/components/avatar.js +4 -0
  175. package/support/components/avatar.js.map +1 -1
  176. package/support/components/bubble.d.ts.map +1 -1
  177. package/support/components/bubble.js +29 -6
  178. package/support/components/bubble.js.map +1 -1
  179. package/support/components/button.d.ts +8 -5
  180. package/support/components/button.d.ts.map +1 -1
  181. package/support/components/button.js +5 -1
  182. package/support/components/button.js.map +1 -1
  183. package/support/components/container.d.ts +0 -1
  184. package/support/components/container.d.ts.map +1 -1
  185. package/support/components/container.js +2 -8
  186. package/support/components/container.js.map +1 -1
  187. package/support/components/conversation-button-link.d.ts +8 -21
  188. package/support/components/conversation-button-link.d.ts.map +1 -1
  189. package/support/components/conversation-button-link.js +62 -178
  190. package/support/components/conversation-button-link.js.map +1 -1
  191. package/support/components/conversation-event.d.ts.map +1 -1
  192. package/support/components/conversation-event.js +4 -0
  193. package/support/components/conversation-event.js.map +1 -1
  194. package/support/components/conversation-timeline.d.ts +10 -1
  195. package/support/components/conversation-timeline.d.ts.map +1 -1
  196. package/support/components/conversation-timeline.js +63 -57
  197. package/support/components/conversation-timeline.js.map +1 -1
  198. package/support/components/cossistant-branding.d.ts +5 -2
  199. package/support/components/cossistant-branding.d.ts.map +1 -1
  200. package/support/components/cossistant-branding.js +3 -0
  201. package/support/components/cossistant-branding.js.map +1 -1
  202. package/support/components/header.d.ts.map +1 -1
  203. package/support/components/header.js +2 -2
  204. package/support/components/header.js.map +1 -1
  205. package/support/components/icons.d.ts.map +1 -1
  206. package/support/components/multimodal-input.d.ts.map +1 -1
  207. package/support/components/multimodal-input.js +5 -24
  208. package/support/components/multimodal-input.js.map +1 -1
  209. package/support/components/navigation-tab.d.ts +7 -2
  210. package/support/components/navigation-tab.d.ts.map +1 -1
  211. package/support/components/navigation-tab.js +4 -0
  212. package/support/components/navigation-tab.js.map +1 -1
  213. package/support/components/support-content.d.ts +1 -1
  214. package/support/components/support-content.d.ts.map +1 -1
  215. package/support/components/support-content.js +7 -10
  216. package/support/components/support-content.js.map +1 -1
  217. package/support/components/text-effect.d.ts +5 -2
  218. package/support/components/text-effect.d.ts.map +1 -1
  219. package/support/components/text-effect.js +4 -0
  220. package/support/components/text-effect.js.map +1 -1
  221. package/support/components/timeline-identification-tool.d.ts +7 -0
  222. package/support/components/timeline-identification-tool.d.ts.map +1 -0
  223. package/support/components/timeline-identification-tool.js +139 -0
  224. package/support/components/timeline-identification-tool.js.map +1 -0
  225. package/support/components/timeline-message-group.d.ts +2 -1
  226. package/support/components/timeline-message-group.d.ts.map +1 -1
  227. package/support/components/timeline-message-group.js +4 -19
  228. package/support/components/timeline-message-group.js.map +1 -1
  229. package/support/components/timeline-message-item.d.ts +6 -2
  230. package/support/components/timeline-message-item.d.ts.map +1 -1
  231. package/support/components/timeline-message-item.js +8 -4
  232. package/support/components/timeline-message-item.js.map +1 -1
  233. package/support/components/typing-indicator.d.ts +5 -2
  234. package/support/components/typing-indicator.d.ts.map +1 -1
  235. package/support/components/typing-indicator.js +4 -4
  236. package/support/components/typing-indicator.js.map +1 -1
  237. package/support/components/watermark.d.ts.map +1 -1
  238. package/support/context/websocket.d.ts +8 -0
  239. package/support/context/websocket.d.ts.map +1 -1
  240. package/support/context/websocket.js +12 -6
  241. package/support/context/websocket.js.map +1 -1
  242. package/support/index.d.ts +8 -8
  243. package/support/index.d.ts.map +1 -1
  244. package/support/index.js +18 -18
  245. package/support/index.js.map +1 -1
  246. package/support/pages/conversation-history.js +46 -54
  247. package/support/pages/conversation-history.js.map +1 -1
  248. package/support/pages/conversation.d.ts +3 -6
  249. package/support/pages/conversation.d.ts.map +1 -1
  250. package/support/pages/conversation.js +19 -9
  251. package/support/pages/conversation.js.map +1 -1
  252. package/support/pages/home.d.ts +2 -2
  253. package/support/pages/home.d.ts.map +1 -1
  254. package/support/pages/home.js +64 -77
  255. package/support/pages/home.js.map +1 -1
  256. package/support/store/support-store.d.ts +18 -2
  257. package/support/store/support-store.d.ts.map +1 -1
  258. package/support/store/support-store.js +20 -5
  259. package/support/store/support-store.js.map +1 -1
  260. package/support/{support-CMoDLQoC.css → support-Ck4jy29i.css} +1 -2
  261. package/support/support-Ck4jy29i.css.map +1 -0
  262. package/support/text/index.d.ts +15 -2
  263. package/support/text/index.d.ts.map +1 -1
  264. package/support/text/index.js +15 -2
  265. package/support/text/index.js.map +1 -1
  266. package/support/text/locales/en.js +22 -4
  267. package/support/text/locales/en.js.map +1 -1
  268. package/support/text/locales/es.js +18 -0
  269. package/support/text/locales/es.js.map +1 -1
  270. package/support/text/locales/fr.js +18 -0
  271. package/support/text/locales/fr.js.map +1 -1
  272. package/support/text/locales/keys.d.ts +69 -9
  273. package/support/text/locales/keys.d.ts.map +1 -1
  274. package/support/text/locales/keys.js +18 -0
  275. package/support/text/locales/keys.js.map +1 -1
  276. package/support/text/runtime.d.ts +21 -0
  277. package/support/text/runtime.d.ts.map +1 -1
  278. package/support/text/runtime.js +21 -0
  279. package/support/text/runtime.js.map +1 -1
  280. package/support/utils/index.d.ts +4 -0
  281. package/support/utils/index.d.ts.map +1 -1
  282. package/support/utils/index.js +4 -1
  283. package/support/utils/index.js.map +1 -1
  284. package/support/utils/time.d.ts +3 -0
  285. package/support/utils/time.d.ts.map +1 -1
  286. package/support/utils/time.js +3 -0
  287. package/support/utils/time.js.map +1 -1
  288. package/support-config.d.ts +2 -1
  289. package/support-config.d.ts.map +1 -1
  290. package/support-config.js.map +1 -1
  291. package/support.css +2 -2
  292. package/timeline-item.d.ts +10 -0
  293. package/timeline-item.d.ts.map +1 -1
  294. package/utils/conversation.d.ts +7 -0
  295. package/utils/conversation.d.ts.map +1 -0
  296. package/utils/conversation.js +18 -0
  297. package/utils/conversation.js.map +1 -0
  298. package/utils/id.d.ts +3 -0
  299. package/utils/id.d.ts.map +1 -1
  300. package/utils/id.js +3 -0
  301. package/utils/id.js.map +1 -1
  302. package/utils/index.d.ts +2 -1
  303. package/utils/index.js +2 -1
  304. package/utils/metadata-hash.d.ts +12 -0
  305. package/utils/metadata-hash.d.ts.map +1 -0
  306. package/utils/metadata-hash.js +26 -0
  307. package/utils/metadata-hash.js.map +1 -0
  308. package/utils/text.d.ts +3 -0
  309. package/utils/text.d.ts.map +1 -1
  310. package/utils/text.js +3 -0
  311. package/utils/text.js.map +1 -1
  312. package/utils/use-render-element.d.ts +3 -0
  313. package/utils/use-render-element.d.ts.map +1 -1
  314. package/utils/use-render-element.js +3 -0
  315. package/utils/use-render-element.js.map +1 -1
  316. package/support/context/config.d.ts +0 -32
  317. package/support/context/config.d.ts.map +0 -1
  318. package/support/context/config.js +0 -27
  319. package/support/context/config.js.map +0 -1
  320. package/support/support-CMoDLQoC.css.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"timeline-message-group.d.ts","names":[],"sources":["../../../src/support/components/timeline-message-group.tsx"],"sourcesContent":[],"mappings":";;;;;KAqCY,yBAAA;SACH;EADG,iBAAA,EAES,gBAFgB,EAAA;EAAA,oBAAA,EAGb,mBAHa,EAAA;kBAC5B,CAAA,EAAA,MAAA;WACY,CAAA,EAAA,MAAA,EAAA;;AACsB,cAK9B,oBAL8B,EAKR,KAAA,CAAM,EALE,CAKC,yBALD,CAAA"}
1
+ {"version":3,"file":"timeline-message-group.d.ts","names":[],"sources":["../../../src/support/components/timeline-message-group.tsx"],"sourcesContent":[],"mappings":";;;;;KAoCY,yBAAA;SACJ;EADI,iBAAA,EAEQ,gBAFiB,EAAA;EAC7B,oBAAA,EAEe,mBAFf,EAAA;EACY,gBAAA,CAAA,EAAA,MAAA;EACG,SAAA,CAAA,EAAA,SAAA,MAAA,EAAA;EAAmB,WAAA,CAAA,EAAA,SAAA,MAAA,EAAA;AAS1C,CAAA;cAAa,sBAAsB,KAAA,CAAM,GAAG"}
@@ -3,7 +3,6 @@ import { Avatar } from "./avatar.js";
3
3
  import { CossistantLogo } from "./cossistant-branding.js";
4
4
  import { TimelineItemGroup, TimelineItemGroupAvatar, TimelineItemGroupContent, TimelineItemGroupHeader, TimelineItemGroupSeenIndicator } from "../../primitives/timeline-item-group.js";
5
5
  import { TimelineMessageItem } from "./timeline-message-item.js";
6
- import { useMemo } from "react";
7
6
  import { SenderType } from "@cossistant/types";
8
7
  import { jsx, jsxs } from "react/jsx-runtime";
9
8
  import { motion } from "motion/react";
@@ -37,27 +36,12 @@ const SEEN_ANIMATION = {
37
36
  ease: "easeOut"
38
37
  }
39
38
  };
40
- const TimelineMessageGroup = ({ items, availableAIAgents, availableHumanAgents, currentVisitorId, seenByIds = [] }) => {
39
+ const EMPTY_SEEN_BY_IDS = Object.freeze([]);
40
+ const EMPTY_SEEN_BY_NAMES = Object.freeze([]);
41
+ const TimelineMessageGroup = ({ items, availableAIAgents, availableHumanAgents, currentVisitorId, seenByIds = EMPTY_SEEN_BY_IDS, seenByNames = EMPTY_SEEN_BY_NAMES }) => {
41
42
  const firstItem = items[0];
42
43
  const humanAgent = availableHumanAgents.find((agent) => agent.id === firstItem?.userId);
43
44
  const aiAgent = availableAIAgents.find((agent) => agent.id === firstItem?.aiAgentId);
44
- const seenByNames = useMemo(() => {
45
- const deduped = /* @__PURE__ */ new Set();
46
- for (const id of seenByIds) {
47
- const human = availableHumanAgents.find((agent) => agent.id === id);
48
- if (human?.name) {
49
- deduped.add(human.name);
50
- continue;
51
- }
52
- const ai = availableAIAgents.find((agent) => agent.id === id);
53
- if (ai?.name) deduped.add(ai.name);
54
- }
55
- return Array.from(deduped);
56
- }, [
57
- seenByIds,
58
- availableHumanAgents,
59
- availableAIAgents
60
- ]);
61
45
  if (items.length === 0) return null;
62
46
  const hasSeenIndicator = seenByIds.length > 0 && seenByNames.length > 0;
63
47
  return /* @__PURE__ */ jsx(TimelineItemGroup, {
@@ -111,6 +95,7 @@ const TimelineMessageGroup = ({ items, availableAIAgents, availableHumanAgents,
111
95
  })
112
96
  });
113
97
  };
98
+ TimelineMessageGroup.displayName = "TimelineMessageGroup";
114
99
 
115
100
  //#endregion
116
101
  export { TimelineMessageGroup };
@@ -1 +1 @@
1
- {"version":3,"file":"timeline-message-group.js","names":["TimelineMessageGroup: React.FC<TimelineMessageGroupProps>","PrimitiveTimelineItemGroup"],"sources":["../../../src/support/components/timeline-message-group.tsx"],"sourcesContent":["import type { AvailableAIAgent, AvailableHumanAgent } from \"@cossistant/types\";\nimport { SenderType } from \"@cossistant/types\";\nimport type { TimelineItem } from \"@cossistant/types/api/timeline-item\";\nimport { motion } from \"motion/react\";\nimport type React from \"react\";\nimport { useMemo } from \"react\";\nimport {\n TimelineItemGroup as PrimitiveTimelineItemGroup,\n TimelineItemGroupAvatar,\n TimelineItemGroupContent,\n TimelineItemGroupHeader,\n TimelineItemGroupSeenIndicator,\n} from \"../../primitives/timeline-item-group\";\nimport { cn } from \"../utils\";\nimport { Avatar } from \"./avatar\";\nimport { CossistantLogo } from \"./cossistant-branding\";\nimport { TimelineMessageItem } from \"./timeline-message-item\";\n\nconst MESSAGE_ANIMATION = {\n initial: { opacity: 0, y: 6 },\n animate: { opacity: 1, y: 0 },\n exit: { opacity: 0 },\n transition: {\n duration: 0.1,\n ease: [0.25, 0.46, 0.45, 0.94] as const, // easeOutCubic\n },\n} as const;\n\nconst SEEN_ANIMATION = {\n initial: { opacity: 0 },\n animate: { opacity: 1 },\n transition: {\n duration: 0.1,\n ease: \"easeOut\" as const,\n },\n} as const;\n\nexport type TimelineMessageGroupProps = {\n items: TimelineItem[];\n availableAIAgents: AvailableAIAgent[];\n availableHumanAgents: AvailableHumanAgent[];\n currentVisitorId?: string;\n seenByIds?: string[];\n};\n\nexport const TimelineMessageGroup: React.FC<TimelineMessageGroupProps> = ({\n items,\n availableAIAgents,\n availableHumanAgents,\n currentVisitorId,\n seenByIds = [],\n}) => {\n // Get agent info for the sender\n const firstItem = items[0];\n const humanAgent = availableHumanAgents.find(\n (agent) => agent.id === firstItem?.userId\n );\n const aiAgent = availableAIAgents.find(\n (agent) => agent.id === firstItem?.aiAgentId\n );\n\n const seenByNames = useMemo(() => {\n const deduped = new Set<string>();\n for (const id of seenByIds) {\n const human = availableHumanAgents.find((agent) => agent.id === id);\n if (human?.name) {\n deduped.add(human.name);\n continue;\n }\n const ai = availableAIAgents.find((agent) => agent.id === id);\n if (ai?.name) {\n deduped.add(ai.name);\n }\n }\n return Array.from(deduped);\n }, [seenByIds, availableHumanAgents, availableAIAgents]);\n\n if (items.length === 0) {\n return null;\n }\n\n const hasSeenIndicator = seenByIds.length > 0 && seenByNames.length > 0;\n\n return (\n <PrimitiveTimelineItemGroup\n items={items}\n seenByIds={seenByIds}\n viewerId={currentVisitorId}\n viewerType={SenderType.VISITOR}\n >\n {({\n isSentByViewer,\n isReceivedByViewer,\n isVisitor,\n isAI,\n isTeamMember,\n }) => (\n <div\n className={cn(\n \"flex w-full gap-2\",\n // Support widget POV: visitor messages are sent (right side)\n // Agent messages are received (left side)\n isSentByViewer && \"flex-row-reverse\",\n isReceivedByViewer && \"flex-row\"\n )}\n >\n {/* Avatar - only show for received messages (agents) */}\n {isReceivedByViewer && (\n <TimelineItemGroupAvatar className=\"flex flex-shrink-0 flex-col justify-end\">\n {isAI ? (\n <div className=\"flex size-6 items-center justify-center rounded-full bg-primary/10\">\n <CossistantLogo className=\"h-4 w-4 text-primary\" />\n </div>\n ) : (\n <Avatar\n className=\"size-6\"\n image={humanAgent?.image}\n name={humanAgent?.name || \"Support\"}\n />\n )}\n </TimelineItemGroupAvatar>\n )}\n\n <TimelineItemGroupContent\n className={cn(\"flex flex-col gap-1\", isSentByViewer && \"items-end\")}\n >\n {/* Header - show sender name for received messages (agents) */}\n {isReceivedByViewer && (\n <TimelineItemGroupHeader className=\"px-1 text-muted-foreground text-xs\">\n {isAI\n ? aiAgent?.name || \"AI Assistant\"\n : humanAgent?.name || \"Support\"}\n </TimelineItemGroupHeader>\n )}\n\n {items.map((item, index) => (\n <motion.div key={item.id} {...MESSAGE_ANIMATION}>\n <TimelineMessageItem\n isLast={index === items.length - 1}\n isSentByViewer={isSentByViewer}\n item={item}\n />\n </motion.div>\n ))}\n\n {isSentByViewer && (\n <div className={cn(\"\", hasSeenIndicator && \"mt-2\")}>\n <div className=\"min-h-[1.25rem]\">\n {hasSeenIndicator && (\n <motion.div key=\"seen-indicator\" {...SEEN_ANIMATION}>\n <TimelineItemGroupSeenIndicator\n className=\"px-1 text-muted-foreground text-xs\"\n seenByIds={seenByIds}\n >\n {() => `Seen by ${seenByNames.join(\", \")}`}\n </TimelineItemGroupSeenIndicator>\n </motion.div>\n )}\n </div>\n </div>\n )}\n </TimelineItemGroupContent>\n </div>\n )}\n </PrimitiveTimelineItemGroup>\n );\n};\n"],"mappings":";;;;;;;;;;;AAkBA,MAAM,oBAAoB;CACxB,SAAS;EAAE,SAAS;EAAG,GAAG;EAAG;CAC7B,SAAS;EAAE,SAAS;EAAG,GAAG;EAAG;CAC7B,MAAM,EAAE,SAAS,GAAG;CACpB,YAAY;EACV,UAAU;EACV,MAAM;GAAC;GAAM;GAAM;GAAM;GAAK;EAC/B;CACF;AAED,MAAM,iBAAiB;CACrB,SAAS,EAAE,SAAS,GAAG;CACvB,SAAS,EAAE,SAAS,GAAG;CACvB,YAAY;EACV,UAAU;EACV,MAAM;EACP;CACF;AAUD,MAAaA,wBAA6D,EACxE,OACA,mBACA,sBACA,kBACA,YAAY,EAAE,OACV;CAEJ,MAAM,YAAY,MAAM;CACxB,MAAM,aAAa,qBAAqB,MACrC,UAAU,MAAM,OAAO,WAAW,OACpC;CACD,MAAM,UAAU,kBAAkB,MAC/B,UAAU,MAAM,OAAO,WAAW,UACpC;CAED,MAAM,cAAc,cAAc;EAChC,MAAM,0BAAU,IAAI,KAAa;AACjC,OAAK,MAAM,MAAM,WAAW;GAC1B,MAAM,QAAQ,qBAAqB,MAAM,UAAU,MAAM,OAAO,GAAG;AACnE,OAAI,OAAO,MAAM;AACf,YAAQ,IAAI,MAAM,KAAK;AACvB;;GAEF,MAAM,KAAK,kBAAkB,MAAM,UAAU,MAAM,OAAO,GAAG;AAC7D,OAAI,IAAI,KACN,SAAQ,IAAI,GAAG,KAAK;;AAGxB,SAAO,MAAM,KAAK,QAAQ;IACzB;EAAC;EAAW;EAAsB;EAAkB,CAAC;AAExD,KAAI,MAAM,WAAW,EACnB,QAAO;CAGT,MAAM,mBAAmB,UAAU,SAAS,KAAK,YAAY,SAAS;AAEtE,QACE,oBAACC;EACQ;EACI;EACX,UAAU;EACV,YAAY,WAAW;aAErB,EACA,gBACA,oBACA,WACA,MACA,mBAEA,qBAAC;GACC,WAAW,GACT,qBAGA,kBAAkB,oBAClB,sBAAsB,WACvB;cAGA,sBACC,oBAAC;IAAwB,WAAU;cAChC,OACC,oBAAC;KAAI,WAAU;eACb,oBAAC,kBAAe,WAAU,yBAAyB;MAC/C,GAEN,oBAAC;KACC,WAAU;KACV,OAAO,YAAY;KACnB,MAAM,YAAY,QAAQ;MAC1B;KAEoB,EAG5B,qBAAC;IACC,WAAW,GAAG,uBAAuB,kBAAkB,YAAY;;KAGlE,sBACC,oBAAC;MAAwB,WAAU;gBAChC,OACG,SAAS,QAAQ,iBACjB,YAAY,QAAQ;OACA;KAG3B,MAAM,KAAK,MAAM,UAChB,oBAAC,OAAO;MAAkB,GAAI;gBAC5B,oBAAC;OACC,QAAQ,UAAU,MAAM,SAAS;OACjB;OACV;QACN;QALa,KAAK,GAMT,CACb;KAED,kBACC,oBAAC;MAAI,WAAW,GAAG,IAAI,oBAAoB,OAAO;gBAChD,oBAAC;OAAI,WAAU;iBACZ,oBACC,oBAAC,OAAO;QAAyB,GAAI;kBACnC,oBAAC;SACC,WAAU;SACC;yBAEJ,WAAW,YAAY,KAAK,KAAK;UACT;UANnB,iBAOH;QAEX;OACF;;KAEiB;IACvB;GAEmB"}
1
+ {"version":3,"file":"timeline-message-group.js","names":["EMPTY_SEEN_BY_IDS: readonly string[]","EMPTY_SEEN_BY_NAMES: readonly string[]","TimelineMessageGroup: React.FC<TimelineMessageGroupProps>","PrimitiveTimelineItemGroup"],"sources":["../../../src/support/components/timeline-message-group.tsx"],"sourcesContent":["import type { AvailableAIAgent, AvailableHumanAgent } from \"@cossistant/types\";\nimport { SenderType } from \"@cossistant/types\";\nimport type { TimelineItem } from \"@cossistant/types/api/timeline-item\";\nimport { motion } from \"motion/react\";\nimport type React from \"react\";\nimport {\n\tTimelineItemGroup as PrimitiveTimelineItemGroup,\n\tTimelineItemGroupAvatar,\n\tTimelineItemGroupContent,\n\tTimelineItemGroupHeader,\n\tTimelineItemGroupSeenIndicator,\n} from \"../../primitives/timeline-item-group\";\nimport { cn } from \"../utils\";\nimport { Avatar } from \"./avatar\";\nimport { CossistantLogo } from \"./cossistant-branding\";\nimport { TimelineMessageItem } from \"./timeline-message-item\";\n\nconst MESSAGE_ANIMATION = {\n\tinitial: { opacity: 0, y: 6 },\n\tanimate: { opacity: 1, y: 0 },\n\texit: { opacity: 0 },\n\ttransition: {\n\t\tduration: 0.1,\n\t\tease: [0.25, 0.46, 0.45, 0.94] as const, // easeOutCubic\n\t},\n} as const;\n\nconst SEEN_ANIMATION = {\n\tinitial: { opacity: 0 },\n\tanimate: { opacity: 1 },\n\ttransition: {\n\t\tduration: 0.1,\n\t\tease: \"easeOut\" as const,\n\t},\n} as const;\n\nexport type TimelineMessageGroupProps = {\n\titems: TimelineItem[];\n\tavailableAIAgents: AvailableAIAgent[];\n\tavailableHumanAgents: AvailableHumanAgent[];\n\tcurrentVisitorId?: string;\n\tseenByIds?: readonly string[];\n\tseenByNames?: readonly string[];\n};\n\nconst EMPTY_SEEN_BY_IDS: readonly string[] = Object.freeze([]);\nconst EMPTY_SEEN_BY_NAMES: readonly string[] = Object.freeze([]);\n\nexport const TimelineMessageGroup: React.FC<TimelineMessageGroupProps> = ({\n\titems,\n\tavailableAIAgents,\n\tavailableHumanAgents,\n\tcurrentVisitorId,\n\tseenByIds = EMPTY_SEEN_BY_IDS,\n\tseenByNames = EMPTY_SEEN_BY_NAMES,\n}) => {\n\t// Get agent info for the sender\n\tconst firstItem = items[0];\n\tconst humanAgent = availableHumanAgents.find(\n\t\t(agent) => agent.id === firstItem?.userId\n\t);\n\tconst aiAgent = availableAIAgents.find(\n\t\t(agent) => agent.id === firstItem?.aiAgentId\n\t);\n\n\tif (items.length === 0) {\n\t\treturn null;\n\t}\n\n\tconst hasSeenIndicator = seenByIds.length > 0 && seenByNames.length > 0;\n\n\treturn (\n\t\t<PrimitiveTimelineItemGroup\n\t\t\titems={items}\n\t\t\tseenByIds={seenByIds}\n\t\t\tviewerId={currentVisitorId}\n\t\t\tviewerType={SenderType.VISITOR}\n\t\t>\n\t\t\t{({\n\t\t\t\tisSentByViewer,\n\t\t\t\tisReceivedByViewer,\n\t\t\t\tisVisitor,\n\t\t\t\tisAI,\n\t\t\t\tisTeamMember,\n\t\t\t}) => (\n\t\t\t\t<div\n\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\"flex w-full gap-2\",\n\t\t\t\t\t\t// Support widget POV: visitor messages are sent (right side)\n\t\t\t\t\t\t// Agent messages are received (left side)\n\t\t\t\t\t\tisSentByViewer && \"flex-row-reverse\",\n\t\t\t\t\t\tisReceivedByViewer && \"flex-row\"\n\t\t\t\t\t)}\n\t\t\t\t>\n\t\t\t\t\t{/* Avatar - only show for received messages (agents) */}\n\t\t\t\t\t{isReceivedByViewer && (\n\t\t\t\t\t\t<TimelineItemGroupAvatar className=\"flex flex-shrink-0 flex-col justify-end\">\n\t\t\t\t\t\t\t{isAI ? (\n\t\t\t\t\t\t\t\t<div className=\"flex size-6 items-center justify-center rounded-full bg-primary/10\">\n\t\t\t\t\t\t\t\t\t<CossistantLogo className=\"h-4 w-4 text-primary\" />\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t<Avatar\n\t\t\t\t\t\t\t\t\tclassName=\"size-6\"\n\t\t\t\t\t\t\t\t\timage={humanAgent?.image}\n\t\t\t\t\t\t\t\t\tname={humanAgent?.name || \"Support\"}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</TimelineItemGroupAvatar>\n\t\t\t\t\t)}\n\n\t\t\t\t\t<TimelineItemGroupContent\n\t\t\t\t\t\tclassName={cn(\"flex flex-col gap-1\", isSentByViewer && \"items-end\")}\n\t\t\t\t\t>\n\t\t\t\t\t\t{/* Header - show sender name for received messages (agents) */}\n\t\t\t\t\t\t{isReceivedByViewer && (\n\t\t\t\t\t\t\t<TimelineItemGroupHeader className=\"px-1 text-muted-foreground text-xs\">\n\t\t\t\t\t\t\t\t{isAI\n\t\t\t\t\t\t\t\t\t? aiAgent?.name || \"AI Assistant\"\n\t\t\t\t\t\t\t\t\t: humanAgent?.name || \"Support\"}\n\t\t\t\t\t\t\t</TimelineItemGroupHeader>\n\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t{items.map((item, index) => (\n\t\t\t\t\t\t\t<motion.div key={item.id} {...MESSAGE_ANIMATION}>\n\t\t\t\t\t\t\t\t<TimelineMessageItem\n\t\t\t\t\t\t\t\t\tisLast={index === items.length - 1}\n\t\t\t\t\t\t\t\t\tisSentByViewer={isSentByViewer}\n\t\t\t\t\t\t\t\t\titem={item}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t</motion.div>\n\t\t\t\t\t\t))}\n\n\t\t\t\t\t\t{isSentByViewer && (\n\t\t\t\t\t\t\t<div className={cn(\"\", hasSeenIndicator && \"mt-2\")}>\n\t\t\t\t\t\t\t\t<div className=\"min-h-[1.25rem]\">\n\t\t\t\t\t\t\t\t\t{hasSeenIndicator && (\n\t\t\t\t\t\t\t\t\t\t<motion.div key=\"seen-indicator\" {...SEEN_ANIMATION}>\n\t\t\t\t\t\t\t\t\t\t\t<TimelineItemGroupSeenIndicator\n\t\t\t\t\t\t\t\t\t\t\t\tclassName=\"px-1 text-muted-foreground text-xs\"\n\t\t\t\t\t\t\t\t\t\t\t\tseenByIds={seenByIds}\n\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t{() => `Seen by ${seenByNames.join(\", \")}`}\n\t\t\t\t\t\t\t\t\t\t\t</TimelineItemGroupSeenIndicator>\n\t\t\t\t\t\t\t\t\t\t</motion.div>\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</TimelineItemGroupContent>\n\t\t\t\t</div>\n\t\t\t)}\n\t\t</PrimitiveTimelineItemGroup>\n\t);\n};\n\nTimelineMessageGroup.displayName = \"TimelineMessageGroup\";\n"],"mappings":";;;;;;;;;;AAiBA,MAAM,oBAAoB;CACzB,SAAS;EAAE,SAAS;EAAG,GAAG;EAAG;CAC7B,SAAS;EAAE,SAAS;EAAG,GAAG;EAAG;CAC7B,MAAM,EAAE,SAAS,GAAG;CACpB,YAAY;EACX,UAAU;EACV,MAAM;GAAC;GAAM;GAAM;GAAM;GAAK;EAC9B;CACD;AAED,MAAM,iBAAiB;CACtB,SAAS,EAAE,SAAS,GAAG;CACvB,SAAS,EAAE,SAAS,GAAG;CACvB,YAAY;EACX,UAAU;EACV,MAAM;EACN;CACD;AAWD,MAAMA,oBAAuC,OAAO,OAAO,EAAE,CAAC;AAC9D,MAAMC,sBAAyC,OAAO,OAAO,EAAE,CAAC;AAEhE,MAAaC,wBAA6D,EACzE,OACA,mBACA,sBACA,kBACA,YAAY,mBACZ,cAAc,0BACT;CAEL,MAAM,YAAY,MAAM;CACxB,MAAM,aAAa,qBAAqB,MACtC,UAAU,MAAM,OAAO,WAAW,OACnC;CACD,MAAM,UAAU,kBAAkB,MAChC,UAAU,MAAM,OAAO,WAAW,UACnC;AAED,KAAI,MAAM,WAAW,EACpB,QAAO;CAGR,MAAM,mBAAmB,UAAU,SAAS,KAAK,YAAY,SAAS;AAEtE,QACC,oBAACC;EACO;EACI;EACX,UAAU;EACV,YAAY,WAAW;aAErB,EACD,gBACA,oBACA,WACA,MACA,mBAEA,qBAAC;GACA,WAAW,GACV,qBAGA,kBAAkB,oBAClB,sBAAsB,WACtB;cAGA,sBACA,oBAAC;IAAwB,WAAU;cACjC,OACA,oBAAC;KAAI,WAAU;eACd,oBAAC,kBAAe,WAAU,yBAAyB;MAC9C,GAEN,oBAAC;KACA,WAAU;KACV,OAAO,YAAY;KACnB,MAAM,YAAY,QAAQ;MACzB;KAEsB,EAG3B,qBAAC;IACA,WAAW,GAAG,uBAAuB,kBAAkB,YAAY;;KAGlE,sBACA,oBAAC;MAAwB,WAAU;gBACjC,OACE,SAAS,QAAQ,iBACjB,YAAY,QAAQ;OACE;KAG1B,MAAM,KAAK,MAAM,UACjB,oBAAC,OAAO;MAAkB,GAAI;gBAC7B,oBAAC;OACA,QAAQ,UAAU,MAAM,SAAS;OACjB;OACV;QACL;QALc,KAAK,GAMT,CACZ;KAED,kBACA,oBAAC;MAAI,WAAW,GAAG,IAAI,oBAAoB,OAAO;gBACjD,oBAAC;OAAI,WAAU;iBACb,oBACA,oBAAC,OAAO;QAAyB,GAAI;kBACpC,oBAAC;SACA,WAAU;SACC;yBAEJ,WAAW,YAAY,KAAK,KAAK;UACR;UANlB,iBAOH;QAET;OACD;;KAEmB;IACtB;GAEqB;;AAI/B,qBAAqB,cAAc"}
@@ -1,5 +1,5 @@
1
1
  import { TimelineItem } from "../../timeline-item.js";
2
- import * as react_jsx_runtime11 from "react/jsx-runtime";
2
+ import React from "react";
3
3
 
4
4
  //#region src/support/components/timeline-message-item.d.ts
5
5
  type TimelineMessageItemProps = {
@@ -7,11 +7,15 @@ type TimelineMessageItemProps = {
7
7
  isLast?: boolean;
8
8
  isSentByViewer?: boolean;
9
9
  };
10
+ /**
11
+ * Message bubble renderer that adapts layout depending on whether the visitor
12
+ * or an agent sent the message.
13
+ */
10
14
  declare function TimelineMessageItem({
11
15
  item,
12
16
  isLast,
13
17
  isSentByViewer
14
- }: TimelineMessageItemProps): react_jsx_runtime11.JSX.Element;
18
+ }: TimelineMessageItemProps): React.ReactElement;
15
19
  //#endregion
16
20
  export { TimelineMessageItem, TimelineMessageItemProps };
17
21
  //# sourceMappingURL=timeline-message-item.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"timeline-message-item.d.ts","names":[],"sources":["../../../src/support/components/timeline-message-item.tsx"],"sourcesContent":[],"mappings":";;;;KAUY,wBAAA;QACL;;EADK,cAAA,CAAA,EAAA,OAAA;AAMZ,CAAA;AAAmC,iBAAnB,mBAAA,CAAmB;EAAA,IAAA;EAAA,MAAA;EAAA;AAAA,CAAA,EAIhC,wBAJgC,CAAA,EAIR,mBAAA,CAAA,GAAA,CAAA,OAJQ"}
1
+ {"version":3,"file":"timeline-message-item.d.ts","names":[],"sources":["../../../src/support/components/timeline-message-item.tsx"],"sourcesContent":[],"mappings":";;;;KAUY,wBAAA;QACL;EADK,MAAA,CAAA,EAAA,OAAA;EAUI,cAAA,CAAA,EAAA,OAAmB;CAClC;;;;;AAG+C,iBAJhC,mBAAA,CAIgC;EAAA,IAAA;EAAA,MAAA;EAAA;AAAA,CAAA,EAA7C,wBAA6C,CAAA,EAAlB,KAAA,CAAM,YAAY"}
@@ -4,19 +4,23 @@ import { useSupportText } from "../text/index.js";
4
4
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
5
5
 
6
6
  //#region src/support/components/timeline-message-item.tsx
7
- function TimelineMessageItem({ item, isLast = false, isSentByViewer }) {
7
+ /**
8
+ * Message bubble renderer that adapts layout depending on whether the visitor
9
+ * or an agent sent the message.
10
+ */
11
+ function TimelineMessageItem({ item, isLast = false, isSentByViewer = false }) {
8
12
  const text = useSupportText();
9
13
  return /* @__PURE__ */ jsx(TimelineItem, {
10
14
  item,
11
- children: ({ isVisitor, isAI, timestamp }) => {
12
- const isSentByViewerFinal = isSentByViewer ?? isVisitor;
15
+ children: ({ isAI, timestamp }) => {
16
+ const isSentByViewerFinal = isSentByViewer;
13
17
  return /* @__PURE__ */ jsx("div", {
14
18
  className: cn("flex w-full gap-2", isSentByViewerFinal && "flex-row-reverse", !isSentByViewerFinal && "flex-row"),
15
19
  children: /* @__PURE__ */ jsxs("div", {
16
20
  className: cn("flex w-full flex-1 flex-col gap-1", isSentByViewerFinal && "items-end"),
17
21
  children: [/* @__PURE__ */ jsx(TimelineItemContent, {
18
22
  className: cn("block w-max max-w-[300px] rounded-lg px-3.5 py-2.5 text-sm", {
19
- "bg-co-background-300 text-foreground dark:bg-co-background-600": !isSentByViewerFinal,
23
+ "bg-background-300 text-foreground dark:bg-background-600": !isSentByViewerFinal,
20
24
  "bg-primary text-primary-foreground": isSentByViewerFinal,
21
25
  "rounded-br-sm": isLast && isSentByViewerFinal,
22
26
  "rounded-bl-sm": isLast && !isSentByViewerFinal
@@ -1 +1 @@
1
- {"version":3,"file":"timeline-message-item.js","names":["PrimitiveTimelineItem"],"sources":["../../../src/support/components/timeline-message-item.tsx"],"sourcesContent":["import type { TimelineItem } from \"@cossistant/types/api/timeline-item\";\nimport type React from \"react\";\nimport {\n\tTimelineItem as PrimitiveTimelineItem,\n\tTimelineItemContent,\n\tTimelineItemTimestamp,\n} from \"../../primitives/timeline-item\";\nimport { useSupportText } from \"../text\";\nimport { cn } from \"../utils\";\n\nexport type TimelineMessageItemProps = {\n\titem: TimelineItem;\n\tisLast?: boolean;\n\tisSentByViewer?: boolean;\n};\n\nexport function TimelineMessageItem({\n\titem,\n\tisLast = false,\n\tisSentByViewer,\n}: TimelineMessageItemProps) {\n\tconst text = useSupportText();\n\treturn (\n\t\t<PrimitiveTimelineItem item={item}>\n\t\t\t{({ isVisitor, isAI, timestamp }) => {\n\t\t\t\t// Use passed isSentByViewer if provided, otherwise fall back to isVisitor\n\t\t\t\tconst isSentByViewerFinal = isSentByViewer ?? isVisitor;\n\n\t\t\t\treturn (\n\t\t\t\t\t<div\n\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\"flex w-full gap-2\",\n\t\t\t\t\t\t\tisSentByViewerFinal && \"flex-row-reverse\",\n\t\t\t\t\t\t\t!isSentByViewerFinal && \"flex-row\"\n\t\t\t\t\t\t)}\n\t\t\t\t\t>\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\"flex w-full flex-1 flex-col gap-1\",\n\t\t\t\t\t\t\t\tisSentByViewerFinal && \"items-end\"\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<TimelineItemContent\n\t\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\t\"block w-max max-w-[300px] rounded-lg px-3.5 py-2.5 text-sm\",\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"bg-co-background-300 text-foreground dark:bg-co-background-600\":\n\t\t\t\t\t\t\t\t\t\t\t!isSentByViewerFinal,\n\t\t\t\t\t\t\t\t\t\t\"bg-primary text-primary-foreground\": isSentByViewerFinal,\n\t\t\t\t\t\t\t\t\t\t\"rounded-br-sm\": isLast && isSentByViewerFinal,\n\t\t\t\t\t\t\t\t\t\t\"rounded-bl-sm\": isLast && !isSentByViewerFinal,\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\trenderMarkdown\n\t\t\t\t\t\t\t\ttext={item.text}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t{isLast && (\n\t\t\t\t\t\t\t\t<TimelineItemTimestamp\n\t\t\t\t\t\t\t\t\tclassName=\"px-1 text-muted-foreground text-xs\"\n\t\t\t\t\t\t\t\t\ttimestamp={timestamp}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t{() => (\n\t\t\t\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t\t\t\t{timestamp.toLocaleTimeString([], {\n\t\t\t\t\t\t\t\t\t\t\t\thour: \"2-digit\",\n\t\t\t\t\t\t\t\t\t\t\t\tminute: \"2-digit\",\n\t\t\t\t\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\t\t\t\t\t{isAI &&\n\t\t\t\t\t\t\t\t\t\t\t\t` ${text(\"component.message.timestamp.aiIndicator\")}`}\n\t\t\t\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t</TimelineItemTimestamp>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t);\n\t\t\t}}\n\t\t</PrimitiveTimelineItem>\n\t);\n}\n"],"mappings":";;;;;;AAgBA,SAAgB,oBAAoB,EACnC,MACA,SAAS,OACT,kBAC4B;CAC5B,MAAM,OAAO,gBAAgB;AAC7B,QACC,oBAACA;EAA4B;aAC1B,EAAE,WAAW,MAAM,gBAAgB;GAEpC,MAAM,sBAAsB,kBAAkB;AAE9C,UACC,oBAAC;IACA,WAAW,GACV,qBACA,uBAAuB,oBACvB,CAAC,uBAAuB,WACxB;cAED,qBAAC;KACA,WAAW,GACV,qCACA,uBAAuB,YACvB;gBAED,oBAAC;MACA,WAAW,GACV,8DACA;OACC,kEACC,CAAC;OACF,sCAAsC;OACtC,iBAAiB,UAAU;OAC3B,iBAAiB,UAAU,CAAC;OAC5B,CACD;MACD;MACA,MAAM,KAAK;OACV,EACD,UACA,oBAAC;MACA,WAAU;MACC;sBAGV,4CACE,UAAU,mBAAmB,EAAE,EAAE;OACjC,MAAM;OACN,QAAQ;OACR,CAAC,EACD,QACA,IAAI,KAAK,0CAA0C,MAClD;OAEmB;MAEpB;KACD;;GAGe"}
1
+ {"version":3,"file":"timeline-message-item.js","names":["PrimitiveTimelineItem"],"sources":["../../../src/support/components/timeline-message-item.tsx"],"sourcesContent":["import type { TimelineItem } from \"@cossistant/types/api/timeline-item\";\nimport type React from \"react\";\nimport {\n\tTimelineItem as PrimitiveTimelineItem,\n\tTimelineItemContent,\n\tTimelineItemTimestamp,\n} from \"../../primitives/timeline-item\";\nimport { useSupportText } from \"../text\";\nimport { cn } from \"../utils\";\n\nexport type TimelineMessageItemProps = {\n\titem: TimelineItem;\n\tisLast?: boolean;\n\tisSentByViewer?: boolean;\n};\n\n/**\n * Message bubble renderer that adapts layout depending on whether the visitor\n * or an agent sent the message.\n */\nexport function TimelineMessageItem({\n\titem,\n\tisLast = false,\n\tisSentByViewer = false,\n}: TimelineMessageItemProps): React.ReactElement {\n\tconst text = useSupportText();\n\treturn (\n\t\t<PrimitiveTimelineItem item={item}>\n\t\t\t{({ isAI, timestamp }) => {\n\t\t\t\t// isSentByViewer defaults to false, meaning messages are treated as received\n\t\t\t\t// (left side with background) unless explicitly marked as sent by viewer\n\t\t\t\tconst isSentByViewerFinal = isSentByViewer;\n\n\t\t\t\treturn (\n\t\t\t\t\t<div\n\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\"flex w-full gap-2\",\n\t\t\t\t\t\t\tisSentByViewerFinal && \"flex-row-reverse\",\n\t\t\t\t\t\t\t!isSentByViewerFinal && \"flex-row\"\n\t\t\t\t\t\t)}\n\t\t\t\t\t>\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\"flex w-full flex-1 flex-col gap-1\",\n\t\t\t\t\t\t\t\tisSentByViewerFinal && \"items-end\"\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<TimelineItemContent\n\t\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\t\"block w-max max-w-[300px] rounded-lg px-3.5 py-2.5 text-sm\",\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"bg-background-300 text-foreground dark:bg-background-600\":\n\t\t\t\t\t\t\t\t\t\t\t!isSentByViewerFinal,\n\t\t\t\t\t\t\t\t\t\t\"bg-primary text-primary-foreground\": isSentByViewerFinal,\n\t\t\t\t\t\t\t\t\t\t\"rounded-br-sm\": isLast && isSentByViewerFinal,\n\t\t\t\t\t\t\t\t\t\t\"rounded-bl-sm\": isLast && !isSentByViewerFinal,\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\trenderMarkdown\n\t\t\t\t\t\t\t\ttext={item.text}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t{isLast && (\n\t\t\t\t\t\t\t\t<TimelineItemTimestamp\n\t\t\t\t\t\t\t\t\tclassName=\"px-1 text-muted-foreground text-xs\"\n\t\t\t\t\t\t\t\t\ttimestamp={timestamp}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t{() => (\n\t\t\t\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t\t\t\t{timestamp.toLocaleTimeString([], {\n\t\t\t\t\t\t\t\t\t\t\t\thour: \"2-digit\",\n\t\t\t\t\t\t\t\t\t\t\t\tminute: \"2-digit\",\n\t\t\t\t\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\t\t\t\t\t{isAI &&\n\t\t\t\t\t\t\t\t\t\t\t\t` ${text(\"component.message.timestamp.aiIndicator\")}`}\n\t\t\t\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t</TimelineItemTimestamp>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t);\n\t\t\t}}\n\t\t</PrimitiveTimelineItem>\n\t);\n}\n"],"mappings":";;;;;;;;;;AAoBA,SAAgB,oBAAoB,EACnC,MACA,SAAS,OACT,iBAAiB,SAC+B;CAChD,MAAM,OAAO,gBAAgB;AAC7B,QACC,oBAACA;EAA4B;aAC1B,EAAE,MAAM,gBAAgB;GAGzB,MAAM,sBAAsB;AAE5B,UACC,oBAAC;IACA,WAAW,GACV,qBACA,uBAAuB,oBACvB,CAAC,uBAAuB,WACxB;cAED,qBAAC;KACA,WAAW,GACV,qCACA,uBAAuB,YACvB;gBAED,oBAAC;MACA,WAAW,GACV,8DACA;OACC,4DACC,CAAC;OACF,sCAAsC;OACtC,iBAAiB,UAAU;OAC3B,iBAAiB,UAAU,CAAC;OAC5B,CACD;MACD;MACA,MAAM,KAAK;OACV,EACD,UACA,oBAAC;MACA,WAAU;MACC;sBAGV,4CACE,UAAU,mBAAmB,EAAE,EAAE;OACjC,MAAM;OACN,QAAQ;OACR,CAAC,EACD,QACA,IAAI,KAAK,0CAA0C,MAClD;OAEmB;MAEpB;KACD;;GAGe"}
@@ -1,6 +1,5 @@
1
1
  import * as React$1 from "react";
2
2
  import { AvailableAIAgent, AvailableHumanAgent } from "@cossistant/types";
3
- import * as react_jsx_runtime9 from "react/jsx-runtime";
4
3
 
5
4
  //#region src/support/components/typing-indicator.d.ts
6
5
  type TypingParticipantType = "visitor" | "team_member" | "ai";
@@ -14,7 +13,11 @@ type TypingIndicatorProps = React$1.HTMLAttributes<HTMLDivElement> & {
14
13
  availableHumanAgents?: AvailableHumanAgent[];
15
14
  withAvatars?: boolean;
16
15
  };
17
- declare const BouncingDots: () => react_jsx_runtime9.JSX.Element;
16
+ declare const BouncingDots: ({
17
+ className
18
+ }: {
19
+ className?: string;
20
+ }) => React$1.ReactElement;
18
21
  declare const TypingIndicator: React$1.ForwardRefExoticComponent<React$1.HTMLAttributes<HTMLDivElement> & {
19
22
  participants: TypingParticipant[];
20
23
  availableAIAgents?: AvailableAIAgent[];
@@ -1 +1 @@
1
- {"version":3,"file":"typing-indicator.d.ts","names":[],"sources":["../../../src/support/components/typing-indicator.tsx"],"sourcesContent":[],"mappings":";;;;;KAKY,qBAAA;KAEA,iBAAA;;EAFA,IAAA,EAIL,qBAJ0B;AAEjC,CAAA;AAKY,KAAA,oBAAA,GAAuB,OAAA,CAAM,cAAT,CAAwB,cAAxB,CAAA,GAAA;EAAA,YAAA,EACjB,iBADiB,EAAA;mBAAwB,CAAA,EAEnC,gBAFmC,EAAA;sBAAf,CAAA,EAGjB,mBAHiB,EAAA;aAC1B,CAAA,EAAA,OAAA;;AAES,cAIX,YAJW,EAAA,GAAA,GAIC,kBAAA,CAAA,GAAA,CAAA,OAJD;AAAmB,cAY9B,eAZ8B,EAYf,OAAA,CAAA,yBAZe,CAYf,OAAA,CAAA,cAZe,CAYf,cAZe,CAAA,GAAA;EAI9B,YAAA,EANE,iBAMU,EAAA;EAQZ,iBAAA,CAuDZ,EApEoB,gBAoEpB,EAAA;EAAA,oBAAA,CAAA,EAnEuB,mBAmEvB,EAAA;aAvD2B,CAAA,EAAA,OAAA;yBAAA,eAAA,CAAA,CAAA"}
1
+ {"version":3,"file":"typing-indicator.d.ts","names":[],"sources":["../../../src/support/components/typing-indicator.tsx"],"sourcesContent":[],"mappings":";;;;KAKY,qBAAA;KAEA,iBAAA;EAFA,EAAA,EAAA,MAAA;EAEA,IAAA,EAEL,qBAFsB;AAK7B,CAAA;AAAwD,KAA5C,oBAAA,GAAuB,OAAA,CAAM,cAAe,CAAA,cAAA,CAAA,GAAA;EAArB,YAAM,EAC1B,iBAD0B,EAAA;EAC1B,iBAAA,CAAA,EACM,gBADN,EAAA;EACM,oBAAA,CAAA,EACG,mBADH,EAAA;EACG,WAAA,CAAA,EAAA,OAAA;CAAmB;AAI9B,cAAA,YAAgB,EAAA,CAAA;EAAA;CAIzB,EAAM;EAuBG,SAAA,CAAA,EAAA,MAuDZ;CAvD2B,EAAA,GAvBxB,OAAA,CAAM,YAuBkB;AAAA,cAAf,eAAe,EAAA,OAAA,CAAA,yBAAA,CAAA,OAAA,CAAA,cAAA,CAAA,cAAA,CAAA,GAAA;EAjCb,YAAA,EAAA,iBAAA,EAAA;EACM,iBAAA,CAAA,EAAA,gBAAA,EAAA;EACG,oBAAA,CAAA,EAAA,mBAAA,EAAA"}
@@ -4,12 +4,12 @@ import * as React$1 from "react";
4
4
  import { jsx, jsxs } from "react/jsx-runtime";
5
5
 
6
6
  //#region src/support/components/typing-indicator.tsx
7
- const BouncingDots = () => /* @__PURE__ */ jsxs("div", {
7
+ const BouncingDots = ({ className }) => /* @__PURE__ */ jsxs("div", {
8
8
  className: "flex gap-1",
9
9
  children: [
10
- /* @__PURE__ */ jsx("span", { className: "dot-bounce-1 size-1 rounded-full bg-co-primary" }),
11
- /* @__PURE__ */ jsx("span", { className: "dot-bounce-2 size-1 rounded-full bg-co-primary" }),
12
- /* @__PURE__ */ jsx("span", { className: "dot-bounce-3 size-1 rounded-full bg-co-primary" })
10
+ /* @__PURE__ */ jsx("span", { className: cn("dot-bounce-1 size-1 rounded-full bg-co-primary", className) }),
11
+ /* @__PURE__ */ jsx("span", { className: cn("dot-bounce-2 size-1 rounded-full bg-co-primary", className) }),
12
+ /* @__PURE__ */ jsx("span", { className: cn("dot-bounce-3 size-1 rounded-full bg-co-primary", className) })
13
13
  ]
14
14
  });
15
15
  const TypingIndicator = React$1.forwardRef(({ participants, availableAIAgents = [], availableHumanAgents = [], withAvatars = true, className,...props }, ref) => {
@@ -1 +1 @@
1
- {"version":3,"file":"typing-indicator.js","names":["React"],"sources":["../../../src/support/components/typing-indicator.tsx"],"sourcesContent":["import type { AvailableAIAgent, AvailableHumanAgent } from \"@cossistant/types\";\nimport * as React from \"react\";\nimport { cn } from \"../utils\";\nimport { AvatarStack } from \"./avatar-stack\";\n\nexport type TypingParticipantType = \"visitor\" | \"team_member\" | \"ai\";\n\nexport type TypingParticipant = {\n\tid: string;\n\ttype: TypingParticipantType;\n};\n\nexport type TypingIndicatorProps = React.HTMLAttributes<HTMLDivElement> & {\n\tparticipants: TypingParticipant[];\n\tavailableAIAgents?: AvailableAIAgent[];\n\tavailableHumanAgents?: AvailableHumanAgent[];\n\twithAvatars?: boolean;\n};\n\nexport const BouncingDots = () => (\n\t<div className=\"flex gap-1\">\n\t\t<span className=\"dot-bounce-1 size-1 rounded-full bg-co-primary\" />\n\t\t<span className=\"dot-bounce-2 size-1 rounded-full bg-co-primary\" />\n\t\t<span className=\"dot-bounce-3 size-1 rounded-full bg-co-primary\" />\n\t</div>\n);\n\nexport const TypingIndicator = React.forwardRef<\n\tHTMLDivElement,\n\tTypingIndicatorProps\n>(\n\t(\n\t\t{\n\t\t\tparticipants,\n\t\t\tavailableAIAgents = [],\n\t\t\tavailableHumanAgents = [],\n\t\t\twithAvatars = true,\n\t\t\tclassName,\n\t\t\t...props\n\t\t},\n\t\tref\n\t) => {\n\t\tif (!participants || participants.length === 0) {\n\t\t\treturn null;\n\t\t}\n\n\t\t// Separate AI and human participants\n\t\tconst humanParticipantIds = participants\n\t\t\t.filter((p) => p.type === \"team_member\")\n\t\t\t.map((p) => p.id);\n\n\t\tconst aiParticipantIds = participants\n\t\t\t.filter((p) => p.type === \"ai\")\n\t\t\t.map((p) => p.id);\n\n\t\t// Get matching agents\n\t\tconst typingHumanAgents = availableHumanAgents.filter((agent) =>\n\t\t\thumanParticipantIds.includes(agent.id)\n\t\t);\n\n\t\tconst typingAIAgents = availableAIAgents.filter((agent) =>\n\t\t\taiParticipantIds.includes(agent.id)\n\t\t);\n\n\t\treturn (\n\t\t\t<div\n\t\t\t\tclassName={cn(\"flex items-center gap-6\", className)}\n\t\t\t\tref={ref}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{withAvatars && (\n\t\t\t\t\t<AvatarStack\n\t\t\t\t\t\taiAgents={typingAIAgents}\n\t\t\t\t\t\thumanAgents={typingHumanAgents}\n\t\t\t\t\t\tsize={24}\n\t\t\t\t\t\tspacing={16}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t\t<BouncingDots />\n\t\t\t</div>\n\t\t);\n\t}\n);\n\nTypingIndicator.displayName = \"TypingIndicator\";\n"],"mappings":";;;;;;AAmBA,MAAa,qBACZ,qBAAC;CAAI,WAAU;;EACd,oBAAC,UAAK,WAAU,mDAAmD;EACnE,oBAAC,UAAK,WAAU,mDAAmD;EACnE,oBAAC,UAAK,WAAU,mDAAmD;;EAC9D;AAGP,MAAa,kBAAkBA,QAAM,YAKnC,EACC,cACA,oBAAoB,EAAE,EACtB,uBAAuB,EAAE,EACzB,cAAc,MACd,UACA,GAAG,SAEJ,QACI;AACJ,KAAI,CAAC,gBAAgB,aAAa,WAAW,EAC5C,QAAO;CAIR,MAAM,sBAAsB,aAC1B,QAAQ,MAAM,EAAE,SAAS,cAAc,CACvC,KAAK,MAAM,EAAE,GAAG;CAElB,MAAM,mBAAmB,aACvB,QAAQ,MAAM,EAAE,SAAS,KAAK,CAC9B,KAAK,MAAM,EAAE,GAAG;CAGlB,MAAM,oBAAoB,qBAAqB,QAAQ,UACtD,oBAAoB,SAAS,MAAM,GAAG,CACtC;CAED,MAAM,iBAAiB,kBAAkB,QAAQ,UAChD,iBAAiB,SAAS,MAAM,GAAG,CACnC;AAED,QACC,qBAAC;EACA,WAAW,GAAG,2BAA2B,UAAU;EAC9C;EACL,GAAI;aAEH,eACA,oBAAC;GACA,UAAU;GACV,aAAa;GACb,MAAM;GACN,SAAS;IACR,EAEH,oBAAC,iBAAe;GACX;EAGR;AAED,gBAAgB,cAAc"}
1
+ {"version":3,"file":"typing-indicator.js","names":["React"],"sources":["../../../src/support/components/typing-indicator.tsx"],"sourcesContent":["import type { AvailableAIAgent, AvailableHumanAgent } from \"@cossistant/types\";\nimport * as React from \"react\";\nimport { cn } from \"../utils\";\nimport { AvatarStack } from \"./avatar-stack\";\n\nexport type TypingParticipantType = \"visitor\" | \"team_member\" | \"ai\";\n\nexport type TypingParticipant = {\n\tid: string;\n\ttype: TypingParticipantType;\n};\n\nexport type TypingIndicatorProps = React.HTMLAttributes<HTMLDivElement> & {\n\tparticipants: TypingParticipant[];\n\tavailableAIAgents?: AvailableAIAgent[];\n\tavailableHumanAgents?: AvailableHumanAgent[];\n\twithAvatars?: boolean;\n};\n\nexport const BouncingDots = ({\n\tclassName,\n}: {\n\tclassName?: string;\n}): React.ReactElement => (\n\t<div className=\"flex gap-1\">\n\t\t<span\n\t\t\tclassName={cn(\n\t\t\t\t\"dot-bounce-1 size-1 rounded-full bg-co-primary\",\n\t\t\t\tclassName\n\t\t\t)}\n\t\t/>\n\t\t<span\n\t\t\tclassName={cn(\n\t\t\t\t\"dot-bounce-2 size-1 rounded-full bg-co-primary\",\n\t\t\t\tclassName\n\t\t\t)}\n\t\t/>\n\t\t<span\n\t\t\tclassName={cn(\n\t\t\t\t\"dot-bounce-3 size-1 rounded-full bg-co-primary\",\n\t\t\t\tclassName\n\t\t\t)}\n\t\t/>\n\t</div>\n);\n\nexport const TypingIndicator = React.forwardRef<\n\tHTMLDivElement,\n\tTypingIndicatorProps\n>(\n\t(\n\t\t{\n\t\t\tparticipants,\n\t\t\tavailableAIAgents = [],\n\t\t\tavailableHumanAgents = [],\n\t\t\twithAvatars = true,\n\t\t\tclassName,\n\t\t\t...props\n\t\t},\n\t\tref\n\t) => {\n\t\tif (!participants || participants.length === 0) {\n\t\t\treturn null;\n\t\t}\n\n\t\t// Separate AI and human participants\n\t\tconst humanParticipantIds = participants\n\t\t\t.filter((p) => p.type === \"team_member\")\n\t\t\t.map((p) => p.id);\n\n\t\tconst aiParticipantIds = participants\n\t\t\t.filter((p) => p.type === \"ai\")\n\t\t\t.map((p) => p.id);\n\n\t\t// Get matching agents\n\t\tconst typingHumanAgents = availableHumanAgents.filter((agent) =>\n\t\t\thumanParticipantIds.includes(agent.id)\n\t\t);\n\n\t\tconst typingAIAgents = availableAIAgents.filter((agent) =>\n\t\t\taiParticipantIds.includes(agent.id)\n\t\t);\n\n\t\treturn (\n\t\t\t<div\n\t\t\t\tclassName={cn(\"flex items-center gap-6\", className)}\n\t\t\t\tref={ref}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{withAvatars && (\n\t\t\t\t\t<AvatarStack\n\t\t\t\t\t\taiAgents={typingAIAgents}\n\t\t\t\t\t\thumanAgents={typingHumanAgents}\n\t\t\t\t\t\tsize={24}\n\t\t\t\t\t\tspacing={16}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t\t<BouncingDots />\n\t\t\t</div>\n\t\t);\n\t}\n);\n\nTypingIndicator.displayName = \"TypingIndicator\";\n"],"mappings":";;;;;;AAmBA,MAAa,gBAAgB,EAC5B,gBAIA,qBAAC;CAAI,WAAU;;EACd,oBAAC,UACA,WAAW,GACV,kDACA,UACA,GACA;EACF,oBAAC,UACA,WAAW,GACV,kDACA,UACA,GACA;EACF,oBAAC,UACA,WAAW,GACV,kDACA,UACA,GACA;;EACG;AAGP,MAAa,kBAAkBA,QAAM,YAKnC,EACC,cACA,oBAAoB,EAAE,EACtB,uBAAuB,EAAE,EACzB,cAAc,MACd,UACA,GAAG,SAEJ,QACI;AACJ,KAAI,CAAC,gBAAgB,aAAa,WAAW,EAC5C,QAAO;CAIR,MAAM,sBAAsB,aAC1B,QAAQ,MAAM,EAAE,SAAS,cAAc,CACvC,KAAK,MAAM,EAAE,GAAG;CAElB,MAAM,mBAAmB,aACvB,QAAQ,MAAM,EAAE,SAAS,KAAK,CAC9B,KAAK,MAAM,EAAE,GAAG;CAGlB,MAAM,oBAAoB,qBAAqB,QAAQ,UACtD,oBAAoB,SAAS,MAAM,GAAG,CACtC;CAED,MAAM,iBAAiB,kBAAkB,QAAQ,UAChD,iBAAiB,SAAS,MAAM,GAAG,CACnC;AAED,QACC,qBAAC;EACA,WAAW,GAAG,2BAA2B,UAAU;EAC9C;EACL,GAAI;aAEH,eACA,oBAAC;GACA,UAAU;GACV,aAAa;GACb,MAAM;GACN,SAAS;IACR,EAEH,oBAAC,iBAAe;GACX;EAGR;AAED,gBAAgB,cAAc"}
@@ -1 +1 @@
1
- {"version":3,"file":"watermark.d.ts","names":[],"sources":["../../../src/support/components/watermark.tsx"],"sourcesContent":[],"mappings":";KAMY,cAAA;EAAA,SAAA,CAAA,EAAA,MAAc;AAI1B,CAAA;AAmCC,cAnCY,SAmCZ,EAnCuB,KAAA,CAAM,EAmC7B,CAnCgC,cAmChC,CAAA"}
1
+ {"version":3,"file":"watermark.d.ts","names":[],"sources":["../../../src/support/components/watermark.tsx"],"sourcesContent":[],"mappings":";KAMY,cAAA;EAAA,SAAA,CAAA,EAAA,MAAc;AAI1B,CAAA;cAAa,WAAW,KAAA,CAAM,GAAG"}
@@ -1,5 +1,6 @@
1
1
  import { RealtimeEvent } from "../../realtime-events.js";
2
2
  import { RealtimeContextValue } from "../../realtime/provider.js";
3
+ import "../../realtime/index.js";
3
4
  import React from "react";
4
5
 
5
6
  //#region src/support/context/websocket.d.ts
@@ -15,7 +16,14 @@ type WebSocketProviderProps = {
15
16
  onDisconnect?: () => void;
16
17
  onError?: (error: Error) => void;
17
18
  };
19
+ /**
20
+ * Support-specific realtime provider that authenticates visitors and keeps the
21
+ * connection alive with presence pings.
22
+ */
18
23
  declare const WebSocketProvider: React.FC<WebSocketProviderProps>;
24
+ /**
25
+ * Accessor for the support websocket context.
26
+ */
19
27
  declare const useWebSocket: () => WebSocketContextValue;
20
28
  //#endregion
21
29
  export { type RealtimeEvent, type WebSocketContextValue, WebSocketProvider, type WebSocketProviderProps, useWebSocket };
@@ -1 +1 @@
1
- {"version":3,"file":"websocket.d.ts","names":[],"sources":["../../../src/support/context/websocket.tsx"],"sourcesContent":[],"mappings":";;;;;KAYK,qBAAA,GAAwB;KAExB,sBAAA;YACM,KAAA,CAAM;EAHZ,SAAA,CAAA,EAAA,MAAA;EAEA,SAAA,CAAA,EAAA,MAAA;EAAsB,SAAA,CAAA,EAAA,MAAA;OAChB,CAAA,EAAA,MAAM;aAQE,CAAA,EAAA,OAAA;EAAK,SAAA,CAAA,EAAA,GAAA,GAAA,IAAA;EAyIX,YAAA,CAAA,EAAA,GAAA,GAyBZ,IAAA;EAAA,OAAA,CAAA,EAAA,CAAA,KAAA,EAlKkB,KAkKlB,EAAA,GAAA,IAAA;;AAzB+B,cAAnB,iBAAyB,EAAN,KAAA,CAAM,EAAA,CAAG,sBAAH,CAAA;AAAE,cA2B3B,YA3B2B,EAAA,GAAA,GA2BR,qBA3BQ"}
1
+ {"version":3,"file":"websocket.d.ts","names":[],"sources":["../../../src/support/context/websocket.tsx"],"sourcesContent":[],"mappings":";;;;;;KAYK,qBAAA,GAAwB;KAExB,sBAAA;YACM,KAAA,CAAM;;EAHZ,SAAA,CAAA,EAAA,MAAA;EAEA,SAAA,CAAA,EAAA,MAAA;EAsJQ,KAAA,CAAA,EAAA,MAAA;EA8BA,WAAA,CAAA,EAAA,OAMZ;;;oBAjLkB;;;;;;cA6IN,mBAAmB,KAAA,CAAM,GAAG;;;;cA8B5B,oBAAmB"}
@@ -83,14 +83,17 @@ const WebSocketBridge = ({ children, onError }) => {
83
83
  children
84
84
  });
85
85
  };
86
+ /**
87
+ * Support-specific realtime provider that authenticates visitors and keeps the
88
+ * connection alive with presence pings.
89
+ */
86
90
  const WebSocketProvider = ({ children, publicKey, websiteId, visitorId, wsUrl, autoConnect = true, onConnect, onDisconnect, onError }) => {
87
- const auth = createVisitorAuthConfig({
88
- publicKey,
89
- websiteId,
90
- visitorId
91
- });
92
91
  return /* @__PURE__ */ jsx(RealtimeProvider, {
93
- auth,
92
+ auth: createVisitorAuthConfig({
93
+ publicKey,
94
+ websiteId,
95
+ visitorId
96
+ }),
94
97
  autoConnect,
95
98
  onConnect,
96
99
  onDisconnect,
@@ -102,6 +105,9 @@ const WebSocketProvider = ({ children, publicKey, websiteId, visitorId, wsUrl, a
102
105
  })
103
106
  });
104
107
  };
108
+ /**
109
+ * Accessor for the support websocket context.
110
+ */
105
111
  const useWebSocket = () => {
106
112
  const context = useContext(WebSocketContext);
107
113
  if (!context) throw new Error("useWebSocket must be used within WebSocketProvider");
@@ -1 +1 @@
1
- {"version":3,"file":"websocket.js","names":["WebSocketBridge: React.FC<WebSocketBridgeProps>","intervalId: number | null","WebSocketProvider: React.FC<WebSocketProviderProps>"],"sources":["../../../src/support/context/websocket.tsx"],"sourcesContent":["\"use client\";\n\nimport { PRESENCE_PING_INTERVAL_MS } from \"@cossistant/types\";\nimport type React from \"react\";\nimport { createContext, useContext, useEffect, useMemo } from \"react\";\nimport {\n\ttype RealtimeAuthConfig,\n\ttype RealtimeContextValue,\n\tRealtimeProvider,\n\tuseRealtimeConnection,\n} from \"../../realtime\";\n\ntype WebSocketContextValue = RealtimeContextValue;\n\ntype WebSocketProviderProps = {\n\tchildren: React.ReactNode;\n\tpublicKey?: string;\n\twebsiteId?: string;\n\tvisitorId?: string;\n\twsUrl?: string;\n\tautoConnect?: boolean;\n\tonConnect?: () => void;\n\tonDisconnect?: () => void;\n\tonError?: (error: Error) => void;\n};\n\nconst WebSocketContext = createContext<WebSocketContextValue | null>(null);\n\nfunction createVisitorAuthConfig({\n\tvisitorId,\n\twebsiteId,\n\tpublicKey,\n}: Pick<\n\tWebSocketProviderProps,\n\t\"visitorId\" | \"websiteId\" | \"publicKey\"\n>): RealtimeAuthConfig | null {\n\tconst normalizedVisitorId = visitorId?.trim();\n\tif (!normalizedVisitorId) {\n\t\treturn null;\n\t}\n\n\treturn {\n\t\tkind: \"visitor\",\n\t\tvisitorId: normalizedVisitorId,\n\t\twebsiteId: websiteId?.trim() || null,\n\t\tpublicKey: publicKey?.trim() || null,\n\t} satisfies RealtimeAuthConfig;\n}\n\ntype WebSocketBridgeProps = {\n\tchildren: React.ReactNode;\n\tonError?: (error: Error) => void;\n};\n\nconst WebSocketBridge: React.FC<WebSocketBridgeProps> = ({\n\tchildren,\n\tonError,\n}) => {\n\tconst connection = useRealtimeConnection();\n\tconst { visitorId, sendRaw, isConnected } = connection;\n\n\tuseEffect(() => {\n\t\tif (typeof window === \"undefined\" || typeof document === \"undefined\") {\n\t\t\treturn;\n\t\t}\n\n\t\tif (!(visitorId && sendRaw)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst pingMessage = \"presence:ping\";\n\n\t\tconst sendPresencePing = () => {\n\t\t\tif (!isConnected) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tsendRaw(pingMessage);\n\t\t\t} catch (error) {\n\t\t\t\tif (!onError) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst normalizedError =\n\t\t\t\t\terror instanceof Error\n\t\t\t\t\t\t? error\n\t\t\t\t\t\t: new Error(\n\t\t\t\t\t\t\t\ttypeof error === \"string\"\n\t\t\t\t\t\t\t\t\t? error\n\t\t\t\t\t\t\t\t\t: \"Unknown presence ping error\"\n\t\t\t\t\t\t\t);\n\n\t\t\t\tif (!normalizedError.message.includes(\"Failed to send presence ping\")) {\n\t\t\t\t\tnormalizedError.message = `Failed to send presence ping: ${normalizedError.message}`;\n\t\t\t\t}\n\n\t\t\t\tonError(normalizedError);\n\t\t\t}\n\t\t};\n\n\t\tlet intervalId: number | null = null;\n\n\t\tconst clearPresenceInterval = () => {\n\t\t\tif (intervalId !== null) {\n\t\t\t\twindow.clearInterval(intervalId);\n\t\t\t\tintervalId = null;\n\t\t\t}\n\t\t};\n\n\t\tconst startPresenceInterval = () => {\n\t\t\tclearPresenceInterval();\n\n\t\t\tif (!isConnected || document.visibilityState === \"hidden\") {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tintervalId = window.setInterval(\n\t\t\t\tsendPresencePing,\n\t\t\t\tPRESENCE_PING_INTERVAL_MS\n\t\t\t);\n\t\t};\n\n\t\tconst handleFocus = () => {\n\t\t\tsendPresencePing();\n\t\t\tstartPresenceInterval();\n\t\t};\n\n\t\tconst handleVisibilityChange = () => {\n\t\t\tif (document.visibilityState === \"hidden\") {\n\t\t\t\tclearPresenceInterval();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tsendPresencePing();\n\t\t\tstartPresenceInterval();\n\t\t};\n\n\t\twindow.addEventListener(\"focus\", handleFocus);\n\t\tdocument.addEventListener(\"visibilitychange\", handleVisibilityChange);\n\n\t\tif (isConnected && document.visibilityState !== \"hidden\") {\n\t\t\tsendPresencePing();\n\t\t\tstartPresenceInterval();\n\t\t}\n\n\t\treturn () => {\n\t\t\twindow.removeEventListener(\"focus\", handleFocus);\n\t\t\tdocument.removeEventListener(\"visibilitychange\", handleVisibilityChange);\n\t\t\tclearPresenceInterval();\n\t\t};\n\t}, [isConnected, onError, sendRaw, visitorId]);\n\tconst value = useMemo(() => connection, [connection]);\n\treturn (\n\t\t<WebSocketContext.Provider value={value}>\n\t\t\t{children}\n\t\t</WebSocketContext.Provider>\n\t);\n};\n\nexport const WebSocketProvider: React.FC<WebSocketProviderProps> = ({\n\tchildren,\n\tpublicKey,\n\twebsiteId,\n\tvisitorId,\n\twsUrl,\n\tautoConnect = true,\n\tonConnect,\n\tonDisconnect,\n\tonError,\n}) => {\n\tconst auth = createVisitorAuthConfig({ publicKey, websiteId, visitorId });\n\n\treturn (\n\t\t<RealtimeProvider\n\t\t\tauth={auth}\n\t\t\tautoConnect={autoConnect}\n\t\t\tonConnect={onConnect}\n\t\t\tonDisconnect={onDisconnect}\n\t\t\tonError={onError}\n\t\t\twsUrl={wsUrl}\n\t\t>\n\t\t\t<WebSocketBridge onError={onError}>{children}</WebSocketBridge>\n\t\t</RealtimeProvider>\n\t);\n};\n\nexport const useWebSocket = (): WebSocketContextValue => {\n\tconst context = useContext(WebSocketContext);\n\tif (!context) {\n\t\tthrow new Error(\"useWebSocket must be used within WebSocketProvider\");\n\t}\n\treturn context;\n};\n\nexport type { WebSocketContextValue, WebSocketProviderProps };\nexport type { RealtimeEvent } from \"@cossistant/types/realtime-events\";\n"],"mappings":";;;;;;;;;AA0BA,MAAM,mBAAmB,cAA4C,KAAK;AAE1E,SAAS,wBAAwB,EAChC,WACA,WACA,aAI6B;CAC7B,MAAM,sBAAsB,WAAW,MAAM;AAC7C,KAAI,CAAC,oBACJ,QAAO;AAGR,QAAO;EACN,MAAM;EACN,WAAW;EACX,WAAW,WAAW,MAAM,IAAI;EAChC,WAAW,WAAW,MAAM,IAAI;EAChC;;AAQF,MAAMA,mBAAmD,EACxD,UACA,cACK;CACL,MAAM,aAAa,uBAAuB;CAC1C,MAAM,EAAE,WAAW,SAAS,gBAAgB;AAE5C,iBAAgB;AACf,MAAI,OAAO,WAAW,eAAe,OAAO,aAAa,YACxD;AAGD,MAAI,EAAE,aAAa,SAClB;EAGD,MAAM,cAAc;EAEpB,MAAM,yBAAyB;AAC9B,OAAI,CAAC,YACJ;AAGD,OAAI;AACH,YAAQ,YAAY;YACZ,OAAO;AACf,QAAI,CAAC,QACJ;IAGD,MAAM,kBACL,iBAAiB,QACd,QACA,IAAI,MACJ,OAAO,UAAU,WACd,QACA,8BACH;AAEJ,QAAI,CAAC,gBAAgB,QAAQ,SAAS,+BAA+B,CACpE,iBAAgB,UAAU,iCAAiC,gBAAgB;AAG5E,YAAQ,gBAAgB;;;EAI1B,IAAIC,aAA4B;EAEhC,MAAM,8BAA8B;AACnC,OAAI,eAAe,MAAM;AACxB,WAAO,cAAc,WAAW;AAChC,iBAAa;;;EAIf,MAAM,8BAA8B;AACnC,0BAAuB;AAEvB,OAAI,CAAC,eAAe,SAAS,oBAAoB,SAChD;AAGD,gBAAa,OAAO,YACnB,kBACA,0BACA;;EAGF,MAAM,oBAAoB;AACzB,qBAAkB;AAClB,0BAAuB;;EAGxB,MAAM,+BAA+B;AACpC,OAAI,SAAS,oBAAoB,UAAU;AAC1C,2BAAuB;AACvB;;AAGD,qBAAkB;AAClB,0BAAuB;;AAGxB,SAAO,iBAAiB,SAAS,YAAY;AAC7C,WAAS,iBAAiB,oBAAoB,uBAAuB;AAErE,MAAI,eAAe,SAAS,oBAAoB,UAAU;AACzD,qBAAkB;AAClB,0BAAuB;;AAGxB,eAAa;AACZ,UAAO,oBAAoB,SAAS,YAAY;AAChD,YAAS,oBAAoB,oBAAoB,uBAAuB;AACxE,0BAAuB;;IAEtB;EAAC;EAAa;EAAS;EAAS;EAAU,CAAC;CAC9C,MAAM,QAAQ,cAAc,YAAY,CAAC,WAAW,CAAC;AACrD,QACC,oBAAC,iBAAiB;EAAgB;EAChC;GAC0B;;AAI9B,MAAaC,qBAAuD,EACnE,UACA,WACA,WACA,WACA,OACA,cAAc,MACd,WACA,cACA,cACK;CACL,MAAM,OAAO,wBAAwB;EAAE;EAAW;EAAW;EAAW,CAAC;AAEzE,QACC,oBAAC;EACM;EACO;EACF;EACG;EACL;EACF;YAEP,oBAAC;GAAyB;GAAU;IAA2B;GAC7C;;AAIrB,MAAa,qBAA4C;CACxD,MAAM,UAAU,WAAW,iBAAiB;AAC5C,KAAI,CAAC,QACJ,OAAM,IAAI,MAAM,qDAAqD;AAEtE,QAAO"}
1
+ {"version":3,"file":"websocket.js","names":["WebSocketBridge: React.FC<WebSocketBridgeProps>","intervalId: number | null","WebSocketProvider: React.FC<WebSocketProviderProps>"],"sources":["../../../src/support/context/websocket.tsx"],"sourcesContent":["\"use client\";\n\nimport { PRESENCE_PING_INTERVAL_MS } from \"@cossistant/types\";\nimport type React from \"react\";\nimport { createContext, useContext, useEffect, useMemo } from \"react\";\nimport {\n\ttype RealtimeAuthConfig,\n\ttype RealtimeContextValue,\n\tRealtimeProvider,\n\tuseRealtimeConnection,\n} from \"../../realtime\";\n\ntype WebSocketContextValue = RealtimeContextValue;\n\ntype WebSocketProviderProps = {\n\tchildren: React.ReactNode;\n\tpublicKey?: string;\n\twebsiteId?: string;\n\tvisitorId?: string;\n\twsUrl?: string;\n\tautoConnect?: boolean;\n\tonConnect?: () => void;\n\tonDisconnect?: () => void;\n\tonError?: (error: Error) => void;\n};\n\nconst WebSocketContext = createContext<WebSocketContextValue | null>(null);\n\nfunction createVisitorAuthConfig({\n\tvisitorId,\n\twebsiteId,\n\tpublicKey,\n}: Pick<\n\tWebSocketProviderProps,\n\t\"visitorId\" | \"websiteId\" | \"publicKey\"\n>): RealtimeAuthConfig | null {\n\tconst normalizedVisitorId = visitorId?.trim();\n\tif (!normalizedVisitorId) {\n\t\treturn null;\n\t}\n\n\treturn {\n\t\tkind: \"visitor\",\n\t\tvisitorId: normalizedVisitorId,\n\t\twebsiteId: websiteId?.trim() || null,\n\t\tpublicKey: publicKey?.trim() || null,\n\t} satisfies RealtimeAuthConfig;\n}\n\ntype WebSocketBridgeProps = {\n\tchildren: React.ReactNode;\n\tonError?: (error: Error) => void;\n};\n\nconst WebSocketBridge: React.FC<WebSocketBridgeProps> = ({\n\tchildren,\n\tonError,\n}) => {\n\tconst connection = useRealtimeConnection();\n\tconst { visitorId, sendRaw, isConnected } = connection;\n\n\tuseEffect(() => {\n\t\tif (typeof window === \"undefined\" || typeof document === \"undefined\") {\n\t\t\treturn;\n\t\t}\n\n\t\tif (!(visitorId && sendRaw)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst pingMessage = \"presence:ping\";\n\n\t\tconst sendPresencePing = () => {\n\t\t\tif (!isConnected) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tsendRaw(pingMessage);\n\t\t\t} catch (error) {\n\t\t\t\tif (!onError) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst normalizedError =\n\t\t\t\t\terror instanceof Error\n\t\t\t\t\t\t? error\n\t\t\t\t\t\t: new Error(\n\t\t\t\t\t\t\t\ttypeof error === \"string\"\n\t\t\t\t\t\t\t\t\t? error\n\t\t\t\t\t\t\t\t\t: \"Unknown presence ping error\"\n\t\t\t\t\t\t\t);\n\n\t\t\t\tif (!normalizedError.message.includes(\"Failed to send presence ping\")) {\n\t\t\t\t\tnormalizedError.message = `Failed to send presence ping: ${normalizedError.message}`;\n\t\t\t\t}\n\n\t\t\t\tonError(normalizedError);\n\t\t\t}\n\t\t};\n\n\t\tlet intervalId: number | null = null;\n\n\t\tconst clearPresenceInterval = () => {\n\t\t\tif (intervalId !== null) {\n\t\t\t\twindow.clearInterval(intervalId);\n\t\t\t\tintervalId = null;\n\t\t\t}\n\t\t};\n\n\t\tconst startPresenceInterval = () => {\n\t\t\tclearPresenceInterval();\n\n\t\t\tif (!isConnected || document.visibilityState === \"hidden\") {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tintervalId = window.setInterval(\n\t\t\t\tsendPresencePing,\n\t\t\t\tPRESENCE_PING_INTERVAL_MS\n\t\t\t);\n\t\t};\n\n\t\tconst handleFocus = () => {\n\t\t\tsendPresencePing();\n\t\t\tstartPresenceInterval();\n\t\t};\n\n\t\tconst handleVisibilityChange = () => {\n\t\t\tif (document.visibilityState === \"hidden\") {\n\t\t\t\tclearPresenceInterval();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tsendPresencePing();\n\t\t\tstartPresenceInterval();\n\t\t};\n\n\t\twindow.addEventListener(\"focus\", handleFocus);\n\t\tdocument.addEventListener(\"visibilitychange\", handleVisibilityChange);\n\n\t\tif (isConnected && document.visibilityState !== \"hidden\") {\n\t\t\tsendPresencePing();\n\t\t\tstartPresenceInterval();\n\t\t}\n\n\t\treturn () => {\n\t\t\twindow.removeEventListener(\"focus\", handleFocus);\n\t\t\tdocument.removeEventListener(\"visibilitychange\", handleVisibilityChange);\n\t\t\tclearPresenceInterval();\n\t\t};\n\t}, [isConnected, onError, sendRaw, visitorId]);\n\tconst value = useMemo(() => connection, [connection]);\n\treturn (\n\t\t<WebSocketContext.Provider value={value}>\n\t\t\t{children}\n\t\t</WebSocketContext.Provider>\n\t);\n};\n\n/**\n * Support-specific realtime provider that authenticates visitors and keeps the\n * connection alive with presence pings.\n */\nexport const WebSocketProvider: React.FC<WebSocketProviderProps> = ({\n\tchildren,\n\tpublicKey,\n\twebsiteId,\n\tvisitorId,\n\twsUrl,\n\tautoConnect = true,\n\tonConnect,\n\tonDisconnect,\n\tonError,\n}) => {\n\tconst auth = createVisitorAuthConfig({ publicKey, websiteId, visitorId });\n\n\treturn (\n\t\t<RealtimeProvider\n\t\t\tauth={auth}\n\t\t\tautoConnect={autoConnect}\n\t\t\tonConnect={onConnect}\n\t\t\tonDisconnect={onDisconnect}\n\t\t\tonError={onError}\n\t\t\twsUrl={wsUrl}\n\t\t>\n\t\t\t<WebSocketBridge onError={onError}>{children}</WebSocketBridge>\n\t\t</RealtimeProvider>\n\t);\n};\n\n/**\n * Accessor for the support websocket context.\n */\nexport const useWebSocket = (): WebSocketContextValue => {\n\tconst context = useContext(WebSocketContext);\n\tif (!context) {\n\t\tthrow new Error(\"useWebSocket must be used within WebSocketProvider\");\n\t}\n\treturn context;\n};\n\nexport type { WebSocketContextValue, WebSocketProviderProps };\nexport type { RealtimeEvent } from \"@cossistant/types/realtime-events\";\n"],"mappings":";;;;;;;;;AA0BA,MAAM,mBAAmB,cAA4C,KAAK;AAE1E,SAAS,wBAAwB,EAChC,WACA,WACA,aAI6B;CAC7B,MAAM,sBAAsB,WAAW,MAAM;AAC7C,KAAI,CAAC,oBACJ,QAAO;AAGR,QAAO;EACN,MAAM;EACN,WAAW;EACX,WAAW,WAAW,MAAM,IAAI;EAChC,WAAW,WAAW,MAAM,IAAI;EAChC;;AAQF,MAAMA,mBAAmD,EACxD,UACA,cACK;CACL,MAAM,aAAa,uBAAuB;CAC1C,MAAM,EAAE,WAAW,SAAS,gBAAgB;AAE5C,iBAAgB;AACf,MAAI,OAAO,WAAW,eAAe,OAAO,aAAa,YACxD;AAGD,MAAI,EAAE,aAAa,SAClB;EAGD,MAAM,cAAc;EAEpB,MAAM,yBAAyB;AAC9B,OAAI,CAAC,YACJ;AAGD,OAAI;AACH,YAAQ,YAAY;YACZ,OAAO;AACf,QAAI,CAAC,QACJ;IAGD,MAAM,kBACL,iBAAiB,QACd,QACA,IAAI,MACJ,OAAO,UAAU,WACd,QACA,8BACH;AAEJ,QAAI,CAAC,gBAAgB,QAAQ,SAAS,+BAA+B,CACpE,iBAAgB,UAAU,iCAAiC,gBAAgB;AAG5E,YAAQ,gBAAgB;;;EAI1B,IAAIC,aAA4B;EAEhC,MAAM,8BAA8B;AACnC,OAAI,eAAe,MAAM;AACxB,WAAO,cAAc,WAAW;AAChC,iBAAa;;;EAIf,MAAM,8BAA8B;AACnC,0BAAuB;AAEvB,OAAI,CAAC,eAAe,SAAS,oBAAoB,SAChD;AAGD,gBAAa,OAAO,YACnB,kBACA,0BACA;;EAGF,MAAM,oBAAoB;AACzB,qBAAkB;AAClB,0BAAuB;;EAGxB,MAAM,+BAA+B;AACpC,OAAI,SAAS,oBAAoB,UAAU;AAC1C,2BAAuB;AACvB;;AAGD,qBAAkB;AAClB,0BAAuB;;AAGxB,SAAO,iBAAiB,SAAS,YAAY;AAC7C,WAAS,iBAAiB,oBAAoB,uBAAuB;AAErE,MAAI,eAAe,SAAS,oBAAoB,UAAU;AACzD,qBAAkB;AAClB,0BAAuB;;AAGxB,eAAa;AACZ,UAAO,oBAAoB,SAAS,YAAY;AAChD,YAAS,oBAAoB,oBAAoB,uBAAuB;AACxE,0BAAuB;;IAEtB;EAAC;EAAa;EAAS;EAAS;EAAU,CAAC;CAC9C,MAAM,QAAQ,cAAc,YAAY,CAAC,WAAW,CAAC;AACrD,QACC,oBAAC,iBAAiB;EAAgB;EAChC;GAC0B;;;;;;AAQ9B,MAAaC,qBAAuD,EACnE,UACA,WACA,WACA,WACA,OACA,cAAc,MACd,WACA,cACA,cACK;AAGL,QACC,oBAAC;EACA,MAJW,wBAAwB;GAAE;GAAW;GAAW;GAAW,CAAC;EAK1D;EACF;EACG;EACL;EACF;YAEP,oBAAC;GAAyB;GAAU;IAA2B;GAC7C;;;;;AAOrB,MAAa,qBAA4C;CACxD,MAAM,UAAU,WAAW,iBAAiB;AAC5C,KAAI,CAAC,QACJ,OAAM,IAAI,MAAM,qDAAqD;AAEtE,QAAO"}
@@ -1,17 +1,17 @@
1
1
  import { SupportLocale, SupportTextContentOverrides } from "./text/locales/keys.js";
2
2
  import { Text, useSupportText } from "./text/index.js";
3
- import { useSupportConfig } from "./context/config.js";
4
3
  import { WebSocketContextValue, WebSocketProvider, useWebSocket } from "./context/websocket.js";
5
- import { useSupportStore } from "./store/support-store.js";
4
+ import { useSupportConfig, useSupportNavigation, useSupportStore } from "./store/support-store.js";
5
+ import "./store/index.js";
6
+ import { ReactElement } from "react";
6
7
  import { DefaultMessage } from "@cossistant/types";
7
- import * as react_jsx_runtime1 from "react/jsx-runtime";
8
8
 
9
9
  //#region src/support/index.d.ts
10
10
  type SupportProps<Locale extends string = SupportLocale> = {
11
11
  className?: string;
12
12
  position?: "top" | "bottom";
13
13
  align?: "right" | "left";
14
- mode?: "floating" | "responsive";
14
+ positioning?: "fixed" | "absolute";
15
15
  quickOptions?: string[];
16
16
  defaultMessages?: DefaultMessage[];
17
17
  defaultOpen?: boolean;
@@ -19,7 +19,7 @@ type SupportProps<Locale extends string = SupportLocale> = {
19
19
  content?: SupportTextContentOverrides<Locale>;
20
20
  };
21
21
  /**
22
- * Orchestrates the end-user support experience by nesting realtime, config and
22
+ * Orchestrates the end-user support experience by nesting realtime and
23
23
  * content providers. Renders nothing until website data is available to avoid
24
24
  * flashing incomplete UI.
25
25
  */
@@ -27,13 +27,13 @@ declare function Support<Locale extends string = SupportLocale>({
27
27
  className,
28
28
  position,
29
29
  align,
30
- mode,
30
+ positioning,
31
31
  quickOptions,
32
32
  defaultMessages,
33
33
  defaultOpen,
34
34
  locale,
35
35
  content
36
- }: SupportProps<Locale>): react_jsx_runtime1.JSX.Element | null;
36
+ }: SupportProps<Locale>): ReactElement | null;
37
37
  //#endregion
38
- export { Support, Support as default, type SupportLocale, SupportProps, type SupportTextContentOverrides, Text, type WebSocketContextValue, WebSocketProvider, useSupportConfig, useSupportStore, useSupportText, useWebSocket };
38
+ export { Support, Support as default, type SupportLocale, SupportProps, type SupportTextContentOverrides, Text, type WebSocketContextValue, WebSocketProvider, useSupportConfig, useSupportNavigation, useSupportStore, useSupportText, useWebSocket };
39
39
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/support/index.tsx"],"sourcesContent":[],"mappings":";;;;;;;;;KAWY,qCAAqC;;;;;;EAArC,eAAY,CAAA,EAOL,cAPK,EAAA;EAAA,WAAA,CAAA,EAAA,OAAA;QAAyB,CAAA,EASvC,MATuC;SAO9B,CAAA,EAGR,2BAHQ,CAGoB,MAHpB,CAAA;;;;;AAYnB;;AAAgD,iBAAhC,OAAgC,CAAA,eAAA,MAAA,GAAA,aAAA,CAAA,CAAA;EAAA,SAAA;EAAA,QAAA;EAAA,KAAA;EAAA,IAAA;EAAA,YAAA;EAAA,eAAA;EAAA,WAAA;EAAA,MAAA;EAAA;AAAA,CAAA,EAU7C,YAV6C,CAUhC,MAVgC,CAAA,CAAA,EAUzB,kBAAA,CAAA,GAAA,CAAA,OAAA,GAVyB,IAAA"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/support/index.tsx"],"sourcesContent":[],"mappings":";;;;;;;;;KAYY,qCAAqC;;;;;EAArC,YAAA,CAAA,EAAY,MAAA,EAAA;EAAyB,eAAA,CAAA,EAM9B,cAN8B,EAAA;EAM9B,WAAA,CAAA,EAAA,OAAA;EAET,MAAA,CAAA,EAAA,MAAA;EAC6B,OAAA,CAAA,EAA5B,2BAA4B,CAAA,MAAA,CAAA;CAA5B;;AASX;;;;AAGC,iBAHe,OAGf,CAAA,eAAA,MAAA,GAH+C,aAG/C,CAAA,CAAA;EAAA,SAAA;EAAA,QAAA;EAAA,KAAA;EAAA,WAAA;EAAA,YAAA;EAAA,eAAA;EAAA,WAAA;EAAA,MAAA;EAAA;AAAA,CAAA,EAOE,YAPF,CAOe,MAPf,CAAA,CAAA,EAOyB,YAPzB,GAAA,IAAA"}
package/support/index.js CHANGED
@@ -1,35 +1,35 @@
1
1
  import "./support.js";
2
2
  import { SupportRealtimeProvider } from "../realtime/support-provider.js";
3
3
  import { SupportConfig } from "../support-config.js";
4
- import { useSupportStore } from "./store/support-store.js";
5
- import { SupportConfigProvider, useSupportConfig } from "./context/config.js";
4
+ import { initializeSupportStore, useSupportConfig, useSupportNavigation, useSupportStore } from "./store/support-store.js";
6
5
  import { SupportTextProvider, Text, useSupportText } from "./text/index.js";
7
6
  import { SupportContent } from "./components/support-content.js";
8
7
  import { WebSocketProvider, useWebSocket } from "./context/websocket.js";
9
8
  import { useSupport } from "../provider.js";
9
+ import React from "react";
10
10
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
11
11
 
12
12
  //#region src/support/index.tsx
13
13
  /**
14
- * Orchestrates the end-user support experience by nesting realtime, config and
14
+ * Orchestrates the end-user support experience by nesting realtime and
15
15
  * content providers. Renders nothing until website data is available to avoid
16
16
  * flashing incomplete UI.
17
17
  */
18
- function Support({ className, position = "bottom", align = "right", mode = "floating", quickOptions, defaultMessages, defaultOpen, locale, content }) {
18
+ function Support({ className, position = "bottom", align = "right", positioning = "fixed", quickOptions, defaultMessages, defaultOpen, locale, content }) {
19
19
  const { website } = useSupport();
20
- if (!website) return null;
21
- return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(SupportRealtimeProvider, { children: /* @__PURE__ */ jsx(SupportConfigProvider, {
22
- defaultOpen,
23
- mode,
24
- children: /* @__PURE__ */ jsx(SupportTextProvider, {
25
- content,
26
- locale,
27
- children: /* @__PURE__ */ jsx(SupportContent, {
28
- align,
29
- className,
30
- mode,
31
- position
32
- })
20
+ const isVisitorBlocked = website?.visitor?.isBlocked ?? false;
21
+ React.useEffect(() => {
22
+ if (defaultOpen !== void 0) initializeSupportStore({ defaultOpen });
23
+ }, [defaultOpen]);
24
+ if (!website || isVisitorBlocked) return null;
25
+ return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(SupportRealtimeProvider, { children: /* @__PURE__ */ jsx(SupportTextProvider, {
26
+ content,
27
+ locale,
28
+ children: /* @__PURE__ */ jsx(SupportContent, {
29
+ align,
30
+ className,
31
+ position,
32
+ positioning
33
33
  })
34
34
  }) }), /* @__PURE__ */ jsx(SupportConfig, {
35
35
  defaultMessages,
@@ -39,5 +39,5 @@ function Support({ className, position = "bottom", align = "right", mode = "floa
39
39
  var support_default = Support;
40
40
 
41
41
  //#endregion
42
- export { Support, Text, WebSocketProvider, support_default as default, useSupportConfig, useSupportStore, useSupportText, useWebSocket };
42
+ export { Support, Text, WebSocketProvider, support_default as default, useSupportConfig, useSupportNavigation, useSupportStore, useSupportText, useWebSocket };
43
43
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/support/index.tsx"],"sourcesContent":["import \"./support.css\";\n\nimport type { DefaultMessage } from \"@cossistant/types\";\nimport { useSupport } from \"../provider\";\nimport { SupportRealtimeProvider } from \"../realtime\";\nimport { SupportConfig } from \"../support-config\";\nimport { SupportContent } from \"./components/support-content\";\nimport { SupportConfigProvider } from \"./context/config\";\nimport type { SupportLocale, SupportTextContentOverrides } from \"./text\";\nimport { SupportTextProvider } from \"./text\";\n\nexport type SupportProps<Locale extends string = SupportLocale> = {\n\tclassName?: string;\n\tposition?: \"top\" | \"bottom\";\n\talign?: \"right\" | \"left\";\n\t// Display the support widget in a floating window or in responsive mode (takes the full width / height of the parent)\n\tmode?: \"floating\" | \"responsive\";\n\tquickOptions?: string[];\n\tdefaultMessages?: DefaultMessage[];\n\tdefaultOpen?: boolean;\n\tlocale?: Locale;\n\tcontent?: SupportTextContentOverrides<Locale>;\n};\n\n// Internal component that needs the conversation context\n/**\n * Orchestrates the end-user support experience by nesting realtime, config and\n * content providers. Renders nothing until website data is available to avoid\n * flashing incomplete UI.\n */\nexport function Support<Locale extends string = SupportLocale>({\n\tclassName,\n\tposition = \"bottom\",\n\talign = \"right\",\n\tmode = \"floating\",\n\tquickOptions,\n\tdefaultMessages,\n\tdefaultOpen,\n\tlocale,\n\tcontent,\n}: SupportProps<Locale>) {\n\tconst { website } = useSupport();\n\n\tif (!website) {\n\t\treturn null;\n\t}\n\n\treturn (\n\t\t<>\n\t\t\t<SupportRealtimeProvider>\n\t\t\t\t<SupportConfigProvider defaultOpen={defaultOpen} mode={mode}>\n\t\t\t\t\t<SupportTextProvider content={content} locale={locale}>\n\t\t\t\t\t\t<SupportContent\n\t\t\t\t\t\t\talign={align}\n\t\t\t\t\t\t\tclassName={className}\n\t\t\t\t\t\t\tmode={mode}\n\t\t\t\t\t\t\tposition={position}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</SupportTextProvider>\n\t\t\t\t</SupportConfigProvider>\n\t\t\t</SupportRealtimeProvider>\n\t\t\t<SupportConfig\n\t\t\t\tdefaultMessages={defaultMessages}\n\t\t\t\tquickOptions={quickOptions}\n\t\t\t/>\n\t\t</>\n\t);\n}\n\nexport default Support;\n\nexport { useSupportConfig } from \"./context/config\";\nexport type { WebSocketContextValue } from \"./context/websocket\";\nexport { useWebSocket, WebSocketProvider } from \"./context/websocket\";\n// Export the store for direct access if needed\nexport { useSupportStore } from \"./store\";\nexport type { SupportLocale, SupportTextContentOverrides } from \"./text\";\nexport { Text, useSupportText } from \"./text\";\n"],"mappings":";;;;;;;;;;;;;;;;;AA8BA,SAAgB,QAA+C,EAC9D,WACA,WAAW,UACX,QAAQ,SACR,OAAO,YACP,cACA,iBACA,aACA,QACA,WACwB;CACxB,MAAM,EAAE,YAAY,YAAY;AAEhC,KAAI,CAAC,QACJ,QAAO;AAGR,QACC,4CACC,oBAAC,qCACA,oBAAC;EAAmC;EAAmB;YACtD,oBAAC;GAA6B;GAAiB;aAC9C,oBAAC;IACO;IACI;IACL;IACI;KACT;IACmB;GACC,GACC,EAC1B,oBAAC;EACiB;EACH;GACb,IACA;;AAIL,sBAAe"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/support/index.tsx"],"sourcesContent":["import \"./support.css\";\n\nimport type { DefaultMessage } from \"@cossistant/types\";\nimport React, { type ReactElement } from \"react\";\nimport { useSupport } from \"../provider\";\nimport { SupportRealtimeProvider } from \"../realtime\";\nimport { SupportConfig } from \"../support-config\";\nimport { SupportContent } from \"./components/support-content\";\nimport { initializeSupportStore } from \"./store/support-store\";\nimport type { SupportLocale, SupportTextContentOverrides } from \"./text\";\nimport { SupportTextProvider } from \"./text\";\n\nexport type SupportProps<Locale extends string = SupportLocale> = {\n\tclassName?: string;\n\tposition?: \"top\" | \"bottom\";\n\talign?: \"right\" | \"left\";\n\tpositioning?: \"fixed\" | \"absolute\";\n\tquickOptions?: string[];\n\tdefaultMessages?: DefaultMessage[];\n\tdefaultOpen?: boolean;\n\tlocale?: Locale;\n\tcontent?: SupportTextContentOverrides<Locale>;\n};\n\n// Internal component that needs the conversation context\n/**\n * Orchestrates the end-user support experience by nesting realtime and\n * content providers. Renders nothing until website data is available to avoid\n * flashing incomplete UI.\n */\nexport function Support<Locale extends string = SupportLocale>({\n\tclassName,\n\tposition = \"bottom\",\n\talign = \"right\",\n\tpositioning = \"fixed\",\n\tquickOptions,\n\tdefaultMessages,\n\tdefaultOpen,\n\tlocale,\n\tcontent,\n}: SupportProps<Locale>): ReactElement | null {\n\tconst { website } = useSupport();\n\tconst isVisitorBlocked = website?.visitor?.isBlocked ?? false;\n\n\t// Initialize support store with defaultOpen when component mounts or prop changes\n\tReact.useEffect(() => {\n\t\tif (defaultOpen !== undefined) {\n\t\t\tinitializeSupportStore({ defaultOpen });\n\t\t}\n\t}, [defaultOpen]);\n\n\tif (!website || isVisitorBlocked) {\n\t\treturn null;\n\t}\n\n\treturn (\n\t\t<>\n\t\t\t<SupportRealtimeProvider>\n\t\t\t\t<SupportTextProvider content={content} locale={locale}>\n\t\t\t\t\t<SupportContent\n\t\t\t\t\t\talign={align}\n\t\t\t\t\t\tclassName={className}\n\t\t\t\t\t\tposition={position}\n\t\t\t\t\t\tpositioning={positioning}\n\t\t\t\t\t/>\n\t\t\t\t</SupportTextProvider>\n\t\t\t</SupportRealtimeProvider>\n\t\t\t<SupportConfig\n\t\t\t\tdefaultMessages={defaultMessages}\n\t\t\t\tquickOptions={quickOptions}\n\t\t\t/>\n\t\t</>\n\t);\n}\n\nexport default Support;\n\nexport type { WebSocketContextValue } from \"./context/websocket\";\nexport { useWebSocket, WebSocketProvider } from \"./context/websocket\";\n// Export the store for direct access if needed\nexport {\n\tuseSupportConfig,\n\tuseSupportNavigation,\n\tuseSupportStore,\n} from \"./store\";\nexport type { SupportLocale, SupportTextContentOverrides } from \"./text\";\nexport { Text, useSupportText } from \"./text\";\n"],"mappings":";;;;;;;;;;;;;;;;;AA8BA,SAAgB,QAA+C,EAC9D,WACA,WAAW,UACX,QAAQ,SACR,cAAc,SACd,cACA,iBACA,aACA,QACA,WAC6C;CAC7C,MAAM,EAAE,YAAY,YAAY;CAChC,MAAM,mBAAmB,SAAS,SAAS,aAAa;AAGxD,OAAM,gBAAgB;AACrB,MAAI,gBAAgB,OACnB,wBAAuB,EAAE,aAAa,CAAC;IAEtC,CAAC,YAAY,CAAC;AAEjB,KAAI,CAAC,WAAW,iBACf,QAAO;AAGR,QACC,4CACC,oBAAC,qCACA,oBAAC;EAA6B;EAAiB;YAC9C,oBAAC;GACO;GACI;GACD;GACG;IACZ;GACmB,GACG,EAC1B,oBAAC;EACiB;EACH;GACb,IACA;;AAIL,sBAAe"}