bitfab 0.64.12 → 0.64.14

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.
@@ -7,7 +7,7 @@ import {
7
7
  flushTraces,
8
8
  parseRetryAfterMs,
9
9
  serializePayloadBody
10
- } from "./chunk-3T32S5N7.js";
10
+ } from "./chunk-DLH4OESM.js";
11
11
  import "./chunk-MT36GJMW.js";
12
12
  export {
13
13
  BitfabError,
@@ -19,4 +19,4 @@ export {
19
19
  parseRetryAfterMs,
20
20
  serializePayloadBody
21
21
  };
22
- //# sourceMappingURL=http-UTQFHWCP.js.map
22
+ //# sourceMappingURL=http-VC2DY72V.js.map
@@ -7,7 +7,7 @@ import {
7
7
  flushTraces,
8
8
  parseRetryAfterMs,
9
9
  serializePayloadBody
10
- } from "./chunk-JBX6A7BW.js";
10
+ } from "./chunk-Q5XWNTP2.js";
11
11
  export {
12
12
  BitfabError,
13
13
  HttpClient,
@@ -18,4 +18,4 @@ export {
18
18
  parseRetryAfterMs,
19
19
  serializePayloadBody
20
20
  };
21
- //# sourceMappingURL=http-HCITQXT5.js.map
21
+ //# sourceMappingURL=http-ZZHVL3NT.js.map
package/dist/index.cjs CHANGED
@@ -51,7 +51,7 @@ var __version__, __packageName__;
51
51
  var init_version_generated = __esm({
52
52
  "src/version.generated.ts"() {
53
53
  "use strict";
54
- __version__ = "0.64.12";
54
+ __version__ = "0.64.14";
55
55
  __packageName__ = "bitfab";
56
56
  }
57
57
  });
@@ -2746,6 +2746,12 @@ var init_http = __esm({
2746
2746
  const response = await this.get(endpoint);
2747
2747
  return response.span;
2748
2748
  }
2749
+ async getSpan(spanId) {
2750
+ const response = await this.get(
2751
+ `/api/sdk/spans/${encodeURIComponent(spanId)}`
2752
+ );
2753
+ return response.span;
2754
+ }
2749
2755
  /**
2750
2756
  * GET a JSON endpoint on the service with the client's API key. Throws a
2751
2757
  * `BitfabError` carrying the status text for any non-2xx response.
@@ -4650,7 +4656,7 @@ async function processItem(httpClient, serverItem, fn, experimentId, mockStrateg
4650
4656
  dbBranchTimings: dbBranchTimings ?? null
4651
4657
  };
4652
4658
  }
4653
- async function waitForReplayPersistence(httpClient, experimentId, replayedTraceIds) {
4659
+ async function waitForReplayPersistence(httpClient, experimentId, replayedTraceIds, replayLabels = {}, warn2 = console.warn) {
4654
4660
  const deferredSettled = await httpClient.settleDeferredWork(
4655
4661
  REPLAY_PERSISTENCE_TIMEOUT_MS
4656
4662
  );
@@ -4683,7 +4689,7 @@ async function waitForReplayPersistence(httpClient, experimentId, replayedTraceI
4683
4689
  return readBackTraceIds;
4684
4690
  }
4685
4691
  const deadline = Date.now() + REPLAY_PERSISTENCE_TIMEOUT_MS;
4686
- let missing = Object.keys(expectedSpanCounts).length;
4692
+ let missing = Object.keys(expectedSpanCounts);
4687
4693
  while (true) {
4688
4694
  const status = await httpClient.getReplayStatus(
4689
4695
  experimentId,
@@ -4693,8 +4699,8 @@ async function waitForReplayPersistence(httpClient, experimentId, replayedTraceI
4693
4699
  Object.assign(readBackTraceIds, ready);
4694
4700
  missing = Object.keys(expectedSpanCounts).filter(
4695
4701
  (traceId) => ready[traceId] === void 0
4696
- ).length;
4697
- if (missing === 0) {
4702
+ );
4703
+ if (missing.length === 0) {
4698
4704
  return readBackTraceIds;
4699
4705
  }
4700
4706
  if (Date.now() >= deadline) {
@@ -4704,10 +4710,19 @@ async function waitForReplayPersistence(httpClient, experimentId, replayedTraceI
4704
4710
  Math.min(100, Math.max(0, deadline - Date.now()))
4705
4711
  );
4706
4712
  }
4707
- const cause = flushed ? "" : " Delivery was also not confirmed before the flush deadline, so the spans likely never reached the server.";
4708
- throw new BitfabError(
4709
- `Replay traces were not fully persisted before the delivery deadline (experiment ${experimentId}, missing ${missing} of ${Object.keys(expectedSpanCounts).length} trace(s)).${cause}`
4710
- );
4713
+ for (const traceId of missing) {
4714
+ warn2(
4715
+ unconfirmedReplayWarning(
4716
+ replayLabels[traceId] ?? traceId,
4717
+ REPLAY_PERSISTENCE_TIMEOUT_MS / 1e3,
4718
+ flushed
4719
+ )
4720
+ );
4721
+ }
4722
+ return readBackTraceIds;
4723
+ }
4724
+ function unconfirmedReplayWarning(label, seconds, flushed) {
4725
+ return `[bitfab] replay ${label} could not confirm all spans reached Bitfab within ${seconds}s. The run continues; Bitfab will show this replay as capture incomplete.${flushed ? "" : " Some spans likely never left this process."}`;
4711
4726
  }
4712
4727
  function sleepForReplayPersistence(ms) {
4713
4728
  return new Promise((resolve) => {
@@ -5110,7 +5125,17 @@ async function runReplaySession(httpClient, fn, session, fullExperimentUrl, maxC
5110
5125
  }
5111
5126
  throwIfInterrupted(interrupted, resultItems, experimentId, fullExperimentUrl);
5112
5127
  const deliveredTraceIds = await preserveReplayFailure(
5113
- () => waitForReplayPersistence(httpClient, experimentId, replayedTraceIds),
5128
+ () => waitForReplayPersistence(
5129
+ httpClient,
5130
+ experimentId,
5131
+ replayedTraceIds,
5132
+ Object.fromEntries(
5133
+ workItems.map(({ serverItem, attempt }, index) => [
5134
+ replayedTraceIds[index],
5135
+ `${serverItem.originalTraceId ?? serverItem.sourceTraceId}#${attempt}`
5136
+ ])
5137
+ )
5138
+ ),
5114
5139
  resultItems,
5115
5140
  experimentId,
5116
5141
  fullExperimentUrl
@@ -11467,6 +11492,12 @@ var Bitfab = class {
11467
11492
  }
11468
11493
  return this.httpClient.getTraceSpan(traceId, lookup);
11469
11494
  }
11495
+ async getSpan(spanId) {
11496
+ if (typeof spanId !== "string" || spanId.trim().length === 0) {
11497
+ throw new BitfabError("spanId must be a non-empty string");
11498
+ }
11499
+ return this.httpClient.getSpan(spanId);
11500
+ }
11470
11501
  /**
11471
11502
  * Get a function wrapper for a specific trace function key.
11472
11503
  *