rampkit-expo-dev 0.0.84 → 0.0.85

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.
@@ -3,7 +3,7 @@ export declare const injectedHardening = "\n(function(){\n try {\n var meta
3
3
  export declare const injectedNoSelect = "\n(function(){\n try {\n if (window.__rkNoSelectApplied) return true;\n window.__rkNoSelectApplied = true;\n var style = document.getElementById('rk-no-select-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'rk-no-select-style';\n style.innerHTML = \"\n * {\n user-select: none !important;\n -webkit-user-select: none !important;\n -webkit-touch-callout: none !important;\n }\n ::selection {\n background: transparent !important;\n }\n \";\n document.head.appendChild(style);\n }\n var prevent = function(e){ if(e && e.preventDefault) e.preventDefault(); return false; };\n document.addEventListener('contextmenu', prevent, { passive: false, capture: true });\n document.addEventListener('selectstart', prevent, { passive: false, capture: true });\n } catch (_) {}\n true;\n})();\n";
4
4
  export declare const injectedVarsHandler = "\n(function(){\n try {\n if (window.__rkVarsHandlerApplied) return true;\n window.__rkVarsHandlerApplied = true;\n \n // Handler function that updates variables and notifies the page\n window.__rkHandleVarsUpdate = function(vars) {\n if (!vars || typeof vars !== 'object') return;\n // Update the global variables object\n window.__rampkitVariables = vars;\n // Dispatch a custom event that the page's JS can listen to for re-rendering\n try {\n document.dispatchEvent(new CustomEvent('rampkit:vars-updated', { detail: vars }));\n } catch(e) {}\n // Also try calling a global handler if the page defined one\n try {\n if (typeof window.onRampkitVarsUpdate === 'function') {\n window.onRampkitVarsUpdate(vars);\n }\n } catch(e) {}\n };\n \n // Listen for message events from React Native\n document.addEventListener('message', function(event) {\n try {\n var data = event.data;\n if (data && data.type === 'rampkit:variables' && data.vars) {\n window.__rkHandleVarsUpdate(data.vars);\n }\n } catch(e) {}\n }, false);\n \n // Also listen on window for compatibility\n window.addEventListener('message', function(event) {\n try {\n var data = event.data;\n if (data && data.type === 'rampkit:variables' && data.vars) {\n window.__rkHandleVarsUpdate(data.vars);\n }\n } catch(e) {}\n }, false);\n } catch (_) {}\n true;\n})();\n";
5
5
  export declare const injectedDynamicTapHandler = "\n(function() {\n if (window.__rampkitClickInterceptorInstalled) return;\n window.__rampkitClickInterceptorInstalled = true;\n\n // Decode HTML entities\n function decodeHtml(str) {\n if (!str) return str;\n return str.replace(/&quot;/g, '\"').replace(/&#34;/g, '\"').replace(/&#x22;/g, '\"')\n .replace(/&apos;/g, \"'\").replace(/&#39;/g, \"'\").replace(/&#x27;/g, \"'\")\n .replace(/&lt;/g, '<').replace(/&gt;/g, '>').replace(/&amp;/g, '&');\n }\n\n // Find dynamic tap config on element or ancestors\n function findDynamicTap(el) {\n var current = el;\n var depth = 0;\n var attrNames = ['data-tap-dynamic', 'data-tapdynamic', 'tapDynamic', 'data-dynamic-tap'];\n while (current && current !== document.body && current !== document.documentElement && depth < 20) {\n if (current.getAttribute) {\n for (var i = 0; i < attrNames.length; i++) {\n var attr = current.getAttribute(attrNames[i]);\n if (attr && attr.length > 2) {\n return { element: current, config: attr };\n }\n }\n if (current.dataset && current.dataset.tapDynamic) {\n return { element: current, config: current.dataset.tapDynamic };\n }\n }\n current = current.parentElement;\n depth++;\n }\n return null;\n }\n \n // Get variables for condition evaluation - check ALL possible sources\n function getVars() {\n var vars = {};\n if (window.__rampkitVariables) {\n Object.keys(window.__rampkitVariables).forEach(function(k) {\n vars[k] = window.__rampkitVariables[k];\n });\n }\n if (window.__rampkitVars) {\n Object.keys(window.__rampkitVars).forEach(function(k) {\n vars[k] = window.__rampkitVars[k];\n });\n }\n if (window.RK_VARS) {\n Object.keys(window.RK_VARS).forEach(function(k) {\n vars[k] = window.RK_VARS[k];\n });\n }\n return vars;\n }\n \n // Evaluate a single rule\n function evalRule(rule, vars) {\n if (!rule || !rule.key) return false;\n var left = vars[rule.key];\n var right = rule.value;\n var op = rule.op || '=';\n if (left === undefined || left === null) left = '';\n if (right === undefined || right === null) right = '';\n var leftStr = String(left);\n var rightStr = String(right);\n var result = false;\n switch (op) {\n case '=': case '==': result = leftStr === rightStr; break;\n case '!=': case '<>': result = leftStr !== rightStr; break;\n case '>': result = parseFloat(left) > parseFloat(right); break;\n case '<': result = parseFloat(left) < parseFloat(right); break;\n case '>=': result = parseFloat(left) >= parseFloat(right); break;\n case '<=': result = parseFloat(left) <= parseFloat(right); break;\n default: result = false;\n }\n return result;\n }\n \n // Evaluate all rules (AND logic)\n function evalRules(rules, vars) {\n if (!rules || !rules.length) return true;\n for (var i = 0; i < rules.length; i++) {\n if (!evalRule(rules[i], vars)) return false;\n }\n return true;\n }\n \n // Execute an action\n function execAction(action) {\n if (!action || !action.type) return;\n var msg = null;\n var actionType = action.type.toLowerCase();\n \n switch (actionType) {\n case 'navigate':\n msg = { type: 'rampkit:navigate', targetScreenId: action.targetScreenId || '__continue__', animation: action.animation || 'fade' };\n break;\n case 'continue':\n msg = { type: 'rampkit:navigate', targetScreenId: '__continue__', animation: action.animation || 'fade' };\n break;\n case 'goback':\n msg = { type: 'rampkit:goBack', animation: action.animation || 'fade' };\n break;\n case 'close':\n msg = { type: 'rampkit:close' };\n break;\n case 'haptic':\n msg = { type: 'rampkit:haptic', hapticType: action.hapticType || 'impact', impactStyle: action.impactStyle || 'Medium', notificationType: action.notificationType };\n break;\n case 'showpaywall':\n msg = { type: 'rampkit:show-paywall', payload: action.payload || { paywallId: action.paywallId } };\n break;\n case 'requestreview':\n msg = { type: 'rampkit:request-review' };\n break;\n case 'requestnotificationpermission':\n msg = { type: 'rampkit:request-notification-permission' };\n break;\n case 'onboardingfinished':\n msg = { type: 'rampkit:onboarding-finished', payload: action.payload };\n break;\n case 'setvariable':\n case 'setstate':\n case 'updatevariable':\n case 'set':\n case 'assign':\n var varKey = action.key || action.variableName || action.name || action.variable;\n var varValue = action.variableValue !== undefined ? action.variableValue :\n action.value !== undefined ? action.value :\n action.newValue !== undefined ? action.newValue : undefined;\n if (varKey && varValue !== undefined) {\n if (window.__rampkitVariables) window.__rampkitVariables[varKey] = varValue;\n if (window.__rampkitVars) window.__rampkitVars[varKey] = varValue;\n var updateVars = {};\n updateVars[varKey] = varValue;\n msg = { type: 'rampkit:variables', vars: updateVars };\n }\n break;\n }\n if (msg) {\n try {\n if (window.ReactNativeWebView && window.ReactNativeWebView.postMessage) {\n window.ReactNativeWebView.postMessage(JSON.stringify(msg));\n }\n } catch(e) {}\n }\n }\n \n // Evaluate dynamic tap config\n function evalDynamicTap(config) {\n if (!config || !config.values) return false;\n var vars = getVars();\n var conditions = config.values;\n for (var i = 0; i < conditions.length; i++) {\n var cond = conditions[i];\n var condType = cond.conditionType || 'if';\n var rules = cond.rules || [];\n var actions = cond.actions || [];\n if (condType === 'else' || evalRules(rules, vars)) {\n for (var j = 0; j < actions.length; j++) {\n execAction(actions[j]);\n }\n return true;\n }\n }\n return false;\n }\n \n // Click interceptor - capture phase, runs BEFORE onclick handlers\n function interceptClick(event) {\n var result = findDynamicTap(event.target);\n if (!result) return;\n\n try {\n var configStr = decodeHtml(result.config);\n var config = JSON.parse(configStr);\n var handled = evalDynamicTap(config);\n if (handled) {\n event.stopImmediatePropagation();\n event.preventDefault();\n return false;\n }\n } catch (e) {\n console.log('[RampKit] Dynamic tap error:', e);\n }\n }\n\n // Install interceptor on window in capture phase\n window.addEventListener('click', interceptClick, true);\n})();\n";
6
- export declare const injectedButtonAnimations = "\n(function(){\n try {\n if (window.__rkButtonAnimApplied) return true;\n window.__rkButtonAnimApplied = true;\n\n var pressed = null;\n var pressedOriginalTransform = '';\n var pressedOriginalOpacity = '';\n var pressedOriginalTransition = '';\n var releaseTimer = null;\n\n // Find interactive element - looks for clickable-looking elements\n function findInteractive(el) {\n var current = el;\n for (var i = 0; i < 20 && current && current !== document.body && current !== document.documentElement; i++) {\n if (!current || !current.tagName) { current = current.parentElement; continue; }\n var tag = current.tagName.toLowerCase();\n\n // Skip tiny elements (likely icons inside buttons)\n var rect = current.getBoundingClientRect();\n if (rect.width < 20 || rect.height < 20) { current = current.parentElement; continue; }\n\n // Match standard interactive elements\n if (tag === 'button' || tag === 'a' || tag === 'input' || tag === 'select') return current;\n\n // Match elements with tap/click-related data attributes\n // Exclude lifecycle attributes like data-on-open-actions, data-on-close-actions\n var attrs = current.attributes;\n if (attrs) {\n for (var j = 0; j < attrs.length; j++) {\n var attrName = attrs[j].name.toLowerCase();\n // Skip lifecycle attributes (on-open, on-close, on-load, on-appear, etc.)\n if (attrName.indexOf('on-open') !== -1 || attrName.indexOf('on-close') !== -1 ||\n attrName.indexOf('on-load') !== -1 || attrName.indexOf('on-appear') !== -1 ||\n attrName.indexOf('onopen') !== -1 || attrName.indexOf('onclose') !== -1 ||\n attrName.indexOf('onload') !== -1 || attrName.indexOf('onappear') !== -1) {\n continue;\n }\n // Match tap/click interaction attributes\n if (attrName.indexOf('click') !== -1 || attrName.indexOf('tap') !== -1 ||\n attrName.indexOf('action') !== -1 || attrName.indexOf('navigate') !== -1 ||\n attrName.indexOf('press') !== -1) {\n return current;\n }\n }\n }\n\n // Match elements with onclick\n if (current.onclick || current.hasAttribute('onclick')) return current;\n\n // Match elements with role=\"button\"\n if (current.getAttribute('role') === 'button') return current;\n\n // Match any element with an ID containing button/btn/cta\n var id = current.id || '';\n if (id && (id.toLowerCase().indexOf('button') !== -1 || id.toLowerCase().indexOf('btn') !== -1 || id.toLowerCase().indexOf('cta') !== -1)) return current;\n\n // Match elements with button-like classes\n var className = current.className;\n if (className && typeof className === 'string') {\n var cls = className.toLowerCase();\n if (cls.indexOf('btn') !== -1 || cls.indexOf('button') !== -1 || cls.indexOf('cta') !== -1 ||\n cls.indexOf('clickable') !== -1 || cls.indexOf('tappable') !== -1 || cls.indexOf('pressable') !== -1) {\n return current;\n }\n }\n\n // Match elements with cursor pointer\n try {\n var computed = window.getComputedStyle(current);\n if (computed && computed.cursor === 'pointer') return current;\n } catch(e) {}\n\n current = current.parentElement;\n }\n return null;\n }\n\n function applyPressedStyle(el) {\n if (!el || !el.style) return;\n // Save original styles\n pressedOriginalTransform = el.style.transform || '';\n pressedOriginalOpacity = el.style.opacity || '';\n pressedOriginalTransition = el.style.transition || '';\n // Apply pressed style with inline styles for maximum specificity\n el.style.transition = 'transform 80ms cubic-bezier(0.25, 0.1, 0.25, 1), opacity 80ms cubic-bezier(0.25, 0.1, 0.25, 1)';\n el.style.transform = 'scale(0.97)';\n el.style.opacity = '0.8';\n }\n\n function applyReleasedStyle(el) {\n if (!el || !el.style) return;\n // Apply spring-back animation\n el.style.transition = 'transform 280ms cubic-bezier(0.34, 1.56, 0.64, 1), opacity 280ms cubic-bezier(0.34, 1.56, 0.64, 1)';\n el.style.transform = pressedOriginalTransform || 'scale(1)';\n el.style.opacity = pressedOriginalOpacity || '1';\n }\n\n function resetStyle(el) {\n if (!el || !el.style) return;\n el.style.transform = pressedOriginalTransform;\n el.style.opacity = pressedOriginalOpacity;\n el.style.transition = pressedOriginalTransition;\n }\n\n function onTouchStart(e) {\n try {\n var target = findInteractive(e.target);\n if (!target) return;\n if (releaseTimer) { clearTimeout(releaseTimer); releaseTimer = null; }\n if (pressed && pressed !== target) { resetStyle(pressed); }\n applyPressedStyle(target);\n pressed = target;\n } catch(err) {}\n }\n \n function onTouchEnd(e) {\n try {\n if (!pressed) return;\n var t = pressed;\n applyReleasedStyle(t);\n releaseTimer = setTimeout(function() {\n resetStyle(t);\n releaseTimer = null;\n }, 300);\n pressed = null;\n } catch(err) {}\n }\n \n function onTouchCancel(e) {\n try {\n if (!pressed) return;\n resetStyle(pressed);\n pressed = null;\n if (releaseTimer) { clearTimeout(releaseTimer); releaseTimer = null; }\n } catch(err) {}\n }\n \n // Use capture phase for immediate response before any other handlers\n document.addEventListener('touchstart', onTouchStart, { passive: true, capture: true });\n document.addEventListener('touchend', onTouchEnd, { passive: true, capture: true });\n document.addEventListener('touchcancel', onTouchCancel, { passive: true, capture: true });\n // Mouse events for testing\n document.addEventListener('mousedown', onTouchStart, { passive: true, capture: true });\n document.addEventListener('mouseup', onTouchEnd, { passive: true, capture: true });\n \n } catch (err) {}\n true;\n})();\n";
6
+ export declare const injectedButtonAnimations = "\n(function(){\n try {\n if (window.__rkButtonAnimApplied) return true;\n window.__rkButtonAnimApplied = true;\n\n var pressed = null;\n var pressedOriginalTransform = '';\n var pressedOriginalOpacity = '';\n var pressedOriginalTransition = '';\n var releaseTimer = null;\n\n // Find interactive element - looks for clickable-looking elements\n function findInteractive(el) {\n var current = el;\n for (var i = 0; i < 20 && current && current !== document.body && current !== document.documentElement; i++) {\n if (!current || !current.tagName) { current = current.parentElement; continue; }\n var tag = current.tagName.toLowerCase();\n\n // Skip tiny elements (likely icons inside buttons)\n var rect = current.getBoundingClientRect();\n if (rect.width < 20 || rect.height < 20) { current = current.parentElement; continue; }\n\n // Match standard interactive elements\n if (tag === 'button' || tag === 'a' || tag === 'input' || tag === 'select') return current;\n\n // Match elements with tap/click-related data attributes\n // Exclude lifecycle attributes like data-on-open-actions, data-on-close-actions\n var attrs = current.attributes;\n if (attrs) {\n for (var j = 0; j < attrs.length; j++) {\n var attrName = attrs[j].name.toLowerCase();\n // Skip lifecycle attributes (on-open, on-close, on-load, on-appear, etc.)\n // These are for screen lifecycle events, not user tap interactions\n var isLifecycleAttr = (attrName.indexOf('on-open') !== -1 || attrName.indexOf('on-close') !== -1 ||\n attrName.indexOf('on-load') !== -1 || attrName.indexOf('on-appear') !== -1 ||\n attrName.indexOf('onopen') !== -1 || attrName.indexOf('onclose') !== -1 ||\n attrName.indexOf('onload') !== -1 || attrName.indexOf('onappear') !== -1);\n if (isLifecycleAttr) {\n continue;\n }\n // Match tap/click interaction attributes\n if (attrName.indexOf('click') !== -1 || attrName.indexOf('tap') !== -1 ||\n attrName.indexOf('action') !== -1 || attrName.indexOf('navigate') !== -1 ||\n attrName.indexOf('press') !== -1) {\n return current;\n }\n }\n }\n\n // Match elements with onclick\n if (current.onclick || current.hasAttribute('onclick')) return current;\n\n // Match elements with role=\"button\"\n if (current.getAttribute('role') === 'button') return current;\n\n // Match any element with an ID containing button/btn/cta\n var id = current.id || '';\n if (id && (id.toLowerCase().indexOf('button') !== -1 || id.toLowerCase().indexOf('btn') !== -1 || id.toLowerCase().indexOf('cta') !== -1)) return current;\n\n // Match elements with button-like classes\n var className = current.className;\n if (className && typeof className === 'string') {\n var cls = className.toLowerCase();\n if (cls.indexOf('btn') !== -1 || cls.indexOf('button') !== -1 || cls.indexOf('cta') !== -1 ||\n cls.indexOf('clickable') !== -1 || cls.indexOf('tappable') !== -1 || cls.indexOf('pressable') !== -1) {\n return current;\n }\n }\n\n // Match elements with cursor pointer\n try {\n var computed = window.getComputedStyle(current);\n if (computed && computed.cursor === 'pointer') return current;\n } catch(e) {}\n\n current = current.parentElement;\n }\n return null;\n }\n\n function applyPressedStyle(el) {\n if (!el || !el.style) return;\n // Save original styles\n pressedOriginalTransform = el.style.transform || '';\n pressedOriginalOpacity = el.style.opacity || '';\n pressedOriginalTransition = el.style.transition || '';\n // Apply pressed style with inline styles for maximum specificity\n el.style.transition = 'transform 80ms cubic-bezier(0.25, 0.1, 0.25, 1), opacity 80ms cubic-bezier(0.25, 0.1, 0.25, 1)';\n el.style.transform = 'scale(0.97)';\n el.style.opacity = '0.8';\n }\n\n function applyReleasedStyle(el) {\n if (!el || !el.style) return;\n // Apply spring-back animation\n el.style.transition = 'transform 280ms cubic-bezier(0.34, 1.56, 0.64, 1), opacity 280ms cubic-bezier(0.34, 1.56, 0.64, 1)';\n el.style.transform = pressedOriginalTransform || 'scale(1)';\n el.style.opacity = pressedOriginalOpacity || '1';\n }\n\n function resetStyle(el) {\n if (!el || !el.style) return;\n el.style.transform = pressedOriginalTransform;\n el.style.opacity = pressedOriginalOpacity;\n el.style.transition = pressedOriginalTransition;\n }\n\n function onTouchStart(e) {\n try {\n var target = findInteractive(e.target);\n if (!target) return;\n if (releaseTimer) { clearTimeout(releaseTimer); releaseTimer = null; }\n if (pressed && pressed !== target) { resetStyle(pressed); }\n applyPressedStyle(target);\n pressed = target;\n } catch(err) {}\n }\n \n function onTouchEnd(e) {\n try {\n if (!pressed) return;\n var t = pressed;\n applyReleasedStyle(t);\n releaseTimer = setTimeout(function() {\n resetStyle(t);\n releaseTimer = null;\n }, 300);\n pressed = null;\n } catch(err) {}\n }\n \n function onTouchCancel(e) {\n try {\n if (!pressed) return;\n resetStyle(pressed);\n pressed = null;\n if (releaseTimer) { clearTimeout(releaseTimer); releaseTimer = null; }\n } catch(err) {}\n }\n \n // Use capture phase for immediate response before any other handlers\n document.addEventListener('touchstart', onTouchStart, { passive: true, capture: true });\n document.addEventListener('touchend', onTouchEnd, { passive: true, capture: true });\n document.addEventListener('touchcancel', onTouchCancel, { passive: true, capture: true });\n // Mouse events for testing\n document.addEventListener('mousedown', onTouchStart, { passive: true, capture: true });\n document.addEventListener('mouseup', onTouchEnd, { passive: true, capture: true });\n \n } catch (err) {}\n true;\n})();\n";
7
7
  export type ScreenPayload = {
8
8
  id: string;
9
9
  html: string;
@@ -406,10 +406,12 @@ exports.injectedButtonAnimations = `
406
406
  for (var j = 0; j < attrs.length; j++) {
407
407
  var attrName = attrs[j].name.toLowerCase();
408
408
  // Skip lifecycle attributes (on-open, on-close, on-load, on-appear, etc.)
409
- if (attrName.indexOf('on-open') !== -1 || attrName.indexOf('on-close') !== -1 ||
409
+ // These are for screen lifecycle events, not user tap interactions
410
+ var isLifecycleAttr = (attrName.indexOf('on-open') !== -1 || attrName.indexOf('on-close') !== -1 ||
410
411
  attrName.indexOf('on-load') !== -1 || attrName.indexOf('on-appear') !== -1 ||
411
412
  attrName.indexOf('onopen') !== -1 || attrName.indexOf('onclose') !== -1 ||
412
- attrName.indexOf('onload') !== -1 || attrName.indexOf('onappear') !== -1) {
413
+ attrName.indexOf('onload') !== -1 || attrName.indexOf('onappear') !== -1);
414
+ if (isLifecycleAttr) {
413
415
  continue;
414
416
  }
415
417
  // Match tap/click interaction attributes
@@ -1986,48 +1988,56 @@ function Overlay(props) {
1986
1988
  }
1987
1989
  if ((data === null || data === void 0 ? void 0 : data.type) === "rampkit:continue" ||
1988
1990
  (data === null || data === void 0 ? void 0 : data.type) === "continue") {
1989
- // Only process continue from the active screen
1991
+ const executeContinue = () => handleAdvance(i, (data === null || data === void 0 ? void 0 : data.animation) || "fade");
1992
+ // Queue if screen is not active (e.g., on-open actions during preload)
1990
1993
  if (!isScreenActive(i)) {
1991
1994
  if (__DEV__)
1992
- console.log(`[RampKit] Ignoring continue from inactive screen ${i}`);
1995
+ console.log(`[Rampkit] Queuing continue from inactive screen ${i}`);
1996
+ queueAction(i, executeContinue);
1993
1997
  return;
1994
1998
  }
1995
- handleAdvance(i, (data === null || data === void 0 ? void 0 : data.animation) || "fade");
1999
+ executeContinue();
1996
2000
  return;
1997
2001
  }
1998
2002
  if ((data === null || data === void 0 ? void 0 : data.type) === "rampkit:navigate") {
1999
- // Only process navigate from the active screen
2003
+ const target = data === null || data === void 0 ? void 0 : data.targetScreenId;
2004
+ const executeNavigate = () => {
2005
+ if (target === "__goBack__") {
2006
+ handleGoBack(i, (data === null || data === void 0 ? void 0 : data.animation) || "fade");
2007
+ return;
2008
+ }
2009
+ if (!target || target === "__continue__") {
2010
+ handleAdvance(i, (data === null || data === void 0 ? void 0 : data.animation) || "fade");
2011
+ return;
2012
+ }
2013
+ const targetIndex = props.screens.findIndex((s) => s.id === target);
2014
+ if (targetIndex >= 0) {
2015
+ navigateToIndex(targetIndex, (data === null || data === void 0 ? void 0 : data.animation) || "fade");
2016
+ }
2017
+ else {
2018
+ handleAdvance(i);
2019
+ }
2020
+ };
2021
+ // Queue if screen is not active (e.g., on-open actions during preload)
2000
2022
  if (!isScreenActive(i)) {
2001
2023
  if (__DEV__)
2002
- console.log(`[RampKit] Ignoring navigate from inactive screen ${i}`);
2003
- return;
2004
- }
2005
- const target = data === null || data === void 0 ? void 0 : data.targetScreenId;
2006
- if (target === "__goBack__") {
2007
- handleGoBack(i, (data === null || data === void 0 ? void 0 : data.animation) || "fade");
2008
- return;
2009
- }
2010
- if (!target || target === "__continue__") {
2011
- handleAdvance(i, (data === null || data === void 0 ? void 0 : data.animation) || "fade");
2024
+ console.log(`[Rampkit] Queuing navigate from inactive screen ${i}`);
2025
+ queueAction(i, executeNavigate);
2012
2026
  return;
2013
2027
  }
2014
- const targetIndex = props.screens.findIndex((s) => s.id === target);
2015
- if (targetIndex >= 0) {
2016
- navigateToIndex(targetIndex, (data === null || data === void 0 ? void 0 : data.animation) || "fade");
2017
- }
2018
- else {
2019
- handleAdvance(i);
2020
- }
2028
+ executeNavigate();
2021
2029
  return;
2022
2030
  }
2023
2031
  if ((data === null || data === void 0 ? void 0 : data.type) === "rampkit:goBack") {
2024
- // Only process goBack from the active screen
2032
+ const executeGoBack = () => handleGoBack(i, (data === null || data === void 0 ? void 0 : data.animation) || "fade");
2033
+ // Queue if screen is not active (e.g., on-open actions during preload)
2025
2034
  if (!isScreenActive(i)) {
2026
2035
  if (__DEV__)
2027
- console.log(`[RampKit] Ignoring goBack from inactive screen ${i}`);
2036
+ console.log(`[Rampkit] Queuing goBack from inactive screen ${i}`);
2037
+ queueAction(i, executeGoBack);
2028
2038
  return;
2029
2039
  }
2030
- handleGoBack(i, (data === null || data === void 0 ? void 0 : data.animation) || "fade");
2040
+ executeGoBack();
2031
2041
  return;
2032
2042
  }
2033
2043
  if ((data === null || data === void 0 ? void 0 : data.type) === "rampkit:close") {
@@ -2049,13 +2059,15 @@ function Overlay(props) {
2049
2059
  if (raw === "rampkit:tap" ||
2050
2060
  raw === "next" ||
2051
2061
  raw === "continue") {
2052
- // Only process from the active screen
2062
+ const executeAdvance = () => handleAdvance(i);
2063
+ // Queue if screen is not active (e.g., on-open actions during preload)
2053
2064
  if (!isScreenActive(i)) {
2054
2065
  if (__DEV__)
2055
- console.log(`[RampKit] Ignoring ${raw} from inactive screen ${i}`);
2066
+ console.log(`[Rampkit] Queuing ${raw} from inactive screen ${i}`);
2067
+ queueAction(i, executeAdvance);
2056
2068
  return;
2057
2069
  }
2058
- handleAdvance(i);
2070
+ executeAdvance();
2059
2071
  return;
2060
2072
  }
2061
2073
  if (raw === "rampkit:request-review" || raw === "rampkit:review") {
@@ -2109,38 +2121,44 @@ function Overlay(props) {
2109
2121
  return;
2110
2122
  }
2111
2123
  if (raw === "rampkit:goBack") {
2112
- // Only process from the active screen
2124
+ const executeGoBack = () => handleGoBack(i);
2125
+ // Queue if screen is not active (e.g., on-open actions during preload)
2113
2126
  if (!isScreenActive(i)) {
2114
2127
  if (__DEV__)
2115
- console.log(`[RampKit] Ignoring goBack (raw) from inactive screen ${i}`);
2128
+ console.log(`[Rampkit] Queuing goBack (raw) from inactive screen ${i}`);
2129
+ queueAction(i, executeGoBack);
2116
2130
  return;
2117
2131
  }
2118
- handleGoBack(i);
2132
+ executeGoBack();
2119
2133
  return;
2120
2134
  }
2121
2135
  if (raw.startsWith("rampkit:navigate:")) {
2122
- // Only process from the active screen
2136
+ const target = raw.slice("rampkit:navigate:".length);
2137
+ const executeNavigate = () => {
2138
+ if (target === "__goBack__") {
2139
+ handleGoBack(i);
2140
+ return;
2141
+ }
2142
+ if (!target || target === "__continue__") {
2143
+ handleAdvance(i);
2144
+ return;
2145
+ }
2146
+ const targetIndex = props.screens.findIndex((s) => s.id === target);
2147
+ if (targetIndex >= 0) {
2148
+ navigateToIndex(targetIndex);
2149
+ }
2150
+ else {
2151
+ handleAdvance(i);
2152
+ }
2153
+ };
2154
+ // Queue if screen is not active (e.g., on-open actions during preload)
2123
2155
  if (!isScreenActive(i)) {
2124
2156
  if (__DEV__)
2125
- console.log(`[RampKit] Ignoring navigate (raw) from inactive screen ${i}`);
2126
- return;
2127
- }
2128
- const target = raw.slice("rampkit:navigate:".length);
2129
- if (target === "__goBack__") {
2130
- handleGoBack(i);
2131
- return;
2132
- }
2133
- if (!target || target === "__continue__") {
2134
- handleAdvance(i);
2157
+ console.log(`[Rampkit] Queuing navigate (raw) from inactive screen ${i}`);
2158
+ queueAction(i, executeNavigate);
2135
2159
  return;
2136
2160
  }
2137
- const targetIndex = props.screens.findIndex((s) => s.id === target);
2138
- if (targetIndex >= 0) {
2139
- navigateToIndex(targetIndex);
2140
- }
2141
- else {
2142
- handleAdvance(i);
2143
- }
2161
+ executeNavigate();
2144
2162
  return;
2145
2163
  }
2146
2164
  if (raw === "rampkit:close") {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rampkit-expo-dev",
3
- "version": "0.0.84",
3
+ "version": "0.0.85",
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",