Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
@doodle/tracking / dist / cjs / src / core / init.js
Size: Mime:
'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

var _rollupPluginBabelHelpers = require('../../_virtual/_rollupPluginBabelHelpers.js');
var utils = require('../helpers/utils.js');
var handlers = require('./handlers.js');
var listener = require('./listener.js');
var constants = require('../constants.js');
var dispatchers_config = require('./dispatchers.config.js');
var consent = require('./consent.js');

/**
 * Reference to the handler function that is attached to the document
 * for declarative tracking.
 */

var declarativeTrackingHandler = null;
/**
 * Runs declarative tracking calls which are not based on clicks
 *
 * @private
 * @return {undefined}
 */

var runDeclarativeTracking = function runDeclarativeTracking(options) {
  var identifyTrackers = _rollupPluginBabelHelpers.toConsumableArray(document.querySelectorAll('[data-identify]'));

  identifyTrackers.forEach(function (trackingEl) {
    var trackingOptions = trackingEl.dataset.trackingOptions ? JSON.parse(trackingEl.dataset.trackingOptions) : options;
    var autoTracking = trackingOptions.autoTracking !== false; // Avoids tracking if autoTracking is set to false in the tracking intent (when omitted default is true)

    if (!autoTracking) {
      return;
    }

    handlers.handleIdentify({
      trackingEl: trackingEl
    }, options);
  });
};
/**
 * Handles the activation (including de-activation) of a service/tracker.
 * @async
 * @param {string} service - The current service for which to handle activation.
 * @param {TrackingApiOptions} options - The API client's options
 * @param {string[]} consents - The currently active consent categories
 * @param {string[]} activeServices - Which services are currently active
 * @returns {Promise<boolean>} True if service was activated (or was active), false it it was removed or does not have consent.
 */


var handleServiceActivation = /*#__PURE__*/function () {
  var _ref = _rollupPluginBabelHelpers.asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee(service, options) {
    var consents,
        activeServices,
        isActive,
        consentCategory,
        removeFn,
        initFn,
        _args = arguments;
    return regeneratorRuntime.wrap(function _callee$(_context) {
      while (1) {
        switch (_context.prev = _context.next) {
          case 0:
            consents = _args.length > 2 && _args[2] !== undefined ? _args[2] : [];
            activeServices = _args.length > 3 && _args[3] !== undefined ? _args[3] : [];
            isActive = activeServices.includes(service);
            consentCategory = dispatchers_config.TRACKERS_TO_CONSENT_CATEGORIES[service];

            if (consent.hasConsent(consentCategory, consents)) {
              _context.next = 20;
              break;
            }

            if (!isActive) {
              _context.next = 19;
              break;
            }

            removeFn = dispatchers_config.TRACKING_HOOKS_TO_FNS[constants.TRACKING_HOOKS.REMOVE][service];

            if (!removeFn) {
              _context.next = 18;
              break;
            }

            _context.prev = 8;
            _context.next = 11;
            return removeFn(options);

          case 11:
            return _context.abrupt("return", false);

          case 14:
            _context.prev = 14;
            _context.t0 = _context["catch"](8);
            console.error("Error removing '".concat(service, " service.'"), _context.t0);
            return _context.abrupt("return", true);

          case 18:
            return _context.abrupt("return", false);

          case 19:
            return _context.abrupt("return", false);

          case 20:
            if (isActive) {
              _context.next = 34;
              break;
            }

            initFn = dispatchers_config.TRACKING_HOOKS_TO_FNS[constants.TRACKING_HOOKS.INIT][service];

            if (!initFn) {
              _context.next = 33;
              break;
            }

            _context.prev = 23;
            _context.next = 26;
            return initFn(options);

          case 26:
            return _context.abrupt("return", true);

          case 29:
            _context.prev = 29;
            _context.t1 = _context["catch"](23);
            console.error("Error initialising '".concat(service, "' service."), _context.t1);
            return _context.abrupt("return", false);

          case 33:
            return _context.abrupt("return", true);

          case 34:
            return _context.abrupt("return", true);

          case 35:
          case "end":
            return _context.stop();
        }
      }
    }, _callee, null, [[8, 14], [23, 29]]);
  }));

  return function handleServiceActivation(_x, _x2) {
    return _ref.apply(this, arguments);
  };
}();
/**
 * Gets an updated version of the initialized services array.
 * @param {string} service - The service that changed state.
 * @param {boolean} wasActivated - If the service was activate (true) or deactivated (false).
 * @param {string[]} activatedServices - The previously activated services.
 * @returns {string[]} - The updated array of activated services.
 */


var updateServiceActivations = function updateServiceActivations(service, wasActivated, activatedServices) {
  if (wasActivated) {
    if (!activatedServices.includes(service)) {
      return [].concat(_rollupPluginBabelHelpers.toConsumableArray(activatedServices), [service]);
    }
  } else if (activatedServices.includes(service)) {
    return activatedServices.filter(function (s) {
      return s !== service;
    });
  }

  return activatedServices;
};
/**
 * Initializes the declarative tracking via DOM elements.
 *
 * @private
 * @param {TrackingApiOptions} options - The API client's options
 * @param {string[]} consents - The currently active consent categories
 */


var initDeclarativeTracking = function initDeclarativeTracking(options) {
  var consents = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];

  // The handler has been added before. To update the passed in options and consents, we need
  // remove and re-attach it.
  if (declarativeTrackingHandler !== null) {
    document.body.removeEventListener('click', declarativeTrackingHandler);
  } // First-time attach or re-attach the handler to the DOM


  declarativeTrackingHandler = listener.handleDeclarativeTracking.bind(null, options, consents);
  document.body.addEventListener('click', declarativeTrackingHandler);
};
/**
 * Initializes @doodle/tracking and its dependencies (currently only amplitude-js needs it)
 * Also by default enables declarative tracking (automatically handle tracking data attributes)
 *
 * To be invoked in your app's client side initialization
 *
 * @private
 * @param {TrackingApiOptions} options - The API client's options
 * @param {string[]} consents - The currently active consent categories
 * @param {string[]} activeServices - Which services are currently active
 * @return {Promise<string[]>} - true for successful initialization, and false for exits on guard conditions
 */


var initTracking = /*#__PURE__*/function () {
  var _ref2 = _rollupPluginBabelHelpers.asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2(options) {
    var consents,
        activeServices,
        services,
        _options$initAll,
        initAll,
        _options$autoTracking,
        autoTracking,
        updatedActiveServices,
        enabledServices,
        allSettled,
        activations,
        i,
        active,
        service,
        _args2 = arguments;

    return regeneratorRuntime.wrap(function _callee2$(_context2) {
      while (1) {
        switch (_context2.prev = _context2.next) {
          case 0:
            consents = _args2.length > 1 && _args2[1] !== undefined ? _args2[1] : [];
            activeServices = _args2.length > 2 && _args2[2] !== undefined ? _args2[2] : [];
            services = options.services, _options$initAll = options.initAll, initAll = _options$initAll === void 0 ? true : _options$initAll, _options$autoTracking = options.autoTracking, autoTracking = _options$autoTracking === void 0 ? true : _options$autoTracking;
            updatedActiveServices = _rollupPluginBabelHelpers.toConsumableArray(activeServices); // Guard against Server Side Rendering

            if (!(typeof document === 'undefined')) {
              _context2.next = 6;
              break;
            }

            return _context2.abrupt("return", []);

          case 6:
            if (!utils.hasDntEnabled()) {
              _context2.next = 8;
              break;
            }

            return _context2.abrupt("return", []);

          case 8:
            // Enable automated click handling behavior for declarative tracking
            if (autoTracking) {
              initDeclarativeTracking(options, consents);
            } // Opt-in trackers initialization behavior


            if (!initAll) {
              _context2.next = 16;
              break;
            }

            enabledServices = Object.keys(services).filter(function (service) {
              return services[service];
            }); // Handle activation/deactivation of each enabled service in parallel, the order of results (resolutions, rejections) is
            // preserved: https://stackoverflow.com/a/28066851
            // In case app does not provide a polyfill for Promise.allSettled we use a basic custom one as fallback

            allSettled = Promise.allSettled ? Promise.allSettled.bind(Promise) : utils.allSettledPolyfill;
            _context2.next = 14;
            return allSettled(enabledServices.map(function (service) {
              return handleServiceActivation(service, options, consents, updatedActiveServices);
            }));

          case 14:
            activations = _context2.sent;

            // Update the "active services" registry with the new states (using indexed foreach to keep order of services and activations).
            for (i = 0; i < activations.length; i += 1) {
              active = activations[i].value;
              service = enabledServices[i];
              updatedActiveServices = updateServiceActivations(service, active, updatedActiveServices);
            }

          case 16:
            // Perform declarative tracking which is not click based (for now, only identify calls)
            runDeclarativeTracking(options);
            return _context2.abrupt("return", updatedActiveServices);

          case 18:
          case "end":
            return _context2.stop();
        }
      }
    }, _callee2);
  }));

  return function initTracking(_x3) {
    return _ref2.apply(this, arguments);
  };
}();

exports.handleServiceActivation = handleServiceActivation;
exports.initDeclarativeTracking = initDeclarativeTracking;
exports.initTracking = initTracking;
exports.runDeclarativeTracking = runDeclarativeTracking;
exports.updateServiceActivations = updateServiceActivations;
//# sourceMappingURL=init.js.map