{"version":3,"file":"ClockValidatorApp-BVj5YWPV.js","sources":["../../Client/Common/heartbeat.ts","../../Client/features/clockValidator/ClockValidatorApp.tsx"],"sourcesContent":["import { Log } from './Log';\nimport { IApproximateWaitingTimeResponse } from '../Common/interfaces';\n\nexport class HeartbeatRequest {\n public RequestWaitingTime = false;\n public RequestWaitingroomMessages = false;\n}\n\nexport interface HeartbeatResponse {\n Message?: string;\n WaitingTime?: IApproximateWaitingTimeResponse;\n Duration?: number;\n BitRate?: number;\n Failed?: boolean;\n}\n\nexport class Heartbeat {\n public static isStarted = false;\n public static isFetching = false;\n public static heartbeatRequest: HeartbeatRequest = new HeartbeatRequest();\n public static start(\n videoSessionId: number,\n heartbeatRequest: HeartbeatRequest,\n onHeartBeatResponseCallBack: (response: HeartbeatResponse) => void,\n ): void {\n Heartbeat.heartbeatRequest = heartbeatRequest;\n if (this.isStarted) {\n Log.warn('Heartbeat already started', { videoSessionId });\n return;\n }\n this.isStarted = true;\n Heartbeat.loop(\n videoSessionId,\n onHeartBeatResponseCallBack,\n Heartbeat.heartbeatRequest,\n );\n setInterval(\n () =>\n Heartbeat.loop(\n videoSessionId,\n onHeartBeatResponseCallBack,\n Heartbeat.heartbeatRequest,\n ),\n 3000,\n );\n }\n\n private static loop(\n videoSessionId: number,\n onHeartBeatResponseCallBack: (data: any) => void,\n heartbeatRequest: HeartbeatRequest,\n ): void {\n if (this.isFetching) {\n return;\n }\n this.isFetching = true;\n\n performance.mark('hb-start');\n fetch('/api/consultations/heartbeat/' + videoSessionId, {\n method: 'POST',\n cache: 'no-cache',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(heartbeatRequest),\n })\n .then(async (response) => {\n let hbr: HeartbeatResponse = {};\n let nbytes = 0;\n if (response.ok) {\n hbr = await response.json();\n nbytes = Number.parseInt(\n response.headers.get('Content-length'),\n );\n } else {\n hbr.Failed = true;\n }\n\n // Get the duratin for the fetch call\n hbr.Duration = performance.measure(\n 'hb-start-to-end',\n 'hb-start',\n ).duration;\n\n // Poor man's bit rate calculation. However, it is a number which depends\n // on body size of the response body and is therefore more relaible then\n // Duration. In case of an request error, response body size will be zero\n // and bit rate will be set to zero as well.\n hbr.BitRate = Math.floor(\n (nbytes * 8) / (hbr.Duration / 1000.0),\n );\n\n // Clear marks and measurments\n performance.clearMarks('hb-start');\n performance.clearMeasures('hb-start-to-end');\n\n return Promise.resolve(hbr);\n })\n .then(onHeartBeatResponseCallBack)\n .catch((exception) => {\n //Swallowing any exception for heartbeat because they are not actionable.\n })\n .finally(() => {\n this.isFetching = false;\n });\n }\n}\n","import * as React from 'react';\nimport { createRoot } from 'react-dom/client';\nimport { Log } from '../../Common/Log';\nimport { Texts } from '../../Common/Texts';\n\nexport function ClockValidatorApp(containerQuery: string) {\n const elm = document.querySelector(containerQuery);\n const root = createRoot(elm);\n root.render();\n}\n\nfunction ClockValidator() {\n const [showWarning, setShowWarning] = React.useState(false);\n\n React.useEffect(() => {\n const fetchData = async () => {\n const data = await fetch('/api/health/time');\n const serverTime = new Date(await data.json()).getTime();\n const clientTime = new Date().getTime();\n const diffMs = Math.abs(serverTime - clientTime);\n const twoMinutesInMs = 1000 * 60 * 2;\n setShowWarning(diffMs >= twoMinutesInMs);\n };\n\n fetchData().catch(Log.error);\n });\n\n return (\n showWarning && (\n
\n {Texts.get('ClockValidatorError')}\n
\n )\n );\n}\n"],"names":["HeartbeatRequest","_Heartbeat","videoSessionId","heartbeatRequest","onHeartBeatResponseCallBack","Log","response","hbr","nbytes","exception","Heartbeat","ClockValidatorApp","containerQuery","elm","createRoot","jsx","ClockValidator","showWarning","setShowWarning","React.useState","React.useEffect","data","serverTime","clientTime","diffMs","twoMinutesInMs","Texts"],"mappings":"oEAGO,MAAMA,CAAiB,CAAvB,aAAA,CACH,KAAO,mBAAqB,GAC5B,KAAO,2BAA6B,EAAA,CACxC,CAUO,MAAMC,EAAN,MAAMA,CAAU,CAInB,OAAc,MACVC,EACAC,EACAC,EACI,CAEJ,GADAH,EAAU,iBAAmBE,EACzB,KAAK,UAAW,CAChBE,EAAI,KAAK,4BAA6B,CAAE,eAAAH,CAAA,CAAgB,EACxD,MAAA,CAEJ,KAAK,UAAY,GACPD,EAAA,KACNC,EACAE,EACAH,EAAU,gBACd,EACA,YACI,IACIA,EAAU,KACNC,EACAE,EACAH,EAAU,gBACd,EACJ,GACJ,CAAA,CAGJ,OAAe,KACXC,EACAE,EACAD,EACI,CACA,KAAK,aAGT,KAAK,WAAa,GAElB,YAAY,KAAK,UAAU,EAC3B,MAAM,gCAAkCD,EAAgB,CACpD,OAAQ,OACR,MAAO,WACP,QAAS,CACL,eAAgB,kBACpB,EACA,KAAM,KAAK,UAAUC,CAAgB,CAAA,CACxC,EACI,KAAK,MAAOG,GAAa,CACtB,IAAIC,EAAyB,CAAC,EAC1BC,EAAS,EACb,OAAIF,EAAS,IACHC,EAAA,MAAMD,EAAS,KAAK,EAC1BE,EAAS,OAAO,SACZF,EAAS,QAAQ,IAAI,gBAAgB,CACzC,GAEAC,EAAI,OAAS,GAIjBA,EAAI,SAAW,YAAY,QACvB,kBACA,UAAA,EACF,SAMFA,EAAI,QAAU,KAAK,MACdC,EAAS,GAAMD,EAAI,SAAW,IACnC,EAGA,YAAY,WAAW,UAAU,EACjC,YAAY,cAAc,iBAAiB,EAEpC,QAAQ,QAAQA,CAAG,CAC7B,CAAA,EACA,KAAKH,CAA2B,EAChC,MAAOK,GAAc,CAAA,CAErB,EACA,QAAQ,IAAM,CACX,KAAK,WAAa,EAAA,CACrB,EAAA,CAEb,EAzFIR,EAAc,UAAY,GAC1BA,EAAc,WAAa,GACbA,EAAA,iBAAqC,IAAID,EAHpD,IAAMU,EAANT,ECXA,SAASU,EAAkBC,EAAwB,CAChD,MAAAC,EAAM,SAAS,cAAcD,CAAc,EACpCE,EAAWD,CAAG,EACtB,OAAQE,EAAAA,IAAAC,EAAA,CAAe,CAAA,CAAE,CAClC,CAEA,SAASA,GAAiB,CACtB,KAAM,CAACC,EAAaC,CAAc,EAAIC,EAAAA,SAAe,EAAK,EAE1DC,OAAAA,EAAAA,UAAgB,IAAM,EACA,SAAY,CACpB,MAAAC,EAAO,MAAM,MAAM,kBAAkB,EACrCC,EAAa,IAAI,KAAK,MAAMD,EAAK,KAAK,CAAC,EAAE,QAAQ,EACjDE,EAAa,IAAI,KAAK,EAAE,QAAQ,EAChCC,EAAS,KAAK,IAAIF,EAAaC,CAAU,EACzCE,EAAiB,IAAO,GAAK,EACnCP,EAAeM,GAAUC,CAAc,CAC3C,KAEY,MAAMpB,EAAI,KAAK,CAAA,CAC9B,EAGGY,SACK,MAAI,CAAA,UAAU,sEACV,SAAMS,EAAA,IAAI,qBAAqB,CACpC,CAAA,CAGZ"}