@loggerjs/browser 0.5.6 → 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/index.js CHANGED
@@ -187,7 +187,7 @@ function browserHttpTransport(options) {
187
187
  let timer;
188
188
  let activeFlush;
189
189
  let flushingBeacon = false;
190
- let replayingOffline = false;
190
+ let replayPromise;
191
191
  let lastContext;
192
192
  const headers = (payloadHeaders, contentType = codec.contentType) => ({
193
193
  "content-type": contentType,
@@ -303,17 +303,18 @@ function browserHttpTransport(options) {
303
303
  incrementLoggerMetaCounter("transport.offline.queued");
304
304
  return true;
305
305
  };
306
+ const isOnline = () => typeof navigator === "undefined" || navigator.onLine !== false;
306
307
  const sendFetchBatch = async (batch) => {
307
- if (batch.length === 0) return;
308
308
  const transformed = await encodeTransformedPayload(batch);
309
- if (offlineQueue && typeof navigator !== "undefined" && navigator.onLine === false) {
309
+ if (offlineQueue && !isOnline()) {
310
310
  await enqueueOfflinePayload(transformed.payload, transformed.headers, transformed.contentType);
311
- return;
311
+ return "queued";
312
312
  }
313
313
  try {
314
314
  await sendPayload(createOfflineEntry(transformed.payload, transformed.headers, transformed.contentType));
315
+ return "sent";
315
316
  } catch (error) {
316
- if (await enqueueOfflinePayload(transformed.payload, transformed.headers, transformed.contentType)) return;
317
+ if (await enqueueOfflinePayload(transformed.payload, transformed.headers, transformed.contentType)) return "queued";
317
318
  throw error;
318
319
  }
319
320
  };
@@ -335,13 +336,23 @@ function browserHttpTransport(options) {
335
336
  await sleep(replayRetryDelay(attempt));
336
337
  }
337
338
  };
338
- const replayOfflineQueue = async () => {
339
- if (!offlineQueue || replayingOffline) return;
340
- replayingOffline = true;
339
+ const replayOfflineQueue = () => {
340
+ if (!offlineQueue) return Promise.resolve();
341
+ replayPromise ??= (async () => {
342
+ try {
343
+ await offlineQueue.replay(sendOfflineEntryWithRetry);
344
+ } finally {
345
+ replayPromise = void 0;
346
+ }
347
+ })();
348
+ return replayPromise;
349
+ };
350
+ const replayOfflineQueueSafely = async (operation) => {
351
+ if (!offlineQueue || !isOnline()) return;
341
352
  try {
342
- await offlineQueue.replay(sendOfflineEntryWithRetry);
343
- } finally {
344
- replayingOffline = false;
353
+ await replayOfflineQueue();
354
+ } catch (error) {
355
+ reportInternalError(error, operation);
345
356
  }
346
357
  };
347
358
  const flushBeaconQueue = () => {
@@ -368,7 +379,7 @@ function browserHttpTransport(options) {
368
379
  }
369
380
  return activeFlush;
370
381
  }
371
- if (queue.length === 0) return Promise.resolve();
382
+ if (queue.length === 0) return preferBeacon ? Promise.resolve() : replayOfflineQueueSafely("replay");
372
383
  clearTimer();
373
384
  let resolve;
374
385
  let reject;
@@ -380,15 +391,19 @@ function browserHttpTransport(options) {
380
391
  (async () => {
381
392
  try {
382
393
  if (preferBeacon) flushBeaconQueue();
394
+ let sent = false;
395
+ let queued = false;
383
396
  while (queue.length > 0) {
384
397
  const batch = queue.splice(0, maxBatchSize);
385
398
  try {
386
- await sendFetchBatch(batch);
399
+ if (await sendFetchBatch(batch) === "sent") sent = true;
400
+ else queued = true;
387
401
  } catch (error) {
388
402
  queue.unshift(...batch);
389
403
  throw error;
390
404
  }
391
405
  }
406
+ if (!preferBeacon && sent && !queued) await replayOfflineQueueSafely("replay");
392
407
  resolve();
393
408
  } catch (error) {
394
409
  reject(error);
@@ -419,7 +434,10 @@ function browserHttpTransport(options) {
419
434
  globalThis.addEventListener?.("pagehide", onPageHide);
420
435
  globalThis.addEventListener?.("visibilitychange", onVisibilityChange);
421
436
  }
422
- if (offlineQueue) globalThis.addEventListener?.("online", onOnline);
437
+ if (offlineQueue) {
438
+ globalThis.addEventListener?.("online", onOnline);
439
+ if (options.offlineReplayOnStart ?? true) setTimeout(() => void replayOfflineQueueSafely("startup-replay"), 0);
440
+ }
423
441
  return {
424
442
  name: options.name ?? "browser-http",
425
443
  minLevel: options.minLevel,
@@ -2073,6 +2091,7 @@ function offlineFirstTransport(remote, options = {}) {
2073
2091
  name,
2074
2092
  minLevel: options.minLevel ?? remote.minLevel,
2075
2093
  queue,
2094
+ ready: remote.ready && (() => remote.ready?.()),
2076
2095
  write(record, context) {
2077
2096
  return sendOrQueue(context.toEvent(record), context);
2078
2097
  },