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.
@@ -10,6 +10,7 @@ import {
10
10
  BitfabError,
11
11
  DEFAULT_SERVICE_URL,
12
12
  HttpClient,
13
+ NO_MOCK_OVERRIDE,
13
14
  deserializeValue,
14
15
  getReplayContext,
15
16
  randomUuid,
@@ -18,7 +19,7 @@ import {
18
19
  toJsonSafe,
19
20
  toJsonSafeReport,
20
21
  warnOnce
21
- } from "./chunk-LHFNHB2J.js";
22
+ } from "./chunk-ZXJ3VQLF.js";
22
23
  import {
23
24
  __privateAdd,
24
25
  __privateGet,
@@ -3280,6 +3281,49 @@ var Bitfab = class {
3280
3281
  } catch {
3281
3282
  }
3282
3283
  };
3284
+ const recordSpan = (result) => {
3285
+ if (options.finalize) {
3286
+ void self.httpClient.trackDeferred(
3287
+ Promise.resolve().then(() => options.finalize(result)).then((output) => sendSpan({ result: output })).catch(
3288
+ (error) => sendSpan({
3289
+ result: void 0,
3290
+ error: error instanceof Error ? `finalize failed: ${error.message}` : `finalize failed: ${String(error)}`
3291
+ })
3292
+ )
3293
+ );
3294
+ } else {
3295
+ void sendSpan({ result });
3296
+ }
3297
+ };
3298
+ executeWithContext = () => {
3299
+ let result;
3300
+ try {
3301
+ result = fn.apply(this, args);
3302
+ } catch (error) {
3303
+ void sendSpan({
3304
+ result: void 0,
3305
+ error: error instanceof Error ? error.message : String(error)
3306
+ });
3307
+ throw error;
3308
+ }
3309
+ if (result instanceof Promise) {
3310
+ return result.then((resolvedResult) => {
3311
+ recordSpan(resolvedResult);
3312
+ return resolvedResult;
3313
+ }).catch((error) => {
3314
+ void sendSpan({
3315
+ result: void 0,
3316
+ error: error instanceof Error ? error.message : String(error)
3317
+ });
3318
+ throw error;
3319
+ });
3320
+ }
3321
+ if (isAsyncGenerator(result)) {
3322
+ return wrapAsyncGenerator(result, newStack, sendSpan);
3323
+ }
3324
+ recordSpan(result);
3325
+ return result;
3326
+ };
3283
3327
  const replayCtxForMock = getReplayContext();
3284
3328
  if (replayCtxForMock?.mockTree && !isRootSpan) {
3285
3329
  const counters = replayCtxForMock.callCounters;
@@ -3338,6 +3382,7 @@ var Bitfab = class {
3338
3382
  }
3339
3383
  return output;
3340
3384
  };
3385
+ const shouldMockWithBaseStrategy = replayCtxForMock.mockStrategy === "all" || replayCtxForMock.mockStrategy === "marked" && options.mockOnReplay === true;
3341
3386
  if (replayCtxForMock.mockOverrides?.length) {
3342
3387
  const nodeMeta = {
3343
3388
  traceFunctionKey,
@@ -3345,28 +3390,75 @@ var Bitfab = class {
3345
3390
  type: options.type ?? "custom",
3346
3391
  originalSpanId: mockSpan?.sourceSpanId
3347
3392
  };
3348
- const override = replayCtxForMock.mockOverrides.find(
3349
- (o) => o.match(nodeMeta)
3350
- );
3351
- if (override) {
3352
- const injected = resolveMockValue(override.value, {
3353
- node: nodeMeta,
3354
- inputs: args,
3355
- getOriginalOutput: () => Promise.resolve(resolveRecordedOutput())
3356
- });
3357
- if (injected instanceof Promise) {
3358
- return emitMockAsync(injected, "override");
3393
+ const overrideCtx = {
3394
+ node: nodeMeta,
3395
+ inputs: args,
3396
+ getOriginalOutput: () => Promise.resolve(resolveRecordedOutput())
3397
+ };
3398
+ const resolveOverrideFrom = (startIndex) => {
3399
+ for (let index = startIndex; index < replayCtxForMock.mockOverrides.length; index += 1) {
3400
+ const override = replayCtxForMock.mockOverrides[index];
3401
+ if (!override?.match(nodeMeta)) {
3402
+ continue;
3403
+ }
3404
+ const injected = resolveMockValue(override.value, overrideCtx);
3405
+ if (injected instanceof Promise) {
3406
+ return injected.then(
3407
+ (output) => output === NO_MOCK_OVERRIDE ? resolveOverrideFrom(index + 1) : { matched: true, output }
3408
+ );
3409
+ }
3410
+ if (injected !== NO_MOCK_OVERRIDE) {
3411
+ return { matched: true, output: injected };
3412
+ }
3359
3413
  }
3360
- return emitMock(injected, "override");
3414
+ return { matched: false };
3415
+ };
3416
+ const resolution = resolveOverrideFrom(0);
3417
+ if (resolution instanceof Promise) {
3418
+ if (!fnReturnsPromise) {
3419
+ throw new BitfabError(
3420
+ `Cannot resolve an asynchronous mock override for synchronous span "${traceFunctionKey}". Make the wrapped function async or return NO_MOCK_OVERRIDE synchronously.`
3421
+ );
3422
+ }
3423
+ return runWithSpanStack(newStack, async () => {
3424
+ const resolved = await resolution;
3425
+ if (resolved.matched) {
3426
+ void sendSpan({
3427
+ result: resolved.output,
3428
+ mocked: true,
3429
+ mockTarget: "output",
3430
+ mockSource: "override"
3431
+ });
3432
+ return resolved.output;
3433
+ }
3434
+ if (shouldMockWithBaseStrategy && !mockSpan) {
3435
+ throw new BitfabError(
3436
+ `Replay selected span "${traceFunctionKey}:${baseSpanParams.spanName}" for mocking, but recorded occurrence ${callIndex + 1} is unavailable. The real span was not executed.`
3437
+ );
3438
+ }
3439
+ if (shouldMockWithBaseStrategy) {
3440
+ const output = await resolveRecordedOutput();
3441
+ void sendSpan({
3442
+ result: output,
3443
+ mocked: true,
3444
+ mockTarget: "output",
3445
+ mockSource: "recorded"
3446
+ });
3447
+ return output;
3448
+ }
3449
+ return executeWithContext();
3450
+ });
3451
+ }
3452
+ if (resolution.matched) {
3453
+ return emitMock(resolution.output, "override");
3361
3454
  }
3362
3455
  }
3363
- const shouldMock = replayCtxForMock.mockStrategy === "all" || replayCtxForMock.mockStrategy === "marked" && options.mockOnReplay === true;
3364
- if (shouldMock && !mockSpan) {
3456
+ if (shouldMockWithBaseStrategy && !mockSpan) {
3365
3457
  throw new BitfabError(
3366
3458
  `Replay selected span "${traceFunctionKey}:${baseSpanParams.spanName}" for mocking, but recorded occurrence ${callIndex + 1} is unavailable. The real span was not executed.`
3367
3459
  );
3368
3460
  }
3369
- if (shouldMock) {
3461
+ if (shouldMockWithBaseStrategy) {
3370
3462
  const recorded = resolveRecordedOutput();
3371
3463
  if (recorded instanceof Promise) {
3372
3464
  return emitMockAsync(recorded, "recorded");
@@ -3374,49 +3466,6 @@ var Bitfab = class {
3374
3466
  return emitMock(recorded, "recorded");
3375
3467
  }
3376
3468
  }
3377
- const recordSpan = (result) => {
3378
- if (options.finalize) {
3379
- void self.httpClient.trackDeferred(
3380
- Promise.resolve().then(() => options.finalize(result)).then((output) => sendSpan({ result: output })).catch(
3381
- (error) => sendSpan({
3382
- result: void 0,
3383
- error: error instanceof Error ? `finalize failed: ${error.message}` : `finalize failed: ${String(error)}`
3384
- })
3385
- )
3386
- );
3387
- } else {
3388
- void sendSpan({ result });
3389
- }
3390
- };
3391
- executeWithContext = () => {
3392
- let result;
3393
- try {
3394
- result = fn.apply(this, args);
3395
- } catch (error) {
3396
- void sendSpan({
3397
- result: void 0,
3398
- error: error instanceof Error ? error.message : String(error)
3399
- });
3400
- throw error;
3401
- }
3402
- if (result instanceof Promise) {
3403
- return result.then((resolvedResult) => {
3404
- recordSpan(resolvedResult);
3405
- return resolvedResult;
3406
- }).catch((error) => {
3407
- void sendSpan({
3408
- result: void 0,
3409
- error: error instanceof Error ? error.message : String(error)
3410
- });
3411
- throw error;
3412
- });
3413
- }
3414
- if (isAsyncGenerator(result)) {
3415
- return wrapAsyncGenerator(result, newStack, sendSpan);
3416
- }
3417
- recordSpan(result);
3418
- return result;
3419
- };
3420
3469
  } catch (setupError) {
3421
3470
  if (registeredTraceId) {
3422
3471
  activeTraceStates.delete(registeredTraceId);
@@ -3703,8 +3752,40 @@ var Bitfab = class {
3703
3752
  ...params.mockSource && { mockSource: params.mockSource }
3704
3753
  });
3705
3754
  }
3706
- registerMockOverride(overrideOrMatch, value) {
3707
- const override = typeof overrideOrMatch === "function" ? { match: overrideOrMatch, value } : overrideOrMatch;
3755
+ registerMockOverride(overrideOrResolverOrMatch, ...values) {
3756
+ let override;
3757
+ if (typeof overrideOrResolverOrMatch === "string") {
3758
+ const keyedOverride = values[0];
3759
+ if (values.length !== 1 || keyedOverride === void 0) {
3760
+ throw new BitfabError(
3761
+ "registerMockOverride(traceFunctionKey, override) requires a resolver function or { match, value } override."
3762
+ );
3763
+ }
3764
+ if (typeof keyedOverride === "function") {
3765
+ override = {
3766
+ match: (node) => node.traceFunctionKey === overrideOrResolverOrMatch,
3767
+ value: keyedOverride
3768
+ };
3769
+ } else if (typeof keyedOverride === "object" && keyedOverride !== null && "match" in keyedOverride && "value" in keyedOverride) {
3770
+ override = {
3771
+ match: (node) => node.traceFunctionKey === overrideOrResolverOrMatch && keyedOverride.match(node),
3772
+ value: keyedOverride.value
3773
+ };
3774
+ } else {
3775
+ throw new BitfabError(
3776
+ "registerMockOverride(traceFunctionKey, override) requires a resolver function or { match, value } override."
3777
+ );
3778
+ }
3779
+ } else if (typeof overrideOrResolverOrMatch !== "function") {
3780
+ override = overrideOrResolverOrMatch;
3781
+ } else if (values.length === 0) {
3782
+ override = { match: () => true, value: overrideOrResolverOrMatch };
3783
+ } else {
3784
+ override = {
3785
+ match: overrideOrResolverOrMatch,
3786
+ value: values[0]
3787
+ };
3788
+ }
3708
3789
  this.mockOverrides.push(override);
3709
3790
  }
3710
3791
  /** Remove all overrides registered via {@link registerMockOverride}. */
@@ -3725,7 +3806,7 @@ var Bitfab = class {
3725
3806
  `Function is wrapped with trace function key '${wrappedKey}' but replay was called with '${traceFunctionKey}'. Pass matching keys, or pass the unwrapped function to replay it under the explicit key.`
3726
3807
  );
3727
3808
  }
3728
- const { replay: doReplay } = await import("./replay-BYW5MCLO.js");
3809
+ const { replay: doReplay } = await import("./replay-HTVEYGC5.js");
3729
3810
  return doReplay(
3730
3811
  this.httpClient,
3731
3812
  this.serviceUrl,
@@ -3969,4 +4050,4 @@ export {
3969
4050
  finalizers,
3970
4051
  defineReplayRegistry
3971
4052
  };
3972
- //# sourceMappingURL=chunk-PXAL7PPD.js.map
4053
+ //# sourceMappingURL=chunk-LQDCJPVV.js.map