@umituz/react-native-subscription 2.14.98 → 2.14.100

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 (92) hide show
  1. package/README.md +211 -395
  2. package/package.json +1 -1
  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/errors/README.md +33 -287
  9. package/src/domain/value-objects/README.md +43 -179
  10. package/src/domains/README.md +52 -0
  11. package/src/domains/README.md.bak +274 -0
  12. package/src/domains/config/README.md +93 -383
  13. package/src/domains/config/domain/README.md +37 -0
  14. package/src/domains/config/domain/entities/README.md +41 -0
  15. package/src/domains/paywall/README.md +99 -369
  16. package/src/domains/paywall/components/README.md +34 -178
  17. package/src/domains/paywall/entities/README.md +34 -193
  18. package/src/domains/paywall/hooks/README.md +34 -122
  19. package/src/domains/wallet/README.md +34 -275
  20. package/src/domains/wallet/README.md.bak +209 -0
  21. package/src/domains/wallet/domain/README.md +34 -101
  22. package/src/domains/wallet/domain/entities/README.md +34 -115
  23. package/src/domains/wallet/domain/errors/README.md +34 -151
  24. package/src/domains/wallet/infrastructure/README.md +34 -89
  25. package/src/domains/wallet/presentation/components/README.md +34 -224
  26. package/src/domains/wallet/presentation/hooks/README.md +34 -248
  27. package/src/infrastructure/README.md +37 -496
  28. package/src/infrastructure/mappers/README.md +0 -13
  29. package/src/infrastructure/repositories/README.md +74 -360
  30. package/src/infrastructure/services/README.md +95 -370
  31. package/src/presentation/README.md +123 -408
  32. package/src/presentation/README.md.bak +172 -0
  33. package/src/presentation/components/README.md +151 -179
  34. package/src/presentation/components/README.md.bak +217 -0
  35. package/src/presentation/components/details/CreditRow.md +65 -310
  36. package/src/presentation/components/details/DetailRow.md +63 -255
  37. package/src/presentation/components/details/PremiumDetailsCard.md +65 -238
  38. package/src/presentation/components/details/PremiumStatusBadge.md +64 -239
  39. package/src/presentation/components/details/README.md +97 -447
  40. package/src/presentation/components/feedback/PaywallFeedbackModal.md +63 -287
  41. package/src/presentation/components/feedback/README.md +97 -445
  42. package/src/presentation/components/paywall/PaywallModal.md +66 -416
  43. package/src/presentation/components/paywall/README.md +50 -186
  44. package/src/presentation/components/sections/README.md +97 -466
  45. package/src/presentation/components/sections/SubscriptionSection.md +92 -244
  46. package/src/presentation/hooks/README.md +154 -741
  47. package/src/presentation/hooks/useAuthAwarePurchase.md +58 -325
  48. package/src/presentation/hooks/useAuthGate.md +61 -375
  49. package/src/presentation/hooks/useAuthSubscriptionSync.md +66 -370
  50. package/src/presentation/hooks/useCreditChecker.md +73 -378
  51. package/src/presentation/hooks/useCredits.md +74 -313
  52. package/src/presentation/hooks/useCredits.md.bak +231 -0
  53. package/src/presentation/hooks/useCreditsGate.md +66 -318
  54. package/src/presentation/hooks/useDeductCredit.md +96 -156
  55. package/src/presentation/hooks/useDevTestCallbacks.md +63 -394
  56. package/src/presentation/hooks/useFeatureGate.md +105 -150
  57. package/src/presentation/hooks/useFeatureGate.md.bak +284 -0
  58. package/src/presentation/hooks/useInitializeCredits.md +64 -430
  59. package/src/presentation/hooks/usePaywall.md +61 -306
  60. package/src/presentation/hooks/usePaywallOperations.md +64 -458
  61. package/src/presentation/hooks/usePaywallVisibility.md +67 -316
  62. package/src/presentation/hooks/usePremium.md +84 -226
  63. package/src/presentation/hooks/usePremiumGate.md +60 -395
  64. package/src/presentation/hooks/usePremiumWithCredits.md +64 -401
  65. package/src/presentation/hooks/useSubscription.md +66 -422
  66. package/src/presentation/hooks/useSubscriptionDetails.md +65 -410
  67. package/src/presentation/hooks/useSubscriptionGate.md +80 -164
  68. package/src/presentation/hooks/useSubscriptionSettingsConfig.md +66 -346
  69. package/src/presentation/hooks/useSubscriptionStatus.md +66 -396
  70. package/src/presentation/hooks/useUserTier.md +63 -328
  71. package/src/presentation/hooks/useUserTierWithRepository.md +64 -424
  72. package/src/presentation/screens/README.md +48 -190
  73. package/src/presentation/types/README.md +0 -16
  74. package/src/presentation/utils/README.md +0 -21
  75. package/src/revenuecat/README.md +99 -518
  76. package/src/revenuecat/application/README.md +43 -0
  77. package/src/revenuecat/application/ports/README.md +41 -0
  78. package/src/revenuecat/domain/README.md +42 -141
  79. package/src/revenuecat/domain/constants/README.md +41 -0
  80. package/src/revenuecat/domain/entities/README.md +42 -0
  81. package/src/revenuecat/domain/errors/README.md +47 -191
  82. package/src/revenuecat/domain/types/README.md +41 -0
  83. package/src/revenuecat/domain/value-objects/README.md +41 -0
  84. package/src/revenuecat/infrastructure/README.md +41 -0
  85. package/src/revenuecat/infrastructure/config/README.md +32 -23
  86. package/src/revenuecat/infrastructure/handlers/README.md +41 -0
  87. package/src/revenuecat/infrastructure/managers/README.md +34 -42
  88. package/src/revenuecat/infrastructure/services/README.md +42 -0
  89. package/src/revenuecat/infrastructure/utils/README.md +41 -0
  90. package/src/revenuecat/presentation/README.md +42 -0
  91. package/src/revenuecat/presentation/hooks/README.md +29 -35
  92. 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`