@splitsoftware/splitio-commons
Version:
Split JavaScript SDK common components
99 lines (98 loc) • 3.85 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.getDelay = exports.parseFFUpdatePayload = exports.isInBitmap = exports.parseBitmap = exports.parseKeyList = void 0;
var decompress_1 = require("../../utils/decompress");
var base64_1 = require("../../utils/base64");
var murmur3_1 = require("../../utils/murmur3/murmur3");
var GZIP = 1;
var ZLIB = 2;
function Uint8ArrayToString(myUint8Arr) {
return String.fromCharCode.apply(null, myUint8Arr);
}
function StringToUint8Array(myString) {
var charCodes = myString.split('').map(function (e) { return e.charCodeAt(0); });
return new Uint8Array(charCodes);
}
/**
* Decode and decompress 'data' with 'compression' algorithm
*
* @param data - base64 encoded string
* @param compression - 1 GZIP, 2 ZLIB
* @returns
* @throws if data string cannot be decoded, decompressed or the provided compression value is invalid (not 1 or 2)
*/
function decompress(data, compression) {
var compressData = (0, base64_1.decodeFromBase64)(data);
var binData = StringToUint8Array(compressData);
if (typeof decompress_1.algorithms === 'string')
throw new Error(decompress_1.algorithms);
if (compression === GZIP)
return decompress_1.algorithms.gunzipSync(binData);
if (compression === ZLIB)
return decompress_1.algorithms.unzlibSync(binData);
throw new Error("Invalid compression algorithm #" + compression);
}
/**
* Decode, decompress and parse the provided 'data' into a KeyList object
*
* @param data - base64 encoded string
* @param compression - 1 GZIP, 2 ZLIB
* @param avoidPrecisionLoss - true as default, set it as false if dont need to avoid precission loss
* @returns keyList
* @throws if data string cannot be decoded, decompressed or parsed
*/
function parseKeyList(data, compression, avoidPrecisionLoss) {
if (avoidPrecisionLoss === void 0) { avoidPrecisionLoss = true; }
var binKeyList = decompress(data, compression);
var strKeyList = Uint8ArrayToString(binKeyList);
// replace numbers to strings, to avoid losing precision
if (avoidPrecisionLoss)
strKeyList = strKeyList.replace(/\d+/g, '"$&"');
return JSON.parse(strKeyList);
}
exports.parseKeyList = parseKeyList;
/**
* Decode, decompress and parse the provided 'data' into a Bitmap object
*
* @param data - base64 encoded string
* @param compression - 1 GZIP, 2 ZLIB
* @returns Bitmap
* @throws if data string cannot be decoded or decompressed
*/
function parseBitmap(data, compression) {
return decompress(data, compression);
}
exports.parseBitmap = parseBitmap;
/**
* Check if the 'bitmap' bit at 'hash64hex' position is 1
*
* @param bitmap - Uint8Array bitmap
* @param hash64hex - 16-chars string, representing a number in hexa
* @returns whether the provided 'hash64hex' index is set in the bitmap
*/
function isInBitmap(bitmap, hash64hex) {
// using the lowest 32 bits as index, to avoid losing precision when converting to number
var index = parseInt(hash64hex.slice(8), 16) % (bitmap.length * 8);
var internal = Math.floor(index / 8);
var offset = index % 8;
return (bitmap[internal] & 1 << offset) > 0;
}
exports.isInBitmap = isInBitmap;
/**
* Parse feature flags notifications for instant feature flag updates
*/
function parseFFUpdatePayload(compression, data) {
return compression > 0 ?
parseKeyList(data, compression, false) :
JSON.parse((0, base64_1.decodeFromBase64)(data));
}
exports.parseFFUpdatePayload = parseFFUpdatePayload;
var DEFAULT_MAX_INTERVAL = 60000;
function getDelay(parsedData, matchingKey) {
if (parsedData.h === 0)
return 0;
var interval = parsedData.i || DEFAULT_MAX_INTERVAL;
var seed = parsedData.s || 0;
return (0, murmur3_1.hash)(matchingKey, seed) % interval;
}
exports.getDelay = getDelay;
;