@umituz/react-native-subscription 2.35.16 → 2.35.17
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/config/utils/planSelectors.ts +1 -1
- package/src/domains/credits/presentation/useCredits.ts +6 -20
- package/src/domains/paywall/hooks/usePaywallActions.ts +2 -82
- package/src/domains/revenuecat/core/customerInfoHelpers.ts +21 -0
- package/src/domains/subscription/application/SubscriptionAuthListener.ts +0 -19
- package/src/domains/subscription/application/initializer/BackgroundInitializer.ts +2 -8
- package/src/domains/subscription/application/statusChangeHandlers.ts +0 -30
- package/src/domains/subscription/constants/thresholds.ts +10 -0
- package/src/domains/subscription/infrastructure/handlers/PurchaseStatusResolver.ts +3 -3
- package/src/domains/subscription/infrastructure/handlers/package-operations/PackageFetcher.ts +0 -19
- package/src/domains/subscription/infrastructure/hooks/customer-info/useCustomerInfo.ts +1 -1
- package/src/domains/subscription/infrastructure/hooks/useInitializeSubscription.ts +2 -4
- package/src/domains/subscription/infrastructure/hooks/usePurchasePackage.ts +0 -44
- package/src/domains/subscription/infrastructure/services/CustomerInfoListenerManager.ts +1 -31
- package/src/domains/subscription/infrastructure/services/OfferingsFetcher.ts +0 -21
- package/src/domains/subscription/infrastructure/services/listeners/CustomerInfoHandler.ts +6 -36
- package/src/domains/subscription/infrastructure/services/purchase/PurchaseExecutor.ts +0 -6
- package/src/domains/subscription/infrastructure/utils/PremiumStatusSyncer.ts +3 -44
- package/src/domains/subscription/presentation/featureGateActions.ts +0 -37
- package/src/domains/subscription/presentation/screens/components/SubscriptionHeader.tsx +1 -1
- package/src/domains/subscription/presentation/screens/components/SubscriptionHeaderContent.tsx +1 -1
- package/src/domains/subscription/presentation/useAuthAwarePurchase.ts +0 -43
- package/src/domains/subscription/presentation/useFeatureGate.ts +0 -39
- package/src/domains/subscription/presentation/useSubscriptionStatus.ts +6 -20
- package/src/domains/subscription/utils/authGuards.ts +26 -2
- package/src/domains/subscription/utils/expirationHelpers.ts +2 -2
- package/src/domains/wallet/presentation/hooks/useProductMetadata.ts +3 -6
- package/src/domains/wallet/presentation/hooks/useTransactionHistory.ts +3 -6
- package/src/shared/infrastructure/react-query/hooks/usePreviousUserCleanup.ts +39 -0
- package/src/shared/infrastructure/react-query/queryConfig.ts +22 -0
- package/src/shared/infrastructure/react-query/queryInvalidation.ts +46 -0
- package/src/shared/presentation/hooks/useServiceCall.ts +2 -1
- package/src/shared/utils/errorUtils.ts +32 -0
- package/src/utils/appUtils.ts +6 -0
- package/src/domains/subscription/presentation/components/details/PremiumDetailsCard.constants.ts +0 -1
- package/src/domains/subscription/presentation/screens/components/SubscriptionHeader.constants.ts +0 -1
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* User Cache Cleanup Hook
|
|
3
|
+
* Automatically cleans up previous user's query cache when userId changes
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { useEffect, useRef } from "react";
|
|
7
|
+
import type { QueryClient } from "@umituz/react-native-design-system";
|
|
8
|
+
import { isAuthenticated } from "../../../../domains/subscription/utils/authGuards";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Cleans up previous user's cache when userId changes (logout or user switch)
|
|
12
|
+
* Prevents data leakage between users
|
|
13
|
+
*
|
|
14
|
+
* @param userId - Current user ID
|
|
15
|
+
* @param queryClient - TanStack Query client
|
|
16
|
+
* @param queryKey - Query key factory function that takes userId
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* usePreviousUserCleanup(userId, queryClient, (id) => creditsQueryKeys.user(id));
|
|
20
|
+
*/
|
|
21
|
+
export function usePreviousUserCleanup(
|
|
22
|
+
userId: string | null | undefined,
|
|
23
|
+
queryClient: QueryClient,
|
|
24
|
+
queryKey: (userId: string) => readonly unknown[]
|
|
25
|
+
): void {
|
|
26
|
+
const prevUserIdRef = useRef(userId);
|
|
27
|
+
|
|
28
|
+
useEffect(() => {
|
|
29
|
+
const prevUserId = prevUserIdRef.current;
|
|
30
|
+
prevUserIdRef.current = userId;
|
|
31
|
+
|
|
32
|
+
// Clear previous user's cache when userId changes (logout or user switch)
|
|
33
|
+
if (prevUserId !== userId && isAuthenticated(prevUserId)) {
|
|
34
|
+
queryClient.removeQueries({
|
|
35
|
+
queryKey: queryKey(prevUserId),
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
}, [userId, queryClient, queryKey]);
|
|
39
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared TanStack Query Configuration
|
|
3
|
+
* Common query configurations to ensure consistency across hooks
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Configuration for queries that should never cache
|
|
8
|
+
* Used for real-time sensitive data (subscriptions, credits, transactions)
|
|
9
|
+
*
|
|
10
|
+
* - gcTime: 0 - Don't keep unused data in memory
|
|
11
|
+
* - staleTime: 0 - Always consider data stale
|
|
12
|
+
* - refetchOnMount: "always" - Always refetch when component mounts
|
|
13
|
+
* - refetchOnWindowFocus: "always" - Always refetch when window regains focus
|
|
14
|
+
* - refetchOnReconnect: "always" - Always refetch when reconnecting
|
|
15
|
+
*/
|
|
16
|
+
export const NO_CACHE_QUERY_CONFIG = {
|
|
17
|
+
gcTime: 0,
|
|
18
|
+
staleTime: 0,
|
|
19
|
+
refetchOnMount: "always" as const,
|
|
20
|
+
refetchOnWindowFocus: "always" as const,
|
|
21
|
+
refetchOnReconnect: "always" as const,
|
|
22
|
+
};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Query Invalidation Utilities
|
|
3
|
+
* Centralized functions for invalidating multiple related queries
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { QueryClient } from "@umituz/react-native-design-system";
|
|
7
|
+
import { creditsQueryKeys } from "../../../domains/credits/presentation/creditsQueryKeys";
|
|
8
|
+
import { subscriptionStatusQueryKeys } from "../../../domains/subscription/presentation/useSubscriptionStatus";
|
|
9
|
+
|
|
10
|
+
// Subscription packages query key
|
|
11
|
+
export const SUBSCRIPTION_QUERY_KEYS = {
|
|
12
|
+
packages: ["subscription", "packages"] as const,
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Invalidates all subscription-related queries
|
|
17
|
+
* Use after purchases, restores, or subscription changes
|
|
18
|
+
*
|
|
19
|
+
* @param queryClient - TanStack Query client
|
|
20
|
+
* @param userId - Optional user ID to invalidate user-specific queries
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* // After successful purchase
|
|
24
|
+
* await invalidateSubscriptionQueries(queryClient, userId);
|
|
25
|
+
*/
|
|
26
|
+
export async function invalidateSubscriptionQueries(
|
|
27
|
+
queryClient: QueryClient,
|
|
28
|
+
userId?: string | null
|
|
29
|
+
): Promise<void> {
|
|
30
|
+
// Invalidate packages (affects all users)
|
|
31
|
+
await queryClient.invalidateQueries({
|
|
32
|
+
queryKey: SUBSCRIPTION_QUERY_KEYS.packages,
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
// Invalidate user-specific queries if userId provided
|
|
36
|
+
if (userId) {
|
|
37
|
+
await Promise.all([
|
|
38
|
+
queryClient.invalidateQueries({
|
|
39
|
+
queryKey: subscriptionStatusQueryKeys.user(userId),
|
|
40
|
+
}),
|
|
41
|
+
queryClient.invalidateQueries({
|
|
42
|
+
queryKey: creditsQueryKeys.user(userId),
|
|
43
|
+
}),
|
|
44
|
+
]);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { useState, useCallback, useRef, useEffect } from "react";
|
|
7
|
+
import { normalizeError } from "../../utils/errorUtils";
|
|
7
8
|
|
|
8
9
|
export interface ServiceCallState<T> {
|
|
9
10
|
data: T | null;
|
|
@@ -54,7 +55,7 @@ export function useServiceCall<T>(
|
|
|
54
55
|
setState({ data, isLoading: false, error: null });
|
|
55
56
|
onSuccessRef.current?.(data);
|
|
56
57
|
} catch (error) {
|
|
57
|
-
const errorObj = error
|
|
58
|
+
const errorObj = normalizeError(error, "Service call failed");
|
|
58
59
|
setState({ data: null, isLoading: false, error: errorObj });
|
|
59
60
|
onErrorRef.current?.(errorObj);
|
|
60
61
|
} finally {
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error Utilities
|
|
3
|
+
* Common error handling and normalization functions
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Normalizes unknown error types to Error objects
|
|
8
|
+
* Useful for catch blocks where error type is unknown
|
|
9
|
+
*
|
|
10
|
+
* @param error - The error to normalize (unknown type)
|
|
11
|
+
* @param fallbackMessage - Message to use if error is not an Error object
|
|
12
|
+
* @returns Always returns an Error object
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* try {
|
|
16
|
+
* await someOperation();
|
|
17
|
+
* } catch (error) {
|
|
18
|
+
* const err = normalizeError(error, "Operation failed");
|
|
19
|
+
* console.error(err.message);
|
|
20
|
+
* }
|
|
21
|
+
*/
|
|
22
|
+
export function normalizeError(
|
|
23
|
+
error: unknown,
|
|
24
|
+
fallbackMessage = "Unknown error"
|
|
25
|
+
): Error {
|
|
26
|
+
if (error instanceof Error) {
|
|
27
|
+
return error;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const message = typeof error === "string" ? error : String(error);
|
|
31
|
+
return new Error(message || fallbackMessage);
|
|
32
|
+
}
|
package/src/utils/appUtils.ts
CHANGED
|
@@ -4,6 +4,12 @@
|
|
|
4
4
|
import { Platform } from "react-native";
|
|
5
5
|
import Constants from "expo-constants";
|
|
6
6
|
|
|
7
|
+
/**
|
|
8
|
+
* Development mode flag
|
|
9
|
+
* Safe check for __DEV__ that works in all environments
|
|
10
|
+
*/
|
|
11
|
+
export const IS_DEV_MODE = typeof __DEV__ !== "undefined" && __DEV__;
|
|
12
|
+
|
|
7
13
|
/**
|
|
8
14
|
* Gets the current app version from Expo constants
|
|
9
15
|
*/
|
package/src/domains/subscription/presentation/components/details/PremiumDetailsCard.constants.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export const DAYS_REMAINING_WARNING_THRESHOLD = 7;
|
package/src/domains/subscription/presentation/screens/components/SubscriptionHeader.constants.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export const EXPIRING_SOON_THRESHOLD_DAYS = 7;
|