@kite-copilot/chat-panel 0.2.50 → 0.2.52

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/dist/index.cjs CHANGED
@@ -408,9 +408,9 @@ function useUserAuth({
408
408
  } catch (error) {
409
409
  if (error instanceof Error) {
410
410
  const errorMessage = error.message.toLowerCase();
411
- const isCorsError = errorMessage.includes("cors") || errorMessage.includes("network");
411
+ const isNetworkError = error instanceof TypeError || errorMessage.includes("failed to fetch") || errorMessage.includes("network");
412
412
  const is404Error = errorMessage.includes("404");
413
- if (isCorsError || is404Error) {
413
+ if (isNetworkError || is404Error) {
414
414
  console.warn("[useUserAuth] Auth endpoint unavailable, falling back to unauthenticated mode:", error.message);
415
415
  setAuthState({ status: "idle" });
416
416
  return;
@@ -1633,6 +1633,8 @@ function ChatPanel({
1633
1633
  const [sessionUser, setSessionUser] = React6.useState(null);
1634
1634
  const orgConfigState = useOrgConfig({ agentUrl, orgId: orgId || "" });
1635
1635
  const effectiveProductBackendUrl = orgConfigState.config?.productBackendUrl || productBackendUrl;
1636
+ const effectiveSupabaseUrl = orgConfigState.config?.supabaseUrl || supabaseUrl;
1637
+ const effectiveSupabaseAnonKey = orgConfigState.config?.supabaseAnonKey || supabaseAnonKey;
1636
1638
  const { authState, retry: retryAuth } = useUserAuth({
1637
1639
  productBackendUrl: effectiveProductBackendUrl,
1638
1640
  sessionId,
@@ -1713,10 +1715,10 @@ function ChatPanel({
1713
1715
  }
1714
1716
  }, [isEscalated, sessionId]);
1715
1717
  React6.useEffect(() => {
1716
- if (supabaseUrl && supabaseAnonKey && !supabaseRef.current) {
1717
- supabaseRef.current = (0, import_supabase_js.createClient)(supabaseUrl, supabaseAnonKey);
1718
+ if (effectiveSupabaseUrl && effectiveSupabaseAnonKey && !supabaseRef.current) {
1719
+ supabaseRef.current = (0, import_supabase_js.createClient)(effectiveSupabaseUrl, effectiveSupabaseAnonKey);
1718
1720
  }
1719
- }, [supabaseUrl, supabaseAnonKey]);
1721
+ }, [effectiveSupabaseUrl, effectiveSupabaseAnonKey]);
1720
1722
  React6.useEffect(() => {
1721
1723
  if (!isEscalated || !sessionId || !supabaseRef.current) {
1722
1724
  return;
@@ -1784,6 +1786,8 @@ function ChatPanel({
1784
1786
  }
1785
1787
  const currentSessionId = sessionId;
1786
1788
  const supabase = supabaseRef.current;
1789
+ const sbUrl = effectiveSupabaseUrl;
1790
+ const sbKey = effectiveSupabaseAnonKey;
1787
1791
  const markActive = () => {
1788
1792
  supabase.from("escalations").update({
1789
1793
  customer_status: "active",
@@ -1794,24 +1798,35 @@ function ChatPanel({
1794
1798
  (err) => console.error("[KiteChat] Failed to update customer status:", err)
1795
1799
  );
1796
1800
  };
1801
+ const markDisconnectedWithKeepalive = () => {
1802
+ if (!sbUrl || !sbKey) return;
1803
+ const url = `${sbUrl}/rest/v1/escalations?session_id=eq.${currentSessionId}`;
1804
+ fetch(url, {
1805
+ method: "PATCH",
1806
+ headers: {
1807
+ "Content-Type": "application/json",
1808
+ "apikey": sbKey,
1809
+ "Authorization": `Bearer ${sbKey}`,
1810
+ "Prefer": "return=minimal"
1811
+ },
1812
+ body: JSON.stringify({
1813
+ customer_status: "disconnected",
1814
+ customer_last_seen: (/* @__PURE__ */ new Date()).toISOString()
1815
+ }),
1816
+ keepalive: true
1817
+ }).catch(() => {
1818
+ });
1819
+ };
1797
1820
  console.log("[KiteChat] Starting presence heartbeat for live chat");
1798
1821
  markActive();
1799
1822
  heartbeatIntervalRef.current = window.setInterval(() => {
1800
1823
  markActive();
1801
1824
  }, 6e4);
1802
1825
  const handleBeforeUnload = () => {
1803
- supabase.from("escalations").update({
1804
- customer_status: "disconnected",
1805
- customer_last_seen: (/* @__PURE__ */ new Date()).toISOString()
1806
- }).eq("session_id", currentSessionId);
1826
+ markDisconnectedWithKeepalive();
1807
1827
  };
1808
1828
  const handleVisibilityChange = () => {
1809
- if (document.visibilityState === "hidden") {
1810
- supabase.from("escalations").update({
1811
- customer_status: "disconnected",
1812
- customer_last_seen: (/* @__PURE__ */ new Date()).toISOString()
1813
- }).eq("session_id", currentSessionId);
1814
- } else if (document.visibilityState === "visible") {
1829
+ if (document.visibilityState === "visible") {
1815
1830
  markActive();
1816
1831
  }
1817
1832
  };
@@ -1835,7 +1850,7 @@ function ChatPanel({
1835
1850
  heartbeatIntervalRef.current = null;
1836
1851
  }
1837
1852
  };
1838
- }, [isEscalated, sessionId]);
1853
+ }, [isEscalated, sessionId, effectiveSupabaseUrl, effectiveSupabaseAnonKey]);
1839
1854
  const sendTypingIndicator = React6.useCallback((isTyping) => {
1840
1855
  if (!typingChannelRef.current || !isEscalated) {
1841
1856
  if (isTyping) {
package/dist/index.js CHANGED
@@ -31,7 +31,7 @@ import {
31
31
  cn,
32
32
  createKiteChat,
33
33
  useGuideCursor
34
- } from "./chunk-BLSVIF7H.js";
34
+ } from "./chunk-KIOKMXFF.js";
35
35
  export {
36
36
  ApiKeyList,
37
37
  AssistantActivity,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kite-copilot/chat-panel",
3
- "version": "0.2.50",
3
+ "version": "0.2.52",
4
4
  "description": "AI-powered chat panel SDK with programmatic lifecycle control",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",