@bitfab/sdk 0.36.4 → 0.36.6

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/node.cjs CHANGED
@@ -88,7 +88,7 @@ var __version__;
88
88
  var init_version_generated = __esm({
89
89
  "src/version.generated.ts"() {
90
90
  "use strict";
91
- __version__ = "0.36.4";
91
+ __version__ = "0.36.6";
92
92
  }
93
93
  });
94
94
 
@@ -2391,12 +2391,13 @@ function sleep(ms) {
2391
2391
  unrefTimer(timer);
2392
2392
  });
2393
2393
  }
2394
- async function mapWithConcurrency2(tasks, maxConcurrency, onSettled) {
2394
+ async function mapWithConcurrency2(tasks, maxConcurrency, onSettled, onStarted) {
2395
2395
  const results = new Array(tasks.length);
2396
2396
  let nextIndex = 0;
2397
2397
  async function worker() {
2398
2398
  while (nextIndex < tasks.length) {
2399
2399
  const index = nextIndex++;
2400
+ onStarted?.(index);
2400
2401
  const result = await tasks[index]();
2401
2402
  results[index] = result;
2402
2403
  onSettled?.(result, index);
@@ -2483,13 +2484,15 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
2483
2484
  )
2484
2485
  );
2485
2486
  const total = tasks.length;
2487
+ const onItemFinish = options?.onItemFinish ?? options?.onProgress;
2486
2488
  let completed = 0;
2489
+ let started = 0;
2487
2490
  let succeeded = 0;
2488
2491
  let errored = 0;
2489
2492
  const resultItems = await mapWithConcurrency2(
2490
2493
  tasks,
2491
2494
  maxConcurrency,
2492
- options?.onProgress ? (item) => {
2495
+ (item) => {
2493
2496
  completed += 1;
2494
2497
  if (item.error === null) {
2495
2498
  succeeded += 1;
@@ -2497,18 +2500,17 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
2497
2500
  errored += 1;
2498
2501
  }
2499
2502
  try {
2500
- options?.onProgress?.({
2503
+ onItemFinish?.({
2501
2504
  testRunId,
2502
2505
  completed,
2503
2506
  total,
2504
2507
  succeeded,
2505
2508
  errored,
2506
2509
  item: {
2507
- // The server replay trace id isn't known until completeReplay
2508
- // runs (below), so it can't be reported mid-run and we never
2509
- // emit the client-side placeholder. originalTraceId (the
2510
- // historical trace) is known now and is what a UI keys on to
2511
- // identify what just settled.
2510
+ // The server replay trace id isn't known until completeReplay runs
2511
+ // (below), so it can't be reported mid-run and we never emit the
2512
+ // client-side placeholder. originalTraceId (the historical trace)
2513
+ // is known now and is what a UI keys on to identify what settled.
2512
2514
  traceId: null,
2513
2515
  originalTraceId: item.originalTraceId ?? null,
2514
2516
  originalSpanId: item.originalSpanId ?? null,
@@ -2529,6 +2531,30 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
2529
2531
  });
2530
2532
  } catch {
2531
2533
  }
2534
+ },
2535
+ options?.onItemStart ? (index) => {
2536
+ started += 1;
2537
+ const serverItem = serverItems[index];
2538
+ const originalTraceId = serverItem.originalTraceId ?? serverItem.sourceTraceId;
2539
+ const originalSpanId = serverItem.originalSpanId ?? serverItem.sourceSpanId;
2540
+ try {
2541
+ options.onItemStart?.({
2542
+ type: "started",
2543
+ testRunId,
2544
+ started,
2545
+ completed,
2546
+ total,
2547
+ succeeded,
2548
+ errored,
2549
+ item: {
2550
+ originalTraceId,
2551
+ originalSpanId,
2552
+ sourceTraceId: originalTraceId,
2553
+ sourceSpanId: originalSpanId
2554
+ }
2555
+ });
2556
+ } catch {
2557
+ }
2532
2558
  } : void 0
2533
2559
  );
2534
2560
  await preserveReplayFailure(
@@ -2591,17 +2617,19 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
2591
2617
  testRunUrl: fullTestRunUrl
2592
2618
  };
2593
2619
  await writeReplayResultFile(result);
2594
- try {
2595
- options?.onProgress?.({
2596
- type: "complete",
2597
- testRunId,
2598
- completed: total,
2599
- total,
2600
- succeeded,
2601
- errored,
2602
- result
2603
- });
2604
- } catch {
2620
+ if (!options?.onItemFinish) {
2621
+ try {
2622
+ options?.onProgress?.({
2623
+ type: "complete",
2624
+ testRunId,
2625
+ completed: total,
2626
+ total,
2627
+ succeeded,
2628
+ errored,
2629
+ result
2630
+ });
2631
+ } catch {
2632
+ }
2605
2633
  }
2606
2634
  return result;
2607
2635
  }
@@ -5782,7 +5810,7 @@ var Bitfab = class {
5782
5810
  }
5783
5811
  };
5784
5812
  executeWithContext = () => {
5785
- const result = fn(...args);
5813
+ const result = fn.apply(this, args);
5786
5814
  if (result instanceof Promise) {
5787
5815
  return result.then((resolvedResult) => {
5788
5816
  recordSpan(resolvedResult);
@@ -5812,7 +5840,7 @@ var Bitfab = class {
5812
5840
  `withSpan-setup:${traceFunctionKey}`,
5813
5841
  `tracing setup failed for "${traceFunctionKey}"; running it untraced. The function still runs and returns normally; no span is recorded.`
5814
5842
  );
5815
- return fn(...args);
5843
+ return fn.apply(this, args);
5816
5844
  }
5817
5845
  return runWithSpanStack(newStack, executeWithContext);
5818
5846
  };
@@ -5821,6 +5849,40 @@ var Bitfab = class {
5821
5849
  });
5822
5850
  return wrappedFn;
5823
5851
  }
5852
+ /**
5853
+ * Create a standard ECMAScript method decorator that records each invocation
5854
+ * as a span.
5855
+ *
5856
+ * It supports instance, static, and private methods; use
5857
+ * {@link Bitfab.withSpan} for standalone functions, class fields, and
5858
+ * accessors.
5859
+ *
5860
+ * @example
5861
+ * ```typescript
5862
+ * const bitfab = new Bitfab({ apiKey: process.env.BITFAB_API_KEY });
5863
+ *
5864
+ * class OrderService {
5865
+ * @bitfab.span("order-processing", { type: "agent" })
5866
+ * async process(orderId: string) {
5867
+ * return { orderId };
5868
+ * }
5869
+ * }
5870
+ * ```
5871
+ *
5872
+ * @param traceFunctionKey - A string identifier for grouping spans
5873
+ * @param options - Span configuration applied to the decorated method
5874
+ * @returns A standard ECMAScript method decorator
5875
+ */
5876
+ span(traceFunctionKey, options = {}) {
5877
+ return (originalMethod, context) => {
5878
+ if (context.kind !== "method") {
5879
+ throw new BitfabError(
5880
+ `Bitfab span decorators can only decorate methods; ${String(context.name)} is a ${context.kind}`
5881
+ );
5882
+ }
5883
+ return this.withSpan(traceFunctionKey, options, originalMethod);
5884
+ };
5885
+ }
5824
5886
  /**
5825
5887
  * Get a detached handle to a previously-created trace, looked up by the
5826
5888
  * canonical Bitfab trace ID.
@@ -6097,6 +6159,27 @@ var BitfabFunction = class {
6097
6159
  const fn = typeof optionsOrFn === "function" ? optionsOrFn : maybeFn;
6098
6160
  return this.client.withSpan(this.traceFunctionKey, options, fn);
6099
6161
  }
6162
+ /**
6163
+ * Create a standard ECMAScript method decorator bound to this function key.
6164
+ *
6165
+ * @example
6166
+ * ```typescript
6167
+ * const orders = client.getFunction("order-processing");
6168
+ *
6169
+ * class OrderService {
6170
+ * @orders.span({ type: "agent" })
6171
+ * async process(orderId: string) {
6172
+ * return { orderId };
6173
+ * }
6174
+ * }
6175
+ * ```
6176
+ *
6177
+ * @param options - Span configuration applied to the decorated method
6178
+ * @returns A standard ECMAScript method decorator
6179
+ */
6180
+ span(options = {}) {
6181
+ return this.client.span(this.traceFunctionKey, options);
6182
+ }
6100
6183
  /**
6101
6184
  * Get a Vercel AI SDK language-model middleware bound to this function's key.
6102
6185
  *