+ public static insertAt = (str: string, subStr: string, pos: number): string =>
+ `${str.slice(0, pos)}${subStr}${str.slice(pos)}`;
+
+ /**
+ * @param [retryNumber=0]
+ * @returns delay in milliseconds
+ */
+ public static exponentialDelay(retryNumber = 0): number {
+ const delay = Math.pow(2, retryNumber) * 100;
+ const randomSum = delay * 0.2 * Utils.secureRandom(); // 0-20% of the delay
+ return delay + randomSum;
+ }
+
+ /**
+ * Convert websocket error code to human readable string message
+ *
+ * @param code websocket error code
+ * @returns human readable string message
+ */
+ public static getWebSocketCloseEventStatusString(code: number): string {
+ if (code >= 0 && code <= 999) {
+ return '(Unused)';
+ } else if (code >= 1016) {
+ if (code <= 1999) {
+ return '(For WebSocket standard)';
+ } else if (code <= 2999) {
+ return '(For WebSocket extensions)';
+ } else if (code <= 3999) {
+ return '(For libraries and frameworks)';
+ } else if (code <= 4999) {
+ return '(For applications)';
+ }
+ }
+ if (!Utils.isUndefined(WebSocketCloseEventStatusString[code])) {
+ return WebSocketCloseEventStatusString[code] as string;
+ }
+ return '(Unknown)';
+ }
+
+ public static workerPoolInUse(): boolean {
+ return [WorkerProcessType.DYNAMIC_POOL, WorkerProcessType.STATIC_POOL].includes(
+ Configuration.getWorkerProcess()
+ );
+ }
+
+ public static workerDynamicPoolInUse(): boolean {
+ return Configuration.getWorkerProcess() === WorkerProcessType.DYNAMIC_POOL;
+ }
+
+ public static async promiseWithTimeout<T>(
+ promise: Promise<T>,
+ timeoutMs: number,
+ timeoutError: Error,
+ timeoutCallback: () => void = () => {
+ /* This is intentional */
+ }
+ ): Promise<T> {
+ // Create a timeout promise that rejects in timeout milliseconds
+ const timeoutPromise = new Promise<never>((_, reject) => {
+ setTimeout(() => {
+ timeoutCallback();
+ reject(timeoutError);
+ }, timeoutMs);
+ });
+
+ // Returns a race between timeout promise and the passed promise
+ return Promise.race<T>([promise, timeoutPromise]);
+ }
+
+ /**
+ * Generate a cryptographically secure random number in the [0,1[ range
+ *
+ * @returns
+ */
+ public static secureRandom(): number {
+ return crypto.randomBytes(4).readUInt32LE() / 0x100000000;
+ }