bitfab 0.36.7 → 0.36.9
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-CFECTUDU.js → chunk-MBKY42QC.js} +379 -160
- package/dist/chunk-MBKY42QC.js.map +1 -0
- package/dist/{chunk-EDOZ3DP3.js → chunk-TJAFKZ4X.js} +3 -3
- package/dist/index.cjs +389 -164
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +56 -8
- package/dist/index.d.ts +56 -8
- package/dist/index.js +2 -2
- package/dist/node.cjs +389 -164
- package/dist/node.cjs.map +1 -1
- package/dist/node.js +2 -2
- package/dist/replay-MH5QFXET.js +21 -0
- package/package.json +1 -1
- package/dist/chunk-CFECTUDU.js.map +0 -1
- package/dist/replay-RAKYO5UI.js +0 -17
- /package/dist/{chunk-EDOZ3DP3.js.map → chunk-TJAFKZ4X.js.map} +0 -0
- /package/dist/{replay-RAKYO5UI.js.map → replay-MH5QFXET.js.map} +0 -0
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.9";
|
|
55
55
|
}
|
|
56
56
|
});
|
|
57
57
|
|
|
@@ -177,10 +177,11 @@ var init_errors = __esm({
|
|
|
177
177
|
"src/errors.ts"() {
|
|
178
178
|
"use strict";
|
|
179
179
|
BitfabError = class extends Error {
|
|
180
|
-
constructor(message, url, status) {
|
|
180
|
+
constructor(message, url, status, retryAfterMs) {
|
|
181
181
|
super(message);
|
|
182
182
|
this.url = url;
|
|
183
183
|
this.status = status;
|
|
184
|
+
this.retryAfterMs = retryAfterMs;
|
|
184
185
|
this.name = "BitfabError";
|
|
185
186
|
}
|
|
186
187
|
};
|
|
@@ -535,6 +536,23 @@ var init_serializePayload = __esm({
|
|
|
535
536
|
}
|
|
536
537
|
});
|
|
537
538
|
|
|
539
|
+
// src/transportTypes.ts
|
|
540
|
+
var DeliveryError;
|
|
541
|
+
var init_transportTypes = __esm({
|
|
542
|
+
"src/transportTypes.ts"() {
|
|
543
|
+
"use strict";
|
|
544
|
+
DeliveryError = class extends Error {
|
|
545
|
+
constructor(message, options = {}) {
|
|
546
|
+
super(message);
|
|
547
|
+
this.name = "DeliveryError";
|
|
548
|
+
this.retryable = options.retryable ?? false;
|
|
549
|
+
this.oversized = options.oversized ?? false;
|
|
550
|
+
this.retryAfterMs = options.retryAfterMs;
|
|
551
|
+
}
|
|
552
|
+
};
|
|
553
|
+
}
|
|
554
|
+
});
|
|
555
|
+
|
|
538
556
|
// src/unrefTimer.ts
|
|
539
557
|
function unrefTimer(timer) {
|
|
540
558
|
const handle = timer;
|
|
@@ -574,59 +592,6 @@ function logError(message, error) {
|
|
|
574
592
|
} catch {
|
|
575
593
|
}
|
|
576
594
|
}
|
|
577
|
-
function recordTraceSubmission(operation, payload) {
|
|
578
|
-
const sourceTraceId = resolveSourceTraceId(payload);
|
|
579
|
-
if (sourceTraceId === void 0) {
|
|
580
|
-
return;
|
|
581
|
-
}
|
|
582
|
-
if (operation === "external_span") {
|
|
583
|
-
const rawSpan = asRecord2(payload.rawSpan);
|
|
584
|
-
if (typeof rawSpan?.id !== "string") {
|
|
585
|
-
submissionCounter += 1;
|
|
586
|
-
}
|
|
587
|
-
const sourceSpanId = typeof rawSpan?.id === "string" ? rawSpan.id : `submission-${submissionCounter}`;
|
|
588
|
-
const existing = traceSubmissionSpanIds.get(sourceTraceId);
|
|
589
|
-
if (existing) {
|
|
590
|
-
existing.add(sourceSpanId);
|
|
591
|
-
} else {
|
|
592
|
-
traceSubmissionSpanIds.set(sourceTraceId, /* @__PURE__ */ new Set([sourceSpanId]));
|
|
593
|
-
}
|
|
594
|
-
return;
|
|
595
|
-
}
|
|
596
|
-
if (payload.completed !== true) {
|
|
597
|
-
return;
|
|
598
|
-
}
|
|
599
|
-
if (typeof payload.testRunId === "string") {
|
|
600
|
-
replayTraceSubmissions.add(sourceTraceId);
|
|
601
|
-
if (!traceSubmissionSpanIds.has(sourceTraceId)) {
|
|
602
|
-
traceSubmissionSpanIds.set(sourceTraceId, /* @__PURE__ */ new Set());
|
|
603
|
-
}
|
|
604
|
-
} else {
|
|
605
|
-
traceSubmissionSpanIds.delete(sourceTraceId);
|
|
606
|
-
}
|
|
607
|
-
}
|
|
608
|
-
function takeReplaySpanCounts(traceIds) {
|
|
609
|
-
const counts = {};
|
|
610
|
-
for (const traceId of traceIds) {
|
|
611
|
-
if (!replayTraceSubmissions.has(traceId)) {
|
|
612
|
-
continue;
|
|
613
|
-
}
|
|
614
|
-
counts[traceId] = traceSubmissionSpanIds.get(traceId)?.size ?? 0;
|
|
615
|
-
traceSubmissionSpanIds.delete(traceId);
|
|
616
|
-
replayTraceSubmissions.delete(traceId);
|
|
617
|
-
}
|
|
618
|
-
return counts;
|
|
619
|
-
}
|
|
620
|
-
function asRecord2(value) {
|
|
621
|
-
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
|
|
622
|
-
}
|
|
623
|
-
function resolveSourceTraceId(payload) {
|
|
624
|
-
if (typeof payload.sourceTraceId === "string") {
|
|
625
|
-
return payload.sourceTraceId;
|
|
626
|
-
}
|
|
627
|
-
const rawTrace = asRecord2(payload.externalTrace) ?? asRecord2(payload.rawTrace);
|
|
628
|
-
return typeof rawTrace?.id === "string" ? rawTrace.id : void 0;
|
|
629
|
-
}
|
|
630
595
|
function otlpValue(value) {
|
|
631
596
|
if (typeof value === "boolean") {
|
|
632
597
|
return { boolValue: value };
|
|
@@ -684,7 +649,11 @@ function spanToOtlp(span) {
|
|
|
684
649
|
}
|
|
685
650
|
function encodeSpan(span) {
|
|
686
651
|
const json = JSON.stringify(spanToOtlp(span));
|
|
687
|
-
return {
|
|
652
|
+
return {
|
|
653
|
+
json,
|
|
654
|
+
size: byteLength(json),
|
|
655
|
+
ref: carrierRefs.get(span)
|
|
656
|
+
};
|
|
688
657
|
}
|
|
689
658
|
function trimEncodedSpan(span) {
|
|
690
659
|
try {
|
|
@@ -767,48 +736,27 @@ async function mapWithConcurrency(items, limit, task) {
|
|
|
767
736
|
await Promise.all(workers);
|
|
768
737
|
return results;
|
|
769
738
|
}
|
|
770
|
-
function responseStatus(error) {
|
|
771
|
-
return error instanceof BitfabError ? error.status : void 0;
|
|
772
|
-
}
|
|
773
739
|
function isRetryable(error) {
|
|
774
|
-
|
|
775
|
-
if (status === void 0) {
|
|
776
|
-
return true;
|
|
777
|
-
}
|
|
778
|
-
return RETRYABLE_STATUSES.has(status) || status >= 500;
|
|
740
|
+
return error instanceof DeliveryError && error.retryable;
|
|
779
741
|
}
|
|
780
|
-
function
|
|
781
|
-
|
|
742
|
+
function isOversized(error) {
|
|
743
|
+
return error instanceof DeliveryError && error.oversized;
|
|
782
744
|
}
|
|
783
|
-
function
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
}
|
|
745
|
+
function retryWaitMillis(error, attempt, remainingMillis) {
|
|
746
|
+
const requested = error instanceof DeliveryError ? error.retryAfterMs : void 0;
|
|
747
|
+
const affordable = remainingMillis / 2;
|
|
748
|
+
if (requested !== void 0) {
|
|
749
|
+
return requested < affordable ? requested : null;
|
|
789
750
|
}
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
const rawSpan = asRecord2(payload.rawSpan);
|
|
797
|
-
const rawTrace = asRecord2(payload.externalTrace) ?? asRecord2(payload.rawTrace);
|
|
798
|
-
const raw = rawSpan?.[field] ?? rawTrace?.[field];
|
|
799
|
-
if (typeof raw !== "string") {
|
|
800
|
-
return void 0;
|
|
801
|
-
}
|
|
802
|
-
const parsed = Date.parse(raw);
|
|
803
|
-
return Number.isNaN(parsed) ? void 0 : parsed;
|
|
751
|
+
const backoff = Math.min(
|
|
752
|
+
RETRY_BASE_DELAY_MILLIS * 2 ** attempt,
|
|
753
|
+
RETRY_BACKOFF_CEILING_MILLIS
|
|
754
|
+
);
|
|
755
|
+
const jittered = backoff / 2 + Math.random() * (backoff / 2);
|
|
756
|
+
return jittered < affordable ? jittered : null;
|
|
804
757
|
}
|
|
805
|
-
function
|
|
806
|
-
|
|
807
|
-
if (spanData?.error != null) {
|
|
808
|
-
return true;
|
|
809
|
-
}
|
|
810
|
-
const errors = payload.errors;
|
|
811
|
-
return Array.isArray(errors) ? errors.length > 0 : Boolean(errors);
|
|
758
|
+
function endSpan(span, endTime) {
|
|
759
|
+
span.end(endTime);
|
|
812
760
|
}
|
|
813
761
|
function createOtelTransport(options) {
|
|
814
762
|
return new OtelBatchTransport({
|
|
@@ -847,7 +795,7 @@ function shutdownOtelTransports(timeoutMs = DEFAULT_LIFECYCLE_TIMEOUT_MS) {
|
|
|
847
795
|
(transport, remaining) => transport.shutdown(remaining)
|
|
848
796
|
);
|
|
849
797
|
}
|
|
850
|
-
var import_api, import_core, import_resources, import_sdk_trace_base, OPERATION_ATTRIBUTE, PAYLOAD_ATTRIBUTE,
|
|
798
|
+
var import_api, import_core, import_resources, import_sdk_trace_base, OPERATION_ATTRIBUTE, PAYLOAD_ATTRIBUTE, MAX_EXPORT_REQUEST_BYTES, MAX_DECOMPRESSED_REQUEST_BYTES, MAX_REQUEST_BYTES_ENV, EXPORT_CONCURRENCY_ENV, MAX_QUEUE_SIZE, DIRECT_MAX_EXPORT_BATCH_SIZE, DIRECT_MAX_REQUEST_BATCH_SIZE, DEFAULT_EXPORT_CONCURRENCY, MAX_EXPORT_CONCURRENCY, SCHEDULE_DELAY_MILLIS, EXPORT_TIMEOUT_MILLIS, RETRY_BASE_DELAY_MILLIS, RETRY_BACKOFF_CEILING_MILLIS, MAX_SEND_ATTEMPTS, DEFAULT_LIFECYCLE_TIMEOUT_MS, liveTransports, carrierRefs, SPAN_SEPARATOR_BYTES, BitfabSpanExporter, DeliveryTrackingExporter, OtelBatchTransport;
|
|
851
799
|
var init_otel = __esm({
|
|
852
800
|
"src/otel.ts"() {
|
|
853
801
|
"use strict";
|
|
@@ -861,11 +809,11 @@ var init_otel = __esm({
|
|
|
861
809
|
init_payloadBudget();
|
|
862
810
|
init_readEnv();
|
|
863
811
|
init_serializePayload();
|
|
812
|
+
init_transportTypes();
|
|
864
813
|
init_unrefTimer();
|
|
865
814
|
init_warnOnce();
|
|
866
815
|
OPERATION_ATTRIBUTE = "bitfab.operation";
|
|
867
816
|
PAYLOAD_ATTRIBUTE = "bitfab.payload";
|
|
868
|
-
OTLP_TRACES_ENDPOINT = "/api/sdk/otel/v1/traces";
|
|
869
817
|
MAX_EXPORT_REQUEST_BYTES = 3e6;
|
|
870
818
|
MAX_DECOMPRESSED_REQUEST_BYTES = 8e6;
|
|
871
819
|
MAX_REQUEST_BYTES_ENV = "BITFAB_OTEL_MAX_REQUEST_BYTES";
|
|
@@ -877,25 +825,23 @@ var init_otel = __esm({
|
|
|
877
825
|
MAX_EXPORT_CONCURRENCY = 64;
|
|
878
826
|
SCHEDULE_DELAY_MILLIS = 5e3;
|
|
879
827
|
EXPORT_TIMEOUT_MILLIS = 3e4;
|
|
880
|
-
|
|
828
|
+
RETRY_BASE_DELAY_MILLIS = 100;
|
|
829
|
+
RETRY_BACKOFF_CEILING_MILLIS = 5e3;
|
|
881
830
|
MAX_SEND_ATTEMPTS = 3;
|
|
882
831
|
DEFAULT_LIFECYCLE_TIMEOUT_MS = 3e4;
|
|
883
|
-
RETRYABLE_STATUSES = /* @__PURE__ */ new Set([408, 425, 429]);
|
|
884
832
|
liveTransports = /* @__PURE__ */ new Set();
|
|
885
|
-
|
|
886
|
-
replayTraceSubmissions = /* @__PURE__ */ new Set();
|
|
887
|
-
submissionCounter = 0;
|
|
833
|
+
carrierRefs = /* @__PURE__ */ new WeakMap();
|
|
888
834
|
SPAN_SEPARATOR_BYTES = 1;
|
|
889
|
-
OtlpPayloadTooLargeError = class extends Error {
|
|
890
|
-
};
|
|
891
|
-
OtlpPartialSuccessError = class extends Error {
|
|
892
|
-
};
|
|
893
835
|
BitfabSpanExporter = class {
|
|
894
|
-
constructor(directSender, maxRequestBytes, maxRequestBatchSize, exportConcurrency) {
|
|
836
|
+
constructor(directSender, maxRequestBytes, maxRequestBatchSize, exportConcurrency, onDelivered, exportTimeoutMillis = EXPORT_TIMEOUT_MILLIS) {
|
|
895
837
|
this.directSender = directSender;
|
|
896
838
|
this.maxRequestBytes = maxRequestBytes;
|
|
897
839
|
this.maxRequestBatchSize = maxRequestBatchSize;
|
|
898
840
|
this.exportConcurrency = exportConcurrency;
|
|
841
|
+
this.onDelivered = onDelivered;
|
|
842
|
+
this.exportTimeoutMillis = exportTimeoutMillis;
|
|
843
|
+
/** Epoch ms until which the server has asked this exporter to stay away. */
|
|
844
|
+
this.throttledUntil = 0;
|
|
899
845
|
}
|
|
900
846
|
export(spans, resultCallback) {
|
|
901
847
|
void this.exportAsync(spans).then(
|
|
@@ -961,6 +907,7 @@ var init_otel = __esm({
|
|
|
961
907
|
);
|
|
962
908
|
if (prepared.wireBytes <= this.maxRequestBytes) {
|
|
963
909
|
await this.sendWithRetries(prepared);
|
|
910
|
+
this.reportDelivered(batch.spans);
|
|
964
911
|
return true;
|
|
965
912
|
}
|
|
966
913
|
}
|
|
@@ -988,15 +935,12 @@ var init_otel = __esm({
|
|
|
988
935
|
alreadyTrimmed = true;
|
|
989
936
|
}
|
|
990
937
|
} catch (error) {
|
|
991
|
-
if (error
|
|
938
|
+
if (isOversized(error)) {
|
|
992
939
|
logError(
|
|
993
940
|
batch.spans.length === 1 ? "a single OpenTelemetry span exceeded the ingestion request limit and could not be exported" : "an OpenTelemetry span batch exceeded the ingestion request limit and could not be exported"
|
|
994
941
|
);
|
|
995
942
|
return false;
|
|
996
943
|
}
|
|
997
|
-
if (error instanceof OtlpPartialSuccessError) {
|
|
998
|
-
return false;
|
|
999
|
-
}
|
|
1000
944
|
logError("failed to export an OpenTelemetry span batch", error);
|
|
1001
945
|
return false;
|
|
1002
946
|
}
|
|
@@ -1014,37 +958,79 @@ var init_otel = __esm({
|
|
|
1014
958
|
* the server does not yet understand. The fix is a client-supplied
|
|
1015
959
|
* idempotency key that ingestion dedupes on.
|
|
1016
960
|
*/
|
|
961
|
+
/**
|
|
962
|
+
* Remember a throttle the server asked for, so the requests fanned out
|
|
963
|
+
* alongside this one respect it too. Delaying only the request that was
|
|
964
|
+
* refused leaves the other seven in the window hitting a server that just
|
|
965
|
+
* asked for room.
|
|
966
|
+
*/
|
|
967
|
+
recordThrottle(error) {
|
|
968
|
+
const requested = error instanceof DeliveryError ? error.retryAfterMs : void 0;
|
|
969
|
+
if (requested !== void 0) {
|
|
970
|
+
this.throttledUntil = Math.max(
|
|
971
|
+
this.throttledUntil,
|
|
972
|
+
Date.now() + requested
|
|
973
|
+
);
|
|
974
|
+
}
|
|
975
|
+
}
|
|
976
|
+
/**
|
|
977
|
+
* Waits out an active throttle, or reports the batch undeliverable when the
|
|
978
|
+
* throttle outlasts what we are willing to hold it for. Either way nothing is
|
|
979
|
+
* sent while the server has asked us to stay away.
|
|
980
|
+
*/
|
|
981
|
+
async awaitThrottle(deadline) {
|
|
982
|
+
const remaining = this.throttledUntil - Date.now();
|
|
983
|
+
if (remaining <= 0) {
|
|
984
|
+
return;
|
|
985
|
+
}
|
|
986
|
+
if (remaining >= (deadline - Date.now()) / 2) {
|
|
987
|
+
throw new DeliveryError(
|
|
988
|
+
`OTLP ingestion is throttled for another ${remaining}ms, longer than the export budget`
|
|
989
|
+
);
|
|
990
|
+
}
|
|
991
|
+
await delay(remaining);
|
|
992
|
+
}
|
|
1017
993
|
async sendWithRetries(request) {
|
|
994
|
+
const deadline = Date.now() + this.exportTimeoutMillis;
|
|
1018
995
|
for (let attempt = 0; attempt < MAX_SEND_ATTEMPTS; attempt += 1) {
|
|
1019
996
|
try {
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
request,
|
|
1023
|
-
EXPORT_TIMEOUT_MILLIS
|
|
1024
|
-
);
|
|
1025
|
-
const partialSuccess = asRecord2(response?.partialSuccess);
|
|
1026
|
-
const rejected = partialSuccess?.rejectedSpans;
|
|
1027
|
-
if (rejected !== void 0 && rejected !== "0" && rejected !== 0) {
|
|
1028
|
-
logError(
|
|
1029
|
-
`OTLP ingestion rejected ${rejected} span(s): ${partialSuccess?.errorMessage ?? "no reason provided"}`
|
|
1030
|
-
);
|
|
1031
|
-
throw new OtlpPartialSuccessError();
|
|
1032
|
-
}
|
|
997
|
+
await this.awaitThrottle(deadline);
|
|
998
|
+
await this.directSender(request, Math.max(0, deadline - Date.now()));
|
|
1033
999
|
return;
|
|
1034
1000
|
} catch (error) {
|
|
1035
|
-
if (error
|
|
1001
|
+
if (isOversized(error)) {
|
|
1036
1002
|
throw error;
|
|
1037
1003
|
}
|
|
1038
|
-
|
|
1039
|
-
throw new OtlpPayloadTooLargeError();
|
|
1040
|
-
}
|
|
1004
|
+
this.recordThrottle(error);
|
|
1041
1005
|
if (attempt === MAX_SEND_ATTEMPTS - 1 || !isRetryable(error)) {
|
|
1042
1006
|
throw error;
|
|
1043
1007
|
}
|
|
1044
|
-
|
|
1008
|
+
const wait = retryWaitMillis(error, attempt, deadline - Date.now());
|
|
1009
|
+
if (wait === null) {
|
|
1010
|
+
throw error;
|
|
1011
|
+
}
|
|
1012
|
+
await delay(wait);
|
|
1045
1013
|
}
|
|
1046
1014
|
}
|
|
1047
1015
|
}
|
|
1016
|
+
/**
|
|
1017
|
+
* Announce the carriers a request delivered. Wrapped because a listener that
|
|
1018
|
+
* throws must never turn a delivered batch into a failed export.
|
|
1019
|
+
*/
|
|
1020
|
+
reportDelivered(spans) {
|
|
1021
|
+
if (this.onDelivered === void 0) {
|
|
1022
|
+
return;
|
|
1023
|
+
}
|
|
1024
|
+
const refs = spans.map((span) => span.ref).filter((ref) => ref !== void 0);
|
|
1025
|
+
if (refs.length === 0) {
|
|
1026
|
+
return;
|
|
1027
|
+
}
|
|
1028
|
+
try {
|
|
1029
|
+
this.onDelivered(refs);
|
|
1030
|
+
} catch (error) {
|
|
1031
|
+
logError("a delivery listener threw", error);
|
|
1032
|
+
}
|
|
1033
|
+
}
|
|
1048
1034
|
async shutdown() {
|
|
1049
1035
|
}
|
|
1050
1036
|
async forceFlush() {
|
|
@@ -1102,7 +1088,9 @@ var init_otel = __esm({
|
|
|
1102
1088
|
options.directSender,
|
|
1103
1089
|
maxRequestBytes,
|
|
1104
1090
|
maxRequestBatchSize,
|
|
1105
|
-
options.exportConcurrency ?? DEFAULT_EXPORT_CONCURRENCY
|
|
1091
|
+
options.exportConcurrency ?? DEFAULT_EXPORT_CONCURRENCY,
|
|
1092
|
+
options.onDelivered,
|
|
1093
|
+
options.exportTimeoutMillis ?? EXPORT_TIMEOUT_MILLIS
|
|
1106
1094
|
)
|
|
1107
1095
|
);
|
|
1108
1096
|
this.processor = new import_sdk_trace_base.BatchSpanProcessor(this.deliveryTracker, {
|
|
@@ -1126,8 +1114,7 @@ var init_otel = __esm({
|
|
|
1126
1114
|
this.tracer = this.provider.getTracer("bitfab", __version__);
|
|
1127
1115
|
liveTransports.add(this);
|
|
1128
1116
|
}
|
|
1129
|
-
submit(operation, payload) {
|
|
1130
|
-
recordTraceSubmission(operation, payload);
|
|
1117
|
+
submit(operation, payload, meta = {}) {
|
|
1131
1118
|
if (this.closed) {
|
|
1132
1119
|
warnOnce(
|
|
1133
1120
|
"otel-submit-after-shutdown",
|
|
@@ -1148,17 +1135,20 @@ var init_otel = __esm({
|
|
|
1148
1135
|
].join(", ")}); they were stubbed so the span still ships, but the trace may be incomplete or not replayable.`
|
|
1149
1136
|
);
|
|
1150
1137
|
}
|
|
1151
|
-
const span = this.tracer.startSpan(
|
|
1138
|
+
const span = this.tracer.startSpan(meta.name ?? `bitfab.${operation}`, {
|
|
1152
1139
|
attributes: {
|
|
1153
1140
|
[OPERATION_ATTRIBUTE]: operation,
|
|
1154
1141
|
[PAYLOAD_ATTRIBUTE]: body
|
|
1155
1142
|
},
|
|
1156
|
-
startTime:
|
|
1143
|
+
startTime: meta.startTime
|
|
1157
1144
|
});
|
|
1158
|
-
if (
|
|
1145
|
+
if (meta.ref !== void 0) {
|
|
1146
|
+
carrierRefs.set(span, meta.ref);
|
|
1147
|
+
}
|
|
1148
|
+
if (meta.errored === true) {
|
|
1159
1149
|
span.setStatus({ code: import_api.SpanStatusCode.ERROR });
|
|
1160
1150
|
}
|
|
1161
|
-
endSpan(span,
|
|
1151
|
+
endSpan(span, meta.endTime);
|
|
1162
1152
|
} catch (error) {
|
|
1163
1153
|
logError("failed to queue an OpenTelemetry span", error);
|
|
1164
1154
|
}
|
|
@@ -1208,9 +1198,6 @@ function flushTraceTransports(timeoutMs) {
|
|
|
1208
1198
|
function shutdownTraceTransports(timeoutMs) {
|
|
1209
1199
|
return shutdownOtelTransports(timeoutMs);
|
|
1210
1200
|
}
|
|
1211
|
-
function takeReplaySpanCounts2(traceIds) {
|
|
1212
|
-
return takeReplaySpanCounts(traceIds);
|
|
1213
|
-
}
|
|
1214
1201
|
var init_transport = __esm({
|
|
1215
1202
|
"src/transport.ts"() {
|
|
1216
1203
|
"use strict";
|
|
@@ -1259,7 +1246,96 @@ async function waitForPromises(promises, timeoutMs) {
|
|
|
1259
1246
|
}
|
|
1260
1247
|
}
|
|
1261
1248
|
}
|
|
1262
|
-
|
|
1249
|
+
function readHeader(response, name) {
|
|
1250
|
+
try {
|
|
1251
|
+
return response.headers?.get(name) ?? null;
|
|
1252
|
+
} catch {
|
|
1253
|
+
return null;
|
|
1254
|
+
}
|
|
1255
|
+
}
|
|
1256
|
+
function parseRetryAfterMs(header) {
|
|
1257
|
+
const value = header?.trim();
|
|
1258
|
+
if (!value) {
|
|
1259
|
+
return void 0;
|
|
1260
|
+
}
|
|
1261
|
+
const seconds = Number(value);
|
|
1262
|
+
if (Number.isFinite(seconds)) {
|
|
1263
|
+
return seconds >= 0 ? seconds * 1e3 : void 0;
|
|
1264
|
+
}
|
|
1265
|
+
const at = Date.parse(value);
|
|
1266
|
+
if (Number.isNaN(at)) {
|
|
1267
|
+
return void 0;
|
|
1268
|
+
}
|
|
1269
|
+
return Math.max(0, at - Date.now());
|
|
1270
|
+
}
|
|
1271
|
+
function carrierMeta(operation, payload, ref) {
|
|
1272
|
+
return {
|
|
1273
|
+
ref,
|
|
1274
|
+
name: carrierName(operation, payload),
|
|
1275
|
+
startTime: payloadTimestamp(payload, "started_at"),
|
|
1276
|
+
endTime: payloadTimestamp(payload, "ended_at"),
|
|
1277
|
+
errored: payloadHasError(payload)
|
|
1278
|
+
};
|
|
1279
|
+
}
|
|
1280
|
+
function carrierName(operation, payload) {
|
|
1281
|
+
if (operation === "external_span") {
|
|
1282
|
+
const spanData = asPayloadRecord(
|
|
1283
|
+
asPayloadRecord(payload.rawSpan)?.span_data
|
|
1284
|
+
);
|
|
1285
|
+
if (typeof spanData?.name === "string") {
|
|
1286
|
+
return spanData.name;
|
|
1287
|
+
}
|
|
1288
|
+
}
|
|
1289
|
+
if (typeof payload.traceFunctionKey === "string") {
|
|
1290
|
+
return payload.traceFunctionKey;
|
|
1291
|
+
}
|
|
1292
|
+
return `bitfab.${operation}`;
|
|
1293
|
+
}
|
|
1294
|
+
function payloadTimestamp(payload, field) {
|
|
1295
|
+
const rawSpan = asPayloadRecord(payload.rawSpan);
|
|
1296
|
+
const rawTrace = asPayloadRecord(payload.externalTrace) ?? asPayloadRecord(payload.rawTrace);
|
|
1297
|
+
const raw = rawSpan?.[field] ?? rawTrace?.[field];
|
|
1298
|
+
if (typeof raw !== "string") {
|
|
1299
|
+
return void 0;
|
|
1300
|
+
}
|
|
1301
|
+
const parsed = Date.parse(raw);
|
|
1302
|
+
return Number.isNaN(parsed) ? void 0 : parsed;
|
|
1303
|
+
}
|
|
1304
|
+
function payloadHasError(payload) {
|
|
1305
|
+
const spanData = asPayloadRecord(asPayloadRecord(payload.rawSpan)?.span_data);
|
|
1306
|
+
if (spanData?.error != null) {
|
|
1307
|
+
return true;
|
|
1308
|
+
}
|
|
1309
|
+
const errors = payload.errors;
|
|
1310
|
+
return Array.isArray(errors) ? errors.length > 0 : Boolean(errors);
|
|
1311
|
+
}
|
|
1312
|
+
function asPayloadRecord(value) {
|
|
1313
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
|
|
1314
|
+
}
|
|
1315
|
+
function carrierRef(payload) {
|
|
1316
|
+
const traceId = sourceTraceIdOf(payload);
|
|
1317
|
+
if (traceId === void 0) {
|
|
1318
|
+
return void 0;
|
|
1319
|
+
}
|
|
1320
|
+
const rawSpan = payload.rawSpan;
|
|
1321
|
+
if (rawSpan === void 0) {
|
|
1322
|
+
return { traceId };
|
|
1323
|
+
}
|
|
1324
|
+
const spanId = rawSpan?.id;
|
|
1325
|
+
return {
|
|
1326
|
+
traceId,
|
|
1327
|
+
spanId: typeof spanId === "string" ? spanId : `submission-${++carrierSeq}`
|
|
1328
|
+
};
|
|
1329
|
+
}
|
|
1330
|
+
function sourceTraceIdOf(payload) {
|
|
1331
|
+
if (typeof payload.sourceTraceId === "string") {
|
|
1332
|
+
return payload.sourceTraceId;
|
|
1333
|
+
}
|
|
1334
|
+
const rawTrace = payload.externalTrace ?? payload.rawTrace;
|
|
1335
|
+
const id = rawTrace?.id;
|
|
1336
|
+
return typeof id === "string" ? id : void 0;
|
|
1337
|
+
}
|
|
1338
|
+
var REPLAY_DB_BRANCH_REQUEST_TIMEOUT_MS, OTLP_TRACES_ENDPOINT, RETRYABLE_STATUSES, EXIT_FLUSH_TIMEOUT_MS, DEFAULT_LIFECYCLE_TIMEOUT_MS2, pendingTracePromises, carrierSeq, HttpClient;
|
|
1263
1339
|
var init_http = __esm({
|
|
1264
1340
|
"src/http.ts"() {
|
|
1265
1341
|
"use strict";
|
|
@@ -1269,9 +1345,12 @@ var init_http = __esm({
|
|
|
1269
1345
|
init_replayContext();
|
|
1270
1346
|
init_serializePayload();
|
|
1271
1347
|
init_transport();
|
|
1348
|
+
init_transportTypes();
|
|
1272
1349
|
init_unrefTimer();
|
|
1273
1350
|
init_warnOnce();
|
|
1274
1351
|
REPLAY_DB_BRANCH_REQUEST_TIMEOUT_MS = 3e5;
|
|
1352
|
+
OTLP_TRACES_ENDPOINT = "/api/sdk/otel/v1/traces";
|
|
1353
|
+
RETRYABLE_STATUSES = /* @__PURE__ */ new Set([429, 500, 502, 503, 504]);
|
|
1275
1354
|
EXIT_FLUSH_TIMEOUT_MS = 5e3;
|
|
1276
1355
|
DEFAULT_LIFECYCLE_TIMEOUT_MS2 = 3e4;
|
|
1277
1356
|
pendingTracePromises = /* @__PURE__ */ new Set();
|
|
@@ -1291,8 +1370,12 @@ var init_http = __esm({
|
|
|
1291
1370
|
});
|
|
1292
1371
|
});
|
|
1293
1372
|
}
|
|
1373
|
+
carrierSeq = 0;
|
|
1294
1374
|
HttpClient = class {
|
|
1295
1375
|
constructor(config) {
|
|
1376
|
+
// Only traces a caller asked about are tracked, so ordinary tracing stores
|
|
1377
|
+
// nothing here.
|
|
1378
|
+
this.traceDeliveries = /* @__PURE__ */ new Map();
|
|
1296
1379
|
// Deferred span work owned by THIS client. The module-global set backs the
|
|
1297
1380
|
// process-wide `flushTraces()` and the exit hook, but per-client lifecycle
|
|
1298
1381
|
// must not wait on another client's slow finalize: a false `close()` failure
|
|
@@ -1328,13 +1411,131 @@ var init_http = __esm({
|
|
|
1328
1411
|
}
|
|
1329
1412
|
if (!this.traceTransport) {
|
|
1330
1413
|
this.traceTransport = createTraceTransport({
|
|
1331
|
-
directSender: (
|
|
1332
|
-
|
|
1333
|
-
})
|
|
1414
|
+
directSender: (request, timeoutMs) => this.deliverCarriers(request, timeoutMs),
|
|
1415
|
+
onDelivered: (refs) => this.recordDeliveredCarriers(refs)
|
|
1334
1416
|
});
|
|
1335
1417
|
}
|
|
1336
1418
|
return this.traceTransport;
|
|
1337
1419
|
}
|
|
1420
|
+
/**
|
|
1421
|
+
* Post one encoded batch and decide what the server's answer means, so the
|
|
1422
|
+
* transport never reads a response. Rejections and permanent statuses come
|
|
1423
|
+
* back as a non-retryable {@link DeliveryError}; anything the server might
|
|
1424
|
+
* still accept on a second try comes back retryable.
|
|
1425
|
+
*/
|
|
1426
|
+
async deliverCarriers(request, timeoutMs) {
|
|
1427
|
+
let response;
|
|
1428
|
+
try {
|
|
1429
|
+
response = await this.sendPrepared(
|
|
1430
|
+
OTLP_TRACES_ENDPOINT,
|
|
1431
|
+
request,
|
|
1432
|
+
{ timeout: timeoutMs }
|
|
1433
|
+
);
|
|
1434
|
+
} catch (error) {
|
|
1435
|
+
const status = error instanceof BitfabError ? error.status : void 0;
|
|
1436
|
+
if (status === void 0) {
|
|
1437
|
+
throw new DeliveryError(`OTLP ingestion failed: ${String(error)}`, {
|
|
1438
|
+
retryable: true
|
|
1439
|
+
});
|
|
1440
|
+
}
|
|
1441
|
+
throw new DeliveryError(`OTLP ingestion failed with HTTP ${status}`, {
|
|
1442
|
+
retryable: RETRYABLE_STATUSES.has(status),
|
|
1443
|
+
oversized: status === 413,
|
|
1444
|
+
...error instanceof BitfabError && error.retryAfterMs !== void 0 ? { retryAfterMs: error.retryAfterMs } : {}
|
|
1445
|
+
});
|
|
1446
|
+
}
|
|
1447
|
+
const partialSuccess = asPayloadRecord(response?.partialSuccess);
|
|
1448
|
+
const rejected = partialSuccess?.rejectedSpans;
|
|
1449
|
+
if (rejected !== void 0 && rejected !== "0" && rejected !== 0) {
|
|
1450
|
+
throw new DeliveryError(
|
|
1451
|
+
`OTLP ingestion rejected ${rejected} span(s): ${partialSuccess?.errorMessage ?? "no reason provided"}`
|
|
1452
|
+
);
|
|
1453
|
+
}
|
|
1454
|
+
}
|
|
1455
|
+
/**
|
|
1456
|
+
* Start tracking delivery for `traceIds`. Nothing is recorded for a trace
|
|
1457
|
+
* that was never tracked, so ordinary tracing costs no bookkeeping at all.
|
|
1458
|
+
*/
|
|
1459
|
+
trackTraceDeliveries(traceIds) {
|
|
1460
|
+
for (const traceId of traceIds) {
|
|
1461
|
+
if (!this.traceDeliveries.has(traceId)) {
|
|
1462
|
+
this.traceDeliveries.set(traceId, {
|
|
1463
|
+
submittedSpanIds: /* @__PURE__ */ new Set(),
|
|
1464
|
+
ackedSpanIds: /* @__PURE__ */ new Set(),
|
|
1465
|
+
closed: false,
|
|
1466
|
+
closingAcked: false
|
|
1467
|
+
});
|
|
1468
|
+
}
|
|
1469
|
+
}
|
|
1470
|
+
}
|
|
1471
|
+
/** Whether any tracked trace has had its closing carrier submitted. */
|
|
1472
|
+
hasClosedDeliveries(traceIds) {
|
|
1473
|
+
return traceIds.some((traceId) => this.traceDeliveries.get(traceId)?.closed);
|
|
1474
|
+
}
|
|
1475
|
+
/**
|
|
1476
|
+
* Report what each tracked trace submitted and whether the server confirmed
|
|
1477
|
+
* it, and stop tracking them. Every id passed is freed, so a caller cannot
|
|
1478
|
+
* leak a record for a trace that never closed.
|
|
1479
|
+
*
|
|
1480
|
+
* `delivered` is only meaningful once a flush has settled: acks land before
|
|
1481
|
+
* an export resolves, so a flush that reported success has already collected
|
|
1482
|
+
* every ack it is going to collect.
|
|
1483
|
+
*/
|
|
1484
|
+
takeTraceDeliveries(traceIds) {
|
|
1485
|
+
const reports = {};
|
|
1486
|
+
for (const traceId of traceIds) {
|
|
1487
|
+
const delivery = this.traceDeliveries.get(traceId);
|
|
1488
|
+
if (delivery === void 0) {
|
|
1489
|
+
continue;
|
|
1490
|
+
}
|
|
1491
|
+
this.traceDeliveries.delete(traceId);
|
|
1492
|
+
reports[traceId] = {
|
|
1493
|
+
spanCount: delivery.submittedSpanIds.size,
|
|
1494
|
+
closed: delivery.closed,
|
|
1495
|
+
delivered: delivery.closingAcked && [...delivery.submittedSpanIds].every(
|
|
1496
|
+
(spanId) => delivery.ackedSpanIds.has(spanId)
|
|
1497
|
+
)
|
|
1498
|
+
};
|
|
1499
|
+
}
|
|
1500
|
+
return reports;
|
|
1501
|
+
}
|
|
1502
|
+
/** Build a carrier's meta and record what it adds to its trace's expected set. */
|
|
1503
|
+
recordedMeta(operation, payload, ref) {
|
|
1504
|
+
this.recordSubmittedCarrier(ref);
|
|
1505
|
+
return carrierMeta(operation, payload, ref);
|
|
1506
|
+
}
|
|
1507
|
+
recordSubmittedCarrier(ref) {
|
|
1508
|
+
if (ref === void 0) {
|
|
1509
|
+
return;
|
|
1510
|
+
}
|
|
1511
|
+
const delivery = this.traceDeliveries.get(ref.traceId);
|
|
1512
|
+
if (delivery === void 0) {
|
|
1513
|
+
return;
|
|
1514
|
+
}
|
|
1515
|
+
if (ref.spanId === void 0) {
|
|
1516
|
+
delivery.closed = true;
|
|
1517
|
+
} else {
|
|
1518
|
+
delivery.submittedSpanIds.add(ref.spanId);
|
|
1519
|
+
}
|
|
1520
|
+
}
|
|
1521
|
+
/**
|
|
1522
|
+
* Ingestion commits every carrier in a request before it answers, so a
|
|
1523
|
+
* delivered ref is proof its row exists: the same fact the replay status
|
|
1524
|
+
* endpoint would report, already in hand.
|
|
1525
|
+
*/
|
|
1526
|
+
recordDeliveredCarriers(refs) {
|
|
1527
|
+
for (const ref of refs) {
|
|
1528
|
+
const delivery = this.traceDeliveries.get(ref.traceId);
|
|
1529
|
+
if (delivery === void 0) {
|
|
1530
|
+
continue;
|
|
1531
|
+
}
|
|
1532
|
+
if (ref.spanId === void 0) {
|
|
1533
|
+
delivery.closingAcked = true;
|
|
1534
|
+
} else {
|
|
1535
|
+
delivery.ackedSpanIds.add(ref.spanId);
|
|
1536
|
+
}
|
|
1537
|
+
}
|
|
1538
|
+
}
|
|
1338
1539
|
/**
|
|
1339
1540
|
* Track deferred span work so this client's own lifecycle waits for it, and
|
|
1340
1541
|
* so the process-wide flush and exit hook do too.
|
|
@@ -1444,7 +1645,8 @@ var init_http = __esm({
|
|
|
1444
1645
|
throw new BitfabError(
|
|
1445
1646
|
`HTTP ${response.status}: ${errorText.slice(0, 500)}`,
|
|
1446
1647
|
void 0,
|
|
1447
|
-
response.status
|
|
1648
|
+
response.status,
|
|
1649
|
+
parseRetryAfterMs(readHeader(response, "retry-after"))
|
|
1448
1650
|
);
|
|
1449
1651
|
}
|
|
1450
1652
|
const result = await response.json();
|
|
@@ -1530,11 +1732,12 @@ var init_http = __esm({
|
|
|
1530
1732
|
* the OTLP carrier has no path to carry it.
|
|
1531
1733
|
*/
|
|
1532
1734
|
sendInternalTrace(functionId, payload) {
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1735
|
+
const body = { ...payload, functionId, sdkVersion: __version__ };
|
|
1736
|
+
this.getTraceTransport()?.submit(
|
|
1737
|
+
"internal_trace",
|
|
1738
|
+
body,
|
|
1739
|
+
carrierMeta("internal_trace", body, void 0)
|
|
1740
|
+
);
|
|
1538
1741
|
}
|
|
1539
1742
|
/**
|
|
1540
1743
|
* Queue an external span (from withSpan wrapper or OpenAI tracing) onto this
|
|
@@ -1543,10 +1746,11 @@ var init_http = __esm({
|
|
|
1543
1746
|
* promise.
|
|
1544
1747
|
*/
|
|
1545
1748
|
sendExternalSpan(payload) {
|
|
1546
|
-
this.getTraceTransport()?.submit(
|
|
1547
|
-
|
|
1548
|
-
sdkVersion: __version__
|
|
1549
|
-
|
|
1749
|
+
this.getTraceTransport()?.submit(
|
|
1750
|
+
"external_span",
|
|
1751
|
+
{ ...payload, sdkVersion: __version__ },
|
|
1752
|
+
this.recordedMeta("external_span", payload, carrierRef(payload))
|
|
1753
|
+
);
|
|
1550
1754
|
}
|
|
1551
1755
|
/**
|
|
1552
1756
|
* Queue an external trace completion (from OpenAI tracing) onto this
|
|
@@ -1555,10 +1759,15 @@ var init_http = __esm({
|
|
|
1555
1759
|
* server-authoritative barrier in `replay.ts`, not by awaiting this call.
|
|
1556
1760
|
*/
|
|
1557
1761
|
sendExternalTrace(payload) {
|
|
1558
|
-
this.getTraceTransport()?.submit(
|
|
1559
|
-
|
|
1560
|
-
sdkVersion: __version__
|
|
1561
|
-
|
|
1762
|
+
this.getTraceTransport()?.submit(
|
|
1763
|
+
"external_trace",
|
|
1764
|
+
{ ...payload, sdkVersion: __version__ },
|
|
1765
|
+
this.recordedMeta(
|
|
1766
|
+
"external_trace",
|
|
1767
|
+
payload,
|
|
1768
|
+
payload.completed === true ? carrierRef(payload) : void 0
|
|
1769
|
+
)
|
|
1770
|
+
);
|
|
1562
1771
|
}
|
|
1563
1772
|
/**
|
|
1564
1773
|
* Partial update of an existing trace identified by its Bitfab trace ID.
|
|
@@ -2154,7 +2363,9 @@ __export(replay_exports, {
|
|
|
2154
2363
|
ReplayError: () => ReplayError,
|
|
2155
2364
|
replay: () => replay,
|
|
2156
2365
|
reportReplayProgress: () => reportReplayProgress,
|
|
2157
|
-
serializeReplayResult: () => serializeReplayResult
|
|
2366
|
+
serializeReplayResult: () => serializeReplayResult,
|
|
2367
|
+
sleepForReplayPersistence: () => sleepForReplayPersistence,
|
|
2368
|
+
waitForReplayPersistence: () => waitForReplayPersistence
|
|
2158
2369
|
});
|
|
2159
2370
|
function dbBranchEnabled(dbBranch) {
|
|
2160
2371
|
return dbBranch !== void 0 && dbBranch !== false;
|
|
@@ -2442,15 +2653,29 @@ async function waitForReplayPersistence(httpClient, testRunId, replayedTraceIds)
|
|
|
2442
2653
|
REPLAY_PERSISTENCE_TIMEOUT_MS
|
|
2443
2654
|
);
|
|
2444
2655
|
if (!deferredSettled) {
|
|
2656
|
+
httpClient.takeTraceDeliveries(replayedTraceIds);
|
|
2445
2657
|
throw new BitfabError(
|
|
2446
2658
|
`Replay could not settle deferred span work before the deadline, so the expected span counts are incomplete (testRunId ${testRunId}).`
|
|
2447
2659
|
);
|
|
2448
2660
|
}
|
|
2449
|
-
|
|
2450
|
-
|
|
2661
|
+
if (!httpClient.hasClosedDeliveries(replayedTraceIds)) {
|
|
2662
|
+
httpClient.takeTraceDeliveries(replayedTraceIds);
|
|
2451
2663
|
return;
|
|
2452
2664
|
}
|
|
2453
2665
|
const flushed = await flushTraces(REPLAY_PERSISTENCE_TIMEOUT_MS);
|
|
2666
|
+
const deliveries = httpClient.takeTraceDeliveries(replayedTraceIds);
|
|
2667
|
+
const expectedSpanCounts = {};
|
|
2668
|
+
let allDelivered = true;
|
|
2669
|
+
for (const [traceId, delivery] of Object.entries(deliveries)) {
|
|
2670
|
+
if (!delivery.closed) {
|
|
2671
|
+
continue;
|
|
2672
|
+
}
|
|
2673
|
+
expectedSpanCounts[traceId] = delivery.spanCount;
|
|
2674
|
+
allDelivered = allDelivered && delivery.delivered;
|
|
2675
|
+
}
|
|
2676
|
+
if (allDelivered) {
|
|
2677
|
+
return;
|
|
2678
|
+
}
|
|
2454
2679
|
const deadline = Date.now() + REPLAY_PERSISTENCE_TIMEOUT_MS;
|
|
2455
2680
|
let missing = Object.keys(expectedSpanCounts).length;
|
|
2456
2681
|
while (true) {
|
|
@@ -2468,17 +2693,18 @@ async function waitForReplayPersistence(httpClient, testRunId, replayedTraceIds)
|
|
|
2468
2693
|
if (Date.now() >= deadline) {
|
|
2469
2694
|
break;
|
|
2470
2695
|
}
|
|
2471
|
-
await
|
|
2696
|
+
await sleepForReplayPersistence(
|
|
2697
|
+
Math.min(100, Math.max(0, deadline - Date.now()))
|
|
2698
|
+
);
|
|
2472
2699
|
}
|
|
2473
2700
|
const cause = flushed ? "" : " Delivery was also not confirmed before the flush deadline, so the spans likely never reached the server.";
|
|
2474
2701
|
throw new BitfabError(
|
|
2475
2702
|
`Replay traces were not fully persisted before the delivery deadline (testRunId ${testRunId}, missing ${missing} of ${Object.keys(expectedSpanCounts).length} trace(s)).${cause}`
|
|
2476
2703
|
);
|
|
2477
2704
|
}
|
|
2478
|
-
function
|
|
2705
|
+
function sleepForReplayPersistence(ms) {
|
|
2479
2706
|
return new Promise((resolve) => {
|
|
2480
|
-
|
|
2481
|
-
unrefTimer(timer);
|
|
2707
|
+
setTimeout(resolve, ms);
|
|
2482
2708
|
});
|
|
2483
2709
|
}
|
|
2484
2710
|
async function mapWithConcurrency2(tasks, maxConcurrency, onSettled, onStarted) {
|
|
@@ -2559,6 +2785,7 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
|
|
|
2559
2785
|
...registeredOverrides
|
|
2560
2786
|
];
|
|
2561
2787
|
const replayedTraceIds = serverItems.map(() => randomUuid());
|
|
2788
|
+
httpClient.trackTraceDeliveries(replayedTraceIds);
|
|
2562
2789
|
const tasks = serverItems.map(
|
|
2563
2790
|
(serverItem, index) => () => processItem(
|
|
2564
2791
|
httpClient,
|
|
@@ -2756,8 +2983,6 @@ var init_replay = __esm({
|
|
|
2756
2983
|
init_randomUuid();
|
|
2757
2984
|
init_replayContext();
|
|
2758
2985
|
init_serialize();
|
|
2759
|
-
init_transport();
|
|
2760
|
-
init_unrefTimer();
|
|
2761
2986
|
REPLAY_PERSISTENCE_TIMEOUT_MS = 3e4;
|
|
2762
2987
|
BITFAB_PROGRESS_PREFIX = "@@bitfab:progress ";
|
|
2763
2988
|
ReplayError = class extends BitfabError {
|