Skip to content
Draft
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
9 changes: 8 additions & 1 deletion packages/core/src/DdAttributes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,12 @@ export const DdAttributes = {
* Custom fingerprint to an error.
* Expects {@link String} value.
*/
errorFingerprint: '_dd.error.fingerprint'
errorFingerprint: '_dd.error.fingerprint',

/**
* Debug ID attached to a log or a RUM event.
* The Debug ID establishes a unique connection between a bundle and its corresponding sourcemap.
* Expects {@link String} value.
*/
debugId: '_dd.debug_id'
};
21 changes: 11 additions & 10 deletions packages/core/src/DdSdkReactNative.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ import { AttributesSingleton } from './sdk/AttributesSingleton/AttributesSinglet
import type { Attributes } from './sdk/AttributesSingleton/types';
import { registerNativeBridge } from './sdk/DatadogInternalBridge/DdSdkInternalNativeBridge';
import { BufferSingleton } from './sdk/DatadogProvider/Buffer/BufferSingleton';
import { DdSdk } from './sdk/DdSdk';
import { NativeDdSdk } from './sdk/DdSdkInternal';
import { FileBasedConfiguration } from './sdk/FileBasedConfiguration/FileBasedConfiguration';
import { GlobalState } from './sdk/GlobalState/GlobalState';
import { UserInfoSingleton } from './sdk/UserInfoSingleton/UserInfoSingleton';
Expand Down Expand Up @@ -83,7 +83,7 @@ export class DdSdkReactNative {
SdkVerbosity.WARN
);
if (!__DEV__) {
DdSdk.telemetryDebug(
NativeDdSdk.telemetryDebug(
'RN SDK was already initialized in javascript'
);
}
Expand All @@ -94,7 +94,7 @@ export class DdSdkReactNative {

registerNativeBridge();

await DdSdk.initialize(
await NativeDdSdk.initialize(
DdSdkReactNative.buildConfiguration(configuration, params)
);

Expand Down Expand Up @@ -187,7 +187,7 @@ export class DdSdkReactNative {
`Setting attributes ${JSON.stringify(attributes)}`,
SdkVerbosity.DEBUG
);
await DdSdk.setAttributes(attributes);
await NativeDdSdk.setAttributes(attributes);
AttributesSingleton.getInstance().setAttributes(attributes);
};

Expand All @@ -210,7 +210,7 @@ export class DdSdkReactNative {
SdkVerbosity.DEBUG
);

await DdSdk.setUserInfo(userInfo);
await NativeDdSdk.setUserInfo(userInfo);
UserInfoSingleton.getInstance().setUserInfo(userInfo);
};

Expand All @@ -220,7 +220,7 @@ export class DdSdkReactNative {
*/
static clearUserInfo = async (): Promise<void> => {
InternalLog.log('Clearing user info', SdkVerbosity.DEBUG);
await DdSdk.clearUserInfo();
await NativeDdSdk.clearUserInfo();
UserInfoSingleton.getInstance().clearUserInfo();
};

Expand Down Expand Up @@ -254,7 +254,7 @@ export class DdSdkReactNative {
}
};

await DdSdk.addUserExtraInfo(extraUserInfo);
await NativeDdSdk.addUserExtraInfo(extraUserInfo);
UserInfoSingleton.getInstance().setUserInfo(updatedUserInfo);
};

Expand All @@ -265,7 +265,7 @@ export class DdSdkReactNative {
*/
static setTrackingConsent = (consent: TrackingConsent): Promise<void> => {
InternalLog.log(`Setting consent ${consent}`, SdkVerbosity.DEBUG);
return DdSdk.setTrackingConsent(consent);
return NativeDdSdk.setTrackingConsent(consent);
};

/**
Expand All @@ -274,7 +274,7 @@ export class DdSdkReactNative {
*/
static clearAllData = (): Promise<void> => {
InternalLog.log('Clearing all data', SdkVerbosity.DEBUG);
return DdSdk.clearAllData();
return NativeDdSdk.clearAllData();
};

private static buildConfiguration = (
Expand Down Expand Up @@ -356,7 +356,8 @@ export class DdSdkReactNative {
configuration.resourceTracingSamplingRate,
configuration.trackWatchdogTerminations,
configuration.batchProcessingLevel,
configuration.initialResourceThreshold
configuration.initialResourceThreshold,
configuration.attributeEncoders
);
};

Expand Down
17 changes: 17 additions & 0 deletions packages/core/src/DdSdkReactNativeConfiguration.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import type { ErrorEventMapper } from './rum/eventMappers/errorEventMapper';
import type { ResourceEventMapper } from './rum/eventMappers/resourceEventMapper';
import type { FirstPartyHost } from './rum/types';
import { PropagatorType } from './rum/types';
import type { AttributeEncoder } from './sdk/AttributesEncoding/types';
import type { LogEventMapper } from './types';

export enum VitalsUpdateFrequency {
Expand Down Expand Up @@ -322,6 +323,22 @@ export class DdSdkReactNativeConfiguration {
*/
public initialResourceThreshold?: number;

/**
* Optional list of custom encoders for attributes.
*
* Each encoder defines how to detect (`check`) and transform (`encode`)
* values of a specific type that is not handled by the built-in encoders
* (e.g., domain-specific objects, custom classes).
*
* These encoders are applied before the built-in ones. If an encoder
* successfully `check` a value, its `encode` result will be used.
*
* Example use cases:
* - Serializing a custom `UUID` class into a string
* - Handling third-party library objects that are not JSON-serializable
*/
public attributeEncoders: AttributeEncoder<any>[] = [];

/**
* Determines whether the SDK should track application termination by the watchdog on iOS. Default: `false`.
*/
Expand Down
48 changes: 31 additions & 17 deletions packages/core/src/__tests__/DdSdkReactNative.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { DdRumUserInteractionTracking } from '../rum/instrumentation/interaction
import { DdRumResourceTracking } from '../rum/instrumentation/resourceTracking/DdRumResourceTracking';
import { PropagatorType, RumActionType } from '../rum/types';
import { AttributesSingleton } from '../sdk/AttributesSingleton/AttributesSingleton';
import { DdSdk } from '../sdk/DdSdk';
import { NativeDdSdk } from '../sdk/DdSdkInternal';
import { GlobalState } from '../sdk/GlobalState/GlobalState';
import { UserInfoSingleton } from '../sdk/UserInfoSingleton/UserInfoSingleton';
import { ErrorSource } from '../types';
Expand Down Expand Up @@ -428,7 +428,9 @@ describe('DdSdkReactNative', () => {
const ddSdkConfiguration = NativeModules.DdSdk.initialize.mock
.calls[0][0] as DdSdkConfiguration;
expect(
ddSdkConfiguration.additionalConfiguration['_dd.version']
(ddSdkConfiguration.additionalConfiguration as {
'_dd.version': string;
})['_dd.version']
).toBe('2.0.0');
});

Expand All @@ -451,10 +453,14 @@ describe('DdSdkReactNative', () => {
const ddSdkConfiguration = NativeModules.DdSdk.initialize.mock
.calls[0][0] as DdSdkConfiguration;
expect(
ddSdkConfiguration.additionalConfiguration['_dd.version']
(ddSdkConfiguration.additionalConfiguration as {
'_dd.version': string;
})['_dd.version']
).toBeUndefined();
expect(
ddSdkConfiguration.additionalConfiguration['_dd.version_suffix']
(ddSdkConfiguration.additionalConfiguration as {
'_dd.version_suffix': string;
})['_dd.version_suffix']
).toBe('-codepush-3');
});

Expand All @@ -478,10 +484,14 @@ describe('DdSdkReactNative', () => {
const ddSdkConfiguration = NativeModules.DdSdk.initialize.mock
.calls[0][0] as DdSdkConfiguration;
expect(
ddSdkConfiguration.additionalConfiguration['_dd.version']
(ddSdkConfiguration.additionalConfiguration as {
'_dd.version': string;
})['_dd.version']
).toBe('2.0.0-codepush-3');
expect(
ddSdkConfiguration.additionalConfiguration['_dd.version_suffix']
(ddSdkConfiguration.additionalConfiguration as {
'_dd.version_suffix': string;
})['_dd.version_suffix']
).toBeUndefined();
});

Expand Down Expand Up @@ -1055,8 +1065,8 @@ describe('DdSdkReactNative', () => {
await DdSdkReactNative.setAttributes(attributes);

// THEN
expect(DdSdk.setAttributes).toHaveBeenCalledTimes(1);
expect(DdSdk.setAttributes).toHaveBeenCalledWith(attributes);
expect(NativeDdSdk.setAttributes).toHaveBeenCalledTimes(1);
expect(NativeDdSdk.setAttributes).toHaveBeenCalledWith(attributes);
expect(AttributesSingleton.getInstance().getAttributes()).toEqual({
foo: 'bar'
});
Expand All @@ -1079,8 +1089,8 @@ describe('DdSdkReactNative', () => {
await DdSdkReactNative.setUserInfo(userInfo);

// THEN
expect(DdSdk.setUserInfo).toHaveBeenCalledTimes(1);
expect(DdSdk.setUserInfo).toHaveBeenCalledWith(userInfo);
expect(NativeDdSdk.setUserInfo).toHaveBeenCalledTimes(1);
expect(NativeDdSdk.setUserInfo).toHaveBeenCalledWith(userInfo);
expect(UserInfoSingleton.getInstance().getUserInfo()).toEqual(
userInfo
);
Expand All @@ -1100,8 +1110,10 @@ describe('DdSdkReactNative', () => {
await DdSdkReactNative.addUserExtraInfo(extraInfo);

// THEN
expect(DdSdk.addUserExtraInfo).toHaveBeenCalledTimes(1);
expect(DdSdk.addUserExtraInfo).toHaveBeenCalledWith(extraInfo);
expect(NativeDdSdk.addUserExtraInfo).toHaveBeenCalledTimes(1);
expect(NativeDdSdk.addUserExtraInfo).toHaveBeenCalledWith(
extraInfo
);
expect(UserInfoSingleton.getInstance().getUserInfo()).toEqual({
id: 'id',
extraInfo: {
Expand Down Expand Up @@ -1130,8 +1142,8 @@ describe('DdSdkReactNative', () => {
await DdSdkReactNative.clearUserInfo();

// THEN
expect(DdSdk.clearUserInfo).toHaveBeenCalledTimes(1);
expect(DdSdk.setUserInfo).toHaveBeenCalled();
expect(NativeDdSdk.clearUserInfo).toHaveBeenCalledTimes(1);
expect(NativeDdSdk.setUserInfo).toHaveBeenCalled();
expect(UserInfoSingleton.getInstance().getUserInfo()).toEqual(
undefined
);
Expand All @@ -1148,8 +1160,10 @@ describe('DdSdkReactNative', () => {
DdSdkReactNative.setTrackingConsent(consent);

// THEN
expect(DdSdk.setTrackingConsent).toHaveBeenCalledTimes(1);
expect(DdSdk.setTrackingConsent).toHaveBeenCalledWith(consent);
expect(NativeDdSdk.setTrackingConsent).toHaveBeenCalledTimes(1);
expect(NativeDdSdk.setTrackingConsent).toHaveBeenCalledWith(
consent
);
});
});

Expand All @@ -1159,7 +1173,7 @@ describe('DdSdkReactNative', () => {
DdSdkReactNative.clearAllData();

// THEN
expect(DdSdk.clearAllData).toHaveBeenCalledTimes(1);
expect(NativeDdSdk.clearAllData).toHaveBeenCalledTimes(1);
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ describe('DdSdkReactNativeConfiguration', () => {
"actionEventMapper": null,
"additionalConfiguration": {},
"applicationId": "fake-app-id",
"attributeEncoders": [],
"batchProcessingLevel": "MEDIUM",
"batchSize": "MEDIUM",
"bundleLogsWithRum": true,
Expand Down Expand Up @@ -133,6 +134,7 @@ describe('DdSdkReactNativeConfiguration', () => {
"additionalField": "fake-value",
},
"applicationId": "fake-app-id",
"attributeEncoders": [],
"batchProcessingLevel": "MEDIUM",
"batchSize": "LARGE",
"bundleLogsWithRum": true,
Expand Down Expand Up @@ -220,6 +222,7 @@ describe('DdSdkReactNativeConfiguration', () => {
"actionEventMapper": null,
"additionalConfiguration": {},
"applicationId": "",
"attributeEncoders": [],
"batchProcessingLevel": "MEDIUM",
"batchSize": "MEDIUM",
"bundleLogsWithRum": false,
Expand Down
Loading