@vivianhealth/braze-segment-debounce
Version:
Segment utilities to debounce data before it reaches the Braze destination
122 lines (95 loc) • 5.25 kB
JavaScript
;
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;