react-native-nami-sdk 3.4.1-dev.202605280043 → 3.4.1-dev.202605300006
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 +2 -2
- package/android/src/main/java/com/namiml/reactnative/{NamiFlowManagerBridge.kt → NamiFlowManagerBridgeModule.kt} +26 -1
- package/dist/specs/NativeNamiFlowManager.d.ts +2 -0
- package/dist/src/version.d.ts +1 -1
- package/ios/NamiFlowManagerBridge.m +2 -0
- package/ios/NamiFlowManagerBridge.swift +26 -5
- package/package.json +2 -2
- package/react-native-nami-sdk.podspec +1 -1
- package/specs/NativeNamiFlowManager.ts +2 -0
- package/src/NamiFlowManager.ts +8 -2
- package/src/__tests__/NamiFlowManager.test.ts +88 -0
- package/src/version.ts +1 -1
package/android/build.gradle
CHANGED
|
@@ -85,8 +85,8 @@ dependencies {
|
|
|
85
85
|
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
|
86
86
|
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
|
|
87
87
|
|
|
88
|
-
playImplementation "com.namiml:sdk-android:3.4.1-dev.
|
|
89
|
-
amazonImplementation "com.namiml:sdk-amazon:3.4.1-dev.
|
|
88
|
+
playImplementation "com.namiml:sdk-android:3.4.1-dev.202605300006"
|
|
89
|
+
amazonImplementation "com.namiml:sdk-amazon:3.4.1-dev.202605300006"
|
|
90
90
|
|
|
91
91
|
implementation "com.facebook.react:react-native:+" // From node_modules
|
|
92
92
|
coreLibraryDesugaring "com.android.tools:desugar_jdk_libs:2.0.4"
|
|
@@ -3,7 +3,12 @@ package com.namiml.reactnative
|
|
|
3
3
|
import android.os.Handler
|
|
4
4
|
import android.os.Looper
|
|
5
5
|
import android.util.Log
|
|
6
|
-
import com.facebook.react.bridge
|
|
6
|
+
import com.facebook.react.bridge.Arguments
|
|
7
|
+
import com.facebook.react.bridge.Promise
|
|
8
|
+
import com.facebook.react.bridge.ReactApplicationContext
|
|
9
|
+
import com.facebook.react.bridge.ReactContextBaseJavaModule
|
|
10
|
+
import com.facebook.react.bridge.ReactMethod
|
|
11
|
+
import com.facebook.react.bridge.WritableMap
|
|
7
12
|
import com.facebook.react.module.annotations.ReactModule
|
|
8
13
|
import com.facebook.react.modules.core.DeviceEventManagerModule
|
|
9
14
|
import com.facebook.react.turbomodule.core.interfaces.TurboModule
|
|
@@ -20,9 +25,17 @@ class NamiFlowManagerBridgeModule internal constructor(
|
|
|
20
25
|
|
|
21
26
|
override fun getName(): String = NAME
|
|
22
27
|
|
|
28
|
+
@Volatile
|
|
29
|
+
private var eventHandlerActive: Boolean = false
|
|
30
|
+
|
|
31
|
+
@Volatile
|
|
32
|
+
private var stepHandoffActive: Boolean = false
|
|
33
|
+
|
|
23
34
|
@ReactMethod
|
|
24
35
|
fun registerStepHandoff() {
|
|
36
|
+
stepHandoffActive = true
|
|
25
37
|
NamiFlowManager.registerStepHandoff { handoffTag, handoffData ->
|
|
38
|
+
if (!stepHandoffActive) return@registerStepHandoff
|
|
26
39
|
val payload =
|
|
27
40
|
Arguments.createMap().apply {
|
|
28
41
|
putString("handoffTag", handoffTag)
|
|
@@ -41,14 +54,26 @@ class NamiFlowManagerBridgeModule internal constructor(
|
|
|
41
54
|
}
|
|
42
55
|
}
|
|
43
56
|
|
|
57
|
+
@ReactMethod
|
|
58
|
+
fun unregisterStepHandoff() {
|
|
59
|
+
stepHandoffActive = false
|
|
60
|
+
}
|
|
61
|
+
|
|
44
62
|
@ReactMethod
|
|
45
63
|
fun registerEventHandler() {
|
|
64
|
+
eventHandlerActive = true
|
|
46
65
|
NamiFlowManager.registerEventHandler { data ->
|
|
66
|
+
if (!eventHandlerActive) return@registerEventHandler
|
|
47
67
|
val payload = Arguments.makeNativeMap(data)
|
|
48
68
|
sendEvent("FlowEvent", payload)
|
|
49
69
|
}
|
|
50
70
|
}
|
|
51
71
|
|
|
72
|
+
@ReactMethod
|
|
73
|
+
fun unregisterEventHandler() {
|
|
74
|
+
eventHandlerActive = false
|
|
75
|
+
}
|
|
76
|
+
|
|
52
77
|
@ReactMethod
|
|
53
78
|
fun resume() {
|
|
54
79
|
Handler(Looper.getMainLooper()).postDelayed({
|
|
@@ -3,9 +3,11 @@ export interface Spec extends TurboModule {
|
|
|
3
3
|
finish(): void;
|
|
4
4
|
isFlowOpen(): Promise<boolean>;
|
|
5
5
|
registerStepHandoff(): void;
|
|
6
|
+
unregisterStepHandoff(): void;
|
|
6
7
|
resume(): void;
|
|
7
8
|
pause(): void;
|
|
8
9
|
registerEventHandler(): void;
|
|
10
|
+
unregisterEventHandler(): void;
|
|
9
11
|
purchaseSuccess(): void;
|
|
10
12
|
}
|
|
11
13
|
declare const _default: Spec;
|
package/dist/src/version.d.ts
CHANGED
|
@@ -10,7 +10,9 @@
|
|
|
10
10
|
|
|
11
11
|
@interface RCT_EXTERN_MODULE(RNNamiFlowManager, RCTEventEmitter)
|
|
12
12
|
RCT_EXTERN_METHOD(registerStepHandoff)
|
|
13
|
+
RCT_EXTERN_METHOD(unregisterStepHandoff)
|
|
13
14
|
RCT_EXTERN_METHOD(registerEventHandler)
|
|
15
|
+
RCT_EXTERN_METHOD(unregisterEventHandler)
|
|
14
16
|
RCT_EXTERN_METHOD(resume)
|
|
15
17
|
RCT_EXTERN_METHOD(pause)
|
|
16
18
|
RCT_EXTERN_METHOD(finish)
|
|
@@ -17,11 +17,20 @@ class RNNamiFlowManager: RCTEventEmitter {
|
|
|
17
17
|
super.init()
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
override class func requiresMainQueueSetup() -> Bool {
|
|
20
|
+
override class func requiresMainQueueSetup() -> Bool {
|
|
21
|
+
true
|
|
22
|
+
}
|
|
21
23
|
|
|
22
24
|
private var hasListeners = false
|
|
23
|
-
|
|
24
|
-
|
|
25
|
+
private var eventHandlerActive = false
|
|
26
|
+
private var stepHandoffActive = false
|
|
27
|
+
override func startObserving() {
|
|
28
|
+
hasListeners = true
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
override func stopObserving() {
|
|
32
|
+
hasListeners = false
|
|
33
|
+
}
|
|
25
34
|
|
|
26
35
|
private func safeSend(withName name: String, body: Any?) {
|
|
27
36
|
guard hasListeners else {
|
|
@@ -36,7 +45,9 @@ class RNNamiFlowManager: RCTEventEmitter {
|
|
|
36
45
|
}
|
|
37
46
|
|
|
38
47
|
@objc func registerStepHandoff() {
|
|
39
|
-
|
|
48
|
+
stepHandoffActive = true
|
|
49
|
+
NamiFlowManager.registerStepHandoff { [weak self] tag, data in
|
|
50
|
+
guard let self = self, self.stepHandoffActive else { return }
|
|
40
51
|
var payload: [String: Any] = [
|
|
41
52
|
"handoffTag": tag,
|
|
42
53
|
]
|
|
@@ -48,12 +59,22 @@ class RNNamiFlowManager: RCTEventEmitter {
|
|
|
48
59
|
}
|
|
49
60
|
}
|
|
50
61
|
|
|
62
|
+
@objc func unregisterStepHandoff() {
|
|
63
|
+
stepHandoffActive = false
|
|
64
|
+
}
|
|
65
|
+
|
|
51
66
|
@objc func registerEventHandler() {
|
|
52
|
-
|
|
67
|
+
eventHandlerActive = true
|
|
68
|
+
NamiFlowManager.registerEventHandler { [weak self] payload in
|
|
69
|
+
guard let self = self, self.eventHandlerActive else { return }
|
|
53
70
|
self.safeSend(withName: "FlowEvent", body: payload)
|
|
54
71
|
}
|
|
55
72
|
}
|
|
56
73
|
|
|
74
|
+
@objc func unregisterEventHandler() {
|
|
75
|
+
eventHandlerActive = false
|
|
76
|
+
}
|
|
77
|
+
|
|
57
78
|
@objc func resume() {
|
|
58
79
|
NamiFlowManager.resume()
|
|
59
80
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-nami-sdk",
|
|
3
|
-
"version": "3.4.1-dev.
|
|
3
|
+
"version": "3.4.1-dev.202605300006",
|
|
4
4
|
"description": "React Native SDK for Nami - No-code paywall and onboarding flows with A/B testing.",
|
|
5
5
|
"main": "index.ts",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
]
|
|
64
64
|
},
|
|
65
65
|
"peerDependencies": {
|
|
66
|
-
"@namiml/expo-nami-iap": "3.4.1-dev.
|
|
66
|
+
"@namiml/expo-nami-iap": "3.4.1-dev.202605300006",
|
|
67
67
|
"react": ">=18",
|
|
68
68
|
"react-native": ">=0.73"
|
|
69
69
|
},
|
|
@@ -21,7 +21,7 @@ Pod::Spec.new do |s|
|
|
|
21
21
|
s.requires_arc = true
|
|
22
22
|
s.swift_version = '5.0' # or your supported version
|
|
23
23
|
|
|
24
|
-
s.dependency 'Nami', '3.4.1-dev.
|
|
24
|
+
s.dependency 'Nami', '3.4.1-dev.202605300006'
|
|
25
25
|
|
|
26
26
|
pod_target_xcconfig = {
|
|
27
27
|
'DEFINES_MODULE' => 'YES',
|
|
@@ -6,9 +6,11 @@ export interface Spec extends TurboModule {
|
|
|
6
6
|
isFlowOpen(): Promise<boolean>;
|
|
7
7
|
|
|
8
8
|
registerStepHandoff(): void;
|
|
9
|
+
unregisterStepHandoff(): void;
|
|
9
10
|
resume(): void;
|
|
10
11
|
pause(): void;
|
|
11
12
|
registerEventHandler(): void;
|
|
13
|
+
unregisterEventHandler(): void;
|
|
12
14
|
purchaseSuccess(): void;
|
|
13
15
|
}
|
|
14
16
|
|
package/src/NamiFlowManager.ts
CHANGED
|
@@ -38,7 +38,10 @@ export const NamiFlowManager = {
|
|
|
38
38
|
|
|
39
39
|
RNNamiFlowManager.registerStepHandoff?.();
|
|
40
40
|
|
|
41
|
-
return () =>
|
|
41
|
+
return () => {
|
|
42
|
+
sub.remove();
|
|
43
|
+
RNNamiFlowManager.unregisterStepHandoff?.();
|
|
44
|
+
};
|
|
42
45
|
},
|
|
43
46
|
|
|
44
47
|
resume: (): void => {
|
|
@@ -56,7 +59,10 @@ export const NamiFlowManager = {
|
|
|
56
59
|
): (() => void) => {
|
|
57
60
|
const sub = emitter.addListener(NamiFlowManagerEvents.FlowEvent, callback);
|
|
58
61
|
RNNamiFlowManager.registerEventHandler?.();
|
|
59
|
-
return () =>
|
|
62
|
+
return () => {
|
|
63
|
+
sub.remove();
|
|
64
|
+
RNNamiFlowManager.unregisterEventHandler?.();
|
|
65
|
+
};
|
|
60
66
|
},
|
|
61
67
|
|
|
62
68
|
finish: (): void => {
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
// Mock react-native BEFORE importing the SDK — `../NamiFlowManager` resolves
|
|
2
|
+
// the native module via TurboModuleRegistry at import time, and the
|
|
3
|
+
// NativeEventEmitter constructor is called at module top-level.
|
|
4
|
+
|
|
5
|
+
const registerStepHandoff = jest.fn();
|
|
6
|
+
const unregisterStepHandoff = jest.fn();
|
|
7
|
+
const registerEventHandler = jest.fn();
|
|
8
|
+
const unregisterEventHandler = jest.fn();
|
|
9
|
+
const finishMock = jest.fn();
|
|
10
|
+
const isFlowOpenMock = jest.fn().mockResolvedValue(false);
|
|
11
|
+
const resumeMock = jest.fn();
|
|
12
|
+
const pauseMock = jest.fn();
|
|
13
|
+
|
|
14
|
+
const subRemove = jest.fn();
|
|
15
|
+
const addListener = jest.fn(() => ({ remove: subRemove }));
|
|
16
|
+
|
|
17
|
+
jest.mock('react-native', () => ({
|
|
18
|
+
TurboModuleRegistry: {
|
|
19
|
+
getEnforcing: jest.fn(() => ({
|
|
20
|
+
registerStepHandoff,
|
|
21
|
+
unregisterStepHandoff,
|
|
22
|
+
registerEventHandler,
|
|
23
|
+
unregisterEventHandler,
|
|
24
|
+
finish: finishMock,
|
|
25
|
+
isFlowOpen: isFlowOpenMock,
|
|
26
|
+
resume: resumeMock,
|
|
27
|
+
pause: pauseMock,
|
|
28
|
+
})),
|
|
29
|
+
},
|
|
30
|
+
NativeModules: {
|
|
31
|
+
RNNamiFlowManager: {
|
|
32
|
+
registerStepHandoff,
|
|
33
|
+
unregisterStepHandoff,
|
|
34
|
+
registerEventHandler,
|
|
35
|
+
unregisterEventHandler,
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
NativeEventEmitter: jest.fn().mockImplementation(() => ({
|
|
39
|
+
addListener,
|
|
40
|
+
})),
|
|
41
|
+
}));
|
|
42
|
+
|
|
43
|
+
import { NamiFlowManager } from '../NamiFlowManager';
|
|
44
|
+
|
|
45
|
+
describe('NamiFlowManager (React Native bridge)', () => {
|
|
46
|
+
beforeEach(() => {
|
|
47
|
+
registerStepHandoff.mockClear();
|
|
48
|
+
unregisterStepHandoff.mockClear();
|
|
49
|
+
registerEventHandler.mockClear();
|
|
50
|
+
unregisterEventHandler.mockClear();
|
|
51
|
+
subRemove.mockClear();
|
|
52
|
+
addListener.mockClear();
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
describe('registerStepHandoff', () => {
|
|
56
|
+
it('returns a function and triggers native register', () => {
|
|
57
|
+
const unsubscribe = NamiFlowManager.registerStepHandoff(() => {});
|
|
58
|
+
expect(typeof unsubscribe).toBe('function');
|
|
59
|
+
expect(registerStepHandoff).toHaveBeenCalledTimes(1);
|
|
60
|
+
expect(addListener).toHaveBeenCalledTimes(1);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it('returned unsubscribe removes the JS listener AND calls native unregister', () => {
|
|
64
|
+
const unsubscribe = NamiFlowManager.registerStepHandoff(() => {});
|
|
65
|
+
unsubscribe();
|
|
66
|
+
|
|
67
|
+
expect(subRemove).toHaveBeenCalledTimes(1);
|
|
68
|
+
expect(unregisterStepHandoff).toHaveBeenCalledTimes(1);
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
describe('registerEventHandler', () => {
|
|
73
|
+
it('returns a function and triggers native register', () => {
|
|
74
|
+
const unsubscribe = NamiFlowManager.registerEventHandler(() => {});
|
|
75
|
+
expect(typeof unsubscribe).toBe('function');
|
|
76
|
+
expect(registerEventHandler).toHaveBeenCalledTimes(1);
|
|
77
|
+
expect(addListener).toHaveBeenCalledTimes(1);
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it('returned unsubscribe removes the JS listener AND calls native unregister', () => {
|
|
81
|
+
const unsubscribe = NamiFlowManager.registerEventHandler(() => {});
|
|
82
|
+
unsubscribe();
|
|
83
|
+
|
|
84
|
+
expect(subRemove).toHaveBeenCalledTimes(1);
|
|
85
|
+
expect(unregisterEventHandler).toHaveBeenCalledTimes(1);
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
});
|
package/src/version.ts
CHANGED