@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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"websocket.js","names":["WebSocketBridge: React.FC<WebSocketBridgeProps>","intervalId: number | null","WebSocketProvider: React.FC<WebSocketProviderProps>"],"sources":["../../../src/support/context/websocket.tsx"],"sourcesContent":["\"use client\";\n\nimport { PRESENCE_PING_INTERVAL_MS } from \"@cossistant/types\";\nimport type React from \"react\";\nimport { createContext, useContext, useEffect, useMemo } from \"react\";\nimport {\n\ttype RealtimeAuthConfig,\n\ttype RealtimeContextValue,\n\tRealtimeProvider,\n\tuseRealtimeConnection,\n} from \"../../realtime\";\n\ntype WebSocketContextValue = RealtimeContextValue;\n\ntype WebSocketProviderProps = {\n\tchildren: React.ReactNode;\n\tpublicKey?: string;\n\twebsiteId?: string;\n\tvisitorId?: string;\n\twsUrl?: string;\n\tautoConnect?: boolean;\n\tonConnect?: () => void;\n\tonDisconnect?: () => void;\n\tonError?: (error: Error) => void;\n};\n\nconst WebSocketContext = createContext<WebSocketContextValue | null>(null);\n\nfunction createVisitorAuthConfig({\n\tvisitorId,\n\twebsiteId,\n\tpublicKey,\n}: Pick<\n\tWebSocketProviderProps,\n\t\"visitorId\" | \"websiteId\" | \"publicKey\"\n>): RealtimeAuthConfig | null {\n\tconst normalizedVisitorId = visitorId?.trim();\n\tif (!normalizedVisitorId) {\n\t\treturn null;\n\t}\n\n\treturn {\n\t\tkind: \"visitor\",\n\t\tvisitorId: normalizedVisitorId,\n\t\twebsiteId: websiteId?.trim() || null,\n\t\tpublicKey: publicKey?.trim() || null,\n\t} satisfies RealtimeAuthConfig;\n}\n\ntype WebSocketBridgeProps = {\n\tchildren: React.ReactNode;\n\tonError?: (error: Error) => void;\n};\n\nconst WebSocketBridge: React.FC<WebSocketBridgeProps> = ({\n\tchildren,\n\tonError,\n}) => {\n\tconst connection = useRealtimeConnection();\n\tconst { visitorId, sendRaw, isConnected } = connection;\n\n\tuseEffect(() => {\n\t\tif (typeof window === \"undefined\" || typeof document === \"undefined\") {\n\t\t\treturn;\n\t\t}\n\n\t\tif (!(visitorId && sendRaw)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst pingMessage = \"presence:ping\";\n\n\t\tconst sendPresencePing = () => {\n\t\t\tif (!isConnected) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tsendRaw(pingMessage);\n\t\t\t} catch (error) {\n\t\t\t\tif (!onError) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst normalizedError =\n\t\t\t\t\terror instanceof Error\n\t\t\t\t\t\t? error\n\t\t\t\t\t\t: new Error(\n\t\t\t\t\t\t\t\ttypeof error === \"string\"\n\t\t\t\t\t\t\t\t\t? error\n\t\t\t\t\t\t\t\t\t: \"Unknown presence ping error\"\n\t\t\t\t\t\t\t);\n\n\t\t\t\tif (!normalizedError.message.includes(\"Failed to send presence ping\")) {\n\t\t\t\t\tnormalizedError.message = `Failed to send presence ping: ${normalizedError.message}`;\n\t\t\t\t}\n\n\t\t\t\tonError(normalizedError);\n\t\t\t}\n\t\t};\n\n\t\tlet intervalId: number | null = null;\n\n\t\tconst clearPresenceInterval = () => {\n\t\t\tif (intervalId !== null) {\n\t\t\t\twindow.clearInterval(intervalId);\n\t\t\t\tintervalId = null;\n\t\t\t}\n\t\t};\n\n\t\tconst startPresenceInterval = () => {\n\t\t\tclearPresenceInterval();\n\n\t\t\tif (!isConnected || document.visibilityState === \"hidden\") {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tintervalId = window.setInterval(\n\t\t\t\tsendPresencePing,\n\t\t\t\tPRESENCE_PING_INTERVAL_MS\n\t\t\t);\n\t\t};\n\n\t\tconst handleFocus = () => {\n\t\t\tsendPresencePing();\n\t\t\tstartPresenceInterval();\n\t\t};\n\n\t\tconst handleVisibilityChange = () => {\n\t\t\tif (document.visibilityState === \"hidden\") {\n\t\t\t\tclearPresenceInterval();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tsendPresencePing();\n\t\t\tstartPresenceInterval();\n\t\t};\n\n\t\twindow.addEventListener(\"focus\", handleFocus);\n\t\tdocument.addEventListener(\"visibilitychange\", handleVisibilityChange);\n\n\t\tif (isConnected && document.visibilityState !== \"hidden\") {\n\t\t\tsendPresencePing();\n\t\t\tstartPresenceInterval();\n\t\t}\n\n\t\treturn () => {\n\t\t\twindow.removeEventListener(\"focus\", handleFocus);\n\t\t\tdocument.removeEventListener(\"visibilitychange\", handleVisibilityChange);\n\t\t\tclearPresenceInterval();\n\t\t};\n\t}, [isConnected, onError, sendRaw, visitorId]);\n\tconst value = useMemo(() => connection, [connection]);\n\treturn (\n\t\t<WebSocketContext.Provider value={value}>\n\t\t\t{children}\n\t\t</WebSocketContext.Provider>\n\t);\n};\n\n/**\n * Support-specific realtime provider that authenticates visitors and keeps the\n * connection alive with presence pings.\n */\nexport const WebSocketProvider: React.FC<WebSocketProviderProps> = ({\n\tchildren,\n\tpublicKey,\n\twebsiteId,\n\tvisitorId,\n\twsUrl,\n\tautoConnect = true,\n\tonConnect,\n\tonDisconnect,\n\tonError,\n}) => {\n\tconst auth = createVisitorAuthConfig({ publicKey, websiteId, visitorId });\n\n\treturn (\n\t\t<RealtimeProvider\n\t\t\tauth={auth}\n\t\t\tautoConnect={autoConnect}\n\t\t\tonConnect={onConnect}\n\t\t\tonDisconnect={onDisconnect}\n\t\t\tonError={onError}\n\t\t\twsUrl={wsUrl}\n\t\t>\n\t\t\t<WebSocketBridge onError={onError}>{children}</WebSocketBridge>\n\t\t</RealtimeProvider>\n\t);\n};\n\n/**\n * Accessor for the support websocket context.\n */\nexport const useWebSocket = (): WebSocketContextValue => {\n\tconst context = useContext(WebSocketContext);\n\tif (!context) {\n\t\tthrow new Error(\"useWebSocket must be used within WebSocketProvider\");\n\t}\n\treturn context;\n};\n\nexport type { WebSocketContextValue, WebSocketProviderProps };\nexport type { RealtimeEvent } from \"@cossistant/types/realtime-events\";\n"],"mappings":";;;;;;;;;AA0BA,MAAM,mBAAmB,cAA4C,KAAK;AAE1E,SAAS,wBAAwB,EAChC,WACA,WACA,aAI6B;CAC7B,MAAM,sBAAsB,WAAW,MAAM;AAC7C,KAAI,CAAC,oBACJ,QAAO;AAGR,QAAO;EACN,MAAM;EACN,WAAW;EACX,WAAW,WAAW,MAAM,IAAI;EAChC,WAAW,WAAW,MAAM,IAAI;EAChC;;AAQF,MAAMA,mBAAmD,EACxD,UACA,cACK;CACL,MAAM,aAAa,uBAAuB;CAC1C,MAAM,EAAE,WAAW,SAAS,gBAAgB;AAE5C,iBAAgB;AACf,MAAI,OAAO,WAAW,eAAe,OAAO,aAAa,YACxD;AAGD,MAAI,EAAE,aAAa,SAClB;EAGD,MAAM,cAAc;EAEpB,MAAM,yBAAyB;AAC9B,OAAI,CAAC,YACJ;AAGD,OAAI;AACH,YAAQ,YAAY;YACZ,OAAO;AACf,QAAI,CAAC,QACJ;IAGD,MAAM,kBACL,iBAAiB,QACd,QACA,IAAI,MACJ,OAAO,UAAU,WACd,QACA,8BACH;AAEJ,QAAI,CAAC,gBAAgB,QAAQ,SAAS,+BAA+B,CACpE,iBAAgB,UAAU,iCAAiC,gBAAgB;AAG5E,YAAQ,gBAAgB;;;EAI1B,IAAIC,aAA4B;EAEhC,MAAM,8BAA8B;AACnC,OAAI,eAAe,MAAM;AACxB,WAAO,cAAc,WAAW;AAChC,iBAAa;;;EAIf,MAAM,8BAA8B;AACnC,0BAAuB;AAEvB,OAAI,CAAC,eAAe,SAAS,oBAAoB,SAChD;AAGD,gBAAa,OAAO,YACnB,kBACA,0BACA;;EAGF,MAAM,oBAAoB;AACzB,qBAAkB;AAClB,0BAAuB;;EAGxB,MAAM,+BAA+B;AACpC,OAAI,SAAS,oBAAoB,UAAU;AAC1C,2BAAuB;AACvB;;AAGD,qBAAkB;AAClB,0BAAuB;;AAGxB,SAAO,iBAAiB,SAAS,YAAY;AAC7C,WAAS,iBAAiB,oBAAoB,uBAAuB;AAErE,MAAI,eAAe,SAAS,oBAAoB,UAAU;AACzD,qBAAkB;AAClB,0BAAuB;;AAGxB,eAAa;AACZ,UAAO,oBAAoB,SAAS,YAAY;AAChD,YAAS,oBAAoB,oBAAoB,uBAAuB;AACxE,0BAAuB;;IAEtB;EAAC;EAAa;EAAS;EAAS;EAAU,CAAC;CAC9C,MAAM,QAAQ,cAAc,YAAY,CAAC,WAAW,CAAC;AACrD,QACC,oBAAC,iBAAiB;EAAgB;EAChC;GAC0B;;;;;;AAQ9B,MAAaC,qBAAuD,EACnE,UACA,WACA,WACA,WACA,OACA,cAAc,MACd,WACA,cACA,cACK;AAGL,QACC,oBAAC;EACA,MAJW,wBAAwB;GAAE;GAAW;GAAW;GAAW,CAAC;EAK1D;EACF;EACG;EACL;EACF;YAEP,oBAAC;GAAyB;GAAU;IAA2B;GAC7C
|
|
1
|
+
{"version":3,"file":"websocket.js","names":["WebSocketBridge: React.FC<WebSocketBridgeProps>","intervalId: number | null","WebSocketProvider: React.FC<WebSocketProviderProps>"],"sources":["../../../src/support/context/websocket.tsx"],"sourcesContent":["\"use client\";\n\nimport { PRESENCE_PING_INTERVAL_MS } from \"@cossistant/types\";\nimport type React from \"react\";\nimport { createContext, useContext, useEffect, useMemo } from \"react\";\nimport {\n\ttype RealtimeAuthConfig,\n\ttype RealtimeContextValue,\n\tRealtimeProvider,\n\tuseRealtimeConnection,\n} from \"../../realtime\";\n\ntype WebSocketContextValue = RealtimeContextValue;\n\ntype WebSocketProviderProps = {\n\tchildren: React.ReactNode;\n\tpublicKey?: string;\n\twebsiteId?: string;\n\tvisitorId?: string;\n\twsUrl?: string;\n\tautoConnect?: boolean;\n\tonConnect?: () => void;\n\tonDisconnect?: () => void;\n\tonError?: (error: Error) => void;\n};\n\nconst WebSocketContext = createContext<WebSocketContextValue | null>(null);\n\nfunction createVisitorAuthConfig({\n\tvisitorId,\n\twebsiteId,\n\tpublicKey,\n}: Pick<\n\tWebSocketProviderProps,\n\t\"visitorId\" | \"websiteId\" | \"publicKey\"\n>): RealtimeAuthConfig | null {\n\tconst normalizedVisitorId = visitorId?.trim();\n\tif (!normalizedVisitorId) {\n\t\treturn null;\n\t}\n\n\treturn {\n\t\tkind: \"visitor\",\n\t\tvisitorId: normalizedVisitorId,\n\t\twebsiteId: websiteId?.trim() || null,\n\t\tpublicKey: publicKey?.trim() || null,\n\t} satisfies RealtimeAuthConfig;\n}\n\ntype WebSocketBridgeProps = {\n\tchildren: React.ReactNode;\n\tonError?: (error: Error) => void;\n};\n\nconst WebSocketBridge: React.FC<WebSocketBridgeProps> = ({\n\tchildren,\n\tonError,\n}) => {\n\tconst connection = useRealtimeConnection();\n\tconst { visitorId, sendRaw, isConnected } = connection;\n\n\tuseEffect(() => {\n\t\tif (typeof window === \"undefined\" || typeof document === \"undefined\") {\n\t\t\treturn;\n\t\t}\n\n\t\tif (!(visitorId && sendRaw)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst pingMessage = \"presence:ping\";\n\n\t\tconst sendPresencePing = () => {\n\t\t\tif (!isConnected) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tsendRaw(pingMessage);\n\t\t\t} catch (error) {\n\t\t\t\tif (!onError) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst normalizedError =\n\t\t\t\t\terror instanceof Error\n\t\t\t\t\t\t? error\n\t\t\t\t\t\t: new Error(\n\t\t\t\t\t\t\t\ttypeof error === \"string\"\n\t\t\t\t\t\t\t\t\t? error\n\t\t\t\t\t\t\t\t\t: \"Unknown presence ping error\"\n\t\t\t\t\t\t\t);\n\n\t\t\t\tif (!normalizedError.message.includes(\"Failed to send presence ping\")) {\n\t\t\t\t\tnormalizedError.message = `Failed to send presence ping: ${normalizedError.message}`;\n\t\t\t\t}\n\n\t\t\t\tonError(normalizedError);\n\t\t\t}\n\t\t};\n\n\t\tlet intervalId: number | null = null;\n\n\t\tconst clearPresenceInterval = () => {\n\t\t\tif (intervalId !== null) {\n\t\t\t\twindow.clearInterval(intervalId);\n\t\t\t\tintervalId = null;\n\t\t\t}\n\t\t};\n\n\t\tconst startPresenceInterval = () => {\n\t\t\tclearPresenceInterval();\n\n\t\t\tif (!isConnected || document.visibilityState === \"hidden\") {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tintervalId = window.setInterval(\n\t\t\t\tsendPresencePing,\n\t\t\t\tPRESENCE_PING_INTERVAL_MS\n\t\t\t);\n\t\t};\n\n\t\tconst handleFocus = () => {\n\t\t\tsendPresencePing();\n\t\t\tstartPresenceInterval();\n\t\t};\n\n\t\tconst handleVisibilityChange = () => {\n\t\t\tif (document.visibilityState === \"hidden\") {\n\t\t\t\tclearPresenceInterval();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tsendPresencePing();\n\t\t\tstartPresenceInterval();\n\t\t};\n\n\t\twindow.addEventListener(\"focus\", handleFocus);\n\t\tdocument.addEventListener(\"visibilitychange\", handleVisibilityChange);\n\n\t\tif (isConnected && document.visibilityState !== \"hidden\") {\n\t\t\tsendPresencePing();\n\t\t\tstartPresenceInterval();\n\t\t}\n\n\t\treturn () => {\n\t\t\twindow.removeEventListener(\"focus\", handleFocus);\n\t\t\tdocument.removeEventListener(\"visibilitychange\", handleVisibilityChange);\n\t\t\tclearPresenceInterval();\n\t\t};\n\t}, [isConnected, onError, sendRaw, visitorId]);\n\tconst value = useMemo(() => connection, [connection]);\n\treturn (\n\t\t<WebSocketContext.Provider value={value}>\n\t\t\t{children}\n\t\t</WebSocketContext.Provider>\n\t);\n};\n\n/**\n * Support-specific realtime provider that authenticates visitors and keeps the\n * connection alive with presence pings.\n */\nexport const WebSocketProvider: React.FC<WebSocketProviderProps> = ({\n\tchildren,\n\tpublicKey,\n\twebsiteId,\n\tvisitorId,\n\twsUrl,\n\tautoConnect = true,\n\tonConnect,\n\tonDisconnect,\n\tonError,\n}) => {\n\tconst auth = createVisitorAuthConfig({ publicKey, websiteId, visitorId });\n\n\treturn (\n\t\t<RealtimeProvider\n\t\t\tauth={auth}\n\t\t\tautoConnect={autoConnect}\n\t\t\tonConnect={onConnect}\n\t\t\tonDisconnect={onDisconnect}\n\t\t\tonError={onError}\n\t\t\twsUrl={wsUrl}\n\t\t>\n\t\t\t<WebSocketBridge onError={onError}>{children}</WebSocketBridge>\n\t\t</RealtimeProvider>\n\t);\n};\n\n/**\n * Accessor for the support websocket context.\n * Throws if used outside WebSocketProvider.\n */\nexport const useWebSocket = (): WebSocketContextValue => {\n\tconst context = useContext(WebSocketContext);\n\tif (!context) {\n\t\tthrow new Error(\"useWebSocket must be used within WebSocketProvider\");\n\t}\n\treturn context;\n};\n\n/**\n * Safe accessor for the support websocket context.\n * Returns null if used outside WebSocketProvider instead of throwing.\n * Useful for optional WebSocket usage in hooks that may or may not have the provider.\n */\nexport const useWebSocketSafe = (): WebSocketContextValue | null =>\n\tuseContext(WebSocketContext);\n\nexport type { WebSocketContextValue, WebSocketProviderProps };\nexport type { RealtimeEvent } from \"@cossistant/types/realtime-events\";\n"],"mappings":";;;;;;;;;AA0BA,MAAM,mBAAmB,cAA4C,KAAK;AAE1E,SAAS,wBAAwB,EAChC,WACA,WACA,aAI6B;CAC7B,MAAM,sBAAsB,WAAW,MAAM;AAC7C,KAAI,CAAC,oBACJ,QAAO;AAGR,QAAO;EACN,MAAM;EACN,WAAW;EACX,WAAW,WAAW,MAAM,IAAI;EAChC,WAAW,WAAW,MAAM,IAAI;EAChC;;AAQF,MAAMA,mBAAmD,EACxD,UACA,cACK;CACL,MAAM,aAAa,uBAAuB;CAC1C,MAAM,EAAE,WAAW,SAAS,gBAAgB;AAE5C,iBAAgB;AACf,MAAI,OAAO,WAAW,eAAe,OAAO,aAAa,YACxD;AAGD,MAAI,EAAE,aAAa,SAClB;EAGD,MAAM,cAAc;EAEpB,MAAM,yBAAyB;AAC9B,OAAI,CAAC,YACJ;AAGD,OAAI;AACH,YAAQ,YAAY;YACZ,OAAO;AACf,QAAI,CAAC,QACJ;IAGD,MAAM,kBACL,iBAAiB,QACd,QACA,IAAI,MACJ,OAAO,UAAU,WACd,QACA,8BACH;AAEJ,QAAI,CAAC,gBAAgB,QAAQ,SAAS,+BAA+B,CACpE,iBAAgB,UAAU,iCAAiC,gBAAgB;AAG5E,YAAQ,gBAAgB;;;EAI1B,IAAIC,aAA4B;EAEhC,MAAM,8BAA8B;AACnC,OAAI,eAAe,MAAM;AACxB,WAAO,cAAc,WAAW;AAChC,iBAAa;;;EAIf,MAAM,8BAA8B;AACnC,0BAAuB;AAEvB,OAAI,CAAC,eAAe,SAAS,oBAAoB,SAChD;AAGD,gBAAa,OAAO,YACnB,kBACA,0BACA;;EAGF,MAAM,oBAAoB;AACzB,qBAAkB;AAClB,0BAAuB;;EAGxB,MAAM,+BAA+B;AACpC,OAAI,SAAS,oBAAoB,UAAU;AAC1C,2BAAuB;AACvB;;AAGD,qBAAkB;AAClB,0BAAuB;;AAGxB,SAAO,iBAAiB,SAAS,YAAY;AAC7C,WAAS,iBAAiB,oBAAoB,uBAAuB;AAErE,MAAI,eAAe,SAAS,oBAAoB,UAAU;AACzD,qBAAkB;AAClB,0BAAuB;;AAGxB,eAAa;AACZ,UAAO,oBAAoB,SAAS,YAAY;AAChD,YAAS,oBAAoB,oBAAoB,uBAAuB;AACxE,0BAAuB;;IAEtB;EAAC;EAAa;EAAS;EAAS;EAAU,CAAC;CAC9C,MAAM,QAAQ,cAAc,YAAY,CAAC,WAAW,CAAC;AACrD,QACC,oBAAC,iBAAiB;EAAgB;EAChC;GAC0B;;;;;;AAQ9B,MAAaC,qBAAuD,EACnE,UACA,WACA,WACA,WACA,OACA,cAAc,MACd,WACA,cACA,cACK;AAGL,QACC,oBAAC;EACA,MAJW,wBAAwB;GAAE;GAAW;GAAW;GAAW,CAAC;EAK1D;EACF;EACG;EACL;EACF;YAEP,oBAAC;GAAyB;GAAU;IAA2B;GAC7C;;;;;;AAQrB,MAAa,qBAA4C;CACxD,MAAM,UAAU,WAAW,iBAAiB;AAC5C,KAAI,CAAC,QACJ,OAAM,IAAI,MAAM,qDAAqD;AAEtE,QAAO;;;;;;;AAQR,MAAa,yBACZ,WAAW,iBAAiB"}
|
package/support/index.d.ts
CHANGED
|
@@ -1,74 +1,259 @@
|
|
|
1
1
|
import { SupportLocale, SupportTextContentOverrides } from "./text/locales/keys.js";
|
|
2
|
-
import { CustomPage } from "./router.js";
|
|
2
|
+
import { CustomPage, PageProps } from "./router.js";
|
|
3
|
+
import { SlotProps } from "./context/slots.js";
|
|
4
|
+
import { ConversationEndEvent, ConversationStartEvent, ErrorEvent, MessageReceivedEvent, MessageSentEvent, SupportEvent, SupportEventCallbacks, SupportEventType, useSupportEventEmitter, useSupportEvents } from "./context/events.js";
|
|
5
|
+
import { SupportHandle, useSupportHandle } from "./context/handle.js";
|
|
3
6
|
import { Text, useSupportText } from "./text/index.js";
|
|
4
|
-
import {
|
|
7
|
+
import { Align, CollisionPadding, ContentProps, RootProps, Side, TriggerRenderProps } from "./types.js";
|
|
5
8
|
import { CoButton } from "./components/button.js";
|
|
6
9
|
import { Header } from "./components/header.js";
|
|
7
10
|
import { WebSocketContextValue, WebSocketProvider, useWebSocket } from "./context/websocket.js";
|
|
8
11
|
import { useSupportConfig, useSupportNavigation, useSupportStore } from "./store/support-store.js";
|
|
9
12
|
import "./store/index.js";
|
|
10
|
-
import
|
|
11
|
-
import
|
|
13
|
+
import * as React$1 from "react";
|
|
14
|
+
import * as _cossistant_core0 from "@cossistant/core";
|
|
15
|
+
import { DefaultRoutes, NavigationState, RouteRegistry, SupportPage as SupportPageType } from "@cossistant/core";
|
|
12
16
|
import { DefaultMessage } from "@cossistant/types";
|
|
13
17
|
|
|
14
18
|
//#region src/support/index.d.ts
|
|
15
19
|
type SupportProps<Locale extends string = SupportLocale> = {
|
|
20
|
+
/**
|
|
21
|
+
* Additional CSS classes for the root wrapper.
|
|
22
|
+
*/
|
|
16
23
|
className?: string;
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
24
|
+
/**
|
|
25
|
+
* Which side of the trigger to place the content.
|
|
26
|
+
* @default "top"
|
|
27
|
+
*/
|
|
28
|
+
side?: Side;
|
|
29
|
+
/**
|
|
30
|
+
* Alignment along the side axis.
|
|
31
|
+
* @default "end"
|
|
32
|
+
*/
|
|
33
|
+
align?: Align;
|
|
34
|
+
/**
|
|
35
|
+
* Distance (in pixels) between the trigger and the content.
|
|
36
|
+
* @default 16
|
|
37
|
+
*/
|
|
38
|
+
sideOffset?: number;
|
|
39
|
+
/**
|
|
40
|
+
* Enable automatic collision avoidance.
|
|
41
|
+
* When true, the content repositions to stay within the viewport.
|
|
42
|
+
* @default true
|
|
43
|
+
*/
|
|
44
|
+
avoidCollisions?: boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Padding from viewport edges when avoiding collisions.
|
|
47
|
+
* @default 8
|
|
48
|
+
*/
|
|
49
|
+
collisionPadding?: CollisionPadding;
|
|
50
|
+
/**
|
|
51
|
+
* Granular className overrides for specific parts.
|
|
52
|
+
*/
|
|
53
|
+
classNames?: {
|
|
54
|
+
trigger?: string;
|
|
55
|
+
content?: string;
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* Force a specific theme. Omit for automatic detection.
|
|
59
|
+
*/
|
|
60
|
+
theme?: "light" | "dark";
|
|
61
|
+
/**
|
|
62
|
+
* Controlled open state.
|
|
63
|
+
* When provided, the widget operates in controlled mode.
|
|
64
|
+
* Use with `onOpenChange` to manage state externally.
|
|
65
|
+
*/
|
|
66
|
+
open?: boolean;
|
|
67
|
+
/**
|
|
68
|
+
* Callback fired when the open state should change.
|
|
69
|
+
* Use with `open` prop for controlled mode.
|
|
70
|
+
*
|
|
71
|
+
* @example
|
|
72
|
+
* const [isOpen, setIsOpen] = useState(false);
|
|
73
|
+
* <Support open={isOpen} onOpenChange={setIsOpen} />
|
|
74
|
+
*/
|
|
75
|
+
onOpenChange?: (open: boolean) => void;
|
|
76
|
+
/**
|
|
77
|
+
* Whether the widget should open automatically on mount (uncontrolled mode).
|
|
78
|
+
* Ignored when `open` prop is provided (controlled mode).
|
|
79
|
+
* @default false
|
|
80
|
+
*/
|
|
81
|
+
defaultOpen?: boolean;
|
|
82
|
+
/**
|
|
83
|
+
* Quick reply options displayed to users.
|
|
84
|
+
*/
|
|
20
85
|
quickOptions?: string[];
|
|
86
|
+
/**
|
|
87
|
+
* Custom welcome messages shown before a conversation starts.
|
|
88
|
+
*/
|
|
21
89
|
defaultMessages?: DefaultMessage[];
|
|
22
|
-
|
|
90
|
+
/**
|
|
91
|
+
* Locale string for widget translations.
|
|
92
|
+
*/
|
|
23
93
|
locale?: Locale;
|
|
94
|
+
/**
|
|
95
|
+
* Custom text content overrides for internationalization.
|
|
96
|
+
*/
|
|
24
97
|
content?: SupportTextContentOverrides<Locale>;
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
container?: React.ComponentType<ContainerSlotProps>;
|
|
29
|
-
router?: React.ComponentType<RouterSlotProps>;
|
|
30
|
-
};
|
|
31
|
-
classNames?: {
|
|
32
|
-
root?: string;
|
|
33
|
-
bubble?: string;
|
|
34
|
-
container?: string;
|
|
35
|
-
};
|
|
98
|
+
/**
|
|
99
|
+
* Custom pages to add to the router.
|
|
100
|
+
*/
|
|
36
101
|
customPages?: CustomPage[];
|
|
37
|
-
|
|
102
|
+
/**
|
|
103
|
+
* Called when a new conversation is started.
|
|
104
|
+
*/
|
|
105
|
+
onConversationStart?: (event: ConversationStartEvent) => void;
|
|
106
|
+
/**
|
|
107
|
+
* Called when a conversation ends (resolved, closed, etc.).
|
|
108
|
+
*/
|
|
109
|
+
onConversationEnd?: (event: ConversationEndEvent) => void;
|
|
110
|
+
/**
|
|
111
|
+
* Called when the visitor sends a message.
|
|
112
|
+
*/
|
|
113
|
+
onMessageSent?: (event: MessageSentEvent) => void;
|
|
114
|
+
/**
|
|
115
|
+
* Called when a message is received from an agent (human or AI).
|
|
116
|
+
*/
|
|
117
|
+
onMessageReceived?: (event: MessageReceivedEvent) => void;
|
|
118
|
+
/**
|
|
119
|
+
* Called when an error occurs within the widget.
|
|
120
|
+
*/
|
|
121
|
+
onError?: (event: ErrorEvent) => void;
|
|
122
|
+
/**
|
|
123
|
+
* Children for composition. Can include:
|
|
124
|
+
* - <Support.Trigger> for custom trigger
|
|
125
|
+
* - <Support.Content> for custom content positioning
|
|
126
|
+
* - <Support.Page> components for custom routes
|
|
127
|
+
*/
|
|
128
|
+
children?: React$1.ReactNode;
|
|
129
|
+
};
|
|
130
|
+
type SupportTriggerProps = Omit<React$1.ButtonHTMLAttributes<HTMLButtonElement>, "children"> & {
|
|
131
|
+
/**
|
|
132
|
+
* Content to render inside the trigger.
|
|
133
|
+
* Can be static content or a function receiving render props.
|
|
134
|
+
*/
|
|
135
|
+
children?: React$1.ReactNode | ((props: TriggerRenderProps) => React$1.ReactNode);
|
|
136
|
+
/**
|
|
137
|
+
* When true, renders children directly with all props passed through.
|
|
138
|
+
*/
|
|
139
|
+
asChild?: boolean;
|
|
140
|
+
className?: string;
|
|
141
|
+
};
|
|
142
|
+
type SupportContentProps = {
|
|
143
|
+
className?: string;
|
|
144
|
+
/**
|
|
145
|
+
* Which side of the trigger to place the content.
|
|
146
|
+
* @default "top"
|
|
147
|
+
*/
|
|
148
|
+
side?: Side;
|
|
149
|
+
/**
|
|
150
|
+
* Alignment along the side axis.
|
|
151
|
+
* @default "end"
|
|
152
|
+
*/
|
|
153
|
+
align?: Align;
|
|
154
|
+
/**
|
|
155
|
+
* Distance (in pixels) between the trigger and the content.
|
|
156
|
+
* @default 16
|
|
157
|
+
*/
|
|
158
|
+
sideOffset?: number;
|
|
159
|
+
/**
|
|
160
|
+
* Enable automatic collision avoidance.
|
|
161
|
+
* When true, the content repositions to stay within the viewport.
|
|
162
|
+
* @default true
|
|
163
|
+
*/
|
|
164
|
+
avoidCollisions?: boolean;
|
|
165
|
+
/**
|
|
166
|
+
* Padding from viewport edges when avoiding collisions.
|
|
167
|
+
* @default 8
|
|
168
|
+
*/
|
|
169
|
+
collisionPadding?: CollisionPadding;
|
|
170
|
+
children?: React$1.ReactNode;
|
|
171
|
+
};
|
|
172
|
+
type SupportRouterProps = {
|
|
173
|
+
/**
|
|
174
|
+
* Custom pages to add alongside built-in pages.
|
|
175
|
+
*/
|
|
176
|
+
customPages?: CustomPage[];
|
|
177
|
+
/**
|
|
178
|
+
* Page components to register.
|
|
179
|
+
*/
|
|
180
|
+
children?: React$1.ReactNode;
|
|
181
|
+
};
|
|
182
|
+
type SupportPageProps<K extends keyof _cossistant_core0.RouteRegistry = keyof _cossistant_core0.RouteRegistry> = {
|
|
183
|
+
name: K;
|
|
184
|
+
component: React$1.ComponentType<{
|
|
185
|
+
params?: _cossistant_core0.RouteRegistry[K];
|
|
186
|
+
}>;
|
|
187
|
+
};
|
|
188
|
+
type SupportRootProps = {
|
|
189
|
+
/**
|
|
190
|
+
* Controlled open state.
|
|
191
|
+
* When provided, the widget operates in controlled mode.
|
|
192
|
+
*/
|
|
193
|
+
open?: boolean;
|
|
194
|
+
/**
|
|
195
|
+
* Callback fired when the open state should change.
|
|
196
|
+
* Use with `open` prop for controlled mode.
|
|
197
|
+
*/
|
|
198
|
+
onOpenChange?: (open: boolean) => void;
|
|
199
|
+
/**
|
|
200
|
+
* Whether the widget should open automatically (uncontrolled mode).
|
|
201
|
+
* Ignored when `open` prop is provided.
|
|
202
|
+
* @default false
|
|
203
|
+
*/
|
|
204
|
+
defaultOpen?: boolean;
|
|
205
|
+
/**
|
|
206
|
+
* Force a specific theme.
|
|
207
|
+
*/
|
|
208
|
+
theme?: "light" | "dark";
|
|
209
|
+
/**
|
|
210
|
+
* Additional CSS classes.
|
|
211
|
+
*/
|
|
212
|
+
className?: string;
|
|
213
|
+
/**
|
|
214
|
+
* Called when a new conversation is started.
|
|
215
|
+
*/
|
|
216
|
+
onConversationStart?: (event: ConversationStartEvent) => void;
|
|
217
|
+
/**
|
|
218
|
+
* Called when a conversation ends.
|
|
219
|
+
*/
|
|
220
|
+
onConversationEnd?: (event: ConversationEndEvent) => void;
|
|
221
|
+
/**
|
|
222
|
+
* Called when the visitor sends a message.
|
|
223
|
+
*/
|
|
224
|
+
onMessageSent?: (event: MessageSentEvent) => void;
|
|
225
|
+
/**
|
|
226
|
+
* Called when a message is received from an agent.
|
|
227
|
+
*/
|
|
228
|
+
onMessageReceived?: (event: MessageReceivedEvent) => void;
|
|
229
|
+
/**
|
|
230
|
+
* Called when an error occurs.
|
|
231
|
+
*/
|
|
232
|
+
onError?: (event: ErrorEvent) => void;
|
|
233
|
+
children: React$1.ReactNode;
|
|
234
|
+
};
|
|
235
|
+
declare const Support: (<Locale extends string = SupportLocale>(props: SupportProps<Locale> & {
|
|
236
|
+
ref?: React$1.Ref<SupportHandle>;
|
|
237
|
+
}) => React$1.ReactElement | null) & {
|
|
238
|
+
Root: React$1.ForwardRefExoticComponent<SupportRootProps & React$1.RefAttributes<SupportHandle>>;
|
|
239
|
+
Trigger: React$1.ForwardRefExoticComponent<Omit<React$1.ButtonHTMLAttributes<HTMLButtonElement>, "children"> & {
|
|
240
|
+
/**
|
|
241
|
+
* Content to render inside the trigger.
|
|
242
|
+
* Can be static content or a function receiving render props.
|
|
243
|
+
*/
|
|
244
|
+
children?: React$1.ReactNode | ((props: TriggerRenderProps) => React$1.ReactNode);
|
|
245
|
+
/**
|
|
246
|
+
* When true, renders children directly with all props passed through.
|
|
247
|
+
*/
|
|
248
|
+
asChild?: boolean;
|
|
249
|
+
className?: string;
|
|
250
|
+
} & React$1.RefAttributes<HTMLButtonElement>>;
|
|
251
|
+
Content: React$1.FC<SupportContentProps>;
|
|
252
|
+
Router: React$1.FC<SupportRouterProps>;
|
|
253
|
+
Page: <K extends keyof _cossistant_core0.RouteRegistry>(_props: PageProps<K>) => null;
|
|
254
|
+
Header: React$1.FC<SlotProps>;
|
|
255
|
+
Footer: React$1.FC<SlotProps>;
|
|
38
256
|
};
|
|
39
|
-
/**
|
|
40
|
-
* Complete support widget with chat, routing, and real-time features.
|
|
41
|
-
*
|
|
42
|
-
* @example
|
|
43
|
-
* // Zero config
|
|
44
|
-
* <Support />
|
|
45
|
-
*
|
|
46
|
-
* @example
|
|
47
|
-
* // With customization and custom pages
|
|
48
|
-
* <Support
|
|
49
|
-
* theme="dark"
|
|
50
|
-
* classNames={{ bubble: "bg-purple-600" }}
|
|
51
|
-
* customPages={[
|
|
52
|
-
* { name: "FAQ", component: FAQPage }
|
|
53
|
-
* ]}
|
|
54
|
-
* />
|
|
55
|
-
*/
|
|
56
|
-
declare function Support<Locale extends string = SupportLocale>({
|
|
57
|
-
className,
|
|
58
|
-
position,
|
|
59
|
-
align,
|
|
60
|
-
positioning,
|
|
61
|
-
quickOptions,
|
|
62
|
-
defaultMessages,
|
|
63
|
-
defaultOpen,
|
|
64
|
-
locale,
|
|
65
|
-
content,
|
|
66
|
-
theme,
|
|
67
|
-
slots,
|
|
68
|
-
classNames,
|
|
69
|
-
customPages,
|
|
70
|
-
children
|
|
71
|
-
}: SupportProps<Locale>): ReactElement | null;
|
|
72
257
|
//#endregion
|
|
73
|
-
export { type
|
|
258
|
+
export { type Align, CoButton as Button, type CollisionPadding, type ContentProps, type ConversationEndEvent, type ConversationStartEvent, type CustomPage, type DefaultRoutes, type ErrorEvent, Header, type MessageReceivedEvent, type MessageSentEvent, type NavigationState, type RootProps, type RouteRegistry, type Side, Support, Support as default, SupportContentProps, type SupportEvent, type SupportEventCallbacks, type SupportEventType, type SupportHandle, type SupportLocale, SupportPageProps, type SupportPageType, SupportProps, SupportRootProps, SupportRouterProps, type SupportTextContentOverrides, SupportTriggerProps, Text, type TriggerRenderProps, type WebSocketContextValue, WebSocketProvider, useSupportConfig, useSupportEventEmitter, useSupportEvents, useSupportHandle, useSupportNavigation, useSupportStore, useSupportText, useWebSocket };
|
|
74
259
|
//# sourceMappingURL=index.d.ts.map
|
package/support/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/support/index.tsx"],"sourcesContent":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/support/index.tsx"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;;;;;;KAsCY,qCAAqC;;;;;;;;;SAUzC;EAVI;;;;EAmCQ,KAAA,CAAA,EAnBX,KAmBW;EA+CD;;;;EAeJ,UAAA,CAAA,EAAA,MAAA;EASgB;;;;;EA4BnB,eAAM,CAAA,EAAA,OAAA;EAAS;AA6M3B;;;EAAkC,gBAAA,CAAA,EAhTd,gBAgTc;EAQtB;;;EAAiE,UAAA,CAAA,EAAA;IAsCjE,OAAA,CAAA,EAAA,MAAA;IAMJ,OAAA,CAAA,EAAA,MAAA;EAKC,CAAA;EAgBW;;;EA4CR,KAAA,CAAA,EAAA,OAAA,GAAA,MAAkB;EAsClB;;;;;EAMwC,IAAA,CAAA,EAAA,OAAA;EADxC;;AAuBZ;;;;;;EA6CW,YAAM,CAAA,EAAA,CAAA,IAAA,EAAA,OAAA,EAAA,GAAA,IAAA;EAAS;AA2F1B;;;;EAtUiD,WAAA,CAAA,EAAA,OAAA;EAAV;;;;;;;oBA1PpB;;;;EAyQ2C,MAAM,CAAA,EApQ1D,MAoQ0D;;;;YA/PzD,4BAA4B;;;;gBAKxB;;;;gCASgB;;;;8BAKF;;;;0BAKJ;;;;8BAKI;;;;oBAKV;;;;;;;aAQP,OAAA,CAAM;;KA6MN,mBAAA,GAAsB,KACjC,OAAA,CAAM,qBAAqB;;;;;aAOhB,OAAA,CAAM,qBAAqB,uBAAuB,OAAA,CAAM;;;;;;;KAsCxD,mBAAA;;;;;;SAMJ;;;;;UAKC;;;;;;;;;;;;;;;;qBAgBW;aACR,OAAA,CAAM;;KA2CN,kBAAA;;;;gBAIG;;;;aAIH,OAAA,CAAM;;KA8BN,iCAAgB,iBAAA,CAEO,sBAAa,iBAAA,CAAoC;QAE7E;aACK,OAAA,CAAM;aADV,iBAAA,CAE8B,aAAA,CAAc;;;KAsBxC,gBAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;gCA4BmB;;;;8BAIF;;;;0BAIJ;;;;8BAII;;;;oBAIV;YACR,OAAA,CAAM;;cA2FJ,mCAxUS,sBAEd,aAAa;QAAkB,OAAA,CAAM,IAAI;MAC5C,OAAA,CAAM;;;;;;;eAcC,OAAA,CAAM,qBAAqB,uBAAuB,OAAA,CAAM"}
|
package/support/index.js
CHANGED
|
@@ -1,65 +1,286 @@
|
|
|
1
1
|
import "./support.js";
|
|
2
|
-
import { SupportRealtimeProvider } from "../realtime/support-provider.js";
|
|
3
2
|
import { SupportConfig } from "../support-config.js";
|
|
3
|
+
import { SupportTrigger as SupportTrigger$1 } from "../primitives/trigger.js";
|
|
4
|
+
import { ControlledStateProvider } from "./context/controlled-state.js";
|
|
4
5
|
import { initializeSupportStore, useSupportConfig, useSupportNavigation, useSupportStore } from "./store/support-store.js";
|
|
6
|
+
import { SupportRealtimeProvider } from "../realtime/support-provider.js";
|
|
7
|
+
import { FooterSlot, HeaderSlot } from "./context/slots.js";
|
|
8
|
+
import { Content } from "./components/content.js";
|
|
9
|
+
import { Root } from "./components/root.js";
|
|
10
|
+
import { ThemeWrapper } from "./components/theme-wrapper.js";
|
|
11
|
+
import { DefaultTrigger } from "./components/trigger.js";
|
|
12
|
+
import { SupportEventsProvider, useSupportEventEmitter, useSupportEvents } from "./context/events.js";
|
|
13
|
+
import { SupportHandleProvider, useSupportHandle } from "./context/handle.js";
|
|
5
14
|
import { CoButton } from "./components/button.js";
|
|
6
15
|
import { Header } from "./components/header.js";
|
|
7
16
|
import { SupportTextProvider, Text, useSupportText } from "./text/index.js";
|
|
8
|
-
import { SupportContent } from "./components/support-content.js";
|
|
9
|
-
import { ThemeWrapper } from "./components/theme-wrapper.js";
|
|
10
17
|
import { WebSocketProvider, useWebSocket } from "./context/websocket.js";
|
|
18
|
+
import { Page, Router } from "./router.js";
|
|
11
19
|
import { useSupport } from "../provider.js";
|
|
12
|
-
import React from "react";
|
|
20
|
+
import * as React$1 from "react";
|
|
13
21
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
14
22
|
|
|
15
23
|
//#region src/support/index.tsx
|
|
24
|
+
function parseChildren(children) {
|
|
25
|
+
const result = {
|
|
26
|
+
trigger: null,
|
|
27
|
+
content: null,
|
|
28
|
+
pages: [],
|
|
29
|
+
other: []
|
|
30
|
+
};
|
|
31
|
+
React$1.Children.forEach(children, (child) => {
|
|
32
|
+
if (!React$1.isValidElement(child)) {
|
|
33
|
+
result.other.push(child);
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
const displayName = child.type?.displayName ?? "";
|
|
37
|
+
if (displayName === "Support.Trigger" || child.type === SupportTrigger) result.trigger = child;
|
|
38
|
+
else if (displayName === "Support.Content" || child.type === SupportContent) result.content = child;
|
|
39
|
+
else if (displayName === "Support.Page" || child.type === Page) result.pages.push(child);
|
|
40
|
+
else result.other.push(child);
|
|
41
|
+
});
|
|
42
|
+
return result;
|
|
43
|
+
}
|
|
16
44
|
/**
|
|
17
45
|
* Complete support widget with chat, routing, and real-time features.
|
|
18
46
|
*
|
|
19
47
|
* @example
|
|
20
|
-
* // Zero config
|
|
48
|
+
* // Zero config - works instantly
|
|
21
49
|
* <Support />
|
|
22
50
|
*
|
|
23
51
|
* @example
|
|
24
|
-
* // With
|
|
52
|
+
* // With styling
|
|
25
53
|
* <Support
|
|
26
54
|
* theme="dark"
|
|
27
|
-
* classNames={{
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
55
|
+
* classNames={{
|
|
56
|
+
* trigger: "bg-purple-600",
|
|
57
|
+
* content: "border-purple-200",
|
|
58
|
+
* }}
|
|
31
59
|
* />
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* // With custom positioning
|
|
63
|
+
* <Support side="bottom" align="end" sideOffset={8} />
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* // Controlled mode - external state management
|
|
67
|
+
* const [isOpen, setIsOpen] = useState(false);
|
|
68
|
+
* <Support open={isOpen} onOpenChange={setIsOpen} />
|
|
69
|
+
*
|
|
70
|
+
* @example
|
|
71
|
+
* // With imperative ref
|
|
72
|
+
* const supportRef = useRef<SupportHandle>(null);
|
|
73
|
+
* supportRef.current?.open();
|
|
74
|
+
* supportRef.current?.startConversation("Hello!");
|
|
75
|
+
* <Support ref={supportRef} />
|
|
76
|
+
*
|
|
77
|
+
* @example
|
|
78
|
+
* // With custom trigger
|
|
79
|
+
* <Support side="bottom" align="end">
|
|
80
|
+
* <Support.Trigger className="px-4 py-2">
|
|
81
|
+
* {({ isOpen, unreadCount }) => (
|
|
82
|
+
* <span>{isOpen ? "Close" : `Help (${unreadCount})`}</span>
|
|
83
|
+
* )}
|
|
84
|
+
* </Support.Trigger>
|
|
85
|
+
* </Support>
|
|
86
|
+
*
|
|
87
|
+
* @example
|
|
88
|
+
* // With custom pages
|
|
89
|
+
* <Support>
|
|
90
|
+
* <Support.Page name="FAQ" component={FAQPage} />
|
|
91
|
+
* </Support>
|
|
32
92
|
*/
|
|
33
|
-
function
|
|
93
|
+
function SupportComponentInner({ className, side = "top", align = "end", sideOffset = 16, avoidCollisions = true, collisionPadding = 8, classNames = {}, theme, open, onOpenChange, defaultOpen, quickOptions, defaultMessages, locale, content, customPages, onConversationStart, onConversationEnd, onMessageSent, onMessageReceived, onError, children }, ref) {
|
|
34
94
|
const { website } = useSupport();
|
|
35
95
|
const isVisitorBlocked = website?.visitor?.isBlocked ?? false;
|
|
36
|
-
React.useEffect(() => {
|
|
37
|
-
if (defaultOpen !== void 0) initializeSupportStore({ defaultOpen });
|
|
38
|
-
}, [defaultOpen]);
|
|
96
|
+
React$1.useEffect(() => {
|
|
97
|
+
if (open === void 0 && defaultOpen !== void 0) initializeSupportStore({ defaultOpen });
|
|
98
|
+
}, [open, defaultOpen]);
|
|
39
99
|
if (!website || isVisitorBlocked) return null;
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
100
|
+
const parsed = parseChildren(children);
|
|
101
|
+
return /* @__PURE__ */ jsx(ControlledStateProvider, {
|
|
102
|
+
onOpenChange,
|
|
103
|
+
open,
|
|
104
|
+
children: /* @__PURE__ */ jsx(SupportEventsProvider, {
|
|
105
|
+
onConversationEnd,
|
|
106
|
+
onConversationStart,
|
|
107
|
+
onError,
|
|
108
|
+
onMessageReceived,
|
|
109
|
+
onMessageSent,
|
|
110
|
+
children: /* @__PURE__ */ jsx(SupportHandleProvider, {
|
|
111
|
+
forwardedRef: ref,
|
|
112
|
+
children: /* @__PURE__ */ jsxs(ThemeWrapper, {
|
|
113
|
+
theme,
|
|
114
|
+
children: [/* @__PURE__ */ jsx(SupportRealtimeProvider, { children: /* @__PURE__ */ jsx(SupportTextProvider, {
|
|
115
|
+
content,
|
|
116
|
+
locale,
|
|
117
|
+
children: /* @__PURE__ */ jsxs(Root, {
|
|
118
|
+
className,
|
|
119
|
+
children: [parsed.trigger ?? /* @__PURE__ */ jsx(DefaultTrigger, { className: classNames.trigger }), parsed.content ?? /* @__PURE__ */ jsx(Content, {
|
|
120
|
+
align,
|
|
121
|
+
avoidCollisions,
|
|
122
|
+
className: classNames.content,
|
|
123
|
+
collisionPadding,
|
|
124
|
+
side,
|
|
125
|
+
sideOffset,
|
|
126
|
+
children: /* @__PURE__ */ jsx(Router, {
|
|
127
|
+
customPages,
|
|
128
|
+
children: parsed.pages
|
|
129
|
+
})
|
|
130
|
+
})]
|
|
131
|
+
})
|
|
132
|
+
}) }), /* @__PURE__ */ jsx(SupportConfig, {
|
|
133
|
+
defaultMessages,
|
|
134
|
+
quickOptions
|
|
135
|
+
})]
|
|
136
|
+
})
|
|
54
137
|
})
|
|
55
|
-
})
|
|
56
|
-
defaultMessages,
|
|
57
|
-
quickOptions
|
|
58
|
-
})]
|
|
138
|
+
})
|
|
59
139
|
});
|
|
60
140
|
}
|
|
141
|
+
const SupportComponent = React$1.forwardRef(SupportComponentInner);
|
|
142
|
+
/**
|
|
143
|
+
* Custom trigger component for the support widget.
|
|
144
|
+
* Use this inside <Support> to replace the default floating button.
|
|
145
|
+
*
|
|
146
|
+
* @example
|
|
147
|
+
* <Support.Trigger className="my-button">
|
|
148
|
+
* {({ isOpen, unreadCount }) => (
|
|
149
|
+
* <span>{isOpen ? "Close" : `Help (${unreadCount})`}</span>
|
|
150
|
+
* )}
|
|
151
|
+
* </Support.Trigger>
|
|
152
|
+
*/
|
|
153
|
+
const SupportTrigger = React$1.forwardRef(({ children, className, asChild = false,...props }, ref) => /* @__PURE__ */ jsx(SupportTrigger$1, {
|
|
154
|
+
asChild,
|
|
155
|
+
className,
|
|
156
|
+
ref,
|
|
157
|
+
...props,
|
|
158
|
+
children
|
|
159
|
+
}));
|
|
160
|
+
SupportTrigger.displayName = "Support.Trigger";
|
|
161
|
+
/**
|
|
162
|
+
* Custom content wrapper for the support widget.
|
|
163
|
+
* Use this inside <Support> for custom positioning or styling.
|
|
164
|
+
*
|
|
165
|
+
* @example
|
|
166
|
+
* <Support>
|
|
167
|
+
* <Support.Trigger>Help</Support.Trigger>
|
|
168
|
+
* <Support.Content side="bottom" align="end" className="my-content">
|
|
169
|
+
* <Support.Router />
|
|
170
|
+
* </Support.Content>
|
|
171
|
+
* </Support>
|
|
172
|
+
*/
|
|
173
|
+
const SupportContent = ({ className, side = "top", align = "end", sideOffset = 16, avoidCollisions = true, collisionPadding = 8, children }) => /* @__PURE__ */ jsx(Content, {
|
|
174
|
+
align,
|
|
175
|
+
avoidCollisions,
|
|
176
|
+
className,
|
|
177
|
+
collisionPadding,
|
|
178
|
+
side,
|
|
179
|
+
sideOffset,
|
|
180
|
+
children: children ?? /* @__PURE__ */ jsx(Router, {})
|
|
181
|
+
});
|
|
182
|
+
SupportContent.displayName = "Support.Content";
|
|
183
|
+
/**
|
|
184
|
+
* Router with all default pages (Home, Conversation, etc.).
|
|
185
|
+
* Use inside <Support.Content> for full control.
|
|
186
|
+
*
|
|
187
|
+
* @example
|
|
188
|
+
* <Support.Content>
|
|
189
|
+
* <Support.Router />
|
|
190
|
+
* </Support.Content>
|
|
191
|
+
*
|
|
192
|
+
* @example
|
|
193
|
+
* // With custom pages
|
|
194
|
+
* <Support.Router>
|
|
195
|
+
* <Support.Page name="FAQ" component={FAQPage} />
|
|
196
|
+
* </Support.Router>
|
|
197
|
+
*/
|
|
198
|
+
const SupportRouter = ({ customPages, children }) => /* @__PURE__ */ jsx(Router, {
|
|
199
|
+
customPages,
|
|
200
|
+
children
|
|
201
|
+
});
|
|
202
|
+
SupportRouter.displayName = "Support.Router";
|
|
203
|
+
/**
|
|
204
|
+
* Declarative page registration for custom routes.
|
|
205
|
+
*
|
|
206
|
+
* @example
|
|
207
|
+
* <Support>
|
|
208
|
+
* <Support.Page name="FAQ" component={FAQPage} />
|
|
209
|
+
* <Support.Page name="SETTINGS" component={SettingsPage} />
|
|
210
|
+
* </Support>
|
|
211
|
+
*/
|
|
212
|
+
const SupportPage = Page;
|
|
213
|
+
SupportPage.displayName = "Support.Page";
|
|
214
|
+
/**
|
|
215
|
+
* Root component for full composition mode.
|
|
216
|
+
* Use when you need complete control over the widget structure.
|
|
217
|
+
*
|
|
218
|
+
* @example
|
|
219
|
+
* // Uncontrolled
|
|
220
|
+
* <Support.Root defaultOpen={false}>
|
|
221
|
+
* <Support.Trigger asChild>
|
|
222
|
+
* <button>Help</button>
|
|
223
|
+
* </Support.Trigger>
|
|
224
|
+
* <Support.Content side="bottom" align="end">
|
|
225
|
+
* <Support.Router />
|
|
226
|
+
* </Support.Content>
|
|
227
|
+
* </Support.Root>
|
|
228
|
+
*
|
|
229
|
+
* @example
|
|
230
|
+
* // Controlled
|
|
231
|
+
* const [isOpen, setIsOpen] = useState(false);
|
|
232
|
+
* <Support.Root open={isOpen} onOpenChange={setIsOpen}>
|
|
233
|
+
* ...
|
|
234
|
+
* </Support.Root>
|
|
235
|
+
*
|
|
236
|
+
* @example
|
|
237
|
+
* // With imperative ref
|
|
238
|
+
* const supportRef = useRef<SupportHandle>(null);
|
|
239
|
+
* <Support.Root ref={supportRef}>
|
|
240
|
+
* ...
|
|
241
|
+
* </Support.Root>
|
|
242
|
+
*/
|
|
243
|
+
const SupportRoot = React$1.forwardRef(({ open, onOpenChange, defaultOpen, theme, className, onConversationStart, onConversationEnd, onMessageSent, onMessageReceived, onError, children }, ref) => {
|
|
244
|
+
const { website } = useSupport();
|
|
245
|
+
const isVisitorBlocked = website?.visitor?.isBlocked ?? false;
|
|
246
|
+
React$1.useEffect(() => {
|
|
247
|
+
if (open === void 0 && defaultOpen !== void 0) initializeSupportStore({ defaultOpen });
|
|
248
|
+
}, [open, defaultOpen]);
|
|
249
|
+
if (!website || isVisitorBlocked) return null;
|
|
250
|
+
return /* @__PURE__ */ jsx(ControlledStateProvider, {
|
|
251
|
+
onOpenChange,
|
|
252
|
+
open,
|
|
253
|
+
children: /* @__PURE__ */ jsx(SupportEventsProvider, {
|
|
254
|
+
onConversationEnd,
|
|
255
|
+
onConversationStart,
|
|
256
|
+
onError,
|
|
257
|
+
onMessageReceived,
|
|
258
|
+
onMessageSent,
|
|
259
|
+
children: /* @__PURE__ */ jsx(SupportHandleProvider, {
|
|
260
|
+
forwardedRef: ref,
|
|
261
|
+
children: /* @__PURE__ */ jsx(ThemeWrapper, {
|
|
262
|
+
theme,
|
|
263
|
+
children: /* @__PURE__ */ jsx(SupportRealtimeProvider, { children: /* @__PURE__ */ jsx(Root, {
|
|
264
|
+
className,
|
|
265
|
+
children
|
|
266
|
+
}) })
|
|
267
|
+
})
|
|
268
|
+
})
|
|
269
|
+
})
|
|
270
|
+
});
|
|
271
|
+
});
|
|
272
|
+
SupportRoot.displayName = "Support.Root";
|
|
273
|
+
const Support = Object.assign(SupportComponent, {
|
|
274
|
+
Root: SupportRoot,
|
|
275
|
+
Trigger: SupportTrigger,
|
|
276
|
+
Content: SupportContent,
|
|
277
|
+
Router: SupportRouter,
|
|
278
|
+
Page: SupportPage,
|
|
279
|
+
Header: HeaderSlot,
|
|
280
|
+
Footer: FooterSlot
|
|
281
|
+
});
|
|
61
282
|
var support_default = Support;
|
|
62
283
|
|
|
63
284
|
//#endregion
|
|
64
|
-
export { CoButton as Button, Header, Support, Text, WebSocketProvider, support_default as default, useSupportConfig, useSupportNavigation, useSupportStore, useSupportText, useWebSocket };
|
|
285
|
+
export { CoButton as Button, Header, Support, Text, WebSocketProvider, support_default as default, useSupportConfig, useSupportEventEmitter, useSupportEvents, useSupportHandle, useSupportNavigation, useSupportStore, useSupportText, useWebSocket };
|
|
65
286
|
//# sourceMappingURL=index.js.map
|