@esri/telemetry-amazon 6.0.0-beta.3 → 6.0.0-beta.4
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.
- package/dist/esm/plugins/esri.js +203 -58
- package/dist/esm/plugins/esri.js.map +1 -1
- package/dist/esm/plugins/esri.test.js +125 -3
- package/dist/esm/plugins/esri.test.js.map +1 -1
- package/dist/node/plugins/esri.js +203 -58
- package/dist/node/plugins/esri.js.map +1 -1
- package/dist/node/plugins/esri.test.js +125 -3
- package/dist/node/plugins/esri.test.js.map +1 -1
- package/dist/umd/telemetry-amazon.js +203 -58
- package/dist/umd/telemetry-amazon.js.map +1 -1
- package/dist/umd/telemetry-amazon.min.js +203 -58
- package/dist/umd/telemetry-amazon.min.js.map +1 -1
- package/package.json +1 -1
|
@@ -1718,6 +1718,9 @@
|
|
|
1718
1718
|
const ESRI_SIGNING_SERVICE = 'execute-api';
|
|
1719
1719
|
const ESRI_SIGNING_REGION = 'us-east-1';
|
|
1720
1720
|
const ESRI_ENDPOINT_URL = (appId) => `https://tedev.arcgis.com/v1/apps/${appId}/events`;
|
|
1721
|
+
const SESSION_START_EVENT = '_session.start';
|
|
1722
|
+
const SESSION_STOP_EVENT = '_session.stop';
|
|
1723
|
+
const DEFAULT_IDLE_TIMEOUT_MS = 30 * 60 * 1000;
|
|
1721
1724
|
/** Converts a string to a number, guarded against invalid values */
|
|
1722
1725
|
function getNumber(value, fallback = 0) {
|
|
1723
1726
|
const numeric = Number(value);
|
|
@@ -1759,11 +1762,17 @@
|
|
|
1759
1762
|
metrics,
|
|
1760
1763
|
};
|
|
1761
1764
|
}
|
|
1762
|
-
function buildBatchEventPayload({ eventName, payload, trackerName, appName, appVersion, }) {
|
|
1765
|
+
function buildBatchEventPayload({ eventName, payload, trackerName, appName, appVersion, session, }) {
|
|
1763
1766
|
var _a, _b, _c, _d;
|
|
1764
1767
|
const endpointId = getEndpointId();
|
|
1765
|
-
const sessionId = `${Date.now()}-${Math.random().toString(16).slice(2)}`;
|
|
1766
1768
|
const timestamp = new Date().toISOString();
|
|
1769
|
+
const sessionContext = session ||
|
|
1770
|
+
{
|
|
1771
|
+
id: `${Date.now()}-${Math.random().toString(16).slice(2)}`,
|
|
1772
|
+
startTimestamp: timestamp,
|
|
1773
|
+
startUnixMs: Date.now(),
|
|
1774
|
+
};
|
|
1775
|
+
const isStopEvent = eventName === SESSION_STOP_EVENT;
|
|
1767
1776
|
const { attributes, metrics } = splitEventData(payload);
|
|
1768
1777
|
return {
|
|
1769
1778
|
BatchEvent: {
|
|
@@ -1790,10 +1799,12 @@
|
|
|
1790
1799
|
EventType: eventName,
|
|
1791
1800
|
Timestamp: timestamp,
|
|
1792
1801
|
Session: {
|
|
1793
|
-
Id:
|
|
1794
|
-
StartTimestamp:
|
|
1802
|
+
Id: sessionContext.id,
|
|
1803
|
+
StartTimestamp: sessionContext.startTimestamp,
|
|
1795
1804
|
EndTimestamp: timestamp,
|
|
1796
|
-
Duration:
|
|
1805
|
+
Duration: isStopEvent
|
|
1806
|
+
? Math.max(0, Date.now() - sessionContext.startUnixMs)
|
|
1807
|
+
: 0,
|
|
1797
1808
|
},
|
|
1798
1809
|
Attributes: attributes,
|
|
1799
1810
|
Metrics: metrics,
|
|
@@ -1806,6 +1817,13 @@
|
|
|
1806
1817
|
const url = ESRI_ENDPOINT_URL(appId);
|
|
1807
1818
|
let isDisabled = false;
|
|
1808
1819
|
let hasWarned = false;
|
|
1820
|
+
let hasSessionStarted = false;
|
|
1821
|
+
let sessionStopSent = false;
|
|
1822
|
+
let activeSession;
|
|
1823
|
+
let idleTimerId;
|
|
1824
|
+
let lifecycleListenersAttached = false;
|
|
1825
|
+
const removeLifecycleListeners = [];
|
|
1826
|
+
const isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined';
|
|
1809
1827
|
const warnOnce = (message, details) => {
|
|
1810
1828
|
if (hasWarned) {
|
|
1811
1829
|
return;
|
|
@@ -1835,64 +1853,191 @@
|
|
|
1835
1853
|
trackerName,
|
|
1836
1854
|
});
|
|
1837
1855
|
}
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1856
|
+
const clearIdleTimer = () => {
|
|
1857
|
+
if (!idleTimerId) {
|
|
1858
|
+
return;
|
|
1859
|
+
}
|
|
1860
|
+
clearTimeout(idleTimerId);
|
|
1861
|
+
idleTimerId = undefined;
|
|
1862
|
+
};
|
|
1863
|
+
const removeAllLifecycleListeners = () => {
|
|
1864
|
+
removeLifecycleListeners.splice(0).forEach((removeListener) => {
|
|
1865
|
+
removeListener();
|
|
1866
|
+
});
|
|
1867
|
+
lifecycleListenersAttached = false;
|
|
1868
|
+
};
|
|
1869
|
+
const createSession = () => {
|
|
1870
|
+
const now = Date.now();
|
|
1871
|
+
return {
|
|
1872
|
+
id: `${now}-${Math.random().toString(16).slice(2)}`,
|
|
1873
|
+
startTimestamp: new Date(now).toISOString(),
|
|
1874
|
+
startUnixMs: now,
|
|
1875
|
+
};
|
|
1876
|
+
};
|
|
1877
|
+
const sendEvent = (eventName, payload, sessionOverride) => {
|
|
1878
|
+
if (isDisabled || !url || !userPoolID) {
|
|
1879
|
+
debugLog('Skipping esri track call', {
|
|
1848
1880
|
eventName,
|
|
1849
|
-
|
|
1850
|
-
url,
|
|
1881
|
+
reason: 'plugin-disabled',
|
|
1851
1882
|
});
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
})
|
|
1881
|
-
.then(() => {
|
|
1882
|
-
debugLog('Endpoint event sent', {
|
|
1883
|
-
eventName,
|
|
1884
|
-
trackerName,
|
|
1885
|
-
});
|
|
1886
|
-
})
|
|
1887
|
-
.catch((error) => {
|
|
1888
|
-
isDisabled = true;
|
|
1889
|
-
warnOnce('Esri telemetry disabled after endpoint track failure', {
|
|
1883
|
+
return false;
|
|
1884
|
+
}
|
|
1885
|
+
debugLog('Sending esri endpoint event', {
|
|
1886
|
+
eventName,
|
|
1887
|
+
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({
|
|
1890
1911
|
eventName,
|
|
1912
|
+
payload: payload,
|
|
1891
1913
|
trackerName,
|
|
1892
|
-
|
|
1893
|
-
|
|
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),
|
|
1894
1934
|
});
|
|
1895
|
-
|
|
1935
|
+
});
|
|
1936
|
+
return true;
|
|
1937
|
+
};
|
|
1938
|
+
const sendSessionLifecycleEvent = (eventName, reason, sessionOverride) => {
|
|
1939
|
+
return sendEvent(eventName, {
|
|
1940
|
+
reason,
|
|
1941
|
+
}, sessionOverride);
|
|
1942
|
+
};
|
|
1943
|
+
const stopSession = (reason) => {
|
|
1944
|
+
if (!hasSessionStarted || sessionStopSent) {
|
|
1945
|
+
return false;
|
|
1946
|
+
}
|
|
1947
|
+
const sessionToStop = activeSession;
|
|
1948
|
+
const didStop = sendSessionLifecycleEvent(SESSION_STOP_EVENT, reason, sessionToStop);
|
|
1949
|
+
if (didStop) {
|
|
1950
|
+
sessionStopSent = true;
|
|
1951
|
+
hasSessionStarted = false;
|
|
1952
|
+
clearIdleTimer();
|
|
1953
|
+
activeSession = undefined;
|
|
1954
|
+
}
|
|
1955
|
+
return didStop;
|
|
1956
|
+
};
|
|
1957
|
+
const startSession = (reason) => {
|
|
1958
|
+
if (hasSessionStarted) {
|
|
1959
|
+
return false;
|
|
1960
|
+
}
|
|
1961
|
+
activeSession = activeSession || createSession();
|
|
1962
|
+
const sessionToStart = activeSession;
|
|
1963
|
+
const didStart = sendSessionLifecycleEvent(SESSION_START_EVENT, reason, sessionToStart);
|
|
1964
|
+
if (didStart) {
|
|
1965
|
+
hasSessionStarted = true;
|
|
1966
|
+
sessionStopSent = false;
|
|
1967
|
+
}
|
|
1968
|
+
else {
|
|
1969
|
+
activeSession = undefined;
|
|
1970
|
+
}
|
|
1971
|
+
return didStart;
|
|
1972
|
+
};
|
|
1973
|
+
const resetIdleTimer = () => {
|
|
1974
|
+
if (!isBrowser || isDisabled || !hasSessionStarted) {
|
|
1975
|
+
return;
|
|
1976
|
+
}
|
|
1977
|
+
clearIdleTimer();
|
|
1978
|
+
idleTimerId = setTimeout(() => {
|
|
1979
|
+
stopSession('idle');
|
|
1980
|
+
}, DEFAULT_IDLE_TIMEOUT_MS);
|
|
1981
|
+
};
|
|
1982
|
+
const handleActivity = () => {
|
|
1983
|
+
if (isDisabled) {
|
|
1984
|
+
return;
|
|
1985
|
+
}
|
|
1986
|
+
if (!hasSessionStarted) {
|
|
1987
|
+
startSession('wakeup');
|
|
1988
|
+
}
|
|
1989
|
+
resetIdleTimer();
|
|
1990
|
+
};
|
|
1991
|
+
const addLifecycleListener = (target, eventName, listener) => {
|
|
1992
|
+
target.addEventListener(eventName, listener);
|
|
1993
|
+
removeLifecycleListeners.push(() => {
|
|
1994
|
+
target.removeEventListener(eventName, listener);
|
|
1995
|
+
});
|
|
1996
|
+
};
|
|
1997
|
+
const attachLifecycleListeners = () => {
|
|
1998
|
+
if (!isBrowser || lifecycleListenersAttached || isDisabled) {
|
|
1999
|
+
return;
|
|
2000
|
+
}
|
|
2001
|
+
const activityEvents = ['pointerdown', 'keydown', 'scroll', 'focus'];
|
|
2002
|
+
activityEvents.forEach((eventName) => {
|
|
2003
|
+
addLifecycleListener(window, eventName, handleActivity);
|
|
2004
|
+
});
|
|
2005
|
+
addLifecycleListener(window, 'beforeunload', () => {
|
|
2006
|
+
stopSession('beforeunload');
|
|
2007
|
+
});
|
|
2008
|
+
lifecycleListenersAttached = true;
|
|
2009
|
+
};
|
|
2010
|
+
return {
|
|
2011
|
+
track: (eventName, payload) => {
|
|
2012
|
+
attachLifecycleListeners();
|
|
2013
|
+
const isSessionStopEvent = eventName === SESSION_STOP_EVENT;
|
|
2014
|
+
if (!hasSessionStarted &&
|
|
2015
|
+
eventName !== SESSION_START_EVENT &&
|
|
2016
|
+
!isSessionStopEvent) {
|
|
2017
|
+
startSession('init');
|
|
2018
|
+
}
|
|
2019
|
+
if (eventName === SESSION_START_EVENT) {
|
|
2020
|
+
activeSession = activeSession || createSession();
|
|
2021
|
+
hasSessionStarted = true;
|
|
2022
|
+
sessionStopSent = false;
|
|
2023
|
+
}
|
|
2024
|
+
if (isSessionStopEvent) {
|
|
2025
|
+
sessionStopSent = true;
|
|
2026
|
+
hasSessionStarted = false;
|
|
2027
|
+
clearIdleTimer();
|
|
2028
|
+
}
|
|
2029
|
+
if (hasSessionStarted && !activeSession && !isSessionStopEvent) {
|
|
2030
|
+
activeSession = createSession();
|
|
2031
|
+
}
|
|
2032
|
+
if (hasSessionStarted && !isSessionStopEvent) {
|
|
2033
|
+
resetIdleTimer();
|
|
2034
|
+
}
|
|
2035
|
+
const sessionForEvent = activeSession;
|
|
2036
|
+
const didSend = sendEvent(eventName, payload, sessionForEvent);
|
|
2037
|
+
if (isSessionStopEvent && didSend) {
|
|
2038
|
+
activeSession = undefined;
|
|
2039
|
+
}
|
|
2040
|
+
return didSend;
|
|
1896
2041
|
},
|
|
1897
2042
|
};
|
|
1898
2043
|
}
|