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.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.38.4";
54
+ __version__ = "0.38.5";
55
55
  __packageName__ = "bitfab";
56
56
  }
57
57
  });
@@ -2196,11 +2196,16 @@ function normalizeMockOverrides(mockOverride) {
2196
2196
  if (mockOverride === void 0) {
2197
2197
  return [];
2198
2198
  }
2199
- return Array.isArray(mockOverride) ? mockOverride : [mockOverride];
2199
+ const overrides = Array.isArray(mockOverride) ? mockOverride : [mockOverride];
2200
+ return overrides.map(
2201
+ (override) => typeof override === "function" ? { match: () => true, value: override } : override
2202
+ );
2200
2203
  }
2204
+ var NO_MOCK_OVERRIDE;
2201
2205
  var init_mockOverride = __esm({
2202
2206
  "src/mockOverride.ts"() {
2203
2207
  "use strict";
2208
+ NO_MOCK_OVERRIDE = /* @__PURE__ */ Symbol("bitfab.noMockOverride");
2204
2209
  }
2205
2210
  });
2206
2211
 
@@ -3142,6 +3147,7 @@ __export(index_exports, {
3142
3147
  DEFAULT_SERVICE_URL: () => DEFAULT_SERVICE_URL,
3143
3148
  DbBranchReplayError: () => DbBranchReplayError,
3144
3149
  HttpClient: () => HttpClient,
3150
+ NO_MOCK_OVERRIDE: () => NO_MOCK_OVERRIDE,
3145
3151
  ReplayError: () => ReplayError,
3146
3152
  SUPPORTED_PROVIDERS: () => SUPPORTED_PROVIDERS,
3147
3153
  __version__: () => __version__,
@@ -6564,6 +6570,49 @@ var Bitfab = class {
6564
6570
  } catch {
6565
6571
  }
6566
6572
  };
6573
+ const recordSpan = (result) => {
6574
+ if (options.finalize) {
6575
+ void self.httpClient.trackDeferred(
6576
+ Promise.resolve().then(() => options.finalize(result)).then((output) => sendSpan({ result: output })).catch(
6577
+ (error) => sendSpan({
6578
+ result: void 0,
6579
+ error: error instanceof Error ? `finalize failed: ${error.message}` : `finalize failed: ${String(error)}`
6580
+ })
6581
+ )
6582
+ );
6583
+ } else {
6584
+ void sendSpan({ result });
6585
+ }
6586
+ };
6587
+ executeWithContext = () => {
6588
+ let result;
6589
+ try {
6590
+ result = fn.apply(this, args);
6591
+ } catch (error) {
6592
+ void sendSpan({
6593
+ result: void 0,
6594
+ error: error instanceof Error ? error.message : String(error)
6595
+ });
6596
+ throw error;
6597
+ }
6598
+ if (result instanceof Promise) {
6599
+ return result.then((resolvedResult) => {
6600
+ recordSpan(resolvedResult);
6601
+ return resolvedResult;
6602
+ }).catch((error) => {
6603
+ void sendSpan({
6604
+ result: void 0,
6605
+ error: error instanceof Error ? error.message : String(error)
6606
+ });
6607
+ throw error;
6608
+ });
6609
+ }
6610
+ if (isAsyncGenerator(result)) {
6611
+ return wrapAsyncGenerator(result, newStack, sendSpan);
6612
+ }
6613
+ recordSpan(result);
6614
+ return result;
6615
+ };
6567
6616
  const replayCtxForMock = getReplayContext();
6568
6617
  if (replayCtxForMock?.mockTree && !isRootSpan) {
6569
6618
  const counters = replayCtxForMock.callCounters;
@@ -6622,6 +6671,7 @@ var Bitfab = class {
6622
6671
  }
6623
6672
  return output;
6624
6673
  };
6674
+ const shouldMockWithBaseStrategy = replayCtxForMock.mockStrategy === "all" || replayCtxForMock.mockStrategy === "marked" && options.mockOnReplay === true;
6625
6675
  if (replayCtxForMock.mockOverrides?.length) {
6626
6676
  const nodeMeta = {
6627
6677
  traceFunctionKey,
@@ -6629,28 +6679,75 @@ var Bitfab = class {
6629
6679
  type: options.type ?? "custom",
6630
6680
  originalSpanId: mockSpan?.sourceSpanId
6631
6681
  };
6632
- const override = replayCtxForMock.mockOverrides.find(
6633
- (o) => o.match(nodeMeta)
6634
- );
6635
- if (override) {
6636
- const injected = resolveMockValue(override.value, {
6637
- node: nodeMeta,
6638
- inputs: args,
6639
- getOriginalOutput: () => Promise.resolve(resolveRecordedOutput())
6640
- });
6641
- if (injected instanceof Promise) {
6642
- return emitMockAsync(injected, "override");
6682
+ const overrideCtx = {
6683
+ node: nodeMeta,
6684
+ inputs: args,
6685
+ getOriginalOutput: () => Promise.resolve(resolveRecordedOutput())
6686
+ };
6687
+ const resolveOverrideFrom = (startIndex) => {
6688
+ for (let index = startIndex; index < replayCtxForMock.mockOverrides.length; index += 1) {
6689
+ const override = replayCtxForMock.mockOverrides[index];
6690
+ if (!override?.match(nodeMeta)) {
6691
+ continue;
6692
+ }
6693
+ const injected = resolveMockValue(override.value, overrideCtx);
6694
+ if (injected instanceof Promise) {
6695
+ return injected.then(
6696
+ (output) => output === NO_MOCK_OVERRIDE ? resolveOverrideFrom(index + 1) : { matched: true, output }
6697
+ );
6698
+ }
6699
+ if (injected !== NO_MOCK_OVERRIDE) {
6700
+ return { matched: true, output: injected };
6701
+ }
6643
6702
  }
6644
- return emitMock(injected, "override");
6703
+ return { matched: false };
6704
+ };
6705
+ const resolution = resolveOverrideFrom(0);
6706
+ if (resolution instanceof Promise) {
6707
+ if (!fnReturnsPromise) {
6708
+ throw new BitfabError(
6709
+ `Cannot resolve an asynchronous mock override for synchronous span "${traceFunctionKey}". Make the wrapped function async or return NO_MOCK_OVERRIDE synchronously.`
6710
+ );
6711
+ }
6712
+ return runWithSpanStack(newStack, async () => {
6713
+ const resolved = await resolution;
6714
+ if (resolved.matched) {
6715
+ void sendSpan({
6716
+ result: resolved.output,
6717
+ mocked: true,
6718
+ mockTarget: "output",
6719
+ mockSource: "override"
6720
+ });
6721
+ return resolved.output;
6722
+ }
6723
+ if (shouldMockWithBaseStrategy && !mockSpan) {
6724
+ throw new BitfabError(
6725
+ `Replay selected span "${traceFunctionKey}:${baseSpanParams.spanName}" for mocking, but recorded occurrence ${callIndex + 1} is unavailable. The real span was not executed.`
6726
+ );
6727
+ }
6728
+ if (shouldMockWithBaseStrategy) {
6729
+ const output = await resolveRecordedOutput();
6730
+ void sendSpan({
6731
+ result: output,
6732
+ mocked: true,
6733
+ mockTarget: "output",
6734
+ mockSource: "recorded"
6735
+ });
6736
+ return output;
6737
+ }
6738
+ return executeWithContext();
6739
+ });
6740
+ }
6741
+ if (resolution.matched) {
6742
+ return emitMock(resolution.output, "override");
6645
6743
  }
6646
6744
  }
6647
- const shouldMock = replayCtxForMock.mockStrategy === "all" || replayCtxForMock.mockStrategy === "marked" && options.mockOnReplay === true;
6648
- if (shouldMock && !mockSpan) {
6745
+ if (shouldMockWithBaseStrategy && !mockSpan) {
6649
6746
  throw new BitfabError(
6650
6747
  `Replay selected span "${traceFunctionKey}:${baseSpanParams.spanName}" for mocking, but recorded occurrence ${callIndex + 1} is unavailable. The real span was not executed.`
6651
6748
  );
6652
6749
  }
6653
- if (shouldMock) {
6750
+ if (shouldMockWithBaseStrategy) {
6654
6751
  const recorded = resolveRecordedOutput();
6655
6752
  if (recorded instanceof Promise) {
6656
6753
  return emitMockAsync(recorded, "recorded");
@@ -6658,49 +6755,6 @@ var Bitfab = class {
6658
6755
  return emitMock(recorded, "recorded");
6659
6756
  }
6660
6757
  }
6661
- const recordSpan = (result) => {
6662
- if (options.finalize) {
6663
- void self.httpClient.trackDeferred(
6664
- Promise.resolve().then(() => options.finalize(result)).then((output) => sendSpan({ result: output })).catch(
6665
- (error) => sendSpan({
6666
- result: void 0,
6667
- error: error instanceof Error ? `finalize failed: ${error.message}` : `finalize failed: ${String(error)}`
6668
- })
6669
- )
6670
- );
6671
- } else {
6672
- void sendSpan({ result });
6673
- }
6674
- };
6675
- executeWithContext = () => {
6676
- let result;
6677
- try {
6678
- result = fn.apply(this, args);
6679
- } catch (error) {
6680
- void sendSpan({
6681
- result: void 0,
6682
- error: error instanceof Error ? error.message : String(error)
6683
- });
6684
- throw error;
6685
- }
6686
- if (result instanceof Promise) {
6687
- return result.then((resolvedResult) => {
6688
- recordSpan(resolvedResult);
6689
- return resolvedResult;
6690
- }).catch((error) => {
6691
- void sendSpan({
6692
- result: void 0,
6693
- error: error instanceof Error ? error.message : String(error)
6694
- });
6695
- throw error;
6696
- });
6697
- }
6698
- if (isAsyncGenerator(result)) {
6699
- return wrapAsyncGenerator(result, newStack, sendSpan);
6700
- }
6701
- recordSpan(result);
6702
- return result;
6703
- };
6704
6758
  } catch (setupError) {
6705
6759
  if (registeredTraceId) {
6706
6760
  activeTraceStates.delete(registeredTraceId);
@@ -6987,8 +7041,40 @@ var Bitfab = class {
6987
7041
  ...params.mockSource && { mockSource: params.mockSource }
6988
7042
  });
6989
7043
  }
6990
- registerMockOverride(overrideOrMatch, value) {
6991
- const override = typeof overrideOrMatch === "function" ? { match: overrideOrMatch, value } : overrideOrMatch;
7044
+ registerMockOverride(overrideOrResolverOrMatch, ...values) {
7045
+ let override;
7046
+ if (typeof overrideOrResolverOrMatch === "string") {
7047
+ const keyedOverride = values[0];
7048
+ if (values.length !== 1 || keyedOverride === void 0) {
7049
+ throw new BitfabError(
7050
+ "registerMockOverride(traceFunctionKey, override) requires a resolver function or { match, value } override."
7051
+ );
7052
+ }
7053
+ if (typeof keyedOverride === "function") {
7054
+ override = {
7055
+ match: (node) => node.traceFunctionKey === overrideOrResolverOrMatch,
7056
+ value: keyedOverride
7057
+ };
7058
+ } else if (typeof keyedOverride === "object" && keyedOverride !== null && "match" in keyedOverride && "value" in keyedOverride) {
7059
+ override = {
7060
+ match: (node) => node.traceFunctionKey === overrideOrResolverOrMatch && keyedOverride.match(node),
7061
+ value: keyedOverride.value
7062
+ };
7063
+ } else {
7064
+ throw new BitfabError(
7065
+ "registerMockOverride(traceFunctionKey, override) requires a resolver function or { match, value } override."
7066
+ );
7067
+ }
7068
+ } else if (typeof overrideOrResolverOrMatch !== "function") {
7069
+ override = overrideOrResolverOrMatch;
7070
+ } else if (values.length === 0) {
7071
+ override = { match: () => true, value: overrideOrResolverOrMatch };
7072
+ } else {
7073
+ override = {
7074
+ match: overrideOrResolverOrMatch,
7075
+ value: values[0]
7076
+ };
7077
+ }
6992
7078
  this.mockOverrides.push(override);
6993
7079
  }
6994
7080
  /** Remove all overrides registered via {@link registerMockOverride}. */
@@ -7238,6 +7324,7 @@ var finalizers = {
7238
7324
 
7239
7325
  // src/index.ts
7240
7326
  init_http();
7327
+ init_mockOverride();
7241
7328
  init_replay();
7242
7329
 
7243
7330
  // src/replayRegistry.ts
@@ -7261,6 +7348,7 @@ function defineReplayRegistry(registry) {
7261
7348
  DEFAULT_SERVICE_URL,
7262
7349
  DbBranchReplayError,
7263
7350
  HttpClient,
7351
+ NO_MOCK_OVERRIDE,
7264
7352
  ReplayError,
7265
7353
  SUPPORTED_PROVIDERS,
7266
7354
  __version__,