expo-superwall 1.1.4 → 1.1.5
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/CHANGELOG.md +6 -0
- package/android/src/main/java/expo/modules/superwallexpo/SuperwallExpoModule.kt +14 -4
- package/android/src/main/java/expo/modules/superwallexpo/bridges/PurchaseControllerBridge.kt +2 -2
- package/android/src/main/java/expo/modules/superwallexpo/bridges/SuperwallDelegateBridge.kt +1 -1
- package/build/package.json +1 -1
- package/build/src/compat/lib/PaywallOptions.d.ts +1 -0
- package/build/src/compat/lib/PaywallOptions.d.ts.map +1 -1
- package/build/src/compat/lib/PaywallOptions.js +5 -0
- package/build/src/compat/lib/PaywallOptions.js.map +1 -1
- package/ios/SuperwallExpoModule.swift +16 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.1.5
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 45be124: Fix purchase events being dropped on cold start when using a custom purchase controller, which left the paywall spinner stuck forever. The native module emitted events through a single static reference that was overwritten by every module instance, so when more than one app context exists (e.g. expo-dev-client's launcher plus the app) the reference could point at an instance whose JS runtime never subscribed and `onPurchase`/`onPurchaseRestore` were silently dropped. Native events are now emitted to every live module instance (tracked weakly) instead of only the most recently created one.
|
|
8
|
+
|
|
3
9
|
## 1.1.4
|
|
4
10
|
|
|
5
11
|
### Patch Changes
|
|
@@ -36,12 +36,25 @@ import kotlinx.coroutines.launch
|
|
|
36
36
|
import kotlinx.coroutines.future.await
|
|
37
37
|
import kotlinx.coroutines.runBlocking
|
|
38
38
|
import android.util.Log
|
|
39
|
+
import java.util.Collections
|
|
40
|
+
import java.util.WeakHashMap
|
|
39
41
|
import java.util.concurrent.CompletableFuture
|
|
40
42
|
|
|
41
43
|
class SuperwallExpoModule : Module() {
|
|
42
44
|
|
|
43
45
|
companion object {
|
|
44
46
|
var instance: SuperwallExpoModule? = null
|
|
47
|
+
private val instances = Collections.newSetFromMap(WeakHashMap<SuperwallExpoModule, Boolean>())
|
|
48
|
+
|
|
49
|
+
// Events must reach every live module instance. More than one app context can
|
|
50
|
+
// exist at once (e.g. expo-dev-client's launcher plus the app), and `instance`
|
|
51
|
+
// may point at a module whose JS runtime never subscribed - sending only
|
|
52
|
+
// through it silently drops events like `onPurchase`, leaving the native
|
|
53
|
+
// purchase future incomplete forever.
|
|
54
|
+
fun emitEvent(name: String, body: Map<String, Any?>?) {
|
|
55
|
+
val liveInstances = synchronized(instances) { instances.toList() }
|
|
56
|
+
liveInstances.forEach { it.sendEvent(name, body ?: emptyMap()) }
|
|
57
|
+
}
|
|
45
58
|
}
|
|
46
59
|
|
|
47
60
|
val scope = CoroutineScope(Dispatchers.Main)
|
|
@@ -50,10 +63,7 @@ class SuperwallExpoModule : Module() {
|
|
|
50
63
|
|
|
51
64
|
init {
|
|
52
65
|
instance = this
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
fun emitEvent(name: String, body: Map<String, Any?>?) {
|
|
56
|
-
SuperwallExpoModule.instance?.sendEvent(name, body?:emptyMap())
|
|
66
|
+
synchronized(instances) { instances.add(this) }
|
|
57
67
|
}
|
|
58
68
|
|
|
59
69
|
private val onPaywallPresent = "onPaywallPresent"
|
package/android/src/main/java/expo/modules/superwallexpo/bridges/PurchaseControllerBridge.kt
CHANGED
|
@@ -41,7 +41,7 @@ class PurchaseControllerBridge(): PurchaseController {
|
|
|
41
41
|
"offerId" to offerId
|
|
42
42
|
)
|
|
43
43
|
|
|
44
|
-
SuperwallExpoModule.
|
|
44
|
+
SuperwallExpoModule.emitEvent(
|
|
45
45
|
"onPurchase",
|
|
46
46
|
productData
|
|
47
47
|
)
|
|
@@ -52,7 +52,7 @@ class PurchaseControllerBridge(): PurchaseController {
|
|
|
52
52
|
override suspend fun restorePurchases(): RestorationResult {
|
|
53
53
|
restorePromise = CompletableFuture()
|
|
54
54
|
|
|
55
|
-
SuperwallExpoModule.
|
|
55
|
+
SuperwallExpoModule.emitEvent("onPurchaseRestore", null)
|
|
56
56
|
|
|
57
57
|
return restorePromise!!.await()
|
|
58
58
|
}
|
|
@@ -95,7 +95,7 @@ class SuperwallDelegateBridge : SuperwallDelegate {
|
|
|
95
95
|
}
|
|
96
96
|
|
|
97
97
|
private fun sendEvent(name: String, body: Map<String, Any?>) {
|
|
98
|
-
SuperwallExpoModule.
|
|
98
|
+
SuperwallExpoModule.emitEvent(name, body)
|
|
99
99
|
}
|
|
100
100
|
|
|
101
101
|
override fun willRedeemLink() {
|
package/build/package.json
CHANGED
|
@@ -31,6 +31,7 @@ export declare class PaywallOptions {
|
|
|
31
31
|
shouldPreload: boolean;
|
|
32
32
|
automaticallyDismiss: boolean;
|
|
33
33
|
transactionBackgroundView: TransactionBackgroundView;
|
|
34
|
+
shouldShowWebPurchaseConfirmationAlert: boolean;
|
|
34
35
|
onBackPressed?: (paywallInfo: PaywallInfo) => boolean;
|
|
35
36
|
constructor(init?: Partial<PaywallOptions>);
|
|
36
37
|
toJson(): object;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PaywallOptions.d.ts","sourceRoot":"","sources":["../../../../src/compat/lib/PaywallOptions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAahD;;;;GAIG;AACH,oBAAY,yBAAyB;IACnC,OAAO,YAAY;IACnB,IAAI,SAAS;CACd;AAED;;;;GAIG;AACH,qBAAa,aAAa;IACxB,KAAK,SAA0B;IAC/B,OAAO,SAA8D;IACrE,gBAAgB,SAAS;IAEzB,MAAM,IAAI,MAAM;CAOjB;AAED;;;;GAIG;AACH,qBAAa,cAAc;IACzB,uBAAuB,UAAO;IAC9B,aAAa,EAAE,aAAa,CAAsB;IAClD,8BAA8B,UAAO;IACrC,aAAa,UAAQ;IACrB,oBAAoB,UAAO;IAC3B,yBAAyB,EAAE,yBAAyB,CAAoC;IACxF,aAAa,CAAC,EAAE,CAAC,WAAW,EAAE,WAAW,KAAK,OAAO,CAAA;gBAEzC,IAAI,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"PaywallOptions.d.ts","sourceRoot":"","sources":["../../../../src/compat/lib/PaywallOptions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAahD;;;;GAIG;AACH,oBAAY,yBAAyB;IACnC,OAAO,YAAY;IACnB,IAAI,SAAS;CACd;AAED;;;;GAIG;AACH,qBAAa,aAAa;IACxB,KAAK,SAA0B;IAC/B,OAAO,SAA8D;IACrE,gBAAgB,SAAS;IAEzB,MAAM,IAAI,MAAM;CAOjB;AAED;;;;GAIG;AACH,qBAAa,cAAc;IACzB,uBAAuB,UAAO;IAC9B,aAAa,EAAE,aAAa,CAAsB;IAClD,8BAA8B,UAAO;IACrC,aAAa,UAAQ;IACrB,oBAAoB,UAAO;IAC3B,yBAAyB,EAAE,yBAAyB,CAAoC;IACxF,sCAAsC,UAAQ;IAC9C,aAAa,CAAC,EAAE,CAAC,WAAW,EAAE,WAAW,KAAK,OAAO,CAAA;gBAEzC,IAAI,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC;IAiC1C,MAAM,IAAI,MAAM;CAWjB"}
|
|
@@ -45,6 +45,7 @@ export class PaywallOptions {
|
|
|
45
45
|
shouldPreload = false;
|
|
46
46
|
automaticallyDismiss = true;
|
|
47
47
|
transactionBackgroundView = TransactionBackgroundView.spinner;
|
|
48
|
+
shouldShowWebPurchaseConfirmationAlert = false;
|
|
48
49
|
onBackPressed;
|
|
49
50
|
constructor(init) {
|
|
50
51
|
if (init) {
|
|
@@ -57,6 +58,9 @@ export class PaywallOptions {
|
|
|
57
58
|
if (init.shouldPreload !== undefined) {
|
|
58
59
|
this.shouldPreload = init.shouldPreload;
|
|
59
60
|
}
|
|
61
|
+
if (init.shouldShowWebPurchaseConfirmationAlert !== undefined) {
|
|
62
|
+
this.shouldShowWebPurchaseConfirmationAlert = init.shouldShowWebPurchaseConfirmationAlert;
|
|
63
|
+
}
|
|
60
64
|
if (init.automaticallyDismiss !== undefined) {
|
|
61
65
|
this.automaticallyDismiss = init.automaticallyDismiss;
|
|
62
66
|
}
|
|
@@ -83,6 +87,7 @@ export class PaywallOptions {
|
|
|
83
87
|
shouldPreload: this.shouldPreload,
|
|
84
88
|
automaticallyDismiss: this.automaticallyDismiss,
|
|
85
89
|
transactionBackgroundView: this.transactionBackgroundView,
|
|
90
|
+
shouldShowWebPurchaseConfirmationAlert: this.shouldShowWebPurchaseConfirmationAlert,
|
|
86
91
|
});
|
|
87
92
|
}
|
|
88
93
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PaywallOptions.js","sourceRoot":"","sources":["../../../../src/compat/lib/PaywallOptions.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"PaywallOptions.js","sourceRoot":"","sources":["../../../../src/compat/lib/PaywallOptions.ts"],"names":[],"mappings":"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","sourcesContent":["import type { PaywallInfo } from \"./PaywallInfo\"\n\n/**\n * Helper function to remove undefined values from an object.\n * This is necessary for Android compatibility as the Expo bridge\n * cannot convert undefined to Kotlin types.\n */\nfunction filterUndefined<T extends Record<string, any>>(obj: T): Partial<T> {\n return Object.fromEntries(\n Object.entries(obj).filter(([_, value]) => value !== undefined),\n ) as Partial<T>\n}\n\n/**\n * @category Enums\n * @since 0.0.15\n * Defines the different types of views that can appear behind Apple's payment sheet during a transaction.\n */\nexport enum TransactionBackgroundView {\n spinner = \"spinner\",\n none = \"none\",\n}\n\n/**\n * @category Models\n * @since 0.0.15\n * Defines the messaging of the alert presented to the user when restoring a transaction fails.\n */\nexport class RestoreFailed {\n title = \"No Subscription Found\"\n message = \"We couldn't find an active subscription for your account.\"\n closeButtonTitle = \"Okay\"\n\n toJson(): object {\n return filterUndefined({\n title: this.title,\n message: this.message,\n closeButtonTitle: this.closeButtonTitle,\n })\n }\n}\n\n/**\n * @category Models\n * @since 0.0.15\n * Options for configuring the appearance and behavior of paywalls.\n */\nexport class PaywallOptions {\n isHapticFeedbackEnabled = true\n restoreFailed: RestoreFailed = new RestoreFailed()\n shouldShowPurchaseFailureAlert = true\n shouldPreload = false\n automaticallyDismiss = true\n transactionBackgroundView: TransactionBackgroundView = TransactionBackgroundView.spinner\n shouldShowWebPurchaseConfirmationAlert = false\n onBackPressed?: (paywallInfo: PaywallInfo) => boolean\n\n constructor(init?: Partial<PaywallOptions>) {\n if (init) {\n if (init.isHapticFeedbackEnabled !== undefined) {\n this.isHapticFeedbackEnabled = init.isHapticFeedbackEnabled\n }\n if (init.shouldShowPurchaseFailureAlert !== undefined) {\n this.shouldShowPurchaseFailureAlert = init.shouldShowPurchaseFailureAlert\n }\n if (init.shouldPreload !== undefined) {\n this.shouldPreload = init.shouldPreload\n }\n if (init.shouldShowWebPurchaseConfirmationAlert !== undefined) {\n this.shouldShowWebPurchaseConfirmationAlert = init.shouldShowWebPurchaseConfirmationAlert\n }\n if (init.automaticallyDismiss !== undefined) {\n this.automaticallyDismiss = init.automaticallyDismiss\n }\n if (init.transactionBackgroundView) {\n this.transactionBackgroundView = init.transactionBackgroundView\n }\n if (init.onBackPressed) {\n this.onBackPressed = init.onBackPressed\n }\n if (init.restoreFailed) {\n // Ensure restoreFailed is always a RestoreFailed instance\n this.restoreFailed =\n init.restoreFailed instanceof RestoreFailed\n ? init.restoreFailed\n : Object.assign(new RestoreFailed(), init.restoreFailed)\n }\n }\n }\n\n toJson(): object {\n return filterUndefined({\n isHapticFeedbackEnabled: this.isHapticFeedbackEnabled,\n restoreFailed: this.restoreFailed.toJson(),\n shouldShowPurchaseFailureAlert: this.shouldShowPurchaseFailureAlert,\n shouldPreload: this.shouldPreload,\n automaticallyDismiss: this.automaticallyDismiss,\n transactionBackgroundView: this.transactionBackgroundView,\n shouldShowWebPurchaseConfirmationAlert: this.shouldShowWebPurchaseConfirmationAlert,\n })\n }\n}\n"]}
|
|
@@ -19,6 +19,8 @@ private final class AtomicFlag {
|
|
|
19
19
|
|
|
20
20
|
public class SuperwallExpoModule: Module {
|
|
21
21
|
public static var shared: SuperwallExpoModule?
|
|
22
|
+
private static let instancesLock = NSLock()
|
|
23
|
+
private static let instances = NSHashTable<SuperwallExpoModule>.weakObjects()
|
|
22
24
|
|
|
23
25
|
private let purchaseController = PurchaseControllerBridge.shared
|
|
24
26
|
private var delegate: SuperwallDelegateBridge?
|
|
@@ -55,10 +57,23 @@ public class SuperwallExpoModule: Module {
|
|
|
55
57
|
public required init(appContext: AppContext) {
|
|
56
58
|
super.init(appContext: appContext)
|
|
57
59
|
SuperwallExpoModule.shared = self
|
|
60
|
+
SuperwallExpoModule.instancesLock.lock()
|
|
61
|
+
SuperwallExpoModule.instances.add(self)
|
|
62
|
+
SuperwallExpoModule.instancesLock.unlock()
|
|
58
63
|
}
|
|
59
64
|
|
|
65
|
+
// Events must reach every live module instance. More than one app context can
|
|
66
|
+
// exist at once (e.g. expo-dev-client's launcher plus the app), and `shared`
|
|
67
|
+
// may point at an instance whose JS runtime never subscribed - sending only
|
|
68
|
+
// through it silently drops events like `onPurchase`, leaving the native
|
|
69
|
+
// purchase continuation suspended forever.
|
|
60
70
|
public static func emitEvent(_ name: String, _ data: [String: Any]?) {
|
|
61
|
-
|
|
71
|
+
instancesLock.lock()
|
|
72
|
+
let liveInstances = instances.allObjects
|
|
73
|
+
instancesLock.unlock()
|
|
74
|
+
for instance in liveInstances {
|
|
75
|
+
instance.sendEvent(name, data ?? [:])
|
|
76
|
+
}
|
|
62
77
|
}
|
|
63
78
|
|
|
64
79
|
public func definition() -> ModuleDefinition {
|