@cedarai/session-replay-sdk 0.4.0 → 0.6.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.
- package/dist/index.d.ts +4 -0
- package/dist/index.js +128 -8
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
interface SDKConfig {
|
|
2
2
|
serverUrl: string;
|
|
3
3
|
cedarSessionId: string;
|
|
4
|
+
environment: string;
|
|
5
|
+
developer?: string;
|
|
4
6
|
batchIntervalMs?: number;
|
|
5
7
|
batchMaxSize?: number;
|
|
6
8
|
console?: ConsoleConfig;
|
|
@@ -23,6 +25,8 @@ interface RecorderConfig {
|
|
|
23
25
|
interface InitConfig {
|
|
24
26
|
serverUrl: string;
|
|
25
27
|
cedarSessionId: string;
|
|
28
|
+
environment: string;
|
|
29
|
+
developer?: string;
|
|
26
30
|
batchIntervalMs?: number;
|
|
27
31
|
batchMaxSize?: number;
|
|
28
32
|
console?: SDKConfig['console'];
|
package/dist/index.js
CHANGED
|
@@ -165,7 +165,11 @@ var Transport = class {
|
|
|
165
165
|
viewportWidth: typeof window !== "undefined" ? window.innerWidth : 0,
|
|
166
166
|
viewportHeight: typeof window !== "undefined" ? window.innerHeight : 0,
|
|
167
167
|
url: typeof window !== "undefined" ? window.location.href : "",
|
|
168
|
-
events
|
|
168
|
+
events,
|
|
169
|
+
metadata: {
|
|
170
|
+
environment: this.config.environment,
|
|
171
|
+
...this.config.developer ? { developer: this.config.developer } : {}
|
|
172
|
+
}
|
|
169
173
|
};
|
|
170
174
|
}
|
|
171
175
|
estimateQueueSize() {
|
|
@@ -299,10 +303,36 @@ var ErrorCapture = class {
|
|
|
299
303
|
// src/network.ts
|
|
300
304
|
var nextId = 0;
|
|
301
305
|
var RESPONSE_BODY_MAX_SIZE = 100 * 1024;
|
|
306
|
+
function extractHeaders(headers) {
|
|
307
|
+
if (!headers) return void 0;
|
|
308
|
+
const result = {};
|
|
309
|
+
if (headers instanceof Headers) {
|
|
310
|
+
headers.forEach((v, k) => {
|
|
311
|
+
result[k] = v;
|
|
312
|
+
});
|
|
313
|
+
} else if (Array.isArray(headers)) {
|
|
314
|
+
for (const [k, v] of headers) {
|
|
315
|
+
result[k] = v;
|
|
316
|
+
}
|
|
317
|
+
} else {
|
|
318
|
+
Object.assign(result, headers);
|
|
319
|
+
}
|
|
320
|
+
return Object.keys(result).length > 0 ? result : void 0;
|
|
321
|
+
}
|
|
322
|
+
function headersToRecord(headers) {
|
|
323
|
+
const result = {};
|
|
324
|
+
headers.forEach((v, k) => {
|
|
325
|
+
result[k] = v;
|
|
326
|
+
});
|
|
327
|
+
return Object.keys(result).length > 0 ? result : void 0;
|
|
328
|
+
}
|
|
302
329
|
var NetworkCapture = class {
|
|
303
330
|
onEvent;
|
|
304
331
|
serverUrl;
|
|
305
332
|
originalFetch = null;
|
|
333
|
+
originalXHROpen = null;
|
|
334
|
+
originalXHRSend = null;
|
|
335
|
+
originalXHRSetHeader = null;
|
|
306
336
|
started = false;
|
|
307
337
|
constructor(onEvent2, serverUrl) {
|
|
308
338
|
this.onEvent = onEvent2;
|
|
@@ -311,6 +341,31 @@ var NetworkCapture = class {
|
|
|
311
341
|
start() {
|
|
312
342
|
if (this.started) return;
|
|
313
343
|
this.started = true;
|
|
344
|
+
this.interceptFetch();
|
|
345
|
+
this.interceptXHR();
|
|
346
|
+
}
|
|
347
|
+
stop() {
|
|
348
|
+
if (!this.started) return;
|
|
349
|
+
this.started = false;
|
|
350
|
+
if (this.originalFetch) {
|
|
351
|
+
globalThis.fetch = this.originalFetch;
|
|
352
|
+
this.originalFetch = null;
|
|
353
|
+
}
|
|
354
|
+
if (this.originalXHROpen) {
|
|
355
|
+
XMLHttpRequest.prototype.open = this.originalXHROpen;
|
|
356
|
+
this.originalXHROpen = null;
|
|
357
|
+
}
|
|
358
|
+
if (this.originalXHRSend) {
|
|
359
|
+
XMLHttpRequest.prototype.send = this.originalXHRSend;
|
|
360
|
+
this.originalXHRSend = null;
|
|
361
|
+
}
|
|
362
|
+
if (this.originalXHRSetHeader) {
|
|
363
|
+
XMLHttpRequest.prototype.setRequestHeader = this.originalXHRSetHeader;
|
|
364
|
+
this.originalXHRSetHeader = null;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
// ── Fetch interception ────────────────────────────────────────
|
|
368
|
+
interceptFetch() {
|
|
314
369
|
this.originalFetch = globalThis.fetch;
|
|
315
370
|
globalThis.fetch = async (input, init) => {
|
|
316
371
|
const url = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
|
|
@@ -319,6 +374,7 @@ var NetworkCapture = class {
|
|
|
319
374
|
}
|
|
320
375
|
const method = init?.method?.toUpperCase() ?? "GET";
|
|
321
376
|
const requestBody = init?.body ? String(init.body) : void 0;
|
|
377
|
+
const requestHeaders = extractHeaders(init?.headers);
|
|
322
378
|
const startTime = performance.now();
|
|
323
379
|
const id = String(++nextId);
|
|
324
380
|
let graphqlOperationName;
|
|
@@ -354,8 +410,10 @@ var NetworkCapture = class {
|
|
|
354
410
|
method,
|
|
355
411
|
url,
|
|
356
412
|
graphqlOperationName,
|
|
413
|
+
requestHeaders,
|
|
357
414
|
requestBody,
|
|
358
415
|
status: response.status,
|
|
416
|
+
responseHeaders: headersToRecord(response.headers),
|
|
359
417
|
responseBody,
|
|
360
418
|
startTime,
|
|
361
419
|
endTime,
|
|
@@ -373,6 +431,7 @@ var NetworkCapture = class {
|
|
|
373
431
|
method,
|
|
374
432
|
url,
|
|
375
433
|
graphqlOperationName,
|
|
434
|
+
requestHeaders,
|
|
376
435
|
requestBody,
|
|
377
436
|
startTime,
|
|
378
437
|
endTime,
|
|
@@ -384,13 +443,72 @@ var NetworkCapture = class {
|
|
|
384
443
|
}
|
|
385
444
|
};
|
|
386
445
|
}
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
446
|
+
// ── XMLHttpRequest interception ───────────────────────────────
|
|
447
|
+
interceptXHR() {
|
|
448
|
+
const self = this;
|
|
449
|
+
const xhrData = /* @__PURE__ */ new WeakMap();
|
|
450
|
+
this.originalXHROpen = XMLHttpRequest.prototype.open;
|
|
451
|
+
this.originalXHRSend = XMLHttpRequest.prototype.send;
|
|
452
|
+
this.originalXHRSetHeader = XMLHttpRequest.prototype.setRequestHeader;
|
|
453
|
+
XMLHttpRequest.prototype.open = function(method, url, ...rest) {
|
|
454
|
+
const urlStr = typeof url === "string" ? url : url.href;
|
|
455
|
+
xhrData.set(this, { method: method.toUpperCase(), url: urlStr, headers: {}, startTime: 0 });
|
|
456
|
+
return self.originalXHROpen.apply(this, [method, url, ...rest]);
|
|
457
|
+
};
|
|
458
|
+
XMLHttpRequest.prototype.setRequestHeader = function(name, value) {
|
|
459
|
+
const data = xhrData.get(this);
|
|
460
|
+
if (data) data.headers[name] = value;
|
|
461
|
+
return self.originalXHRSetHeader.apply(this, [name, value]);
|
|
462
|
+
};
|
|
463
|
+
XMLHttpRequest.prototype.send = function(body) {
|
|
464
|
+
const data = xhrData.get(this);
|
|
465
|
+
if (data && data.url.startsWith(self.serverUrl)) {
|
|
466
|
+
return self.originalXHRSend.apply(this, [body]);
|
|
467
|
+
}
|
|
468
|
+
if (data) {
|
|
469
|
+
data.startTime = performance.now();
|
|
470
|
+
}
|
|
471
|
+
const requestBody = body != null ? String(body) : void 0;
|
|
472
|
+
this.addEventListener("loadend", function() {
|
|
473
|
+
if (!data) return;
|
|
474
|
+
const endTime = performance.now();
|
|
475
|
+
const rawHeaders = this.getAllResponseHeaders();
|
|
476
|
+
const responseHeaders = {};
|
|
477
|
+
if (rawHeaders) {
|
|
478
|
+
rawHeaders.trim().split(/[\r\n]+/).forEach((line) => {
|
|
479
|
+
const idx = line.indexOf(": ");
|
|
480
|
+
if (idx > 0) responseHeaders[line.substring(0, idx)] = line.substring(idx + 2);
|
|
481
|
+
});
|
|
482
|
+
}
|
|
483
|
+
let responseBody;
|
|
484
|
+
if (this.responseType === "" || this.responseType === "text") {
|
|
485
|
+
try {
|
|
486
|
+
const text = this.responseText;
|
|
487
|
+
if (text.length <= RESPONSE_BODY_MAX_SIZE) responseBody = text;
|
|
488
|
+
} catch {
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
self.onEvent({
|
|
492
|
+
type: "network",
|
|
493
|
+
timestamp: Date.now(),
|
|
494
|
+
data: {
|
|
495
|
+
id: String(++nextId),
|
|
496
|
+
method: data.method,
|
|
497
|
+
url: data.url,
|
|
498
|
+
requestHeaders: Object.keys(data.headers).length > 0 ? data.headers : void 0,
|
|
499
|
+
requestBody,
|
|
500
|
+
status: this.status,
|
|
501
|
+
responseHeaders: Object.keys(responseHeaders).length > 0 ? responseHeaders : void 0,
|
|
502
|
+
responseBody,
|
|
503
|
+
startTime: data.startTime,
|
|
504
|
+
endTime,
|
|
505
|
+
duration: endTime - data.startTime,
|
|
506
|
+
error: this.status === 0 ? "Network error" : void 0
|
|
507
|
+
}
|
|
508
|
+
});
|
|
509
|
+
});
|
|
510
|
+
return self.originalXHRSend.apply(this, [body]);
|
|
511
|
+
};
|
|
394
512
|
}
|
|
395
513
|
};
|
|
396
514
|
|
|
@@ -552,6 +670,8 @@ var CedarReplay = {
|
|
|
552
670
|
{
|
|
553
671
|
serverUrl: config.serverUrl,
|
|
554
672
|
cedarSessionId: config.cedarSessionId,
|
|
673
|
+
environment: config.environment,
|
|
674
|
+
developer: config.developer,
|
|
555
675
|
batchIntervalMs: config.batchIntervalMs,
|
|
556
676
|
batchMaxSize: config.batchMaxSize
|
|
557
677
|
},
|