react-native-marketap-sdk 0.1.0-beta.11 → 0.1.0-beta.13

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 (43) hide show
  1. package/android/build.gradle +1 -1
  2. package/android/src/main/AndroidManifest.xml +1 -10
  3. package/android/src/main/java/com/marketapsdk/MarketapSdkModule.kt +278 -69
  4. package/android/src/main/java/com/marketapsdk/ReactNativeBridgeRegistry.kt +110 -0
  5. package/ios/MarketapSdk.m +30 -23
  6. package/ios/MarketapSdk.swift +163 -22
  7. package/lib/commonjs/MarketapWebBridge.js +205 -15
  8. package/lib/commonjs/MarketapWebBridge.js.map +1 -1
  9. package/lib/commonjs/core/MarketapCore.js +233 -0
  10. package/lib/commonjs/core/MarketapCore.js.map +1 -0
  11. package/lib/commonjs/index.js +20 -166
  12. package/lib/commonjs/index.js.map +1 -1
  13. package/lib/commonjs/internal/marketapCore.js +9 -0
  14. package/lib/commonjs/internal/marketapCore.js.map +1 -0
  15. package/lib/commonjs/internal/marketapPlugin.js +40 -0
  16. package/lib/commonjs/internal/marketapPlugin.js.map +1 -0
  17. package/lib/commonjs/version.js +1 -1
  18. package/lib/module/MarketapWebBridge.js +204 -15
  19. package/lib/module/MarketapWebBridge.js.map +1 -1
  20. package/lib/module/core/MarketapCore.js +226 -0
  21. package/lib/module/core/MarketapCore.js.map +1 -0
  22. package/lib/module/index.js +20 -165
  23. package/lib/module/index.js.map +1 -1
  24. package/lib/module/internal/marketapCore.js +3 -0
  25. package/lib/module/internal/marketapCore.js.map +1 -0
  26. package/lib/module/internal/marketapPlugin.js +35 -0
  27. package/lib/module/internal/marketapPlugin.js.map +1 -0
  28. package/lib/module/version.js +1 -1
  29. package/lib/typescript/MarketapWebBridge.d.ts +33 -6
  30. package/lib/typescript/MarketapWebBridge.d.ts.map +1 -1
  31. package/lib/typescript/core/MarketapCore.d.ts +54 -0
  32. package/lib/typescript/core/MarketapCore.d.ts.map +1 -0
  33. package/lib/typescript/index.d.ts +2 -41
  34. package/lib/typescript/index.d.ts.map +1 -1
  35. package/lib/typescript/internal/marketapCore.d.ts +3 -0
  36. package/lib/typescript/internal/marketapCore.d.ts.map +1 -0
  37. package/lib/typescript/internal/marketapPlugin.d.ts +10 -0
  38. package/lib/typescript/internal/marketapPlugin.d.ts.map +1 -0
  39. package/lib/typescript/types.d.ts +1 -2
  40. package/lib/typescript/types.d.ts.map +1 -1
  41. package/lib/typescript/version.d.ts +1 -1
  42. package/package.json +1 -1
  43. package/react-native-marketap-sdk.podspec +1 -1
package/ios/MarketapSdk.m CHANGED
@@ -8,51 +8,41 @@
8
8
  return YES;
9
9
  }
10
10
 
11
- RCT_EXTERN_METHOD(initialize:(nonnull NSString *)projectId
11
+ RCT_EXTERN_METHOD(initialize:(nullable NSDictionary *)payload
12
12
  withResolver:(RCTPromiseResolveBlock)resolve
13
13
  withRejecter:(RCTPromiseRejectBlock)reject)
14
14
 
15
- RCT_EXTERN_METHOD(setLogLevel:(nonnull NSNumber *)logLevel)
15
+ RCT_EXTERN_METHOD(setLogLevel:(nullable NSDictionary *)payload)
16
16
 
17
- RCT_EXTERN_METHOD(signup:(nonnull NSString *)userId
18
- userProperties:(nullable NSDictionary *)userProperties
19
- eventProperties:(nullable NSDictionary *)eventProperties
20
- persistUser:(nullable NSNumber *)persistUser
17
+ RCT_EXTERN_METHOD(signup:(nullable NSDictionary *)payload
21
18
  withResolver:(RCTPromiseResolveBlock)resolve
22
19
  withRejecter:(RCTPromiseRejectBlock)reject)
23
20
 
24
- RCT_EXTERN_METHOD(login:(nonnull NSString *)userId
25
- userProperties:(nullable NSDictionary *)userProperties
26
- eventProperties:(nullable NSDictionary *)eventProperties
21
+ RCT_EXTERN_METHOD(login:(nullable NSDictionary *)payload
27
22
  withResolver:(RCTPromiseResolveBlock)resolve
28
23
  withRejecter:(RCTPromiseRejectBlock)reject)
29
24
 
30
- RCT_EXTERN_METHOD(logout:(nullable NSDictionary *)eventProperties
25
+ RCT_EXTERN_METHOD(logout:(nullable NSDictionary *)payload
31
26
  withResolver:(RCTPromiseResolveBlock)resolve
32
27
  withRejecter:(RCTPromiseRejectBlock)reject)
33
28
 
34
- RCT_EXTERN_METHOD(track:(nonnull NSString *)eventName
35
- eventProperties:(nullable NSDictionary *)eventProperties
29
+ RCT_EXTERN_METHOD(track:(nullable NSDictionary *)payload
36
30
  withResolver:(RCTPromiseResolveBlock)resolve
37
31
  withRejecter:(RCTPromiseRejectBlock)reject)
38
32
 
39
- RCT_EXTERN_METHOD(trackPurchase:(nonnull NSNumber *)revenue
40
- eventProperties:(nullable NSDictionary *)eventProperties
33
+ RCT_EXTERN_METHOD(trackPurchase:(nullable NSDictionary *)payload
41
34
  withResolver:(RCTPromiseResolveBlock)resolve
42
35
  withRejecter:(RCTPromiseRejectBlock)reject)
43
36
 
44
- RCT_EXTERN_METHOD(trackRevenue:(nonnull NSString *)eventName
45
- revenue:(nonnull NSNumber *)revenue
46
- eventProperties:(nullable NSDictionary *)eventProperties
37
+ RCT_EXTERN_METHOD(trackRevenue:(nullable NSDictionary *)payload
47
38
  withResolver:(RCTPromiseResolveBlock)resolve
48
39
  withRejecter:(RCTPromiseRejectBlock)reject)
49
40
 
50
- RCT_EXTERN_METHOD(trackPageView:(nullable NSDictionary *)eventProperties
41
+ RCT_EXTERN_METHOD(trackPageView:(nullable NSDictionary *)payload
51
42
  withResolver:(RCTPromiseResolveBlock)resolve
52
43
  withRejecter:(RCTPromiseRejectBlock)reject)
53
44
 
54
- RCT_EXTERN_METHOD(identify:(nonnull NSString *)userId
55
- userProperties:(nullable NSDictionary *)userProperties
45
+ RCT_EXTERN_METHOD(identify:(nullable NSDictionary *)payload
56
46
  withResolver:(RCTPromiseResolveBlock)resolve
57
47
  withRejecter:(RCTPromiseRejectBlock)reject)
58
48
 
@@ -65,11 +55,28 @@ RCT_EXTERN_METHOD(setClickHandler:(RCTPromiseResolveBlock)resolve
65
55
  RCT_EXTERN_METHOD(requestAuthorizationForPushNotifications:(RCTPromiseResolveBlock)resolve
66
56
  withRejecter:(RCTPromiseRejectBlock)reject)
67
57
 
68
- RCT_EXTERN_METHOD(setPushToken:(nonnull NSString *)token
58
+ RCT_EXTERN_METHOD(trackFromWebBridge:(nullable NSDictionary *)payload
69
59
  withResolver:(RCTPromiseResolveBlock)resolve
70
60
  withRejecter:(RCTPromiseRejectBlock)reject)
71
61
 
72
- RCT_EXTERN_METHOD(getInitialNotification:(RCTPromiseResolveBlock)resolve
62
+ RCT_EXTERN_METHOD(setUserProperties:(nullable NSDictionary *)payload
63
+ withResolver:(RCTPromiseResolveBlock)resolve
64
+ withRejecter:(RCTPromiseRejectBlock)reject)
65
+
66
+ RCT_EXTERN_METHOD(trackInAppImpression:(nullable NSDictionary *)payload
67
+ withResolver:(RCTPromiseResolveBlock)resolve
68
+ withRejecter:(RCTPromiseRejectBlock)reject)
69
+
70
+ RCT_EXTERN_METHOD(trackInAppClick:(nullable NSDictionary *)payload
71
+ withResolver:(RCTPromiseResolveBlock)resolve
72
+ withRejecter:(RCTPromiseRejectBlock)reject)
73
+
74
+ RCT_EXTERN_METHOD(setDeviceOptIn:(nullable NSDictionary *)payload
75
+ withResolver:(RCTPromiseResolveBlock)resolve
76
+ withRejecter:(RCTPromiseRejectBlock)reject)
77
+
78
+ RCT_EXTERN_METHOD(hideCampaign:(nullable NSDictionary *)payload
79
+ withResolver:(RCTPromiseResolveBlock)resolve
73
80
  withRejecter:(RCTPromiseRejectBlock)reject)
74
81
 
75
- @end
82
+ @end
@@ -27,6 +27,9 @@ class MarketapSdk: RCTEventEmitter {
27
27
  private var initializedProjectId: String?
28
28
 
29
29
  private static var pendingClickEvent: [String: Any]? = nil
30
+ private static var pendingInAppMessageEvent: [String: Any]? = nil
31
+ private static var currentEmitter: MarketapSdk? = nil
32
+ private static var isExternalInAppCallbackRegistered = false
30
33
 
31
34
  override init() {
32
35
  super.init()
@@ -38,19 +41,31 @@ class MarketapSdk: RCTEventEmitter {
38
41
  }
39
42
 
40
43
  override func supportedEvents() -> [String]! {
41
- return ["MarketapClickEvent"]
44
+ return ["MarketapClickEvent", "MarketapInAppMessageEvent"]
42
45
  }
43
46
 
44
47
  override func startObserving() {
45
48
  hasListeners = true
49
+ Self.currentEmitter = self
50
+ print("[MarketapSdk] startObserving (hasListeners=true)")
51
+
52
+ if let pendingEvent = Self.pendingInAppMessageEvent {
53
+ self.sendEvent(withName: "MarketapInAppMessageEvent", body: pendingEvent)
54
+ Self.pendingInAppMessageEvent = nil
55
+ }
46
56
  }
47
57
 
48
58
  override func stopObserving() {
49
59
  hasListeners = false
60
+ if Self.currentEmitter === self {
61
+ Self.currentEmitter = nil
62
+ }
63
+ print("[MarketapSdk] stopObserving (hasListeners=false)")
50
64
  }
51
65
 
52
66
  @objc
53
- func initialize(_ projectId: String, withResolver resolve: @escaping RCTPromiseResolveBlock, withRejecter reject: @escaping RCTPromiseRejectBlock) {
67
+ func initialize(_ payload: NSDictionary?, withResolver resolve: @escaping RCTPromiseResolveBlock, withRejecter reject: @escaping RCTPromiseRejectBlock) {
68
+ let projectId = payload?["projectId"] as? String ?? ""
54
69
  if isInitialized {
55
70
  if initializedProjectId != projectId {
56
71
  print("[MarketapSDK] Already initialized with projectId '\(initializedProjectId ?? "unknown")'. Ignoring re-initialization with '\(projectId)'.")
@@ -62,11 +77,13 @@ class MarketapSdk: RCTEventEmitter {
62
77
  Marketap.initialize(projectId: projectId)
63
78
  isInitialized = true
64
79
  initializedProjectId = projectId
80
+ Self.registerExternalInAppCallbackIfNeeded()
65
81
  resolve(nil)
66
82
  }
67
83
 
68
84
  @objc
69
- func setLogLevel(_ logLevel: NSNumber) {
85
+ func setLogLevel(_ payload: NSDictionary?) {
86
+ let logLevel = payload?["logLevel"] as? NSNumber ?? NSNumber(value: 0)
70
87
  switch logLevel.intValue {
71
88
  case 0:
72
89
  Marketap.setLogLevel(.none)
@@ -86,49 +103,67 @@ class MarketapSdk: RCTEventEmitter {
86
103
  }
87
104
 
88
105
  @objc
89
- func signup(_ userId: String, userProperties: [String: Any]?, eventProperties: [String: Any]?, persistUser: NSNumber?, withResolver resolve: @escaping RCTPromiseResolveBlock, withRejecter reject: @escaping RCTPromiseRejectBlock) {
90
- Marketap.signup(userId: userId, userProperties: userProperties, eventProperties: eventProperties, persistUser: persistUser?.boolValue ?? true)
106
+ func signup(_ payload: NSDictionary?, withResolver resolve: @escaping RCTPromiseResolveBlock, withRejecter reject: @escaping RCTPromiseRejectBlock) {
107
+ let userId = payload?["userId"] as? String ?? ""
108
+ let userProperties = payload?["userProperties"] as? [String: Any]
109
+ let eventProperties = payload?["eventProperties"] as? [String: Any]
110
+ let persistUser = (payload?["persistUser"] as? NSNumber)?.boolValue ?? true
111
+ Marketap.signup(userId: userId, userProperties: userProperties, eventProperties: eventProperties, persistUser: persistUser)
91
112
  resolve(nil)
92
113
  }
93
114
 
94
115
  @objc
95
- func login(_ userId: String, userProperties: [String: Any]?, eventProperties: [String: Any]?, withResolver resolve: @escaping RCTPromiseResolveBlock, withRejecter reject: @escaping RCTPromiseRejectBlock) {
116
+ func login(_ payload: NSDictionary?, withResolver resolve: @escaping RCTPromiseResolveBlock, withRejecter reject: @escaping RCTPromiseRejectBlock) {
117
+ let userId = payload?["userId"] as? String ?? ""
118
+ let userProperties = payload?["userProperties"] as? [String: Any]
119
+ let eventProperties = payload?["eventProperties"] as? [String: Any]
96
120
  Marketap.login(userId: userId, userProperties: userProperties, eventProperties: eventProperties)
97
121
  resolve(nil)
98
122
  }
99
123
 
100
124
  @objc
101
- func logout(_ eventProperties: [String: Any]?, withResolver resolve: @escaping RCTPromiseResolveBlock, withRejecter reject: @escaping RCTPromiseRejectBlock) {
125
+ func logout(_ payload: NSDictionary?, withResolver resolve: @escaping RCTPromiseResolveBlock, withRejecter reject: @escaping RCTPromiseRejectBlock) {
126
+ let eventProperties = payload?["eventProperties"] as? [String: Any]
102
127
  Marketap.logout(eventProperties: eventProperties)
103
128
  resolve(nil)
104
129
  }
105
130
 
106
131
  @objc
107
- func track(_ eventName: String, eventProperties: [String: Any]?, withResolver resolve: @escaping RCTPromiseResolveBlock, withRejecter reject: @escaping RCTPromiseRejectBlock) {
132
+ func track(_ payload: NSDictionary?, withResolver resolve: @escaping RCTPromiseResolveBlock, withRejecter reject: @escaping RCTPromiseRejectBlock) {
133
+ let eventName = payload?["eventName"] as? String ?? ""
134
+ let eventProperties = payload?["eventProperties"] as? [String: Any]
108
135
  Marketap.track(eventName: eventName, eventProperties: eventProperties)
109
136
  resolve(nil)
110
137
  }
111
138
 
112
139
  @objc
113
- func trackPurchase(_ revenue: NSNumber, eventProperties: [String: Any]?, withResolver resolve: @escaping RCTPromiseResolveBlock, withRejecter reject: @escaping RCTPromiseRejectBlock) {
114
- Marketap.trackPurchase(revenue: revenue.doubleValue, eventProperties: eventProperties)
140
+ func trackPurchase(_ payload: NSDictionary?, withResolver resolve: @escaping RCTPromiseResolveBlock, withRejecter reject: @escaping RCTPromiseRejectBlock) {
141
+ let revenue = (payload?["revenue"] as? NSNumber)?.doubleValue ?? 0
142
+ let eventProperties = payload?["eventProperties"] as? [String: Any]
143
+ Marketap.trackPurchase(revenue: revenue, eventProperties: eventProperties)
115
144
  resolve(nil)
116
145
  }
117
146
 
118
147
  @objc
119
- func trackRevenue(_ eventName: String, revenue: NSNumber, eventProperties: [String: Any]?, withResolver resolve: @escaping RCTPromiseResolveBlock, withRejecter reject: @escaping RCTPromiseRejectBlock) {
120
- Marketap.trackRevenue(eventName: eventName, revenue: revenue.doubleValue, eventProperties: eventProperties)
148
+ func trackRevenue(_ payload: NSDictionary?, withResolver resolve: @escaping RCTPromiseResolveBlock, withRejecter reject: @escaping RCTPromiseRejectBlock) {
149
+ let eventName = payload?["eventName"] as? String ?? ""
150
+ let revenue = (payload?["revenue"] as? NSNumber)?.doubleValue ?? 0
151
+ let eventProperties = payload?["eventProperties"] as? [String: Any]
152
+ Marketap.trackRevenue(eventName: eventName, revenue: revenue, eventProperties: eventProperties)
121
153
  resolve(nil)
122
154
  }
123
155
 
124
156
  @objc
125
- func trackPageView(_ eventProperties: [String: Any]?, withResolver resolve: @escaping RCTPromiseResolveBlock, withRejecter reject: @escaping RCTPromiseRejectBlock) {
157
+ func trackPageView(_ payload: NSDictionary?, withResolver resolve: @escaping RCTPromiseResolveBlock, withRejecter reject: @escaping RCTPromiseRejectBlock) {
158
+ let eventProperties = payload?["eventProperties"] as? [String: Any]
126
159
  Marketap.trackPageView(eventProperties: eventProperties)
127
160
  resolve(nil)
128
161
  }
129
162
 
130
163
  @objc
131
- func identify(_ userId: String, userProperties: [String: Any]?, withResolver resolve: @escaping RCTPromiseResolveBlock, withRejecter reject: @escaping RCTPromiseRejectBlock) {
164
+ func identify(_ payload: NSDictionary?, withResolver resolve: @escaping RCTPromiseResolveBlock, withRejecter reject: @escaping RCTPromiseRejectBlock) {
165
+ let userId = payload?["userId"] as? String ?? ""
166
+ let userProperties = payload?["userProperties"] as? [String: Any]
132
167
  Marketap.identify(userId: userId, userProperties: userProperties)
133
168
  resolve(nil)
134
169
  }
@@ -141,7 +176,9 @@ class MarketapSdk: RCTEventEmitter {
141
176
 
142
177
  @objc
143
178
  func setClickHandler(_ resolve: @escaping RCTPromiseResolveBlock, withRejecter reject: @escaping RCTPromiseRejectBlock) {
179
+ print("[MarketapSdk] setClickHandler called")
144
180
  Marketap.setClickHandler { [weak self] event in
181
+ print("[MarketapSdk] click event received")
145
182
  let campaignType: String = {
146
183
  switch event.campaignType {
147
184
  case .push: return "push"
@@ -178,21 +215,125 @@ class MarketapSdk: RCTEventEmitter {
178
215
  resolve(nil)
179
216
  }
180
217
 
218
+ // MARK: - WebBridge In-App Methods
219
+
181
220
  @objc
182
- func setPushToken(_ token: String, withResolver resolve: @escaping RCTPromiseResolveBlock, withRejecter reject: @escaping RCTPromiseRejectBlock) {
183
- if let tokenData = Data(hexString: token) {
184
- Marketap.setPushToken(token: tokenData)
221
+ func trackFromWebBridge(_ payload: NSDictionary?, withResolver resolve: @escaping RCTPromiseResolveBlock, withRejecter reject: @escaping RCTPromiseRejectBlock) {
222
+ let eventName = payload?["eventName"] as? String ?? ""
223
+ let eventProperties = payload?["eventProperties"] as? [String: Any]
224
+ let handleInApp = (payload?["handleInAppInReactNative"] as? NSNumber)?.boolValue ?? false
225
+
226
+ if handleInApp {
227
+ MarketapWebBridge.setExternalWebBridgeActive(true)
228
+ } else {
229
+ MarketapWebBridge.setExternalWebBridgeActive(false)
185
230
  }
231
+
232
+ MarketapPlugin.trackEvent(eventName: eventName, eventProperties: eventProperties)
186
233
  resolve(nil)
187
234
  }
188
235
 
189
236
  @objc
190
- func getInitialNotification(_ resolve: @escaping RCTPromiseResolveBlock, withRejecter reject: @escaping RCTPromiseRejectBlock) {
191
- if let pendingEvent = Self.pendingClickEvent {
192
- Self.pendingClickEvent = nil
193
- resolve(pendingEvent)
237
+ func setUserProperties(_ payload: NSDictionary?, withResolver resolve: @escaping RCTPromiseResolveBlock, withRejecter reject: @escaping RCTPromiseRejectBlock) {
238
+ let userProperties = payload?["userProperties"] as? [String: Any]
239
+ guard let userProperties = userProperties else {
240
+ reject("ARG_ERROR", "Missing userProperties", nil)
241
+ return
242
+ }
243
+
244
+ MarketapPlugin.setUserProperties(userProperties: userProperties)
245
+ resolve(nil)
246
+ }
247
+
248
+ @objc
249
+ func trackInAppImpression(_ payload: NSDictionary?, withResolver resolve: @escaping RCTPromiseResolveBlock, withRejecter reject: @escaping RCTPromiseRejectBlock) {
250
+ let campaignId = payload?["campaignId"] as? String
251
+ let messageId = payload?["messageId"] as? String
252
+ let layoutSubType = payload?["layoutSubType"] as? String
253
+ guard let campaignId = campaignId, let messageId = messageId else {
254
+ print("[MarketapSdk] trackInAppImpression: missing required params (campaignId=\(String(describing: campaignId)), messageId=\(String(describing: messageId)))")
255
+ resolve(nil)
256
+ return
257
+ }
258
+
259
+ MarketapPlugin.trackInAppImpression(
260
+ campaignId: campaignId,
261
+ messageId: messageId,
262
+ layoutSubType: layoutSubType
263
+ )
264
+ resolve(nil)
265
+ }
266
+
267
+ @objc
268
+ func trackInAppClick(_ payload: NSDictionary?, withResolver resolve: @escaping RCTPromiseResolveBlock, withRejecter reject: @escaping RCTPromiseRejectBlock) {
269
+ let campaignId = payload?["campaignId"] as? String
270
+ let messageId = payload?["messageId"] as? String
271
+ let locationId = payload?["locationId"] as? String
272
+ let url = payload?["url"] as? String
273
+ let layoutSubType = payload?["layoutSubType"] as? String
274
+ guard let campaignId = campaignId, let messageId = messageId, let locationId = locationId else {
275
+ print("[MarketapSdk] trackInAppClick: missing required params (campaignId=\(String(describing: campaignId)), messageId=\(String(describing: messageId)), locationId=\(String(describing: locationId)))")
276
+ resolve(nil)
277
+ return
278
+ }
279
+
280
+ MarketapPlugin.trackInAppClick(
281
+ campaignId: campaignId,
282
+ messageId: messageId,
283
+ locationId: locationId,
284
+ url: url,
285
+ layoutSubType: layoutSubType
286
+ )
287
+ resolve(nil)
288
+ }
289
+
290
+ @objc
291
+ func setDeviceOptIn(_ payload: NSDictionary?, withResolver resolve: @escaping RCTPromiseResolveBlock, withRejecter reject: @escaping RCTPromiseRejectBlock) {
292
+ let optIn: Bool?
293
+ if let value = payload?["optIn"] as? NSNumber {
294
+ optIn = value.boolValue
194
295
  } else {
195
- resolve(NSNull())
296
+ optIn = nil
297
+ }
298
+ Marketap.setDeviceOptIn(optIn: optIn)
299
+ resolve(nil)
300
+ }
301
+
302
+ @objc
303
+ func hideCampaign(_ payload: NSDictionary?, withResolver resolve: @escaping RCTPromiseResolveBlock, withRejecter reject: @escaping RCTPromiseRejectBlock) {
304
+ let campaignId = payload?["campaignId"] as? String
305
+ let hideType = payload?["hideType"] as? String
306
+ guard let campaignId = campaignId else {
307
+ print("[MarketapSdk] hideCampaign: missing campaignId")
308
+ resolve(nil)
309
+ return
310
+ }
311
+
312
+ MarketapPlugin.hideInAppMessage(campaignId: campaignId, hideType: hideType)
313
+ resolve(nil)
314
+ }
315
+
316
+ // MARK: - Private
317
+
318
+ private static func registerExternalInAppCallbackIfNeeded() {
319
+ if isExternalInAppCallbackRegistered {
320
+ return
321
+ }
322
+ isExternalInAppCallbackRegistered = true
323
+
324
+ MarketapWebBridge.setExternalInAppMessageCallback { campaign, messageId, hasCustomClickHandler in
325
+ let payload: [String: Any] = [
326
+ "campaign": campaign,
327
+ "messageId": messageId,
328
+ "hasCustomClickHandler": hasCustomClickHandler
329
+ ]
330
+
331
+ if let emitter = currentEmitter, emitter.hasListeners {
332
+ emitter.sendEvent(withName: "MarketapInAppMessageEvent", body: payload)
333
+ pendingInAppMessageEvent = nil
334
+ } else {
335
+ pendingInAppMessageEvent = payload
336
+ }
196
337
  }
197
338
  }
198
339
  }
@@ -6,18 +6,103 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.default = void 0;
7
7
  var _reactNative = require("react-native");
8
8
  var _version = require("./version");
9
- class MarketapWebBridgeClass {
10
- injectJavaScriptFunction = null;
11
- setInjectJavaScriptFunction(fn) {
12
- this.injectJavaScriptFunction = fn;
9
+ var _marketapPlugin = _interopRequireDefault(require("./internal/marketapPlugin"));
10
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
11
+ class InAppCampaign {
12
+ constructor(params) {
13
+ this.id = params.id;
14
+ this.layout = params.layout;
15
+ this.html = params.html;
16
+ this.triggerEventCondition = params.triggerEventCondition;
17
+ this.priority = params.priority;
18
+ this.updatedAt = params.updatedAt;
13
19
  }
14
- getInjectJavaScriptFunction() {
15
- if (!this.injectJavaScriptFunction) {
16
- throw new Error('[MarketapWebBridge] injectJavaScriptFunction is not set. ' + 'Call MarketapWebBridge.setInjectJavaScriptFunction() before using the bridge.');
20
+ static fromJson(json) {
21
+ return new InAppCampaign({
22
+ id: String(json.id ?? ''),
23
+ layout: InAppCampaign.convertToStringDynamicMap(json.layout),
24
+ html: json.html,
25
+ triggerEventCondition: json.triggerEventCondition ? InAppCampaign.convertToStringDynamicMap(json.triggerEventCondition) : undefined,
26
+ priority: json.priority != null ? String(json.priority) : undefined,
27
+ updatedAt: json.updatedAt
28
+ });
29
+ }
30
+ toJson() {
31
+ return {
32
+ id: this.id,
33
+ layout: this.layout,
34
+ html: this.html,
35
+ triggerEventCondition: this.triggerEventCondition,
36
+ priority: this.priority,
37
+ updatedAt: this.updatedAt
38
+ };
39
+ }
40
+ static convertToStringDynamicMap(value) {
41
+ if (value && typeof value === 'object' && !Array.isArray(value)) {
42
+ const result = {};
43
+ Object.keys(value).forEach(key => {
44
+ const v = value[key];
45
+ if (Array.isArray(v)) {
46
+ result[String(key)] = InAppCampaign.convertList(v);
47
+ } else if (v && typeof v === 'object') {
48
+ result[String(key)] = InAppCampaign.convertToStringDynamicMap(v);
49
+ } else {
50
+ result[String(key)] = v;
51
+ }
52
+ });
53
+ return result;
17
54
  }
18
- return this.injectJavaScriptFunction;
55
+ return {};
56
+ }
57
+ static convertList(list) {
58
+ return list.map(item => {
59
+ if (Array.isArray(item)) {
60
+ return InAppCampaign.convertList(item);
61
+ }
62
+ if (item && typeof item === 'object') {
63
+ return InAppCampaign.convertToStringDynamicMap(item);
64
+ }
65
+ return item;
66
+ });
67
+ }
68
+ }
69
+
70
+ /**
71
+ * WebView와 네이티브 SDK를 연결하는 브릿지.
72
+ *
73
+ * 사용 예시:
74
+ * const bridge = new MarketapWebBridge(
75
+ * (script) => webViewRef.current?.injectJavaScript(script),
76
+ * true
77
+ * );
78
+ *
79
+ * // WebView 메시지 수신 시
80
+ * bridge.handleMessage(event.nativeEvent.data);
81
+ *
82
+ * // unmount 시
83
+ * bridge.dispose();
84
+ */
85
+ class MarketapWebBridge {
86
+ static activeInstance = null;
87
+ currentCampaign = null;
88
+ isDisposed = false;
89
+ handleInAppInWebView = true;
90
+ constructor(injectJavaScriptFunction, handleInAppInWebView = true) {
91
+ this.evaluateJavaScriptFunction = injectJavaScriptFunction;
92
+ this.handleInAppInWebView = handleInAppInWebView;
93
+ }
94
+ dispose() {
95
+ if (MarketapWebBridge.activeInstance === this) {
96
+ MarketapWebBridge.activeInstance = null;
97
+ }
98
+ this.currentCampaign = null;
99
+ this.isDisposed = true;
19
100
  }
20
101
  handleMessage(message) {
102
+ if (this.isDisposed) {
103
+ console.warn('[MarketapWebBridge] ignoring message - bridge is disposed');
104
+ return;
105
+ }
21
106
  let data;
22
107
  try {
23
108
  data = JSON.parse(message);
@@ -30,10 +115,10 @@ class MarketapWebBridgeClass {
30
115
  }
31
116
  const params = data.params || {};
32
117
  const Marketap = require('./index').default;
33
- console.log(`[MarketapWebBridgeClass] ${type}: ${JSON.stringify(params)}`);
118
+ console.log(`[MarketapWebBridge] ${type}: ${JSON.stringify(params)}`);
34
119
  switch (type) {
35
120
  case 'track':
36
- this.handleTrack(Marketap, params);
121
+ this.handleTrack(params);
37
122
  break;
38
123
  case 'identify':
39
124
  this.handleIdentify(Marketap, params);
@@ -44,17 +129,63 @@ class MarketapWebBridgeClass {
44
129
  case 'marketapBridgeCheck':
45
130
  this.handleBridgeCheck();
46
131
  break;
132
+ case 'inAppMessageImpression':
133
+ this.handleInAppImpression(params);
134
+ break;
135
+ case 'inAppMessageClick':
136
+ this.handleInAppClick(params);
137
+ break;
138
+ case 'inAppMessageHide':
139
+ this.handleInAppHide(params);
140
+ break;
141
+ case 'inAppMessageTrack':
142
+ this.handleInAppTrack(Marketap, params);
143
+ break;
144
+ case 'inAppMessageSetUserProperties':
145
+ this.handleInAppSetUserProperties(params);
146
+ break;
47
147
  default:
48
148
  console.warn(`[MarketapWebBridge] Unknown event type: '${String(type)}'`);
49
149
  }
50
150
  }
51
- handleTrack(Marketap, params) {
151
+ showInAppMessage(campaignJson, messageId, hasCustomClickHandler) {
152
+ if (this.isDisposed) {
153
+ console.warn('[MarketapWebBridge] ignoring message - bridge is disposed');
154
+ return;
155
+ }
156
+ try {
157
+ const campaign = InAppCampaign.fromJson(campaignJson);
158
+ this.currentCampaign = campaign;
159
+ this.sendCampaignToWeb(campaign, messageId, hasCustomClickHandler);
160
+ } catch (error) {
161
+ console.error('[MarketapWebBridge] failed to show in-app message', error);
162
+ }
163
+ }
164
+ sendCampaignToWeb(campaign, messageId, hasCustomClickHandler) {
165
+ const campaignJson = JSON.stringify(campaign.toJson());
166
+ const script = `
167
+ window.postMessage({
168
+ type: 'marketapShowInAppMessage',
169
+ campaign: ${campaignJson},
170
+ messageId: '${messageId}',
171
+ hasCustomClickHandler: ${hasCustomClickHandler}
172
+ }, '*');
173
+ `;
174
+ this.evaluateJavaScriptFunction(script);
175
+ }
176
+ handleTrack(params) {
52
177
  const eventName = params.eventName;
53
178
  const eventProperties = params.eventProperties;
54
179
  if (eventName) {
55
- Marketap.track(eventName, eventProperties);
180
+ if (this.handleInAppInWebView) {
181
+ MarketapWebBridge.setActiveInstance(this);
182
+ }
183
+ _marketapPlugin.default.trackFromWebBridge(eventName, this.handleInAppInWebView, eventProperties);
56
184
  }
57
185
  }
186
+ static setActiveInstance(instance) {
187
+ MarketapWebBridge.activeInstance = instance;
188
+ }
58
189
  handleIdentify(Marketap, params) {
59
190
  const userId = params.userId;
60
191
  const userProperties = params.userProperties;
@@ -63,7 +194,6 @@ class MarketapWebBridgeClass {
63
194
  }
64
195
  }
65
196
  handleBridgeCheck() {
66
- const injectJavaScriptFunction = this.getInjectJavaScriptFunction();
67
197
  const script = `
68
198
  window.postMessage({
69
199
  type: 'marketapBridgeAck',
@@ -74,9 +204,69 @@ class MarketapWebBridgeClass {
74
204
  }
75
205
  }, '*');
76
206
  `;
77
- injectJavaScriptFunction(script);
207
+ this.evaluateJavaScriptFunction(script);
208
+ }
209
+ handleInAppImpression(params) {
210
+ const campaignId = params.campaignId;
211
+ const messageId = params.messageId;
212
+ if (!campaignId || !messageId) {
213
+ console.warn('[MarketapWebBridge] inAppMessageImpression missing required params');
214
+ return;
215
+ }
216
+ if (this.currentCampaign && this.currentCampaign.id === campaignId) {
217
+ _marketapPlugin.default.trackInAppImpression(campaignId, messageId, this.currentCampaign.layout?.layoutSubType);
218
+ }
219
+ }
220
+ handleInAppClick(params) {
221
+ const campaignId = params.campaignId;
222
+ const messageId = params.messageId;
223
+ const locationId = params.locationId;
224
+ const url = params.url;
225
+ if (!campaignId || !messageId || !locationId) {
226
+ console.warn('[MarketapWebBridge] inAppMessageClick missing required params');
227
+ return;
228
+ }
229
+ if (this.currentCampaign && this.currentCampaign.id === campaignId) {
230
+ _marketapPlugin.default.trackInAppClick(campaignId, messageId, locationId, url, this.currentCampaign.layout?.layoutSubType);
231
+ }
232
+ }
233
+ handleInAppHide(params) {
234
+ const campaignId = params.campaignId;
235
+ const hideType = params.hideType;
236
+ if (!campaignId) {
237
+ console.warn('[MarketapWebBridge] inAppMessageHide missing campaignId');
238
+ return;
239
+ }
240
+ _marketapPlugin.default.hideCampaign(campaignId, hideType);
241
+ if (this.currentCampaign && this.currentCampaign.id === campaignId) {
242
+ this.currentCampaign = null;
243
+ }
244
+ }
245
+ handleInAppTrack(Marketap, params) {
246
+ const eventName = params.eventName;
247
+ const eventProperties = params.eventProperties;
248
+ if (!eventName) {
249
+ console.warn('[MarketapWebBridge] inAppMessageTrack missing eventName');
250
+ return;
251
+ }
252
+ Marketap.track(eventName, eventProperties);
253
+ }
254
+ handleInAppSetUserProperties(params) {
255
+ const userProperties = params.userProperties;
256
+ if (!userProperties) {
257
+ console.warn('[MarketapWebBridge] inAppMessageSetUserProperties missing userProperties');
258
+ return;
259
+ }
260
+ _marketapPlugin.default.setUserProperties(userProperties);
261
+ }
262
+ static sendToActiveWebBridge(campaign, messageId, hasCustomClickHandler) {
263
+ const activeInstance = MarketapWebBridge.activeInstance;
264
+ if (activeInstance !== null) {
265
+ activeInstance.showInAppMessage(campaign, messageId, hasCustomClickHandler);
266
+ } else {
267
+ console.warn('[MarketapWebBridge] no active web bridge instance available');
268
+ }
78
269
  }
79
270
  }
80
- const MarketapWebBridge = new MarketapWebBridgeClass();
81
271
  var _default = exports.default = MarketapWebBridge;
82
272
  //# sourceMappingURL=MarketapWebBridge.js.map