UNPKG

@vivianhealth/braze-segment-debounce

Version:

Segment utilities to debounce data before it reaches the Braze destination

122 lines (95 loc) 5.25 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.debouncePayloadSync = void 0; var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _index = require("./index"); var _utils = require("./utils"); function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } var defaultFetchPayload = function defaultFetchPayload(key) { if (typeof window !== 'undefined') { return window.localStorage.getItem(key); } throw new Error('Unable to fetch payload outside of a browser environment by default. Please specify fetchPayload.'); }; var defaultPersistPayload = function defaultPersistPayload(key, serializedPayload) { if (typeof window !== 'undefined') { return window.localStorage.setItem(key, serializedPayload); } throw new Error('Unable to persist payload outside of a browser environment by default. Please specify persistPayload.'); }; /** * `debouncePayloadSync` provides a full solution that integrates with the * Analytics.js Source Middleware to debounce data before it is sent * to the Braze destination. It stores previous payloads in `localStorage`, * or a similar solution which you can override, and compares the `payload` * provided by this middleware against the previous versions so that it * only sends new or updated `traits`. * @param {Object} payload The data provided by the Analytics.js middleware * @param {Function} options.fetchPayload An optional function to override `localStorage.getItem` * @param {Function} options.persistPayload An optional function to override `localStorage.setItem` * @return {Object} The debounced payload to send to Braze. If `null`, * there is no new or updated data to send. * @example * ``` * import { debouncePayloadSync } from 'braze-segment-debounce/browser'; * * const _identifyDebounceSourceMiddleware = ({ payload, next, integrations }) => { * // TODO filter Braze integration, called `AppBoy` * if (payload.type() !== 'identify') { * next(payload); * return; * } * const identifyPayload = debouncePayloadSync(payload); * if (identifyPayload) { * next(identifyPayload); * } * } * analytics.addSourceMiddleware(_identifyDebounceSourceMiddleware); * ``` * */ var debouncePayloadSync = function debouncePayloadSync(payload) { var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, _ref$fetchPayload = _ref.fetchPayload, fetchPayload = _ref$fetchPayload === void 0 ? defaultFetchPayload : _ref$fetchPayload, _ref$persistPayload = _ref.persistPayload, persistPayload = _ref$persistPayload === void 0 ? defaultPersistPayload : _ref$persistPayload; var getPayloadProperty = function getPayloadProperty(payload, prop) { var _payload$obj; return payload === null || payload === void 0 ? void 0 : (_payload$obj = payload.obj) === null || _payload$obj === void 0 ? void 0 : _payload$obj[prop]; }; var key = (0, _utils.getPayloadKey)(payload, getPayloadProperty); var parsedPreviousPayload = null; try { var rawPreviousPayload = fetchPayload(key); if (rawPreviousPayload) { parsedPreviousPayload = JSON.parse(rawPreviousPayload); } } catch (_unused) { console.error('debouncePayloadSync: failed to fetch previous payload for debouncing'); } var previousPayload = parsedPreviousPayload || {}; // Remove undefined fields var sanitizedPayload = JSON.parse(JSON.stringify(payload)); var _debouncePayloads = (0, _index.debouncePayloads)(previousPayload, sanitizedPayload, getPayloadProperty), nextPayload = _debouncePayloads.nextPayload, newOrUpdatedTraits = _debouncePayloads.newOrUpdatedTraits; if (nextPayload) { var debouncedPayload = _objectSpread(_objectSpread({}, nextPayload), {}, { obj: _objectSpread(_objectSpread({}, nextPayload.obj), {}, { traits: newOrUpdatedTraits || nextPayload.obj.traits }) }); var previousPayloadToStore = (0, _utils.combinePreviousPayloads)([previousPayload, sanitizedPayload]); try { persistPayload(key, JSON.stringify(previousPayloadToStore)); } catch (_unused2) {// no-op } return debouncedPayload; } return null; }; exports.debouncePayloadSync = debouncePayloadSync;