@microsoft/applicationinsights-core-js
Version:
Microsoft Application Insights Core Javascript SDK
172 lines (170 loc) • 7.56 kB
JavaScript
/*
* Application Insights JavaScript SDK - Core, 3.3.6
* Copyright (c) Microsoft and contributors. All rights reserved.
*/
import { dumpObj, isUndefined, objDefine, objForEachKey } from "@nevware21/ts-utils";
import { createUniqueNamespace } from "../JavaScriptSDK/DataCacheHelper";
import { STR_NOT_DYNAMIC_ERROR } from "../JavaScriptSDK/InternalConstants";
import { _DYN_THROW_INTERNAL, _DYN_WARN_TO_CONSOLE, _DYN_WATCH } from "../__DynamicConstants";
import { _applyDefaultValue } from "./ConfigDefaults";
import { _makeDynamicObject, _setDynamicProperty, _setDynamicPropertyState, _throwDynamicError } from "./DynamicProperty";
import { _createState } from "./DynamicState";
import { CFG_HANDLER_LINK, _cfgDeepCopy, getDynamicConfigHandler, throwInvalidAccess } from "./DynamicSupport";
/**
* Identifies a function which will be re-called whenever any of it's accessed configuration values
* change.
* @param configHandler - The callback that will be called for the initial request and then whenever any
* accessed configuration changes are identified.
*/
function _createAndUseHandler(state, configHandler) {
var handler = {
fn: configHandler,
rm: function () {
// Clear all references to the handler so it can be garbage collected
// This will also cause this handler to never get called and eventually removed
handler.fn = null;
state = null;
configHandler = null;
}
};
objDefine(handler, "toJSON", { v: function () { return "WatcherHandler" + (handler.fn ? "" : "[X]"); } });
state.use(handler, configHandler);
return handler;
}
/**
* Creates the dynamic config handler and associates with the target config as the root object
* @param target - The config that you want to be root of the dynamic config
* @param inPlace - Should the passed config be converted in-place or a new proxy returned
* @returns The existing dynamic handler or a new instance with the provided config values
*/
function _createDynamicHandler(logger, target, inPlace) {
var dynamicHandler = getDynamicConfigHandler(target);
if (dynamicHandler) {
// The passed config is already dynamic so return it's tracker
return dynamicHandler;
}
var uid = createUniqueNamespace("dyncfg", true);
var newTarget = (target && inPlace !== false) ? target : _cfgDeepCopy(target);
var theState;
function _notifyWatchers() {
theState.notify();
}
function _setValue(target, name, value) {
try {
target = _setDynamicProperty(theState, target, name, value);
}
catch (e) {
// Unable to convert to dynamic property so just leave as non-dynamic
_throwDynamicError(logger, name, "Setting value", e);
}
return target[name];
}
function _watch(configHandler) {
return _createAndUseHandler(theState, configHandler);
}
function _block(configHandler, allowUpdate) {
theState.use(null, function (details) {
var prevUpd = theState.upd;
try {
if (!isUndefined(allowUpdate)) {
theState.upd = allowUpdate;
}
configHandler(details);
}
finally {
theState.upd = prevUpd;
}
});
}
function _ref(target, name) {
var _a;
// Make sure it's dynamic and mark as referenced with it's current value
return _setDynamicPropertyState(theState, target, name, (_a = {}, _a[0 /* _eSetDynamicPropertyFlags.inPlace */] = true, _a))[name];
}
function _rdOnly(target, name) {
var _a;
// Make sure it's dynamic and mark as readonly with it's current value
return _setDynamicPropertyState(theState, target, name, (_a = {}, _a[1 /* _eSetDynamicPropertyFlags.readOnly */] = true, _a))[name];
}
function _blkPropValue(target, name) {
var _a;
// Make sure it's dynamic and mark as readonly with it's current value
return _setDynamicPropertyState(theState, target, name, (_a = {}, _a[2 /* _eSetDynamicPropertyFlags.blockDynamicProperty */] = true, _a))[name];
}
function _applyDefaults(theConfig, defaultValues) {
if (defaultValues) {
// Resolve/apply the defaults
objForEachKey(defaultValues, function (name, value) {
// Sets the value and makes it dynamic (if it doesn't already exist)
_applyDefaultValue(cfgHandler, theConfig, name, value);
});
}
return theConfig;
}
var cfgHandler = {
uid: null,
cfg: newTarget,
logger: logger,
notify: _notifyWatchers,
set: _setValue,
setDf: _applyDefaults,
watch: _watch,
ref: _ref,
rdOnly: _rdOnly,
blkVal: _blkPropValue,
_block: _block
};
objDefine(cfgHandler, "uid", {
c: false,
e: false,
w: false,
v: uid
});
theState = _createState(cfgHandler);
// Setup tracking for all defined default keys
_makeDynamicObject(theState, newTarget, "config", "Creating");
return cfgHandler;
}
/**
* Log an invalid access message to the console
*/
function _logInvalidAccess(logger, message) {
if (logger) {
logger[_DYN_WARN_TO_CONSOLE /* @min:%2ewarnToConsole */](message);
logger[_DYN_THROW_INTERNAL /* @min:%2ethrowInternal */](2 /* eLoggingSeverity.WARNING */, 108 /* _eInternalMessageId.DynamicConfigException */, message);
}
else {
// We don't have a logger so just throw an exception
throwInvalidAccess(message);
}
}
/**
* Create or return a dynamic version of the passed config, if it is not already dynamic
* @param config - The config to be converted into a dynamic config
* @param defaultConfig - The default values to apply on the config if the properties don't already exist
* @param inPlace - Should the config be converted in-place into a dynamic config or a new instance returned, defaults to true
* @returns The dynamic config handler for the config (whether new or existing)
*/
export function createDynamicConfig(config, defaultConfig, logger, inPlace) {
var dynamicHandler = _createDynamicHandler(logger, config || {}, inPlace);
if (defaultConfig) {
dynamicHandler.setDf(dynamicHandler.cfg, defaultConfig);
}
return dynamicHandler;
}
/**
* Watch and track changes for accesses to the current config, the provided config MUST already be
* a dynamic config or a child accessed via the dynamic config
* @param logger - The logger instance to use if there is no existing handler
* @returns A watcher handler instance that can be used to remove itself when being unloaded
* @throws TypeError if the provided config is not a dynamic config instance
*/
export function onConfigChange(config, configHandler, logger) {
var handler = config[CFG_HANDLER_LINK] || config;
if (handler.cfg && (handler.cfg === config || handler.cfg[CFG_HANDLER_LINK] === handler)) {
return handler[_DYN_WATCH /* @min:%2ewatch */](configHandler);
}
_logInvalidAccess(logger, STR_NOT_DYNAMIC_ERROR + dumpObj(config));
return createDynamicConfig(config, null, logger)[_DYN_WATCH /* @min:%2ewatch */](configHandler);
}
//# sourceMappingURL=DynamicConfig.js.map