bitfab 0.38.4 → 0.38.5

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
@@ -147,10 +147,23 @@ interface MockOverrideCtx {
147
147
  */
148
148
  getOriginalOutput: () => Promise<unknown>;
149
149
  }
150
+ /**
151
+ * Return this from a mock override resolver to decline the override for the
152
+ * current span. Resolution continues with the next override, then the replay's
153
+ * base mock strategy.
154
+ */
155
+ declare const NO_MOCK_OVERRIDE: unique symbol;
150
156
  /** Selects which spans an override applies to. Runs on structural metadata. */
151
157
  type NodeMatcher = (node: SpanNodeMeta) => boolean;
152
158
  /** The function form of {@link MockValue}, receiving the override context. */
153
159
  type MockValueFn = (ctx: MockOverrideCtx) => unknown | Promise<unknown>;
160
+ /**
161
+ * A client-wide, keyed, or per-replay resolver. A global resolver can route on
162
+ * `ctx.node.traceFunctionKey`; a keyed resolver is only invoked for spans with
163
+ * its registered key. Return {@link NO_MOCK_OVERRIDE} for spans the resolver
164
+ * does not want to override.
165
+ */
166
+ type MockOverrideResolver = (ctx: MockOverrideCtx) => unknown | Promise<unknown>;
154
167
  /**
155
168
  * The value injected for a matched span: either a flat value used as-is, or a
156
169
  * function of the {@link MockOverrideCtx} that returns one (or a Promise of
@@ -168,6 +181,8 @@ interface MockOverride {
168
181
  match: NodeMatcher;
169
182
  value: MockValue;
170
183
  }
184
+ /** Accepted shape for one mock override declaration. */
185
+ type MockOverrideInput = MockOverride | MockOverrideResolver;
171
186
 
172
187
  /**
173
188
  * Replay context propagation via AsyncLocalStorage.
@@ -1268,12 +1283,12 @@ interface ReplayOptions {
1268
1283
  /**
1269
1284
  * Selective mock overrides: inject custom values into specific spans during
1270
1285
  * replay, so downstream real code runs against the substituted output. Each
1271
- * override is a `{ match, value }` pair; the first matcher that
1272
- * matches a span wins. These take precedence over any overrides registered on
1273
- * the client via `registerMockOverride`, and over the base `mock` strategy - a
1274
- * span no override matches falls back to that strategy. See {@link MockOverride}.
1286
+ * Pass `{ match, value }` pairs, or one resolver invoked for every child span.
1287
+ * A resolver can route on `ctx.node.traceFunctionKey` and return
1288
+ * `NO_MOCK_OVERRIDE` to continue to the next override and base strategy.
1289
+ * Per-call overrides take precedence over registrations on the client.
1275
1290
  */
1276
- mockOverride?: MockOverride | MockOverride[];
1291
+ mockOverride?: MockOverrideInput | MockOverrideInput[];
1277
1292
  /**
1278
1293
  * Run each item against a database branch restored to the state its source
1279
1294
  * trace saw. Pass `true` to branch with the mirror project's own sizing, or a
@@ -2584,10 +2599,22 @@ declare class Bitfab {
2584
2599
  * (node) => node.traceFunctionKey === "classify-intent",
2585
2600
  * ({ inputs }) => ({ label: "refund" }),
2586
2601
  * )
2602
+ * // Keyed form: the resolver only sees spans for this trace function key.
2603
+ * bitfab.registerMockOverride("classify-intent", ({ inputs }) => ({
2604
+ * label: String(inputs[0]),
2605
+ * }))
2606
+ * // Or one resolver for every child span:
2607
+ * bitfab.registerMockOverride(({ node }) =>
2608
+ * node.traceFunctionKey === "classify-intent"
2609
+ * ? { label: "refund" }
2610
+ * : NO_MOCK_OVERRIDE,
2611
+ * )
2587
2612
  * ```
2588
2613
  */
2589
2614
  registerMockOverride(override: MockOverride): void;
2615
+ registerMockOverride(resolver: MockOverrideResolver): void;
2590
2616
  registerMockOverride(match: NodeMatcher, value: MockValue): void;
2617
+ registerMockOverride(traceFunctionKey: string, override: MockOverride | MockOverrideResolver): void;
2591
2618
  /** Remove all overrides registered via {@link registerMockOverride}. */
2592
2619
  clearMockOverrides(): void;
2593
2620
  replay<TReturn>(traceFunctionKey: string, fn: (...args: any[]) => TReturn | Promise<TReturn>, options?: ReplayOptions): Promise<ReplayResult<TReturn>>;
@@ -2759,7 +2786,7 @@ declare class BitfabFunction {
2759
2786
  /**
2760
2787
  * SDK version from package.json (injected at build time)
2761
2788
  */
2762
- declare const __version__ = "0.38.4";
2789
+ declare const __version__ = "0.38.5";
2763
2790
 
2764
2791
  /**
2765
2792
  * Constants for the Bitfab SDK.
@@ -2862,4 +2889,4 @@ type ReplayRegistry = Record<string, ReplayRegistration>;
2862
2889
  */
2863
2890
  declare function defineReplayRegistry<TRegistry extends ReplayRegistry>(registry: TRegistry): TRegistry;
2864
2891
 
2865
- export { type ActiveSpanContext, type AdaptContext, type AdaptInputsFn, type AllowedEnvVars, BITFAB_PROGRESS_PREFIX, type BamlExecutionResult, Bitfab, BitfabClaudeAgentHandler, type BitfabConfig, BitfabError, BitfabFunction, BitfabLangGraphCallbackHandler as BitfabLangChainCallbackHandler, BitfabLangGraphCallbackHandler, type BitfabLanguageModelMiddleware, BitfabOpenAIAgentHandler, BitfabOpenAITracingProcessor, BitfabVercelAiHandler, type CaptureWhen, type CapturedSpan, type CodeChangeFile, type CurrentSpan, type CurrentTrace, DEFAULT_SERVICE_URL, type DbBranchOptions, DbBranchReplayError, type DbBranchTimings, type DbSnapshotConfig, type DbSnapshotProvider, type DbSnapshotRef, type DetachedTrace, HttpClient, type MockOverride, type MockOverrideCtx, type MockStrategy, type MockValue, type NodeMatcher, type NodeMethodDecorator, type NodeOptions, type ProviderDefinition, ReplayBranch, ReplayError, type ReplayItem, type ReplayItemFinishProgress, type ReplayItemStartProgress, type ReplayOptions, type ReplayOptionsFactory, type ReplayProgress, type ReplayProgressItem, type ReplayRegistration, type ReplayRegistry, type ReplayRegistryContext, type ReplayRegistryOptions, type ReplayResult, SUPPORTED_PROVIDERS, type SpanLookup, type SpanMethodDecorator, type SpanMethodDecoratorContext, type SpanNodeMeta, type SpanOccurrence, type SpanOptions, type SpanType, type TokenUsage, type TraceResponse, type TracingProcessor, type VercelCallParams, type VercelGenerateResult, type VercelStreamResult, type WrapBAMLOptions, type WrappedBamlFn, __version__, defineReplayRegistry, finalizers, flushTraces, getCurrentReplayBranch, getCurrentSpan, getCurrentTrace, reportReplayProgress, serializeReplayResult };
2892
+ export { type ActiveSpanContext, type AdaptContext, type AdaptInputsFn, type AllowedEnvVars, BITFAB_PROGRESS_PREFIX, type BamlExecutionResult, Bitfab, BitfabClaudeAgentHandler, type BitfabConfig, BitfabError, BitfabFunction, BitfabLangGraphCallbackHandler as BitfabLangChainCallbackHandler, BitfabLangGraphCallbackHandler, type BitfabLanguageModelMiddleware, BitfabOpenAIAgentHandler, BitfabOpenAITracingProcessor, BitfabVercelAiHandler, type CaptureWhen, type CapturedSpan, type CodeChangeFile, type CurrentSpan, type CurrentTrace, DEFAULT_SERVICE_URL, type DbBranchOptions, DbBranchReplayError, type DbBranchTimings, type DbSnapshotConfig, type DbSnapshotProvider, type DbSnapshotRef, type DetachedTrace, HttpClient, type MockOverride, type MockOverrideCtx, type MockOverrideInput, type MockOverrideResolver, type MockStrategy, type MockValue, NO_MOCK_OVERRIDE, type NodeMatcher, type NodeMethodDecorator, type NodeOptions, type ProviderDefinition, ReplayBranch, ReplayError, type ReplayItem, type ReplayItemFinishProgress, type ReplayItemStartProgress, type ReplayOptions, type ReplayOptionsFactory, type ReplayProgress, type ReplayProgressItem, type ReplayRegistration, type ReplayRegistry, type ReplayRegistryContext, type ReplayRegistryOptions, type ReplayResult, SUPPORTED_PROVIDERS, type SpanLookup, type SpanMethodDecorator, type SpanMethodDecoratorContext, type SpanNodeMeta, type SpanOccurrence, type SpanOptions, type SpanType, type TokenUsage, type TraceResponse, type TracingProcessor, type VercelCallParams, type VercelGenerateResult, type VercelStreamResult, type WrapBAMLOptions, type WrappedBamlFn, __version__, defineReplayRegistry, finalizers, flushTraces, getCurrentReplayBranch, getCurrentSpan, getCurrentTrace, reportReplayProgress, serializeReplayResult };
package/dist/index.d.ts CHANGED
@@ -147,10 +147,23 @@ interface MockOverrideCtx {
147
147
  */
148
148
  getOriginalOutput: () => Promise<unknown>;
149
149
  }
150
+ /**
151
+ * Return this from a mock override resolver to decline the override for the
152
+ * current span. Resolution continues with the next override, then the replay's
153
+ * base mock strategy.
154
+ */
155
+ declare const NO_MOCK_OVERRIDE: unique symbol;
150
156
  /** Selects which spans an override applies to. Runs on structural metadata. */
151
157
  type NodeMatcher = (node: SpanNodeMeta) => boolean;
152
158
  /** The function form of {@link MockValue}, receiving the override context. */
153
159
  type MockValueFn = (ctx: MockOverrideCtx) => unknown | Promise<unknown>;
160
+ /**
161
+ * A client-wide, keyed, or per-replay resolver. A global resolver can route on
162
+ * `ctx.node.traceFunctionKey`; a keyed resolver is only invoked for spans with
163
+ * its registered key. Return {@link NO_MOCK_OVERRIDE} for spans the resolver
164
+ * does not want to override.
165
+ */
166
+ type MockOverrideResolver = (ctx: MockOverrideCtx) => unknown | Promise<unknown>;
154
167
  /**
155
168
  * The value injected for a matched span: either a flat value used as-is, or a
156
169
  * function of the {@link MockOverrideCtx} that returns one (or a Promise of
@@ -168,6 +181,8 @@ interface MockOverride {
168
181
  match: NodeMatcher;
169
182
  value: MockValue;
170
183
  }
184
+ /** Accepted shape for one mock override declaration. */
185
+ type MockOverrideInput = MockOverride | MockOverrideResolver;
171
186
 
172
187
  /**
173
188
  * Replay context propagation via AsyncLocalStorage.
@@ -1268,12 +1283,12 @@ interface ReplayOptions {
1268
1283
  /**
1269
1284
  * Selective mock overrides: inject custom values into specific spans during
1270
1285
  * replay, so downstream real code runs against the substituted output. Each
1271
- * override is a `{ match, value }` pair; the first matcher that
1272
- * matches a span wins. These take precedence over any overrides registered on
1273
- * the client via `registerMockOverride`, and over the base `mock` strategy - a
1274
- * span no override matches falls back to that strategy. See {@link MockOverride}.
1286
+ * Pass `{ match, value }` pairs, or one resolver invoked for every child span.
1287
+ * A resolver can route on `ctx.node.traceFunctionKey` and return
1288
+ * `NO_MOCK_OVERRIDE` to continue to the next override and base strategy.
1289
+ * Per-call overrides take precedence over registrations on the client.
1275
1290
  */
1276
- mockOverride?: MockOverride | MockOverride[];
1291
+ mockOverride?: MockOverrideInput | MockOverrideInput[];
1277
1292
  /**
1278
1293
  * Run each item against a database branch restored to the state its source
1279
1294
  * trace saw. Pass `true` to branch with the mirror project's own sizing, or a
@@ -2584,10 +2599,22 @@ declare class Bitfab {
2584
2599
  * (node) => node.traceFunctionKey === "classify-intent",
2585
2600
  * ({ inputs }) => ({ label: "refund" }),
2586
2601
  * )
2602
+ * // Keyed form: the resolver only sees spans for this trace function key.
2603
+ * bitfab.registerMockOverride("classify-intent", ({ inputs }) => ({
2604
+ * label: String(inputs[0]),
2605
+ * }))
2606
+ * // Or one resolver for every child span:
2607
+ * bitfab.registerMockOverride(({ node }) =>
2608
+ * node.traceFunctionKey === "classify-intent"
2609
+ * ? { label: "refund" }
2610
+ * : NO_MOCK_OVERRIDE,
2611
+ * )
2587
2612
  * ```
2588
2613
  */
2589
2614
  registerMockOverride(override: MockOverride): void;
2615
+ registerMockOverride(resolver: MockOverrideResolver): void;
2590
2616
  registerMockOverride(match: NodeMatcher, value: MockValue): void;
2617
+ registerMockOverride(traceFunctionKey: string, override: MockOverride | MockOverrideResolver): void;
2591
2618
  /** Remove all overrides registered via {@link registerMockOverride}. */
2592
2619
  clearMockOverrides(): void;
2593
2620
  replay<TReturn>(traceFunctionKey: string, fn: (...args: any[]) => TReturn | Promise<TReturn>, options?: ReplayOptions): Promise<ReplayResult<TReturn>>;
@@ -2759,7 +2786,7 @@ declare class BitfabFunction {
2759
2786
  /**
2760
2787
  * SDK version from package.json (injected at build time)
2761
2788
  */
2762
- declare const __version__ = "0.38.4";
2789
+ declare const __version__ = "0.38.5";
2763
2790
 
2764
2791
  /**
2765
2792
  * Constants for the Bitfab SDK.
@@ -2862,4 +2889,4 @@ type ReplayRegistry = Record<string, ReplayRegistration>;
2862
2889
  */
2863
2890
  declare function defineReplayRegistry<TRegistry extends ReplayRegistry>(registry: TRegistry): TRegistry;
2864
2891
 
2865
- export { type ActiveSpanContext, type AdaptContext, type AdaptInputsFn, type AllowedEnvVars, BITFAB_PROGRESS_PREFIX, type BamlExecutionResult, Bitfab, BitfabClaudeAgentHandler, type BitfabConfig, BitfabError, BitfabFunction, BitfabLangGraphCallbackHandler as BitfabLangChainCallbackHandler, BitfabLangGraphCallbackHandler, type BitfabLanguageModelMiddleware, BitfabOpenAIAgentHandler, BitfabOpenAITracingProcessor, BitfabVercelAiHandler, type CaptureWhen, type CapturedSpan, type CodeChangeFile, type CurrentSpan, type CurrentTrace, DEFAULT_SERVICE_URL, type DbBranchOptions, DbBranchReplayError, type DbBranchTimings, type DbSnapshotConfig, type DbSnapshotProvider, type DbSnapshotRef, type DetachedTrace, HttpClient, type MockOverride, type MockOverrideCtx, type MockStrategy, type MockValue, type NodeMatcher, type NodeMethodDecorator, type NodeOptions, type ProviderDefinition, ReplayBranch, ReplayError, type ReplayItem, type ReplayItemFinishProgress, type ReplayItemStartProgress, type ReplayOptions, type ReplayOptionsFactory, type ReplayProgress, type ReplayProgressItem, type ReplayRegistration, type ReplayRegistry, type ReplayRegistryContext, type ReplayRegistryOptions, type ReplayResult, SUPPORTED_PROVIDERS, type SpanLookup, type SpanMethodDecorator, type SpanMethodDecoratorContext, type SpanNodeMeta, type SpanOccurrence, type SpanOptions, type SpanType, type TokenUsage, type TraceResponse, type TracingProcessor, type VercelCallParams, type VercelGenerateResult, type VercelStreamResult, type WrapBAMLOptions, type WrappedBamlFn, __version__, defineReplayRegistry, finalizers, flushTraces, getCurrentReplayBranch, getCurrentSpan, getCurrentTrace, reportReplayProgress, serializeReplayResult };
2892
+ export { type ActiveSpanContext, type AdaptContext, type AdaptInputsFn, type AllowedEnvVars, BITFAB_PROGRESS_PREFIX, type BamlExecutionResult, Bitfab, BitfabClaudeAgentHandler, type BitfabConfig, BitfabError, BitfabFunction, BitfabLangGraphCallbackHandler as BitfabLangChainCallbackHandler, BitfabLangGraphCallbackHandler, type BitfabLanguageModelMiddleware, BitfabOpenAIAgentHandler, BitfabOpenAITracingProcessor, BitfabVercelAiHandler, type CaptureWhen, type CapturedSpan, type CodeChangeFile, type CurrentSpan, type CurrentTrace, DEFAULT_SERVICE_URL, type DbBranchOptions, DbBranchReplayError, type DbBranchTimings, type DbSnapshotConfig, type DbSnapshotProvider, type DbSnapshotRef, type DetachedTrace, HttpClient, type MockOverride, type MockOverrideCtx, type MockOverrideInput, type MockOverrideResolver, type MockStrategy, type MockValue, NO_MOCK_OVERRIDE, type NodeMatcher, type NodeMethodDecorator, type NodeOptions, type ProviderDefinition, ReplayBranch, ReplayError, type ReplayItem, type ReplayItemFinishProgress, type ReplayItemStartProgress, type ReplayOptions, type ReplayOptionsFactory, type ReplayProgress, type ReplayProgressItem, type ReplayRegistration, type ReplayRegistry, type ReplayRegistryContext, type ReplayRegistryOptions, type ReplayResult, SUPPORTED_PROVIDERS, type SpanLookup, type SpanMethodDecorator, type SpanMethodDecoratorContext, type SpanNodeMeta, type SpanOccurrence, type SpanOptions, type SpanType, type TokenUsage, type TraceResponse, type TracingProcessor, type VercelCallParams, type VercelGenerateResult, type VercelStreamResult, type WrapBAMLOptions, type WrappedBamlFn, __version__, defineReplayRegistry, finalizers, flushTraces, getCurrentReplayBranch, getCurrentSpan, getCurrentTrace, reportReplayProgress, serializeReplayResult };
package/dist/index.js CHANGED
@@ -21,7 +21,7 @@ import {
21
21
  getCurrentReplayBranch,
22
22
  getCurrentSpan,
23
23
  getCurrentTrace
24
- } from "./chunk-PXAL7PPD.js";
24
+ } from "./chunk-LQDCJPVV.js";
25
25
  import "./chunk-J47KPS77.js";
26
26
  import {
27
27
  BITFAB_PROGRESS_PREFIX,
@@ -29,12 +29,13 @@ import {
29
29
  DEFAULT_SERVICE_URL,
30
30
  DbBranchReplayError,
31
31
  HttpClient,
32
+ NO_MOCK_OVERRIDE,
32
33
  ReplayError,
33
34
  __version__,
34
35
  flushTraces,
35
36
  reportReplayProgress,
36
37
  serializeReplayResult
37
- } from "./chunk-LHFNHB2J.js";
38
+ } from "./chunk-ZXJ3VQLF.js";
38
39
  import "./chunk-H6LZRFMN.js";
39
40
  export {
40
41
  BITFAB_PROGRESS_PREFIX,
@@ -50,6 +51,7 @@ export {
50
51
  DEFAULT_SERVICE_URL,
51
52
  DbBranchReplayError,
52
53
  HttpClient,
54
+ NO_MOCK_OVERRIDE,
53
55
  ReplayError,
54
56
  SUPPORTED_PROVIDERS,
55
57
  __version__,
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.38.4";
100
+ __version__ = "0.38.5";
101
101
  __packageName__ = "bitfab";
102
102
  }
103
103
  });
@@ -2203,11 +2203,16 @@ function normalizeMockOverrides(mockOverride) {
2203
2203
  if (mockOverride === void 0) {
2204
2204
  return [];
2205
2205
  }
2206
- return Array.isArray(mockOverride) ? mockOverride : [mockOverride];
2206
+ const overrides = Array.isArray(mockOverride) ? mockOverride : [mockOverride];
2207
+ return overrides.map(
2208
+ (override) => typeof override === "function" ? { match: () => true, value: override } : override
2209
+ );
2207
2210
  }
2211
+ var NO_MOCK_OVERRIDE;
2208
2212
  var init_mockOverride = __esm({
2209
2213
  "src/mockOverride.ts"() {
2210
2214
  "use strict";
2215
+ NO_MOCK_OVERRIDE = /* @__PURE__ */ Symbol("bitfab.noMockOverride");
2211
2216
  }
2212
2217
  });
2213
2218
 
@@ -3149,6 +3154,7 @@ __export(node_exports, {
3149
3154
  DEFAULT_SERVICE_URL: () => DEFAULT_SERVICE_URL,
3150
3155
  DbBranchReplayError: () => DbBranchReplayError,
3151
3156
  HttpClient: () => HttpClient,
3157
+ NO_MOCK_OVERRIDE: () => NO_MOCK_OVERRIDE,
3152
3158
  ReplayError: () => ReplayError,
3153
3159
  SUPPORTED_PROVIDERS: () => SUPPORTED_PROVIDERS,
3154
3160
  __version__: () => __version__,
@@ -6578,6 +6584,49 @@ var Bitfab = class {
6578
6584
  } catch {
6579
6585
  }
6580
6586
  };
6587
+ const recordSpan = (result) => {
6588
+ if (options.finalize) {
6589
+ void self.httpClient.trackDeferred(
6590
+ Promise.resolve().then(() => options.finalize(result)).then((output) => sendSpan({ result: output })).catch(
6591
+ (error) => sendSpan({
6592
+ result: void 0,
6593
+ error: error instanceof Error ? `finalize failed: ${error.message}` : `finalize failed: ${String(error)}`
6594
+ })
6595
+ )
6596
+ );
6597
+ } else {
6598
+ void sendSpan({ result });
6599
+ }
6600
+ };
6601
+ executeWithContext = () => {
6602
+ let result;
6603
+ try {
6604
+ result = fn.apply(this, args);
6605
+ } catch (error) {
6606
+ void sendSpan({
6607
+ result: void 0,
6608
+ error: error instanceof Error ? error.message : String(error)
6609
+ });
6610
+ throw error;
6611
+ }
6612
+ if (result instanceof Promise) {
6613
+ return result.then((resolvedResult) => {
6614
+ recordSpan(resolvedResult);
6615
+ return resolvedResult;
6616
+ }).catch((error) => {
6617
+ void sendSpan({
6618
+ result: void 0,
6619
+ error: error instanceof Error ? error.message : String(error)
6620
+ });
6621
+ throw error;
6622
+ });
6623
+ }
6624
+ if (isAsyncGenerator(result)) {
6625
+ return wrapAsyncGenerator(result, newStack, sendSpan);
6626
+ }
6627
+ recordSpan(result);
6628
+ return result;
6629
+ };
6581
6630
  const replayCtxForMock = getReplayContext();
6582
6631
  if (replayCtxForMock?.mockTree && !isRootSpan) {
6583
6632
  const counters = replayCtxForMock.callCounters;
@@ -6636,6 +6685,7 @@ var Bitfab = class {
6636
6685
  }
6637
6686
  return output;
6638
6687
  };
6688
+ const shouldMockWithBaseStrategy = replayCtxForMock.mockStrategy === "all" || replayCtxForMock.mockStrategy === "marked" && options.mockOnReplay === true;
6639
6689
  if (replayCtxForMock.mockOverrides?.length) {
6640
6690
  const nodeMeta = {
6641
6691
  traceFunctionKey,
@@ -6643,28 +6693,75 @@ var Bitfab = class {
6643
6693
  type: options.type ?? "custom",
6644
6694
  originalSpanId: mockSpan?.sourceSpanId
6645
6695
  };
6646
- const override = replayCtxForMock.mockOverrides.find(
6647
- (o) => o.match(nodeMeta)
6648
- );
6649
- if (override) {
6650
- const injected = resolveMockValue(override.value, {
6651
- node: nodeMeta,
6652
- inputs: args,
6653
- getOriginalOutput: () => Promise.resolve(resolveRecordedOutput())
6654
- });
6655
- if (injected instanceof Promise) {
6656
- return emitMockAsync(injected, "override");
6696
+ const overrideCtx = {
6697
+ node: nodeMeta,
6698
+ inputs: args,
6699
+ getOriginalOutput: () => Promise.resolve(resolveRecordedOutput())
6700
+ };
6701
+ const resolveOverrideFrom = (startIndex) => {
6702
+ for (let index = startIndex; index < replayCtxForMock.mockOverrides.length; index += 1) {
6703
+ const override = replayCtxForMock.mockOverrides[index];
6704
+ if (!override?.match(nodeMeta)) {
6705
+ continue;
6706
+ }
6707
+ const injected = resolveMockValue(override.value, overrideCtx);
6708
+ if (injected instanceof Promise) {
6709
+ return injected.then(
6710
+ (output) => output === NO_MOCK_OVERRIDE ? resolveOverrideFrom(index + 1) : { matched: true, output }
6711
+ );
6712
+ }
6713
+ if (injected !== NO_MOCK_OVERRIDE) {
6714
+ return { matched: true, output: injected };
6715
+ }
6657
6716
  }
6658
- return emitMock(injected, "override");
6717
+ return { matched: false };
6718
+ };
6719
+ const resolution = resolveOverrideFrom(0);
6720
+ if (resolution instanceof Promise) {
6721
+ if (!fnReturnsPromise) {
6722
+ throw new BitfabError(
6723
+ `Cannot resolve an asynchronous mock override for synchronous span "${traceFunctionKey}". Make the wrapped function async or return NO_MOCK_OVERRIDE synchronously.`
6724
+ );
6725
+ }
6726
+ return runWithSpanStack(newStack, async () => {
6727
+ const resolved = await resolution;
6728
+ if (resolved.matched) {
6729
+ void sendSpan({
6730
+ result: resolved.output,
6731
+ mocked: true,
6732
+ mockTarget: "output",
6733
+ mockSource: "override"
6734
+ });
6735
+ return resolved.output;
6736
+ }
6737
+ if (shouldMockWithBaseStrategy && !mockSpan) {
6738
+ throw new BitfabError(
6739
+ `Replay selected span "${traceFunctionKey}:${baseSpanParams.spanName}" for mocking, but recorded occurrence ${callIndex + 1} is unavailable. The real span was not executed.`
6740
+ );
6741
+ }
6742
+ if (shouldMockWithBaseStrategy) {
6743
+ const output = await resolveRecordedOutput();
6744
+ void sendSpan({
6745
+ result: output,
6746
+ mocked: true,
6747
+ mockTarget: "output",
6748
+ mockSource: "recorded"
6749
+ });
6750
+ return output;
6751
+ }
6752
+ return executeWithContext();
6753
+ });
6754
+ }
6755
+ if (resolution.matched) {
6756
+ return emitMock(resolution.output, "override");
6659
6757
  }
6660
6758
  }
6661
- const shouldMock = replayCtxForMock.mockStrategy === "all" || replayCtxForMock.mockStrategy === "marked" && options.mockOnReplay === true;
6662
- if (shouldMock && !mockSpan) {
6759
+ if (shouldMockWithBaseStrategy && !mockSpan) {
6663
6760
  throw new BitfabError(
6664
6761
  `Replay selected span "${traceFunctionKey}:${baseSpanParams.spanName}" for mocking, but recorded occurrence ${callIndex + 1} is unavailable. The real span was not executed.`
6665
6762
  );
6666
6763
  }
6667
- if (shouldMock) {
6764
+ if (shouldMockWithBaseStrategy) {
6668
6765
  const recorded = resolveRecordedOutput();
6669
6766
  if (recorded instanceof Promise) {
6670
6767
  return emitMockAsync(recorded, "recorded");
@@ -6672,49 +6769,6 @@ var Bitfab = class {
6672
6769
  return emitMock(recorded, "recorded");
6673
6770
  }
6674
6771
  }
6675
- const recordSpan = (result) => {
6676
- if (options.finalize) {
6677
- void self.httpClient.trackDeferred(
6678
- Promise.resolve().then(() => options.finalize(result)).then((output) => sendSpan({ result: output })).catch(
6679
- (error) => sendSpan({
6680
- result: void 0,
6681
- error: error instanceof Error ? `finalize failed: ${error.message}` : `finalize failed: ${String(error)}`
6682
- })
6683
- )
6684
- );
6685
- } else {
6686
- void sendSpan({ result });
6687
- }
6688
- };
6689
- executeWithContext = () => {
6690
- let result;
6691
- try {
6692
- result = fn.apply(this, args);
6693
- } catch (error) {
6694
- void sendSpan({
6695
- result: void 0,
6696
- error: error instanceof Error ? error.message : String(error)
6697
- });
6698
- throw error;
6699
- }
6700
- if (result instanceof Promise) {
6701
- return result.then((resolvedResult) => {
6702
- recordSpan(resolvedResult);
6703
- return resolvedResult;
6704
- }).catch((error) => {
6705
- void sendSpan({
6706
- result: void 0,
6707
- error: error instanceof Error ? error.message : String(error)
6708
- });
6709
- throw error;
6710
- });
6711
- }
6712
- if (isAsyncGenerator(result)) {
6713
- return wrapAsyncGenerator(result, newStack, sendSpan);
6714
- }
6715
- recordSpan(result);
6716
- return result;
6717
- };
6718
6772
  } catch (setupError) {
6719
6773
  if (registeredTraceId) {
6720
6774
  activeTraceStates.delete(registeredTraceId);
@@ -7001,8 +7055,40 @@ var Bitfab = class {
7001
7055
  ...params.mockSource && { mockSource: params.mockSource }
7002
7056
  });
7003
7057
  }
7004
- registerMockOverride(overrideOrMatch, value) {
7005
- const override = typeof overrideOrMatch === "function" ? { match: overrideOrMatch, value } : overrideOrMatch;
7058
+ registerMockOverride(overrideOrResolverOrMatch, ...values) {
7059
+ let override;
7060
+ if (typeof overrideOrResolverOrMatch === "string") {
7061
+ const keyedOverride = values[0];
7062
+ if (values.length !== 1 || keyedOverride === void 0) {
7063
+ throw new BitfabError(
7064
+ "registerMockOverride(traceFunctionKey, override) requires a resolver function or { match, value } override."
7065
+ );
7066
+ }
7067
+ if (typeof keyedOverride === "function") {
7068
+ override = {
7069
+ match: (node) => node.traceFunctionKey === overrideOrResolverOrMatch,
7070
+ value: keyedOverride
7071
+ };
7072
+ } else if (typeof keyedOverride === "object" && keyedOverride !== null && "match" in keyedOverride && "value" in keyedOverride) {
7073
+ override = {
7074
+ match: (node) => node.traceFunctionKey === overrideOrResolverOrMatch && keyedOverride.match(node),
7075
+ value: keyedOverride.value
7076
+ };
7077
+ } else {
7078
+ throw new BitfabError(
7079
+ "registerMockOverride(traceFunctionKey, override) requires a resolver function or { match, value } override."
7080
+ );
7081
+ }
7082
+ } else if (typeof overrideOrResolverOrMatch !== "function") {
7083
+ override = overrideOrResolverOrMatch;
7084
+ } else if (values.length === 0) {
7085
+ override = { match: () => true, value: overrideOrResolverOrMatch };
7086
+ } else {
7087
+ override = {
7088
+ match: overrideOrResolverOrMatch,
7089
+ value: values[0]
7090
+ };
7091
+ }
7006
7092
  this.mockOverrides.push(override);
7007
7093
  }
7008
7094
  /** Remove all overrides registered via {@link registerMockOverride}. */
@@ -7252,6 +7338,7 @@ var finalizers = {
7252
7338
 
7253
7339
  // src/index.ts
7254
7340
  init_http();
7341
+ init_mockOverride();
7255
7342
  init_replay();
7256
7343
 
7257
7344
  // src/replayRegistry.ts
@@ -7279,6 +7366,7 @@ assertAsyncStorageRegistered();
7279
7366
  DEFAULT_SERVICE_URL,
7280
7367
  DbBranchReplayError,
7281
7368
  HttpClient,
7369
+ NO_MOCK_OVERRIDE,
7282
7370
  ReplayError,
7283
7371
  SUPPORTED_PROVIDERS,
7284
7372
  __version__,