diff --git a/src/listeners/browser.ts b/src/listeners/browser.ts index 0792c3a6..c99675bf 100644 --- a/src/listeners/browser.ts +++ b/src/listeners/browser.ts @@ -28,14 +28,14 @@ export class BrowserSignalListener implements ISignalListener { private serviceApi: ISplitApi; private fromImpressionsCollector: (data: SplitIO.ImpressionDTO[]) => ImpressionsPayload; - constructor({ syncManager, settings, storage, splitApi }: ISdkFactoryContextSync) { + constructor({ syncManager, settings, storage, splitApi, entityType }: ISdkFactoryContextSync) { this.syncManager = syncManager; this.settings = settings; this.storage = storage; this.serviceApi = splitApi; this.flushData = this.flushData.bind(this); this.flushDataIfHidden = this.flushDataIfHidden.bind(this); - this.fromImpressionsCollector = fromImpressionsCollector.bind(undefined, settings.core.labelsEnabled); + this.fromImpressionsCollector = fromImpressionsCollector.bind(undefined, settings.core.labelsEnabled, entityType); } /** diff --git a/src/sdkFactory/types.ts b/src/sdkFactory/types.ts index 2b822dd0..1ef00591 100644 --- a/src/sdkFactory/types.ts +++ b/src/sdkFactory/types.ts @@ -43,6 +43,9 @@ export interface IPlatform { SignalListener?: new (params: ISdkFactoryContext) => ISignalListener, // Used by BrowserSignalListener } +// Definition type +export type EntityType = 'config' | 'flag'; + export interface ISdkFactoryContext { platform: IPlatform, sdkReadinessManager: ISdkReadinessManager, @@ -55,7 +58,8 @@ export interface ISdkFactoryContext { splitApi?: ISplitApi, syncManager?: ISyncManager, clients: Record, - fallbackCalculator: IFallbackCalculator + fallbackCalculator: IFallbackCalculator, + entityType?: EntityType } export interface ISdkFactoryContextSync extends ISdkFactoryContext { diff --git a/src/sync/submitters/__tests__/impressionsSubmitter.spec.ts b/src/sync/submitters/__tests__/impressionsSubmitter.spec.ts index 135abb2e..92c5f511 100644 --- a/src/sync/submitters/__tests__/impressionsSubmitter.spec.ts +++ b/src/sync/submitters/__tests__/impressionsSubmitter.spec.ts @@ -1,4 +1,4 @@ -import { impressionsSubmitterFactory } from '../impressionsSubmitter'; +import { fromImpressionsCollector, impressionsSubmitterFactory } from '../impressionsSubmitter'; import { loggerMock } from '../../../logger/__tests__/sdkLogger.mock'; import { ImpressionsCacheInMemory } from '../../../storages/inMemory/ImpressionsCacheInMemory'; @@ -96,3 +96,20 @@ describe('Impressions submitter', () => { }); }); + +describe('fromImpressionsCollector', () => { + + test('includes entityType in payload when provided', () => { + const impressions = [imp1, imp2]; + const result = fromImpressionsCollector(false, 'config', impressions); + + expect(result).toEqual([{ + f: 'someFeature', + i: [ + { k: 'k1', t: 'someTreatment', m: 0, c: 123, et: 'config' }, + { k: 'k2', t: 'someTreatment', m: 0, c: 123, et: 'config' }, + ] + }]); + }); + +}); diff --git a/src/sync/submitters/impressionsSubmitter.ts b/src/sync/submitters/impressionsSubmitter.ts index 2fa85ab4..b756a34e 100644 --- a/src/sync/submitters/impressionsSubmitter.ts +++ b/src/sync/submitters/impressionsSubmitter.ts @@ -3,20 +3,20 @@ import SplitIO from '../../../types/splitio'; import { submitterFactory } from './submitter'; import { ImpressionsPayload } from './types'; import { SUBMITTERS_PUSH_FULL_QUEUE } from '../../logger/constants'; -import { ISdkFactoryContextSync } from '../../sdkFactory/types'; +import { EntityType, ISdkFactoryContextSync } from '../../sdkFactory/types'; /** * Converts `impressions` data from cache into request payload. */ -export function fromImpressionsCollector(sendLabels: boolean, data: SplitIO.ImpressionDTO[]): ImpressionsPayload { +export function fromImpressionsCollector(sendLabels: boolean, entityType: EntityType | undefined, data: SplitIO.ImpressionDTO[]): ImpressionsPayload { let groupedByFeature = groupBy(data, 'feature'); let dto: ImpressionsPayload = []; forOwn(groupedByFeature, (value, name) => { dto.push({ - f: name, // Test Name + f: name, // Definition type i: value.map(entry => { // Key Impressions - const keyImpression = { + return { k: entry.keyName, // Key t: entry.treatment, // Treatment m: entry.time, // Timestamp @@ -24,10 +24,9 @@ export function fromImpressionsCollector(sendLabels: boolean, data: SplitIO.Impr r: sendLabels ? entry.label : undefined, // Rule b: entry.bucketingKey, // Bucketing Key pt: entry.pt, // Previous time - properties: entry.properties // Properties + properties: entry.properties, // Properties + et: entityType, // Definition type }; - - return keyImpression; }) }); }); @@ -43,11 +42,12 @@ export function impressionsSubmitterFactory(params: ISdkFactoryContextSync) { const { settings: { log, scheduler: { impressionsRefreshRate }, core: { labelsEnabled } }, splitApi: { postTestImpressionsBulk }, - storage: { impressions } + storage: { impressions }, + entityType } = params; // retry impressions only once. - const syncTask = submitterFactory(log, postTestImpressionsBulk, impressions, impressionsRefreshRate, fromImpressionsCollector.bind(undefined, labelsEnabled), 1); + const syncTask = submitterFactory(log, postTestImpressionsBulk, impressions, impressionsRefreshRate, fromImpressionsCollector.bind(undefined, labelsEnabled, entityType), 1); // register impressions submitter to be executed when impressions cache is full impressions.setOnFullQueueCb(() => { diff --git a/src/sync/submitters/types.ts b/src/sync/submitters/types.ts index 36a76c9b..c5c44381 100644 --- a/src/sync/submitters/types.ts +++ b/src/sync/submitters/types.ts @@ -2,6 +2,7 @@ import { IMetadata } from '../../dtos/types'; import SplitIO from '../../../types/splitio'; import { ISyncTask } from '../types'; +import { EntityType } from '../../sdkFactory/types'; type ImpressionPayload = { /** Matching Key */ @@ -20,6 +21,8 @@ type ImpressionPayload = { pt?: number; /** Stringified JSON object with properties */ properties?: string; + /** Definition type */ + et?: EntityType, }; export type ImpressionsPayload = {