@microsoft/applicationinsights-core-js 2.8.0-beta.2203-02 → 2.8.0-beta.2203-05

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. package/browser/applicationinsights-core-js.integrity.json +9 -9
  2. package/browser/applicationinsights-core-js.js +319 -29
  3. package/browser/applicationinsights-core-js.js.map +1 -1
  4. package/browser/applicationinsights-core-js.min.js +2 -2
  5. package/browser/applicationinsights-core-js.min.js.map +1 -1
  6. package/dist/applicationinsights-core-js.api.json +2458 -250
  7. package/dist/applicationinsights-core-js.api.md +87 -7
  8. package/dist/applicationinsights-core-js.d.ts +192 -7
  9. package/dist/applicationinsights-core-js.js +319 -29
  10. package/dist/applicationinsights-core-js.js.map +1 -1
  11. package/dist/applicationinsights-core-js.min.js +2 -2
  12. package/dist/applicationinsights-core-js.min.js.map +1 -1
  13. package/dist/applicationinsights-core-js.rollup.d.ts +195 -10
  14. package/dist-esm/JavaScriptSDK/AppInsightsCore.js +1 -1
  15. package/dist-esm/JavaScriptSDK/BaseCore.js +205 -13
  16. package/dist-esm/JavaScriptSDK/BaseCore.js.map +1 -1
  17. package/dist-esm/JavaScriptSDK/BaseTelemetryPlugin.js +37 -3
  18. package/dist-esm/JavaScriptSDK/BaseTelemetryPlugin.js.map +1 -1
  19. package/dist-esm/JavaScriptSDK/ChannelController.js +14 -2
  20. package/dist-esm/JavaScriptSDK/ChannelController.js.map +1 -1
  21. package/dist-esm/JavaScriptSDK/Constants.js +1 -1
  22. package/dist-esm/JavaScriptSDK/CookieMgr.js +3 -2
  23. package/dist-esm/JavaScriptSDK/CookieMgr.js.map +1 -1
  24. package/dist-esm/JavaScriptSDK/CoreUtils.js +1 -1
  25. package/dist-esm/JavaScriptSDK/DataCacheHelper.js +1 -1
  26. package/dist-esm/JavaScriptSDK/DbgExtensionUtils.js +1 -1
  27. package/dist-esm/JavaScriptSDK/DiagnosticLogger.js +14 -1
  28. package/dist-esm/JavaScriptSDK/DiagnosticLogger.js.map +1 -1
  29. package/dist-esm/JavaScriptSDK/EnvUtils.js +1 -1
  30. package/dist-esm/JavaScriptSDK/EventHelpers.js +18 -13
  31. package/dist-esm/JavaScriptSDK/EventHelpers.js.map +1 -1
  32. package/dist-esm/JavaScriptSDK/HelperFuncs.js +3 -13
  33. package/dist-esm/JavaScriptSDK/HelperFuncs.js.map +1 -1
  34. package/dist-esm/JavaScriptSDK/InstrumentHooks.js +1 -1
  35. package/dist-esm/JavaScriptSDK/InternalConstants.js +1 -1
  36. package/dist-esm/JavaScriptSDK/NotificationManager.js +1 -1
  37. package/dist-esm/JavaScriptSDK/PerfManager.js +1 -1
  38. package/dist-esm/JavaScriptSDK/ProcessTelemetryContext.js +71 -6
  39. package/dist-esm/JavaScriptSDK/ProcessTelemetryContext.js.map +1 -1
  40. package/dist-esm/JavaScriptSDK/RandomHelper.js +1 -1
  41. package/dist-esm/JavaScriptSDK/TelemetryHelpers.js +1 -1
  42. package/dist-esm/JavaScriptSDK/TelemetryInitializerPlugin.js +3 -2
  43. package/dist-esm/JavaScriptSDK/TelemetryInitializerPlugin.js.map +1 -1
  44. package/dist-esm/JavaScriptSDK/UnloadHandlerContainer.js +33 -0
  45. package/dist-esm/JavaScriptSDK/UnloadHandlerContainer.js.map +1 -0
  46. package/dist-esm/JavaScriptSDK.Enums/EventsDiscardedReason.js +1 -1
  47. package/dist-esm/JavaScriptSDK.Enums/LoggingEnums.js +1 -1
  48. package/dist-esm/JavaScriptSDK.Enums/SendRequestReason.js +1 -1
  49. package/dist-esm/JavaScriptSDK.Enums/TelemetryUnloadReason.js +1 -1
  50. package/dist-esm/JavaScriptSDK.Enums/TelemetryUpdateReason.js +8 -0
  51. package/dist-esm/JavaScriptSDK.Enums/TelemetryUpdateReason.js.map +1 -0
  52. package/dist-esm/JavaScriptSDK.Interfaces/IAppInsightsCore.js +1 -1
  53. package/dist-esm/JavaScriptSDK.Interfaces/IChannelControls.js +1 -1
  54. package/dist-esm/JavaScriptSDK.Interfaces/IConfiguration.js +1 -1
  55. package/dist-esm/JavaScriptSDK.Interfaces/ICookieMgr.js +1 -1
  56. package/dist-esm/JavaScriptSDK.Interfaces/IDbgExtension.js +1 -1
  57. package/dist-esm/JavaScriptSDK.Interfaces/IDiagnosticLogger.js +1 -1
  58. package/dist-esm/JavaScriptSDK.Interfaces/IInstrumentHooks.js +1 -1
  59. package/dist-esm/JavaScriptSDK.Interfaces/INotificationListener.js +1 -1
  60. package/dist-esm/JavaScriptSDK.Interfaces/INotificationManager.js +1 -1
  61. package/dist-esm/JavaScriptSDK.Interfaces/IPerfEvent.js +1 -1
  62. package/dist-esm/JavaScriptSDK.Interfaces/IPerfManager.js +1 -1
  63. package/dist-esm/JavaScriptSDK.Interfaces/IProcessTelemetryContext.js +1 -1
  64. package/dist-esm/JavaScriptSDK.Interfaces/ITelemetryInitializers.js +1 -1
  65. package/dist-esm/JavaScriptSDK.Interfaces/ITelemetryItem.js +1 -1
  66. package/dist-esm/JavaScriptSDK.Interfaces/ITelemetryPlugin.js +1 -1
  67. package/dist-esm/JavaScriptSDK.Interfaces/ITelemetryPluginChain.js +1 -1
  68. package/dist-esm/JavaScriptSDK.Interfaces/ITelemetryUnloadState.js +1 -1
  69. package/dist-esm/JavaScriptSDK.Interfaces/ITelemetryUpdateState.js +8 -0
  70. package/dist-esm/JavaScriptSDK.Interfaces/ITelemetryUpdateState.js.map +1 -0
  71. package/dist-esm/applicationinsights-core-js.js +3 -2
  72. package/dist-esm/applicationinsights-core-js.js.map +1 -1
  73. package/package.json +1 -1
  74. package/src/JavaScriptSDK/BaseCore.ts +272 -14
  75. package/src/JavaScriptSDK/BaseTelemetryPlugin.ts +70 -4
  76. package/src/JavaScriptSDK/ChannelController.ts +18 -1
  77. package/src/JavaScriptSDK/CookieMgr.ts +3 -1
  78. package/src/JavaScriptSDK/DiagnosticLogger.ts +14 -0
  79. package/src/JavaScriptSDK/EventHelpers.ts +18 -12
  80. package/src/JavaScriptSDK/HelperFuncs.ts +4 -2
  81. package/src/JavaScriptSDK/ProcessTelemetryContext.ts +87 -10
  82. package/src/JavaScriptSDK/TelemetryInitializerPlugin.ts +3 -1
  83. package/src/JavaScriptSDK/UnloadHandlerContainer.ts +46 -0
  84. package/src/JavaScriptSDK.Enums/SendRequestReason.ts +5 -0
  85. package/src/JavaScriptSDK.Enums/TelemetryUnloadReason.ts +3 -3
  86. package/src/JavaScriptSDK.Enums/TelemetryUpdateReason.ts +27 -0
  87. package/src/JavaScriptSDK.Interfaces/IAppInsightsCore.ts +29 -2
  88. package/src/JavaScriptSDK.Interfaces/IInstrumentHooks.ts +11 -6
  89. package/src/JavaScriptSDK.Interfaces/IProcessTelemetryContext.ts +25 -2
  90. package/src/JavaScriptSDK.Interfaces/ITelemetryPlugin.ts +12 -1
  91. package/src/JavaScriptSDK.Interfaces/ITelemetryUpdateState.ts +34 -0
  92. package/types/JavaScriptSDK/BaseCore.d.ts +27 -2
  93. package/types/JavaScriptSDK/BaseTelemetryPlugin.d.ts +23 -1
  94. package/types/JavaScriptSDK/DiagnosticLogger.d.ts +10 -0
  95. package/types/JavaScriptSDK/EventHelpers.d.ts +4 -2
  96. package/types/JavaScriptSDK/HelperFuncs.d.ts +2 -1
  97. package/types/JavaScriptSDK/ProcessTelemetryContext.d.ts +11 -1
  98. package/types/JavaScriptSDK/UnloadHandlerContainer.d.ts +11 -0
  99. package/types/JavaScriptSDK.Enums/SendRequestReason.d.ts +4 -0
  100. package/types/JavaScriptSDK.Enums/TelemetryUnloadReason.d.ts +13 -1
  101. package/types/JavaScriptSDK.Enums/TelemetryUpdateReason.d.ts +20 -0
  102. package/types/JavaScriptSDK.Interfaces/IAppInsightsCore.d.ts +24 -1
  103. package/types/JavaScriptSDK.Interfaces/IInstrumentHooks.d.ts +5 -0
  104. package/types/JavaScriptSDK.Interfaces/IProcessTelemetryContext.d.ts +23 -2
  105. package/types/JavaScriptSDK.Interfaces/ITelemetryPlugin.d.ts +11 -1
  106. package/types/JavaScriptSDK.Interfaces/ITelemetryUpdateState.d.ts +22 -0
  107. package/types/applicationinsights-core-js.d.ts +6 -2
@@ -49,12 +49,12 @@ function _normalizeNamespace(name: string) {
49
49
  return name;
50
50
  }
51
51
 
52
- function _getEvtNamespace(eventName: string, namespaces: string | string[]): IEventDetails {
53
- if (namespaces) {
52
+ function _getEvtNamespace(eventName: string, evtNamespace?: string | string[]): IEventDetails {
53
+ if (evtNamespace) {
54
54
  let theNamespace: string = "";
55
- if (isArray(namespaces)) {
55
+ if (isArray(evtNamespace)) {
56
56
  theNamespace = "";
57
- arrForEach(namespaces, (name) => {
57
+ arrForEach(evtNamespace, (name) => {
58
58
  name = _normalizeNamespace(name);
59
59
  if (name) {
60
60
  if (name[0] !== ".") {
@@ -65,7 +65,7 @@ function _getEvtNamespace(eventName: string, namespaces: string | string[]): IEv
65
65
  }
66
66
  });
67
67
  } else {
68
- theNamespace = _normalizeNamespace(namespaces);
68
+ theNamespace = _normalizeNamespace(evtNamespace);
69
69
  }
70
70
 
71
71
  if (theNamespace) {
@@ -96,18 +96,24 @@ export interface _IRegisteredEvents {
96
96
  * Get all of the registered events on the target object, this is primarily used for testing cleanup but may also be used by
97
97
  * applications to remove their own events
98
98
  * @param target - The EventTarget that has registered events
99
- * @param evtName - [Optional] The name of the event to return the registered handlers and full name (with namespaces)
99
+ * @param eventName - [Optional] The name of the event to return the registered handlers and full name (with namespaces)
100
+ * @param evtNamespace - [Optional] Additional namespace(s) to append to the event listeners so they can be uniquely identified and removed based on this namespace,
101
+ * if the eventName also includes a namespace the namespace(s) are merged into a single namespace
100
102
  */
101
- export function __getRegisteredEvents(target: any, evtName?: string): _IRegisteredEvents[] {
103
+ export function __getRegisteredEvents(target: any, eventName?: string, evtNamespace?: string | string[]): _IRegisteredEvents[] {
102
104
  let theEvents: _IRegisteredEvents[] = [];
103
105
  let eventCache = elmNodeData.get<IAiEvents>(target, strEvents, {}, false);
106
+ let evtName = _getEvtNamespace(eventName, evtNamespace);
107
+
104
108
  objForEachKey(eventCache, (evtType, registeredEvents) => {
105
109
  arrForEach(registeredEvents, (value) => {
106
- if (!evtName || evtName === value.evtName.type) {
107
- theEvents.push({
108
- name: value.evtName.type + (value.evtName.ns ? "." + value.evtName.ns : ""),
109
- handler: value.handler
110
- });
110
+ if (!evtName.type || evtName.type === value.evtName.type) {
111
+ if (!evtName.ns || evtName.ns === evtName.ns) {
112
+ theEvents.push({
113
+ name: value.evtName.type + (value.evtName.ns ? "." + value.evtName.ns : ""),
114
+ handler: value.handler
115
+ });
116
+ }
111
117
  }
112
118
  });
113
119
  });
@@ -836,7 +836,7 @@ export function createEnumStyle<T>(values: T) {
836
836
  enumClass[field] = value;
837
837
  // Add Reverse lookup
838
838
  if (!isUndefined(enumClass[value])) {
839
- throwError("Value: [" + value + "] already exists for " + field);
839
+ throwError("[" + value + "] exists for " + field);
840
840
  }
841
841
  enumClass[value] = field;
842
842
  });
@@ -871,7 +871,9 @@ export function optimizeObject<T>(theObject: T): T {
871
871
  * @param obj5 - object to merge.
872
872
  * @returns The extended first object.
873
873
  */
874
- export function objExtend<T1, T2, T3, T4, T5, T6>(obj?: boolean | T1, obj2?: T2, obj3?: T3, obj4?: T4, obj5?: T5, obj6?: T6): T1 & T2 & T3 & T4 & T5 & T6 {
874
+ export function objExtend<T2, T3, T4, T5, T6>(deepExtend?: boolean, obj2?: T2, obj3?: T3, obj4?: T4, obj5?: T5, obj6?: T6): T2 & T3 & T4 & T5 & T6
875
+ export function objExtend<T1, T2, T3, T4, T5, T6>(obj1?: T1, obj2?: T2, obj3?: T3, obj4?: T4, obj5?: T5, obj6?: T6): T1 & T2 & T3 & T4 & T5 & T6
876
+ export function objExtend<T1, T2, T3, T4, T5, T6>(obj1?: T1 | any, obj2?: T2, obj3?: T3, obj4?: T4, obj5?: T5, obj6?: T6): T1 & T2 & T3 & T4 & T5 & T6 {
875
877
  // Variables
876
878
  let theArgs = arguments as any;
877
879
  let extended: T1 & T2 & T3 & T4 & T5 & T6 = theArgs[0] || {};
@@ -6,16 +6,17 @@ import { IAppInsightsCore } from "../JavaScriptSDK.Interfaces/IAppInsightsCore";
6
6
  import { IConfiguration } from "../JavaScriptSDK.Interfaces/IConfiguration";
7
7
  import { ITelemetryItem } from "../JavaScriptSDK.Interfaces/ITelemetryItem";
8
8
  import { IPlugin, ITelemetryPlugin } from "../JavaScriptSDK.Interfaces/ITelemetryPlugin";
9
- import { GetExtCfgMergeType, IBaseProcessingContext, IProcessTelemetryContext, IProcessTelemetryUnloadContext } from "../JavaScriptSDK.Interfaces/IProcessTelemetryContext";
9
+ import { GetExtCfgMergeType, IBaseProcessingContext, IProcessTelemetryContext, IProcessTelemetryUnloadContext, IProcessTelemetryUpdateContext } from "../JavaScriptSDK.Interfaces/IProcessTelemetryContext";
10
10
  import { ITelemetryPluginChain } from "../JavaScriptSDK.Interfaces/ITelemetryPluginChain";
11
- import { safeGetLogger } from "./DiagnosticLogger";
11
+ import { safeGetLogger, _throwInternal } from "./DiagnosticLogger";
12
12
  import { arrForEach, isArray, isFunction, isNullOrUndefined, isObject, isUndefined, objExtend, objForEachKey, objFreeze, objKeys, proxyFunctions } from "./HelperFuncs";
13
13
  import { doPerf } from "./PerfManager";
14
14
  import { eLoggingSeverity, _eInternalMessageId } from "../JavaScriptSDK.Enums/LoggingEnums";
15
15
  import { dumpObj } from "./EnvUtils";
16
- import { strCore, strDisabled, strEmpty, strIsInitialized, strTeardown } from "./InternalConstants";
16
+ import { strCore, strDisabled, strEmpty, strIsInitialized, strTeardown, strUpdate } from "./InternalConstants";
17
17
  import { IDiagnosticLogger } from "../JavaScriptSDK.Interfaces/IDiagnosticLogger";
18
18
  import { ITelemetryUnloadState } from "../JavaScriptSDK.Interfaces/ITelemetryUnloadState";
19
+ import { ITelemetryUpdateState } from "../JavaScriptSDK.Interfaces/ITelemetryUpdateState";
19
20
  import { _getPluginState } from "./TelemetryHelpers";
20
21
 
21
22
  const strTelemetryPluginChain = "TelemetryPluginChain";
@@ -55,12 +56,25 @@ function _getNextProxyStart(proxy: ITelemetryPluginChain, config: IConfiguration
55
56
  return createTelemetryProxyChain([startAt], config, core);
56
57
  }
57
58
 
59
+ /**
60
+ * @ignore
61
+ * @param telemetryChain
62
+ * @param config
63
+ * @param core
64
+ * @param startAt - Identifies the next plugin to execute, if null there is no "next" plugin and if undefined it should assume the start of the chain
65
+ * @returns
66
+ */
58
67
  function _createInternalContext<T extends IBaseProcessingContext>(telemetryChain: ITelemetryPluginChain, config: IConfiguration, core:IAppInsightsCore, startAt?: IPlugin): IInternalContext<T> {
59
68
  // We have a special case where we want to start execution from this specific plugin
60
69
  // or we simply reuse the existing telemetry plugin chain (normal execution case)
61
- let _nextProxy: ITelemetryPluginChain = startAt ? _getNextProxyStart(telemetryChain, config, core, startAt) : telemetryChain;
70
+ let _nextProxy: ITelemetryPluginChain = null; // By Default set as no next plugin
62
71
  let _onComplete: OnCompleteCallback[] = [];
63
72
 
73
+ if (startAt !== null) {
74
+ // There is no next element (null) vs not defined (undefined) so use the full chain
75
+ _nextProxy = startAt ? _getNextProxyStart(telemetryChain, config, core, startAt) : telemetryChain;
76
+ }
77
+
64
78
  let context: IInternalContext<T> = {
65
79
  _next: _moveNext,
66
80
  ctx: {
@@ -110,10 +124,11 @@ function _createInternalContext<T extends IBaseProcessingContext>(telemetryChain
110
124
  try {
111
125
  completeDetails.func.call(completeDetails.self, completeDetails.args);
112
126
  } catch (e) {
113
- core.logger.throwInternal(
114
- eLoggingSeverity.WARNING,
115
- _eInternalMessageId.PluginException,
116
- "Unexpected Exception during onComplete - " + dumpObj(e));
127
+ _throwInternal(
128
+ core.logger,
129
+ eLoggingSeverity.WARNING,
130
+ _eInternalMessageId.PluginException,
131
+ "Unexpected Exception during onComplete - " + dumpObj(e));
117
132
  }
118
133
  });
119
134
 
@@ -192,9 +207,9 @@ function _createInternalContext<T extends IBaseProcessingContext>(telemetryChain
192
207
  * @param plugins - The plugin instances that will be executed
193
208
  * @param config - The current config
194
209
  * @param core - The current core instance
210
+ * @param startAt - Identifies the next plugin to execute, if null there is no "next" plugin and if undefined it should assume the start of the chain
195
211
  */
196
212
  export function createProcessTelemetryContext(telemetryChain: ITelemetryPluginChain, config: IConfiguration, core:IAppInsightsCore, startAt?: IPlugin): IProcessTelemetryContext {
197
-
198
213
  let internalContext: IInternalContext<IProcessTelemetryContext> = _createInternalContext<IProcessTelemetryContext>(telemetryChain, config, core, startAt);
199
214
  let context = internalContext.ctx;
200
215
 
@@ -225,6 +240,7 @@ export function createProcessTelemetryContext(telemetryChain: ITelemetryPluginCh
225
240
  * @param plugins - The plugin instances that will be executed
226
241
  * @param config - The current config
227
242
  * @param core - The current core instance
243
+ * @param startAt - Identifies the next plugin to execute, if null there is no "next" plugin and if undefined it should assume the start of the chain
228
244
  */
229
245
  export function createProcessTelemetryUnloadContext(telemetryChain: ITelemetryPluginChain, config: IConfiguration, core:IAppInsightsCore, startAt?: IPlugin): IProcessTelemetryUnloadContext {
230
246
  let internalContext: IInternalContext<IProcessTelemetryUnloadContext> = _createInternalContext<IProcessTelemetryUnloadContext>(telemetryChain, config, core, startAt);
@@ -251,6 +267,38 @@ export function createProcessTelemetryUnloadContext(telemetryChain: ITelemetryPl
251
267
  return context;
252
268
  }
253
269
 
270
+ /**
271
+ * Creates a new Telemetry Item context with the current config, core and plugin execution chain for updating the configuration
272
+ * @param plugins - The plugin instances that will be executed
273
+ * @param config - The current config
274
+ * @param core - The current core instance
275
+ * @param startAt - Identifies the next plugin to execute, if null there is no "next" plugin and if undefined it should assume the start of the chain
276
+ */
277
+ export function createProcessTelemetryUpdateContext(telemetryChain: ITelemetryPluginChain, config: IConfiguration, core:IAppInsightsCore, startAt?: IPlugin): IProcessTelemetryUpdateContext {
278
+ let internalContext: IInternalContext<IProcessTelemetryUpdateContext> = _createInternalContext<IProcessTelemetryUpdateContext>(telemetryChain, config, core, startAt);
279
+ let context = internalContext.ctx;
280
+
281
+ function _processNext(updateState: ITelemetryUpdateState) {
282
+ return context.iterate((plugin) => {
283
+ if (isFunction(plugin[strUpdate])) {
284
+ plugin[strUpdate](context, updateState);
285
+ }
286
+ });
287
+ }
288
+
289
+ function _createNew(plugins: IPlugin[] | ITelemetryPluginChain = null, startAt?: IPlugin) {
290
+ if (isArray(plugins)) {
291
+ plugins = createTelemetryProxyChain(plugins, config, core, startAt);
292
+ }
293
+
294
+ return createProcessTelemetryUpdateContext(plugins || context.getNext(), config, core, startAt);
295
+ }
296
+
297
+ context.processNext = _processNext;
298
+ context.createNew = _createNew;
299
+
300
+ return context;
301
+ }
254
302
 
255
303
  /**
256
304
  * Creates an execution chain from the array of plugins
@@ -326,6 +374,7 @@ export function createTelemetryPluginProxy(plugin: ITelemetryPlugin, config: ICo
326
374
  },
327
375
  processTelemetry: _processTelemetry,
328
376
  unload: _unloadPlugin,
377
+ update: _updatePlugin,
329
378
  _id: chainId,
330
379
  _setNext: (nextPlugin: IInternalTelemetryPluginChain) => {
331
380
  nextProxy = nextPlugin;
@@ -391,7 +440,8 @@ export function createTelemetryPluginProxy(plugin: ITelemetryPlugin, config: ICo
391
440
 
392
441
  // Either we have no next plugin or the current one did not attempt to call the next plugin
393
442
  // Which means the current one is the root of the failure so log/report this failure
394
- itemCtx.diagLog().throwInternal(
443
+ _throwInternal(
444
+ itemCtx.diagLog(),
395
445
  eLoggingSeverity.CRITICAL,
396
446
  _eInternalMessageId.PluginException,
397
447
  "Plugin [" + plugin.identifier + "] failed during " + name + " - " + dumpObj(error) + ", run flags: " + dumpObj(hasRunContext));
@@ -468,6 +518,33 @@ export function createTelemetryPluginProxy(plugin: ITelemetryPlugin, config: ICo
468
518
  }
469
519
  }
470
520
 
521
+ function _updatePlugin(updateCtx: IProcessTelemetryUpdateContext, updateState: ITelemetryUpdateState) {
522
+
523
+ function _callUpdate() {
524
+ // Setting default of hasRun as false so the proxyProcessFn() is called as teardown() doesn't have to exist or call unloadNext().
525
+ let hasRun = false;
526
+ if (plugin) {
527
+ let pluginState = _getPluginState(plugin);
528
+ let pluginCore = plugin[strCore] || pluginState.core;
529
+
530
+ // Only update the plugin if it was initialized by the current core (i.e. It's not a shared plugin)
531
+ if (plugin && (!pluginCore || pluginCore === updateCtx[strCore]()) && !pluginState[strTeardown]) {
532
+ if (plugin[strUpdate] && plugin[strUpdate](updateCtx, updateState) === true) {
533
+ // plugin told us that it was going to (or has) call unloadCtx.processNext()
534
+ hasRun = true;
535
+ }
536
+ }
537
+ }
538
+
539
+ return hasRun;
540
+ }
541
+
542
+ if (!_processChain(updateCtx, _callUpdate, "update", () => {}, false)) {
543
+ // Only called if we hasRun was not true
544
+ updateCtx.processNext(updateState);
545
+ }
546
+ }
547
+
471
548
  return objFreeze(proxyChain);
472
549
  }
473
550
 
@@ -7,6 +7,7 @@ import { IProcessTelemetryContext } from "../JavaScriptSDK.Interfaces/IProcessTe
7
7
  import { ITelemetryInitializerContainer, ITelemetryInitializerHandler, TelemetryInitializerFunction } from "../JavaScriptSDK.Interfaces/ITelemetryInitializers";
8
8
  import { ITelemetryItem } from "../JavaScriptSDK.Interfaces/ITelemetryItem";
9
9
  import { BaseTelemetryPlugin } from "./BaseTelemetryPlugin";
10
+ import { _throwInternal } from "./DiagnosticLogger";
10
11
  import { dumpObj } from "./EnvUtils";
11
12
  import { arrForEach, getExceptionName } from "./HelperFuncs";
12
13
  import { strDoTeardown } from "./InternalConstants";
@@ -68,7 +69,8 @@ export class TelemetryInitializerPlugin extends BaseTelemetryPlugin implements I
68
69
  } catch (e) {
69
70
  // log error but dont stop executing rest of the telemetry initializers
70
71
  // doNotSendItem = true;
71
- itemCtx.diagLog().throwInternal(
72
+ _throwInternal(
73
+ itemCtx.diagLog(),
72
74
  eLoggingSeverity.CRITICAL,
73
75
  _eInternalMessageId.TelemetryInitializerFailed,
74
76
  "One of telemetry initializers failed, telemetry item will not be sent: " + getExceptionName(e),
@@ -0,0 +1,46 @@
1
+ // Copyright (c) Microsoft Corporation. All rights reserved.
2
+ // Licensed under the MIT License.
3
+
4
+ import { eLoggingSeverity, _eInternalMessageId } from "../JavaScriptSDK.Enums/LoggingEnums";
5
+ import { IProcessTelemetryUnloadContext } from "../JavaScriptSDK.Interfaces/IProcessTelemetryContext";
6
+ import { ITelemetryUnloadState } from "../JavaScriptSDK.Interfaces/ITelemetryUnloadState";
7
+ import { _throwInternal } from "./DiagnosticLogger";
8
+ import { dumpObj } from "./EnvUtils";
9
+ import { arrForEach } from "./HelperFuncs";
10
+
11
+ export type UnloadHandler = (itemCtx: IProcessTelemetryUnloadContext, unloadState: ITelemetryUnloadState) => void;
12
+
13
+ export interface IUnloadHandlerContainer {
14
+ add: (handler: UnloadHandler) => void;
15
+ run: (itemCtx: IProcessTelemetryUnloadContext, unloadState: ITelemetryUnloadState) => void
16
+ }
17
+
18
+ export function createUnloadHandlerContainer() {
19
+ let handlers: UnloadHandler[] = [];
20
+
21
+ function _addHandler(handler: UnloadHandler) {
22
+ if (handler) {
23
+ handlers.push(handler);
24
+ }
25
+ }
26
+
27
+ function _runHandlers(unloadCtx: IProcessTelemetryUnloadContext, unloadState: ITelemetryUnloadState) {
28
+ arrForEach(handlers, (handler) => {
29
+ try {
30
+ handler(unloadCtx, unloadState);
31
+ } catch (e) {
32
+ _throwInternal(
33
+ unloadCtx.diagLog(),
34
+ eLoggingSeverity.WARNING,
35
+ _eInternalMessageId.PluginException,
36
+ "Unexpected error calling unload handler - " + dumpObj(e));
37
+ }
38
+ });
39
+ handlers = [];
40
+ }
41
+
42
+ return {
43
+ add: _addHandler,
44
+ run: _runHandlers
45
+ }
46
+ }
@@ -38,6 +38,11 @@ export const enum SendRequestReason {
38
38
  * The event(s) being sent as a retry
39
39
  */
40
40
  Retry = 5,
41
+
42
+ /**
43
+ * The SDK is unloading
44
+ */
45
+ SdkUnload = 6,
41
46
 
42
47
  /**
43
48
  * Maximum batch size would be exceeded
@@ -13,15 +13,15 @@
13
13
  /**
14
14
  * Just this plugin is being removed
15
15
  */
16
- //PluginUnload = 1,
16
+ PluginUnload = 1,
17
17
 
18
18
  /**
19
19
  * This instance of the plugin is being removed and replaced
20
20
  */
21
- //PluginReplace = 2,
21
+ PluginReplace = 2,
22
22
 
23
23
  /**
24
24
  * The entire SDK is being unloaded
25
25
  */
26
- //SdkUnload = 50
26
+ SdkUnload = 50
27
27
  }
@@ -0,0 +1,27 @@
1
+ // Copyright (c) Microsoft Corporation. All rights reserved.
2
+ // Licensed under the MIT License.
3
+
4
+ /**
5
+ * The TelemetryUpdateReason enumeration contains a set of bit-wise values that specify the reason for update request.
6
+ */
7
+ export const enum TelemetryUpdateReason {
8
+ /**
9
+ * Unknown.
10
+ */
11
+ Unknown = 0,
12
+
13
+ /**
14
+ * The configuration has ben updated or changed
15
+ */
16
+ //ConfigurationChanged = 0x01,
17
+
18
+ /**
19
+ * One or more plugins have been added
20
+ */
21
+ PluginAdded = 0x10,
22
+
23
+ /**
24
+ * One or more plugins have been removed
25
+ */
26
+ PluginRemoved = 0x20,
27
+ }
@@ -2,7 +2,7 @@
2
2
  // Licensed under the MIT License.
3
3
  import { ITelemetryItem } from "./ITelemetryItem";
4
4
  import { IChannelControls } from "./IChannelControls";
5
- import { IPlugin } from "./ITelemetryPlugin";
5
+ import { IPlugin, ITelemetryPlugin } from "./ITelemetryPlugin";
6
6
  import { IConfiguration } from "./IConfiguration";
7
7
  import { INotificationManager } from "./INotificationManager";
8
8
  import { INotificationListener } from "./INotificationListener";
@@ -11,6 +11,7 @@ import { IProcessTelemetryContext } from "./IProcessTelemetryContext";
11
11
  import { IPerfManagerProvider } from "./IPerfManager";
12
12
  import { ICookieMgr } from "./ICookieMgr";
13
13
  import { ITelemetryInitializerHandler, TelemetryInitializerFunction } from "./ITelemetryInitializers";
14
+ import { UnloadHandler } from "../applicationinsights-core-js";
14
15
 
15
16
  export interface ILoadedPlugin<T extends IPlugin> {
16
17
  plugin: T;
@@ -29,6 +30,8 @@ export interface ILoadedPlugin<T extends IPlugin> {
29
30
  * (unless it's also been re-initialized)
30
31
  */
31
32
  setEnabled: (isEnabled: boolean) => void;
33
+
34
+ remove: (isAsync?: boolean, removeCb?: (removed?: boolean) => void) => void;
32
35
  }
33
36
 
34
37
  export interface IAppInsightsCore extends IPerfManagerProvider {
@@ -106,14 +109,38 @@ export interface IAppInsightsCore extends IPerfManagerProvider {
106
109
  */
107
110
  getProcessTelContext() : IProcessTelemetryContext;
108
111
 
112
+ /**
113
+ * Unload and Tear down the SDK and any initialized plugins, after calling this the SDK will be considered
114
+ * to be un-initialized and non-operational, re-initializing the SDK should only be attempted if the previous
115
+ * unload call return `true` stating that all plugins reported that they also unloaded, the recommended
116
+ * approach is to create a new instance and initialize that instance.
117
+ * This is due to possible unexpected side effects caused by plugins not supporting unload / teardown, unable
118
+ * to successfully remove any global references or they may just be completing the unload process asynchronously.
119
+ */
120
+ unload(isAsync?: boolean, unloadComplete?: () => void): void;
121
+
109
122
  /**
110
123
  * Find and return the (first) plugin with the specified identifier if present
111
124
  * @param pluginIdentifier
112
125
  */
113
126
  getPlugin<T extends IPlugin = IPlugin>(pluginIdentifier: string): ILoadedPlugin<T>;
114
127
 
128
+ /**
129
+ * Add a new plugin to the installation
130
+ * @param plugin - The new plugin to add
131
+ * @param replaceExisting - should any existing plugin be replaced
132
+ * @param doAsync - Should the add be performed asynchronously
133
+ */
134
+ addPlugin<T extends IPlugin = ITelemetryPlugin>(plugin: T, replaceExisting: boolean, doAsync: boolean, addCb?: (added?: boolean) => void): void;
135
+
115
136
  /**
116
137
  * Returns the unique event namespace that should be used when registering events
117
138
  */
118
139
  evtNamespace(): string;
119
- }
140
+
141
+ /**
142
+ * Add a handler that will be called when the SDK is being unloaded
143
+ * @param handler - the handler
144
+ */
145
+ addUnloadCb(handler: UnloadHandler): void;
146
+ }
@@ -12,6 +12,11 @@ export type InstrumentorHooksCallback = (funcArgs:IInstrumentCallDetails, ...org
12
12
  * You must always supply the error callback
13
13
  */
14
14
  export interface IInstrumentHooksCallbacks {
15
+ /**
16
+ * [Optional] Namespace details (same as the namespace used for events), useful for debugging and testing to
17
+ * identify the source of the instrumented hooks
18
+ */
19
+ ns?: string | string[];
15
20
 
16
21
  /**
17
22
  * The hook callback to call before the original function is called
@@ -40,20 +45,20 @@ export interface IInstrumentHooksCallbacks {
40
45
  */
41
46
  export interface IInstrumentHook {
42
47
  /** Unique Id for this callback on the hooked method */
43
- id:number;
48
+ id: number;
44
49
 
45
50
  /** Holds the callbacks */
46
- cbks:IInstrumentHooksCallbacks;
51
+ cbks: IInstrumentHooksCallbacks;
47
52
 
48
53
  /** Remove this hook from the function */
49
54
  rm: () => void;
50
55
  }
51
56
 
52
57
  export interface IInstrumentHooks {
53
- i:number; // Used to create unique ids
54
- n:string; // Function name
55
- f:any; // Original Function
56
- h:IInstrumentHook[]; // The hook
58
+ i: number; // Used to create unique ids
59
+ n: string; // Function name
60
+ f: any; // Original Function
61
+ h: IInstrumentHook[]; // The hook
57
62
  }
58
63
 
59
64
  export interface IInstrumentCallDetails {
@@ -9,6 +9,7 @@ import { ITelemetryItem } from "./ITelemetryItem";
9
9
  import { IPlugin, ITelemetryPlugin } from "./ITelemetryPlugin";
10
10
  import { ITelemetryPluginChain } from "./ITelemetryPluginChain";
11
11
  import { ITelemetryUnloadState } from "./ITelemetryUnloadState";
12
+ import { ITelemetryUpdateState } from "./ITelemetryUpdateState";
12
13
 
13
14
  export const enum GetExtCfgMergeType {
14
15
  None = 0,
@@ -110,8 +111,8 @@ export interface IProcessTelemetryContext extends IBaseProcessingContext {
110
111
  }
111
112
 
112
113
  /**
113
- * The current context for the current call to processTelemetry(), used to support sharing the same plugin instance
114
- * between multiple AppInsights instances
114
+ * The current context for the current call to teardown() implementations, used to support when plugins are being removed
115
+ * or the SDK is being unloaded.
115
116
  */
116
117
  export interface IProcessTelemetryUnloadContext extends IBaseProcessingContext {
117
118
 
@@ -131,3 +132,25 @@ export interface IProcessTelemetryUnloadContext extends IBaseProcessingContext {
131
132
  */
132
133
  createNew: (plugins?: IPlugin[] | ITelemetryPluginChain, startAt?: IPlugin) => IProcessTelemetryUnloadContext;
133
134
  }
135
+
136
+ /**
137
+ * The current context for the current call to the plugin update() implementations, used to support the notifications
138
+ * for when plugins are added, removed or the configuration was changed.
139
+ */
140
+ export interface IProcessTelemetryUpdateContext extends IBaseProcessingContext {
141
+ /**
142
+ * This Plugin has finished unloading, so unload the next one
143
+ * @param updateState - The update State
144
+ * @returns boolean (true) if there is no more plugins to process otherwise false or undefined (void)
145
+ */
146
+ processNext: (updateState: ITelemetryUpdateState) => boolean | void;
147
+
148
+ /**
149
+ * Create a new context using the core and config from the current instance, returns a new instance of the same type
150
+ * @param plugins - The execution order to process the plugins, if null or not supplied
151
+ * then the current execution order will be copied.
152
+ * @param startAt - The plugin to start processing from, if missing from the execution
153
+ * order then the next plugin will be NOT set.
154
+ */
155
+ createNew: (plugins?: IPlugin[] | ITelemetryPluginChain, startAt?: IPlugin) => IProcessTelemetryUpdateContext;
156
+ }
@@ -5,9 +5,10 @@
5
5
  import { ITelemetryItem } from "./ITelemetryItem";
6
6
  import { IConfiguration } from "./IConfiguration";
7
7
  import { IAppInsightsCore } from "./IAppInsightsCore";
8
- import { IProcessTelemetryContext, IProcessTelemetryUnloadContext } from "./IProcessTelemetryContext";
8
+ import { IProcessTelemetryContext, IProcessTelemetryUnloadContext, IProcessTelemetryUpdateContext } from "./IProcessTelemetryContext";
9
9
  import { ITelemetryPluginChain } from "./ITelemetryPluginChain";
10
10
  import { ITelemetryUnloadState } from "./ITelemetryUnloadState";
11
+ import { ITelemetryUpdateState } from "./ITelemetryUpdateState";
11
12
 
12
13
  export interface ITelemetryProcessor {
13
14
  /**
@@ -18,6 +19,16 @@ export interface ITelemetryProcessor {
18
19
  * to later plugins (vs appending items to the telemetry item)
19
20
  */
20
21
  processTelemetry: (env: ITelemetryItem, itemCtx?: IProcessTelemetryContext) => void;
22
+
23
+ /**
24
+ * The the plugin should re-evaluate configuration and update any cached configuration settings or
25
+ * plugins. If implemented this method will be called whenever a plugin is added or removed and if
26
+ * the configuration has bee updated.
27
+ * @param updateCtx - This is the context that should be used during updating.
28
+ * @param updateState - The details / state of the update process, it holds details like the current and previous configuration.
29
+ * @returns boolean - true if the plugin has or will call updateCtx.processNext(), this allows the plugin to perform any asynchronous operations.
30
+ */
31
+ update?: (updateCtx: IProcessTelemetryUpdateContext, updateState: ITelemetryUpdateState) => void | boolean;
21
32
  }
22
33
 
23
34
  /**
@@ -0,0 +1,34 @@
1
+ // Copyright (c) Microsoft Corporation. All rights reserved.
2
+ // Licensed under the MIT License.
3
+
4
+ import { TelemetryUpdateReason } from "../JavaScriptSDK.Enums/TelemetryUpdateReason";
5
+ import { IConfiguration } from "./IConfiguration";
6
+ import { IPlugin } from "./ITelemetryPlugin";
7
+
8
+ export interface ITelemetryUpdateState {
9
+
10
+ /**
11
+ * Identifies the reason for the update notification, this is a bitwise numeric value
12
+ */
13
+ reason: TelemetryUpdateReason;
14
+
15
+ /**
16
+ * If this is a configuration update this was the previous configuration that was used
17
+ */
18
+ //prvCfg?: IConfiguration,
19
+
20
+ /**
21
+ * If this is a configuration update is the new configuration that is being used
22
+ */
23
+ //newCfg?: IConfiguration,
24
+
25
+ /**
26
+ * This holds a collection of plugins that have been added (if the reason identifies that one or more plugins have been added)
27
+ */
28
+ added?: IPlugin[];
29
+
30
+ /**
31
+ * This holds a collection of plugins that have been removed (if the reason identifies that one or more plugins have been removed)
32
+ */
33
+ removed?: IPlugin[]
34
+ }
@@ -1,15 +1,18 @@
1
1
  import { IAppInsightsCore, ILoadedPlugin } from "../JavaScriptSDK.Interfaces/IAppInsightsCore";
2
2
  import { IConfiguration } from "../JavaScriptSDK.Interfaces/IConfiguration";
3
- import { IPlugin } from "../JavaScriptSDK.Interfaces/ITelemetryPlugin";
3
+ import { IPlugin, ITelemetryPlugin } from "../JavaScriptSDK.Interfaces/ITelemetryPlugin";
4
4
  import { IChannelControls } from "../JavaScriptSDK.Interfaces/IChannelControls";
5
5
  import { ITelemetryItem } from "../JavaScriptSDK.Interfaces/ITelemetryItem";
6
6
  import { INotificationManager } from "../JavaScriptSDK.Interfaces/INotificationManager";
7
7
  import { INotificationListener } from "../JavaScriptSDK.Interfaces/INotificationListener";
8
8
  import { IDiagnosticLogger } from "../JavaScriptSDK.Interfaces/IDiagnosticLogger";
9
- import { IProcessTelemetryContext } from "../JavaScriptSDK.Interfaces/IProcessTelemetryContext";
9
+ import { IProcessTelemetryContext, IProcessTelemetryUpdateContext } from "../JavaScriptSDK.Interfaces/IProcessTelemetryContext";
10
10
  import { IPerfManager } from "../JavaScriptSDK.Interfaces/IPerfManager";
11
11
  import { ICookieMgr } from "../JavaScriptSDK.Interfaces/ICookieMgr";
12
12
  import { ITelemetryInitializerHandler, TelemetryInitializerFunction } from "../JavaScriptSDK.Interfaces/ITelemetryInitializers";
13
+ import { UnloadHandler } from "./UnloadHandlerContainer";
14
+ import { ITelemetryUpdateState } from "../JavaScriptSDK.Interfaces/ITelemetryUpdateState";
15
+ import { ITelemetryUnloadState } from "../JavaScriptSDK.Interfaces/ITelemetryUnloadState";
13
16
  export declare class BaseCore implements IAppInsightsCore {
14
17
  static defaultConfig: IConfiguration;
15
18
  config: IConfiguration;
@@ -60,10 +63,32 @@ export declare class BaseCore implements IAppInsightsCore {
60
63
  * @returns - A ITelemetryInitializerHandler to enable the initializer to be removed
61
64
  */
62
65
  addTelemetryInitializer(telemetryInitializer: TelemetryInitializerFunction): ITelemetryInitializerHandler | void;
66
+ /**
67
+ * Unload and Tear down the SDK and any initialized plugins, after calling this the SDK will be considered
68
+ * to be un-initialized and non-operational, re-initializing the SDK should only be attempted if the previous
69
+ * unload call return `true` stating that all plugins reported that they also unloaded, the recommended
70
+ * approach is to create a new instance and initialize that instance.
71
+ * This is due to possible unexpected side effects caused by plugins not supporting unload / teardown, unable
72
+ * to successfully remove any global references or they may just be completing the unload process asynchronously.
73
+ */
74
+ unload(isAsync?: boolean, unloadComplete?: (unloadState: ITelemetryUnloadState) => void, cbTimeout?: number): void;
63
75
  getPlugin<T extends IPlugin = IPlugin>(pluginIdentifier: string): ILoadedPlugin<T>;
76
+ addPlugin<T extends IPlugin = ITelemetryPlugin>(plugin: T, replaceExisting: boolean, doAsync: boolean, addCb?: (added?: boolean) => void): void;
64
77
  /**
65
78
  * Returns the unique event namespace that should be used
66
79
  */
67
80
  evtNamespace(): string;
81
+ /**
82
+ * Add an unload handler that will be called when the SDK is being unloaded
83
+ * @param handler - the handler
84
+ */
85
+ addUnloadCb(handler: UnloadHandler): void;
68
86
  protected releaseQueue(): void;
87
+ /**
88
+ * Hook for Core extensions to allow them to update their own configuration before updating all of the plugins.
89
+ * @param updateCtx - The plugin update context
90
+ * @param updateState - The Update State
91
+ * @returns boolean - True means the extension class will call updateState otherwise the Core will
92
+ */
93
+ protected _updateHook?(updateCtx: IProcessTelemetryUpdateContext, updateState: ITelemetryUpdateState): void | boolean;
69
94
  }