bitfab 0.36.9 → 0.36.11
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-MBKY42QC.js → chunk-EKOAKLZC.js} +100 -22
- package/dist/chunk-EKOAKLZC.js.map +1 -0
- package/dist/{chunk-TJAFKZ4X.js → chunk-VDFPZYLH.js} +3 -3
- package/dist/index.cjs +99 -21
- 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 +99 -21
- package/dist/node.cjs.map +1 -1
- package/dist/node.js +2 -2
- package/dist/{replay-MH5QFXET.js → replay-TW3ONJ3W.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-MBKY42QC.js.map +0 -1
- /package/dist/{chunk-TJAFKZ4X.js.map → chunk-VDFPZYLH.js.map} +0 -0
- /package/dist/{replay-MH5QFXET.js.map → replay-TW3ONJ3W.js.map} +0 -0
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
toJsonSafe,
|
|
17
17
|
toJsonSafeReport,
|
|
18
18
|
warnOnce
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-EKOAKLZC.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-TW3ONJ3W.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-VDFPZYLH.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.11";
|
|
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);
|
|
@@ -2239,7 +2269,7 @@ async function captureCodeChangeFromGit(cwd, label) {
|
|
|
2239
2269
|
const tracked = await git(root, [
|
|
2240
2270
|
"diff",
|
|
2241
2271
|
"--name-status",
|
|
2242
|
-
"--
|
|
2272
|
+
"--find-renames",
|
|
2243
2273
|
"-z",
|
|
2244
2274
|
base,
|
|
2245
2275
|
"--",
|
|
@@ -2255,23 +2285,23 @@ async function captureCodeChangeFromGit(cwd, label) {
|
|
|
2255
2285
|
]);
|
|
2256
2286
|
const entries = [
|
|
2257
2287
|
...parseNameStatusZ(tracked ?? ""),
|
|
2258
|
-
...(untracked ?? "").split(NUL).filter((p) => p.length > 0).map((path) => ({ status: "A", path }))
|
|
2288
|
+
...(untracked ?? "").split(NUL).filter((p) => p.length > 0).map((path) => ({ status: "A", beforePath: path, path }))
|
|
2259
2289
|
];
|
|
2260
2290
|
if (entries.length === 0) {
|
|
2261
2291
|
return null;
|
|
2262
2292
|
}
|
|
2263
2293
|
const files = [];
|
|
2264
2294
|
let totalBytes = 0;
|
|
2265
|
-
for (const { status, path } of entries) {
|
|
2295
|
+
for (const { status, beforePath, path } of entries) {
|
|
2266
2296
|
if (files.length >= MAX_FILES) {
|
|
2267
2297
|
break;
|
|
2268
2298
|
}
|
|
2269
|
-
const beforeBytes = status === "A" ? 0 : await blobBytes(base,
|
|
2299
|
+
const beforeBytes = status === "A" ? 0 : await blobBytes(base, beforePath);
|
|
2270
2300
|
const afterBytes = status === "D" ? 0 : await workingBytes(path);
|
|
2271
2301
|
if (beforeBytes > MAX_FILE_BYTES || afterBytes > MAX_FILE_BYTES) {
|
|
2272
2302
|
continue;
|
|
2273
2303
|
}
|
|
2274
|
-
const before = (status === "A" ? "" : await git(root, ["show", `${base}:${
|
|
2304
|
+
const before = (status === "A" ? "" : await git(root, ["show", `${base}:${beforePath}`]) ?? "").replace(/\r\n/g, "\n");
|
|
2275
2305
|
const after = (status === "D" ? "" : await readWorkingFile(readFile, root, path)).replace(/\r\n/g, "\n");
|
|
2276
2306
|
if (before === after) {
|
|
2277
2307
|
continue;
|
|
@@ -2329,8 +2359,18 @@ async function readWorkingFile(readFile, root, path) {
|
|
|
2329
2359
|
function parseNameStatusZ(raw) {
|
|
2330
2360
|
const parts = raw.split(NUL).filter((p) => p.length > 0);
|
|
2331
2361
|
const out = [];
|
|
2332
|
-
|
|
2333
|
-
|
|
2362
|
+
let i = 0;
|
|
2363
|
+
while (i + 1 < parts.length) {
|
|
2364
|
+
const status = parts[i].charAt(0);
|
|
2365
|
+
i += 1;
|
|
2366
|
+
const beforePath = parts[i];
|
|
2367
|
+
i += 1;
|
|
2368
|
+
if ((status === "R" || status === "C") && i < parts.length) {
|
|
2369
|
+
out.push({ status, beforePath, path: parts[i] });
|
|
2370
|
+
i += 1;
|
|
2371
|
+
} else {
|
|
2372
|
+
out.push({ status, beforePath, path: beforePath });
|
|
2373
|
+
}
|
|
2334
2374
|
}
|
|
2335
2375
|
return out;
|
|
2336
2376
|
}
|
|
@@ -2660,13 +2700,17 @@ async function waitForReplayPersistence(httpClient, testRunId, replayedTraceIds)
|
|
|
2660
2700
|
}
|
|
2661
2701
|
if (!httpClient.hasClosedDeliveries(replayedTraceIds)) {
|
|
2662
2702
|
httpClient.takeTraceDeliveries(replayedTraceIds);
|
|
2663
|
-
return;
|
|
2703
|
+
return {};
|
|
2664
2704
|
}
|
|
2665
2705
|
const flushed = await flushTraces(REPLAY_PERSISTENCE_TIMEOUT_MS);
|
|
2666
2706
|
const deliveries = httpClient.takeTraceDeliveries(replayedTraceIds);
|
|
2667
2707
|
const expectedSpanCounts = {};
|
|
2708
|
+
const readBackTraceIds = {};
|
|
2668
2709
|
let allDelivered = true;
|
|
2669
2710
|
for (const [traceId, delivery] of Object.entries(deliveries)) {
|
|
2711
|
+
if (delivery.serverTraceId !== void 0) {
|
|
2712
|
+
readBackTraceIds[traceId] = delivery.serverTraceId;
|
|
2713
|
+
}
|
|
2670
2714
|
if (!delivery.closed) {
|
|
2671
2715
|
continue;
|
|
2672
2716
|
}
|
|
@@ -2674,7 +2718,7 @@ async function waitForReplayPersistence(httpClient, testRunId, replayedTraceIds)
|
|
|
2674
2718
|
allDelivered = allDelivered && delivery.delivered;
|
|
2675
2719
|
}
|
|
2676
2720
|
if (allDelivered) {
|
|
2677
|
-
return;
|
|
2721
|
+
return readBackTraceIds;
|
|
2678
2722
|
}
|
|
2679
2723
|
const deadline = Date.now() + REPLAY_PERSISTENCE_TIMEOUT_MS;
|
|
2680
2724
|
let missing = Object.keys(expectedSpanCounts).length;
|
|
@@ -2688,7 +2732,7 @@ async function waitForReplayPersistence(httpClient, testRunId, replayedTraceIds)
|
|
|
2688
2732
|
(traceId) => ready[traceId] === void 0
|
|
2689
2733
|
).length;
|
|
2690
2734
|
if (missing === 0) {
|
|
2691
|
-
return;
|
|
2735
|
+
return readBackTraceIds;
|
|
2692
2736
|
}
|
|
2693
2737
|
if (Date.now() >= deadline) {
|
|
2694
2738
|
break;
|
|
@@ -2716,7 +2760,7 @@ async function mapWithConcurrency2(tasks, maxConcurrency, onSettled, onStarted)
|
|
|
2716
2760
|
onStarted?.(index);
|
|
2717
2761
|
const result = await tasks[index]();
|
|
2718
2762
|
results[index] = result;
|
|
2719
|
-
onSettled?.(result, index);
|
|
2763
|
+
await onSettled?.(result, index);
|
|
2720
2764
|
}
|
|
2721
2765
|
}
|
|
2722
2766
|
const workers = Array.from(
|
|
@@ -2806,10 +2850,36 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
|
|
|
2806
2850
|
let started = 0;
|
|
2807
2851
|
let succeeded = 0;
|
|
2808
2852
|
let errored = 0;
|
|
2853
|
+
let flushInFlight = null;
|
|
2854
|
+
let flushPending = false;
|
|
2855
|
+
const flushFinishedItemTrace = () => {
|
|
2856
|
+
flushPending = true;
|
|
2857
|
+
if (!flushInFlight) {
|
|
2858
|
+
flushInFlight = (async () => {
|
|
2859
|
+
try {
|
|
2860
|
+
while (flushPending) {
|
|
2861
|
+
flushPending = false;
|
|
2862
|
+
await httpClient.settleDeferredWork(REPLAY_PERSISTENCE_TIMEOUT_MS);
|
|
2863
|
+
await flushTraces(REPLAY_PERSISTENCE_TIMEOUT_MS);
|
|
2864
|
+
}
|
|
2865
|
+
} finally {
|
|
2866
|
+
flushInFlight = null;
|
|
2867
|
+
}
|
|
2868
|
+
})();
|
|
2869
|
+
}
|
|
2870
|
+
return flushInFlight;
|
|
2871
|
+
};
|
|
2809
2872
|
const resultItems = await mapWithConcurrency2(
|
|
2810
2873
|
tasks,
|
|
2811
2874
|
maxConcurrency,
|
|
2812
|
-
(item) => {
|
|
2875
|
+
async (item, index) => {
|
|
2876
|
+
let serverTraceId = null;
|
|
2877
|
+
try {
|
|
2878
|
+
await flushFinishedItemTrace();
|
|
2879
|
+
serverTraceId = httpClient.peekServerTraceId(replayedTraceIds[index]) ?? null;
|
|
2880
|
+
} catch {
|
|
2881
|
+
}
|
|
2882
|
+
item.traceId = serverTraceId;
|
|
2813
2883
|
completed += 1;
|
|
2814
2884
|
if (item.error === null) {
|
|
2815
2885
|
succeeded += 1;
|
|
@@ -2824,11 +2894,12 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
|
|
|
2824
2894
|
succeeded,
|
|
2825
2895
|
errored,
|
|
2826
2896
|
item: {
|
|
2827
|
-
// The server
|
|
2828
|
-
//
|
|
2829
|
-
//
|
|
2830
|
-
//
|
|
2831
|
-
|
|
2897
|
+
// The server's assigned traces.id, read back off the ingest
|
|
2898
|
+
// response and surfaced as this item finishes. Null only if the
|
|
2899
|
+
// per-item flush could not confirm delivery in time; the end-of-run
|
|
2900
|
+
// barrier then fills the returned ReplayItem. The client-side
|
|
2901
|
+
// placeholder is never surfaced.
|
|
2902
|
+
traceId: serverTraceId,
|
|
2832
2903
|
originalTraceId: item.originalTraceId ?? null,
|
|
2833
2904
|
originalSpanId: item.originalSpanId ?? null,
|
|
2834
2905
|
// Deprecated aliases for originalTraceId/originalSpanId.
|
|
@@ -2874,12 +2945,19 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
|
|
|
2874
2945
|
}
|
|
2875
2946
|
} : void 0
|
|
2876
2947
|
);
|
|
2877
|
-
await preserveReplayFailure(
|
|
2948
|
+
const deliveredTraceIds = await preserveReplayFailure(
|
|
2878
2949
|
() => waitForReplayPersistence(httpClient, testRunId, replayedTraceIds),
|
|
2879
2950
|
resultItems,
|
|
2880
2951
|
testRunId,
|
|
2881
2952
|
fullTestRunUrl
|
|
2882
2953
|
);
|
|
2954
|
+
for (let index = 0; index < resultItems.length; index += 1) {
|
|
2955
|
+
const localId = replayedTraceIds[index];
|
|
2956
|
+
const readBack = localId ? deliveredTraceIds[localId] : void 0;
|
|
2957
|
+
if (readBack !== void 0) {
|
|
2958
|
+
resultItems[index].traceId = readBack;
|
|
2959
|
+
}
|
|
2960
|
+
}
|
|
2883
2961
|
const completeResult = await preserveReplayFailure(
|
|
2884
2962
|
() => httpClient.completeReplay(testRunId),
|
|
2885
2963
|
resultItems,
|
|
@@ -2895,7 +2973,7 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
|
|
|
2895
2973
|
const item = resultItems[index];
|
|
2896
2974
|
const localId = replayedTraceIds[index];
|
|
2897
2975
|
const mapped = localId ? serverTraceIds[localId] : void 0;
|
|
2898
|
-
item.traceId = mapped ?? null;
|
|
2976
|
+
item.traceId = item.traceId ?? mapped ?? null;
|
|
2899
2977
|
if (item.error === null) {
|
|
2900
2978
|
completedCount += 1;
|
|
2901
2979
|
if (mapped === void 0) {
|