@cossistant/react 0.0.26 → 0.0.29

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 (247) hide show
  1. package/README.md +1 -1
  2. package/api.d.ts +1 -1
  3. package/api.d.ts.map +1 -1
  4. package/checks.d.ts +1 -1
  5. package/checks.d.ts.map +1 -1
  6. package/coerce.d.ts +1 -1
  7. package/coerce.d.ts.map +1 -1
  8. package/conversation.d.ts +6 -3
  9. package/conversation.d.ts.map +1 -1
  10. package/core.d.ts +1 -1
  11. package/core.d.ts.map +1 -1
  12. package/errors.d.ts +12 -3
  13. package/errors.d.ts.map +1 -1
  14. package/errors2.d.ts +1 -1
  15. package/errors2.d.ts.map +1 -1
  16. package/hooks/index.d.ts +3 -2
  17. package/hooks/index.js +6 -5
  18. package/hooks/private/store/use-website-store.js +2 -1
  19. package/hooks/private/store/use-website-store.js.map +1 -1
  20. package/hooks/private/use-client-query.d.ts +6 -0
  21. package/hooks/private/use-client-query.d.ts.map +1 -1
  22. package/hooks/private/use-client-query.js +26 -3
  23. package/hooks/private/use-client-query.js.map +1 -1
  24. package/hooks/private/use-grouped-messages.d.ts +8 -5
  25. package/hooks/private/use-grouped-messages.d.ts.map +1 -1
  26. package/hooks/private/use-grouped-messages.js +44 -11
  27. package/hooks/private/use-grouped-messages.js.map +1 -1
  28. package/hooks/private/use-multimodal-input.d.ts.map +1 -1
  29. package/hooks/private/use-multimodal-input.js +7 -5
  30. package/hooks/private/use-multimodal-input.js.map +1 -1
  31. package/hooks/private/use-visitor-typing-reporter.d.ts +18 -1
  32. package/hooks/private/use-visitor-typing-reporter.d.ts.map +1 -1
  33. package/hooks/private/use-visitor-typing-reporter.js +34 -4
  34. package/hooks/private/use-visitor-typing-reporter.js.map +1 -1
  35. package/hooks/use-conversation-page.d.ts +1 -0
  36. package/hooks/use-conversation-page.d.ts.map +1 -1
  37. package/hooks/use-conversation-page.js +6 -1
  38. package/hooks/use-conversation-page.js.map +1 -1
  39. package/hooks/use-conversation-preview.d.ts +2 -1
  40. package/hooks/use-conversation-preview.d.ts.map +1 -1
  41. package/hooks/use-conversation-preview.js +1 -1
  42. package/hooks/use-conversation-preview.js.map +1 -1
  43. package/hooks/use-conversation-seen.js +1 -1
  44. package/hooks/use-conversation-seen.js.map +1 -1
  45. package/hooks/use-conversation-timeline-items.js +2 -1
  46. package/hooks/use-conversation-timeline-items.js.map +1 -1
  47. package/hooks/use-conversation-timeline.d.ts.map +1 -1
  48. package/hooks/use-conversation-timeline.js +1 -3
  49. package/hooks/use-conversation-timeline.js.map +1 -1
  50. package/hooks/use-conversation.js +2 -1
  51. package/hooks/use-conversation.js.map +1 -1
  52. package/hooks/use-conversations.js +1 -0
  53. package/hooks/use-conversations.js.map +1 -1
  54. package/hooks/use-create-conversation.d.ts.map +1 -1
  55. package/hooks/use-file-upload.d.ts +55 -0
  56. package/hooks/use-file-upload.d.ts.map +1 -0
  57. package/hooks/use-file-upload.js +100 -0
  58. package/hooks/use-file-upload.js.map +1 -0
  59. package/hooks/use-message-composer.d.ts +11 -0
  60. package/hooks/use-message-composer.d.ts.map +1 -1
  61. package/hooks/use-message-composer.js +7 -3
  62. package/hooks/use-message-composer.js.map +1 -1
  63. package/hooks/use-send-message.d.ts +1 -0
  64. package/hooks/use-send-message.d.ts.map +1 -1
  65. package/hooks/use-send-message.js +63 -11
  66. package/hooks/use-send-message.js.map +1 -1
  67. package/index.d.ts +7 -4
  68. package/index.js +13 -10
  69. package/json-schema.d.ts +70 -0
  70. package/json-schema.d.ts.map +1 -0
  71. package/package.json +4 -3
  72. package/parse.d.ts +1 -1
  73. package/parse.d.ts.map +1 -1
  74. package/primitives/avatar/fallback.d.ts.map +1 -1
  75. package/primitives/avatar/fallback.js +1 -1
  76. package/primitives/avatar/fallback.js.map +1 -1
  77. package/primitives/conversation-timeline.d.ts.map +1 -1
  78. package/primitives/conversation-timeline.js +10 -5
  79. package/primitives/conversation-timeline.js.map +1 -1
  80. package/primitives/day-separator.d.ts +76 -0
  81. package/primitives/day-separator.d.ts.map +1 -0
  82. package/primitives/day-separator.js +111 -0
  83. package/primitives/day-separator.js.map +1 -0
  84. package/primitives/index.d.ts +5 -3
  85. package/primitives/index.js +17 -5
  86. package/primitives/index.parts.d.ts +4 -2
  87. package/primitives/index.parts.js +5 -3
  88. package/primitives/timeline-item-attachments.d.ts +100 -0
  89. package/primitives/timeline-item-attachments.d.ts.map +1 -0
  90. package/primitives/timeline-item-attachments.js +151 -0
  91. package/primitives/timeline-item-attachments.js.map +1 -0
  92. package/primitives/timeline-item-group.d.ts.map +1 -1
  93. package/primitives/timeline-item-group.js +1 -1
  94. package/primitives/timeline-item-group.js.map +1 -1
  95. package/primitives/timeline-item.js +1 -1
  96. package/primitives/timeline-item.js.map +1 -1
  97. package/primitives/trigger.d.ts +91 -0
  98. package/primitives/trigger.d.ts.map +1 -0
  99. package/primitives/trigger.js +74 -0
  100. package/primitives/trigger.js.map +1 -0
  101. package/primitives/window.d.ts +22 -1
  102. package/primitives/window.d.ts.map +1 -1
  103. package/primitives/window.js +91 -5
  104. package/primitives/window.js.map +1 -1
  105. package/provider.d.ts.map +1 -1
  106. package/provider.js +8 -3
  107. package/provider.js.map +1 -1
  108. package/realtime/index.js +1 -1
  109. package/realtime/provider.js +1 -1
  110. package/realtime/support-provider.js +5 -1
  111. package/realtime/support-provider.js.map +1 -1
  112. package/realtime-events.d.ts +165 -2
  113. package/realtime-events.d.ts.map +1 -1
  114. package/registries.d.ts +1 -1
  115. package/registries.d.ts.map +1 -1
  116. package/schemas.d.ts +305 -7
  117. package/schemas.d.ts.map +1 -1
  118. package/schemas2.d.ts +29 -4
  119. package/schemas2.d.ts.map +1 -1
  120. package/schemas3.d.ts +2 -1
  121. package/schemas3.d.ts.map +1 -1
  122. package/standard-schema.d.ts +83 -21
  123. package/standard-schema.d.ts.map +1 -1
  124. package/support/components/button.d.ts +1 -1
  125. package/support/components/content.d.ts +30 -0
  126. package/support/components/content.d.ts.map +1 -0
  127. package/support/components/content.js +282 -0
  128. package/support/components/content.js.map +1 -0
  129. package/support/components/conversation-button-link.js +1 -1
  130. package/support/components/conversation-timeline.d.ts +5 -0
  131. package/support/components/conversation-timeline.d.ts.map +1 -1
  132. package/support/components/conversation-timeline.js +25 -5
  133. package/support/components/conversation-timeline.js.map +1 -1
  134. package/support/components/header.js +1 -1
  135. package/support/components/image-lightbox.d.ts +49 -0
  136. package/support/components/image-lightbox.d.ts.map +1 -0
  137. package/support/components/image-lightbox.js +142 -0
  138. package/support/components/image-lightbox.js.map +1 -0
  139. package/support/components/index.d.ts +5 -4
  140. package/support/components/index.js +4 -4
  141. package/support/components/multimodal-input.d.ts +4 -1
  142. package/support/components/multimodal-input.d.ts.map +1 -1
  143. package/support/components/multimodal-input.js +71 -45
  144. package/support/components/multimodal-input.js.map +1 -1
  145. package/support/components/navigation-tab.js +1 -1
  146. package/support/components/root.d.ts +23 -0
  147. package/support/components/root.d.ts.map +1 -0
  148. package/support/components/root.js +36 -0
  149. package/support/components/root.js.map +1 -0
  150. package/support/components/timeline-message-item.d.ts.map +1 -1
  151. package/support/components/timeline-message-item.js +82 -18
  152. package/support/components/timeline-message-item.js.map +1 -1
  153. package/support/components/trigger.d.ts +14 -0
  154. package/support/components/trigger.d.ts.map +1 -0
  155. package/support/components/{bubble.js → trigger.js} +16 -12
  156. package/support/components/trigger.js.map +1 -0
  157. package/support/components/typing-indicator.d.ts.map +1 -1
  158. package/support/components/typing-indicator.js +1 -0
  159. package/support/components/typing-indicator.js.map +1 -1
  160. package/support/context/controlled-state.d.ts +46 -0
  161. package/support/context/controlled-state.d.ts.map +1 -0
  162. package/support/context/controlled-state.js +34 -0
  163. package/support/context/controlled-state.js.map +1 -0
  164. package/support/context/events.d.ts +103 -0
  165. package/support/context/events.d.ts.map +1 -0
  166. package/support/context/events.js +139 -0
  167. package/support/context/events.js.map +1 -0
  168. package/support/context/handle.d.ts +90 -0
  169. package/support/context/handle.d.ts.map +1 -0
  170. package/support/context/handle.js +79 -0
  171. package/support/context/handle.js.map +1 -0
  172. package/support/context/positioning.d.ts +17 -0
  173. package/support/context/positioning.d.ts.map +1 -0
  174. package/support/context/positioning.js +26 -0
  175. package/support/context/positioning.js.map +1 -0
  176. package/support/context/slots.d.ts +85 -0
  177. package/support/context/slots.d.ts.map +1 -0
  178. package/support/context/slots.js +115 -0
  179. package/support/context/slots.js.map +1 -0
  180. package/support/context/websocket.d.ts +8 -1
  181. package/support/context/websocket.d.ts.map +1 -1
  182. package/support/context/websocket.js +8 -1
  183. package/support/context/websocket.js.map +1 -1
  184. package/support/index.d.ts +239 -54
  185. package/support/index.d.ts.map +1 -1
  186. package/support/index.js +254 -33
  187. package/support/index.js.map +1 -1
  188. package/support/pages/articles.d.ts.map +1 -1
  189. package/support/pages/articles.js +3 -4
  190. package/support/pages/articles.js.map +1 -1
  191. package/support/pages/conversation-history.js +2 -2
  192. package/support/pages/conversation.js +6 -5
  193. package/support/pages/conversation.js.map +1 -1
  194. package/support/pages/home.js +2 -2
  195. package/support/router.d.ts +52 -12
  196. package/support/router.d.ts.map +1 -1
  197. package/support/router.js +78 -30
  198. package/support/router.js.map +1 -1
  199. package/support/store/index.d.ts +2 -2
  200. package/support/store/support-store.d.ts +26 -20
  201. package/support/store/support-store.d.ts.map +1 -1
  202. package/support/store/support-store.js +47 -6
  203. package/support/store/support-store.js.map +1 -1
  204. package/support/{support-D2EgfIts.css → support-C7Xaw-N6.css} +1 -2
  205. package/support/support-C7Xaw-N6.css.map +1 -0
  206. package/support/text/index.d.ts +1 -1
  207. package/support/text/index.d.ts.map +1 -1
  208. package/support/text/index.js.map +1 -1
  209. package/support/types.d.ts +75 -12
  210. package/support/types.d.ts.map +1 -1
  211. package/support.css +2 -2
  212. package/tailwind.css +0 -1
  213. package/timeline-item.d.ts +68 -2
  214. package/timeline-item.d.ts.map +1 -1
  215. package/to-json-schema.d.ts +96 -0
  216. package/to-json-schema.d.ts.map +1 -0
  217. package/util.d.ts +6 -2
  218. package/util.d.ts.map +1 -1
  219. package/utils/index.d.ts +2 -1
  220. package/utils/index.js +2 -1
  221. package/utils/merge-refs.d.ts +30 -0
  222. package/utils/merge-refs.d.ts.map +1 -0
  223. package/utils/merge-refs.js +46 -0
  224. package/utils/merge-refs.js.map +1 -0
  225. package/utils/use-render-element.d.ts.map +1 -1
  226. package/utils/use-render-element.js +36 -8
  227. package/utils/use-render-element.js.map +1 -1
  228. package/versions.d.ts +2 -2
  229. package/versions.d.ts.map +1 -1
  230. package/zod-extensions.d.ts +1 -1
  231. package/zod-extensions.d.ts.map +1 -1
  232. package/primitives/bubble.d.ts +0 -38
  233. package/primitives/bubble.d.ts.map +0 -1
  234. package/primitives/bubble.js +0 -57
  235. package/primitives/bubble.js.map +0 -1
  236. package/support/components/bubble.d.ts +0 -10
  237. package/support/components/bubble.d.ts.map +0 -1
  238. package/support/components/bubble.js.map +0 -1
  239. package/support/components/container.d.ts +0 -13
  240. package/support/components/container.d.ts.map +0 -1
  241. package/support/components/container.js +0 -109
  242. package/support/components/container.js.map +0 -1
  243. package/support/components/support-content.d.ts +0 -22
  244. package/support/components/support-content.d.ts.map +0 -1
  245. package/support/components/support-content.js +0 -48
  246. package/support/components/support-content.js.map +0 -1
  247. package/support/support-D2EgfIts.css.map +0 -1
@@ -0,0 +1,139 @@
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/events.tsx
8
+ const SupportEventsContext = React$1.createContext(null);
9
+ /**
10
+ * Provider for support widget events.
11
+ * Allows listening to lifecycle events like message sent/received,
12
+ * conversation start/end, and errors.
13
+ *
14
+ * @example
15
+ * <Support
16
+ * onMessageSent={({ message }) => console.log("Sent:", message)}
17
+ * onMessageReceived={({ message }) => console.log("Received:", message)}
18
+ * onConversationStart={({ conversationId }) => console.log("Started:", conversationId)}
19
+ * onError={({ error }) => console.error("Error:", error)}
20
+ * />
21
+ */
22
+ const SupportEventsProvider = ({ onConversationStart, onConversationEnd, onMessageSent, onMessageReceived, onError, children }) => {
23
+ const callbacksRef = React$1.useRef({
24
+ onConversationStart,
25
+ onConversationEnd,
26
+ onMessageSent,
27
+ onMessageReceived,
28
+ onError
29
+ });
30
+ React$1.useEffect(() => {
31
+ callbacksRef.current = {
32
+ onConversationStart,
33
+ onConversationEnd,
34
+ onMessageSent,
35
+ onMessageReceived,
36
+ onError
37
+ };
38
+ }, [
39
+ onConversationStart,
40
+ onConversationEnd,
41
+ onMessageSent,
42
+ onMessageReceived,
43
+ onError
44
+ ]);
45
+ const subscribersRef = React$1.useRef(/* @__PURE__ */ new Map());
46
+ const emit = React$1.useCallback((event) => {
47
+ switch (event.type) {
48
+ case "conversationStart":
49
+ callbacksRef.current.onConversationStart?.(event);
50
+ break;
51
+ case "conversationEnd":
52
+ callbacksRef.current.onConversationEnd?.(event);
53
+ break;
54
+ case "messageSent":
55
+ callbacksRef.current.onMessageSent?.(event);
56
+ break;
57
+ case "messageReceived":
58
+ callbacksRef.current.onMessageReceived?.(event);
59
+ break;
60
+ case "error":
61
+ callbacksRef.current.onError?.(event);
62
+ break;
63
+ default: break;
64
+ }
65
+ const subscribers = subscribersRef.current.get(event.type);
66
+ if (subscribers) for (const callback of subscribers) callback(event);
67
+ }, []);
68
+ const subscribe = React$1.useCallback((type, callback) => {
69
+ if (!subscribersRef.current.has(type)) subscribersRef.current.set(type, /* @__PURE__ */ new Set());
70
+ const subscribers = subscribersRef.current.get(type);
71
+ subscribers?.add(callback);
72
+ return () => {
73
+ subscribers?.delete(callback);
74
+ };
75
+ }, []);
76
+ const value = React$1.useMemo(() => ({
77
+ emit,
78
+ subscribe
79
+ }), [emit, subscribe]);
80
+ return /* @__PURE__ */ jsx(SupportEventsContext.Provider, {
81
+ value,
82
+ children
83
+ });
84
+ };
85
+ /**
86
+ * Access the events context.
87
+ * Returns null if not inside a SupportEventsProvider.
88
+ */
89
+ function useSupportEvents() {
90
+ return React$1.useContext(SupportEventsContext);
91
+ }
92
+ /**
93
+ * Hook to emit events from within the widget.
94
+ * Safe to use outside of provider (will no-op).
95
+ */
96
+ function useSupportEventEmitter() {
97
+ const events = useSupportEvents();
98
+ return React$1.useMemo(() => ({
99
+ emitConversationStart: (conversationId, conversation) => {
100
+ events?.emit({
101
+ type: "conversationStart",
102
+ conversationId,
103
+ conversation
104
+ });
105
+ },
106
+ emitConversationEnd: (conversationId, conversation) => {
107
+ events?.emit({
108
+ type: "conversationEnd",
109
+ conversationId,
110
+ conversation
111
+ });
112
+ },
113
+ emitMessageSent: (conversationId, message) => {
114
+ events?.emit({
115
+ type: "messageSent",
116
+ conversationId,
117
+ message
118
+ });
119
+ },
120
+ emitMessageReceived: (conversationId, message) => {
121
+ events?.emit({
122
+ type: "messageReceived",
123
+ conversationId,
124
+ message
125
+ });
126
+ },
127
+ emitError: (error, context) => {
128
+ events?.emit({
129
+ type: "error",
130
+ error,
131
+ context
132
+ });
133
+ }
134
+ }), [events]);
135
+ }
136
+
137
+ //#endregion
138
+ export { SupportEventsProvider, useSupportEventEmitter, useSupportEvents };
139
+ //# sourceMappingURL=events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.js","names":["React","SupportEventsProvider: React.FC<SupportEventsProviderProps>"],"sources":["../../../src/support/context/events.tsx"],"sourcesContent":["\"use client\";\n\nimport type { Conversation } from \"@cossistant/types\";\nimport type { TimelineItem } from \"@cossistant/types/api/timeline-item\";\nimport * as React from \"react\";\n\n// =============================================================================\n// Event Types\n// =============================================================================\n\nexport type SupportEventType =\n\t| \"conversationStart\"\n\t| \"conversationEnd\"\n\t| \"messageSent\"\n\t| \"messageReceived\"\n\t| \"error\";\n\nexport type ConversationStartEvent = {\n\ttype: \"conversationStart\";\n\tconversationId: string;\n\tconversation?: Conversation;\n};\n\nexport type ConversationEndEvent = {\n\ttype: \"conversationEnd\";\n\tconversationId: string;\n\tconversation?: Conversation;\n};\n\nexport type MessageSentEvent = {\n\ttype: \"messageSent\";\n\tconversationId: string;\n\tmessage: TimelineItem;\n};\n\nexport type MessageReceivedEvent = {\n\ttype: \"messageReceived\";\n\tconversationId: string;\n\tmessage: TimelineItem;\n};\n\nexport type ErrorEvent = {\n\ttype: \"error\";\n\terror: Error;\n\tcontext?: string;\n};\n\nexport type SupportEvent =\n\t| ConversationStartEvent\n\t| ConversationEndEvent\n\t| MessageSentEvent\n\t| MessageReceivedEvent\n\t| ErrorEvent;\n\n// =============================================================================\n// Event Callbacks\n// =============================================================================\n\nexport type SupportEventCallbacks = {\n\t/**\n\t * Called when a new conversation is started.\n\t */\n\tonConversationStart?: (event: ConversationStartEvent) => void;\n\t/**\n\t * Called when a conversation ends (resolved, closed, etc.).\n\t */\n\tonConversationEnd?: (event: ConversationEndEvent) => void;\n\t/**\n\t * Called when the visitor sends a message.\n\t */\n\tonMessageSent?: (event: MessageSentEvent) => void;\n\t/**\n\t * Called when a message is received from an agent (human or AI).\n\t */\n\tonMessageReceived?: (event: MessageReceivedEvent) => void;\n\t/**\n\t * Called when an error occurs.\n\t */\n\tonError?: (event: ErrorEvent) => void;\n};\n\n// =============================================================================\n// Context\n// =============================================================================\n\nexport type SupportEventsContextValue = {\n\t/**\n\t * Emit an event to all registered callbacks.\n\t */\n\temit: <T extends SupportEvent>(event: T) => void;\n\t/**\n\t * Subscribe to a specific event type.\n\t * Returns an unsubscribe function.\n\t */\n\tsubscribe: <T extends SupportEventType>(\n\t\ttype: T,\n\t\tcallback: (event: Extract<SupportEvent, { type: T }>) => void\n\t) => () => void;\n};\n\nconst SupportEventsContext =\n\tReact.createContext<SupportEventsContextValue | null>(null);\n\nexport type SupportEventsProviderProps = SupportEventCallbacks & {\n\tchildren: React.ReactNode;\n};\n\n/**\n * Provider for support widget events.\n * Allows listening to lifecycle events like message sent/received,\n * conversation start/end, and errors.\n *\n * @example\n * <Support\n * onMessageSent={({ message }) => console.log(\"Sent:\", message)}\n * onMessageReceived={({ message }) => console.log(\"Received:\", message)}\n * onConversationStart={({ conversationId }) => console.log(\"Started:\", conversationId)}\n * onError={({ error }) => console.error(\"Error:\", error)}\n * />\n */\nexport const SupportEventsProvider: React.FC<SupportEventsProviderProps> = ({\n\tonConversationStart,\n\tonConversationEnd,\n\tonMessageSent,\n\tonMessageReceived,\n\tonError,\n\tchildren,\n}) => {\n\t// Store callbacks in refs to avoid stale closures\n\tconst callbacksRef = React.useRef<SupportEventCallbacks>({\n\t\tonConversationStart,\n\t\tonConversationEnd,\n\t\tonMessageSent,\n\t\tonMessageReceived,\n\t\tonError,\n\t});\n\n\t// Update refs when callbacks change\n\tReact.useEffect(() => {\n\t\tcallbacksRef.current = {\n\t\t\tonConversationStart,\n\t\t\tonConversationEnd,\n\t\t\tonMessageSent,\n\t\t\tonMessageReceived,\n\t\t\tonError,\n\t\t};\n\t}, [\n\t\tonConversationStart,\n\t\tonConversationEnd,\n\t\tonMessageSent,\n\t\tonMessageReceived,\n\t\tonError,\n\t]);\n\n\t// Additional subscribers (for internal use)\n\tconst subscribersRef = React.useRef<\n\t\tMap<SupportEventType, Set<(event: SupportEvent) => void>>\n\t>(new Map());\n\n\tconst emit = React.useCallback(<T extends SupportEvent>(event: T) => {\n\t\t// Call the prop callback\n\t\tswitch (event.type) {\n\t\t\tcase \"conversationStart\":\n\t\t\t\tcallbacksRef.current.onConversationStart?.(event);\n\t\t\t\tbreak;\n\t\t\tcase \"conversationEnd\":\n\t\t\t\tcallbacksRef.current.onConversationEnd?.(event);\n\t\t\t\tbreak;\n\t\t\tcase \"messageSent\":\n\t\t\t\tcallbacksRef.current.onMessageSent?.(event);\n\t\t\t\tbreak;\n\t\t\tcase \"messageReceived\":\n\t\t\t\tcallbacksRef.current.onMessageReceived?.(event);\n\t\t\t\tbreak;\n\t\t\tcase \"error\":\n\t\t\t\tcallbacksRef.current.onError?.(event);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\t// Unknown event type - no callback to call\n\t\t\t\tbreak;\n\t\t}\n\n\t\t// Call any additional subscribers\n\t\tconst subscribers = subscribersRef.current.get(event.type);\n\t\tif (subscribers) {\n\t\t\tfor (const callback of subscribers) {\n\t\t\t\tcallback(event);\n\t\t\t}\n\t\t}\n\t}, []);\n\n\tconst subscribe = React.useCallback(\n\t\t<T extends SupportEventType>(\n\t\t\ttype: T,\n\t\t\tcallback: (event: Extract<SupportEvent, { type: T }>) => void\n\t\t) => {\n\t\t\tif (!subscribersRef.current.has(type)) {\n\t\t\t\tsubscribersRef.current.set(type, new Set());\n\t\t\t}\n\t\t\tconst subscribers = subscribersRef.current.get(type);\n\t\t\tsubscribers?.add(callback as (event: SupportEvent) => void);\n\n\t\t\t// Return unsubscribe function\n\t\t\treturn () => {\n\t\t\t\tsubscribers?.delete(callback as (event: SupportEvent) => void);\n\t\t\t};\n\t\t},\n\t\t[]\n\t);\n\n\tconst value = React.useMemo<SupportEventsContextValue>(\n\t\t() => ({ emit, subscribe }),\n\t\t[emit, subscribe]\n\t);\n\n\treturn (\n\t\t<SupportEventsContext.Provider value={value}>\n\t\t\t{children}\n\t\t</SupportEventsContext.Provider>\n\t);\n};\n\n/**\n * Access the events context.\n * Returns null if not inside a SupportEventsProvider.\n */\nexport function useSupportEvents(): SupportEventsContextValue | null {\n\treturn React.useContext(SupportEventsContext);\n}\n\n/**\n * Hook to emit events from within the widget.\n * Safe to use outside of provider (will no-op).\n */\nexport function useSupportEventEmitter() {\n\tconst events = useSupportEvents();\n\n\treturn React.useMemo(\n\t\t() => ({\n\t\t\temitConversationStart: (\n\t\t\t\tconversationId: string,\n\t\t\t\tconversation?: Conversation\n\t\t\t) => {\n\t\t\t\tevents?.emit({\n\t\t\t\t\ttype: \"conversationStart\",\n\t\t\t\t\tconversationId,\n\t\t\t\t\tconversation,\n\t\t\t\t});\n\t\t\t},\n\t\t\temitConversationEnd: (\n\t\t\t\tconversationId: string,\n\t\t\t\tconversation?: Conversation\n\t\t\t) => {\n\t\t\t\tevents?.emit({\n\t\t\t\t\ttype: \"conversationEnd\",\n\t\t\t\t\tconversationId,\n\t\t\t\t\tconversation,\n\t\t\t\t});\n\t\t\t},\n\t\t\temitMessageSent: (conversationId: string, message: TimelineItem) => {\n\t\t\t\tevents?.emit({\n\t\t\t\t\ttype: \"messageSent\",\n\t\t\t\t\tconversationId,\n\t\t\t\t\tmessage,\n\t\t\t\t});\n\t\t\t},\n\t\t\temitMessageReceived: (conversationId: string, message: TimelineItem) => {\n\t\t\t\tevents?.emit({\n\t\t\t\t\ttype: \"messageReceived\",\n\t\t\t\t\tconversationId,\n\t\t\t\t\tmessage,\n\t\t\t\t});\n\t\t\t},\n\t\t\temitError: (error: Error, context?: string) => {\n\t\t\t\tevents?.emit({\n\t\t\t\t\ttype: \"error\",\n\t\t\t\t\terror,\n\t\t\t\t\tcontext,\n\t\t\t\t});\n\t\t\t},\n\t\t}),\n\t\t[events]\n\t);\n}\n"],"mappings":";;;;;;;AAoGA,MAAM,uBACLA,QAAM,cAAgD,KAAK;;;;;;;;;;;;;;AAmB5D,MAAaC,yBAA+D,EAC3E,qBACA,mBACA,eACA,mBACA,SACA,eACK;CAEL,MAAM,eAAeD,QAAM,OAA8B;EACxD;EACA;EACA;EACA;EACA;EACA,CAAC;AAGF,SAAM,gBAAgB;AACrB,eAAa,UAAU;GACtB;GACA;GACA;GACA;GACA;GACA;IACC;EACF;EACA;EACA;EACA;EACA;EACA,CAAC;CAGF,MAAM,iBAAiBA,QAAM,uBAE3B,IAAI,KAAK,CAAC;CAEZ,MAAM,OAAOA,QAAM,aAAqC,UAAa;AAEpE,UAAQ,MAAM,MAAd;GACC,KAAK;AACJ,iBAAa,QAAQ,sBAAsB,MAAM;AACjD;GACD,KAAK;AACJ,iBAAa,QAAQ,oBAAoB,MAAM;AAC/C;GACD,KAAK;AACJ,iBAAa,QAAQ,gBAAgB,MAAM;AAC3C;GACD,KAAK;AACJ,iBAAa,QAAQ,oBAAoB,MAAM;AAC/C;GACD,KAAK;AACJ,iBAAa,QAAQ,UAAU,MAAM;AACrC;GACD,QAEC;;EAIF,MAAM,cAAc,eAAe,QAAQ,IAAI,MAAM,KAAK;AAC1D,MAAI,YACH,MAAK,MAAM,YAAY,YACtB,UAAS,MAAM;IAGf,EAAE,CAAC;CAEN,MAAM,YAAYA,QAAM,aAEtB,MACA,aACI;AACJ,MAAI,CAAC,eAAe,QAAQ,IAAI,KAAK,CACpC,gBAAe,QAAQ,IAAI,sBAAM,IAAI,KAAK,CAAC;EAE5C,MAAM,cAAc,eAAe,QAAQ,IAAI,KAAK;AACpD,eAAa,IAAI,SAA0C;AAG3D,eAAa;AACZ,gBAAa,OAAO,SAA0C;;IAGhE,EAAE,CACF;CAED,MAAM,QAAQA,QAAM,eACZ;EAAE;EAAM;EAAW,GAC1B,CAAC,MAAM,UAAU,CACjB;AAED,QACC,oBAAC,qBAAqB;EAAgB;EACpC;GAC8B;;;;;;AAQlC,SAAgB,mBAAqD;AACpE,QAAOA,QAAM,WAAW,qBAAqB;;;;;;AAO9C,SAAgB,yBAAyB;CACxC,MAAM,SAAS,kBAAkB;AAEjC,QAAOA,QAAM,eACL;EACN,wBACC,gBACA,iBACI;AACJ,WAAQ,KAAK;IACZ,MAAM;IACN;IACA;IACA,CAAC;;EAEH,sBACC,gBACA,iBACI;AACJ,WAAQ,KAAK;IACZ,MAAM;IACN;IACA;IACA,CAAC;;EAEH,kBAAkB,gBAAwB,YAA0B;AACnE,WAAQ,KAAK;IACZ,MAAM;IACN;IACA;IACA,CAAC;;EAEH,sBAAsB,gBAAwB,YAA0B;AACvE,WAAQ,KAAK;IACZ,MAAM;IACN;IACA;IACA,CAAC;;EAEH,YAAY,OAAc,YAAqB;AAC9C,WAAQ,KAAK;IACZ,MAAM;IACN;IACA;IACA,CAAC;;EAEH,GACD,CAAC,OAAO,CACR"}
@@ -0,0 +1,90 @@
1
+ import * as React$1 from "react";
2
+ import { RouteRegistry } from "@cossistant/core";
3
+
4
+ //#region src/support/context/handle.d.ts
5
+
6
+ /**
7
+ * Imperative handle for programmatic control of the Support widget.
8
+ * Access via ref on the Support component or via useSupportHandle hook.
9
+ *
10
+ * @example
11
+ * const supportRef = useRef<SupportHandle>(null);
12
+ *
13
+ * // Open the widget
14
+ * supportRef.current?.open();
15
+ *
16
+ * // Navigate to a conversation
17
+ * supportRef.current?.openConversation("conv_123");
18
+ *
19
+ * // Start a new conversation with a message
20
+ * supportRef.current?.startConversation("I need help with...");
21
+ *
22
+ * <Support ref={supportRef} />
23
+ */
24
+ type SupportHandle = {
25
+ /**
26
+ * Open the support widget.
27
+ */
28
+ open: () => void;
29
+ /**
30
+ * Close the support widget.
31
+ */
32
+ close: () => void;
33
+ /**
34
+ * Toggle the support widget open/closed.
35
+ */
36
+ toggle: () => void;
37
+ /**
38
+ * Navigate to a specific page with optional params.
39
+ */
40
+ navigate: <K extends keyof RouteRegistry>(options: {
41
+ page: K;
42
+ params?: RouteRegistry[K];
43
+ }) => void;
44
+ /**
45
+ * Go back to the previous page.
46
+ */
47
+ goBack: () => void;
48
+ /**
49
+ * Open a specific conversation.
50
+ */
51
+ openConversation: (conversationId: string) => void;
52
+ /**
53
+ * Start a new conversation, optionally with an initial message.
54
+ */
55
+ startConversation: (initialMessage?: string) => void;
56
+ /**
57
+ * Navigate to the home page.
58
+ */
59
+ goHome: () => void;
60
+ };
61
+ type SupportHandleProviderProps = {
62
+ /**
63
+ * Ref to expose the handle to parent components.
64
+ */
65
+ forwardedRef?: React$1.Ref<SupportHandle>;
66
+ children: React$1.ReactNode;
67
+ };
68
+ /**
69
+ * Provider that creates and exposes the imperative handle.
70
+ */
71
+ declare const SupportHandleProvider: React$1.FC<SupportHandleProviderProps>;
72
+ /**
73
+ * Hook to access the imperative handle from within the widget.
74
+ * Returns null if not inside Support component.
75
+ *
76
+ * @example
77
+ * function MyComponent() {
78
+ * const support = useSupportHandle();
79
+ *
80
+ * return (
81
+ * <button onClick={() => support?.startConversation("Hello!")}>
82
+ * Get Help
83
+ * </button>
84
+ * );
85
+ * }
86
+ */
87
+ declare function useSupportHandle(): SupportHandle | null;
88
+ //#endregion
89
+ export { SupportHandle, SupportHandleProvider, SupportHandleProviderProps, useSupportHandle };
90
+ //# sourceMappingURL=handle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handle.d.ts","names":[],"sources":["../../../src/support/context/handle.tsx"],"sourcesContent":[],"mappings":";;;;;;;AA6BA;;;;;;AA4CA;;;;;AAWA;AA2EA;;;;KAlIY,aAAA;;;;;;;;;;;;;;;;6BAgBgB;UACpB;aACG,cAAc;;;;;;;;;;;;;;;;;;;KA0Bb,0BAAA;;;;iBAII,OAAA,CAAM,IAAI;YACf,OAAA,CAAM;;;;;cAMJ,uBAAuB,OAAA,CAAM,GAAG;;;;;;;;;;;;;;;;iBA2E7B,gBAAA,CAAA,GAAoB"}
@@ -0,0 +1,79 @@
1
+ "use client";
2
+
3
+
4
+ import { useSupportConfig, useSupportNavigation } from "../store/support-store.js";
5
+ import { PENDING_CONVERSATION_ID } from "../../utils/id.js";
6
+ import * as React$1 from "react";
7
+ import { jsx } from "react/jsx-runtime";
8
+
9
+ //#region src/support/context/handle.tsx
10
+ const SupportHandleContext = React$1.createContext(null);
11
+ /**
12
+ * Provider that creates and exposes the imperative handle.
13
+ */
14
+ const SupportHandleProvider = ({ forwardedRef, children }) => {
15
+ const { open, close, toggle } = useSupportConfig();
16
+ const { navigate, goBack } = useSupportNavigation();
17
+ const handle = React$1.useMemo(() => ({
18
+ open,
19
+ close,
20
+ toggle,
21
+ navigate: (options) => {
22
+ navigate(options);
23
+ },
24
+ goBack,
25
+ openConversation: (conversationId) => {
26
+ navigate({
27
+ page: "CONVERSATION",
28
+ params: { conversationId }
29
+ });
30
+ open();
31
+ },
32
+ startConversation: (initialMessage) => {
33
+ navigate({
34
+ page: "CONVERSATION",
35
+ params: {
36
+ conversationId: PENDING_CONVERSATION_ID,
37
+ initialMessage
38
+ }
39
+ });
40
+ open();
41
+ },
42
+ goHome: () => {
43
+ navigate({ page: "HOME" });
44
+ }
45
+ }), [
46
+ open,
47
+ close,
48
+ toggle,
49
+ navigate,
50
+ goBack
51
+ ]);
52
+ React$1.useImperativeHandle(forwardedRef, () => handle, [handle]);
53
+ return /* @__PURE__ */ jsx(SupportHandleContext.Provider, {
54
+ value: handle,
55
+ children
56
+ });
57
+ };
58
+ /**
59
+ * Hook to access the imperative handle from within the widget.
60
+ * Returns null if not inside Support component.
61
+ *
62
+ * @example
63
+ * function MyComponent() {
64
+ * const support = useSupportHandle();
65
+ *
66
+ * return (
67
+ * <button onClick={() => support?.startConversation("Hello!")}>
68
+ * Get Help
69
+ * </button>
70
+ * );
71
+ * }
72
+ */
73
+ function useSupportHandle() {
74
+ return React$1.useContext(SupportHandleContext);
75
+ }
76
+
77
+ //#endregion
78
+ export { SupportHandleProvider, useSupportHandle };
79
+ //# sourceMappingURL=handle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handle.js","names":["React","SupportHandleProvider: React.FC<SupportHandleProviderProps>"],"sources":["../../../src/support/context/handle.tsx"],"sourcesContent":["\"use client\";\n\nimport type { RouteRegistry } from \"@cossistant/core\";\nimport * as React from \"react\";\nimport { PENDING_CONVERSATION_ID } from \"../../utils/id\";\nimport { useSupportConfig, useSupportNavigation } from \"../store/support-store\";\n\n// =============================================================================\n// Handle Type\n// =============================================================================\n\n/**\n * Imperative handle for programmatic control of the Support widget.\n * Access via ref on the Support component or via useSupportHandle hook.\n *\n * @example\n * const supportRef = useRef<SupportHandle>(null);\n *\n * // Open the widget\n * supportRef.current?.open();\n *\n * // Navigate to a conversation\n * supportRef.current?.openConversation(\"conv_123\");\n *\n * // Start a new conversation with a message\n * supportRef.current?.startConversation(\"I need help with...\");\n *\n * <Support ref={supportRef} />\n */\nexport type SupportHandle = {\n\t/**\n\t * Open the support widget.\n\t */\n\topen: () => void;\n\t/**\n\t * Close the support widget.\n\t */\n\tclose: () => void;\n\t/**\n\t * Toggle the support widget open/closed.\n\t */\n\ttoggle: () => void;\n\t/**\n\t * Navigate to a specific page with optional params.\n\t */\n\tnavigate: <K extends keyof RouteRegistry>(options: {\n\t\tpage: K;\n\t\tparams?: RouteRegistry[K];\n\t}) => void;\n\t/**\n\t * Go back to the previous page.\n\t */\n\tgoBack: () => void;\n\t/**\n\t * Open a specific conversation.\n\t */\n\topenConversation: (conversationId: string) => void;\n\t/**\n\t * Start a new conversation, optionally with an initial message.\n\t */\n\tstartConversation: (initialMessage?: string) => void;\n\t/**\n\t * Navigate to the home page.\n\t */\n\tgoHome: () => void;\n};\n\n// =============================================================================\n// Context\n// =============================================================================\n\nconst SupportHandleContext = React.createContext<SupportHandle | null>(null);\n\nexport type SupportHandleProviderProps = {\n\t/**\n\t * Ref to expose the handle to parent components.\n\t */\n\tforwardedRef?: React.Ref<SupportHandle>;\n\tchildren: React.ReactNode;\n};\n\n/**\n * Provider that creates and exposes the imperative handle.\n */\nexport const SupportHandleProvider: React.FC<SupportHandleProviderProps> = ({\n\tforwardedRef,\n\tchildren,\n}) => {\n\tconst { open, close, toggle } = useSupportConfig();\n\tconst { navigate, goBack } = useSupportNavigation();\n\n\tconst handle = React.useMemo<SupportHandle>(\n\t\t() => ({\n\t\t\topen,\n\t\t\tclose,\n\t\t\ttoggle,\n\t\t\tnavigate: <K extends keyof RouteRegistry>(options: {\n\t\t\t\tpage: K;\n\t\t\t\tparams?: RouteRegistry[K];\n\t\t\t}) => {\n\t\t\t\t// Use type assertion since we know the navigate function accepts these types\n\t\t\t\tnavigate(options as Parameters<typeof navigate>[0]);\n\t\t\t},\n\t\t\tgoBack,\n\t\t\topenConversation: (conversationId: string) => {\n\t\t\t\tnavigate({\n\t\t\t\t\tpage: \"CONVERSATION\",\n\t\t\t\t\tparams: { conversationId },\n\t\t\t\t});\n\t\t\t\t// Also open the widget if closed\n\t\t\t\topen();\n\t\t\t},\n\t\t\tstartConversation: (initialMessage?: string) => {\n\t\t\t\tnavigate({\n\t\t\t\t\tpage: \"CONVERSATION\",\n\t\t\t\t\tparams: {\n\t\t\t\t\t\tconversationId: PENDING_CONVERSATION_ID,\n\t\t\t\t\t\tinitialMessage,\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\t// Also open the widget if closed\n\t\t\t\topen();\n\t\t\t},\n\t\t\tgoHome: () => {\n\t\t\t\tnavigate({ page: \"HOME\" });\n\t\t\t},\n\t\t}),\n\t\t[open, close, toggle, navigate, goBack]\n\t);\n\n\t// Expose handle via ref\n\tReact.useImperativeHandle(forwardedRef, () => handle, [handle]);\n\n\treturn (\n\t\t<SupportHandleContext.Provider value={handle}>\n\t\t\t{children}\n\t\t</SupportHandleContext.Provider>\n\t);\n};\n\n// =============================================================================\n// Hook\n// =============================================================================\n\n/**\n * Hook to access the imperative handle from within the widget.\n * Returns null if not inside Support component.\n *\n * @example\n * function MyComponent() {\n * const support = useSupportHandle();\n *\n * return (\n * <button onClick={() => support?.startConversation(\"Hello!\")}>\n * Get Help\n * </button>\n * );\n * }\n */\nexport function useSupportHandle(): SupportHandle | null {\n\treturn React.useContext(SupportHandleContext);\n}\n"],"mappings":";;;;;;;;;AAuEA,MAAM,uBAAuBA,QAAM,cAAoC,KAAK;;;;AAa5E,MAAaC,yBAA+D,EAC3E,cACA,eACK;CACL,MAAM,EAAE,MAAM,OAAO,WAAW,kBAAkB;CAClD,MAAM,EAAE,UAAU,WAAW,sBAAsB;CAEnD,MAAM,SAASD,QAAM,eACb;EACN;EACA;EACA;EACA,WAA0C,YAGpC;AAEL,YAAS,QAA0C;;EAEpD;EACA,mBAAmB,mBAA2B;AAC7C,YAAS;IACR,MAAM;IACN,QAAQ,EAAE,gBAAgB;IAC1B,CAAC;AAEF,SAAM;;EAEP,oBAAoB,mBAA4B;AAC/C,YAAS;IACR,MAAM;IACN,QAAQ;KACP,gBAAgB;KAChB;KACA;IACD,CAAC;AAEF,SAAM;;EAEP,cAAc;AACb,YAAS,EAAE,MAAM,QAAQ,CAAC;;EAE3B,GACD;EAAC;EAAM;EAAO;EAAQ;EAAU;EAAO,CACvC;AAGD,SAAM,oBAAoB,oBAAoB,QAAQ,CAAC,OAAO,CAAC;AAE/D,QACC,oBAAC,qBAAqB;EAAS,OAAO;EACpC;GAC8B;;;;;;;;;;;;;;;;;AAuBlC,SAAgB,mBAAyC;AACxD,QAAOA,QAAM,WAAW,qBAAqB"}
@@ -0,0 +1,17 @@
1
+ import * as React$1 from "react";
2
+
3
+ //#region src/support/context/positioning.d.ts
4
+ type TriggerRefContextValue = {
5
+ /** The trigger element (state-based for reactivity) */
6
+ triggerElement: HTMLElement | null;
7
+ /** Set the trigger element - triggers re-render when called */
8
+ setTriggerElement: (element: HTMLElement | null) => void;
9
+ };
10
+ type TriggerRefProviderProps = {
11
+ children: React$1.ReactNode;
12
+ };
13
+ declare const TriggerRefProvider: React$1.FC<TriggerRefProviderProps>;
14
+ declare function useTriggerRef(): TriggerRefContextValue | null;
15
+ //#endregion
16
+ export { TriggerRefContextValue, TriggerRefProvider, TriggerRefProviderProps, useTriggerRef };
17
+ //# sourceMappingURL=positioning.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"positioning.d.ts","names":[],"sources":["../../../src/support/context/positioning.tsx"],"sourcesContent":[],"mappings":";;;KAQY,sBAAA;;EAAA,cAAA,EAEK,WAFiB,GAAA,IAAA;EAmBtB;EAIC,iBAAA,EAAA,CAAA,OAqBZ,EAxC6B,WAmBY,GAAA,IAAA,EAAA,GAAA,IAAA;AA2B1C,CAAA;KA/BY,uBAAA;YACD,OAAA,CAAM;;cAGJ,oBAAoB,OAAA,CAAM,GAAG;iBA2B1B,aAAA,CAAA,GAAiB"}
@@ -0,0 +1,26 @@
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/positioning.tsx
8
+ const TriggerRefContext = React$1.createContext(null);
9
+ const TriggerRefProvider = ({ children }) => {
10
+ const [triggerElement, setTriggerElement] = React$1.useState(null);
11
+ const value = React$1.useMemo(() => ({
12
+ triggerElement,
13
+ setTriggerElement
14
+ }), [triggerElement]);
15
+ return /* @__PURE__ */ jsx(TriggerRefContext.Provider, {
16
+ value,
17
+ children
18
+ });
19
+ };
20
+ function useTriggerRef() {
21
+ return React$1.useContext(TriggerRefContext);
22
+ }
23
+
24
+ //#endregion
25
+ export { TriggerRefProvider, useTriggerRef };
26
+ //# sourceMappingURL=positioning.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"positioning.js","names":["React","TriggerRefProvider: React.FC<TriggerRefProviderProps>"],"sources":["../../../src/support/context/positioning.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport type TriggerRefContextValue = {\n\t/** The trigger element (state-based for reactivity) */\n\ttriggerElement: HTMLElement | null;\n\t/** Set the trigger element - triggers re-render when called */\n\tsetTriggerElement: (element: HTMLElement | null) => void;\n};\n\n// =============================================================================\n// Context\n// =============================================================================\n\nconst TriggerRefContext = React.createContext<TriggerRefContextValue | null>(\n\tnull\n);\n\n// =============================================================================\n// Provider\n// =============================================================================\n\nexport type TriggerRefProviderProps = {\n\tchildren: React.ReactNode;\n};\n\nexport const TriggerRefProvider: React.FC<TriggerRefProviderProps> = ({\n\tchildren,\n}) => {\n\t// Using state instead of ref to trigger re-renders when trigger mounts\n\t// This ensures Floating UI receives the reference element\n\tconst [triggerElement, setTriggerElement] =\n\t\tReact.useState<HTMLElement | null>(null);\n\n\tconst value = React.useMemo<TriggerRefContextValue>(\n\t\t() => ({\n\t\t\ttriggerElement,\n\t\t\tsetTriggerElement,\n\t\t}),\n\t\t[triggerElement]\n\t);\n\n\treturn (\n\t\t<TriggerRefContext.Provider value={value}>\n\t\t\t{children}\n\t\t</TriggerRefContext.Provider>\n\t);\n};\n\n// =============================================================================\n// Hook\n// =============================================================================\n\nexport function useTriggerRef(): TriggerRefContextValue | null {\n\treturn React.useContext(TriggerRefContext);\n}\n"],"mappings":";;;;;;;AAmBA,MAAM,oBAAoBA,QAAM,cAC/B,KACA;AAUD,MAAaC,sBAAyD,EACrE,eACK;CAGL,MAAM,CAAC,gBAAgB,qBACtBD,QAAM,SAA6B,KAAK;CAEzC,MAAM,QAAQA,QAAM,eACZ;EACN;EACA;EACA,GACD,CAAC,eAAe,CAChB;AAED,QACC,oBAAC,kBAAkB;EAAgB;EACjC;GAC2B;;AAQ/B,SAAgB,gBAA+C;AAC9D,QAAOA,QAAM,WAAW,kBAAkB"}
@@ -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