@microsoft/applicationinsights-offlinechannel-js 0.1.0-nightly3.2402-06

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 (47) hide show
  1. package/CODE_OF_CONDUCT.md +9 -0
  2. package/CONTRIBUTING.md +14 -0
  3. package/LICENSE.TXT +21 -0
  4. package/PRIVACY +3 -0
  5. package/README.md +63 -0
  6. package/SECURITY.md +41 -0
  7. package/SUPPORT.md +14 -0
  8. package/dist/es5/applicationinsights-offlinechannel-js.js +6391 -0
  9. package/dist/es5/applicationinsights-offlinechannel-js.js.map +1 -0
  10. package/dist/es5/applicationinsights-offlinechannel-js.min.js +6 -0
  11. package/dist/es5/applicationinsights-offlinechannel-js.min.js.map +1 -0
  12. package/dist-es5/Helpers/Utils.js +185 -0
  13. package/dist-es5/Helpers/Utils.js.map +1 -0
  14. package/dist-es5/InMemoryBatch.js +64 -0
  15. package/dist-es5/InMemoryBatch.js.map +1 -0
  16. package/dist-es5/Interfaces/IInMemoryBatch.js +8 -0
  17. package/dist-es5/Interfaces/IInMemoryBatch.js.map +1 -0
  18. package/dist-es5/Interfaces/IOfflineBatch.js +9 -0
  19. package/dist-es5/Interfaces/IOfflineBatch.js.map +1 -0
  20. package/dist-es5/Interfaces/IOfflineIndexDb.js +8 -0
  21. package/dist-es5/Interfaces/IOfflineIndexDb.js.map +1 -0
  22. package/dist-es5/Interfaces/IOfflineProvider.js +8 -0
  23. package/dist-es5/Interfaces/IOfflineProvider.js.map +1 -0
  24. package/dist-es5/Interfaces/ISender.js +8 -0
  25. package/dist-es5/Interfaces/ISender.js.map +1 -0
  26. package/dist-es5/OfflineBatchHandler.js +343 -0
  27. package/dist-es5/OfflineBatchHandler.js.map +1 -0
  28. package/dist-es5/OfflineChannel.js +465 -0
  29. package/dist-es5/OfflineChannel.js.map +1 -0
  30. package/dist-es5/PayloadHelper.js +62 -0
  31. package/dist-es5/PayloadHelper.js.map +1 -0
  32. package/dist-es5/Providers/IndexDbHelper.js +626 -0
  33. package/dist-es5/Providers/IndexDbHelper.js.map +1 -0
  34. package/dist-es5/Providers/IndexDbProvider.js +468 -0
  35. package/dist-es5/Providers/IndexDbProvider.js.map +1 -0
  36. package/dist-es5/Providers/WebStorageProvider.js +463 -0
  37. package/dist-es5/Providers/WebStorageProvider.js.map +1 -0
  38. package/dist-es5/Sender.js +572 -0
  39. package/dist-es5/Sender.js.map +1 -0
  40. package/dist-es5/__DynamicConstants.js +80 -0
  41. package/dist-es5/__DynamicConstants.js.map +1 -0
  42. package/dist-es5/applicationinsights-offlinechannel-js.js +11 -0
  43. package/dist-es5/applicationinsights-offlinechannel-js.js.map +1 -0
  44. package/package.json +65 -0
  45. package/tsconfig.json +28 -0
  46. package/types/applicationinsights-offlinechannel-js.d.ts +605 -0
  47. package/types/applicationinsights-offlinechannel-js.namespaced.d.ts +601 -0
@@ -0,0 +1,572 @@
1
+ /*
2
+ * Application Insights JavaScript SDK - Offline Channel, 0.1.0-nightly3.2402-06
3
+ * Copyright (c) Microsoft and contributors. All rights reserved.
4
+ */
5
+
6
+
7
+ import dynamicProto from "@microsoft/dynamicproto-js";
8
+ import { BreezeChannelIdentifier, DisabledPropertyName, utlSetStoragePrefix } from "@microsoft/applicationinsights-common";
9
+ import { _throwInternal, arrForEach, createProcessTelemetryContext, dumpObj, getExceptionName, getJSON, getLocation, getNavigator, getWindow, isArray, isBeaconsSupported, isFetchSupported, isXhrSupported, objKeys, onConfigChange, useXDomainRequest } from "@microsoft/applicationinsights-core-js";
10
+ import { createPromise, doAwaitResponse } from "@nevware21/ts-async";
11
+ import { isFunction, isNumber } from "@nevware21/ts-utils";
12
+ import { _DYN_DATA, _DYN_INITIALIZE, _DYN_IS_COMPLETELY_IDLE, _DYN_LENGTH, _DYN_ONERROR, _DYN_REASON, _DYN_REJECTED, _DYN_REPLACE, _DYN_SEND_POST, _DYN_SET_REQUEST_HEADER, _DYN_STATUS, _DYN_URL_STRING, _DYN_VALUE } from "./__DynamicConstants";
13
+ var DefaultOfflineIdentifier = "OfflineChannel";
14
+ //const FetchSyncRequestSizeLimitBytes = 65000; // approx 64kb (the current Edge, Firefox and Chrome max limit)
15
+ var PostChannelId = "PostChannel";
16
+ function _getResponseText(xhr) {
17
+ try {
18
+ return xhr.responseText;
19
+ }
20
+ catch (e) {
21
+ // Best effort, as XHR may throw while XDR wont so just ignore
22
+ }
23
+ return null;
24
+ }
25
+ function isOverrideFn(httpXHROverride) {
26
+ return httpXHROverride && httpXHROverride[_DYN_SEND_POST /* @min:%2esendPOST */];
27
+ }
28
+ function _prependTransports(theTransports, newTransports) {
29
+ if (newTransports) {
30
+ if (isNumber(newTransports)) {
31
+ theTransports = [newTransports].concat(theTransports);
32
+ }
33
+ else if (isArray(newTransports)) {
34
+ theTransports = newTransports.concat(theTransports);
35
+ }
36
+ }
37
+ return theTransports;
38
+ }
39
+ var Sender = /** @class */ (function () {
40
+ function Sender() {
41
+ var _consecutiveErrors; // How many times in a row a retryable error condition has occurred.
42
+ var _retryAt; // The time to retry at in milliseconds from 1970/01/01 (this makes the timer calculation easy).
43
+ //let _lastSend: number; // The time of the last send operation.
44
+ var _paused; // Flag indicating that the sending should be paused
45
+ var _stamp_specific_redirects;
46
+ var _syncFetchPayload = 0; // Keep track of the outstanding sync fetch payload total (as sync fetch has limits)
47
+ var _enableSendPromise;
48
+ var _alwaysUseCustomSend;
49
+ var _disableXhr;
50
+ var _fallbackSend;
51
+ var _isInitialized;
52
+ var _diagLog;
53
+ var _core;
54
+ var _httpInterface;
55
+ var _onlineChannelId;
56
+ var _isOneDs;
57
+ dynamicProto(Sender, this, function (_self, _base) {
58
+ var _sendCredentials = true; // for 1ds
59
+ _initDefaults();
60
+ _self.pause = function () {
61
+ _clearScheduledTimer();
62
+ _paused = true;
63
+ };
64
+ _self.resume = function () {
65
+ if (_paused) {
66
+ _paused = false;
67
+ _retryAt = null;
68
+ }
69
+ };
70
+ _self.getXhrInst = function (sync) {
71
+ // unload events will be saved. so not return unload interface
72
+ return _httpInterface;
73
+ };
74
+ _self[_DYN_INITIALIZE /* @min:%2einitialize */] = function (config, core, cxt, diagLog, channelId, unloadHookContainer) {
75
+ _diagLog = diagLog || core.logger;
76
+ if (_isInitialized) {
77
+ _throwInternal(_diagLog, 1 /* eLoggingSeverity.CRITICAL */, 28 /* _eInternalMessageId.SenderNotInitialized */, "Sender is already initialized");
78
+ }
79
+ _core = core;
80
+ _consecutiveErrors = 0;
81
+ _retryAt = null;
82
+ _stamp_specific_redirects = 0;
83
+ // This function will be re-called whenever any referenced configuration is changed
84
+ var hook = onConfigChange(config, function (details) {
85
+ var config = details.cfg;
86
+ if (config.storagePrefix) {
87
+ utlSetStoragePrefix(config.storagePrefix);
88
+ }
89
+ var ctx = createProcessTelemetryContext(null, config, core);
90
+ var offlineCfg = ctx.getExtCfg(DefaultOfflineIdentifier);
91
+ _onlineChannelId = channelId || BreezeChannelIdentifier;
92
+ var senderConfig = ctx.getExtCfg(_onlineChannelId, {});
93
+ var offlineSenderCfg = offlineCfg.senderCfg || {};
94
+ if (_onlineChannelId == PostChannelId) {
95
+ _isOneDs = true;
96
+ }
97
+ _alwaysUseCustomSend = offlineSenderCfg.alwaysUseXhrOverride;
98
+ // default true
99
+ _enableSendPromise = !(senderConfig.enableSendPromise === false);
100
+ var xhrOverride = senderConfig.httpXHROverride;
101
+ var customInterface = isOverrideFn(xhrOverride) ? xhrOverride : null;
102
+ if (!customInterface && _isOneDs) {
103
+ var location_1 = getLocation();
104
+ if (location_1 && location_1.protocol && location_1.protocol.toLowerCase() === "file:") {
105
+ // Special case where a local html file fails with a CORS error on Chromium browsers
106
+ _sendCredentials = false;
107
+ }
108
+ }
109
+ var httpInterface = null;
110
+ var customTransPorts = offlineSenderCfg.transports || senderConfig.transports || [];
111
+ // User requested transport(s) values > Beacon > Fetch > XHR
112
+ // Beacon would be filtered out if user has set disableBeaconApi to true at _getSenderInterface
113
+ var theTransports = _prependTransports([1 /* TransportType.Xhr */, 2 /* TransportType.Fetch */, 3 /* TransportType.Beacon */], customTransPorts);
114
+ httpInterface = _getSenderInterface(theTransports, false);
115
+ var xhrInterface = { sendPOST: _xhrSender };
116
+ _fallbackSend = _xhrSender;
117
+ httpInterface = _alwaysUseCustomSend ? customInterface : (httpInterface || customInterface || xhrInterface);
118
+ _httpInterface = httpInterface || xhrInterface;
119
+ });
120
+ unloadHookContainer && unloadHookContainer.add(hook);
121
+ };
122
+ _self[_DYN_IS_COMPLETELY_IDLE /* @min:%2eisCompletelyIdle */] = function () {
123
+ try {
124
+ var senderPlugin = _core.getPlugin(_onlineChannelId).plugin;
125
+ if (senderPlugin && isFunction(senderPlugin[_DYN_IS_COMPLETELY_IDLE /* @min:%2eisCompletelyIdle */])) {
126
+ if (!senderPlugin[_DYN_IS_COMPLETELY_IDLE /* @min:%2eisCompletelyIdle */]()) {
127
+ return false;
128
+ }
129
+ }
130
+ }
131
+ catch (e) {
132
+ // if can't get idle status of online sender, then isidle status only depends on offine sender idle status
133
+ }
134
+ return !_paused && _syncFetchPayload === 0;
135
+ };
136
+ _self._doTeardown = function (unloadCtx, unloadState) {
137
+ _initDefaults();
138
+ };
139
+ /**
140
+ * success handler
141
+ */
142
+ function _onSuccess(res, onComplete) {
143
+ _doOnComplete(onComplete, 200, {}, res);
144
+ }
145
+ /**
146
+ * error handler
147
+ */
148
+ function _onError(message, onComplete) {
149
+ _throwInternal(_diagLog, 2 /* eLoggingSeverity.WARNING */, 26 /* _eInternalMessageId.OnError */, "Failed to send telemetry.", { message: message });
150
+ _doOnComplete(onComplete, 400, {});
151
+ }
152
+ function _onNoPayloadUrl(onComplete) {
153
+ _onError("No endpoint url is provided for the batch", onComplete);
154
+ }
155
+ /**
156
+ * partial success handler
157
+ */
158
+ //TODO: partial success handler
159
+ // function _onPartialSuccess (payload: string[], results: IBackendResponse, onComplete?: OnCompleteCallback) {
160
+ // }
161
+ function _getSenderInterface(transports, syncSupport) {
162
+ var _a;
163
+ var transportType = null;
164
+ var sendPostFunc = null;
165
+ var lp = 0;
166
+ while (sendPostFunc == null && lp < transports[_DYN_LENGTH /* @min:%2elength */]) {
167
+ transportType = transports[lp];
168
+ if (!_disableXhr && transportType === 1 /* TransportType.Xhr */) {
169
+ if (useXDomainRequest()) {
170
+ // IE 8 and 9
171
+ sendPostFunc = _xdrSender;
172
+ }
173
+ else if (isXhrSupported()) {
174
+ sendPostFunc = _xhrSender;
175
+ }
176
+ }
177
+ else if (transportType === 2 /* TransportType.Fetch */ && isFetchSupported(syncSupport)) {
178
+ sendPostFunc = _fetchSender;
179
+ }
180
+ else if (transportType === 3 /* TransportType.Beacon */ && isBeaconsSupported()) {
181
+ sendPostFunc = _beaconSender;
182
+ }
183
+ lp++;
184
+ }
185
+ if (sendPostFunc) {
186
+ return _a = {},
187
+ _a[_DYN_SEND_POST /* @min:sendPOST */] = sendPostFunc,
188
+ _a;
189
+ }
190
+ return null;
191
+ }
192
+ /**
193
+ * Send fetch API request
194
+ * @param payload - {string} - The data payload to be sent.
195
+ * @param oncomplete - {function} on complete function
196
+ * @param sync - {boolean} - not used
197
+ */
198
+ function _fetchSender(payload, oncomplete, sync) {
199
+ return _doFetchSender(payload, oncomplete, false);
200
+ }
201
+ function _doOnComplete(oncomplete, status, headers, response) {
202
+ try {
203
+ oncomplete && oncomplete(status, headers, response);
204
+ }
205
+ catch (e) {
206
+ // eslint-disable-next-line no-empty
207
+ }
208
+ }
209
+ function _doBeaconSend(payload, oncomplete) {
210
+ var nav = getNavigator();
211
+ var url = payload[_DYN_URL_STRING /* @min:%2eurlString */];
212
+ if (!url) {
213
+ _onNoPayloadUrl(oncomplete);
214
+ // return true here, because we don't want to retry it with fallback sender
215
+ return true;
216
+ }
217
+ var data = payload[_DYN_DATA /* @min:%2edata */];
218
+ // Chrome only allows CORS-safelisted values for the sendBeacon data argument
219
+ // see: https://bugs.chromium.org/p/chromium/issues/detail?id=720283
220
+ //const batch = buffer.batchPayloads(payload);
221
+ // Chrome only allows CORS-safelisted values for the sendBeacon data argument
222
+ // see: https://bugs.chromium.org/p/chromium/issues/detail?id=720283
223
+ var plainTextBatch = new Blob([data], { type: "text/plain;charset=UTF-8" });
224
+ // The sendBeacon method returns true if the user agent is able to successfully queue the data for transfer. Otherwise it returns false.
225
+ var queued = nav.sendBeacon(url, plainTextBatch);
226
+ if (queued) {
227
+ _onSuccess(null, oncomplete);
228
+ }
229
+ return queued;
230
+ }
231
+ /**
232
+ * Send Beacon API request
233
+ * @param payload - {string} - The data payload to be sent.
234
+ * @param sync - {boolean} - not used
235
+ * Note: Beacon API does not support custom headers and we are not able to get
236
+ * appId from the backend for the correct correlation.
237
+ */
238
+ function _beaconSender(payload, oncomplete, sync) {
239
+ var data = payload[_DYN_DATA /* @min:%2edata */];
240
+ if (data) {
241
+ // The sendBeacon method returns true if the user agent is able to successfully queue the data for transfer. Otherwise it returns false.
242
+ if (!_doBeaconSend(payload, oncomplete)) {
243
+ _fallbackSend && _fallbackSend(payload, oncomplete, true);
244
+ _throwInternal(_diagLog, 2 /* eLoggingSeverity.WARNING */, 40 /* _eInternalMessageId.TransmissionFailed */, ". " + "Failed to send telemetry with Beacon API, retried with normal sender.");
245
+ }
246
+ }
247
+ return;
248
+ }
249
+ /**
250
+ * Send XMLHttpRequest
251
+ * @param payload - {string} - The data payload to be sent.
252
+ * @param sync - {boolean} - Indicates if the request should be sent synchronously
253
+ */
254
+ function _xhrSender(payload, oncomplete, sync) {
255
+ //let internalPayload = payload as IInternalPayloadData;
256
+ var thePromise;
257
+ var resolveFunc;
258
+ var rejectFunc;
259
+ var headers = payload.headers || {};
260
+ if (!sync && _enableSendPromise) {
261
+ thePromise = createPromise(function (resolve, reject) {
262
+ resolveFunc = resolve;
263
+ rejectFunc = reject;
264
+ });
265
+ }
266
+ var xhr = new XMLHttpRequest();
267
+ var endPointUrl = payload[_DYN_URL_STRING /* @min:%2eurlString */];
268
+ if (!endPointUrl) {
269
+ _onNoPayloadUrl(oncomplete);
270
+ resolveFunc && resolveFunc(false);
271
+ return;
272
+ }
273
+ try {
274
+ xhr[DisabledPropertyName] = true;
275
+ }
276
+ catch (e) {
277
+ // If the environment has locked down the XMLHttpRequest (preventExtensions and/or freeze), this would
278
+ // cause the request to fail and we no telemetry would be sent
279
+ }
280
+ xhr.open("POST", endPointUrl, !sync);
281
+ xhr[_DYN_SET_REQUEST_HEADER /* @min:%2esetRequestHeader */]("Content-type", "application/json");
282
+ arrForEach(objKeys(headers), function (headerName) {
283
+ xhr[_DYN_SET_REQUEST_HEADER /* @min:%2esetRequestHeader */](headerName, headers[headerName]);
284
+ });
285
+ xhr.onreadystatechange = function () {
286
+ var response = _getResponseText(xhr);
287
+ if (xhr.readyState !== 4) {
288
+ //TODO: this should not need, add in case
289
+ _handleResponse(oncomplete, xhr[_DYN_STATUS /* @min:%2estatus */], {}, response);
290
+ resolveFunc && resolveFunc(false);
291
+ }
292
+ _handleResponse(oncomplete, xhr[_DYN_STATUS /* @min:%2estatus */], {}, response);
293
+ resolveFunc && resolveFunc(true);
294
+ };
295
+ xhr[_DYN_ONERROR /* @min:%2eonerror */] = function (event) {
296
+ _doOnComplete(oncomplete, 400, {}, _formatErrorMessageXhr(xhr));
297
+ rejectFunc && rejectFunc(event);
298
+ };
299
+ xhr.ontimeout = function () {
300
+ _doOnComplete(oncomplete, 500, {}, _formatErrorMessageXhr(xhr));
301
+ resolveFunc && resolveFunc(false);
302
+ };
303
+ xhr.send(payload[_DYN_DATA /* @min:%2edata */]);
304
+ return thePromise;
305
+ }
306
+ /**
307
+ * Send fetch API request
308
+ * @param payload - {string} - The data payload to be sent.
309
+ * @param sync - {boolean} - For fetch this identifies whether we are "unloading" (false) or a normal request
310
+ */
311
+ function _doFetchSender(payload, oncomplete, sync) {
312
+ var _a;
313
+ var endPointUrl = payload[_DYN_URL_STRING /* @min:%2eurlString */];
314
+ var batch = payload[_DYN_DATA /* @min:%2edata */];
315
+ var plainTextBatch = new Blob([batch], { type: "application/json" });
316
+ var thePromise;
317
+ var resolveFunc;
318
+ var rejectFunc;
319
+ var requestHeaders = new Headers();
320
+ var batchLength = batch[_DYN_LENGTH /* @min:%2elength */];
321
+ var ignoreResponse = false;
322
+ var responseHandled = false;
323
+ var headers = payload.headers || [];
324
+ //TODO: handle time out for 1ds
325
+ arrForEach(objKeys(headers), function (headerName) {
326
+ requestHeaders.append(headerName, headers[headerName]);
327
+ });
328
+ var init = (_a = {
329
+ method: "POST",
330
+ headers: requestHeaders,
331
+ body: plainTextBatch
332
+ },
333
+ _a[DisabledPropertyName] = true // Mark so we don't attempt to track this request
334
+ ,
335
+ _a);
336
+ if (_sendCredentials && _isOneDs) {
337
+ // for 1ds, Don't send credentials when URL is file://
338
+ init.credentials = "include";
339
+ }
340
+ if (sync) {
341
+ // since offline will not trigger sync call
342
+ // this will not be called, add it here in case
343
+ init.keepalive = true;
344
+ ignoreResponse = true;
345
+ _syncFetchPayload += batchLength;
346
+ }
347
+ var request = new Request(endPointUrl, init);
348
+ try {
349
+ // Also try and tag the request (just in case the value in init is not copied over)
350
+ request[DisabledPropertyName] = true;
351
+ }
352
+ catch (e) {
353
+ // If the environment has locked down the XMLHttpRequest (preventExtensions and/or freeze), this would
354
+ // cause the request to fail and we no telemetry would be sent
355
+ }
356
+ if (!sync && _enableSendPromise) {
357
+ thePromise = createPromise(function (resolve, reject) {
358
+ resolveFunc = resolve;
359
+ rejectFunc = reject;
360
+ });
361
+ }
362
+ if (!endPointUrl) {
363
+ _onNoPayloadUrl(oncomplete);
364
+ resolveFunc && resolveFunc(false);
365
+ return;
366
+ }
367
+ try {
368
+ doAwaitResponse(fetch(request), function (result) {
369
+ if (sync) {
370
+ _syncFetchPayload -= batchLength;
371
+ batchLength = 0;
372
+ }
373
+ if (!responseHandled) {
374
+ responseHandled = true;
375
+ if (!result[_DYN_REJECTED /* @min:%2erejected */]) {
376
+ var response_1 = result[_DYN_VALUE /* @min:%2evalue */];
377
+ /**
378
+ * The Promise returned from fetch() won’t reject on HTTP error status even if the response is an HTTP 404 or 500.
379
+ * Instead, it will resolve normally (with ok status set to false), and it will only reject on network failure
380
+ * or if anything prevented the request from completing.
381
+ */
382
+ if (!response_1.ok) {
383
+ _doOnComplete(oncomplete, 400, {}, response_1.statusText);
384
+ resolveFunc && resolveFunc(false);
385
+ }
386
+ else {
387
+ doAwaitResponse(response_1.text(), function (resp) {
388
+ var status = response_1[_DYN_STATUS /* @min:%2estatus */];
389
+ _handleResponse(oncomplete, status, {}, response_1.statusText);
390
+ resolveFunc && resolveFunc(true);
391
+ });
392
+ }
393
+ }
394
+ else {
395
+ _doOnComplete(oncomplete, 400, {}, result[_DYN_REASON /* @min:%2ereason */] && result[_DYN_REASON /* @min:%2ereason */].message);
396
+ rejectFunc && rejectFunc(result[_DYN_REASON /* @min:%2ereason */]);
397
+ }
398
+ }
399
+ });
400
+ }
401
+ catch (e) {
402
+ if (!responseHandled) {
403
+ _doOnComplete(oncomplete, 400, {}, dumpObj(e));
404
+ rejectFunc && rejectFunc(e);
405
+ }
406
+ }
407
+ if (ignoreResponse && !responseHandled) {
408
+ // Assume success during unload processing as we most likely won't get the response
409
+ responseHandled = true;
410
+ _doOnComplete(oncomplete, 200, {});
411
+ resolveFunc && resolveFunc(true);
412
+ }
413
+ return thePromise;
414
+ }
415
+ function _handleResponse(oncomplete, status, headers, response) {
416
+ if (status == 206 && !_isOneDs) {
417
+ // for breeze, 206 is partially success, currently consider success
418
+ // TODO: handle partial success
419
+ _doOnComplete(oncomplete, 200, headers, response); // TODO: doc (support partial success)-> partial success add known issue (breeze)
420
+ }
421
+ else if (status == 204 && _isOneDs) {
422
+ // one collector
423
+ _doOnComplete(oncomplete, 200, headers, response);
424
+ }
425
+ else {
426
+ _doOnComplete(oncomplete, status, headers, response);
427
+ }
428
+ }
429
+ /**
430
+ * Parses the response from the backend.
431
+ * @param response - XMLHttpRequest or XDomainRequest response
432
+ */
433
+ function _parseResponse(response) {
434
+ try {
435
+ if (response && response !== "") {
436
+ var result = getJSON().parse(response);
437
+ if (_isOneDs) {
438
+ return result;
439
+ }
440
+ // TODO: handle partial success
441
+ // if (result && result.itemsReceived && result.itemsReceived >= result.itemsAccepted &&
442
+ // result.itemsReceived - result.itemsAccepted === result.errors.length) {
443
+ // return result;
444
+ // }
445
+ if (result && result.itemsReceived) {
446
+ return result;
447
+ }
448
+ }
449
+ }
450
+ catch (e) {
451
+ _throwInternal(_diagLog, 1 /* eLoggingSeverity.CRITICAL */, 43 /* _eInternalMessageId.InvalidBackendResponse */, "Cannot parse the response. " + getExceptionName(e), {
452
+ response: response
453
+ });
454
+ }
455
+ return null;
456
+ }
457
+ function _clearScheduledTimer() {
458
+ _retryAt = null;
459
+ }
460
+ function _formatErrorMessageXhr(xhr, message) {
461
+ if (xhr) {
462
+ return "XMLHttpRequest,Status:" + xhr[_DYN_STATUS /* @min:%2estatus */] + ",Response:" + _getResponseText(xhr) || xhr.response || "";
463
+ }
464
+ return message;
465
+ }
466
+ /**
467
+ * Send XDomainRequest
468
+ * @param payload - {string} - The data payload to be sent.
469
+ * @param sync - {boolean} - Indicates if the request should be sent synchronously
470
+ *
471
+ * Note: XDomainRequest does not support sync requests. This 'isAsync' parameter is added
472
+ * to maintain consistency with the xhrSender's contract
473
+ * Note: XDomainRequest does not support custom headers and we are not able to get
474
+ * appId from the backend for the correct correlation.
475
+ */
476
+ function _xdrSender(payload, oncomplete, sync) {
477
+ // It doesn't support custom headers, so no action is taken with current requestHeaders
478
+ var _window = getWindow();
479
+ var xdr = new XDomainRequest();
480
+ var data = payload[_DYN_DATA /* @min:%2edata */];
481
+ xdr.onload = function () {
482
+ var response = _getResponseText(xdr);
483
+ if (_isOneDs) {
484
+ // for 1ds. we will assume onload means the request succeeded.
485
+ _doOnComplete(oncomplete, 200, {}, response);
486
+ }
487
+ else {
488
+ _xdrOnLoad(xdr, oncomplete);
489
+ }
490
+ };
491
+ xdr[_DYN_ONERROR /* @min:%2eonerror */] = function () {
492
+ _doOnComplete(oncomplete, 400, {}, _formatErrorMessageXdr(xdr));
493
+ };
494
+ xdr.ontimeout = function () {
495
+ _doOnComplete(oncomplete, 500, {});
496
+ };
497
+ xdr.onprogress = function () { };
498
+ // XDomainRequest requires the same protocol as the hosting page.
499
+ // If the protocol doesn't match, we can't send the telemetry :(.
500
+ var hostingProtocol = _window && _window.location && _window.location.protocol || "";
501
+ var endpoint = payload[_DYN_URL_STRING /* @min:%2eurlString */];
502
+ if (!endpoint) {
503
+ _onNoPayloadUrl(oncomplete);
504
+ return;
505
+ }
506
+ if (endpoint.lastIndexOf(hostingProtocol, 0) !== 0) {
507
+ _throwInternal(_diagLog, 2 /* eLoggingSeverity.WARNING */, 40 /* _eInternalMessageId.TransmissionFailed */, ". " +
508
+ "Cannot send XDomain request. The endpoint URL protocol doesn't match the hosting page protocol.");
509
+ return;
510
+ }
511
+ var endpointUrl = endpoint[_DYN_REPLACE /* @min:%2ereplace */](/^(https?:)/, "");
512
+ xdr.open("POST", endpointUrl);
513
+ xdr.send(data);
514
+ }
515
+ /**
516
+ * xdr state changes
517
+ */
518
+ function _xdrOnLoad(xdr, oncomplete) {
519
+ var responseText = _getResponseText(xdr);
520
+ if (xdr && (responseText + "" === "200" || responseText === "")) {
521
+ _consecutiveErrors = 0;
522
+ _onSuccess(responseText, oncomplete);
523
+ }
524
+ else {
525
+ var results = _parseResponse(responseText);
526
+ if (results && results.itemsAccepted) {
527
+ // TODO: onPartial success for appInsights
528
+ _onSuccess(responseText, oncomplete);
529
+ }
530
+ else {
531
+ _onError(_formatErrorMessageXdr(xdr), oncomplete);
532
+ }
533
+ }
534
+ }
535
+ function _formatErrorMessageXdr(xdr, message) {
536
+ if (xdr) {
537
+ return "XDomainRequest,Response:" + _getResponseText(xdr) || "";
538
+ }
539
+ return message;
540
+ }
541
+ // TDOD: add notification manager
542
+ // TODO: handler one collector "MSFPC"
543
+ function _initDefaults() {
544
+ _self._appId = null;
545
+ _consecutiveErrors = 0;
546
+ _retryAt = null;
547
+ _paused = false;
548
+ _stamp_specific_redirects = 0;
549
+ _syncFetchPayload = 0;
550
+ _disableXhr = false;
551
+ _isInitialized = false;
552
+ _fallbackSend = null;
553
+ _core = null;
554
+ _onlineChannelId = null;
555
+ }
556
+ });
557
+ }
558
+ // Removed Stub for Sender.prototype.pause.
559
+ // Removed Stub for Sender.prototype.resume.
560
+ // Removed Stub for Sender.prototype.initialize.
561
+ // Removed Stub for Sender.prototype.triggerSend.
562
+ // Removed Stub for Sender.prototype.isCompletelyIdle.
563
+ // Removed Stub for Sender.prototype.getXhrInst.
564
+ // Removed Stub for Sender.prototype._doTeardown.
565
+ // This is a workaround for an IE bug when using dynamicProto() with classes that don't have any
566
+ // non-dynamic functions or static properties/functions when using uglify-js to minify the resulting code.
567
+ Sender.__ieDyn=1;
568
+
569
+ return Sender;
570
+ }());
571
+ export { Sender };
572
+ //# sourceMappingURL=Sender.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Sender.js.map","sources":["Sender.js"],"sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved.\r\n// Licensed under the MIT License.\r\nimport dynamicProto from \"@microsoft/dynamicproto-js\";\r\nimport { BreezeChannelIdentifier, DisabledPropertyName, utlSetStoragePrefix } from \"@microsoft/applicationinsights-common\";\r\nimport { _throwInternal, arrForEach, createProcessTelemetryContext, dumpObj, getExceptionName, getJSON, getLocation, getNavigator, getWindow, isArray, isBeaconsSupported, isFetchSupported, isXhrSupported, objKeys, onConfigChange, useXDomainRequest } from \"@microsoft/applicationinsights-core-js\";\r\nimport { createPromise, doAwaitResponse } from \"@nevware21/ts-async\";\r\nimport { isFunction, isNumber } from \"@nevware21/ts-utils\";\r\nimport { _DYN_DATA, _DYN_INITIALIZE, _DYN_IS_COMPLETELY_IDLE, _DYN_LENGTH, _DYN_ONERROR, _DYN_REASON, _DYN_REJECTED, _DYN_REPLACE, _DYN_SEND_POST, _DYN_SET_REQUEST_HEADER, _DYN_STATUS, _DYN_URL_STRING, _DYN_VALUE } from \"./__DynamicConstants\";\r\nvar DefaultOfflineIdentifier = \"OfflineChannel\";\r\n//const FetchSyncRequestSizeLimitBytes = 65000; // approx 64kb (the current Edge, Firefox and Chrome max limit)\r\nvar PostChannelId = \"PostChannel\";\r\nfunction _getResponseText(xhr) {\r\n try {\r\n return xhr.responseText;\r\n }\r\n catch (e) {\r\n // Best effort, as XHR may throw while XDR wont so just ignore\r\n }\r\n return null;\r\n}\r\nfunction isOverrideFn(httpXHROverride) {\r\n return httpXHROverride && httpXHROverride[_DYN_SEND_POST /* @min:%2esendPOST */];\r\n}\r\nfunction _prependTransports(theTransports, newTransports) {\r\n if (newTransports) {\r\n if (isNumber(newTransports)) {\r\n theTransports = [newTransports].concat(theTransports);\r\n }\r\n else if (isArray(newTransports)) {\r\n theTransports = newTransports.concat(theTransports);\r\n }\r\n }\r\n return theTransports;\r\n}\r\nvar Sender = /** @class */ (function () {\r\n function Sender() {\r\n var _consecutiveErrors; // How many times in a row a retryable error condition has occurred.\r\n var _retryAt; // The time to retry at in milliseconds from 1970/01/01 (this makes the timer calculation easy).\r\n //let _lastSend: number; // The time of the last send operation.\r\n var _paused; // Flag indicating that the sending should be paused\r\n var _stamp_specific_redirects;\r\n var _syncFetchPayload = 0; // Keep track of the outstanding sync fetch payload total (as sync fetch has limits)\r\n var _enableSendPromise;\r\n var _alwaysUseCustomSend;\r\n var _disableXhr;\r\n var _fallbackSend;\r\n var _isInitialized;\r\n var _diagLog;\r\n var _core;\r\n var _httpInterface;\r\n var _onlineChannelId;\r\n var _isOneDs;\r\n dynamicProto(Sender, this, function (_self, _base) {\r\n var _sendCredentials = true; // for 1ds\r\n _initDefaults();\r\n _self.pause = function () {\r\n _clearScheduledTimer();\r\n _paused = true;\r\n };\r\n _self.resume = function () {\r\n if (_paused) {\r\n _paused = false;\r\n _retryAt = null;\r\n }\r\n };\r\n _self.getXhrInst = function (sync) {\r\n // unload events will be saved. so not return unload interface\r\n return _httpInterface;\r\n };\r\n _self[_DYN_INITIALIZE /* @min:%2einitialize */] = function (config, core, cxt, diagLog, channelId, unloadHookContainer) {\r\n _diagLog = diagLog || core.logger;\r\n if (_isInitialized) {\r\n _throwInternal(_diagLog, 1 /* eLoggingSeverity.CRITICAL */, 28 /* _eInternalMessageId.SenderNotInitialized */, \"Sender is already initialized\");\r\n }\r\n _core = core;\r\n _consecutiveErrors = 0;\r\n _retryAt = null;\r\n _stamp_specific_redirects = 0;\r\n // This function will be re-called whenever any referenced configuration is changed\r\n var hook = onConfigChange(config, function (details) {\r\n var config = details.cfg;\r\n if (config.storagePrefix) {\r\n utlSetStoragePrefix(config.storagePrefix);\r\n }\r\n var ctx = createProcessTelemetryContext(null, config, core);\r\n var offlineCfg = ctx.getExtCfg(DefaultOfflineIdentifier);\r\n _onlineChannelId = channelId || BreezeChannelIdentifier;\r\n var senderConfig = ctx.getExtCfg(_onlineChannelId, {});\r\n var offlineSenderCfg = offlineCfg.senderCfg || {};\r\n if (_onlineChannelId == PostChannelId) {\r\n _isOneDs = true;\r\n }\r\n _alwaysUseCustomSend = offlineSenderCfg.alwaysUseXhrOverride;\r\n // default true\r\n _enableSendPromise = !(senderConfig.enableSendPromise === false);\r\n var xhrOverride = senderConfig.httpXHROverride;\r\n var customInterface = isOverrideFn(xhrOverride) ? xhrOverride : null;\r\n if (!customInterface && _isOneDs) {\r\n var location_1 = getLocation();\r\n if (location_1 && location_1.protocol && location_1.protocol.toLowerCase() === \"file:\") {\r\n // Special case where a local html file fails with a CORS error on Chromium browsers\r\n _sendCredentials = false;\r\n }\r\n }\r\n var httpInterface = null;\r\n var customTransPorts = offlineSenderCfg.transports || senderConfig.transports || [];\r\n // User requested transport(s) values > Beacon > Fetch > XHR\r\n // Beacon would be filtered out if user has set disableBeaconApi to true at _getSenderInterface\r\n var theTransports = _prependTransports([1 /* TransportType.Xhr */, 2 /* TransportType.Fetch */, 3 /* TransportType.Beacon */], customTransPorts);\r\n httpInterface = _getSenderInterface(theTransports, false);\r\n var xhrInterface = { sendPOST: _xhrSender };\r\n _fallbackSend = _xhrSender;\r\n httpInterface = _alwaysUseCustomSend ? customInterface : (httpInterface || customInterface || xhrInterface);\r\n _httpInterface = httpInterface || xhrInterface;\r\n });\r\n unloadHookContainer && unloadHookContainer.add(hook);\r\n };\r\n _self[_DYN_IS_COMPLETELY_IDLE /* @min:%2eisCompletelyIdle */] = function () {\r\n try {\r\n var senderPlugin = _core.getPlugin(_onlineChannelId).plugin;\r\n if (senderPlugin && isFunction(senderPlugin[_DYN_IS_COMPLETELY_IDLE /* @min:%2eisCompletelyIdle */])) {\r\n if (!senderPlugin[_DYN_IS_COMPLETELY_IDLE /* @min:%2eisCompletelyIdle */]()) {\r\n return false;\r\n }\r\n }\r\n }\r\n catch (e) {\r\n // if can't get idle status of online sender, then isidle status only depends on offine sender idle status\r\n }\r\n return !_paused && _syncFetchPayload === 0;\r\n };\r\n _self._doTeardown = function (unloadCtx, unloadState) {\r\n _initDefaults();\r\n };\r\n /**\r\n * success handler\r\n */\r\n function _onSuccess(res, onComplete) {\r\n _doOnComplete(onComplete, 200, {}, res);\r\n }\r\n /**\r\n * error handler\r\n */\r\n function _onError(message, onComplete) {\r\n _throwInternal(_diagLog, 2 /* eLoggingSeverity.WARNING */, 26 /* _eInternalMessageId.OnError */, \"Failed to send telemetry.\", { message: message });\r\n _doOnComplete(onComplete, 400, {});\r\n }\r\n function _onNoPayloadUrl(onComplete) {\r\n _onError(\"No endpoint url is provided for the batch\", onComplete);\r\n }\r\n /**\r\n * partial success handler\r\n */\r\n //TODO: partial success handler\r\n // function _onPartialSuccess (payload: string[], results: IBackendResponse, onComplete?: OnCompleteCallback) {\r\n // }\r\n function _getSenderInterface(transports, syncSupport) {\r\n var _a;\r\n var transportType = null;\r\n var sendPostFunc = null;\r\n var lp = 0;\r\n while (sendPostFunc == null && lp < transports[_DYN_LENGTH /* @min:%2elength */]) {\r\n transportType = transports[lp];\r\n if (!_disableXhr && transportType === 1 /* TransportType.Xhr */) {\r\n if (useXDomainRequest()) {\r\n // IE 8 and 9\r\n sendPostFunc = _xdrSender;\r\n }\r\n else if (isXhrSupported()) {\r\n sendPostFunc = _xhrSender;\r\n }\r\n }\r\n else if (transportType === 2 /* TransportType.Fetch */ && isFetchSupported(syncSupport)) {\r\n sendPostFunc = _fetchSender;\r\n }\r\n else if (transportType === 3 /* TransportType.Beacon */ && isBeaconsSupported()) {\r\n sendPostFunc = _beaconSender;\r\n }\r\n lp++;\r\n }\r\n if (sendPostFunc) {\r\n return _a = {},\r\n _a[_DYN_SEND_POST /* @min:sendPOST */] = sendPostFunc,\r\n _a;\r\n }\r\n return null;\r\n }\r\n /**\r\n * Send fetch API request\r\n * @param payload - {string} - The data payload to be sent.\r\n * @param oncomplete - {function} on complete function\r\n * @param sync - {boolean} - not used\r\n */\r\n function _fetchSender(payload, oncomplete, sync) {\r\n return _doFetchSender(payload, oncomplete, false);\r\n }\r\n function _doOnComplete(oncomplete, status, headers, response) {\r\n try {\r\n oncomplete && oncomplete(status, headers, response);\r\n }\r\n catch (e) {\r\n // eslint-disable-next-line no-empty\r\n }\r\n }\r\n function _doBeaconSend(payload, oncomplete) {\r\n var nav = getNavigator();\r\n var url = payload[_DYN_URL_STRING /* @min:%2eurlString */];\r\n if (!url) {\r\n _onNoPayloadUrl(oncomplete);\r\n // return true here, because we don't want to retry it with fallback sender\r\n return true;\r\n }\r\n var data = payload[_DYN_DATA /* @min:%2edata */];\r\n // Chrome only allows CORS-safelisted values for the sendBeacon data argument\r\n // see: https://bugs.chromium.org/p/chromium/issues/detail?id=720283\r\n //const batch = buffer.batchPayloads(payload);\r\n // Chrome only allows CORS-safelisted values for the sendBeacon data argument\r\n // see: https://bugs.chromium.org/p/chromium/issues/detail?id=720283\r\n var plainTextBatch = new Blob([data], { type: \"text/plain;charset=UTF-8\" });\r\n // The sendBeacon method returns true if the user agent is able to successfully queue the data for transfer. Otherwise it returns false.\r\n var queued = nav.sendBeacon(url, plainTextBatch);\r\n if (queued) {\r\n _onSuccess(null, oncomplete);\r\n }\r\n return queued;\r\n }\r\n /**\r\n * Send Beacon API request\r\n * @param payload - {string} - The data payload to be sent.\r\n * @param sync - {boolean} - not used\r\n * Note: Beacon API does not support custom headers and we are not able to get\r\n * appId from the backend for the correct correlation.\r\n */\r\n function _beaconSender(payload, oncomplete, sync) {\r\n var data = payload[_DYN_DATA /* @min:%2edata */];\r\n if (data) {\r\n // The sendBeacon method returns true if the user agent is able to successfully queue the data for transfer. Otherwise it returns false.\r\n if (!_doBeaconSend(payload, oncomplete)) {\r\n _fallbackSend && _fallbackSend(payload, oncomplete, true);\r\n _throwInternal(_diagLog, 2 /* eLoggingSeverity.WARNING */, 40 /* _eInternalMessageId.TransmissionFailed */, \". \" + \"Failed to send telemetry with Beacon API, retried with normal sender.\");\r\n }\r\n }\r\n return;\r\n }\r\n /**\r\n * Send XMLHttpRequest\r\n * @param payload - {string} - The data payload to be sent.\r\n * @param sync - {boolean} - Indicates if the request should be sent synchronously\r\n */\r\n function _xhrSender(payload, oncomplete, sync) {\r\n //let internalPayload = payload as IInternalPayloadData;\r\n var thePromise;\r\n var resolveFunc;\r\n var rejectFunc;\r\n var headers = payload.headers || {};\r\n if (!sync && _enableSendPromise) {\r\n thePromise = createPromise(function (resolve, reject) {\r\n resolveFunc = resolve;\r\n rejectFunc = reject;\r\n });\r\n }\r\n var xhr = new XMLHttpRequest();\r\n var endPointUrl = payload[_DYN_URL_STRING /* @min:%2eurlString */];\r\n if (!endPointUrl) {\r\n _onNoPayloadUrl(oncomplete);\r\n resolveFunc && resolveFunc(false);\r\n return;\r\n }\r\n try {\r\n xhr[DisabledPropertyName] = true;\r\n }\r\n catch (e) {\r\n // If the environment has locked down the XMLHttpRequest (preventExtensions and/or freeze), this would\r\n // cause the request to fail and we no telemetry would be sent\r\n }\r\n xhr.open(\"POST\", endPointUrl, !sync);\r\n xhr[_DYN_SET_REQUEST_HEADER /* @min:%2esetRequestHeader */](\"Content-type\", \"application/json\");\r\n arrForEach(objKeys(headers), function (headerName) {\r\n xhr[_DYN_SET_REQUEST_HEADER /* @min:%2esetRequestHeader */](headerName, headers[headerName]);\r\n });\r\n xhr.onreadystatechange = function () {\r\n var response = _getResponseText(xhr);\r\n if (xhr.readyState !== 4) {\r\n //TODO: this should not need, add in case\r\n _handleResponse(oncomplete, xhr[_DYN_STATUS /* @min:%2estatus */], {}, response);\r\n resolveFunc && resolveFunc(false);\r\n }\r\n _handleResponse(oncomplete, xhr[_DYN_STATUS /* @min:%2estatus */], {}, response);\r\n resolveFunc && resolveFunc(true);\r\n };\r\n xhr[_DYN_ONERROR /* @min:%2eonerror */] = function (event) {\r\n _doOnComplete(oncomplete, 400, {}, _formatErrorMessageXhr(xhr));\r\n rejectFunc && rejectFunc(event);\r\n };\r\n xhr.ontimeout = function () {\r\n _doOnComplete(oncomplete, 500, {}, _formatErrorMessageXhr(xhr));\r\n resolveFunc && resolveFunc(false);\r\n };\r\n xhr.send(payload[_DYN_DATA /* @min:%2edata */]);\r\n return thePromise;\r\n }\r\n /**\r\n * Send fetch API request\r\n * @param payload - {string} - The data payload to be sent.\r\n * @param sync - {boolean} - For fetch this identifies whether we are \"unloading\" (false) or a normal request\r\n */\r\n function _doFetchSender(payload, oncomplete, sync) {\r\n var _a;\r\n var endPointUrl = payload[_DYN_URL_STRING /* @min:%2eurlString */];\r\n var batch = payload[_DYN_DATA /* @min:%2edata */];\r\n var plainTextBatch = new Blob([batch], { type: \"application/json\" });\r\n var thePromise;\r\n var resolveFunc;\r\n var rejectFunc;\r\n var requestHeaders = new Headers();\r\n var batchLength = batch[_DYN_LENGTH /* @min:%2elength */];\r\n var ignoreResponse = false;\r\n var responseHandled = false;\r\n var headers = payload.headers || [];\r\n //TODO: handle time out for 1ds\r\n arrForEach(objKeys(headers), function (headerName) {\r\n requestHeaders.append(headerName, headers[headerName]);\r\n });\r\n var init = (_a = {\r\n method: \"POST\",\r\n headers: requestHeaders,\r\n body: plainTextBatch\r\n },\r\n _a[DisabledPropertyName] = true // Mark so we don't attempt to track this request\r\n ,\r\n _a);\r\n if (_sendCredentials && _isOneDs) {\r\n // for 1ds, Don't send credentials when URL is file://\r\n init.credentials = \"include\";\r\n }\r\n if (sync) {\r\n // since offline will not trigger sync call\r\n // this will not be called, add it here in case\r\n init.keepalive = true;\r\n ignoreResponse = true;\r\n _syncFetchPayload += batchLength;\r\n }\r\n var request = new Request(endPointUrl, init);\r\n try {\r\n // Also try and tag the request (just in case the value in init is not copied over)\r\n request[DisabledPropertyName] = true;\r\n }\r\n catch (e) {\r\n // If the environment has locked down the XMLHttpRequest (preventExtensions and/or freeze), this would\r\n // cause the request to fail and we no telemetry would be sent\r\n }\r\n if (!sync && _enableSendPromise) {\r\n thePromise = createPromise(function (resolve, reject) {\r\n resolveFunc = resolve;\r\n rejectFunc = reject;\r\n });\r\n }\r\n if (!endPointUrl) {\r\n _onNoPayloadUrl(oncomplete);\r\n resolveFunc && resolveFunc(false);\r\n return;\r\n }\r\n try {\r\n doAwaitResponse(fetch(request), function (result) {\r\n if (sync) {\r\n _syncFetchPayload -= batchLength;\r\n batchLength = 0;\r\n }\r\n if (!responseHandled) {\r\n responseHandled = true;\r\n if (!result[_DYN_REJECTED /* @min:%2erejected */]) {\r\n var response_1 = result[_DYN_VALUE /* @min:%2evalue */];\r\n /**\r\n * The Promise returned from fetch() won’t reject on HTTP error status even if the response is an HTTP 404 or 500.\r\n * Instead, it will resolve normally (with ok status set to false), and it will only reject on network failure\r\n * or if anything prevented the request from completing.\r\n */\r\n if (!response_1.ok) {\r\n _doOnComplete(oncomplete, 400, {}, response_1.statusText);\r\n resolveFunc && resolveFunc(false);\r\n }\r\n else {\r\n doAwaitResponse(response_1.text(), function (resp) {\r\n var status = response_1[_DYN_STATUS /* @min:%2estatus */];\r\n _handleResponse(oncomplete, status, {}, response_1.statusText);\r\n resolveFunc && resolveFunc(true);\r\n });\r\n }\r\n }\r\n else {\r\n _doOnComplete(oncomplete, 400, {}, result[_DYN_REASON /* @min:%2ereason */] && result[_DYN_REASON /* @min:%2ereason */].message);\r\n rejectFunc && rejectFunc(result[_DYN_REASON /* @min:%2ereason */]);\r\n }\r\n }\r\n });\r\n }\r\n catch (e) {\r\n if (!responseHandled) {\r\n _doOnComplete(oncomplete, 400, {}, dumpObj(e));\r\n rejectFunc && rejectFunc(e);\r\n }\r\n }\r\n if (ignoreResponse && !responseHandled) {\r\n // Assume success during unload processing as we most likely won't get the response\r\n responseHandled = true;\r\n _doOnComplete(oncomplete, 200, {});\r\n resolveFunc && resolveFunc(true);\r\n }\r\n return thePromise;\r\n }\r\n function _handleResponse(oncomplete, status, headers, response) {\r\n if (status == 206 && !_isOneDs) {\r\n // for breeze, 206 is partially success, currently consider success\r\n // TODO: handle partial success\r\n _doOnComplete(oncomplete, 200, headers, response); // TODO: doc (support partial success)-> partial success add known issue (breeze)\r\n }\r\n else if (status == 204 && _isOneDs) {\r\n // one collector\r\n _doOnComplete(oncomplete, 200, headers, response);\r\n }\r\n else {\r\n _doOnComplete(oncomplete, status, headers, response);\r\n }\r\n }\r\n /**\r\n * Parses the response from the backend.\r\n * @param response - XMLHttpRequest or XDomainRequest response\r\n */\r\n function _parseResponse(response) {\r\n try {\r\n if (response && response !== \"\") {\r\n var result = getJSON().parse(response);\r\n if (_isOneDs) {\r\n return result;\r\n }\r\n // TODO: handle partial success\r\n // if (result && result.itemsReceived && result.itemsReceived >= result.itemsAccepted &&\r\n // result.itemsReceived - result.itemsAccepted === result.errors.length) {\r\n // return result;\r\n // }\r\n if (result && result.itemsReceived) {\r\n return result;\r\n }\r\n }\r\n }\r\n catch (e) {\r\n _throwInternal(_diagLog, 1 /* eLoggingSeverity.CRITICAL */, 43 /* _eInternalMessageId.InvalidBackendResponse */, \"Cannot parse the response. \" + getExceptionName(e), {\r\n response: response\r\n });\r\n }\r\n return null;\r\n }\r\n function _clearScheduledTimer() {\r\n _retryAt = null;\r\n }\r\n function _formatErrorMessageXhr(xhr, message) {\r\n if (xhr) {\r\n return \"XMLHttpRequest,Status:\" + xhr[_DYN_STATUS /* @min:%2estatus */] + \",Response:\" + _getResponseText(xhr) || xhr.response || \"\";\r\n }\r\n return message;\r\n }\r\n /**\r\n * Send XDomainRequest\r\n * @param payload - {string} - The data payload to be sent.\r\n * @param sync - {boolean} - Indicates if the request should be sent synchronously\r\n *\r\n * Note: XDomainRequest does not support sync requests. This 'isAsync' parameter is added\r\n * to maintain consistency with the xhrSender's contract\r\n * Note: XDomainRequest does not support custom headers and we are not able to get\r\n * appId from the backend for the correct correlation.\r\n */\r\n function _xdrSender(payload, oncomplete, sync) {\r\n // It doesn't support custom headers, so no action is taken with current requestHeaders\r\n var _window = getWindow();\r\n var xdr = new XDomainRequest();\r\n var data = payload[_DYN_DATA /* @min:%2edata */];\r\n xdr.onload = function () {\r\n var response = _getResponseText(xdr);\r\n if (_isOneDs) {\r\n // for 1ds. we will assume onload means the request succeeded.\r\n _doOnComplete(oncomplete, 200, {}, response);\r\n }\r\n else {\r\n _xdrOnLoad(xdr, oncomplete);\r\n }\r\n };\r\n xdr[_DYN_ONERROR /* @min:%2eonerror */] = function () {\r\n _doOnComplete(oncomplete, 400, {}, _formatErrorMessageXdr(xdr));\r\n };\r\n xdr.ontimeout = function () {\r\n _doOnComplete(oncomplete, 500, {});\r\n };\r\n xdr.onprogress = function () { };\r\n // XDomainRequest requires the same protocol as the hosting page.\r\n // If the protocol doesn't match, we can't send the telemetry :(.\r\n var hostingProtocol = _window && _window.location && _window.location.protocol || \"\";\r\n var endpoint = payload[_DYN_URL_STRING /* @min:%2eurlString */];\r\n if (!endpoint) {\r\n _onNoPayloadUrl(oncomplete);\r\n return;\r\n }\r\n if (endpoint.lastIndexOf(hostingProtocol, 0) !== 0) {\r\n _throwInternal(_diagLog, 2 /* eLoggingSeverity.WARNING */, 40 /* _eInternalMessageId.TransmissionFailed */, \". \" +\r\n \"Cannot send XDomain request. The endpoint URL protocol doesn't match the hosting page protocol.\");\r\n return;\r\n }\r\n var endpointUrl = endpoint[_DYN_REPLACE /* @min:%2ereplace */](/^(https?:)/, \"\");\r\n xdr.open(\"POST\", endpointUrl);\r\n xdr.send(data);\r\n }\r\n /**\r\n * xdr state changes\r\n */\r\n function _xdrOnLoad(xdr, oncomplete) {\r\n var responseText = _getResponseText(xdr);\r\n if (xdr && (responseText + \"\" === \"200\" || responseText === \"\")) {\r\n _consecutiveErrors = 0;\r\n _onSuccess(responseText, oncomplete);\r\n }\r\n else {\r\n var results = _parseResponse(responseText);\r\n if (results && results.itemsAccepted) {\r\n // TODO: onPartial success for appInsights\r\n _onSuccess(responseText, oncomplete);\r\n }\r\n else {\r\n _onError(_formatErrorMessageXdr(xdr), oncomplete);\r\n }\r\n }\r\n }\r\n function _formatErrorMessageXdr(xdr, message) {\r\n if (xdr) {\r\n return \"XDomainRequest,Response:\" + _getResponseText(xdr) || \"\";\r\n }\r\n return message;\r\n }\r\n // TDOD: add notification manager\r\n // TODO: handler one collector \"MSFPC\"\r\n function _initDefaults() {\r\n _self._appId = null;\r\n _consecutiveErrors = 0;\r\n _retryAt = null;\r\n _paused = false;\r\n _stamp_specific_redirects = 0;\r\n _syncFetchPayload = 0;\r\n _disableXhr = false;\r\n _isInitialized = false;\r\n _fallbackSend = null;\r\n _core = null;\r\n _onlineChannelId = null;\r\n }\r\n });\r\n }\r\n /**\r\n * Pause the sending (transmission) of events, this will cause all events to be batched only until the maximum limits are\r\n * hit at which point new events are dropped. Will also cause events to NOT be sent during page unload, so if Session storage\r\n * is disabled events will be lost.\r\n */\r\n Sender.prototype.pause = function () {\r\n // @DynamicProtoStub -- DO NOT add any code as this will be removed during packaging\r\n };\r\n /**\r\n * Resume the sending (transmission) of events, this will restart the timer and any batched events will be sent using the normal\r\n * send interval.\r\n */\r\n Sender.prototype.resume = function () {\r\n // @DynamicProtoStub -- DO NOT add any code as this will be removed during packaging\r\n };\r\n Sender.prototype.initialize = function (config, core, cxt, diagLog, channelId, unloadHookContainer) {\r\n // @DynamicProtoStub -- DO NOT add any code as this will be removed during packaging\r\n };\r\n /**\r\n * Trigger the immediate send of buffered data; If executing asynchronously (the default) this may (not required) return\r\n * an [IPromise](https://nevware21.github.io/ts-async/typedoc/interfaces/IPromise.html) that will resolve once the\r\n * send is complete. The actual implementation of the `IPromise` will be a native Promise (if supported) or the default\r\n * as supplied by [ts-async library](https://github.com/nevware21/ts-async)\r\n * @param async - Indicates if the events should be sent asynchronously\r\n * @param forcedSender - {SenderFunction} - Indicates the forcedSender, undefined if not passed\r\n * @returns - Nothing or optionally, if occurring asynchronously a [IPromise](https://nevware21.github.io/ts-async/typedoc/interfaces/IPromise.html)\r\n * which will be resolved (or reject) once the send is complete, the [IPromise](https://nevware21.github.io/ts-async/typedoc/interfaces/IPromise.html)\r\n * should only be returned when async is true.\r\n */\r\n Sender.prototype.triggerSend = function (async, forcedSender, sendReason) {\r\n if (async === void 0) { async = true; }\r\n // @DynamicProtoStub -- DO NOT add any code as this will be removed during packaging\r\n };\r\n /**\r\n * Check if there are no active requests being sent.\r\n * @returns True if idle, false otherwise.\r\n */\r\n Sender.prototype.isCompletelyIdle = function () {\r\n // @DynamicProtoStub - DO NOT add any code as this will be removed during packaging\r\n return false;\r\n };\r\n /**\r\n * Get current xhr instance\r\n */\r\n Sender.prototype.getXhrInst = function (sync) {\r\n // @DynamicProtoStub - DO NOT add any code as this will be removed during packaging\r\n return null;\r\n };\r\n Sender.prototype._doTeardown = function (unloadCtx, unloadState) {\r\n // @DynamicProtoStub -- DO NOT add any code as this will be removed during packaging\r\n };\r\n return Sender;\r\n}());\r\nexport { Sender };\r\n//# sourceMappingURL=Sender.js.map"],"names":[],"mappings":";;;;AAA4D;AAC1B;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;iDAkDM,CAAC;;;;;kBACW;AAClB;AACA;AACA"}