@primer-io/react-native 2.43.0 → 2.44.0
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/android/build.gradle +1 -1
- package/android/src/main/java/com/primerioreactnative/datamodels/PrimerSettingsRN.kt +6 -3
- package/android/src/main/java/com/primerioreactnative/extensions/PrimerUIOptionsRN.kt +3 -2
- package/ios/Sources/version.swift +1 -1
- package/lib/module/HeadlessUniversalCheckout/Managers/PaymentMethodManagers/KlarnaManager.js +33 -9
- package/lib/module/HeadlessUniversalCheckout/Managers/PaymentMethodManagers/KlarnaManager.js.map +1 -1
- package/lib/typescript/src/HeadlessUniversalCheckout/Managers/PaymentMethodManagers/KlarnaManager.d.ts +9 -0
- package/lib/typescript/src/HeadlessUniversalCheckout/Managers/PaymentMethodManagers/KlarnaManager.d.ts.map +1 -1
- package/package.json +1 -1
- package/primer-io-react-native.podspec +1 -1
- package/src/HeadlessUniversalCheckout/Managers/PaymentMethodManagers/KlarnaManager.ts +41 -9
package/android/build.gradle
CHANGED
|
@@ -133,7 +133,7 @@ dependencies {
|
|
|
133
133
|
implementation 'com.facebook.react:react-native:+'
|
|
134
134
|
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
|
135
135
|
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.3"
|
|
136
|
-
implementation 'io.primer:android:2.
|
|
136
|
+
implementation 'io.primer:android:2.50.0'
|
|
137
137
|
testImplementation 'io.mockk:mockk:1.14.2'
|
|
138
138
|
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.10.2'
|
|
139
139
|
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.10.2'
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
package com.primerioreactnative.datamodels
|
|
2
2
|
|
|
3
3
|
import android.content.Context
|
|
4
|
+
import android.content.res.Configuration
|
|
4
5
|
import com.primerioreactnative.extensions.toLocale
|
|
5
6
|
import com.primerioreactnative.extensions.toPrimerDebugOptions
|
|
6
7
|
import com.primerioreactnative.extensions.toPrimerPaymentMethodOptions
|
|
@@ -62,8 +63,10 @@ data class PrimerThemeRN(
|
|
|
62
63
|
val colors: ColorThemeRN? = null,
|
|
63
64
|
val darkModeColors: ColorThemeRN? = null,
|
|
64
65
|
) {
|
|
65
|
-
fun toPrimerTheme(): PrimerTheme {
|
|
66
|
-
val isDarkMode =
|
|
66
|
+
fun toPrimerTheme(context: Context): PrimerTheme {
|
|
67
|
+
val isDarkMode =
|
|
68
|
+
(context.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK) ==
|
|
69
|
+
Configuration.UI_MODE_NIGHT_YES
|
|
67
70
|
|
|
68
71
|
return PrimerTheme.buildWithDynamicValues(
|
|
69
72
|
isDarkMode = isDarkMode,
|
|
@@ -206,7 +209,7 @@ fun PrimerSettingsRN.toPrimerSettings(context: Context) =
|
|
|
206
209
|
paymentHandling = paymentHandling,
|
|
207
210
|
locale = localeData.toLocale(),
|
|
208
211
|
paymentMethodOptions = paymentMethodOptions.toPrimerPaymentMethodOptions(context),
|
|
209
|
-
uiOptions = uiOptions.toPrimerUIOptions(),
|
|
212
|
+
uiOptions = uiOptions.toPrimerUIOptions(context),
|
|
210
213
|
debugOptions = debugOptions.toPrimerDebugOptions(),
|
|
211
214
|
clientSessionCachingEnabled = clientSessionCachingEnabled,
|
|
212
215
|
apiVersion = when (apiVersion) {
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
package com.primerioreactnative.extensions
|
|
2
2
|
|
|
3
|
+
import android.content.Context
|
|
3
4
|
import com.primerioreactnative.datamodels.PrimerUIOptionsRN
|
|
4
5
|
import io.primer.android.data.settings.DismissalMechanism
|
|
5
6
|
import io.primer.android.ui.settings.PrimerUIOptions
|
|
6
7
|
|
|
7
8
|
@OptIn(kotlin.ExperimentalStdlibApi::class)
|
|
8
|
-
internal fun PrimerUIOptionsRN.toPrimerUIOptions() =
|
|
9
|
+
internal fun PrimerUIOptionsRN.toPrimerUIOptions(context: Context) =
|
|
9
10
|
PrimerUIOptions(
|
|
10
11
|
isInitScreenEnabled,
|
|
11
12
|
isSuccessScreenEnabled,
|
|
@@ -19,6 +20,6 @@ internal fun PrimerUIOptionsRN.toPrimerUIOptions() =
|
|
|
19
20
|
}
|
|
20
21
|
}
|
|
21
22
|
}.toList().takeIf { it.isNotEmpty() } ?: listOf(DismissalMechanism.GESTURES),
|
|
22
|
-
theme.toPrimerTheme(),
|
|
23
|
+
theme.toPrimerTheme(context),
|
|
23
24
|
cardFormUIOptions.toPrimerCardFormUIOptions(),
|
|
24
25
|
)
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// swiftlint:disable:next identifier_name
|
|
2
|
-
public let PrimerReactNativeSDKVersion = "2.
|
|
2
|
+
public let PrimerReactNativeSDKVersion = "2.44.0"
|
package/lib/module/HeadlessUniversalCheckout/Managers/PaymentMethodManagers/KlarnaManager.js
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
import { NativeEventEmitter, NativeModules } from 'react-native';
|
|
4
|
-
import { eventTypes } from "./Utils/EventType.js";
|
|
5
4
|
const {
|
|
6
5
|
RNTPrimerHeadlessUniversalCheckoutKlarnaComponent
|
|
7
6
|
} = NativeModules;
|
|
8
7
|
const eventEmitter = new NativeEventEmitter(RNTPrimerHeadlessUniversalCheckoutKlarnaComponent);
|
|
9
8
|
export class PrimerHeadlessUniversalCheckoutKlarnaManager {
|
|
9
|
+
subscriptions = [];
|
|
10
|
+
|
|
10
11
|
///////////////////////////////////////////
|
|
11
12
|
// Init
|
|
12
13
|
///////////////////////////////////////////
|
|
@@ -17,6 +18,9 @@ export class PrimerHeadlessUniversalCheckoutKlarnaManager {
|
|
|
17
18
|
///////////////////////////////////////////
|
|
18
19
|
|
|
19
20
|
async provide(props) {
|
|
21
|
+
// Drain any subscriptions left over from a previous provide() on this instance,
|
|
22
|
+
// so consumers who skip explicit cleanUp don't accumulate duplicate listeners.
|
|
23
|
+
this.drainSubscriptions();
|
|
20
24
|
await this.configureListeners(props);
|
|
21
25
|
const klarnaComponent = {
|
|
22
26
|
start: async () => {
|
|
@@ -36,6 +40,10 @@ export class PrimerHeadlessUniversalCheckoutKlarnaManager {
|
|
|
36
40
|
},
|
|
37
41
|
finalizePayment: async () => {
|
|
38
42
|
RNTPrimerHeadlessUniversalCheckoutKlarnaComponent.onFinalizePayment();
|
|
43
|
+
},
|
|
44
|
+
cleanUp: async () => {
|
|
45
|
+
await RNTPrimerHeadlessUniversalCheckoutKlarnaComponent.cleanUp();
|
|
46
|
+
this.drainSubscriptions();
|
|
39
47
|
}
|
|
40
48
|
};
|
|
41
49
|
await RNTPrimerHeadlessUniversalCheckoutKlarnaComponent.configure(props.primerSessionIntent);
|
|
@@ -43,34 +51,40 @@ export class PrimerHeadlessUniversalCheckoutKlarnaManager {
|
|
|
43
51
|
}
|
|
44
52
|
async configureListeners(props) {
|
|
45
53
|
if (props?.onStep) {
|
|
46
|
-
this.addListener('onStep', data => {
|
|
54
|
+
const sub = await this.addListener('onStep', data => {
|
|
47
55
|
props.onStep?.(data);
|
|
48
56
|
});
|
|
57
|
+
this.subscriptions.push(sub);
|
|
49
58
|
}
|
|
50
59
|
if (props?.onInvalid) {
|
|
51
|
-
this.addListener('onInvalid', data => {
|
|
60
|
+
const sub = await this.addListener('onInvalid', data => {
|
|
52
61
|
props.onInvalid?.(data);
|
|
53
62
|
});
|
|
63
|
+
this.subscriptions.push(sub);
|
|
54
64
|
}
|
|
55
65
|
if (props?.onError) {
|
|
56
|
-
this.addListener('onError', data => {
|
|
66
|
+
const sub = await this.addListener('onError', data => {
|
|
57
67
|
props.onError?.(data);
|
|
58
68
|
});
|
|
69
|
+
this.subscriptions.push(sub);
|
|
59
70
|
}
|
|
60
71
|
if (props?.onValid) {
|
|
61
|
-
this.addListener('onValid', data => {
|
|
72
|
+
const sub = await this.addListener('onValid', data => {
|
|
62
73
|
props.onValid?.(data);
|
|
63
74
|
});
|
|
75
|
+
this.subscriptions.push(sub);
|
|
64
76
|
}
|
|
65
77
|
if (props?.onValidating) {
|
|
66
|
-
this.addListener('onValidating', data => {
|
|
78
|
+
const sub = await this.addListener('onValidating', data => {
|
|
67
79
|
props.onValidating?.(data);
|
|
68
80
|
});
|
|
81
|
+
this.subscriptions.push(sub);
|
|
69
82
|
}
|
|
70
83
|
if (props?.onValidationError) {
|
|
71
|
-
this.addListener('onValidationError', data => {
|
|
84
|
+
const sub = await this.addListener('onValidationError', data => {
|
|
72
85
|
props.onValidationError?.(data);
|
|
73
86
|
});
|
|
87
|
+
this.subscriptions.push(sub);
|
|
74
88
|
}
|
|
75
89
|
}
|
|
76
90
|
|
|
@@ -82,13 +96,23 @@ export class PrimerHeadlessUniversalCheckoutKlarnaManager {
|
|
|
82
96
|
return eventEmitter.addListener(eventType, listener);
|
|
83
97
|
}
|
|
84
98
|
removeListener(subscription) {
|
|
85
|
-
|
|
99
|
+
subscription.remove();
|
|
100
|
+
this.subscriptions = this.subscriptions.filter(sub => sub !== subscription);
|
|
86
101
|
}
|
|
87
102
|
removeAllListenersForEvent(eventType) {
|
|
88
103
|
eventEmitter.removeAllListeners(eventType);
|
|
89
104
|
}
|
|
105
|
+
|
|
106
|
+
// Routes through per-instance bookkeeping. Avoids the global-nuke approach
|
|
107
|
+
// (eventEmitter.removeAllListeners(eventName)) which on Android would also
|
|
108
|
+
// wipe other modules' listeners for overlapping event names like onError —
|
|
109
|
+
// those modules share the global RCTDeviceEventEmitter.
|
|
90
110
|
removeAllListeners() {
|
|
91
|
-
|
|
111
|
+
this.drainSubscriptions();
|
|
112
|
+
}
|
|
113
|
+
drainSubscriptions() {
|
|
114
|
+
this.subscriptions.forEach(subscription => subscription.remove());
|
|
115
|
+
this.subscriptions = [];
|
|
92
116
|
}
|
|
93
117
|
}
|
|
94
118
|
//# sourceMappingURL=KlarnaManager.js.map
|
package/lib/module/HeadlessUniversalCheckout/Managers/PaymentMethodManagers/KlarnaManager.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["NativeEventEmitter","NativeModules","
|
|
1
|
+
{"version":3,"names":["NativeEventEmitter","NativeModules","RNTPrimerHeadlessUniversalCheckoutKlarnaComponent","eventEmitter","PrimerHeadlessUniversalCheckoutKlarnaManager","subscriptions","constructor","provide","props","drainSubscriptions","configureListeners","klarnaComponent","start","submit","onSetPaymentOptions","paymentOptions","handlePaymentOptionsChange","onFinalizePayment","finalizePayment","cleanUp","configure","primerSessionIntent","onStep","sub","addListener","data","push","onInvalid","onError","onValid","onValidating","onValidationError","eventType","listener","removeListener","subscription","remove","filter","removeAllListenersForEvent","removeAllListeners","forEach"],"sourceRoot":"../../../../../src","sources":["HeadlessUniversalCheckout/Managers/PaymentMethodManagers/KlarnaManager.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -50,8 +50,16 @@ export interface KlarnaComponent {
|
|
|
50
50
|
* {@link handlePaymentOptionsChange}.
|
|
51
51
|
*/
|
|
52
52
|
submit(): Promise<void>;
|
|
53
|
+
/**
|
|
54
|
+
* Tears down the underlying Klarna component and releases the JS event
|
|
55
|
+
* subscriptions registered by {@link KlarnaManager.provide}. Call this after
|
|
56
|
+
* a payment completes (or before initiating another) to allow consecutive
|
|
57
|
+
* Klarna payments within the same app session.
|
|
58
|
+
*/
|
|
59
|
+
cleanUp(): Promise<void>;
|
|
53
60
|
}
|
|
54
61
|
export declare class PrimerHeadlessUniversalCheckoutKlarnaManager {
|
|
62
|
+
private subscriptions;
|
|
55
63
|
constructor();
|
|
56
64
|
provide(props: KlarnaManagerProps): Promise<KlarnaComponent>;
|
|
57
65
|
private configureListeners;
|
|
@@ -59,5 +67,6 @@ export declare class PrimerHeadlessUniversalCheckoutKlarnaManager {
|
|
|
59
67
|
removeListener(subscription: EmitterSubscription): void;
|
|
60
68
|
removeAllListenersForEvent(eventType: EventType): void;
|
|
61
69
|
removeAllListeners(): void;
|
|
70
|
+
private drainSubscriptions;
|
|
62
71
|
}
|
|
63
72
|
//# sourceMappingURL=KlarnaManager.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"KlarnaManager.d.ts","sourceRoot":"","sources":["../../../../../../src/HeadlessUniversalCheckout/Managers/PaymentMethodManagers/KlarnaManager.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACxD,OAAO,KAAK,EACV,kCAAkC,EAClC,0BAA0B,EAC1B,wBAAwB,EACxB,6BAA6B,EAC9B,MAAM,+CAA+C,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC1D,OAAO,KAAK,EACV,oBAAoB,EACpB,4BAA4B,EAC7B,MAAM,qDAAqD,CAAC;AAC7D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2CAA2C,CAAC;
|
|
1
|
+
{"version":3,"file":"KlarnaManager.d.ts","sourceRoot":"","sources":["../../../../../../src/HeadlessUniversalCheckout/Managers/PaymentMethodManagers/KlarnaManager.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACxD,OAAO,KAAK,EACV,kCAAkC,EAClC,0BAA0B,EAC1B,wBAAwB,EACxB,6BAA6B,EAC9B,MAAM,+CAA+C,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC1D,OAAO,KAAK,EACV,oBAAoB,EACpB,4BAA4B,EAC7B,MAAM,qDAAqD,CAAC;AAC7D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2CAA2C,CAAC;AACnF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAK1E,MAAM,WAAW,kBAAkB;IACjC,mBAAmB,EAAE,mBAAmB,CAAC;IACzC,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,iBAAiB,KAAK,IAAI,CAAC;IAC3C,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;IACvC,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,0BAA0B,CAAC,4BAA4B,CAAC,KAAK,IAAI,CAAC;IACrF,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,wBAAwB,CAAC,4BAA4B,CAAC,KAAK,IAAI,CAAC;IACjF,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,6BAA6B,CAAC,4BAA4B,CAAC,KAAK,IAAI,CAAC;IAC3F,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,kCAAkC,CAAC,4BAA4B,CAAC,KAAK,IAAI,CAAC;CACtG;AAED,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvB;;;;;;OAMG;IACH,mBAAmB,CAAC,cAAc,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEzE;;;;;OAKG;IACH,0BAA0B,CAAC,cAAc,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEhF;;;OAGG;IACH,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEnC;;OAEG;IACH,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjC;;;;OAIG;IACH,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAExB;;;;;OAKG;IACH,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B;AAED,qBAAa,4CAA4C;IACvD,OAAO,CAAC,aAAa,CAA6B;;IAW5C,OAAO,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,eAAe,CAAC;YAkCpD,kBAAkB;IAgD1B,WAAW,CAAC,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAIxG,cAAc,CAAC,YAAY,EAAE,mBAAmB,GAAG,IAAI;IAKvD,0BAA0B,CAAC,SAAS,EAAE,SAAS;IAQ/C,kBAAkB;IAIlB,OAAO,CAAC,kBAAkB;CAI3B"}
|
package/package.json
CHANGED
|
@@ -17,7 +17,7 @@ Pod::Spec.new do |s|
|
|
|
17
17
|
s.private_header_files = ['ios/PrimerSwiftInterop.h' ]
|
|
18
18
|
|
|
19
19
|
s.dependency "React-Core"
|
|
20
|
-
s.dependency "PrimerSDK", "2.
|
|
20
|
+
s.dependency "PrimerSDK", "2.48.0"
|
|
21
21
|
|
|
22
22
|
s.pod_target_xcconfig = {
|
|
23
23
|
"SWIFT_ENABLE_EXPLICIT_MODULES" => "NO"
|
|
@@ -12,7 +12,6 @@ import type {
|
|
|
12
12
|
KlarnaPaymentValidatableData,
|
|
13
13
|
} from '../../../models/klarna/KlarnaPaymentCollectableData';
|
|
14
14
|
import type { KlarnaPaymentStep } from '../../../models/klarna/KlarnaPaymentSteps';
|
|
15
|
-
import { eventTypes } from './Utils/EventType';
|
|
16
15
|
import type { EventType } from './Utils/EventType';
|
|
17
16
|
import { PrimerSessionIntent } from '../../../models/PrimerSessionIntent';
|
|
18
17
|
|
|
@@ -70,9 +69,19 @@ export interface KlarnaComponent {
|
|
|
70
69
|
* {@link handlePaymentOptionsChange}.
|
|
71
70
|
*/
|
|
72
71
|
submit(): Promise<void>;
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Tears down the underlying Klarna component and releases the JS event
|
|
75
|
+
* subscriptions registered by {@link KlarnaManager.provide}. Call this after
|
|
76
|
+
* a payment completes (or before initiating another) to allow consecutive
|
|
77
|
+
* Klarna payments within the same app session.
|
|
78
|
+
*/
|
|
79
|
+
cleanUp(): Promise<void>;
|
|
73
80
|
}
|
|
74
81
|
|
|
75
82
|
export class PrimerHeadlessUniversalCheckoutKlarnaManager {
|
|
83
|
+
private subscriptions: EmitterSubscription[] = [];
|
|
84
|
+
|
|
76
85
|
///////////////////////////////////////////
|
|
77
86
|
// Init
|
|
78
87
|
///////////////////////////////////////////
|
|
@@ -83,6 +92,9 @@ export class PrimerHeadlessUniversalCheckoutKlarnaManager {
|
|
|
83
92
|
///////////////////////////////////////////
|
|
84
93
|
|
|
85
94
|
async provide(props: KlarnaManagerProps): Promise<KlarnaComponent> {
|
|
95
|
+
// Drain any subscriptions left over from a previous provide() on this instance,
|
|
96
|
+
// so consumers who skip explicit cleanUp don't accumulate duplicate listeners.
|
|
97
|
+
this.drainSubscriptions();
|
|
86
98
|
await this.configureListeners(props);
|
|
87
99
|
|
|
88
100
|
const klarnaComponent: KlarnaComponent = {
|
|
@@ -104,6 +116,10 @@ export class PrimerHeadlessUniversalCheckoutKlarnaManager {
|
|
|
104
116
|
finalizePayment: async () => {
|
|
105
117
|
RNTPrimerHeadlessUniversalCheckoutKlarnaComponent.onFinalizePayment();
|
|
106
118
|
},
|
|
119
|
+
cleanUp: async () => {
|
|
120
|
+
await RNTPrimerHeadlessUniversalCheckoutKlarnaComponent.cleanUp();
|
|
121
|
+
this.drainSubscriptions();
|
|
122
|
+
},
|
|
107
123
|
};
|
|
108
124
|
await RNTPrimerHeadlessUniversalCheckoutKlarnaComponent.configure(props.primerSessionIntent);
|
|
109
125
|
return klarnaComponent;
|
|
@@ -111,39 +127,45 @@ export class PrimerHeadlessUniversalCheckoutKlarnaManager {
|
|
|
111
127
|
|
|
112
128
|
private async configureListeners(props: KlarnaManagerProps): Promise<void> {
|
|
113
129
|
if (props?.onStep) {
|
|
114
|
-
this.addListener('onStep', (data) => {
|
|
130
|
+
const sub = await this.addListener('onStep', (data) => {
|
|
115
131
|
props.onStep?.(data);
|
|
116
132
|
});
|
|
133
|
+
this.subscriptions.push(sub);
|
|
117
134
|
}
|
|
118
135
|
|
|
119
136
|
if (props?.onInvalid) {
|
|
120
|
-
this.addListener('onInvalid', (data) => {
|
|
137
|
+
const sub = await this.addListener('onInvalid', (data) => {
|
|
121
138
|
props.onInvalid?.(data);
|
|
122
139
|
});
|
|
140
|
+
this.subscriptions.push(sub);
|
|
123
141
|
}
|
|
124
142
|
|
|
125
143
|
if (props?.onError) {
|
|
126
|
-
this.addListener('onError', (data) => {
|
|
144
|
+
const sub = await this.addListener('onError', (data) => {
|
|
127
145
|
props.onError?.(data);
|
|
128
146
|
});
|
|
147
|
+
this.subscriptions.push(sub);
|
|
129
148
|
}
|
|
130
149
|
|
|
131
150
|
if (props?.onValid) {
|
|
132
|
-
this.addListener('onValid', (data) => {
|
|
151
|
+
const sub = await this.addListener('onValid', (data) => {
|
|
133
152
|
props.onValid?.(data);
|
|
134
153
|
});
|
|
154
|
+
this.subscriptions.push(sub);
|
|
135
155
|
}
|
|
136
156
|
|
|
137
157
|
if (props?.onValidating) {
|
|
138
|
-
this.addListener('onValidating', (data) => {
|
|
158
|
+
const sub = await this.addListener('onValidating', (data) => {
|
|
139
159
|
props.onValidating?.(data);
|
|
140
160
|
});
|
|
161
|
+
this.subscriptions.push(sub);
|
|
141
162
|
}
|
|
142
163
|
|
|
143
164
|
if (props?.onValidationError) {
|
|
144
|
-
this.addListener('onValidationError', (data) => {
|
|
165
|
+
const sub = await this.addListener('onValidationError', (data) => {
|
|
145
166
|
props.onValidationError?.(data);
|
|
146
167
|
});
|
|
168
|
+
this.subscriptions.push(sub);
|
|
147
169
|
}
|
|
148
170
|
}
|
|
149
171
|
|
|
@@ -156,14 +178,24 @@ export class PrimerHeadlessUniversalCheckoutKlarnaManager {
|
|
|
156
178
|
}
|
|
157
179
|
|
|
158
180
|
removeListener(subscription: EmitterSubscription): void {
|
|
159
|
-
|
|
181
|
+
subscription.remove();
|
|
182
|
+
this.subscriptions = this.subscriptions.filter((sub) => sub !== subscription);
|
|
160
183
|
}
|
|
161
184
|
|
|
162
185
|
removeAllListenersForEvent(eventType: EventType) {
|
|
163
186
|
eventEmitter.removeAllListeners(eventType);
|
|
164
187
|
}
|
|
165
188
|
|
|
189
|
+
// Routes through per-instance bookkeeping. Avoids the global-nuke approach
|
|
190
|
+
// (eventEmitter.removeAllListeners(eventName)) which on Android would also
|
|
191
|
+
// wipe other modules' listeners for overlapping event names like onError —
|
|
192
|
+
// those modules share the global RCTDeviceEventEmitter.
|
|
166
193
|
removeAllListeners() {
|
|
167
|
-
|
|
194
|
+
this.drainSubscriptions();
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
private drainSubscriptions(): void {
|
|
198
|
+
this.subscriptions.forEach((subscription) => subscription.remove());
|
|
199
|
+
this.subscriptions = [];
|
|
168
200
|
}
|
|
169
201
|
}
|