@billdog.io/react-native 1.0.0-beta.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/BillDogReactNative.podspec +30 -0
- package/LICENSE +21 -0
- package/README.md +330 -0
- package/android/build.gradle +99 -0
- package/android/src/main/AndroidManifest.xml +1 -0
- package/android/src/main/kotlin/io/billdog/reactnative/BillDogABTestModule.kt +317 -0
- package/android/src/main/kotlin/io/billdog/reactnative/BillDogAnalyticsModule.kt +389 -0
- package/android/src/main/kotlin/io/billdog/reactnative/BillDogModule.kt +817 -0
- package/android/src/main/kotlin/io/billdog/reactnative/BillDogPaywallViewManager.kt +383 -0
- package/android/src/main/kotlin/io/billdog/reactnative/BillDogSurveyModule.kt +427 -0
- package/android/src/main/kotlin/io/billdog/reactnative/BillDogVirtualCurrencyModule.kt +407 -0
- package/android/src/main/kotlin/io/billdog/virtualcurrency/BillDogVirtualCurrencyPackage.kt +44 -0
- package/dist/AdvancedPaywallCache.d.ts +70 -0
- package/dist/AdvancedPaywallCache.js +344 -0
- package/dist/BillDog.d.ts +255 -0
- package/dist/BillDog.js +918 -0
- package/dist/BillDogConfiguration.d.ts +145 -0
- package/dist/BillDogConfiguration.js +229 -0
- package/dist/ComponentRenderer.d.ts +17 -0
- package/dist/ComponentRenderer.js +886 -0
- package/dist/LayoutEngine.d.ts +101 -0
- package/dist/LayoutEngine.js +394 -0
- package/dist/LocalizationResolver.d.ts +99 -0
- package/dist/LocalizationResolver.js +266 -0
- package/dist/NativePaywallView.d.ts +36 -0
- package/dist/NativePaywallView.js +59 -0
- package/dist/PaywallCache.d.ts +74 -0
- package/dist/PaywallCache.js +293 -0
- package/dist/PaywallStateManager.d.ts +62 -0
- package/dist/PaywallStateManager.js +147 -0
- package/dist/PaywallView.d.ts +42 -0
- package/dist/PaywallView.js +275 -0
- package/dist/ProductVariableProvider.d.ts +60 -0
- package/dist/ProductVariableProvider.js +239 -0
- package/dist/VariableResolver.d.ts +120 -0
- package/dist/VariableResolver.js +379 -0
- package/dist/WebViewPaywall.d.ts +75 -0
- package/dist/WebViewPaywall.js +360 -0
- package/dist/animations/presets.d.ts +49 -0
- package/dist/animations/presets.js +367 -0
- package/dist/components/AccoladeCpsComponent.d.ts +13 -0
- package/dist/components/AccoladeCpsComponent.js +248 -0
- package/dist/components/AccordionComponent.d.ts +10 -0
- package/dist/components/AccordionComponent.js +187 -0
- package/dist/components/AnimatedWrapper.d.ts +35 -0
- package/dist/components/AnimatedWrapper.js +277 -0
- package/dist/components/CarouselComponent.d.ts +23 -0
- package/dist/components/CarouselComponent.js +484 -0
- package/dist/components/ChartCurveComponent.d.ts +13 -0
- package/dist/components/ChartCurveComponent.js +333 -0
- package/dist/components/CheckboxComponent.d.ts +9 -0
- package/dist/components/CheckboxComponent.js +172 -0
- package/dist/components/ConfettiComponent.d.ts +9 -0
- package/dist/components/ConfettiComponent.js +172 -0
- package/dist/components/CountdownComponent.d.ts +16 -0
- package/dist/components/CountdownComponent.js +414 -0
- package/dist/components/DelayedXComponent.d.ts +12 -0
- package/dist/components/DelayedXComponent.js +240 -0
- package/dist/components/DrawerModalComponent.d.ts +20 -0
- package/dist/components/DrawerModalComponent.js +286 -0
- package/dist/components/GradientView.d.ts +38 -0
- package/dist/components/GradientView.js +126 -0
- package/dist/components/HapticFeedbackComponent.d.ts +16 -0
- package/dist/components/HapticFeedbackComponent.js +64 -0
- package/dist/components/HorizontalProductsComponent.d.ts +17 -0
- package/dist/components/HorizontalProductsComponent.js +284 -0
- package/dist/components/MultiChoiceGridComponent.d.ts +13 -0
- package/dist/components/MultiChoiceGridComponent.js +234 -0
- package/dist/components/NPSScaleComponent.d.ts +16 -0
- package/dist/components/NPSScaleComponent.js +260 -0
- package/dist/components/NavigationComponent.d.ts +26 -0
- package/dist/components/NavigationComponent.js +302 -0
- package/dist/components/OAuthButtonComponent.d.ts +20 -0
- package/dist/components/OAuthButtonComponent.js +237 -0
- package/dist/components/ProgressLoaderComponent.d.ts +13 -0
- package/dist/components/ProgressLoaderComponent.js +308 -0
- package/dist/components/ProgressStepperComponent.d.ts +18 -0
- package/dist/components/ProgressStepperComponent.js +228 -0
- package/dist/components/SegmentedPickerComponent.d.ts +10 -0
- package/dist/components/SegmentedPickerComponent.js +221 -0
- package/dist/components/ShareButtonsComponent.d.ts +21 -0
- package/dist/components/ShareButtonsComponent.js +265 -0
- package/dist/components/ShareCodeComponent.d.ts +16 -0
- package/dist/components/ShareCodeComponent.js +274 -0
- package/dist/components/SingleChoiceGridComponent.d.ts +13 -0
- package/dist/components/SingleChoiceGridComponent.js +210 -0
- package/dist/components/SliderComponent.d.ts +9 -0
- package/dist/components/SliderComponent.js +263 -0
- package/dist/components/StarRatingInputComponent.d.ts +20 -0
- package/dist/components/StarRatingInputComponent.js +198 -0
- package/dist/components/StickerCompositeComponent.d.ts +13 -0
- package/dist/components/StickerCompositeComponent.js +136 -0
- package/dist/components/TabsComponent.d.ts +19 -0
- package/dist/components/TabsComponent.js +431 -0
- package/dist/components/TextInputComponent.d.ts +18 -0
- package/dist/components/TextInputComponent.js +227 -0
- package/dist/components/TimelineComponent.d.ts +19 -0
- package/dist/components/TimelineComponent.js +104 -0
- package/dist/components/ToggleComponent.d.ts +14 -0
- package/dist/components/ToggleComponent.js +132 -0
- package/dist/components/VerticalProductsComponent.d.ts +17 -0
- package/dist/components/VerticalProductsComponent.js +311 -0
- package/dist/dynamicValues.d.ts +36 -0
- package/dist/dynamicValues.js +142 -0
- package/dist/filters/dateFilters.d.ts +50 -0
- package/dist/filters/dateFilters.js +390 -0
- package/dist/filters/index.d.ts +18 -0
- package/dist/filters/index.js +253 -0
- package/dist/hooks/useOfferings.d.ts +76 -0
- package/dist/hooks/useOfferings.js +99 -0
- package/dist/hooks/usePaywall.d.ts +27 -0
- package/dist/hooks/usePaywall.js +114 -0
- package/dist/hooks/usePlacement.d.ts +34 -0
- package/dist/hooks/usePlacement.js +89 -0
- package/dist/hooks/useSubscription.d.ts +40 -0
- package/dist/hooks/useSubscription.js +97 -0
- package/dist/index.d.ts +98 -0
- package/dist/index.js +198 -0
- package/dist/models/BillDogError.d.ts +40 -0
- package/dist/models/BillDogError.js +11 -0
- package/dist/models/CacheFetchPolicy.d.ts +8 -0
- package/dist/models/CacheFetchPolicy.js +4 -0
- package/dist/models/CustomProduct.d.ts +32 -0
- package/dist/models/CustomProduct.js +15 -0
- package/dist/models/CustomerInfo.d.ts +17 -0
- package/dist/models/CustomerInfo.js +11 -0
- package/dist/models/Delegate.d.ts +20 -0
- package/dist/models/Delegate.js +11 -0
- package/dist/models/EntitlementInfo.d.ts +19 -0
- package/dist/models/EntitlementInfo.js +2 -0
- package/dist/models/Placement.d.ts +54 -0
- package/dist/models/Placement.js +15 -0
- package/dist/models/PurchaseParams.d.ts +39 -0
- package/dist/models/PurchaseParams.js +60 -0
- package/dist/models/PurchaseResult.d.ts +30 -0
- package/dist/models/PurchaseResult.js +15 -0
- package/dist/models/RestoreResult.d.ts +30 -0
- package/dist/models/RestoreResult.js +22 -0
- package/dist/models/RestoredItem.d.ts +26 -0
- package/dist/models/RestoredItem.js +13 -0
- package/dist/modules/ABTest.d.ts +65 -0
- package/dist/modules/ABTest.js +113 -0
- package/dist/modules/Analytics.d.ts +91 -0
- package/dist/modules/Analytics.js +182 -0
- package/dist/modules/Survey.d.ts +65 -0
- package/dist/modules/Survey.js +82 -0
- package/dist/modules/VirtualCurrency.d.ts +63 -0
- package/dist/modules/VirtualCurrency.js +147 -0
- package/dist/murmur.d.ts +23 -0
- package/dist/murmur.js +104 -0
- package/dist/notifications/LiveActivitiesManager.d.ts +47 -0
- package/dist/notifications/LiveActivitiesManager.js +106 -0
- package/dist/notifications/NotificationScheduler.d.ts +55 -0
- package/dist/notifications/NotificationScheduler.js +199 -0
- package/dist/notifications/PurchaseNotificationHandler.d.ts +24 -0
- package/dist/notifications/PurchaseNotificationHandler.js +55 -0
- package/dist/notifications/useDeviceToken.d.ts +36 -0
- package/dist/notifications/useDeviceToken.js +97 -0
- package/dist/notifications/useLiveActivity.d.ts +39 -0
- package/dist/notifications/useLiveActivity.js +104 -0
- package/dist/review/ReviewAnalytics.d.ts +34 -0
- package/dist/review/ReviewAnalytics.js +73 -0
- package/dist/review/ReviewManager.d.ts +83 -0
- package/dist/review/ReviewManager.js +339 -0
- package/dist/review/ReviewTimingManager.d.ts +82 -0
- package/dist/review/ReviewTimingManager.js +224 -0
- package/dist/survey-core/types.d.ts +215 -0
- package/dist/survey-core/types.js +8 -0
- package/dist/types.d.ts +438 -0
- package/dist/types.js +158 -0
- package/dist/utils/ApiClient.d.ts +65 -0
- package/dist/utils/ApiClient.js +132 -0
- package/dist/utils/CSSConverter.d.ts +49 -0
- package/dist/utils/CSSConverter.js +470 -0
- package/dist/utils/animations.d.ts +41 -0
- package/dist/utils/animations.js +194 -0
- package/dist/utils/calendarIntegration.d.ts +36 -0
- package/dist/utils/calendarIntegration.js +89 -0
- package/dist/utils/configurationResolver.d.ts +23 -0
- package/dist/utils/configurationResolver.js +78 -0
- package/dist/utils/deviceDetection.d.ts +38 -0
- package/dist/utils/deviceDetection.js +59 -0
- package/dist/utils/hapticFeedback.d.ts +17 -0
- package/dist/utils/hapticFeedback.js +53 -0
- package/dist/utils/iconMapper.d.ts +26 -0
- package/dist/utils/iconMapper.js +113 -0
- package/dist/utils/notificationPermissions.d.ts +13 -0
- package/dist/utils/notificationPermissions.js +51 -0
- package/dist/utils/priceFormatting.d.ts +19 -0
- package/dist/utils/priceFormatting.js +99 -0
- package/dist/utils/shareSheet.d.ts +17 -0
- package/dist/utils/shareSheet.js +42 -0
- package/dist/utils/subscriptionUpgrade.d.ts +84 -0
- package/dist/utils/subscriptionUpgrade.js +100 -0
- package/dist/valueUtils.d.ts +48 -0
- package/dist/valueUtils.js +129 -0
- package/dist/xFlowTags.d.ts +18 -0
- package/dist/xFlowTags.js +385 -0
- package/ios/BillDogABTest.m +50 -0
- package/ios/BillDogABTest.swift +188 -0
- package/ios/BillDogAnalytics.m +105 -0
- package/ios/BillDogAnalytics.swift +324 -0
- package/ios/BillDogBridge.m +222 -0
- package/ios/BillDogBridge.swift +715 -0
- package/ios/BillDogLiveActivities.m +41 -0
- package/ios/BillDogLiveActivities.swift +104 -0
- package/ios/BillDogPaywallViewManager.m +39 -0
- package/ios/BillDogPaywallViewManager.swift +361 -0
- package/ios/BillDogSurvey.m +34 -0
- package/ios/BillDogSurvey.swift +257 -0
- package/ios/BillDogVirtualCurrencyBridge.m +63 -0
- package/ios/BillDogVirtualCurrencyBridge.swift +511 -0
- package/junit.xml +25 -0
- package/package.json +61 -0
- package/react-native.config.js +13 -0
- package/src/AdvancedPaywallCache.ts +433 -0
- package/src/BillDog.ts +983 -0
- package/src/BillDogConfiguration.ts +318 -0
- package/src/ComponentRenderer.tsx +1325 -0
- package/src/LayoutEngine.ts +459 -0
- package/src/LocalizationResolver.ts +311 -0
- package/src/NativePaywallView.tsx +132 -0
- package/src/PaywallCache.ts +358 -0
- package/src/PaywallStateManager.ts +154 -0
- package/src/PaywallView.tsx +328 -0
- package/src/ProductVariableProvider.ts +282 -0
- package/src/VariableResolver.ts +516 -0
- package/src/WebViewPaywall.tsx +454 -0
- package/src/animations/presets.ts +421 -0
- package/src/components/AccoladeCpsComponent.tsx +259 -0
- package/src/components/AccordionComponent.tsx +213 -0
- package/src/components/AnimatedWrapper.tsx +316 -0
- package/src/components/CarouselComponent.tsx +615 -0
- package/src/components/ChartCurveComponent.tsx +452 -0
- package/src/components/CheckboxComponent.tsx +185 -0
- package/src/components/ConfettiComponent.tsx +178 -0
- package/src/components/CountdownComponent.tsx +454 -0
- package/src/components/DelayedXComponent.tsx +266 -0
- package/src/components/DrawerModalComponent.tsx +324 -0
- package/src/components/GradientView.tsx +129 -0
- package/src/components/HapticFeedbackComponent.tsx +39 -0
- package/src/components/HorizontalProductsComponent.tsx +329 -0
- package/src/components/MultiChoiceGridComponent.tsx +265 -0
- package/src/components/NPSScaleComponent.tsx +294 -0
- package/src/components/NavigationComponent.tsx +329 -0
- package/src/components/OAuthButtonComponent.tsx +266 -0
- package/src/components/ProgressLoaderComponent.tsx +366 -0
- package/src/components/ProgressStepperComponent.tsx +250 -0
- package/src/components/SegmentedPickerComponent.tsx +245 -0
- package/src/components/ShareButtonsComponent.tsx +299 -0
- package/src/components/ShareCodeComponent.tsx +303 -0
- package/src/components/SingleChoiceGridComponent.tsx +229 -0
- package/src/components/SliderComponent.tsx +280 -0
- package/src/components/StarRatingInputComponent.tsx +223 -0
- package/src/components/StickerCompositeComponent.tsx +168 -0
- package/src/components/TabsComponent.tsx +496 -0
- package/src/components/TextInputComponent.tsx +258 -0
- package/src/components/TimelineComponent.tsx +129 -0
- package/src/components/ToggleComponent.tsx +142 -0
- package/src/components/VerticalProductsComponent.tsx +357 -0
- package/src/dynamicValues.ts +180 -0
- package/src/filters/dateFilters.ts +411 -0
- package/src/filters/index.ts +281 -0
- package/src/hooks/useOfferings.ts +192 -0
- package/src/hooks/usePaywall.ts +154 -0
- package/src/hooks/usePlacement.ts +143 -0
- package/src/hooks/useSubscription.ts +154 -0
- package/src/index.ts +245 -0
- package/src/models/BillDogError.ts +24 -0
- package/src/models/CacheFetchPolicy.ts +13 -0
- package/src/models/CustomProduct.ts +33 -0
- package/src/models/CustomerInfo.ts +26 -0
- package/src/models/Delegate.ts +22 -0
- package/src/models/EntitlementInfo.ts +27 -0
- package/src/models/Placement.ts +50 -0
- package/src/models/PurchaseParams.ts +81 -0
- package/src/models/PurchaseResult.ts +32 -0
- package/src/models/RestoreResult.ts +27 -0
- package/src/models/RestoredItem.ts +25 -0
- package/src/modules/ABTest.ts +131 -0
- package/src/modules/Analytics.ts +227 -0
- package/src/modules/Survey.ts +126 -0
- package/src/modules/VirtualCurrency.ts +223 -0
- package/src/murmur.ts +102 -0
- package/src/notifications/LiveActivitiesManager.ts +140 -0
- package/src/notifications/NotificationScheduler.ts +292 -0
- package/src/notifications/PurchaseNotificationHandler.ts +67 -0
- package/src/notifications/useDeviceToken.ts +116 -0
- package/src/notifications/useLiveActivity.ts +125 -0
- package/src/review/ReviewAnalytics.ts +89 -0
- package/src/review/ReviewManager.ts +355 -0
- package/src/review/ReviewTimingManager.ts +265 -0
- package/src/survey-core/types.ts +244 -0
- package/src/types/ambient.d.ts +9 -0
- package/src/types.ts +680 -0
- package/src/utils/ApiClient.ts +163 -0
- package/src/utils/CSSConverter.ts +552 -0
- package/src/utils/animations.ts +232 -0
- package/src/utils/calendarIntegration.ts +113 -0
- package/src/utils/configurationResolver.ts +106 -0
- package/src/utils/deviceDetection.ts +83 -0
- package/src/utils/hapticFeedback.ts +55 -0
- package/src/utils/iconMapper.ts +102 -0
- package/src/utils/notificationPermissions.ts +48 -0
- package/src/utils/priceFormatting.ts +119 -0
- package/src/utils/shareSheet.ts +55 -0
- package/src/utils/subscriptionUpgrade.ts +183 -0
- package/src/valueUtils.ts +108 -0
- package/src/xFlowTags.ts +463 -0
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Phase 4: Advanced Caching Features for React Native
|
|
4
|
+
* - Cache compression (reduce storage by 60%)
|
|
5
|
+
* - Multi-level caching (memory + disk)
|
|
6
|
+
* - Intelligent prefetching
|
|
7
|
+
* - Analytics tracking
|
|
8
|
+
*/
|
|
9
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
10
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
11
|
+
};
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.AdvancedPaywallCache = exports.DEFAULT_ADVANCED_CONFIG = void 0;
|
|
14
|
+
const async_storage_1 = __importDefault(require("@react-native-async-storage/async-storage"));
|
|
15
|
+
const react_native_fs_1 = __importDefault(require("react-native-fs"));
|
|
16
|
+
const pako_1 = require("pako");
|
|
17
|
+
exports.DEFAULT_ADVANCED_CONFIG = {
|
|
18
|
+
enabled: true,
|
|
19
|
+
maxCacheAge: 604800000, // 7 days
|
|
20
|
+
compressionEnabled: true,
|
|
21
|
+
memoryCache: true,
|
|
22
|
+
maxMemoryEntries: 20,
|
|
23
|
+
intelligentPrefetch: true,
|
|
24
|
+
analyticsEnabled: true,
|
|
25
|
+
};
|
|
26
|
+
class AdvancedPaywallCache {
|
|
27
|
+
constructor(config = {}) {
|
|
28
|
+
this.memoryCache = new Map();
|
|
29
|
+
this.accessPatterns = new Map();
|
|
30
|
+
this.analytics = {
|
|
31
|
+
hits: 0,
|
|
32
|
+
misses: 0,
|
|
33
|
+
memoryHits: 0,
|
|
34
|
+
diskHits: 0,
|
|
35
|
+
compressionSavings: 0,
|
|
36
|
+
averageRetrievalTime: 0,
|
|
37
|
+
prefetchSuccessRate: 0,
|
|
38
|
+
};
|
|
39
|
+
this.config = { ...exports.DEFAULT_ADVANCED_CONFIG, ...config };
|
|
40
|
+
this.cacheDir = `${react_native_fs_1.default.CachesDirectoryPath}/billdog_paywalls_advanced`;
|
|
41
|
+
react_native_fs_1.default.mkdir(this.cacheDir).catch(() => {
|
|
42
|
+
// Directory might already exist
|
|
43
|
+
});
|
|
44
|
+
this.loadAnalytics();
|
|
45
|
+
this.loadAccessPatterns();
|
|
46
|
+
}
|
|
47
|
+
// MARK: - Compression
|
|
48
|
+
compressData(data) {
|
|
49
|
+
if (!this.config.compressionEnabled) {
|
|
50
|
+
return { compressed: data, originalSize: data.length, compressedSize: data.length };
|
|
51
|
+
}
|
|
52
|
+
const originalSize = Buffer.from(data).length;
|
|
53
|
+
try {
|
|
54
|
+
const compressed = (0, pako_1.deflate)(data);
|
|
55
|
+
const compressedStr = Buffer.from(compressed).toString('base64');
|
|
56
|
+
const compressedSize = compressedStr.length;
|
|
57
|
+
const savings = originalSize - compressedSize;
|
|
58
|
+
this.analytics.compressionSavings += savings;
|
|
59
|
+
const savingsPercent = Math.round((1 - compressedSize / originalSize) * 100);
|
|
60
|
+
console.log(`[AdvancedCache] Compressed ${originalSize}B → ${compressedSize}B (${savingsPercent}% savings)`);
|
|
61
|
+
return { compressed: compressedStr, originalSize, compressedSize };
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
console.error('[AdvancedCache] Compression failed:', error);
|
|
65
|
+
return { compressed: data, originalSize, compressedSize: originalSize };
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
decompressData(compressed) {
|
|
69
|
+
if (!this.config.compressionEnabled)
|
|
70
|
+
return compressed;
|
|
71
|
+
try {
|
|
72
|
+
const buffer = Buffer.from(compressed, 'base64');
|
|
73
|
+
const decompressed = (0, pako_1.inflate)(buffer, { to: 'string' });
|
|
74
|
+
return decompressed;
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
console.error('[AdvancedCache] Decompression failed:', error);
|
|
78
|
+
return compressed;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
// MARK: - Multi-Level Caching
|
|
82
|
+
async get(identifier) {
|
|
83
|
+
if (!this.config.enabled)
|
|
84
|
+
return null;
|
|
85
|
+
const startTime = Date.now();
|
|
86
|
+
// Level 1: Memory cache
|
|
87
|
+
if (this.config.memoryCache && this.memoryCache.has(identifier)) {
|
|
88
|
+
const cached = this.memoryCache.get(identifier);
|
|
89
|
+
if (Date.now() <= cached.expiresAt) {
|
|
90
|
+
this.analytics.hits++;
|
|
91
|
+
this.analytics.memoryHits++;
|
|
92
|
+
this.trackAccess(identifier);
|
|
93
|
+
this.updateAverageRetrievalTime(Date.now() - startTime);
|
|
94
|
+
console.log(`[AdvancedCache] MEMORY HIT: ${identifier} (${Date.now() - startTime}ms)`);
|
|
95
|
+
return cached;
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
this.memoryCache.delete(identifier);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
// Level 2: Disk cache
|
|
102
|
+
const diskCached = await this.getDiskCached(identifier);
|
|
103
|
+
if (diskCached) {
|
|
104
|
+
this.analytics.hits++;
|
|
105
|
+
this.analytics.diskHits++;
|
|
106
|
+
this.trackAccess(identifier);
|
|
107
|
+
// Add to memory cache
|
|
108
|
+
if (this.config.memoryCache) {
|
|
109
|
+
this.addToMemoryCache(identifier, diskCached);
|
|
110
|
+
}
|
|
111
|
+
this.updateAverageRetrievalTime(Date.now() - startTime);
|
|
112
|
+
console.log(`[AdvancedCache] DISK HIT: ${identifier} (${Date.now() - startTime}ms)`);
|
|
113
|
+
// Intelligent prefetch
|
|
114
|
+
if (this.config.intelligentPrefetch) {
|
|
115
|
+
this.schedulePrefetch(identifier);
|
|
116
|
+
}
|
|
117
|
+
return diskCached;
|
|
118
|
+
}
|
|
119
|
+
this.analytics.misses++;
|
|
120
|
+
console.log(`[AdvancedCache] MISS: ${identifier}`);
|
|
121
|
+
return null;
|
|
122
|
+
}
|
|
123
|
+
async getDiskCached(identifier) {
|
|
124
|
+
try {
|
|
125
|
+
const key = `paywall:${identifier}`;
|
|
126
|
+
const cachedJson = await async_storage_1.default.getItem(key);
|
|
127
|
+
if (!cachedJson)
|
|
128
|
+
return null;
|
|
129
|
+
const isCompressed = (await async_storage_1.default.getItem(`${key}:compressed`)) === 'true';
|
|
130
|
+
const dataToUse = isCompressed ? this.decompressData(cachedJson) : cachedJson;
|
|
131
|
+
const cached = JSON.parse(dataToUse);
|
|
132
|
+
// Check expiration
|
|
133
|
+
if (Date.now() > cached.expiresAt) {
|
|
134
|
+
await this.delete(identifier);
|
|
135
|
+
return null;
|
|
136
|
+
}
|
|
137
|
+
return cached;
|
|
138
|
+
}
|
|
139
|
+
catch (error) {
|
|
140
|
+
console.error(`[AdvancedCache] ERROR reading disk cache:`, error);
|
|
141
|
+
return null;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
async set(identifier, paywall) {
|
|
145
|
+
if (!this.config.enabled)
|
|
146
|
+
return;
|
|
147
|
+
// Add to memory cache (uncompressed)
|
|
148
|
+
if (this.config.memoryCache) {
|
|
149
|
+
this.addToMemoryCache(identifier, paywall);
|
|
150
|
+
}
|
|
151
|
+
// Compress and save to disk
|
|
152
|
+
try {
|
|
153
|
+
const jsonString = JSON.stringify(paywall);
|
|
154
|
+
if (this.config.compressionEnabled) {
|
|
155
|
+
const { compressed, originalSize, compressedSize } = this.compressData(jsonString);
|
|
156
|
+
const key = `paywall:${identifier}`;
|
|
157
|
+
await async_storage_1.default.multiSet([
|
|
158
|
+
[key, compressed],
|
|
159
|
+
[`${key}:compressed`, 'true'],
|
|
160
|
+
[`${key}:originalSize`, originalSize.toString()],
|
|
161
|
+
[`${key}:compressedSize`, compressedSize.toString()],
|
|
162
|
+
]);
|
|
163
|
+
console.log(`[AdvancedCache] CACHED: ${identifier} (compressed)`);
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
await async_storage_1.default.setItem(`paywall:${identifier}`, jsonString);
|
|
167
|
+
console.log(`[AdvancedCache] CACHED: ${identifier}`);
|
|
168
|
+
}
|
|
169
|
+
this.trackAccess(identifier);
|
|
170
|
+
this.saveAnalytics();
|
|
171
|
+
}
|
|
172
|
+
catch (error) {
|
|
173
|
+
console.error(`[AdvancedCache] ERROR writing cache:`, error);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
addToMemoryCache(identifier, data) {
|
|
177
|
+
// LRU eviction
|
|
178
|
+
if (this.memoryCache.size >= this.config.maxMemoryEntries) {
|
|
179
|
+
const oldestKey = this.findLeastRecentlyUsed();
|
|
180
|
+
if (oldestKey) {
|
|
181
|
+
this.memoryCache.delete(oldestKey);
|
|
182
|
+
console.log(`[AdvancedCache] Memory evicted: ${oldestKey}`);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
this.memoryCache.set(identifier, data);
|
|
186
|
+
}
|
|
187
|
+
findLeastRecentlyUsed() {
|
|
188
|
+
let oldestKey = null;
|
|
189
|
+
let oldestTime = Date.now();
|
|
190
|
+
this.accessPatterns.forEach((pattern, key) => {
|
|
191
|
+
if (pattern.lastAccessed < oldestTime) {
|
|
192
|
+
oldestTime = pattern.lastAccessed;
|
|
193
|
+
oldestKey = key;
|
|
194
|
+
}
|
|
195
|
+
});
|
|
196
|
+
return oldestKey;
|
|
197
|
+
}
|
|
198
|
+
// MARK: - Intelligent Prefetching
|
|
199
|
+
trackAccess(identifier) {
|
|
200
|
+
const pattern = this.accessPatterns.get(identifier) || {
|
|
201
|
+
identifier,
|
|
202
|
+
lastAccessed: 0,
|
|
203
|
+
accessCount: 0,
|
|
204
|
+
relatedPaywalls: [],
|
|
205
|
+
};
|
|
206
|
+
pattern.lastAccessed = Date.now();
|
|
207
|
+
pattern.accessCount++;
|
|
208
|
+
this.accessPatterns.set(identifier, pattern);
|
|
209
|
+
// Save periodically
|
|
210
|
+
if (pattern.accessCount % 10 === 0) {
|
|
211
|
+
this.saveAccessPatterns();
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
async schedulePrefetch(identifier) {
|
|
215
|
+
if (!this.config.intelligentPrefetch)
|
|
216
|
+
return;
|
|
217
|
+
const pattern = this.accessPatterns.get(identifier);
|
|
218
|
+
if (!pattern || pattern.relatedPaywalls.length === 0)
|
|
219
|
+
return;
|
|
220
|
+
// Prefetch top 2 related paywalls
|
|
221
|
+
const toPrefetch = pattern.relatedPaywalls.slice(0, 2);
|
|
222
|
+
for (const relatedId of toPrefetch) {
|
|
223
|
+
if (!this.memoryCache.has(relatedId)) {
|
|
224
|
+
console.log(`[AdvancedCache] Prefetching: ${relatedId}`);
|
|
225
|
+
// Prefetch would trigger actual fetch here
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
learnRelationship(fromId, toId) {
|
|
230
|
+
const pattern = this.accessPatterns.get(fromId);
|
|
231
|
+
if (pattern) {
|
|
232
|
+
if (!pattern.relatedPaywalls.includes(toId)) {
|
|
233
|
+
pattern.relatedPaywalls.push(toId);
|
|
234
|
+
// Keep only top 5
|
|
235
|
+
if (pattern.relatedPaywalls.length > 5) {
|
|
236
|
+
pattern.relatedPaywalls.shift();
|
|
237
|
+
}
|
|
238
|
+
this.saveAccessPatterns();
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
// MARK: - Analytics
|
|
243
|
+
updateAverageRetrievalTime(time) {
|
|
244
|
+
const totalRequests = this.analytics.hits + this.analytics.misses;
|
|
245
|
+
this.analytics.averageRetrievalTime =
|
|
246
|
+
(this.analytics.averageRetrievalTime * (totalRequests - 1) + time) / totalRequests;
|
|
247
|
+
}
|
|
248
|
+
async saveAnalytics() {
|
|
249
|
+
try {
|
|
250
|
+
await async_storage_1.default.setItem('billdog:cache:analytics', JSON.stringify(this.analytics));
|
|
251
|
+
}
|
|
252
|
+
catch (error) {
|
|
253
|
+
console.error('[AdvancedCache] Failed to save analytics:', error);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
async loadAnalytics() {
|
|
257
|
+
try {
|
|
258
|
+
const stored = await async_storage_1.default.getItem('billdog:cache:analytics');
|
|
259
|
+
if (stored) {
|
|
260
|
+
this.analytics = JSON.parse(stored);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
catch (error) {
|
|
264
|
+
console.error('[AdvancedCache] Failed to load analytics:', error);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
getAnalytics() {
|
|
268
|
+
const total = this.analytics.hits + this.analytics.misses;
|
|
269
|
+
const hitRate = total > 0 ? (this.analytics.hits / total) * 100 : 0;
|
|
270
|
+
const memoryHitRate = this.analytics.hits > 0 ? (this.analytics.memoryHits / this.analytics.hits) * 100 : 0;
|
|
271
|
+
return {
|
|
272
|
+
...this.analytics,
|
|
273
|
+
hitRate: Math.round(hitRate * 100) / 100,
|
|
274
|
+
memoryHitRate: Math.round(memoryHitRate * 100) / 100,
|
|
275
|
+
memorySize: this.memoryCache.size,
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
resetAnalytics() {
|
|
279
|
+
this.analytics = {
|
|
280
|
+
hits: 0,
|
|
281
|
+
misses: 0,
|
|
282
|
+
memoryHits: 0,
|
|
283
|
+
diskHits: 0,
|
|
284
|
+
compressionSavings: 0,
|
|
285
|
+
averageRetrievalTime: 0,
|
|
286
|
+
prefetchSuccessRate: 0,
|
|
287
|
+
};
|
|
288
|
+
this.saveAnalytics();
|
|
289
|
+
}
|
|
290
|
+
// MARK: - Persistence
|
|
291
|
+
async saveAccessPatterns() {
|
|
292
|
+
try {
|
|
293
|
+
const patternsObj = Object.fromEntries(this.accessPatterns);
|
|
294
|
+
await async_storage_1.default.setItem('billdog:cache:patterns', JSON.stringify(patternsObj));
|
|
295
|
+
}
|
|
296
|
+
catch (error) {
|
|
297
|
+
console.error('[AdvancedCache] Failed to save patterns:', error);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
async loadAccessPatterns() {
|
|
301
|
+
try {
|
|
302
|
+
const stored = await async_storage_1.default.getItem('billdog:cache:patterns');
|
|
303
|
+
if (stored) {
|
|
304
|
+
const patternsObj = JSON.parse(stored);
|
|
305
|
+
this.accessPatterns = new Map(Object.entries(patternsObj));
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
catch (error) {
|
|
309
|
+
console.error('[AdvancedCache] Failed to load patterns:', error);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
// MARK: - Cleanup
|
|
313
|
+
async delete(identifier) {
|
|
314
|
+
this.memoryCache.delete(identifier);
|
|
315
|
+
const key = `paywall:${identifier}`;
|
|
316
|
+
await async_storage_1.default.multiRemove([key, `${key}:compressed`, `${key}:originalSize`, `${key}:compressedSize`]);
|
|
317
|
+
console.log(`[AdvancedCache] DELETED: ${identifier}`);
|
|
318
|
+
}
|
|
319
|
+
async clearAll() {
|
|
320
|
+
this.memoryCache.clear();
|
|
321
|
+
this.accessPatterns.clear();
|
|
322
|
+
// Clear AsyncStorage
|
|
323
|
+
const keys = await async_storage_1.default.getAllKeys();
|
|
324
|
+
const paywallKeys = keys.filter((key) => key.startsWith('paywall:') || key.includes(':cache:'));
|
|
325
|
+
await async_storage_1.default.multiRemove(paywallKeys);
|
|
326
|
+
console.log('[AdvancedCache] All caches cleared (memory + disk)');
|
|
327
|
+
}
|
|
328
|
+
async getStats() {
|
|
329
|
+
try {
|
|
330
|
+
const keys = await async_storage_1.default.getAllKeys();
|
|
331
|
+
const paywallCount = keys.filter((key) => key.startsWith('paywall:') && !key.includes(':')).length;
|
|
332
|
+
return {
|
|
333
|
+
paywallCount,
|
|
334
|
+
memoryCount: this.memoryCache.size,
|
|
335
|
+
compressionSavings: this.analytics.compressionSavings,
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
catch (error) {
|
|
339
|
+
console.error('[AdvancedCache] Error getting stats:', error);
|
|
340
|
+
return { paywallCount: 0, memoryCount: 0, compressionSavings: 0 };
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
exports.AdvancedPaywallCache = AdvancedPaywallCache;
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BillDog — top-level RN facade.
|
|
3
|
+
*
|
|
4
|
+
* Spec: PUR-063, PUR-064, PUR-080..085, PUR-121, PUR-122, PUR-140..146,
|
|
5
|
+
* PUR-224, PUR-350, PUR-360, PUR-362, PUR-363, PUR-364
|
|
6
|
+
* (.lovable/purchase-conformance-spec.md)
|
|
7
|
+
* Standard: mem://architecture/react-native/sdk-unified-standard
|
|
8
|
+
* mem://architecture/customer-info-cache-standard
|
|
9
|
+
* mem://architecture/entitlements-authoritative-standard
|
|
10
|
+
* mem://architecture/purchase-conformance-standard
|
|
11
|
+
*
|
|
12
|
+
* Slice J (PUR-364) propagates the v1.4 purchase parity surface to the RN
|
|
13
|
+
* bridge with iOS/Android wire parity:
|
|
14
|
+
* - `purchase(params)` — typed PurchaseParams, returns canonical PurchaseResult
|
|
15
|
+
* - `purchase(custom)` — Superwall-style non-StoreKit products via host controller
|
|
16
|
+
* - `setPurchaseController(...)` — JS-side controller for EXTERNAL/CUSTOM flows
|
|
17
|
+
* - `setProxyURL` / `getProxyURL` — self-hosted proxy
|
|
18
|
+
* - `canMakePayments`, `presentCodeRedemptionSheet`,
|
|
19
|
+
* `checkTrialOrIntroDiscountEligibility`, `onStorefrontChange`
|
|
20
|
+
* - 14-provider attribution matrix + `collectDeviceIdentifiers`
|
|
21
|
+
*
|
|
22
|
+
* Every method gracefully falls back when `NativeModules.BillDog` is null so
|
|
23
|
+
* consumer apps compile against the contract before the native bridge is wired
|
|
24
|
+
* in their host project. The facade NEVER throws across the public boundary —
|
|
25
|
+
* store/network errors are surfaced as typed result unions.
|
|
26
|
+
*/
|
|
27
|
+
import type { RestoreResult } from './models/RestoreResult';
|
|
28
|
+
import type { CacheFetchPolicy } from './models/CacheFetchPolicy';
|
|
29
|
+
import { type CustomerInfo } from './models/CustomerInfo';
|
|
30
|
+
import type { EntitlementInfo } from './models/EntitlementInfo';
|
|
31
|
+
import type { PurchaseParams } from './models/PurchaseParams';
|
|
32
|
+
import { PurchaseParams as PurchaseParamsNS } from './models/PurchaseParams';
|
|
33
|
+
import type { PurchaseResult } from './models/PurchaseResult';
|
|
34
|
+
import type { CustomProduct } from './models/CustomProduct';
|
|
35
|
+
import type { PlacementResult, PresentationResult, PaywallPresentationHandler } from './models/Placement';
|
|
36
|
+
import type { BillDogDelegate } from './models/Delegate';
|
|
37
|
+
/**
|
|
38
|
+
* PUR-142/224: multi-subscriber CustomerInfo emitter with replay-1 semantics.
|
|
39
|
+
* New subscribers immediately receive the most recent cached value (if any).
|
|
40
|
+
*/
|
|
41
|
+
type CustomerInfoListener = (info: CustomerInfo) => void;
|
|
42
|
+
declare class CustomerInfoEmitter {
|
|
43
|
+
private listeners;
|
|
44
|
+
private lastValue;
|
|
45
|
+
addListener(fn: CustomerInfoListener): {
|
|
46
|
+
remove: () => void;
|
|
47
|
+
};
|
|
48
|
+
emit(info: CustomerInfo): void;
|
|
49
|
+
get latest(): CustomerInfo | null;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* PUR-364: Storefront country observer (iOS-only on the producer side; the
|
|
53
|
+
* RN bridge surfaces a no-op on Android until Play exposes a country API).
|
|
54
|
+
*/
|
|
55
|
+
type StorefrontListener = (storefront: {
|
|
56
|
+
countryCode: string;
|
|
57
|
+
}) => void;
|
|
58
|
+
/**
|
|
59
|
+
* PUR-364: JS-side PurchaseController contract — mirrors iOS/Android.
|
|
60
|
+
* Implementations MUST map user cancellation to `{type:'cancelled'}` and
|
|
61
|
+
* Ask-to-Buy / Android PENDING to `{type:'pending'}` — never `failed`.
|
|
62
|
+
*/
|
|
63
|
+
export interface PurchaseController {
|
|
64
|
+
purchase(productId: string): Promise<PurchaseResult>;
|
|
65
|
+
restorePurchases(): Promise<RestoreResult>;
|
|
66
|
+
}
|
|
67
|
+
/** SDK version constant — Android parity (BillDog.kt:51). */
|
|
68
|
+
export declare const SDK_VERSION = "1.0.0-beta.2";
|
|
69
|
+
export declare const BillDog: {
|
|
70
|
+
/** SDK version constant — re-exposed on the singleton for ergonomic access. */
|
|
71
|
+
SDK_VERSION: string;
|
|
72
|
+
/**
|
|
73
|
+
* Purchase a product with typed `PurchaseParams`. Returns canonical
|
|
74
|
+
* `PurchaseResult` — NEVER throws across the public boundary.
|
|
75
|
+
*
|
|
76
|
+
* If a host `PurchaseController` is registered (see `setPurchaseController`),
|
|
77
|
+
* the controller drives the transaction and the receipt is stamped
|
|
78
|
+
* `source = EXTERNAL`. Otherwise the bundled native controller is used
|
|
79
|
+
* (`source = INTERNAL`).
|
|
80
|
+
*/
|
|
81
|
+
purchase(params: PurchaseParams): Promise<PurchaseResult>;
|
|
82
|
+
/**
|
|
83
|
+
* PUR-363: Purchase a Superwall-style non-StoreKit / non-Play product.
|
|
84
|
+
* Routing is ONLY through a host-provided PurchaseController.
|
|
85
|
+
*/
|
|
86
|
+
purchaseCustom(product: CustomProduct): Promise<PurchaseResult>;
|
|
87
|
+
/** Get the currently-registered host PurchaseController, or null. */
|
|
88
|
+
getPurchaseController(): PurchaseController | null;
|
|
89
|
+
/** Flush pending analytics events to the backend. */
|
|
90
|
+
flushAnalytics(): Promise<void>;
|
|
91
|
+
/** PUR-364: Register a host PurchaseController. Pass `null` to detach. */
|
|
92
|
+
setPurchaseController(controller: PurchaseController | null): void;
|
|
93
|
+
/**
|
|
94
|
+
* Restore previous purchases (PUR-080).
|
|
95
|
+
*
|
|
96
|
+
* - `{type:'restored', items: []}` — nothing to restore
|
|
97
|
+
* - `{type:'restored', items: [...]}` — items resurfaced
|
|
98
|
+
* - `{type:'failed', error: BillDogError}` — global failure
|
|
99
|
+
*/
|
|
100
|
+
restore(): Promise<RestoreResult>;
|
|
101
|
+
getCustomerInfo(policy?: CacheFetchPolicy): Promise<CustomerInfo | null>;
|
|
102
|
+
customerInfoEmitter: CustomerInfoEmitter;
|
|
103
|
+
/**
|
|
104
|
+
* PUR-121: resolve entitlements unlocked by a [productId] from the local
|
|
105
|
+
* `productEntitlementMapping`. Used for instant gating.
|
|
106
|
+
*/
|
|
107
|
+
entitlementsForProduct(productId: string): EntitlementInfo[];
|
|
108
|
+
/** PUR-201: Can the device transact at all? (parental controls, MDM) */
|
|
109
|
+
canMakePayments(): Promise<boolean>;
|
|
110
|
+
/** PUR-330: Present the App Store promo code redemption sheet (iOS-only). */
|
|
111
|
+
presentCodeRedemptionSheet(): Promise<void>;
|
|
112
|
+
/**
|
|
113
|
+
* PUR-037: Check trial / intro-discount eligibility for an array of product
|
|
114
|
+
* ids. Returns a map of `productId` -> `'eligible' | 'ineligible' | 'unknown'`.
|
|
115
|
+
*/
|
|
116
|
+
checkTrialOrIntroDiscountEligibility(productIds: string[]): Promise<Record<string, "eligible" | "ineligible" | "unknown">>;
|
|
117
|
+
/** PUR-202: Subscribe to storefront country changes (iOS-only producer). */
|
|
118
|
+
onStorefrontChange(listener: StorefrontListener): {
|
|
119
|
+
remove: () => void;
|
|
120
|
+
};
|
|
121
|
+
setProxyURL(url: string | null): void;
|
|
122
|
+
setConsentRequired(required: boolean): void;
|
|
123
|
+
setConsent(purpose: "analytics" | "replay" | "messaging" | "survey", granted: boolean): void;
|
|
124
|
+
setConsentGiven(given: boolean): void;
|
|
125
|
+
consentHeaderValue(): Promise<string | null>;
|
|
126
|
+
getProxyURL(): string | null;
|
|
127
|
+
/**
|
|
128
|
+
* Set one or more attribution ids at once. Keys are the provider attribution
|
|
129
|
+
* keys (e.g. `mixpanelDistinctId`, `cleverTapId`, `iterableId`). Prefer the
|
|
130
|
+
* named convenience setters below unless batching.
|
|
131
|
+
*/
|
|
132
|
+
setAttribution(data: Record<string, string>): void;
|
|
133
|
+
setCleverTapID: (id: string | null) => void;
|
|
134
|
+
setMixpanelDistinctID: (id: string | null) => void;
|
|
135
|
+
setOnesignalID: (id: string | null) => void;
|
|
136
|
+
setFBAnonymousID: (id: string | null) => void;
|
|
137
|
+
setAirshipChannelID: (id: string | null) => void;
|
|
138
|
+
setMoEngageAnonymousID: (id: string | null) => void;
|
|
139
|
+
setMparticleID: (id: string | null) => void;
|
|
140
|
+
setKochavaDeviceID: (id: string | null) => void;
|
|
141
|
+
setTenjinAnalyticsInstallationID: (id: string | null) => void;
|
|
142
|
+
setIterableUserID: (id: string | null) => void;
|
|
143
|
+
setSegmentAnonymousID: (id: string | null) => void;
|
|
144
|
+
setAdjustId: (id: string | null) => void;
|
|
145
|
+
setAppsflyerId: (id: string | null) => void;
|
|
146
|
+
setFirebaseAppInstanceId: (id: string | null) => void;
|
|
147
|
+
/** Collect IDFA / GAID after consent has been granted. */
|
|
148
|
+
collectDeviceIdentifiers(): void;
|
|
149
|
+
/**
|
|
150
|
+
* Log in an app user. Persists the user id, propagates to the native bridge
|
|
151
|
+
* (if wired) and the analytics module. Throws on blank ids — mirrors KMP/Unity.
|
|
152
|
+
*/
|
|
153
|
+
logIn(appUserId: string): Promise<void>;
|
|
154
|
+
/** Log out the current user and return to anonymous state. */
|
|
155
|
+
logOut(): Promise<void>;
|
|
156
|
+
/**
|
|
157
|
+
* Identify a user with optional attributes. Behaves as `logIn` plus an
|
|
158
|
+
* analytics super-properties update for the supplied attributes.
|
|
159
|
+
*/
|
|
160
|
+
identify(userId: string, attributes?: Record<string, any>): Promise<void>;
|
|
161
|
+
/** True when no app user is currently logged in. */
|
|
162
|
+
isAnonymous(): boolean;
|
|
163
|
+
/** Returns the currently logged-in app user id, or null when anonymous. */
|
|
164
|
+
getAppUserId(): string | null;
|
|
165
|
+
/**
|
|
166
|
+
* Mirrors Android `BillDog.isConfigured()` (BillDog.kt:325). Delegates to
|
|
167
|
+
* the configuration singleton so the apiKey-presence check lives in one place.
|
|
168
|
+
*/
|
|
169
|
+
isConfigured(): boolean;
|
|
170
|
+
/**
|
|
171
|
+
* Cross-SDK parity stub matching KMP / Unity / Android. Toggles a local
|
|
172
|
+
* flag and forwards to the native bridge if wired; otherwise a documented
|
|
173
|
+
* no-op (sandbox is primarily controlled via API key prefix).
|
|
174
|
+
*/
|
|
175
|
+
setSandboxMode(enabled: boolean): void;
|
|
176
|
+
/**
|
|
177
|
+
* Register a placement and run the canonical placement flow: fetch config →
|
|
178
|
+
* check entitlement → present paywall if needed. Returns a `PlacementResult`
|
|
179
|
+
* describing the outcome. Optional `handler` receives lifecycle callbacks
|
|
180
|
+
* mirroring Android's `PaywallPresentationHandler`.
|
|
181
|
+
*
|
|
182
|
+
* Returns `{ type: 'entitled' }` immediately if the user already holds the
|
|
183
|
+
* placement's required entitlement (no paywall shown). Returns
|
|
184
|
+
* `{ type: 'error', message }` on any failure — never throws across the
|
|
185
|
+
* public boundary.
|
|
186
|
+
*/
|
|
187
|
+
register(placementId: string, params?: Record<string, unknown>, handler?: PaywallPresentationHandler): Promise<PlacementResult>;
|
|
188
|
+
/**
|
|
189
|
+
* Synchronous probe — does the current user have access to a placement?
|
|
190
|
+
* Returns `true` when the placement is unregistered or has no required
|
|
191
|
+
* entitlement (safe default matching Android's behaviour).
|
|
192
|
+
*/
|
|
193
|
+
hasAccessForPlacement(placementId: string): boolean;
|
|
194
|
+
/** Open the IAM inbox / present a single message. */
|
|
195
|
+
showInAppMessages(placementId?: string): Promise<void>;
|
|
196
|
+
/** Route a deep link through the SDK. Returns true when handled. */
|
|
197
|
+
handleDeepLink(uri: string): Promise<boolean>;
|
|
198
|
+
getSelectedProductIndex(componentId: string): number | null;
|
|
199
|
+
setSelectedProductIndex(componentId: string, index: number): void;
|
|
200
|
+
/** Apply runtime theme overrides. Map of token name → value. */
|
|
201
|
+
updateTheme(overrides: Record<string, string>): void;
|
|
202
|
+
/** Set the SDK-wide interface style. Pass `null` to follow system. */
|
|
203
|
+
setInterfaceStyle(style: "light" | "dark" | null): void;
|
|
204
|
+
/**
|
|
205
|
+
* Open the platform-native subscription management UI. iOS routes to
|
|
206
|
+
* the App Store; Android routes to Play Store; web throws since no
|
|
207
|
+
* platform UI is available.
|
|
208
|
+
*/
|
|
209
|
+
showManageSubscriptions(subscriptionId?: string): Promise<void>;
|
|
210
|
+
/** Clear all SDK caches (paywall configs, customer info, products). */
|
|
211
|
+
clearCache(): Promise<void>;
|
|
212
|
+
/** Invalidate the cached customer info — next read triggers a refetch. */
|
|
213
|
+
invalidateCustomerInfoCache(): Promise<void>;
|
|
214
|
+
/** Set typed attributes on the current user (targeting + analytics). */
|
|
215
|
+
setUserAttributes(attributes: Record<string, unknown>): Promise<void>;
|
|
216
|
+
/** Get the current user attributes (snapshot). */
|
|
217
|
+
getUserAttributes(): Promise<Record<string, unknown>>;
|
|
218
|
+
/** Notify BillDog that an externally-driven purchase has started. */
|
|
219
|
+
observePurchaseStart(productId: string): void;
|
|
220
|
+
/** Notify BillDog that an externally-driven purchase succeeded. */
|
|
221
|
+
observePurchaseResult(productId: string, orderId?: string): void;
|
|
222
|
+
/** Notify BillDog that an externally-driven purchase failed. */
|
|
223
|
+
observePurchaseError(productId: string, error: string): void;
|
|
224
|
+
/**
|
|
225
|
+
* Set the active delegate. Pass `null` to detach. All delegate callbacks
|
|
226
|
+
* are optional; the SDK fires the ones that are defined.
|
|
227
|
+
*/
|
|
228
|
+
setDelegate(delegate: BillDogDelegate | null): void;
|
|
229
|
+
/** Internal — emit a typed lifecycle event to the delegate (if any). */
|
|
230
|
+
_emitDelegate<K extends keyof BillDogDelegate>(event: K, ...args: Parameters<NonNullable<BillDogDelegate[K]>>): void;
|
|
231
|
+
/**
|
|
232
|
+
* Evaluate what would happen if `register(placementId)` were called, without
|
|
233
|
+
* presenting a paywall. Returns one of `paywall`, `userSubscribed`,
|
|
234
|
+
* `noPaywall`, `holdout`, or `error`.
|
|
235
|
+
*/
|
|
236
|
+
getPresentationResult(placementId: string): Promise<PresentationResult>;
|
|
237
|
+
/**
|
|
238
|
+
* Execute a server-side paywall tap action (Route B).
|
|
239
|
+
* Delegates to native SDK bridge `executeAction` if present; falls back to direct
|
|
240
|
+
* JavaScript fetch request to `execute-paywall-action` Edge Function if native is absent.
|
|
241
|
+
*/
|
|
242
|
+
executeAction(paywallId: string | null, componentId: string, actionType: string, idempotencyKey?: string | null, metadata?: Record<string, any>): Promise<any>;
|
|
243
|
+
};
|
|
244
|
+
export { PurchaseParamsNS as PurchaseParams };
|
|
245
|
+
export type { RestoreResult } from './models/RestoreResult';
|
|
246
|
+
export type { RestoredItem, RestoreItemStatus } from './models/RestoredItem';
|
|
247
|
+
export type { BillDogError } from './models/BillDogError';
|
|
248
|
+
export type { CacheFetchPolicy } from './models/CacheFetchPolicy';
|
|
249
|
+
export type { CustomerInfo } from './models/CustomerInfo';
|
|
250
|
+
export type { EntitlementInfo, EntitlementState } from './models/EntitlementInfo';
|
|
251
|
+
export type { PurchaseParams as PurchaseParamsType, GoogleReplacementMode } from './models/PurchaseParams';
|
|
252
|
+
export type { PurchaseResult } from './models/PurchaseResult';
|
|
253
|
+
export type { CustomProduct } from './models/CustomProduct';
|
|
254
|
+
export type { PlacementResult, PresentationResult, PaywallLoadingState, SkipReason, PostPurchaseBehavior, PaywallPresentationHandler, } from './models/Placement';
|
|
255
|
+
export type { BillDogDelegate } from './models/Delegate';
|