expo-helium 0.8.2 → 0.8.3
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/README.md +18 -125
- package/build/HeliumPaywallSdk.types.d.ts +3 -0
- package/build/HeliumPaywallSdk.types.d.ts.map +1 -1
- package/build/HeliumPaywallSdk.types.js.map +1 -1
- package/build/HeliumPaywallSdkModule.d.ts +6 -0
- package/build/HeliumPaywallSdkModule.d.ts.map +1 -1
- package/build/HeliumPaywallSdkModule.js.map +1 -1
- package/build/index.d.ts +1 -0
- package/build/index.d.ts.map +1 -1
- package/build/index.js +36 -5
- package/build/index.js.map +1 -1
- package/ios/HeliumPaywallSdk.podspec +1 -1
- package/ios/HeliumPaywallSdkModule.swift +65 -1
- package/package.json +1 -1
- package/src/HeliumPaywallSdk.types.ts +3 -0
- package/src/HeliumPaywallSdkModule.ts +9 -0
- package/src/index.ts +46 -6
package/README.md
CHANGED
|
@@ -1,139 +1,32 @@
|
|
|
1
1
|
# helium-expo-sdk
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Helium is an upsell experimentation and optimization platform for mobile apps of all sizes.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## How to Integrate
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Follow our [official documentation here](https://docs.tryhelium.com/sdk/quickstart-react-native) to integrate Helium into your Expo / React Native app!
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
## Contributing
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
Helpful: expo [module documentation here](https://docs.expo.dev/modules/native-module-tutorial/) and [API here](https://docs.expo.dev/modules/module-api/)
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
npx expo install expo-helium
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
We recommend using Expo 53 and up.
|
|
18
|
-
|
|
19
|
-
## **Configuration**
|
|
20
|
-
|
|
21
|
-
### Initialization
|
|
22
|
-
|
|
23
|
-
Initialize Helium by calling `initialize()` early in your app's lifecycle, typically in your root component.
|
|
24
|
-
`initialize` takes in a configuration object that includes your purchase config, event handlers, and other settings. (If you are using **RevenueCat**, skip to the next section.)
|
|
25
|
-
|
|
26
|
-
```tsx
|
|
27
|
-
import { initialize, createCustomPurchaseConfig, HELIUM_CTA_NAMES } from 'expo-helium';
|
|
13
|
+
### Run the Example Project
|
|
28
14
|
|
|
29
|
-
|
|
30
|
-
useEffect(() => {
|
|
31
|
-
initialize({
|
|
32
|
-
// Helium provided api key
|
|
33
|
-
apiKey: '<your-helium-api-key>',
|
|
15
|
+
Start the TypeScript compiler to watch for changes.
|
|
34
16
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
// Purchase configuration (see next section if using RevenueCat)
|
|
39
|
-
purchaseConfig: createCustomPurchaseConfig({
|
|
40
|
-
makePurchase: async (productId) => {
|
|
41
|
-
// Your purchase logic here
|
|
42
|
-
return { status: 'purchased' };
|
|
43
|
-
},
|
|
44
|
-
restorePurchases: async () => {
|
|
45
|
-
// Your restore logic here
|
|
46
|
-
return true;
|
|
47
|
-
}
|
|
48
|
-
}),
|
|
49
|
-
|
|
50
|
-
// Event handler for paywall events
|
|
51
|
-
onHeliumPaywallEvent: (event) => {
|
|
52
|
-
switch (event.type) {
|
|
53
|
-
case 'paywallOpen':
|
|
54
|
-
break;
|
|
55
|
-
case 'ctaPressed':
|
|
56
|
-
if (event.ctaName === HELIUM_CTA_NAMES.SCHEDULE_CALL) {
|
|
57
|
-
// Handle schedule call
|
|
58
|
-
}
|
|
59
|
-
break;
|
|
60
|
-
case 'subscriptionSucceeded':
|
|
61
|
-
// Handle successful subscription
|
|
62
|
-
break;
|
|
63
|
-
}
|
|
64
|
-
},
|
|
65
|
-
|
|
66
|
-
// Custom user traits
|
|
67
|
-
customUserTraits: {
|
|
68
|
-
"example_trait": "example_value",
|
|
69
|
-
},
|
|
70
|
-
|
|
71
|
-
});
|
|
72
|
-
}, []);
|
|
73
|
-
}
|
|
17
|
+
```shell
|
|
18
|
+
npm run build
|
|
74
19
|
```
|
|
75
20
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
**Important** Make sure that you've already:
|
|
21
|
+
In a separate terminal window, run the example app.
|
|
79
22
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
const asyncHeliumInit = async () => {
|
|
89
|
-
initialize({
|
|
90
|
-
apiKey: '<your-helium-api-key>',
|
|
91
|
-
customUserId: '<your-custom-user-id>',
|
|
92
|
-
purchaseConfig: createRevenueCatPurchaseConfig(),
|
|
93
|
-
onHeliumPaywallEvent: (event) => {
|
|
94
|
-
switch (event.type) {
|
|
95
|
-
case 'subscriptionFailed':
|
|
96
|
-
// Custom logic
|
|
97
|
-
break;
|
|
98
|
-
case 'subscriptionSucceeded':
|
|
99
|
-
// Handle a subscription success event
|
|
100
|
-
// e.g. navigate to a premium page
|
|
101
|
-
break;
|
|
102
|
-
}
|
|
103
|
-
},
|
|
104
|
-
revenueCatAppUserId: await Purchases.getAppUserID()
|
|
105
|
-
});
|
|
106
|
-
};
|
|
107
|
-
|
|
108
|
-
useEffect(() => {
|
|
109
|
-
void asyncHeliumInit();
|
|
110
|
-
}, []);
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
## **Presenting Paywalls**
|
|
114
|
-
|
|
115
|
-
`presentUpsell` takes in a dictionary specifying the `triggerName` as well as an optional `onFallback` parameter defining custom fallback behavior (in case the user didn't have a network connection)
|
|
116
|
-
|
|
117
|
-
```typescript
|
|
118
|
-
import { presentUpsell } from 'expo-helium';
|
|
119
|
-
|
|
120
|
-
function YourComponent() {
|
|
121
|
-
const handlePremiumPress = () => {
|
|
122
|
-
presentUpsell({
|
|
123
|
-
triggerName: 'premium_feature_press',
|
|
124
|
-
onFallback: () => {
|
|
125
|
-
// Implement logic to open a default paywall
|
|
126
|
-
console.log('[Helium] onFallback called!');
|
|
127
|
-
}
|
|
128
|
-
});
|
|
129
|
-
};
|
|
130
|
-
|
|
131
|
-
return (
|
|
132
|
-
<Button title="Try Premium" onPress={handlePremiumPress} />
|
|
133
|
-
);
|
|
134
|
-
}
|
|
23
|
+
```shell
|
|
24
|
+
cd example
|
|
25
|
+
# Run the example app on Android
|
|
26
|
+
npx expo run:android
|
|
27
|
+
# Run the example app on iOS
|
|
28
|
+
npx expo run:ios
|
|
29
|
+
# or
|
|
30
|
+
npx expo run:ios --device
|
|
135
31
|
```
|
|
136
32
|
|
|
137
|
-
## **Paywall Events**
|
|
138
|
-
|
|
139
|
-
Helium emits various events during the lifecycle of a paywall. You can handle these events in your payment delegate. See the [Helium Events](https://docs.tryhelium.com/sdk/helium-events) for more details.
|
|
@@ -57,6 +57,7 @@ export interface HeliumConfig {
|
|
|
57
57
|
purchaseConfig: HeliumPurchaseConfig;
|
|
58
58
|
/** Callback for receiving all Helium paywall events. */
|
|
59
59
|
onHeliumPaywallEvent: (event: HeliumPaywallEvent) => void;
|
|
60
|
+
fallbackBundle?: object;
|
|
60
61
|
triggers?: string[];
|
|
61
62
|
customUserId?: string;
|
|
62
63
|
customAPIEndpoint?: string;
|
|
@@ -69,6 +70,8 @@ export interface NativeHeliumConfig {
|
|
|
69
70
|
customAPIEndpoint?: string;
|
|
70
71
|
customUserTraits?: Record<string, any>;
|
|
71
72
|
revenueCatAppUserId?: string;
|
|
73
|
+
fallbackBundleUrlString?: string;
|
|
74
|
+
fallbackBundleString?: string;
|
|
72
75
|
}
|
|
73
76
|
export interface PaywallInfo {
|
|
74
77
|
paywallTemplateName: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HeliumPaywallSdk.types.d.ts","sourceRoot":"","sources":["../src/HeliumPaywallSdk.types.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"HeliumPaywallSdk.types.d.ts","sourceRoot":"","sources":["../src/HeliumPaywallSdk.types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HeliumPaywallSdk.types.js","sourceRoot":"","sources":["../src/HeliumPaywallSdk.types.ts"],"names":[],"mappings":"AAwDA,sDAAsD;AACtD,MAAM,UAAU,0BAA0B,CAAC,SAG1C;IACC,OAAO;QACL,YAAY,EAAE,SAAS,CAAC,YAAY;QACpC,gBAAgB,EAAE,SAAS,CAAC,gBAAgB;KAC7C,CAAC;AACJ,CAAC;
|
|
1
|
+
{"version":3,"file":"HeliumPaywallSdk.types.js","sourceRoot":"","sources":["../src/HeliumPaywallSdk.types.ts"],"names":[],"mappings":"AAwDA,sDAAsD;AACtD,MAAM,UAAU,0BAA0B,CAAC,SAG1C;IACC,OAAO;QACL,YAAY,EAAE,SAAS,CAAC,YAAY;QACpC,gBAAgB,EAAE,SAAS,CAAC,gBAAgB;KAC7C,CAAC;AACJ,CAAC;AAkCD,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,aAAa,EAAE,eAAe;IAC9B,gBAAgB,EAAE,kBAAkB;CACrC,CAAA","sourcesContent":["import type { StyleProp, ViewStyle } from 'react-native';\n\nexport type OnLoadEventPayload = {\n url: string;\n};\n\nexport type HeliumPaywallSdkModuleEvents = {\n onHeliumPaywallEvent: (params: HeliumPaywallEvent) => void;\n onDelegateActionEvent: (params: DelegateActionEvent) => void;\n};\nexport type HeliumPaywallEvent = {\n type: string;\n triggerName?: string;\n paywallTemplateName?: string;\n productKey?: string;\n ctaName?: string;\n configId?: string;\n numAttempts?: number;\n downloadTimeTakenMS?: number;\n webviewRenderTimeTakenMS?: number;\n imagesDownloadTimeTakenMS?: number;\n fontsDownloadTimeTakenMS?: number;\n bundleDownloadTimeMS?: number;\n dismissAll?: boolean;\n errorDescription?: string;\n};\nexport type DelegateActionEvent = {\n type: 'purchase' | 'restore';\n productId?: string;\n};\n\nexport type HeliumPaywallSdkViewProps = {\n url: string;\n onLoad: (event: { nativeEvent: OnLoadEventPayload }) => void;\n style?: StyleProp<ViewStyle>;\n};\n\nexport type HeliumTransactionStatus = 'purchased' | 'failed' | 'cancelled' | 'pending' | 'restored';\nexport type HeliumPurchaseResult = {\n status: HeliumTransactionStatus;\n error?: string; // Optional error message\n};\nexport type HeliumDownloadStatus = 'downloadSuccess' | 'downloadFailure' | 'inProgress' | 'notDownloadedYet';\n\n// --- Purchase Configuration Types ---\n\n/** Interface for providing custom purchase handling logic. */\n\nexport interface HeliumPurchaseConfig {\n makePurchase: (productId: string) => Promise<HeliumPurchaseResult>;\n restorePurchases: () => Promise<boolean>;\n\n /** Optional RevenueCat API Key. If not provided, RevenueCat must be configured elsewhere. */\n apiKey?: string;\n}\n\n// Helper function for creating Custom Purchase Config\nexport function createCustomPurchaseConfig(callbacks: {\n makePurchase: (productId: string) => Promise<HeliumPurchaseResult>;\n restorePurchases: () => Promise<boolean>;\n}): HeliumPurchaseConfig {\n return {\n makePurchase: callbacks.makePurchase,\n restorePurchases: callbacks.restorePurchases,\n };\n}\n\nexport interface HeliumConfig {\n /** Your Helium API Key */\n apiKey: string;\n /** Configuration for handling purchases. Can be custom functions or a pre-built handler config. */\n purchaseConfig: HeliumPurchaseConfig;\n /** Callback for receiving all Helium paywall events. */\n onHeliumPaywallEvent: (event: HeliumPaywallEvent) => void; // Still mandatory\n\n // Optional configurations\n fallbackBundle?: object;\n triggers?: string[];\n customUserId?: string;\n customAPIEndpoint?: string;\n customUserTraits?: Record<string, any>;\n revenueCatAppUserId?: string;\n}\n\nexport interface NativeHeliumConfig {\n apiKey: string;\n customUserId?: string;\n customAPIEndpoint?: string;\n customUserTraits?: Record<string, any>;\n revenueCatAppUserId?: string;\n fallbackBundleUrlString?: string;\n fallbackBundleString?: string;\n}\n\nexport interface PaywallInfo {\n paywallTemplateName: string;\n shouldShow: boolean;\n}\n\nexport const HELIUM_CTA_NAMES = {\n SCHEDULE_CALL: 'schedule_call',\n SUBSCRIBE_BUTTON: 'subscribe_button',\n}\n"]}
|
|
@@ -5,16 +5,22 @@ interface PaywallInfoResult {
|
|
|
5
5
|
templateName?: string;
|
|
6
6
|
shouldShow?: boolean;
|
|
7
7
|
}
|
|
8
|
+
interface CanPresentUpsellResult {
|
|
9
|
+
canPresent?: boolean;
|
|
10
|
+
reason?: string;
|
|
11
|
+
}
|
|
8
12
|
declare class HeliumPaywallSdkModule extends NativeModule<HeliumPaywallSdkModuleEvents> {
|
|
9
13
|
initialize(config: NativeHeliumConfig): void;
|
|
10
14
|
presentUpsell(triggerName: string): void;
|
|
11
15
|
hideUpsell(): void;
|
|
12
16
|
hideAllUpsells(): void;
|
|
13
17
|
getDownloadStatus(): HeliumDownloadStatus;
|
|
18
|
+
canPresentUpsell(trigger: string): CanPresentUpsellResult;
|
|
14
19
|
fallbackOpenOrCloseEvent(trigger: string, isOpen: boolean, viewType: string): void;
|
|
15
20
|
handlePurchaseResult(statusString: HeliumTransactionStatus, errorMsg?: string): void;
|
|
16
21
|
handleRestoreResult(success: boolean): void;
|
|
17
22
|
getPaywallInfo(trigger: string): PaywallInfoResult;
|
|
23
|
+
handleDeepLink(urlString: string): boolean;
|
|
18
24
|
}
|
|
19
25
|
declare const _default: HeliumPaywallSdkModule;
|
|
20
26
|
export default _default;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HeliumPaywallSdkModule.d.ts","sourceRoot":"","sources":["../src/HeliumPaywallSdkModule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAuB,MAAM,MAAM,CAAC;AAEzD,OAAO,EACL,oBAAoB,EACpB,4BAA4B,EAC5B,uBAAuB,EACvB,kBAAkB,EACnB,MAAM,0BAA0B,CAAC;AAElC,UAAU,iBAAiB;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,OAAO,OAAO,sBAAuB,SAAQ,YAAY,CAAC,4BAA4B,CAAC;IACrF,UAAU,CAAC,MAAM,EAAE,kBAAkB,GAAG,IAAI;IAE5C,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IAExC,UAAU,IAAI,IAAI;IAElB,cAAc,IAAI,IAAI;IAEtB,iBAAiB,IAAI,oBAAoB;IAEzC,wBAAwB,CACtB,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,OAAO,EACf,QAAQ,EAAE,MAAM,GACf,IAAI;IAEP,oBAAoB,CAClB,YAAY,EAAE,uBAAuB,EACrC,QAAQ,CAAC,EAAE,MAAM,GAChB,IAAI;IAEP,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAE3C,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,iBAAiB;
|
|
1
|
+
{"version":3,"file":"HeliumPaywallSdkModule.d.ts","sourceRoot":"","sources":["../src/HeliumPaywallSdkModule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAuB,MAAM,MAAM,CAAC;AAEzD,OAAO,EACL,oBAAoB,EACpB,4BAA4B,EAC5B,uBAAuB,EACvB,kBAAkB,EACnB,MAAM,0BAA0B,CAAC;AAElC,UAAU,iBAAiB;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,UAAU,sBAAsB;IAC9B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,OAAO,OAAO,sBAAuB,SAAQ,YAAY,CAAC,4BAA4B,CAAC;IACrF,UAAU,CAAC,MAAM,EAAE,kBAAkB,GAAG,IAAI;IAE5C,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IAExC,UAAU,IAAI,IAAI;IAElB,cAAc,IAAI,IAAI;IAEtB,iBAAiB,IAAI,oBAAoB;IAEzC,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,sBAAsB;IAEzD,wBAAwB,CACtB,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,OAAO,EACf,QAAQ,EAAE,MAAM,GACf,IAAI;IAEP,oBAAoB,CAClB,YAAY,EAAE,uBAAuB,EACrC,QAAQ,CAAC,EAAE,MAAM,GAChB,IAAI;IAEP,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAE3C,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,iBAAiB;IAElD,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;CAC3C;;AAGD,wBAA+E"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HeliumPaywallSdkModule.js","sourceRoot":"","sources":["../src/HeliumPaywallSdkModule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,mBAAmB,EAAE,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"HeliumPaywallSdkModule.js","sourceRoot":"","sources":["../src/HeliumPaywallSdkModule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,mBAAmB,EAAE,MAAM,MAAM,CAAC;AAmDzD,yDAAyD;AACzD,eAAe,mBAAmB,CAAyB,kBAAkB,CAAC,CAAC","sourcesContent":["import { NativeModule, requireNativeModule } from \"expo\";\n\nimport {\n HeliumDownloadStatus,\n HeliumPaywallSdkModuleEvents,\n HeliumTransactionStatus,\n NativeHeliumConfig,\n} from \"./HeliumPaywallSdk.types\";\n\ninterface PaywallInfoResult {\n errorMsg?: string;\n templateName?: string;\n shouldShow?: boolean;\n}\n\ninterface CanPresentUpsellResult {\n canPresent?: boolean;\n reason?: string;\n}\n\ndeclare class HeliumPaywallSdkModule extends NativeModule<HeliumPaywallSdkModuleEvents> {\n initialize(config: NativeHeliumConfig): void;\n\n presentUpsell(triggerName: string): void;\n\n hideUpsell(): void;\n\n hideAllUpsells(): void;\n\n getDownloadStatus(): HeliumDownloadStatus;\n\n canPresentUpsell(trigger: string): CanPresentUpsellResult;\n\n fallbackOpenOrCloseEvent(\n trigger: string,\n isOpen: boolean,\n viewType: string,\n ): void;\n\n handlePurchaseResult(\n statusString: HeliumTransactionStatus,\n errorMsg?: string,\n ): void;\n\n handleRestoreResult(success: boolean): void;\n\n getPaywallInfo(trigger: string): PaywallInfoResult;\n\n handleDeepLink(urlString: string): boolean;\n}\n\n// This call loads the native module object from the JSI.\nexport default requireNativeModule<HeliumPaywallSdkModule>(\"HeliumPaywallSdk\");\n"]}
|
package/build/index.d.ts
CHANGED
|
@@ -10,6 +10,7 @@ export declare const hideUpsell: () => void;
|
|
|
10
10
|
export declare const hideAllUpsells: () => void;
|
|
11
11
|
export declare const getDownloadStatus: () => import("./HeliumPaywallSdk.types").HeliumDownloadStatus;
|
|
12
12
|
export declare const getPaywallInfo: (trigger: string) => PaywallInfo | undefined;
|
|
13
|
+
export declare const handleDeepLink: (url: string | null) => boolean;
|
|
13
14
|
export { createCustomPurchaseConfig, HELIUM_CTA_NAMES } from './HeliumPaywallSdk.types';
|
|
14
15
|
export type { HeliumTransactionStatus, HeliumConfig, } from './HeliumPaywallSdk.types';
|
|
15
16
|
//# sourceMappingURL=index.d.ts.map
|
package/build/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,YAAY,EAEQ,WAAW,EAChC,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,YAAY,EAEQ,WAAW,EAChC,MAAM,0BAA0B,CAAC;AAKlC,OAAO,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AAEnD,cAAe,0BAA0B,CAAC;AAW1C,eAAO,MAAM,UAAU,GAAI,QAAQ,YAAY,SA2C9C,CAAC;AAyCF,eAAO,MAAM,aAAa,GAAI,6BAGG;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;CACzB,SAmBA,CAAC;AAEF,eAAO,MAAM,UAAU,YAAoC,CAAC;AAC5D,eAAO,MAAM,cAAc,YAAwC,CAAC;AACpE,eAAO,MAAM,iBAAiB,+DAA2C,CAAC;AAE1E,eAAO,MAAM,cAAc,GAAI,SAAS,MAAM,KAAG,WAAW,GAAG,SAc9D,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,KAAK,MAAM,GAAG,IAAI,YAOhD,CAAC;AAEF,OAAO,EAAC,0BAA0B,EAAE,gBAAgB,EAAC,MAAM,0BAA0B,CAAC;AAEtF,YAAY,EACV,uBAAuB,EACvB,YAAY,GACb,MAAM,0BAA0B,CAAC"}
|
package/build/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import HeliumPaywallSdkModule from "./HeliumPaywallSdkModule";
|
|
2
|
+
import * as ExpoFileSystem from 'expo-file-system';
|
|
2
3
|
export { default } from './HeliumPaywallSdkModule';
|
|
3
4
|
// export { default as HeliumPaywallSdkView } from './HeliumPaywallSdkView';
|
|
4
5
|
export * from './HeliumPaywallSdk.types';
|
|
@@ -48,22 +49,44 @@ export const initialize = (config) => {
|
|
|
48
49
|
}
|
|
49
50
|
}
|
|
50
51
|
});
|
|
52
|
+
nativeInitializeAsync(config).catch(error => {
|
|
53
|
+
console.error('[Helium] Initialization failed:', error);
|
|
54
|
+
});
|
|
55
|
+
};
|
|
56
|
+
const nativeInitializeAsync = async (config) => {
|
|
57
|
+
let fallbackBundleUrlString;
|
|
58
|
+
let fallbackBundleString;
|
|
59
|
+
if (config.fallbackBundle) {
|
|
60
|
+
try {
|
|
61
|
+
const jsonContent = JSON.stringify(config.fallbackBundle);
|
|
62
|
+
// Write to documents directory
|
|
63
|
+
fallbackBundleUrlString = `${ExpoFileSystem.documentDirectory}helium-fallback.json`;
|
|
64
|
+
// This is ASYNC but that's ok because helium initialize in swift code is async anyways.
|
|
65
|
+
await ExpoFileSystem.writeAsStringAsync(fallbackBundleUrlString, jsonContent);
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
// Fallback to string approach if unexpected error occurs
|
|
69
|
+
console.log('[Helium] expo-file-system not available, attempting to pass fallback bundle as string.');
|
|
70
|
+
fallbackBundleString = JSON.stringify(config.fallbackBundle);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
51
73
|
// Create native config object
|
|
52
74
|
const nativeConfig = {
|
|
53
75
|
apiKey: config.apiKey,
|
|
54
76
|
customUserId: config.customUserId,
|
|
55
77
|
customAPIEndpoint: config.customAPIEndpoint,
|
|
56
78
|
customUserTraits: config.customUserTraits,
|
|
57
|
-
revenueCatAppUserId: config.revenueCatAppUserId
|
|
79
|
+
revenueCatAppUserId: config.revenueCatAppUserId,
|
|
80
|
+
fallbackBundleUrlString: fallbackBundleUrlString,
|
|
81
|
+
fallbackBundleString: fallbackBundleString,
|
|
58
82
|
};
|
|
59
83
|
// Initialize the native module
|
|
60
84
|
HeliumPaywallSdkModule.initialize(nativeConfig);
|
|
61
85
|
};
|
|
62
86
|
export const presentUpsell = ({ triggerName, onFallback }) => {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
console.log(`Helium trigger "${triggerName}" not found or download status not successful. Status:`, downloadStatus);
|
|
87
|
+
const { canPresent, reason } = HeliumPaywallSdkModule.canPresentUpsell(triggerName);
|
|
88
|
+
if (!canPresent) {
|
|
89
|
+
console.log(`[Helium] Cannot present trigger "${triggerName}". Reason: ${reason}`);
|
|
67
90
|
onFallback?.();
|
|
68
91
|
HeliumPaywallSdkModule.fallbackOpenOrCloseEvent(triggerName, true, 'presented');
|
|
69
92
|
return;
|
|
@@ -95,5 +118,13 @@ export const getPaywallInfo = (trigger) => {
|
|
|
95
118
|
shouldShow: result.shouldShow ?? true,
|
|
96
119
|
};
|
|
97
120
|
};
|
|
121
|
+
export const handleDeepLink = (url) => {
|
|
122
|
+
if (url) {
|
|
123
|
+
const handled = HeliumPaywallSdkModule.handleDeepLink(url);
|
|
124
|
+
console.log('[Helium] Handled deep link:', handled);
|
|
125
|
+
return handled;
|
|
126
|
+
}
|
|
127
|
+
return false;
|
|
128
|
+
};
|
|
98
129
|
export { createCustomPurchaseConfig, HELIUM_CTA_NAMES } from './HeliumPaywallSdk.types';
|
|
99
130
|
//# sourceMappingURL=index.js.map
|
package/build/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n DelegateActionEvent,\n HeliumConfig,\n HeliumPaywallEvent,\n NativeHeliumConfig, PaywallInfo,\n} from \"./HeliumPaywallSdk.types\";\nimport HeliumPaywallSdkModule from \"./HeliumPaywallSdkModule\";\nimport { EventSubscription } from 'expo-modules-core';\n\nexport { default } from './HeliumPaywallSdkModule';\n// export { default as HeliumPaywallSdkView } from './HeliumPaywallSdkView';\nexport * from './HeliumPaywallSdk.types';\n\nfunction addHeliumPaywallEventListener(listener: (event: HeliumPaywallEvent) => void): EventSubscription {\n return HeliumPaywallSdkModule.addListener('onHeliumPaywallEvent', listener);\n}\n\nfunction addDelegateActionEventListener(listener: (event: DelegateActionEvent) => void): EventSubscription {\n return HeliumPaywallSdkModule.addListener('onDelegateActionEvent', listener);\n}\n\nlet isInitialized = false;\nexport const initialize = (config: HeliumConfig) => {\n if (isInitialized) {\n return;\n }\n isInitialized = true;\n\n HeliumPaywallSdkModule.removeAllListeners('onHeliumPaywallEvent');\n HeliumPaywallSdkModule.removeAllListeners('onDelegateActionEvent');\n\n // Set up listener for paywall events\n addHeliumPaywallEventListener((event) => {\n config.onHeliumPaywallEvent(event);\n });\n\n // Set up delegate action listener for purchase and restore operations\n addDelegateActionEventListener(async (event) => {\n try {\n if (event.type === 'purchase') {\n if (event.productId) {\n const result = await config.purchaseConfig.makePurchase(event.productId);\n HeliumPaywallSdkModule.handlePurchaseResult(result.status, result.error);\n } else {\n HeliumPaywallSdkModule.handlePurchaseResult('failed', 'No product ID for purchase event.');\n }\n }\n else if (event.type === 'restore') {\n const success = await config.purchaseConfig.restorePurchases();\n HeliumPaywallSdkModule.handleRestoreResult(success);\n }\n } catch (error) {\n // Send failure result based on action type\n if (event.type === 'purchase') {\n console.log('[Helium] Unexpected error: ', error);\n HeliumPaywallSdkModule.handlePurchaseResult('failed');\n } else if (event.type === 'restore') {\n HeliumPaywallSdkModule.handleRestoreResult(false);\n }\n }\n });\n\n // Create native config object\n const nativeConfig: NativeHeliumConfig = {\n apiKey: config.apiKey,\n customUserId: config.customUserId,\n customAPIEndpoint: config.customAPIEndpoint,\n customUserTraits: config.customUserTraits,\n revenueCatAppUserId: config.revenueCatAppUserId\n };\n\n // Initialize the native module\n HeliumPaywallSdkModule.initialize(nativeConfig);\n};\n\nexport const presentUpsell = ({\n triggerName,\n onFallback\n }: {\n triggerName: string;\n onFallback?: () => void;\n}) => {\n // todo check HeliumBridge.getFetchedTriggerNames((triggerNames: string[]) ??\n const downloadStatus = getDownloadStatus();\n if (downloadStatus !== 'downloadSuccess') {\n console.log(\n `Helium trigger \"${triggerName}\" not found or download status not successful. Status:`,\n downloadStatus\n );\n onFallback?.();\n HeliumPaywallSdkModule.fallbackOpenOrCloseEvent(triggerName, true, 'presented');\n return;\n }\n\n try {\n HeliumPaywallSdkModule.presentUpsell(triggerName);\n } catch (error) {\n console.log('Helium present error', error);\n onFallback?.();\n HeliumPaywallSdkModule.fallbackOpenOrCloseEvent(triggerName, true, 'presented');\n }\n};\n\nexport const hideUpsell = HeliumPaywallSdkModule.hideUpsell;\nexport const hideAllUpsells = HeliumPaywallSdkModule.hideAllUpsells;\nexport const getDownloadStatus = HeliumPaywallSdkModule.getDownloadStatus;\n\nexport const getPaywallInfo = (trigger: string): PaywallInfo | undefined => {\n const result = HeliumPaywallSdkModule.getPaywallInfo(trigger);\n if (!result) {\n console.log('[Helium] getPaywallInfo unexpected error.');\n return;\n }\n if (result.errorMsg) {\n console.log(`[Helium] ${result.errorMsg}`);\n return;\n }\n return {\n paywallTemplateName: result.templateName ?? 'unknown template',\n shouldShow: result.shouldShow ?? true,\n };\n};\n\nexport {createCustomPurchaseConfig, HELIUM_CTA_NAMES} from './HeliumPaywallSdk.types';\n\nexport type {\n HeliumTransactionStatus,\n HeliumConfig,\n} from './HeliumPaywallSdk.types';\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n DelegateActionEvent,\n HeliumConfig,\n HeliumPaywallEvent,\n NativeHeliumConfig, PaywallInfo,\n} from \"./HeliumPaywallSdk.types\";\nimport HeliumPaywallSdkModule from \"./HeliumPaywallSdkModule\";\nimport { EventSubscription } from 'expo-modules-core';\nimport * as ExpoFileSystem from 'expo-file-system';\n\nexport { default } from './HeliumPaywallSdkModule';\n// export { default as HeliumPaywallSdkView } from './HeliumPaywallSdkView';\nexport * from './HeliumPaywallSdk.types';\n\nfunction addHeliumPaywallEventListener(listener: (event: HeliumPaywallEvent) => void): EventSubscription {\n return HeliumPaywallSdkModule.addListener('onHeliumPaywallEvent', listener);\n}\n\nfunction addDelegateActionEventListener(listener: (event: DelegateActionEvent) => void): EventSubscription {\n return HeliumPaywallSdkModule.addListener('onDelegateActionEvent', listener);\n}\n\nlet isInitialized = false;\nexport const initialize = (config: HeliumConfig) => {\n if (isInitialized) {\n return;\n }\n isInitialized = true;\n\n HeliumPaywallSdkModule.removeAllListeners('onHeliumPaywallEvent');\n HeliumPaywallSdkModule.removeAllListeners('onDelegateActionEvent');\n\n // Set up listener for paywall events\n addHeliumPaywallEventListener((event) => {\n config.onHeliumPaywallEvent(event);\n });\n\n // Set up delegate action listener for purchase and restore operations\n addDelegateActionEventListener(async (event) => {\n try {\n if (event.type === 'purchase') {\n if (event.productId) {\n const result = await config.purchaseConfig.makePurchase(event.productId);\n HeliumPaywallSdkModule.handlePurchaseResult(result.status, result.error);\n } else {\n HeliumPaywallSdkModule.handlePurchaseResult('failed', 'No product ID for purchase event.');\n }\n }\n else if (event.type === 'restore') {\n const success = await config.purchaseConfig.restorePurchases();\n HeliumPaywallSdkModule.handleRestoreResult(success);\n }\n } catch (error) {\n // Send failure result based on action type\n if (event.type === 'purchase') {\n console.log('[Helium] Unexpected error: ', error);\n HeliumPaywallSdkModule.handlePurchaseResult('failed');\n } else if (event.type === 'restore') {\n HeliumPaywallSdkModule.handleRestoreResult(false);\n }\n }\n });\n\n nativeInitializeAsync(config).catch(error => {\n console.error('[Helium] Initialization failed:', error);\n });\n};\n\nconst nativeInitializeAsync = async (config: HeliumConfig) => {\n let fallbackBundleUrlString;\n let fallbackBundleString;\n if (config.fallbackBundle) {\n try {\n const jsonContent = JSON.stringify(config.fallbackBundle);\n\n // Write to documents directory\n fallbackBundleUrlString = `${ExpoFileSystem.documentDirectory}helium-fallback.json`;\n // This is ASYNC but that's ok because helium initialize in swift code is async anyways.\n await ExpoFileSystem.writeAsStringAsync(\n fallbackBundleUrlString,\n jsonContent\n );\n } catch (error) {\n // Fallback to string approach if unexpected error occurs\n console.log(\n '[Helium] expo-file-system not available, attempting to pass fallback bundle as string.'\n );\n fallbackBundleString = JSON.stringify(config.fallbackBundle);\n }\n }\n\n\n // Create native config object\n const nativeConfig: NativeHeliumConfig = {\n apiKey: config.apiKey,\n customUserId: config.customUserId,\n customAPIEndpoint: config.customAPIEndpoint,\n customUserTraits: config.customUserTraits,\n revenueCatAppUserId: config.revenueCatAppUserId,\n fallbackBundleUrlString: fallbackBundleUrlString,\n fallbackBundleString: fallbackBundleString,\n };\n\n // Initialize the native module\n HeliumPaywallSdkModule.initialize(nativeConfig);\n};\n\nexport const presentUpsell = ({\n triggerName,\n onFallback\n }: {\n triggerName: string;\n onFallback?: () => void;\n}) => {\n const { canPresent, reason } = HeliumPaywallSdkModule.canPresentUpsell(triggerName);\n\n if (!canPresent) {\n console.log(\n `[Helium] Cannot present trigger \"${triggerName}\". Reason: ${reason}`\n );\n onFallback?.();\n HeliumPaywallSdkModule.fallbackOpenOrCloseEvent(triggerName, true, 'presented');\n return;\n }\n\n try {\n HeliumPaywallSdkModule.presentUpsell(triggerName);\n } catch (error) {\n console.log('Helium present error', error);\n onFallback?.();\n HeliumPaywallSdkModule.fallbackOpenOrCloseEvent(triggerName, true, 'presented');\n }\n};\n\nexport const hideUpsell = HeliumPaywallSdkModule.hideUpsell;\nexport const hideAllUpsells = HeliumPaywallSdkModule.hideAllUpsells;\nexport const getDownloadStatus = HeliumPaywallSdkModule.getDownloadStatus;\n\nexport const getPaywallInfo = (trigger: string): PaywallInfo | undefined => {\n const result = HeliumPaywallSdkModule.getPaywallInfo(trigger);\n if (!result) {\n console.log('[Helium] getPaywallInfo unexpected error.');\n return;\n }\n if (result.errorMsg) {\n console.log(`[Helium] ${result.errorMsg}`);\n return;\n }\n return {\n paywallTemplateName: result.templateName ?? 'unknown template',\n shouldShow: result.shouldShow ?? true,\n };\n};\n\nexport const handleDeepLink = (url: string | null) => {\n if (url) {\n const handled = HeliumPaywallSdkModule.handleDeepLink(url);\n console.log('[Helium] Handled deep link:', handled);\n return handled;\n }\n return false;\n};\n\nexport {createCustomPurchaseConfig, HELIUM_CTA_NAMES} from './HeliumPaywallSdk.types';\n\nexport type {\n HeliumTransactionStatus,\n HeliumConfig,\n} from './HeliumPaywallSdk.types';\n"]}
|
|
@@ -28,6 +28,13 @@ struct PaywallInfoResult: Record {
|
|
|
28
28
|
var shouldShow: Bool? = nil
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
+
struct CanPresentPaywallResult: Record {
|
|
32
|
+
@Field
|
|
33
|
+
var canPresent: Bool = false
|
|
34
|
+
@Field
|
|
35
|
+
var reason: String? = nil
|
|
36
|
+
}
|
|
37
|
+
|
|
31
38
|
public class HeliumPaywallSdkModule: Module {
|
|
32
39
|
// Single continuations for ongoing operations
|
|
33
40
|
private var currentProductId: String? = nil
|
|
@@ -54,6 +61,8 @@ public class HeliumPaywallSdkModule: Module {
|
|
|
54
61
|
// todo use Record here? https://docs.expo.dev/modules/module-api/#records
|
|
55
62
|
Function("initialize") { (config: [String : Any]) in
|
|
56
63
|
let userTraitsMap = config["customUserTraits"] as? [String : Any]
|
|
64
|
+
let fallbackBundleURLString = config["fallbackBundleUrlString"] as? String
|
|
65
|
+
let fallbackBundleString = config["fallbackBundleString"] as? String
|
|
57
66
|
|
|
58
67
|
// Create delegate with closures that send events to JavaScript
|
|
59
68
|
let delegate = InternalDelegate(
|
|
@@ -101,6 +110,21 @@ public class HeliumPaywallSdkModule: Module {
|
|
|
101
110
|
}
|
|
102
111
|
)
|
|
103
112
|
|
|
113
|
+
// Handle fallback bundle - either as URL string or JSON string
|
|
114
|
+
var fallbackBundleURL: URL? = nil
|
|
115
|
+
if let urlString = fallbackBundleURLString {
|
|
116
|
+
fallbackBundleURL = URL(string: urlString)
|
|
117
|
+
} else if let jsonString = fallbackBundleString {
|
|
118
|
+
// write the string to a temp file
|
|
119
|
+
let tempURL = FileManager.default.temporaryDirectory
|
|
120
|
+
.appendingPathComponent("helium-fallback.json")
|
|
121
|
+
|
|
122
|
+
if let data = jsonString.data(using: .utf8) {
|
|
123
|
+
try? data.write(to: tempURL)
|
|
124
|
+
fallbackBundleURL = tempURL
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
104
128
|
Helium.shared.initialize(
|
|
105
129
|
apiKey: config["apiKey"] as? String ?? "",
|
|
106
130
|
heliumPaywallDelegate: delegate,
|
|
@@ -108,7 +132,8 @@ public class HeliumPaywallSdkModule: Module {
|
|
|
108
132
|
customUserId: config["customUserId"] as? String,
|
|
109
133
|
customAPIEndpoint: config["customAPIEndpoint"] as? String,
|
|
110
134
|
customUserTraits: userTraitsMap != nil ? HeliumUserTraits(userTraitsMap!) : nil,
|
|
111
|
-
revenueCatAppUserId: config["revenueCatAppUserId"] as? String
|
|
135
|
+
revenueCatAppUserId: config["revenueCatAppUserId"] as? String,
|
|
136
|
+
fallbackBundleURL: fallbackBundleURL
|
|
112
137
|
)
|
|
113
138
|
}
|
|
114
139
|
|
|
@@ -185,6 +210,45 @@ public class HeliumPaywallSdkModule: Module {
|
|
|
185
210
|
)
|
|
186
211
|
}
|
|
187
212
|
|
|
213
|
+
Function("canPresentUpsell") { (trigger: String) in
|
|
214
|
+
// Check if paywalls are downloaded successfully
|
|
215
|
+
let paywallsLoaded = Helium.shared.paywallsLoaded()
|
|
216
|
+
|
|
217
|
+
// Check if trigger exists in fetched triggers
|
|
218
|
+
let triggerNames = HeliumFetchedConfigManager.shared.getFetchedTriggerNames()
|
|
219
|
+
let hasTrigger = triggerNames.contains(trigger)
|
|
220
|
+
|
|
221
|
+
let canPresent: Bool
|
|
222
|
+
let reason: String
|
|
223
|
+
|
|
224
|
+
if paywallsLoaded && hasTrigger {
|
|
225
|
+
// Normal case - paywall is ready
|
|
226
|
+
canPresent = true
|
|
227
|
+
reason = "ready"
|
|
228
|
+
} else if HeliumFallbackViewManager.shared.getFallbackInfo(trigger: trigger) != nil {
|
|
229
|
+
// Fallback is available (via downloaded bundle)
|
|
230
|
+
canPresent = true
|
|
231
|
+
reason = "fallback_ready"
|
|
232
|
+
} else {
|
|
233
|
+
// No paywall and no fallback bundle
|
|
234
|
+
canPresent = false
|
|
235
|
+
reason = !paywallsLoaded ? "download status - \(Helium.shared.getDownloadStatus().rawValue)" : "trigger_not_found"
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
return CanPresentPaywallResult(
|
|
239
|
+
canPresent: canPresent,
|
|
240
|
+
reason: reason
|
|
241
|
+
)
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
Function("handleDeepLink") { (urlString: String) in
|
|
245
|
+
guard let url = URL(string: urlString) else {
|
|
246
|
+
return false
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
return Helium.shared.handleDeepLink(url)
|
|
250
|
+
}
|
|
251
|
+
|
|
188
252
|
// Defines a JavaScript function that always returns a Promise and whose native code
|
|
189
253
|
// is by default dispatched on the different thread than the JavaScript runtime runs on.
|
|
190
254
|
// AsyncFunction("setValueAsync") { (value: String) in
|
package/package.json
CHANGED
|
@@ -74,6 +74,7 @@ export interface HeliumConfig {
|
|
|
74
74
|
onHeliumPaywallEvent: (event: HeliumPaywallEvent) => void; // Still mandatory
|
|
75
75
|
|
|
76
76
|
// Optional configurations
|
|
77
|
+
fallbackBundle?: object;
|
|
77
78
|
triggers?: string[];
|
|
78
79
|
customUserId?: string;
|
|
79
80
|
customAPIEndpoint?: string;
|
|
@@ -87,6 +88,8 @@ export interface NativeHeliumConfig {
|
|
|
87
88
|
customAPIEndpoint?: string;
|
|
88
89
|
customUserTraits?: Record<string, any>;
|
|
89
90
|
revenueCatAppUserId?: string;
|
|
91
|
+
fallbackBundleUrlString?: string;
|
|
92
|
+
fallbackBundleString?: string;
|
|
90
93
|
}
|
|
91
94
|
|
|
92
95
|
export interface PaywallInfo {
|
|
@@ -13,6 +13,11 @@ interface PaywallInfoResult {
|
|
|
13
13
|
shouldShow?: boolean;
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
+
interface CanPresentUpsellResult {
|
|
17
|
+
canPresent?: boolean;
|
|
18
|
+
reason?: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
16
21
|
declare class HeliumPaywallSdkModule extends NativeModule<HeliumPaywallSdkModuleEvents> {
|
|
17
22
|
initialize(config: NativeHeliumConfig): void;
|
|
18
23
|
|
|
@@ -24,6 +29,8 @@ declare class HeliumPaywallSdkModule extends NativeModule<HeliumPaywallSdkModule
|
|
|
24
29
|
|
|
25
30
|
getDownloadStatus(): HeliumDownloadStatus;
|
|
26
31
|
|
|
32
|
+
canPresentUpsell(trigger: string): CanPresentUpsellResult;
|
|
33
|
+
|
|
27
34
|
fallbackOpenOrCloseEvent(
|
|
28
35
|
trigger: string,
|
|
29
36
|
isOpen: boolean,
|
|
@@ -38,6 +45,8 @@ declare class HeliumPaywallSdkModule extends NativeModule<HeliumPaywallSdkModule
|
|
|
38
45
|
handleRestoreResult(success: boolean): void;
|
|
39
46
|
|
|
40
47
|
getPaywallInfo(trigger: string): PaywallInfoResult;
|
|
48
|
+
|
|
49
|
+
handleDeepLink(urlString: string): boolean;
|
|
41
50
|
}
|
|
42
51
|
|
|
43
52
|
// This call loads the native module object from the JSI.
|
package/src/index.ts
CHANGED
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
} from "./HeliumPaywallSdk.types";
|
|
7
7
|
import HeliumPaywallSdkModule from "./HeliumPaywallSdkModule";
|
|
8
8
|
import { EventSubscription } from 'expo-modules-core';
|
|
9
|
+
import * as ExpoFileSystem from 'expo-file-system';
|
|
9
10
|
|
|
10
11
|
export { default } from './HeliumPaywallSdkModule';
|
|
11
12
|
// export { default as HeliumPaywallSdkView } from './HeliumPaywallSdkView';
|
|
@@ -60,13 +61,44 @@ export const initialize = (config: HeliumConfig) => {
|
|
|
60
61
|
}
|
|
61
62
|
});
|
|
62
63
|
|
|
64
|
+
nativeInitializeAsync(config).catch(error => {
|
|
65
|
+
console.error('[Helium] Initialization failed:', error);
|
|
66
|
+
});
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const nativeInitializeAsync = async (config: HeliumConfig) => {
|
|
70
|
+
let fallbackBundleUrlString;
|
|
71
|
+
let fallbackBundleString;
|
|
72
|
+
if (config.fallbackBundle) {
|
|
73
|
+
try {
|
|
74
|
+
const jsonContent = JSON.stringify(config.fallbackBundle);
|
|
75
|
+
|
|
76
|
+
// Write to documents directory
|
|
77
|
+
fallbackBundleUrlString = `${ExpoFileSystem.documentDirectory}helium-fallback.json`;
|
|
78
|
+
// This is ASYNC but that's ok because helium initialize in swift code is async anyways.
|
|
79
|
+
await ExpoFileSystem.writeAsStringAsync(
|
|
80
|
+
fallbackBundleUrlString,
|
|
81
|
+
jsonContent
|
|
82
|
+
);
|
|
83
|
+
} catch (error) {
|
|
84
|
+
// Fallback to string approach if unexpected error occurs
|
|
85
|
+
console.log(
|
|
86
|
+
'[Helium] expo-file-system not available, attempting to pass fallback bundle as string.'
|
|
87
|
+
);
|
|
88
|
+
fallbackBundleString = JSON.stringify(config.fallbackBundle);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
|
|
63
93
|
// Create native config object
|
|
64
94
|
const nativeConfig: NativeHeliumConfig = {
|
|
65
95
|
apiKey: config.apiKey,
|
|
66
96
|
customUserId: config.customUserId,
|
|
67
97
|
customAPIEndpoint: config.customAPIEndpoint,
|
|
68
98
|
customUserTraits: config.customUserTraits,
|
|
69
|
-
revenueCatAppUserId: config.revenueCatAppUserId
|
|
99
|
+
revenueCatAppUserId: config.revenueCatAppUserId,
|
|
100
|
+
fallbackBundleUrlString: fallbackBundleUrlString,
|
|
101
|
+
fallbackBundleString: fallbackBundleString,
|
|
70
102
|
};
|
|
71
103
|
|
|
72
104
|
// Initialize the native module
|
|
@@ -80,12 +112,11 @@ export const presentUpsell = ({
|
|
|
80
112
|
triggerName: string;
|
|
81
113
|
onFallback?: () => void;
|
|
82
114
|
}) => {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
if (
|
|
115
|
+
const { canPresent, reason } = HeliumPaywallSdkModule.canPresentUpsell(triggerName);
|
|
116
|
+
|
|
117
|
+
if (!canPresent) {
|
|
86
118
|
console.log(
|
|
87
|
-
`Helium trigger "${triggerName}"
|
|
88
|
-
downloadStatus
|
|
119
|
+
`[Helium] Cannot present trigger "${triggerName}". Reason: ${reason}`
|
|
89
120
|
);
|
|
90
121
|
onFallback?.();
|
|
91
122
|
HeliumPaywallSdkModule.fallbackOpenOrCloseEvent(triggerName, true, 'presented');
|
|
@@ -121,6 +152,15 @@ export const getPaywallInfo = (trigger: string): PaywallInfo | undefined => {
|
|
|
121
152
|
};
|
|
122
153
|
};
|
|
123
154
|
|
|
155
|
+
export const handleDeepLink = (url: string | null) => {
|
|
156
|
+
if (url) {
|
|
157
|
+
const handled = HeliumPaywallSdkModule.handleDeepLink(url);
|
|
158
|
+
console.log('[Helium] Handled deep link:', handled);
|
|
159
|
+
return handled;
|
|
160
|
+
}
|
|
161
|
+
return false;
|
|
162
|
+
};
|
|
163
|
+
|
|
124
164
|
export {createCustomPurchaseConfig, HELIUM_CTA_NAMES} from './HeliumPaywallSdk.types';
|
|
125
165
|
|
|
126
166
|
export type {
|