@cossistant/react 0.0.28 → 0.0.30

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 (301) hide show
  1. package/README.md +1 -1
  2. package/_virtual/rolldown_runtime.js +9 -23
  3. package/hooks/index.d.ts +3 -3
  4. package/hooks/private/store/use-conversations-store.d.ts +2 -0
  5. package/hooks/private/store/use-conversations-store.d.ts.map +1 -1
  6. package/hooks/private/store/use-conversations-store.js +15 -8
  7. package/hooks/private/store/use-conversations-store.js.map +1 -1
  8. package/hooks/private/store/use-store-selector.d.ts +3 -0
  9. package/hooks/private/store/use-store-selector.d.ts.map +1 -1
  10. package/hooks/private/store/use-store-selector.js +4 -8
  11. package/hooks/private/store/use-store-selector.js.map +1 -1
  12. package/hooks/private/store/use-website-store.d.ts +3 -1
  13. package/hooks/private/store/use-website-store.d.ts.map +1 -1
  14. package/hooks/private/store/use-website-store.js +14 -6
  15. package/hooks/private/store/use-website-store.js.map +1 -1
  16. package/hooks/private/use-client-query.d.ts +1 -1
  17. package/hooks/private/use-client-query.d.ts.map +1 -1
  18. package/hooks/private/use-client-query.js +1 -0
  19. package/hooks/private/use-client-query.js.map +1 -1
  20. package/hooks/private/use-default-messages.d.ts +1 -1
  21. package/hooks/private/use-grouped-messages.d.ts +10 -7
  22. package/hooks/private/use-grouped-messages.d.ts.map +1 -1
  23. package/hooks/private/use-grouped-messages.js +44 -11
  24. package/hooks/private/use-grouped-messages.js.map +1 -1
  25. package/hooks/private/use-rest-client.d.ts +13 -3
  26. package/hooks/private/use-rest-client.d.ts.map +1 -1
  27. package/hooks/private/use-rest-client.js +49 -22
  28. package/hooks/private/use-rest-client.js.map +1 -1
  29. package/hooks/private/use-visitor-typing-reporter.d.ts +1 -1
  30. package/hooks/use-conversation-auto-seen.d.ts +1 -1
  31. package/hooks/use-conversation-page.d.ts +1 -1
  32. package/hooks/use-conversation-page.d.ts.map +1 -1
  33. package/hooks/use-conversation-page.js +10 -3
  34. package/hooks/use-conversation-page.js.map +1 -1
  35. package/hooks/use-conversation-preview.d.ts +3 -1
  36. package/hooks/use-conversation-preview.d.ts.map +1 -1
  37. package/hooks/use-conversation-preview.js +6 -3
  38. package/hooks/use-conversation-preview.js.map +1 -1
  39. package/hooks/use-conversation-seen.d.ts +1 -1
  40. package/hooks/use-conversation-seen.js +1 -1
  41. package/hooks/use-conversation-seen.js.map +1 -1
  42. package/hooks/use-conversation-timeline-items.d.ts +1 -1
  43. package/hooks/use-conversation-timeline-items.js +2 -3
  44. package/hooks/use-conversation-timeline-items.js.map +1 -1
  45. package/hooks/use-conversation-timeline.d.ts +1 -1
  46. package/hooks/use-conversation-timeline.d.ts.map +1 -1
  47. package/hooks/use-conversation-timeline.js +1 -3
  48. package/hooks/use-conversation-timeline.js.map +1 -1
  49. package/hooks/use-conversation.d.ts +1 -1
  50. package/hooks/use-conversation.js +2 -3
  51. package/hooks/use-conversation.js.map +1 -1
  52. package/hooks/use-conversations.d.ts +1 -1
  53. package/hooks/use-conversations.js +5 -3
  54. package/hooks/use-conversations.js.map +1 -1
  55. package/hooks/use-create-conversation.d.ts +3 -3
  56. package/hooks/use-create-conversation.js +1 -0
  57. package/hooks/use-create-conversation.js.map +1 -1
  58. package/hooks/use-file-upload.d.ts +1 -1
  59. package/hooks/use-file-upload.js +3 -3
  60. package/hooks/use-file-upload.js.map +1 -1
  61. package/hooks/use-home-page.js +3 -3
  62. package/hooks/use-home-page.js.map +1 -1
  63. package/hooks/use-message-composer.d.ts +10 -3
  64. package/hooks/use-message-composer.d.ts.map +1 -1
  65. package/hooks/use-message-composer.js +5 -2
  66. package/hooks/use-message-composer.js.map +1 -1
  67. package/hooks/use-realtime-support.d.ts +1 -1
  68. package/hooks/use-send-message.d.ts +8 -2
  69. package/hooks/use-send-message.d.ts.map +1 -1
  70. package/hooks/use-send-message.js +5 -3
  71. package/hooks/use-send-message.js.map +1 -1
  72. package/hooks/use-visitor.js +2 -2
  73. package/hooks/use-visitor.js.map +1 -1
  74. package/identify-visitor.d.ts.map +1 -1
  75. package/identify-visitor.js +15 -1
  76. package/identify-visitor.js.map +1 -1
  77. package/index.d.ts +3 -3
  78. package/index.js +1 -1
  79. package/package.json +5 -3
  80. package/{conversation.d.ts → packages/types/src/api/conversation.d.ts} +368 -64
  81. package/packages/types/src/api/conversation.d.ts.map +1 -0
  82. package/packages/types/src/api/timeline-item.d.ts +460 -0
  83. package/packages/types/src/api/timeline-item.d.ts.map +1 -0
  84. package/packages/types/src/realtime-events.d.ts +1004 -0
  85. package/packages/types/src/realtime-events.d.ts.map +1 -0
  86. package/{schemas3.d.ts → packages/types/src/schemas.d.ts} +95 -19
  87. package/packages/types/src/schemas.d.ts.map +1 -0
  88. package/primitives/avatar/avatar.js +1 -1
  89. package/primitives/avatar/avatar.js.map +1 -1
  90. package/primitives/avatar/fallback.d.ts.map +1 -1
  91. package/primitives/avatar/fallback.js +2 -2
  92. package/primitives/avatar/fallback.js.map +1 -1
  93. package/primitives/avatar/image.d.ts +1 -1
  94. package/primitives/avatar/image.js +1 -1
  95. package/primitives/avatar/image.js.map +1 -1
  96. package/primitives/button.js +1 -1
  97. package/primitives/button.js.map +1 -1
  98. package/primitives/conversation-timeline.d.ts +1 -1
  99. package/primitives/conversation-timeline.js +4 -4
  100. package/primitives/conversation-timeline.js.map +1 -1
  101. package/primitives/day-separator.d.ts +76 -0
  102. package/primitives/day-separator.d.ts.map +1 -0
  103. package/primitives/day-separator.js +111 -0
  104. package/primitives/day-separator.js.map +1 -0
  105. package/primitives/index.d.ts +3 -2
  106. package/primitives/index.js +6 -1
  107. package/primitives/index.parts.d.ts +2 -1
  108. package/primitives/index.parts.js +2 -1
  109. package/primitives/multimodal-input.d.ts +2 -2
  110. package/primitives/multimodal-input.d.ts.map +1 -1
  111. package/primitives/multimodal-input.js +2 -2
  112. package/primitives/multimodal-input.js.map +1 -1
  113. package/primitives/timeline-item-attachments.d.ts +1 -1
  114. package/primitives/timeline-item-attachments.js +6 -7
  115. package/primitives/timeline-item-attachments.js.map +1 -1
  116. package/primitives/timeline-item-group.d.ts +1 -1
  117. package/primitives/timeline-item-group.d.ts.map +1 -1
  118. package/primitives/timeline-item-group.js +8 -8
  119. package/primitives/timeline-item-group.js.map +1 -1
  120. package/primitives/timeline-item.d.ts +1 -1
  121. package/primitives/timeline-item.d.ts.map +1 -1
  122. package/primitives/timeline-item.js +33 -8
  123. package/primitives/timeline-item.js.map +1 -1
  124. package/primitives/trigger.js +1 -1
  125. package/primitives/trigger.js.map +1 -1
  126. package/primitives/window.js +1 -1
  127. package/primitives/window.js.map +1 -1
  128. package/provider.d.ts +4 -2
  129. package/provider.d.ts.map +1 -1
  130. package/provider.js +56 -8
  131. package/provider.js.map +1 -1
  132. package/realtime/event-filter.d.ts +4 -1
  133. package/realtime/event-filter.d.ts.map +1 -1
  134. package/realtime/event-filter.js +14 -0
  135. package/realtime/event-filter.js.map +1 -1
  136. package/realtime/provider.d.ts +1 -1
  137. package/realtime/provider.d.ts.map +1 -1
  138. package/realtime/provider.js +1 -2
  139. package/realtime/provider.js.map +1 -1
  140. package/realtime/seen-store.d.ts +2 -2
  141. package/realtime/support-provider.js +6 -1
  142. package/realtime/support-provider.js.map +1 -1
  143. package/realtime/typing-store.d.ts +1 -1
  144. package/realtime/use-realtime.d.ts +1 -1
  145. package/support/components/avatar-stack.d.ts.map +1 -1
  146. package/support/components/avatar-stack.js +32 -12
  147. package/support/components/avatar-stack.js.map +1 -1
  148. package/support/components/avatar.d.ts +34 -3
  149. package/support/components/avatar.d.ts.map +1 -1
  150. package/support/components/avatar.js +61 -8
  151. package/support/components/avatar.js.map +1 -1
  152. package/support/components/button.d.ts +4 -2
  153. package/support/components/button.d.ts.map +1 -1
  154. package/support/components/button.js +3 -3
  155. package/support/components/button.js.map +1 -1
  156. package/support/components/configuration-error.d.ts +16 -0
  157. package/support/components/configuration-error.d.ts.map +1 -0
  158. package/support/components/configuration-error.js +162 -0
  159. package/support/components/configuration-error.js.map +1 -0
  160. package/support/components/content.js +1 -2
  161. package/support/components/content.js.map +1 -1
  162. package/support/components/conversation-button-link.js +18 -23
  163. package/support/components/conversation-button-link.js.map +1 -1
  164. package/support/components/conversation-event.d.ts.map +1 -1
  165. package/support/components/conversation-event.js +7 -5
  166. package/support/components/conversation-event.js.map +1 -1
  167. package/support/components/conversation-timeline.d.ts +6 -1
  168. package/support/components/conversation-timeline.d.ts.map +1 -1
  169. package/support/components/conversation-timeline.js +22 -2
  170. package/support/components/conversation-timeline.js.map +1 -1
  171. package/support/components/header.js +1 -1
  172. package/support/components/image-lightbox.d.ts +1 -1
  173. package/support/components/image-lightbox.js +1 -2
  174. package/support/components/image-lightbox.js.map +1 -1
  175. package/support/components/index.js +1 -1
  176. package/support/components/multimodal-input.js +0 -1
  177. package/support/components/multimodal-input.js.map +1 -1
  178. package/support/components/navigation-tab.js +1 -1
  179. package/support/components/online-indicator.d.ts +50 -0
  180. package/support/components/online-indicator.d.ts.map +1 -0
  181. package/support/components/online-indicator.js +65 -0
  182. package/support/components/online-indicator.js.map +1 -0
  183. package/support/components/root.js +0 -1
  184. package/support/components/root.js.map +1 -1
  185. package/support/components/timeline-identification-tool.js +4 -4
  186. package/support/components/timeline-identification-tool.js.map +1 -1
  187. package/support/components/timeline-message-group.d.ts +1 -1
  188. package/support/components/timeline-message-group.d.ts.map +1 -1
  189. package/support/components/timeline-message-group.js +6 -4
  190. package/support/components/timeline-message-group.js.map +1 -1
  191. package/support/components/timeline-message-item.d.ts +1 -1
  192. package/support/components/timeline-message-item.js +4 -4
  193. package/support/components/timeline-message-item.js.map +1 -1
  194. package/support/components/trigger.js +1 -2
  195. package/support/components/trigger.js.map +1 -1
  196. package/support/components/typing-indicator.js +1 -1
  197. package/support/components/typing-indicator.js.map +1 -1
  198. package/support/context/controlled-state.js +0 -1
  199. package/support/context/controlled-state.js.map +1 -1
  200. package/support/context/events.d.ts +1 -1
  201. package/support/context/events.js +0 -1
  202. package/support/context/events.js.map +1 -1
  203. package/support/context/handle.js +0 -1
  204. package/support/context/handle.js.map +1 -1
  205. package/support/context/identification.d.ts +33 -0
  206. package/support/context/identification.d.ts.map +1 -0
  207. package/support/context/identification.js +34 -0
  208. package/support/context/identification.js.map +1 -0
  209. package/support/context/positioning.js +0 -1
  210. package/support/context/positioning.js.map +1 -1
  211. package/support/context/slots.js +0 -1
  212. package/support/context/slots.js.map +1 -1
  213. package/support/context/websocket.d.ts +1 -1
  214. package/support/context/websocket.js +0 -1
  215. package/support/context/websocket.js.map +1 -1
  216. package/support/index.d.ts.map +1 -1
  217. package/support/index.js +51 -18
  218. package/support/index.js.map +1 -1
  219. package/support/pages/conversation-history.js +2 -1
  220. package/support/pages/conversation-history.js.map +1 -1
  221. package/support/pages/conversation.d.ts +1 -1
  222. package/support/pages/conversation.js +1 -1
  223. package/support/pages/conversation.js.map +1 -1
  224. package/support/pages/home.js +5 -3
  225. package/support/pages/home.js.map +1 -1
  226. package/support/router.d.ts.map +1 -1
  227. package/support/router.js +4 -0
  228. package/support/router.js.map +1 -1
  229. package/support/store/support-store.js +0 -1
  230. package/support/store/support-store.js.map +1 -1
  231. package/support/{support-C7Xaw-N6.css → support-DmViRaga.css} +2 -2
  232. package/support/{support-C7Xaw-N6.css.map → support-DmViRaga.css.map} +1 -1
  233. package/support/text/index.d.ts +1 -1
  234. package/support/text/index.d.ts.map +1 -1
  235. package/support/text/index.js +1 -1
  236. package/support/text/index.js.map +1 -1
  237. package/support/text/locales/en.js +1 -1
  238. package/support/text/locales/en.js.map +1 -1
  239. package/support/text/locales/es.js +1 -1
  240. package/support/text/locales/es.js.map +1 -1
  241. package/support/text/locales/fr.js +1 -1
  242. package/support/text/locales/fr.js.map +1 -1
  243. package/support/utils/index.d.ts +1 -1
  244. package/support-config.js +0 -1
  245. package/support-config.js.map +1 -1
  246. package/support.css +1 -1
  247. package/tailwind.css +1 -1
  248. package/utils/conversation.d.ts.map +1 -1
  249. package/utils/conversation.js +1 -3
  250. package/utils/conversation.js.map +1 -1
  251. package/utils/use-render-element.d.ts.map +1 -1
  252. package/utils/use-render-element.js +20 -5
  253. package/utils/use-render-element.js.map +1 -1
  254. package/api.d.ts +0 -71
  255. package/api.d.ts.map +0 -1
  256. package/checks.d.ts +0 -189
  257. package/checks.d.ts.map +0 -1
  258. package/clsx.d.ts +0 -7
  259. package/clsx.d.ts.map +0 -1
  260. package/coerce.d.ts +0 -9
  261. package/coerce.d.ts.map +0 -1
  262. package/conversation.d.ts.map +0 -1
  263. package/core.d.ts +0 -35
  264. package/core.d.ts.map +0 -1
  265. package/errors.d.ts +0 -121
  266. package/errors.d.ts.map +0 -1
  267. package/errors2.d.ts +0 -24
  268. package/errors2.d.ts.map +0 -1
  269. package/index2.d.ts +0 -4
  270. package/index3.d.ts +0 -1
  271. package/metadata.d.ts +0 -1
  272. package/openapi-generator.d.ts +0 -1
  273. package/openapi-generator2.d.ts +0 -1
  274. package/openapi-generator3.d.ts +0 -1
  275. package/openapi30.d.ts +0 -125
  276. package/openapi30.d.ts.map +0 -1
  277. package/openapi31.d.ts +0 -131
  278. package/openapi31.d.ts.map +0 -1
  279. package/parse.d.ts +0 -17
  280. package/parse.d.ts.map +0 -1
  281. package/realtime-events.d.ts +0 -482
  282. package/realtime-events.d.ts.map +0 -1
  283. package/registries.d.ts +0 -32
  284. package/registries.d.ts.map +0 -1
  285. package/schemas.d.ts +0 -673
  286. package/schemas.d.ts.map +0 -1
  287. package/schemas2.d.ts +0 -320
  288. package/schemas2.d.ts.map +0 -1
  289. package/schemas3.d.ts.map +0 -1
  290. package/specification-extension.d.ts +0 -9
  291. package/specification-extension.d.ts.map +0 -1
  292. package/standard-schema.d.ts +0 -59
  293. package/standard-schema.d.ts.map +0 -1
  294. package/timeline-item.d.ts +0 -227
  295. package/timeline-item.d.ts.map +0 -1
  296. package/util.d.ts +0 -41
  297. package/util.d.ts.map +0 -1
  298. package/versions.d.ts +0 -9
  299. package/versions.d.ts.map +0 -1
  300. package/zod-extensions.d.ts +0 -39
  301. package/zod-extensions.d.ts.map +0 -1
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Build fully featured customer support experiences in React with the official `@cossistant/react` package. The SDK wraps the REST and WebSocket APIs, comes with a prebuilt widget, hooks, and UI primitives so you can ship your support quickly and customize later.
4
4
 
5
- > 📚 **New to Cossistant?** Follow the [Quickstart guide](https://cossistant/docs/quickstart) in our official documentation.
5
+ > 📚 **New to Cossistant?** Follow the [Quickstart guide](https://cossistant.com/docs/quickstart) in our official documentation.
6
6
 
7
7
  ## Installation
8
8
 
@@ -1,32 +1,18 @@
1
1
  //#region rolldown:runtime
2
- var __create = Object.create;
3
2
  var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __export = (all) => {
3
+ var __export = (all, symbols) => {
9
4
  let target = {};
10
- for (var name in all) __defProp(target, name, {
11
- get: all[name],
12
- enumerable: true
13
- });
14
- return target;
15
- };
16
- var __copyProps = (to, from, except, desc) => {
17
- if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
18
- key = keys[i];
19
- if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
20
- get: ((k) => from[k]).bind(null, key),
21
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
5
+ for (var name in all) {
6
+ __defProp(target, name, {
7
+ get: all[name],
8
+ enumerable: true
22
9
  });
23
10
  }
24
- return to;
11
+ if (symbols) {
12
+ __defProp(target, Symbol.toStringTag, { value: "Module" });
13
+ }
14
+ return target;
25
15
  };
26
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
27
- value: mod,
28
- enumerable: true
29
- }) : target, mod));
30
16
 
31
17
  //#endregion
32
18
  export { __export };
package/hooks/index.d.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  import { useClientQuery } from "./private/use-client-query.js";
2
2
  import { useDefaultMessages } from "./private/use-default-messages.js";
3
- import { ConversationItem, GroupedMessage, TimelineEventItem, TimelineToolItem, UseGroupedMessagesOptions, UseGroupedMessagesProps, useGroupedMessages } from "./private/use-grouped-messages.js";
3
+ import { ConversationItem, DaySeparatorItem, GroupedMessage, TimelineEventItem, TimelineToolItem, UseGroupedMessagesOptions, UseGroupedMessagesProps, useGroupedMessages } from "./private/use-grouped-messages.js";
4
4
  import { UseMultimodalInputOptions, UseMultimodalInputReturn, useMultimodalInput } from "./private/use-multimodal-input.js";
5
- import { UseClientResult, useClient } from "./private/use-rest-client.js";
5
+ import { ConfigurationError, UseClientResult, useClient } from "./private/use-rest-client.js";
6
6
  import { UseComposerRefocusOptions, UseComposerRefocusReturn, useComposerRefocus } from "./use-composer-refocus.js";
7
7
  import { UseConversationOptions, UseConversationResult, useConversation } from "./use-conversation.js";
8
8
  import { CONVERSATION_AUTO_SEEN_DELAY_MS, UseConversationAutoSeenOptions, useConversationAutoSeen } from "./use-conversation-auto-seen.js";
@@ -27,4 +27,4 @@ import { UseSoundEffectOptions, UseSoundEffectReturn, useSoundEffect } from "./u
27
27
  import { useTypingSound } from "./use-typing-sound.js";
28
28
  import { UseVisitorReturn, useVisitor } from "./use-visitor.js";
29
29
  import { WindowVisibilityFocusState, useWindowVisibilityFocus } from "./use-window-visibility-focus.js";
30
- export { CONVERSATION_AUTO_SEEN_DELAY_MS, ConversationItem, ConversationLifecycleState, ConversationPreviewAssignedAgent, ConversationPreviewLastMessage, ConversationPreviewTypingParticipant, ConversationPreviewTypingState, ConversationTimelineTypingParticipant, ConversationTypingParticipant, CreateConversationVariables, FileUploadPart, GroupedMessage, SendMessageOptions, SendMessageResult, TimelineEventItem, TimelineToolItem, UseClientResult, UseComposerRefocusOptions, UseComposerRefocusReturn, UseConversationAutoSeenOptions, UseConversationHistoryPageOptions, UseConversationHistoryPageReturn, UseConversationLifecycleOptions, UseConversationLifecycleReturn, UseConversationOptions, UseConversationPageOptions, UseConversationPageReturn, UseConversationPreviewOptions, UseConversationPreviewReturn, UseConversationResult, UseConversationTimelineItemsOptions, UseConversationTimelineItemsResult, UseConversationTimelineOptions, UseConversationTimelineReturn, UseConversationsOptions, UseConversationsResult, UseCreateConversationOptions, UseCreateConversationResult, UseFileUploadOptions, UseFileUploadReturn, UseGroupedMessagesOptions, UseGroupedMessagesProps, UseHomePageOptions, UseHomePageReturn, UseMessageComposerOptions, UseMessageComposerReturn, UseMultimodalInputOptions, UseMultimodalInputReturn, UseRealtimeSupportOptions, UseRealtimeSupportResult, UseScrollMaskOptions, UseScrollMaskReturn, UseSendMessageOptions, UseSendMessageResult, UseSoundEffectOptions, UseSoundEffectReturn, UseVisitorReturn, WindowVisibilityFocusState, useClient, useClientQuery, useComposerRefocus, useConversation, useConversationAutoSeen, useConversationHistoryPage, useConversationLifecycle, useConversationPage, useConversationPreview, useConversationSeen, useConversationTimeline, useConversationTimelineItems, useConversationTyping, useConversations, useCreateConversation, useDebouncedConversationSeen, useDefaultMessages, useFileUpload, useGroupedMessages, useHomePage, useMessageComposer, useMultimodalInput, useNewMessageSound, useRealtimeSupport, useScrollMask, useSendMessage, useSoundEffect, useTypingSound, useVisitor, useWindowVisibilityFocus };
30
+ export { CONVERSATION_AUTO_SEEN_DELAY_MS, ConfigurationError, ConversationItem, ConversationLifecycleState, ConversationPreviewAssignedAgent, ConversationPreviewLastMessage, ConversationPreviewTypingParticipant, ConversationPreviewTypingState, ConversationTimelineTypingParticipant, ConversationTypingParticipant, CreateConversationVariables, DaySeparatorItem, FileUploadPart, GroupedMessage, SendMessageOptions, SendMessageResult, TimelineEventItem, TimelineToolItem, UseClientResult, UseComposerRefocusOptions, UseComposerRefocusReturn, UseConversationAutoSeenOptions, UseConversationHistoryPageOptions, UseConversationHistoryPageReturn, UseConversationLifecycleOptions, UseConversationLifecycleReturn, UseConversationOptions, UseConversationPageOptions, UseConversationPageReturn, UseConversationPreviewOptions, UseConversationPreviewReturn, UseConversationResult, UseConversationTimelineItemsOptions, UseConversationTimelineItemsResult, UseConversationTimelineOptions, UseConversationTimelineReturn, UseConversationsOptions, UseConversationsResult, UseCreateConversationOptions, UseCreateConversationResult, UseFileUploadOptions, UseFileUploadReturn, UseGroupedMessagesOptions, UseGroupedMessagesProps, UseHomePageOptions, UseHomePageReturn, UseMessageComposerOptions, UseMessageComposerReturn, UseMultimodalInputOptions, UseMultimodalInputReturn, UseRealtimeSupportOptions, UseRealtimeSupportResult, UseScrollMaskOptions, UseScrollMaskReturn, UseSendMessageOptions, UseSendMessageResult, UseSoundEffectOptions, UseSoundEffectReturn, UseVisitorReturn, WindowVisibilityFocusState, useClient, useClientQuery, useComposerRefocus, useConversation, useConversationAutoSeen, useConversationHistoryPage, useConversationLifecycle, useConversationPage, useConversationPreview, useConversationSeen, useConversationTimeline, useConversationTimelineItems, useConversationTyping, useConversations, useCreateConversation, useDebouncedConversationSeen, useDefaultMessages, useFileUpload, useGroupedMessages, useHomePage, useMessageComposer, useMultimodalInput, useNewMessageSound, useRealtimeSupport, useScrollMask, useSendMessage, useSoundEffect, useTypingSound, useVisitor, useWindowVisibilityFocus };
@@ -9,6 +9,8 @@ type ConversationSelection = {
9
9
  /**
10
10
  * Selector hook that exposes the normalized conversations list from the
11
11
  * internal store alongside pagination metadata.
12
+ *
13
+ * Returns empty selection when client is not available (configuration error).
12
14
  */
13
15
  declare function useConversationsStore(): ConversationSelection;
14
16
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"use-conversations-store.d.ts","names":[],"sources":["../../../../src/hooks/private/store/use-conversations-store.ts"],"sourcesContent":[],"mappings":";;;;KAQK,qBAAA;iBACW;EADX,UAAA,EAEQ,sBAFa,GACV,IAAA;AAwChB,CAAA;AA4BA;;;;iBA5BgB,qBAAA,CAAA,GAAyB;;;;;iBA4BzB,mBAAA,iCAEb"}
1
+ {"version":3,"file":"use-conversations-store.d.ts","names":[],"sources":["../../../../src/hooks/private/store/use-conversations-store.ts"],"sourcesContent":[],"mappings":";;;;KAQK,qBAAA;iBACW;EADX,UAAA,EAEQ,sBAFa,GACV,IAAA;AA+ChB,CAAA;AA2BA;;;;;;iBA3BgB,qBAAA,CAAA,GAAyB;;;;;iBA2BzB,mBAAA,iCAEb"}
@@ -2,6 +2,10 @@ import { useStoreSelector } from "./use-store-selector.js";
2
2
  import { useSupport } from "../../../provider.js";
3
3
 
4
4
  //#region src/hooks/private/store/use-conversations-store.ts
5
+ const EMPTY_SELECTION = {
6
+ conversations: [],
7
+ pagination: null
8
+ };
5
9
  function areSelectionsEqual(a, b) {
6
10
  if (a === b) return true;
7
11
  if (a.pagination !== b.pagination) {
@@ -15,14 +19,18 @@ function areSelectionsEqual(a, b) {
15
19
  /**
16
20
  * Selector hook that exposes the normalized conversations list from the
17
21
  * internal store alongside pagination metadata.
22
+ *
23
+ * Returns empty selection when client is not available (configuration error).
18
24
  */
19
25
  function useConversationsStore() {
20
26
  const { client } = useSupport();
21
- if (!client) throw new Error("useConversationsStore requires a configured Cossistant client");
22
- return useStoreSelector(client.conversationsStore, (state) => ({
23
- conversations: state.ids.map((id) => state.byId[id]).filter((conversation) => conversation !== void 0),
24
- pagination: state.pagination
25
- }), areSelectionsEqual);
27
+ return useStoreSelector(client?.conversationsStore ?? null, (state) => {
28
+ if (!state) return EMPTY_SELECTION;
29
+ return {
30
+ conversations: state.ids.map((id) => state.byId[id]).filter((conversation) => conversation !== void 0),
31
+ pagination: state.pagination
32
+ };
33
+ }, areSelectionsEqual);
26
34
  }
27
35
  /**
28
36
  * Picks a single conversation entity from the store by id. Returns `null` when
@@ -30,9 +38,8 @@ function useConversationsStore() {
30
38
  */
31
39
  function useConversationById(conversationId) {
32
40
  const { client } = useSupport();
33
- if (!client) throw new Error("useConversationById requires a configured Cossistant client");
34
- return useStoreSelector(client.conversationsStore, (state) => {
35
- if (!conversationId) return null;
41
+ return useStoreSelector(client?.conversationsStore ?? null, (state) => {
42
+ if (!(state && conversationId)) return null;
36
43
  return state.byId[conversationId] ?? null;
37
44
  });
38
45
  }
@@ -1 +1 @@
1
- {"version":3,"file":"use-conversations-store.js","names":[],"sources":["../../../../src/hooks/private/store/use-conversations-store.ts"],"sourcesContent":["import type {\n\tConversationPagination,\n\tConversationsState,\n} from \"@cossistant/core\";\nimport type { Conversation } from \"@cossistant/types\";\nimport { useSupport } from \"../../../provider\";\nimport { useStoreSelector } from \"./use-store-selector\";\n\ntype ConversationSelection = {\n\tconversations: Conversation[];\n\tpagination: ConversationPagination | null;\n};\n\nfunction areSelectionsEqual(\n\ta: ConversationSelection,\n\tb: ConversationSelection\n): boolean {\n\tif (a === b) {\n\t\treturn true;\n\t}\n\tif (a.pagination !== b.pagination) {\n\t\tif (!(a.pagination && b.pagination)) {\n\t\t\treturn false;\n\t\t}\n\t\tif (\n\t\t\ta.pagination.page !== b.pagination.page ||\n\t\t\ta.pagination.limit !== b.pagination.limit ||\n\t\t\ta.pagination.total !== b.pagination.total ||\n\t\t\ta.pagination.totalPages !== b.pagination.totalPages ||\n\t\t\ta.pagination.hasMore !== b.pagination.hasMore\n\t\t) {\n\t\t\treturn false;\n\t\t}\n\t}\n\tif (a.conversations.length !== b.conversations.length) {\n\t\treturn false;\n\t}\n\tfor (let index = 0; index < a.conversations.length; index += 1) {\n\t\tif (a.conversations[index] !== b.conversations[index]) {\n\t\t\treturn false;\n\t\t}\n\t}\n\treturn true;\n}\n\n/**\n * Selector hook that exposes the normalized conversations list from the\n * internal store alongside pagination metadata.\n */\nexport function useConversationsStore(): ConversationSelection {\n\tconst { client } = useSupport();\n\n\tif (!client) {\n\t\tthrow new Error(\n\t\t\t\"useConversationsStore requires a configured Cossistant client\"\n\t\t);\n\t}\n\n\treturn useStoreSelector(\n\t\tclient.conversationsStore,\n\t\t(state: ConversationsState) => ({\n\t\t\tconversations: state.ids\n\t\t\t\t.map((id) => state.byId[id])\n\t\t\t\t.filter(\n\t\t\t\t\t(conversation): conversation is Conversation =>\n\t\t\t\t\t\tconversation !== undefined\n\t\t\t\t),\n\t\t\tpagination: state.pagination,\n\t\t}),\n\t\tareSelectionsEqual\n\t);\n}\n\n/**\n * Picks a single conversation entity from the store by id. Returns `null` when\n * the identifier is missing or the entity has not been fetched yet.\n */\nexport function useConversationById(\n\tconversationId: string | null\n): Conversation | null {\n\tconst { client } = useSupport();\n\n\tif (!client) {\n\t\tthrow new Error(\n\t\t\t\"useConversationById requires a configured Cossistant client\"\n\t\t);\n\t}\n\n\treturn useStoreSelector(client.conversationsStore, (state) => {\n\t\tif (!conversationId) {\n\t\t\treturn null;\n\t\t}\n\t\treturn state.byId[conversationId] ?? null;\n\t});\n}\n"],"mappings":";;;;AAaA,SAAS,mBACR,GACA,GACU;AACV,KAAI,MAAM,EACT,QAAO;AAER,KAAI,EAAE,eAAe,EAAE,YAAY;AAClC,MAAI,EAAE,EAAE,cAAc,EAAE,YACvB,QAAO;AAER,MACC,EAAE,WAAW,SAAS,EAAE,WAAW,QACnC,EAAE,WAAW,UAAU,EAAE,WAAW,SACpC,EAAE,WAAW,UAAU,EAAE,WAAW,SACpC,EAAE,WAAW,eAAe,EAAE,WAAW,cACzC,EAAE,WAAW,YAAY,EAAE,WAAW,QAEtC,QAAO;;AAGT,KAAI,EAAE,cAAc,WAAW,EAAE,cAAc,OAC9C,QAAO;AAER,MAAK,IAAI,QAAQ,GAAG,QAAQ,EAAE,cAAc,QAAQ,SAAS,EAC5D,KAAI,EAAE,cAAc,WAAW,EAAE,cAAc,OAC9C,QAAO;AAGT,QAAO;;;;;;AAOR,SAAgB,wBAA+C;CAC9D,MAAM,EAAE,WAAW,YAAY;AAE/B,KAAI,CAAC,OACJ,OAAM,IAAI,MACT,gEACA;AAGF,QAAO,iBACN,OAAO,qBACN,WAA+B;EAC/B,eAAe,MAAM,IACnB,KAAK,OAAO,MAAM,KAAK,IAAI,CAC3B,QACC,iBACA,iBAAiB,OAClB;EACF,YAAY,MAAM;EAClB,GACD,mBACA;;;;;;AAOF,SAAgB,oBACf,gBACsB;CACtB,MAAM,EAAE,WAAW,YAAY;AAE/B,KAAI,CAAC,OACJ,OAAM,IAAI,MACT,8DACA;AAGF,QAAO,iBAAiB,OAAO,qBAAqB,UAAU;AAC7D,MAAI,CAAC,eACJ,QAAO;AAER,SAAO,MAAM,KAAK,mBAAmB;GACpC"}
1
+ {"version":3,"file":"use-conversations-store.js","names":["EMPTY_SELECTION: ConversationSelection"],"sources":["../../../../src/hooks/private/store/use-conversations-store.ts"],"sourcesContent":["import type {\n\tConversationPagination,\n\tConversationsState,\n} from \"@cossistant/core\";\nimport type { Conversation } from \"@cossistant/types\";\nimport { useSupport } from \"../../../provider\";\nimport { useStoreSelector } from \"./use-store-selector\";\n\ntype ConversationSelection = {\n\tconversations: Conversation[];\n\tpagination: ConversationPagination | null;\n};\n\nconst EMPTY_SELECTION: ConversationSelection = {\n\tconversations: [],\n\tpagination: null,\n};\n\nfunction areSelectionsEqual(\n\ta: ConversationSelection,\n\tb: ConversationSelection\n): boolean {\n\tif (a === b) {\n\t\treturn true;\n\t}\n\tif (a.pagination !== b.pagination) {\n\t\tif (!(a.pagination && b.pagination)) {\n\t\t\treturn false;\n\t\t}\n\t\tif (\n\t\t\ta.pagination.page !== b.pagination.page ||\n\t\t\ta.pagination.limit !== b.pagination.limit ||\n\t\t\ta.pagination.total !== b.pagination.total ||\n\t\t\ta.pagination.totalPages !== b.pagination.totalPages ||\n\t\t\ta.pagination.hasMore !== b.pagination.hasMore\n\t\t) {\n\t\t\treturn false;\n\t\t}\n\t}\n\tif (a.conversations.length !== b.conversations.length) {\n\t\treturn false;\n\t}\n\tfor (let index = 0; index < a.conversations.length; index += 1) {\n\t\tif (a.conversations[index] !== b.conversations[index]) {\n\t\t\treturn false;\n\t\t}\n\t}\n\treturn true;\n}\n\n/**\n * Selector hook that exposes the normalized conversations list from the\n * internal store alongside pagination metadata.\n *\n * Returns empty selection when client is not available (configuration error).\n */\nexport function useConversationsStore(): ConversationSelection {\n\tconst { client } = useSupport();\n\n\treturn useStoreSelector(\n\t\tclient?.conversationsStore ?? null,\n\t\t(state: ConversationsState | null) => {\n\t\t\tif (!state) {\n\t\t\t\treturn EMPTY_SELECTION;\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tconversations: state.ids\n\t\t\t\t\t.map((id) => state.byId[id])\n\t\t\t\t\t.filter(\n\t\t\t\t\t\t(conversation): conversation is Conversation =>\n\t\t\t\t\t\t\tconversation !== undefined\n\t\t\t\t\t),\n\t\t\t\tpagination: state.pagination,\n\t\t\t};\n\t\t},\n\t\tareSelectionsEqual\n\t);\n}\n\n/**\n * Picks a single conversation entity from the store by id. Returns `null` when\n * the identifier is missing or the entity has not been fetched yet.\n */\nexport function useConversationById(\n\tconversationId: string | null\n): Conversation | null {\n\tconst { client } = useSupport();\n\n\treturn useStoreSelector(\n\t\tclient?.conversationsStore ?? null,\n\t\t(state: ConversationsState | null) => {\n\t\t\tif (!(state && conversationId)) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\treturn state.byId[conversationId] ?? null;\n\t\t}\n\t);\n}\n"],"mappings":";;;;AAaA,MAAMA,kBAAyC;CAC9C,eAAe,EAAE;CACjB,YAAY;CACZ;AAED,SAAS,mBACR,GACA,GACU;AACV,KAAI,MAAM,EACT,QAAO;AAER,KAAI,EAAE,eAAe,EAAE,YAAY;AAClC,MAAI,EAAE,EAAE,cAAc,EAAE,YACvB,QAAO;AAER,MACC,EAAE,WAAW,SAAS,EAAE,WAAW,QACnC,EAAE,WAAW,UAAU,EAAE,WAAW,SACpC,EAAE,WAAW,UAAU,EAAE,WAAW,SACpC,EAAE,WAAW,eAAe,EAAE,WAAW,cACzC,EAAE,WAAW,YAAY,EAAE,WAAW,QAEtC,QAAO;;AAGT,KAAI,EAAE,cAAc,WAAW,EAAE,cAAc,OAC9C,QAAO;AAER,MAAK,IAAI,QAAQ,GAAG,QAAQ,EAAE,cAAc,QAAQ,SAAS,EAC5D,KAAI,EAAE,cAAc,WAAW,EAAE,cAAc,OAC9C,QAAO;AAGT,QAAO;;;;;;;;AASR,SAAgB,wBAA+C;CAC9D,MAAM,EAAE,WAAW,YAAY;AAE/B,QAAO,iBACN,QAAQ,sBAAsB,OAC7B,UAAqC;AACrC,MAAI,CAAC,MACJ,QAAO;AAER,SAAO;GACN,eAAe,MAAM,IACnB,KAAK,OAAO,MAAM,KAAK,IAAI,CAC3B,QACC,iBACA,iBAAiB,OAClB;GACF,YAAY,MAAM;GAClB;IAEF,mBACA;;;;;;AAOF,SAAgB,oBACf,gBACsB;CACtB,MAAM,EAAE,WAAW,YAAY;AAE/B,QAAO,iBACN,QAAQ,sBAAsB,OAC7B,UAAqC;AACrC,MAAI,EAAE,SAAS,gBACd,QAAO;AAER,SAAO,MAAM,KAAK,mBAAmB;GAEtC"}
@@ -7,8 +7,11 @@ type BasicStore<TState> = {
7
7
  /**
8
8
  * React hook that bridges Zustand-like stores with React components by
9
9
  * memoizing selector results and resubscribing when dependencies change.
10
+ *
11
+ * Overloaded to support both nullable and non-nullable stores.
10
12
  */
11
13
  declare function useStoreSelector<TState, TSelected>(store: BasicStore<TState>, selector: (state: TState) => TSelected, isEqual?: (previous: TSelected, next: TSelected) => boolean): TSelected;
14
+ declare function useStoreSelector<TState, TSelected>(store: BasicStore<TState> | null, selector: (state: TState | null) => TSelected, isEqual?: (previous: TSelected, next: TSelected) => boolean): TSelected;
12
15
  //#endregion
13
16
  export { useStoreSelector };
14
17
  //# sourceMappingURL=use-store-selector.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-store-selector.d.ts","names":[],"sources":["../../../../src/hooks/private/store/use-store-selector.ts"],"sourcesContent":[],"mappings":";KAEK,+BAA+B;KAE/B,UAFA,CAAA,MAAY,CAAA,GAAA;EAEZ,QAAA,EAAA,EACQ,MADE;EACF,SAAA,CAAA,QAAA,EACQ,YADR,CACqB,MADrB,CAAA,CAAA,EAAA,GAAA,GAAA,IAAA;CACqB;;;AAOlC;;AACQ,iBADQ,gBACR,CAAA,MAAA,EAAA,SAAA,CAAA,CAAA,KAAA,EAAA,UAAA,CAAW,MAAX,CAAA,EAAA,QAAA,EAAA,CAAA,KAAA,EACW,MADX,EAAA,GACsB,SADtB,EAAA,OAAA,CAAA,EAAA,CAAA,QAAA,EAEa,SAFb,EAAA,IAAA,EAE8B,SAF9B,EAAA,GAAA,OAAA,CAAA,EAGL,SAHK"}
1
+ {"version":3,"file":"use-store-selector.d.ts","names":[],"sources":["../../../../src/hooks/private/store/use-store-selector.ts"],"sourcesContent":[],"mappings":";KAEK,+BAA+B;KAE/B,UAFA,CAAA,MAAY,CAAA,GAAA;EAEZ,QAAA,EAAA,EACQ,MADE;EACF,SAAA,CAAA,QAAA,EACQ,YADR,CACqB,MADrB,CAAA,CAAA,EAAA,GAAA,GAAA,IAAA;CACqB;;;AAYlC;;;;AAE8B,iBAFd,gBAEc,CAAA,MAAA,EAAA,SAAA,CAAA,CAAA,KAAA,EADtB,UACsB,CADX,MACW,CAAA,EAAA,QAAA,EAAA,CAAA,KAAA,EAAX,MAAW,EAAA,GAAA,SAAA,EAAA,OAAA,CAAA,EAAA,CAAA,QAAA,EACR,SADQ,EAAA,IAAA,EACS,SADT,EAAA,GAAA,OAAA,CAAA,EAE3B,SAF2B;AACR,iBAGN,gBAHM,CAAA,MAAA,EAAA,SAAA,CAAA,CAAA,KAAA,EAId,UAJc,CAIH,MAJG,CAAA,GAAA,IAAA,EAAA,QAAA,EAAA,CAAA,KAAA,EAKH,MALG,GAAA,IAAA,EAAA,GAKe,SALf,EAAA,OAAA,CAAA,EAAA,CAAA,QAAA,EAMA,SANA,EAAA,IAAA,EAMiB,SANjB,EAAA,GAAA,OAAA,CAAA,EAOnB,SAPmB"}
@@ -1,16 +1,12 @@
1
1
  import { useRef, useSyncExternalStore } from "react";
2
2
 
3
3
  //#region src/hooks/private/store/use-store-selector.ts
4
- /**
5
- * React hook that bridges Zustand-like stores with React components by
6
- * memoizing selector results and resubscribing when dependencies change.
7
- */
4
+ const noopSubscribe = () => () => {};
8
5
  function useStoreSelector(store, selector, isEqual = Object.is) {
9
6
  const selectionRef = useRef(void 0);
10
- const subscribe = (onStoreChange) => store.subscribe(() => {
11
- onStoreChange();
12
- });
13
- const selected = selector(useSyncExternalStore(subscribe, () => store.getState(), () => store.getState()));
7
+ const subscribe = store ? (onStoreChange) => store.subscribe(() => onStoreChange()) : noopSubscribe;
8
+ const getSnapshot = store ? () => store.getState() : () => null;
9
+ const selected = selector(useSyncExternalStore(subscribe, getSnapshot, getSnapshot));
14
10
  if (selectionRef.current === void 0 || !isEqual(selectionRef.current, selected)) selectionRef.current = selected;
15
11
  return selectionRef.current;
16
12
  }
@@ -1 +1 @@
1
- {"version":3,"file":"use-store-selector.js","names":[],"sources":["../../../../src/hooks/private/store/use-store-selector.ts"],"sourcesContent":["import { useRef, useSyncExternalStore } from \"react\";\n\ntype Subscription<TState> = (state: TState) => void;\n\ntype BasicStore<TState> = {\n\tgetState(): TState;\n\tsubscribe(listener: Subscription<TState>): () => void;\n};\n\n/**\n * React hook that bridges Zustand-like stores with React components by\n * memoizing selector results and resubscribing when dependencies change.\n */\nexport function useStoreSelector<TState, TSelected>(\n\tstore: BasicStore<TState>,\n\tselector: (state: TState) => TSelected,\n\tisEqual: (previous: TSelected, next: TSelected) => boolean = 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\t() => store.getState(),\n\t\t() => store.getState()\n\t);\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"],"mappings":";;;;;;;AAaA,SAAgB,iBACf,OACA,UACA,UAA6D,OAAO,IACxD;CACZ,MAAM,eAAe,OAAkB,OAAU;CAEjD,MAAM,aAAa,kBAClB,MAAM,gBAAgB;AACrB,iBAAe;GACd;CAOH,MAAM,WAAW,SALA,qBAChB,iBACM,MAAM,UAAU,QAChB,MAAM,UAAU,CACtB,CACkC;AAEnC,KACC,aAAa,YAAY,UACzB,CAAC,QAAQ,aAAa,SAAS,SAAS,CAExC,cAAa,UAAU;AAGxB,QAAO,aAAa"}
1
+ {"version":3,"file":"use-store-selector.js","names":[],"sources":["../../../../src/hooks/private/store/use-store-selector.ts"],"sourcesContent":["import { useRef, useSyncExternalStore } from \"react\";\n\ntype Subscription<TState> = (state: TState) => void;\n\ntype BasicStore<TState> = {\n\tgetState(): TState;\n\tsubscribe(listener: Subscription<TState>): () => void;\n};\n\n// No-op subscribe function for null store case\nconst noopSubscribe = () => () => {};\n\n/**\n * React hook that bridges Zustand-like stores with React components by\n * memoizing selector results and resubscribing when dependencies change.\n *\n * Overloaded to support both nullable and non-nullable stores.\n */\nexport function useStoreSelector<TState, TSelected>(\n\tstore: BasicStore<TState>,\n\tselector: (state: TState) => TSelected,\n\tisEqual?: (previous: TSelected, next: TSelected) => boolean\n): TSelected;\n\nexport function useStoreSelector<TState, TSelected>(\n\tstore: BasicStore<TState> | null,\n\tselector: (state: TState | null) => TSelected,\n\tisEqual?: (previous: TSelected, next: TSelected) => boolean\n): TSelected;\n\nexport function useStoreSelector<TState, TSelected>(\n\tstore: BasicStore<TState> | null,\n\tselector: (state: TState | null) => TSelected,\n\tisEqual: (previous: TSelected, next: TSelected) => boolean = Object.is\n): TSelected {\n\tconst selectionRef = useRef<TSelected>(undefined);\n\n\t// Create stable subscribe function\n\tconst subscribe = store\n\t\t? (onStoreChange: () => void) => store.subscribe(() => onStoreChange())\n\t\t: noopSubscribe;\n\n\t// Create stable getSnapshot function\n\tconst getSnapshot = store ? () => store.getState() : () => null;\n\n\t// Always call useSyncExternalStore unconditionally\n\tconst snapshot = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\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"],"mappings":";;;AAUA,MAAM,4BAA4B;AAoBlC,SAAgB,iBACf,OACA,UACA,UAA6D,OAAO,IACxD;CACZ,MAAM,eAAe,OAAkB,OAAU;CAGjD,MAAM,YAAY,SACd,kBAA8B,MAAM,gBAAgB,eAAe,CAAC,GACrE;CAGH,MAAM,cAAc,cAAc,MAAM,UAAU,SAAS;CAK3D,MAAM,WAAW,SAFA,qBAAqB,WAAW,aAAa,YAAY,CAEvC;AAEnC,KACC,aAAa,YAAY,UACzB,CAAC,QAAQ,aAAa,SAAS,SAAS,CAExC,cAAa,UAAU;AAGxB,QAAO,aAAa"}
@@ -15,8 +15,10 @@ type UseWebsiteStoreOptions = {
15
15
  /**
16
16
  * Subscribes to the shared website store on the SDK client and exposes
17
17
  * convenient loading/error state plus a manual refresh helper.
18
+ *
19
+ * When client is null (e.g., due to configuration error), returns an idle state.
18
20
  */
19
- declare function useWebsiteStore(client: CossistantClient, options?: UseWebsiteStoreOptions): UseWebsiteStoreResult;
21
+ declare function useWebsiteStore(client: CossistantClient | null, options?: UseWebsiteStoreOptions): UseWebsiteStoreResult;
20
22
  //#endregion
21
23
  export { UseWebsiteStoreOptions, UseWebsiteStoreResult, useWebsiteStore };
22
24
  //# sourceMappingURL=use-website-store.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-website-store.d.ts","names":[],"sources":["../../../../src/hooks/private/store/use-website-store.ts"],"sourcesContent":[],"mappings":";;;KAgBY,qBAAA;WACF;EADE,MAAA,EAEH,YAFG,CAAA,QAAqB,CAAA;EACvB,SAAA,EAAA,OAAA;EACD,KAAA,EAED,KAFC,GAAA,IAAA;EAED,OAAA,EAAA,GAAA,GACQ,OADR,CACgB,YADhB,CAAA,SAAA,CAAA,GAAA,IAAA,CAAA;CACgB;AAAR,KAGJ,sBAAA,GAHI;EAAO,eAAA,CAAA,EAAA,MAAA,GAAA,KAAA;EAGX,oBAAA,CAAA,EAAA,OAAsB;AAqBlC,CAAA;;;;;iBAAgB,eAAA,SACP,4BACC,yBACP"}
1
+ {"version":3,"file":"use-website-store.d.ts","names":[],"sources":["../../../../src/hooks/private/store/use-website-store.ts"],"sourcesContent":[],"mappings":";;;KAgBY,qBAAA;WACF;EADE,MAAA,EAEH,YAFG,CAAA,QAAqB,CAAA;EACvB,SAAA,EAAA,OAAA;EACD,KAAA,EAED,KAFC,GAAA,IAAA;EAED,OAAA,EAAA,GAAA,GACQ,OADR,CACgB,YADhB,CAAA,SAAA,CAAA,GAAA,IAAA,CAAA;CACgB;AAAR,KAGJ,sBAAA,GAHI;EAAO,eAAA,CAAA,EAAA,MAAA,GAAA,KAAA;EAGX,oBAAA,CAAA,EAAA,OAAsB;AAuBlC,CAAA;;;;;;;iBAAgB,eAAA,SACP,mCACC,yBACP"}
@@ -3,6 +3,11 @@ import { useStoreSelector } from "./use-store-selector.js";
3
3
  import { useMemo } from "react";
4
4
 
5
5
  //#region src/hooks/private/store/use-website-store.ts
6
+ const EMPTY_STATE = {
7
+ website: null,
8
+ status: "idle",
9
+ error: null
10
+ };
6
11
  function toError(state, fallback) {
7
12
  if (fallback) return fallback;
8
13
  if (!state.error) return null;
@@ -11,24 +16,27 @@ function toError(state, fallback) {
11
16
  /**
12
17
  * Subscribes to the shared website store on the SDK client and exposes
13
18
  * convenient loading/error state plus a manual refresh helper.
19
+ *
20
+ * When client is null (e.g., due to configuration error), returns an idle state.
14
21
  */
15
22
  function useWebsiteStore(client, options = {}) {
16
- const state = useStoreSelector(client.websiteStore ?? (() => {
17
- throw new Error("Website store is not available on the client instance");
18
- })(), (current) => current);
23
+ const state = useStoreSelector(client?.websiteStore ?? null, (current) => current ? current : EMPTY_STATE);
19
24
  const query = useClientQuery({
20
25
  client,
21
26
  queryKey: "website",
22
27
  queryFn: (instance, params) => instance.fetchWebsite(params ?? {}),
23
- enabled: true,
28
+ enabled: client !== null,
24
29
  refetchInterval: options.refetchInterval ?? false,
25
30
  refetchOnWindowFocus: options.refetchOnWindowFocus ?? false,
26
31
  refetchOnMount: state.status === "idle",
27
32
  initialData: state.website ?? void 0
28
33
  });
29
34
  const error = useMemo(() => toError(state, query.error), [state, query.error]);
30
- const isLoading = query.isLoading || state.status === "loading" || state.status === "idle";
31
- const refresh = () => query.refetch({ force: true }).then((result) => result ?? client.websiteStore.getState().website).catch(() => client.websiteStore.getState().website).then((website) => website ?? null);
35
+ const isLoading = client !== null && (query.isLoading || state.status === "loading" || state.status === "idle");
36
+ const refresh = () => {
37
+ if (!client) return Promise.resolve(null);
38
+ return query.refetch({ force: true }).then((result) => result ?? client.websiteStore.getState().website).catch(() => client.websiteStore.getState().website).then((website) => website ?? null);
39
+ };
32
40
  return {
33
41
  website: state.website,
34
42
  status: state.status,
@@ -1 +1 @@
1
- {"version":3,"file":"use-website-store.js","names":[],"sources":["../../../../src/hooks/private/store/use-website-store.ts"],"sourcesContent":["import type {\n\tCossistantClient,\n\tWebsiteState,\n\tWebsiteStore,\n} from \"@cossistant/core\";\nimport type { PublicWebsiteResponse } from \"@cossistant/types\";\nimport { useMemo } from \"react\";\nimport { useClientQuery } from \"../use-client-query\";\nimport { useStoreSelector } from \"./use-store-selector\";\n\nconst EMPTY_STATE: WebsiteState = {\n\twebsite: null,\n\tstatus: \"idle\",\n\terror: null,\n};\n\nexport type UseWebsiteStoreResult = {\n\twebsite: WebsiteState[\"website\"];\n\tstatus: WebsiteState[\"status\"];\n\tisLoading: boolean;\n\terror: Error | null;\n\trefresh: () => Promise<WebsiteState[\"website\"] | null>;\n};\n\nexport type UseWebsiteStoreOptions = {\n\trefetchInterval?: number | false;\n\trefetchOnWindowFocus?: boolean;\n};\n\nfunction toError(state: WebsiteState, fallback: Error | null): Error | null {\n\tif (fallback) {\n\t\treturn fallback;\n\t}\n\n\tif (!state.error) {\n\t\treturn null;\n\t}\n\n\treturn new Error(state.error.message);\n}\n\n/**\n * Subscribes to the shared website store on the SDK client and exposes\n * convenient loading/error state plus a manual refresh helper.\n */\nexport function useWebsiteStore(\n\tclient: CossistantClient,\n\toptions: UseWebsiteStoreOptions = {}\n): UseWebsiteStoreResult {\n\tconst store =\n\t\tclient.websiteStore ??\n\t\t((): WebsiteStore => {\n\t\t\tthrow new Error(\"Website store is not available on the client instance\");\n\t\t})();\n\tconst state = useStoreSelector(store, (current) => current);\n\n\tconst query = useClientQuery<PublicWebsiteResponse, { force?: boolean }>({\n\t\tclient,\n\t\tqueryKey: \"website\",\n\t\tqueryFn: (instance, params) => instance.fetchWebsite(params ?? {}),\n\t\tenabled: true,\n\t\trefetchInterval: options.refetchInterval ?? false,\n\t\trefetchOnWindowFocus: options.refetchOnWindowFocus ?? false,\n\t\trefetchOnMount: state.status === \"idle\",\n\t\tinitialData: state.website ?? undefined,\n\t});\n\n\tconst error = useMemo(\n\t\t() => toError(state, query.error),\n\t\t[state, query.error]\n\t);\n\tconst isLoading =\n\t\tquery.isLoading || state.status === \"loading\" || state.status === \"idle\";\n\n\tconst refresh = () =>\n\t\tquery\n\t\t\t.refetch({ force: true })\n\t\t\t.then((result) => result ?? client.websiteStore.getState().website)\n\t\t\t.catch(() => client.websiteStore.getState().website)\n\t\t\t.then((website) => website ?? null);\n\n\treturn {\n\t\twebsite: state.website,\n\t\tstatus: state.status,\n\t\tisLoading,\n\t\terror,\n\t\trefresh,\n\t};\n}\n"],"mappings":";;;;;AA6BA,SAAS,QAAQ,OAAqB,UAAsC;AAC3E,KAAI,SACH,QAAO;AAGR,KAAI,CAAC,MAAM,MACV,QAAO;AAGR,QAAO,IAAI,MAAM,MAAM,MAAM,QAAQ;;;;;;AAOtC,SAAgB,gBACf,QACA,UAAkC,EAAE,EACZ;CAMxB,MAAM,QAAQ,iBAJb,OAAO,uBACc;AACpB,QAAM,IAAI,MAAM,wDAAwD;KACrE,GACkC,YAAY,QAAQ;CAE3D,MAAM,QAAQ,eAA2D;EACxE;EACA,UAAU;EACV,UAAU,UAAU,WAAW,SAAS,aAAa,UAAU,EAAE,CAAC;EAClE,SAAS;EACT,iBAAiB,QAAQ,mBAAmB;EAC5C,sBAAsB,QAAQ,wBAAwB;EACtD,gBAAgB,MAAM,WAAW;EACjC,aAAa,MAAM,WAAW;EAC9B,CAAC;CAEF,MAAM,QAAQ,cACP,QAAQ,OAAO,MAAM,MAAM,EACjC,CAAC,OAAO,MAAM,MAAM,CACpB;CACD,MAAM,YACL,MAAM,aAAa,MAAM,WAAW,aAAa,MAAM,WAAW;CAEnE,MAAM,gBACL,MACE,QAAQ,EAAE,OAAO,MAAM,CAAC,CACxB,MAAM,WAAW,UAAU,OAAO,aAAa,UAAU,CAAC,QAAQ,CAClE,YAAY,OAAO,aAAa,UAAU,CAAC,QAAQ,CACnD,MAAM,YAAY,WAAW,KAAK;AAErC,QAAO;EACN,SAAS,MAAM;EACf,QAAQ,MAAM;EACd;EACA;EACA;EACA"}
1
+ {"version":3,"file":"use-website-store.js","names":["EMPTY_STATE: WebsiteState"],"sources":["../../../../src/hooks/private/store/use-website-store.ts"],"sourcesContent":["import type {\n\tCossistantClient,\n\tWebsiteState,\n\tWebsiteStore,\n} from \"@cossistant/core\";\nimport type { PublicWebsiteResponse } from \"@cossistant/types\";\nimport { useMemo } from \"react\";\nimport { useClientQuery } from \"../use-client-query\";\nimport { useStoreSelector } from \"./use-store-selector\";\n\nconst EMPTY_STATE: WebsiteState = {\n\twebsite: null,\n\tstatus: \"idle\",\n\terror: null,\n};\n\nexport type UseWebsiteStoreResult = {\n\twebsite: WebsiteState[\"website\"];\n\tstatus: WebsiteState[\"status\"];\n\tisLoading: boolean;\n\terror: Error | null;\n\trefresh: () => Promise<WebsiteState[\"website\"] | null>;\n};\n\nexport type UseWebsiteStoreOptions = {\n\trefetchInterval?: number | false;\n\trefetchOnWindowFocus?: boolean;\n};\n\nfunction toError(state: WebsiteState, fallback: Error | null): Error | null {\n\tif (fallback) {\n\t\treturn fallback;\n\t}\n\n\tif (!state.error) {\n\t\treturn null;\n\t}\n\n\treturn new Error(state.error.message);\n}\n\n/**\n * Subscribes to the shared website store on the SDK client and exposes\n * convenient loading/error state plus a manual refresh helper.\n *\n * When client is null (e.g., due to configuration error), returns an idle state.\n */\nexport function useWebsiteStore(\n\tclient: CossistantClient | null,\n\toptions: UseWebsiteStoreOptions = {}\n): UseWebsiteStoreResult {\n\t// Handle null client (configuration error case)\n\tconst store = client?.websiteStore ?? null;\n\n\tconst state = useStoreSelector(store, (current) =>\n\t\tcurrent ? current : EMPTY_STATE\n\t);\n\n\tconst query = useClientQuery<PublicWebsiteResponse, { force?: boolean }>({\n\t\tclient,\n\t\tqueryKey: \"website\",\n\t\tqueryFn: (instance, params) => instance.fetchWebsite(params ?? {}),\n\t\tenabled: client !== null,\n\t\trefetchInterval: options.refetchInterval ?? false,\n\t\trefetchOnWindowFocus: options.refetchOnWindowFocus ?? false,\n\t\trefetchOnMount: state.status === \"idle\",\n\t\tinitialData: state.website ?? undefined,\n\t});\n\n\tconst error = useMemo(\n\t\t() => toError(state, query.error),\n\t\t[state, query.error]\n\t);\n\tconst isLoading =\n\t\tclient !== null &&\n\t\t(query.isLoading || state.status === \"loading\" || state.status === \"idle\");\n\n\tconst refresh = () => {\n\t\tif (!client) {\n\t\t\treturn Promise.resolve(null);\n\t\t}\n\t\treturn query\n\t\t\t.refetch({ force: true })\n\t\t\t.then((result) => result ?? client.websiteStore.getState().website)\n\t\t\t.catch(() => client.websiteStore.getState().website)\n\t\t\t.then((website) => website ?? null);\n\t};\n\n\treturn {\n\t\twebsite: state.website,\n\t\tstatus: state.status,\n\t\tisLoading,\n\t\terror,\n\t\trefresh,\n\t};\n}\n"],"mappings":";;;;;AAUA,MAAMA,cAA4B;CACjC,SAAS;CACT,QAAQ;CACR,OAAO;CACP;AAeD,SAAS,QAAQ,OAAqB,UAAsC;AAC3E,KAAI,SACH,QAAO;AAGR,KAAI,CAAC,MAAM,MACV,QAAO;AAGR,QAAO,IAAI,MAAM,MAAM,MAAM,QAAQ;;;;;;;;AAStC,SAAgB,gBACf,QACA,UAAkC,EAAE,EACZ;CAIxB,MAAM,QAAQ,iBAFA,QAAQ,gBAAgB,OAEC,YACtC,UAAU,UAAU,YACpB;CAED,MAAM,QAAQ,eAA2D;EACxE;EACA,UAAU;EACV,UAAU,UAAU,WAAW,SAAS,aAAa,UAAU,EAAE,CAAC;EAClE,SAAS,WAAW;EACpB,iBAAiB,QAAQ,mBAAmB;EAC5C,sBAAsB,QAAQ,wBAAwB;EACtD,gBAAgB,MAAM,WAAW;EACjC,aAAa,MAAM,WAAW;EAC9B,CAAC;CAEF,MAAM,QAAQ,cACP,QAAQ,OAAO,MAAM,MAAM,EACjC,CAAC,OAAO,MAAM,MAAM,CACpB;CACD,MAAM,YACL,WAAW,SACV,MAAM,aAAa,MAAM,WAAW,aAAa,MAAM,WAAW;CAEpE,MAAM,gBAAgB;AACrB,MAAI,CAAC,OACJ,QAAO,QAAQ,QAAQ,KAAK;AAE7B,SAAO,MACL,QAAQ,EAAE,OAAO,MAAM,CAAC,CACxB,MAAM,WAAW,UAAU,OAAO,aAAa,UAAU,CAAC,QAAQ,CAClE,YAAY,OAAO,aAAa,UAAU,CAAC,QAAQ,CACnD,MAAM,YAAY,WAAW,KAAK;;AAGrC,QAAO;EACN,SAAS,MAAM;EACf,QAAQ,MAAM;EACd;EACA;EACA;EACA"}
@@ -3,7 +3,7 @@ import { CossistantClient } from "@cossistant/core";
3
3
  //#region src/hooks/private/use-client-query.d.ts
4
4
  type QueryFn<TData, TArgs> = (client: CossistantClient, args?: TArgs | undefined) => Promise<TData>;
5
5
  type UseClientQueryOptions<TData, TArgs> = {
6
- client: CossistantClient;
6
+ client: CossistantClient | null;
7
7
  queryFn: QueryFn<TData, TArgs>;
8
8
  /**
9
9
  * Unique key to identify this query for deduplication.
@@ -1 +1 @@
1
- {"version":3,"file":"use-client-query.d.ts","names":[],"sources":["../../../src/hooks/private/use-client-query.ts"],"sourcesContent":[],"mappings":";;;KAGK,iCACI,yBACD,sBACH,QAAQ;KAER;EALA,MAAA,EAMI,gBANG;EACH,OAAA,EAMC,OAND,CAMS,KANT,EAMgB,KANhB,CAAA;EACD;;;;AACI;EAGH,QAAA,CAAA,EAAA,MAAA;EACS,OAAA,CAAA,EAAA,OAAA;EAAO,eAAA,CAAA,EAAA,MAAA,GAAA,KAAA;EAAf,oBAAA,CAAA,EAAA,OAAA;EAWK,cAAA,CAAA,EAAA,OAAA;EACA,WAAA,CAAA,EADA,KACA;EAAK,WAAA,CAAA,EAAL,KAAK;EAIf,YAAA,CAAA,EAAA,SAAoB,OAAA,EAAA;CAClB;KADF,oBAEG,CAAA,KAAA,EAAA,KAAA,CAAA,GAAA;EAEU,IAAA,EAHX,KAGW,GAAA,SAAA;EAAkB,KAAA,EAF5B,KAE4B,GAAA,IAAA;EAAR,SAAA,EAAA,OAAA;EAAO,OAAA,EAAA,CAAA,IAAA,CAAA,EAAjB,KAAiB,EAAA,GAAP,OAAO,CAAC,KAAD,GAAA,SAAA,CAAA;AAqDnC,CAAA;;;;;;AAEG,iBAFa,cAEb,CAAA,KAAA,EAAA,QAAA,IAAA,CAAA,CAAA,OAAA,EADO,qBACP,CAD6B,KAC7B,EADoC,KACpC,CAAA,CAAA,EAAA,oBAAA,CAAqB,KAArB,EAA4B,KAA5B,CAAA"}
1
+ {"version":3,"file":"use-client-query.d.ts","names":[],"sources":["../../../src/hooks/private/use-client-query.ts"],"sourcesContent":[],"mappings":";;;KAGK,iCACI,yBACD,sBACH,QAAQ;KAER;EALA,MAAA,EAMI,gBANG,GAAA,IAAA;EACH,OAAA,EAMC,OAND,CAMS,KANT,EAMgB,KANhB,CAAA;EACD;;;;AACI;EAGH,QAAA,CAAA,EAAA,MAAA;EACS,OAAA,CAAA,EAAA,OAAA;EAAO,eAAA,CAAA,EAAA,MAAA,GAAA,KAAA;EAAf,oBAAA,CAAA,EAAA,OAAA;EAWK,cAAA,CAAA,EAAA,OAAA;EACA,WAAA,CAAA,EADA,KACA;EAAK,WAAA,CAAA,EAAL,KAAK;EAIf,YAAA,CAAA,EAAA,SAAoB,OAAA,EAAA;CAClB;KADF,oBAEG,CAAA,KAAA,EAAA,KAAA,CAAA,GAAA;EAEU,IAAA,EAHX,KAGW,GAAA,SAAA;EAAkB,KAAA,EAF5B,KAE4B,GAAA,IAAA;EAAR,SAAA,EAAA,OAAA;EAAO,OAAA,EAAA,CAAA,IAAA,CAAA,EAAjB,KAAiB,EAAA,GAAP,OAAO,CAAC,KAAD,GAAA,SAAA,CAAA;AAqDnC,CAAA;;;;;;AAEG,iBAFa,cAEb,CAAA,KAAA,EAAA,QAAA,IAAA,CAAA,CAAA,OAAA,EADO,qBACP,CAD6B,KAC7B,EADoC,KACpC,CAAA,CAAA,EAAA,oBAAA,CAAqB,KAArB,EAA4B,KAA5B,CAAA"}
@@ -51,6 +51,7 @@ function useClientQuery(options) {
51
51
  argsRef.current = initialArgs;
52
52
  }, [initialArgs]);
53
53
  const execute = useCallback(async (args, ignoreEnabled = false) => {
54
+ if (!client) return dataRef.current;
54
55
  if (!(enabled || ignoreEnabled)) return dataRef.current;
55
56
  const nextArgs = args ?? argsRef.current;
56
57
  argsRef.current = nextArgs;
@@ -1 +1 @@
1
- {"version":3,"file":"use-client-query.js","names":["EMPTY_DEPENDENCIES: readonly unknown[]","raw: unknown"],"sources":["../../../src/hooks/private/use-client-query.ts"],"sourcesContent":["import type { CossistantClient } from \"@cossistant/core\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\n\ntype QueryFn<TData, TArgs> = (\n\tclient: CossistantClient,\n\targs?: TArgs | undefined\n) => Promise<TData>;\n\ntype UseClientQueryOptions<TData, TArgs> = {\n\tclient: CossistantClient;\n\tqueryFn: QueryFn<TData, TArgs>;\n\t/**\n\t * Unique key to identify this query for deduplication.\n\t * When provided, concurrent requests with the same key will share a single\n\t * in-flight promise instead of making duplicate API calls.\n\t */\n\tqueryKey?: string;\n\tenabled?: boolean;\n\trefetchInterval?: number | false;\n\trefetchOnWindowFocus?: boolean;\n\trefetchOnMount?: boolean;\n\tinitialData?: TData;\n\tinitialArgs?: TArgs;\n\tdependencies?: readonly unknown[];\n};\n\ntype UseClientQueryResult<TData, TArgs> = {\n\tdata: TData | undefined;\n\terror: Error | null;\n\tisLoading: boolean;\n\trefetch: (args?: TArgs) => Promise<TData | undefined>;\n};\n\nfunction toError(error: unknown): Error {\n\tif (error instanceof Error) {\n\t\treturn error;\n\t}\n\n\treturn new Error(typeof error === \"string\" ? error : \"Unknown error\");\n}\n\nconst EMPTY_DEPENDENCIES: readonly unknown[] = [];\n\n/**\n * Module-level cache for in-flight requests.\n * Maps query keys to their pending promises for deduplication.\n */\nconst inFlightRequests = new Map<string, Promise<unknown>>();\n\n/**\n * Execute a query with deduplication support.\n * If a query with the same key is already in flight, returns the existing promise.\n */\nfunction executeWithDeduplication<TData>(\n\tqueryKey: string | undefined,\n\tqueryFn: () => Promise<TData>\n): Promise<TData> {\n\t// No deduplication if no key provided\n\tif (!queryKey) {\n\t\treturn queryFn();\n\t}\n\n\t// Check for existing in-flight request\n\tconst existing = inFlightRequests.get(queryKey);\n\tif (existing) {\n\t\treturn existing as Promise<TData>;\n\t}\n\n\t// Create new request and track it\n\tconst promise = queryFn().finally(() => {\n\t\t// Clean up after request completes (success or error)\n\t\tinFlightRequests.delete(queryKey);\n\t});\n\n\tinFlightRequests.set(queryKey, promise);\n\treturn promise;\n}\n\n/**\n * Lightweight data-fetching abstraction that plugs into the SDK client instead\n * of React Query. It tracks loading/error state, supports polling, window\n * focus refetching and exposes a typed refetch helper.\n */\nexport function useClientQuery<TData, TArgs = void>(\n\toptions: UseClientQueryOptions<TData, TArgs>\n): UseClientQueryResult<TData, TArgs> {\n\tconst {\n\t\tclient,\n\t\tqueryFn,\n\t\tqueryKey,\n\t\tenabled = true,\n\t\trefetchInterval = false,\n\t\trefetchOnWindowFocus = false,\n\t\trefetchOnMount = true,\n\t\tinitialData,\n\t\tinitialArgs,\n\t\tdependencies = EMPTY_DEPENDENCIES,\n\t} = options;\n\n\tconst [data, setData] = useState<TData | undefined>(initialData);\n\tconst [error, setError] = useState<Error | null>(null);\n\tconst [isLoading, setIsLoading] = useState(\n\t\tinitialData === undefined && Boolean(enabled)\n\t);\n\n\tconst dataRef = useRef(data);\n\tdataRef.current = data;\n\n\tconst argsRef = useRef<TArgs | undefined>(initialArgs);\n\tconst fetchIdRef = useRef(0);\n\tconst hasMountedRef = useRef(false);\n\tconst hasFetchedRef = useRef(initialData !== undefined);\n\tconst isMountedRef = useRef(true);\n\tconst queryFnRef = useRef(queryFn);\n\n\tqueryFnRef.current = queryFn;\n\n\tuseEffect(\n\t\t() => () => {\n\t\t\tisMountedRef.current = false;\n\t\t},\n\t\t[]\n\t);\n\n\tuseEffect(() => {\n\t\targsRef.current = initialArgs;\n\t}, [initialArgs]);\n\n\tconst execute = useCallback(\n\t\tasync (args?: TArgs, ignoreEnabled = false): Promise<TData | undefined> => {\n\t\t\tif (!(enabled || ignoreEnabled)) {\n\t\t\t\treturn dataRef.current;\n\t\t\t}\n\n\t\t\tconst nextArgs = args ?? argsRef.current;\n\t\t\targsRef.current = nextArgs;\n\n\t\t\tconst fetchId = fetchIdRef.current + 1;\n\t\t\tfetchIdRef.current = fetchId;\n\n\t\t\tsetIsLoading(true);\n\t\t\tsetError(null);\n\n\t\t\ttry {\n\t\t\t\t// Use deduplication to share in-flight requests with the same key\n\t\t\t\tconst result = await executeWithDeduplication(queryKey, () =>\n\t\t\t\t\tqueryFnRef.current(client, nextArgs)\n\t\t\t\t);\n\n\t\t\t\tif (!isMountedRef.current || fetchId !== fetchIdRef.current) {\n\t\t\t\t\treturn dataRef.current;\n\t\t\t\t}\n\n\t\t\t\tdataRef.current = result;\n\t\t\t\tsetData(result);\n\t\t\t\tsetError(null);\n\t\t\t\tsetIsLoading(false);\n\t\t\t\thasFetchedRef.current = true;\n\n\t\t\t\treturn result;\n\t\t\t} catch (raw: unknown) {\n\t\t\t\tif (!isMountedRef.current || fetchId !== fetchIdRef.current) {\n\t\t\t\t\treturn dataRef.current;\n\t\t\t\t}\n\n\t\t\t\tconst normalized = toError(raw);\n\t\t\t\tsetError(normalized);\n\t\t\t\tsetIsLoading(false);\n\n\t\t\t\tthrow normalized;\n\t\t\t}\n\t\t},\n\t\t[client, enabled, queryKey]\n\t);\n\n\tuseEffect(() => {\n\t\tif (!enabled) {\n\t\t\tsetIsLoading(false);\n\t\t\treturn;\n\t\t}\n\n\t\tconst shouldFetchInitially = hasMountedRef.current\n\t\t\t? true\n\t\t\t: refetchOnMount || !hasFetchedRef.current;\n\n\t\thasMountedRef.current = true;\n\n\t\tif (!shouldFetchInitially) {\n\t\t\treturn;\n\t\t}\n\n\t\tvoid execute(argsRef.current);\n\t}, [enabled, execute, refetchOnMount, ...dependencies]);\n\n\tuseEffect(() => {\n\t\tif (!enabled) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (\n\t\t\trefetchInterval === false ||\n\t\t\trefetchInterval === null ||\n\t\t\trefetchInterval <= 0 ||\n\t\t\ttypeof window === \"undefined\"\n\t\t) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst timer = window.setInterval(() => {\n\t\t\tvoid execute(argsRef.current);\n\t\t}, refetchInterval);\n\n\t\treturn () => {\n\t\t\twindow.clearInterval(timer);\n\t\t};\n\t}, [enabled, execute, refetchInterval]);\n\n\tuseEffect(() => {\n\t\tif (\n\t\t\t!refetchOnWindowFocus ||\n\t\t\ttypeof window === \"undefined\" ||\n\t\t\ttypeof document === \"undefined\"\n\t\t) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst handleRefetch = () => {\n\t\t\tif (!enabled) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvoid execute(argsRef.current);\n\t\t};\n\n\t\tconst onFocus = () => {\n\t\t\tvoid handleRefetch();\n\t\t};\n\n\t\tconst onVisibilityChange = () => {\n\t\t\tif (document.visibilityState === \"visible\") {\n\t\t\t\tvoid handleRefetch();\n\t\t\t}\n\t\t};\n\n\t\twindow.addEventListener(\"focus\", onFocus);\n\t\tdocument.addEventListener(\"visibilitychange\", onVisibilityChange);\n\n\t\treturn () => {\n\t\t\twindow.removeEventListener(\"focus\", onFocus);\n\t\t\tdocument.removeEventListener(\"visibilitychange\", onVisibilityChange);\n\t\t};\n\t}, [enabled, execute, refetchOnWindowFocus]);\n\n\tconst refetch = useCallback(\n\t\tasync (args?: TArgs) => execute(args, true),\n\t\t[execute]\n\t);\n\n\treturn useMemo(\n\t\t() => ({\n\t\t\tdata,\n\t\t\terror,\n\t\t\tisLoading,\n\t\t\trefetch,\n\t\t}),\n\t\t[data, error, isLoading, refetch]\n\t);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"use-client-query.js","names":["EMPTY_DEPENDENCIES: readonly unknown[]","raw: unknown"],"sources":["../../../src/hooks/private/use-client-query.ts"],"sourcesContent":["import type { CossistantClient } from \"@cossistant/core\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\n\ntype QueryFn<TData, TArgs> = (\n\tclient: CossistantClient,\n\targs?: TArgs | undefined\n) => Promise<TData>;\n\ntype UseClientQueryOptions<TData, TArgs> = {\n\tclient: CossistantClient | null;\n\tqueryFn: QueryFn<TData, TArgs>;\n\t/**\n\t * Unique key to identify this query for deduplication.\n\t * When provided, concurrent requests with the same key will share a single\n\t * in-flight promise instead of making duplicate API calls.\n\t */\n\tqueryKey?: string;\n\tenabled?: boolean;\n\trefetchInterval?: number | false;\n\trefetchOnWindowFocus?: boolean;\n\trefetchOnMount?: boolean;\n\tinitialData?: TData;\n\tinitialArgs?: TArgs;\n\tdependencies?: readonly unknown[];\n};\n\ntype UseClientQueryResult<TData, TArgs> = {\n\tdata: TData | undefined;\n\terror: Error | null;\n\tisLoading: boolean;\n\trefetch: (args?: TArgs) => Promise<TData | undefined>;\n};\n\nfunction toError(error: unknown): Error {\n\tif (error instanceof Error) {\n\t\treturn error;\n\t}\n\n\treturn new Error(typeof error === \"string\" ? error : \"Unknown error\");\n}\n\nconst EMPTY_DEPENDENCIES: readonly unknown[] = [];\n\n/**\n * Module-level cache for in-flight requests.\n * Maps query keys to their pending promises for deduplication.\n */\nconst inFlightRequests = new Map<string, Promise<unknown>>();\n\n/**\n * Execute a query with deduplication support.\n * If a query with the same key is already in flight, returns the existing promise.\n */\nfunction executeWithDeduplication<TData>(\n\tqueryKey: string | undefined,\n\tqueryFn: () => Promise<TData>\n): Promise<TData> {\n\t// No deduplication if no key provided\n\tif (!queryKey) {\n\t\treturn queryFn();\n\t}\n\n\t// Check for existing in-flight request\n\tconst existing = inFlightRequests.get(queryKey);\n\tif (existing) {\n\t\treturn existing as Promise<TData>;\n\t}\n\n\t// Create new request and track it\n\tconst promise = queryFn().finally(() => {\n\t\t// Clean up after request completes (success or error)\n\t\tinFlightRequests.delete(queryKey);\n\t});\n\n\tinFlightRequests.set(queryKey, promise);\n\treturn promise;\n}\n\n/**\n * Lightweight data-fetching abstraction that plugs into the SDK client instead\n * of React Query. It tracks loading/error state, supports polling, window\n * focus refetching and exposes a typed refetch helper.\n */\nexport function useClientQuery<TData, TArgs = void>(\n\toptions: UseClientQueryOptions<TData, TArgs>\n): UseClientQueryResult<TData, TArgs> {\n\tconst {\n\t\tclient,\n\t\tqueryFn,\n\t\tqueryKey,\n\t\tenabled = true,\n\t\trefetchInterval = false,\n\t\trefetchOnWindowFocus = false,\n\t\trefetchOnMount = true,\n\t\tinitialData,\n\t\tinitialArgs,\n\t\tdependencies = EMPTY_DEPENDENCIES,\n\t} = options;\n\n\tconst [data, setData] = useState<TData | undefined>(initialData);\n\tconst [error, setError] = useState<Error | null>(null);\n\tconst [isLoading, setIsLoading] = useState(\n\t\tinitialData === undefined && Boolean(enabled)\n\t);\n\n\tconst dataRef = useRef(data);\n\tdataRef.current = data;\n\n\tconst argsRef = useRef<TArgs | undefined>(initialArgs);\n\tconst fetchIdRef = useRef(0);\n\tconst hasMountedRef = useRef(false);\n\tconst hasFetchedRef = useRef(initialData !== undefined);\n\tconst isMountedRef = useRef(true);\n\tconst queryFnRef = useRef(queryFn);\n\n\tqueryFnRef.current = queryFn;\n\n\tuseEffect(\n\t\t() => () => {\n\t\t\tisMountedRef.current = false;\n\t\t},\n\t\t[]\n\t);\n\n\tuseEffect(() => {\n\t\targsRef.current = initialArgs;\n\t}, [initialArgs]);\n\n\tconst execute = useCallback(\n\t\tasync (args?: TArgs, ignoreEnabled = false): Promise<TData | undefined> => {\n\t\t\t// Handle null client (configuration error case)\n\t\t\tif (!client) {\n\t\t\t\treturn dataRef.current;\n\t\t\t}\n\n\t\t\tif (!(enabled || ignoreEnabled)) {\n\t\t\t\treturn dataRef.current;\n\t\t\t}\n\n\t\t\tconst nextArgs = args ?? argsRef.current;\n\t\t\targsRef.current = nextArgs;\n\n\t\t\tconst fetchId = fetchIdRef.current + 1;\n\t\t\tfetchIdRef.current = fetchId;\n\n\t\t\tsetIsLoading(true);\n\t\t\tsetError(null);\n\n\t\t\ttry {\n\t\t\t\t// Use deduplication to share in-flight requests with the same key\n\t\t\t\tconst result = await executeWithDeduplication(queryKey, () =>\n\t\t\t\t\tqueryFnRef.current(client, nextArgs)\n\t\t\t\t);\n\n\t\t\t\tif (!isMountedRef.current || fetchId !== fetchIdRef.current) {\n\t\t\t\t\treturn dataRef.current;\n\t\t\t\t}\n\n\t\t\t\tdataRef.current = result;\n\t\t\t\tsetData(result);\n\t\t\t\tsetError(null);\n\t\t\t\tsetIsLoading(false);\n\t\t\t\thasFetchedRef.current = true;\n\n\t\t\t\treturn result;\n\t\t\t} catch (raw: unknown) {\n\t\t\t\tif (!isMountedRef.current || fetchId !== fetchIdRef.current) {\n\t\t\t\t\treturn dataRef.current;\n\t\t\t\t}\n\n\t\t\t\tconst normalized = toError(raw);\n\t\t\t\tsetError(normalized);\n\t\t\t\tsetIsLoading(false);\n\n\t\t\t\tthrow normalized;\n\t\t\t}\n\t\t},\n\t\t[client, enabled, queryKey]\n\t);\n\n\tuseEffect(() => {\n\t\tif (!enabled) {\n\t\t\tsetIsLoading(false);\n\t\t\treturn;\n\t\t}\n\n\t\tconst shouldFetchInitially = hasMountedRef.current\n\t\t\t? true\n\t\t\t: refetchOnMount || !hasFetchedRef.current;\n\n\t\thasMountedRef.current = true;\n\n\t\tif (!shouldFetchInitially) {\n\t\t\treturn;\n\t\t}\n\n\t\tvoid execute(argsRef.current);\n\t}, [enabled, execute, refetchOnMount, ...dependencies]);\n\n\tuseEffect(() => {\n\t\tif (!enabled) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (\n\t\t\trefetchInterval === false ||\n\t\t\trefetchInterval === null ||\n\t\t\trefetchInterval <= 0 ||\n\t\t\ttypeof window === \"undefined\"\n\t\t) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst timer = window.setInterval(() => {\n\t\t\tvoid execute(argsRef.current);\n\t\t}, refetchInterval);\n\n\t\treturn () => {\n\t\t\twindow.clearInterval(timer);\n\t\t};\n\t}, [enabled, execute, refetchInterval]);\n\n\tuseEffect(() => {\n\t\tif (\n\t\t\t!refetchOnWindowFocus ||\n\t\t\ttypeof window === \"undefined\" ||\n\t\t\ttypeof document === \"undefined\"\n\t\t) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst handleRefetch = () => {\n\t\t\tif (!enabled) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvoid execute(argsRef.current);\n\t\t};\n\n\t\tconst onFocus = () => {\n\t\t\tvoid handleRefetch();\n\t\t};\n\n\t\tconst onVisibilityChange = () => {\n\t\t\tif (document.visibilityState === \"visible\") {\n\t\t\t\tvoid handleRefetch();\n\t\t\t}\n\t\t};\n\n\t\twindow.addEventListener(\"focus\", onFocus);\n\t\tdocument.addEventListener(\"visibilitychange\", onVisibilityChange);\n\n\t\treturn () => {\n\t\t\twindow.removeEventListener(\"focus\", onFocus);\n\t\t\tdocument.removeEventListener(\"visibilitychange\", onVisibilityChange);\n\t\t};\n\t}, [enabled, execute, refetchOnWindowFocus]);\n\n\tconst refetch = useCallback(\n\t\tasync (args?: TArgs) => execute(args, true),\n\t\t[execute]\n\t);\n\n\treturn useMemo(\n\t\t() => ({\n\t\t\tdata,\n\t\t\terror,\n\t\t\tisLoading,\n\t\t\trefetch,\n\t\t}),\n\t\t[data, error, isLoading, refetch]\n\t);\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { TimelineItem } from "../../timeline-item.js";
1
+ import { TimelineItem } from "../../packages/types/src/api/timeline-item.js";
2
2
 
3
3
  //#region src/hooks/private/use-default-messages.d.ts
4
4
  type UseDefaultMessagesParams = {
@@ -1,5 +1,5 @@
1
- import { TimelineItem } from "../../timeline-item.js";
2
- import { ConversationSeen } from "../../schemas3.js";
1
+ import { TimelineItem } from "../../packages/types/src/api/timeline-item.js";
2
+ import { ConversationSeen } from "../../packages/types/src/schemas.js";
3
3
  import { SenderType } from "@cossistant/types";
4
4
 
5
5
  //#region src/hooks/private/use-grouped-messages.d.ts
@@ -24,12 +24,16 @@ type TimelineToolItem = {
24
24
  tool: string | null;
25
25
  timestamp: Date;
26
26
  };
27
- type ConversationItem = GroupedMessage | TimelineEventItem | TimelineToolItem;
27
+ type DaySeparatorItem = {
28
+ type: "day_separator";
29
+ date: Date;
30
+ dateString: string;
31
+ };
32
+ type ConversationItem = GroupedMessage | TimelineEventItem | TimelineToolItem | DaySeparatorItem;
28
33
  type UseGroupedMessagesOptions = {
29
34
  items: TimelineItem[];
30
35
  seenData?: ConversationSeen[];
31
36
  currentViewerId?: string;
32
- viewerType?: SenderType;
33
37
  };
34
38
  type UseGroupedMessagesProps = UseGroupedMessagesOptions;
35
39
  /**
@@ -41,8 +45,7 @@ type UseGroupedMessagesProps = UseGroupedMessagesOptions;
41
45
  declare const useGroupedMessages: ({
42
46
  items,
43
47
  seenData,
44
- currentViewerId,
45
- viewerType
48
+ currentViewerId
46
49
  }: UseGroupedMessagesOptions) => {
47
50
  items: ConversationItem[];
48
51
  seenByMap: Map<string, Set<string>>;
@@ -56,5 +59,5 @@ declare const useGroupedMessages: ({
56
59
  hasUnreadAfter: (messageId: string, userId: string) => boolean;
57
60
  };
58
61
  //#endregion
59
- export { ConversationItem, GroupedMessage, TimelineEventItem, TimelineToolItem, UseGroupedMessagesOptions, UseGroupedMessagesProps, useGroupedMessages };
62
+ export { ConversationItem, DaySeparatorItem, GroupedMessage, TimelineEventItem, TimelineToolItem, UseGroupedMessagesOptions, UseGroupedMessagesProps, useGroupedMessages };
60
63
  //# sourceMappingURL=use-grouped-messages.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-grouped-messages.d.ts","names":[],"sources":["../../../src/hooks/private/use-grouped-messages.ts"],"sourcesContent":[],"mappings":";;;;;KAKY,cAAA;;EAAA,QAAA,EAAA,MAAA;EAGC,UAAA,EAAA,UAAA;EACL,KAAA,EAAA,YAAA,EAAA;EAGW,cAAA,EAAA,MAAA;EACD,aAAA,EAAA,MAAA;EAAI,gBAAA,EADH,IACG;EAGV,eAAA,EAHM,IAGW;AAM7B,CAAA;AAOY,KAbA,iBAAA,GAagB;EACzB,IAAA,EAAA,gBAAA;EACA,IAAA,EAbI,YAaJ;EACA,SAAA,EAbS,IAaT;CAAgB;AAEP,KAZA,gBAAA,GAYA;EACJ,IAAA,EAAA,eAAA;EACI,IAAA,EAZL,YAYK;EAEE,IAAA,EAAA,MAAA,GAAA,IAAA;EAAU,SAAA,EAZZ,IAYY;AAGxB,CAAA;AA+La,KA3MD,gBAAA,GACT,cA8QF,GA7QE,iBA6QF,GA5QE,gBA4QF;AApEkC,KAtMvB,yBAAA,GAsMuB;EAAA,KAAA,EArM3B,YAqM2B,EAAA;EAAA,QAAA,CAAA,EApMvB,gBAoMuB,EAAA;EAAA,eAAA,CAAA,EAAA,MAAA;EAKhC,UAAA,CAAA,EAvMW,UAuMX;;KApMS,uBAAA,GAA0B;;;;;;;cA+LzB;;;;;GAKV"}
1
+ {"version":3,"file":"use-grouped-messages.d.ts","names":[],"sources":["../../../src/hooks/private/use-grouped-messages.ts"],"sourcesContent":[],"mappings":";;;;;KAKY,cAAA;;EAAA,QAAA,EAAA,MAAA;EAGC,UAAA,EAAA,UAAA;EACL,KAAA,EAAA,YAAA,EAAA;EAGW,cAAA,EAAA,MAAA;EACD,aAAA,EAAA,MAAA;EAAI,gBAAA,EADH,IACG;EAGV,eAAA,EAHM,IAGW;AAM7B,CAAA;AAOY,KAbA,iBAAA,GAagB;EAMhB,IAAA,EAAA,gBAAgB;EACzB,IAAA,EAlBI,YAkBJ;EACA,SAAA,EAlBS,IAkBT;CACA;AACA,KAjBS,gBAAA,GAiBT;EAAgB,IAAA,EAAA,eAAA;EAEP,IAAA,EAjBL,YAiBK;EAMA,IAAA,EAAA,MAAA,GAAA,IAAA;EAsOC,SAAA,EA3PD,IA2PC;CAAsB;AAAA,KAxPvB,gBAAA,GAwPuB;EAAA,IAAA,EAAA,eAAA;EAIhC,IAAA,EA1PI,IA0PJ;;;KAtPS,gBAAA,GACT,iBACA,oBACA,mBACA;KAES,yBAAA;SACJ;aACI;;;KAIA,uBAAA,GAA0B;;;;;;;cAsOzB;;;;GAIV"}
@@ -12,6 +12,13 @@ const toDate = (date) => {
12
12
  if (typeof date === "string") return new Date(date);
13
13
  return date;
14
14
  };
15
+ const getDateString = (date) => {
16
+ return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, "0")}-${String(date.getDate()).padStart(2, "0")}`;
17
+ };
18
+ const createDayDate = (dateString) => {
19
+ const [year, month, day] = dateString.split("-").map(Number);
20
+ return new Date(year ?? 0, (month ?? 1) - 1, day ?? 1, 0, 0, 0, 0);
21
+ };
15
22
  const getSenderIdAndTypeFromTimelineItem = (item) => {
16
23
  if (item.visitorId) return {
17
24
  senderId: item.visitorId,
@@ -34,7 +41,25 @@ const EMPTY_STRING_ARRAY = Object.freeze([]);
34
41
  const groupTimelineItems = (items) => {
35
42
  const result = [];
36
43
  let currentGroup = null;
44
+ let currentDayString = null;
45
+ const maybeInsertDaySeparator = (itemDate) => {
46
+ const itemDayString = getDateString(itemDate);
47
+ if (currentDayString !== itemDayString) {
48
+ if (currentGroup) {
49
+ result.push(currentGroup);
50
+ currentGroup = null;
51
+ }
52
+ result.push({
53
+ type: "day_separator",
54
+ date: createDayDate(itemDayString),
55
+ dateString: itemDayString
56
+ });
57
+ currentDayString = itemDayString;
58
+ }
59
+ };
37
60
  for (const item of items) {
61
+ const itemDate = toDate(item.createdAt);
62
+ maybeInsertDaySeparator(itemDate);
38
63
  if (item.type === "event") {
39
64
  if (currentGroup) {
40
65
  result.push(currentGroup);
@@ -43,7 +68,7 @@ const groupTimelineItems = (items) => {
43
68
  result.push({
44
69
  type: "timeline_event",
45
70
  item,
46
- timestamp: toDate(item.createdAt)
71
+ timestamp: itemDate
47
72
  });
48
73
  continue;
49
74
  }
@@ -56,7 +81,7 @@ const groupTimelineItems = (items) => {
56
81
  type: "timeline_tool",
57
82
  item,
58
83
  tool: item.tool ?? null,
59
- timestamp: toDate(item.createdAt)
84
+ timestamp: itemDate
60
85
  });
61
86
  continue;
62
87
  }
@@ -64,7 +89,7 @@ const groupTimelineItems = (items) => {
64
89
  if (currentGroup && currentGroup.senderId === senderId) {
65
90
  currentGroup.items.push(item);
66
91
  currentGroup.lastMessageId = item.id || currentGroup.lastMessageId;
67
- currentGroup.lastMessageTime = toDate(item.createdAt);
92
+ currentGroup.lastMessageTime = itemDate;
68
93
  } else {
69
94
  if (currentGroup) result.push(currentGroup);
70
95
  currentGroup = {
@@ -74,27 +99,26 @@ const groupTimelineItems = (items) => {
74
99
  items: [item],
75
100
  firstMessageId: item.id || "",
76
101
  lastMessageId: item.id || "",
77
- firstMessageTime: toDate(item.createdAt),
78
- lastMessageTime: toDate(item.createdAt)
102
+ firstMessageTime: itemDate,
103
+ lastMessageTime: itemDate
79
104
  };
80
105
  }
81
106
  }
82
107
  if (currentGroup) result.push(currentGroup);
83
108
  return result;
84
109
  };
85
- const buildTimelineReadReceiptData = (seenData, items) => {
110
+ const buildTimelineReadReceiptData = (seenData, items, sortedMessageItems) => {
86
111
  const seenByMap = /* @__PURE__ */ new Map();
87
112
  const lastReadMessageMap = /* @__PURE__ */ new Map();
88
113
  const unreadCountMap = /* @__PURE__ */ new Map();
89
114
  for (const item of items) if (item.type === "message" && item.id) seenByMap.set(item.id, /* @__PURE__ */ new Set());
90
- const sortedItems = [...items].filter((item) => item.type === "message").sort((a, b) => getTimestamp(a.createdAt) - getTimestamp(b.createdAt));
91
115
  for (const seen of seenData) {
92
116
  const seenTime = getTimestamp(seen.lastSeenAt);
93
117
  const viewerId = seen.userId || seen.visitorId || seen.aiAgentId;
94
118
  if (!viewerId) continue;
95
119
  let lastReadItem = null;
96
120
  let unreadCount = 0;
97
- for (const item of sortedItems) if (getTimestamp(item.createdAt) <= seenTime) {
121
+ for (const item of sortedMessageItems) if (getTimestamp(item.createdAt) <= seenTime) {
98
122
  if (item.id) {
99
123
  const seenBy = seenByMap.get(item.id);
100
124
  if (seenBy) seenBy.add(viewerId);
@@ -116,10 +140,16 @@ const buildTimelineReadReceiptData = (seenData, items) => {
116
140
  * minimal effort. Seen data is normalised into quick lookup maps for unread
117
141
  * indicators.
118
142
  */
119
- const useGroupedMessages = ({ items, seenData = [], currentViewerId, viewerType }) => {
143
+ const useGroupedMessages = ({ items, seenData = [], currentViewerId }) => {
120
144
  return useMemo(() => {
121
145
  const groupedItems = groupTimelineItems(items);
122
- const { seenByMap, lastReadMessageMap, unreadCountMap } = buildTimelineReadReceiptData(seenData, items);
146
+ const sortedMessageItems = items.filter((item) => item.type === "message").sort((a, b) => getTimestamp(a.createdAt) - getTimestamp(b.createdAt));
147
+ const messageIndexMap = /* @__PURE__ */ new Map();
148
+ for (let i = 0; i < sortedMessageItems.length; i++) {
149
+ const item = sortedMessageItems[i];
150
+ if (item?.id) messageIndexMap.set(item.id, i);
151
+ }
152
+ const { seenByMap, lastReadMessageMap, unreadCountMap } = buildTimelineReadReceiptData(seenData, items, sortedMessageItems);
123
153
  const seenByArrayCache = /* @__PURE__ */ new Map();
124
154
  return {
125
155
  items: groupedItems,
@@ -148,7 +178,10 @@ const useGroupedMessages = ({ items, seenData = [], currentViewerId, viewerType
148
178
  hasUnreadAfter: (messageId, userId) => {
149
179
  const lastRead = lastReadMessageMap.get(userId);
150
180
  if (!lastRead) return true;
151
- return items.findIndex((item) => item.id === messageId) < items.findIndex((item) => item.id === lastRead);
181
+ const messageIndex = messageIndexMap.get(messageId);
182
+ const lastReadIndex = messageIndexMap.get(lastRead);
183
+ if (messageIndex === void 0 || lastReadIndex === void 0) return true;
184
+ return messageIndex < lastReadIndex;
152
185
  }
153
186
  };
154
187
  }, [