@flightstats/airframe-react-tracking
Version:
Declarative tracking for React apps.
99 lines (85 loc) • 4.15 kB
JavaScript
;
require("core-js/modules/es.object.define-property");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = useTrackingImpl;
var _react = require("react");
var _deepmerge = _interopRequireDefault(require("deepmerge"));
var _ReactTrackingContext = _interopRequireDefault(require("./ReactTrackingContext"));
var _dispatchTrackingEvent = _interopRequireDefault(require("./dispatchTrackingEvent"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function useTrackingImpl(trackingData, options) {
var _useContext = (0, _react.useContext)(_ReactTrackingContext["default"]),
tracking = _useContext.tracking;
var latestData = (0, _react.useRef)(trackingData);
var latestOptions = (0, _react.useRef)(options);
(0, _react.useEffect)(function () {
// store the latest data & options in a mutable ref to prevent
// dependencies from changing when the consumer passes in non-memoized objects
// same approach that we use for props in withTrackingComponentDecorator
latestData.current = trackingData;
latestOptions.current = options;
});
var _useMemo = (0, _react.useMemo)(function () {
return latestOptions.current || {};
}, []),
_useMemo$dispatch = _useMemo.dispatch,
dispatch = _useMemo$dispatch === void 0 ? _dispatchTrackingEvent["default"] : _useMemo$dispatch,
_useMemo$dispatchOnMo = _useMemo.dispatchOnMount,
dispatchOnMount = _useMemo$dispatchOnMo === void 0 ? false : _useMemo$dispatchOnMo,
process = _useMemo.process;
var getProcessFn = (0, _react.useCallback)(function () {
return tracking && tracking.process;
}, [tracking]);
var getOwnTrackingData = (0, _react.useCallback)(function () {
var data = latestData.current;
var ownTrackingData = typeof data === 'function' ? data() : data;
return ownTrackingData || {};
}, []);
var getTrackingDataFn = (0, _react.useCallback)(function () {
var contextGetTrackingData = tracking && tracking.getTrackingData || getOwnTrackingData;
return function () {
return contextGetTrackingData === getOwnTrackingData ? getOwnTrackingData() : (0, _deepmerge["default"])(contextGetTrackingData(), getOwnTrackingData());
};
}, [getOwnTrackingData, tracking]);
var getTrackingDispatcher = (0, _react.useCallback)(function () {
var contextDispatch = tracking && tracking.dispatch || dispatch;
return function (data) {
return contextDispatch((0, _deepmerge["default"])(getOwnTrackingData(), data || {}));
};
}, [getOwnTrackingData, tracking, dispatch]);
var trackEvent = (0, _react.useCallback)(function () {
var data = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
getTrackingDispatcher()(data);
}, [getTrackingDispatcher]);
(0, _react.useEffect)(function () {
var contextProcess = getProcessFn();
var getTrackingData = getTrackingDataFn();
if (contextProcess && process) {
// eslint-disable-next-line
console.error('[react-tracking] options.process should be defined once on a top-level component');
}
if (typeof contextProcess === 'function' && typeof dispatchOnMount === 'function') {
trackEvent((0, _deepmerge["default"])(contextProcess(getOwnTrackingData()) || {}, dispatchOnMount(getTrackingData()) || {}));
} else if (typeof contextProcess === 'function') {
var processed = contextProcess(getOwnTrackingData());
if (processed || dispatchOnMount === true) {
trackEvent(processed);
}
} else if (typeof dispatchOnMount === 'function') {
trackEvent(dispatchOnMount(getTrackingData()));
} else if (dispatchOnMount === true) {
trackEvent();
}
}, [getOwnTrackingData, getProcessFn, getTrackingDataFn, trackEvent, dispatchOnMount, process]);
return (0, _react.useMemo)(function () {
return {
tracking: {
dispatch: getTrackingDispatcher(),
getTrackingData: getTrackingDataFn(),
process: getProcessFn() || process
}
};
}, [getTrackingDispatcher, getTrackingDataFn, getProcessFn, process]);
}