@usebridge/sdk-react 0.4.0 → 0.5.0

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
@@ -187,32 +187,57 @@ __export(index_exports, {
187
187
  module.exports = __toCommonJS(index_exports);
188
188
 
189
189
  // src/sdk/index.tsx
190
- var import_react2 = require("react");
190
+ var import_react3 = require("react");
191
191
  var import_sdk_core2 = require("@usebridge/sdk-core");
192
192
 
193
193
  // src/sdk/use-prefetch-payers.ts
194
194
  var import_sdk_core = require("@usebridge/sdk-core");
195
195
  var import_react = require("react");
196
196
  function usePrefetchPayers(bridgeSdk, enabled) {
197
+ const fetched = (0, import_react.useRef)(false);
197
198
  (0, import_react.useEffect)(() => {
199
+ if (fetched.current) return;
198
200
  if (enabled) {
199
201
  void Promise.all(
200
202
  ["", "b", "u", "a"].map((query) => bridgeSdk.payerSearch({ query, limit: 10 }))
201
203
  );
204
+ fetched.current = true;
202
205
  }
203
206
  }, [bridgeSdk, enabled]);
204
207
  }
205
208
 
209
+ // src/sdk/use-analytics-lifecycle.ts
210
+ var import_react2 = require("react");
211
+ function useAnalyticsLifecycle(bridgeSdk) {
212
+ (0, import_react2.useEffect)(() => {
213
+ return () => {
214
+ bridgeSdk._analytics.flush();
215
+ };
216
+ }, [bridgeSdk]);
217
+ (0, import_react2.useEffect)(() => {
218
+ const flush = () => {
219
+ if (document.visibilityState === "hidden") bridgeSdk._analytics.flush();
220
+ };
221
+ if (typeof window !== "undefined") window.addEventListener("visibilitychange", flush);
222
+ return () => {
223
+ if (typeof window !== "undefined") window.removeEventListener("visibilitychange", flush);
224
+ };
225
+ }, [bridgeSdk]);
226
+ }
227
+
206
228
  // src/sdk/index.tsx
207
229
  var import_jsx_runtime = require("react/jsx-runtime");
208
- var BridgeSdkContext = (0, import_react2.createContext)(null);
230
+ var BridgeSdkContext = (0, import_react3.createContext)(null);
209
231
  var BridgeSdkProvider = ({
210
232
  config,
211
233
  prefetchPayers = true,
212
234
  children
213
235
  }) => {
214
- const { current } = (0, import_react2.useRef)(new import_sdk_core2.BridgeSdk(config));
236
+ const sdkRef = (0, import_react3.useRef)(null);
237
+ if (!sdkRef.current) sdkRef.current = new import_sdk_core2.BridgeSdk(config);
238
+ const current = sdkRef.current;
215
239
  usePrefetchPayers(current, prefetchPayers);
240
+ useAnalyticsLifecycle(current);
216
241
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(BridgeSdkContext.Provider, { value: current, children: [
217
242
  " ",
218
243
  children,
@@ -220,26 +245,26 @@ var BridgeSdkProvider = ({
220
245
  ] });
221
246
  };
222
247
  function useBridgeSdk() {
223
- const context = (0, import_react2.useContext)(BridgeSdkContext);
248
+ const context = (0, import_react3.useContext)(BridgeSdkContext);
224
249
  if (!context) throw new Error("useBridgeSdk must be used within a BridgeSdkProvider");
225
250
  return context;
226
251
  }
227
252
 
228
253
  // src/payer-search/use-payer-autocomplete.ts
229
- var import_react5 = require("react");
254
+ var import_react6 = require("react");
230
255
 
231
256
  // ../../node_modules/usehooks-ts/dist/index.js
232
- var import_react3 = require("react");
257
+ var import_react4 = require("react");
233
258
  var import_lodash = __toESM(require_lodash(), 1);
234
259
  function useIsMounted() {
235
- const isMounted = (0, import_react3.useRef)(false);
236
- (0, import_react3.useEffect)(() => {
260
+ const isMounted = (0, import_react4.useRef)(false);
261
+ (0, import_react4.useEffect)(() => {
237
262
  isMounted.current = true;
238
263
  return () => {
239
264
  isMounted.current = false;
240
265
  };
241
266
  }, []);
242
- return (0, import_react3.useCallback)(() => isMounted.current, []);
267
+ return (0, import_react4.useCallback)(() => isMounted.current, []);
243
268
  }
244
269
 
245
270
  // src/lib/retry-loop.ts
@@ -254,7 +279,7 @@ async function retryLoop(fn, shouldRetry, delayMs = 500) {
254
279
  while (!cancelled) {
255
280
  try {
256
281
  return await fn();
257
- } catch (err) {
282
+ } catch (_) {
258
283
  if (!shouldRetry()) {
259
284
  cancelled = true;
260
285
  } else {
@@ -266,10 +291,10 @@ async function retryLoop(fn, shouldRetry, delayMs = 500) {
266
291
  }
267
292
 
268
293
  // src/payer-search/use-payer-search.ts
269
- var import_react4 = require("react");
294
+ var import_react5 = require("react");
270
295
  function usePayerSearch() {
271
296
  const sdk = useBridgeSdk();
272
- return (0, import_react4.useCallback)(
297
+ return (0, import_react5.useCallback)(
273
298
  (...args) => sdk.payerSearch(...args),
274
299
  [sdk]
275
300
  );
@@ -1808,14 +1833,14 @@ var omit_default = omit;
1808
1833
  var resultCache = /* @__PURE__ */ new Map();
1809
1834
  function usePayerAutocomplete(query, {
1810
1835
  limit = 10
1811
- }) {
1836
+ } = {}) {
1812
1837
  const payerSearch = usePayerSearch();
1813
- const [isLoading, setIsLoading] = (0, import_react5.useState)(false);
1814
- const [results, setResults] = (0, import_react5.useState)([]);
1838
+ const [isLoading, setIsLoading] = (0, import_react6.useState)(false);
1839
+ const [results, setResults] = (0, import_react6.useState)([]);
1815
1840
  const normalizedQuery = query.trim().toLowerCase();
1816
- const reqId = (0, import_react5.useRef)(0);
1841
+ const reqId = (0, import_react6.useRef)(0);
1817
1842
  const isMounted = useIsMounted();
1818
- (0, import_react5.useEffect)(() => {
1843
+ (0, import_react6.useEffect)(() => {
1819
1844
  const thisId = ++reqId.current;
1820
1845
  const cachedResults = resultCache.get(normalizedQuery);
1821
1846
  if (cachedResults) {
@@ -1842,23 +1867,23 @@ function usePayerAutocomplete(query, {
1842
1867
  }
1843
1868
  void run();
1844
1869
  }, [payerSearch, normalizedQuery, limit]);
1845
- return (0, import_react5.useMemo)(
1870
+ return (0, import_react6.useMemo)(
1846
1871
  () => ({ isLoading, results: results.map((r) => omit_default(r, "code")) }),
1847
1872
  [isLoading, results]
1848
1873
  );
1849
1874
  }
1850
1875
 
1851
1876
  // src/soft-eligibility/soft-eligibility-provider.tsx
1852
- var import_react16 = require("react");
1877
+ var import_react18 = require("react");
1853
1878
  var import_sdk_core10 = require("@usebridge/sdk-core");
1854
1879
 
1855
1880
  // src/soft-eligibility/soft-eligibility-context.ts
1856
1881
  var import_sdk_core3 = require("@usebridge/sdk-core");
1857
- var import_react6 = require("react");
1858
- var SoftEligibilityContext = (0, import_react6.createContext)(null);
1882
+ var import_react7 = require("react");
1883
+ var SoftEligibilityContext = (0, import_react7.createContext)(null);
1859
1884
 
1860
1885
  // src/eligibility-input/eligibility-input-provider.tsx
1861
- var import_react15 = require("react");
1886
+ var import_react17 = require("react");
1862
1887
  var import_zustand4 = require("zustand");
1863
1888
 
1864
1889
  // src/eligibility-input/eligibility-input-store.ts
@@ -1894,24 +1919,24 @@ function createEligibilityInputStore(requirePatient) {
1894
1919
  }
1895
1920
 
1896
1921
  // src/eligibility-input/eligibility-input-context.ts
1897
- var import_react7 = require("react");
1922
+ var import_react8 = require("react");
1898
1923
  var import_zustand2 = require("zustand");
1899
- var EligibilityInputContext = (0, import_react7.createContext)(null);
1924
+ var EligibilityInputContext = (0, import_react8.createContext)(null);
1900
1925
 
1901
1926
  // src/hard-eligibility/use-create-hard-eligibility-session.ts
1902
- var import_react8 = require("react");
1927
+ var import_react9 = require("react");
1903
1928
  function useCreateHardEligibilitySession() {
1904
1929
  const bridgeSdk = useBridgeSdk();
1905
- return (0, import_react8.useCallback)(
1930
+ return (0, import_react9.useCallback)(
1906
1931
  (...args) => bridgeSdk.createHardEligibilitySession(...args),
1907
1932
  [bridgeSdk]
1908
1933
  );
1909
1934
  }
1910
1935
 
1911
1936
  // src/hard-eligibility/hard-eligibility-context.ts
1912
- var import_react9 = require("react");
1937
+ var import_react10 = require("react");
1913
1938
  var import_sdk_core4 = require("@usebridge/sdk-core");
1914
- var HardEligibilityContext = (0, import_react9.createContext)(null);
1939
+ var HardEligibilityContext = (0, import_react10.createContext)(null);
1915
1940
 
1916
1941
  // src/hard-eligibility/hard-eligibility-provider.tsx
1917
1942
  var import_sdk_core5 = require("@usebridge/sdk-core");
@@ -1922,14 +1947,14 @@ var HardEligibilityProvider = ({
1922
1947
  }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(HardEligibilityContext.Provider, { value: session, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(EligibilityInputProvider, { children }) });
1923
1948
 
1924
1949
  // src/hard-eligibility/use-hard-eligibility-state.ts
1925
- var import_react11 = require("react");
1950
+ var import_react12 = require("react");
1926
1951
  var import_sdk_core7 = require("@usebridge/sdk-core");
1927
1952
 
1928
1953
  // src/hard-eligibility/use-hard-eligibility.ts
1929
- var import_react10 = require("react");
1954
+ var import_react11 = require("react");
1930
1955
  var import_sdk_core6 = require("@usebridge/sdk-core");
1931
1956
  function useHardEligibilitySession() {
1932
- const session = (0, import_react10.useContext)(HardEligibilityContext);
1957
+ const session = (0, import_react11.useContext)(HardEligibilityContext);
1933
1958
  if (!session) throw new Error("useHardEligibilitySession must be within a SoftEligibilityContext");
1934
1959
  return session;
1935
1960
  }
@@ -1937,8 +1962,8 @@ function useHardEligibilitySession() {
1937
1962
  // src/hard-eligibility/use-hard-eligibility-state.ts
1938
1963
  function useHardEligibilityState() {
1939
1964
  const session = useHardEligibilitySession();
1940
- const [state, setState] = (0, import_react11.useState)(session.state);
1941
- (0, import_react11.useEffect)(() => {
1965
+ const [state, setState] = (0, import_react12.useState)(session.state);
1966
+ (0, import_react12.useEffect)(() => {
1942
1967
  session.on("update", setState);
1943
1968
  return () => {
1944
1969
  session.removeListener("update", setState);
@@ -1948,13 +1973,13 @@ function useHardEligibilityState() {
1948
1973
  }
1949
1974
 
1950
1975
  // src/hard-eligibility/use-hard-eligibility-submit.ts
1951
- var import_react14 = require("react");
1976
+ var import_react15 = require("react");
1952
1977
 
1953
1978
  // src/eligibility-input/use-eligibility-input.ts
1954
- var import_react12 = require("react");
1979
+ var import_react13 = require("react");
1955
1980
  var import_zustand3 = require("zustand");
1956
1981
  var useEligibilityInput = () => {
1957
- const store = (0, import_react12.useContext)(EligibilityInputContext);
1982
+ const store = (0, import_react13.useContext)(EligibilityInputContext);
1958
1983
  if (!store) throw new Error("useEligibilityInputStore must be within an EligibilityInputProvider");
1959
1984
  return (0, import_zustand3.useStore)(store);
1960
1985
  };
@@ -1963,30 +1988,30 @@ var useEligibilityInput = () => {
1963
1988
  var import_sdk_core9 = require("@usebridge/sdk-core");
1964
1989
 
1965
1990
  // src/eligibility-input/use-eligibility-input-field.ts
1966
- var import_react13 = require("react");
1991
+ var import_react14 = require("react");
1967
1992
  var import_sdk_core8 = require("@usebridge/sdk-core");
1968
- function useEligibilityInputField(field) {
1993
+ function useEligibilityInputField(field, defaultValue) {
1969
1994
  const input = useEligibilityInput();
1970
1995
  const inputField = input[field];
1971
1996
  const { requirePatient } = input;
1972
1997
  const { value, set } = inputField;
1973
- const hardEligibilityContext = (0, import_react13.useContext)(HardEligibilityContext);
1998
+ const hardEligibilityContext = (0, import_react14.useContext)(HardEligibilityContext);
1974
1999
  let isDisabled = false;
1975
- const [forceMemberId, setForceMemberId] = (0, import_react13.useState)(false);
2000
+ const [forceMemberId, setForceMemberId] = (0, import_react14.useState)(false);
1976
2001
  const errorForceMemberId = hardEligibilityContext?.state.error?.forceMemberId;
1977
- (0, import_react13.useEffect)(() => {
2002
+ (0, import_react14.useEffect)(() => {
1978
2003
  if (errorForceMemberId) setForceMemberId(true);
1979
2004
  }, [errorForceMemberId]);
1980
2005
  try {
1981
2006
  const { status } = useHardEligibilityState();
1982
2007
  isDisabled = !import_sdk_core8.HardEligibility.canSubmit(status);
1983
2008
  if (status === "WAITING_FOR_SERVICE_ELIGIBILITY") isDisabled = true;
1984
- } catch (err) {
2009
+ } catch (_) {
1985
2010
  }
1986
2011
  try {
1987
2012
  const { status } = useSoftEligibilityState();
1988
2013
  isDisabled = !import_sdk_core8.SoftEligibility.canSubmit(status);
1989
- } catch (err) {
2014
+ } catch (_) {
1990
2015
  }
1991
2016
  if (requirePatient && !hardEligibilityContext)
1992
2017
  throw new Error(`useEligibilityInputField("${field}") requires a HardEligibilityContext`);
@@ -2028,16 +2053,23 @@ function useEligibilityInputField(field) {
2028
2053
  default:
2029
2054
  throw new Error(`Unknown field: ${field}`);
2030
2055
  }
2031
- return (0, import_react13.useMemo)(
2056
+ const setValue = set;
2057
+ const hasSetDefaultValue = (0, import_react14.useRef)(false);
2058
+ (0, import_react14.useLayoutEffect)(() => {
2059
+ if (hasSetDefaultValue.current) return;
2060
+ if (defaultValue) setValue(defaultValue);
2061
+ hasSetDefaultValue.current = true;
2062
+ }, [setValue, defaultValue]);
2063
+ return (0, import_react14.useMemo)(
2032
2064
  () => ({
2033
2065
  value,
2034
- setValue: set,
2066
+ setValue,
2035
2067
  isVisible,
2036
2068
  isValid,
2037
2069
  isRequired,
2038
2070
  isDisabled
2039
2071
  }),
2040
- [value, set, isVisible, isValid, isRequired, isDisabled]
2072
+ [value, setValue, isVisible, isValid, isRequired, isDisabled]
2041
2073
  );
2042
2074
  }
2043
2075
 
@@ -2062,7 +2094,7 @@ function useHardEligibilitySubmit() {
2062
2094
  const usesExistingPolicy = session.usesExistingPolicy;
2063
2095
  const inputIsValid = usesExistingPolicy ? Boolean(state.value) : useEligibilityInputIsValid();
2064
2096
  const isDisabled = !inputIsValid || !import_sdk_core9.HardEligibility.canSubmit(status);
2065
- const submit = (0, import_react14.useCallback)(
2097
+ const submit = (0, import_react15.useCallback)(
2066
2098
  ({ clinicalInfo } = {}) => {
2067
2099
  if (!state.value) throw new Error("State is required");
2068
2100
  const submitArgs = {
@@ -2085,15 +2117,49 @@ function useHardEligibilitySubmit() {
2085
2117
  },
2086
2118
  [session, state, payer, firstName, lastName, dateOfBirth, memberId]
2087
2119
  );
2088
- return (0, import_react14.useMemo)(() => ({ isDisabled, submit }), [isDisabled, submit]);
2120
+ return (0, import_react15.useMemo)(() => ({ isDisabled, submit }), [isDisabled, submit]);
2121
+ }
2122
+
2123
+ // src/eligibility-input/eligibility-input-analytics.tsx
2124
+ var import_react16 = require("react");
2125
+ function useEligibilityInputFieldState(field) {
2126
+ const fieldState = useEligibilityInputField(field);
2127
+ return (0, import_react16.useMemo)(
2128
+ () => omit_default(fieldState, "setValue"),
2129
+ [
2130
+ fieldState.value,
2131
+ fieldState.isVisible,
2132
+ fieldState.isValid,
2133
+ fieldState.isRequired,
2134
+ fieldState.isDisabled
2135
+ ]
2136
+ );
2089
2137
  }
2138
+ var EligibilityInputAnalytics = () => {
2139
+ const { _analytics: analytics } = useBridgeSdk();
2140
+ const firstName = useEligibilityInputFieldState("firstName");
2141
+ const lastName = useEligibilityInputFieldState("lastName");
2142
+ const dateOfBirth = useEligibilityInputFieldState("dateOfBirth");
2143
+ const memberId = useEligibilityInputFieldState("memberId");
2144
+ const payer = useEligibilityInputFieldState("payer");
2145
+ const state = useEligibilityInputFieldState("state");
2146
+ const isValid = useEligibilityInputIsValid();
2147
+ const payload = (0, import_react16.useMemo)(
2148
+ () => ({ firstName, lastName, dateOfBirth, memberId, payer, state, isValid }),
2149
+ [firstName, lastName, dateOfBirth, memberId, payer, state, isValid]
2150
+ );
2151
+ (0, import_react16.useEffect)(() => {
2152
+ analytics.event("input.state.updated", payload);
2153
+ }, [analytics, payload]);
2154
+ return null;
2155
+ };
2090
2156
 
2091
2157
  // src/eligibility-input/eligibility-input-provider.tsx
2092
2158
  var import_jsx_runtime3 = require("react/jsx-runtime");
2093
2159
  var EligibilityInputProvider = ({ children }) => {
2094
- const storeRef = (0, import_react15.useRef)(null);
2095
- const softEligibilityContext = (0, import_react15.useContext)(SoftEligibilityContext);
2096
- const hardEligibilityContext = (0, import_react15.useContext)(HardEligibilityContext);
2160
+ const storeRef = (0, import_react17.useRef)(null);
2161
+ const softEligibilityContext = (0, import_react17.useContext)(SoftEligibilityContext);
2162
+ const hardEligibilityContext = (0, import_react17.useContext)(HardEligibilityContext);
2097
2163
  if (!storeRef.current) {
2098
2164
  let requirePatient;
2099
2165
  if (softEligibilityContext) requirePatient = false;
@@ -2101,7 +2167,10 @@ var EligibilityInputProvider = ({ children }) => {
2101
2167
  else throw new Error("Missing SoftEligibilityContext or HardEligibilityContext");
2102
2168
  storeRef.current = createEligibilityInputStore(requirePatient);
2103
2169
  }
2104
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(EligibilityInputContext.Provider, { value: storeRef.current, children });
2170
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(EligibilityInputContext.Provider, { value: storeRef.current, children: [
2171
+ children,
2172
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(EligibilityInputAnalytics, {})
2173
+ ] });
2105
2174
  };
2106
2175
 
2107
2176
  // src/soft-eligibility/soft-eligibility-provider.tsx
@@ -2112,24 +2181,24 @@ var SoftEligibilityProvider = ({
2112
2181
  }) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(SoftEligibilityContext.Provider, { value: session, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(EligibilityInputProvider, { children }) });
2113
2182
 
2114
2183
  // src/soft-eligibility/use-create-soft-eligibility-session.ts
2115
- var import_react17 = require("react");
2184
+ var import_react19 = require("react");
2116
2185
  function useCreateSoftEligibilitySession() {
2117
2186
  const bridgeSdk = useBridgeSdk();
2118
- return (0, import_react17.useCallback)(
2187
+ return (0, import_react19.useCallback)(
2119
2188
  (...args) => bridgeSdk.createSoftEligibilitySession(...args),
2120
2189
  [bridgeSdk]
2121
2190
  );
2122
2191
  }
2123
2192
 
2124
2193
  // src/soft-eligibility/use-soft-eligibility-state.ts
2125
- var import_react19 = require("react");
2194
+ var import_react21 = require("react");
2126
2195
  var import_sdk_core12 = require("@usebridge/sdk-core");
2127
2196
 
2128
2197
  // src/soft-eligibility/use-soft-eligibility.ts
2129
- var import_react18 = require("react");
2198
+ var import_react20 = require("react");
2130
2199
  var import_sdk_core11 = require("@usebridge/sdk-core");
2131
2200
  function useSoftEligibilitySession() {
2132
- const session = (0, import_react18.useContext)(SoftEligibilityContext);
2201
+ const session = (0, import_react20.useContext)(SoftEligibilityContext);
2133
2202
  if (!session) throw new Error("useSoftEligibilitySession must be within a SoftEligibilityContext");
2134
2203
  return session;
2135
2204
  }
@@ -2137,8 +2206,8 @@ function useSoftEligibilitySession() {
2137
2206
  // src/soft-eligibility/use-soft-eligibility-state.ts
2138
2207
  function useSoftEligibilityState() {
2139
2208
  const session = useSoftEligibilitySession();
2140
- const [state, setState] = (0, import_react19.useState)(session.state);
2141
- (0, import_react19.useEffect)(() => {
2209
+ const [state, setState] = (0, import_react21.useState)(session.state);
2210
+ (0, import_react21.useEffect)(() => {
2142
2211
  session.on("update", setState);
2143
2212
  return () => {
2144
2213
  session.removeListener("update", setState);
@@ -2148,7 +2217,7 @@ function useSoftEligibilityState() {
2148
2217
  }
2149
2218
 
2150
2219
  // src/soft-eligibility/use-soft-eligibility-submit.ts
2151
- var import_react20 = require("react");
2220
+ var import_react22 = require("react");
2152
2221
  var import_sdk_core13 = require("@usebridge/sdk-core");
2153
2222
  function useSoftEligibilitySubmit() {
2154
2223
  const session = useSoftEligibilitySession();
@@ -2156,12 +2225,12 @@ function useSoftEligibilitySubmit() {
2156
2225
  const { status } = useSoftEligibilityState();
2157
2226
  const inputIsValid = useEligibilityInputIsValid();
2158
2227
  const isDisabled = !inputIsValid || !import_sdk_core13.SoftEligibility.canSubmit(status);
2159
- const submit = (0, import_react20.useCallback)(() => {
2228
+ const submit = (0, import_react22.useCallback)(() => {
2160
2229
  if (!payer.value) throw new Error("Payer is required");
2161
2230
  if (!state.value) throw new Error("State is required");
2162
2231
  return session.submit({ payerId: payer.value.id, state: state.value });
2163
2232
  }, [session, payer, state]);
2164
- return (0, import_react20.useMemo)(
2233
+ return (0, import_react22.useMemo)(
2165
2234
  () => ({
2166
2235
  isDisabled,
2167
2236
  submit