@cossistant/react 0.0.26 → 0.0.28

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 (227) hide show
  1. package/api.d.ts +1 -1
  2. package/api.d.ts.map +1 -1
  3. package/checks.d.ts +1 -1
  4. package/checks.d.ts.map +1 -1
  5. package/clsx.d.ts +1 -1
  6. package/clsx.d.ts.map +1 -1
  7. package/coerce.d.ts +1 -1
  8. package/coerce.d.ts.map +1 -1
  9. package/conversation.d.ts +3 -0
  10. package/conversation.d.ts.map +1 -1
  11. package/core.d.ts +1 -1
  12. package/core.d.ts.map +1 -1
  13. package/errors.d.ts +1 -1
  14. package/errors.d.ts.map +1 -1
  15. package/errors2.d.ts +1 -1
  16. package/errors2.d.ts.map +1 -1
  17. package/hooks/index.d.ts +2 -1
  18. package/hooks/index.js +6 -5
  19. package/hooks/private/store/use-website-store.js +2 -1
  20. package/hooks/private/store/use-website-store.js.map +1 -1
  21. package/hooks/private/use-client-query.d.ts +6 -0
  22. package/hooks/private/use-client-query.d.ts.map +1 -1
  23. package/hooks/private/use-client-query.js +26 -3
  24. package/hooks/private/use-client-query.js.map +1 -1
  25. package/hooks/private/use-multimodal-input.d.ts.map +1 -1
  26. package/hooks/private/use-multimodal-input.js +7 -5
  27. package/hooks/private/use-multimodal-input.js.map +1 -1
  28. package/hooks/private/use-visitor-typing-reporter.d.ts +18 -1
  29. package/hooks/private/use-visitor-typing-reporter.d.ts.map +1 -1
  30. package/hooks/private/use-visitor-typing-reporter.js +34 -4
  31. package/hooks/private/use-visitor-typing-reporter.js.map +1 -1
  32. package/hooks/use-conversation-page.d.ts +1 -0
  33. package/hooks/use-conversation-page.d.ts.map +1 -1
  34. package/hooks/use-conversation-page.js +6 -1
  35. package/hooks/use-conversation-page.js.map +1 -1
  36. package/hooks/use-conversation-preview.d.ts +2 -1
  37. package/hooks/use-conversation-preview.d.ts.map +1 -1
  38. package/hooks/use-conversation-preview.js +1 -1
  39. package/hooks/use-conversation-preview.js.map +1 -1
  40. package/hooks/use-conversation-timeline-items.js +2 -1
  41. package/hooks/use-conversation-timeline-items.js.map +1 -1
  42. package/hooks/use-conversation.js +2 -1
  43. package/hooks/use-conversation.js.map +1 -1
  44. package/hooks/use-conversations.js +1 -0
  45. package/hooks/use-conversations.js.map +1 -1
  46. package/hooks/use-create-conversation.d.ts.map +1 -1
  47. package/hooks/use-file-upload.d.ts +55 -0
  48. package/hooks/use-file-upload.d.ts.map +1 -0
  49. package/hooks/use-file-upload.js +100 -0
  50. package/hooks/use-file-upload.js.map +1 -0
  51. package/hooks/use-message-composer.d.ts +11 -0
  52. package/hooks/use-message-composer.d.ts.map +1 -1
  53. package/hooks/use-message-composer.js +7 -3
  54. package/hooks/use-message-composer.js.map +1 -1
  55. package/hooks/use-send-message.d.ts +1 -0
  56. package/hooks/use-send-message.d.ts.map +1 -1
  57. package/hooks/use-send-message.js +63 -11
  58. package/hooks/use-send-message.js.map +1 -1
  59. package/index.d.ts +6 -3
  60. package/index.js +13 -10
  61. package/openapi30.d.ts +1 -1
  62. package/openapi30.d.ts.map +1 -1
  63. package/openapi31.d.ts +1 -1
  64. package/openapi31.d.ts.map +1 -1
  65. package/package.json +4 -3
  66. package/parse.d.ts +1 -1
  67. package/parse.d.ts.map +1 -1
  68. package/primitives/avatar/image.d.ts +1 -1
  69. package/primitives/conversation-timeline.d.ts.map +1 -1
  70. package/primitives/conversation-timeline.js +10 -5
  71. package/primitives/conversation-timeline.js.map +1 -1
  72. package/primitives/index.d.ts +4 -3
  73. package/primitives/index.js +12 -5
  74. package/primitives/index.parts.d.ts +3 -2
  75. package/primitives/index.parts.js +4 -3
  76. package/primitives/multimodal-input.d.ts +2 -2
  77. package/primitives/multimodal-input.d.ts.map +1 -1
  78. package/primitives/timeline-item-attachments.d.ts +100 -0
  79. package/primitives/timeline-item-attachments.d.ts.map +1 -0
  80. package/primitives/timeline-item-attachments.js +151 -0
  81. package/primitives/timeline-item-attachments.js.map +1 -0
  82. package/primitives/trigger.d.ts +91 -0
  83. package/primitives/trigger.d.ts.map +1 -0
  84. package/primitives/trigger.js +74 -0
  85. package/primitives/trigger.js.map +1 -0
  86. package/primitives/window.d.ts +22 -1
  87. package/primitives/window.d.ts.map +1 -1
  88. package/primitives/window.js +91 -5
  89. package/primitives/window.js.map +1 -1
  90. package/provider.d.ts.map +1 -1
  91. package/provider.js +8 -3
  92. package/provider.js.map +1 -1
  93. package/realtime/index.js +1 -1
  94. package/realtime/provider.js +1 -1
  95. package/realtime/support-provider.js +1 -1
  96. package/realtime/support-provider.js.map +1 -1
  97. package/realtime-events.d.ts +40 -1
  98. package/realtime-events.d.ts.map +1 -1
  99. package/registries.d.ts +1 -1
  100. package/registries.d.ts.map +1 -1
  101. package/schemas.d.ts +1 -1
  102. package/schemas.d.ts.map +1 -1
  103. package/schemas2.d.ts +1 -1
  104. package/schemas2.d.ts.map +1 -1
  105. package/schemas3.d.ts +1 -0
  106. package/schemas3.d.ts.map +1 -1
  107. package/specification-extension.d.ts +1 -1
  108. package/specification-extension.d.ts.map +1 -1
  109. package/standard-schema.d.ts +1 -1
  110. package/standard-schema.d.ts.map +1 -1
  111. package/support/components/content.d.ts +30 -0
  112. package/support/components/content.d.ts.map +1 -0
  113. package/support/components/content.js +282 -0
  114. package/support/components/content.js.map +1 -0
  115. package/support/components/conversation-button-link.js +1 -1
  116. package/support/components/conversation-timeline.js +3 -3
  117. package/support/components/conversation-timeline.js.map +1 -1
  118. package/support/components/header.js +1 -1
  119. package/support/components/image-lightbox.d.ts +49 -0
  120. package/support/components/image-lightbox.d.ts.map +1 -0
  121. package/support/components/image-lightbox.js +142 -0
  122. package/support/components/image-lightbox.js.map +1 -0
  123. package/support/components/index.d.ts +5 -4
  124. package/support/components/index.js +4 -4
  125. package/support/components/multimodal-input.d.ts +4 -1
  126. package/support/components/multimodal-input.d.ts.map +1 -1
  127. package/support/components/multimodal-input.js +71 -45
  128. package/support/components/multimodal-input.js.map +1 -1
  129. package/support/components/navigation-tab.js +1 -1
  130. package/support/components/root.d.ts +23 -0
  131. package/support/components/root.d.ts.map +1 -0
  132. package/support/components/root.js +36 -0
  133. package/support/components/root.js.map +1 -0
  134. package/support/components/timeline-message-item.d.ts.map +1 -1
  135. package/support/components/timeline-message-item.js +82 -18
  136. package/support/components/timeline-message-item.js.map +1 -1
  137. package/support/components/trigger.d.ts +14 -0
  138. package/support/components/trigger.d.ts.map +1 -0
  139. package/support/components/{bubble.js → trigger.js} +16 -12
  140. package/support/components/trigger.js.map +1 -0
  141. package/support/components/typing-indicator.d.ts.map +1 -1
  142. package/support/components/typing-indicator.js +1 -0
  143. package/support/components/typing-indicator.js.map +1 -1
  144. package/support/context/controlled-state.d.ts +46 -0
  145. package/support/context/controlled-state.d.ts.map +1 -0
  146. package/support/context/controlled-state.js +34 -0
  147. package/support/context/controlled-state.js.map +1 -0
  148. package/support/context/events.d.ts +103 -0
  149. package/support/context/events.d.ts.map +1 -0
  150. package/support/context/events.js +139 -0
  151. package/support/context/events.js.map +1 -0
  152. package/support/context/handle.d.ts +90 -0
  153. package/support/context/handle.d.ts.map +1 -0
  154. package/support/context/handle.js +79 -0
  155. package/support/context/handle.js.map +1 -0
  156. package/support/context/positioning.d.ts +17 -0
  157. package/support/context/positioning.d.ts.map +1 -0
  158. package/support/context/positioning.js +26 -0
  159. package/support/context/positioning.js.map +1 -0
  160. package/support/context/slots.d.ts +85 -0
  161. package/support/context/slots.d.ts.map +1 -0
  162. package/support/context/slots.js +115 -0
  163. package/support/context/slots.js.map +1 -0
  164. package/support/context/websocket.d.ts +8 -1
  165. package/support/context/websocket.d.ts.map +1 -1
  166. package/support/context/websocket.js +8 -1
  167. package/support/context/websocket.js.map +1 -1
  168. package/support/index.d.ts +239 -54
  169. package/support/index.d.ts.map +1 -1
  170. package/support/index.js +254 -33
  171. package/support/index.js.map +1 -1
  172. package/support/pages/articles.d.ts.map +1 -1
  173. package/support/pages/articles.js +3 -4
  174. package/support/pages/articles.js.map +1 -1
  175. package/support/pages/conversation-history.js +2 -2
  176. package/support/pages/conversation.js +6 -5
  177. package/support/pages/conversation.js.map +1 -1
  178. package/support/pages/home.js +2 -2
  179. package/support/router.d.ts +52 -12
  180. package/support/router.d.ts.map +1 -1
  181. package/support/router.js +78 -30
  182. package/support/router.js.map +1 -1
  183. package/support/store/index.d.ts +2 -2
  184. package/support/store/support-store.d.ts +26 -20
  185. package/support/store/support-store.d.ts.map +1 -1
  186. package/support/store/support-store.js +47 -6
  187. package/support/store/support-store.js.map +1 -1
  188. package/support/{support-D2EgfIts.css → support-C7Xaw-N6.css} +1 -2
  189. package/support/support-C7Xaw-N6.css.map +1 -0
  190. package/support/text/index.js.map +1 -1
  191. package/support/types.d.ts +75 -12
  192. package/support/types.d.ts.map +1 -1
  193. package/support.css +2 -2
  194. package/tailwind.css +0 -1
  195. package/timeline-item.d.ts +68 -2
  196. package/timeline-item.d.ts.map +1 -1
  197. package/util.d.ts +1 -1
  198. package/util.d.ts.map +1 -1
  199. package/utils/index.d.ts +2 -1
  200. package/utils/index.js +2 -1
  201. package/utils/merge-refs.d.ts +30 -0
  202. package/utils/merge-refs.d.ts.map +1 -0
  203. package/utils/merge-refs.js +46 -0
  204. package/utils/merge-refs.js.map +1 -0
  205. package/utils/use-render-element.d.ts.map +1 -1
  206. package/utils/use-render-element.js +20 -7
  207. package/utils/use-render-element.js.map +1 -1
  208. package/versions.d.ts +1 -1
  209. package/versions.d.ts.map +1 -1
  210. package/zod-extensions.d.ts +1 -1
  211. package/zod-extensions.d.ts.map +1 -1
  212. package/primitives/bubble.d.ts +0 -38
  213. package/primitives/bubble.d.ts.map +0 -1
  214. package/primitives/bubble.js +0 -57
  215. package/primitives/bubble.js.map +0 -1
  216. package/support/components/bubble.d.ts +0 -10
  217. package/support/components/bubble.d.ts.map +0 -1
  218. package/support/components/bubble.js.map +0 -1
  219. package/support/components/container.d.ts +0 -13
  220. package/support/components/container.d.ts.map +0 -1
  221. package/support/components/container.js +0 -109
  222. package/support/components/container.js.map +0 -1
  223. package/support/components/support-content.d.ts +0 -22
  224. package/support/components/support-content.d.ts.map +0 -1
  225. package/support/components/support-content.js +0 -48
  226. package/support/components/support-content.js.map +0 -1
  227. package/support/support-D2EgfIts.css.map +0 -1
@@ -0,0 +1,85 @@
1
+ import * as React$1 from "react";
2
+
3
+ //#region src/support/context/slots.d.ts
4
+ type SlotContextValue = {
5
+ /**
6
+ * Custom header slot content
7
+ */
8
+ header: React$1.ReactNode | null;
9
+ /**
10
+ * Custom footer slot content
11
+ */
12
+ footer: React$1.ReactNode | null;
13
+ /**
14
+ * Whether to use the custom header
15
+ */
16
+ hasCustomHeader: boolean;
17
+ /**
18
+ * Whether to use the custom footer
19
+ */
20
+ hasCustomFooter: boolean;
21
+ };
22
+ type SlotProviderProps = {
23
+ children: React$1.ReactNode;
24
+ };
25
+ /**
26
+ * Provider for slot-based customization.
27
+ * Allows children to register custom header/footer content.
28
+ */
29
+ declare const SlotProvider: React$1.FC<SlotProviderProps>;
30
+ /**
31
+ * Access slot values (for content component)
32
+ */
33
+ declare function useSlots(): SlotContextValue;
34
+ type SlotProps = {
35
+ /**
36
+ * Content to render in the slot.
37
+ */
38
+ children: React$1.ReactNode;
39
+ /**
40
+ * When true, renders children directly without a wrapper.
41
+ * Useful when you want your component to receive all props.
42
+ */
43
+ asChild?: boolean;
44
+ };
45
+ /**
46
+ * Header slot component.
47
+ * Use inside Support.Content to replace the default header.
48
+ *
49
+ * @example
50
+ * <Support.Content>
51
+ * <Support.Header>
52
+ * <MyCustomHeader />
53
+ * </Support.Header>
54
+ * <Support.Router />
55
+ * </Support.Content>
56
+ *
57
+ * @example
58
+ * // With asChild pattern
59
+ * <Support.Header asChild>
60
+ * <MyCustomHeader showBackButton />
61
+ * </Support.Header>
62
+ */
63
+ declare const HeaderSlot: React$1.FC<SlotProps>;
64
+ /**
65
+ * Footer slot component.
66
+ * Use inside Support.Content to replace the default footer.
67
+ *
68
+ * @example
69
+ * <Support.Content>
70
+ * <Support.Router />
71
+ * <Support.Footer>
72
+ * <MyCustomFooter />
73
+ * </Support.Footer>
74
+ * </Support.Content>
75
+ *
76
+ * @example
77
+ * // With asChild pattern
78
+ * <Support.Footer asChild>
79
+ * <MyCustomFooter showBranding={false} />
80
+ * </Support.Footer>
81
+ */
82
+ declare const FooterSlot: React$1.FC<SlotProps>;
83
+ //#endregion
84
+ export { FooterSlot, HeaderSlot, SlotContextValue, SlotProps, SlotProvider, SlotProviderProps, useSlots };
85
+ //# sourceMappingURL=slots.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slots.d.ts","names":[],"sources":["../../../src/support/context/slots.tsx"],"sourcesContent":[],"mappings":";;;KAQY,gBAAA;;AAAZ;AAyCA;EAQa,MAAA,EA7CJ,OAAA,CAAM,SA0Ed,GAAA,IA7BmC;EAsCpB;AAehB;AA8BA;EAoCa,MAAA,EAhKJ,OAAA,CAAM,SA6Kd,GAbiC,IAAA;;;;;;;;;;KA/HtB,iBAAA;YACD,OAAA,CAAM;;;;;;cAOJ,cAAc,OAAA,CAAM,GAAG;;;;iBAsCpB,QAAA,CAAA,GAAY;KAehB,SAAA;;;;YAID,OAAA,CAAM;;;;;;;;;;;;;;;;;;;;;;;;;cA0BJ,YAAY,OAAA,CAAM,GAAG;;;;;;;;;;;;;;;;;;;cAoCrB,YAAY,OAAA,CAAM,GAAG"}
@@ -0,0 +1,115 @@
1
+ "use client";
2
+
3
+
4
+ import * as React$1 from "react";
5
+ import { jsx } from "react/jsx-runtime";
6
+
7
+ //#region src/support/context/slots.tsx
8
+ const SlotContext = React$1.createContext({
9
+ header: null,
10
+ footer: null,
11
+ hasCustomHeader: false,
12
+ hasCustomFooter: false
13
+ });
14
+ const SlotRegistrationContext = React$1.createContext(null);
15
+ /**
16
+ * Provider for slot-based customization.
17
+ * Allows children to register custom header/footer content.
18
+ */
19
+ const SlotProvider = ({ children }) => {
20
+ const [header, setHeader] = React$1.useState(null);
21
+ const [footer, setFooter] = React$1.useState(null);
22
+ const registration = React$1.useMemo(() => ({
23
+ registerHeader: (content) => setHeader(content),
24
+ registerFooter: (content) => setFooter(content),
25
+ unregisterHeader: () => setHeader(null),
26
+ unregisterFooter: () => setFooter(null)
27
+ }), []);
28
+ const value = React$1.useMemo(() => ({
29
+ header,
30
+ footer,
31
+ hasCustomHeader: header !== null,
32
+ hasCustomFooter: footer !== null
33
+ }), [header, footer]);
34
+ return /* @__PURE__ */ jsx(SlotRegistrationContext.Provider, {
35
+ value: registration,
36
+ children: /* @__PURE__ */ jsx(SlotContext.Provider, {
37
+ value,
38
+ children
39
+ })
40
+ });
41
+ };
42
+ /**
43
+ * Access slot values (for content component)
44
+ */
45
+ function useSlots() {
46
+ return React$1.useContext(SlotContext);
47
+ }
48
+ /**
49
+ * Access slot registration (for slot components)
50
+ */
51
+ function useSlotRegistration() {
52
+ return React$1.useContext(SlotRegistrationContext);
53
+ }
54
+ /**
55
+ * Header slot component.
56
+ * Use inside Support.Content to replace the default header.
57
+ *
58
+ * @example
59
+ * <Support.Content>
60
+ * <Support.Header>
61
+ * <MyCustomHeader />
62
+ * </Support.Header>
63
+ * <Support.Router />
64
+ * </Support.Content>
65
+ *
66
+ * @example
67
+ * // With asChild pattern
68
+ * <Support.Header asChild>
69
+ * <MyCustomHeader showBackButton />
70
+ * </Support.Header>
71
+ */
72
+ const HeaderSlot = ({ children, asChild }) => {
73
+ const registration = useSlotRegistration();
74
+ React$1.useEffect(() => {
75
+ if (registration) {
76
+ registration.registerHeader(children);
77
+ return () => registration.unregisterHeader();
78
+ }
79
+ }, [registration, children]);
80
+ return null;
81
+ };
82
+ HeaderSlot.displayName = "Support.Header";
83
+ /**
84
+ * Footer slot component.
85
+ * Use inside Support.Content to replace the default footer.
86
+ *
87
+ * @example
88
+ * <Support.Content>
89
+ * <Support.Router />
90
+ * <Support.Footer>
91
+ * <MyCustomFooter />
92
+ * </Support.Footer>
93
+ * </Support.Content>
94
+ *
95
+ * @example
96
+ * // With asChild pattern
97
+ * <Support.Footer asChild>
98
+ * <MyCustomFooter showBranding={false} />
99
+ * </Support.Footer>
100
+ */
101
+ const FooterSlot = ({ children, asChild }) => {
102
+ const registration = useSlotRegistration();
103
+ React$1.useEffect(() => {
104
+ if (registration) {
105
+ registration.registerFooter(children);
106
+ return () => registration.unregisterFooter();
107
+ }
108
+ }, [registration, children]);
109
+ return null;
110
+ };
111
+ FooterSlot.displayName = "Support.Footer";
112
+
113
+ //#endregion
114
+ export { FooterSlot, HeaderSlot, SlotProvider, useSlots };
115
+ //# sourceMappingURL=slots.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slots.js","names":["React","SlotProvider: React.FC<SlotProviderProps>","HeaderSlot: React.FC<SlotProps>","FooterSlot: React.FC<SlotProps>"],"sources":["../../../src/support/context/slots.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\n\n// =============================================================================\n// Slot Types\n// =============================================================================\n\nexport type SlotContextValue = {\n\t/**\n\t * Custom header slot content\n\t */\n\theader: React.ReactNode | null;\n\t/**\n\t * Custom footer slot content\n\t */\n\tfooter: React.ReactNode | null;\n\t/**\n\t * Whether to use the custom header\n\t */\n\thasCustomHeader: boolean;\n\t/**\n\t * Whether to use the custom footer\n\t */\n\thasCustomFooter: boolean;\n};\n\ntype SlotRegistration = {\n\tregisterHeader: (content: React.ReactNode) => void;\n\tregisterFooter: (content: React.ReactNode) => void;\n\tunregisterHeader: () => void;\n\tunregisterFooter: () => void;\n};\n\nconst SlotContext = React.createContext<SlotContextValue>({\n\theader: null,\n\tfooter: null,\n\thasCustomHeader: false,\n\thasCustomFooter: false,\n});\n\nconst SlotRegistrationContext = React.createContext<SlotRegistration | null>(\n\tnull\n);\n\n// =============================================================================\n// Provider\n// =============================================================================\n\nexport type SlotProviderProps = {\n\tchildren: React.ReactNode;\n};\n\n/**\n * Provider for slot-based customization.\n * Allows children to register custom header/footer content.\n */\nexport const SlotProvider: React.FC<SlotProviderProps> = ({ children }) => {\n\tconst [header, setHeader] = React.useState<React.ReactNode | null>(null);\n\tconst [footer, setFooter] = React.useState<React.ReactNode | null>(null);\n\n\tconst registration = React.useMemo<SlotRegistration>(\n\t\t() => ({\n\t\t\tregisterHeader: (content) => setHeader(content),\n\t\t\tregisterFooter: (content) => setFooter(content),\n\t\t\tunregisterHeader: () => setHeader(null),\n\t\t\tunregisterFooter: () => setFooter(null),\n\t\t}),\n\t\t[]\n\t);\n\n\tconst value = React.useMemo<SlotContextValue>(\n\t\t() => ({\n\t\t\theader,\n\t\t\tfooter,\n\t\t\thasCustomHeader: header !== null,\n\t\t\thasCustomFooter: footer !== null,\n\t\t}),\n\t\t[header, footer]\n\t);\n\n\treturn (\n\t\t<SlotRegistrationContext.Provider value={registration}>\n\t\t\t<SlotContext.Provider value={value}>{children}</SlotContext.Provider>\n\t\t</SlotRegistrationContext.Provider>\n\t);\n};\n\n// =============================================================================\n// Hooks\n// =============================================================================\n\n/**\n * Access slot values (for content component)\n */\nexport function useSlots(): SlotContextValue {\n\treturn React.useContext(SlotContext);\n}\n\n/**\n * Access slot registration (for slot components)\n */\nfunction useSlotRegistration(): SlotRegistration | null {\n\treturn React.useContext(SlotRegistrationContext);\n}\n\n// =============================================================================\n// Slot Components\n// =============================================================================\n\nexport type SlotProps = {\n\t/**\n\t * Content to render in the slot.\n\t */\n\tchildren: React.ReactNode;\n\t/**\n\t * When true, renders children directly without a wrapper.\n\t * Useful when you want your component to receive all props.\n\t */\n\tasChild?: boolean;\n};\n\n/**\n * Header slot component.\n * Use inside Support.Content to replace the default header.\n *\n * @example\n * <Support.Content>\n * <Support.Header>\n * <MyCustomHeader />\n * </Support.Header>\n * <Support.Router />\n * </Support.Content>\n *\n * @example\n * // With asChild pattern\n * <Support.Header asChild>\n * <MyCustomHeader showBackButton />\n * </Support.Header>\n */\nexport const HeaderSlot: React.FC<SlotProps> = ({ children, asChild }) => {\n\tconst registration = useSlotRegistration();\n\n\tReact.useEffect(() => {\n\t\tif (registration) {\n\t\t\tregistration.registerHeader(children);\n\t\t\treturn () => registration.unregisterHeader();\n\t\t}\n\t}, [registration, children]);\n\n\t// This component doesn't render anything directly\n\t// It registers its children as the header slot\n\treturn null;\n};\n\n(HeaderSlot as React.FC & { displayName?: string }).displayName =\n\t\"Support.Header\";\n\n/**\n * Footer slot component.\n * Use inside Support.Content to replace the default footer.\n *\n * @example\n * <Support.Content>\n * <Support.Router />\n * <Support.Footer>\n * <MyCustomFooter />\n * </Support.Footer>\n * </Support.Content>\n *\n * @example\n * // With asChild pattern\n * <Support.Footer asChild>\n * <MyCustomFooter showBranding={false} />\n * </Support.Footer>\n */\nexport const FooterSlot: React.FC<SlotProps> = ({ children, asChild }) => {\n\tconst registration = useSlotRegistration();\n\n\tReact.useEffect(() => {\n\t\tif (registration) {\n\t\t\tregistration.registerFooter(children);\n\t\t\treturn () => registration.unregisterFooter();\n\t\t}\n\t}, [registration, children]);\n\n\t// This component doesn't render anything directly\n\t// It registers its children as the footer slot\n\treturn null;\n};\n\n(FooterSlot as React.FC & { displayName?: string }).displayName =\n\t\"Support.Footer\";\n"],"mappings":";;;;;;;AAkCA,MAAM,cAAcA,QAAM,cAAgC;CACzD,QAAQ;CACR,QAAQ;CACR,iBAAiB;CACjB,iBAAiB;CACjB,CAAC;AAEF,MAAM,0BAA0BA,QAAM,cACrC,KACA;;;;;AAcD,MAAaC,gBAA6C,EAAE,eAAe;CAC1E,MAAM,CAAC,QAAQ,aAAaD,QAAM,SAAiC,KAAK;CACxE,MAAM,CAAC,QAAQ,aAAaA,QAAM,SAAiC,KAAK;CAExE,MAAM,eAAeA,QAAM,eACnB;EACN,iBAAiB,YAAY,UAAU,QAAQ;EAC/C,iBAAiB,YAAY,UAAU,QAAQ;EAC/C,wBAAwB,UAAU,KAAK;EACvC,wBAAwB,UAAU,KAAK;EACvC,GACD,EAAE,CACF;CAED,MAAM,QAAQA,QAAM,eACZ;EACN;EACA;EACA,iBAAiB,WAAW;EAC5B,iBAAiB,WAAW;EAC5B,GACD,CAAC,QAAQ,OAAO,CAChB;AAED,QACC,oBAAC,wBAAwB;EAAS,OAAO;YACxC,oBAAC,YAAY;GAAgB;GAAQ;IAAgC;GACnC;;;;;AAWrC,SAAgB,WAA6B;AAC5C,QAAOA,QAAM,WAAW,YAAY;;;;;AAMrC,SAAS,sBAA+C;AACvD,QAAOA,QAAM,WAAW,wBAAwB;;;;;;;;;;;;;;;;;;;;AAqCjD,MAAaE,cAAmC,EAAE,UAAU,cAAc;CACzE,MAAM,eAAe,qBAAqB;AAE1C,SAAM,gBAAgB;AACrB,MAAI,cAAc;AACjB,gBAAa,eAAe,SAAS;AACrC,gBAAa,aAAa,kBAAkB;;IAE3C,CAAC,cAAc,SAAS,CAAC;AAI5B,QAAO;;AAGR,AAAC,WAAmD,cACnD;;;;;;;;;;;;;;;;;;;AAoBD,MAAaC,cAAmC,EAAE,UAAU,cAAc;CACzE,MAAM,eAAe,qBAAqB;AAE1C,SAAM,gBAAgB;AACrB,MAAI,cAAc;AACjB,gBAAa,eAAe,SAAS;AACrC,gBAAa,aAAa,kBAAkB;;IAE3C,CAAC,cAAc,SAAS,CAAC;AAI5B,QAAO;;AAGR,AAAC,WAAmD,cACnD"}
@@ -23,8 +23,15 @@ type WebSocketProviderProps = {
23
23
  declare const WebSocketProvider: React.FC<WebSocketProviderProps>;
24
24
  /**
25
25
  * Accessor for the support websocket context.
26
+ * Throws if used outside WebSocketProvider.
26
27
  */
27
28
  declare const useWebSocket: () => WebSocketContextValue;
29
+ /**
30
+ * Safe accessor for the support websocket context.
31
+ * Returns null if used outside WebSocketProvider instead of throwing.
32
+ * Useful for optional WebSocket usage in hooks that may or may not have the provider.
33
+ */
34
+ declare const useWebSocketSafe: () => WebSocketContextValue | null;
28
35
  //#endregion
29
- export { type RealtimeEvent, type WebSocketContextValue, WebSocketProvider, type WebSocketProviderProps, useWebSocket };
36
+ export { type RealtimeEvent, type WebSocketContextValue, WebSocketProvider, type WebSocketProviderProps, useWebSocket, useWebSocketSafe };
30
37
  //# sourceMappingURL=websocket.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"websocket.d.ts","names":[],"sources":["../../../src/support/context/websocket.tsx"],"sourcesContent":[],"mappings":";;;;;;KAYK,qBAAA,GAAwB;KAExB,sBAAA;YACM,KAAA,CAAM;;EAHZ,SAAA,CAAA,EAAA,MAAA;EAEA,SAAA,CAAA,EAAA,MAAA;EAsJQ,KAAA,CAAA,EAAA,MAAA;EA8BA,WAAA,CAAA,EAAA,OAMZ;;;oBAjLkB;;;;;;cA6IN,mBAAmB,KAAA,CAAM,GAAG;;;;cA8B5B,oBAAmB"}
1
+ {"version":3,"file":"websocket.d.ts","names":[],"sources":["../../../src/support/context/websocket.tsx"],"sourcesContent":[],"mappings":";;;;;;KAYK,qBAAA,GAAwB;KAExB,sBAAA;YACM,KAAA,CAAM;;EAHZ,SAAA,CAAA,EAAA,MAAA;EAEA,SAAA,CAAA,EAAA,MAAA;EAsJQ,KAAA,CAAA,EAAA,MAAA;EA+BA,WAAA,CAAA,EAAA,OAMZ;EAOY,SAAA,CAAA,EAAA,GAAA,GAAA,IACgB;;oBA1LV;;;;;;cA6IN,mBAAmB,KAAA,CAAM,GAAG;;;;;cA+B5B,oBAAmB;;;;;;cAanB,wBAAuB"}
@@ -107,13 +107,20 @@ const WebSocketProvider = ({ children, publicKey, websiteId, visitorId, wsUrl, a
107
107
  };
108
108
  /**
109
109
  * Accessor for the support websocket context.
110
+ * Throws if used outside WebSocketProvider.
110
111
  */
111
112
  const useWebSocket = () => {
112
113
  const context = useContext(WebSocketContext);
113
114
  if (!context) throw new Error("useWebSocket must be used within WebSocketProvider");
114
115
  return context;
115
116
  };
117
+ /**
118
+ * Safe accessor for the support websocket context.
119
+ * Returns null if used outside WebSocketProvider instead of throwing.
120
+ * Useful for optional WebSocket usage in hooks that may or may not have the provider.
121
+ */
122
+ const useWebSocketSafe = () => useContext(WebSocketContext);
116
123
 
117
124
  //#endregion
118
- export { WebSocketProvider, useWebSocket };
125
+ export { WebSocketProvider, useWebSocket, useWebSocketSafe };
119
126
  //# sourceMappingURL=websocket.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"websocket.js","names":["WebSocketBridge: React.FC<WebSocketBridgeProps>","intervalId: number | null","WebSocketProvider: React.FC<WebSocketProviderProps>"],"sources":["../../../src/support/context/websocket.tsx"],"sourcesContent":["\"use client\";\n\nimport { PRESENCE_PING_INTERVAL_MS } from \"@cossistant/types\";\nimport type React from \"react\";\nimport { createContext, useContext, useEffect, useMemo } from \"react\";\nimport {\n\ttype RealtimeAuthConfig,\n\ttype RealtimeContextValue,\n\tRealtimeProvider,\n\tuseRealtimeConnection,\n} from \"../../realtime\";\n\ntype WebSocketContextValue = RealtimeContextValue;\n\ntype WebSocketProviderProps = {\n\tchildren: React.ReactNode;\n\tpublicKey?: string;\n\twebsiteId?: string;\n\tvisitorId?: string;\n\twsUrl?: string;\n\tautoConnect?: boolean;\n\tonConnect?: () => void;\n\tonDisconnect?: () => void;\n\tonError?: (error: Error) => void;\n};\n\nconst WebSocketContext = createContext<WebSocketContextValue | null>(null);\n\nfunction createVisitorAuthConfig({\n\tvisitorId,\n\twebsiteId,\n\tpublicKey,\n}: Pick<\n\tWebSocketProviderProps,\n\t\"visitorId\" | \"websiteId\" | \"publicKey\"\n>): RealtimeAuthConfig | null {\n\tconst normalizedVisitorId = visitorId?.trim();\n\tif (!normalizedVisitorId) {\n\t\treturn null;\n\t}\n\n\treturn {\n\t\tkind: \"visitor\",\n\t\tvisitorId: normalizedVisitorId,\n\t\twebsiteId: websiteId?.trim() || null,\n\t\tpublicKey: publicKey?.trim() || null,\n\t} satisfies RealtimeAuthConfig;\n}\n\ntype WebSocketBridgeProps = {\n\tchildren: React.ReactNode;\n\tonError?: (error: Error) => void;\n};\n\nconst WebSocketBridge: React.FC<WebSocketBridgeProps> = ({\n\tchildren,\n\tonError,\n}) => {\n\tconst connection = useRealtimeConnection();\n\tconst { visitorId, sendRaw, isConnected } = connection;\n\n\tuseEffect(() => {\n\t\tif (typeof window === \"undefined\" || typeof document === \"undefined\") {\n\t\t\treturn;\n\t\t}\n\n\t\tif (!(visitorId && sendRaw)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst pingMessage = \"presence:ping\";\n\n\t\tconst sendPresencePing = () => {\n\t\t\tif (!isConnected) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tsendRaw(pingMessage);\n\t\t\t} catch (error) {\n\t\t\t\tif (!onError) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst normalizedError =\n\t\t\t\t\terror instanceof Error\n\t\t\t\t\t\t? error\n\t\t\t\t\t\t: new Error(\n\t\t\t\t\t\t\t\ttypeof error === \"string\"\n\t\t\t\t\t\t\t\t\t? error\n\t\t\t\t\t\t\t\t\t: \"Unknown presence ping error\"\n\t\t\t\t\t\t\t);\n\n\t\t\t\tif (!normalizedError.message.includes(\"Failed to send presence ping\")) {\n\t\t\t\t\tnormalizedError.message = `Failed to send presence ping: ${normalizedError.message}`;\n\t\t\t\t}\n\n\t\t\t\tonError(normalizedError);\n\t\t\t}\n\t\t};\n\n\t\tlet intervalId: number | null = null;\n\n\t\tconst clearPresenceInterval = () => {\n\t\t\tif (intervalId !== null) {\n\t\t\t\twindow.clearInterval(intervalId);\n\t\t\t\tintervalId = null;\n\t\t\t}\n\t\t};\n\n\t\tconst startPresenceInterval = () => {\n\t\t\tclearPresenceInterval();\n\n\t\t\tif (!isConnected || document.visibilityState === \"hidden\") {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tintervalId = window.setInterval(\n\t\t\t\tsendPresencePing,\n\t\t\t\tPRESENCE_PING_INTERVAL_MS\n\t\t\t);\n\t\t};\n\n\t\tconst handleFocus = () => {\n\t\t\tsendPresencePing();\n\t\t\tstartPresenceInterval();\n\t\t};\n\n\t\tconst handleVisibilityChange = () => {\n\t\t\tif (document.visibilityState === \"hidden\") {\n\t\t\t\tclearPresenceInterval();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tsendPresencePing();\n\t\t\tstartPresenceInterval();\n\t\t};\n\n\t\twindow.addEventListener(\"focus\", handleFocus);\n\t\tdocument.addEventListener(\"visibilitychange\", handleVisibilityChange);\n\n\t\tif (isConnected && document.visibilityState !== \"hidden\") {\n\t\t\tsendPresencePing();\n\t\t\tstartPresenceInterval();\n\t\t}\n\n\t\treturn () => {\n\t\t\twindow.removeEventListener(\"focus\", handleFocus);\n\t\t\tdocument.removeEventListener(\"visibilitychange\", handleVisibilityChange);\n\t\t\tclearPresenceInterval();\n\t\t};\n\t}, [isConnected, onError, sendRaw, visitorId]);\n\tconst value = useMemo(() => connection, [connection]);\n\treturn (\n\t\t<WebSocketContext.Provider value={value}>\n\t\t\t{children}\n\t\t</WebSocketContext.Provider>\n\t);\n};\n\n/**\n * Support-specific realtime provider that authenticates visitors and keeps the\n * connection alive with presence pings.\n */\nexport const WebSocketProvider: React.FC<WebSocketProviderProps> = ({\n\tchildren,\n\tpublicKey,\n\twebsiteId,\n\tvisitorId,\n\twsUrl,\n\tautoConnect = true,\n\tonConnect,\n\tonDisconnect,\n\tonError,\n}) => {\n\tconst auth = createVisitorAuthConfig({ publicKey, websiteId, visitorId });\n\n\treturn (\n\t\t<RealtimeProvider\n\t\t\tauth={auth}\n\t\t\tautoConnect={autoConnect}\n\t\t\tonConnect={onConnect}\n\t\t\tonDisconnect={onDisconnect}\n\t\t\tonError={onError}\n\t\t\twsUrl={wsUrl}\n\t\t>\n\t\t\t<WebSocketBridge onError={onError}>{children}</WebSocketBridge>\n\t\t</RealtimeProvider>\n\t);\n};\n\n/**\n * Accessor for the support websocket context.\n */\nexport const useWebSocket = (): WebSocketContextValue => {\n\tconst context = useContext(WebSocketContext);\n\tif (!context) {\n\t\tthrow new Error(\"useWebSocket must be used within WebSocketProvider\");\n\t}\n\treturn context;\n};\n\nexport type { WebSocketContextValue, WebSocketProviderProps };\nexport type { RealtimeEvent } from \"@cossistant/types/realtime-events\";\n"],"mappings":";;;;;;;;;AA0BA,MAAM,mBAAmB,cAA4C,KAAK;AAE1E,SAAS,wBAAwB,EAChC,WACA,WACA,aAI6B;CAC7B,MAAM,sBAAsB,WAAW,MAAM;AAC7C,KAAI,CAAC,oBACJ,QAAO;AAGR,QAAO;EACN,MAAM;EACN,WAAW;EACX,WAAW,WAAW,MAAM,IAAI;EAChC,WAAW,WAAW,MAAM,IAAI;EAChC;;AAQF,MAAMA,mBAAmD,EACxD,UACA,cACK;CACL,MAAM,aAAa,uBAAuB;CAC1C,MAAM,EAAE,WAAW,SAAS,gBAAgB;AAE5C,iBAAgB;AACf,MAAI,OAAO,WAAW,eAAe,OAAO,aAAa,YACxD;AAGD,MAAI,EAAE,aAAa,SAClB;EAGD,MAAM,cAAc;EAEpB,MAAM,yBAAyB;AAC9B,OAAI,CAAC,YACJ;AAGD,OAAI;AACH,YAAQ,YAAY;YACZ,OAAO;AACf,QAAI,CAAC,QACJ;IAGD,MAAM,kBACL,iBAAiB,QACd,QACA,IAAI,MACJ,OAAO,UAAU,WACd,QACA,8BACH;AAEJ,QAAI,CAAC,gBAAgB,QAAQ,SAAS,+BAA+B,CACpE,iBAAgB,UAAU,iCAAiC,gBAAgB;AAG5E,YAAQ,gBAAgB;;;EAI1B,IAAIC,aAA4B;EAEhC,MAAM,8BAA8B;AACnC,OAAI,eAAe,MAAM;AACxB,WAAO,cAAc,WAAW;AAChC,iBAAa;;;EAIf,MAAM,8BAA8B;AACnC,0BAAuB;AAEvB,OAAI,CAAC,eAAe,SAAS,oBAAoB,SAChD;AAGD,gBAAa,OAAO,YACnB,kBACA,0BACA;;EAGF,MAAM,oBAAoB;AACzB,qBAAkB;AAClB,0BAAuB;;EAGxB,MAAM,+BAA+B;AACpC,OAAI,SAAS,oBAAoB,UAAU;AAC1C,2BAAuB;AACvB;;AAGD,qBAAkB;AAClB,0BAAuB;;AAGxB,SAAO,iBAAiB,SAAS,YAAY;AAC7C,WAAS,iBAAiB,oBAAoB,uBAAuB;AAErE,MAAI,eAAe,SAAS,oBAAoB,UAAU;AACzD,qBAAkB;AAClB,0BAAuB;;AAGxB,eAAa;AACZ,UAAO,oBAAoB,SAAS,YAAY;AAChD,YAAS,oBAAoB,oBAAoB,uBAAuB;AACxE,0BAAuB;;IAEtB;EAAC;EAAa;EAAS;EAAS;EAAU,CAAC;CAC9C,MAAM,QAAQ,cAAc,YAAY,CAAC,WAAW,CAAC;AACrD,QACC,oBAAC,iBAAiB;EAAgB;EAChC;GAC0B;;;;;;AAQ9B,MAAaC,qBAAuD,EACnE,UACA,WACA,WACA,WACA,OACA,cAAc,MACd,WACA,cACA,cACK;AAGL,QACC,oBAAC;EACA,MAJW,wBAAwB;GAAE;GAAW;GAAW;GAAW,CAAC;EAK1D;EACF;EACG;EACL;EACF;YAEP,oBAAC;GAAyB;GAAU;IAA2B;GAC7C;;;;;AAOrB,MAAa,qBAA4C;CACxD,MAAM,UAAU,WAAW,iBAAiB;AAC5C,KAAI,CAAC,QACJ,OAAM,IAAI,MAAM,qDAAqD;AAEtE,QAAO"}
1
+ {"version":3,"file":"websocket.js","names":["WebSocketBridge: React.FC<WebSocketBridgeProps>","intervalId: number | null","WebSocketProvider: React.FC<WebSocketProviderProps>"],"sources":["../../../src/support/context/websocket.tsx"],"sourcesContent":["\"use client\";\n\nimport { PRESENCE_PING_INTERVAL_MS } from \"@cossistant/types\";\nimport type React from \"react\";\nimport { createContext, useContext, useEffect, useMemo } from \"react\";\nimport {\n\ttype RealtimeAuthConfig,\n\ttype RealtimeContextValue,\n\tRealtimeProvider,\n\tuseRealtimeConnection,\n} from \"../../realtime\";\n\ntype WebSocketContextValue = RealtimeContextValue;\n\ntype WebSocketProviderProps = {\n\tchildren: React.ReactNode;\n\tpublicKey?: string;\n\twebsiteId?: string;\n\tvisitorId?: string;\n\twsUrl?: string;\n\tautoConnect?: boolean;\n\tonConnect?: () => void;\n\tonDisconnect?: () => void;\n\tonError?: (error: Error) => void;\n};\n\nconst WebSocketContext = createContext<WebSocketContextValue | null>(null);\n\nfunction createVisitorAuthConfig({\n\tvisitorId,\n\twebsiteId,\n\tpublicKey,\n}: Pick<\n\tWebSocketProviderProps,\n\t\"visitorId\" | \"websiteId\" | \"publicKey\"\n>): RealtimeAuthConfig | null {\n\tconst normalizedVisitorId = visitorId?.trim();\n\tif (!normalizedVisitorId) {\n\t\treturn null;\n\t}\n\n\treturn {\n\t\tkind: \"visitor\",\n\t\tvisitorId: normalizedVisitorId,\n\t\twebsiteId: websiteId?.trim() || null,\n\t\tpublicKey: publicKey?.trim() || null,\n\t} satisfies RealtimeAuthConfig;\n}\n\ntype WebSocketBridgeProps = {\n\tchildren: React.ReactNode;\n\tonError?: (error: Error) => void;\n};\n\nconst WebSocketBridge: React.FC<WebSocketBridgeProps> = ({\n\tchildren,\n\tonError,\n}) => {\n\tconst connection = useRealtimeConnection();\n\tconst { visitorId, sendRaw, isConnected } = connection;\n\n\tuseEffect(() => {\n\t\tif (typeof window === \"undefined\" || typeof document === \"undefined\") {\n\t\t\treturn;\n\t\t}\n\n\t\tif (!(visitorId && sendRaw)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst pingMessage = \"presence:ping\";\n\n\t\tconst sendPresencePing = () => {\n\t\t\tif (!isConnected) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tsendRaw(pingMessage);\n\t\t\t} catch (error) {\n\t\t\t\tif (!onError) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst normalizedError =\n\t\t\t\t\terror instanceof Error\n\t\t\t\t\t\t? error\n\t\t\t\t\t\t: new Error(\n\t\t\t\t\t\t\t\ttypeof error === \"string\"\n\t\t\t\t\t\t\t\t\t? error\n\t\t\t\t\t\t\t\t\t: \"Unknown presence ping error\"\n\t\t\t\t\t\t\t);\n\n\t\t\t\tif (!normalizedError.message.includes(\"Failed to send presence ping\")) {\n\t\t\t\t\tnormalizedError.message = `Failed to send presence ping: ${normalizedError.message}`;\n\t\t\t\t}\n\n\t\t\t\tonError(normalizedError);\n\t\t\t}\n\t\t};\n\n\t\tlet intervalId: number | null = null;\n\n\t\tconst clearPresenceInterval = () => {\n\t\t\tif (intervalId !== null) {\n\t\t\t\twindow.clearInterval(intervalId);\n\t\t\t\tintervalId = null;\n\t\t\t}\n\t\t};\n\n\t\tconst startPresenceInterval = () => {\n\t\t\tclearPresenceInterval();\n\n\t\t\tif (!isConnected || document.visibilityState === \"hidden\") {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tintervalId = window.setInterval(\n\t\t\t\tsendPresencePing,\n\t\t\t\tPRESENCE_PING_INTERVAL_MS\n\t\t\t);\n\t\t};\n\n\t\tconst handleFocus = () => {\n\t\t\tsendPresencePing();\n\t\t\tstartPresenceInterval();\n\t\t};\n\n\t\tconst handleVisibilityChange = () => {\n\t\t\tif (document.visibilityState === \"hidden\") {\n\t\t\t\tclearPresenceInterval();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tsendPresencePing();\n\t\t\tstartPresenceInterval();\n\t\t};\n\n\t\twindow.addEventListener(\"focus\", handleFocus);\n\t\tdocument.addEventListener(\"visibilitychange\", handleVisibilityChange);\n\n\t\tif (isConnected && document.visibilityState !== \"hidden\") {\n\t\t\tsendPresencePing();\n\t\t\tstartPresenceInterval();\n\t\t}\n\n\t\treturn () => {\n\t\t\twindow.removeEventListener(\"focus\", handleFocus);\n\t\t\tdocument.removeEventListener(\"visibilitychange\", handleVisibilityChange);\n\t\t\tclearPresenceInterval();\n\t\t};\n\t}, [isConnected, onError, sendRaw, visitorId]);\n\tconst value = useMemo(() => connection, [connection]);\n\treturn (\n\t\t<WebSocketContext.Provider value={value}>\n\t\t\t{children}\n\t\t</WebSocketContext.Provider>\n\t);\n};\n\n/**\n * Support-specific realtime provider that authenticates visitors and keeps the\n * connection alive with presence pings.\n */\nexport const WebSocketProvider: React.FC<WebSocketProviderProps> = ({\n\tchildren,\n\tpublicKey,\n\twebsiteId,\n\tvisitorId,\n\twsUrl,\n\tautoConnect = true,\n\tonConnect,\n\tonDisconnect,\n\tonError,\n}) => {\n\tconst auth = createVisitorAuthConfig({ publicKey, websiteId, visitorId });\n\n\treturn (\n\t\t<RealtimeProvider\n\t\t\tauth={auth}\n\t\t\tautoConnect={autoConnect}\n\t\t\tonConnect={onConnect}\n\t\t\tonDisconnect={onDisconnect}\n\t\t\tonError={onError}\n\t\t\twsUrl={wsUrl}\n\t\t>\n\t\t\t<WebSocketBridge onError={onError}>{children}</WebSocketBridge>\n\t\t</RealtimeProvider>\n\t);\n};\n\n/**\n * Accessor for the support websocket context.\n * Throws if used outside WebSocketProvider.\n */\nexport const useWebSocket = (): WebSocketContextValue => {\n\tconst context = useContext(WebSocketContext);\n\tif (!context) {\n\t\tthrow new Error(\"useWebSocket must be used within WebSocketProvider\");\n\t}\n\treturn context;\n};\n\n/**\n * Safe accessor for the support websocket context.\n * Returns null if used outside WebSocketProvider instead of throwing.\n * Useful for optional WebSocket usage in hooks that may or may not have the provider.\n */\nexport const useWebSocketSafe = (): WebSocketContextValue | null =>\n\tuseContext(WebSocketContext);\n\nexport type { WebSocketContextValue, WebSocketProviderProps };\nexport type { RealtimeEvent } from \"@cossistant/types/realtime-events\";\n"],"mappings":";;;;;;;;;AA0BA,MAAM,mBAAmB,cAA4C,KAAK;AAE1E,SAAS,wBAAwB,EAChC,WACA,WACA,aAI6B;CAC7B,MAAM,sBAAsB,WAAW,MAAM;AAC7C,KAAI,CAAC,oBACJ,QAAO;AAGR,QAAO;EACN,MAAM;EACN,WAAW;EACX,WAAW,WAAW,MAAM,IAAI;EAChC,WAAW,WAAW,MAAM,IAAI;EAChC;;AAQF,MAAMA,mBAAmD,EACxD,UACA,cACK;CACL,MAAM,aAAa,uBAAuB;CAC1C,MAAM,EAAE,WAAW,SAAS,gBAAgB;AAE5C,iBAAgB;AACf,MAAI,OAAO,WAAW,eAAe,OAAO,aAAa,YACxD;AAGD,MAAI,EAAE,aAAa,SAClB;EAGD,MAAM,cAAc;EAEpB,MAAM,yBAAyB;AAC9B,OAAI,CAAC,YACJ;AAGD,OAAI;AACH,YAAQ,YAAY;YACZ,OAAO;AACf,QAAI,CAAC,QACJ;IAGD,MAAM,kBACL,iBAAiB,QACd,QACA,IAAI,MACJ,OAAO,UAAU,WACd,QACA,8BACH;AAEJ,QAAI,CAAC,gBAAgB,QAAQ,SAAS,+BAA+B,CACpE,iBAAgB,UAAU,iCAAiC,gBAAgB;AAG5E,YAAQ,gBAAgB;;;EAI1B,IAAIC,aAA4B;EAEhC,MAAM,8BAA8B;AACnC,OAAI,eAAe,MAAM;AACxB,WAAO,cAAc,WAAW;AAChC,iBAAa;;;EAIf,MAAM,8BAA8B;AACnC,0BAAuB;AAEvB,OAAI,CAAC,eAAe,SAAS,oBAAoB,SAChD;AAGD,gBAAa,OAAO,YACnB,kBACA,0BACA;;EAGF,MAAM,oBAAoB;AACzB,qBAAkB;AAClB,0BAAuB;;EAGxB,MAAM,+BAA+B;AACpC,OAAI,SAAS,oBAAoB,UAAU;AAC1C,2BAAuB;AACvB;;AAGD,qBAAkB;AAClB,0BAAuB;;AAGxB,SAAO,iBAAiB,SAAS,YAAY;AAC7C,WAAS,iBAAiB,oBAAoB,uBAAuB;AAErE,MAAI,eAAe,SAAS,oBAAoB,UAAU;AACzD,qBAAkB;AAClB,0BAAuB;;AAGxB,eAAa;AACZ,UAAO,oBAAoB,SAAS,YAAY;AAChD,YAAS,oBAAoB,oBAAoB,uBAAuB;AACxE,0BAAuB;;IAEtB;EAAC;EAAa;EAAS;EAAS;EAAU,CAAC;CAC9C,MAAM,QAAQ,cAAc,YAAY,CAAC,WAAW,CAAC;AACrD,QACC,oBAAC,iBAAiB;EAAgB;EAChC;GAC0B;;;;;;AAQ9B,MAAaC,qBAAuD,EACnE,UACA,WACA,WACA,WACA,OACA,cAAc,MACd,WACA,cACA,cACK;AAGL,QACC,oBAAC;EACA,MAJW,wBAAwB;GAAE;GAAW;GAAW;GAAW,CAAC;EAK1D;EACF;EACG;EACL;EACF;YAEP,oBAAC;GAAyB;GAAU;IAA2B;GAC7C;;;;;;AAQrB,MAAa,qBAA4C;CACxD,MAAM,UAAU,WAAW,iBAAiB;AAC5C,KAAI,CAAC,QACJ,OAAM,IAAI,MAAM,qDAAqD;AAEtE,QAAO;;;;;;;AAQR,MAAa,yBACZ,WAAW,iBAAiB"}
@@ -1,74 +1,259 @@
1
1
  import { SupportLocale, SupportTextContentOverrides } from "./text/locales/keys.js";
2
- import { CustomPage } from "./router.js";
2
+ import { CustomPage, PageProps } from "./router.js";
3
+ import { SlotProps } from "./context/slots.js";
4
+ import { ConversationEndEvent, ConversationStartEvent, ErrorEvent, MessageReceivedEvent, MessageSentEvent, SupportEvent, SupportEventCallbacks, SupportEventType, useSupportEventEmitter, useSupportEvents } from "./context/events.js";
5
+ import { SupportHandle, useSupportHandle } from "./context/handle.js";
3
6
  import { Text, useSupportText } from "./text/index.js";
4
- import { BubbleSlotProps, ContainerSlotProps, RouterSlotProps } from "./types.js";
7
+ import { Align, CollisionPadding, ContentProps, RootProps, Side, TriggerRenderProps } from "./types.js";
5
8
  import { CoButton } from "./components/button.js";
6
9
  import { Header } from "./components/header.js";
7
10
  import { WebSocketContextValue, WebSocketProvider, useWebSocket } from "./context/websocket.js";
8
11
  import { useSupportConfig, useSupportNavigation, useSupportStore } from "./store/support-store.js";
9
12
  import "./store/index.js";
10
- import React, { ReactElement } from "react";
11
- import { DefaultRoutes, NavigationState, RouteRegistry, SupportPage } from "@cossistant/core";
13
+ import * as React$1 from "react";
14
+ import * as _cossistant_core0 from "@cossistant/core";
15
+ import { DefaultRoutes, NavigationState, RouteRegistry, SupportPage as SupportPageType } from "@cossistant/core";
12
16
  import { DefaultMessage } from "@cossistant/types";
13
17
 
14
18
  //#region src/support/index.d.ts
15
19
  type SupportProps<Locale extends string = SupportLocale> = {
20
+ /**
21
+ * Additional CSS classes for the root wrapper.
22
+ */
16
23
  className?: string;
17
- position?: "top" | "bottom";
18
- align?: "right" | "left";
19
- positioning?: "fixed" | "absolute";
24
+ /**
25
+ * Which side of the trigger to place the content.
26
+ * @default "top"
27
+ */
28
+ side?: Side;
29
+ /**
30
+ * Alignment along the side axis.
31
+ * @default "end"
32
+ */
33
+ align?: Align;
34
+ /**
35
+ * Distance (in pixels) between the trigger and the content.
36
+ * @default 16
37
+ */
38
+ sideOffset?: number;
39
+ /**
40
+ * Enable automatic collision avoidance.
41
+ * When true, the content repositions to stay within the viewport.
42
+ * @default true
43
+ */
44
+ avoidCollisions?: boolean;
45
+ /**
46
+ * Padding from viewport edges when avoiding collisions.
47
+ * @default 8
48
+ */
49
+ collisionPadding?: CollisionPadding;
50
+ /**
51
+ * Granular className overrides for specific parts.
52
+ */
53
+ classNames?: {
54
+ trigger?: string;
55
+ content?: string;
56
+ };
57
+ /**
58
+ * Force a specific theme. Omit for automatic detection.
59
+ */
60
+ theme?: "light" | "dark";
61
+ /**
62
+ * Controlled open state.
63
+ * When provided, the widget operates in controlled mode.
64
+ * Use with `onOpenChange` to manage state externally.
65
+ */
66
+ open?: boolean;
67
+ /**
68
+ * Callback fired when the open state should change.
69
+ * Use with `open` prop for controlled mode.
70
+ *
71
+ * @example
72
+ * const [isOpen, setIsOpen] = useState(false);
73
+ * <Support open={isOpen} onOpenChange={setIsOpen} />
74
+ */
75
+ onOpenChange?: (open: boolean) => void;
76
+ /**
77
+ * Whether the widget should open automatically on mount (uncontrolled mode).
78
+ * Ignored when `open` prop is provided (controlled mode).
79
+ * @default false
80
+ */
81
+ defaultOpen?: boolean;
82
+ /**
83
+ * Quick reply options displayed to users.
84
+ */
20
85
  quickOptions?: string[];
86
+ /**
87
+ * Custom welcome messages shown before a conversation starts.
88
+ */
21
89
  defaultMessages?: DefaultMessage[];
22
- defaultOpen?: boolean;
90
+ /**
91
+ * Locale string for widget translations.
92
+ */
23
93
  locale?: Locale;
94
+ /**
95
+ * Custom text content overrides for internationalization.
96
+ */
24
97
  content?: SupportTextContentOverrides<Locale>;
25
- theme?: "light" | "dark";
26
- slots?: {
27
- bubble?: React.ComponentType<BubbleSlotProps>;
28
- container?: React.ComponentType<ContainerSlotProps>;
29
- router?: React.ComponentType<RouterSlotProps>;
30
- };
31
- classNames?: {
32
- root?: string;
33
- bubble?: string;
34
- container?: string;
35
- };
98
+ /**
99
+ * Custom pages to add to the router.
100
+ */
36
101
  customPages?: CustomPage[];
37
- children?: React.ReactNode;
102
+ /**
103
+ * Called when a new conversation is started.
104
+ */
105
+ onConversationStart?: (event: ConversationStartEvent) => void;
106
+ /**
107
+ * Called when a conversation ends (resolved, closed, etc.).
108
+ */
109
+ onConversationEnd?: (event: ConversationEndEvent) => void;
110
+ /**
111
+ * Called when the visitor sends a message.
112
+ */
113
+ onMessageSent?: (event: MessageSentEvent) => void;
114
+ /**
115
+ * Called when a message is received from an agent (human or AI).
116
+ */
117
+ onMessageReceived?: (event: MessageReceivedEvent) => void;
118
+ /**
119
+ * Called when an error occurs within the widget.
120
+ */
121
+ onError?: (event: ErrorEvent) => void;
122
+ /**
123
+ * Children for composition. Can include:
124
+ * - <Support.Trigger> for custom trigger
125
+ * - <Support.Content> for custom content positioning
126
+ * - <Support.Page> components for custom routes
127
+ */
128
+ children?: React$1.ReactNode;
129
+ };
130
+ type SupportTriggerProps = Omit<React$1.ButtonHTMLAttributes<HTMLButtonElement>, "children"> & {
131
+ /**
132
+ * Content to render inside the trigger.
133
+ * Can be static content or a function receiving render props.
134
+ */
135
+ children?: React$1.ReactNode | ((props: TriggerRenderProps) => React$1.ReactNode);
136
+ /**
137
+ * When true, renders children directly with all props passed through.
138
+ */
139
+ asChild?: boolean;
140
+ className?: string;
141
+ };
142
+ type SupportContentProps = {
143
+ className?: string;
144
+ /**
145
+ * Which side of the trigger to place the content.
146
+ * @default "top"
147
+ */
148
+ side?: Side;
149
+ /**
150
+ * Alignment along the side axis.
151
+ * @default "end"
152
+ */
153
+ align?: Align;
154
+ /**
155
+ * Distance (in pixels) between the trigger and the content.
156
+ * @default 16
157
+ */
158
+ sideOffset?: number;
159
+ /**
160
+ * Enable automatic collision avoidance.
161
+ * When true, the content repositions to stay within the viewport.
162
+ * @default true
163
+ */
164
+ avoidCollisions?: boolean;
165
+ /**
166
+ * Padding from viewport edges when avoiding collisions.
167
+ * @default 8
168
+ */
169
+ collisionPadding?: CollisionPadding;
170
+ children?: React$1.ReactNode;
171
+ };
172
+ type SupportRouterProps = {
173
+ /**
174
+ * Custom pages to add alongside built-in pages.
175
+ */
176
+ customPages?: CustomPage[];
177
+ /**
178
+ * Page components to register.
179
+ */
180
+ children?: React$1.ReactNode;
181
+ };
182
+ type SupportPageProps<K extends keyof _cossistant_core0.RouteRegistry = keyof _cossistant_core0.RouteRegistry> = {
183
+ name: K;
184
+ component: React$1.ComponentType<{
185
+ params?: _cossistant_core0.RouteRegistry[K];
186
+ }>;
187
+ };
188
+ type SupportRootProps = {
189
+ /**
190
+ * Controlled open state.
191
+ * When provided, the widget operates in controlled mode.
192
+ */
193
+ open?: boolean;
194
+ /**
195
+ * Callback fired when the open state should change.
196
+ * Use with `open` prop for controlled mode.
197
+ */
198
+ onOpenChange?: (open: boolean) => void;
199
+ /**
200
+ * Whether the widget should open automatically (uncontrolled mode).
201
+ * Ignored when `open` prop is provided.
202
+ * @default false
203
+ */
204
+ defaultOpen?: boolean;
205
+ /**
206
+ * Force a specific theme.
207
+ */
208
+ theme?: "light" | "dark";
209
+ /**
210
+ * Additional CSS classes.
211
+ */
212
+ className?: string;
213
+ /**
214
+ * Called when a new conversation is started.
215
+ */
216
+ onConversationStart?: (event: ConversationStartEvent) => void;
217
+ /**
218
+ * Called when a conversation ends.
219
+ */
220
+ onConversationEnd?: (event: ConversationEndEvent) => void;
221
+ /**
222
+ * Called when the visitor sends a message.
223
+ */
224
+ onMessageSent?: (event: MessageSentEvent) => void;
225
+ /**
226
+ * Called when a message is received from an agent.
227
+ */
228
+ onMessageReceived?: (event: MessageReceivedEvent) => void;
229
+ /**
230
+ * Called when an error occurs.
231
+ */
232
+ onError?: (event: ErrorEvent) => void;
233
+ children: React$1.ReactNode;
234
+ };
235
+ declare const Support: (<Locale extends string = SupportLocale>(props: SupportProps<Locale> & {
236
+ ref?: React$1.Ref<SupportHandle>;
237
+ }) => React$1.ReactElement | null) & {
238
+ Root: React$1.ForwardRefExoticComponent<SupportRootProps & React$1.RefAttributes<SupportHandle>>;
239
+ Trigger: React$1.ForwardRefExoticComponent<Omit<React$1.ButtonHTMLAttributes<HTMLButtonElement>, "children"> & {
240
+ /**
241
+ * Content to render inside the trigger.
242
+ * Can be static content or a function receiving render props.
243
+ */
244
+ children?: React$1.ReactNode | ((props: TriggerRenderProps) => React$1.ReactNode);
245
+ /**
246
+ * When true, renders children directly with all props passed through.
247
+ */
248
+ asChild?: boolean;
249
+ className?: string;
250
+ } & React$1.RefAttributes<HTMLButtonElement>>;
251
+ Content: React$1.FC<SupportContentProps>;
252
+ Router: React$1.FC<SupportRouterProps>;
253
+ Page: <K extends keyof _cossistant_core0.RouteRegistry>(_props: PageProps<K>) => null;
254
+ Header: React$1.FC<SlotProps>;
255
+ Footer: React$1.FC<SlotProps>;
38
256
  };
39
- /**
40
- * Complete support widget with chat, routing, and real-time features.
41
- *
42
- * @example
43
- * // Zero config
44
- * <Support />
45
- *
46
- * @example
47
- * // With customization and custom pages
48
- * <Support
49
- * theme="dark"
50
- * classNames={{ bubble: "bg-purple-600" }}
51
- * customPages={[
52
- * { name: "FAQ", component: FAQPage }
53
- * ]}
54
- * />
55
- */
56
- declare function Support<Locale extends string = SupportLocale>({
57
- className,
58
- position,
59
- align,
60
- positioning,
61
- quickOptions,
62
- defaultMessages,
63
- defaultOpen,
64
- locale,
65
- content,
66
- theme,
67
- slots,
68
- classNames,
69
- customPages,
70
- children
71
- }: SupportProps<Locale>): ReactElement | null;
72
257
  //#endregion
73
- export { type BubbleSlotProps, CoButton as Button, type ContainerSlotProps, type CustomPage, type DefaultRoutes, Header, type NavigationState, type RouteRegistry, type RouterSlotProps, Support, Support as default, type SupportLocale, type SupportPage, SupportProps, type SupportTextContentOverrides, Text, type WebSocketContextValue, WebSocketProvider, useSupportConfig, useSupportNavigation, useSupportStore, useSupportText, useWebSocket };
258
+ export { type Align, CoButton as Button, type CollisionPadding, type ContentProps, type ConversationEndEvent, type ConversationStartEvent, type CustomPage, type DefaultRoutes, type ErrorEvent, Header, type MessageReceivedEvent, type MessageSentEvent, type NavigationState, type RootProps, type RouteRegistry, type Side, Support, Support as default, SupportContentProps, type SupportEvent, type SupportEventCallbacks, type SupportEventType, type SupportHandle, type SupportLocale, SupportPageProps, type SupportPageType, SupportProps, SupportRootProps, SupportRouterProps, type SupportTextContentOverrides, SupportTriggerProps, Text, type TriggerRenderProps, type WebSocketContextValue, WebSocketProvider, useSupportConfig, useSupportEventEmitter, useSupportEvents, useSupportHandle, useSupportNavigation, useSupportStore, useSupportText, useWebSocket };
74
259
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/support/index.tsx"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;;KAmBY,qCAAqC;;;;;;oBAO9B;;EAPP,MAAA,CAAA,EASF,MATc;EAAyB,OAAA,CAAA,EAUtC,2BAVsC,CAUV,MAVU,CAAA;EAO9B,KAAA,CAAA,EAAA,OAAA,GAAA,MAAA;EAET,KAAA,CAAA,EAAA;IAC6B,MAAA,CAAA,EAO5B,KAAA,CAAM,aAPsB,CAOR,eAPQ,CAAA;IAA5B,SAAA,CAAA,EAQG,KAAA,CAAM,aART,CAQuB,kBARvB,CAAA;IAOoB,MAAA,CAAA,EAEpB,KAAA,CAAM,aAFc,CAEA,eAFA,CAAA;EAApB,CAAA;EACuB,UAAA,CAAA,EAAA;IAAd,IAAA,CAAA,EAAA,MAAA;IACW,MAAA,CAAA,EAAA,MAAA;IAAd,SAAA,CAAA,EAAA,MAAA;EAWF,CAAA;EAEH,WAAM,CAAA,EAFH,UAEG,EAAA;EAAS,QAAA,CAAA,EAAf,KAAA,CAAM,SAAS;AAoB3B,CAAA;;;;;;;;;;;;;;;;;;AAe0B,iBAfV,OAeU,CAAA,eAAA,MAAA,GAfsB,aAetB,CAAA,CAAA;EAAA,SAAA;EAAA,QAAA;EAAA,KAAA;EAAA,WAAA;EAAA,YAAA;EAAA,eAAA;EAAA,WAAA;EAAA,MAAA;EAAA,OAAA;EAAA,KAAA;EAAA,KAAA;EAAA,UAAA;EAAA,WAAA;EAAA;AAAA,CAAA,EAAvB,YAAuB,CAAV,MAAU,CAAA,CAAA,EAAA,YAAA,GAAA,IAAA"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/support/index.tsx"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;;;;;;KAsCY,qCAAqC;;;;;;;;;SAUzC;EAVI;;;;EAmCQ,KAAA,CAAA,EAnBX,KAmBW;EA+CD;;;;EAeJ,UAAA,CAAA,EAAA,MAAA;EASgB;;;;;EA4BnB,eAAM,CAAA,EAAA,OAAA;EAAS;AA6M3B;;;EAAkC,gBAAA,CAAA,EAhTd,gBAgTc;EAQtB;;;EAAiE,UAAA,CAAA,EAAA;IAsCjE,OAAA,CAAA,EAAA,MAAA;IAMJ,OAAA,CAAA,EAAA,MAAA;EAKC,CAAA;EAgBW;;;EA4CR,KAAA,CAAA,EAAA,OAAA,GAAA,MAAkB;EAsClB;;;;;EAMwC,IAAA,CAAA,EAAA,OAAA;EADxC;;AAuBZ;;;;;;EA6CW,YAAM,CAAA,EAAA,CAAA,IAAA,EAAA,OAAA,EAAA,GAAA,IAAA;EAAS;AA2F1B;;;;EAtUiD,WAAA,CAAA,EAAA,OAAA;EAAV;;;;;;;oBA1PpB;;;;EAyQ2C,MAAM,CAAA,EApQ1D,MAoQ0D;;;;YA/PzD,4BAA4B;;;;gBAKxB;;;;gCASgB;;;;8BAKF;;;;0BAKJ;;;;8BAKI;;;;oBAKV;;;;;;;aAQP,OAAA,CAAM;;KA6MN,mBAAA,GAAsB,KACjC,OAAA,CAAM,qBAAqB;;;;;aAOhB,OAAA,CAAM,qBAAqB,uBAAuB,OAAA,CAAM;;;;;;;KAsCxD,mBAAA;;;;;;SAMJ;;;;;UAKC;;;;;;;;;;;;;;;;qBAgBW;aACR,OAAA,CAAM;;KA2CN,kBAAA;;;;gBAIG;;;;aAIH,OAAA,CAAM;;KA8BN,iCAAgB,iBAAA,CAEO,sBAAa,iBAAA,CAAoC;QAE7E;aACK,OAAA,CAAM;aADV,iBAAA,CAE8B,aAAA,CAAc;;;KAsBxC,gBAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;gCA4BmB;;;;8BAIF;;;;0BAIJ;;;;8BAII;;;;oBAIV;YACR,OAAA,CAAM;;cA2FJ,mCAxUS,sBAEd,aAAa;QAAkB,OAAA,CAAM,IAAI;MAC5C,OAAA,CAAM;;;;;;;eAcC,OAAA,CAAM,qBAAqB,uBAAuB,OAAA,CAAM"}