@adwait12345/telemetry-core 0.1.2 → 0.1.3

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/index.d.mts CHANGED
@@ -65,6 +65,18 @@ interface TelemetryConfig {
65
65
  * This is required since these requests originate from the server and cannot pass domain validation checks via Origin.
66
66
  */
67
67
  serverSecret?: string;
68
+ /**
69
+ * Fully custom Authorization header value.
70
+ * Overrides the default "Bearer {serverSecret}" format.
71
+ * e.g. "Token mytoken" or "Basic dXNlcjpwYXNz"
72
+ */
73
+ authorizationHeader?: string;
74
+ /**
75
+ * Additional custom headers to send with every telemetry request.
76
+ * These are merged on top of the defaults and can override them.
77
+ * e.g. { "x-workspace-id": "abc123" }
78
+ */
79
+ headers?: Record<string, string>;
68
80
  }
69
81
  /** Payload sent to the Telemetry server-side tracking endpoint */
70
82
  interface ServerTrackPayload {
@@ -142,7 +154,7 @@ declare const ALL_BOTS: BotDefinition[];
142
154
 
143
155
  /**
144
156
  * Sends a server-side payload to the Telemetry backend.
145
- * This is meant to be fire-and-forget, so it does not throw errors.
157
+ * Automatically retries on transient failures with exponential backoff.
146
158
  *
147
159
  * @param payload The data to track.
148
160
  * @param config The Telemetry configuration.
package/dist/index.d.ts CHANGED
@@ -65,6 +65,18 @@ interface TelemetryConfig {
65
65
  * This is required since these requests originate from the server and cannot pass domain validation checks via Origin.
66
66
  */
67
67
  serverSecret?: string;
68
+ /**
69
+ * Fully custom Authorization header value.
70
+ * Overrides the default "Bearer {serverSecret}" format.
71
+ * e.g. "Token mytoken" or "Basic dXNlcjpwYXNz"
72
+ */
73
+ authorizationHeader?: string;
74
+ /**
75
+ * Additional custom headers to send with every telemetry request.
76
+ * These are merged on top of the defaults and can override them.
77
+ * e.g. { "x-workspace-id": "abc123" }
78
+ */
79
+ headers?: Record<string, string>;
68
80
  }
69
81
  /** Payload sent to the Telemetry server-side tracking endpoint */
70
82
  interface ServerTrackPayload {
@@ -142,7 +154,7 @@ declare const ALL_BOTS: BotDefinition[];
142
154
 
143
155
  /**
144
156
  * Sends a server-side payload to the Telemetry backend.
145
- * This is meant to be fire-and-forget, so it does not throw errors.
157
+ * Automatically retries on transient failures with exponential backoff.
146
158
  *
147
159
  * @param payload The data to track.
148
160
  * @param config The Telemetry configuration.
package/dist/index.js CHANGED
@@ -1112,6 +1112,59 @@ function extractAutomationHeaders(headers) {
1112
1112
  }
1113
1113
 
1114
1114
  // src/index.ts
1115
+ function buildHeaders(config) {
1116
+ const headers = {
1117
+ "Content-Type": "application/json"
1118
+ };
1119
+ if (config.authorizationHeader) {
1120
+ headers["Authorization"] = config.authorizationHeader;
1121
+ } else if (config.serverSecret) {
1122
+ headers["Authorization"] = `Bearer ${config.serverSecret}`;
1123
+ }
1124
+ if (config.headers) {
1125
+ Object.assign(headers, config.headers);
1126
+ }
1127
+ return headers;
1128
+ }
1129
+ async function sendWithRetry(endpoint, payload, config, retries = 2) {
1130
+ const headers = buildHeaders(config);
1131
+ for (let attempt = 0; attempt <= retries; attempt++) {
1132
+ const controller = new AbortController();
1133
+ const timeout = setTimeout(() => controller.abort(), 5e3);
1134
+ try {
1135
+ const response = await fetch(endpoint, {
1136
+ method: "POST",
1137
+ headers,
1138
+ body: JSON.stringify(payload),
1139
+ signal: controller.signal
1140
+ });
1141
+ clearTimeout(timeout);
1142
+ if (response.ok) return;
1143
+ if (config.debug) {
1144
+ const text = await response.text();
1145
+ console.error(
1146
+ `[Telemetry] Attempt ${attempt + 1} failed: ${response.status} \u2014 ${text}`
1147
+ );
1148
+ }
1149
+ if (response.status >= 400 && response.status < 500) return;
1150
+ } catch (error) {
1151
+ clearTimeout(timeout);
1152
+ if (config.debug) {
1153
+ if (error?.name === "AbortError") {
1154
+ console.error(`[Telemetry] Attempt ${attempt + 1} timed out after 5s.`);
1155
+ } else {
1156
+ console.error(`[Telemetry] Attempt ${attempt + 1} error:`, error);
1157
+ }
1158
+ }
1159
+ }
1160
+ if (attempt < retries) {
1161
+ await new Promise((r) => setTimeout(r, 200 * Math.pow(2, attempt)));
1162
+ }
1163
+ }
1164
+ if (config.debug) {
1165
+ console.error("[Telemetry] All retry attempts failed \u2014 giving up.");
1166
+ }
1167
+ }
1115
1168
  async function sendToTelemetry(payload, config) {
1116
1169
  if (!config.apiUrl) {
1117
1170
  if (config.debug) {
@@ -1123,34 +1176,7 @@ async function sendToTelemetry(payload, config) {
1123
1176
  if (config.debug) {
1124
1177
  console.log(`[Telemetry] Sending payload to ${endpoint}`, payload);
1125
1178
  }
1126
- const controller = new AbortController();
1127
- const timeout = setTimeout(() => controller.abort(), 3e3);
1128
- try {
1129
- const response = await fetch(endpoint, {
1130
- method: "POST",
1131
- headers: {
1132
- "Content-Type": "application/json",
1133
- "Authorization": `Bearer ${config.serverSecret}`
1134
- },
1135
- body: JSON.stringify(payload),
1136
- signal: controller.signal
1137
- });
1138
- if (!response.ok && config.debug) {
1139
- console.error(`[Telemetry] Failed to send payload: ${response.status} ${response.statusText}`);
1140
- const text = await response.text();
1141
- console.error(`[Telemetry] Response body:`, text);
1142
- }
1143
- } catch (error) {
1144
- if (config.debug) {
1145
- if (error?.name === "AbortError") {
1146
- console.error("[Telemetry] Request timed out after 3s \u2014 skipping.");
1147
- } else {
1148
- console.error("[Telemetry] Error sending payload:", error);
1149
- }
1150
- }
1151
- } finally {
1152
- clearTimeout(timeout);
1153
- }
1179
+ await sendWithRetry(endpoint, payload, config);
1154
1180
  }
1155
1181
  // Annotate the CommonJS export names for ESM import in node:
1156
1182
  0 && (module.exports = {
package/dist/index.mjs CHANGED
@@ -1068,6 +1068,59 @@ function extractAutomationHeaders(headers) {
1068
1068
  }
1069
1069
 
1070
1070
  // src/index.ts
1071
+ function buildHeaders(config) {
1072
+ const headers = {
1073
+ "Content-Type": "application/json"
1074
+ };
1075
+ if (config.authorizationHeader) {
1076
+ headers["Authorization"] = config.authorizationHeader;
1077
+ } else if (config.serverSecret) {
1078
+ headers["Authorization"] = `Bearer ${config.serverSecret}`;
1079
+ }
1080
+ if (config.headers) {
1081
+ Object.assign(headers, config.headers);
1082
+ }
1083
+ return headers;
1084
+ }
1085
+ async function sendWithRetry(endpoint, payload, config, retries = 2) {
1086
+ const headers = buildHeaders(config);
1087
+ for (let attempt = 0; attempt <= retries; attempt++) {
1088
+ const controller = new AbortController();
1089
+ const timeout = setTimeout(() => controller.abort(), 5e3);
1090
+ try {
1091
+ const response = await fetch(endpoint, {
1092
+ method: "POST",
1093
+ headers,
1094
+ body: JSON.stringify(payload),
1095
+ signal: controller.signal
1096
+ });
1097
+ clearTimeout(timeout);
1098
+ if (response.ok) return;
1099
+ if (config.debug) {
1100
+ const text = await response.text();
1101
+ console.error(
1102
+ `[Telemetry] Attempt ${attempt + 1} failed: ${response.status} \u2014 ${text}`
1103
+ );
1104
+ }
1105
+ if (response.status >= 400 && response.status < 500) return;
1106
+ } catch (error) {
1107
+ clearTimeout(timeout);
1108
+ if (config.debug) {
1109
+ if (error?.name === "AbortError") {
1110
+ console.error(`[Telemetry] Attempt ${attempt + 1} timed out after 5s.`);
1111
+ } else {
1112
+ console.error(`[Telemetry] Attempt ${attempt + 1} error:`, error);
1113
+ }
1114
+ }
1115
+ }
1116
+ if (attempt < retries) {
1117
+ await new Promise((r) => setTimeout(r, 200 * Math.pow(2, attempt)));
1118
+ }
1119
+ }
1120
+ if (config.debug) {
1121
+ console.error("[Telemetry] All retry attempts failed \u2014 giving up.");
1122
+ }
1123
+ }
1071
1124
  async function sendToTelemetry(payload, config) {
1072
1125
  if (!config.apiUrl) {
1073
1126
  if (config.debug) {
@@ -1079,34 +1132,7 @@ async function sendToTelemetry(payload, config) {
1079
1132
  if (config.debug) {
1080
1133
  console.log(`[Telemetry] Sending payload to ${endpoint}`, payload);
1081
1134
  }
1082
- const controller = new AbortController();
1083
- const timeout = setTimeout(() => controller.abort(), 3e3);
1084
- try {
1085
- const response = await fetch(endpoint, {
1086
- method: "POST",
1087
- headers: {
1088
- "Content-Type": "application/json",
1089
- "Authorization": `Bearer ${config.serverSecret}`
1090
- },
1091
- body: JSON.stringify(payload),
1092
- signal: controller.signal
1093
- });
1094
- if (!response.ok && config.debug) {
1095
- console.error(`[Telemetry] Failed to send payload: ${response.status} ${response.statusText}`);
1096
- const text = await response.text();
1097
- console.error(`[Telemetry] Response body:`, text);
1098
- }
1099
- } catch (error) {
1100
- if (config.debug) {
1101
- if (error?.name === "AbortError") {
1102
- console.error("[Telemetry] Request timed out after 3s \u2014 skipping.");
1103
- } else {
1104
- console.error("[Telemetry] Error sending payload:", error);
1105
- }
1106
- }
1107
- } finally {
1108
- clearTimeout(timeout);
1109
- }
1135
+ await sendWithRetry(endpoint, payload, config);
1110
1136
  }
1111
1137
  export {
1112
1138
  ACCESSIBILITY_BOTS,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adwait12345/telemetry-core",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "Framework-agnostic core for Telemetry SDK — bot detection and server-side tracking",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",