bitfab 0.36.8 → 0.36.10
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/{chunk-QUX6N7ON.js → chunk-AAMRJGZJ.js} +89 -19
- package/dist/chunk-AAMRJGZJ.js.map +1 -0
- package/dist/{chunk-B4HK3BPE.js → chunk-RSM2TLKG.js} +3 -3
- package/dist/index.cjs +88 -19
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +19 -1
- package/dist/index.d.ts +19 -1
- package/dist/index.js +2 -2
- package/dist/node.cjs +88 -19
- package/dist/node.cjs.map +1 -1
- package/dist/node.js +2 -2
- package/dist/{replay-7PUB6ZOG.js → replay-WKWBBIGE.js} +4 -2
- package/package.json +1 -1
- package/dist/chunk-QUX6N7ON.js.map +0 -1
- /package/dist/{chunk-B4HK3BPE.js.map → chunk-RSM2TLKG.js.map} +0 -0
- /package/dist/{replay-7PUB6ZOG.js.map → replay-WKWBBIGE.js.map} +0 -0
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
toJsonSafe,
|
|
17
17
|
toJsonSafeReport,
|
|
18
18
|
warnOnce
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-AAMRJGZJ.js";
|
|
20
20
|
|
|
21
21
|
// src/processorPayload.ts
|
|
22
22
|
var SERIALIZATION_DEGRADED_STEP = "serialization_degraded";
|
|
@@ -3371,7 +3371,7 @@ var Bitfab = class {
|
|
|
3371
3371
|
`Function is wrapped with trace function key '${wrappedKey}' but replay was called with '${traceFunctionKey}'. Pass matching keys, or pass the unwrapped function to replay it under the explicit key.`
|
|
3372
3372
|
);
|
|
3373
3373
|
}
|
|
3374
|
-
const { replay: doReplay } = await import("./replay-
|
|
3374
|
+
const { replay: doReplay } = await import("./replay-WKWBBIGE.js");
|
|
3375
3375
|
return doReplay(
|
|
3376
3376
|
this.httpClient,
|
|
3377
3377
|
this.serviceUrl,
|
|
@@ -3609,4 +3609,4 @@ export {
|
|
|
3609
3609
|
BitfabFunction,
|
|
3610
3610
|
finalizers
|
|
3611
3611
|
};
|
|
3612
|
-
//# sourceMappingURL=chunk-
|
|
3612
|
+
//# sourceMappingURL=chunk-RSM2TLKG.js.map
|
package/dist/index.cjs
CHANGED
|
@@ -51,7 +51,7 @@ var __version__;
|
|
|
51
51
|
var init_version_generated = __esm({
|
|
52
52
|
"src/version.generated.ts"() {
|
|
53
53
|
"use strict";
|
|
54
|
-
__version__ = "0.36.
|
|
54
|
+
__version__ = "0.36.10";
|
|
55
55
|
}
|
|
56
56
|
});
|
|
57
57
|
|
|
@@ -1444,6 +1444,10 @@ var init_http = __esm({
|
|
|
1444
1444
|
...error instanceof BitfabError && error.retryAfterMs !== void 0 ? { retryAfterMs: error.retryAfterMs } : {}
|
|
1445
1445
|
});
|
|
1446
1446
|
}
|
|
1447
|
+
const serverTraceIds = asPayloadRecord(response?.traceIds);
|
|
1448
|
+
if (serverTraceIds !== void 0) {
|
|
1449
|
+
this.recordServerTraceIds(serverTraceIds);
|
|
1450
|
+
}
|
|
1447
1451
|
const partialSuccess = asPayloadRecord(response?.partialSuccess);
|
|
1448
1452
|
const rejected = partialSuccess?.rejectedSpans;
|
|
1449
1453
|
if (rejected !== void 0 && rejected !== "0" && rejected !== 0) {
|
|
@@ -1468,6 +1472,14 @@ var init_http = __esm({
|
|
|
1468
1472
|
}
|
|
1469
1473
|
}
|
|
1470
1474
|
}
|
|
1475
|
+
/**
|
|
1476
|
+
* The server's assigned `traces.id` for a tracked trace if it has already
|
|
1477
|
+
* been read back off an ingest response, without stopping tracking. Lets a
|
|
1478
|
+
* replay surface the id mid-run for items whose spans already landed.
|
|
1479
|
+
*/
|
|
1480
|
+
peekServerTraceId(traceId) {
|
|
1481
|
+
return this.traceDeliveries.get(traceId)?.serverTraceId;
|
|
1482
|
+
}
|
|
1471
1483
|
/** Whether any tracked trace has had its closing carrier submitted. */
|
|
1472
1484
|
hasClosedDeliveries(traceIds) {
|
|
1473
1485
|
return traceIds.some((traceId) => this.traceDeliveries.get(traceId)?.closed);
|
|
@@ -1494,7 +1506,8 @@ var init_http = __esm({
|
|
|
1494
1506
|
closed: delivery.closed,
|
|
1495
1507
|
delivered: delivery.closingAcked && [...delivery.submittedSpanIds].every(
|
|
1496
1508
|
(spanId) => delivery.ackedSpanIds.has(spanId)
|
|
1497
|
-
)
|
|
1509
|
+
),
|
|
1510
|
+
serverTraceId: delivery.serverTraceId
|
|
1498
1511
|
};
|
|
1499
1512
|
}
|
|
1500
1513
|
return reports;
|
|
@@ -1523,6 +1536,23 @@ var init_http = __esm({
|
|
|
1523
1536
|
* delivered ref is proof its row exists: the same fact the replay status
|
|
1524
1537
|
* endpoint would report, already in hand.
|
|
1525
1538
|
*/
|
|
1539
|
+
/**
|
|
1540
|
+
* Record the server's assigned `traces.id` for each tracked source trace,
|
|
1541
|
+
* read back from the OTLP ingest response. Keyed by source trace id, the same
|
|
1542
|
+
* key the delivery ledger uses. Untracked ids are ignored.
|
|
1543
|
+
*/
|
|
1544
|
+
recordServerTraceIds(map) {
|
|
1545
|
+
for (const [sourceTraceId, serverTraceId] of Object.entries(map)) {
|
|
1546
|
+
if (typeof serverTraceId !== "string") {
|
|
1547
|
+
continue;
|
|
1548
|
+
}
|
|
1549
|
+
const delivery = this.traceDeliveries.get(sourceTraceId);
|
|
1550
|
+
if (delivery === void 0) {
|
|
1551
|
+
continue;
|
|
1552
|
+
}
|
|
1553
|
+
delivery.serverTraceId = serverTraceId;
|
|
1554
|
+
}
|
|
1555
|
+
}
|
|
1526
1556
|
recordDeliveredCarriers(refs) {
|
|
1527
1557
|
for (const ref of refs) {
|
|
1528
1558
|
const delivery = this.traceDeliveries.get(ref.traceId);
|
|
@@ -2364,6 +2394,7 @@ __export(replay_exports, {
|
|
|
2364
2394
|
replay: () => replay,
|
|
2365
2395
|
reportReplayProgress: () => reportReplayProgress,
|
|
2366
2396
|
serializeReplayResult: () => serializeReplayResult,
|
|
2397
|
+
sleepForReplayPersistence: () => sleepForReplayPersistence,
|
|
2367
2398
|
waitForReplayPersistence: () => waitForReplayPersistence
|
|
2368
2399
|
});
|
|
2369
2400
|
function dbBranchEnabled(dbBranch) {
|
|
@@ -2659,13 +2690,17 @@ async function waitForReplayPersistence(httpClient, testRunId, replayedTraceIds)
|
|
|
2659
2690
|
}
|
|
2660
2691
|
if (!httpClient.hasClosedDeliveries(replayedTraceIds)) {
|
|
2661
2692
|
httpClient.takeTraceDeliveries(replayedTraceIds);
|
|
2662
|
-
return;
|
|
2693
|
+
return {};
|
|
2663
2694
|
}
|
|
2664
2695
|
const flushed = await flushTraces(REPLAY_PERSISTENCE_TIMEOUT_MS);
|
|
2665
2696
|
const deliveries = httpClient.takeTraceDeliveries(replayedTraceIds);
|
|
2666
2697
|
const expectedSpanCounts = {};
|
|
2698
|
+
const readBackTraceIds = {};
|
|
2667
2699
|
let allDelivered = true;
|
|
2668
2700
|
for (const [traceId, delivery] of Object.entries(deliveries)) {
|
|
2701
|
+
if (delivery.serverTraceId !== void 0) {
|
|
2702
|
+
readBackTraceIds[traceId] = delivery.serverTraceId;
|
|
2703
|
+
}
|
|
2669
2704
|
if (!delivery.closed) {
|
|
2670
2705
|
continue;
|
|
2671
2706
|
}
|
|
@@ -2673,7 +2708,7 @@ async function waitForReplayPersistence(httpClient, testRunId, replayedTraceIds)
|
|
|
2673
2708
|
allDelivered = allDelivered && delivery.delivered;
|
|
2674
2709
|
}
|
|
2675
2710
|
if (allDelivered) {
|
|
2676
|
-
return;
|
|
2711
|
+
return readBackTraceIds;
|
|
2677
2712
|
}
|
|
2678
2713
|
const deadline = Date.now() + REPLAY_PERSISTENCE_TIMEOUT_MS;
|
|
2679
2714
|
let missing = Object.keys(expectedSpanCounts).length;
|
|
@@ -2687,22 +2722,23 @@ async function waitForReplayPersistence(httpClient, testRunId, replayedTraceIds)
|
|
|
2687
2722
|
(traceId) => ready[traceId] === void 0
|
|
2688
2723
|
).length;
|
|
2689
2724
|
if (missing === 0) {
|
|
2690
|
-
return;
|
|
2725
|
+
return readBackTraceIds;
|
|
2691
2726
|
}
|
|
2692
2727
|
if (Date.now() >= deadline) {
|
|
2693
2728
|
break;
|
|
2694
2729
|
}
|
|
2695
|
-
await
|
|
2730
|
+
await sleepForReplayPersistence(
|
|
2731
|
+
Math.min(100, Math.max(0, deadline - Date.now()))
|
|
2732
|
+
);
|
|
2696
2733
|
}
|
|
2697
2734
|
const cause = flushed ? "" : " Delivery was also not confirmed before the flush deadline, so the spans likely never reached the server.";
|
|
2698
2735
|
throw new BitfabError(
|
|
2699
2736
|
`Replay traces were not fully persisted before the delivery deadline (testRunId ${testRunId}, missing ${missing} of ${Object.keys(expectedSpanCounts).length} trace(s)).${cause}`
|
|
2700
2737
|
);
|
|
2701
2738
|
}
|
|
2702
|
-
function
|
|
2739
|
+
function sleepForReplayPersistence(ms) {
|
|
2703
2740
|
return new Promise((resolve) => {
|
|
2704
|
-
|
|
2705
|
-
unrefTimer(timer);
|
|
2741
|
+
setTimeout(resolve, ms);
|
|
2706
2742
|
});
|
|
2707
2743
|
}
|
|
2708
2744
|
async function mapWithConcurrency2(tasks, maxConcurrency, onSettled, onStarted) {
|
|
@@ -2714,7 +2750,7 @@ async function mapWithConcurrency2(tasks, maxConcurrency, onSettled, onStarted)
|
|
|
2714
2750
|
onStarted?.(index);
|
|
2715
2751
|
const result = await tasks[index]();
|
|
2716
2752
|
results[index] = result;
|
|
2717
|
-
onSettled?.(result, index);
|
|
2753
|
+
await onSettled?.(result, index);
|
|
2718
2754
|
}
|
|
2719
2755
|
}
|
|
2720
2756
|
const workers = Array.from(
|
|
@@ -2804,10 +2840,36 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
|
|
|
2804
2840
|
let started = 0;
|
|
2805
2841
|
let succeeded = 0;
|
|
2806
2842
|
let errored = 0;
|
|
2843
|
+
let flushInFlight = null;
|
|
2844
|
+
let flushPending = false;
|
|
2845
|
+
const flushFinishedItemTrace = () => {
|
|
2846
|
+
flushPending = true;
|
|
2847
|
+
if (!flushInFlight) {
|
|
2848
|
+
flushInFlight = (async () => {
|
|
2849
|
+
try {
|
|
2850
|
+
while (flushPending) {
|
|
2851
|
+
flushPending = false;
|
|
2852
|
+
await httpClient.settleDeferredWork(REPLAY_PERSISTENCE_TIMEOUT_MS);
|
|
2853
|
+
await flushTraces(REPLAY_PERSISTENCE_TIMEOUT_MS);
|
|
2854
|
+
}
|
|
2855
|
+
} finally {
|
|
2856
|
+
flushInFlight = null;
|
|
2857
|
+
}
|
|
2858
|
+
})();
|
|
2859
|
+
}
|
|
2860
|
+
return flushInFlight;
|
|
2861
|
+
};
|
|
2807
2862
|
const resultItems = await mapWithConcurrency2(
|
|
2808
2863
|
tasks,
|
|
2809
2864
|
maxConcurrency,
|
|
2810
|
-
(item) => {
|
|
2865
|
+
async (item, index) => {
|
|
2866
|
+
let serverTraceId = null;
|
|
2867
|
+
try {
|
|
2868
|
+
await flushFinishedItemTrace();
|
|
2869
|
+
serverTraceId = httpClient.peekServerTraceId(replayedTraceIds[index]) ?? null;
|
|
2870
|
+
} catch {
|
|
2871
|
+
}
|
|
2872
|
+
item.traceId = serverTraceId;
|
|
2811
2873
|
completed += 1;
|
|
2812
2874
|
if (item.error === null) {
|
|
2813
2875
|
succeeded += 1;
|
|
@@ -2822,11 +2884,12 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
|
|
|
2822
2884
|
succeeded,
|
|
2823
2885
|
errored,
|
|
2824
2886
|
item: {
|
|
2825
|
-
// The server
|
|
2826
|
-
//
|
|
2827
|
-
//
|
|
2828
|
-
//
|
|
2829
|
-
|
|
2887
|
+
// The server's assigned traces.id, read back off the ingest
|
|
2888
|
+
// response and surfaced as this item finishes. Null only if the
|
|
2889
|
+
// per-item flush could not confirm delivery in time; the end-of-run
|
|
2890
|
+
// barrier then fills the returned ReplayItem. The client-side
|
|
2891
|
+
// placeholder is never surfaced.
|
|
2892
|
+
traceId: serverTraceId,
|
|
2830
2893
|
originalTraceId: item.originalTraceId ?? null,
|
|
2831
2894
|
originalSpanId: item.originalSpanId ?? null,
|
|
2832
2895
|
// Deprecated aliases for originalTraceId/originalSpanId.
|
|
@@ -2872,12 +2935,19 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
|
|
|
2872
2935
|
}
|
|
2873
2936
|
} : void 0
|
|
2874
2937
|
);
|
|
2875
|
-
await preserveReplayFailure(
|
|
2938
|
+
const deliveredTraceIds = await preserveReplayFailure(
|
|
2876
2939
|
() => waitForReplayPersistence(httpClient, testRunId, replayedTraceIds),
|
|
2877
2940
|
resultItems,
|
|
2878
2941
|
testRunId,
|
|
2879
2942
|
fullTestRunUrl
|
|
2880
2943
|
);
|
|
2944
|
+
for (let index = 0; index < resultItems.length; index += 1) {
|
|
2945
|
+
const localId = replayedTraceIds[index];
|
|
2946
|
+
const readBack = localId ? deliveredTraceIds[localId] : void 0;
|
|
2947
|
+
if (readBack !== void 0) {
|
|
2948
|
+
resultItems[index].traceId = readBack;
|
|
2949
|
+
}
|
|
2950
|
+
}
|
|
2881
2951
|
const completeResult = await preserveReplayFailure(
|
|
2882
2952
|
() => httpClient.completeReplay(testRunId),
|
|
2883
2953
|
resultItems,
|
|
@@ -2893,7 +2963,7 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
|
|
|
2893
2963
|
const item = resultItems[index];
|
|
2894
2964
|
const localId = replayedTraceIds[index];
|
|
2895
2965
|
const mapped = localId ? serverTraceIds[localId] : void 0;
|
|
2896
|
-
item.traceId = mapped ?? null;
|
|
2966
|
+
item.traceId = item.traceId ?? mapped ?? null;
|
|
2897
2967
|
if (item.error === null) {
|
|
2898
2968
|
completedCount += 1;
|
|
2899
2969
|
if (mapped === void 0) {
|
|
@@ -2981,7 +3051,6 @@ var init_replay = __esm({
|
|
|
2981
3051
|
init_randomUuid();
|
|
2982
3052
|
init_replayContext();
|
|
2983
3053
|
init_serialize();
|
|
2984
|
-
init_unrefTimer();
|
|
2985
3054
|
REPLAY_PERSISTENCE_TIMEOUT_MS = 3e4;
|
|
2986
3055
|
BITFAB_PROGRESS_PREFIX = "@@bitfab:progress ";
|
|
2987
3056
|
ReplayError = class extends BitfabError {
|