Skip to content
Draft
Show file tree
Hide file tree
Changes from 3 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