@usereelay/browser 0.1.1 → 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 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 = 6e4;
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 segment begins with a
13827
- // full snapshot, so segments.flat() is always replayable from its head.
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.segments.flat();
13897
- if (events.length === 0) return;
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 = 6e4;
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 segment begins with a
13825
- // full snapshot, so segments.flat() is always replayable from its head.
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.segments.flat();
13895
- if (events.length === 0) return;
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@usereelay/browser",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "Reelay SDK for browsers: error capture, breadcrumbs, fetch trace stitching, masked DOM session replay.",
5
5
  "license": "MIT",
6
6
  "publishConfig": {