@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
|
@@ -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
|
@@ -42,7 +42,7 @@ var __version__;
|
|
|
42
42
|
var init_version_generated = __esm({
|
|
43
43
|
"src/version.generated.ts"() {
|
|
44
44
|
"use strict";
|
|
45
|
-
__version__ = "0.36.
|
|
45
|
+
__version__ = "0.36.10";
|
|
46
46
|
}
|
|
47
47
|
});
|
|
48
48
|
|
|
@@ -1435,6 +1435,10 @@ var init_http = __esm({
|
|
|
1435
1435
|
...error instanceof BitfabError && error.retryAfterMs !== void 0 ? { retryAfterMs: error.retryAfterMs } : {}
|
|
1436
1436
|
});
|
|
1437
1437
|
}
|
|
1438
|
+
const serverTraceIds = asPayloadRecord(response?.traceIds);
|
|
1439
|
+
if (serverTraceIds !== void 0) {
|
|
1440
|
+
this.recordServerTraceIds(serverTraceIds);
|
|
1441
|
+
}
|
|
1438
1442
|
const partialSuccess = asPayloadRecord(response?.partialSuccess);
|
|
1439
1443
|
const rejected = partialSuccess?.rejectedSpans;
|
|
1440
1444
|
if (rejected !== void 0 && rejected !== "0" && rejected !== 0) {
|
|
@@ -1459,6 +1463,14 @@ var init_http = __esm({
|
|
|
1459
1463
|
}
|
|
1460
1464
|
}
|
|
1461
1465
|
}
|
|
1466
|
+
/**
|
|
1467
|
+
* The server's assigned `traces.id` for a tracked trace if it has already
|
|
1468
|
+
* been read back off an ingest response, without stopping tracking. Lets a
|
|
1469
|
+
* replay surface the id mid-run for items whose spans already landed.
|
|
1470
|
+
*/
|
|
1471
|
+
peekServerTraceId(traceId) {
|
|
1472
|
+
return this.traceDeliveries.get(traceId)?.serverTraceId;
|
|
1473
|
+
}
|
|
1462
1474
|
/** Whether any tracked trace has had its closing carrier submitted. */
|
|
1463
1475
|
hasClosedDeliveries(traceIds) {
|
|
1464
1476
|
return traceIds.some((traceId) => this.traceDeliveries.get(traceId)?.closed);
|
|
@@ -1485,7 +1497,8 @@ var init_http = __esm({
|
|
|
1485
1497
|
closed: delivery.closed,
|
|
1486
1498
|
delivered: delivery.closingAcked && [...delivery.submittedSpanIds].every(
|
|
1487
1499
|
(spanId) => delivery.ackedSpanIds.has(spanId)
|
|
1488
|
-
)
|
|
1500
|
+
),
|
|
1501
|
+
serverTraceId: delivery.serverTraceId
|
|
1489
1502
|
};
|
|
1490
1503
|
}
|
|
1491
1504
|
return reports;
|
|
@@ -1514,6 +1527,23 @@ var init_http = __esm({
|
|
|
1514
1527
|
* delivered ref is proof its row exists: the same fact the replay status
|
|
1515
1528
|
* endpoint would report, already in hand.
|
|
1516
1529
|
*/
|
|
1530
|
+
/**
|
|
1531
|
+
* Record the server's assigned `traces.id` for each tracked source trace,
|
|
1532
|
+
* read back from the OTLP ingest response. Keyed by source trace id, the same
|
|
1533
|
+
* key the delivery ledger uses. Untracked ids are ignored.
|
|
1534
|
+
*/
|
|
1535
|
+
recordServerTraceIds(map) {
|
|
1536
|
+
for (const [sourceTraceId, serverTraceId] of Object.entries(map)) {
|
|
1537
|
+
if (typeof serverTraceId !== "string") {
|
|
1538
|
+
continue;
|
|
1539
|
+
}
|
|
1540
|
+
const delivery = this.traceDeliveries.get(sourceTraceId);
|
|
1541
|
+
if (delivery === void 0) {
|
|
1542
|
+
continue;
|
|
1543
|
+
}
|
|
1544
|
+
delivery.serverTraceId = serverTraceId;
|
|
1545
|
+
}
|
|
1546
|
+
}
|
|
1517
1547
|
recordDeliveredCarriers(refs) {
|
|
1518
1548
|
for (const ref of refs) {
|
|
1519
1549
|
const delivery = this.traceDeliveries.get(ref.traceId);
|
|
@@ -2355,6 +2385,7 @@ __export(replay_exports, {
|
|
|
2355
2385
|
replay: () => replay,
|
|
2356
2386
|
reportReplayProgress: () => reportReplayProgress,
|
|
2357
2387
|
serializeReplayResult: () => serializeReplayResult,
|
|
2388
|
+
sleepForReplayPersistence: () => sleepForReplayPersistence,
|
|
2358
2389
|
waitForReplayPersistence: () => waitForReplayPersistence
|
|
2359
2390
|
});
|
|
2360
2391
|
function dbBranchEnabled(dbBranch) {
|
|
@@ -2650,13 +2681,17 @@ async function waitForReplayPersistence(httpClient, testRunId, replayedTraceIds)
|
|
|
2650
2681
|
}
|
|
2651
2682
|
if (!httpClient.hasClosedDeliveries(replayedTraceIds)) {
|
|
2652
2683
|
httpClient.takeTraceDeliveries(replayedTraceIds);
|
|
2653
|
-
return;
|
|
2684
|
+
return {};
|
|
2654
2685
|
}
|
|
2655
2686
|
const flushed = await flushTraces(REPLAY_PERSISTENCE_TIMEOUT_MS);
|
|
2656
2687
|
const deliveries = httpClient.takeTraceDeliveries(replayedTraceIds);
|
|
2657
2688
|
const expectedSpanCounts = {};
|
|
2689
|
+
const readBackTraceIds = {};
|
|
2658
2690
|
let allDelivered = true;
|
|
2659
2691
|
for (const [traceId, delivery] of Object.entries(deliveries)) {
|
|
2692
|
+
if (delivery.serverTraceId !== void 0) {
|
|
2693
|
+
readBackTraceIds[traceId] = delivery.serverTraceId;
|
|
2694
|
+
}
|
|
2660
2695
|
if (!delivery.closed) {
|
|
2661
2696
|
continue;
|
|
2662
2697
|
}
|
|
@@ -2664,7 +2699,7 @@ async function waitForReplayPersistence(httpClient, testRunId, replayedTraceIds)
|
|
|
2664
2699
|
allDelivered = allDelivered && delivery.delivered;
|
|
2665
2700
|
}
|
|
2666
2701
|
if (allDelivered) {
|
|
2667
|
-
return;
|
|
2702
|
+
return readBackTraceIds;
|
|
2668
2703
|
}
|
|
2669
2704
|
const deadline = Date.now() + REPLAY_PERSISTENCE_TIMEOUT_MS;
|
|
2670
2705
|
let missing = Object.keys(expectedSpanCounts).length;
|
|
@@ -2678,22 +2713,23 @@ async function waitForReplayPersistence(httpClient, testRunId, replayedTraceIds)
|
|
|
2678
2713
|
(traceId) => ready[traceId] === void 0
|
|
2679
2714
|
).length;
|
|
2680
2715
|
if (missing === 0) {
|
|
2681
|
-
return;
|
|
2716
|
+
return readBackTraceIds;
|
|
2682
2717
|
}
|
|
2683
2718
|
if (Date.now() >= deadline) {
|
|
2684
2719
|
break;
|
|
2685
2720
|
}
|
|
2686
|
-
await
|
|
2721
|
+
await sleepForReplayPersistence(
|
|
2722
|
+
Math.min(100, Math.max(0, deadline - Date.now()))
|
|
2723
|
+
);
|
|
2687
2724
|
}
|
|
2688
2725
|
const cause = flushed ? "" : " Delivery was also not confirmed before the flush deadline, so the spans likely never reached the server.";
|
|
2689
2726
|
throw new BitfabError(
|
|
2690
2727
|
`Replay traces were not fully persisted before the delivery deadline (testRunId ${testRunId}, missing ${missing} of ${Object.keys(expectedSpanCounts).length} trace(s)).${cause}`
|
|
2691
2728
|
);
|
|
2692
2729
|
}
|
|
2693
|
-
function
|
|
2730
|
+
function sleepForReplayPersistence(ms) {
|
|
2694
2731
|
return new Promise((resolve) => {
|
|
2695
|
-
|
|
2696
|
-
unrefTimer(timer);
|
|
2732
|
+
setTimeout(resolve, ms);
|
|
2697
2733
|
});
|
|
2698
2734
|
}
|
|
2699
2735
|
async function mapWithConcurrency2(tasks, maxConcurrency, onSettled, onStarted) {
|
|
@@ -2705,7 +2741,7 @@ async function mapWithConcurrency2(tasks, maxConcurrency, onSettled, onStarted)
|
|
|
2705
2741
|
onStarted?.(index);
|
|
2706
2742
|
const result = await tasks[index]();
|
|
2707
2743
|
results[index] = result;
|
|
2708
|
-
onSettled?.(result, index);
|
|
2744
|
+
await onSettled?.(result, index);
|
|
2709
2745
|
}
|
|
2710
2746
|
}
|
|
2711
2747
|
const workers = Array.from(
|
|
@@ -2795,10 +2831,36 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
|
|
|
2795
2831
|
let started = 0;
|
|
2796
2832
|
let succeeded = 0;
|
|
2797
2833
|
let errored = 0;
|
|
2834
|
+
let flushInFlight = null;
|
|
2835
|
+
let flushPending = false;
|
|
2836
|
+
const flushFinishedItemTrace = () => {
|
|
2837
|
+
flushPending = true;
|
|
2838
|
+
if (!flushInFlight) {
|
|
2839
|
+
flushInFlight = (async () => {
|
|
2840
|
+
try {
|
|
2841
|
+
while (flushPending) {
|
|
2842
|
+
flushPending = false;
|
|
2843
|
+
await httpClient.settleDeferredWork(REPLAY_PERSISTENCE_TIMEOUT_MS);
|
|
2844
|
+
await flushTraces(REPLAY_PERSISTENCE_TIMEOUT_MS);
|
|
2845
|
+
}
|
|
2846
|
+
} finally {
|
|
2847
|
+
flushInFlight = null;
|
|
2848
|
+
}
|
|
2849
|
+
})();
|
|
2850
|
+
}
|
|
2851
|
+
return flushInFlight;
|
|
2852
|
+
};
|
|
2798
2853
|
const resultItems = await mapWithConcurrency2(
|
|
2799
2854
|
tasks,
|
|
2800
2855
|
maxConcurrency,
|
|
2801
|
-
(item) => {
|
|
2856
|
+
async (item, index) => {
|
|
2857
|
+
let serverTraceId = null;
|
|
2858
|
+
try {
|
|
2859
|
+
await flushFinishedItemTrace();
|
|
2860
|
+
serverTraceId = httpClient.peekServerTraceId(replayedTraceIds[index]) ?? null;
|
|
2861
|
+
} catch {
|
|
2862
|
+
}
|
|
2863
|
+
item.traceId = serverTraceId;
|
|
2802
2864
|
completed += 1;
|
|
2803
2865
|
if (item.error === null) {
|
|
2804
2866
|
succeeded += 1;
|
|
@@ -2813,11 +2875,12 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
|
|
|
2813
2875
|
succeeded,
|
|
2814
2876
|
errored,
|
|
2815
2877
|
item: {
|
|
2816
|
-
// The server
|
|
2817
|
-
//
|
|
2818
|
-
//
|
|
2819
|
-
//
|
|
2820
|
-
|
|
2878
|
+
// The server's assigned traces.id, read back off the ingest
|
|
2879
|
+
// response and surfaced as this item finishes. Null only if the
|
|
2880
|
+
// per-item flush could not confirm delivery in time; the end-of-run
|
|
2881
|
+
// barrier then fills the returned ReplayItem. The client-side
|
|
2882
|
+
// placeholder is never surfaced.
|
|
2883
|
+
traceId: serverTraceId,
|
|
2821
2884
|
originalTraceId: item.originalTraceId ?? null,
|
|
2822
2885
|
originalSpanId: item.originalSpanId ?? null,
|
|
2823
2886
|
// Deprecated aliases for originalTraceId/originalSpanId.
|
|
@@ -2863,12 +2926,19 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
|
|
|
2863
2926
|
}
|
|
2864
2927
|
} : void 0
|
|
2865
2928
|
);
|
|
2866
|
-
await preserveReplayFailure(
|
|
2929
|
+
const deliveredTraceIds = await preserveReplayFailure(
|
|
2867
2930
|
() => waitForReplayPersistence(httpClient, testRunId, replayedTraceIds),
|
|
2868
2931
|
resultItems,
|
|
2869
2932
|
testRunId,
|
|
2870
2933
|
fullTestRunUrl
|
|
2871
2934
|
);
|
|
2935
|
+
for (let index = 0; index < resultItems.length; index += 1) {
|
|
2936
|
+
const localId = replayedTraceIds[index];
|
|
2937
|
+
const readBack = localId ? deliveredTraceIds[localId] : void 0;
|
|
2938
|
+
if (readBack !== void 0) {
|
|
2939
|
+
resultItems[index].traceId = readBack;
|
|
2940
|
+
}
|
|
2941
|
+
}
|
|
2872
2942
|
const completeResult = await preserveReplayFailure(
|
|
2873
2943
|
() => httpClient.completeReplay(testRunId),
|
|
2874
2944
|
resultItems,
|
|
@@ -2884,7 +2954,7 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
|
|
|
2884
2954
|
const item = resultItems[index];
|
|
2885
2955
|
const localId = replayedTraceIds[index];
|
|
2886
2956
|
const mapped = localId ? serverTraceIds[localId] : void 0;
|
|
2887
|
-
item.traceId = mapped ?? null;
|
|
2957
|
+
item.traceId = item.traceId ?? mapped ?? null;
|
|
2888
2958
|
if (item.error === null) {
|
|
2889
2959
|
completedCount += 1;
|
|
2890
2960
|
if (mapped === void 0) {
|
|
@@ -2972,7 +3042,6 @@ var init_replay = __esm({
|
|
|
2972
3042
|
init_randomUuid();
|
|
2973
3043
|
init_replayContext();
|
|
2974
3044
|
init_serialize();
|
|
2975
|
-
init_unrefTimer();
|
|
2976
3045
|
REPLAY_PERSISTENCE_TIMEOUT_MS = 3e4;
|
|
2977
3046
|
BITFAB_PROGRESS_PREFIX = "@@bitfab:progress ";
|
|
2978
3047
|
ReplayError = class extends BitfabError {
|