@mobana/react-native-sdk 0.2.10

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.
Files changed (96) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +249 -0
  3. package/android/build.gradle +50 -0
  4. package/android/src/main/AndroidManifest.xml +6 -0
  5. package/android/src/main/java/ai/mobana/sdk/MobanaModule.kt +67 -0
  6. package/android/src/main/java/ai/mobana/sdk/MobanaPackage.kt +19 -0
  7. package/app.plugin.js +274 -0
  8. package/ios/Mobana.h +11 -0
  9. package/ios/Mobana.m +20 -0
  10. package/lib/commonjs/Mobana.js +676 -0
  11. package/lib/commonjs/Mobana.js.map +1 -0
  12. package/lib/commonjs/NativeMobana.js +53 -0
  13. package/lib/commonjs/NativeMobana.js.map +1 -0
  14. package/lib/commonjs/api.js +201 -0
  15. package/lib/commonjs/api.js.map +1 -0
  16. package/lib/commonjs/bridge/index.js +19 -0
  17. package/lib/commonjs/bridge/index.js.map +1 -0
  18. package/lib/commonjs/bridge/injectBridge.js +528 -0
  19. package/lib/commonjs/bridge/injectBridge.js.map +1 -0
  20. package/lib/commonjs/components/FlowWebView.js +676 -0
  21. package/lib/commonjs/components/FlowWebView.js.map +1 -0
  22. package/lib/commonjs/components/MobanaProvider.js +275 -0
  23. package/lib/commonjs/components/MobanaProvider.js.map +1 -0
  24. package/lib/commonjs/components/index.js +20 -0
  25. package/lib/commonjs/components/index.js.map +1 -0
  26. package/lib/commonjs/device.js +49 -0
  27. package/lib/commonjs/device.js.map +1 -0
  28. package/lib/commonjs/index.js +20 -0
  29. package/lib/commonjs/index.js.map +1 -0
  30. package/lib/commonjs/package.json +1 -0
  31. package/lib/commonjs/storage.js +277 -0
  32. package/lib/commonjs/storage.js.map +1 -0
  33. package/lib/commonjs/types.js +2 -0
  34. package/lib/commonjs/types.js.map +1 -0
  35. package/lib/module/Mobana.js +673 -0
  36. package/lib/module/Mobana.js.map +1 -0
  37. package/lib/module/NativeMobana.js +49 -0
  38. package/lib/module/NativeMobana.js.map +1 -0
  39. package/lib/module/api.js +194 -0
  40. package/lib/module/api.js.map +1 -0
  41. package/lib/module/bridge/index.js +4 -0
  42. package/lib/module/bridge/index.js.map +1 -0
  43. package/lib/module/bridge/injectBridge.js +523 -0
  44. package/lib/module/bridge/injectBridge.js.map +1 -0
  45. package/lib/module/components/FlowWebView.js +672 -0
  46. package/lib/module/components/FlowWebView.js.map +1 -0
  47. package/lib/module/components/MobanaProvider.js +270 -0
  48. package/lib/module/components/MobanaProvider.js.map +1 -0
  49. package/lib/module/components/index.js +5 -0
  50. package/lib/module/components/index.js.map +1 -0
  51. package/lib/module/device.js +45 -0
  52. package/lib/module/device.js.map +1 -0
  53. package/lib/module/index.js +53 -0
  54. package/lib/module/index.js.map +1 -0
  55. package/lib/module/storage.js +257 -0
  56. package/lib/module/storage.js.map +1 -0
  57. package/lib/module/types.js +2 -0
  58. package/lib/module/types.js.map +1 -0
  59. package/lib/typescript/Mobana.d.ts +209 -0
  60. package/lib/typescript/Mobana.d.ts.map +1 -0
  61. package/lib/typescript/NativeMobana.d.ts +11 -0
  62. package/lib/typescript/NativeMobana.d.ts.map +1 -0
  63. package/lib/typescript/api.d.ts +34 -0
  64. package/lib/typescript/api.d.ts.map +1 -0
  65. package/lib/typescript/bridge/index.d.ts +3 -0
  66. package/lib/typescript/bridge/index.d.ts.map +1 -0
  67. package/lib/typescript/bridge/injectBridge.d.ts +23 -0
  68. package/lib/typescript/bridge/injectBridge.d.ts.map +1 -0
  69. package/lib/typescript/components/FlowWebView.d.ts +38 -0
  70. package/lib/typescript/components/FlowWebView.d.ts.map +1 -0
  71. package/lib/typescript/components/MobanaProvider.d.ts +65 -0
  72. package/lib/typescript/components/MobanaProvider.d.ts.map +1 -0
  73. package/lib/typescript/components/index.d.ts +5 -0
  74. package/lib/typescript/components/index.d.ts.map +1 -0
  75. package/lib/typescript/device.d.ts +6 -0
  76. package/lib/typescript/device.d.ts.map +1 -0
  77. package/lib/typescript/index.d.ts +46 -0
  78. package/lib/typescript/index.d.ts.map +1 -0
  79. package/lib/typescript/storage.d.ts +68 -0
  80. package/lib/typescript/storage.d.ts.map +1 -0
  81. package/lib/typescript/types.d.ts +298 -0
  82. package/lib/typescript/types.d.ts.map +1 -0
  83. package/mobana.podspec +19 -0
  84. package/package.json +131 -0
  85. package/src/Mobana.ts +742 -0
  86. package/src/NativeMobana.ts +61 -0
  87. package/src/api.ts +259 -0
  88. package/src/bridge/index.ts +2 -0
  89. package/src/bridge/injectBridge.ts +542 -0
  90. package/src/components/FlowWebView.tsx +826 -0
  91. package/src/components/MobanaProvider.tsx +393 -0
  92. package/src/components/index.ts +4 -0
  93. package/src/device.ts +42 -0
  94. package/src/index.ts +66 -0
  95. package/src/storage.ts +262 -0
  96. package/src/types.ts +362 -0
@@ -0,0 +1,65 @@
1
+ import React, { ReactNode } from 'react';
2
+ import type { WebViewProps } from 'react-native-webview';
3
+ import type { ModalProps } from 'react-native';
4
+ import type { FlowConfig, FlowResult, FlowOptions, Attribution } from '../types';
5
+ /**
6
+ * Internal flow request from SDK
7
+ */
8
+ export interface FlowRequest {
9
+ slug: string;
10
+ config: FlowConfig;
11
+ installId: string;
12
+ endpoint: string;
13
+ appKey: string;
14
+ attribution: Attribution | null;
15
+ options?: FlowOptions;
16
+ resolve: (result: FlowResult) => void;
17
+ debug?: boolean;
18
+ }
19
+ /**
20
+ * Context for flow presentation
21
+ */
22
+ interface FlowContextValue {
23
+ presentFlow: (request: FlowRequest) => void;
24
+ isProviderMounted: boolean;
25
+ }
26
+ export declare function getGlobalFlowContext(): FlowContextValue | null;
27
+ /**
28
+ * Props for MobanaProvider
29
+ */
30
+ export interface MobanaProviderProps {
31
+ children: ReactNode;
32
+ /**
33
+ * Custom props for the Modal component
34
+ */
35
+ modalProps?: Partial<ModalProps>;
36
+ /**
37
+ * Custom props for the WebView component
38
+ */
39
+ webViewProps?: Partial<WebViewProps>;
40
+ /**
41
+ * Custom loading component to show while flow is loading
42
+ */
43
+ loadingComponent?: ReactNode;
44
+ }
45
+ /**
46
+ * Provider component for Mobana flows
47
+ *
48
+ * Wrap your app with this component to enable flow presentation:
49
+ *
50
+ * @example
51
+ * ```tsx
52
+ * import { MobanaProvider } from '@mobana/react-native-sdk';
53
+ *
54
+ * export default function App() {
55
+ * return (
56
+ * <MobanaProvider>
57
+ * <YourApp />
58
+ * </MobanaProvider>
59
+ * );
60
+ * }
61
+ * ```
62
+ */
63
+ export declare function MobanaProvider({ children, modalProps, webViewProps, loadingComponent, }: MobanaProviderProps): React.JSX.Element;
64
+ export {};
65
+ //# sourceMappingURL=MobanaProvider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MobanaProvider.d.ts","sourceRoot":"","sources":["../../../src/components/MobanaProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAMZ,SAAS,EACV,MAAM,OAAO,CAAC;AAUf,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAgCjF;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,UAAU,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,WAAW,GAAG,IAAI,CAAC;IAChC,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,OAAO,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,IAAI,CAAC;IACtC,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;GAEG;AACH,UAAU,gBAAgB;IACxB,WAAW,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,IAAI,CAAC;IAC5C,iBAAiB,EAAE,OAAO,CAAC;CAC5B;AASD,wBAAgB,oBAAoB,IAAI,gBAAgB,GAAG,IAAI,CAE9D;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,SAAS,CAAC;IACpB;;OAEG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;IACjC;;OAEG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IACrC;;OAEG;IACH,gBAAgB,CAAC,EAAE,SAAS,CAAC;CAC9B;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,cAAc,CAAC,EAC7B,QAAQ,EACR,UAAU,EACV,YAAY,EACZ,gBAAgB,GACjB,EAAE,mBAAmB,qBA8PrB"}
@@ -0,0 +1,5 @@
1
+ export { MobanaProvider } from './MobanaProvider';
2
+ export type { MobanaProviderProps } from './MobanaProvider';
3
+ export { FlowWebView } from './FlowWebView';
4
+ export type { FlowWebViewProps } from './FlowWebView';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,YAAY,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,YAAY,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC"}
@@ -0,0 +1,6 @@
1
+ import type { DeviceInfo } from './types';
2
+ /**
3
+ * Collect device information for attribution matching
4
+ */
5
+ export declare function getDeviceInfo(): DeviceInfo;
6
+ //# sourceMappingURL=device.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"device.d.ts","sourceRoot":"","sources":["../../src/device.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAE1C;;GAEG;AACH,wBAAgB,aAAa,IAAI,UAAU,CAU1C"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * @mobana/react-native-sdk
3
+ *
4
+ * Simple, privacy-focused mobile app attribution, conversions, and remote flows.
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * import { Mobana, MobanaProvider } from '@mobana/react-native-sdk';
9
+ *
10
+ * // 1. Wrap your app with the provider (in App.tsx)
11
+ * function App() {
12
+ * return (
13
+ * <MobanaProvider>
14
+ * <YourApp />
15
+ * </MobanaProvider>
16
+ * );
17
+ * }
18
+ *
19
+ * // 2. Initialize the SDK
20
+ * await Mobana.init({ appId: 'a1b2c3d4' });
21
+ *
22
+ * // 3. Get attribution
23
+ * const attribution = await Mobana.getAttribution();
24
+ *
25
+ * // 4. Track conversions
26
+ * Mobana.trackConversion('signup');
27
+ * Mobana.trackConversion('purchase', 49.99);
28
+ *
29
+ * // 5. Show flows and track post-flow events
30
+ * const result = await Mobana.startFlow('onboarding');
31
+ * if (result.completed) {
32
+ * // Track events after flow closes using result.trackEvent()
33
+ * await result.trackEvent('feature_used');
34
+ * // Link conversions to flow session using result.sessionId
35
+ * await Mobana.trackConversion('purchase', 9.99, result.sessionId);
36
+ * }
37
+ * ```
38
+ *
39
+ * @packageDocumentation
40
+ */
41
+ export { Mobana } from './Mobana';
42
+ export { MobanaProvider } from './components/MobanaProvider';
43
+ export type { MobanaProviderProps } from './components/MobanaProvider';
44
+ export type { MobanaConfig, GetAttributionOptions, Attribution, } from './types';
45
+ export type { FlowConfig, FlowResult, FlowOptions, FlowError, HapticStyle, LocationPermissionStatus, ATTStatus, LocationCoordinates, } from './types';
46
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAGH,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAGlC,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,YAAY,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAGvE,YAAY,EACV,YAAY,EACZ,qBAAqB,EACrB,WAAW,GACZ,MAAM,SAAS,CAAC;AAGjB,YAAY,EACV,UAAU,EACV,UAAU,EACV,WAAW,EACX,SAAS,EACT,WAAW,EACX,wBAAwB,EACxB,SAAS,EACT,mBAAmB,GACpB,MAAM,SAAS,CAAC"}
@@ -0,0 +1,68 @@
1
+ import type { Attribution, CachedAttributionResult, ConversionEvent, CachedFlow } from './types';
2
+ /**
3
+ * Get or create a stable install ID (UUID)
4
+ * Generated once on first launch and persisted locally
5
+ */
6
+ export declare function getInstallId(): Promise<string>;
7
+ /**
8
+ * Get cached attribution result (includes matched: false responses)
9
+ */
10
+ export declare function getCachedResult<T = Record<string, unknown>>(): Promise<CachedAttributionResult<T> | null>;
11
+ /**
12
+ * Store attribution result in cache (stores both matched and unmatched responses)
13
+ */
14
+ export declare function setCachedResult<T = Record<string, unknown>>(matched: boolean, attribution?: Attribution<T>): Promise<void>;
15
+ /**
16
+ * Clear all stored attribution data (for testing/reset)
17
+ */
18
+ export declare function clearAttribution(): Promise<void>;
19
+ /**
20
+ * Queue a conversion event for later sending (offline support)
21
+ */
22
+ export declare function queueConversion(event: ConversionEvent): Promise<void>;
23
+ /**
24
+ * Get all queued conversion events
25
+ */
26
+ export declare function getConversionQueue(): Promise<ConversionEvent[]>;
27
+ /**
28
+ * Clear the conversion queue after successful send
29
+ */
30
+ export declare function clearConversionQueue(): Promise<void>;
31
+ /**
32
+ * Generate a UUID v4
33
+ * Uses crypto.getRandomValues when available (Hermes 0.73+), falls back to Math.random
34
+ */
35
+ export declare function generateUUID(): string;
36
+ /**
37
+ * Get cached flow content by slug
38
+ */
39
+ export declare function getCachedFlow(slug: string): Promise<CachedFlow | null>;
40
+ /**
41
+ * Cache flow content
42
+ */
43
+ export declare function setCachedFlow(slug: string, flow: Omit<CachedFlow, 'cachedAt'>): Promise<void>;
44
+ /**
45
+ * Clear cached flow by slug
46
+ */
47
+ export declare function clearCachedFlow(slug: string): Promise<void>;
48
+ /**
49
+ * Clear all cached flows
50
+ */
51
+ export declare function clearAllCachedFlows(): Promise<void>;
52
+ /**
53
+ * Get all local data
54
+ */
55
+ export declare function getAllLocalData(): Promise<Record<string, unknown>>;
56
+ /**
57
+ * Store data locally on device (persists across app sessions)
58
+ */
59
+ export declare function setLocalData(key: string, value: unknown): Promise<void>;
60
+ /**
61
+ * Retrieve locally stored data
62
+ */
63
+ export declare function getLocalData(key: string): Promise<unknown>;
64
+ /**
65
+ * Clear all local data
66
+ */
67
+ export declare function clearLocalData(): Promise<void>;
68
+ //# sourceMappingURL=storage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../src/storage.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,uBAAuB,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAWjG;;;GAGG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC,CAgBpD;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,uBAAuB,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAU/G;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/D,OAAO,EAAE,OAAO,EAChB,WAAW,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,GAC3B,OAAO,CAAC,IAAI,CAAC,CAWf;AAED;;GAEG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAMtD;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAQ3E;AAED;;GAEG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC,CAUrE;AAED;;GAEG;AACH,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC,CAM1D;AAED;;;GAGG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAqBrC;AAMD;;GAEG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAW5E;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,UAAU,EAAE,UAAU,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAWnG;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAOjE;AAED;;GAEG;AACH,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC,CAUzD;AAMD;;GAEG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAUxE;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAQ7E;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAOhE;AAED;;GAEG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CAMpD"}
@@ -0,0 +1,298 @@
1
+ /**
2
+ * Configuration options for Mobana SDK
3
+ */
4
+ export interface MobanaConfig {
5
+ /**
6
+ * Your Mobana app ID from the dashboard (e.g., 'a1b2c3d4')
7
+ * Required.
8
+ */
9
+ appId: string;
10
+ /**
11
+ * Your Mobana app key from the dashboard. Sent as X-App-Key header.
12
+ * Required. Regenerate from dashboard if leaked.
13
+ */
14
+ appKey: string;
15
+ /**
16
+ * Custom endpoint URL for attribution API
17
+ * Optional. Use this if proxying through your own domain (e.g., 'https://myapp.com/d')
18
+ * If not set, defaults to https://{appId}.mobana.ai
19
+ */
20
+ endpoint?: string;
21
+ /**
22
+ * Enable or disable the SDK (default: true)
23
+ * Set to false to disable all attribution tracking (e.g., for GDPR opt-out)
24
+ */
25
+ enabled?: boolean;
26
+ /**
27
+ * Enable debug logging (default: false)
28
+ * When true, logs SDK operations to console
29
+ */
30
+ debug?: boolean;
31
+ }
32
+ /**
33
+ * Flow content returned from the API
34
+ */
35
+ export interface FlowConfig {
36
+ /** Unique version identifier (immutable) */
37
+ versionId: string;
38
+ /** HTML content of the flow */
39
+ html: string;
40
+ /** CSS styles (may be embedded in HTML) */
41
+ css?: string;
42
+ /** JavaScript code (may be embedded in HTML) */
43
+ js?: string;
44
+ }
45
+ /**
46
+ * Result returned from startFlow()
47
+ */
48
+ export interface FlowResult {
49
+ /** Whether the flow was completed (user called Mobana.complete()) */
50
+ completed: boolean;
51
+ /** Whether the flow was dismissed (user called Mobana.dismiss()) */
52
+ dismissed: boolean;
53
+ /** Error code if flow couldn't be shown */
54
+ error?: FlowError;
55
+ /** Custom data passed to Mobana.complete(data) */
56
+ data?: Record<string, unknown>;
57
+ /** Session ID for this flow presentation (use with trackConversion's flowSessionId) */
58
+ sessionId?: string;
59
+ /**
60
+ * Track a custom event for this flow session after the flow has closed.
61
+ * Useful for tracking events that happen after the flow (e.g., purchase after onboarding).
62
+ *
63
+ * @param event - Event name (e.g., 'purchase_completed', 'feature_used')
64
+ * @param data - Optional event data (will be stored as JSON)
65
+ * @returns Promise resolving to true if event was tracked successfully
66
+ *
67
+ * @example
68
+ * ```typescript
69
+ * const result = await Mobana.startFlow('pre-purchase');
70
+ * // ... user makes purchase via Adapty ...
71
+ * await result.trackEvent('purchase_initiated');
72
+ * ```
73
+ */
74
+ trackEvent?: (event: string, data?: Record<string, unknown>) => Promise<boolean>;
75
+ }
76
+ /**
77
+ * Possible flow error codes
78
+ */
79
+ export type FlowError = 'NOT_FOUND' | 'PLAN_REQUIRED' | 'FLOW_LIMIT_EXCEEDED' | 'NETWORK_ERROR' | 'SERVER_ERROR' | 'PROVIDER_NOT_MOUNTED' | 'SDK_NOT_CONFIGURED';
80
+ /**
81
+ * Options for startFlow()
82
+ */
83
+ export interface FlowOptions {
84
+ /**
85
+ * Custom parameters available in the flow via Mobana.getParams()
86
+ * Use this to pass context to your flow (e.g., user name, feature flags)
87
+ */
88
+ params?: Record<string, unknown>;
89
+ /**
90
+ * Callback when flow emits custom events via Mobana.trackEvent()
91
+ * Useful for analytics integration
92
+ */
93
+ onEvent?: (event: string) => void;
94
+ /**
95
+ * Async callback invoked when the flow calls Mobana.requestCallback(data).
96
+ * Allows the flow to request the app to perform an action (e.g., trigger a purchase,
97
+ * validate a promo code) and await the result — without closing the flow.
98
+ *
99
+ * @param data - Arbitrary data sent from the flow
100
+ * @returns Promise resolving to arbitrary data returned to the flow
101
+ *
102
+ * @example
103
+ * ```typescript
104
+ * const result = await Mobana.startFlow('paywall', {
105
+ * onCallback: async (data) => {
106
+ * if (data.action === 'purchase') {
107
+ * const purchase = await purchaseManager.buy(data.planId);
108
+ * return { success: purchase.success, receipt: purchase.receipt };
109
+ * }
110
+ * return { error: 'Unknown action' };
111
+ * },
112
+ * });
113
+ * ```
114
+ */
115
+ onCallback?: (data: Record<string, unknown>) => Promise<Record<string, unknown>>;
116
+ }
117
+ /**
118
+ * Cached flow content (stored in AsyncStorage)
119
+ */
120
+ export interface CachedFlow {
121
+ versionId: string;
122
+ html: string;
123
+ css?: string;
124
+ js?: string;
125
+ cachedAt: number;
126
+ }
127
+ /**
128
+ * API response from GET /api/flows/[slug]
129
+ */
130
+ export interface FlowFetchResponse {
131
+ /** True if client's cached version is still current */
132
+ cached?: boolean;
133
+ /** Version ID (always present if not an error) */
134
+ versionId?: string;
135
+ /** HTML content (present if not cached) */
136
+ html?: string;
137
+ /** CSS content (present if not cached) */
138
+ css?: string;
139
+ /** JS content (present if not cached) */
140
+ js?: string;
141
+ /** Error code if flow unavailable */
142
+ error?: string;
143
+ }
144
+ /**
145
+ * Flow event to send to the server
146
+ */
147
+ export interface FlowEvent {
148
+ installId: string;
149
+ versionId: string;
150
+ sessionId: string;
151
+ event: string;
152
+ step?: number;
153
+ data?: unknown;
154
+ }
155
+ /**
156
+ * Haptic feedback styles
157
+ */
158
+ export type HapticStyle = 'light' | 'medium' | 'heavy' | 'success' | 'warning' | 'error' | 'selection';
159
+ /**
160
+ * Location permission status
161
+ */
162
+ export type LocationPermissionStatus = 'granted' | 'denied' | 'blocked' | 'unavailable' | 'limited';
163
+ /**
164
+ * ATT (App Tracking Transparency) status (iOS only)
165
+ */
166
+ export type ATTStatus = 'authorized' | 'denied' | 'not-determined' | 'restricted';
167
+ /**
168
+ * Device color scheme (light/dark mode)
169
+ */
170
+ export type ColorScheme = 'light' | 'dark';
171
+ /**
172
+ * Location coordinates
173
+ */
174
+ export interface LocationCoordinates {
175
+ latitude: number;
176
+ longitude: number;
177
+ accuracy: number;
178
+ altitude: number | null;
179
+ altitudeAccuracy: number | null;
180
+ heading: number | null;
181
+ speed: number | null;
182
+ timestamp: number;
183
+ }
184
+ /**
185
+ * Message from WebView to native
186
+ */
187
+ export interface BridgeMessage {
188
+ type: string;
189
+ requestId?: number;
190
+ payload?: any;
191
+ }
192
+ /**
193
+ * Options for getAttribution call
194
+ */
195
+ export interface GetAttributionOptions {
196
+ /**
197
+ * Timeout in milliseconds for the attribution request (default: 10000)
198
+ */
199
+ timeout?: number;
200
+ }
201
+ /**
202
+ * Attribution data returned from the API
203
+ */
204
+ export interface Attribution<T = Record<string, unknown>> {
205
+ /**
206
+ * Traffic source (e.g., 'facebook', 'google', 'tiktok')
207
+ */
208
+ utm_source?: string;
209
+ /**
210
+ * Marketing medium (e.g., 'cpc', 'social', 'email')
211
+ */
212
+ utm_medium?: string;
213
+ /**
214
+ * Campaign name
215
+ */
216
+ utm_campaign?: string;
217
+ /**
218
+ * Ad content identifier
219
+ */
220
+ utm_content?: string;
221
+ /**
222
+ * Search keywords
223
+ */
224
+ utm_term?: string;
225
+ /**
226
+ * Referring domain that sent the user to the tracking link (e.g., 'facebook.com')
227
+ * Only the domain is stored (not the full URL) for privacy.
228
+ */
229
+ referrer_domain?: string;
230
+ /**
231
+ * Custom deeplink data passed through the attribution flow
232
+ * Use generics for type-safe access: getAttribution<MyDataType>()
233
+ */
234
+ data?: T;
235
+ /**
236
+ * Match confidence score (0.0 - 1.0)
237
+ * - 1.0 = Deterministic match via Android Install Referrer
238
+ * - < 1.0 = Probabilistic match
239
+ */
240
+ confidence: number;
241
+ }
242
+ /**
243
+ * Internal: API response from /find endpoint
244
+ */
245
+ export interface FindResponse<T = Record<string, unknown>> {
246
+ matched: boolean;
247
+ attribution?: Attribution<T>;
248
+ confidence?: number;
249
+ }
250
+ /**
251
+ * Internal: Cached attribution result (includes matched: false responses)
252
+ */
253
+ export interface CachedAttributionResult<T = Record<string, unknown>> {
254
+ matched: boolean;
255
+ attribution?: Attribution<T>;
256
+ checkedAt: number;
257
+ }
258
+ /**
259
+ * Internal: Conversion event to be sent or queued
260
+ */
261
+ export interface ConversionEvent {
262
+ installId: string;
263
+ name: string;
264
+ value?: number;
265
+ timestamp: number;
266
+ /** Optional flow session ID to link conversion to a specific flow presentation */
267
+ flowSessionId?: string;
268
+ }
269
+ /**
270
+ * Internal: Device info collected for attribution matching
271
+ */
272
+ export interface DeviceInfo {
273
+ platform: 'ios' | 'android';
274
+ timezone?: string;
275
+ screenWidth?: number;
276
+ screenHeight?: number;
277
+ language?: string;
278
+ }
279
+ /**
280
+ * Safe area insets for the device screen
281
+ * Represents the areas of the screen that may be obscured by system UI
282
+ * (status bar, notch/dynamic island, home indicator, etc.)
283
+ */
284
+ export interface SafeArea {
285
+ /** Inset from top (status bar, notch, dynamic island) in points */
286
+ top: number;
287
+ /** Inset from bottom (home indicator, navigation bar) in points */
288
+ bottom: number;
289
+ /** Inset from left (typically 0, but can be non-zero in landscape) in points */
290
+ left: number;
291
+ /** Inset from right (typically 0, but can be non-zero in landscape) in points */
292
+ right: number;
293
+ /** Full screen width in points */
294
+ width: number;
295
+ /** Full screen height in points */
296
+ height: number;
297
+ }
298
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}
package/mobana.podspec ADDED
@@ -0,0 +1,19 @@
1
+ require 'json'
2
+
3
+ package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
4
+
5
+ Pod::Spec.new do |s|
6
+ s.name = "mobana"
7
+ s.version = package['version']
8
+ s.summary = package['description']
9
+ s.homepage = package['homepage']
10
+ s.license = package['license']
11
+ s.authors = package['author']
12
+
13
+ s.platforms = { :ios => "13.0" }
14
+ s.source = { :git => package['repository']['url'], :tag => "#{s.version}" }
15
+
16
+ s.source_files = "ios/**/*.{h,m,mm,swift}"
17
+
18
+ s.dependency "React-Core"
19
+ end
package/package.json ADDED
@@ -0,0 +1,131 @@
1
+ {
2
+ "name": "@mobana/react-native-sdk",
3
+ "version": "0.2.10",
4
+ "description": "React Native SDK for Mobana — Simple mobile app attribution, deeplinking, and dynamic remote flows",
5
+ "main": "lib/commonjs/index.js",
6
+ "module": "lib/module/index.js",
7
+ "types": "lib/typescript/index.d.ts",
8
+ "react-native": "src/index.ts",
9
+ "source": "src/index.ts",
10
+ "files": [
11
+ "src",
12
+ "lib",
13
+ "android",
14
+ "ios",
15
+ "app.plugin.js",
16
+ "mobana.podspec",
17
+ "!**/__tests__",
18
+ "!**/__fixtures__",
19
+ "!**/__mocks__",
20
+ "!lib/typescript/example"
21
+ ],
22
+ "scripts": {
23
+ "build": "bob build",
24
+ "typecheck": "tsc --noEmit",
25
+ "test": "jest",
26
+ "test:watch": "jest --watch",
27
+ "clean": "del-cli lib android/build ios/build",
28
+ "prepare": "bob build"
29
+ },
30
+ "keywords": [
31
+ "react-native",
32
+ "attribution",
33
+ "app-attribution",
34
+ "mobile-attribution",
35
+ "deeplinking",
36
+ "deep-link",
37
+ "universal-links",
38
+ "app-links",
39
+ "mobile",
40
+ "analytics",
41
+ "install-referrer",
42
+ "utm",
43
+ "referral",
44
+ "onboarding",
45
+ "in-app-flows",
46
+ "fingerprinting",
47
+ "mobana"
48
+ ],
49
+ "repository": {
50
+ "type": "git",
51
+ "url": "https://github.com/mobana-hq/react-native-sdk.git"
52
+ },
53
+ "author": "Mobana",
54
+ "license": "MIT",
55
+ "bugs": {
56
+ "url": "https://github.com/mobana-hq/react-native-sdk/issues"
57
+ },
58
+ "homepage": "https://mobana.ai",
59
+ "publishConfig": {
60
+ "access": "public"
61
+ },
62
+ "peerDependencies": {
63
+ "@react-native-async-storage/async-storage": ">=1.17.0",
64
+ "react": ">=17.0.0",
65
+ "react-native": ">=0.72.0",
66
+ "react-native-geolocation-service": ">=5.0.0",
67
+ "react-native-haptic-feedback": ">=2.0.0",
68
+ "react-native-in-app-review": ">=4.0.0",
69
+ "react-native-permissions": ">=4.0.0",
70
+ "react-native-safe-area-context": ">=4.0.0",
71
+ "react-native-webview": ">=13.0.0"
72
+ },
73
+ "peerDependenciesMeta": {
74
+ "@react-native-async-storage/async-storage": {
75
+ "optional": false
76
+ },
77
+ "react-native-geolocation-service": {
78
+ "optional": true
79
+ },
80
+ "react-native-haptic-feedback": {
81
+ "optional": true
82
+ },
83
+ "react-native-in-app-review": {
84
+ "optional": true
85
+ },
86
+ "react-native-permissions": {
87
+ "optional": true
88
+ },
89
+ "react-native-safe-area-context": {
90
+ "optional": true
91
+ },
92
+ "react-native-webview": {
93
+ "optional": true
94
+ }
95
+ },
96
+ "devDependencies": {
97
+ "@react-native-async-storage/async-storage": "^1.21.0",
98
+ "@types/jest": "^30.0.0",
99
+ "@types/react": "^19.1.0",
100
+ "del-cli": "^7.0.0",
101
+ "jest": "^29.7.0",
102
+ "react": "^19.1.0",
103
+ "react-native": "^0.84.0",
104
+ "react-native-builder-bob": "^0.40.0",
105
+ "react-native-geolocation-service": "^5.3.1",
106
+ "react-native-haptic-feedback": "^2.2.0",
107
+ "react-native-in-app-review": "^4.3.3",
108
+ "react-native-permissions": "^4.1.5",
109
+ "react-native-safe-area-context": "^4.10.0",
110
+ "react-native-webview": "^13.6.0",
111
+ "ts-jest": "^29.4.6",
112
+ "typescript": "^5.3.0"
113
+ },
114
+ "overrides": {
115
+ "minimatch": "^10.2.1"
116
+ },
117
+ "react-native-builder-bob": {
118
+ "source": "src",
119
+ "output": "lib",
120
+ "targets": [
121
+ "commonjs",
122
+ "module",
123
+ [
124
+ "typescript",
125
+ {
126
+ "project": "tsconfig.build.json"
127
+ }
128
+ ]
129
+ ]
130
+ }
131
+ }