@amplytools/react-native-amply-sdk 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +178 -0
- package/README.md +714 -0
- package/android/build.gradle +90 -0
- package/android/consumer-rules.pro +1 -0
- package/android/gradle.properties +3 -0
- package/android/settings.gradle +9 -0
- package/android/src/main/AndroidManifest.xml +3 -0
- package/android/src/main/java/tools/amply/sdk/reactnative/AmplyModule.kt +384 -0
- package/android/src/main/java/tools/amply/sdk/reactnative/AmplyPackage.kt +39 -0
- package/android/src/main/java/tools/amply/sdk/reactnative/core/AmplyClient.kt +30 -0
- package/android/src/main/java/tools/amply/sdk/reactnative/core/DefaultAmplyClient.kt +296 -0
- package/android/src/main/java/tools/amply/sdk/reactnative/model/AmplyInitializationOptions.kt +10 -0
- package/android/src/main/java/tools/amply/sdk/reactnative/model/DataSetType.kt +42 -0
- package/android/src/main/java/tools/amply/sdk/reactnative/model/DataSetTypeMapper.kt +38 -0
- package/android/src/main/java/tools/amply/sdk/reactnative/model/DeepLinkPayload.kt +8 -0
- package/android/src/main/java/tools/amply/sdk/reactnative/model/EventEnvelope.kt +9 -0
- package/android/src/main/jni/AmplyTurboModule.cpp +29 -0
- package/android/src/main/jni/CMakeLists.txt +76 -0
- package/android/src/newarch/java/tools/amply/sdk/reactnative/NativeAmplyModuleSpec.java +75 -0
- package/android/src/newarch/jni/AmplyReactNative-generated.cpp +77 -0
- package/android/src/newarch/jni/AmplyReactNative.h +31 -0
- package/android/src/newarch/jni/CMakeLists.txt +40 -0
- package/app.plugin.js +1 -0
- package/dist/index.js +272 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +234 -0
- package/dist/index.mjs.map +1 -0
- package/dist/plugin/index.d.ts +6 -0
- package/dist/plugin/index.d.ts.map +1 -0
- package/dist/plugin/index.js +186 -0
- package/dist/plugin/index.js.map +1 -0
- package/dist/plugin/index.mjs +169 -0
- package/dist/plugin/index.mjs.map +1 -0
- package/dist/plugin/src/index.d.ts +6 -0
- package/dist/plugin/src/index.d.ts.map +1 -0
- package/dist/plugin/src/index.js +3 -0
- package/dist/plugin/src/withAmply.d.ts +30 -0
- package/dist/plugin/src/withAmply.d.ts.map +1 -0
- package/dist/plugin/src/withAmply.js +51 -0
- package/dist/plugin/withAmply.d.ts +12 -0
- package/dist/plugin/withAmply.d.ts.map +1 -0
- package/dist/src/__tests__/index.test.d.ts +2 -0
- package/dist/src/__tests__/index.test.d.ts.map +1 -0
- package/dist/src/__tests__/index.test.js +70 -0
- package/dist/src/hooks/useAmplySystemEvents.d.ts +12 -0
- package/dist/src/hooks/useAmplySystemEvents.d.ts.map +1 -0
- package/dist/src/hooks/useAmplySystemEvents.js +56 -0
- package/dist/src/index.d.ts +32 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +80 -0
- package/dist/src/nativeModule.d.ts +5 -0
- package/dist/src/nativeModule.d.ts.map +1 -0
- package/dist/src/nativeModule.js +48 -0
- package/dist/src/nativeSpecs/NativeAmplyModule.d.ts +75 -0
- package/dist/src/nativeSpecs/NativeAmplyModule.d.ts.map +1 -0
- package/dist/src/nativeSpecs/NativeAmplyModule.js +2 -0
- package/dist/src/systemEventUtils.d.ts +3 -0
- package/dist/src/systemEventUtils.d.ts.map +1 -0
- package/dist/src/systemEventUtils.js +30 -0
- package/dist/src/systemEvents.d.ts +6 -0
- package/dist/src/systemEvents.d.ts.map +1 -0
- package/dist/src/systemEvents.js +8 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/docs/ARCHITECTURE.md +1115 -0
- package/expo-module.config.json +11 -0
- package/ios/AmplyReactNative.podspec +32 -0
- package/ios/README.md +11 -0
- package/ios/Sources/AmplyReactNative/AmplyModule.mm +332 -0
- package/ios/Sources/AmplyReactNative/AmplyReactNative/AmplyReactNative-generated.mm +111 -0
- package/ios/Sources/AmplyReactNative/AmplyReactNative/AmplyReactNative.h +152 -0
- package/package.json +71 -0
- package/plugin/build/index.d.ts +5 -0
- package/plugin/build/index.js +8 -0
- package/plugin/build/withAmply.d.ts +29 -0
- package/plugin/build/withAmply.js +53 -0
- package/plugin/src/index.ts +7 -0
- package/plugin/src/withAmply.ts +68 -0
- package/plugin/tsconfig.json +8 -0
- package/plugin/tsconfig.tsbuildinfo +1 -0
- package/react-native.config.js +34 -0
- package/scripts/codegen.js +212 -0
- package/src/__tests__/index.test.ts +92 -0
- package/src/hooks/useAmplySystemEvents.ts +75 -0
- package/src/index.ts +115 -0
- package/src/nativeModule.ts +65 -0
- package/src/nativeSpecs/NativeAmplyModule.ts +80 -0
- package/src/systemEventUtils.ts +35 -0
- package/src/systemEvents.ts +13 -0
package/src/index.ts
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import getNativeModule from './nativeModule';
|
|
2
|
+
import {addSystemEventListener as addSystemEventListenerInternal} from './systemEvents';
|
|
3
|
+
export {useAmplySystemEvents} from './hooks/useAmplySystemEvents';
|
|
4
|
+
export {formatSystemEventLabel} from './systemEventUtils';
|
|
5
|
+
import type {
|
|
6
|
+
AmplyInitializationConfig,
|
|
7
|
+
DataSetSnapshot,
|
|
8
|
+
DataSetType,
|
|
9
|
+
DeepLinkEvent,
|
|
10
|
+
EventRecord,
|
|
11
|
+
TrackEventPayload,
|
|
12
|
+
} from './nativeSpecs/NativeAmplyModule';
|
|
13
|
+
|
|
14
|
+
let deepLinkRegistered = false;
|
|
15
|
+
const deepLinkSubscriptions = new Set<() => void>();
|
|
16
|
+
|
|
17
|
+
async function ensureDeepLinkRegistration(): Promise<void> {
|
|
18
|
+
if (!deepLinkRegistered) {
|
|
19
|
+
console.log('[Amply] Calling registerDeepLinkListener on native module');
|
|
20
|
+
getNativeModule().registerDeepLinkListener();
|
|
21
|
+
deepLinkRegistered = true;
|
|
22
|
+
console.log('[Amply] registerDeepLinkListener completed');
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function trackDeepLinkSubscription(subscription?: {remove?: () => void}): () => void {
|
|
27
|
+
let removed = false;
|
|
28
|
+
const unsubscribe = () => {
|
|
29
|
+
if (removed) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
removed = true;
|
|
33
|
+
subscription?.remove?.();
|
|
34
|
+
deepLinkSubscriptions.delete(unsubscribe);
|
|
35
|
+
};
|
|
36
|
+
deepLinkSubscriptions.add(unsubscribe);
|
|
37
|
+
return unsubscribe;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export async function initialize(config: AmplyInitializationConfig): Promise<void> {
|
|
41
|
+
await getNativeModule().initialize(config);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function isInitialized(): boolean {
|
|
45
|
+
return getNativeModule().isInitialized();
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export async function track(payload: TrackEventPayload): Promise<void> {
|
|
49
|
+
await getNativeModule().track(payload);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export async function getRecentEvents(limit: number): Promise<EventRecord[]> {
|
|
53
|
+
return getNativeModule().getRecentEvents(limit);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export async function getDataSetSnapshot(type: DataSetType): Promise<DataSetSnapshot> {
|
|
57
|
+
return getNativeModule().getDataSetSnapshot(type);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export async function addDeepLinkListener(
|
|
61
|
+
listener: (event: DeepLinkEvent) => void
|
|
62
|
+
): Promise<() => void> {
|
|
63
|
+
await ensureDeepLinkRegistration();
|
|
64
|
+
const subscription = getNativeModule().onDeepLink(listener);
|
|
65
|
+
return trackDeepLinkSubscription(subscription);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export async function addSystemEventListener(
|
|
69
|
+
listener: (event: EventRecord) => void
|
|
70
|
+
): Promise<() => void> {
|
|
71
|
+
return addSystemEventListenerInternal(listener);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export function removeAllListeners(): void {
|
|
75
|
+
deepLinkSubscriptions.forEach(unsubscribe => {
|
|
76
|
+
try {
|
|
77
|
+
unsubscribe();
|
|
78
|
+
} catch (error) {
|
|
79
|
+
console.warn('[Amply] Failed to remove deep link listener', error);
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
deepLinkSubscriptions.clear();
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export type {
|
|
86
|
+
AmplyInitializationConfig,
|
|
87
|
+
DataSetSnapshot,
|
|
88
|
+
DataSetType,
|
|
89
|
+
DeepLinkEvent,
|
|
90
|
+
EventRecord,
|
|
91
|
+
TrackEventPayload,
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
export function addSystemEventsListener(
|
|
95
|
+
listener: (event: EventRecord) => void,
|
|
96
|
+
): Promise<() => void> {
|
|
97
|
+
return addSystemEventListener(listener);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export const systemEvents = {
|
|
101
|
+
addListener: addSystemEventsListener,
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
export default {
|
|
105
|
+
initialize,
|
|
106
|
+
isInitialized,
|
|
107
|
+
track,
|
|
108
|
+
getRecentEvents,
|
|
109
|
+
getDataSetSnapshot,
|
|
110
|
+
addDeepLinkListener,
|
|
111
|
+
addSystemEventListener,
|
|
112
|
+
addSystemEventsListener,
|
|
113
|
+
removeAllListeners,
|
|
114
|
+
systemEvents,
|
|
115
|
+
};
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import {NativeModules, TurboModuleRegistry} from 'react-native';
|
|
2
|
+
import type {Spec} from './nativeSpecs/NativeAmplyModule';
|
|
3
|
+
|
|
4
|
+
const MODULE_NAME = 'Amply';
|
|
5
|
+
|
|
6
|
+
let cachedModule: Spec | null = null;
|
|
7
|
+
let attemptedTurboLookup = false;
|
|
8
|
+
let resolvedTurboModule: Spec | null = null;
|
|
9
|
+
|
|
10
|
+
function loadModule(): Spec | null {
|
|
11
|
+
const globalWithTurbo = globalThis as typeof globalThis & {
|
|
12
|
+
__turboModuleProxy?: unknown;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
if (globalWithTurbo.__turboModuleProxy != null) {
|
|
16
|
+
if (!attemptedTurboLookup) {
|
|
17
|
+
attemptedTurboLookup = true;
|
|
18
|
+
try {
|
|
19
|
+
resolvedTurboModule = TurboModuleRegistry.getEnforcing<Spec>(MODULE_NAME);
|
|
20
|
+
} catch (error) {
|
|
21
|
+
resolvedTurboModule = null;
|
|
22
|
+
if (__DEV__) {
|
|
23
|
+
console.warn(
|
|
24
|
+
"[Amply] TurboModule lookup failed; falling back to legacy NativeModules. " +
|
|
25
|
+
(error instanceof Error ? error.message : String(error))
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
if (resolvedTurboModule) {
|
|
31
|
+
return resolvedTurboModule;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const legacyModule = NativeModules[MODULE_NAME] as Spec | undefined;
|
|
36
|
+
if (legacyModule) {
|
|
37
|
+
return legacyModule;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function getNativeModule(): Spec {
|
|
44
|
+
if (cachedModule) {
|
|
45
|
+
return cachedModule;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const module = loadModule();
|
|
49
|
+
if (!module) {
|
|
50
|
+
throw new Error(
|
|
51
|
+
`Amply native module '${MODULE_NAME}' not found. ` +
|
|
52
|
+
'Ensure the module is properly linked and new architecture is enabled.'
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
cachedModule = module;
|
|
57
|
+
return cachedModule;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Testing hook to override the resolved native module.
|
|
61
|
+
export function __setNativeModule(mock: Spec | null): void {
|
|
62
|
+
cachedModule = mock;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export default getNativeModule;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import type {TurboModule} from 'react-native';
|
|
2
|
+
import {TurboModuleRegistry} from 'react-native';
|
|
3
|
+
import type {EventEmitter} from 'react-native/Libraries/Types/CodegenTypes';
|
|
4
|
+
|
|
5
|
+
type JsonMap = {[key: string]: unknown};
|
|
6
|
+
|
|
7
|
+
export type AmplyInitializationConfig = {
|
|
8
|
+
appId: string;
|
|
9
|
+
apiKeyPublic: string;
|
|
10
|
+
apiKeySecret?: string | null;
|
|
11
|
+
endpoint?: string | null;
|
|
12
|
+
datasetPrefetch?: DataSetType[] | null;
|
|
13
|
+
defaultConfig?: string | null;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export type EventType = 'custom' | 'system';
|
|
17
|
+
|
|
18
|
+
export type TrackEventPayload = {
|
|
19
|
+
name: string;
|
|
20
|
+
properties?: JsonMap | null;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export type EventRecord = {
|
|
24
|
+
id?: string | null;
|
|
25
|
+
name: string;
|
|
26
|
+
type: EventType;
|
|
27
|
+
timestamp: number;
|
|
28
|
+
properties: JsonMap;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export type SystemEventPayload = EventRecord;
|
|
32
|
+
|
|
33
|
+
export type TriggeredEventCountStrategy = 'total' | 'session' | 'user';
|
|
34
|
+
|
|
35
|
+
export type TriggeredEventParam = {
|
|
36
|
+
name: string;
|
|
37
|
+
value: unknown;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export type TriggeredEventData = {
|
|
41
|
+
countStrategy: TriggeredEventCountStrategy;
|
|
42
|
+
params: TriggeredEventParam[];
|
|
43
|
+
eventName?: string | null;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export type EventsDataSetEvent = {
|
|
47
|
+
name: string;
|
|
48
|
+
type: EventType;
|
|
49
|
+
params: TriggeredEventParam[];
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export type DataSetType =
|
|
53
|
+
| {kind: '@device'}
|
|
54
|
+
| {kind: '@user'}
|
|
55
|
+
| {kind: '@session'}
|
|
56
|
+
| {kind: '@triggeredEvent'; data: TriggeredEventData}
|
|
57
|
+
| {kind: '@events'; data: EventsDataSetEvent[]};
|
|
58
|
+
|
|
59
|
+
export type DataSetSnapshot = JsonMap;
|
|
60
|
+
|
|
61
|
+
export type DeepLinkEvent = {
|
|
62
|
+
url: string;
|
|
63
|
+
info: JsonMap;
|
|
64
|
+
consumed: boolean;
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
export interface Spec extends TurboModule {
|
|
68
|
+
initialize(config: AmplyInitializationConfig): Promise<void>;
|
|
69
|
+
isInitialized(): boolean;
|
|
70
|
+
track(payload: TrackEventPayload): Promise<void>;
|
|
71
|
+
getRecentEvents(limit: number): Promise<EventRecord[]>;
|
|
72
|
+
getDataSetSnapshot(type: DataSetType): Promise<DataSetSnapshot>;
|
|
73
|
+
registerDeepLinkListener(): void;
|
|
74
|
+
readonly onSystemEvent: EventEmitter<SystemEventPayload>;
|
|
75
|
+
readonly onDeepLink: EventEmitter<DeepLinkEvent>;
|
|
76
|
+
addListener(eventName: string): void;
|
|
77
|
+
removeListeners(count: number): void;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export default TurboModuleRegistry.getEnforcing<Spec>('Amply');
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type {EventRecord} from './nativeSpecs/NativeAmplyModule';
|
|
2
|
+
|
|
3
|
+
const DEFAULT_LABELS: Record<string, string> = {
|
|
4
|
+
SdkInitialized: 'SDK initialized',
|
|
5
|
+
ConfigFetchStarted: 'Config fetch started',
|
|
6
|
+
ConfigFetchFinished: 'Config fetch finished',
|
|
7
|
+
SessionStarted: 'Session started',
|
|
8
|
+
SessionFinished: 'Session finished',
|
|
9
|
+
CampaignShown: 'Campaign shown',
|
|
10
|
+
EventTriggered: 'Event triggered',
|
|
11
|
+
CampaignStarted: 'Campaign processing started',
|
|
12
|
+
CampaignFinished: 'Campaign finished',
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export function formatSystemEventLabel(event: EventRecord): string {
|
|
16
|
+
if (event.name === 'CampaignShown') {
|
|
17
|
+
const campaignId = event.properties.campaignId as string | undefined;
|
|
18
|
+
const source = event.properties.source as string | undefined;
|
|
19
|
+
return `Campaign shown${campaignId ? ` (${campaignId})` : ''}${
|
|
20
|
+
source ? ` via ${source}` : ''
|
|
21
|
+
}`;
|
|
22
|
+
}
|
|
23
|
+
if (event.name === 'EventTriggered') {
|
|
24
|
+
const source = event.properties.sourceEvent as string | undefined;
|
|
25
|
+
return source ? `Event triggered (${source})` : DEFAULT_LABELS[event.name] ?? event.name;
|
|
26
|
+
}
|
|
27
|
+
if (event.name === 'ConfigFetchFinished') {
|
|
28
|
+
const success = event.properties.success as boolean | undefined;
|
|
29
|
+
const campaignCount = event.properties.campaignCount as number | undefined;
|
|
30
|
+
const countLabel =
|
|
31
|
+
typeof campaignCount === 'number' ? ` (${campaignCount} campaigns)` : '';
|
|
32
|
+
return success === false ? 'Config fetch failed' : `Config fetch finished${countLabel}`;
|
|
33
|
+
}
|
|
34
|
+
return DEFAULT_LABELS[event.name] ?? `System event ${event.name}`;
|
|
35
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import getNativeModule from './nativeModule';
|
|
2
|
+
import type {SystemEventPayload} from './nativeSpecs/NativeAmplyModule';
|
|
3
|
+
|
|
4
|
+
export async function addSystemEventListener(
|
|
5
|
+
listener: (event: SystemEventPayload) => void,
|
|
6
|
+
): Promise<() => void> {
|
|
7
|
+
const subscription = getNativeModule().onSystemEvent(listener);
|
|
8
|
+
return () => subscription?.remove?.();
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const systemEvents = {
|
|
12
|
+
addListener: addSystemEventListener,
|
|
13
|
+
};
|