@splitsoftware/splitio-commons
Version:
Split JavaScript SDK common components
91 lines (90 loc) • 3.43 kB
JavaScript
import { algorithms } from '../../utils/decompress';
import { decodeFromBase64 } from '../../utils/base64';
import { hash } from '../../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 = decodeFromBase64(data);
var binData = StringToUint8Array(compressData);
if (typeof algorithms === 'string')
throw new Error(algorithms);
if (compression === GZIP)
return algorithms.gunzipSync(binData);
if (compression === ZLIB)
return algorithms.unzlibSync(binData);
throw new Error("Invalid compression algorithm #".concat(compression));
}
/**
* Decode, decompress and parse the provided 'data' into an object of type T
*
* @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 parsed object
* @throws if data string cannot be decoded, decompressed or parsed
*/
export function parseCompressedData(data, compression, avoidPrecisionLoss) {
if (avoidPrecisionLoss === void 0) { avoidPrecisionLoss = true; }
var binData = decompress(data, compression);
var str = Uint8ArrayToString(binData);
// replace numbers to strings, to avoid losing precision (e.g., 64-bit IDs in KeyList)
if (avoidPrecisionLoss)
str = str.replace(/\d+/g, '"$&"');
return JSON.parse(str);
}
/**
* 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
*/
export function parseBitmap(data, compression) {
return decompress(data, compression);
}
/**
* 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
*/
export 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;
}
/**
* Parse feature flags notifications for instant feature flag updates
*/
export function parseFFUpdatePayload(compression, data) {
return compression > 0 ?
parseCompressedData(data, compression, false) :
JSON.parse(decodeFromBase64(data));
}
var DEFAULT_MAX_INTERVAL = 60000;
export function getDelay(parsedData, matchingKey) {
if (parsedData.h === 0)
return 0;
var interval = parsedData.i || DEFAULT_MAX_INTERVAL;
var seed = parsedData.s || 0;
return hash(matchingKey, seed) % interval;
}