@microsoft/applicationinsights-core-js
Version:
Microsoft Application Insights Core Javascript SDK
931 lines (929 loc) • 66.7 kB
JavaScript
/*
* Application Insights JavaScript SDK - Core, 3.3.9
* Copyright (c) Microsoft and contributors. All rights reserved.
*/
var _a;
import { __spreadArrayFn as __spreadArray } from "@microsoft/applicationinsights-shims";
import dynamicProto from "@microsoft/dynamicproto-js";
import { createPromise, createSyncAllSettledPromise, doAwaitResponse } from "@nevware21/ts-async";
import { arrAppend, arrForEach, arrIndexOf, createTimeout, deepExtend, hasDocument, isFunction, isNullOrUndefined, isPlainObject, isPromiseLike, objDeepFreeze, objDefine, objForEachKey, objFreeze, objHasOwn, scheduleTimeout, throwError } from "@nevware21/ts-utils";
import { createDynamicConfig, onConfigChange } from "../Config/DynamicConfig";
import { ActiveStatus } from "../JavaScriptSDK.Enums/InitActiveStatusEnum";
import { _DYN_ADD_NOTIFICATION_LIS1, _DYN_CANCEL, _DYN_CREATE_NEW, _DYN_ENABLED, _DYN_GET_NOTIFY_MGR, _DYN_GET_PLUGIN, _DYN_GET_PROCESS_TEL_CONT2, _DYN_IDENTIFIER, _DYN_INITIALIZE, _DYN_IS_INITIALIZED, _DYN_LENGTH, _DYN_LOGGER, _DYN_LOGGING_LEVEL_CONSOL4, _DYN_MESSAGE, _DYN_MESSAGE_ID, _DYN_NAME, _DYN_ON_COMPLETE, _DYN_PROCESS_NEXT, _DYN_PUSH, _DYN_REMOVE_NOTIFICATION_0, _DYN_SPLICE, _DYN_STOP_POLLING_INTERNA3, _DYN_TEARDOWN, _DYN_UNLOAD, _DYN_VALUE, _DYN_VERSION, _DYN_WATCH } from "../__DynamicConstants";
import { doUnloadAll, runTargetUnload } from "./AsyncUtils";
import { ChannelControllerPriority } from "./Constants";
import { createCookieMgr } from "./CookieMgr";
import { createUniqueNamespace } from "./DataCacheHelper";
import { getDebugListener } from "./DbgExtensionUtils";
import { DiagnosticLogger, _InternalLogMessage, _throwInternal, _warnToConsole } from "./DiagnosticLogger";
import { getSetValue, isNotNullOrUndefined, proxyFunctionAs, proxyFunctions, toISOString } from "./HelperFuncs";
import { STR_CHANNELS, STR_CORE, STR_CREATE_PERF_MGR, STR_DISABLED, STR_EMPTY, STR_EVENTS_DISCARDED, STR_EXTENSIONS, STR_EXTENSION_CONFIG, STR_GET_PERF_MGR, STR_PRIORITY, UNDEFINED_VALUE } from "./InternalConstants";
import { NotificationManager } from "./NotificationManager";
import { PerfManager, doPerf, getGblPerfMgr } from "./PerfManager";
import { createProcessTelemetryContext, createProcessTelemetryUnloadContext, createProcessTelemetryUpdateContext, createTelemetryProxyChain } from "./ProcessTelemetryContext";
import { _getPluginState, createDistributedTraceContext, initializePlugins, sortPlugins } from "./TelemetryHelpers";
import { TelemetryInitializerPlugin } from "./TelemetryInitializerPlugin";
import { createUnloadHandlerContainer } from "./UnloadHandlerContainer";
import { createUnloadHookContainer } from "./UnloadHookContainer";
// import { IStatsBeat, IStatsBeatConfig, IStatsBeatState } from "../JavaScriptSDK.Interfaces/IStatsBeat";
// import { IStatsMgr } from "../JavaScriptSDK.Interfaces/IStatsMgr";
var strValidationError = "Plugins must provide initialize method";
var strNotificationManager = "_notificationManager";
var strSdkUnloadingError = "SDK is still unloading...";
var strSdkNotInitialized = "SDK is not initialized";
var maxInitQueueSize = 100;
var maxInitTimeout = 50000;
// const strPluginUnloadFailed = "Failed to unload plugin";
// /**
// * Default StatsBeatMgr configuration
// * @internal
// */
// const defaultStatsCfg: IConfigDefaults<IStatsBeatConfig> = objDeepFreeze({
// shrtInt: UNDEFINED_VALUE,
// endCfg: cfgDfMerge([])
// });
// /**
// * Default SDK initialization configuration
// * @internal
// */
// const defaultSdkConfig: IConfigDefaults<IInternalSdkConfiguration> = objDeepFreeze({
// stats: { rdOnly: true, mrg: true, v: defaultStatsCfg }
// });
/**
* The default settings for the config.
* WE MUST include all defaults here to ensure that the config is created with all of the properties
* defined as dynamic.
*/
var defaultConfig = objDeepFreeze((_a = {
cookieCfg: {}
},
_a[STR_EXTENSIONS] = { rdOnly: true, ref: true, v: [] },
_a[STR_CHANNELS] = { rdOnly: true, ref: true, v: [] },
_a[STR_EXTENSION_CONFIG] = { ref: true, v: {} },
_a[STR_CREATE_PERF_MGR] = UNDEFINED_VALUE,
_a.loggingLevelConsole = 0 /* eLoggingSeverity.DISABLED */,
_a.diagnosticLogInterval = UNDEFINED_VALUE,
_a));
/**
* Helper to create the default performance manager
* @param core - The AppInsightsCore instance
* @param notificationMgr - The notification manager
*/
function _createPerfManager(core, notificationMgr) {
return new PerfManager(notificationMgr);
}
function _validateExtensions(logger, channelPriority, allExtensions) {
// Concat all available extensions
var coreExtensions = [];
var channels = [];
// Check if any two extensions have the same priority, then warn to console
// And extract the local extensions from the
var extPriorities = {};
// Extension validation
arrForEach(allExtensions, function (ext) {
// Check for ext.initialize
if (isNullOrUndefined(ext) || isNullOrUndefined(ext[_DYN_INITIALIZE /* @min:%2einitialize */])) {
throwError(strValidationError);
}
var extPriority = ext[STR_PRIORITY /* @min:%2epriority */];
var identifier = ext[_DYN_IDENTIFIER /* @min:%2eidentifier */];
if (ext && extPriority) {
if (!isNullOrUndefined(extPriorities[extPriority])) {
_warnToConsole(logger, "Two extensions have same priority #" + extPriority + " - " + extPriorities[extPriority] + ", " + identifier);
}
else {
// set a value
extPriorities[extPriority] = identifier;
}
}
// Split extensions to core and channels
if (!extPriority || extPriority < channelPriority) {
// Add to core extension that will be managed by AppInsightsCore
coreExtensions[_DYN_PUSH /* @min:%2epush */](ext);
}
else {
channels[_DYN_PUSH /* @min:%2epush */](ext);
}
});
return {
core: coreExtensions,
channels: channels
};
}
function _isPluginPresent(thePlugin, plugins) {
var exists = false;
arrForEach(plugins, function (plugin) {
if (plugin === thePlugin) {
exists = true;
return -1;
}
});
return exists;
}
function _deepMergeConfig(details, target, newValues, merge) {
// Lets assign the new values to the existing config
if (newValues) {
objForEachKey(newValues, function (key, value) {
if (merge) {
if (isPlainObject(value) && isPlainObject(target[key])) {
// The target is an object and it has a value
_deepMergeConfig(details, target[key], value, merge);
}
}
if (merge && isPlainObject(value) && isPlainObject(target[key])) {
// The target is an object and it has a value
_deepMergeConfig(details, target[key], value, merge);
}
else {
// Just Assign (replace) and/or make the property dynamic
details.set(target, key, value);
}
});
}
}
function _findWatcher(listeners, newWatcher) {
var theListener = null;
var idx = -1;
arrForEach(listeners, function (listener, lp) {
if (listener.w === newWatcher) {
theListener = listener;
idx = lp;
return -1;
}
});
return { i: idx, l: theListener };
}
function _addDelayedCfgListener(listeners, newWatcher) {
var theListener = _findWatcher(listeners, newWatcher).l;
if (!theListener) {
theListener = {
w: newWatcher,
rm: function () {
var fnd = _findWatcher(listeners, newWatcher);
if (fnd.i !== -1) {
listeners[_DYN_SPLICE /* @min:%2esplice */](fnd.i, 1);
}
}
};
listeners[_DYN_PUSH /* @min:%2epush */](theListener);
}
return theListener;
}
function _registerDelayedCfgListener(config, listeners, logger) {
arrForEach(listeners, function (listener) {
var unloadHdl = onConfigChange(config, listener.w, logger);
delete listener.w; // Clear the listener reference so it will get garbage collected.
// replace the remove function
listener.rm = function () {
unloadHdl.rm();
};
});
}
// Moved this outside of the closure to reduce the retained memory footprint
function _initDebugListener(configHandler, unloadContainer, notificationManager, debugListener) {
// Will get recalled if any referenced config values are changed
unloadContainer.add(configHandler[_DYN_WATCH /* @min:%2ewatch */](function (details) {
var disableDbgExt = details.cfg.disableDbgExt;
if (disableDbgExt === true && debugListener) {
// Remove any previously loaded debug listener
notificationManager[_DYN_REMOVE_NOTIFICATION_0 /* @min:%2eremoveNotificationListener */](debugListener);
debugListener = null;
}
if (notificationManager && !debugListener && disableDbgExt !== true) {
debugListener = getDebugListener(details.cfg);
notificationManager[_DYN_ADD_NOTIFICATION_LIS1 /* @min:%2eaddNotificationListener */](debugListener);
}
}));
return debugListener;
}
// Moved this outside of the closure to reduce the retained memory footprint
function _createUnloadHook(unloadHook) {
return objDefine({
rm: function () {
unloadHook.rm();
}
}, "toJSON", { v: function () { return "aicore::onCfgChange<" + JSON.stringify(unloadHook) + ">"; } });
}
/**
* @group Classes
* @group Entrypoint
*/
var AppInsightsCore = /** @class */ (function () {
function AppInsightsCore() {
// NOTE!: DON'T set default values here, instead set them in the _initDefaults() function as it is also called during teardown()
var _configHandler;
var _isInitialized;
var _logger;
var _eventQueue;
var _notificationManager;
// let _statsBeat: IStatsBeat | null;
// let _statsMgr: IStatsMgr | null;
var _perfManager;
var _cfgPerfManager;
var _cookieManager;
var _pluginChain;
var _configExtensions;
var _channelConfig;
var _channels;
var _isUnloading;
var _telemetryInitializerPlugin;
var _internalLogsEventName;
var _evtNamespace;
var _unloadHandlers;
var _hookContainer;
var _debugListener;
var _traceCtx;
var _instrumentationKey;
var _cfgListeners;
var _extensions;
var _pluginVersionStringArr;
var _pluginVersionString;
var _activeStatus; // to indicate if ikey or endpoint url promised is resolved or not
var _endpoint;
var _initInMemoMaxSize; // max event count limit during wait for init promises to be resolved
var _isStatusSet; // track if active status is set in case of init timeout and init promises setting the status twice
var _initTimer;
/**
* Internal log poller
*/
var _internalLogPoller;
var _internalLogPollerListening;
var _forceStopInternalLogPoller;
dynamicProto(AppInsightsCore, this, function (_self) {
// Set the default values (also called during teardown)
_initDefaults();
// Special internal method to allow the unit tests and DebugPlugin to hook embedded objects
_self["_getDbgPlgTargets"] = function () {
return [_extensions, _eventQueue];
};
_self[_DYN_IS_INITIALIZED /* @min:%2eisInitialized */] = function () { return _isInitialized; };
// since version 3.3.0
_self.activeStatus = function () { return _activeStatus; };
// since version 3.3.0
// internal
_self._setPendingStatus = function () {
_activeStatus = 3 /* eActiveStatus.PENDING */;
};
// Creating the self.initialize = ()
_self[_DYN_INITIALIZE /* @min:%2einitialize */] = function (config, extensions, logger, notificationManager) {
if (_isUnloading) {
throwError(strSdkUnloadingError);
}
// Make sure core is only initialized once
if (_self[_DYN_IS_INITIALIZED /* @min:%2eisInitialized */]()) {
throwError("Core cannot be initialized more than once");
}
_configHandler = createDynamicConfig(config, defaultConfig, logger || _self[_DYN_LOGGER /* @min:%2elogger */], false);
// Re-assigning the local config property so we don't have any references to the passed value and it can be garbage collected
config = _configHandler.cfg;
// This will be "re-run" if the referenced config properties are changed
_addUnloadHook(_configHandler[_DYN_WATCH /* @min:%2ewatch */](function (details) {
var rootCfg = details.cfg;
_initInMemoMaxSize = rootCfg.initInMemoMaxSize || maxInitQueueSize;
_handleIKeyEndpointPromises(rootCfg);
// Mark the extensionConfig and all first level keys as referenced
// This is so that calls to getExtCfg() will always return the same object
// Even when a user may "re-assign" the plugin properties (or it's unloaded/reloaded)
var extCfg = details.ref(details.cfg, STR_EXTENSION_CONFIG);
objForEachKey(extCfg, function (key) {
details.ref(extCfg, key);
});
}));
_notificationManager = notificationManager;
// Initialize the debug listener outside of the closure to reduce the retained memory footprint
_debugListener = _initDebugListener(_configHandler, _hookContainer, _notificationManager && _self[_DYN_GET_NOTIFY_MGR /* @min:%2egetNotifyMgr */](), _debugListener);
_initPerfManager();
_self[_DYN_LOGGER /* @min:%2elogger */] = logger;
var cfgExtensions = config[STR_EXTENSIONS /* @min:%2eextensions */];
// Extension validation
_configExtensions = [];
_configExtensions[_DYN_PUSH /* @min:%2epush */].apply(_configExtensions, __spreadArray(__spreadArray([], extensions, false), cfgExtensions, false));
_channelConfig = config[STR_CHANNELS /* @min:%2echannels */];
_initPluginChain(null);
if (!_channels || _channels[_DYN_LENGTH /* @min:%2elength */] === 0) {
throwError("No " + STR_CHANNELS + " available");
}
if (_channelConfig && _channelConfig[_DYN_LENGTH /* @min:%2elength */] > 1) {
var teeController = _self[_DYN_GET_PLUGIN /* @min:%2egetPlugin */]("TeeChannelController");
if (!teeController || !teeController.plugin) {
_throwInternal(_logger, 1 /* eLoggingSeverity.CRITICAL */, 28 /* _eInternalMessageId.SenderNotInitialized */, "TeeChannel required");
}
}
_registerDelayedCfgListener(config, _cfgListeners, _logger);
_cfgListeners = null;
_isInitialized = true;
if (_activeStatus === ActiveStatus.ACTIVE) {
_releaseQueues();
}
};
_self.getChannels = function () {
var controls = [];
if (_channels) {
arrForEach(_channels, function (channel) {
controls[_DYN_PUSH /* @min:%2epush */](channel);
});
}
return objFreeze(controls);
};
_self.track = function (telemetryItem) {
doPerf(_self[STR_GET_PERF_MGR /* @min:%2egetPerfMgr */](), function () { return "AppInsightsCore:track"; }, function () {
if (telemetryItem === null) {
_notifyInvalidEvent(telemetryItem);
// throw error
throwError("Invalid telemetry item");
}
// do basic validation before sending it through the pipeline
if (!telemetryItem[_DYN_NAME /* @min:%2ename */] && isNullOrUndefined(telemetryItem[_DYN_NAME /* @min:%2ename */])) {
_notifyInvalidEvent(telemetryItem);
throwError("telemetry name required");
}
// setup default iKey if not passed in
telemetryItem.iKey = telemetryItem.iKey || _instrumentationKey;
// add default timestamp if not passed in
telemetryItem.time = telemetryItem.time || toISOString(new Date());
// Common Schema 4.0
telemetryItem.ver = telemetryItem.ver || "4.0";
if (!_isUnloading && _self[_DYN_IS_INITIALIZED /* @min:%2eisInitialized */]() && _activeStatus === ActiveStatus.ACTIVE) {
// Process the telemetry plugin chain
_createTelCtx()[_DYN_PROCESS_NEXT /* @min:%2eprocessNext */](telemetryItem);
}
else if (_activeStatus !== ActiveStatus.INACTIVE) {
// Queue events until all extensions are initialized
if (_eventQueue[_DYN_LENGTH /* @min:%2elength */] <= _initInMemoMaxSize) {
// set limit, if full, stop adding new events
_eventQueue[_DYN_PUSH /* @min:%2epush */](telemetryItem);
}
}
}, function () { return ({ item: telemetryItem }); }, !(telemetryItem.sync));
};
_self[_DYN_GET_PROCESS_TEL_CONT2 /* @min:%2egetProcessTelContext */] = _createTelCtx;
_self[_DYN_GET_NOTIFY_MGR /* @min:%2egetNotifyMgr */] = function () {
if (!_notificationManager) {
_notificationManager = new NotificationManager(_configHandler.cfg);
// For backward compatibility only
_self[strNotificationManager] = _notificationManager;
}
return _notificationManager;
};
/**
* Adds a notification listener. The SDK calls methods on the listener when an appropriate notification is raised.
* The added plugins must raise notifications. If the plugins do not implement the notifications, then no methods will be
* called.
* @param listener - An INotificationListener object.
*/
_self[_DYN_ADD_NOTIFICATION_LIS1 /* @min:%2eaddNotificationListener */] = function (listener) {
_self.getNotifyMgr()[_DYN_ADD_NOTIFICATION_LIS1 /* @min:%2eaddNotificationListener */](listener);
};
/**
* Removes all instances of the listener.
* @param listener - INotificationListener to remove.
*/
_self[_DYN_REMOVE_NOTIFICATION_0 /* @min:%2eremoveNotificationListener */] = function (listener) {
if (_notificationManager) {
_notificationManager[_DYN_REMOVE_NOTIFICATION_0 /* @min:%2eremoveNotificationListener */](listener);
}
};
_self.getCookieMgr = function () {
if (!_cookieManager) {
_cookieManager = createCookieMgr(_configHandler.cfg, _self[_DYN_LOGGER /* @min:%2elogger */]);
}
return _cookieManager;
};
_self.setCookieMgr = function (cookieMgr) {
if (_cookieManager !== cookieMgr) {
runTargetUnload(_cookieManager, false);
_cookieManager = cookieMgr;
}
};
_self[STR_GET_PERF_MGR /* @min:%2egetPerfMgr */] = function () {
return _perfManager || _cfgPerfManager || getGblPerfMgr();
};
_self.setPerfMgr = function (perfMgr) {
_perfManager = perfMgr;
};
// _self.getStatsBeat = (statsBeatState: IStatsBeatState) => {
// // create a new statsbeat if not initialize yet or the endpoint is different
// // otherwise, return the existing one, or null
// if (statsBeatState) {
// if (_statsMgr && _statsMgr.enabled) {
// if (_statsBeat && _statsBeat.endpoint !== statsBeatState.endpoint) {
// // Different endpoint, so unload the existing and create a new one
// _statsBeat.enabled = false;
// _statsBeat = null;
// }
// if (!_statsBeat) {
// // Create a new statsbeat instance
// _statsBeat = _statsMgr.newInst(statsBeatState);
// }
// } else if (_statsBeat) {
// // Disable and remove any previously created statsbeat instance
// _statsBeat.enabled = false;
// _statsBeat = null;
// }
// // Return the current statsbeat instance or null if not created
// return _statsBeat;
// }
// // Return null as no statsbeat state was provided
// return null;
// };
// _self.setStatsMgr = (statsMgr: IStatsMgr) => {
// if (_statsMgr && _statsMgr !== statsMgr) {
// // Disable any previously created statsbeat instance
// if (_statsBeat) {
// _statsBeat.enabled = false;
// _statsBeat = null;
// }
// }
// _statsMgr = statsMgr;
// };
_self.eventCnt = function () {
return _eventQueue[_DYN_LENGTH /* @min:%2elength */];
};
_self.releaseQueue = function () {
if (_isInitialized && _eventQueue[_DYN_LENGTH /* @min:%2elength */] > 0) {
var eventQueue = _eventQueue;
_eventQueue = [];
if (_activeStatus === 2 /* eActiveStatus.ACTIVE */) {
arrForEach(eventQueue, function (event) {
event.iKey = event.iKey || _instrumentationKey;
_createTelCtx()[_DYN_PROCESS_NEXT /* @min:%2eprocessNext */](event);
});
}
else {
// new one for msg ikey
_throwInternal(_logger, 2 /* eLoggingSeverity.WARNING */, 20 /* _eInternalMessageId.FailedToSendQueuedTelemetry */, "core init status is not active");
}
}
};
_self.pollInternalLogs = function (eventName) {
_internalLogsEventName = eventName || null;
_forceStopInternalLogPoller = false;
_internalLogPoller && _internalLogPoller[_DYN_CANCEL /* @min:%2ecancel */]();
return _startLogPoller(true);
};
function _handleIKeyEndpointPromises(theConfig) {
// app Insights core only handle ikey and endpointurl, aisku will handle cs
// But we want to reference these config values so that if any future changes are made
// this will trigger the re-run of the watch function
// and the ikey and endpointUrl will be set to the new values
var ikey = theConfig.instrumentationKey;
var endpointUrl = theConfig.endpointUrl; // do not need to validate endpoint url, if it is null, default one will be set by sender
// Check if we are waiting for previous promises to be resolved, won't apply new changes
if (_activeStatus !== 3 /* eActiveStatus.PENDING */) {
if (isNullOrUndefined(ikey)) {
_instrumentationKey = null;
// if new ikey is null, set status to be inactive, all new events will be saved in memory or dropped
_activeStatus = ActiveStatus.INACTIVE;
var msg = "Please provide instrumentation key";
if (!_isInitialized) {
// only throw error during initialization
throwError(msg);
}
else {
_throwInternal(_logger, 1 /* eLoggingSeverity.CRITICAL */, 100 /* _eInternalMessageId.InvalidInstrumentationKey */, msg);
_releaseQueues();
}
return;
}
var promises = [];
if (isPromiseLike(ikey)) {
promises[_DYN_PUSH /* @min:%2epush */](ikey);
_instrumentationKey = null; // reset current local ikey variable (otherwise it will always be the previous ikeys if timeout is called before promise cb)
}
else {
// string
_instrumentationKey = ikey;
}
if (isPromiseLike(endpointUrl)) {
promises[_DYN_PUSH /* @min:%2epush */](endpointUrl);
_endpoint = null; // reset current local endpoint variable (otherwise it will always be the previous urls if timeout is called before promise cb)
}
else {
// string or null
_endpoint = endpointUrl;
}
// at least have one promise
if (promises[_DYN_LENGTH /* @min:%2elength */]) {
_waitForInitPromises(theConfig, promises);
}
else {
// means no promises
_setStatus();
}
}
}
function _waitForInitPromises(theConfig, promises) {
// reset to false for new dynamic changes
_isStatusSet = false;
_activeStatus = 3 /* eActiveStatus.PENDING */;
var initTimeout = isNotNullOrUndefined(theConfig.initTimeOut) ? theConfig.initTimeOut : maxInitTimeout; // theConfig.initTimeOut could be 0
var allPromises = createSyncAllSettledPromise(promises);
if (_initTimer) {
// Stop any previous timer
_initTimer[_DYN_CANCEL /* @min:%2ecancel */]();
}
_initTimer = scheduleTimeout(function () {
// set _isStatusSet to true
// set active status
// release queues
_initTimer = null;
if (!_isStatusSet) {
_setStatus();
}
}, initTimeout);
doAwaitResponse(allPromises, function (response) {
try {
if (_isStatusSet) {
// promises take too long to resolve, ignore them
// active status should be set by timeout already
return;
}
if (!response.rejected) {
var values = response[_DYN_VALUE /* @min:%2evalue */];
if (values && values[_DYN_LENGTH /* @min:%2elength */]) {
// ikey
var ikeyRes = values[0];
_instrumentationKey = ikeyRes && ikeyRes[_DYN_VALUE /* @min:%2evalue */];
// endpoint
if (values[_DYN_LENGTH /* @min:%2elength */] > 1) {
var endpointRes = values[1];
_endpoint = endpointRes && endpointRes[_DYN_VALUE /* @min:%2evalue */];
}
}
if (_instrumentationKey) {
// if ikey is null, no need to trigger extra dynamic changes for extensions
theConfig.instrumentationKey = _instrumentationKey; // set config.instrumentationKey for extensions to consume
theConfig.endpointUrl = _endpoint; // set config.endpointUrl for extensions to consume
}
}
// set _isStatusSet to true
// set active status
// release queues
_setStatus();
}
catch (e) {
if (!_isStatusSet) {
_setStatus();
}
}
});
}
function _setStatus() {
_isStatusSet = true;
if (isNullOrUndefined(_instrumentationKey)) {
_activeStatus = ActiveStatus.INACTIVE;
_throwInternal(_logger, 1 /* eLoggingSeverity.CRITICAL */, 112 /* _eInternalMessageId.InitPromiseException */, "ikey can't be resolved from promises");
}
else {
_activeStatus = ActiveStatus.ACTIVE;
}
_releaseQueues();
}
function _releaseQueues() {
if (_isInitialized) {
_self.releaseQueue();
_self.pollInternalLogs();
}
}
function _startLogPoller(alwaysStart) {
if ((!_internalLogPoller || !_internalLogPoller[_DYN_ENABLED /* @min:%2eenabled */]) && !_forceStopInternalLogPoller) {
var shouldStart = alwaysStart || (_logger && _logger.queue[_DYN_LENGTH /* @min:%2elength */] > 0);
if (shouldStart) {
if (!_internalLogPollerListening) {
_internalLogPollerListening = true;
// listen for any configuration changes so that changes to the
// interval will cause the timer to be re-initialized
_addUnloadHook(_configHandler[_DYN_WATCH /* @min:%2ewatch */](function (details) {
var interval = details.cfg.diagnosticLogInterval;
if (!interval || !(interval > 0)) {
interval = 10000;
}
var isRunning = false;
if (_internalLogPoller) {
// It was already created so remember it's running and cancel
isRunning = _internalLogPoller[_DYN_ENABLED /* @min:%2eenabled */];
_internalLogPoller[_DYN_CANCEL /* @min:%2ecancel */]();
}
// Create / reconfigure
_internalLogPoller = createTimeout(_flushInternalLogs, interval);
_internalLogPoller.unref();
// Restart if previously running
_internalLogPoller[_DYN_ENABLED /* @min:%2eenabled */] = isRunning;
}));
}
_internalLogPoller[_DYN_ENABLED /* @min:%2eenabled */] = true;
}
}
return _internalLogPoller;
}
_self[_DYN_STOP_POLLING_INTERNA3 /* @min:%2estopPollingInternalLogs */] = function () {
_forceStopInternalLogPoller = true;
_internalLogPoller && _internalLogPoller[_DYN_CANCEL /* @min:%2ecancel */]();
_flushInternalLogs();
};
// Add addTelemetryInitializer
proxyFunctions(_self, function () { return _telemetryInitializerPlugin; }, ["addTelemetryInitializer"]);
_self[_DYN_UNLOAD /* @min:%2eunload */] = function (isAsync, unloadComplete, cbTimeout) {
if (isAsync === void 0) { isAsync = true; }
if (!_isInitialized) {
// The SDK is not initialized
throwError(strSdkNotInitialized);
}
// Check if the SDK still unloading so throw
if (_isUnloading) {
// The SDK is already unloading
throwError(strSdkUnloadingError);
}
var unloadState = {
reason: 50 /* TelemetryUnloadReason.SdkUnload */,
isAsync: isAsync,
flushComplete: false
};
var result;
if (isAsync && !unloadComplete) {
result = createPromise(function (resolve) {
// Set the callback to the promise resolve callback
unloadComplete = resolve;
});
}
var processUnloadCtx = createProcessTelemetryUnloadContext(_getPluginChain(), _self);
processUnloadCtx[_DYN_ON_COMPLETE /* @min:%2eonComplete */](function () {
// if (_statsBeat) {
// // Disable any statsbeat instance
// _statsBeat.enabled = false;
// _statsBeat = null;
// }
_hookContainer.run(_self[_DYN_LOGGER /* @min:%2elogger */]);
// Run any "unload" functions for the _cookieManager, _notificationManager and _logger
doUnloadAll([_cookieManager, _notificationManager, _logger], isAsync, function () {
_initDefaults();
unloadComplete && unloadComplete(unloadState);
});
}, _self);
function _doUnload(flushComplete) {
unloadState.flushComplete = flushComplete;
_isUnloading = true;
// Run all of the unload handlers first (before unloading the plugins)
_unloadHandlers.run(processUnloadCtx, unloadState);
// Stop polling the internal logs
_self[_DYN_STOP_POLLING_INTERNA3 /* @min:%2estopPollingInternalLogs */]();
// Start unloading the components, from this point onwards the SDK should be considered to be in an unstable state
processUnloadCtx[_DYN_PROCESS_NEXT /* @min:%2eprocessNext */](unloadState);
}
_flushInternalLogs();
if (!_flushChannels(isAsync, _doUnload, 6 /* SendRequestReason.SdkUnload */, cbTimeout)) {
_doUnload(false);
}
return result;
};
_self[_DYN_GET_PLUGIN /* @min:%2egetPlugin */] = _getPlugin;
_self.addPlugin = function (plugin, replaceExisting, isAsync, addCb) {
if (!plugin) {
addCb && addCb(false);
_logOrThrowError(strValidationError);
return;
}
var existingPlugin = _getPlugin(plugin[_DYN_IDENTIFIER /* @min:%2eidentifier */]);
if (existingPlugin && !replaceExisting) {
addCb && addCb(false);
_logOrThrowError("Plugin [" + plugin[_DYN_IDENTIFIER /* @min:%2eidentifier */] + "] is already loaded!");
return;
}
var updateState = {
reason: 16 /* TelemetryUpdateReason.PluginAdded */
};
function _addPlugin(removed) {
_configExtensions[_DYN_PUSH /* @min:%2epush */](plugin);
updateState.added = [plugin];
// Re-Initialize the plugin chain
_initPluginChain(updateState);
addCb && addCb(true);
}
if (existingPlugin) {
var removedPlugins_1 = [existingPlugin.plugin];
var unloadState = {
reason: 2 /* TelemetryUnloadReason.PluginReplace */,
isAsync: !!isAsync
};
_removePlugins(removedPlugins_1, unloadState, function (removed) {
if (!removed) {
// Previous plugin was successfully removed or was not installed
addCb && addCb(false);
}
else {
updateState.removed = removedPlugins_1;
updateState.reason |= 32 /* TelemetryUpdateReason.PluginRemoved */;
_addPlugin(true);
}
});
}
else {
_addPlugin(false);
}
};
_self.updateCfg = function (newConfig, mergeExisting) {
if (mergeExisting === void 0) { mergeExisting = true; }
var updateState;
if (_self[_DYN_IS_INITIALIZED /* @min:%2eisInitialized */]()) {
updateState = {
reason: 1 /* TelemetryUpdateReason.ConfigurationChanged */,
cfg: _configHandler.cfg,
oldCfg: deepExtend({}, _configHandler.cfg),
newConfig: deepExtend({}, newConfig),
merge: mergeExisting
};
newConfig = updateState.newConfig;
var cfg = _configHandler.cfg;
// replace the immutable (if initialized) values
// We don't currently allow updating the extensions and channels via the update config
// So overwriting any user provided values to reuse the existing values
newConfig[STR_EXTENSIONS /* @min:%2eextensions */] = cfg[STR_EXTENSIONS /* @min:%2eextensions */];
newConfig[STR_CHANNELS /* @min:%2echannels */] = cfg[STR_CHANNELS /* @min:%2echannels */];
}
// Explicitly blocking any previous config watchers so that they don't get called because
// of this bulk update (Probably not necessary)
_configHandler._block(function (details) {
// Lets assign the new values to the existing config either overwriting or re-assigning
var theConfig = details.cfg;
_deepMergeConfig(details, theConfig, newConfig, mergeExisting);
if (!mergeExisting) {
// Remove (unassign) the values "missing" from the newConfig and also not in the default config
objForEachKey(theConfig, function (key) {
if (!objHasOwn(newConfig, key)) {
// Set the value to undefined
details.set(theConfig, key, UNDEFINED_VALUE);
}
});
}
// Apply defaults to the new config
details.setDf(theConfig, defaultConfig);
}, true);
// Now execute all of the listeners (synchronously) so they update their values immediately
_configHandler.notify();
if (updateState) {
_doUpdate(updateState);
}
};
_self.evtNamespace = function () {
return _evtNamespace;
};
_self.flush = _flushChannels;
_self.getTraceCtx = function (createNew) {
if (!_traceCtx) {
_traceCtx = createDistributedTraceContext();
}
return _traceCtx;
};
_self.setTraceCtx = function (traceCtx) {
_traceCtx = traceCtx || null;
};
_self.addUnloadHook = _addUnloadHook;
// Create the addUnloadCb
proxyFunctionAs(_self, "addUnloadCb", function () { return _unloadHandlers; }, "add");
_self.onCfgChange = function (handler) {
var unloadHook;
if (!_isInitialized) {
unloadHook = _addDelayedCfgListener(_cfgListeners, handler);
}
else {
unloadHook = onConfigChange(_configHandler.cfg, handler, _self[_DYN_LOGGER /* @min:%2elogger */]);
}
return _createUnloadHook(unloadHook);
};
_self.getWParam = function () {
return (hasDocument() || !!_configHandler.cfg.enableWParam) ? 0 : -1;
};
function _setPluginVersions() {
var thePlugins = {};
_pluginVersionStringArr = [];
var _addPluginVersions = function (plugins) {
if (plugins) {
arrForEach(plugins, function (plugin) {
if (plugin[_DYN_IDENTIFIER /* @min:%2eidentifier */] && plugin[_DYN_VERSION /* @min:%2eversion */] && !thePlugins[plugin.identifier]) {
var ver = plugin[_DYN_IDENTIFIER /* @min:%2eidentifier */] + "=" + plugin[_DYN_VERSION /* @min:%2eversion */];
_pluginVersionStringArr[_DYN_PUSH /* @min:%2epush */](ver);
thePlugins[plugin.identifier] = plugin;
}
});
}
};
_addPluginVersions(_channels);
if (_channelConfig) {
arrForEach(_channelConfig, function (channels) {
_addPluginVersions(channels);
});
}
_addPluginVersions(_configExtensions);
}
function _initDefaults() {
_isInitialized = false;
// Use a default logger so initialization errors are not dropped on the floor with full logging
_configHandler = createDynamicConfig({}, defaultConfig, _self[_DYN_LOGGER /* @min:%2elogger */]);
// Set the logging level to critical so that any critical initialization failures are displayed on the console
_configHandler.cfg[_DYN_LOGGING_LEVEL_CONSOL4 /* @min:%2eloggingLevelConsole */] = 1 /* eLoggingSeverity.CRITICAL */;
// Define _self.config
objDefine(_self, "config", {
g: function () { return _configHandler.cfg; },
s: function (newValue) {
_self.updateCfg(newValue, false);
}
});
objDefine(_self, "pluginVersionStringArr", {
g: function () {
if (!_pluginVersionStringArr) {
_setPluginVersions();
}
return _pluginVersionStringArr;
}
});
objDefine(_self, "pluginVersionString", {
g: function () {
if (!_pluginVersionString) {
if (!_pluginVersionStringArr) {
_setPluginVersions();
}
_pluginVersionString = _pluginVersionStringArr.join(";");
}
return _pluginVersionString || STR_EMPTY;
}
});
objDefine(_self, "logger", {
g: function () {
if (!_logger) {
_logger = new DiagnosticLogger(_configHandler.cfg);
_configHandler[_DYN_LOGGER /* @min:%2elogger */] = _logger;
}
return _logger;
},
s: function (newLogger) {
_configHandler[_DYN_LOGGER /* @min:%2elogger */] = newLogger;
if (_logger !== newLogger) {
runTargetUnload(_logger, false);
_logger = newLogger;
}
}
});
_self[_DYN_LOGGER /* @min:%2elogger */] = new DiagnosticLogger(_configHandler.cfg);
_extensions = [];
var cfgExtensions = _self.config[STR_EXTENSIONS /* @min:%2eextensions */] || [];
cfgExtensions.splice(0, cfgExtensions[_DYN_LENGTH /* @min:%2elength */]);
arrAppend(cfgExtensions, _extensions);
_telemetryInitializerPlugin = new TelemetryInitializerPlugin();
_eventQueue = [];
runTargetUnload(_notificationManager, false);
_notificationManager = null;
_perfManager = null;
// _statsBeat = null;
_cfgPerfManager = null;
runTargetUnload(_cookieManager, false);
_cookieManager = null;
_pluginChain = null;
_configExtensions = [];
_channelConfig = null;
_channels = null;
_isUnloading = false;
_internalLogsEventName = null;
_evtNamespace = createUniqueNamespace("AIBaseCore", true);
_unloadHandlers = createUnloadHandlerContainer();
_traceCtx = null;
_instrumentationKey = null;
_hookContainer = createUnloadHookContainer();
_cfgListeners = [];
_pluginVersionString = null;
_pluginVersionStringArr = null;
_forceStopInternalLogPoller = false;
_internalLogPoller = null;
_internalLogPollerListening = false;
_activeStatus = 0 /* eActiveStatus.NONE */; // default is None
_endpoint = null;
_initInMemoMaxSize = null;
_isStatusSet = false;
_initTimer = null;
// if (_statsBeat) {
// // Unload and disable any statsbeat instance
// _statsBeat.enabled = false;
// }
// _statsBeat = null;
}
function _createTelCtx() {
var theCtx = createProcessTelemetryContext(_getPluginChain(), _configHandler.cfg, _self);
theCtx[_DYN_ON_COMPLETE /* @min:%2eonComplete */](_startLogPoller);
return theCtx;
}
// Initialize or Re-initialize the plugins
function _initPluginChain(updateState) {
// Extension validation
var theExtensions = _validateExtensions(_self[_DYN_LOGGER /* @min:%2elogger */], ChannelControllerPriority, _configExtensions);
_pluginChain = null;
_pluginVersionString = null;
_pluginVersionStringArr = null;
// Get the primary channel queue and include as part of the normal extensions
_channels = (_channelConfig || [])[0] || [];
// Add any channels provided in the extensions and sort them
_channels = sortPlugins(arrAppend(_channels, theExtensions[STR_CHANNELS /* @min:%2echannels */]));
// Create an array of all extensions, including the _channels
var allExtensions = arrAppend(sortPlugins(theExtensions[STR_CORE /* @min:%2ecore */]), _channels);
// Required to allow plugins to call core.getPlugin() during their own initialization
_extensions = objFreeze(allExtensions);
// This has a side effect of adding the extensions passed during initialization
// into