@loggerjs/browser 0.5.4 → 0.5.6
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/http-transport.cjs +83 -37
- package/dist/http-transport.cjs.map +1 -1
- package/dist/http-transport.d.ts +1 -0
- package/dist/http-transport.d.ts.map +1 -1
- package/dist/http-transport.js +83 -37
- package/dist/http-transport.js.map +1 -1
- package/dist/index.cjs +83 -37
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +83 -37
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -169,8 +169,10 @@ function remainingEvents(chunks, startIndex) {
|
|
|
169
169
|
}
|
|
170
170
|
function browserHttpTransport(options) {
|
|
171
171
|
const codec = options.codec ?? (0, _loggerjs_core.safeJsonCodec)();
|
|
172
|
+
const beaconCodec = options.beaconCodec ?? codec;
|
|
172
173
|
const queue = [];
|
|
173
174
|
const maxBatchSize = options.maxBatchSize ?? 50;
|
|
175
|
+
if (!Number.isSafeInteger(maxBatchSize) || maxBatchSize <= 0) throw new RangeError("maxBatchSize must be a positive safe integer");
|
|
174
176
|
const flushIntervalMs = options.flushIntervalMs ?? 2e3;
|
|
175
177
|
const maxQueueSize = options.maxQueueSize ?? 1e3;
|
|
176
178
|
const dropPolicy = options.dropPolicy ?? "drop-oldest";
|
|
@@ -183,7 +185,8 @@ function browserHttpTransport(options) {
|
|
|
183
185
|
const fetchFn = options.fetchFn ?? globalThis.fetch?.bind(globalThis);
|
|
184
186
|
let offlineEntrySeq = 0;
|
|
185
187
|
let timer;
|
|
186
|
-
let
|
|
188
|
+
let activeFlush;
|
|
189
|
+
let flushingBeacon = false;
|
|
187
190
|
let replayingOffline = false;
|
|
188
191
|
let lastContext;
|
|
189
192
|
const headers = (payloadHeaders, contentType = codec.contentType) => ({
|
|
@@ -209,54 +212,62 @@ function browserHttpTransport(options) {
|
|
|
209
212
|
};
|
|
210
213
|
const createBeaconChunks = (batch) => {
|
|
211
214
|
const chunks = [];
|
|
215
|
+
const oversized = [];
|
|
212
216
|
let currentEvents = [];
|
|
213
217
|
let currentPayload;
|
|
214
218
|
for (const event of batch) {
|
|
219
|
+
if (currentEvents.length === maxBatchSize && currentPayload !== void 0) {
|
|
220
|
+
chunks.push({
|
|
221
|
+
events: currentEvents,
|
|
222
|
+
payload: currentPayload
|
|
223
|
+
});
|
|
224
|
+
currentEvents = [];
|
|
225
|
+
currentPayload = void 0;
|
|
226
|
+
}
|
|
215
227
|
const candidateEvents = [...currentEvents, event];
|
|
216
|
-
const candidatePayload =
|
|
228
|
+
const candidatePayload = beaconCodec.encode(candidateEvents);
|
|
217
229
|
if (payloadByteLength$1(candidatePayload) <= beaconMaxBytes) {
|
|
218
230
|
currentEvents = candidateEvents;
|
|
219
231
|
currentPayload = candidatePayload;
|
|
220
232
|
continue;
|
|
221
233
|
}
|
|
222
|
-
if (currentEvents.length > 0 && currentPayload) chunks.push({
|
|
234
|
+
if (currentEvents.length > 0 && currentPayload !== void 0) chunks.push({
|
|
223
235
|
events: currentEvents,
|
|
224
236
|
payload: currentPayload
|
|
225
237
|
});
|
|
226
|
-
const singlePayload =
|
|
238
|
+
const singlePayload = beaconCodec.encode([event]);
|
|
227
239
|
if (payloadByteLength$1(singlePayload) <= beaconMaxBytes) {
|
|
228
240
|
currentEvents = [event];
|
|
229
241
|
currentPayload = singlePayload;
|
|
230
242
|
} else {
|
|
231
243
|
currentEvents = [];
|
|
232
244
|
currentPayload = void 0;
|
|
233
|
-
|
|
245
|
+
oversized.push(event);
|
|
234
246
|
}
|
|
235
247
|
}
|
|
236
|
-
if (currentEvents.length > 0 && currentPayload) chunks.push({
|
|
248
|
+
if (currentEvents.length > 0 && currentPayload !== void 0) chunks.push({
|
|
237
249
|
events: currentEvents,
|
|
238
250
|
payload: currentPayload
|
|
239
251
|
});
|
|
252
|
+
for (const event of oversized) reportDrop(event, "beacon-too-large");
|
|
240
253
|
return chunks;
|
|
241
254
|
};
|
|
242
255
|
const sendBeaconBatch = (batch) => {
|
|
243
|
-
if (typeof navigator === "undefined" || !navigator.sendBeacon) return {
|
|
244
|
-
ok: false,
|
|
245
|
-
remaining: batch
|
|
246
|
-
};
|
|
256
|
+
if (typeof navigator === "undefined" || !navigator.sendBeacon) return { remaining: batch };
|
|
247
257
|
const chunks = createBeaconChunks(batch);
|
|
248
258
|
for (let index = 0; index < chunks.length; index++) {
|
|
249
259
|
const chunk = chunks[index];
|
|
250
260
|
if (!chunk) continue;
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
261
|
+
try {
|
|
262
|
+
if (!navigator.sendBeacon(options.url, payloadToBeaconBody(chunk.payload, beaconCodec.contentType))) return { remaining: remainingEvents(chunks, index) };
|
|
263
|
+
} catch (error) {
|
|
264
|
+
return {
|
|
265
|
+
remaining: remainingEvents(chunks, index),
|
|
266
|
+
failure: { error }
|
|
267
|
+
};
|
|
268
|
+
}
|
|
255
269
|
}
|
|
256
|
-
return {
|
|
257
|
-
ok: true,
|
|
258
|
-
remaining: []
|
|
259
|
-
};
|
|
270
|
+
return { remaining: [] };
|
|
260
271
|
};
|
|
261
272
|
const sendPayload = async (entry) => {
|
|
262
273
|
if (!fetchFn) throw new Error("fetch is not available for browserHttpTransport");
|
|
@@ -333,31 +344,65 @@ function browserHttpTransport(options) {
|
|
|
333
344
|
replayingOffline = false;
|
|
334
345
|
}
|
|
335
346
|
};
|
|
336
|
-
const
|
|
337
|
-
if (
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
const batch = queue.splice(0, queue.length);
|
|
341
|
-
let pendingBatch = batch;
|
|
347
|
+
const flushBeaconQueue = () => {
|
|
348
|
+
if (flushingBeacon || options.transformPayload || queue.length === 0) return;
|
|
349
|
+
flushingBeacon = true;
|
|
350
|
+
let pending = queue.splice(0, queue.length);
|
|
342
351
|
try {
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
pendingBatch = beaconResult.remaining;
|
|
347
|
-
}
|
|
348
|
-
await sendFetchBatch(pendingBatch);
|
|
349
|
-
pendingBatch = [];
|
|
350
|
-
} catch (error) {
|
|
351
|
-
if (pendingBatch.length > 0) queue.unshift(...pendingBatch);
|
|
352
|
-
throw error;
|
|
352
|
+
const result = sendBeaconBatch(pending);
|
|
353
|
+
pending = result.remaining;
|
|
354
|
+
if (result.failure) throw result.failure.error;
|
|
353
355
|
} finally {
|
|
354
|
-
|
|
355
|
-
|
|
356
|
+
if (pending.length > 0) queue.unshift(...pending);
|
|
357
|
+
flushingBeacon = false;
|
|
356
358
|
}
|
|
357
359
|
};
|
|
360
|
+
const flush = (preferBeacon = false) => {
|
|
361
|
+
if (activeFlush) {
|
|
362
|
+
if (preferBeacon) try {
|
|
363
|
+
flushBeaconQueue();
|
|
364
|
+
} catch (error) {
|
|
365
|
+
return activeFlush.then(() => {
|
|
366
|
+
throw error;
|
|
367
|
+
});
|
|
368
|
+
}
|
|
369
|
+
return activeFlush;
|
|
370
|
+
}
|
|
371
|
+
if (queue.length === 0) return Promise.resolve();
|
|
372
|
+
clearTimer();
|
|
373
|
+
let resolve;
|
|
374
|
+
let reject;
|
|
375
|
+
const task = new Promise((onResolve, onReject) => {
|
|
376
|
+
resolve = onResolve;
|
|
377
|
+
reject = onReject;
|
|
378
|
+
});
|
|
379
|
+
activeFlush = task;
|
|
380
|
+
(async () => {
|
|
381
|
+
try {
|
|
382
|
+
if (preferBeacon) flushBeaconQueue();
|
|
383
|
+
while (queue.length > 0) {
|
|
384
|
+
const batch = queue.splice(0, maxBatchSize);
|
|
385
|
+
try {
|
|
386
|
+
await sendFetchBatch(batch);
|
|
387
|
+
} catch (error) {
|
|
388
|
+
queue.unshift(...batch);
|
|
389
|
+
throw error;
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
resolve();
|
|
393
|
+
} catch (error) {
|
|
394
|
+
reject(error);
|
|
395
|
+
} finally {
|
|
396
|
+
activeFlush = void 0;
|
|
397
|
+
if (queue.length > 0) schedule();
|
|
398
|
+
}
|
|
399
|
+
})();
|
|
400
|
+
return task;
|
|
401
|
+
};
|
|
358
402
|
const schedule = () => {
|
|
359
|
-
if (timer || flushIntervalMs <= 0) return;
|
|
403
|
+
if (activeFlush || timer || flushIntervalMs <= 0) return;
|
|
360
404
|
timer = setTimeout(() => {
|
|
405
|
+
timer = void 0;
|
|
361
406
|
flush(false).catch((error) => reportInternalError(error, "flush"));
|
|
362
407
|
}, flushIntervalMs);
|
|
363
408
|
};
|
|
@@ -390,6 +435,7 @@ function browserHttpTransport(options) {
|
|
|
390
435
|
if (dropped) reportDrop(dropped, "queue-full");
|
|
391
436
|
}
|
|
392
437
|
queue.push(event);
|
|
438
|
+
if (activeFlush) return;
|
|
393
439
|
if (queue.length >= maxBatchSize) flush(false).catch((error) => reportInternalError(error, "flush"));
|
|
394
440
|
else schedule();
|
|
395
441
|
},
|