@tracelog/capture-web 1.3.0 → 1.3.1
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/CHANGELOG.md +7 -0
- package/README.md +6 -4
- package/dist/tracelog.esm.js +77 -30
- package/dist/tracelog.iife.js +77 -30
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -18,6 +18,13 @@ patch, and neither requires reading your code.
|
|
|
18
18
|
Entries after 1.0.0 are drafted from the commits that touched this package and
|
|
19
19
|
edited before release.
|
|
20
20
|
|
|
21
|
+
## [1.3.1](https://github.com/nacorga/tracelog-sdk/compare/capture-web@1.3.0...capture-web@1.3.1) (2026-09-30)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
### Fixed
|
|
25
|
+
|
|
26
|
+
* **capture-core:** a send outlives the page that started it ([86faf5f](https://github.com/nacorga/tracelog-sdk/commit/86faf5f479a76d69f6413f9db82daae1482492df))
|
|
27
|
+
|
|
21
28
|
## [1.3.0](https://github.com/nacorga/tracelog-sdk/compare/capture-web@1.2.0...capture-web@1.3.0) (2026-09-27)
|
|
22
29
|
|
|
23
30
|
|
package/README.md
CHANGED
|
@@ -22,13 +22,13 @@ as they are served.
|
|
|
22
22
|
<!-- x-release-please-start-version -->
|
|
23
23
|
|
|
24
24
|
```bash
|
|
25
|
-
npm install --save-exact @tracelog/capture-web@1.3.
|
|
25
|
+
npm install --save-exact @tracelog/capture-web@1.3.1
|
|
26
26
|
```
|
|
27
27
|
|
|
28
28
|
Without a build step, the same runtime as a script tag:
|
|
29
29
|
|
|
30
30
|
```html
|
|
31
|
-
<script src="https://cdn.tracelog.io/v/1.3.
|
|
31
|
+
<script src="https://cdn.tracelog.io/v/1.3.1/tracelog.js"></script>
|
|
32
32
|
```
|
|
33
33
|
|
|
34
34
|
<!-- x-release-please-end -->
|
|
@@ -105,8 +105,10 @@ An IP address is read once when the event arrives to derive a two-letter country
|
|
|
105
105
|
code, then discarded.
|
|
106
106
|
|
|
107
107
|
Events queue locally once consent allows, batch, and deliver with retry, backoff
|
|
108
|
-
and circuit breaking.
|
|
109
|
-
|
|
108
|
+
and circuit breaking. A step is sent when it is taken, and every send uses
|
|
109
|
+
`keepalive`, so a click that leaves the page — even for another site — does not
|
|
110
|
+
cancel it. Delivery failure surfaces as a diagnosable condition, never as
|
|
111
|
+
silent loss.
|
|
110
112
|
|
|
111
113
|
## Where it runs
|
|
112
114
|
|
package/dist/tracelog.esm.js
CHANGED
|
@@ -27,6 +27,14 @@ const RETRY_BASE_MS = 1000;
|
|
|
27
27
|
const RETRY_CAP_MS = 60 * 1000;
|
|
28
28
|
const CIRCUIT_FAILURE_THRESHOLD = 5;
|
|
29
29
|
const CIRCUIT_PROBE_MS = 60 * 1000;
|
|
30
|
+
/**
|
|
31
|
+
* What the browser lets `keepalive` bodies in flight add up to. Every send
|
|
32
|
+
* uses `keepalive`, so no navigation cancels one, and every send fits what is
|
|
33
|
+
* left of this beside the sends already in flight ([spec/capture.md]
|
|
34
|
+
* § Delivery). It is below the contract's `MAX_BATCH_BYTES`, so it is the
|
|
35
|
+
* batch budget too.
|
|
36
|
+
*/
|
|
37
|
+
const KEEPALIVE_BUDGET_BYTES = 64 * 1024;
|
|
30
38
|
const EVENT_NAME_PATTERN = /^[a-z][a-z0-9_]{0,63}$/;
|
|
31
39
|
const PUBLIC_KEY_PATTERN = /^tl_pk_[a-z2-7]{26}$/;
|
|
32
40
|
/**
|
|
@@ -171,7 +179,12 @@ function isConversionValid(options) {
|
|
|
171
179
|
function serializedBytes(value) {
|
|
172
180
|
return textEncoder.encode(JSON.stringify(value)).byteLength;
|
|
173
181
|
}
|
|
174
|
-
|
|
182
|
+
/**
|
|
183
|
+
* As many events as fit `room`, oldest first. An event that alone exceeds the
|
|
184
|
+
* whole keepalive budget can never be sent; one that only exceeds what the
|
|
185
|
+
* sends in flight leave waits for them.
|
|
186
|
+
*/
|
|
187
|
+
function batchFrom(events, room) {
|
|
175
188
|
const selected = [];
|
|
176
189
|
const unsendable = [];
|
|
177
190
|
for (const event of events) {
|
|
@@ -181,8 +194,9 @@ function batchFrom(events) {
|
|
|
181
194
|
v: EVENT_ENVELOPE_VERSION,
|
|
182
195
|
events: [...selected, event],
|
|
183
196
|
};
|
|
184
|
-
|
|
185
|
-
|
|
197
|
+
const bytes = serializedBytes(candidate);
|
|
198
|
+
if (bytes > room) {
|
|
199
|
+
if (selected.length === 0 && bytes > KEEPALIVE_BUDGET_BYTES) {
|
|
186
200
|
unsendable.push(event);
|
|
187
201
|
continue;
|
|
188
202
|
}
|
|
@@ -199,11 +213,13 @@ function createCaptureEngine(ports, acquisition) {
|
|
|
199
213
|
let pending = [];
|
|
200
214
|
let lastDeclaredName;
|
|
201
215
|
/**
|
|
202
|
-
* Every send in flight, by count and by the union of their event
|
|
203
|
-
* page hide
|
|
204
|
-
*
|
|
216
|
+
* Every send in flight, by count, by bytes and by the union of their event
|
|
217
|
+
* ids: a step taken and a page hide send beside one rather than wait for
|
|
218
|
+
* it, so there can be several, each must leave the others' events alone,
|
|
219
|
+
* and together they stay within the keepalive budget.
|
|
205
220
|
*/
|
|
206
221
|
let sendsInFlight = 0;
|
|
222
|
+
let bytesInFlight = 0;
|
|
207
223
|
const inFlight = new Set();
|
|
208
224
|
/**
|
|
209
225
|
* The conversions this page emitted and holds for their tag sighting
|
|
@@ -329,6 +345,38 @@ function createCaptureEngine(ports, acquisition) {
|
|
|
329
345
|
return;
|
|
330
346
|
}
|
|
331
347
|
emit(pendingEvent);
|
|
348
|
+
sendTaken();
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* A step, and a conversion that is not held, leaves when it is taken: a
|
|
352
|
+
* click that navigates to another site may fire no hide event at all, and a
|
|
353
|
+
* send started by the click itself is the one that arrives ([spec/capture.md]
|
|
354
|
+
* § Delivery). An open circuit keeps it queued for the probe.
|
|
355
|
+
*/
|
|
356
|
+
function sendTaken() {
|
|
357
|
+
if (circuit !== "closed" || !PUBLIC_KEY_PATTERN.test(config.key))
|
|
358
|
+
return;
|
|
359
|
+
void sendNow();
|
|
360
|
+
}
|
|
361
|
+
/**
|
|
362
|
+
* Sends at once what is queued and in no send in flight, beside any send in
|
|
363
|
+
* flight, within what the keepalive budget has left.
|
|
364
|
+
*/
|
|
365
|
+
async function sendNow() {
|
|
366
|
+
const queue = readQueue(ports.storage);
|
|
367
|
+
const ready = queue.events.filter((event) => !held.has(event.eventId) && !inFlight.has(event.eventId));
|
|
368
|
+
const { batch, unsendable } = batchFrom(ready, KEEPALIVE_BUDGET_BYTES - bytesInFlight);
|
|
369
|
+
dropUnsendable(queue, unsendable);
|
|
370
|
+
if (batch.events.length > 0)
|
|
371
|
+
await deliver(batch);
|
|
372
|
+
}
|
|
373
|
+
function dropUnsendable(queue, unsendable) {
|
|
374
|
+
if (unsendable.length === 0)
|
|
375
|
+
return;
|
|
376
|
+
const dropped = new Set(unsendable.map((event) => event.eventId));
|
|
377
|
+
queue.events = queue.events.filter((event) => !dropped.has(event.eventId));
|
|
378
|
+
addDrop(queue, "invalid_event", unsendable.length);
|
|
379
|
+
writeQueue(ports.storage, queue);
|
|
332
380
|
}
|
|
333
381
|
/**
|
|
334
382
|
* Gives each held conversion whose window has closed — or every one, at
|
|
@@ -381,11 +429,21 @@ function createCaptureEngine(ports, acquisition) {
|
|
|
381
429
|
}
|
|
382
430
|
return Math.max(0, earliest - now);
|
|
383
431
|
}
|
|
384
|
-
async function flush(
|
|
385
|
-
release(
|
|
432
|
+
async function flush(hidden = false) {
|
|
433
|
+
release(hidden);
|
|
386
434
|
if (!initialized || consentState !== "granted")
|
|
387
435
|
return;
|
|
388
|
-
|
|
436
|
+
/**
|
|
437
|
+
* A page being hidden gets no later chance, so it sends what no send in
|
|
438
|
+
* flight carries at once, whatever the circuit's state, and the answer is
|
|
439
|
+
* read as any other's.
|
|
440
|
+
*/
|
|
441
|
+
if (hidden) {
|
|
442
|
+
if (PUBLIC_KEY_PATTERN.test(config.key))
|
|
443
|
+
await sendNow();
|
|
444
|
+
return;
|
|
445
|
+
}
|
|
446
|
+
if (sendsInFlight > 0)
|
|
389
447
|
return;
|
|
390
448
|
const queue = readQueue(ports.storage);
|
|
391
449
|
const ready = queue.events.filter((event) => !held.has(event.eventId) && !inFlight.has(event.eventId));
|
|
@@ -397,17 +455,6 @@ function createCaptureEngine(ports, acquisition) {
|
|
|
397
455
|
}
|
|
398
456
|
return;
|
|
399
457
|
}
|
|
400
|
-
/**
|
|
401
|
-
* A page being hidden gets no later chance, so it sends what no send in
|
|
402
|
-
* flight carries at once, whatever the circuit's state, and the answer is
|
|
403
|
-
* read as any other's.
|
|
404
|
-
*/
|
|
405
|
-
if (sendsInFlight > 0) {
|
|
406
|
-
const { batch } = batchFrom(ready);
|
|
407
|
-
if (batch.events.length > 0)
|
|
408
|
-
await deliver(batch, true);
|
|
409
|
-
return;
|
|
410
|
-
}
|
|
411
458
|
const now = ports.clock.now().getTime();
|
|
412
459
|
if (circuit === "open") {
|
|
413
460
|
if (now < nextProbeAt) {
|
|
@@ -416,35 +463,32 @@ function createCaptureEngine(ports, acquisition) {
|
|
|
416
463
|
}
|
|
417
464
|
circuit = "half_open";
|
|
418
465
|
}
|
|
419
|
-
const { batch, unsendable } = batchFrom(ready);
|
|
420
|
-
|
|
421
|
-
const dropped = new Set(unsendable.map((event) => event.eventId));
|
|
422
|
-
queue.events = queue.events.filter((event) => !dropped.has(event.eventId));
|
|
423
|
-
addDrop(queue, "invalid_event", unsendable.length);
|
|
424
|
-
writeQueue(ports.storage, queue);
|
|
425
|
-
}
|
|
466
|
+
const { batch, unsendable } = batchFrom(ready, KEEPALIVE_BUDGET_BYTES);
|
|
467
|
+
dropUnsendable(queue, unsendable);
|
|
426
468
|
if (batch.events.length === 0) {
|
|
427
469
|
scheduleFlush(FLUSH_INTERVAL_MS);
|
|
428
470
|
return;
|
|
429
471
|
}
|
|
430
|
-
await deliver(batch
|
|
472
|
+
await deliver(batch);
|
|
431
473
|
}
|
|
432
474
|
/**
|
|
433
475
|
* One send, and its answer. It removes from the stored queue exactly what
|
|
434
476
|
* it carried, by its own read, filter and write at the moment it settles,
|
|
435
477
|
* so a send beside it keeps what it delivered.
|
|
436
478
|
*/
|
|
437
|
-
async function deliver(batch
|
|
479
|
+
async function deliver(batch) {
|
|
438
480
|
const carried = new Set(batch.events.map((event) => event.eventId));
|
|
481
|
+
const bytes = serializedBytes(batch);
|
|
439
482
|
for (const eventId of carried)
|
|
440
483
|
inFlight.add(eventId);
|
|
441
484
|
sendsInFlight += 1;
|
|
485
|
+
bytesInFlight += bytes;
|
|
442
486
|
try {
|
|
443
487
|
const response = await ports.transport.send({
|
|
444
488
|
endpoint: config.endpoint,
|
|
445
489
|
key: config.key,
|
|
446
490
|
batch,
|
|
447
|
-
keepalive,
|
|
491
|
+
keepalive: true,
|
|
448
492
|
});
|
|
449
493
|
if (response.status >= 200 && response.status < 300) {
|
|
450
494
|
const currentQueue = readQueue(ports.storage);
|
|
@@ -496,6 +540,7 @@ function createCaptureEngine(ports, acquisition) {
|
|
|
496
540
|
for (const eventId of carried)
|
|
497
541
|
inFlight.delete(eventId);
|
|
498
542
|
sendsInFlight -= 1;
|
|
543
|
+
bytesInFlight -= bytes;
|
|
499
544
|
}
|
|
500
545
|
}
|
|
501
546
|
const engine = {
|
|
@@ -526,6 +571,8 @@ function createCaptureEngine(ports, acquisition) {
|
|
|
526
571
|
pending = [];
|
|
527
572
|
for (const pendingEvent of buffered)
|
|
528
573
|
emit(pendingEvent, true);
|
|
574
|
+
if (buffered.length > 0)
|
|
575
|
+
sendTaken();
|
|
529
576
|
scheduleFlush(FLUSH_INTERVAL_MS);
|
|
530
577
|
},
|
|
531
578
|
deny() {
|
package/dist/tracelog.iife.js
CHANGED
|
@@ -28,6 +28,14 @@ const RETRY_BASE_MS = 1000;
|
|
|
28
28
|
const RETRY_CAP_MS = 60 * 1000;
|
|
29
29
|
const CIRCUIT_FAILURE_THRESHOLD = 5;
|
|
30
30
|
const CIRCUIT_PROBE_MS = 60 * 1000;
|
|
31
|
+
/**
|
|
32
|
+
* What the browser lets `keepalive` bodies in flight add up to. Every send
|
|
33
|
+
* uses `keepalive`, so no navigation cancels one, and every send fits what is
|
|
34
|
+
* left of this beside the sends already in flight ([spec/capture.md]
|
|
35
|
+
* § Delivery). It is below the contract's `MAX_BATCH_BYTES`, so it is the
|
|
36
|
+
* batch budget too.
|
|
37
|
+
*/
|
|
38
|
+
const KEEPALIVE_BUDGET_BYTES = 64 * 1024;
|
|
31
39
|
const EVENT_NAME_PATTERN = /^[a-z][a-z0-9_]{0,63}$/;
|
|
32
40
|
const PUBLIC_KEY_PATTERN = /^tl_pk_[a-z2-7]{26}$/;
|
|
33
41
|
/**
|
|
@@ -172,7 +180,12 @@ function isConversionValid(options) {
|
|
|
172
180
|
function serializedBytes(value) {
|
|
173
181
|
return textEncoder.encode(JSON.stringify(value)).byteLength;
|
|
174
182
|
}
|
|
175
|
-
|
|
183
|
+
/**
|
|
184
|
+
* As many events as fit `room`, oldest first. An event that alone exceeds the
|
|
185
|
+
* whole keepalive budget can never be sent; one that only exceeds what the
|
|
186
|
+
* sends in flight leave waits for them.
|
|
187
|
+
*/
|
|
188
|
+
function batchFrom(events, room) {
|
|
176
189
|
const selected = [];
|
|
177
190
|
const unsendable = [];
|
|
178
191
|
for (const event of events) {
|
|
@@ -182,8 +195,9 @@ function batchFrom(events) {
|
|
|
182
195
|
v: EVENT_ENVELOPE_VERSION,
|
|
183
196
|
events: [...selected, event],
|
|
184
197
|
};
|
|
185
|
-
|
|
186
|
-
|
|
198
|
+
const bytes = serializedBytes(candidate);
|
|
199
|
+
if (bytes > room) {
|
|
200
|
+
if (selected.length === 0 && bytes > KEEPALIVE_BUDGET_BYTES) {
|
|
187
201
|
unsendable.push(event);
|
|
188
202
|
continue;
|
|
189
203
|
}
|
|
@@ -200,11 +214,13 @@ function createCaptureEngine(ports, acquisition) {
|
|
|
200
214
|
let pending = [];
|
|
201
215
|
let lastDeclaredName;
|
|
202
216
|
/**
|
|
203
|
-
* Every send in flight, by count and by the union of their event
|
|
204
|
-
* page hide
|
|
205
|
-
*
|
|
217
|
+
* Every send in flight, by count, by bytes and by the union of their event
|
|
218
|
+
* ids: a step taken and a page hide send beside one rather than wait for
|
|
219
|
+
* it, so there can be several, each must leave the others' events alone,
|
|
220
|
+
* and together they stay within the keepalive budget.
|
|
206
221
|
*/
|
|
207
222
|
let sendsInFlight = 0;
|
|
223
|
+
let bytesInFlight = 0;
|
|
208
224
|
const inFlight = new Set();
|
|
209
225
|
/**
|
|
210
226
|
* The conversions this page emitted and holds for their tag sighting
|
|
@@ -330,6 +346,38 @@ function createCaptureEngine(ports, acquisition) {
|
|
|
330
346
|
return;
|
|
331
347
|
}
|
|
332
348
|
emit(pendingEvent);
|
|
349
|
+
sendTaken();
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* A step, and a conversion that is not held, leaves when it is taken: a
|
|
353
|
+
* click that navigates to another site may fire no hide event at all, and a
|
|
354
|
+
* send started by the click itself is the one that arrives ([spec/capture.md]
|
|
355
|
+
* § Delivery). An open circuit keeps it queued for the probe.
|
|
356
|
+
*/
|
|
357
|
+
function sendTaken() {
|
|
358
|
+
if (circuit !== "closed" || !PUBLIC_KEY_PATTERN.test(config.key))
|
|
359
|
+
return;
|
|
360
|
+
void sendNow();
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* Sends at once what is queued and in no send in flight, beside any send in
|
|
364
|
+
* flight, within what the keepalive budget has left.
|
|
365
|
+
*/
|
|
366
|
+
async function sendNow() {
|
|
367
|
+
const queue = readQueue(ports.storage);
|
|
368
|
+
const ready = queue.events.filter((event) => !held.has(event.eventId) && !inFlight.has(event.eventId));
|
|
369
|
+
const { batch, unsendable } = batchFrom(ready, KEEPALIVE_BUDGET_BYTES - bytesInFlight);
|
|
370
|
+
dropUnsendable(queue, unsendable);
|
|
371
|
+
if (batch.events.length > 0)
|
|
372
|
+
await deliver(batch);
|
|
373
|
+
}
|
|
374
|
+
function dropUnsendable(queue, unsendable) {
|
|
375
|
+
if (unsendable.length === 0)
|
|
376
|
+
return;
|
|
377
|
+
const dropped = new Set(unsendable.map((event) => event.eventId));
|
|
378
|
+
queue.events = queue.events.filter((event) => !dropped.has(event.eventId));
|
|
379
|
+
addDrop(queue, "invalid_event", unsendable.length);
|
|
380
|
+
writeQueue(ports.storage, queue);
|
|
333
381
|
}
|
|
334
382
|
/**
|
|
335
383
|
* Gives each held conversion whose window has closed — or every one, at
|
|
@@ -382,11 +430,21 @@ function createCaptureEngine(ports, acquisition) {
|
|
|
382
430
|
}
|
|
383
431
|
return Math.max(0, earliest - now);
|
|
384
432
|
}
|
|
385
|
-
async function flush(
|
|
386
|
-
release(
|
|
433
|
+
async function flush(hidden = false) {
|
|
434
|
+
release(hidden);
|
|
387
435
|
if (!initialized || consentState !== "granted")
|
|
388
436
|
return;
|
|
389
|
-
|
|
437
|
+
/**
|
|
438
|
+
* A page being hidden gets no later chance, so it sends what no send in
|
|
439
|
+
* flight carries at once, whatever the circuit's state, and the answer is
|
|
440
|
+
* read as any other's.
|
|
441
|
+
*/
|
|
442
|
+
if (hidden) {
|
|
443
|
+
if (PUBLIC_KEY_PATTERN.test(config.key))
|
|
444
|
+
await sendNow();
|
|
445
|
+
return;
|
|
446
|
+
}
|
|
447
|
+
if (sendsInFlight > 0)
|
|
390
448
|
return;
|
|
391
449
|
const queue = readQueue(ports.storage);
|
|
392
450
|
const ready = queue.events.filter((event) => !held.has(event.eventId) && !inFlight.has(event.eventId));
|
|
@@ -398,17 +456,6 @@ function createCaptureEngine(ports, acquisition) {
|
|
|
398
456
|
}
|
|
399
457
|
return;
|
|
400
458
|
}
|
|
401
|
-
/**
|
|
402
|
-
* A page being hidden gets no later chance, so it sends what no send in
|
|
403
|
-
* flight carries at once, whatever the circuit's state, and the answer is
|
|
404
|
-
* read as any other's.
|
|
405
|
-
*/
|
|
406
|
-
if (sendsInFlight > 0) {
|
|
407
|
-
const { batch } = batchFrom(ready);
|
|
408
|
-
if (batch.events.length > 0)
|
|
409
|
-
await deliver(batch, true);
|
|
410
|
-
return;
|
|
411
|
-
}
|
|
412
459
|
const now = ports.clock.now().getTime();
|
|
413
460
|
if (circuit === "open") {
|
|
414
461
|
if (now < nextProbeAt) {
|
|
@@ -417,35 +464,32 @@ function createCaptureEngine(ports, acquisition) {
|
|
|
417
464
|
}
|
|
418
465
|
circuit = "half_open";
|
|
419
466
|
}
|
|
420
|
-
const { batch, unsendable } = batchFrom(ready);
|
|
421
|
-
|
|
422
|
-
const dropped = new Set(unsendable.map((event) => event.eventId));
|
|
423
|
-
queue.events = queue.events.filter((event) => !dropped.has(event.eventId));
|
|
424
|
-
addDrop(queue, "invalid_event", unsendable.length);
|
|
425
|
-
writeQueue(ports.storage, queue);
|
|
426
|
-
}
|
|
467
|
+
const { batch, unsendable } = batchFrom(ready, KEEPALIVE_BUDGET_BYTES);
|
|
468
|
+
dropUnsendable(queue, unsendable);
|
|
427
469
|
if (batch.events.length === 0) {
|
|
428
470
|
scheduleFlush(FLUSH_INTERVAL_MS);
|
|
429
471
|
return;
|
|
430
472
|
}
|
|
431
|
-
await deliver(batch
|
|
473
|
+
await deliver(batch);
|
|
432
474
|
}
|
|
433
475
|
/**
|
|
434
476
|
* One send, and its answer. It removes from the stored queue exactly what
|
|
435
477
|
* it carried, by its own read, filter and write at the moment it settles,
|
|
436
478
|
* so a send beside it keeps what it delivered.
|
|
437
479
|
*/
|
|
438
|
-
async function deliver(batch
|
|
480
|
+
async function deliver(batch) {
|
|
439
481
|
const carried = new Set(batch.events.map((event) => event.eventId));
|
|
482
|
+
const bytes = serializedBytes(batch);
|
|
440
483
|
for (const eventId of carried)
|
|
441
484
|
inFlight.add(eventId);
|
|
442
485
|
sendsInFlight += 1;
|
|
486
|
+
bytesInFlight += bytes;
|
|
443
487
|
try {
|
|
444
488
|
const response = await ports.transport.send({
|
|
445
489
|
endpoint: config.endpoint,
|
|
446
490
|
key: config.key,
|
|
447
491
|
batch,
|
|
448
|
-
keepalive,
|
|
492
|
+
keepalive: true,
|
|
449
493
|
});
|
|
450
494
|
if (response.status >= 200 && response.status < 300) {
|
|
451
495
|
const currentQueue = readQueue(ports.storage);
|
|
@@ -497,6 +541,7 @@ function createCaptureEngine(ports, acquisition) {
|
|
|
497
541
|
for (const eventId of carried)
|
|
498
542
|
inFlight.delete(eventId);
|
|
499
543
|
sendsInFlight -= 1;
|
|
544
|
+
bytesInFlight -= bytes;
|
|
500
545
|
}
|
|
501
546
|
}
|
|
502
547
|
const engine = {
|
|
@@ -527,6 +572,8 @@ function createCaptureEngine(ports, acquisition) {
|
|
|
527
572
|
pending = [];
|
|
528
573
|
for (const pendingEvent of buffered)
|
|
529
574
|
emit(pendingEvent, true);
|
|
575
|
+
if (buffered.length > 0)
|
|
576
|
+
sendTaken();
|
|
530
577
|
scheduleFlush(FLUSH_INTERVAL_MS);
|
|
531
578
|
},
|
|
532
579
|
deny() {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tracelog/capture-web",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.1",
|
|
4
4
|
"description": "The TraceLog browser capture runtime: consent-first, pinned per version.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"conversion",
|
|
@@ -45,8 +45,8 @@
|
|
|
45
45
|
"access": "public"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
|
-
"@tracelog/capture-core": "1.3.
|
|
49
|
-
"@tracelog/event-contract": "1.3.
|
|
48
|
+
"@tracelog/capture-core": "1.3.1",
|
|
49
|
+
"@tracelog/event-contract": "1.3.1"
|
|
50
50
|
},
|
|
51
51
|
"scripts": {
|
|
52
52
|
"build": "tsc -p tsconfig.build.json && node build.mjs",
|