@digia-engage/core 1.0.0-beta.1

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 (56) hide show
  1. package/DigiaEngageReactNative.podspec +21 -0
  2. package/README.md +277 -0
  3. package/android/build.gradle +82 -0
  4. package/android/gradle/wrapper/gradle-wrapper.jar +0 -0
  5. package/android/gradlew +185 -0
  6. package/android/gradlew.bat +89 -0
  7. package/android/settings.gradle +33 -0
  8. package/android/src/main/AndroidManifest.xml +2 -0
  9. package/android/src/main/java/com/digia/engage/rn/DigiaModule.kt +234 -0
  10. package/android/src/main/java/com/digia/engage/rn/DigiaPackage.kt +69 -0
  11. package/android/src/main/java/com/digia/engage/rn/DigiaSlotViewManager.kt +64 -0
  12. package/android/src/main/java/com/digia/engage/rn/DigiaViewManager.kt +63 -0
  13. package/ios/DigiaEngageModule.m +71 -0
  14. package/lib/commonjs/Digia.js +106 -0
  15. package/lib/commonjs/Digia.js.map +1 -0
  16. package/lib/commonjs/DigiaHostView.js +73 -0
  17. package/lib/commonjs/DigiaHostView.js.map +1 -0
  18. package/lib/commonjs/DigiaSlotView.js +73 -0
  19. package/lib/commonjs/DigiaSlotView.js.map +1 -0
  20. package/lib/commonjs/NativeDigiaModule.js +56 -0
  21. package/lib/commonjs/NativeDigiaModule.js.map +1 -0
  22. package/lib/commonjs/index.js +27 -0
  23. package/lib/commonjs/index.js.map +1 -0
  24. package/lib/commonjs/types.js +2 -0
  25. package/lib/commonjs/types.js.map +1 -0
  26. package/lib/module/Digia.js +100 -0
  27. package/lib/module/Digia.js.map +1 -0
  28. package/lib/module/DigiaHostView.js +67 -0
  29. package/lib/module/DigiaHostView.js.map +1 -0
  30. package/lib/module/DigiaSlotView.js +66 -0
  31. package/lib/module/DigiaSlotView.js.map +1 -0
  32. package/lib/module/NativeDigiaModule.js +51 -0
  33. package/lib/module/NativeDigiaModule.js.map +1 -0
  34. package/lib/module/index.js +15 -0
  35. package/lib/module/index.js.map +1 -0
  36. package/lib/module/types.js +2 -0
  37. package/lib/module/types.js.map +1 -0
  38. package/lib/typescript/Digia.d.ts +62 -0
  39. package/lib/typescript/Digia.d.ts.map +1 -0
  40. package/lib/typescript/DigiaHostView.d.ts +40 -0
  41. package/lib/typescript/DigiaHostView.d.ts.map +1 -0
  42. package/lib/typescript/DigiaSlotView.d.ts +52 -0
  43. package/lib/typescript/DigiaSlotView.d.ts.map +1 -0
  44. package/lib/typescript/NativeDigiaModule.d.ts +45 -0
  45. package/lib/typescript/NativeDigiaModule.d.ts.map +1 -0
  46. package/lib/typescript/index.d.ts +15 -0
  47. package/lib/typescript/index.d.ts.map +1 -0
  48. package/lib/typescript/types.d.ts +58 -0
  49. package/lib/typescript/types.d.ts.map +1 -0
  50. package/package.json +89 -0
  51. package/src/Digia.ts +104 -0
  52. package/src/DigiaHostView.tsx +83 -0
  53. package/src/DigiaSlotView.tsx +79 -0
  54. package/src/NativeDigiaModule.ts +86 -0
  55. package/src/index.ts +15 -0
  56. package/src/types.ts +61 -0
@@ -0,0 +1,234 @@
1
+ /**
2
+ * DigiaModule
3
+ *
4
+ * React Native NativeModule that bridges the Digia Engage Android SDK.
5
+ *
6
+ * Exposed methods (callable from JS via NativeModules.DigiaEngageModule):
7
+ *
8
+ * initialize(apiKey, environment, logLevel): Promise<void> register(): void setCurrentScreen(name):
9
+ * void triggerCampaign(id, content, cepContext): void invalidateCampaign(campaignId): void
10
+ *
11
+ * Architecture ──────────── The RN bridge mirrors the native Digia.initialize / Digia.register /
12
+ * Digia.setCurrentScreen flow exactly. An internal [RNEventBridgePlugin] is the single native
13
+ * DigiaCEPPlugin registered via Digia.register().
14
+ *
15
+ * When the SDK calls plugin.setup(delegate), the bridge stores that delegate reference. JS plugins
16
+ * that need to push campaigns into the Compose overlay call triggerCampaign / invalidateCampaign
17
+ * which forward to delegate.onCampaignTriggered / delegate.onCampaignInvalidated.
18
+ *
19
+ * Overlay lifecycle events (impressed / clicked / dismissed) are forwarded from the native
20
+ * plugin.notifyEvent() to JS via DeviceEventEmitter so that pure-JS CEP plugins (e.g.
21
+ * DigiaMoEngagePlugin) can report analytics.
22
+ */
23
+ package com.digia.engage.rn
24
+
25
+ import android.widget.FrameLayout
26
+ import androidx.lifecycle.LifecycleOwner
27
+ import androidx.lifecycle.ViewModelStoreOwner
28
+ import androidx.lifecycle.setViewTreeLifecycleOwner
29
+ import androidx.lifecycle.setViewTreeViewModelStoreOwner
30
+ import androidx.savedstate.SavedStateRegistryOwner
31
+ import androidx.savedstate.setViewTreeSavedStateRegistryOwner
32
+ import com.digia.engage.DiagnosticReport
33
+ import com.digia.engage.Digia
34
+ import com.digia.engage.DigiaCEPDelegate
35
+ import com.digia.engage.DigiaCEPPlugin
36
+ import com.digia.engage.DigiaConfig
37
+ import com.digia.engage.DigiaEnvironment
38
+ import com.digia.engage.DigiaExperienceEvent
39
+ import com.digia.engage.DigiaHostView
40
+ import com.digia.engage.DigiaLogLevel
41
+ import com.digia.engage.InAppPayload
42
+ import com.facebook.react.bridge.Arguments
43
+ import com.facebook.react.bridge.Promise
44
+ import com.facebook.react.bridge.ReactApplicationContext
45
+ import com.facebook.react.bridge.ReactContextBaseJavaModule
46
+ import com.facebook.react.bridge.ReactMethod
47
+ import com.facebook.react.bridge.ReadableMap
48
+ import com.facebook.react.bridge.UiThreadUtil
49
+ import com.facebook.react.modules.core.DeviceEventManagerModule
50
+
51
+ internal class DigiaModule(
52
+ private val reactContext: ReactApplicationContext,
53
+ ) : ReactContextBaseJavaModule(reactContext) {
54
+
55
+ private val rnPlugin = RNEventBridgePlugin(reactContext)
56
+
57
+ override fun getName(): String = MODULE_NAME
58
+
59
+ // ─── initialize ───────────────────────────────────────────────────────────
60
+
61
+ @ReactMethod
62
+ fun initialize(apiKey: String, environment: String, logLevel: String, promise: Promise) {
63
+ try {
64
+ val config =
65
+ DigiaConfig(
66
+ apiKey = apiKey,
67
+ environment =
68
+ when (environment.lowercase()) {
69
+ "sandbox" -> DigiaEnvironment.SANDBOX
70
+ else -> DigiaEnvironment.PRODUCTION
71
+ },
72
+ logLevel =
73
+ when (logLevel.lowercase()) {
74
+ "verbose" -> DigiaLogLevel.VERBOSE
75
+ "none" -> DigiaLogLevel.NONE
76
+ else -> DigiaLogLevel.ERROR
77
+ },
78
+ )
79
+ Digia.initialize(reactContext.applicationContext, config)
80
+
81
+ UiThreadUtil.runOnUiThread {
82
+ mountDigiaHost()
83
+ promise.resolve(null)
84
+ }
85
+ } catch (e: Exception) {
86
+ promise.reject("DIGIA_INIT_ERROR", e.message ?: "Initialisation failed", e)
87
+ }
88
+ }
89
+
90
+ // ─── register ─────────────────────────────────────────────────────────────
91
+
92
+ /**
93
+ * Registers [RNEventBridgePlugin] with the native Digia SDK.
94
+ *
95
+ * This is bridge infrastructure — not a user-facing CEP plugin. Called once by the JS
96
+ * `Digia.register()` wrapper on the first plugin registration so that
97
+ * [RNEventBridgePlugin.delegate] is populated before any triggerCampaign / invalidateCampaign
98
+ * calls arrive from JS.
99
+ */
100
+ @ReactMethod
101
+ fun registerBridge() {
102
+ Digia.register(rnPlugin)
103
+ }
104
+
105
+ // ─── setCurrentScreen ─────────────────────────────────────────────────────
106
+
107
+ @ReactMethod
108
+ fun setCurrentScreen(name: String) {
109
+ Digia.setCurrentScreen(name)
110
+ }
111
+
112
+ // ─── triggerCampaign ──────────────────────────────────────────────────────
113
+
114
+ /**
115
+ * Forwards a campaign payload to the native DigiaCEPDelegate.
116
+ *
117
+ * This is called by the JS DigiaDelegate.onCampaignTriggered() implementation when a JS CEP
118
+ * plugin (e.g. DigiaMoEngagePlugin) delivers a campaign. The delegate routes it into the
119
+ * Compose overlay for rendering.
120
+ */
121
+ @ReactMethod
122
+ fun triggerCampaign(id: String, content: ReadableMap, cepContext: ReadableMap) {
123
+ val delegate = rnPlugin.delegate ?: return
124
+ delegate.onCampaignTriggered(
125
+ InAppPayload(
126
+ id = id,
127
+ content = content.toHashMap().toMap(),
128
+ cepContext = cepContext.toHashMap().toMap(),
129
+ )
130
+ )
131
+ }
132
+
133
+ // ─── invalidateCampaign ───────────────────────────────────────────────────
134
+
135
+ /** Forwards a campaign invalidation to the native DigiaCEPDelegate. */
136
+ @ReactMethod
137
+ fun invalidateCampaign(campaignId: String) {
138
+ rnPlugin.delegate?.onCampaignInvalidated(campaignId)
139
+ }
140
+
141
+ // ─── Internal: mount the Compose overlay host ─────────────────────────────
142
+
143
+ private fun mountDigiaHost() {
144
+ val activity = reactContext.currentActivity ?: return
145
+
146
+ val contentRoot = activity.window.decorView.findViewWithTag<DigiaHostView>(DIGIA_HOST_TAG)
147
+ if (contentRoot != null) return
148
+
149
+ val composeView =
150
+ DigiaHostView(activity).apply {
151
+ tag = DIGIA_HOST_TAG
152
+ if (activity is LifecycleOwner) setViewTreeLifecycleOwner(activity)
153
+ if (activity is ViewModelStoreOwner) setViewTreeViewModelStoreOwner(activity)
154
+ if (activity is SavedStateRegistryOwner)
155
+ setViewTreeSavedStateRegistryOwner(activity)
156
+ }
157
+
158
+ activity.addContentView(
159
+ composeView,
160
+ FrameLayout.LayoutParams(
161
+ FrameLayout.LayoutParams.MATCH_PARENT,
162
+ FrameLayout.LayoutParams.MATCH_PARENT,
163
+ ),
164
+ )
165
+ }
166
+
167
+ companion object {
168
+ const val MODULE_NAME = "DigiaEngageModule"
169
+ private const val DIGIA_HOST_TAG = "digia_host_compose_view"
170
+ }
171
+ }
172
+
173
+ /**
174
+ * RNEventBridgePlugin
175
+ *
176
+ * The single native DigiaCEPPlugin used in React Native.
177
+ *
178
+ * When Digia.register(rnPlugin) is called, the SDK calls setup(delegate) which gives us the
179
+ * DigiaCEPDelegate reference. This delegate is used by triggerCampaign / invalidateCampaign bridge
180
+ * methods to push campaigns into the native rendering engine.
181
+ *
182
+ * Overlay lifecycle events (impressed / clicked / dismissed) received via notifyEvent() are emitted
183
+ * to JS as DeviceEventEmitter events so that JS CEP plugins can report analytics back to their
184
+ * platform.
185
+ */
186
+ internal class RNEventBridgePlugin(
187
+ private val reactContext: ReactApplicationContext,
188
+ ) : DigiaCEPPlugin {
189
+
190
+ override val identifier: String = "rn-event-bridge"
191
+
192
+ /** Delegate received from the SDK via setup(). Used by DigiaModule bridge methods. */
193
+ var delegate: DigiaCEPDelegate? = null
194
+ private set
195
+
196
+ private fun emit(event: String, params: com.facebook.react.bridge.WritableMap) {
197
+ if (reactContext.hasActiveReactInstance()) {
198
+ reactContext
199
+ .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
200
+ .emit(event, params)
201
+ }
202
+ }
203
+
204
+ override fun setup(delegate: DigiaCEPDelegate) {
205
+ this.delegate = delegate
206
+ }
207
+
208
+ override fun forwardScreen(name: String) {
209
+ /* forwarded by Digia.setCurrentScreen() on the native side */
210
+ }
211
+
212
+ override fun notifyEvent(event: DigiaExperienceEvent, payload: InAppPayload) {
213
+ val params =
214
+ Arguments.createMap().apply {
215
+ putString("campaignId", payload.id)
216
+ when (event) {
217
+ is DigiaExperienceEvent.Impressed -> putString("type", "impressed")
218
+ is DigiaExperienceEvent.Clicked -> {
219
+ putString("type", "clicked")
220
+ event.elementId?.let { putString("elementId", it) }
221
+ }
222
+ is DigiaExperienceEvent.Dismissed -> putString("type", "dismissed")
223
+ }
224
+ }
225
+ emit("digiaOverlayEvent", params)
226
+ }
227
+
228
+ override fun teardown() {
229
+ delegate = null
230
+ }
231
+
232
+ override fun healthCheck(): DiagnosticReport =
233
+ DiagnosticReport(isHealthy = true, metadata = mapOf("identifier" to identifier))
234
+ }
@@ -0,0 +1,69 @@
1
+ /**
2
+ * DigiaPackage
3
+ *
4
+ * Registers the Digia Engage native module and view managers with React Native.
5
+ *
6
+ * Extends TurboReactPackage so the package works transparently on both Old Architecture (bridge)
7
+ * and New Architecture (TurboModules / JSI).
8
+ *
9
+ * Why is this needed? ──────────────────── React Native's auto-linker reads react-native.config.js,
10
+ * which declares `packageInstance: 'new DigiaPackage()'`. At host-app compile time, RN injects this
11
+ * into the generated `PackageList`, making our native module and view managers available to JS
12
+ * without any manual MainApplication edits.
13
+ *
14
+ * JS: NativeModules.DigiaEngageModule ──► DigiaModule.kt JS:
15
+ * requireNativeComponent('DigiaHostView') ──► DigiaViewManager.kt JS:
16
+ * requireNativeComponent('DigiaSlotView') ──► DigiaSlotViewManager.kt
17
+ */
18
+ package com.digia.engage.rn
19
+
20
+ import com.facebook.react.BaseReactPackage
21
+ import com.facebook.react.bridge.NativeModule
22
+ import com.facebook.react.bridge.ReactApplicationContext
23
+ import com.facebook.react.module.model.ReactModuleInfo
24
+ import com.facebook.react.module.model.ReactModuleInfoProvider
25
+ import com.facebook.react.uimanager.ViewManager
26
+
27
+ class DigiaPackage : BaseReactPackage() {
28
+
29
+ // ─── Native Modules ───────────────────────────────────────────────────────
30
+
31
+ /**
32
+ * Called by New Architecture (TurboModules) to instantiate the module by name. Old Architecture
33
+ * continues to use createNativeModules() which TurboReactPackage implements internally by
34
+ * delegating to this method via getReactModuleInfoProvider.
35
+ */
36
+ override fun getModule(name: String, reactContext: ReactApplicationContext): NativeModule? =
37
+ when (name) {
38
+ DigiaModule.MODULE_NAME -> DigiaModule(reactContext)
39
+ else -> null
40
+ }
41
+
42
+ /**
43
+ * Metadata table: tells the RN runtime which modules this package provides and whether they
44
+ * should be treated as TurboModules (New Architecture).
45
+ */
46
+ override fun getReactModuleInfoProvider(): ReactModuleInfoProvider = ReactModuleInfoProvider {
47
+ mapOf(
48
+ DigiaModule.MODULE_NAME to
49
+ ReactModuleInfo(
50
+ /* name */ DigiaModule.MODULE_NAME,
51
+ /* className */ DigiaModule.MODULE_NAME,
52
+ /* canOverrideExistingModule */ false,
53
+ /* needsEagerInit */ false,
54
+ /* isCxxModule */ false,
55
+ /* isTurboModule */ false,
56
+ ),
57
+ )
58
+ }
59
+
60
+ // ─── View Managers ────────────────────────────────────────────────────────
61
+
62
+ override fun createViewManagers(
63
+ reactContext: ReactApplicationContext,
64
+ ): List<ViewManager<*, *>> =
65
+ listOf(
66
+ DigiaViewManager(),
67
+ DigiaSlotViewManager(),
68
+ )
69
+ }
@@ -0,0 +1,64 @@
1
+ /**
2
+ * DigiaSlotViewManager
3
+ *
4
+ * React Native ViewManager that exposes [DigiaSlotView] (from the Digia Android SDK) as the native
5
+ * view behind the JS `<DigiaSlotView>` component.
6
+ *
7
+ * Supported JS props:
8
+ * - `placementKey` (String) — matches the placement key set in the Digia dashboard.
9
+ */
10
+ package com.digia.engage.rn
11
+
12
+ import android.content.Context
13
+ import android.widget.FrameLayout
14
+ import androidx.lifecycle.LifecycleOwner
15
+ import androidx.lifecycle.ViewModelStoreOwner
16
+ import androidx.lifecycle.setViewTreeLifecycleOwner
17
+ import androidx.lifecycle.setViewTreeViewModelStoreOwner
18
+ import androidx.savedstate.SavedStateRegistryOwner
19
+ import androidx.savedstate.setViewTreeSavedStateRegistryOwner
20
+ import com.digia.engage.DigiaSlotView
21
+ import com.facebook.react.uimanager.SimpleViewManager
22
+ import com.facebook.react.uimanager.ThemedReactContext
23
+ import com.facebook.react.uimanager.annotations.ReactProp
24
+
25
+ internal class DigiaSlotViewManager : SimpleViewManager<DigiaSlotView>() {
26
+
27
+ override fun getName(): String = VIEW_NAME
28
+
29
+ override fun createViewInstance(context: ThemedReactContext): DigiaSlotView {
30
+ val activityContext: Context = context.currentActivity ?: context
31
+
32
+ val view = DigiaSlotView(activityContext)
33
+
34
+ // Wire Architecture Component owners so the Compose runtime works correctly.
35
+ val activity = context.currentActivity
36
+ if (activity is LifecycleOwner) {
37
+ view.setViewTreeLifecycleOwner(activity)
38
+ }
39
+ if (activity is ViewModelStoreOwner) {
40
+ view.setViewTreeViewModelStoreOwner(activity)
41
+ }
42
+ if (activity is SavedStateRegistryOwner) {
43
+ view.setViewTreeSavedStateRegistryOwner(activity)
44
+ }
45
+
46
+ // React Native controls sizing; fill whatever space the JS stylesheet allocates.
47
+ view.layoutParams =
48
+ FrameLayout.LayoutParams(
49
+ FrameLayout.LayoutParams.MATCH_PARENT,
50
+ FrameLayout.LayoutParams.MATCH_PARENT,
51
+ )
52
+
53
+ return view
54
+ }
55
+
56
+ @ReactProp(name = "placementKey")
57
+ fun setPlacementKey(view: DigiaSlotView, placementKey: String?) {
58
+ view.placementKey = placementKey.orEmpty()
59
+ }
60
+
61
+ companion object {
62
+ const val VIEW_NAME = "DigiaSlotView"
63
+ }
64
+ }
@@ -0,0 +1,63 @@
1
+ /**
2
+ * DigiaViewManager
3
+ *
4
+ * React Native ViewManager that exposes `DigiaHostView` (from the Digia Android SDK) as the native
5
+ * view behind the JS `<DigiaHostView>` component.
6
+ *
7
+ * The view hosts the `DigiaHost` composable which manages dialog and bottom-sheet overlays driven
8
+ * by Digia CEP plugins.
9
+ */
10
+ package com.digia.engage.rn
11
+
12
+ import android.content.Context
13
+ import android.widget.FrameLayout
14
+ import androidx.lifecycle.LifecycleOwner
15
+ import androidx.lifecycle.ViewModelStoreOwner
16
+ import androidx.lifecycle.setViewTreeLifecycleOwner
17
+ import androidx.lifecycle.setViewTreeViewModelStoreOwner
18
+ import androidx.savedstate.SavedStateRegistryOwner
19
+ import androidx.savedstate.setViewTreeSavedStateRegistryOwner
20
+ import com.digia.engage.DigiaHostView
21
+ import com.facebook.react.uimanager.SimpleViewManager
22
+ import com.facebook.react.uimanager.ThemedReactContext
23
+
24
+ internal class DigiaViewManager : SimpleViewManager<DigiaHostView>() {
25
+
26
+ override fun getName(): String = VIEW_NAME
27
+
28
+ override fun createViewInstance(context: ThemedReactContext): DigiaHostView {
29
+ // Prefer the current Activity as the context provider so that the Compose
30
+ // runtime can access a proper LifecycleOwner / ViewModelStoreOwner.
31
+ val activityContext: Context = context.currentActivity ?: context
32
+
33
+ val view = DigiaHostView(activityContext)
34
+
35
+ // Explicitly wire the Android Architecture Component owners so that the
36
+ // Compose runtime (which uses ViewTree* APIs) works correctly regardless
37
+ // of React Native's internal view hierarchy wiring.
38
+ val activity = context.currentActivity
39
+ if (activity is LifecycleOwner) {
40
+ view.setViewTreeLifecycleOwner(activity)
41
+ }
42
+ if (activity is ViewModelStoreOwner) {
43
+ view.setViewTreeViewModelStoreOwner(activity)
44
+ }
45
+ if (activity is SavedStateRegistryOwner) {
46
+ view.setViewTreeSavedStateRegistryOwner(activity)
47
+ }
48
+
49
+ // React Native controls sizing via its layout system; fill whatever space
50
+ // the JS stylesheet allocates (typically StyleSheet.absoluteFill).
51
+ view.layoutParams =
52
+ FrameLayout.LayoutParams(
53
+ FrameLayout.LayoutParams.MATCH_PARENT,
54
+ FrameLayout.LayoutParams.MATCH_PARENT,
55
+ )
56
+
57
+ return view
58
+ }
59
+
60
+ companion object {
61
+ const val VIEW_NAME = "DigiaHostView"
62
+ }
63
+ }
@@ -0,0 +1,71 @@
1
+ /**
2
+ * DigiaEngageModule (iOS stub)
3
+ *
4
+ * iOS support is not yet implemented. This stub registers the module so that
5
+ * the JS layer does not crash when imported on iOS. All methods are no-ops.
6
+ */
7
+ #import <React/RCTBridgeModule.h>
8
+ #import <React/RCTViewManager.h>
9
+
10
+ // ── NativeModule stub ─────────────────────────────────────────────────────────
11
+
12
+ @interface DigiaEngageModule : NSObject <RCTBridgeModule>
13
+ @end
14
+
15
+ @implementation DigiaEngageModule
16
+
17
+ RCT_EXPORT_MODULE(DigiaEngageModule)
18
+
19
+ RCT_EXPORT_METHOD(initialize:(NSString *)apiKey
20
+ environment:(NSString *)environment
21
+ logLevel:(NSString *)logLevel
22
+ resolve:(RCTPromiseResolveBlock)resolve
23
+ reject:(RCTPromiseRejectBlock)reject)
24
+ {
25
+ // iOS not yet implemented – resolve immediately so JS doesn't hang.
26
+ resolve(nil);
27
+ }
28
+
29
+ RCT_EXPORT_METHOD(setCurrentScreen:(NSString *)name)
30
+ {
31
+ // no-op
32
+ }
33
+
34
+ RCT_EXPORT_METHOD(openNavigation:(nullable NSString *)startPageId
35
+ pageArgs:(NSDictionary *)pageArgs)
36
+ {
37
+ // no-op
38
+ }
39
+
40
+ RCT_EXPORT_METHOD(triggerCampaign:(NSString *)campaignId
41
+ content:(NSDictionary *)content
42
+ cepContext:(NSDictionary *)cepContext)
43
+ {
44
+ // no-op — iOS Digia SDK not yet available
45
+ }
46
+
47
+ RCT_EXPORT_METHOD(invalidateCampaign:(NSString *)campaignId)
48
+ {
49
+ // no-op
50
+ }
51
+
52
+ @end
53
+
54
+
55
+ // ── ViewManager stub ──────────────────────────────────────────────────────────
56
+
57
+ @interface DigiaHostViewManager : RCTViewManager
58
+ @end
59
+
60
+ @implementation DigiaHostViewManager
61
+
62
+ RCT_EXPORT_MODULE(DigiaHostView)
63
+
64
+ - (UIView *)view {
65
+ // Return a transparent placeholder view
66
+ UIView *v = [[UIView alloc] init];
67
+ v.userInteractionEnabled = NO;
68
+ return v;
69
+ }
70
+
71
+ @end
@@ -0,0 +1,106 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.Digia = void 0;
7
+ var _NativeDigiaModule = require("./NativeDigiaModule");
8
+ /**
9
+ * High-level Digia Engage SDK wrapper.
10
+ *
11
+ * Usage
12
+ * ──────
13
+ * ```ts
14
+ * import { Digia } from '@digia/engage-react-native';
15
+ *
16
+ * // In your App entry point (e.g. App.tsx):
17
+ * await Digia.initialize({ apiKey: 'YOUR_API_KEY' });
18
+ *
19
+ * // Whenever your navigation screen changes:
20
+ * Digia.setCurrentScreen('Home');
21
+ *
22
+ * ```
23
+ */
24
+
25
+ class DigiaClass {
26
+ _plugins = new Map();
27
+ // Tracks whether the native bridge plugin (RNEventBridgePlugin) has been
28
+ // wired to the native SDK. Done once on the first Digia.register() call.
29
+ _nativeBridgeWired = false;
30
+
31
+ /**
32
+ * Initialise the Digia Engage SDK.
33
+ *
34
+ * Must be called once before anything else – ideally as early as possible
35
+ * in your application lifecycle (start of `App.tsx`).
36
+ */
37
+ async initialize(config) {
38
+ const environment = config.environment ?? 'production';
39
+ const logLevel = config.logLevel ?? 'error';
40
+ await _NativeDigiaModule.nativeDigiaModule.initialize(config.apiKey, environment, logLevel);
41
+ }
42
+
43
+ /**
44
+ * Register a CEP plugin with the Digia SDK.
45
+ *
46
+ * On the first call this also wires the internal RNEventBridgePlugin with
47
+ * the native Android SDK so it holds the DigiaCEPDelegate reference needed
48
+ * to show overlays and emit lifecycle events back to JS. This is transparent
49
+ * bridge plumbing — you never interact with RNEventBridgePlugin directly.
50
+ *
51
+ * ```ts
52
+ * import { DigiaMoEngagePlugin } from '@digia/moengage-plugin';
53
+ *
54
+ * await Digia.initialize({ apiKey: 'YOUR_KEY' });
55
+ * Digia.register(new DigiaMoEngagePlugin({ moEngage: MoEngage }));
56
+ * ```
57
+ */
58
+ register(plugin) {
59
+ if (this._plugins.has(plugin.identifier)) {
60
+ this._plugins.get(plugin.identifier).teardown();
61
+ }
62
+ // Wire the native bridge plugin once, before the first plugin's setup()
63
+ // so the delegate is ready when JS campaigns start flowing.
64
+ if (!this._nativeBridgeWired) {
65
+ _NativeDigiaModule.nativeDigiaModule.registerBridge();
66
+ this._nativeBridgeWired = true;
67
+ }
68
+ plugin.setup(this);
69
+ this._plugins.set(plugin.identifier, plugin);
70
+ }
71
+
72
+ /**
73
+ * Unregister a previously registered plugin.
74
+ * Calls plugin.teardown() internally.
75
+ */
76
+ unregister(pluginOrId) {
77
+ const id = typeof pluginOrId === 'string' ? pluginOrId : pluginOrId.identifier;
78
+ this._plugins.get(id)?.teardown();
79
+ this._plugins.delete(id);
80
+ }
81
+
82
+ /**
83
+ * Notify the SDK of the currently active screen name.
84
+ *
85
+ * Wire this up to your navigation library's screen-change listener
86
+ * (e.g. React Navigation focus events or `useNavigationContainerRef`).
87
+ * All registered plugins will have forwardScreen() called automatically.
88
+ */
89
+ setCurrentScreen(name) {
90
+ _NativeDigiaModule.nativeDigiaModule.setCurrentScreen(name);
91
+ this._plugins.forEach(plugin => plugin.forwardScreen(name));
92
+ }
93
+
94
+ // ── DigiaDelegate ────────────────────────────────────────────────────────
95
+ // Mirrors DigiaCEPDelegate on Android.
96
+ // Forwards to the native DigiaCEPDelegate via the bridge.
97
+
98
+ onCampaignTriggered(payload) {
99
+ _NativeDigiaModule.nativeDigiaModule.triggerCampaign(payload.id, payload.content, payload.cepContext);
100
+ }
101
+ onCampaignInvalidated(campaignId) {
102
+ _NativeDigiaModule.nativeDigiaModule.invalidateCampaign(campaignId);
103
+ }
104
+ }
105
+ const Digia = exports.Digia = new DigiaClass();
106
+ //# sourceMappingURL=Digia.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_NativeDigiaModule","require","DigiaClass","_plugins","Map","_nativeBridgeWired","initialize","config","environment","logLevel","nativeDigiaModule","apiKey","register","plugin","has","identifier","get","teardown","registerBridge","setup","set","unregister","pluginOrId","id","delete","setCurrentScreen","name","forEach","forwardScreen","onCampaignTriggered","payload","triggerCampaign","content","cepContext","onCampaignInvalidated","campaignId","invalidateCampaign","Digia","exports"],"sourceRoot":"../../src","sources":["Digia.ts"],"mappings":";;;;;;AAiBA,IAAAA,kBAAA,GAAAC,OAAA;AAjBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAKA,MAAMC,UAAU,CAA0B;EACrBC,QAAQ,GAAG,IAAIC,GAAG,CAAsB,CAAC;EAC1D;EACA;EACQC,kBAAkB,GAAG,KAAK;;EAElC;AACJ;AACA;AACA;AACA;AACA;EACI,MAAMC,UAAUA,CAACC,MAAmB,EAAiB;IACjD,MAAMC,WAAW,GAAGD,MAAM,CAACC,WAAW,IAAI,YAAY;IACtD,MAAMC,QAAQ,GAAGF,MAAM,CAACE,QAAQ,IAAI,OAAO;IAC3C,MAAMC,oCAAiB,CAACJ,UAAU,CAACC,MAAM,CAACI,MAAM,EAAEH,WAAW,EAAEC,QAAQ,CAAC;EAC5E;;EAEA;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACIG,QAAQA,CAACC,MAAmB,EAAQ;IAChC,IAAI,IAAI,CAACV,QAAQ,CAACW,GAAG,CAACD,MAAM,CAACE,UAAU,CAAC,EAAE;MACtC,IAAI,CAACZ,QAAQ,CAACa,GAAG,CAACH,MAAM,CAACE,UAAU,CAAC,CAAEE,QAAQ,CAAC,CAAC;IACpD;IACA;IACA;IACA,IAAI,CAAC,IAAI,CAACZ,kBAAkB,EAAE;MAC1BK,oCAAiB,CAACQ,cAAc,CAAC,CAAC;MAClC,IAAI,CAACb,kBAAkB,GAAG,IAAI;IAClC;IACAQ,MAAM,CAACM,KAAK,CAAC,IAAI,CAAC;IAClB,IAAI,CAAChB,QAAQ,CAACiB,GAAG,CAACP,MAAM,CAACE,UAAU,EAAEF,MAAM,CAAC;EAChD;;EAEA;AACJ;AACA;AACA;EACIQ,UAAUA,CAACC,UAAgC,EAAQ;IAC/C,MAAMC,EAAE,GAAG,OAAOD,UAAU,KAAK,QAAQ,GAAGA,UAAU,GAAGA,UAAU,CAACP,UAAU;IAC9E,IAAI,CAACZ,QAAQ,CAACa,GAAG,CAACO,EAAE,CAAC,EAAEN,QAAQ,CAAC,CAAC;IACjC,IAAI,CAACd,QAAQ,CAACqB,MAAM,CAACD,EAAE,CAAC;EAC5B;;EAEA;AACJ;AACA;AACA;AACA;AACA;AACA;EACIE,gBAAgBA,CAACC,IAAY,EAAQ;IACjChB,oCAAiB,CAACe,gBAAgB,CAACC,IAAI,CAAC;IACxC,IAAI,CAACvB,QAAQ,CAACwB,OAAO,CAAEd,MAAM,IAAKA,MAAM,CAACe,aAAa,CAACF,IAAI,CAAC,CAAC;EACjE;;EAEA;EACA;EACA;;EAEAG,mBAAmBA,CAACC,OAAqB,EAAQ;IAC7CpB,oCAAiB,CAACqB,eAAe,CAACD,OAAO,CAACP,EAAE,EAAEO,OAAO,CAACE,OAAO,EAAEF,OAAO,CAACG,UAAU,CAAC;EACtF;EAEAC,qBAAqBA,CAACC,UAAkB,EAAQ;IAC5CzB,oCAAiB,CAAC0B,kBAAkB,CAACD,UAAU,CAAC;EACpD;AAEJ;AAEO,MAAME,KAAK,GAAAC,OAAA,CAAAD,KAAA,GAAG,IAAInC,UAAU,CAAC,CAAC","ignoreList":[]}