@umituz/react-native-subscription 2.14.99 → 2.14.101

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 (98) hide show
  1. package/README.md +211 -394
  2. package/package.json +3 -3
  3. package/src/application/README.md +46 -225
  4. package/src/application/ports/README.md +42 -97
  5. package/src/domain/README.md +36 -384
  6. package/src/domain/constants/README.md +0 -56
  7. package/src/domain/entities/README.md +43 -169
  8. package/src/domain/entities/SubscriptionStatus.ts +1 -1
  9. package/src/domain/errors/README.md +33 -287
  10. package/src/domain/value-objects/README.md +43 -179
  11. package/src/domains/README.md +50 -238
  12. package/src/domains/README.md.bak +274 -0
  13. package/src/domains/config/README.md +93 -383
  14. package/src/domains/config/domain/README.md +23 -376
  15. package/src/domains/config/domain/entities/README.md +34 -343
  16. package/src/domains/paywall/README.md +99 -369
  17. package/src/domains/paywall/components/README.md +34 -178
  18. package/src/domains/paywall/entities/README.md +34 -193
  19. package/src/domains/paywall/hooks/README.md +34 -122
  20. package/src/domains/wallet/README.md +34 -275
  21. package/src/domains/wallet/README.md.bak +209 -0
  22. package/src/domains/wallet/domain/README.md +34 -101
  23. package/src/domains/wallet/domain/entities/README.md +34 -115
  24. package/src/domains/wallet/domain/errors/README.md +34 -151
  25. package/src/domains/wallet/infrastructure/README.md +34 -89
  26. package/src/domains/wallet/presentation/components/README.md +34 -224
  27. package/src/domains/wallet/presentation/components/TransactionItem.tsx +1 -1
  28. package/src/domains/wallet/presentation/hooks/README.md +34 -248
  29. package/src/infrastructure/README.md +37 -496
  30. package/src/infrastructure/mappers/README.md +0 -13
  31. package/src/infrastructure/repositories/README.md +74 -360
  32. package/src/infrastructure/services/ActivationHandler.ts +1 -1
  33. package/src/infrastructure/services/README.md +95 -370
  34. package/src/infrastructure/services/SubscriptionService.ts +1 -1
  35. package/src/presentation/README.md +123 -408
  36. package/src/presentation/README.md.bak +172 -0
  37. package/src/presentation/components/README.md +151 -179
  38. package/src/presentation/components/README.md.bak +217 -0
  39. package/src/presentation/components/details/CreditRow.md +65 -310
  40. package/src/presentation/components/details/DetailRow.md +63 -255
  41. package/src/presentation/components/details/PremiumDetailsCard.md +65 -238
  42. package/src/presentation/components/details/PremiumStatusBadge.md +64 -239
  43. package/src/presentation/components/details/README.md +97 -447
  44. package/src/presentation/components/feedback/PaywallFeedbackModal.md +63 -287
  45. package/src/presentation/components/feedback/README.md +97 -445
  46. package/src/presentation/components/paywall/PaywallModal.md +66 -416
  47. package/src/presentation/components/paywall/README.md +50 -186
  48. package/src/presentation/components/sections/README.md +97 -466
  49. package/src/presentation/components/sections/SubscriptionSection.md +92 -244
  50. package/src/presentation/hooks/README.md +154 -741
  51. package/src/presentation/hooks/useAuthAwarePurchase.md +58 -325
  52. package/src/presentation/hooks/useAuthGate.md +61 -375
  53. package/src/presentation/hooks/useAuthSubscriptionSync.md +66 -370
  54. package/src/presentation/hooks/useCreditChecker.md +73 -378
  55. package/src/presentation/hooks/useCredits.md +74 -313
  56. package/src/presentation/hooks/useCredits.md.bak +231 -0
  57. package/src/presentation/hooks/useCreditsGate.md +66 -318
  58. package/src/presentation/hooks/useDeductCredit.md +0 -76
  59. package/src/presentation/hooks/useDeductCredit.ts +1 -1
  60. package/src/presentation/hooks/useDevTestCallbacks.md +63 -394
  61. package/src/presentation/hooks/useFeatureGate.md +105 -150
  62. package/src/presentation/hooks/useFeatureGate.md.bak +284 -0
  63. package/src/presentation/hooks/useInitializeCredits.md +64 -430
  64. package/src/presentation/hooks/usePaywall.md +61 -306
  65. package/src/presentation/hooks/usePaywallOperations.md +64 -458
  66. package/src/presentation/hooks/usePaywallVisibility.md +67 -316
  67. package/src/presentation/hooks/usePremium.md +84 -226
  68. package/src/presentation/hooks/usePremiumGate.md +60 -395
  69. package/src/presentation/hooks/usePremiumWithCredits.md +64 -401
  70. package/src/presentation/hooks/useSubscription.md +66 -422
  71. package/src/presentation/hooks/useSubscriptionDetails.md +65 -410
  72. package/src/presentation/hooks/useSubscriptionGate.md +80 -164
  73. package/src/presentation/hooks/useSubscriptionSettingsConfig.md +66 -346
  74. package/src/presentation/hooks/useSubscriptionStatus.md +66 -396
  75. package/src/presentation/hooks/useUserTier.md +63 -328
  76. package/src/presentation/hooks/useUserTierWithRepository.md +64 -424
  77. package/src/presentation/screens/README.md +48 -190
  78. package/src/presentation/types/README.md +0 -16
  79. package/src/presentation/utils/README.md +0 -21
  80. package/src/presentation/utils/subscriptionDateUtils.ts +1 -1
  81. package/src/revenuecat/README.md +99 -518
  82. package/src/revenuecat/application/README.md +35 -150
  83. package/src/revenuecat/application/ports/README.md +34 -162
  84. package/src/revenuecat/domain/README.md +42 -141
  85. package/src/revenuecat/domain/constants/README.md +34 -176
  86. package/src/revenuecat/domain/entities/README.md +34 -374
  87. package/src/revenuecat/domain/errors/README.md +47 -191
  88. package/src/revenuecat/domain/types/README.md +34 -366
  89. package/src/revenuecat/domain/value-objects/README.md +34 -434
  90. package/src/revenuecat/infrastructure/README.md +34 -43
  91. package/src/revenuecat/infrastructure/config/README.md +32 -23
  92. package/src/revenuecat/infrastructure/handlers/README.md +34 -211
  93. package/src/revenuecat/infrastructure/managers/README.md +34 -42
  94. package/src/revenuecat/infrastructure/services/README.md +35 -318
  95. package/src/revenuecat/infrastructure/utils/README.md +34 -375
  96. package/src/revenuecat/presentation/README.md +34 -176
  97. package/src/revenuecat/presentation/hooks/README.md +29 -35
  98. package/src/utils/README.md +38 -525
@@ -2,397 +2,93 @@
2
2
 
3
3
  Automatically synchronizes subscription state with authentication changes.
4
4
 
5
- ## Import
5
+ ## Location
6
6
 
7
- ```typescript
8
- import { useAuthSubscriptionSync } from '@umituz/react-native-subscription';
9
- ```
7
+ **Import Path**: `@umituz/react-native-subscription`
10
8
 
11
- ## Signature
9
+ **File**: `src/presentation/hooks/useAuthSubscriptionSync.ts`
12
10
 
13
- ```typescript
14
- function useAuthSubscriptionSync(config: {
15
- onAuthStateChanged: (callback: (userId: string | null) => void) => () => void;
16
- initializeSubscription: (userId: string) => Promise<void>;
17
- }): void
18
- ```
11
+ **Type**: Hook
19
12
 
20
- ## Parameters
13
+ ## Strategy
21
14
 
22
- | Parameter | Type | Default | Description |
23
- |-----------|------|---------|-------------|
24
- | `onAuthStateChanged` | `(callback) => () => void` | **Required** | Subscribe to auth changes, returns unsubscribe function |
25
- | `initializeSubscription` | `(userId) => Promise<void>` | **Required** | Initialize subscription for user |
15
+ ### Auth-Subscription Synchronization
26
16
 
27
- ## Basic Usage
17
+ 1. **Auth Listener Setup**: Subscribe to auth state changes via provided callback
18
+ 2. **User Change Detection**: Detect when userId changes (including sign out)
19
+ 3. **Subscription Initialization**: Initialize subscription when user signs in
20
+ 4. **One-Time Init**: Only initialize once per user session (skips duplicates)
21
+ 5. **User Switching**: Re-initialize when switching between accounts
22
+ 6. **Cleanup**: Unsubscribe from auth listener on unmount
28
23
 
29
- ```typescript
30
- function App() {
31
- useAuthSubscriptionSync({
32
- onAuthStateChanged: (callback) => {
33
- // Subscribe to Firebase auth changes
34
- const unsubscribe = auth.onAuthStateChanged((user) => {
35
- callback(user?.uid || null);
36
- });
37
- return unsubscribe;
38
- },
39
- initializeSubscription: async (userId) => {
40
- // Initialize RevenueCat or subscription service
41
- await Purchases.configure({ apiKey: 'your_key', appUserID: userId });
42
- await fetchSubscriptionStatus(userId);
43
- },
44
- });
24
+ ### Integration Points
45
25
 
46
- return <YourAppNavigation />;
47
- }
48
- ```
26
+ - **Auth Provider**: Any auth system (Firebase, Auth0, custom)
27
+ - **RevenueCat**: For subscription initialization with logIn
28
+ - **Subscription Service**: Backend subscription sync
29
+ - **Credits System**: Optional credits initialization
30
+ - **App Root**: Should be placed in root App component
49
31
 
50
- ## Advanced Usage
32
+ ## Restrictions
51
33
 
52
- ### With Firebase Auth
34
+ ### REQUIRED
53
35
 
54
- ```typescript
55
- function AppWithFirebase() {
56
- useAuthSubscriptionSync({
57
- onAuthStateChanged: (callback) => {
58
- const unsubscribe = auth.onAuthStateChanged((user) => {
59
- callback(user?.uid || null);
60
- });
61
- return unsubscribe;
62
- },
63
- initializeSubscription: async (userId) => {
64
- if (!userId) return;
36
+ - **Auth State Change Callback**: MUST provide onAuthStateChanged function
37
+ - **Subscription Init**: MUST provide initializeSubscription function
38
+ - **App Root Setup**: SHOULD be placed in root App component
39
+ - **Unsubscribe Handling**: Callback MUST return unsubscribe function
65
40
 
66
- // Configure RevenueCat with user ID
67
- await Purchases.logIn(userId);
68
- await syncSubscriptionWithBackend(userId);
69
- },
70
- });
41
+ ### PROHIBITED
71
42
 
72
- return <AppNavigator />;
73
- }
74
- ```
43
+ - **NEVER** place in individual screen components (use app root)
44
+ - **NEVER** call without proper auth callback
45
+ - **DO NOT** manually call initializeSubscription (hook handles it)
46
+ - **DO NOT** configure multiple times (one-time setup)
75
47
 
76
- ### With Custom Auth Provider
48
+ ### CRITICAL SAFETY
77
49
 
78
- ```typescript
79
- function AppWithCustomAuth() {
80
- const authManager = useAuthManager();
50
+ - **ALWAYS** configure at app root level
51
+ - **MUST** handle user switching correctly
52
+ - **ALWAYS** return unsubscribe function from callback
53
+ - **NEVER** rely on manual subscription initialization
81
54
 
82
- useAuthSubscriptionSync({
83
- onAuthStateChanged: (callback) => {
84
- // Your custom auth system
85
- const unsubscribe = authManager.addListener((user) => {
86
- callback(user?.id || null);
87
- });
88
- return unsubscribe;
89
- },
90
- initializeSubscription: async (userId) => {
91
- // Initialize your subscription system
92
- await subscriptionService.initialize(userId);
93
- await loadSubscriptionData(userId);
94
- },
95
- });
55
+ ## AI Agent Guidelines
96
56
 
97
- return <App />;
98
- }
99
- ```
57
+ ### When Implementing Auth-Subscription Sync
100
58
 
101
- ### With Multiple Subscription Services
59
+ 1. **Always** place in root App component
60
+ 2. **Always** provide onAuthStateChanged that returns unsubscribe
61
+ 3. **Always** provide initializeSubscription for user ID
62
+ 4. **Always** test user switching scenarios
63
+ 5. **Never** place in child components
102
64
 
103
- ```typescript
104
- function AppWithMultipleServices() {
105
- useAuthSubscriptionSync({
106
- onAuthStateChanged: (callback) => {
107
- return auth.onAuthStateChanged((user) => {
108
- callback(user?.uid || null);
109
- });
110
- },
111
- initializeSubscription: async (userId) => {
112
- // Initialize RevenueCat
113
- await Purchases.logIn(userId);
65
+ ### Integration Checklist
114
66
 
115
- // Initialize custom credits system
116
- await creditsRepository.initialize(userId);
67
+ - [ ] Import from correct path: `@umituz/react-native-subscription`
68
+ - [ ] Place in root App component
69
+ - [ ] Provide onAuthStateChanged callback
70
+ - [ ] Ensure callback returns unsubscribe function
71
+ - [ ] Provide initializeSubscription function
72
+ - [ ] Test with initial user sign-in
73
+ - [ ] Test with user sign-out
74
+ - [ ] Test with account switching
75
+ - [ ] Verify subscription initializes only once per user
76
+ - [ ] Test cleanup on unmount
117
77
 
118
- // Sync with backend
119
- await subscriptionSyncService.sync(userId);
120
- },
121
- });
78
+ ### Common Patterns
122
79
 
123
- return <App />;
124
- }
125
- ```
80
+ 1. **Firebase + RevenueCat**: Sync Firebase auth with RevenueCat
81
+ 2. **Custom Auth + Backend**: Use custom auth with backend sync
82
+ 3. **Multi-Service Setup**: Initialize multiple services (RevenueCat, credits, backend)
83
+ 4. **Error Handling**: Handle initialization failures gracefully
84
+ 5. **Loading State**: Show loading during sync
85
+ 6. **Analytics Tracking**: Track auth and subscription events
126
86
 
127
- ### With Error Handling
87
+ ## Related Documentation
128
88
 
129
- ```typescript
130
- function AppWithErrorHandling() {
131
- const [syncError, setSyncError] = useState<Error | null>(null);
132
-
133
- useAuthSubscriptionSync({
134
- onAuthStateChanged: (callback) => {
135
- return auth.onAuthStateChanged((user) => {
136
- callback(user?.uid || null);
137
- });
138
- },
139
- initializeSubscription: async (userId) => {
140
- try {
141
- setSyncError(null);
142
- await Purchases.logIn(userId);
143
- await syncSubscriptionData(userId);
144
- } catch (error) {
145
- console.error('Subscription sync failed:', error);
146
- setSyncError(error as Error);
147
- // Optionally retry or show error to user
148
- }
149
- },
150
- });
151
-
152
- if (syncError) {
153
- return <ErrorScreen error={syncError} />;
154
- }
155
-
156
- return <AppNavigation />;
157
- }
158
- ```
159
-
160
- ### With Loading State
161
-
162
- ```typescript
163
- function AppWithLoadingState() {
164
- const [isSyncing, setIsSyncing] = useState(false);
165
- const [isInitialized, setIsInitialized] = useState(false);
166
-
167
- useAuthSubscriptionSync({
168
- onAuthStateChanged: (callback) => {
169
- return auth.onAuthStateChanged((user) => {
170
- callback(user?.uid || null);
171
- });
172
- },
173
- initializeSubscription: async (userId) => {
174
- if (!userId) {
175
- setIsInitialized(false);
176
- return;
177
- }
178
-
179
- setIsSyncing(true);
180
- try {
181
- await Purchases.logIn(userId);
182
- await loadUserSubscription(userId);
183
- setIsInitialized(true);
184
- } finally {
185
- setIsSyncing(false);
186
- }
187
- },
188
- });
189
-
190
- if (isSyncing) {
191
- return <LoadingScreen message="Syncing subscription..." />;
192
- }
193
-
194
- return <AppNavigation />;
195
- }
196
- ```
197
-
198
- ## Examples
199
-
200
- ### Complete App Setup
201
-
202
- ```typescript
203
- import React from 'react';
204
- import { useAuthSubscriptionSync } from '@umituz/react-native-subscription';
205
- import { auth } from './firebase/config';
206
- import { Purchases } from 'react-native-purchases';
207
- import { subscriptionService } from './services/subscription';
208
-
209
- function App() {
210
- useAuthSubscriptionSync({
211
- onAuthStateChanged: (callback) => {
212
- const unsubscribe = auth.onAuthStateChanged(async (user) => {
213
- console.log('Auth state changed:', user?.uid || 'none');
214
- callback(user?.uid || null);
215
- });
216
- return unsubscribe;
217
- },
218
- initializeSubscription: async (userId) => {
219
- if (!userId) {
220
- console.log('No user, skipping subscription init');
221
- return;
222
- }
223
-
224
- console.log('Initializing subscription for:', userId);
225
-
226
- try {
227
- // Step 1: Identify user in RevenueCat
228
- await Purchases.logIn(userId);
229
-
230
- // Step 2: Fetch subscription status
231
- await subscriptionService.fetchStatus(userId);
232
-
233
- // Step 3: Sync with backend
234
- await subscriptionService.syncWithBackend(userId);
235
-
236
- console.log('Subscription initialized successfully');
237
- } catch (error) {
238
- console.error('Failed to initialize subscription:', error);
239
- }
240
- },
241
- });
242
-
243
- return <AppNavigator />;
244
- }
245
-
246
- export default App;
247
- ```
248
-
249
- ### With Analytics Tracking
250
-
251
- ```typescript
252
- function AppWithAnalytics() {
253
- useAuthSubscriptionSync({
254
- onAuthStateChanged: (callback) => {
255
- return auth.onAuthStateChanged((user) => {
256
- const userId = user?.uid || null;
257
- analytics.identify(userId);
258
- callback(userId);
259
- });
260
- },
261
- initializeSubscription: async (userId) => {
262
- analytics.track('subscription_sync_start', { userId });
263
-
264
- await Purchases.logIn(userId);
265
-
266
- const customerInfo = await Purchases.getCustomerInfo();
267
- const isPremium = !!customerInfo.entitlements.active.premium;
268
-
269
- analytics.track('subscription_sync_complete', {
270
- userId,
271
- isPremium,
272
- });
273
- },
274
- });
275
-
276
- return <App />;
277
- }
278
- ```
279
-
280
- ### With User Switching
281
-
282
- ```typescript
283
- function AppWithUserSwitching() {
284
- useAuthSubscriptionSync({
285
- onAuthStateChanged: (callback) => {
286
- return auth.onAuthStateChanged((user) => {
287
- const newUserId = user?.uid || null;
288
- console.log('User changed:', newUserId);
289
- callback(newUserId);
290
- });
291
- },
292
- initializeSubscription: async (userId) => {
293
- if (!userId) {
294
- // User signed out - clear subscription data
295
- subscriptionService.clear();
296
- return;
297
- }
298
-
299
- // New user signed in or account switch
300
- // The hook handles detecting userId changes
301
- await Purchases.logIn(userId);
302
- await subscriptionService.loadForUser(userId);
303
- },
304
- });
305
-
306
- return <App />;
307
- }
308
- ```
309
-
310
- ## How It Works
311
-
312
- ### Automatic Initialization
313
-
314
- The hook automatically:
315
-
316
- 1. **Listens to auth changes** - Subscribes to your auth provider
317
- 2. **Detects user changes** - Identifies when user ID changes
318
- 3. **Initializes once** - Only initializes once per user session
319
- 4. **Re-initializes on user switch** - Detects account switching
320
- 5. **Cleans up** - Unsubscribes when component unmounts
321
-
322
- ### User Change Detection
323
-
324
- ```typescript
325
- // Initial mount with user A
326
- auth.onAuthStateChanged => callback('user-a-id')
327
- initializeSubscription('user-a-id') // ✅ Runs
328
-
329
- // Same user, no change
330
- auth.onAuthStateChanged => callback('user-a-id')
331
- initializeSubscription('user-a-id') // ❌ Skipped (same user)
332
-
333
- // User switches to user B
334
- auth.onAuthStateChanged => callback('user-b-id')
335
- initializeSubscription('user-b-id') // ✅ Runs (user changed)
336
-
337
- // User signs out
338
- auth.onAuthStateChanged => callback(null)
339
- // ❌ No initialization (no user)
340
- ```
341
-
342
- ## Best Practices
343
-
344
- 1. **Configure at app root** - Place in root App component
345
- 2. **Handle errors gracefully** - Catch and log initialization errors
346
- 3. **Show loading state** - Display loading during sync
347
- 4. **Test user switching** - Verify account switching works
348
- 5. **Cleanup properly** - Let hook handle unsubscribe
349
- 6. **One-time setup** - Configure once, don't reinitialize
350
- 7. **Monitor logs** - Use dev logs to verify behavior
351
-
352
- ## Common Patterns
353
-
354
- ### Firebase + RevenueCat
355
-
356
- ```typescript
357
- useAuthSubscriptionSync({
358
- onAuthStateChanged: (callback) => auth.onAuthStateChanged((user) => callback(user?.uid || null)),
359
- initializeSubscription: (userId) => Purchases.logIn(userId),
360
- });
361
- ```
362
-
363
- ### Custom Auth + Backend
364
-
365
- ```typescript
366
- useAuthSubscriptionSync({
367
- onAuthStateChanged: (callback) => customAuth.onAuthChange((user) => callback(user?.id || null)),
368
- initializeSubscription: (userId) => backend.syncSubscription(userId),
369
- });
370
- ```
371
-
372
- ### Multi-Service Setup
373
-
374
- ```typescript
375
- useAuthSubscriptionSync({
376
- onAuthStateChanged: (callback) => auth.onAuthStateChanged((user) => callback(user?.uid)),
377
- initializeSubscription: async (userId) => {
378
- await Promise.all([
379
- Purchases.logIn(userId),
380
- creditsService.init(userId),
381
- subscriptionBackend.sync(userId),
382
- ]);
383
- },
384
- });
385
- ```
386
-
387
- ## Related Hooks
388
-
389
- - **useAuth** - For authentication state
390
- - **usePremium** - For subscription status
391
- - **useAuthAwarePurchase** - For auth-gated purchases
392
- - **useUserTier** - For tier determination
393
-
394
- ## See Also
395
-
396
- - [Auth Integration Guide](../../../docs/AUTH_INTEGRATION.md)
397
- - [RevenueCat Setup](../../../docs/REVENUECAT_SETUP.md)
398
- - [Subscription State Management](../providers/README.md)
89
+ - **useAuth**: For authentication state
90
+ - **usePremium**: For subscription status
91
+ - **useAuthAwarePurchase**: For auth-gated purchases
92
+ - **useUserTier**: For tier determination
93
+ - **Auth Integration Guide**: `src/docs/AUTH_INTEGRATION.md`
94
+ - **RevenueCat Setup**: `src/docs/REVENUECAT_SETUP.md`