@neroom/nevision 0.1.7 → 0.1.8

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.js CHANGED
@@ -37,7 +37,7 @@ __export(index_exports, {
37
37
  module.exports = __toCommonJS(index_exports);
38
38
  var import_react = require("react");
39
39
  var DEFAULT_API_URL = "https://api.ne-room.io";
40
- var CHUNK_INTERVAL = 1e4;
40
+ var CHUNK_INTERVAL = 2e3;
41
41
  var MAX_EVENTS_PER_CHUNK = 100;
42
42
  var DB_NAME = "nevision_recordings";
43
43
  var STORE_NAME = "pending_events";
@@ -173,7 +173,6 @@ function NevisionRecorder({
173
173
  const recordConfig = {
174
174
  emit: (event) => {
175
175
  eventsBufferRef.current.push(event);
176
- persistEventsToStorage();
177
176
  },
178
177
  sampling: currentSampling ? {
179
178
  mousemove: currentSampling.mousemove,
@@ -211,44 +210,30 @@ function NevisionRecorder({
211
210
  endSession(apiUrl, sessionIdRef.current);
212
211
  }
213
212
  };
214
- document.addEventListener("visibilitychange", () => {
213
+ const handleVisibilityChange = () => {
215
214
  if (document.visibilityState === "hidden") {
216
215
  handleFinalSync(false);
217
216
  }
218
- });
219
- window.addEventListener("beforeunload", () => {
217
+ };
218
+ const handleBeforeUnload = () => {
220
219
  handleFinalSync(true);
221
- });
222
- window.addEventListener("pagehide", (e) => {
220
+ };
221
+ const handlePageHide = (e) => {
223
222
  handleFinalSync(!e.persisted);
224
- });
223
+ };
224
+ const handleWindowBlur = () => {
225
+ if (eventsBufferRef.current.length > 0 && sessionIdRef.current) {
226
+ sendChunk(apiUrl, sessionIdRef.current, true);
227
+ }
228
+ };
229
+ document.addEventListener("visibilitychange", handleVisibilityChange);
230
+ window.addEventListener("beforeunload", handleBeforeUnload);
231
+ window.addEventListener("pagehide", handlePageHide);
232
+ window.addEventListener("blur", handleWindowBlur);
225
233
  } catch (error) {
226
234
  onErrorRef.current?.(error instanceof Error ? error : new Error(String(error)));
227
235
  }
228
236
  };
229
- let persistTimeout = null;
230
- const persistEventsToStorage = () => {
231
- if (persistTimeout) return;
232
- persistTimeout = setTimeout(async () => {
233
- persistTimeout = null;
234
- if (!sessionIdRef.current || !eventStoreRef.current) return;
235
- if (eventsBufferRef.current.length === 0) return;
236
- const events = [...eventsBufferRef.current];
237
- const chunkId = `${sessionIdRef.current}_${Date.now()}_${Math.random().toString(36).slice(2)}`;
238
- try {
239
- await eventStoreRef.current.saveChunk({
240
- id: chunkId,
241
- sessionId: sessionIdRef.current,
242
- siteId,
243
- apiKey,
244
- events,
245
- chunkIndex: chunkIndexRef.current,
246
- timestamp: Date.now()
247
- });
248
- } catch {
249
- }
250
- }, 1e3);
251
- };
252
237
  const retrySendPendingChunks = async (url) => {
253
238
  if (!eventStoreRef.current) return;
254
239
  try {
@@ -277,23 +262,8 @@ function NevisionRecorder({
277
262
  };
278
263
  const sendChunk = async (url, sessionId, isBeacon = false) => {
279
264
  if (eventsBufferRef.current.length === 0) return;
280
- const events = eventsBufferRef.current.splice(0, MAX_EVENTS_PER_CHUNK);
265
+ const events = isBeacon ? eventsBufferRef.current.splice(0) : eventsBufferRef.current.splice(0, MAX_EVENTS_PER_CHUNK);
281
266
  const chunkIndex = chunkIndexRef.current++;
282
- const chunkId = `${sessionId}_${chunkIndex}_${Date.now()}`;
283
- if (eventStoreRef.current) {
284
- try {
285
- await eventStoreRef.current.saveChunk({
286
- id: chunkId,
287
- sessionId,
288
- siteId,
289
- apiKey,
290
- events,
291
- chunkIndex,
292
- timestamp: Date.now()
293
- });
294
- } catch {
295
- }
296
- }
297
267
  const payload = JSON.stringify({
298
268
  sessionId,
299
269
  siteId,
@@ -302,15 +272,26 @@ function NevisionRecorder({
302
272
  chunkIndex
303
273
  });
304
274
  if (isBeacon && navigator.sendBeacon) {
305
- const sent = navigator.sendBeacon(
275
+ navigator.sendBeacon(
306
276
  `${url}/public/recordings/chunk`,
307
277
  new Blob([payload], { type: "application/json" })
308
278
  );
309
- if (sent && eventStoreRef.current) {
310
- eventStoreRef.current.deleteChunk(chunkId).catch(() => {
311
- });
312
- }
313
279
  } else {
280
+ const chunkId = `${sessionId}_${chunkIndex}_${Date.now()}`;
281
+ if (eventStoreRef.current) {
282
+ try {
283
+ await eventStoreRef.current.saveChunk({
284
+ id: chunkId,
285
+ sessionId,
286
+ siteId,
287
+ apiKey,
288
+ events,
289
+ chunkIndex,
290
+ timestamp: Date.now()
291
+ });
292
+ } catch {
293
+ }
294
+ }
314
295
  try {
315
296
  const response = await fetch(`${url}/public/recordings/chunk`, {
316
297
  method: "POST",
@@ -339,10 +320,6 @@ function NevisionRecorder({
339
320
  isActive = false;
340
321
  clearInterval(intervalId);
341
322
  stopFnRef.current?.();
342
- if (sessionIdRef.current) {
343
- sendChunk(apiUrl, sessionIdRef.current, true);
344
- endSession(apiUrl, sessionIdRef.current);
345
- }
346
323
  sessionIdRef.current = null;
347
324
  chunkIndexRef.current = 0;
348
325
  eventsBufferRef.current = [];
package/dist/index.mjs CHANGED
@@ -3,7 +3,7 @@
3
3
  // src/index.tsx
4
4
  import { useEffect, useRef } from "react";
5
5
  var DEFAULT_API_URL = "https://api.ne-room.io";
6
- var CHUNK_INTERVAL = 1e4;
6
+ var CHUNK_INTERVAL = 2e3;
7
7
  var MAX_EVENTS_PER_CHUNK = 100;
8
8
  var DB_NAME = "nevision_recordings";
9
9
  var STORE_NAME = "pending_events";
@@ -139,7 +139,6 @@ function NevisionRecorder({
139
139
  const recordConfig = {
140
140
  emit: (event) => {
141
141
  eventsBufferRef.current.push(event);
142
- persistEventsToStorage();
143
142
  },
144
143
  sampling: currentSampling ? {
145
144
  mousemove: currentSampling.mousemove,
@@ -177,44 +176,30 @@ function NevisionRecorder({
177
176
  endSession(apiUrl, sessionIdRef.current);
178
177
  }
179
178
  };
180
- document.addEventListener("visibilitychange", () => {
179
+ const handleVisibilityChange = () => {
181
180
  if (document.visibilityState === "hidden") {
182
181
  handleFinalSync(false);
183
182
  }
184
- });
185
- window.addEventListener("beforeunload", () => {
183
+ };
184
+ const handleBeforeUnload = () => {
186
185
  handleFinalSync(true);
187
- });
188
- window.addEventListener("pagehide", (e) => {
186
+ };
187
+ const handlePageHide = (e) => {
189
188
  handleFinalSync(!e.persisted);
190
- });
189
+ };
190
+ const handleWindowBlur = () => {
191
+ if (eventsBufferRef.current.length > 0 && sessionIdRef.current) {
192
+ sendChunk(apiUrl, sessionIdRef.current, true);
193
+ }
194
+ };
195
+ document.addEventListener("visibilitychange", handleVisibilityChange);
196
+ window.addEventListener("beforeunload", handleBeforeUnload);
197
+ window.addEventListener("pagehide", handlePageHide);
198
+ window.addEventListener("blur", handleWindowBlur);
191
199
  } catch (error) {
192
200
  onErrorRef.current?.(error instanceof Error ? error : new Error(String(error)));
193
201
  }
194
202
  };
195
- let persistTimeout = null;
196
- const persistEventsToStorage = () => {
197
- if (persistTimeout) return;
198
- persistTimeout = setTimeout(async () => {
199
- persistTimeout = null;
200
- if (!sessionIdRef.current || !eventStoreRef.current) return;
201
- if (eventsBufferRef.current.length === 0) return;
202
- const events = [...eventsBufferRef.current];
203
- const chunkId = `${sessionIdRef.current}_${Date.now()}_${Math.random().toString(36).slice(2)}`;
204
- try {
205
- await eventStoreRef.current.saveChunk({
206
- id: chunkId,
207
- sessionId: sessionIdRef.current,
208
- siteId,
209
- apiKey,
210
- events,
211
- chunkIndex: chunkIndexRef.current,
212
- timestamp: Date.now()
213
- });
214
- } catch {
215
- }
216
- }, 1e3);
217
- };
218
203
  const retrySendPendingChunks = async (url) => {
219
204
  if (!eventStoreRef.current) return;
220
205
  try {
@@ -243,23 +228,8 @@ function NevisionRecorder({
243
228
  };
244
229
  const sendChunk = async (url, sessionId, isBeacon = false) => {
245
230
  if (eventsBufferRef.current.length === 0) return;
246
- const events = eventsBufferRef.current.splice(0, MAX_EVENTS_PER_CHUNK);
231
+ const events = isBeacon ? eventsBufferRef.current.splice(0) : eventsBufferRef.current.splice(0, MAX_EVENTS_PER_CHUNK);
247
232
  const chunkIndex = chunkIndexRef.current++;
248
- const chunkId = `${sessionId}_${chunkIndex}_${Date.now()}`;
249
- if (eventStoreRef.current) {
250
- try {
251
- await eventStoreRef.current.saveChunk({
252
- id: chunkId,
253
- sessionId,
254
- siteId,
255
- apiKey,
256
- events,
257
- chunkIndex,
258
- timestamp: Date.now()
259
- });
260
- } catch {
261
- }
262
- }
263
233
  const payload = JSON.stringify({
264
234
  sessionId,
265
235
  siteId,
@@ -268,15 +238,26 @@ function NevisionRecorder({
268
238
  chunkIndex
269
239
  });
270
240
  if (isBeacon && navigator.sendBeacon) {
271
- const sent = navigator.sendBeacon(
241
+ navigator.sendBeacon(
272
242
  `${url}/public/recordings/chunk`,
273
243
  new Blob([payload], { type: "application/json" })
274
244
  );
275
- if (sent && eventStoreRef.current) {
276
- eventStoreRef.current.deleteChunk(chunkId).catch(() => {
277
- });
278
- }
279
245
  } else {
246
+ const chunkId = `${sessionId}_${chunkIndex}_${Date.now()}`;
247
+ if (eventStoreRef.current) {
248
+ try {
249
+ await eventStoreRef.current.saveChunk({
250
+ id: chunkId,
251
+ sessionId,
252
+ siteId,
253
+ apiKey,
254
+ events,
255
+ chunkIndex,
256
+ timestamp: Date.now()
257
+ });
258
+ } catch {
259
+ }
260
+ }
280
261
  try {
281
262
  const response = await fetch(`${url}/public/recordings/chunk`, {
282
263
  method: "POST",
@@ -305,10 +286,6 @@ function NevisionRecorder({
305
286
  isActive = false;
306
287
  clearInterval(intervalId);
307
288
  stopFnRef.current?.();
308
- if (sessionIdRef.current) {
309
- sendChunk(apiUrl, sessionIdRef.current, true);
310
- endSession(apiUrl, sessionIdRef.current);
311
- }
312
289
  sessionIdRef.current = null;
313
290
  chunkIndexRef.current = 0;
314
291
  eventsBufferRef.current = [];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neroom/nevision",
3
- "version": "0.1.7",
3
+ "version": "0.1.8",
4
4
  "description": "React SDK for NEROOM/NEVISION session recording",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",