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
3 changes: 2 additions & 1 deletion src/mp-instance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1438,7 +1438,8 @@ function completeSDKInitialization(apiKey, config, mpInstance) {
mpInstance.Identity,
mpInstance._Store,
mpInstance.Logger,
roktOptions
roktOptions,
mpInstance.captureTiming
);
}

Expand Down
14 changes: 11 additions & 3 deletions src/roktManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { SDKIdentityApi } from "./identity.interfaces";
import { SDKLoggerApi } from "./sdkRuntimeModels";
import { IStore, LocalSessionAttributes } from "./store";
import { UserIdentities } from "@mparticle/web-sdk";
import { IdentityType } from "./types";
import { IdentityType, PerformanceMarkType } from "./types";

// https://docs.rokt.com/developers/integration-guides/web/library/attributes
export type RoktAttributeValueArray = Array<string | number | boolean>;
Expand Down Expand Up @@ -101,6 +101,7 @@ export default class RoktManager {
private logger: SDKLoggerApi;
private domain?: string;
private mappedEmailShaIdentityType?: string | null;
private captureTiming?: (metricsName: string) => void;
/**
* Initializes the RoktManager with configuration settings and user data.
*
Expand All @@ -109,6 +110,7 @@ export default class RoktManager {
* @param {SDKIdentityApi} identityService - The mParticle Identity instance
* @param {SDKLoggerApi} logger - The mParticle Logger instance
* @param {IRoktOptions} options - Options for the RoktManager
* @param {Function} captureTiming - Function to capture performance timing marks
*
* @throws Logs error to console if placementAttributesMapping parsing fails
*/
Expand All @@ -118,7 +120,8 @@ export default class RoktManager {
identityService: SDKIdentityApi,
store: IStore,
logger?: SDKLoggerApi,
options?: IRoktOptions
options?: IRoktOptions,
captureTiming?: (metricsName: string) => void
): void {
const { userAttributeFilters, settings } = roktConfig || {};
const { placementAttributesMapping, hashedEmailUserIdentityType } = settings || {};
Expand All @@ -127,6 +130,7 @@ export default class RoktManager {
this.identityService = identityService;
this.store = store;
this.logger = logger;
this.captureTiming = captureTiming;

this.filters = {
userAttributeFilters,
Expand Down Expand Up @@ -176,6 +180,10 @@ export default class RoktManager {
* });
*/
public async selectPlacements(options: IRoktSelectPlacementsOptions): Promise<IRoktSelection> {
if (this.captureTiming) {
this.captureTiming(PerformanceMarkType.JointSdkSelectPlacements);
}

if (!this.isReady()) {
return this.deferredCall<IRoktSelection>('selectPlacements', options);
}
Expand Down Expand Up @@ -514,4 +522,4 @@ export default class RoktManager {

return false; // Values are the same
}
}
}
1 change: 1 addition & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,7 @@ export const ApplicationTransitionType = {

export const PerformanceMarkType = {
SdkStart: 'mp:sdkStart' as const,
JointSdkSelectPlacements: 'mp:jointSdkSelectPlacements' as const,
}

export default {
Expand Down
61 changes: 61 additions & 0 deletions test/jest/roktManager.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { SDKIdentityApi } from "../../src/identity.interfaces";
import { IMParticleWebSDKInstance } from "../../src/mp-instance";
import RoktManager, { IRoktKit, IRoktSelectPlacementsOptions } from "../../src/roktManager";
import { testMPID } from '../src/config/constants';
import { PerformanceMarkType } from "../../src/types";

const resolvePromise = () => new Promise(resolve => setTimeout(resolve, 0));

Expand Down Expand Up @@ -635,6 +636,66 @@ describe('RoktManager', () => {
jest.clearAllMocks();
});

it('should capture jointSdkSelectPlacements timing when selectPlacements is called', () => {
const mockCaptureTiming = jest.fn();
roktManager.init(
{} as IKitConfigs,
{} as IMParticleUser,
mockMPInstance.Identity,
mockMPInstance._Store,
mockMPInstance.Logger,
undefined,
mockCaptureTiming
);

const kit: IRoktKit = {
launcher: {
selectPlacements: jest.fn(),
hashAttributes: jest.fn(),
use: jest.fn(),
},
filters: undefined,
filteredUser: undefined,
userAttributes: undefined,
selectPlacements: jest.fn(),
hashAttributes: jest.fn(),
setExtensionData: jest.fn(),
use: jest.fn(),
};

roktManager.attachKit(kit);

const options = {
attributes: {}
} as IRoktSelectPlacementsOptions;

roktManager.selectPlacements(options);
expect(mockCaptureTiming).toHaveBeenCalledWith(PerformanceMarkType.JointSdkSelectPlacements);
expect(mockCaptureTiming).toHaveBeenCalledTimes(1);
});

it('should capture jointSdkSelectPlacements timing even when kit is not ready (deferred call)', () => {
const mockCaptureTiming = jest.fn();
roktManager.init(
{} as IKitConfigs,
{} as IMParticleUser,
mockMPInstance.Identity,
mockMPInstance._Store,
mockMPInstance.Logger,
undefined,
mockCaptureTiming
);

const options = {
attributes: {}
} as IRoktSelectPlacementsOptions;

roktManager.selectPlacements(options);
expect(mockCaptureTiming).toHaveBeenCalledWith(PerformanceMarkType.JointSdkSelectPlacements);
expect(mockCaptureTiming).toHaveBeenCalledTimes(1);
});


it('should call kit.selectPlacements with empty attributes', () => {
const kit: IRoktKit = {
launcher: {
Expand Down
Loading