UNPKG

@aller/blink

Version:

A library for tracking user behaviour.

149 lines 5.07 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.calculateEventTime = exports.discardUnrealisticallyHighInscreen = exports.hasFinalStopTime = void 0; /** * Checks if there is a stop time present. */ function hasFinalStopTime(times) { var lastTime = times[times.length - 1]; return !times.length || (lastTime && lastTime.type === 'stop'); } exports.hasFinalStopTime = hasFinalStopTime; /** * Skips duplicate start and end times. Could occur if * the machine has a hick-up when updating the inscreen time. * * [ { start 1 }, { start 2 }, { end 1 } ] * Would be converted to: * [ { start 1 }, { end 1 } ] */ function mergeDuplicateTimesTogether(times) { return times.filter(function (_a, index) { var type = _a.type; var prevTime = times[index - 1]; var prevTimeIsADuplicate = prevTime && type === prevTime.type; return !prevTimeIsADuplicate; }); } function integrateScreenEvents(times, screenEvents) { var allTimes = times .concat(screenEvents) .sort(function (a, b) { return a.time.getTime() - b.time.getTime(); }); return allTimes.filter(function (current, index) { var prev = allTimes[index - 1]; var prevType = prev ? prev.type : 'none'; // Remove stop after hide if (prevType === 'hide' && current.type === 'stop') { return false; } // Remove show after start if (prevType === 'start' && current.type === 'show') { return false; } // Only accept start event as event after stop if (prevType === 'stop' && (current.type === 'hide' || current.type === 'show')) { return false; } return true; }); } function convertScreenToTimeEvents(times) { return times.map(function (timeEv) { if (timeEv.type === 'show') { var event_1 = { time: timeEv.time, type: 'start', }; return event_1; } if (timeEv.type === 'hide') { var event_2 = { time: timeEv.time, type: 'stop', }; return event_2; } return timeEv; }); } /** * Removs a stop time if there is one at the beginning. * This can happen in some in-view libraries when the page * loads elements outside of the screen * * [ {stop 1 }, { start 2 }, { stop 3 } ] * Would be converted to: * [ { start 2 }, { stop 3 } ] */ function removeStopTimeAtBeginningIfPresent(times) { if (times.length > 0 && times[0].type === 'stop') { return times.slice(1); } return times; } /** * Appends a stop time if there is no end to the tracking. * This can happen if a user closes her browser while an * impression is inscreen. * * [ { start 1 } ] * Would be converted to: * [ { start 1 }, { end 1 } ] */ function appendStopTimeIfNotPresent(times, now, maxIdleTime) { if (now === void 0) { now = new Date(); } if (!(now instanceof Date)) { throw Error('Now must be of the Date type. Are you mapping?'); } if (hasFinalStopTime(times)) { return times; } var lastTimeEvent = times[times.length - 1]; var maxTime = lastTimeEvent ? new Date(lastTimeEvent.time.getTime() + maxIdleTime) : now; // Add a stop event with whichever is smaller: the maxTime or current time return times.concat([{ type: 'stop', time: maxTime < now ? maxTime : now }]); } /** * Sets any values that are unrealistically high to zero. */ function discardUnrealisticallyHighInscreen(inscreenTime) { var twoHours = 2 * 60 * 60 * 1000; return inscreenTime < twoHours ? inscreenTime : 0; } exports.discardUnrealisticallyHighInscreen = discardUnrealisticallyHighInscreen; /** * Adds together all the intervals that were recorded * while an impression was inscreen. */ function sumStartAndStopTimes(times) { return times.reduce(function (total, _a) { var type = _a.type, time = _a.time; if (type === 'start') { return total - time.getTime(); } return total + time.getTime(); }, 0); } /** * Calculates the total inscreen time in milliseconds from * a list of start and end times. */ function calculateEventTime(input) { if (!input.times || input.times.length === 0) { return 0; } var times = integrateScreenEvents(input.times, input.screenEvents || []); times = convertScreenToTimeEvents(times); times = appendStopTimeIfNotPresent(times, input.now || new Date(), input.maxIdleTime || 10000); times = mergeDuplicateTimesTogether(times); var cleanedInterval = removeStopTimeAtBeginningIfPresent(times); var summedInterval = sumStartAndStopTimes(cleanedInterval); var positiveInterval = Math.max(0, summedInterval); var realisticInterval = discardUnrealisticallyHighInscreen(positiveInterval); return realisticInterval; } exports.calculateEventTime = calculateEventTime; //# sourceMappingURL=event-time.js.map