rampkit-expo-dev 0.0.61 → 0.0.63
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/build/EventManager.d.ts +33 -44
- package/build/EventManager.js +92 -76
- package/build/RampKit.d.ts +0 -14
- package/build/RampKit.js +17 -52
- package/build/RampkitOverlay.d.ts +2 -0
- package/build/RampkitOverlay.js +17 -7
- package/build/constants.d.ts +1 -0
- package/build/constants.js +2 -0
- package/build/index.d.ts +1 -1
- package/build/types.d.ts +54 -49
- package/package.json +1 -1
package/build/EventManager.d.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* RampKit Event Manager
|
|
3
3
|
* Handles event tracking for the /app-user-events endpoint
|
|
4
4
|
*/
|
|
5
|
-
import { DeviceInfo, EventContext, RampKitEventName } from "./types";
|
|
5
|
+
import { DeviceInfo, EventContext, RampKitEventName, PurchaseCompletedProperties, PurchaseStartedProperties, PurchaseRestoredProperties } from "./types";
|
|
6
6
|
declare class EventManager {
|
|
7
7
|
private static _instance;
|
|
8
8
|
private appId;
|
|
@@ -67,50 +67,47 @@ declare class EventManager {
|
|
|
67
67
|
* Track app session started
|
|
68
68
|
*/
|
|
69
69
|
trackAppSessionStarted(isFirstLaunch: boolean, launchCount: number): void;
|
|
70
|
-
/**
|
|
71
|
-
* Track app backgrounded
|
|
72
|
-
*/
|
|
73
|
-
trackAppBackgrounded(sessionDurationSeconds: number): void;
|
|
74
|
-
/**
|
|
75
|
-
* Track app foregrounded
|
|
76
|
-
*/
|
|
77
|
-
trackAppForegrounded(): void;
|
|
78
|
-
/**
|
|
79
|
-
* Track screen view
|
|
80
|
-
*/
|
|
81
|
-
trackScreenView(screenName: string, referrer?: string): void;
|
|
82
|
-
/**
|
|
83
|
-
* Track CTA tap
|
|
84
|
-
*/
|
|
85
|
-
trackCtaTap(buttonId: string, buttonText?: string): void;
|
|
86
70
|
/**
|
|
87
71
|
* Track onboarding started
|
|
88
72
|
*/
|
|
89
73
|
trackOnboardingStarted(onboardingId: string, totalSteps?: number): void;
|
|
90
74
|
/**
|
|
91
|
-
* Track onboarding
|
|
75
|
+
* Track onboarding abandoned
|
|
92
76
|
*/
|
|
93
|
-
|
|
77
|
+
trackOnboardingAbandoned(reason: string, lastScreenName?: string, onboardingId?: string): void;
|
|
94
78
|
/**
|
|
95
|
-
*
|
|
79
|
+
* Check if onboarding has already been marked as completed
|
|
96
80
|
*/
|
|
97
|
-
|
|
81
|
+
hasOnboardingBeenCompleted(): Promise<boolean>;
|
|
98
82
|
/**
|
|
99
|
-
*
|
|
83
|
+
* Mark onboarding as completed in persistent storage
|
|
100
84
|
*/
|
|
101
|
-
|
|
85
|
+
private markOnboardingAsCompleted;
|
|
102
86
|
/**
|
|
103
|
-
*
|
|
87
|
+
* Reset onboarding completion status (useful for testing or user reset)
|
|
104
88
|
*/
|
|
105
|
-
|
|
89
|
+
resetOnboardingCompletionStatus(): Promise<void>;
|
|
106
90
|
/**
|
|
107
|
-
* Track
|
|
91
|
+
* Track onboarding completed event - fires ONCE per user
|
|
92
|
+
* Called when:
|
|
93
|
+
* 1. User completes the onboarding flow (onboarding-finished action)
|
|
94
|
+
* 2. User closes the onboarding (close action)
|
|
95
|
+
* 3. A paywall is shown (show-paywall action)
|
|
96
|
+
*
|
|
97
|
+
* @param trigger - The reason for completion ("finished", "closed", "paywall_shown")
|
|
98
|
+
* @param completedSteps - Number of steps the user completed
|
|
99
|
+
* @param totalSteps - Total number of steps in the onboarding
|
|
100
|
+
* @param onboardingId - The onboarding ID
|
|
108
101
|
*/
|
|
109
|
-
|
|
102
|
+
trackOnboardingCompletedOnce(trigger: string, completedSteps?: number, totalSteps?: number, onboardingId?: string): Promise<void>;
|
|
110
103
|
/**
|
|
111
104
|
* Track notification response
|
|
112
105
|
*/
|
|
113
106
|
trackNotificationsResponse(status: "granted" | "denied" | "provisional"): void;
|
|
107
|
+
/**
|
|
108
|
+
* Track option selected (interaction event)
|
|
109
|
+
*/
|
|
110
|
+
trackOptionSelected(optionId: string, optionValue: any, questionId?: string): void;
|
|
114
111
|
/**
|
|
115
112
|
* Track paywall shown
|
|
116
113
|
*/
|
|
@@ -119,33 +116,25 @@ declare class EventManager {
|
|
|
119
116
|
price?: number;
|
|
120
117
|
currency?: string;
|
|
121
118
|
}>): void;
|
|
122
|
-
/**
|
|
123
|
-
* Track paywall primary action tap
|
|
124
|
-
*/
|
|
125
|
-
trackPaywallPrimaryActionTap(paywallId: string, productId?: string): void;
|
|
126
|
-
/**
|
|
127
|
-
* Track paywall closed
|
|
128
|
-
*/
|
|
129
|
-
trackPaywallClosed(paywallId: string, reason: "dismissed" | "purchased" | "backgrounded"): void;
|
|
130
119
|
/**
|
|
131
120
|
* Track purchase started
|
|
121
|
+
* Call this when user initiates a purchase from a paywall
|
|
132
122
|
*/
|
|
133
|
-
trackPurchaseStarted(
|
|
123
|
+
trackPurchaseStarted(properties: PurchaseStartedProperties): void;
|
|
134
124
|
/**
|
|
135
125
|
* Track purchase completed
|
|
126
|
+
* CRITICAL: originalTransactionId is required for attribution
|
|
127
|
+
* Context (paywallId, screenName, flowId) is automatically included
|
|
136
128
|
*/
|
|
137
|
-
trackPurchaseCompleted(properties:
|
|
138
|
-
productId: string;
|
|
139
|
-
amount: number;
|
|
140
|
-
currency: string;
|
|
141
|
-
transactionId: string;
|
|
142
|
-
originalTransactionId?: string;
|
|
143
|
-
purchaseDate?: string;
|
|
144
|
-
}): void;
|
|
129
|
+
trackPurchaseCompleted(properties: PurchaseCompletedProperties): void;
|
|
145
130
|
/**
|
|
146
131
|
* Track purchase failed
|
|
147
132
|
*/
|
|
148
133
|
trackPurchaseFailed(productId: string, errorCode: string, errorMessage: string): void;
|
|
134
|
+
/**
|
|
135
|
+
* Track purchase restored
|
|
136
|
+
*/
|
|
137
|
+
trackPurchaseRestored(properties: PurchaseRestoredProperties): void;
|
|
149
138
|
/**
|
|
150
139
|
* Reset the event manager (e.g., on logout)
|
|
151
140
|
*/
|
package/build/EventManager.js
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
7
|
exports.EventManager = exports.eventManager = void 0;
|
|
8
8
|
const constants_1 = require("./constants");
|
|
9
|
+
const RampKitNative_1 = require("./RampKitNative");
|
|
9
10
|
/**
|
|
10
11
|
* Generate a UUID v4 using Math.random
|
|
11
12
|
* This is sufficient for event IDs - no crypto dependency needed
|
|
@@ -202,31 +203,6 @@ class EventManager {
|
|
|
202
203
|
trackAppSessionStarted(isFirstLaunch, launchCount) {
|
|
203
204
|
this.track("app_session_started", { isFirstLaunch, launchCount });
|
|
204
205
|
}
|
|
205
|
-
/**
|
|
206
|
-
* Track app backgrounded
|
|
207
|
-
*/
|
|
208
|
-
trackAppBackgrounded(sessionDurationSeconds) {
|
|
209
|
-
this.track("app_backgrounded", { sessionDurationSeconds });
|
|
210
|
-
}
|
|
211
|
-
/**
|
|
212
|
-
* Track app foregrounded
|
|
213
|
-
*/
|
|
214
|
-
trackAppForegrounded() {
|
|
215
|
-
this.track("app_foregrounded", {});
|
|
216
|
-
}
|
|
217
|
-
/**
|
|
218
|
-
* Track screen view
|
|
219
|
-
*/
|
|
220
|
-
trackScreenView(screenName, referrer) {
|
|
221
|
-
this.setCurrentScreen(screenName);
|
|
222
|
-
this.track("screen_view", { screenName, referrer });
|
|
223
|
-
}
|
|
224
|
-
/**
|
|
225
|
-
* Track CTA tap
|
|
226
|
-
*/
|
|
227
|
-
trackCtaTap(buttonId, buttonText) {
|
|
228
|
-
this.track("cta_tap", { buttonId, buttonText });
|
|
229
|
-
}
|
|
230
206
|
/**
|
|
231
207
|
* Track onboarding started
|
|
232
208
|
*/
|
|
@@ -235,59 +211,88 @@ class EventManager {
|
|
|
235
211
|
this.track("onboarding_started", { onboardingId, totalSteps });
|
|
236
212
|
}
|
|
237
213
|
/**
|
|
238
|
-
* Track onboarding
|
|
214
|
+
* Track onboarding abandoned
|
|
239
215
|
*/
|
|
240
|
-
|
|
241
|
-
this.
|
|
242
|
-
this.track("
|
|
216
|
+
trackOnboardingAbandoned(reason, lastScreenName, onboardingId) {
|
|
217
|
+
const timeSpentSeconds = this.getOnboardingDurationSeconds();
|
|
218
|
+
this.track("onboarding_abandoned", {
|
|
243
219
|
onboardingId: onboardingId || this.currentOnboardingId,
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
220
|
+
reason,
|
|
221
|
+
lastScreenName,
|
|
222
|
+
timeSpentSeconds,
|
|
247
223
|
});
|
|
224
|
+
this.endOnboardingTracking();
|
|
248
225
|
}
|
|
226
|
+
// ============================================================================
|
|
227
|
+
// Onboarding Completion (Once Per User)
|
|
228
|
+
// ============================================================================
|
|
249
229
|
/**
|
|
250
|
-
*
|
|
230
|
+
* Check if onboarding has already been marked as completed
|
|
251
231
|
*/
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
232
|
+
async hasOnboardingBeenCompleted() {
|
|
233
|
+
try {
|
|
234
|
+
const value = await (0, RampKitNative_1.getStoredValue)(constants_1.STORAGE_KEYS.ONBOARDING_COMPLETED);
|
|
235
|
+
return value === "true";
|
|
236
|
+
}
|
|
237
|
+
catch (_a) {
|
|
238
|
+
return false;
|
|
239
|
+
}
|
|
259
240
|
}
|
|
260
241
|
/**
|
|
261
|
-
*
|
|
242
|
+
* Mark onboarding as completed in persistent storage
|
|
262
243
|
*/
|
|
263
|
-
|
|
244
|
+
async markOnboardingAsCompleted() {
|
|
245
|
+
try {
|
|
246
|
+
await (0, RampKitNative_1.setStoredValue)(constants_1.STORAGE_KEYS.ONBOARDING_COMPLETED, "true");
|
|
247
|
+
console.log("[RampKit] EventManager: onboarding marked as completed (persisted)");
|
|
248
|
+
}
|
|
249
|
+
catch (error) {
|
|
250
|
+
console.warn("[RampKit] EventManager: failed to persist onboarding completion:", error);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Reset onboarding completion status (useful for testing or user reset)
|
|
255
|
+
*/
|
|
256
|
+
async resetOnboardingCompletionStatus() {
|
|
257
|
+
try {
|
|
258
|
+
await (0, RampKitNative_1.setStoredValue)(constants_1.STORAGE_KEYS.ONBOARDING_COMPLETED, "");
|
|
259
|
+
console.log("[RampKit] EventManager: onboarding completion status reset");
|
|
260
|
+
}
|
|
261
|
+
catch (error) {
|
|
262
|
+
console.warn("[RampKit] EventManager: failed to reset onboarding completion:", error);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Track onboarding completed event - fires ONCE per user
|
|
267
|
+
* Called when:
|
|
268
|
+
* 1. User completes the onboarding flow (onboarding-finished action)
|
|
269
|
+
* 2. User closes the onboarding (close action)
|
|
270
|
+
* 3. A paywall is shown (show-paywall action)
|
|
271
|
+
*
|
|
272
|
+
* @param trigger - The reason for completion ("finished", "closed", "paywall_shown")
|
|
273
|
+
* @param completedSteps - Number of steps the user completed
|
|
274
|
+
* @param totalSteps - Total number of steps in the onboarding
|
|
275
|
+
* @param onboardingId - The onboarding ID
|
|
276
|
+
*/
|
|
277
|
+
async trackOnboardingCompletedOnce(trigger, completedSteps, totalSteps, onboardingId) {
|
|
278
|
+
// Check if already completed - skip if so
|
|
279
|
+
const alreadyCompleted = await this.hasOnboardingBeenCompleted();
|
|
280
|
+
if (alreadyCompleted) {
|
|
281
|
+
console.log(`[RampKit] EventManager: onboarding_completed already sent, skipping (trigger: ${trigger})`);
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
284
|
+
// Mark as completed BEFORE sending to prevent race conditions
|
|
285
|
+
await this.markOnboardingAsCompleted();
|
|
264
286
|
const timeToCompleteSeconds = this.getOnboardingDurationSeconds();
|
|
265
287
|
this.track("onboarding_completed", {
|
|
266
288
|
onboardingId: onboardingId || this.currentOnboardingId,
|
|
267
289
|
timeToCompleteSeconds,
|
|
268
290
|
completedSteps,
|
|
269
291
|
totalSteps,
|
|
292
|
+
trigger,
|
|
270
293
|
});
|
|
271
294
|
this.endOnboardingTracking();
|
|
272
|
-
|
|
273
|
-
/**
|
|
274
|
-
* Track onboarding abandoned
|
|
275
|
-
*/
|
|
276
|
-
trackOnboardingAbandoned(reason, lastScreenName, onboardingId) {
|
|
277
|
-
const timeSpentSeconds = this.getOnboardingDurationSeconds();
|
|
278
|
-
this.track("onboarding_abandoned", {
|
|
279
|
-
onboardingId: onboardingId || this.currentOnboardingId,
|
|
280
|
-
reason,
|
|
281
|
-
lastScreenName,
|
|
282
|
-
timeSpentSeconds,
|
|
283
|
-
});
|
|
284
|
-
this.endOnboardingTracking();
|
|
285
|
-
}
|
|
286
|
-
/**
|
|
287
|
-
* Track notification prompt shown
|
|
288
|
-
*/
|
|
289
|
-
trackNotificationsPromptShown() {
|
|
290
|
-
this.track("notifications_prompt_shown", {});
|
|
295
|
+
console.log(`[RampKit] EventManager: 📊 onboarding_completed sent (trigger: ${trigger})`);
|
|
291
296
|
}
|
|
292
297
|
/**
|
|
293
298
|
* Track notification response
|
|
@@ -295,6 +300,12 @@ class EventManager {
|
|
|
295
300
|
trackNotificationsResponse(status) {
|
|
296
301
|
this.track("notifications_response", { status });
|
|
297
302
|
}
|
|
303
|
+
/**
|
|
304
|
+
* Track option selected (interaction event)
|
|
305
|
+
*/
|
|
306
|
+
trackOptionSelected(optionId, optionValue, questionId) {
|
|
307
|
+
this.track("option_selected", { optionId, optionValue, questionId });
|
|
308
|
+
}
|
|
298
309
|
/**
|
|
299
310
|
* Track paywall shown
|
|
300
311
|
*/
|
|
@@ -302,37 +313,40 @@ class EventManager {
|
|
|
302
313
|
this.setCurrentPaywall(paywallId, placement);
|
|
303
314
|
this.track("paywall_shown", { paywallId, placement, products }, { paywallId, placement });
|
|
304
315
|
}
|
|
305
|
-
/**
|
|
306
|
-
* Track paywall primary action tap
|
|
307
|
-
*/
|
|
308
|
-
trackPaywallPrimaryActionTap(paywallId, productId) {
|
|
309
|
-
this.track("paywall_primary_action_tap", { paywallId, productId }, { paywallId });
|
|
310
|
-
}
|
|
311
|
-
/**
|
|
312
|
-
* Track paywall closed
|
|
313
|
-
*/
|
|
314
|
-
trackPaywallClosed(paywallId, reason) {
|
|
315
|
-
this.track("paywall_closed", { paywallId, reason }, { paywallId });
|
|
316
|
-
this.setCurrentPaywall(null);
|
|
317
|
-
}
|
|
318
316
|
/**
|
|
319
317
|
* Track purchase started
|
|
318
|
+
* Call this when user initiates a purchase from a paywall
|
|
320
319
|
*/
|
|
321
|
-
trackPurchaseStarted(
|
|
322
|
-
|
|
320
|
+
trackPurchaseStarted(properties) {
|
|
321
|
+
// Context (paywallId, placement) is automatically included from current state
|
|
322
|
+
// which was set when trackPaywallShown was called
|
|
323
|
+
console.log(`[RampKit] EventManager: 🛒 purchase_started`, `\n productId: ${properties.productId}`, properties.amount ? `\n amount: ${properties.amount} ${properties.currency || ""}` : "");
|
|
324
|
+
this.track("purchase_started", properties);
|
|
323
325
|
}
|
|
324
326
|
/**
|
|
325
327
|
* Track purchase completed
|
|
328
|
+
* CRITICAL: originalTransactionId is required for attribution
|
|
329
|
+
* Context (paywallId, screenName, flowId) is automatically included
|
|
326
330
|
*/
|
|
327
331
|
trackPurchaseCompleted(properties) {
|
|
332
|
+
// Context is automatically included from current state (paywallId, placement, etc.)
|
|
333
|
+
console.log(`[RampKit] EventManager: ✅ purchase_completed`, `\n productId: ${properties.productId}`, `\n transactionId: ${properties.transactionId}`, `\n originalTransactionId: ${properties.originalTransactionId}`, properties.isTrial ? `\n isTrial: true` : "", properties.environment ? `\n environment: ${properties.environment}` : "");
|
|
328
334
|
this.track("purchase_completed", properties);
|
|
329
335
|
}
|
|
330
336
|
/**
|
|
331
337
|
* Track purchase failed
|
|
332
338
|
*/
|
|
333
339
|
trackPurchaseFailed(productId, errorCode, errorMessage) {
|
|
340
|
+
console.log(`[RampKit] EventManager: ❌ purchase_failed`, `\n productId: ${productId}`, `\n errorCode: ${errorCode}`, `\n errorMessage: ${errorMessage}`);
|
|
334
341
|
this.track("purchase_failed", { productId, errorCode, errorMessage });
|
|
335
342
|
}
|
|
343
|
+
/**
|
|
344
|
+
* Track purchase restored
|
|
345
|
+
*/
|
|
346
|
+
trackPurchaseRestored(properties) {
|
|
347
|
+
console.log(`[RampKit] EventManager: 🔄 purchase_restored`, `\n productId: ${properties.productId}`, properties.transactionId ? `\n transactionId: ${properties.transactionId}` : "", properties.originalTransactionId ? `\n originalTransactionId: ${properties.originalTransactionId}` : "");
|
|
348
|
+
this.track("purchase_restored", properties);
|
|
349
|
+
}
|
|
336
350
|
/**
|
|
337
351
|
* Reset the event manager (e.g., on logout)
|
|
338
352
|
*/
|
|
@@ -350,6 +364,8 @@ class EventManager {
|
|
|
350
364
|
this.onboardingStartTime = null;
|
|
351
365
|
this.currentOnboardingId = null;
|
|
352
366
|
this.initialized = false;
|
|
367
|
+
// Reset onboarding completion status so it can fire again for new user
|
|
368
|
+
this.resetOnboardingCompletionStatus();
|
|
353
369
|
}
|
|
354
370
|
}
|
|
355
371
|
exports.EventManager = EventManager;
|
package/build/RampKit.d.ts
CHANGED
|
@@ -12,8 +12,6 @@ export declare class RampKitCore {
|
|
|
12
12
|
private deviceInfo;
|
|
13
13
|
private onOnboardingFinished?;
|
|
14
14
|
private onShowPaywall?;
|
|
15
|
-
private appStateSubscription;
|
|
16
|
-
private lastAppState;
|
|
17
15
|
private initialized;
|
|
18
16
|
/** Custom App User ID provided by the developer (alias for their user system) */
|
|
19
17
|
private appUserID;
|
|
@@ -47,10 +45,6 @@ export declare class RampKitCore {
|
|
|
47
45
|
* Send user/device data to the /app-users endpoint
|
|
48
46
|
*/
|
|
49
47
|
private sendUserDataToBackend;
|
|
50
|
-
/**
|
|
51
|
-
* Setup app state listener for background/foreground tracking
|
|
52
|
-
*/
|
|
53
|
-
private setupAppStateListener;
|
|
54
48
|
/**
|
|
55
49
|
* Get the onboarding data
|
|
56
50
|
*/
|
|
@@ -87,14 +81,6 @@ export declare class RampKitCore {
|
|
|
87
81
|
* Track a custom event
|
|
88
82
|
*/
|
|
89
83
|
trackEvent(eventName: string, properties?: Record<string, any>, context?: Partial<EventContext>): void;
|
|
90
|
-
/**
|
|
91
|
-
* Track a screen view
|
|
92
|
-
*/
|
|
93
|
-
trackScreenView(screenName: string, referrer?: string): void;
|
|
94
|
-
/**
|
|
95
|
-
* Track a CTA tap
|
|
96
|
-
*/
|
|
97
|
-
trackCtaTap(buttonId: string, buttonText?: string): void;
|
|
98
84
|
/**
|
|
99
85
|
* Reset the SDK state and re-initialize
|
|
100
86
|
* Call this when a user logs out or when you need to clear all cached state
|
package/build/RampKit.js
CHANGED
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
7
|
exports.RampKitCore = void 0;
|
|
8
|
-
const react_native_1 = require("react-native");
|
|
9
8
|
const RampkitOverlay_1 = require("./RampkitOverlay");
|
|
10
9
|
const userId_1 = require("./userId");
|
|
11
10
|
const DeviceInfoCollector_1 = require("./DeviceInfoCollector");
|
|
@@ -20,8 +19,6 @@ class RampKitCore {
|
|
|
20
19
|
this.userId = null;
|
|
21
20
|
this.appId = null;
|
|
22
21
|
this.deviceInfo = null;
|
|
23
|
-
this.appStateSubscription = null;
|
|
24
|
-
this.lastAppState = "active";
|
|
25
22
|
this.initialized = false;
|
|
26
23
|
/** Custom App User ID provided by the developer (alias for their user system) */
|
|
27
24
|
this.appUserID = null;
|
|
@@ -64,9 +61,7 @@ class RampKitCore {
|
|
|
64
61
|
EventManager_1.eventManager.initialize(config.appId, this.deviceInfo);
|
|
65
62
|
// Step 4: Track app session started
|
|
66
63
|
EventManager_1.eventManager.trackAppSessionStarted(this.deviceInfo.isFirstLaunch, this.deviceInfo.launchCount);
|
|
67
|
-
// Step 5:
|
|
68
|
-
this.setupAppStateListener();
|
|
69
|
-
// Step 6: Start transaction observer for automatic purchase tracking
|
|
64
|
+
// Step 5: Start transaction observer for automatic purchase tracking
|
|
70
65
|
console.log("[RampKit] Configure: Starting transaction observer...");
|
|
71
66
|
await RampKitNative_1.TransactionObserver.start(config.appId);
|
|
72
67
|
this.initialized = true;
|
|
@@ -195,26 +190,6 @@ class RampKitCore {
|
|
|
195
190
|
console.warn(`[RampKit] Configure: Network error sending user data`, `\n Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
196
191
|
}
|
|
197
192
|
}
|
|
198
|
-
/**
|
|
199
|
-
* Setup app state listener for background/foreground tracking
|
|
200
|
-
*/
|
|
201
|
-
setupAppStateListener() {
|
|
202
|
-
this.appStateSubscription = react_native_1.AppState.addEventListener("change", (nextAppState) => {
|
|
203
|
-
if (this.lastAppState === "active" &&
|
|
204
|
-
(nextAppState === "background" || nextAppState === "inactive")) {
|
|
205
|
-
// App went to background
|
|
206
|
-
const sessionDuration = (0, DeviceInfoCollector_1.getSessionDurationSeconds)();
|
|
207
|
-
EventManager_1.eventManager.trackAppBackgrounded(sessionDuration);
|
|
208
|
-
}
|
|
209
|
-
else if ((this.lastAppState === "background" ||
|
|
210
|
-
this.lastAppState === "inactive") &&
|
|
211
|
-
nextAppState === "active") {
|
|
212
|
-
// App came to foreground
|
|
213
|
-
EventManager_1.eventManager.trackAppForegrounded();
|
|
214
|
-
}
|
|
215
|
-
this.lastAppState = nextAppState;
|
|
216
|
-
});
|
|
217
|
-
}
|
|
218
193
|
/**
|
|
219
194
|
* Get the onboarding data
|
|
220
195
|
*/
|
|
@@ -314,28 +289,35 @@ class RampKitCore {
|
|
|
314
289
|
navigation,
|
|
315
290
|
onOnboardingFinished: (payload) => {
|
|
316
291
|
var _a;
|
|
317
|
-
// Track onboarding completed
|
|
318
|
-
EventManager_1.eventManager.
|
|
292
|
+
// Track onboarding completed (once per user) - trigger: finished
|
|
293
|
+
EventManager_1.eventManager.trackOnboardingCompletedOnce("finished", screens.length, screens.length, onboardingId);
|
|
319
294
|
try {
|
|
320
295
|
(_a = this.onOnboardingFinished) === null || _a === void 0 ? void 0 : _a.call(this, payload);
|
|
321
296
|
}
|
|
322
297
|
catch (_) { }
|
|
323
298
|
},
|
|
324
|
-
onShowPaywall: (
|
|
325
|
-
|
|
326
|
-
//
|
|
327
|
-
|
|
299
|
+
onShowPaywall: (payload) => {
|
|
300
|
+
// Track onboarding completed (once per user) - trigger: paywall_shown
|
|
301
|
+
EventManager_1.eventManager.trackOnboardingCompletedOnce("paywall_shown", screens.length, // We don't know exact step, use total
|
|
302
|
+
screens.length, onboardingId);
|
|
303
|
+
// Call the original callback
|
|
304
|
+
const paywallCallback = (opts === null || opts === void 0 ? void 0 : opts.onShowPaywall) || (opts === null || opts === void 0 ? void 0 : opts.showPaywall) || this.onShowPaywall;
|
|
305
|
+
try {
|
|
306
|
+
paywallCallback === null || paywallCallback === void 0 ? void 0 : paywallCallback(payload);
|
|
307
|
+
}
|
|
308
|
+
catch (_) { }
|
|
328
309
|
},
|
|
329
310
|
onOnboardingAbandoned: (reason, lastScreenIndex, lastScreenId) => {
|
|
330
311
|
// Track onboarding abandoned
|
|
331
312
|
EventManager_1.eventManager.trackOnboardingAbandoned(reason, lastScreenId, onboardingId);
|
|
332
313
|
},
|
|
333
|
-
onNotificationPermissionRequested: () => {
|
|
334
|
-
EventManager_1.eventManager.trackNotificationsPromptShown();
|
|
335
|
-
},
|
|
336
314
|
onNotificationPermissionResult: (granted) => {
|
|
337
315
|
EventManager_1.eventManager.trackNotificationsResponse(granted ? "granted" : "denied");
|
|
338
316
|
},
|
|
317
|
+
onCloseAction: (screenIndex, _screenId) => {
|
|
318
|
+
// Track onboarding completed (once per user) - trigger: closed
|
|
319
|
+
EventManager_1.eventManager.trackOnboardingCompletedOnce("closed", screenIndex + 1, screens.length, onboardingId);
|
|
320
|
+
},
|
|
339
321
|
});
|
|
340
322
|
}
|
|
341
323
|
catch (e) {
|
|
@@ -357,18 +339,6 @@ class RampKitCore {
|
|
|
357
339
|
trackEvent(eventName, properties = {}, context) {
|
|
358
340
|
EventManager_1.eventManager.track(eventName, properties, context);
|
|
359
341
|
}
|
|
360
|
-
/**
|
|
361
|
-
* Track a screen view
|
|
362
|
-
*/
|
|
363
|
-
trackScreenView(screenName, referrer) {
|
|
364
|
-
EventManager_1.eventManager.trackScreenView(screenName, referrer);
|
|
365
|
-
}
|
|
366
|
-
/**
|
|
367
|
-
* Track a CTA tap
|
|
368
|
-
*/
|
|
369
|
-
trackCtaTap(buttonId, buttonText) {
|
|
370
|
-
EventManager_1.eventManager.trackCtaTap(buttonId, buttonText);
|
|
371
|
-
}
|
|
372
342
|
// Note: Purchase and paywall events are automatically tracked by the native
|
|
373
343
|
// StoreKit 2 (iOS) and Google Play Billing (Android) transaction observers.
|
|
374
344
|
// No manual tracking is needed.
|
|
@@ -384,11 +354,6 @@ class RampKitCore {
|
|
|
384
354
|
console.log("[RampKit] Reset: Clearing SDK state...");
|
|
385
355
|
// Stop transaction observer
|
|
386
356
|
await RampKitNative_1.TransactionObserver.stop();
|
|
387
|
-
// Remove app state listener
|
|
388
|
-
if (this.appStateSubscription) {
|
|
389
|
-
this.appStateSubscription.remove();
|
|
390
|
-
this.appStateSubscription = null;
|
|
391
|
-
}
|
|
392
357
|
// Reset event manager state
|
|
393
358
|
EventManager_1.eventManager.reset();
|
|
394
359
|
// Reset session
|
|
@@ -24,6 +24,7 @@ export declare function showRampkitOverlay(opts: {
|
|
|
24
24
|
onOnboardingAbandoned?: (reason: string, lastScreenIndex: number, lastScreenId: string) => void;
|
|
25
25
|
onNotificationPermissionRequested?: () => void;
|
|
26
26
|
onNotificationPermissionResult?: (granted: boolean) => void;
|
|
27
|
+
onCloseAction?: (screenIndex: number, screenId: string) => void;
|
|
27
28
|
}): void;
|
|
28
29
|
export declare function hideRampkitOverlay(): void;
|
|
29
30
|
export declare function closeRampkitOverlay(): void;
|
|
@@ -50,5 +51,6 @@ declare function Overlay(props: {
|
|
|
50
51
|
onOnboardingAbandoned?: (reason: string, lastScreenIndex: number, lastScreenId: string) => void;
|
|
51
52
|
onNotificationPermissionRequested?: () => void;
|
|
52
53
|
onNotificationPermissionResult?: (granted: boolean) => void;
|
|
54
|
+
onCloseAction?: (screenIndex: number, screenId: string) => void;
|
|
53
55
|
}): any;
|
|
54
56
|
export default Overlay;
|
package/build/RampkitOverlay.js
CHANGED
|
@@ -580,7 +580,7 @@ function showRampkitOverlay(opts) {
|
|
|
580
580
|
(_a = opts.onClose) === null || _a === void 0 ? void 0 : _a.call(opts);
|
|
581
581
|
}, onOnboardingFinished: opts.onOnboardingFinished, onShowPaywall: opts.onShowPaywall, onRegisterClose: (handler) => {
|
|
582
582
|
activeCloseHandler = handler;
|
|
583
|
-
}, onScreenChange: opts.onScreenChange, onOnboardingAbandoned: opts.onOnboardingAbandoned, onNotificationPermissionRequested: opts.onNotificationPermissionRequested, onNotificationPermissionResult: opts.onNotificationPermissionResult })));
|
|
583
|
+
}, onScreenChange: opts.onScreenChange, onOnboardingAbandoned: opts.onOnboardingAbandoned, onNotificationPermissionRequested: opts.onNotificationPermissionRequested, onNotificationPermissionResult: opts.onNotificationPermissionResult, onCloseAction: opts.onCloseAction })));
|
|
584
584
|
// Once shown, we can safely discard the preloader sibling if present
|
|
585
585
|
if (preloadSibling) {
|
|
586
586
|
preloadSibling.destroy();
|
|
@@ -1653,7 +1653,7 @@ function Overlay(props) {
|
|
|
1653
1653
|
sendOnboardingStateToWebView(i);
|
|
1654
1654
|
}
|
|
1655
1655
|
}, onMessage: (ev) => {
|
|
1656
|
-
var _a, _b, _c, _d, _e, _f;
|
|
1656
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
1657
1657
|
const raw = ev.nativeEvent.data;
|
|
1658
1658
|
console.log("raw", raw);
|
|
1659
1659
|
// Accept either raw strings or JSON payloads from your editor
|
|
@@ -1819,7 +1819,12 @@ function Overlay(props) {
|
|
|
1819
1819
|
return;
|
|
1820
1820
|
}
|
|
1821
1821
|
if ((data === null || data === void 0 ? void 0 : data.type) === "rampkit:close") {
|
|
1822
|
-
|
|
1822
|
+
// Track close action for onboarding completion
|
|
1823
|
+
try {
|
|
1824
|
+
(_e = props.onCloseAction) === null || _e === void 0 ? void 0 : _e.call(props, i, ((_f = props.screens[i]) === null || _f === void 0 ? void 0 : _f.id) || "");
|
|
1825
|
+
}
|
|
1826
|
+
catch (_) { }
|
|
1827
|
+
handleRequestClose({ completed: true }); // Mark as completed so abandonment isn't tracked
|
|
1823
1828
|
return;
|
|
1824
1829
|
}
|
|
1825
1830
|
if ((data === null || data === void 0 ? void 0 : data.type) === "rampkit:haptic") {
|
|
@@ -1827,7 +1832,7 @@ function Overlay(props) {
|
|
|
1827
1832
|
return;
|
|
1828
1833
|
}
|
|
1829
1834
|
}
|
|
1830
|
-
catch (
|
|
1835
|
+
catch (_l) {
|
|
1831
1836
|
// String path
|
|
1832
1837
|
if (raw === "rampkit:tap" ||
|
|
1833
1838
|
raw === "next" ||
|
|
@@ -1854,7 +1859,7 @@ function Overlay(props) {
|
|
|
1854
1859
|
if (raw === "rampkit:onboarding-finished") {
|
|
1855
1860
|
setOnboardingCompleted(true);
|
|
1856
1861
|
try {
|
|
1857
|
-
(
|
|
1862
|
+
(_g = props.onOnboardingFinished) === null || _g === void 0 ? void 0 : _g.call(props, undefined);
|
|
1858
1863
|
}
|
|
1859
1864
|
catch (_) { }
|
|
1860
1865
|
handleRequestClose({ completed: true });
|
|
@@ -1862,7 +1867,7 @@ function Overlay(props) {
|
|
|
1862
1867
|
}
|
|
1863
1868
|
if (raw === "rampkit:show-paywall") {
|
|
1864
1869
|
try {
|
|
1865
|
-
(
|
|
1870
|
+
(_h = props.onShowPaywall) === null || _h === void 0 ? void 0 : _h.call(props);
|
|
1866
1871
|
}
|
|
1867
1872
|
catch (_) { }
|
|
1868
1873
|
return;
|
|
@@ -1891,7 +1896,12 @@ function Overlay(props) {
|
|
|
1891
1896
|
return;
|
|
1892
1897
|
}
|
|
1893
1898
|
if (raw === "rampkit:close") {
|
|
1894
|
-
|
|
1899
|
+
// Track close action for onboarding completion
|
|
1900
|
+
try {
|
|
1901
|
+
(_j = props.onCloseAction) === null || _j === void 0 ? void 0 : _j.call(props, i, ((_k = props.screens[i]) === null || _k === void 0 ? void 0 : _k.id) || "");
|
|
1902
|
+
}
|
|
1903
|
+
catch (_) { }
|
|
1904
|
+
handleRequestClose({ completed: true }); // Mark as completed so abandonment isn't tracked
|
|
1895
1905
|
return;
|
|
1896
1906
|
}
|
|
1897
1907
|
if (raw.startsWith("haptic:")) {
|
package/build/constants.d.ts
CHANGED
|
@@ -14,6 +14,7 @@ export declare const STORAGE_KEYS: {
|
|
|
14
14
|
readonly LAUNCH_COUNT: "rk_launch_count";
|
|
15
15
|
readonly LAST_LAUNCH: "rk_last_launch";
|
|
16
16
|
readonly ONBOARDING_RESPONSES: "rk_onboarding_responses";
|
|
17
|
+
readonly ONBOARDING_COMPLETED: "rk_onboarding_completed";
|
|
17
18
|
};
|
|
18
19
|
export declare const CAPABILITIES: readonly ["onboarding", "paywall_event_receiver", "haptic_feedback", "push_notifications"];
|
|
19
20
|
export declare const SUPABASE_ANON_KEY = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InV1c3RsenV2am1vY2h4a3hhdGZ4Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3NjIxMDM2NTUsImV4cCI6MjA3NzY3OTY1NX0.d5XsIMGnia4n9Pou0IidipyyEfSlwpXFoeDBufMOEwE";
|
package/build/constants.js
CHANGED
|
@@ -20,6 +20,8 @@ exports.STORAGE_KEYS = {
|
|
|
20
20
|
LAST_LAUNCH: "rk_last_launch",
|
|
21
21
|
// Onboarding responses (persisted)
|
|
22
22
|
ONBOARDING_RESPONSES: "rk_onboarding_responses",
|
|
23
|
+
// Onboarding completion status (persisted) - fires once per user
|
|
24
|
+
ONBOARDING_COMPLETED: "rk_onboarding_completed",
|
|
23
25
|
};
|
|
24
26
|
exports.CAPABILITIES = [
|
|
25
27
|
"onboarding",
|
package/build/index.d.ts
CHANGED
|
@@ -11,5 +11,5 @@ export { default as RampKitNative } from "./RampKitNative";
|
|
|
11
11
|
export type { NativeDeviceInfo, NativeLaunchData } from "./RampKitNative";
|
|
12
12
|
export { Haptics, StoreReview, Notifications, TransactionObserver } from "./RampKitNative";
|
|
13
13
|
export type { ImpactStyle, NotificationType, NotificationOptions, NotificationPermissionResult } from "./RampKitNative";
|
|
14
|
-
export type { DeviceInfo, RampKitEvent, EventDevice, EventContext, RampKitConfig, RampKitEventName, RampKitContext, RampKitDeviceContext, RampKitUserContext, NavigationData, ScreenPosition, OnboardingResponse, AppSessionStartedProperties,
|
|
14
|
+
export type { DeviceInfo, RampKitEvent, EventDevice, EventContext, RampKitConfig, RampKitEventName, RampKitContext, RampKitDeviceContext, RampKitUserContext, NavigationData, ScreenPosition, OnboardingResponse, AppSessionStartedProperties, OnboardingStartedProperties, OnboardingCompletedProperties, OnboardingAbandonedProperties, OptionSelectedProperties, NotificationsResponseProperties, PaywallShownProperties, PurchaseStartedProperties, PurchaseCompletedProperties, PurchaseFailedProperties, PurchaseRestoredProperties, } from "./types";
|
|
15
15
|
export { SDK_VERSION, CAPABILITIES } from "./constants";
|
package/build/types.d.ts
CHANGED
|
@@ -81,36 +81,16 @@ export interface AppSessionStartedProperties {
|
|
|
81
81
|
isFirstLaunch: boolean;
|
|
82
82
|
launchCount: number;
|
|
83
83
|
}
|
|
84
|
-
export interface AppSessionEndedProperties {
|
|
85
|
-
reason: string;
|
|
86
|
-
sessionDurationSeconds: number;
|
|
87
|
-
}
|
|
88
|
-
export interface AppBackgroundedProperties {
|
|
89
|
-
sessionDurationSeconds: number;
|
|
90
|
-
}
|
|
91
|
-
export interface AppForegroundedProperties {
|
|
92
|
-
}
|
|
93
84
|
export interface OnboardingStartedProperties {
|
|
94
85
|
onboardingId?: string;
|
|
95
86
|
totalSteps?: number;
|
|
96
87
|
}
|
|
97
|
-
export interface OnboardingScreenViewedProperties {
|
|
98
|
-
onboardingId?: string;
|
|
99
|
-
screenName: string;
|
|
100
|
-
screenIndex: number;
|
|
101
|
-
totalScreens: number;
|
|
102
|
-
}
|
|
103
|
-
export interface OnboardingQuestionAnsweredProperties {
|
|
104
|
-
onboardingId?: string;
|
|
105
|
-
questionId: string;
|
|
106
|
-
answer: any;
|
|
107
|
-
questionText?: string;
|
|
108
|
-
}
|
|
109
88
|
export interface OnboardingCompletedProperties {
|
|
110
89
|
onboardingId?: string;
|
|
111
90
|
timeToCompleteSeconds: number;
|
|
112
91
|
completedSteps: number;
|
|
113
92
|
totalSteps: number;
|
|
93
|
+
trigger: string;
|
|
114
94
|
}
|
|
115
95
|
export interface OnboardingAbandonedProperties {
|
|
116
96
|
onboardingId?: string;
|
|
@@ -118,15 +98,10 @@ export interface OnboardingAbandonedProperties {
|
|
|
118
98
|
lastScreenName?: string;
|
|
119
99
|
timeSpentSeconds: number;
|
|
120
100
|
}
|
|
121
|
-
export interface
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
export interface CtaTapProperties {
|
|
126
|
-
buttonId: string;
|
|
127
|
-
buttonText?: string;
|
|
128
|
-
}
|
|
129
|
-
export interface NotificationsPromptShownProperties {
|
|
101
|
+
export interface OptionSelectedProperties {
|
|
102
|
+
optionId: string;
|
|
103
|
+
optionValue: any;
|
|
104
|
+
questionId?: string;
|
|
130
105
|
}
|
|
131
106
|
export interface NotificationsResponseProperties {
|
|
132
107
|
status: "granted" | "denied" | "provisional";
|
|
@@ -140,39 +115,69 @@ export interface PaywallShownProperties {
|
|
|
140
115
|
currency?: string;
|
|
141
116
|
}>;
|
|
142
117
|
}
|
|
143
|
-
export interface PaywallPrimaryActionTapProperties {
|
|
144
|
-
paywallId: string;
|
|
145
|
-
productId?: string;
|
|
146
|
-
}
|
|
147
|
-
export interface PaywallClosedProperties {
|
|
148
|
-
paywallId: string;
|
|
149
|
-
reason: "dismissed" | "purchased" | "backgrounded";
|
|
150
|
-
}
|
|
151
118
|
export interface PurchaseStartedProperties {
|
|
152
119
|
productId: string;
|
|
153
120
|
amount?: number;
|
|
154
121
|
currency?: string;
|
|
122
|
+
priceFormatted?: string;
|
|
155
123
|
}
|
|
124
|
+
/**
|
|
125
|
+
* Properties for purchase_completed event
|
|
126
|
+
* Critical for attribution: originalTransactionId links renewals to original purchase
|
|
127
|
+
*/
|
|
156
128
|
export interface PurchaseCompletedProperties {
|
|
129
|
+
/** Product identifier (e.g., "com.app.yearly") */
|
|
157
130
|
productId: string;
|
|
158
|
-
|
|
159
|
-
|
|
131
|
+
/** Price as number (e.g., 39.99) */
|
|
132
|
+
amount?: number;
|
|
133
|
+
/** Currency code (e.g., "USD") */
|
|
134
|
+
currency?: string;
|
|
135
|
+
/** Formatted price string (e.g., "$39.99") */
|
|
136
|
+
priceFormatted?: string;
|
|
137
|
+
/** Unique transaction ID from App Store/Play Store */
|
|
160
138
|
transactionId: string;
|
|
161
|
-
|
|
162
|
-
|
|
139
|
+
/** CRITICAL: Original transaction ID - links renewals to original purchase */
|
|
140
|
+
originalTransactionId: string;
|
|
141
|
+
/** ISO 8601 purchase timestamp */
|
|
142
|
+
purchaseDate: string;
|
|
143
|
+
/** ISO 8601 expiration date for subscriptions */
|
|
144
|
+
expirationDate?: string;
|
|
145
|
+
/** Whether this is a free trial */
|
|
146
|
+
isTrial?: boolean;
|
|
147
|
+
/** Whether this is an introductory offer */
|
|
148
|
+
isIntroOffer?: boolean;
|
|
149
|
+
/** Offer type: "introductory", "promotional", "code", or null */
|
|
150
|
+
offerType?: string | null;
|
|
151
|
+
/** Offer ID if applicable */
|
|
152
|
+
offerId?: string;
|
|
153
|
+
/** ISO 8601 duration (e.g., "P1M" for monthly, "P1Y" for yearly) */
|
|
154
|
+
subscriptionPeriod?: string;
|
|
155
|
+
/** Subscription group ID */
|
|
156
|
+
subscriptionGroupId?: string;
|
|
157
|
+
/** App Store storefront country code */
|
|
158
|
+
storefront?: string;
|
|
159
|
+
/** Environment: "Production" or "Sandbox" */
|
|
160
|
+
environment?: string;
|
|
161
|
+
/** Quantity purchased */
|
|
162
|
+
quantity?: number;
|
|
163
163
|
}
|
|
164
164
|
export interface PurchaseFailedProperties {
|
|
165
165
|
productId: string;
|
|
166
166
|
errorCode: string;
|
|
167
167
|
errorMessage: string;
|
|
168
168
|
}
|
|
169
|
-
export
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
export type
|
|
175
|
-
export type
|
|
169
|
+
export interface PurchaseRestoredProperties {
|
|
170
|
+
productId: string;
|
|
171
|
+
transactionId?: string;
|
|
172
|
+
originalTransactionId?: string;
|
|
173
|
+
}
|
|
174
|
+
export type AppLifecycleEventName = "app_session_started";
|
|
175
|
+
export type OnboardingEventName = "onboarding_started" | "onboarding_completed" | "onboarding_abandoned";
|
|
176
|
+
export type InteractionEventName = "option_selected";
|
|
177
|
+
export type PermissionEventName = "notifications_response" | "tracking_response";
|
|
178
|
+
export type PaywallEventName = "paywall_shown";
|
|
179
|
+
export type PurchaseEventName = "purchase_started" | "purchase_completed" | "purchase_failed" | "purchase_restored";
|
|
180
|
+
export type RampKitEventName = AppLifecycleEventName | OnboardingEventName | InteractionEventName | PermissionEventName | PaywallEventName | PurchaseEventName;
|
|
176
181
|
export interface RampKitConfig {
|
|
177
182
|
appId: string;
|
|
178
183
|
apiKey?: string;
|
package/package.json
CHANGED