@cossistant/react 0.0.4 → 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 (319) hide show
  1. package/_virtual/rolldown_runtime.js +19 -0
  2. package/conversation.d.ts +26 -3
  3. package/conversation.d.ts.map +1 -1
  4. package/hooks/index.d.ts +5 -3
  5. package/hooks/index.js +7 -5
  6. package/hooks/private/store/use-conversations-store.d.ts +8 -0
  7. package/hooks/private/store/use-conversations-store.d.ts.map +1 -1
  8. package/hooks/private/store/use-conversations-store.js +8 -0
  9. package/hooks/private/store/use-conversations-store.js.map +1 -1
  10. package/hooks/private/store/use-store-selector.d.ts +4 -0
  11. package/hooks/private/store/use-store-selector.d.ts.map +1 -1
  12. package/hooks/private/store/use-store-selector.js +5 -2
  13. package/hooks/private/store/use-store-selector.js.map +1 -1
  14. package/hooks/private/store/use-website-store.d.ts +4 -0
  15. package/hooks/private/store/use-website-store.d.ts.map +1 -1
  16. package/hooks/private/store/use-website-store.js +6 -3
  17. package/hooks/private/store/use-website-store.js.map +1 -1
  18. package/hooks/private/typing.d.ts +35 -0
  19. package/hooks/private/typing.d.ts.map +1 -0
  20. package/hooks/private/typing.js +49 -0
  21. package/hooks/private/typing.js.map +1 -0
  22. package/hooks/private/use-client-query.d.ts +5 -0
  23. package/hooks/private/use-client-query.d.ts.map +1 -1
  24. package/hooks/private/use-client-query.js +5 -0
  25. package/hooks/private/use-client-query.js.map +1 -1
  26. package/hooks/private/use-grouped-messages.d.ts +10 -4
  27. package/hooks/private/use-grouped-messages.d.ts.map +1 -1
  28. package/hooks/private/use-grouped-messages.js +24 -4
  29. package/hooks/private/use-grouped-messages.js.map +1 -1
  30. package/hooks/private/use-multimodal-input.d.ts.map +1 -1
  31. package/hooks/private/use-rest-client.d.ts.map +1 -1
  32. package/hooks/private/use-visitor-typing-reporter.d.ts +6 -0
  33. package/hooks/private/use-visitor-typing-reporter.d.ts.map +1 -1
  34. package/hooks/private/use-visitor-typing-reporter.js +6 -0
  35. package/hooks/private/use-visitor-typing-reporter.js.map +1 -1
  36. package/hooks/use-composer-refocus.d.ts.map +1 -1
  37. package/hooks/use-conversation-auto-seen.d.ts +9 -0
  38. package/hooks/use-conversation-auto-seen.d.ts.map +1 -1
  39. package/hooks/use-conversation-auto-seen.js +44 -3
  40. package/hooks/use-conversation-auto-seen.js.map +1 -1
  41. package/hooks/use-conversation-history-page.d.ts.map +1 -1
  42. package/hooks/use-conversation-history-page.js +16 -18
  43. package/hooks/use-conversation-history-page.js.map +1 -1
  44. package/hooks/use-conversation-lifecycle.d.ts.map +1 -1
  45. package/hooks/use-conversation-lifecycle.js +2 -4
  46. package/hooks/use-conversation-lifecycle.js.map +1 -1
  47. package/hooks/use-conversation-page.d.ts +6 -0
  48. package/hooks/use-conversation-page.d.ts.map +1 -1
  49. package/hooks/use-conversation-page.js +41 -3
  50. package/hooks/use-conversation-page.js.map +1 -1
  51. package/hooks/use-conversation-preview.d.ts +61 -0
  52. package/hooks/use-conversation-preview.d.ts.map +1 -0
  53. package/hooks/use-conversation-preview.js +173 -0
  54. package/hooks/use-conversation-preview.js.map +1 -0
  55. package/hooks/use-conversation-seen.d.ts +4 -0
  56. package/hooks/use-conversation-seen.d.ts.map +1 -1
  57. package/hooks/use-conversation-seen.js +4 -0
  58. package/hooks/use-conversation-seen.js.map +1 -1
  59. package/hooks/use-conversation-timeline-items.d.ts +4 -0
  60. package/hooks/use-conversation-timeline-items.d.ts.map +1 -1
  61. package/hooks/use-conversation-timeline-items.js +4 -0
  62. package/hooks/use-conversation-timeline-items.js.map +1 -1
  63. package/hooks/use-conversation-timeline.d.ts +32 -0
  64. package/hooks/use-conversation-timeline.d.ts.map +1 -0
  65. package/hooks/use-conversation-timeline.js +41 -0
  66. package/hooks/use-conversation-timeline.js.map +1 -0
  67. package/hooks/use-conversation-typing.d.ts +4 -0
  68. package/hooks/use-conversation-typing.d.ts.map +1 -1
  69. package/hooks/use-conversation-typing.js +4 -0
  70. package/hooks/use-conversation-typing.js.map +1 -1
  71. package/hooks/use-conversation.d.ts +11 -0
  72. package/hooks/use-conversation.d.ts.map +1 -1
  73. package/hooks/use-conversation.js +11 -0
  74. package/hooks/use-conversation.js.map +1 -1
  75. package/hooks/use-conversations.d.ts +12 -0
  76. package/hooks/use-conversations.d.ts.map +1 -1
  77. package/hooks/use-conversations.js +12 -0
  78. package/hooks/use-conversations.js.map +1 -1
  79. package/hooks/use-create-conversation.d.ts +5 -0
  80. package/hooks/use-create-conversation.d.ts.map +1 -1
  81. package/hooks/use-create-conversation.js +12 -9
  82. package/hooks/use-create-conversation.js.map +1 -1
  83. package/hooks/use-home-page.d.ts.map +1 -1
  84. package/hooks/use-home-page.js +6 -4
  85. package/hooks/use-home-page.js.map +1 -1
  86. package/hooks/use-message-composer.d.ts.map +1 -1
  87. package/hooks/use-realtime-support.d.ts.map +1 -1
  88. package/hooks/use-send-message.d.ts +9 -0
  89. package/hooks/use-send-message.d.ts.map +1 -1
  90. package/hooks/use-send-message.js +15 -13
  91. package/hooks/use-send-message.js.map +1 -1
  92. package/hooks/use-visitor.d.ts.map +1 -1
  93. package/hooks/use-visitor.js +28 -30
  94. package/hooks/use-visitor.js.map +1 -1
  95. package/hooks/use-window-visibility-focus.d.ts +4 -0
  96. package/hooks/use-window-visibility-focus.d.ts.map +1 -1
  97. package/hooks/use-window-visibility-focus.js +5 -2
  98. package/hooks/use-window-visibility-focus.js.map +1 -1
  99. package/identify-visitor.d.ts +12 -3
  100. package/identify-visitor.d.ts.map +1 -1
  101. package/identify-visitor.js +58 -9
  102. package/identify-visitor.js.map +1 -1
  103. package/index.d.ts +10 -7
  104. package/index.js +10 -9
  105. package/package.json +11 -16
  106. package/primitives/avatar/avatar.d.ts.map +1 -1
  107. package/primitives/avatar/fallback.d.ts.map +1 -1
  108. package/primitives/avatar/fallback.js +1 -3
  109. package/primitives/avatar/fallback.js.map +1 -1
  110. package/primitives/avatar/image.d.ts.map +1 -1
  111. package/primitives/avatar/index.d.ts +1 -0
  112. package/primitives/bubble.d.ts +2 -0
  113. package/primitives/bubble.d.ts.map +1 -1
  114. package/primitives/bubble.js +8 -2
  115. package/primitives/bubble.js.map +1 -1
  116. package/primitives/button.d.ts.map +1 -1
  117. package/primitives/conversation-timeline.d.ts.map +1 -1
  118. package/primitives/conversation-timeline.js +58 -5
  119. package/primitives/conversation-timeline.js.map +1 -1
  120. package/primitives/index.d.ts +1 -0
  121. package/primitives/index.parts.d.ts +1 -0
  122. package/primitives/multimodal-input.d.ts.map +1 -1
  123. package/primitives/timeline-item-group.d.ts +7 -7
  124. package/primitives/timeline-item-group.d.ts.map +1 -1
  125. package/primitives/timeline-item-group.js.map +1 -1
  126. package/primitives/timeline-item.d.ts +1 -1
  127. package/primitives/timeline-item.d.ts.map +1 -1
  128. package/primitives/timeline-item.js +7 -1
  129. package/primitives/timeline-item.js.map +1 -1
  130. package/primitives/window.d.ts +1 -1
  131. package/primitives/window.d.ts.map +1 -1
  132. package/primitives/window.js +4 -4
  133. package/primitives/window.js.map +1 -1
  134. package/provider.d.ts +23 -43
  135. package/provider.d.ts.map +1 -1
  136. package/provider.js +152 -49
  137. package/provider.js.map +1 -1
  138. package/realtime/event-filter.d.ts +4 -0
  139. package/realtime/event-filter.d.ts.map +1 -1
  140. package/realtime/event-filter.js +4 -0
  141. package/realtime/event-filter.js.map +1 -1
  142. package/realtime/index.js +1 -1
  143. package/realtime/provider.d.ts +7 -2
  144. package/realtime/provider.d.ts.map +1 -1
  145. package/realtime/provider.js +23 -1
  146. package/realtime/provider.js.map +1 -1
  147. package/realtime/seen-store.d.ts +13 -0
  148. package/realtime/seen-store.d.ts.map +1 -1
  149. package/realtime/seen-store.js +14 -2
  150. package/realtime/seen-store.js.map +1 -1
  151. package/realtime/support-provider.d.ts +1 -2
  152. package/realtime/support-provider.d.ts.map +1 -1
  153. package/realtime/support-provider.js +19 -20
  154. package/realtime/support-provider.js.map +1 -1
  155. package/realtime/typing-store.d.ts +18 -0
  156. package/realtime/typing-store.d.ts.map +1 -1
  157. package/realtime/typing-store.js +19 -2
  158. package/realtime/typing-store.js.map +1 -1
  159. package/realtime/use-realtime.d.ts +8 -4
  160. package/realtime/use-realtime.d.ts.map +1 -1
  161. package/realtime/use-realtime.js +4 -0
  162. package/realtime/use-realtime.js.map +1 -1
  163. package/realtime-events.d.ts +17 -3
  164. package/realtime-events.d.ts.map +1 -1
  165. package/schemas.d.ts +7 -1
  166. package/schemas.d.ts.map +1 -1
  167. package/support/components/avatar-stack.d.ts +8 -4
  168. package/support/components/avatar-stack.d.ts.map +1 -1
  169. package/support/components/avatar-stack.js +4 -0
  170. package/support/components/avatar-stack.js.map +1 -1
  171. package/support/components/avatar.d.ts +11 -6
  172. package/support/components/avatar.d.ts.map +1 -1
  173. package/support/components/avatar.js +4 -0
  174. package/support/components/avatar.js.map +1 -1
  175. package/support/components/bubble.d.ts.map +1 -1
  176. package/support/components/bubble.js +29 -6
  177. package/support/components/bubble.js.map +1 -1
  178. package/support/components/button.d.ts +8 -5
  179. package/support/components/button.d.ts.map +1 -1
  180. package/support/components/button.js +5 -1
  181. package/support/components/button.js.map +1 -1
  182. package/support/components/container.d.ts +0 -1
  183. package/support/components/container.d.ts.map +1 -1
  184. package/support/components/container.js +2 -8
  185. package/support/components/container.js.map +1 -1
  186. package/support/components/conversation-button-link.d.ts +8 -21
  187. package/support/components/conversation-button-link.d.ts.map +1 -1
  188. package/support/components/conversation-button-link.js +62 -178
  189. package/support/components/conversation-button-link.js.map +1 -1
  190. package/support/components/conversation-event.d.ts.map +1 -1
  191. package/support/components/conversation-event.js +4 -0
  192. package/support/components/conversation-event.js.map +1 -1
  193. package/support/components/conversation-timeline.d.ts +10 -1
  194. package/support/components/conversation-timeline.d.ts.map +1 -1
  195. package/support/components/conversation-timeline.js +63 -57
  196. package/support/components/conversation-timeline.js.map +1 -1
  197. package/support/components/cossistant-branding.d.ts +5 -2
  198. package/support/components/cossistant-branding.d.ts.map +1 -1
  199. package/support/components/cossistant-branding.js +3 -0
  200. package/support/components/cossistant-branding.js.map +1 -1
  201. package/support/components/header.d.ts.map +1 -1
  202. package/support/components/header.js +2 -2
  203. package/support/components/header.js.map +1 -1
  204. package/support/components/icons.d.ts.map +1 -1
  205. package/support/components/multimodal-input.d.ts.map +1 -1
  206. package/support/components/multimodal-input.js +5 -24
  207. package/support/components/multimodal-input.js.map +1 -1
  208. package/support/components/navigation-tab.d.ts +7 -2
  209. package/support/components/navigation-tab.d.ts.map +1 -1
  210. package/support/components/navigation-tab.js +4 -0
  211. package/support/components/navigation-tab.js.map +1 -1
  212. package/support/components/support-content.d.ts +1 -1
  213. package/support/components/support-content.d.ts.map +1 -1
  214. package/support/components/support-content.js +7 -10
  215. package/support/components/support-content.js.map +1 -1
  216. package/support/components/text-effect.d.ts +5 -2
  217. package/support/components/text-effect.d.ts.map +1 -1
  218. package/support/components/text-effect.js +4 -0
  219. package/support/components/text-effect.js.map +1 -1
  220. package/support/components/timeline-identification-tool.d.ts +7 -0
  221. package/support/components/timeline-identification-tool.d.ts.map +1 -0
  222. package/support/components/timeline-identification-tool.js +139 -0
  223. package/support/components/timeline-identification-tool.js.map +1 -0
  224. package/support/components/timeline-message-group.d.ts +2 -1
  225. package/support/components/timeline-message-group.d.ts.map +1 -1
  226. package/support/components/timeline-message-group.js +4 -19
  227. package/support/components/timeline-message-group.js.map +1 -1
  228. package/support/components/timeline-message-item.d.ts +6 -2
  229. package/support/components/timeline-message-item.d.ts.map +1 -1
  230. package/support/components/timeline-message-item.js +8 -4
  231. package/support/components/timeline-message-item.js.map +1 -1
  232. package/support/components/typing-indicator.d.ts +5 -2
  233. package/support/components/typing-indicator.d.ts.map +1 -1
  234. package/support/components/typing-indicator.js +4 -4
  235. package/support/components/typing-indicator.js.map +1 -1
  236. package/support/components/watermark.d.ts.map +1 -1
  237. package/support/context/websocket.d.ts +8 -0
  238. package/support/context/websocket.d.ts.map +1 -1
  239. package/support/context/websocket.js +12 -6
  240. package/support/context/websocket.js.map +1 -1
  241. package/support/index.d.ts +8 -8
  242. package/support/index.d.ts.map +1 -1
  243. package/support/index.js +18 -18
  244. package/support/index.js.map +1 -1
  245. package/support/pages/conversation-history.js +46 -54
  246. package/support/pages/conversation-history.js.map +1 -1
  247. package/support/pages/conversation.d.ts +3 -6
  248. package/support/pages/conversation.d.ts.map +1 -1
  249. package/support/pages/conversation.js +19 -9
  250. package/support/pages/conversation.js.map +1 -1
  251. package/support/pages/home.d.ts +2 -2
  252. package/support/pages/home.d.ts.map +1 -1
  253. package/support/pages/home.js +64 -77
  254. package/support/pages/home.js.map +1 -1
  255. package/support/store/support-store.d.ts +18 -2
  256. package/support/store/support-store.d.ts.map +1 -1
  257. package/support/store/support-store.js +20 -5
  258. package/support/store/support-store.js.map +1 -1
  259. package/support/{support-CMoDLQoC.css → support-Ck4jy29i.css} +1 -2
  260. package/support/support-Ck4jy29i.css.map +1 -0
  261. package/support/text/index.d.ts +15 -2
  262. package/support/text/index.d.ts.map +1 -1
  263. package/support/text/index.js +15 -2
  264. package/support/text/index.js.map +1 -1
  265. package/support/text/locales/en.js +22 -4
  266. package/support/text/locales/en.js.map +1 -1
  267. package/support/text/locales/es.js +18 -0
  268. package/support/text/locales/es.js.map +1 -1
  269. package/support/text/locales/fr.js +18 -0
  270. package/support/text/locales/fr.js.map +1 -1
  271. package/support/text/locales/keys.d.ts +69 -9
  272. package/support/text/locales/keys.d.ts.map +1 -1
  273. package/support/text/locales/keys.js +18 -0
  274. package/support/text/locales/keys.js.map +1 -1
  275. package/support/text/runtime.d.ts +21 -0
  276. package/support/text/runtime.d.ts.map +1 -1
  277. package/support/text/runtime.js +21 -0
  278. package/support/text/runtime.js.map +1 -1
  279. package/support/utils/index.d.ts +4 -0
  280. package/support/utils/index.d.ts.map +1 -1
  281. package/support/utils/index.js +4 -1
  282. package/support/utils/index.js.map +1 -1
  283. package/support/utils/time.d.ts +3 -0
  284. package/support/utils/time.d.ts.map +1 -1
  285. package/support/utils/time.js +3 -0
  286. package/support/utils/time.js.map +1 -1
  287. package/support-config.d.ts +2 -1
  288. package/support-config.d.ts.map +1 -1
  289. package/support-config.js.map +1 -1
  290. package/support.css +2 -2
  291. package/timeline-item.d.ts +10 -0
  292. package/timeline-item.d.ts.map +1 -1
  293. package/utils/conversation.d.ts +7 -0
  294. package/utils/conversation.d.ts.map +1 -0
  295. package/utils/conversation.js +18 -0
  296. package/utils/conversation.js.map +1 -0
  297. package/utils/id.d.ts +3 -0
  298. package/utils/id.d.ts.map +1 -1
  299. package/utils/id.js +3 -0
  300. package/utils/id.js.map +1 -1
  301. package/utils/index.d.ts +2 -1
  302. package/utils/index.js +2 -1
  303. package/utils/metadata-hash.d.ts +12 -0
  304. package/utils/metadata-hash.d.ts.map +1 -0
  305. package/utils/metadata-hash.js +26 -0
  306. package/utils/metadata-hash.js.map +1 -0
  307. package/utils/text.d.ts +3 -0
  308. package/utils/text.d.ts.map +1 -1
  309. package/utils/text.js +3 -0
  310. package/utils/text.js.map +1 -1
  311. package/utils/use-render-element.d.ts +3 -0
  312. package/utils/use-render-element.d.ts.map +1 -1
  313. package/utils/use-render-element.js +3 -0
  314. package/utils/use-render-element.js.map +1 -1
  315. package/support/context/config.d.ts +0 -32
  316. package/support/context/config.d.ts.map +0 -1
  317. package/support/context/config.js +0 -27
  318. package/support/context/config.js.map +0 -1
  319. package/support/support-CMoDLQoC.css.map +0 -1
@@ -5,14 +5,27 @@ import { SeenActorType, SeenState } from "@cossistant/core";
5
5
  //#region src/realtime/seen-store.d.ts
6
6
  type Selector<T> = (state: SeenState) => T;
7
7
  type EqualityChecker<T> = (previous: T, next: T) => boolean;
8
+ /**
9
+ * Public hook for subscribing to slices of the shared "seen" store.
10
+ */
8
11
  declare function useSeenStore<TSelected>(selector: Selector<TSelected>, isEqual?: EqualityChecker<TSelected>): TSelected;
12
+ /**
13
+ * Seeds the seen store with initial data, typically from the REST API or SSR.
14
+ */
9
15
  declare function hydrateConversationSeen(conversationId: string, entries: ConversationSeen[]): void;
16
+ /**
17
+ * Inserts or updates a seen entry for the provided actor.
18
+ */
10
19
  declare function upsertConversationSeen(options: {
11
20
  conversationId: string;
12
21
  actorType: SeenActorType;
13
22
  actorId: string;
14
23
  lastSeenAt: Date;
15
24
  }): void;
25
+ /**
26
+ * Applies realtime `conversationSeen` events to the store while optionally
27
+ * ignoring the local visitor/user.
28
+ */
16
29
  declare function applyConversationSeenEvent(event: RealtimeEvent<"conversationSeen">, options?: {
17
30
  ignoreVisitorId?: string | null;
18
31
  ignoreUserId?: string | null;
@@ -1 +1 @@
1
- {"version":3,"file":"seen-store.d.ts","names":[],"sources":["../../src/realtime/seen-store.ts"],"sourcesContent":[],"mappings":";;;;;KAeK,sBAAsB,cAAc;KAEpC,gCAAgC,SAAS;AAFzC,iBAiCW,YAjCH,CAAA,SAAA,CAAA,CAAA,QAAA,EAkCF,QAlCE,CAkCO,SAlCP,CAAA,EAAA,OAAA,CAAA,EAmCF,eAnCE,CAmCc,SAnCd,CAAA,CAAA,EAoCV,SApCU;AAAA,iBAwCG,uBAAA,CAxCH,cAAA,EAAA,MAAA,EAAA,OAAA,EA0CH,gBA1CG,EAAA,CAAA,EAAA,IAAA;AAAc,iBA+CX,sBAAA,CA/CW,OAAA,EAAA;gBAAc,EAAA,MAAA;EAAC,SAAA,EAiD9B,aAjD8B;EAErC,OAAA,EAAA,MAAA;EAAe,UAAA,EAiDP,IAjDO;QAAiB;AAAS,iBAyD9B,0BAAA,CAzD8B,KAAA,EA0DtC,aA1DsC,CAAA,kBAAA,CAAA,EAAA,QAAA,EAAA;EAAC,eAAA,CAAA,EAAA,MAAA,GAAA,IAAA;EA+B/B,YAAA,CAAA,EAAY,MAAA,GAAA,IAAA;EAAA,eAAA,CAAA,EAAA,MAAA,GAAA,IAAA;QACR"}
1
+ {"version":3,"file":"seen-store.d.ts","names":[],"sources":["../../src/realtime/seen-store.ts"],"sourcesContent":[],"mappings":";;;;;KAeK,sBAAsB,cAAc;KAEpC,gCAAgC,SAAS;AAPoB;AAKxB;AAoC1C;AACoB,iBADJ,YACI,CAAA,SAAA,CAAA,CAAA,QAAA,EAAT,QAAS,CAAA,SAAA,CAAA,EAAA,OAAA,CAAA,EACT,eADS,CACO,SADP,CAAA,CAAA,EAEjB,SAFiB;;;;AAEjB,iBAOa,uBAAA,CAPb,cAAA,EAAA,MAAA,EAAA,OAAA,EASO,gBATP,EAAA,CAAA,EAAA,IAAA;;AAOH;AAUA;AAgBgB,iBAhBA,sBAAA,CAiBR,OAAA,EAAA;;aAfI;;cAEC;;;;;;iBAYG,0BAAA,QACR"}
@@ -8,23 +8,35 @@ function useSelector(selector, isEqual = Object.is) {
8
8
  const subscribe = (onStoreChange) => store.subscribe(() => {
9
9
  onStoreChange();
10
10
  });
11
- const snapshot = useSyncExternalStore(subscribe, store.getState, store.getState);
12
- const selected = selector(snapshot);
11
+ const selected = selector(useSyncExternalStore(subscribe, store.getState, store.getState));
13
12
  if (selectionRef.current === void 0 || !isEqual(selectionRef.current, selected)) selectionRef.current = selected;
14
13
  return selectionRef.current;
15
14
  }
15
+ /**
16
+ * Public hook for subscribing to slices of the shared "seen" store.
17
+ */
16
18
  function useSeenStore(selector, isEqual) {
17
19
  return useSelector(selector, isEqual);
18
20
  }
21
+ /**
22
+ * Seeds the seen store with initial data, typically from the REST API or SSR.
23
+ */
19
24
  function hydrateConversationSeen(conversationId, entries) {
20
25
  hydrateConversationSeen$1(store, conversationId, entries);
21
26
  }
27
+ /**
28
+ * Inserts or updates a seen entry for the provided actor.
29
+ */
22
30
  function upsertConversationSeen(options) {
23
31
  upsertConversationSeen$1(store, {
24
32
  ...options,
25
33
  lastSeenAt: options.lastSeenAt.toISOString()
26
34
  });
27
35
  }
36
+ /**
37
+ * Applies realtime `conversationSeen` events to the store while optionally
38
+ * ignoring the local visitor/user.
39
+ */
28
40
  function applyConversationSeenEvent(event, options) {
29
41
  applyConversationSeenEvent$1(store, event, options);
30
42
  }
@@ -1 +1 @@
1
- {"version":3,"file":"seen-store.js","names":[],"sources":["../../src/realtime/seen-store.ts"],"sourcesContent":["import {\n\tapplyConversationSeenEvent as applyEvent,\n\tcreateSeenStore,\n\thydrateConversationSeen as hydrateStore,\n\ttype SeenActorType,\n\ttype SeenEntry,\n\ttype SeenState,\n\tupsertConversationSeen as upsertStore,\n} from \"@cossistant/core\";\nimport type { RealtimeEvent } from \"@cossistant/types/realtime-events\";\nimport type { ConversationSeen } from \"@cossistant/types/schemas\";\nimport { useRef, useSyncExternalStore } from \"react\";\n\nconst store = createSeenStore();\n\ntype Selector<T> = (state: SeenState) => T;\n\ntype EqualityChecker<T> = (previous: T, next: T) => boolean;\n\nfunction useSelector<TSelected>(\n\tselector: Selector<TSelected>,\n\tisEqual: EqualityChecker<TSelected> = Object.is\n): TSelected {\n\tconst selectionRef = useRef<TSelected>(undefined);\n\n\tconst subscribe = (onStoreChange: () => void) =>\n\t\tstore.subscribe(() => {\n\t\t\tonStoreChange();\n\t\t});\n\n\tconst snapshot = useSyncExternalStore(\n\t\tsubscribe,\n\t\tstore.getState,\n\t\tstore.getState\n\t);\n\n\tconst selected = selector(snapshot);\n\n\tif (\n\t\tselectionRef.current === undefined ||\n\t\t!isEqual(selectionRef.current, selected)\n\t) {\n\t\tselectionRef.current = selected;\n\t}\n\n\treturn selectionRef.current as TSelected;\n}\n\nexport function useSeenStore<TSelected>(\n\tselector: Selector<TSelected>,\n\tisEqual?: EqualityChecker<TSelected>\n): TSelected {\n\treturn useSelector(selector, isEqual);\n}\n\nexport function hydrateConversationSeen(\n\tconversationId: string,\n\tentries: ConversationSeen[]\n) {\n\thydrateStore(store, conversationId, entries);\n}\n\nexport function upsertConversationSeen(options: {\n\tconversationId: string;\n\tactorType: SeenActorType;\n\tactorId: string;\n\tlastSeenAt: Date;\n}) {\n\tupsertStore(store, {\n\t\t...options,\n\t\tlastSeenAt: options.lastSeenAt.toISOString(),\n\t});\n}\n\nexport function applyConversationSeenEvent(\n\tevent: RealtimeEvent<\"conversationSeen\">,\n\toptions?: {\n\t\tignoreVisitorId?: string | null;\n\t\tignoreUserId?: string | null;\n\t\tignoreAiAgentId?: string | null;\n\t}\n) {\n\tapplyEvent(store, event, options);\n}\n"],"mappings":";;;;AAaA,MAAM,QAAQ,iBAAiB;AAM/B,SAAS,YACR,UACA,UAAsC,OAAO,IACjC;CACZ,MAAM,eAAe,OAAkB,OAAU;CAEjD,MAAM,aAAa,kBAClB,MAAM,gBAAgB;AACrB,iBAAe;GACd;CAEH,MAAM,WAAW,qBAChB,WACA,MAAM,UACN,MAAM,SACN;CAED,MAAM,WAAW,SAAS,SAAS;AAEnC,KACC,aAAa,YAAY,UACzB,CAAC,QAAQ,aAAa,SAAS,SAAS,CAExC,cAAa,UAAU;AAGxB,QAAO,aAAa;;AAGrB,SAAgB,aACf,UACA,SACY;AACZ,QAAO,YAAY,UAAU,QAAQ;;AAGtC,SAAgB,wBACf,gBACA,SACC;AACD,2BAAa,OAAO,gBAAgB,QAAQ;;AAG7C,SAAgB,uBAAuB,SAKpC;AACF,0BAAY,OAAO;EAClB,GAAG;EACH,YAAY,QAAQ,WAAW,aAAa;EAC5C,CAAC;;AAGH,SAAgB,2BACf,OACA,SAKC;AACD,8BAAW,OAAO,OAAO,QAAQ"}
1
+ {"version":3,"file":"seen-store.js","names":[],"sources":["../../src/realtime/seen-store.ts"],"sourcesContent":["import {\n\tapplyConversationSeenEvent as applyEvent,\n\tcreateSeenStore,\n\thydrateConversationSeen as hydrateStore,\n\ttype SeenActorType,\n\ttype SeenEntry,\n\ttype SeenState,\n\tupsertConversationSeen as upsertStore,\n} from \"@cossistant/core\";\nimport type { RealtimeEvent } from \"@cossistant/types/realtime-events\";\nimport type { ConversationSeen } from \"@cossistant/types/schemas\";\nimport { useRef, useSyncExternalStore } from \"react\";\n\nconst store = createSeenStore();\n\ntype Selector<T> = (state: SeenState) => T;\n\ntype EqualityChecker<T> = (previous: T, next: T) => boolean;\n\nfunction useSelector<TSelected>(\n\tselector: Selector<TSelected>,\n\tisEqual: EqualityChecker<TSelected> = Object.is\n): TSelected {\n\tconst selectionRef = useRef<TSelected>(undefined);\n\n\tconst subscribe = (onStoreChange: () => void) =>\n\t\tstore.subscribe(() => {\n\t\t\tonStoreChange();\n\t\t});\n\n\tconst snapshot = useSyncExternalStore(\n\t\tsubscribe,\n\t\tstore.getState,\n\t\tstore.getState\n\t);\n\n\tconst selected = selector(snapshot);\n\n\tif (\n\t\tselectionRef.current === undefined ||\n\t\t!isEqual(selectionRef.current, selected)\n\t) {\n\t\tselectionRef.current = selected;\n\t}\n\n\treturn selectionRef.current as TSelected;\n}\n\n/**\n * Public hook for subscribing to slices of the shared \"seen\" store.\n */\nexport function useSeenStore<TSelected>(\n\tselector: Selector<TSelected>,\n\tisEqual?: EqualityChecker<TSelected>\n): TSelected {\n\treturn useSelector(selector, isEqual);\n}\n\n/**\n * Seeds the seen store with initial data, typically from the REST API or SSR.\n */\nexport function hydrateConversationSeen(\n\tconversationId: string,\n\tentries: ConversationSeen[]\n) {\n\thydrateStore(store, conversationId, entries);\n}\n\n/**\n * Inserts or updates a seen entry for the provided actor.\n */\nexport function upsertConversationSeen(options: {\n\tconversationId: string;\n\tactorType: SeenActorType;\n\tactorId: string;\n\tlastSeenAt: Date;\n}) {\n\tupsertStore(store, {\n\t\t...options,\n\t\tlastSeenAt: options.lastSeenAt.toISOString(),\n\t});\n}\n\n/**\n * Applies realtime `conversationSeen` events to the store while optionally\n * ignoring the local visitor/user.\n */\nexport function applyConversationSeenEvent(\n\tevent: RealtimeEvent<\"conversationSeen\">,\n\toptions?: {\n\t\tignoreVisitorId?: string | null;\n\t\tignoreUserId?: string | null;\n\t\tignoreAiAgentId?: string | null;\n\t}\n) {\n\tapplyEvent(store, event, options);\n}\n"],"mappings":";;;;AAaA,MAAM,QAAQ,iBAAiB;AAM/B,SAAS,YACR,UACA,UAAsC,OAAO,IACjC;CACZ,MAAM,eAAe,OAAkB,OAAU;CAEjD,MAAM,aAAa,kBAClB,MAAM,gBAAgB;AACrB,iBAAe;GACd;CAQH,MAAM,WAAW,SANA,qBAChB,WACA,MAAM,UACN,MAAM,SACN,CAEkC;AAEnC,KACC,aAAa,YAAY,UACzB,CAAC,QAAQ,aAAa,SAAS,SAAS,CAExC,cAAa,UAAU;AAGxB,QAAO,aAAa;;;;;AAMrB,SAAgB,aACf,UACA,SACY;AACZ,QAAO,YAAY,UAAU,QAAQ;;;;;AAMtC,SAAgB,wBACf,gBACA,SACC;AACD,2BAAa,OAAO,gBAAgB,QAAQ;;;;;AAM7C,SAAgB,uBAAuB,SAKpC;AACF,0BAAY,OAAO;EAClB,GAAG;EACH,YAAY,QAAQ,WAAW,aAAa;EAC5C,CAAC;;;;;;AAOH,SAAgB,2BACf,OACA,SAKC;AACD,8BAAW,OAAO,OAAO,QAAQ"}
@@ -1,5 +1,4 @@
1
1
  import React from "react";
2
- import * as react_jsx_runtime2 from "react/jsx-runtime";
3
2
 
4
3
  //#region src/realtime/support-provider.d.ts
5
4
  type SupportRealtimeProviderProps = {
@@ -11,7 +10,7 @@ type SupportRealtimeProviderProps = {
11
10
  */
12
11
  declare function SupportRealtimeProvider({
13
12
  children
14
- }: SupportRealtimeProviderProps): react_jsx_runtime2.JSX.Element;
13
+ }: SupportRealtimeProviderProps): React.ReactElement;
15
14
  //#endregion
16
15
  export { SupportRealtimeProvider };
17
16
  //# sourceMappingURL=support-provider.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"support-provider.d.ts","names":[],"sources":["../../src/realtime/support-provider.tsx"],"sourcesContent":[],"mappings":";;;;KAkBK,4BAAA;YACM,KAAA,CAAM;;AAjBc;AAwB/B;;;AAEG,iBAFa,uBAAA,CAEb;EAAA;AAAA,CAAA,EAAA,4BAAA,CAAA,EAA4B,kBAAA,CAAA,GAAA,CAAA,OAA5B"}
1
+ {"version":3,"file":"support-provider.d.ts","names":[],"sources":["../../src/realtime/support-provider.tsx"],"sourcesContent":[],"mappings":";;;KAkBK,4BAAA;YACM,KAAA,CAAM;AAjBc,CAAA;AAwB/B;;;;AAEoD,iBAFpC,uBAAA,CAEoC;EAAA;AAAA,CAAA,EAAjD,4BAAiD,CAAA,EAAlB,KAAA,CAAM,YAAY"}
@@ -21,28 +21,27 @@ function SupportRealtimeProvider({ children }) {
21
21
  visitor?.id,
22
22
  client
23
23
  ]);
24
- const events = useMemo(() => ({
25
- timelineItemCreated: (_data, { event, context }) => {
26
- if (context.websiteId && event.payload.websiteId !== context.websiteId) return;
27
- clearTypingFromTimelineItem(event);
28
- context.client.handleRealtimeEvent(event);
29
- },
30
- conversationSeen: (_data, { event, context }) => {
31
- if (context.websiteId && event.payload.websiteId !== context.websiteId) return;
32
- applyConversationSeenEvent(event);
33
- },
34
- conversationTyping: (_data, { event, context }) => {
35
- if (context.websiteId && event.payload.websiteId !== context.websiteId) return;
36
- applyConversationTypingEvent(event, { ignoreVisitorId: context.visitorId });
37
- },
38
- conversationEventCreated: (_data, { event, context }) => {
39
- if (context.websiteId && event.payload.websiteId !== context.websiteId) return;
40
- context.client.handleRealtimeEvent(event);
41
- }
42
- }), []);
43
24
  useRealtime({
44
25
  context: realtimeContext,
45
- events,
26
+ events: useMemo(() => ({
27
+ timelineItemCreated: (_data, { event, context }) => {
28
+ if (context.websiteId && event.payload.websiteId !== context.websiteId) return;
29
+ clearTypingFromTimelineItem(event);
30
+ context.client.handleRealtimeEvent(event);
31
+ },
32
+ conversationSeen: (_data, { event, context }) => {
33
+ if (context.websiteId && event.payload.websiteId !== context.websiteId) return;
34
+ applyConversationSeenEvent(event);
35
+ },
36
+ conversationTyping: (_data, { event, context }) => {
37
+ if (context.websiteId && event.payload.websiteId !== context.websiteId) return;
38
+ applyConversationTypingEvent(event, { ignoreVisitorId: context.visitorId });
39
+ },
40
+ conversationEventCreated: (_data, { event, context }) => {
41
+ if (context.websiteId && event.payload.websiteId !== context.websiteId) return;
42
+ context.client.handleRealtimeEvent(event);
43
+ }
44
+ }), []),
46
45
  websiteId: realtimeContext.websiteId,
47
46
  visitorId: realtimeContext.visitorId
48
47
  });
@@ -1 +1 @@
1
- {"version":3,"file":"support-provider.js","names":[],"sources":["../../src/realtime/support-provider.tsx"],"sourcesContent":["import type { CossistantClient } from \"@cossistant/core\";\nimport type { RealtimeEvent } from \"@cossistant/types/realtime-events\";\nimport type React from \"react\";\nimport { useMemo } from \"react\";\nimport { useSupport } from \"../provider\";\nimport { applyConversationSeenEvent } from \"./seen-store\";\nimport {\n\tapplyConversationTypingEvent,\n\tclearTypingFromTimelineItem,\n} from \"./typing-store\";\nimport { useRealtime } from \"./use-realtime\";\n\ntype SupportRealtimeContext = {\n\twebsiteId: string | null;\n\tvisitorId: string | null;\n\tclient: CossistantClient;\n};\n\ntype SupportRealtimeProviderProps = {\n\tchildren: React.ReactNode;\n};\n\n/**\n * Bridges websocket events into the core client stores so support hooks stay\n * in sync without forcing refetches.\n */\nexport function SupportRealtimeProvider({\n\tchildren,\n}: SupportRealtimeProviderProps) {\n\tconst { website, client, visitor } = useSupport();\n\n\tconst realtimeContext = useMemo<SupportRealtimeContext>(\n\t\t() => ({\n\t\t\twebsiteId: website?.id ?? null,\n\t\t\tvisitorId: visitor?.id ?? null,\n\t\t\tclient,\n\t\t}),\n\t\t[website?.id, visitor?.id, client]\n\t);\n\n\tconst events = useMemo(\n\t\t() => ({\n\t\t\ttimelineItemCreated: (\n\t\t\t\t_data: unknown,\n\t\t\t\t{\n\t\t\t\t\tevent,\n\t\t\t\t\tcontext,\n\t\t\t\t}: {\n\t\t\t\t\tevent: RealtimeEvent<\"timelineItemCreated\">;\n\t\t\t\t\tcontext: SupportRealtimeContext;\n\t\t\t\t}\n\t\t\t) => {\n\t\t\t\tif (\n\t\t\t\t\tcontext.websiteId &&\n\t\t\t\t\tevent.payload.websiteId !== context.websiteId\n\t\t\t\t) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Clear typing state when a timeline item is created\n\t\t\t\tclearTypingFromTimelineItem(event);\n\n\t\t\t\tcontext.client.handleRealtimeEvent(event);\n\t\t\t},\n\t\t\tconversationSeen: (\n\t\t\t\t_data: unknown,\n\t\t\t\t{\n\t\t\t\t\tevent,\n\t\t\t\t\tcontext,\n\t\t\t\t}: {\n\t\t\t\t\tevent: RealtimeEvent<\"conversationSeen\">;\n\t\t\t\t\tcontext: SupportRealtimeContext;\n\t\t\t\t}\n\t\t\t) => {\n\t\t\t\tif (\n\t\t\t\t\tcontext.websiteId &&\n\t\t\t\t\tevent.payload.websiteId !== context.websiteId\n\t\t\t\t) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Update the seen store so the UI reflects who has seen messages\n\t\t\t\tapplyConversationSeenEvent(event);\n\t\t\t},\n\t\t\tconversationTyping: (\n\t\t\t\t_data: unknown,\n\t\t\t\t{\n\t\t\t\t\tevent,\n\t\t\t\t\tcontext,\n\t\t\t\t}: {\n\t\t\t\t\tevent: RealtimeEvent<\"conversationTyping\">;\n\t\t\t\t\tcontext: SupportRealtimeContext;\n\t\t\t\t}\n\t\t\t) => {\n\t\t\t\tif (\n\t\t\t\t\tcontext.websiteId &&\n\t\t\t\t\tevent.payload.websiteId !== context.websiteId\n\t\t\t\t) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Update typing store, but ignore events from the current visitor (their own typing)\n\t\t\t\t// Note: We use context.visitorId which is fresh from the context object\n\t\t\t\tapplyConversationTypingEvent(event, {\n\t\t\t\t\tignoreVisitorId: context.visitorId,\n\t\t\t\t});\n\t\t\t},\n\t\t\tconversationEventCreated: (\n\t\t\t\t_data: unknown,\n\t\t\t\t{\n\t\t\t\t\tevent,\n\t\t\t\t\tcontext,\n\t\t\t\t}: {\n\t\t\t\t\tevent: RealtimeEvent<\"conversationEventCreated\">;\n\t\t\t\t\tcontext: SupportRealtimeContext;\n\t\t\t\t}\n\t\t\t) => {\n\t\t\t\tif (\n\t\t\t\t\tcontext.websiteId &&\n\t\t\t\t\tevent.payload.websiteId !== context.websiteId\n\t\t\t\t) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tcontext.client.handleRealtimeEvent(event);\n\t\t\t},\n\t\t}),\n\t\t// Empty dependencies is fine here since we use the context parameter\n\t\t// which always has fresh data from the memoized realtimeContext\n\t\t[]\n\t);\n\n\tuseRealtime<SupportRealtimeContext>({\n\t\tcontext: realtimeContext,\n\t\tevents,\n\t\twebsiteId: realtimeContext.websiteId,\n\t\tvisitorId: realtimeContext.visitorId,\n\t});\n\n\treturn <>{children}</>;\n}\n"],"mappings":";;;;;;;;;;;;AA0BA,SAAgB,wBAAwB,EACvC,YACgC;CAChC,MAAM,EAAE,SAAS,QAAQ,YAAY,YAAY;CAEjD,MAAM,kBAAkB,eAChB;EACN,WAAW,SAAS,MAAM;EAC1B,WAAW,SAAS,MAAM;EAC1B;EACA,GACD;EAAC,SAAS;EAAI,SAAS;EAAI;EAAO,CAClC;CAED,MAAM,SAAS,eACP;EACN,sBACC,OACA,EACC,OACA,cAKG;AACJ,OACC,QAAQ,aACR,MAAM,QAAQ,cAAc,QAAQ,UAEpC;AAID,+BAA4B,MAAM;AAElC,WAAQ,OAAO,oBAAoB,MAAM;;EAE1C,mBACC,OACA,EACC,OACA,cAKG;AACJ,OACC,QAAQ,aACR,MAAM,QAAQ,cAAc,QAAQ,UAEpC;AAID,8BAA2B,MAAM;;EAElC,qBACC,OACA,EACC,OACA,cAKG;AACJ,OACC,QAAQ,aACR,MAAM,QAAQ,cAAc,QAAQ,UAEpC;AAKD,gCAA6B,OAAO,EACnC,iBAAiB,QAAQ,WACzB,CAAC;;EAEH,2BACC,OACA,EACC,OACA,cAKG;AACJ,OACC,QAAQ,aACR,MAAM,QAAQ,cAAc,QAAQ,UAEpC;AAGD,WAAQ,OAAO,oBAAoB,MAAM;;EAE1C,GAGD,EAAE,CACF;AAED,aAAoC;EACnC,SAAS;EACT;EACA,WAAW,gBAAgB;EAC3B,WAAW,gBAAgB;EAC3B,CAAC;AAEF,QAAO,gCAAG,WAAY"}
1
+ {"version":3,"file":"support-provider.js","names":[],"sources":["../../src/realtime/support-provider.tsx"],"sourcesContent":["import type { CossistantClient } from \"@cossistant/core\";\nimport type { RealtimeEvent } from \"@cossistant/types/realtime-events\";\nimport type React from \"react\";\nimport { useMemo } from \"react\";\nimport { useSupport } from \"../provider\";\nimport { applyConversationSeenEvent } from \"./seen-store\";\nimport {\n\tapplyConversationTypingEvent,\n\tclearTypingFromTimelineItem,\n} from \"./typing-store\";\nimport { useRealtime } from \"./use-realtime\";\n\ntype SupportRealtimeContext = {\n\twebsiteId: string | null;\n\tvisitorId: string | null;\n\tclient: CossistantClient;\n};\n\ntype SupportRealtimeProviderProps = {\n\tchildren: React.ReactNode;\n};\n\n/**\n * Bridges websocket events into the core client stores so support hooks stay\n * in sync without forcing refetches.\n */\nexport function SupportRealtimeProvider({\n\tchildren,\n}: SupportRealtimeProviderProps): React.ReactElement {\n\tconst { website, client, visitor } = useSupport();\n\n\tconst realtimeContext = useMemo<SupportRealtimeContext>(\n\t\t() => ({\n\t\t\twebsiteId: website?.id ?? null,\n\t\t\tvisitorId: visitor?.id ?? null,\n\t\t\tclient,\n\t\t}),\n\t\t[website?.id, visitor?.id, client]\n\t);\n\n\tconst events = useMemo(\n\t\t() => ({\n\t\t\ttimelineItemCreated: (\n\t\t\t\t_data: unknown,\n\t\t\t\t{\n\t\t\t\t\tevent,\n\t\t\t\t\tcontext,\n\t\t\t\t}: {\n\t\t\t\t\tevent: RealtimeEvent<\"timelineItemCreated\">;\n\t\t\t\t\tcontext: SupportRealtimeContext;\n\t\t\t\t}\n\t\t\t) => {\n\t\t\t\tif (\n\t\t\t\t\tcontext.websiteId &&\n\t\t\t\t\tevent.payload.websiteId !== context.websiteId\n\t\t\t\t) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Clear typing state when a timeline item is created\n\t\t\t\tclearTypingFromTimelineItem(event);\n\n\t\t\t\tcontext.client.handleRealtimeEvent(event);\n\t\t\t},\n\t\t\tconversationSeen: (\n\t\t\t\t_data: unknown,\n\t\t\t\t{\n\t\t\t\t\tevent,\n\t\t\t\t\tcontext,\n\t\t\t\t}: {\n\t\t\t\t\tevent: RealtimeEvent<\"conversationSeen\">;\n\t\t\t\t\tcontext: SupportRealtimeContext;\n\t\t\t\t}\n\t\t\t) => {\n\t\t\t\tif (\n\t\t\t\t\tcontext.websiteId &&\n\t\t\t\t\tevent.payload.websiteId !== context.websiteId\n\t\t\t\t) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Update the seen store so the UI reflects who has seen messages\n\t\t\t\tapplyConversationSeenEvent(event);\n\t\t\t},\n\t\t\tconversationTyping: (\n\t\t\t\t_data: unknown,\n\t\t\t\t{\n\t\t\t\t\tevent,\n\t\t\t\t\tcontext,\n\t\t\t\t}: {\n\t\t\t\t\tevent: RealtimeEvent<\"conversationTyping\">;\n\t\t\t\t\tcontext: SupportRealtimeContext;\n\t\t\t\t}\n\t\t\t) => {\n\t\t\t\tif (\n\t\t\t\t\tcontext.websiteId &&\n\t\t\t\t\tevent.payload.websiteId !== context.websiteId\n\t\t\t\t) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Update typing store, but ignore events from the current visitor (their own typing)\n\t\t\t\t// Note: We use context.visitorId which is fresh from the context object\n\t\t\t\tapplyConversationTypingEvent(event, {\n\t\t\t\t\tignoreVisitorId: context.visitorId,\n\t\t\t\t});\n\t\t\t},\n\t\t\tconversationEventCreated: (\n\t\t\t\t_data: unknown,\n\t\t\t\t{\n\t\t\t\t\tevent,\n\t\t\t\t\tcontext,\n\t\t\t\t}: {\n\t\t\t\t\tevent: RealtimeEvent<\"conversationEventCreated\">;\n\t\t\t\t\tcontext: SupportRealtimeContext;\n\t\t\t\t}\n\t\t\t) => {\n\t\t\t\tif (\n\t\t\t\t\tcontext.websiteId &&\n\t\t\t\t\tevent.payload.websiteId !== context.websiteId\n\t\t\t\t) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tcontext.client.handleRealtimeEvent(event);\n\t\t\t},\n\t\t}),\n\t\t// Empty dependencies is fine here since we use the context parameter\n\t\t// which always has fresh data from the memoized realtimeContext\n\t\t[]\n\t);\n\n\tuseRealtime<SupportRealtimeContext>({\n\t\tcontext: realtimeContext,\n\t\tevents,\n\t\twebsiteId: realtimeContext.websiteId,\n\t\tvisitorId: realtimeContext.visitorId,\n\t});\n\n\treturn <>{children}</>;\n}\n"],"mappings":";;;;;;;;;;;;AA0BA,SAAgB,wBAAwB,EACvC,YACoD;CACpD,MAAM,EAAE,SAAS,QAAQ,YAAY,YAAY;CAEjD,MAAM,kBAAkB,eAChB;EACN,WAAW,SAAS,MAAM;EAC1B,WAAW,SAAS,MAAM;EAC1B;EACA,GACD;EAAC,SAAS;EAAI,SAAS;EAAI;EAAO,CAClC;AA8FD,aAAoC;EACnC,SAAS;EACT,QA9Fc,eACP;GACN,sBACC,OACA,EACC,OACA,cAKG;AACJ,QACC,QAAQ,aACR,MAAM,QAAQ,cAAc,QAAQ,UAEpC;AAID,gCAA4B,MAAM;AAElC,YAAQ,OAAO,oBAAoB,MAAM;;GAE1C,mBACC,OACA,EACC,OACA,cAKG;AACJ,QACC,QAAQ,aACR,MAAM,QAAQ,cAAc,QAAQ,UAEpC;AAID,+BAA2B,MAAM;;GAElC,qBACC,OACA,EACC,OACA,cAKG;AACJ,QACC,QAAQ,aACR,MAAM,QAAQ,cAAc,QAAQ,UAEpC;AAKD,iCAA6B,OAAO,EACnC,iBAAiB,QAAQ,WACzB,CAAC;;GAEH,2BACC,OACA,EACC,OACA,cAKG;AACJ,QACC,QAAQ,aACR,MAAM,QAAQ,cAAc,QAAQ,UAEpC;AAGD,YAAQ,OAAO,oBAAoB,MAAM;;GAE1C,GAGD,EAAE,CACF;EAKA,WAAW,gBAAgB;EAC3B,WAAW,gBAAgB;EAC3B,CAAC;AAEF,QAAO,gCAAG,WAAY"}
@@ -4,7 +4,14 @@ import { TypingActorType, TypingState } from "@cossistant/core";
4
4
  //#region src/realtime/typing-store.d.ts
5
5
  type Selector<T> = (state: TypingState) => T;
6
6
  type EqualityChecker<T> = (previous: T, next: T) => boolean;
7
+ /**
8
+ * Hook wrapper for the typing Zustand store used by realtime helpers.
9
+ */
7
10
  declare function useTypingStore<TSelected>(selector: Selector<TSelected>, isEqual?: EqualityChecker<TSelected>): TSelected;
11
+ /**
12
+ * Manually sets the typing state for a participant, typically in response to
13
+ * local input changes.
14
+ */
8
15
  declare function setTypingState(options: {
9
16
  conversationId: string;
10
17
  actorType: TypingActorType;
@@ -13,17 +20,28 @@ declare function setTypingState(options: {
13
20
  preview?: string | null;
14
21
  ttlMs?: number;
15
22
  }): void;
23
+ /**
24
+ * Removes typing state entries for a participant.
25
+ */
16
26
  declare function clearTypingState(options: {
17
27
  conversationId: string;
18
28
  actorType: TypingActorType;
19
29
  actorId: string;
20
30
  }): void;
31
+ /**
32
+ * Applies realtime typing events to the store while supporting exclusions for
33
+ * the current visitor or agents.
34
+ */
21
35
  declare function applyConversationTypingEvent(event: RealtimeEvent<"conversationTyping">, options?: {
22
36
  ignoreVisitorId?: string | null;
23
37
  ignoreUserId?: string | null;
24
38
  ignoreAiAgentId?: string | null;
25
39
  ttlMs?: number;
26
40
  }): void;
41
+ /**
42
+ * Utility invoked when a timeline item is created to clear stale typing
43
+ * indicators for the sender.
44
+ */
27
45
  declare function clearTypingFromTimelineItem(event: RealtimeEvent<"timelineItemCreated">): void;
28
46
  //#endregion
29
47
  export { applyConversationTypingEvent, clearTypingFromTimelineItem, clearTypingState, setTypingState, useTypingStore };
@@ -1 +1 @@
1
- {"version":3,"file":"typing-store.d.ts","names":[],"sources":["../../src/realtime/typing-store.ts"],"sourcesContent":[],"mappings":";;;;KAgBK,sBAAsB,gBAAgB;KAEtC,gCAAgC,SAAS;AAFzC,iBAiCW,cAjCH,CAAA,SAAA,CAAA,CAAA,QAAA,EAkCF,QAlCE,CAkCO,SAlCP,CAAA,EAAA,OAAA,CAAA,EAmCF,eAnCE,CAmCc,SAnCd,CAAA,CAAA,EAoCV,SApCU;AAAA,iBAwCG,cAAA,CAxCH,OAAA,EAAA;gBAAc,EAAA,MAAA;WAAgB,EA0C/B,eA1C+B;EAAC,OAAA,EAAA,MAAA;EAEvC,QAAA,EAAA,OAAA;EAAe,OAAA,CAAA,EAAA,MAAA,GAAA,IAAA;OAAiB,CAAA,EAAA,MAAA;QAAS;AAAC,iBAiD/B,gBAAA,CAjD+B,OAAA,EAAA;EA+B/B,cAAA,EAAA,MAAc;EAAA,SAAA,EAoBlB,eApBkB;SACV,EAAA,MAAA;QAAT;AACgB,iBAwBX,4BAAA,CAxBW,KAAA,EAyBnB,aAzBmB,CAAA,oBAAA,CAAA,EAAA,OAgB3B,CAhB2B,EAAA;iBAAhB,CAAA,EAAA,MAAA,GAAA,IAAA;cACR,CAAA,EAAA,MAAA,GAAA,IAAA;EAAS,eAAA,CAAA,EAAA,MAAA,GAAA,IAAA;EAII,KAAA,CAAA,EAAA,MAAA;AAWhB,CAAA,CAAA,EAAgB,IAAA;AAQA,iBAYA,2BAAA,CAXR,KAAA,EAYA,aAZa,CAAA,qBAAA,CAAA,CAAA,EAAA,IAAA"}
1
+ {"version":3,"file":"typing-store.d.ts","names":[],"sources":["../../src/realtime/typing-store.ts"],"sourcesContent":[],"mappings":";;;;KAgBK,sBAAsB,gBAAgB;KAEtC,gCAAgC,SAAS;AAPyB;AAK3B;AAoC5C;AACoB,iBADJ,cACI,CAAA,SAAA,CAAA,CAAA,QAAA,EAAT,QAAS,CAAA,SAAA,CAAA,EAAA,OAAA,CAAA,EACT,eADS,CACO,SADP,CAAA,CAAA,EAEjB,SAFiB;;;;;AAER,iBAQI,cAAA,CARJ,OAAA,EAAA;EAQI,cAAA,EAAA,MAAc;EAcd,SAAA,EAZJ,eAYoB;EAYhB,OAAA,EAAA,MAAA;EAgBA,QAAA,EAAA,OAAA;;;;;;;iBA5BA,gBAAA;;aAEJ;;;;;;;iBAUI,4BAAA,QACR;;;;;;;;;;iBAeQ,2BAAA,QACR"}
@@ -8,23 +8,40 @@ function useSelector(selector, isEqual = Object.is) {
8
8
  const subscribe = (onStoreChange) => store.subscribe(() => {
9
9
  onStoreChange();
10
10
  });
11
- const snapshot = useSyncExternalStore(subscribe, store.getState, store.getState);
12
- const selected = selector(snapshot);
11
+ const selected = selector(useSyncExternalStore(subscribe, store.getState, store.getState));
13
12
  if (selectionRef.current === void 0 || !isEqual(selectionRef.current, selected)) selectionRef.current = selected;
14
13
  return selectionRef.current;
15
14
  }
15
+ /**
16
+ * Hook wrapper for the typing Zustand store used by realtime helpers.
17
+ */
16
18
  function useTypingStore(selector, isEqual) {
17
19
  return useSelector(selector, isEqual);
18
20
  }
21
+ /**
22
+ * Manually sets the typing state for a participant, typically in response to
23
+ * local input changes.
24
+ */
19
25
  function setTypingState(options) {
20
26
  setTypingState$1(store, options);
21
27
  }
28
+ /**
29
+ * Removes typing state entries for a participant.
30
+ */
22
31
  function clearTypingState(options) {
23
32
  clearTypingState$1(store, options);
24
33
  }
34
+ /**
35
+ * Applies realtime typing events to the store while supporting exclusions for
36
+ * the current visitor or agents.
37
+ */
25
38
  function applyConversationTypingEvent(event, options) {
26
39
  applyConversationTypingEvent$1(store, event, options);
27
40
  }
41
+ /**
42
+ * Utility invoked when a timeline item is created to clear stale typing
43
+ * indicators for the sender.
44
+ */
28
45
  function clearTypingFromTimelineItem(event) {
29
46
  clearTypingFromTimelineItem$1(store, event);
30
47
  }
@@ -1 +1 @@
1
- {"version":3,"file":"typing-store.js","names":[],"sources":["../../src/realtime/typing-store.ts"],"sourcesContent":["import {\n\tapplyConversationTypingEvent as applyEvent,\n\ttype ConversationTypingState,\n\tclearTypingFromTimelineItem as clearFromTimelineItem,\n\tclearTypingState as clearState,\n\tcreateTypingStore,\n\tsetTypingState as setState,\n\ttype TypingActorType,\n\ttype TypingEntry,\n\ttype TypingState,\n} from \"@cossistant/core\";\nimport type { RealtimeEvent } from \"@cossistant/types/realtime-events\";\nimport { useRef, useSyncExternalStore } from \"react\";\n\nconst store = createTypingStore();\n\ntype Selector<T> = (state: TypingState) => T;\n\ntype EqualityChecker<T> = (previous: T, next: T) => boolean;\n\nfunction useSelector<TSelected>(\n\tselector: Selector<TSelected>,\n\tisEqual: EqualityChecker<TSelected> = Object.is\n): TSelected {\n\tconst selectionRef = useRef<TSelected>(undefined);\n\n\tconst subscribe = (onStoreChange: () => void) =>\n\t\tstore.subscribe(() => {\n\t\t\tonStoreChange();\n\t\t});\n\n\tconst snapshot = useSyncExternalStore(\n\t\tsubscribe,\n\t\tstore.getState,\n\t\tstore.getState\n\t);\n\n\tconst selected = selector(snapshot);\n\n\tif (\n\t\tselectionRef.current === undefined ||\n\t\t!isEqual(selectionRef.current, selected)\n\t) {\n\t\tselectionRef.current = selected;\n\t}\n\n\treturn selectionRef.current as TSelected;\n}\n\nexport function useTypingStore<TSelected>(\n\tselector: Selector<TSelected>,\n\tisEqual?: EqualityChecker<TSelected>\n): TSelected {\n\treturn useSelector(selector, isEqual);\n}\n\nexport function setTypingState(options: {\n\tconversationId: string;\n\tactorType: TypingActorType;\n\tactorId: string;\n\tisTyping: boolean;\n\tpreview?: string | null;\n\tttlMs?: number;\n}) {\n\tsetState(store, options);\n}\n\nexport function clearTypingState(options: {\n\tconversationId: string;\n\tactorType: TypingActorType;\n\tactorId: string;\n}) {\n\tclearState(store, options);\n}\n\nexport function applyConversationTypingEvent(\n\tevent: RealtimeEvent<\"conversationTyping\">,\n\toptions?: {\n\t\tignoreVisitorId?: string | null;\n\t\tignoreUserId?: string | null;\n\t\tignoreAiAgentId?: string | null;\n\t\tttlMs?: number;\n\t}\n) {\n\tapplyEvent(store, event, options);\n}\n\nexport function clearTypingFromTimelineItem(\n\tevent: RealtimeEvent<\"timelineItemCreated\">\n) {\n\tclearFromTimelineItem(store, event);\n}\n"],"mappings":";;;;AAcA,MAAM,QAAQ,mBAAmB;AAMjC,SAAS,YACR,UACA,UAAsC,OAAO,IACjC;CACZ,MAAM,eAAe,OAAkB,OAAU;CAEjD,MAAM,aAAa,kBAClB,MAAM,gBAAgB;AACrB,iBAAe;GACd;CAEH,MAAM,WAAW,qBAChB,WACA,MAAM,UACN,MAAM,SACN;CAED,MAAM,WAAW,SAAS,SAAS;AAEnC,KACC,aAAa,YAAY,UACzB,CAAC,QAAQ,aAAa,SAAS,SAAS,CAExC,cAAa,UAAU;AAGxB,QAAO,aAAa;;AAGrB,SAAgB,eACf,UACA,SACY;AACZ,QAAO,YAAY,UAAU,QAAQ;;AAGtC,SAAgB,eAAe,SAO5B;AACF,kBAAS,OAAO,QAAQ;;AAGzB,SAAgB,iBAAiB,SAI9B;AACF,oBAAW,OAAO,QAAQ;;AAG3B,SAAgB,6BACf,OACA,SAMC;AACD,gCAAW,OAAO,OAAO,QAAQ;;AAGlC,SAAgB,4BACf,OACC;AACD,+BAAsB,OAAO,MAAM"}
1
+ {"version":3,"file":"typing-store.js","names":[],"sources":["../../src/realtime/typing-store.ts"],"sourcesContent":["import {\n\tapplyConversationTypingEvent as applyEvent,\n\ttype ConversationTypingState,\n\tclearTypingFromTimelineItem as clearFromTimelineItem,\n\tclearTypingState as clearState,\n\tcreateTypingStore,\n\tsetTypingState as setState,\n\ttype TypingActorType,\n\ttype TypingEntry,\n\ttype TypingState,\n} from \"@cossistant/core\";\nimport type { RealtimeEvent } from \"@cossistant/types/realtime-events\";\nimport { useRef, useSyncExternalStore } from \"react\";\n\nconst store = createTypingStore();\n\ntype Selector<T> = (state: TypingState) => T;\n\ntype EqualityChecker<T> = (previous: T, next: T) => boolean;\n\nfunction useSelector<TSelected>(\n\tselector: Selector<TSelected>,\n\tisEqual: EqualityChecker<TSelected> = Object.is\n): TSelected {\n\tconst selectionRef = useRef<TSelected>(undefined);\n\n\tconst subscribe = (onStoreChange: () => void) =>\n\t\tstore.subscribe(() => {\n\t\t\tonStoreChange();\n\t\t});\n\n\tconst snapshot = useSyncExternalStore(\n\t\tsubscribe,\n\t\tstore.getState,\n\t\tstore.getState\n\t);\n\n\tconst selected = selector(snapshot);\n\n\tif (\n\t\tselectionRef.current === undefined ||\n\t\t!isEqual(selectionRef.current, selected)\n\t) {\n\t\tselectionRef.current = selected;\n\t}\n\n\treturn selectionRef.current as TSelected;\n}\n\n/**\n * Hook wrapper for the typing Zustand store used by realtime helpers.\n */\nexport function useTypingStore<TSelected>(\n\tselector: Selector<TSelected>,\n\tisEqual?: EqualityChecker<TSelected>\n): TSelected {\n\treturn useSelector(selector, isEqual);\n}\n\n/**\n * Manually sets the typing state for a participant, typically in response to\n * local input changes.\n */\nexport function setTypingState(options: {\n\tconversationId: string;\n\tactorType: TypingActorType;\n\tactorId: string;\n\tisTyping: boolean;\n\tpreview?: string | null;\n\tttlMs?: number;\n}) {\n\tsetState(store, options);\n}\n\n/**\n * Removes typing state entries for a participant.\n */\nexport function clearTypingState(options: {\n\tconversationId: string;\n\tactorType: TypingActorType;\n\tactorId: string;\n}) {\n\tclearState(store, options);\n}\n\n/**\n * Applies realtime typing events to the store while supporting exclusions for\n * the current visitor or agents.\n */\nexport function applyConversationTypingEvent(\n\tevent: RealtimeEvent<\"conversationTyping\">,\n\toptions?: {\n\t\tignoreVisitorId?: string | null;\n\t\tignoreUserId?: string | null;\n\t\tignoreAiAgentId?: string | null;\n\t\tttlMs?: number;\n\t}\n) {\n\tapplyEvent(store, event, options);\n}\n\n/**\n * Utility invoked when a timeline item is created to clear stale typing\n * indicators for the sender.\n */\nexport function clearTypingFromTimelineItem(\n\tevent: RealtimeEvent<\"timelineItemCreated\">\n) {\n\tclearFromTimelineItem(store, event);\n}\n"],"mappings":";;;;AAcA,MAAM,QAAQ,mBAAmB;AAMjC,SAAS,YACR,UACA,UAAsC,OAAO,IACjC;CACZ,MAAM,eAAe,OAAkB,OAAU;CAEjD,MAAM,aAAa,kBAClB,MAAM,gBAAgB;AACrB,iBAAe;GACd;CAQH,MAAM,WAAW,SANA,qBAChB,WACA,MAAM,UACN,MAAM,SACN,CAEkC;AAEnC,KACC,aAAa,YAAY,UACzB,CAAC,QAAQ,aAAa,SAAS,SAAS,CAExC,cAAa,UAAU;AAGxB,QAAO,aAAa;;;;;AAMrB,SAAgB,eACf,UACA,SACY;AACZ,QAAO,YAAY,UAAU,QAAQ;;;;;;AAOtC,SAAgB,eAAe,SAO5B;AACF,kBAAS,OAAO,QAAQ;;;;;AAMzB,SAAgB,iBAAiB,SAI9B;AACF,oBAAW,OAAO,QAAQ;;;;;;AAO3B,SAAgB,6BACf,OACA,SAMC;AACD,gCAAW,OAAO,OAAO,QAAQ;;;;;;AAOlC,SAAgB,4BACf,OACC;AACD,+BAAsB,OAAO,MAAM"}
@@ -3,12 +3,12 @@ import { RealtimeContextValue } from "./provider.js";
3
3
 
4
4
  //#region src/realtime/use-realtime.d.ts
5
5
  type RealtimeHandlerContext<TContext> = TContext;
6
- type RealtimeEventMeta<TType extends RealtimeEventType, TContext> = {
7
- event: RealtimeEvent<TType>;
6
+ type RealtimeEventMeta<TType$1 extends RealtimeEventType, TContext> = {
7
+ event: RealtimeEvent<TType$1>;
8
8
  context: RealtimeHandlerContext<TContext>;
9
9
  };
10
- type RealtimeEventHandler<TType extends RealtimeEventType, TContext> = (data: RealtimeEventData<TType>, meta: RealtimeEventMeta<TType, TContext>) => void | Promise<void>;
11
- type RealtimeEventHandlerEntry<TType extends RealtimeEventType, TContext> = RealtimeEventHandler<TType, TContext> | RealtimeEventHandler<TType, TContext>[];
10
+ type RealtimeEventHandler<TType$1 extends RealtimeEventType, TContext> = (data: RealtimeEventData<TType$1>, meta: RealtimeEventMeta<TType$1, TContext>) => void | Promise<void>;
11
+ type RealtimeEventHandlerEntry<TType$1 extends RealtimeEventType, TContext> = RealtimeEventHandler<TType$1, TContext> | RealtimeEventHandler<TType$1, TContext>[];
12
12
  type RealtimeEventHandlersMap<TContext> = Partial<{ [TType in RealtimeEventType]: RealtimeEventHandlerEntry<TType, TContext> }>;
13
13
  type UseRealtimeOptions<TContext, THandlers extends RealtimeEventHandlersMap<TContext>> = {
14
14
  events: THandlers;
@@ -17,6 +17,10 @@ type UseRealtimeOptions<TContext, THandlers extends RealtimeEventHandlersMap<TCo
17
17
  context?: TContext;
18
18
  onEventError?: (error: unknown, event: RealtimeEvent<RealtimeEventType>) => void;
19
19
  };
20
+ /**
21
+ * Binds realtime connection events to typed handler maps with automatic
22
+ * filtering by website/visitor ids.
23
+ */
20
24
  declare function useRealtime<TContext = void, THandlers extends RealtimeEventHandlersMap<TContext> = RealtimeEventHandlersMap<TContext>>({
21
25
  events,
22
26
  websiteId,
@@ -1 +1 @@
1
- {"version":3,"file":"use-realtime.d.ts","names":[],"sources":["../../src/realtime/use-realtime.ts"],"sourcesContent":[],"mappings":";;;;KAUY,mCAAmC;KAEnC,gCAAgC;SACpC,cAAc;EAHV,OAAA,EAIF,sBAJwB,CAID,QAJc,CAAA;AAE/C,CAAA;AAA6B,KAKjB,oBALiB,CAAA,cAKkB,iBALlB,EAAA,QAAA,CAAA,GAAA,CAAA,IAAA,EAMtB,iBANsB,CAMJ,KANI,CAAA,EAAA,IAAA,EAOtB,iBAPsB,CAOJ,KAPI,EAOG,QAPH,CAAA,EAAA,GAAA,IAAA,GAQjB,OARiB,CAAA,IAAA,CAAA;AAAe,KAUhC,yBAVgC,CAAA,cAW7B,iBAX6B,EAAA,QAAA,CAAA,GAczC,oBAdyC,CAcpB,KAdoB,EAcb,QAda,CAAA,GAezC,oBAfyC,CAepB,KAfoB,EAeb,QAfa,CAAA,EAAA;AACtB,KAgBV,wBAhBU,CAAA,QAAA,CAAA,GAgB2B,OAhB3B,CAAA,YAiBX,iBAjBH,GAiBuB,yBAjBvB,CAiBiD,KAjBjD,EAiBwD,QAjBxD,CAAA;KAoBH,kBAnBK,CAAA,QAAA,EAAA,kBAqBS,wBArBT,CAqBkC,QArBlC,CAAA,CAAA,GAAA;EAAsB,MAAA,EAuBvB,SAvBuB;EAGpB,SAAA,CAAA,EAAA,MAAA,GAAA,IAAoB;EAAA,SAAA,CAAA,EAAA,MAAA,GAAA,IAAA;SAAe,CAAA,EAuBpC,QAvBoC;cACtB,CAAA,EAAA,CAAA,KAAA,EAAA,OAAA,EAAA,KAAA,EAyBhB,aAzBgB,CAyBF,iBAzBE,CAAA,EAAA,GAAA,IAAA;;AACA,iBA4BT,WA5BS,CAAA,WAAA,IAAA,EAAA,kBA+BvB,wBA/BuB,CA+BE,QA/BF,CAAA,GA+Bc,wBA/Bd,CA+BuC,QA/BvC,CAAA,CAAA,CAAA;EAAA,MAAA;EAAA,SAAA;EAAA,SAAA;EAAA,OAAA;EAAA;AAAA,CAAA,EAsCtB,kBAtCsB,CAsCH,QAtCG,EAsCO,SAtCP,CAAA,CAAA,EAsCJ,oBAtCI"}
1
+ {"version":3,"file":"use-realtime.d.ts","names":[],"sources":["../../src/realtime/use-realtime.ts"],"sourcesContent":[],"mappings":";;;;KAUY,mCAAmC;KAEnC,kCAAgC;SACpC,cAAc;EAHV,OAAA,EAIF,sBAJwB,CAID,QAJC,CAAA;AAElC,CAAA;AAA4C,KAKhC,oBALgC,CAAA,gBAKG,iBALH,EAAA,QAAA,CAAA,GAAA,CAAA,IAAA,EAMrC,iBANqC,CAMnB,OANmB,CAAA,EAAA,IAAA,EAOrC,iBAPqC,CAOnB,OAPmB,EAOZ,QAPY,CAAA,EAAA,GAAA,IAAA,GAQhC,OARgC,CAAA,IAAA,CAAA;AACtB,KASV,yBATU,CAAA,gBAUP,iBAVO,EAAA,QAAA,CAAA,GAanB,oBAbmB,CAaE,OAbF,EAaS,QAbT,CAAA,GAcnB,oBAdmB,CAcE,OAdF,EAcS,QAdT,CAAA,EAAA;AAAd,KAgBI,wBAhBJ,CAAA,QAAA,CAAA,GAgByC,OAhBzC,CAAA,YAiBG,iBAhBsB,GAgBF,yBAhBE,CAgBwB,KAhBxB,EAgB+B,QAhB/B,CAAA,EAAvB,CAAA;KAmBL,kBAnB2B,CAAA,QAAA,EAAA,kBAqBb,wBArBa,CAqBY,QArBZ,CAAA,CAAA,GAAA;EAGpB,MAAA,EAoBH,SApBG;EAAmC,SAAA,CAAA,EAAA,MAAA,GAAA,IAAA;EACtB,SAAA,CAAA,EAAA,MAAA,GAAA,IAAA;EAAlB,OAAA,CAAA,EAsBI,QAtBJ;EACkB,YAAA,CAAA,EAAA,CAAA,KAAA,EAAA,OAAA,EAAA,KAAA,EAwBhB,aAxBgB,CAwBF,iBAxBE,CAAA,EAAA,GAAA,IAAA;CAAO;;;;AAGhC;AACe,iBA4BC,WA5BD,CAAA,WAAA,IAAA,EAAA,kBA+Bb,wBA/Ba,CA+BY,QA/BZ,CAAA,GA+BwB,wBA/BxB,CA+BiD,QA/BjD,CAAA,CAAA,CAAA;EAAA,MAAA;EAAA,SAAA;EAAA,SAAA;EAAA,OAAA;EAAA;AAAA,CAAA,EAsCZ,kBAtCY,CAsCO,QAtCP,EAsCiB,SAtCjB,CAAA,CAAA,EAsCM,oBAtCN"}
@@ -3,6 +3,10 @@ import { shouldDeliverEvent } from "./event-filter.js";
3
3
  import { useEffect, useRef } from "react";
4
4
 
5
5
  //#region src/realtime/use-realtime.ts
6
+ /**
7
+ * Binds realtime connection events to typed handler maps with automatic
8
+ * filtering by website/visitor ids.
9
+ */
6
10
  function useRealtime({ events, websiteId, visitorId, context, onEventError }) {
7
11
  const connection = useRealtimeConnection();
8
12
  const handlersRef = useRef(events);
@@ -1 +1 @@
1
- {"version":3,"file":"use-realtime.js","names":[],"sources":["../../src/realtime/use-realtime.ts"],"sourcesContent":["import type {\n\tAnyRealtimeEvent,\n\tRealtimeEvent,\n\tRealtimeEventData,\n\tRealtimeEventType,\n} from \"@cossistant/types/realtime-events\";\nimport { useEffect, useRef } from \"react\";\nimport { shouldDeliverEvent } from \"./event-filter\";\nimport { useRealtimeConnection } from \"./provider\";\n\nexport type RealtimeHandlerContext<TContext> = TContext;\n\nexport type RealtimeEventMeta<TType extends RealtimeEventType, TContext> = {\n\tevent: RealtimeEvent<TType>;\n\tcontext: RealtimeHandlerContext<TContext>;\n};\n\nexport type RealtimeEventHandler<TType extends RealtimeEventType, TContext> = (\n\tdata: RealtimeEventData<TType>,\n\tmeta: RealtimeEventMeta<TType, TContext>\n) => void | Promise<void>;\n\nexport type RealtimeEventHandlerEntry<\n\tTType extends RealtimeEventType,\n\tTContext,\n> =\n\t| RealtimeEventHandler<TType, TContext>\n\t| RealtimeEventHandler<TType, TContext>[];\n\nexport type RealtimeEventHandlersMap<TContext> = Partial<{\n\t[TType in RealtimeEventType]: RealtimeEventHandlerEntry<TType, TContext>;\n}>;\n\ntype UseRealtimeOptions<\n\tTContext,\n\tTHandlers extends RealtimeEventHandlersMap<TContext>,\n> = {\n\tevents: THandlers;\n\twebsiteId?: string | null;\n\tvisitorId?: string | null;\n\tcontext?: TContext;\n\tonEventError?: (\n\t\terror: unknown,\n\t\tevent: RealtimeEvent<RealtimeEventType>\n\t) => void;\n};\n\nexport function useRealtime<\n\tTContext = void,\n\tTHandlers extends\n\t\tRealtimeEventHandlersMap<TContext> = RealtimeEventHandlersMap<TContext>,\n>({\n\tevents,\n\twebsiteId,\n\tvisitorId,\n\tcontext,\n\tonEventError,\n}: UseRealtimeOptions<TContext, THandlers>) {\n\tconst connection = useRealtimeConnection();\n\tconst handlersRef = useRef<RealtimeEventHandlersMap<TContext>>(events);\n\tconst contextRef = useRef<TContext | undefined>(context);\n\tconst websiteIdRef = useRef<string | null>(websiteId ?? null);\n\tconst visitorIdRef = useRef<string | null>(visitorId ?? null);\n\tconst errorHandlerRef = useRef<\n\t\t| ((error: unknown, event: RealtimeEvent<RealtimeEventType>) => void)\n\t\t| undefined\n\t>(onEventError);\n\n\tuseEffect(() => {\n\t\thandlersRef.current = events;\n\t}, [events]);\n\n\tuseEffect(() => {\n\t\tcontextRef.current = context;\n\t}, [context]);\n\n\tuseEffect(() => {\n\t\twebsiteIdRef.current = websiteId ?? null;\n\t}, [websiteId]);\n\n\tuseEffect(() => {\n\t\tvisitorIdRef.current = visitorId ?? null;\n\t}, [visitorId]);\n\n\tuseEffect(() => {\n\t\terrorHandlerRef.current = onEventError;\n\t}, [onEventError]);\n\n\tuseEffect(\n\t\t() =>\n\t\t\tconnection.subscribe((event) => {\n\t\t\t\tconst handlers = handlersRef.current[event.type];\n\n\t\t\t\tif (!handlers) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (\n\t\t\t\t\t!shouldDeliverEvent(event, websiteIdRef.current, visitorIdRef.current)\n\t\t\t\t) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst payload = Array.isArray(handlers) ? handlers : [handlers];\n\n\t\t\t\tfor (const handler of payload) {\n\t\t\t\t\tPromise.resolve(\n\t\t\t\t\t\thandler(event.payload as never, {\n\t\t\t\t\t\t\tevent: event as never,\n\t\t\t\t\t\t\tcontext: contextRef.current as TContext,\n\t\t\t\t\t\t})\n\t\t\t\t\t).catch((error) => {\n\t\t\t\t\t\tconst errorHandler = errorHandlerRef.current;\n\t\t\t\t\t\tif (errorHandler) {\n\t\t\t\t\t\t\terrorHandler(error, event);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tconsole.error(\"[Realtime] Event handler threw an error\", error);\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}),\n\t\t[connection]\n\t);\n\n\treturn connection;\n}\n"],"mappings":";;;;;AA+CA,SAAgB,YAId,EACD,QACA,WACA,WACA,SACA,gBAC2C;CAC3C,MAAM,aAAa,uBAAuB;CAC1C,MAAM,cAAc,OAA2C,OAAO;CACtE,MAAM,aAAa,OAA6B,QAAQ;CACxD,MAAM,eAAe,OAAsB,aAAa,KAAK;CAC7D,MAAM,eAAe,OAAsB,aAAa,KAAK;CAC7D,MAAM,kBAAkB,OAGtB,aAAa;AAEf,iBAAgB;AACf,cAAY,UAAU;IACpB,CAAC,OAAO,CAAC;AAEZ,iBAAgB;AACf,aAAW,UAAU;IACnB,CAAC,QAAQ,CAAC;AAEb,iBAAgB;AACf,eAAa,UAAU,aAAa;IAClC,CAAC,UAAU,CAAC;AAEf,iBAAgB;AACf,eAAa,UAAU,aAAa;IAClC,CAAC,UAAU,CAAC;AAEf,iBAAgB;AACf,kBAAgB,UAAU;IACxB,CAAC,aAAa,CAAC;AAElB,iBAEE,WAAW,WAAW,UAAU;EAC/B,MAAM,WAAW,YAAY,QAAQ,MAAM;AAE3C,MAAI,CAAC,SACJ;AAGD,MACC,CAAC,mBAAmB,OAAO,aAAa,SAAS,aAAa,QAAQ,CAEtE;EAGD,MAAM,UAAU,MAAM,QAAQ,SAAS,GAAG,WAAW,CAAC,SAAS;AAE/D,OAAK,MAAM,WAAW,QACrB,SAAQ,QACP,QAAQ,MAAM,SAAkB;GACxB;GACP,SAAS,WAAW;GACpB,CAAC,CACF,CAAC,OAAO,UAAU;GAClB,MAAM,eAAe,gBAAgB;AACrC,OAAI,aACH,cAAa,OAAO,MAAM;OAE1B,SAAQ,MAAM,2CAA2C,MAAM;IAE/D;GAEF,EACH,CAAC,WAAW,CACZ;AAED,QAAO"}
1
+ {"version":3,"file":"use-realtime.js","names":[],"sources":["../../src/realtime/use-realtime.ts"],"sourcesContent":["import type {\n\tAnyRealtimeEvent,\n\tRealtimeEvent,\n\tRealtimeEventData,\n\tRealtimeEventType,\n} from \"@cossistant/types/realtime-events\";\nimport { useEffect, useRef } from \"react\";\nimport { shouldDeliverEvent } from \"./event-filter\";\nimport { useRealtimeConnection } from \"./provider\";\n\nexport type RealtimeHandlerContext<TContext> = TContext;\n\nexport type RealtimeEventMeta<TType extends RealtimeEventType, TContext> = {\n\tevent: RealtimeEvent<TType>;\n\tcontext: RealtimeHandlerContext<TContext>;\n};\n\nexport type RealtimeEventHandler<TType extends RealtimeEventType, TContext> = (\n\tdata: RealtimeEventData<TType>,\n\tmeta: RealtimeEventMeta<TType, TContext>\n) => void | Promise<void>;\n\nexport type RealtimeEventHandlerEntry<\n\tTType extends RealtimeEventType,\n\tTContext,\n> =\n\t| RealtimeEventHandler<TType, TContext>\n\t| RealtimeEventHandler<TType, TContext>[];\n\nexport type RealtimeEventHandlersMap<TContext> = Partial<{\n\t[TType in RealtimeEventType]: RealtimeEventHandlerEntry<TType, TContext>;\n}>;\n\ntype UseRealtimeOptions<\n\tTContext,\n\tTHandlers extends RealtimeEventHandlersMap<TContext>,\n> = {\n\tevents: THandlers;\n\twebsiteId?: string | null;\n\tvisitorId?: string | null;\n\tcontext?: TContext;\n\tonEventError?: (\n\t\terror: unknown,\n\t\tevent: RealtimeEvent<RealtimeEventType>\n\t) => void;\n};\n\n/**\n * Binds realtime connection events to typed handler maps with automatic\n * filtering by website/visitor ids.\n */\nexport function useRealtime<\n\tTContext = void,\n\tTHandlers extends\n\t\tRealtimeEventHandlersMap<TContext> = RealtimeEventHandlersMap<TContext>,\n>({\n\tevents,\n\twebsiteId,\n\tvisitorId,\n\tcontext,\n\tonEventError,\n}: UseRealtimeOptions<TContext, THandlers>) {\n\tconst connection = useRealtimeConnection();\n\tconst handlersRef = useRef<RealtimeEventHandlersMap<TContext>>(events);\n\tconst contextRef = useRef<TContext | undefined>(context);\n\tconst websiteIdRef = useRef<string | null>(websiteId ?? null);\n\tconst visitorIdRef = useRef<string | null>(visitorId ?? null);\n\tconst errorHandlerRef = useRef<\n\t\t| ((error: unknown, event: RealtimeEvent<RealtimeEventType>) => void)\n\t\t| undefined\n\t>(onEventError);\n\n\tuseEffect(() => {\n\t\thandlersRef.current = events;\n\t}, [events]);\n\n\tuseEffect(() => {\n\t\tcontextRef.current = context;\n\t}, [context]);\n\n\tuseEffect(() => {\n\t\twebsiteIdRef.current = websiteId ?? null;\n\t}, [websiteId]);\n\n\tuseEffect(() => {\n\t\tvisitorIdRef.current = visitorId ?? null;\n\t}, [visitorId]);\n\n\tuseEffect(() => {\n\t\terrorHandlerRef.current = onEventError;\n\t}, [onEventError]);\n\n\tuseEffect(\n\t\t() =>\n\t\t\tconnection.subscribe((event) => {\n\t\t\t\tconst handlers = handlersRef.current[event.type];\n\n\t\t\t\tif (!handlers) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (\n\t\t\t\t\t!shouldDeliverEvent(event, websiteIdRef.current, visitorIdRef.current)\n\t\t\t\t) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst payload = Array.isArray(handlers) ? handlers : [handlers];\n\n\t\t\t\tfor (const handler of payload) {\n\t\t\t\t\tPromise.resolve(\n\t\t\t\t\t\thandler(event.payload as never, {\n\t\t\t\t\t\t\tevent: event as never,\n\t\t\t\t\t\t\tcontext: contextRef.current as TContext,\n\t\t\t\t\t\t})\n\t\t\t\t\t).catch((error) => {\n\t\t\t\t\t\tconst errorHandler = errorHandlerRef.current;\n\t\t\t\t\t\tif (errorHandler) {\n\t\t\t\t\t\t\terrorHandler(error, event);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tconsole.error(\"[Realtime] Event handler threw an error\", error);\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}),\n\t\t[connection]\n\t);\n\n\treturn connection;\n}\n"],"mappings":";;;;;;;;;AAmDA,SAAgB,YAId,EACD,QACA,WACA,WACA,SACA,gBAC2C;CAC3C,MAAM,aAAa,uBAAuB;CAC1C,MAAM,cAAc,OAA2C,OAAO;CACtE,MAAM,aAAa,OAA6B,QAAQ;CACxD,MAAM,eAAe,OAAsB,aAAa,KAAK;CAC7D,MAAM,eAAe,OAAsB,aAAa,KAAK;CAC7D,MAAM,kBAAkB,OAGtB,aAAa;AAEf,iBAAgB;AACf,cAAY,UAAU;IACpB,CAAC,OAAO,CAAC;AAEZ,iBAAgB;AACf,aAAW,UAAU;IACnB,CAAC,QAAQ,CAAC;AAEb,iBAAgB;AACf,eAAa,UAAU,aAAa;IAClC,CAAC,UAAU,CAAC;AAEf,iBAAgB;AACf,eAAa,UAAU,aAAa;IAClC,CAAC,UAAU,CAAC;AAEf,iBAAgB;AACf,kBAAgB,UAAU;IACxB,CAAC,aAAa,CAAC;AAElB,iBAEE,WAAW,WAAW,UAAU;EAC/B,MAAM,WAAW,YAAY,QAAQ,MAAM;AAE3C,MAAI,CAAC,SACJ;AAGD,MACC,CAAC,mBAAmB,OAAO,aAAa,SAAS,aAAa,QAAQ,CAEtE;EAGD,MAAM,UAAU,MAAM,QAAQ,SAAS,GAAG,WAAW,CAAC,SAAS;AAE/D,OAAK,MAAM,WAAW,QACrB,SAAQ,QACP,QAAQ,MAAM,SAAkB;GACxB;GACP,SAAS,WAAW;GACpB,CAAC,CACF,CAAC,OAAO,UAAU;GAClB,MAAM,eAAe,gBAAgB;AACrC,OAAI,aACH,cAAa,OAAO,MAAM;OAE1B,SAAQ,MAAM,2CAA2C,MAAM;IAE/D;GAEF,EACH,CAAC,WAAW,CACZ;AAED,QAAO"}
@@ -83,6 +83,7 @@ declare const realtimeSchema: {
83
83
  type: z.ZodEnum<{
84
84
  message: "message";
85
85
  event: "event";
86
+ identification: "identification";
86
87
  }>;
87
88
  text: z.ZodNullable<z.ZodString>;
88
89
  parts: z.ZodArray<z.ZodUnknown>;
@@ -91,6 +92,7 @@ declare const realtimeSchema: {
91
92
  aiAgentId: z.ZodNullable<z.ZodString>;
92
93
  createdAt: z.ZodString;
93
94
  deletedAt: z.ZodNullable<z.ZodString>;
95
+ tool: z.ZodOptional<z.ZodNullable<z.ZodString>>;
94
96
  }, z.core.$strip>;
95
97
  }, z.core.$strip>;
96
98
  readonly conversationCreated: z.ZodObject<{
@@ -107,10 +109,11 @@ declare const realtimeSchema: {
107
109
  visitorId: z.ZodString;
108
110
  websiteId: z.ZodString;
109
111
  status: z.ZodDefault<z.ZodEnum<{
110
- resolved: "resolved";
111
112
  open: "open";
113
+ resolved: "resolved";
112
114
  spam: "spam";
113
115
  }>>;
116
+ deletedAt: z.ZodDefault<z.ZodNullable<z.ZodString>>;
114
117
  lastTimelineItem: z.ZodOptional<z.ZodObject<{
115
118
  id: z.ZodOptional<z.ZodString>;
116
119
  conversationId: z.ZodString;
@@ -122,8 +125,10 @@ declare const realtimeSchema: {
122
125
  type: z.ZodEnum<{
123
126
  message: "message";
124
127
  event: "event";
128
+ identification: "identification";
125
129
  }>;
126
130
  text: z.ZodNullable<z.ZodString>;
131
+ tool: z.ZodOptional<z.ZodNullable<z.ZodString>>;
127
132
  parts: z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
128
133
  type: z.ZodLiteral<"text">;
129
134
  text: z.ZodString;
@@ -141,6 +146,9 @@ declare const realtimeSchema: {
141
146
  tag_removed: "tag_removed";
142
147
  resolved: "resolved";
143
148
  reopened: "reopened";
149
+ visitor_blocked: "visitor_blocked";
150
+ visitor_unblocked: "visitor_unblocked";
151
+ visitor_identified: "visitor_identified";
144
152
  }>;
145
153
  actorUserId: z.ZodNullable<z.ZodString>;
146
154
  actorAiAgentId: z.ZodNullable<z.ZodString>;
@@ -172,14 +180,14 @@ declare const realtimeSchema: {
172
180
  header: z.ZodObject<{
173
181
  id: z.ZodString;
174
182
  status: z.ZodEnum<{
175
- resolved: "resolved";
176
183
  open: "open";
184
+ resolved: "resolved";
177
185
  spam: "spam";
178
186
  }>;
179
187
  priority: z.ZodEnum<{
180
- normal: "normal";
181
188
  high: "high";
182
189
  low: "low";
190
+ normal: "normal";
183
191
  urgent: "urgent";
184
192
  }>;
185
193
  organizationId: z.ZodString;
@@ -195,6 +203,7 @@ declare const realtimeSchema: {
195
203
  name: z.ZodNullable<z.ZodString>;
196
204
  email: z.ZodNullable<z.ZodString>;
197
205
  image: z.ZodNullable<z.ZodString>;
206
+ metadataHash: z.ZodOptional<z.ZodString>;
198
207
  }, z.core.$strip>>;
199
208
  }, z.core.$strip>;
200
209
  websiteId: z.ZodString;
@@ -222,8 +231,10 @@ declare const realtimeSchema: {
222
231
  type: z.ZodEnum<{
223
232
  message: "message";
224
233
  event: "event";
234
+ identification: "identification";
225
235
  }>;
226
236
  text: z.ZodNullable<z.ZodString>;
237
+ tool: z.ZodOptional<z.ZodNullable<z.ZodString>>;
227
238
  parts: z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
228
239
  type: z.ZodLiteral<"text">;
229
240
  text: z.ZodString;
@@ -241,6 +252,9 @@ declare const realtimeSchema: {
241
252
  tag_removed: "tag_removed";
242
253
  resolved: "resolved";
243
254
  reopened: "reopened";
255
+ visitor_blocked: "visitor_blocked";
256
+ visitor_unblocked: "visitor_unblocked";
257
+ visitor_identified: "visitor_identified";
244
258
  }>;
245
259
  actorUserId: z.ZodNullable<z.ZodString>;
246
260
  actorAiAgentId: z.ZodNullable<z.ZodString>;
@@ -1 +1 @@
1
- {"version":3,"file":"realtime-events.d.ts","names":[],"sources":["../../types/src/realtime-events.ts"],"sourcesContent":[],"mappings":";;;;;;;;cAiBa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAiED,iBAAA,gBAAiC;KAEjC,+BAA+B,qBAAqB,CAAA,CAAE,cACzD,gBAAgB;KAGb,wBAAwB;QAC7B;WACG,qBAAqB;;KAGnB,gBAAA,WACL,oBAAoB,cAAc,KACvC;KAEU,4BAA4B,qBACvC,qBAAqB"}
1
+ {"version":3,"file":"realtime-events.d.ts","names":[],"sources":["../../types/src/realtime-events.ts"],"sourcesContent":[],"mappings":";;;;;;;;cAiBa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAmED,iBAAA,gBAAiC;KAEjC,+BAA+B,qBAAqB,CAAA,CAAE,cACzD,gBAAgB;KAGb,wBAAwB;QAC7B;WACG,qBAAqB;;KAGnB,gBAAA,WACL,oBAAoB,cAAc,KACvC;KAEU,4BAA4B,qBACvC,qBAAqB"}
package/schemas.d.ts CHANGED
@@ -10,10 +10,11 @@ declare const conversationSchema: z.ZodObject<{
10
10
  visitorId: z.ZodString;
11
11
  websiteId: z.ZodString;
12
12
  status: z.ZodDefault<z.ZodEnum<{
13
- resolved: "resolved";
14
13
  open: "open";
14
+ resolved: "resolved";
15
15
  spam: "spam";
16
16
  }>>;
17
+ deletedAt: z.ZodDefault<z.ZodNullable<z.ZodString>>;
17
18
  lastTimelineItem: z.ZodOptional<z.ZodObject<{
18
19
  id: z.ZodOptional<z.ZodString>;
19
20
  conversationId: z.ZodString;
@@ -25,8 +26,10 @@ declare const conversationSchema: z.ZodObject<{
25
26
  type: z.ZodEnum<{
26
27
  message: "message";
27
28
  event: "event";
29
+ identification: "identification";
28
30
  }>;
29
31
  text: z.ZodNullable<z.ZodString>;
32
+ tool: z.ZodOptional<z.ZodNullable<z.ZodString>>;
30
33
  parts: z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
31
34
  type: z.ZodLiteral<"text">;
32
35
  text: z.ZodString;
@@ -44,6 +47,9 @@ declare const conversationSchema: z.ZodObject<{
44
47
  tag_removed: "tag_removed";
45
48
  resolved: "resolved";
46
49
  reopened: "reopened";
50
+ visitor_blocked: "visitor_blocked";
51
+ visitor_unblocked: "visitor_unblocked";
52
+ visitor_identified: "visitor_identified";
47
53
  }>;
48
54
  actorUserId: z.ZodNullable<z.ZodString>;
49
55
  actorAiAgentId: z.ZodNullable<z.ZodString>;
package/schemas.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"schemas.d.ts","names":[],"sources":["../../types/src/schemas.ts"],"sourcesContent":[],"mappings":";;;;cAkBa,oBAAkB,CAAA,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAAA,SAAA,aAAA;IAAA,SAAA,eAAA,cAAA,YAAA,CAAA,CAAA;EAiBnB,CAAA,eAAY,CAAA,CAAA;CAAA,eAAA,CAAA;AAAkB,KAA9B,YAAA,GAAe,CAAA,CAAE,KAAa,CAAA,OAAA,kBAAA,CAAA;AAAf,cAEd,sBAFgB,EAEM,CAAA,CAAA,SAFN,CAAA;EAAK,EAAA,aAAA;EAErB,cAAA,aAUX;EAAA,MAAA,eAAA,YAAA,CAAA;;;;;;;;KAEU,gBAAA,GAAmB,CAAA,CAAE,aAAa"}
1
+ {"version":3,"file":"schemas.d.ts","names":[],"sources":["../../types/src/schemas.ts"],"sourcesContent":[],"mappings":";;;;cAkBa,oBAAkB,CAAA,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAAA,SAAA,eAAA,YAAA,CAAA;IAAA,SAAA,aAAA;IAkBnB,SAAA,eAA8B,cAAA,YAAb,CAAA,CAAK;EAErB,CAAA,eAAA,CAAA,CAAA;;KAFD,YAAA,GAAe,CAAA,CAAE,aAAa;cAE7B,wBAAsB,CAAA,CAAA;;;;;;;;;;;KAYvB,gBAAA,GAAmB,CAAA,CAAE,aAAa"}
@@ -1,4 +1,4 @@
1
- import * as react0 from "react";
1
+ import { ReactElement, ReactNode } from "react";
2
2
  import { AvailableAIAgent, AvailableHumanAgent } from "@cossistant/types";
3
3
 
4
4
  //#region src/support/components/avatar-stack.d.ts
@@ -23,13 +23,17 @@ declare const AvatarStackItem: ({
23
23
  gapWidth,
24
24
  className
25
25
  }: {
26
- children: React.ReactNode;
26
+ children: ReactNode;
27
27
  index: number;
28
28
  size?: number;
29
29
  spacing?: number;
30
30
  gapWidth?: number;
31
31
  className?: string;
32
- }) => react0.ReactElement<unknown, string | react0.JSXElementConstructor<any>> | null;
32
+ }) => ReactElement | null;
33
+ /**
34
+ * Displays a compact row of agent avatars with optional branding and overflow
35
+ * counts.
36
+ */
33
37
  declare function AvatarStack({
34
38
  humanAgents,
35
39
  aiAgents,
@@ -39,7 +43,7 @@ declare function AvatarStack({
39
43
  size,
40
44
  spacing,
41
45
  gapWidth
42
- }: AvatarStackProps): react0.ReactElement<unknown, string | react0.JSXElementConstructor<any>> | null;
46
+ }: AvatarStackProps): ReactElement | null;
43
47
  //#endregion
44
48
  export { AvatarStack, AvatarStackItem };
45
49
  //# sourceMappingURL=avatar-stack.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"avatar-stack.d.ts","names":[],"sources":["../../../src/support/components/avatar-stack.tsx"],"sourcesContent":[],"mappings":";;;;KAMK,gBAAA;eACS;YACH;EAFN,YAAA,CAAA,EAAA,OAAgB;EAAA,kBAAA,CAAA,EAAA,OAAA;WACP,CAAA,EAAA,MAAA;;EACa,IAAA,CAAA,EAAA,MAAA;EAYd;EA8CZ,OAAA,CAAA,EAAA,MAAA;;UA9C+B,CAAA,EAAA,MAAA;;AAAA,cAAnB,eAAmB,EAAA,CAAA;EAAA,QAAA;EAAA,KAAA;EAAA,IAAA;EAAA,OAAA;EAAA,QAAA;EAAA;AAgDhC,CAhDgC,EAAA;UAAA,EAQrB,KAAA,CAAM,SARe;OAAA,EAAA,MAAA;MAQrB,CAAA,EAAA,MAAM;SAAS,CAAA,EAMzB,MAAA;UAAA,CAAA,EAAA,MAAA;EAAA,SAAA,CAAA,EAAA,MAAA;AAkCD,CAAA,EAAA,GAlCC,MAAA,CAAA,YAkC0B,CAAA,OAAA,EAAA,MAAA,GAxCD,MAAA,CAMzB,qBAkC0B,CAAA,GAAA,CAAA,CAAA,GAAA,IAAA;AAAA,iBAAX,WAAA,CAAW;EAAA,WAAA;EAAA,QAAA;EAAA,YAAA;EAAA,kBAAA;EAAA,SAAA;EAAA,IAAA;EAAA,OAAA;EAAA;AAAA,CAAA,EASxB,gBATwB,CAAA,EASR,MAAA,CAAA,YATQ,CAAA,OAAA,EAAA,MAAA,GASR,MAAA,CAAA,qBATQ,CAAA,GAAA,CAAA,CAAA,GAAA,IAAA"}
1
+ {"version":3,"file":"avatar-stack.d.ts","names":[],"sources":["../../../src/support/components/avatar-stack.tsx"],"sourcesContent":[],"mappings":";;;;KAOK,gBAAA;eACS;EADT,QAAA,EAEM,gBAFU,EAAA;EAcR,YAAA,CAAA,EAAA,OA8CZ;EA9C+B,kBAAA,CAAA,EAAA,OAAA;EAAA,SAAA,CAAA,EAAA,MAAA;EAAA;EAAA,IAAA,CAAA,EAAA,MAAA;EAAA;EAAA,OAAA,CAAA,EAAA,MAAA;EAQrB;EAMP,QAAA,CAAA,EAAA,MAAA;CAAY;AAsCA,cApDH,eAoDc,EAAA,CAAA;EAAA,QAAA;EAAA,KAAA;EAAA,IAAA;EAAA,OAAA;EAAA,QAAA;EAAA;CAAA,EAAA;EAC1B,QAAA,EA7CU,SA6CV;EACA,KAAA,EAAA,MAAA;EACA,IAAA,CAAA,EAAA,MAAA;EACA,OAAA,CAAA,EAAA,MAAA;EACA,QAAA,CAAA,EAAA,MAAA;EACA,SAAA,CAAA,EAAA,MAAA;CACA,EAAA,GA7CG,YA6CH,GAAA,IAAA;;;;;iBAPe,WAAA;;;;;;;;;GASb,mBAAmB"}
@@ -23,6 +23,10 @@ const AvatarStackItem = ({ children, index, size = 44, spacing = 28, gapWidth =
23
23
  children
24
24
  } });
25
25
  };
26
+ /**
27
+ * Displays a compact row of agent avatars with optional branding and overflow
28
+ * counts.
29
+ */
26
30
  function AvatarStack({ humanAgents, aiAgents, hideBranding = false, hideDefaultAIAgent = true, className, size = 44, spacing = 28, gapWidth = 3 }) {
27
31
  const displayedHumanAgents = humanAgents.slice(0, 2);
28
32
  const remainingHumanAgentsCount = Math.max(0, humanAgents.length - 2);
@@ -1 +1 @@
1
- {"version":3,"file":"avatar-stack.js","names":[],"sources":["../../../src/support/components/avatar-stack.tsx"],"sourcesContent":["import type { AvailableAIAgent, AvailableHumanAgent } from \"@cossistant/types\";\nimport { useRenderElement } from \"../../utils/use-render-element\";\nimport { cn } from \"../utils\";\nimport { Avatar } from \"./avatar\";\nimport { CossistantLogo } from \"./cossistant-branding\";\n\ntype AvatarStackProps = {\n\thumanAgents: AvailableHumanAgent[];\n\taiAgents: AvailableAIAgent[];\n\thideBranding?: boolean;\n\thideDefaultAIAgent?: boolean;\n\tclassName?: string;\n\t/** Size of avatars (default: 44px) */\n\tsize?: number;\n\t/** Space between avatars (default: 28px) */\n\tspacing?: number;\n\t/** Gap width between avatars (default: 2px) */\n\tgapWidth?: number;\n};\n\nexport const AvatarStackItem = ({\n\tchildren,\n\tindex,\n\tsize = 44,\n\tspacing = 28,\n\tgapWidth = 2,\n\tclassName,\n}: {\n\tchildren: React.ReactNode;\n\tindex: number;\n\tsize?: number;\n\tspacing?: number;\n\tgapWidth?: number;\n\tclassName?: string;\n}) => {\n\tconst isFirst = index === 0;\n\n\t// Calculate the circle radius for the mask cutout\n\tconst circleRadius = size * 0.5;\n\tconst cutoutRadius = circleRadius + gapWidth; // Add gap width to create visible border\n\tconst cutoutPosition = `${circleRadius - spacing}px`;\n\n\treturn useRenderElement(\n\t\t\"div\",\n\t\t{ className },\n\t\t{\n\t\t\tprops: {\n\t\t\t\tclassName: cn(\n\t\t\t\t\t\"relative grid place-items-center\",\n\t\t\t\t\t!isFirst && \"[mask-repeat:no-repeat] [mask-size:100%_100%]\"\n\t\t\t\t),\n\t\t\t\tstyle: {\n\t\t\t\t\twidth: `${size}px`,\n\t\t\t\t\theight: `${size}px`,\n\t\t\t\t\t// Apply mask only to non-first items\n\t\t\t\t\t...(isFirst\n\t\t\t\t\t\t? {}\n\t\t\t\t\t\t: {\n\t\t\t\t\t\t\t\tmask: `radial-gradient(${cutoutRadius}px ${cutoutRadius}px at ${cutoutPosition} 50%, transparent ${cutoutRadius}px, white ${cutoutRadius}px)`,\n\t\t\t\t\t\t\t\tWebkitMask: `radial-gradient(${cutoutRadius}px ${cutoutRadius}px at ${cutoutPosition} 50%, transparent ${cutoutRadius}px, white ${cutoutRadius}px)`,\n\t\t\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t\tchildren,\n\t\t\t},\n\t\t}\n\t);\n};\n\nexport function AvatarStack({\n\thumanAgents,\n\taiAgents,\n\thideBranding = false,\n\thideDefaultAIAgent = true,\n\tclassName,\n\tsize = 44,\n\tspacing = 28,\n\tgapWidth = 3,\n}: AvatarStackProps) {\n\tconst displayedHumanAgents = humanAgents.slice(0, 2);\n\tconst remainingHumanAgentsCount = Math.max(0, humanAgents.length - 2);\n\n\t// Create array of all items to display\n\tconst items = [\n\t\t...displayedHumanAgents.map((agent) => ({\n\t\t\ttype: \"human\" as const,\n\t\t\tagent,\n\t\t})),\n\t\t...(remainingHumanAgentsCount > 0\n\t\t\t? [\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: \"count\" as const,\n\t\t\t\t\t\tcount: remainingHumanAgentsCount,\n\t\t\t\t\t},\n\t\t\t\t]\n\t\t\t: []),\n\t\t...(hideDefaultAIAgent\n\t\t\t? []\n\t\t\t: [\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: \"ai\" as const,\n\t\t\t\t\t\tagent: aiAgents[0],\n\t\t\t\t\t},\n\t\t\t\t]),\n\t];\n\n\treturn useRenderElement(\n\t\t\"div\",\n\t\t{ className },\n\t\t{\n\t\t\tprops: {\n\t\t\t\tclassName: \"inline-grid items-center\",\n\t\t\t\tstyle: {\n\t\t\t\t\tgridTemplateColumns: `repeat(${items.length}, ${spacing}px)`,\n\t\t\t\t},\n\t\t\t\tchildren: items.map((item, index) => (\n\t\t\t\t\t<AvatarStackItem\n\t\t\t\t\t\tgapWidth={gapWidth}\n\t\t\t\t\t\tindex={index}\n\t\t\t\t\t\tkey={`avatar-${index}`}\n\t\t\t\t\t\tsize={size}\n\t\t\t\t\t\tspacing={spacing}\n\t\t\t\t\t>\n\t\t\t\t\t\t{item.type === \"human\" && (\n\t\t\t\t\t\t\t<Avatar\n\t\t\t\t\t\t\t\tclassName={cn(\"size-full\")}\n\t\t\t\t\t\t\t\timage={item.agent.image}\n\t\t\t\t\t\t\t\tname={item.agent.name}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t{item.type === \"count\" && (\n\t\t\t\t\t\t\t<div className=\"flex size-full items-center justify-center rounded-full bg-co-background-200 font-medium text-co-text-900 text-sm dark:bg-co-background-500\">\n\t\t\t\t\t\t\t\t+{item.count}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t{item.type === \"ai\" && (\n\t\t\t\t\t\t\t<div className=\"flex size-full items-center justify-center rounded-full bg-co-background-200 dark:bg-co-background-600\">\n\t\t\t\t\t\t\t\t<CossistantLogo className=\"h-[50%] min-h-4 w-[50%] min-w-4\" />\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</AvatarStackItem>\n\t\t\t\t)),\n\t\t\t},\n\t\t}\n\t);\n}\n"],"mappings":";;;;;;;AAoBA,MAAa,mBAAmB,EAC/B,UACA,OACA,OAAO,IACP,UAAU,IACV,WAAW,GACX,gBAQK;CACL,MAAM,UAAU,UAAU;CAG1B,MAAM,eAAe,OAAO;CAC5B,MAAM,eAAe,eAAe;CACpC,MAAM,iBAAiB,GAAG,eAAe,QAAQ;AAEjD,QAAO,iBACN,OACA,EAAE,WAAW,EACb,EACC,OAAO;EACN,WAAW,GACV,oCACA,CAAC,WAAW,gDACZ;EACD,OAAO;GACN,OAAO,GAAG,KAAK;GACf,QAAQ,GAAG,KAAK;GAEhB,GAAI,UACD,EAAE,GACF;IACA,MAAM,mBAAmB,aAAa,KAAK,aAAa,QAAQ,eAAe,oBAAoB,aAAa,YAAY,aAAa;IACzI,YAAY,mBAAmB,aAAa,KAAK,aAAa,QAAQ,eAAe,oBAAoB,aAAa,YAAY,aAAa;IAC/I;GACH;EACD;EACA,EACD,CACD;;AAGF,SAAgB,YAAY,EAC3B,aACA,UACA,eAAe,OACf,qBAAqB,MACrB,WACA,OAAO,IACP,UAAU,IACV,WAAW,KACS;CACpB,MAAM,uBAAuB,YAAY,MAAM,GAAG,EAAE;CACpD,MAAM,4BAA4B,KAAK,IAAI,GAAG,YAAY,SAAS,EAAE;CAGrE,MAAM,QAAQ;EACb,GAAG,qBAAqB,KAAK,WAAW;GACvC,MAAM;GACN;GACA,EAAE;EACH,GAAI,4BAA4B,IAC7B,CACA;GACC,MAAM;GACN,OAAO;GACP,CACD,GACA,EAAE;EACL,GAAI,qBACD,EAAE,GACF,CACA;GACC,MAAM;GACN,OAAO,SAAS;GAChB,CACD;EACH;AAED,QAAO,iBACN,OACA,EAAE,WAAW,EACb,EACC,OAAO;EACN,WAAW;EACX,OAAO,EACN,qBAAqB,UAAU,MAAM,OAAO,IAAI,QAAQ,MACxD;EACD,UAAU,MAAM,KAAK,MAAM,UAC1B,qBAAC;GACU;GACH;GAED;GACG;;IAER,KAAK,SAAS,WACd,oBAAC;KACA,WAAW,GAAG,YAAY;KAC1B,OAAO,KAAK,MAAM;KAClB,MAAM,KAAK,MAAM;MAChB;IAEF,KAAK,SAAS,WACd,qBAAC;KAAI,WAAU;gBAA8I,KAC1J,KAAK;MACF;IAEN,KAAK,SAAS,QACd,oBAAC;KAAI,WAAU;eACd,oBAAC,kBAAe,WAAU,oCAAoC;MACzD;;KAnBF,UAAU,QAqBE,CACjB;EACF,EACD,CACD"}
1
+ {"version":3,"file":"avatar-stack.js","names":[],"sources":["../../../src/support/components/avatar-stack.tsx"],"sourcesContent":["import type { AvailableAIAgent, AvailableHumanAgent } from \"@cossistant/types\";\nimport type { ReactElement, ReactNode } from \"react\";\nimport { useRenderElement } from \"../../utils/use-render-element\";\nimport { cn } from \"../utils\";\nimport { Avatar } from \"./avatar\";\nimport { CossistantLogo } from \"./cossistant-branding\";\n\ntype AvatarStackProps = {\n\thumanAgents: AvailableHumanAgent[];\n\taiAgents: AvailableAIAgent[];\n\thideBranding?: boolean;\n\thideDefaultAIAgent?: boolean;\n\tclassName?: string;\n\t/** Size of avatars (default: 44px) */\n\tsize?: number;\n\t/** Space between avatars (default: 28px) */\n\tspacing?: number;\n\t/** Gap width between avatars (default: 2px) */\n\tgapWidth?: number;\n};\n\nexport const AvatarStackItem = ({\n\tchildren,\n\tindex,\n\tsize = 44,\n\tspacing = 28,\n\tgapWidth = 2,\n\tclassName,\n}: {\n\tchildren: ReactNode;\n\tindex: number;\n\tsize?: number;\n\tspacing?: number;\n\tgapWidth?: number;\n\tclassName?: string;\n}): ReactElement | null => {\n\tconst isFirst = index === 0;\n\n\t// Calculate the circle radius for the mask cutout\n\tconst circleRadius = size * 0.5;\n\tconst cutoutRadius = circleRadius + gapWidth; // Add gap width to create visible border\n\tconst cutoutPosition = `${circleRadius - spacing}px`;\n\n\treturn useRenderElement(\n\t\t\"div\",\n\t\t{ className },\n\t\t{\n\t\t\tprops: {\n\t\t\t\tclassName: cn(\n\t\t\t\t\t\"relative grid place-items-center\",\n\t\t\t\t\t!isFirst && \"[mask-repeat:no-repeat] [mask-size:100%_100%]\"\n\t\t\t\t),\n\t\t\t\tstyle: {\n\t\t\t\t\twidth: `${size}px`,\n\t\t\t\t\theight: `${size}px`,\n\t\t\t\t\t// Apply mask only to non-first items\n\t\t\t\t\t...(isFirst\n\t\t\t\t\t\t? {}\n\t\t\t\t\t\t: {\n\t\t\t\t\t\t\t\tmask: `radial-gradient(${cutoutRadius}px ${cutoutRadius}px at ${cutoutPosition} 50%, transparent ${cutoutRadius}px, white ${cutoutRadius}px)`,\n\t\t\t\t\t\t\t\tWebkitMask: `radial-gradient(${cutoutRadius}px ${cutoutRadius}px at ${cutoutPosition} 50%, transparent ${cutoutRadius}px, white ${cutoutRadius}px)`,\n\t\t\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t\tchildren,\n\t\t\t},\n\t\t}\n\t);\n};\n\n/**\n * Displays a compact row of agent avatars with optional branding and overflow\n * counts.\n */\nexport function AvatarStack({\n\thumanAgents,\n\taiAgents,\n\thideBranding = false,\n\thideDefaultAIAgent = true,\n\tclassName,\n\tsize = 44,\n\tspacing = 28,\n\tgapWidth = 3,\n}: AvatarStackProps): ReactElement | null {\n\tconst displayedHumanAgents = humanAgents.slice(0, 2);\n\tconst remainingHumanAgentsCount = Math.max(0, humanAgents.length - 2);\n\n\t// Create array of all items to display\n\tconst items = [\n\t\t...displayedHumanAgents.map((agent) => ({\n\t\t\ttype: \"human\" as const,\n\t\t\tagent,\n\t\t})),\n\t\t...(remainingHumanAgentsCount > 0\n\t\t\t? [\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: \"count\" as const,\n\t\t\t\t\t\tcount: remainingHumanAgentsCount,\n\t\t\t\t\t},\n\t\t\t\t]\n\t\t\t: []),\n\t\t...(hideDefaultAIAgent\n\t\t\t? []\n\t\t\t: [\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: \"ai\" as const,\n\t\t\t\t\t\tagent: aiAgents[0],\n\t\t\t\t\t},\n\t\t\t\t]),\n\t];\n\n\treturn useRenderElement(\n\t\t\"div\",\n\t\t{ className },\n\t\t{\n\t\t\tprops: {\n\t\t\t\tclassName: \"inline-grid items-center\",\n\t\t\t\tstyle: {\n\t\t\t\t\tgridTemplateColumns: `repeat(${items.length}, ${spacing}px)`,\n\t\t\t\t},\n\t\t\t\tchildren: items.map((item, index) => (\n\t\t\t\t\t<AvatarStackItem\n\t\t\t\t\t\tgapWidth={gapWidth}\n\t\t\t\t\t\tindex={index}\n\t\t\t\t\t\tkey={`avatar-${index}`}\n\t\t\t\t\t\tsize={size}\n\t\t\t\t\t\tspacing={spacing}\n\t\t\t\t\t>\n\t\t\t\t\t\t{item.type === \"human\" && (\n\t\t\t\t\t\t\t<Avatar\n\t\t\t\t\t\t\t\tclassName={cn(\"size-full\")}\n\t\t\t\t\t\t\t\timage={item.agent.image}\n\t\t\t\t\t\t\t\tname={item.agent.name}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t{item.type === \"count\" && (\n\t\t\t\t\t\t\t<div className=\"flex size-full items-center justify-center rounded-full bg-co-background-200 font-medium text-co-text-900 text-sm dark:bg-co-background-500\">\n\t\t\t\t\t\t\t\t+{item.count}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t{item.type === \"ai\" && (\n\t\t\t\t\t\t\t<div className=\"flex size-full items-center justify-center rounded-full bg-co-background-200 dark:bg-co-background-600\">\n\t\t\t\t\t\t\t\t<CossistantLogo className=\"h-[50%] min-h-4 w-[50%] min-w-4\" />\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</AvatarStackItem>\n\t\t\t\t)),\n\t\t\t},\n\t\t}\n\t);\n}\n"],"mappings":";;;;;;;AAqBA,MAAa,mBAAmB,EAC/B,UACA,OACA,OAAO,IACP,UAAU,IACV,WAAW,GACX,gBAQ0B;CAC1B,MAAM,UAAU,UAAU;CAG1B,MAAM,eAAe,OAAO;CAC5B,MAAM,eAAe,eAAe;CACpC,MAAM,iBAAiB,GAAG,eAAe,QAAQ;AAEjD,QAAO,iBACN,OACA,EAAE,WAAW,EACb,EACC,OAAO;EACN,WAAW,GACV,oCACA,CAAC,WAAW,gDACZ;EACD,OAAO;GACN,OAAO,GAAG,KAAK;GACf,QAAQ,GAAG,KAAK;GAEhB,GAAI,UACD,EAAE,GACF;IACA,MAAM,mBAAmB,aAAa,KAAK,aAAa,QAAQ,eAAe,oBAAoB,aAAa,YAAY,aAAa;IACzI,YAAY,mBAAmB,aAAa,KAAK,aAAa,QAAQ,eAAe,oBAAoB,aAAa,YAAY,aAAa;IAC/I;GACH;EACD;EACA,EACD,CACD;;;;;;AAOF,SAAgB,YAAY,EAC3B,aACA,UACA,eAAe,OACf,qBAAqB,MACrB,WACA,OAAO,IACP,UAAU,IACV,WAAW,KAC8B;CACzC,MAAM,uBAAuB,YAAY,MAAM,GAAG,EAAE;CACpD,MAAM,4BAA4B,KAAK,IAAI,GAAG,YAAY,SAAS,EAAE;CAGrE,MAAM,QAAQ;EACb,GAAG,qBAAqB,KAAK,WAAW;GACvC,MAAM;GACN;GACA,EAAE;EACH,GAAI,4BAA4B,IAC7B,CACA;GACC,MAAM;GACN,OAAO;GACP,CACD,GACA,EAAE;EACL,GAAI,qBACD,EAAE,GACF,CACA;GACC,MAAM;GACN,OAAO,SAAS;GAChB,CACD;EACH;AAED,QAAO,iBACN,OACA,EAAE,WAAW,EACb,EACC,OAAO;EACN,WAAW;EACX,OAAO,EACN,qBAAqB,UAAU,MAAM,OAAO,IAAI,QAAQ,MACxD;EACD,UAAU,MAAM,KAAK,MAAM,UAC1B,qBAAC;GACU;GACH;GAED;GACG;;IAER,KAAK,SAAS,WACd,oBAAC;KACA,WAAW,GAAG,YAAY;KAC1B,OAAO,KAAK,MAAM;KAClB,MAAM,KAAK,MAAM;MAChB;IAEF,KAAK,SAAS,WACd,qBAAC;KAAI,WAAU;gBAA8I,KAC1J,KAAK;MACF;IAEN,KAAK,SAAS,QACd,oBAAC;KAAI,WAAU;eACd,oBAAC,kBAAe,WAAU,oCAAoC;MACzD;;KAnBF,UAAU,QAqBE,CACjB;EACF,EACD,CACD"}