@umituz/react-native-subscription 3.1.34 → 3.1.36
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/package.json +1 -1
- package/src/domains/credits/application/CreditsInitializer.ts +34 -39
- package/src/domains/credits/application/DeductCreditsCommand.ts +13 -12
- package/src/domains/credits/infrastructure/operations/CreditsWriter.ts +1 -1
- package/src/domains/credits/presentation/deduct-credit/useDeductCredit.ts +1 -1
- package/src/domains/credits/presentation/useCredits.types.ts +1 -1
- package/src/domains/paywall/components/PaywallScreen.tsx +12 -11
- package/src/domains/paywall/hooks/usePaywallActions.ts +4 -3
- package/src/domains/paywall/hooks/usePaywallActions.utils.ts +14 -19
- package/src/domains/paywall/hooks/usePaywallPurchase.ts +10 -17
- package/src/domains/paywall/hooks/usePaywallRestore.ts +8 -15
- package/src/domains/revenuecat/core/errors/RevenueCatError.ts +1 -1
- package/src/domains/revenuecat/infrastructure/services/ConfigurationStateManager.ts +1 -1
- package/src/domains/revenuecat/infrastructure/services/RevenueCatInitializer.ts +7 -6
- package/src/domains/revenuecat/infrastructure/services/UserSwitchMutex.ts +8 -10
- package/src/domains/revenuecat/infrastructure/services/initializerConstants.ts +1 -1
- package/src/domains/revenuecat/infrastructure/services/userSwitchCore.ts +17 -34
- package/src/domains/revenuecat/infrastructure/services/userSwitchHelpers.ts +4 -5
- package/src/domains/revenuecat/infrastructure/services/userSwitchInitializer.ts +19 -29
- package/src/domains/subscription/application/initializer/BackgroundInitializer.ts +17 -29
- package/src/domains/subscription/application/sync/CreditDocumentOperations.ts +16 -17
- package/src/domains/subscription/application/sync/PurchaseSyncHandler.ts +20 -23
- package/src/domains/subscription/application/sync/RenewalSyncHandler.ts +8 -7
- package/src/domains/subscription/application/sync/StatusChangeSyncHandler.ts +4 -3
- package/src/domains/subscription/application/sync/SyncProcessorLogger.ts +40 -65
- package/src/domains/subscription/application/sync/UserIdResolver.ts +5 -1
- package/src/domains/subscription/infrastructure/handlers/PackageHandler.ts +1 -1
- package/src/domains/subscription/infrastructure/handlers/PurchaseStatusResolver.ts +1 -1
- package/src/domains/subscription/infrastructure/handlers/package-operations/PackageFetcher.ts +7 -6
- package/src/domains/subscription/infrastructure/handlers/package-operations/PackagePurchaser.ts +8 -7
- package/src/domains/subscription/infrastructure/hooks/usePurchasePackage.ts +4 -3
- package/src/domains/subscription/infrastructure/managers/SubscriptionManager.ts +21 -28
- package/src/domains/subscription/infrastructure/managers/initializationHandler.ts +1 -1
- package/src/domains/subscription/infrastructure/managers/managerOperations.ts +1 -1
- package/src/domains/subscription/infrastructure/managers/packageHandlerFactory.ts +1 -1
- package/src/domains/subscription/infrastructure/managers/premiumStatusChecker.ts +1 -1
- package/src/domains/subscription/infrastructure/managers/subscriptionManagerUtils.ts +1 -1
- package/src/domains/subscription/infrastructure/services/CustomerInfoListenerManager.ts +10 -9
- package/src/domains/subscription/infrastructure/services/OfferingsFetcher.ts +14 -21
- package/src/domains/subscription/infrastructure/services/PurchaseHandler.ts +9 -8
- package/src/domains/subscription/infrastructure/services/RestoreHandler.ts +1 -1
- package/src/domains/subscription/infrastructure/services/RevenueCatService.types.ts +5 -4
- package/src/domains/subscription/infrastructure/services/listeners/CustomerInfoHandler.ts +15 -29
- package/src/domains/subscription/infrastructure/services/purchase/PurchaseErrorHandler.ts +4 -2
- package/src/domains/subscription/infrastructure/services/purchase/PurchaseExecutor.ts +27 -33
- package/src/domains/subscription/infrastructure/utils/InitializationCache.ts +5 -1
- package/src/domains/subscription/infrastructure/utils/PremiumStatusSyncer.ts +11 -17
- package/src/domains/subscription/presentation/providers/SubscriptionFlowProvider.tsx +11 -12
- package/src/domains/subscription/presentation/screens/SubscriptionDetailScreen.tsx +1 -1
- package/src/domains/subscription/presentation/useSyncStatusListener.ts +10 -9
- package/src/domains/wallet/presentation/components/TransactionList.tsx +1 -1
- package/src/domains/wallet/presentation/hooks/useTransactionHistory.ts +2 -2
- package/src/domains/wallet/presentation/screens/WalletScreen.tsx +1 -1
- package/src/init/createSubscriptionInitModule.ts +4 -1
- package/src/shared/infrastructure/SubscriptionEventBus.ts +4 -1
|
@@ -4,6 +4,9 @@ import { syncPremiumStatus } from "../../utils/PremiumStatusSyncer";
|
|
|
4
4
|
import { detectRenewal } from "../../utils/renewal/RenewalDetector";
|
|
5
5
|
import { updateRenewalState } from "../../utils/renewal/RenewalStateUpdater";
|
|
6
6
|
import type { RenewalState } from "../../utils/renewal/types";
|
|
7
|
+
import { createLogger } from "../../../../../shared/utils/logger";
|
|
8
|
+
|
|
9
|
+
const logger = createLogger("CustomerInfoHandler");
|
|
7
10
|
|
|
8
11
|
async function handleRenewal(
|
|
9
12
|
userId: string,
|
|
@@ -17,11 +20,7 @@ async function handleRenewal(
|
|
|
17
20
|
try {
|
|
18
21
|
await onRenewalDetected({ userId, productId, newExpirationDate: expirationDate, customerInfo });
|
|
19
22
|
} catch (error) {
|
|
20
|
-
|
|
21
|
-
userId,
|
|
22
|
-
productId,
|
|
23
|
-
error: error instanceof Error ? error.message : String(error)
|
|
24
|
-
});
|
|
23
|
+
logger.error("Renewal callback failed", error, { userId, productId });
|
|
25
24
|
}
|
|
26
25
|
}
|
|
27
26
|
|
|
@@ -38,13 +37,7 @@ async function handlePlanChange(
|
|
|
38
37
|
try {
|
|
39
38
|
await onPlanChanged({ userId, newProductId, previousProductId, isUpgrade, customerInfo });
|
|
40
39
|
} catch (error) {
|
|
41
|
-
|
|
42
|
-
userId,
|
|
43
|
-
newProductId,
|
|
44
|
-
previousProductId,
|
|
45
|
-
isUpgrade,
|
|
46
|
-
error: error instanceof Error ? error.message : String(error)
|
|
47
|
-
});
|
|
40
|
+
logger.error("Plan change callback failed", error, { userId, newProductId, previousProductId, isUpgrade });
|
|
48
41
|
}
|
|
49
42
|
}
|
|
50
43
|
|
|
@@ -56,10 +49,7 @@ async function handlePremiumStatusSync(
|
|
|
56
49
|
try {
|
|
57
50
|
await syncPremiumStatus(config, userId, customerInfo);
|
|
58
51
|
} catch (error) {
|
|
59
|
-
|
|
60
|
-
userId,
|
|
61
|
-
error: error instanceof Error ? error.message : String(error)
|
|
62
|
-
});
|
|
52
|
+
logger.error("Premium status sync failed", error, { userId });
|
|
63
53
|
}
|
|
64
54
|
}
|
|
65
55
|
|
|
@@ -69,14 +59,12 @@ export async function processCustomerInfo(
|
|
|
69
59
|
renewalState: RenewalState,
|
|
70
60
|
config: RevenueCatConfig
|
|
71
61
|
): Promise<RenewalState> {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
});
|
|
79
|
-
}
|
|
62
|
+
logger.debug("processCustomerInfo called", {
|
|
63
|
+
userId,
|
|
64
|
+
renewalState,
|
|
65
|
+
entitlementId: config.entitlementIdentifier,
|
|
66
|
+
activeEntitlements: Object.keys(customerInfo.entitlements.active),
|
|
67
|
+
});
|
|
80
68
|
|
|
81
69
|
const renewalResult = detectRenewal(
|
|
82
70
|
renewalState,
|
|
@@ -86,7 +74,7 @@ export async function processCustomerInfo(
|
|
|
86
74
|
|
|
87
75
|
if (renewalResult.isRenewal) {
|
|
88
76
|
if (!renewalResult.productId || !renewalResult.newExpirationDate) {
|
|
89
|
-
|
|
77
|
+
logger.error("Invalid renewal state: missing productId or expirationDate");
|
|
90
78
|
return renewalState;
|
|
91
79
|
}
|
|
92
80
|
await handleRenewal(
|
|
@@ -100,7 +88,7 @@ export async function processCustomerInfo(
|
|
|
100
88
|
|
|
101
89
|
if (renewalResult.isPlanChange) {
|
|
102
90
|
if (!renewalResult.productId || !renewalResult.previousProductId) {
|
|
103
|
-
|
|
91
|
+
logger.error("Invalid plan change state: missing productId(s)");
|
|
104
92
|
return renewalState;
|
|
105
93
|
}
|
|
106
94
|
await handlePlanChange(
|
|
@@ -114,9 +102,7 @@ export async function processCustomerInfo(
|
|
|
114
102
|
}
|
|
115
103
|
|
|
116
104
|
if (!renewalResult.isRenewal && !renewalResult.isPlanChange) {
|
|
117
|
-
|
|
118
|
-
console.log("[CustomerInfoHandler] Handling premium status sync (new purchase or status update)");
|
|
119
|
-
}
|
|
105
|
+
logger.debug("Handling premium status sync (new purchase or status update)");
|
|
120
106
|
await handlePremiumStatusSync(config, userId, customerInfo);
|
|
121
107
|
}
|
|
122
108
|
|
|
@@ -15,6 +15,9 @@ import { getSavedPurchase, clearSavedPurchase } from "../../../presentation/useA
|
|
|
15
15
|
import { notifyPurchaseCompleted } from "../../utils/PremiumStatusSyncer";
|
|
16
16
|
import { handleRestore } from "../RestoreHandler";
|
|
17
17
|
import type { PurchaseHandlerDeps } from "../PurchaseHandler";
|
|
18
|
+
import { createLogger } from "../../../../../shared/utils/logger";
|
|
19
|
+
|
|
20
|
+
const logger = createLogger("PurchaseErrorHandler");
|
|
18
21
|
|
|
19
22
|
export async function handleAlreadyPurchasedError(
|
|
20
23
|
deps: PurchaseHandlerDeps,
|
|
@@ -85,11 +88,10 @@ export function handlePurchaseError(
|
|
|
85
88
|
? `${errorMessage} (Code: ${errorCode})`
|
|
86
89
|
: errorMessage;
|
|
87
90
|
|
|
88
|
-
|
|
91
|
+
logger.error("Purchase failed", error, {
|
|
89
92
|
productId: pkg.product.identifier,
|
|
90
93
|
userId,
|
|
91
94
|
errorCode,
|
|
92
|
-
error,
|
|
93
95
|
});
|
|
94
96
|
|
|
95
97
|
throw new RevenueCatPurchaseError(
|
|
@@ -4,13 +4,16 @@ import type { RevenueCatConfig } from "../../../../revenuecat/core/types/Revenue
|
|
|
4
4
|
import type { PackageType } from "../../../../revenuecat/core/types/RevenueCatTypes";
|
|
5
5
|
import { notifyPurchaseCompleted, syncPremiumStatus } from "../../utils/PremiumStatusSyncer";
|
|
6
6
|
import { getSavedPurchase, clearSavedPurchase } from "../../../presentation/useAuthAwarePurchase";
|
|
7
|
+
import { createLogger } from "../../../../../shared/utils/logger";
|
|
8
|
+
|
|
9
|
+
const logger = createLogger("PurchaseExecutor");
|
|
7
10
|
|
|
8
11
|
async function attemptRecovery(config: RevenueCatConfig, userId: string, customerInfo: CustomerInfo): Promise<void> {
|
|
9
12
|
try {
|
|
10
|
-
|
|
13
|
+
logger.warn("Attempting recovery via syncPremiumStatus...");
|
|
11
14
|
await syncPremiumStatus(config, userId, customerInfo);
|
|
12
15
|
} catch (recoveryError) {
|
|
13
|
-
|
|
16
|
+
logger.error("Recovery also failed", recoveryError);
|
|
14
17
|
}
|
|
15
18
|
}
|
|
16
19
|
|
|
@@ -27,7 +30,7 @@ async function executeConsumablePurchase(
|
|
|
27
30
|
try {
|
|
28
31
|
await notifyPurchaseCompleted(config, userId, productId, customerInfo, source, packageType);
|
|
29
32
|
} catch (syncError) {
|
|
30
|
-
|
|
33
|
+
logger.error("Post-purchase sync failed, attempting recovery", syncError);
|
|
31
34
|
await attemptRecovery(config, userId, customerInfo);
|
|
32
35
|
} finally {
|
|
33
36
|
if (savedPurchase) {
|
|
@@ -56,34 +59,29 @@ async function executeSubscriptionPurchase(
|
|
|
56
59
|
const savedPurchase = getSavedPurchase();
|
|
57
60
|
const source = savedPurchase?.source;
|
|
58
61
|
|
|
59
|
-
|
|
60
|
-
|
|
62
|
+
logger.debug("executeSubscriptionPurchase: START", {
|
|
63
|
+
userId,
|
|
64
|
+
productId,
|
|
65
|
+
isPremium,
|
|
66
|
+
entitlementIdentifier,
|
|
67
|
+
activeEntitlements: Object.keys(customerInfo.entitlements.active),
|
|
68
|
+
source,
|
|
69
|
+
packageType,
|
|
70
|
+
timestamp: new Date().toISOString(),
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
try {
|
|
74
|
+
await notifyPurchaseCompleted(config, userId, productId, customerInfo, source, packageType);
|
|
75
|
+
logger.debug("executeSubscriptionPurchase: SUCCESS", {
|
|
61
76
|
userId,
|
|
62
77
|
productId,
|
|
63
78
|
isPremium,
|
|
64
|
-
entitlementIdentifier,
|
|
65
|
-
activeEntitlements: Object.keys(customerInfo.entitlements.active),
|
|
66
|
-
source,
|
|
67
|
-
packageType,
|
|
68
79
|
timestamp: new Date().toISOString(),
|
|
69
80
|
});
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
try {
|
|
73
|
-
await notifyPurchaseCompleted(config, userId, productId, customerInfo, source, packageType);
|
|
74
|
-
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
75
|
-
console.log("[PurchaseExecutor] 🟢 executeSubscriptionPurchase: SUCCESS", {
|
|
76
|
-
userId,
|
|
77
|
-
productId,
|
|
78
|
-
isPremium,
|
|
79
|
-
timestamp: new Date().toISOString(),
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
81
|
} catch (syncError) {
|
|
83
|
-
|
|
82
|
+
logger.error("Post-purchase sync failed, attempting recovery", syncError, {
|
|
84
83
|
userId,
|
|
85
84
|
productId,
|
|
86
|
-
error: syncError instanceof Error ? syncError.message : String(syncError),
|
|
87
85
|
timestamp: new Date().toISOString(),
|
|
88
86
|
});
|
|
89
87
|
await attemptRecovery(config, userId, customerInfo);
|
|
@@ -122,13 +120,11 @@ export async function executePurchase(
|
|
|
122
120
|
pkg: PurchasesPackage,
|
|
123
121
|
isConsumable: boolean
|
|
124
122
|
): Promise<PurchaseResult> {
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
});
|
|
131
|
-
}
|
|
123
|
+
logger.debug("Starting Purchases.purchasePackage", {
|
|
124
|
+
productId: pkg.product.identifier,
|
|
125
|
+
userId,
|
|
126
|
+
isConsumable,
|
|
127
|
+
});
|
|
132
128
|
|
|
133
129
|
const { customerInfo } = await withTimeout(
|
|
134
130
|
Purchases.purchasePackage(pkg),
|
|
@@ -136,9 +132,7 @@ export async function executePurchase(
|
|
|
136
132
|
`Purchases.purchasePackage(${pkg.product.identifier})`
|
|
137
133
|
);
|
|
138
134
|
|
|
139
|
-
|
|
140
|
-
console.log("[PurchaseExecutor] Purchases.purchasePackage completed successfully");
|
|
141
|
-
}
|
|
135
|
+
logger.debug("Purchases.purchasePackage completed successfully");
|
|
142
136
|
|
|
143
137
|
const productId = pkg.product.identifier;
|
|
144
138
|
const packageType = pkg.packageType ?? null;
|
|
@@ -4,6 +4,10 @@ interface CacheEntry {
|
|
|
4
4
|
completed: boolean;
|
|
5
5
|
}
|
|
6
6
|
|
|
7
|
+
import { createLogger } from "../../../shared/utils/logger";
|
|
8
|
+
|
|
9
|
+
const logger = createLogger("InitializationCache");
|
|
10
|
+
|
|
7
11
|
export class InitializationCache {
|
|
8
12
|
private entries: Map<string, CacheEntry> = new Map();
|
|
9
13
|
|
|
@@ -38,7 +42,7 @@ export class InitializationCache {
|
|
|
38
42
|
if (this.entries.get(cacheKey) === entry) {
|
|
39
43
|
this.entries.delete(cacheKey);
|
|
40
44
|
}
|
|
41
|
-
|
|
45
|
+
logger.error("Initialization failed", error, { cacheKey });
|
|
42
46
|
return false;
|
|
43
47
|
});
|
|
44
48
|
|
|
@@ -3,20 +3,21 @@ import type { RevenueCatConfig } from "../../../revenuecat/core/types/RevenueCat
|
|
|
3
3
|
import type { PurchaseSource } from "../../core/SubscriptionConstants";
|
|
4
4
|
import type { PackageType } from "../../../revenuecat/core/types/RevenueCatTypes";
|
|
5
5
|
import { getPremiumEntitlement } from "../../../revenuecat/core/types/RevenueCatTypes";
|
|
6
|
+
import { createLogger } from "../../../shared/utils/logger";
|
|
7
|
+
|
|
8
|
+
const logger = createLogger("PremiumStatusSyncer");
|
|
6
9
|
|
|
7
10
|
export async function syncPremiumStatus(
|
|
8
11
|
config: RevenueCatConfig,
|
|
9
12
|
userId: string,
|
|
10
13
|
customerInfo: CustomerInfo
|
|
11
14
|
): Promise<{ success: boolean; error?: Error }> {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
});
|
|
19
|
-
}
|
|
15
|
+
logger.debug("syncPremiumStatus called", {
|
|
16
|
+
userId,
|
|
17
|
+
hasCallback: !!config.onPremiumStatusChanged,
|
|
18
|
+
entitlementId: config.entitlementIdentifier,
|
|
19
|
+
activeEntitlements: Object.keys(customerInfo.entitlements.active),
|
|
20
|
+
});
|
|
20
21
|
|
|
21
22
|
if (!config.onPremiumStatusChanged) {
|
|
22
23
|
return { success: true };
|
|
@@ -49,12 +50,7 @@ export async function syncPremiumStatus(
|
|
|
49
50
|
}
|
|
50
51
|
return { success: true };
|
|
51
52
|
} catch (error) {
|
|
52
|
-
|
|
53
|
-
console.error('[PremiumStatusSyncer] Premium status callback failed:', {
|
|
54
|
-
userId,
|
|
55
|
-
error: error instanceof Error ? error.message : String(error)
|
|
56
|
-
});
|
|
57
|
-
}
|
|
53
|
+
logger.error("Premium status callback failed", error, { userId });
|
|
58
54
|
|
|
59
55
|
return {
|
|
60
56
|
success: false,
|
|
@@ -87,8 +83,6 @@ export async function notifyRestoreCompleted(
|
|
|
87
83
|
try {
|
|
88
84
|
await config.onRestoreCompleted({ userId, isPremium, customerInfo });
|
|
89
85
|
} catch (error) {
|
|
90
|
-
|
|
91
|
-
console.error('[PremiumStatusSyncer] Restore callback failed:', error instanceof Error ? error.message : String(error));
|
|
92
|
-
}
|
|
86
|
+
logger.error("Restore callback failed", error);
|
|
93
87
|
}
|
|
94
88
|
}
|
|
@@ -2,6 +2,9 @@ import React, { createContext, useContext, useEffect } from "react";
|
|
|
2
2
|
import { useSubscriptionFlowStore, SubscriptionFlowStatus } from "../useSubscriptionFlow";
|
|
3
3
|
import { useSyncStatusListener } from "../useSyncStatusListener";
|
|
4
4
|
import { initializationState } from "../../infrastructure/state/initializationState";
|
|
5
|
+
import { createLogger } from "../../../shared/utils/logger";
|
|
6
|
+
|
|
7
|
+
const logger = createLogger("SubscriptionFlowProvider");
|
|
5
8
|
|
|
6
9
|
interface SubscriptionFlowContextType {
|
|
7
10
|
status: SubscriptionFlowStatus;
|
|
@@ -24,9 +27,7 @@ export const SubscriptionFlowProvider: React.FC<{ children: React.ReactNode }> =
|
|
|
24
27
|
// 1. Listen to background initialization state
|
|
25
28
|
const unsubscribe = initializationState.subscribe(() => {
|
|
26
29
|
const { initialized } = initializationState.getSnapshot();
|
|
27
|
-
|
|
28
|
-
console.log('[SubscriptionFlowProvider] 🔄 Initialization status updated:', { initialized });
|
|
29
|
-
}
|
|
30
|
+
logger.debug("Initialization status updated", { initialized });
|
|
30
31
|
if (initialized && !isInitialized) {
|
|
31
32
|
setInitialized(true);
|
|
32
33
|
}
|
|
@@ -35,7 +36,7 @@ export const SubscriptionFlowProvider: React.FC<{ children: React.ReactNode }> =
|
|
|
35
36
|
// Check initial state
|
|
36
37
|
const { initialized: currentlyInitialized } = initializationState.getSnapshot();
|
|
37
38
|
if (currentlyInitialized && !isInitialized) {
|
|
38
|
-
|
|
39
|
+
logger.debug("Already initialized on mount");
|
|
39
40
|
setInitialized(true);
|
|
40
41
|
}
|
|
41
42
|
|
|
@@ -44,13 +45,11 @@ export const SubscriptionFlowProvider: React.FC<{ children: React.ReactNode }> =
|
|
|
44
45
|
|
|
45
46
|
useEffect(() => {
|
|
46
47
|
// This effect manages the overall flow status transition
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
});
|
|
53
|
-
}
|
|
48
|
+
logger.debug("Calculating Status Transition", {
|
|
49
|
+
isInitialized,
|
|
50
|
+
isOnboardingComplete,
|
|
51
|
+
currentStatus: status
|
|
52
|
+
});
|
|
54
53
|
|
|
55
54
|
let nextStatus = SubscriptionFlowStatus.READY;
|
|
56
55
|
|
|
@@ -70,7 +69,7 @@ export const SubscriptionFlowProvider: React.FC<{ children: React.ReactNode }> =
|
|
|
70
69
|
}
|
|
71
70
|
|
|
72
71
|
if (nextStatus !== status) {
|
|
73
|
-
|
|
72
|
+
logger.debug("Transitioning status to", nextStatus);
|
|
74
73
|
setStatus(nextStatus);
|
|
75
74
|
}
|
|
76
75
|
}, [
|
|
@@ -5,7 +5,7 @@ import { AtomicIcon, AtomicText } from "@umituz/react-native-design-system/atoms
|
|
|
5
5
|
import { NavigationHeader } from "@umituz/react-native-design-system/molecules";
|
|
6
6
|
import { useAppDesignTokens } from "@umituz/react-native-design-system/theme";
|
|
7
7
|
import { useAuthStore, selectUserId } from "@umituz/react-native-auth";
|
|
8
|
-
import { ScreenLayout } from "
|
|
8
|
+
import { ScreenLayout } from "../../../shared/presentation/layouts/ScreenLayout";
|
|
9
9
|
import { getCreditsRepository } from "../../../credits/infrastructure/CreditsRepositoryManager";
|
|
10
10
|
import { SubscriptionHeader } from "./components/SubscriptionHeader";
|
|
11
11
|
import { CreditsList } from "./components/CreditsList";
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { useEffect } from "react";
|
|
2
2
|
import { subscriptionEventBus, SUBSCRIPTION_EVENTS } from "../../../shared/infrastructure/SubscriptionEventBus";
|
|
3
3
|
import { useSubscriptionFlowStore, SyncStatus } from "./useSubscriptionFlow";
|
|
4
|
+
import { createLogger } from "../../../shared/utils/logger";
|
|
5
|
+
|
|
6
|
+
const logger = createLogger("useSyncStatusListener");
|
|
4
7
|
|
|
5
8
|
interface SyncStatusEvent {
|
|
6
9
|
status: 'syncing' | 'success' | 'error';
|
|
@@ -30,15 +33,13 @@ export function useSyncStatusListener() {
|
|
|
30
33
|
|
|
31
34
|
setSyncStatus(syncStatus, event.error);
|
|
32
35
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
});
|
|
41
|
-
}
|
|
36
|
+
logger.debug("Sync status updated", {
|
|
37
|
+
status: event.status,
|
|
38
|
+
phase: event.phase,
|
|
39
|
+
userId: event.userId,
|
|
40
|
+
productId: event.productId,
|
|
41
|
+
error: event.error,
|
|
42
|
+
});
|
|
42
43
|
}
|
|
43
44
|
);
|
|
44
45
|
|
|
@@ -7,7 +7,7 @@ import { transactionListStyles } from "./TransactionList.styles";
|
|
|
7
7
|
import { LoadingState, EmptyState } from "./TransactionListStates";
|
|
8
8
|
import { DEFAULT_TRANSACTION_LIST_MAX_HEIGHT } from "./TransactionList.constants";
|
|
9
9
|
import type { TransactionListTranslations, TransactionListProps } from "./TransactionList.types";
|
|
10
|
-
import { isEmptyArray } from "
|
|
10
|
+
import { isEmptyArray } from "../../../shared/utils/arrayUtils";
|
|
11
11
|
|
|
12
12
|
export type { TransactionListTranslations };
|
|
13
13
|
|
|
@@ -5,8 +5,8 @@ import type {
|
|
|
5
5
|
CreditLog,
|
|
6
6
|
TransactionRepositoryConfig,
|
|
7
7
|
} from "../../domain/types/transaction.types";
|
|
8
|
-
import { requireFirestore } from "
|
|
9
|
-
import { useFirestoreCollectionRealTime } from "
|
|
8
|
+
import { requireFirestore } from "../../../shared/infrastructure/firestore/collectionUtils";
|
|
9
|
+
import { useFirestoreCollectionRealTime } from "../../../shared/presentation/hooks/useFirestoreRealTime";
|
|
10
10
|
|
|
11
11
|
export interface UseTransactionHistoryParams {
|
|
12
12
|
config: TransactionRepositoryConfig;
|
|
@@ -2,7 +2,7 @@ import React from "react";
|
|
|
2
2
|
import { View, StyleSheet, TouchableOpacity } from "react-native";
|
|
3
3
|
import { AtomicText, AtomicIcon, AtomicSpinner } from "@umituz/react-native-design-system/atoms";
|
|
4
4
|
import { useAppDesignTokens } from "@umituz/react-native-design-system/theme";
|
|
5
|
-
import { ScreenLayout } from "
|
|
5
|
+
import { ScreenLayout } from "../../../shared/presentation/layouts/ScreenLayout";
|
|
6
6
|
import { useAppNavigation } from "@umituz/react-native-design-system/molecules";
|
|
7
7
|
import { useWallet } from "../hooks/useWallet";
|
|
8
8
|
import { getWalletConfig } from "../../infrastructure/config/walletConfig";
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import type { InitModule } from '@umituz/react-native-design-system/init';
|
|
2
2
|
import { initializeSubscription } from "../domains/subscription/application/initializer/SubscriptionInitializer";
|
|
3
3
|
import type { SubscriptionInitConfig } from "../domains/subscription/application/SubscriptionInitializerTypes";
|
|
4
|
+
import { createLogger } from "../shared/utils/logger";
|
|
5
|
+
|
|
6
|
+
const logger = createLogger("SubscriptionInitModule");
|
|
4
7
|
|
|
5
8
|
export interface SubscriptionInitModuleConfig extends Omit<SubscriptionInitConfig, 'apiKey'> {
|
|
6
9
|
getApiKey: () => string | undefined;
|
|
@@ -34,7 +37,7 @@ export function createSubscriptionInitModule(config: SubscriptionInitModuleConfi
|
|
|
34
37
|
subscriptionCleanup = await initializeSubscription({ apiKey, ...subscriptionConfig });
|
|
35
38
|
return true;
|
|
36
39
|
} catch (error) {
|
|
37
|
-
|
|
40
|
+
logger.error("Initialization failed", error);
|
|
38
41
|
throw error;
|
|
39
42
|
}
|
|
40
43
|
},
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
type EventCallback<T = unknown> = (data: T) => void;
|
|
2
|
+
import { createLogger } from "../utils/logger";
|
|
3
|
+
|
|
4
|
+
const logger = createLogger("SubscriptionEventBus");
|
|
2
5
|
|
|
3
6
|
class SubscriptionEventBus {
|
|
4
7
|
private static instance: SubscriptionEventBus;
|
|
@@ -43,7 +46,7 @@ class SubscriptionEventBus {
|
|
|
43
46
|
try {
|
|
44
47
|
callback(data);
|
|
45
48
|
} catch (error) {
|
|
46
|
-
|
|
49
|
+
logger.error("Listener error for event", error, { event });
|
|
47
50
|
}
|
|
48
51
|
});
|
|
49
52
|
});
|