@monoscopetech/browser 0.5.8 → 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/replay.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import { getRecordConsolePlugin } from "@rrweb/rrweb-plugin-console-record";
2
2
  import * as rrweb from "rrweb";
3
3
  const MAX_EVENT_BATCH = 50;
4
- const SAVE_INTERVAL = 10000;
5
- const MAX_RETRY_EVENTS = 1000;
4
+ const SAVE_INTERVAL = 2000;
5
+ const MAX_RETRY_EVENTS = 5000;
6
6
  export class MonoscopeReplay {
7
7
  constructor(config, sessionId) {
8
8
  this.events = [];
@@ -106,13 +106,20 @@ export class MonoscopeReplay {
106
106
  return;
107
107
  }
108
108
  if (this.events.length > MAX_RETRY_EVENTS) {
109
- console.warn(`Event queue exceeded ${MAX_RETRY_EVENTS}, dropping oldest events`);
110
- this.events = this.events.slice(-MAX_RETRY_EVENTS);
109
+ console.warn(`Event queue exceeded ${MAX_RETRY_EVENTS}, dropping middle events (preserving snapshots)`);
110
+ // Find full snapshot events (type 2) - these are critical for replay
111
+ const fullSnapshots = this.events.filter((e) => e.type === 2);
112
+ const otherEvents = this.events.filter((e) => e.type !== 2);
113
+ // Keep all snapshots and the most recent other events
114
+ const remainingSlots = MAX_RETRY_EVENTS - fullSnapshots.length;
115
+ this.events = [...fullSnapshots, ...otherEvents.slice(-remainingSlots)];
116
+ // Re-sort by timestamp to maintain order
117
+ this.events.sort((a, b) => a.timestamp - b.timestamp);
111
118
  }
112
119
  this.isSaving = true;
113
120
  const { replayEventsBaseUrl, projectId } = this.config;
114
121
  // Construct base URL
115
- let baseUrl = replayEventsBaseUrl || "https://app.apitoolkit.io";
122
+ let baseUrl = replayEventsBaseUrl || "https://app.monoscope.tech";
116
123
  baseUrl = `${baseUrl}/rrweb/${projectId}`;
117
124
  // Get events to send and clear buffer
118
125
  const eventsToSend = [...this.events];
@@ -134,27 +141,33 @@ export class MonoscopeReplay {
134
141
  }
135
142
  }
136
143
  else {
137
- // Regular fetch with keepalive
144
+ // Use keepalive so the request survives page navigation,
145
+ // but only when payload fits under the 64KB keepalive limit
146
+ const body = JSON.stringify(payload);
138
147
  const response = await fetch(baseUrl, {
139
148
  method: "POST",
140
149
  headers: {
141
150
  "Content-Type": "application/json",
142
151
  },
143
- body: JSON.stringify(payload),
152
+ body,
153
+ keepalive: body.length < 63000,
144
154
  });
145
155
  if (!response.ok) {
146
- console.log(response);
147
156
  throw new Error(`Failed to save replay events: ${response.status} ${response.statusText}`);
148
157
  }
149
158
  console.log(`Successfully saved ${eventsToSend.length} replay events`);
150
159
  }
151
160
  }
152
161
  catch (error) {
153
- console.log(error);
154
162
  console.error("Failed to save replay events:", error);
155
163
  this.events = [...eventsToSend, ...this.events];
156
164
  if (this.events.length > MAX_RETRY_EVENTS) {
157
- this.events = this.events.slice(-MAX_RETRY_EVENTS);
165
+ // Preserve full snapshots when trimming
166
+ const fullSnapshots = this.events.filter((e) => e.type === 2);
167
+ const otherEvents = this.events.filter((e) => e.type !== 2);
168
+ const remainingSlots = MAX_RETRY_EVENTS - fullSnapshots.length;
169
+ this.events = [...fullSnapshots, ...otherEvents.slice(-remainingSlots)];
170
+ this.events.sort((a, b) => a.timestamp - b.timestamp);
158
171
  }
159
172
  }
160
173
  finally {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@monoscopetech/browser",
3
- "version": "0.5.8",
3
+ "version": "0.6.0",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "type": "module",