@umituz/react-native-subscription 2.41.3 → 2.41.5

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@umituz/react-native-subscription",
3
- "version": "2.41.3",
3
+ "version": "2.41.5",
4
4
  "description": "Complete subscription management with RevenueCat, paywall UI, and credits system for React Native apps",
5
5
  "main": "./src/index.ts",
6
6
  "types": "./src/index.ts",
@@ -158,7 +158,7 @@ export const PaywallScreen: React.FC<PaywallScreenProps> = React.memo((props) =>
158
158
  return (
159
159
  <View key={`feat-${item.feature.text}`} style={[styles.featureRow, { marginHorizontal: 24, marginBottom: 16 }]}>
160
160
  <View style={[styles.featureIcon, { backgroundColor: tokens.colors.primary }]}>
161
- <AtomicIcon name={item.feature.icon as any} customSize={16} customColor={tokens.colors.onPrimary} />
161
+ <AtomicIcon name={item.feature.icon} customSize={16} customColor={tokens.colors.onPrimary} />
162
162
  </View>
163
163
  <AtomicText type="bodyMedium" style={[styles.featureText, { color: tokens.colors.textPrimary }]}>
164
164
  {item.feature.text}
@@ -1,5 +1,5 @@
1
1
  interface CacheEntry {
2
- promise: Promise<boolean>;
2
+ promise: Promise<boolean> | null;
3
3
  resolvedUserId: string | null;
4
4
  completed: boolean;
5
5
  }
@@ -18,7 +18,7 @@ export class InitializationCache {
18
18
 
19
19
  setPromise(promise: Promise<boolean>, cacheKey: string, realUserId: string | null): void {
20
20
  const entry: CacheEntry = {
21
- promise: null as any, // Placeholder to be assigned immediately
21
+ promise: null,
22
22
  resolvedUserId: realUserId,
23
23
  completed: false,
24
24
  };
@@ -9,68 +9,71 @@ interface SubscriptionFlowContextType {
9
9
  const SubscriptionFlowContext = createContext<SubscriptionFlowContextType | undefined>(undefined);
10
10
 
11
11
  export const SubscriptionFlowProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
12
- const store = useSubscriptionFlowStore();
12
+ // Selectors for stable references and only what we need
13
+ const isInitialized = useSubscriptionFlowStore((state) => state.isInitialized);
14
+ const isOnboardingComplete = useSubscriptionFlowStore((state) => state.isOnboardingComplete);
15
+ const showPostOnboardingPaywall = useSubscriptionFlowStore((state) => state.showPostOnboardingPaywall);
16
+ const status = useSubscriptionFlowStore((state) => state.status);
17
+ const setInitialized = useSubscriptionFlowStore((state) => state.setInitialized);
18
+ const setStatus = useSubscriptionFlowStore((state) => state.setStatus);
13
19
 
14
20
  useEffect(() => {
15
21
  // 1. Listen to background initialization state
16
22
  const unsubscribe = initializationState.subscribe(() => {
17
23
  const { initialized } = initializationState.getSnapshot();
18
24
  if (__DEV__) {
19
- console.log('[SubscriptionFlowProvider] 🔄 Initialization state updated:', { initialized });
25
+ console.log('[SubscriptionFlowProvider] 🔄 Initialization status updated:', { initialized });
20
26
  }
21
- if (initialized && !store.isInitialized) {
22
- store.setInitialized(true);
27
+ if (initialized && !isInitialized) {
28
+ setInitialized(true);
23
29
  }
24
30
  });
25
31
 
26
32
  // Check initial state
27
- const { initialized } = initializationState.getSnapshot();
28
- if (initialized && !store.isInitialized) {
33
+ const { initialized: currentlyInitialized } = initializationState.getSnapshot();
34
+ if (currentlyInitialized && !isInitialized) {
29
35
  if (__DEV__) console.log('[SubscriptionFlowProvider] ✅ Already initialized on mount');
30
- store.setInitialized(true);
36
+ setInitialized(true);
31
37
  }
32
38
 
33
39
  return () => unsubscribe();
34
- }, [store.isInitialized, store.setInitialized]);
40
+ }, [isInitialized, setInitialized]);
35
41
 
36
42
  useEffect(() => {
37
43
  // This effect manages the overall flow status transition
38
44
  if (__DEV__) {
39
45
  console.log('[SubscriptionFlowProvider] 🧠 Calculating Status Transition', {
40
- isInitialized: store.isInitialized,
41
- isOnboardingComplete: store.isOnboardingComplete,
42
- showPostOnboardingPaywall: store.showPostOnboardingPaywall,
43
- currentStatus: store.status
46
+ isInitialized,
47
+ isOnboardingComplete,
48
+ showPostOnboardingPaywall,
49
+ currentStatus: status
44
50
  });
45
51
  }
46
52
 
47
- if (!store.isInitialized) {
48
- store.setStatus(SubscriptionFlowStatus.INITIALIZING);
49
- return;
50
- }
53
+ let nextStatus = SubscriptionFlowStatus.READY;
51
54
 
52
- if (!store.isOnboardingComplete) {
53
- store.setStatus(SubscriptionFlowStatus.ONBOARDING);
54
- return;
55
+ if (!isInitialized) {
56
+ nextStatus = SubscriptionFlowStatus.INITIALIZING;
57
+ } else if (!isOnboardingComplete) {
58
+ nextStatus = SubscriptionFlowStatus.ONBOARDING;
59
+ } else if (showPostOnboardingPaywall) {
60
+ nextStatus = SubscriptionFlowStatus.POST_ONBOARDING_PAYWALL;
55
61
  }
56
62
 
57
- if (store.showPostOnboardingPaywall) {
58
- store.setStatus(SubscriptionFlowStatus.POST_ONBOARDING_PAYWALL);
59
- return;
63
+ if (nextStatus !== status) {
64
+ if (__DEV__) console.log('[SubscriptionFlowProvider] 🚀 Transitioning status to:', nextStatus);
65
+ setStatus(nextStatus);
60
66
  }
61
-
62
- if (__DEV__) console.log('[SubscriptionFlowProvider] 🏆 Flow is READY');
63
- store.setStatus(SubscriptionFlowStatus.READY);
64
67
  }, [
65
- store.isInitialized,
66
- store.isOnboardingComplete,
67
- store.showPostOnboardingPaywall,
68
- store.paywallShown,
69
- store
68
+ isInitialized,
69
+ isOnboardingComplete,
70
+ showPostOnboardingPaywall,
71
+ status,
72
+ setStatus
70
73
  ]);
71
74
 
72
75
  return (
73
- <SubscriptionFlowContext.Provider value={{ status: store.status }}>
76
+ <SubscriptionFlowContext.Provider value={{ status: status }}>
74
77
  {children}
75
78
  </SubscriptionFlowContext.Provider>
76
79
  );
@@ -93,8 +93,14 @@ export const useSubscriptionFlowStore = createStore<SubscriptionFlowState, Subsc
93
93
  setAuthModalOpen: (open: boolean) => set({ isAuthModalOpen: open }),
94
94
  setShowFeedback: (show: boolean) => set({ showFeedback: show }),
95
95
  markPaywallShown: async () => set({ paywallShown: true }),
96
- setInitialized: (initialized: boolean) => set({ isInitialized: initialized }),
97
- setStatus: (status: SubscriptionFlowStatus) => set({ status }),
96
+ setInitialized: (initialized: boolean) => set((state) => {
97
+ if (state.isInitialized === initialized) return state;
98
+ return { isInitialized: initialized };
99
+ }),
100
+ setStatus: (status: SubscriptionFlowStatus) => set((state) => {
101
+ if (state.status === status) return state;
102
+ return { status };
103
+ }),
98
104
  setSyncStatus: (syncStatus: SyncStatus, syncError: string | null = null) =>
99
105
  set({ syncStatus, syncError }),
100
106
  resetFlow: async () => {