@bitfab/sdk 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
|
@@ -304,7 +304,7 @@ function encodeRequestBody(body) {
|
|
|
304
304
|
}
|
|
305
305
|
|
|
306
306
|
// src/version.generated.ts
|
|
307
|
-
var __version__ = "0.36.
|
|
307
|
+
var __version__ = "0.36.10";
|
|
308
308
|
|
|
309
309
|
// src/constants.ts
|
|
310
310
|
var DEFAULT_SERVICE_URL = "https://bitfab.ai";
|
|
@@ -1503,6 +1503,10 @@ var HttpClient = class {
|
|
|
1503
1503
|
...error instanceof BitfabError && error.retryAfterMs !== void 0 ? { retryAfterMs: error.retryAfterMs } : {}
|
|
1504
1504
|
});
|
|
1505
1505
|
}
|
|
1506
|
+
const serverTraceIds = asPayloadRecord(response?.traceIds);
|
|
1507
|
+
if (serverTraceIds !== void 0) {
|
|
1508
|
+
this.recordServerTraceIds(serverTraceIds);
|
|
1509
|
+
}
|
|
1506
1510
|
const partialSuccess = asPayloadRecord(response?.partialSuccess);
|
|
1507
1511
|
const rejected = partialSuccess?.rejectedSpans;
|
|
1508
1512
|
if (rejected !== void 0 && rejected !== "0" && rejected !== 0) {
|
|
@@ -1527,6 +1531,14 @@ var HttpClient = class {
|
|
|
1527
1531
|
}
|
|
1528
1532
|
}
|
|
1529
1533
|
}
|
|
1534
|
+
/**
|
|
1535
|
+
* The server's assigned `traces.id` for a tracked trace if it has already
|
|
1536
|
+
* been read back off an ingest response, without stopping tracking. Lets a
|
|
1537
|
+
* replay surface the id mid-run for items whose spans already landed.
|
|
1538
|
+
*/
|
|
1539
|
+
peekServerTraceId(traceId) {
|
|
1540
|
+
return this.traceDeliveries.get(traceId)?.serverTraceId;
|
|
1541
|
+
}
|
|
1530
1542
|
/** Whether any tracked trace has had its closing carrier submitted. */
|
|
1531
1543
|
hasClosedDeliveries(traceIds) {
|
|
1532
1544
|
return traceIds.some((traceId) => this.traceDeliveries.get(traceId)?.closed);
|
|
@@ -1553,7 +1565,8 @@ var HttpClient = class {
|
|
|
1553
1565
|
closed: delivery.closed,
|
|
1554
1566
|
delivered: delivery.closingAcked && [...delivery.submittedSpanIds].every(
|
|
1555
1567
|
(spanId) => delivery.ackedSpanIds.has(spanId)
|
|
1556
|
-
)
|
|
1568
|
+
),
|
|
1569
|
+
serverTraceId: delivery.serverTraceId
|
|
1557
1570
|
};
|
|
1558
1571
|
}
|
|
1559
1572
|
return reports;
|
|
@@ -1582,6 +1595,23 @@ var HttpClient = class {
|
|
|
1582
1595
|
* delivered ref is proof its row exists: the same fact the replay status
|
|
1583
1596
|
* endpoint would report, already in hand.
|
|
1584
1597
|
*/
|
|
1598
|
+
/**
|
|
1599
|
+
* Record the server's assigned `traces.id` for each tracked source trace,
|
|
1600
|
+
* read back from the OTLP ingest response. Keyed by source trace id, the same
|
|
1601
|
+
* key the delivery ledger uses. Untracked ids are ignored.
|
|
1602
|
+
*/
|
|
1603
|
+
recordServerTraceIds(map) {
|
|
1604
|
+
for (const [sourceTraceId, serverTraceId] of Object.entries(map)) {
|
|
1605
|
+
if (typeof serverTraceId !== "string") {
|
|
1606
|
+
continue;
|
|
1607
|
+
}
|
|
1608
|
+
const delivery = this.traceDeliveries.get(sourceTraceId);
|
|
1609
|
+
if (delivery === void 0) {
|
|
1610
|
+
continue;
|
|
1611
|
+
}
|
|
1612
|
+
delivery.serverTraceId = serverTraceId;
|
|
1613
|
+
}
|
|
1614
|
+
}
|
|
1585
1615
|
recordDeliveredCarriers(refs) {
|
|
1586
1616
|
for (const ref of refs) {
|
|
1587
1617
|
const delivery = this.traceDeliveries.get(ref.traceId);
|
|
@@ -2511,13 +2541,17 @@ async function waitForReplayPersistence(httpClient, testRunId, replayedTraceIds)
|
|
|
2511
2541
|
}
|
|
2512
2542
|
if (!httpClient.hasClosedDeliveries(replayedTraceIds)) {
|
|
2513
2543
|
httpClient.takeTraceDeliveries(replayedTraceIds);
|
|
2514
|
-
return;
|
|
2544
|
+
return {};
|
|
2515
2545
|
}
|
|
2516
2546
|
const flushed = await flushTraces(REPLAY_PERSISTENCE_TIMEOUT_MS);
|
|
2517
2547
|
const deliveries = httpClient.takeTraceDeliveries(replayedTraceIds);
|
|
2518
2548
|
const expectedSpanCounts = {};
|
|
2549
|
+
const readBackTraceIds = {};
|
|
2519
2550
|
let allDelivered = true;
|
|
2520
2551
|
for (const [traceId, delivery] of Object.entries(deliveries)) {
|
|
2552
|
+
if (delivery.serverTraceId !== void 0) {
|
|
2553
|
+
readBackTraceIds[traceId] = delivery.serverTraceId;
|
|
2554
|
+
}
|
|
2521
2555
|
if (!delivery.closed) {
|
|
2522
2556
|
continue;
|
|
2523
2557
|
}
|
|
@@ -2525,7 +2559,7 @@ async function waitForReplayPersistence(httpClient, testRunId, replayedTraceIds)
|
|
|
2525
2559
|
allDelivered = allDelivered && delivery.delivered;
|
|
2526
2560
|
}
|
|
2527
2561
|
if (allDelivered) {
|
|
2528
|
-
return;
|
|
2562
|
+
return readBackTraceIds;
|
|
2529
2563
|
}
|
|
2530
2564
|
const deadline = Date.now() + REPLAY_PERSISTENCE_TIMEOUT_MS;
|
|
2531
2565
|
let missing = Object.keys(expectedSpanCounts).length;
|
|
@@ -2539,22 +2573,23 @@ async function waitForReplayPersistence(httpClient, testRunId, replayedTraceIds)
|
|
|
2539
2573
|
(traceId) => ready[traceId] === void 0
|
|
2540
2574
|
).length;
|
|
2541
2575
|
if (missing === 0) {
|
|
2542
|
-
return;
|
|
2576
|
+
return readBackTraceIds;
|
|
2543
2577
|
}
|
|
2544
2578
|
if (Date.now() >= deadline) {
|
|
2545
2579
|
break;
|
|
2546
2580
|
}
|
|
2547
|
-
await
|
|
2581
|
+
await sleepForReplayPersistence(
|
|
2582
|
+
Math.min(100, Math.max(0, deadline - Date.now()))
|
|
2583
|
+
);
|
|
2548
2584
|
}
|
|
2549
2585
|
const cause = flushed ? "" : " Delivery was also not confirmed before the flush deadline, so the spans likely never reached the server.";
|
|
2550
2586
|
throw new BitfabError(
|
|
2551
2587
|
`Replay traces were not fully persisted before the delivery deadline (testRunId ${testRunId}, missing ${missing} of ${Object.keys(expectedSpanCounts).length} trace(s)).${cause}`
|
|
2552
2588
|
);
|
|
2553
2589
|
}
|
|
2554
|
-
function
|
|
2590
|
+
function sleepForReplayPersistence(ms) {
|
|
2555
2591
|
return new Promise((resolve) => {
|
|
2556
|
-
|
|
2557
|
-
unrefTimer(timer);
|
|
2592
|
+
setTimeout(resolve, ms);
|
|
2558
2593
|
});
|
|
2559
2594
|
}
|
|
2560
2595
|
async function mapWithConcurrency2(tasks, maxConcurrency, onSettled, onStarted) {
|
|
@@ -2566,7 +2601,7 @@ async function mapWithConcurrency2(tasks, maxConcurrency, onSettled, onStarted)
|
|
|
2566
2601
|
onStarted?.(index);
|
|
2567
2602
|
const result = await tasks[index]();
|
|
2568
2603
|
results[index] = result;
|
|
2569
|
-
onSettled?.(result, index);
|
|
2604
|
+
await onSettled?.(result, index);
|
|
2570
2605
|
}
|
|
2571
2606
|
}
|
|
2572
2607
|
const workers = Array.from(
|
|
@@ -2656,10 +2691,36 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
|
|
|
2656
2691
|
let started = 0;
|
|
2657
2692
|
let succeeded = 0;
|
|
2658
2693
|
let errored = 0;
|
|
2694
|
+
let flushInFlight = null;
|
|
2695
|
+
let flushPending = false;
|
|
2696
|
+
const flushFinishedItemTrace = () => {
|
|
2697
|
+
flushPending = true;
|
|
2698
|
+
if (!flushInFlight) {
|
|
2699
|
+
flushInFlight = (async () => {
|
|
2700
|
+
try {
|
|
2701
|
+
while (flushPending) {
|
|
2702
|
+
flushPending = false;
|
|
2703
|
+
await httpClient.settleDeferredWork(REPLAY_PERSISTENCE_TIMEOUT_MS);
|
|
2704
|
+
await flushTraces(REPLAY_PERSISTENCE_TIMEOUT_MS);
|
|
2705
|
+
}
|
|
2706
|
+
} finally {
|
|
2707
|
+
flushInFlight = null;
|
|
2708
|
+
}
|
|
2709
|
+
})();
|
|
2710
|
+
}
|
|
2711
|
+
return flushInFlight;
|
|
2712
|
+
};
|
|
2659
2713
|
const resultItems = await mapWithConcurrency2(
|
|
2660
2714
|
tasks,
|
|
2661
2715
|
maxConcurrency,
|
|
2662
|
-
(item) => {
|
|
2716
|
+
async (item, index) => {
|
|
2717
|
+
let serverTraceId = null;
|
|
2718
|
+
try {
|
|
2719
|
+
await flushFinishedItemTrace();
|
|
2720
|
+
serverTraceId = httpClient.peekServerTraceId(replayedTraceIds[index]) ?? null;
|
|
2721
|
+
} catch {
|
|
2722
|
+
}
|
|
2723
|
+
item.traceId = serverTraceId;
|
|
2663
2724
|
completed += 1;
|
|
2664
2725
|
if (item.error === null) {
|
|
2665
2726
|
succeeded += 1;
|
|
@@ -2674,11 +2735,12 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
|
|
|
2674
2735
|
succeeded,
|
|
2675
2736
|
errored,
|
|
2676
2737
|
item: {
|
|
2677
|
-
// The server
|
|
2678
|
-
//
|
|
2679
|
-
//
|
|
2680
|
-
//
|
|
2681
|
-
|
|
2738
|
+
// The server's assigned traces.id, read back off the ingest
|
|
2739
|
+
// response and surfaced as this item finishes. Null only if the
|
|
2740
|
+
// per-item flush could not confirm delivery in time; the end-of-run
|
|
2741
|
+
// barrier then fills the returned ReplayItem. The client-side
|
|
2742
|
+
// placeholder is never surfaced.
|
|
2743
|
+
traceId: serverTraceId,
|
|
2682
2744
|
originalTraceId: item.originalTraceId ?? null,
|
|
2683
2745
|
originalSpanId: item.originalSpanId ?? null,
|
|
2684
2746
|
// Deprecated aliases for originalTraceId/originalSpanId.
|
|
@@ -2724,12 +2786,19 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
|
|
|
2724
2786
|
}
|
|
2725
2787
|
} : void 0
|
|
2726
2788
|
);
|
|
2727
|
-
await preserveReplayFailure(
|
|
2789
|
+
const deliveredTraceIds = await preserveReplayFailure(
|
|
2728
2790
|
() => waitForReplayPersistence(httpClient, testRunId, replayedTraceIds),
|
|
2729
2791
|
resultItems,
|
|
2730
2792
|
testRunId,
|
|
2731
2793
|
fullTestRunUrl
|
|
2732
2794
|
);
|
|
2795
|
+
for (let index = 0; index < resultItems.length; index += 1) {
|
|
2796
|
+
const localId = replayedTraceIds[index];
|
|
2797
|
+
const readBack = localId ? deliveredTraceIds[localId] : void 0;
|
|
2798
|
+
if (readBack !== void 0) {
|
|
2799
|
+
resultItems[index].traceId = readBack;
|
|
2800
|
+
}
|
|
2801
|
+
}
|
|
2733
2802
|
const completeResult = await preserveReplayFailure(
|
|
2734
2803
|
() => httpClient.completeReplay(testRunId),
|
|
2735
2804
|
resultItems,
|
|
@@ -2745,7 +2814,7 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
|
|
|
2745
2814
|
const item = resultItems[index];
|
|
2746
2815
|
const localId = replayedTraceIds[index];
|
|
2747
2816
|
const mapped = localId ? serverTraceIds[localId] : void 0;
|
|
2748
|
-
item.traceId = mapped ?? null;
|
|
2817
|
+
item.traceId = item.traceId ?? mapped ?? null;
|
|
2749
2818
|
if (item.error === null) {
|
|
2750
2819
|
completedCount += 1;
|
|
2751
2820
|
if (mapped === void 0) {
|
|
@@ -2851,6 +2920,7 @@ export {
|
|
|
2851
2920
|
DbBranchReplayError,
|
|
2852
2921
|
serializeReplayResult,
|
|
2853
2922
|
waitForReplayPersistence,
|
|
2923
|
+
sleepForReplayPersistence,
|
|
2854
2924
|
replay
|
|
2855
2925
|
};
|
|
2856
|
-
//# sourceMappingURL=chunk-
|
|
2926
|
+
//# sourceMappingURL=chunk-AAMRJGZJ.js.map
|