configcat-common
Version:
ConfigCat is a configuration as a service that lets you manage your features and configurations without actually deploying new code.
153 lines (152 loc) • 5.76 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseFloatStrict = exports.utf8Encode = exports.isPromiseLike = exports.formatStringList = exports.isStringArray = exports.isArray = exports.throwError = exports.errorToString = exports.delay = exports.AbortToken = void 0;
// NOTE: Normally, we'd just use AbortController/AbortSignal, however that may not be available on all platforms,
// and we don't want to include a complete polyfill. So we implement a simplified version that fits our use case.
var AbortToken = /** @class */ (function () {
function AbortToken() {
this.callbacks = [];
}
Object.defineProperty(AbortToken.prototype, "aborted", {
get: function () { return !this.callbacks; },
enumerable: false,
configurable: true
});
AbortToken.prototype.abort = function () {
if (!this.aborted) {
var callbacks = this.callbacks;
this.callbacks = null;
for (var _i = 0, callbacks_1 = callbacks; _i < callbacks_1.length; _i++) {
var callback = callbacks_1[_i];
callback();
}
}
};
AbortToken.prototype.registerCallback = function (callback) {
var _this = this;
if (this.aborted) {
callback();
return function () { };
}
this.callbacks.push(callback);
return function () {
var callbacks = _this.callbacks;
var index;
if (callbacks && (index = callbacks.indexOf(callback)) >= 0) {
callbacks.splice(index, 1);
}
};
};
return AbortToken;
}());
exports.AbortToken = AbortToken;
function delay(delayMs, abortToken) {
var timerId;
return new Promise(function (resolve) {
var unregisterAbortCallback = abortToken === null || abortToken === void 0 ? void 0 : abortToken.registerCallback(function () {
clearTimeout(timerId);
resolve(false);
});
timerId = setTimeout(function () {
unregisterAbortCallback === null || unregisterAbortCallback === void 0 ? void 0 : unregisterAbortCallback();
resolve(true);
}, delayMs);
});
}
exports.delay = delay;
function errorToString(err, includeStackTrace) {
if (includeStackTrace === void 0) { includeStackTrace = false; }
return err instanceof Error
? includeStackTrace && err.stack ? err.stack : err.toString()
: err + "";
}
exports.errorToString = errorToString;
function throwError(err) {
throw err;
}
exports.throwError = throwError;
function isArray(value) {
// See also: https://github.com/microsoft/TypeScript/issues/17002#issuecomment-1477626624
return Array.isArray(value);
}
exports.isArray = isArray;
function isStringArray(value) {
return isArray(value) && !value.some(function (item) { return typeof item !== "string"; });
}
exports.isStringArray = isStringArray;
function formatStringList(items, maxLength, getOmittedItemsText, separator) {
if (maxLength === void 0) { maxLength = 0; }
if (separator === void 0) { separator = ", "; }
var length = items.length;
if (!length) {
return "";
}
var appendix = "";
if (maxLength > 0 && length > maxLength) {
items = items.slice(0, maxLength);
if (getOmittedItemsText) {
appendix = getOmittedItemsText(length - maxLength);
}
}
return "'" + items.join("'" + separator + "'") + "'" + appendix;
}
exports.formatStringList = formatStringList;
function isPromiseLike(obj) {
var _a;
// See also: https://stackoverflow.com/a/27746324/8656352
return typeof ((_a = obj) === null || _a === void 0 ? void 0 : _a.then) === "function";
}
exports.isPromiseLike = isPromiseLike;
function utf8Encode(text) {
function codePointAt(text, index) {
var ch = text.charCodeAt(index);
if (0xD800 <= ch && ch < 0xDC00) { // is high surrogate?
var nextCh = text.charCodeAt(index + 1);
if (0xDC00 <= nextCh && nextCh <= 0xDFFF) { // is low surrogate?
return (ch << 10) + nextCh - 0x35FDC00;
}
}
return ch;
}
var utf8text = "", chunkStart = 0;
var fromCharCode = String.fromCharCode;
var i;
for (i = 0; i < text.length; i++) {
var cp = codePointAt(text, i);
if (cp <= 0x7F) {
continue;
}
// See also: https://stackoverflow.com/a/6240184/8656352
utf8text += text.slice(chunkStart, i);
if (cp <= 0x7FF) {
utf8text += fromCharCode(0xC0 | (cp >> 6));
utf8text += fromCharCode(0x80 | (cp & 0x3F));
}
else if (cp <= 0xFFFF) {
utf8text += fromCharCode(0xE0 | (cp >> 12));
utf8text += fromCharCode(0x80 | ((cp >> 6) & 0x3F));
utf8text += fromCharCode(0x80 | (cp & 0x3F));
}
else {
utf8text += fromCharCode(0xF0 | (cp >> 18));
utf8text += fromCharCode(0x80 | ((cp >> 12) & 0x3F));
utf8text += fromCharCode(0x80 | ((cp >> 6) & 0x3F));
utf8text += fromCharCode(0x80 | (cp & 0x3F));
++i;
}
chunkStart = i + 1;
}
return utf8text += text.slice(chunkStart, i);
}
exports.utf8Encode = utf8Encode;
function parseFloatStrict(value) {
// NOTE: JS's float to string conversion is too forgiving, it accepts hex numbers and ignores invalid characters after the number.
if (typeof value === "number") {
return value;
}
if (typeof value !== "string" || !value.length || /^\s*$|^\s*0[^\d.e]/.test(value)) {
return NaN;
}
return +value;
}
exports.parseFloatStrict = parseFloatStrict;