@bitfab/sdk 0.36.11 → 0.36.13

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
@@ -182,8 +182,9 @@ interface MockOverride {
182
182
  * A single span entry in the mock tree.
183
183
  *
184
184
  * Under the eager path (`mock: "all"`) `output`/`outputMeta` are populated
185
- * inline. Under the lazy path (`marked` / overrides) they are absent and the
186
- * recorded output is fetched on demand via `externalSpanId` - see
185
+ * inline, even when overrides are present. Under a non-`all` path that needs a
186
+ * tree (`marked`, or `none` with overrides), they are absent and the recorded
187
+ * output is fetched on demand via `externalSpanId` - see
187
188
  * {@link ReplayContext.fetchSpanOutput}.
188
189
  */
189
190
  interface MockSpan {
@@ -267,9 +268,10 @@ interface ReplayContext {
267
268
  mockOverrides?: MockOverride[];
268
269
  /**
269
270
  * Memoized lazy fetch of a span's recorded output (deserialized), keyed by
270
- * `externalSpanId`. Present ONLY on the lazy path (`marked` / overrides);
271
- * absent under `mock: "all"`, where outputs are inline on the mock tree. Its
272
- * presence is the signal that outputs must be fetched rather than read inline.
271
+ * `externalSpanId`. Present ONLY on a non-`all` path that needs a tree
272
+ * (`marked`, or `none` with overrides); absent under `mock: "all"`, where
273
+ * outputs are inline even when overrides are present. Its presence is the
274
+ * signal that outputs must be fetched rather than read inline.
273
275
  */
274
276
  fetchSpanOutput?: (externalSpanId: string) => Promise<unknown>;
275
277
  dbBranchLease?: DbBranchLease;
@@ -1177,9 +1179,9 @@ interface DbBranchOptions {
1177
1179
  }
1178
1180
  interface ReplayOptions {
1179
1181
  /**
1180
- * Maximum number of traces to replay (1-100, default 5). Ignored when
1181
- * `traceIds` is passed (with a warning): an explicit ID list already
1182
- * determines how many traces replay.
1182
+ * Maximum number of traces to replay (1-5,000, default 5). Ignored when
1183
+ * `traceIds` is passed (with a warning), or when `datasetId` is passed,
1184
+ * because either source already determines how many traces replay.
1183
1185
  */
1184
1186
  limit?: number;
1185
1187
  /** Optional list of specific trace IDs to replay (max 100). */
@@ -1209,7 +1211,8 @@ interface ReplayOptions {
1209
1211
  * Mock strategy for child spans during replay.
1210
1212
  * - "marked": only spans tagged with { mockOnReplay: true } in SpanOptions are mocked (default)
1211
1213
  * - "none": everything runs real code
1212
- * - "all": every child withSpan returns historical output
1214
+ * - "all": every matched recorded child withSpan returns historical output;
1215
+ * a missing occurrence fails the replay item closed
1213
1216
  */
1214
1217
  mock?: MockStrategy;
1215
1218
  /**
@@ -1229,9 +1232,10 @@ interface ReplayOptions {
1229
1232
  * branch with `getCurrentReplayBranch()`.
1230
1233
  *
1231
1234
  * Items whose source trace carried no DB snapshot reference get no branch and
1232
- * run against the live database. An item whose branch was requested but could
1233
- * not be resolved fails instead of running, so a replay never silently
1234
- * reports a result that did not use the historical data you asked for.
1235
+ * use the app's normal database path. Unsafe calls on that path still require
1236
+ * replay mocking. An item whose branch was requested but could not be resolved
1237
+ * fails instead of running, so replay never silently reports a result that did
1238
+ * not use the historical data you asked for.
1235
1239
  */
1236
1240
  dbBranch?: DbBranchOptions | boolean;
1237
1241
  /** Group ID to associate this replay with an experiment group for live streaming in Studio. */
@@ -1966,7 +1970,9 @@ interface SpanOptions {
1966
1970
  *
1967
1971
  * Use this for child spans that are expensive (paid LLM/API calls),
1968
1972
  * slow, or non-deterministic - the root function still runs real code,
1969
- * only the marked descendants return their recorded output.
1973
+ * only the marked descendants return their recorded output. If a selected
1974
+ * occurrence is unavailable, replay fails the item without executing the
1975
+ * real child.
1970
1976
  */
1971
1977
  mockOnReplay?: boolean;
1972
1978
  /**
@@ -2575,7 +2581,7 @@ declare class BitfabFunction {
2575
2581
  /**
2576
2582
  * SDK version from package.json (injected at build time)
2577
2583
  */
2578
- declare const __version__ = "0.36.11";
2584
+ declare const __version__ = "0.36.13";
2579
2585
 
2580
2586
  /**
2581
2587
  * Constants for the Bitfab SDK.
package/dist/index.d.ts CHANGED
@@ -182,8 +182,9 @@ interface MockOverride {
182
182
  * A single span entry in the mock tree.
183
183
  *
184
184
  * Under the eager path (`mock: "all"`) `output`/`outputMeta` are populated
185
- * inline. Under the lazy path (`marked` / overrides) they are absent and the
186
- * recorded output is fetched on demand via `externalSpanId` - see
185
+ * inline, even when overrides are present. Under a non-`all` path that needs a
186
+ * tree (`marked`, or `none` with overrides), they are absent and the recorded
187
+ * output is fetched on demand via `externalSpanId` - see
187
188
  * {@link ReplayContext.fetchSpanOutput}.
188
189
  */
189
190
  interface MockSpan {
@@ -267,9 +268,10 @@ interface ReplayContext {
267
268
  mockOverrides?: MockOverride[];
268
269
  /**
269
270
  * Memoized lazy fetch of a span's recorded output (deserialized), keyed by
270
- * `externalSpanId`. Present ONLY on the lazy path (`marked` / overrides);
271
- * absent under `mock: "all"`, where outputs are inline on the mock tree. Its
272
- * presence is the signal that outputs must be fetched rather than read inline.
271
+ * `externalSpanId`. Present ONLY on a non-`all` path that needs a tree
272
+ * (`marked`, or `none` with overrides); absent under `mock: "all"`, where
273
+ * outputs are inline even when overrides are present. Its presence is the
274
+ * signal that outputs must be fetched rather than read inline.
273
275
  */
274
276
  fetchSpanOutput?: (externalSpanId: string) => Promise<unknown>;
275
277
  dbBranchLease?: DbBranchLease;
@@ -1177,9 +1179,9 @@ interface DbBranchOptions {
1177
1179
  }
1178
1180
  interface ReplayOptions {
1179
1181
  /**
1180
- * Maximum number of traces to replay (1-100, default 5). Ignored when
1181
- * `traceIds` is passed (with a warning): an explicit ID list already
1182
- * determines how many traces replay.
1182
+ * Maximum number of traces to replay (1-5,000, default 5). Ignored when
1183
+ * `traceIds` is passed (with a warning), or when `datasetId` is passed,
1184
+ * because either source already determines how many traces replay.
1183
1185
  */
1184
1186
  limit?: number;
1185
1187
  /** Optional list of specific trace IDs to replay (max 100). */
@@ -1209,7 +1211,8 @@ interface ReplayOptions {
1209
1211
  * Mock strategy for child spans during replay.
1210
1212
  * - "marked": only spans tagged with { mockOnReplay: true } in SpanOptions are mocked (default)
1211
1213
  * - "none": everything runs real code
1212
- * - "all": every child withSpan returns historical output
1214
+ * - "all": every matched recorded child withSpan returns historical output;
1215
+ * a missing occurrence fails the replay item closed
1213
1216
  */
1214
1217
  mock?: MockStrategy;
1215
1218
  /**
@@ -1229,9 +1232,10 @@ interface ReplayOptions {
1229
1232
  * branch with `getCurrentReplayBranch()`.
1230
1233
  *
1231
1234
  * Items whose source trace carried no DB snapshot reference get no branch and
1232
- * run against the live database. An item whose branch was requested but could
1233
- * not be resolved fails instead of running, so a replay never silently
1234
- * reports a result that did not use the historical data you asked for.
1235
+ * use the app's normal database path. Unsafe calls on that path still require
1236
+ * replay mocking. An item whose branch was requested but could not be resolved
1237
+ * fails instead of running, so replay never silently reports a result that did
1238
+ * not use the historical data you asked for.
1235
1239
  */
1236
1240
  dbBranch?: DbBranchOptions | boolean;
1237
1241
  /** Group ID to associate this replay with an experiment group for live streaming in Studio. */
@@ -1966,7 +1970,9 @@ interface SpanOptions {
1966
1970
  *
1967
1971
  * Use this for child spans that are expensive (paid LLM/API calls),
1968
1972
  * slow, or non-deterministic - the root function still runs real code,
1969
- * only the marked descendants return their recorded output.
1973
+ * only the marked descendants return their recorded output. If a selected
1974
+ * occurrence is unavailable, replay fails the item without executing the
1975
+ * real child.
1970
1976
  */
1971
1977
  mockOnReplay?: boolean;
1972
1978
  /**
@@ -2575,7 +2581,7 @@ declare class BitfabFunction {
2575
2581
  /**
2576
2582
  * SDK version from package.json (injected at build time)
2577
2583
  */
2578
- declare const __version__ = "0.36.11";
2584
+ declare const __version__ = "0.36.13";
2579
2585
 
2580
2586
  /**
2581
2587
  * Constants for the Bitfab SDK.
package/dist/index.js CHANGED
@@ -11,7 +11,7 @@ import {
11
11
  getCurrentReplayBranch,
12
12
  getCurrentSpan,
13
13
  getCurrentTrace
14
- } from "./chunk-VDFPZYLH.js";
14
+ } from "./chunk-XAQJOZMJ.js";
15
15
  import {
16
16
  BITFAB_PROGRESS_PREFIX,
17
17
  BitfabError,
@@ -23,7 +23,7 @@ import {
23
23
  flushTraces,
24
24
  reportReplayProgress,
25
25
  serializeReplayResult
26
- } from "./chunk-EKOAKLZC.js";
26
+ } from "./chunk-VOUV7ZTS.js";
27
27
  export {
28
28
  BITFAB_PROGRESS_PREFIX,
29
29
  Bitfab,
package/dist/node.cjs CHANGED
@@ -88,7 +88,7 @@ var __version__;
88
88
  var init_version_generated = __esm({
89
89
  "src/version.generated.ts"() {
90
90
  "use strict";
91
- __version__ = "0.36.11";
91
+ __version__ = "0.36.13";
92
92
  }
93
93
  });
94
94
 
@@ -2593,20 +2593,17 @@ async function processItem(httpClient, serverItem, fn, testRunId, mockStrategy,
2593
2593
  includeOutputs,
2594
2594
  includeRootOutput: false
2595
2595
  });
2596
- if (treeResponse.root) {
2597
- mockTree = buildMockTree(treeResponse.root);
2598
- } else if (mockStrategy === "all" || hasOverrides) {
2596
+ if (!treeResponse.root) {
2599
2597
  throw new BitfabError(
2600
2598
  `Replay mock strategy "${mockStrategy}"${hasOverrides ? " with overrides" : ""} requires a span tree root for original span ${originalSpanId}.`
2601
2599
  );
2602
- } else {
2603
- mockTree = void 0;
2604
2600
  }
2605
- } catch (e) {
2606
- if (mockStrategy === "all" || hasOverrides) {
2607
- throw e;
2601
+ mockTree = buildMockTree(treeResponse.root);
2602
+ } catch (error2) {
2603
+ if (mockStrategy !== "marked" || hasOverrides) {
2604
+ throw error2;
2608
2605
  }
2609
- mockTree = void 0;
2606
+ mockTree = { spans: /* @__PURE__ */ new Map() };
2610
2607
  }
2611
2608
  }
2612
2609
  const outputCache = /* @__PURE__ */ new Map();
@@ -6115,14 +6112,19 @@ var Bitfab = class {
6115
6112
  counters.set(counterKey, callIndex + 1);
6116
6113
  const mockKey = `${counterKey}:${callIndex}`;
6117
6114
  const mockSpan = replayCtxForMock.mockTree.spans.get(mockKey);
6118
- const emitMock = (output) => {
6119
- void sendSpan({ result: output, mocked: true });
6115
+ const emitMock = (output, mockSource) => {
6116
+ void sendSpan({
6117
+ result: output,
6118
+ mocked: true,
6119
+ mockTarget: "output",
6120
+ mockSource
6121
+ });
6120
6122
  if (fnReturnsPromise) {
6121
6123
  return Promise.resolve(output);
6122
6124
  }
6123
6125
  return output;
6124
6126
  };
6125
- const emitMockAsync = (pending) => {
6127
+ const emitMockAsync = (pending, mockSource) => {
6126
6128
  if (!fnReturnsPromise) {
6127
6129
  throw new BitfabError(
6128
6130
  `Cannot mock synchronous span "${traceFunctionKey}" with an asynchronously-resolved value (lazy recorded-output fetch or an async value function). Make the wrapped function async, or use mock: "all" so recorded outputs are fetched eagerly.`
@@ -6130,7 +6132,12 @@ var Bitfab = class {
6130
6132
  }
6131
6133
  return (async () => {
6132
6134
  const output = await pending;
6133
- void sendSpan({ result: output, mocked: true });
6135
+ void sendSpan({
6136
+ result: output,
6137
+ mocked: true,
6138
+ mockTarget: "output",
6139
+ mockSource
6140
+ });
6134
6141
  return output;
6135
6142
  })();
6136
6143
  };
@@ -6172,18 +6179,23 @@ var Bitfab = class {
6172
6179
  getOriginalOutput: () => Promise.resolve(resolveRecordedOutput())
6173
6180
  });
6174
6181
  if (injected instanceof Promise) {
6175
- return emitMockAsync(injected);
6182
+ return emitMockAsync(injected, "override");
6176
6183
  }
6177
- return emitMock(injected);
6184
+ return emitMock(injected, "override");
6178
6185
  }
6179
6186
  }
6180
6187
  const shouldMock = replayCtxForMock.mockStrategy === "all" || replayCtxForMock.mockStrategy === "marked" && options.mockOnReplay === true;
6181
- if (shouldMock && mockSpan) {
6188
+ if (shouldMock && !mockSpan) {
6189
+ throw new BitfabError(
6190
+ `Replay selected span "${traceFunctionKey}:${baseSpanParams.spanName}" for mocking, but recorded occurrence ${callIndex + 1} is unavailable. The real span was not executed.`
6191
+ );
6192
+ }
6193
+ if (shouldMock) {
6182
6194
  const recorded = resolveRecordedOutput();
6183
6195
  if (recorded instanceof Promise) {
6184
- return emitMockAsync(recorded);
6196
+ return emitMockAsync(recorded, "recorded");
6185
6197
  }
6186
- return emitMock(recorded);
6198
+ return emitMock(recorded, "recorded");
6187
6199
  }
6188
6200
  }
6189
6201
  const recordSpan = (result) => {
@@ -6483,7 +6495,9 @@ var Bitfab = class {
6483
6495
  traceFunctionKey: params.traceFunctionKey,
6484
6496
  rawSpan: externalSpan,
6485
6497
  ...params.testRunId && { testRunId: params.testRunId },
6486
- ...params.mocked && { mocked: true }
6498
+ ...params.mocked && { mocked: true },
6499
+ ...params.mockTarget && { mockTarget: params.mockTarget },
6500
+ ...params.mockSource && { mockSource: params.mockSource }
6487
6501
  });
6488
6502
  }
6489
6503
  registerMockOverride(overrideOrMatch, value) {