@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.
- package/DigiaEngageReactNative.podspec +21 -0
- package/README.md +277 -0
- package/android/build.gradle +82 -0
- package/android/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/android/gradlew +185 -0
- package/android/gradlew.bat +89 -0
- package/android/settings.gradle +33 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/java/com/digia/engage/rn/DigiaModule.kt +234 -0
- package/android/src/main/java/com/digia/engage/rn/DigiaPackage.kt +69 -0
- package/android/src/main/java/com/digia/engage/rn/DigiaSlotViewManager.kt +64 -0
- package/android/src/main/java/com/digia/engage/rn/DigiaViewManager.kt +63 -0
- package/ios/DigiaEngageModule.m +71 -0
- package/lib/commonjs/Digia.js +106 -0
- package/lib/commonjs/Digia.js.map +1 -0
- package/lib/commonjs/DigiaHostView.js +73 -0
- package/lib/commonjs/DigiaHostView.js.map +1 -0
- package/lib/commonjs/DigiaSlotView.js +73 -0
- package/lib/commonjs/DigiaSlotView.js.map +1 -0
- package/lib/commonjs/NativeDigiaModule.js +56 -0
- package/lib/commonjs/NativeDigiaModule.js.map +1 -0
- package/lib/commonjs/index.js +27 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/types.js +2 -0
- package/lib/commonjs/types.js.map +1 -0
- package/lib/module/Digia.js +100 -0
- package/lib/module/Digia.js.map +1 -0
- package/lib/module/DigiaHostView.js +67 -0
- package/lib/module/DigiaHostView.js.map +1 -0
- package/lib/module/DigiaSlotView.js +66 -0
- package/lib/module/DigiaSlotView.js.map +1 -0
- package/lib/module/NativeDigiaModule.js +51 -0
- package/lib/module/NativeDigiaModule.js.map +1 -0
- package/lib/module/index.js +15 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/types.js +2 -0
- package/lib/module/types.js.map +1 -0
- package/lib/typescript/Digia.d.ts +62 -0
- package/lib/typescript/Digia.d.ts.map +1 -0
- package/lib/typescript/DigiaHostView.d.ts +40 -0
- package/lib/typescript/DigiaHostView.d.ts.map +1 -0
- package/lib/typescript/DigiaSlotView.d.ts +52 -0
- package/lib/typescript/DigiaSlotView.d.ts.map +1 -0
- package/lib/typescript/NativeDigiaModule.d.ts +45 -0
- package/lib/typescript/NativeDigiaModule.d.ts.map +1 -0
- package/lib/typescript/index.d.ts +15 -0
- package/lib/typescript/index.d.ts.map +1 -0
- package/lib/typescript/types.d.ts +58 -0
- package/lib/typescript/types.d.ts.map +1 -0
- package/package.json +89 -0
- package/src/Digia.ts +104 -0
- package/src/DigiaHostView.tsx +83 -0
- package/src/DigiaSlotView.tsx +79 -0
- package/src/NativeDigiaModule.ts +86 -0
- package/src/index.ts +15 -0
- package/src/types.ts +61 -0
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* High-level Digia Engage SDK wrapper.
|
|
3
|
+
*
|
|
4
|
+
* Usage
|
|
5
|
+
* ──────
|
|
6
|
+
* ```ts
|
|
7
|
+
* import { Digia } from '@digia/engage-react-native';
|
|
8
|
+
*
|
|
9
|
+
* // In your App entry point (e.g. App.tsx):
|
|
10
|
+
* await Digia.initialize({ apiKey: 'YOUR_API_KEY' });
|
|
11
|
+
*
|
|
12
|
+
* // Whenever your navigation screen changes:
|
|
13
|
+
* Digia.setCurrentScreen('Home');
|
|
14
|
+
*
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
import type { DigiaConfig, DigiaDelegate, DigiaPlugin, InAppPayload } from './types';
|
|
18
|
+
declare class DigiaClass implements DigiaDelegate {
|
|
19
|
+
private readonly _plugins;
|
|
20
|
+
private _nativeBridgeWired;
|
|
21
|
+
/**
|
|
22
|
+
* Initialise the Digia Engage SDK.
|
|
23
|
+
*
|
|
24
|
+
* Must be called once before anything else – ideally as early as possible
|
|
25
|
+
* in your application lifecycle (start of `App.tsx`).
|
|
26
|
+
*/
|
|
27
|
+
initialize(config: DigiaConfig): Promise<void>;
|
|
28
|
+
/**
|
|
29
|
+
* Register a CEP plugin with the Digia SDK.
|
|
30
|
+
*
|
|
31
|
+
* On the first call this also wires the internal RNEventBridgePlugin with
|
|
32
|
+
* the native Android SDK so it holds the DigiaCEPDelegate reference needed
|
|
33
|
+
* to show overlays and emit lifecycle events back to JS. This is transparent
|
|
34
|
+
* bridge plumbing — you never interact with RNEventBridgePlugin directly.
|
|
35
|
+
*
|
|
36
|
+
* ```ts
|
|
37
|
+
* import { DigiaMoEngagePlugin } from '@digia/moengage-plugin';
|
|
38
|
+
*
|
|
39
|
+
* await Digia.initialize({ apiKey: 'YOUR_KEY' });
|
|
40
|
+
* Digia.register(new DigiaMoEngagePlugin({ moEngage: MoEngage }));
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
register(plugin: DigiaPlugin): void;
|
|
44
|
+
/**
|
|
45
|
+
* Unregister a previously registered plugin.
|
|
46
|
+
* Calls plugin.teardown() internally.
|
|
47
|
+
*/
|
|
48
|
+
unregister(pluginOrId: DigiaPlugin | string): void;
|
|
49
|
+
/**
|
|
50
|
+
* Notify the SDK of the currently active screen name.
|
|
51
|
+
*
|
|
52
|
+
* Wire this up to your navigation library's screen-change listener
|
|
53
|
+
* (e.g. React Navigation focus events or `useNavigationContainerRef`).
|
|
54
|
+
* All registered plugins will have forwardScreen() called automatically.
|
|
55
|
+
*/
|
|
56
|
+
setCurrentScreen(name: string): void;
|
|
57
|
+
onCampaignTriggered(payload: InAppPayload): void;
|
|
58
|
+
onCampaignInvalidated(campaignId: string): void;
|
|
59
|
+
}
|
|
60
|
+
export declare const Digia: DigiaClass;
|
|
61
|
+
export {};
|
|
62
|
+
//# sourceMappingURL=Digia.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Digia.d.ts","sourceRoot":"","sources":["../../src/Digia.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAErF,cAAM,UAAW,YAAW,aAAa;IACrC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAkC;IAG3D,OAAO,CAAC,kBAAkB,CAAS;IAEnC;;;;;OAKG;IACG,UAAU,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAMpD;;;;;;;;;;;;;;OAcG;IACH,QAAQ,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI;IAcnC;;;OAGG;IACH,UAAU,CAAC,UAAU,EAAE,WAAW,GAAG,MAAM,GAAG,IAAI;IAMlD;;;;;;OAMG;IACH,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IASpC,mBAAmB,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI;IAIhD,qBAAqB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;CAIlD;AAED,eAAO,MAAM,KAAK,YAAmB,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DigiaHostView
|
|
3
|
+
*
|
|
4
|
+
* A transparent React Native view that attaches the Digia Android Compose
|
|
5
|
+
* overlay layer (dialogs, bottom sheets) on top of your app's content.
|
|
6
|
+
*
|
|
7
|
+
* ─── Usage ───────────────────────────────────────────────────────────────────
|
|
8
|
+
* Place `<DigiaHostView>` at the **root** of your component tree so that
|
|
9
|
+
* Digia dialogs and bottom sheets can stack on top of all your content.
|
|
10
|
+
*
|
|
11
|
+
* ```tsx
|
|
12
|
+
* import React from 'react';
|
|
13
|
+
* import { StyleSheet, View } from 'react-native';
|
|
14
|
+
* import { DigiaHostView } from '@digia/engage-react-native';
|
|
15
|
+
*
|
|
16
|
+
* export default function App() {
|
|
17
|
+
* return (
|
|
18
|
+
* <View style={styles.root}>
|
|
19
|
+
* <DigiaHostView style={StyleSheet.absoluteFill} />
|
|
20
|
+
* {/ * your navigation / app content here * /}
|
|
21
|
+
* </View>
|
|
22
|
+
* );
|
|
23
|
+
* }
|
|
24
|
+
*
|
|
25
|
+
* const styles = StyleSheet.create({ root: { flex: 1 } });
|
|
26
|
+
* ```
|
|
27
|
+
*
|
|
28
|
+
* On Android this mounts a Jetpack Compose `DigiaHost` composable that
|
|
29
|
+
* manages dialog + bottom-sheet presentation triggered by CEP plugins.
|
|
30
|
+
* On iOS the view is a transparent no-op until iOS support is implemented.
|
|
31
|
+
* ─────────────────────────────────────────────────────────────────────────────
|
|
32
|
+
*/
|
|
33
|
+
import React from 'react';
|
|
34
|
+
import { type StyleProp, type ViewStyle } from 'react-native';
|
|
35
|
+
interface DigiaHostViewProps {
|
|
36
|
+
style?: StyleProp<ViewStyle>;
|
|
37
|
+
}
|
|
38
|
+
export declare function DigiaHostView({ style }: DigiaHostViewProps): React.JSX.Element | null;
|
|
39
|
+
export {};
|
|
40
|
+
//# sourceMappingURL=DigiaHostView.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DigiaHostView.d.ts","sourceRoot":"","sources":["../../src/DigiaHostView.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAIH,KAAK,SAAS,EACd,KAAK,SAAS,EACjB,MAAM,cAAc,CAAC;AAEtB,UAAU,kBAAkB;IACxB,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;CAChC;AAgBD,wBAAgB,aAAa,CAAC,EAAE,KAAK,EAAE,EAAE,kBAAkB,4BAc1D"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DigiaSlotView
|
|
3
|
+
*
|
|
4
|
+
* A React Native view that renders inline campaign content (banners, cards,
|
|
5
|
+
* widgets) at a specific placement position inside your screen layout.
|
|
6
|
+
*
|
|
7
|
+
* On Android this mounts a Jetpack Compose `DigiaSlot` composable that
|
|
8
|
+
* observes the slot payload for the given placement key and renders the
|
|
9
|
+
* matching campaign component. On iOS it is a transparent no-op.
|
|
10
|
+
*
|
|
11
|
+
* ─── Usage ───────────────────────────────────────────────────────────────────
|
|
12
|
+
* ```tsx
|
|
13
|
+
* import { DigiaSlotView } from '@digia/engage-react-native';
|
|
14
|
+
*
|
|
15
|
+
* // Fixed height (you control the space)
|
|
16
|
+
* <DigiaSlotView
|
|
17
|
+
* placementKey="hero_banner"
|
|
18
|
+
* style={{ width: '100%', height: 200 }}
|
|
19
|
+
* />
|
|
20
|
+
*
|
|
21
|
+
* // Inside a scroll view
|
|
22
|
+
* <ScrollView>
|
|
23
|
+
* <ProductList />
|
|
24
|
+
* <DigiaSlotView
|
|
25
|
+
* placementKey="pdp_mid_banner"
|
|
26
|
+
* style={{ width: '100%', height: 120 }}
|
|
27
|
+
* />
|
|
28
|
+
* <RelatedProducts />
|
|
29
|
+
* </ScrollView>
|
|
30
|
+
* ```
|
|
31
|
+
*
|
|
32
|
+
* The `placementKey` must match the key the marketer selects when creating
|
|
33
|
+
* inline content on the Digia dashboard. The view collapses to nothing when
|
|
34
|
+
* no campaign is active for that key.
|
|
35
|
+
*
|
|
36
|
+
* ─── Sizing ──────────────────────────────────────────────────────────────────
|
|
37
|
+
* React Native's layout system controls the dimensions of this view.
|
|
38
|
+
* Provide an explicit `height` (or flex) via the `style` prop so that the
|
|
39
|
+
* native Compose layer has space to render. When no campaign is active the
|
|
40
|
+
* Compose `DigiaSlot` renders nothing inside that space.
|
|
41
|
+
* ─────────────────────────────────────────────────────────────────────────────
|
|
42
|
+
*/
|
|
43
|
+
import React from 'react';
|
|
44
|
+
import { type StyleProp, type ViewStyle } from 'react-native';
|
|
45
|
+
interface DigiaSlotViewProps {
|
|
46
|
+
/** Placement key that links this view to a Digia dashboard slot. */
|
|
47
|
+
placementKey: string;
|
|
48
|
+
style?: StyleProp<ViewStyle>;
|
|
49
|
+
}
|
|
50
|
+
export declare function DigiaSlotView({ placementKey, style }: DigiaSlotViewProps): React.JSX.Element | null;
|
|
51
|
+
export {};
|
|
52
|
+
//# sourceMappingURL=DigiaSlotView.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DigiaSlotView.d.ts","sourceRoot":"","sources":["../../src/DigiaSlotView.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAGH,KAAK,SAAS,EACd,KAAK,SAAS,EACjB,MAAM,cAAc,CAAC;AAEtB,UAAU,kBAAkB;IACxB,oEAAoE;IACpE,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;CAChC;AAWD,wBAAgB,aAAa,CAAC,EAAE,YAAY,EAAE,KAAK,EAAE,EAAE,kBAAkB,4BAYxE"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NativeDigiaModule
|
|
3
|
+
*
|
|
4
|
+
* Low-level TurboModule binding to the native Digia Engage module.
|
|
5
|
+
*
|
|
6
|
+
* The module is resolved lazily on first use (not at import time) so that
|
|
7
|
+
* module evaluation before native initialisation doesn't throw.
|
|
8
|
+
* Resolution order:
|
|
9
|
+
* 1. TurboModuleRegistry.get() — New Architecture / JSI path
|
|
10
|
+
* 2. NativeModules — bridge interop layer (RN 0.73+ New Arch
|
|
11
|
+
* with isTurboModule: false in ReactModuleInfo)
|
|
12
|
+
* 3. null — non-Android environments; methods no-op
|
|
13
|
+
*
|
|
14
|
+
* Prefer using the high-level `Digia` singleton from `index.ts`.
|
|
15
|
+
*/
|
|
16
|
+
import type { TurboModule } from 'react-native';
|
|
17
|
+
/**
|
|
18
|
+
* Codegen spec — drives Android/iOS TurboModule generation.
|
|
19
|
+
*
|
|
20
|
+
* Rules for codegen compatibility:
|
|
21
|
+
* • File must be named `Native*.ts` (already satisfied).
|
|
22
|
+
* • All method parameter types must be scalar, Promise, Object, or Array.
|
|
23
|
+
* • `Object` maps to ReadableMap on Android, NSDictionary on iOS.
|
|
24
|
+
*/
|
|
25
|
+
export interface Spec extends TurboModule {
|
|
26
|
+
/** Initialise the SDK. Call once before anything else. */
|
|
27
|
+
initialize(apiKey: string, environment: string, logLevel: string): Promise<void>;
|
|
28
|
+
/**
|
|
29
|
+
* Wire the internal RNEventBridgePlugin with the native SDK.
|
|
30
|
+
* Called automatically by Digia.register() on first plugin registration.
|
|
31
|
+
* Never call this directly.
|
|
32
|
+
*/
|
|
33
|
+
registerBridge(): void;
|
|
34
|
+
/** Notify the SDK of the currently visible screen. */
|
|
35
|
+
setCurrentScreen(name: string): void;
|
|
36
|
+
/**
|
|
37
|
+
* Forward a campaign payload from a JS CEP plugin into the native
|
|
38
|
+
* rendering engine via the DigiaCEPDelegate.
|
|
39
|
+
*/
|
|
40
|
+
triggerCampaign(id: string, content: Object, cepContext: Object): void;
|
|
41
|
+
/** Invalidate / dismiss a campaign by its ID. */
|
|
42
|
+
invalidateCampaign(campaignId: string): void;
|
|
43
|
+
}
|
|
44
|
+
export declare const nativeDigiaModule: Spec;
|
|
45
|
+
//# sourceMappingURL=NativeDigiaModule.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NativeDigiaModule.d.ts","sourceRoot":"","sources":["../../src/NativeDigiaModule.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAGhD;;;;;;;GAOG;AACH,MAAM,WAAW,IAAK,SAAQ,WAAW;IACrC,0DAA0D;IAC1D,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjF;;;;OAIG;IACH,cAAc,IAAI,IAAI,CAAC;IAEvB,sDAAsD;IACtD,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAErC;;;OAGG;IACH,eAAe,CACX,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,GACnB,IAAI,CAAC;IAER,iDAAiD;IACjD,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAChD;AAwBD,eAAO,MAAM,iBAAiB,EAAE,IAS/B,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @digia/engage-react-native
|
|
3
|
+
*
|
|
4
|
+
* React Native bridge for the Digia Engage SDK.
|
|
5
|
+
*
|
|
6
|
+
* The SDK surfaces Digia Compose UI inside React Native via:
|
|
7
|
+
* • `Digia` – SDK lifecycle (initialize, setCurrentScreen)
|
|
8
|
+
* • `DigiaHostView` – Transparent native overlay view that hosts Compose dialogs/
|
|
9
|
+
* bottom-sheets managed by the Digia CEP engine.
|
|
10
|
+
*/
|
|
11
|
+
export { Digia } from './Digia';
|
|
12
|
+
export { DigiaHostView } from './DigiaHostView';
|
|
13
|
+
export { DigiaSlotView } from './DigiaSlotView';
|
|
14
|
+
export type { DigiaConfig, DigiaDelegate, DigiaPlugin, InAppPayload } from './types';
|
|
15
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Payload delivered to the Digia rendering engine for a CEP campaign.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors InAppPayload on Android / Flutter.
|
|
5
|
+
*/
|
|
6
|
+
export interface InAppPayload {
|
|
7
|
+
/** Unique campaign ID from the CEP platform. */
|
|
8
|
+
id: string;
|
|
9
|
+
/** Marketer-authored content map (JSON-serialisable). */
|
|
10
|
+
content: Record<string, unknown>;
|
|
11
|
+
/** CEP-platform metadata, e.g. { campaignId, campaignName }. */
|
|
12
|
+
cepContext: Record<string, unknown>;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Delegate passed by the Digia SDK to each registered plugin via setup().
|
|
16
|
+
*
|
|
17
|
+
* Mirrors DigiaCEPDelegate on Android / Flutter.
|
|
18
|
+
* Call these instead of touching Digia directly from inside a plugin.
|
|
19
|
+
*/
|
|
20
|
+
export interface DigiaDelegate {
|
|
21
|
+
/** Deliver a campaign payload into the Digia rendering engine. */
|
|
22
|
+
onCampaignTriggered(payload: InAppPayload): void;
|
|
23
|
+
/** Invalidate / dismiss a campaign by its ID. */
|
|
24
|
+
onCampaignInvalidated(campaignId: string): void;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Interface that every Digia CEP plugin must implement.
|
|
28
|
+
*
|
|
29
|
+
* Mirrors DigiaCEPPlugin on Android / Flutter.
|
|
30
|
+
* Register plugins via `Digia.register(plugin)` — do NOT call setup() directly.
|
|
31
|
+
*/
|
|
32
|
+
export interface DigiaPlugin {
|
|
33
|
+
readonly identifier: string;
|
|
34
|
+
/** Called by Digia.register() — do not call manually. */
|
|
35
|
+
setup(delegate: DigiaDelegate): void;
|
|
36
|
+
/** Called by Digia.setCurrentScreen() — do not call manually. */
|
|
37
|
+
forwardScreen(name: string): void;
|
|
38
|
+
/** Called by Digia.unregister() or when tearing down the app. */
|
|
39
|
+
teardown(): void;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Configuration for initialising the Digia Engage SDK.
|
|
43
|
+
*/
|
|
44
|
+
export interface DigiaConfig {
|
|
45
|
+
/** The API key provided by Digia. */
|
|
46
|
+
apiKey: string;
|
|
47
|
+
/**
|
|
48
|
+
* The target environment.
|
|
49
|
+
* @default 'production'
|
|
50
|
+
*/
|
|
51
|
+
environment?: 'production' | 'sandbox';
|
|
52
|
+
/**
|
|
53
|
+
* Log verbosity.
|
|
54
|
+
* @default 'error'
|
|
55
|
+
*/
|
|
56
|
+
logLevel?: 'none' | 'error' | 'verbose';
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,WAAW,YAAY;IACzB,gDAAgD;IAChD,EAAE,EAAE,MAAM,CAAC;IACX,yDAAyD;IACzD,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,gEAAgE;IAChE,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACvC;AAED;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC1B,kEAAkE;IAClE,mBAAmB,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI,CAAC;IACjD,iDAAiD;IACjD,qBAAqB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CACnD;AAED;;;;;GAKG;AACH,MAAM,WAAW,WAAW;IACxB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,yDAAyD;IACzD,KAAK,CAAC,QAAQ,EAAE,aAAa,GAAG,IAAI,CAAC;IACrC,iEAAiE;IACjE,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,iEAAiE;IACjE,QAAQ,IAAI,IAAI,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IACxB,qCAAqC;IACrC,MAAM,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,WAAW,CAAC,EAAE,YAAY,GAAG,SAAS,CAAC;IACvC;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;CAC3C"}
|
package/package.json
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@digia-engage/core",
|
|
3
|
+
"version": "1.0.0-beta.1",
|
|
4
|
+
"description": "React Native bridge for Digia Engage – renders native Android Compose UI inside React Native apps",
|
|
5
|
+
"main": "lib/commonjs/index",
|
|
6
|
+
"module": "lib/module/index",
|
|
7
|
+
"types": "lib/typescript/index.d.ts",
|
|
8
|
+
"react-native": "src/index",
|
|
9
|
+
"source": "src/index",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"import": "./lib/module/index.js",
|
|
13
|
+
"require": "./lib/commonjs/index.js",
|
|
14
|
+
"types": "./lib/typescript/index.d.ts"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"src",
|
|
19
|
+
"lib",
|
|
20
|
+
"android",
|
|
21
|
+
"ios",
|
|
22
|
+
"*.podspec",
|
|
23
|
+
"!lib/typescript/example",
|
|
24
|
+
"!android/.gradle",
|
|
25
|
+
"!android/build",
|
|
26
|
+
"!android/example",
|
|
27
|
+
"!ios/build",
|
|
28
|
+
"!**/__tests__",
|
|
29
|
+
"!**/__fixtures__",
|
|
30
|
+
"!**/__mocks__"
|
|
31
|
+
],
|
|
32
|
+
"scripts": {
|
|
33
|
+
"typecheck": "tsc --noEmit",
|
|
34
|
+
"lint": "eslint \"**/*.{js,ts,tsx}\"",
|
|
35
|
+
"build": "bob build",
|
|
36
|
+
"prepare": "bob build"
|
|
37
|
+
},
|
|
38
|
+
"keywords": [
|
|
39
|
+
"react-native",
|
|
40
|
+
"digia",
|
|
41
|
+
"engage",
|
|
42
|
+
"compose",
|
|
43
|
+
"android",
|
|
44
|
+
"native"
|
|
45
|
+
],
|
|
46
|
+
"repository": {
|
|
47
|
+
"type": "git",
|
|
48
|
+
"url": "git+https://github.com/Digia-Technology-Private-Limited/digia_engage.git",
|
|
49
|
+
"directory": "react-native"
|
|
50
|
+
},
|
|
51
|
+
"author": "Digia Technology Private Limited",
|
|
52
|
+
"license": "MIT",
|
|
53
|
+
"peerDependencies": {
|
|
54
|
+
"react": "*",
|
|
55
|
+
"react-native": "*"
|
|
56
|
+
},
|
|
57
|
+
"devDependencies": {
|
|
58
|
+
"@react-native/eslint-config": "^0.73.0",
|
|
59
|
+
"@types/react": "^18.2.0",
|
|
60
|
+
"@types/react-native": "^0.73.0",
|
|
61
|
+
"eslint": "^8.51.0",
|
|
62
|
+
"react": "18.2.0",
|
|
63
|
+
"react-native": "0.73.0",
|
|
64
|
+
"react-native-builder-bob": "^0.23.0",
|
|
65
|
+
"typescript": "^5.2.0"
|
|
66
|
+
},
|
|
67
|
+
"react-native-builder-bob": {
|
|
68
|
+
"source": "src",
|
|
69
|
+
"output": "lib",
|
|
70
|
+
"targets": [
|
|
71
|
+
"commonjs",
|
|
72
|
+
"module",
|
|
73
|
+
[
|
|
74
|
+
"typescript",
|
|
75
|
+
{
|
|
76
|
+
"project": "tsconfig.build.json"
|
|
77
|
+
}
|
|
78
|
+
]
|
|
79
|
+
]
|
|
80
|
+
},
|
|
81
|
+
"codegenConfig": {
|
|
82
|
+
"name": "DigiaEngageSpec",
|
|
83
|
+
"type": "modules",
|
|
84
|
+
"jsSrcsDir": "src",
|
|
85
|
+
"android": {
|
|
86
|
+
"javaPackageName": "com.digia.engage.rn"
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
package/src/Digia.ts
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* High-level Digia Engage SDK wrapper.
|
|
3
|
+
*
|
|
4
|
+
* Usage
|
|
5
|
+
* ──────
|
|
6
|
+
* ```ts
|
|
7
|
+
* import { Digia } from '@digia/engage-react-native';
|
|
8
|
+
*
|
|
9
|
+
* // In your App entry point (e.g. App.tsx):
|
|
10
|
+
* await Digia.initialize({ apiKey: 'YOUR_API_KEY' });
|
|
11
|
+
*
|
|
12
|
+
* // Whenever your navigation screen changes:
|
|
13
|
+
* Digia.setCurrentScreen('Home');
|
|
14
|
+
*
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import { nativeDigiaModule } from './NativeDigiaModule';
|
|
19
|
+
import type { DigiaConfig, DigiaDelegate, DigiaPlugin, InAppPayload } from './types';
|
|
20
|
+
|
|
21
|
+
class DigiaClass implements DigiaDelegate {
|
|
22
|
+
private readonly _plugins = new Map<string, DigiaPlugin>();
|
|
23
|
+
// Tracks whether the native bridge plugin (RNEventBridgePlugin) has been
|
|
24
|
+
// wired to the native SDK. Done once on the first Digia.register() call.
|
|
25
|
+
private _nativeBridgeWired = false;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Initialise the Digia Engage SDK.
|
|
29
|
+
*
|
|
30
|
+
* Must be called once before anything else – ideally as early as possible
|
|
31
|
+
* in your application lifecycle (start of `App.tsx`).
|
|
32
|
+
*/
|
|
33
|
+
async initialize(config: DigiaConfig): Promise<void> {
|
|
34
|
+
const environment = config.environment ?? 'production';
|
|
35
|
+
const logLevel = config.logLevel ?? 'error';
|
|
36
|
+
await nativeDigiaModule.initialize(config.apiKey, environment, logLevel);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Register a CEP plugin with the Digia SDK.
|
|
41
|
+
*
|
|
42
|
+
* On the first call this also wires the internal RNEventBridgePlugin with
|
|
43
|
+
* the native Android SDK so it holds the DigiaCEPDelegate reference needed
|
|
44
|
+
* to show overlays and emit lifecycle events back to JS. This is transparent
|
|
45
|
+
* bridge plumbing — you never interact with RNEventBridgePlugin directly.
|
|
46
|
+
*
|
|
47
|
+
* ```ts
|
|
48
|
+
* import { DigiaMoEngagePlugin } from '@digia/moengage-plugin';
|
|
49
|
+
*
|
|
50
|
+
* await Digia.initialize({ apiKey: 'YOUR_KEY' });
|
|
51
|
+
* Digia.register(new DigiaMoEngagePlugin({ moEngage: MoEngage }));
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
54
|
+
register(plugin: DigiaPlugin): void {
|
|
55
|
+
if (this._plugins.has(plugin.identifier)) {
|
|
56
|
+
this._plugins.get(plugin.identifier)!.teardown();
|
|
57
|
+
}
|
|
58
|
+
// Wire the native bridge plugin once, before the first plugin's setup()
|
|
59
|
+
// so the delegate is ready when JS campaigns start flowing.
|
|
60
|
+
if (!this._nativeBridgeWired) {
|
|
61
|
+
nativeDigiaModule.registerBridge();
|
|
62
|
+
this._nativeBridgeWired = true;
|
|
63
|
+
}
|
|
64
|
+
plugin.setup(this);
|
|
65
|
+
this._plugins.set(plugin.identifier, plugin);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Unregister a previously registered plugin.
|
|
70
|
+
* Calls plugin.teardown() internally.
|
|
71
|
+
*/
|
|
72
|
+
unregister(pluginOrId: DigiaPlugin | string): void {
|
|
73
|
+
const id = typeof pluginOrId === 'string' ? pluginOrId : pluginOrId.identifier;
|
|
74
|
+
this._plugins.get(id)?.teardown();
|
|
75
|
+
this._plugins.delete(id);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Notify the SDK of the currently active screen name.
|
|
80
|
+
*
|
|
81
|
+
* Wire this up to your navigation library's screen-change listener
|
|
82
|
+
* (e.g. React Navigation focus events or `useNavigationContainerRef`).
|
|
83
|
+
* All registered plugins will have forwardScreen() called automatically.
|
|
84
|
+
*/
|
|
85
|
+
setCurrentScreen(name: string): void {
|
|
86
|
+
nativeDigiaModule.setCurrentScreen(name);
|
|
87
|
+
this._plugins.forEach((plugin) => plugin.forwardScreen(name));
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// ── DigiaDelegate ────────────────────────────────────────────────────────
|
|
91
|
+
// Mirrors DigiaCEPDelegate on Android.
|
|
92
|
+
// Forwards to the native DigiaCEPDelegate via the bridge.
|
|
93
|
+
|
|
94
|
+
onCampaignTriggered(payload: InAppPayload): void {
|
|
95
|
+
nativeDigiaModule.triggerCampaign(payload.id, payload.content, payload.cepContext);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
onCampaignInvalidated(campaignId: string): void {
|
|
99
|
+
nativeDigiaModule.invalidateCampaign(campaignId);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export const Digia = new DigiaClass();
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DigiaHostView
|
|
3
|
+
*
|
|
4
|
+
* A transparent React Native view that attaches the Digia Android Compose
|
|
5
|
+
* overlay layer (dialogs, bottom sheets) on top of your app's content.
|
|
6
|
+
*
|
|
7
|
+
* ─── Usage ───────────────────────────────────────────────────────────────────
|
|
8
|
+
* Place `<DigiaHostView>` at the **root** of your component tree so that
|
|
9
|
+
* Digia dialogs and bottom sheets can stack on top of all your content.
|
|
10
|
+
*
|
|
11
|
+
* ```tsx
|
|
12
|
+
* import React from 'react';
|
|
13
|
+
* import { StyleSheet, View } from 'react-native';
|
|
14
|
+
* import { DigiaHostView } from '@digia/engage-react-native';
|
|
15
|
+
*
|
|
16
|
+
* export default function App() {
|
|
17
|
+
* return (
|
|
18
|
+
* <View style={styles.root}>
|
|
19
|
+
* <DigiaHostView style={StyleSheet.absoluteFill} />
|
|
20
|
+
* {/ * your navigation / app content here * /}
|
|
21
|
+
* </View>
|
|
22
|
+
* );
|
|
23
|
+
* }
|
|
24
|
+
*
|
|
25
|
+
* const styles = StyleSheet.create({ root: { flex: 1 } });
|
|
26
|
+
* ```
|
|
27
|
+
*
|
|
28
|
+
* On Android this mounts a Jetpack Compose `DigiaHost` composable that
|
|
29
|
+
* manages dialog + bottom-sheet presentation triggered by CEP plugins.
|
|
30
|
+
* On iOS the view is a transparent no-op until iOS support is implemented.
|
|
31
|
+
* ─────────────────────────────────────────────────────────────────────────────
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
import React from 'react';
|
|
35
|
+
import {
|
|
36
|
+
Platform,
|
|
37
|
+
StyleSheet,
|
|
38
|
+
requireNativeComponent,
|
|
39
|
+
type StyleProp,
|
|
40
|
+
type ViewStyle,
|
|
41
|
+
} from 'react-native';
|
|
42
|
+
|
|
43
|
+
interface DigiaHostViewProps {
|
|
44
|
+
style?: StyleProp<ViewStyle>;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// requireNativeComponent expects a plain ViewStyle, not StyleProp.
|
|
48
|
+
interface NativeDigiaHostViewProps {
|
|
49
|
+
style?: ViewStyle;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Fabric (New Architecture) resolves view configs lazily — no UIManager
|
|
53
|
+
// guard needed. requireNativeComponent is called unconditionally on Android.
|
|
54
|
+
const NativeDigiaHostView =
|
|
55
|
+
Platform.OS === 'android'
|
|
56
|
+
? requireNativeComponent<NativeDigiaHostViewProps>('DigiaHostView')
|
|
57
|
+
: null;
|
|
58
|
+
|
|
59
|
+
// ── DigiaHostView ─────────────────────────────────────────────────────────────
|
|
60
|
+
|
|
61
|
+
export function DigiaHostView({ style }: DigiaHostViewProps) {
|
|
62
|
+
if (Platform.OS === 'android' && NativeDigiaHostView) {
|
|
63
|
+
// The native Compose DigiaHost renders dialogs / bottom sheets that
|
|
64
|
+
// float above the view hierarchy on their own — the host view only
|
|
65
|
+
// needs to be mounted in the tree, not take up any screen space.
|
|
66
|
+
return (
|
|
67
|
+
<NativeDigiaHostView
|
|
68
|
+
style={StyleSheet.flatten([styles.host, style])}
|
|
69
|
+
/>
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// iOS / other platforms: no-op, nothing to mount.
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const styles = StyleSheet.create({
|
|
78
|
+
host: {
|
|
79
|
+
width: 0,
|
|
80
|
+
height: 0,
|
|
81
|
+
overflow: 'hidden',
|
|
82
|
+
},
|
|
83
|
+
});
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DigiaSlotView
|
|
3
|
+
*
|
|
4
|
+
* A React Native view that renders inline campaign content (banners, cards,
|
|
5
|
+
* widgets) at a specific placement position inside your screen layout.
|
|
6
|
+
*
|
|
7
|
+
* On Android this mounts a Jetpack Compose `DigiaSlot` composable that
|
|
8
|
+
* observes the slot payload for the given placement key and renders the
|
|
9
|
+
* matching campaign component. On iOS it is a transparent no-op.
|
|
10
|
+
*
|
|
11
|
+
* ─── Usage ───────────────────────────────────────────────────────────────────
|
|
12
|
+
* ```tsx
|
|
13
|
+
* import { DigiaSlotView } from '@digia/engage-react-native';
|
|
14
|
+
*
|
|
15
|
+
* // Fixed height (you control the space)
|
|
16
|
+
* <DigiaSlotView
|
|
17
|
+
* placementKey="hero_banner"
|
|
18
|
+
* style={{ width: '100%', height: 200 }}
|
|
19
|
+
* />
|
|
20
|
+
*
|
|
21
|
+
* // Inside a scroll view
|
|
22
|
+
* <ScrollView>
|
|
23
|
+
* <ProductList />
|
|
24
|
+
* <DigiaSlotView
|
|
25
|
+
* placementKey="pdp_mid_banner"
|
|
26
|
+
* style={{ width: '100%', height: 120 }}
|
|
27
|
+
* />
|
|
28
|
+
* <RelatedProducts />
|
|
29
|
+
* </ScrollView>
|
|
30
|
+
* ```
|
|
31
|
+
*
|
|
32
|
+
* The `placementKey` must match the key the marketer selects when creating
|
|
33
|
+
* inline content on the Digia dashboard. The view collapses to nothing when
|
|
34
|
+
* no campaign is active for that key.
|
|
35
|
+
*
|
|
36
|
+
* ─── Sizing ──────────────────────────────────────────────────────────────────
|
|
37
|
+
* React Native's layout system controls the dimensions of this view.
|
|
38
|
+
* Provide an explicit `height` (or flex) via the `style` prop so that the
|
|
39
|
+
* native Compose layer has space to render. When no campaign is active the
|
|
40
|
+
* Compose `DigiaSlot` renders nothing inside that space.
|
|
41
|
+
* ─────────────────────────────────────────────────────────────────────────────
|
|
42
|
+
*/
|
|
43
|
+
|
|
44
|
+
import React from 'react';
|
|
45
|
+
import {
|
|
46
|
+
Platform,
|
|
47
|
+
requireNativeComponent,
|
|
48
|
+
type StyleProp,
|
|
49
|
+
type ViewStyle,
|
|
50
|
+
} from 'react-native';
|
|
51
|
+
|
|
52
|
+
interface DigiaSlotViewProps {
|
|
53
|
+
/** Placement key that links this view to a Digia dashboard slot. */
|
|
54
|
+
placementKey: string;
|
|
55
|
+
style?: StyleProp<ViewStyle>;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Fabric (New Architecture) resolves view configs lazily — no UIManager
|
|
59
|
+
// guard needed. requireNativeComponent is called unconditionally on Android.
|
|
60
|
+
const NativeDigiaSlotView =
|
|
61
|
+
Platform.OS === 'android'
|
|
62
|
+
? requireNativeComponent<DigiaSlotViewProps>('DigiaSlotView')
|
|
63
|
+
: null;
|
|
64
|
+
|
|
65
|
+
// ── DigiaSlotView ─────────────────────────────────────────────────────────────
|
|
66
|
+
|
|
67
|
+
export function DigiaSlotView({ placementKey, style }: DigiaSlotViewProps) {
|
|
68
|
+
if (Platform.OS === 'android' && NativeDigiaSlotView) {
|
|
69
|
+
return (
|
|
70
|
+
<NativeDigiaSlotView
|
|
71
|
+
placementKey={placementKey}
|
|
72
|
+
style={style}
|
|
73
|
+
/>
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// iOS / other platforms: not yet implemented — render nothing.
|
|
78
|
+
return null;
|
|
79
|
+
}
|