@usereelay/browser 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.cjs +19 -10
- package/dist/index.js +19 -10
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -13817,14 +13817,17 @@ var pack = (event) => {
|
|
|
13817
13817
|
|
|
13818
13818
|
// src/replay.ts
|
|
13819
13819
|
var CHECKOUT_EVERY_MS = 3e4;
|
|
13820
|
-
var MAX_CHUNK_BYTES =
|
|
13820
|
+
var MAX_CHUNK_BYTES = 45e3;
|
|
13821
13821
|
var MAX_CLIPS_PER_PAGE = 5;
|
|
13822
13822
|
var MAX_EVENTS_PER_SEGMENT = 8e3;
|
|
13823
|
+
var RRWEB_EVENT_FULL_SNAPSHOT = 2;
|
|
13824
|
+
var RRWEB_EVENT_META = 4;
|
|
13823
13825
|
var ReplayRecorder = class {
|
|
13824
13826
|
constructor(opts) {
|
|
13825
13827
|
this.started = false;
|
|
13826
|
-
// Ring buffer of the last two checkout segments. Each
|
|
13827
|
-
//
|
|
13828
|
+
// Ring buffer of the last two complete checkout segments. Each replayable
|
|
13829
|
+
// segment begins with Meta followed by FullSnapshot, so the flattened buffer
|
|
13830
|
+
// can be handed directly to rrweb-player after unpacking.
|
|
13828
13831
|
this.segments = [[]];
|
|
13829
13832
|
this.seq = 0;
|
|
13830
13833
|
this.clips = 0;
|
|
@@ -13841,9 +13844,6 @@ var ReplayRecorder = class {
|
|
|
13841
13844
|
try {
|
|
13842
13845
|
this.stopFn = record({
|
|
13843
13846
|
emit: (event, isCheckout) => this.onEvent(event, isCheckout),
|
|
13844
|
-
// Pack each event at record time so the ring buffer and the wire stay
|
|
13845
|
-
// compact; the dashboard unpacks before playback.
|
|
13846
|
-
packFn: pack,
|
|
13847
13847
|
checkoutEveryNms: CHECKOUT_EVERY_MS,
|
|
13848
13848
|
// Fidelity: inline same-origin CSS + fonts so the replica renders
|
|
13849
13849
|
// without depending on the original site being reachable.
|
|
@@ -13874,7 +13874,7 @@ var ReplayRecorder = class {
|
|
|
13874
13874
|
}
|
|
13875
13875
|
onEvent(event, isCheckout) {
|
|
13876
13876
|
try {
|
|
13877
|
-
if (isCheckout || this.segments.length === 0) {
|
|
13877
|
+
if (isCheckout && event.type === RRWEB_EVENT_META || this.segments.length === 0) {
|
|
13878
13878
|
this.segments.push([]);
|
|
13879
13879
|
if (this.segments.length > 2) this.segments.shift();
|
|
13880
13880
|
}
|
|
@@ -13893,8 +13893,8 @@ var ReplayRecorder = class {
|
|
|
13893
13893
|
try {
|
|
13894
13894
|
if (!errorEventId || this.flushedErrors.has(errorEventId)) return;
|
|
13895
13895
|
if (this.clips >= MAX_CLIPS_PER_PAGE) return;
|
|
13896
|
-
const events = this.
|
|
13897
|
-
if (events.length
|
|
13896
|
+
const events = this.replayableEvents();
|
|
13897
|
+
if (events.length < 2) return;
|
|
13898
13898
|
this.flushedErrors.add(errorEventId);
|
|
13899
13899
|
this.clips += 1;
|
|
13900
13900
|
this.shipClip(errorEventId, events);
|
|
@@ -13905,9 +13905,13 @@ var ReplayRecorder = class {
|
|
|
13905
13905
|
/** Best-effort flush on page hide — no-op in error-buffered mode. */
|
|
13906
13906
|
flush() {
|
|
13907
13907
|
}
|
|
13908
|
+
replayableEvents() {
|
|
13909
|
+
const completeSegments = this.segments.filter((segment) => hasReplayHead(segment));
|
|
13910
|
+
return completeSegments.slice(-2).flat();
|
|
13911
|
+
}
|
|
13908
13912
|
shipClip(errorEventId, events) {
|
|
13909
13913
|
const clipSessionId = clipId(this.opts.sessionId, errorEventId);
|
|
13910
|
-
const json = JSON.stringify(events);
|
|
13914
|
+
const json = JSON.stringify(events.map((event) => pack(event)));
|
|
13911
13915
|
for (let offset = 0; offset < json.length; offset += MAX_CHUNK_BYTES) {
|
|
13912
13916
|
this.sendChunk(clipSessionId, errorEventId, json.slice(offset, offset + MAX_CHUNK_BYTES));
|
|
13913
13917
|
}
|
|
@@ -13940,6 +13944,11 @@ var ReplayRecorder = class {
|
|
|
13940
13944
|
function clipId(sessionId, errorEventId) {
|
|
13941
13945
|
return `${sessionId}~${errorEventId}`;
|
|
13942
13946
|
}
|
|
13947
|
+
function hasReplayHead(segment) {
|
|
13948
|
+
const metaIndex = segment.findIndex((event) => event.type === RRWEB_EVENT_META);
|
|
13949
|
+
if (metaIndex < 0) return false;
|
|
13950
|
+
return segment.slice(metaIndex + 1).some((event) => event.type === RRWEB_EVENT_FULL_SNAPSHOT);
|
|
13951
|
+
}
|
|
13943
13952
|
|
|
13944
13953
|
// src/client.ts
|
|
13945
13954
|
var BrowserClient = class extends BaseClient {
|
package/dist/index.js
CHANGED
|
@@ -13815,14 +13815,17 @@ var pack = (event) => {
|
|
|
13815
13815
|
|
|
13816
13816
|
// src/replay.ts
|
|
13817
13817
|
var CHECKOUT_EVERY_MS = 3e4;
|
|
13818
|
-
var MAX_CHUNK_BYTES =
|
|
13818
|
+
var MAX_CHUNK_BYTES = 45e3;
|
|
13819
13819
|
var MAX_CLIPS_PER_PAGE = 5;
|
|
13820
13820
|
var MAX_EVENTS_PER_SEGMENT = 8e3;
|
|
13821
|
+
var RRWEB_EVENT_FULL_SNAPSHOT = 2;
|
|
13822
|
+
var RRWEB_EVENT_META = 4;
|
|
13821
13823
|
var ReplayRecorder = class {
|
|
13822
13824
|
constructor(opts) {
|
|
13823
13825
|
this.started = false;
|
|
13824
|
-
// Ring buffer of the last two checkout segments. Each
|
|
13825
|
-
//
|
|
13826
|
+
// Ring buffer of the last two complete checkout segments. Each replayable
|
|
13827
|
+
// segment begins with Meta followed by FullSnapshot, so the flattened buffer
|
|
13828
|
+
// can be handed directly to rrweb-player after unpacking.
|
|
13826
13829
|
this.segments = [[]];
|
|
13827
13830
|
this.seq = 0;
|
|
13828
13831
|
this.clips = 0;
|
|
@@ -13839,9 +13842,6 @@ var ReplayRecorder = class {
|
|
|
13839
13842
|
try {
|
|
13840
13843
|
this.stopFn = record({
|
|
13841
13844
|
emit: (event, isCheckout) => this.onEvent(event, isCheckout),
|
|
13842
|
-
// Pack each event at record time so the ring buffer and the wire stay
|
|
13843
|
-
// compact; the dashboard unpacks before playback.
|
|
13844
|
-
packFn: pack,
|
|
13845
13845
|
checkoutEveryNms: CHECKOUT_EVERY_MS,
|
|
13846
13846
|
// Fidelity: inline same-origin CSS + fonts so the replica renders
|
|
13847
13847
|
// without depending on the original site being reachable.
|
|
@@ -13872,7 +13872,7 @@ var ReplayRecorder = class {
|
|
|
13872
13872
|
}
|
|
13873
13873
|
onEvent(event, isCheckout) {
|
|
13874
13874
|
try {
|
|
13875
|
-
if (isCheckout || this.segments.length === 0) {
|
|
13875
|
+
if (isCheckout && event.type === RRWEB_EVENT_META || this.segments.length === 0) {
|
|
13876
13876
|
this.segments.push([]);
|
|
13877
13877
|
if (this.segments.length > 2) this.segments.shift();
|
|
13878
13878
|
}
|
|
@@ -13891,8 +13891,8 @@ var ReplayRecorder = class {
|
|
|
13891
13891
|
try {
|
|
13892
13892
|
if (!errorEventId || this.flushedErrors.has(errorEventId)) return;
|
|
13893
13893
|
if (this.clips >= MAX_CLIPS_PER_PAGE) return;
|
|
13894
|
-
const events = this.
|
|
13895
|
-
if (events.length
|
|
13894
|
+
const events = this.replayableEvents();
|
|
13895
|
+
if (events.length < 2) return;
|
|
13896
13896
|
this.flushedErrors.add(errorEventId);
|
|
13897
13897
|
this.clips += 1;
|
|
13898
13898
|
this.shipClip(errorEventId, events);
|
|
@@ -13903,9 +13903,13 @@ var ReplayRecorder = class {
|
|
|
13903
13903
|
/** Best-effort flush on page hide — no-op in error-buffered mode. */
|
|
13904
13904
|
flush() {
|
|
13905
13905
|
}
|
|
13906
|
+
replayableEvents() {
|
|
13907
|
+
const completeSegments = this.segments.filter((segment) => hasReplayHead(segment));
|
|
13908
|
+
return completeSegments.slice(-2).flat();
|
|
13909
|
+
}
|
|
13906
13910
|
shipClip(errorEventId, events) {
|
|
13907
13911
|
const clipSessionId = clipId(this.opts.sessionId, errorEventId);
|
|
13908
|
-
const json = JSON.stringify(events);
|
|
13912
|
+
const json = JSON.stringify(events.map((event) => pack(event)));
|
|
13909
13913
|
for (let offset = 0; offset < json.length; offset += MAX_CHUNK_BYTES) {
|
|
13910
13914
|
this.sendChunk(clipSessionId, errorEventId, json.slice(offset, offset + MAX_CHUNK_BYTES));
|
|
13911
13915
|
}
|
|
@@ -13938,6 +13942,11 @@ var ReplayRecorder = class {
|
|
|
13938
13942
|
function clipId(sessionId, errorEventId) {
|
|
13939
13943
|
return `${sessionId}~${errorEventId}`;
|
|
13940
13944
|
}
|
|
13945
|
+
function hasReplayHead(segment) {
|
|
13946
|
+
const metaIndex = segment.findIndex((event) => event.type === RRWEB_EVENT_META);
|
|
13947
|
+
if (metaIndex < 0) return false;
|
|
13948
|
+
return segment.slice(metaIndex + 1).some((event) => event.type === RRWEB_EVENT_FULL_SNAPSHOT);
|
|
13949
|
+
}
|
|
13941
13950
|
|
|
13942
13951
|
// src/client.ts
|
|
13943
13952
|
var BrowserClient = class extends BaseClient {
|
package/package.json
CHANGED