rampkit-expo-dev 0.0.19 → 0.0.23

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.
@@ -0,0 +1,255 @@
1
+ "use strict";
2
+ /**
3
+ * RampKit Native Module Bridge
4
+ * TypeScript interface to the native iOS/Android module
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.Notifications = exports.StoreReview = exports.Haptics = void 0;
8
+ exports.getDeviceInfo = getDeviceInfo;
9
+ exports.getUserId = getUserId;
10
+ exports.getStoredValue = getStoredValue;
11
+ exports.setStoredValue = setStoredValue;
12
+ exports.getLaunchTrackingData = getLaunchTrackingData;
13
+ const expo_modules_core_1 = require("expo-modules-core");
14
+ const react_native_1 = require("react-native");
15
+ // Get the native module
16
+ let RampKitNativeModule;
17
+ try {
18
+ RampKitNativeModule = (0, expo_modules_core_1.requireNativeModule)("RampKit");
19
+ }
20
+ catch (e) {
21
+ console.warn("[RampKit] Native module not available. Using JavaScript fallback.");
22
+ RampKitNativeModule = createFallbackModule();
23
+ }
24
+ // Fallback module for when native module is not available
25
+ function createFallbackModule() {
26
+ return {
27
+ async getDeviceInfo() {
28
+ return getFallbackDeviceInfo();
29
+ },
30
+ async getUserId() {
31
+ return generateFallbackUserId();
32
+ },
33
+ async getStoredValue(_key) {
34
+ return null;
35
+ },
36
+ async setStoredValue(_key, _value) { },
37
+ async getLaunchTrackingData() {
38
+ return {
39
+ installDate: new Date().toISOString(),
40
+ isFirstLaunch: true,
41
+ launchCount: 1,
42
+ lastLaunchAt: null,
43
+ };
44
+ },
45
+ async impactAsync(_style) { },
46
+ async notificationAsync(_type) { },
47
+ async selectionAsync() { },
48
+ async requestReview() {
49
+ return false;
50
+ },
51
+ async isReviewAvailable() {
52
+ return false;
53
+ },
54
+ async getStoreUrl() {
55
+ return null;
56
+ },
57
+ async requestNotificationPermissions(_options) {
58
+ return { granted: false, status: "denied", canAskAgain: false };
59
+ },
60
+ async getNotificationPermissions() {
61
+ return { granted: false, status: "denied", canAskAgain: false };
62
+ },
63
+ };
64
+ }
65
+ function generateFallbackUserId() {
66
+ return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
67
+ const r = (Math.random() * 16) | 0;
68
+ const v = c === "x" ? r : (r & 0x3) | 0x8;
69
+ return v.toString(16);
70
+ });
71
+ }
72
+ function getFallbackDeviceInfo() {
73
+ const now = new Date().toISOString();
74
+ return {
75
+ appUserId: generateFallbackUserId(),
76
+ vendorId: null,
77
+ appSessionId: generateFallbackUserId(),
78
+ installDate: now,
79
+ isFirstLaunch: true,
80
+ launchCount: 1,
81
+ lastLaunchAt: null,
82
+ bundleId: null,
83
+ appName: null,
84
+ appVersion: null,
85
+ buildNumber: null,
86
+ platform: react_native_1.Platform.OS === "ios" ? "iOS" : "Android",
87
+ platformVersion: String(react_native_1.Platform.Version),
88
+ deviceModel: "unknown",
89
+ deviceName: "unknown",
90
+ isSimulator: false,
91
+ deviceLanguageCode: null,
92
+ deviceLocale: "en_US",
93
+ regionCode: null,
94
+ preferredLanguage: null,
95
+ preferredLanguages: [],
96
+ deviceCurrencyCode: null,
97
+ deviceCurrencySymbol: null,
98
+ timezoneIdentifier: "UTC",
99
+ timezoneOffsetSeconds: 0,
100
+ interfaceStyle: "unspecified",
101
+ screenWidth: 0,
102
+ screenHeight: 0,
103
+ screenScale: 1,
104
+ isLowPowerMode: false,
105
+ totalMemoryBytes: 0,
106
+ collectedAt: now,
107
+ };
108
+ }
109
+ // Export the native module
110
+ exports.default = RampKitNativeModule;
111
+ // ============================================================================
112
+ // Convenience exports for Device Info
113
+ // ============================================================================
114
+ async function getDeviceInfo() {
115
+ return RampKitNativeModule.getDeviceInfo();
116
+ }
117
+ async function getUserId() {
118
+ return RampKitNativeModule.getUserId();
119
+ }
120
+ async function getStoredValue(key) {
121
+ return RampKitNativeModule.getStoredValue(key);
122
+ }
123
+ async function setStoredValue(key, value) {
124
+ return RampKitNativeModule.setStoredValue(key, value);
125
+ }
126
+ async function getLaunchTrackingData() {
127
+ return RampKitNativeModule.getLaunchTrackingData();
128
+ }
129
+ // ============================================================================
130
+ // Haptics API (replaces expo-haptics)
131
+ // ============================================================================
132
+ exports.Haptics = {
133
+ /**
134
+ * Trigger an impact haptic feedback
135
+ */
136
+ async impactAsync(style = "medium") {
137
+ try {
138
+ await RampKitNativeModule.impactAsync(style);
139
+ }
140
+ catch (e) {
141
+ // Silently fail - haptics are non-critical
142
+ }
143
+ },
144
+ /**
145
+ * Trigger a notification haptic feedback
146
+ */
147
+ async notificationAsync(type = "success") {
148
+ try {
149
+ await RampKitNativeModule.notificationAsync(type);
150
+ }
151
+ catch (e) {
152
+ // Silently fail
153
+ }
154
+ },
155
+ /**
156
+ * Trigger a selection haptic feedback
157
+ */
158
+ async selectionAsync() {
159
+ try {
160
+ await RampKitNativeModule.selectionAsync();
161
+ }
162
+ catch (e) {
163
+ // Silently fail
164
+ }
165
+ },
166
+ };
167
+ // ============================================================================
168
+ // Store Review API (replaces expo-store-review)
169
+ // ============================================================================
170
+ exports.StoreReview = {
171
+ /**
172
+ * Request an in-app review
173
+ */
174
+ async requestReview() {
175
+ try {
176
+ await RampKitNativeModule.requestReview();
177
+ }
178
+ catch (e) {
179
+ console.warn("[RampKit] Failed to request review:", e);
180
+ }
181
+ },
182
+ /**
183
+ * Check if in-app review is available
184
+ */
185
+ async isAvailableAsync() {
186
+ try {
187
+ return await RampKitNativeModule.isReviewAvailable();
188
+ }
189
+ catch (e) {
190
+ return false;
191
+ }
192
+ },
193
+ /**
194
+ * Check if the review action is available
195
+ */
196
+ async hasAction() {
197
+ return true;
198
+ },
199
+ /**
200
+ * Get the store URL for the app
201
+ */
202
+ storeUrl() {
203
+ // This is synchronous in the original API, so we can't await here
204
+ // Return null and let callers handle it
205
+ return null;
206
+ },
207
+ };
208
+ // ============================================================================
209
+ // Notifications API (replaces expo-notifications)
210
+ // ============================================================================
211
+ exports.Notifications = {
212
+ /**
213
+ * Request notification permissions
214
+ */
215
+ async requestPermissionsAsync(options) {
216
+ try {
217
+ return await RampKitNativeModule.requestNotificationPermissions(options);
218
+ }
219
+ catch (e) {
220
+ return { granted: false, status: "denied", canAskAgain: false };
221
+ }
222
+ },
223
+ /**
224
+ * Get current notification permissions
225
+ */
226
+ async getPermissionsAsync() {
227
+ try {
228
+ return await RampKitNativeModule.getNotificationPermissions();
229
+ }
230
+ catch (e) {
231
+ return { granted: false, status: "denied", canAskAgain: false };
232
+ }
233
+ },
234
+ /**
235
+ * Set notification handler (no-op in native implementation)
236
+ * The app should handle this separately if needed
237
+ */
238
+ setNotificationHandler(_handler) {
239
+ // No-op - notification handling is done by the app
240
+ },
241
+ /**
242
+ * Android notification channel creation is handled in requestPermissionsAsync
243
+ */
244
+ async setNotificationChannelAsync(_channelId, _options) {
245
+ // No-op - handled in requestPermissionsAsync
246
+ },
247
+ // Android importance constants for compatibility
248
+ AndroidImportance: {
249
+ MAX: 5,
250
+ HIGH: 4,
251
+ DEFAULT: 3,
252
+ LOW: 2,
253
+ MIN: 1,
254
+ },
255
+ };
@@ -14,6 +14,10 @@ export declare function showRampkitOverlay(opts: {
14
14
  onClose?: () => void;
15
15
  onOnboardingFinished?: (payload?: any) => void;
16
16
  onShowPaywall?: (payload?: any) => void;
17
+ onScreenChange?: (screenIndex: number, screenId: string) => void;
18
+ onOnboardingAbandoned?: (reason: string, lastScreenIndex: number, lastScreenId: string) => void;
19
+ onNotificationPermissionRequested?: () => void;
20
+ onNotificationPermissionResult?: (granted: boolean) => void;
17
21
  }): void;
18
22
  export declare function hideRampkitOverlay(): void;
19
23
  export declare function closeRampkitOverlay(): void;
@@ -33,5 +37,9 @@ declare function Overlay(props: {
33
37
  onOnboardingFinished?: (payload?: any) => void;
34
38
  onShowPaywall?: (payload?: any) => void;
35
39
  onRegisterClose?: (handler: (() => void) | null) => void;
40
+ onScreenChange?: (screenIndex: number, screenId: string) => void;
41
+ onOnboardingAbandoned?: (reason: string, lastScreenIndex: number, lastScreenId: string) => void;
42
+ onNotificationPermissionRequested?: () => void;
43
+ onNotificationPermissionResult?: (granted: boolean) => void;
36
44
  }): any;
37
45
  export default Overlay;
@@ -47,9 +47,7 @@ const react_native_1 = require("react-native");
47
47
  const react_native_root_siblings_1 = __importDefault(require("react-native-root-siblings"));
48
48
  const react_native_pager_view_1 = __importDefault(require("react-native-pager-view"));
49
49
  const react_native_webview_1 = require("react-native-webview");
50
- const Haptics = __importStar(require("expo-haptics"));
51
- const StoreReview = __importStar(require("expo-store-review"));
52
- const Notifications = __importStar(require("expo-notifications"));
50
+ const RampKitNative_1 = require("./RampKitNative");
53
51
  // Reuse your injected script from App
54
52
  exports.injectedHardening = `
55
53
  (function(){
@@ -131,7 +129,7 @@ function performRampkitHaptic(event) {
131
129
  if (!event || event.action !== "haptic") {
132
130
  // Backwards compatible default
133
131
  try {
134
- Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Medium).catch(() => { });
132
+ RampKitNative_1.Haptics.impactAsync("medium").catch(() => { });
135
133
  }
136
134
  catch (_) { }
137
135
  return;
@@ -140,46 +138,36 @@ function performRampkitHaptic(event) {
140
138
  try {
141
139
  if (hapticType === "impact") {
142
140
  const styleMap = {
143
- Light: Haptics.ImpactFeedbackStyle.Light,
144
- Medium: Haptics.ImpactFeedbackStyle.Medium,
145
- Heavy: Haptics.ImpactFeedbackStyle.Heavy,
146
- Rigid: Haptics.ImpactFeedbackStyle.Rigid,
147
- Soft: Haptics.ImpactFeedbackStyle.Soft,
141
+ Light: "light",
142
+ Medium: "medium",
143
+ Heavy: "heavy",
144
+ Rigid: "rigid",
145
+ Soft: "soft",
148
146
  };
149
- const impactStyle = event.impactStyle &&
150
- styleMap[event.impactStyle]
151
- ? event.impactStyle
152
- : "Medium";
153
- const style = (impactStyle && styleMap[impactStyle]) ||
154
- Haptics.ImpactFeedbackStyle.Medium;
155
- Haptics.impactAsync(style).catch(() => { });
147
+ const impactStyle = styleMap[event.impactStyle] || "medium";
148
+ RampKitNative_1.Haptics.impactAsync(impactStyle).catch(() => { });
156
149
  return;
157
150
  }
158
151
  if (hapticType === "notification") {
159
152
  const notificationMap = {
160
- Success: Haptics.NotificationFeedbackType.Success,
161
- Warning: Haptics.NotificationFeedbackType.Warning,
162
- Error: Haptics.NotificationFeedbackType.Error,
153
+ Success: "success",
154
+ Warning: "warning",
155
+ Error: "error",
163
156
  };
164
- const notificationType = event.notificationType &&
165
- notificationMap[event.notificationType]
166
- ? event.notificationType
167
- : "Success";
168
- const style = (notificationType && notificationMap[notificationType]) ||
169
- Haptics.NotificationFeedbackType.Success;
170
- Haptics.notificationAsync(style).catch(() => { });
157
+ const notificationType = notificationMap[event.notificationType] || "success";
158
+ RampKitNative_1.Haptics.notificationAsync(notificationType).catch(() => { });
171
159
  return;
172
160
  }
173
161
  if (hapticType === "selection") {
174
- Haptics.selectionAsync().catch(() => { });
162
+ RampKitNative_1.Haptics.selectionAsync().catch(() => { });
175
163
  return;
176
164
  }
177
165
  // Fallback for unknown hapticType
178
- Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Medium).catch(() => { });
166
+ RampKitNative_1.Haptics.impactAsync("medium").catch(() => { });
179
167
  }
180
168
  catch (_) {
181
169
  try {
182
- Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Medium).catch(() => { });
170
+ RampKitNative_1.Haptics.impactAsync("medium").catch(() => { });
183
171
  }
184
172
  catch (__) { }
185
173
  }
@@ -200,7 +188,7 @@ function showRampkitOverlay(opts) {
200
188
  (_a = opts.onClose) === null || _a === void 0 ? void 0 : _a.call(opts);
201
189
  }, onOnboardingFinished: opts.onOnboardingFinished, onShowPaywall: opts.onShowPaywall, onRegisterClose: (handler) => {
202
190
  activeCloseHandler = handler;
203
- } })));
191
+ }, onScreenChange: opts.onScreenChange, onOnboardingAbandoned: opts.onOnboardingAbandoned, onNotificationPermissionRequested: opts.onNotificationPermissionRequested, onNotificationPermissionResult: opts.onNotificationPermissionResult })));
204
192
  // Once shown, we can safely discard the preloader sibling if present
205
193
  if (preloadSibling) {
206
194
  preloadSibling.destroy();
@@ -306,9 +294,11 @@ function Overlay(props) {
306
294
  const [visible, setVisible] = (0, react_1.useState)(false);
307
295
  const [isTransitioning, setIsTransitioning] = (0, react_1.useState)(false);
308
296
  const [isClosing, setIsClosing] = (0, react_1.useState)(false);
297
+ const [onboardingCompleted, setOnboardingCompleted] = (0, react_1.useState)(false);
309
298
  const overlayOpacity = (0, react_1.useRef)(new react_native_1.Animated.Value(0)).current;
310
299
  const fadeOpacity = (0, react_1.useRef)(new react_native_1.Animated.Value(0)).current;
311
300
  const allLoaded = loadedCount >= props.screens.length;
301
+ const hasTrackedInitialScreen = (0, react_1.useRef)(false);
312
302
  // shared vars across all webviews
313
303
  const varsRef = (0, react_1.useRef)({});
314
304
  // hold refs for injection
@@ -326,10 +316,15 @@ function Overlay(props) {
326
316
  }).start();
327
317
  }
328
318
  }, [visible, isClosing, overlayOpacity]);
329
- const handleRequestClose = react_1.default.useCallback(() => {
319
+ const handleRequestClose = react_1.default.useCallback((options) => {
330
320
  if (isClosing)
331
321
  return;
332
322
  setIsClosing(true);
323
+ // Track abandonment if not completed
324
+ const isCompleted = (options === null || options === void 0 ? void 0 : options.completed) || onboardingCompleted;
325
+ if (!isCompleted && props.onOnboardingAbandoned && props.screens[index]) {
326
+ props.onOnboardingAbandoned("dismissed", index, props.screens[index].id);
327
+ }
333
328
  react_native_1.Animated.sequence([
334
329
  react_native_1.Animated.delay(150),
335
330
  react_native_1.Animated.timing(overlayOpacity, {
@@ -341,7 +336,7 @@ function Overlay(props) {
341
336
  ]).start(() => {
342
337
  props.onRequestClose();
343
338
  });
344
- }, [isClosing, overlayOpacity, props.onRequestClose]);
339
+ }, [isClosing, overlayOpacity, props.onRequestClose, onboardingCompleted, index, props.screens, props.onOnboardingAbandoned]);
345
340
  react_1.default.useEffect(() => {
346
341
  var _a;
347
342
  (_a = props.onRegisterClose) === null || _a === void 0 ? void 0 : _a.call(props, handleRequestClose);
@@ -476,73 +471,49 @@ function Overlay(props) {
476
471
  if (__DEV__)
477
472
  console.log("[Rampkit] onPageSelected", pos);
478
473
  sendVarsToWebView(pos);
474
+ // Track screen change event
475
+ if (props.onScreenChange && props.screens[pos]) {
476
+ props.onScreenChange(pos, props.screens[pos].id);
477
+ }
479
478
  };
480
479
  const handleAdvance = (i, animation = "fade") => {
481
480
  const last = props.screens.length - 1;
482
481
  if (i < last) {
483
482
  navigateToIndex(i + 1, animation);
484
- Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light).catch(() => { });
483
+ RampKitNative_1.Haptics.impactAsync("light").catch(() => { });
485
484
  }
486
485
  else {
487
- // finish
488
- Haptics.notificationAsync(Haptics.NotificationFeedbackType.Success).catch(() => { });
489
- handleRequestClose();
486
+ // finish - mark as completed before closing
487
+ setOnboardingCompleted(true);
488
+ RampKitNative_1.Haptics.notificationAsync("success").catch(() => { });
489
+ handleRequestClose({ completed: true });
490
490
  }
491
491
  };
492
492
  async function handleNotificationPermissionRequest(payload) {
493
+ var _a, _b;
494
+ // Track that notification permission was requested
495
+ try {
496
+ (_a = props.onNotificationPermissionRequested) === null || _a === void 0 ? void 0 : _a.call(props);
497
+ }
498
+ catch (_) { }
493
499
  const iosDefaults = { allowAlert: true, allowBadge: true, allowSound: true };
494
500
  const androidDefaults = {
495
501
  channelId: "default",
496
502
  name: "Default Channel",
497
503
  importance: "MAX",
498
504
  };
499
- const behaviorDefaults = { shouldShowBanner: true, shouldPlaySound: false };
500
505
  const iosReq = { ...((payload === null || payload === void 0 ? void 0 : payload.ios) || iosDefaults) };
501
506
  const androidCfg = { ...((payload === null || payload === void 0 ? void 0 : payload.android) || androidDefaults) };
502
- const behavior = { ...((payload === null || payload === void 0 ? void 0 : payload.behavior) || behaviorDefaults) };
503
- try {
504
- // Set foreground behavior
505
- Notifications.setNotificationHandler({
506
- handleNotification: async () => ({
507
- shouldShowAlert: !!behavior.shouldShowBanner,
508
- shouldPlaySound: !!behavior.shouldPlaySound,
509
- shouldSetBadge: false,
510
- }),
511
- });
512
- }
513
- catch (_) { }
514
- try {
515
- // Minimal Android 13+ permission + channel config
516
- if (react_native_1.Platform.OS === "android") {
517
- const importanceMap = {
518
- MAX: Notifications.AndroidImportance.MAX,
519
- HIGH: Notifications.AndroidImportance.HIGH,
520
- DEFAULT: Notifications.AndroidImportance.DEFAULT,
521
- LOW: Notifications.AndroidImportance.LOW,
522
- MIN: Notifications.AndroidImportance.MIN,
523
- };
524
- const mappedImportance = importanceMap[String(androidCfg.importance || "MAX").toUpperCase()] ||
525
- Notifications.AndroidImportance.MAX;
526
- if (androidCfg.channelId && androidCfg.name) {
527
- try {
528
- await Notifications.setNotificationChannelAsync(androidCfg.channelId, {
529
- name: androidCfg.name,
530
- importance: mappedImportance,
531
- });
532
- }
533
- catch (_) { }
534
- }
535
- }
536
- }
537
- catch (_) { }
538
507
  let result = null;
539
508
  try {
540
- if (react_native_1.Platform.OS === "ios") {
541
- result = await Notifications.requestPermissionsAsync({ ios: iosReq });
542
- }
543
- else {
544
- result = await Notifications.requestPermissionsAsync();
545
- }
509
+ result = await RampKitNative_1.Notifications.requestPermissionsAsync({
510
+ ios: iosReq,
511
+ android: {
512
+ channelId: androidCfg.channelId,
513
+ name: androidCfg.name,
514
+ importance: (androidCfg.importance || "MAX"),
515
+ },
516
+ });
546
517
  }
547
518
  catch (e) {
548
519
  result = {
@@ -556,6 +527,11 @@ function Overlay(props) {
556
527
  console.log("[Rampkit] Notification permission status:", result);
557
528
  }
558
529
  catch (_) { }
530
+ // Track notification permission result
531
+ try {
532
+ (_b = props.onNotificationPermissionResult) === null || _b === void 0 ? void 0 : _b.call(props, !!(result === null || result === void 0 ? void 0 : result.granted));
533
+ }
534
+ catch (_) { }
559
535
  // Save to shared vars and broadcast to all pages
560
536
  try {
561
537
  varsRef.current = {
@@ -564,9 +540,7 @@ function Overlay(props) {
564
540
  granted: !!(result === null || result === void 0 ? void 0 : result.granted),
565
541
  status: (result === null || result === void 0 ? void 0 : result.status) || "undetermined",
566
542
  canAskAgain: !!(result === null || result === void 0 ? void 0 : result.canAskAgain),
567
- expires: (result === null || result === void 0 ? void 0 : result.expires) || "never",
568
543
  ios: result === null || result === void 0 ? void 0 : result.ios,
569
- android: result === null || result === void 0 ? void 0 : result.android,
570
544
  },
571
545
  };
572
546
  broadcastVars();
@@ -579,8 +553,14 @@ function Overlay(props) {
579
553
  visible && { opacity: overlayOpacity },
580
554
  ], pointerEvents: visible && !isClosing ? "auto" : "none", children: [(0, jsx_runtime_1.jsx)(react_native_pager_view_1.default, { ref: pagerRef, style: react_native_1.StyleSheet.absoluteFill, scrollEnabled: false, initialPage: 0, onPageSelected: onPageSelected, offscreenPageLimit: props.screens.length, overScrollMode: "never", children: docs.map((doc, i) => ((0, jsx_runtime_1.jsx)(react_native_1.View, { style: styles.page, renderToHardwareTextureAndroid: true, children: (0, jsx_runtime_1.jsx)(react_native_webview_1.WebView, { ref: (r) => (webviewsRef.current[i] = r), style: styles.webview, originWhitelist: ["*"], source: { html: doc }, injectedJavaScriptBeforeContentLoaded: exports.injectedHardening, injectedJavaScript: exports.injectedNoSelect, automaticallyAdjustContentInsets: false, contentInsetAdjustmentBehavior: "never", bounces: false, scrollEnabled: false, overScrollMode: "never", scalesPageToFit: false, showsHorizontalScrollIndicator: false, dataDetectorTypes: "none", allowsLinkPreview: false, allowsInlineMediaPlayback: true, mediaPlaybackRequiresUserAction: false, cacheEnabled: true, javaScriptEnabled: true, domStorageEnabled: true, hideKeyboardAccessoryView: true, onLoadEnd: () => {
581
555
  setLoadedCount((c) => c + 1);
582
- if (i === 0)
556
+ if (i === 0) {
583
557
  setFirstPageLoaded(true);
558
+ // Track initial screen view
559
+ if (!hasTrackedInitialScreen.current && props.onScreenChange && props.screens[0]) {
560
+ hasTrackedInitialScreen.current = true;
561
+ props.onScreenChange(0, props.screens[0].id);
562
+ }
563
+ }
584
564
  // Initialize this page with current vars
585
565
  if (__DEV__)
586
566
  console.log("[Rampkit] onLoadEnd init send vars", i);
@@ -637,17 +617,9 @@ function Overlay(props) {
637
617
  (data === null || data === void 0 ? void 0 : data.type) === "rampkit:review") {
638
618
  (async () => {
639
619
  try {
640
- const available = await StoreReview.isAvailableAsync();
641
- if (available && (await StoreReview.hasAction())) {
642
- await StoreReview.requestReview();
643
- return;
644
- }
645
- const url = StoreReview.storeUrl();
646
- if (url) {
647
- const writeUrl = react_native_1.Platform.OS === "ios"
648
- ? `${url}${url.includes("?") ? "&" : "?"}action=write-review`
649
- : url;
650
- await react_native_1.Linking.openURL(writeUrl);
620
+ const available = await RampKitNative_1.StoreReview.isAvailableAsync();
621
+ if (available) {
622
+ await RampKitNative_1.StoreReview.requestReview();
651
623
  }
652
624
  }
653
625
  catch (_) { }
@@ -665,11 +637,12 @@ function Overlay(props) {
665
637
  }
666
638
  // 5) Onboarding finished event from page
667
639
  if ((data === null || data === void 0 ? void 0 : data.type) === "rampkit:onboarding-finished") {
640
+ setOnboardingCompleted(true);
668
641
  try {
669
642
  (_a = props.onOnboardingFinished) === null || _a === void 0 ? void 0 : _a.call(props, data === null || data === void 0 ? void 0 : data.payload);
670
643
  }
671
644
  catch (_) { }
672
- handleRequestClose();
645
+ handleRequestClose({ completed: true });
673
646
  return;
674
647
  }
675
648
  // 6) Request to show paywall
@@ -738,17 +711,9 @@ function Overlay(props) {
738
711
  if (raw === "rampkit:request-review" || raw === "rampkit:review") {
739
712
  (async () => {
740
713
  try {
741
- const available = await StoreReview.isAvailableAsync();
742
- if (available && (await StoreReview.hasAction())) {
743
- await StoreReview.requestReview();
744
- return;
745
- }
746
- const url = StoreReview.storeUrl();
747
- if (url) {
748
- const writeUrl = react_native_1.Platform.OS === "ios"
749
- ? `${url}${url.includes("?") ? "&" : "?"}action=write-review`
750
- : url;
751
- await react_native_1.Linking.openURL(writeUrl);
714
+ const available = await RampKitNative_1.StoreReview.isAvailableAsync();
715
+ if (available) {
716
+ await RampKitNative_1.StoreReview.requestReview();
752
717
  }
753
718
  }
754
719
  catch (_) { }
@@ -760,11 +725,12 @@ function Overlay(props) {
760
725
  return;
761
726
  }
762
727
  if (raw === "rampkit:onboarding-finished") {
728
+ setOnboardingCompleted(true);
763
729
  try {
764
730
  (_c = props.onOnboardingFinished) === null || _c === void 0 ? void 0 : _c.call(props, undefined);
765
731
  }
766
732
  catch (_) { }
767
- handleRequestClose();
733
+ handleRequestClose({ completed: true });
768
734
  return;
769
735
  }
770
736
  if (raw === "rampkit:show-paywall") {
@@ -0,0 +1,18 @@
1
+ /**
2
+ * RampKit SDK Constants
3
+ */
4
+ export declare const SDK_VERSION = "1.0.0";
5
+ export declare const ENDPOINTS: {
6
+ readonly BASE_URL: "https://uustlzuvjmochxkxatfx.supabase.co/functions/v1";
7
+ readonly APP_USERS: "/app-users";
8
+ readonly APP_USER_EVENTS: "/app-user-events";
9
+ };
10
+ export declare const MANIFEST_BASE_URL = "https://dh1psiwzzzkgr.cloudfront.net";
11
+ export declare const STORAGE_KEYS: {
12
+ readonly APP_USER_ID: "rk_user_id";
13
+ readonly INSTALL_DATE: "rk_install_date";
14
+ readonly LAUNCH_COUNT: "rk_launch_count";
15
+ readonly LAST_LAUNCH: "rk_last_launch";
16
+ };
17
+ export declare const CAPABILITIES: readonly ["onboarding", "paywall_event_receiver", "haptic_feedback", "push_notifications"];
18
+ export declare const SUPABASE_ANON_KEY = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InV1c3RsenV2am1vY2h4a3hhdGZ4Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3MzU1NjQ0NjYsImV4cCI6MjA1MTE0MDQ2Nn0.5cNrph5LHmssNo39UKpULkC9n4OD5n6gsnTEQV-gwQk";
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ /**
3
+ * RampKit SDK Constants
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.SUPABASE_ANON_KEY = exports.CAPABILITIES = exports.STORAGE_KEYS = exports.MANIFEST_BASE_URL = exports.ENDPOINTS = exports.SDK_VERSION = void 0;
7
+ exports.SDK_VERSION = "1.0.0";
8
+ exports.ENDPOINTS = {
9
+ BASE_URL: "https://uustlzuvjmochxkxatfx.supabase.co/functions/v1",
10
+ APP_USERS: "/app-users",
11
+ APP_USER_EVENTS: "/app-user-events",
12
+ };
13
+ exports.MANIFEST_BASE_URL = "https://dh1psiwzzzkgr.cloudfront.net";
14
+ exports.STORAGE_KEYS = {
15
+ // SecureStore (sensitive)
16
+ APP_USER_ID: "rk_user_id",
17
+ // AsyncStorage (persisted)
18
+ INSTALL_DATE: "rk_install_date",
19
+ LAUNCH_COUNT: "rk_launch_count",
20
+ LAST_LAUNCH: "rk_last_launch",
21
+ };
22
+ exports.CAPABILITIES = [
23
+ "onboarding",
24
+ "paywall_event_receiver",
25
+ "haptic_feedback",
26
+ "push_notifications",
27
+ ];
28
+ // Supabase anon key for API calls
29
+ exports.SUPABASE_ANON_KEY = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InV1c3RsenV2am1vY2h4a3hhdGZ4Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3MzU1NjQ0NjYsImV4cCI6MjA1MTE0MDQ2Nn0.5cNrph5LHmssNo39UKpULkC9n4OD5n6gsnTEQV-gwQk";
package/build/index.d.ts CHANGED
@@ -1,3 +1,15 @@
1
+ /**
2
+ * RampKit Expo SDK
3
+ * Main entry point for the SDK
4
+ */
1
5
  import { RampKitCore } from "./RampKit";
2
6
  export declare const RampKit: RampKitCore;
3
7
  export { getRampKitUserId } from "./userId";
8
+ export { eventManager } from "./EventManager";
9
+ export { collectDeviceInfo, getSessionDurationSeconds, getSessionStartTime, } from "./DeviceInfoCollector";
10
+ export { default as RampKitNative } from "./RampKitNative";
11
+ export type { NativeDeviceInfo, NativeLaunchData } from "./RampKitNative";
12
+ export { Haptics, StoreReview, Notifications } from "./RampKitNative";
13
+ export type { ImpactStyle, NotificationType, NotificationOptions, NotificationPermissionResult } from "./RampKitNative";
14
+ export type { DeviceInfo, RampKitEvent, EventDevice, EventContext, RampKitConfig, RampKitEventName, AppSessionStartedProperties, AppSessionEndedProperties, AppBackgroundedProperties, AppForegroundedProperties, OnboardingStartedProperties, OnboardingScreenViewedProperties, OnboardingQuestionAnsweredProperties, OnboardingCompletedProperties, OnboardingAbandonedProperties, ScreenViewProperties, CtaTapProperties, NotificationsPromptShownProperties, NotificationsResponseProperties, PaywallShownProperties, PaywallPrimaryActionTapProperties, PaywallClosedProperties, PurchaseStartedProperties, PurchaseCompletedProperties, PurchaseFailedProperties, } from "./types";
15
+ export { SDK_VERSION, CAPABILITIES } from "./constants";