@merit-systems/echo-react-sdk 1.0.8 → 1.0.10

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.js CHANGED
@@ -3,7 +3,7 @@ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { en
3
3
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
4
  var _a;
5
5
  import { jsx, jsxs, Fragment } from "react/jsx-runtime";
6
- import React2, { useState, useCallback, useEffect, createContext, useContext, useRef } from "react";
6
+ import React2, { useState, useCallback, useEffect, createContext, useMemo, useContext, useRef } from "react";
7
7
  class InvalidTokenError extends Error {
8
8
  }
9
9
  InvalidTokenError.prototype.name = "InvalidTokenError";
@@ -9067,19 +9067,18 @@ function useEchoBalance(echoClient, appId) {
9067
9067
  };
9068
9068
  }
9069
9069
  function useEchoClient({ apiUrl }) {
9070
- var _a2;
9070
+ var _a2, _b;
9071
9071
  const auth = useAuth();
9072
9072
  const [client, setClient] = useState(null);
9073
9073
  useEffect(() => {
9074
- var _a3;
9075
- if (!((_a3 = auth.user) == null ? void 0 : _a3.access_token)) {
9074
+ if (!auth.isAuthenticated || !auth.user) {
9076
9075
  setClient(null);
9077
9076
  return;
9078
9077
  }
9079
9078
  const tokenProvider = new OAuthTokenProvider({
9080
9079
  getTokenFn: () => {
9081
- var _a4;
9082
- return Promise.resolve(((_a4 = auth.user) == null ? void 0 : _a4.access_token) || null);
9080
+ var _a3;
9081
+ return Promise.resolve(((_a3 = auth.user) == null ? void 0 : _a3.access_token) || null);
9083
9082
  },
9084
9083
  refreshTokenFn: async () => {
9085
9084
  await auth.signinSilent();
@@ -9097,7 +9096,14 @@ function useEchoClient({ apiUrl }) {
9097
9096
  return () => {
9098
9097
  setClient(null);
9099
9098
  };
9100
- }, [apiUrl, (_a2 = auth.user) == null ? void 0 : _a2.access_token, auth.signinSilent, auth.signoutSilent]);
9099
+ }, [
9100
+ apiUrl,
9101
+ auth.isAuthenticated,
9102
+ (_b = (_a2 = auth.user) == null ? void 0 : _a2.profile) == null ? void 0 : _b.sub,
9103
+ // Only recreate if user ID changes
9104
+ auth.signinSilent,
9105
+ auth.signoutSilent
9106
+ ]);
9101
9107
  return client;
9102
9108
  }
9103
9109
  function useEchoPayments(echoClient) {
@@ -9135,6 +9141,9 @@ function useEchoPayments(echoClient) {
9135
9141
  };
9136
9142
  }
9137
9143
  const EchoContext = createContext(null);
9144
+ const EchoRefreshContext = createContext(
9145
+ null
9146
+ );
9138
9147
  function EchoProviderInternal({ config, children }) {
9139
9148
  var _a2, _b, _c;
9140
9149
  const auth = useAuth();
@@ -9167,25 +9176,51 @@ function EchoProviderInternal({ config, children }) {
9167
9176
  return ((_a3 = auth.user) == null ? void 0 : _a3.access_token) || null;
9168
9177
  }, [(_b = auth.user) == null ? void 0 : _b.access_token]);
9169
9178
  const combinedError = ((_c = auth.error) == null ? void 0 : _c.message) || balanceError || paymentError || null;
9170
- const combinedLoading = auth.isLoading || balanceLoading || paymentLoading;
9171
- const contextValue = {
9172
- user: echoUser || null,
9173
- rawUser: user,
9174
- balance,
9175
- freeTierBalance,
9176
- isAuthenticated: auth.isAuthenticated,
9177
- isLoading: combinedLoading,
9178
- error: combinedError,
9179
- token,
9180
- echoClient,
9181
- signIn: auth.signinRedirect,
9182
- signOut: clearAuth,
9183
- refreshBalance,
9184
- createPaymentLink,
9185
- getToken,
9186
- clearAuth
9187
- };
9188
- return /* @__PURE__ */ jsx(EchoContext.Provider, { value: contextValue, children });
9179
+ const isInitialAuthLoading = auth.isLoading && !auth.isAuthenticated;
9180
+ const isTokenRefreshing = auth.isLoading && auth.isAuthenticated;
9181
+ const combinedLoading = isInitialAuthLoading || balanceLoading || paymentLoading;
9182
+ const contextValue = useMemo(
9183
+ () => ({
9184
+ user: echoUser || null,
9185
+ rawUser: user,
9186
+ balance,
9187
+ freeTierBalance,
9188
+ isAuthenticated: auth.isAuthenticated,
9189
+ isLoading: combinedLoading,
9190
+ error: combinedError,
9191
+ token,
9192
+ echoClient,
9193
+ signIn: auth.signinRedirect,
9194
+ signOut: clearAuth,
9195
+ refreshBalance,
9196
+ createPaymentLink,
9197
+ getToken,
9198
+ clearAuth
9199
+ }),
9200
+ [
9201
+ echoUser,
9202
+ user,
9203
+ balance,
9204
+ freeTierBalance,
9205
+ auth.isAuthenticated,
9206
+ combinedLoading,
9207
+ combinedError,
9208
+ token,
9209
+ echoClient,
9210
+ auth.signinRedirect,
9211
+ clearAuth,
9212
+ refreshBalance,
9213
+ createPaymentLink,
9214
+ getToken
9215
+ ]
9216
+ );
9217
+ const refreshContextValue = useMemo(
9218
+ () => ({
9219
+ isRefreshing: isTokenRefreshing
9220
+ }),
9221
+ [isTokenRefreshing]
9222
+ );
9223
+ return /* @__PURE__ */ jsx(EchoContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx(EchoRefreshContext.Provider, { value: refreshContextValue, children }) });
9189
9224
  }
9190
9225
  function EchoProvider({ config, children }) {
9191
9226
  const [isClient, setIsClient] = useState(false);
@@ -10724,8 +10759,10 @@ function EchoTokenPurchase({
10724
10759
  }).format(value);
10725
10760
  };
10726
10761
  const calculateAvailableSpend = () => {
10727
- var _a2;
10728
- return (((_a2 = freeTierBalance == null ? void 0 : freeTierBalance.userSpendInfo) == null ? void 0 : _a2.amountLeft) || 0) + ((balance == null ? void 0 : balance.balance) || 0);
10762
+ var _a2, _b;
10763
+ const freeTierAmountLeft = (((_a2 = freeTierBalance == null ? void 0 : freeTierBalance.userSpendInfo) == null ? void 0 : _a2.amountLeft) || 0) < 0 ? 0 : ((_b = freeTierBalance == null ? void 0 : freeTierBalance.userSpendInfo) == null ? void 0 : _b.amountLeft) || 0;
10764
+ const balanceAmount = (balance == null ? void 0 : balance.balance) || 0;
10765
+ return freeTierAmountLeft + balanceAmount;
10729
10766
  };
10730
10767
  const handlePurchase = async (purchaseAmount) => {
10731
10768
  if (!isAuthenticated) {
@@ -10949,17 +10986,20 @@ function EchoTokenPurchase({
10949
10986
  width: "6px",
10950
10987
  height: "6px",
10951
10988
  borderRadius: "50%",
10952
- backgroundColor: "#ef4444"
10989
+ backgroundColor: "#3b82f6"
10953
10990
  }
10954
10991
  }
10955
10992
  ),
10956
10993
  /* @__PURE__ */ jsxs("span", { children: [
10957
- formatCurrency(freeTierBalance.userSpendInfo.amountLeft),
10994
+ formatCurrency(
10995
+ freeTierBalance.userSpendInfo.amountLeft < 0 ? 0 : freeTierBalance.userSpendInfo.amountLeft
10996
+ ),
10958
10997
  " ",
10959
10998
  "Free Tier",
10960
10999
  freeTierBalance.userSpendInfo && freeTierBalance.userSpendInfo.spendLimit && /* @__PURE__ */ jsxs("span", { style: { color: "#9ca3af", marginLeft: "8px" }, children: [
11000
+ "(",
10961
11001
  formatCurrency(
10962
- freeTierBalance.userSpendInfo.amountSpent
11002
+ freeTierBalance.userSpendInfo.amountSpent > freeTierBalance.userSpendInfo.spendLimit ? freeTierBalance.userSpendInfo.spendLimit : freeTierBalance.userSpendInfo.amountSpent
10963
11003
  ),
10964
11004
  " ",
10965
11005
  "of",
@@ -10968,7 +11008,7 @@ function EchoTokenPurchase({
10968
11008
  freeTierBalance.userSpendInfo.spendLimit
10969
11009
  ),
10970
11010
  " ",
10971
- "used"
11011
+ "spent)"
10972
11012
  ] })
10973
11013
  ] })
10974
11014
  ]
@@ -10990,9 +11030,9 @@ function EchoTokenPurchase({
10990
11030
  "div",
10991
11031
  {
10992
11032
  style: {
10993
- width: `${Math.min(100, freeTierBalance.userSpendInfo.amountSpent / (freeTierBalance.userSpendInfo.spendLimit || 1) * 100)}%`,
11033
+ width: `${Math.max(0, Math.min(100, Math.max(0, freeTierBalance.userSpendInfo.amountLeft) / (freeTierBalance.userSpendInfo.spendLimit || 1) * 100))}%`,
10994
11034
  height: "100%",
10995
- backgroundColor: "#dc2626"
11035
+ backgroundColor: "#3b82f6"
10996
11036
  }
10997
11037
  }
10998
11038
  )
@@ -11005,25 +11045,68 @@ function EchoTokenPurchase({
11005
11045
  style: {
11006
11046
  fontSize: "12px",
11007
11047
  color: "#6b7280",
11008
- fontFamily: "HelveticaNowDisplay, sans-serif",
11009
- display: "flex",
11010
- alignItems: "center",
11011
- gap: "6px"
11048
+ fontFamily: "HelveticaNowDisplay, sans-serif"
11012
11049
  },
11013
11050
  children: [
11014
- /* @__PURE__ */ jsx(
11051
+ /* @__PURE__ */ jsxs(
11015
11052
  "div",
11016
11053
  {
11017
11054
  style: {
11018
- width: "6px",
11019
- height: "6px",
11020
- borderRadius: "50%",
11021
- backgroundColor: "#3b82f6"
11022
- }
11055
+ display: "flex",
11056
+ alignItems: "center",
11057
+ gap: "6px",
11058
+ marginBottom: "4px"
11059
+ },
11060
+ children: [
11061
+ /* @__PURE__ */ jsx(
11062
+ "div",
11063
+ {
11064
+ style: {
11065
+ width: "6px",
11066
+ height: "6px",
11067
+ borderRadius: "50%",
11068
+ backgroundColor: "#dc2626"
11069
+ }
11070
+ }
11071
+ ),
11072
+ /* @__PURE__ */ jsxs("span", { children: [
11073
+ formatCurrency(balance.balance),
11074
+ " Paid Credits",
11075
+ balance.totalSpent && /* @__PURE__ */ jsxs("span", { style: { color: "#9ca3af", marginLeft: "8px" }, children: [
11076
+ "(",
11077
+ formatCurrency(balance.totalSpent),
11078
+ " /",
11079
+ " ",
11080
+ formatCurrency(balance.totalPaid),
11081
+ " spent)"
11082
+ ] })
11083
+ ] })
11084
+ ]
11023
11085
  }
11024
11086
  ),
11025
- formatCurrency(balance.balance),
11026
- " Paid Credits"
11087
+ balance.totalPaid > 0 && /* @__PURE__ */ jsx(
11088
+ "div",
11089
+ {
11090
+ style: {
11091
+ width: "100%",
11092
+ height: "4px",
11093
+ backgroundColor: "#e5e7eb",
11094
+ borderRadius: "2px",
11095
+ overflow: "hidden",
11096
+ border: "1px solid #d1d5db"
11097
+ },
11098
+ children: /* @__PURE__ */ jsx(
11099
+ "div",
11100
+ {
11101
+ style: {
11102
+ width: `${Math.max(0, Math.min(100, balance.balance / balance.totalPaid * 100))}%`,
11103
+ height: "100%",
11104
+ backgroundColor: "#dc2626"
11105
+ }
11106
+ }
11107
+ )
11108
+ }
11109
+ )
11027
11110
  ]
11028
11111
  }
11029
11112
  )