@bitfab/sdk 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.cjs CHANGED
@@ -42,7 +42,7 @@ var __version__, __packageName__;
42
42
  var init_version_generated = __esm({
43
43
  "src/version.generated.ts"() {
44
44
  "use strict";
45
- __version__ = "0.41.0";
45
+ __version__ = "0.42.0";
46
46
  __packageName__ = "@bitfab/sdk";
47
47
  }
48
48
  });
@@ -1337,7 +1337,7 @@ function sourceTraceIdOf(payload) {
1337
1337
  const id = rawTrace?.id;
1338
1338
  return typeof id === "string" ? id : void 0;
1339
1339
  }
1340
- var REPLAY_DB_BRANCH_REQUEST_TIMEOUT_MS, OTLP_TRACES_ENDPOINT, RETRYABLE_STATUSES, EXIT_FLUSH_TIMEOUT_MS, DEFAULT_LIFECYCLE_TIMEOUT_MS2, pendingTracePromises, carrierSeq, HttpClient;
1340
+ 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;
1341
1341
  var init_http = __esm({
1342
1342
  "src/http.ts"() {
1343
1343
  "use strict";
@@ -1351,6 +1351,7 @@ var init_http = __esm({
1351
1351
  init_unrefTimer();
1352
1352
  init_warnOnce();
1353
1353
  REPLAY_DB_BRANCH_REQUEST_TIMEOUT_MS = 3e5;
1354
+ REPLAY_COMPLETE_REQUEST_TIMEOUT_MS = 12e4;
1354
1355
  OTLP_TRACES_ENDPOINT = "/api/sdk/otel/v1/traces";
1355
1356
  RETRYABLE_STATUSES = /* @__PURE__ */ new Set([429, 500, 502, 503, 504]);
1356
1357
  EXIT_FLUSH_TIMEOUT_MS = 5e3;
@@ -1840,7 +1841,7 @@ var init_http = __esm({
1840
1841
  * Start a replay session by fetching historical traces.
1841
1842
  * Blocking call - creates a test run and returns lightweight item references.
1842
1843
  */
1843
- async startReplay(traceFunctionKey, limit, traceIds, name, codeChangeDescription, codeChangeFiles, includeDbBranchLease, experimentGroupId, datasetId, graderIds, dbBranchSettings) {
1844
+ async startReplay(traceFunctionKey, limit, traceIds, name, codeChangeDescription, codeChangeFiles, includeDbBranchLease, experimentGroupId, datasetId, graderIds, dbBranchSettings, attempts) {
1844
1845
  const payload = { traceFunctionKey };
1845
1846
  if (limit !== void 0) {
1846
1847
  payload.limit = limit;
@@ -1873,6 +1874,9 @@ var init_http = __esm({
1873
1874
  if (dbBranchSettings !== void 0) {
1874
1875
  payload.dbBranchSettings = dbBranchSettings;
1875
1876
  }
1877
+ if (attempts !== void 0 && attempts > 1) {
1878
+ payload.attempts = attempts;
1879
+ }
1876
1880
  const timeout = includeDbBranchLease ? REPLAY_DB_BRANCH_REQUEST_TIMEOUT_MS : 3e4;
1877
1881
  return this.request("/api/sdk/replay/start", payload, {
1878
1882
  timeout
@@ -1988,7 +1992,7 @@ var init_http = __esm({
1988
1992
  return this.request(
1989
1993
  "/api/sdk/replay/complete",
1990
1994
  { testRunId },
1991
- { timeout: 3e4 }
1995
+ { timeout: REPLAY_COMPLETE_REQUEST_TIMEOUT_MS }
1992
1996
  );
1993
1997
  }
1994
1998
  /**
@@ -1997,10 +2001,15 @@ var init_http = __esm({
1997
2001
  * snapshot + preview branch and polls operations to readiness, which
1998
2002
  * can take seconds.
1999
2003
  */
2000
- async resolveDbBranchLease(testRunId, traceId, dbBranchSettings) {
2004
+ async resolveDbBranchLease(testRunId, traceId, dbBranchSettings, attempt) {
2001
2005
  return this.request(
2002
2006
  "/api/sdk/replay/resolveDbBranchLease",
2003
- { testRunId, traceId, dbBranchSettings },
2007
+ {
2008
+ testRunId,
2009
+ traceId,
2010
+ dbBranchSettings,
2011
+ ...attempt !== void 0 && attempt > 0 ? { attempt } : {}
2012
+ },
2004
2013
  { timeout: REPLAY_DB_BRANCH_REQUEST_TIMEOUT_MS }
2005
2014
  );
2006
2015
  }
@@ -2436,6 +2445,23 @@ __export(replay_exports, {
2436
2445
  sleepForReplayPersistence: () => sleepForReplayPersistence,
2437
2446
  waitForReplayPersistence: () => waitForReplayPersistence
2438
2447
  });
2448
+ function expandReplayWork(serverItems, attempts) {
2449
+ return Array.from(
2450
+ { length: attempts },
2451
+ (_, attempt) => serverItems.map((serverItem) => ({ serverItem, attempt }))
2452
+ ).flat();
2453
+ }
2454
+ function resolveAttempts(attempts) {
2455
+ if (attempts === void 0) {
2456
+ return 1;
2457
+ }
2458
+ if (!Number.isInteger(attempts) || attempts < 1 || attempts > MAX_REPLAY_ATTEMPTS) {
2459
+ throw new BitfabError(
2460
+ `attempts must be an integer from 1 to ${MAX_REPLAY_ATTEMPTS} (got ${attempts}).`
2461
+ );
2462
+ }
2463
+ return attempts;
2464
+ }
2439
2465
  function dbBranchEnabled(dbBranch) {
2440
2466
  return dbBranch !== void 0 && dbBranch !== false;
2441
2467
  }
@@ -2559,7 +2585,7 @@ function buildMockTree(rootNode) {
2559
2585
  }
2560
2586
  return { spans };
2561
2587
  }
2562
- async function processItem(httpClient, serverItem, fn, testRunId, mockStrategy, resolvedOverrides, replayedTraceId, includeDbBranchLease, dbBranchSettings, adaptInputs, dryRun) {
2588
+ async function processItem(httpClient, serverItem, fn, testRunId, mockStrategy, resolvedOverrides, replayedTraceId, attempt, includeDbBranchLease, dbBranchSettings, adaptInputs, dryRun) {
2563
2589
  let lease = includeDbBranchLease ? serverItem.dbBranchLease : void 0;
2564
2590
  let leaseError = includeDbBranchLease ? serverItem.dbBranchLeaseError : void 0;
2565
2591
  let dbSnapshotRef = serverItem.dbSnapshotRef;
@@ -2581,7 +2607,8 @@ async function processItem(httpClient, serverItem, fn, testRunId, mockStrategy,
2581
2607
  resolved = await httpClient.resolveDbBranchLease(
2582
2608
  testRunId,
2583
2609
  originalTraceId,
2584
- dbBranchSettings
2610
+ dbBranchSettings,
2611
+ attempt
2585
2612
  );
2586
2613
  } catch (cause) {
2587
2614
  throw new DbBranchReplayError(
@@ -2661,6 +2688,7 @@ async function processItem(httpClient, serverItem, fn, testRunId, mockStrategy,
2661
2688
  originalSpanId,
2662
2689
  sourceTraceId: originalTraceId,
2663
2690
  sourceSpanId: originalSpanId,
2691
+ attempt,
2664
2692
  input: inputs,
2665
2693
  result: void 0,
2666
2694
  originalOutput,
@@ -2689,6 +2717,7 @@ async function processItem(httpClient, serverItem, fn, testRunId, mockStrategy,
2689
2717
  inputSourceSpanId: span.id,
2690
2718
  inputSourceTraceId: span.externalTraceId,
2691
2719
  sourceBitfabTraceId: originalTraceId,
2720
+ replayAttempt: attempt,
2692
2721
  mockTree,
2693
2722
  callCounters: mockTree ? /* @__PURE__ */ new Map() : void 0,
2694
2723
  mockStrategy,
@@ -2740,6 +2769,7 @@ async function processItem(httpClient, serverItem, fn, testRunId, mockStrategy,
2740
2769
  // Deprecated aliases for originalTraceId/originalSpanId.
2741
2770
  sourceTraceId: originalTraceId,
2742
2771
  sourceSpanId: originalSpanId,
2772
+ attempt,
2743
2773
  input: inputs,
2744
2774
  result,
2745
2775
  originalOutput,
@@ -2868,6 +2898,7 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
2868
2898
  } catch {
2869
2899
  }
2870
2900
  }
2901
+ const attempts = resolveAttempts(options?.attempts);
2871
2902
  await replayContextReady;
2872
2903
  let codeChangeDescription = options?.codeChangeDescription;
2873
2904
  let codeChangeFiles = options?.codeChangeFiles;
@@ -2900,7 +2931,8 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
2900
2931
  options?.experimentGroupId,
2901
2932
  options?.datasetId,
2902
2933
  options?.graderIds,
2903
- resolveDbBranchSettings(options?.dbBranch)
2934
+ resolveDbBranchSettings(options?.dbBranch),
2935
+ attempts
2904
2936
  );
2905
2937
  if (serverItems.length === 0) {
2906
2938
  try {
@@ -2917,10 +2949,11 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
2917
2949
  ...normalizeMockOverrides(options?.mockOverride),
2918
2950
  ...registeredOverrides
2919
2951
  ];
2920
- const replayedTraceIds = serverItems.map(() => randomUuid());
2952
+ const workItems = expandReplayWork(serverItems, attempts);
2953
+ const replayedTraceIds = workItems.map(() => randomUuid());
2921
2954
  httpClient.trackTraceDeliveries(replayedTraceIds);
2922
- const tasks = serverItems.map(
2923
- (serverItem, index) => () => processItem(
2955
+ const tasks = workItems.map(
2956
+ ({ serverItem, attempt }, index) => () => processItem(
2924
2957
  httpClient,
2925
2958
  serverItem,
2926
2959
  fn,
@@ -2928,6 +2961,7 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
2928
2961
  mockStrategy,
2929
2962
  resolvedOverrides,
2930
2963
  replayedTraceIds[index],
2964
+ attempt,
2931
2965
  dbBranchEnabled(options?.dbBranch) && options?.dryRun !== true,
2932
2966
  resolveDbBranchSettings(options?.dbBranch),
2933
2967
  options?.adaptInputs,
@@ -2995,6 +3029,7 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
2995
3029
  // Deprecated aliases for originalTraceId/originalSpanId.
2996
3030
  sourceTraceId: item.originalTraceId ?? null,
2997
3031
  sourceSpanId: item.originalSpanId ?? null,
3032
+ attempt: item.attempt,
2998
3033
  input: item.input,
2999
3034
  result: item.result,
3000
3035
  originalOutput: item.originalOutput,
@@ -3016,7 +3051,7 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
3016
3051
  },
3017
3052
  options?.onItemStart ? (index) => {
3018
3053
  started += 1;
3019
- const serverItem = serverItems[index];
3054
+ const { serverItem, attempt } = workItems[index];
3020
3055
  const originalTraceId = serverItem.originalTraceId ?? serverItem.sourceTraceId;
3021
3056
  const originalSpanId = serverItem.originalSpanId ?? serverItem.sourceSpanId;
3022
3057
  try {
@@ -3032,7 +3067,8 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
3032
3067
  originalTraceId,
3033
3068
  originalSpanId,
3034
3069
  sourceTraceId: originalTraceId,
3035
- sourceSpanId: originalSpanId
3070
+ sourceSpanId: originalSpanId,
3071
+ attempt
3036
3072
  }
3037
3073
  });
3038
3074
  } catch {
@@ -3044,7 +3080,8 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
3044
3080
  const dryResult = {
3045
3081
  items: resultItems,
3046
3082
  testRunId,
3047
- testRunUrl: fullTestRunUrl
3083
+ testRunUrl: fullTestRunUrl,
3084
+ attempts
3048
3085
  };
3049
3086
  await writeReplayResultFile(dryResult);
3050
3087
  return dryResult;
@@ -3113,7 +3150,8 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
3113
3150
  const result = {
3114
3151
  items: resultItems,
3115
3152
  testRunId,
3116
- testRunUrl: fullTestRunUrl
3153
+ testRunUrl: fullTestRunUrl,
3154
+ attempts
3117
3155
  };
3118
3156
  await writeReplayResultFile(result);
3119
3157
  if (!options?.onItemFinish) {
@@ -3154,7 +3192,7 @@ async function writeReplayResultFile(result) {
3154
3192
  }
3155
3193
  }
3156
3194
  }
3157
- var REPLAY_PERSISTENCE_TIMEOUT_MS, BITFAB_PROGRESS_PREFIX, ReplayError, DbBranchReplayError;
3195
+ var REPLAY_PERSISTENCE_TIMEOUT_MS, MAX_REPLAY_ATTEMPTS, BITFAB_PROGRESS_PREFIX, ReplayError, DbBranchReplayError;
3158
3196
  var init_replay = __esm({
3159
3197
  "src/replay.ts"() {
3160
3198
  "use strict";
@@ -3166,6 +3204,7 @@ var init_replay = __esm({
3166
3204
  init_replayContext();
3167
3205
  init_serialize();
3168
3206
  REPLAY_PERSISTENCE_TIMEOUT_MS = 3e4;
3207
+ MAX_REPLAY_ATTEMPTS = 100;
3169
3208
  BITFAB_PROGRESS_PREFIX = "@@bitfab:progress ";
3170
3209
  ReplayError = class extends BitfabError {
3171
3210
  constructor(message, items, testRunId, testRunUrl, cause) {
@@ -7012,6 +7051,9 @@ var Bitfab = class {
7012
7051
  ...replayCtxAtStart?.inputSourceTraceId && {
7013
7052
  inputSourceTraceId: replayCtxAtStart.inputSourceTraceId
7014
7053
  },
7054
+ ...replayCtxAtStart?.replayAttempt !== void 0 && {
7055
+ replayAttempt: replayCtxAtStart.replayAttempt
7056
+ },
7015
7057
  dbSnapshotRef
7016
7058
  });
7017
7059
  registeredTraceId = traceId;
@@ -7062,6 +7104,7 @@ var Bitfab = class {
7062
7104
  contexts: traceState?.contexts ?? [],
7063
7105
  testRunId: traceState?.testRunId,
7064
7106
  inputSourceTraceId: traceState?.inputSourceTraceId,
7107
+ replayAttempt: traceState?.replayAttempt,
7065
7108
  dbSnapshotRef: traceState?.dbSnapshotRef,
7066
7109
  dropped: traceState?.dropped,
7067
7110
  ingestionType: traceState?.ingestionType,
@@ -7459,6 +7502,9 @@ var Bitfab = class {
7459
7502
  if (params.inputSourceTraceId) {
7460
7503
  rawTrace.input_source_trace_id = params.inputSourceTraceId;
7461
7504
  }
7505
+ if (params.replayAttempt !== void 0) {
7506
+ rawTrace.replay_attempt = params.replayAttempt;
7507
+ }
7462
7508
  if (params.dbSnapshotRef) {
7463
7509
  rawTrace.db_snapshot_ref = params.dbSnapshotRef;
7464
7510
  }