@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.
Files changed (55) hide show
  1. package/package.json +1 -1
  2. package/src/domains/credits/application/CreditsInitializer.ts +34 -39
  3. package/src/domains/credits/application/DeductCreditsCommand.ts +13 -12
  4. package/src/domains/credits/infrastructure/operations/CreditsWriter.ts +1 -1
  5. package/src/domains/credits/presentation/deduct-credit/useDeductCredit.ts +1 -1
  6. package/src/domains/credits/presentation/useCredits.types.ts +1 -1
  7. package/src/domains/paywall/components/PaywallScreen.tsx +12 -11
  8. package/src/domains/paywall/hooks/usePaywallActions.ts +4 -3
  9. package/src/domains/paywall/hooks/usePaywallActions.utils.ts +14 -19
  10. package/src/domains/paywall/hooks/usePaywallPurchase.ts +10 -17
  11. package/src/domains/paywall/hooks/usePaywallRestore.ts +8 -15
  12. package/src/domains/revenuecat/core/errors/RevenueCatError.ts +1 -1
  13. package/src/domains/revenuecat/infrastructure/services/ConfigurationStateManager.ts +1 -1
  14. package/src/domains/revenuecat/infrastructure/services/RevenueCatInitializer.ts +7 -6
  15. package/src/domains/revenuecat/infrastructure/services/UserSwitchMutex.ts +8 -10
  16. package/src/domains/revenuecat/infrastructure/services/initializerConstants.ts +1 -1
  17. package/src/domains/revenuecat/infrastructure/services/userSwitchCore.ts +17 -34
  18. package/src/domains/revenuecat/infrastructure/services/userSwitchHelpers.ts +4 -5
  19. package/src/domains/revenuecat/infrastructure/services/userSwitchInitializer.ts +19 -29
  20. package/src/domains/subscription/application/initializer/BackgroundInitializer.ts +17 -29
  21. package/src/domains/subscription/application/sync/CreditDocumentOperations.ts +16 -17
  22. package/src/domains/subscription/application/sync/PurchaseSyncHandler.ts +20 -23
  23. package/src/domains/subscription/application/sync/RenewalSyncHandler.ts +8 -7
  24. package/src/domains/subscription/application/sync/StatusChangeSyncHandler.ts +4 -3
  25. package/src/domains/subscription/application/sync/SyncProcessorLogger.ts +40 -65
  26. package/src/domains/subscription/application/sync/UserIdResolver.ts +5 -1
  27. package/src/domains/subscription/infrastructure/handlers/PackageHandler.ts +1 -1
  28. package/src/domains/subscription/infrastructure/handlers/PurchaseStatusResolver.ts +1 -1
  29. package/src/domains/subscription/infrastructure/handlers/package-operations/PackageFetcher.ts +7 -6
  30. package/src/domains/subscription/infrastructure/handlers/package-operations/PackagePurchaser.ts +8 -7
  31. package/src/domains/subscription/infrastructure/hooks/usePurchasePackage.ts +4 -3
  32. package/src/domains/subscription/infrastructure/managers/SubscriptionManager.ts +21 -28
  33. package/src/domains/subscription/infrastructure/managers/initializationHandler.ts +1 -1
  34. package/src/domains/subscription/infrastructure/managers/managerOperations.ts +1 -1
  35. package/src/domains/subscription/infrastructure/managers/packageHandlerFactory.ts +1 -1
  36. package/src/domains/subscription/infrastructure/managers/premiumStatusChecker.ts +1 -1
  37. package/src/domains/subscription/infrastructure/managers/subscriptionManagerUtils.ts +1 -1
  38. package/src/domains/subscription/infrastructure/services/CustomerInfoListenerManager.ts +10 -9
  39. package/src/domains/subscription/infrastructure/services/OfferingsFetcher.ts +14 -21
  40. package/src/domains/subscription/infrastructure/services/PurchaseHandler.ts +9 -8
  41. package/src/domains/subscription/infrastructure/services/RestoreHandler.ts +1 -1
  42. package/src/domains/subscription/infrastructure/services/RevenueCatService.types.ts +5 -4
  43. package/src/domains/subscription/infrastructure/services/listeners/CustomerInfoHandler.ts +15 -29
  44. package/src/domains/subscription/infrastructure/services/purchase/PurchaseErrorHandler.ts +4 -2
  45. package/src/domains/subscription/infrastructure/services/purchase/PurchaseExecutor.ts +27 -33
  46. package/src/domains/subscription/infrastructure/utils/InitializationCache.ts +5 -1
  47. package/src/domains/subscription/infrastructure/utils/PremiumStatusSyncer.ts +11 -17
  48. package/src/domains/subscription/presentation/providers/SubscriptionFlowProvider.tsx +11 -12
  49. package/src/domains/subscription/presentation/screens/SubscriptionDetailScreen.tsx +1 -1
  50. package/src/domains/subscription/presentation/useSyncStatusListener.ts +10 -9
  51. package/src/domains/wallet/presentation/components/TransactionList.tsx +1 -1
  52. package/src/domains/wallet/presentation/hooks/useTransactionHistory.ts +2 -2
  53. package/src/domains/wallet/presentation/screens/WalletScreen.tsx +1 -1
  54. package/src/init/createSubscriptionInitModule.ts +4 -1
  55. package/src/shared/infrastructure/SubscriptionEventBus.ts +4 -1
@@ -3,8 +3,11 @@
3
3
  * Centralized logging for subscription sync operations
4
4
  */
5
5
 
6
- import { subscriptionEventBus, SUBSCRIPTION_EVENTS } from "../../../../shared/infrastructure/SubscriptionEventBus";
6
+ import { subscriptionEventBus, SUBSCRIPTION_EVENTS } from "../../../shared/infrastructure/SubscriptionEventBus";
7
7
  import type { PurchaseCompletedEvent, RenewalDetectedEvent, PremiumStatusChangedEvent } from "../../core/SubscriptionEvents";
8
+ import { createLogger } from "../../../shared/utils/logger";
9
+
10
+ const logger = createLogger("SubscriptionSyncProcessor");
8
11
 
9
12
  export type SyncPhase = 'purchase' | 'renewal' | 'status_change';
10
13
 
@@ -24,97 +27,69 @@ export class SyncProcessorLogger {
24
27
  }
25
28
 
26
29
  logPurchaseStart(event: PurchaseCompletedEvent) {
27
- if (__DEV__) {
28
- console.log('[SubscriptionSyncProcessor] 🔵 PURCHASE START', {
29
- userId: event.userId,
30
- productId: event.productId,
31
- source: event.source,
32
- packageType: event.packageType,
33
- timestamp: new Date().toISOString(),
34
- });
35
- }
30
+ logger.debug("PURCHASE START", {
31
+ userId: event.userId,
32
+ productId: event.productId,
33
+ source: event.source,
34
+ packageType: event.packageType,
35
+ timestamp: new Date().toISOString(),
36
+ });
36
37
  }
37
38
 
38
39
  logPurchaseSuccess(userId: string, productId: string) {
39
- if (__DEV__) {
40
- console.log('[SubscriptionSyncProcessor] 🟢 PURCHASE SUCCESS', {
41
- userId,
42
- productId,
43
- timestamp: new Date().toISOString(),
44
- });
45
- }
46
- }
47
-
48
- logPurchaseError(userId: string, productId: string, error: string) {
49
- console.error('[SubscriptionSyncProcessor] 🔴 PURCHASE FAILED', {
40
+ logger.debug("PURCHASE SUCCESS", {
50
41
  userId,
51
42
  productId,
52
- error,
53
43
  timestamp: new Date().toISOString(),
54
44
  });
55
45
  }
56
46
 
57
- logRenewalStart(event: RenewalDetectedEvent) {
58
- if (__DEV__) {
59
- console.log('[SubscriptionSyncProcessor] 🔵 RENEWAL START', {
60
- userId: event.userId,
61
- productId: event.productId,
62
- newExpirationDate: event.newExpirationDate,
63
- timestamp: new Date().toISOString(),
64
- });
65
- }
47
+ logPurchaseError(userId: string, productId: string, error: string) {
48
+ logger.error("PURCHASE FAILED", error, { userId, productId, timestamp: new Date().toISOString() });
66
49
  }
67
50
 
68
- logRenewalSuccess(userId: string, productId: string) {
69
- if (__DEV__) {
70
- console.log('[SubscriptionSyncProcessor] 🟢 RENEWAL SUCCESS', {
71
- userId,
72
- productId,
73
- timestamp: new Date().toISOString(),
74
- });
75
- }
51
+ logRenewalStart(event: RenewalDetectedEvent) {
52
+ logger.debug("RENEWAL START", {
53
+ userId: event.userId,
54
+ productId: event.productId,
55
+ newExpirationDate: event.newExpirationDate,
56
+ timestamp: new Date().toISOString(),
57
+ });
76
58
  }
77
59
 
78
- logRenewalError(userId: string, productId: string, error: string) {
79
- console.error('[SubscriptionSyncProcessor] 🔴 RENEWAL FAILED', {
60
+ logRenewalSuccess(userId: string, productId: string) {
61
+ logger.debug("RENEWAL SUCCESS", {
80
62
  userId,
81
63
  productId,
82
- error,
83
64
  timestamp: new Date().toISOString(),
84
65
  });
85
66
  }
86
67
 
87
- logStatusChangeStart(event: PremiumStatusChangedEvent) {
88
- if (__DEV__) {
89
- console.log('[SubscriptionSyncProcessor] 🔵 STATUS CHANGE START', {
90
- userId: event.userId,
91
- isPremium: event.isPremium,
92
- productId: event.productId,
93
- willRenew: event.willRenew,
94
- expirationDate: event.expirationDate,
95
- timestamp: new Date().toISOString(),
96
- });
97
- }
68
+ logRenewalError(userId: string, productId: string, error: string) {
69
+ logger.error("RENEWAL FAILED", error, { userId, productId, timestamp: new Date().toISOString() });
98
70
  }
99
71
 
100
- logStatusChangeSuccess(userId: string, isPremium: boolean, productId?: string) {
101
- if (__DEV__) {
102
- console.log('[SubscriptionSyncProcessor] 🟢 STATUS CHANGE SUCCESS', {
103
- userId,
104
- isPremium,
105
- productId,
106
- timestamp: new Date().toISOString(),
107
- });
108
- }
72
+ logStatusChangeStart(event: PremiumStatusChangedEvent) {
73
+ logger.debug("STATUS CHANGE START", {
74
+ userId: event.userId,
75
+ isPremium: event.isPremium,
76
+ productId: event.productId,
77
+ willRenew: event.willRenew,
78
+ expirationDate: event.expirationDate,
79
+ timestamp: new Date().toISOString(),
80
+ });
109
81
  }
110
82
 
111
- logStatusChangeError(userId: string, isPremium: boolean, productId: string | undefined, error: string) {
112
- console.error('[SubscriptionSyncProcessor] 🔴 STATUS CHANGE FAILED', {
83
+ logStatusChangeSuccess(userId: string, isPremium: boolean, productId?: string) {
84
+ logger.debug("STATUS CHANGE SUCCESS", {
113
85
  userId,
114
86
  isPremium,
115
87
  productId,
116
- error,
117
88
  timestamp: new Date().toISOString(),
118
89
  });
119
90
  }
91
+
92
+ logStatusChangeError(userId: string, isPremium: boolean, productId: string | undefined, error: string) {
93
+ logger.error("STATUS CHANGE FAILED", error, { userId, isPremium, productId, timestamp: new Date().toISOString() });
94
+ }
120
95
  }
@@ -3,6 +3,10 @@
3
3
  * Handles resolution of RevenueCat user ID to credits user ID
4
4
  */
5
5
 
6
+ import { createLogger } from "../../../shared/utils/logger";
7
+
8
+ const logger = createLogger("UserIdResolver");
9
+
6
10
  export class UserIdResolver {
7
11
  constructor(private getAnonymousUserId: () => Promise<string>) {}
8
12
 
@@ -14,7 +18,7 @@ export class UserIdResolver {
14
18
  }
15
19
 
16
20
  // Fallback to anonymous user ID
17
- console.warn("[UserIdResolver] revenueCatUserId is empty/null, falling back to anonymousUserId");
21
+ logger.warn("revenueCatUserId is empty/null, falling back to anonymousUserId");
18
22
  const anonymousId = await this.getAnonymousUserId();
19
23
  const trimmedAnonymous = anonymousId?.trim();
20
24
 
@@ -1,5 +1,5 @@
1
1
  import type { PurchasesPackage, CustomerInfo } from "react-native-purchases";
2
- import type { IRevenueCatService } from "../../../../shared/application/ports/IRevenueCatService";
2
+ import type { IRevenueCatService } from "../../../shared/application/ports/IRevenueCatService";
3
3
  import { PurchaseStatusResolver, type PremiumStatus } from "./PurchaseStatusResolver";
4
4
  import { fetchPackages } from "./package-operations/PackageFetcher";
5
5
  import { executePurchase } from "./package-operations/PackagePurchaser";
@@ -1,6 +1,6 @@
1
1
  import type { CustomerInfo } from "react-native-purchases";
2
2
  import { getPremiumEntitlement } from "../../../revenuecat/core/types/RevenueCatTypes";
3
- import { toDate } from "../../../../shared/utils/dateConverter";
3
+ import { toDate } from "../../../shared/utils/dateConverter";
4
4
  import { detectPackageType } from "../../../../utils/packageTypeDetector";
5
5
  import type { PremiumStatus } from "../../core/types/PremiumStatus";
6
6
 
@@ -1,5 +1,8 @@
1
1
  import type { PurchasesPackage } from "react-native-purchases";
2
2
  import type { IRevenueCatService } from "../../../../../shared/application/ports/IRevenueCatService";
3
+ import { createLogger } from "../../../../../shared/utils/logger";
4
+
5
+ const logger = createLogger("PackageFetcher");
3
6
 
4
7
  export async function fetchPackages(
5
8
  service: IRevenueCatService
@@ -20,12 +23,10 @@ export async function fetchPackages(
20
23
  return [];
21
24
  }
22
25
 
23
- if (__DEV__) {
24
- console.log('[PackageHandler] Returning packages:', {
25
- count: packages.length,
26
- packageIds: packages.map(p => p.product.identifier),
27
- });
28
- }
26
+ logger.debug("Returning packages", {
27
+ count: packages.length,
28
+ packageIds: packages.map(p => p.product.identifier),
29
+ });
29
30
 
30
31
  return packages;
31
32
  } catch (error) {
@@ -1,18 +1,19 @@
1
1
  import type { PurchasesPackage } from "react-native-purchases";
2
2
  import type { IRevenueCatService } from "../../../../../shared/application/ports/IRevenueCatService";
3
+ import { createLogger } from "../../../../../shared/utils/logger";
4
+
5
+ const logger = createLogger("PackagePurchaser");
3
6
 
4
7
  export async function executePurchase(
5
8
  service: IRevenueCatService,
6
9
  pkg: PurchasesPackage,
7
10
  userId: string
8
11
  ): Promise<boolean> {
9
- if (typeof __DEV__ !== "undefined" && __DEV__) {
10
- console.log("[PackagePurchaser] executePurchase called", {
11
- productId: pkg.product.identifier,
12
- userId,
13
- serviceInitialized: service.isInitialized(),
14
- });
15
- }
12
+ logger.debug("executePurchase called", {
13
+ productId: pkg.product.identifier,
14
+ userId,
15
+ serviceInitialized: service.isInitialized(),
16
+ });
16
17
 
17
18
  if (!service.isInitialized()) {
18
19
  throw new Error("Service not initialized");
@@ -7,6 +7,9 @@ import {
7
7
  } from "@umituz/react-native-auth";
8
8
  import { SubscriptionManager } from "../../infrastructure/managers/SubscriptionManager";
9
9
  import { getErrorMessage } from "../../../revenuecat/core/errors/RevenueCatErrorHandler";
10
+ import { createLogger } from "../../../shared/utils/logger";
11
+
12
+ const logger = createLogger("usePurchasePackage");
10
13
 
11
14
  interface PurchaseMutationResult {
12
15
  success: boolean;
@@ -24,9 +27,7 @@ export const usePurchasePackage = () => {
24
27
  }
25
28
 
26
29
  const productId = pkg.product.identifier;
27
- if (typeof __DEV__ !== "undefined" && __DEV__) {
28
- console.log(`[Purchase] Initializing and purchasing. User: ${userId}`);
29
- }
30
+ logger.debug("Initializing and purchasing", { userId, productId });
30
31
 
31
32
  const success = await SubscriptionManager.purchasePackage(pkg, userId);
32
33
 
@@ -1,5 +1,5 @@
1
1
  import type { PurchasesPackage } from "react-native-purchases";
2
- import type { IRevenueCatService } from "../../../../shared/application/ports/IRevenueCatService";
2
+ import type { IRevenueCatService } from "../../../shared/application/ports/IRevenueCatService";
3
3
  import type { PackageHandler } from "../handlers/PackageHandler";
4
4
  import { InitializationCache } from "../utils/InitializationCache";
5
5
  import { ensureServiceAvailable, getCurrentUserIdOrThrow } from "./subscriptionManagerUtils";
@@ -10,6 +10,9 @@ import { getPackagesOperation, purchasePackageOperation, restoreOperation } from
10
10
  import { performServiceInitialization } from "./initializationHandler";
11
11
  import { initializationState } from "../state/initializationState";
12
12
  import { ANONYMOUS_CACHE_KEY } from "../../core/SubscriptionConstants";
13
+ import { createLogger } from "../../../shared/utils/logger";
14
+
15
+ const logger = createLogger("SubscriptionManager");
13
16
 
14
17
  class SubscriptionManagerImpl {
15
18
  private managerConfig: SubscriptionManagerConfig | null = null;
@@ -23,14 +26,14 @@ class SubscriptionManagerImpl {
23
26
 
24
27
  private ensureConfigured(): void {
25
28
  if (!this.managerConfig) {
26
- throw new Error('[SubscriptionManager] Not configured. Call configure() first.');
29
+ throw new Error('SubscriptionManager: Not configured. Call configure() first.');
27
30
  }
28
31
  }
29
32
 
30
33
  private ensurePackageHandlerInitialized(): void {
31
34
  if (this.packageHandler) return;
32
35
  if (!this.serviceInstance || !this.managerConfig) {
33
- throw new Error('[SubscriptionManager] Cannot create package handler without service and config');
36
+ throw new Error('SubscriptionManager: Cannot create package handler without service and config');
34
37
  }
35
38
  this.packageHandler = createPackageHandler(this.serviceInstance, this.managerConfig);
36
39
  }
@@ -40,20 +43,16 @@ class SubscriptionManagerImpl {
40
43
 
41
44
  const actualUserId: string = (userId && userId.length > 0) ? userId : '';
42
45
 
43
- if (typeof __DEV__ !== 'undefined' && __DEV__) {
44
- console.log('[SubscriptionManager] initialize called:', {
45
- providedUserId: userId,
46
- actualUserId: actualUserId || '(empty - RevenueCat will generate anonymous ID)',
47
- });
48
- }
46
+ logger.debug("initialize called", {
47
+ providedUserId: userId,
48
+ actualUserId: actualUserId || '(empty - RevenueCat will generate anonymous ID)',
49
+ });
49
50
 
50
51
  const cacheKey = actualUserId || ANONYMOUS_CACHE_KEY;
51
52
  const { shouldInit, existingPromise } = this.initCache.tryAcquireInitialization(cacheKey);
52
53
 
53
54
  if (!shouldInit && existingPromise) {
54
- if (typeof __DEV__ !== 'undefined' && __DEV__) {
55
- console.log('[SubscriptionManager] Using cached initialization for:', cacheKey);
56
- }
55
+ logger.debug("Using cached initialization for", cacheKey);
57
56
  return existingPromise;
58
57
  }
59
58
 
@@ -67,11 +66,9 @@ class SubscriptionManagerImpl {
67
66
  }
68
67
 
69
68
  private async performInitialization(userId: string): Promise<boolean> {
70
- if (typeof __DEV__ !== 'undefined' && __DEV__) {
71
- console.log('[SubscriptionManager] performInitialization:', {
72
- userId: userId || '(empty - anonymous)',
73
- });
74
- }
69
+ logger.debug("performInitialization", {
70
+ userId: userId || '(empty - anonymous)',
71
+ });
75
72
 
76
73
  const config = this.managerConfig!;
77
74
  const { service, success } = await performServiceInitialization(config.config, userId);
@@ -83,9 +80,7 @@ class SubscriptionManagerImpl {
83
80
  initializationState.markInitialized(notifyUserId);
84
81
  }
85
82
 
86
- if (typeof __DEV__ !== 'undefined' && __DEV__) {
87
- console.log('[SubscriptionManager] Initialization completed:', { success });
88
- }
83
+ logger.debug("Initialization completed", { success });
89
84
 
90
85
  return success;
91
86
  }
@@ -107,14 +102,12 @@ class SubscriptionManagerImpl {
107
102
  if (explicitUserId) {
108
103
  await this.initialize(explicitUserId);
109
104
  }
110
- if (typeof __DEV__ !== 'undefined' && __DEV__) {
111
- console.log('[SubscriptionManager] purchasePackage: init complete, starting purchase', {
112
- productId: pkg.product.identifier,
113
- hasPackageHandler: !!this.packageHandler,
114
- hasService: !!this.serviceInstance,
115
- serviceInitialized: this.serviceInstance?.isInitialized() ?? false,
116
- });
117
- }
105
+ logger.debug("purchasePackage: init complete, starting purchase", {
106
+ productId: pkg.product.identifier,
107
+ hasPackageHandler: !!this.packageHandler,
108
+ hasService: !!this.serviceInstance,
109
+ serviceInitialized: this.serviceInstance?.isInitialized() ?? false,
110
+ });
118
111
  this.ensurePackageHandlerInitialized();
119
112
  const resolvedUserId = explicitUserId || getCurrentUserIdOrThrow(this.initCache);
120
113
  const handler = this.packageHandler!;
@@ -1,4 +1,4 @@
1
- import type { IRevenueCatService } from "../../../../shared/application/ports/IRevenueCatService";
1
+ import type { IRevenueCatService } from "../../../shared/application/ports/IRevenueCatService";
2
2
  import { initializeRevenueCatService, getRevenueCatService } from "../services/revenueCatServiceInstance";
3
3
  import { ensureServiceAvailable } from "./subscriptionManagerUtils";
4
4
  import type { RevenueCatConfig } from "../../../revenuecat/core/types/RevenueCatConfig";
@@ -1,5 +1,5 @@
1
1
  import type { PurchasesPackage } from "react-native-purchases";
2
- import type { IRevenueCatService } from "../../../../shared/application/ports/IRevenueCatService";
2
+ import type { IRevenueCatService } from "../../../shared/application/ports/IRevenueCatService";
3
3
  import type { PackageHandler } from "../handlers/PackageHandler";
4
4
  import type { RestoreResultInfo } from "./SubscriptionManager.types";
5
5
  import { ensureConfigured, getOrCreateService } from "./subscriptionManagerUtils";
@@ -1,4 +1,4 @@
1
- import type { IRevenueCatService } from "../../../../shared/application/ports/IRevenueCatService";
1
+ import type { IRevenueCatService } from "../../../shared/application/ports/IRevenueCatService";
2
2
  import { PackageHandler } from "../handlers/PackageHandler";
3
3
  import { ensureServiceAvailable, ensureConfigured } from "./subscriptionManagerUtils";
4
4
  import type { SubscriptionManagerConfig } from "./SubscriptionManager.types";
@@ -1,4 +1,4 @@
1
- import type { IRevenueCatService } from "../../../../shared/application/ports/IRevenueCatService";
1
+ import type { IRevenueCatService } from "../../../shared/application/ports/IRevenueCatService";
2
2
  import type { PackageHandler } from "../handlers/PackageHandler";
3
3
  import type { PremiumStatus } from "./SubscriptionManager.types";
4
4
 
@@ -1,5 +1,5 @@
1
1
  import type { SubscriptionManagerConfig } from "./SubscriptionManager.types";
2
- import type { IRevenueCatService } from "../../../../shared/application/ports/IRevenueCatService";
2
+ import type { IRevenueCatService } from "../../../shared/application/ports/IRevenueCatService";
3
3
  import { getRevenueCatService } from "../services/revenueCatServiceInstance";
4
4
  import type { InitializationCache } from "../utils/InitializationCache";
5
5
 
@@ -2,6 +2,9 @@ import Purchases, { type CustomerInfo } from "react-native-purchases";
2
2
  import type { RevenueCatConfig } from "../../../revenuecat/core/types/RevenueCatConfig";
3
3
  import { ListenerState } from "./listeners/ListenerState";
4
4
  import { processCustomerInfo } from "./listeners/CustomerInfoHandler";
5
+ import { createLogger } from "../../../shared/utils/logger";
6
+
7
+ const logger = createLogger("CustomerInfoListenerManager");
5
8
 
6
9
  export class CustomerInfoListenerManager {
7
10
  private state = new ListenerState();
@@ -33,7 +36,7 @@ export class CustomerInfoListenerManager {
33
36
  this._createAndAttachListener(config);
34
37
  return true;
35
38
  } catch (error) {
36
- console.error("[CustomerInfoListenerManager] Failed to setup listener:", error);
39
+ logger.error("Failed to setup listener", error);
37
40
  this.state.currentUserId = null;
38
41
  return false;
39
42
  }
@@ -41,13 +44,11 @@ export class CustomerInfoListenerManager {
41
44
 
42
45
  private _createAndAttachListener(config: RevenueCatConfig): void {
43
46
  this.state.listener = async (customerInfo: CustomerInfo) => {
44
- if (typeof __DEV__ !== "undefined" && __DEV__) {
45
- console.log("[CustomerInfoListener] 🔔 LISTENER TRIGGERED!", {
46
- userId: this.state.currentUserId,
47
- activeEntitlements: Object.keys(customerInfo.entitlements.active),
48
- entitlementsCount: Object.keys(customerInfo.entitlements.all).length,
49
- });
50
- }
47
+ logger.debug("LISTENER TRIGGERED", {
48
+ userId: this.state.currentUserId,
49
+ activeEntitlements: Object.keys(customerInfo.entitlements.active),
50
+ entitlementsCount: Object.keys(customerInfo.entitlements.all).length,
51
+ });
51
52
 
52
53
  const capturedUserId = this.state.currentUserId;
53
54
  if (!capturedUserId) {
@@ -67,7 +68,7 @@ export class CustomerInfoListenerManager {
67
68
  }
68
69
  // else: User switched during async operation, discard stale renewal state
69
70
  } catch (error) {
70
- console.error("[CustomerInfoListener] processCustomerInfo failed:", error);
71
+ logger.error("processCustomerInfo failed", error);
71
72
  }
72
73
  };
73
74
 
@@ -1,4 +1,7 @@
1
1
  import Purchases, { type PurchasesOffering } from "react-native-purchases";
2
+ import { createLogger } from "../../../shared/utils/logger";
3
+
4
+ const logger = createLogger("OfferingsFetcher");
2
5
 
3
6
  interface OfferingsFetcherDeps {
4
7
  isInitialized: () => boolean;
@@ -14,15 +17,13 @@ export async function fetchOfferings(deps: OfferingsFetcherDeps): Promise<Purcha
14
17
  try {
15
18
  const offerings = await Purchases.getOfferings();
16
19
 
17
- if (typeof __DEV__ !== "undefined" && __DEV__) {
18
- console.log('[OfferingsFetcher] Offerings received:', {
19
- attempt,
20
- hasCurrent: !!offerings.current,
21
- currentId: offerings.current?.identifier,
22
- allOfferingsCount: Object.keys(offerings.all).length,
23
- allOfferingIds: Object.keys(offerings.all),
24
- });
25
- }
20
+ logger.debug("Offerings received", {
21
+ attempt,
22
+ hasCurrent: !!offerings.current,
23
+ currentId: offerings.current?.identifier,
24
+ allOfferingsCount: Object.keys(offerings.all).length,
25
+ allOfferingIds: Object.keys(offerings.all),
26
+ });
26
27
 
27
28
  if (offerings.current) {
28
29
  return offerings.current;
@@ -35,28 +36,20 @@ export async function fetchOfferings(deps: OfferingsFetcherDeps): Promise<Purcha
35
36
 
36
37
  // No offerings found - retry after delay (RevenueCat may still be syncing)
37
38
  if (attempt < MAX_FETCH_RETRIES) {
38
- if (typeof __DEV__ !== "undefined" && __DEV__) {
39
- console.log('[OfferingsFetcher] No offerings found, retrying...', { attempt: attempt + 1 });
40
- }
39
+ logger.debug("No offerings found, retrying...", { attempt: attempt + 1 });
41
40
  await new Promise<void>(resolve => setTimeout(resolve, FETCH_RETRY_DELAY_MS));
42
41
  continue;
43
42
  }
44
43
 
45
- if (typeof __DEV__ !== "undefined" && __DEV__) {
46
- console.warn('[OfferingsFetcher] No offerings found after all retries');
47
- }
44
+ logger.warn("No offerings found after all retries");
48
45
  return null;
49
46
  } catch (error) {
50
47
  if (attempt < MAX_FETCH_RETRIES) {
51
- if (typeof __DEV__ !== "undefined" && __DEV__) {
52
- console.warn('[OfferingsFetcher] Fetch failed, retrying...', { attempt: attempt + 1, error });
53
- }
48
+ logger.warn("Fetch failed, retrying...", error, { attempt: attempt + 1 });
54
49
  await new Promise<void>(resolve => setTimeout(resolve, FETCH_RETRY_DELAY_MS));
55
50
  continue;
56
51
  }
57
- if (typeof __DEV__ !== "undefined" && __DEV__) {
58
- console.warn('[OfferingsFetcher] Failed to fetch offerings after all retries:', error);
59
- }
52
+ logger.warn("Failed to fetch offerings after all retries", error);
60
53
  return null;
61
54
  }
62
55
  }
@@ -1,10 +1,13 @@
1
1
  import type { PurchasesPackage } from "react-native-purchases";
2
- import type { PurchaseResult } from "../../../../shared/application/ports/IRevenueCatService";
2
+ import type { PurchaseResult } from "../../../shared/application/ports/IRevenueCatService";
3
3
  import type { RevenueCatConfig } from "../../../revenuecat/core/types/RevenueCatConfig";
4
4
  import { isUserCancelledError, isAlreadyPurchasedError } from "../../../revenuecat/core/types/RevenueCatTypes";
5
5
  import { validatePurchaseReady, isConsumableProduct } from "./purchase/PurchaseValidator";
6
6
  import { executePurchase } from "./purchase/PurchaseExecutor";
7
7
  import { handleAlreadyPurchasedError, handlePurchaseError } from "./purchase/PurchaseErrorHandler";
8
+ import { createLogger } from "../../../shared/utils/logger";
9
+
10
+ const logger = createLogger("PurchaseHandler");
8
11
 
9
12
  export interface PurchaseHandlerDeps {
10
13
  config: RevenueCatConfig;
@@ -21,13 +24,11 @@ export async function handlePurchase(
21
24
  const consumableIds = deps.config.consumableProductIdentifiers || [];
22
25
  const isConsumable = isConsumableProduct(pkg, consumableIds);
23
26
 
24
- if (typeof __DEV__ !== "undefined" && __DEV__) {
25
- console.log("[PurchaseHandler] handlePurchase:", {
26
- productId: pkg.product.identifier,
27
- userId,
28
- isConsumable,
29
- });
30
- }
27
+ logger.debug("handlePurchase", {
28
+ productId: pkg.product.identifier,
29
+ userId,
30
+ isConsumable,
31
+ });
31
32
 
32
33
  try {
33
34
  const result = await executePurchase(deps.config, userId, pkg, isConsumable);
@@ -1,5 +1,5 @@
1
1
  import Purchases from "react-native-purchases";
2
- import type { RestoreResult } from "../../../../shared/application/ports/IRevenueCatService";
2
+ import type { RestoreResult } from "../../../shared/application/ports/IRevenueCatService";
3
3
  import {
4
4
  RevenueCatRestoreError,
5
5
  RevenueCatInitializationError,
@@ -1,6 +1,6 @@
1
1
  import Purchases from "react-native-purchases";
2
2
  import type { PurchasesOffering, PurchasesPackage, CustomerInfo } from "react-native-purchases";
3
- import type { IRevenueCatService, InitializeResult, PurchaseResult, RestoreResult } from "../../../../shared/application/ports/IRevenueCatService";
3
+ import type { IRevenueCatService, InitializeResult, PurchaseResult, RestoreResult } from "../../../shared/application/ports/IRevenueCatService";
4
4
  import type { RevenueCatConfig } from "../../../revenuecat/core/types/RevenueCatConfig";
5
5
  import { initializeSDK } from "../../../revenuecat/infrastructure/services/RevenueCatInitializer";
6
6
  import { fetchOfferings } from "./OfferingsFetcher";
@@ -8,6 +8,9 @@ import { handlePurchase } from "./PurchaseHandler";
8
8
  import { handleRestore } from "./RestoreHandler";
9
9
  import { CustomerInfoListenerManager } from "./CustomerInfoListenerManager";
10
10
  import { ServiceStateManager } from "./ServiceStateManager";
11
+ import { createLogger } from "../../../shared/utils/logger";
12
+
13
+ const logger = createLogger("RevenueCatService");
11
14
 
12
15
  export class RevenueCatService implements IRevenueCatService {
13
16
  private stateManager: ServiceStateManager;
@@ -83,9 +86,7 @@ export class RevenueCatService implements IRevenueCatService {
83
86
  try {
84
87
  await Purchases.logOut();
85
88
  } catch (error) {
86
- if (__DEV__) {
87
- console.warn('[RevenueCatService] logOut failed during reset', { error });
88
- }
89
+ logger.warn("logOut failed during reset", error);
89
90
  }
90
91
  }
91
92