cryptique-sdk 1.2.4 → 1.2.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.
package/lib/cjs/index.js CHANGED
@@ -4302,31 +4302,6 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
4302
4302
 
4303
4303
  };
4304
4304
 
4305
- // ============================================================================
4306
- // SECTION 13: API COMMUNICATION
4307
- // ============================================================================
4308
- // PURPOSE: Unified API client for all backend communication. Handles sending
4309
- // session data, custom events, and UTM events.
4310
- //
4311
- // KEY PRINCIPLES:
4312
- // 1. Unified API client for all endpoints
4313
- // 2. Transforms data using DataTransformer before sending
4314
- // 3. Handles retries and errors gracefully
4315
- // 4. Uses sendBeacon for beforeunload (last resort)
4316
- // 5. Uses fetch with keepalive for regular sends
4317
- // 6. Comprehensive error handling and logging
4318
- //
4319
- // BENEFITS:
4320
- // - Single place to handle all API communication
4321
- // - Consistent error handling
4322
- // - Retry logic for reliability
4323
- // - Proper use of sendBeacon vs fetch
4324
- // ============================================================================
4325
-
4326
- // Throttle network error logs (e.g. "Failed to fetch" from ad blockers) - log at most once per 30s
4327
- let _lastNetworkErrorLog = 0;
4328
- const _NETWORK_ERROR_THROTTLE_MS = 30000;
4329
-
4330
4305
  /**
4331
4306
  * APIClient - Unified API communication
4332
4307
  *
@@ -4502,17 +4477,24 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
4502
4477
  }
4503
4478
 
4504
4479
  // Handle AbortError gracefully (timeout or page unload)
4505
- if (error.name === 'AbortError' || error.message?.includes('aborted') || error.message?.includes('signal is aborted')) {
4480
+ if (
4481
+ error.name === 'AbortError' ||
4482
+ error.message?.includes('aborted') ||
4483
+ error.message?.includes('signal is aborted')
4484
+ ) {
4506
4485
  // Don't log as error - this is expected behavior for timeouts or page unloads
4507
4486
  // Don't retry aborted requests - they were intentionally cancelled
4508
4487
  return; // Silently return, don't throw
4509
4488
  }
4510
4489
 
4511
- // Throttle "Failed to fetch" logs (common with ad blockers, CORS, network issues)
4512
- const isNetworkError = error.name === 'TypeError' && (error.message === 'Failed to fetch' || error.message?.includes('fetch'));
4513
- const now = Date.now();
4514
- if (isNetworkError && (now - _lastNetworkErrorLog) < _NETWORK_ERROR_THROTTLE_MS) ; else {
4515
- if (isNetworkError) _lastNetworkErrorLog = now;
4490
+ // Treat common network issues (ad blockers, CORS, offline, etc.) as silent failures.
4491
+ // We still retry according to the "retries" option, but we do not log these to the console.
4492
+ const isNetworkError =
4493
+ error.name === 'TypeError' &&
4494
+ (error.message === 'Failed to fetch' || error.message?.includes('fetch'));
4495
+
4496
+ // Only log unexpected / non‑network errors
4497
+ if (!isNetworkError) {
4516
4498
  console.error('❌ Error sending data:', error);
4517
4499
  }
4518
4500
 
@@ -4522,7 +4504,11 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
4522
4504
  return this.send(endpoint, data, { ...options, retries: retries - 1 });
4523
4505
  }
4524
4506
 
4525
- throw error;
4507
+ // For non‑network errors that made it this far, surface to callers
4508
+ if (!isNetworkError) {
4509
+ throw error;
4510
+ }
4511
+ // For network errors, fail silently after retries are exhausted
4526
4512
  }
4527
4513
  },
4528
4514
 
@@ -5339,57 +5325,16 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
5339
5325
  },
5340
5326
 
5341
5327
  /**
5342
- * NetworkTracker - Tracks network errors (fetch and XMLHttpRequest)
5328
+ * NetworkTracker - Tracks network errors (XHR only)
5329
+ *
5330
+ * NOTE:
5331
+ * We intentionally do NOT wrap window.fetch here, to avoid confusing
5332
+ * browser DevTools attribution for third‑party requests. All SDK
5333
+ * fetch-based calls to backend.cryptique.io are already error-handled
5334
+ * inside APIClient.send(), so fetch wrapping is redundant.
5343
5335
  */
5344
5336
  startNetworkTracking() {
5345
5337
  try {
5346
- // Track fetch errors - only intercept calls to our own backend
5347
- // Use _nativeFetch as the base so the wrapper always delegates to the
5348
- // true browser fetch, regardless of what other libraries have patched.
5349
- window.fetch = function(...args) {
5350
- const startTime = Date.now();
5351
- const url = typeof args[0] === 'string' ? args[0] : (args[0]?.url || '');
5352
-
5353
- // Pass third-party requests through completely untouched — no interception,
5354
- // no involvement of our SDK in their call stack or error handling
5355
- if (!url.includes('backend.cryptique.io')) {
5356
- return _nativeFetch.apply(this, args);
5357
- }
5358
-
5359
- return _nativeFetch.apply(this, args).then(response => {
5360
- // Only track error status codes (4xx, 5xx)
5361
- if (response.status >= 400) {
5362
- const networkErrorData = {
5363
- type: 'api_error',
5364
- url: url,
5365
- method: 'GET',
5366
- status: response.status,
5367
- error: `HTTP ${response.status} Error`,
5368
- duration: Date.now() - startTime,
5369
- path: window.location.pathname
5370
- };
5371
-
5372
- InteractionManager.add('networkEvents', networkErrorData);
5373
- }
5374
-
5375
- return response;
5376
- }).catch(error => {
5377
- // Track actual network errors
5378
- const networkErrorData = {
5379
- type: 'api_error',
5380
- url: url,
5381
- method: 'GET',
5382
- status: 0,
5383
- error: error.message || 'Network Error',
5384
- duration: Date.now() - startTime,
5385
- path: window.location.pathname
5386
- };
5387
-
5388
- InteractionManager.add('networkEvents', networkErrorData);
5389
- throw error;
5390
- });
5391
- };
5392
-
5393
5338
  // Track XMLHttpRequest errors - only intercept calls to our own backend
5394
5339
  const originalXHROpen = XMLHttpRequest.prototype.open;
5395
5340
  const originalXHRSend = XMLHttpRequest.prototype.send;
package/lib/esm/index.js CHANGED
@@ -4300,31 +4300,6 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
4300
4300
 
4301
4301
  };
4302
4302
 
4303
- // ============================================================================
4304
- // SECTION 13: API COMMUNICATION
4305
- // ============================================================================
4306
- // PURPOSE: Unified API client for all backend communication. Handles sending
4307
- // session data, custom events, and UTM events.
4308
- //
4309
- // KEY PRINCIPLES:
4310
- // 1. Unified API client for all endpoints
4311
- // 2. Transforms data using DataTransformer before sending
4312
- // 3. Handles retries and errors gracefully
4313
- // 4. Uses sendBeacon for beforeunload (last resort)
4314
- // 5. Uses fetch with keepalive for regular sends
4315
- // 6. Comprehensive error handling and logging
4316
- //
4317
- // BENEFITS:
4318
- // - Single place to handle all API communication
4319
- // - Consistent error handling
4320
- // - Retry logic for reliability
4321
- // - Proper use of sendBeacon vs fetch
4322
- // ============================================================================
4323
-
4324
- // Throttle network error logs (e.g. "Failed to fetch" from ad blockers) - log at most once per 30s
4325
- let _lastNetworkErrorLog = 0;
4326
- const _NETWORK_ERROR_THROTTLE_MS = 30000;
4327
-
4328
4303
  /**
4329
4304
  * APIClient - Unified API communication
4330
4305
  *
@@ -4500,17 +4475,24 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
4500
4475
  }
4501
4476
 
4502
4477
  // Handle AbortError gracefully (timeout or page unload)
4503
- if (error.name === 'AbortError' || error.message?.includes('aborted') || error.message?.includes('signal is aborted')) {
4478
+ if (
4479
+ error.name === 'AbortError' ||
4480
+ error.message?.includes('aborted') ||
4481
+ error.message?.includes('signal is aborted')
4482
+ ) {
4504
4483
  // Don't log as error - this is expected behavior for timeouts or page unloads
4505
4484
  // Don't retry aborted requests - they were intentionally cancelled
4506
4485
  return; // Silently return, don't throw
4507
4486
  }
4508
4487
 
4509
- // Throttle "Failed to fetch" logs (common with ad blockers, CORS, network issues)
4510
- const isNetworkError = error.name === 'TypeError' && (error.message === 'Failed to fetch' || error.message?.includes('fetch'));
4511
- const now = Date.now();
4512
- if (isNetworkError && (now - _lastNetworkErrorLog) < _NETWORK_ERROR_THROTTLE_MS) ; else {
4513
- if (isNetworkError) _lastNetworkErrorLog = now;
4488
+ // Treat common network issues (ad blockers, CORS, offline, etc.) as silent failures.
4489
+ // We still retry according to the "retries" option, but we do not log these to the console.
4490
+ const isNetworkError =
4491
+ error.name === 'TypeError' &&
4492
+ (error.message === 'Failed to fetch' || error.message?.includes('fetch'));
4493
+
4494
+ // Only log unexpected / non‑network errors
4495
+ if (!isNetworkError) {
4514
4496
  console.error('❌ Error sending data:', error);
4515
4497
  }
4516
4498
 
@@ -4520,7 +4502,11 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
4520
4502
  return this.send(endpoint, data, { ...options, retries: retries - 1 });
4521
4503
  }
4522
4504
 
4523
- throw error;
4505
+ // For non‑network errors that made it this far, surface to callers
4506
+ if (!isNetworkError) {
4507
+ throw error;
4508
+ }
4509
+ // For network errors, fail silently after retries are exhausted
4524
4510
  }
4525
4511
  },
4526
4512
 
@@ -5337,57 +5323,16 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
5337
5323
  },
5338
5324
 
5339
5325
  /**
5340
- * NetworkTracker - Tracks network errors (fetch and XMLHttpRequest)
5326
+ * NetworkTracker - Tracks network errors (XHR only)
5327
+ *
5328
+ * NOTE:
5329
+ * We intentionally do NOT wrap window.fetch here, to avoid confusing
5330
+ * browser DevTools attribution for third‑party requests. All SDK
5331
+ * fetch-based calls to backend.cryptique.io are already error-handled
5332
+ * inside APIClient.send(), so fetch wrapping is redundant.
5341
5333
  */
5342
5334
  startNetworkTracking() {
5343
5335
  try {
5344
- // Track fetch errors - only intercept calls to our own backend
5345
- // Use _nativeFetch as the base so the wrapper always delegates to the
5346
- // true browser fetch, regardless of what other libraries have patched.
5347
- window.fetch = function(...args) {
5348
- const startTime = Date.now();
5349
- const url = typeof args[0] === 'string' ? args[0] : (args[0]?.url || '');
5350
-
5351
- // Pass third-party requests through completely untouched — no interception,
5352
- // no involvement of our SDK in their call stack or error handling
5353
- if (!url.includes('backend.cryptique.io')) {
5354
- return _nativeFetch.apply(this, args);
5355
- }
5356
-
5357
- return _nativeFetch.apply(this, args).then(response => {
5358
- // Only track error status codes (4xx, 5xx)
5359
- if (response.status >= 400) {
5360
- const networkErrorData = {
5361
- type: 'api_error',
5362
- url: url,
5363
- method: 'GET',
5364
- status: response.status,
5365
- error: `HTTP ${response.status} Error`,
5366
- duration: Date.now() - startTime,
5367
- path: window.location.pathname
5368
- };
5369
-
5370
- InteractionManager.add('networkEvents', networkErrorData);
5371
- }
5372
-
5373
- return response;
5374
- }).catch(error => {
5375
- // Track actual network errors
5376
- const networkErrorData = {
5377
- type: 'api_error',
5378
- url: url,
5379
- method: 'GET',
5380
- status: 0,
5381
- error: error.message || 'Network Error',
5382
- duration: Date.now() - startTime,
5383
- path: window.location.pathname
5384
- };
5385
-
5386
- InteractionManager.add('networkEvents', networkErrorData);
5387
- throw error;
5388
- });
5389
- };
5390
-
5391
5336
  // Track XMLHttpRequest errors - only intercept calls to our own backend
5392
5337
  const originalXHROpen = XMLHttpRequest.prototype.open;
5393
5338
  const originalXHRSend = XMLHttpRequest.prototype.send;
package/lib/umd/index.js CHANGED
@@ -4306,31 +4306,6 @@
4306
4306
 
4307
4307
  };
4308
4308
 
4309
- // ============================================================================
4310
- // SECTION 13: API COMMUNICATION
4311
- // ============================================================================
4312
- // PURPOSE: Unified API client for all backend communication. Handles sending
4313
- // session data, custom events, and UTM events.
4314
- //
4315
- // KEY PRINCIPLES:
4316
- // 1. Unified API client for all endpoints
4317
- // 2. Transforms data using DataTransformer before sending
4318
- // 3. Handles retries and errors gracefully
4319
- // 4. Uses sendBeacon for beforeunload (last resort)
4320
- // 5. Uses fetch with keepalive for regular sends
4321
- // 6. Comprehensive error handling and logging
4322
- //
4323
- // BENEFITS:
4324
- // - Single place to handle all API communication
4325
- // - Consistent error handling
4326
- // - Retry logic for reliability
4327
- // - Proper use of sendBeacon vs fetch
4328
- // ============================================================================
4329
-
4330
- // Throttle network error logs (e.g. "Failed to fetch" from ad blockers) - log at most once per 30s
4331
- let _lastNetworkErrorLog = 0;
4332
- const _NETWORK_ERROR_THROTTLE_MS = 30000;
4333
-
4334
4309
  /**
4335
4310
  * APIClient - Unified API communication
4336
4311
  *
@@ -4506,17 +4481,24 @@
4506
4481
  }
4507
4482
 
4508
4483
  // Handle AbortError gracefully (timeout or page unload)
4509
- if (error.name === 'AbortError' || error.message?.includes('aborted') || error.message?.includes('signal is aborted')) {
4484
+ if (
4485
+ error.name === 'AbortError' ||
4486
+ error.message?.includes('aborted') ||
4487
+ error.message?.includes('signal is aborted')
4488
+ ) {
4510
4489
  // Don't log as error - this is expected behavior for timeouts or page unloads
4511
4490
  // Don't retry aborted requests - they were intentionally cancelled
4512
4491
  return; // Silently return, don't throw
4513
4492
  }
4514
4493
 
4515
- // Throttle "Failed to fetch" logs (common with ad blockers, CORS, network issues)
4516
- const isNetworkError = error.name === 'TypeError' && (error.message === 'Failed to fetch' || error.message?.includes('fetch'));
4517
- const now = Date.now();
4518
- if (isNetworkError && (now - _lastNetworkErrorLog) < _NETWORK_ERROR_THROTTLE_MS) ; else {
4519
- if (isNetworkError) _lastNetworkErrorLog = now;
4494
+ // Treat common network issues (ad blockers, CORS, offline, etc.) as silent failures.
4495
+ // We still retry according to the "retries" option, but we do not log these to the console.
4496
+ const isNetworkError =
4497
+ error.name === 'TypeError' &&
4498
+ (error.message === 'Failed to fetch' || error.message?.includes('fetch'));
4499
+
4500
+ // Only log unexpected / non‑network errors
4501
+ if (!isNetworkError) {
4520
4502
  console.error('❌ Error sending data:', error);
4521
4503
  }
4522
4504
 
@@ -4526,7 +4508,11 @@
4526
4508
  return this.send(endpoint, data, { ...options, retries: retries - 1 });
4527
4509
  }
4528
4510
 
4529
- throw error;
4511
+ // For non‑network errors that made it this far, surface to callers
4512
+ if (!isNetworkError) {
4513
+ throw error;
4514
+ }
4515
+ // For network errors, fail silently after retries are exhausted
4530
4516
  }
4531
4517
  },
4532
4518
 
@@ -5343,57 +5329,16 @@
5343
5329
  },
5344
5330
 
5345
5331
  /**
5346
- * NetworkTracker - Tracks network errors (fetch and XMLHttpRequest)
5332
+ * NetworkTracker - Tracks network errors (XHR only)
5333
+ *
5334
+ * NOTE:
5335
+ * We intentionally do NOT wrap window.fetch here, to avoid confusing
5336
+ * browser DevTools attribution for third‑party requests. All SDK
5337
+ * fetch-based calls to backend.cryptique.io are already error-handled
5338
+ * inside APIClient.send(), so fetch wrapping is redundant.
5347
5339
  */
5348
5340
  startNetworkTracking() {
5349
5341
  try {
5350
- // Track fetch errors - only intercept calls to our own backend
5351
- // Use _nativeFetch as the base so the wrapper always delegates to the
5352
- // true browser fetch, regardless of what other libraries have patched.
5353
- window.fetch = function(...args) {
5354
- const startTime = Date.now();
5355
- const url = typeof args[0] === 'string' ? args[0] : (args[0]?.url || '');
5356
-
5357
- // Pass third-party requests through completely untouched — no interception,
5358
- // no involvement of our SDK in their call stack or error handling
5359
- if (!url.includes('backend.cryptique.io')) {
5360
- return _nativeFetch.apply(this, args);
5361
- }
5362
-
5363
- return _nativeFetch.apply(this, args).then(response => {
5364
- // Only track error status codes (4xx, 5xx)
5365
- if (response.status >= 400) {
5366
- const networkErrorData = {
5367
- type: 'api_error',
5368
- url: url,
5369
- method: 'GET',
5370
- status: response.status,
5371
- error: `HTTP ${response.status} Error`,
5372
- duration: Date.now() - startTime,
5373
- path: window.location.pathname
5374
- };
5375
-
5376
- InteractionManager.add('networkEvents', networkErrorData);
5377
- }
5378
-
5379
- return response;
5380
- }).catch(error => {
5381
- // Track actual network errors
5382
- const networkErrorData = {
5383
- type: 'api_error',
5384
- url: url,
5385
- method: 'GET',
5386
- status: 0,
5387
- error: error.message || 'Network Error',
5388
- duration: Date.now() - startTime,
5389
- path: window.location.pathname
5390
- };
5391
-
5392
- InteractionManager.add('networkEvents', networkErrorData);
5393
- throw error;
5394
- });
5395
- };
5396
-
5397
5342
  // Track XMLHttpRequest errors - only intercept calls to our own backend
5398
5343
  const originalXHROpen = XMLHttpRequest.prototype.open;
5399
5344
  const originalXHRSend = XMLHttpRequest.prototype.send;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cryptique-sdk",
3
- "version": "1.2.4",
3
+ "version": "1.2.6",
4
4
  "type": "module",
5
5
  "description": "Cryptique Analytics SDK - Comprehensive web analytics and user tracking for modern web applications",
6
6
  "main": "lib/cjs/index.js",