configcat-common
Version:
ConfigCat is a configuration as a service that lets you manage your features and configurations without actually deploying new code.
185 lines (184 loc) • 7.13 kB
JavaScript
// 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;
}());
export { AbortToken };
export 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);
});
}
export var getMonotonicTimeMs = typeof performance !== "undefined" && typeof performance.now === "function"
? function () { return performance.now(); }
: function () { return new Date().getTime(); };
/** Formats error in a similar way to Chromium-based browsers. */
export function errorToString(err, includeStackTrace) {
if (includeStackTrace === void 0) { includeStackTrace = false; }
return err instanceof Error ? visit(err, "") : "" + err;
function visit(err, indent, visited) {
var errString = err.toString();
var s = (!indent ? indent : indent.substring(4) + "--> ") + errString;
if (includeStackTrace && err.stack) {
var stack = err.stack.trim();
// NOTE: Some JS runtimes (e.g. V8) includes the error in the stack trace, some don't (e.g. SpiderMonkey).
if (stack.lastIndexOf(errString, 0) === 0) {
stack = stack.substring(errString.length).trim();
}
s += "\n" + stack.replace(/^\s*(?:at\s)?/gm, indent + " at ");
}
if (typeof AggregateError !== "undefined" && err instanceof AggregateError) {
(visited !== null && visited !== void 0 ? visited : (visited = [])).push(err);
for (var _i = 0, _a = err.errors; _i < _a.length; _i++) {
var innerErr = _a[_i];
if (innerErr instanceof Error) {
if (visited.indexOf(innerErr) >= 0) {
continue;
}
s += "\n" + visit(innerErr, indent + " ", visited);
}
else {
s += "\n" + indent + "--> " + innerErr;
}
}
visited.pop();
}
return s;
}
}
export function throwError(err) {
throw err;
}
export function isObject(value) {
return value !== null && typeof value === "object" && !isArray(value);
}
export function isArray(value) {
// See also: https://github.com/microsoft/TypeScript/issues/17002#issuecomment-1477626624
return Array.isArray(value);
}
export function isStringArray(value) {
return isArray(value) && !value.some(function (item) { return typeof item !== "string"; });
}
export 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;
}
export 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";
}
export 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);
}
export 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.eE]/.test(value)) {
return NaN;
}
return +value;
}
export function shallowClone(obj, propertyReplacer) {
var clone = {};
for (var key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
var value = obj[key];
clone[key] = propertyReplacer ? propertyReplacer(key, value) : value;
}
}
return clone;
}