UNPKG

coveo-search-ui

Version:

Coveo JavaScript Search Framework

83 lines (67 loc) 2.81 kB
import { last, compact, filter, reduceRight } from 'underscore'; import { IAnalyticsOmniboxSuggestionMeta } from '../Analytics/AnalyticsActionListMeta'; export interface IOmniboxAnalytics { partialQueries: string[]; suggestionRanking: number; suggestions: string[]; partialQuery: string; buildCustomDataForPartialQueries: () => IAnalyticsOmniboxSuggestionMeta; } export class OmniboxAnalytics implements IOmniboxAnalytics { public partialQueries: string[] = []; public suggestionRanking: number; public suggestions: string[] = []; public partialQuery: string; private readonly analyticsLengthLimit = 256; constructor() {} public buildCustomDataForPartialQueries(): IAnalyticsOmniboxSuggestionMeta { this.partialQuery = last(this.partialQueries); return { partialQueries: this.cleanCustomData(this.partialQueries), suggestionRanking: this.suggestionRanking, suggestions: this.cleanCustomData(this.suggestions), partialQuery: this.partialQuery }; } private cleanCustomData(toClean: string[], rejectLength = this.analyticsLengthLimit) { const filterOutConsecutiveValues = this.filterOutConsecutiveValues(toClean); // Custom dimensions cannot be an array in analytics service: Send a string joined by ; instead. // Need to replace ; const redimensionedArray = filterOutConsecutiveValues.map(value => this.removeSemicolons(value)); // Reduce right to get the last X words that adds to less then rejectLength const reducedToRejectLengthOrLess = this.reduceAnalyticsToLengthLimit(redimensionedArray, rejectLength); const cleanStrings = reducedToRejectLengthOrLess.reverse(); const ret = cleanStrings.join(';'); // analytics service can store max 256 char in a custom event // if we're over that, call cleanup again with an arbitrary 10 less char accepted if (ret.length >= this.analyticsLengthLimit) { return this.cleanCustomData(cleanStrings, rejectLength - 10); } return cleanStrings.join(';'); } private filterOutConsecutiveValues(toClean: string[]) { return compact( filter(toClean, (partial: string, pos?: number, array?: string[]) => { return pos === 0 || partial !== array[pos - 1]; }) ); } private removeSemicolons(partial: string) { return partial.replace(/;/g, ''); } private reduceAnalyticsToLengthLimit(toClean: string[], rejectLength: number) { const reducedToRejectLengthOrLess: string[] = []; reduceRight( toClean, (memo: number, partial: string) => { const totalSoFar = memo + partial.length; if (totalSoFar <= rejectLength) { reducedToRejectLengthOrLess.push(partial); } return totalSoFar; }, 0 ); return reducedToRejectLengthOrLess; } }