@cedarai/session-replay-sdk 0.4.0 → 0.5.0

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 (2) hide show
  1. package/dist/index.js +121 -7
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -299,10 +299,36 @@ var ErrorCapture = class {
299
299
  // src/network.ts
300
300
  var nextId = 0;
301
301
  var RESPONSE_BODY_MAX_SIZE = 100 * 1024;
302
+ function extractHeaders(headers) {
303
+ if (!headers) return void 0;
304
+ const result = {};
305
+ if (headers instanceof Headers) {
306
+ headers.forEach((v, k) => {
307
+ result[k] = v;
308
+ });
309
+ } else if (Array.isArray(headers)) {
310
+ for (const [k, v] of headers) {
311
+ result[k] = v;
312
+ }
313
+ } else {
314
+ Object.assign(result, headers);
315
+ }
316
+ return Object.keys(result).length > 0 ? result : void 0;
317
+ }
318
+ function headersToRecord(headers) {
319
+ const result = {};
320
+ headers.forEach((v, k) => {
321
+ result[k] = v;
322
+ });
323
+ return Object.keys(result).length > 0 ? result : void 0;
324
+ }
302
325
  var NetworkCapture = class {
303
326
  onEvent;
304
327
  serverUrl;
305
328
  originalFetch = null;
329
+ originalXHROpen = null;
330
+ originalXHRSend = null;
331
+ originalXHRSetHeader = null;
306
332
  started = false;
307
333
  constructor(onEvent2, serverUrl) {
308
334
  this.onEvent = onEvent2;
@@ -311,6 +337,31 @@ var NetworkCapture = class {
311
337
  start() {
312
338
  if (this.started) return;
313
339
  this.started = true;
340
+ this.interceptFetch();
341
+ this.interceptXHR();
342
+ }
343
+ stop() {
344
+ if (!this.started) return;
345
+ this.started = false;
346
+ if (this.originalFetch) {
347
+ globalThis.fetch = this.originalFetch;
348
+ this.originalFetch = null;
349
+ }
350
+ if (this.originalXHROpen) {
351
+ XMLHttpRequest.prototype.open = this.originalXHROpen;
352
+ this.originalXHROpen = null;
353
+ }
354
+ if (this.originalXHRSend) {
355
+ XMLHttpRequest.prototype.send = this.originalXHRSend;
356
+ this.originalXHRSend = null;
357
+ }
358
+ if (this.originalXHRSetHeader) {
359
+ XMLHttpRequest.prototype.setRequestHeader = this.originalXHRSetHeader;
360
+ this.originalXHRSetHeader = null;
361
+ }
362
+ }
363
+ // ── Fetch interception ────────────────────────────────────────
364
+ interceptFetch() {
314
365
  this.originalFetch = globalThis.fetch;
315
366
  globalThis.fetch = async (input, init) => {
316
367
  const url = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
@@ -319,6 +370,7 @@ var NetworkCapture = class {
319
370
  }
320
371
  const method = init?.method?.toUpperCase() ?? "GET";
321
372
  const requestBody = init?.body ? String(init.body) : void 0;
373
+ const requestHeaders = extractHeaders(init?.headers);
322
374
  const startTime = performance.now();
323
375
  const id = String(++nextId);
324
376
  let graphqlOperationName;
@@ -354,8 +406,10 @@ var NetworkCapture = class {
354
406
  method,
355
407
  url,
356
408
  graphqlOperationName,
409
+ requestHeaders,
357
410
  requestBody,
358
411
  status: response.status,
412
+ responseHeaders: headersToRecord(response.headers),
359
413
  responseBody,
360
414
  startTime,
361
415
  endTime,
@@ -373,6 +427,7 @@ var NetworkCapture = class {
373
427
  method,
374
428
  url,
375
429
  graphqlOperationName,
430
+ requestHeaders,
376
431
  requestBody,
377
432
  startTime,
378
433
  endTime,
@@ -384,13 +439,72 @@ var NetworkCapture = class {
384
439
  }
385
440
  };
386
441
  }
387
- stop() {
388
- if (!this.started) return;
389
- this.started = false;
390
- if (this.originalFetch) {
391
- globalThis.fetch = this.originalFetch;
392
- this.originalFetch = null;
393
- }
442
+ // ── XMLHttpRequest interception ───────────────────────────────
443
+ interceptXHR() {
444
+ const self = this;
445
+ const xhrData = /* @__PURE__ */ new WeakMap();
446
+ this.originalXHROpen = XMLHttpRequest.prototype.open;
447
+ this.originalXHRSend = XMLHttpRequest.prototype.send;
448
+ this.originalXHRSetHeader = XMLHttpRequest.prototype.setRequestHeader;
449
+ XMLHttpRequest.prototype.open = function(method, url, ...rest) {
450
+ const urlStr = typeof url === "string" ? url : url.href;
451
+ xhrData.set(this, { method: method.toUpperCase(), url: urlStr, headers: {}, startTime: 0 });
452
+ return self.originalXHROpen.apply(this, [method, url, ...rest]);
453
+ };
454
+ XMLHttpRequest.prototype.setRequestHeader = function(name, value) {
455
+ const data = xhrData.get(this);
456
+ if (data) data.headers[name] = value;
457
+ return self.originalXHRSetHeader.apply(this, [name, value]);
458
+ };
459
+ XMLHttpRequest.prototype.send = function(body) {
460
+ const data = xhrData.get(this);
461
+ if (data && data.url.startsWith(self.serverUrl)) {
462
+ return self.originalXHRSend.apply(this, [body]);
463
+ }
464
+ if (data) {
465
+ data.startTime = performance.now();
466
+ }
467
+ const requestBody = body != null ? String(body) : void 0;
468
+ this.addEventListener("loadend", function() {
469
+ if (!data) return;
470
+ const endTime = performance.now();
471
+ const rawHeaders = this.getAllResponseHeaders();
472
+ const responseHeaders = {};
473
+ if (rawHeaders) {
474
+ rawHeaders.trim().split(/[\r\n]+/).forEach((line) => {
475
+ const idx = line.indexOf(": ");
476
+ if (idx > 0) responseHeaders[line.substring(0, idx)] = line.substring(idx + 2);
477
+ });
478
+ }
479
+ let responseBody;
480
+ if (this.responseType === "" || this.responseType === "text") {
481
+ try {
482
+ const text = this.responseText;
483
+ if (text.length <= RESPONSE_BODY_MAX_SIZE) responseBody = text;
484
+ } catch {
485
+ }
486
+ }
487
+ self.onEvent({
488
+ type: "network",
489
+ timestamp: Date.now(),
490
+ data: {
491
+ id: String(++nextId),
492
+ method: data.method,
493
+ url: data.url,
494
+ requestHeaders: Object.keys(data.headers).length > 0 ? data.headers : void 0,
495
+ requestBody,
496
+ status: this.status,
497
+ responseHeaders: Object.keys(responseHeaders).length > 0 ? responseHeaders : void 0,
498
+ responseBody,
499
+ startTime: data.startTime,
500
+ endTime,
501
+ duration: endTime - data.startTime,
502
+ error: this.status === 0 ? "Network error" : void 0
503
+ }
504
+ });
505
+ });
506
+ return self.originalXHRSend.apply(this, [body]);
507
+ };
394
508
  }
395
509
  };
396
510
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cedarai/session-replay-sdk",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",