rampkit-expo-dev 0.0.87 → 0.0.89

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.
@@ -1,24 +1,42 @@
1
1
  /**
2
2
  * OnboardingResponseStorage
3
- * Manages persistent storage of onboarding responses
3
+ * Manages persistent storage of onboarding state variables
4
4
  */
5
- import { OnboardingResponse } from "./types";
6
5
  /**
7
- * Manages persistent storage of onboarding responses
6
+ * Represents the stored onboarding state
7
+ */
8
+ export interface OnboardingState {
9
+ /** The state variables as key-value pairs */
10
+ variables: Record<string, any>;
11
+ /** ISO 8601 timestamp when the state was last updated */
12
+ updatedAt: string;
13
+ }
14
+ /**
15
+ * Manages persistent storage of onboarding state variables
8
16
  */
9
17
  export declare const OnboardingResponseStorage: {
10
18
  /**
11
- * Save a new response, merging with existing responses
12
- * If a response with the same questionId exists, it will be updated
19
+ * Initialize the state with initial values from onboarding config
20
+ * This should be called when onboarding starts
21
+ */
22
+ initializeState(initialVariables: Record<string, any>): Promise<void>;
23
+ /**
24
+ * Update state with new variable values (merges with existing)
25
+ */
26
+ updateState(newVariables: Record<string, any>): Promise<void>;
27
+ /**
28
+ * Retrieve the stored state
29
+ * @returns OnboardingState object with variables and timestamp
13
30
  */
14
- saveResponse(response: OnboardingResponse): Promise<void>;
31
+ retrieveState(): Promise<OnboardingState>;
15
32
  /**
16
- * Retrieve all stored responses
17
- * @returns Array of OnboardingResponse objects, empty array if none found
33
+ * Retrieve just the variables (convenience method)
34
+ * @returns Record of variable name to value
18
35
  */
19
- retrieveResponses(): Promise<OnboardingResponse[]>;
36
+ retrieveVariables(): Promise<Record<string, any>>;
20
37
  /**
21
- * Clear all stored responses
38
+ * Clear all stored state
22
39
  */
40
+ clearState(): Promise<void>;
23
41
  clearResponses(): Promise<void>;
24
42
  };
@@ -1,70 +1,98 @@
1
1
  "use strict";
2
2
  /**
3
3
  * OnboardingResponseStorage
4
- * Manages persistent storage of onboarding responses
4
+ * Manages persistent storage of onboarding state variables
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
7
  exports.OnboardingResponseStorage = void 0;
8
8
  const RampKitNative_1 = require("./RampKitNative");
9
9
  const constants_1 = require("./constants");
10
10
  /**
11
- * Manages persistent storage of onboarding responses
11
+ * Manages persistent storage of onboarding state variables
12
12
  */
13
13
  exports.OnboardingResponseStorage = {
14
14
  /**
15
- * Save a new response, merging with existing responses
16
- * If a response with the same questionId exists, it will be updated
15
+ * Initialize the state with initial values from onboarding config
16
+ * This should be called when onboarding starts
17
17
  */
18
- async saveResponse(response) {
18
+ async initializeState(initialVariables) {
19
19
  try {
20
- const responses = await this.retrieveResponses();
21
- // Update existing response for same questionId or append new
22
- const existingIndex = responses.findIndex((r) => r.questionId === response.questionId);
23
- if (existingIndex >= 0) {
24
- responses[existingIndex] = response;
25
- }
26
- else {
27
- responses.push(response);
20
+ const state = {
21
+ variables: { ...initialVariables },
22
+ updatedAt: new Date().toISOString(),
23
+ };
24
+ await (0, RampKitNative_1.setStoredValue)(constants_1.STORAGE_KEYS.ONBOARDING_RESPONSES, JSON.stringify(state));
25
+ if (__DEV__) {
26
+ console.log("[RampKit] Initialized onboarding state:", initialVariables);
28
27
  }
29
- // Serialize and save
30
- await (0, RampKitNative_1.setStoredValue)(constants_1.STORAGE_KEYS.ONBOARDING_RESPONSES, JSON.stringify(responses));
28
+ }
29
+ catch (error) {
30
+ console.warn("[RampKit] Failed to initialize onboarding state:", error);
31
+ }
32
+ },
33
+ /**
34
+ * Update state with new variable values (merges with existing)
35
+ */
36
+ async updateState(newVariables) {
37
+ try {
38
+ const currentState = await this.retrieveState();
39
+ const updatedState = {
40
+ variables: {
41
+ ...currentState.variables,
42
+ ...newVariables,
43
+ },
44
+ updatedAt: new Date().toISOString(),
45
+ };
46
+ await (0, RampKitNative_1.setStoredValue)(constants_1.STORAGE_KEYS.ONBOARDING_RESPONSES, JSON.stringify(updatedState));
31
47
  if (__DEV__) {
32
- console.log(`[RampKit] Saved response for question: ${response.questionId}`);
48
+ console.log("[RampKit] Updated onboarding state:", newVariables);
33
49
  }
34
50
  }
35
51
  catch (error) {
36
- console.warn("[RampKit] Failed to save onboarding response:", error);
52
+ console.warn("[RampKit] Failed to update onboarding state:", error);
37
53
  }
38
54
  },
39
55
  /**
40
- * Retrieve all stored responses
41
- * @returns Array of OnboardingResponse objects, empty array if none found
56
+ * Retrieve the stored state
57
+ * @returns OnboardingState object with variables and timestamp
42
58
  */
43
- async retrieveResponses() {
59
+ async retrieveState() {
44
60
  try {
45
61
  const jsonString = await (0, RampKitNative_1.getStoredValue)(constants_1.STORAGE_KEYS.ONBOARDING_RESPONSES);
46
62
  if (!jsonString) {
47
- return [];
63
+ return { variables: {}, updatedAt: "" };
48
64
  }
49
65
  return JSON.parse(jsonString);
50
66
  }
51
67
  catch (error) {
52
- console.warn("[RampKit] Failed to retrieve onboarding responses:", error);
53
- return [];
68
+ console.warn("[RampKit] Failed to retrieve onboarding state:", error);
69
+ return { variables: {}, updatedAt: "" };
54
70
  }
55
71
  },
56
72
  /**
57
- * Clear all stored responses
73
+ * Retrieve just the variables (convenience method)
74
+ * @returns Record of variable name to value
58
75
  */
59
- async clearResponses() {
76
+ async retrieveVariables() {
77
+ const state = await this.retrieveState();
78
+ return state.variables;
79
+ },
80
+ /**
81
+ * Clear all stored state
82
+ */
83
+ async clearState() {
60
84
  try {
61
85
  await (0, RampKitNative_1.setStoredValue)(constants_1.STORAGE_KEYS.ONBOARDING_RESPONSES, "");
62
86
  if (__DEV__) {
63
- console.log("[RampKit] Cleared all onboarding responses");
87
+ console.log("[RampKit] Cleared onboarding state");
64
88
  }
65
89
  }
66
90
  catch (error) {
67
- console.warn("[RampKit] Failed to clear onboarding responses:", error);
91
+ console.warn("[RampKit] Failed to clear onboarding state:", error);
68
92
  }
69
93
  },
94
+ // Legacy aliases for backwards compatibility
95
+ async clearResponses() {
96
+ return this.clearState();
97
+ },
70
98
  };
@@ -2,7 +2,8 @@
2
2
  * RampKit Core SDK
3
3
  * Main SDK class for RampKit Expo integration
4
4
  */
5
- import { DeviceInfo, RampKitConfig, EventContext, OnboardingResponse } from "./types";
5
+ import { DeviceInfo, RampKitConfig, EventContext } from "./types";
6
+ import { OnboardingState } from "./OnboardingResponseStorage";
6
7
  export declare class RampKitCore {
7
8
  private static _instance;
8
9
  private config;
@@ -62,10 +63,19 @@ export declare class RampKitCore {
62
63
  */
63
64
  isInitialized(): boolean;
64
65
  /**
65
- * Get all stored onboarding responses
66
- * @returns Promise resolving to array of OnboardingResponse objects
66
+ * Get all stored onboarding state variables
67
+ * @returns Promise resolving to OnboardingState with variables and timestamp
67
68
  */
68
- getOnboardingResponses(): Promise<OnboardingResponse[]>;
69
+ getOnboardingState(): Promise<OnboardingState>;
70
+ /**
71
+ * Get just the onboarding variables (convenience method)
72
+ * @returns Promise resolving to Record of variable name to value
73
+ */
74
+ getOnboardingVariables(): Promise<Record<string, any>>;
75
+ /**
76
+ * @deprecated Use getOnboardingState() or getOnboardingVariables() instead
77
+ */
78
+ getOnboardingResponses(): Promise<Record<string, any>>;
69
79
  /**
70
80
  * Show the onboarding overlay
71
81
  */
package/build/RampKit.js CHANGED
@@ -221,11 +221,24 @@ class RampKitCore {
221
221
  return this.initialized;
222
222
  }
223
223
  /**
224
- * Get all stored onboarding responses
225
- * @returns Promise resolving to array of OnboardingResponse objects
224
+ * Get all stored onboarding state variables
225
+ * @returns Promise resolving to OnboardingState with variables and timestamp
226
+ */
227
+ async getOnboardingState() {
228
+ return OnboardingResponseStorage_1.OnboardingResponseStorage.retrieveState();
229
+ }
230
+ /**
231
+ * Get just the onboarding variables (convenience method)
232
+ * @returns Promise resolving to Record of variable name to value
233
+ */
234
+ async getOnboardingVariables() {
235
+ return OnboardingResponseStorage_1.OnboardingResponseStorage.retrieveVariables();
236
+ }
237
+ /**
238
+ * @deprecated Use getOnboardingState() or getOnboardingVariables() instead
226
239
  */
227
240
  async getOnboardingResponses() {
228
- return OnboardingResponseStorage_1.OnboardingResponseStorage.retrieveResponses();
241
+ return OnboardingResponseStorage_1.OnboardingResponseStorage.retrieveVariables();
229
242
  }
230
243
  /**
231
244
  * Show the onboarding overlay
@@ -251,6 +264,8 @@ class RampKitCore {
251
264
  return {};
252
265
  }
253
266
  })();
267
+ // Initialize state storage with initial values
268
+ OnboardingResponseStorage_1.OnboardingResponseStorage.initializeState(variables);
254
269
  const screens = data.screens.map((s) => ({
255
270
  id: s.id,
256
271
  html: s.html ||
@@ -1948,7 +1948,7 @@ function Overlay(props) {
1948
1948
  }
1949
1949
  }
1950
1950
  }, onMessage: (ev) => {
1951
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
1951
+ var _a, _b, _c, _d, _e, _f, _g, _h;
1952
1952
  const raw = ev.nativeEvent.data;
1953
1953
  console.log("raw", raw);
1954
1954
  // Accept either raw strings or JSON payloads from your editor
@@ -2014,6 +2014,8 @@ function Overlay(props) {
2014
2014
  if (__DEV__) {
2015
2015
  console.log("[Rampkit] variables updated:", newVars);
2016
2016
  }
2017
+ // Persist state updates to storage
2018
+ OnboardingResponseStorage_1.OnboardingResponseStorage.updateState(newVars);
2017
2019
  // CRITICAL: Send merged vars back to the active screen
2018
2020
  // This ensures window.__rampkitVariables has the complete state
2019
2021
  // which is needed for dynamic tap conditions to evaluate correctly
@@ -2032,7 +2034,13 @@ function Overlay(props) {
2032
2034
  // 3) A page requested an in-app review prompt
2033
2035
  if ((data === null || data === void 0 ? void 0 : data.type) === "rampkit:request-review" ||
2034
2036
  (data === null || data === void 0 ? void 0 : data.type) === "rampkit:review") {
2035
- const executeReview = async () => {
2037
+ // Only process from active screen (on-open actions are handled by SDK in activateScreen)
2038
+ if (!isScreenActive(i)) {
2039
+ if (__DEV__)
2040
+ console.log(`[Rampkit] Ignoring review request from inactive screen ${i} (SDK handles on-open)`);
2041
+ return;
2042
+ }
2043
+ (async () => {
2036
2044
  try {
2037
2045
  const available = await RampKitNative_1.StoreReview.isAvailableAsync();
2038
2046
  if (available) {
@@ -2040,36 +2048,22 @@ function Overlay(props) {
2040
2048
  }
2041
2049
  }
2042
2050
  catch (_) { }
2043
- };
2044
- // Only execute if screen is active, otherwise queue for later
2045
- if (isScreenActive(i)) {
2046
- executeReview();
2047
- }
2048
- else {
2049
- if (__DEV__)
2050
- console.log(`[Rampkit] Queuing review request from inactive screen ${i}`);
2051
- queueAction(i, executeReview);
2052
- }
2051
+ })();
2053
2052
  return;
2054
2053
  }
2055
2054
  // 4) A page requested notification permission
2056
2055
  if ((data === null || data === void 0 ? void 0 : data.type) === "rampkit:request-notification-permission") {
2057
- const executeNotification = () => {
2058
- handleNotificationPermissionRequest({
2059
- ios: data === null || data === void 0 ? void 0 : data.ios,
2060
- android: data === null || data === void 0 ? void 0 : data.android,
2061
- behavior: data === null || data === void 0 ? void 0 : data.behavior,
2062
- });
2063
- };
2064
- // Only execute if screen is active, otherwise queue for later
2065
- if (isScreenActive(i)) {
2066
- executeNotification();
2067
- }
2068
- else {
2056
+ // Only process from active screen (on-open actions are handled by SDK in activateScreen)
2057
+ if (!isScreenActive(i)) {
2069
2058
  if (__DEV__)
2070
- console.log(`[Rampkit] Queuing notification request from inactive screen ${i}`);
2071
- queueAction(i, executeNotification);
2059
+ console.log(`[Rampkit] Ignoring notification request from inactive screen ${i} (SDK handles on-open)`);
2060
+ return;
2072
2061
  }
2062
+ handleNotificationPermissionRequest({
2063
+ ios: data === null || data === void 0 ? void 0 : data.ios,
2064
+ android: data === null || data === void 0 ? void 0 : data.android,
2065
+ behavior: data === null || data === void 0 ? void 0 : data.behavior,
2066
+ });
2073
2067
  return;
2074
2068
  }
2075
2069
  // 5) Onboarding finished event from page
@@ -2090,21 +2084,6 @@ function Overlay(props) {
2090
2084
  catch (_) { }
2091
2085
  return;
2092
2086
  }
2093
- // 7) Question answered - persist response locally
2094
- if ((data === null || data === void 0 ? void 0 : data.type) === "rampkit:question-answered") {
2095
- const questionId = data === null || data === void 0 ? void 0 : data.questionId;
2096
- if (questionId) {
2097
- const response = {
2098
- questionId,
2099
- answer: (_c = data === null || data === void 0 ? void 0 : data.answer) !== null && _c !== void 0 ? _c : "",
2100
- questionText: data === null || data === void 0 ? void 0 : data.questionText,
2101
- screenName: (_d = props.screens[i]) === null || _d === void 0 ? void 0 : _d.id,
2102
- answeredAt: new Date().toISOString(),
2103
- };
2104
- OnboardingResponseStorage_1.OnboardingResponseStorage.saveResponse(response);
2105
- }
2106
- return;
2107
- }
2108
2087
  if ((data === null || data === void 0 ? void 0 : data.type) === "rampkit:continue" ||
2109
2088
  (data === null || data === void 0 ? void 0 : data.type) === "continue") {
2110
2089
  // Only process from active screen (on-open actions are handled by SDK in activateScreen)
@@ -2154,7 +2133,7 @@ function Overlay(props) {
2154
2133
  if ((data === null || data === void 0 ? void 0 : data.type) === "rampkit:close") {
2155
2134
  // Track close action for onboarding completion
2156
2135
  try {
2157
- (_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) || "");
2136
+ (_c = props.onCloseAction) === null || _c === void 0 ? void 0 : _c.call(props, i, ((_d = props.screens[i]) === null || _d === void 0 ? void 0 : _d.id) || "");
2158
2137
  }
2159
2138
  catch (_) { }
2160
2139
  handleRequestClose({ completed: true }); // Mark as completed so abandonment isn't tracked
@@ -2165,7 +2144,7 @@ function Overlay(props) {
2165
2144
  return;
2166
2145
  }
2167
2146
  }
2168
- catch (_l) {
2147
+ catch (_j) {
2169
2148
  // String path
2170
2149
  if (raw === "rampkit:tap" ||
2171
2150
  raw === "next" ||
@@ -2180,7 +2159,13 @@ function Overlay(props) {
2180
2159
  return;
2181
2160
  }
2182
2161
  if (raw === "rampkit:request-review" || raw === "rampkit:review") {
2183
- const executeReview = async () => {
2162
+ // Only process from active screen (on-open actions are handled by SDK in activateScreen)
2163
+ if (!isScreenActive(i)) {
2164
+ if (__DEV__)
2165
+ console.log(`[Rampkit] Ignoring review request (raw) from inactive screen ${i} (SDK handles on-open)`);
2166
+ return;
2167
+ }
2168
+ (async () => {
2184
2169
  try {
2185
2170
  const available = await RampKitNative_1.StoreReview.isAvailableAsync();
2186
2171
  if (available) {
@@ -2188,35 +2173,23 @@ function Overlay(props) {
2188
2173
  }
2189
2174
  }
2190
2175
  catch (_) { }
2191
- };
2192
- // Only execute if screen is active, otherwise queue for later
2193
- if (isScreenActive(i)) {
2194
- executeReview();
2195
- }
2196
- else {
2197
- if (__DEV__)
2198
- console.log(`[Rampkit] Queuing review request (raw) from inactive screen ${i}`);
2199
- queueAction(i, executeReview);
2200
- }
2176
+ })();
2201
2177
  return;
2202
2178
  }
2203
2179
  if (raw === "rampkit:request-notification-permission") {
2204
- const executeNotification = () => handleNotificationPermissionRequest(undefined);
2205
- // Only execute if screen is active, otherwise queue for later
2206
- if (isScreenActive(i)) {
2207
- executeNotification();
2208
- }
2209
- else {
2180
+ // Only process from active screen (on-open actions are handled by SDK in activateScreen)
2181
+ if (!isScreenActive(i)) {
2210
2182
  if (__DEV__)
2211
- console.log(`[Rampkit] Queuing notification request (raw) from inactive screen ${i}`);
2212
- queueAction(i, executeNotification);
2183
+ console.log(`[Rampkit] Ignoring notification request (raw) from inactive screen ${i} (SDK handles on-open)`);
2184
+ return;
2213
2185
  }
2186
+ handleNotificationPermissionRequest(undefined);
2214
2187
  return;
2215
2188
  }
2216
2189
  if (raw === "rampkit:onboarding-finished") {
2217
2190
  setOnboardingCompleted(true);
2218
2191
  try {
2219
- (_g = props.onOnboardingFinished) === null || _g === void 0 ? void 0 : _g.call(props, undefined);
2192
+ (_e = props.onOnboardingFinished) === null || _e === void 0 ? void 0 : _e.call(props, undefined);
2220
2193
  }
2221
2194
  catch (_) { }
2222
2195
  handleRequestClose({ completed: true });
@@ -2224,7 +2197,7 @@ function Overlay(props) {
2224
2197
  }
2225
2198
  if (raw === "rampkit:show-paywall") {
2226
2199
  try {
2227
- (_h = props.onShowPaywall) === null || _h === void 0 ? void 0 : _h.call(props);
2200
+ (_f = props.onShowPaywall) === null || _f === void 0 ? void 0 : _f.call(props);
2228
2201
  }
2229
2202
  catch (_) { }
2230
2203
  return;
@@ -2267,7 +2240,7 @@ function Overlay(props) {
2267
2240
  if (raw === "rampkit:close") {
2268
2241
  // Track close action for onboarding completion
2269
2242
  try {
2270
- (_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) || "");
2243
+ (_g = props.onCloseAction) === null || _g === void 0 ? void 0 : _g.call(props, i, ((_h = props.screens[i]) === null || _h === void 0 ? void 0 : _h.id) || "");
2271
2244
  }
2272
2245
  catch (_) { }
2273
2246
  handleRequestClose({ completed: true }); // Mark as completed so abandonment isn't tracked
package/build/index.d.ts CHANGED
@@ -11,5 +11,6 @@ export { default as RampKitNative } from "./RampKitNative";
11
11
  export type { NativeDeviceInfo, NativeLaunchData } from "./RampKitNative";
12
12
  export { Haptics, StoreReview, Notifications, TransactionObserver, isNativeModuleAvailable } from "./RampKitNative";
13
13
  export type { ImpactStyle, NotificationType, NotificationOptions, NotificationPermissionResult, TransactionObserverResult, SentEventResult, TrackedTransactionDetail, EntitlementCheckResult } from "./RampKitNative";
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";
14
+ export type { DeviceInfo, RampKitEvent, EventDevice, EventContext, RampKitConfig, RampKitEventName, RampKitContext, RampKitDeviceContext, RampKitUserContext, NavigationData, ScreenPosition, AppSessionStartedProperties, OnboardingStartedProperties, OnboardingCompletedProperties, OnboardingAbandonedProperties, OptionSelectedProperties, NotificationsResponseProperties, PaywallShownProperties, PurchaseStartedProperties, PurchaseCompletedProperties, PurchaseFailedProperties, PurchaseRestoredProperties, } from "./types";
15
+ export type { OnboardingState } from "./OnboardingResponseStorage";
15
16
  export { SDK_VERSION, CAPABILITIES } from "./constants";
package/build/types.d.ts CHANGED
@@ -271,18 +271,3 @@ export interface ScreenPosition {
271
271
  /** Row classification: "main" for main row screens, "variant" for screens below */
272
272
  row: "main" | "variant";
273
273
  }
274
- /**
275
- * Represents a single onboarding question response stored locally
276
- */
277
- export interface OnboardingResponse {
278
- /** Unique identifier for the question */
279
- questionId: string;
280
- /** The user's answer (can be any JSON-serializable value) */
281
- answer: any;
282
- /** Optional text of the question shown to user */
283
- questionText?: string;
284
- /** Screen where the question was answered */
285
- screenName?: string;
286
- /** ISO 8601 timestamp when the answer was recorded */
287
- answeredAt: string;
288
- }
package/build/types.js CHANGED
@@ -3,3 +3,7 @@
3
3
  * RampKit SDK Types
4
4
  */
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ // ============================================================================
7
+ // Onboarding State Storage
8
+ // ============================================================================
9
+ // OnboardingState is exported from OnboardingResponseStorage.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rampkit-expo-dev",
3
- "version": "0.0.87",
3
+ "version": "0.0.89",
4
4
  "description": "The Expo SDK for RampKit. Build, test, and personalize app onboardings with instant updates.",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",