[Beta] Fix issue with replacing a value (object) on the config which was clearing (setting to undefined) previous properties of the replaced instance. (#1933)

This commit is contained in:
Nev 2022-10-21 15:14:57 -07:00 коммит произвёл GitHub
Родитель 375a0e8686
Коммит 6f169ae7e7
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
38 изменённых файлов: 298 добавлений и 212 удалений

Просмотреть файл

@ -106,7 +106,7 @@
instrumentationKey: instrumentationKey,
endpointUrl: "http://localhost:9001/v2/track",
//extensions: [reactPlugin],
enableDebug: true,
enableDebug: false,
loggingLevelConsole: enableDebug ? 2 : 0,
loggingLevelTelemetry: enableDebug ? 2 : 1,
autoTrackPageVisitTime: true,
@ -115,7 +115,8 @@
enableUnhandledPromiseRejectionTracking: true,
enableCorsCorrelation: false,
enableRequestHeaderTracking: true,
enableResponseHeaderTracking: true
enableResponseHeaderTracking: true,
hello: "World"
}
});
@ -136,6 +137,15 @@
logMessage("onCfgChange 3 - called", "cfg");
});
appInsights.onCfgChange(function (details) {
if (details.cfg.enableDebug) {
logMessage("Debug Enable - " + details.cfg.loggingLevelConsole);
} else {
logMessage("Debug Not enabled!");
}
logMessage("onCfgChange 4 - called");
});
appInsights.loadAppInsights();
appInsights.trackPageView();

Просмотреть файл

@ -11,7 +11,7 @@ import {
dateNow, dumpObj, eLoggingSeverity, getExceptionName, getIEVersion, getJSON, getNavigator, getWindow, isArray, isBeaconsSupported,
isFetchSupported, isNullOrUndefined, isXhrSupported, mergeEvtNamespace, objExtend, objKeys, onConfigChange, useXDomainRequest
} from "@microsoft/applicationinsights-core-js";
import { isTruthy, objDeepFreeze, objDefineProp } from "@nevware21/ts-utils";
import { ITimerHandler, isTruthy, objDeepFreeze, objDefineProp, scheduleTimeout } from "@nevware21/ts-utils";
import {
DependencyEnvelopeCreator, EventEnvelopeCreator, ExceptionEnvelopeCreator, MetricEnvelopeCreator, PageViewEnvelopeCreator,
PageViewPerformanceEnvelopeCreator, TraceEnvelopeCreator
@ -129,7 +129,7 @@ export class Sender extends BaseTelemetryPlugin implements IChannelControlsAI {
let _retryAt: number; // The time to retry at in milliseconds from 1970/01/01 (this makes the timer calculation easy).
let _lastSend: number; // The time of the last send operation.
let _paused: boolean; // Flag indicating that the sending should be paused
let _timeoutHandle: any; // Handle to the timer for delayed sending of batches of data.
let _timeoutHandle: ITimerHandler; // Handle to the timer for delayed sending of batches of data.
let _serializer: Serializer;
let _stamp_specific_redirects: number;
let _headers: { [name: string]: string };
@ -964,7 +964,7 @@ export class Sender extends BaseTelemetryPlugin implements IChannelControlsAI {
const retryInterval = _retryAt ? Math.max(0, _retryAt - dateNow()) : 0;
const timerValue = Math.max(_maxBatchInterval, retryInterval);
_timeoutHandle = setTimeout(() => {
_timeoutHandle = scheduleTimeout(() => {
_timeoutHandle = null;
_self.triggerSend(true, null, SendRequestReason.NormalSchedule);
}, timerValue);
@ -972,7 +972,7 @@ export class Sender extends BaseTelemetryPlugin implements IChannelControlsAI {
}
function _clearScheduledTimer() {
clearTimeout(_timeoutHandle);
_timeoutHandle && _timeoutHandle.cancel();
_timeoutHandle = null;
_retryAt = null;
}

Просмотреть файл

@ -1,6 +1,7 @@
import { Assert } from "./Assert";
import { AITestClass } from "./AITestClass";
import { ITestContext } from "./TestCase";
import { scheduleTimeout } from "@nevware21/ts-utils";
export class PollingAssert {
/**
@ -23,11 +24,11 @@ export class PollingAssert {
Assert.ok(false, "assert didn't succeed for " + timeout + " seconds: " + assertDescription + "[" + (AITestClass.currentTestInfo ? AITestClass.currentTestInfo.name : "<null>") + "]");
nextTestStep();
} else {
setTimeout(polling, pollIntervalMs);
scheduleTimeout(polling, pollIntervalMs);
}
} catch (e) {
Assert.ok(true, "Polling exception - " + e);
setTimeout(polling, pollIntervalMs);
scheduleTimeout(polling, pollIntervalMs);
}
if (testContext.clock) {
@ -38,7 +39,7 @@ export class PollingAssert {
}
}
setTimeout(polling, pollIntervalMs);
scheduleTimeout(polling, pollIntervalMs);
if (testContext.clock) {
AITestClass.orgSetTimeout(() => {
testContext.clock.tick(pollIntervalMs);

Просмотреть файл

@ -2,7 +2,7 @@ import { Assert, AITestClass } from "@microsoft/ai-test-framework";
import * as pako from "pako";
export class AnalyticsExtensionSizeCheck extends AITestClass {
private readonly MAX_DEFLATE_SIZE = 21;
private readonly MAX_DEFLATE_SIZE = 22;
private readonly rawFilePath = "../dist/applicationinsights-analytics-js.min.js";
private readonly prodFilePaath = "../browser/applicationinsights-analytics-js.min.js"

Просмотреть файл

@ -21,7 +21,7 @@ import {
mergeEvtNamespace, objDefineAccessors, onConfigChange, safeGetCookieMgr, strUndefined, throwError
} from "@microsoft/applicationinsights-core-js";
import { PropertiesPlugin } from "@microsoft/applicationinsights-properties-js";
import { objDeepFreeze, objDefineProp } from "@nevware21/ts-utils";
import { objDeepFreeze, objDefineProp, scheduleTimeout, strIndexOf } from "@nevware21/ts-utils";
import { IAppInsightsInternal, PageViewManager } from "./Telemetry/PageViewManager";
import { PageViewPerformanceManager } from "./Telemetry/PageViewPerformanceManager";
import { PageVisitTimeManager } from "./Telemetry/PageVisitTimeManager";
@ -640,7 +640,7 @@ export class AnalyticsPlugin extends BaseTelemetryPlugin implements IAppInsights
let remoteData = envelope.baseData as IDependencyTelemetry;
if (remoteData) {
for (let i = 0; i < browserLinkPaths.length; i++) {
if (remoteData.target && remoteData.target.indexOf(browserLinkPaths[i]) >= 0) {
if (remoteData.target && strIndexOf(remoteData.target, browserLinkPaths[i]) >= 0) {
return false;
}
}
@ -778,7 +778,7 @@ export class AnalyticsPlugin extends BaseTelemetryPlugin implements IAppInsights
distributedTraceCtx.setName(dataSanitizeString(_self.diagLog(), traceLocationName));
}
setTimeout(((uri: string) => {
scheduleTimeout(((uri: string) => {
// todo: override start time so that it is not affected by autoRoutePVDelay
_self.trackPageView({ refUri: uri, properties: { duration: 0 } }); // SPA route change loading durations are undefined, so send 0
}).bind(this, _prevUri), _self.autoRoutePVDelay);

Просмотреть файл

@ -6,6 +6,7 @@ import { IPageViewPerformanceTelemetryInternal, dateTimeUtilsDuration, msToTimeS
import {
IAppInsightsCore, IDiagnosticLogger, _eInternalMessageId, _throwInternal, eLoggingSeverity, getNavigator, getPerformance, safeGetLogger
} from "@microsoft/applicationinsights-core-js";
import { strIndexOf } from "@nevware21/ts-utils";
const MAX_DURATION_ALLOWED = 3600000; // 1h
const botAgentNames = ["googlebot", "adsbot-google", "apis-google", "mediapartners-google"];
@ -62,7 +63,7 @@ function _shouldCollectDuration(...durations: number[]): boolean {
if (userAgent) {
for (let i = 0; i < botAgentNames.length; i++) {
isGoogleBot = isGoogleBot || userAgent.toLowerCase().indexOf(botAgentNames[i]) !== -1;
isGoogleBot = isGoogleBot || strIndexOf(userAgent.toLowerCase(), botAgentNames[i]) !== -1;
}
}

Просмотреть файл

@ -3,6 +3,7 @@
*/
import { getDocument, getLocation, getWindow, hasDocument, isFunction } from "@microsoft/applicationinsights-core-js";
import { scheduleTimeout } from "@nevware21/ts-utils";
import { IClickAnalyticsConfiguration, IOverrideValues } from "./Interfaces/Datamodel";
import { findClosestAnchor, isValueAssigned } from "./common/Utils";
@ -92,7 +93,7 @@ function onDomReadyDo(f: any) {
/// <param type='function'>function to call on domRead</param>
let doc = getDocument() || ({} as Document);
/in/.test(doc.readyState) ? setTimeout(() => {
/in/.test(doc.readyState) ? scheduleTimeout(() => {
onDomReadyDo(f);
}, 100) : f.call();
}

Просмотреть файл

@ -1,5 +1,6 @@
import dynamicProto from "@microsoft/dynamicproto-js";
import { arrForEach, arrIndexOf } from "@microsoft/applicationinsights-core-js";
import { ITimerHandler, scheduleTimeout } from "@nevware21/ts-utils";
import { LogEntry } from "./LogEntry";
import { FilterList } from "./filterList";
import { copySelectedTree } from "./helpers";
@ -195,13 +196,12 @@ export class Dashboard {
};
textFilterInput.onkeyup = (evt: Event) => {
if (keyupTimer != null) {
clearTimeout(keyupTimer);
}
keyupTimer && keyupTimer.cancel();
keyupTimer = null;
let newValue = textFilterInput.value;
if (newValue !== _self.getTextFilter()) {
keyupTimer = setTimeout(() => {
keyupTimer = scheduleTimeout(() => {
keyupTimer = null;
_self.setTextFilter(textFilterInput.value);
}, 200);
@ -216,7 +216,7 @@ export class Dashboard {
copyButton.onclick = copySelectedTree;
copyButton.ontouchend = copySelectedTree;
let keyupTimer: any = null;
let keyupTimer: ITimerHandler = null;
filterList = new FilterList(controlDiv, trackers.slice(0), () => _self.render());

Просмотреть файл

@ -1,6 +1,8 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
import { scheduleTimeout } from "@nevware21/ts-utils";
export class DebugBinParent {
public showChildren: boolean = false;
@ -120,6 +122,6 @@ export class DebugBin {
_self.elValue.innerText = `${++_self.value}`;
_self.parent.increment();
_self.elValue.className = "el-value incremented";
setTimeout(() => _self.elValue.className = "el-value", 1);
scheduleTimeout(() => _self.elValue.className = "el-value", 1);
}
}

Просмотреть файл

@ -8,6 +8,7 @@ import {
} from "@microsoft/applicationinsights-core-js";
import { IDependencyListenerDetails } from "../../../src/DependencyListener";
import { FakeXMLHttpRequest } from "@microsoft/ai-test-framework/dist-esm/src/AITestClass";
import { setBypassLazyCache } from "@nevware21/ts-utils";
interface IFetchArgs {
input: RequestInfo,
@ -2103,6 +2104,7 @@ export class AjaxTests extends AITestClass {
name: "Ajax: test ajax duration is calculated correctly",
test: () => {
var initialPerformance = window.performance;
setBypassLazyCache(true);
this._ajax = new AjaxMonitor();
try {
// Mocking window performance (sinon doesn't have it).
@ -2545,6 +2547,7 @@ export class AjaxPerfTrackTests extends AITestClass {
testThis._initialPerformance = performance;
testThis._perfEntries = [];
setBypassLazyCache(true);
// Add polyfil / mock
(<any>window).performance = {

Просмотреть файл

@ -15,7 +15,7 @@ import {
dumpObj, eLoggingSeverity, eventOn, generateW3CId, getExceptionName, getGlobal, getIEVersion, getLocation, getPerformance, isFunction,
isNullOrUndefined, isString, isXhrSupported, mergeEvtNamespace, onConfigChange, strPrototype, strTrim
} from "@microsoft/applicationinsights-core-js";
import { objFreeze } from "@nevware21/ts-utils";
import { objFreeze, scheduleTimeout, strIndexOf } from "@nevware21/ts-utils";
import { DependencyInitializerFunction, IDependencyInitializerDetails, IDependencyInitializerHandler } from "./DependencyInitializer";
import {
DependencyListenerFunction, IDependencyHandler, IDependencyListenerContainer, IDependencyListenerDetails, IDependencyListenerHandler
@ -141,7 +141,7 @@ function _createErrorCallbackFunc(ajaxMonitorInstance:AjaxMonitor, internalMessa
function _indexOf(value:string, match:string):number {
if (value && match) {
return value.indexOf(match);
return strIndexOf(value, match);
}
return -1;
@ -1048,7 +1048,7 @@ export class AjaxMonitor extends BaseTelemetryPlugin implements IDependenciesPlu
// We need to wait for the browser to populate the window.performance entry
// This needs to be at least 1ms as waiting <= 1 (on firefox) is not enough time for fetch or xhr,
// this is a scheduling issue for the browser implementation
setTimeout(locateResourceTiming, retryDelay);
scheduleTimeout(locateResourceTiming, retryDelay);
}
} catch (e) {
reportError(e);

Просмотреть файл

@ -4,6 +4,7 @@
import {
IDiagnosticLogger, arrForEach, arrMap, isArray, isError, isFunction, isNullOrUndefined, isObject, isString, strTrim
} from "@microsoft/applicationinsights-core-js";
import { strIndexOf } from "@nevware21/ts-utils";
import { strNotSpecified } from "../Constants";
import { FieldType } from "../Enums";
import { IExceptionData } from "../Interfaces/Contracts/IExceptionData";
@ -66,7 +67,7 @@ function _formatMessage(theEvent: any, errorType: string) {
}
// Automatically add the error type to the message if it does already appear to be present
if (errorType && errorType !== "String" && errorType !== "Object" && errorType !== "Error" && (evtMessage || "").indexOf(errorType) === -1) {
if (errorType && errorType !== "String" && errorType !== "Object" && errorType !== "Error" && strIndexOf(evtMessage || "", errorType) === -1) {
evtMessage = errorType + ": " + evtMessage;
}
@ -302,7 +303,7 @@ export function _formatErrorCode(errorObj:any) {
result = _stringify(errorObj, true);
}
if (result.indexOf(errorType) !== 0 && errorType !== "String") {
if (strIndexOf(result, errorType) !== 0 && errorType !== "String") {
return errorType + ":" + result;
}

Просмотреть файл

@ -5,6 +5,7 @@ import {
IDiagnosticLogger, IDistributedTraceContext, arrForEach, arrIndexOf, dateNow, getPerformance, isNullOrUndefined, isValidSpanId,
isValidTraceId
} from "@microsoft/applicationinsights-core-js";
import { strIndexOf } from "@nevware21/ts-utils";
import { DEFAULT_BREEZE_ENDPOINT, DEFAULT_BREEZE_PATH } from "./Constants";
import { ITelemetryTrace } from "./Interfaces/Context/ITelemetryTrace";
import { ICorrelationConfig } from "./Interfaces/ICorrelationConfig";
@ -54,7 +55,7 @@ export function correlationIdCanIncludeCorrelationHeader(config: ICorrelationCon
}
let requestHost = urlParseUrl(requestUrl).host.toLowerCase();
if (requestHost && (requestHost.indexOf(":443") !== -1 || requestHost.indexOf(":80") !== -1)) {
if (requestHost && (strIndexOf(requestHost, ":443") !== -1 || strIndexOf(requestHost, ":80") !== -1)) {
// [Bug #1260] IE can include the port even for http and https URLs so if present
// try and parse it to remove if it matches the default protocol port
requestHost = (urlParseFullHost(requestUrl, true) || "").toLowerCase();

Просмотреть файл

@ -1,7 +1,8 @@
import { Assert, AITestClass } from "@microsoft/ai-test-framework";
import { _eInternalMessageId } from "../../../src/JavaScriptSDK.Enums/LoggingEnums";
import { _InternalLogMessage } from "../../../src/JavaScriptSDK/DiagnosticLogger";
import { isObject, isPlainObject, isString, objForEachKey, objKeys, optimizeObject, setValue } from "../../../src/JavaScriptSDK/HelperFuncs";
import { objForEachKey, optimizeObject, setValue } from "../../../src/JavaScriptSDK/HelperFuncs";
import { isObject, isPlainObject, isString, objKeys } from "@nevware21/ts-utils";
interface PerfMeasurements {
duration: number;

Просмотреть файл

@ -5,12 +5,11 @@ import { IConfigDefaults } from "../../../src/Config/IConfigDefaults";
import { IConfiguration } from "../../../src/JavaScriptSDK.Interfaces/IConfiguration";
import { getDynamicConfigHandler } from "../../../src/Config/DynamicSupport";
import { createDynamicConfig, onConfigChange } from "../../../src/Config/DynamicConfig";
import { arrForEach, dumpObj, isArray, isFunction, objForEachKey, objKeys } from "@nevware21/ts-utils";
import { isPlainObject } from "../../../src/JavaScriptSDK/HelperFuncs";
import { arrForEach, dumpObj, isArray, isFunction, objForEachKey, objKeys, isPlainObject } from "@nevware21/ts-utils";
import { IAppInsightsCore } from "../../../src/JavaScriptSDK.Interfaces/IAppInsightsCore";
import { INotificationManager } from "../../../src/JavaScriptSDK.Interfaces/INotificationManager";
import { IPerfManager } from "../../../src/JavaScriptSDK.Interfaces/IPerfManager";
import { AppInsightsCore } from "../../../src/applicationinsights-core-js";
import { AppInsightsCore, setEnableEnvMocks } from "../../../src/applicationinsights-core-js";
import { ITelemetryItem } from "../../../src/JavaScriptSDK.Interfaces/ITelemetryItem";
import { ITelemetryPluginChain } from "../../../src/JavaScriptSDK.Interfaces/ITelemetryPluginChain";
import { ITelemetryPlugin } from "../../../src/JavaScriptSDK.Interfaces/ITelemetryPlugin";
@ -490,6 +489,70 @@ export class DynamicConfigTests extends AITestClass {
}
});
this.testCase({
name: "onCfgChange only calls accessed changes",
useFakeTimers: true,
test: () => {
let theConfig: IConfiguration = {
instrumentationKey: "testiKey",
endpointUrl: "https://localhost:9001",
enableDebugExceptions: false,
loggingLevelConsole: 1
};
const channelPlugin = new TestChannelPlugin();
let core = new AppInsightsCore();
let expectedEnableDebugExceptions = theConfig.enableDebugExceptions;
let expectedLoggingLevel = theConfig.loggingLevelConsole;
core.initialize(theConfig, [channelPlugin]);
let onChangeCalled = 0;
let handler = core.onCfgChange((details) => {
onChangeCalled ++;
Assert.equal(expectedEnableDebugExceptions, details.cfg.enableDebugExceptions, "Expect the endpoint to be set");
if (details.cfg.enableDebugExceptions) {
Assert.equal(expectedLoggingLevel, details.cfg.loggingLevelConsole, "Expected the logging level console")
}
});
Assert.equal(1, onChangeCalled, "OnCfgChange was not called");
// This should not trigger the listener as enableDebugExceptions was false
expectedLoggingLevel = 99;
core.config.loggingLevelConsole = expectedLoggingLevel;
this.clock.tick(10);
Assert.equal(1, onChangeCalled, "listener should not have been called as enableDebugExceptions was false");
// Enable Debug extensions
expectedEnableDebugExceptions = true;
core.config.enableDebugExceptions = expectedEnableDebugExceptions;
this.clock.tick(10);
Assert.equal(2, onChangeCalled, "listener should have been called enableDebugExceptions");
// This should trigger the listener as enableDebugExceptions was false
expectedLoggingLevel = 2;
core.config.loggingLevelConsole = expectedLoggingLevel;
this.clock.tick(10);
Assert.equal(3, onChangeCalled, "listener should have been called as enableDebugExceptions was true");
// Disable Debug extensions again
expectedEnableDebugExceptions = false;
core.config.enableDebugExceptions = expectedEnableDebugExceptions;
this.clock.tick(10);
Assert.equal(4, onChangeCalled, "listener should have been called enableDebugExceptions");
// This should not call trigger the listener as enableDebugExceptions was false
expectedLoggingLevel = 42;
core.config.loggingLevelConsole = expectedLoggingLevel;
this.clock.tick(10);
Assert.equal(4, onChangeCalled, "listener should have been called as enableDebugExceptions was disabled");
}
});
function createPerfMgr(core: IAppInsightsCore, manager: INotificationManager): IPerfManager {
return createPerfMgr(core, manager);
}

Просмотреть файл

@ -1,9 +1,9 @@
import { Assert, AITestClass } from "@microsoft/ai-test-framework";
import { _eInternalMessageId } from "../../../src/JavaScriptSDK.Enums/LoggingEnums";
import { _InternalLogMessage } from "../../../src/JavaScriptSDK/DiagnosticLogger";
import { normalizeJsName, objExtend, _getObjProto, isPlainObject, dateNow } from "../../../src/JavaScriptSDK/HelperFuncs";
import { normalizeJsName, objExtend, _getObjProto } from "../../../src/JavaScriptSDK/HelperFuncs";
import { AppInsightsCore } from "../../../src/JavaScriptSDK/AppInsightsCore";
import { isArray, isObject, objKeys, strEndsWith, strStartsWith } from "@nevware21/ts-utils";
import { isArray, isObject, objKeys, strEndsWith, strStartsWith, isPlainObject, utcNow } from "@nevware21/ts-utils";
import { dumpObj } from "../../../src/applicationinsights-core-js";
@ -282,7 +282,7 @@ export class HelperFuncTests extends AITestClass {
Assert.equal(true, isPlainObject({}));
Assert.equal(true, isPlainObject(Object.create(null)));
Assert.equal(false, isPlainObject(new AppInsightsCore()));
Assert.equal(false, isPlainObject(dateNow()));
Assert.equal(false, isPlainObject(utcNow()));
Assert.equal(false, isPlainObject([]));
Assert.equal(false, isPlainObject(true), "true");
Assert.equal(false, isPlainObject(1), "1");
@ -303,7 +303,7 @@ export class HelperFuncTests extends AITestClass {
Assert.equal(true, isObject({}), "{}");
Assert.equal(true, isObject(Object.create(null)), "Object.create");
Assert.equal(true, isObject(new AppInsightsCore()), "AppInsightsCore");
Assert.equal(false, isObject(dateNow()), "dateNow");
Assert.equal(false, isObject(utcNow()), "utcNow");
Assert.equal(true, isObject([]), "[]");
Assert.equal(false, isObject(true), "true");
Assert.equal(false, isObject(1), "1");
@ -327,7 +327,7 @@ export class HelperFuncTests extends AITestClass {
});
Assert.equal(Object.prototype, _getObjProto({}));
Assert.equal(Date.prototype, _getObjProto(new Date()));
Assert.equal(Number.prototype, _getObjProto(dateNow()));
Assert.equal(Number.prototype, _getObjProto(utcNow()));
Assert.equal(Array.prototype, _getObjProto([]));
Assert.equal(Boolean.prototype, _getObjProto(true), "new Boolean(true)");
Assert.equal(Number.prototype, _getObjProto(1), "new Number(1)");

Просмотреть файл

@ -1,7 +1,7 @@
import { Assert, AITestClass } from "@microsoft/ai-test-framework";
import { utcNow } from "@nevware21/ts-utils";
import { ITraceParent } from "../../../src/JavaScriptSDK.Interfaces/ITraceParent";
import { generateW3CId, newGuid } from "../../../src/JavaScriptSDK/CoreUtils";
import { dateNow } from "../../../src/JavaScriptSDK/HelperFuncs";
import { formatTraceParent, isSampledFlag, isValidSpanId, isValidTraceId, isValidTraceParent, parseTraceParent } from "../../../src/JavaScriptSDK/W3cTraceParent";
export class W3cTraceParentTests extends AITestClass {
@ -265,12 +265,12 @@ export class W3cTraceParentTests extends AITestClass {
let maxAttempts = 3;
let orgTotal = -1;
do {
let start = dateNow();
let start = utcNow();
for (let lp = 0; lp < 10000; lp++) {
let newId = generateW3CId();
}
orgTotal = dateNow() - start;
orgTotal = utcNow() - start;
maxAttempts--;
// Virtualized test servers are slooooow, so try and perform a couple of tests before failing
} while (orgTotal >= 300 && maxAttempts > 0);
@ -304,12 +304,12 @@ export class W3cTraceParentTests extends AITestClass {
let maxAttempts = 3;
let guidTotal = -1;
do {
let start = dateNow();
let start = utcNow();
for (let lp = 0; lp < 10000; lp++) {
let newId = newGuid();
}
guidTotal = dateNow() - start;
guidTotal = utcNow() - start;
maxAttempts--;
// Virtualized test servers are slooooow, so try and perform a couple of tests before failing
} while (guidTotal >= 300 && maxAttempts > 0);

Просмотреть файл

@ -1,9 +1,8 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
import { asString, isArray, isDefined, isNullOrUndefined, isObject, objHasOwn } from "@nevware21/ts-utils";
import { asString, isArray, isDefined, isNullOrUndefined, isObject, isPlainObject, objHasOwn } from "@nevware21/ts-utils";
import { IConfiguration } from "../JavaScriptSDK.Interfaces/IConfiguration";
import { isPlainObject } from "../JavaScriptSDK/HelperFuncs";
import { _cfgDeepCopy } from "./DynamicSupport";
import { IConfigCheckFn, IConfigDefaultCheck, IConfigSetFn } from "./IConfigDefaults";
import { IDynamicConfigHandler } from "./IDynamicConfigHandler";

Просмотреть файл

@ -1,12 +1,11 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
import { dumpObj, objDefineProp } from "@nevware21/ts-utils";
import { dumpObj, objDefineProp, objForEachKey } from "@nevware21/ts-utils";
import { _eInternalMessageId, eLoggingSeverity } from "../JavaScriptSDK.Enums/LoggingEnums";
import { IConfiguration } from "../JavaScriptSDK.Interfaces/IConfiguration";
import { IDiagnosticLogger } from "../JavaScriptSDK.Interfaces/IDiagnosticLogger";
import { createUniqueNamespace } from "../JavaScriptSDK/DataCacheHelper";
import { objForEachKey } from "../JavaScriptSDK/HelperFuncs";
import { STR_NOT_DYNAMIC_ERROR } from "../JavaScriptSDK/InternalConstants";
import { _applyDefaultValue } from "./ConfigDefaults";
import { _makeDynamicObject, _setDynamicProperty } from "./DynamicProperty";

Просмотреть файл

@ -2,13 +2,11 @@
// Licensed under the MIT License.
import {
arrForEach, dumpObj, isArray, objDefineAccessors, objDefineProp, objForEachKey, objGetOwnPropertyDescriptor
arrForEach, arrIndexOf, dumpObj, isArray, isPlainObject, objDefineAccessors, objDefineProp, objForEachKey, objGetOwnPropertyDescriptor
} from "@nevware21/ts-utils";
import { isPlainObject } from "../JavaScriptSDK/HelperFuncs";
import { UNDEFINED_VALUE } from "../JavaScriptSDK/InternalConstants";
import { CFG_HANDLER_LINK, throwInvalidAccess } from "./DynamicSupport";
import { IWatcherHandler, _IDynamicDetail } from "./IDynamicWatcher";
import { _IDynamicConfigHandlerState } from "./_IDynamicConfigHandlerState";
import { _IDynamicConfigHandlerState, _IDynamicGetter } from "./_IDynamicConfigHandlerState";
const arrayMethodsToPatch = [
"push",
@ -40,9 +38,20 @@ function _makeDynamicProperty<T, C, V = any>(state: _IDynamicConfigHandlerState<
let detail: _IDynamicDetail<T> = {
n: name,
h: [],
add: function (handler: IWatcherHandler<T>) {
if (handler && handler.fn && detail.h.indexOf(handler) === -1) {
detail.h.push(handler);
trk: function (handler: IWatcherHandler<T>) {
if (handler && handler.fn) {
if (arrIndexOf(detail.h, handler) === -1) {
// Add this handler to the collection that should be notified when the value changes
detail.h.push(handler);
}
state.trk(handler, detail);
}
},
clr: function(handler: IWatcherHandler<T>) {
let idx = arrIndexOf(detail.h, handler);
if (idx !== -1) {
detail.h.splice(idx, 1);
}
}
}
@ -64,14 +73,18 @@ function _makeDynamicProperty<T, C, V = any>(state: _IDynamicConfigHandlerState<
// If there is an active handler then add it to the tracking set of handlers
let activeHandler = state.act;
if (activeHandler) {
detail.add(activeHandler);
detail.trk(activeHandler);
}
return value;
}
// Tag this getting as our dynamic property
_getProperty[state.prop] = true;
// Tag this getter as our dynamic property and provide shortcut for notifying a change
_getProperty[state.prop] = {
chng: function() {
state.add(detail);
}
};
function _setProperty(newValue: V) {
if (value !== newValue) {
@ -85,13 +98,15 @@ function _makeDynamicProperty<T, C, V = any>(state: _IDynamicConfigHandlerState<
if (value && value[CFG_HANDLER_LINK]) {
// For objects / arrays, we can indirectly inform any listeners by just changing the value to undefined
// This will trigger any listeners by simply calling their version of the setter.
if (isPlainObject(value)) {
if (isPlainObject(value) || isArray(value)) {
objForEachKey(value, (key) => {
value[key] = UNDEFINED_VALUE;
});
} else if (isArray(value)) {
arrForEach(value, (propValue, idx) => {
value[idx] = UNDEFINED_VALUE;
// Check if the value is dynamic
let propDesc = objGetOwnPropertyDescriptor(value, key);
if (propDesc && propDesc.get) {
// And if it is tell it's listeners that the value has changed
let valueState: _IDynamicGetter = propDesc.get[state.prop];
valueState && valueState.chng();
}
});
}
}

Просмотреть файл

@ -1,7 +1,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
import { ITimerHandler, arrForEach, dumpObj, newSymbol, scheduleTimeout } from "@nevware21/ts-utils";
import { ITimerHandler, arrForEach, arrIndexOf, dumpObj, newSymbol, scheduleTimeout } from "@nevware21/ts-utils";
import { _eInternalMessageId, eLoggingSeverity } from "../JavaScriptSDK.Enums/LoggingEnums";
import { throwAggregationError } from "../JavaScriptSDK/AggregationError";
import { _IInternalDynamicConfigHandler } from "./IDynamicConfigHandler";
@ -14,25 +14,24 @@ const symPostfix = "]]";
/**
* @internal
* @ignore
* Add the watcher to the collection of watchers to be notified for the named value that is changing
* @param watchers - The collection of watchers
* @param theDetail - The dynamic property detail
* @param prevValue - The previous value
*/
function _insertWatcher<T>(watchers: IWatcherHandler<T>[], theDetail: _IDynamicDetail<T>) {
if (theDetail && theDetail.h && theDetail.h.length > 0) {
arrForEach(theDetail.h, (handler) => {
// The handler may have self removed and we also want to only call the handler once.
if (handler && handler.fn && watchers.indexOf(handler) === -1) {
watchers.push(handler);
}
});
}
interface _IWaitingHandlers<T> {
/**
* The handler to be re-executed
*/
h: IWatcherHandler<T>;
/**
* The detail objects that caused this handler to be re-executed, each property has a detail instance
* but may be the same handler
*/
//d: _IDynamicDetail<T>[];
}
export function _createState<T>(cfgHandler: _IInternalDynamicConfigHandler<T>): _IDynamicConfigHandlerState<T> {
let dynamicPropertySymbol = newSymbol(symPrefix + "get" + cfgHandler.uid + symPostfix);
let dynamicPropertyReadOnly = newSymbol(symPrefix + "ro" + cfgHandler.uid + symPostfix);
let dynamicPropertyDetail = newSymbol(symPrefix + "dtl" + cfgHandler.uid + symPostfix);
let _waitingHandlers: IWatcherHandler<T>[] = null;
let _watcherTimer: ITimerHandler = null;
let theState: _IDynamicConfigHandlerState<T>;
@ -41,6 +40,15 @@ export function _createState<T>(cfgHandler: _IInternalDynamicConfigHandler<T>):
let prevWatcher = theState.act;
try {
theState.act = activeHandler;
if (activeHandler && activeHandler[dynamicPropertyDetail]) {
// Clear out the previously tracked details for this handler, so that access are re-evaluated
arrForEach(activeHandler[dynamicPropertyDetail], (detail) => {
detail.clr(activeHandler);
});
activeHandler[dynamicPropertyDetail] = [];
}
callback({
cfg: cfgHandler.cfg,
set: cfgHandler.set.bind(cfgHandler),
@ -50,7 +58,7 @@ export function _createState<T>(cfgHandler: _IInternalDynamicConfigHandler<T>):
let logger = cfgHandler.logger;
if (logger) {
// Don't let one individual failure break everyone
logger.throwInternal(eLoggingSeverity.CRITICAL, _eInternalMessageId.ConfigWatcherException, "Watcher [" + dumpObj(callback) + "] failed [" + dumpObj(e) + "]");
logger.throwInternal(eLoggingSeverity.CRITICAL, _eInternalMessageId.ConfigWatcherException, dumpObj(e));
}
// Re-throw the exception so that any true "error" is reported back to the called
@ -64,23 +72,33 @@ export function _createState<T>(cfgHandler: _IInternalDynamicConfigHandler<T>):
if (_waitingHandlers) {
let notifyHandlers = _waitingHandlers;
_waitingHandlers = null;
if (_watcherTimer) {
// Stop any timer as we are running them now anyway
_watcherTimer.cancel();
_watcherTimer = null;
}
// Stop any timer as we are running them now anyway
_watcherTimer && _watcherTimer.cancel();
_watcherTimer = null;
let watcherFailures: any[] = [];
// Now run the handlers
arrForEach(notifyHandlers, (handler) => {
// The handler may have self removed as part of another handler so re-check
if (handler.fn) {
try {
_useHandler(handler, handler.fn);
} catch (e) {
// Don't let a single failing watcher cause other watches to fail
watcherFailures.push(e);
if (handler) {
if (handler[dynamicPropertyDetail]) {
arrForEach(handler[dynamicPropertyDetail], (detail) => {
// Clear out this handler from previously tracked details, so that access are re-evaluated
detail.clr(handler);
});
handler[dynamicPropertyDetail] = null;
}
// The handler may have self removed as part of another handler so re-check
if (handler.fn) {
try {
_useHandler(handler, handler.fn);
} catch (e) {
// Don't let a single failing watcher cause other watches to fail
watcherFailures.push(e);
}
}
}
});
@ -95,7 +113,7 @@ export function _createState<T>(cfgHandler: _IInternalDynamicConfigHandler<T>):
}
if (watcherFailures.length > 0) {
throwAggregationError("Unexpected watcher error occurred: ", watcherFailures);
throwAggregationError("Watcher error(s): ", watcherFailures);
}
}
}
@ -113,8 +131,25 @@ export function _createState<T>(cfgHandler: _IInternalDynamicConfigHandler<T>):
}, 0);
}
// Add the watcher to the collection of waiting watchers to be executed later
_insertWatcher(_waitingHandlers, detail);
// Add all of the handlers for this detail (if not already present) - using normal for-loop for performance
for (let idx = 0; idx < detail.h.length; idx++) {
let handler = detail.h[idx];
// Add this handler to the collection of handlers to re-execute
if (handler && arrIndexOf(_waitingHandlers, handler) === -1) {
_waitingHandlers.push(handler);
}
}
}
}
function _trackHandler(handler: IWatcherHandler<T>, detail: _IDynamicDetail<T>) {
if (handler) {
let details = handler[dynamicPropertyDetail] = handler[dynamicPropertyDetail] || [];
if (arrIndexOf(details, detail) === -1) {
// If this detail is not already listed as tracked then add it so that we re-evaluate it's usage
details.push(detail);
}
}
}
@ -124,7 +159,8 @@ export function _createState<T>(cfgHandler: _IInternalDynamicConfigHandler<T>):
hdlr: cfgHandler,
add: _addWatcher,
notify: _notifyWatchers,
use: _useHandler
use: _useHandler,
trk: _trackHandler
};
return theState;

Просмотреть файл

@ -1,8 +1,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
import { isArray, objForEachKey, symbolFor, throwTypeError } from "@nevware21/ts-utils";
import { isPlainObject } from "../JavaScriptSDK/HelperFuncs";
import { isArray, isPlainObject, objForEachKey, symbolFor, throwTypeError } from "@nevware21/ts-utils";
import { IDynamicConfigHandler } from "./IDynamicConfigHandler";
// Using Symbol.for so that if the same symbol was already created it would be returned

Просмотреть файл

@ -45,7 +45,12 @@ export interface _IDynamicDetail<T extends IConfiguration> extends IDynamicPrope
/**
* Add the watcher for monitoring changes
*/
add: (handler: IWatcherHandler<T>) => void;
trk: (handler: IWatcherHandler<T>) => void;
/**
* Clear all of the watchers from monitoring changes
*/
clr: (handler: IWatcherHandler<T>) => void;
}
export interface IWatcherHandler<T extends IConfiguration> extends IUnloadHook {

Просмотреть файл

@ -1,6 +1,19 @@
import { IDynamicConfigHandler } from "./IDynamicConfigHandler";
import { IDynamicPropertyHandler } from "./IDynamicPropertyHandler";
import { IWatcherHandler, WatcherFunction } from "./IDynamicWatcher";
import { IWatcherHandler, WatcherFunction, _IDynamicDetail } from "./IDynamicWatcher";
/**
* @internal
* Interface for internal communication to notifying state changes
*/
export interface _IDynamicGetter {
/**
* Cause any listeners of this property to be notified that the value has changed.
* Primarily used to ensure that listeners of child properties of an object that is getting replaced
* will be notified.
*/
chng: () => void;
}
/**
* @internal
@ -35,6 +48,11 @@ export interface _IDynamicConfigHandlerState<T> {
*/
add: (handler: IDynamicPropertyHandler<T>) => void;
/**
* Add this handler as a handler for
*/
trk: (handler: IWatcherHandler<T>, detail: _IDynamicDetail<T>) => void;
/**
* Use the provided handler to listen for changes
*/

Просмотреть файл

@ -4,8 +4,8 @@
import dynamicProto from "@microsoft/dynamicproto-js";
import {
arrAppend, arrForEach, arrIndexOf, deepExtend, dumpObj, isFunction, isNullOrUndefined, objDeepFreeze, objDefineProp, objFreeze,
objHasOwn, throwError
arrAppend, arrForEach, arrIndexOf, deepExtend, dumpObj, isFunction, isNullOrUndefined, isPlainObject, objDeepFreeze, objDefineProp,
objForEachKey, objFreeze, objHasOwn, throwError
} from "@nevware21/ts-utils";
import { createDynamicConfig, onConfigChange } from "../Config/DynamicConfig";
import { IConfigDefaults } from "../Config/IConfigDefaults";
@ -41,7 +41,7 @@ import { createCookieMgr } from "./CookieMgr";
import { createUniqueNamespace } from "./DataCacheHelper";
import { getDebugListener } from "./DbgExtensionUtils";
import { DiagnosticLogger, _InternalLogMessage, _throwInternal, _warnToConsole } from "./DiagnosticLogger";
import { getSetValue, isPlainObject, objForEachKey, proxyFunctionAs, proxyFunctions, toISOString } from "./HelperFuncs";
import { getSetValue, proxyFunctionAs, proxyFunctions, toISOString } from "./HelperFuncs";
import {
STR_CHANNELS, STR_CREATE_PERF_MGR, STR_DISABLED, STR_EXTENSIONS, STR_EXTENSION_CONFIG, UNDEFINED_VALUE
} from "./InternalConstants";

Просмотреть файл

@ -1,7 +1,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// // Licensed under the MIT License.
import { arrForEach, isArray, objFreeze, throwError } from "@nevware21/ts-utils";
import { ITimerHandler, arrForEach, isArray, objFreeze, scheduleTimeout, throwError } from "@nevware21/ts-utils";
import { SendRequestReason } from "../JavaScriptSDK.Enums/SendRequestReason";
import { TelemetryUnloadReason } from "../JavaScriptSDK.Enums/TelemetryUnloadReason";
import { TelemetryUpdateReason } from "../JavaScriptSDK.Enums/TelemetryUpdateReason";
@ -193,17 +193,15 @@ export function createChannelControllerPlugin(channelQueue: _IInternalChannels[]
// Setting waiting to one so that we don't call the callBack until we finish iterating
let waiting = 1;
let doneIterating = false;
let cbTimer: any = null;
let cbTimer: ITimerHandler = null;
cbTimeout = cbTimeout || 5000;
function doCallback() {
waiting--;
if (doneIterating && waiting === 0) {
if (cbTimer) {
clearTimeout(cbTimer);
cbTimer = null;
}
cbTimer && cbTimer.cancel();
cbTimer = null;
callBack && callBack(doneIterating);
callBack = null;
@ -226,7 +224,7 @@ export function createChannelControllerPlugin(channelQueue: _IInternalChannels[]
// will never be called, so use a timeout to allow the channel(s) some time to "finish" before triggering any
// followup function (such as unloading)
if (isAsync && cbTimer == null) {
cbTimer = setTimeout(() => {
cbTimer = scheduleTimeout(() => {
cbTimer = null;
doCallback();
}, cbTimeout);

Просмотреть файл

@ -1,8 +1,8 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
import {
arrForEach, dumpObj, getDocument, getNavigator, isArray, isFunction, isNullOrUndefined, isString, isTruthy, isUndefined, objDeepFreeze,
objForEachKey, strEndsWith, strTrim
arrForEach, arrIndexOf, dumpObj, getDocument, getNavigator, isArray, isFunction, isNullOrUndefined, isString, isTruthy, isUndefined,
objDeepFreeze, objForEachKey, strEndsWith, strIndexOf, strLeft, strSubstring, strTrim, utcNow
} from "@nevware21/ts-utils";
import { createDynamicConfig, onConfigChange } from "../Config/DynamicConfig";
import { IConfigDefaults } from "../Config/IConfigDefaults";
@ -13,7 +13,7 @@ import { ICookieMgr, ICookieMgrConfig } from "../JavaScriptSDK.Interfaces/ICooki
import { IDiagnosticLogger } from "../JavaScriptSDK.Interfaces/IDiagnosticLogger";
import { _throwInternal } from "./DiagnosticLogger";
import { getLocation, isIE } from "./EnvUtils";
import { dateNow, getExceptionName, isNotNullOrUndefined, setValue, strContains } from "./HelperFuncs";
import { getExceptionName, isNotNullOrUndefined, setValue, strContains } from "./HelperFuncs";
import { STR_DOMAIN, STR_EMPTY, STR_PATH, UNDEFINED_VALUE } from "./InternalConstants";
const strToGMTString = "toGMTString";
@ -86,7 +86,7 @@ function _isMgrEnabled(cookieMgr: ICookieMgr) {
function _isIgnoredCookie(cookieMgrCfg: ICookieMgrConfig, name: string) {
if (name && cookieMgrCfg && isArray(cookieMgrCfg.ignoreCookies)) {
return cookieMgrCfg.ignoreCookies.indexOf(name) !== -1;
return arrIndexOf(cookieMgrCfg.ignoreCookies, name) !== -1;
}
return false;
@ -94,7 +94,7 @@ function _isIgnoredCookie(cookieMgrCfg: ICookieMgrConfig, name: string) {
function _isBlockedCookie(cookieMgrCfg: ICookieMgrConfig, name: string) {
if (name && cookieMgrCfg && isArray(cookieMgrCfg.blockedCookies)) {
if (cookieMgrCfg.blockedCookies.indexOf(name) !== -1) {
if (arrIndexOf(cookieMgrCfg.blockedCookies, name) !== -1) {
return true;
}
}
@ -206,10 +206,10 @@ export function createCookieMgr(rootConfig?: IConfiguration, logger?: IDiagnosti
if (_isMgrEnabled(cookieMgr) && !_isBlockedCookie(cookieMgrConfig, name)) {
let values: any = {};
let theValue = strTrim(value || STR_EMPTY);
let idx = theValue.indexOf(";");
let idx = strIndexOf(theValue, ";");
if (idx !== -1) {
theValue = strTrim(value.substring(0, idx));
values = _extractParts(value.substring(idx + 1));
theValue = strTrim(strLeft(value, idx));
values = _extractParts(strSubstring(value, idx + 1));
}
// Only update domain if not already present (isUndefined) and the value is truthy (not null, undefined or empty string)
@ -218,7 +218,7 @@ export function createCookieMgr(rootConfig?: IConfiguration, logger?: IDiagnosti
if (!isNullOrUndefined(maxAgeSec)) {
const _isIE = isIE();
if (isUndefined(values[strExpires])) {
const nowMs = dateNow();
const nowMs = utcNow();
// Only add expires if not already present
let expireMs = nowMs + (maxAgeSec * 1000);
@ -337,11 +337,11 @@ function _extractParts(theValue: string) {
arrForEach(parts, (thePart) => {
thePart = strTrim(thePart || STR_EMPTY);
if (thePart) {
let idx = thePart.indexOf("=");
let idx = strIndexOf(thePart, "=");
if (idx === -1) {
values[thePart] = null;
} else {
values[strTrim(thePart.substring(0, idx))] = strTrim(thePart.substring(idx + 1));
values[strTrim(strLeft(thePart, idx))] = strTrim(strSubstring(thePart, idx + 1));
}
}
});

Просмотреть файл

@ -3,8 +3,6 @@
"use strict";
import { strShimUndefined } from "@microsoft/applicationinsights-shims";
import { strSubstr, strSubstring } from "@nevware21/ts-utils";
import { getPerformance } from "./EnvUtils";
import { dateNow } from "./HelperFuncs";
import { STR_EMPTY } from "./InternalConstants";
import { random32 } from "./RandomHelper";
@ -17,19 +15,6 @@ export function newGuid(): string {
return strSubstring(uuid, 0, 8) + "-" + strSubstring(uuid, 8, 12) + "-" + strSubstring(uuid, 12, 16) + "-" + strSubstring(uuid, 16, 20) + "-" + strSubstring(uuid, 20);
}
/**
* Return the current value of the Performance Api now() function (if available) and fallback to dateNow() if it is unavailable (IE9 or less)
* https://caniuse.com/#search=performance.now
*/
export function perfNow(): number {
let perf = getPerformance();
if (perf && perf.now) {
return perf.now();
}
return dateNow();
}
/**
* The strEndsWith() method determines whether a string ends with the characters of a specified string, returning true or false as appropriate.
* @param value - The value to check whether it ends with the search value.

Просмотреть файл

@ -5,8 +5,9 @@ import { getInst } from "@nevware21/ts-utils";
import { IConfiguration } from "../JavaScriptSDK.Interfaces/IConfiguration";
import { IDbgExtension } from "../JavaScriptSDK.Interfaces/IDbgExtension";
import { INotificationListener } from "../JavaScriptSDK.Interfaces/INotificationListener";
import { STR_EVENTS_DISCARDED, STR_EVENTS_SEND_REQUEST, STR_EVENTS_SENT, STR_PERF_EVENT } from "./InternalConstants";
const listenerFuncs = [ "eventsSent", "eventsDiscarded", "eventsSendRequest", "perfEvent" ];
const listenerFuncs = [ STR_EVENTS_SENT, STR_EVENTS_DISCARDED, STR_EVENTS_SEND_REQUEST, STR_PERF_EVENT ];
let _aiNamespace: any = null;
let _debugListener: INotificationListener;

Просмотреть файл

@ -3,7 +3,7 @@
"use strict";
import { strShimObject, strShimPrototype, strShimUndefined } from "@microsoft/applicationinsights-shims";
import { getDocument, getInst, getNavigator, hasNavigator, isString, isUndefined } from "@nevware21/ts-utils";
import { getDocument, getInst, getNavigator, getPerformance, hasNavigator, isString, isUndefined, strIndexOf } from "@nevware21/ts-utils";
import { strContains } from "./HelperFuncs";
import { STR_EMPTY } from "./InternalConstants";
@ -102,15 +102,6 @@ export function getConsole(): Console | null {
return getInst(strConsole);
}
/**
* Returns the performance object if it is present otherwise null.
* This helper is used to access the performance object from the current
* global instance which could be window or globalThis for a web worker
*/
export function getPerformance(): Performance | null {
return getInst(strPerformance);
}
/**
* Checks if JSON object is available, this is required as we support the API running without a
* window /document (eg. Node server, electron webworkers) and if we attempt to assign a history
@ -212,7 +203,7 @@ export function isSafari(userAgentStr ?: string) {
}
var ua = (userAgentStr || STR_EMPTY).toLowerCase();
return (ua.indexOf("safari") >= 0);
return (strIndexOf(ua, "safari") >= 0);
}
/**

Просмотреть файл

@ -1,8 +1,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
import { arrForEach, arrIndexOf, getDocument, getWindow, isArray, objKeys } from "@nevware21/ts-utils";
import { arrForEach, arrIndexOf, getDocument, getWindow, isArray, objForEachKey, objKeys } from "@nevware21/ts-utils";
import { createElmNodeData, createUniqueNamespace } from "./DataCacheHelper";
import { objForEachKey } from "./HelperFuncs";
import { STR_EMPTY } from "./InternalConstants";
// Added to help with minfication

Просмотреть файл

@ -1,9 +1,9 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
import { ObjAssign, ObjClass, strShimFunction } from "@microsoft/applicationinsights-shims";
import { ObjAssign, ObjClass } from "@microsoft/applicationinsights-shims";
import {
arrForEach, asString as asString21, isArray, isBoolean, isError, isFunction, isNullOrUndefined, isObject, isString, isUndefined,
objDeepFreeze, objDefineAccessors, objForEachKey as objForEachKey21, objHasOwn, objHasOwnProperty, strIndexOf
arrForEach, asString as asString21, isArray, isBoolean, isError, isFunction, isNullOrUndefined, isObject, isPlainObject, isString,
isUndefined, objDeepFreeze, objDefineAccessors, objForEachKey, objHasOwn, strIndexOf
} from "@nevware21/ts-utils";
import { STR_EMPTY } from "./InternalConstants";
@ -62,14 +62,6 @@ export function normalizeJsName(name: string): string {
return value;
}
/**
* This is a helper function for the equivalent of arForEach(objKeys(target), callbackFn), this is a
* performance optimization to avoid the creation of a new array for large objects
* @param target - The target object to find and process the keys
* @param callbackfn - The function to call with the details
*/
export const objForEachKey = objForEachKey21;
/**
* A simple wrapper (for minification support) to check if the value contains the search string.
* @param value - The string value to check for the existence of the search value
@ -83,32 +75,6 @@ export function strContains(value: string, search: string): boolean {
return false;
}
/**
* Checks if the type of the value is a normal plain object (not a null or data)
* @param value
*/
export function isPlainObject(value: any): boolean {
let result: boolean = false;
if (value && typeof value === "object") {
// Inlining _objGetPrototypeOf for performance to avoid an additional function call
let proto = _getObjProto(value);
if (!proto) {
// No prototype found so this is a plain Object eg. 'Object.create(null)'
result = true;
} else {
// Objects that have a prototype are plain only if they were created using the Object global (native) function
if (proto[strConstructor] && objHasOwnProperty(proto, strConstructor)) {
proto = proto[strConstructor];
}
result = typeof proto === strShimFunction && _fnToString.call(proto) === _objFunctionString;
}
}
return result;
}
/**
* Convert a date to I.S.O. format in IE8
*/
@ -118,16 +84,6 @@ export function toISOString(date: Date) {
export const deepFreeze: <T>(obj: T) => T = objDeepFreeze;
/**
* Return the current time via the Date now() function (if available) and falls back to (new Date()).getTime() if now() is unavailable (IE8 or less)
* https://caniuse.com/#search=Date.now
*/
export function dateNow() {
let dt = Date;
return dt.now ? dt.now() : new dt().getTime();
}
/**
* Returns the name of object if it's an Error. Otherwise, returns empty string.
*/

Просмотреть файл

@ -1,7 +1,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
import dynamicProto from "@microsoft/dynamicproto-js";
import { arrForEach, arrIndexOf } from "@nevware21/ts-utils";
import { arrForEach, arrIndexOf, scheduleTimeout } from "@nevware21/ts-utils";
import { createDynamicConfig } from "../Config/DynamicConfig";
import { IConfiguration } from "../JavaScriptSDK.Interfaces/IConfiguration";
import { INotificationListener } from "../JavaScriptSDK.Interfaces/INotificationListener";
@ -18,7 +18,7 @@ function _runListeners(listeners: INotificationListener[], name: string, isAsync
arrForEach(listeners, (listener) => {
if (listener && listener[name]) {
if (isAsync) {
setTimeout(() => callback(listener), 0);
scheduleTimeout(() => callback(listener), 0);
} else {
try {
callback(listener);
@ -102,7 +102,7 @@ export class NotificationManager implements INotificationManager {
if (perfEvtsSendAll || !perfEvent.isChildEvt()) {
_runListeners(_self.listeners, STR_PERF_EVENT, false, (listener) => {
if (perfEvent.isAsync) {
setTimeout(() => listener.perfEvent(perfEvent), 0);
scheduleTimeout(() => listener.perfEvent(perfEvent), 0);
} else {
listener.perfEvent(perfEvent);
}

Просмотреть файл

@ -1,11 +1,10 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
import dynamicProto from "@microsoft/dynamicproto-js";
import { isArray, isFunction, objDefineAccessors } from "@nevware21/ts-utils";
import { isArray, isFunction, objDefineAccessors, utcNow } from "@nevware21/ts-utils";
import { INotificationManager } from "../JavaScriptSDK.Interfaces/INotificationManager";
import { IPerfEvent } from "../JavaScriptSDK.Interfaces/IPerfEvent";
import { IPerfManager, IPerfManagerProvider } from "../JavaScriptSDK.Interfaces/IPerfManager";
import { dateNow } from "./HelperFuncs";
import { STR_GET_PERF_MGR } from "./InternalConstants";
const strExecutionContextKey = "ctx";
@ -64,7 +63,7 @@ export class PerfEvent implements IPerfEvent {
constructor(name: string, payloadDetails: () => any, isAsync: boolean) {
let _self = this;
_self.start = dateNow();
_self.start = utcNow();
_self.name = name;
_self.isAsync = isAsync;
_self.isChildEvt = (): boolean => false;
@ -127,7 +126,7 @@ export class PerfEvent implements IPerfEvent {
}
}
_self.time = dateNow() - _self.start;
_self.time = utcNow() - _self.start;
_self.exTime = _self.time - childTime;
_self.complete = () => {};
};

Просмотреть файл

@ -2,7 +2,9 @@
// Licensed under the MIT License.
"use strict";
import { arrForEach, dumpObj, isArray, isFunction, isNullOrUndefined, isUndefined, objFreeze, objKeys } from "@nevware21/ts-utils";
import {
arrForEach, dumpObj, isArray, isFunction, isNullOrUndefined, isUndefined, objForEachKey, objFreeze, objKeys
} from "@nevware21/ts-utils";
import { _applyDefaultValue } from "../Config/ConfigDefaults";
import { createDynamicConfig } from "../Config/DynamicConfig";
import { IConfigDefaults } from "../Config/IConfigDefaults";
@ -20,8 +22,8 @@ import { ITelemetryPluginChain } from "../JavaScriptSDK.Interfaces/ITelemetryPlu
import { ITelemetryUnloadState } from "../JavaScriptSDK.Interfaces/ITelemetryUnloadState";
import { ITelemetryUpdateState } from "../JavaScriptSDK.Interfaces/ITelemetryUpdateState";
import { _throwInternal, safeGetLogger } from "./DiagnosticLogger";
import { objForEachKey, proxyFunctions } from "./HelperFuncs";
import { STR_CORE, STR_DISABLED, STR_EMPTY } from "./InternalConstants";
import { proxyFunctions } from "./HelperFuncs";
import { STR_CORE, STR_DISABLED, STR_EMPTY, STR_EXTENSION_CONFIG } from "./InternalConstants";
import { doPerf } from "./PerfManager";
import { _getPluginState } from "./TelemetryHelpers";
@ -161,7 +163,7 @@ function _createInternalContext<T extends IBaseProcessingContext>(telemetryChain
}
// Always set the value so that it's created as a dynamic config element (if not already)
dynamicHandler.set(cfg, "extensionConfig", extCfg); // Note: it is valid for the "value" to be undefined
dynamicHandler.set(cfg, STR_EXTENSION_CONFIG, extCfg); // Note: it is valid for the "value" to be undefined
extCfg = cfg.extensionConfig;
if (extCfg) {

Просмотреть файл

@ -1,7 +1,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
import { utcNow } from "@nevware21/ts-utils";
import { getCrypto, getMsCrypto, isIE } from "./EnvUtils";
import { dateNow } from "./HelperFuncs";
import { STR_EMPTY } from "./InternalConstants";
const UInt32Mask = 0x100000000;
@ -28,7 +28,7 @@ function _autoSeedMwc() {
// Simple initialization using default Math.random() - So we inherit any entropy from the browser
// and bitwise XOR with the current milliseconds
try {
const now = dateNow() & 0x7fffffff;
const now = utcNow() & 0x7fffffff;
_mwcSeed(((Math.random() * UInt32Mask) ^ now) + now);
} catch (e) {
// Don't crash if something goes wrong

Просмотреть файл

@ -1,4 +1,4 @@
import { isArray, isString, strTrim } from "@nevware21/ts-utils";
import { isArray, isString, strLeft, strTrim } from "@nevware21/ts-utils";
import { ITraceParent } from "../JavaScriptSDK.Interfaces/ITraceParent";
import { generateW3CId } from "./CoreUtils";
import { findMetaTag, findNamedServerTiming } from "./EnvUtils";
@ -54,7 +54,7 @@ export function createTraceParent(traceId?: string, spanId?: string, flags?: num
return {
version: _isValid(version, 2, INVALID_VERSION) ? version : DEFAULT_VERSION,
traceId: isValidTraceId(traceId) ? traceId : generateW3CId(),
spanId: isValidSpanId(spanId) ? spanId : generateW3CId().substr(0, 16),
spanId: isValidSpanId(spanId) ? spanId : strLeft(generateW3CId(), 16),
traceFlags: flags >= 0 && flags <= 0xFF ? flags : 1
};
}

Просмотреть файл

@ -21,10 +21,10 @@ export { AppInsightsCore } from "./JavaScriptSDK/AppInsightsCore";
export { BaseTelemetryPlugin } from "./JavaScriptSDK/BaseTelemetryPlugin";
export { randomValue, random32, mwcRandomSeed, mwcRandom32, newId } from "./JavaScriptSDK/RandomHelper";
export {
Undefined, newGuid, perfNow, generateW3CId
Undefined, newGuid, generateW3CId
} from "./JavaScriptSDK/CoreUtils";
export {
normalizeJsName, toISOString, dateNow, getExceptionName, strContains, setValue, getSetValue,
normalizeJsName, toISOString, getExceptionName, strContains, setValue, getSetValue,
proxyAssign, proxyFunctions, proxyFunctionAs, createClassFromInterface, optimizeObject,
isNotUndefined, isNotNullOrUndefined, objExtend
} from "./JavaScriptSDK/HelperFuncs";
@ -35,7 +35,7 @@ export {
arrReduce, arrMap, strTrim, objKeys, objDefineAccessors, throwError, isSymbol,
isNotTruthy, isTruthy, objFreeze, objSeal, objToString, objDeepFreeze as deepFreeze,
getInst as getGlobalInst, hasWindow, getWindow, hasDocument, getDocument, hasNavigator, getNavigator, hasHistory,
getHistory, dumpObj, asString, objForEachKey
getHistory, dumpObj, asString, objForEachKey, getPerformance, utcNow as dateNow, perfNow
} from "@nevware21/ts-utils";
export { EnumValue, createEnumStyle, createValueMap } from "./JavaScriptSDK.Enums/EnumHelperFuncs";
export {
@ -45,7 +45,7 @@ export {
} from "./JavaScriptSDK/EventHelpers";
export {
getCrypto, getMsCrypto, getLocation, getPerformance, hasJSON, getJSON,
getCrypto, getMsCrypto, getLocation, hasJSON, getJSON,
isReactNative, getConsole, isIE, getIEVersion, isSafari,
setEnableEnvMocks, isBeaconsSupported, isFetchSupported, useXDomainRequest, isXhrSupported,
findMetaTag, findNamedServerTiming