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
package/dist/index.d.cts
CHANGED
|
@@ -353,6 +353,12 @@ interface DeliveryReport {
|
|
|
353
353
|
closed: boolean;
|
|
354
354
|
/** Every carrier submitted under this trace came back accepted. */
|
|
355
355
|
delivered: boolean;
|
|
356
|
+
/**
|
|
357
|
+
* The server's assigned `traces.id`, read back from the OTLP ingest response.
|
|
358
|
+
* Absent when talking to a server that predates this field, or before any
|
|
359
|
+
* carrier for the trace has been acked.
|
|
360
|
+
*/
|
|
361
|
+
serverTraceId?: string;
|
|
356
362
|
}
|
|
357
363
|
declare class HttpClient {
|
|
358
364
|
private readonly apiKey;
|
|
@@ -390,6 +396,12 @@ declare class HttpClient {
|
|
|
390
396
|
* that was never tracked, so ordinary tracing costs no bookkeeping at all.
|
|
391
397
|
*/
|
|
392
398
|
trackTraceDeliveries(traceIds: string[]): void;
|
|
399
|
+
/**
|
|
400
|
+
* The server's assigned `traces.id` for a tracked trace if it has already
|
|
401
|
+
* been read back off an ingest response, without stopping tracking. Lets a
|
|
402
|
+
* replay surface the id mid-run for items whose spans already landed.
|
|
403
|
+
*/
|
|
404
|
+
peekServerTraceId(traceId: string): string | undefined;
|
|
393
405
|
/** Whether any tracked trace has had its closing carrier submitted. */
|
|
394
406
|
hasClosedDeliveries(traceIds: string[]): boolean;
|
|
395
407
|
/**
|
|
@@ -410,6 +422,12 @@ declare class HttpClient {
|
|
|
410
422
|
* delivered ref is proof its row exists: the same fact the replay status
|
|
411
423
|
* endpoint would report, already in hand.
|
|
412
424
|
*/
|
|
425
|
+
/**
|
|
426
|
+
* Record the server's assigned `traces.id` for each tracked source trace,
|
|
427
|
+
* read back from the OTLP ingest response. Keyed by source trace id, the same
|
|
428
|
+
* key the delivery ledger uses. Untracked ids are ignored.
|
|
429
|
+
*/
|
|
430
|
+
private recordServerTraceIds;
|
|
413
431
|
private recordDeliveredCarriers;
|
|
414
432
|
/**
|
|
415
433
|
* Track deferred span work so this client's own lifecycle waits for it, and
|
|
@@ -2557,7 +2575,7 @@ declare class BitfabFunction {
|
|
|
2557
2575
|
/**
|
|
2558
2576
|
* SDK version from package.json (injected at build time)
|
|
2559
2577
|
*/
|
|
2560
|
-
declare const __version__ = "0.36.
|
|
2578
|
+
declare const __version__ = "0.36.10";
|
|
2561
2579
|
|
|
2562
2580
|
/**
|
|
2563
2581
|
* Constants for the Bitfab SDK.
|
package/dist/index.d.ts
CHANGED
|
@@ -353,6 +353,12 @@ interface DeliveryReport {
|
|
|
353
353
|
closed: boolean;
|
|
354
354
|
/** Every carrier submitted under this trace came back accepted. */
|
|
355
355
|
delivered: boolean;
|
|
356
|
+
/**
|
|
357
|
+
* The server's assigned `traces.id`, read back from the OTLP ingest response.
|
|
358
|
+
* Absent when talking to a server that predates this field, or before any
|
|
359
|
+
* carrier for the trace has been acked.
|
|
360
|
+
*/
|
|
361
|
+
serverTraceId?: string;
|
|
356
362
|
}
|
|
357
363
|
declare class HttpClient {
|
|
358
364
|
private readonly apiKey;
|
|
@@ -390,6 +396,12 @@ declare class HttpClient {
|
|
|
390
396
|
* that was never tracked, so ordinary tracing costs no bookkeeping at all.
|
|
391
397
|
*/
|
|
392
398
|
trackTraceDeliveries(traceIds: string[]): void;
|
|
399
|
+
/**
|
|
400
|
+
* The server's assigned `traces.id` for a tracked trace if it has already
|
|
401
|
+
* been read back off an ingest response, without stopping tracking. Lets a
|
|
402
|
+
* replay surface the id mid-run for items whose spans already landed.
|
|
403
|
+
*/
|
|
404
|
+
peekServerTraceId(traceId: string): string | undefined;
|
|
393
405
|
/** Whether any tracked trace has had its closing carrier submitted. */
|
|
394
406
|
hasClosedDeliveries(traceIds: string[]): boolean;
|
|
395
407
|
/**
|
|
@@ -410,6 +422,12 @@ declare class HttpClient {
|
|
|
410
422
|
* delivered ref is proof its row exists: the same fact the replay status
|
|
411
423
|
* endpoint would report, already in hand.
|
|
412
424
|
*/
|
|
425
|
+
/**
|
|
426
|
+
* Record the server's assigned `traces.id` for each tracked source trace,
|
|
427
|
+
* read back from the OTLP ingest response. Keyed by source trace id, the same
|
|
428
|
+
* key the delivery ledger uses. Untracked ids are ignored.
|
|
429
|
+
*/
|
|
430
|
+
private recordServerTraceIds;
|
|
413
431
|
private recordDeliveredCarriers;
|
|
414
432
|
/**
|
|
415
433
|
* Track deferred span work so this client's own lifecycle waits for it, and
|
|
@@ -2557,7 +2575,7 @@ declare class BitfabFunction {
|
|
|
2557
2575
|
/**
|
|
2558
2576
|
* SDK version from package.json (injected at build time)
|
|
2559
2577
|
*/
|
|
2560
|
-
declare const __version__ = "0.36.
|
|
2578
|
+
declare const __version__ = "0.36.10";
|
|
2561
2579
|
|
|
2562
2580
|
/**
|
|
2563
2581
|
* Constants for the Bitfab SDK.
|
package/dist/index.js
CHANGED
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
getCurrentReplayBranch,
|
|
21
21
|
getCurrentSpan,
|
|
22
22
|
getCurrentTrace
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-RSM2TLKG.js";
|
|
24
24
|
import {
|
|
25
25
|
BITFAB_PROGRESS_PREFIX,
|
|
26
26
|
BitfabError,
|
|
@@ -32,7 +32,7 @@ import {
|
|
|
32
32
|
flushTraces,
|
|
33
33
|
reportReplayProgress,
|
|
34
34
|
serializeReplayResult
|
|
35
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-AAMRJGZJ.js";
|
|
36
36
|
export {
|
|
37
37
|
BITFAB_PROGRESS_PREFIX,
|
|
38
38
|
Bitfab,
|
package/dist/node.cjs
CHANGED
|
@@ -97,7 +97,7 @@ var __version__;
|
|
|
97
97
|
var init_version_generated = __esm({
|
|
98
98
|
"src/version.generated.ts"() {
|
|
99
99
|
"use strict";
|
|
100
|
-
__version__ = "0.36.
|
|
100
|
+
__version__ = "0.36.10";
|
|
101
101
|
}
|
|
102
102
|
});
|
|
103
103
|
|
|
@@ -1451,6 +1451,10 @@ var init_http = __esm({
|
|
|
1451
1451
|
...error instanceof BitfabError && error.retryAfterMs !== void 0 ? { retryAfterMs: error.retryAfterMs } : {}
|
|
1452
1452
|
});
|
|
1453
1453
|
}
|
|
1454
|
+
const serverTraceIds = asPayloadRecord(response?.traceIds);
|
|
1455
|
+
if (serverTraceIds !== void 0) {
|
|
1456
|
+
this.recordServerTraceIds(serverTraceIds);
|
|
1457
|
+
}
|
|
1454
1458
|
const partialSuccess = asPayloadRecord(response?.partialSuccess);
|
|
1455
1459
|
const rejected = partialSuccess?.rejectedSpans;
|
|
1456
1460
|
if (rejected !== void 0 && rejected !== "0" && rejected !== 0) {
|
|
@@ -1475,6 +1479,14 @@ var init_http = __esm({
|
|
|
1475
1479
|
}
|
|
1476
1480
|
}
|
|
1477
1481
|
}
|
|
1482
|
+
/**
|
|
1483
|
+
* The server's assigned `traces.id` for a tracked trace if it has already
|
|
1484
|
+
* been read back off an ingest response, without stopping tracking. Lets a
|
|
1485
|
+
* replay surface the id mid-run for items whose spans already landed.
|
|
1486
|
+
*/
|
|
1487
|
+
peekServerTraceId(traceId) {
|
|
1488
|
+
return this.traceDeliveries.get(traceId)?.serverTraceId;
|
|
1489
|
+
}
|
|
1478
1490
|
/** Whether any tracked trace has had its closing carrier submitted. */
|
|
1479
1491
|
hasClosedDeliveries(traceIds) {
|
|
1480
1492
|
return traceIds.some((traceId) => this.traceDeliveries.get(traceId)?.closed);
|
|
@@ -1501,7 +1513,8 @@ var init_http = __esm({
|
|
|
1501
1513
|
closed: delivery.closed,
|
|
1502
1514
|
delivered: delivery.closingAcked && [...delivery.submittedSpanIds].every(
|
|
1503
1515
|
(spanId) => delivery.ackedSpanIds.has(spanId)
|
|
1504
|
-
)
|
|
1516
|
+
),
|
|
1517
|
+
serverTraceId: delivery.serverTraceId
|
|
1505
1518
|
};
|
|
1506
1519
|
}
|
|
1507
1520
|
return reports;
|
|
@@ -1530,6 +1543,23 @@ var init_http = __esm({
|
|
|
1530
1543
|
* delivered ref is proof its row exists: the same fact the replay status
|
|
1531
1544
|
* endpoint would report, already in hand.
|
|
1532
1545
|
*/
|
|
1546
|
+
/**
|
|
1547
|
+
* Record the server's assigned `traces.id` for each tracked source trace,
|
|
1548
|
+
* read back from the OTLP ingest response. Keyed by source trace id, the same
|
|
1549
|
+
* key the delivery ledger uses. Untracked ids are ignored.
|
|
1550
|
+
*/
|
|
1551
|
+
recordServerTraceIds(map) {
|
|
1552
|
+
for (const [sourceTraceId, serverTraceId] of Object.entries(map)) {
|
|
1553
|
+
if (typeof serverTraceId !== "string") {
|
|
1554
|
+
continue;
|
|
1555
|
+
}
|
|
1556
|
+
const delivery = this.traceDeliveries.get(sourceTraceId);
|
|
1557
|
+
if (delivery === void 0) {
|
|
1558
|
+
continue;
|
|
1559
|
+
}
|
|
1560
|
+
delivery.serverTraceId = serverTraceId;
|
|
1561
|
+
}
|
|
1562
|
+
}
|
|
1533
1563
|
recordDeliveredCarriers(refs) {
|
|
1534
1564
|
for (const ref of refs) {
|
|
1535
1565
|
const delivery = this.traceDeliveries.get(ref.traceId);
|
|
@@ -2371,6 +2401,7 @@ __export(replay_exports, {
|
|
|
2371
2401
|
replay: () => replay,
|
|
2372
2402
|
reportReplayProgress: () => reportReplayProgress,
|
|
2373
2403
|
serializeReplayResult: () => serializeReplayResult,
|
|
2404
|
+
sleepForReplayPersistence: () => sleepForReplayPersistence,
|
|
2374
2405
|
waitForReplayPersistence: () => waitForReplayPersistence
|
|
2375
2406
|
});
|
|
2376
2407
|
function dbBranchEnabled(dbBranch) {
|
|
@@ -2666,13 +2697,17 @@ async function waitForReplayPersistence(httpClient, testRunId, replayedTraceIds)
|
|
|
2666
2697
|
}
|
|
2667
2698
|
if (!httpClient.hasClosedDeliveries(replayedTraceIds)) {
|
|
2668
2699
|
httpClient.takeTraceDeliveries(replayedTraceIds);
|
|
2669
|
-
return;
|
|
2700
|
+
return {};
|
|
2670
2701
|
}
|
|
2671
2702
|
const flushed = await flushTraces(REPLAY_PERSISTENCE_TIMEOUT_MS);
|
|
2672
2703
|
const deliveries = httpClient.takeTraceDeliveries(replayedTraceIds);
|
|
2673
2704
|
const expectedSpanCounts = {};
|
|
2705
|
+
const readBackTraceIds = {};
|
|
2674
2706
|
let allDelivered = true;
|
|
2675
2707
|
for (const [traceId, delivery] of Object.entries(deliveries)) {
|
|
2708
|
+
if (delivery.serverTraceId !== void 0) {
|
|
2709
|
+
readBackTraceIds[traceId] = delivery.serverTraceId;
|
|
2710
|
+
}
|
|
2676
2711
|
if (!delivery.closed) {
|
|
2677
2712
|
continue;
|
|
2678
2713
|
}
|
|
@@ -2680,7 +2715,7 @@ async function waitForReplayPersistence(httpClient, testRunId, replayedTraceIds)
|
|
|
2680
2715
|
allDelivered = allDelivered && delivery.delivered;
|
|
2681
2716
|
}
|
|
2682
2717
|
if (allDelivered) {
|
|
2683
|
-
return;
|
|
2718
|
+
return readBackTraceIds;
|
|
2684
2719
|
}
|
|
2685
2720
|
const deadline = Date.now() + REPLAY_PERSISTENCE_TIMEOUT_MS;
|
|
2686
2721
|
let missing = Object.keys(expectedSpanCounts).length;
|
|
@@ -2694,22 +2729,23 @@ async function waitForReplayPersistence(httpClient, testRunId, replayedTraceIds)
|
|
|
2694
2729
|
(traceId) => ready[traceId] === void 0
|
|
2695
2730
|
).length;
|
|
2696
2731
|
if (missing === 0) {
|
|
2697
|
-
return;
|
|
2732
|
+
return readBackTraceIds;
|
|
2698
2733
|
}
|
|
2699
2734
|
if (Date.now() >= deadline) {
|
|
2700
2735
|
break;
|
|
2701
2736
|
}
|
|
2702
|
-
await
|
|
2737
|
+
await sleepForReplayPersistence(
|
|
2738
|
+
Math.min(100, Math.max(0, deadline - Date.now()))
|
|
2739
|
+
);
|
|
2703
2740
|
}
|
|
2704
2741
|
const cause = flushed ? "" : " Delivery was also not confirmed before the flush deadline, so the spans likely never reached the server.";
|
|
2705
2742
|
throw new BitfabError(
|
|
2706
2743
|
`Replay traces were not fully persisted before the delivery deadline (testRunId ${testRunId}, missing ${missing} of ${Object.keys(expectedSpanCounts).length} trace(s)).${cause}`
|
|
2707
2744
|
);
|
|
2708
2745
|
}
|
|
2709
|
-
function
|
|
2746
|
+
function sleepForReplayPersistence(ms) {
|
|
2710
2747
|
return new Promise((resolve) => {
|
|
2711
|
-
|
|
2712
|
-
unrefTimer(timer);
|
|
2748
|
+
setTimeout(resolve, ms);
|
|
2713
2749
|
});
|
|
2714
2750
|
}
|
|
2715
2751
|
async function mapWithConcurrency2(tasks, maxConcurrency, onSettled, onStarted) {
|
|
@@ -2721,7 +2757,7 @@ async function mapWithConcurrency2(tasks, maxConcurrency, onSettled, onStarted)
|
|
|
2721
2757
|
onStarted?.(index);
|
|
2722
2758
|
const result = await tasks[index]();
|
|
2723
2759
|
results[index] = result;
|
|
2724
|
-
onSettled?.(result, index);
|
|
2760
|
+
await onSettled?.(result, index);
|
|
2725
2761
|
}
|
|
2726
2762
|
}
|
|
2727
2763
|
const workers = Array.from(
|
|
@@ -2811,10 +2847,36 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
|
|
|
2811
2847
|
let started = 0;
|
|
2812
2848
|
let succeeded = 0;
|
|
2813
2849
|
let errored = 0;
|
|
2850
|
+
let flushInFlight = null;
|
|
2851
|
+
let flushPending = false;
|
|
2852
|
+
const flushFinishedItemTrace = () => {
|
|
2853
|
+
flushPending = true;
|
|
2854
|
+
if (!flushInFlight) {
|
|
2855
|
+
flushInFlight = (async () => {
|
|
2856
|
+
try {
|
|
2857
|
+
while (flushPending) {
|
|
2858
|
+
flushPending = false;
|
|
2859
|
+
await httpClient.settleDeferredWork(REPLAY_PERSISTENCE_TIMEOUT_MS);
|
|
2860
|
+
await flushTraces(REPLAY_PERSISTENCE_TIMEOUT_MS);
|
|
2861
|
+
}
|
|
2862
|
+
} finally {
|
|
2863
|
+
flushInFlight = null;
|
|
2864
|
+
}
|
|
2865
|
+
})();
|
|
2866
|
+
}
|
|
2867
|
+
return flushInFlight;
|
|
2868
|
+
};
|
|
2814
2869
|
const resultItems = await mapWithConcurrency2(
|
|
2815
2870
|
tasks,
|
|
2816
2871
|
maxConcurrency,
|
|
2817
|
-
(item) => {
|
|
2872
|
+
async (item, index) => {
|
|
2873
|
+
let serverTraceId = null;
|
|
2874
|
+
try {
|
|
2875
|
+
await flushFinishedItemTrace();
|
|
2876
|
+
serverTraceId = httpClient.peekServerTraceId(replayedTraceIds[index]) ?? null;
|
|
2877
|
+
} catch {
|
|
2878
|
+
}
|
|
2879
|
+
item.traceId = serverTraceId;
|
|
2818
2880
|
completed += 1;
|
|
2819
2881
|
if (item.error === null) {
|
|
2820
2882
|
succeeded += 1;
|
|
@@ -2829,11 +2891,12 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
|
|
|
2829
2891
|
succeeded,
|
|
2830
2892
|
errored,
|
|
2831
2893
|
item: {
|
|
2832
|
-
// The server
|
|
2833
|
-
//
|
|
2834
|
-
//
|
|
2835
|
-
//
|
|
2836
|
-
|
|
2894
|
+
// The server's assigned traces.id, read back off the ingest
|
|
2895
|
+
// response and surfaced as this item finishes. Null only if the
|
|
2896
|
+
// per-item flush could not confirm delivery in time; the end-of-run
|
|
2897
|
+
// barrier then fills the returned ReplayItem. The client-side
|
|
2898
|
+
// placeholder is never surfaced.
|
|
2899
|
+
traceId: serverTraceId,
|
|
2837
2900
|
originalTraceId: item.originalTraceId ?? null,
|
|
2838
2901
|
originalSpanId: item.originalSpanId ?? null,
|
|
2839
2902
|
// Deprecated aliases for originalTraceId/originalSpanId.
|
|
@@ -2879,12 +2942,19 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
|
|
|
2879
2942
|
}
|
|
2880
2943
|
} : void 0
|
|
2881
2944
|
);
|
|
2882
|
-
await preserveReplayFailure(
|
|
2945
|
+
const deliveredTraceIds = await preserveReplayFailure(
|
|
2883
2946
|
() => waitForReplayPersistence(httpClient, testRunId, replayedTraceIds),
|
|
2884
2947
|
resultItems,
|
|
2885
2948
|
testRunId,
|
|
2886
2949
|
fullTestRunUrl
|
|
2887
2950
|
);
|
|
2951
|
+
for (let index = 0; index < resultItems.length; index += 1) {
|
|
2952
|
+
const localId = replayedTraceIds[index];
|
|
2953
|
+
const readBack = localId ? deliveredTraceIds[localId] : void 0;
|
|
2954
|
+
if (readBack !== void 0) {
|
|
2955
|
+
resultItems[index].traceId = readBack;
|
|
2956
|
+
}
|
|
2957
|
+
}
|
|
2888
2958
|
const completeResult = await preserveReplayFailure(
|
|
2889
2959
|
() => httpClient.completeReplay(testRunId),
|
|
2890
2960
|
resultItems,
|
|
@@ -2900,7 +2970,7 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
|
|
|
2900
2970
|
const item = resultItems[index];
|
|
2901
2971
|
const localId = replayedTraceIds[index];
|
|
2902
2972
|
const mapped = localId ? serverTraceIds[localId] : void 0;
|
|
2903
|
-
item.traceId = mapped ?? null;
|
|
2973
|
+
item.traceId = item.traceId ?? mapped ?? null;
|
|
2904
2974
|
if (item.error === null) {
|
|
2905
2975
|
completedCount += 1;
|
|
2906
2976
|
if (mapped === void 0) {
|
|
@@ -2988,7 +3058,6 @@ var init_replay = __esm({
|
|
|
2988
3058
|
init_randomUuid();
|
|
2989
3059
|
init_replayContext();
|
|
2990
3060
|
init_serialize();
|
|
2991
|
-
init_unrefTimer();
|
|
2992
3061
|
REPLAY_PERSISTENCE_TIMEOUT_MS = 3e4;
|
|
2993
3062
|
BITFAB_PROGRESS_PREFIX = "@@bitfab:progress ";
|
|
2994
3063
|
ReplayError = class extends BitfabError {
|