Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 53 additions & 53 deletions example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1893,9 +1893,9 @@ SPEC CHECKSUMS:
DatadogInternal: a514ba01c9eb99dbe1ddd4452e218706bb0ddc2b
DatadogLogs: 9352c58e4ab4a88f0ed7c20f27dc8d24442acc5e
DatadogRUM: ab979c800d3fb7d7b2ff364a11d137b6a4be6831
DatadogSDKReactNative: 25d1ef8cf3b8a9d5f1d2ceb311460ba99515f881
DatadogSDKReactNativeSessionReplay: ce29bf5592cd01f56ffc92d1e905c37542ecb3f9
DatadogSDKReactNativeWebView: 1e5f4236da00714f72a7fb97e3fbace23df92017
DatadogSDKReactNative: 9aa3b8303f63e169e2d6b63ffe9e1d05f11ebf5a
DatadogSDKReactNativeSessionReplay: 861cfbfd31726df6445f0507ed2a5cc8ef3e9ca7
DatadogSDKReactNativeWebView: 3e3375b728c767db90ddd844bb8cbb540f7d30f3
DatadogSessionReplay: 84f73417237cb02ad93889cd0a2fb564bce2ccab
DatadogTrace: 23df8545911d219d4c15446a4c6c04862ff76175
DatadogWebViewTracking: e88b8057eb5ff06a68baf232ae37637b8bb7518b
Expand All @@ -1907,69 +1907,69 @@ SPEC CHECKSUMS:
HMSegmentedControl: 34c1f54d822d8308e7b24f5d901ec674dfa31352
OpenTelemetrySwiftApi: aaee576ed961e0c348af78df58b61300e95bd104
PLCrashReporter: db59ef96fa3d25f3650040d02ec2798cffee75f2
RCT-Folly: 34124ae2e667a0e5f0ea378db071d27548124321
RCT-Folly: 4464f4d875961fce86008d45f4ecf6cef6de0740
RCTDeprecation: 726d24248aeab6d7180dac71a936bbca6a994ed1
RCTRequired: a94e7febda6db0345d207e854323c37e3a31d93b
RCTTypeSafety: 28e24a6e44f5cbf912c66dde6ab7e07d1059a205
React: c2830fa483b0334bda284e46a8579ebbe0c5447e
React-callinvoker: 4aecde929540c26b841a4493f70ebf6016691eb8
React-Core: 32a581847d74ce9b5f51d9d11a4e4d132ad61553
React-CoreModules: f53e0674e1747fa41c83bc970e82add97b14ad87
React-cxxreact: 86f3b1692081fd954a0cb27cc90d14674645b64b
React-Core: 9c059899f00d46b5cec3ed79251f77d9c469553d
React-CoreModules: 9fac2d31803c0ed03e4ddaa17f1481714f8633a5
React-cxxreact: a979810a3ca4045ceb09407a17563046a7f71494
React-debug: 3d21f69d8def0656f8b8ec25c0f05954f4d862c5
React-defaultsnativemodule: 2ed121c5a1edeab09cff382b8d9b538260f07848
React-domnativemodule: 4393dd5dd7e13dbe42e69ebc791064a616990f91
React-Fabric: cbf38ceefb1ac6236897abdb538130228e126695
React-FabricComponents: dd4b01c4a60920d8dc15f3b5594c6fe9e7648a38
React-FabricImage: 8b13aedfbd20f349b9b3314baf993c71c02995d9
React-defaultsnativemodule: 2fa2bdb7bd03ff9764facc04aa8520ebf14febae
React-domnativemodule: 986e6fe7569e1383dce452a7b013b6c843a752df
React-Fabric: 3bc7be9e3a6b7581fc828dc2aa041e107fc8ffb8
React-FabricComponents: 668e0cb02344c2942e4c8921a643648faa6dc364
React-FabricImage: 3f44dd25a2b020ed5215d4438a1bb1f3461cd4f1
React-featureflags: ee1abd6f71555604a36cda6476e3c502ca9a48e5
React-featureflagsnativemodule: 87b58caf3cd8eca1e53179453789def019af2a65
React-graphics: f5c4cf3abc5aa083e28fe7a866bd95fb3bbbc1e0
React-hermes: cad69ee9a53870cc38e5386889aa7ea81c75b6a1
React-idlecallbacksnativemodule: 445390be0f533797ace18c419eb57110dbfe90d6
React-ImageManager: cb78d7a24f45f8f9a5a1640b52fce4c9f637f98d
React-jserrorhandler: dfe9b96e99a93d4f4858bad66d5bc4813a87a21a
React-jsi: bc1f6073e203fb540edd6d26f926ad041809b443
React-jsiexecutor: 1e8fc70dd9614c3e9d5c3c876b2ea3cd1d931ee4
React-jsinspector: 7544a20e9beac390f1b65d9f0040d97cd55dc198
React-jsitracing: cac972ccc097db399df8044e49add8e5b25cb34a
React-logger: 80d87daf2f98bf95ab668b79062c1e0c3f0c2f8a
React-Mapbuffer: acffb35a53a5f474ede09f082ac609b41aafab2e
React-microtasksnativemodule: 71ca9282bce93b319218d75362c0d646b376eb43
react-native-crash-tester: 48bde9d6f5256c61ef2e0c52dfc74256b26e55eb
react-native-safe-area-context: e134b241010ebe2aacdcea013565963d13826faa
react-native-webview: f38fd87322055d2ce09058cf19f50f708fb174da
React-featureflagsnativemodule: 7ccc0cd666c2a6257401dceb7920818ac2b42803
React-graphics: d7dd9c8d75cad5af19e19911fa370f78f2febd96
React-hermes: 2069b08e965e48b7f8aa2c0ca0a2f383349ed55d
React-idlecallbacksnativemodule: e211b2099b6dced97959cb58257bab2b2de4d7ef
React-ImageManager: ab7a7d17dd0ff1ef1d4e1e88197d1119da9957ce
React-jserrorhandler: d9e867bb83b868472f3f7601883f0403b3e3942d
React-jsi: d68f1d516e5120a510afe356647a6a1e1f98f2db
React-jsiexecutor: 6366a08a0fc01c9b65736f8deacd47c4a397912a
React-jsinspector: 0ac947411f0c73b34908800cc7a6a31d8f93e1a8
React-jsitracing: 0e8c0aadb1fcec6b1e4f2a66ee3b0da80f0f8615
React-logger: d79b704bf215af194f5213a6b7deec50ba8e6a9b
React-Mapbuffer: b982d5bba94a8bc073bda48f0d27c9b28417fae3
React-microtasksnativemodule: 2b73e68f0462f3175f98782db08896f8501afd20
react-native-crash-tester: 3ffaa64141427ca362079cb53559fe9a532487ae
react-native-safe-area-context: 04803a01f39f31cc6605a5531280b477b48f8a88
react-native-webview: 4cec209f46fca53257d987ac16a6a63974417f8b
React-nativeconfig: 8c83d992b9cc7d75b5abe262069eaeea4349f794
React-NativeModulesApple: 97f606f09fd9840b3868333984d6a0e7bcc425b5
React-NativeModulesApple: 9f7920224a3b0c7d04d77990067ded14cee3c614
React-perflogger: 59e1a3182dca2cee7b9f1f7aab204018d46d1914
React-performancetimeline: 3e3f5c5576fe1cc2dd5fcfb1ae2046d5dceda3d7
React-performancetimeline: a9d05533ff834c6aa1f532e05e571f3fd2e3c1ed
React-RCTActionSheet: d80e68d3baa163e4012a47c1f42ddd8bcd9672cc
React-RCTAnimation: 051f0781709c5ed80ba8aa2b421dfb1d72a03162
React-RCTAppDelegate: 106d225d076988b06aa4834e68d1ab754f40cacf
React-RCTBlob: 895eaf8bca2e76ee1c95b479235c6ccebe586fc6
React-RCTFabric: 8d01df202ee9e933f9b5dd44b72ec89a7ac6ee01
React-RCTImage: b73149c0cd54b641dba2d6250aaf168fee784d9f
React-RCTLinking: 23e519712285427e50372fbc6e0265d422abf462
React-RCTNetwork: a5d06d122588031989115f293654b13353753630
React-RCTSettings: 87d03b5d94e6eadd1e8c1d16a62f790751aafb55
React-RCTText: 75e9dd39684f4bcd1836134ac2348efaca7437b3
React-RCTVibration: 033c161fe875e6fa096d0d9733c2e2501682e3d4
React-RCTAnimation: bde981f6bd7f8493696564da9b3bd05721d3b3cc
React-RCTAppDelegate: 0176615c51476c88212bf3edbafb840d39ea7631
React-RCTBlob: 520a0382bf8e89b9153d60e3c6293e51615834e9
React-RCTFabric: c9da097b19b30017a99498b8c66a69c72f3ce689
React-RCTImage: 90448d2882464af6015ed57c98f463f8748be465
React-RCTLinking: 1bd95d0a704c271d21d758e0f0388cced768d77d
React-RCTNetwork: 218af6e63eb9b47935cc5a775b7a1396cf10ff91
React-RCTSettings: e10b8e42b0fce8a70fbf169de32a2ae03243ef6b
React-RCTText: e7bf9f4997a1a0b45c052d4ad9a0fe653061cf29
React-RCTVibration: 5b70b7f11e48d1c57e0d4832c2097478adbabe93
React-rendererconsistency: f620c6e003e3c4593e6349d8242b8aeb3d4633f0
React-rendererdebug: 5be7b834677b2a7a263f4d2545f0d4966cafad82
React-rendererdebug: e697680f4dd117becc5daf9ea9800067abcee91c
React-rncore: c22bd84cc2f38947f0414fab6646db22ff4f80cd
React-RuntimeApple: 71160e6c02efa07d198b84ef5c3a52a7d9d0399d
React-RuntimeCore: f88f79ec995c12af56a265d7505c7630733d9d82
React-RuntimeApple: de0976836b90b484305638616898cbc665c67c13
React-RuntimeCore: 3c4a5aa63d9e7a3c17b7fb23f32a72a8bcfccf57
React-runtimeexecutor: ea90d8e3a9e0f4326939858dafc6ab17c031a5d3
React-RuntimeHermes: 49f86328914021f50fd5a5b9756685f5f6d8b4da
React-runtimescheduler: fed70991b942c6df752a59a22081e45fc811b11c
React-utils: 02526ea15628a768b8db9517b6017a1785c734d2
ReactCodegen: 8b5341ecb61898b8bd40a73ebc443c6bf2d14423
ReactCommon: 36d48f542b4010786d6b2bcee615fe5f906b7105
ReactNativeNavigation: 81b3f87d96a0b963f8bdf1f6fb6ac2abe9f653d1
RNCAsyncStorage: b9f5f78da5d16a853fe3dc22e8268d932fc45a83
RNCMaskedView: 4c5ee1c8667d56077246cc6d1977f77393923560
RNGestureHandler: fc491c834d09b0538618a3f328ab75fe8f90f5b4
RNScreens: df5b744737987bdfe5f04e05579b53ce1bcdbfa9
React-RuntimeHermes: c6b0afdf1f493621214eeb6517fb859ce7b21b81
React-runtimescheduler: 84f0d876d254bce6917a277b3930eb9bc29df6c7
React-utils: cbe8b8b3d7b2ac282e018e46f0e7b25cdc87c5a0
ReactCodegen: 4bcb34e6b5ebf6eef5cee34f55aa39991ea1c1f1
ReactCommon: 6a952e50c2a4b694731d7682aaa6c79bc156e4ad
ReactNativeNavigation: 84cfcceb62947491beda20b96c5999c15ff5b959
RNCAsyncStorage: addfc2cb6511dbe199c56c6b26ede383b6c38919
RNCMaskedView: 0e1bc4bfa8365eba5fbbb71e07fbdc0555249489
RNGestureHandler: 2e4971181218718ab9c5871ea5ef855ec5c389fe
RNScreens: b51f1a8be0dd7bb470b757f6cca8ba878acb2000
SocketRocket: abac6f5de4d4d62d24e11868d7a2f427e0ef940d
Yoga: 055f92ad73f8c8600a93f0e25ac0b2344c3b07e6

Expand Down
1 change: 1 addition & 0 deletions example/src/screens/MainScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { APPLICATION_KEY, API_KEY } from '../../src/ddCredentials';
import { DdSdkReactNative, TrackingConsent } from '@datadog/mobile-react-native';
import { getTrackingConsent, saveTrackingConsent } from '../utils';
import { ConsentModal } from '../components/consent';
import { DdRum } from '../../../packages/core/src/rum/DdRum';

const axios = require('../axiosConfig');

Expand Down
8 changes: 7 additions & 1 deletion packages/core/__mocks__/react-native.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,13 @@ actualRN.NativeModules.DdSdk = {
) as jest.MockedFunction<DdNativeSdkType['consumeWebviewEvent']>,
clearAllData: jest.fn().mockImplementation(
() => new Promise<void>(resolve => resolve())
) as jest.MockedFunction<DdNativeSdkType['clearAllData']>
) as jest.MockedFunction<DdNativeSdkType['clearAllData']>,
Comment thread
marco-saia-datadog marked this conversation as resolved.
addListener: jest.fn().mockImplementation((_: string) => {
/* empty */
}) as jest.MockedFunction<DdNativeSdkType['addListener']>,
removeListeners: jest.fn().mockImplementation((_: number) => {
/* empty */
}) as jest.MockedFunction<DdNativeSdkType['removeListeners']>
};

actualRN.NativeModules.DdLogs = {
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/DdSdkReactNative.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import { DdRum } from './rum/DdRum';
import { DdRumErrorTracking } from './rum/instrumentation/DdRumErrorTracking';
import { DdRumUserInteractionTracking } from './rum/instrumentation/interactionTracking/DdRumUserInteractionTracking';
import { DdRumResourceTracking } from './rum/instrumentation/resourceTracking/DdRumResourceTracking';
import { registerRumSessionIdListener } from './rum/sessionId/sessionIdHelper';
import { AttributesSingleton } from './sdk/AttributesSingleton/AttributesSingleton';
import type { Attributes } from './sdk/AttributesSingleton/types';
import { BufferSingleton } from './sdk/DatadogProvider/Buffer/BufferSingleton';
Expand Down Expand Up @@ -75,6 +76,7 @@ export class DdSdkReactNative {
initializationModeForTelemetry: InitializationModeForTelemetry;
}
): Promise<void> => {
registerRumSessionIdListener();
if (GlobalState.instance.isInitialized) {
InternalLog.log(
"Can't initialize Datadog, SDK was already initialized",
Expand Down
45 changes: 42 additions & 3 deletions packages/core/src/__tests__/DdSdkReactNative.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { DdRum } from '../rum/DdRum';
import { DdRumErrorTracking } from '../rum/instrumentation/DdRumErrorTracking';
import { DdRumUserInteractionTracking } from '../rum/instrumentation/interactionTracking/DdRumUserInteractionTracking';
import { DdRumResourceTracking } from '../rum/instrumentation/resourceTracking/DdRumResourceTracking';
import { registerRumSessionIdListener } from '../rum/sessionId/sessionIdHelper';
import { ErrorSource, PropagatorType, RumActionType } from '../rum/types';
import { AttributesSingleton } from '../sdk/AttributesSingleton/AttributesSingleton';
import { DdSdk } from '../sdk/DdSdk';
Expand Down Expand Up @@ -57,6 +58,15 @@ jest.mock('../rum/instrumentation/DdRumErrorTracking', () => {
};
});

jest.mock('../rum/sessionId/sessionIdHelper', () => {
return {
registerRumSessionIdListener: jest.fn(),
removeRumSessionIdListeners: jest.fn(),
getCachedRumSessionId: jest.fn(),
setCachedRumSessionId: jest.fn()
};
});

beforeEach(async () => {
GlobalState.instance.isInitialized = false;
DdSdkReactNative['wasAutoInstrumented'] = false;
Expand All @@ -78,6 +88,10 @@ beforeEach(async () => {

UserInfoSingleton.reset();
AttributesSingleton.reset();

(registerRumSessionIdListener as jest.MockedFunction<
() => void
>).mockClear();
});

describe('DdSdkReactNative', () => {
Expand Down Expand Up @@ -156,11 +170,13 @@ describe('DdSdkReactNative', () => {
});

expect(GlobalState.instance.isInitialized).toBe(false);
expect(DdRumUserInteractionTracking.startTracking).toBeCalledTimes(
expect(
DdRumUserInteractionTracking.startTracking
).toHaveBeenCalledTimes(0);
expect(DdRumResourceTracking.startTracking).toHaveBeenCalledTimes(
0
);
expect(DdRumResourceTracking.startTracking).toBeCalledTimes(0);
expect(DdRumErrorTracking.startTracking).toBeCalledTimes(0);
expect(DdRumErrorTracking.startTracking).toHaveBeenCalledTimes(0);
});

it('initializes the SDK when initialize { explicit tracking consent }', async () => {
Expand Down Expand Up @@ -1017,6 +1033,29 @@ describe('DdSdkReactNative', () => {
logs: 'https://logs.example.com/'
});
});

it('registers RUM Session ID listener when initialize', async () => {
// GIVEN
const fakeAppId = '1';
const fakeClientToken = '2';
const fakeEnvName = 'env';
const configuration = new DdSdkReactNativeConfiguration(
fakeClientToken,
fakeEnvName,
fakeAppId,
false,
false,
true
);

NativeModules.DdSdk.initialize.mockResolvedValue(null);

// WHEN
await DdSdkReactNative.initialize(configuration);

// THEN
expect(registerRumSessionIdListener).toHaveBeenCalledTimes(1);
});
});

describe('setAttributes', () => {
Expand Down
34 changes: 13 additions & 21 deletions packages/core/src/rum/DdRum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
* Copyright 2016-Present Datadog, Inc.
*/
import type { GestureResponderEvent } from 'react-native';
import { NativeEventEmitter, NativeModules, Platform } from 'react-native';

import { InternalLog } from '../InternalLog';
import { SdkVerbosity } from '../SdkVerbosity';
Expand All @@ -30,6 +29,10 @@ import {
getTracingContext,
getTracingContextForPropagators
} from './instrumentation/resourceTracking/distributedTracing/distributedTracingHeaders';
import {
getCachedRumSessionId,
setCachedRumSessionId
} from './sessionId/sessionIdHelper';
import type {
ErrorSource,
DdRumType,
Expand All @@ -41,11 +44,6 @@ import type {

const generateEmptyPromise = () => new Promise<void>(resolve => resolve());

const nativeEventEmitter =
Platform.OS === 'android'
? new NativeEventEmitter()
: new NativeEventEmitter(NativeModules.DdSdk);

class DdRumWrapper implements DdRumType {
// eslint-disable-next-line global-require, @typescript-eslint/no-var-requires
private nativeRum: DdNativeRumType = require('../specs/NativeDdRum')
Expand All @@ -56,19 +54,10 @@ class DdRumWrapper implements DdRumType {
private actionEventMapper = generateActionEventMapper(undefined);
private timeProvider: TimeProvider = new DefaultTimeProvider();

private currentRumSessionId: string | null = null;

constructor() {
// listen to future events
nativeEventEmitter.addListener('RumSessionStarted', (e: Event) => {
const field = 'sessionId';
const sessionId = e[field as keyof Event] as string | null;
this.currentRumSessionId = sessionId;
});

// fetch the current session if any (because we might have missed the first RumSessionStarted event)
// Fetch the current session if any (because we might have missed the first RumSessionStarted event)
this.getCurrentSessionId().then(value => {
this.currentRumSessionId = value ?? null;
setCachedRumSessionId(value ?? null);
});
}

Expand Down Expand Up @@ -334,11 +323,14 @@ class DdRumWrapper implements DdRumType {
if (!GlobalState.instance.isInitialized) {
return undefined;
}
return this.nativeRum.getCurrentSessionId();
const sessionId = await this.nativeRum.getCurrentSessionId();
setCachedRumSessionId(sessionId ?? null);

return sessionId;
}

getCachedSessionId(): string | null {
return this.currentRumSessionId;
return getCachedRumSessionId();
}

getTracingContext = (
Expand All @@ -350,7 +342,7 @@ class DdRumWrapper implements DdRumType {
url,
tracingSamplingRate,
firstPartyHosts,
this.currentRumSessionId
getCachedRumSessionId()
);
};

Expand All @@ -361,7 +353,7 @@ class DdRumWrapper implements DdRumType {
return getTracingContextForPropagators(
propagators,
tracingSamplingRate,
this.currentRumSessionId
getCachedRumSessionId()
);
};

Expand Down
Loading