@sudobility/consumables_client 0.0.2
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/CLAUDE.md +69 -0
- package/dist/adapters/index.d.ts +3 -0
- package/dist/adapters/index.d.ts.map +1 -0
- package/dist/adapters/index.js +3 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/adapters/revenuecat-rn.d.ts +7 -0
- package/dist/adapters/revenuecat-rn.d.ts.map +1 -0
- package/dist/adapters/revenuecat-rn.js +129 -0
- package/dist/adapters/revenuecat-rn.js.map +1 -0
- package/dist/adapters/revenuecat-web.d.ts +7 -0
- package/dist/adapters/revenuecat-web.d.ts.map +1 -0
- package/dist/adapters/revenuecat-web.js +143 -0
- package/dist/adapters/revenuecat-web.js.map +1 -0
- package/dist/core/index.d.ts +3 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +3 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/service.d.ts +31 -0
- package/dist/core/service.d.ts.map +1 -0
- package/dist/core/service.js +92 -0
- package/dist/core/service.js.map +1 -0
- package/dist/core/singleton.d.ts +18 -0
- package/dist/core/singleton.d.ts.map +1 -0
- package/dist/core/singleton.js +74 -0
- package/dist/core/singleton.js.map +1 -0
- package/dist/hooks/index.d.ts +6 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +6 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/hooks/useBalance.d.ts +9 -0
- package/dist/hooks/useBalance.d.ts.map +1 -0
- package/dist/hooks/useBalance.js +53 -0
- package/dist/hooks/useBalance.js.map +1 -0
- package/dist/hooks/useConsumableProducts.d.ts +9 -0
- package/dist/hooks/useConsumableProducts.d.ts.map +1 -0
- package/dist/hooks/useConsumableProducts.js +32 -0
- package/dist/hooks/useConsumableProducts.js.map +1 -0
- package/dist/hooks/usePurchaseCredits.d.ts +7 -0
- package/dist/hooks/usePurchaseCredits.d.ts.map +1 -0
- package/dist/hooks/usePurchaseCredits.js +29 -0
- package/dist/hooks/usePurchaseCredits.js.map +1 -0
- package/dist/hooks/usePurchaseHistory.d.ts +10 -0
- package/dist/hooks/usePurchaseHistory.d.ts.map +1 -0
- package/dist/hooks/usePurchaseHistory.js +48 -0
- package/dist/hooks/usePurchaseHistory.js.map +1 -0
- package/dist/hooks/useUsageHistory.d.ts +10 -0
- package/dist/hooks/useUsageHistory.d.ts.map +1 -0
- package/dist/hooks/useUsageHistory.js +48 -0
- package/dist/hooks/useUsageHistory.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/network/ConsumablesApiClient.d.ts +28 -0
- package/dist/network/ConsumablesApiClient.d.ts.map +1 -0
- package/dist/network/ConsumablesApiClient.js +55 -0
- package/dist/network/ConsumablesApiClient.js.map +1 -0
- package/dist/types/adapter.d.ts +25 -0
- package/dist/types/adapter.d.ts.map +1 -0
- package/dist/types/adapter.js +2 -0
- package/dist/types/adapter.js.map +1 -0
- package/dist/types/index.d.ts +22 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -0
- package/package.json +65 -0
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { ConsumablesService } from "./service";
|
|
2
|
+
let instance = null;
|
|
3
|
+
let currentAdapter = null;
|
|
4
|
+
let currentUserId = undefined;
|
|
5
|
+
const balanceChangeListeners = [];
|
|
6
|
+
const userIdChangeListeners = [];
|
|
7
|
+
export function initializeConsumables(config) {
|
|
8
|
+
currentAdapter = config.adapter;
|
|
9
|
+
instance = new ConsumablesService({
|
|
10
|
+
adapter: config.adapter,
|
|
11
|
+
apiClient: config.apiClient,
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
export function getConsumablesInstance() {
|
|
15
|
+
if (!instance) {
|
|
16
|
+
throw new Error("Consumables not initialized. Call initializeConsumables() first.");
|
|
17
|
+
}
|
|
18
|
+
return instance;
|
|
19
|
+
}
|
|
20
|
+
export function isConsumablesInitialized() {
|
|
21
|
+
return instance !== null;
|
|
22
|
+
}
|
|
23
|
+
export function resetConsumables() {
|
|
24
|
+
instance = null;
|
|
25
|
+
currentAdapter = null;
|
|
26
|
+
currentUserId = undefined;
|
|
27
|
+
}
|
|
28
|
+
export async function refreshConsumablesBalance() {
|
|
29
|
+
if (!instance)
|
|
30
|
+
return;
|
|
31
|
+
await instance.loadBalance();
|
|
32
|
+
for (const listener of balanceChangeListeners) {
|
|
33
|
+
listener();
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
export async function setConsumablesUserId(userId, email) {
|
|
37
|
+
if (currentUserId === userId)
|
|
38
|
+
return;
|
|
39
|
+
currentUserId = userId;
|
|
40
|
+
if (currentAdapter?.setUserId) {
|
|
41
|
+
await currentAdapter.setUserId(userId, email);
|
|
42
|
+
}
|
|
43
|
+
if (instance) {
|
|
44
|
+
instance.clearCache();
|
|
45
|
+
}
|
|
46
|
+
for (const listener of userIdChangeListeners) {
|
|
47
|
+
listener();
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
export function getConsumablesUserId() {
|
|
51
|
+
return currentUserId;
|
|
52
|
+
}
|
|
53
|
+
export function onConsumablesBalanceChange(listener) {
|
|
54
|
+
balanceChangeListeners.push(listener);
|
|
55
|
+
return () => {
|
|
56
|
+
const index = balanceChangeListeners.indexOf(listener);
|
|
57
|
+
if (index >= 0)
|
|
58
|
+
balanceChangeListeners.splice(index, 1);
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
export function onConsumablesUserIdChange(listener) {
|
|
62
|
+
userIdChangeListeners.push(listener);
|
|
63
|
+
return () => {
|
|
64
|
+
const index = userIdChangeListeners.indexOf(listener);
|
|
65
|
+
if (index >= 0)
|
|
66
|
+
userIdChangeListeners.splice(index, 1);
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
export function notifyBalanceChange() {
|
|
70
|
+
for (const listener of balanceChangeListeners) {
|
|
71
|
+
listener();
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=singleton.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"singleton.js","sourceRoot":"","sources":["../../src/core/singleton.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAO/C,IAAI,QAAQ,GAA8B,IAAI,CAAC;AAC/C,IAAI,cAAc,GAA8B,IAAI,CAAC;AACrD,IAAI,aAAa,GAAuB,SAAS,CAAC;AAClD,MAAM,sBAAsB,GAAsB,EAAE,CAAC;AACrD,MAAM,qBAAqB,GAAsB,EAAE,CAAC;AAGpD,MAAM,UAAU,qBAAqB,CAAC,MAAyB;IAC7D,cAAc,GAAG,MAAM,CAAC,OAAO,CAAC;IAChC,QAAQ,GAAG,IAAI,kBAAkB,CAAC;QAChC,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,SAAS,EAAE,MAAM,CAAC,SAAS;KAC5B,CAAC,CAAC;AACL,CAAC;AAGD,MAAM,UAAU,sBAAsB;IACpC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CACb,kEAAkE,CACnE,CAAC;IACJ,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAGD,MAAM,UAAU,wBAAwB;IACtC,OAAO,QAAQ,KAAK,IAAI,CAAC;AAC3B,CAAC;AAGD,MAAM,UAAU,gBAAgB;IAC9B,QAAQ,GAAG,IAAI,CAAC;IAChB,cAAc,GAAG,IAAI,CAAC;IACtB,aAAa,GAAG,SAAS,CAAC;AAC5B,CAAC;AAGD,MAAM,CAAC,KAAK,UAAU,yBAAyB;IAC7C,IAAI,CAAC,QAAQ;QAAE,OAAO;IACtB,MAAM,QAAQ,CAAC,WAAW,EAAE,CAAC;IAC7B,KAAK,MAAM,QAAQ,IAAI,sBAAsB,EAAE,CAAC;QAC9C,QAAQ,EAAE,CAAC;IACb,CAAC;AACH,CAAC;AAMD,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,MAA0B,EAC1B,KAAc;IAEd,IAAI,aAAa,KAAK,MAAM;QAAE,OAAO;IAErC,aAAa,GAAG,MAAM,CAAC;IAEvB,IAAI,cAAc,EAAE,SAAS,EAAE,CAAC;QAC9B,MAAM,cAAc,CAAC,SAAS,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAChD,CAAC;IAED,IAAI,QAAQ,EAAE,CAAC;QACb,QAAQ,CAAC,UAAU,EAAE,CAAC;IACxB,CAAC;IAED,KAAK,MAAM,QAAQ,IAAI,qBAAqB,EAAE,CAAC;QAC7C,QAAQ,EAAE,CAAC;IACb,CAAC;AACH,CAAC;AAGD,MAAM,UAAU,oBAAoB;IAClC,OAAO,aAAa,CAAC;AACvB,CAAC;AAGD,MAAM,UAAU,0BAA0B,CAAC,QAAoB;IAC7D,sBAAsB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACtC,OAAO,GAAG,EAAE;QACV,MAAM,KAAK,GAAG,sBAAsB,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACvD,IAAI,KAAK,IAAI,CAAC;YAAE,sBAAsB,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IAC1D,CAAC,CAAC;AACJ,CAAC;AAGD,MAAM,UAAU,yBAAyB,CAAC,QAAoB;IAC5D,qBAAqB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACrC,OAAO,GAAG,EAAE;QACV,MAAM,KAAK,GAAG,qBAAqB,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACtD,IAAI,KAAK,IAAI,CAAC;YAAE,qBAAqB,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IACzD,CAAC,CAAC;AACJ,CAAC;AAGD,MAAM,UAAU,mBAAmB;IACjC,KAAK,MAAM,QAAQ,IAAI,sBAAsB,EAAE,CAAC;QAC9C,QAAQ,EAAE,CAAC;IACb,CAAC;AACH,CAAC","sourcesContent":["import type { ConsumablesAdapter } from \"../types/adapter\";\nimport type { ConsumablesApiClient } from \"../network/ConsumablesApiClient\";\nimport { ConsumablesService } from \"./service\";\n\nexport interface ConsumablesConfig {\n adapter: ConsumablesAdapter;\n apiClient: ConsumablesApiClient;\n}\n\nlet instance: ConsumablesService | null = null;\nlet currentAdapter: ConsumablesAdapter | null = null;\nlet currentUserId: string | undefined = undefined;\nconst balanceChangeListeners: Array<() => void> = [];\nconst userIdChangeListeners: Array<() => void> = [];\n\n/** Initialize the consumables singleton. Call once at app startup. */\nexport function initializeConsumables(config: ConsumablesConfig): void {\n currentAdapter = config.adapter;\n instance = new ConsumablesService({\n adapter: config.adapter,\n apiClient: config.apiClient,\n });\n}\n\n/** Get the consumables service singleton. Throws if not initialized. */\nexport function getConsumablesInstance(): ConsumablesService {\n if (!instance) {\n throw new Error(\n \"Consumables not initialized. Call initializeConsumables() first.\",\n );\n }\n return instance;\n}\n\n/** Check if consumables singleton is initialized. */\nexport function isConsumablesInitialized(): boolean {\n return instance !== null;\n}\n\n/** Reset the singleton (mainly for testing). */\nexport function resetConsumables(): void {\n instance = null;\n currentAdapter = null;\n currentUserId = undefined;\n}\n\n/** Refresh balance from server and notify listeners. */\nexport async function refreshConsumablesBalance(): Promise<void> {\n if (!instance) return;\n await instance.loadBalance();\n for (const listener of balanceChangeListeners) {\n listener();\n }\n}\n\n/**\n * Set the user ID for the consumables service.\n * Clears cached balance and re-initializes RevenueCat adapter.\n */\nexport async function setConsumablesUserId(\n userId: string | undefined,\n email?: string,\n): Promise<void> {\n if (currentUserId === userId) return;\n\n currentUserId = userId;\n\n if (currentAdapter?.setUserId) {\n await currentAdapter.setUserId(userId, email);\n }\n\n if (instance) {\n instance.clearCache();\n }\n\n for (const listener of userIdChangeListeners) {\n listener();\n }\n}\n\n/** Get the current user ID. */\nexport function getConsumablesUserId(): string | undefined {\n return currentUserId;\n}\n\n/** Subscribe to balance changes. Returns unsubscribe function. */\nexport function onConsumablesBalanceChange(listener: () => void): () => void {\n balanceChangeListeners.push(listener);\n return () => {\n const index = balanceChangeListeners.indexOf(listener);\n if (index >= 0) balanceChangeListeners.splice(index, 1);\n };\n}\n\n/** Subscribe to user ID changes. Returns unsubscribe function. */\nexport function onConsumablesUserIdChange(listener: () => void): () => void {\n userIdChangeListeners.push(listener);\n return () => {\n const index = userIdChangeListeners.indexOf(listener);\n if (index >= 0) userIdChangeListeners.splice(index, 1);\n };\n}\n\n/** Notify balance change listeners (call after purchase/usage). */\nexport function notifyBalanceChange(): void {\n for (const listener of balanceChangeListeners) {\n listener();\n }\n}\n"]}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { useBalance, type UseBalanceResult } from "./useBalance";
|
|
2
|
+
export { useConsumableProducts, type UseConsumableProductsResult, } from "./useConsumableProducts";
|
|
3
|
+
export { usePurchaseCredits, type UsePurchaseCreditsResult, } from "./usePurchaseCredits";
|
|
4
|
+
export { usePurchaseHistory, type UsePurchaseHistoryResult, } from "./usePurchaseHistory";
|
|
5
|
+
export { useUsageHistory, type UseUsageHistoryResult } from "./useUsageHistory";
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,KAAK,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACjE,OAAO,EACL,qBAAqB,EACrB,KAAK,2BAA2B,GACjC,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,kBAAkB,EAClB,KAAK,wBAAwB,GAC9B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,kBAAkB,EAClB,KAAK,wBAAwB,GAC9B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,eAAe,EAAE,KAAK,qBAAqB,EAAE,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { useBalance } from "./useBalance";
|
|
2
|
+
export { useConsumableProducts, } from "./useConsumableProducts";
|
|
3
|
+
export { usePurchaseCredits, } from "./usePurchaseCredits";
|
|
4
|
+
export { usePurchaseHistory, } from "./usePurchaseHistory";
|
|
5
|
+
export { useUsageHistory } from "./useUsageHistory";
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAyB,MAAM,cAAc,CAAC;AACjE,OAAO,EACL,qBAAqB,GAEtB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,kBAAkB,GAEnB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,kBAAkB,GAEnB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,eAAe,EAA8B,MAAM,mBAAmB,CAAC","sourcesContent":["export { useBalance, type UseBalanceResult } from \"./useBalance\";\nexport {\n useConsumableProducts,\n type UseConsumableProductsResult,\n} from \"./useConsumableProducts\";\nexport {\n usePurchaseCredits,\n type UsePurchaseCreditsResult,\n} from \"./usePurchaseCredits\";\nexport {\n usePurchaseHistory,\n type UsePurchaseHistoryResult,\n} from \"./usePurchaseHistory\";\nexport { useUsageHistory, type UseUsageHistoryResult } from \"./useUsageHistory\";\n"]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export interface UseBalanceResult {
|
|
2
|
+
balance: number | null;
|
|
3
|
+
initialCredits: number | null;
|
|
4
|
+
isLoading: boolean;
|
|
5
|
+
error: Error | null;
|
|
6
|
+
refetch: () => Promise<void>;
|
|
7
|
+
}
|
|
8
|
+
export declare function useBalance(): UseBalanceResult;
|
|
9
|
+
//# sourceMappingURL=useBalance.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useBalance.d.ts","sourceRoot":"","sources":["../../src/hooks/useBalance.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B;AAED,wBAAgB,UAAU,IAAI,gBAAgB,CAoD7C"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { useCallback, useEffect, useState } from "react";
|
|
2
|
+
import { getConsumablesInstance, getConsumablesUserId, isConsumablesInitialized, onConsumablesBalanceChange, onConsumablesUserIdChange, } from "../core/singleton";
|
|
3
|
+
export function useBalance() {
|
|
4
|
+
const [balance, setBalance] = useState(null);
|
|
5
|
+
const [initialCredits, setInitialCredits] = useState(null);
|
|
6
|
+
const [isLoading, setIsLoading] = useState(true);
|
|
7
|
+
const [error, setError] = useState(null);
|
|
8
|
+
const loadBalance = useCallback(async () => {
|
|
9
|
+
if (!isConsumablesInitialized() || !getConsumablesUserId()) {
|
|
10
|
+
setBalance(null);
|
|
11
|
+
setInitialCredits(null);
|
|
12
|
+
setIsLoading(false);
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
setIsLoading(true);
|
|
16
|
+
setError(null);
|
|
17
|
+
try {
|
|
18
|
+
const instance = getConsumablesInstance();
|
|
19
|
+
const result = await instance.loadBalance();
|
|
20
|
+
setBalance(result.balance);
|
|
21
|
+
setInitialCredits(result.initialCredits);
|
|
22
|
+
}
|
|
23
|
+
catch (err) {
|
|
24
|
+
setError(err instanceof Error ? err : new Error(String(err)));
|
|
25
|
+
}
|
|
26
|
+
finally {
|
|
27
|
+
setIsLoading(false);
|
|
28
|
+
}
|
|
29
|
+
}, []);
|
|
30
|
+
useEffect(() => {
|
|
31
|
+
loadBalance();
|
|
32
|
+
}, [loadBalance]);
|
|
33
|
+
useEffect(() => {
|
|
34
|
+
const unsubBalance = onConsumablesBalanceChange(() => {
|
|
35
|
+
if (isConsumablesInitialized()) {
|
|
36
|
+
const cached = getConsumablesInstance().getCachedBalance();
|
|
37
|
+
if (cached) {
|
|
38
|
+
setBalance(cached.balance);
|
|
39
|
+
setInitialCredits(cached.initialCredits);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
const unsubUser = onConsumablesUserIdChange(() => {
|
|
44
|
+
loadBalance();
|
|
45
|
+
});
|
|
46
|
+
return () => {
|
|
47
|
+
unsubBalance();
|
|
48
|
+
unsubUser();
|
|
49
|
+
};
|
|
50
|
+
}, [loadBalance]);
|
|
51
|
+
return { balance, initialCredits, isLoading, error, refetch: loadBalance };
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=useBalance.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useBalance.js","sourceRoot":"","sources":["../../src/hooks/useBalance.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACzD,OAAO,EACL,sBAAsB,EACtB,oBAAoB,EACpB,wBAAwB,EACxB,0BAA0B,EAC1B,yBAAyB,GAC1B,MAAM,mBAAmB,CAAC;AAU3B,MAAM,UAAU,UAAU;IACxB,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;IAC5D,MAAM,CAAC,cAAc,EAAE,iBAAiB,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;IAC1E,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IACjD,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAe,IAAI,CAAC,CAAC;IAEvD,MAAM,WAAW,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;QACzC,IAAI,CAAC,wBAAwB,EAAE,IAAI,CAAC,oBAAoB,EAAE,EAAE,CAAC;YAC3D,UAAU,CAAC,IAAI,CAAC,CAAC;YACjB,iBAAiB,CAAC,IAAI,CAAC,CAAC;YACxB,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,OAAO;QACT,CAAC;QAED,YAAY,CAAC,IAAI,CAAC,CAAC;QACnB,QAAQ,CAAC,IAAI,CAAC,CAAC;QACf,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,sBAAsB,EAAE,CAAC;YAC1C,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,WAAW,EAAE,CAAC;YAC5C,UAAU,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YAC3B,iBAAiB,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;QAC3C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,QAAQ,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAChE,CAAC;gBAAS,CAAC;YACT,YAAY,CAAC,KAAK,CAAC,CAAC;QACtB,CAAC;IACH,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,SAAS,CAAC,GAAG,EAAE;QACb,WAAW,EAAE,CAAC;IAChB,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;IAElB,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,YAAY,GAAG,0BAA0B,CAAC,GAAG,EAAE;YACnD,IAAI,wBAAwB,EAAE,EAAE,CAAC;gBAC/B,MAAM,MAAM,GAAG,sBAAsB,EAAE,CAAC,gBAAgB,EAAE,CAAC;gBAC3D,IAAI,MAAM,EAAE,CAAC;oBACX,UAAU,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;oBAC3B,iBAAiB,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;gBAC3C,CAAC;YACH,CAAC;QACH,CAAC,CAAC,CAAC;QACH,MAAM,SAAS,GAAG,yBAAyB,CAAC,GAAG,EAAE;YAC/C,WAAW,EAAE,CAAC;QAChB,CAAC,CAAC,CAAC;QACH,OAAO,GAAG,EAAE;YACV,YAAY,EAAE,CAAC;YACf,SAAS,EAAE,CAAC;QACd,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;IAElB,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC;AAC7E,CAAC","sourcesContent":["import { useCallback, useEffect, useState } from \"react\";\nimport {\n getConsumablesInstance,\n getConsumablesUserId,\n isConsumablesInitialized,\n onConsumablesBalanceChange,\n onConsumablesUserIdChange,\n} from \"../core/singleton\";\n\nexport interface UseBalanceResult {\n balance: number | null;\n initialCredits: number | null;\n isLoading: boolean;\n error: Error | null;\n refetch: () => Promise<void>;\n}\n\nexport function useBalance(): UseBalanceResult {\n const [balance, setBalance] = useState<number | null>(null);\n const [initialCredits, setInitialCredits] = useState<number | null>(null);\n const [isLoading, setIsLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n\n const loadBalance = useCallback(async () => {\n if (!isConsumablesInitialized() || !getConsumablesUserId()) {\n setBalance(null);\n setInitialCredits(null);\n setIsLoading(false);\n return;\n }\n\n setIsLoading(true);\n setError(null);\n try {\n const instance = getConsumablesInstance();\n const result = await instance.loadBalance();\n setBalance(result.balance);\n setInitialCredits(result.initialCredits);\n } catch (err) {\n setError(err instanceof Error ? err : new Error(String(err)));\n } finally {\n setIsLoading(false);\n }\n }, []);\n\n useEffect(() => {\n loadBalance();\n }, [loadBalance]);\n\n useEffect(() => {\n const unsubBalance = onConsumablesBalanceChange(() => {\n if (isConsumablesInitialized()) {\n const cached = getConsumablesInstance().getCachedBalance();\n if (cached) {\n setBalance(cached.balance);\n setInitialCredits(cached.initialCredits);\n }\n }\n });\n const unsubUser = onConsumablesUserIdChange(() => {\n loadBalance();\n });\n return () => {\n unsubBalance();\n unsubUser();\n };\n }, [loadBalance]);\n\n return { balance, initialCredits, isLoading, error, refetch: loadBalance };\n}\n"]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { CreditPackage } from "../types";
|
|
2
|
+
export interface UseConsumableProductsResult {
|
|
3
|
+
packages: CreditPackage[];
|
|
4
|
+
isLoading: boolean;
|
|
5
|
+
error: Error | null;
|
|
6
|
+
refetch: () => Promise<void>;
|
|
7
|
+
}
|
|
8
|
+
export declare function useConsumableProducts(offeringId: string): UseConsumableProductsResult;
|
|
9
|
+
//# sourceMappingURL=useConsumableProducts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useConsumableProducts.d.ts","sourceRoot":"","sources":["../../src/hooks/useConsumableProducts.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B;AAED,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,MAAM,GACjB,2BAA2B,CA8B7B"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { useCallback, useEffect, useState } from "react";
|
|
2
|
+
import { getConsumablesInstance, isConsumablesInitialized, } from "../core/singleton";
|
|
3
|
+
export function useConsumableProducts(offeringId) {
|
|
4
|
+
const [packages, setPackages] = useState([]);
|
|
5
|
+
const [isLoading, setIsLoading] = useState(true);
|
|
6
|
+
const [error, setError] = useState(null);
|
|
7
|
+
const loadProducts = useCallback(async () => {
|
|
8
|
+
if (!isConsumablesInitialized()) {
|
|
9
|
+
setIsLoading(false);
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
setIsLoading(true);
|
|
13
|
+
setError(null);
|
|
14
|
+
try {
|
|
15
|
+
const instance = getConsumablesInstance();
|
|
16
|
+
await instance.loadOfferings();
|
|
17
|
+
const offering = instance.getOffering(offeringId);
|
|
18
|
+
setPackages(offering?.packages ?? []);
|
|
19
|
+
}
|
|
20
|
+
catch (err) {
|
|
21
|
+
setError(err instanceof Error ? err : new Error(String(err)));
|
|
22
|
+
}
|
|
23
|
+
finally {
|
|
24
|
+
setIsLoading(false);
|
|
25
|
+
}
|
|
26
|
+
}, [offeringId]);
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
loadProducts();
|
|
29
|
+
}, [loadProducts]);
|
|
30
|
+
return { packages, isLoading, error, refetch: loadProducts };
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=useConsumableProducts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useConsumableProducts.js","sourceRoot":"","sources":["../../src/hooks/useConsumableProducts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACzD,OAAO,EACL,sBAAsB,EACtB,wBAAwB,GACzB,MAAM,mBAAmB,CAAC;AAU3B,MAAM,UAAU,qBAAqB,CACnC,UAAkB;IAElB,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAkB,EAAE,CAAC,CAAC;IAC9D,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IACjD,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAe,IAAI,CAAC,CAAC;IAEvD,MAAM,YAAY,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;QAC1C,IAAI,CAAC,wBAAwB,EAAE,EAAE,CAAC;YAChC,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,OAAO;QACT,CAAC;QAED,YAAY,CAAC,IAAI,CAAC,CAAC;QACnB,QAAQ,CAAC,IAAI,CAAC,CAAC;QACf,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,sBAAsB,EAAE,CAAC;YAC1C,MAAM,QAAQ,CAAC,aAAa,EAAE,CAAC;YAC/B,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;YAClD,WAAW,CAAC,QAAQ,EAAE,QAAQ,IAAI,EAAE,CAAC,CAAC;QACxC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,QAAQ,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAChE,CAAC;gBAAS,CAAC;YACT,YAAY,CAAC,KAAK,CAAC,CAAC;QACtB,CAAC;IACH,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;IAEjB,SAAS,CAAC,GAAG,EAAE;QACb,YAAY,EAAE,CAAC;IACjB,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC;IAEnB,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC;AAC/D,CAAC","sourcesContent":["import { useCallback, useEffect, useState } from \"react\";\nimport {\n getConsumablesInstance,\n isConsumablesInitialized,\n} from \"../core/singleton\";\nimport type { CreditPackage } from \"../types\";\n\nexport interface UseConsumableProductsResult {\n packages: CreditPackage[];\n isLoading: boolean;\n error: Error | null;\n refetch: () => Promise<void>;\n}\n\nexport function useConsumableProducts(\n offeringId: string,\n): UseConsumableProductsResult {\n const [packages, setPackages] = useState<CreditPackage[]>([]);\n const [isLoading, setIsLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n\n const loadProducts = useCallback(async () => {\n if (!isConsumablesInitialized()) {\n setIsLoading(false);\n return;\n }\n\n setIsLoading(true);\n setError(null);\n try {\n const instance = getConsumablesInstance();\n await instance.loadOfferings();\n const offering = instance.getOffering(offeringId);\n setPackages(offering?.packages ?? []);\n } catch (err) {\n setError(err instanceof Error ? err : new Error(String(err)));\n } finally {\n setIsLoading(false);\n }\n }, [offeringId]);\n\n useEffect(() => {\n loadProducts();\n }, [loadProducts]);\n\n return { packages, isLoading, error, refetch: loadProducts };\n}\n"]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export interface UsePurchaseCreditsResult {
|
|
2
|
+
purchase: (packageId: string, offeringId: string) => Promise<boolean>;
|
|
3
|
+
isPurchasing: boolean;
|
|
4
|
+
error: Error | null;
|
|
5
|
+
}
|
|
6
|
+
export declare function usePurchaseCredits(): UsePurchaseCreditsResult;
|
|
7
|
+
//# sourceMappingURL=usePurchaseCredits.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usePurchaseCredits.d.ts","sourceRoot":"","sources":["../../src/hooks/usePurchaseCredits.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,wBAAwB;IACvC,QAAQ,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACtE,YAAY,EAAE,OAAO,CAAC;IACtB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;CACrB;AAED,wBAAgB,kBAAkB,IAAI,wBAAwB,CA6B7D"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { useCallback, useState } from "react";
|
|
2
|
+
import { getConsumablesInstance, isConsumablesInitialized, notifyBalanceChange, } from "../core/singleton";
|
|
3
|
+
export function usePurchaseCredits() {
|
|
4
|
+
const [isPurchasing, setIsPurchasing] = useState(false);
|
|
5
|
+
const [error, setError] = useState(null);
|
|
6
|
+
const purchase = useCallback(async (packageId, offeringId) => {
|
|
7
|
+
if (!isConsumablesInitialized()) {
|
|
8
|
+
setError(new Error("Consumables not initialized"));
|
|
9
|
+
return false;
|
|
10
|
+
}
|
|
11
|
+
setIsPurchasing(true);
|
|
12
|
+
setError(null);
|
|
13
|
+
try {
|
|
14
|
+
const instance = getConsumablesInstance();
|
|
15
|
+
await instance.purchase({ packageId, offeringId });
|
|
16
|
+
notifyBalanceChange();
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
catch (err) {
|
|
20
|
+
setError(err instanceof Error ? err : new Error(String(err)));
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
finally {
|
|
24
|
+
setIsPurchasing(false);
|
|
25
|
+
}
|
|
26
|
+
}, []);
|
|
27
|
+
return { purchase, isPurchasing, error };
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=usePurchaseCredits.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usePurchaseCredits.js","sourceRoot":"","sources":["../../src/hooks/usePurchaseCredits.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC9C,OAAO,EACL,sBAAsB,EACtB,wBAAwB,EACxB,mBAAmB,GACpB,MAAM,mBAAmB,CAAC;AAQ3B,MAAM,UAAU,kBAAkB;IAChC,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IACxD,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAe,IAAI,CAAC,CAAC;IAEvD,MAAM,QAAQ,GAAG,WAAW,CAC1B,KAAK,EAAE,SAAiB,EAAE,UAAkB,EAAoB,EAAE;QAChE,IAAI,CAAC,wBAAwB,EAAE,EAAE,CAAC;YAChC,QAAQ,CAAC,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC,CAAC;YACnD,OAAO,KAAK,CAAC;QACf,CAAC;QAED,eAAe,CAAC,IAAI,CAAC,CAAC;QACtB,QAAQ,CAAC,IAAI,CAAC,CAAC;QACf,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,sBAAsB,EAAE,CAAC;YAC1C,MAAM,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC,CAAC;YACnD,mBAAmB,EAAE,CAAC;YACtB,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,QAAQ,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YAC9D,OAAO,KAAK,CAAC;QACf,CAAC;gBAAS,CAAC;YACT,eAAe,CAAC,KAAK,CAAC,CAAC;QACzB,CAAC;IACH,CAAC,EACD,EAAE,CACH,CAAC;IAEF,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC;AAC3C,CAAC","sourcesContent":["import { useCallback, useState } from \"react\";\nimport {\n getConsumablesInstance,\n isConsumablesInitialized,\n notifyBalanceChange,\n} from \"../core/singleton\";\n\nexport interface UsePurchaseCreditsResult {\n purchase: (packageId: string, offeringId: string) => Promise<boolean>;\n isPurchasing: boolean;\n error: Error | null;\n}\n\nexport function usePurchaseCredits(): UsePurchaseCreditsResult {\n const [isPurchasing, setIsPurchasing] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const purchase = useCallback(\n async (packageId: string, offeringId: string): Promise<boolean> => {\n if (!isConsumablesInitialized()) {\n setError(new Error(\"Consumables not initialized\"));\n return false;\n }\n\n setIsPurchasing(true);\n setError(null);\n try {\n const instance = getConsumablesInstance();\n await instance.purchase({ packageId, offeringId });\n notifyBalanceChange();\n return true;\n } catch (err) {\n setError(err instanceof Error ? err : new Error(String(err)));\n return false;\n } finally {\n setIsPurchasing(false);\n }\n },\n [],\n );\n\n return { purchase, isPurchasing, error };\n}\n"]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { CreditPurchaseRecord } from "../types";
|
|
2
|
+
export interface UsePurchaseHistoryResult {
|
|
3
|
+
purchases: CreditPurchaseRecord[];
|
|
4
|
+
isLoading: boolean;
|
|
5
|
+
error: Error | null;
|
|
6
|
+
loadMore: () => Promise<void>;
|
|
7
|
+
refetch: () => Promise<void>;
|
|
8
|
+
}
|
|
9
|
+
export declare function usePurchaseHistory(limit?: number): UsePurchaseHistoryResult;
|
|
10
|
+
//# sourceMappingURL=usePurchaseHistory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usePurchaseHistory.d.ts","sourceRoot":"","sources":["../../src/hooks/usePurchaseHistory.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAErD,MAAM,WAAW,wBAAwB;IACvC,SAAS,EAAE,oBAAoB,EAAE,CAAC;IAClC,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9B,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B;AAED,wBAAgB,kBAAkB,CAAC,KAAK,SAAK,GAAG,wBAAwB,CA8CvE"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { useCallback, useEffect, useState } from "react";
|
|
2
|
+
import { getConsumablesInstance, getConsumablesUserId, isConsumablesInitialized, onConsumablesUserIdChange, } from "../core/singleton";
|
|
3
|
+
export function usePurchaseHistory(limit = 50) {
|
|
4
|
+
const [purchases, setPurchases] = useState([]);
|
|
5
|
+
const [isLoading, setIsLoading] = useState(true);
|
|
6
|
+
const [error, setError] = useState(null);
|
|
7
|
+
const load = useCallback(async () => {
|
|
8
|
+
if (!isConsumablesInitialized() || !getConsumablesUserId()) {
|
|
9
|
+
setPurchases([]);
|
|
10
|
+
setIsLoading(false);
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
setIsLoading(true);
|
|
14
|
+
setError(null);
|
|
15
|
+
try {
|
|
16
|
+
const instance = getConsumablesInstance();
|
|
17
|
+
const result = await instance.getPurchaseHistory(limit, 0);
|
|
18
|
+
setPurchases(result);
|
|
19
|
+
}
|
|
20
|
+
catch (err) {
|
|
21
|
+
setError(err instanceof Error ? err : new Error(String(err)));
|
|
22
|
+
}
|
|
23
|
+
finally {
|
|
24
|
+
setIsLoading(false);
|
|
25
|
+
}
|
|
26
|
+
}, [limit]);
|
|
27
|
+
const loadMore = useCallback(async () => {
|
|
28
|
+
if (!isConsumablesInitialized())
|
|
29
|
+
return;
|
|
30
|
+
try {
|
|
31
|
+
const instance = getConsumablesInstance();
|
|
32
|
+
const result = await instance.getPurchaseHistory(limit, purchases.length);
|
|
33
|
+
setPurchases((prev) => [...prev, ...result]);
|
|
34
|
+
}
|
|
35
|
+
catch (err) {
|
|
36
|
+
setError(err instanceof Error ? err : new Error(String(err)));
|
|
37
|
+
}
|
|
38
|
+
}, [limit, purchases.length]);
|
|
39
|
+
useEffect(() => {
|
|
40
|
+
load();
|
|
41
|
+
}, [load]);
|
|
42
|
+
useEffect(() => {
|
|
43
|
+
const unsub = onConsumablesUserIdChange(() => load());
|
|
44
|
+
return unsub;
|
|
45
|
+
}, [load]);
|
|
46
|
+
return { purchases, isLoading, error, loadMore, refetch: load };
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=usePurchaseHistory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usePurchaseHistory.js","sourceRoot":"","sources":["../../src/hooks/usePurchaseHistory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACzD,OAAO,EACL,sBAAsB,EACtB,oBAAoB,EACpB,wBAAwB,EACxB,yBAAyB,GAC1B,MAAM,mBAAmB,CAAC;AAW3B,MAAM,UAAU,kBAAkB,CAAC,KAAK,GAAG,EAAE;IAC3C,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAyB,EAAE,CAAC,CAAC;IACvE,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IACjD,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAe,IAAI,CAAC,CAAC;IAEvD,MAAM,IAAI,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;QAClC,IAAI,CAAC,wBAAwB,EAAE,IAAI,CAAC,oBAAoB,EAAE,EAAE,CAAC;YAC3D,YAAY,CAAC,EAAE,CAAC,CAAC;YACjB,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,OAAO;QACT,CAAC;QAED,YAAY,CAAC,IAAI,CAAC,CAAC;QACnB,QAAQ,CAAC,IAAI,CAAC,CAAC;QACf,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,sBAAsB,EAAE,CAAC;YAC1C,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,kBAAkB,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;YAC3D,YAAY,CAAC,MAAM,CAAC,CAAC;QACvB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,QAAQ,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAChE,CAAC;gBAAS,CAAC;YACT,YAAY,CAAC,KAAK,CAAC,CAAC;QACtB,CAAC;IACH,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;IAEZ,MAAM,QAAQ,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;QACtC,IAAI,CAAC,wBAAwB,EAAE;YAAE,OAAO;QACxC,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,sBAAsB,EAAE,CAAC;YAC1C,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,kBAAkB,CAAC,KAAK,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;YAC1E,YAAY,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC;QAC/C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,QAAQ,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAChE,CAAC;IACH,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;IAE9B,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,EAAE,CAAC;IACT,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;IAEX,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,KAAK,GAAG,yBAAyB,CAAC,GAAG,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC;QACtD,OAAO,KAAK,CAAC;IACf,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;IAEX,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AAClE,CAAC","sourcesContent":["import { useCallback, useEffect, useState } from \"react\";\nimport {\n getConsumablesInstance,\n getConsumablesUserId,\n isConsumablesInitialized,\n onConsumablesUserIdChange,\n} from \"../core/singleton\";\nimport type { CreditPurchaseRecord } from \"../types\";\n\nexport interface UsePurchaseHistoryResult {\n purchases: CreditPurchaseRecord[];\n isLoading: boolean;\n error: Error | null;\n loadMore: () => Promise<void>;\n refetch: () => Promise<void>;\n}\n\nexport function usePurchaseHistory(limit = 50): UsePurchaseHistoryResult {\n const [purchases, setPurchases] = useState<CreditPurchaseRecord[]>([]);\n const [isLoading, setIsLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n\n const load = useCallback(async () => {\n if (!isConsumablesInitialized() || !getConsumablesUserId()) {\n setPurchases([]);\n setIsLoading(false);\n return;\n }\n\n setIsLoading(true);\n setError(null);\n try {\n const instance = getConsumablesInstance();\n const result = await instance.getPurchaseHistory(limit, 0);\n setPurchases(result);\n } catch (err) {\n setError(err instanceof Error ? err : new Error(String(err)));\n } finally {\n setIsLoading(false);\n }\n }, [limit]);\n\n const loadMore = useCallback(async () => {\n if (!isConsumablesInitialized()) return;\n try {\n const instance = getConsumablesInstance();\n const result = await instance.getPurchaseHistory(limit, purchases.length);\n setPurchases((prev) => [...prev, ...result]);\n } catch (err) {\n setError(err instanceof Error ? err : new Error(String(err)));\n }\n }, [limit, purchases.length]);\n\n useEffect(() => {\n load();\n }, [load]);\n\n useEffect(() => {\n const unsub = onConsumablesUserIdChange(() => load());\n return unsub;\n }, [load]);\n\n return { purchases, isLoading, error, loadMore, refetch: load };\n}\n"]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { CreditUsageRecord } from "../types";
|
|
2
|
+
export interface UseUsageHistoryResult {
|
|
3
|
+
usages: CreditUsageRecord[];
|
|
4
|
+
isLoading: boolean;
|
|
5
|
+
error: Error | null;
|
|
6
|
+
loadMore: () => Promise<void>;
|
|
7
|
+
refetch: () => Promise<void>;
|
|
8
|
+
}
|
|
9
|
+
export declare function useUsageHistory(limit?: number): UseUsageHistoryResult;
|
|
10
|
+
//# sourceMappingURL=useUsageHistory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useUsageHistory.d.ts","sourceRoot":"","sources":["../../src/hooks/useUsageHistory.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAElD,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,iBAAiB,EAAE,CAAC;IAC5B,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9B,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B;AAED,wBAAgB,eAAe,CAAC,KAAK,SAAK,GAAG,qBAAqB,CA8CjE"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { useCallback, useEffect, useState } from "react";
|
|
2
|
+
import { getConsumablesInstance, getConsumablesUserId, isConsumablesInitialized, onConsumablesUserIdChange, } from "../core/singleton";
|
|
3
|
+
export function useUsageHistory(limit = 50) {
|
|
4
|
+
const [usages, setUsages] = useState([]);
|
|
5
|
+
const [isLoading, setIsLoading] = useState(true);
|
|
6
|
+
const [error, setError] = useState(null);
|
|
7
|
+
const load = useCallback(async () => {
|
|
8
|
+
if (!isConsumablesInitialized() || !getConsumablesUserId()) {
|
|
9
|
+
setUsages([]);
|
|
10
|
+
setIsLoading(false);
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
setIsLoading(true);
|
|
14
|
+
setError(null);
|
|
15
|
+
try {
|
|
16
|
+
const instance = getConsumablesInstance();
|
|
17
|
+
const result = await instance.getUsageHistory(limit, 0);
|
|
18
|
+
setUsages(result);
|
|
19
|
+
}
|
|
20
|
+
catch (err) {
|
|
21
|
+
setError(err instanceof Error ? err : new Error(String(err)));
|
|
22
|
+
}
|
|
23
|
+
finally {
|
|
24
|
+
setIsLoading(false);
|
|
25
|
+
}
|
|
26
|
+
}, [limit]);
|
|
27
|
+
const loadMore = useCallback(async () => {
|
|
28
|
+
if (!isConsumablesInitialized())
|
|
29
|
+
return;
|
|
30
|
+
try {
|
|
31
|
+
const instance = getConsumablesInstance();
|
|
32
|
+
const result = await instance.getUsageHistory(limit, usages.length);
|
|
33
|
+
setUsages((prev) => [...prev, ...result]);
|
|
34
|
+
}
|
|
35
|
+
catch (err) {
|
|
36
|
+
setError(err instanceof Error ? err : new Error(String(err)));
|
|
37
|
+
}
|
|
38
|
+
}, [limit, usages.length]);
|
|
39
|
+
useEffect(() => {
|
|
40
|
+
load();
|
|
41
|
+
}, [load]);
|
|
42
|
+
useEffect(() => {
|
|
43
|
+
const unsub = onConsumablesUserIdChange(() => load());
|
|
44
|
+
return unsub;
|
|
45
|
+
}, [load]);
|
|
46
|
+
return { usages, isLoading, error, loadMore, refetch: load };
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=useUsageHistory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useUsageHistory.js","sourceRoot":"","sources":["../../src/hooks/useUsageHistory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACzD,OAAO,EACL,sBAAsB,EACtB,oBAAoB,EACpB,wBAAwB,EACxB,yBAAyB,GAC1B,MAAM,mBAAmB,CAAC;AAW3B,MAAM,UAAU,eAAe,CAAC,KAAK,GAAG,EAAE;IACxC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAsB,EAAE,CAAC,CAAC;IAC9D,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IACjD,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAe,IAAI,CAAC,CAAC;IAEvD,MAAM,IAAI,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;QAClC,IAAI,CAAC,wBAAwB,EAAE,IAAI,CAAC,oBAAoB,EAAE,EAAE,CAAC;YAC3D,SAAS,CAAC,EAAE,CAAC,CAAC;YACd,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,OAAO;QACT,CAAC;QAED,YAAY,CAAC,IAAI,CAAC,CAAC;QACnB,QAAQ,CAAC,IAAI,CAAC,CAAC;QACf,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,sBAAsB,EAAE,CAAC;YAC1C,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,eAAe,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;YACxD,SAAS,CAAC,MAAM,CAAC,CAAC;QACpB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,QAAQ,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAChE,CAAC;gBAAS,CAAC;YACT,YAAY,CAAC,KAAK,CAAC,CAAC;QACtB,CAAC;IACH,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;IAEZ,MAAM,QAAQ,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;QACtC,IAAI,CAAC,wBAAwB,EAAE;YAAE,OAAO;QACxC,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,sBAAsB,EAAE,CAAC;YAC1C,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,eAAe,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;YACpE,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC;QAC5C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,QAAQ,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAChE,CAAC;IACH,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;IAE3B,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,EAAE,CAAC;IACT,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;IAEX,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,KAAK,GAAG,yBAAyB,CAAC,GAAG,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC;QACtD,OAAO,KAAK,CAAC;IACf,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;IAEX,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AAC/D,CAAC","sourcesContent":["import { useCallback, useEffect, useState } from \"react\";\nimport {\n getConsumablesInstance,\n getConsumablesUserId,\n isConsumablesInitialized,\n onConsumablesUserIdChange,\n} from \"../core/singleton\";\nimport type { CreditUsageRecord } from \"../types\";\n\nexport interface UseUsageHistoryResult {\n usages: CreditUsageRecord[];\n isLoading: boolean;\n error: Error | null;\n loadMore: () => Promise<void>;\n refetch: () => Promise<void>;\n}\n\nexport function useUsageHistory(limit = 50): UseUsageHistoryResult {\n const [usages, setUsages] = useState<CreditUsageRecord[]>([]);\n const [isLoading, setIsLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n\n const load = useCallback(async () => {\n if (!isConsumablesInitialized() || !getConsumablesUserId()) {\n setUsages([]);\n setIsLoading(false);\n return;\n }\n\n setIsLoading(true);\n setError(null);\n try {\n const instance = getConsumablesInstance();\n const result = await instance.getUsageHistory(limit, 0);\n setUsages(result);\n } catch (err) {\n setError(err instanceof Error ? err : new Error(String(err)));\n } finally {\n setIsLoading(false);\n }\n }, [limit]);\n\n const loadMore = useCallback(async () => {\n if (!isConsumablesInitialized()) return;\n try {\n const instance = getConsumablesInstance();\n const result = await instance.getUsageHistory(limit, usages.length);\n setUsages((prev) => [...prev, ...result]);\n } catch (err) {\n setError(err instanceof Error ? err : new Error(String(err)));\n }\n }, [limit, usages.length]);\n\n useEffect(() => {\n load();\n }, [load]);\n\n useEffect(() => {\n const unsub = onConsumablesUserIdChange(() => load());\n return unsub;\n }, [load]);\n\n return { usages, isLoading, error, loadMore, refetch: load };\n}\n"]}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { initializeConsumables, getConsumablesInstance, isConsumablesInitialized, resetConsumables, refreshConsumablesBalance, setConsumablesUserId, getConsumablesUserId, onConsumablesBalanceChange, onConsumablesUserIdChange, notifyBalanceChange, ConsumablesService, type ConsumablesConfig, type ConsumablesServiceConfig, } from "./core";
|
|
2
|
+
export { ConsumablesApiClient, type ConsumablesApiClientConfig, } from "./network/ConsumablesApiClient";
|
|
3
|
+
export { useBalance, useConsumableProducts, usePurchaseCredits, usePurchaseHistory, useUsageHistory, type UseBalanceResult, type UseConsumableProductsResult, type UsePurchaseCreditsResult, type UsePurchaseHistoryResult, type UseUsageHistoryResult, } from "./hooks";
|
|
4
|
+
export type { ConsumableSource, ConsumableBalanceResponse, ConsumablePurchaseRequest, ConsumableUseRequest, ConsumableUseResponse, ConsumablePurchaseRecord, ConsumableUsageRecord, CreditPurchaseRecord, CreditUsageRecord, } from "./types";
|
|
5
|
+
export type { ConsumablesAdapter, ConsumablePurchaseResult, ConsumablePurchaseParams, CreditPackage, CreditOffering, CreditBalance, } from "./types";
|
|
6
|
+
export { configureConsumablesWebAdapter, createConsumablesWebAdapter, setConsumablesWebUser, clearConsumablesWebUser, hasConsumablesWebUser, configureConsumablesRNAdapter, createConsumablesRNAdapter, setConsumablesRNUser, clearConsumablesRNUser, hasConsumablesRNUser, } from "./adapters";
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAQA,OAAO,EACL,qBAAqB,EACrB,sBAAsB,EACtB,wBAAwB,EACxB,gBAAgB,EAChB,yBAAyB,EACzB,oBAAoB,EACpB,oBAAoB,EACpB,0BAA0B,EAC1B,yBAAyB,EACzB,mBAAmB,EACnB,kBAAkB,EAClB,KAAK,iBAAiB,EACtB,KAAK,wBAAwB,GAC9B,MAAM,QAAQ,CAAC;AAGhB,OAAO,EACL,oBAAoB,EACpB,KAAK,0BAA0B,GAChC,MAAM,gCAAgC,CAAC;AAGxC,OAAO,EACL,UAAU,EACV,qBAAqB,EACrB,kBAAkB,EAClB,kBAAkB,EAClB,eAAe,EACf,KAAK,gBAAgB,EACrB,KAAK,2BAA2B,EAChC,KAAK,wBAAwB,EAC7B,KAAK,wBAAwB,EAC7B,KAAK,qBAAqB,GAC3B,MAAM,SAAS,CAAC;AAGjB,YAAY,EACV,gBAAgB,EAChB,yBAAyB,EACzB,yBAAyB,EACzB,oBAAoB,EACpB,qBAAqB,EACrB,wBAAwB,EACxB,qBAAqB,EAErB,oBAAoB,EACpB,iBAAiB,GAClB,MAAM,SAAS,CAAC;AAGjB,YAAY,EACV,kBAAkB,EAClB,wBAAwB,EACxB,wBAAwB,EACxB,aAAa,EACb,cAAc,EACd,aAAa,GACd,MAAM,SAAS,CAAC;AAGjB,OAAO,EACL,8BAA8B,EAC9B,2BAA2B,EAC3B,qBAAqB,EACrB,uBAAuB,EACvB,qBAAqB,EACrB,6BAA6B,EAC7B,0BAA0B,EAC1B,oBAAoB,EACpB,sBAAsB,EACtB,oBAAoB,GACrB,MAAM,YAAY,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { initializeConsumables, getConsumablesInstance, isConsumablesInitialized, resetConsumables, refreshConsumablesBalance, setConsumablesUserId, getConsumablesUserId, onConsumablesBalanceChange, onConsumablesUserIdChange, notifyBalanceChange, ConsumablesService, } from "./core";
|
|
2
|
+
export { ConsumablesApiClient, } from "./network/ConsumablesApiClient";
|
|
3
|
+
export { useBalance, useConsumableProducts, usePurchaseCredits, usePurchaseHistory, useUsageHistory, } from "./hooks";
|
|
4
|
+
export { configureConsumablesWebAdapter, createConsumablesWebAdapter, setConsumablesWebUser, clearConsumablesWebUser, hasConsumablesWebUser, configureConsumablesRNAdapter, createConsumablesRNAdapter, setConsumablesRNUser, clearConsumablesRNUser, hasConsumablesRNUser, } from "./adapters";
|
|
5
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAQA,OAAO,EACL,qBAAqB,EACrB,sBAAsB,EACtB,wBAAwB,EACxB,gBAAgB,EAChB,yBAAyB,EACzB,oBAAoB,EACpB,oBAAoB,EACpB,0BAA0B,EAC1B,yBAAyB,EACzB,mBAAmB,EACnB,kBAAkB,GAGnB,MAAM,QAAQ,CAAC;AAGhB,OAAO,EACL,oBAAoB,GAErB,MAAM,gCAAgC,CAAC;AAGxC,OAAO,EACL,UAAU,EACV,qBAAqB,EACrB,kBAAkB,EAClB,kBAAkB,EAClB,eAAe,GAMhB,MAAM,SAAS,CAAC;AA2BjB,OAAO,EACL,8BAA8B,EAC9B,2BAA2B,EAC3B,qBAAqB,EACrB,uBAAuB,EACvB,qBAAqB,EACrB,6BAA6B,EAC7B,0BAA0B,EAC1B,oBAAoB,EACpB,sBAAsB,EACtB,oBAAoB,GACrB,MAAM,YAAY,CAAC","sourcesContent":["/**\n * @sudobility/consumables_client\n *\n * Cross-platform consumable credits client with RevenueCat adapter pattern.\n * Works with both React (web) and React Native.\n */\n\n// Core\nexport {\n initializeConsumables,\n getConsumablesInstance,\n isConsumablesInitialized,\n resetConsumables,\n refreshConsumablesBalance,\n setConsumablesUserId,\n getConsumablesUserId,\n onConsumablesBalanceChange,\n onConsumablesUserIdChange,\n notifyBalanceChange,\n ConsumablesService,\n type ConsumablesConfig,\n type ConsumablesServiceConfig,\n} from \"./core\";\n\n// Network\nexport {\n ConsumablesApiClient,\n type ConsumablesApiClientConfig,\n} from \"./network/ConsumablesApiClient\";\n\n// Hooks\nexport {\n useBalance,\n useConsumableProducts,\n usePurchaseCredits,\n usePurchaseHistory,\n useUsageHistory,\n type UseBalanceResult,\n type UseConsumableProductsResult,\n type UsePurchaseCreditsResult,\n type UsePurchaseHistoryResult,\n type UseUsageHistoryResult,\n} from \"./hooks\";\n\n// Types (shared from @sudobility/types, re-exported via ./types)\nexport type {\n ConsumableSource,\n ConsumableBalanceResponse,\n ConsumablePurchaseRequest,\n ConsumableUseRequest,\n ConsumableUseResponse,\n ConsumablePurchaseRecord,\n ConsumableUsageRecord,\n // Backward-compat aliases\n CreditPurchaseRecord,\n CreditUsageRecord,\n} from \"./types\";\n\n// Types (client-only)\nexport type {\n ConsumablesAdapter,\n ConsumablePurchaseResult,\n ConsumablePurchaseParams,\n CreditPackage,\n CreditOffering,\n CreditBalance,\n} from \"./types\";\n\n// Adapters (platform-specific)\nexport {\n configureConsumablesWebAdapter,\n createConsumablesWebAdapter,\n setConsumablesWebUser,\n clearConsumablesWebUser,\n hasConsumablesWebUser,\n configureConsumablesRNAdapter,\n createConsumablesRNAdapter,\n setConsumablesRNUser,\n clearConsumablesRNUser,\n hasConsumablesRNUser,\n} from \"./adapters\";\n"]}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { CreditBalance, CreditPurchaseRecord, CreditUsageRecord } from "../types";
|
|
2
|
+
export interface ConsumablesApiClientConfig {
|
|
3
|
+
baseUrl: string;
|
|
4
|
+
getToken?: () => Promise<string | null>;
|
|
5
|
+
}
|
|
6
|
+
export declare class ConsumablesApiClient {
|
|
7
|
+
private baseUrl;
|
|
8
|
+
private getToken;
|
|
9
|
+
constructor(config: ConsumablesApiClientConfig);
|
|
10
|
+
private headers;
|
|
11
|
+
private request;
|
|
12
|
+
getBalance(): Promise<CreditBalance>;
|
|
13
|
+
recordPurchase(params: {
|
|
14
|
+
credits: number;
|
|
15
|
+
source: string;
|
|
16
|
+
transaction_ref_id?: string;
|
|
17
|
+
product_id?: string;
|
|
18
|
+
price_cents?: number;
|
|
19
|
+
currency?: string;
|
|
20
|
+
}): Promise<CreditBalance>;
|
|
21
|
+
recordUsage(filename?: string): Promise<{
|
|
22
|
+
balance: number;
|
|
23
|
+
success: boolean;
|
|
24
|
+
}>;
|
|
25
|
+
getPurchaseHistory(limit?: number, offset?: number): Promise<CreditPurchaseRecord[]>;
|
|
26
|
+
getUsageHistory(limit?: number, offset?: number): Promise<CreditUsageRecord[]>;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=ConsumablesApiClient.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ConsumablesApiClient.d.ts","sourceRoot":"","sources":["../../src/network/ConsumablesApiClient.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,oBAAoB,EACpB,iBAAiB,EAClB,MAAM,UAAU,CAAC;AAElB,MAAM,WAAW,0BAA0B;IACzC,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CACzC;AAED,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,QAAQ,CAA6C;gBAEjD,MAAM,EAAE,0BAA0B;YAKhC,OAAO;YASP,OAAO;IAWf,UAAU,IAAI,OAAO,CAAC,aAAa,CAAC;IAWpC,cAAc,CAAC,MAAM,EAAE;QAC3B,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,EAAE,MAAM,CAAC;QACf,kBAAkB,CAAC,EAAE,MAAM,CAAC;QAC5B,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,GAAG,OAAO,CAAC,aAAa,CAAC;IAcpB,WAAW,CACf,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;IAO3C,kBAAkB,CACtB,KAAK,SAAK,EACV,MAAM,SAAI,GACT,OAAO,CAAC,oBAAoB,EAAE,CAAC;IAM5B,eAAe,CAAC,KAAK,SAAK,EAAE,MAAM,SAAI,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC;CAK5E"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
export class ConsumablesApiClient {
|
|
2
|
+
constructor(config) {
|
|
3
|
+
this.baseUrl = config.baseUrl.replace(/\/$/, "");
|
|
4
|
+
this.getToken = config.getToken;
|
|
5
|
+
}
|
|
6
|
+
async headers() {
|
|
7
|
+
const h = { "Content-Type": "application/json" };
|
|
8
|
+
if (this.getToken) {
|
|
9
|
+
const token = await this.getToken();
|
|
10
|
+
if (token)
|
|
11
|
+
h["Authorization"] = `Bearer ${token}`;
|
|
12
|
+
}
|
|
13
|
+
return h;
|
|
14
|
+
}
|
|
15
|
+
async request(path, options) {
|
|
16
|
+
const url = `${this.baseUrl}/api/v1/consumables${path}`;
|
|
17
|
+
const headers = await this.headers();
|
|
18
|
+
const res = await fetch(url, { ...options, headers });
|
|
19
|
+
const json = (await res.json());
|
|
20
|
+
if (!res.ok) {
|
|
21
|
+
throw new Error(json.error || `Request failed: ${res.status}`);
|
|
22
|
+
}
|
|
23
|
+
return json.data;
|
|
24
|
+
}
|
|
25
|
+
async getBalance() {
|
|
26
|
+
const data = await this.request("/balance");
|
|
27
|
+
return {
|
|
28
|
+
balance: data.balance,
|
|
29
|
+
initialCredits: data.initial_credits,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
async recordPurchase(params) {
|
|
33
|
+
const data = await this.request("/purchase", {
|
|
34
|
+
method: "POST",
|
|
35
|
+
body: JSON.stringify(params),
|
|
36
|
+
});
|
|
37
|
+
return {
|
|
38
|
+
balance: data.balance,
|
|
39
|
+
initialCredits: data.initial_credits,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
async recordUsage(filename) {
|
|
43
|
+
return this.request("/use", {
|
|
44
|
+
method: "POST",
|
|
45
|
+
body: JSON.stringify({ filename }),
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
async getPurchaseHistory(limit = 50, offset = 0) {
|
|
49
|
+
return this.request(`/purchases?limit=${limit}&offset=${offset}`);
|
|
50
|
+
}
|
|
51
|
+
async getUsageHistory(limit = 50, offset = 0) {
|
|
52
|
+
return this.request(`/usages?limit=${limit}&offset=${offset}`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=ConsumablesApiClient.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ConsumablesApiClient.js","sourceRoot":"","sources":["../../src/network/ConsumablesApiClient.ts"],"names":[],"mappings":"AAWA,MAAM,OAAO,oBAAoB;IAI/B,YAAY,MAAkC;QAC5C,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QACjD,IAAI,CAAC,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;IAClC,CAAC;IAEO,KAAK,CAAC,OAAO;QACnB,MAAM,CAAC,GAA2B,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC;QACzE,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClB,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAC;YACpC,IAAI,KAAK;gBAAE,CAAC,CAAC,eAAe,CAAC,GAAG,UAAU,KAAK,EAAE,CAAC;QACpD,CAAC;QACD,OAAO,CAAC,CAAC;IACX,CAAC;IAEO,KAAK,CAAC,OAAO,CAAI,IAAY,EAAE,OAAqB;QAC1D,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,OAAO,sBAAsB,IAAI,EAAE,CAAC;QACxD,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;QACrC,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,GAAG,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;QACtD,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAQ,CAAC;QACvC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,mBAAmB,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;QACjE,CAAC;QACD,OAAO,IAAI,CAAC,IAAS,CAAC;IACxB,CAAC;IAED,KAAK,CAAC,UAAU;QACd,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,OAAO,CAG5B,UAAU,CAAC,CAAC;QACf,OAAO;YACL,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,cAAc,EAAE,IAAI,CAAC,eAAe;SACrC,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,MAOpB;QACC,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,OAAO,CAG5B,WAAW,EAAE;YACd,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC;SAC7B,CAAC,CAAC;QACH,OAAO;YACL,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,cAAc,EAAE,IAAI,CAAC,eAAe;SACrC,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,WAAW,CACf,QAAiB;QAEjB,OAAO,IAAI,CAAC,OAAO,CAAwC,MAAM,EAAE;YACjE,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,QAAQ,EAAE,CAAC;SACnC,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,kBAAkB,CACtB,KAAK,GAAG,EAAE,EACV,MAAM,GAAG,CAAC;QAEV,OAAO,IAAI,CAAC,OAAO,CACjB,oBAAoB,KAAK,WAAW,MAAM,EAAE,CAC7C,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,eAAe,CAAC,KAAK,GAAG,EAAE,EAAE,MAAM,GAAG,CAAC;QAC1C,OAAO,IAAI,CAAC,OAAO,CACjB,iBAAiB,KAAK,WAAW,MAAM,EAAE,CAC1C,CAAC;IACJ,CAAC;CACF","sourcesContent":["import type {\n CreditBalance,\n CreditPurchaseRecord,\n CreditUsageRecord,\n} from \"../types\";\n\nexport interface ConsumablesApiClientConfig {\n baseUrl: string;\n getToken?: () => Promise<string | null>;\n}\n\nexport class ConsumablesApiClient {\n private baseUrl: string;\n private getToken: (() => Promise<string | null>) | undefined;\n\n constructor(config: ConsumablesApiClientConfig) {\n this.baseUrl = config.baseUrl.replace(/\\/$/, \"\");\n this.getToken = config.getToken;\n }\n\n private async headers(): Promise<Record<string, string>> {\n const h: Record<string, string> = { \"Content-Type\": \"application/json\" };\n if (this.getToken) {\n const token = await this.getToken();\n if (token) h[\"Authorization\"] = `Bearer ${token}`;\n }\n return h;\n }\n\n private async request<T>(path: string, options?: RequestInit): Promise<T> {\n const url = `${this.baseUrl}/api/v1/consumables${path}`;\n const headers = await this.headers();\n const res = await fetch(url, { ...options, headers });\n const json = (await res.json()) as any;\n if (!res.ok) {\n throw new Error(json.error || `Request failed: ${res.status}`);\n }\n return json.data as T;\n }\n\n async getBalance(): Promise<CreditBalance> {\n const data = await this.request<{\n balance: number;\n initial_credits: number;\n }>(\"/balance\");\n return {\n balance: data.balance,\n initialCredits: data.initial_credits,\n };\n }\n\n async recordPurchase(params: {\n credits: number;\n source: string;\n transaction_ref_id?: string;\n product_id?: string;\n price_cents?: number;\n currency?: string;\n }): Promise<CreditBalance> {\n const data = await this.request<{\n balance: number;\n initial_credits: number;\n }>(\"/purchase\", {\n method: \"POST\",\n body: JSON.stringify(params),\n });\n return {\n balance: data.balance,\n initialCredits: data.initial_credits,\n };\n }\n\n async recordUsage(\n filename?: string,\n ): Promise<{ balance: number; success: boolean }> {\n return this.request<{ balance: number; success: boolean }>(\"/use\", {\n method: \"POST\",\n body: JSON.stringify({ filename }),\n });\n }\n\n async getPurchaseHistory(\n limit = 50,\n offset = 0,\n ): Promise<CreditPurchaseRecord[]> {\n return this.request<CreditPurchaseRecord[]>(\n `/purchases?limit=${limit}&offset=${offset}`,\n );\n }\n\n async getUsageHistory(limit = 50, offset = 0): Promise<CreditUsageRecord[]> {\n return this.request<CreditUsageRecord[]>(\n `/usages?limit=${limit}&offset=${offset}`,\n );\n }\n}\n"]}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { CreditPackage } from "./index";
|
|
2
|
+
export interface ConsumablePurchaseResult {
|
|
3
|
+
transactionId: string;
|
|
4
|
+
productId: string;
|
|
5
|
+
credits: number;
|
|
6
|
+
priceCents: number;
|
|
7
|
+
currency: string;
|
|
8
|
+
source: "web" | "apple" | "google";
|
|
9
|
+
}
|
|
10
|
+
export interface ConsumablePurchaseParams {
|
|
11
|
+
packageId: string;
|
|
12
|
+
offeringId: string;
|
|
13
|
+
}
|
|
14
|
+
export interface ConsumablesAdapter {
|
|
15
|
+
getOfferings(): Promise<{
|
|
16
|
+
all: Record<string, {
|
|
17
|
+
identifier: string;
|
|
18
|
+
metadata: Record<string, unknown> | null;
|
|
19
|
+
packages: CreditPackage[];
|
|
20
|
+
}>;
|
|
21
|
+
}>;
|
|
22
|
+
purchase(params: ConsumablePurchaseParams): Promise<ConsumablePurchaseResult>;
|
|
23
|
+
setUserId?(userId: string | undefined, email?: string): Promise<void>;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../src/types/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAG7C,MAAM,WAAW,wBAAwB;IACvC,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,KAAK,GAAG,OAAO,GAAG,QAAQ,CAAC;CACpC;AAGD,MAAM,WAAW,wBAAwB;IACvC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAKD,MAAM,WAAW,kBAAkB;IAEjC,YAAY,IAAI,OAAO,CAAC;QACtB,GAAG,EAAE,MAAM,CACT,MAAM,EACN;YACE,UAAU,EAAE,MAAM,CAAC;YACnB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;YACzC,QAAQ,EAAE,aAAa,EAAE,CAAC;SAC3B,CACF,CAAC;KACH,CAAC,CAAC;IAGH,QAAQ,CAAC,MAAM,EAAE,wBAAwB,GAAG,OAAO,CAAC,wBAAwB,CAAC,CAAC;IAG9E,SAAS,CAAC,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACvE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../src/types/adapter.ts"],"names":[],"mappings":"","sourcesContent":["import type { CreditPackage } from \"./index\";\n\n/** Platform-specific purchase result */\nexport interface ConsumablePurchaseResult {\n transactionId: string;\n productId: string;\n credits: number;\n priceCents: number;\n currency: string;\n source: \"web\" | \"apple\" | \"google\";\n}\n\n/** Purchase parameters */\nexport interface ConsumablePurchaseParams {\n packageId: string;\n offeringId: string;\n}\n\n/**\n * Adapter interface for platform-specific purchase flows.\n */\nexport interface ConsumablesAdapter {\n /** Get offerings (credit packages) from RevenueCat */\n getOfferings(): Promise<{\n all: Record<\n string,\n {\n identifier: string;\n metadata: Record<string, unknown> | null;\n packages: CreditPackage[];\n }\n >;\n }>;\n\n /** Execute a purchase via RevenueCat (opens payment UI) */\n purchase(params: ConsumablePurchaseParams): Promise<ConsumablePurchaseResult>;\n\n /** Set the current user (called on auth state change) */\n setUserId?(userId: string | undefined, email?: string): Promise<void>;\n}\n"]}
|