@bitfab/sdk 0.38.1 → 0.38.2

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.
@@ -0,0 +1,187 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/autoTrace.ts
21
+ var autoTrace_exports = {};
22
+ __export(autoTrace_exports, {
23
+ __bitfabAutoSpan: () => __bitfabAutoSpan,
24
+ __bitfabAutoTraceActive: () => __bitfabAutoTraceActive,
25
+ __bitfabAutoWrap: () => __bitfabAutoWrap,
26
+ __setBitfabAutoTraceCapturePolicy: () => __setBitfabAutoTraceCapturePolicy,
27
+ getAutoTraceCapturePolicy: () => getAutoTraceCapturePolicy,
28
+ runWithAutoTraceContext: () => runWithAutoTraceContext,
29
+ runWithAutoTraceRootContext: () => runWithAutoTraceRootContext
30
+ });
31
+ module.exports = __toCommonJS(autoTrace_exports);
32
+
33
+ // src/asyncStorage.ts
34
+ var AsyncLocalStorageClass = null;
35
+ var initDone = false;
36
+ function registerAsyncLocalStorageClass(cls) {
37
+ if (!AsyncLocalStorageClass) {
38
+ AsyncLocalStorageClass = cls;
39
+ }
40
+ initDone = true;
41
+ }
42
+ var asyncStorageReady = (typeof process !== "undefined" && process.versions?.node ? (
43
+ // The join trick hides "node:async_hooks" from static analysis so
44
+ // bundlers that ban Node.js built-ins don't fail at build time.
45
+ // webpackIgnore tells webpack/turbopack to emit a native import()
46
+ // so Node.js can resolve the module at runtime.
47
+ import(
48
+ /* webpackIgnore: true */
49
+ ["node", "async_hooks"].join(":")
50
+ ).then(
51
+ (mod) => {
52
+ registerAsyncLocalStorageClass(mod.AsyncLocalStorage);
53
+ }
54
+ ).catch(() => {
55
+ })
56
+ ) : Promise.resolve()).then(() => {
57
+ initDone = true;
58
+ });
59
+ function createAsyncLocalStorage() {
60
+ return AsyncLocalStorageClass ? new AsyncLocalStorageClass() : null;
61
+ }
62
+
63
+ // src/autoTrace.ts
64
+ var autoTraceGlobal = globalThis;
65
+ var autoTraceState = autoTraceGlobal.__bitfabAutoTraceStateV3 ?? {
66
+ storage: null,
67
+ browserScope: void 0,
68
+ capturePolicies: /* @__PURE__ */ new WeakMap(),
69
+ activeRoots: 0
70
+ };
71
+ autoTraceGlobal.__bitfabAutoTraceStateV3 = autoTraceState;
72
+ function initializeAutoTraceStorage() {
73
+ autoTraceState.storage ?? (autoTraceState.storage = createAsyncLocalStorage());
74
+ }
75
+ function runWithAutoTraceContext(context, fn, depth = 0) {
76
+ initializeAutoTraceStorage();
77
+ const scope = { context, depth };
78
+ if (autoTraceState.storage) {
79
+ return autoTraceState.storage.run(scope, fn);
80
+ }
81
+ const previous = autoTraceState.browserScope;
82
+ autoTraceState.browserScope = scope;
83
+ try {
84
+ return fn();
85
+ } finally {
86
+ autoTraceState.browserScope = previous;
87
+ }
88
+ }
89
+ function runWithAutoTraceRootContext(context, fn) {
90
+ autoTraceState.activeRoots += 1;
91
+ let result;
92
+ try {
93
+ result = runWithAutoTraceContext(context, fn);
94
+ } catch (error) {
95
+ autoTraceState.activeRoots -= 1;
96
+ throw error;
97
+ }
98
+ if (isAutoTraceAsyncGenerator(result)) {
99
+ autoTraceState.activeRoots -= 1;
100
+ return wrapAutoTraceAsyncGenerator(context, result);
101
+ }
102
+ if (result instanceof Promise) {
103
+ return result.finally(() => {
104
+ autoTraceState.activeRoots -= 1;
105
+ });
106
+ }
107
+ autoTraceState.activeRoots -= 1;
108
+ return result;
109
+ }
110
+ function isAutoTraceAsyncGenerator(value) {
111
+ if (value === null || typeof value !== "object") {
112
+ return false;
113
+ }
114
+ const candidate = value;
115
+ return typeof candidate.next === "function" && typeof candidate.return === "function" && typeof candidate.throw === "function" && typeof candidate[Symbol.asyncIterator] === "function";
116
+ }
117
+ function wrapAutoTraceAsyncGenerator(context, source) {
118
+ const step = (method, value) => runWithAutoTraceRootContext(context, () => source[method](value));
119
+ const wrapped = {
120
+ next: (value) => step("next", value),
121
+ return: (value) => step("return", value),
122
+ throw: (error) => step("throw", error),
123
+ [Symbol.asyncIterator]: () => wrapped
124
+ };
125
+ return wrapped;
126
+ }
127
+ function __bitfabAutoSpan(definition, inputs, fn) {
128
+ const scope = currentAutoTraceScope();
129
+ if (!scope) {
130
+ return fn();
131
+ }
132
+ return scope.context.invoke(definition, inputs, fn, scope.depth);
133
+ }
134
+ function __bitfabAutoWrap(definition, fn) {
135
+ if (fn.name === "") {
136
+ const nameParts = definition.name.split(".");
137
+ const inferredName = nameParts[nameParts.length - 1];
138
+ if (inferredName !== void 0) {
139
+ Object.defineProperty(fn, "name", {
140
+ configurable: true,
141
+ value: inferredName
142
+ });
143
+ }
144
+ }
145
+ const target = fn;
146
+ return new Proxy(target, {
147
+ apply(callTarget, thisArg, args) {
148
+ if (!__bitfabAutoTraceActive()) {
149
+ return Reflect.apply(callTarget, thisArg, args);
150
+ }
151
+ return __bitfabAutoSpan(
152
+ definition,
153
+ args,
154
+ () => Reflect.apply(callTarget, thisArg, args)
155
+ );
156
+ }
157
+ });
158
+ }
159
+ function __bitfabAutoTraceActive() {
160
+ if (autoTraceState.activeRoots === 0) {
161
+ return false;
162
+ }
163
+ return currentAutoTraceScope() !== void 0;
164
+ }
165
+ function currentAutoTraceScope() {
166
+ initializeAutoTraceStorage();
167
+ return autoTraceState.storage?.getStore() ?? autoTraceState.browserScope;
168
+ }
169
+ function __setBitfabAutoTraceCapturePolicy(client, traceFunctionKey, functionIds) {
170
+ const policies = autoTraceState.capturePolicies.get(client) ?? /* @__PURE__ */ new Map();
171
+ policies.set(traceFunctionKey, new Set(functionIds));
172
+ autoTraceState.capturePolicies.set(client, policies);
173
+ }
174
+ function getAutoTraceCapturePolicy(client, traceFunctionKey) {
175
+ return autoTraceState.capturePolicies.get(client)?.get(traceFunctionKey) ?? /* @__PURE__ */ new Set();
176
+ }
177
+ // Annotate the CommonJS export names for ESM import in node:
178
+ 0 && (module.exports = {
179
+ __bitfabAutoSpan,
180
+ __bitfabAutoTraceActive,
181
+ __bitfabAutoWrap,
182
+ __setBitfabAutoTraceCapturePolicy,
183
+ getAutoTraceCapturePolicy,
184
+ runWithAutoTraceContext,
185
+ runWithAutoTraceRootContext
186
+ });
187
+ //# sourceMappingURL=autoTrace.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/autoTrace.ts","../src/asyncStorage.ts"],"sourcesContent":["import {\n type AsyncLocalStorageLike,\n createAsyncLocalStorage,\n} from \"./asyncStorage.js\"\n\nexport interface AutoTraceFunctionDefinition {\n id: string\n name: string\n file: string\n line: number\n column: number\n wrapper?: boolean\n}\n\nexport interface AutoTraceContext {\n invoke<T>(\n definition: AutoTraceFunctionDefinition,\n inputs: unknown[],\n fn: () => T,\n depth: number,\n ): T\n}\n\ninterface AutoTraceScope {\n context: AutoTraceContext\n depth: number\n}\n\ninterface AutoTraceState {\n storage: AsyncLocalStorageLike<AutoTraceScope> | null\n browserScope: AutoTraceScope | undefined\n capturePolicies: WeakMap<object, Map<string, ReadonlySet<string>>>\n activeRoots: number\n}\n\ninterface AutoTraceGlobal {\n __bitfabAutoTraceStateV3?: AutoTraceState\n}\n\ninterface AutoTraceAsyncGenerator {\n next(value?: unknown): Promise<IteratorResult<unknown, unknown>>\n return(value?: unknown): Promise<IteratorResult<unknown, unknown>>\n throw(error?: unknown): Promise<IteratorResult<unknown, unknown>>\n [Symbol.asyncIterator](): AutoTraceAsyncGenerator\n}\n\nconst autoTraceGlobal = globalThis as unknown as AutoTraceGlobal\nconst autoTraceState: AutoTraceState =\n autoTraceGlobal.__bitfabAutoTraceStateV3 ?? {\n storage: null,\n browserScope: undefined,\n capturePolicies: new WeakMap(),\n activeRoots: 0,\n }\nautoTraceGlobal.__bitfabAutoTraceStateV3 = autoTraceState\n\nfunction initializeAutoTraceStorage(): void {\n autoTraceState.storage ??= createAsyncLocalStorage<AutoTraceScope>()\n}\n\nexport function runWithAutoTraceContext<T>(\n context: AutoTraceContext,\n fn: () => T,\n depth = 0,\n): T {\n initializeAutoTraceStorage()\n const scope = { context, depth }\n if (autoTraceState.storage) {\n return autoTraceState.storage.run(scope, fn)\n }\n\n const previous = autoTraceState.browserScope\n autoTraceState.browserScope = scope\n try {\n return fn()\n } finally {\n autoTraceState.browserScope = previous\n }\n}\n\nexport function runWithAutoTraceRootContext<T>(\n context: AutoTraceContext,\n fn: () => T,\n): T {\n autoTraceState.activeRoots += 1\n let result: T\n try {\n result = runWithAutoTraceContext(context, fn)\n } catch (error) {\n autoTraceState.activeRoots -= 1\n throw error\n }\n\n if (isAutoTraceAsyncGenerator(result)) {\n autoTraceState.activeRoots -= 1\n return wrapAutoTraceAsyncGenerator(context, result) as T\n }\n\n if (result instanceof Promise) {\n return result.finally(() => {\n autoTraceState.activeRoots -= 1\n }) as T\n }\n\n autoTraceState.activeRoots -= 1\n return result\n}\n\nfunction isAutoTraceAsyncGenerator(\n value: unknown,\n): value is AutoTraceAsyncGenerator {\n if (value === null || typeof value !== \"object\") {\n return false\n }\n const candidate = value as Record<PropertyKey, unknown>\n return (\n typeof candidate.next === \"function\" &&\n typeof candidate.return === \"function\" &&\n typeof candidate.throw === \"function\" &&\n typeof candidate[Symbol.asyncIterator] === \"function\"\n )\n}\n\nfunction wrapAutoTraceAsyncGenerator(\n context: AutoTraceContext,\n source: AutoTraceAsyncGenerator,\n): AutoTraceAsyncGenerator {\n const step = (\n method: \"next\" | \"return\" | \"throw\",\n value?: unknown,\n ): Promise<IteratorResult<unknown, unknown>> =>\n runWithAutoTraceRootContext(context, () => source[method](value))\n const wrapped: AutoTraceAsyncGenerator = {\n next: (value) => step(\"next\", value),\n return: (value) => step(\"return\", value),\n throw: (error) => step(\"throw\", error),\n [Symbol.asyncIterator]: () => wrapped,\n }\n return wrapped\n}\n\nexport function __bitfabAutoSpan<T>(\n definition: AutoTraceFunctionDefinition,\n inputs: unknown[],\n fn: () => T,\n): T {\n const scope = currentAutoTraceScope()\n if (!scope) {\n return fn()\n }\n return scope.context.invoke(definition, inputs, fn, scope.depth)\n}\n\n/**\n * Preserve a function's original call arguments for transform cases where\n * parameter bindings discard them, such as destructured arrow parameters.\n *\n * This helper is internal transform/runtime protocol. The proxy preserves the\n * target's callability, arity, async identity, and non-constructibility while\n * only allocating a trace closure beneath an active automatic trace root.\n *\n * @experimental The automatic tracing protocol may change.\n */\nexport function __bitfabAutoWrap<T extends (...args: never[]) => unknown>(\n definition: AutoTraceFunctionDefinition,\n fn: T,\n): T {\n if (fn.name === \"\") {\n const nameParts = definition.name.split(\".\")\n const inferredName = nameParts[nameParts.length - 1]\n if (inferredName !== undefined) {\n Object.defineProperty(fn, \"name\", {\n configurable: true,\n value: inferredName,\n })\n }\n }\n\n const target = fn as unknown as (...args: unknown[]) => unknown\n return new Proxy(target, {\n apply(callTarget, thisArg, args) {\n if (!__bitfabAutoTraceActive()) {\n return Reflect.apply(callTarget, thisArg, args)\n }\n return __bitfabAutoSpan(definition, args, () =>\n Reflect.apply(callTarget, thisArg, args),\n )\n },\n }) as unknown as T\n}\n\n/**\n * Return whether the current call is inside an automatic trace root.\n *\n * Build transforms use this before allocating function metadata, captured\n * inputs, or an invocation closure. It is internal transform/runtime protocol,\n * not a supported application API.\n *\n * @experimental The automatic tracing protocol may change.\n */\nexport function __bitfabAutoTraceActive(): boolean {\n if (autoTraceState.activeRoots === 0) {\n return false\n }\n return currentAutoTraceScope() !== undefined\n}\n\nfunction currentAutoTraceScope(): AutoTraceScope | undefined {\n initializeAutoTraceStorage()\n return autoTraceState.storage?.getStore() ?? autoTraceState.browserScope\n}\n\nexport function __setBitfabAutoTraceCapturePolicy(\n client: object,\n traceFunctionKey: string,\n functionIds: Iterable<string>,\n): void {\n const policies = autoTraceState.capturePolicies.get(client) ?? new Map()\n policies.set(traceFunctionKey, new Set(functionIds))\n autoTraceState.capturePolicies.set(client, policies)\n}\n\nexport function getAutoTraceCapturePolicy(\n client: object,\n traceFunctionKey: string,\n): ReadonlySet<string> {\n return (\n autoTraceState.capturePolicies.get(client)?.get(traceFunctionKey) ??\n new Set()\n )\n}\n","/**\n * Shared AsyncLocalStorage loader.\n *\n * Provides two ways to initialize AsyncLocalStorage:\n *\n * 1. **Synchronous registration** (preferred for Node.js):\n * `asyncStorageNode.ts` calls `registerAsyncLocalStorageClass()` at module\n * evaluation time, so the class is available immediately - no async gap.\n * The `node.ts` entry point imports it before anything else.\n *\n * 2. **Async dynamic import** (fallback for the default entry point):\n * Loads `node:async_hooks` via a bundler-safe dynamic import. This is used\n * by the default `index.ts` entry point so the SDK works in browsers\n * (where the import silently fails) and in Node.js when imported via the\n * default entry point.\n *\n * ## Why the dynamic import looks like this\n *\n * We need to handle three environments:\n *\n * 1. **Pure Node.js** - `import(\"node:async_hooks\")` works natively.\n * 2. **Webpack/Turbopack (Next.js server)** - The bundler processes\n * `import()` calls at build time. The `webpackIgnore` magic comment tells\n * webpack (and turbopack) to emit a native `import()` call instead of\n * trying to resolve it, so Node.js handles it at runtime.\n * 3. **Browsers / Edge** - The `process.versions?.node` guard prevents\n * execution entirely. If it somehow runs, `.catch(() => {})` swallows\n * the failure.\n */\n\nexport interface AsyncLocalStorageLike<T> {\n getStore(): T | undefined\n run<R>(store: T, fn: () => R): R\n}\n\nlet AsyncLocalStorageClass: (new () => AsyncLocalStorageLike<unknown>) | null =\n null\nlet initDone = false\n\n/**\n * Register the AsyncLocalStorage class synchronously.\n *\n * Called by `asyncStorageNode.ts` at module evaluation time so the class\n * is available before any span is created - no async gap, no race condition.\n *\n * Safe to call multiple times; subsequent calls are no-ops.\n */\nexport function registerAsyncLocalStorageClass(\n cls: new () => AsyncLocalStorageLike<unknown>,\n): void {\n if (!AsyncLocalStorageClass) {\n AsyncLocalStorageClass = cls\n }\n initDone = true\n}\n\n/**\n * Assert that AsyncLocalStorage was registered successfully.\n *\n * Called by `node.ts` after importing `asyncStorageNode.ts` to catch\n * import-order bugs at startup rather than silently degrading to the\n * browser fallback (flat spans with no nesting).\n *\n * This should ONLY be called from the Node.js entry point where we\n * know `node:async_hooks` must be available.\n */\nexport function assertAsyncStorageRegistered(): void {\n if (!AsyncLocalStorageClass) {\n console.warn(\n \"Bitfab: AsyncLocalStorage not available - nested span context will not propagate.\",\n )\n }\n}\n\nexport const asyncStorageReady: Promise<void> = (\n typeof process !== \"undefined\" && process.versions?.node\n ? // The join trick hides \"node:async_hooks\" from static analysis so\n // bundlers that ban Node.js built-ins don't fail at build time.\n // webpackIgnore tells webpack/turbopack to emit a native import()\n // so Node.js can resolve the module at runtime.\n import(\n /* webpackIgnore: true */\n [\"node\", \"async_hooks\"].join(\":\")\n )\n .then(\n (mod: {\n AsyncLocalStorage: new () => AsyncLocalStorageLike<unknown>\n }) => {\n registerAsyncLocalStorageClass(mod.AsyncLocalStorage)\n },\n )\n .catch(() => {})\n : Promise.resolve()\n).then(() => {\n initDone = true\n})\n\nexport function isAsyncStorageInitDone(): boolean {\n return initDone\n}\n\nexport function createAsyncLocalStorage<T>(): AsyncLocalStorageLike<T> | null {\n return AsyncLocalStorageClass\n ? (new AsyncLocalStorageClass() as AsyncLocalStorageLike<T>)\n : null\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,39 @@
1
+ interface AutoTraceFunctionDefinition {
2
+ id: string;
3
+ name: string;
4
+ file: string;
5
+ line: number;
6
+ column: number;
7
+ wrapper?: boolean;
8
+ }
9
+ interface AutoTraceContext {
10
+ invoke<T>(definition: AutoTraceFunctionDefinition, inputs: unknown[], fn: () => T, depth: number): T;
11
+ }
12
+ declare function runWithAutoTraceContext<T>(context: AutoTraceContext, fn: () => T, depth?: number): T;
13
+ declare function runWithAutoTraceRootContext<T>(context: AutoTraceContext, fn: () => T): T;
14
+ declare function __bitfabAutoSpan<T>(definition: AutoTraceFunctionDefinition, inputs: unknown[], fn: () => T): T;
15
+ /**
16
+ * Preserve a function's original call arguments for transform cases where
17
+ * parameter bindings discard them, such as destructured arrow parameters.
18
+ *
19
+ * This helper is internal transform/runtime protocol. The proxy preserves the
20
+ * target's callability, arity, async identity, and non-constructibility while
21
+ * only allocating a trace closure beneath an active automatic trace root.
22
+ *
23
+ * @experimental The automatic tracing protocol may change.
24
+ */
25
+ declare function __bitfabAutoWrap<T extends (...args: never[]) => unknown>(definition: AutoTraceFunctionDefinition, fn: T): T;
26
+ /**
27
+ * Return whether the current call is inside an automatic trace root.
28
+ *
29
+ * Build transforms use this before allocating function metadata, captured
30
+ * inputs, or an invocation closure. It is internal transform/runtime protocol,
31
+ * not a supported application API.
32
+ *
33
+ * @experimental The automatic tracing protocol may change.
34
+ */
35
+ declare function __bitfabAutoTraceActive(): boolean;
36
+ declare function __setBitfabAutoTraceCapturePolicy(client: object, traceFunctionKey: string, functionIds: Iterable<string>): void;
37
+ declare function getAutoTraceCapturePolicy(client: object, traceFunctionKey: string): ReadonlySet<string>;
38
+
39
+ export { type AutoTraceContext, type AutoTraceFunctionDefinition, __bitfabAutoSpan, __bitfabAutoTraceActive, __bitfabAutoWrap, __setBitfabAutoTraceCapturePolicy, getAutoTraceCapturePolicy, runWithAutoTraceContext, runWithAutoTraceRootContext };
@@ -0,0 +1,39 @@
1
+ interface AutoTraceFunctionDefinition {
2
+ id: string;
3
+ name: string;
4
+ file: string;
5
+ line: number;
6
+ column: number;
7
+ wrapper?: boolean;
8
+ }
9
+ interface AutoTraceContext {
10
+ invoke<T>(definition: AutoTraceFunctionDefinition, inputs: unknown[], fn: () => T, depth: number): T;
11
+ }
12
+ declare function runWithAutoTraceContext<T>(context: AutoTraceContext, fn: () => T, depth?: number): T;
13
+ declare function runWithAutoTraceRootContext<T>(context: AutoTraceContext, fn: () => T): T;
14
+ declare function __bitfabAutoSpan<T>(definition: AutoTraceFunctionDefinition, inputs: unknown[], fn: () => T): T;
15
+ /**
16
+ * Preserve a function's original call arguments for transform cases where
17
+ * parameter bindings discard them, such as destructured arrow parameters.
18
+ *
19
+ * This helper is internal transform/runtime protocol. The proxy preserves the
20
+ * target's callability, arity, async identity, and non-constructibility while
21
+ * only allocating a trace closure beneath an active automatic trace root.
22
+ *
23
+ * @experimental The automatic tracing protocol may change.
24
+ */
25
+ declare function __bitfabAutoWrap<T extends (...args: never[]) => unknown>(definition: AutoTraceFunctionDefinition, fn: T): T;
26
+ /**
27
+ * Return whether the current call is inside an automatic trace root.
28
+ *
29
+ * Build transforms use this before allocating function metadata, captured
30
+ * inputs, or an invocation closure. It is internal transform/runtime protocol,
31
+ * not a supported application API.
32
+ *
33
+ * @experimental The automatic tracing protocol may change.
34
+ */
35
+ declare function __bitfabAutoTraceActive(): boolean;
36
+ declare function __setBitfabAutoTraceCapturePolicy(client: object, traceFunctionKey: string, functionIds: Iterable<string>): void;
37
+ declare function getAutoTraceCapturePolicy(client: object, traceFunctionKey: string): ReadonlySet<string>;
38
+
39
+ export { type AutoTraceContext, type AutoTraceFunctionDefinition, __bitfabAutoSpan, __bitfabAutoTraceActive, __bitfabAutoWrap, __setBitfabAutoTraceCapturePolicy, getAutoTraceCapturePolicy, runWithAutoTraceContext, runWithAutoTraceRootContext };
@@ -0,0 +1,20 @@
1
+ import {
2
+ __bitfabAutoSpan,
3
+ __bitfabAutoTraceActive,
4
+ __bitfabAutoWrap,
5
+ __setBitfabAutoTraceCapturePolicy,
6
+ getAutoTraceCapturePolicy,
7
+ runWithAutoTraceContext,
8
+ runWithAutoTraceRootContext
9
+ } from "./chunk-GFBQ2AMO.js";
10
+ import "./chunk-H6LZRFMN.js";
11
+ export {
12
+ __bitfabAutoSpan,
13
+ __bitfabAutoTraceActive,
14
+ __bitfabAutoWrap,
15
+ __setBitfabAutoTraceCapturePolicy,
16
+ getAutoTraceCapturePolicy,
17
+ runWithAutoTraceContext,
18
+ runWithAutoTraceRootContext
19
+ };
20
+ //# sourceMappingURL=autoTrace.js.map
@@ -1,22 +1,30 @@
1
+ import {
2
+ __setBitfabAutoTraceCapturePolicy,
3
+ getAutoTraceCapturePolicy,
4
+ runWithAutoTraceContext,
5
+ runWithAutoTraceRootContext
6
+ } from "./chunk-GFBQ2AMO.js";
1
7
  import {
2
8
  BitfabError,
3
9
  DEFAULT_SERVICE_URL,
4
10
  HttpClient,
5
- __privateAdd,
6
- __privateGet,
7
- __privateSet,
8
- asyncStorageReady,
9
- createAsyncLocalStorage,
10
11
  deserializeValue,
11
12
  getReplayContext,
12
- isAsyncStorageInitDone,
13
13
  randomUuid,
14
14
  resolveMockValue,
15
15
  serializeValue,
16
16
  toJsonSafe,
17
17
  toJsonSafeReport,
18
18
  warnOnce
19
- } from "./chunk-MGA7ROIK.js";
19
+ } from "./chunk-SU7EAKOV.js";
20
+ import {
21
+ __privateAdd,
22
+ __privateGet,
23
+ __privateSet,
24
+ asyncStorageReady,
25
+ createAsyncLocalStorage,
26
+ isAsyncStorageInitDone
27
+ } from "./chunk-H6LZRFMN.js";
20
28
 
21
29
  // src/processorPayload.ts
22
30
  var SERIALIZATION_DEGRADED_STEP = "serialization_degraded";
@@ -2337,6 +2345,14 @@ function readEnv(name) {
2337
2345
  }
2338
2346
  return void 0;
2339
2347
  }
2348
+ var DEFAULT_AUTO_TRACE_MAX_DEPTH = 30;
2349
+ var DEFAULT_AUTO_TRACE_MAX_SPANS = 500;
2350
+ var AUTO_TRACE_PROTOCOL = "ts-auto-v1";
2351
+ var AUTO_TRACE_POLICY_REFRESH_MS = 6e4;
2352
+ var AUTO_TRACE_POLICY_RETRY_MS = 1e4;
2353
+ function autoTraceLimit(value, fallback) {
2354
+ return value !== void 0 && Number.isFinite(value) && value >= 0 ? Math.floor(value) : fallback;
2355
+ }
2340
2356
  var Bitfab = class {
2341
2357
  /**
2342
2358
  * Initialize the Bitfab client.
@@ -2346,6 +2362,7 @@ var Bitfab = class {
2346
2362
  constructor(config) {
2347
2363
  /** Gate the empty-key warning to fire at most once. */
2348
2364
  this.apiKeyWarned = false;
2365
+ this.autoTracePolicyRefreshes = /* @__PURE__ */ new Map();
2349
2366
  /**
2350
2367
  * Mock overrides registered via {@link Bitfab.registerMockOverride}, applied
2351
2368
  * to every `replay` on this client (after any per-call `mockOverride`). In
@@ -2369,6 +2386,178 @@ var Bitfab = class {
2369
2386
  timeout: this.timeout
2370
2387
  });
2371
2388
  }
2389
+ /**
2390
+ * Decorate a class method as an automatically expanded trace root.
2391
+ *
2392
+ * Build instrumentation turns repository functions called beneath this
2393
+ * method into nested spans. Every generated span preserves structure; only
2394
+ * function IDs selected by the capture policy include inputs and output.
2395
+ * Without a compatible build transform, this still records the decorated
2396
+ * method as a normal rich root span but cannot discover child calls.
2397
+ *
2398
+ * @param traceFunctionKey - Groups traces and their capture policy.
2399
+ * @param options - Root presentation, subtree bounds, and exclusions.
2400
+ * @experimental Automatic child-call instrumentation is experimental.
2401
+ */
2402
+ trace(traceFunctionKey, options = {}) {
2403
+ const decorator = (...args) => {
2404
+ if (args.length === 3) {
2405
+ const propertyKey = args[1];
2406
+ const descriptor = args[2];
2407
+ if (!descriptor || typeof descriptor.value !== "function") {
2408
+ throw new BitfabError("@bitfab.trace can only decorate methods");
2409
+ }
2410
+ if (!this.explicitlyEnabled) {
2411
+ return;
2412
+ }
2413
+ descriptor.value = this.createAutoTraceRoot(
2414
+ traceFunctionKey,
2415
+ String(propertyKey),
2416
+ options,
2417
+ descriptor.value
2418
+ );
2419
+ return;
2420
+ }
2421
+ const method = args[0];
2422
+ const context = args[1];
2423
+ if (typeof method !== "function" || context?.kind !== "method" || context.name === void 0) {
2424
+ throw new BitfabError("@bitfab.trace can only decorate methods");
2425
+ }
2426
+ if (!this.explicitlyEnabled) {
2427
+ return method;
2428
+ }
2429
+ return this.createAutoTraceRoot(
2430
+ traceFunctionKey,
2431
+ String(context.name),
2432
+ options,
2433
+ method
2434
+ );
2435
+ };
2436
+ return decorator;
2437
+ }
2438
+ withTrace(traceFunctionKey, optionsOrFn, maybeFn) {
2439
+ const options = typeof optionsOrFn === "function" ? {} : optionsOrFn;
2440
+ const fn = typeof optionsOrFn === "function" ? optionsOrFn : maybeFn;
2441
+ if (!fn) {
2442
+ throw new BitfabError("bitfab.withTrace requires a function");
2443
+ }
2444
+ if (!this.explicitlyEnabled) {
2445
+ return fn;
2446
+ }
2447
+ const name = fn.name !== "" ? fn.name : traceFunctionKey;
2448
+ return this.createAutoTraceRoot(traceFunctionKey, name, options, fn);
2449
+ }
2450
+ createAutoTraceRoot(traceFunctionKey, name, options, fn) {
2451
+ const self = this;
2452
+ const maxDepth = autoTraceLimit(
2453
+ options.maxDepth,
2454
+ DEFAULT_AUTO_TRACE_MAX_DEPTH
2455
+ );
2456
+ const maxSpans = autoTraceLimit(
2457
+ options.maxSpans,
2458
+ DEFAULT_AUTO_TRACE_MAX_SPANS
2459
+ );
2460
+ const excluded = new Set(options.exclude ?? []);
2461
+ const includeWrappers = options.includeWrappers ?? false;
2462
+ const tracedRoot = this.withSpan(
2463
+ traceFunctionKey,
2464
+ { name: options.name ?? name, type: options.type ?? "custom" },
2465
+ function(...args) {
2466
+ const capturePolicy = getAutoTraceCapturePolicy(self, traceFunctionKey);
2467
+ self.refreshAutoTraceCapturePolicy(traceFunctionKey);
2468
+ let spansUsed = 0;
2469
+ let truncated = false;
2470
+ const warnTruncated = () => {
2471
+ if (!truncated) {
2472
+ truncated = true;
2473
+ getCurrentTrace().setMetadata({
2474
+ bitfabAutoTrace: {
2475
+ protocol: AUTO_TRACE_PROTOCOL,
2476
+ truncated: true,
2477
+ maxDepth,
2478
+ maxSpans
2479
+ }
2480
+ });
2481
+ }
2482
+ warnOnce(
2483
+ `auto-trace-truncated:${traceFunctionKey}`,
2484
+ `"${traceFunctionKey}" hit an automatic subtree capture limit (maxDepth=${maxDepth}, maxSpans=${maxSpans}); its trace is incomplete. Raise the limits or narrow the subtree with exclude.`
2485
+ );
2486
+ };
2487
+ const autoTraceContext = {
2488
+ invoke(definition, inputs, invokeFn, depth) {
2489
+ const nameParts = definition.name.split(".");
2490
+ const simpleName = nameParts[nameParts.length - 1];
2491
+ if (excluded.has(definition.name) || simpleName !== void 0 && excluded.has(simpleName) || definition.wrapper === true && !includeWrappers) {
2492
+ return invokeFn();
2493
+ }
2494
+ if (depth >= maxDepth || spansUsed >= maxSpans) {
2495
+ warnTruncated();
2496
+ return invokeFn();
2497
+ }
2498
+ spansUsed += 1;
2499
+ const childOptions = {
2500
+ name: definition.name,
2501
+ type: "function",
2502
+ captureWhen: "nested",
2503
+ functionId: definition.id,
2504
+ captureContent: capturePolicy.has(definition.id),
2505
+ autoTraceDefinition: definition
2506
+ };
2507
+ const tracedChild = self.withSpan(
2508
+ traceFunctionKey,
2509
+ childOptions,
2510
+ (..._inputs) => runWithAutoTraceContext(autoTraceContext, invokeFn, depth + 1)
2511
+ );
2512
+ return tracedChild(...inputs);
2513
+ }
2514
+ };
2515
+ return runWithAutoTraceRootContext(
2516
+ autoTraceContext,
2517
+ () => fn.apply(this, args)
2518
+ );
2519
+ }
2520
+ );
2521
+ const autoTraceRoot = function(...args) {
2522
+ if (!self.isTracingEnabled()) {
2523
+ return fn.apply(this, args);
2524
+ }
2525
+ return tracedRoot.apply(this, args);
2526
+ };
2527
+ Object.defineProperty(autoTraceRoot, "_bitfabTraceFunctionKey", {
2528
+ value: traceFunctionKey
2529
+ });
2530
+ return autoTraceRoot;
2531
+ }
2532
+ refreshAutoTraceCapturePolicy(traceFunctionKey) {
2533
+ const now = Date.now();
2534
+ const state = this.autoTracePolicyRefreshes.get(traceFunctionKey) ?? {
2535
+ refreshAfter: 0
2536
+ };
2537
+ if (state.inFlight || now < state.refreshAfter) {
2538
+ return;
2539
+ }
2540
+ const request = this.httpClient.getAutoTracePolicy(
2541
+ traceFunctionKey,
2542
+ AUTO_TRACE_PROTOCOL
2543
+ ).then((policy) => {
2544
+ if (policy.protocol !== AUTO_TRACE_PROTOCOL) {
2545
+ state.refreshAfter = Date.now() + AUTO_TRACE_POLICY_RETRY_MS;
2546
+ return;
2547
+ }
2548
+ const functionIds = Array.isArray(policy.functionIds) ? policy.functionIds.filter(
2549
+ (id) => typeof id === "string" && id.startsWith(`${AUTO_TRACE_PROTOCOL}:`)
2550
+ ).slice(0, DEFAULT_AUTO_TRACE_MAX_SPANS) : [];
2551
+ __setBitfabAutoTraceCapturePolicy(this, traceFunctionKey, functionIds);
2552
+ state.refreshAfter = Date.now() + AUTO_TRACE_POLICY_REFRESH_MS;
2553
+ }).catch(() => {
2554
+ state.refreshAfter = Date.now() + AUTO_TRACE_POLICY_RETRY_MS;
2555
+ }).finally(() => {
2556
+ state.inFlight = void 0;
2557
+ });
2558
+ state.inFlight = request;
2559
+ this.autoTracePolicyRefreshes.set(traceFunctionKey, state);
2560
+ }
2372
2561
  /**
2373
2562
  * Flush and permanently close this client's tracing resources: its pending
2374
2563
  * requests and the single span-transport worker shared by its decorators and
@@ -2915,7 +3104,10 @@ var Bitfab = class {
2915
3104
  parentSpanId,
2916
3105
  inputs,
2917
3106
  startedAt,
2918
- spanType: options.type ?? "custom"
3107
+ spanType: options.type ?? "custom",
3108
+ functionId: options.functionId,
3109
+ captureContent: options.captureContent ?? true,
3110
+ autoTraceDefinition: options.autoTraceDefinition
2919
3111
  };
2920
3112
  const sendSpan = async (params) => {
2921
3113
  const replayCtx = getReplayContext();
@@ -3080,7 +3272,16 @@ var Bitfab = class {
3080
3272
  }
3081
3273
  };
3082
3274
  executeWithContext = () => {
3083
- const result = fn.apply(this, args);
3275
+ let result;
3276
+ try {
3277
+ result = fn.apply(this, args);
3278
+ } catch (error) {
3279
+ void sendSpan({
3280
+ result: void 0,
3281
+ error: error instanceof Error ? error.message : String(error)
3282
+ });
3283
+ throw error;
3284
+ }
3084
3285
  if (result instanceof Promise) {
3085
3286
  return result.then((resolvedResult) => {
3086
3287
  recordSpan(resolvedResult);
@@ -3321,8 +3522,8 @@ var Bitfab = class {
3321
3522
  * Queued on the client's span transport; delivery is the transport's job.
3322
3523
  */
3323
3524
  sendWrapperSpan(params) {
3324
- const serializedInputs = serializeValue(params.inputs);
3325
- const serializedResult = serializeValue(params.result);
3525
+ const serializedInputs = params.captureContent ? serializeValue(params.inputs) : void 0;
3526
+ const serializedResult = params.captureContent ? serializeValue(params.result) : void 0;
3326
3527
  const externalSpan = {
3327
3528
  id: params.spanId,
3328
3529
  trace_id: params.traceId,
@@ -3331,26 +3532,38 @@ var Bitfab = class {
3331
3532
  span_data: {
3332
3533
  name: params.spanName,
3333
3534
  type: params.spanType,
3334
- input: serializedInputs.json,
3335
- output: serializedResult.json,
3336
- // Include superjson meta for type preservation
3337
- ...serializedInputs.meta !== void 0 && {
3338
- input_meta: serializedInputs.meta
3535
+ ...params.functionId !== void 0 && {
3536
+ function_id: params.functionId,
3537
+ content_captured: params.captureContent
3339
3538
  },
3340
- ...serializedResult.meta !== void 0 && {
3341
- output_meta: serializedResult.meta
3539
+ ...params.autoTraceDefinition !== void 0 && {
3540
+ function_file: params.autoTraceDefinition.file,
3541
+ function_line: params.autoTraceDefinition.line,
3542
+ function_column: params.autoTraceDefinition.column
3543
+ },
3544
+ ...serializedInputs !== void 0 && {
3545
+ input: serializedInputs.json,
3546
+ ...serializedInputs.meta !== void 0 && {
3547
+ input_meta: serializedInputs.meta
3548
+ }
3549
+ },
3550
+ ...serializedResult !== void 0 && {
3551
+ output: serializedResult.json,
3552
+ ...serializedResult.meta !== void 0 && {
3553
+ output_meta: serializedResult.meta
3554
+ }
3342
3555
  },
3343
3556
  ...params.functionName !== void 0 && {
3344
3557
  function_name: params.functionName
3345
3558
  },
3346
- ...params.error !== void 0 && {
3559
+ ...params.captureContent && params.error !== void 0 && {
3347
3560
  error: params.error,
3348
3561
  error_source: "code"
3349
3562
  },
3350
- ...params.contexts && params.contexts.length > 0 && {
3563
+ ...params.captureContent && params.contexts && params.contexts.length > 0 && {
3351
3564
  contexts: params.contexts
3352
3565
  },
3353
- ...params.prompt !== void 0 && { prompt: params.prompt }
3566
+ ...params.captureContent && params.prompt !== void 0 && { prompt: params.prompt }
3354
3567
  }
3355
3568
  };
3356
3569
  if (params.parentSpanId) {
@@ -3395,7 +3608,7 @@ var Bitfab = class {
3395
3608
  `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.`
3396
3609
  );
3397
3610
  }
3398
- const { replay: doReplay } = await import("./replay-WSFDZ2UV.js");
3611
+ const { replay: doReplay } = await import("./replay-A5UVFNZ3.js");
3399
3612
  return doReplay(
3400
3613
  this.httpClient,
3401
3614
  this.serviceUrl,
@@ -3633,4 +3846,4 @@ export {
3633
3846
  BitfabFunction,
3634
3847
  finalizers
3635
3848
  };
3636
- //# sourceMappingURL=chunk-WD4AO3BK.js.map
3849
+ //# sourceMappingURL=chunk-CWXCVY75.js.map