@fonderie/react-billing 0.1.0 → 0.3.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.d.cts CHANGED
@@ -6,23 +6,27 @@ interface IUseBillingPortalReturn {
6
6
  isLoading: boolean;
7
7
  error: FonderieApiError | null;
8
8
  }
9
- declare function useBillingPortal(client: BillingClient): IUseBillingPortalReturn;
9
+ declare function useBillingPortal(client?: BillingClient): IUseBillingPortalReturn;
10
10
 
11
11
  interface IUseCheckoutReturn {
12
12
  checkout: (input: ICheckoutInput) => Promise<string>;
13
13
  isLoading: boolean;
14
14
  error: FonderieApiError | null;
15
15
  }
16
- declare function useCheckout(client: BillingClient): IUseCheckoutReturn;
16
+ declare function useCheckout(client?: BillingClient): IUseCheckoutReturn;
17
17
 
18
18
  interface IUsePlanReturn {
19
19
  plan: IPlanDTO | null;
20
20
  isLoading: boolean;
21
21
  error: FonderieApiError | null;
22
- refresh: () => Promise<void>;
22
+ refresh: (opts?: {
23
+ force?: boolean;
24
+ }) => Promise<void>;
23
25
  }
24
- declare function usePlan(client: BillingClient, planId: string): IUsePlanReturn;
26
+ declare function usePlan(planId: string): IUsePlanReturn;
27
+ declare function usePlan(client: BillingClient | undefined, planId: string): IUsePlanReturn;
25
28
 
29
+ /** @deprecated Use `usePlans().createPlan` / `updatePlan` / `deletePlan` instead — the list hook self-refreshes after each write. */
26
30
  interface IUsePlanAdminReturn {
27
31
  createPlan: (input: ICreatePlanInput) => Promise<IPlanDTO>;
28
32
  updatePlan: (planId: string, input: IUpdatePlanInput) => Promise<IPlanDTO>;
@@ -30,37 +34,51 @@ interface IUsePlanAdminReturn {
30
34
  isLoading: boolean;
31
35
  error: FonderieApiError | null;
32
36
  }
33
- declare function usePlanAdmin(client: BillingClient): IUsePlanAdminReturn;
37
+ /** @deprecated Use `usePlans().createPlan` / `updatePlan` / `deletePlan` instead — the list hook self-refreshes after each write. */
38
+ declare function usePlanAdmin(client?: BillingClient): IUsePlanAdminReturn;
34
39
 
35
40
  interface IUsePlansReturn {
36
41
  plans: IPlanDTO[];
37
42
  isLoading: boolean;
38
43
  error: FonderieApiError | null;
39
- refresh: () => Promise<void>;
44
+ refresh: (opts?: {
45
+ force?: boolean;
46
+ }) => Promise<void>;
47
+ createPlan: (input: ICreatePlanInput) => Promise<IPlanDTO>;
48
+ updatePlan: (planId: string, input: IUpdatePlanInput) => Promise<IPlanDTO>;
49
+ deletePlan: (planId: string) => Promise<void>;
40
50
  }
41
- declare function usePlans(client: BillingClient): IUsePlansReturn;
51
+ declare function usePlans(client?: BillingClient): IUsePlansReturn;
42
52
 
53
+ /** @deprecated Use `useUsage(metric).recordUsage` instead — the usage hook self-refreshes after the write. */
43
54
  interface IUseRecordUsageReturn {
44
55
  recordUsage: (input: IRecordUsageInput) => Promise<void>;
45
56
  isLoading: boolean;
46
57
  error: FonderieApiError | null;
47
58
  }
48
- declare function useRecordUsage(client: BillingClient): IUseRecordUsageReturn;
59
+ /** @deprecated Use `useUsage(metric).recordUsage` instead — the usage hook self-refreshes after the write. */
60
+ declare function useRecordUsage(client?: BillingClient): IUseRecordUsageReturn;
49
61
 
50
62
  interface IUseSubscriptionReturn {
51
63
  subscription: ISubscriptionDTO | null;
52
64
  isLoading: boolean;
53
65
  error: FonderieApiError | null;
54
- refresh: () => Promise<void>;
66
+ refresh: (opts?: {
67
+ force?: boolean;
68
+ }) => Promise<void>;
55
69
  }
56
- declare function useSubscription(client: BillingClient): IUseSubscriptionReturn;
70
+ declare function useSubscription(client?: BillingClient): IUseSubscriptionReturn;
57
71
 
58
72
  interface IUseUsageReturn {
59
73
  total: number | null;
60
74
  isLoading: boolean;
61
75
  error: FonderieApiError | null;
62
- refresh: () => Promise<void>;
76
+ refresh: (opts?: {
77
+ force?: boolean;
78
+ }) => Promise<void>;
79
+ recordUsage: (input: IRecordUsageInput) => Promise<void>;
63
80
  }
64
- declare function useUsage(client: BillingClient, metric: string): IUseUsageReturn;
81
+ declare function useUsage(metric: string): IUseUsageReturn;
82
+ declare function useUsage(client: BillingClient | undefined, metric: string): IUseUsageReturn;
65
83
 
66
84
  export { type IUseBillingPortalReturn, type IUseCheckoutReturn, type IUsePlanAdminReturn, type IUsePlanReturn, type IUsePlansReturn, type IUseRecordUsageReturn, type IUseSubscriptionReturn, type IUseUsageReturn, useBillingPortal, useCheckout, usePlan, usePlanAdmin, usePlans, useRecordUsage, useSubscription, useUsage };
package/dist/index.d.ts CHANGED
@@ -6,23 +6,27 @@ interface IUseBillingPortalReturn {
6
6
  isLoading: boolean;
7
7
  error: FonderieApiError | null;
8
8
  }
9
- declare function useBillingPortal(client: BillingClient): IUseBillingPortalReturn;
9
+ declare function useBillingPortal(client?: BillingClient): IUseBillingPortalReturn;
10
10
 
11
11
  interface IUseCheckoutReturn {
12
12
  checkout: (input: ICheckoutInput) => Promise<string>;
13
13
  isLoading: boolean;
14
14
  error: FonderieApiError | null;
15
15
  }
16
- declare function useCheckout(client: BillingClient): IUseCheckoutReturn;
16
+ declare function useCheckout(client?: BillingClient): IUseCheckoutReturn;
17
17
 
18
18
  interface IUsePlanReturn {
19
19
  plan: IPlanDTO | null;
20
20
  isLoading: boolean;
21
21
  error: FonderieApiError | null;
22
- refresh: () => Promise<void>;
22
+ refresh: (opts?: {
23
+ force?: boolean;
24
+ }) => Promise<void>;
23
25
  }
24
- declare function usePlan(client: BillingClient, planId: string): IUsePlanReturn;
26
+ declare function usePlan(planId: string): IUsePlanReturn;
27
+ declare function usePlan(client: BillingClient | undefined, planId: string): IUsePlanReturn;
25
28
 
29
+ /** @deprecated Use `usePlans().createPlan` / `updatePlan` / `deletePlan` instead — the list hook self-refreshes after each write. */
26
30
  interface IUsePlanAdminReturn {
27
31
  createPlan: (input: ICreatePlanInput) => Promise<IPlanDTO>;
28
32
  updatePlan: (planId: string, input: IUpdatePlanInput) => Promise<IPlanDTO>;
@@ -30,37 +34,51 @@ interface IUsePlanAdminReturn {
30
34
  isLoading: boolean;
31
35
  error: FonderieApiError | null;
32
36
  }
33
- declare function usePlanAdmin(client: BillingClient): IUsePlanAdminReturn;
37
+ /** @deprecated Use `usePlans().createPlan` / `updatePlan` / `deletePlan` instead — the list hook self-refreshes after each write. */
38
+ declare function usePlanAdmin(client?: BillingClient): IUsePlanAdminReturn;
34
39
 
35
40
  interface IUsePlansReturn {
36
41
  plans: IPlanDTO[];
37
42
  isLoading: boolean;
38
43
  error: FonderieApiError | null;
39
- refresh: () => Promise<void>;
44
+ refresh: (opts?: {
45
+ force?: boolean;
46
+ }) => Promise<void>;
47
+ createPlan: (input: ICreatePlanInput) => Promise<IPlanDTO>;
48
+ updatePlan: (planId: string, input: IUpdatePlanInput) => Promise<IPlanDTO>;
49
+ deletePlan: (planId: string) => Promise<void>;
40
50
  }
41
- declare function usePlans(client: BillingClient): IUsePlansReturn;
51
+ declare function usePlans(client?: BillingClient): IUsePlansReturn;
42
52
 
53
+ /** @deprecated Use `useUsage(metric).recordUsage` instead — the usage hook self-refreshes after the write. */
43
54
  interface IUseRecordUsageReturn {
44
55
  recordUsage: (input: IRecordUsageInput) => Promise<void>;
45
56
  isLoading: boolean;
46
57
  error: FonderieApiError | null;
47
58
  }
48
- declare function useRecordUsage(client: BillingClient): IUseRecordUsageReturn;
59
+ /** @deprecated Use `useUsage(metric).recordUsage` instead — the usage hook self-refreshes after the write. */
60
+ declare function useRecordUsage(client?: BillingClient): IUseRecordUsageReturn;
49
61
 
50
62
  interface IUseSubscriptionReturn {
51
63
  subscription: ISubscriptionDTO | null;
52
64
  isLoading: boolean;
53
65
  error: FonderieApiError | null;
54
- refresh: () => Promise<void>;
66
+ refresh: (opts?: {
67
+ force?: boolean;
68
+ }) => Promise<void>;
55
69
  }
56
- declare function useSubscription(client: BillingClient): IUseSubscriptionReturn;
70
+ declare function useSubscription(client?: BillingClient): IUseSubscriptionReturn;
57
71
 
58
72
  interface IUseUsageReturn {
59
73
  total: number | null;
60
74
  isLoading: boolean;
61
75
  error: FonderieApiError | null;
62
- refresh: () => Promise<void>;
76
+ refresh: (opts?: {
77
+ force?: boolean;
78
+ }) => Promise<void>;
79
+ recordUsage: (input: IRecordUsageInput) => Promise<void>;
63
80
  }
64
- declare function useUsage(client: BillingClient, metric: string): IUseUsageReturn;
81
+ declare function useUsage(metric: string): IUseUsageReturn;
82
+ declare function useUsage(client: BillingClient | undefined, metric: string): IUseUsageReturn;
65
83
 
66
84
  export { type IUseBillingPortalReturn, type IUseCheckoutReturn, type IUsePlanAdminReturn, type IUsePlanReturn, type IUsePlansReturn, type IUseRecordUsageReturn, type IUseSubscriptionReturn, type IUseUsageReturn, useBillingPortal, useCheckout, usePlan, usePlanAdmin, usePlans, useRecordUsage, useSubscription, useUsage };
package/dist/index.js CHANGED
@@ -3,15 +3,17 @@ import { FonderieApiError as FonderieApiError9 } from "@fonderie/client";
3
3
 
4
4
  // src/hooks/useBillingPortal.ts
5
5
  import { FonderieApiError } from "@fonderie/client";
6
+ import { useFonderieSubClient } from "@fonderie/react";
6
7
  import { useCallback, useState } from "react";
7
8
  function useBillingPortal(client) {
9
+ const billing = useFonderieSubClient(client, (c) => c.billing, "useBillingPortal");
8
10
  const [isLoading, setIsLoading] = useState(false);
9
11
  const [error, setError] = useState(null);
10
12
  const openPortal = useCallback(async () => {
11
13
  setIsLoading(true);
12
14
  setError(null);
13
15
  try {
14
- const { result } = await client.createPortalSession();
16
+ const { result } = await billing.createPortalSession();
15
17
  return result.url;
16
18
  } catch (err) {
17
19
  const apiError = err instanceof FonderieApiError ? err : new FonderieApiError("unknown", String(err), 0);
@@ -20,14 +22,16 @@ function useBillingPortal(client) {
20
22
  } finally {
21
23
  setIsLoading(false);
22
24
  }
23
- }, [client]);
25
+ }, [billing]);
24
26
  return { openPortal, isLoading, error };
25
27
  }
26
28
 
27
29
  // src/hooks/useCheckout.ts
28
30
  import { FonderieApiError as FonderieApiError2 } from "@fonderie/client";
31
+ import { useFonderieSubClient as useFonderieSubClient2 } from "@fonderie/react";
29
32
  import { useCallback as useCallback2, useState as useState2 } from "react";
30
33
  function useCheckout(client) {
34
+ const billing = useFonderieSubClient2(client, (c) => c.billing, "useCheckout");
31
35
  const [isLoading, setIsLoading] = useState2(false);
32
36
  const [error, setError] = useState2(null);
33
37
  const checkout = useCallback2(
@@ -35,7 +39,7 @@ function useCheckout(client) {
35
39
  setIsLoading(true);
36
40
  setError(null);
37
41
  try {
38
- const { result } = await client.createCheckoutSession(input);
42
+ const { result } = await billing.createCheckoutSession(input);
39
43
  return result.url;
40
44
  } catch (err) {
41
45
  const apiError = err instanceof FonderieApiError2 ? err : new FonderieApiError2("unknown", String(err), 0);
@@ -45,31 +49,39 @@ function useCheckout(client) {
45
49
  setIsLoading(false);
46
50
  }
47
51
  },
48
- [client]
52
+ [billing]
49
53
  );
50
54
  return { checkout, isLoading, error };
51
55
  }
52
56
 
53
57
  // src/hooks/usePlan.ts
54
- import { FonderieApiError as FonderieApiError3 } from "@fonderie/client";
58
+ import { BillingClient, FonderieApiError as FonderieApiError3 } from "@fonderie/client";
59
+ import { useFonderieSubClient as useFonderieSubClient3 } from "@fonderie/react";
55
60
  import { useCallback as useCallback3, useEffect, useState as useState3 } from "react";
56
- function usePlan(client, planId) {
61
+ function usePlan(clientOrPlanId, maybePlanId) {
62
+ const firstIsClient = clientOrPlanId === void 0 || clientOrPlanId instanceof BillingClient;
63
+ const explicit = firstIsClient ? clientOrPlanId : void 0;
64
+ const planId = firstIsClient ? maybePlanId : clientOrPlanId;
65
+ const billing = useFonderieSubClient3(explicit, (c) => c.billing, "usePlan");
57
66
  const [plan, setPlan] = useState3(null);
58
67
  const [isLoading, setIsLoading] = useState3(true);
59
68
  const [error, setError] = useState3(null);
60
- const refresh = useCallback3(async () => {
61
- setIsLoading(true);
62
- setError(null);
63
- try {
64
- const { result } = await client.getPlan(planId);
65
- setPlan(result.plan);
66
- } catch (err) {
67
- const apiError = err instanceof FonderieApiError3 ? err : new FonderieApiError3("unknown", String(err), 0);
68
- setError(apiError);
69
- } finally {
70
- setIsLoading(false);
71
- }
72
- }, [client, planId]);
69
+ const refresh = useCallback3(
70
+ async (opts) => {
71
+ setIsLoading(true);
72
+ setError(null);
73
+ try {
74
+ const { result } = await billing.getPlan(planId, { bust: opts?.force });
75
+ setPlan(result.plan);
76
+ } catch (err) {
77
+ const apiError = err instanceof FonderieApiError3 ? err : new FonderieApiError3("unknown", String(err), 0);
78
+ setError(apiError);
79
+ } finally {
80
+ setIsLoading(false);
81
+ }
82
+ },
83
+ [billing, planId]
84
+ );
73
85
  useEffect(() => {
74
86
  void refresh();
75
87
  }, [refresh]);
@@ -78,8 +90,10 @@ function usePlan(client, planId) {
78
90
 
79
91
  // src/hooks/usePlanAdmin.ts
80
92
  import { FonderieApiError as FonderieApiError4 } from "@fonderie/client";
93
+ import { useFonderieSubClient as useFonderieSubClient4 } from "@fonderie/react";
81
94
  import { useCallback as useCallback4, useState as useState4 } from "react";
82
95
  function usePlanAdmin(client) {
96
+ const billing = useFonderieSubClient4(client, (c) => c.billing, "usePlanAdmin");
83
97
  const [isLoading, setIsLoading] = useState4(false);
84
98
  const [error, setError] = useState4(null);
85
99
  const createPlan = useCallback4(
@@ -87,7 +101,7 @@ function usePlanAdmin(client) {
87
101
  setIsLoading(true);
88
102
  setError(null);
89
103
  try {
90
- const { result } = await client.createPlan(input);
104
+ const { result } = await billing.createPlan(input);
91
105
  return result.plan;
92
106
  } catch (err) {
93
107
  const apiError = err instanceof FonderieApiError4 ? err : new FonderieApiError4("unknown", String(err), 0);
@@ -97,14 +111,14 @@ function usePlanAdmin(client) {
97
111
  setIsLoading(false);
98
112
  }
99
113
  },
100
- [client]
114
+ [billing]
101
115
  );
102
116
  const updatePlan = useCallback4(
103
117
  async (planId, input) => {
104
118
  setIsLoading(true);
105
119
  setError(null);
106
120
  try {
107
- const { result } = await client.updatePlan(planId, input);
121
+ const { result } = await billing.updatePlan(planId, input);
108
122
  return result.plan;
109
123
  } catch (err) {
110
124
  const apiError = err instanceof FonderieApiError4 ? err : new FonderieApiError4("unknown", String(err), 0);
@@ -114,14 +128,14 @@ function usePlanAdmin(client) {
114
128
  setIsLoading(false);
115
129
  }
116
130
  },
117
- [client]
131
+ [billing]
118
132
  );
119
133
  const deletePlan = useCallback4(
120
134
  async (planId) => {
121
135
  setIsLoading(true);
122
136
  setError(null);
123
137
  try {
124
- await client.deletePlan(planId);
138
+ await billing.deletePlan(planId);
125
139
  } catch (err) {
126
140
  const apiError = err instanceof FonderieApiError4 ? err : new FonderieApiError4("unknown", String(err), 0);
127
141
  setError(apiError);
@@ -130,41 +144,92 @@ function usePlanAdmin(client) {
130
144
  setIsLoading(false);
131
145
  }
132
146
  },
133
- [client]
147
+ [billing]
134
148
  );
135
149
  return { createPlan, updatePlan, deletePlan, isLoading, error };
136
150
  }
137
151
 
138
152
  // src/hooks/usePlans.ts
139
153
  import { FonderieApiError as FonderieApiError5 } from "@fonderie/client";
154
+ import { useFonderieSubClient as useFonderieSubClient5 } from "@fonderie/react";
140
155
  import { useCallback as useCallback5, useEffect as useEffect2, useState as useState5 } from "react";
141
156
  function usePlans(client) {
157
+ const billing = useFonderieSubClient5(client, (c) => c.billing, "usePlans");
142
158
  const [plans, setPlans] = useState5([]);
143
159
  const [isLoading, setIsLoading] = useState5(true);
144
160
  const [error, setError] = useState5(null);
145
- const refresh = useCallback5(async () => {
146
- setIsLoading(true);
147
- setError(null);
148
- try {
149
- const { result } = await client.listPlans();
150
- setPlans(result.plans);
151
- } catch (err) {
152
- const apiError = err instanceof FonderieApiError5 ? err : new FonderieApiError5("unknown", String(err), 0);
153
- setError(apiError);
154
- } finally {
155
- setIsLoading(false);
156
- }
157
- }, [client]);
161
+ const refresh = useCallback5(
162
+ async (opts) => {
163
+ setIsLoading(true);
164
+ setError(null);
165
+ try {
166
+ const { result } = await billing.listPlans({ bust: opts?.force });
167
+ setPlans(result.plans);
168
+ } catch (err) {
169
+ const apiError = err instanceof FonderieApiError5 ? err : new FonderieApiError5("unknown", String(err), 0);
170
+ setError(apiError);
171
+ } finally {
172
+ setIsLoading(false);
173
+ }
174
+ },
175
+ [billing]
176
+ );
177
+ const createPlan = useCallback5(
178
+ async (input) => {
179
+ setError(null);
180
+ try {
181
+ const { result } = await billing.createPlan(input);
182
+ await refresh();
183
+ return result.plan;
184
+ } catch (err) {
185
+ const apiError = err instanceof FonderieApiError5 ? err : new FonderieApiError5("unknown", String(err), 0);
186
+ setError(apiError);
187
+ throw apiError;
188
+ }
189
+ },
190
+ [billing, refresh]
191
+ );
192
+ const updatePlan = useCallback5(
193
+ async (planId, input) => {
194
+ setError(null);
195
+ try {
196
+ const { result } = await billing.updatePlan(planId, input);
197
+ await refresh();
198
+ return result.plan;
199
+ } catch (err) {
200
+ const apiError = err instanceof FonderieApiError5 ? err : new FonderieApiError5("unknown", String(err), 0);
201
+ setError(apiError);
202
+ throw apiError;
203
+ }
204
+ },
205
+ [billing, refresh]
206
+ );
207
+ const deletePlan = useCallback5(
208
+ async (planId) => {
209
+ setError(null);
210
+ try {
211
+ await billing.deletePlan(planId);
212
+ await refresh();
213
+ } catch (err) {
214
+ const apiError = err instanceof FonderieApiError5 ? err : new FonderieApiError5("unknown", String(err), 0);
215
+ setError(apiError);
216
+ throw apiError;
217
+ }
218
+ },
219
+ [billing, refresh]
220
+ );
158
221
  useEffect2(() => {
159
222
  void refresh();
160
223
  }, [refresh]);
161
- return { plans, isLoading, error, refresh };
224
+ return { plans, isLoading, error, refresh, createPlan, updatePlan, deletePlan };
162
225
  }
163
226
 
164
227
  // src/hooks/useRecordUsage.ts
165
228
  import { FonderieApiError as FonderieApiError6 } from "@fonderie/client";
229
+ import { useFonderieSubClient as useFonderieSubClient6 } from "@fonderie/react";
166
230
  import { useCallback as useCallback6, useState as useState6 } from "react";
167
231
  function useRecordUsage(client) {
232
+ const billing = useFonderieSubClient6(client, (c) => c.billing, "useRecordUsage");
168
233
  const [isLoading, setIsLoading] = useState6(false);
169
234
  const [error, setError] = useState6(null);
170
235
  const recordUsage = useCallback6(
@@ -172,7 +237,7 @@ function useRecordUsage(client) {
172
237
  setIsLoading(true);
173
238
  setError(null);
174
239
  try {
175
- await client.recordUsage(input);
240
+ await billing.recordUsage(input);
176
241
  } catch (err) {
177
242
  const apiError = err instanceof FonderieApiError6 ? err : new FonderieApiError6("unknown", String(err), 0);
178
243
  setError(apiError);
@@ -181,32 +246,37 @@ function useRecordUsage(client) {
181
246
  setIsLoading(false);
182
247
  }
183
248
  },
184
- [client]
249
+ [billing]
185
250
  );
186
251
  return { recordUsage, isLoading, error };
187
252
  }
188
253
 
189
254
  // src/hooks/useSubscription.ts
190
255
  import { FonderieApiError as FonderieApiError7 } from "@fonderie/client";
256
+ import { useFonderieSubClient as useFonderieSubClient7 } from "@fonderie/react";
191
257
  import { useCallback as useCallback7, useEffect as useEffect3, useState as useState7 } from "react";
192
258
  function useSubscription(client) {
259
+ const billing = useFonderieSubClient7(client, (c) => c.billing, "useSubscription");
193
260
  const [subscription, setSubscription] = useState7(null);
194
261
  const [isLoading, setIsLoading] = useState7(true);
195
262
  const [error, setError] = useState7(null);
196
- const refresh = useCallback7(async () => {
197
- setIsLoading(true);
198
- setError(null);
199
- try {
200
- const { result } = await client.getSubscription();
201
- setSubscription(result.subscription);
202
- } catch (err) {
203
- const apiError = err instanceof FonderieApiError7 ? err : new FonderieApiError7("unknown", String(err), 0);
204
- if (apiError.status !== 404) setError(apiError);
205
- setSubscription(null);
206
- } finally {
207
- setIsLoading(false);
208
- }
209
- }, [client]);
263
+ const refresh = useCallback7(
264
+ async (opts) => {
265
+ setIsLoading(true);
266
+ setError(null);
267
+ try {
268
+ const { result } = await billing.getSubscription({ bust: opts?.force });
269
+ setSubscription(result.subscription);
270
+ } catch (err) {
271
+ const apiError = err instanceof FonderieApiError7 ? err : new FonderieApiError7("unknown", String(err), 0);
272
+ if (apiError.status !== 404) setError(apiError);
273
+ setSubscription(null);
274
+ } finally {
275
+ setIsLoading(false);
276
+ }
277
+ },
278
+ [billing]
279
+ );
210
280
  useEffect3(() => {
211
281
  void refresh();
212
282
  }, [refresh]);
@@ -214,29 +284,51 @@ function useSubscription(client) {
214
284
  }
215
285
 
216
286
  // src/hooks/useUsage.ts
217
- import { FonderieApiError as FonderieApiError8 } from "@fonderie/client";
287
+ import { BillingClient as BillingClient2, FonderieApiError as FonderieApiError8 } from "@fonderie/client";
288
+ import { useFonderieSubClient as useFonderieSubClient8 } from "@fonderie/react";
218
289
  import { useCallback as useCallback8, useEffect as useEffect4, useState as useState8 } from "react";
219
- function useUsage(client, metric) {
290
+ function useUsage(clientOrMetric, maybeMetric) {
291
+ const firstIsClient = clientOrMetric === void 0 || clientOrMetric instanceof BillingClient2;
292
+ const explicit = firstIsClient ? clientOrMetric : void 0;
293
+ const metric = firstIsClient ? maybeMetric : clientOrMetric;
294
+ const billing = useFonderieSubClient8(explicit, (c) => c.billing, "useUsage");
220
295
  const [total, setTotal] = useState8(null);
221
296
  const [isLoading, setIsLoading] = useState8(true);
222
297
  const [error, setError] = useState8(null);
223
- const refresh = useCallback8(async () => {
224
- setIsLoading(true);
225
- setError(null);
226
- try {
227
- const { result } = await client.getUsage(metric);
228
- setTotal(result.total);
229
- } catch (err) {
230
- const apiError = err instanceof FonderieApiError8 ? err : new FonderieApiError8("unknown", String(err), 0);
231
- setError(apiError);
232
- } finally {
233
- setIsLoading(false);
234
- }
235
- }, [client, metric]);
298
+ const refresh = useCallback8(
299
+ async (opts) => {
300
+ setIsLoading(true);
301
+ setError(null);
302
+ try {
303
+ const { result } = await billing.getUsage(metric, { bust: opts?.force });
304
+ setTotal(result.total);
305
+ } catch (err) {
306
+ const apiError = err instanceof FonderieApiError8 ? err : new FonderieApiError8("unknown", String(err), 0);
307
+ setError(apiError);
308
+ } finally {
309
+ setIsLoading(false);
310
+ }
311
+ },
312
+ [billing, metric]
313
+ );
314
+ const recordUsage = useCallback8(
315
+ async (input) => {
316
+ setError(null);
317
+ try {
318
+ await billing.recordUsage(input);
319
+ await refresh();
320
+ } catch (err) {
321
+ const apiError = err instanceof FonderieApiError8 ? err : new FonderieApiError8("unknown", String(err), 0);
322
+ setError(apiError);
323
+ throw apiError;
324
+ }
325
+ },
326
+ [billing, refresh]
327
+ );
236
328
  useEffect4(() => {
237
329
  void refresh();
238
330
  }, [refresh]);
239
- return { total, isLoading, error, refresh };
331
+ return { total, isLoading, error, refresh, recordUsage };
240
332
  }
241
333
  export {
242
334
  FonderieApiError9 as FonderieApiError,