@esri/telemetry-amazon 6.0.0-beta.4 → 6.0.0-beta.6

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 (45) hide show
  1. package/dist/esm/auth.js +11 -18
  2. package/dist/esm/auth.js.map +1 -1
  3. package/dist/esm/index.js +2 -2
  4. package/dist/esm/index.js.map +1 -1
  5. package/dist/esm/index.test.js +17 -0
  6. package/dist/esm/index.test.js.map +1 -1
  7. package/dist/esm/plugins/esri.js +172 -83
  8. package/dist/esm/plugins/esri.js.map +1 -1
  9. package/dist/esm/plugins/esri.test.js +341 -68
  10. package/dist/esm/plugins/esri.test.js.map +1 -1
  11. package/dist/esm/plugins/utils/browser.js +97 -0
  12. package/dist/esm/plugins/utils/browser.js.map +1 -0
  13. package/dist/esm/plugins/utils/os.js +42 -0
  14. package/dist/esm/plugins/utils/os.js.map +1 -0
  15. package/dist/esm/plugins/{shared.js → utils/shared.js} +1 -1
  16. package/dist/esm/plugins/utils/shared.js.map +1 -0
  17. package/dist/node/auth.js +11 -18
  18. package/dist/node/auth.js.map +1 -1
  19. package/dist/node/index.js +2 -2
  20. package/dist/node/index.js.map +1 -1
  21. package/dist/node/index.test.js +17 -0
  22. package/dist/node/index.test.js.map +1 -1
  23. package/dist/node/plugins/esri.js +172 -83
  24. package/dist/node/plugins/esri.js.map +1 -1
  25. package/dist/node/plugins/esri.test.js +342 -68
  26. package/dist/node/plugins/esri.test.js.map +1 -1
  27. package/dist/node/plugins/utils/browser.js +101 -0
  28. package/dist/node/plugins/utils/browser.js.map +1 -0
  29. package/dist/node/plugins/utils/os.js +46 -0
  30. package/dist/node/plugins/utils/os.js.map +1 -0
  31. package/dist/node/plugins/{shared.js → utils/shared.js} +3 -2
  32. package/dist/node/plugins/utils/shared.js.map +1 -0
  33. package/dist/types/index.d.ts +2 -2
  34. package/dist/types/plugins/esri.d.ts +5 -10
  35. package/dist/types/plugins/utils/browser.d.ts +12 -0
  36. package/dist/types/plugins/utils/os.d.ts +5 -0
  37. package/dist/types/plugins/{shared.d.ts → utils/shared.d.ts} +1 -0
  38. package/dist/types/types.d.ts +87 -3
  39. package/dist/umd/telemetry-amazon.js +321 -103
  40. package/dist/umd/telemetry-amazon.js.map +1 -1
  41. package/dist/umd/telemetry-amazon.min.js +321 -103
  42. package/dist/umd/telemetry-amazon.min.js.map +1 -1
  43. package/package.json +1 -1
  44. package/dist/esm/plugins/shared.js.map +0 -1
  45. package/dist/node/plugins/shared.js.map +0 -1
@@ -257,16 +257,13 @@
257
257
  },
258
258
  body: JSON.stringify({ IdentityPoolId }),
259
259
  };
260
- return fetch(COGNITO_URL, fetchOptions)
261
- .then((response) => {
262
- if (!response.ok) {
263
- throw new Error(response.statusText);
260
+ return (async () => {
261
+ const getIdResponse = await fetch(COGNITO_URL, fetchOptions);
262
+ if (!getIdResponse.ok) {
263
+ throw new Error(getIdResponse.statusText);
264
264
  }
265
- return response.json();
266
- })
267
- .then((response) => {
268
- const { IdentityId } = response;
269
- const options = {
265
+ const { IdentityId } = await getIdResponse.json();
266
+ const credentialsOptions = {
270
267
  method: 'POST',
271
268
  headers: {
272
269
  'Content-type': 'application/x-amz-json-1.1',
@@ -274,18 +271,14 @@
274
271
  },
275
272
  body: JSON.stringify({ IdentityId }),
276
273
  };
277
- return fetch(COGNITO_URL, options);
278
- })
279
- .then((response) => {
280
- if (!response.ok) {
281
- throw new Error(response.statusText);
274
+ const getCredentialsResponse = await fetch(COGNITO_URL, credentialsOptions);
275
+ if (!getCredentialsResponse.ok) {
276
+ throw new Error(getCredentialsResponse.statusText);
282
277
  }
283
- return response.json();
284
- })
285
- .then(({ Credentials }) => {
278
+ const { Credentials } = await getCredentialsResponse.json();
286
279
  storage.set(COGNITO_KEY, Credentials);
287
280
  return Credentials;
288
- });
281
+ })();
289
282
  }
290
283
 
291
284
  /******************************************************************************
@@ -1667,7 +1660,144 @@
1667
1660
  return [HOST_SERVICES[service] || service, region || '']
1668
1661
  }
1669
1662
 
1670
- // Shared utilities for plugins
1663
+ function parseOS(userAgent) {
1664
+ var _a;
1665
+ const cleanAgent = userAgent.toLowerCase().replace(/ /g, '');
1666
+ const osMatchers = [
1667
+ {
1668
+ name: 'Windows',
1669
+ regex: /windowsnt/i,
1670
+ versionRegex: /windowsnt([\d\.]+)/i,
1671
+ },
1672
+ {
1673
+ name: 'MacOS',
1674
+ regex: /macos|macosx|macintosh|macintel|darwin/i,
1675
+ versionRegex: /osx([\d_\.]+)/i,
1676
+ },
1677
+ {
1678
+ name: 'Android',
1679
+ regex: /android/i,
1680
+ versionRegex: /android([\d\.]+)/i,
1681
+ },
1682
+ {
1683
+ name: 'iOS',
1684
+ regex: /iphone|ipad|ipod/i,
1685
+ versionRegex: /os([\d_\.]+)/i,
1686
+ },
1687
+ {
1688
+ name: 'Linux',
1689
+ regex: /linux/i,
1690
+ },
1691
+ ];
1692
+ const matched = osMatchers.find((entry) => entry.regex.test(cleanAgent));
1693
+ if (!matched) {
1694
+ return {};
1695
+ }
1696
+ const version = matched.versionRegex
1697
+ ? (_a = (cleanAgent.match(matched.versionRegex) || [])[1]) === null || _a === void 0 ? void 0 : _a.replace(/_/g, '.')
1698
+ : undefined;
1699
+ return {
1700
+ name: matched.name,
1701
+ version,
1702
+ };
1703
+ }
1704
+
1705
+ function getNavigatorSafe() {
1706
+ if (typeof window === 'undefined' || !window.navigator) {
1707
+ return undefined;
1708
+ }
1709
+ return window.navigator;
1710
+ }
1711
+ function getLanguageInfo(nav) {
1712
+ if (!nav) {
1713
+ return '';
1714
+ }
1715
+ const lang = nav.language ||
1716
+ nav.browserLanguage ||
1717
+ (Array.isArray(nav.languages) && nav.languages.length > 0
1718
+ ? nav.languages[0]
1719
+ : 'en_US') ||
1720
+ '';
1721
+ return String(lang).toLowerCase().replace('-', '_');
1722
+ }
1723
+ function getBrowserTimezone() {
1724
+ const tzMatch = /\(([A-Za-z\s].*)\)/.exec(new Date().toString());
1725
+ return tzMatch ? tzMatch[1] || '' : '';
1726
+ }
1727
+ function parseBrowserType(userAgent) {
1728
+ const operaMatch = /.+(Opera[\s[A-Z]*|OPR[\sA-Z]*)\/([0-9\.]+).*/i.exec(userAgent);
1729
+ if (operaMatch) {
1730
+ return {
1731
+ type: operaMatch[1],
1732
+ version: operaMatch[2],
1733
+ };
1734
+ }
1735
+ const edgeOrTridentMatch = /.+(Trident|Edge)\/([0-9\.]+).*/i.exec(userAgent);
1736
+ if (edgeOrTridentMatch) {
1737
+ return {
1738
+ type: edgeOrTridentMatch[1],
1739
+ version: edgeOrTridentMatch[2],
1740
+ };
1741
+ }
1742
+ const headlessMatch = /(headlesschrome)(?:\/([\w\.]+)| )/i.exec(userAgent);
1743
+ if (headlessMatch) {
1744
+ return {
1745
+ type: headlessMatch[1],
1746
+ version: headlessMatch[2],
1747
+ };
1748
+ }
1749
+ const browserMatch = /.+(Chrome|Firefox|FxiOS)\/([0-9\.]+).*/i.exec(userAgent);
1750
+ if (browserMatch) {
1751
+ return {
1752
+ type: browserMatch[1],
1753
+ version: browserMatch[2],
1754
+ };
1755
+ }
1756
+ const safariMatch = /.+(Safari)\/([0-9\.]+).*/i.exec(userAgent);
1757
+ if (safariMatch) {
1758
+ return {
1759
+ type: safariMatch[1],
1760
+ version: safariMatch[2],
1761
+ };
1762
+ }
1763
+ const webkitMatch = /.+(AppleWebKit)\/([0-9\.]+).*/i.exec(userAgent);
1764
+ if (webkitMatch) {
1765
+ return {
1766
+ type: webkitMatch[1],
1767
+ version: webkitMatch[2],
1768
+ };
1769
+ }
1770
+ const anyMatch = /.*([A-Z]+)\/([0-9\.]+).*/i.exec(userAgent);
1771
+ const fallback = anyMatch || ['', 'NA', '0.0.0'];
1772
+ return {
1773
+ type: fallback[1],
1774
+ version: fallback[2],
1775
+ };
1776
+ }
1777
+ function getBrowserClientInfo() {
1778
+ const nav = getNavigatorSafe();
1779
+ if (!nav) {
1780
+ return {};
1781
+ }
1782
+ const userAgent = nav.userAgent || '';
1783
+ const browser = parseBrowserType(userAgent);
1784
+ const isBrave = (nav.brave && nav.brave.isBrave) || false;
1785
+ const type = isBrave ? 'Brave' : browser.type;
1786
+ const os = parseOS(userAgent);
1787
+ const vendorToken = (nav.vendor || '').split(' ').filter(Boolean)[0];
1788
+ const make = type === 'Brave' ? type : vendorToken || nav.product || '';
1789
+ return {
1790
+ language: getLanguageInfo(nav),
1791
+ make,
1792
+ model: type,
1793
+ version: browser.version,
1794
+ name: [type, browser.version].filter(Boolean).join('/'),
1795
+ timezone: getBrowserTimezone(),
1796
+ platform: nav.platform,
1797
+ os,
1798
+ };
1799
+ }
1800
+
1671
1801
  const PINPOINT_ENDPOINT_KEY = 'TELEMETRY_PINPOINT_ENDPOINT_ID';
1672
1802
  const LOG_PREFIX = '[telemetry-amazon]';
1673
1803
  function isDebugEnabled() {
@@ -1721,11 +1851,13 @@
1721
1851
  const SESSION_START_EVENT = '_session.start';
1722
1852
  const SESSION_STOP_EVENT = '_session.stop';
1723
1853
  const DEFAULT_IDLE_TIMEOUT_MS = 30 * 60 * 1000;
1854
+ const DEFAULT_DEBOUNCE_MS = 5000;
1724
1855
  /** Converts a string to a number, guarded against invalid values */
1725
1856
  function getNumber(value, fallback = 0) {
1726
1857
  const numeric = Number(value);
1727
1858
  return Number.isFinite(numeric) ? numeric : fallback;
1728
1859
  }
1860
+ /** Splits an EsriBatchEventPayload into attributes and metrics */
1729
1861
  function splitEventData(payload) {
1730
1862
  const attributes = {};
1731
1863
  const metrics = {};
@@ -1762,58 +1894,73 @@
1762
1894
  metrics,
1763
1895
  };
1764
1896
  }
1765
- function buildBatchEventPayload({ eventName, payload, trackerName, appName, appVersion, session, }) {
1766
- var _a, _b, _c, _d;
1767
- const endpointId = getEndpointId();
1768
- const timestamp = new Date().toISOString();
1769
- const sessionContext = session ||
1897
+ /** Constructs an event payload in the shape expected by the endpoint. */
1898
+ function buildBatchEventPayload({ queuedEvents, trackerName, appName, appVersion, }) {
1899
+ var _a, _b, _c, _d, _e, _f;
1900
+ const endpointEvent = queuedEvents[queuedEvents.length - 1] ||
1770
1901
  {
1771
- id: `${Date.now()}-${Math.random().toString(16).slice(2)}`,
1772
- startTimestamp: timestamp,
1773
- startUnixMs: Date.now(),
1902
+ payload: {},
1903
+ browserInfo: {},
1774
1904
  };
1775
- const isStopEvent = eventName === SESSION_STOP_EVENT;
1776
- const { attributes, metrics } = splitEventData(payload);
1905
+ const payload = endpointEvent.payload || {};
1906
+ const browserInfo = endpointEvent.browserInfo || {};
1907
+ const endpointId = getEndpointId();
1908
+ const location = {};
1909
+ if (payload === null || payload === void 0 ? void 0 : payload.city) {
1910
+ location.City = payload.city;
1911
+ }
1912
+ if (payload === null || payload === void 0 ? void 0 : payload.country) {
1913
+ location.Country = payload.country;
1914
+ }
1915
+ if ((payload === null || payload === void 0 ? void 0 : payload.lat) !== undefined && (payload === null || payload === void 0 ? void 0 : payload.lat) !== null) {
1916
+ location.Lat = getNumber(payload.lat);
1917
+ }
1918
+ if ((payload === null || payload === void 0 ? void 0 : payload.lon) !== undefined && (payload === null || payload === void 0 ? void 0 : payload.lon) !== null) {
1919
+ location.Lon = getNumber(payload.lon);
1920
+ }
1777
1921
  return {
1778
1922
  BatchEvent: {
1779
1923
  Endpoint: {
1780
1924
  Id: endpointId,
1781
- Device: {
1782
- Make: (payload === null || payload === void 0 ? void 0 : payload.deviceMake) || '',
1783
- Model: (payload === null || payload === void 0 ? void 0 : payload.deviceModel) || '',
1784
- },
1785
- Location: {
1786
- City: (payload === null || payload === void 0 ? void 0 : payload.city) || '',
1787
- Country: (payload === null || payload === void 0 ? void 0 : payload.country) || '',
1788
- Lat: getNumber(payload === null || payload === void 0 ? void 0 : payload.lat),
1789
- Lon: getNumber(payload === null || payload === void 0 ? void 0 : payload.lon),
1790
- },
1925
+ Device: Object.assign({ Locale: (browserInfo === null || browserInfo === void 0 ? void 0 : browserInfo.language) || '', Make: (payload === null || payload === void 0 ? void 0 : payload.deviceMake) || (browserInfo === null || browserInfo === void 0 ? void 0 : browserInfo.make) || '', Model: (payload === null || payload === void 0 ? void 0 : payload.deviceModel) || (browserInfo === null || browserInfo === void 0 ? void 0 : browserInfo.model) || '', ModelVersion: (browserInfo === null || browserInfo === void 0 ? void 0 : browserInfo.version) || '', Platform: ((_a = browserInfo === null || browserInfo === void 0 ? void 0 : browserInfo.os) === null || _a === void 0 ? void 0 : _a.name) || (browserInfo === null || browserInfo === void 0 ? void 0 : browserInfo.platform) || '' }, (((_b = browserInfo === null || browserInfo === void 0 ? void 0 : browserInfo.os) === null || _b === void 0 ? void 0 : _b.version)
1926
+ ? { PlatformVersion: browserInfo.os.version }
1927
+ : {})),
1928
+ Location: location,
1791
1929
  Application: {
1792
- AppTitle: (_b = (_a = payload === null || payload === void 0 ? void 0 : payload.appTitle) !== null && _a !== void 0 ? _a : appName) !== null && _b !== void 0 ? _b : trackerName,
1793
- AppVersion: (_c = payload === null || payload === void 0 ? void 0 : payload.appVersion) !== null && _c !== void 0 ? _c : appVersion,
1794
- ClientSdkVersion: (_d = payload === null || payload === void 0 ? void 0 : payload.clientSdkVersion) !== null && _d !== void 0 ? _d : trackerName,
1930
+ AppTitle: (_d = (_c = payload === null || payload === void 0 ? void 0 : payload.appTitle) !== null && _c !== void 0 ? _c : appName) !== null && _d !== void 0 ? _d : trackerName,
1931
+ AppVersion: (_e = payload === null || payload === void 0 ? void 0 : payload.appVersion) !== null && _e !== void 0 ? _e : appVersion,
1932
+ ClientSdkVersion: (_f = payload === null || payload === void 0 ? void 0 : payload.clientSdkVersion) !== null && _f !== void 0 ? _f : trackerName,
1795
1933
  },
1796
1934
  },
1797
- Events: [
1798
- {
1799
- EventType: eventName,
1935
+ Events: queuedEvents.map((queuedEvent) => {
1936
+ const timestamp = queuedEvent.timestamp;
1937
+ const { attributes, metrics } = splitEventData(queuedEvent.payload);
1938
+ const sessionContext = queuedEvent.session ||
1939
+ {
1940
+ id: `${queuedEvent.unixMs}-${Math.random().toString(16).slice(2)}`,
1941
+ startTimestamp: timestamp,
1942
+ startUnixMs: queuedEvent.unixMs,
1943
+ };
1944
+ const isStopEvent = queuedEvent.eventName === SESSION_STOP_EVENT;
1945
+ return {
1946
+ EventType: queuedEvent.eventName,
1800
1947
  Timestamp: timestamp,
1801
1948
  Session: {
1802
1949
  Id: sessionContext.id,
1803
1950
  StartTimestamp: sessionContext.startTimestamp,
1804
1951
  EndTimestamp: timestamp,
1805
1952
  Duration: isStopEvent
1806
- ? Math.max(0, Date.now() - sessionContext.startUnixMs)
1953
+ ? Math.max(0, queuedEvent.unixMs - sessionContext.startUnixMs)
1807
1954
  : 0,
1808
1955
  },
1809
1956
  Attributes: attributes,
1810
1957
  Metrics: metrics,
1811
- },
1812
- ],
1958
+ };
1959
+ }),
1813
1960
  },
1814
1961
  };
1815
1962
  }
1816
- function createEsriPlugin({ trackerName, appName, appId, appVersion, userPoolID, fips, }) {
1963
+ function createEsriPlugin({ trackerName, appName, appId, appVersion, userPoolID, fips, debounceMs = DEFAULT_DEBOUNCE_MS, }) {
1817
1964
  const url = ESRI_ENDPOINT_URL(appId);
1818
1965
  let isDisabled = false;
1819
1966
  let hasWarned = false;
@@ -1821,8 +1968,10 @@
1821
1968
  let sessionStopSent = false;
1822
1969
  let activeSession;
1823
1970
  let idleTimerId;
1971
+ let debounceTimerId;
1824
1972
  let lifecycleListenersAttached = false;
1825
1973
  const removeLifecycleListeners = [];
1974
+ let pendingEvents = [];
1826
1975
  const isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined';
1827
1976
  const warnOnce = (message, details) => {
1828
1977
  if (hasWarned) {
@@ -1860,6 +2009,106 @@
1860
2009
  clearTimeout(idleTimerId);
1861
2010
  idleTimerId = undefined;
1862
2011
  };
2012
+ const clearDebounceTimer = () => {
2013
+ if (!debounceTimerId) {
2014
+ return;
2015
+ }
2016
+ clearTimeout(debounceTimerId);
2017
+ debounceTimerId = undefined;
2018
+ };
2019
+ const clearPendingEvents = () => {
2020
+ pendingEvents = [];
2021
+ };
2022
+ const enqueueEvent = (event) => {
2023
+ pendingEvents.push(event);
2024
+ };
2025
+ const dequeuePendingEvents = () => {
2026
+ if (pendingEvents.length === 0) {
2027
+ return [];
2028
+ }
2029
+ const queuedEvents = pendingEvents;
2030
+ pendingEvents = [];
2031
+ return queuedEvents;
2032
+ };
2033
+ const sendQueuedEvents = (queuedEvents) => {
2034
+ var _a;
2035
+ if (queuedEvents.length === 0) {
2036
+ return;
2037
+ }
2038
+ if (isDisabled || !url || !userPoolID) {
2039
+ debugLog('Skipping esri track call', {
2040
+ eventName: (_a = queuedEvents[queuedEvents.length - 1]) === null || _a === void 0 ? void 0 : _a.eventName,
2041
+ reason: 'plugin-disabled',
2042
+ });
2043
+ return;
2044
+ }
2045
+ debugLog('Sending esri endpoint batch event', {
2046
+ trackerName,
2047
+ url,
2048
+ eventCount: queuedEvents.length,
2049
+ });
2050
+ void (async () => {
2051
+ var _a;
2052
+ try {
2053
+ const credentials = await getCredentials(userPoolID, { fips });
2054
+ const accessKeyId = (credentials === null || credentials === void 0 ? void 0 : credentials.AccessKeyId) || (credentials === null || credentials === void 0 ? void 0 : credentials.accessKeyId);
2055
+ const secretAccessKey = (credentials === null || credentials === void 0 ? void 0 : credentials.SecretKey) || (credentials === null || credentials === void 0 ? void 0 : credentials.secretAccessKey);
2056
+ const sessionToken = (credentials === null || credentials === void 0 ? void 0 : credentials.SessionToken) || (credentials === null || credentials === void 0 ? void 0 : credentials.sessionToken);
2057
+ if (!accessKeyId || !secretAccessKey) {
2058
+ throw new Error('Signed endpoint credentials are missing required key fields.');
2059
+ }
2060
+ const client = new AwsClient({
2061
+ accessKeyId,
2062
+ secretAccessKey,
2063
+ sessionToken,
2064
+ service: ESRI_SIGNING_SERVICE,
2065
+ region: ESRI_SIGNING_REGION,
2066
+ });
2067
+ await client.fetch(url, {
2068
+ method: 'POST',
2069
+ headers: {
2070
+ 'Content-Type': 'application/json',
2071
+ },
2072
+ body: JSON.stringify(buildBatchEventPayload({
2073
+ queuedEvents,
2074
+ trackerName,
2075
+ appName,
2076
+ appVersion,
2077
+ })),
2078
+ });
2079
+ debugLog('Endpoint event sent', {
2080
+ trackerName,
2081
+ eventCount: queuedEvents.length,
2082
+ });
2083
+ }
2084
+ catch (error) {
2085
+ isDisabled = true;
2086
+ clearIdleTimer();
2087
+ clearDebounceTimer();
2088
+ clearPendingEvents();
2089
+ removeAllLifecycleListeners();
2090
+ warnOnce('Esri telemetry disabled after endpoint track failure', {
2091
+ eventName: (_a = queuedEvents[queuedEvents.length - 1]) === null || _a === void 0 ? void 0 : _a.eventName,
2092
+ trackerName,
2093
+ message: (error === null || error === void 0 ? void 0 : error.message) || String(error),
2094
+ });
2095
+ }
2096
+ })();
2097
+ };
2098
+ const flushPendingEvents = (eventToAppend) => {
2099
+ clearDebounceTimer();
2100
+ const queuedEvents = dequeuePendingEvents();
2101
+ if (eventToAppend) {
2102
+ queuedEvents.push(eventToAppend);
2103
+ }
2104
+ sendQueuedEvents(queuedEvents);
2105
+ };
2106
+ const scheduleDebounceFlush = () => {
2107
+ clearDebounceTimer();
2108
+ debounceTimerId = setTimeout(() => {
2109
+ flushPendingEvents();
2110
+ }, debounceMs);
2111
+ };
1863
2112
  const removeAllLifecycleListeners = () => {
1864
2113
  removeLifecycleListeners.splice(0).forEach((removeListener) => {
1865
2114
  removeListener();
@@ -1874,7 +2123,7 @@
1874
2123
  startUnixMs: now,
1875
2124
  };
1876
2125
  };
1877
- const sendEvent = (eventName, payload, sessionOverride) => {
2126
+ const sendEvent = (eventName, payload, sessionOverride, options, forceImmediate = false) => {
1878
2127
  if (isDisabled || !url || !userPoolID) {
1879
2128
  debugLog('Skipping esri track call', {
1880
2129
  eventName,
@@ -1882,63 +2131,32 @@
1882
2131
  });
1883
2132
  return false;
1884
2133
  }
1885
- debugLog('Sending esri endpoint event', {
2134
+ debugLog('Queueing esri endpoint event', {
1886
2135
  eventName,
1887
2136
  trackerName,
1888
- url,
1889
- });
1890
- void getCredentials(userPoolID, { fips })
1891
- .then((credentials) => {
1892
- const accessKeyId = (credentials === null || credentials === void 0 ? void 0 : credentials.AccessKeyId) || (credentials === null || credentials === void 0 ? void 0 : credentials.accessKeyId);
1893
- const secretAccessKey = (credentials === null || credentials === void 0 ? void 0 : credentials.SecretKey) || (credentials === null || credentials === void 0 ? void 0 : credentials.secretAccessKey);
1894
- const sessionToken = (credentials === null || credentials === void 0 ? void 0 : credentials.SessionToken) || (credentials === null || credentials === void 0 ? void 0 : credentials.sessionToken);
1895
- if (!accessKeyId || !secretAccessKey) {
1896
- throw new Error('Signed endpoint credentials are missing required key fields.');
1897
- }
1898
- const client = new AwsClient({
1899
- accessKeyId,
1900
- secretAccessKey,
1901
- sessionToken,
1902
- service: ESRI_SIGNING_SERVICE,
1903
- region: ESRI_SIGNING_REGION,
1904
- });
1905
- return client.fetch(url, {
1906
- method: 'POST',
1907
- headers: {
1908
- 'Content-Type': 'application/json',
1909
- },
1910
- body: JSON.stringify(buildBatchEventPayload({
1911
- eventName,
1912
- payload: payload,
1913
- trackerName,
1914
- appName,
1915
- appVersion,
1916
- session: sessionOverride || activeSession,
1917
- })),
1918
- });
1919
- })
1920
- .then(() => {
1921
- debugLog('Endpoint event sent', {
1922
- eventName,
1923
- trackerName,
1924
- });
1925
- })
1926
- .catch((error) => {
1927
- isDisabled = true;
1928
- clearIdleTimer();
1929
- removeAllLifecycleListeners();
1930
- warnOnce('Esri telemetry disabled after endpoint track failure', {
1931
- eventName,
1932
- trackerName,
1933
- message: (error === null || error === void 0 ? void 0 : error.message) || String(error),
1934
- });
2137
+ immediate: Boolean((options === null || options === void 0 ? void 0 : options.immediate) || forceImmediate),
1935
2138
  });
2139
+ const queuedEvent = {
2140
+ eventName,
2141
+ payload: payload,
2142
+ session: sessionOverride || activeSession,
2143
+ browserInfo: getBrowserClientInfo(),
2144
+ timestamp: new Date().toISOString(),
2145
+ unixMs: Date.now(),
2146
+ };
2147
+ if ((options === null || options === void 0 ? void 0 : options.immediate) || forceImmediate) {
2148
+ flushPendingEvents(queuedEvent);
2149
+ }
2150
+ else {
2151
+ enqueueEvent(queuedEvent);
2152
+ scheduleDebounceFlush();
2153
+ }
1936
2154
  return true;
1937
2155
  };
1938
2156
  const sendSessionLifecycleEvent = (eventName, reason, sessionOverride) => {
1939
2157
  return sendEvent(eventName, {
1940
2158
  reason,
1941
- }, sessionOverride);
2159
+ }, sessionOverride, undefined, true);
1942
2160
  };
1943
2161
  const stopSession = (reason) => {
1944
2162
  if (!hasSessionStarted || sessionStopSent) {
@@ -2008,7 +2226,7 @@
2008
2226
  lifecycleListenersAttached = true;
2009
2227
  };
2010
2228
  return {
2011
- track: (eventName, payload) => {
2229
+ track: (eventName, payload, options) => {
2012
2230
  attachLifecycleListeners();
2013
2231
  const isSessionStopEvent = eventName === SESSION_STOP_EVENT;
2014
2232
  if (!hasSessionStarted &&
@@ -2033,7 +2251,7 @@
2033
2251
  resetIdleTimer();
2034
2252
  }
2035
2253
  const sessionForEvent = activeSession;
2036
- const didSend = sendEvent(eventName, payload, sessionForEvent);
2254
+ const didSend = sendEvent(eventName, payload, sessionForEvent, options, eventName === SESSION_START_EVENT || eventName === SESSION_STOP_EVENT);
2037
2255
  if (isSessionStopEvent && didSend) {
2038
2256
  activeSession = undefined;
2039
2257
  }
@@ -2111,14 +2329,14 @@
2111
2329
  const result = this.analytics.track('pageView', telemetryPayload);
2112
2330
  return typeof result === 'boolean' ? result : true;
2113
2331
  }
2114
- logEvent(event = {}) {
2332
+ logEvent(event = {}, trackOptions) {
2115
2333
  const telemetryPayload = createEventLog({
2116
2334
  event,
2117
2335
  dimensionLookup: this.dimensions,
2118
2336
  metricLookup: this.metrics,
2119
2337
  });
2120
2338
  const { name } = telemetryPayload;
2121
- const result = this.analytics.track(name, telemetryPayload);
2339
+ const result = this.analytics.track(name, telemetryPayload, trackOptions);
2122
2340
  return typeof result === 'boolean' ? result : true;
2123
2341
  }
2124
2342
  }