@umituz/react-native-subscription 2.43.1 → 2.43.2

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.43.1",
3
+ "version": "2.43.2",
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",
@@ -2,7 +2,6 @@
2
2
  * Paywall Screen Component
3
3
  *
4
4
  * Full-screen paywall with optimized FlatList for performance and modern design.
5
- * This is a "dumb" component that receives all data and actions via props.
6
5
  */
7
6
 
8
7
  import React, { useCallback, useEffect, useMemo } from "react";
@@ -22,9 +22,6 @@ export interface PaywallOrchestratorOptions {
22
22
  * High-level orchestrator for Paywall navigation.
23
23
  * Handles automatic triggers (post-onboarding) and manual triggers (showPaywall state).
24
24
  * Centralizes handlers for success, close, and feedback triggers.
25
- *
26
- * This orchestrator fetches all subscription data and passes it to PaywallScreen as props.
27
- * PaywallScreen is now a "dumb" component that doesn't call usePremium internally.
28
25
  */
29
26
  export function usePaywallOrchestrator({
30
27
  navigation,
@@ -86,7 +83,6 @@ export function usePaywallOrchestrator({
86
83
  packagesCount: packages.length
87
84
  });
88
85
 
89
- // Pass all data and actions as props - PaywallScreen is now a dumb component
90
86
  navigation.navigate("PaywallScreen", {
91
87
  // UI Props
92
88
  translations,
@@ -1,9 +1,9 @@
1
1
  import { PURCHASE_SOURCE, PURCHASE_TYPE } from "../core/SubscriptionConstants";
2
- import type { PremiumStatusChangedEvent, PurchaseCompletedEvent, RenewalDetectedEvent } from "../core/SubscriptionEvents";
2
+ import { subscriptionEventBus, SUBSCRIPTION_EVENTS } from "../../../shared/infrastructure/SubscriptionEventBus";
3
+ import type { PurchaseCompletedEvent, RenewalDetectedEvent, PremiumStatusChangedEvent } from "../core/SubscriptionEvents";
3
4
  import { getCreditsRepository } from "../../credits/infrastructure/CreditsRepositoryManager";
4
5
  import { extractRevenueCatData } from "./SubscriptionSyncUtils";
5
6
  import { generatePurchaseId, generateRenewalId } from "./syncIdGenerators";
6
- import { subscriptionEventBus, SUBSCRIPTION_EVENTS } from "../../../shared/infrastructure/SubscriptionEventBus";
7
7
 
8
8
  /**
9
9
  * Central processor for all subscription sync operations.
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Application flow events
3
+ * Events emitted during high-level application flow transitions
4
+ */
5
+
6
+ export const FLOW_EVENTS = {
7
+ ONBOARDING_COMPLETED: "flow_onboarding_completed",
8
+ PAYWALL_SHOWN: "flow_paywall_shown",
9
+ PAYWALL_CLOSED: "flow_paywall_closed",
10
+ } as const;
11
+
12
+ export type FlowEventType = typeof FLOW_EVENTS[keyof typeof FLOW_EVENTS];
13
+
14
+ export interface OnboardingCompletedEvent {
15
+ timestamp: number;
16
+ }
17
+
18
+ export interface PaywallShownEvent {
19
+ timestamp: number;
20
+ }
21
+
22
+ export interface PaywallClosedEvent {
23
+ timestamp: number;
24
+ }
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Subscription-related events
3
+ * Events emitted during subscription lifecycle operations
4
+ */
5
+
6
+ export const SUBSCRIPTION_EVENTS = {
7
+ CREDITS_UPDATED: "credits_updated",
8
+ PURCHASE_COMPLETED: "purchase_completed",
9
+ RENEWAL_DETECTED: "renewal_detected",
10
+ PREMIUM_STATUS_CHANGED: "premium_status_changed",
11
+ SYNC_STATUS_CHANGED: "sync_status_changed",
12
+ } as const;
13
+
14
+ export type SubscriptionEventType = typeof SUBSCRIPTION_EVENTS[keyof typeof SUBSCRIPTION_EVENTS];
15
+
16
+ export interface SyncStatusChangedEvent {
17
+ status: 'syncing' | 'success' | 'error';
18
+ phase: 'purchase' | 'renewal';
19
+ userId?: string;
20
+ productId?: string;
21
+ error?: string;
22
+ }
@@ -7,11 +7,7 @@ import { UsePremiumResult } from './usePremium.types';
7
7
  /**
8
8
  * Facade hook that combines status, packages, and actions.
9
9
  *
10
- * This provides backward compatibility with existing code while allowing
11
- * components to use more focused hooks (usePremiumStatus, usePremiumPackages, usePremiumActions)
12
- * for better performance and testability.
13
- *
14
- * For new components, consider using the focused hooks:
10
+ * Consider using the focused hooks for better performance:
15
11
  * - usePremiumStatus() - when you only need premium status
16
12
  * - usePremiumPackages() - when you only need package data
17
13
  * - usePremiumActions() - when you only need actions
@@ -28,7 +24,6 @@ export const usePremium = (): UsePremiumResult => {
28
24
  ...status,
29
25
  ...packages,
30
26
  ...actions,
31
- // Merge loading states for backward compatibility
32
27
  isLoading: status.isSyncing || packages.isLoading || actions.isLoading,
33
28
  }), [
34
29
  status,
package/src/index.ts CHANGED
@@ -9,6 +9,13 @@ export {
9
9
  PURCHASE_TYPE,
10
10
  ANONYMOUS_CACHE_KEY,
11
11
  } from "./domains/subscription/core/SubscriptionConstants";
12
+
13
+ // Domain Events
14
+ export { SUBSCRIPTION_EVENTS } from "./domains/subscription/core/events/SubscriptionEvents";
15
+ export type { SubscriptionEventType, SyncStatusChangedEvent } from "./domains/subscription/core/events/SubscriptionEvents";
16
+ export type { PurchaseCompletedEvent, RenewalDetectedEvent, PremiumStatusChangedEvent } from "./domains/subscription/core/SubscriptionEvents";
17
+ export { FLOW_EVENTS } from "./domains/subscription/core/events/FlowEvents";
18
+ export type { FlowEventType, OnboardingCompletedEvent, PaywallShownEvent, PaywallClosedEvent } from "./domains/subscription/core/events/FlowEvents";
12
19
  export type {
13
20
  UserTierType,
14
21
  SubscriptionStatusType,
@@ -176,10 +183,6 @@ export type { ManagedSubscriptionFlowProps } from "./domains/subscription/presen
176
183
  export { SubscriptionFlowStatus } from "./domains/subscription/presentation/useSubscriptionFlow";
177
184
  export { SubscriptionFlowProvider, useSubscriptionFlowStatus } from "./domains/subscription/presentation/providers/SubscriptionFlowProvider";
178
185
 
179
- // Purchase Loading Overlay
180
- export { PurchaseLoadingOverlay } from "./domains/subscription/presentation/components/overlay/PurchaseLoadingOverlay";
181
- export type { PurchaseLoadingOverlayProps } from "./domains/subscription/presentation/components/overlay/PurchaseLoadingOverlay";
182
-
183
186
  // Init Module Factory
184
187
  export {
185
188
  createSubscriptionInitModule,
@@ -17,7 +17,7 @@ class SubscriptionEventBus {
17
17
  if (!this.listeners.has(event)) {
18
18
  this.listeners.set(event, new Set());
19
19
  }
20
-
20
+
21
21
  const eventSet = this.listeners.get(event)!;
22
22
  eventSet.add(callback as EventCallback);
23
23
 
@@ -36,8 +36,6 @@ class SubscriptionEventBus {
36
36
  const listeners = this.listeners.get(event);
37
37
  if (!listeners || listeners.size === 0) return;
38
38
 
39
- // Use microtask for async execution to not block main thread
40
- // but keep it fast.
41
39
  listeners.forEach(callback => {
42
40
  queueMicrotask(() => {
43
41
  try {
@@ -71,19 +69,9 @@ class SubscriptionEventBus {
71
69
 
72
70
  export const subscriptionEventBus = SubscriptionEventBus.getInstance();
73
71
 
74
- export const SUBSCRIPTION_EVENTS = {
75
- CREDITS_UPDATED: "credits_updated",
76
- PURCHASE_COMPLETED: "purchase_completed",
77
- RENEWAL_DETECTED: "renewal_detected",
78
- PREMIUM_STATUS_CHANGED: "premium_status_changed",
79
- SYNC_STATUS_CHANGED: "sync_status_changed",
80
- } as const;
81
-
82
- export const FLOW_EVENTS = {
83
- ONBOARDING_COMPLETED: "flow_onboarding_completed",
84
- PAYWALL_SHOWN: "flow_paywall_shown",
85
- PAYWALL_CLOSED: "flow_paywall_closed",
86
- } as const;
72
+ // Re-export event constants for external use
73
+ export { SUBSCRIPTION_EVENTS } from "../../domains/subscription/core/events/SubscriptionEvents";
74
+ export { FLOW_EVENTS } from "../../domains/subscription/core/events/FlowEvents";
75
+ export type { SubscriptionEventType } from "../../domains/subscription/core/events/SubscriptionEvents";
76
+ export type { FlowEventType } from "../../domains/subscription/core/events/FlowEvents";
87
77
 
88
- export type SubscriptionEventType = typeof SUBSCRIPTION_EVENTS[keyof typeof SUBSCRIPTION_EVENTS];
89
- export type FlowEventType = typeof FLOW_EVENTS[keyof typeof FLOW_EVENTS];
@@ -36,6 +36,3 @@ export const LONG_CACHE_CONFIG = {
36
36
  refetchOnWindowFocus: false,
37
37
  refetchOnReconnect: true,
38
38
  };
39
-
40
- /** @deprecated Use SHORT_CACHE_CONFIG instead */
41
- export const NO_CACHE_QUERY_CONFIG = SHORT_CACHE_CONFIG;
@@ -1,60 +0,0 @@
1
- /**
2
- * Purchase Loading Overlay
3
- * Full-screen overlay shown during purchase operations
4
- * Locks the UI and shows a spinner with optional message
5
- *
6
- * This is now a props-based component. Pass isLoading from parent component.
7
- */
8
-
9
- import React from "react";
10
- import { View, Modal, StyleSheet } from "react-native";
11
- import { AtomicSpinner, AtomicText } from "@umituz/react-native-design-system/atoms";
12
- import { useAppDesignTokens } from "@umituz/react-native-design-system/theme";
13
- import type { PurchaseLoadingOverlayProps } from "./PurchaseLoadingOverlay.types";
14
-
15
- export type { PurchaseLoadingOverlayProps };
16
-
17
- export const PurchaseLoadingOverlay: React.FC<PurchaseLoadingOverlayProps> = React.memo(
18
- ({ loadingText, isLoading }) => {
19
- const tokens = useAppDesignTokens();
20
-
21
- return (
22
- <Modal visible={isLoading} transparent animationType="none" statusBarTranslucent>
23
- <View style={[styles.container, { backgroundColor: "rgba(0, 0, 0, 0.7)" }]}>
24
- <View style={[styles.content, { backgroundColor: tokens.colors.surface }]}>
25
- <AtomicSpinner size="lg" color="primary" />
26
- {loadingText && (
27
- <AtomicText
28
- type="bodyLarge"
29
- style={[styles.text, { color: tokens.colors.textPrimary }]}
30
- >
31
- {loadingText}
32
- </AtomicText>
33
- )}
34
- </View>
35
- </View>
36
- </Modal>
37
- );
38
- }
39
- );
40
-
41
- PurchaseLoadingOverlay.displayName = "PurchaseLoadingOverlay";
42
-
43
- const styles = StyleSheet.create({
44
- container: {
45
- flex: 1,
46
- justifyContent: "center",
47
- alignItems: "center",
48
- },
49
- content: {
50
- paddingHorizontal: 32,
51
- paddingVertical: 24,
52
- borderRadius: 16,
53
- alignItems: "center",
54
- minWidth: 200,
55
- },
56
- text: {
57
- marginTop: 16,
58
- textAlign: "center",
59
- },
60
- });
@@ -1,6 +0,0 @@
1
- export interface PurchaseLoadingOverlayProps {
2
- /** Whether the overlay is visible */
3
- isLoading: boolean;
4
- /** Loading message to display */
5
- loadingText?: string;
6
- }