plugin/boomerang/countly_boomerang.js
/**
         *  Initialize Boomerang
         *  @param {Object} BOOMR - Boomerang object
         */
Initialize Boomerang
@param {Object} BOOMR - Boomerang object
Initialize Boomerang @param { Object } BOOMR - Boomerang object
function initBoomerang(BOOMR) {
            if (BOOMR && !initedBoomr) {
                BOOMR.subscribe("before_beacon", function(beaconData) {
                    self._internals.log("BOOMR", "before_beacon", JSON.stringify(beaconData, null, 2));
                    var trace = {};
                    if (beaconData["rt.start"] !== "manual" && !beaconData["http.initiator"] && beaconData["rt.quit"] !== "") {
                        trace.type = "device";
                        trace.apm_metrics = {};
                        if (typeof beaconData["pt.fp"] !== "undefined") {
                            trace.apm_metrics.first_paint = beaconData["pt.fp"];
                        }
                        else if (typeof beaconData.nt_first_paint !== "undefined") {
                            trace.apm_metrics.first_paint = beaconData.nt_first_paint - beaconData["rt.tstart"];
                        }
                        if (typeof beaconData["pt.fcp"] !== "undefined") {
                            trace.apm_metrics.first_contentful_paint = beaconData["pt.fcp"];
                        }
                        if (typeof beaconData.nt_domint !== "undefined") {
                            trace.apm_metrics.dom_interactive = beaconData.nt_domint - beaconData["rt.tstart"];
                        }
                        if (typeof beaconData.nt_domcontloaded_st !== "undefined" && typeof beaconData.nt_domcontloaded_end !== "undefined") {
                            trace.apm_metrics.dom_content_loaded_event_end = beaconData.nt_domcontloaded_end - beaconData.nt_domcontloaded_st;
                        }
                        if (typeof beaconData.nt_load_st !== "undefined" && typeof beaconData.nt_load_end !== "undefined") {
                            trace.apm_metrics.load_event_end = beaconData.nt_load_end - beaconData.nt_load_st;
                        }
                        if (typeof beaconData["c.fid"] !== "undefined") {
                            trace.apm_metrics.first_input_delay = beaconData["c.fid"];
                        }
                    }
                    else if (beaconData["http.initiator"] && ["xhr", "spa", "spa_hard"].indexOf(beaconData["http.initiator"]) !== -1) {
                        var responseTime, responsePayloadSize, requestPayloadSize, responseCode;
                        responseTime = beaconData.t_resp;
                        responseCode = (typeof beaconData["http.errno"] !== "undefined") ? beaconData["http.errno"] : 200;
                        try {
                            var restiming = JSON.parse(beaconData.restiming);
                            var ResourceTimingDecompression = window.ResourceTimingDecompression;
                            if (ResourceTimingDecompression && restiming) {
                                ResourceTimingDecompression.HOSTNAMES_REVERSED = false;
                                var decompressedData = ResourceTimingDecompression.decompressResources(restiming);
                                var currentBeacon = decompressedData.filter(function(resource) {
                                    return resource.name === beaconData.u;
                                });
                                if (currentBeacon.length) {
                                    responsePayloadSize = currentBeacon[0].decodedBodySize;
                                    responseTime = currentBeacon[0].duration ? currentBeacon[0].duration : responseTime;
                                }
                            }
                        }
                        catch (e) {
                            self._internals.log("Error while using resource timing data decompression", config);
                        }
                        trace.type = "network";
                        trace.apm_metrics = {
                            response_time: responseTime,
                            response_payload_size: responsePayloadSize,
                            request_payload_size: requestPayloadSize,
                            response_code: responseCode
                        };
                    }
                    if (trace.type) {
                        trace.name = (beaconData.u + "").split("//").pop().split("?")[0];
                        trace.stz = beaconData["rt.tstart"];
                        trace.etz = beaconData["rt.end"];
                        self.report_trace(trace);
                    }
                });
                BOOMR.xhr_excludes = BOOMR.xhr_excludes || {};
                BOOMR.xhr_excludes[self.url.split("//").pop()] = true;
                if (typeof config.beacon_disable_sendbeacon === "undefined") {
                    config.beacon_disable_sendbeacon = true;
                }
                BOOMR.init(config);
                BOOMR.t_end = new Date().getTime();
                Countly.BOOMR = BOOMR;
                initedBoomr = true;
                self._internals.log("Boomerang initiated:", config);
            }
            else {
                self._internals.log("Boomerang called without its instance or was already initialized");
            }
        }
function initBoomerang ( BOOMR ) { if ( BOOMR && ! initedBoomr ) { BOOMR . subscribe ( "before_beacon" , function ( beaconData ) { self . _internals . log ( "BOOMR" , "before_beacon" , JSON . stringify ( beaconData , null , 2 ) ) ; var trace = { } ; if ( beaconData [ "rt.start" ] !== "manual" && ! beaconData [ "http.initiator" ] && beaconData [ "rt.quit" ] !== "" ) { trace . type = "device" ; trace . apm_metrics = { } ; if ( typeof beaconData [ "pt.fp" ] !== "undefined" ) { trace . apm_metrics . first_paint = beaconData [ "pt.fp" ] ; } else if ( typeof beaconData . nt_first_paint !== "undefined" ) { trace . apm_metrics . first_paint = beaconData . nt_first_paint - beaconData [ "rt.tstart" ] ; } if ( typeof beaconData [ "pt.fcp" ] !== "undefined" ) { trace . apm_metrics . first_contentful_paint = beaconData [ "pt.fcp" ] ; } if ( typeof beaconData . nt_domint !== "undefined" ) { trace . apm_metrics . dom_interactive = beaconData . nt_domint - beaconData [ "rt.tstart" ] ; } if ( typeof beaconData . nt_domcontloaded_st !== "undefined" && typeof beaconData . nt_domcontloaded_end !== "undefined" ) { trace . apm_metrics . dom_content_loaded_event_end = beaconData . nt_domcontloaded_end - beaconData . nt_domcontloaded_st ; } if ( typeof beaconData . nt_load_st !== "undefined" && typeof beaconData . nt_load_end !== "undefined" ) { trace . apm_metrics . load_event_end = beaconData . nt_load_end - beaconData . nt_load_st ; } if ( typeof beaconData [ "c.fid" ] !== "undefined" ) { trace . apm_metrics . first_input_delay = beaconData [ "c.fid" ] ; } } else if ( beaconData [ "http.initiator" ] && [ "xhr" , "spa" , "spa_hard" ] . indexOf ( beaconData [ "http.initiator" ] ) !== - 1 ) { var responseTime , responsePayloadSize , requestPayloadSize , responseCode ; responseTime = beaconData . t_resp ; responseCode = ( typeof beaconData [ "http.errno" ] !== "undefined" ) ? beaconData [ "http.errno" ] : 200 ; try { var restiming = JSON . parse ( beaconData . restiming ) ; var ResourceTimingDecompression = window . ResourceTimingDecompression ; if ( ResourceTimingDecompression && restiming ) { ResourceTimingDecompression . HOSTNAMES_REVERSED = false ; var decompressedData = ResourceTimingDecompression . decompressResources ( restiming ) ; var currentBeacon = decompressedData . filter ( function ( resource ) { return resource . name === beaconData . u ; } ) ; if ( currentBeacon . length ) { responsePayloadSize = currentBeacon [ 0 ] . decodedBodySize ; responseTime = currentBeacon [ 0 ] . duration ? currentBeacon [ 0 ] . duration : responseTime ; } } } catch ( e ) { self . _internals . log ( "Error while using resource timing data decompression" , config ) ; } trace . type = "network" ; trace . apm_metrics = { response_time : responseTime , response_payload_size : responsePayloadSize , request_payload_size : requestPayloadSize , response_code : responseCode } ; } if ( trace . type ) { trace . name = ( beaconData . u + "" ) . split ( "//" ) . pop ( ) . split ( "?" ) [ 0 ] ; trace . stz = beaconData [ "rt.tstart" ] ; trace . etz = beaconData [ "rt.end" ] ; self . report_trace ( trace ) ; } } ) ; BOOMR . xhr_excludes = BOOMR . xhr_excludes || { } ; BOOMR . xhr_excludes [ self . url . split ( "//" ) . pop ( ) ] = true ; if ( typeof config . beacon_disable_sendbeacon === "undefined" ) { config . beacon_disable_sendbeacon = true ; } BOOMR . init ( config ) ; BOOMR . t_end = new Date ( ) . getTime ( ) ; Countly . BOOMR = BOOMR ; initedBoomr = true ; self . _internals . log ( "Boomerang initiated:" , config ) ; } else { self . _internals . log ( "Boomerang called without its instance or was already initialized" ) ; } }
Initialize Boomerang
  @param {Object} BOOMR - Boomerang object
Initialize Boomerang @param { Object } BOOMR - Boomerang object
//t_resp - Time taken from the user initiating the request to the first byte of the response. - Added by RT //restiming contains information regarging all the resources that are loaded in any //spa, spa_hard or xhr requests. //xhr requests should ideally have only one entry in the array which is the one for //which the beacon is being sent. //But for spa_hard requests it can contain multiple entries, one for each resource //that is loaded in the application. Example - all images, scripts etc. //ResourceTimingDecompression is not included in the official boomerang library. //duration - Returns the difference between the resource's responseEnd timestamp and its startTime timestamp - ResourceTiming API