@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/auto.cjs CHANGED
@@ -377,9 +377,9 @@ function useUserAuth({
377
377
  } catch (error) {
378
378
  if (error instanceof Error) {
379
379
  const errorMessage = error.message.toLowerCase();
380
- const isCorsError = errorMessage.includes("cors") || errorMessage.includes("network");
380
+ const isNetworkError = error instanceof TypeError || errorMessage.includes("failed to fetch") || errorMessage.includes("network");
381
381
  const is404Error = errorMessage.includes("404");
382
- if (isCorsError || is404Error) {
382
+ if (isNetworkError || is404Error) {
383
383
  console.warn("[useUserAuth] Auth endpoint unavailable, falling back to unauthenticated mode:", error.message);
384
384
  setAuthState({ status: "idle" });
385
385
  return;
@@ -1579,6 +1579,8 @@ function ChatPanel({
1579
1579
  const [sessionUser, setSessionUser] = React6.useState(null);
1580
1580
  const orgConfigState = useOrgConfig({ agentUrl, orgId: orgId || "" });
1581
1581
  const effectiveProductBackendUrl = orgConfigState.config?.productBackendUrl || productBackendUrl;
1582
+ const effectiveSupabaseUrl = orgConfigState.config?.supabaseUrl || supabaseUrl;
1583
+ const effectiveSupabaseAnonKey = orgConfigState.config?.supabaseAnonKey || supabaseAnonKey;
1582
1584
  const { authState, retry: retryAuth } = useUserAuth({
1583
1585
  productBackendUrl: effectiveProductBackendUrl,
1584
1586
  sessionId,
@@ -1659,10 +1661,10 @@ function ChatPanel({
1659
1661
  }
1660
1662
  }, [isEscalated, sessionId]);
1661
1663
  React6.useEffect(() => {
1662
- if (supabaseUrl && supabaseAnonKey && !supabaseRef.current) {
1663
- supabaseRef.current = (0, import_supabase_js.createClient)(supabaseUrl, supabaseAnonKey);
1664
+ if (effectiveSupabaseUrl && effectiveSupabaseAnonKey && !supabaseRef.current) {
1665
+ supabaseRef.current = (0, import_supabase_js.createClient)(effectiveSupabaseUrl, effectiveSupabaseAnonKey);
1664
1666
  }
1665
- }, [supabaseUrl, supabaseAnonKey]);
1667
+ }, [effectiveSupabaseUrl, effectiveSupabaseAnonKey]);
1666
1668
  React6.useEffect(() => {
1667
1669
  if (!isEscalated || !sessionId || !supabaseRef.current) {
1668
1670
  return;
@@ -1730,6 +1732,8 @@ function ChatPanel({
1730
1732
  }
1731
1733
  const currentSessionId = sessionId;
1732
1734
  const supabase = supabaseRef.current;
1735
+ const sbUrl = effectiveSupabaseUrl;
1736
+ const sbKey = effectiveSupabaseAnonKey;
1733
1737
  const markActive = () => {
1734
1738
  supabase.from("escalations").update({
1735
1739
  customer_status: "active",
@@ -1740,24 +1744,35 @@ function ChatPanel({
1740
1744
  (err) => console.error("[KiteChat] Failed to update customer status:", err)
1741
1745
  );
1742
1746
  };
1747
+ const markDisconnectedWithKeepalive = () => {
1748
+ if (!sbUrl || !sbKey) return;
1749
+ const url = `${sbUrl}/rest/v1/escalations?session_id=eq.${currentSessionId}`;
1750
+ fetch(url, {
1751
+ method: "PATCH",
1752
+ headers: {
1753
+ "Content-Type": "application/json",
1754
+ "apikey": sbKey,
1755
+ "Authorization": `Bearer ${sbKey}`,
1756
+ "Prefer": "return=minimal"
1757
+ },
1758
+ body: JSON.stringify({
1759
+ customer_status: "disconnected",
1760
+ customer_last_seen: (/* @__PURE__ */ new Date()).toISOString()
1761
+ }),
1762
+ keepalive: true
1763
+ }).catch(() => {
1764
+ });
1765
+ };
1743
1766
  console.log("[KiteChat] Starting presence heartbeat for live chat");
1744
1767
  markActive();
1745
1768
  heartbeatIntervalRef.current = window.setInterval(() => {
1746
1769
  markActive();
1747
1770
  }, 6e4);
1748
1771
  const handleBeforeUnload = () => {
1749
- supabase.from("escalations").update({
1750
- customer_status: "disconnected",
1751
- customer_last_seen: (/* @__PURE__ */ new Date()).toISOString()
1752
- }).eq("session_id", currentSessionId);
1772
+ markDisconnectedWithKeepalive();
1753
1773
  };
1754
1774
  const handleVisibilityChange = () => {
1755
- if (document.visibilityState === "hidden") {
1756
- supabase.from("escalations").update({
1757
- customer_status: "disconnected",
1758
- customer_last_seen: (/* @__PURE__ */ new Date()).toISOString()
1759
- }).eq("session_id", currentSessionId);
1760
- } else if (document.visibilityState === "visible") {
1775
+ if (document.visibilityState === "visible") {
1761
1776
  markActive();
1762
1777
  }
1763
1778
  };
@@ -1781,7 +1796,7 @@ function ChatPanel({
1781
1796
  heartbeatIntervalRef.current = null;
1782
1797
  }
1783
1798
  };
1784
- }, [isEscalated, sessionId]);
1799
+ }, [isEscalated, sessionId, effectiveSupabaseUrl, effectiveSupabaseAnonKey]);
1785
1800
  const sendTypingIndicator = React6.useCallback((isTyping) => {
1786
1801
  if (!typingChannelRef.current || !isEscalated) {
1787
1802
  if (isTyping) {
package/dist/auto.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createKiteChat
3
- } from "./chunk-BLSVIF7H.js";
3
+ } from "./chunk-KIOKMXFF.js";
4
4
 
5
5
  // src/auto.ts
6
6
  function mountKiteChat(config) {
@@ -925,9 +925,9 @@ function useUserAuth({
925
925
  } catch (error) {
926
926
  if (error instanceof Error) {
927
927
  const errorMessage = error.message.toLowerCase();
928
- const isCorsError = errorMessage.includes("cors") || errorMessage.includes("network");
928
+ const isNetworkError = error instanceof TypeError || errorMessage.includes("failed to fetch") || errorMessage.includes("network");
929
929
  const is404Error = errorMessage.includes("404");
930
- if (isCorsError || is404Error) {
930
+ if (isNetworkError || is404Error) {
931
931
  console.warn("[useUserAuth] Auth endpoint unavailable, falling back to unauthenticated mode:", error.message);
932
932
  setAuthState({ status: "idle" });
933
933
  return;
@@ -1580,6 +1580,8 @@ function ChatPanel({
1580
1580
  const [sessionUser, setSessionUser] = React6.useState(null);
1581
1581
  const orgConfigState = useOrgConfig({ agentUrl, orgId: orgId || "" });
1582
1582
  const effectiveProductBackendUrl = orgConfigState.config?.productBackendUrl || productBackendUrl;
1583
+ const effectiveSupabaseUrl = orgConfigState.config?.supabaseUrl || supabaseUrl;
1584
+ const effectiveSupabaseAnonKey = orgConfigState.config?.supabaseAnonKey || supabaseAnonKey;
1583
1585
  const { authState, retry: retryAuth } = useUserAuth({
1584
1586
  productBackendUrl: effectiveProductBackendUrl,
1585
1587
  sessionId,
@@ -1660,10 +1662,10 @@ function ChatPanel({
1660
1662
  }
1661
1663
  }, [isEscalated, sessionId]);
1662
1664
  React6.useEffect(() => {
1663
- if (supabaseUrl && supabaseAnonKey && !supabaseRef.current) {
1664
- supabaseRef.current = createClient(supabaseUrl, supabaseAnonKey);
1665
+ if (effectiveSupabaseUrl && effectiveSupabaseAnonKey && !supabaseRef.current) {
1666
+ supabaseRef.current = createClient(effectiveSupabaseUrl, effectiveSupabaseAnonKey);
1665
1667
  }
1666
- }, [supabaseUrl, supabaseAnonKey]);
1668
+ }, [effectiveSupabaseUrl, effectiveSupabaseAnonKey]);
1667
1669
  React6.useEffect(() => {
1668
1670
  if (!isEscalated || !sessionId || !supabaseRef.current) {
1669
1671
  return;
@@ -1731,6 +1733,8 @@ function ChatPanel({
1731
1733
  }
1732
1734
  const currentSessionId = sessionId;
1733
1735
  const supabase = supabaseRef.current;
1736
+ const sbUrl = effectiveSupabaseUrl;
1737
+ const sbKey = effectiveSupabaseAnonKey;
1734
1738
  const markActive = () => {
1735
1739
  supabase.from("escalations").update({
1736
1740
  customer_status: "active",
@@ -1741,24 +1745,35 @@ function ChatPanel({
1741
1745
  (err) => console.error("[KiteChat] Failed to update customer status:", err)
1742
1746
  );
1743
1747
  };
1748
+ const markDisconnectedWithKeepalive = () => {
1749
+ if (!sbUrl || !sbKey) return;
1750
+ const url = `${sbUrl}/rest/v1/escalations?session_id=eq.${currentSessionId}`;
1751
+ fetch(url, {
1752
+ method: "PATCH",
1753
+ headers: {
1754
+ "Content-Type": "application/json",
1755
+ "apikey": sbKey,
1756
+ "Authorization": `Bearer ${sbKey}`,
1757
+ "Prefer": "return=minimal"
1758
+ },
1759
+ body: JSON.stringify({
1760
+ customer_status: "disconnected",
1761
+ customer_last_seen: (/* @__PURE__ */ new Date()).toISOString()
1762
+ }),
1763
+ keepalive: true
1764
+ }).catch(() => {
1765
+ });
1766
+ };
1744
1767
  console.log("[KiteChat] Starting presence heartbeat for live chat");
1745
1768
  markActive();
1746
1769
  heartbeatIntervalRef.current = window.setInterval(() => {
1747
1770
  markActive();
1748
1771
  }, 6e4);
1749
1772
  const handleBeforeUnload = () => {
1750
- supabase.from("escalations").update({
1751
- customer_status: "disconnected",
1752
- customer_last_seen: (/* @__PURE__ */ new Date()).toISOString()
1753
- }).eq("session_id", currentSessionId);
1773
+ markDisconnectedWithKeepalive();
1754
1774
  };
1755
1775
  const handleVisibilityChange = () => {
1756
- if (document.visibilityState === "hidden") {
1757
- supabase.from("escalations").update({
1758
- customer_status: "disconnected",
1759
- customer_last_seen: (/* @__PURE__ */ new Date()).toISOString()
1760
- }).eq("session_id", currentSessionId);
1761
- } else if (document.visibilityState === "visible") {
1776
+ if (document.visibilityState === "visible") {
1762
1777
  markActive();
1763
1778
  }
1764
1779
  };
@@ -1782,7 +1797,7 @@ function ChatPanel({
1782
1797
  heartbeatIntervalRef.current = null;
1783
1798
  }
1784
1799
  };
1785
- }, [isEscalated, sessionId]);
1800
+ }, [isEscalated, sessionId, effectiveSupabaseUrl, effectiveSupabaseAnonKey]);
1786
1801
  const sendTypingIndicator = React6.useCallback((isTyping) => {
1787
1802
  if (!typingChannelRef.current || !isEscalated) {
1788
1803
  if (isTyping) {