clean-insights-sdk
Version:
A privacy-preserving measurement framework.
164 lines (163 loc) • 7.63 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Campaign = void 0;
var dayjs_1 = __importDefault(require("dayjs"));
var duration_1 = __importDefault(require("dayjs/plugin/duration"));
var isSameOrBefore_1 = __importDefault(require("dayjs/plugin/isSameOrBefore"));
dayjs_1.default.extend(duration_1.default);
dayjs_1.default.extend(isSameOrBefore_1.default);
var EventAggregationRule_1 = require("./EventAggregationRule");
var Campaign = /** @class */ (function () {
/**
* @param {dayjs.Dayjs|CampaignData} start
* The start of the campaign. (inclusive)
*
* @param {dayjs.Dayjs=} end
* The end of the campaign. (inclusive) OPTIONAL if provided via an object as first argument.
*
* @param {number=} aggregationPeriodLength
* The length of the aggregation period in number of days. At the end of a period,
* the aggregated data will be sent to the analytics server.
* OPTIONAL if provided via an object as first argument.
*
* @param {number=} numberOfPeriods=1
* The number of periods you want to measure in a row. Therefore the total
* length in days you measure one user is `aggregationPeriodLength * numberOfPeriods`
* beginning with the first day of the next period after the user consented.
*
* @param {boolean=} onlyRecordOnce=false
* Will result in recording only the first time a visit or event happened
* per period. Useful for yes/no questions.
*
* @param {EventAggregationRule=} eventAggregationRule=.Sum
* The rule how to aggregate the value of an event (if any given)
* with subsequent calls.
*
* @param {boolean=} strengthenAnonymity=false
* When set to true, measurements only ever start at the next full period.
* This ensures, that anonymity guaranties aren't accidentally reduced because the
* first period is very short.
*/
function Campaign(start, end, aggregationPeriodLength, numberOfPeriods, onlyRecordOnce, eventAggregationRule, strengthenAnonymity) {
if ('isValid' in start) { // Just checks for an arbitrary Day.js function, because instanceof test throws.
if (!end || !aggregationPeriodLength) {
throw TypeError('You either need to provide all non-optional arguments in their place or in an object as the first argument.');
}
this.start = start;
this.end = end;
this.aggregationPeriodLength = aggregationPeriodLength;
this.numberOfPeriods = typeof numberOfPeriods === 'number' ? numberOfPeriods : 1;
this.onlyRecordOnce = onlyRecordOnce || false;
this.eventAggregationRule = eventAggregationRule || EventAggregationRule_1.EventAggregationRule.Sum;
this.strengthenAnonymity = strengthenAnonymity || false;
}
else {
this.start = (0, dayjs_1.default)(start.start);
this.end = (0, dayjs_1.default)(start.end);
this.aggregationPeriodLength = start.aggregationPeriodLength;
this.numberOfPeriods = typeof start.numberOfPeriods === 'number' ? start.numberOfPeriods : 1;
this.onlyRecordOnce = start.onlyRecordOnce || false;
this.eventAggregationRule = start.eventAggregationRule === "avg" ? EventAggregationRule_1.EventAggregationRule.Avg : EventAggregationRule_1.EventAggregationRule.Sum;
this.strengthenAnonymity = start.strengthenAnonymity || false;
}
}
Object.defineProperty(Campaign.prototype, "aggregationPeriod", {
get: function () {
return dayjs_1.default.duration(this.aggregationPeriodLength, 'days');
},
enumerable: false,
configurable: true
});
Object.defineProperty(Campaign.prototype, "currentMeasurementPeriod", {
/**
* Returns the current measurement period, aka. the period where NOW is in.
*
* If NOW is outside any possible period, because the campaign hasn't started,
* yet, or already ended, will return `null`.
*
* The first period is defined as `aggregationPeriodLength` number of days after
* the `start` of the campaign.
*
* @returns {?{start: dayjs.Dayjs, end: dayjs.Dayjs}}
*/
get: function () {
if (this.numberOfPeriods <= 0) {
return null;
}
var now = (0, dayjs_1.default)();
var periodEnd = this.start;
do {
periodEnd = periodEnd.add(this.aggregationPeriod);
} while (periodEnd.isSameOrBefore(now));
var periodStart = periodEnd.subtract(this.aggregationPeriod).isAfter(this.start)
? periodEnd.subtract(this.aggregationPeriod)
: this.start;
if (periodEnd.isAfter(this.end)) {
periodEnd = this.end;
}
now = (0, dayjs_1.default)();
if (periodStart.isAfter(now) || periodEnd.isBefore(now)) {
return null;
}
return { start: periodStart, end: periodEnd };
},
enumerable: false,
configurable: true
});
Object.defineProperty(Campaign.prototype, "nextTotalMeasurementPeriod", {
/**
* @returns {?{start: dayjs.Dayjs, end: dayjs.Dayjs}}
*/
get: function () {
var current = this.currentMeasurementPeriod;
if (!current) {
return null;
}
var periodStart = this.strengthenAnonymity ? current.end : current.start;
var periodEnd = periodStart;
var counter = 0;
while (counter < this.numberOfPeriods && periodEnd.add(this.aggregationPeriod) <= this.end) {
periodEnd = periodEnd.add(this.aggregationPeriod);
counter += 1;
}
if (periodStart.isSame(periodEnd)) {
return null;
}
return { start: periodStart, end: periodEnd };
},
enumerable: false,
configurable: true
});
/**
* Apply the `eventAggregationRule` to the given event with the given value.
*
* @param {Event} event
* The event to apply the value to.
*
* @param {number=} value
* The value to apply.
*/
Campaign.prototype.apply = function (event, value) {
if (this.onlyRecordOnce || typeof value !== 'number') {
return;
}
var oldVal = typeof event.value === 'number' ? event.value : 0;
switch (this.eventAggregationRule) {
case "sum":
event.value = oldVal + value;
break;
case "avg":
// times was already increased in CleanInsights#getAndMeasure!
event.value = (oldVal * (event.times - 1) + value) / event.times;
break;
}
};
Campaign.prototype.toString = function () {
return "[".concat(this.constructor.name, ": start=").concat(this.start, ", end=").concat(this.end, ", aggregationPeriodLength=").concat(this.aggregationPeriodLength, ", numberOfPeriods=").concat(this.numberOfPeriods, ", onlyRecordOnce=").concat(this.onlyRecordOnce, ", eventAggregationRule=").concat(this.eventAggregationRule, "]");
};
return Campaign;
}());
exports.Campaign = Campaign;