Socket
Socket
Sign inDemoInstall

@sentry/replay

Package Overview
Dependencies
Maintainers
12
Versions
230
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@sentry/replay - npm Package Compare versions

Comparing version 0.2.0-6 to 0.2.0-7

109

dist/index.es.js

@@ -348,2 +348,3 @@ import * as Sentry from '@sentry/browser';

logger.log('Document has become active, but session has expired');
_this.loadSession({ expiry: VISIBILITY_CHANGE_TIMEOUT });
_this.triggerFullSnapshot();

@@ -378,4 +379,6 @@ }

SentryReplay.attachmentUrlFromDsn = function (dsn, eventId) {
var host = dsn.host, path = dsn.path, projectId = dsn.projectId, port = dsn.port, protocol = dsn.protocol, user = dsn.user;
return "".concat(protocol, "://").concat(host).concat(port !== '' ? ":".concat(port) : '').concat(path !== '' ? "/".concat(path) : '', "/api/").concat(projectId, "/events/").concat(eventId, "/attachments/?sentry_key=").concat(user, "&sentry_version=7&sentry_client=replay");
var host = dsn.host, projectId = dsn.projectId, protocol = dsn.protocol, user = dsn.user;
var port = dsn.port !== '' ? ":".concat(dsn.port) : '';
var path = dsn.path !== '' ? "/".concat(dsn.path) : '';
return "".concat(protocol, "://").concat(host).concat(port).concat(path, "/api/").concat(projectId, "/events/").concat(eventId, "/attachments/?sentry_key=").concat(user, "&sentry_version=7&sentry_client=replay");
};

@@ -421,9 +424,11 @@ SentryReplay.prototype.setupOnce = function () {

}
var uploadMaxDelayExceeded = isExpired(_this.initialEventTimestampSinceFlush, _this.options.uploadMaxDelay, now);
// Do not finish the replay event if we receive a new replay event
// unless `<uploadMaxDelay>` ms have elapsed since the last time we
// finished the replay
if (_this.timeout && !uploadMaxDelayExceeded) {
if (_this.timeout) {
window.clearTimeout(_this.timeout);
}
// If this is false, it means session is expired, create and a new session and wait for checkout
if (!_this.checkAndHandleExpiredSession()) {
logger.error(new Error('Received replay event after session expired.'));
return;
}
// We need to clear existing events on a checkout, otherwise they are

@@ -441,8 +446,15 @@ // incremental event updates and should be appended

// A fullsnapshot happens on initial load and if we need to start a
// new replay due to idle timeout. In the later case we will need to
// create a new session before finishing the replay.
_this.loadSession({ expiry: SESSION_IDLE_DURATION });
// new replay due to idle timeout. In the latter case, a new session *should* have been started
// before triggering a new checkout
_this.finishReplayEvent();
return;
}
var uploadMaxDelayExceeded = isExpired(_this.initialEventTimestampSinceFlush, _this.options.uploadMaxDelay, now);
// If `uploadMaxDelayExceeded` is true, then we should finish the replay event immediately,
// Otherwise schedule it to be finished in `this.options.uploadMinDelay`
if (uploadMaxDelayExceeded) {
logger.log('replay max delay exceeded, finishing replay event');
_this.finishReplayEvent();
return;
}
// Set timer to finish replay event and send replay attachment to

@@ -452,3 +464,3 @@ // Sentry. Will be cancelled if an event happens before `uploadMinDelay`

_this.timeout = window.setTimeout(function () {
logger.log('rrweb timeout hit, finishing replay event');
logger.log('replay timeout exceeded, finishing replay event');
_this.finishReplayEvent();

@@ -458,3 +470,2 @@ }, _this.options.uploadMinDelay);

this.addListeners();
// XXX: this needs to be in `setupOnce` vs `constructor`, otherwise SDK is
// not fully initialized and the event will not get properly sent to Sentry

@@ -464,2 +475,8 @@ this.createReplayEvent();

/**
* Currently, this needs to be manually called (e.g. for tests). Sentry SDK does not support a teardown
*/
SentryReplay.prototype.teardown = function () {
this.removeListeners();
};
/**
* Loads a session from storage, or creates a new one

@@ -475,9 +492,31 @@ */

SentryReplay.prototype.addListeners = function () {
var _this = this;
document.addEventListener('visibilitychange', this.handleVisibilityChange);
if ('PerformanceObserver' in window) {
this.performanceObserver = new PerformanceObserver(this.handlePerformanceObserver);
// Observe everything for now
this.performanceObserver.observe({
entryTypes: __spreadArray([], PerformanceObserver.supportedEntryTypes, true),
if (!('PerformanceObserver' in window)) {
return;
}
this.performanceObserver = new PerformanceObserver(this.handlePerformanceObserver);
// Observe almost everything for now (no mark/measure)
[
'element',
'event',
'first-input',
'largest-contentful-paint',
'layout-shift',
'longtask',
'navigation',
'paint',
'resource',
].forEach(function (type) {
return _this.performanceObserver.observe({
type: type,
buffered: true,
});
});
};
SentryReplay.prototype.removeListeners = function () {
document.removeEventListener('visibilitychange', this.handleVisibilityChange);
if (this.performanceObserver) {
this.performanceObserver.disconnect();
this.performanceObserver = null;
}

@@ -501,3 +540,3 @@ };

logger.log('CreateReplayEvent rootReplayId', this.session.id);
this.replayEvent = Sentry.startTransaction({
this.replayEvent = Sentry.getCurrentHub().startTransaction({
name: REPLAY_EVENT_NAME,

@@ -543,11 +582,29 @@ parentSpanId: this.session.spanId,

};
/**
*
*
* Returns true if session is not expired, false otherwise.
*/
SentryReplay.prototype.checkAndHandleExpiredSession = function (expiry) {
if (expiry === void 0) { expiry = SESSION_IDLE_DURATION; }
var oldSessionId = this.session.id;
// This will create a new session if expired, based on expiry length
this.loadSession({ expiry: expiry });
// Session was expired if session ids do not match
var isExpired = oldSessionId !== this.session.id;
if (!isExpired) {
return true;
}
// TODO: We could potentially figure out a way to save the last session,
// and produce a checkout based on a previous checkout + updates, and then
// replay the event on top. Or maybe replay the event on top of a refresh
// snapshot.
// For now create a new snapshot
this.triggerFullSnapshot();
return false;
};
SentryReplay.prototype.finishReplayEvent = function () {
var _a;
// Ensure that our existing session has not expired
var isExpired = isSessionExpired(this.session, SESSION_IDLE_DURATION);
if (isExpired) {
// TBD: If it is expired, we do not send any events...we could send to
// the expired session, but not sure if that's great
console.error(new Error('Attempting to finish replay event after session expired.'));
return;
if (!this.checkAndHandleExpiredSession()) {
logger.error(new Error('Attempting to finish replay event after session expired.'));
}

@@ -621,7 +678,7 @@ if (!this.session.id) {

this.events = [];
client = Sentry.getCurrentHub().getClient();
endpoint = SentryReplay.attachmentUrlFromDsn(client.getDsn(), eventId);
_a.label = 1;
case 1:
_a.trys.push([1, 3, , 4]);
client = Sentry.getCurrentHub().getClient();
endpoint = SentryReplay.attachmentUrlFromDsn(client.getDsn(), eventId);
return [4 /*yield*/, this.sendReplayRequest(endpoint, events)];

@@ -628,0 +685,0 @@ case 2:

@@ -372,2 +372,3 @@ 'use strict';

logger.log('Document has become active, but session has expired');
_this.loadSession({ expiry: VISIBILITY_CHANGE_TIMEOUT });
_this.triggerFullSnapshot();

@@ -402,4 +403,6 @@ }

SentryReplay.attachmentUrlFromDsn = function (dsn, eventId) {
var host = dsn.host, path = dsn.path, projectId = dsn.projectId, port = dsn.port, protocol = dsn.protocol, user = dsn.user;
return "".concat(protocol, "://").concat(host).concat(port !== '' ? ":".concat(port) : '').concat(path !== '' ? "/".concat(path) : '', "/api/").concat(projectId, "/events/").concat(eventId, "/attachments/?sentry_key=").concat(user, "&sentry_version=7&sentry_client=replay");
var host = dsn.host, projectId = dsn.projectId, protocol = dsn.protocol, user = dsn.user;
var port = dsn.port !== '' ? ":".concat(dsn.port) : '';
var path = dsn.path !== '' ? "/".concat(dsn.path) : '';
return "".concat(protocol, "://").concat(host).concat(port).concat(path, "/api/").concat(projectId, "/events/").concat(eventId, "/attachments/?sentry_key=").concat(user, "&sentry_version=7&sentry_client=replay");
};

@@ -445,9 +448,11 @@ SentryReplay.prototype.setupOnce = function () {

}
var uploadMaxDelayExceeded = isExpired(_this.initialEventTimestampSinceFlush, _this.options.uploadMaxDelay, now);
// Do not finish the replay event if we receive a new replay event
// unless `<uploadMaxDelay>` ms have elapsed since the last time we
// finished the replay
if (_this.timeout && !uploadMaxDelayExceeded) {
if (_this.timeout) {
window.clearTimeout(_this.timeout);
}
// If this is false, it means session is expired, create and a new session and wait for checkout
if (!_this.checkAndHandleExpiredSession()) {
logger.error(new Error('Received replay event after session expired.'));
return;
}
// We need to clear existing events on a checkout, otherwise they are

@@ -465,8 +470,15 @@ // incremental event updates and should be appended

// A fullsnapshot happens on initial load and if we need to start a
// new replay due to idle timeout. In the later case we will need to
// create a new session before finishing the replay.
_this.loadSession({ expiry: SESSION_IDLE_DURATION });
// new replay due to idle timeout. In the latter case, a new session *should* have been started
// before triggering a new checkout
_this.finishReplayEvent();
return;
}
var uploadMaxDelayExceeded = isExpired(_this.initialEventTimestampSinceFlush, _this.options.uploadMaxDelay, now);
// If `uploadMaxDelayExceeded` is true, then we should finish the replay event immediately,
// Otherwise schedule it to be finished in `this.options.uploadMinDelay`
if (uploadMaxDelayExceeded) {
logger.log('replay max delay exceeded, finishing replay event');
_this.finishReplayEvent();
return;
}
// Set timer to finish replay event and send replay attachment to

@@ -476,3 +488,3 @@ // Sentry. Will be cancelled if an event happens before `uploadMinDelay`

_this.timeout = window.setTimeout(function () {
logger.log('rrweb timeout hit, finishing replay event');
logger.log('replay timeout exceeded, finishing replay event');
_this.finishReplayEvent();

@@ -482,3 +494,2 @@ }, _this.options.uploadMinDelay);

this.addListeners();
// XXX: this needs to be in `setupOnce` vs `constructor`, otherwise SDK is
// not fully initialized and the event will not get properly sent to Sentry

@@ -488,2 +499,8 @@ this.createReplayEvent();

/**
* Currently, this needs to be manually called (e.g. for tests). Sentry SDK does not support a teardown
*/
SentryReplay.prototype.teardown = function () {
this.removeListeners();
};
/**
* Loads a session from storage, or creates a new one

@@ -499,9 +516,31 @@ */

SentryReplay.prototype.addListeners = function () {
var _this = this;
document.addEventListener('visibilitychange', this.handleVisibilityChange);
if ('PerformanceObserver' in window) {
this.performanceObserver = new PerformanceObserver(this.handlePerformanceObserver);
// Observe everything for now
this.performanceObserver.observe({
entryTypes: __spreadArray([], PerformanceObserver.supportedEntryTypes, true),
if (!('PerformanceObserver' in window)) {
return;
}
this.performanceObserver = new PerformanceObserver(this.handlePerformanceObserver);
// Observe almost everything for now (no mark/measure)
[
'element',
'event',
'first-input',
'largest-contentful-paint',
'layout-shift',
'longtask',
'navigation',
'paint',
'resource',
].forEach(function (type) {
return _this.performanceObserver.observe({
type: type,
buffered: true,
});
});
};
SentryReplay.prototype.removeListeners = function () {
document.removeEventListener('visibilitychange', this.handleVisibilityChange);
if (this.performanceObserver) {
this.performanceObserver.disconnect();
this.performanceObserver = null;
}

@@ -525,3 +564,3 @@ };

logger.log('CreateReplayEvent rootReplayId', this.session.id);
this.replayEvent = Sentry__namespace.startTransaction({
this.replayEvent = Sentry__namespace.getCurrentHub().startTransaction({
name: REPLAY_EVENT_NAME,

@@ -567,11 +606,29 @@ parentSpanId: this.session.spanId,

};
/**
*
*
* Returns true if session is not expired, false otherwise.
*/
SentryReplay.prototype.checkAndHandleExpiredSession = function (expiry) {
if (expiry === void 0) { expiry = SESSION_IDLE_DURATION; }
var oldSessionId = this.session.id;
// This will create a new session if expired, based on expiry length
this.loadSession({ expiry: expiry });
// Session was expired if session ids do not match
var isExpired = oldSessionId !== this.session.id;
if (!isExpired) {
return true;
}
// TODO: We could potentially figure out a way to save the last session,
// and produce a checkout based on a previous checkout + updates, and then
// replay the event on top. Or maybe replay the event on top of a refresh
// snapshot.
// For now create a new snapshot
this.triggerFullSnapshot();
return false;
};
SentryReplay.prototype.finishReplayEvent = function () {
var _a;
// Ensure that our existing session has not expired
var isExpired = isSessionExpired(this.session, SESSION_IDLE_DURATION);
if (isExpired) {
// TBD: If it is expired, we do not send any events...we could send to
// the expired session, but not sure if that's great
console.error(new Error('Attempting to finish replay event after session expired.'));
return;
if (!this.checkAndHandleExpiredSession()) {
logger.error(new Error('Attempting to finish replay event after session expired.'));
}

@@ -645,7 +702,7 @@ if (!this.session.id) {

this.events = [];
client = Sentry__namespace.getCurrentHub().getClient();
endpoint = SentryReplay.attachmentUrlFromDsn(client.getDsn(), eventId);
_a.label = 1;
case 1:
_a.trys.push([1, 3, , 4]);
client = Sentry__namespace.getCurrentHub().getClient();
endpoint = SentryReplay.attachmentUrlFromDsn(client.getDsn(), eventId);
return [4 /*yield*/, this.sendReplayRequest(endpoint, events)];

@@ -652,0 +709,0 @@ case 2:

{
"name": "@sentry/replay",
"version": "0.2.0-6",
"version": "0.2.0-7",
"description": "User replays for Sentry",

@@ -5,0 +5,0 @@ "main": "dist/index.js",

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc