+import { randomBytes, randomInt, randomUUID, webcrypto } from 'node:crypto';
+import { env } from 'node:process';
+import { inspect } from 'node:util';
+
+import {
+ formatDuration,
+ hoursToMinutes,
+ hoursToSeconds,
+ isDate,
+ millisecondsToHours,
+ millisecondsToMinutes,
+ millisecondsToSeconds,
+ minutesToSeconds,
+ secondsToMilliseconds,
+} from 'date-fns';
+
+import { Constants } from './Constants';
+import { type TimestampedData, WebSocketCloseEventStatusString } from '../types';
+
+export const logPrefix = (prefixString = ''): string => {
+ return `${new Date().toLocaleString()}${prefixString}`;
+};
+
+export const generateUUID = (): string => {
+ return randomUUID();
+};
+
+export const validateUUID = (uuid: string): boolean => {
+ return /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/.test(
+ uuid,
+ );
+};
+
+export const sleep = async (milliSeconds: number): Promise<NodeJS.Timeout> => {
+ return new Promise<NodeJS.Timeout>((resolve) => setTimeout(resolve as () => void, milliSeconds));
+};
+
+export const formatDurationMilliSeconds = (duration: number): string => {
+ duration = convertToInt(duration);
+ const days = Math.floor(duration / (24 * 3600 * 1000));
+ const hours = Math.floor(millisecondsToHours(duration) - days * 24);
+ const minutes = Math.floor(
+ millisecondsToMinutes(duration) - days * 24 * 60 - hoursToMinutes(hours),
+ );
+ const seconds = Math.floor(
+ millisecondsToSeconds(duration) -
+ days * 24 * 3600 -
+ hoursToSeconds(hours) -
+ minutesToSeconds(minutes),
+ );
+ return formatDuration({
+ days,
+ hours,
+ minutes,
+ seconds,
+ });
+};
+
+export const formatDurationSeconds = (duration: number): string => {
+ return formatDurationMilliSeconds(secondsToMilliseconds(duration));
+};
+
+// More efficient time validation function than the one provided by date-fns
+export const isValidTime = (date: unknown): boolean => {
+ if (typeof date === 'number') {
+ return !isNaN(date);
+ } else if (isDate(date)) {
+ return !isNaN((date as Date).getTime());