bitfab 0.41.0 → 0.42.0

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/index.d.cts CHANGED
@@ -306,6 +306,7 @@ interface ReplayContext {
306
306
  * customer sees in the Bitfab dashboard.
307
307
  */
308
308
  sourceBitfabTraceId?: string;
309
+ replayAttempt?: number;
309
310
  mockTree?: MockTree;
310
311
  callCounters?: Map<string, number>;
311
312
  mockStrategy?: "none" | "all" | "marked";
@@ -584,7 +585,7 @@ declare class HttpClient {
584
585
  * Start a replay session by fetching historical traces.
585
586
  * Blocking call - creates a test run and returns lightweight item references.
586
587
  */
587
- startReplay(traceFunctionKey: string, limit: number | undefined, traceIds?: string[], name?: string, codeChangeDescription?: string | null, codeChangeFiles?: CodeChangeFile[] | null, includeDbBranchLease?: boolean, experimentGroupId?: string, datasetId?: string, graderIds?: string[], dbBranchSettings?: DbBranchSettings): Promise<StartReplayResponse>;
588
+ startReplay(traceFunctionKey: string, limit: number | undefined, traceIds?: string[], name?: string, codeChangeDescription?: string | null, codeChangeFiles?: CodeChangeFile[] | null, includeDbBranchLease?: boolean, experimentGroupId?: string, datasetId?: string, graderIds?: string[], dbBranchSettings?: DbBranchSettings, attempts?: number): Promise<StartReplayResponse>;
588
589
  /**
589
590
  * Fetch an external span by ID.
590
591
  * Blocking GET request.
@@ -625,7 +626,7 @@ declare class HttpClient {
625
626
  * snapshot + preview branch and polls operations to readiness, which
626
627
  * can take seconds.
627
628
  */
628
- resolveDbBranchLease(testRunId: string, traceId: string, dbBranchSettings?: DbBranchSettings): Promise<{
629
+ resolveDbBranchLease(testRunId: string, traceId: string, dbBranchSettings?: DbBranchSettings, attempt?: number): Promise<{
629
630
  dbSnapshotRef: DbSnapshotRef | null;
630
631
  lease: DbBranchLease | null;
631
632
  leaseError: {
@@ -658,6 +659,7 @@ interface CodeChangeFile {
658
659
  interface StartReplayResponse {
659
660
  testRunId: string;
660
661
  testRunUrl: string;
662
+ attempts?: number;
661
663
  items: Array<{
662
664
  /** Bitfab trace ID of the original (historical) trace being replayed. */
663
665
  originalTraceId?: string;
@@ -1472,6 +1474,7 @@ interface ReplayOptions {
1472
1474
  * because either source already determines how many traces replay.
1473
1475
  */
1474
1476
  limit?: number;
1477
+ attempts?: number;
1475
1478
  /** Optional list of specific trace IDs to replay (max 100). Mutually exclusive with `datasetId`. */
1476
1479
  traceIds?: string[];
1477
1480
  /** Optional display name for the resulting experiment/test run. */
@@ -1624,6 +1627,7 @@ interface ReplayItemStartProgress {
1624
1627
  sourceTraceId: string;
1625
1628
  /** @deprecated alias for `originalSpanId`. */
1626
1629
  sourceSpanId: string;
1630
+ attempt: number;
1627
1631
  };
1628
1632
  }
1629
1633
  /** Running totals reported to {@link ReplayOptions.onItemFinish} as replay proceeds. */
@@ -1663,6 +1667,7 @@ interface ReplayProgressItem {
1663
1667
  sourceTraceId: string | null;
1664
1668
  /** @deprecated alias for `originalSpanId`. */
1665
1669
  sourceSpanId?: string | null;
1670
+ attempt: number;
1666
1671
  /** Deserialized inputs from the original trace. */
1667
1672
  input?: unknown[];
1668
1673
  /** The result returned by the replayed function, or undefined on error. */
@@ -1772,6 +1777,7 @@ interface ReplayItem<T> {
1772
1777
  sourceTraceId: string;
1773
1778
  /** @deprecated alias for {@link ReplayItem.originalSpanId}. */
1774
1779
  sourceSpanId: string;
1780
+ attempt: number;
1775
1781
  /** Deserialized inputs from the original trace. */
1776
1782
  input: unknown[];
1777
1783
  /** The result returned by the function during replay, or undefined on error. */
@@ -1850,6 +1856,7 @@ interface ReplayResult<T> {
1850
1856
  testRunId: string;
1851
1857
  /** Full URL to view the test run in the dashboard. */
1852
1858
  testRunUrl: string;
1859
+ attempts: number;
1853
1860
  }
1854
1861
  /**
1855
1862
  * Whole-run replay failure that preserves every item collected before the run
@@ -3100,7 +3107,7 @@ declare class BitfabFunction {
3100
3107
  /**
3101
3108
  * SDK version from package.json (injected at build time)
3102
3109
  */
3103
- declare const __version__ = "0.41.0";
3110
+ declare const __version__ = "0.42.0";
3104
3111
 
3105
3112
  /**
3106
3113
  * Constants for the Bitfab SDK.
package/dist/index.d.ts CHANGED
@@ -306,6 +306,7 @@ interface ReplayContext {
306
306
  * customer sees in the Bitfab dashboard.
307
307
  */
308
308
  sourceBitfabTraceId?: string;
309
+ replayAttempt?: number;
309
310
  mockTree?: MockTree;
310
311
  callCounters?: Map<string, number>;
311
312
  mockStrategy?: "none" | "all" | "marked";
@@ -584,7 +585,7 @@ declare class HttpClient {
584
585
  * Start a replay session by fetching historical traces.
585
586
  * Blocking call - creates a test run and returns lightweight item references.
586
587
  */
587
- startReplay(traceFunctionKey: string, limit: number | undefined, traceIds?: string[], name?: string, codeChangeDescription?: string | null, codeChangeFiles?: CodeChangeFile[] | null, includeDbBranchLease?: boolean, experimentGroupId?: string, datasetId?: string, graderIds?: string[], dbBranchSettings?: DbBranchSettings): Promise<StartReplayResponse>;
588
+ startReplay(traceFunctionKey: string, limit: number | undefined, traceIds?: string[], name?: string, codeChangeDescription?: string | null, codeChangeFiles?: CodeChangeFile[] | null, includeDbBranchLease?: boolean, experimentGroupId?: string, datasetId?: string, graderIds?: string[], dbBranchSettings?: DbBranchSettings, attempts?: number): Promise<StartReplayResponse>;
588
589
  /**
589
590
  * Fetch an external span by ID.
590
591
  * Blocking GET request.
@@ -625,7 +626,7 @@ declare class HttpClient {
625
626
  * snapshot + preview branch and polls operations to readiness, which
626
627
  * can take seconds.
627
628
  */
628
- resolveDbBranchLease(testRunId: string, traceId: string, dbBranchSettings?: DbBranchSettings): Promise<{
629
+ resolveDbBranchLease(testRunId: string, traceId: string, dbBranchSettings?: DbBranchSettings, attempt?: number): Promise<{
629
630
  dbSnapshotRef: DbSnapshotRef | null;
630
631
  lease: DbBranchLease | null;
631
632
  leaseError: {
@@ -658,6 +659,7 @@ interface CodeChangeFile {
658
659
  interface StartReplayResponse {
659
660
  testRunId: string;
660
661
  testRunUrl: string;
662
+ attempts?: number;
661
663
  items: Array<{
662
664
  /** Bitfab trace ID of the original (historical) trace being replayed. */
663
665
  originalTraceId?: string;
@@ -1472,6 +1474,7 @@ interface ReplayOptions {
1472
1474
  * because either source already determines how many traces replay.
1473
1475
  */
1474
1476
  limit?: number;
1477
+ attempts?: number;
1475
1478
  /** Optional list of specific trace IDs to replay (max 100). Mutually exclusive with `datasetId`. */
1476
1479
  traceIds?: string[];
1477
1480
  /** Optional display name for the resulting experiment/test run. */
@@ -1624,6 +1627,7 @@ interface ReplayItemStartProgress {
1624
1627
  sourceTraceId: string;
1625
1628
  /** @deprecated alias for `originalSpanId`. */
1626
1629
  sourceSpanId: string;
1630
+ attempt: number;
1627
1631
  };
1628
1632
  }
1629
1633
  /** Running totals reported to {@link ReplayOptions.onItemFinish} as replay proceeds. */
@@ -1663,6 +1667,7 @@ interface ReplayProgressItem {
1663
1667
  sourceTraceId: string | null;
1664
1668
  /** @deprecated alias for `originalSpanId`. */
1665
1669
  sourceSpanId?: string | null;
1670
+ attempt: number;
1666
1671
  /** Deserialized inputs from the original trace. */
1667
1672
  input?: unknown[];
1668
1673
  /** The result returned by the replayed function, or undefined on error. */
@@ -1772,6 +1777,7 @@ interface ReplayItem<T> {
1772
1777
  sourceTraceId: string;
1773
1778
  /** @deprecated alias for {@link ReplayItem.originalSpanId}. */
1774
1779
  sourceSpanId: string;
1780
+ attempt: number;
1775
1781
  /** Deserialized inputs from the original trace. */
1776
1782
  input: unknown[];
1777
1783
  /** The result returned by the function during replay, or undefined on error. */
@@ -1850,6 +1856,7 @@ interface ReplayResult<T> {
1850
1856
  testRunId: string;
1851
1857
  /** Full URL to view the test run in the dashboard. */
1852
1858
  testRunUrl: string;
1859
+ attempts: number;
1853
1860
  }
1854
1861
  /**
1855
1862
  * Whole-run replay failure that preserves every item collected before the run
@@ -3100,7 +3107,7 @@ declare class BitfabFunction {
3100
3107
  /**
3101
3108
  * SDK version from package.json (injected at build time)
3102
3109
  */
3103
- declare const __version__ = "0.41.0";
3110
+ declare const __version__ = "0.42.0";
3104
3111
 
3105
3112
  /**
3106
3113
  * Constants for the Bitfab SDK.
package/dist/index.js CHANGED
@@ -24,7 +24,7 @@ import {
24
24
  getCurrentSpan,
25
25
  getCurrentTrace,
26
26
  seedFromRegistry
27
- } from "./chunk-7NLXU444.js";
27
+ } from "./chunk-GUKZZRAA.js";
28
28
  import "./chunk-ZUD7OFYB.js";
29
29
  import {
30
30
  BITFAB_PROGRESS_PREFIX,
@@ -33,14 +33,14 @@ import {
33
33
  ReplayError,
34
34
  reportReplayProgress,
35
35
  serializeReplayResult
36
- } from "./chunk-7VQJ2ABI.js";
36
+ } from "./chunk-73EBNSFJ.js";
37
37
  import {
38
38
  BitfabError,
39
39
  DEFAULT_SERVICE_URL,
40
40
  HttpClient,
41
41
  __version__,
42
42
  flushTraces
43
- } from "./chunk-T3JPGYBQ.js";
43
+ } from "./chunk-PDPMZA4Y.js";
44
44
  import "./chunk-H6LZRFMN.js";
45
45
  export {
46
46
  BITFAB_PROGRESS_PREFIX,
package/dist/node.cjs CHANGED
@@ -97,7 +97,7 @@ var __version__, __packageName__;
97
97
  var init_version_generated = __esm({
98
98
  "src/version.generated.ts"() {
99
99
  "use strict";
100
- __version__ = "0.41.0";
100
+ __version__ = "0.42.0";
101
101
  __packageName__ = "bitfab";
102
102
  }
103
103
  });
@@ -1353,7 +1353,7 @@ function sourceTraceIdOf(payload) {
1353
1353
  const id = rawTrace?.id;
1354
1354
  return typeof id === "string" ? id : void 0;
1355
1355
  }
1356
- var REPLAY_DB_BRANCH_REQUEST_TIMEOUT_MS, OTLP_TRACES_ENDPOINT, RETRYABLE_STATUSES, EXIT_FLUSH_TIMEOUT_MS, DEFAULT_LIFECYCLE_TIMEOUT_MS2, pendingTracePromises, carrierSeq, HttpClient;
1356
+ var REPLAY_DB_BRANCH_REQUEST_TIMEOUT_MS, REPLAY_COMPLETE_REQUEST_TIMEOUT_MS, OTLP_TRACES_ENDPOINT, RETRYABLE_STATUSES, EXIT_FLUSH_TIMEOUT_MS, DEFAULT_LIFECYCLE_TIMEOUT_MS2, pendingTracePromises, carrierSeq, HttpClient;
1357
1357
  var init_http = __esm({
1358
1358
  "src/http.ts"() {
1359
1359
  "use strict";
@@ -1367,6 +1367,7 @@ var init_http = __esm({
1367
1367
  init_unrefTimer();
1368
1368
  init_warnOnce();
1369
1369
  REPLAY_DB_BRANCH_REQUEST_TIMEOUT_MS = 3e5;
1370
+ REPLAY_COMPLETE_REQUEST_TIMEOUT_MS = 12e4;
1370
1371
  OTLP_TRACES_ENDPOINT = "/api/sdk/otel/v1/traces";
1371
1372
  RETRYABLE_STATUSES = /* @__PURE__ */ new Set([429, 500, 502, 503, 504]);
1372
1373
  EXIT_FLUSH_TIMEOUT_MS = 5e3;
@@ -1856,7 +1857,7 @@ var init_http = __esm({
1856
1857
  * Start a replay session by fetching historical traces.
1857
1858
  * Blocking call - creates a test run and returns lightweight item references.
1858
1859
  */
1859
- async startReplay(traceFunctionKey, limit, traceIds, name, codeChangeDescription, codeChangeFiles, includeDbBranchLease, experimentGroupId, datasetId, graderIds, dbBranchSettings) {
1860
+ async startReplay(traceFunctionKey, limit, traceIds, name, codeChangeDescription, codeChangeFiles, includeDbBranchLease, experimentGroupId, datasetId, graderIds, dbBranchSettings, attempts) {
1860
1861
  const payload = { traceFunctionKey };
1861
1862
  if (limit !== void 0) {
1862
1863
  payload.limit = limit;
@@ -1889,6 +1890,9 @@ var init_http = __esm({
1889
1890
  if (dbBranchSettings !== void 0) {
1890
1891
  payload.dbBranchSettings = dbBranchSettings;
1891
1892
  }
1893
+ if (attempts !== void 0 && attempts > 1) {
1894
+ payload.attempts = attempts;
1895
+ }
1892
1896
  const timeout = includeDbBranchLease ? REPLAY_DB_BRANCH_REQUEST_TIMEOUT_MS : 3e4;
1893
1897
  return this.request("/api/sdk/replay/start", payload, {
1894
1898
  timeout
@@ -2004,7 +2008,7 @@ var init_http = __esm({
2004
2008
  return this.request(
2005
2009
  "/api/sdk/replay/complete",
2006
2010
  { testRunId },
2007
- { timeout: 3e4 }
2011
+ { timeout: REPLAY_COMPLETE_REQUEST_TIMEOUT_MS }
2008
2012
  );
2009
2013
  }
2010
2014
  /**
@@ -2013,10 +2017,15 @@ var init_http = __esm({
2013
2017
  * snapshot + preview branch and polls operations to readiness, which
2014
2018
  * can take seconds.
2015
2019
  */
2016
- async resolveDbBranchLease(testRunId, traceId, dbBranchSettings) {
2020
+ async resolveDbBranchLease(testRunId, traceId, dbBranchSettings, attempt) {
2017
2021
  return this.request(
2018
2022
  "/api/sdk/replay/resolveDbBranchLease",
2019
- { testRunId, traceId, dbBranchSettings },
2023
+ {
2024
+ testRunId,
2025
+ traceId,
2026
+ dbBranchSettings,
2027
+ ...attempt !== void 0 && attempt > 0 ? { attempt } : {}
2028
+ },
2020
2029
  { timeout: REPLAY_DB_BRANCH_REQUEST_TIMEOUT_MS }
2021
2030
  );
2022
2031
  }
@@ -2452,6 +2461,23 @@ __export(replay_exports, {
2452
2461
  sleepForReplayPersistence: () => sleepForReplayPersistence,
2453
2462
  waitForReplayPersistence: () => waitForReplayPersistence
2454
2463
  });
2464
+ function expandReplayWork(serverItems, attempts) {
2465
+ return Array.from(
2466
+ { length: attempts },
2467
+ (_, attempt) => serverItems.map((serverItem) => ({ serverItem, attempt }))
2468
+ ).flat();
2469
+ }
2470
+ function resolveAttempts(attempts) {
2471
+ if (attempts === void 0) {
2472
+ return 1;
2473
+ }
2474
+ if (!Number.isInteger(attempts) || attempts < 1 || attempts > MAX_REPLAY_ATTEMPTS) {
2475
+ throw new BitfabError(
2476
+ `attempts must be an integer from 1 to ${MAX_REPLAY_ATTEMPTS} (got ${attempts}).`
2477
+ );
2478
+ }
2479
+ return attempts;
2480
+ }
2455
2481
  function dbBranchEnabled(dbBranch) {
2456
2482
  return dbBranch !== void 0 && dbBranch !== false;
2457
2483
  }
@@ -2575,7 +2601,7 @@ function buildMockTree(rootNode) {
2575
2601
  }
2576
2602
  return { spans };
2577
2603
  }
2578
- async function processItem(httpClient, serverItem, fn, testRunId, mockStrategy, resolvedOverrides, replayedTraceId, includeDbBranchLease, dbBranchSettings, adaptInputs, dryRun) {
2604
+ async function processItem(httpClient, serverItem, fn, testRunId, mockStrategy, resolvedOverrides, replayedTraceId, attempt, includeDbBranchLease, dbBranchSettings, adaptInputs, dryRun) {
2579
2605
  let lease = includeDbBranchLease ? serverItem.dbBranchLease : void 0;
2580
2606
  let leaseError = includeDbBranchLease ? serverItem.dbBranchLeaseError : void 0;
2581
2607
  let dbSnapshotRef = serverItem.dbSnapshotRef;
@@ -2597,7 +2623,8 @@ async function processItem(httpClient, serverItem, fn, testRunId, mockStrategy,
2597
2623
  resolved = await httpClient.resolveDbBranchLease(
2598
2624
  testRunId,
2599
2625
  originalTraceId,
2600
- dbBranchSettings
2626
+ dbBranchSettings,
2627
+ attempt
2601
2628
  );
2602
2629
  } catch (cause) {
2603
2630
  throw new DbBranchReplayError(
@@ -2677,6 +2704,7 @@ async function processItem(httpClient, serverItem, fn, testRunId, mockStrategy,
2677
2704
  originalSpanId,
2678
2705
  sourceTraceId: originalTraceId,
2679
2706
  sourceSpanId: originalSpanId,
2707
+ attempt,
2680
2708
  input: inputs,
2681
2709
  result: void 0,
2682
2710
  originalOutput,
@@ -2705,6 +2733,7 @@ async function processItem(httpClient, serverItem, fn, testRunId, mockStrategy,
2705
2733
  inputSourceSpanId: span.id,
2706
2734
  inputSourceTraceId: span.externalTraceId,
2707
2735
  sourceBitfabTraceId: originalTraceId,
2736
+ replayAttempt: attempt,
2708
2737
  mockTree,
2709
2738
  callCounters: mockTree ? /* @__PURE__ */ new Map() : void 0,
2710
2739
  mockStrategy,
@@ -2756,6 +2785,7 @@ async function processItem(httpClient, serverItem, fn, testRunId, mockStrategy,
2756
2785
  // Deprecated aliases for originalTraceId/originalSpanId.
2757
2786
  sourceTraceId: originalTraceId,
2758
2787
  sourceSpanId: originalSpanId,
2788
+ attempt,
2759
2789
  input: inputs,
2760
2790
  result,
2761
2791
  originalOutput,
@@ -2884,6 +2914,7 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
2884
2914
  } catch {
2885
2915
  }
2886
2916
  }
2917
+ const attempts = resolveAttempts(options?.attempts);
2887
2918
  await replayContextReady;
2888
2919
  let codeChangeDescription = options?.codeChangeDescription;
2889
2920
  let codeChangeFiles = options?.codeChangeFiles;
@@ -2916,7 +2947,8 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
2916
2947
  options?.experimentGroupId,
2917
2948
  options?.datasetId,
2918
2949
  options?.graderIds,
2919
- resolveDbBranchSettings(options?.dbBranch)
2950
+ resolveDbBranchSettings(options?.dbBranch),
2951
+ attempts
2920
2952
  );
2921
2953
  if (serverItems.length === 0) {
2922
2954
  try {
@@ -2933,10 +2965,11 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
2933
2965
  ...normalizeMockOverrides(options?.mockOverride),
2934
2966
  ...registeredOverrides
2935
2967
  ];
2936
- const replayedTraceIds = serverItems.map(() => randomUuid());
2968
+ const workItems = expandReplayWork(serverItems, attempts);
2969
+ const replayedTraceIds = workItems.map(() => randomUuid());
2937
2970
  httpClient.trackTraceDeliveries(replayedTraceIds);
2938
- const tasks = serverItems.map(
2939
- (serverItem, index) => () => processItem(
2971
+ const tasks = workItems.map(
2972
+ ({ serverItem, attempt }, index) => () => processItem(
2940
2973
  httpClient,
2941
2974
  serverItem,
2942
2975
  fn,
@@ -2944,6 +2977,7 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
2944
2977
  mockStrategy,
2945
2978
  resolvedOverrides,
2946
2979
  replayedTraceIds[index],
2980
+ attempt,
2947
2981
  dbBranchEnabled(options?.dbBranch) && options?.dryRun !== true,
2948
2982
  resolveDbBranchSettings(options?.dbBranch),
2949
2983
  options?.adaptInputs,
@@ -3011,6 +3045,7 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
3011
3045
  // Deprecated aliases for originalTraceId/originalSpanId.
3012
3046
  sourceTraceId: item.originalTraceId ?? null,
3013
3047
  sourceSpanId: item.originalSpanId ?? null,
3048
+ attempt: item.attempt,
3014
3049
  input: item.input,
3015
3050
  result: item.result,
3016
3051
  originalOutput: item.originalOutput,
@@ -3032,7 +3067,7 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
3032
3067
  },
3033
3068
  options?.onItemStart ? (index) => {
3034
3069
  started += 1;
3035
- const serverItem = serverItems[index];
3070
+ const { serverItem, attempt } = workItems[index];
3036
3071
  const originalTraceId = serverItem.originalTraceId ?? serverItem.sourceTraceId;
3037
3072
  const originalSpanId = serverItem.originalSpanId ?? serverItem.sourceSpanId;
3038
3073
  try {
@@ -3048,7 +3083,8 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
3048
3083
  originalTraceId,
3049
3084
  originalSpanId,
3050
3085
  sourceTraceId: originalTraceId,
3051
- sourceSpanId: originalSpanId
3086
+ sourceSpanId: originalSpanId,
3087
+ attempt
3052
3088
  }
3053
3089
  });
3054
3090
  } catch {
@@ -3060,7 +3096,8 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
3060
3096
  const dryResult = {
3061
3097
  items: resultItems,
3062
3098
  testRunId,
3063
- testRunUrl: fullTestRunUrl
3099
+ testRunUrl: fullTestRunUrl,
3100
+ attempts
3064
3101
  };
3065
3102
  await writeReplayResultFile(dryResult);
3066
3103
  return dryResult;
@@ -3129,7 +3166,8 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
3129
3166
  const result = {
3130
3167
  items: resultItems,
3131
3168
  testRunId,
3132
- testRunUrl: fullTestRunUrl
3169
+ testRunUrl: fullTestRunUrl,
3170
+ attempts
3133
3171
  };
3134
3172
  await writeReplayResultFile(result);
3135
3173
  if (!options?.onItemFinish) {
@@ -3170,7 +3208,7 @@ async function writeReplayResultFile(result) {
3170
3208
  }
3171
3209
  }
3172
3210
  }
3173
- var REPLAY_PERSISTENCE_TIMEOUT_MS, BITFAB_PROGRESS_PREFIX, ReplayError, DbBranchReplayError;
3211
+ var REPLAY_PERSISTENCE_TIMEOUT_MS, MAX_REPLAY_ATTEMPTS, BITFAB_PROGRESS_PREFIX, ReplayError, DbBranchReplayError;
3174
3212
  var init_replay = __esm({
3175
3213
  "src/replay.ts"() {
3176
3214
  "use strict";
@@ -3182,6 +3220,7 @@ var init_replay = __esm({
3182
3220
  init_replayContext();
3183
3221
  init_serialize();
3184
3222
  REPLAY_PERSISTENCE_TIMEOUT_MS = 3e4;
3223
+ MAX_REPLAY_ATTEMPTS = 100;
3185
3224
  BITFAB_PROGRESS_PREFIX = "@@bitfab:progress ";
3186
3225
  ReplayError = class extends BitfabError {
3187
3226
  constructor(message, items, testRunId, testRunUrl, cause) {
@@ -7035,6 +7074,9 @@ var Bitfab = class {
7035
7074
  ...replayCtxAtStart?.inputSourceTraceId && {
7036
7075
  inputSourceTraceId: replayCtxAtStart.inputSourceTraceId
7037
7076
  },
7077
+ ...replayCtxAtStart?.replayAttempt !== void 0 && {
7078
+ replayAttempt: replayCtxAtStart.replayAttempt
7079
+ },
7038
7080
  dbSnapshotRef
7039
7081
  });
7040
7082
  registeredTraceId = traceId;
@@ -7085,6 +7127,7 @@ var Bitfab = class {
7085
7127
  contexts: traceState?.contexts ?? [],
7086
7128
  testRunId: traceState?.testRunId,
7087
7129
  inputSourceTraceId: traceState?.inputSourceTraceId,
7130
+ replayAttempt: traceState?.replayAttempt,
7088
7131
  dbSnapshotRef: traceState?.dbSnapshotRef,
7089
7132
  dropped: traceState?.dropped,
7090
7133
  ingestionType: traceState?.ingestionType,
@@ -7482,6 +7525,9 @@ var Bitfab = class {
7482
7525
  if (params.inputSourceTraceId) {
7483
7526
  rawTrace.input_source_trace_id = params.inputSourceTraceId;
7484
7527
  }
7528
+ if (params.replayAttempt !== void 0) {
7529
+ rawTrace.replay_attempt = params.replayAttempt;
7530
+ }
7485
7531
  if (params.dbSnapshotRef) {
7486
7532
  rawTrace.db_snapshot_ref = params.dbSnapshotRef;
7487
7533
  }