@azure/msal-browser
Version:
Microsoft Authentication Library for js
128 lines (125 loc) • 5.77 kB
JavaScript
/*! @azure/msal-browser v5.6.3 2026-04-01 */
;
import { PerformanceClient, Constants, Logger } from '@azure/msal-common/browser';
import { name, version } from '../packageMetadata.mjs';
import { BrowserCacheLocation } from '../utils/BrowserConstants.mjs';
import { createNewGuid } from '../crypto/BrowserCrypto.mjs';
import { BROWSER_PERF_ENABLED_KEY } from '../cache/CacheKeys.mjs';
import { getNetworkInfo } from '../utils/MsalFrameStatsUtils.mjs';
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
/**
* Returns browser performance measurement module if session flag is enabled. Returns undefined otherwise.
*/
function getPerfMeasurementModule() {
let sessionStorage;
try {
sessionStorage = window[BrowserCacheLocation.SessionStorage];
const perfEnabled = sessionStorage?.getItem(BROWSER_PERF_ENABLED_KEY);
if (Number(perfEnabled) === 1) {
return import('./BrowserPerformanceMeasurement.mjs');
}
// Mute errors if it's a non-browser environment or cookies are blocked.
}
catch (e) { }
return undefined;
}
/**
* Returns boolean, indicating whether browser supports window.performance.now() function.
*/
function supportsBrowserPerformanceNow() {
return (typeof window !== "undefined" &&
typeof window.performance !== "undefined" &&
typeof window.performance.now === "function");
}
/**
* Returns event duration in milliseconds using window performance API if available. Returns undefined otherwise.
* @param startTime {DOMHighResTimeStamp | undefined}
* @returns {number | undefined}
*/
function getPerfDurationMs(startTime) {
if (!startTime || !supportsBrowserPerformanceNow()) {
return undefined;
}
return Math.round(window.performance.now() - startTime);
}
class BrowserPerformanceClient extends PerformanceClient {
constructor(configuration, intFields) {
super(configuration.auth.clientId, configuration.auth.authority || `${Constants.DEFAULT_AUTHORITY}`, new Logger(configuration.system?.loggerOptions || {}, name, version), name, version, configuration.telemetry?.application || {
appName: "",
appVersion: "",
}, intFields);
}
generateId() {
return createNewGuid();
}
getPageVisibility() {
return document.visibilityState?.toString() || null;
}
getOnlineStatus() {
return typeof navigator !== "undefined" ? navigator.onLine : null;
}
deleteIncompleteSubMeasurements(inProgressEvent) {
void getPerfMeasurementModule()?.then((module) => {
const rootEvent = this.eventsByCorrelationId.get(inProgressEvent.event.correlationId);
const isRootEvent = rootEvent &&
rootEvent.eventId === inProgressEvent.event.eventId;
const incompleteMeasurements = [];
if (isRootEvent && rootEvent?.incompleteSubMeasurements) {
rootEvent.incompleteSubMeasurements.forEach((subMeasurement) => {
incompleteMeasurements.push({ ...subMeasurement });
});
}
// Clean up remaining marks for incomplete sub-measurements
module.BrowserPerformanceMeasurement.flushMeasurements(inProgressEvent.event.correlationId, incompleteMeasurements);
});
}
/**
* Starts measuring performance for a given operation. Returns a function that should be used to end the measurement.
* Also captures browser page visibilityState.
*
* @param {PerformanceEvents} measureName
* @param {?string} [correlationId]
* @returns {((event?: Partial<PerformanceEvent>) => PerformanceEvent| null)}
*/
startMeasurement(measureName, correlationId) {
// Capture page visibilityState and then invoke start/end measurement
const startPageVisibility = this.getPageVisibility();
const startOnlineStatus = this.getOnlineStatus();
const inProgressEvent = super.startMeasurement(measureName, correlationId);
const startTime = supportsBrowserPerformanceNow()
? window.performance.now()
: undefined;
const browserMeasurement = getPerfMeasurementModule()?.then((module) => {
return new module.BrowserPerformanceMeasurement(measureName, inProgressEvent.event.correlationId);
});
void browserMeasurement?.then((measurement) => measurement.startMeasurement());
return {
...inProgressEvent,
end: (event, error, account) => {
const networkInfo = getNetworkInfo();
const res = inProgressEvent.end({
...event,
startPageVisibility,
startOnlineStatus,
endPageVisibility: this.getPageVisibility(),
durationMs: getPerfDurationMs(startTime),
networkEffectiveType: networkInfo.effectiveType,
networkRtt: networkInfo.rtt,
}, error, account);
void browserMeasurement?.then((measurement) => measurement.endMeasurement());
this.deleteIncompleteSubMeasurements(inProgressEvent);
return res;
},
discard: () => {
inProgressEvent.discard();
void browserMeasurement?.then((measurement) => measurement.flushMeasurement());
this.deleteIncompleteSubMeasurements(inProgressEvent);
},
};
}
}
export { BrowserPerformanceClient };
//# sourceMappingURL=BrowserPerformanceClient.mjs.map