@splitsoftware/splitio-commons
Version:
Split JavaScript SDK common components
67 lines (56 loc) • 2.33 kB
text/typescript
import { groupBy, forOwn } from '../../utils/lang';
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';
const DATA_NAME = 'impressions';
/**
* Converts `impressions` data from cache into request payload.
*/
export function fromImpressionsCollector(sendLabels: boolean, data: SplitIO.ImpressionDTO[]): ImpressionsPayload {
let groupedByFeature = groupBy(data, 'feature');
let dto: ImpressionsPayload = [];
// using forOwn instead of for...in since the last also iterates over prototype enumerables
forOwn(groupedByFeature, (value, name) => {
dto.push({
f: name, // Test Name
i: value.map(entry => { // Key Impressions
const keyImpression = {
k: entry.keyName, // Key
t: entry.treatment, // Treatment
m: entry.time, // Timestamp
c: entry.changeNumber, // ChangeNumber
r: sendLabels ? entry.label : undefined, // Rule
b: entry.bucketingKey, // Bucketing Key
pt: entry.pt, // Previous time
properties: entry.properties // Properties
};
return keyImpression;
})
});
});
return dto;
}
/**
* Submitter that periodically posts impressions data
*/
export function impressionsSubmitterFactory(params: ISdkFactoryContextSync) {
const {
settings: { log, scheduler: { impressionsRefreshRate }, core: { labelsEnabled } },
splitApi: { postTestImpressionsBulk },
storage: { impressions }
} = params;
// retry impressions only once.
const syncTask = submitterFactory(log, postTestImpressionsBulk, impressions, impressionsRefreshRate, DATA_NAME, fromImpressionsCollector.bind(undefined, labelsEnabled), 1);
// register impressions submitter to be executed when impressions cache is full
impressions.setOnFullQueueCb(() => {
if (syncTask.isRunning()) {
log.info(SUBMITTERS_PUSH_FULL_QUEUE, [DATA_NAME]);
syncTask.execute();
}
// If submitter is stopped (e.g., user consent declined or unknown, or app state offline), we don't send the data.
// Data will be sent when submitter is resumed.
});
return syncTask;
}