@bitfab/sdk 0.38.2 → 0.38.4

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.38.2";
45
+ __version__ = "0.38.4";
46
46
  __packageName__ = "@bitfab/sdk";
47
47
  }
48
48
  });
@@ -2804,6 +2804,11 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
2804
2804
  );
2805
2805
  }
2806
2806
  }
2807
+ if (options?.traceIds !== void 0 && options?.datasetId !== void 0) {
2808
+ throw new BitfabError(
2809
+ "traceIds and datasetId select different replay sources and cannot be used together."
2810
+ );
2811
+ }
2807
2812
  if (options?.limit !== void 0 && options?.traceIds !== void 0) {
2808
2813
  try {
2809
2814
  console.warn(
@@ -3131,6 +3136,7 @@ __export(index_exports, {
3131
3136
  ReplayError: () => ReplayError,
3132
3137
  SUPPORTED_PROVIDERS: () => SUPPORTED_PROVIDERS,
3133
3138
  __version__: () => __version__,
3139
+ defineReplayRegistry: () => defineReplayRegistry,
3134
3140
  finalizers: () => finalizers,
3135
3141
  flushTraces: () => flushTraces,
3136
3142
  getCurrentReplayBranch: () => getCurrentReplayBranch,
@@ -3782,6 +3788,29 @@ function runWithAutoTraceContext(context, fn, depth = 0) {
3782
3788
  autoTraceState.browserScope = previous;
3783
3789
  }
3784
3790
  }
3791
+ function runWithAutoTraceNodeConfiguration(nodeConfiguration, fn) {
3792
+ const scope = currentAutoTraceScope();
3793
+ if (!scope) {
3794
+ return fn();
3795
+ }
3796
+ const configuredScope = { ...scope, nodeConfiguration };
3797
+ let result;
3798
+ if (autoTraceState.storage) {
3799
+ result = autoTraceState.storage.run(configuredScope, fn);
3800
+ } else {
3801
+ const previous = autoTraceState.browserScope;
3802
+ autoTraceState.browserScope = configuredScope;
3803
+ try {
3804
+ result = fn();
3805
+ } finally {
3806
+ autoTraceState.browserScope = previous;
3807
+ }
3808
+ }
3809
+ if (isAutoTraceAsyncGenerator(result)) {
3810
+ return wrapAutoTraceNodeAsyncGenerator(nodeConfiguration, result);
3811
+ }
3812
+ return result;
3813
+ }
3785
3814
  function runWithAutoTraceRootContext(context, fn) {
3786
3815
  autoTraceState.activeRoots += 1;
3787
3816
  let result;
@@ -3820,6 +3849,29 @@ function wrapAutoTraceAsyncGenerator(context, source) {
3820
3849
  };
3821
3850
  return wrapped;
3822
3851
  }
3852
+ function wrapAutoTraceNodeAsyncGenerator(nodeConfiguration, source) {
3853
+ const step = (method, value) => runWithAutoTraceNodeConfiguration(
3854
+ nodeConfiguration,
3855
+ () => source[method](value)
3856
+ );
3857
+ const wrapped = {
3858
+ next: (value) => step("next", value),
3859
+ return: (value) => step("return", value),
3860
+ throw: (error) => step("throw", error),
3861
+ [Symbol.asyncIterator]: () => wrapped
3862
+ };
3863
+ return wrapped;
3864
+ }
3865
+ function __bitfabAutoTraceActive() {
3866
+ if (autoTraceState.activeRoots === 0) {
3867
+ return false;
3868
+ }
3869
+ return currentAutoTraceScope() !== void 0;
3870
+ }
3871
+ function currentAutoTraceScope() {
3872
+ initializeAutoTraceStorage();
3873
+ return autoTraceState.storage?.getStore() ?? autoTraceState.browserScope;
3874
+ }
3823
3875
  function __setBitfabAutoTraceCapturePolicy(client, traceFunctionKey, functionIds) {
3824
3876
  const policies = autoTraceState.capturePolicies.get(client) ?? /* @__PURE__ */ new Map();
3825
3877
  policies.set(traceFunctionKey, new Set(functionIds));
@@ -5672,6 +5724,102 @@ var Bitfab = class {
5672
5724
  const name = fn.name !== "" ? fn.name : traceFunctionKey;
5673
5725
  return this.createAutoTraceRoot(traceFunctionKey, name, options, fn);
5674
5726
  }
5727
+ /**
5728
+ * Configure a transformed class method when it is discovered beneath a
5729
+ * {@link Bitfab.trace} root.
5730
+ *
5731
+ * The decorator creates no span or trace by itself. Beneath an active trace,
5732
+ * it can rename or retype the discovered call, capture its contents, mark it
5733
+ * for recorded-output replay, finalize its output, or omit it while leaving
5734
+ * captured descendants attached to the nearest captured parent.
5735
+ *
5736
+ * @param options - Trace-owned call configuration.
5737
+ * @experimental Automatic child-call instrumentation is experimental.
5738
+ */
5739
+ node(options = {}) {
5740
+ const configuration = this.resolveNodeConfiguration(options);
5741
+ const decorator = (...args) => {
5742
+ if (args.length === 3) {
5743
+ const descriptor = args[2];
5744
+ if (!descriptor || typeof descriptor.value !== "function") {
5745
+ throw new BitfabError("@bitfab.node can only decorate methods");
5746
+ }
5747
+ if (!this.explicitlyEnabled) {
5748
+ return;
5749
+ }
5750
+ descriptor.value = this.createAutoTraceNode(
5751
+ configuration,
5752
+ descriptor.value,
5753
+ String(args[1])
5754
+ );
5755
+ return;
5756
+ }
5757
+ const method = args[0];
5758
+ const context = args[1];
5759
+ if (typeof method !== "function" || context?.kind !== "method") {
5760
+ throw new BitfabError("@bitfab.node can only decorate methods");
5761
+ }
5762
+ if (!this.explicitlyEnabled) {
5763
+ return method;
5764
+ }
5765
+ return this.createAutoTraceNode(
5766
+ configuration,
5767
+ method,
5768
+ String(context.name)
5769
+ );
5770
+ };
5771
+ return decorator;
5772
+ }
5773
+ withNode(optionsOrFn, maybeFn, internalFunctionName) {
5774
+ const options = typeof optionsOrFn === "function" ? {} : optionsOrFn;
5775
+ const fn = typeof optionsOrFn === "function" ? optionsOrFn : maybeFn;
5776
+ if (!fn) {
5777
+ throw new BitfabError("bitfab.withNode requires a function");
5778
+ }
5779
+ const configuration = this.resolveNodeConfiguration(options);
5780
+ if (!this.explicitlyEnabled) {
5781
+ return fn;
5782
+ }
5783
+ const functionName = internalFunctionName ?? fn.name;
5784
+ if (functionName === "") {
5785
+ throw new BitfabError(
5786
+ "bitfab.withNode requires a named function so the subtree transform can bind its configuration to the correct call."
5787
+ );
5788
+ }
5789
+ return this.createAutoTraceNode(configuration, fn, functionName);
5790
+ }
5791
+ resolveNodeConfiguration(options) {
5792
+ const capture = options.capture ?? true;
5793
+ if (!capture && options.mockOnReplay === true) {
5794
+ throw new BitfabError(
5795
+ "bitfab.node({ capture: false }) cannot use mockOnReplay: true because an uncaptured node has no recorded output."
5796
+ );
5797
+ }
5798
+ return {
5799
+ capture,
5800
+ type: options.type ?? "custom",
5801
+ ...options.name !== void 0 && { name: options.name },
5802
+ ...options.testRunId !== void 0 && {
5803
+ testRunId: options.testRunId
5804
+ },
5805
+ ...options.mockOnReplay !== void 0 && {
5806
+ mockOnReplay: options.mockOnReplay
5807
+ },
5808
+ ...options.finalize !== void 0 && { finalize: options.finalize }
5809
+ };
5810
+ }
5811
+ createAutoTraceNode(configuration, fn, functionName) {
5812
+ const nodeConfiguration = { ...configuration, functionName };
5813
+ return function(...args) {
5814
+ if (!__bitfabAutoTraceActive()) {
5815
+ return fn.apply(this, args);
5816
+ }
5817
+ return runWithAutoTraceNodeConfiguration(
5818
+ nodeConfiguration,
5819
+ () => fn.apply(this, args)
5820
+ );
5821
+ };
5822
+ }
5675
5823
  createAutoTraceRoot(traceFunctionKey, name, options, fn) {
5676
5824
  const self = this;
5677
5825
  const maxDepth = autoTraceLimit(
@@ -5710,29 +5858,51 @@ var Bitfab = class {
5710
5858
  );
5711
5859
  };
5712
5860
  const autoTraceContext = {
5713
- invoke(definition, inputs, invokeFn, depth) {
5861
+ invoke(definition, inputs, invokeFn, depth, nodeConfiguration) {
5714
5862
  const nameParts = definition.name.split(".");
5715
5863
  const simpleName = nameParts[nameParts.length - 1];
5716
- if (excluded.has(definition.name) || simpleName !== void 0 && excluded.has(simpleName) || definition.wrapper === true && !includeWrappers) {
5717
- return invokeFn();
5864
+ const invokeWithoutNode = () => nodeConfiguration === void 0 ? invokeFn() : runWithAutoTraceContext(autoTraceContext, invokeFn, depth);
5865
+ if (excluded.has(definition.name) || simpleName !== void 0 && excluded.has(simpleName) || nodeConfiguration === void 0 && definition.wrapper === true && !includeWrappers) {
5866
+ return invokeWithoutNode();
5867
+ }
5868
+ if (nodeConfiguration?.capture === false) {
5869
+ return runWithAutoTraceContext(autoTraceContext, invokeFn, depth);
5718
5870
  }
5719
5871
  if (depth >= maxDepth || spansUsed >= maxSpans) {
5720
5872
  warnTruncated();
5721
- return invokeFn();
5873
+ return invokeWithoutNode();
5722
5874
  }
5723
5875
  spansUsed += 1;
5724
5876
  const childOptions = {
5725
- name: definition.name,
5726
- type: "function",
5877
+ name: nodeConfiguration?.name ?? definition.name,
5878
+ type: nodeConfiguration?.type ?? "function",
5727
5879
  captureWhen: "nested",
5728
5880
  functionId: definition.id,
5729
- captureContent: capturePolicy.has(definition.id),
5730
- autoTraceDefinition: definition
5881
+ captureContent: nodeConfiguration !== void 0 || capturePolicy.has(definition.id),
5882
+ autoTraceDefinition: definition,
5883
+ ...nodeConfiguration?.testRunId !== void 0 && {
5884
+ testRunId: nodeConfiguration.testRunId
5885
+ },
5886
+ ...nodeConfiguration?.mockOnReplay !== void 0 && {
5887
+ mockOnReplay: nodeConfiguration.mockOnReplay
5888
+ },
5889
+ ...nodeConfiguration?.finalize !== void 0 && {
5890
+ finalize: nodeConfiguration.finalize
5891
+ }
5731
5892
  };
5893
+ const invokeWithAutoTraceContext = () => runWithAutoTraceContext(autoTraceContext, invokeFn, depth + 1);
5894
+ if (definition.async === true) {
5895
+ const tracedAsyncChild = self.withSpan(
5896
+ traceFunctionKey,
5897
+ childOptions,
5898
+ async (..._inputs) => await invokeWithAutoTraceContext()
5899
+ );
5900
+ return tracedAsyncChild(...inputs);
5901
+ }
5732
5902
  const tracedChild = self.withSpan(
5733
5903
  traceFunctionKey,
5734
5904
  childOptions,
5735
- (..._inputs) => runWithAutoTraceContext(autoTraceContext, invokeFn, depth + 1)
5905
+ (..._inputs) => invokeWithAutoTraceContext()
5736
5906
  );
5737
5907
  return tracedChild(...inputs);
5738
5908
  }
@@ -6302,18 +6472,17 @@ var Bitfab = class {
6302
6472
  newStack = [...currentStack, newContext];
6303
6473
  const inputs = args;
6304
6474
  const startedAt = (/* @__PURE__ */ new Date()).toISOString();
6475
+ const replayCtxAtStart = getReplayContext();
6476
+ const testRunId = replayCtxAtStart?.testRunId ?? options.testRunId;
6305
6477
  if (isRootSpan && !activeTraceStates.has(traceId)) {
6306
- const replayCtxAtRoot = getReplayContext();
6307
6478
  const dbSnapshotRef = buildSnapshotRef(self.dbSnapshot, startedAt);
6308
6479
  activeTraceStates.set(traceId, {
6309
6480
  traceId,
6310
6481
  startedAt,
6311
6482
  contexts: [],
6312
- ...replayCtxAtRoot?.testRunId && {
6313
- testRunId: replayCtxAtRoot.testRunId
6314
- },
6315
- ...replayCtxAtRoot?.inputSourceTraceId && {
6316
- inputSourceTraceId: replayCtxAtRoot.inputSourceTraceId
6483
+ ...testRunId !== void 0 && { testRunId },
6484
+ ...replayCtxAtStart?.inputSourceTraceId && {
6485
+ inputSourceTraceId: replayCtxAtStart.inputSourceTraceId
6317
6486
  },
6318
6487
  dbSnapshotRef
6319
6488
  });
@@ -6346,9 +6515,7 @@ var Bitfab = class {
6346
6515
  contexts: newContext.contexts,
6347
6516
  prompt: newContext.prompt,
6348
6517
  endedAt,
6349
- ...replayCtx?.testRunId && {
6350
- testRunId: replayCtx.testRunId
6351
- },
6518
+ ...testRunId !== void 0 && { testRunId },
6352
6519
  ...replayCtx?.inputSourceSpanId && {
6353
6520
  inputSourceSpanId: replayCtx.inputSourceSpanId
6354
6521
  }
@@ -7063,6 +7230,13 @@ var finalizers = {
7063
7230
  // src/index.ts
7064
7231
  init_http();
7065
7232
  init_replay();
7233
+
7234
+ // src/replayRegistry.ts
7235
+ init_errors();
7236
+ init_replay();
7237
+ function defineReplayRegistry(registry) {
7238
+ return registry;
7239
+ }
7066
7240
  // Annotate the CommonJS export names for ESM import in node:
7067
7241
  0 && (module.exports = {
7068
7242
  BITFAB_PROGRESS_PREFIX,
@@ -7081,6 +7255,7 @@ init_replay();
7081
7255
  ReplayError,
7082
7256
  SUPPORTED_PROVIDERS,
7083
7257
  __version__,
7258
+ defineReplayRegistry,
7084
7259
  finalizers,
7085
7260
  flushTraces,
7086
7261
  getCurrentReplayBranch,