@esri/telemetry-amazon 6.0.0-beta.1 → 6.0.0-beta.11

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 (83) hide show
  1. package/README.md +9 -7
  2. package/dist/esm/auth.js +22 -31
  3. package/dist/esm/auth.js.map +1 -1
  4. package/dist/esm/create-event-log.js +15 -15
  5. package/dist/esm/create-event-log.js.map +1 -1
  6. package/dist/esm/create-event-log.test.js +50 -8
  7. package/dist/esm/create-event-log.test.js.map +1 -1
  8. package/dist/esm/create-page-view-log.js +0 -5
  9. package/dist/esm/create-page-view-log.js.map +1 -1
  10. package/dist/esm/format-telemetry-attributes.js +8 -4
  11. package/dist/esm/format-telemetry-attributes.js.map +1 -1
  12. package/dist/esm/index.js +42 -25
  13. package/dist/esm/index.js.map +1 -1
  14. package/dist/esm/index.test.js +94 -16
  15. package/dist/esm/index.test.js.map +1 -1
  16. package/dist/esm/plugins/esri.js +358 -65
  17. package/dist/esm/plugins/esri.js.map +1 -1
  18. package/dist/esm/plugins/esri.test.js +521 -36
  19. package/dist/esm/plugins/esri.test.js.map +1 -1
  20. package/dist/esm/plugins/utils/browser.js +97 -0
  21. package/dist/esm/plugins/utils/browser.js.map +1 -0
  22. package/dist/esm/plugins/utils/browser.test.js +130 -0
  23. package/dist/esm/plugins/utils/browser.test.js.map +1 -0
  24. package/dist/esm/plugins/utils/os.js +140 -0
  25. package/dist/esm/plugins/utils/os.js.map +1 -0
  26. package/dist/esm/plugins/utils/os.test.js +54 -0
  27. package/dist/esm/plugins/utils/os.test.js.map +1 -0
  28. package/dist/esm/plugins/{shared.js → utils/shared.js} +1 -1
  29. package/dist/esm/plugins/utils/shared.js.map +1 -0
  30. package/dist/esm/types.js +97 -1
  31. package/dist/esm/types.js.map +1 -1
  32. package/dist/node/auth.js +22 -31
  33. package/dist/node/auth.js.map +1 -1
  34. package/dist/node/create-event-log.js +15 -15
  35. package/dist/node/create-event-log.js.map +1 -1
  36. package/dist/node/create-event-log.test.js +50 -8
  37. package/dist/node/create-event-log.test.js.map +1 -1
  38. package/dist/node/create-page-view-log.js +0 -5
  39. package/dist/node/create-page-view-log.js.map +1 -1
  40. package/dist/node/format-telemetry-attributes.js +8 -4
  41. package/dist/node/format-telemetry-attributes.js.map +1 -1
  42. package/dist/node/index.js +43 -25
  43. package/dist/node/index.js.map +1 -1
  44. package/dist/node/index.test.js +95 -16
  45. package/dist/node/index.test.js.map +1 -1
  46. package/dist/node/plugins/esri.js +358 -65
  47. package/dist/node/plugins/esri.js.map +1 -1
  48. package/dist/node/plugins/esri.test.js +522 -36
  49. package/dist/node/plugins/esri.test.js.map +1 -1
  50. package/dist/node/plugins/utils/browser.js +101 -0
  51. package/dist/node/plugins/utils/browser.js.map +1 -0
  52. package/dist/node/plugins/utils/browser.test.js +132 -0
  53. package/dist/node/plugins/utils/browser.test.js.map +1 -0
  54. package/dist/node/plugins/utils/os.js +144 -0
  55. package/dist/node/plugins/utils/os.js.map +1 -0
  56. package/dist/node/plugins/utils/os.test.js +56 -0
  57. package/dist/node/plugins/utils/os.test.js.map +1 -0
  58. package/dist/node/plugins/{shared.js → utils/shared.js} +3 -2
  59. package/dist/node/plugins/utils/shared.js.map +1 -0
  60. package/dist/node/types.js +98 -0
  61. package/dist/node/types.js.map +1 -1
  62. package/dist/types/create-event-log.d.ts +2 -2
  63. package/dist/types/format-telemetry-attributes.d.ts +3 -3
  64. package/dist/types/index.d.ts +7 -3
  65. package/dist/types/plugins/esri.d.ts +5 -9
  66. package/dist/types/plugins/utils/browser.d.ts +12 -0
  67. package/dist/types/plugins/utils/browser.test.d.ts +1 -0
  68. package/dist/types/plugins/utils/os.d.ts +5 -0
  69. package/dist/types/plugins/utils/os.test.d.ts +1 -0
  70. package/dist/types/plugins/{shared.d.ts → utils/shared.d.ts} +1 -0
  71. package/dist/types/types.d.ts +111 -18
  72. package/dist/umd/telemetry-amazon.js +928 -368
  73. package/dist/umd/telemetry-amazon.js.map +1 -1
  74. package/dist/umd/telemetry-amazon.min.js +928 -368
  75. package/dist/umd/telemetry-amazon.min.js.map +1 -1
  76. package/package.json +4 -2
  77. package/dist/esm/plugins/pinpoint.js +0 -163
  78. package/dist/esm/plugins/pinpoint.js.map +0 -1
  79. package/dist/esm/plugins/shared.js.map +0 -1
  80. package/dist/node/plugins/pinpoint.js +0 -167
  81. package/dist/node/plugins/pinpoint.js.map +0 -1
  82. package/dist/node/plugins/shared.js.map +0 -1
  83. package/dist/types/plugins/pinpoint.d.ts +0 -11
@@ -1,16 +1,27 @@
1
1
  import { Amazon } from '.';
2
- import { createPinpointPlugin } from './plugins/pinpoint';
2
+ import Analytics from 'analytics';
3
+ import awsPinpointPlugin from '@analytics/aws-pinpoint';
3
4
  import { createEsriPlugin } from './plugins/esri';
4
- jest.mock('./plugins/pinpoint', () => ({
5
- createPinpointPlugin: jest.fn(() => ({ track: jest.fn(() => true) })),
5
+ jest.mock('analytics', () => ({
6
+ __esModule: true,
7
+ default: jest.fn(() => ({ track: jest.fn(() => true) })),
8
+ }));
9
+ jest.mock('@analytics/aws-pinpoint', () => ({
10
+ __esModule: true,
11
+ default: jest.fn(() => ({
12
+ name: 'aws-pinpoint',
13
+ })),
6
14
  }));
7
15
  jest.mock('./plugins/esri', () => ({
8
16
  createEsriPlugin: jest.fn(() => ({ track: jest.fn(() => true) })),
9
17
  }));
10
- const createPinpointPluginMock = createPinpointPlugin;
18
+ const AnalyticsMock = Analytics;
19
+ const awsPinpointPluginMock = awsPinpointPlugin;
11
20
  const createEsriPluginMock = createEsriPlugin;
21
+ const PINPOINT_RETIREMENT_CUTOFF_UTC_ISO = '2026-10-31T00:00:00.000Z';
12
22
  describe('Amazon', () => {
13
23
  afterEach(() => {
24
+ jest.useRealTimers();
14
25
  jest.clearAllMocks();
15
26
  });
16
27
  test('Amazon constructor and permissions', () => {
@@ -29,9 +40,12 @@ describe('Amazon', () => {
29
40
  mode: 'pinpoint',
30
41
  }));
31
42
  });
32
- test('pinpoint mode initializes pinpoint plugin with mapped options', () => {
33
- const pinpointPlugin = { track: jest.fn(() => true) };
34
- createPinpointPluginMock.mockReturnValue(pinpointPlugin);
43
+ test('pinpoint mode initializes upstream analytics pinpoint plugin', () => {
44
+ jest
45
+ .useFakeTimers('modern')
46
+ .setSystemTime(new Date('2026-10-30T23:59:59.000Z').getTime());
47
+ const analyticsInstance = { track: jest.fn(() => true) };
48
+ AnalyticsMock.mockReturnValue(analyticsInstance);
35
49
  new Amazon({
36
50
  userPoolID: 'pool-id',
37
51
  app: {
@@ -42,16 +56,45 @@ describe('Amazon', () => {
42
56
  mode: 'pinpoint',
43
57
  fips: true,
44
58
  });
45
- expect(createPinpointPluginMock).toHaveBeenCalledWith({
59
+ expect(awsPinpointPluginMock).toHaveBeenCalledWith({
60
+ fips: true,
61
+ pinpointAppId: '1234',
62
+ getCredentials: expect.any(Function),
63
+ });
64
+ expect(AnalyticsMock).toHaveBeenCalledWith({
65
+ app: 'test',
66
+ version: '1.0.0',
67
+ plugins: [expect.any(Object)],
68
+ });
69
+ expect(createEsriPluginMock).not.toHaveBeenCalled();
70
+ });
71
+ test('pinpoint mode falls back to esri mode on and after retirement cutoff', () => {
72
+ jest
73
+ .useFakeTimers('modern')
74
+ .setSystemTime(new Date(PINPOINT_RETIREMENT_CUTOFF_UTC_ISO));
75
+ new Amazon({
76
+ userPoolID: 'pool-id',
77
+ app: {
78
+ name: 'test',
79
+ id: '1234',
80
+ version: '1.0.0',
81
+ },
82
+ mode: 'pinpoint',
83
+ fips: true,
84
+ });
85
+ expect(awsPinpointPluginMock).not.toHaveBeenCalled();
86
+ expect(AnalyticsMock).not.toHaveBeenCalled();
87
+ expect(createEsriPluginMock).toHaveBeenCalledWith({
88
+ trackerName: 'amazon',
46
89
  appName: 'test',
47
90
  appVersion: '1.0.0',
48
91
  appId: '1234',
49
92
  userPoolID: 'pool-id',
50
93
  fips: true,
94
+ env: undefined,
51
95
  });
52
- expect(createEsriPluginMock).not.toHaveBeenCalled();
53
96
  });
54
- test('esri mode initializes esri plugin with url/headers', () => {
97
+ test('esri mode initializes esri plugin with internal endpoint config', () => {
55
98
  const esriPlugin = { track: jest.fn(() => true) };
56
99
  createEsriPluginMock.mockReturnValue(esriPlugin);
57
100
  new Amazon({
@@ -61,19 +104,54 @@ describe('Amazon', () => {
61
104
  id: '1234',
62
105
  },
63
106
  mode: 'esri',
64
- endpoint: {
65
- url: 'https://example.com/events',
66
- headers: { 'x-test': '1' },
107
+ env: 'qa',
108
+ });
109
+ expect(createEsriPluginMock).toHaveBeenCalledWith({
110
+ trackerName: 'amazon',
111
+ appName: 'test',
112
+ appVersion: undefined,
113
+ appId: '1234',
114
+ userPoolID: 'pool-id',
115
+ fips: undefined,
116
+ env: 'qa',
117
+ });
118
+ expect(AnalyticsMock).not.toHaveBeenCalled();
119
+ });
120
+ test('esri mode does not throw when userPoolID is missing at runtime', () => {
121
+ new Amazon({
122
+ mode: 'esri',
123
+ app: {
124
+ name: 'test',
125
+ id: '1234',
67
126
  },
68
127
  });
69
128
  expect(createEsriPluginMock).toHaveBeenCalledWith({
70
- url: 'https://example.com/events',
71
- headers: { 'x-test': '1' },
72
129
  trackerName: 'amazon',
73
130
  appName: 'test',
74
131
  appVersion: undefined,
132
+ appId: '1234',
133
+ userPoolID: undefined,
134
+ fips: undefined,
135
+ env: undefined,
136
+ });
137
+ expect(AnalyticsMock).not.toHaveBeenCalled();
138
+ });
139
+ test('logEvent forwards immediate track option to analytics.track', () => {
140
+ const track = jest.fn(() => true);
141
+ createEsriPluginMock.mockReturnValue({ track });
142
+ const telemetry = new Amazon({
143
+ userPoolID: 'pool-id',
144
+ app: {
145
+ name: 'test',
146
+ id: '1234',
147
+ },
148
+ mode: 'esri',
75
149
  });
76
- expect(createPinpointPluginMock).not.toHaveBeenCalled();
150
+ const result = telemetry.logEvent({ eventType: 'cta_click', category: 'nav' }, { immediate: true });
151
+ const trackMock = track;
152
+ expect(result).toBe(true);
153
+ expect(trackMock).toHaveBeenCalledTimes(1);
154
+ expect(trackMock.mock.calls[0][2]).toEqual({ immediate: true });
77
155
  });
78
156
  });
79
157
  //# sourceMappingURL=index.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.test.js","sourceRoot":"","sources":["../../src/index.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.test.js","sourceRoot":"","sources":["../../src/index.test.ts"],"names":[],"mappings":"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"}
@@ -1,14 +1,24 @@
1
- import { debugLog, warnLog, getEndpointId } from './shared';
2
- function getString(value, fallback = '') {
3
- if (value === undefined || value === null) {
4
- return fallback;
5
- }
6
- return String(value);
7
- }
1
+ import { AwsClient } from 'aws4fetch';
2
+ import { getCredentials } from '../auth';
3
+ import { debugLog, warnLog, getEndpointId, getBrowserClientInfo, } from './utils/shared';
4
+ const ESRI_SIGNING_SERVICE = 'execute-api';
5
+ const ESRI_SIGNING_REGION = 'us-east-1';
6
+ const ESRI_ENDPOINT_SUBDOMAINS = {
7
+ production: 'te',
8
+ qa: 'teqa',
9
+ dev: 'tedev',
10
+ };
11
+ const ESRI_ENDPOINT_URL = (appId, env = 'production') => `https://${ESRI_ENDPOINT_SUBDOMAINS[env || 'production']}.arcgis.com/v1/apps/${appId}/events`;
12
+ const SESSION_START_EVENT = '_session.start';
13
+ const SESSION_STOP_EVENT = '_session.stop';
14
+ const DEFAULT_IDLE_TIMEOUT_MS = 30 * 60 * 1000;
15
+ const DEFAULT_DEBOUNCE_MS = 5000;
16
+ /** Converts a string to a number, guarded against invalid values */
8
17
  function getNumber(value, fallback = 0) {
9
18
  const numeric = Number(value);
10
19
  return Number.isFinite(numeric) ? numeric : fallback;
11
20
  }
21
+ /** Splits an EsriBatchEventPayload into attributes and metrics */
12
22
  function splitEventData(payload) {
13
23
  const attributes = {};
14
24
  const metrics = {};
@@ -45,93 +55,376 @@ function splitEventData(payload) {
45
55
  metrics,
46
56
  };
47
57
  }
48
- function buildBatchEventPayload({ eventName, payload, trackerName, appName, appVersion, }) {
58
+ /** Constructs an event payload in the shape expected by the endpoint. */
59
+ function buildBatchEventPayload({ queuedEvents, trackerName, appName, appVersion, }) {
60
+ var _a, _b, _c, _d, _e, _f;
61
+ const endpointEvent = queuedEvents[queuedEvents.length - 1] ||
62
+ {
63
+ payload: {},
64
+ browserInfo: {},
65
+ };
66
+ const payload = endpointEvent.payload || {};
67
+ const browserInfo = endpointEvent.browserInfo || {};
49
68
  const endpointId = getEndpointId();
50
- const sessionId = `${Date.now()}-${Math.random().toString(16).slice(2)}`;
51
- const timestamp = new Date().toISOString();
52
- const { attributes, metrics } = splitEventData(payload);
69
+ const location = {};
70
+ if (payload === null || payload === void 0 ? void 0 : payload.city) {
71
+ location.City = payload.city;
72
+ }
73
+ if (payload === null || payload === void 0 ? void 0 : payload.country) {
74
+ location.Country = payload.country;
75
+ }
76
+ if ((payload === null || payload === void 0 ? void 0 : payload.lat) !== undefined && (payload === null || payload === void 0 ? void 0 : payload.lat) !== null) {
77
+ location.Lat = getNumber(payload.lat);
78
+ }
79
+ if ((payload === null || payload === void 0 ? void 0 : payload.lon) !== undefined && (payload === null || payload === void 0 ? void 0 : payload.lon) !== null) {
80
+ location.Lon = getNumber(payload.lon);
81
+ }
53
82
  return {
54
83
  BatchEvent: {
55
84
  Endpoint: {
56
85
  Id: endpointId,
57
- Device: {
58
- Make: getString(payload === null || payload === void 0 ? void 0 : payload.deviceMake),
59
- Model: getString(payload === null || payload === void 0 ? void 0 : payload.deviceModel),
60
- },
61
- Location: {
62
- City: getString(payload === null || payload === void 0 ? void 0 : payload.city),
63
- Country: getString(payload === null || payload === void 0 ? void 0 : payload.country),
64
- Lat: getNumber(payload === null || payload === void 0 ? void 0 : payload.lat),
65
- Lon: getNumber(payload === null || payload === void 0 ? void 0 : payload.lon),
66
- },
86
+ 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)
87
+ ? { PlatformVersion: browserInfo.os.version }
88
+ : {})),
89
+ Location: location,
67
90
  Application: {
68
- AppTitle: getString(payload === null || payload === void 0 ? void 0 : payload.appTitle, appName || trackerName),
69
- AppVersion: getString(payload === null || payload === void 0 ? void 0 : payload.appVersion, appVersion),
70
- ClientSdkVersion: getString(payload === null || payload === void 0 ? void 0 : payload.clientSdkVersion, trackerName),
91
+ AppTitle: (_d = (_c = payload === null || payload === void 0 ? void 0 : payload.appTitle) !== null && _c !== void 0 ? _c : appName) !== null && _d !== void 0 ? _d : trackerName,
92
+ AppVersion: (_e = payload === null || payload === void 0 ? void 0 : payload.appVersion) !== null && _e !== void 0 ? _e : appVersion,
93
+ ClientSdkVersion: (_f = payload === null || payload === void 0 ? void 0 : payload.clientSdkVersion) !== null && _f !== void 0 ? _f : trackerName,
71
94
  },
72
95
  },
73
- Events: [
74
- {
75
- EventType: eventName,
96
+ Events: queuedEvents.map((queuedEvent) => {
97
+ const timestamp = queuedEvent.timestamp;
98
+ const { attributes, metrics } = splitEventData(queuedEvent.payload);
99
+ const sessionContext = queuedEvent.session ||
100
+ {
101
+ id: `${queuedEvent.unixMs}-${Math.random().toString(16).slice(2)}`,
102
+ startTimestamp: timestamp,
103
+ startUnixMs: queuedEvent.unixMs,
104
+ };
105
+ const isStopEvent = queuedEvent.eventName === SESSION_STOP_EVENT;
106
+ return {
107
+ EventType: queuedEvent.eventName,
76
108
  Timestamp: timestamp,
77
109
  Session: {
78
- Id: sessionId,
79
- StartTimestamp: timestamp,
110
+ Id: sessionContext.id,
111
+ StartTimestamp: sessionContext.startTimestamp,
80
112
  EndTimestamp: timestamp,
81
- Duration: 0,
113
+ Duration: isStopEvent
114
+ ? Math.max(0, queuedEvent.unixMs - sessionContext.startUnixMs)
115
+ : 0,
82
116
  },
83
117
  Attributes: attributes,
84
118
  Metrics: metrics,
85
- },
86
- ],
119
+ };
120
+ }),
87
121
  },
88
122
  };
89
123
  }
90
- export function createEsriPlugin({ url, headers = {}, trackerName, appName, appVersion, }) {
124
+ export function createEsriPlugin({ trackerName, appName, appId, appVersion, userPoolID, fips, debounceMs = DEFAULT_DEBOUNCE_MS, env = 'production', }) {
125
+ const url = ESRI_ENDPOINT_URL(appId, env);
126
+ console.log("url set", url);
127
+ let isDisabled = false;
128
+ let hasWarned = false;
129
+ let hasSessionStarted = false;
130
+ let sessionStopSent = false;
131
+ let activeSession;
132
+ let idleTimerId;
133
+ let debounceTimerId;
134
+ let lifecycleListenersAttached = false;
135
+ const removeLifecycleListeners = [];
136
+ let pendingEvents = [];
137
+ const isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined';
138
+ const warnOnce = (message, details) => {
139
+ if (hasWarned) {
140
+ return;
141
+ }
142
+ hasWarned = true;
143
+ warnLog(message, details);
144
+ };
91
145
  debugLog('createEsriPlugin initialized', {
92
146
  trackerName,
93
147
  hasUrl: Boolean(url),
94
- headerCount: Object.keys(headers).length,
95
148
  });
96
- return {
97
- track: (eventName, payload) => {
98
- if (!url || typeof fetch !== 'function') {
99
- debugLog('Skipping endpoint track call', {
100
- eventName,
101
- reason: !url ? 'missing-url' : 'fetch-unavailable',
102
- });
103
- return false;
104
- }
105
- debugLog('Sending endpoint event', {
106
- eventName,
107
- trackerName,
108
- url,
149
+ if (!url) {
150
+ isDisabled = true;
151
+ warnOnce('Esri telemetry disabled due to missing internal endpoint URL', {
152
+ trackerName,
153
+ });
154
+ }
155
+ if (!userPoolID) {
156
+ isDisabled = true;
157
+ warnOnce('Esri telemetry disabled due to missing userPoolID', {
158
+ trackerName,
159
+ });
160
+ }
161
+ if (typeof fetch !== 'function') {
162
+ isDisabled = true;
163
+ warnOnce('Esri telemetry disabled because fetch is unavailable', {
164
+ trackerName,
165
+ });
166
+ }
167
+ const clearIdleTimer = () => {
168
+ if (!idleTimerId) {
169
+ return;
170
+ }
171
+ clearTimeout(idleTimerId);
172
+ idleTimerId = undefined;
173
+ };
174
+ const clearDebounceTimer = () => {
175
+ if (!debounceTimerId) {
176
+ return;
177
+ }
178
+ clearTimeout(debounceTimerId);
179
+ debounceTimerId = undefined;
180
+ };
181
+ const clearPendingEvents = () => {
182
+ pendingEvents = [];
183
+ };
184
+ const enqueueEvent = (event) => {
185
+ pendingEvents.push(event);
186
+ };
187
+ const dequeuePendingEvents = () => {
188
+ if (pendingEvents.length === 0) {
189
+ return [];
190
+ }
191
+ const queuedEvents = pendingEvents;
192
+ pendingEvents = [];
193
+ return queuedEvents;
194
+ };
195
+ const sendQueuedEvents = (queuedEvents) => {
196
+ var _a;
197
+ if (queuedEvents.length === 0) {
198
+ return;
199
+ }
200
+ if (isDisabled || !url || !userPoolID) {
201
+ debugLog('Skipping esri track call', {
202
+ eventName: (_a = queuedEvents[queuedEvents.length - 1]) === null || _a === void 0 ? void 0 : _a.eventName,
203
+ reason: 'plugin-disabled',
109
204
  });
110
- void fetch(url, {
111
- method: 'POST',
112
- headers: Object.assign({ 'Content-Type': 'application/json' }, headers),
113
- body: JSON.stringify(buildBatchEventPayload({
114
- eventName,
115
- payload,
116
- trackerName,
117
- appName,
118
- appVersion,
119
- })),
120
- })
121
- .then(() => {
205
+ return;
206
+ }
207
+ debugLog('Sending esri endpoint batch event', {
208
+ trackerName,
209
+ url,
210
+ eventCount: queuedEvents.length,
211
+ });
212
+ void (async () => {
213
+ var _a;
214
+ try {
215
+ const credentials = await getCredentials(userPoolID, { fips });
216
+ const accessKeyId = (credentials === null || credentials === void 0 ? void 0 : credentials.AccessKeyId) || (credentials === null || credentials === void 0 ? void 0 : credentials.accessKeyId);
217
+ const secretAccessKey = (credentials === null || credentials === void 0 ? void 0 : credentials.SecretKey) || (credentials === null || credentials === void 0 ? void 0 : credentials.secretAccessKey);
218
+ const sessionToken = (credentials === null || credentials === void 0 ? void 0 : credentials.SessionToken) || (credentials === null || credentials === void 0 ? void 0 : credentials.sessionToken);
219
+ if (!accessKeyId || !secretAccessKey) {
220
+ throw new Error('Signed endpoint credentials are missing required key fields.');
221
+ }
222
+ const client = new AwsClient({
223
+ accessKeyId,
224
+ secretAccessKey,
225
+ sessionToken,
226
+ service: ESRI_SIGNING_SERVICE,
227
+ region: ESRI_SIGNING_REGION,
228
+ });
229
+ const response = await client.fetch(url, {
230
+ method: 'POST',
231
+ headers: {
232
+ 'Content-Type': 'application/json',
233
+ },
234
+ body: JSON.stringify(buildBatchEventPayload({
235
+ queuedEvents,
236
+ trackerName,
237
+ appName,
238
+ appVersion,
239
+ })),
240
+ });
241
+ if (response.status === 403) {
242
+ warnLog('Response forbidden. Confirm that the configured env matches the the supplied app ID.', { env, url });
243
+ }
244
+ if (!response.ok) {
245
+ throw new Error(`Esri telemetry endpoint returned ${response.status}.`);
246
+ }
122
247
  debugLog('Endpoint event sent', {
123
- eventName,
124
248
  trackerName,
249
+ eventCount: queuedEvents.length,
125
250
  });
126
- })
127
- .catch((error) => {
128
- warnLog('Endpoint track failed', {
129
- eventName,
251
+ }
252
+ catch (error) {
253
+ isDisabled = true;
254
+ clearIdleTimer();
255
+ clearDebounceTimer();
256
+ clearPendingEvents();
257
+ removeAllLifecycleListeners();
258
+ warnOnce('Esri telemetry disabled after endpoint track failure', {
259
+ eventName: (_a = queuedEvents[queuedEvents.length - 1]) === null || _a === void 0 ? void 0 : _a.eventName,
130
260
  trackerName,
131
261
  message: (error === null || error === void 0 ? void 0 : error.message) || String(error),
132
262
  });
263
+ }
264
+ })();
265
+ };
266
+ const flushPendingEvents = (eventToAppend) => {
267
+ clearDebounceTimer();
268
+ const queuedEvents = dequeuePendingEvents();
269
+ if (eventToAppend) {
270
+ queuedEvents.push(eventToAppend);
271
+ }
272
+ sendQueuedEvents(queuedEvents);
273
+ };
274
+ const scheduleDebounceFlush = () => {
275
+ clearDebounceTimer();
276
+ debounceTimerId = setTimeout(() => {
277
+ flushPendingEvents();
278
+ }, debounceMs);
279
+ };
280
+ const removeAllLifecycleListeners = () => {
281
+ removeLifecycleListeners.splice(0).forEach((removeListener) => {
282
+ removeListener();
283
+ });
284
+ lifecycleListenersAttached = false;
285
+ };
286
+ const createSession = () => {
287
+ const now = Date.now();
288
+ return {
289
+ id: `${now}-${Math.random().toString(16).slice(2)}`,
290
+ startTimestamp: new Date(now).toISOString(),
291
+ startUnixMs: now,
292
+ };
293
+ };
294
+ const sendEvent = (eventName, payload, sessionOverride, options, forceImmediate = false) => {
295
+ if (isDisabled || !url || !userPoolID) {
296
+ debugLog('Skipping esri track call', {
297
+ eventName,
298
+ reason: 'plugin-disabled',
133
299
  });
134
- return true;
300
+ return false;
301
+ }
302
+ debugLog('Queueing esri endpoint event', {
303
+ eventName,
304
+ trackerName,
305
+ immediate: Boolean((options === null || options === void 0 ? void 0 : options.immediate) || forceImmediate),
306
+ });
307
+ const queuedEvent = {
308
+ eventName,
309
+ payload: payload,
310
+ session: sessionOverride || activeSession,
311
+ browserInfo: getBrowserClientInfo(),
312
+ timestamp: new Date().toISOString(),
313
+ unixMs: Date.now(),
314
+ };
315
+ if ((options === null || options === void 0 ? void 0 : options.immediate) || forceImmediate) {
316
+ flushPendingEvents(queuedEvent);
317
+ }
318
+ else {
319
+ enqueueEvent(queuedEvent);
320
+ scheduleDebounceFlush();
321
+ }
322
+ return true;
323
+ };
324
+ const sendSessionLifecycleEvent = (eventName, reason, sessionOverride) => {
325
+ return sendEvent(eventName, {
326
+ reason,
327
+ }, sessionOverride, undefined, true);
328
+ };
329
+ const stopSession = (reason) => {
330
+ if (!hasSessionStarted || sessionStopSent) {
331
+ return false;
332
+ }
333
+ const sessionToStop = activeSession;
334
+ const didStop = sendSessionLifecycleEvent(SESSION_STOP_EVENT, reason, sessionToStop);
335
+ if (didStop) {
336
+ sessionStopSent = true;
337
+ hasSessionStarted = false;
338
+ clearIdleTimer();
339
+ activeSession = undefined;
340
+ }
341
+ return didStop;
342
+ };
343
+ const startSession = (reason) => {
344
+ if (hasSessionStarted) {
345
+ return false;
346
+ }
347
+ activeSession = activeSession || createSession();
348
+ const sessionToStart = activeSession;
349
+ const didStart = sendSessionLifecycleEvent(SESSION_START_EVENT, reason, sessionToStart);
350
+ if (didStart) {
351
+ hasSessionStarted = true;
352
+ sessionStopSent = false;
353
+ }
354
+ else {
355
+ activeSession = undefined;
356
+ }
357
+ return didStart;
358
+ };
359
+ const resetIdleTimer = () => {
360
+ if (!isBrowser || isDisabled || !hasSessionStarted) {
361
+ return;
362
+ }
363
+ clearIdleTimer();
364
+ idleTimerId = setTimeout(() => {
365
+ stopSession('idle');
366
+ }, DEFAULT_IDLE_TIMEOUT_MS);
367
+ };
368
+ const handleActivity = () => {
369
+ if (isDisabled) {
370
+ return;
371
+ }
372
+ if (!hasSessionStarted) {
373
+ startSession('wakeup');
374
+ }
375
+ resetIdleTimer();
376
+ };
377
+ const addLifecycleListener = (target, eventName, listener) => {
378
+ target.addEventListener(eventName, listener);
379
+ removeLifecycleListeners.push(() => {
380
+ target.removeEventListener(eventName, listener);
381
+ });
382
+ };
383
+ const attachLifecycleListeners = () => {
384
+ if (!isBrowser || lifecycleListenersAttached || isDisabled) {
385
+ return;
386
+ }
387
+ const activityEvents = ['pointerdown', 'keydown', 'scroll', 'focus'];
388
+ activityEvents.forEach((eventName) => {
389
+ addLifecycleListener(window, eventName, handleActivity);
390
+ });
391
+ addLifecycleListener(window, 'beforeunload', () => {
392
+ stopSession('beforeunload');
393
+ });
394
+ lifecycleListenersAttached = true;
395
+ };
396
+ return {
397
+ track: (eventName, payload, options) => {
398
+ void options;
399
+ attachLifecycleListeners();
400
+ const isSessionStopEvent = eventName === SESSION_STOP_EVENT;
401
+ if (!hasSessionStarted &&
402
+ eventName !== SESSION_START_EVENT &&
403
+ !isSessionStopEvent) {
404
+ startSession('init');
405
+ }
406
+ if (eventName === SESSION_START_EVENT) {
407
+ activeSession = activeSession || createSession();
408
+ hasSessionStarted = true;
409
+ sessionStopSent = false;
410
+ }
411
+ if (isSessionStopEvent) {
412
+ sessionStopSent = true;
413
+ hasSessionStarted = false;
414
+ clearIdleTimer();
415
+ }
416
+ if (hasSessionStarted && !activeSession && !isSessionStopEvent) {
417
+ activeSession = createSession();
418
+ }
419
+ if (hasSessionStarted && !isSessionStopEvent) {
420
+ resetIdleTimer();
421
+ }
422
+ const sessionForEvent = activeSession;
423
+ const didSend = sendEvent(eventName, payload, sessionForEvent, options, eventName === SESSION_START_EVENT || eventName === SESSION_STOP_EVENT);
424
+ if (isSessionStopEvent && didSend) {
425
+ activeSession = undefined;
426
+ }
427
+ return didSend;
135
428
  },
136
429
  };
137
430
  }