@bitfab/sdk 0.38.3 → 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.3";
45
+ __version__ = "0.38.4";
46
46
  __packageName__ = "@bitfab/sdk";
47
47
  }
48
48
  });
@@ -3788,6 +3788,29 @@ function runWithAutoTraceContext(context, fn, depth = 0) {
3788
3788
  autoTraceState.browserScope = previous;
3789
3789
  }
3790
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
+ }
3791
3814
  function runWithAutoTraceRootContext(context, fn) {
3792
3815
  autoTraceState.activeRoots += 1;
3793
3816
  let result;
@@ -3826,6 +3849,29 @@ function wrapAutoTraceAsyncGenerator(context, source) {
3826
3849
  };
3827
3850
  return wrapped;
3828
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
+ }
3829
3875
  function __setBitfabAutoTraceCapturePolicy(client, traceFunctionKey, functionIds) {
3830
3876
  const policies = autoTraceState.capturePolicies.get(client) ?? /* @__PURE__ */ new Map();
3831
3877
  policies.set(traceFunctionKey, new Set(functionIds));
@@ -5678,6 +5724,102 @@ var Bitfab = class {
5678
5724
  const name = fn.name !== "" ? fn.name : traceFunctionKey;
5679
5725
  return this.createAutoTraceRoot(traceFunctionKey, name, options, fn);
5680
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
+ }
5681
5823
  createAutoTraceRoot(traceFunctionKey, name, options, fn) {
5682
5824
  const self = this;
5683
5825
  const maxDepth = autoTraceLimit(
@@ -5716,29 +5858,51 @@ var Bitfab = class {
5716
5858
  );
5717
5859
  };
5718
5860
  const autoTraceContext = {
5719
- invoke(definition, inputs, invokeFn, depth) {
5861
+ invoke(definition, inputs, invokeFn, depth, nodeConfiguration) {
5720
5862
  const nameParts = definition.name.split(".");
5721
5863
  const simpleName = nameParts[nameParts.length - 1];
5722
- if (excluded.has(definition.name) || simpleName !== void 0 && excluded.has(simpleName) || definition.wrapper === true && !includeWrappers) {
5723
- 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);
5724
5870
  }
5725
5871
  if (depth >= maxDepth || spansUsed >= maxSpans) {
5726
5872
  warnTruncated();
5727
- return invokeFn();
5873
+ return invokeWithoutNode();
5728
5874
  }
5729
5875
  spansUsed += 1;
5730
5876
  const childOptions = {
5731
- name: definition.name,
5732
- type: "function",
5877
+ name: nodeConfiguration?.name ?? definition.name,
5878
+ type: nodeConfiguration?.type ?? "function",
5733
5879
  captureWhen: "nested",
5734
5880
  functionId: definition.id,
5735
- captureContent: capturePolicy.has(definition.id),
5736
- 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
+ }
5737
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
+ }
5738
5902
  const tracedChild = self.withSpan(
5739
5903
  traceFunctionKey,
5740
5904
  childOptions,
5741
- (..._inputs) => runWithAutoTraceContext(autoTraceContext, invokeFn, depth + 1)
5905
+ (..._inputs) => invokeWithAutoTraceContext()
5742
5906
  );
5743
5907
  return tracedChild(...inputs);
5744
5908
  }
@@ -6308,18 +6472,17 @@ var Bitfab = class {
6308
6472
  newStack = [...currentStack, newContext];
6309
6473
  const inputs = args;
6310
6474
  const startedAt = (/* @__PURE__ */ new Date()).toISOString();
6475
+ const replayCtxAtStart = getReplayContext();
6476
+ const testRunId = replayCtxAtStart?.testRunId ?? options.testRunId;
6311
6477
  if (isRootSpan && !activeTraceStates.has(traceId)) {
6312
- const replayCtxAtRoot = getReplayContext();
6313
6478
  const dbSnapshotRef = buildSnapshotRef(self.dbSnapshot, startedAt);
6314
6479
  activeTraceStates.set(traceId, {
6315
6480
  traceId,
6316
6481
  startedAt,
6317
6482
  contexts: [],
6318
- ...replayCtxAtRoot?.testRunId && {
6319
- testRunId: replayCtxAtRoot.testRunId
6320
- },
6321
- ...replayCtxAtRoot?.inputSourceTraceId && {
6322
- inputSourceTraceId: replayCtxAtRoot.inputSourceTraceId
6483
+ ...testRunId !== void 0 && { testRunId },
6484
+ ...replayCtxAtStart?.inputSourceTraceId && {
6485
+ inputSourceTraceId: replayCtxAtStart.inputSourceTraceId
6323
6486
  },
6324
6487
  dbSnapshotRef
6325
6488
  });
@@ -6352,9 +6515,7 @@ var Bitfab = class {
6352
6515
  contexts: newContext.contexts,
6353
6516
  prompt: newContext.prompt,
6354
6517
  endedAt,
6355
- ...replayCtx?.testRunId && {
6356
- testRunId: replayCtx.testRunId
6357
- },
6518
+ ...testRunId !== void 0 && { testRunId },
6358
6519
  ...replayCtx?.inputSourceSpanId && {
6359
6520
  inputSourceSpanId: replayCtx.inputSourceSpanId
6360
6521
  }