@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.
- package/README.md +1 -1
- package/api.d.ts +1 -1
- package/api.d.ts.map +1 -1
- package/checks.d.ts +1 -1
- package/checks.d.ts.map +1 -1
- package/coerce.d.ts +1 -1
- package/coerce.d.ts.map +1 -1
- package/conversation.d.ts +6 -3
- package/conversation.d.ts.map +1 -1
- package/core.d.ts +1 -1
- package/core.d.ts.map +1 -1
- package/errors.d.ts +12 -3
- package/errors.d.ts.map +1 -1
- package/errors2.d.ts +1 -1
- package/errors2.d.ts.map +1 -1
- package/hooks/index.d.ts +3 -2
- package/hooks/index.js +6 -5
- package/hooks/private/store/use-website-store.js +2 -1
- package/hooks/private/store/use-website-store.js.map +1 -1
- package/hooks/private/use-client-query.d.ts +6 -0
- package/hooks/private/use-client-query.d.ts.map +1 -1
- package/hooks/private/use-client-query.js +26 -3
- package/hooks/private/use-client-query.js.map +1 -1
- package/hooks/private/use-grouped-messages.d.ts +8 -5
- package/hooks/private/use-grouped-messages.d.ts.map +1 -1
- package/hooks/private/use-grouped-messages.js +44 -11
- package/hooks/private/use-grouped-messages.js.map +1 -1
- package/hooks/private/use-multimodal-input.d.ts.map +1 -1
- package/hooks/private/use-multimodal-input.js +7 -5
- package/hooks/private/use-multimodal-input.js.map +1 -1
- package/hooks/private/use-visitor-typing-reporter.d.ts +18 -1
- package/hooks/private/use-visitor-typing-reporter.d.ts.map +1 -1
- package/hooks/private/use-visitor-typing-reporter.js +34 -4
- package/hooks/private/use-visitor-typing-reporter.js.map +1 -1
- package/hooks/use-conversation-page.d.ts +1 -0
- package/hooks/use-conversation-page.d.ts.map +1 -1
- package/hooks/use-conversation-page.js +6 -1
- package/hooks/use-conversation-page.js.map +1 -1
- package/hooks/use-conversation-preview.d.ts +2 -1
- package/hooks/use-conversation-preview.d.ts.map +1 -1
- package/hooks/use-conversation-preview.js +1 -1
- package/hooks/use-conversation-preview.js.map +1 -1
- package/hooks/use-conversation-seen.js +1 -1
- package/hooks/use-conversation-seen.js.map +1 -1
- package/hooks/use-conversation-timeline-items.js +2 -1
- package/hooks/use-conversation-timeline-items.js.map +1 -1
- package/hooks/use-conversation-timeline.d.ts.map +1 -1
- package/hooks/use-conversation-timeline.js +1 -3
- package/hooks/use-conversation-timeline.js.map +1 -1
- package/hooks/use-conversation.js +2 -1
- package/hooks/use-conversation.js.map +1 -1
- package/hooks/use-conversations.js +1 -0
- package/hooks/use-conversations.js.map +1 -1
- package/hooks/use-create-conversation.d.ts.map +1 -1
- package/hooks/use-file-upload.d.ts +55 -0
- package/hooks/use-file-upload.d.ts.map +1 -0
- package/hooks/use-file-upload.js +100 -0
- package/hooks/use-file-upload.js.map +1 -0
- package/hooks/use-message-composer.d.ts +11 -0
- package/hooks/use-message-composer.d.ts.map +1 -1
- package/hooks/use-message-composer.js +7 -3
- package/hooks/use-message-composer.js.map +1 -1
- package/hooks/use-send-message.d.ts +1 -0
- package/hooks/use-send-message.d.ts.map +1 -1
- package/hooks/use-send-message.js +63 -11
- package/hooks/use-send-message.js.map +1 -1
- package/index.d.ts +7 -4
- package/index.js +13 -10
- package/json-schema.d.ts +70 -0
- package/json-schema.d.ts.map +1 -0
- package/package.json +4 -3
- package/parse.d.ts +1 -1
- package/parse.d.ts.map +1 -1
- package/primitives/avatar/fallback.d.ts.map +1 -1
- package/primitives/avatar/fallback.js +1 -1
- package/primitives/avatar/fallback.js.map +1 -1
- package/primitives/conversation-timeline.d.ts.map +1 -1
- package/primitives/conversation-timeline.js +10 -5
- package/primitives/conversation-timeline.js.map +1 -1
- package/primitives/day-separator.d.ts +76 -0
- package/primitives/day-separator.d.ts.map +1 -0
- package/primitives/day-separator.js +111 -0
- package/primitives/day-separator.js.map +1 -0
- package/primitives/index.d.ts +5 -3
- package/primitives/index.js +17 -5
- package/primitives/index.parts.d.ts +4 -2
- package/primitives/index.parts.js +5 -3
- package/primitives/timeline-item-attachments.d.ts +100 -0
- package/primitives/timeline-item-attachments.d.ts.map +1 -0
- package/primitives/timeline-item-attachments.js +151 -0
- package/primitives/timeline-item-attachments.js.map +1 -0
- package/primitives/timeline-item-group.d.ts.map +1 -1
- package/primitives/timeline-item-group.js +1 -1
- package/primitives/timeline-item-group.js.map +1 -1
- package/primitives/timeline-item.js +1 -1
- package/primitives/timeline-item.js.map +1 -1
- package/primitives/trigger.d.ts +91 -0
- package/primitives/trigger.d.ts.map +1 -0
- package/primitives/trigger.js +74 -0
- package/primitives/trigger.js.map +1 -0
- package/primitives/window.d.ts +22 -1
- package/primitives/window.d.ts.map +1 -1
- package/primitives/window.js +91 -5
- package/primitives/window.js.map +1 -1
- package/provider.d.ts.map +1 -1
- package/provider.js +8 -3
- package/provider.js.map +1 -1
- package/realtime/index.js +1 -1
- package/realtime/provider.js +1 -1
- package/realtime/support-provider.js +5 -1
- package/realtime/support-provider.js.map +1 -1
- package/realtime-events.d.ts +165 -2
- package/realtime-events.d.ts.map +1 -1
- package/registries.d.ts +1 -1
- package/registries.d.ts.map +1 -1
- package/schemas.d.ts +305 -7
- package/schemas.d.ts.map +1 -1
- package/schemas2.d.ts +29 -4
- package/schemas2.d.ts.map +1 -1
- package/schemas3.d.ts +2 -1
- package/schemas3.d.ts.map +1 -1
- package/standard-schema.d.ts +83 -21
- package/standard-schema.d.ts.map +1 -1
- package/support/components/button.d.ts +1 -1
- package/support/components/content.d.ts +30 -0
- package/support/components/content.d.ts.map +1 -0
- package/support/components/content.js +282 -0
- package/support/components/content.js.map +1 -0
- package/support/components/conversation-button-link.js +1 -1
- package/support/components/conversation-timeline.d.ts +5 -0
- package/support/components/conversation-timeline.d.ts.map +1 -1
- package/support/components/conversation-timeline.js +25 -5
- package/support/components/conversation-timeline.js.map +1 -1
- package/support/components/header.js +1 -1
- package/support/components/image-lightbox.d.ts +49 -0
- package/support/components/image-lightbox.d.ts.map +1 -0
- package/support/components/image-lightbox.js +142 -0
- package/support/components/image-lightbox.js.map +1 -0
- package/support/components/index.d.ts +5 -4
- package/support/components/index.js +4 -4
- package/support/components/multimodal-input.d.ts +4 -1
- package/support/components/multimodal-input.d.ts.map +1 -1
- package/support/components/multimodal-input.js +71 -45
- package/support/components/multimodal-input.js.map +1 -1
- package/support/components/navigation-tab.js +1 -1
- package/support/components/root.d.ts +23 -0
- package/support/components/root.d.ts.map +1 -0
- package/support/components/root.js +36 -0
- package/support/components/root.js.map +1 -0
- package/support/components/timeline-message-item.d.ts.map +1 -1
- package/support/components/timeline-message-item.js +82 -18
- package/support/components/timeline-message-item.js.map +1 -1
- package/support/components/trigger.d.ts +14 -0
- package/support/components/trigger.d.ts.map +1 -0
- package/support/components/{bubble.js → trigger.js} +16 -12
- package/support/components/trigger.js.map +1 -0
- package/support/components/typing-indicator.d.ts.map +1 -1
- package/support/components/typing-indicator.js +1 -0
- package/support/components/typing-indicator.js.map +1 -1
- package/support/context/controlled-state.d.ts +46 -0
- package/support/context/controlled-state.d.ts.map +1 -0
- package/support/context/controlled-state.js +34 -0
- package/support/context/controlled-state.js.map +1 -0
- package/support/context/events.d.ts +103 -0
- package/support/context/events.d.ts.map +1 -0
- package/support/context/events.js +139 -0
- package/support/context/events.js.map +1 -0
- package/support/context/handle.d.ts +90 -0
- package/support/context/handle.d.ts.map +1 -0
- package/support/context/handle.js +79 -0
- package/support/context/handle.js.map +1 -0
- package/support/context/positioning.d.ts +17 -0
- package/support/context/positioning.d.ts.map +1 -0
- package/support/context/positioning.js +26 -0
- package/support/context/positioning.js.map +1 -0
- package/support/context/slots.d.ts +85 -0
- package/support/context/slots.d.ts.map +1 -0
- package/support/context/slots.js +115 -0
- package/support/context/slots.js.map +1 -0
- package/support/context/websocket.d.ts +8 -1
- package/support/context/websocket.d.ts.map +1 -1
- package/support/context/websocket.js +8 -1
- package/support/context/websocket.js.map +1 -1
- package/support/index.d.ts +239 -54
- package/support/index.d.ts.map +1 -1
- package/support/index.js +254 -33
- package/support/index.js.map +1 -1
- package/support/pages/articles.d.ts.map +1 -1
- package/support/pages/articles.js +3 -4
- package/support/pages/articles.js.map +1 -1
- package/support/pages/conversation-history.js +2 -2
- package/support/pages/conversation.js +6 -5
- package/support/pages/conversation.js.map +1 -1
- package/support/pages/home.js +2 -2
- package/support/router.d.ts +52 -12
- package/support/router.d.ts.map +1 -1
- package/support/router.js +78 -30
- package/support/router.js.map +1 -1
- package/support/store/index.d.ts +2 -2
- package/support/store/support-store.d.ts +26 -20
- package/support/store/support-store.d.ts.map +1 -1
- package/support/store/support-store.js +47 -6
- package/support/store/support-store.js.map +1 -1
- package/support/{support-D2EgfIts.css → support-C7Xaw-N6.css} +1 -2
- package/support/support-C7Xaw-N6.css.map +1 -0
- package/support/text/index.d.ts +1 -1
- package/support/text/index.d.ts.map +1 -1
- package/support/text/index.js.map +1 -1
- package/support/types.d.ts +75 -12
- package/support/types.d.ts.map +1 -1
- package/support.css +2 -2
- package/tailwind.css +0 -1
- package/timeline-item.d.ts +68 -2
- package/timeline-item.d.ts.map +1 -1
- package/to-json-schema.d.ts +96 -0
- package/to-json-schema.d.ts.map +1 -0
- package/util.d.ts +6 -2
- package/util.d.ts.map +1 -1
- package/utils/index.d.ts +2 -1
- package/utils/index.js +2 -1
- package/utils/merge-refs.d.ts +30 -0
- package/utils/merge-refs.d.ts.map +1 -0
- package/utils/merge-refs.js +46 -0
- package/utils/merge-refs.js.map +1 -0
- package/utils/use-render-element.d.ts.map +1 -1
- package/utils/use-render-element.js +36 -8
- package/utils/use-render-element.js.map +1 -1
- package/versions.d.ts +2 -2
- package/versions.d.ts.map +1 -1
- package/zod-extensions.d.ts +1 -1
- package/zod-extensions.d.ts.map +1 -1
- package/primitives/bubble.d.ts +0 -38
- package/primitives/bubble.d.ts.map +0 -1
- package/primitives/bubble.js +0 -57
- package/primitives/bubble.js.map +0 -1
- package/support/components/bubble.d.ts +0 -10
- package/support/components/bubble.d.ts.map +0 -1
- package/support/components/bubble.js.map +0 -1
- package/support/components/container.d.ts +0 -13
- package/support/components/container.d.ts.map +0 -1
- package/support/components/container.js +0 -109
- package/support/components/container.js.map +0 -1
- package/support/components/support-content.d.ts +0 -22
- package/support/components/support-content.d.ts.map +0 -1
- package/support/components/support-content.js +0 -48
- package/support/components/support-content.js.map +0 -1
- 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;
|
|
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
|