@huskel/sdk 0.4.6 → 0.4.7

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.mjs CHANGED
@@ -168,6 +168,32 @@ var HuskelAPI = class {
168
168
  if (!res.ok) throw new Error("Failed to fetch checkout config");
169
169
  return res.json();
170
170
  }
171
+ async initiatePayment(phoneNumber, email, firstName, lastName) {
172
+ const res = await fetch(`${this.apiUrl}/payment/initiate`, {
173
+ method: "POST",
174
+ headers: this.buildHeaders(),
175
+ body: JSON.stringify({
176
+ siteId: this.siteId,
177
+ phoneNumber,
178
+ email,
179
+ firstName,
180
+ lastName
181
+ })
182
+ });
183
+ if (!res.ok) {
184
+ const errText = await res.text();
185
+ throw new Error("Failed to initiate payment: " + errText);
186
+ }
187
+ return res.json();
188
+ }
189
+ async getPaymentStatus(ref) {
190
+ const res = await fetch(`${this.apiUrl}/payment/status?ref=${ref}`, {
191
+ method: "GET",
192
+ headers: this.buildHeaders()
193
+ });
194
+ if (!res.ok) throw new Error("Failed to get payment status");
195
+ return res.json();
196
+ }
171
197
  };
172
198
 
173
199
  // src/client.ts
@@ -588,9 +614,10 @@ function useChat() {
588
614
  const [sources, setSources] = useState3([]);
589
615
  const [loading, setLoading] = useState3(false);
590
616
  const [error, setError] = useState3(null);
617
+ const [lastAction, setLastAction] = useState3(null);
591
618
  const abortRef = useRef5(null);
592
619
  const send = useCallback3(async (query, displayQuery) => {
593
- var _a, _b, _c, _d, _e;
620
+ var _a, _b, _c, _d, _e, _f;
594
621
  if (!query.trim() || loading) return;
595
622
  (_a = abortRef.current) == null ? void 0 : _a.abort();
596
623
  abortRef.current = new AbortController();
@@ -621,6 +648,7 @@ function useChat() {
621
648
  }
622
649
  if (signal.aborted) return;
623
650
  setSources((_b = res.sources) != null ? _b : []);
651
+ if (res.action) setLastAction(res.action);
624
652
  if (((_c = res.action) == null ? void 0 : _c.type) === "add_to_cart" || res.checkout) {
625
653
  if (typeof window !== "undefined") {
626
654
  window.dispatchEvent(new CustomEvent("huskel:cart_updated", { detail: res.checkout }));
@@ -631,12 +659,17 @@ function useChat() {
631
659
  window.dispatchEvent(new CustomEvent("huskel:trigger_checkout", { detail: res.checkout }));
632
660
  }
633
661
  }
662
+ if (((_e = res.action) == null ? void 0 : _e.type) === "awaiting_payment") {
663
+ if (typeof window !== "undefined") {
664
+ window.dispatchEvent(new CustomEvent("huskel:awaiting_payment", { detail: res.action }));
665
+ }
666
+ }
634
667
  if (res.checkout && client.onCheckout) {
635
668
  client.onCheckout(res.checkout);
636
669
  }
637
670
  } catch (e) {
638
671
  if (signal.aborted) return;
639
- let msg = (_e = e == null ? void 0 : e.message) != null ? _e : "Chat request failed";
672
+ let msg = (_f = e == null ? void 0 : e.message) != null ? _f : "Chat request failed";
640
673
  try {
641
674
  const parsed = JSON.parse(msg);
642
675
  if (parsed && parsed.error) {
@@ -659,8 +692,9 @@ function useChat() {
659
692
  setSources([]);
660
693
  setError(null);
661
694
  setLoading(false);
695
+ setLastAction(null);
662
696
  }, []);
663
- return { messages, sources, loading, error, send, reset };
697
+ return { messages, sources, loading, error, lastAction, send, reset };
664
698
  }
665
699
 
666
700
  // src/hooks/useCart.ts
@@ -699,8 +733,71 @@ function useCart() {
699
733
  return { cart, loading, fetchCart };
700
734
  }
701
735
 
702
- // src/components/SearchBar.tsx
736
+ // src/hooks/usePaymentPolling.ts
703
737
  import { useState as useState5, useEffect as useEffect4, useRef as useRef6 } from "react";
738
+ function usePaymentPolling({
739
+ client,
740
+ merchantReference,
741
+ onSuccess,
742
+ onFailure,
743
+ intervalMs = 3e3,
744
+ timeoutMs = 3e5
745
+ // 5 minutes default
746
+ }) {
747
+ const [status, setStatus] = useState5("IDLE");
748
+ const [error, setError] = useState5(null);
749
+ const onSuccessRef = useRef6(onSuccess);
750
+ const onFailureRef = useRef6(onFailure);
751
+ useEffect4(() => {
752
+ onSuccessRef.current = onSuccess;
753
+ onFailureRef.current = onFailure;
754
+ }, [onSuccess, onFailure]);
755
+ useEffect4(() => {
756
+ if (!merchantReference) {
757
+ setStatus("IDLE");
758
+ setError(null);
759
+ return;
760
+ }
761
+ setStatus("PENDING");
762
+ setError(null);
763
+ const startTime = Date.now();
764
+ let timerId = null;
765
+ async function checkStatus() {
766
+ try {
767
+ if (Date.now() - startTime >= timeoutMs) {
768
+ setStatus("FAILED");
769
+ setError("Payment session timed out");
770
+ if (onFailureRef.current) onFailureRef.current("Payment session timed out");
771
+ return;
772
+ }
773
+ const res = await client.getPaymentStatus(merchantReference);
774
+ if (res.status === "COMPLETED") {
775
+ setStatus("COMPLETED");
776
+ if (onSuccessRef.current) onSuccessRef.current();
777
+ } else if (res.status === "FAILED") {
778
+ setStatus("FAILED");
779
+ setError("Payment failed");
780
+ if (onFailureRef.current) onFailureRef.current("Payment failed");
781
+ } else {
782
+ timerId = setTimeout(checkStatus, intervalMs);
783
+ }
784
+ } catch (err) {
785
+ console.error("[Huskel Polling Error]", err);
786
+ timerId = setTimeout(checkStatus, intervalMs);
787
+ }
788
+ }
789
+ timerId = setTimeout(checkStatus, intervalMs);
790
+ return () => {
791
+ if (timerId) {
792
+ clearTimeout(timerId);
793
+ }
794
+ };
795
+ }, [client, merchantReference, intervalMs, timeoutMs]);
796
+ return { status, error };
797
+ }
798
+
799
+ // src/components/SearchBar.tsx
800
+ import { useState as useState6, useEffect as useEffect5, useRef as useRef7 } from "react";
704
801
 
705
802
  // src/utils/cn.ts
706
803
  import { clsx } from "clsx";
@@ -727,15 +824,15 @@ function SearchBar({
727
824
  theme,
728
825
  classNames = {}
729
826
  }) {
730
- const [query, setQuery] = useState5("");
731
- const [open, setOpen] = useState5(false);
732
- const [isDebouncing, setIsDebouncing] = useState5(false);
827
+ const [query, setQuery] = useState6("");
828
+ const [open, setOpen] = useState6(false);
829
+ const [isDebouncing, setIsDebouncing] = useState6(false);
733
830
  const { results, loading, search, clear } = useSearch();
734
831
  const client = useHuskelContext();
735
- const timer = useRef6();
736
- const wrap = useRef6(null);
737
- const ignoreNextQueryChange = useRef6(false);
738
- useEffect4(() => {
832
+ const timer = useRef7();
833
+ const wrap = useRef7(null);
834
+ const ignoreNextQueryChange = useRef7(false);
835
+ useEffect5(() => {
739
836
  if (ignoreNextQueryChange.current) {
740
837
  ignoreNextQueryChange.current = false;
741
838
  return;
@@ -755,7 +852,7 @@ function SearchBar({
755
852
  }, debounceMs);
756
853
  return () => clearTimeout(timer.current);
757
854
  }, [query]);
758
- useEffect4(() => {
855
+ useEffect5(() => {
759
856
  const h = (e) => {
760
857
  if (wrap.current && !wrap.current.contains(e.target)) setOpen(false);
761
858
  };
@@ -859,7 +956,7 @@ function SearchBar({
859
956
  }
860
957
 
861
958
  // src/components/Sparkle.tsx
862
- import { useState as useState6, useEffect as useEffect5, useRef as useRef7 } from "react";
959
+ import { useState as useState7, useEffect as useEffect6, useRef as useRef8 } from "react";
863
960
  import { createPortal } from "react-dom";
864
961
 
865
962
  // src/utils/markdown.tsx
@@ -991,14 +1088,14 @@ function SparkleModal({
991
1088
  }) {
992
1089
  var _a, _b, _c;
993
1090
  const client = useHuskelContext();
994
- const [fetchedProduct, setFetchedProduct] = useState6(null);
1091
+ const [fetchedProduct, setFetchedProduct] = useState7(null);
995
1092
  const displayProduct = initialProduct || fetchedProduct;
996
1093
  const { results, loading: searchLoading, search } = useSearch();
997
1094
  const { messages, sources, loading: chatLoading, error: chatError, send } = useChat();
998
- const [chatInput, setChatInput] = useState6("");
999
- const chatBottomRef = useRef7(null);
1000
- const chatTextareaRef = useRef7(null);
1001
- useEffect5(() => {
1095
+ const [chatInput, setChatInput] = useState7("");
1096
+ const chatBottomRef = useRef8(null);
1097
+ const chatTextareaRef = useRef8(null);
1098
+ useEffect6(() => {
1002
1099
  if (!initialProduct && !fetchedProduct) {
1003
1100
  client.api.searchVector(productName, 1).then((res) => {
1004
1101
  if (res.results && res.results.length > 0) {
@@ -1008,17 +1105,17 @@ function SparkleModal({
1008
1105
  }
1009
1106
  search(productName, limit);
1010
1107
  }, [productName, initialProduct, fetchedProduct, client, limit, search]);
1011
- useEffect5(() => {
1108
+ useEffect6(() => {
1012
1109
  if (results.length > 0) onResult == null ? void 0 : onResult(results);
1013
1110
  }, [results, onResult]);
1014
- useEffect5(() => {
1111
+ useEffect6(() => {
1015
1112
  const h = (e) => {
1016
1113
  if (e.key === "Escape") onClose();
1017
1114
  };
1018
1115
  document.addEventListener("keydown", h);
1019
1116
  return () => document.removeEventListener("keydown", h);
1020
1117
  }, [onClose]);
1021
- useEffect5(() => {
1118
+ useEffect6(() => {
1022
1119
  var _a2;
1023
1120
  (_a2 = chatBottomRef.current) == null ? void 0 : _a2.scrollIntoView({ behavior: "smooth" });
1024
1121
  }, [messages, chatLoading]);
@@ -1250,9 +1347,9 @@ function Sparkle({
1250
1347
  classNames = {},
1251
1348
  product
1252
1349
  }) {
1253
- const [open, setOpen] = useState6(false);
1254
- const [mounted, setMounted] = useState6(false);
1255
- useEffect5(() => {
1350
+ const [open, setOpen] = useState7(false);
1351
+ const [mounted, setMounted] = useState7(false);
1352
+ useEffect6(() => {
1256
1353
  setMounted(true);
1257
1354
  }, []);
1258
1355
  const customStyles = __spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues({}, (theme == null ? void 0 : theme.primaryColor) && { "--hsk-primary": theme.primaryColor }), (theme == null ? void 0 : theme.backgroundColor) && { "--hsk-bg": theme.backgroundColor }), (theme == null ? void 0 : theme.textColor) && { "--hsk-text": theme.textColor }), (theme == null ? void 0 : theme.fontFamily) && { "--hsk-font": theme.fontFamily }), (theme == null ? void 0 : theme.borderRadius) && { "--hsk-border-radius": theme.borderRadius });
@@ -1290,7 +1387,7 @@ function Sparkle({
1290
1387
  }
1291
1388
 
1292
1389
  // src/components/ChatWidget.tsx
1293
- import { useState as useState7, useRef as useRef8, useEffect as useEffect6 } from "react";
1390
+ import { useState as useState8, useRef as useRef9, useEffect as useEffect7 } from "react";
1294
1391
  import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
1295
1392
  var SparkleIcon2 = () => /* @__PURE__ */ jsx5("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx5("path", { d: "m12 3-1.912 5.813a2 2 0 0 1-1.275 1.275L3 12l5.813 1.912a2 2 0 0 1 1.275 1.275L12 21l1.912-5.813a2 2 0 0 1 1.275-1.275L21 12l-5.813-1.912a2 2 0 0 1-1.275-1.275L12 3Z" }) });
1296
1393
  var ArrowUpIcon2 = () => /* @__PURE__ */ jsxs3("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
@@ -1323,10 +1420,10 @@ function ChatWidget({
1323
1420
  onSelectSource
1324
1421
  }) {
1325
1422
  const { messages, sources, loading, error, send, reset } = useChat();
1326
- const [input, setInput] = useState7("");
1327
- const bottomRef = useRef8(null);
1328
- const textareaRef = useRef8(null);
1329
- useEffect6(() => {
1423
+ const [input, setInput] = useState8("");
1424
+ const bottomRef = useRef9(null);
1425
+ const textareaRef = useRef9(null);
1426
+ useEffect7(() => {
1330
1427
  var _a;
1331
1428
  (_a = bottomRef.current) == null ? void 0 : _a.scrollIntoView({ behavior: "smooth" });
1332
1429
  }, [messages, loading]);
@@ -1423,7 +1520,7 @@ function ChatWidget({
1423
1520
  }
1424
1521
 
1425
1522
  // src/components/AIChatButton.tsx
1426
- import { useState as useState8, useEffect as useEffect7, useRef as useRef9, useCallback as useCallback5 } from "react";
1523
+ import { useState as useState9, useEffect as useEffect8, useRef as useRef10, useCallback as useCallback5 } from "react";
1427
1524
  import { createPortal as createPortal2 } from "react-dom";
1428
1525
  import { Fragment as Fragment4, jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
1429
1526
  var SparkleIcon3 = ({ className }) => /* @__PURE__ */ jsx6("svg", { className, width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx6("path", { d: "m12 3-1.912 5.813a2 2 0 0 1-1.275 1.275L3 12l5.813 1.912a2 2 0 0 1 1.275 1.275L12 21l1.912-5.813a2 2 0 0 1 1.275-1.275L21 12l-5.813-1.912a2 2 0 0 1-1.275-1.275L12 3Z" }) });
@@ -1443,15 +1540,15 @@ var DEFAULT_CHIPS = [
1443
1540
  "Best laptop for students"
1444
1541
  ];
1445
1542
  function SourcesCarousel({ sources, defaultCurrency, onSelectSource }) {
1446
- const railRef = useRef9(null);
1447
- const [showNext, setShowNext] = useState8(false);
1543
+ const railRef = useRef10(null);
1544
+ const [showNext, setShowNext] = useState9(false);
1448
1545
  const measure = useCallback5(() => {
1449
1546
  const el = railRef.current;
1450
1547
  if (!el) return;
1451
1548
  const atEnd = el.scrollLeft + el.clientWidth >= el.scrollWidth - 8;
1452
1549
  setShowNext(el.scrollWidth > el.clientWidth + 4 && !atEnd);
1453
1550
  }, []);
1454
- useEffect7(() => {
1551
+ useEffect8(() => {
1455
1552
  measure();
1456
1553
  const el = railRef.current;
1457
1554
  if (!el) return;
@@ -1516,16 +1613,53 @@ function ChatModal({
1516
1613
  classNames = {}
1517
1614
  }) {
1518
1615
  var _a, _b;
1519
- const { messages, sources, loading, error, send, reset } = useChat();
1520
- const [input, setInput] = useState8("");
1521
- const [selectedProduct, setSelectedProduct] = useState8(null);
1522
- const bottomRef = useRef9(null);
1523
- const textareaRef = useRef9(null);
1524
- useEffect7(() => {
1616
+ const client = useHuskelContext();
1617
+ const { messages, sources, loading, error, lastAction, send, reset } = useChat();
1618
+ const [input, setInput] = useState9("");
1619
+ const [selectedProduct, setSelectedProduct] = useState9(null);
1620
+ const bottomRef = useRef10(null);
1621
+ const textareaRef = useRef10(null);
1622
+ const [phoneInput, setPhoneInput] = useState9("");
1623
+ const [merchantRef, setMerchantRef] = useState9(null);
1624
+ const [paymentPhase, setPaymentPhase] = useState9("idle");
1625
+ const { status: pollStatus } = usePaymentPolling({
1626
+ client: client.api,
1627
+ merchantReference: merchantRef,
1628
+ onSuccess: () => {
1629
+ setPaymentPhase("done");
1630
+ setMerchantRef(null);
1631
+ },
1632
+ onFailure: () => {
1633
+ setPaymentPhase("failed");
1634
+ setMerchantRef(null);
1635
+ }
1636
+ });
1637
+ useEffect8(() => {
1638
+ var _a2;
1639
+ if (!lastAction) return;
1640
+ if (lastAction.type === "request_phone") {
1641
+ setPaymentPhase("prompt_phone");
1642
+ } else if (lastAction.type === "awaiting_payment") {
1643
+ setMerchantRef((_a2 = lastAction.merchantReference) != null ? _a2 : null);
1644
+ setPaymentPhase("awaiting");
1645
+ }
1646
+ }, [lastAction]);
1647
+ const handlePhoneSubmit = async () => {
1648
+ if (!phoneInput.trim()) return;
1649
+ try {
1650
+ const res = await client.api.initiatePayment(phoneInput);
1651
+ setMerchantRef(res.merchantReference);
1652
+ setPaymentPhase("awaiting");
1653
+ } catch (e) {
1654
+ console.error("[Huskel] initiatePayment error", e);
1655
+ setPaymentPhase("failed");
1656
+ }
1657
+ };
1658
+ useEffect8(() => {
1525
1659
  var _a2;
1526
1660
  (_a2 = bottomRef.current) == null ? void 0 : _a2.scrollIntoView({ behavior: "smooth" });
1527
1661
  }, [messages, loading, selectedProduct]);
1528
- useEffect7(() => {
1662
+ useEffect8(() => {
1529
1663
  const h = (e) => {
1530
1664
  if (e.key === "Escape") onClose();
1531
1665
  };
@@ -1641,6 +1775,39 @@ function ChatModal({
1641
1775
  ] })
1642
1776
  ] }),
1643
1777
  error && /* @__PURE__ */ jsx6("div", { className: "hsk-cb-error", children: error }),
1778
+ paymentPhase === "prompt_phone" && /* @__PURE__ */ jsxs4("div", { className: "hsk-cb-payment-prompt", children: [
1779
+ /* @__PURE__ */ jsx6("div", { className: "hsk-cb-payment-icon", children: "\u{1F4F1}" }),
1780
+ /* @__PURE__ */ jsx6("p", { className: "hsk-cb-payment-label", children: "Enter your M-Pesa number to pay" }),
1781
+ /* @__PURE__ */ jsx6(
1782
+ "input",
1783
+ {
1784
+ type: "tel",
1785
+ className: "hsk-cb-phone-input",
1786
+ placeholder: "e.g. 0712 345 678",
1787
+ value: phoneInput,
1788
+ onChange: (e) => setPhoneInput(e.target.value),
1789
+ onKeyDown: (e) => e.key === "Enter" && handlePhoneSubmit()
1790
+ }
1791
+ ),
1792
+ /* @__PURE__ */ jsx6("button", { className: "hsk-cb-pay-submit", onClick: handlePhoneSubmit, children: "Send STK Push \u2192" })
1793
+ ] }),
1794
+ paymentPhase === "awaiting" && /* @__PURE__ */ jsxs4("div", { className: "hsk-cb-payment-prompt", children: [
1795
+ /* @__PURE__ */ jsx6("div", { className: "hsk-cb-payment-icon", style: { fontSize: "2rem" }, children: "\u23F3" }),
1796
+ /* @__PURE__ */ jsx6("p", { className: "hsk-cb-payment-label", style: { fontWeight: 600 }, children: "Check your phone" }),
1797
+ /* @__PURE__ */ jsx6("p", { style: { fontSize: "0.8rem", opacity: 0.6 }, children: "An M-Pesa STK push has been sent. Enter your PIN to complete payment." })
1798
+ ] }),
1799
+ paymentPhase === "done" && /* @__PURE__ */ jsxs4("div", { className: "hsk-cb-payment-prompt", children: [
1800
+ /* @__PURE__ */ jsx6("div", { className: "hsk-cb-payment-icon", style: { color: "#22c55e", fontSize: "2rem" }, children: "\u2705" }),
1801
+ /* @__PURE__ */ jsx6("p", { className: "hsk-cb-payment-label", children: "Payment complete! Thank you." })
1802
+ ] }),
1803
+ paymentPhase === "failed" && /* @__PURE__ */ jsxs4("div", { className: "hsk-cb-payment-prompt", children: [
1804
+ /* @__PURE__ */ jsx6("div", { className: "hsk-cb-payment-icon", style: { color: "#ef4444", fontSize: "2rem" }, children: "\u274C" }),
1805
+ /* @__PURE__ */ jsx6("p", { className: "hsk-cb-payment-label", children: "Payment failed or timed out." }),
1806
+ /* @__PURE__ */ jsx6("button", { className: "hsk-cb-pay-submit", onClick: () => {
1807
+ setPaymentPhase("idle");
1808
+ setMerchantRef(null);
1809
+ }, children: "Try again" })
1810
+ ] }),
1644
1811
  /* @__PURE__ */ jsx6("div", { ref: bottomRef, style: { height: 1 } })
1645
1812
  ] }),
1646
1813
  /* @__PURE__ */ jsxs4("div", { className: "hsk-cb-input-wrap", children: [
@@ -1689,9 +1856,9 @@ function AIChatButton({
1689
1856
  theme,
1690
1857
  classNames = {}
1691
1858
  }) {
1692
- const [open, setOpen] = useState8(false);
1693
- const [mounted, setMounted] = useState8(false);
1694
- useEffect7(() => {
1859
+ const [open, setOpen] = useState9(false);
1860
+ const [mounted, setMounted] = useState9(false);
1861
+ useEffect8(() => {
1695
1862
  setMounted(true);
1696
1863
  }, []);
1697
1864
  const customStyles = __spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues({}, (theme == null ? void 0 : theme.primaryColor) && { "--hsk-primary": theme.primaryColor }), (theme == null ? void 0 : theme.backgroundColor) && { "--hsk-bg": theme.backgroundColor }), (theme == null ? void 0 : theme.textColor) && { "--hsk-text": theme.textColor }), (theme == null ? void 0 : theme.fontFamily) && { "--hsk-font": theme.fontFamily }), (theme == null ? void 0 : theme.borderRadius) && { "--hsk-border-radius": theme.borderRadius });
@@ -1739,11 +1906,11 @@ function CartBadge({ className }) {
1739
1906
  }
1740
1907
 
1741
1908
  // src/components/CartDrawer.tsx
1742
- import { useState as useState10, useEffect as useEffect9 } from "react";
1909
+ import { useState as useState11, useEffect as useEffect10 } from "react";
1743
1910
  import { createPortal as createPortal4 } from "react-dom";
1744
1911
 
1745
1912
  // src/components/CheckoutModal.tsx
1746
- import { useState as useState9, useEffect as useEffect8 } from "react";
1913
+ import { useState as useState10, useEffect as useEffect9 } from "react";
1747
1914
  import { createPortal as createPortal3 } from "react-dom";
1748
1915
  import { Fragment as Fragment5, jsx as jsx8, jsxs as jsxs5 } from "react/jsx-runtime";
1749
1916
  function CheckoutModal({
@@ -1755,11 +1922,11 @@ function CheckoutModal({
1755
1922
  var _a, _b, _c, _d;
1756
1923
  const { cart, loading: cartLoading } = useCart();
1757
1924
  const client = useHuskelContext();
1758
- const [config, setConfig] = useState9(null);
1759
- const [loading, setLoading] = useState9(true);
1760
- const [checkingOut, setCheckingOut] = useState9(false);
1761
- const [paymentSuccess, setPaymentSuccess] = useState9(false);
1762
- useEffect8(() => {
1925
+ const [config, setConfig] = useState10(null);
1926
+ const [loading, setLoading] = useState10(true);
1927
+ const [checkingOut, setCheckingOut] = useState10(false);
1928
+ const [paymentSuccess, setPaymentSuccess] = useState10(false);
1929
+ useEffect9(() => {
1763
1930
  client.api.getCheckoutConfig().then((res) => setConfig(res.payment_methods)).catch((e) => console.error("[Huskel] Failed to fetch checkout config", e)).finally(() => setLoading(false));
1764
1931
  }, [client]);
1765
1932
  const handlePay = async (method) => {
@@ -1861,11 +2028,11 @@ function CartDrawer({
1861
2028
  theme
1862
2029
  }) {
1863
2030
  const { cart, loading } = useCart();
1864
- const [open, setOpen] = useState10(false);
1865
- const [showCheckout, setShowCheckout] = useState10(false);
1866
- const [mounted, setMounted] = useState10(false);
2031
+ const [open, setOpen] = useState11(false);
2032
+ const [showCheckout, setShowCheckout] = useState11(false);
2033
+ const [mounted, setMounted] = useState11(false);
1867
2034
  const client = useHuskelContext();
1868
- useEffect9(() => {
2035
+ useEffect10(() => {
1869
2036
  setMounted(true);
1870
2037
  const handleTriggerCheckout = () => {
1871
2038
  setShowCheckout(true);
@@ -1876,7 +2043,7 @@ function CartDrawer({
1876
2043
  window.removeEventListener("huskel:trigger_checkout", handleTriggerCheckout);
1877
2044
  };
1878
2045
  }, []);
1879
- useEffect9(() => {
2046
+ useEffect10(() => {
1880
2047
  if (open) {
1881
2048
  document.body.style.overflow = "hidden";
1882
2049
  } else {
@@ -1994,8 +2161,10 @@ export {
1994
2161
  useCart,
1995
2162
  useChat,
1996
2163
  useHuskel,
2164
+ useHuskelContext,
1997
2165
  useIngest,
1998
2166
  usePageIngest,
2167
+ usePaymentPolling,
1999
2168
  useSearch
2000
2169
  };
2001
2170
  //# sourceMappingURL=index.mjs.map